diff --git a/3rdparty/sgx-install.sh b/3rdparty/sgx-install.sh deleted file mode 100644 index 81246ce3dec6b16eeca6186f42a434b571193cc5..0000000000000000000000000000000000000000 --- a/3rdparty/sgx-install.sh +++ /dev/null @@ -1,146 +0,0 @@ -#!/bin/sh -e - -if ! id | grep -q root; then - echo "must be run as root" - exit -fi - -install_lib_n_system () { - if [ -f ${libdir}/${file} ] ; then - cp -v ${libdir}/${file} /usr/lib/${file} - if [ -d /usr/lib/arm-linux-gnueabihf/ ] ; then - cp -v ${libdir}/${file} /usr/lib/arm-linux-gnueabihf/${file} - fi - fi -} - -install_lib () { - if [ -f ${libdir}/${file} ] ; then - cp -v ${libdir}/${file} /usr/lib/${file} - fi -} - -install_bin () { - if [ -f ${libdir}/${file} ] ; then - cp -v ${libdir}/${file} /usr/local/bin/${file} - fi -} - -distro=$(lsb_release -si) - -if [ ! -f /lib/modules/`uname -r`/extra/es8.x/pvrsrvkm.ko ] ; then - if [ -f /opt/gfxmodules/gfx_rel_es8.x/pvrsrvkm.ko ] ; then - if [ ! -d /lib/modules/$(uname -r)/extra/ ] ; then - mkdir -p /lib/modules/$(uname -r)/extra/ || true - fi - - cp -v /opt/gfxmodules/gfx_rel_es8.x/pvrsrvkm.ko /lib/modules/$(uname -r)/extra/pvrsrvkm.ko - cp -v /opt/gfxmodules/gfx_rel_es8.x/omaplfb.ko /lib/modules/$(uname -r)/extra/omaplfb.ko - fi -fi - -echo "Running [depmod -a `uname -r`]" -depmod -a `uname -r` - -if [ -d /opt/gfxlibraries/gfx_rel_es8.x/ ] ; then - echo "Copying libraries" - libdir="/opt/gfxlibraries/gfx_rel_es8.x" - - # Install the standard libraries - # - file="libGLES_CM.so" ; install_lib - - file="libusc.so" ; install_lib - - file="libGLESv2.so" ; install_lib_n_system - - file="libglslcompiler.so" ; install_lib - - file="libIMGegl.so" ; install_lib - file="libEGL.so" ; install_lib_n_system - file="libpvr2d.so" ; install_lib - - file="libpvrPVR2D_BLITWSEGL.so" ; install_lib - file="libpvrPVR2D_FLIPWSEGL.so" ; install_lib - file="libpvrPVR2D_FRONTWSEGL.so" ; install_lib - file="libpvrPVR2D_LINUXFBWSEGL.so" ; install_lib - - file="libpvrEWS_WSEGL.so" ; install_lib - file="libpvrEWS_REMWSEGL.so" ; install_lib - - file="libsrv_um.so" ; install_lib - file="libsrv_init.so" ; install_lib - file="libPVRScopeServices.so" ; install_lib - - file="libews.so" ; install_lib - - # Install the standard executables - # - file="pvrsrvctl" ; install_bin - file="sgx_init_test" ; install_bin - - file="ews_server" ; install_bin - file="ews_server_es2" ; install_bin - - # Install the standard unittests - # - - file="services_test" ; install_bin - file="sgx_blit_test" ; install_bin - file="sgx_clipblit_test" ; install_bin - file="sgx_flip_test" ; install_bin - file="sgx_render_flip_test" ; install_bin - file="pvr2d_test" ; install_bin - - file="gles1test1" ; install_bin - file="gles1_texture_stream" ; install_bin - - file="gles2test1" ; install_bin - file="glsltest1_vertshader.txt" ; install_bin - file="glsltest1_fragshaderA.txt" ; install_bin - file="glsltest1_fragshaderB.txt" ; install_bin - file="gles2_texture_stream" ; install_bin - file="eglinfo" ; install_bin - - file="ews_test_gles1" ; install_bin - file="ews_test_gles1_egl_image_external" ; install_bin - - file="ews_test_gles2" ; install_bin - file="ews_test_gles2_main.vert" ; install_bin - file="ews_test_gles2_main.frag" ; install_bin - file="ews_test_gles2_pp.vert" ; install_bin - file="ews_test_gles2_pp.frag" ; install_bin - file="ews_test_gles2_egl_image_external" ; install_bin - file="ews_test_gles2_egl_image_external.vert" ; install_bin - file="ews_test_gles2_egl_image_external.frag" ; install_bin - file="ews_test_swrender" ; install_bin -fi - -case "${distro}" in -Debian) - if [ -f /opt/gfxinstall/scripts/sgx-startup-sysv.sh ] ; then - if [ -f /etc/init.d/sgx-startup.sh ] ; then - insserv --remove sgx-startup.sh - rm -rf /etc/init.d/sgx-startup.sh || true - fi - - cp -v /opt/gfxinstall/scripts/sgx-startup-sysv.sh /etc/init.d/sgx-startup.sh - chown root:root /etc/init.d/sgx-startup.sh - chmod +x /etc/init.d/sgx-startup.sh - insserv sgx-startup.sh || true - fi - ;; -Ubuntu) - if [ -f /opt/gfxinstall/scripts/sgx-startup-sysv.sh ] ; then - if [ -f /etc/init.d/sgx-startup.sh ] ; then - rm -rf /etc/init.d/sgx-startup.sh || true - update-rc.d sgx-startup.sh remove - fi - - cp -v /opt/gfxinstall/scripts/sgx-startup-sysv.sh /etc/init.d/sgx-startup.sh - chown root:root /etc/init.d/sgx-startup.sh - chmod +x /etc/init.d/sgx-startup.sh - update-rc.d sgx-startup.sh defaults - fi - ;; -esac diff --git a/3rdparty/sgx-startup-sysv.sh b/3rdparty/sgx-startup-sysv.sh deleted file mode 100644 index 70bc92acb1edc61432eb79032adc9e519ebd4475..0000000000000000000000000000000000000000 --- a/3rdparty/sgx-startup-sysv.sh +++ /dev/null @@ -1,52 +0,0 @@ -#!/bin/sh -e -### BEGIN INIT INFO -# Provides: sgx-startup.sh -# Required-Start: $local_fs -# Required-Stop: $local_fs -# Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 -# Short-Description: Start daemon at boot time -# Description: Enable service provided by daemon. -### END INIT INFO - -case "$1" in -start) - if [ -d /sys/devices/ocp*/56000000.sgx ] || [ -d /sys/devices/platform/ocp/56000000.sgx ] ; then - echo "sgx: Starting PVR" - - modprobe -q pvrsrvkm - - # Delete the device for PVR services device and recreate with the - # correct major number. - # - pvr_maj=$(grep "pvrsrvkm$" /proc/devices | cut -b1,2,3) - - if [ -e /dev/pvrsrvkm ] ; then - rm -f /dev/pvrsrvkm - fi - - mknod /dev/pvrsrvkm c $pvr_maj 0 - chmod 666 /dev/pvrsrvkm - - if [ -f /usr/local/bin/pvrsrvctl ] ; then - /usr/local/bin/pvrsrvctl --start --no-module - - modprobe -q omaplfb - fi - fi - ;; -reload|force-reload|restart) - if [ -d /sys/devices/ocp*/56000000.sgx ] || [ -d /sys/devices/platform/ocp/56000000.sgx ] ; then - echo "sgx: Restarting PVR" - fi - ;; -stop) - exit 0 - ;; -*) - echo "Usage: /etc/init.d/sgx-startup.sh {start|stop|reload|restart|force-reload}" - exit 1 - ;; -esac - -exit 0 diff --git a/patch.sh b/patch.sh index 171be34776000c70b35c4812a1946ed525726acf..1f3cf5506d16e966ca5d10092ccf83cd7288feb3 100644 --- a/patch.sh +++ b/patch.sh @@ -197,7 +197,7 @@ local_patch () { #external_git #aufs4 -rt +#rt #local_patch reverts () { @@ -246,42 +246,43 @@ ti () { cleanup fi fi - unset is_mainline - echo "dir: ti/dtbs" - #regenerate="enable" - if [ "x${regenerate}" = "xenable" ] ; then - start_cleanup - fi + if [ "x${is_mainline}" = "xenable" ] ; then + echo "dir: ti/ticpufreq/" + #regenerate="enable" + if [ "x${regenerate}" = "xenable" ] ; then + start_cleanup + fi - ${git} "${DIR}/patches/ti/dtbs/0001-sync-with-ti-4.4.patch" + ${git} "${DIR}/patches/ti/ticpufreq/0001-Documentation-dt-add-bindings-for-ti-cpufreq.patch" + ${git} "${DIR}/patches/ti/ticpufreq/0002-cpufreq-ti-Add-cpufreq-driver-to-determine-available.patch" + ${git} "${DIR}/patches/ti/ticpufreq/0003-ARM-dts-am335x-Update-MPU-regulator-range-for-TI-boa.patch" + ${git} "${DIR}/patches/ti/ticpufreq/0004-ARM-dts-am33xx-Move-to-operating-points-v2-table-and.patch" + ${git} "${DIR}/patches/ti/ticpufreq/0005-ARM-dts-am335x-boneblack-Enable-1GHz-OPP-for-cpu.patch" + ${git} "${DIR}/patches/ti/ticpufreq/0006-ARM-dts-am4372-Add-operating-points-v2-table.patch" + ${git} "${DIR}/patches/ti/ticpufreq/0007-ARM-dts-am437x-gp-evm-Hook-dcdc2-as-the-cpu0-supply.patch" + ${git} "${DIR}/patches/ti/ticpufreq/0008-ARM-dts-dra7-Add-dt-node-for-the-syscon-control-modu.patch" + ${git} "${DIR}/patches/ti/ticpufreq/0009-ARM-dts-dra7-Move-cpus-node-to-parent-dts-for-dra74x.patch" + ${git} "${DIR}/patches/ti/ticpufreq/0010-ARM-dts-dra7-Move-to-operating-points-v2-table.patch" - if [ "x${regenerate}" = "xenable" ] ; then - number=1 - cleanup + if [ "x${regenerate}" = "xenable" ] ; then + wdir="ti/ticpufreq" + number=10 + cleanup + fi fi -} + unset is_mainline -exynos () { - echo "dir: exynos/" + echo "dir: ti/dtbs" #regenerate="enable" if [ "x${regenerate}" = "xenable" ] ; then start_cleanup fi - ${git} "${DIR}/patches/exynos/0001-clk-samsung-exynos3250-Add-UART2-clock.patch" - ${git} "${DIR}/patches/exynos/0002-clk-samsung-exynos3250-Add-MMC2-clock.patch" - ${git} "${DIR}/patches/exynos/0003-ARM-dts-Add-UART2-dt-node-for-Exynos3250-SoC.patch" - ${git} "${DIR}/patches/exynos/0004-ARM-dts-Add-MSHC2-dt-node-for-Exynos3250-SoC.patch" - ${git} "${DIR}/patches/exynos/0005-ARM-dts-Add-exynos3250-artik5-dtsi-file-for-ARTIK5-m.patch" - ${git} "${DIR}/patches/exynos/0006-ARM-dts-Add-MSHC0-dt-node-for-eMMC-device-for-exynos.patch" - ${git} "${DIR}/patches/exynos/0007-ARM-dts-Add-thermal-zone-and-cpufreq-node-for-exynos.patch" - ${git} "${DIR}/patches/exynos/0008-ARM-dts-Add-rtc-and-adc-dt-node-for-exynos3250-artik.patch" - ${git} "${DIR}/patches/exynos/0009-ARM-dts-Add-MSHC2-dt-node-for-SD-card-for-exynos3250.patch" - ${git} "${DIR}/patches/exynos/0010-ARM-dts-Add-PPMU-node-for-exynos3250-artik5-module.patch" + ${git} "${DIR}/patches/ti/dtbs/0001-sync-with-ti-4.4.patch" if [ "x${regenerate}" = "xenable" ] ; then - number=10 + number=1 cleanup fi } @@ -320,47 +321,13 @@ pru_rpmsg () { } bbb_overlays () { - echo "dir: bbb_overlays/dtc" - #regenerate="enable" - if [ "x${regenerate}" = "xenable" ] ; then - - cd ../ - if [ -d dtc ] ; then - rm -rf dtc - fi - git clone https://git.kernel.org/pub/scm/utils/dtc/dtc.git - cd dtc - git pull --no-edit https://github.com/RobertCNelson/dtc bb.org-4.1-dt-overlays5-dtc-b06e55c88b9b - - cd ../KERNEL/ - sed -i -e 's:git commit:#git commit:g' ./scripts/dtc/update-dtc-source.sh - ./scripts/dtc/update-dtc-source.sh - sed -i -e 's:#git commit:git commit:g' ./scripts/dtc/update-dtc-source.sh - git commit -a -m "scripts/dtc: Update to upstream version overlays" -s - git format-patch -1 -o ../patches/bbb_overlays/dtc/ - exit 2 - else - #regenerate="enable" - if [ "x${regenerate}" = "xenable" ] ; then - start_cleanup - fi - - #4.6.0-rc: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=91feabc2e2240ee80dc8ac08103cb83f497e4d12 - ${git} "${DIR}/patches/bbb_overlays/dtc/0001-scripts-dtc-Update-to-upstream-version-overlays.patch" - - if [ "x${regenerate}" = "xenable" ] ; then - number=1 - cleanup - fi - fi - echo "dir: bbb_overlays" #regenerate="enable" if [ "x${regenerate}" = "xenable" ] ; then start_cleanup fi - ${git} "${DIR}/patches/bbb_overlays/0001-OF-DT-Overlay-configfs-interface-v7.patch" + ${git} "${DIR}/patches/bbb_overlays/0001-scripts-dtc-Update-to-upstream-version-1.4.1-Overlay.patch" ${git} "${DIR}/patches/bbb_overlays/0002-gitignore-Ignore-DTB-files.patch" if [ "x${regenerate}" = "xenable" ] ; then @@ -368,69 +335,50 @@ bbb_overlays () { ${git} "${DIR}/patches/bbb_overlays/0004-ARM-CUSTOM-Build-a-uImage-with-dtb-already-appended.patch" fi - #depends on: cf26f1137333251f3515dea31f95775b99df0fd5 ${git} "${DIR}/patches/bbb_overlays/0005-omap-Fix-crash-when-omap-device-is-disabled.patch" - ${git} "${DIR}/patches/bbb_overlays/0006-serial-omap-Fix-port-line-number-without-aliases.patch" ${git} "${DIR}/patches/bbb_overlays/0007-tty-omap-serial-Fix-up-platform-data-alloc.patch" - ${git} "${DIR}/patches/bbb_overlays/0008-ARM-DT-Enable-symbols-when-CONFIG_OF_OVERLAY-is-used.patch" - - #v4.5.0-rc0 merge... - #https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=33caf82acf4dc420bf0f0136b886f7b27ecf90c5 - ${git} "${DIR}/patches/bbb_overlays/0009-of-Custom-printk-format-specifier-for-device-node.patch" - - #v4.5.0-rc0 (api change):183223770ae8625df8966ed15811d1b3ee8720aa - ${git} "${DIR}/patches/bbb_overlays/0010-of-overlay-kobjectify-overlay-objects.patch" - - ${git} "${DIR}/patches/bbb_overlays/0011-of-overlay-global-sysfs-enable-attribute.patch" - ${git} "${DIR}/patches/bbb_overlays/0012-Documentation-ABI-overlays-global-attributes.patch" - ${git} "${DIR}/patches/bbb_overlays/0013-Documentation-document-of_overlay_disable-parameter.patch" - - #v4.5.0-rc0 (api change):183223770ae8625df8966ed15811d1b3ee8720aa - ${git} "${DIR}/patches/bbb_overlays/0014-of-overlay-add-per-overlay-sysfs-attributes.patch" - - ${git} "${DIR}/patches/bbb_overlays/0015-Documentation-ABI-overlays-per-overlay-docs.patch" - ${git} "${DIR}/patches/bbb_overlays/0016-misc-Beaglebone-capemanager.patch" - ${git} "${DIR}/patches/bbb_overlays/0017-doc-misc-Beaglebone-capemanager-documentation.patch" - ${git} "${DIR}/patches/bbb_overlays/0018-doc-dt-beaglebone-cape-manager-bindings.patch" - ${git} "${DIR}/patches/bbb_overlays/0019-doc-ABI-bone_capemgr-sysfs-API.patch" - ${git} "${DIR}/patches/bbb_overlays/0020-MAINTAINERS-Beaglebone-capemanager-maintainer.patch" - ${git} "${DIR}/patches/bbb_overlays/0021-arm-dts-Enable-beaglebone-cape-manager.patch" - ${git} "${DIR}/patches/bbb_overlays/0022-of-overlay-Implement-indirect-target-support.patch" - ${git} "${DIR}/patches/bbb_overlays/0023-of-unittest-Add-indirect-overlay-target-test.patch" - ${git} "${DIR}/patches/bbb_overlays/0024-doc-dt-Document-the-indirect-overlay-method.patch" - ${git} "${DIR}/patches/bbb_overlays/0025-of-overlay-Introduce-target-root-capability.patch" - ${git} "${DIR}/patches/bbb_overlays/0026-of-unittest-Unit-tests-for-target-root-overlays.patch" - ${git} "${DIR}/patches/bbb_overlays/0027-doc-dt-Document-the-target-root-overlay-method.patch" - ${git} "${DIR}/patches/bbb_overlays/0028-of-dynamic-Add-__of_node_dupv.patch" - - #v4.5.0-rc0 (api change):183223770ae8625df8966ed15811d1b3ee8720aa - ${git} "${DIR}/patches/bbb_overlays/0029-of-changesets-Introduce-changeset-helper-methods.patch" - - #v4.5.0-rc0 (api change):183223770ae8625df8966ed15811d1b3ee8720aa - ${git} "${DIR}/patches/bbb_overlays/0030-RFC-Device-overlay-manager-PCI-USB-DT.patch" - - if [ "x${regenerate}" = "xenable" ] ; then - ${git} "${DIR}/patches/bbb_overlays/0031-boneblack-defconfig.patch" - fi - - ${git} "${DIR}/patches/bbb_overlays/0032-of-remove-bogus-return-in-of_core_init.patch" - ${git} "${DIR}/patches/bbb_overlays/0033-of-Maintainer-fixes-for-dynamic.patch" - - #v4.5.0-rc0 (api change):183223770ae8625df8966ed15811d1b3ee8720aa - ${git} "${DIR}/patches/bbb_overlays/0034-of-unittest-changeset-helpers.patch" - + ${git} "${DIR}/patches/bbb_overlays/0008-of-Custom-printk-format-specifier-for-device-node.patch" + ${git} "${DIR}/patches/bbb_overlays/0009-of-overlay-kobjectify-overlay-objects.patch" + ${git} "${DIR}/patches/bbb_overlays/0010-of-overlay-global-sysfs-enable-attribute.patch" + ${git} "${DIR}/patches/bbb_overlays/0011-Documentation-ABI-overlays-global-attributes.patch" + ${git} "${DIR}/patches/bbb_overlays/0012-Documentation-document-of_overlay_disable-parameter.patch" + ${git} "${DIR}/patches/bbb_overlays/0013-of-overlay-add-per-overlay-sysfs-attributes.patch" + ${git} "${DIR}/patches/bbb_overlays/0014-Documentation-ABI-overlays-per-overlay-docs.patch" + ${git} "${DIR}/patches/bbb_overlays/0015-of-dynamic-Add-__of_node_dupv.patch" + ${git} "${DIR}/patches/bbb_overlays/0016-of-changesets-Introduce-changeset-helper-methods.patch" + ${git} "${DIR}/patches/bbb_overlays/0017-of-changeset-Add-of_changeset_node_move-method.patch" + ${git} "${DIR}/patches/bbb_overlays/0018-of-unittest-changeset-helpers.patch" + ${git} "${DIR}/patches/bbb_overlays/0019-i2c-demux-Use-changeset-helpers-for-clarity.patch" + ${git} "${DIR}/patches/bbb_overlays/0020-OF-DT-Overlay-configfs-interface-v7.patch" + ${git} "${DIR}/patches/bbb_overlays/0021-ARM-DT-Enable-symbols-when-CONFIG_OF_OVERLAY-is-used.patch" + ${git} "${DIR}/patches/bbb_overlays/0022-misc-Beaglebone-capemanager.patch" + ${git} "${DIR}/patches/bbb_overlays/0023-doc-misc-Beaglebone-capemanager-documentation.patch" + ${git} "${DIR}/patches/bbb_overlays/0024-doc-dt-beaglebone-cape-manager-bindings.patch" + ${git} "${DIR}/patches/bbb_overlays/0025-doc-ABI-bone_capemgr-sysfs-API.patch" + ${git} "${DIR}/patches/bbb_overlays/0026-MAINTAINERS-Beaglebone-capemanager-maintainer.patch" + ${git} "${DIR}/patches/bbb_overlays/0027-arm-dts-Enable-beaglebone-cape-manager.patch" + ${git} "${DIR}/patches/bbb_overlays/0028-of-overlay-Implement-target-index-support.patch" + ${git} "${DIR}/patches/bbb_overlays/0029-of-unittest-Add-indirect-overlay-target-test.patch" + ${git} "${DIR}/patches/bbb_overlays/0030-doc-dt-Document-the-indirect-overlay-method.patch" + ${git} "${DIR}/patches/bbb_overlays/0031-of-overlay-Introduce-target-root-capability.patch" + ${git} "${DIR}/patches/bbb_overlays/0032-of-unittest-Unit-tests-for-target-root-overlays.patch" + ${git} "${DIR}/patches/bbb_overlays/0033-doc-dt-Document-the-target-root-overlay-method.patch" + ${git} "${DIR}/patches/bbb_overlays/0034-RFC-Device-overlay-manager-PCI-USB-DT.patch" ${git} "${DIR}/patches/bbb_overlays/0035-of-rename-_node_sysfs-to-_node_post.patch" ${git} "${DIR}/patches/bbb_overlays/0036-of-Support-hashtable-lookups-for-phandles.patch" - ${git} "${DIR}/patches/bbb_overlays/0037-of-overlay-Pick-up-label-symbols-from-overlays.patch" + ${git} "${DIR}/patches/bbb_overlays/0037-of-unittest-hashed-phandles-unitest.patch" + ${git} "${DIR}/patches/bbb_overlays/0038-of-overlay-Pick-up-label-symbols-from-overlays.patch" + ${git} "${DIR}/patches/bbb_overlays/0039-of-overlay-Add-pr_fmt-for-clarity.patch" + ${git} "${DIR}/patches/bbb_overlays/0040-of-Portable-Device-Tree-connector.patch" if [ "x${regenerate}" = "xenable" ] ; then - ${git} "${DIR}/patches/bbb_overlays/0038-connector-wip.patch" + ${git} "${DIR}/patches/bbb_overlays/0041-boneblack-defconfig.patch" fi if [ "x${regenerate}" = "xenable" ] ; then wdir="bbb_overlays" - number=38 + number=41 cleanup fi } @@ -638,21 +586,6 @@ beaglebone () { cleanup fi - echo "dir: beaglebone/mctrl_gpio" - #regenerate="enable" - if [ "x${regenerate}" = "xenable" ] ; then - start_cleanup - fi - ${git} "${DIR}/patches/beaglebone/mctrl_gpio/0001-tty-serial-8250-make-UART_MCR-register-access-consis.patch" - ${git} "${DIR}/patches/beaglebone/mctrl_gpio/0002-serial-mctrl_gpio-add-modem-control-read-routine.patch" - ${git} "${DIR}/patches/beaglebone/mctrl_gpio/0003-serial-mctrl_gpio-add-IRQ-locking.patch" - - if [ "x${regenerate}" = "xenable" ] ; then - wdir="beaglebone/mctrl_gpio" - number=3 - cleanup - fi - echo "dir: beaglebone/jtag" #regenerate="enable" if [ "x${regenerate}" = "xenable" ] ; then @@ -666,114 +599,22 @@ beaglebone () { cleanup fi + echo "dir: beaglebone/tilcdc" #regenerate="enable" if [ "x${regenerate}" = "xenable" ] ; then - cherrypick_dir="beaglebone/tilcdc" - #https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/log/?qt=grep&q=tilcdc - - #merged in 4.5.0-rc0 - - #drm/tilcdc: rewrite pixel clock calculation - SHA="3d19306a8240a163f6b02bb46213c277d6d44e08" ; num="1" ; cherrypick - - #drm/tilcdc: verify fb pitch - SHA="6f206e9d2a965771e99bca4c22dbadac1b58a0e8" ; cherrypick - - #drm/tilcdc: adopt pinctrl support - SHA="416a07fbe7b1f1a6f7e0595b43b5a85a1c877e05" ; cherrypick - - #drm/tilcdc: fix kernel panic on suspend when no hdmi monitor connected - SHA="85fd27f80b3641c9af9f04cde1b712c8c20916d8" ; cherrypick - - #drm/tilcdc: make frame_done interrupt active at all times - SHA="b62222fcaab994177f121d58acdab269f0f54897" ; cherrypick - - #drm/tilcdc: disable the lcd controller/dma engine when suspend invoked - SHA="614b3cfeb8d22e2b0f49bcfeaf5b52900242a944" ; cherrypick - - #drm/tilcdc: Implement dma-buf support for tilcdc - SHA="9c15390506d6888978fa98094f7578142d2e2f01" ; cherrypick - - #drm/tilcdc: fix build error when !CONFIG_CPU_FREQ - SHA="7974dff4957f953f0f6fd71c30e02a7c25aea7f0" ; cherrypick - - #drm/tilcdc: Allocate register storage based on the actual number registers - SHA="29ddd6e171abae990a881b9e221359f13c546369" ; cherrypick - - #drm/tilcdc: cleanup runtime PM handling - SHA="65734a262350a746100dcfd85a81f7dc1b69dd10" ; cherrypick - - #drm/tilcdc: disable crtc on unload - SHA="1aea1e79dbfd65a99da11868829c3e147b85cc32" ; cherrypick - - #drm/tilcdc: split reset to a separate function - SHA="2efec4f3064d084bac1b2c1e1513a7452e8e245d" ; cherrypick - - #drm/tilcdc: remove broken error handling - SHA="31ec5a2c7eed3a3e182a592591f4fb04304668a1" ; cherrypick - - #drm/tilcdc: cleanup irq handling - SHA="317aae738b6402cd66fb9b52434b783f17ff5dd4" ; cherrypick - - #drm/tilcdc: Get rid of complex ping-pong mechanism - SHA="2b2080d7e9ae2463b15a003629d2ea7d733759a0" ; cherrypick - - #drm/tilcdc: Do not update the next frame buffer close to vertical blank - SHA="2b3a8cd71c2b830164df5de07e4ddebe0faa58f5" ; cherrypick - - #drm/tilcdc: Fix interrupt enable/disable code for version 2 tilcdc - SHA="947df7e3f019bba902a55485635060e5970fb9a2" ; cherrypick - - #drm/tilcdc: Remove the duplicate LCDC_INT_ENABLE_SET_REG in registers[] - SHA="f3a99946a95b3482eabec63b9f662963d7d2e3c8" ; cherrypick - - #drm/tilcdc: Add prints on sync lost and FIFO underrun interrupts - SHA="c0c2baaab1b553df92a24e9175440f15e6ad3e2c" ; cherrypick - - #drm/tilcdc: Disable sync lost interrupt if it fires on every frame - SHA="5895d08f6ff2175dabc373dada7d1bfa26123fc9" ; cherrypick - - #drm/tilcdc: Initialize crtc->port - SHA="d66284fba15014daacef64cfc610a249553534c6" ; cherrypick + start_cleanup + fi - #drm/tilcdc: Use devm_kzalloc() and devm_kcalloc() for private data - SHA="d0ec32caef0baa490b419895ef61c8481d49f7cd" ; cherrypick + ${git} "${DIR}/patches/beaglebone/tilcdc/0001-drm-tilcdc-Write-to-LCDC_END_OF_INT_IND_REG-at-the-e.patch" + ${git} "${DIR}/patches/beaglebone/tilcdc/0002-drm-tilcdc-Move-waiting-of-LCDC_FRAME_DONE-IRQ-into-.patch" + ${git} "${DIR}/patches/beaglebone/tilcdc/0003-drm-tilcdc-Recover-from-sync-lost-error-flood-by-res.patch" - exit 2 + if [ "x${regenerate}" = "xenable" ] ; then + wdir="beaglebone/tilcdc" + number=3 + cleanup fi - if [ "x${merged_in_4_6}" = "xenable" ] ; then - echo "dir: beaglebone/tilcdc" - #merged in 4.6.0-rc0 - ${git} "${DIR}/patches/beaglebone/tilcdc/0001-drm-tilcdc-rewrite-pixel-clock-calculation.patch" - ${git} "${DIR}/patches/beaglebone/tilcdc/0002-drm-tilcdc-verify-fb-pitch.patch" - ${git} "${DIR}/patches/beaglebone/tilcdc/0003-drm-tilcdc-adopt-pinctrl-support.patch" - ${git} "${DIR}/patches/beaglebone/tilcdc/0004-drm-tilcdc-fix-kernel-panic-on-suspend-when-no-hdmi-.patch" - ${git} "${DIR}/patches/beaglebone/tilcdc/0005-drm-tilcdc-make-frame_done-interrupt-active-at-all-t.patch" - ${git} "${DIR}/patches/beaglebone/tilcdc/0006-drm-tilcdc-disable-the-lcd-controller-dma-engine-whe.patch" - ${git} "${DIR}/patches/beaglebone/tilcdc/0007-drm-tilcdc-Implement-dma-buf-support-for-tilcdc.patch" - ${git} "${DIR}/patches/beaglebone/tilcdc/0008-drm-tilcdc-fix-build-error-when-CONFIG_CPU_FREQ.patch" - ${git} "${DIR}/patches/beaglebone/tilcdc/0009-drm-tilcdc-Allocate-register-storage-based-on-the-ac.patch" - ${git} "${DIR}/patches/beaglebone/tilcdc/0010-drm-tilcdc-cleanup-runtime-PM-handling.patch" - ${git} "${DIR}/patches/beaglebone/tilcdc/0011-drm-tilcdc-disable-crtc-on-unload.patch" - ${git} "${DIR}/patches/beaglebone/tilcdc/0012-drm-tilcdc-split-reset-to-a-separate-function.patch" - ${git} "${DIR}/patches/beaglebone/tilcdc/0013-drm-tilcdc-remove-broken-error-handling.patch" - ${git} "${DIR}/patches/beaglebone/tilcdc/0014-drm-tilcdc-cleanup-irq-handling.patch" - ${git} "${DIR}/patches/beaglebone/tilcdc/0015-drm-tilcdc-Get-rid-of-complex-ping-pong-mechanism.patch" - ${git} "${DIR}/patches/beaglebone/tilcdc/0016-drm-tilcdc-Do-not-update-the-next-frame-buffer-close.patch" - ${git} "${DIR}/patches/beaglebone/tilcdc/0017-drm-tilcdc-Fix-interrupt-enable-disable-code-for-ver.patch" - ${git} "${DIR}/patches/beaglebone/tilcdc/0018-drm-tilcdc-Remove-the-duplicate-LCDC_INT_ENABLE_SET_.patch" - ${git} "${DIR}/patches/beaglebone/tilcdc/0019-drm-tilcdc-Add-prints-on-sync-lost-and-FIFO-underrun.patch" - ${git} "${DIR}/patches/beaglebone/tilcdc/0020-drm-tilcdc-Disable-sync-lost-interrupt-if-it-fires-o.patch" - ${git} "${DIR}/patches/beaglebone/tilcdc/0021-drm-tilcdc-Initialize-crtc-port.patch" - ${git} "${DIR}/patches/beaglebone/tilcdc/0022-drm-tilcdc-Use-devm_kzalloc-and-devm_kcalloc-for-pri.patch" - fi - - #[PATCH v2 0/3] Recover from sync lost error flood by resetting the LCDC - ${git} "${DIR}/patches/beaglebone/tilcdc/0023-drm-tilcdc-Write-to-LCDC_END_OF_INT_IND_REG-at-the-e.patch" - ${git} "${DIR}/patches/beaglebone/tilcdc/0024-drm-tilcdc-Move-waiting-of-LCDC_FRAME_DONE-IRQ-into-.patch" - ${git} "${DIR}/patches/beaglebone/tilcdc/0025-drm-tilcdc-Recover-from-sync-lost-error-flood-by-res.patch" - #This has to be last... echo "dir: beaglebone/dtbs" #regenerate="enable" @@ -899,41 +740,15 @@ quieter () { fi } -sgx () { - echo "dir: sgx" - #regenerate="enable" - if [ "x${regenerate}" = "xenable" ] ; then - start_cleanup - fi - - ${git} "${DIR}/patches/sgx/0001-HACK-drm-fb_helper-enable-panning-support.patch" - ${git} "${DIR}/patches/sgx/0002-HACK-drm-tilcdc-add-vsync-callback-for-use-in-omaplf.patch" - ${git} "${DIR}/patches/sgx/0003-drm-tilcdc-fix-the-ping-pong-dma-tearing-issue-seen-.patch" - ${git} "${DIR}/patches/sgx/0004-ARM-OMAP2-Use-pdata-quirks-for-sgx-deassert_hardrese.patch" - ${git} "${DIR}/patches/sgx/0005-ARM-dts-am33xx-add-DT-node-for-gpu.patch" - ${git} "${DIR}/patches/sgx/0006-Revert-ARM-reduce-visibility-of-dmac_-functions.patch" - ${git} "${DIR}/patches/sgx/0007-arm-Export-cache-flush-management-symbols-when-MULTI.patch" - - if [ "x${regenerate}" = "xenable" ] ; then - number=7 - cleanup - fi -} - ### reverts #fixes ti -#exynos -#dts -#wand -#udoo pru_uio pru_rpmsg bbb_overlays beaglebone quieter -#sgx packaging () { echo "dir: packaging" diff --git a/patches/bbb_overlays/0001-scripts-dtc-Update-to-upstream-version-1.4.1-Overlay.patch b/patches/bbb_overlays/0001-scripts-dtc-Update-to-upstream-version-1.4.1-Overlay.patch new file mode 100644 index 0000000000000000000000000000000000000000..8ac0a871cd4efda74f9e43208a9001bfe4796563 --- /dev/null +++ b/patches/bbb_overlays/0001-scripts-dtc-Update-to-upstream-version-1.4.1-Overlay.patch @@ -0,0 +1,5270 @@ +From f32c8280ab343a969ca1852b77ea7371b4c21835 Mon Sep 17 00:00:00 2001 +From: Pantelis Antoniou <pantelis.antoniou@konsulko.com> +Date: Mon, 23 May 2016 16:33:22 +0300 +Subject: [PATCH 01/41] scripts/dtc: Update to upstream version 1.4.1+Overlays + +--- + scripts/dtc/checks.c | 8 +- + scripts/dtc/dtc-lexer.l | 5 + + scripts/dtc/dtc-lexer.lex.c_shipped | 490 +++---- + scripts/dtc/dtc-parser.tab.c_shipped | 2382 ++++++++++++++++++---------------- + scripts/dtc/dtc-parser.tab.h_shipped | 109 +- + scripts/dtc/dtc-parser.y | 56 +- + scripts/dtc/dtc.c | 37 +- + scripts/dtc/dtc.h | 32 +- + scripts/dtc/flattree.c | 13 +- + scripts/dtc/fstree.c | 2 +- + scripts/dtc/libfdt/fdt.c | 2 +- + scripts/dtc/libfdt/fdt.h | 3 +- + scripts/dtc/libfdt/libfdt.h | 60 +- + scripts/dtc/libfdt/libfdt_internal.h | 1 + + scripts/dtc/livetree.c | 217 +++- + scripts/dtc/version_gen.h | 2 +- + 16 files changed, 1982 insertions(+), 1437 deletions(-) + +diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c +index 386f956..3d4c3c6 100644 +--- a/scripts/dtc/checks.c ++++ b/scripts/dtc/checks.c +@@ -490,8 +490,12 @@ static void fixup_phandle_references(struct check *c, struct node *dt, + + refnode = get_node_by_ref(dt, m->ref); + if (! refnode) { +- FAIL(c, "Reference to non-existent node or label \"%s\"\n", +- m->ref); ++ if (!(tree_get_versionflags(dt) & VF_PLUGIN)) ++ FAIL(c, "Reference to non-existent node or " ++ "label \"%s\"\n", m->ref); ++ else /* mark the entry as unresolved */ ++ *((cell_t *)(prop->val.val + m->offset)) = ++ cpu_to_fdt32(0xffffffff); + continue; + } + +diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l +index 790fbf6..40bbc87 100644 +--- a/scripts/dtc/dtc-lexer.l ++++ b/scripts/dtc/dtc-lexer.l +@@ -121,6 +121,11 @@ static void lexical_error(const char *fmt, ...); + return DT_V1; + } + ++<*>"/plugin/" { ++ DPRINT("Keyword: /plugin/\n"); ++ return DT_PLUGIN; ++ } ++ + <*>"/memreserve/" { + DPRINT("Keyword: /memreserve/\n"); + BEGIN_DEFAULT(); +diff --git a/scripts/dtc/dtc-lexer.lex.c_shipped b/scripts/dtc/dtc-lexer.lex.c_shipped +index ba525c2..39b9f60 100644 +--- a/scripts/dtc/dtc-lexer.lex.c_shipped ++++ b/scripts/dtc/dtc-lexer.lex.c_shipped +@@ -9,7 +9,7 @@ + #define FLEX_SCANNER + #define YY_FLEX_MAJOR_VERSION 2 + #define YY_FLEX_MINOR_VERSION 5 +-#define YY_FLEX_SUBMINOR_VERSION 39 ++#define YY_FLEX_SUBMINOR_VERSION 35 + #if YY_FLEX_SUBMINOR_VERSION > 0 + #define FLEX_BETA + #endif +@@ -162,12 +162,7 @@ typedef unsigned int flex_uint32_t; + typedef struct yy_buffer_state *YY_BUFFER_STATE; + #endif + +-#ifndef YY_TYPEDEF_YY_SIZE_T +-#define YY_TYPEDEF_YY_SIZE_T +-typedef size_t yy_size_t; +-#endif +- +-extern yy_size_t yyleng; ++extern int yyleng; + + extern FILE *yyin, *yyout; + +@@ -176,7 +171,6 @@ extern FILE *yyin, *yyout; + #define EOB_ACT_LAST_MATCH 2 + + #define YY_LESS_LINENO(n) +- #define YY_LINENO_REWIND_TO(ptr) + + /* Return all but the first "n" matched characters back to the input stream. */ + #define yyless(n) \ +@@ -194,6 +188,11 @@ extern FILE *yyin, *yyout; + + #define unput(c) yyunput( c, (yytext_ptr) ) + ++#ifndef YY_TYPEDEF_YY_SIZE_T ++#define YY_TYPEDEF_YY_SIZE_T ++typedef size_t yy_size_t; ++#endif ++ + #ifndef YY_STRUCT_YY_BUFFER_STATE + #define YY_STRUCT_YY_BUFFER_STATE + struct yy_buffer_state +@@ -211,7 +210,7 @@ struct yy_buffer_state + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ +- yy_size_t yy_n_chars; ++ int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to +@@ -281,8 +280,8 @@ static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ + + /* yy_hold_char holds the character lost when yytext is formed. */ + static char yy_hold_char; +-static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */ +-yy_size_t yyleng; ++static int yy_n_chars; /* number of characters read into yy_ch_buf */ ++int yyleng; + + /* Points to current character in buffer. */ + static char *yy_c_buf_p = (char *) 0; +@@ -310,7 +309,7 @@ static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); + + YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); + YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); +-YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len ); ++YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ); + + void *yyalloc (yy_size_t ); + void *yyrealloc (void *,yy_size_t ); +@@ -342,7 +341,7 @@ void yyfree (void * ); + + /* Begin user sect3 */ + +-#define yywrap() 1 ++#define yywrap(n) 1 + #define YY_SKIP_YYWRAP + + typedef unsigned char YY_CHAR; +@@ -373,8 +372,8 @@ static void yy_fatal_error (yyconst char msg[] ); + *yy_cp = '\0'; \ + (yy_c_buf_p) = yy_cp; + +-#define YY_NUM_RULES 30 +-#define YY_END_OF_BUFFER 31 ++#define YY_NUM_RULES 31 ++#define YY_END_OF_BUFFER 32 + /* This struct is not used in this scanner, + but its presence is necessary. */ + struct yy_trans_info +@@ -382,25 +381,26 @@ struct yy_trans_info + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +-static yyconst flex_int16_t yy_accept[159] = ++static yyconst flex_int16_t yy_accept[166] = + { 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 31, 29, +- 18, 18, 29, 29, 29, 29, 29, 29, 29, 29, +- 29, 29, 29, 29, 29, 29, 15, 16, 16, 29, +- 16, 10, 10, 18, 26, 0, 3, 0, 27, 12, +- 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, +- 21, 23, 25, 24, 22, 0, 9, 28, 0, 0, +- 0, 14, 14, 16, 16, 16, 10, 10, 10, 0, +- 12, 0, 11, 0, 0, 0, 20, 0, 0, 0, +- 0, 0, 0, 0, 0, 16, 10, 10, 10, 0, +- 13, 19, 0, 0, 0, 0, 0, 0, 0, 0, +- +- 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 16, 6, 0, 0, 0, 0, 0, 0, 2, +- 0, 0, 0, 0, 0, 0, 0, 0, 4, 17, +- 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, +- 5, 8, 0, 0, 0, 0, 7, 0 ++ 0, 0, 0, 0, 0, 0, 0, 0, 32, 30, ++ 19, 19, 30, 30, 30, 30, 30, 30, 30, 30, ++ 30, 30, 30, 30, 30, 30, 16, 17, 17, 30, ++ 17, 11, 11, 19, 27, 0, 3, 0, 28, 13, ++ 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, ++ 0, 22, 24, 26, 25, 23, 0, 10, 29, 0, ++ 0, 0, 15, 15, 17, 17, 17, 11, 11, 11, ++ 0, 13, 0, 12, 0, 0, 0, 21, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 17, 11, 11, ++ 11, 0, 14, 20, 0, 0, 0, 0, 0, 0, ++ ++ 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 17, 7, 0, 0, 0, ++ 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 4, 18, 0, 0, 5, 2, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 1, 0, 0, 0, 0, 6, 9, 0, ++ 0, 0, 0, 8, 0 + } ; + + static yyconst flex_int32_t yy_ec[256] = +@@ -416,9 +416,9 @@ static yyconst flex_int32_t yy_ec[256] = + 22, 22, 22, 22, 24, 22, 22, 25, 22, 22, + 1, 26, 27, 1, 22, 1, 21, 28, 29, 30, + +- 31, 21, 22, 22, 32, 22, 22, 33, 34, 35, +- 36, 37, 22, 38, 39, 40, 41, 42, 22, 25, +- 43, 22, 44, 45, 46, 1, 1, 1, 1, 1, ++ 31, 21, 32, 22, 33, 22, 22, 34, 35, 36, ++ 37, 38, 22, 39, 40, 41, 42, 43, 22, 25, ++ 44, 22, 45, 46, 47, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +@@ -435,163 +435,165 @@ static yyconst flex_int32_t yy_ec[256] = + 1, 1, 1, 1, 1 + } ; + +-static yyconst flex_int32_t yy_meta[47] = ++static yyconst flex_int32_t yy_meta[48] = + { 0, + 1, 1, 1, 1, 1, 1, 2, 3, 1, 2, + 2, 2, 4, 5, 5, 5, 6, 1, 1, 1, + 7, 8, 8, 8, 8, 1, 1, 7, 7, 7, + 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, +- 8, 8, 8, 3, 1, 4 ++ 8, 8, 8, 8, 3, 1, 4 + } ; + +-static yyconst flex_int16_t yy_base[173] = ++static yyconst flex_int16_t yy_base[180] = + { 0, +- 0, 383, 34, 382, 65, 381, 37, 105, 387, 391, +- 54, 111, 367, 110, 109, 109, 112, 41, 366, 104, +- 367, 338, 124, 117, 0, 144, 391, 0, 121, 0, +- 135, 155, 140, 179, 391, 160, 391, 379, 391, 0, +- 368, 141, 391, 167, 370, 376, 346, 103, 342, 345, +- 391, 391, 391, 391, 391, 358, 391, 391, 175, 342, +- 338, 391, 355, 0, 185, 339, 184, 347, 346, 0, +- 0, 322, 175, 357, 175, 363, 352, 324, 330, 323, +- 332, 326, 201, 324, 329, 322, 391, 333, 181, 309, +- 391, 341, 340, 313, 320, 338, 178, 311, 146, 317, +- +- 314, 315, 335, 331, 303, 300, 309, 299, 308, 188, +- 336, 335, 391, 305, 320, 281, 283, 271, 203, 288, +- 281, 271, 266, 264, 245, 242, 208, 104, 391, 391, +- 244, 218, 204, 219, 206, 224, 201, 212, 204, 229, +- 215, 208, 207, 200, 219, 391, 233, 221, 200, 181, +- 391, 391, 149, 122, 86, 41, 391, 391, 245, 251, +- 259, 263, 267, 273, 280, 284, 292, 300, 304, 310, +- 318, 326 ++ 0, 393, 35, 392, 66, 391, 38, 107, 397, 401, ++ 55, 113, 377, 112, 111, 111, 114, 42, 376, 106, ++ 377, 347, 126, 120, 0, 147, 401, 0, 124, 0, ++ 137, 158, 170, 163, 401, 153, 401, 389, 401, 0, ++ 378, 120, 401, 131, 380, 386, 355, 139, 351, 355, ++ 351, 401, 401, 401, 401, 401, 367, 401, 401, 185, ++ 350, 346, 401, 364, 0, 185, 347, 189, 356, 355, ++ 0, 0, 330, 180, 366, 141, 372, 361, 332, 338, ++ 331, 341, 334, 326, 205, 331, 337, 329, 401, 341, ++ 167, 316, 401, 349, 348, 320, 328, 346, 180, 318, ++ ++ 324, 209, 324, 320, 322, 342, 338, 309, 306, 315, ++ 305, 315, 312, 192, 342, 341, 401, 293, 306, 282, ++ 268, 252, 255, 203, 285, 282, 272, 268, 252, 233, ++ 232, 239, 208, 107, 401, 401, 238, 211, 401, 211, ++ 212, 208, 228, 203, 215, 207, 233, 222, 212, 211, ++ 203, 227, 401, 237, 225, 204, 185, 401, 401, 149, ++ 128, 88, 42, 401, 401, 253, 259, 267, 271, 275, ++ 281, 288, 292, 300, 308, 312, 318, 326, 334 + } ; + +-static yyconst flex_int16_t yy_def[173] = ++static yyconst flex_int16_t yy_def[180] = + { 0, +- 158, 1, 1, 3, 158, 5, 1, 1, 158, 158, +- 158, 158, 158, 159, 160, 161, 158, 158, 158, 158, +- 162, 158, 158, 158, 163, 162, 158, 164, 165, 164, +- 164, 158, 158, 158, 158, 159, 158, 159, 158, 166, +- 158, 161, 158, 161, 167, 168, 158, 158, 158, 158, +- 158, 158, 158, 158, 158, 162, 158, 158, 158, 158, +- 158, 158, 162, 164, 165, 164, 158, 158, 158, 169, +- 166, 170, 161, 167, 167, 168, 158, 158, 158, 158, +- 158, 158, 158, 158, 158, 164, 158, 158, 169, 170, +- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, +- +- 158, 164, 158, 158, 158, 158, 158, 158, 158, 171, +- 158, 164, 158, 158, 158, 158, 158, 158, 171, 158, +- 171, 158, 158, 158, 158, 158, 158, 158, 158, 158, +- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, +- 172, 158, 158, 158, 172, 158, 172, 158, 158, 158, +- 158, 158, 158, 158, 158, 158, 158, 0, 158, 158, +- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, +- 158, 158 ++ 165, 1, 1, 3, 165, 5, 1, 1, 165, 165, ++ 165, 165, 165, 166, 167, 168, 165, 165, 165, 165, ++ 169, 165, 165, 165, 170, 169, 165, 171, 172, 171, ++ 171, 165, 165, 165, 165, 166, 165, 166, 165, 173, ++ 165, 168, 165, 168, 174, 175, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 169, 165, 165, 165, ++ 165, 165, 165, 169, 171, 172, 171, 165, 165, 165, ++ 176, 173, 177, 168, 174, 174, 175, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 171, 165, 165, ++ 176, 177, 165, 165, 165, 165, 165, 165, 165, 165, ++ ++ 165, 165, 165, 165, 171, 165, 165, 165, 165, 165, ++ 165, 165, 165, 178, 165, 171, 165, 165, 165, 165, ++ 165, 165, 165, 178, 165, 178, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 179, 165, 165, ++ 165, 179, 165, 179, 165, 165, 165, 165, 165, 165, ++ 165, 165, 165, 165, 0, 165, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 165, 165 + } ; + +-static yyconst flex_int16_t yy_nxt[438] = ++static yyconst flex_int16_t yy_nxt[449] = + { 0, + 10, 11, 12, 11, 13, 14, 10, 15, 16, 10, + 10, 10, 17, 10, 10, 10, 10, 18, 19, 20, + 21, 21, 21, 21, 21, 10, 10, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, +- 21, 21, 21, 10, 22, 10, 24, 25, 25, 25, +- 32, 33, 33, 157, 26, 34, 34, 34, 51, 52, +- 27, 26, 26, 26, 26, 10, 11, 12, 11, 13, +- 14, 28, 15, 16, 28, 28, 28, 24, 28, 28, +- 28, 10, 18, 19, 20, 29, 29, 29, 29, 29, +- 30, 10, 29, 29, 29, 29, 29, 29, 29, 29, +- +- 29, 29, 29, 29, 29, 29, 29, 29, 10, 22, +- 10, 23, 34, 34, 34, 37, 39, 43, 32, 33, +- 33, 45, 54, 55, 46, 59, 45, 64, 156, 46, +- 64, 64, 64, 79, 44, 38, 59, 57, 134, 47, +- 135, 48, 80, 49, 47, 50, 48, 99, 61, 43, +- 50, 110, 41, 67, 67, 67, 60, 63, 63, 63, +- 57, 155, 68, 69, 63, 37, 44, 66, 67, 67, +- 67, 63, 63, 63, 63, 73, 59, 68, 69, 70, +- 34, 34, 34, 43, 75, 38, 154, 92, 83, 83, +- 83, 64, 44, 120, 64, 64, 64, 67, 67, 67, +- +- 44, 57, 99, 68, 69, 107, 68, 69, 120, 127, +- 108, 153, 152, 121, 83, 83, 83, 133, 133, 133, +- 146, 133, 133, 133, 146, 140, 140, 140, 121, 141, +- 140, 140, 140, 151, 141, 158, 150, 149, 148, 144, +- 147, 143, 142, 139, 147, 36, 36, 36, 36, 36, +- 36, 36, 36, 40, 138, 137, 136, 40, 40, 42, +- 42, 42, 42, 42, 42, 42, 42, 56, 56, 56, +- 56, 62, 132, 62, 64, 131, 130, 64, 129, 64, +- 64, 65, 128, 158, 65, 65, 65, 65, 71, 127, +- 71, 71, 74, 74, 74, 74, 74, 74, 74, 74, +- +- 76, 76, 76, 76, 76, 76, 76, 76, 89, 126, +- 89, 90, 125, 90, 90, 124, 90, 90, 119, 119, +- 119, 119, 119, 119, 119, 119, 145, 145, 145, 145, +- 145, 145, 145, 145, 123, 122, 59, 59, 118, 117, +- 116, 115, 114, 113, 45, 112, 108, 111, 109, 106, +- 105, 104, 46, 103, 91, 87, 102, 101, 100, 98, +- 97, 96, 95, 94, 93, 77, 75, 91, 88, 87, +- 86, 57, 85, 84, 57, 82, 81, 78, 77, 75, +- 72, 158, 58, 57, 53, 35, 158, 31, 23, 23, +- 9, 158, 158, 158, 158, 158, 158, 158, 158, 158, +- +- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, +- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, +- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, +- 158, 158, 158, 158, 158, 158, 158 ++ 21, 21, 21, 21, 10, 22, 10, 24, 25, 25, ++ 25, 32, 33, 33, 164, 26, 34, 34, 34, 52, ++ 53, 27, 26, 26, 26, 26, 10, 11, 12, 11, ++ 13, 14, 28, 15, 16, 28, 28, 28, 24, 28, ++ 28, 28, 10, 18, 19, 20, 29, 29, 29, 29, ++ 29, 30, 10, 29, 29, 29, 29, 29, 29, 29, ++ ++ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, ++ 10, 22, 10, 23, 34, 34, 34, 37, 39, 43, ++ 32, 33, 33, 45, 55, 56, 46, 60, 43, 45, ++ 65, 163, 46, 65, 65, 65, 44, 38, 60, 74, ++ 58, 47, 141, 48, 142, 44, 49, 47, 50, 48, ++ 76, 51, 62, 94, 50, 41, 44, 51, 37, 61, ++ 64, 64, 64, 58, 34, 34, 34, 64, 162, 80, ++ 67, 68, 68, 68, 64, 64, 64, 64, 38, 81, ++ 69, 70, 71, 68, 68, 68, 60, 161, 43, 69, ++ 70, 65, 69, 70, 65, 65, 65, 125, 85, 85, ++ ++ 85, 58, 68, 68, 68, 44, 102, 110, 125, 133, ++ 102, 69, 70, 111, 114, 160, 159, 126, 85, 85, ++ 85, 140, 140, 140, 140, 140, 140, 153, 126, 147, ++ 147, 147, 153, 148, 147, 147, 147, 158, 148, 165, ++ 157, 156, 155, 151, 150, 149, 146, 154, 145, 144, ++ 143, 139, 154, 36, 36, 36, 36, 36, 36, 36, ++ 36, 40, 138, 137, 136, 40, 40, 42, 42, 42, ++ 42, 42, 42, 42, 42, 57, 57, 57, 57, 63, ++ 135, 63, 65, 134, 165, 65, 133, 65, 65, 66, ++ 132, 131, 66, 66, 66, 66, 72, 130, 72, 72, ++ ++ 75, 75, 75, 75, 75, 75, 75, 75, 77, 77, ++ 77, 77, 77, 77, 77, 77, 91, 129, 91, 92, ++ 128, 92, 92, 127, 92, 92, 124, 124, 124, 124, ++ 124, 124, 124, 124, 152, 152, 152, 152, 152, 152, ++ 152, 152, 60, 60, 123, 122, 121, 120, 119, 118, ++ 117, 45, 116, 111, 115, 113, 112, 109, 108, 107, ++ 46, 106, 93, 89, 105, 104, 103, 101, 100, 99, ++ 98, 97, 96, 95, 78, 76, 93, 90, 89, 88, ++ 58, 87, 86, 58, 84, 83, 82, 79, 78, 76, ++ 73, 165, 59, 58, 54, 35, 165, 31, 23, 23, ++ ++ 9, 165, 165, 165, 165, 165, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 165 + } ; + +-static yyconst flex_int16_t yy_chk[438] = ++static yyconst flex_int16_t yy_chk[449] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, +- 7, 7, 7, 156, 3, 11, 11, 11, 18, 18, +- 3, 3, 3, 3, 3, 5, 5, 5, 5, 5, ++ 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, ++ 3, 7, 7, 7, 163, 3, 11, 11, 11, 18, ++ 18, 3, 3, 3, 3, 3, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, +- 5, 8, 12, 12, 12, 14, 15, 16, 8, 8, +- 8, 17, 20, 20, 17, 23, 24, 29, 155, 24, +- 29, 29, 29, 48, 16, 14, 31, 29, 128, 17, +- 128, 17, 48, 17, 24, 17, 24, 99, 24, 42, +- 24, 99, 15, 33, 33, 33, 23, 26, 26, 26, +- 26, 154, 33, 33, 26, 36, 42, 31, 32, 32, +- 32, 26, 26, 26, 26, 44, 59, 32, 32, 32, +- 34, 34, 34, 73, 75, 36, 153, 75, 59, 59, +- 59, 65, 44, 110, 65, 65, 65, 67, 67, 67, +- +- 73, 65, 83, 89, 89, 97, 67, 67, 119, 127, +- 97, 150, 149, 110, 83, 83, 83, 133, 133, 133, +- 141, 127, 127, 127, 145, 136, 136, 136, 119, 136, +- 140, 140, 140, 148, 140, 147, 144, 143, 142, 139, +- 141, 138, 137, 135, 145, 159, 159, 159, 159, 159, +- 159, 159, 159, 160, 134, 132, 131, 160, 160, 161, +- 161, 161, 161, 161, 161, 161, 161, 162, 162, 162, +- 162, 163, 126, 163, 164, 125, 124, 164, 123, 164, +- 164, 165, 122, 121, 165, 165, 165, 165, 166, 120, +- 166, 166, 167, 167, 167, 167, 167, 167, 167, 167, +- +- 168, 168, 168, 168, 168, 168, 168, 168, 169, 118, +- 169, 170, 117, 170, 170, 116, 170, 170, 171, 171, +- 171, 171, 171, 171, 171, 171, 172, 172, 172, 172, +- 172, 172, 172, 172, 115, 114, 112, 111, 109, 108, +- 107, 106, 105, 104, 103, 102, 101, 100, 98, 96, +- 95, 94, 93, 92, 90, 88, 86, 85, 84, 82, +- 81, 80, 79, 78, 77, 76, 74, 72, 69, 68, +- 66, 63, 61, 60, 56, 50, 49, 47, 46, 45, ++ 5, 5, 5, 8, 12, 12, 12, 14, 15, 16, ++ 8, 8, 8, 17, 20, 20, 17, 23, 42, 24, ++ 29, 162, 24, 29, 29, 29, 16, 14, 31, 44, ++ 29, 17, 134, 17, 134, 42, 17, 24, 17, 24, ++ 76, 17, 24, 76, 24, 15, 44, 24, 36, 23, ++ 26, 26, 26, 26, 34, 34, 34, 26, 161, 48, ++ 31, 32, 32, 32, 26, 26, 26, 26, 36, 48, ++ 32, 32, 32, 33, 33, 33, 60, 160, 74, 91, ++ 91, 66, 33, 33, 66, 66, 66, 114, 60, 60, ++ ++ 60, 66, 68, 68, 68, 74, 85, 99, 124, 133, ++ 102, 68, 68, 99, 102, 157, 156, 114, 85, 85, ++ 85, 133, 133, 133, 140, 140, 140, 148, 124, 143, ++ 143, 143, 152, 143, 147, 147, 147, 155, 147, 154, ++ 151, 150, 149, 146, 145, 144, 142, 148, 141, 138, ++ 137, 132, 152, 166, 166, 166, 166, 166, 166, 166, ++ 166, 167, 131, 130, 129, 167, 167, 168, 168, 168, ++ 168, 168, 168, 168, 168, 169, 169, 169, 169, 170, ++ 128, 170, 171, 127, 126, 171, 125, 171, 171, 172, ++ 123, 122, 172, 172, 172, 172, 173, 121, 173, 173, ++ ++ 174, 174, 174, 174, 174, 174, 174, 174, 175, 175, ++ 175, 175, 175, 175, 175, 175, 176, 120, 176, 177, ++ 119, 177, 177, 118, 177, 177, 178, 178, 178, 178, ++ 178, 178, 178, 178, 179, 179, 179, 179, 179, 179, ++ 179, 179, 116, 115, 113, 112, 111, 110, 109, 108, ++ 107, 106, 105, 104, 103, 101, 100, 98, 97, 96, ++ 95, 94, 92, 90, 88, 87, 86, 84, 83, 82, ++ 81, 80, 79, 78, 77, 75, 73, 70, 69, 67, ++ 64, 62, 61, 57, 51, 50, 49, 47, 46, 45, + 41, 38, 22, 21, 19, 13, 9, 6, 4, 2, +- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + +- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, +- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, +- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, +- 158, 158, 158, 158, 158, 158, 158 ++ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, ++ 165, 165, 165, 165, 165, 165, 165, 165 + } ; + + static yy_state_type yy_last_accepting_state; +@@ -662,7 +664,7 @@ static int dts_version = 1; + static void push_input_file(const char *filename); + static bool pop_input_file(void); + static void lexical_error(const char *fmt, ...); +-#line 666 "dtc-lexer.lex.c" ++#line 668 "dtc-lexer.lex.c" + + #define INITIAL 0 + #define BYTESTRING 1 +@@ -704,7 +706,7 @@ FILE *yyget_out (void ); + + void yyset_out (FILE * out_str ); + +-yy_size_t yyget_leng (void ); ++int yyget_leng (void ); + + char *yyget_text (void ); + +@@ -853,6 +855,10 @@ YY_DECL + register char *yy_cp, *yy_bp; + register int yy_act; + ++#line 68 "dtc-lexer.l" ++ ++#line 861 "dtc-lexer.lex.c" ++ + if ( !(yy_init) ) + { + (yy_init) = 1; +@@ -879,11 +885,6 @@ YY_DECL + yy_load_buffer_state( ); + } + +- { +-#line 68 "dtc-lexer.l" +- +-#line 886 "dtc-lexer.lex.c" +- + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = (yy_c_buf_p); +@@ -901,7 +902,7 @@ YY_DECL + yy_match: + do + { +- register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; ++ register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; +@@ -910,13 +911,13 @@ yy_match: + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; +- if ( yy_current_state >= 159 ) ++ if ( yy_current_state >= 166 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + ++yy_cp; + } +- while ( yy_current_state != 158 ); ++ while ( yy_current_state != 165 ); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + +@@ -1015,23 +1016,31 @@ case 5: + YY_RULE_SETUP + #line 124 "dtc-lexer.l" + { ++ DPRINT("Keyword: /plugin/\n"); ++ return DT_PLUGIN; ++ } ++ YY_BREAK ++case 6: ++YY_RULE_SETUP ++#line 129 "dtc-lexer.l" ++{ + DPRINT("Keyword: /memreserve/\n"); + BEGIN_DEFAULT(); + return DT_MEMRESERVE; + } + YY_BREAK +-case 6: ++case 7: + YY_RULE_SETUP +-#line 130 "dtc-lexer.l" ++#line 135 "dtc-lexer.l" + { + DPRINT("Keyword: /bits/\n"); + BEGIN_DEFAULT(); + return DT_BITS; + } + YY_BREAK +-case 7: ++case 8: + YY_RULE_SETUP +-#line 136 "dtc-lexer.l" ++#line 141 "dtc-lexer.l" + { + DPRINT("Keyword: /delete-property/\n"); + DPRINT("<PROPNODENAME>\n"); +@@ -1039,9 +1048,9 @@ YY_RULE_SETUP + return DT_DEL_PROP; + } + YY_BREAK +-case 8: ++case 9: + YY_RULE_SETUP +-#line 143 "dtc-lexer.l" ++#line 148 "dtc-lexer.l" + { + DPRINT("Keyword: /delete-node/\n"); + DPRINT("<PROPNODENAME>\n"); +@@ -1049,9 +1058,9 @@ YY_RULE_SETUP + return DT_DEL_NODE; + } + YY_BREAK +-case 9: ++case 10: + YY_RULE_SETUP +-#line 150 "dtc-lexer.l" ++#line 155 "dtc-lexer.l" + { + DPRINT("Label: %s\n", yytext); + yylval.labelref = xstrdup(yytext); +@@ -1059,9 +1068,9 @@ YY_RULE_SETUP + return DT_LABEL; + } + YY_BREAK +-case 10: ++case 11: + YY_RULE_SETUP +-#line 157 "dtc-lexer.l" ++#line 162 "dtc-lexer.l" + { + char *e; + DPRINT("Integer Literal: '%s'\n", yytext); +@@ -1084,10 +1093,10 @@ YY_RULE_SETUP + return DT_LITERAL; + } + YY_BREAK +-case 11: +-/* rule 11 can match eol */ ++case 12: ++/* rule 12 can match eol */ + YY_RULE_SETUP +-#line 179 "dtc-lexer.l" ++#line 184 "dtc-lexer.l" + { + struct data d; + DPRINT("Character literal: %s\n", yytext); +@@ -1109,18 +1118,18 @@ YY_RULE_SETUP + return DT_CHAR_LITERAL; + } + YY_BREAK +-case 12: ++case 13: + YY_RULE_SETUP +-#line 200 "dtc-lexer.l" ++#line 205 "dtc-lexer.l" + { /* label reference */ + DPRINT("Ref: %s\n", yytext+1); + yylval.labelref = xstrdup(yytext+1); + return DT_REF; + } + YY_BREAK +-case 13: ++case 14: + YY_RULE_SETUP +-#line 206 "dtc-lexer.l" ++#line 211 "dtc-lexer.l" + { /* new-style path reference */ + yytext[yyleng-1] = '\0'; + DPRINT("Ref: %s\n", yytext+2); +@@ -1128,27 +1137,27 @@ YY_RULE_SETUP + return DT_REF; + } + YY_BREAK +-case 14: ++case 15: + YY_RULE_SETUP +-#line 213 "dtc-lexer.l" ++#line 218 "dtc-lexer.l" + { + yylval.byte = strtol(yytext, NULL, 16); + DPRINT("Byte: %02x\n", (int)yylval.byte); + return DT_BYTE; + } + YY_BREAK +-case 15: ++case 16: + YY_RULE_SETUP +-#line 219 "dtc-lexer.l" ++#line 224 "dtc-lexer.l" + { + DPRINT("/BYTESTRING\n"); + BEGIN_DEFAULT(); + return ']'; + } + YY_BREAK +-case 16: ++case 17: + YY_RULE_SETUP +-#line 225 "dtc-lexer.l" ++#line 230 "dtc-lexer.l" + { + DPRINT("PropNodeName: %s\n", yytext); + yylval.propnodename = xstrdup((yytext[0] == '\\') ? +@@ -1157,75 +1166,75 @@ YY_RULE_SETUP + return DT_PROPNODENAME; + } + YY_BREAK +-case 17: ++case 18: + YY_RULE_SETUP +-#line 233 "dtc-lexer.l" ++#line 238 "dtc-lexer.l" + { + DPRINT("Binary Include\n"); + return DT_INCBIN; + } + YY_BREAK +-case 18: +-/* rule 18 can match eol */ +-YY_RULE_SETUP +-#line 238 "dtc-lexer.l" +-/* eat whitespace */ +- YY_BREAK + case 19: + /* rule 19 can match eol */ + YY_RULE_SETUP +-#line 239 "dtc-lexer.l" +-/* eat C-style comments */ ++#line 243 "dtc-lexer.l" ++/* eat whitespace */ + YY_BREAK + case 20: + /* rule 20 can match eol */ + YY_RULE_SETUP +-#line 240 "dtc-lexer.l" +-/* eat C++-style comments */ ++#line 244 "dtc-lexer.l" ++/* eat C-style comments */ + YY_BREAK + case 21: ++/* rule 21 can match eol */ + YY_RULE_SETUP +-#line 242 "dtc-lexer.l" +-{ return DT_LSHIFT; }; ++#line 245 "dtc-lexer.l" ++/* eat C++-style comments */ + YY_BREAK + case 22: + YY_RULE_SETUP +-#line 243 "dtc-lexer.l" +-{ return DT_RSHIFT; }; ++#line 247 "dtc-lexer.l" ++{ return DT_LSHIFT; }; + YY_BREAK + case 23: + YY_RULE_SETUP +-#line 244 "dtc-lexer.l" +-{ return DT_LE; }; ++#line 248 "dtc-lexer.l" ++{ return DT_RSHIFT; }; + YY_BREAK + case 24: + YY_RULE_SETUP +-#line 245 "dtc-lexer.l" +-{ return DT_GE; }; ++#line 249 "dtc-lexer.l" ++{ return DT_LE; }; + YY_BREAK + case 25: + YY_RULE_SETUP +-#line 246 "dtc-lexer.l" +-{ return DT_EQ; }; ++#line 250 "dtc-lexer.l" ++{ return DT_GE; }; + YY_BREAK + case 26: + YY_RULE_SETUP +-#line 247 "dtc-lexer.l" +-{ return DT_NE; }; ++#line 251 "dtc-lexer.l" ++{ return DT_EQ; }; + YY_BREAK + case 27: + YY_RULE_SETUP +-#line 248 "dtc-lexer.l" +-{ return DT_AND; }; ++#line 252 "dtc-lexer.l" ++{ return DT_NE; }; + YY_BREAK + case 28: + YY_RULE_SETUP +-#line 249 "dtc-lexer.l" +-{ return DT_OR; }; ++#line 253 "dtc-lexer.l" ++{ return DT_AND; }; + YY_BREAK + case 29: + YY_RULE_SETUP +-#line 251 "dtc-lexer.l" ++#line 254 "dtc-lexer.l" ++{ return DT_OR; }; ++ YY_BREAK ++case 30: ++YY_RULE_SETUP ++#line 256 "dtc-lexer.l" + { + DPRINT("Char: %c (\\x%02x)\n", yytext[0], + (unsigned)yytext[0]); +@@ -1241,12 +1250,12 @@ YY_RULE_SETUP + return yytext[0]; + } + YY_BREAK +-case 30: ++case 31: + YY_RULE_SETUP +-#line 266 "dtc-lexer.l" ++#line 271 "dtc-lexer.l" + ECHO; + YY_BREAK +-#line 1250 "dtc-lexer.lex.c" ++#line 1259 "dtc-lexer.lex.c" + + case YY_END_OF_BUFFER: + { +@@ -1376,7 +1385,6 @@ ECHO; + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ +- } /* end of user's declarations */ + } /* end of yylex */ + + /* yy_get_next_buffer - try to read in a new buffer +@@ -1432,21 +1440,21 @@ static int yy_get_next_buffer (void) + + else + { +- yy_size_t num_to_read = ++ int num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ +- YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; ++ YY_BUFFER_STATE b = YY_CURRENT_BUFFER; + + int yy_c_buf_p_offset = + (int) ((yy_c_buf_p) - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { +- yy_size_t new_size = b->yy_buf_size * 2; ++ int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; +@@ -1477,7 +1485,7 @@ static int yy_get_next_buffer (void) + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), +- (yy_n_chars), num_to_read ); ++ (yy_n_chars), (size_t) num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } +@@ -1539,7 +1547,7 @@ static int yy_get_next_buffer (void) + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; +- if ( yy_current_state >= 159 ) ++ if ( yy_current_state >= 166 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; +@@ -1567,13 +1575,13 @@ static int yy_get_next_buffer (void) + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; +- if ( yy_current_state >= 159 ) ++ if ( yy_current_state >= 166 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; +- yy_is_jam = (yy_current_state == 158); ++ yy_is_jam = (yy_current_state == 165); + +- return yy_is_jam ? 0 : yy_current_state; ++ return yy_is_jam ? 0 : yy_current_state; + } + + #ifndef YY_NO_INPUT +@@ -1600,7 +1608,7 @@ static int yy_get_next_buffer (void) + + else + { /* need more input */ +- yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); ++ int offset = (yy_c_buf_p) - (yytext_ptr); + ++(yy_c_buf_p); + + switch ( yy_get_next_buffer( ) ) +@@ -1874,7 +1882,7 @@ void yypop_buffer_state (void) + */ + static void yyensure_buffer_stack (void) + { +- yy_size_t num_to_alloc; ++ int num_to_alloc; + + if (!(yy_buffer_stack)) { + +@@ -1971,12 +1979,12 @@ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) + * + * @return the newly allocated buffer state object. + */ +-YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len ) ++YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len ) + { + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; +- yy_size_t i; ++ int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = _yybytes_len + 2; +@@ -2058,7 +2066,7 @@ FILE *yyget_out (void) + /** Get the length of the current token. + * + */ +-yy_size_t yyget_leng (void) ++int yyget_leng (void) + { + return yyleng; + } +@@ -2206,7 +2214,7 @@ void yyfree (void * ptr ) + + #define YYTABLES_NAME "yytables" + +-#line 265 "dtc-lexer.l" ++#line 271 "dtc-lexer.l" + + + +diff --git a/scripts/dtc/dtc-parser.tab.c_shipped b/scripts/dtc/dtc-parser.tab.c_shipped +index 31cec50..ed31164 100644 +--- a/scripts/dtc/dtc-parser.tab.c_shipped ++++ b/scripts/dtc/dtc-parser.tab.c_shipped +@@ -1,19 +1,21 @@ +-/* A Bison parser, made by GNU Bison 3.0.2. */ + +-/* Bison implementation for Yacc-like parsers in C +- +- Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. ++/* A Bison parser, made by GNU Bison 2.4.1. */ + ++/* Skeleton implementation for Bison's Yacc-like parsers in C ++ ++ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 ++ Free Software Foundation, Inc. ++ + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. +- ++ + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. +- ++ + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +@@ -26,7 +28,7 @@ + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. +- ++ + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +@@ -44,7 +46,7 @@ + #define YYBISON 1 + + /* Bison version. */ +-#define YYBISON_VERSION "3.0.2" ++#define YYBISON_VERSION "2.4.1" + + /* Skeleton name. */ + #define YYSKELETON_NAME "yacc.c" +@@ -58,13 +60,18 @@ + /* Pull parsers. */ + #define YYPULL 1 + ++/* Using locations. */ ++#define YYLSP_NEEDED 1 + + + + /* Copy the first part of user declarations. */ +-#line 20 "dtc-parser.y" /* yacc.c:339 */ ++ ++/* Line 189 of yacc.c */ ++#line 20 "dtc-parser.y" + + #include <stdio.h> ++#include <inttypes.h> + + #include "dtc.h" + #include "srcpos.h" +@@ -80,15 +87,14 @@ extern void yyerror(char const *s); + extern struct boot_info *the_boot_info; + extern bool treesource_error; + +-#line 84 "dtc-parser.tab.c" /* yacc.c:339 */ + +-# ifndef YY_NULLPTR +-# if defined __cplusplus && 201103L <= __cplusplus +-# define YY_NULLPTR nullptr +-# else +-# define YY_NULLPTR 0 +-# endif +-# endif ++/* Line 189 of yacc.c */ ++#line 93 "dtc-parser.tab.c" ++ ++/* Enabling traces. */ ++#ifndef YYDEBUG ++# define YYDEBUG 0 ++#endif + + /* Enabling verbose error messages. */ + #ifdef YYERROR_VERBOSE +@@ -98,53 +104,51 @@ extern bool treesource_error; + # define YYERROR_VERBOSE 0 + #endif + +-/* In a future release of Bison, this section will be replaced +- by #include "dtc-parser.tab.h". */ +-#ifndef YY_YY_DTC_PARSER_TAB_H_INCLUDED +-# define YY_YY_DTC_PARSER_TAB_H_INCLUDED +-/* Debug traces. */ +-#ifndef YYDEBUG +-# define YYDEBUG 0 +-#endif +-#if YYDEBUG +-extern int yydebug; ++/* Enabling the token table. */ ++#ifndef YYTOKEN_TABLE ++# define YYTOKEN_TABLE 0 + #endif + +-/* Token type. */ ++ ++/* Tokens. */ + #ifndef YYTOKENTYPE + # define YYTOKENTYPE +- enum yytokentype +- { +- DT_V1 = 258, +- DT_MEMRESERVE = 259, +- DT_LSHIFT = 260, +- DT_RSHIFT = 261, +- DT_LE = 262, +- DT_GE = 263, +- DT_EQ = 264, +- DT_NE = 265, +- DT_AND = 266, +- DT_OR = 267, +- DT_BITS = 268, +- DT_DEL_PROP = 269, +- DT_DEL_NODE = 270, +- DT_PROPNODENAME = 271, +- DT_LITERAL = 272, +- DT_CHAR_LITERAL = 273, +- DT_BYTE = 274, +- DT_STRING = 275, +- DT_LABEL = 276, +- DT_REF = 277, +- DT_INCBIN = 278 +- }; ++ /* Put the tokens into the symbol table, so that GDB and other debuggers ++ know about them. */ ++ enum yytokentype { ++ DT_V1 = 258, ++ DT_PLUGIN = 259, ++ DT_MEMRESERVE = 260, ++ DT_LSHIFT = 261, ++ DT_RSHIFT = 262, ++ DT_LE = 263, ++ DT_GE = 264, ++ DT_EQ = 265, ++ DT_NE = 266, ++ DT_AND = 267, ++ DT_OR = 268, ++ DT_BITS = 269, ++ DT_DEL_PROP = 270, ++ DT_DEL_NODE = 271, ++ DT_PROPNODENAME = 272, ++ DT_LITERAL = 273, ++ DT_CHAR_LITERAL = 274, ++ DT_BYTE = 275, ++ DT_STRING = 276, ++ DT_LABEL = 277, ++ DT_REF = 278, ++ DT_INCBIN = 279 ++ }; + #endif + +-/* Value type. */ ++ ++ + #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +-typedef union YYSTYPE YYSTYPE; +-union YYSTYPE ++typedef union YYSTYPE + { +-#line 38 "dtc-parser.y" /* yacc.c:355 */ ++ ++/* Line 214 of yacc.c */ ++#line 39 "dtc-parser.y" + + char *propnodename; + char *labelref; +@@ -162,37 +166,37 @@ union YYSTYPE + struct node *nodelist; + struct reserve_info *re; + uint64_t integer; ++ unsigned int flags; + +-#line 167 "dtc-parser.tab.c" /* yacc.c:355 */ +-}; ++ ++ ++/* Line 214 of yacc.c */ ++#line 175 "dtc-parser.tab.c" ++} YYSTYPE; + # define YYSTYPE_IS_TRIVIAL 1 ++# define yystype YYSTYPE /* obsolescent; will be withdrawn */ + # define YYSTYPE_IS_DECLARED 1 + #endif + +-/* Location type. */ + #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED +-typedef struct YYLTYPE YYLTYPE; +-struct YYLTYPE ++typedef struct YYLTYPE + { + int first_line; + int first_column; + int last_line; + int last_column; +-}; ++} YYLTYPE; ++# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ + # define YYLTYPE_IS_DECLARED 1 + # define YYLTYPE_IS_TRIVIAL 1 + #endif + + +-extern YYSTYPE yylval; +-extern YYLTYPE yylloc; +-int yyparse (void); +- +-#endif /* !YY_YY_DTC_PARSER_TAB_H_INCLUDED */ +- + /* Copy the second part of user declarations. */ + +-#line 196 "dtc-parser.tab.c" /* yacc.c:358 */ ++ ++/* Line 264 of yacc.c */ ++#line 200 "dtc-parser.tab.c" + + #ifdef short + # undef short +@@ -206,8 +210,11 @@ typedef unsigned char yytype_uint8; + + #ifdef YYTYPE_INT8 + typedef YYTYPE_INT8 yytype_int8; +-#else ++#elif (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) + typedef signed char yytype_int8; ++#else ++typedef short int yytype_int8; + #endif + + #ifdef YYTYPE_UINT16 +@@ -227,7 +234,8 @@ typedef short int yytype_int16; + # define YYSIZE_T __SIZE_TYPE__ + # elif defined size_t + # define YYSIZE_T size_t +-# elif ! defined YYSIZE_T ++# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) + # include <stddef.h> /* INFRINGES ON USER NAME SPACE */ + # define YYSIZE_T size_t + # else +@@ -238,71 +246,42 @@ typedef short int yytype_int16; + #define YYSIZE_MAXIMUM ((YYSIZE_T) -1) + + #ifndef YY_ +-# if defined YYENABLE_NLS && YYENABLE_NLS ++# if YYENABLE_NLS + # if ENABLE_NLS + # include <libintl.h> /* INFRINGES ON USER NAME SPACE */ +-# define YY_(Msgid) dgettext ("bison-runtime", Msgid) ++# define YY_(msgid) dgettext ("bison-runtime", msgid) + # endif + # endif + # ifndef YY_ +-# define YY_(Msgid) Msgid +-# endif +-#endif +- +-#ifndef YY_ATTRIBUTE +-# if (defined __GNUC__ \ +- && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ +- || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C +-# define YY_ATTRIBUTE(Spec) __attribute__(Spec) +-# else +-# define YY_ATTRIBUTE(Spec) /* empty */ +-# endif +-#endif +- +-#ifndef YY_ATTRIBUTE_PURE +-# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) +-#endif +- +-#ifndef YY_ATTRIBUTE_UNUSED +-# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) +-#endif +- +-#if !defined _Noreturn \ +- && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112) +-# if defined _MSC_VER && 1200 <= _MSC_VER +-# define _Noreturn __declspec (noreturn) +-# else +-# define _Noreturn YY_ATTRIBUTE ((__noreturn__)) ++# define YY_(msgid) msgid + # endif + #endif + + /* Suppress unused-variable warnings by "using" E. */ + #if ! defined lint || defined __GNUC__ +-# define YYUSE(E) ((void) (E)) ++# define YYUSE(e) ((void) (e)) + #else +-# define YYUSE(E) /* empty */ ++# define YYUSE(e) /* empty */ + #endif + +-#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ +-/* Suppress an incorrect diagnostic about yylval being uninitialized. */ +-# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ +- _Pragma ("GCC diagnostic push") \ +- _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ +- _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") +-# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ +- _Pragma ("GCC diagnostic pop") ++/* Identity function, used to suppress warnings about constant conditions. */ ++#ifndef lint ++# define YYID(n) (n) + #else +-# define YY_INITIAL_VALUE(Value) Value +-#endif +-#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +-# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +-# define YY_IGNORE_MAYBE_UNINITIALIZED_END ++#if (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) ++static int ++YYID (int yyi) ++#else ++static int ++YYID (yyi) ++ int yyi; + #endif +-#ifndef YY_INITIAL_VALUE +-# define YY_INITIAL_VALUE(Value) /* Nothing. */ ++{ ++ return yyi; ++} + #endif + +- + #if ! defined yyoverflow || YYERROR_VERBOSE + + /* The parser invokes alloca or malloc; define the necessary symbols. */ +@@ -320,11 +299,11 @@ typedef short int yytype_int16; + # define alloca _alloca + # else + # define YYSTACK_ALLOC alloca +-# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS ++# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) + # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ +- /* Use EXIT_SUCCESS as a witness for stdlib.h. */ +-# ifndef EXIT_SUCCESS +-# define EXIT_SUCCESS 0 ++# ifndef _STDLIB_H ++# define _STDLIB_H 1 + # endif + # endif + # endif +@@ -332,8 +311,8 @@ typedef short int yytype_int16; + # endif + + # ifdef YYSTACK_ALLOC +- /* Pacify GCC's 'empty if-body' warning. */ +-# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) ++ /* Pacify GCC's `empty if-body' warning. */ ++# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) + # ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely +@@ -347,23 +326,25 @@ typedef short int yytype_int16; + # ifndef YYSTACK_ALLOC_MAXIMUM + # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM + # endif +-# if (defined __cplusplus && ! defined EXIT_SUCCESS \ ++# if (defined __cplusplus && ! defined _STDLIB_H \ + && ! ((defined YYMALLOC || defined malloc) \ +- && (defined YYFREE || defined free))) ++ && (defined YYFREE || defined free))) + # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ +-# ifndef EXIT_SUCCESS +-# define EXIT_SUCCESS 0 ++# ifndef _STDLIB_H ++# define _STDLIB_H 1 + # endif + # endif + # ifndef YYMALLOC + # define YYMALLOC malloc +-# if ! defined malloc && ! defined EXIT_SUCCESS ++# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) + void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ + # endif + # endif + # ifndef YYFREE + # define YYFREE free +-# if ! defined free && ! defined EXIT_SUCCESS ++# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) + void free (void *); /* INFRINGES ON USER NAME SPACE */ + # endif + # endif +@@ -373,8 +354,8 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */ + + #if (! defined yyoverflow \ + && (! defined __cplusplus \ +- || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ +- && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) ++ || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ ++ && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + + /* A type that is properly aligned for any stack member. */ + union yyalloc +@@ -393,85 +374,79 @@ union yyalloc + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \ + + 2 * YYSTACK_GAP_MAXIMUM) + +-# define YYCOPY_NEEDED 1 ++/* Copy COUNT objects from FROM to TO. The source and destination do ++ not overlap. */ ++# ifndef YYCOPY ++# if defined __GNUC__ && 1 < __GNUC__ ++# define YYCOPY(To, From, Count) \ ++ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) ++# else ++# define YYCOPY(To, From, Count) \ ++ do \ ++ { \ ++ YYSIZE_T yyi; \ ++ for (yyi = 0; yyi < (Count); yyi++) \ ++ (To)[yyi] = (From)[yyi]; \ ++ } \ ++ while (YYID (0)) ++# endif ++# endif + + /* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +-# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ +- do \ +- { \ +- YYSIZE_T yynewbytes; \ +- YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ +- Stack = &yyptr->Stack_alloc; \ +- yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ +- yyptr += yynewbytes / sizeof (*yyptr); \ +- } \ +- while (0) ++# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ ++ do \ ++ { \ ++ YYSIZE_T yynewbytes; \ ++ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ ++ Stack = &yyptr->Stack_alloc; \ ++ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ ++ yyptr += yynewbytes / sizeof (*yyptr); \ ++ } \ ++ while (YYID (0)) + + #endif + +-#if defined YYCOPY_NEEDED && YYCOPY_NEEDED +-/* Copy COUNT objects from SRC to DST. The source and destination do +- not overlap. */ +-# ifndef YYCOPY +-# if defined __GNUC__ && 1 < __GNUC__ +-# define YYCOPY(Dst, Src, Count) \ +- __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) +-# else +-# define YYCOPY(Dst, Src, Count) \ +- do \ +- { \ +- YYSIZE_T yyi; \ +- for (yyi = 0; yyi < (Count); yyi++) \ +- (Dst)[yyi] = (Src)[yyi]; \ +- } \ +- while (0) +-# endif +-# endif +-#endif /* !YYCOPY_NEEDED */ +- + /* YYFINAL -- State number of the termination state. */ +-#define YYFINAL 4 ++#define YYFINAL 6 + /* YYLAST -- Last index in YYTABLE. */ + #define YYLAST 136 + + /* YYNTOKENS -- Number of terminals. */ +-#define YYNTOKENS 47 ++#define YYNTOKENS 48 + /* YYNNTS -- Number of nonterminals. */ +-#define YYNNTS 28 ++#define YYNNTS 31 + /* YYNRULES -- Number of rules. */ +-#define YYNRULES 80 +-/* YYNSTATES -- Number of states. */ +-#define YYNSTATES 144 ++#define YYNRULES 86 ++/* YYNRULES -- Number of states. */ ++#define YYNSTATES 150 + +-/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned +- by yylex, with out-of-bounds checking. */ ++/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ + #define YYUNDEFTOK 2 +-#define YYMAXUTOK 278 ++#define YYMAXUTOK 279 + +-#define YYTRANSLATE(YYX) \ ++#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +-/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM +- as returned by yylex, without out-of-bounds checking. */ ++/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ + static const yytype_uint8 yytranslate[] = + { + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 46, 2, 2, 2, 44, 40, 2, +- 32, 34, 43, 41, 33, 42, 2, 25, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 37, 24, +- 35, 28, 29, 36, 2, 2, 2, 2, 2, 2, ++ 2, 2, 2, 47, 2, 2, 2, 45, 41, 2, ++ 33, 35, 44, 42, 34, 43, 2, 26, 2, 2, ++ 2, 2, 2, 2, 2, 2, 2, 2, 38, 25, ++ 36, 29, 30, 37, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 30, 2, 31, 39, 2, 2, 2, 2, 2, ++ 2, 31, 2, 32, 40, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 26, 38, 27, 45, 2, 2, 2, ++ 2, 2, 2, 27, 39, 28, 46, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +@@ -486,366 +461,408 @@ static const yytype_uint8 yytranslate[] = + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, +- 15, 16, 17, 18, 19, 20, 21, 22, 23 ++ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 + }; + + #if YYDEBUG +- /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ ++/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in ++ YYRHS. */ ++static const yytype_uint16 yyprhs[] = ++{ ++ 0, 0, 3, 9, 12, 14, 15, 18, 19, 20, ++ 23, 28, 31, 34, 38, 43, 47, 52, 53, 59, ++ 60, 63, 68, 71, 75, 78, 81, 85, 90, 93, ++ 103, 109, 112, 113, 116, 119, 123, 125, 128, 131, ++ 134, 136, 138, 142, 144, 146, 152, 154, 158, 160, ++ 164, 166, 170, 172, 176, 178, 182, 184, 188, 192, ++ 194, 198, 202, 206, 210, 214, 218, 220, 224, 228, ++ 230, 234, 238, 242, 244, 246, 249, 252, 255, 256, ++ 259, 262, 263, 266, 269, 272, 276 ++}; ++ ++/* YYRHS -- A `-1'-separated list of the rules' RHS. */ ++static const yytype_int8 yyrhs[] = ++{ ++ 49, 0, -1, 50, 25, 52, 53, 55, -1, 3, ++ 51, -1, 4, -1, -1, 4, 25, -1, -1, -1, ++ 54, 53, -1, 5, 62, 62, 25, -1, 22, 54, ++ -1, 26, 56, -1, 55, 26, 56, -1, 55, 22, ++ 23, 56, -1, 55, 23, 56, -1, 55, 16, 23, ++ 25, -1, -1, 27, 57, 77, 28, 25, -1, -1, ++ 57, 58, -1, 17, 29, 59, 25, -1, 17, 25, ++ -1, 15, 17, 25, -1, 22, 58, -1, 60, 21, ++ -1, 60, 61, 30, -1, 60, 31, 76, 32, -1, ++ 60, 23, -1, 60, 24, 33, 21, 34, 62, 34, ++ 62, 35, -1, 60, 24, 33, 21, 35, -1, 59, ++ 22, -1, -1, 59, 34, -1, 60, 22, -1, 14, ++ 18, 36, -1, 36, -1, 61, 62, -1, 61, 23, ++ -1, 61, 22, -1, 18, -1, 19, -1, 33, 63, ++ 35, -1, 64, -1, 65, -1, 65, 37, 63, 38, ++ 64, -1, 66, -1, 65, 13, 66, -1, 67, -1, ++ 66, 12, 67, -1, 68, -1, 67, 39, 68, -1, ++ 69, -1, 68, 40, 69, -1, 70, -1, 69, 41, ++ 70, -1, 71, -1, 70, 10, 71, -1, 70, 11, ++ 71, -1, 72, -1, 71, 36, 72, -1, 71, 30, ++ 72, -1, 71, 8, 72, -1, 71, 9, 72, -1, ++ 72, 6, 73, -1, 72, 7, 73, -1, 73, -1, ++ 73, 42, 74, -1, 73, 43, 74, -1, 74, -1, ++ 74, 44, 75, -1, 74, 26, 75, -1, 74, 45, ++ 75, -1, 75, -1, 62, -1, 43, 75, -1, 46, ++ 75, -1, 47, 75, -1, -1, 76, 20, -1, 76, ++ 22, -1, -1, 78, 77, -1, 78, 58, -1, 17, ++ 56, -1, 16, 17, 25, -1, 22, 78, -1 ++}; ++ ++/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ + static const yytype_uint16 yyrline[] = + { +- 0, 104, 104, 113, 116, 123, 127, 135, 139, 144, +- 155, 165, 180, 188, 191, 198, 202, 206, 210, 218, +- 222, 226, 230, 234, 250, 260, 268, 271, 275, 282, +- 298, 303, 322, 336, 343, 344, 345, 352, 356, 357, +- 361, 362, 366, 367, 371, 372, 376, 377, 381, 382, +- 386, 387, 388, 392, 393, 394, 395, 396, 400, 401, +- 402, 406, 407, 408, 412, 413, 422, 431, 435, 436, +- 437, 438, 443, 446, 450, 458, 461, 465, 473, 477, +- 481 ++ 0, 110, 110, 118, 125, 130, 136, 141, 148, 151, ++ 158, 162, 170, 174, 179, 190, 204, 217, 224, 232, ++ 235, 242, 246, 250, 254, 262, 266, 270, 274, 278, ++ 294, 304, 312, 315, 319, 326, 342, 347, 366, 380, ++ 387, 388, 389, 396, 400, 401, 405, 406, 410, 411, ++ 415, 416, 420, 421, 425, 426, 430, 431, 432, 436, ++ 437, 438, 439, 440, 444, 445, 446, 450, 451, 452, ++ 456, 457, 466, 475, 479, 480, 481, 482, 487, 490, ++ 494, 502, 505, 509, 517, 521, 525 + }; + #endif + +-#if YYDEBUG || YYERROR_VERBOSE || 0 ++#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE + /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ + static const char *const yytname[] = + { +- "$end", "error", "$undefined", "DT_V1", "DT_MEMRESERVE", "DT_LSHIFT", +- "DT_RSHIFT", "DT_LE", "DT_GE", "DT_EQ", "DT_NE", "DT_AND", "DT_OR", +- "DT_BITS", "DT_DEL_PROP", "DT_DEL_NODE", "DT_PROPNODENAME", "DT_LITERAL", +- "DT_CHAR_LITERAL", "DT_BYTE", "DT_STRING", "DT_LABEL", "DT_REF", +- "DT_INCBIN", "';'", "'/'", "'{'", "'}'", "'='", "'>'", "'['", "']'", +- "'('", "','", "')'", "'<'", "'?'", "':'", "'|'", "'^'", "'&'", "'+'", +- "'-'", "'*'", "'%'", "'~'", "'!'", "$accept", "sourcefile", +- "memreserves", "memreserve", "devicetree", "nodedef", "proplist", +- "propdef", "propdata", "propdataprefix", "arrayprefix", "integer_prim", +- "integer_expr", "integer_trinary", "integer_or", "integer_and", +- "integer_bitor", "integer_bitxor", "integer_bitand", "integer_eq", +- "integer_rela", "integer_shift", "integer_add", "integer_mul", +- "integer_unary", "bytestring", "subnodes", "subnode", YY_NULLPTR ++ "$end", "error", "$undefined", "DT_V1", "DT_PLUGIN", "DT_MEMRESERVE", ++ "DT_LSHIFT", "DT_RSHIFT", "DT_LE", "DT_GE", "DT_EQ", "DT_NE", "DT_AND", ++ "DT_OR", "DT_BITS", "DT_DEL_PROP", "DT_DEL_NODE", "DT_PROPNODENAME", ++ "DT_LITERAL", "DT_CHAR_LITERAL", "DT_BYTE", "DT_STRING", "DT_LABEL", ++ "DT_REF", "DT_INCBIN", "';'", "'/'", "'{'", "'}'", "'='", "'>'", "'['", ++ "']'", "'('", "','", "')'", "'<'", "'?'", "':'", "'|'", "'^'", "'&'", ++ "'+'", "'-'", "'*'", "'%'", "'~'", "'!'", "$accept", "sourcefile", ++ "versioninfo", "plugindecl", "oldplugindecl", "memreserves", ++ "memreserve", "devicetree", "nodedef", "proplist", "propdef", "propdata", ++ "propdataprefix", "arrayprefix", "integer_prim", "integer_expr", ++ "integer_trinary", "integer_or", "integer_and", "integer_bitor", ++ "integer_bitxor", "integer_bitand", "integer_eq", "integer_rela", ++ "integer_shift", "integer_add", "integer_mul", "integer_unary", ++ "bytestring", "subnodes", "subnode", 0 + }; + #endif + + # ifdef YYPRINT +-/* YYTOKNUM[NUM] -- (External) token number corresponding to the +- (internal) symbol number NUM (which must be that of a token). */ ++/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to ++ token YYLEX-NUM. */ + static const yytype_uint16 yytoknum[] = + { + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, +- 275, 276, 277, 278, 59, 47, 123, 125, 61, 62, +- 91, 93, 40, 44, 41, 60, 63, 58, 124, 94, +- 38, 43, 45, 42, 37, 126, 33 ++ 275, 276, 277, 278, 279, 59, 47, 123, 125, 61, ++ 62, 91, 93, 40, 44, 41, 60, 63, 58, 124, ++ 94, 38, 43, 45, 42, 37, 126, 33 + }; + # endif + +-#define YYPACT_NINF -81 +- +-#define yypact_value_is_default(Yystate) \ +- (!!((Yystate) == (-81))) +- +-#define YYTABLE_NINF -1 +- +-#define yytable_value_is_error(Yytable_value) \ +- 0 +- +- /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing +- STATE-NUM. */ +-static const yytype_int8 yypact[] = ++/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ ++static const yytype_uint8 yyr1[] = + { +- 16, -11, 21, 10, -81, 25, 10, 19, 10, -81, +- -81, -9, 25, -81, 2, 51, -81, -9, -9, -9, +- -81, 1, -81, -6, 50, 14, 28, 29, 36, 3, +- 58, 44, -3, -81, 47, -81, -81, 65, 68, 2, +- 2, -81, -81, -81, -81, -9, -9, -9, -9, -9, +- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, +- -9, -9, -9, -9, -81, 63, 69, 2, -81, -81, +- 50, 57, 14, 28, 29, 36, 3, 3, 58, 58, +- 58, 58, 44, 44, -3, -3, -81, -81, -81, 79, +- 80, -8, 63, -81, 72, 63, -81, -81, -9, 76, +- 77, -81, -81, -81, -81, -81, 78, -81, -81, -81, +- -81, -81, 35, 4, -81, -81, -81, -81, 86, -81, +- -81, -81, 73, -81, -81, 33, 71, 84, 39, -81, +- -81, -81, -81, -81, 41, -81, -81, -81, 25, -81, +- 74, 25, 75, -81 ++ 0, 48, 49, 50, 51, 51, 52, 52, 53, 53, ++ 54, 54, 55, 55, 55, 55, 55, 55, 56, 57, ++ 57, 58, 58, 58, 58, 59, 59, 59, 59, 59, ++ 59, 59, 60, 60, 60, 61, 61, 61, 61, 61, ++ 62, 62, 62, 63, 64, 64, 65, 65, 66, 66, ++ 67, 67, 68, 68, 69, 69, 70, 70, 70, 71, ++ 71, 71, 71, 71, 72, 72, 72, 73, 73, 73, ++ 74, 74, 74, 74, 75, 75, 75, 75, 76, 76, ++ 76, 77, 77, 77, 78, 78, 78 + }; + +- /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. +- Performed when YYTABLE does not specify something else to do. Zero +- means the default is an error. */ +-static const yytype_uint8 yydefact[] = ++/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ ++static const yytype_uint8 yyr2[] = + { +- 0, 0, 0, 3, 1, 0, 0, 0, 3, 34, +- 35, 0, 0, 6, 0, 2, 4, 0, 0, 0, +- 68, 0, 37, 38, 40, 42, 44, 46, 48, 50, +- 53, 60, 63, 67, 0, 13, 7, 0, 0, 0, +- 0, 69, 70, 71, 36, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 5, 75, 0, 0, 10, 8, +- 41, 0, 43, 45, 47, 49, 51, 52, 56, 57, +- 55, 54, 58, 59, 61, 62, 65, 64, 66, 0, +- 0, 0, 0, 14, 0, 75, 11, 9, 0, 0, +- 0, 16, 26, 78, 18, 80, 0, 77, 76, 39, +- 17, 79, 0, 0, 12, 25, 15, 27, 0, 19, +- 28, 22, 0, 72, 30, 0, 0, 0, 0, 33, +- 32, 20, 31, 29, 0, 73, 74, 21, 0, 24, +- 0, 0, 0, 23 ++ 0, 2, 5, 2, 1, 0, 2, 0, 0, 2, ++ 4, 2, 2, 3, 4, 3, 4, 0, 5, 0, ++ 2, 4, 2, 3, 2, 2, 3, 4, 2, 9, ++ 5, 2, 0, 2, 2, 3, 1, 2, 2, 2, ++ 1, 1, 3, 1, 1, 5, 1, 3, 1, 3, ++ 1, 3, 1, 3, 1, 3, 1, 3, 3, 1, ++ 3, 3, 3, 3, 3, 3, 1, 3, 3, 1, ++ 3, 3, 3, 1, 1, 2, 2, 2, 0, 2, ++ 2, 0, 2, 2, 2, 3, 2 + }; + +- /* YYPGOTO[NTERM-NUM]. */ +-static const yytype_int8 yypgoto[] = ++/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state ++ STATE-NUM when YYTABLE doesn't specify something else to do. Zero ++ means the default is an error. */ ++static const yytype_uint8 yydefact[] = + { +- -81, -81, 100, 104, -81, -38, -81, -80, -81, -81, +- -81, -5, 66, 13, -81, 70, 67, 81, 64, 82, +- 37, 27, 34, 38, -14, -81, 22, 24 ++ 0, 5, 0, 0, 4, 3, 1, 7, 0, 8, ++ 6, 0, 0, 17, 8, 40, 41, 0, 0, 11, ++ 0, 2, 9, 0, 0, 0, 74, 0, 43, 44, ++ 46, 48, 50, 52, 54, 56, 59, 66, 69, 73, ++ 0, 19, 12, 0, 0, 0, 0, 75, 76, 77, ++ 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 10, 81, 0, 0, 15, 13, 47, 0, 49, 51, ++ 53, 55, 57, 58, 62, 63, 61, 60, 64, 65, ++ 67, 68, 71, 70, 72, 0, 0, 0, 0, 20, ++ 0, 81, 16, 14, 0, 0, 0, 22, 32, 84, ++ 24, 86, 0, 83, 82, 45, 23, 85, 0, 0, ++ 18, 31, 21, 33, 0, 25, 34, 28, 0, 78, ++ 36, 0, 0, 0, 0, 39, 38, 26, 37, 35, ++ 0, 79, 80, 27, 0, 30, 0, 0, 0, 29 + }; + +- /* YYDEFGOTO[NTERM-NUM]. */ ++/* YYDEFGOTO[NTERM-NUM]. */ + static const yytype_int16 yydefgoto[] = + { +- -1, 2, 7, 8, 15, 36, 65, 93, 112, 113, +- 125, 20, 21, 22, 23, 24, 25, 26, 27, 28, +- 29, 30, 31, 32, 33, 128, 94, 95 ++ -1, 2, 3, 5, 9, 13, 14, 21, 42, 71, ++ 99, 118, 119, 131, 26, 27, 28, 29, 30, 31, ++ 32, 33, 34, 35, 36, 37, 38, 39, 134, 100, ++ 101 + }; + +- /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If +- positive, shift that token. If negative, reduce the rule whose +- number is the opposite. If YYTABLE_NINF, syntax error. */ +-static const yytype_uint8 yytable[] = ++/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing ++ STATE-NUM. */ ++#define YYPACT_NINF -87 ++static const yytype_int8 yypact[] = + { +- 12, 68, 69, 41, 42, 43, 45, 34, 9, 10, +- 53, 54, 104, 3, 5, 107, 101, 118, 35, 1, +- 102, 4, 61, 11, 119, 120, 121, 122, 35, 97, +- 46, 6, 55, 17, 123, 44, 18, 19, 56, 124, +- 62, 63, 9, 10, 14, 51, 52, 86, 87, 88, +- 9, 10, 48, 103, 129, 130, 115, 11, 135, 116, +- 136, 47, 131, 57, 58, 11, 37, 49, 117, 50, +- 137, 64, 38, 39, 138, 139, 40, 89, 90, 91, +- 78, 79, 80, 81, 92, 59, 60, 66, 76, 77, +- 67, 82, 83, 96, 98, 99, 100, 84, 85, 106, +- 110, 111, 114, 126, 134, 127, 133, 141, 16, 143, +- 13, 109, 71, 74, 72, 70, 105, 108, 0, 0, +- 132, 0, 0, 0, 0, 0, 0, 0, 0, 73, +- 0, 0, 75, 140, 0, 0, 142 ++ 43, 14, 13, 27, -87, -87, -87, 31, 39, 9, ++ -87, 24, 9, 61, 9, -87, -87, -10, 24, -87, ++ 42, 44, -87, -10, -10, -10, -87, 55, -87, -7, ++ 79, 53, 54, 52, 10, 2, 38, 37, -4, -87, ++ 70, -87, -87, 73, 74, 42, 42, -87, -87, -87, ++ -87, -10, -10, -10, -10, -10, -10, -10, -10, -10, ++ -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, ++ -87, 56, 75, 42, -87, -87, 79, 60, 53, 54, ++ 52, 10, 2, 2, 38, 38, 38, 38, 37, 37, ++ -4, -4, -87, -87, -87, 82, 84, 34, 56, -87, ++ 76, 56, -87, -87, -10, 77, 78, -87, -87, -87, ++ -87, -87, 80, -87, -87, -87, -87, -87, -6, 3, ++ -87, -87, -87, -87, 88, -87, -87, -87, 81, -87, ++ -87, 32, 71, 87, 36, -87, -87, -87, -87, -87, ++ 47, -87, -87, -87, 24, -87, 83, 24, 86, -87 + }; + +-static const yytype_int16 yycheck[] = ++/* YYPGOTO[NTERM-NUM]. */ ++static const yytype_int8 yypgoto[] = + { +- 5, 39, 40, 17, 18, 19, 12, 12, 17, 18, +- 7, 8, 92, 24, 4, 95, 24, 13, 26, 3, +- 28, 0, 25, 32, 20, 21, 22, 23, 26, 67, +- 36, 21, 29, 42, 30, 34, 45, 46, 35, 35, +- 43, 44, 17, 18, 25, 9, 10, 61, 62, 63, +- 17, 18, 38, 91, 21, 22, 21, 32, 19, 24, +- 21, 11, 29, 5, 6, 32, 15, 39, 33, 40, +- 31, 24, 21, 22, 33, 34, 25, 14, 15, 16, +- 53, 54, 55, 56, 21, 41, 42, 22, 51, 52, +- 22, 57, 58, 24, 37, 16, 16, 59, 60, 27, +- 24, 24, 24, 17, 20, 32, 35, 33, 8, 34, +- 6, 98, 46, 49, 47, 45, 92, 95, -1, -1, +- 125, -1, -1, -1, -1, -1, -1, -1, -1, 48, +- -1, -1, 50, 138, -1, -1, 141 ++ -87, -87, -87, -87, -87, 95, 98, -87, -44, -87, ++ -86, -87, -87, -87, -11, 59, 8, -87, 62, 63, ++ 64, 67, 68, 26, 15, 22, 23, -20, -87, 18, ++ 17 + }; + +- /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing +- symbol of state STATE-NUM. */ +-static const yytype_uint8 yystos[] = ++/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If ++ positive, shift that token. If negative, reduce the rule which ++ number is the opposite. If zero, do what YYDEFACT says. ++ If YYTABLE_NINF, syntax error. */ ++#define YYTABLE_NINF -1 ++static const yytype_uint8 yytable[] = + { +- 0, 3, 48, 24, 0, 4, 21, 49, 50, 17, +- 18, 32, 58, 50, 25, 51, 49, 42, 45, 46, +- 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, +- 68, 69, 70, 71, 58, 26, 52, 15, 21, 22, +- 25, 71, 71, 71, 34, 12, 36, 11, 38, 39, +- 40, 9, 10, 7, 8, 29, 35, 5, 6, 41, +- 42, 25, 43, 44, 24, 53, 22, 22, 52, 52, +- 62, 59, 63, 64, 65, 66, 67, 67, 68, 68, +- 68, 68, 69, 69, 70, 70, 71, 71, 71, 14, +- 15, 16, 21, 54, 73, 74, 24, 52, 37, 16, +- 16, 24, 28, 52, 54, 74, 27, 54, 73, 60, +- 24, 24, 55, 56, 24, 21, 24, 33, 13, 20, +- 21, 22, 23, 30, 35, 57, 17, 32, 72, 21, +- 22, 29, 58, 35, 20, 19, 21, 31, 33, 34, +- 58, 33, 58, 34 ++ 18, 74, 75, 47, 48, 49, 51, 40, 15, 16, ++ 59, 60, 110, 6, 11, 113, 121, 124, 4, 122, ++ 57, 58, 67, 17, 125, 126, 127, 128, 123, 103, ++ 52, 12, 61, 23, 129, 8, 24, 25, 62, 130, ++ 68, 69, 15, 16, 63, 64, 1, 92, 93, 94, ++ 15, 16, 7, 109, 135, 136, 141, 17, 142, 107, ++ 43, 41, 137, 108, 10, 17, 44, 45, 143, 41, ++ 46, 95, 96, 97, 84, 85, 86, 87, 98, 65, ++ 66, 144, 145, 82, 83, 88, 89, 20, 90, 91, ++ 50, 53, 54, 56, 55, 70, 72, 73, 104, 105, ++ 102, 106, 116, 117, 112, 120, 132, 139, 140, 22, ++ 19, 77, 115, 76, 133, 111, 78, 147, 79, 114, ++ 138, 149, 80, 0, 81, 0, 0, 0, 0, 0, ++ 0, 0, 0, 146, 0, 0, 148 + }; + +- /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +-static const yytype_uint8 yyr1[] = ++static const yytype_int16 yycheck[] = + { +- 0, 47, 48, 49, 49, 50, 50, 51, 51, 51, +- 51, 51, 52, 53, 53, 54, 54, 54, 54, 55, +- 55, 55, 55, 55, 55, 55, 56, 56, 56, 57, +- 57, 57, 57, 57, 58, 58, 58, 59, 60, 60, +- 61, 61, 62, 62, 63, 63, 64, 64, 65, 65, +- 66, 66, 66, 67, 67, 67, 67, 67, 68, 68, +- 68, 69, 69, 69, 70, 70, 70, 70, 71, 71, +- 71, 71, 72, 72, 72, 73, 73, 73, 74, 74, +- 74 ++ 11, 45, 46, 23, 24, 25, 13, 18, 18, 19, ++ 8, 9, 98, 0, 5, 101, 22, 14, 4, 25, ++ 10, 11, 26, 33, 21, 22, 23, 24, 34, 73, ++ 37, 22, 30, 43, 31, 4, 46, 47, 36, 36, ++ 44, 45, 18, 19, 6, 7, 3, 67, 68, 69, ++ 18, 19, 25, 97, 22, 23, 20, 33, 22, 25, ++ 16, 27, 30, 29, 25, 33, 22, 23, 32, 27, ++ 26, 15, 16, 17, 59, 60, 61, 62, 22, 42, ++ 43, 34, 35, 57, 58, 63, 64, 26, 65, 66, ++ 35, 12, 39, 41, 40, 25, 23, 23, 38, 17, ++ 25, 17, 25, 25, 28, 25, 18, 36, 21, 14, ++ 12, 52, 104, 51, 33, 98, 53, 34, 54, 101, ++ 131, 35, 55, -1, 56, -1, -1, -1, -1, -1, ++ -1, -1, -1, 144, -1, -1, 147 + }; + +- /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ +-static const yytype_uint8 yyr2[] = ++/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing ++ symbol of state STATE-NUM. */ ++static const yytype_uint8 yystos[] = + { +- 0, 2, 4, 0, 2, 4, 2, 2, 3, 4, +- 3, 4, 5, 0, 2, 4, 2, 3, 2, 2, +- 3, 4, 2, 9, 5, 2, 0, 2, 2, 3, +- 1, 2, 2, 2, 1, 1, 3, 1, 1, 5, +- 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, +- 1, 3, 3, 1, 3, 3, 3, 3, 3, 3, +- 1, 3, 3, 1, 3, 3, 3, 1, 1, 2, +- 2, 2, 0, 2, 2, 0, 2, 2, 2, 3, +- 2 ++ 0, 3, 49, 50, 4, 51, 0, 25, 4, 52, ++ 25, 5, 22, 53, 54, 18, 19, 33, 62, 54, ++ 26, 55, 53, 43, 46, 47, 62, 63, 64, 65, ++ 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, ++ 62, 27, 56, 16, 22, 23, 26, 75, 75, 75, ++ 35, 13, 37, 12, 39, 40, 41, 10, 11, 8, ++ 9, 30, 36, 6, 7, 42, 43, 26, 44, 45, ++ 25, 57, 23, 23, 56, 56, 66, 63, 67, 68, ++ 69, 70, 71, 71, 72, 72, 72, 72, 73, 73, ++ 74, 74, 75, 75, 75, 15, 16, 17, 22, 58, ++ 77, 78, 25, 56, 38, 17, 17, 25, 29, 56, ++ 58, 78, 28, 58, 77, 64, 25, 25, 59, 60, ++ 25, 22, 25, 34, 14, 21, 22, 23, 24, 31, ++ 36, 61, 18, 33, 76, 22, 23, 30, 62, 36, ++ 21, 20, 22, 32, 34, 35, 62, 34, 62, 35 + }; + ++#define yyerrok (yyerrstatus = 0) ++#define yyclearin (yychar = YYEMPTY) ++#define YYEMPTY (-2) ++#define YYEOF 0 + +-#define yyerrok (yyerrstatus = 0) +-#define yyclearin (yychar = YYEMPTY) +-#define YYEMPTY (-2) +-#define YYEOF 0 ++#define YYACCEPT goto yyacceptlab ++#define YYABORT goto yyabortlab ++#define YYERROR goto yyerrorlab + +-#define YYACCEPT goto yyacceptlab +-#define YYABORT goto yyabortlab +-#define YYERROR goto yyerrorlab + ++/* Like YYERROR except do call yyerror. This remains here temporarily ++ to ease the transition to the new meaning of YYERROR, for GCC. ++ Once GCC version 2 has supplanted version 1, this can go. */ ++ ++#define YYFAIL goto yyerrlab + + #define YYRECOVERING() (!!yyerrstatus) + +-#define YYBACKUP(Token, Value) \ +-do \ +- if (yychar == YYEMPTY) \ +- { \ +- yychar = (Token); \ +- yylval = (Value); \ +- YYPOPSTACK (yylen); \ +- yystate = *yyssp; \ +- goto yybackup; \ +- } \ +- else \ +- { \ ++#define YYBACKUP(Token, Value) \ ++do \ ++ if (yychar == YYEMPTY && yylen == 1) \ ++ { \ ++ yychar = (Token); \ ++ yylval = (Value); \ ++ yytoken = YYTRANSLATE (yychar); \ ++ YYPOPSTACK (1); \ ++ goto yybackup; \ ++ } \ ++ else \ ++ { \ + yyerror (YY_("syntax error: cannot back up")); \ +- YYERROR; \ +- } \ +-while (0) ++ YYERROR; \ ++ } \ ++while (YYID (0)) ++ + +-/* Error token number */ +-#define YYTERROR 1 +-#define YYERRCODE 256 ++#define YYTERROR 1 ++#define YYERRCODE 256 + + + /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + ++#define YYRHSLOC(Rhs, K) ((Rhs)[K]) + #ifndef YYLLOC_DEFAULT +-# define YYLLOC_DEFAULT(Current, Rhs, N) \ +- do \ +- if (N) \ +- { \ +- (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ +- (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ +- (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ +- (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ +- } \ +- else \ +- { \ +- (Current).first_line = (Current).last_line = \ +- YYRHSLOC (Rhs, 0).last_line; \ +- (Current).first_column = (Current).last_column = \ +- YYRHSLOC (Rhs, 0).last_column; \ +- } \ +- while (0) ++# define YYLLOC_DEFAULT(Current, Rhs, N) \ ++ do \ ++ if (YYID (N)) \ ++ { \ ++ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ ++ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ ++ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ ++ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ ++ } \ ++ else \ ++ { \ ++ (Current).first_line = (Current).last_line = \ ++ YYRHSLOC (Rhs, 0).last_line; \ ++ (Current).first_column = (Current).last_column = \ ++ YYRHSLOC (Rhs, 0).last_column; \ ++ } \ ++ while (YYID (0)) + #endif + +-#define YYRHSLOC(Rhs, K) ((Rhs)[K]) +- +- +-/* Enable debugging if requested. */ +-#if YYDEBUG +- +-# ifndef YYFPRINTF +-# include <stdio.h> /* INFRINGES ON USER NAME SPACE */ +-# define YYFPRINTF fprintf +-# endif +- +-# define YYDPRINTF(Args) \ +-do { \ +- if (yydebug) \ +- YYFPRINTF Args; \ +-} while (0) +- + + /* YY_LOCATION_PRINT -- Print the location on the stream. + This macro was not mandated originally: define only if we know + we won't break user code: when these are the locations we know. */ + + #ifndef YY_LOCATION_PRINT +-# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL ++# if YYLTYPE_IS_TRIVIAL ++# define YY_LOCATION_PRINT(File, Loc) \ ++ fprintf (File, "%d.%d-%d.%d", \ ++ (Loc).first_line, (Loc).first_column, \ ++ (Loc).last_line, (Loc).last_column) ++# else ++# define YY_LOCATION_PRINT(File, Loc) ((void) 0) ++# endif ++#endif + +-/* Print *YYLOCP on YYO. Private, do not rely on its existence. */ + +-YY_ATTRIBUTE_UNUSED +-static unsigned +-yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp) +-{ +- unsigned res = 0; +- int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0; +- if (0 <= yylocp->first_line) +- { +- res += YYFPRINTF (yyo, "%d", yylocp->first_line); +- if (0 <= yylocp->first_column) +- res += YYFPRINTF (yyo, ".%d", yylocp->first_column); +- } +- if (0 <= yylocp->last_line) +- { +- if (yylocp->first_line < yylocp->last_line) +- { +- res += YYFPRINTF (yyo, "-%d", yylocp->last_line); +- if (0 <= end_col) +- res += YYFPRINTF (yyo, ".%d", end_col); +- } +- else if (0 <= end_col && yylocp->first_column < end_col) +- res += YYFPRINTF (yyo, "-%d", end_col); +- } +- return res; +- } ++/* YYLEX -- calling `yylex' with the right arguments. */ + +-# define YY_LOCATION_PRINT(File, Loc) \ +- yy_location_print_ (File, &(Loc)) ++#ifdef YYLEX_PARAM ++# define YYLEX yylex (YYLEX_PARAM) ++#else ++# define YYLEX yylex () ++#endif + +-# else +-# define YY_LOCATION_PRINT(File, Loc) ((void) 0) ++/* Enable debugging if requested. */ ++#if YYDEBUG ++ ++# ifndef YYFPRINTF ++# include <stdio.h> /* INFRINGES ON USER NAME SPACE */ ++# define YYFPRINTF fprintf + # endif +-#endif + ++# define YYDPRINTF(Args) \ ++do { \ ++ if (yydebug) \ ++ YYFPRINTF Args; \ ++} while (YYID (0)) + +-# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +-do { \ +- if (yydebug) \ +- { \ +- YYFPRINTF (stderr, "%s ", Title); \ +- yy_symbol_print (stderr, \ +- Type, Value, Location); \ +- YYFPRINTF (stderr, "\n"); \ +- } \ +-} while (0) ++# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ ++do { \ ++ if (yydebug) \ ++ { \ ++ YYFPRINTF (stderr, "%s ", Title); \ ++ yy_symbol_print (stderr, \ ++ Type, Value, Location); \ ++ YYFPRINTF (stderr, "\n"); \ ++ } \ ++} while (YYID (0)) + + +-/*----------------------------------------. +-| Print this symbol's value on YYOUTPUT. | +-`----------------------------------------*/ ++/*--------------------------------. ++| Print this symbol on YYOUTPUT. | ++`--------------------------------*/ + ++/*ARGSUSED*/ ++#if (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) + static void + yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp) ++#else ++static void ++yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp) ++ FILE *yyoutput; ++ int yytype; ++ YYSTYPE const * const yyvaluep; ++ YYLTYPE const * const yylocationp; ++#endif + { +- FILE *yyo = yyoutput; +- YYUSE (yyo); +- YYUSE (yylocationp); + if (!yyvaluep) + return; ++ YYUSE (yylocationp); + # ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); ++# else ++ YYUSE (yyoutput); + # endif +- YYUSE (yytype); ++ switch (yytype) ++ { ++ default: ++ break; ++ } + } + + +@@ -853,11 +870,23 @@ yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvalue + | Print this symbol on YYOUTPUT. | + `--------------------------------*/ + ++#if (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) + static void + yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp) ++#else ++static void ++yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp) ++ FILE *yyoutput; ++ int yytype; ++ YYSTYPE const * const yyvaluep; ++ YYLTYPE const * const yylocationp; ++#endif + { +- YYFPRINTF (yyoutput, "%s %s (", +- yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); ++ if (yytype < YYNTOKENS) ++ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); ++ else ++ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + YY_LOCATION_PRINT (yyoutput, *yylocationp); + YYFPRINTF (yyoutput, ": "); +@@ -870,8 +899,16 @@ yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYL + | TOP (included). | + `------------------------------------------------------------------*/ + ++#if (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) + static void + yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) ++#else ++static void ++yy_stack_print (yybottom, yytop) ++ yytype_int16 *yybottom; ++ yytype_int16 *yytop; ++#endif + { + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) +@@ -882,42 +919,50 @@ yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) + YYFPRINTF (stderr, "\n"); + } + +-# define YY_STACK_PRINT(Bottom, Top) \ +-do { \ +- if (yydebug) \ +- yy_stack_print ((Bottom), (Top)); \ +-} while (0) ++# define YY_STACK_PRINT(Bottom, Top) \ ++do { \ ++ if (yydebug) \ ++ yy_stack_print ((Bottom), (Top)); \ ++} while (YYID (0)) + + + /*------------------------------------------------. + | Report that the YYRULE is going to be reduced. | + `------------------------------------------------*/ + ++#if (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) + static void +-yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule) ++yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule) ++#else ++static void ++yy_reduce_print (yyvsp, yylsp, yyrule) ++ YYSTYPE *yyvsp; ++ YYLTYPE *yylsp; ++ int yyrule; ++#endif + { +- unsigned long int yylno = yyrline[yyrule]; + int yynrhs = yyr2[yyrule]; + int yyi; ++ unsigned long int yylno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", +- yyrule - 1, yylno); ++ yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); +- yy_symbol_print (stderr, +- yystos[yyssp[yyi + 1 - yynrhs]], +- &(yyvsp[(yyi + 1) - (yynrhs)]) +- , &(yylsp[(yyi + 1) - (yynrhs)]) ); ++ yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], ++ &(yyvsp[(yyi + 1) - (yynrhs)]) ++ , &(yylsp[(yyi + 1) - (yynrhs)]) ); + YYFPRINTF (stderr, "\n"); + } + } + +-# define YY_REDUCE_PRINT(Rule) \ +-do { \ +- if (yydebug) \ +- yy_reduce_print (yyssp, yyvsp, yylsp, Rule); \ +-} while (0) ++# define YY_REDUCE_PRINT(Rule) \ ++do { \ ++ if (yydebug) \ ++ yy_reduce_print (yyvsp, yylsp, Rule); \ ++} while (YYID (0)) + + /* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +@@ -931,7 +976,7 @@ int yydebug; + + + /* YYINITDEPTH -- initial size of the parser's stacks. */ +-#ifndef YYINITDEPTH ++#ifndef YYINITDEPTH + # define YYINITDEPTH 200 + #endif + +@@ -946,6 +991,7 @@ int yydebug; + # define YYMAXDEPTH 10000 + #endif + ++ + + #if YYERROR_VERBOSE + +@@ -954,8 +1000,15 @@ int yydebug; + # define yystrlen strlen + # else + /* Return the length of YYSTR. */ ++#if (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) + static YYSIZE_T + yystrlen (const char *yystr) ++#else ++static YYSIZE_T ++yystrlen (yystr) ++ const char *yystr; ++#endif + { + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) +@@ -971,8 +1024,16 @@ yystrlen (const char *yystr) + # else + /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ ++#if (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) + static char * + yystpcpy (char *yydest, const char *yysrc) ++#else ++static char * ++yystpcpy (yydest, yysrc) ++ char *yydest; ++ const char *yysrc; ++#endif + { + char *yyd = yydest; + const char *yys = yysrc; +@@ -1002,27 +1063,27 @@ yytnamerr (char *yyres, const char *yystr) + char const *yyp = yystr; + + for (;;) +- switch (*++yyp) +- { +- case '\'': +- case ',': +- goto do_not_strip_quotes; +- +- case '\\': +- if (*++yyp != '\\') +- goto do_not_strip_quotes; +- /* Fall through. */ +- default: +- if (yyres) +- yyres[yyn] = *yyp; +- yyn++; +- break; +- +- case '"': +- if (yyres) +- yyres[yyn] = '\0'; +- return yyn; +- } ++ switch (*++yyp) ++ { ++ case '\'': ++ case ',': ++ goto do_not_strip_quotes; ++ ++ case '\\': ++ if (*++yyp != '\\') ++ goto do_not_strip_quotes; ++ /* Fall through. */ ++ default: ++ if (yyres) ++ yyres[yyn] = *yyp; ++ yyn++; ++ break; ++ ++ case '"': ++ if (yyres) ++ yyres[yyn] = '\0'; ++ return yyn; ++ } + do_not_strip_quotes: ; + } + +@@ -1033,161 +1094,163 @@ yytnamerr (char *yyres, const char *yystr) + } + # endif + +-/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message +- about the unexpected token YYTOKEN for the state stack whose top is +- YYSSP. +- +- Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is +- not large enough to hold the message. In that case, also set +- *YYMSG_ALLOC to the required number of bytes. Return 2 if the +- required number of bytes is too large to store. */ +-static int +-yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, +- yytype_int16 *yyssp, int yytoken) ++/* Copy into YYRESULT an error message about the unexpected token ++ YYCHAR while in state YYSTATE. Return the number of bytes copied, ++ including the terminating null byte. If YYRESULT is null, do not ++ copy anything; just return the number of bytes that would be ++ copied. As a special case, return 0 if an ordinary "syntax error" ++ message will do. Return YYSIZE_MAXIMUM if overflow occurs during ++ size calculation. */ ++static YYSIZE_T ++yysyntax_error (char *yyresult, int yystate, int yychar) + { +- YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); +- YYSIZE_T yysize = yysize0; +- enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; +- /* Internationalized format string. */ +- const char *yyformat = YY_NULLPTR; +- /* Arguments of yyformat. */ +- char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; +- /* Number of reported tokens (one for the "unexpected", one per +- "expected"). */ +- int yycount = 0; +- +- /* There are many possibilities here to consider: +- - If this state is a consistent state with a default action, then +- the only way this function was invoked is if the default action +- is an error action. In that case, don't check for expected +- tokens because there are none. +- - The only way there can be no lookahead present (in yychar) is if +- this state is a consistent state with a default action. Thus, +- detecting the absence of a lookahead is sufficient to determine +- that there is no unexpected or expected token to report. In that +- case, just report a simple "syntax error". +- - Don't assume there isn't a lookahead just because this state is a +- consistent state with a default action. There might have been a +- previous inconsistent state, consistent state with a non-default +- action, or user semantic action that manipulated yychar. +- - Of course, the expected token list depends on states to have +- correct lookahead information, and it depends on the parser not +- to perform extra reductions after fetching a lookahead from the +- scanner and before detecting a syntax error. Thus, state merging +- (from LALR or IELR) and default reductions corrupt the expected +- token list. However, the list is correct for canonical LR with +- one exception: it will still contain any token that will not be +- accepted due to an error action in a later state. +- */ +- if (yytoken != YYEMPTY) +- { +- int yyn = yypact[*yyssp]; +- yyarg[yycount++] = yytname[yytoken]; +- if (!yypact_value_is_default (yyn)) +- { +- /* Start YYX at -YYN if negative to avoid negative indexes in +- YYCHECK. In other words, skip the first -YYN actions for +- this state because they are default actions. */ +- int yyxbegin = yyn < 0 ? -yyn : 0; +- /* Stay within bounds of both yycheck and yytname. */ +- int yychecklim = YYLAST - yyn + 1; +- int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; +- int yyx; +- +- for (yyx = yyxbegin; yyx < yyxend; ++yyx) +- if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR +- && !yytable_value_is_error (yytable[yyx + yyn])) +- { +- if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) +- { +- yycount = 1; +- yysize = yysize0; +- break; +- } +- yyarg[yycount++] = yytname[yyx]; +- { +- YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); +- if (! (yysize <= yysize1 +- && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) +- return 2; +- yysize = yysize1; +- } +- } +- } +- } ++ int yyn = yypact[yystate]; + +- switch (yycount) +- { +-# define YYCASE_(N, S) \ +- case N: \ +- yyformat = S; \ +- break +- YYCASE_(0, YY_("syntax error")); +- YYCASE_(1, YY_("syntax error, unexpected %s")); +- YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); +- YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); +- YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); +- YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); +-# undef YYCASE_ +- } +- +- { +- YYSIZE_T yysize1 = yysize + yystrlen (yyformat); +- if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) +- return 2; +- yysize = yysize1; +- } +- +- if (*yymsg_alloc < yysize) ++ if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) ++ return 0; ++ else + { +- *yymsg_alloc = 2 * yysize; +- if (! (yysize <= *yymsg_alloc +- && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) +- *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; +- return 1; ++ int yytype = YYTRANSLATE (yychar); ++ YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); ++ YYSIZE_T yysize = yysize0; ++ YYSIZE_T yysize1; ++ int yysize_overflow = 0; ++ enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; ++ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; ++ int yyx; ++ ++# if 0 ++ /* This is so xgettext sees the translatable formats that are ++ constructed on the fly. */ ++ YY_("syntax error, unexpected %s"); ++ YY_("syntax error, unexpected %s, expecting %s"); ++ YY_("syntax error, unexpected %s, expecting %s or %s"); ++ YY_("syntax error, unexpected %s, expecting %s or %s or %s"); ++ YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); ++# endif ++ char *yyfmt; ++ char const *yyf; ++ static char const yyunexpected[] = "syntax error, unexpected %s"; ++ static char const yyexpecting[] = ", expecting %s"; ++ static char const yyor[] = " or %s"; ++ char yyformat[sizeof yyunexpected ++ + sizeof yyexpecting - 1 ++ + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) ++ * (sizeof yyor - 1))]; ++ char const *yyprefix = yyexpecting; ++ ++ /* Start YYX at -YYN if negative to avoid negative indexes in ++ YYCHECK. */ ++ int yyxbegin = yyn < 0 ? -yyn : 0; ++ ++ /* Stay within bounds of both yycheck and yytname. */ ++ int yychecklim = YYLAST - yyn + 1; ++ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; ++ int yycount = 1; ++ ++ yyarg[0] = yytname[yytype]; ++ yyfmt = yystpcpy (yyformat, yyunexpected); ++ ++ for (yyx = yyxbegin; yyx < yyxend; ++yyx) ++ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) ++ { ++ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) ++ { ++ yycount = 1; ++ yysize = yysize0; ++ yyformat[sizeof yyunexpected - 1] = '\0'; ++ break; ++ } ++ yyarg[yycount++] = yytname[yyx]; ++ yysize1 = yysize + yytnamerr (0, yytname[yyx]); ++ yysize_overflow |= (yysize1 < yysize); ++ yysize = yysize1; ++ yyfmt = yystpcpy (yyfmt, yyprefix); ++ yyprefix = yyor; ++ } ++ ++ yyf = YY_(yyformat); ++ yysize1 = yysize + yystrlen (yyf); ++ yysize_overflow |= (yysize1 < yysize); ++ yysize = yysize1; ++ ++ if (yysize_overflow) ++ return YYSIZE_MAXIMUM; ++ ++ if (yyresult) ++ { ++ /* Avoid sprintf, as that infringes on the user's name space. ++ Don't have undefined behavior even if the translation ++ produced a string with the wrong number of "%s"s. */ ++ char *yyp = yyresult; ++ int yyi = 0; ++ while ((*yyp = *yyf) != '\0') ++ { ++ if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) ++ { ++ yyp += yytnamerr (yyp, yyarg[yyi++]); ++ yyf += 2; ++ } ++ else ++ { ++ yyp++; ++ yyf++; ++ } ++ } ++ } ++ return yysize; + } +- +- /* Avoid sprintf, as that infringes on the user's name space. +- Don't have undefined behavior even if the translation +- produced a string with the wrong number of "%s"s. */ +- { +- char *yyp = *yymsg; +- int yyi = 0; +- while ((*yyp = *yyformat) != '\0') +- if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) +- { +- yyp += yytnamerr (yyp, yyarg[yyi++]); +- yyformat += 2; +- } +- else +- { +- yyp++; +- yyformat++; +- } +- } +- return 0; + } + #endif /* YYERROR_VERBOSE */ ++ + + /*-----------------------------------------------. + | Release the memory associated to this symbol. | + `-----------------------------------------------*/ + ++/*ARGSUSED*/ ++#if (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) + static void + yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp) ++#else ++static void ++yydestruct (yymsg, yytype, yyvaluep, yylocationp) ++ const char *yymsg; ++ int yytype; ++ YYSTYPE *yyvaluep; ++ YYLTYPE *yylocationp; ++#endif + { + YYUSE (yyvaluep); + YYUSE (yylocationp); ++ + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + +- YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +- YYUSE (yytype); +- YY_IGNORE_MAYBE_UNINITIALIZED_END +-} ++ switch (yytype) ++ { + ++ default: ++ break; ++ } ++} + ++/* Prevent warnings from -Wmissing-prototypes. */ ++#ifdef YYPARSE_PARAM ++#if defined __STDC__ || defined __cplusplus ++int yyparse (void *YYPARSE_PARAM); ++#else ++int yyparse (); ++#endif ++#else /* ! YYPARSE_PARAM */ ++#if defined __STDC__ || defined __cplusplus ++int yyparse (void); ++#else ++int yyparse (); ++#endif ++#endif /* ! YYPARSE_PARAM */ + + + /* The lookahead symbol. */ +@@ -1195,33 +1258,53 @@ int yychar; + + /* The semantic value of the lookahead symbol. */ + YYSTYPE yylval; ++ + /* Location data for the lookahead symbol. */ +-YYLTYPE yylloc +-# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL +- = { 1, 1, 1, 1 } +-# endif +-; ++YYLTYPE yylloc; ++ + /* Number of syntax errors so far. */ + int yynerrs; + + +-/*----------. +-| yyparse. | +-`----------*/ + ++/*-------------------------. ++| yyparse or yypush_parse. | ++`-------------------------*/ ++ ++#ifdef YYPARSE_PARAM ++#if (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) ++int ++yyparse (void *YYPARSE_PARAM) ++#else ++int ++yyparse (YYPARSE_PARAM) ++ void *YYPARSE_PARAM; ++#endif ++#else /* ! YYPARSE_PARAM */ ++#if (defined __STDC__ || defined __C99__FUNC__ \ ++ || defined __cplusplus || defined _MSC_VER) + int + yyparse (void) ++#else ++int ++yyparse () ++ ++#endif ++#endif + { ++ ++ + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + + /* The stacks and their tools: +- 'yyss': related to states. +- 'yyvs': related to semantic values. +- 'yyls': related to locations. ++ `yyss': related to states. ++ `yyvs': related to semantic values. ++ `yyls': related to locations. + +- Refer to the stacks through separate pointers, to allow yyoverflow ++ Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ +@@ -1240,14 +1323,14 @@ yyparse (void) + YYLTYPE *yylsp; + + /* The locations where the error started and ended. */ +- YYLTYPE yyerror_range[3]; ++ YYLTYPE yyerror_range[2]; + + YYSIZE_T yystacksize; + + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ +- int yytoken = 0; ++ int yytoken; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; +@@ -1266,9 +1349,10 @@ yyparse (void) + Keep to zero when no symbol should be popped. */ + int yylen = 0; + +- yyssp = yyss = yyssa; +- yyvsp = yyvs = yyvsa; +- yylsp = yyls = yylsa; ++ yytoken = 0; ++ yyss = yyssa; ++ yyvs = yyvsa; ++ yyls = yylsa; + yystacksize = YYINITDEPTH; + + YYDPRINTF ((stderr, "Starting parse\n")); +@@ -1277,7 +1361,21 @@ yyparse (void) + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ +- yylsp[0] = yylloc; ++ ++ /* Initialize stack pointers. ++ Waste one element of value and location stack ++ so that they stay on the same level as the state stack. ++ The wasted elements are never initialized. */ ++ yyssp = yyss; ++ yyvsp = yyvs; ++ yylsp = yyls; ++ ++#if YYLTYPE_IS_TRIVIAL ++ /* Initialize the default location before parsing starts. */ ++ yylloc.first_line = yylloc.last_line = 1; ++ yylloc.first_column = yylloc.last_column = 1; ++#endif ++ + goto yysetstate; + + /*------------------------------------------------------------. +@@ -1298,26 +1396,26 @@ yyparse (void) + + #ifdef yyoverflow + { +- /* Give user a chance to reallocate the stack. Use copies of +- these so that the &'s don't force the real ones into +- memory. */ +- YYSTYPE *yyvs1 = yyvs; +- yytype_int16 *yyss1 = yyss; +- YYLTYPE *yyls1 = yyls; +- +- /* Each stack pointer address is followed by the size of the +- data in use in that stack, in bytes. This used to be a +- conditional around just the two extra args, but that might +- be undefined if yyoverflow is a macro. */ +- yyoverflow (YY_("memory exhausted"), +- &yyss1, yysize * sizeof (*yyssp), +- &yyvs1, yysize * sizeof (*yyvsp), +- &yyls1, yysize * sizeof (*yylsp), +- &yystacksize); +- +- yyls = yyls1; +- yyss = yyss1; +- yyvs = yyvs1; ++ /* Give user a chance to reallocate the stack. Use copies of ++ these so that the &'s don't force the real ones into ++ memory. */ ++ YYSTYPE *yyvs1 = yyvs; ++ yytype_int16 *yyss1 = yyss; ++ YYLTYPE *yyls1 = yyls; ++ ++ /* Each stack pointer address is followed by the size of the ++ data in use in that stack, in bytes. This used to be a ++ conditional around just the two extra args, but that might ++ be undefined if yyoverflow is a macro. */ ++ yyoverflow (YY_("memory exhausted"), ++ &yyss1, yysize * sizeof (*yyssp), ++ &yyvs1, yysize * sizeof (*yyvsp), ++ &yyls1, yysize * sizeof (*yylsp), ++ &yystacksize); ++ ++ yyls = yyls1; ++ yyss = yyss1; ++ yyvs = yyvs1; + } + #else /* no yyoverflow */ + # ifndef YYSTACK_RELOCATE +@@ -1325,23 +1423,23 @@ yyparse (void) + # else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) +- goto yyexhaustedlab; ++ goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) +- yystacksize = YYMAXDEPTH; ++ yystacksize = YYMAXDEPTH; + + { +- yytype_int16 *yyss1 = yyss; +- union yyalloc *yyptr = +- (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); +- if (! yyptr) +- goto yyexhaustedlab; +- YYSTACK_RELOCATE (yyss_alloc, yyss); +- YYSTACK_RELOCATE (yyvs_alloc, yyvs); +- YYSTACK_RELOCATE (yyls_alloc, yyls); ++ yytype_int16 *yyss1 = yyss; ++ union yyalloc *yyptr = ++ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); ++ if (! yyptr) ++ goto yyexhaustedlab; ++ YYSTACK_RELOCATE (yyss_alloc, yyss); ++ YYSTACK_RELOCATE (yyvs_alloc, yyvs); ++ YYSTACK_RELOCATE (yyls_alloc, yyls); + # undef YYSTACK_RELOCATE +- if (yyss1 != yyssa) +- YYSTACK_FREE (yyss1); ++ if (yyss1 != yyssa) ++ YYSTACK_FREE (yyss1); + } + # endif + #endif /* no yyoverflow */ +@@ -1351,10 +1449,10 @@ yyparse (void) + yylsp = yyls + yysize - 1; + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", +- (unsigned long int) yystacksize)); ++ (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) +- YYABORT; ++ YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); +@@ -1374,7 +1472,7 @@ yybackup: + + /* First try to decide what to do without reference to lookahead token. */ + yyn = yypact[yystate]; +- if (yypact_value_is_default (yyn)) ++ if (yyn == YYPACT_NINF) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ +@@ -1383,7 +1481,7 @@ yybackup: + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); +- yychar = yylex (); ++ yychar = YYLEX; + } + + if (yychar <= YYEOF) +@@ -1405,8 +1503,8 @@ yybackup: + yyn = yytable[yyn]; + if (yyn <= 0) + { +- if (yytable_value_is_error (yyn)) +- goto yyerrlab; ++ if (yyn == 0 || yyn == YYTABLE_NINF) ++ goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } +@@ -1423,9 +1521,7 @@ yybackup: + yychar = YYEMPTY; + + yystate = yyn; +- YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; +- YY_IGNORE_MAYBE_UNINITIALIZED_END + *++yylsp = yylloc; + goto yynewstate; + +@@ -1448,7 +1544,7 @@ yyreduce: + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: +- '$$ = $1'. ++ `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison +@@ -1463,297 +1559,387 @@ yyreduce: + switch (yyn) + { + case 2: +-#line 105 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1455 of yacc.c */ ++#line 111 "dtc-parser.y" + { +- the_boot_info = build_boot_info((yyvsp[-1].re), (yyvsp[0].node), +- guess_boot_cpuid((yyvsp[0].node))); +- } +-#line 1472 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ the_boot_info = build_boot_info((yyvsp[(1) - (5)].flags) | (yyvsp[(3) - (5)].flags), (yyvsp[(4) - (5)].re), (yyvsp[(5) - (5)].node), ++ guess_boot_cpuid((yyvsp[(5) - (5)].node))); ++ ;} + break; + + case 3: +-#line 113 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1455 of yacc.c */ ++#line 119 "dtc-parser.y" + { +- (yyval.re) = NULL; +- } +-#line 1480 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ (yyval.flags) = VF_DT_V1 | (yyvsp[(2) - (2)].flags); ++ ;} + break; + + case 4: +-#line 117 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1455 of yacc.c */ ++#line 126 "dtc-parser.y" + { +- (yyval.re) = chain_reserve_entry((yyvsp[-1].re), (yyvsp[0].re)); +- } +-#line 1488 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ (yyval.flags) = VF_PLUGIN; ++ ;} + break; + + case 5: +-#line 124 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1455 of yacc.c */ ++#line 130 "dtc-parser.y" + { +- (yyval.re) = build_reserve_entry((yyvsp[-2].integer), (yyvsp[-1].integer)); +- } +-#line 1496 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ (yyval.flags) = 0; ++ ;} + break; + + case 6: +-#line 128 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1455 of yacc.c */ ++#line 137 "dtc-parser.y" + { +- add_label(&(yyvsp[0].re)->labels, (yyvsp[-1].labelref)); +- (yyval.re) = (yyvsp[0].re); +- } +-#line 1505 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ (yyval.flags) = VF_PLUGIN; ++ ;} + break; + + case 7: +-#line 136 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1455 of yacc.c */ ++#line 141 "dtc-parser.y" + { +- (yyval.node) = name_node((yyvsp[0].node), ""); +- } +-#line 1513 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ (yyval.flags) = 0; ++ ;} + break; + + case 8: +-#line 140 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1455 of yacc.c */ ++#line 148 "dtc-parser.y" + { +- (yyval.node) = merge_nodes((yyvsp[-2].node), (yyvsp[0].node)); +- } +-#line 1521 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ (yyval.re) = NULL; ++ ;} + break; + + case 9: +-#line 145 "dtc-parser.y" /* yacc.c:1646 */ +- { +- struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref)); + +- add_label(&target->labels, (yyvsp[-2].labelref)); +- if (target) +- merge_nodes(target, (yyvsp[0].node)); +- else +- ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref)); +- (yyval.node) = (yyvsp[-3].node); +- } +-#line 1536 "dtc-parser.tab.c" /* yacc.c:1646 */ ++/* Line 1455 of yacc.c */ ++#line 152 "dtc-parser.y" ++ { ++ (yyval.re) = chain_reserve_entry((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].re)); ++ ;} + break; + + case 10: +-#line 156 "dtc-parser.y" /* yacc.c:1646 */ +- { +- struct node *target = get_node_by_ref((yyvsp[-2].node), (yyvsp[-1].labelref)); + +- if (target) +- merge_nodes(target, (yyvsp[0].node)); +- else +- ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref)); +- (yyval.node) = (yyvsp[-2].node); +- } +-#line 1550 "dtc-parser.tab.c" /* yacc.c:1646 */ ++/* Line 1455 of yacc.c */ ++#line 159 "dtc-parser.y" ++ { ++ (yyval.re) = build_reserve_entry((yyvsp[(2) - (4)].integer), (yyvsp[(3) - (4)].integer)); ++ ;} + break; + + case 11: +-#line 166 "dtc-parser.y" /* yacc.c:1646 */ +- { +- struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref)); + +- if (target) +- delete_node(target); +- else +- ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref)); +- +- +- (yyval.node) = (yyvsp[-3].node); +- } +-#line 1566 "dtc-parser.tab.c" /* yacc.c:1646 */ ++/* Line 1455 of yacc.c */ ++#line 163 "dtc-parser.y" ++ { ++ add_label(&(yyvsp[(2) - (2)].re)->labels, (yyvsp[(1) - (2)].labelref)); ++ (yyval.re) = (yyvsp[(2) - (2)].re); ++ ;} + break; + + case 12: +-#line 181 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1455 of yacc.c */ ++#line 171 "dtc-parser.y" + { +- (yyval.node) = build_node((yyvsp[-3].proplist), (yyvsp[-2].nodelist)); +- } +-#line 1574 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ (yyval.node) = name_node((yyvsp[(2) - (2)].node), ""); ++ ;} + break; + + case 13: +-#line 188 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1455 of yacc.c */ ++#line 175 "dtc-parser.y" + { +- (yyval.proplist) = NULL; +- } +-#line 1582 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ (yyval.node) = merge_nodes((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node)); ++ ;} + break; + + case 14: +-#line 192 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1455 of yacc.c */ ++#line 180 "dtc-parser.y" + { +- (yyval.proplist) = chain_property((yyvsp[0].prop), (yyvsp[-1].proplist)); +- } +-#line 1590 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ struct node *target = get_node_by_ref((yyvsp[(1) - (4)].node), (yyvsp[(3) - (4)].labelref)); ++ ++ add_label(&target->labels, (yyvsp[(2) - (4)].labelref)); ++ if (target) ++ merge_nodes(target, (yyvsp[(4) - (4)].node)); ++ else ++ ERROR(&(yylsp[(3) - (4)]), "Label or path %s not found", (yyvsp[(3) - (4)].labelref)); ++ (yyval.node) = (yyvsp[(1) - (4)].node); ++ ;} + break; + + case 15: +-#line 199 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1455 of yacc.c */ ++#line 191 "dtc-parser.y" + { +- (yyval.prop) = build_property((yyvsp[-3].propnodename), (yyvsp[-1].data)); +- } +-#line 1598 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ struct node *target = get_node_by_ref((yyvsp[(1) - (3)].node), (yyvsp[(2) - (3)].labelref)); ++ ++ if (target) { ++ merge_nodes(target, (yyvsp[(3) - (3)].node)); ++ } else { ++ if (symbol_fixup_support) ++ add_orphan_node((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yyvsp[(2) - (3)].labelref)); ++ else ++ ERROR(&(yylsp[(2) - (3)]), "Label or path %s not found", (yyvsp[(2) - (3)].labelref)); ++ } ++ (yyval.node) = (yyvsp[(1) - (3)].node); ++ ;} + break; + + case 16: +-#line 203 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1455 of yacc.c */ ++#line 205 "dtc-parser.y" + { +- (yyval.prop) = build_property((yyvsp[-1].propnodename), empty_data); +- } +-#line 1606 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ struct node *target = get_node_by_ref((yyvsp[(1) - (4)].node), (yyvsp[(3) - (4)].labelref)); ++ ++ if (target) ++ delete_node(target); ++ else ++ ERROR(&(yylsp[(3) - (4)]), "Label or path %s not found", (yyvsp[(3) - (4)].labelref)); ++ ++ ++ (yyval.node) = (yyvsp[(1) - (4)].node); ++ ;} + break; + + case 17: +-#line 207 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1455 of yacc.c */ ++#line 217 "dtc-parser.y" + { +- (yyval.prop) = build_property_delete((yyvsp[-1].propnodename)); +- } +-#line 1614 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ /* build empty node */ ++ (yyval.node) = name_node(build_node(NULL, NULL), ""); ++ ;} + break; + + case 18: +-#line 211 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1455 of yacc.c */ ++#line 225 "dtc-parser.y" + { +- add_label(&(yyvsp[0].prop)->labels, (yyvsp[-1].labelref)); +- (yyval.prop) = (yyvsp[0].prop); +- } +-#line 1623 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ (yyval.node) = build_node((yyvsp[(2) - (5)].proplist), (yyvsp[(3) - (5)].nodelist)); ++ ;} + break; + + case 19: +-#line 219 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1455 of yacc.c */ ++#line 232 "dtc-parser.y" + { +- (yyval.data) = data_merge((yyvsp[-1].data), (yyvsp[0].data)); +- } +-#line 1631 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ (yyval.proplist) = NULL; ++ ;} + break; + + case 20: +-#line 223 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1455 of yacc.c */ ++#line 236 "dtc-parser.y" + { +- (yyval.data) = data_merge((yyvsp[-2].data), (yyvsp[-1].array).data); +- } +-#line 1639 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ (yyval.proplist) = chain_property((yyvsp[(2) - (2)].prop), (yyvsp[(1) - (2)].proplist)); ++ ;} + break; + + case 21: +-#line 227 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1455 of yacc.c */ ++#line 243 "dtc-parser.y" + { +- (yyval.data) = data_merge((yyvsp[-3].data), (yyvsp[-1].data)); +- } +-#line 1647 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ (yyval.prop) = build_property((yyvsp[(1) - (4)].propnodename), (yyvsp[(3) - (4)].data)); ++ ;} + break; + + case 22: +-#line 231 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1455 of yacc.c */ ++#line 247 "dtc-parser.y" + { +- (yyval.data) = data_add_marker((yyvsp[-1].data), REF_PATH, (yyvsp[0].labelref)); +- } +-#line 1655 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ (yyval.prop) = build_property((yyvsp[(1) - (2)].propnodename), empty_data); ++ ;} + break; + + case 23: +-#line 235 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1455 of yacc.c */ ++#line 251 "dtc-parser.y" ++ { ++ (yyval.prop) = build_property_delete((yyvsp[(2) - (3)].propnodename)); ++ ;} ++ break; ++ ++ case 24: ++ ++/* Line 1455 of yacc.c */ ++#line 255 "dtc-parser.y" ++ { ++ add_label(&(yyvsp[(2) - (2)].prop)->labels, (yyvsp[(1) - (2)].labelref)); ++ (yyval.prop) = (yyvsp[(2) - (2)].prop); ++ ;} ++ break; ++ ++ case 25: ++ ++/* Line 1455 of yacc.c */ ++#line 263 "dtc-parser.y" + { +- FILE *f = srcfile_relative_open((yyvsp[-5].data).val, NULL); ++ (yyval.data) = data_merge((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].data)); ++ ;} ++ break; ++ ++ case 26: ++ ++/* Line 1455 of yacc.c */ ++#line 267 "dtc-parser.y" ++ { ++ (yyval.data) = data_merge((yyvsp[(1) - (3)].data), (yyvsp[(2) - (3)].array).data); ++ ;} ++ break; ++ ++ case 27: ++ ++/* Line 1455 of yacc.c */ ++#line 271 "dtc-parser.y" ++ { ++ (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data)); ++ ;} ++ break; ++ ++ case 28: ++ ++/* Line 1455 of yacc.c */ ++#line 275 "dtc-parser.y" ++ { ++ (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), REF_PATH, (yyvsp[(2) - (2)].labelref)); ++ ;} ++ break; ++ ++ case 29: ++ ++/* Line 1455 of yacc.c */ ++#line 279 "dtc-parser.y" ++ { ++ FILE *f = srcfile_relative_open((yyvsp[(4) - (9)].data).val, NULL); + struct data d; + +- if ((yyvsp[-3].integer) != 0) +- if (fseek(f, (yyvsp[-3].integer), SEEK_SET) != 0) ++ if ((yyvsp[(6) - (9)].integer) != 0) ++ if (fseek(f, (yyvsp[(6) - (9)].integer), SEEK_SET) != 0) + die("Couldn't seek to offset %llu in \"%s\": %s", +- (unsigned long long)(yyvsp[-3].integer), (yyvsp[-5].data).val, ++ (unsigned long long)(yyvsp[(6) - (9)].integer), (yyvsp[(4) - (9)].data).val, + strerror(errno)); + +- d = data_copy_file(f, (yyvsp[-1].integer)); ++ d = data_copy_file(f, (yyvsp[(8) - (9)].integer)); + +- (yyval.data) = data_merge((yyvsp[-8].data), d); ++ (yyval.data) = data_merge((yyvsp[(1) - (9)].data), d); + fclose(f); +- } +-#line 1675 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ;} + break; + +- case 24: +-#line 251 "dtc-parser.y" /* yacc.c:1646 */ ++ case 30: ++ ++/* Line 1455 of yacc.c */ ++#line 295 "dtc-parser.y" + { +- FILE *f = srcfile_relative_open((yyvsp[-1].data).val, NULL); ++ FILE *f = srcfile_relative_open((yyvsp[(4) - (5)].data).val, NULL); + struct data d = empty_data; + + d = data_copy_file(f, -1); + +- (yyval.data) = data_merge((yyvsp[-4].data), d); ++ (yyval.data) = data_merge((yyvsp[(1) - (5)].data), d); + fclose(f); +- } +-#line 1689 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ;} + break; + +- case 25: +-#line 261 "dtc-parser.y" /* yacc.c:1646 */ ++ case 31: ++ ++/* Line 1455 of yacc.c */ ++#line 305 "dtc-parser.y" + { +- (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); +- } +-#line 1697 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); ++ ;} + break; + +- case 26: +-#line 268 "dtc-parser.y" /* yacc.c:1646 */ ++ case 32: ++ ++/* Line 1455 of yacc.c */ ++#line 312 "dtc-parser.y" + { + (yyval.data) = empty_data; +- } +-#line 1705 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ;} + break; + +- case 27: +-#line 272 "dtc-parser.y" /* yacc.c:1646 */ ++ case 33: ++ ++/* Line 1455 of yacc.c */ ++#line 316 "dtc-parser.y" + { +- (yyval.data) = (yyvsp[-1].data); +- } +-#line 1713 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ (yyval.data) = (yyvsp[(1) - (2)].data); ++ ;} + break; + +- case 28: +-#line 276 "dtc-parser.y" /* yacc.c:1646 */ ++ case 34: ++ ++/* Line 1455 of yacc.c */ ++#line 320 "dtc-parser.y" + { +- (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); +- } +-#line 1721 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); ++ ;} + break; + +- case 29: +-#line 283 "dtc-parser.y" /* yacc.c:1646 */ ++ case 35: ++ ++/* Line 1455 of yacc.c */ ++#line 327 "dtc-parser.y" + { + unsigned long long bits; + +- bits = (yyvsp[-1].integer); ++ bits = (yyvsp[(2) - (3)].integer); + + if ((bits != 8) && (bits != 16) && + (bits != 32) && (bits != 64)) { +- ERROR(&(yylsp[-1]), "Array elements must be" ++ ERROR(&(yylsp[(2) - (3)]), "Array elements must be" + " 8, 16, 32 or 64-bits"); + bits = 32; + } + + (yyval.array).data = empty_data; + (yyval.array).bits = bits; +- } +-#line 1741 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ;} + break; + +- case 30: +-#line 299 "dtc-parser.y" /* yacc.c:1646 */ ++ case 36: ++ ++/* Line 1455 of yacc.c */ ++#line 343 "dtc-parser.y" + { + (yyval.array).data = empty_data; + (yyval.array).bits = 32; +- } +-#line 1750 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ;} + break; + +- case 31: +-#line 304 "dtc-parser.y" /* yacc.c:1646 */ ++ case 37: ++ ++/* Line 1455 of yacc.c */ ++#line 348 "dtc-parser.y" + { +- if ((yyvsp[-1].array).bits < 64) { +- uint64_t mask = (1ULL << (yyvsp[-1].array).bits) - 1; ++ if ((yyvsp[(1) - (2)].array).bits < 64) { ++ uint64_t mask = (1ULL << (yyvsp[(1) - (2)].array).bits) - 1; + /* + * Bits above mask must either be all zero + * (positive within range of mask) or all one +@@ -1762,285 +1948,309 @@ yyreduce: + * within the mask to one (i.e. | in the + * mask), all bits are one. + */ +- if (((yyvsp[0].integer) > mask) && (((yyvsp[0].integer) | mask) != -1ULL)) +- ERROR(&(yylsp[0]), "Value out of range for" +- " %d-bit array element", (yyvsp[-1].array).bits); ++ if (((yyvsp[(2) - (2)].integer) > mask) && (((yyvsp[(2) - (2)].integer) | mask) != -1ULL)) ++ ERROR(&(yylsp[(2) - (2)]), "Value out of range for" ++ " %d-bit array element", (yyvsp[(1) - (2)].array).bits); + } + +- (yyval.array).data = data_append_integer((yyvsp[-1].array).data, (yyvsp[0].integer), (yyvsp[-1].array).bits); +- } +-#line 1773 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ (yyval.array).data = data_append_integer((yyvsp[(1) - (2)].array).data, (yyvsp[(2) - (2)].integer), (yyvsp[(1) - (2)].array).bits); ++ ;} + break; + +- case 32: +-#line 323 "dtc-parser.y" /* yacc.c:1646 */ ++ case 38: ++ ++/* Line 1455 of yacc.c */ ++#line 367 "dtc-parser.y" + { +- uint64_t val = ~0ULL >> (64 - (yyvsp[-1].array).bits); ++ uint64_t val = ~0ULL >> (64 - (yyvsp[(1) - (2)].array).bits); + +- if ((yyvsp[-1].array).bits == 32) +- (yyvsp[-1].array).data = data_add_marker((yyvsp[-1].array).data, ++ if ((yyvsp[(1) - (2)].array).bits == 32) ++ (yyvsp[(1) - (2)].array).data = data_add_marker((yyvsp[(1) - (2)].array).data, + REF_PHANDLE, +- (yyvsp[0].labelref)); ++ (yyvsp[(2) - (2)].labelref)); + else +- ERROR(&(yylsp[0]), "References are only allowed in " ++ ERROR(&(yylsp[(2) - (2)]), "References are only allowed in " + "arrays with 32-bit elements."); + +- (yyval.array).data = data_append_integer((yyvsp[-1].array).data, val, (yyvsp[-1].array).bits); +- } +-#line 1791 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ (yyval.array).data = data_append_integer((yyvsp[(1) - (2)].array).data, val, (yyvsp[(1) - (2)].array).bits); ++ ;} + break; + +- case 33: +-#line 337 "dtc-parser.y" /* yacc.c:1646 */ +- { +- (yyval.array).data = data_add_marker((yyvsp[-1].array).data, LABEL, (yyvsp[0].labelref)); +- } +-#line 1799 "dtc-parser.tab.c" /* yacc.c:1646 */ +- break; ++ case 39: + +- case 36: +-#line 346 "dtc-parser.y" /* yacc.c:1646 */ ++/* Line 1455 of yacc.c */ ++#line 381 "dtc-parser.y" + { +- (yyval.integer) = (yyvsp[-1].integer); +- } +-#line 1807 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ (yyval.array).data = data_add_marker((yyvsp[(1) - (2)].array).data, LABEL, (yyvsp[(2) - (2)].labelref)); ++ ;} + break; + +- case 39: +-#line 357 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-4].integer) ? (yyvsp[-2].integer) : (yyvsp[0].integer); } +-#line 1813 "dtc-parser.tab.c" /* yacc.c:1646 */ +- break; +- +- case 41: +-#line 362 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) || (yyvsp[0].integer); } +-#line 1819 "dtc-parser.tab.c" /* yacc.c:1646 */ +- break; ++ case 42: + +- case 43: +-#line 367 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) && (yyvsp[0].integer); } +-#line 1825 "dtc-parser.tab.c" /* yacc.c:1646 */ ++/* Line 1455 of yacc.c */ ++#line 390 "dtc-parser.y" ++ { ++ (yyval.integer) = (yyvsp[(2) - (3)].integer); ++ ;} + break; + + case 45: +-#line 372 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) | (yyvsp[0].integer); } +-#line 1831 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ++/* Line 1455 of yacc.c */ ++#line 401 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (5)].integer) ? (yyvsp[(3) - (5)].integer) : (yyvsp[(5) - (5)].integer); ;} + break; + + case 47: +-#line 377 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) ^ (yyvsp[0].integer); } +-#line 1837 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ++/* Line 1455 of yacc.c */ ++#line 406 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) || (yyvsp[(3) - (3)].integer); ;} + break; + + case 49: +-#line 382 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) & (yyvsp[0].integer); } +-#line 1843 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ++/* Line 1455 of yacc.c */ ++#line 411 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) && (yyvsp[(3) - (3)].integer); ;} + break; + + case 51: +-#line 387 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) == (yyvsp[0].integer); } +-#line 1849 "dtc-parser.tab.c" /* yacc.c:1646 */ +- break; + +- case 52: +-#line 388 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) != (yyvsp[0].integer); } +-#line 1855 "dtc-parser.tab.c" /* yacc.c:1646 */ ++/* Line 1455 of yacc.c */ ++#line 416 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) | (yyvsp[(3) - (3)].integer); ;} + break; + +- case 54: +-#line 393 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) < (yyvsp[0].integer); } +-#line 1861 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ case 53: ++ ++/* Line 1455 of yacc.c */ ++#line 421 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) ^ (yyvsp[(3) - (3)].integer); ;} + break; + + case 55: +-#line 394 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) > (yyvsp[0].integer); } +-#line 1867 "dtc-parser.tab.c" /* yacc.c:1646 */ +- break; + +- case 56: +-#line 395 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) <= (yyvsp[0].integer); } +-#line 1873 "dtc-parser.tab.c" /* yacc.c:1646 */ ++/* Line 1455 of yacc.c */ ++#line 426 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) & (yyvsp[(3) - (3)].integer); ;} + break; + + case 57: +-#line 396 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) >= (yyvsp[0].integer); } +-#line 1879 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ++/* Line 1455 of yacc.c */ ++#line 431 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) == (yyvsp[(3) - (3)].integer); ;} + break; + + case 58: +-#line 400 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) << (yyvsp[0].integer); } +-#line 1885 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ++/* Line 1455 of yacc.c */ ++#line 432 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) != (yyvsp[(3) - (3)].integer); ;} + break; + +- case 59: +-#line 401 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) >> (yyvsp[0].integer); } +-#line 1891 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ case 60: ++ ++/* Line 1455 of yacc.c */ ++#line 437 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) < (yyvsp[(3) - (3)].integer); ;} + break; + + case 61: +-#line 406 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) + (yyvsp[0].integer); } +-#line 1897 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ++/* Line 1455 of yacc.c */ ++#line 438 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) > (yyvsp[(3) - (3)].integer); ;} + break; + + case 62: +-#line 407 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) - (yyvsp[0].integer); } +-#line 1903 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ++/* Line 1455 of yacc.c */ ++#line 439 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) <= (yyvsp[(3) - (3)].integer); ;} ++ break; ++ ++ case 63: ++ ++/* Line 1455 of yacc.c */ ++#line 440 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) >= (yyvsp[(3) - (3)].integer); ;} + break; + + case 64: +-#line 412 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = (yyvsp[-2].integer) * (yyvsp[0].integer); } +-#line 1909 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ++/* Line 1455 of yacc.c */ ++#line 444 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) << (yyvsp[(3) - (3)].integer); ;} + break; + + case 65: +-#line 414 "dtc-parser.y" /* yacc.c:1646 */ ++ ++/* Line 1455 of yacc.c */ ++#line 445 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) >> (yyvsp[(3) - (3)].integer); ;} ++ break; ++ ++ case 67: ++ ++/* Line 1455 of yacc.c */ ++#line 450 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) + (yyvsp[(3) - (3)].integer); ;} ++ break; ++ ++ case 68: ++ ++/* Line 1455 of yacc.c */ ++#line 451 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) - (yyvsp[(3) - (3)].integer); ;} ++ break; ++ ++ case 70: ++ ++/* Line 1455 of yacc.c */ ++#line 456 "dtc-parser.y" ++ { (yyval.integer) = (yyvsp[(1) - (3)].integer) * (yyvsp[(3) - (3)].integer); ;} ++ break; ++ ++ case 71: ++ ++/* Line 1455 of yacc.c */ ++#line 458 "dtc-parser.y" + { +- if ((yyvsp[0].integer) != 0) { +- (yyval.integer) = (yyvsp[-2].integer) / (yyvsp[0].integer); ++ if ((yyvsp[(3) - (3)].integer) != 0) { ++ (yyval.integer) = (yyvsp[(1) - (3)].integer) / (yyvsp[(3) - (3)].integer); + } else { + ERROR(&(yyloc), "Division by zero"); + (yyval.integer) = 0; + } +- } +-#line 1922 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ;} + break; + +- case 66: +-#line 423 "dtc-parser.y" /* yacc.c:1646 */ ++ case 72: ++ ++/* Line 1455 of yacc.c */ ++#line 467 "dtc-parser.y" + { +- if ((yyvsp[0].integer) != 0) { +- (yyval.integer) = (yyvsp[-2].integer) % (yyvsp[0].integer); ++ if ((yyvsp[(3) - (3)].integer) != 0) { ++ (yyval.integer) = (yyvsp[(1) - (3)].integer) % (yyvsp[(3) - (3)].integer); + } else { + ERROR(&(yyloc), "Division by zero"); + (yyval.integer) = 0; + } +- } +-#line 1935 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ;} + break; + +- case 69: +-#line 436 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = -(yyvsp[0].integer); } +-#line 1941 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ case 75: ++ ++/* Line 1455 of yacc.c */ ++#line 480 "dtc-parser.y" ++ { (yyval.integer) = -(yyvsp[(2) - (2)].integer); ;} + break; + +- case 70: +-#line 437 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = ~(yyvsp[0].integer); } +-#line 1947 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ case 76: ++ ++/* Line 1455 of yacc.c */ ++#line 481 "dtc-parser.y" ++ { (yyval.integer) = ~(yyvsp[(2) - (2)].integer); ;} + break; + +- case 71: +-#line 438 "dtc-parser.y" /* yacc.c:1646 */ +- { (yyval.integer) = !(yyvsp[0].integer); } +-#line 1953 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ case 77: ++ ++/* Line 1455 of yacc.c */ ++#line 482 "dtc-parser.y" ++ { (yyval.integer) = !(yyvsp[(2) - (2)].integer); ;} + break; + +- case 72: +-#line 443 "dtc-parser.y" /* yacc.c:1646 */ ++ case 78: ++ ++/* Line 1455 of yacc.c */ ++#line 487 "dtc-parser.y" + { + (yyval.data) = empty_data; +- } +-#line 1961 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ;} + break; + +- case 73: +-#line 447 "dtc-parser.y" /* yacc.c:1646 */ ++ case 79: ++ ++/* Line 1455 of yacc.c */ ++#line 491 "dtc-parser.y" + { +- (yyval.data) = data_append_byte((yyvsp[-1].data), (yyvsp[0].byte)); +- } +-#line 1969 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ (yyval.data) = data_append_byte((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].byte)); ++ ;} + break; + +- case 74: +-#line 451 "dtc-parser.y" /* yacc.c:1646 */ ++ case 80: ++ ++/* Line 1455 of yacc.c */ ++#line 495 "dtc-parser.y" + { +- (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); +- } +-#line 1977 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); ++ ;} + break; + +- case 75: +-#line 458 "dtc-parser.y" /* yacc.c:1646 */ ++ case 81: ++ ++/* Line 1455 of yacc.c */ ++#line 502 "dtc-parser.y" + { + (yyval.nodelist) = NULL; +- } +-#line 1985 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ;} + break; + +- case 76: +-#line 462 "dtc-parser.y" /* yacc.c:1646 */ ++ case 82: ++ ++/* Line 1455 of yacc.c */ ++#line 506 "dtc-parser.y" + { +- (yyval.nodelist) = chain_node((yyvsp[-1].node), (yyvsp[0].nodelist)); +- } +-#line 1993 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ (yyval.nodelist) = chain_node((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].nodelist)); ++ ;} + break; + +- case 77: +-#line 466 "dtc-parser.y" /* yacc.c:1646 */ ++ case 83: ++ ++/* Line 1455 of yacc.c */ ++#line 510 "dtc-parser.y" + { +- ERROR(&(yylsp[0]), "Properties must precede subnodes"); ++ ERROR(&(yylsp[(2) - (2)]), "Properties must precede subnodes"); + YYERROR; +- } +-#line 2002 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ;} + break; + +- case 78: +-#line 474 "dtc-parser.y" /* yacc.c:1646 */ ++ case 84: ++ ++/* Line 1455 of yacc.c */ ++#line 518 "dtc-parser.y" + { +- (yyval.node) = name_node((yyvsp[0].node), (yyvsp[-1].propnodename)); +- } +-#line 2010 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ (yyval.node) = name_node((yyvsp[(2) - (2)].node), (yyvsp[(1) - (2)].propnodename)); ++ ;} + break; + +- case 79: +-#line 478 "dtc-parser.y" /* yacc.c:1646 */ ++ case 85: ++ ++/* Line 1455 of yacc.c */ ++#line 522 "dtc-parser.y" + { +- (yyval.node) = name_node(build_node_delete(), (yyvsp[-1].propnodename)); +- } +-#line 2018 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ (yyval.node) = name_node(build_node_delete(), (yyvsp[(2) - (3)].propnodename)); ++ ;} + break; + +- case 80: +-#line 482 "dtc-parser.y" /* yacc.c:1646 */ ++ case 86: ++ ++/* Line 1455 of yacc.c */ ++#line 526 "dtc-parser.y" + { +- add_label(&(yyvsp[0].node)->labels, (yyvsp[-1].labelref)); +- (yyval.node) = (yyvsp[0].node); +- } +-#line 2027 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ add_label(&(yyvsp[(2) - (2)].node)->labels, (yyvsp[(1) - (2)].labelref)); ++ (yyval.node) = (yyvsp[(2) - (2)].node); ++ ;} + break; + + +-#line 2031 "dtc-parser.tab.c" /* yacc.c:1646 */ ++ ++/* Line 1455 of yacc.c */ ++#line 2252 "dtc-parser.tab.c" + default: break; + } +- /* User semantic actions sometimes alter yychar, and that requires +- that yytoken be updated with the new translation. We take the +- approach of translating immediately before every use of yytoken. +- One alternative is translating here after every semantic action, +- but that translation would be missed if the semantic action invokes +- YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or +- if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an +- incorrect destructor might then be invoked immediately. In the +- case of YYERROR or YYBACKUP, subsequent parser actions might lead +- to an incorrect destructor call or verbose syntax error message +- before the lookahead is translated. */ + YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + + YYPOPSTACK (yylen); +@@ -2050,7 +2260,7 @@ yyreduce: + *++yyvsp = yyval; + *++yylsp = yyloc; + +- /* Now 'shift' the result of the reduction. Determine what state ++ /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + +@@ -2065,14 +2275,10 @@ yyreduce: + goto yynewstate; + + +-/*--------------------------------------. +-| yyerrlab -- here on detecting error. | +-`--------------------------------------*/ ++/*------------------------------------. ++| yyerrlab -- here on detecting error | ++`------------------------------------*/ + yyerrlab: +- /* Make sure we have latest lookahead translation. See comments at +- user semantic actions for why this is necessary. */ +- yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); +- + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { +@@ -2080,58 +2286,59 @@ yyerrlab: + #if ! YYERROR_VERBOSE + yyerror (YY_("syntax error")); + #else +-# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ +- yyssp, yytoken) + { +- char const *yymsgp = YY_("syntax error"); +- int yysyntax_error_status; +- yysyntax_error_status = YYSYNTAX_ERROR; +- if (yysyntax_error_status == 0) +- yymsgp = yymsg; +- else if (yysyntax_error_status == 1) +- { +- if (yymsg != yymsgbuf) +- YYSTACK_FREE (yymsg); +- yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); +- if (!yymsg) +- { +- yymsg = yymsgbuf; +- yymsg_alloc = sizeof yymsgbuf; +- yysyntax_error_status = 2; +- } +- else +- { +- yysyntax_error_status = YYSYNTAX_ERROR; +- yymsgp = yymsg; +- } +- } +- yyerror (yymsgp); +- if (yysyntax_error_status == 2) +- goto yyexhaustedlab; ++ YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); ++ if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) ++ { ++ YYSIZE_T yyalloc = 2 * yysize; ++ if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) ++ yyalloc = YYSTACK_ALLOC_MAXIMUM; ++ if (yymsg != yymsgbuf) ++ YYSTACK_FREE (yymsg); ++ yymsg = (char *) YYSTACK_ALLOC (yyalloc); ++ if (yymsg) ++ yymsg_alloc = yyalloc; ++ else ++ { ++ yymsg = yymsgbuf; ++ yymsg_alloc = sizeof yymsgbuf; ++ } ++ } ++ ++ if (0 < yysize && yysize <= yymsg_alloc) ++ { ++ (void) yysyntax_error (yymsg, yystate, yychar); ++ yyerror (yymsg); ++ } ++ else ++ { ++ yyerror (YY_("syntax error")); ++ if (yysize != 0) ++ goto yyexhaustedlab; ++ } + } +-# undef YYSYNTAX_ERROR + #endif + } + +- yyerror_range[1] = yylloc; ++ yyerror_range[0] = yylloc; + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an +- error, discard it. */ ++ error, discard it. */ + + if (yychar <= YYEOF) +- { +- /* Return failure if at end of input. */ +- if (yychar == YYEOF) +- YYABORT; +- } ++ { ++ /* Return failure if at end of input. */ ++ if (yychar == YYEOF) ++ YYABORT; ++ } + else +- { +- yydestruct ("Error: discarding", +- yytoken, &yylval, &yylloc); +- yychar = YYEMPTY; +- } ++ { ++ yydestruct ("Error: discarding", ++ yytoken, &yylval, &yylloc); ++ yychar = YYEMPTY; ++ } + } + + /* Else will try to reuse lookahead token after shifting the error +@@ -2150,8 +2357,8 @@ yyerrorlab: + if (/*CONSTCOND*/ 0) + goto yyerrorlab; + +- yyerror_range[1] = yylsp[1-yylen]; +- /* Do not reclaim the symbols of the rule whose action triggered ++ yyerror_range[0] = yylsp[1-yylen]; ++ /* Do not reclaim the symbols of the rule which action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; +@@ -2164,42 +2371,40 @@ yyerrorlab: + | yyerrlab1 -- common code for both syntax error and YYERROR. | + `-------------------------------------------------------------*/ + yyerrlab1: +- yyerrstatus = 3; /* Each real token shifted decrements this. */ ++ yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; +- if (!yypact_value_is_default (yyn)) +- { +- yyn += YYTERROR; +- if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) +- { +- yyn = yytable[yyn]; +- if (0 < yyn) +- break; +- } +- } ++ if (yyn != YYPACT_NINF) ++ { ++ yyn += YYTERROR; ++ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) ++ { ++ yyn = yytable[yyn]; ++ if (0 < yyn) ++ break; ++ } ++ } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) +- YYABORT; ++ YYABORT; + +- yyerror_range[1] = *yylsp; ++ yyerror_range[0] = *yylsp; + yydestruct ("Error: popping", +- yystos[yystate], yyvsp, yylsp); ++ yystos[yystate], yyvsp, yylsp); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + +- YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; +- YY_IGNORE_MAYBE_UNINITIALIZED_END + +- yyerror_range[2] = yylloc; ++ yyerror_range[1] = yylloc; + /* Using YYLLOC is tempting, but would change the location of + the lookahead. YYLOC is available though. */ +- YYLLOC_DEFAULT (yyloc, yyerror_range, 2); ++ YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2); + *++yylsp = yyloc; + + /* Shift the error token. */ +@@ -2223,7 +2428,7 @@ yyabortlab: + yyresult = 1; + goto yyreturn; + +-#if !defined yyoverflow || YYERROR_VERBOSE ++#if !defined(yyoverflow) || YYERROR_VERBOSE + /*-------------------------------------------------. + | yyexhaustedlab -- memory exhaustion comes here. | + `-------------------------------------------------*/ +@@ -2235,21 +2440,16 @@ yyexhaustedlab: + + yyreturn: + if (yychar != YYEMPTY) +- { +- /* Make sure we have latest lookahead translation. See comments at +- user semantic actions for why this is necessary. */ +- yytoken = YYTRANSLATE (yychar); +- yydestruct ("Cleanup: discarding lookahead", +- yytoken, &yylval, &yylloc); +- } +- /* Do not reclaim the symbols of the rule whose action triggered ++ yydestruct ("Cleanup: discarding lookahead", ++ yytoken, &yylval, &yylloc); ++ /* Do not reclaim the symbols of the rule which action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", +- yystos[*yyssp], yyvsp, yylsp); ++ yystos[*yyssp], yyvsp, yylsp); + YYPOPSTACK (1); + } + #ifndef yyoverflow +@@ -2260,12 +2460,18 @@ yyreturn: + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + #endif +- return yyresult; ++ /* Make sure YYID is used. */ ++ return YYID (yyresult); + } +-#line 488 "dtc-parser.y" /* yacc.c:1906 */ ++ ++ ++ ++/* Line 1675 of yacc.c */ ++#line 532 "dtc-parser.y" + + + void yyerror(char const *s) + { + ERROR(&yylloc, "%s", s); + } ++ +diff --git a/scripts/dtc/dtc-parser.tab.h_shipped b/scripts/dtc/dtc-parser.tab.h_shipped +index 30867c6..18c7d5b 100644 +--- a/scripts/dtc/dtc-parser.tab.h_shipped ++++ b/scripts/dtc/dtc-parser.tab.h_shipped +@@ -1,19 +1,21 @@ +-/* A Bison parser, made by GNU Bison 3.0.2. */ + +-/* Bison interface for Yacc-like parsers in C +- +- Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. ++/* A Bison parser, made by GNU Bison 2.4.1. */ + ++/* Skeleton interface for Bison's Yacc-like parsers in C ++ ++ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 ++ Free Software Foundation, Inc. ++ + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. +- ++ + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. +- ++ + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +@@ -26,55 +28,50 @@ + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. +- ++ + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +-#ifndef YY_YY_DTC_PARSER_TAB_H_INCLUDED +-# define YY_YY_DTC_PARSER_TAB_H_INCLUDED +-/* Debug traces. */ +-#ifndef YYDEBUG +-# define YYDEBUG 0 +-#endif +-#if YYDEBUG +-extern int yydebug; +-#endif + +-/* Token type. */ ++/* Tokens. */ + #ifndef YYTOKENTYPE + # define YYTOKENTYPE +- enum yytokentype +- { +- DT_V1 = 258, +- DT_MEMRESERVE = 259, +- DT_LSHIFT = 260, +- DT_RSHIFT = 261, +- DT_LE = 262, +- DT_GE = 263, +- DT_EQ = 264, +- DT_NE = 265, +- DT_AND = 266, +- DT_OR = 267, +- DT_BITS = 268, +- DT_DEL_PROP = 269, +- DT_DEL_NODE = 270, +- DT_PROPNODENAME = 271, +- DT_LITERAL = 272, +- DT_CHAR_LITERAL = 273, +- DT_BYTE = 274, +- DT_STRING = 275, +- DT_LABEL = 276, +- DT_REF = 277, +- DT_INCBIN = 278 +- }; ++ /* Put the tokens into the symbol table, so that GDB and other debuggers ++ know about them. */ ++ enum yytokentype { ++ DT_V1 = 258, ++ DT_PLUGIN = 259, ++ DT_MEMRESERVE = 260, ++ DT_LSHIFT = 261, ++ DT_RSHIFT = 262, ++ DT_LE = 263, ++ DT_GE = 264, ++ DT_EQ = 265, ++ DT_NE = 266, ++ DT_AND = 267, ++ DT_OR = 268, ++ DT_BITS = 269, ++ DT_DEL_PROP = 270, ++ DT_DEL_NODE = 271, ++ DT_PROPNODENAME = 272, ++ DT_LITERAL = 273, ++ DT_CHAR_LITERAL = 274, ++ DT_BYTE = 275, ++ DT_STRING = 276, ++ DT_LABEL = 277, ++ DT_REF = 278, ++ DT_INCBIN = 279 ++ }; + #endif + +-/* Value type. */ ++ ++ + #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +-typedef union YYSTYPE YYSTYPE; +-union YYSTYPE ++typedef union YYSTYPE + { +-#line 38 "dtc-parser.y" /* yacc.c:1909 */ ++ ++/* Line 1676 of yacc.c */ ++#line 39 "dtc-parser.y" + + char *propnodename; + char *labelref; +@@ -92,30 +89,32 @@ union YYSTYPE + struct node *nodelist; + struct reserve_info *re; + uint64_t integer; ++ unsigned int flags; ++ + +-#line 97 "dtc-parser.tab.h" /* yacc.c:1909 */ +-}; ++ ++/* Line 1676 of yacc.c */ ++#line 98 "dtc-parser.tab.h" ++} YYSTYPE; + # define YYSTYPE_IS_TRIVIAL 1 ++# define yystype YYSTYPE /* obsolescent; will be withdrawn */ + # define YYSTYPE_IS_DECLARED 1 + #endif + +-/* Location type. */ ++extern YYSTYPE yylval; ++ + #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED +-typedef struct YYLTYPE YYLTYPE; +-struct YYLTYPE ++typedef struct YYLTYPE + { + int first_line; + int first_column; + int last_line; + int last_column; +-}; ++} YYLTYPE; ++# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ + # define YYLTYPE_IS_DECLARED 1 + # define YYLTYPE_IS_TRIVIAL 1 + #endif + +- +-extern YYSTYPE yylval; + extern YYLTYPE yylloc; +-int yyparse (void); + +-#endif /* !YY_YY_DTC_PARSER_TAB_H_INCLUDED */ +diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y +index 000873f..3f006b4 100644 +--- a/scripts/dtc/dtc-parser.y ++++ b/scripts/dtc/dtc-parser.y +@@ -19,6 +19,7 @@ + */ + %{ + #include <stdio.h> ++#include <inttypes.h> + + #include "dtc.h" + #include "srcpos.h" +@@ -52,9 +53,11 @@ extern bool treesource_error; + struct node *nodelist; + struct reserve_info *re; + uint64_t integer; ++ unsigned int flags; + } + + %token DT_V1 ++%token DT_PLUGIN + %token DT_MEMRESERVE + %token DT_LSHIFT DT_RSHIFT DT_LE DT_GE DT_EQ DT_NE DT_AND DT_OR + %token DT_BITS +@@ -71,6 +74,9 @@ extern bool treesource_error; + + %type <data> propdata + %type <data> propdataprefix ++%type <flags> versioninfo ++%type <flags> plugindecl ++%type <flags> oldplugindecl + %type <re> memreserve + %type <re> memreserves + %type <array> arrayprefix +@@ -101,10 +107,39 @@ extern bool treesource_error; + %% + + sourcefile: +- DT_V1 ';' memreserves devicetree ++ versioninfo ';' oldplugindecl memreserves devicetree + { +- the_boot_info = build_boot_info($3, $4, +- guess_boot_cpuid($4)); ++ the_boot_info = build_boot_info($1 | $3, $4, $5, ++ guess_boot_cpuid($5)); ++ } ++ ; ++ ++versioninfo: ++ DT_V1 plugindecl ++ { ++ $$ = VF_DT_V1 | $2; ++ } ++ ; ++ ++plugindecl: ++ DT_PLUGIN ++ { ++ $$ = VF_PLUGIN; ++ } ++ | /* empty */ ++ { ++ $$ = 0; ++ } ++ ; ++ ++oldplugindecl: ++ DT_PLUGIN ';' ++ { ++ $$ = VF_PLUGIN; ++ } ++ | /* empty */ ++ { ++ $$ = 0; + } + ; + +@@ -156,10 +191,14 @@ devicetree: + { + struct node *target = get_node_by_ref($1, $2); + +- if (target) ++ if (target) { + merge_nodes(target, $3); +- else +- ERROR(&@2, "Label or path %s not found", $2); ++ } else { ++ if (symbol_fixup_support) ++ add_orphan_node($1, $3, $2); ++ else ++ ERROR(&@2, "Label or path %s not found", $2); ++ } + $$ = $1; + } + | devicetree DT_DEL_NODE DT_REF ';' +@@ -174,6 +213,11 @@ devicetree: + + $$ = $1; + } ++ | /* empty */ ++ { ++ /* build empty node */ ++ $$ = name_node(build_node(NULL, NULL), ""); ++ } + ; + + nodedef: +diff --git a/scripts/dtc/dtc.c b/scripts/dtc/dtc.c +index 5fa23c4..1330e15 100644 +--- a/scripts/dtc/dtc.c ++++ b/scripts/dtc/dtc.c +@@ -31,6 +31,8 @@ int reservenum; /* Number of memory reservation slots */ + int minsize; /* Minimum blob size */ + int padsize; /* Additional padding to blob */ + int phandle_format = PHANDLE_BOTH; /* Use linux,phandle or phandle properties */ ++int symbol_fixup_support; ++int auto_label_aliases; + + static void fill_fullpaths(struct node *tree, const char *prefix) + { +@@ -53,7 +55,7 @@ static void fill_fullpaths(struct node *tree, const char *prefix) + #define FDT_VERSION(version) _FDT_VERSION(version) + #define _FDT_VERSION(version) #version + static const char usage_synopsis[] = "dtc [options] <input file>"; +-static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:fb:i:H:sW:E:hv"; ++static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:fb:i:H:sW:E:@Ahv"; + static struct option const usage_long_opts[] = { + {"quiet", no_argument, NULL, 'q'}, + {"in-format", a_argument, NULL, 'I'}, +@@ -71,6 +73,8 @@ static struct option const usage_long_opts[] = { + {"phandle", a_argument, NULL, 'H'}, + {"warning", a_argument, NULL, 'W'}, + {"error", a_argument, NULL, 'E'}, ++ {"symbols", no_argument, NULL, '@'}, ++ {"auto-alias", no_argument, NULL, 'A'}, + {"help", no_argument, NULL, 'h'}, + {"version", no_argument, NULL, 'v'}, + {NULL, no_argument, NULL, 0x0}, +@@ -101,6 +105,8 @@ static const char * const usage_opts_help[] = { + "\t\tboth - Both \"linux,phandle\" and \"phandle\" properties", + "\n\tEnable/disable warnings (prefix with \"no-\")", + "\n\tEnable/disable errors (prefix with \"no-\")", ++ "\n\tEnable symbols/fixup support", ++ "\n\tEnable auto-alias of labels", + "\n\tPrint this help and exit", + "\n\tPrint version and exit", + NULL, +@@ -117,6 +123,8 @@ static const char *guess_type_by_name(const char *fname, const char *fallback) + return "dts"; + if (!strcasecmp(s, ".dtb")) + return "dtb"; ++ if (!strcasecmp(s, ".dtbo")) ++ return "dtbo"; + return fallback; + } + +@@ -147,6 +155,8 @@ static const char *guess_input_format(const char *fname, const char *fallback) + magic = fdt32_to_cpu(magic); + if (magic == FDT_MAGIC) + return "dtb"; ++ if (magic == FDT_MAGIC_DTBO) ++ return "dtbo"; + + return guess_type_by_name(fname, fallback); + } +@@ -233,7 +243,12 @@ int main(int argc, char *argv[]) + case 'E': + parse_checks_option(false, true, optarg); + break; +- ++ case '@': ++ symbol_fixup_support = 1; ++ break; ++ case 'A': ++ auto_label_aliases = 1; ++ break; + case 'h': + usage(NULL); + default: +@@ -275,7 +290,7 @@ int main(int argc, char *argv[]) + bi = dt_from_source(arg); + else if (streq(inform, "fs")) + bi = dt_from_fs(arg); +- else if(streq(inform, "dtb")) ++ else if(streq(inform, "dtb") || streq(inform, "dtbo")) + bi = dt_from_blob(arg); + else + die("Unknown input format \"%s\"\n", inform); +@@ -294,6 +309,14 @@ int main(int argc, char *argv[]) + if (sort) + sort_tree(bi); + ++ if (auto_label_aliases) ++ generate_label_tree(bi->dt, "aliases", false); ++ ++ if (symbol_fixup_support) { ++ generate_label_tree(bi->dt, "__symbols__", true); ++ generate_fixups_tree(bi->dt); ++ } ++ + if (streq(outname, "-")) { + outf = stdout; + } else { +@@ -306,9 +329,13 @@ int main(int argc, char *argv[]) + if (streq(outform, "dts")) { + dt_to_source(outf, bi); + } else if (streq(outform, "dtb")) { +- dt_to_blob(outf, bi, outversion); ++ dt_to_blob(outf, bi, FDT_MAGIC, outversion); ++ } else if (streq(outform, "dtbo")) { ++ dt_to_blob(outf, bi, FDT_MAGIC_DTBO, outversion); + } else if (streq(outform, "asm")) { +- dt_to_asm(outf, bi, outversion); ++ dt_to_asm(outf, bi, FDT_MAGIC, outversion); ++ } else if (streq(outform, "asmo")) { ++ dt_to_asm(outf, bi, FDT_MAGIC_DTBO, outversion); + } else if (streq(outform, "null")) { + /* do nothing */ + } else { +diff --git a/scripts/dtc/dtc.h b/scripts/dtc/dtc.h +index 56212c8..aea6509 100644 +--- a/scripts/dtc/dtc.h ++++ b/scripts/dtc/dtc.h +@@ -20,7 +20,6 @@ + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ +- + #include <stdio.h> + #include <string.h> + #include <stdlib.h> +@@ -54,6 +53,12 @@ extern int reservenum; /* Number of memory reservation slots */ + extern int minsize; /* Minimum blob size */ + extern int padsize; /* Additional padding to blob */ + extern int phandle_format; /* Use linux,phandle or phandle properties */ ++extern int symbol_fixup_support;/* enable symbols & fixup support */ ++extern int auto_label_aliases; /* auto generate labels -> aliases */ ++ ++/* ++ * Tree source globals ++ */ + + #define PHANDLE_LEGACY 0x1 + #define PHANDLE_EPAPR 0x2 +@@ -158,6 +163,9 @@ struct node { + int addr_cells, size_cells; + + struct label *labels; ++ ++ /* only for the root (parent == NULL) */ ++ struct boot_info *bi; + }; + + #define for_each_label_withdel(l0, l) \ +@@ -194,6 +202,7 @@ struct node *build_node_delete(void); + struct node *name_node(struct node *node, char *name); + struct node *chain_node(struct node *first, struct node *list); + struct node *merge_nodes(struct node *old_node, struct node *new_node); ++void add_orphan_node(struct node *old_node, struct node *new_node, char *ref); + + void add_property(struct node *node, struct property *prop); + void delete_property_by_name(struct node *node, char *name); +@@ -236,14 +245,29 @@ struct reserve_info *add_reserve_entry(struct reserve_info *list, + + + struct boot_info { ++ unsigned int versionflags; + struct reserve_info *reservelist; + struct node *dt; /* the device tree */ + uint32_t boot_cpuid_phys; + }; + +-struct boot_info *build_boot_info(struct reserve_info *reservelist, ++/* version flags definitions */ ++#define VF_DT_V1 0x0001 /* /dts-v1/ */ ++#define VF_PLUGIN 0x0002 /* /plugin/ */ ++ ++static inline unsigned int tree_get_versionflags(struct node *dt) ++{ ++ if (!dt || !dt->bi) ++ return 0; ++ return dt->bi->versionflags; ++} ++ ++struct boot_info *build_boot_info(unsigned int versionflags, ++ struct reserve_info *reservelist, + struct node *tree, uint32_t boot_cpuid_phys); + void sort_tree(struct boot_info *bi); ++void generate_label_tree(struct node *dt, char *gen_node_name, bool allocph); ++void generate_fixups_tree(struct node *dt); + + /* Checks */ + +@@ -252,8 +276,8 @@ void process_checks(bool force, struct boot_info *bi); + + /* Flattened trees */ + +-void dt_to_blob(FILE *f, struct boot_info *bi, int version); +-void dt_to_asm(FILE *f, struct boot_info *bi, int version); ++void dt_to_blob(FILE *f, struct boot_info *bi, fdt32_t magic, int version); ++void dt_to_asm(FILE *f, struct boot_info *bi, fdt32_t magic, int version); + + struct boot_info *dt_from_blob(const char *fname); + +diff --git a/scripts/dtc/flattree.c b/scripts/dtc/flattree.c +index ec14954..4fe64d4 100644 +--- a/scripts/dtc/flattree.c ++++ b/scripts/dtc/flattree.c +@@ -335,6 +335,7 @@ static struct data flatten_reserve_list(struct reserve_info *reservelist, + } + + static void make_fdt_header(struct fdt_header *fdt, ++ fdt32_t magic, + struct version_info *vi, + int reservesize, int dtsize, int strsize, + int boot_cpuid_phys) +@@ -345,7 +346,7 @@ static void make_fdt_header(struct fdt_header *fdt, + + memset(fdt, 0xff, sizeof(*fdt)); + +- fdt->magic = cpu_to_fdt32(FDT_MAGIC); ++ fdt->magic = cpu_to_fdt32(magic); + fdt->version = cpu_to_fdt32(vi->version); + fdt->last_comp_version = cpu_to_fdt32(vi->last_comp_version); + +@@ -366,7 +367,7 @@ static void make_fdt_header(struct fdt_header *fdt, + fdt->size_dt_struct = cpu_to_fdt32(dtsize); + } + +-void dt_to_blob(FILE *f, struct boot_info *bi, int version) ++void dt_to_blob(FILE *f, struct boot_info *bi, fdt32_t magic, int version) + { + struct version_info *vi = NULL; + int i; +@@ -390,7 +391,7 @@ void dt_to_blob(FILE *f, struct boot_info *bi, int version) + reservebuf = flatten_reserve_list(bi->reservelist, vi); + + /* Make header */ +- make_fdt_header(&fdt, vi, reservebuf.len, dtbuf.len, strbuf.len, ++ make_fdt_header(&fdt, magic, vi, reservebuf.len, dtbuf.len, strbuf.len, + bi->boot_cpuid_phys); + + /* +@@ -460,7 +461,7 @@ static void dump_stringtable_asm(FILE *f, struct data strbuf) + } + } + +-void dt_to_asm(FILE *f, struct boot_info *bi, int version) ++void dt_to_asm(FILE *f, struct boot_info *bi, fdt32_t magic, int version) + { + struct version_info *vi = NULL; + int i; +@@ -832,7 +833,7 @@ struct boot_info *dt_from_blob(const char *fname) + } + + magic = fdt32_to_cpu(magic); +- if (magic != FDT_MAGIC) ++ if (magic != FDT_MAGIC && magic != FDT_MAGIC_DTBO) + die("Blob has incorrect magic number\n"); + + rc = fread(&totalsize, sizeof(totalsize), 1, f); +@@ -929,5 +930,5 @@ struct boot_info *dt_from_blob(const char *fname) + + fclose(f); + +- return build_boot_info(reservelist, tree, boot_cpuid_phys); ++ return build_boot_info(VF_DT_V1, reservelist, tree, boot_cpuid_phys); + } +diff --git a/scripts/dtc/fstree.c b/scripts/dtc/fstree.c +index 6d1beec..54f520b 100644 +--- a/scripts/dtc/fstree.c ++++ b/scripts/dtc/fstree.c +@@ -86,6 +86,6 @@ struct boot_info *dt_from_fs(const char *dirname) + tree = read_fstree(dirname); + tree = name_node(tree, ""); + +- return build_boot_info(NULL, tree, guess_boot_cpuid(tree)); ++ return build_boot_info(VF_DT_V1, NULL, tree, guess_boot_cpuid(tree)); + } + +diff --git a/scripts/dtc/libfdt/fdt.c b/scripts/dtc/libfdt/fdt.c +index 22286a1..28d422c 100644 +--- a/scripts/dtc/libfdt/fdt.c ++++ b/scripts/dtc/libfdt/fdt.c +@@ -57,7 +57,7 @@ + + int fdt_check_header(const void *fdt) + { +- if (fdt_magic(fdt) == FDT_MAGIC) { ++ if (fdt_magic(fdt) == FDT_MAGIC || fdt_magic(fdt) == FDT_MAGIC_DTBO) { + /* Complete tree */ + if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION) + return -FDT_ERR_BADVERSION; +diff --git a/scripts/dtc/libfdt/fdt.h b/scripts/dtc/libfdt/fdt.h +index 526aedb..493cd55 100644 +--- a/scripts/dtc/libfdt/fdt.h ++++ b/scripts/dtc/libfdt/fdt.h +@@ -55,7 +55,7 @@ + #ifndef __ASSEMBLY__ + + struct fdt_header { +- fdt32_t magic; /* magic word FDT_MAGIC */ ++ fdt32_t magic; /* magic word FDT_MAGIC[|_DTBO] */ + fdt32_t totalsize; /* total size of DT block */ + fdt32_t off_dt_struct; /* offset to structure */ + fdt32_t off_dt_strings; /* offset to strings */ +@@ -93,6 +93,7 @@ struct fdt_property { + #endif /* !__ASSEMBLY */ + + #define FDT_MAGIC 0xd00dfeed /* 4: version, 4: total size */ ++#define FDT_MAGIC_DTBO 0xd00dfdb0 /* DTBO magic */ + #define FDT_TAGSIZE sizeof(fdt32_t) + + #define FDT_BEGIN_NODE 0x1 /* Start node: full name */ +diff --git a/scripts/dtc/libfdt/libfdt.h b/scripts/dtc/libfdt/libfdt.h +index 59ca339..f7e3989 100644 +--- a/scripts/dtc/libfdt/libfdt.h ++++ b/scripts/dtc/libfdt/libfdt.h +@@ -174,21 +174,21 @@ int fdt_next_subnode(const void *fdt, int offset); + + #define fdt_get_header(fdt, field) \ + (fdt32_to_cpu(((const struct fdt_header *)(fdt))->field)) +-#define fdt_magic(fdt) (fdt_get_header(fdt, magic)) ++#define fdt_magic(fdt) (fdt_get_header(fdt, magic)) + #define fdt_totalsize(fdt) (fdt_get_header(fdt, totalsize)) + #define fdt_off_dt_struct(fdt) (fdt_get_header(fdt, off_dt_struct)) + #define fdt_off_dt_strings(fdt) (fdt_get_header(fdt, off_dt_strings)) + #define fdt_off_mem_rsvmap(fdt) (fdt_get_header(fdt, off_mem_rsvmap)) + #define fdt_version(fdt) (fdt_get_header(fdt, version)) +-#define fdt_last_comp_version(fdt) (fdt_get_header(fdt, last_comp_version)) +-#define fdt_boot_cpuid_phys(fdt) (fdt_get_header(fdt, boot_cpuid_phys)) +-#define fdt_size_dt_strings(fdt) (fdt_get_header(fdt, size_dt_strings)) ++#define fdt_last_comp_version(fdt) (fdt_get_header(fdt, last_comp_version)) ++#define fdt_boot_cpuid_phys(fdt) (fdt_get_header(fdt, boot_cpuid_phys)) ++#define fdt_size_dt_strings(fdt) (fdt_get_header(fdt, size_dt_strings)) + #define fdt_size_dt_struct(fdt) (fdt_get_header(fdt, size_dt_struct)) + + #define __fdt_set_hdr(name) \ + static inline void fdt_set_##name(void *fdt, uint32_t val) \ + { \ +- struct fdt_header *fdth = (struct fdt_header*)fdt; \ ++ struct fdt_header *fdth = (struct fdt_header *)fdt; \ + fdth->name = cpu_to_fdt32(val); \ + } + __fdt_set_hdr(magic); +@@ -318,8 +318,9 @@ int fdt_subnode_offset_namelen(const void *fdt, int parentoffset, + * returns: + * structure block offset of the requested subnode (>=0), on success + * -FDT_ERR_NOTFOUND, if the requested subnode does not exist +- * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE tag +- * -FDT_ERR_BADMAGIC, ++ * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE ++ * tag ++ * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, +@@ -351,7 +352,8 @@ int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen); + * address). + * + * returns: +- * structure block offset of the node with the requested path (>=0), on success ++ * structure block offset of the node with the requested path (>=0), on ++ * success + * -FDT_ERR_BADPATH, given path does not begin with '/' or is invalid + * -FDT_ERR_NOTFOUND, if the requested node does not exist + * -FDT_ERR_BADMAGIC, +@@ -375,10 +377,12 @@ int fdt_path_offset(const void *fdt, const char *path); + * + * returns: + * pointer to the node's name, on success +- * If lenp is non-NULL, *lenp contains the length of that name (>=0) ++ * If lenp is non-NULL, *lenp contains the length of that name ++ * (>=0) + * NULL, on error + * if lenp is non-NULL *lenp contains an error code (<0): +- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag ++ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE ++ * tag + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, standard meanings +@@ -490,7 +494,8 @@ const struct fdt_property *fdt_get_property_namelen(const void *fdt, + * NULL, on error + * if lenp is non-NULL, *lenp contains an error code (<0): + * -FDT_ERR_NOTFOUND, node does not have named property +- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag ++ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE ++ * tag + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, +@@ -575,7 +580,8 @@ const void *fdt_getprop_namelen(const void *fdt, int nodeoffset, + * NULL, on error + * if lenp is non-NULL, *lenp contains an error code (<0): + * -FDT_ERR_NOTFOUND, node does not have named property +- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag ++ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE ++ * tag + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, +@@ -647,7 +653,7 @@ const char *fdt_get_alias(const void *fdt, const char *name); + * 0, on success + * buf contains the absolute path of the node at + * nodeoffset, as a NUL-terminated string. +- * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag ++ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag + * -FDT_ERR_NOSPACE, the path of the given node is longer than (bufsize-1) + * characters and will not fit in the given buffer. + * -FDT_ERR_BADMAGIC, +@@ -677,11 +683,11 @@ int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen); + * structure from the start to nodeoffset. + * + * returns: +- + * structure block offset of the node at node offset's ancestor + * of depth supernodedepth (>=0), on success +- * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag +-* -FDT_ERR_NOTFOUND, supernodedepth was greater than the depth of nodeoffset ++ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag ++ * -FDT_ERR_NOTFOUND, supernodedepth was greater than the depth of ++ * nodeoffset + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, +@@ -703,7 +709,7 @@ int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset, + * + * returns: + * depth of the node at nodeoffset (>=0), on success +- * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag ++ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, +@@ -726,7 +732,7 @@ int fdt_node_depth(const void *fdt, int nodeoffset); + * returns: + * structure block offset of the parent of the node at nodeoffset + * (>=0), on success +- * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag ++ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, +@@ -766,7 +772,7 @@ int fdt_parent_offset(const void *fdt, int nodeoffset); + * on success + * -FDT_ERR_NOTFOUND, no node matching the criterion exists in the + * tree after startoffset +- * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag ++ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, +@@ -813,7 +819,7 @@ int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle); + * 1, if the node has a 'compatible' property, but it does not list + * the given string + * -FDT_ERR_NOTFOUND, if the given node has no 'compatible' property +- * -FDT_ERR_BADOFFSET, if nodeoffset does not refer to a BEGIN_NODE tag ++ * -FDT_ERR_BADOFFSET, if nodeoffset does not refer to a BEGIN_NODE tag + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, +@@ -850,7 +856,7 @@ int fdt_node_check_compatible(const void *fdt, int nodeoffset, + * on success + * -FDT_ERR_NOTFOUND, no node matching the criterion exists in the + * tree after startoffset +- * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag ++ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, +@@ -960,7 +966,8 @@ const char *fdt_stringlist_get(const void *fdt, int nodeoffset, + * returns: + * 0 <= n < FDT_MAX_NCELLS, on success + * 2, if the node has no #address-cells property +- * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid #address-cells property ++ * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid ++ * #address-cells property + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, +@@ -980,7 +987,8 @@ int fdt_address_cells(const void *fdt, int nodeoffset); + * returns: + * 0 <= n < FDT_MAX_NCELLS, on success + * 2, if the node has no #address-cells property +- * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid #size-cells property ++ * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid ++ * #size-cells property + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, +@@ -1604,9 +1612,11 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset, + * change the offsets of some existing nodes. + + * returns: +- * structure block offset of the created nodeequested subnode (>=0), on success ++ * structure block offset of the created nodeequested subnode (>=0), on ++ * success + * -FDT_ERR_NOTFOUND, if the requested subnode does not exist +- * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE tag ++ * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE ++ * tag + * -FDT_ERR_EXISTS, if the node at parentoffset already has a subnode of + * the given name + * -FDT_ERR_NOSPACE, if there is insufficient free space in the +diff --git a/scripts/dtc/libfdt/libfdt_internal.h b/scripts/dtc/libfdt/libfdt_internal.h +index 02cfa6f..773dfa3 100644 +--- a/scripts/dtc/libfdt/libfdt_internal.h ++++ b/scripts/dtc/libfdt/libfdt_internal.h +@@ -91,5 +91,6 @@ static inline struct fdt_reserve_entry *_fdt_mem_rsv_w(void *fdt, int n) + } + + #define FDT_SW_MAGIC (~FDT_MAGIC) ++#define FDT_SW_MAGIC_DTBO (~FDT_MAGIC_DTBO) + + #endif /* _LIBFDT_INTERNAL_H */ +diff --git a/scripts/dtc/livetree.c b/scripts/dtc/livetree.c +index e229b84..e7d0fe5 100644 +--- a/scripts/dtc/livetree.c ++++ b/scripts/dtc/livetree.c +@@ -18,6 +18,7 @@ + * USA + */ + ++#define _GNU_SOURCE + #include "dtc.h" + + /* +@@ -216,6 +217,34 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node) + return old_node; + } + ++void add_orphan_node(struct node *dt, struct node *new_node, char *ref) ++{ ++ static unsigned int next_orphan_fragment = 0; ++ struct node *node = xmalloc(sizeof(*node)); ++ struct property *p; ++ struct data d = empty_data; ++ char *name; ++ int ret; ++ ++ memset(node, 0, sizeof(*node)); ++ ++ d = data_add_marker(d, REF_PHANDLE, ref); ++ d = data_append_integer(d, 0xffffffff, 32); ++ ++ p = build_property("target", d); ++ add_property(node, p); ++ ++ ret = asprintf(&name, "fragment@%u", ++ next_orphan_fragment++); ++ if (ret == -1) ++ die("asprintf() failed\n"); ++ name_node(node, name); ++ name_node(new_node, "__overlay__"); ++ ++ add_child(dt, node); ++ add_child(node, new_node); ++} ++ + struct node *chain_node(struct node *first, struct node *list) + { + assert(first->next_sibling == NULL); +@@ -335,15 +364,19 @@ struct reserve_info *add_reserve_entry(struct reserve_info *list, + return list; + } + +-struct boot_info *build_boot_info(struct reserve_info *reservelist, ++struct boot_info *build_boot_info(unsigned int versionflags, ++ struct reserve_info *reservelist, + struct node *tree, uint32_t boot_cpuid_phys) + { + struct boot_info *bi; + + bi = xmalloc(sizeof(*bi)); ++ bi->versionflags = versionflags; + bi->reservelist = reservelist; + bi->dt = tree; + bi->boot_cpuid_phys = boot_cpuid_phys; ++ /* link back */ ++ tree->bi = bi; + + return bi; + } +@@ -709,3 +742,185 @@ void sort_tree(struct boot_info *bi) + sort_reserve_entries(bi); + sort_node(bi->dt); + } ++ ++/* utility helper to avoid code duplication */ ++static struct node *build_and_name_child_node(struct node *parent, char *name) ++{ ++ struct node *node; ++ ++ node = build_node(NULL, NULL); ++ name_node(node, xstrdup(name)); ++ add_child(parent, node); ++ ++ return node; ++} ++ ++static void generate_label_tree_internal(struct node *dt, struct node *node, ++ char *gen_node_name, bool allocph) ++{ ++ struct node *c, *an; ++ struct property *p; ++ struct label *l; ++ ++ /* if if there are labels */ ++ if (node->labels) { ++ /* an is the aliases/__symbols__ node */ ++ an = get_subnode(dt, gen_node_name); ++ /* if no node exists, create it */ ++ if (!an) ++ die("Could not get label node\n"); ++ ++ /* now add the label in the node */ ++ for_each_label(node->labels, l) { ++ /* check whether the label already exists */ ++ p = get_property(an, l->label); ++ if (p) { ++ fprintf(stderr, "WARNING: label %s already" ++ " exists in /%s", l->label, ++ gen_node_name); ++ continue; ++ } ++ ++ /* insert it */ ++ p = build_property(l->label, ++ data_copy_escape_string(node->fullpath, ++ strlen(node->fullpath))); ++ add_property(an, p); ++ } ++ ++ /* force allocation of a phandle for this node */ ++ if (allocph) ++ (void)get_node_phandle(dt, node); ++ } ++ ++ for_each_child(node, c) ++ generate_label_tree_internal(dt, c, gen_node_name, allocph); ++} ++ ++void generate_label_tree(struct node *dt, char *gen_node_name, bool allocph) ++{ ++ build_and_name_child_node(dt, gen_node_name); ++ generate_label_tree_internal(dt, dt, gen_node_name, allocph); ++} ++ ++static char *fixups_name = "__fixups__"; ++static char *local_fixups_name = "__local_fixups__"; ++ ++static void add_fixup_entry(struct node *dt, struct node *node, ++ struct property *prop, struct marker *m) ++{ ++ struct node *fn; /* local fixup node */ ++ struct property *p; ++ struct data d; ++ char *entry; ++ int ret; ++ ++ /* m->ref can only be a REF_PHANDLE, but check anyway */ ++ if (m->type != REF_PHANDLE) ++ die("Fixup entry can only be a ref to a phandle\n"); ++ ++ /* fn is the node we're putting entries in */ ++ fn = get_subnode(dt, fixups_name); ++ if (!fn) ++ die("Can't get fixups node\n"); ++ ++ /* there shouldn't be any ':' in the arguments */ ++ if (strchr(node->fullpath, ':') || strchr(prop->name, ':')) ++ die("arguments should not contain ':'\n"); ++ ++ ret = asprintf(&entry, "%s:%s:%u", ++ node->fullpath, prop->name, m->offset); ++ if (ret == -1) ++ die("asprintf() failed\n"); ++ ++ p = get_property(fn, m->ref); ++ if (p) { ++ d = data_append_data(p->val, entry, strlen(entry) + 1); ++ p->val = d; ++ } else { ++ d = data_append_data(empty_data, entry, strlen(entry) + 1); ++ add_property(fn, build_property(m->ref, d)); ++ } ++} ++ ++static void add_local_fixup_entry(struct node *dt, struct node *node, ++ struct property *prop, struct marker *m, ++ struct node *refnode) ++{ ++ struct node *lfn, *wn, *nwn; /* local fixup node, walk node, new */ ++ struct property *p; ++ struct data d; ++ char *s, *e, *comp; ++ int len; ++ ++ /* fn is the node we're putting entries in */ ++ lfn = get_subnode(dt, local_fixups_name); ++ if (!lfn) ++ die("Can't get local fixups node\n"); ++ ++ /* walk the path components creating nodes if they don't exist */ ++ comp = xmalloc(strlen(node->fullpath) + 1); ++ /* start skipping the first / */ ++ s = node->fullpath + 1; ++ wn = lfn; ++ while (*s) { ++ /* retrieve path component */ ++ e = strchr(s, '/'); ++ if (e == NULL) ++ e = s + strlen(s); ++ len = e - s; ++ memcpy(comp, s, len); ++ comp[len] = '\0'; ++ ++ /* if no node exists, create it */ ++ nwn = get_subnode(wn, comp); ++ if (!nwn) ++ nwn = build_and_name_child_node(wn, comp); ++ wn = nwn; ++ ++ /* last path component */ ++ if (!*e) ++ break; ++ ++ /* next path component */ ++ s = e + 1; ++ } ++ free(comp); ++ ++ p = get_property(wn, prop->name); ++ d = data_append_cell(p ? p->val : empty_data, (cell_t)m->offset); ++ if (!p) ++ add_property(wn, build_property(prop->name, d)); ++ else ++ p->val = d; ++} ++ ++static void generate_fixups_tree_internal(struct node *dt, struct node *node) ++{ ++ struct node *c; ++ struct property *prop; ++ struct marker *m; ++ struct node *refnode; ++ ++ for_each_property(node, prop) { ++ m = prop->val.markers; ++ for_each_marker_of_type(m, REF_PHANDLE) { ++ refnode = get_node_by_ref(dt, m->ref); ++ if (!refnode) ++ add_fixup_entry(dt, node, prop, m); ++ else ++ add_local_fixup_entry(dt, node, prop, m, ++ refnode); ++ } ++ } ++ ++ for_each_child(node, c) ++ generate_fixups_tree_internal(dt, c); ++} ++ ++void generate_fixups_tree(struct node *dt) ++{ ++ build_and_name_child_node(dt, fixups_name); ++ build_and_name_child_node(dt, local_fixups_name); ++ generate_fixups_tree_internal(dt, dt); ++} +diff --git a/scripts/dtc/version_gen.h b/scripts/dtc/version_gen.h +index ad9b05a..f934c71 100644 +--- a/scripts/dtc/version_gen.h ++++ b/scripts/dtc/version_gen.h +@@ -1 +1 @@ +-#define DTC_VERSION "DTC 1.4.1-g53bf130b" ++#define DTC_VERSION "DTC 1.4.1-g6f4db2fc" +-- +2.8.1 + diff --git a/patches/bbb_overlays/0002-gitignore-Ignore-DTB-files.patch b/patches/bbb_overlays/0002-gitignore-Ignore-DTB-files.patch index a4ecbd9a5713d6c20b31b9478be8761e6de83dde..f3332910483b556f04643141f203c0fe53cbfeb8 100644 --- a/patches/bbb_overlays/0002-gitignore-Ignore-DTB-files.patch +++ b/patches/bbb_overlays/0002-gitignore-Ignore-DTB-files.patch @@ -1,7 +1,7 @@ -From 60283675ba11e35b655066cc063c5d06c12dd8e8 Mon Sep 17 00:00:00 2001 +From aaa838a2700990505dadac8f207e8c7c781824b9 Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou <pantelis.antoniou@konsulko.com> Date: Fri, 21 Feb 2014 18:49:29 +0200 -Subject: [PATCH 02/38] gitignore: Ignore DTB files +Subject: [PATCH 02/41] gitignore: Ignore DTB files Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com> --- @@ -9,7 +9,7 @@ Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com> 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore -index fd3a355..a36edcc 100644 +index 0c320bf..32a6b8c 100644 --- a/.gitignore +++ b/.gitignore @@ -112,3 +112,7 @@ all.config @@ -21,5 +21,5 @@ index fd3a355..a36edcc 100644 +*.dtb +*.dtbo -- -2.8.0.rc3 +2.8.1 diff --git a/patches/bbb_overlays/0003-add-PM-firmware.patch b/patches/bbb_overlays/0003-add-PM-firmware.patch index fc8e1c219382f2013c9eeac6ff617ab2e7362241..da710aafd8f67cdc275d67a67a0800b2fb83f089 100644 --- a/patches/bbb_overlays/0003-add-PM-firmware.patch +++ b/patches/bbb_overlays/0003-add-PM-firmware.patch @@ -1,7 +1,7 @@ -From 427efc6f82807a0f7afb8a738eab5dacf63d32cc Mon Sep 17 00:00:00 2001 +From af1946e3895157b83bbf88370baad311ae79dc95 Mon Sep 17 00:00:00 2001 From: Koen Kooi <koen@dominion.thruhere.net> Date: Thu, 6 Jun 2013 17:09:38 +0200 -Subject: [PATCH 03/38] add PM firmware +Subject: [PATCH 03/41] add PM firmware Signed-off-by: Koen Kooi <koen@dominion.thruhere.net> --- @@ -100,5 +100,5 @@ literal 0 HcmV?d00001 -- -2.8.0.rc3 +2.8.1 diff --git a/patches/bbb_overlays/0004-ARM-CUSTOM-Build-a-uImage-with-dtb-already-appended.patch b/patches/bbb_overlays/0004-ARM-CUSTOM-Build-a-uImage-with-dtb-already-appended.patch index 61ad07350d3df8ab60d1176b6cf22652c50ccf69..9d66a06beab1b511d8d5b57033c575340c381a75 100644 --- a/patches/bbb_overlays/0004-ARM-CUSTOM-Build-a-uImage-with-dtb-already-appended.patch +++ b/patches/bbb_overlays/0004-ARM-CUSTOM-Build-a-uImage-with-dtb-already-appended.patch @@ -1,7 +1,7 @@ -From d6b35f6818cd8c7e6c58d30f56d4bbf498012608 Mon Sep 17 00:00:00 2001 +From 427e0949454f4f9f03287ab30ce212814c07e164 Mon Sep 17 00:00:00 2001 From: Grant Likely <grant.likely@secretlab.ca> Date: Tue, 2 Aug 2011 15:30:09 +0100 -Subject: [PATCH 04/38] ARM: CUSTOM: Build a uImage with dtb already appended +Subject: [PATCH 04/41] ARM: CUSTOM: Build a uImage with dtb already appended Do not commit to mainline; this is a useful hack only for now. @@ -13,10 +13,10 @@ Signed-off-by: Vaibhav Hiremath <hvaibhav@ti.com> 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/arch/arm/Makefile b/arch/arm/Makefile -index 8c3ce2a..5576419 100644 +index 274e8a6..ce25e35ee 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile -@@ -330,7 +330,10 @@ $(BOOT_TARGETS): vmlinux +@@ -331,7 +331,10 @@ $(BOOT_TARGETS): vmlinux $(INSTALL_TARGETS): $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@ @@ -29,7 +29,7 @@ index 8c3ce2a..5576419 100644 PHONY += dtbs dtbs_install diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile -index 48fab15..dadaa3d 100644 +index 446705a..1ef9f99 100644 --- a/arch/arm/boot/Makefile +++ b/arch/arm/boot/Makefile @@ -55,6 +55,9 @@ $(obj)/zImage: $(obj)/compressed/vmlinux FORCE @@ -54,5 +54,5 @@ index 48fab15..dadaa3d 100644 $(Q)$(MAKE) $(build)=$(obj)/bootp $@ @: -- -2.8.0.rc3 +2.8.1 diff --git a/patches/bbb_overlays/0005-omap-Fix-crash-when-omap-device-is-disabled.patch b/patches/bbb_overlays/0005-omap-Fix-crash-when-omap-device-is-disabled.patch index 4050de34ebd22081f3be548c2204d3b72bc74712..6aa97bb3bba3fe9ff2fc66540ed42be34417b02a 100644 --- a/patches/bbb_overlays/0005-omap-Fix-crash-when-omap-device-is-disabled.patch +++ b/patches/bbb_overlays/0005-omap-Fix-crash-when-omap-device-is-disabled.patch @@ -1,7 +1,7 @@ -From 84bf0a3c5700c1a74f9c71ac36ba6f75fbc7ec4c Mon Sep 17 00:00:00 2001 +From de54fecde8c33c8b524dc66991431c4bc6fe961e Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou <pantelis.antoniou@konsulko.com> Date: Tue, 8 Mar 2016 20:01:46 +0200 -Subject: [PATCH 05/38] omap: Fix crash when omap device is disabled +Subject: [PATCH 05/41] omap: Fix crash when omap device is disabled When disabling an omap device (not when removing the driver), the device is removed but the hwmod's linger. @@ -15,10 +15,10 @@ Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com> 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c -index 956fffa..efcce61 100644 +index f7ff3b9..7f5647b 100644 --- a/arch/arm/mach-omap2/omap_device.c +++ b/arch/arm/mach-omap2/omap_device.c -@@ -211,12 +211,21 @@ static int _omap_device_notifier_call(struct notifier_block *nb, +@@ -191,12 +191,21 @@ static int _omap_device_notifier_call(struct notifier_block *nb, { struct platform_device *pdev = to_platform_device(dev); struct omap_device *od; @@ -43,7 +43,7 @@ index 956fffa..efcce61 100644 break; case BUS_NOTIFY_UNBOUND_DRIVER: od = to_omap_device(pdev); -@@ -790,6 +799,8 @@ int omap_device_idle(struct platform_device *pdev) +@@ -770,6 +779,8 @@ int omap_device_idle(struct platform_device *pdev) struct omap_device *od; od = to_omap_device(pdev); @@ -53,5 +53,5 @@ index 956fffa..efcce61 100644 if (od->_state != OMAP_DEVICE_STATE_ENABLED) { dev_warn(&pdev->dev, -- -2.8.0.rc3 +2.8.1 diff --git a/patches/bbb_overlays/0006-serial-omap-Fix-port-line-number-without-aliases.patch b/patches/bbb_overlays/0006-serial-omap-Fix-port-line-number-without-aliases.patch index f2070f85356c89bc9351209be0f2b94a55856095..fb9ce849fbb9465acfa4375d3b77129a052eb25c 100644 --- a/patches/bbb_overlays/0006-serial-omap-Fix-port-line-number-without-aliases.patch +++ b/patches/bbb_overlays/0006-serial-omap-Fix-port-line-number-without-aliases.patch @@ -1,7 +1,7 @@ -From 3f004b73b6c28b5bcc4f3e065a933bf4d7f8f05e Mon Sep 17 00:00:00 2001 +From ec2054d3d4705c054e2f61b1e484e8ac863d2c33 Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou <pantelis.antoniou@konsulko.com> Date: Thu, 6 Nov 2014 14:12:14 +0200 -Subject: [PATCH 06/38] serial: omap: Fix port line number without aliases +Subject: [PATCH 06/41] serial: omap: Fix port line number without aliases Having an omap serial device without a serial aliases doesn't work. For now fallback to using the hwmod instance. @@ -57,5 +57,5 @@ index a2a5299..202b8ba 100644 ret = pdev->id; -- -2.8.0.rc3 +2.8.1 diff --git a/patches/bbb_overlays/0007-tty-omap-serial-Fix-up-platform-data-alloc.patch b/patches/bbb_overlays/0007-tty-omap-serial-Fix-up-platform-data-alloc.patch index 4f568c1559a61ccc5f5e40b620f7307a1a3d19de..d4f28400abc4cfade1f2fade5adfe772033ca3bf 100644 --- a/patches/bbb_overlays/0007-tty-omap-serial-Fix-up-platform-data-alloc.patch +++ b/patches/bbb_overlays/0007-tty-omap-serial-Fix-up-platform-data-alloc.patch @@ -1,7 +1,7 @@ -From 76b5b59b103b0baad78f04b9d34ba513978fb36b Mon Sep 17 00:00:00 2001 +From 95fa05a08bb48996735afda88bec9014ba326fc2 Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou <pantelis.antoniou@konsulko.com> Date: Mon, 9 Dec 2013 20:12:17 +0200 -Subject: [PATCH 07/38] tty: omap-serial: Fix up platform data alloc +Subject: [PATCH 07/41] tty: omap-serial: Fix up platform data alloc When using DT the driver devm_kalloc's platform data and assigns them directly to the pdev->dev.platform variable. @@ -33,5 +33,5 @@ index 202b8ba..b9b8b4d 100644 uartirq = platform_get_irq(pdev, 0); if (uartirq < 0) -- -2.8.0.rc3 +2.8.1 diff --git a/patches/bbb_overlays/0009-of-Custom-printk-format-specifier-for-device-node.patch b/patches/bbb_overlays/0008-of-Custom-printk-format-specifier-for-device-node.patch similarity index 95% rename from patches/bbb_overlays/0009-of-Custom-printk-format-specifier-for-device-node.patch rename to patches/bbb_overlays/0008-of-Custom-printk-format-specifier-for-device-node.patch index 6f90db52c886d3686f115630999720e9a19679cd..f96911e96e1f060764786ebf53b077cfc6ac9106 100644 --- a/patches/bbb_overlays/0009-of-Custom-printk-format-specifier-for-device-node.patch +++ b/patches/bbb_overlays/0008-of-Custom-printk-format-specifier-for-device-node.patch @@ -1,7 +1,7 @@ -From 13308de3b99d8ab79557ca461f900b4708abc6fa Mon Sep 17 00:00:00 2001 +From a799fccfc922808d0768ab8b08f2510757526252 Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou <pantelis.antoniou@konsulko.com> Date: Tue, 20 Jan 2015 16:15:05 +0200 -Subject: [PATCH 09/38] of: Custom printk format specifier for device node +Subject: [PATCH 08/41] of: Custom printk format specifier for device node 90% of the usage of device node's full_name is printing it out in a kernel message. Preparing for the eventual delayed allocation @@ -80,10 +80,10 @@ index 5962949..d1ba882 100644 diff --git a/lib/vsprintf.c b/lib/vsprintf.c -index ccb664b..f03c70a 100644 +index 0967771..319e09d 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c -@@ -34,6 +34,7 @@ +@@ -35,6 +35,7 @@ #ifdef CONFIG_BLOCK #include <linux/blkdev.h> #endif @@ -91,7 +91,7 @@ index ccb664b..f03c70a 100644 #include "../mm/internal.h" /* For the trace_print_flags arrays */ -@@ -1475,6 +1476,141 @@ char *flags_string(char *buf, char *end, void *flags_ptr, const char *fmt) +@@ -1470,6 +1471,141 @@ char *flags_string(char *buf, char *end, void *flags_ptr, const char *fmt) return format_flags(buf, end, flags, names); } @@ -233,7 +233,7 @@ index ccb664b..f03c70a 100644 int kptr_restrict __read_mostly; /* -@@ -1568,6 +1704,16 @@ int kptr_restrict __read_mostly; +@@ -1563,6 +1699,16 @@ int kptr_restrict __read_mostly; * p page flags (see struct page) given as pointer to unsigned long * g gfp flags (GFP_* and __GFP_*) given as pointer to gfp_t * v vma flags (VM_*) given as pointer to unsigned long @@ -250,7 +250,7 @@ index ccb664b..f03c70a 100644 * * ** Please update also Documentation/printk-formats.txt when making changes ** * -@@ -1723,6 +1869,10 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr, +@@ -1718,6 +1864,10 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr, case 'G': return flags_string(buf, end, ptr, fmt); @@ -262,5 +262,5 @@ index ccb664b..f03c70a 100644 spec.flags |= SMALL; if (spec.field_width == -1) { -- -2.8.0.rc3 +2.8.1 diff --git a/patches/bbb_overlays/0010-of-overlay-kobjectify-overlay-objects.patch b/patches/bbb_overlays/0009-of-overlay-kobjectify-overlay-objects.patch similarity index 92% rename from patches/bbb_overlays/0010-of-overlay-kobjectify-overlay-objects.patch rename to patches/bbb_overlays/0009-of-overlay-kobjectify-overlay-objects.patch index 03c38f0931e5d6a96fdc552a503ef6d2126a0e66..d9781e37091ac26311b32da532ddc651611129c5 100644 --- a/patches/bbb_overlays/0010-of-overlay-kobjectify-overlay-objects.patch +++ b/patches/bbb_overlays/0009-of-overlay-kobjectify-overlay-objects.patch @@ -1,7 +1,7 @@ -From 7f31016e0b13781665d79aedde4521901bec31d8 Mon Sep 17 00:00:00 2001 +From 31a95ab6fd487e3eb8492a4270569fc45ed46539 Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou <pantelis.antoniou@konsulko.com> Date: Sun, 15 Mar 2015 20:39:36 +0200 -Subject: [PATCH 10/38] of: overlay: kobjectify overlay objects +Subject: [PATCH 09/41] of: overlay: kobjectify overlay objects We are going to need the overlays to appear on sysfs with runtime global properties (like master enable) so turn them into kobjects. @@ -12,14 +12,15 @@ removal is possible. In a future more attributes can be added in a backwards compatible manner. Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com> +Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> --- - drivers/of/base.c | 7 +++++++ + drivers/of/base.c | 5 +++++ drivers/of/of_private.h | 9 +++++++++ drivers/of/overlay.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++-- - 3 files changed, 64 insertions(+), 2 deletions(-) + 3 files changed, 62 insertions(+), 2 deletions(-) diff --git a/drivers/of/base.c b/drivers/of/base.c -index b299de2..c025728 100644 +index ebf84e3..ccd2ef3 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -192,6 +192,7 @@ int __of_attach_node_sysfs(struct device_node *np) @@ -30,7 +31,7 @@ index b299de2..c025728 100644 /* Create the kset, and register existing nodes */ mutex_lock(&of_mutex); -@@ -208,6 +209,12 @@ void __init of_core_init(void) +@@ -208,6 +209,10 @@ void __init of_core_init(void) /* Symlink in /proc as required by userspace ABI */ if (of_root) proc_symlink("device-tree", NULL, "/sys/firmware/devicetree/base"); @@ -38,8 +39,6 @@ index b299de2..c025728 100644 + ret = of_overlay_init(); + if (ret != 0) + pr_warn("of_init: of_overlay_init failed!\n"); -+ -+ return 0; } static struct property *__of_find_property(const struct device_node *np, @@ -176,5 +175,5 @@ index 8225081..4e06c34 100644 + return 0; +} -- -2.8.0.rc3 +2.8.1 diff --git a/patches/bbb_overlays/0011-of-overlay-global-sysfs-enable-attribute.patch b/patches/bbb_overlays/0010-of-overlay-global-sysfs-enable-attribute.patch similarity index 93% rename from patches/bbb_overlays/0011-of-overlay-global-sysfs-enable-attribute.patch rename to patches/bbb_overlays/0010-of-overlay-global-sysfs-enable-attribute.patch index 5ed8097bd9be0e241c665d2b511d25fae76c710f..0643efcf0eb4334aaa1c33a38ddc2324ecd5c72f 100644 --- a/patches/bbb_overlays/0011-of-overlay-global-sysfs-enable-attribute.patch +++ b/patches/bbb_overlays/0010-of-overlay-global-sysfs-enable-attribute.patch @@ -1,7 +1,7 @@ -From e3888bb90c5a0caeff29ba43103e4e34d087009f Mon Sep 17 00:00:00 2001 +From 99d2e12fd6e67d5ac56d3d125269c2916275a89c Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou <pantelis.antoniou@konsulko.com> Date: Tue, 17 Mar 2015 15:25:46 +0200 -Subject: [PATCH 11/38] of: overlay: global sysfs enable attribute +Subject: [PATCH 10/41] of: overlay: global sysfs enable attribute A throw once master enable switch to protect against any further overlay applications if the administrator desires so. @@ -9,6 +9,7 @@ further overlay applications if the administrator desires so. A kernel command line option is provided as well. Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com> +Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> --- drivers/of/overlay.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) @@ -103,5 +104,5 @@ index 4e06c34..47e8d3a 100644 + return rc; } -- -2.8.0.rc3 +2.8.1 diff --git a/patches/bbb_overlays/0012-Documentation-ABI-overlays-global-attributes.patch b/patches/bbb_overlays/0011-Documentation-ABI-overlays-global-attributes.patch similarity index 89% rename from patches/bbb_overlays/0012-Documentation-ABI-overlays-global-attributes.patch rename to patches/bbb_overlays/0011-Documentation-ABI-overlays-global-attributes.patch index fe777cf4038ce170c0af11db809b69d86ddecf1c..438b81c49be8a2d8f9ca495b8209a0788ade274c 100644 --- a/patches/bbb_overlays/0012-Documentation-ABI-overlays-global-attributes.patch +++ b/patches/bbb_overlays/0011-Documentation-ABI-overlays-global-attributes.patch @@ -1,11 +1,12 @@ -From 95de39d15b7babf6ddddb0a848eb67b4abedc3ac Mon Sep 17 00:00:00 2001 +From aa812d4cfdca5644982a8fd62a8b25c3df8bc334 Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou <pantelis.antoniou@konsulko.com> Date: Tue, 17 Mar 2015 21:42:10 +0200 -Subject: [PATCH 12/38] Documentation: ABI: overlays - global attributes +Subject: [PATCH 11/41] Documentation: ABI: overlays - global attributes Documentation ABI entry for overlays sysfs entries. Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com> +Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> --- .../ABI/testing/sysfs-firmware-devicetree-overlays | 24 ++++++++++++++++++++++ 1 file changed, 24 insertions(+) @@ -42,5 +43,5 @@ index 0000000..e938f44 + that systems that have this interface can choose to turn it off + during initial boot, etc." -- -2.8.0.rc3 +2.8.1 diff --git a/patches/bbb_overlays/0013-Documentation-document-of_overlay_disable-parameter.patch b/patches/bbb_overlays/0012-Documentation-document-of_overlay_disable-parameter.patch similarity index 80% rename from patches/bbb_overlays/0013-Documentation-document-of_overlay_disable-parameter.patch rename to patches/bbb_overlays/0012-Documentation-document-of_overlay_disable-parameter.patch index f019b6bc227967430000e8b3cda99238bd37cf4f..5f937ca8e8982c9d9225afeb0ef0a431fc20054a 100644 --- a/patches/bbb_overlays/0013-Documentation-document-of_overlay_disable-parameter.patch +++ b/patches/bbb_overlays/0012-Documentation-document-of_overlay_disable-parameter.patch @@ -1,17 +1,18 @@ -From cee639afb1a2793578c6c5ccd7915dd7e7299527 Mon Sep 17 00:00:00 2001 +From 78c25ecb55cae72d6867b6f36ad4d7d429e1c3ff Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou <pantelis.antoniou@konsulko.com> Date: Thu, 22 Oct 2015 22:37:06 +0300 -Subject: [PATCH 13/38] Documentation: document of_overlay_disable parameter +Subject: [PATCH 12/41] Documentation: document of_overlay_disable parameter Document the of_overlay_disable parameter. Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com> +Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> --- Documentation/kernel-parameters.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt -index 0b3de80..cc8d434 100644 +index 82b42c9..7134c37 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -90,6 +90,7 @@ parameter is applicable: @@ -22,7 +23,7 @@ index 0b3de80..cc8d434 100644 OSS OSS sound support is enabled. PV_OPS A paravirtualized kernel is enabled. PARIDE The ParIDE (parallel port IDE) subsystem is enabled. -@@ -2715,6 +2716,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted. +@@ -2759,6 +2760,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted. This can be set from sysctl after boot. See Documentation/sysctl/vm.txt for details. @@ -32,5 +33,5 @@ index 0b3de80..cc8d434 100644 See Documentation/debugging-via-ohci1394.txt for more info. -- -2.8.0.rc3 +2.8.1 diff --git a/patches/bbb_overlays/0014-of-overlay-add-per-overlay-sysfs-attributes.patch b/patches/bbb_overlays/0013-of-overlay-add-per-overlay-sysfs-attributes.patch similarity index 96% rename from patches/bbb_overlays/0014-of-overlay-add-per-overlay-sysfs-attributes.patch rename to patches/bbb_overlays/0013-of-overlay-add-per-overlay-sysfs-attributes.patch index aee403304075d718ebd74ff556bb023672b576dd..3bd09ff9f5ef295b407a8205e7f0f1ce1bc0cb8c 100644 --- a/patches/bbb_overlays/0014-of-overlay-add-per-overlay-sysfs-attributes.patch +++ b/patches/bbb_overlays/0013-of-overlay-add-per-overlay-sysfs-attributes.patch @@ -1,7 +1,7 @@ -From 516ecef7ea97ccc45589117b4ddc976ac6fb0990 Mon Sep 17 00:00:00 2001 +From 54c46996fcdba218a52e8ba324e02915fe02f486 Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou <pantelis.antoniou@konsulko.com> Date: Thu, 23 Apr 2015 19:02:16 +0300 -Subject: [PATCH 14/38] of: overlay: add per overlay sysfs attributes +Subject: [PATCH 13/41] of: overlay: add per overlay sysfs attributes * A per overlay can_remove sysfs attribute that reports whether the overlay can be removed or not due to another overlapping overlay. @@ -10,6 +10,7 @@ the overlay can be removed or not due to another overlapping overlay. in a group named after the name of the fragment. Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com> +Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> --- drivers/of/overlay.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 99 insertions(+), 4 deletions(-) @@ -223,5 +224,5 @@ index 47e8d3a..fdfc487 100644 of_free_overlay_info(ov); idr_remove(&ov_idr, id); -- -2.8.0.rc3 +2.8.1 diff --git a/patches/bbb_overlays/0015-Documentation-ABI-overlays-per-overlay-docs.patch b/patches/bbb_overlays/0014-Documentation-ABI-overlays-per-overlay-docs.patch similarity index 90% rename from patches/bbb_overlays/0015-Documentation-ABI-overlays-per-overlay-docs.patch rename to patches/bbb_overlays/0014-Documentation-ABI-overlays-per-overlay-docs.patch index 8866604f6e6e3519a4eb033dbb2d900a21f5bc64..d5f0cf2fb7fa0fdb3f996fdc30875bf623d0036e 100644 --- a/patches/bbb_overlays/0015-Documentation-ABI-overlays-per-overlay-docs.patch +++ b/patches/bbb_overlays/0014-Documentation-ABI-overlays-per-overlay-docs.patch @@ -1,11 +1,12 @@ -From 2308e171170bbc024f4d680729e87b867ba489f0 Mon Sep 17 00:00:00 2001 +From f1fd0aa2469c89c1bc490e4cc83941650b263221 Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou <pantelis.antoniou@konsulko.com> Date: Thu, 22 Oct 2015 20:59:27 +0300 -Subject: [PATCH 15/38] Documentation: ABI: overlays - per overlay docs +Subject: [PATCH 14/41] Documentation: ABI: overlays - per overlay docs Documentation for the per-overlay attributes. Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com> +Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> --- .../ABI/testing/sysfs-firmware-devicetree-overlays | 28 ++++++++++++++++++++++ 1 file changed, 28 insertions(+) @@ -47,5 +48,5 @@ index e938f44..88d1549 100644 +Description: + The full-path of the target of the fragment -- -2.8.0.rc3 +2.8.1 diff --git a/patches/bbb_overlays/0028-of-dynamic-Add-__of_node_dupv.patch b/patches/bbb_overlays/0015-of-dynamic-Add-__of_node_dupv.patch similarity index 86% rename from patches/bbb_overlays/0028-of-dynamic-Add-__of_node_dupv.patch rename to patches/bbb_overlays/0015-of-dynamic-Add-__of_node_dupv.patch index 799502f82ff5b7c947de03b71e03668109722d8b..e4f6b10634f405129ee51b244885cf13d58add97 100644 --- a/patches/bbb_overlays/0028-of-dynamic-Add-__of_node_dupv.patch +++ b/patches/bbb_overlays/0015-of-dynamic-Add-__of_node_dupv.patch @@ -1,7 +1,7 @@ -From 2669c91ec05becf0bedd7ae71566987ef8bdfe80 Mon Sep 17 00:00:00 2001 +From 6ee8fc96bd1cf4c4672a23b11d86c32097e0225e Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou <pantelis.antoniou@konsulko.com> Date: Wed, 10 Jun 2015 17:54:17 +0300 -Subject: [PATCH 28/38] of: dynamic: Add __of_node_dupv() +Subject: [PATCH 15/41] of: dynamic: Add __of_node_dupv() Add an __of_node_dupv() private method and make __of_node_dup() use it. This is required for the subsequent changeset accessors which will @@ -13,10 +13,10 @@ Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com> 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c -index c647bd1..bd817eb 100644 +index 3033fa3..b3111ad 100644 --- a/drivers/of/dynamic.c +++ b/drivers/of/dynamic.c -@@ -394,8 +394,9 @@ struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags) +@@ -395,8 +395,9 @@ struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags) } /** @@ -28,7 +28,7 @@ index c647bd1..bd817eb 100644 * * Create an device tree node, either by duplicating an empty node or by allocating * an empty one suitable for further modification. The node data are -@@ -403,17 +404,15 @@ struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags) +@@ -404,17 +405,15 @@ struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags) * OF_DETACHED bits set. Returns the newly allocated node or NULL on out of * memory error. */ @@ -48,7 +48,7 @@ index c647bd1..bd817eb 100644 if (!node->full_name) { kfree(node); return NULL; -@@ -445,6 +444,24 @@ struct device_node *__of_node_dup(const struct device_node *np, const char *fmt, +@@ -446,6 +445,24 @@ struct device_node *__of_node_dup(const struct device_node *np, const char *fmt, return NULL; } @@ -74,5 +74,5 @@ index c647bd1..bd817eb 100644 { of_node_put(ce->np); -- -2.8.0.rc3 +2.8.1 diff --git a/patches/bbb_overlays/0016-of-changesets-Introduce-changeset-helper-methods.patch b/patches/bbb_overlays/0016-of-changesets-Introduce-changeset-helper-methods.patch new file mode 100644 index 0000000000000000000000000000000000000000..18724640c79bf4181a7fcfbe0c14433f0fb7b799 --- /dev/null +++ b/patches/bbb_overlays/0016-of-changesets-Introduce-changeset-helper-methods.patch @@ -0,0 +1,621 @@ +From ebae43447d426d0afdb7eee84fdcd9cf4c25ad95 Mon Sep 17 00:00:00 2001 +From: Pantelis Antoniou <pantelis.antoniou@konsulko.com> +Date: Wed, 10 Jun 2015 18:35:53 +0300 +Subject: [PATCH 16/41] of: changesets: Introduce changeset helper methods + +Changesets are very powerful, but the lack of a helper API +makes using them cumbersome. Introduce a simple copy based +API that makes things considerably easier. + +To wit, adding a property using the raw API. + + struct property *prop; + prop = kzalloc(sizeof(*prop)), GFP_KERNEL); + prop->name = kstrdup("compatible"); + prop->value = kstrdup("foo,bar"); + prop->length = strlen(prop->value) + 1; + of_changeset_add_property(ocs, np, prop); + +while using the helper API + + of_changeset_add_property_string(ocs, np, "compatible", + "foo,bar"); + +Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com> +--- + drivers/of/dynamic.c | 226 +++++++++++++++++++++++++++++++++++ + include/linux/of.h | 328 +++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 554 insertions(+) + +diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c +index b3111ad..6a54bad 100644 +--- a/drivers/of/dynamic.c ++++ b/drivers/of/dynamic.c +@@ -829,3 +829,229 @@ int of_changeset_action(struct of_changeset *ocs, unsigned long action, + return 0; + } + EXPORT_SYMBOL_GPL(of_changeset_action); ++ ++/* changeset helpers */ ++ ++/** ++ * of_changeset_create_device_node - Create an empty device node ++ * ++ * @ocs: changeset pointer ++ * @parent: parent device node ++ * @fmt: format string for the node's full_name ++ * @args: argument list for the format string ++ * ++ * Create an empty device node, marking it as detached and allocated. ++ * ++ * Returns a device node on success, an error encoded pointer otherwise ++ */ ++struct device_node *of_changeset_create_device_nodev( ++ struct of_changeset *ocs, struct device_node *parent, ++ const char *fmt, va_list vargs) ++{ ++ struct device_node *node; ++ ++ node = __of_node_dupv(NULL, fmt, vargs); ++ if (!node) ++ return ERR_PTR(-ENOMEM); ++ ++ node->parent = parent; ++ return node; ++} ++EXPORT_SYMBOL_GPL(of_changeset_create_device_nodev); ++ ++/** ++ * of_changeset_create_device_node - Create an empty device node ++ * ++ * @ocs: changeset pointer ++ * @parent: parent device node ++ * @fmt: Format string for the node's full_name ++ * ... Arguments ++ * ++ * Create an empty device node, marking it as detached and allocated. ++ * ++ * Returns a device node on success, an error encoded pointer otherwise ++ */ ++__printf(3, 4) struct device_node * ++of_changeset_create_device_node(struct of_changeset *ocs, ++ struct device_node *parent, const char *fmt, ...) ++{ ++ va_list vargs; ++ struct device_node *node; ++ ++ va_start(vargs, fmt); ++ node = of_changeset_create_device_nodev(ocs, parent, fmt, vargs); ++ va_end(vargs); ++ return node; ++} ++EXPORT_SYMBOL_GPL(of_changeset_create_device_node); ++ ++/** ++ * __of_changeset_add_property_copy - Create/update a new property copying ++ * name & value ++ * ++ * @ocs: changeset pointer ++ * @np: device node pointer ++ * @name: name of the property ++ * @value: pointer to the value data ++ * @length: length of the value in bytes ++ * @update: True on update operation ++ * ++ * Adds/updates a property to the changeset by making copies of the name & value ++ * entries. The @update parameter controls whether an add or update takes place. ++ * ++ * Returns zero on success, a negative error value otherwise. ++ */ ++int __of_changeset_add_update_property_copy(struct of_changeset *ocs, ++ struct device_node *np, const char *name, const void *value, ++ int length, bool update) ++{ ++ struct property *prop; ++ char *new_name; ++ void *new_value; ++ int ret = -ENOMEM; ++ ++ prop = kzalloc(sizeof(*prop), GFP_KERNEL); ++ if (!prop) ++ return -ENOMEM; ++ ++ new_name = kstrdup(name, GFP_KERNEL); ++ if (!new_name) ++ goto out_err; ++ ++ /* ++ * NOTE: There is no check for zero length value. ++ * In case of a boolean property, this will allocate a value ++ * of zero bytes. We do this to work around the use ++ * of of_get_property() calls on boolean values. ++ */ ++ new_value = kmemdup(value, length, GFP_KERNEL); ++ if (!new_value) ++ goto out_err; ++ ++ of_property_set_flag(prop, OF_DYNAMIC); ++ ++ prop->name = new_name; ++ prop->value = new_value; ++ prop->length = length; ++ ++ if (!update) ++ ret = of_changeset_add_property(ocs, np, prop); ++ else ++ ret = of_changeset_update_property(ocs, np, prop); ++ ++ if (!ret) ++ return 0; ++ ++out_err: ++ kfree(prop->value); ++ kfree(prop->name); ++ kfree(prop); ++ return ret; ++} ++EXPORT_SYMBOL_GPL(__of_changeset_add_update_property_copy); ++ ++/** ++ * of_changeset_add_property_stringf - Create a new formatted string property ++ * ++ * @ocs: changeset pointer ++ * @np: device node pointer ++ * @name: name of the property ++ * @fmt: format of string property ++ * ... arguments of the format string ++ * ++ * Adds a string property to the changeset by making copies of the name ++ * and the formatted value. ++ * ++ * Returns zero on success, a negative error value otherwise. ++ */ ++__printf(4, 5) int of_changeset_add_property_stringf( ++ struct of_changeset *ocs, struct device_node *np, ++ const char *name, const char *fmt, ...) ++{ ++ va_list vargs; ++ int ret; ++ ++ va_start(vargs, fmt); ++ ret = __of_changeset_add_update_property_stringv(ocs, np, name, fmt, ++ vargs, false); ++ va_end(vargs); ++ return ret; ++} ++EXPORT_SYMBOL_GPL(of_changeset_add_property_stringf); ++ ++/** ++ * of_changeset_update_property_stringf - Update formatted string property ++ * ++ * @ocs: changeset pointer ++ * @np: device node pointer ++ * @name: name of the property ++ * @fmt: format of string property ++ * ... arguments of the format string ++ * ++ * Updates a string property to the changeset by making copies of the name ++ * and the formatted value. ++ * ++ * Returns zero on success, a negative error value otherwise. ++ */ ++int of_changeset_update_property_stringf( ++ struct of_changeset *ocs, struct device_node *np, ++ const char *name, const char *fmt, ...) ++{ ++ va_list vargs; ++ int ret; ++ ++ va_start(vargs, fmt); ++ ret = __of_changeset_add_update_property_stringv(ocs, np, name, fmt, ++ vargs, true); ++ va_end(vargs); ++ return ret; ++} ++EXPORT_SYMBOL_GPL(of_changeset_update_property_stringf); ++ ++/** ++ * __of_changeset_add_update_property_string_list - Create/update a string ++ * list property ++ * ++ * @ocs: changeset pointer ++ * @np: device node pointer ++ * @name: name of the property ++ * @strs: pointer to the string list ++ * @count: string count ++ * @update: True on update operation ++ * ++ * Adds a string list property to the changeset. ++ * ++ * Returns zero on success, a negative error value otherwise. ++ */ ++int __of_changeset_add_update_property_string_list( ++ struct of_changeset *ocs, struct device_node *np, ++ const char *name, const char **strs, int count, bool update) ++{ ++ int total = 0, i, ret; ++ char *value, *s; ++ ++ for (i = 0; i < count; i++) { ++ /* check if it's NULL */ ++ if (!strs[i]) ++ return -EINVAL; ++ total += strlen(strs[i]) + 1; ++ } ++ ++ value = kmalloc(total, GFP_KERNEL); ++ if (!value) ++ return -ENOMEM; ++ ++ for (i = 0, s = value; i < count; i++) { ++ /* no need to check for NULL, check above */ ++ strcpy(s, strs[i]); ++ s += strlen(strs[i]) + 1; ++ } ++ ++ ret = __of_changeset_add_update_property_copy(ocs, np, name, value, ++ total, update); ++ ++ kfree(value); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(__of_changeset_add_update_property_string_list); +diff --git a/include/linux/of.h b/include/linux/of.h +index c7292e8..9f7fa3d 100644 +--- a/include/linux/of.h ++++ b/include/linux/of.h +@@ -1059,6 +1059,8 @@ enum of_reconfig_change { + }; + + #ifdef CONFIG_OF_DYNAMIC ++#include <linux/slab.h> ++ + extern int of_reconfig_notifier_register(struct notifier_block *); + extern int of_reconfig_notifier_unregister(struct notifier_block *); + extern int of_reconfig_notify(unsigned long, struct of_reconfig_data *rd); +@@ -1102,6 +1104,23 @@ static inline int of_changeset_update_property(struct of_changeset *ocs, + { + return of_changeset_action(ocs, OF_RECONFIG_UPDATE_PROPERTY, np, prop); + } ++ ++struct device_node *of_changeset_create_device_nodev( ++ struct of_changeset *ocs, struct device_node *parent, ++ const char *fmt, va_list vargs); ++ ++__printf(3, 4) struct device_node * ++of_changeset_create_device_node(struct of_changeset *ocs, ++ struct device_node *parent, const char *fmt, ...); ++ ++int __of_changeset_add_update_property_copy(struct of_changeset *ocs, ++ struct device_node *np, const char *name, const void *value, ++ int length, bool update); ++ ++int __of_changeset_add_update_property_string_list( ++ struct of_changeset *ocs, struct device_node *np, ++ const char *name, const char **strs, int count, bool update); ++ + #else /* CONFIG_OF_DYNAMIC */ + static inline int of_reconfig_notifier_register(struct notifier_block *nb) + { +@@ -1121,8 +1140,317 @@ static inline int of_reconfig_get_state_change(unsigned long action, + { + return -EINVAL; + } ++ ++static inline struct device_node *of_changeset_create_device_nodev( ++ struct of_changeset *ocs, struct device_node *parent, ++ const char *fmt, va_list vargs) ++{ ++ return ERR_PTR(-EINVAL); ++} ++ ++static inline __printf(3, 4) struct device_node * ++of_changeset_create_device_node(struct of_changeset *ocs, ++ struct device_node *parent, const char *fmt, ...) ++{ ++ return ERR_PTR(-EINVAL); ++} ++ ++static inline int __of_changeset_add_update_property_copy( ++ struct of_changeset *ocs, struct device_node *np, ++ const char *name, const void *value, int length, bool update) ++{ ++ return -EINVAL; ++} ++ ++static inline __printf(4, 5) int of_changeset_add_property_stringf( ++ struct of_changeset *ocs, struct device_node *np, ++ const char *name, const char *fmt, ...) ++{ ++ return -EINVAL; ++} ++ ++static inline int of_changeset_update_property_stringf( ++ struct of_changeset *ocs, struct device_node *np, ++ const char *name, const char *fmt, ...) ++{ ++ return -EINVAL; ++} ++ ++static inline int __of_changeset_add_update_property_string_list( ++ struct of_changeset *ocs, struct device_node *np, ++ const char *name, const char **strs, int count, bool update) ++{ ++ return -EINVAL; ++} ++ + #endif /* CONFIG_OF_DYNAMIC */ + ++/** ++ * of_changeset_add_property_copy - Create a new property copying name & value ++ * ++ * @ocs: changeset pointer ++ * @np: device node pointer ++ * @name: name of the property ++ * @value: pointer to the value data ++ * @length: length of the value in bytes ++ * ++ * Adds a property to the changeset by making copies of the name & value ++ * entries. ++ * ++ * Returns zero on success, a negative error value otherwise. ++ */ ++static inline int of_changeset_add_property_copy(struct of_changeset *ocs, ++ struct device_node *np, const char *name, ++ const void *value, int length) ++{ ++ return __of_changeset_add_update_property_copy(ocs, np, name, value, ++ length, false); ++} ++ ++/** ++ * of_changeset_update_property_copy - Update a property copying name & value ++ * ++ * @ocs: changeset pointer ++ * @np: device node pointer ++ * @name: name of the property ++ * @value: pointer to the value data ++ * @length: length of the value in bytes ++ * ++ * Update a property to the changeset by making copies of the name & value ++ * entries. ++ * ++ * Returns zero on success, a negative error value otherwise. ++ */ ++static inline int of_changeset_update_property_copy(struct of_changeset *ocs, ++ struct device_node *np, const char *name, ++ const void *value, int length) ++{ ++ return __of_changeset_add_update_property_copy(ocs, np, name, value, ++ length, true); ++} ++ ++/** ++ * __of_changeset_add_update_property_string - Create/update a string property ++ * ++ * @ocs: changeset pointer ++ * @np: device node pointer ++ * @name: name of the property ++ * @str: string property value ++ * @update: True on update operation ++ * ++ * Adds/updates a string property to the changeset by making copies of the name ++ * and the given value. The @update parameter controls whether an add or ++ * update takes place. ++ * ++ * Returns zero on success, a negative error value otherwise. ++ */ ++static inline int __of_changeset_add_update_property_string( ++ struct of_changeset *ocs, struct device_node *np, const char *name, ++ const char *str, bool update) ++{ ++ return __of_changeset_add_update_property_copy(ocs, np, name, str, ++ strlen(str) + 1, update); ++} ++ ++/** ++ * __of_changeset_add_update_property_stringv - Create/update a formatted ++ * string property ++ * ++ * @ocs: changeset pointer ++ * @np: device node pointer ++ * @name: name of the property ++ * @fmt: format of string property ++ * @vargs: arguments of the format string ++ * @update: True on update operation ++ * ++ * Adds/updates a string property to the changeset by making copies of the name ++ * and the formatted value. The @update parameter controls whether an add or ++ * update takes place. ++ * ++ * Returns zero on success, a negative error value otherwise. ++ */ ++static inline int __of_changeset_add_update_property_stringv( ++ struct of_changeset *ocs, struct device_node *np, const char *name, ++ const char *fmt, va_list vargs, bool update) ++{ ++ char *str; ++ int ret; ++ ++ str = kvasprintf(GFP_KERNEL, fmt, vargs); ++ if (!str) ++ return -ENOMEM; ++ ret = __of_changeset_add_update_property_string(ocs, np, name, str, ++ update); ++ kfree(str); ++ ++ return ret; ++} ++ ++/** ++ * of_changeset_add_property_string_list - Create a new string list property ++ * ++ * @ocs: changeset pointer ++ * @np: device node pointer ++ * @name: name of the property ++ * @strs: pointer to the string list ++ * @count: string count ++ * ++ * Adds a string list property to the changeset. ++ * ++ * Returns zero on success, a negative error value otherwise. ++ */ ++static inline int of_changeset_add_property_string_list( ++ struct of_changeset *ocs, struct device_node *np, const char *name, ++ const char **strs, int count) ++{ ++ return __of_changeset_add_update_property_string_list(ocs, np, name, ++ strs, count, false); ++} ++ ++/** ++ * of_changeset_update_property_string_list - Update string list property ++ * ++ * @ocs: changeset pointer ++ * @np: device node pointer ++ * @name: name of the property ++ * @strs: pointer to the string list ++ * @count: string count ++ * ++ * Updates a string list property to the changeset. ++ * ++ * Returns zero on success, a negative error value otherwise. ++ */ ++static inline int of_changeset_update_property_string_list( ++ struct of_changeset *ocs, struct device_node *np, ++ const char *name, const char **strs, int count) ++{ ++ return __of_changeset_add_update_property_string_list(ocs, np, name, ++ strs, count, true); ++} ++ ++/** ++ * of_changeset_add_property_string - Adds a string property ++ * ++ * @ocs: changeset pointer ++ * @np: device node pointer ++ * @name: name of the property ++ * @str: string property ++ * ++ * Adds a string property to the changeset by making copies of the name ++ * and the string value. ++ * ++ * Returns zero on success, a negative error value otherwise. ++ */ ++static inline int of_changeset_add_property_string( ++ struct of_changeset *ocs, struct device_node *np, ++ const char *name, const char *str) ++{ ++ return __of_changeset_add_update_property_string(ocs, np, name, str, ++ false); ++} ++ ++/** ++ * of_changeset_update_property_string - Update a string property ++ * ++ * @ocs: changeset pointer ++ * @np: device node pointer ++ * @name: name of the property ++ * @str: string property ++ * ++ * Updates a string property to the changeset by making copies of the name ++ * and the string value. ++ * ++ * Returns zero on success, a negative error value otherwise. ++ */ ++static inline int of_changeset_update_property_string( ++ struct of_changeset *ocs, struct device_node *np, ++ const char *name, const char *str) ++{ ++ return __of_changeset_add_update_property_string(ocs, np, name, str, ++ true); ++} ++ ++/** ++ * of_changeset_add_property_u32 - Create a new u32 property ++ * ++ * @ocs: changeset pointer ++ * @np: device node pointer ++ * @name: name of the property ++ * @val: value in host endian format ++ * ++ * Adds a u32 property to the changeset. ++ * ++ * Returns zero on success, a negative error value otherwise. ++ */ ++static inline int of_changeset_add_property_u32(struct of_changeset *ocs, ++ struct device_node *np, const char *name, u32 val) ++{ ++ val = cpu_to_be32(val); ++ return __of_changeset_add_update_property_copy(ocs, np, name, &val, ++ sizeof(val), false); ++} ++ ++/** ++ * of_changeset_update_property_u32 - Update u32 property ++ * ++ * @ocs: changeset pointer ++ * @np: device node pointer ++ * @name: name of the property ++ * @val: value in host endian format ++ * ++ * Updates a u32 property to the changeset. ++ * ++ * Returns zero on success, a negative error value otherwise. ++ */ ++static inline int of_changeset_update_property_u32( ++ struct of_changeset *ocs, struct device_node *np, ++ const char *name, u32 val) ++{ ++ val = cpu_to_be32(val); ++ return __of_changeset_add_update_property_copy(ocs, np, name, &val, ++ sizeof(val), true); ++} ++ ++/** ++ * of_changeset_add_property_bool - Create a new u32 property ++ * ++ * @ocs: changeset pointer ++ * @np: device node pointer ++ * @name: name of the property ++ * ++ * Adds a bool property to the changeset. Note that there is ++ * no option to set the value to false, since the property ++ * existing sets it to true. ++ * ++ * Returns zero on success, a negative error value otherwise. ++ */ ++static inline int of_changeset_add_property_bool( ++ struct of_changeset *ocs, struct device_node *np, const char *name) ++{ ++ return __of_changeset_add_update_property_copy(ocs, np, name, "", 0, ++ false); ++} ++ ++/** ++ * of_changeset_update_property_bool - Update a bool property ++ * ++ * @ocs: changeset pointer ++ * @np: device node pointer ++ * @name: name of the property ++ * ++ * Updates a property to the changeset. Note that there is ++ * no option to set the value to false, since the property ++ * existing sets it to true. ++ * ++ * Returns zero on success, a negative error value otherwise. ++ */ ++static inline int of_changeset_update_property_bool(struct of_changeset *ocs, ++ struct device_node *np, const char *name) ++{ ++ return __of_changeset_add_update_property_copy(ocs, np, name, "", 0, ++ true); ++} ++ + /* CONFIG_OF_RESOLVE api */ + extern int of_resolve_phandles(struct device_node *tree); + +-- +2.8.1 + diff --git a/patches/bbb_overlays/0017-of-changeset-Add-of_changeset_node_move-method.patch b/patches/bbb_overlays/0017-of-changeset-Add-of_changeset_node_move-method.patch new file mode 100644 index 0000000000000000000000000000000000000000..ee71cdd41af68f4872a73d92e4ee0dbf8db64ef7 --- /dev/null +++ b/patches/bbb_overlays/0017-of-changeset-Add-of_changeset_node_move-method.patch @@ -0,0 +1,119 @@ +From 0dafdbbcf212947ffe94f428a2c7ea2935e5c39c Mon Sep 17 00:00:00 2001 +From: Pantelis Antoniou <pantelis.antoniou@konsulko.com> +Date: Mon, 16 May 2016 14:21:35 +0300 +Subject: [PATCH 17/41] of: changeset: Add of_changeset_node_move method + +Adds a changeset helper for moving a subtree to a different place +in the running tree. This is useful in advances cases of dynamic +device tree construction. + +Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com> +--- + drivers/of/dynamic.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++ + include/linux/of.h | 9 +++++++ + 2 files changed, 75 insertions(+) + +diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c +index 6a54bad..4cef6eb 100644 +--- a/drivers/of/dynamic.c ++++ b/drivers/of/dynamic.c +@@ -1055,3 +1055,69 @@ int __of_changeset_add_update_property_string_list( + return ret; + } + EXPORT_SYMBOL_GPL(__of_changeset_add_update_property_string_list); ++ ++static struct device_node * ++__of_changeset_node_move_one(struct of_changeset *ocs, ++ struct device_node *np, struct device_node *new_parent) ++{ ++ struct device_node *np2; ++ const char *unitname; ++ int err; ++ ++ err = of_changeset_detach_node(ocs, np); ++ if (err) ++ return ERR_PTR(err); ++ ++ unitname = strrchr(np->full_name, '/'); ++ if (!unitname) ++ unitname = np->full_name; ++ ++ np2 = __of_node_dup(np, "%s/%s", ++ new_parent->full_name, unitname); ++ if (!np2) ++ return ERR_PTR(-ENOMEM); ++ np2->parent = new_parent; ++ ++ err = of_changeset_attach_node(ocs, np2); ++ if (err) ++ return ERR_PTR(err); ++ ++ return np2; ++} ++ ++/** ++ * of_changeset_node_move_to - Moves a subtree to a new place in ++ * the tree ++ * ++ * @ocs: changeset pointer ++ * @np: device node pointer to be moved ++ * @to: device node of the new parent ++ * ++ * Moves a subtree to a new place in the tree. ++ * Note that a move is a safe operation because the phandles ++ * remain valid. ++ * ++ * Returns zero on success, a negative error value otherwise. ++ */ ++int of_changeset_node_move(struct of_changeset *ocs, ++ struct device_node *np, struct device_node *new_parent) ++{ ++ struct device_node *npc, *nppc; ++ ++ /* move the root first */ ++ nppc = __of_changeset_node_move_one(ocs, np, new_parent); ++ if (IS_ERR(nppc)) ++ return PTR_ERR(nppc); ++ ++ /* move the subtrees next */ ++ for_each_child_of_node(np, npc) { ++ nppc = __of_changeset_node_move_one(ocs, npc, nppc); ++ if (IS_ERR(nppc)) { ++ of_node_put(npc); ++ return PTR_ERR(nppc); ++ } ++ } ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(of_changeset_node_move); +diff --git a/include/linux/of.h b/include/linux/of.h +index 9f7fa3d..28b88bb 100644 +--- a/include/linux/of.h ++++ b/include/linux/of.h +@@ -1121,6 +1121,9 @@ int __of_changeset_add_update_property_string_list( + struct of_changeset *ocs, struct device_node *np, + const char *name, const char **strs, int count, bool update); + ++int of_changeset_node_move(struct of_changeset *ocs, ++ struct device_node *np, struct device_node *new_parent); ++ + #else /* CONFIG_OF_DYNAMIC */ + static inline int of_reconfig_notifier_register(struct notifier_block *nb) + { +@@ -1183,6 +1186,12 @@ static inline int __of_changeset_add_update_property_string_list( + return -EINVAL; + } + ++static inline int of_changeset_node_move(struct of_changeset *ocs, ++ struct device_node *np, struct device_node *new_parent) ++{ ++ return -EINVAL; ++} ++ + #endif /* CONFIG_OF_DYNAMIC */ + + /** +-- +2.8.1 + diff --git a/patches/bbb_overlays/0034-of-unittest-changeset-helpers.patch b/patches/bbb_overlays/0018-of-unittest-changeset-helpers.patch similarity index 59% rename from patches/bbb_overlays/0034-of-unittest-changeset-helpers.patch rename to patches/bbb_overlays/0018-of-unittest-changeset-helpers.patch index 4bc75af92208a716ae03b8ad5cc69ba9ed029fc3..22612299aaae2cfc1dc3c871621cd8071c1e4f27 100644 --- a/patches/bbb_overlays/0034-of-unittest-changeset-helpers.patch +++ b/patches/bbb_overlays/0018-of-unittest-changeset-helpers.patch @@ -1,18 +1,20 @@ -From 98c90e08a83183adc6ce814e02fc563e166b9112 Mon Sep 17 00:00:00 2001 +From 9750bc8568b15c99f5f1e76d6e9c1bffd2394242 Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou <pantelis.antoniou@konsulko.com> Date: Wed, 14 Oct 2015 13:16:15 +0300 -Subject: [PATCH 34/38] of: unittest: changeset helpers +Subject: [PATCH 18/41] of: unittest: changeset helpers + +Add a unitest specific for the new changeset helpers. Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com> --- - drivers/of/unittest.c | 40 ++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 40 insertions(+) + drivers/of/unittest.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 54 insertions(+) diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c -index 4f6b605..2bfe0bc 100644 +index f34ed93..d8dd3c8 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c -@@ -543,6 +543,45 @@ static void __init of_unittest_changeset(void) +@@ -542,6 +542,59 @@ static void __init of_unittest_changeset(void) #endif } @@ -35,15 +37,29 @@ index 4f6b605..2bfe0bc 100644 + unittest(n2, "testcase setup failure\n"); + n21 = of_changeset_create_device_node(&chgset, n2, "%s/%s", + "/testcase-data/changeset/n2", "n21"); ++ unittest(n21, "testcase setup failure\n"); + -+ of_changeset_init(&chgset); + unittest(!of_changeset_add_property_string(&chgset, parent, + "prop-add", "foo"), "fail add prop\n"); ++ ++ unittest(!of_changeset_attach_node(&chgset, n1), "fail n1 attach\n"); ++ unittest(!of_changeset_attach_node(&chgset, n2), "fail n2 attach\n"); ++ unittest(!of_changeset_attach_node(&chgset, n21), "fail n21 attach\n"); ++ + unittest(!of_changeset_apply(&chgset), "apply failed\n"); + + /* Make sure node names are constructed correctly */ -+ unittest((np = of_find_node_by_path("/testcase-data/changeset/n2/n21")), -+ "'%s' not added\n", n21->full_name); ++ np = of_find_node_by_path("/testcase-data/changeset/n1"); ++ unittest(np, "'%s' not added\n", n1->full_name); ++ of_node_put(np); ++ ++ /* Make sure node names are constructed correctly */ ++ np = of_find_node_by_path("/testcase-data/changeset/n2"); ++ unittest(np, "'%s' not added\n", n2->full_name); ++ of_node_put(np); ++ ++ np = of_find_node_by_path("/testcase-data/changeset/n2/n21"); ++ unittest(np, "'%s' not added\n", n21->full_name); + of_node_put(np); + + unittest(!of_changeset_revert(&chgset), "revert failed\n"); @@ -58,7 +74,7 @@ index 4f6b605..2bfe0bc 100644 static void __init of_unittest_parse_interrupts(void) { struct device_node *np; -@@ -2241,6 +2280,7 @@ static int __init of_unittest(void) +@@ -1955,6 +2008,7 @@ static int __init of_unittest(void) of_unittest_property_string(); of_unittest_property_copy(); of_unittest_changeset(); @@ -67,5 +83,5 @@ index 4f6b605..2bfe0bc 100644 of_unittest_parse_interrupts_extended(); of_unittest_match_node(); -- -2.8.0.rc3 +2.8.1 diff --git a/patches/bbb_overlays/0019-i2c-demux-Use-changeset-helpers-for-clarity.patch b/patches/bbb_overlays/0019-i2c-demux-Use-changeset-helpers-for-clarity.patch new file mode 100644 index 0000000000000000000000000000000000000000..5714492d3ac56eedd4caf7f3eb0b2e9dd7dfa1c3 --- /dev/null +++ b/patches/bbb_overlays/0019-i2c-demux-Use-changeset-helpers-for-clarity.patch @@ -0,0 +1,39 @@ +From 71b44c2b25ece4cc941e0979c9c27eadd17f136e Mon Sep 17 00:00:00 2001 +From: Pantelis Antoniou <pantelis.antoniou@konsulko.com> +Date: Mon, 16 May 2016 19:02:07 +0300 +Subject: [PATCH 19/41] i2c: demux: Use changeset helpers for clarity + +The changeset helpers are easier to use, use them instead of +using the static property. + +Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com> +--- + drivers/i2c/muxes/i2c-demux-pinctrl.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/drivers/i2c/muxes/i2c-demux-pinctrl.c b/drivers/i2c/muxes/i2c-demux-pinctrl.c +index 8de073a..ddaca9e 100644 +--- a/drivers/i2c/muxes/i2c-demux-pinctrl.c ++++ b/drivers/i2c/muxes/i2c-demux-pinctrl.c +@@ -37,8 +37,6 @@ struct i2c_demux_pinctrl_priv { + struct i2c_demux_pinctrl_chan chan[]; + }; + +-static struct property status_okay = { .name = "status", .length = 3, .value = "ok" }; +- + static int i2c_demux_master_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) + { + struct i2c_demux_pinctrl_priv *priv = adap->algo_data; +@@ -219,7 +217,8 @@ static int i2c_demux_pinctrl_probe(struct platform_device *pdev) + priv->chan[i].parent_np = adap_np; + + of_changeset_init(&priv->chan[i].chgset); +- of_changeset_update_property(&priv->chan[i].chgset, adap_np, &status_okay); ++ of_changeset_update_property_string(&priv->chan[i].chgset, ++ adap_np, "status", "okay"); + } + + priv->num_chan = num_chan; +-- +2.8.1 + diff --git a/patches/bbb_overlays/0001-OF-DT-Overlay-configfs-interface-v7.patch b/patches/bbb_overlays/0020-OF-DT-Overlay-configfs-interface-v7.patch similarity index 96% rename from patches/bbb_overlays/0001-OF-DT-Overlay-configfs-interface-v7.patch rename to patches/bbb_overlays/0020-OF-DT-Overlay-configfs-interface-v7.patch index 8148fba080b7d431c6334e64afa7053b2b2bbc8f..34dca2e99c3c76cd3d57c7ec3d7dca673c3030d9 100644 --- a/patches/bbb_overlays/0001-OF-DT-Overlay-configfs-interface-v7.patch +++ b/patches/bbb_overlays/0020-OF-DT-Overlay-configfs-interface-v7.patch @@ -1,7 +1,7 @@ -From 8677541391d96648adc67627cf9e9df0e9039075 Mon Sep 17 00:00:00 2001 +From b7ee7ee793b31f4eba4707c4e3a6bdf2f4cb3c52 Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou <pantelis.antoniou@konsulko.com> Date: Wed, 4 Dec 2013 19:32:00 +0200 -Subject: [PATCH 01/38] OF: DT-Overlay configfs interface (v7) +Subject: [PATCH 20/41] OF: DT-Overlay configfs interface (v7) Add a runtime interface to using configfs for generic device tree overlay usage. With it its possible to use device tree overlays without having @@ -31,8 +31,6 @@ Changes since v1: - of_resolve() -> of_resolve_phandles(). Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com> - -cfs-of --- Documentation/devicetree/configfs-overlays.txt | 31 +++ drivers/of/Kconfig | 7 + @@ -80,12 +78,12 @@ index 0000000..5fa43e0 +intended to be used by hardware managers in the kernel, while the copy interface +make sense for developers (since it avoids problems with namespaces). diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig -index e2a4841..59efeda 100644 +index b3bec3a..06adbfc 100644 --- a/drivers/of/Kconfig +++ b/drivers/of/Kconfig -@@ -112,4 +112,11 @@ config OF_OVERLAY - While this option is selected automatically when needed, you can - enable it manually to improve device tree unit test coverage. +@@ -115,4 +115,11 @@ config OF_OVERLAY + config OF_NUMA + bool +config OF_CONFIGFS + bool "Device Tree Overlay ConfigFS interface" @@ -96,7 +94,7 @@ index e2a4841..59efeda 100644 + endif # OF diff --git a/drivers/of/Makefile b/drivers/of/Makefile -index 156c072..46c8f57 100644 +index bee3fa9..1cf0db5 100644 --- a/drivers/of/Makefile +++ b/drivers/of/Makefile @@ -1,4 +1,5 @@ @@ -107,7 +105,7 @@ index 156c072..46c8f57 100644 obj-$(CONFIG_OF_EARLY_FLATTREE) += fdt_address.o diff --git a/drivers/of/configfs.c b/drivers/of/configfs.c new file mode 100644 -index 0000000..fa73b98f +index 0000000..c7e999c --- /dev/null +++ b/drivers/of/configfs.c @@ -0,0 +1,307 @@ @@ -158,7 +156,7 @@ index 0000000..fa73b98f + int err; + + /* unflatten the tree */ -+ of_fdt_unflatten_tree(blob, &overlay->overlay); ++ of_fdt_unflatten_tree(blob, NULL, &overlay->overlay); + if (overlay->overlay == NULL) { + pr_err("%s: failed to unflatten tree\n", __func__); + err = -EINVAL; @@ -419,5 +417,5 @@ index 0000000..fa73b98f +} +late_initcall(of_cfs_init); -- -2.8.0.rc3 +2.8.1 diff --git a/patches/bbb_overlays/0008-ARM-DT-Enable-symbols-when-CONFIG_OF_OVERLAY-is-used.patch b/patches/bbb_overlays/0021-ARM-DT-Enable-symbols-when-CONFIG_OF_OVERLAY-is-used.patch similarity index 62% rename from patches/bbb_overlays/0008-ARM-DT-Enable-symbols-when-CONFIG_OF_OVERLAY-is-used.patch rename to patches/bbb_overlays/0021-ARM-DT-Enable-symbols-when-CONFIG_OF_OVERLAY-is-used.patch index 762f45ebaa6edd4949b04677df2fe5596d86df23..b5014f2b881c9e702b449dc0a027ea5009d9ec3a 100644 --- a/patches/bbb_overlays/0008-ARM-DT-Enable-symbols-when-CONFIG_OF_OVERLAY-is-used.patch +++ b/patches/bbb_overlays/0021-ARM-DT-Enable-symbols-when-CONFIG_OF_OVERLAY-is-used.patch @@ -1,15 +1,15 @@ -From 507079b2fe715d2e7278a830fa493a433e24ba00 Mon Sep 17 00:00:00 2001 +From c3335e947f57c46810a08478124e04a7b9ccc526 Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou <pantelis.antoniou@konsulko.com> Date: Sat, 6 Dec 2014 20:10:49 +0200 -Subject: [PATCH 08/38] ARM: DT: Enable symbols when CONFIG_OF_OVERLAY is used +Subject: [PATCH 21/41] ARM: DT: Enable symbols when CONFIG_OF_OVERLAY is used --- arch/arm/boot/Makefile | 4 ++++ - arch/arm/boot/dts/Makefile | 4 ++++ - 2 files changed, 8 insertions(+) + arch/arm/boot/dts/Makefile | 6 ++++++ + 2 files changed, 10 insertions(+) diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile -index dadaa3d..d249d95 100644 +index 1ef9f99..e7ebcfd 100644 --- a/arch/arm/boot/Makefile +++ b/arch/arm/boot/Makefile @@ -27,6 +27,10 @@ export ZRELADDR INITRD_PHYS PARAMS_PHYS @@ -24,10 +24,10 @@ index dadaa3d..d249d95 100644 $(obj)/xipImage: vmlinux FORCE diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 659bf7a..419bc93 100644 +index 0f89d87..5d1a36c 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile -@@ -1,5 +1,9 @@ +@@ -1,11 +1,17 @@ ifeq ($(CONFIG_OF),y) +ifeq ($(CONFIG_OF_OVERLAY),y) @@ -37,6 +37,14 @@ index 659bf7a..419bc93 100644 dtb-$(CONFIG_ARCH_ALPINE) += \ alpine-db.dtb dtb-$(CONFIG_MACH_ARTPEC6) += \ + artpec6-devboard.dtb ++ + dtb-$(CONFIG_MACH_ASM9260) += \ + alphascale-asm9260-devkit.dtb ++ + # Keep at91 dtb files sorted alphabetically for each SoC + dtb-$(CONFIG_SOC_SAM_V4_V5) += \ + at91rm9200ek.dtb \ -- -2.8.0.rc3 +2.8.1 diff --git a/patches/bbb_overlays/0016-misc-Beaglebone-capemanager.patch b/patches/bbb_overlays/0022-misc-Beaglebone-capemanager.patch similarity index 99% rename from patches/bbb_overlays/0016-misc-Beaglebone-capemanager.patch rename to patches/bbb_overlays/0022-misc-Beaglebone-capemanager.patch index fd4d4cf4478174b358c58c44015b49b591294954..33cffbdeb53057924800e074b28b5d97a93ae05f 100644 --- a/patches/bbb_overlays/0016-misc-Beaglebone-capemanager.patch +++ b/patches/bbb_overlays/0022-misc-Beaglebone-capemanager.patch @@ -1,7 +1,7 @@ -From 2b41588b3abeea9b580033c2e939a05047c7af43 Mon Sep 17 00:00:00 2001 +From ea1aa474ca58d2b8f746345a75b1774103b7ceee Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou <pantelis.antoniou@konsulko.com> Date: Wed, 6 May 2015 23:09:53 +0300 -Subject: [PATCH 16/38] misc: Beaglebone capemanager +Subject: [PATCH 22/41] misc: Beaglebone capemanager A cape loader based on DT overlays and DT objects. @@ -24,8 +24,8 @@ Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com> --- drivers/misc/Kconfig | 10 + drivers/misc/Makefile | 1 + - drivers/misc/bone_capemgr.c | 1884 +++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 1895 insertions(+) + drivers/misc/bone_capemgr.c | 1885 +++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 1896 insertions(+) create mode 100644 drivers/misc/bone_capemgr.c diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig @@ -60,10 +60,10 @@ index b2fb6dbf..32715fa 100644 +obj-$(CONFIG_BONE_CAPEMGR) += bone_capemgr.o diff --git a/drivers/misc/bone_capemgr.c b/drivers/misc/bone_capemgr.c new file mode 100644 -index 0000000..094ea75 +index 0000000..f82623d --- /dev/null +++ b/drivers/misc/bone_capemgr.c -@@ -0,0 +1,1884 @@ +@@ -0,0 +1,1885 @@ +/* + * TI Beaglebone cape manager + * @@ -1236,7 +1236,8 @@ index 0000000..094ea75 + dev_dbg(dev, "slot #%d: dtbo '%s' loaded; converting to live tree\n", + slot->slotno, slot->dtbo); + -+ of_fdt_unflatten_tree((unsigned long *)slot->fw->data, &slot->overlay); ++ of_fdt_unflatten_tree((unsigned long *)slot->fw->data, NULL, ++ &slot->overlay); + if (slot->overlay == NULL) { + dev_err(dev, "slot #%d: Failed to unflatten\n", + slot->slotno); @@ -1949,5 +1950,5 @@ index 0000000..094ea75 +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:bone_capemgr"); -- -2.8.0.rc3 +2.8.1 diff --git a/patches/bbb_overlays/0022-of-overlay-Implement-indirect-target-support.patch b/patches/bbb_overlays/0022-of-overlay-Implement-indirect-target-support.patch deleted file mode 100644 index 6132c6596f7e5946a1461cb9cf4e13c5aa012d23..0000000000000000000000000000000000000000 --- a/patches/bbb_overlays/0022-of-overlay-Implement-indirect-target-support.patch +++ /dev/null @@ -1,259 +0,0 @@ -From 11f55514d5b2371c5c0f19b373209ad8e64151c4 Mon Sep 17 00:00:00 2001 -From: Pantelis Antoniou <pantelis.antoniou@konsulko.com> -Date: Thu, 21 May 2015 12:31:06 +0300 -Subject: [PATCH 22/38] of: overlay: Implement indirect target support - -Some applications require applying the same overlay to a different -target according to some external condition (for instance depending -on the slot a card has been inserted, the overlay target is different). - -The indirect target use requires using the new -of_overlay_create_indirect() API which uses a text selector. - -The format requires the use of a target-indirect node as follows: - - fragment@0 { - target-indirect { - foo { target = <&foo_target>; }; - bar { target = <&bar_target>; }; - }; - }; - -Calling of_overlay_create_indirect() with a "foo" argument selects -the foo_target and so on. - -Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com> ---- - drivers/of/overlay.c | 126 +++++++++++++++++++++++++++++++++++++++++---------- - include/linux/of.h | 8 ++++ - 2 files changed, 110 insertions(+), 24 deletions(-) - -diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c -index fdfc487..364b619 100644 ---- a/drivers/of/overlay.c -+++ b/drivers/of/overlay.c -@@ -75,6 +75,7 @@ struct of_overlay { - const struct attribute_group **attr_groups; - struct of_changeset cset; - struct kobject kobj; -+ char *indirect_id; - }; - - /* master enable switch; once set to 0 can't be re-enabled */ -@@ -220,14 +221,8 @@ static int of_overlay_apply(struct of_overlay *ov) - return 0; - } - --/* -- * Find the target node using a number of different strategies -- * in order of preference -- * -- * "target" property containing the phandle of the target -- * "target-path" property containing the path of the target -- */ --static struct device_node *find_target_node(struct device_node *info_node) -+static struct device_node *find_target_node_direct(struct of_overlay *ov, -+ struct device_node *info_node) - { - const char *path; - u32 val; -@@ -238,17 +233,66 @@ static struct device_node *find_target_node(struct device_node *info_node) - if (ret == 0) - return of_find_node_by_phandle(val); - -- /* now try to locate by path */ -+ /* failed, try to locate by path */ - ret = of_property_read_string(info_node, "target-path", &path); - if (ret == 0) - return of_find_node_by_path(path); - -- pr_err("%s: Failed to find target for node %p (%s)\n", __func__, -- info_node, info_node->name); -- - return NULL; - } - -+/* -+ * Find the target node using a number of different strategies -+ * in order of preference. Respects the indirect id if available. -+ * -+ * "target" property containing the phandle of the target -+ * "target-path" property containing the path of the target -+ */ -+static struct device_node *find_target_node(struct of_overlay *ov, -+ struct device_node *info_node) -+{ -+ struct device_node *target; -+ struct device_node *target_indirect; -+ struct device_node *indirect; -+ -+ /* try direct target */ -+ target = find_target_node_direct(ov, info_node); -+ if (target) -+ return target; -+ -+ /* try indirect if there */ -+ if (!ov->indirect_id) -+ return NULL; -+ -+ target_indirect = of_get_child_by_name(info_node, "target-indirect"); -+ if (!target_indirect) { -+ pr_err("%s: Failed to find target-indirect node at %s\n", -+ __func__, -+ of_node_full_name(info_node)); -+ return NULL; -+ } -+ -+ indirect = of_get_child_by_name(target_indirect, ov->indirect_id); -+ of_node_put(target_indirect); -+ if (!indirect) { -+ pr_err("%s: Failed to find indirect child node \"%s\" at %s\n", -+ __func__, ov->indirect_id, -+ of_node_full_name(info_node)); -+ return NULL; -+ } -+ -+ target = find_target_node_direct(ov, indirect); -+ -+ if (!target) { -+ pr_err("%s: Failed to find target for \"%s\" at %s\n", -+ __func__, ov->indirect_id, -+ of_node_full_name(indirect)); -+ } -+ of_node_put(indirect); -+ -+ return target; -+} -+ - /** - * of_fill_overlay_info() - Fill an overlay info structure - * @ov Overlay to fill -@@ -270,7 +314,7 @@ static int of_fill_overlay_info(struct of_overlay *ov, - if (ovinfo->overlay == NULL) - goto err_fail; - -- ovinfo->target = find_target_node(info_node); -+ ovinfo->target = find_target_node(ov, info_node); - if (ovinfo->target == NULL) - goto err_fail; - -@@ -418,6 +462,7 @@ void of_overlay_release(struct kobject *kobj) - { - struct of_overlay *ov = kobj_to_overlay(kobj); - -+ kfree(ov->indirect_id); - kfree(ov); - } - -@@ -473,17 +518,8 @@ static struct kobj_type of_overlay_ktype = { - - static struct kset *ov_kset; - --/** -- * of_overlay_create() - Create and apply an overlay -- * @tree: Device node containing all the overlays -- * -- * Creates and applies an overlay while also keeping track -- * of the overlay in a list. This list can be used to prevent -- * illegal overlay removals. -- * -- * Returns the id of the created overlay, or a negative error number -- */ --int of_overlay_create(struct device_node *tree) -+static int __of_overlay_create(struct device_node *tree, -+ const char *indirect_id) - { - struct of_overlay *ov; - int err, id; -@@ -498,6 +534,14 @@ int of_overlay_create(struct device_node *tree) - return -ENOMEM; - ov->id = -1; - -+ if (indirect_id) { -+ ov->indirect_id = kstrdup(indirect_id, GFP_KERNEL); -+ if (!ov->indirect_id) { -+ err = -ENOMEM; -+ goto err_no_mem; -+ } -+ } -+ - INIT_LIST_HEAD(&ov->node); - - of_changeset_init(&ov->cset); -@@ -572,13 +616,47 @@ err_free_idr: - idr_remove(&ov_idr, ov->id); - err_destroy_trans: - of_changeset_destroy(&ov->cset); -+err_no_mem: -+ kfree(ov->indirect_id); - kfree(ov); - mutex_unlock(&of_mutex); - - return err; - } -+ -+/** -+ * of_overlay_create() - Create and apply an overlay -+ * @tree: Device node containing all the overlays -+ * -+ * Creates and applies an overlay while also keeping track -+ * of the overlay in a list. This list can be used to prevent -+ * illegal overlay removals. -+ * -+ * Returns the id of the created overlay, or a negative error number -+ */ -+int of_overlay_create(struct device_node *tree) -+{ -+ return __of_overlay_create(tree, NULL); -+} - EXPORT_SYMBOL_GPL(of_overlay_create); - -+/** -+ * of_overlay_create_indirect() - Create and apply an overlay -+ * @tree: Device node containing all the overlays -+ * @id: Indirect property phandle -+ * -+ * Creates and applies an overlay while also keeping track -+ * of the overlay in a list. This list can be used to prevent -+ * illegal overlay removals. -+ * -+ * Returns the id of the created overlay, or a negative error number -+ */ -+int of_overlay_create_indirect(struct device_node *tree, const char *id) -+{ -+ return __of_overlay_create(tree, id); -+} -+EXPORT_SYMBOL_GPL(of_overlay_create_indirect); -+ - /* check whether the given node, lies under the given tree */ - static int overlay_subtree_check(struct device_node *tree, - struct device_node *dn) -diff --git a/include/linux/of.h b/include/linux/of.h -index 7fcb681..56bed18 100644 ---- a/include/linux/of.h -+++ b/include/linux/of.h -@@ -1083,6 +1083,8 @@ int of_overlay_create(struct device_node *tree); - int of_overlay_destroy(int id); - int of_overlay_destroy_all(void); - -+int of_overlay_create_indirect(struct device_node *tree, const char *id); -+ - #else - - static inline int of_overlay_create(struct device_node *tree) -@@ -1100,6 +1102,12 @@ static inline int of_overlay_destroy_all(void) - return -ENOTSUPP; - } - -+static inline int of_overlay_create_indirect(struct device_node *tree, -+ const char *id) -+{ -+ return -ENOTSUPP; -+} -+ - #endif - - #endif /* _LINUX_OF_H */ --- -2.8.0.rc3 - diff --git a/patches/bbb_overlays/0017-doc-misc-Beaglebone-capemanager-documentation.patch b/patches/bbb_overlays/0023-doc-misc-Beaglebone-capemanager-documentation.patch similarity index 96% rename from patches/bbb_overlays/0017-doc-misc-Beaglebone-capemanager-documentation.patch rename to patches/bbb_overlays/0023-doc-misc-Beaglebone-capemanager-documentation.patch index 90087068f4d3fdede101f92f75c1cca52d24ae30..e4a7567487624a62dbeb3a171a70004470994c9a 100644 --- a/patches/bbb_overlays/0017-doc-misc-Beaglebone-capemanager-documentation.patch +++ b/patches/bbb_overlays/0023-doc-misc-Beaglebone-capemanager-documentation.patch @@ -1,7 +1,7 @@ -From 496bb0ed33b7f5996e9ade2a3ec8099c3f0c3d94 Mon Sep 17 00:00:00 2001 +From 9d4664a3a27a3451b0739cf78792beff6b623df2 Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou <pantelis.antoniou@konsulko.com> Date: Wed, 13 May 2015 10:27:46 +0300 -Subject: [PATCH 17/38] doc: misc: Beaglebone capemanager documentation +Subject: [PATCH 23/41] doc: misc: Beaglebone capemanager documentation Add beaglebone capemanager documentation entry. @@ -81,5 +81,5 @@ index 0000000..2a8c766 +Applying the device tree overlay makes the cape operational, as if it was part +of the kernel's booting device tree. -- -2.8.0.rc3 +2.8.1 diff --git a/patches/bbb_overlays/0024-doc-dt-Document-the-indirect-overlay-method.patch b/patches/bbb_overlays/0024-doc-dt-Document-the-indirect-overlay-method.patch deleted file mode 100644 index a557c157319bd82109f6c1ce91de639e7c2cd795..0000000000000000000000000000000000000000 --- a/patches/bbb_overlays/0024-doc-dt-Document-the-indirect-overlay-method.patch +++ /dev/null @@ -1,51 +0,0 @@ -From a449b26b0648ec8dc831419cb2ace955bfd09448 Mon Sep 17 00:00:00 2001 -From: Pantelis Antoniou <pantelis.antoniou@konsulko.com> -Date: Fri, 12 Jun 2015 16:39:18 +0300 -Subject: [PATCH 24/38] doc: dt: Document the indirect overlay method. - -Add a description of the indirect overlay method to the overlay -documention file. - -Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com> ---- - Documentation/devicetree/overlay-notes.txt | 13 +++++++++++++ - 1 file changed, 13 insertions(+) - -diff --git a/Documentation/devicetree/overlay-notes.txt b/Documentation/devicetree/overlay-notes.txt -index d418a6c..dd595e6 100644 ---- a/Documentation/devicetree/overlay-notes.txt -+++ b/Documentation/devicetree/overlay-notes.txt -@@ -100,6 +100,10 @@ Finally, if you need to remove all overlays in one-go, just call - of_overlay_destroy_all() which will remove every single one in the correct - order. - -+If your board has multiple slots/places where a single overlay can work -+and each slot is defined by a node, you can use the of_overlay_create_indirect() -+method to select the target. -+ - Overlay DTS Format - ------------------ - -@@ -113,6 +117,11 @@ The DTS of an overlay should have the following format: - target=<phandle>; /* phandle target of the overlay */ - or - target-path="/path"; /* target path of the overlay */ -+ or -+ target-indirect { /* indirect target selector */ -+ foo { target|target-path ... }; -+ bar { .... }; -+ }; - - __overlay__ { - property-a; /* add property-a to the target */ -@@ -131,3 +140,7 @@ Using the non-phandle based target method allows one to use a base DT which does - not contain a __symbols__ node, i.e. it was not compiled with the -@ option. - The __symbols__ node is only required for the target=<phandle> method, since it - contains the information required to map from a phandle to a tree location. -+ -+The indirect target requires the use of a selector target on the call to -+of_overlay_create_indirect(). I.e. passing the "foo" id will select the target -+in the foo node, "bar" in bar node, etc. --- -2.8.0.rc3 - diff --git a/patches/bbb_overlays/0018-doc-dt-beaglebone-cape-manager-bindings.patch b/patches/bbb_overlays/0024-doc-dt-beaglebone-cape-manager-bindings.patch similarity index 97% rename from patches/bbb_overlays/0018-doc-dt-beaglebone-cape-manager-bindings.patch rename to patches/bbb_overlays/0024-doc-dt-beaglebone-cape-manager-bindings.patch index ae4ea793996cdd705720e44a404d851bc0a667c2..e12a9b459c8bbc3f85a8b4fcedf656e43cdd1bb8 100644 --- a/patches/bbb_overlays/0018-doc-dt-beaglebone-cape-manager-bindings.patch +++ b/patches/bbb_overlays/0024-doc-dt-beaglebone-cape-manager-bindings.patch @@ -1,7 +1,7 @@ -From 762425d0cb7bec0beee29943e84319f8be162d58 Mon Sep 17 00:00:00 2001 +From 86455714a430bb0d5065b0451d7b9139fc2b356d Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou <pantelis.antoniou@konsulko.com> Date: Tue, 12 May 2015 15:24:22 +0300 -Subject: [PATCH 18/38] doc: dt: beaglebone cape manager bindings. +Subject: [PATCH 24/41] doc: dt: beaglebone cape manager bindings. Bindings document for the beaglebone cape manager. @@ -129,5 +129,5 @@ index 0000000..7e4fbc9 + }; +}; -- -2.8.0.rc3 +2.8.1 diff --git a/patches/bbb_overlays/0019-doc-ABI-bone_capemgr-sysfs-API.patch b/patches/bbb_overlays/0025-doc-ABI-bone_capemgr-sysfs-API.patch similarity index 96% rename from patches/bbb_overlays/0019-doc-ABI-bone_capemgr-sysfs-API.patch rename to patches/bbb_overlays/0025-doc-ABI-bone_capemgr-sysfs-API.patch index 6de431ad921736f16ce8bc2d7f22bff1e224efbe..2f9c135b3e1d3354cff2ebc0c6efbf8ef463bf12 100644 --- a/patches/bbb_overlays/0019-doc-ABI-bone_capemgr-sysfs-API.patch +++ b/patches/bbb_overlays/0025-doc-ABI-bone_capemgr-sysfs-API.patch @@ -1,7 +1,7 @@ -From 26152f30d3a43cc8976dafe70d7778d7b6fa0dab Mon Sep 17 00:00:00 2001 +From 8db7c9a7f4287aec1a4c1bb5819c3bdb90bd91c0 Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou <pantelis.antoniou@konsulko.com> Date: Tue, 12 May 2015 16:20:08 +0300 -Subject: [PATCH 19/38] doc: ABI: bone_capemgr sysfs API +Subject: [PATCH 25/41] doc: ABI: bone_capemgr sysfs API Document the beaglebone's capemgr sysfs API @@ -81,5 +81,5 @@ index 0000000..e2df613 + serial-number - baseboard serial number + config-option - displayed but ignored -- -2.8.0.rc3 +2.8.1 diff --git a/patches/bbb_overlays/0020-MAINTAINERS-Beaglebone-capemanager-maintainer.patch b/patches/bbb_overlays/0026-MAINTAINERS-Beaglebone-capemanager-maintainer.patch similarity index 78% rename from patches/bbb_overlays/0020-MAINTAINERS-Beaglebone-capemanager-maintainer.patch rename to patches/bbb_overlays/0026-MAINTAINERS-Beaglebone-capemanager-maintainer.patch index cbe213c38919ee06f8133d574695ee57da05de07..b0e0069e6877241a8a695a2303a15981a81e1861 100644 --- a/patches/bbb_overlays/0020-MAINTAINERS-Beaglebone-capemanager-maintainer.patch +++ b/patches/bbb_overlays/0026-MAINTAINERS-Beaglebone-capemanager-maintainer.patch @@ -1,7 +1,7 @@ -From d11c1ed38bd2d7c94b5c42bde13b3b22c5b1463d Mon Sep 17 00:00:00 2001 +From 6810c865305ff9d21ca840ea36d1b33e11e5ec8f Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou <pantelis.antoniou@konsulko.com> Date: Wed, 13 May 2015 10:32:27 +0300 -Subject: [PATCH 20/38] MAINTAINERS: Beaglebone capemanager maintainer +Subject: [PATCH 26/41] MAINTAINERS: Beaglebone capemanager maintainer Add me as the capemanager maintainer. @@ -11,10 +11,10 @@ Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com> 1 file changed, 8 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS -index 1d9c011..2e4e813 100644 +index 5f83015..8c9baf4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS -@@ -2231,6 +2231,14 @@ W: https://linuxtv.org +@@ -2299,6 +2299,14 @@ W: https://linuxtv.org S: Supported F: drivers/media/platform/sti/bdisp @@ -30,5 +30,5 @@ index 1d9c011..2e4e813 100644 S: Orphan F: Documentation/filesystems/befs.txt -- -2.8.0.rc3 +2.8.1 diff --git a/patches/bbb_overlays/0021-arm-dts-Enable-beaglebone-cape-manager.patch b/patches/bbb_overlays/0027-arm-dts-Enable-beaglebone-cape-manager.patch similarity index 81% rename from patches/bbb_overlays/0021-arm-dts-Enable-beaglebone-cape-manager.patch rename to patches/bbb_overlays/0027-arm-dts-Enable-beaglebone-cape-manager.patch index 05e9fe58172f8bc0619f3f58842a4c75f8be766f..ee693339ecc6f5361f0ad6663d965cac13678b9e 100644 --- a/patches/bbb_overlays/0021-arm-dts-Enable-beaglebone-cape-manager.patch +++ b/patches/bbb_overlays/0027-arm-dts-Enable-beaglebone-cape-manager.patch @@ -1,7 +1,7 @@ -From f7c5c80fdf60c0a14f39bf86980389b7c5ea0daa Mon Sep 17 00:00:00 2001 -From: Robert Nelson <robertcnelson@gmail.com> -Date: Tue, 15 Mar 2016 16:15:47 -0500 -Subject: [PATCH 21/38] arm: dts: Enable beaglebone cape-manager +From 0f437c539e29b242f2830c05ad13981af36655c0 Mon Sep 17 00:00:00 2001 +From: Pantelis Antoniou <pantelis.antoniou@konsulko.com> +Date: Tue, 12 May 2015 14:35:13 +0300 +Subject: [PATCH 27/41] arm: dts: Enable beaglebone cape-manager Enable the cape manager on the beaglebone family of boards. @@ -11,7 +11,7 @@ Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com> 1 file changed, 25 insertions(+) diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi -index 62837c0..a9e9eb1 100644 +index a8235ae..3a424b5 100644 --- a/arch/arm/boot/dts/am335x-bone-common.dtsi +++ b/arch/arm/boot/dts/am335x-bone-common.dtsi @@ -397,3 +397,28 @@ @@ -44,5 +44,5 @@ index 62837c0..a9e9eb1 100644 + }; +}; -- -2.8.0.rc3 +2.8.1 diff --git a/patches/bbb_overlays/0028-of-overlay-Implement-target-index-support.patch b/patches/bbb_overlays/0028-of-overlay-Implement-target-index-support.patch new file mode 100644 index 0000000000000000000000000000000000000000..ee451a3baa4ee1f2fb9d2978fe9e8eaf790063fb --- /dev/null +++ b/patches/bbb_overlays/0028-of-overlay-Implement-target-index-support.patch @@ -0,0 +1,185 @@ +From bc63d76fb6ff7a108f7233b0c8a571ab8ac22ade Mon Sep 17 00:00:00 2001 +From: Pantelis Antoniou <pantelis.antoniou@konsulko.com> +Date: Thu, 21 May 2015 12:31:06 +0300 +Subject: [PATCH 28/41] of: overlay: Implement target index support + +Some applications require applying the same overlay to a different +target according to some external condition (for instance depending +on the slot a card has been inserted, the overlay target is different). + +The target index functionality use requires using the new +of_overlay_create_target_index() API which uses an index argument. + +The format changes as follow + + fragment@0 { + target = <&foo_target>, <&bar_target>; + }; + +Calling of_overlay_create_target_index() with a 0 index selects +the foo_target, while using an index of 1 selects the bar_target. + +Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com> +--- + drivers/of/overlay.c | 65 ++++++++++++++++++++++++++++++++++++---------------- + include/linux/of.h | 8 +++++++ + 2 files changed, 53 insertions(+), 20 deletions(-) + +diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c +index fdfc487..2efd4b7 100644 +--- a/drivers/of/overlay.c ++++ b/drivers/of/overlay.c +@@ -75,6 +75,7 @@ struct of_overlay { + const struct attribute_group **attr_groups; + struct of_changeset cset; + struct kobject kobj; ++ int target_index; + }; + + /* master enable switch; once set to 0 can't be re-enabled */ +@@ -222,30 +223,29 @@ static int of_overlay_apply(struct of_overlay *ov) + + /* + * Find the target node using a number of different strategies +- * in order of preference ++ * in order of preference. Respects the target index if available. + * + * "target" property containing the phandle of the target + * "target-path" property containing the path of the target + */ +-static struct device_node *find_target_node(struct device_node *info_node) ++static struct device_node *find_target_node(struct of_overlay *ov, ++ struct device_node *info_node, int index) + { + const char *path; + u32 val; + int ret; + + /* first try to go by using the target as a phandle */ +- ret = of_property_read_u32(info_node, "target", &val); ++ ret = of_property_read_u32_index(info_node, "target", index, &val); + if (ret == 0) + return of_find_node_by_phandle(val); + +- /* now try to locate by path */ +- ret = of_property_read_string(info_node, "target-path", &path); ++ /* failed, try to locate by path */ ++ ret = of_property_read_string_index(info_node, "target-path", index, ++ &path); + if (ret == 0) + return of_find_node_by_path(path); + +- pr_err("%s: Failed to find target for node %p (%s)\n", __func__, +- info_node, info_node->name); +- + return NULL; + } + +@@ -270,7 +270,7 @@ static int of_fill_overlay_info(struct of_overlay *ov, + if (ovinfo->overlay == NULL) + goto err_fail; + +- ovinfo->target = find_target_node(info_node); ++ ovinfo->target = find_target_node(ov, info_node, ov->target_index); + if (ovinfo->target == NULL) + goto err_fail; + +@@ -473,17 +473,8 @@ static struct kobj_type of_overlay_ktype = { + + static struct kset *ov_kset; + +-/** +- * of_overlay_create() - Create and apply an overlay +- * @tree: Device node containing all the overlays +- * +- * Creates and applies an overlay while also keeping track +- * of the overlay in a list. This list can be used to prevent +- * illegal overlay removals. +- * +- * Returns the id of the created overlay, or a negative error number +- */ +-int of_overlay_create(struct device_node *tree) ++static int __of_overlay_create(struct device_node *tree, ++ int target_index) + { + struct of_overlay *ov; + int err, id; +@@ -498,6 +489,8 @@ int of_overlay_create(struct device_node *tree) + return -ENOMEM; + ov->id = -1; + ++ ov->target_index = target_index; ++ + INIT_LIST_HEAD(&ov->node); + + of_changeset_init(&ov->cset); +@@ -577,8 +570,40 @@ err_destroy_trans: + + return err; + } ++ ++/** ++ * of_overlay_create() - Create and apply an overlay ++ * @tree: Device node containing all the overlays ++ * ++ * Creates and applies an overlay while also keeping track ++ * of the overlay in a list. This list can be used to prevent ++ * illegal overlay removals. ++ * ++ * Returns the id of the created overlay, or a negative error number ++ */ ++int of_overlay_create(struct device_node *tree) ++{ ++ return __of_overlay_create(tree, 0); ++} + EXPORT_SYMBOL_GPL(of_overlay_create); + ++/** ++ * of_overlay_create_target_index() - Create and apply an overlay ++ * @tree: Device node containing all the overlays ++ * @index: Index to use in the target properties ++ * ++ * Creates and applies an overlay while also keeping track ++ * of the overlay in a list. This list can be used to prevent ++ * illegal overlay removals. ++ * ++ * Returns the id of the created overlay, or a negative error number ++ */ ++int of_overlay_create_target_index(struct device_node *tree, int index) ++{ ++ return __of_overlay_create(tree, index); ++} ++EXPORT_SYMBOL_GPL(of_overlay_create_target_index); ++ + /* check whether the given node, lies under the given tree */ + static int overlay_subtree_check(struct device_node *tree, + struct device_node *dn) +diff --git a/include/linux/of.h b/include/linux/of.h +index 28b88bb..ca41b2f 100644 +--- a/include/linux/of.h ++++ b/include/linux/of.h +@@ -1485,6 +1485,8 @@ int of_overlay_create(struct device_node *tree); + int of_overlay_destroy(int id); + int of_overlay_destroy_all(void); + ++int of_overlay_create_target_index(struct device_node *tree, int index); ++ + #else + + static inline int of_overlay_create(struct device_node *tree) +@@ -1502,6 +1504,12 @@ static inline int of_overlay_destroy_all(void) + return -ENOTSUPP; + } + ++static inline int of_overlay_create_target_index(struct device_node *tree, ++ int index) ++{ ++ return -ENOTSUPP; ++} ++ + #endif + + #endif /* _LINUX_OF_H */ +-- +2.8.1 + diff --git a/patches/bbb_overlays/0029-of-changesets-Introduce-changeset-helper-methods.patch b/patches/bbb_overlays/0029-of-changesets-Introduce-changeset-helper-methods.patch deleted file mode 100644 index 6aef837ba5da7464e849abe5afdbdfdb956f33e7..0000000000000000000000000000000000000000 --- a/patches/bbb_overlays/0029-of-changesets-Introduce-changeset-helper-methods.patch +++ /dev/null @@ -1,383 +0,0 @@ -From 7dd3d6286d150d599d54d5a00151fe45b29aed54 Mon Sep 17 00:00:00 2001 -From: Pantelis Antoniou <pantelis.antoniou@konsulko.com> -Date: Wed, 10 Jun 2015 18:35:53 +0300 -Subject: [PATCH 29/38] of: changesets: Introduce changeset helper methods - -Changesets are very powerful, but the lack of a helper API -makes using them cumbersome. Introduce a simple copy based -API that makes things considerably easier. - -To wit, adding a property using the raw API. - - struct property *prop; - prop = kzalloc(sizeof(*prop)), GFP_KERNEL); - prop->name = kstrdup("compatible"); - prop->value = kstrdup("foo,bar"); - prop->length = strlen(prop->value) + 1; - of_changeset_add_property(ocs, np, prop); - -while using the helper API - - of_changeset_add_property_string(ocs, np, "compatible", - "foo,bar"); - -Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com> ---- - drivers/of/dynamic.c | 251 +++++++++++++++++++++++++++++++++++++++++++++++++++ - include/linux/of.h | 74 +++++++++++++++ - 2 files changed, 325 insertions(+) - -diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c -index bd817eb..7b0469f 100644 ---- a/drivers/of/dynamic.c -+++ b/drivers/of/dynamic.c -@@ -823,3 +823,254 @@ int of_changeset_action(struct of_changeset *ocs, unsigned long action, - return 0; - } - EXPORT_SYMBOL_GPL(of_changeset_action); -+ -+/* changeset helpers */ -+ -+/** -+ * of_changeset_create_device_node - Create an empty device node -+ * -+ * @ocs: changeset pointer -+ * @parent: parent device node -+ * @fmt: format string for the node's full_name -+ * @args: argument list for the format string -+ * -+ * Create an empty device node, marking it as detached and allocated. -+ * -+ * Returns a device node on success, an error encoded pointer otherwise -+ */ -+struct device_node *of_changeset_create_device_nodev( -+ struct of_changeset *ocs, struct device_node *parent, -+ const char *fmt, va_list vargs) -+{ -+ struct device_node *node; -+ -+ node = __of_node_dupv(NULL, fmt, vargs); -+ if (!node) -+ return ERR_PTR(-ENOMEM); -+ -+ node->parent = parent; -+ return node; -+} -+ -+/** -+ * of_changeset_create_device_node - Create an empty device node -+ * -+ * @ocs: changeset pointer -+ * @parent: parent device node -+ * @fmt: Format string for the node's full_name -+ * ... Arguments -+ * -+ * Create an empty device node, marking it as detached and allocated. -+ * -+ * Returns a device node on success, an error encoded pointer otherwise -+ */ -+struct device_node *of_changeset_create_device_node( -+ struct of_changeset *ocs, struct device_node *parent, -+ const char *fmt, ...) -+{ -+ va_list vargs; -+ struct device_node *node; -+ -+ va_start(vargs, fmt); -+ node = of_changeset_create_device_nodev(ocs, parent, fmt, vargs); -+ va_end(vargs); -+ return node; -+} -+ -+/** -+ * of_changeset_add_property_copy - Create a new property copying name & value -+ * -+ * @ocs: changeset pointer -+ * @np: device node pointer -+ * @name: name of the property -+ * @value: pointer to the value data -+ * @length: length of the value in bytes -+ * -+ * Adds a property to the changeset by making copies of the name & value -+ * entries. -+ * -+ * Returns zero on success, a negative error value otherwise. -+ */ -+int of_changeset_add_property_copy(struct of_changeset *ocs, -+ struct device_node *np, const char *name, const void *value, -+ int length) -+{ -+ struct property *prop; -+ char *new_name; -+ void *new_value; -+ int ret; -+ -+ ret = -ENOMEM; -+ -+ prop = kzalloc(sizeof(*prop), GFP_KERNEL); -+ if (!prop) -+ goto out_no_prop; -+ -+ new_name = kstrdup(name, GFP_KERNEL); -+ if (!new_name) -+ goto out_no_name; -+ -+ /* -+ * NOTE: There is no check for zero length value. -+ * In case of a boolean property, this will allocate a value -+ * of zero bytes. We do this to work around the use -+ * of of_get_property() calls on boolean values. -+ */ -+ new_value = kmemdup(value, length, GFP_KERNEL); -+ if (!new_value) -+ goto out_no_value; -+ -+ of_property_set_flag(prop, OF_DYNAMIC); -+ -+ prop->name = new_name; -+ prop->value = new_value; -+ prop->length = length; -+ -+ ret = of_changeset_add_property(ocs, np, prop); -+ if (ret != 0) -+ goto out_no_add; -+ -+ return 0; -+ -+out_no_add: -+ kfree(prop->value); -+out_no_value: -+ kfree(prop->name); -+out_no_name: -+ kfree(prop); -+out_no_prop: -+ return ret; -+} -+ -+/** -+ * of_changeset_add_property_string - Create a new string property -+ * -+ * @ocs: changeset pointer -+ * @np: device node pointer -+ * @name: name of the property -+ * @str: string property -+ * -+ * Adds a string property to the changeset by making copies of the name -+ * and the string value. -+ * -+ * Returns zero on success, a negative error value otherwise. -+ */ -+int of_changeset_add_property_string(struct of_changeset *ocs, -+ struct device_node *np, const char *name, const char *str) -+{ -+ return of_changeset_add_property_copy(ocs, np, name, str, -+ strlen(str) + 1); -+} -+ -+/** -+ * of_changeset_add_property_stringf - Create a new formatted string property -+ * -+ * @ocs: changeset pointer -+ * @np: device node pointer -+ * @name: name of the property -+ * @fmt: format of string property -+ * ... arguments of the format string -+ * -+ * Adds a string property to the changeset by making copies of the name -+ * and the formatted value. -+ * -+ * Returns zero on success, a negative error value otherwise. -+ */ -+int of_changeset_add_property_stringf(struct of_changeset *ocs, -+ struct device_node *np, const char *name, const char *fmt, ...) -+{ -+ va_list vargs; -+ char *str; -+ int ret; -+ -+ va_start(vargs, fmt); -+ str = kvasprintf(GFP_KERNEL, fmt, vargs); -+ va_end(vargs); -+ -+ ret = of_changeset_add_property_string(ocs, np, name, str); -+ -+ kfree(str); -+ return ret; -+} -+ -+/** -+ * of_changeset_add_property_string_list - Create a new string list property -+ * -+ * @ocs: changeset pointer -+ * @np: device node pointer -+ * @name: name of the property -+ * @strs: pointer to the string list -+ * @count: string count -+ * -+ * Adds a string list property to the changeset. -+ * -+ * Returns zero on success, a negative error value otherwise. -+ */ -+int of_changeset_add_property_string_list(struct of_changeset *ocs, -+ struct device_node *np, const char *name, const char **strs, -+ int count) -+{ -+ int total, length, i, ret; -+ char *value, *s; -+ -+ total = 0; -+ for (i = 0; i < count; i++) { -+ length = strlen(strs[i]); -+ total += length + 1; -+ } -+ -+ value = kmalloc(total, GFP_KERNEL); -+ if (!value) -+ return -ENOMEM; -+ -+ for (i = 0, s = value; i < count; i++) { -+ length = strlen(strs[i]); -+ memcpy(s, strs[i], length + 1); -+ s += length + 1; -+ } -+ -+ ret = of_changeset_add_property_copy(ocs, np, name, value, total); -+ -+ kfree(value); -+ -+ return ret; -+} -+ -+/** -+ * of_changeset_add_property_u32 - Create a new u32 property -+ * -+ * @ocs: changeset pointer -+ * @np: device node pointer -+ * @name: name of the property -+ * @val: value in host endian format -+ * -+ * Adds a u32 property to the changeset. -+ * -+ * Returns zero on success, a negative error value otherwise. -+ */ -+int of_changeset_add_property_u32(struct of_changeset *ocs, -+ struct device_node *np, const char *name, u32 val) -+{ -+ /* in place */ -+ val = cpu_to_be32(val); -+ return of_changeset_add_property_copy(ocs, np, name, &val, sizeof(val)); -+} -+ -+/** -+ * of_changeset_add_property_bool - Create a new u32 property -+ * -+ * @ocs: changeset pointer -+ * @np: device node pointer -+ * @name: name of the property -+ * -+ * Adds a bool property to the changeset. Note that there is -+ * no option to set the value to false, since the property -+ * existing sets it to true. -+ * -+ * Returns zero on success, a negative error value otherwise. -+ */ -+int of_changeset_add_property_bool(struct of_changeset *ocs, -+ struct device_node *np, const char *name) -+{ -+ return of_changeset_add_property_copy(ocs, np, name, "", 0); -+} -diff --git a/include/linux/of.h b/include/linux/of.h -index c20e9a5..da4eae5 100644 ---- a/include/linux/of.h -+++ b/include/linux/of.h -@@ -1037,6 +1037,27 @@ static inline int of_changeset_update_property(struct of_changeset *ocs, - { - return of_changeset_action(ocs, OF_RECONFIG_UPDATE_PROPERTY, np, prop); - } -+ -+struct device_node *of_changeset_create_device_nodev( -+ struct of_changeset *ocs, struct device_node *parent, -+ const char *fmt, va_list vargs); -+__printf(3, 4) struct device_node *of_changeset_create_device_node( -+ struct of_changeset *ocs, struct device_node *parent, -+ const char *fmt, ...); -+int of_changeset_add_property_copy(struct of_changeset *ocs, -+ struct device_node *np, const char *name, -+ const void *value, int length); -+int of_changeset_add_property_string(struct of_changeset *ocs, -+ struct device_node *np, const char *name, const char *str); -+__printf(4, 5) int of_changeset_add_property_stringf(struct of_changeset *ocs, -+ struct device_node *np, const char *name, const char *fmt, ...); -+int of_changeset_add_property_string_list(struct of_changeset *ocs, -+ struct device_node *np, const char *name, const char **strs, int count); -+int of_changeset_add_property_u32(struct of_changeset *ocs, -+ struct device_node *np, const char *name, u32 val); -+int of_changeset_add_property_bool(struct of_changeset *ocs, -+ struct device_node *np, const char *name); -+ - #else /* CONFIG_OF_DYNAMIC */ - static inline int of_reconfig_notifier_register(struct notifier_block *nb) - { -@@ -1056,6 +1077,59 @@ static inline int of_reconfig_get_state_change(unsigned long action, - { - return -EINVAL; - } -+ -+static inline int of_changeset_create_device_node(struct of_changeset *ocs, -+ struct device_node *parent, const char *fmt, ...) -+{ -+ return -EINVAL; -+} -+ -+int of_changeset_add_property_copy(struct of_changeset *ocs, -+ struct device_node *np, const char *name, -+ const void *value, int length) -+{ -+ return -EINVAL; -+} -+ -+int of_changeset_add_property_string(struct of_changeset *ocs, -+ struct device_node *np, const char *name, const char *str) -+{ -+ return -EINVAL; -+} -+ -+static inline struct device_node *of_changeset_create_device_nodev( -+ struct of_changeset *ocs, struct device_node *parent, -+ const char *fmt, va_list vargs) -+{ -+ return ERR_PTR(-EINVAL); -+} -+ -+static inline __printf(4, 5) struct device_node * -+ of_changeset_add_property_stringf( -+ struct of_changeset *ocs, struct device_node *np, -+ const char *name, const char *fmt, ...) -+{ -+ return ERR_PTR(-EINVAL); -+} -+ -+static inline int of_changeset_add_property_string_list( -+ struct of_changeset *ocs, struct device_node *np, const char *name, -+ const char **strs, int count) -+{ -+ return -EINVAL; -+} -+ -+static inline int of_changeset_add_property_u32(struct of_changeset *ocs, -+ struct device_node *np, const char *name, u32 val) -+{ -+ return -EINVAL; -+} -+ -+static inline int of_changeset_add_property_bool(struct of_changeset *ocs, -+ struct device_node *np, const char *name) -+{ -+ return -EINVAL; -+} - #endif /* CONFIG_OF_DYNAMIC */ - - /* CONFIG_OF_RESOLVE api */ --- -2.8.0.rc3 - diff --git a/patches/bbb_overlays/0023-of-unittest-Add-indirect-overlay-target-test.patch b/patches/bbb_overlays/0029-of-unittest-Add-indirect-overlay-target-test.patch similarity index 77% rename from patches/bbb_overlays/0023-of-unittest-Add-indirect-overlay-target-test.patch rename to patches/bbb_overlays/0029-of-unittest-Add-indirect-overlay-target-test.patch index fd2a215e509e4cadf3919c0e26c00f031b989da0..750ab657b31a43a6991f193b47d0a611751f63a0 100644 --- a/patches/bbb_overlays/0023-of-unittest-Add-indirect-overlay-target-test.patch +++ b/patches/bbb_overlays/0029-of-unittest-Add-indirect-overlay-target-test.patch @@ -1,38 +1,34 @@ -From 66c4c27035e0e9e5fc2395060bb9af7a6bef34e5 Mon Sep 17 00:00:00 2001 +From ef743f063ee9aa05bfc1b168ae316be324aa5181 Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou <pantelis.antoniou@konsulko.com> Date: Thu, 21 May 2015 12:37:27 +0300 -Subject: [PATCH 23/38] of: unittest: Add indirect overlay target test +Subject: [PATCH 29/41] of: unittest: Add indirect overlay target test Add a unittest for the indirect overlay target case. Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com> --- - drivers/of/unittest-data/testcases.dts | 9 +++++ - drivers/of/unittest-data/tests-overlay.dtsi | 19 ++++++++++ - drivers/of/unittest.c | 59 +++++++++++++++++++++++++++++ - 3 files changed, 87 insertions(+) + drivers/of/unittest-data/testcases.dts | 5 +++ + drivers/of/unittest-data/tests-overlay.dtsi | 15 ++++++++ + drivers/of/unittest.c | 60 +++++++++++++++++++++++++++++ + 3 files changed, 80 insertions(+) diff --git a/drivers/of/unittest-data/testcases.dts b/drivers/of/unittest-data/testcases.dts -index 12f7c3d..ec17ab7 100644 +index 12f7c3d..74e8805 100644 --- a/drivers/of/unittest-data/testcases.dts +++ b/drivers/of/unittest-data/testcases.dts -@@ -75,5 +75,14 @@ +@@ -75,5 +75,10 @@ target = <0x00000000>; }; }; + overlay16 { + fragment@0 { -+ target-indirect { -+ unittest16 { -+ target = <0x00000000>; -+ }; -+ }; ++ target = <0x00000000 0x00000004>; + }; + }; }; }; }; diff --git a/drivers/of/unittest-data/tests-overlay.dtsi b/drivers/of/unittest-data/tests-overlay.dtsi -index 02ba56c..881d863 100644 +index 02ba56c..ab32996 100644 --- a/drivers/of/unittest-data/tests-overlay.dtsi +++ b/drivers/of/unittest-data/tests-overlay.dtsi @@ -110,6 +110,12 @@ @@ -48,18 +44,14 @@ index 02ba56c..881d863 100644 }; }; -@@ -325,5 +331,18 @@ +@@ -325,5 +331,14 @@ }; }; + /* test enable using indirect functionality */ + overlay16 { + fragment@0 { -+ target-indirect { -+ unittest16 { -+ target = <&unittest16>; -+ }; -+ }; ++ target = <&unittest17>, <&unittest16>; + __overlay__ { + status = "okay"; + }; @@ -68,10 +60,10 @@ index 02ba56c..881d863 100644 }; }; diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c -index e986e6e..cecde32 100644 +index d8dd3c8..15cd995 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c -@@ -1868,6 +1868,63 @@ static inline void of_unittest_overlay_i2c_15(void) { } +@@ -1907,6 +1907,64 @@ static inline void of_unittest_overlay_i2c_15(void) { } #endif @@ -103,7 +95,8 @@ index e986e6e..cecde32 100644 + goto out; + } + -+ ret = of_overlay_create_indirect(np, "unittest16"); ++ /* unittest16 is at index #1 */ ++ ret = of_overlay_create_target_index(np, 1); + if (ret < 0) { + unittest(0, "could not create overlay from \"%s\"\n", + overlay_path(overlay_nr)); @@ -135,7 +128,7 @@ index e986e6e..cecde32 100644 static void __init of_unittest_overlay(void) { struct device_node *bus_np = NULL; -@@ -1919,6 +1976,8 @@ static void __init of_unittest_overlay(void) +@@ -1958,6 +2016,8 @@ static void __init of_unittest_overlay(void) of_unittest_overlay_10(); of_unittest_overlay_11(); @@ -145,5 +138,5 @@ index e986e6e..cecde32 100644 if (unittest(of_unittest_overlay_i2c_init() == 0, "i2c init failed\n")) goto out; -- -2.8.0.rc3 +2.8.1 diff --git a/patches/bbb_overlays/0030-doc-dt-Document-the-indirect-overlay-method.patch b/patches/bbb_overlays/0030-doc-dt-Document-the-indirect-overlay-method.patch new file mode 100644 index 0000000000000000000000000000000000000000..d69a3ba44fdb630396adc5435be19a34f1023cc3 --- /dev/null +++ b/patches/bbb_overlays/0030-doc-dt-Document-the-indirect-overlay-method.patch @@ -0,0 +1,53 @@ +From 9ea8c4c78d9bc8156dc031a866915ef7f6b8c47a Mon Sep 17 00:00:00 2001 +From: Pantelis Antoniou <pantelis.antoniou@konsulko.com> +Date: Fri, 12 Jun 2015 16:39:18 +0300 +Subject: [PATCH 30/41] doc: dt: Document the indirect overlay method. + +Add a description of the target index overlay method to the overlay +documention file. + +Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com> +--- + Documentation/devicetree/overlay-notes.txt | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +diff --git a/Documentation/devicetree/overlay-notes.txt b/Documentation/devicetree/overlay-notes.txt +index d418a6c..6995fc1 100644 +--- a/Documentation/devicetree/overlay-notes.txt ++++ b/Documentation/devicetree/overlay-notes.txt +@@ -100,6 +100,10 @@ Finally, if you need to remove all overlays in one-go, just call + of_overlay_destroy_all() which will remove every single one in the correct + order. + ++If your board has multiple slots/places where a single overlay can work ++and each slot is defined by a node, you can use the ++of_overlay_create_target_index() method to select the target. ++ + Overlay DTS Format + ------------------ + +@@ -110,9 +114,11 @@ The DTS of an overlay should have the following format: + + fragment@0 { /* first child node */ + +- target=<phandle>; /* phandle target of the overlay */ ++ /* phandle target of the overlay */ ++ target=<phandle> [, <phandle>, ...]; + or +- target-path="/path"; /* target path of the overlay */ ++ /* target path of the overlay */ ++ target-path="/path" [ , "/path", ...]; + + __overlay__ { + property-a; /* add property-a to the target */ +@@ -131,3 +137,7 @@ Using the non-phandle based target method allows one to use a base DT which does + not contain a __symbols__ node, i.e. it was not compiled with the -@ option. + The __symbols__ node is only required for the target=<phandle> method, since it + contains the information required to map from a phandle to a tree location. ++ ++Using a target index requires the use of a selector target on the call to ++of_overlay_create_target_index(). I.e. passing an index of 0 will select the ++target in the foo node, an index of 1 the bar node, etc. +-- +2.8.1 + diff --git a/patches/bbb_overlays/0025-of-overlay-Introduce-target-root-capability.patch b/patches/bbb_overlays/0031-of-overlay-Introduce-target-root-capability.patch similarity index 75% rename from patches/bbb_overlays/0025-of-overlay-Introduce-target-root-capability.patch rename to patches/bbb_overlays/0031-of-overlay-Introduce-target-root-capability.patch index 2231898f5c97b141c8fc5f7cf9a80e6f15ccfc6c..ec73141fda43d6173acbb1265f59d37af25991d3 100644 --- a/patches/bbb_overlays/0025-of-overlay-Introduce-target-root-capability.patch +++ b/patches/bbb_overlays/0031-of-overlay-Introduce-target-root-capability.patch @@ -1,7 +1,7 @@ -From 78960ae372cef93cf1ee87b1938e53bac4d995f6 Mon Sep 17 00:00:00 2001 +From 42bf1cb2609f9be4e1d5492bec24a5a21b50fd31 Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou <pantelis.antoniou@konsulko.com> Date: Fri, 12 Jun 2015 15:32:55 +0300 -Subject: [PATCH 25/38] of: overlay: Introduce target root capability. +Subject: [PATCH 31/41] of: overlay: Introduce target root capability. The target facility of an overlay allows the target to be any point in the live kernel tree, since it usually that's required when @@ -22,20 +22,20 @@ Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com> 2 files changed, 102 insertions(+), 7 deletions(-) diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c -index 364b619..a274d65 100644 +index 2efd4b7..49bdcba 100644 --- a/drivers/of/overlay.c +++ b/drivers/of/overlay.c @@ -76,6 +76,7 @@ struct of_overlay { struct of_changeset cset; struct kobject kobj; - char *indirect_id; + int target_index; + struct device_node *target_root; }; /* master enable switch; once set to 0 can't be re-enabled */ -@@ -224,20 +225,83 @@ static int of_overlay_apply(struct of_overlay *ov) - static struct device_node *find_target_node_direct(struct of_overlay *ov, - struct device_node *info_node) +@@ -231,22 +232,85 @@ static int of_overlay_apply(struct of_overlay *ov) + static struct device_node *find_target_node(struct of_overlay *ov, + struct device_node *info_node, int index) { + struct device_node *target = NULL, *np; const char *path; @@ -44,7 +44,7 @@ index 364b619..a274d65 100644 int ret; /* first try to go by using the target as a phandle */ - ret = of_property_read_u32(info_node, "target", &val); + ret = of_property_read_u32_index(info_node, "target", index, &val); - if (ret == 0) - return of_find_node_by_phandle(val); + if (ret == 0) { @@ -58,7 +58,8 @@ index 364b619..a274d65 100644 + } /* failed, try to locate by path */ - ret = of_property_read_string(info_node, "target-path", &path); + ret = of_property_read_string_index(info_node, "target-path", index, + &path); - if (ret == 0) - return of_find_node_by_path(path); + if (ret == 0) { @@ -101,9 +102,9 @@ index 364b619..a274d65 100644 + } + goto check_root; + } -+ -+ return NULL; + return NULL; ++ +check_root: + if (!ov->target_root) + return target; @@ -118,59 +119,60 @@ index 364b619..a274d65 100644 + of_node_full_name(ov->target_root)); + /* target is not under target_root */ + of_node_put(target); - return NULL; ++ return NULL; } -@@ -462,6 +526,7 @@ void of_overlay_release(struct kobject *kobj) + /** +@@ -418,6 +482,7 @@ void of_overlay_release(struct kobject *kobj) { struct of_overlay *ov = kobj_to_overlay(kobj); + of_node_put(ov->target_root); - kfree(ov->indirect_id); kfree(ov); } -@@ -519,7 +584,7 @@ static struct kobj_type of_overlay_ktype = { + +@@ -474,7 +539,7 @@ static struct kobj_type of_overlay_ktype = { static struct kset *ov_kset; static int __of_overlay_create(struct device_node *tree, -- const char *indirect_id) -+ const char *indirect_id, struct device_node *target_root) +- int target_index) ++ int target_index, struct device_node *target_root) { struct of_overlay *ov; int err, id; -@@ -541,6 +606,7 @@ static int __of_overlay_create(struct device_node *tree, - goto err_no_mem; - } - } +@@ -490,6 +555,7 @@ static int __of_overlay_create(struct device_node *tree, + ov->id = -1; + + ov->target_index = target_index; + ov->target_root = of_node_get(target_root); INIT_LIST_HEAD(&ov->node); -@@ -617,6 +683,7 @@ err_free_idr: +@@ -565,6 +631,7 @@ err_free_idr: + idr_remove(&ov_idr, ov->id); err_destroy_trans: of_changeset_destroy(&ov->cset); - err_no_mem: + of_node_put(ov->target_root); - kfree(ov->indirect_id); kfree(ov); mutex_unlock(&of_mutex); -@@ -636,7 +703,7 @@ err_no_mem: + +@@ -583,7 +650,7 @@ err_destroy_trans: */ int of_overlay_create(struct device_node *tree) { -- return __of_overlay_create(tree, NULL); -+ return __of_overlay_create(tree, NULL, NULL); +- return __of_overlay_create(tree, 0); ++ return __of_overlay_create(tree, 0, NULL); } EXPORT_SYMBOL_GPL(of_overlay_create); -@@ -653,10 +720,30 @@ EXPORT_SYMBOL_GPL(of_overlay_create); +@@ -600,10 +667,30 @@ EXPORT_SYMBOL_GPL(of_overlay_create); */ - int of_overlay_create_indirect(struct device_node *tree, const char *id) + int of_overlay_create_target_index(struct device_node *tree, int index) { -- return __of_overlay_create(tree, id); -+ return __of_overlay_create(tree, id, NULL); +- return __of_overlay_create(tree, index); ++ return __of_overlay_create(tree, index, NULL); } - EXPORT_SYMBOL_GPL(of_overlay_create_indirect); + EXPORT_SYMBOL_GPL(of_overlay_create_target_index); +/** + * of_overlay_create_target_root() - Create and apply an overlay @@ -188,7 +190,7 @@ index 364b619..a274d65 100644 +int of_overlay_create_target_root(struct device_node *tree, + struct device_node *target_root) +{ -+ return __of_overlay_create(tree, NULL, target_root); ++ return __of_overlay_create(tree, 0, target_root); +} +EXPORT_SYMBOL_GPL(of_overlay_create_target_root); + @@ -196,19 +198,19 @@ index 364b619..a274d65 100644 static int overlay_subtree_check(struct device_node *tree, struct device_node *dn) diff --git a/include/linux/of.h b/include/linux/of.h -index 56bed18..c20e9a5 100644 +index ca41b2f..f835026 100644 --- a/include/linux/of.h +++ b/include/linux/of.h -@@ -1084,6 +1084,8 @@ int of_overlay_destroy(int id); +@@ -1486,6 +1486,8 @@ int of_overlay_destroy(int id); int of_overlay_destroy_all(void); - int of_overlay_create_indirect(struct device_node *tree, const char *id); + int of_overlay_create_target_index(struct device_node *tree, int index); +int of_overlay_create_target_root(struct device_node *tree, + struct device_node *target_root); #else -@@ -1108,6 +1110,12 @@ static inline int of_overlay_create_indirect(struct device_node *tree, +@@ -1510,6 +1512,12 @@ static inline int of_overlay_create_target_index(struct device_node *tree, return -ENOTSUPP; } @@ -222,5 +224,5 @@ index 56bed18..c20e9a5 100644 #endif /* _LINUX_OF_H */ -- -2.8.0.rc3 +2.8.1 diff --git a/patches/bbb_overlays/0032-of-remove-bogus-return-in-of_core_init.patch b/patches/bbb_overlays/0032-of-remove-bogus-return-in-of_core_init.patch deleted file mode 100644 index 1eaafb97f1419bc93a679d3204195b85582c8dd6..0000000000000000000000000000000000000000 --- a/patches/bbb_overlays/0032-of-remove-bogus-return-in-of_core_init.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 288296b3cc85084a3cebd90ab6ee1c0f8c57a7f6 Mon Sep 17 00:00:00 2001 -From: Pantelis Antoniou <pantelis.antoniou@konsulko.com> -Date: Wed, 14 Oct 2015 13:22:38 +0300 -Subject: [PATCH 32/38] of: remove bogus return in of_core_init - -Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com> ---- - drivers/of/base.c | 2 -- - 1 file changed, 2 deletions(-) - -diff --git a/drivers/of/base.c b/drivers/of/base.c -index c025728..9bbca56 100644 ---- a/drivers/of/base.c -+++ b/drivers/of/base.c -@@ -213,8 +213,6 @@ void __init of_core_init(void) - ret = of_overlay_init(); - if (ret != 0) - pr_warn("of_init: of_overlay_init failed!\n"); -- -- return 0; - } - - static struct property *__of_find_property(const struct device_node *np, --- -2.8.0.rc3 - diff --git a/patches/bbb_overlays/0026-of-unittest-Unit-tests-for-target-root-overlays.patch b/patches/bbb_overlays/0032-of-unittest-Unit-tests-for-target-root-overlays.patch similarity index 95% rename from patches/bbb_overlays/0026-of-unittest-Unit-tests-for-target-root-overlays.patch rename to patches/bbb_overlays/0032-of-unittest-Unit-tests-for-target-root-overlays.patch index b87f8d07105e974d500a2d102dabd5f16fd81a94..afbca984bbe7815e80b97753172060f8f2870c1a 100644 --- a/patches/bbb_overlays/0026-of-unittest-Unit-tests-for-target-root-overlays.patch +++ b/patches/bbb_overlays/0032-of-unittest-Unit-tests-for-target-root-overlays.patch @@ -1,7 +1,7 @@ -From 87ea6302755c3a840c1d1a1b82f0b853ed57210b Mon Sep 17 00:00:00 2001 +From fd600471fd7b6a137dce0008744aa9fafcc9edcb Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou <pantelis.antoniou@konsulko.com> Date: Fri, 12 Jun 2015 16:18:26 +0300 -Subject: [PATCH 26/38] of: unittest: Unit-tests for target root overlays. +Subject: [PATCH 32/41] of: unittest: Unit-tests for target root overlays. Add unittests for target-root based overlays. @@ -13,11 +13,11 @@ Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com> 3 files changed, 266 insertions(+) diff --git a/drivers/of/unittest-data/testcases.dts b/drivers/of/unittest-data/testcases.dts -index ec17ab7..8052b96 100644 +index 74e8805..a6ded1b6 100644 --- a/drivers/of/unittest-data/testcases.dts +++ b/drivers/of/unittest-data/testcases.dts -@@ -84,5 +84,10 @@ - }; +@@ -80,5 +80,10 @@ + target = <0x00000000 0x00000004>; }; }; + overlay18 { @@ -28,7 +28,7 @@ index ec17ab7..8052b96 100644 }; }; }; diff --git a/drivers/of/unittest-data/tests-overlay.dtsi b/drivers/of/unittest-data/tests-overlay.dtsi -index 881d863..e10ff5a 100644 +index ab32996..170b04d 100644 --- a/drivers/of/unittest-data/tests-overlay.dtsi +++ b/drivers/of/unittest-data/tests-overlay.dtsi @@ -116,6 +116,24 @@ @@ -56,7 +56,7 @@ index 881d863..e10ff5a 100644 }; }; -@@ -344,5 +362,35 @@ +@@ -340,5 +358,35 @@ }; }; }; @@ -93,10 +93,10 @@ index 881d863..e10ff5a 100644 }; }; diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c -index cecde32..4f6b605 100644 +index 15cd995..94d5dfe 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c -@@ -1925,6 +1925,215 @@ out: +@@ -1965,6 +1965,215 @@ out: unittest(1, "overlay test %d passed\n", 16); } @@ -312,7 +312,7 @@ index cecde32..4f6b605 100644 static void __init of_unittest_overlay(void) { struct device_node *bus_np = NULL; -@@ -1978,6 +2187,10 @@ static void __init of_unittest_overlay(void) +@@ -2018,6 +2227,10 @@ static void __init of_unittest_overlay(void) of_unittest_overlay_16(); @@ -324,5 +324,5 @@ index cecde32..4f6b605 100644 if (unittest(of_unittest_overlay_i2c_init() == 0, "i2c init failed\n")) goto out; -- -2.8.0.rc3 +2.8.1 diff --git a/patches/bbb_overlays/0027-doc-dt-Document-the-target-root-overlay-method.patch b/patches/bbb_overlays/0033-doc-dt-Document-the-target-root-overlay-method.patch similarity index 67% rename from patches/bbb_overlays/0027-doc-dt-Document-the-target-root-overlay-method.patch rename to patches/bbb_overlays/0033-doc-dt-Document-the-target-root-overlay-method.patch index 7425ecbffb1acd76c44192a3e9ecf4d9a0eea6fe..9d030b2d3416a7b26770e8c3d6bb9c2b892a2b1e 100644 --- a/patches/bbb_overlays/0027-doc-dt-Document-the-target-root-overlay-method.patch +++ b/patches/bbb_overlays/0033-doc-dt-Document-the-target-root-overlay-method.patch @@ -1,7 +1,7 @@ -From f349c9956aa36ab0b19fdcb7b023adb5278eef71 Mon Sep 17 00:00:00 2001 +From 2e991a84dea116cb04671248b693ff58687f32e4 Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou <pantelis.antoniou@konsulko.com> Date: Fri, 12 Jun 2015 16:51:27 +0300 -Subject: [PATCH 27/38] doc: dt: Document the target root overlay method +Subject: [PATCH 33/41] doc: dt: Document the target root overlay method Add a description of the target root overlay method to the overlay documention file. @@ -12,12 +12,12 @@ Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com> 1 file changed, 8 insertions(+) diff --git a/Documentation/devicetree/overlay-notes.txt b/Documentation/devicetree/overlay-notes.txt -index dd595e6..00ede57 100644 +index 6995fc1..3e8df30 100644 --- a/Documentation/devicetree/overlay-notes.txt +++ b/Documentation/devicetree/overlay-notes.txt @@ -104,6 +104,10 @@ If your board has multiple slots/places where a single overlay can work - and each slot is defined by a node, you can use the of_overlay_create_indirect() - method to select the target. + and each slot is defined by a node, you can use the + of_overlay_create_target_index() method to select the target. +For overlays on probeable busses, use the of_overlay_create_target_root() method +in which you supply a device node as a target root, and which all target @@ -26,14 +26,14 @@ index dd595e6..00ede57 100644 Overlay DTS Format ------------------ -@@ -144,3 +148,7 @@ contains the information required to map from a phandle to a tree location. - The indirect target requires the use of a selector target on the call to - of_overlay_create_indirect(). I.e. passing the "foo" id will select the target - in the foo node, "bar" in bar node, etc. +@@ -141,3 +145,7 @@ contains the information required to map from a phandle to a tree location. + Using a target index requires the use of a selector target on the call to + of_overlay_create_target_index(). I.e. passing an index of 0 will select the + target in the foo node, an index of 1 the bar node, etc. + +Note that when using the target root create method all target references must +lie under the target root node. I.e. the overlay is not allowed to 'break' out +of the root. -- -2.8.0.rc3 +2.8.1 diff --git a/patches/bbb_overlays/0033-of-Maintainer-fixes-for-dynamic.patch b/patches/bbb_overlays/0033-of-Maintainer-fixes-for-dynamic.patch deleted file mode 100644 index 7461e3ffc4d24e04fdc3e717d61981fc83d6d21e..0000000000000000000000000000000000000000 --- a/patches/bbb_overlays/0033-of-Maintainer-fixes-for-dynamic.patch +++ /dev/null @@ -1,60 +0,0 @@ -From fe6a70c7553dbccb0dd58489b0a9135bed96acf4 Mon Sep 17 00:00:00 2001 -From: Pantelis Antoniou <pantelis.antoniou@konsulko.com> -Date: Wed, 14 Oct 2015 13:14:29 +0300 -Subject: [PATCH 33/38] of: Maintainer fixes for dynamic - -Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com> ---- - drivers/of/dynamic.c | 19 +++++++++---------- - 1 file changed, 9 insertions(+), 10 deletions(-) - -diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c -index 7b0469f..eca22b4 100644 ---- a/drivers/of/dynamic.c -+++ b/drivers/of/dynamic.c -@@ -898,9 +898,7 @@ int of_changeset_add_property_copy(struct of_changeset *ocs, - struct property *prop; - char *new_name; - void *new_value; -- int ret; -- -- ret = -ENOMEM; -+ int ret = -ENOMEM; - - prop = kzalloc(sizeof(*prop), GFP_KERNEL); - if (!prop) -@@ -1010,13 +1008,14 @@ int of_changeset_add_property_string_list(struct of_changeset *ocs, - struct device_node *np, const char *name, const char **strs, - int count) - { -- int total, length, i, ret; -+ int total = 0, i, ret; - char *value, *s; - -- total = 0; - for (i = 0; i < count; i++) { -- length = strlen(strs[i]); -- total += length + 1; -+ /* check if it's NULL */ -+ if (!strs[i]) -+ return -EINVAL; -+ total += strlen(strs[i]) + 1; - } - - value = kmalloc(total, GFP_KERNEL); -@@ -1024,9 +1023,9 @@ int of_changeset_add_property_string_list(struct of_changeset *ocs, - return -ENOMEM; - - for (i = 0, s = value; i < count; i++) { -- length = strlen(strs[i]); -- memcpy(s, strs[i], length + 1); -- s += length + 1; -+ /* no need to check for NULL, check above */ -+ strcpy(s, strs[i]); -+ s += strlen(strs[i]) + 1; - } - - ret = of_changeset_add_property_copy(ocs, np, name, value, total); --- -2.8.0.rc3 - diff --git a/patches/bbb_overlays/0030-RFC-Device-overlay-manager-PCI-USB-DT.patch b/patches/bbb_overlays/0034-RFC-Device-overlay-manager-PCI-USB-DT.patch similarity index 99% rename from patches/bbb_overlays/0030-RFC-Device-overlay-manager-PCI-USB-DT.patch rename to patches/bbb_overlays/0034-RFC-Device-overlay-manager-PCI-USB-DT.patch index 7aed72b9f01a37d980c372f343656355d3786ec6..e915ba7c2aaa642ef70d7ab784a5ef891f7fa3d3 100644 --- a/patches/bbb_overlays/0030-RFC-Device-overlay-manager-PCI-USB-DT.patch +++ b/patches/bbb_overlays/0034-RFC-Device-overlay-manager-PCI-USB-DT.patch @@ -1,7 +1,7 @@ -From 1431479996f365eaf76508092b05cbee0d3ed5d4 Mon Sep 17 00:00:00 2001 +From fc11ece52cf28abb28ab0d8a01808c879465cc29 Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou <pantelis.antoniou@konsulko.com> Date: Thu, 21 May 2015 12:08:54 +0300 -Subject: [PATCH 30/38] RFC: Device overlay manager (PCI/USB + DT) +Subject: [PATCH 34/41] RFC: Device overlay manager (PCI/USB + DT) This probably misplaced (in drivers/misc) patch allows use of device tree overlays on the two kinds of probeable busses @@ -1366,5 +1366,5 @@ index 0000000..d5c8d1d +} +late_initcall(dovmgr_init); -- -2.8.0.rc3 +2.8.1 diff --git a/patches/bbb_overlays/0035-of-rename-_node_sysfs-to-_node_post.patch b/patches/bbb_overlays/0035-of-rename-_node_sysfs-to-_node_post.patch index 7bc65d807a2f4f57517fea6f15314d5abac7d853..e13dce157c5261596463503e7821050f3a9d24cd 100644 --- a/patches/bbb_overlays/0035-of-rename-_node_sysfs-to-_node_post.patch +++ b/patches/bbb_overlays/0035-of-rename-_node_sysfs-to-_node_post.patch @@ -1,7 +1,11 @@ -From 4225054e76c8db4bbc3ddc21f8fca7f89cf99425 Mon Sep 17 00:00:00 2001 +From db2f3d8e0214d643db0be330244ebfe4aafa9983 Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou <pantelis.antoniou@konsulko.com> Date: Wed, 14 Oct 2015 13:20:54 +0300 -Subject: [PATCH 35/38] of: rename *_node_sysfs to _node_post +Subject: [PATCH 35/41] of: rename *_node_sysfs to _node_post + +Renames the *_node_sysfs methods to _node_post which is more accurate +when more work takes place besides sysfs tweaking (as in with +phandle hash management). Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com> --- @@ -12,7 +16,7 @@ Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com> 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/of/base.c b/drivers/of/base.c -index 9bbca56..20bbc2f 100644 +index ccd2ef3..de6925e 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -156,7 +156,7 @@ int __of_add_property_sysfs(struct device_node *np, struct property *pp) @@ -34,7 +38,7 @@ index 9bbca56..20bbc2f 100644 /* Symlink in /proc as required by userspace ABI */ diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c -index eca22b4..fcbcd38 100644 +index 4cef6eb..bf6ecd8 100644 --- a/drivers/of/dynamic.c +++ b/drivers/of/dynamic.c @@ -41,7 +41,7 @@ void of_node_put(struct device_node *node) @@ -64,7 +68,7 @@ index eca22b4..fcbcd38 100644 mutex_unlock(&of_mutex); of_reconfig_notify(OF_RECONFIG_DETACH_NODE, &rd); -@@ -623,10 +623,10 @@ static int __of_changeset_entry_apply(struct of_changeset_entry *ce) +@@ -629,10 +629,10 @@ static int __of_changeset_entry_apply(struct of_changeset_entry *ce) switch (ce->action) { case OF_RECONFIG_ATTACH_NODE: @@ -94,10 +98,10 @@ index 092cba7..10b0342 100644 /* iterators for transactions, used for overlays */ /* forward iterator */ diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c -index 2bfe0bc..0c5994f 100644 +index 94d5dfe..04dfaac 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c -@@ -917,7 +917,7 @@ static int attach_node_and_children(struct device_node *np) +@@ -930,7 +930,7 @@ static int attach_node_and_children(struct device_node *np) of_node_clear_flag(np, OF_DETACHED); raw_spin_unlock_irqrestore(&devtree_lock, flags); @@ -106,7 +110,7 @@ index 2bfe0bc..0c5994f 100644 mutex_unlock(&of_mutex); while (child) { -@@ -975,7 +975,7 @@ static int __init unittest_data_add(void) +@@ -988,7 +988,7 @@ static int __init unittest_data_add(void) if (!of_root) { of_root = unittest_data_node; for_each_of_allnodes(np) @@ -116,5 +120,5 @@ index 2bfe0bc..0c5994f 100644 of_chosen = of_find_node_by_path("/chosen"); return 0; -- -2.8.0.rc3 +2.8.1 diff --git a/patches/bbb_overlays/0036-of-Support-hashtable-lookups-for-phandles.patch b/patches/bbb_overlays/0036-of-Support-hashtable-lookups-for-phandles.patch index 516dce9ffde6b7cbd85d608e37772434854c0921..12bae358a11bb84363137311da53a8689f6ae793 100644 --- a/patches/bbb_overlays/0036-of-Support-hashtable-lookups-for-phandles.patch +++ b/patches/bbb_overlays/0036-of-Support-hashtable-lookups-for-phandles.patch @@ -1,18 +1,22 @@ -From f10143bbcaeac1f6e2bf0676e9c93b8cf18096f7 Mon Sep 17 00:00:00 2001 +From 0a97e951f23db39ae794d1c89ff682e7547ed6ff Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou <pantelis.antoniou@konsulko.com> Date: Wed, 14 Oct 2015 13:29:23 +0300 -Subject: [PATCH 36/38] of: Support hashtable lookups for phandles +Subject: [PATCH 36/41] of: Support hashtable lookups for phandles + +When a device tree contains a lot of phandles, resolving one +takes time because the original method uses a search against +all nodes (not just the ones with phandles). Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com> --- - drivers/of/base.c | 35 ++++++++++++++++++++++++++++++++--- + drivers/of/base.c | 41 ++++++++++++++++++++++++++++++++++++++--- drivers/of/dynamic.c | 8 ++++++++ - drivers/of/of_private.h | 31 +++++++++++++++++++++++++++++++ + drivers/of/of_private.h | 33 +++++++++++++++++++++++++++++++++ include/linux/of.h | 2 ++ - 4 files changed, 73 insertions(+), 3 deletions(-) + 4 files changed, 81 insertions(+), 3 deletions(-) diff --git a/drivers/of/base.c b/drivers/of/base.c -index 20bbc2f..770cb95 100644 +index de6925e..ecc7914 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -27,6 +27,7 @@ @@ -23,7 +27,7 @@ index 20bbc2f..770cb95 100644 #include "of_private.h" -@@ -41,6 +42,16 @@ static const char *of_stdout_options; +@@ -41,6 +42,18 @@ static const char *of_stdout_options; struct kset *of_kset; @@ -34,13 +38,15 @@ index 20bbc2f..770cb95 100644 + .automatic_shrinking = true, +}; + -+struct rhashtable of_phandle_ht; -+bool of_phandle_ht_initialized; ++struct rhashtable *of_phandle_ht; ++ ++/* default is false */ ++bool of_phandle_ht_is_disabled; + /* * Used to protect the of_aliases, to hold off addition of nodes to sysfs. * This mutex must be held whenever modifications are being made to the -@@ -162,6 +173,12 @@ int __of_attach_node_post(struct device_node *np) +@@ -162,6 +175,12 @@ int __of_attach_node_post(struct device_node *np) struct property *pp; int rc; @@ -53,29 +59,33 @@ index 20bbc2f..770cb95 100644 if (!IS_ENABLED(CONFIG_SYSFS)) return 0; -@@ -194,6 +211,13 @@ void __init of_core_init(void) +@@ -194,6 +213,17 @@ void __init of_core_init(void) struct device_node *np; int ret; -+ ret = rhashtable_init(&of_phandle_ht, &of_phandle_ht_params); ++ of_phandle_ht = kzalloc(sizeof(*of_phandle_ht), GFP_KERNEL); ++ if (!of_phandle_ht) { ++ pr_warn("devicetree: Failed to allocate hashtable\n"); ++ return; ++ } ++ ret = rhashtable_init(of_phandle_ht, &of_phandle_ht_params); + if (ret) { + pr_warn("devicetree: Failed to initialize hashtable\n"); + return; + } -+ of_phandle_ht_initialized = 1; + /* Create the kset, and register existing nodes */ mutex_lock(&of_mutex); of_kset = kset_create_and_add("devicetree", NULL, firmware_kobj); -@@ -1073,9 +1097,14 @@ struct device_node *of_find_node_by_phandle(phandle handle) +@@ -1074,9 +1104,14 @@ struct device_node *of_find_node_by_phandle(phandle handle) return NULL; raw_spin_lock_irqsave(&devtree_lock, flags); - for_each_of_allnodes(np) - if (np->phandle == handle) - break; -+ /* when we're ready use the hash table */ -+ if (of_phandle_ht_available() && !in_interrupt()) ++ /* when we're ready use the hash table (and not disabled) */ ++ if (of_phandle_ht_available() && !of_phandle_ht_is_disabled) + np = of_phandle_ht_lookup(handle); + else { /* fallback */ + for_each_of_allnodes(np) @@ -86,7 +96,7 @@ index 20bbc2f..770cb95 100644 raw_spin_unlock_irqrestore(&devtree_lock, flags); return np; diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c -index fcbcd38..24af842 100644 +index bf6ecd8..2bfaeaa 100644 --- a/drivers/of/dynamic.c +++ b/drivers/of/dynamic.c @@ -11,6 +11,7 @@ @@ -112,27 +122,29 @@ index fcbcd38..24af842 100644 if (!IS_ENABLED(CONFIG_SYSFS)) return; diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h -index 10b0342..88b3b8f 100644 +index 10b0342..386ae71 100644 --- a/drivers/of/of_private.h +++ b/drivers/of/of_private.h -@@ -101,4 +101,35 @@ static inline int of_overlay_init(void) +@@ -101,4 +101,37 @@ static inline int of_overlay_init(void) } #endif +extern const struct rhashtable_params of_phandle_ht_params; -+extern struct rhashtable of_phandle_ht; -+extern bool of_phandle_ht_initialized; ++extern struct rhashtable *of_phandle_ht; ++ ++/* for unittest use */ ++extern bool of_phandle_ht_is_disabled; + +static inline bool of_phandle_ht_available(void) +{ -+ return of_phandle_ht_initialized; ++ return of_phandle_ht != NULL; +} + +static inline int of_phandle_ht_insert(struct device_node *np) +{ + if (!np || !np->phandle) + return 0; -+ return rhashtable_insert_fast(&of_phandle_ht, ++ return rhashtable_insert_fast(of_phandle_ht, + &np->ht_node, of_phandle_ht_params); +} + @@ -140,19 +152,19 @@ index 10b0342..88b3b8f 100644 +{ + if (!np || !np->phandle) + return 0; -+ return rhashtable_remove_fast(&of_phandle_ht, ++ return rhashtable_remove_fast(of_phandle_ht, + &np->ht_node, of_phandle_ht_params); +} + +static inline struct device_node *of_phandle_ht_lookup(phandle handle) +{ -+ return rhashtable_lookup_fast(&of_phandle_ht, ++ return rhashtable_lookup_fast(of_phandle_ht, + &handle, of_phandle_ht_params); +} + #endif /* _LINUX_OF_PRIVATE_H */ diff --git a/include/linux/of.h b/include/linux/of.h -index da4eae5..8d3f423 100644 +index f835026..aa0d28d 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -25,6 +25,7 @@ @@ -172,5 +184,5 @@ index da4eae5..8d3f423 100644 struct property *properties; struct property *deadprops; /* removed properties */ -- -2.8.0.rc3 +2.8.1 diff --git a/patches/bbb_overlays/0037-of-unittest-hashed-phandles-unitest.patch b/patches/bbb_overlays/0037-of-unittest-hashed-phandles-unitest.patch new file mode 100644 index 0000000000000000000000000000000000000000..4fcfac2ec9d846344636a0d47ebf4b6beedb1613 --- /dev/null +++ b/patches/bbb_overlays/0037-of-unittest-hashed-phandles-unitest.patch @@ -0,0 +1,119 @@ +From f579548c6f24c0ee03c39348443f5046d7aa7094 Mon Sep 17 00:00:00 2001 +From: Pantelis Antoniou <pantelis.antoniou@konsulko.com> +Date: Mon, 16 May 2016 17:36:59 +0300 +Subject: [PATCH 37/41] of: unittest: hashed phandles unitest + +Add a benchmarking hashed phandles unittest which report what kind +of speed up we get switching to hashed phandle lookups. + + ### dt-test ### the hash method is 8.2 times faster than the original + +On the beaglebone we perform about 1877 phandle lookups until that +point in the unittest. Each non-hashed lookup takes about 23us when +the cash is hot, while the hash lookup takes about 3us. + +For those 1877 lookup we get a speedup in the boot sequence of +1877 * (23 - 3) = 37.5ms, which is not spectacular but there's no +point in wasting cycles and energy. + +Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com> +--- + drivers/of/unittest.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 68 insertions(+) + +diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c +index 04dfaac..86de457 100644 +--- a/drivers/of/unittest.c ++++ b/drivers/of/unittest.c +@@ -24,6 +24,9 @@ + + #include <linux/bitops.h> + ++#include <linux/timekeeping.h> ++#include <linux/random.h> ++ + #include "of_private.h" + + static struct unittest_results { +@@ -2253,6 +2256,70 @@ out: + static inline void __init of_unittest_overlay(void) { } + #endif + ++#define PHANDLE_LOOKUPS 1000 ++ ++static void __init of_unittest_phandle_hash(void) ++{ ++ struct device_node *node; ++ phandle max_phandle; ++ u32 ph; ++ unsigned long flags; ++ int i, j, total; ++ ktime_t start, end; ++ s64 dur[2]; ++ int dec, frac; ++ ++ /* test only available when hashing is available */ ++ if (!of_phandle_ht_available()) { ++ pr_warn("phandle hash test requires hash to be initialized\n"); ++ return; ++ } ++ ++ /* find the maximum phandle of the tree */ ++ raw_spin_lock_irqsave(&devtree_lock, flags); ++ max_phandle = 0; ++ total = 0; ++ for_each_of_allnodes(node) { ++ if (node->phandle != (phandle)-1U && ++ node->phandle > max_phandle) ++ max_phandle = node->phandle; ++ total++; ++ } ++ raw_spin_unlock_irqrestore(&devtree_lock, flags); ++ max_phandle++; ++ ++ pr_debug("phandle: max-phandle #%u, #%d total nodes\n", ++ (u32)max_phandle, total); ++ ++ /* perform random lookups using the hash */ ++ for (j = 0; j < 2; j++) { ++ ++ /* disabled for pass #0, enabled for pass #1 */ ++ of_phandle_ht_is_disabled = j == 0; ++ ++ start = ktime_get_raw(); ++ for (i = 0; i < PHANDLE_LOOKUPS; i++) { ++ ph = prandom_u32() % max_phandle; ++ node = of_find_node_by_phandle(ph); ++ of_node_put(node); ++ } ++ end = ktime_get_raw(); ++ ++ dur[j] = ktime_to_us(end) - ktime_to_us(start); ++ pr_debug("#%d lookups in %lld us (%s)\n", ++ PHANDLE_LOOKUPS, dur[j], ++ j == 0 ? "original" : "hashed"); ++ } ++ ++ unittest(dur[0] > dur[1], "Non hashing phandles are faster!?"); ++ ++ dec = (int)div64_s64(dur[0] * 10 + 5, dur[1]); ++ frac = dec % 10; ++ dec /= 10; ++ pr_info("the hash method is %d.%d times faster than the original\n", ++ dec, frac); ++} ++ + static int __init of_unittest(void) + { + struct device_node *np; +@@ -2287,6 +2354,7 @@ static int __init of_unittest(void) + of_unittest_match_node(); + of_unittest_platform_populate(); + of_unittest_overlay(); ++ of_unittest_phandle_hash(); + + /* Double check linkage after removing testcase data */ + of_unittest_check_tree_linkage(); +-- +2.8.1 + diff --git a/patches/bbb_overlays/0037-of-overlay-Pick-up-label-symbols-from-overlays.patch b/patches/bbb_overlays/0038-of-overlay-Pick-up-label-symbols-from-overlays.patch similarity index 62% rename from patches/bbb_overlays/0037-of-overlay-Pick-up-label-symbols-from-overlays.patch rename to patches/bbb_overlays/0038-of-overlay-Pick-up-label-symbols-from-overlays.patch index 8c3914169732d8c4f70099efea7c6fea9871bdf7..389a3813d8097fb53a80732bb2d650a3d28a2e80 100644 --- a/patches/bbb_overlays/0037-of-overlay-Pick-up-label-symbols-from-overlays.patch +++ b/patches/bbb_overlays/0038-of-overlay-Pick-up-label-symbols-from-overlays.patch @@ -1,7 +1,7 @@ -From f223eab94743097e460a6cb5df98dd7e0537e8aa Mon Sep 17 00:00:00 2001 +From c1858b02fe89d0f8ccfd0bc9c685ff76bd8ced50 Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou <pantelis.antoniou@konsulko.com> Date: Tue, 22 Mar 2016 23:16:40 +0200 -Subject: [PATCH 37/38] of: overlay: Pick up label symbols from overlays. +Subject: [PATCH 38/41] of: overlay: Pick up label symbols from overlays. Insert overlay symbols to the base tree when applied. This makes it possible to apply an overlay that references a label @@ -9,14 +9,22 @@ that a previously inserted overlay had. Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com> --- - drivers/of/overlay.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 102 insertions(+) + drivers/of/overlay.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 93 insertions(+) diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c -index a274d65..a7956a2 100644 +index 49bdcba..c6df3ff 100644 --- a/drivers/of/overlay.c +++ b/drivers/of/overlay.c -@@ -514,6 +514,101 @@ static int of_free_overlay_info(struct of_overlay *ov) +@@ -8,6 +8,7 @@ + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + */ ++ + #undef DEBUG + #include <linux/kernel.h> + #include <linux/module.h> +@@ -470,6 +471,91 @@ static int of_free_overlay_info(struct of_overlay *ov) return 0; } @@ -32,24 +40,15 @@ index a274d65..a7956a2 100644 + char *new_path; + int i, len, err; + -+ /* this may fail (if no fixups are required) */ ++ /* both may fail (if no fixups are required) */ + root_sym = of_find_node_by_path("/__symbols__"); ++ child = of_get_child_by_name(tree, "__symbols__"); + -+ /* do nothing if no root symbols */ -+ if (!root_sym) -+ return 0; ++ err = 0; ++ /* do nothing if either is NULL */ ++ if (!root_sym || !child) ++ goto out; + -+ /* locate the symbols & fixups nodes on resolve */ -+ for_each_child_of_node(tree, child) { -+ if (of_node_cmp(child->name, "__symbols__") == 0) -+ goto found; -+ } -+ /* no symbols, no problem */ -+ of_node_put(root_sym); -+ return 0; -+ -+found: -+ err = -EINVAL; + for_each_property_of_node(child, prop) { + + /* skip properties added automatically */ @@ -59,23 +58,19 @@ index a274d65..a7956a2 100644 + err = of_property_read_string(child, + prop->name, &path); + if (err != 0) { -+ pr_err("%s: Could not find symbol '%s'\n", -+ __func__, prop->name); ++ pr_err("Could not find symbol '%s'\n", prop->name); + continue; + } + -+ + /* now find fragment index */ + s = path; + + /* compare paths to find fragment index */ -+ ovinfo = NULL; -+ len = -1; -+ for (i = 0; i < ov->count; i++) { ++ for (i = 0, ovinfo = NULL, len = -1; i < ov->count; i++) { + ovinfo = &ov->ovinfo_tab[i]; + -+ pr_debug("%s: #%d: overlay->name=%s target->name=%s\n", -+ __func__, i, ovinfo->overlay->full_name, ++ pr_debug("#%d: overlay->name=%s target->name=%s\n", ++ i, ovinfo->overlay->full_name, + ovinfo->target->full_name); + + len = strlen(ovinfo->overlay->full_name); @@ -87,14 +82,15 @@ index a274d65..a7956a2 100644 + if (i >= ov->count) + continue; + -+ pr_debug("%s: found target at #%d\n", __func__, i); ++ pr_debug("found target at #%d\n", i); + new_path = kasprintf(GFP_KERNEL, "%s%s", + ovinfo->target->full_name, + path + len); + if (!new_path) { -+ pr_err("%s: Failed to allocate propname for \"%s\"\n", -+ __func__, prop->name); -+ continue; ++ pr_err("Failed to allocate propname for \"%s\"\n", ++ prop->name); ++ err = -ENOMEM; ++ break; + } + + err = of_changeset_add_property_string(&ov->cset, root_sym, @@ -104,21 +100,23 @@ index a274d65..a7956a2 100644 + kfree(new_path); + + if (err) { -+ pr_err("%s: Failed to add property for \"%s\"\n", -+ __func__, prop->name); ++ pr_err("Failed to add property for \"%s\"\n", ++ prop->name); ++ break; + } + } + ++out: + of_node_put(child); + of_node_put(root_sym); + -+ return 0; ++ return err; +} + static LIST_HEAD(ov_list); static DEFINE_IDR(ov_idr); -@@ -642,6 +737,13 @@ static int __of_overlay_create(struct device_node *tree, +@@ -591,6 +677,13 @@ static int __of_overlay_create(struct device_node *tree, goto err_abort_trans; } @@ -133,5 +131,5 @@ index a274d65..a7956a2 100644 err = __of_changeset_apply(&ov->cset); if (err) { -- -2.8.0.rc3 +2.8.1 diff --git a/patches/bbb_overlays/0039-of-overlay-Add-pr_fmt-for-clarity.patch b/patches/bbb_overlays/0039-of-overlay-Add-pr_fmt-for-clarity.patch new file mode 100644 index 0000000000000000000000000000000000000000..766cb6d285c7d56ceef0eb2914d6ba40f7d9d1f5 --- /dev/null +++ b/patches/bbb_overlays/0039-of-overlay-Add-pr_fmt-for-clarity.patch @@ -0,0 +1,225 @@ +From 3bdf917bb51fd7c42c95cbbc7c8aa5fb9e42ba1d Mon Sep 17 00:00:00 2001 +From: Pantelis Antoniou <pantelis.antoniou@konsulko.com> +Date: Mon, 16 May 2016 15:18:28 +0300 +Subject: [PATCH 39/41] of: overlay: Add pr_fmt for clarity + +There are a bunch of pr_.*() messages in the file, use a common pr_fmt +for making them a little bit shorter. + +Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com> +--- + drivers/of/overlay.c | 73 ++++++++++++++++++++++++---------------------------- + 1 file changed, 33 insertions(+), 40 deletions(-) + +diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c +index c6df3ff..6d203c4 100644 +--- a/drivers/of/overlay.c ++++ b/drivers/of/overlay.c +@@ -9,6 +9,8 @@ + * version 2 as published by the Free Software Foundation. + */ + ++#define pr_fmt(fmt) "overlay: %s() " fmt, __func__ ++ + #undef DEBUG + #include <linux/kernel.h> + #include <linux/module.h> +@@ -175,8 +177,8 @@ static int of_overlay_apply_one(struct of_overlay *ov, + for_each_property_of_node(overlay, prop) { + ret = of_overlay_apply_single_property(ov, target, prop); + if (ret) { +- pr_err("%s: Failed to apply prop @%s/%s\n", +- __func__, target->full_name, prop->name); ++ pr_err("Failed to apply prop @%s/%s\n", ++ target->full_name, prop->name); + return ret; + } + } +@@ -184,9 +186,8 @@ static int of_overlay_apply_one(struct of_overlay *ov, + for_each_child_of_node(overlay, child) { + ret = of_overlay_apply_single_device_node(ov, target, child); + if (ret != 0) { +- pr_err("%s: Failed to apply single node @%s/%s\n", +- __func__, target->full_name, +- child->name); ++ pr_err("Failed to apply single node @%s/%s\n", ++ target->full_name, child->name); + of_node_put(child); + return ret; + } +@@ -214,8 +215,8 @@ static int of_overlay_apply(struct of_overlay *ov) + + err = of_overlay_apply_one(ov, ovinfo->target, ovinfo->overlay); + if (err != 0) { +- pr_err("%s: overlay failed '%s'\n", +- __func__, ovinfo->target->full_name); ++ pr_err("overlay failed '%s'\n", ++ ovinfo->target->full_name); + return err; + } + } +@@ -244,8 +245,7 @@ static struct device_node *find_target_node(struct of_overlay *ov, + if (ret == 0) { + target = of_find_node_by_phandle(val); + if (!target) { +- pr_err("%s: Could not find target phandle 0x%x\n", +- __func__, val); ++ pr_err("Could not find target phandle 0x%x\n", val); + return NULL; + } + goto check_root; +@@ -259,8 +259,8 @@ static struct device_node *find_target_node(struct of_overlay *ov, + if (!ov->target_root) { + target = of_find_node_by_path(path); + if (!target) +- pr_err("%s: Could not find target path \"%s\"\n", +- __func__, path); ++ pr_err("Could not find target path \"%s\"\n", ++ path); + return target; + } + +@@ -273,8 +273,7 @@ static struct device_node *find_target_node(struct of_overlay *ov, + of_node_full_name(ov->target_root), + *path ? "/" : "", path); + if (!newpath) { +- pr_err("%s: Could not allocate \"%s%s%s\"\n", +- __func__, ++ pr_err("Could not allocate \"%s%s%s\"\n", + of_node_full_name(ov->target_root), + *path ? "/" : "", path); + return NULL; +@@ -288,8 +287,7 @@ static struct device_node *find_target_node(struct of_overlay *ov, + /* target is an alias, need to check */ + target = of_find_node_by_path(path); + if (!target) { +- pr_err("%s: Could not find alias \"%s\"\n", +- __func__, path); ++ pr_err("Could not find alias \"%s\"\n", path); + return NULL; + } + goto check_root; +@@ -306,8 +304,8 @@ check_root: + if (np == ov->target_root) + return target; + } +- pr_err("%s: target \"%s\" not under target_root \"%s\"\n", +- __func__, of_node_full_name(target), ++ pr_err("target \"%s\" not under target_root \"%s\"\n", ++ of_node_full_name(target), + of_node_full_name(ov->target_root)); + /* target is not under target_root */ + of_node_put(target); +@@ -654,8 +652,7 @@ static int __of_overlay_create(struct device_node *tree, + + id = idr_alloc(&ov_idr, ov, 0, 0, GFP_KERNEL); + if (id < 0) { +- pr_err("%s: idr_alloc() failed for tree@%s\n", +- __func__, tree->full_name); ++ pr_err("idr_alloc() failed for tree@%s\n", tree->full_name); + err = id; + goto err_destroy_trans; + } +@@ -664,46 +661,46 @@ static int __of_overlay_create(struct device_node *tree, + /* build the overlay info structures */ + err = of_build_overlay_info(ov, tree); + if (err) { +- pr_err("%s: of_build_overlay_info() failed for tree@%s\n", +- __func__, tree->full_name); ++ pr_err("of_build_overlay_info() failed for tree@%s\n", ++ tree->full_name); + goto err_free_idr; + } + + /* apply the overlay */ + err = of_overlay_apply(ov); + if (err) { +- pr_err("%s: of_overlay_apply() failed for tree@%s\n", +- __func__, tree->full_name); ++ pr_err("of_overlay_apply() failed for tree@%s\n", ++ tree->full_name); + goto err_abort_trans; + } + + err = of_overlay_add_symbols(tree, ov); + if (err) { +- pr_err("%s: of_overlay_add_symbols() failed for tree@%s\n", +- __func__, tree->full_name); ++ pr_err("of_overlay_add_symbols() failed for tree@%s\n", ++ tree->full_name); + goto err_abort_trans; + } + + /* apply the changeset */ + err = __of_changeset_apply(&ov->cset); + if (err) { +- pr_err("%s: __of_changeset_apply() failed for tree@%s\n", +- __func__, tree->full_name); ++ pr_err("__of_changeset_apply() failed for tree@%s\n", ++ tree->full_name); + goto err_revert_overlay; + } + + ov->kobj.kset = ov_kset; + err = kobject_add(&ov->kobj, NULL, "%d", id); + if (err != 0) { +- pr_err("%s: kobject_add() failed for tree@%s\n", +- __func__, tree->full_name); ++ pr_err("kobject_add() failed for tree@%s\n", ++ tree->full_name); + goto err_cancel_overlay; + } + + err = sysfs_create_groups(&ov->kobj, ov->attr_groups); + if (err != 0) { +- pr_err("%s: sysfs_create_groups() failed for tree@%s\n", +- __func__, tree->full_name); ++ pr_err("sysfs_create_groups() failed for tree@%s\n", ++ tree->full_name); + goto err_remove_kobj; + } + +@@ -818,9 +815,8 @@ static int overlay_is_topmost(struct of_overlay *ov, struct device_node *dn) + /* check against each subtree affected by this overlay */ + list_for_each_entry(ce, &ovt->cset.entries, node) { + if (overlay_subtree_check(ce->np, dn)) { +- pr_err("%s: #%d clashes #%d @%s\n", +- __func__, ov->id, ovt->id, +- dn->full_name); ++ pr_err("#%d clashes #%d @%s\n", ++ ov->id, ovt->id, dn->full_name); + return 0; + } + } +@@ -846,8 +842,7 @@ static int overlay_removal_is_ok(struct of_overlay *ov) + + list_for_each_entry(ce, &ov->cset.entries, node) { + if (!overlay_is_topmost(ov, ce->np)) { +- pr_err("%s: overlay #%d is not topmost\n", +- __func__, ov->id); ++ pr_err("overlay #%d is not topmost\n", ov->id); + return 0; + } + } +@@ -873,16 +868,14 @@ int of_overlay_destroy(int id) + ov = idr_find(&ov_idr, id); + if (ov == NULL) { + err = -ENODEV; +- pr_err("%s: Could not find overlay #%d\n", +- __func__, id); ++ pr_err("Could not find overlay #%d\n", id); + goto out; + } + + /* check whether the overlay is safe to remove */ + if (!overlay_removal_is_ok(ov)) { + err = -EBUSY; +- pr_err("%s: removal check failed for overlay #%d\n", +- __func__, id); ++ pr_err("removal check failed for overlay #%d\n", id); + goto out; + } + +-- +2.8.1 + diff --git a/patches/bbb_overlays/0038-connector-wip.patch b/patches/bbb_overlays/0040-of-Portable-Device-Tree-connector.patch similarity index 75% rename from patches/bbb_overlays/0038-connector-wip.patch rename to patches/bbb_overlays/0040-of-Portable-Device-Tree-connector.patch index d92d14c70b4ab61e9c25c22e1a79ccb8c493ac02..18d04084250bff4e1109ef3ebe0601e4da32bdd3 100644 --- a/patches/bbb_overlays/0038-connector-wip.patch +++ b/patches/bbb_overlays/0040-of-Portable-Device-Tree-connector.patch @@ -1,27 +1,260 @@ -From 0c3710cae0a260d97f18ac4fd51d717795335048 Mon Sep 17 00:00:00 2001 +From 7a9b12138535ce196b1a4217bd3537aafb233188 Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou <pantelis.antoniou@konsulko.com> Date: Wed, 16 Sep 2015 13:02:34 +0300 -Subject: [PATCH 38/38] connector wip +Subject: [PATCH 40/41] of: Portable Device Tree connector +Introducing the portable device tree based connector. + +It is a method of describing an expansion connector in such a way +that the hardware definition for devices present on the connector +are portable between any board that has a hardware compatible connector. + +The connector will maintain the mapping of resources to +actual SoC level resources. + +Take for example a simple four pin connector (FPC) which can +be configured as a serial port, an i2c bus or +general purpose gpios. + +In connector terms the connector is defined as follows: + +FPC: fpc { + compatible = "extcon,dt-con"; + status = "okay"; + + connector { + #address-cells = <1>; + #size-cells = <0>; + + P0: p0 { + reg = <0>; + gpio = <&gpio0 10>; + }; + + P1: p1 { + reg = <1>; + gpio = <&gpio1 8>; + }; + + P2: p2 { + reg = <2>; + gpio = <&gpio0 4>; + }; + + P3: p3 { + reg = <3>; + gpio = <&gpio2 0>; + }; + }; + +}; + +The 'reg' property contains the address of the connector pin; it's the +pin# from the schematic usually. If the connector contains more than one +physical connectors the address may be of the form +< connector-nr pin-nr> + +The gpio property is present when that pin can be configured as a gpio +and points to the real board level gpio chip and gpio number. + +Note that the connector node may contain arbitrary properties that +may be used for informational purposes. I.e. a property may be the SoC +pad name that the connector pin is routed from. + +&FPC { + functions { + gpio { + gpio-base = <256>; + }; + + uart { + params { + #param-cells = <2>; + generate-pinctrl; + + txd { + required; + connector-pin; + }; + + rxd { + required; + connector-pin; + }; + + }; + + uart0 { + device = <&uart0>; + mux@0 { + txd = <&P0 &uart0_txd>; + rxd = <&P1 &uart0_rxd_mux0>, + <&P3 &uart0_rxd_mux1>; + }; + }; + uart1 { + device = <&uart1>; + mux@0 { + txd = <&P2 &uart1_txd>; + rxd = <&P3 &uart1_rxd>; + }; + }; + }; + + i2c { + params { + #param-cells = <2>; + copy-subdevices; + generate-pinctrl; + + scl { + required; + connector-pin; + }; + + sda { + required; + connector-pin; + }; + + clock-frequency { + copy; + }; + }; + i2c0 { + device = <&i2c2>; + mux@0 { + scl = <&P1 &i2c2_scl>; + sda = <&P2 &i2c2_sda>; + }; + }; + }; + }; +}; + +For each function that the connector provides a functions nodes +containing the possible configurations. + +For this connector, all four pins can be GPIOs. +Two uarts are routed to the connector. +uart0 with txd at P0 and rxd at either P1 or P3 via a mux option +uart1 with txd at P2 and rxd at P3. +The i2c2 device is routed with scl at P1 and sda at P2. + +The parameters node for each function contains a list of the +supported parameters for this function. + +For the uart there are two required parameters txd & rxd and the +are defined as connector-pin type. + +For the i2c function the two required parameters are scl & sda +while the clock-frequency property will be copied verbatim to +the real hardware i2c device when instantiated. + +&FPC { + plugged { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + + UART { + compatible = "dtcon-uart"; + status = "okay"; + txd = <0>; + rxd = <1>; + }; + + LEDS { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + + GPIO_LEDS: gpio_leds { + compatible = "dtcon-gpio"; + status = "okay"; + + gpio-controller; + #gpio-cells = <2>; + + pin-list = <2>, + <3>; + }; + + LEDS { + compatible = "gpio-leds"; + status = "okay"; + + jp0 { + label = "jp0"; + gpios = <&GPIO_LEDS 0 + GPIO_ACTIVE_HIGH>; + }; + jp1 { + label = "jp1"; + gpios = <&GPIO_LEDS 1 + GPIO_ACTIVE_HIGH>; + }; + }; + + LIGHT_I2C { + compatible = "dtcon-i2c"; + status = "disabled"; + + scl = <1>; + sda = <2>; + + #address-cells = <1>; + #size-cells = <0>; + + clock-frequency = <100000>; + + /* Ambient light sensor */ + tsl2550@39 { + compatible = "tsl,tsl2550"; + reg = <0x39>; + status = "okay"; + }; + }; + }; + }; +}; + +Any activated device nodes in the plugged node will be instantiated. + +This example displays two enabled devices and one disabled. + +The UART device selects the uart function at pins #0 & #1. The connector +will locate the backend device (uart0) select the right pinctrl by +injecting pinctrl-0 and pinctrl-names properties that are build +dynamically and activates the uart0 device. + +The LEDS simple-bus defines a gpio chip forwarder at the two pins (2 & 3) +and creates a LED device using it. + +The LIGHT_I2C device is disabled, but if enabled it will activate the +i2c2 real backend device while copying the clock-frequency property and +the ambient light sensor device. + +Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com> --- - arch/arm/boot/dts/am335x-bone-common.dtsi | 1703 +++++++++++++++++++++++++++++ + arch/arm/boot/dts/am335x-bone-common.dtsi | 1759 +++++++++++++++++++++++++++++ drivers/extcon/Kconfig | 20 + drivers/extcon/Makefile | 3 + - drivers/extcon/extcon-dt-con-gpio.c | 672 ++++++++++++ - drivers/extcon/extcon-dt-con-uart.c | 66 ++ - drivers/extcon/extcon-dt-con.c | 485 ++++++++ - drivers/extcon/extcon-dt-con.h | 85 ++ - 7 files changed, 3034 insertions(+) + drivers/extcon/extcon-dt-con-gpio.c | 510 +++++++++ + drivers/extcon/extcon-dt-con-proxy.c | 480 ++++++++ + drivers/extcon/extcon-dt-con.c | 491 ++++++++ + drivers/extcon/extcon-dt-con.h | 93 ++ + 7 files changed, 3356 insertions(+) create mode 100644 drivers/extcon/extcon-dt-con-gpio.c - create mode 100644 drivers/extcon/extcon-dt-con-uart.c + create mode 100644 drivers/extcon/extcon-dt-con-proxy.c create mode 100644 drivers/extcon/extcon-dt-con.c create mode 100644 drivers/extcon/extcon-dt-con.h diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi -index a9e9eb1..e9b9ee0 100644 +index ce66713..f652e55 100644 --- a/arch/arm/boot/dts/am335x-bone-common.dtsi +++ b/arch/arm/boot/dts/am335x-bone-common.dtsi -@@ -421,4 +421,1707 @@ +@@ -417,4 +417,1763 @@ }; }; }; @@ -948,7 +1181,7 @@ index a9e9eb1..e9b9ee0 100644 + +/* the device tree based connector */ +/ { -+ dtcon { ++ P8_P9 { + compatible = "extcon,dt-con"; + status = "okay"; + @@ -963,264 +1196,308 @@ index a9e9eb1..e9b9ee0 100644 + modes = "gpmc_ad6", "mmc1_dat6", "", "", "", "", "", "gpio1_6"; + + pinmuxes = <&gpio1_6_in &gpio1_6_out>; ++ gpio = <&gpio1 6>; + }; + GPIO1_7: GPIO1_7 { + reg = <8 4>; + pad = "T9"; + modes = "gpmc_ad7", "mmc1_dat7", "", "", "", "", "", "gpio1_7"; + pinmuxes = <&gpio1_7_in &gpio1_7_out>; ++ gpio = <&gpio1 7>; + }; + GPIO1_2: GPIO1_2 { + reg = <8 5>; + pad = "R8"; + modes = "gpmc_ad2", "mmc1_dat2", "", "", "", "", "", "gpio1_2"; + pinmuxes = <&gpio1_2_in &gpio1_2_out>; ++ gpio = <&gpio1 2>; + }; + GPIO1_3: GPIO1_3 { + reg = <8 6>; + pad = "T8"; + modes = "gpmc_ad3", "mmc1_dat3", "", "", "", "", "", "gpio1_3"; + pinmuxes = <&gpio1_3_in &gpio1_3_out>; ++ gpio = <&gpio1 3>; + }; + TIMER4: TIMER4 { + reg = <8 7>; + pad = "R7"; + modes = "gpmc_advn_ale", "", "timer4", "", "", "", "", "gpio2_2"; + pinmuxes = <&gpio2_2_in &gpio2_2_out>; ++ gpio = <&gpio2 2>; + }; + TIMER7: TIMER7 { + reg = <8 8>; + pad = "T7"; + modes = "gpmc_oen_ren", "", "timer7", "", "", "", "", "gpio2_3"; + pinmuxes = <&gpio2_3_in &gpio2_3_out>; ++ gpio = <&gpio2 3>; + }; + TIMER5: TIMER5 { + reg = <8 9>; + pad = "T6"; + modes = "gpmc_be0n_cle", "", "timer5", "", "", "", "", "gpio2_5"; + pinmuxes = <&gpio2_5_in &gpio2_5_out>; ++ gpio = <&gpio2 5>; + }; + TIMER6: TIMER6 { + reg = <8 10>; + pad = "U6"; + modes = "gpmc_wen", "", "timer6", "", "", "", "", "gpio2_4"; + pinmuxes = <&gpio2_4_in &gpio2_4_out>; ++ gpio = <&gpio2 4>; + }; + GPIO1_13: GPIO1_13 { + reg = <8 11>; + pad = "R12"; + modes = "gpmc_ad13", "lcd_data18", "mmc1_dat5", "mmc2_dat1", "eqep2b_in", "", "", "gpio1_13"; + pinmuxes = <&gpio1_13_in &gpio1_13_out>; ++ gpio = <&gpio1 13>; + }; + GPIO1_12: GPIO1_12 { + reg = <8 12>; + pad = "T12"; + modes = "gpmc_ad12", "lcd_data19", "mmc1_dat4", "mmc2_dat0", "eqep2a_in", "", "", "gpio1_12"; + pinmuxes = <&gpio1_12_in &gpio1_12_out>; ++ gpio = <&gpio1 12>; + }; + EHRPWM2B: EHRPWM2B { + reg = <8 13>; + pad = "T10"; + modes = "gpmc_ad9", "lcd_data22", "mmc1_dat1", "mmc2_dat5", "ehrpwm2B", "", "", "gpio0_23"; + pinmuxes = <&gpio0_23_in &gpio0_23_out>; ++ gpio = <&gpio0 23>; + }; + GPIO0_26: GPIO0_26 { + reg = <8 14>; + pad = "T11"; + modes = "gpmc_ad10", "lcd_data21", "mmc1_dat2", "mmc2_dat6", "ehrpwm2_tripzone_in", "", "", "gpio0_26"; + pinmuxes = <&gpio0_26_in &gpio0_26_out>; ++ gpio = <&gpio0 26>; + }; + GPIO1_15: GPIO1_15 { + reg = <8 15>; + pad = "U13"; + modes = "gpmc_ad15", "lcd_data16", "mmc1_dat7", "mmc2_dat3", "eqep2_strobe", "", "", "gpio1_15"; + pinmuxes = <&gpio1_15_in &gpio1_15_out>; ++ gpio = <&gpio1 15>; + }; + GPIO1_14: GPIO1_14 { + reg = <8 16>; + pad = "V13"; + modes = "gpmc_ad14", "lcd_data17", "mmc1_dat6", "mmc2_dat2", "eqep2_index", "", "", "gpio1_14"; + pinmuxes = <&gpio1_14_in &gpio1_14_out>; ++ gpio = <&gpio1 14>; + }; + GPIO0_27: GPIO0_27 { + reg = <8 17>; + pad = "U12"; + modes = "gpmc_ad11", "lcd_data20", "mmc1_dat3", "mmc2_dat7", "ehrpwm0_synco", "", "", "gpio0_27"; + pinmuxes = <&gpio0_27_in &gpio0_27_out>; ++ gpio = <&gpio0 27>; + }; + GPIO2_1: GPIO2_1 { + reg = <8 18>; + pad = "V12"; + modes = "gpmc_clk_mux0", "lcd_memory_clk", "gpmc_wait1", "mmc2_clk", "", "", "mcasp0_fsr", "gpio2_1"; + pinmuxes = <&gpio2_1_in &gpio2_1_out>; ++ gpio = <&gpio2 1>; + }; + EHRPWM2A: EHRPWM2A { + reg = <8 19>; + pad = "U10"; + modes = "gpmc_ad8", "lcd_data23", "mmc1_dat0", "mmc2_dat4", "ehrpwm2A", "", "", "gpio0_22"; + pinmuxes = <&gpio0_22_in &gpio0_22_out>; ++ gpio = <&gpio0 22>; + }; + GPIO1_31: GPIO1_31 { + reg = <8 20>; + pad = "V9"; + modes = "gpmc_csn2", "gpmc_be1n", "mmc1_cmd", "", "", "", "", "gpio1_31"; + pinmuxes = <&gpio1_31_in &gpio1_31_out>; ++ gpio = <&gpio1 31>; + }; + GPIO1_30: GPIO1_30 { + reg = <8 21>; + pad = "U9"; + modes = "gpmc_csn1", "gpmc_clk", "mmc1_clk", "", "", "", "", "gpio1_30"; + pinmuxes = <&gpio1_30_in &gpio1_30_out>; ++ gpio = <&gpio1 30>; + }; + GPIO1_5: GPIO1_5 { + reg = <8 22>; + pad = "V8"; + modes = "gpmc_ad5", "mmc1_dat5", "", "", "", "", "", "gpio1_5"; + pinmuxes = <&gpio1_5_in &gpio1_5_out>; ++ gpio = <&gpio1 5>; + }; + GPIO1_4: GPIO1_4 { + reg = <8 23>; + pad = "U8"; + modes = "gpmc_ad4", "mmc1_dat4", "", "", "", "", "", "gpio1_4"; + pinmuxes = <&gpio1_4_in &gpio1_4_out>; ++ gpio = <&gpio1 4>; + }; + GPIO1_1: GPIO1_1 { + reg = <8 24>; + pad = "V7"; + modes = "gpmc_ad1", "mmc1_dat1", "", "", "", "", "", "gpio1_1"; + pinmuxes = <&gpio1_1_in &gpio1_1_out>; ++ gpio = <&gpio1 1>; + }; + GPIO1_0: GPIO1_0 { + reg = <8 25>; + pad = "U7"; + modes = "gpmc_ad0", "mmc1_dat0", "", "", "", "", "", "gpio1_0"; + pinmuxes = <&gpio1_0_in &gpio1_0_out>; ++ gpio = <&gpio1 0>; + }; + GPIO1_29: GPIO1_29 { + reg = <8 26>; + pad = "V6"; + modes = "gpmc_csn0", "", "", "", "", "", "", "gpio1_29"; + pinmuxes = <&gpio1_29_in &gpio1_29_out>; ++ gpio = <&gpio1 29>; + }; + GPIO2_22: GPIO2_22 { + reg = <8 27>; + pad = "U5"; + modes = "lcd_vsync", "gpmc_a8", "", "", "", "", "", "gpio2_22"; + pinmuxes = <&gpio2_22_in &gpio2_22_out>; ++ gpio = <&gpio2 22>; + }; + GPIO2_24: GPIO2_24 { + reg = <8 28>; + pad = "V5"; + modes = "lcd_pclk", "gpmc_a10", "", "", "", "", "", "gpio2_24"; + pinmuxes = <&gpio2_24_in &gpio2_24_out>; ++ gpio = <&gpio2 24>; + }; + GPIO2_23: GPIO2_23 { + reg = <8 29>; + pad = "R5"; + modes = "lcd_hsync", "gpmc_a9", "", "", "", "", "", "gpio2_23"; + pinmuxes = <&gpio2_23_in &gpio2_23_out>; ++ gpio = <&gpio2 23>; + }; + GPIO2_25: GPIO2_25 { + reg = <8 30>; + pad = "R6"; + modes = "lcd_ac_bias_en", "gpmc_a11", "", "", "", "", "", "gpio2_25"; + pinmuxes = <&gpio2_25_in &gpio2_25_out>; ++ gpio = <&gpio2 25>; + }; + UART5_CTSN: UART5_CTSN { + reg = <8 31>; + pad = "V4"; + modes = "lcd_data14", "gpmc_a18", "eqep1_index", "mcasp0_axr1", "uart5_rxd_mux1", "", "uart5_ctsn", "gpio0_10"; + pinmuxes = <&uart5_rxd_mux1 &uart5_ctsn &gpio0_10_in &gpio0_10_out>; ++ gpio = <&gpio0 10>; + }; + UART5_RTSN: UART5_RTSN { + reg = <8 32>; + pad = "T5"; + modes = "lcd_data15", "gpmc_a19", "eqep1_strobe", "mcasp0_ahclkx", "mcasp0_axr3", "", "uart5_rtsn", "gpio0_11"; + pinmuxes = <&uart5_rtsn &gpio0_11_in &gpio0_11_out>; ++ gpio = <&gpio0 11>; + }; + UART4_RTSN: UART4_RTSN { + reg = <8 33>; + pad = "V3"; + modes = "lcd_data13", "gpmc_a17", "eqep1b_in", "mcasp0_fsr", "mcasp0_axr3", "", "uart4_rtsn", "gpio0_9"; + pinmuxes = <&gpio0_9_in &gpio0_9_out>; ++ gpio = <&gpio0 9>; + }; + UART3_RTSN: UART3_RTSN { + reg = <8 34>; + pad = "U4"; + modes = "lcd_data11", "gpmc_a15", "ehrpwm1B", "mcasp0_ahclkr", "mcasp0_axr2", "", "uart3_rtsn", "gpio2_17"; + pinmuxes = <&gpio2_17_in &gpio2_17_out>; ++ gpio = <&gpio2 17>; + }; + UART4_CTSN: UART4_CTSN { + reg = <8 35>; + pad = "V2"; + modes = "lcd_data12", "gpmc_a16", "eqep1a_in", "mcasp0_aclkr", "mcasp0_axr2", "", "uart4_ctsn", "gpio0_8"; + pinmuxes = <&gpio0_8_in &gpio0_8_out>; ++ gpio = <&gpio0 8>; + }; + UART3_CTSN: UART3_CTSN { + reg = <8 36>; + pad = "U3"; + modes = "lcd_data10", "gpmc_a14", "ehrpwm1A", "mcasp0_axr0", "", "", "uart3_ctsn", "gpio2_16"; + pinmuxes = <&gpio2_16_in &gpio2_16_out>; ++ gpio = <&gpio2 16>; + }; + UART5_TXD: UART5_TXD { + reg = <8 37>; + pad = "U1"; + modes = "lcd_data8", "gpmc_a12", "ehrpwm1_tripzone_in", "mcasp0_aclkx", "uart5_txd", "", "uart2_ctsn", "gpio2_14"; + pinmuxes = <&uart5_txd &uart2_ctsn &gpio2_14_in &gpio2_14_out>; ++ gpio = <&gpio2 14>; + }; + UART5_RXD: UART5_RXD { + reg = <8 38>; + pad = "U2"; + modes = "lcd_data9", "gpmc_a13", "ehrpwm0_synco", "mcasp0_fsx", "uart5_rxd", "", "uart2_rtsn", "gpio2_15"; + pinmuxes = <&uart5_rxd &uart2_rtsn &gpio2_15_in &gpio2_15_out>; ++ gpio = <&gpio2 15>; + }; + GPIO2_12: GPIO2_12 { + reg = <8 39>; + pad = "T3"; + modes = "lcd_data6", "gpmc_a6", "", "eqep2_index", "", "", "", "gpio2_12"; + pinmuxes = <&gpio2_12_in &gpio2_12_out>; ++ gpio = <&gpio2 12>; + }; + GPIO2_13: GPIO2_13 { + reg = <8 40>; + pad = "T4"; + modes = "lcd_data7", "gpmc_a7", "", "eqep2_strobe", "pr1_edio_data_out7", "", "", "gpio2_13"; + pinmuxes = <&gpio2_13_in &gpio2_13_out>; ++ gpio = <&gpio2 13>; + }; + GPIO2_10: GPIO2_10 { + reg = <8 41>; + pad = "T1"; + modes = "lcd_data4", "gpmc_a4", "", "eqep2a_in", "", "", "", "gpio2_10"; + pinmuxes = <&gpio2_10_in &gpio2_10_out>; ++ gpio = <&gpio2 10>; + }; + GPIO2_11: GPIO2_11 { + reg = <8 42>; + pad = "T2"; + modes = "lcd_data5", "gpmc_a5", "", "eqep2b_in", "", "", "", "gpio2_11"; + pinmuxes = <&gpio2_11_in &gpio2_11_out>; ++ gpio = <&gpio2 11>; + }; + GPIO2_8: GPIO2_8 { + reg = <8 43>; + pad = "R3"; + modes = "lcd_data2", "gpmc_a2", "", "ehrpwm2_tripzone_in", "", "", "", "gpio2_8"; + pinmuxes = <&gpio2_8_in &gpio2_8_out>; ++ gpio = <&gpio2 8>; + }; + GPIO2_9: GPIO2_9 { + reg = <8 44>; + pad = "R4"; + modes = "lcd_data3", "gpmc_a3", "", "ehrpwm0_synco", "", "", "", "gpio2_9"; + pinmuxes = <&gpio2_9_in &gpio2_9_out>; ++ gpio = <&gpio2 9>; + }; + GPIO2_6: GPIO2_6 { + reg = <8 45>; + pad = "R1"; + modes = "lcd_data0", "gpmc_a0", "", "ehrpwm2A", "", "", "", "gpio2_6"; + pinmuxes = <&gpio2_6_in &gpio2_6_out>; ++ gpio = <&gpio2 6>; + }; + GPIO2_7: GPIO2_7 { + reg = <8 46>; + pad = "R2"; + modes = "lcd_data1", "gpmc_a1", "", "ehrpwm2B", "", "", "", "gpio2_7"; + pinmuxes = <&gpio2_7_in &gpio2_7_out>; ++ gpio = <&gpio2 7>; + }; + + @@ -1251,126 +1528,147 @@ index a9e9eb1..e9b9ee0 100644 + pad = "T17"; + modes = "gpmc_wait0", "mii2_crs", "gpmc_csn4", "rmii2_crs_dv", "mmc1_sdcd", "", "uart4_rxd_mux2", "gpio0_30"; + pinmuxes = <&gpio0_30_in &gpio0_30_out>; ++ gpio = <&gpio0 30>; + }; + GPIO1_28: GPIO1_28 { + reg = <9 12>; + pad = "U18"; + modes = "gpmc_be1n", "mii2_col", "gpmc_csn6", "mmc2_dat3", "gpmc_dir", "", "mcasp0_aclkr_mux3", "gpio1_28"; + pinmuxes = <&gpio1_28_in &gpio1_28_out>; ++ gpio = <&gpio1 28>; + }; + UART4_TXD: UART4_TXD { + reg = <9 13>; + pad = "U17"; + modes = "gpmc_wpn", "mii2_rxerr", "gpmc_csn5", "rmii2_rxerr", "mmc2_sdcd", "", "uart4_txd_mux2", "gpio0_31"; + pinmuxes = <&gpio0_31_in &gpio0_31_out>; ++ gpio = <&gpio0 31>; + }; + EHRPWM1A: EHRPWM1A { + reg = <9 14>; + pad = "U14"; + modes = "gpmc_a2", "mii2_txd3", "rgmii2_td3", "mmc2_dat1", "gpmc_a18", "", "ehrpwm1A_mux1", "gpio1_18"; + pinmuxes = <&gpio1_18_in &gpio1_18_out>; ++ gpio = <&gpio1 18>; + }; + GPIO1_16: GPIO1_16 { + reg = <9 15>; + pad = "R13"; + modes = "gpmc_a0", "gmii2_txen", "rmii2_tctl", "mii2_txen", "gpmc_a16", "", "ehrpwm1_tripzone_input", "gpio1_16"; + pinmuxes = <&gpio1_16_in &gpio1_16_out>; ++ gpio = <&gpio1 16>; + }; + EHRPWM1B: EHRPWM1B { + reg = <9 16>; + pad = "T14"; + modes = "gpmc_a3", "mii2_txd2", "rgmii2_td2", "mmc2_dat2", "gpmc_a19", "", "ehrpwm1B_mux1", "gpio1_19"; -+ pinmuxes = <&i2c1_scl &gpio0_19_in &gpio0_19_out>; ++ pinmuxes = <&gpio0_19_in &gpio0_19_out>; ++ gpio = <&gpio0 19>; + }; + I2C1_SCL: I2C1_SCL { + reg = <9 17>; + pad = "A16"; + modes = "spi0_cs0", "mmc2_sdwp", "i2c1_scl", "ehrpwm0_synci", "", "", "", "gpio0_5"; + pinmuxes = <&i2c1_scl &gpio0_5_in &gpio0_5_out>; ++ gpio = <&gpio0 5>; + }; + I2C1_SDA: I2C1_SDA { + reg = <9 18>; + pad = "B16"; + modes = "spi0_d1", "mmc1_sdwp", "i2c1_sda", "ehrpwm0_tripzone", "", "", "", "gpio0_4"; + pinmuxes = <&i2c1_sda &gpio0_4_in &gpio0_4_out>; ++ gpio = <&gpio0 4>; + }; + I2C2_SCL: I2C2_SCL { + reg = <9 19>; + pad = "D17"; + modes = "uart1_rtsn", "timer5", "dcan0_rx", "i2c2_scl", "spi1_cs1", "", "", "gpio0_13"; + pinmuxes = <&uart1_rtsn &gpio0_13_in &gpio0_13_out>; ++ gpio = <&gpio0 13>; + }; + I2C2_SDA: I2C2_SDA { + reg = <9 20>; + pad = "D18"; + modes = "uart1_ctsn", "timer6", "dcan0_tx", "i2c2_sda", "spi1_cs0", "", "", "gpio0_12"; + pinmuxes = <&uart1_ctsn &gpio0_12_in &gpio0_12_out>; ++ gpio = <&gpio0 12>; + }; + UART2_TXD: UART2_TXD { + reg = <9 21>; + pad = "B17"; + modes = "spi0_d0", "uart2_txd", "i2c2_scl", "ehrpwm0B", "", "", "emu3_mux1", "gpio0_3"; + pinmuxes = <&uart2_txd &gpio0_3_in &gpio0_3_out>; ++ gpio = <&gpio0 3>; + }; + UART2_RXD: UART2_RXD { + reg = <9 22>; + pad = "A17"; + modes = "spi0_sclk", "uart2_rxd", "i2c2_sda", "ehrpwm0A", "", "", "emu2_mux1", "gpio0_2"; + pinmuxes = <&uart2_rxd &gpio0_2_in &gpio0_2_out>; ++ gpio = <&gpio0 2>; + }; + GPIO1_17: GPIO1_17 { + reg = <9 23>; + pad = "V14"; + modes = "gpmc_a1", "gmii2_rxdv", "rgmii2_rxdv", "mmc2_dat0", "gpmc_a17", "", "ehrpwm0_synco", "gpio1_17"; + pinmuxes = <&gpio1_17_in &gpio1_17_out>; ++ gpio = <&gpio1 17>; + }; + UART1_TXD: UART1_TXD { + reg = <9 24>; + pad = "D15"; + modes = "uart1_txd", "mmc2_sdwp", "dcan1_rx", "i2c1_scl_mux1", "", "", "", "gpio0_15"; + pinmuxes = <&uart1_txd &i2c1_scl_mux1 &gpio0_15_in &gpio0_15_out>; ++ gpio = <&gpio0 15>; + }; + GPIO3_21: GPIO3_21 { + reg = <9 25>; + pad = "A14"; + modes = "mcasp0_ahclkx", "eqep0_strobe", "mcasp0_axr3", "mcasp1_axr1", "emu4_mux2", "", "", "gpio3_21"; + pinmuxes = <&gpio3_21_in &gpio3_21_out>; ++ gpio = <&gpio3 21>; + }; + UART1_RXD: UART1_RXD { + reg = <9 26>; + pad = "D16"; + modes = "uart1_rxd", "mmc1_sdwp", "dcan1_tx", "i2c1_sda_mux1", "", "", "", "gpio0_14"; + pinmuxes = <&uart1_rxd &i2c1_sda_mux1 &gpio0_14_in &gpio0_14_out>; ++ gpio = <&gpio0 14>; + }; + GPIO3_19: GPIO3_19 { + reg = <9 27>; + pad = "C13"; + modes = "mcasp0_fsr", "eqep0b_in", "mcasp0_axr3", "mcasp1_fsx", "emu2_mux2", "", "", "gpio3_19"; + pinmuxes = <&gpio3_19_in &gpio3_19_out>; ++ gpio = <&gpio3 19>; + }; + SPI1_CS0: SPI1_CS0 { + reg = <9 28>; + pad = "C12"; + modes = "mcasp0_ahclkr", "ehrpwm0_synci", "mcasp0_axr2", "spi1_cs0", "ecap2_in_pwm2_out", "", "", "gpio3_17"; + pinmuxes = <&gpio3_17_in &gpio3_17_out>; ++ gpio = <&gpio3 17>; + }; + SPI1_D0: SPI1_D0 { + reg = <9 29>; + pad = "B13"; + modes = "mcasp0_fsx", "ehrpwm0b", "", "spi1_d0", "mmc1_sdcd_mux1", "", "", "gpio3_15"; + pinmuxes = <&gpio3_15_in &gpio3_15_out>; ++ gpio = <&gpio3 15>; + }; + SPI1_D1: SPI1_D1 { + reg = <9 30>; + pad = "D12"; + modes = "mcasp0_axr0", "ehrpwm0_tripzone", "", "spi1_d1", "mmc2_sdcd_mux1", "", "", "gpio3_16"; + pinmuxes = <&gpio3_16_in &gpio3_16_out>; ++ gpio = <&gpio3 16>; + }; + SPI1_SCLK: SPI1_SCLK { + reg = <9 31>; + pad = "A13"; + modes = "mcasp0_aclkx", "ehrpwm0a", "", "spi1_sclk", "mmc0_sdcd_mux1", "", "", "gpio3_14"; + pinmuxes = <&gpio3_14_in &gpio3_14_out>; ++ gpio = <&gpio3 14>; + }; + VADC: VADC { + reg = <9 32>; @@ -1412,6 +1710,7 @@ index a9e9eb1..e9b9ee0 100644 + pad = "D14"; + modes = "xdma_event_intr1", "", "tclkin", "clkout2", "timer7_mux1", "", "emu3_mux0", "gpio0_20"; + pinmuxes = <&gpio0_20_in &gpio0_20_out>; ++ gpio = <&gpio0 20>; + }; + GPIO3_20: GPIO3_20 { + /* wired with CLKOUT2 */ @@ -1419,6 +1718,7 @@ index a9e9eb1..e9b9ee0 100644 + pad = "D13"; + modes = "mcasp0_axr1", "eqep0_index", "", "mcasp1_axr0", "emu3", "", "", "gpio3_20"; + pinmuxes = <&gpio3_20_in &gpio3_20_out>; ++ gpio = <&gpio3 20>; + }; + GPIO0_7: GPIO0_7 { + /* wired with GPIO3_18 */ @@ -1426,6 +1726,7 @@ index a9e9eb1..e9b9ee0 100644 + pad = "C18"; + modes = "ecap0_in_pwm0_out", "uart3_txd", "spi1_cs1", "pr1_ecap0_ecap_capin_apwm_o", "spi1_sclk", "mmc0_sdwp", "xdma_event_intr2", "gpio0_7"; + pinmuxes = <&gpio0_7_in &gpio0_7_out>; ++ gpio = <&gpio0 7>; + }; + GPIO3_18: GPIO3_18 { + /* wired with GPIO0_7 */ @@ -1433,141 +1734,79 @@ index a9e9eb1..e9b9ee0 100644 + pad = "B12"; + modes = "mcasp0_aclkr", "eqep0a_in", "mcaspo_axr2", "mcasp1_aclkx", "", "", "", "gpio3_18"; + pinmuxes = <&gpio3_18_in &gpio3_18_out>; ++ gpio = <&gpio3 18>; + }; + }; + + functions { + -+ dtcon_gpio: gpio { ++ gpio { + /* base of allocation - this is global for the connector */ + gpio-base = <256>; -+ -+ #modes = <2>; -+ modes = "in", "out"; -+ -+ /* format: <gpio-phandle> <gpio-nr> <connector-pin-phandle> <modes>.. */ -+ gpio = <&gpio0 2 &UART2_RXD &gpio0_2_in &gpio0_2_out >, -+ <&gpio0 3 &UART2_TXD &gpio0_3_in &gpio0_3_out >, -+ <&gpio0 4 &I2C1_SDA &gpio0_4_in &gpio0_4_out >, -+ <&gpio0 5 &I2C1_SCL &gpio0_5_in &gpio0_5_out >, -+ <&gpio0 7 &GPIO0_7 &gpio0_7_in &gpio0_7_out >, -+ <&gpio0 8 &UART4_CTSN &gpio0_8_in &gpio0_8_out >, -+ <&gpio0 9 &UART4_RTSN &gpio0_9_in &gpio0_9_out >, -+ <&gpio0 10 &UART5_CTSN &gpio0_10_in &gpio0_10_out>, -+ <&gpio0 11 &UART5_RTSN &gpio0_11_in &gpio0_11_out>, -+ <&gpio0 12 &I2C2_SDA &gpio0_12_in &gpio0_12_out>, -+ <&gpio0 13 &I2C2_SCL &gpio0_13_in &gpio0_13_out>, -+ <&gpio0 14 &UART1_RXD &gpio0_14_in &gpio0_14_out>, -+ <&gpio0 15 &UART1_TXD &gpio0_15_in &gpio0_15_out>, -+ <&gpio0 19 &EHRPWM1B &gpio0_19_in &gpio0_19_out>, -+ <&gpio0 20 &CLKOUT2 &gpio0_20_in &gpio0_20_out>, -+ <&gpio0 22 &EHRPWM2A &gpio0_22_in &gpio0_22_out>, -+ <&gpio0 23 &EHRPWM2B &gpio0_23_in &gpio0_23_out>, -+ <&gpio0 26 &GPIO0_26 &gpio0_26_in &gpio0_26_out>, -+ <&gpio0 27 &GPIO0_27 &gpio0_27_in &gpio0_27_out>, -+ <&gpio0 30 &UART4_RXD &gpio0_30_in &gpio0_30_out>, -+ <&gpio0 31 &UART4_TXD &gpio0_31_in &gpio0_31_out>, -+ <&gpio1 0 &GPIO1_0 &gpio1_0_in &gpio1_0_out >, -+ <&gpio1 1 &GPIO1_1 &gpio1_1_in &gpio1_1_out >, -+ <&gpio1 2 &GPIO1_2 &gpio1_2_in &gpio1_2_out >, -+ <&gpio1 3 &GPIO1_3 &gpio1_3_in &gpio1_3_out >, -+ <&gpio1 4 &GPIO1_4 &gpio1_4_in &gpio1_4_out >, -+ <&gpio1 5 &GPIO1_5 &gpio1_5_in &gpio1_5_out >, -+ <&gpio1 6 &GPIO1_6 &gpio1_6_in &gpio1_6_out >, -+ <&gpio1 7 &GPIO1_7 &gpio1_7_in &gpio1_7_out >, -+ <&gpio1 12 &GPIO1_12 &gpio1_12_in &gpio1_12_out>, -+ <&gpio1 13 &GPIO1_13 &gpio1_13_in &gpio1_13_out>, -+ <&gpio1 14 &GPIO1_14 &gpio1_14_in &gpio1_14_out>, -+ <&gpio1 15 &GPIO1_15 &gpio1_15_in &gpio1_15_out>, -+ <&gpio1 16 &GPIO1_16 &gpio1_16_in &gpio1_16_out>, -+ <&gpio1 17 &GPIO1_17 &gpio1_17_in &gpio1_17_out>, -+ <&gpio1 18 &EHRPWM1A &gpio1_18_in &gpio1_18_out>, -+ <&gpio1 28 &GPIO1_28 &gpio1_28_in &gpio1_28_out>, -+ <&gpio1 29 &GPIO1_29 &gpio1_29_in &gpio1_29_out>, -+ <&gpio1 30 &GPIO1_30 &gpio1_30_in &gpio1_30_out>, -+ <&gpio1 31 &GPIO1_31 &gpio1_31_in &gpio1_31_out>, -+ <&gpio2 1 &GPIO2_1 &gpio2_1_in &gpio2_1_out >, -+ <&gpio2 2 &TIMER4 &gpio2_2_in &gpio2_2_out >, -+ <&gpio2 3 &TIMER7 &gpio2_3_in &gpio2_3_out >, -+ <&gpio2 4 &TIMER6 &gpio2_4_in &gpio2_4_out >, -+ <&gpio2 5 &TIMER5 &gpio2_5_in &gpio2_5_out >, -+ <&gpio2 6 &GPIO2_6 &gpio2_6_in &gpio2_6_out >, -+ <&gpio2 7 &GPIO2_7 &gpio2_7_in &gpio2_7_out >, -+ <&gpio2 8 &GPIO2_8 &gpio2_8_in &gpio2_8_out >, -+ <&gpio2 9 &GPIO2_9 &gpio2_9_in &gpio2_9_out >, -+ <&gpio2 10 &GPIO2_10 &gpio2_10_in &gpio2_10_out>, -+ <&gpio2 11 &GPIO2_11 &gpio2_11_in &gpio2_11_out>, -+ <&gpio2 12 &GPIO2_12 &gpio2_12_in &gpio2_12_out>, -+ <&gpio2 13 &GPIO2_13 &gpio2_13_in &gpio2_13_out>, -+ <&gpio2 14 &UART5_TXD &gpio2_14_in &gpio2_14_out>, -+ <&gpio2 15 &UART5_RXD &gpio2_15_in &gpio2_15_out>, -+ <&gpio2 16 &UART3_CTSN &gpio2_16_in &gpio2_16_out>, -+ <&gpio2 17 &UART3_RTSN &gpio2_17_in &gpio2_17_out>, -+ <&gpio2 22 &GPIO2_22 &gpio2_22_in &gpio2_22_out>, -+ <&gpio2 23 &GPIO2_23 &gpio2_23_in &gpio2_23_out>, -+ <&gpio2 24 &GPIO2_24 &gpio2_24_in &gpio2_24_out>, -+ <&gpio2 25 &GPIO2_25 &gpio2_25_in &gpio2_25_out>, -+ <&gpio3 14 &SPI1_SCLK &gpio3_14_in &gpio3_14_out>, -+ <&gpio3 15 &SPI1_D0 &gpio3_15_in &gpio3_15_out>, -+ <&gpio3 16 &SPI1_D1 &gpio3_16_in &gpio3_16_out>, -+ <&gpio3 17 &SPI1_CS0 &gpio3_17_in &gpio3_17_out>, -+ <&gpio3 18 &GPIO3_18 &gpio3_18_in &gpio3_18_out>, -+ <&gpio3 19 &GPIO3_19 &gpio3_19_in &gpio3_19_out>, -+ <&gpio3 20 &GPIO3_20 &gpio3_20_in &gpio3_20_out>, -+ <&gpio3 21 &GPIO3_21 &gpio3_21_in &gpio3_21_out>; + }; + + /* connector uart0 is uart2 of the bone */ + uart { + params { ++ ++ #param-cells = <2>; ++ generate-pinctrl; ++ + txd { + required; ++ connector-pin; + }; + + rxd { + required; ++ connector-pin; + }; + + cts { + optional; ++ connector-pin; + gpio-property = "cts-gpios"; -+ gpio-mode = "in"; ++ gpio-args = <GPIO_ACTIVE_LOW>; + }; + + rts { + optional; ++ connector-pin; + gpio-property = "rts-gpios"; -+ gpio-mode = "out"; ++ gpio-args = <GPIO_ACTIVE_LOW>; + }; + + dtr { + optional; ++ connector-pin; + gpio-property = "dtr-gpios"; -+ gpio-mode = "out"; ++ gpio-args = <GPIO_ACTIVE_LOW>; + }; + + dsr { + optional; ++ connector-pin; + gpio-property = "dsr-gpios"; -+ gpio-mode = "in"; ++ gpio-args = <GPIO_ACTIVE_LOW>; + }; + + dcd { + optional; ++ connector-pin; + gpio-property = "dcd-gpios"; -+ gpio-mode = "in"; ++ gpio-args = <GPIO_ACTIVE_LOW>; + }; + + rng { + optional; ++ connector-pin; + gpio-property = "rnd-gpios"; -+ gpio-mode = "in"; ++ gpio-args = <GPIO_ACTIVE_LOW>; + }; + }; + -+ uart@0 { ++ uart1 { + device = <&uart1>; -+ gpio = <&dtcon_gpio>; + mux@0 { + txd = <&UART1_TXD &uart1_txd>; + rxd = <&UART1_RXD &uart1_rxd>; @@ -1575,9 +1814,8 @@ index a9e9eb1..e9b9ee0 100644 + rts = <&I2C2_SCL &uart1_rtsn>; + }; + }; -+ uart@1 { ++ uart2 { + device = <&uart2>; -+ gpio = <&dtcon_gpio>; + mux@0 { + txd = <&UART2_TXD &uart2_txd>; + rxd = <&UART2_RXD &uart2_rxd>; @@ -1585,9 +1823,8 @@ index a9e9eb1..e9b9ee0 100644 + rts = <&UART5_RXD &uart2_rtsn>; + }; + }; -+ uart@2 { ++ uart5 { + device = <&uart5>; -+ gpio = <&dtcon_gpio>; + mux@0 { + txd = <&UART5_TXD &uart5_txd>; + rxd = <&UART5_RXD &uart5_rxd>, @@ -1600,25 +1837,48 @@ index a9e9eb1..e9b9ee0 100644 + + i2c { + params { ++ ++ #param-cells = <2>; ++ copy-subdevices; ++ generate-pinctrl; ++ + scl { + required; ++ connector-pin; + }; + + sda { + required; ++ connector-pin; + }; ++ ++ clock-frequency { ++ copy; ++ }; ++ + }; + -+ i2c@0 { ++ i2c1 { + device = <&i2c1>; + + mux@0 { -+ scl = <&EHRPWM1B &i2c1_scl>, -+ <&I2C1_SDA &i2c1_sda>; -+ sda = <&UART1_TXD &i2c1_scl_mux1>, ++ scl = <&I2C1_SCL &i2c1_scl>, ++ <&UART1_TXD &i2c1_scl_mux1>; ++ sda = <&I2C1_SDA &i2c1_sda>, + <&UART1_RXD &i2c1_sda_mux1>; + }; + }; ++ ++ i2c2 { ++ device = <&i2c2>; ++ ++ mux@0 { ++ /* I2C2 is preconfigured and available */ ++ scl = <&I2C2_SCL 0>; ++ sda = <&I2C2_SDA 0>; ++ pre-enabled; ++ }; ++ }; + }; + }; + @@ -1629,19 +1889,14 @@ index a9e9eb1..e9b9ee0 100644 + +#if 0 + BB_BONE_UART { -+ compatible = "simple-bus"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ uart@0 { -+ compatible = "dtcon-uart"; -+ status = "okay"; -+ txd = <9 21>; /* at P9.21 */ -+ rxd = <9 22>; /* at P9.22 */ -+ }; ++ compatible = "dtcon-uart"; ++ status = "okay"; ++ txd = <9 21>; /* at P9.21 */ ++ rxd = <9 22>; /* at P9.22 */ + }; +#endif + ++#if 1 + BB_RELAY_4PORT { + compatible = "simple-bus"; + #address-cells = <1>; @@ -1655,7 +1910,7 @@ index a9e9eb1..e9b9ee0 100644 + #gpio-cells = <2>; + + pin-list = <9 15>, /* #0 P9.15 */ -+ <9 23>, /* #1 P9.23 */ ++ <9 23>, /* #1 P9.23 */ + <9 12>, /* #2 P9.12 */ + <9 27>, /* #3 P9.27 */ + <9 28>; /* #4 P9.28 */ @@ -1690,39 +1945,73 @@ index a9e9eb1..e9b9ee0 100644 + }; + }; + }; -+ ++#endif + +#if 0 + BB_BONE_UART_RTSCTS { -+ uart@0 { -+ compatible = "dtcon-uart"; -+ status = "okay"; ++ compatible = "dtcon-uart"; ++ status = "okay"; + -+ txd = <9 21>; /* at P9.21 */ -+ rxd = <9 22>; /* at P9.22 */ -+ rts = <8 38>; /* at P8.38 */ -+ cts = <8 37>; /* at P8.37 */ -+ }; ++ txd = <9 21>; /* at P9.21 */ ++ rxd = <9 22>; /* at P9.22 */ ++ rts = <8 38>; /* at P8.38 */ ++ cts = <8 37>; /* at P8.37 */ ++ dcd = <8 39>; + }; ++#endif + ++#if 0 + BB_RTC { -+ bb_rtc_i2c: i2c@0 { -+ compatible = "dtcon-i2c"; ++ compatible = "dtcon-i2c"; ++ status = "okay"; ++ ++ scl = <9 17>; ++ sda = <9 18>; ++ ++ clock-frequency = <100000>; ++ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ /* MCP79410 RTC module */ ++ rtc@68 { ++ compatible = "maxim,ds1338"; + status = "okay"; ++ reg = <0x68>; ++ }; ++ }; ++#endif ++ ++#if 0 ++ BB_BONE_WTHR { ++ compatible = "dtcon-i2c"; ++ status = "okay"; + -+ scl = <9 17>; -+ sda = <9 18>; ++ scl = <9 19>; ++ sda = <9 20>; + -+ clock-frequency = <100000>; ++ #address-cells = <1>; ++ #size-cells = <0>; + -+ #address-cells = <1>; -+ #size-cells = <0>; ++ /* Ambient light sensor */ ++ tsl2550@39 { ++ compatible = "tsl,tsl2550"; ++ reg = <0x39>; ++ status = "okay"; ++ }; + -+ /* MCP79410 RTC module */ -+ rtc@68 { -+ compatible = "maxim,ds1338"; -+ reg = <0x68>; -+ }; ++ /* Humidity Sensor */ ++ htu21@40 { ++ compatible = "meas-spec,htu21"; ++ reg = <0x40>; ++ status = "okay"; ++ }; ++ ++ /* Barometric pressure sensor */ ++ bmp085@77 { ++ compatible = "bosch,bmp085"; ++ reg = <0x77>; ++ status = "okay"; + }; + }; +#endif @@ -1730,7 +2019,7 @@ index a9e9eb1..e9b9ee0 100644 + }; }; diff --git a/drivers/extcon/Kconfig b/drivers/extcon/Kconfig -index 3d89e60..341d7b1 100644 +index 3d89e60..a004269 100644 --- a/drivers/extcon/Kconfig +++ b/drivers/extcon/Kconfig @@ -35,6 +35,26 @@ config EXTCON_AXP288 @@ -1740,15 +2029,15 @@ index 3d89e60..341d7b1 100644 +config EXTCON_DT_CON + tristate "Device Tree Overlay based connector" + depends on OF || COMPILE_TEST -+ select OF_OVERLAY ++ depends on OF_OVERLAY + help + Say Y here to enable Device Tree Overlay based connector + -+config EXTCON_DT_CON_UART -+ tristate "Device Tree Connector UART proxy driver" ++config EXTCON_DT_CON_PROXY ++ tristate "Device Tree Connector Generic proxy driver" + select EXTCONF_DT_CON + help -+ Say Y here to enable Device Tree UART proxy connector driver ++ Say Y here to enable Device Tree generic proxy connector driver + +config EXTCON_DT_CON_GPIO + tristate "Device Tree Connector GPIO proxy driver" @@ -1761,7 +2050,7 @@ index 3d89e60..341d7b1 100644 tristate "GPIO extcon support" depends on GPIOLIB || COMPILE_TEST diff --git a/drivers/extcon/Makefile b/drivers/extcon/Makefile -index 2a0e4f4..7b136be 100644 +index 2a0e4f4..7db472d 100644 --- a/drivers/extcon/Makefile +++ b/drivers/extcon/Makefile @@ -6,6 +6,9 @@ obj-$(CONFIG_EXTCON) += extcon.o @@ -1770,16 +2059,16 @@ index 2a0e4f4..7b136be 100644 obj-$(CONFIG_EXTCON_AXP288) += extcon-axp288.o +obj-$(CONFIG_EXTCON_DT_CON) += extcon-dt-con.o +obj-$(CONFIG_EXTCON_DT_CON_GPIO)+= extcon-dt-con-gpio.o -+obj-$(CONFIG_EXTCON_DT_CON_UART)+= extcon-dt-con-uart.o ++obj-$(CONFIG_EXTCON_DT_CON_PROXY)+= extcon-dt-con-proxy.o obj-$(CONFIG_EXTCON_GPIO) += extcon-gpio.o obj-$(CONFIG_EXTCON_MAX14577) += extcon-max14577.o obj-$(CONFIG_EXTCON_MAX3355) += extcon-max3355.o diff --git a/drivers/extcon/extcon-dt-con-gpio.c b/drivers/extcon/extcon-dt-con-gpio.c new file mode 100644 -index 0000000..1dd0f91 +index 0000000..1c1bb54 --- /dev/null +++ b/drivers/extcon/extcon-dt-con-gpio.c -@@ -0,0 +1,672 @@ +@@ -0,0 +1,510 @@ +/* + * Copyright (C) 2016 Konsulko Group + * @@ -1793,7 +2082,6 @@ index 0000000..1dd0f91 + * GNU General Public License for more details. + * + */ -+ +#include <linux/module.h> +#include <linux/interrupt.h> +#include <linux/kernel.h> @@ -1807,6 +2095,9 @@ index 0000000..1dd0f91 + +#include "extcon-dt-con.h" + ++/* format: <gpio-phandle> <gpio-nr> <connector-pin-phandle> */ ++#define GPIO_CELLS_NUM 3 ++ +struct dtcon_gpio_func_data { + struct dtcon_function *function; + int gpio_base; @@ -1816,7 +2107,6 @@ index 0000000..1dd0f91 +/* indexed by gpio number */ +struct dtcon_gpio_pin_data { + struct dtcon_pin *dtcp; -+ int gpio_index; + struct device_node *chip_np; + struct gpio_chip *chip; /* when requested */ + int hwnum; @@ -1831,147 +2121,6 @@ index 0000000..1dd0f91 +}; +#define to_dtcon_gpio_data(x) container_of((x), struct dtcon_gpio_data, chip) + -+static int dtcon_gpio_get_gpio_value_count(struct dtcon_gpio_data *dtcg) -+{ -+ struct dtcon_proxy *proxy = dtcg->proxy; -+ struct dtcon_function *dtcf = proxy->dtcf; -+ struct dtcon_gpio_func_data *dtcgf = dtcf->data; -+ const void *value; -+ int len; -+ -+ /* get the gpio property */ -+ value = of_get_property(dtcf->np, "gpio", &len); -+ if (!value) -+ return -EINVAL; -+ -+ /* must be a cell multiple */ -+ if (len % sizeof(u32)) -+ return -EINVAL; -+ -+ /* convert to cells */ -+ len /= sizeof(u32); -+ -+ /* make sure it's a gpio cell multiple */ -+ if (len % dtcgf->gpio_cells) -+ return -EINVAL; -+ -+ /* convert to gpio cells */ -+ len /= dtcgf->gpio_cells; -+ -+ return len; -+} -+ -+static const __be32 *dtcon_gpio_get_gpio_value_index( -+ struct dtcon_gpio_data *dtcg, int index) -+{ -+ struct dtcon_proxy *proxy = dtcg->proxy; -+ struct dtcon_function *dtcf = proxy->dtcf; -+ struct dtcon_gpio_func_data *dtcgf = dtcf->data; -+ const void *value; -+ int len; -+ -+ /* get the gpio property */ -+ value = of_get_property(dtcf->np, "gpio", &len); -+ if (!value) -+ return NULL; -+ -+ /* must be a cell multiple */ -+ if (len % sizeof(u32)) -+ return NULL; -+ -+ /* convert to cells */ -+ len /= sizeof(u32); -+ -+ /* make sure it's a gpio cell multiple */ -+ if (len % dtcgf->gpio_cells) -+ return NULL; -+ -+ /* convert to gpio cells */ -+ len /= dtcgf->gpio_cells; -+ -+ /* must fit */ -+ if (index >= len) -+ return NULL; -+ -+ /* return pointer */ -+ return value + index * sizeof(u32) * dtcgf->gpio_cells; -+} -+ -+static int dtcon_gpio_get_info(struct dtcon_gpio_data *dtcg, int index, -+ struct device_node **gpio_node, int *gpio, -+ struct device_node **pin_node) -+{ -+ const __be32 *value; -+ phandle phandle; -+ -+ /* get pointer to the value array */ -+ value = dtcon_gpio_get_gpio_value_index(dtcg, index); -+ if (!value) -+ return -EINVAL; -+ -+ phandle = be32_to_cpu(value[0]); -+ if (gpio_node) { -+ *gpio_node = of_find_node_by_phandle(phandle); -+ if (!*gpio_node) -+ return -EINVAL; -+ } -+ if (gpio) -+ *gpio = be32_to_cpu(value[1]); -+ -+ phandle = be32_to_cpu(value[2]); -+ if (pin_node) { -+ *pin_node = of_find_node_by_phandle(phandle); -+ if (!*pin_node) { -+ if (gpio_node) -+ of_node_put(*gpio_node); -+ return -EINVAL; -+ } -+ } -+ -+ return 0; -+} -+ -+/* map from a connector reg address to a function gpio index */ -+static int dtcon_gpio_address_to_gpio_index(struct dtcon_gpio_data *dtcg, -+ const void *regp, int regsz) -+{ -+ int i, j, count, err, len; -+ struct device_node *np = NULL; -+ const void *value; -+ -+ count = dtcon_gpio_get_gpio_value_count(dtcg); -+ if (count < 0) -+ return count; -+ -+ if (count == 0) -+ return -EINVAL; -+ -+ for (j = 0; j < count; j++) { -+ /* get pin node */ -+ err = dtcon_gpio_get_info(dtcg, j, NULL, NULL, &np); -+ if (err) -+ continue; -+ -+ value = of_get_property(np, "reg", &len); -+ -+ /* check that it exists and is a multiple */ -+ if (!value || (len % regsz) != 0) { -+ of_node_put(np); -+ continue; -+ } -+ -+ /* iterate over all */ -+ for (i = 0; i < len; i += regsz, value += regsz) { -+ if (memcmp(value, regp, regsz) == 0) { -+ of_node_put(np); -+ return j; /* got index */ -+ } -+ } -+ } -+ -+ return -1; -+} -+ +/* match when we got the same device node */ +static int dtcon_find_gpiochip(struct gpio_chip *gc, void *data) +{ @@ -2014,7 +2163,7 @@ index 0000000..1dd0f91 + return err; + } + -+ dev_info(dev, "%s(%u) -> %d\n", __func__, offset, err); ++ dev_dbg(dev, "%s(%u) -> %d\n", __func__, offset, err); + + return err; +} @@ -2035,7 +2184,7 @@ index 0000000..1dd0f91 + if (gc->free) + gc->free(gc, pin_data->hwnum); + -+ dev_info(dev, "%s(%u)\n", __func__, offset); ++ dev_dbg(dev, "%s(%u)\n", __func__, offset); + +} + @@ -2047,9 +2196,13 @@ index 0000000..1dd0f91 + struct gpio_chip *gc; + int err; + ++ /* if we're still in probe? return input */ ++ if (platform_get_drvdata(dtcg->pdev) != dtcg) ++ return 1; ++ ++ BUG_ON(!dtcg); + if (offset >= dtcg->chip.ngpio) + return -EINVAL; -+ + pin_data = &dtcg->pin_data[offset]; + gc = pin_data->chip; + if (!gc->get_direction) @@ -2061,7 +2214,7 @@ index 0000000..1dd0f91 + return err; + } + -+ dev_info(dev, "%s(%u) -> %d\n", __func__, offset, err); ++ dev_dbg(dev, "%s(%u) -> %d\n", __func__, offset, err); + + return err; +} @@ -2088,7 +2241,7 @@ index 0000000..1dd0f91 + return err; + } + -+ dev_info(dev, "%s(%u) -> %d\n", __func__, offset, err); ++ dev_dbg(dev, "%s(%u) -> %d\n", __func__, offset, err); + + return err; +} @@ -2115,7 +2268,7 @@ index 0000000..1dd0f91 + return err; + } + -+ dev_info(dev, "%s(%u) -> %d\n", __func__, offset, err); ++ dev_dbg(dev, "%s(%u) -> %d\n", __func__, offset, err); + + return err; +} @@ -2143,7 +2296,7 @@ index 0000000..1dd0f91 + return err; + } + -+ dev_info(dev, "%s(%u, %d) -> %d\n", __func__, offset, value, err); ++ dev_dbg(dev, "%s(%u, %d) -> %d\n", __func__, offset, value, err); + + return err; +} @@ -2171,7 +2324,7 @@ index 0000000..1dd0f91 + return err; + } + -+ dev_info(dev, "%s(%u, %d) -> %d\n", __func__, offset, debounce, err); ++ dev_dbg(dev, "%s(%u, %d) -> %d\n", __func__, offset, debounce, err); + + return err; +} @@ -2194,7 +2347,7 @@ index 0000000..1dd0f91 + + gc->set(gc, pin_data->hwnum, value); + -+ dev_info(dev, "%s(%u, %d) -> %d\n", __func__, offset, value, err); ++ dev_dbg(dev, "%s(%u, %d) -> %d\n", __func__, offset, value, err); +} + +/* gpio function methods */ @@ -2227,17 +2380,8 @@ index 0000000..1dd0f91 + + dtcgf->gpio_base = num; + -+ err = of_property_read_u32(dtcf->np, "#modes", &num); -+ if (err) { -+ dev_err(dev, "No gpio-base in function configuration\n"); -+ err = -EINVAL; -+ goto err_out; -+ } -+ -+ /* format: <gpio-phandle> <gpio-nr> <connector-pin-phandle> <modes>.. */ -+ dtcgf->gpio_cells = 3 + num; -+ -+ dev_info(dev, "%s\n", __func__); ++ /* format: <gpio-phandle> <gpio-nr> <connector-pin-phandle> */ ++ dtcgf->gpio_cells = GPIO_CELLS_NUM; + + return 0; + @@ -2248,12 +2392,8 @@ index 0000000..1dd0f91 + +static void dtcon_gpio_function_fini(struct dtcon_function *dtcf) +{ -+ struct dtcon_data *dtcd = dtcf->dtcd; -+ struct device *dev = &dtcd->pdev->dev; + struct dtcon_gpio_func_data *dtcgf = dtcf->data; + -+ dev_info(dev, "%s\n", __func__); -+ + kfree(dtcgf); +} + @@ -2268,6 +2408,7 @@ index 0000000..1dd0f91 + struct dtcon_proxy *proxy; + struct dtcon_pin *dtcp; + struct dtcon_gpio_pin_data *pin_data; ++ struct of_phandle_args args; + const void *pin_regs; + int i, err, count, regsz, index; + @@ -2331,15 +2472,6 @@ index 0000000..1dd0f91 + dtcg->chip.ngpio = count; + dtcg->chip.of_node = of_node_get(np); + -+ err = gpiochip_add_data(&dtcg->chip, dtcg); -+ if (err) { -+ dev_err(dev, "Could not register gpio chip %d\n", err); -+ goto out_destroy_proxy; -+ } -+ -+ /* advance base */ -+ dtcgf->gpio_base += count; -+ + /* request all pins */ + regsz = sizeof(u32) * dtcd->connector_address_cells; + for (i = 0; i < count; i++, pin_regs += regsz) { @@ -2350,27 +2482,18 @@ index 0000000..1dd0f91 + if (IS_ERR(dtcp)) { + dev_err(dev, "could not request gpio #%d\n", i); + err = PTR_ERR(dtcp); -+ goto out_gpiochip_remove; ++ goto out_release_pin; + } + + pin_data->dtcp = dtcp; + -+ /* keep it */ -+ index = dtcon_gpio_address_to_gpio_index(dtcg, pin_regs, regsz); -+ if (index < 0) { -+ err = index; -+ dev_err(dev, "gpio #%d not pointing to pin\n", i); -+ goto out_release_pin; -+ } -+ pin_data->gpio_index = index; -+ -+ err = dtcon_gpio_get_info(dtcg, index, &pin_data->chip_np, -+ &pin_data->hwnum, NULL); ++ err = of_parse_phandle_with_fixed_args(dtcp->np, "gpio", 1, 0, &args); + if (err) { -+ dev_err(dev, "gpio #%d index #%d no info\n", -+ i, index); ++ dev_err(dev, "could not #%d parse gpio property\n", i); + goto out_release_pin; + } ++ pin_data->chip_np = args.np; ++ pin_data->hwnum = args.args[0]; + + pin_data->chip = dtcon_gpio_get_gpiochip(dtcg, i); + if (!pin_data->chip) { @@ -2390,14 +2513,20 @@ index 0000000..1dd0f91 + goto out_release_pin; + } + -+ dev_err(dev, "gpio #%d -> [%d] %-8s @ %s\n", -+ i, dtcg->pin_data[i].gpio_index, -+ dtcp->regstr, dtcp->np->name); ++ dev_err(dev, "gpio #%d -> %-8s @ %s\n", ++ i, dtcp->regstr, dtcp->np->name); + } + -+ platform_set_drvdata(pdev, dtcg); ++ err = gpiochip_add_data(&dtcg->chip, dtcg); ++ if (err) { ++ dev_err(dev, "Could not register gpio chip %d\n", err); ++ goto out_release_pin; ++ } + -+ dev_info(dev, "OK\n"); ++ /* advance base */ ++ dtcgf->gpio_base += count; ++ ++ platform_set_drvdata(pdev, dtcg); + + return 0; + @@ -2408,8 +2537,6 @@ index 0000000..1dd0f91 + dtcon_proxy_pin_release(proxy, pin_data->dtcp); + } + -+out_gpiochip_remove: -+ gpiochip_remove(&dtcg->chip); +out_destroy_proxy: + dtcon_proxy_destroy(dtcg->proxy, dtcon_gpio_function_fini); + return err; @@ -2452,12 +2579,12 @@ index 0000000..1dd0f91 +module_platform_driver(dtcon_gpio); +MODULE_AUTHOR("Pantelis Antoniou <pantelis.antoniou@konsulko.com>"); +MODULE_LICENSE("GPL"); -diff --git a/drivers/extcon/extcon-dt-con-uart.c b/drivers/extcon/extcon-dt-con-uart.c +diff --git a/drivers/extcon/extcon-dt-con-proxy.c b/drivers/extcon/extcon-dt-con-proxy.c new file mode 100644 -index 0000000..59418c9 +index 0000000..dbbbc0e --- /dev/null -+++ b/drivers/extcon/extcon-dt-con-uart.c -@@ -0,0 +1,66 @@ ++++ b/drivers/extcon/extcon-dt-con-proxy.c +@@ -0,0 +1,480 @@ +/* + * Copyright (C) 2016 Konsulko Group + * @@ -2480,56 +2607,470 @@ index 0000000..59418c9 +#include <linux/platform_device.h> +#include <linux/io.h> +#include <linux/of.h> ++#include <linux/of_device.h> ++#include <linux/slab.h> + +#include "extcon-dt-con.h" + -+static int dtcon_uart_probe(struct platform_device *pdev) ++static const struct of_device_id dtcon_proxy_of_match[] = { ++ { .compatible = "dtcon-uart", .data = "uart" }, ++ { .compatible = "dtcon-i2c", .data = "i2c" }, ++ { .compatible = "dtcon-spi", .data = "spi" }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, dtcon_proxy_of_match); ++ ++struct dtcon_proxy_data { ++ struct platform_device *pdev; ++ struct dtcon_proxy *proxy; ++ struct of_changeset ocs; ++ struct device_node *paramsnp; ++ int param_cells; ++}; ++ ++static int dtcon_proxy_parse_params(struct dtcon_proxy_data *dtcpd) ++{ ++ struct device *dev = &dtcpd->pdev->dev; ++ struct dtcon_proxy *proxy = dtcpd->proxy; ++ struct dtcon_function *dtcf = proxy->dtcf; ++ struct device_node *np; ++ struct dtcon_pin *dtcp; ++ const void *value; ++ int err, len; ++ u32 num; ++ ++ dtcpd->paramsnp = of_get_child_by_name(dtcf->np, "params"); ++ ++ /* no parameters? no problem */ ++ if (!dtcpd->paramsnp) ++ return -EINVAL; ++ ++ /* get number of param cells */ ++ if (of_property_read_u32(dtcpd->paramsnp, "#param-cells", &num)) ++ num = 2; ++ ++ dtcpd->param_cells = num; ++ ++ /* iterate over list of parameters */ ++ err = 0; ++ for_each_child_of_node(dtcpd->paramsnp, np) { ++ value = of_get_property(dev->of_node, np->name, &len); ++ if (!value) { ++ /* ignore non-required parameter */ ++ if (!of_property_read_bool(np, "required")) ++ continue; ++ /* missing required parameter */ ++ dev_err(dev, "%s: Missing required parameter %s\n", ++ dtcf->kind, np->name); ++err_out: ++ of_node_put(np); ++ err = -EINVAL; ++ goto out; ++ } ++ ++ /* we have a parameter; instantiate it */ ++ dev_dbg(dev, "%s: param %s\n", dtcf->kind, ++ np->name); ++ ++ /* connector-pin parameter <connector reg address> */ ++ if (of_property_read_bool(np, "connector-pin")) { ++ dtcp = dtcon_proxy_pin_request(proxy, value, len, 0); ++ if (!dtcp) { ++ dev_err(dev, "%s: failed to request %s's pin\n", ++ dtcf->kind, np->name); ++ goto err_out; ++ } ++ /* no need to keep dtcp around; it's on proxy's list */ ++ dev_info(dev, "%s: %s pin is @%s\n", dtcf->kind, ++ np->name, dtcp->np->name); ++ ++ dtcp->param = of_node_get(np); ++ /* need to iterate over the mux options for matches */ ++ } ++ } ++out: ++ return err; ++} ++ ++static int dtcon_proxy_grade_single(struct dtcon_proxy_data *dtcpd, ++ struct device_node *fnp, struct device_node *devnp, ++ struct device_node *muxnp) ++{ ++ struct device *dev = &dtcpd->pdev->dev; ++ struct dtcon_pin *dtcp; ++ struct dtcon_proxy *proxy = dtcpd->proxy; ++ int ret, paramsz, paramcells, i, count, len, match, score; ++ const char *param, *gpio_prop; ++ const __be32 *paramp; ++ bool avail; ++ u32 ph; ++ ++ if (!devnp) ++ return 0; ++ ++ paramcells = dtcpd->param_cells; ++ paramsz = paramcells * sizeof(u32); ++ ++ score = 0; ++ list_for_each_entry(dtcp, &proxy->proxy_pin_list, proxy_node) { ++ ++ param = dtcp->param->name; ++ paramp = of_get_property(muxnp, param, &len); ++ ++ /* no such parameter? */ ++ if (!paramp) { ++ /* GPIO parameters only on disabled devices */ ++ if (of_device_is_available(devnp)) { ++ dev_err(dev, "param %s with enabled device\n", param); ++ score = 0; ++ break; ++ } ++ ++ ret = of_property_read_string(dtcp->param, ++ "gpio-property", &gpio_prop); ++ if (ret) { ++ dev_err(dev, "no param %s\n", param); ++ score = 0; ++ break; ++ } ++ dtcp->proxy_gpio = true; ++ /* gpio matches have a low score */ ++ score++; ++ continue; ++ } ++ ++ /* not-there? malformed? bail out */ ++ if ((len % paramsz)) { ++ dev_err(dev, "malformed param %s\n", param); ++ score = 0; ++ break; ++ } ++ ++ count = len / paramsz; ++ ++ match = 0; ++ for (i = 0; i < count; i++, paramp += paramcells) { ++ /* get phandle of connector pin */ ++ ph = be32_to_cpu(paramp[0]); ++ if (ph != dtcp->np->phandle) ++ continue; ++ ++ avail = of_device_is_available(devnp); ++ /* when not preeneabled ++ * -> device must be disabled ++ * when preenabled ++ * -> device must be enabled ++ */ ++ if (of_property_read_bool(muxnp, "pre-enabled")) ++ match = avail; ++ else ++ match = !avail; ++ ++ if (match) { ++ dtcp->proxy_gpio = false; ++ /* pinmux changes only on disabled devices */ ++ if (!avail) { ++ ph = be32_to_cpu(paramp[1]); ++ dtcp->match_mux = ph; ++ } ++ score += (1 << 16); ++ break; ++ } ++ } ++ ++ if (!match) ++ return 0; ++ } ++ ++ return score; ++} ++ ++static int dtcon_proxy_instantiate(struct dtcon_proxy_data *dtcpd) ++{ ++ struct device *dev = &dtcpd->pdev->dev; ++ struct dtcon_proxy *proxy = dtcpd->proxy; ++ struct dtcon_function *dtcf = proxy->dtcf; ++ struct device_node *np, *fnp, *devnp, *muxnp, *best_devnp; ++ struct dtcon_pin *dtcp; ++ int err, len, count, score, best_score, arg_len; ++ const void *value; ++ const char *gpio_prop; ++ const void *arg_value; ++ void *data; ++ __be32 *muxp; ++ ++ err = 0; ++ ++ /* iterate over the device targets */ ++ best_score = 0; ++ best_devnp = NULL; ++ for_each_child_of_node(dtcf->np, fnp) { ++ devnp = of_parse_phandle(fnp, "device", 0); ++ if (!devnp) ++ continue; ++ for_each_child_of_node(fnp, muxnp) { ++ ++ score = dtcon_proxy_grade_single(dtcpd, fnp, ++ devnp, muxnp); ++ ++ if (score <= best_score) ++ continue; ++ ++ /* new best score */ ++ best_score = score; ++ of_node_put(best_devnp); ++ best_devnp = of_node_get(devnp); ++ list_for_each_entry(dtcp, &proxy->proxy_pin_list, ++ proxy_node) { ++ ++ /* if it's a GPIO do not select it */ ++ if (dtcp->proxy_gpio) ++ continue; ++ ++ of_node_put(dtcp->pinctrl); ++ dtcp->pinctrl = of_find_node_by_phandle( ++ dtcp->match_mux); ++ dtcp->match_mux = 0; ++ } ++ } ++ of_node_put(devnp); ++ } ++ ++ if (best_score == 0) { ++ dev_info(dev, "no matching proxy config\n"); ++ return -ENODEV; ++ } ++ ++ devnp = best_devnp; ++ best_devnp = NULL; ++ ++ dev_dbg(dev, "matches device %s\n", devnp->full_name); ++ ++ /* need to copy subdevices? */ ++ if (of_property_read_bool(dtcpd->paramsnp, "copy-subdevices")) { ++ for_each_available_child_of_node(dev->of_node, np) { ++ err = of_changeset_node_move(&dtcpd->ocs, np, devnp); ++ if (err) { ++ dev_err(dev, "Failed to move nodes\n"); ++ of_node_put(np); ++ goto err_out; ++ } ++ } ++ } ++ ++ /* changes only allowed to non-activated devices */ ++ if (!of_device_is_available(devnp)) { ++ ++ /* iterate over parameters */ ++ ++ /* iterate over list of parameters */ ++ for_each_child_of_node(dtcpd->paramsnp, np) { ++ if (!of_property_read_bool(np, "copy")) ++ continue; ++ ++ value = of_get_property(dev->of_node, np->name, &len); ++ if (!value) { ++ if (!of_property_read_bool(np, "required")) ++ continue; ++ dev_err(dev, "Missing required property %s\n", ++ np->name); ++ of_node_put(np); ++ err = -ENODEV; ++ goto err_out; ++ } ++ ++ of_changeset_update_property_copy(&dtcpd->ocs, devnp, ++ np->name, value, len); ++ ++ } ++ ++ /* generate pinctrl for each pin of the connector */ ++ if (of_property_read_bool(dtcpd->paramsnp, ++ "generate-pinctrl")) { ++ /* count the pinctrl entries we're going to need */ ++ count = 0; ++ list_for_each_entry(dtcp, &proxy->proxy_pin_list, ++ proxy_node) { ++ if (dtcp->pinctrl) ++ count++; ++ } ++ ++ if (count > 0) { ++ muxp = kzalloc(sizeof(u32) * count, GFP_KERNEL); ++ if (!muxp) { ++ dev_err(dev, ++ "Failed to allocate pinmux\n"); ++ err = -ENOMEM; ++ goto err_out; ++ } ++ ++ count = 0; ++ list_for_each_entry(dtcp, ++ &proxy->proxy_pin_list, ++ proxy_node) { ++ if (!dtcp->pinctrl) ++ continue; ++ muxp[count++] = cpu_to_be32( ++ dtcp->pinctrl->phandle); ++ } ++ ++ of_changeset_update_property_string(&dtcpd->ocs, ++ devnp, "pinctrl-names", ++ "default"); ++ of_changeset_update_property_copy(&dtcpd->ocs, ++ devnp, "pinctrl-0", muxp, ++ sizeof(u32) * count); ++ ++ kfree(muxp); ++ } ++ } ++ ++ /* fill in gpio properties if required */ ++ list_for_each_entry(dtcp, &proxy->proxy_pin_list, proxy_node) { ++ if (!dtcp->proxy_gpio) ++ continue; ++ err = of_property_read_string(dtcp->param, ++ "gpio-property", &gpio_prop); ++ if (err) { ++ dev_err(dev, ++ "Failed to read gpio-property name %s\n", ++ dtcp->param->name); ++ goto err_out; ++ } ++ value = of_get_property(dtcp->np, "gpio", &len); ++ if (!value) { ++ dev_err(dev, ++ "Failed on gpio name %s - %s\n", ++ dtcp->param->name, dtcp->np->name); ++ err = -EINVAL; ++ goto err_out; ++ } ++ arg_value = of_get_property(dtcp->param, ++ "gpio-args", &arg_len); ++ if (!arg_value) { ++ dev_err(dev, ++ "Failed on gpio-args name %s - %s\n", ++ dtcp->param->name, dtcp->param->name); ++ err = -EINVAL; ++ goto err_out; ++ } ++ data = kmalloc(len + arg_len, GFP_KERNEL); ++ if (!data) { ++ dev_err(dev, ++ "Failed to allocate %s - %s\n", ++ dtcp->param->name, dtcp->param->name); ++ err = -ENOMEM; ++ goto err_out; ++ } ++ memcpy(data, value, len); ++ memcpy(data + len, arg_value, arg_len); ++ of_changeset_add_property_copy(&dtcpd->ocs, devnp, ++ gpio_prop, data, len + arg_len); ++ kfree(data); ++ } ++ ++ /* enabled target device and go */ ++ of_changeset_update_property_string(&dtcpd->ocs, devnp, ++ "status", "okay"); ++ } ++ ++ of_changeset_apply(&dtcpd->ocs); ++ ++ of_node_put(devnp); ++ of_node_put(muxnp); ++ ++ return 0; ++ ++err_out: ++ of_changeset_destroy(&dtcpd->ocs); ++ ++ of_node_put(devnp); ++ ++ return err; ++} ++ ++static int dtcon_proxy_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct dtcon_proxy *proxy; ++ struct dtcon_function *dtcf; ++ struct dtcon_proxy_data *dtcpd; ++ const struct of_device_id *of_id; ++ const char *function; ++ int err; ++ ++ of_id = of_match_device(dtcon_proxy_of_match, dev); ++ if (!of_id) { ++ dev_err(dev, "Could not match device\n"); ++ return -ENODEV; ++ } ++ function = of_id->data; ++ ++ dtcpd = devm_kzalloc(dev, sizeof(*dtcpd), GFP_KERNEL); ++ if (!dtcpd) { ++ dev_err(dev, "Failed to allocate device data\n"); ++ return -ENOMEM; ++ } ++ dtcpd->pdev = pdev; ++ of_changeset_init(&dtcpd->ocs); + -+ proxy = dtcon_proxy_create(pdev, "uart", NULL); ++ proxy = dtcon_proxy_create(pdev, function, NULL); + if (IS_ERR(proxy)) + return PTR_ERR(proxy); + -+ platform_set_drvdata(pdev, proxy); ++ dtcpd->proxy = proxy; ++ ++ dtcf = proxy->dtcf; ++ ++ platform_set_drvdata(pdev, dtcpd); ++ ++ err = dtcon_proxy_parse_params(dtcpd); ++ if (err) { ++ dev_err(dev, "Failed to parse params\n"); ++ return err; ++ } ++ ++ err = dtcon_proxy_instantiate(dtcpd); ++ if (err) { ++ dev_err(dev, "Failed to instantiate device\n"); ++ return err; ++ } + + dev_info(dev, "OK\n"); + + return 0; +} + -+static int dtcon_uart_remove(struct platform_device *pdev) ++static int dtcon_proxy_remove(struct platform_device *pdev) +{ -+ dtcon_proxy_destroy(platform_get_drvdata(pdev), NULL); ++ struct dtcon_proxy_data *dtcpd = platform_get_drvdata(pdev); ++ ++ of_changeset_revert(&dtcpd->ocs); ++ of_changeset_destroy(&dtcpd->ocs); ++ dtcon_proxy_destroy(dtcpd->proxy, NULL); ++ of_node_put(dtcpd->paramsnp); + return 0; +} + -+static const struct of_device_id dtcon_uart_of_match[] = { -+ { .compatible = "dtcon-uart", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, dtcon_uart_of_match); -+ -+static struct platform_driver dtcon_uart = { -+ .probe = dtcon_uart_probe, -+ .remove = dtcon_uart_remove, ++static struct platform_driver dtcon_proxy = { ++ .probe = dtcon_proxy_probe, ++ .remove = dtcon_proxy_remove, + .driver = { -+ .name = "dtcon-uart", ++ .name = "dtcon-proxy", + .owner = THIS_MODULE, -+ .of_match_table = dtcon_uart_of_match, ++ .of_match_table = dtcon_proxy_of_match, + } +}; + -+module_platform_driver(dtcon_uart); ++module_platform_driver(dtcon_proxy); +MODULE_AUTHOR("Pantelis Antoniou <pantelis.antoniou@konsulko.com>"); +MODULE_LICENSE("GPL"); diff --git a/drivers/extcon/extcon-dt-con.c b/drivers/extcon/extcon-dt-con.c new file mode 100644 -index 0000000..a51f605 +index 0000000..fbc1a35 --- /dev/null +++ b/drivers/extcon/extcon-dt-con.c -@@ -0,0 +1,485 @@ +@@ -0,0 +1,491 @@ +/* + * drivers/extcon/extcon-dt-conn.c + * @@ -2686,7 +3227,7 @@ index 0000000..a51f605 + } + + /* populate anything in plugged */ -+ of_platform_default_populate(dtcd->plugged, NULL, dev); ++ of_platform_default_populate(dev->of_node, NULL, dev); + + dev_info(dev, "OK\n"); + @@ -2741,7 +3282,7 @@ index 0000000..a51f605 + }, + { }, +}; -+MODULE_DEVICE_TABLE(of, capemgr_of_match); ++MODULE_DEVICE_TABLE(of, dtcon_of_match); + +static struct platform_driver dtcon_driver = { + .probe = dtcon_probe, @@ -2892,6 +3433,12 @@ index 0000000..a51f605 + list_del(&dtcp->proxy_node); + dtcp->proxy = NULL; + dtcp->data = NULL; ++ ++ /* proxy device data release */ ++ of_node_put(dtcp->param); ++ of_node_put(dtcp->pinctrl); ++ dtcp->param = NULL; ++ dtcp->pinctrl = NULL; + return 0; +} +EXPORT_SYMBOL(dtcon_proxy_pin_release); @@ -2991,7 +3538,7 @@ index 0000000..a51f605 + dtcf = proxy->dtcf; + dtcd = dtcf->dtcd; + -+ list_del(&dtcp->node); ++ list_del(&proxy->node); + + /* last proxy; remove function */ + if (list_empty(&dtcf->proxy_list)) { @@ -3017,10 +3564,10 @@ index 0000000..a51f605 +MODULE_ALIAS("platform:extcon-dt-con"); diff --git a/drivers/extcon/extcon-dt-con.h b/drivers/extcon/extcon-dt-con.h new file mode 100644 -index 0000000..ac54499 +index 0000000..9f08f1d --- /dev/null +++ b/drivers/extcon/extcon-dt-con.h -@@ -0,0 +1,85 @@ +@@ -0,0 +1,93 @@ +/* + * dt-con.h + * @@ -3049,6 +3596,14 @@ index 0000000..ac54499 + struct dtcon_proxy *proxy; + struct list_head proxy_node; + void *data; ++ ++ /* proxy device data */ ++ struct device_node *param; ++ ++ /* pinctrl config device node */ ++ bool proxy_gpio; ++ struct device_node *pinctrl; ++ phandle match_mux; +}; + +struct dtcon_data { @@ -3107,5 +3662,5 @@ index 0000000..ac54499 + +#endif /* __LINUX_EXTCON_DT_CON_H */ -- -2.8.0.rc3 +2.8.1 diff --git a/patches/bbb_overlays/0031-boneblack-defconfig.patch b/patches/bbb_overlays/0041-boneblack-defconfig.patch similarity index 98% rename from patches/bbb_overlays/0031-boneblack-defconfig.patch rename to patches/bbb_overlays/0041-boneblack-defconfig.patch index 304978132dd155c35ec5711480f2cc63ebf41e65..b92e28744f18c93c884371fb9b4b29b533ecae26 100644 --- a/patches/bbb_overlays/0031-boneblack-defconfig.patch +++ b/patches/bbb_overlays/0041-boneblack-defconfig.patch @@ -1,25 +1,24 @@ -From aced9712b6e094ef10aa1bf94f4c52967f4869ff Mon Sep 17 00:00:00 2001 +From 17df1d50e0bf069cd08b30aac6bb743f70304fde Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou <pantelis.antoniou@konsulko.com> Date: Sat, 21 Jun 2014 17:38:38 +0300 -Subject: [PATCH 31/38] boneblack defconfig +Subject: [PATCH 41/41] boneblack defconfig Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com> --- - arch/arm/configs/am335x-boneblack_defconfig | 1247 +++++++++++++++++++++++++++ - 1 file changed, 1247 insertions(+) + arch/arm/configs/am335x-boneblack_defconfig | 1241 +++++++++++++++++++++++++++ + 1 file changed, 1241 insertions(+) create mode 100644 arch/arm/configs/am335x-boneblack_defconfig diff --git a/arch/arm/configs/am335x-boneblack_defconfig b/arch/arm/configs/am335x-boneblack_defconfig new file mode 100644 -index 0000000..3d6eafd +index 0000000..e6cd172 --- /dev/null +++ b/arch/arm/configs/am335x-boneblack_defconfig -@@ -0,0 +1,1247 @@ +@@ -0,0 +1,1241 @@ +CONFIG_KERNEL_LZO=y +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +# CONFIG_CROSS_MEMORY_ATTACH is not set -+CONFIG_FHANDLE=y +CONFIG_USELIB=y +CONFIG_AUDIT=y +CONFIG_NO_HZ=y @@ -125,7 +124,6 @@ index 0000000..3d6eafd +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m -+CONFIG_INET_LRO=m +CONFIG_INET_UDP_DIAG=m +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_HSTCP=m @@ -205,25 +203,24 @@ index 0000000..3d6eafd +CONFIG_BATMAN_ADV_DAT=y +CONFIG_OPENVSWITCH=m +CONFIG_VSOCKETS=m -+CONFIG_NETLINK_MMAP=y +CONFIG_NETLINK_DIAG=m +CONFIG_BPF_JIT=y +CONFIG_CAN=m +CONFIG_CAN_VCAN=m +CONFIG_CAN_SLCAN=m -+CONFIG_CAN_TI_HECC=m +CONFIG_CAN_FLEXCAN=m +CONFIG_CAN_GRCAN=m -+CONFIG_CAN_SJA1000=m ++CONFIG_CAN_TI_HECC=m +CONFIG_CAN_C_CAN=m +CONFIG_CAN_C_CAN_PLATFORM=m ++CONFIG_CAN_SJA1000=m ++CONFIG_CAN_SOFTING=m +CONFIG_CAN_MCP251X=m +CONFIG_CAN_EMS_USB=m +CONFIG_CAN_ESD_USB2=m +CONFIG_CAN_KVASER_USB=m +CONFIG_CAN_PEAK_USB=m +CONFIG_CAN_8DEV_USB=m -+CONFIG_CAN_SOFTING=m +CONFIG_IRDA=m +CONFIG_IRLAN=m +CONFIG_IRNET=m @@ -284,7 +281,6 @@ index 0000000..3d6eafd +CONFIG_NFC_NCI_SPI=m +CONFIG_NFC_HCI=m +CONFIG_NFC_SHDLC=y -+CONFIG_NFC_PN533=m +CONFIG_NFC_WILINK=m +CONFIG_NFC_SIM=m +CONFIG_NFC_PN544_I2C=m @@ -317,7 +313,6 @@ index 0000000..3d6eafd +CONFIG_HMC6352=m +CONFIG_BMP085_I2C=m +CONFIG_BONE_CAPEMGR=y -+CONFIG_DEV_OVERLAYMGR=y +CONFIG_EEPROM_AT24=y +CONFIG_TI_ST=m +CONFIG_SCSI=y @@ -768,6 +763,7 @@ index 0000000..3d6eafd +CONFIG_DRM_I2C_NXP_TDA998X=y +CONFIG_DRM_UDL=m +CONFIG_DRM_OMAP=m ++CONFIG_OMAP2_DSS=m +CONFIG_OMAP2_DSS_SDI=y +CONFIG_OMAP2_DSS_DSI=y +CONFIG_DRM_TILCDC=y @@ -776,7 +772,6 @@ index 0000000..3d6eafd +CONFIG_FB_TILEBLITTING=y +CONFIG_FB_UDL=m +CONFIG_FB_SIMPLE=y -+CONFIG_FB_SSD1307=y +CONFIG_LCD_CLASS_DEVICE=y +CONFIG_LCD_ILI9320=y +CONFIG_LCD_PLATFORM=y @@ -873,7 +868,6 @@ index 0000000..3d6eafd +CONFIG_HID_ROCCAT=m +CONFIG_HID_SAITEK=m +CONFIG_HID_SAMSUNG=m -+CONFIG_HID_SONY=m +CONFIG_HID_SPEEDLINK=m +CONFIG_HID_STEELSERIES=m +CONFIG_HID_SUNPLUS=m @@ -1090,9 +1084,7 @@ index 0000000..3d6eafd +CONFIG_R8188EU=m +CONFIG_ADIS16201=m +CONFIG_ADIS16203=m -+CONFIG_ADIS16204=m +CONFIG_ADIS16209=m -+CONFIG_ADIS16220=m +CONFIG_ADIS16240=m +CONFIG_LIS3L02DQ=m +CONFIG_AD7606=m @@ -1124,10 +1116,13 @@ index 0000000..3d6eafd +CONFIG_AD2S1200=m +CONFIG_AD2S1210=m +CONFIG_LTE_GDM724X=m ++CONFIG_LNET=m +CONFIG_LUSTRE_FS=m +CONFIG_MAILBOX=y +CONFIG_STE_MODEM_RPROC=m +CONFIG_EXTCON_DT_CON=y ++CONFIG_EXTCON_DT_CON_PROXY=y ++CONFIG_EXTCON_DT_CON_GPIO=y +CONFIG_IIO=y +CONFIG_BMA180=m +CONFIG_HID_SENSOR_ACCEL_3D=m @@ -1191,6 +1186,7 @@ index 0000000..3d6eafd +CONFIG_IIO_SYSFS_TRIGGER=y +CONFIG_IIO_ST_PRESS=m +CONFIG_TMP006=m ++CONFIG_PWM=y +CONFIG_PWM_PCA9685=m +CONFIG_PWM_TIECAP=y +CONFIG_PWM_TIEHRPWM=y @@ -1198,6 +1194,7 @@ index 0000000..3d6eafd +CONFIG_PWM_TWL_LED=m +CONFIG_RESET_CONTROLLER=y +CONFIG_GENERIC_PHY=y ++CONFIG_FPGA=y +CONFIG_EXT2_FS=y +CONFIG_EXT3_FS=y +CONFIG_FANOTIFY=y @@ -1247,9 +1244,6 @@ index 0000000..3d6eafd +CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_DEV_OMAP_SHAM=y +CONFIG_CRYPTO_DEV_OMAP_AES=y -+CONFIG_ASYMMETRIC_KEY_TYPE=m -+CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=m -+CONFIG_X509_CERTIFICATE_PARSER=m +CONFIG_CRC_CCITT=y +CONFIG_CRC_ITU_T=y +CONFIG_CRC7=y @@ -1263,5 +1257,5 @@ index 0000000..3d6eafd +CONFIG_FONT_8x16=y +CONFIG_FONT_MINI_4x6=y -- -2.8.0.rc3 +2.8.1 diff --git a/patches/bbb_overlays/dtc/0001-scripts-dtc-Update-to-upstream-version-overlays.patch b/patches/bbb_overlays/dtc/0001-scripts-dtc-Update-to-upstream-version-overlays.patch deleted file mode 100644 index 66fe736bd9ea00bf88e6d459cd174e9f60e9d793..0000000000000000000000000000000000000000 --- a/patches/bbb_overlays/dtc/0001-scripts-dtc-Update-to-upstream-version-overlays.patch +++ /dev/null @@ -1,3206 +0,0 @@ -From 844a63fc5e8ab2480f9d69fca9b187b9dd88e193 Mon Sep 17 00:00:00 2001 -From: Robert Nelson <robertcnelson@gmail.com> -Date: Mon, 21 Mar 2016 10:15:27 -0500 -Subject: [PATCH] scripts/dtc: Update to upstream version overlays - -Signed-off-by: Robert Nelson <robertcnelson@gmail.com> ---- - scripts/dtc/checks.c | 132 ++++++- - scripts/dtc/dtc-lexer.l | 5 + - scripts/dtc/dtc-lexer.lex.c_shipped | 539 ++++++++++++++------------ - scripts/dtc/dtc-parser.tab.c_shipped | 732 ++++++++++++++++++----------------- - scripts/dtc/dtc-parser.tab.h_shipped | 54 +-- - scripts/dtc/dtc-parser.y | 22 +- - scripts/dtc/dtc.c | 9 +- - scripts/dtc/dtc.h | 40 ++ - scripts/dtc/flattree.c | 206 +++++++++- - scripts/dtc/libfdt/fdt_ro.c | 6 +- - scripts/dtc/libfdt/libfdt.h | 60 +-- - scripts/dtc/version_gen.h | 2 +- - 12 files changed, 1132 insertions(+), 675 deletions(-) - -diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c -index 0c03ac9..207a923 100644 ---- a/scripts/dtc/checks.c -+++ b/scripts/dtc/checks.c -@@ -294,6 +294,30 @@ static void check_node_name_format(struct check *c, struct node *dt, - } - NODE_ERROR(node_name_format, NULL, &node_name_chars); - -+static void check_unit_address_vs_reg(struct check *c, struct node *dt, -+ struct node *node) -+{ -+ const char *unitname = get_unitname(node); -+ struct property *prop = get_property(node, "reg"); -+ -+ if (!prop) { -+ prop = get_property(node, "ranges"); -+ if (prop && !prop->val.len) -+ prop = NULL; -+ } -+ -+ if (prop) { -+ if (!unitname[0]) -+ FAIL(c, "Node %s has a reg or ranges property, but no unit name", -+ node->fullpath); -+ } else { -+ if (unitname[0]) -+ FAIL(c, "Node %s has a unit name, but no reg property", -+ node->fullpath); -+ } -+} -+NODE_WARNING(unit_address_vs_reg, NULL); -+ - static void check_property_name_chars(struct check *c, struct node *dt, - struct node *node, struct property *prop) - { -@@ -458,6 +482,8 @@ static void fixup_phandle_references(struct check *c, struct node *dt, - struct node *node, struct property *prop) - { - struct marker *m = prop->val.markers; -+ struct fixup *f, **fp; -+ struct fixup_entry *fe, **fep; - struct node *refnode; - cell_t phandle; - -@@ -466,14 +492,73 @@ static void fixup_phandle_references(struct check *c, struct node *dt, - - refnode = get_node_by_ref(dt, m->ref); - if (! refnode) { -- FAIL(c, "Reference to non-existent node or label \"%s\"\n", -- m->ref); -+ if (!dt->is_plugin) { -+ FAIL(c, "Reference to non-existent node or label \"%s\"\n", -+ m->ref); -+ continue; -+ } -+ -+ /* allocate fixup entry */ -+ fe = xmalloc(sizeof(*fe)); -+ -+ fe->node = node; -+ fe->prop = prop; -+ fe->offset = m->offset; -+ fe->next = NULL; -+ -+ /* search for an already existing fixup */ -+ for_each_fixup(dt, f) -+ if (strcmp(f->ref, m->ref) == 0) -+ break; -+ -+ /* no fixup found, add new */ -+ if (f == NULL) { -+ f = xmalloc(sizeof(*f)); -+ f->ref = m->ref; -+ f->entries = NULL; -+ f->next = NULL; -+ -+ /* add it to the tree */ -+ fp = &dt->fixups; -+ while (*fp) -+ fp = &(*fp)->next; -+ *fp = f; -+ } -+ -+ /* and now append fixup entry */ -+ fep = &f->entries; -+ while (*fep) -+ fep = &(*fep)->next; -+ *fep = fe; -+ -+ /* mark the entry as unresolved */ -+ *((cell_t *)(prop->val.val + m->offset)) = -+ cpu_to_fdt32(0xdeadbeef); - continue; - } - -+ /* if it's a local reference, we need to record it */ -+ if (symbol_fixup_support) { -+ -+ /* allocate a new local fixup entry */ -+ fe = xmalloc(sizeof(*fe)); -+ -+ fe->node = node; -+ fe->prop = prop; -+ fe->offset = m->offset; -+ fe->next = NULL; -+ -+ /* append it to the local fixups */ -+ fep = &dt->local_fixups; -+ while (*fep) -+ fep = &(*fep)->next; -+ *fep = fe; -+ } -+ - phandle = get_node_phandle(dt, refnode); - *((cell_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle); - } -+ - } - ERROR(phandle_references, NULL, NULL, fixup_phandle_references, NULL, - &duplicate_node_names, &explicit_phandles); -@@ -652,6 +737,45 @@ static void check_obsolete_chosen_interrupt_controller(struct check *c, - } - TREE_WARNING(obsolete_chosen_interrupt_controller, NULL); - -+static void check_auto_label_phandles(struct check *c, struct node *dt, -+ struct node *node) -+{ -+ struct label *l; -+ struct symbol *s, **sp; -+ int has_label; -+ -+ if (!symbol_fixup_support) -+ return; -+ -+ has_label = 0; -+ for_each_label(node->labels, l) { -+ has_label = 1; -+ break; -+ } -+ -+ if (!has_label) -+ return; -+ -+ /* force allocation of a phandle for this node */ -+ (void)get_node_phandle(dt, node); -+ -+ /* add the symbol */ -+ for_each_label(node->labels, l) { -+ -+ s = xmalloc(sizeof(*s)); -+ s->label = l; -+ s->node = node; -+ s->next = NULL; -+ -+ /* add it to the symbols list */ -+ sp = &dt->symbols; -+ while (*sp) -+ sp = &((*sp)->next); -+ *sp = s; -+ } -+} -+NODE_WARNING(auto_label_phandles, NULL); -+ - static struct check *check_table[] = { - &duplicate_node_names, &duplicate_property_names, - &node_name_chars, &node_name_format, &property_name_chars, -@@ -667,9 +791,13 @@ static struct check *check_table[] = { - - &addr_size_cells, ®_format, &ranges_format, - -+ &unit_address_vs_reg, -+ - &avoid_default_addr_size, - &obsolete_chosen_interrupt_controller, - -+ &auto_label_phandles, -+ - &always_fail, - }; - -diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l -index 790fbf6..40bbc87 100644 ---- a/scripts/dtc/dtc-lexer.l -+++ b/scripts/dtc/dtc-lexer.l -@@ -121,6 +121,11 @@ static void lexical_error(const char *fmt, ...); - return DT_V1; - } - -+<*>"/plugin/" { -+ DPRINT("Keyword: /plugin/\n"); -+ return DT_PLUGIN; -+ } -+ - <*>"/memreserve/" { - DPRINT("Keyword: /memreserve/\n"); - BEGIN_DEFAULT(); -diff --git a/scripts/dtc/dtc-lexer.lex.c_shipped b/scripts/dtc/dtc-lexer.lex.c_shipped -index ba525c2..d29e2a9 100644 ---- a/scripts/dtc/dtc-lexer.lex.c_shipped -+++ b/scripts/dtc/dtc-lexer.lex.c_shipped -@@ -8,8 +8,8 @@ - - #define FLEX_SCANNER - #define YY_FLEX_MAJOR_VERSION 2 --#define YY_FLEX_MINOR_VERSION 5 --#define YY_FLEX_SUBMINOR_VERSION 39 -+#define YY_FLEX_MINOR_VERSION 6 -+#define YY_FLEX_SUBMINOR_VERSION 0 - #if YY_FLEX_SUBMINOR_VERSION > 0 - #define FLEX_BETA - #endif -@@ -211,7 +211,7 @@ struct yy_buffer_state - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ -- yy_size_t yy_n_chars; -+ int yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to -@@ -281,7 +281,7 @@ static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ - - /* yy_hold_char holds the character lost when yytext is formed. */ - static char yy_hold_char; --static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */ -+static int yy_n_chars; /* number of characters read into yy_ch_buf */ - yy_size_t yyleng; - - /* Points to current character in buffer. */ -@@ -342,7 +342,7 @@ void yyfree (void * ); - - /* Begin user sect3 */ - --#define yywrap() 1 -+#define yywrap() (/*CONSTCOND*/1) - #define YY_SKIP_YYWRAP - - typedef unsigned char YY_CHAR; -@@ -356,11 +356,17 @@ extern int yylineno; - int yylineno = 1; - - extern char *yytext; -+#ifdef yytext_ptr -+#undef yytext_ptr -+#endif - #define yytext_ptr yytext - - static yy_state_type yy_get_previous_state (void ); - static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); - static int yy_get_next_buffer (void ); -+#if defined(__GNUC__) && __GNUC__ >= 3 -+__attribute__((__noreturn__)) -+#endif - static void yy_fatal_error (yyconst char msg[] ); - - /* Done after the current pattern has been matched and before the -@@ -373,8 +379,8 @@ static void yy_fatal_error (yyconst char msg[] ); - *yy_cp = '\0'; \ - (yy_c_buf_p) = yy_cp; - --#define YY_NUM_RULES 30 --#define YY_END_OF_BUFFER 31 -+#define YY_NUM_RULES 31 -+#define YY_END_OF_BUFFER 32 - /* This struct is not used in this scanner, - but its presence is necessary. */ - struct yy_trans_info -@@ -382,28 +388,29 @@ struct yy_trans_info - flex_int32_t yy_verify; - flex_int32_t yy_nxt; - }; --static yyconst flex_int16_t yy_accept[159] = -+static yyconst flex_int16_t yy_accept[166] = - { 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 31, 29, -- 18, 18, 29, 29, 29, 29, 29, 29, 29, 29, -- 29, 29, 29, 29, 29, 29, 15, 16, 16, 29, -- 16, 10, 10, 18, 26, 0, 3, 0, 27, 12, -- 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, -- 21, 23, 25, 24, 22, 0, 9, 28, 0, 0, -- 0, 14, 14, 16, 16, 16, 10, 10, 10, 0, -- 12, 0, 11, 0, 0, 0, 20, 0, 0, 0, -- 0, 0, 0, 0, 0, 16, 10, 10, 10, 0, -- 13, 19, 0, 0, 0, 0, 0, 0, 0, 0, -- -- 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 16, 6, 0, 0, 0, 0, 0, 0, 2, -- 0, 0, 0, 0, 0, 0, 0, 0, 4, 17, -- 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, -- 5, 8, 0, 0, 0, 0, 7, 0 -+ 0, 0, 0, 0, 0, 0, 0, 0, 32, 30, -+ 19, 19, 30, 30, 30, 30, 30, 30, 30, 30, -+ 30, 30, 30, 30, 30, 30, 16, 17, 17, 30, -+ 17, 11, 11, 19, 27, 0, 3, 0, 28, 13, -+ 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, -+ 0, 22, 24, 26, 25, 23, 0, 10, 29, 0, -+ 0, 0, 15, 15, 17, 17, 17, 11, 11, 11, -+ 0, 13, 0, 12, 0, 0, 0, 21, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 17, 11, 11, -+ 11, 0, 14, 20, 0, 0, 0, 0, 0, 0, -+ -+ 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 17, 7, 0, 0, 0, -+ 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 4, 18, 0, 0, 5, 2, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 1, 0, 0, 0, 0, 6, 9, 0, -+ 0, 0, 0, 8, 0 - } ; - --static yyconst flex_int32_t yy_ec[256] = -+static yyconst YY_CHAR yy_ec[256] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, - 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, -@@ -416,9 +423,9 @@ static yyconst flex_int32_t yy_ec[256] = - 22, 22, 22, 22, 24, 22, 22, 25, 22, 22, - 1, 26, 27, 1, 22, 1, 21, 28, 29, 30, - -- 31, 21, 22, 22, 32, 22, 22, 33, 34, 35, -- 36, 37, 22, 38, 39, 40, 41, 42, 22, 25, -- 43, 22, 44, 45, 46, 1, 1, 1, 1, 1, -+ 31, 21, 32, 22, 33, 22, 22, 34, 35, 36, -+ 37, 38, 22, 39, 40, 41, 42, 43, 22, 25, -+ 44, 22, 45, 46, 47, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -@@ -435,163 +442,165 @@ static yyconst flex_int32_t yy_ec[256] = - 1, 1, 1, 1, 1 - } ; - --static yyconst flex_int32_t yy_meta[47] = -+static yyconst YY_CHAR yy_meta[48] = - { 0, - 1, 1, 1, 1, 1, 1, 2, 3, 1, 2, - 2, 2, 4, 5, 5, 5, 6, 1, 1, 1, - 7, 8, 8, 8, 8, 1, 1, 7, 7, 7, - 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, -- 8, 8, 8, 3, 1, 4 -+ 8, 8, 8, 8, 3, 1, 4 - } ; - --static yyconst flex_int16_t yy_base[173] = -+static yyconst flex_uint16_t yy_base[180] = - { 0, -- 0, 383, 34, 382, 65, 381, 37, 105, 387, 391, -- 54, 111, 367, 110, 109, 109, 112, 41, 366, 104, -- 367, 338, 124, 117, 0, 144, 391, 0, 121, 0, -- 135, 155, 140, 179, 391, 160, 391, 379, 391, 0, -- 368, 141, 391, 167, 370, 376, 346, 103, 342, 345, -- 391, 391, 391, 391, 391, 358, 391, 391, 175, 342, -- 338, 391, 355, 0, 185, 339, 184, 347, 346, 0, -- 0, 322, 175, 357, 175, 363, 352, 324, 330, 323, -- 332, 326, 201, 324, 329, 322, 391, 333, 181, 309, -- 391, 341, 340, 313, 320, 338, 178, 311, 146, 317, -- -- 314, 315, 335, 331, 303, 300, 309, 299, 308, 188, -- 336, 335, 391, 305, 320, 281, 283, 271, 203, 288, -- 281, 271, 266, 264, 245, 242, 208, 104, 391, 391, -- 244, 218, 204, 219, 206, 224, 201, 212, 204, 229, -- 215, 208, 207, 200, 219, 391, 233, 221, 200, 181, -- 391, 391, 149, 122, 86, 41, 391, 391, 245, 251, -- 259, 263, 267, 273, 280, 284, 292, 300, 304, 310, -- 318, 326 -+ 0, 393, 35, 392, 66, 391, 38, 107, 397, 401, -+ 55, 113, 377, 112, 111, 111, 114, 42, 376, 106, -+ 377, 347, 126, 120, 0, 147, 401, 0, 124, 0, -+ 137, 158, 170, 163, 401, 153, 401, 389, 401, 0, -+ 378, 120, 401, 131, 380, 386, 355, 139, 351, 355, -+ 351, 401, 401, 401, 401, 401, 367, 401, 401, 185, -+ 350, 346, 401, 364, 0, 185, 347, 189, 356, 355, -+ 0, 0, 330, 180, 366, 141, 372, 361, 332, 338, -+ 331, 341, 334, 326, 205, 331, 337, 329, 401, 341, -+ 167, 316, 401, 349, 348, 320, 328, 346, 180, 318, -+ -+ 324, 209, 324, 320, 322, 342, 338, 309, 306, 315, -+ 305, 315, 312, 192, 342, 341, 401, 293, 306, 282, -+ 268, 252, 255, 203, 285, 282, 272, 268, 252, 233, -+ 232, 239, 208, 107, 401, 401, 238, 211, 401, 211, -+ 212, 208, 228, 203, 215, 207, 233, 222, 212, 211, -+ 203, 227, 401, 237, 225, 204, 185, 401, 401, 149, -+ 128, 88, 42, 401, 401, 253, 259, 267, 271, 275, -+ 281, 288, 292, 300, 308, 312, 318, 326, 334 - } ; - --static yyconst flex_int16_t yy_def[173] = -+static yyconst flex_int16_t yy_def[180] = - { 0, -- 158, 1, 1, 3, 158, 5, 1, 1, 158, 158, -- 158, 158, 158, 159, 160, 161, 158, 158, 158, 158, -- 162, 158, 158, 158, 163, 162, 158, 164, 165, 164, -- 164, 158, 158, 158, 158, 159, 158, 159, 158, 166, -- 158, 161, 158, 161, 167, 168, 158, 158, 158, 158, -- 158, 158, 158, 158, 158, 162, 158, 158, 158, 158, -- 158, 158, 162, 164, 165, 164, 158, 158, 158, 169, -- 166, 170, 161, 167, 167, 168, 158, 158, 158, 158, -- 158, 158, 158, 158, 158, 164, 158, 158, 169, 170, -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- -- 158, 164, 158, 158, 158, 158, 158, 158, 158, 171, -- 158, 164, 158, 158, 158, 158, 158, 158, 171, 158, -- 171, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- 172, 158, 158, 158, 172, 158, 172, 158, 158, 158, -- 158, 158, 158, 158, 158, 158, 158, 0, 158, 158, -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- 158, 158 -+ 165, 1, 1, 3, 165, 5, 1, 1, 165, 165, -+ 165, 165, 165, 166, 167, 168, 165, 165, 165, 165, -+ 169, 165, 165, 165, 170, 169, 165, 171, 172, 171, -+ 171, 165, 165, 165, 165, 166, 165, 166, 165, 173, -+ 165, 168, 165, 168, 174, 175, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 169, 165, 165, 165, -+ 165, 165, 165, 169, 171, 172, 171, 165, 165, 165, -+ 176, 173, 177, 168, 174, 174, 175, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 171, 165, 165, -+ 176, 177, 165, 165, 165, 165, 165, 165, 165, 165, -+ -+ 165, 165, 165, 165, 171, 165, 165, 165, 165, 165, -+ 165, 165, 165, 178, 165, 171, 165, 165, 165, 165, -+ 165, 165, 165, 178, 165, 178, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 179, 165, 165, -+ 165, 179, 165, 179, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 0, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165 - } ; - --static yyconst flex_int16_t yy_nxt[438] = -+static yyconst flex_uint16_t yy_nxt[449] = - { 0, - 10, 11, 12, 11, 13, 14, 10, 15, 16, 10, - 10, 10, 17, 10, 10, 10, 10, 18, 19, 20, - 21, 21, 21, 21, 21, 10, 10, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, -- 21, 21, 21, 10, 22, 10, 24, 25, 25, 25, -- 32, 33, 33, 157, 26, 34, 34, 34, 51, 52, -- 27, 26, 26, 26, 26, 10, 11, 12, 11, 13, -- 14, 28, 15, 16, 28, 28, 28, 24, 28, 28, -- 28, 10, 18, 19, 20, 29, 29, 29, 29, 29, -- 30, 10, 29, 29, 29, 29, 29, 29, 29, 29, -- -- 29, 29, 29, 29, 29, 29, 29, 29, 10, 22, -- 10, 23, 34, 34, 34, 37, 39, 43, 32, 33, -- 33, 45, 54, 55, 46, 59, 45, 64, 156, 46, -- 64, 64, 64, 79, 44, 38, 59, 57, 134, 47, -- 135, 48, 80, 49, 47, 50, 48, 99, 61, 43, -- 50, 110, 41, 67, 67, 67, 60, 63, 63, 63, -- 57, 155, 68, 69, 63, 37, 44, 66, 67, 67, -- 67, 63, 63, 63, 63, 73, 59, 68, 69, 70, -- 34, 34, 34, 43, 75, 38, 154, 92, 83, 83, -- 83, 64, 44, 120, 64, 64, 64, 67, 67, 67, -- -- 44, 57, 99, 68, 69, 107, 68, 69, 120, 127, -- 108, 153, 152, 121, 83, 83, 83, 133, 133, 133, -- 146, 133, 133, 133, 146, 140, 140, 140, 121, 141, -- 140, 140, 140, 151, 141, 158, 150, 149, 148, 144, -- 147, 143, 142, 139, 147, 36, 36, 36, 36, 36, -- 36, 36, 36, 40, 138, 137, 136, 40, 40, 42, -- 42, 42, 42, 42, 42, 42, 42, 56, 56, 56, -- 56, 62, 132, 62, 64, 131, 130, 64, 129, 64, -- 64, 65, 128, 158, 65, 65, 65, 65, 71, 127, -- 71, 71, 74, 74, 74, 74, 74, 74, 74, 74, -- -- 76, 76, 76, 76, 76, 76, 76, 76, 89, 126, -- 89, 90, 125, 90, 90, 124, 90, 90, 119, 119, -- 119, 119, 119, 119, 119, 119, 145, 145, 145, 145, -- 145, 145, 145, 145, 123, 122, 59, 59, 118, 117, -- 116, 115, 114, 113, 45, 112, 108, 111, 109, 106, -- 105, 104, 46, 103, 91, 87, 102, 101, 100, 98, -- 97, 96, 95, 94, 93, 77, 75, 91, 88, 87, -- 86, 57, 85, 84, 57, 82, 81, 78, 77, 75, -- 72, 158, 58, 57, 53, 35, 158, 31, 23, 23, -- 9, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- 158, 158, 158, 158, 158, 158, 158 -+ 21, 21, 21, 21, 10, 22, 10, 24, 25, 25, -+ 25, 32, 33, 33, 164, 26, 34, 34, 34, 52, -+ 53, 27, 26, 26, 26, 26, 10, 11, 12, 11, -+ 13, 14, 28, 15, 16, 28, 28, 28, 24, 28, -+ 28, 28, 10, 18, 19, 20, 29, 29, 29, 29, -+ 29, 30, 10, 29, 29, 29, 29, 29, 29, 29, -+ -+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -+ 10, 22, 10, 23, 34, 34, 34, 37, 39, 43, -+ 32, 33, 33, 45, 55, 56, 46, 60, 43, 45, -+ 65, 163, 46, 65, 65, 65, 44, 38, 60, 74, -+ 58, 47, 141, 48, 142, 44, 49, 47, 50, 48, -+ 76, 51, 62, 94, 50, 41, 44, 51, 37, 61, -+ 64, 64, 64, 58, 34, 34, 34, 64, 162, 80, -+ 67, 68, 68, 68, 64, 64, 64, 64, 38, 81, -+ 69, 70, 71, 68, 68, 68, 60, 161, 43, 69, -+ 70, 65, 69, 70, 65, 65, 65, 125, 85, 85, -+ -+ 85, 58, 68, 68, 68, 44, 102, 110, 125, 133, -+ 102, 69, 70, 111, 114, 160, 159, 126, 85, 85, -+ 85, 140, 140, 140, 140, 140, 140, 153, 126, 147, -+ 147, 147, 153, 148, 147, 147, 147, 158, 148, 165, -+ 157, 156, 155, 151, 150, 149, 146, 154, 145, 144, -+ 143, 139, 154, 36, 36, 36, 36, 36, 36, 36, -+ 36, 40, 138, 137, 136, 40, 40, 42, 42, 42, -+ 42, 42, 42, 42, 42, 57, 57, 57, 57, 63, -+ 135, 63, 65, 134, 165, 65, 133, 65, 65, 66, -+ 132, 131, 66, 66, 66, 66, 72, 130, 72, 72, -+ -+ 75, 75, 75, 75, 75, 75, 75, 75, 77, 77, -+ 77, 77, 77, 77, 77, 77, 91, 129, 91, 92, -+ 128, 92, 92, 127, 92, 92, 124, 124, 124, 124, -+ 124, 124, 124, 124, 152, 152, 152, 152, 152, 152, -+ 152, 152, 60, 60, 123, 122, 121, 120, 119, 118, -+ 117, 45, 116, 111, 115, 113, 112, 109, 108, 107, -+ 46, 106, 93, 89, 105, 104, 103, 101, 100, 99, -+ 98, 97, 96, 95, 78, 76, 93, 90, 89, 88, -+ 58, 87, 86, 58, 84, 83, 82, 79, 78, 76, -+ 73, 165, 59, 58, 54, 35, 165, 31, 23, 23, -+ -+ 9, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165 - } ; - --static yyconst flex_int16_t yy_chk[438] = -+static yyconst flex_int16_t yy_chk[449] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -- 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, -- 7, 7, 7, 156, 3, 11, 11, 11, 18, 18, -- 3, 3, 3, 3, 3, 5, 5, 5, 5, 5, -+ 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, -+ 3, 7, 7, 7, 163, 3, 11, 11, 11, 18, -+ 18, 3, 3, 3, 3, 3, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -- 5, 8, 12, 12, 12, 14, 15, 16, 8, 8, -- 8, 17, 20, 20, 17, 23, 24, 29, 155, 24, -- 29, 29, 29, 48, 16, 14, 31, 29, 128, 17, -- 128, 17, 48, 17, 24, 17, 24, 99, 24, 42, -- 24, 99, 15, 33, 33, 33, 23, 26, 26, 26, -- 26, 154, 33, 33, 26, 36, 42, 31, 32, 32, -- 32, 26, 26, 26, 26, 44, 59, 32, 32, 32, -- 34, 34, 34, 73, 75, 36, 153, 75, 59, 59, -- 59, 65, 44, 110, 65, 65, 65, 67, 67, 67, -- -- 73, 65, 83, 89, 89, 97, 67, 67, 119, 127, -- 97, 150, 149, 110, 83, 83, 83, 133, 133, 133, -- 141, 127, 127, 127, 145, 136, 136, 136, 119, 136, -- 140, 140, 140, 148, 140, 147, 144, 143, 142, 139, -- 141, 138, 137, 135, 145, 159, 159, 159, 159, 159, -- 159, 159, 159, 160, 134, 132, 131, 160, 160, 161, -- 161, 161, 161, 161, 161, 161, 161, 162, 162, 162, -- 162, 163, 126, 163, 164, 125, 124, 164, 123, 164, -- 164, 165, 122, 121, 165, 165, 165, 165, 166, 120, -- 166, 166, 167, 167, 167, 167, 167, 167, 167, 167, -- -- 168, 168, 168, 168, 168, 168, 168, 168, 169, 118, -- 169, 170, 117, 170, 170, 116, 170, 170, 171, 171, -- 171, 171, 171, 171, 171, 171, 172, 172, 172, 172, -- 172, 172, 172, 172, 115, 114, 112, 111, 109, 108, -- 107, 106, 105, 104, 103, 102, 101, 100, 98, 96, -- 95, 94, 93, 92, 90, 88, 86, 85, 84, 82, -- 81, 80, 79, 78, 77, 76, 74, 72, 69, 68, -- 66, 63, 61, 60, 56, 50, 49, 47, 46, 45, -+ 5, 5, 5, 8, 12, 12, 12, 14, 15, 16, -+ 8, 8, 8, 17, 20, 20, 17, 23, 42, 24, -+ 29, 162, 24, 29, 29, 29, 16, 14, 31, 44, -+ 29, 17, 134, 17, 134, 42, 17, 24, 17, 24, -+ 76, 17, 24, 76, 24, 15, 44, 24, 36, 23, -+ 26, 26, 26, 26, 34, 34, 34, 26, 161, 48, -+ 31, 32, 32, 32, 26, 26, 26, 26, 36, 48, -+ 32, 32, 32, 33, 33, 33, 60, 160, 74, 91, -+ 91, 66, 33, 33, 66, 66, 66, 114, 60, 60, -+ -+ 60, 66, 68, 68, 68, 74, 85, 99, 124, 133, -+ 102, 68, 68, 99, 102, 157, 156, 114, 85, 85, -+ 85, 133, 133, 133, 140, 140, 140, 148, 124, 143, -+ 143, 143, 152, 143, 147, 147, 147, 155, 147, 154, -+ 151, 150, 149, 146, 145, 144, 142, 148, 141, 138, -+ 137, 132, 152, 166, 166, 166, 166, 166, 166, 166, -+ 166, 167, 131, 130, 129, 167, 167, 168, 168, 168, -+ 168, 168, 168, 168, 168, 169, 169, 169, 169, 170, -+ 128, 170, 171, 127, 126, 171, 125, 171, 171, 172, -+ 123, 122, 172, 172, 172, 172, 173, 121, 173, 173, -+ -+ 174, 174, 174, 174, 174, 174, 174, 174, 175, 175, -+ 175, 175, 175, 175, 175, 175, 176, 120, 176, 177, -+ 119, 177, 177, 118, 177, 177, 178, 178, 178, 178, -+ 178, 178, 178, 178, 179, 179, 179, 179, 179, 179, -+ 179, 179, 116, 115, 113, 112, 111, 110, 109, 108, -+ 107, 106, 105, 104, 103, 101, 100, 98, 97, 96, -+ 95, 94, 92, 90, 88, 87, 86, 84, 83, 82, -+ 81, 80, 79, 78, 77, 75, 73, 70, 69, 67, -+ 64, 62, 61, 57, 51, 50, 49, 47, 46, 45, - 41, 38, 22, 21, 19, 13, 9, 6, 4, 2, -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, - -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- 158, 158, 158, 158, 158, 158, 158 -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165 - } ; - - static yy_state_type yy_last_accepting_state; -@@ -662,7 +671,7 @@ static int dts_version = 1; - static void push_input_file(const char *filename); - static bool pop_input_file(void); - static void lexical_error(const char *fmt, ...); --#line 666 "dtc-lexer.lex.c" -+#line 675 "dtc-lexer.lex.c" - - #define INITIAL 0 - #define BYTESTRING 1 -@@ -698,11 +707,11 @@ void yyset_extra (YY_EXTRA_TYPE user_defined ); - - FILE *yyget_in (void ); - --void yyset_in (FILE * in_str ); -+void yyset_in (FILE * _in_str ); - - FILE *yyget_out (void ); - --void yyset_out (FILE * out_str ); -+void yyset_out (FILE * _out_str ); - - yy_size_t yyget_leng (void ); - -@@ -710,7 +719,7 @@ char *yyget_text (void ); - - int yyget_lineno (void ); - --void yyset_lineno (int line_number ); -+void yyset_lineno (int _line_number ); - - /* Macros after this point can all be overridden by user definitions in - * section 1. -@@ -724,6 +733,10 @@ extern int yywrap (void ); - #endif - #endif - -+#ifndef YY_NO_UNPUT -+ -+#endif -+ - #ifndef yytext_ptr - static void yy_flex_strncpy (char *,yyconst char *,int ); - #endif -@@ -836,7 +849,7 @@ extern int yylex (void); - - /* Code executed at the end of each rule. */ - #ifndef YY_BREAK --#define YY_BREAK break; -+#define YY_BREAK /*LINTED*/break; - #endif - - #define YY_RULE_SETUP \ -@@ -849,9 +862,9 @@ extern int yylex (void); - */ - YY_DECL - { -- register yy_state_type yy_current_state; -- register char *yy_cp, *yy_bp; -- register int yy_act; -+ yy_state_type yy_current_state; -+ char *yy_cp, *yy_bp; -+ int yy_act; - - if ( !(yy_init) ) - { -@@ -882,9 +895,9 @@ YY_DECL - { - #line 68 "dtc-lexer.l" - --#line 886 "dtc-lexer.lex.c" -+#line 899 "dtc-lexer.lex.c" - -- while ( 1 ) /* loops until end-of-file is reached */ -+ while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ - { - yy_cp = (yy_c_buf_p); - -@@ -901,7 +914,7 @@ YY_DECL - yy_match: - do - { -- register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; -+ YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; - if ( yy_accept[yy_current_state] ) - { - (yy_last_accepting_state) = yy_current_state; -@@ -910,13 +923,13 @@ yy_match: - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; -- if ( yy_current_state >= 159 ) -+ if ( yy_current_state >= 166 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - ++yy_cp; - } -- while ( yy_current_state != 158 ); -+ while ( yy_current_state != 165 ); - yy_cp = (yy_last_accepting_cpos); - yy_current_state = (yy_last_accepting_state); - -@@ -1015,23 +1028,31 @@ case 5: - YY_RULE_SETUP - #line 124 "dtc-lexer.l" - { -+ DPRINT("Keyword: /plugin/\n"); -+ return DT_PLUGIN; -+ } -+ YY_BREAK -+case 6: -+YY_RULE_SETUP -+#line 129 "dtc-lexer.l" -+{ - DPRINT("Keyword: /memreserve/\n"); - BEGIN_DEFAULT(); - return DT_MEMRESERVE; - } - YY_BREAK --case 6: -+case 7: - YY_RULE_SETUP --#line 130 "dtc-lexer.l" -+#line 135 "dtc-lexer.l" - { - DPRINT("Keyword: /bits/\n"); - BEGIN_DEFAULT(); - return DT_BITS; - } - YY_BREAK --case 7: -+case 8: - YY_RULE_SETUP --#line 136 "dtc-lexer.l" -+#line 141 "dtc-lexer.l" - { - DPRINT("Keyword: /delete-property/\n"); - DPRINT("<PROPNODENAME>\n"); -@@ -1039,9 +1060,9 @@ YY_RULE_SETUP - return DT_DEL_PROP; - } - YY_BREAK --case 8: -+case 9: - YY_RULE_SETUP --#line 143 "dtc-lexer.l" -+#line 148 "dtc-lexer.l" - { - DPRINT("Keyword: /delete-node/\n"); - DPRINT("<PROPNODENAME>\n"); -@@ -1049,9 +1070,9 @@ YY_RULE_SETUP - return DT_DEL_NODE; - } - YY_BREAK --case 9: -+case 10: - YY_RULE_SETUP --#line 150 "dtc-lexer.l" -+#line 155 "dtc-lexer.l" - { - DPRINT("Label: %s\n", yytext); - yylval.labelref = xstrdup(yytext); -@@ -1059,9 +1080,9 @@ YY_RULE_SETUP - return DT_LABEL; - } - YY_BREAK --case 10: -+case 11: - YY_RULE_SETUP --#line 157 "dtc-lexer.l" -+#line 162 "dtc-lexer.l" - { - char *e; - DPRINT("Integer Literal: '%s'\n", yytext); -@@ -1084,10 +1105,10 @@ YY_RULE_SETUP - return DT_LITERAL; - } - YY_BREAK --case 11: --/* rule 11 can match eol */ -+case 12: -+/* rule 12 can match eol */ - YY_RULE_SETUP --#line 179 "dtc-lexer.l" -+#line 184 "dtc-lexer.l" - { - struct data d; - DPRINT("Character literal: %s\n", yytext); -@@ -1109,18 +1130,18 @@ YY_RULE_SETUP - return DT_CHAR_LITERAL; - } - YY_BREAK --case 12: -+case 13: - YY_RULE_SETUP --#line 200 "dtc-lexer.l" -+#line 205 "dtc-lexer.l" - { /* label reference */ - DPRINT("Ref: %s\n", yytext+1); - yylval.labelref = xstrdup(yytext+1); - return DT_REF; - } - YY_BREAK --case 13: -+case 14: - YY_RULE_SETUP --#line 206 "dtc-lexer.l" -+#line 211 "dtc-lexer.l" - { /* new-style path reference */ - yytext[yyleng-1] = '\0'; - DPRINT("Ref: %s\n", yytext+2); -@@ -1128,27 +1149,27 @@ YY_RULE_SETUP - return DT_REF; - } - YY_BREAK --case 14: -+case 15: - YY_RULE_SETUP --#line 213 "dtc-lexer.l" -+#line 218 "dtc-lexer.l" - { - yylval.byte = strtol(yytext, NULL, 16); - DPRINT("Byte: %02x\n", (int)yylval.byte); - return DT_BYTE; - } - YY_BREAK --case 15: -+case 16: - YY_RULE_SETUP --#line 219 "dtc-lexer.l" -+#line 224 "dtc-lexer.l" - { - DPRINT("/BYTESTRING\n"); - BEGIN_DEFAULT(); - return ']'; - } - YY_BREAK --case 16: -+case 17: - YY_RULE_SETUP --#line 225 "dtc-lexer.l" -+#line 230 "dtc-lexer.l" - { - DPRINT("PropNodeName: %s\n", yytext); - yylval.propnodename = xstrdup((yytext[0] == '\\') ? -@@ -1157,75 +1178,75 @@ YY_RULE_SETUP - return DT_PROPNODENAME; - } - YY_BREAK --case 17: -+case 18: - YY_RULE_SETUP --#line 233 "dtc-lexer.l" -+#line 238 "dtc-lexer.l" - { - DPRINT("Binary Include\n"); - return DT_INCBIN; - } - YY_BREAK --case 18: --/* rule 18 can match eol */ --YY_RULE_SETUP --#line 238 "dtc-lexer.l" --/* eat whitespace */ -- YY_BREAK - case 19: - /* rule 19 can match eol */ - YY_RULE_SETUP --#line 239 "dtc-lexer.l" --/* eat C-style comments */ -+#line 243 "dtc-lexer.l" -+/* eat whitespace */ - YY_BREAK - case 20: - /* rule 20 can match eol */ - YY_RULE_SETUP --#line 240 "dtc-lexer.l" --/* eat C++-style comments */ -+#line 244 "dtc-lexer.l" -+/* eat C-style comments */ - YY_BREAK - case 21: -+/* rule 21 can match eol */ - YY_RULE_SETUP --#line 242 "dtc-lexer.l" --{ return DT_LSHIFT; }; -+#line 245 "dtc-lexer.l" -+/* eat C++-style comments */ - YY_BREAK - case 22: - YY_RULE_SETUP --#line 243 "dtc-lexer.l" --{ return DT_RSHIFT; }; -+#line 247 "dtc-lexer.l" -+{ return DT_LSHIFT; }; - YY_BREAK - case 23: - YY_RULE_SETUP --#line 244 "dtc-lexer.l" --{ return DT_LE; }; -+#line 248 "dtc-lexer.l" -+{ return DT_RSHIFT; }; - YY_BREAK - case 24: - YY_RULE_SETUP --#line 245 "dtc-lexer.l" --{ return DT_GE; }; -+#line 249 "dtc-lexer.l" -+{ return DT_LE; }; - YY_BREAK - case 25: - YY_RULE_SETUP --#line 246 "dtc-lexer.l" --{ return DT_EQ; }; -+#line 250 "dtc-lexer.l" -+{ return DT_GE; }; - YY_BREAK - case 26: - YY_RULE_SETUP --#line 247 "dtc-lexer.l" --{ return DT_NE; }; -+#line 251 "dtc-lexer.l" -+{ return DT_EQ; }; - YY_BREAK - case 27: - YY_RULE_SETUP --#line 248 "dtc-lexer.l" --{ return DT_AND; }; -+#line 252 "dtc-lexer.l" -+{ return DT_NE; }; - YY_BREAK - case 28: - YY_RULE_SETUP --#line 249 "dtc-lexer.l" --{ return DT_OR; }; -+#line 253 "dtc-lexer.l" -+{ return DT_AND; }; - YY_BREAK - case 29: - YY_RULE_SETUP --#line 251 "dtc-lexer.l" -+#line 254 "dtc-lexer.l" -+{ return DT_OR; }; -+ YY_BREAK -+case 30: -+YY_RULE_SETUP -+#line 256 "dtc-lexer.l" - { - DPRINT("Char: %c (\\x%02x)\n", yytext[0], - (unsigned)yytext[0]); -@@ -1241,12 +1262,12 @@ YY_RULE_SETUP - return yytext[0]; - } - YY_BREAK --case 30: -+case 31: - YY_RULE_SETUP --#line 266 "dtc-lexer.l" -+#line 271 "dtc-lexer.l" - ECHO; - YY_BREAK --#line 1250 "dtc-lexer.lex.c" -+#line 1271 "dtc-lexer.lex.c" - - case YY_END_OF_BUFFER: - { -@@ -1388,9 +1409,9 @@ ECHO; - */ - static int yy_get_next_buffer (void) - { -- register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; -- register char *source = (yytext_ptr); -- register int number_to_move, i; -+ char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; -+ char *source = (yytext_ptr); -+ yy_size_t number_to_move, i; - int ret_val; - - if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) -@@ -1419,7 +1440,7 @@ static int yy_get_next_buffer (void) - /* Try to read more data. */ - - /* First move last chars to start of buffer. */ -- number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; -+ number_to_move = (yy_size_t) ((yy_c_buf_p) - (yytext_ptr)) - 1; - - for ( i = 0; i < number_to_move; ++i ) - *(dest++) = *(source++); -@@ -1501,9 +1522,9 @@ static int yy_get_next_buffer (void) - else - ret_val = EOB_ACT_CONTINUE_SCAN; - -- if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { -+ if ((int) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { - /* Extend the array by 50%, plus the number we really need. */ -- yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); -+ int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); - if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); -@@ -1522,15 +1543,15 @@ static int yy_get_next_buffer (void) - - static yy_state_type yy_get_previous_state (void) - { -- register yy_state_type yy_current_state; -- register char *yy_cp; -+ yy_state_type yy_current_state; -+ char *yy_cp; - - yy_current_state = (yy_start); - yy_current_state += YY_AT_BOL(); - - for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) - { -- register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); -+ YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); - if ( yy_accept[yy_current_state] ) - { - (yy_last_accepting_state) = yy_current_state; -@@ -1539,7 +1560,7 @@ static int yy_get_next_buffer (void) - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; -- if ( yy_current_state >= 159 ) -+ if ( yy_current_state >= 166 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; -@@ -1555,10 +1576,10 @@ static int yy_get_next_buffer (void) - */ - static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) - { -- register int yy_is_jam; -- register char *yy_cp = (yy_c_buf_p); -+ int yy_is_jam; -+ char *yy_cp = (yy_c_buf_p); - -- register YY_CHAR yy_c = 1; -+ YY_CHAR yy_c = 1; - if ( yy_accept[yy_current_state] ) - { - (yy_last_accepting_state) = yy_current_state; -@@ -1567,15 +1588,19 @@ static int yy_get_next_buffer (void) - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; -- if ( yy_current_state >= 159 ) -+ if ( yy_current_state >= 166 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; -- yy_is_jam = (yy_current_state == 158); -+ yy_is_jam = (yy_current_state == 165); - - return yy_is_jam ? 0 : yy_current_state; - } - -+#ifndef YY_NO_UNPUT -+ -+#endif -+ - #ifndef YY_NO_INPUT - #ifdef __cplusplus - static int yyinput (void) -@@ -1727,7 +1752,7 @@ static void yy_load_buffer_state (void) - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - -- b->yy_buf_size = size; -+ b->yy_buf_size = (yy_size_t)size; - - /* yy_ch_buf has to be 2 characters longer than the size given because - * we need to put in 2 end-of-buffer characters. -@@ -1882,7 +1907,7 @@ static void yyensure_buffer_stack (void) - * scanner will even need a stack. We use 2 instead of 1 to avoid an - * immediate realloc on the next call. - */ -- num_to_alloc = 1; -+ num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ - (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc - (num_to_alloc * sizeof(struct yy_buffer_state*) - ); -@@ -1899,7 +1924,7 @@ static void yyensure_buffer_stack (void) - if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ - - /* Increase the buffer to prepare for a possible push. */ -- int grow_size = 8 /* arbitrary grow size */; -+ yy_size_t grow_size = 8 /* arbitrary grow size */; - - num_to_alloc = (yy_buffer_stack_max) + grow_size; - (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc -@@ -2007,7 +2032,7 @@ YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len - - static void yy_fatal_error (yyconst char* msg ) - { -- (void) fprintf( stderr, "%s\n", msg ); -+ (void) fprintf( stderr, "%s\n", msg ); - exit( YY_EXIT_FAILURE ); - } - -@@ -2073,29 +2098,29 @@ char *yyget_text (void) - } - - /** Set the current line number. -- * @param line_number -+ * @param _line_number line number - * - */ --void yyset_lineno (int line_number ) -+void yyset_lineno (int _line_number ) - { - -- yylineno = line_number; -+ yylineno = _line_number; - } - - /** Set the input stream. This does not discard the current - * input buffer. -- * @param in_str A readable stream. -+ * @param _in_str A readable stream. - * - * @see yy_switch_to_buffer - */ --void yyset_in (FILE * in_str ) -+void yyset_in (FILE * _in_str ) - { -- yyin = in_str ; -+ yyin = _in_str ; - } - --void yyset_out (FILE * out_str ) -+void yyset_out (FILE * _out_str ) - { -- yyout = out_str ; -+ yyout = _out_str ; - } - - int yyget_debug (void) -@@ -2103,9 +2128,9 @@ int yyget_debug (void) - return yy_flex_debug; - } - --void yyset_debug (int bdebug ) -+void yyset_debug (int _bdebug ) - { -- yy_flex_debug = bdebug ; -+ yy_flex_debug = _bdebug ; - } - - static int yy_init_globals (void) -@@ -2165,7 +2190,8 @@ int yylex_destroy (void) - #ifndef yytext_ptr - static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) - { -- register int i; -+ -+ int i; - for ( i = 0; i < n; ++i ) - s1[i] = s2[i]; - } -@@ -2174,7 +2200,7 @@ static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) - #ifdef YY_NEED_STRLEN - static int yy_flex_strlen (yyconst char * s ) - { -- register int n; -+ int n; - for ( n = 0; s[n]; ++n ) - ; - -@@ -2184,11 +2210,12 @@ static int yy_flex_strlen (yyconst char * s ) - - void *yyalloc (yy_size_t size ) - { -- return (void *) malloc( size ); -+ return (void *) malloc( size ); - } - - void *yyrealloc (void * ptr, yy_size_t size ) - { -+ - /* The cast to (char *) in the following accommodates both - * implementations that use char* generic pointers, and those - * that use void* generic pointers. It works with the latter -@@ -2201,12 +2228,12 @@ void *yyrealloc (void * ptr, yy_size_t size ) - - void yyfree (void * ptr ) - { -- free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ -+ free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ - } - - #define YYTABLES_NAME "yytables" - --#line 265 "dtc-lexer.l" -+#line 271 "dtc-lexer.l" - - - -diff --git a/scripts/dtc/dtc-parser.tab.c_shipped b/scripts/dtc/dtc-parser.tab.c_shipped -index 31cec50..ce71569 100644 ---- a/scripts/dtc/dtc-parser.tab.c_shipped -+++ b/scripts/dtc/dtc-parser.tab.c_shipped -@@ -1,8 +1,8 @@ --/* A Bison parser, made by GNU Bison 3.0.2. */ -+/* A Bison parser, made by GNU Bison 3.0.4. */ - - /* Bison implementation for Yacc-like parsers in C - -- Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. -+ Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by -@@ -44,7 +44,7 @@ - #define YYBISON 1 - - /* Bison version. */ --#define YYBISON_VERSION "3.0.2" -+#define YYBISON_VERSION "3.0.4" - - /* Skeleton name. */ - #define YYSKELETON_NAME "yacc.c" -@@ -65,6 +65,7 @@ - #line 20 "dtc-parser.y" /* yacc.c:339 */ - - #include <stdio.h> -+#include <inttypes.h> - - #include "dtc.h" - #include "srcpos.h" -@@ -80,7 +81,7 @@ extern void yyerror(char const *s); - extern struct boot_info *the_boot_info; - extern bool treesource_error; - --#line 84 "dtc-parser.tab.c" /* yacc.c:339 */ -+#line 85 "dtc-parser.tab.c" /* yacc.c:339 */ - - # ifndef YY_NULLPTR - # if defined __cplusplus && 201103L <= __cplusplus -@@ -116,35 +117,36 @@ extern int yydebug; - enum yytokentype - { - DT_V1 = 258, -- DT_MEMRESERVE = 259, -- DT_LSHIFT = 260, -- DT_RSHIFT = 261, -- DT_LE = 262, -- DT_GE = 263, -- DT_EQ = 264, -- DT_NE = 265, -- DT_AND = 266, -- DT_OR = 267, -- DT_BITS = 268, -- DT_DEL_PROP = 269, -- DT_DEL_NODE = 270, -- DT_PROPNODENAME = 271, -- DT_LITERAL = 272, -- DT_CHAR_LITERAL = 273, -- DT_BYTE = 274, -- DT_STRING = 275, -- DT_LABEL = 276, -- DT_REF = 277, -- DT_INCBIN = 278 -+ DT_PLUGIN = 259, -+ DT_MEMRESERVE = 260, -+ DT_LSHIFT = 261, -+ DT_RSHIFT = 262, -+ DT_LE = 263, -+ DT_GE = 264, -+ DT_EQ = 265, -+ DT_NE = 266, -+ DT_AND = 267, -+ DT_OR = 268, -+ DT_BITS = 269, -+ DT_DEL_PROP = 270, -+ DT_DEL_NODE = 271, -+ DT_PROPNODENAME = 272, -+ DT_LITERAL = 273, -+ DT_CHAR_LITERAL = 274, -+ DT_BYTE = 275, -+ DT_STRING = 276, -+ DT_LABEL = 277, -+ DT_REF = 278, -+ DT_INCBIN = 279 - }; - #endif - - /* Value type. */ - #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED --typedef union YYSTYPE YYSTYPE; -+ - union YYSTYPE - { --#line 38 "dtc-parser.y" /* yacc.c:355 */ -+#line 39 "dtc-parser.y" /* yacc.c:355 */ - - char *propnodename; - char *labelref; -@@ -162,9 +164,12 @@ union YYSTYPE - struct node *nodelist; - struct reserve_info *re; - uint64_t integer; -+ bool is_plugin; - --#line 167 "dtc-parser.tab.c" /* yacc.c:355 */ -+#line 170 "dtc-parser.tab.c" /* yacc.c:355 */ - }; -+ -+typedef union YYSTYPE YYSTYPE; - # define YYSTYPE_IS_TRIVIAL 1 - # define YYSTYPE_IS_DECLARED 1 - #endif -@@ -192,7 +197,7 @@ int yyparse (void); - - /* Copy the second part of user declarations. */ - --#line 196 "dtc-parser.tab.c" /* yacc.c:358 */ -+#line 201 "dtc-parser.tab.c" /* yacc.c:358 */ - - #ifdef short - # undef short -@@ -439,18 +444,18 @@ union yyalloc - #define YYLAST 136 - - /* YYNTOKENS -- Number of terminals. */ --#define YYNTOKENS 47 -+#define YYNTOKENS 48 - /* YYNNTS -- Number of nonterminals. */ --#define YYNNTS 28 -+#define YYNNTS 29 - /* YYNRULES -- Number of rules. */ --#define YYNRULES 80 -+#define YYNRULES 82 - /* YYNSTATES -- Number of states. */ --#define YYNSTATES 144 -+#define YYNSTATES 147 - - /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned - by yylex, with out-of-bounds checking. */ - #define YYUNDEFTOK 2 --#define YYMAXUTOK 278 -+#define YYMAXUTOK 279 - - #define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) -@@ -462,16 +467,16 @@ static const yytype_uint8 yytranslate[] = - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -- 2, 2, 2, 46, 2, 2, 2, 44, 40, 2, -- 32, 34, 43, 41, 33, 42, 2, 25, 2, 2, -- 2, 2, 2, 2, 2, 2, 2, 2, 37, 24, -- 35, 28, 29, 36, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 47, 2, 2, 2, 45, 41, 2, -+ 33, 35, 44, 42, 34, 43, 2, 26, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 38, 25, -+ 36, 29, 30, 37, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -- 2, 30, 2, 31, 39, 2, 2, 2, 2, 2, -+ 2, 31, 2, 32, 40, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -- 2, 2, 2, 26, 38, 27, 45, 2, 2, 2, -+ 2, 2, 2, 27, 39, 28, 46, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -@@ -486,22 +491,22 @@ static const yytype_uint8 yytranslate[] = - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, -- 15, 16, 17, 18, 19, 20, 21, 22, 23 -+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 - }; - - #if YYDEBUG - /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ - static const yytype_uint16 yyrline[] = - { -- 0, 104, 104, 113, 116, 123, 127, 135, 139, 144, -- 155, 165, 180, 188, 191, 198, 202, 206, 210, 218, -- 222, 226, 230, 234, 250, 260, 268, 271, 275, 282, -- 298, 303, 322, 336, 343, 344, 345, 352, 356, 357, -- 361, 362, 366, 367, 371, 372, 376, 377, 381, 382, -- 386, 387, 388, 392, 393, 394, 395, 396, 400, 401, -- 402, 406, 407, 408, 412, 413, 422, 431, 435, 436, -- 437, 438, 443, 446, 450, 458, 461, 465, 473, 477, -- 481 -+ 0, 108, 108, 118, 121, 129, 132, 139, 143, 151, -+ 155, 160, 171, 181, 196, 204, 207, 214, 218, 222, -+ 226, 234, 238, 242, 246, 250, 266, 276, 284, 287, -+ 291, 298, 314, 319, 338, 352, 359, 360, 361, 368, -+ 372, 373, 377, 378, 382, 383, 387, 388, 392, 393, -+ 397, 398, 402, 403, 404, 408, 409, 410, 411, 412, -+ 416, 417, 418, 422, 423, 424, 428, 429, 438, 447, -+ 451, 452, 453, 454, 459, 462, 466, 474, 477, 481, -+ 489, 493, 497 - }; - #endif - -@@ -510,19 +515,19 @@ static const yytype_uint16 yyrline[] = - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ - static const char *const yytname[] = - { -- "$end", "error", "$undefined", "DT_V1", "DT_MEMRESERVE", "DT_LSHIFT", -- "DT_RSHIFT", "DT_LE", "DT_GE", "DT_EQ", "DT_NE", "DT_AND", "DT_OR", -- "DT_BITS", "DT_DEL_PROP", "DT_DEL_NODE", "DT_PROPNODENAME", "DT_LITERAL", -- "DT_CHAR_LITERAL", "DT_BYTE", "DT_STRING", "DT_LABEL", "DT_REF", -- "DT_INCBIN", "';'", "'/'", "'{'", "'}'", "'='", "'>'", "'['", "']'", -- "'('", "','", "')'", "'<'", "'?'", "':'", "'|'", "'^'", "'&'", "'+'", -- "'-'", "'*'", "'%'", "'~'", "'!'", "$accept", "sourcefile", -- "memreserves", "memreserve", "devicetree", "nodedef", "proplist", -- "propdef", "propdata", "propdataprefix", "arrayprefix", "integer_prim", -- "integer_expr", "integer_trinary", "integer_or", "integer_and", -- "integer_bitor", "integer_bitxor", "integer_bitand", "integer_eq", -- "integer_rela", "integer_shift", "integer_add", "integer_mul", -- "integer_unary", "bytestring", "subnodes", "subnode", YY_NULLPTR -+ "$end", "error", "$undefined", "DT_V1", "DT_PLUGIN", "DT_MEMRESERVE", -+ "DT_LSHIFT", "DT_RSHIFT", "DT_LE", "DT_GE", "DT_EQ", "DT_NE", "DT_AND", -+ "DT_OR", "DT_BITS", "DT_DEL_PROP", "DT_DEL_NODE", "DT_PROPNODENAME", -+ "DT_LITERAL", "DT_CHAR_LITERAL", "DT_BYTE", "DT_STRING", "DT_LABEL", -+ "DT_REF", "DT_INCBIN", "';'", "'/'", "'{'", "'}'", "'='", "'>'", "'['", -+ "']'", "'('", "','", "')'", "'<'", "'?'", "':'", "'|'", "'^'", "'&'", -+ "'+'", "'-'", "'*'", "'%'", "'~'", "'!'", "$accept", "sourcefile", -+ "plugindecl", "memreserves", "memreserve", "devicetree", "nodedef", -+ "proplist", "propdef", "propdata", "propdataprefix", "arrayprefix", -+ "integer_prim", "integer_expr", "integer_trinary", "integer_or", -+ "integer_and", "integer_bitor", "integer_bitxor", "integer_bitand", -+ "integer_eq", "integer_rela", "integer_shift", "integer_add", -+ "integer_mul", "integer_unary", "bytestring", "subnodes", "subnode", YY_NULLPTR - }; - #endif - -@@ -533,16 +538,16 @@ static const yytype_uint16 yytoknum[] = - { - 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, -- 275, 276, 277, 278, 59, 47, 123, 125, 61, 62, -- 91, 93, 40, 44, 41, 60, 63, 58, 124, 94, -- 38, 43, 45, 42, 37, 126, 33 -+ 275, 276, 277, 278, 279, 59, 47, 123, 125, 61, -+ 62, 91, 93, 40, 44, 41, 60, 63, 58, 124, -+ 94, 38, 43, 45, 42, 37, 126, 33 - }; - # endif - --#define YYPACT_NINF -81 -+#define YYPACT_NINF -84 - - #define yypact_value_is_default(Yystate) \ -- (!!((Yystate) == (-81))) -+ (!!((Yystate) == (-84))) - - #define YYTABLE_NINF -1 - -@@ -553,21 +558,21 @@ static const yytype_uint16 yytoknum[] = - STATE-NUM. */ - static const yytype_int8 yypact[] = - { -- 16, -11, 21, 10, -81, 25, 10, 19, 10, -81, -- -81, -9, 25, -81, 2, 51, -81, -9, -9, -9, -- -81, 1, -81, -6, 50, 14, 28, 29, 36, 3, -- 58, 44, -3, -81, 47, -81, -81, 65, 68, 2, -- 2, -81, -81, -81, -81, -9, -9, -9, -9, -9, -- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -- -9, -9, -9, -9, -81, 63, 69, 2, -81, -81, -- 50, 57, 14, 28, 29, 36, 3, 3, 58, 58, -- 58, 58, 44, 44, -3, -3, -81, -81, -81, 79, -- 80, -8, 63, -81, 72, 63, -81, -81, -9, 76, -- 77, -81, -81, -81, -81, -81, 78, -81, -81, -81, -- -81, -81, 35, 4, -81, -81, -81, -81, 86, -81, -- -81, -81, 73, -81, -81, 33, 71, 84, 39, -81, -- -81, -81, -81, -81, 41, -81, -81, -81, 25, -81, -- 74, 25, 75, -81 -+ 15, -12, 35, 42, -84, 27, 9, -84, 24, 9, -+ 43, 9, -84, -84, -10, 24, -84, 60, 44, -84, -+ -10, -10, -10, -84, 55, -84, -7, 52, 53, 51, -+ 54, 10, 2, 38, 37, -4, -84, 68, -84, -84, -+ 71, 73, 60, 60, -84, -84, -84, -84, -10, -10, -+ -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -+ -10, -10, -10, -10, -10, -10, -10, -84, 56, 72, -+ 60, -84, -84, 52, 61, 53, 51, 54, 10, 2, -+ 2, 38, 38, 38, 38, 37, 37, -4, -4, -84, -+ -84, -84, 81, 83, 34, 56, -84, 74, 56, -84, -+ -84, -10, 76, 78, -84, -84, -84, -84, -84, 79, -+ -84, -84, -84, -84, -84, -6, 3, -84, -84, -84, -+ -84, 87, -84, -84, -84, 75, -84, -84, 32, 70, -+ 86, 36, -84, -84, -84, -84, -84, 47, -84, -84, -+ -84, 24, -84, 77, 24, 80, -84 - }; - - /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. -@@ -575,37 +580,37 @@ static const yytype_int8 yypact[] = - means the default is an error. */ - static const yytype_uint8 yydefact[] = - { -- 0, 0, 0, 3, 1, 0, 0, 0, 3, 34, -- 35, 0, 0, 6, 0, 2, 4, 0, 0, 0, -- 68, 0, 37, 38, 40, 42, 44, 46, 48, 50, -- 53, 60, 63, 67, 0, 13, 7, 0, 0, 0, -- 0, 69, 70, 71, 36, 0, 0, 0, 0, 0, -+ 0, 0, 0, 3, 1, 0, 5, 4, 0, 0, -+ 0, 5, 36, 37, 0, 0, 8, 0, 2, 6, -+ 0, 0, 0, 70, 0, 39, 40, 42, 44, 46, -+ 48, 50, 52, 55, 62, 65, 69, 0, 15, 9, -+ 0, 0, 0, 0, 71, 72, 73, 38, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 5, 75, 0, 0, 10, 8, -- 41, 0, 43, 45, 47, 49, 51, 52, 56, 57, -- 55, 54, 58, 59, 61, 62, 65, 64, 66, 0, -- 0, 0, 0, 14, 0, 75, 11, 9, 0, 0, -- 0, 16, 26, 78, 18, 80, 0, 77, 76, 39, -- 17, 79, 0, 0, 12, 25, 15, 27, 0, 19, -- 28, 22, 0, 72, 30, 0, 0, 0, 0, 33, -- 32, 20, 31, 29, 0, 73, 74, 21, 0, 24, -- 0, 0, 0, 23 -+ 0, 0, 0, 0, 0, 0, 0, 7, 77, 0, -+ 0, 12, 10, 43, 0, 45, 47, 49, 51, 53, -+ 54, 58, 59, 57, 56, 60, 61, 63, 64, 67, -+ 66, 68, 0, 0, 0, 0, 16, 0, 77, 13, -+ 11, 0, 0, 0, 18, 28, 80, 20, 82, 0, -+ 79, 78, 41, 19, 81, 0, 0, 14, 27, 17, -+ 29, 0, 21, 30, 24, 0, 74, 32, 0, 0, -+ 0, 0, 35, 34, 22, 33, 31, 0, 75, 76, -+ 23, 0, 26, 0, 0, 0, 25 - }; - - /* YYPGOTO[NTERM-NUM]. */ - static const yytype_int8 yypgoto[] = - { -- -81, -81, 100, 104, -81, -38, -81, -80, -81, -81, -- -81, -5, 66, 13, -81, 70, 67, 81, 64, 82, -- 37, 27, 34, 38, -14, -81, 22, 24 -+ -84, -84, -84, 98, 101, -84, -41, -84, -83, -84, -+ -84, -84, -8, 63, 12, -84, 66, 67, 65, 69, -+ 82, 29, 18, 25, 26, -17, -84, 20, 28 - }; - - /* YYDEFGOTO[NTERM-NUM]. */ - static const yytype_int16 yydefgoto[] = - { -- -1, 2, 7, 8, 15, 36, 65, 93, 112, 113, -- 125, 20, 21, 22, 23, 24, 25, 26, 27, 28, -- 29, 30, 31, 32, 33, 128, 94, 95 -+ -1, 2, 6, 10, 11, 18, 39, 68, 96, 115, -+ 116, 128, 23, 24, 25, 26, 27, 28, 29, 30, -+ 31, 32, 33, 34, 35, 36, 131, 97, 98 - }; - - /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If -@@ -613,87 +618,87 @@ static const yytype_int16 yydefgoto[] = - number is the opposite. If YYTABLE_NINF, syntax error. */ - static const yytype_uint8 yytable[] = - { -- 12, 68, 69, 41, 42, 43, 45, 34, 9, 10, -- 53, 54, 104, 3, 5, 107, 101, 118, 35, 1, -- 102, 4, 61, 11, 119, 120, 121, 122, 35, 97, -- 46, 6, 55, 17, 123, 44, 18, 19, 56, 124, -- 62, 63, 9, 10, 14, 51, 52, 86, 87, 88, -- 9, 10, 48, 103, 129, 130, 115, 11, 135, 116, -- 136, 47, 131, 57, 58, 11, 37, 49, 117, 50, -- 137, 64, 38, 39, 138, 139, 40, 89, 90, 91, -- 78, 79, 80, 81, 92, 59, 60, 66, 76, 77, -- 67, 82, 83, 96, 98, 99, 100, 84, 85, 106, -- 110, 111, 114, 126, 134, 127, 133, 141, 16, 143, -- 13, 109, 71, 74, 72, 70, 105, 108, 0, 0, -- 132, 0, 0, 0, 0, 0, 0, 0, 0, 73, -- 0, 0, 75, 140, 0, 0, 142 -+ 15, 71, 72, 44, 45, 46, 48, 37, 12, 13, -+ 56, 57, 107, 3, 8, 110, 118, 121, 1, 119, -+ 54, 55, 64, 14, 122, 123, 124, 125, 120, 100, -+ 49, 9, 58, 20, 126, 4, 21, 22, 59, 127, -+ 65, 66, 12, 13, 60, 61, 5, 89, 90, 91, -+ 12, 13, 7, 106, 132, 133, 138, 14, 139, 104, -+ 40, 38, 134, 105, 50, 14, 41, 42, 140, 17, -+ 43, 92, 93, 94, 81, 82, 83, 84, 95, 62, -+ 63, 141, 142, 79, 80, 85, 86, 38, 87, 88, -+ 47, 52, 51, 67, 69, 53, 70, 99, 102, 101, -+ 103, 113, 109, 114, 117, 129, 136, 137, 130, 19, -+ 16, 144, 74, 112, 73, 146, 76, 75, 111, 0, -+ 135, 77, 0, 108, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 143, 0, 78, 145 - }; - - static const yytype_int16 yycheck[] = - { -- 5, 39, 40, 17, 18, 19, 12, 12, 17, 18, -- 7, 8, 92, 24, 4, 95, 24, 13, 26, 3, -- 28, 0, 25, 32, 20, 21, 22, 23, 26, 67, -- 36, 21, 29, 42, 30, 34, 45, 46, 35, 35, -- 43, 44, 17, 18, 25, 9, 10, 61, 62, 63, -- 17, 18, 38, 91, 21, 22, 21, 32, 19, 24, -- 21, 11, 29, 5, 6, 32, 15, 39, 33, 40, -- 31, 24, 21, 22, 33, 34, 25, 14, 15, 16, -- 53, 54, 55, 56, 21, 41, 42, 22, 51, 52, -- 22, 57, 58, 24, 37, 16, 16, 59, 60, 27, -- 24, 24, 24, 17, 20, 32, 35, 33, 8, 34, -- 6, 98, 46, 49, 47, 45, 92, 95, -1, -1, -- 125, -1, -1, -1, -1, -1, -1, -1, -1, 48, -- -1, -1, 50, 138, -1, -1, 141 -+ 8, 42, 43, 20, 21, 22, 13, 15, 18, 19, -+ 8, 9, 95, 25, 5, 98, 22, 14, 3, 25, -+ 10, 11, 26, 33, 21, 22, 23, 24, 34, 70, -+ 37, 22, 30, 43, 31, 0, 46, 47, 36, 36, -+ 44, 45, 18, 19, 6, 7, 4, 64, 65, 66, -+ 18, 19, 25, 94, 22, 23, 20, 33, 22, 25, -+ 16, 27, 30, 29, 12, 33, 22, 23, 32, 26, -+ 26, 15, 16, 17, 56, 57, 58, 59, 22, 42, -+ 43, 34, 35, 54, 55, 60, 61, 27, 62, 63, -+ 35, 40, 39, 25, 23, 41, 23, 25, 17, 38, -+ 17, 25, 28, 25, 25, 18, 36, 21, 33, 11, -+ 9, 34, 49, 101, 48, 35, 51, 50, 98, -1, -+ 128, 52, -1, 95, -1, -1, -1, -1, -1, -1, -+ -1, -1, -1, 141, -1, 53, 144 - }; - - /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ - static const yytype_uint8 yystos[] = - { -- 0, 3, 48, 24, 0, 4, 21, 49, 50, 17, -- 18, 32, 58, 50, 25, 51, 49, 42, 45, 46, -- 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, -- 68, 69, 70, 71, 58, 26, 52, 15, 21, 22, -- 25, 71, 71, 71, 34, 12, 36, 11, 38, 39, -- 40, 9, 10, 7, 8, 29, 35, 5, 6, 41, -- 42, 25, 43, 44, 24, 53, 22, 22, 52, 52, -- 62, 59, 63, 64, 65, 66, 67, 67, 68, 68, -- 68, 68, 69, 69, 70, 70, 71, 71, 71, 14, -- 15, 16, 21, 54, 73, 74, 24, 52, 37, 16, -- 16, 24, 28, 52, 54, 74, 27, 54, 73, 60, -- 24, 24, 55, 56, 24, 21, 24, 33, 13, 20, -- 21, 22, 23, 30, 35, 57, 17, 32, 72, 21, -- 22, 29, 58, 35, 20, 19, 21, 31, 33, 34, -- 58, 33, 58, 34 -+ 0, 3, 49, 25, 0, 4, 50, 25, 5, 22, -+ 51, 52, 18, 19, 33, 60, 52, 26, 53, 51, -+ 43, 46, 47, 60, 61, 62, 63, 64, 65, 66, -+ 67, 68, 69, 70, 71, 72, 73, 60, 27, 54, -+ 16, 22, 23, 26, 73, 73, 73, 35, 13, 37, -+ 12, 39, 40, 41, 10, 11, 8, 9, 30, 36, -+ 6, 7, 42, 43, 26, 44, 45, 25, 55, 23, -+ 23, 54, 54, 64, 61, 65, 66, 67, 68, 69, -+ 69, 70, 70, 70, 70, 71, 71, 72, 72, 73, -+ 73, 73, 15, 16, 17, 22, 56, 75, 76, 25, -+ 54, 38, 17, 17, 25, 29, 54, 56, 76, 28, -+ 56, 75, 62, 25, 25, 57, 58, 25, 22, 25, -+ 34, 14, 21, 22, 23, 24, 31, 36, 59, 18, -+ 33, 74, 22, 23, 30, 60, 36, 21, 20, 22, -+ 32, 34, 35, 60, 34, 60, 35 - }; - - /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ - static const yytype_uint8 yyr1[] = - { -- 0, 47, 48, 49, 49, 50, 50, 51, 51, 51, -- 51, 51, 52, 53, 53, 54, 54, 54, 54, 55, -- 55, 55, 55, 55, 55, 55, 56, 56, 56, 57, -- 57, 57, 57, 57, 58, 58, 58, 59, 60, 60, -- 61, 61, 62, 62, 63, 63, 64, 64, 65, 65, -- 66, 66, 66, 67, 67, 67, 67, 67, 68, 68, -- 68, 69, 69, 69, 70, 70, 70, 70, 71, 71, -- 71, 71, 72, 72, 72, 73, 73, 73, 74, 74, -- 74 -+ 0, 48, 49, 50, 50, 51, 51, 52, 52, 53, -+ 53, 53, 53, 53, 54, 55, 55, 56, 56, 56, -+ 56, 57, 57, 57, 57, 57, 57, 57, 58, 58, -+ 58, 59, 59, 59, 59, 59, 60, 60, 60, 61, -+ 62, 62, 63, 63, 64, 64, 65, 65, 66, 66, -+ 67, 67, 68, 68, 68, 69, 69, 69, 69, 69, -+ 70, 70, 70, 71, 71, 71, 72, 72, 72, 72, -+ 73, 73, 73, 73, 74, 74, 74, 75, 75, 75, -+ 76, 76, 76 - }; - - /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ - static const yytype_uint8 yyr2[] = - { -- 0, 2, 4, 0, 2, 4, 2, 2, 3, 4, -- 3, 4, 5, 0, 2, 4, 2, 3, 2, 2, -- 3, 4, 2, 9, 5, 2, 0, 2, 2, 3, -- 1, 2, 2, 2, 1, 1, 3, 1, 1, 5, -- 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, -- 1, 3, 3, 1, 3, 3, 3, 3, 3, 3, -- 1, 3, 3, 1, 3, 3, 3, 1, 1, 2, -- 2, 2, 0, 2, 2, 0, 2, 2, 2, 3, -- 2 -+ 0, 2, 5, 0, 2, 0, 2, 4, 2, 2, -+ 3, 4, 3, 4, 5, 0, 2, 4, 2, 3, -+ 2, 2, 3, 4, 2, 9, 5, 2, 0, 2, -+ 2, 3, 1, 2, 2, 2, 1, 1, 3, 1, -+ 1, 5, 1, 3, 1, 3, 1, 3, 1, 3, -+ 1, 3, 1, 3, 3, 1, 3, 3, 3, 3, -+ 3, 3, 1, 3, 3, 1, 3, 3, 3, 1, -+ 1, 2, 2, 2, 0, 2, 2, 0, 2, 2, -+ 2, 3, 2 - }; - - -@@ -1463,65 +1468,82 @@ yyreduce: - switch (yyn) - { - case 2: --#line 105 "dtc-parser.y" /* yacc.c:1646 */ -+#line 109 "dtc-parser.y" /* yacc.c:1646 */ - { -+ (yyvsp[0].node)->is_plugin = (yyvsp[-2].is_plugin); - the_boot_info = build_boot_info((yyvsp[-1].re), (yyvsp[0].node), - guess_boot_cpuid((yyvsp[0].node))); - } --#line 1472 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1478 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 3: --#line 113 "dtc-parser.y" /* yacc.c:1646 */ -+#line 118 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.re) = NULL; -+ (yyval.is_plugin) = false; - } --#line 1480 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1486 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 4: --#line 117 "dtc-parser.y" /* yacc.c:1646 */ -+#line 122 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.re) = chain_reserve_entry((yyvsp[-1].re), (yyvsp[0].re)); -+ (yyval.is_plugin) = true; - } --#line 1488 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1494 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 5: --#line 124 "dtc-parser.y" /* yacc.c:1646 */ -+#line 129 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.re) = build_reserve_entry((yyvsp[-2].integer), (yyvsp[-1].integer)); -+ (yyval.re) = NULL; - } --#line 1496 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1502 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 6: --#line 128 "dtc-parser.y" /* yacc.c:1646 */ -+#line 133 "dtc-parser.y" /* yacc.c:1646 */ -+ { -+ (yyval.re) = chain_reserve_entry((yyvsp[-1].re), (yyvsp[0].re)); -+ } -+#line 1510 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ break; -+ -+ case 7: -+#line 140 "dtc-parser.y" /* yacc.c:1646 */ -+ { -+ (yyval.re) = build_reserve_entry((yyvsp[-2].integer), (yyvsp[-1].integer)); -+ } -+#line 1518 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ break; -+ -+ case 8: -+#line 144 "dtc-parser.y" /* yacc.c:1646 */ - { - add_label(&(yyvsp[0].re)->labels, (yyvsp[-1].labelref)); - (yyval.re) = (yyvsp[0].re); - } --#line 1505 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1527 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 7: --#line 136 "dtc-parser.y" /* yacc.c:1646 */ -+ case 9: -+#line 152 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.node) = name_node((yyvsp[0].node), ""); - } --#line 1513 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1535 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 8: --#line 140 "dtc-parser.y" /* yacc.c:1646 */ -+ case 10: -+#line 156 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.node) = merge_nodes((yyvsp[-2].node), (yyvsp[0].node)); - } --#line 1521 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1543 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 9: --#line 145 "dtc-parser.y" /* yacc.c:1646 */ -+ case 11: -+#line 161 "dtc-parser.y" /* yacc.c:1646 */ - { - struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref)); - -@@ -1532,11 +1554,11 @@ yyreduce: - ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref)); - (yyval.node) = (yyvsp[-3].node); - } --#line 1536 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1558 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 10: --#line 156 "dtc-parser.y" /* yacc.c:1646 */ -+ case 12: -+#line 172 "dtc-parser.y" /* yacc.c:1646 */ - { - struct node *target = get_node_by_ref((yyvsp[-2].node), (yyvsp[-1].labelref)); - -@@ -1546,11 +1568,11 @@ yyreduce: - ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref)); - (yyval.node) = (yyvsp[-2].node); - } --#line 1550 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1572 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 11: --#line 166 "dtc-parser.y" /* yacc.c:1646 */ -+ case 13: -+#line 182 "dtc-parser.y" /* yacc.c:1646 */ - { - struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref)); - -@@ -1562,100 +1584,100 @@ yyreduce: - - (yyval.node) = (yyvsp[-3].node); - } --#line 1566 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1588 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 12: --#line 181 "dtc-parser.y" /* yacc.c:1646 */ -+ case 14: -+#line 197 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.node) = build_node((yyvsp[-3].proplist), (yyvsp[-2].nodelist)); - } --#line 1574 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1596 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 13: --#line 188 "dtc-parser.y" /* yacc.c:1646 */ -+ case 15: -+#line 204 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.proplist) = NULL; - } --#line 1582 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1604 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 14: --#line 192 "dtc-parser.y" /* yacc.c:1646 */ -+ case 16: -+#line 208 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.proplist) = chain_property((yyvsp[0].prop), (yyvsp[-1].proplist)); - } --#line 1590 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1612 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 15: --#line 199 "dtc-parser.y" /* yacc.c:1646 */ -+ case 17: -+#line 215 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.prop) = build_property((yyvsp[-3].propnodename), (yyvsp[-1].data)); - } --#line 1598 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1620 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 16: --#line 203 "dtc-parser.y" /* yacc.c:1646 */ -+ case 18: -+#line 219 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.prop) = build_property((yyvsp[-1].propnodename), empty_data); - } --#line 1606 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1628 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 17: --#line 207 "dtc-parser.y" /* yacc.c:1646 */ -+ case 19: -+#line 223 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.prop) = build_property_delete((yyvsp[-1].propnodename)); - } --#line 1614 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1636 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 18: --#line 211 "dtc-parser.y" /* yacc.c:1646 */ -+ case 20: -+#line 227 "dtc-parser.y" /* yacc.c:1646 */ - { - add_label(&(yyvsp[0].prop)->labels, (yyvsp[-1].labelref)); - (yyval.prop) = (yyvsp[0].prop); - } --#line 1623 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1645 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 19: --#line 219 "dtc-parser.y" /* yacc.c:1646 */ -+ case 21: -+#line 235 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = data_merge((yyvsp[-1].data), (yyvsp[0].data)); - } --#line 1631 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1653 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 20: --#line 223 "dtc-parser.y" /* yacc.c:1646 */ -+ case 22: -+#line 239 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = data_merge((yyvsp[-2].data), (yyvsp[-1].array).data); - } --#line 1639 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1661 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 21: --#line 227 "dtc-parser.y" /* yacc.c:1646 */ -+ case 23: -+#line 243 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = data_merge((yyvsp[-3].data), (yyvsp[-1].data)); - } --#line 1647 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1669 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 22: --#line 231 "dtc-parser.y" /* yacc.c:1646 */ -+ case 24: -+#line 247 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = data_add_marker((yyvsp[-1].data), REF_PATH, (yyvsp[0].labelref)); - } --#line 1655 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1677 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 23: --#line 235 "dtc-parser.y" /* yacc.c:1646 */ -+ case 25: -+#line 251 "dtc-parser.y" /* yacc.c:1646 */ - { - FILE *f = srcfile_relative_open((yyvsp[-5].data).val, NULL); - struct data d; -@@ -1671,11 +1693,11 @@ yyreduce: - (yyval.data) = data_merge((yyvsp[-8].data), d); - fclose(f); - } --#line 1675 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1697 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 24: --#line 251 "dtc-parser.y" /* yacc.c:1646 */ -+ case 26: -+#line 267 "dtc-parser.y" /* yacc.c:1646 */ - { - FILE *f = srcfile_relative_open((yyvsp[-1].data).val, NULL); - struct data d = empty_data; -@@ -1685,43 +1707,43 @@ yyreduce: - (yyval.data) = data_merge((yyvsp[-4].data), d); - fclose(f); - } --#line 1689 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1711 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 25: --#line 261 "dtc-parser.y" /* yacc.c:1646 */ -+ case 27: -+#line 277 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); - } --#line 1697 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1719 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 26: --#line 268 "dtc-parser.y" /* yacc.c:1646 */ -+ case 28: -+#line 284 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = empty_data; - } --#line 1705 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1727 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 27: --#line 272 "dtc-parser.y" /* yacc.c:1646 */ -+ case 29: -+#line 288 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = (yyvsp[-1].data); - } --#line 1713 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1735 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 28: --#line 276 "dtc-parser.y" /* yacc.c:1646 */ -+ case 30: -+#line 292 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); - } --#line 1721 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1743 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 29: --#line 283 "dtc-parser.y" /* yacc.c:1646 */ -+ case 31: -+#line 299 "dtc-parser.y" /* yacc.c:1646 */ - { - unsigned long long bits; - -@@ -1737,20 +1759,20 @@ yyreduce: - (yyval.array).data = empty_data; - (yyval.array).bits = bits; - } --#line 1741 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1763 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 30: --#line 299 "dtc-parser.y" /* yacc.c:1646 */ -+ case 32: -+#line 315 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.array).data = empty_data; - (yyval.array).bits = 32; - } --#line 1750 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1772 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 31: --#line 304 "dtc-parser.y" /* yacc.c:1646 */ -+ case 33: -+#line 320 "dtc-parser.y" /* yacc.c:1646 */ - { - if ((yyvsp[-1].array).bits < 64) { - uint64_t mask = (1ULL << (yyvsp[-1].array).bits) - 1; -@@ -1769,11 +1791,11 @@ yyreduce: - - (yyval.array).data = data_append_integer((yyvsp[-1].array).data, (yyvsp[0].integer), (yyvsp[-1].array).bits); - } --#line 1773 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1795 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 32: --#line 323 "dtc-parser.y" /* yacc.c:1646 */ -+ case 34: -+#line 339 "dtc-parser.y" /* yacc.c:1646 */ - { - uint64_t val = ~0ULL >> (64 - (yyvsp[-1].array).bits); - -@@ -1787,129 +1809,129 @@ yyreduce: - - (yyval.array).data = data_append_integer((yyvsp[-1].array).data, val, (yyvsp[-1].array).bits); - } --#line 1791 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1813 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 33: --#line 337 "dtc-parser.y" /* yacc.c:1646 */ -+ case 35: -+#line 353 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.array).data = data_add_marker((yyvsp[-1].array).data, LABEL, (yyvsp[0].labelref)); - } --#line 1799 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1821 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 36: --#line 346 "dtc-parser.y" /* yacc.c:1646 */ -+ case 38: -+#line 362 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.integer) = (yyvsp[-1].integer); - } --#line 1807 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1829 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 39: --#line 357 "dtc-parser.y" /* yacc.c:1646 */ -+ case 41: -+#line 373 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-4].integer) ? (yyvsp[-2].integer) : (yyvsp[0].integer); } --#line 1813 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1835 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 41: --#line 362 "dtc-parser.y" /* yacc.c:1646 */ -+ case 43: -+#line 378 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) || (yyvsp[0].integer); } --#line 1819 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1841 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 43: --#line 367 "dtc-parser.y" /* yacc.c:1646 */ -+ case 45: -+#line 383 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) && (yyvsp[0].integer); } --#line 1825 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1847 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 45: --#line 372 "dtc-parser.y" /* yacc.c:1646 */ -+ case 47: -+#line 388 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) | (yyvsp[0].integer); } --#line 1831 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1853 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 47: --#line 377 "dtc-parser.y" /* yacc.c:1646 */ -+ case 49: -+#line 393 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) ^ (yyvsp[0].integer); } --#line 1837 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1859 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 49: --#line 382 "dtc-parser.y" /* yacc.c:1646 */ -+ case 51: -+#line 398 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) & (yyvsp[0].integer); } --#line 1843 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1865 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 51: --#line 387 "dtc-parser.y" /* yacc.c:1646 */ -+ case 53: -+#line 403 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) == (yyvsp[0].integer); } --#line 1849 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1871 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 52: --#line 388 "dtc-parser.y" /* yacc.c:1646 */ -+ case 54: -+#line 404 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) != (yyvsp[0].integer); } --#line 1855 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1877 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 54: --#line 393 "dtc-parser.y" /* yacc.c:1646 */ -+ case 56: -+#line 409 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) < (yyvsp[0].integer); } --#line 1861 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1883 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 55: --#line 394 "dtc-parser.y" /* yacc.c:1646 */ -+ case 57: -+#line 410 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) > (yyvsp[0].integer); } --#line 1867 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1889 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 56: --#line 395 "dtc-parser.y" /* yacc.c:1646 */ -+ case 58: -+#line 411 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) <= (yyvsp[0].integer); } --#line 1873 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1895 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 57: --#line 396 "dtc-parser.y" /* yacc.c:1646 */ -+ case 59: -+#line 412 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) >= (yyvsp[0].integer); } --#line 1879 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1901 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 58: --#line 400 "dtc-parser.y" /* yacc.c:1646 */ -+ case 60: -+#line 416 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) << (yyvsp[0].integer); } --#line 1885 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1907 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 59: --#line 401 "dtc-parser.y" /* yacc.c:1646 */ -+ case 61: -+#line 417 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) >> (yyvsp[0].integer); } --#line 1891 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1913 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 61: --#line 406 "dtc-parser.y" /* yacc.c:1646 */ -+ case 63: -+#line 422 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) + (yyvsp[0].integer); } --#line 1897 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1919 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 62: --#line 407 "dtc-parser.y" /* yacc.c:1646 */ -+ case 64: -+#line 423 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) - (yyvsp[0].integer); } --#line 1903 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1925 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 64: --#line 412 "dtc-parser.y" /* yacc.c:1646 */ -+ case 66: -+#line 428 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) * (yyvsp[0].integer); } --#line 1909 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1931 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 65: --#line 414 "dtc-parser.y" /* yacc.c:1646 */ -+ case 67: -+#line 430 "dtc-parser.y" /* yacc.c:1646 */ - { - if ((yyvsp[0].integer) != 0) { - (yyval.integer) = (yyvsp[-2].integer) / (yyvsp[0].integer); -@@ -1918,11 +1940,11 @@ yyreduce: - (yyval.integer) = 0; - } - } --#line 1922 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1944 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 66: --#line 423 "dtc-parser.y" /* yacc.c:1646 */ -+ case 68: -+#line 439 "dtc-parser.y" /* yacc.c:1646 */ - { - if ((yyvsp[0].integer) != 0) { - (yyval.integer) = (yyvsp[-2].integer) % (yyvsp[0].integer); -@@ -1931,103 +1953,103 @@ yyreduce: - (yyval.integer) = 0; - } - } --#line 1935 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1957 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 69: --#line 436 "dtc-parser.y" /* yacc.c:1646 */ -+ case 71: -+#line 452 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = -(yyvsp[0].integer); } --#line 1941 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1963 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 70: --#line 437 "dtc-parser.y" /* yacc.c:1646 */ -+ case 72: -+#line 453 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = ~(yyvsp[0].integer); } --#line 1947 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1969 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 71: --#line 438 "dtc-parser.y" /* yacc.c:1646 */ -+ case 73: -+#line 454 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = !(yyvsp[0].integer); } --#line 1953 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1975 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 72: --#line 443 "dtc-parser.y" /* yacc.c:1646 */ -+ case 74: -+#line 459 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = empty_data; - } --#line 1961 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1983 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 73: --#line 447 "dtc-parser.y" /* yacc.c:1646 */ -+ case 75: -+#line 463 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = data_append_byte((yyvsp[-1].data), (yyvsp[0].byte)); - } --#line 1969 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1991 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 74: --#line 451 "dtc-parser.y" /* yacc.c:1646 */ -+ case 76: -+#line 467 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); - } --#line 1977 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1999 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 75: --#line 458 "dtc-parser.y" /* yacc.c:1646 */ -+ case 77: -+#line 474 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.nodelist) = NULL; - } --#line 1985 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 2007 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 76: --#line 462 "dtc-parser.y" /* yacc.c:1646 */ -+ case 78: -+#line 478 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.nodelist) = chain_node((yyvsp[-1].node), (yyvsp[0].nodelist)); - } --#line 1993 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 2015 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 77: --#line 466 "dtc-parser.y" /* yacc.c:1646 */ -+ case 79: -+#line 482 "dtc-parser.y" /* yacc.c:1646 */ - { - ERROR(&(yylsp[0]), "Properties must precede subnodes"); - YYERROR; - } --#line 2002 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 2024 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 78: --#line 474 "dtc-parser.y" /* yacc.c:1646 */ -+ case 80: -+#line 490 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.node) = name_node((yyvsp[0].node), (yyvsp[-1].propnodename)); - } --#line 2010 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 2032 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 79: --#line 478 "dtc-parser.y" /* yacc.c:1646 */ -+ case 81: -+#line 494 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.node) = name_node(build_node_delete(), (yyvsp[-1].propnodename)); - } --#line 2018 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 2040 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 80: --#line 482 "dtc-parser.y" /* yacc.c:1646 */ -+ case 82: -+#line 498 "dtc-parser.y" /* yacc.c:1646 */ - { - add_label(&(yyvsp[0].node)->labels, (yyvsp[-1].labelref)); - (yyval.node) = (yyvsp[0].node); - } --#line 2027 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 2049 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - --#line 2031 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 2053 "dtc-parser.tab.c" /* yacc.c:1646 */ - default: break; - } - /* User semantic actions sometimes alter yychar, and that requires -@@ -2262,7 +2284,7 @@ yyreturn: - #endif - return yyresult; - } --#line 488 "dtc-parser.y" /* yacc.c:1906 */ -+#line 504 "dtc-parser.y" /* yacc.c:1906 */ - - - void yyerror(char const *s) -diff --git a/scripts/dtc/dtc-parser.tab.h_shipped b/scripts/dtc/dtc-parser.tab.h_shipped -index 30867c6..c2a4246 100644 ---- a/scripts/dtc/dtc-parser.tab.h_shipped -+++ b/scripts/dtc/dtc-parser.tab.h_shipped -@@ -1,8 +1,8 @@ --/* A Bison parser, made by GNU Bison 3.0.2. */ -+/* A Bison parser, made by GNU Bison 3.0.4. */ - - /* Bison interface for Yacc-like parsers in C - -- Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. -+ Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by -@@ -46,35 +46,36 @@ extern int yydebug; - enum yytokentype - { - DT_V1 = 258, -- DT_MEMRESERVE = 259, -- DT_LSHIFT = 260, -- DT_RSHIFT = 261, -- DT_LE = 262, -- DT_GE = 263, -- DT_EQ = 264, -- DT_NE = 265, -- DT_AND = 266, -- DT_OR = 267, -- DT_BITS = 268, -- DT_DEL_PROP = 269, -- DT_DEL_NODE = 270, -- DT_PROPNODENAME = 271, -- DT_LITERAL = 272, -- DT_CHAR_LITERAL = 273, -- DT_BYTE = 274, -- DT_STRING = 275, -- DT_LABEL = 276, -- DT_REF = 277, -- DT_INCBIN = 278 -+ DT_PLUGIN = 259, -+ DT_MEMRESERVE = 260, -+ DT_LSHIFT = 261, -+ DT_RSHIFT = 262, -+ DT_LE = 263, -+ DT_GE = 264, -+ DT_EQ = 265, -+ DT_NE = 266, -+ DT_AND = 267, -+ DT_OR = 268, -+ DT_BITS = 269, -+ DT_DEL_PROP = 270, -+ DT_DEL_NODE = 271, -+ DT_PROPNODENAME = 272, -+ DT_LITERAL = 273, -+ DT_CHAR_LITERAL = 274, -+ DT_BYTE = 275, -+ DT_STRING = 276, -+ DT_LABEL = 277, -+ DT_REF = 278, -+ DT_INCBIN = 279 - }; - #endif - - /* Value type. */ - #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED --typedef union YYSTYPE YYSTYPE; -+ - union YYSTYPE - { --#line 38 "dtc-parser.y" /* yacc.c:1909 */ -+#line 39 "dtc-parser.y" /* yacc.c:1909 */ - - char *propnodename; - char *labelref; -@@ -92,9 +93,12 @@ union YYSTYPE - struct node *nodelist; - struct reserve_info *re; - uint64_t integer; -+ bool is_plugin; - --#line 97 "dtc-parser.tab.h" /* yacc.c:1909 */ -+#line 99 "dtc-parser.tab.h" /* yacc.c:1909 */ - }; -+ -+typedef union YYSTYPE YYSTYPE; - # define YYSTYPE_IS_TRIVIAL 1 - # define YYSTYPE_IS_DECLARED 1 - #endif -diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y -index 000873f..bd67bac 100644 ---- a/scripts/dtc/dtc-parser.y -+++ b/scripts/dtc/dtc-parser.y -@@ -19,6 +19,7 @@ - */ - %{ - #include <stdio.h> -+#include <inttypes.h> - - #include "dtc.h" - #include "srcpos.h" -@@ -52,9 +53,11 @@ extern bool treesource_error; - struct node *nodelist; - struct reserve_info *re; - uint64_t integer; -+ bool is_plugin; - } - - %token DT_V1 -+%token DT_PLUGIN - %token DT_MEMRESERVE - %token DT_LSHIFT DT_RSHIFT DT_LE DT_GE DT_EQ DT_NE DT_AND DT_OR - %token DT_BITS -@@ -71,6 +74,7 @@ extern bool treesource_error; - - %type <data> propdata - %type <data> propdataprefix -+%type <is_plugin> plugindecl - %type <re> memreserve - %type <re> memreserves - %type <array> arrayprefix -@@ -101,10 +105,22 @@ extern bool treesource_error; - %% - - sourcefile: -- DT_V1 ';' memreserves devicetree -+ DT_V1 ';' plugindecl memreserves devicetree - { -- the_boot_info = build_boot_info($3, $4, -- guess_boot_cpuid($4)); -+ $5->is_plugin = $3; -+ the_boot_info = build_boot_info($4, $5, -+ guess_boot_cpuid($5)); -+ } -+ ; -+ -+plugindecl: -+ /* empty */ -+ { -+ $$ = false; -+ } -+ | DT_PLUGIN ';' -+ { -+ $$ = true; - } - ; - -diff --git a/scripts/dtc/dtc.c b/scripts/dtc/dtc.c -index 5fa23c4..1f8c285 100644 ---- a/scripts/dtc/dtc.c -+++ b/scripts/dtc/dtc.c -@@ -31,6 +31,7 @@ int reservenum; /* Number of memory reservation slots */ - int minsize; /* Minimum blob size */ - int padsize; /* Additional padding to blob */ - int phandle_format = PHANDLE_BOTH; /* Use linux,phandle or phandle properties */ -+int symbol_fixup_support = 0; - - static void fill_fullpaths(struct node *tree, const char *prefix) - { -@@ -53,7 +54,7 @@ static void fill_fullpaths(struct node *tree, const char *prefix) - #define FDT_VERSION(version) _FDT_VERSION(version) - #define _FDT_VERSION(version) #version - static const char usage_synopsis[] = "dtc [options] <input file>"; --static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:fb:i:H:sW:E:hv"; -+static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:fb:i:H:sW:E:@hv"; - static struct option const usage_long_opts[] = { - {"quiet", no_argument, NULL, 'q'}, - {"in-format", a_argument, NULL, 'I'}, -@@ -71,6 +72,7 @@ static struct option const usage_long_opts[] = { - {"phandle", a_argument, NULL, 'H'}, - {"warning", a_argument, NULL, 'W'}, - {"error", a_argument, NULL, 'E'}, -+ {"symbols", no_argument, NULL, '@'}, - {"help", no_argument, NULL, 'h'}, - {"version", no_argument, NULL, 'v'}, - {NULL, no_argument, NULL, 0x0}, -@@ -101,6 +103,7 @@ static const char * const usage_opts_help[] = { - "\t\tboth - Both \"linux,phandle\" and \"phandle\" properties", - "\n\tEnable/disable warnings (prefix with \"no-\")", - "\n\tEnable/disable errors (prefix with \"no-\")", -+ "\n\tEnable symbols/fixup support", - "\n\tPrint this help and exit", - "\n\tPrint version and exit", - NULL, -@@ -233,7 +236,9 @@ int main(int argc, char *argv[]) - case 'E': - parse_checks_option(false, true, optarg); - break; -- -+ case '@': -+ symbol_fixup_support = 1; -+ break; - case 'h': - usage(NULL); - default: -diff --git a/scripts/dtc/dtc.h b/scripts/dtc/dtc.h -index 56212c8..f163b22 100644 ---- a/scripts/dtc/dtc.h -+++ b/scripts/dtc/dtc.h -@@ -54,6 +54,7 @@ extern int reservenum; /* Number of memory reservation slots */ - extern int minsize; /* Minimum blob size */ - extern int padsize; /* Additional padding to blob */ - extern int phandle_format; /* Use linux,phandle or phandle properties */ -+extern int symbol_fixup_support;/* enable symbols & fixup support */ - - #define PHANDLE_LEGACY 0x1 - #define PHANDLE_EPAPR 0x2 -@@ -132,6 +133,26 @@ struct label { - struct label *next; - }; - -+struct fixup_entry { -+ int offset; -+ struct node *node; -+ struct property *prop; -+ struct fixup_entry *next; -+ bool local_fixup_generated; -+}; -+ -+struct fixup { -+ char *ref; -+ struct fixup_entry *entries; -+ struct fixup *next; -+}; -+ -+struct symbol { -+ struct label *label; -+ struct node *node; -+ struct symbol *next; -+}; -+ - struct property { - bool deleted; - char *name; -@@ -158,6 +179,13 @@ struct node { - int addr_cells, size_cells; - - struct label *labels; -+ -+ struct symbol *symbols; -+ struct fixup_entry *local_fixups; -+ bool emit_local_fixup_node; -+ -+ bool is_plugin; -+ struct fixup *fixups; - }; - - #define for_each_label_withdel(l0, l) \ -@@ -181,6 +209,18 @@ struct node { - for_each_child_withdel(n, c) \ - if (!(c)->deleted) - -+#define for_each_fixup(n, f) \ -+ for ((f) = (n)->fixups; (f); (f) = (f)->next) -+ -+#define for_each_fixup_entry(f, fe) \ -+ for ((fe) = (f)->entries; (fe); (fe) = (fe)->next) -+ -+#define for_each_symbol(n, s) \ -+ for ((s) = (n)->symbols; (s); (s) = (s)->next) -+ -+#define for_each_local_fixup_entry(n, fe) \ -+ for ((fe) = (n)->local_fixups; (fe); (fe) = (fe)->next) -+ - void add_label(struct label **labels, char *label); - void delete_labels(struct label **labels); - -diff --git a/scripts/dtc/flattree.c b/scripts/dtc/flattree.c -index bd99fa2..f8f1e34 100644 ---- a/scripts/dtc/flattree.c -+++ b/scripts/dtc/flattree.c -@@ -255,6 +255,204 @@ static int stringtable_insert(struct data *d, const char *str) - return i; - } - -+static void emit_local_fixups(struct node *tree, struct emitter *emit, -+ void *etarget, struct data *strbuf, struct version_info *vi, -+ struct node *node) -+{ -+ struct fixup_entry *fe, *fen; -+ struct node *child; -+ int nameoff, count; -+ cell_t *buf; -+ struct data d; -+ -+ if (node->emit_local_fixup_node) { -+ -+ /* emit the external fixups (do not emit /) */ -+ if (node != tree) { -+ emit->beginnode(etarget, NULL); -+ emit->string(etarget, node->name, 0); -+ emit->align(etarget, sizeof(cell_t)); -+ } -+ -+ for_each_local_fixup_entry(tree, fe) { -+ if (fe->node != node || fe->local_fixup_generated) -+ continue; -+ -+ /* count the number of fixup entries */ -+ count = 0; -+ for_each_local_fixup_entry(tree, fen) { -+ if (fen->prop != fe->prop) -+ continue; -+ fen->local_fixup_generated = true; -+ count++; -+ } -+ -+ /* allocate buffer */ -+ buf = xmalloc(count * sizeof(cell_t)); -+ -+ /* collect all the offsets in buffer */ -+ count = 0; -+ for_each_local_fixup_entry(tree, fen) { -+ if (fen->prop != fe->prop) -+ continue; -+ fen->local_fixup_generated = true; -+ buf[count++] = cpu_to_fdt32(fen->offset); -+ } -+ d = empty_data; -+ d.len = count * sizeof(cell_t); -+ d.val = (char *)buf; -+ -+ nameoff = stringtable_insert(strbuf, fe->prop->name); -+ emit->property(etarget, fe->prop->labels); -+ emit->cell(etarget, count * sizeof(cell_t)); -+ emit->cell(etarget, nameoff); -+ -+ if ((vi->flags & FTF_VARALIGN) && -+ (count * sizeof(cell_t)) >= 8) -+ emit->align(etarget, 8); -+ -+ emit->data(etarget, d); -+ emit->align(etarget, sizeof(cell_t)); -+ -+ free(buf); -+ } -+ } -+ -+ for_each_child(node, child) -+ emit_local_fixups(tree, emit, etarget, strbuf, vi, child); -+ -+ if (node->emit_local_fixup_node && node != tree) -+ emit->endnode(etarget, tree->labels); -+} -+ -+static void emit_symbols_node(struct node *tree, struct emitter *emit, -+ void *etarget, struct data *strbuf, -+ struct version_info *vi) -+{ -+ struct symbol *sym; -+ int nameoff, vallen; -+ -+ /* do nothing if no symbols */ -+ if (!tree->symbols) -+ return; -+ -+ emit->beginnode(etarget, NULL); -+ emit->string(etarget, "__symbols__", 0); -+ emit->align(etarget, sizeof(cell_t)); -+ -+ for_each_symbol(tree, sym) { -+ -+ vallen = strlen(sym->node->fullpath); -+ -+ nameoff = stringtable_insert(strbuf, sym->label->label); -+ -+ emit->property(etarget, NULL); -+ emit->cell(etarget, vallen + 1); -+ emit->cell(etarget, nameoff); -+ -+ if ((vi->flags & FTF_VARALIGN) && vallen >= 8) -+ emit->align(etarget, 8); -+ -+ emit->string(etarget, sym->node->fullpath, -+ strlen(sym->node->fullpath)); -+ emit->align(etarget, sizeof(cell_t)); -+ } -+ -+ emit->endnode(etarget, NULL); -+} -+ -+static void emit_local_fixups_node(struct node *tree, struct emitter *emit, -+ void *etarget, struct data *strbuf, -+ struct version_info *vi) -+{ -+ struct fixup_entry *fe; -+ struct node *node; -+ -+ /* do nothing if no local fixups */ -+ if (!tree->local_fixups) -+ return; -+ -+ /* mark all nodes that need a local fixup generated (and parents) */ -+ for_each_local_fixup_entry(tree, fe) { -+ node = fe->node; -+ while (node != NULL && !node->emit_local_fixup_node) { -+ node->emit_local_fixup_node = true; -+ node = node->parent; -+ } -+ } -+ -+ /* emit the local fixups node now */ -+ emit->beginnode(etarget, NULL); -+ emit->string(etarget, "__local_fixups__", 0); -+ emit->align(etarget, sizeof(cell_t)); -+ -+ emit_local_fixups(tree, emit, etarget, strbuf, vi, tree); -+ -+ emit->endnode(etarget, tree->labels); -+} -+ -+static void emit_fixups_node(struct node *tree, struct emitter *emit, -+ void *etarget, struct data *strbuf, -+ struct version_info *vi) -+{ -+ struct fixup *f; -+ struct fixup_entry *fe; -+ char *name, *s; -+ const char *fullpath; -+ int namesz, nameoff, vallen; -+ -+ /* do nothing if no fixups */ -+ if (!tree->fixups) -+ return; -+ -+ /* emit the external fixups */ -+ emit->beginnode(etarget, NULL); -+ emit->string(etarget, "__fixups__", 0); -+ emit->align(etarget, sizeof(cell_t)); -+ -+ for_each_fixup(tree, f) { -+ -+ namesz = 0; -+ for_each_fixup_entry(f, fe) { -+ fullpath = fe->node->fullpath; -+ if (fullpath[0] == '\0') -+ fullpath = "/"; -+ namesz += strlen(fullpath) + 1; -+ namesz += strlen(fe->prop->name) + 1; -+ namesz += 32; /* space for :<number> + '\0' */ -+ } -+ -+ name = xmalloc(namesz); -+ -+ s = name; -+ for_each_fixup_entry(f, fe) { -+ fullpath = fe->node->fullpath; -+ if (fullpath[0] == '\0') -+ fullpath = "/"; -+ snprintf(s, name + namesz - s, "%s:%s:%d", fullpath, -+ fe->prop->name, fe->offset); -+ s += strlen(s) + 1; -+ } -+ -+ nameoff = stringtable_insert(strbuf, f->ref); -+ vallen = s - name - 1; -+ -+ emit->property(etarget, NULL); -+ emit->cell(etarget, vallen + 1); -+ emit->cell(etarget, nameoff); -+ -+ if ((vi->flags & FTF_VARALIGN) && vallen >= 8) -+ emit->align(etarget, 8); -+ -+ emit->string(etarget, name, vallen); -+ emit->align(etarget, sizeof(cell_t)); -+ -+ free(name); -+ } -+ -+ emit->endnode(etarget, tree->labels); -+} -+ - static void flatten_tree(struct node *tree, struct emitter *emit, - void *etarget, struct data *strbuf, - struct version_info *vi) -@@ -310,6 +508,10 @@ static void flatten_tree(struct node *tree, struct emitter *emit, - flatten_tree(child, emit, etarget, strbuf, vi); - } - -+ emit_symbols_node(tree, emit, etarget, strbuf, vi); -+ emit_local_fixups_node(tree, emit, etarget, strbuf, vi); -+ emit_fixups_node(tree, emit, etarget, strbuf, vi); -+ - emit->endnode(etarget, tree->labels); - } - -@@ -889,7 +1091,7 @@ struct boot_info *dt_from_blob(const char *fname) - - if (version >= 3) { - uint32_t size_str = fdt32_to_cpu(fdt->size_dt_strings); -- if (off_str+size_str > totalsize) -+ if ((off_str+size_str < off_str) || (off_str+size_str > totalsize)) - die("String table extends past total size\n"); - inbuf_init(&strbuf, blob + off_str, blob + off_str + size_str); - } else { -@@ -898,7 +1100,7 @@ struct boot_info *dt_from_blob(const char *fname) - - if (version >= 17) { - size_dt = fdt32_to_cpu(fdt->size_dt_struct); -- if (off_dt+size_dt > totalsize) -+ if ((off_dt+size_dt < off_dt) || (off_dt+size_dt > totalsize)) - die("Structure block extends past total size\n"); - } - -diff --git a/scripts/dtc/libfdt/fdt_ro.c b/scripts/dtc/libfdt/fdt_ro.c -index e5b3136..50cce86 100644 ---- a/scripts/dtc/libfdt/fdt_ro.c -+++ b/scripts/dtc/libfdt/fdt_ro.c -@@ -647,10 +647,8 @@ int fdt_node_check_compatible(const void *fdt, int nodeoffset, - prop = fdt_getprop(fdt, nodeoffset, "compatible", &len); - if (!prop) - return len; -- if (fdt_stringlist_contains(prop, len, compatible)) -- return 0; -- else -- return 1; -+ -+ return !fdt_stringlist_contains(prop, len, compatible); - } - - int fdt_node_offset_by_compatible(const void *fdt, int startoffset, -diff --git a/scripts/dtc/libfdt/libfdt.h b/scripts/dtc/libfdt/libfdt.h -index 59ca339..f7e3989 100644 ---- a/scripts/dtc/libfdt/libfdt.h -+++ b/scripts/dtc/libfdt/libfdt.h -@@ -174,21 +174,21 @@ int fdt_next_subnode(const void *fdt, int offset); - - #define fdt_get_header(fdt, field) \ - (fdt32_to_cpu(((const struct fdt_header *)(fdt))->field)) --#define fdt_magic(fdt) (fdt_get_header(fdt, magic)) -+#define fdt_magic(fdt) (fdt_get_header(fdt, magic)) - #define fdt_totalsize(fdt) (fdt_get_header(fdt, totalsize)) - #define fdt_off_dt_struct(fdt) (fdt_get_header(fdt, off_dt_struct)) - #define fdt_off_dt_strings(fdt) (fdt_get_header(fdt, off_dt_strings)) - #define fdt_off_mem_rsvmap(fdt) (fdt_get_header(fdt, off_mem_rsvmap)) - #define fdt_version(fdt) (fdt_get_header(fdt, version)) --#define fdt_last_comp_version(fdt) (fdt_get_header(fdt, last_comp_version)) --#define fdt_boot_cpuid_phys(fdt) (fdt_get_header(fdt, boot_cpuid_phys)) --#define fdt_size_dt_strings(fdt) (fdt_get_header(fdt, size_dt_strings)) -+#define fdt_last_comp_version(fdt) (fdt_get_header(fdt, last_comp_version)) -+#define fdt_boot_cpuid_phys(fdt) (fdt_get_header(fdt, boot_cpuid_phys)) -+#define fdt_size_dt_strings(fdt) (fdt_get_header(fdt, size_dt_strings)) - #define fdt_size_dt_struct(fdt) (fdt_get_header(fdt, size_dt_struct)) - - #define __fdt_set_hdr(name) \ - static inline void fdt_set_##name(void *fdt, uint32_t val) \ - { \ -- struct fdt_header *fdth = (struct fdt_header*)fdt; \ -+ struct fdt_header *fdth = (struct fdt_header *)fdt; \ - fdth->name = cpu_to_fdt32(val); \ - } - __fdt_set_hdr(magic); -@@ -318,8 +318,9 @@ int fdt_subnode_offset_namelen(const void *fdt, int parentoffset, - * returns: - * structure block offset of the requested subnode (>=0), on success - * -FDT_ERR_NOTFOUND, if the requested subnode does not exist -- * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE tag -- * -FDT_ERR_BADMAGIC, -+ * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE -+ * tag -+ * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, -@@ -351,7 +352,8 @@ int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen); - * address). - * - * returns: -- * structure block offset of the node with the requested path (>=0), on success -+ * structure block offset of the node with the requested path (>=0), on -+ * success - * -FDT_ERR_BADPATH, given path does not begin with '/' or is invalid - * -FDT_ERR_NOTFOUND, if the requested node does not exist - * -FDT_ERR_BADMAGIC, -@@ -375,10 +377,12 @@ int fdt_path_offset(const void *fdt, const char *path); - * - * returns: - * pointer to the node's name, on success -- * If lenp is non-NULL, *lenp contains the length of that name (>=0) -+ * If lenp is non-NULL, *lenp contains the length of that name -+ * (>=0) - * NULL, on error - * if lenp is non-NULL *lenp contains an error code (<0): -- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag -+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE -+ * tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, standard meanings -@@ -490,7 +494,8 @@ const struct fdt_property *fdt_get_property_namelen(const void *fdt, - * NULL, on error - * if lenp is non-NULL, *lenp contains an error code (<0): - * -FDT_ERR_NOTFOUND, node does not have named property -- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag -+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE -+ * tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, -@@ -575,7 +580,8 @@ const void *fdt_getprop_namelen(const void *fdt, int nodeoffset, - * NULL, on error - * if lenp is non-NULL, *lenp contains an error code (<0): - * -FDT_ERR_NOTFOUND, node does not have named property -- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag -+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE -+ * tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, -@@ -647,7 +653,7 @@ const char *fdt_get_alias(const void *fdt, const char *name); - * 0, on success - * buf contains the absolute path of the node at - * nodeoffset, as a NUL-terminated string. -- * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag -+ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag - * -FDT_ERR_NOSPACE, the path of the given node is longer than (bufsize-1) - * characters and will not fit in the given buffer. - * -FDT_ERR_BADMAGIC, -@@ -677,11 +683,11 @@ int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen); - * structure from the start to nodeoffset. - * - * returns: -- - * structure block offset of the node at node offset's ancestor - * of depth supernodedepth (>=0), on success -- * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag --* -FDT_ERR_NOTFOUND, supernodedepth was greater than the depth of nodeoffset -+ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag -+ * -FDT_ERR_NOTFOUND, supernodedepth was greater than the depth of -+ * nodeoffset - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, -@@ -703,7 +709,7 @@ int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset, - * - * returns: - * depth of the node at nodeoffset (>=0), on success -- * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag -+ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, -@@ -726,7 +732,7 @@ int fdt_node_depth(const void *fdt, int nodeoffset); - * returns: - * structure block offset of the parent of the node at nodeoffset - * (>=0), on success -- * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag -+ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, -@@ -766,7 +772,7 @@ int fdt_parent_offset(const void *fdt, int nodeoffset); - * on success - * -FDT_ERR_NOTFOUND, no node matching the criterion exists in the - * tree after startoffset -- * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag -+ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, -@@ -813,7 +819,7 @@ int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle); - * 1, if the node has a 'compatible' property, but it does not list - * the given string - * -FDT_ERR_NOTFOUND, if the given node has no 'compatible' property -- * -FDT_ERR_BADOFFSET, if nodeoffset does not refer to a BEGIN_NODE tag -+ * -FDT_ERR_BADOFFSET, if nodeoffset does not refer to a BEGIN_NODE tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, -@@ -850,7 +856,7 @@ int fdt_node_check_compatible(const void *fdt, int nodeoffset, - * on success - * -FDT_ERR_NOTFOUND, no node matching the criterion exists in the - * tree after startoffset -- * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag -+ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, -@@ -960,7 +966,8 @@ const char *fdt_stringlist_get(const void *fdt, int nodeoffset, - * returns: - * 0 <= n < FDT_MAX_NCELLS, on success - * 2, if the node has no #address-cells property -- * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid #address-cells property -+ * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid -+ * #address-cells property - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, -@@ -980,7 +987,8 @@ int fdt_address_cells(const void *fdt, int nodeoffset); - * returns: - * 0 <= n < FDT_MAX_NCELLS, on success - * 2, if the node has no #address-cells property -- * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid #size-cells property -+ * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid -+ * #size-cells property - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, -@@ -1604,9 +1612,11 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset, - * change the offsets of some existing nodes. - - * returns: -- * structure block offset of the created nodeequested subnode (>=0), on success -+ * structure block offset of the created nodeequested subnode (>=0), on -+ * success - * -FDT_ERR_NOTFOUND, if the requested subnode does not exist -- * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE tag -+ * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE -+ * tag - * -FDT_ERR_EXISTS, if the node at parentoffset already has a subnode of - * the given name - * -FDT_ERR_NOSPACE, if there is insufficient free space in the -diff --git a/scripts/dtc/version_gen.h b/scripts/dtc/version_gen.h -index 11d93e6..d2c2bd3 100644 ---- a/scripts/dtc/version_gen.h -+++ b/scripts/dtc/version_gen.h -@@ -1 +1 @@ --#define DTC_VERSION "DTC 1.4.1-gb06e55c8" -+#define DTC_VERSION "DTC 1.4.1-g640cd742" --- -2.7.0 - diff --git a/patches/beaglebone/dtbs/0001-sync-am335x-peripheral-pinmux.patch b/patches/beaglebone/dtbs/0001-sync-am335x-peripheral-pinmux.patch index 0586879d6cc13624b4d672a4502f6b66866f4060..f09272df6d1f75811d343c250e7a467ec09baa67 100644 --- a/patches/beaglebone/dtbs/0001-sync-am335x-peripheral-pinmux.patch +++ b/patches/beaglebone/dtbs/0001-sync-am335x-peripheral-pinmux.patch @@ -1,13 +1,12 @@ -From b077a58b83f3564fcecd97872ed8fd5c527db368 Mon Sep 17 00:00:00 2001 +From 6e850c61dea58fd2ea70855af701dcfbfc9b9bc4 Mon Sep 17 00:00:00 2001 From: Robert Nelson <robertcnelson@gmail.com> -Date: Fri, 8 Apr 2016 18:18:07 -0500 +Date: Wed, 18 May 2016 20:26:44 -0500 Subject: [PATCH] sync: am335x-peripheral/pinmux Signed-off-by: Robert Nelson <robertcnelson@gmail.com> --- - arch/arm/boot/dts/am335x-abbbi.dts | 19 ++-- - arch/arm/boot/dts/am335x-arduino-tre.dts | 1 + - .../boot/dts/am335x-bone-common-no-capemgr.dtsi | 10 +- + arch/arm/boot/dts/am335x-abbbi.dts | 29 +++-- + .../boot/dts/am335x-bone-common-no-capemgr.dtsi | 12 +-- arch/arm/boot/dts/am335x-bone-common.dtsi | 6 +- arch/arm/boot/dts/am335x-bone-emmc-in-reset.dtsi | 18 ++++ arch/arm/boot/dts/am335x-bone-pinmux-can1.dtsi | 45 ++++++++ @@ -18,20 +17,19 @@ Signed-off-by: Robert Nelson <robertcnelson@gmail.com> arch/arm/boot/dts/am335x-bone-pinmux-spi1.dtsi | 27 +++++ arch/arm/boot/dts/am335x-bone-pinmux-spi1a.dtsi | 28 +++++ arch/arm/boot/dts/am335x-bone-pinmux-ttyS5.dtsi | 48 +++++++++ - arch/arm/boot/dts/am335x-boneblack-audio.dts | 15 +-- - arch/arm/boot/dts/am335x-boneblack-bbb-exp-c.dts | 5 +- - arch/arm/boot/dts/am335x-boneblack-bbb-exp-r.dts | 5 +- - arch/arm/boot/dts/am335x-boneblack-bbbmini.dts | 5 +- - .../boot/dts/am335x-boneblack-cape-bone-argus.dts | 5 +- - .../arm/boot/dts/am335x-boneblack-emmc-overlay.dts | 5 +- - .../arm/boot/dts/am335x-boneblack-hdmi-overlay.dts | 5 +- - .../boot/dts/am335x-boneblack-nhdmi-overlay.dts | 5 +- - arch/arm/boot/dts/am335x-boneblack-overlay.dts | 5 +- - arch/arm/boot/dts/am335x-boneblack-wl1835mod.dts | 5 +- - arch/arm/boot/dts/am335x-boneblack.dts | 6 +- - arch/arm/boot/dts/am335x-bonegreen-overlay.dts | 5 +- - arch/arm/boot/dts/am335x-bonegreen-wireless.dts | 1 + - arch/arm/boot/dts/am335x-bonegreen.dts | 20 +--- + arch/arm/boot/dts/am335x-boneblack-audio.dts | 25 +++-- + arch/arm/boot/dts/am335x-boneblack-bbb-exp-c.dts | 11 +- + arch/arm/boot/dts/am335x-boneblack-bbb-exp-r.dts | 11 +- + arch/arm/boot/dts/am335x-boneblack-bbbmini.dts | 15 ++- + .../boot/dts/am335x-boneblack-cape-bone-argus.dts | 15 ++- + .../arm/boot/dts/am335x-boneblack-emmc-overlay.dts | 11 +- + .../arm/boot/dts/am335x-boneblack-hdmi-overlay.dts | 16 ++- + .../boot/dts/am335x-boneblack-nhdmi-overlay.dts | 16 ++- + arch/arm/boot/dts/am335x-boneblack-overlay.dts | 11 +- + arch/arm/boot/dts/am335x-boneblack-wl1835mod.dts | 15 ++- + arch/arm/boot/dts/am335x-boneblack.dts | 5 +- + arch/arm/boot/dts/am335x-bonegreen-overlay.dts | 4 - + arch/arm/boot/dts/am335x-bonegreen.dts | 19 ---- arch/arm/boot/dts/am335x-cape-rtc-ds1307.dtsi | 31 ++++++ arch/arm/boot/dts/am335x-peripheral-can1.dtsi | 13 +++ arch/arm/boot/dts/am335x-peripheral-emmc.dtsi | 15 +++ @@ -41,9 +39,8 @@ Signed-off-by: Robert Nelson <robertcnelson@gmail.com> arch/arm/boot/dts/am335x-peripheral-spi1.dtsi | 13 +++ arch/arm/boot/dts/am335x-peripheral-spi1a.dtsi | 13 +++ arch/arm/boot/dts/am335x-peripheral-ttyS5.dtsi | 13 +++ - arch/arm/boot/dts/am335x-sancloud-bbe.dts | 5 +- - arch/arm/boot/dts/am33xx-es2.dtsi | 34 ++++++ - 38 files changed, 697 insertions(+), 93 deletions(-) + arch/arm/boot/dts/am335x-sancloud-bbe.dts | 4 - + 35 files changed, 762 insertions(+), 86 deletions(-) create mode 100644 arch/arm/boot/dts/am335x-bone-emmc-in-reset.dtsi create mode 100644 arch/arm/boot/dts/am335x-bone-pinmux-can1.dtsi create mode 100644 arch/arm/boot/dts/am335x-bone-pinmux-emmc.dtsi @@ -62,21 +59,30 @@ Signed-off-by: Robert Nelson <robertcnelson@gmail.com> create mode 100644 arch/arm/boot/dts/am335x-peripheral-spi1.dtsi create mode 100644 arch/arm/boot/dts/am335x-peripheral-spi1a.dtsi create mode 100644 arch/arm/boot/dts/am335x-peripheral-ttyS5.dtsi - create mode 100644 arch/arm/boot/dts/am33xx-es2.dtsi diff --git a/arch/arm/boot/dts/am335x-abbbi.dts b/arch/arm/boot/dts/am335x-abbbi.dts -index cc9b1f4..5fa9349 100644 +index cc9b1f4..accf950 100644 --- a/arch/arm/boot/dts/am335x-abbbi.dts +++ b/arch/arm/boot/dts/am335x-abbbi.dts -@@ -9,6 +9,7 @@ - /dts-v1/; - - #include "am33xx.dtsi" -+#include "am33xx-es2.dtsi" - #include "am335x-bone-common.dtsi" - #include "am33xx-overlay-edma-fix.dtsi" +@@ -35,6 +35,17 @@ + status = "okay"; + }; -@@ -129,21 +130,21 @@ ++&cpu0_opp_table { ++ /* ++ * All PG 2.0 silicon may not support 1GHz but some of the early ++ * BeagleBone Blacks have PG 2.0 silicon which is guaranteed ++ * to support 1GHz OPP so enable it for PG 2.0 on this board. ++ */ ++ oppnitro@1000000000 { ++ opp-supported-hw = <0x06 0x0100>; ++ }; ++}; ++ + &am33xx_pinmux { + adi_hdmi_bbbi_pins: adi_hdmi_bbbi_pins { + pinctrl-single,pins = < +@@ -129,21 +140,21 @@ / { clk_mcasp0_fixed: clk_mcasp0_fixed { @@ -107,22 +113,19 @@ index cc9b1f4..5fa9349 100644 }; sound { -diff --git a/arch/arm/boot/dts/am335x-arduino-tre.dts b/arch/arm/boot/dts/am335x-arduino-tre.dts -index 9e27df0..0e6b364 100644 ---- a/arch/arm/boot/dts/am335x-arduino-tre.dts -+++ b/arch/arm/boot/dts/am335x-arduino-tre.dts -@@ -8,6 +8,7 @@ - /dts-v1/; - - #include "am33xx.dtsi" -+#include "am33xx-es2.dtsi" - - / { - model = "TI AM335x Arduino Tre"; diff --git a/arch/arm/boot/dts/am335x-bone-common-no-capemgr.dtsi b/arch/arm/boot/dts/am335x-bone-common-no-capemgr.dtsi -index 1f272a1..fa5311f 100644 +index 1f272a1..12464cc 100644 --- a/arch/arm/boot/dts/am335x-bone-common-no-capemgr.dtsi +++ b/arch/arm/boot/dts/am335x-bone-common-no-capemgr.dtsi +@@ -267,7 +267,7 @@ + /* VDD_MPU voltage limits 0.95V - 1.26V with +/-4% tolerance */ + regulator-name = "vdd_mpu"; + regulator-min-microvolt = <925000>; +- regulator-max-microvolt = <1325000>; ++ regulator-max-microvolt = <1351500>; + regulator-boot-on; + regulator-always-on; + }; @@ -308,15 +308,11 @@ phy-mode = "mii"; }; @@ -149,7 +152,7 @@ index 1f272a1..fa5311f 100644 + system-power-controller; +}; diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi -index 7e59d0b..b34f3bb 100644 +index 483ece1..05fce10 100644 --- a/arch/arm/boot/dts/am335x-bone-common.dtsi +++ b/arch/arm/boot/dts/am335x-bone-common.dtsi @@ -357,15 +357,11 @@ @@ -694,18 +697,10 @@ index 0000000..01d0aec + pinctrl-0 = <&uart5_pins>; +}; diff --git a/arch/arm/boot/dts/am335x-boneblack-audio.dts b/arch/arm/boot/dts/am335x-boneblack-audio.dts -index cac3626..1c5299c 100644 +index cac3626..44e9f9c 100644 --- a/arch/arm/boot/dts/am335x-boneblack-audio.dts +++ b/arch/arm/boot/dts/am335x-boneblack-audio.dts -@@ -8,6 +8,7 @@ - /dts-v1/; - - #include "am33xx.dtsi" -+#include "am33xx-es2.dtsi" - #include "am335x-bone-common.dtsi" - - / { -@@ -15,16 +16,16 @@ +@@ -15,16 +15,16 @@ compatible = "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx"; clk_mcasp0_fixed: clk_mcasp0_fixed { @@ -729,61 +724,88 @@ index cac3626..1c5299c 100644 }; }; +@@ -37,3 +37,14 @@ + &mmc1 { + vmmc-supply = <&vmmcsd_fixed>; + }; ++ ++&cpu0_opp_table { ++ /* ++ * All PG 2.0 silicon may not support 1GHz but some of the early ++ * BeagleBone Blacks have PG 2.0 silicon which is guaranteed ++ * to support 1GHz OPP so enable it for PG 2.0 on this board. ++ */ ++ oppnitro@1000000000 { ++ opp-supported-hw = <0x06 0x0100>; ++ }; ++}; diff --git a/arch/arm/boot/dts/am335x-boneblack-bbb-exp-c.dts b/arch/arm/boot/dts/am335x-boneblack-bbb-exp-c.dts -index 857c21e..f5ec278 100644 +index 857c21e..8d795c0 100644 --- a/arch/arm/boot/dts/am335x-boneblack-bbb-exp-c.dts +++ b/arch/arm/boot/dts/am335x-boneblack-bbb-exp-c.dts -@@ -8,6 +8,7 @@ - /dts-v1/; - - #include "am33xx.dtsi" -+#include "am33xx-es2.dtsi" - #include "am335x-bone-common-no-capemgr.dtsi" - - / { -@@ -33,8 +34,4 @@ +@@ -33,8 +33,15 @@ status = "okay"; }; -&rtc { - system-power-controller; --}; -- ++&cpu0_opp_table { ++ /* ++ * All PG 2.0 silicon may not support 1GHz but some of the early ++ * BeagleBone Blacks have PG 2.0 silicon which is guaranteed ++ * to support 1GHz OPP so enable it for PG 2.0 on this board. ++ */ ++ oppnitro@1000000000 { ++ opp-supported-hw = <0x06 0x0100>; ++ }; + }; + #include "am335x-cape-bbb-exp-c.dtsi" diff --git a/arch/arm/boot/dts/am335x-boneblack-bbb-exp-r.dts b/arch/arm/boot/dts/am335x-boneblack-bbb-exp-r.dts -index b834fa2..27b3b72 100644 +index b834fa2..5df881e 100644 --- a/arch/arm/boot/dts/am335x-boneblack-bbb-exp-r.dts +++ b/arch/arm/boot/dts/am335x-boneblack-bbb-exp-r.dts -@@ -8,6 +8,7 @@ - /dts-v1/; - - #include "am33xx.dtsi" -+#include "am33xx-es2.dtsi" - #include "am335x-bone-common-no-capemgr.dtsi" - - / { -@@ -33,8 +34,4 @@ +@@ -33,8 +33,15 @@ status = "okay"; }; -&rtc { - system-power-controller; --}; -- ++&cpu0_opp_table { ++ /* ++ * All PG 2.0 silicon may not support 1GHz but some of the early ++ * BeagleBone Blacks have PG 2.0 silicon which is guaranteed ++ * to support 1GHz OPP so enable it for PG 2.0 on this board. ++ */ ++ oppnitro@1000000000 { ++ opp-supported-hw = <0x06 0x0100>; ++ }; + }; + #include "am335x-cape-bbb-exp-r.dtsi" diff --git a/arch/arm/boot/dts/am335x-boneblack-bbbmini.dts b/arch/arm/boot/dts/am335x-boneblack-bbbmini.dts -index adb317c..8e41afc 100644 +index adb317c..5ed89a2 100644 --- a/arch/arm/boot/dts/am335x-boneblack-bbbmini.dts +++ b/arch/arm/boot/dts/am335x-boneblack-bbbmini.dts -@@ -9,6 +9,7 @@ - /dts-v1/; - - #include "am33xx.dtsi" -+#include "am33xx-es2.dtsi" - #include "am335x-bone-common.dtsi" +@@ -37,6 +37,17 @@ + status = "okay"; + }; - #include <dt-bindings/board/am335x-bbw-bbb-base.h> -@@ -194,7 +195,3 @@ ++&cpu0_opp_table { ++ /* ++ * All PG 2.0 silicon may not support 1GHz but some of the early ++ * BeagleBone Blacks have PG 2.0 silicon which is guaranteed ++ * to support 1GHz OPP so enable it for PG 2.0 on this board. ++ */ ++ oppnitro@1000000000 { ++ opp-supported-hw = <0x06 0x0100>; ++ }; ++}; ++ + &am33xx_pinmux { + dcan1_pins: pinmux_dcan1_pins { + pinctrl-single,pins = < +@@ -194,7 +205,3 @@ pinctrl-0 = <&uart5_pins>; status = "okay"; }; @@ -792,18 +814,28 @@ index adb317c..8e41afc 100644 - system-power-controller; -}; diff --git a/arch/arm/boot/dts/am335x-boneblack-cape-bone-argus.dts b/arch/arm/boot/dts/am335x-boneblack-cape-bone-argus.dts -index cecb0fcc..6f16d4c 100644 +index cecb0fcc..c97c912 100644 --- a/arch/arm/boot/dts/am335x-boneblack-cape-bone-argus.dts +++ b/arch/arm/boot/dts/am335x-boneblack-cape-bone-argus.dts -@@ -8,6 +8,7 @@ - /dts-v1/; - - #include "am33xx.dtsi" -+#include "am33xx-es2.dtsi" - #include "am335x-bone-common-no-capemgr.dtsi" +@@ -33,6 +33,17 @@ + status = "okay"; + }; - / { -@@ -91,8 +92,4 @@ ++&cpu0_opp_table { ++ /* ++ * All PG 2.0 silicon may not support 1GHz but some of the early ++ * BeagleBone Blacks have PG 2.0 silicon which is guaranteed ++ * to support 1GHz OPP so enable it for PG 2.0 on this board. ++ */ ++ oppnitro@1000000000 { ++ opp-supported-hw = <0x06 0x0100>; ++ }; ++}; ++ + &am33xx_pinmux { + nxp_hdmi_bonelt_pins: nxp_hdmi_bonelt_pins { + pinctrl-single,pins = < +@@ -91,8 +102,4 @@ }; }; @@ -813,38 +845,49 @@ index cecb0fcc..6f16d4c 100644 - #include "am335x-bone-argus.dtsi" diff --git a/arch/arm/boot/dts/am335x-boneblack-emmc-overlay.dts b/arch/arm/boot/dts/am335x-boneblack-emmc-overlay.dts -index 5946a7e..68ae67c 100644 +index 5946a7e..3859359 100644 --- a/arch/arm/boot/dts/am335x-boneblack-emmc-overlay.dts +++ b/arch/arm/boot/dts/am335x-boneblack-emmc-overlay.dts -@@ -8,6 +8,7 @@ - /dts-v1/; - - #include "am33xx.dtsi" -+#include "am33xx-es2.dtsi" - #include "am335x-bone-common.dtsi" - #include "am33xx-overlay-edma-fix.dtsi" - -@@ -33,7 +34,3 @@ - bus-width = <8>; +@@ -34,6 +34,13 @@ status = "okay"; }; -- + -&rtc { - system-power-controller; --}; ++&cpu0_opp_table { ++ /* ++ * All PG 2.0 silicon may not support 1GHz but some of the early ++ * BeagleBone Blacks have PG 2.0 silicon which is guaranteed ++ * to support 1GHz OPP so enable it for PG 2.0 on this board. ++ */ ++ oppnitro@1000000000 { ++ opp-supported-hw = <0x06 0x0100>; ++ }; + }; diff --git a/arch/arm/boot/dts/am335x-boneblack-hdmi-overlay.dts b/arch/arm/boot/dts/am335x-boneblack-hdmi-overlay.dts -index 9b0a7ba..6d419f7 100644 +index 9b0a7ba..4c3a477 100644 --- a/arch/arm/boot/dts/am335x-boneblack-hdmi-overlay.dts +++ b/arch/arm/boot/dts/am335x-boneblack-hdmi-overlay.dts -@@ -8,6 +8,7 @@ - /dts-v1/; - - #include "am33xx.dtsi" -+#include "am33xx-es2.dtsi" - #include "am335x-bone-common.dtsi" - #include "am33xx-overlay-edma-fix.dtsi" +@@ -36,6 +36,18 @@ + }; + }; -@@ -93,7 +94,3 @@ ++ ++&cpu0_opp_table { ++ /* ++ * All PG 2.0 silicon may not support 1GHz but some of the early ++ * BeagleBone Blacks have PG 2.0 silicon which is guaranteed ++ * to support 1GHz OPP so enable it for PG 2.0 on this board. ++ */ ++ oppnitro@1000000000 { ++ opp-supported-hw = <0x06 0x0100>; ++ }; ++}; ++ + &am33xx_pinmux { + nxp_hdmi_bonelt_pins: nxp_hdmi_bonelt_pins { + pinctrl-single,pins = < +@@ -93,7 +105,3 @@ }; }; }; @@ -853,18 +896,29 @@ index 9b0a7ba..6d419f7 100644 - system-power-controller; -}; diff --git a/arch/arm/boot/dts/am335x-boneblack-nhdmi-overlay.dts b/arch/arm/boot/dts/am335x-boneblack-nhdmi-overlay.dts -index 9b0a7ba..6d419f7 100644 +index 9b0a7ba..4c3a477 100644 --- a/arch/arm/boot/dts/am335x-boneblack-nhdmi-overlay.dts +++ b/arch/arm/boot/dts/am335x-boneblack-nhdmi-overlay.dts -@@ -8,6 +8,7 @@ - /dts-v1/; - - #include "am33xx.dtsi" -+#include "am33xx-es2.dtsi" - #include "am335x-bone-common.dtsi" - #include "am33xx-overlay-edma-fix.dtsi" +@@ -36,6 +36,18 @@ + }; + }; -@@ -93,7 +94,3 @@ ++ ++&cpu0_opp_table { ++ /* ++ * All PG 2.0 silicon may not support 1GHz but some of the early ++ * BeagleBone Blacks have PG 2.0 silicon which is guaranteed ++ * to support 1GHz OPP so enable it for PG 2.0 on this board. ++ */ ++ oppnitro@1000000000 { ++ opp-supported-hw = <0x06 0x0100>; ++ }; ++}; ++ + &am33xx_pinmux { + nxp_hdmi_bonelt_pins: nxp_hdmi_bonelt_pins { + pinctrl-single,pins = < +@@ -93,7 +105,3 @@ }; }; }; @@ -873,38 +927,30 @@ index 9b0a7ba..6d419f7 100644 - system-power-controller; -}; diff --git a/arch/arm/boot/dts/am335x-boneblack-overlay.dts b/arch/arm/boot/dts/am335x-boneblack-overlay.dts -index 880629c..d8051b6 100644 +index 880629c..d8dece7 100644 --- a/arch/arm/boot/dts/am335x-boneblack-overlay.dts +++ b/arch/arm/boot/dts/am335x-boneblack-overlay.dts -@@ -8,6 +8,7 @@ - /dts-v1/; - - #include "am33xx.dtsi" -+#include "am33xx-es2.dtsi" - #include "am335x-bone-common.dtsi" - #include "am33xx-overlay-edma-fix.dtsi" - -@@ -35,7 +36,3 @@ - line-name = "EMMC ResetN"; +@@ -36,6 +36,13 @@ }; }; -- + -&rtc { - system-power-controller; --}; ++&cpu0_opp_table { ++ /* ++ * All PG 2.0 silicon may not support 1GHz but some of the early ++ * BeagleBone Blacks have PG 2.0 silicon which is guaranteed ++ * to support 1GHz OPP so enable it for PG 2.0 on this board. ++ */ ++ oppnitro@1000000000 { ++ opp-supported-hw = <0x06 0x0100>; ++ }; + }; diff --git a/arch/arm/boot/dts/am335x-boneblack-wl1835mod.dts b/arch/arm/boot/dts/am335x-boneblack-wl1835mod.dts -index e376613..ec953a9 100644 +index e376613..f35b64a 100644 --- a/arch/arm/boot/dts/am335x-boneblack-wl1835mod.dts +++ b/arch/arm/boot/dts/am335x-boneblack-wl1835mod.dts -@@ -8,6 +8,7 @@ - /dts-v1/; - - #include "am33xx.dtsi" -+#include "am33xx-es2.dtsi" - #include "am335x-bone-common-no-capemgr.dtsi" - - / { -@@ -25,10 +26,6 @@ +@@ -25,10 +25,6 @@ vmmc-supply = <&vmmcsd_fixed>; }; @@ -915,22 +961,35 @@ index e376613..ec953a9 100644 /* EMMC in reset */ &gpio1 { emmc_rst { +@@ -39,4 +35,15 @@ + }; + }; + ++&cpu0_opp_table { ++ /* ++ * All PG 2.0 silicon may not support 1GHz but some of the early ++ * BeagleBone Blacks have PG 2.0 silicon which is guaranteed ++ * to support 1GHz OPP so enable it for PG 2.0 on this board. ++ */ ++ oppnitro@1000000000 { ++ opp-supported-hw = <0x06 0x0100>; ++ }; ++}; ++ + #include "am335x-boneblack-wl1835mod-cape.dtsi" diff --git a/arch/arm/boot/dts/am335x-boneblack.dts b/arch/arm/boot/dts/am335x-boneblack.dts -index db5beb5..11e4a16 100644 +index 315bd5d..944c16c 100644 --- a/arch/arm/boot/dts/am335x-boneblack.dts +++ b/arch/arm/boot/dts/am335x-boneblack.dts -@@ -8,8 +8,10 @@ - /dts-v1/; - +@@ -10,6 +10,7 @@ #include "am33xx.dtsi" -+#include "am33xx-es2.dtsi" #include "am335x-bone-common.dtsi" #include "am33xx-overlay-edma-fix.dtsi" +/* #include "am335x-bone-jtag.dtsi" */ / { model = "TI AM335x BeagleBone Black"; -@@ -91,7 +93,3 @@ +@@ -102,7 +103,3 @@ }; }; }; @@ -939,18 +998,10 @@ index db5beb5..11e4a16 100644 - system-power-controller; -}; diff --git a/arch/arm/boot/dts/am335x-bonegreen-overlay.dts b/arch/arm/boot/dts/am335x-bonegreen-overlay.dts -index b87a606..c4bb320 100644 +index b87a606..da54bf3 100644 --- a/arch/arm/boot/dts/am335x-bonegreen-overlay.dts +++ b/arch/arm/boot/dts/am335x-bonegreen-overlay.dts -@@ -8,6 +8,7 @@ - /dts-v1/; - - #include "am33xx.dtsi" -+#include "am33xx-es2.dtsi" - #include "am335x-bone-common.dtsi" - #include "am33xx-overlay-edma-fix.dtsi" - -@@ -35,7 +36,3 @@ +@@ -35,7 +35,3 @@ line-name = "EMMC ResetN"; }; }; @@ -958,31 +1009,11 @@ index b87a606..c4bb320 100644 -&rtc { - system-power-controller; -}; -diff --git a/arch/arm/boot/dts/am335x-bonegreen-wireless.dts b/arch/arm/boot/dts/am335x-bonegreen-wireless.dts -index b4fabfe..44c872d 100644 ---- a/arch/arm/boot/dts/am335x-bonegreen-wireless.dts -+++ b/arch/arm/boot/dts/am335x-bonegreen-wireless.dts -@@ -8,6 +8,7 @@ - /dts-v1/; - - #include "am33xx.dtsi" -+#include "am33xx-es2.dtsi" - #include "am335x-bone-common.dtsi" - #include "am335x-bonegreen-wl1835.dtsi" - diff --git a/arch/arm/boot/dts/am335x-bonegreen.dts b/arch/arm/boot/dts/am335x-bonegreen.dts -index 42ac698..ef2e6cd 100644 +index 42ac698..14b74cc 100644 --- a/arch/arm/boot/dts/am335x-bonegreen.dts +++ b/arch/arm/boot/dts/am335x-bonegreen.dts -@@ -8,6 +8,7 @@ - /dts-v1/; - - #include "am33xx.dtsi" -+#include "am33xx-es2.dtsi" - #include "am335x-bone-common.dtsi" - #include "am33xx-overlay-edma-fix.dtsi" - -@@ -33,22 +34,3 @@ +@@ -33,22 +33,3 @@ bus-width = <8>; status = "okay"; }; @@ -1213,18 +1244,10 @@ index 0000000..8b42fb0 + status = "okay"; +}; diff --git a/arch/arm/boot/dts/am335x-sancloud-bbe.dts b/arch/arm/boot/dts/am335x-sancloud-bbe.dts -index 561f98a..1212a53 100644 +index 561f98a..0cb95a8 100644 --- a/arch/arm/boot/dts/am335x-sancloud-bbe.dts +++ b/arch/arm/boot/dts/am335x-sancloud-bbe.dts -@@ -8,6 +8,7 @@ - /dts-v1/; - - #include "am33xx.dtsi" -+#include "am33xx-es2.dtsi" - #include "am335x-bone-common.dtsi" - #include "am33xx-overlay-edma-fix.dtsi" - #include <dt-bindings/interrupt-controller/irq.h> -@@ -199,7 +200,3 @@ +@@ -199,7 +199,3 @@ //orientation = <0xff 0 0 0 1 0 0 0 0xff>; }; }; @@ -1232,46 +1255,6 @@ index 561f98a..1212a53 100644 -&rtc { - system-power-controller; -}; -diff --git a/arch/arm/boot/dts/am33xx-es2.dtsi b/arch/arm/boot/dts/am33xx-es2.dtsi -new file mode 100644 -index 0000000..6e252d42 ---- /dev/null -+++ b/arch/arm/boot/dts/am33xx-es2.dtsi -@@ -0,0 +1,34 @@ -+/* -+ * Device Tree Source for AM33XX SoC -+ * -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This file is licensed under the terms of the GNU General Public License -+ * version 2. This program is licensed "as is" without any warranty of any -+ * kind, whether express or implied. -+ */ -+ -+/ { -+ cpus { -+ cpu@0 { -+ /* -+ * To consider voltage drop between PMIC and SoC, -+ * tolerance value is reduced to 2% from 4% and -+ * voltage value is increased as a precaution. -+ */ -+ operating-points = < -+ /* kHz uV */ -+ 1000000 1325000 -+ 800000 1300000 -+ 600000 1112000 -+ 300000 969000 -+ >; -+ voltage-tolerance = <2>; /* 2 percentage */ -+ -+ clocks = <&dpll_mpu_ck>; -+ clock-names = "cpu"; -+ -+ clock-latency = <300000>; /* From omap-cpufreq driver */ -+ }; -+ }; -+}; -- -2.8.0.rc3 +2.8.1 diff --git a/patches/beaglebone/dts/0004-tps65217-Enable-KEY_POWER-press-on-AC-loss-PWR_BUT.patch b/patches/beaglebone/dts/0004-tps65217-Enable-KEY_POWER-press-on-AC-loss-PWR_BUT.patch index 98139a2b11808b831bd87074125c4ee5c43c7d5e..ac1fdefe85bdf071c8d6bba6e0f428ff5162031c 100644 --- a/patches/beaglebone/dts/0004-tps65217-Enable-KEY_POWER-press-on-AC-loss-PWR_BUT.patch +++ b/patches/beaglebone/dts/0004-tps65217-Enable-KEY_POWER-press-on-AC-loss-PWR_BUT.patch @@ -14,7 +14,7 @@ Signed-off-by: Robert Nelson <robertcnelson@gmail.com> 3 files changed, 128 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi -index da93a73..7e59d0b 100644 +index 807894a..483ece1 100644 --- a/arch/arm/boot/dts/am335x-bone-common.dtsi +++ b/arch/arm/boot/dts/am335x-bone-common.dtsi @@ -303,6 +303,9 @@ @@ -28,7 +28,7 @@ index da93a73..7e59d0b 100644 dcdc1_reg: regulator@0 { regulator-name = "vdds_dpr"; diff --git a/drivers/mfd/tps65217.c b/drivers/mfd/tps65217.c -index d32b5442..ca19130 100644 +index 049a6fc..403f795 100644 --- a/drivers/mfd/tps65217.c +++ b/drivers/mfd/tps65217.c @@ -24,8 +24,12 @@ @@ -191,8 +191,8 @@ index d32b5442..ca19130 100644 + } + } + - ret = mfd_add_devices(tps->dev, -1, tps65217s, - ARRAY_SIZE(tps65217s), NULL, 0, NULL); + ret = devm_mfd_add_devices(tps->dev, -1, tps65217s, + ARRAY_SIZE(tps65217s), NULL, 0, NULL); if (ret < 0) { diff --git a/include/linux/mfd/tps65217.h b/include/linux/mfd/tps65217.h index ac7fba4..05d24a6 100644 @@ -211,5 +211,5 @@ index ac7fba4..05d24a6 100644 static inline struct tps65217 *dev_to_tps65217(struct device *dev) -- -2.8.0.rc3 +2.8.1 diff --git a/patches/beaglebone/mctrl_gpio/0001-tty-serial-8250-make-UART_MCR-register-access-consis.patch b/patches/beaglebone/mctrl_gpio/0001-tty-serial-8250-make-UART_MCR-register-access-consis.patch deleted file mode 100644 index 010b90a26b5d7c0509dc70be967282184a278190..0000000000000000000000000000000000000000 --- a/patches/beaglebone/mctrl_gpio/0001-tty-serial-8250-make-UART_MCR-register-access-consis.patch +++ /dev/null @@ -1,232 +0,0 @@ -From f1d2e7f8d47154dda86f4d8bb4e5cfaaced9affc Mon Sep 17 00:00:00 2001 -From: Yegor Yefremov <yegorslists@googlemail.com> -Date: Tue, 22 Mar 2016 14:12:06 +0100 -Subject: [PATCH 1/3] tty/serial/8250: make UART_MCR register access consistent - -Introduce serial8250_out_MCR() and serial8250_in_MCR() routines, that -replace following calls: - -serial_out(port, UART_MCR, val) -serial_port_out(up, UART_MCR, val) -serial_in(port, UART_MCR) - -This patch is needed in order to integrate reading/writing of MCR -signals via SERIAL_MCTRL_GPIO infrastructure later. - -CC: Peter Hurley <peter@hurleysoftware.com> -Signed-off-by: Yegor Yefremov <yegorslists@googlemail.com> ---- - drivers/tty/serial/8250/8250.h | 10 ++++++++ - drivers/tty/serial/8250/8250_omap.c | 4 ++-- - drivers/tty/serial/8250/8250_port.c | 47 ++++++++++++++++++------------------- - 3 files changed, 35 insertions(+), 26 deletions(-) - -diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h -index 047a7ba..73bf57d 100644 ---- a/drivers/tty/serial/8250/8250.h -+++ b/drivers/tty/serial/8250/8250.h -@@ -132,6 +132,16 @@ void serial8250_rpm_put(struct uart_8250_port *p); - int serial8250_em485_init(struct uart_8250_port *p); - void serial8250_em485_destroy(struct uart_8250_port *p); - -+static inline void serial8250_out_MCR(struct uart_8250_port *up, int value) -+{ -+ serial_out(up, UART_MCR, value); -+} -+ -+static inline int serial8250_in_MCR(struct uart_8250_port *up) -+{ -+ return serial_in(up, UART_MCR); -+} -+ - #if defined(__alpha__) && !defined(CONFIG_PCI) - /* - * Digital did something really horribly wrong with the OUT1 and OUT2 -diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c -index 6f76051..d8bd8ce 100644 ---- a/drivers/tty/serial/8250/8250_omap.c -+++ b/drivers/tty/serial/8250/8250_omap.c -@@ -274,7 +274,7 @@ static void omap8250_restore_regs(struct uart_8250_port *up) - serial_out(up, UART_EFR, UART_EFR_ECB); - - serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); -- serial_out(up, UART_MCR, UART_MCR_TCRTLR); -+ serial8250_out_MCR(up, UART_MCR_TCRTLR); - serial_out(up, UART_FCR, up->fcr); - - omap8250_update_scr(up, priv); -@@ -290,7 +290,7 @@ static void omap8250_restore_regs(struct uart_8250_port *up) - serial_out(up, UART_LCR, 0); - - /* drop TCR + TLR access, we setup XON/XOFF later */ -- serial_out(up, UART_MCR, up->mcr); -+ serial8250_out_MCR(up, up->mcr); - serial_out(up, UART_IER, up->ier); - - serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); -diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c -index 00ad263..094763b 100644 ---- a/drivers/tty/serial/8250/8250_port.c -+++ b/drivers/tty/serial/8250/8250_port.c -@@ -527,13 +527,13 @@ static void serial8250_clear_fifos(struct uart_8250_port *p) - - static inline void serial8250_em485_rts_after_send(struct uart_8250_port *p) - { -- unsigned char mcr = serial_in(p, UART_MCR); -+ unsigned char mcr = serial8250_in_MCR(p); - - if (p->port.rs485.flags & SER_RS485_RTS_AFTER_SEND) - mcr |= UART_MCR_RTS; - else - mcr &= ~UART_MCR_RTS; -- serial_out(p, UART_MCR, mcr); -+ serial8250_out_MCR(p, mcr); - } - - static void serial8250_em485_handle_start_tx(unsigned long arg); -@@ -785,10 +785,10 @@ static int size_fifo(struct uart_8250_port *up) - old_lcr = serial_in(up, UART_LCR); - serial_out(up, UART_LCR, 0); - old_fcr = serial_in(up, UART_FCR); -- old_mcr = serial_in(up, UART_MCR); -+ old_mcr = serial8250_in_MCR(up); - serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | - UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); -- serial_out(up, UART_MCR, UART_MCR_LOOP); -+ serial8250_out_MCR(up, UART_MCR_LOOP); - serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); - old_dl = serial_dl_read(up); - serial_dl_write(up, 0x0001); -@@ -800,7 +800,7 @@ static int size_fifo(struct uart_8250_port *up) - (count < 256); count++) - serial_in(up, UART_RX); - serial_out(up, UART_FCR, old_fcr); -- serial_out(up, UART_MCR, old_mcr); -+ serial8250_out_MCR(up, old_mcr); - serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); - serial_dl_write(up, old_dl); - serial_out(up, UART_LCR, old_lcr); -@@ -1040,17 +1040,17 @@ static void autoconfig_16550a(struct uart_8250_port *up) - * it's changed. If so, set baud_base in EXCR2 to 921600. -- dwmw2 - */ - serial_out(up, UART_LCR, 0); -- status1 = serial_in(up, UART_MCR); -+ status1 = serial8250_in_MCR(up); - serial_out(up, UART_LCR, 0xE0); - status2 = serial_in(up, 0x02); /* EXCR1 */ - - if (!((status2 ^ status1) & UART_MCR_LOOP)) { - serial_out(up, UART_LCR, 0); -- serial_out(up, UART_MCR, status1 ^ UART_MCR_LOOP); -+ serial8250_out_MCR(up, status1 ^ UART_MCR_LOOP); - serial_out(up, UART_LCR, 0xE0); - status2 = serial_in(up, 0x02); /* EXCR1 */ - serial_out(up, UART_LCR, 0); -- serial_out(up, UART_MCR, status1); -+ serial8250_out_MCR(up, status1); - - if ((status2 ^ status1) & UART_MCR_LOOP) { - unsigned short quot; -@@ -1224,7 +1224,7 @@ static void autoconfig(struct uart_8250_port *up) - } - } - -- save_mcr = serial_in(up, UART_MCR); -+ save_mcr = serial8250_in_MCR(up); - save_lcr = serial_in(up, UART_LCR); - - /* -@@ -1237,9 +1237,9 @@ static void autoconfig(struct uart_8250_port *up) - * that conflicts with COM 1-4 --- we hope! - */ - if (!(port->flags & UPF_SKIP_TEST)) { -- serial_out(up, UART_MCR, UART_MCR_LOOP | 0x0A); -+ serial8250_out_MCR(up, UART_MCR_LOOP | 0x0A); - status1 = serial_in(up, UART_MSR) & 0xF0; -- serial_out(up, UART_MCR, save_mcr); -+ serial8250_out_MCR(up, save_mcr); - if (status1 != 0x90) { - spin_unlock_irqrestore(&port->lock, flags); - DEBUG_AUTOCONF("LOOP test failed (%02x) ", -@@ -1305,7 +1305,7 @@ static void autoconfig(struct uart_8250_port *up) - if (port->type == PORT_RSA) - serial_out(up, UART_RSA_FRR, 0); - #endif -- serial_out(up, UART_MCR, save_mcr); -+ serial8250_out_MCR(up, save_mcr); - serial8250_clear_fifos(up); - serial_in(up, UART_RX); - if (up->capabilities & UART_CAP_UUE) -@@ -1346,19 +1346,18 @@ static void autoconfig_irq(struct uart_8250_port *up) - - /* forget possible initially masked and pending IRQ */ - probe_irq_off(probe_irq_on()); -- save_mcr = serial_in(up, UART_MCR); -+ save_mcr = serial8250_in_MCR(up); - save_ier = serial_in(up, UART_IER); -- serial_out(up, UART_MCR, UART_MCR_OUT1 | UART_MCR_OUT2); -+ serial8250_out_MCR(up, UART_MCR_OUT1 | UART_MCR_OUT2); - - irqs = probe_irq_on(); -- serial_out(up, UART_MCR, 0); -+ serial8250_out_MCR(up, 0); - udelay(10); - if (port->flags & UPF_FOURPORT) { -- serial_out(up, UART_MCR, -- UART_MCR_DTR | UART_MCR_RTS); -+ serial8250_out_MCR(up, UART_MCR_DTR | UART_MCR_RTS); - } else { -- serial_out(up, UART_MCR, -- UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2); -+ serial8250_out_MCR(up, -+ UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2); - } - serial_out(up, UART_IER, 0x0f); /* enable all intrs */ - serial_in(up, UART_LSR); -@@ -1369,7 +1368,7 @@ static void autoconfig_irq(struct uart_8250_port *up) - udelay(20); - irq = probe_irq_off(irqs); - -- serial_out(up, UART_MCR, save_mcr); -+ serial8250_out_MCR(up, save_mcr); - serial_out(up, UART_IER, save_ier); - - if (port->flags & UPF_FOURPORT) -@@ -1542,14 +1541,14 @@ static inline void start_tx_rs485(struct uart_port *port) - del_timer(&em485->stop_tx_timer); - em485->active_timer = NULL; - -- mcr = serial_in(up, UART_MCR); -+ mcr = serial8250_in_MCR(up); - if (!!(up->port.rs485.flags & SER_RS485_RTS_ON_SEND) != - !!(mcr & UART_MCR_RTS)) { - if (up->port.rs485.flags & SER_RS485_RTS_ON_SEND) - mcr |= UART_MCR_RTS; - else - mcr &= ~UART_MCR_RTS; -- serial_out(up, UART_MCR, mcr); -+ serial8250_out_MCR(up, mcr); - - if (up->port.rs485.delay_rts_before_send > 0) { - em485->active_timer = &em485->start_tx_timer; -@@ -1922,7 +1921,7 @@ void serial8250_do_set_mctrl(struct uart_port *port, unsigned int mctrl) - - mcr = (mcr & up->mcr_mask) | up->mcr_force | up->mcr; - -- serial_port_out(port, UART_MCR, mcr); -+ serial8250_out_MCR(up, mcr); - } - EXPORT_SYMBOL_GPL(serial8250_do_set_mctrl); - -@@ -3071,7 +3070,7 @@ static void serial8250_console_restore(struct uart_8250_port *up) - - serial8250_set_divisor(port, baud, quot, frac); - serial_port_out(port, UART_LCR, up->lcr); -- serial_port_out(port, UART_MCR, UART_MCR_DTR | UART_MCR_RTS); -+ serial8250_out_MCR(up, UART_MCR_DTR | UART_MCR_RTS); - } - - /* --- -2.8.0.rc3 - diff --git a/patches/beaglebone/mctrl_gpio/0002-serial-mctrl_gpio-add-modem-control-read-routine.patch b/patches/beaglebone/mctrl_gpio/0002-serial-mctrl_gpio-add-modem-control-read-routine.patch deleted file mode 100644 index 1fb12e0f2dfeb1d2c640711acb696613b89310df..0000000000000000000000000000000000000000 --- a/patches/beaglebone/mctrl_gpio/0002-serial-mctrl_gpio-add-modem-control-read-routine.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 4ea18ddf562c7b602ddef6d359946186a9194cf5 Mon Sep 17 00:00:00 2001 -From: Yegor Yefremov <yegorslists@googlemail.com> -Date: Tue, 22 Mar 2016 14:12:07 +0100 -Subject: [PATCH 2/3] serial: mctrl_gpio: add modem control read routine - -mctrl_gpio_get_outputs() returns the state of following signals: - -RTS, DTR, OUT1, OUT2 - -Signed-off-by: Yegor Yefremov <yegorslists@googlemail.com> ---- - drivers/tty/serial/serial_mctrl_gpio.c | 18 ++++++++++++++++++ - drivers/tty/serial/serial_mctrl_gpio.h | 15 ++++++++++++++- - 2 files changed, 32 insertions(+), 1 deletion(-) - -diff --git a/drivers/tty/serial/serial_mctrl_gpio.c b/drivers/tty/serial/serial_mctrl_gpio.c -index 0214736..bb5e4f9 100644 ---- a/drivers/tty/serial/serial_mctrl_gpio.c -+++ b/drivers/tty/serial/serial_mctrl_gpio.c -@@ -88,6 +88,24 @@ unsigned int mctrl_gpio_get(struct mctrl_gpios *gpios, unsigned int *mctrl) - } - EXPORT_SYMBOL_GPL(mctrl_gpio_get); - -+unsigned int -+mctrl_gpio_get_outputs(struct mctrl_gpios *gpios, unsigned int *mctrl) -+{ -+ enum mctrl_gpio_idx i; -+ -+ for (i = 0; i < UART_GPIO_MAX; i++) { -+ if (gpios->gpio[i] && mctrl_gpios_desc[i].dir_out) { -+ if (gpiod_get_value(gpios->gpio[i])) -+ *mctrl |= mctrl_gpios_desc[i].mctrl; -+ else -+ *mctrl &= ~mctrl_gpios_desc[i].mctrl; -+ } -+ } -+ -+ return *mctrl; -+} -+EXPORT_SYMBOL_GPL(mctrl_gpio_get_outputs); -+ - struct mctrl_gpios *mctrl_gpio_init_noauto(struct device *dev, unsigned int idx) - { - struct mctrl_gpios *gpios; -diff --git a/drivers/tty/serial/serial_mctrl_gpio.h b/drivers/tty/serial/serial_mctrl_gpio.h -index 9716db2..e8ad5e6 100644 ---- a/drivers/tty/serial/serial_mctrl_gpio.h -+++ b/drivers/tty/serial/serial_mctrl_gpio.h -@@ -50,12 +50,19 @@ struct mctrl_gpios; - void mctrl_gpio_set(struct mctrl_gpios *gpios, unsigned int mctrl); - - /* -- * Get state of the modem control output lines from GPIOs. -+ * Get state of the modem control input lines from GPIOs. - * The mctrl flags are updated and returned. - */ - unsigned int mctrl_gpio_get(struct mctrl_gpios *gpios, unsigned int *mctrl); - - /* -+ * Get state of the modem control output lines from GPIOs. -+ * The mctrl flags are updated and returned. -+ */ -+unsigned int -+mctrl_gpio_get_outputs(struct mctrl_gpios *gpios, unsigned int *mctrl); -+ -+/* - * Returns the associated struct gpio_desc to the modem line gidx - */ - struct gpio_desc *mctrl_gpio_to_gpiod(struct mctrl_gpios *gpios, -@@ -109,6 +116,12 @@ unsigned int mctrl_gpio_get(struct mctrl_gpios *gpios, unsigned int *mctrl) - return *mctrl; - } - -+static inline unsigned int -+mctrl_gpio_get_outputs(struct mctrl_gpios *gpios, unsigned int *mctrl) -+{ -+ return *mctrl; -+} -+ - static inline - struct gpio_desc *mctrl_gpio_to_gpiod(struct mctrl_gpios *gpios, - enum mctrl_gpio_idx gidx) --- -2.8.0.rc3 - diff --git a/patches/beaglebone/mctrl_gpio/0003-serial-mctrl_gpio-add-IRQ-locking.patch b/patches/beaglebone/mctrl_gpio/0003-serial-mctrl_gpio-add-IRQ-locking.patch deleted file mode 100644 index 3a2a5f857f6f593e91bce784f24caa4ce0053b82..0000000000000000000000000000000000000000 --- a/patches/beaglebone/mctrl_gpio/0003-serial-mctrl_gpio-add-IRQ-locking.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 23c13f70de5d4b409415bb0779db02d4061ed6eb Mon Sep 17 00:00:00 2001 -From: Yegor Yefremov <yegorslists@googlemail.com> -Date: Tue, 22 Mar 2016 14:12:08 +0100 -Subject: [PATCH 3/3] serial: mctrl_gpio: add IRQ locking -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -uart_handle_cts_change() should be called in IRQ locked state, hence -use port->lock to disable interrupts. - -CC: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> -Signed-off-by: Yegor Yefremov <yegorslists@googlemail.com> ---- - drivers/tty/serial/serial_mctrl_gpio.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/drivers/tty/serial/serial_mctrl_gpio.c b/drivers/tty/serial/serial_mctrl_gpio.c -index bb5e4f9..85b77ba 100644 ---- a/drivers/tty/serial/serial_mctrl_gpio.c -+++ b/drivers/tty/serial/serial_mctrl_gpio.c -@@ -143,6 +143,9 @@ static irqreturn_t mctrl_gpio_irq_handle(int irq, void *context) - struct uart_port *port = gpios->port; - u32 mctrl = gpios->mctrl_prev; - u32 mctrl_diff; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&port->lock, flags); - - mctrl_gpio_get(gpios, &mctrl); - -@@ -165,6 +168,8 @@ static irqreturn_t mctrl_gpio_irq_handle(int irq, void *context) - wake_up_interruptible(&port->state->port.delta_msr_wait); - } - -+ spin_unlock_irqrestore(&port->lock, flags); -+ - return IRQ_HANDLED; - } - --- -2.8.0.rc3 - diff --git a/patches/beaglebone/tilcdc/0023-drm-tilcdc-Write-to-LCDC_END_OF_INT_IND_REG-at-the-e.patch b/patches/beaglebone/tilcdc/0001-drm-tilcdc-Write-to-LCDC_END_OF_INT_IND_REG-at-the-e.patch similarity index 91% rename from patches/beaglebone/tilcdc/0023-drm-tilcdc-Write-to-LCDC_END_OF_INT_IND_REG-at-the-e.patch rename to patches/beaglebone/tilcdc/0001-drm-tilcdc-Write-to-LCDC_END_OF_INT_IND_REG-at-the-e.patch index cdb320dc13770e7a10a965a60c78f51be279719e..bc789fc4a8b5ce0b0499a1fc86d66bb9e69df0a5 100644 --- a/patches/beaglebone/tilcdc/0023-drm-tilcdc-Write-to-LCDC_END_OF_INT_IND_REG-at-the-e.patch +++ b/patches/beaglebone/tilcdc/0001-drm-tilcdc-Write-to-LCDC_END_OF_INT_IND_REG-at-the-e.patch @@ -1,7 +1,7 @@ -From 739b8621b8819a79ef4fd62ae79fd786df1266f4 Mon Sep 17 00:00:00 2001 +From fde10a931679124e08060595c25627374be4cde7 Mon Sep 17 00:00:00 2001 From: Jyri Sarha <jsarha@ti.com> Date: Fri, 8 Apr 2016 12:31:02 +0300 -Subject: [PATCH 23/25] drm/tilcdc: Write to LCDC_END_OF_INT_IND_REG at the end +Subject: [PATCH 1/3] drm/tilcdc: Write to LCDC_END_OF_INT_IND_REG at the end of IRQ function Reorder the IRQ function so that the write to LCDC_END_OF_INT_IND_REG @@ -16,7 +16,7 @@ Signed-off-by: Jyri Sarha <jsarha@ti.com> 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -index 051e5e1..a06e73a 100644 +index 79027b1..7ad9bd7 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c @@ -718,14 +718,19 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc) @@ -60,5 +60,5 @@ index 051e5e1..a06e73a 100644 return IRQ_HANDLED; } -- -2.8.0.rc3 +2.8.1 diff --git a/patches/beaglebone/tilcdc/0001-drm-tilcdc-rewrite-pixel-clock-calculation.patch b/patches/beaglebone/tilcdc/0001-drm-tilcdc-rewrite-pixel-clock-calculation.patch deleted file mode 100644 index bcad43d5ca30099b1938c9b8e558031a2f9f8442..0000000000000000000000000000000000000000 --- a/patches/beaglebone/tilcdc/0001-drm-tilcdc-rewrite-pixel-clock-calculation.patch +++ /dev/null @@ -1,123 +0,0 @@ -From 3d19306a8240a163f6b02bb46213c277d6d44e08 Mon Sep 17 00:00:00 2001 -From: Darren Etheridge <detheridge@ti.com> -Date: Wed, 15 Jan 2014 15:52:36 -0600 -Subject: [PATCH] drm/tilcdc: rewrite pixel clock calculation - -Updating the tilcdc DRM driver code to calculate the LCD controller -pixel clock more accurately. Based on a suggested implementation by -Tomi Valkeinen. - -The current code does not work correctly and produces wrong results -with many requested clock rates. It also oddly uses two different -clocks, a display pll clock and a divider clock (child of display -pll), instead of just using the clock coming to the lcdc. - -This patch removes the use of the display pll clock, and rewrites the -code to calculate the clock rates. The idea is simply to request a -clock rate of pixelclock*2, as the LCD controller has an internal -divider which we set to 2. - -Signed-off-by: Darren Etheridge <detheridge@ti.com> -[Rewrapped description] -Signed-off-by: Jyri Sarha <jsarha@ti.com> -Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ti.com> ---- - drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 16 ++++++++-------- - drivers/gpu/drm/tilcdc/tilcdc_drv.c | 11 +---------- - drivers/gpu/drm/tilcdc/tilcdc_drv.h | 1 - - 3 files changed, 9 insertions(+), 19 deletions(-) - -diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -index 4802da8..aaf8989 100644 ---- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -@@ -573,7 +573,8 @@ void tilcdc_crtc_update_clk(struct drm_crtc *crtc) - struct drm_device *dev = crtc->dev; - struct tilcdc_drm_private *priv = dev->dev_private; - int dpms = tilcdc_crtc->dpms; -- unsigned int lcd_clk, div; -+ unsigned long lcd_clk; -+ const unsigned clkdiv = 2; /* using a fixed divider of 2 */ - int ret; - - pm_runtime_get_sync(dev->dev); -@@ -581,22 +582,21 @@ void tilcdc_crtc_update_clk(struct drm_crtc *crtc) - if (dpms == DRM_MODE_DPMS_ON) - tilcdc_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); - -- /* in raster mode, minimum divisor is 2: */ -- ret = clk_set_rate(priv->disp_clk, crtc->mode.clock * 1000 * 2); -- if (ret) { -+ /* mode.clock is in KHz, set_rate wants parameter in Hz */ -+ ret = clk_set_rate(priv->clk, crtc->mode.clock * 1000 * clkdiv); -+ if (ret < 0) { - dev_err(dev->dev, "failed to set display clock rate to: %d\n", - crtc->mode.clock); - goto out; - } - - lcd_clk = clk_get_rate(priv->clk); -- div = lcd_clk / (crtc->mode.clock * 1000); - -- DBG("lcd_clk=%u, mode clock=%d, div=%u", lcd_clk, crtc->mode.clock, div); -- DBG("fck=%lu, dpll_disp_ck=%lu", clk_get_rate(priv->clk), clk_get_rate(priv->disp_clk)); -+ DBG("lcd_clk=%lu, mode clock=%d, div=%u", -+ lcd_clk, crtc->mode.clock, clkdiv); - - /* Configure the LCD clock divisor. */ -- tilcdc_write(dev, LCDC_CTRL_REG, LCDC_CLK_DIVISOR(div) | -+ tilcdc_write(dev, LCDC_CTRL_REG, LCDC_CLK_DIVISOR(clkdiv) | - LCDC_RASTER_MODE); - - if (priv->rev == 2) -diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c -index 8190ac3..b3dbbe9 100644 ---- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c -+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c -@@ -192,13 +192,6 @@ static int tilcdc_load(struct drm_device *dev, unsigned long flags) - goto fail_iounmap; - } - -- priv->disp_clk = clk_get(dev->dev, "dpll_disp_ck"); -- if (IS_ERR(priv->clk)) { -- dev_err(dev->dev, "failed to get display clock\n"); -- ret = -ENODEV; -- goto fail_put_clk; -- } -- - #ifdef CONFIG_CPU_FREQ - priv->lcd_fck_rate = clk_get_rate(priv->clk); - priv->freq_transition.notifier_call = cpufreq_transition; -@@ -206,7 +199,7 @@ static int tilcdc_load(struct drm_device *dev, unsigned long flags) - CPUFREQ_TRANSITION_NOTIFIER); - if (ret) { - dev_err(dev->dev, "failed to register cpufreq notifier\n"); -- goto fail_put_disp_clk; -+ goto fail_put_clk; - } - #endif - -@@ -330,8 +323,6 @@ fail_cpufreq_unregister: - #ifdef CONFIG_CPU_FREQ - cpufreq_unregister_notifier(&priv->freq_transition, - CPUFREQ_TRANSITION_NOTIFIER); --fail_put_disp_clk: -- clk_put(priv->disp_clk); - #endif - - fail_put_clk: -diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.h b/drivers/gpu/drm/tilcdc/tilcdc_drv.h -index 66105d8..62a1d68 100644 ---- a/drivers/gpu/drm/tilcdc/tilcdc_drv.h -+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.h -@@ -49,7 +49,6 @@ - struct tilcdc_drm_private { - void __iomem *mmio; - -- struct clk *disp_clk; /* display dpll */ - struct clk *clk; /* functional clock */ - int rev; /* IP revision */ - --- -2.7.0 - diff --git a/patches/beaglebone/tilcdc/0024-drm-tilcdc-Move-waiting-of-LCDC_FRAME_DONE-IRQ-into-.patch b/patches/beaglebone/tilcdc/0002-drm-tilcdc-Move-waiting-of-LCDC_FRAME_DONE-IRQ-into-.patch similarity index 91% rename from patches/beaglebone/tilcdc/0024-drm-tilcdc-Move-waiting-of-LCDC_FRAME_DONE-IRQ-into-.patch rename to patches/beaglebone/tilcdc/0002-drm-tilcdc-Move-waiting-of-LCDC_FRAME_DONE-IRQ-into-.patch index 2eb6ac1e9a43661636e0d66352841bbb1c92fa3a..476b64f64ae88beda6133bb4fb6a3d276d66d308 100644 --- a/patches/beaglebone/tilcdc/0024-drm-tilcdc-Move-waiting-of-LCDC_FRAME_DONE-IRQ-into-.patch +++ b/patches/beaglebone/tilcdc/0002-drm-tilcdc-Move-waiting-of-LCDC_FRAME_DONE-IRQ-into-.patch @@ -1,7 +1,7 @@ -From 513c7e9450434a2f71129f8c15b67db4e10cd4b7 Mon Sep 17 00:00:00 2001 +From 2de8bcad44ea3a27e2ed2f86ed00fab9425add05 Mon Sep 17 00:00:00 2001 From: Jyri Sarha <jsarha@ti.com> Date: Fri, 8 Apr 2016 12:31:03 +0300 -Subject: [PATCH 24/25] drm/tilcdc: Move waiting of LCDC_FRAME_DONE IRQ into +Subject: [PATCH 2/3] drm/tilcdc: Move waiting of LCDC_FRAME_DONE IRQ into stop() Move wait queue waiting of LCDC_FRAME_DONE IRQ from tilcdc_crtc_dpms() @@ -13,7 +13,7 @@ Signed-off-by: Jyri Sarha <jsarha@ti.com> 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -index a06e73a..7a5cc03 100644 +index 7ad9bd7..a6682c7 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c @@ -113,9 +113,25 @@ static void start(struct drm_crtc *crtc) @@ -66,5 +66,5 @@ index a06e73a..7a5cc03 100644 if (tilcdc_crtc->next_fb) { -- -2.8.0.rc3 +2.8.1 diff --git a/patches/beaglebone/tilcdc/0002-drm-tilcdc-verify-fb-pitch.patch b/patches/beaglebone/tilcdc/0002-drm-tilcdc-verify-fb-pitch.patch deleted file mode 100644 index 739216d136f5446792b46779e9f3c4c6913a336e..0000000000000000000000000000000000000000 --- a/patches/beaglebone/tilcdc/0002-drm-tilcdc-verify-fb-pitch.patch +++ /dev/null @@ -1,88 +0,0 @@ -From 6f206e9d2a965771e99bca4c22dbadac1b58a0e8 Mon Sep 17 00:00:00 2001 -From: Tomi Valkeinen <tomi.valkeinen@ti.com> -Date: Fri, 7 Feb 2014 17:37:07 +0000 -Subject: [PATCH] drm/tilcdc: verify fb pitch - -LCDC hardware does not support fb pitch that is different (i.e. larger) -than the screen size. The driver currently does no checks for this, and -the results of too big pitch are are flickering and lower fps. - -This issue easily happens when using libdrm's modetest tool with non-32 -bpp modes. As modetest always allocated 4 bytes per pixel, it implies a -bigger pitch for 16 or 24 bpp modes. - -This patch adds a check to reject pitches the hardware cannot support. - -Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> -Signed-off-by: Darren Etheridge <detheridge@ti.com> -Signed-off-by: Jyri Sarha <jsarha@ti.com> ---- - drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 31 +++++++++++++++++++++++++++++++ - 1 file changed, 31 insertions(+) - -diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -index aaf8989..6485e1c 100644 ---- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -@@ -151,6 +151,22 @@ static void tilcdc_crtc_destroy(struct drm_crtc *crtc) - kfree(tilcdc_crtc); - } - -+static int tilcdc_verify_fb(struct drm_crtc *crtc, struct drm_framebuffer *fb) -+{ -+ struct drm_device *dev = crtc->dev; -+ unsigned int depth, bpp; -+ -+ drm_fb_get_bpp_depth(fb->pixel_format, &depth, &bpp); -+ -+ if (fb->pitches[0] != crtc->mode.hdisplay * bpp / 8) { -+ dev_err(dev->dev, -+ "Invalid pitch: fb and crtc widths must be the same"); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ - static int tilcdc_crtc_page_flip(struct drm_crtc *crtc, - struct drm_framebuffer *fb, - struct drm_pending_vblank_event *event, -@@ -158,6 +174,11 @@ static int tilcdc_crtc_page_flip(struct drm_crtc *crtc, - { - struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); - struct drm_device *dev = crtc->dev; -+ int r; -+ -+ r = tilcdc_verify_fb(crtc, fb); -+ if (r) -+ return r; - - if (tilcdc_crtc->event) { - dev_err(dev->dev, "already pending page flip!\n"); -@@ -272,6 +293,10 @@ static int tilcdc_crtc_mode_set(struct drm_crtc *crtc, - if (WARN_ON(!info)) - return -EINVAL; - -+ ret = tilcdc_verify_fb(crtc, crtc->primary->fb); -+ if (ret) -+ return ret; -+ - pm_runtime_get_sync(dev->dev); - - /* Configure the Burst Size and fifo threshold of DMA: */ -@@ -431,6 +456,12 @@ static int tilcdc_crtc_mode_set(struct drm_crtc *crtc, - static int tilcdc_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, - struct drm_framebuffer *old_fb) - { -+ int r; -+ -+ r = tilcdc_verify_fb(crtc, crtc->primary->fb); -+ if (r) -+ return r; -+ - update_scanout(crtc); - return 0; - } --- -2.7.0 - diff --git a/patches/beaglebone/tilcdc/0025-drm-tilcdc-Recover-from-sync-lost-error-flood-by-res.patch b/patches/beaglebone/tilcdc/0003-drm-tilcdc-Recover-from-sync-lost-error-flood-by-res.patch similarity index 93% rename from patches/beaglebone/tilcdc/0025-drm-tilcdc-Recover-from-sync-lost-error-flood-by-res.patch rename to patches/beaglebone/tilcdc/0003-drm-tilcdc-Recover-from-sync-lost-error-flood-by-res.patch index 8c8f6a8296bfd2cd74820209d30665537007f8b0..faa10d697fde8b9ddc5319d4a6ccd3c6272643a5 100644 --- a/patches/beaglebone/tilcdc/0025-drm-tilcdc-Recover-from-sync-lost-error-flood-by-res.patch +++ b/patches/beaglebone/tilcdc/0003-drm-tilcdc-Recover-from-sync-lost-error-flood-by-res.patch @@ -1,7 +1,7 @@ -From 430c28b76b0520dbcfe541ce582f408c0c6521e2 Mon Sep 17 00:00:00 2001 +From 6e8fe065acdeaa55e3887072989127bc0383d2d1 Mon Sep 17 00:00:00 2001 From: Jyri Sarha <jsarha@ti.com> Date: Fri, 8 Apr 2016 12:31:04 +0300 -Subject: [PATCH 25/25] drm/tilcdc: Recover from sync lost error flood by +Subject: [PATCH 3/3] drm/tilcdc: Recover from sync lost error flood by resetting the LCDC Recover from sync lost error flood by resetting the LCDC instead of @@ -17,7 +17,7 @@ Signed-off-by: Jyri Sarha <jsarha@ti.com> 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -index 7a5cc03..6dce763 100644 +index a6682c7..e894fc7 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c @@ -46,6 +46,7 @@ struct tilcdc_crtc { @@ -80,5 +80,5 @@ index 7a5cc03..6dce763 100644 ret = drm_crtc_init(dev, crtc, &tilcdc_crtc_funcs); if (ret < 0) -- -2.8.0.rc3 +2.8.1 diff --git a/patches/beaglebone/tilcdc/0003-drm-tilcdc-adopt-pinctrl-support.patch b/patches/beaglebone/tilcdc/0003-drm-tilcdc-adopt-pinctrl-support.patch deleted file mode 100644 index 757fc5a25e04bbe4e788df1e0754bd91cf930de4..0000000000000000000000000000000000000000 --- a/patches/beaglebone/tilcdc/0003-drm-tilcdc-adopt-pinctrl-support.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 416a07fbe7b1f1a6f7e0595b43b5a85a1c877e05 Mon Sep 17 00:00:00 2001 -From: Dave Gerlach <d-gerlach@ti.com> -Date: Tue, 29 Jul 2014 06:27:58 +0000 -Subject: [PATCH] drm/tilcdc: adopt pinctrl support - -Update tilcdc driver to set the state of the pins to: -- "default on resume -- "sleep" on suspend - -By optionally putting the pins into sleep state in the suspend callback -we can accomplish two things. -- minimize current leakage from pins and thus save power, -- prevent the IP from driving pins output in an uncontrolled manner, -which may happen if the power domain drops the domain regulator. - -Signed-off-by: Dave Gerlach <d-gerlach@ti.com> -Signed-off-by: Darren Etheridge <detheridge@ti.com> -Signed-off-by: Jyri Sarha <jsarha@ti.com> -Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ti.com> ---- - drivers/gpu/drm/tilcdc/tilcdc_drv.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c -index b3dbbe9..420a237 100644 ---- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c -+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c -@@ -18,6 +18,8 @@ - /* LCDC DRM driver, based on da8xx-fb */ - - #include <linux/component.h> -+#include <linux/pinctrl/consumer.h> -+#include <linux/suspend.h> - - #include "tilcdc_drv.h" - #include "tilcdc_regs.h" -@@ -585,6 +587,9 @@ static int tilcdc_pm_suspend(struct device *dev) - if (registers[i].save && (priv->rev >= registers[i].rev)) - priv->saved_register[n++] = tilcdc_read(ddev, registers[i].reg); - -+ /* Select sleep pin state */ -+ pinctrl_pm_select_sleep_state(dev); -+ - return 0; - } - -@@ -594,6 +599,9 @@ static int tilcdc_pm_resume(struct device *dev) - struct tilcdc_drm_private *priv = ddev->dev_private; - unsigned i, n = 0; - -+ /* Select default pin state */ -+ pinctrl_pm_select_default_state(dev); -+ - /* Restore register state: */ - for (i = 0; i < ARRAY_SIZE(registers); i++) - if (registers[i].save && (priv->rev >= registers[i].rev)) --- -2.7.0 - diff --git a/patches/beaglebone/tilcdc/0004-drm-tilcdc-fix-kernel-panic-on-suspend-when-no-hdmi-.patch b/patches/beaglebone/tilcdc/0004-drm-tilcdc-fix-kernel-panic-on-suspend-when-no-hdmi-.patch deleted file mode 100644 index fdbf4f46edfc8a6b7292d237e03226970721772e..0000000000000000000000000000000000000000 --- a/patches/beaglebone/tilcdc/0004-drm-tilcdc-fix-kernel-panic-on-suspend-when-no-hdmi-.patch +++ /dev/null @@ -1,110 +0,0 @@ -From 85fd27f80b3641c9af9f04cde1b712c8c20916d8 Mon Sep 17 00:00:00 2001 -From: Darren Etheridge <detheridge@ti.com> -Date: Fri, 19 Sep 2014 01:42:57 +0000 -Subject: [PATCH] drm/tilcdc: fix kernel panic on suspend when no hdmi monitor - connected - -On BeagleBone Black if no HDMI monitor is connected and suspend -is requested a kernel panic will result: - -root@am335x-evm:~# echo mem > /sys/power/state -[ 65.548710] PM: Syncing filesystems ... done. -[ 65.631311] Freezing user space processes ... (elapsed 0.006 seconds) done. -[ 65.648619] Freezing remaining freezable tasks ... (elapsed 0.005 seconds) done. -[ 65.833500] Unhandled fault: external abort on non-linefetch (0x1028) at 0xfa30e004 -[ 65.841692] Internal error: : 1028 [#1] SMP ARM - <snip> -[ 66.105287] [<c03765f0>] (platform_pm_suspend) from [<c037b6d4>] (dpm_run_callback+0x34/0x70) -[ 66.114370] [<c037b6d4>] (dpm_run_callback) from [<c037ba84>] (__device_suspend+0x10c/0x2f4) -[ 66.123357] [<c037ba84>] (__device_suspend) from [<c037d004>] (dpm_suspend+0x58/0x218) -[ 66.131796] [<c037d004>] (dpm_suspend) from [<c008d948>] (suspend_devices_and_enter+0x9c/0x3c0) -[ 66.141055] [<c008d948>] (suspend_devices_and_enter) from [<c008de7c>] (pm_suspend+0x210/0x24c) -[ 66.150312] [<c008de7c>] (pm_suspend) from [<c008cabc>] (state_store+0x68/0xb8) -[ 66.158103] [<c008cabc>] (state_store) from [<c02e9654>] (kobj_attr_store+0x14/0x20) -[ 66.166355] [<c02e9654>] (kobj_attr_store) from [<c0185c70>] (sysfs_kf_write+0x4c/0x50) -[ 66.174883] [<c0185c70>] (sysfs_kf_write) from [<c018926c>] (kernfs_fop_write+0xb4/0x150) -[ 66.183598] [<c018926c>] (kernfs_fop_write) from [<c0122638>] (vfs_write+0xa8/0x180) -[ 66.191846] [<c0122638>] (vfs_write) from [<c01229f8>] (SyS_write+0x40/0x8c) -[ 66.199365] [<c01229f8>] (SyS_write) from [<c000e580>] (ret_fast_syscall+0x0/0x48) -[ 66.207426] Code: e595c210 e5932000 e59cc000 e08c2002 (e592c000) - -This is because the lcdc module is not enabled when no monitor is detected -to save power. However the suspend handler just blindly tries to save the -lcdc state by copying out the pertinent registers. However module is off -so no good things happen when you try and access it. - -This patch only saves off the registers if the module is enabled, and -then only restores the registers on resume if they were saved off during -suspend. - -Signed-off-by: Darren Etheridge <detheridge@ti.com> -Tested-by: Dave Gerlach <d-gerlach@ti.com> -Acked-by: Felipe Balbi <balbi@ti.com> -Signed-off-by: Jyri Sarha <jsarha@ti.com> -Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ti.com> ---- - drivers/gpu/drm/tilcdc/tilcdc_drv.c | 23 +++++++++++++++++------ - drivers/gpu/drm/tilcdc/tilcdc_drv.h | 1 + - 2 files changed, 18 insertions(+), 6 deletions(-) - -diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c -index 420a237..67ed9f7 100644 ---- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c -+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c -@@ -582,13 +582,20 @@ static int tilcdc_pm_suspend(struct device *dev) - - drm_kms_helper_poll_disable(ddev); - -+ /* Select sleep pin state */ -+ pinctrl_pm_select_sleep_state(dev); -+ -+ if (pm_runtime_suspended(dev)) { -+ priv->ctx_valid = false; -+ return 0; -+ } -+ - /* Save register state: */ - for (i = 0; i < ARRAY_SIZE(registers); i++) - if (registers[i].save && (priv->rev >= registers[i].rev)) - priv->saved_register[n++] = tilcdc_read(ddev, registers[i].reg); - -- /* Select sleep pin state */ -- pinctrl_pm_select_sleep_state(dev); -+ priv->ctx_valid = true; - - return 0; - } -@@ -602,10 +609,14 @@ static int tilcdc_pm_resume(struct device *dev) - /* Select default pin state */ - pinctrl_pm_select_default_state(dev); - -- /* Restore register state: */ -- for (i = 0; i < ARRAY_SIZE(registers); i++) -- if (registers[i].save && (priv->rev >= registers[i].rev)) -- tilcdc_write(ddev, registers[i].reg, priv->saved_register[n++]); -+ if (priv->ctx_valid == true) { -+ /* Restore register state: */ -+ for (i = 0; i < ARRAY_SIZE(registers); i++) -+ if (registers[i].save && -+ (priv->rev >= registers[i].rev)) -+ tilcdc_write(ddev, registers[i].reg, -+ priv->saved_register[n++]); -+ } - - drm_kms_helper_poll_enable(ddev); - -diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.h b/drivers/gpu/drm/tilcdc/tilcdc_drv.h -index 62a1d68..55d17b3 100644 ---- a/drivers/gpu/drm/tilcdc/tilcdc_drv.h -+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.h -@@ -67,6 +67,7 @@ struct tilcdc_drm_private { - - /* register contents saved across suspend/resume: */ - u32 saved_register[12]; -+ bool ctx_valid; - - #ifdef CONFIG_CPU_FREQ - struct notifier_block freq_transition; --- -2.7.0 - diff --git a/patches/beaglebone/tilcdc/0005-drm-tilcdc-make-frame_done-interrupt-active-at-all-t.patch b/patches/beaglebone/tilcdc/0005-drm-tilcdc-make-frame_done-interrupt-active-at-all-t.patch deleted file mode 100644 index 9e9951d9b6d87a04cda4d288bd212ed30b14294c..0000000000000000000000000000000000000000 --- a/patches/beaglebone/tilcdc/0005-drm-tilcdc-make-frame_done-interrupt-active-at-all-t.patch +++ /dev/null @@ -1,46 +0,0 @@ -From b62222fcaab994177f121d58acdab269f0f54897 Mon Sep 17 00:00:00 2001 -From: Darren Etheridge <detheridge@ti.com> -Date: Thu, 25 Sep 2014 00:59:31 +0000 -Subject: [PATCH] drm/tilcdc: make frame_done interrupt active at all times - -The frame_done interrupt was only being enabled when the vsync -interrupts were being enabled by DRM. However the frame_done is -used to determine if the LCD controller has successfully completed -the raster_enable, raster_disable commands and the vsync interrupts -are not always enabled during these operations. - -Signed-off-by: Darren Etheridge <detheridge@ti.com> -Tested-by: Dave Gerlach <d-gerlach@ti.com> -Signed-off-by: Jyri Sarha <jsarha@ti.com> -Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ti.com> ---- - drivers/gpu/drm/tilcdc/tilcdc_drv.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c -index 67ed9f7..7c39362 100644 ---- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c -+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c -@@ -369,7 +369,9 @@ static int tilcdc_irq_postinstall(struct drm_device *dev) - if (priv->rev == 1) - tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_V1_UNDERFLOW_INT_ENA); - else -- tilcdc_set(dev, LCDC_INT_ENABLE_SET_REG, LCDC_V2_UNDERFLOW_INT_ENA); -+ tilcdc_set(dev, LCDC_INT_ENABLE_SET_REG, -+ LCDC_V2_UNDERFLOW_INT_ENA | -+ LCDC_FRAME_DONE); - - return 0; - } -@@ -403,7 +405,7 @@ static void enable_vblank(struct drm_device *dev, bool enable) - } else { - reg = LCDC_INT_ENABLE_SET_REG; - mask = LCDC_V2_END_OF_FRAME0_INT_ENA | -- LCDC_V2_END_OF_FRAME1_INT_ENA | LCDC_FRAME_DONE; -+ LCDC_V2_END_OF_FRAME1_INT_ENA; - } - - if (enable) --- -2.7.0 - diff --git a/patches/beaglebone/tilcdc/0006-drm-tilcdc-disable-the-lcd-controller-dma-engine-whe.patch b/patches/beaglebone/tilcdc/0006-drm-tilcdc-disable-the-lcd-controller-dma-engine-whe.patch deleted file mode 100644 index 79d3e4ef17eba5e9e8371ec6d840e5b0c31d044f..0000000000000000000000000000000000000000 --- a/patches/beaglebone/tilcdc/0006-drm-tilcdc-disable-the-lcd-controller-dma-engine-whe.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 614b3cfeb8d22e2b0f49bcfeaf5b52900242a944 Mon Sep 17 00:00:00 2001 -From: Darren Etheridge <detheridge@ti.com> -Date: Thu, 25 Sep 2014 00:59:32 +0000 -Subject: [PATCH] drm/tilcdc: disable the lcd controller/dma engine when - suspend invoked - -The LCD controller must be deactivated and all DMA transactions stopped -when the suspend power state is entered otherwise the PRCM causes the L3 -bus to get stuck in transition state. - -This commit forces the lcdc to be shut down and waits for all pending DMA -transactions to complete as part of the suspend handler for this driver. - -Signed-off-by: Darren Etheridge <detheridge@ti.com> -Tested-by: Dave Gerlach <d-gerlach@ti.com> -Signed-off-by: Jyri Sarha <jsarha@ti.com> -Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ti.com> ---- - drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 3 +-- - drivers/gpu/drm/tilcdc/tilcdc_drv.c | 3 +++ - drivers/gpu/drm/tilcdc/tilcdc_drv.h | 1 + - 3 files changed, 5 insertions(+), 2 deletions(-) - -diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -index 6485e1c..465fd04 100644 ---- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -@@ -138,7 +138,6 @@ static void stop(struct drm_crtc *crtc) - tilcdc_clear(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE); - } - --static void tilcdc_crtc_dpms(struct drm_crtc *crtc, int mode); - static void tilcdc_crtc_destroy(struct drm_crtc *crtc) - { - struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); -@@ -192,7 +191,7 @@ static int tilcdc_crtc_page_flip(struct drm_crtc *crtc, - return 0; - } - --static void tilcdc_crtc_dpms(struct drm_crtc *crtc, int mode) -+void tilcdc_crtc_dpms(struct drm_crtc *crtc, int mode) - { - struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); - struct drm_device *dev = crtc->dev; -diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c -index 7c39362..30d8ac6 100644 ---- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c -+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c -@@ -592,6 +592,9 @@ static int tilcdc_pm_suspend(struct device *dev) - return 0; - } - -+ /* Disable the LCDC controller, to avoid locking up the PRCM */ -+ tilcdc_crtc_dpms(priv->crtc, DRM_MODE_DPMS_OFF); -+ - /* Save register state: */ - for (i = 0; i < ARRAY_SIZE(registers); i++) - if (registers[i].save && (priv->rev >= registers[i].rev)) -diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.h b/drivers/gpu/drm/tilcdc/tilcdc_drv.h -index 55d17b3..95324f1 100644 ---- a/drivers/gpu/drm/tilcdc/tilcdc_drv.h -+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.h -@@ -171,5 +171,6 @@ void tilcdc_crtc_set_simulate_vesa_sync(struct drm_crtc *crtc, - bool simulate_vesa_sync); - int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode); - int tilcdc_crtc_max_width(struct drm_crtc *crtc); -+void tilcdc_crtc_dpms(struct drm_crtc *crtc, int mode); - - #endif /* __TILCDC_DRV_H__ */ --- -2.7.0 - diff --git a/patches/beaglebone/tilcdc/0007-drm-tilcdc-Implement-dma-buf-support-for-tilcdc.patch b/patches/beaglebone/tilcdc/0007-drm-tilcdc-Implement-dma-buf-support-for-tilcdc.patch deleted file mode 100644 index bd6163c5f68ccf1778e094f009deb347aa0a6f79..0000000000000000000000000000000000000000 --- a/patches/beaglebone/tilcdc/0007-drm-tilcdc-Implement-dma-buf-support-for-tilcdc.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 9c15390506d6888978fa98094f7578142d2e2f01 Mon Sep 17 00:00:00 2001 -From: Jyri Sarha <jsarha@ti.com> -Date: Tue, 23 Jun 2015 14:31:17 +0300 -Subject: [PATCH] drm/tilcdc: Implement dma-buf support for tilcdc - -There is nothing special about tilcdc HW when the video memory is -concerned. Just using the standard drm helpers for implementation is -enough. - -Signed-off-by: Jyri Sarha <jsarha@ti.com> -Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ti.com> ---- - drivers/gpu/drm/tilcdc/tilcdc_drv.c | 13 ++++++++++++- - 1 file changed, 12 insertions(+), 1 deletion(-) - -diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c -index 30d8ac6..c204359 100644 ---- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c -+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c -@@ -542,7 +542,8 @@ static const struct file_operations fops = { - }; - - static struct drm_driver tilcdc_driver = { -- .driver_features = DRIVER_HAVE_IRQ | DRIVER_GEM | DRIVER_MODESET, -+ .driver_features = (DRIVER_HAVE_IRQ | DRIVER_GEM | DRIVER_MODESET | -+ DRIVER_PRIME), - .load = tilcdc_load, - .unload = tilcdc_unload, - .lastclose = tilcdc_lastclose, -@@ -559,6 +560,16 @@ static struct drm_driver tilcdc_driver = { - .dumb_create = drm_gem_cma_dumb_create, - .dumb_map_offset = drm_gem_cma_dumb_map_offset, - .dumb_destroy = drm_gem_dumb_destroy, -+ -+ .prime_handle_to_fd = drm_gem_prime_handle_to_fd, -+ .prime_fd_to_handle = drm_gem_prime_fd_to_handle, -+ .gem_prime_import = drm_gem_prime_import, -+ .gem_prime_export = drm_gem_prime_export, -+ .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table, -+ .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table, -+ .gem_prime_vmap = drm_gem_cma_prime_vmap, -+ .gem_prime_vunmap = drm_gem_cma_prime_vunmap, -+ .gem_prime_mmap = drm_gem_cma_prime_mmap, - #ifdef CONFIG_DEBUG_FS - .debugfs_init = tilcdc_debugfs_init, - .debugfs_cleanup = tilcdc_debugfs_cleanup, --- -2.7.0 - diff --git a/patches/beaglebone/tilcdc/0008-drm-tilcdc-fix-build-error-when-CONFIG_CPU_FREQ.patch b/patches/beaglebone/tilcdc/0008-drm-tilcdc-fix-build-error-when-CONFIG_CPU_FREQ.patch deleted file mode 100644 index f8e60d5dbfa397abe1b5a93aad96d8c761e6ad99..0000000000000000000000000000000000000000 --- a/patches/beaglebone/tilcdc/0008-drm-tilcdc-fix-build-error-when-CONFIG_CPU_FREQ.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 7974dff4957f953f0f6fd71c30e02a7c25aea7f0 Mon Sep 17 00:00:00 2001 -From: Grygorii Strashko <Grygorii.Strashko@linaro.org> -Date: Wed, 25 Feb 2015 18:19:43 +0200 -Subject: [PATCH] drm/tilcdc: fix build error when !CONFIG_CPU_FREQ - -Fix build error when !CONFIG_CPU_FREQ -drivers/gpu/drm/tilcdc/tilcdc_drv.c: In function 'tilcdc_load': -drivers/gpu/drm/tilcdc/tilcdc_drv.c:327:1: error: label 'fail_put_clk' defined but not used [-Werror=unused-label] - fail_put_clk: - ^ - -Signed-off-by: Grygorii Strashko <Grygorii.Strashko@linaro.org> -Signed-off-by: Jyri Sarha <jsarha@ti.com> -Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ti.com> ---- - drivers/gpu/drm/tilcdc/tilcdc_drv.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c -index c204359..977c843 100644 ---- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c -+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c -@@ -325,9 +325,9 @@ fail_cpufreq_unregister: - #ifdef CONFIG_CPU_FREQ - cpufreq_unregister_notifier(&priv->freq_transition, - CPUFREQ_TRANSITION_NOTIFIER); --#endif - - fail_put_clk: -+#endif - clk_put(priv->clk); - - fail_iounmap: --- -2.7.0 - diff --git a/patches/beaglebone/tilcdc/0009-drm-tilcdc-Allocate-register-storage-based-on-the-ac.patch b/patches/beaglebone/tilcdc/0009-drm-tilcdc-Allocate-register-storage-based-on-the-ac.patch deleted file mode 100644 index ab43a05e1084eb872a63e4aa3e7ccbc0a8b48d95..0000000000000000000000000000000000000000 --- a/patches/beaglebone/tilcdc/0009-drm-tilcdc-Allocate-register-storage-based-on-the-ac.patch +++ /dev/null @@ -1,92 +0,0 @@ -From 29ddd6e171abae990a881b9e221359f13c546369 Mon Sep 17 00:00:00 2001 -From: Jyri Sarha <jsarha@ti.com> -Date: Thu, 2 Jul 2015 16:26:12 +0300 -Subject: [PATCH] drm/tilcdc: Allocate register storage based on the actual - number registers - -Allocate suspend/resume register storage based on the actual number -registers the driver is aware of. The static allocation for register -storage had fallen behind badly. - -Reported-by: Michael Bode <michael@bumbleB.de> -Signed-off-by: Jyri Sarha <jsarha@ti.com> -Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ti.com> ---- - drivers/gpu/drm/tilcdc/tilcdc_drv.c | 21 ++++++++++++++++++++- - drivers/gpu/drm/tilcdc/tilcdc_drv.h | 2 +- - 2 files changed, 21 insertions(+), 2 deletions(-) - -diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c -index 977c843..47096b1 100644 ---- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c -+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c -@@ -141,11 +141,14 @@ static int tilcdc_unload(struct drm_device *dev) - - pm_runtime_disable(dev->dev); - -+ kfree(priv->saved_register); - kfree(priv); - - return 0; - } - -+static size_t tilcdc_num_regs(void); -+ - static int tilcdc_load(struct drm_device *dev, unsigned long flags) - { - struct platform_device *pdev = dev->platformdev; -@@ -157,7 +160,12 @@ static int tilcdc_load(struct drm_device *dev, unsigned long flags) - int ret; - - priv = kzalloc(sizeof(*priv), GFP_KERNEL); -- if (!priv) { -+ if (priv) -+ priv->saved_register = kcalloc(tilcdc_num_regs(), -+ sizeof(*priv->saved_register), -+ GFP_KERNEL); -+ if (!priv || !priv->saved_register) { -+ kfree(priv); - dev_err(dev->dev, "failed to allocate private data\n"); - return -ENOMEM; - } -@@ -339,6 +347,7 @@ fail_free_wq: - - fail_free_priv: - dev->dev_private = NULL; -+ kfree(priv->saved_register); - kfree(priv); - return ret; - } -@@ -456,6 +465,16 @@ static const struct { - REG(2, true, LCDC_INT_ENABLE_SET_REG), - #undef REG - }; -+ -+static size_t tilcdc_num_regs(void) -+{ -+ return ARRAY_SIZE(registers); -+} -+#else -+static size_t tilcdc_num_regs(void) -+{ -+ return 0; -+} - #endif - - #ifdef CONFIG_DEBUG_FS -diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.h b/drivers/gpu/drm/tilcdc/tilcdc_drv.h -index 95324f1..c1de18b 100644 ---- a/drivers/gpu/drm/tilcdc/tilcdc_drv.h -+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.h -@@ -66,7 +66,7 @@ struct tilcdc_drm_private { - uint32_t max_width; - - /* register contents saved across suspend/resume: */ -- u32 saved_register[12]; -+ u32 *saved_register; - bool ctx_valid; - - #ifdef CONFIG_CPU_FREQ --- -2.7.0 - diff --git a/patches/beaglebone/tilcdc/0010-drm-tilcdc-cleanup-runtime-PM-handling.patch b/patches/beaglebone/tilcdc/0010-drm-tilcdc-cleanup-runtime-PM-handling.patch deleted file mode 100644 index a64d6f0eaa3d3626ded4be38f28318843e723a10..0000000000000000000000000000000000000000 --- a/patches/beaglebone/tilcdc/0010-drm-tilcdc-cleanup-runtime-PM-handling.patch +++ /dev/null @@ -1,111 +0,0 @@ -From 65734a262350a746100dcfd85a81f7dc1b69dd10 Mon Sep 17 00:00:00 2001 -From: Tomi Valkeinen <tomi.valkeinen@ti.com> -Date: Mon, 19 Oct 2015 12:30:03 +0300 -Subject: [PATCH] drm/tilcdc: cleanup runtime PM handling - -Cleanup runtime PM handling. Before the patch the usage of pm_runtime -calls was inconsistent and hard to follow. After the update the -pm_runtime calls are removed from set_scanout() and called around -major operations that access the HW. After the patch the DPMS code does -not have pm_runtime_forbid/allow calls any more and -pm_runtime_irq_safe() is not set anymore. - -Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> -[Added description to the patch] -Signed-off-by: Jyri Sarha <jsarha@ti.com> ---- - drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 19 +++++++++++-------- - drivers/gpu/drm/tilcdc/tilcdc_drv.c | 1 - - 2 files changed, 11 insertions(+), 9 deletions(-) - -diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -index 465fd04..08b1e03 100644 ---- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -@@ -71,7 +71,6 @@ static void set_scanout(struct drm_crtc *crtc, int n) - struct drm_device *dev = crtc->dev; - struct tilcdc_drm_private *priv = dev->dev_private; - -- pm_runtime_get_sync(dev->dev); - tilcdc_write(dev, base_reg[n], tilcdc_crtc->start); - tilcdc_write(dev, ceil_reg[n], tilcdc_crtc->end); - if (tilcdc_crtc->scanout[n]) { -@@ -81,7 +80,6 @@ static void set_scanout(struct drm_crtc *crtc, int n) - tilcdc_crtc->scanout[n] = crtc->primary->fb; - drm_framebuffer_reference(tilcdc_crtc->scanout[n]); - tilcdc_crtc->dirty &= ~stat[n]; -- pm_runtime_put_sync(dev->dev); - } - - static void update_scanout(struct drm_crtc *crtc) -@@ -186,8 +184,13 @@ static int tilcdc_crtc_page_flip(struct drm_crtc *crtc, - - crtc->primary->fb = fb; - tilcdc_crtc->event = event; -+ -+ pm_runtime_get_sync(dev->dev); -+ - update_scanout(crtc); - -+ pm_runtime_put_sync(dev->dev); -+ - return 0; - } - -@@ -206,10 +209,8 @@ void tilcdc_crtc_dpms(struct drm_crtc *crtc, int mode) - - tilcdc_crtc->dpms = mode; - -- pm_runtime_get_sync(dev->dev); -- - if (mode == DRM_MODE_DPMS_ON) { -- pm_runtime_forbid(dev->dev); -+ pm_runtime_get_sync(dev->dev); - start(crtc); - } else { - tilcdc_crtc->frame_done = false; -@@ -227,10 +228,9 @@ void tilcdc_crtc_dpms(struct drm_crtc *crtc, int mode) - if (ret == 0) - dev_err(dev->dev, "timeout waiting for framedone\n"); - } -- pm_runtime_allow(dev->dev); -- } - -- pm_runtime_put_sync(dev->dev); -+ pm_runtime_put_sync(dev->dev); -+ } - } - - static bool tilcdc_crtc_mode_fixup(struct drm_crtc *crtc, -@@ -455,13 +455,16 @@ static int tilcdc_crtc_mode_set(struct drm_crtc *crtc, - static int tilcdc_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, - struct drm_framebuffer *old_fb) - { -+ struct drm_device *dev = crtc->dev; - int r; - - r = tilcdc_verify_fb(crtc, crtc->primary->fb); - if (r) - return r; - -+ pm_runtime_get_sync(dev->dev); - update_scanout(crtc); -+ pm_runtime_put_sync(dev->dev); - return 0; - } - -diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c -index 47096b1..47f0e02 100644 ---- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c -+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c -@@ -230,7 +230,6 @@ static int tilcdc_load(struct drm_device *dev, unsigned long flags) - DBG("Maximum Pixel Clock Value %dKHz", priv->max_pixelclock); - - pm_runtime_enable(dev->dev); -- pm_runtime_irq_safe(dev->dev); - - /* Determine LCD IP Version */ - pm_runtime_get_sync(dev->dev); --- -2.7.0 - diff --git a/patches/beaglebone/tilcdc/0011-drm-tilcdc-disable-crtc-on-unload.patch b/patches/beaglebone/tilcdc/0011-drm-tilcdc-disable-crtc-on-unload.patch deleted file mode 100644 index 968037176f2c33fa92b608410d5e72f5adb28826..0000000000000000000000000000000000000000 --- a/patches/beaglebone/tilcdc/0011-drm-tilcdc-disable-crtc-on-unload.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 1aea1e79dbfd65a99da11868829c3e147b85cc32 Mon Sep 17 00:00:00 2001 -From: Tomi Valkeinen <tomi.valkeinen@ti.com> -Date: Mon, 19 Oct 2015 14:15:26 +0300 -Subject: [PATCH] drm/tilcdc: disable crtc on unload - -Disable crtc on unload. Call tilcdc_crtc_dpms() with DRM_MODE_DPMS_OFF -in the beginning of unload function. - -Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> -[Added description to the patch] -Signed-off-by: Jyri Sarha <jsarha@ti.com> ---- - drivers/gpu/drm/tilcdc/tilcdc_drv.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c -index 47f0e02..e1f6979 100644 ---- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c -+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c -@@ -112,6 +112,8 @@ static int tilcdc_unload(struct drm_device *dev) - { - struct tilcdc_drm_private *priv = dev->dev_private; - -+ tilcdc_crtc_dpms(priv->crtc, DRM_MODE_DPMS_OFF); -+ - tilcdc_remove_external_encoders(dev); - - drm_fbdev_cma_fini(priv->fbdev); --- -2.7.0 - diff --git a/patches/beaglebone/tilcdc/0012-drm-tilcdc-split-reset-to-a-separate-function.patch b/patches/beaglebone/tilcdc/0012-drm-tilcdc-split-reset-to-a-separate-function.patch deleted file mode 100644 index d32d9f01eb73561d18e55ec4726dfa38da90157d..0000000000000000000000000000000000000000 --- a/patches/beaglebone/tilcdc/0012-drm-tilcdc-split-reset-to-a-separate-function.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 2efec4f3064d084bac1b2c1e1513a7452e8e245d Mon Sep 17 00:00:00 2001 -From: Tomi Valkeinen <tomi.valkeinen@ti.com> -Date: Tue, 20 Oct 2015 09:37:27 +0300 -Subject: [PATCH] drm/tilcdc: split reset to a separate function - -Split reset to a separate function and use usleep_range(250, 1000) -instead of msleep(1) to to keep the reset bit on long enough. - -Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> -[Added description to the patch, changed mdelay(500) to usleep_range(250, 1000)] -Signed-off-by: Jyri Sarha <jsarha@ti.com> ---- - drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 21 ++++++++++++++------- - 1 file changed, 14 insertions(+), 7 deletions(-) - -diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -index 08b1e03..e62a950 100644 ---- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -@@ -112,17 +112,24 @@ static void update_scanout(struct drm_crtc *crtc) - } - } - --static void start(struct drm_crtc *crtc) -+static void reset(struct drm_crtc *crtc) - { - struct drm_device *dev = crtc->dev; - struct tilcdc_drm_private *priv = dev->dev_private; - -- if (priv->rev == 2) { -- tilcdc_set(dev, LCDC_CLK_RESET_REG, LCDC_CLK_MAIN_RESET); -- msleep(1); -- tilcdc_clear(dev, LCDC_CLK_RESET_REG, LCDC_CLK_MAIN_RESET); -- msleep(1); -- } -+ if (priv->rev != 2) -+ return; -+ -+ tilcdc_set(dev, LCDC_CLK_RESET_REG, LCDC_CLK_MAIN_RESET); -+ usleep_range(250, 1000); -+ tilcdc_clear(dev, LCDC_CLK_RESET_REG, LCDC_CLK_MAIN_RESET); -+} -+ -+static void start(struct drm_crtc *crtc) -+{ -+ struct drm_device *dev = crtc->dev; -+ -+ reset(crtc); - - tilcdc_set(dev, LCDC_DMA_CTRL_REG, LCDC_DUAL_FRAME_BUFFER_ENABLE); - tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_PALETTE_LOAD_MODE(DATA_ONLY)); --- -2.7.0 - diff --git a/patches/beaglebone/tilcdc/0013-drm-tilcdc-remove-broken-error-handling.patch b/patches/beaglebone/tilcdc/0013-drm-tilcdc-remove-broken-error-handling.patch deleted file mode 100644 index 69c1137ba227d988d418cf337484eb9397ce23cd..0000000000000000000000000000000000000000 --- a/patches/beaglebone/tilcdc/0013-drm-tilcdc-remove-broken-error-handling.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 31ec5a2c7eed3a3e182a592591f4fb04304668a1 Mon Sep 17 00:00:00 2001 -From: Tomi Valkeinen <tomi.valkeinen@ti.com> -Date: Tue, 20 Oct 2015 12:04:05 +0300 -Subject: [PATCH] drm/tilcdc: remove broken error handling - -Remove broken error handling. The condition for handling the -LCDC_SYNC_LOST and LCDC_FIFO_UNDERFLOW could never be satisfied as the -LCDC_SYNC_LOST interrupt is not enabled. Also the requirement to have -both LCDC_SYNC_LOST and LCDC_FIFO_UNDERFLOW fired at once before -handling the error looks weird. - -Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> -[Added description to the patch] -Signed-off-by: Jyri Sarha <jsarha@ti.com> ---- - drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 7 +------ - 1 file changed, 1 insertion(+), 6 deletions(-) - -diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -index e62a950..61aead2 100644 ---- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -@@ -658,12 +658,7 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc) - struct tilcdc_drm_private *priv = dev->dev_private; - uint32_t stat = tilcdc_read_irqstatus(dev); - -- if ((stat & LCDC_SYNC_LOST) && (stat & LCDC_FIFO_UNDERFLOW)) { -- stop(crtc); -- dev_err(dev->dev, "error: %08x\n", stat); -- tilcdc_clear_irqstatus(dev, stat); -- start(crtc); -- } else if (stat & LCDC_PL_LOAD_DONE) { -+ if (stat & LCDC_PL_LOAD_DONE) { - tilcdc_clear_irqstatus(dev, stat); - } else { - struct drm_pending_vblank_event *event; --- -2.7.0 - diff --git a/patches/beaglebone/tilcdc/0014-drm-tilcdc-cleanup-irq-handling.patch b/patches/beaglebone/tilcdc/0014-drm-tilcdc-cleanup-irq-handling.patch deleted file mode 100644 index dc5adb9c7ed73abef93513621e6dc7ef62593300..0000000000000000000000000000000000000000 --- a/patches/beaglebone/tilcdc/0014-drm-tilcdc-cleanup-irq-handling.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 317aae738b6402cd66fb9b52434b783f17ff5dd4 Mon Sep 17 00:00:00 2001 -From: Tomi Valkeinen <tomi.valkeinen@ti.com> -Date: Tue, 20 Oct 2015 12:08:03 +0300 -Subject: [PATCH] drm/tilcdc: cleanup irq handling - -Cleanup irq handling. Clear the irq status unconditionally and -restructure the status bit conditions. - -Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> -[Added description to the patch] -Signed-off-by: Jyri Sarha <jsarha@ti.com> ---- - drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 9 +++++---- - 1 file changed, 5 insertions(+), 4 deletions(-) - -diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -index 61aead2..a6ef737 100644 ---- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -@@ -656,11 +656,12 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc) - struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); - struct drm_device *dev = crtc->dev; - struct tilcdc_drm_private *priv = dev->dev_private; -- uint32_t stat = tilcdc_read_irqstatus(dev); -+ uint32_t stat; - -- if (stat & LCDC_PL_LOAD_DONE) { -- tilcdc_clear_irqstatus(dev, stat); -- } else { -+ stat = tilcdc_read_irqstatus(dev); -+ tilcdc_clear_irqstatus(dev, stat); -+ -+ if ((stat & LCDC_END_OF_FRAME0) || (stat & LCDC_END_OF_FRAME1)) { - struct drm_pending_vblank_event *event; - unsigned long flags; - uint32_t dirty = tilcdc_crtc->dirty & stat; --- -2.7.0 - diff --git a/patches/beaglebone/tilcdc/0015-drm-tilcdc-Get-rid-of-complex-ping-pong-mechanism.patch b/patches/beaglebone/tilcdc/0015-drm-tilcdc-Get-rid-of-complex-ping-pong-mechanism.patch deleted file mode 100644 index 427e4f9a674b28ad00daaacf81e7ea8c3ee90dff..0000000000000000000000000000000000000000 --- a/patches/beaglebone/tilcdc/0015-drm-tilcdc-Get-rid-of-complex-ping-pong-mechanism.patch +++ /dev/null @@ -1,310 +0,0 @@ -From 2b2080d7e9ae2463b15a003629d2ea7d733759a0 Mon Sep 17 00:00:00 2001 -From: Tomi Valkeinen <tomi.valkeinen@ti.com> -Date: Tue, 20 Oct 2015 09:37:27 +0300 -Subject: [PATCH] drm/tilcdc: Get rid of complex ping-pong mechanism - -Get rid of complex ping-pong mechanism and replace it with simpler -single buffer flipping code. - -The LCDC HW appears to be designed mainly static framebuffers in -mind. There are two modes of operation, either static single buffer, -or ping pong double buffering with two static buffers switching back -and forth. Luckily the framebuffer start address is fetched only in -the beginning of the frame and changing the address after that only -takes effect after the next vertical blank. The page flipping code can -simply write the address of the new framebuffer and the page is -flipped automatically after the next vertical blank. Using the ping -pong double buffering makes the flipping code way more complex and it -does not provide any benefit, so it is better to switch to single -buffer operation. - -There is still one problem in updating the framebuffer dma address on -the fly. There are two registers defining the framebuffer dma area and -things may break if the dma address is fetched in while the registers -are are being updated. - -Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> -[Added description to the patch] -Signed-off-by: Jyri Sarha <jsarha@ti.com> ---- - drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 121 +++++++++++++++-------------------- - drivers/gpu/drm/tilcdc/tilcdc_drv.c | 27 +------- - 2 files changed, 53 insertions(+), 95 deletions(-) - -diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -index a6ef737..3257228 100644 ---- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -@@ -25,15 +25,12 @@ struct tilcdc_crtc { - struct drm_crtc base; - - const struct tilcdc_panel_info *info; -- uint32_t dirty; -- dma_addr_t start, end; - struct drm_pending_vblank_event *event; - int dpms; - wait_queue_head_t frame_done_wq; - bool frame_done; - -- /* fb currently set to scanout 0/1: */ -- struct drm_framebuffer *scanout[2]; -+ struct drm_framebuffer *curr_fb; - - /* for deferred fb unref's: */ - struct drm_flip_work unref_work; -@@ -54,62 +51,31 @@ static void unref_worker(struct drm_flip_work *work, void *val) - mutex_unlock(&dev->mode_config.mutex); - } - --static void set_scanout(struct drm_crtc *crtc, int n) --{ -- static const uint32_t base_reg[] = { -- LCDC_DMA_FB_BASE_ADDR_0_REG, -- LCDC_DMA_FB_BASE_ADDR_1_REG, -- }; -- static const uint32_t ceil_reg[] = { -- LCDC_DMA_FB_CEILING_ADDR_0_REG, -- LCDC_DMA_FB_CEILING_ADDR_1_REG, -- }; -- static const uint32_t stat[] = { -- LCDC_END_OF_FRAME0, LCDC_END_OF_FRAME1, -- }; -- struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); -- struct drm_device *dev = crtc->dev; -- struct tilcdc_drm_private *priv = dev->dev_private; -- -- tilcdc_write(dev, base_reg[n], tilcdc_crtc->start); -- tilcdc_write(dev, ceil_reg[n], tilcdc_crtc->end); -- if (tilcdc_crtc->scanout[n]) { -- drm_flip_work_queue(&tilcdc_crtc->unref_work, tilcdc_crtc->scanout[n]); -- drm_flip_work_commit(&tilcdc_crtc->unref_work, priv->wq); -- } -- tilcdc_crtc->scanout[n] = crtc->primary->fb; -- drm_framebuffer_reference(tilcdc_crtc->scanout[n]); -- tilcdc_crtc->dirty &= ~stat[n]; --} -- --static void update_scanout(struct drm_crtc *crtc) -+static void set_scanout(struct drm_crtc *crtc, struct drm_framebuffer *fb) - { - struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); - struct drm_device *dev = crtc->dev; -- struct drm_framebuffer *fb = crtc->primary->fb; - struct drm_gem_cma_object *gem; - unsigned int depth, bpp; -+ dma_addr_t start, end; - - drm_fb_get_bpp_depth(fb->pixel_format, &depth, &bpp); - gem = drm_fb_cma_get_gem_obj(fb, 0); - -- tilcdc_crtc->start = gem->paddr + fb->offsets[0] + -- (crtc->y * fb->pitches[0]) + (crtc->x * bpp/8); -+ start = gem->paddr + fb->offsets[0] + -+ crtc->y * fb->pitches[0] + -+ crtc->x * bpp / 8; - -- tilcdc_crtc->end = tilcdc_crtc->start + -- (crtc->mode.vdisplay * fb->pitches[0]); -+ end = start + (crtc->mode.vdisplay * fb->pitches[0]); - -- if (tilcdc_crtc->dpms == DRM_MODE_DPMS_ON) { -- /* already enabled, so just mark the frames that need -- * updating and they will be updated on vblank: -- */ -- tilcdc_crtc->dirty |= LCDC_END_OF_FRAME0 | LCDC_END_OF_FRAME1; -- drm_vblank_get(dev, 0); -- } else { -- /* not enabled yet, so update registers immediately: */ -- set_scanout(crtc, 0); -- set_scanout(crtc, 1); -- } -+ tilcdc_write(dev, LCDC_DMA_FB_BASE_ADDR_0_REG, start); -+ tilcdc_write(dev, LCDC_DMA_FB_CEILING_ADDR_0_REG, end); -+ -+ if (tilcdc_crtc->curr_fb) -+ drm_flip_work_queue(&tilcdc_crtc->unref_work, -+ tilcdc_crtc->curr_fb); -+ -+ tilcdc_crtc->curr_fb = fb; - } - - static void reset(struct drm_crtc *crtc) -@@ -131,7 +97,7 @@ static void start(struct drm_crtc *crtc) - - reset(crtc); - -- tilcdc_set(dev, LCDC_DMA_CTRL_REG, LCDC_DUAL_FRAME_BUFFER_ENABLE); -+ tilcdc_clear(dev, LCDC_DMA_CTRL_REG, LCDC_DUAL_FRAME_BUFFER_ENABLE); - tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_PALETTE_LOAD_MODE(DATA_ONLY)); - tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE); - } -@@ -179,6 +145,7 @@ static int tilcdc_crtc_page_flip(struct drm_crtc *crtc, - struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); - struct drm_device *dev = crtc->dev; - int r; -+ unsigned long flags; - - r = tilcdc_verify_fb(crtc, fb); - if (r) -@@ -189,12 +156,18 @@ static int tilcdc_crtc_page_flip(struct drm_crtc *crtc, - return -EBUSY; - } - -+ drm_framebuffer_reference(fb); -+ - crtc->primary->fb = fb; -- tilcdc_crtc->event = event; - - pm_runtime_get_sync(dev->dev); - -- update_scanout(crtc); -+ -+ set_scanout(crtc, fb); -+ -+ spin_lock_irqsave(&dev->event_lock, flags); -+ tilcdc_crtc->event = event; -+ spin_unlock_irqrestore(&dev->event_lock, flags); - - pm_runtime_put_sync(dev->dev); - -@@ -237,6 +210,14 @@ void tilcdc_crtc_dpms(struct drm_crtc *crtc, int mode) - } - - pm_runtime_put_sync(dev->dev); -+ -+ if (tilcdc_crtc->curr_fb) { -+ drm_flip_work_queue(&tilcdc_crtc->unref_work, -+ tilcdc_crtc->curr_fb); -+ tilcdc_crtc->curr_fb = NULL; -+ } -+ -+ drm_flip_work_commit(&tilcdc_crtc->unref_work, priv->wq); - } - } - -@@ -450,8 +431,10 @@ static int tilcdc_crtc_mode_set(struct drm_crtc *crtc, - else - tilcdc_clear(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ORDER); - -+ drm_framebuffer_reference(crtc->primary->fb); -+ -+ set_scanout(crtc, crtc->primary->fb); - -- update_scanout(crtc); - tilcdc_crtc_update_clk(crtc); - - pm_runtime_put_sync(dev->dev); -@@ -469,9 +452,14 @@ static int tilcdc_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, - if (r) - return r; - -+ drm_framebuffer_reference(crtc->primary->fb); -+ - pm_runtime_get_sync(dev->dev); -- update_scanout(crtc); -+ -+ set_scanout(crtc, crtc->primary->fb); -+ - pm_runtime_put_sync(dev->dev); -+ - return 0; - } - -@@ -661,30 +649,21 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc) - stat = tilcdc_read_irqstatus(dev); - tilcdc_clear_irqstatus(dev, stat); - -- if ((stat & LCDC_END_OF_FRAME0) || (stat & LCDC_END_OF_FRAME1)) { -- struct drm_pending_vblank_event *event; -+ if (stat & LCDC_END_OF_FRAME0) { - unsigned long flags; -- uint32_t dirty = tilcdc_crtc->dirty & stat; -- -- tilcdc_clear_irqstatus(dev, stat); - -- if (dirty & LCDC_END_OF_FRAME0) -- set_scanout(crtc, 0); -- -- if (dirty & LCDC_END_OF_FRAME1) -- set_scanout(crtc, 1); -+ drm_flip_work_commit(&tilcdc_crtc->unref_work, priv->wq); - - drm_handle_vblank(dev, 0); - - spin_lock_irqsave(&dev->event_lock, flags); -- event = tilcdc_crtc->event; -- tilcdc_crtc->event = NULL; -- if (event) -- drm_send_vblank_event(dev, 0, event); -- spin_unlock_irqrestore(&dev->event_lock, flags); - -- if (dirty && !tilcdc_crtc->dirty) -- drm_vblank_put(dev, 0); -+ if (tilcdc_crtc->event) { -+ drm_send_vblank_event(dev, 0, tilcdc_crtc->event); -+ tilcdc_crtc->event = NULL; -+ } -+ -+ spin_unlock_irqrestore(&dev->event_lock, flags); - } - - if (priv->rev == 2) { -diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c -index e1f6979..c5d9e3a 100644 ---- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c -+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c -@@ -381,6 +381,7 @@ static int tilcdc_irq_postinstall(struct drm_device *dev) - else - tilcdc_set(dev, LCDC_INT_ENABLE_SET_REG, - LCDC_V2_UNDERFLOW_INT_ENA | -+ LCDC_V2_END_OF_FRAME0_INT_ENA | - LCDC_FRAME_DONE); - - return 0; -@@ -398,41 +399,19 @@ static void tilcdc_irq_uninstall(struct drm_device *dev) - } else { - tilcdc_clear(dev, LCDC_INT_ENABLE_SET_REG, - LCDC_V2_UNDERFLOW_INT_ENA | LCDC_V2_PL_INT_ENA | -- LCDC_V2_END_OF_FRAME0_INT_ENA | LCDC_V2_END_OF_FRAME1_INT_ENA | -+ LCDC_V2_END_OF_FRAME0_INT_ENA | - LCDC_FRAME_DONE); - } -- --} -- --static void enable_vblank(struct drm_device *dev, bool enable) --{ -- struct tilcdc_drm_private *priv = dev->dev_private; -- u32 reg, mask; -- -- if (priv->rev == 1) { -- reg = LCDC_DMA_CTRL_REG; -- mask = LCDC_V1_END_OF_FRAME_INT_ENA; -- } else { -- reg = LCDC_INT_ENABLE_SET_REG; -- mask = LCDC_V2_END_OF_FRAME0_INT_ENA | -- LCDC_V2_END_OF_FRAME1_INT_ENA; -- } -- -- if (enable) -- tilcdc_set(dev, reg, mask); -- else -- tilcdc_clear(dev, reg, mask); - } - - static int tilcdc_enable_vblank(struct drm_device *dev, unsigned int pipe) - { -- enable_vblank(dev, true); - return 0; - } - - static void tilcdc_disable_vblank(struct drm_device *dev, unsigned int pipe) - { -- enable_vblank(dev, false); -+ return; - } - - #if defined(CONFIG_DEBUG_FS) || defined(CONFIG_PM_SLEEP) --- -2.7.0 - diff --git a/patches/beaglebone/tilcdc/0016-drm-tilcdc-Do-not-update-the-next-frame-buffer-close.patch b/patches/beaglebone/tilcdc/0016-drm-tilcdc-Do-not-update-the-next-frame-buffer-close.patch deleted file mode 100644 index 8e3252840d339b7025bfc3f42ec9b6fc08ac0c72..0000000000000000000000000000000000000000 --- a/patches/beaglebone/tilcdc/0016-drm-tilcdc-Do-not-update-the-next-frame-buffer-close.patch +++ /dev/null @@ -1,147 +0,0 @@ -From 2b3a8cd71c2b830164df5de07e4ddebe0faa58f5 Mon Sep 17 00:00:00 2001 -From: Tomi Valkeinen <tomi.valkeinen@ti.com> -Date: Tue, 3 Nov 2015 12:00:51 +0200 -Subject: [PATCH] drm/tilcdc: Do not update the next frame buffer close to - vertical blank - -Do not update the next frame buffer close to vertical blank. This is -to avoid situation when the frame changes between writing of -LCDC_DMA_FB_BASE_ADDR_0_REG and LCDC_DMA_FB_CEILING_ADDR_0_REG. - -Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> -[Added description to the patch] -Signed-off-by: Jyri Sarha <jsarha@ti.com> ---- - drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 61 +++++++++++++++++++++++++++++++----- - 1 file changed, 53 insertions(+), 8 deletions(-) - -diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -index 3257228..b1df046 100644 ---- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -@@ -21,6 +21,8 @@ - #include "tilcdc_drv.h" - #include "tilcdc_regs.h" - -+#define TILCDC_VBLANK_SAFETY_THRESHOLD_US 1000 -+ - struct tilcdc_crtc { - struct drm_crtc base; - -@@ -29,8 +31,12 @@ struct tilcdc_crtc { - int dpms; - wait_queue_head_t frame_done_wq; - bool frame_done; -+ spinlock_t irq_lock; -+ -+ ktime_t last_vblank; - - struct drm_framebuffer *curr_fb; -+ struct drm_framebuffer *next_fb; - - /* for deferred fb unref's: */ - struct drm_flip_work unref_work; -@@ -146,6 +152,8 @@ static int tilcdc_crtc_page_flip(struct drm_crtc *crtc, - struct drm_device *dev = crtc->dev; - int r; - unsigned long flags; -+ s64 tdiff; -+ ktime_t next_vblank; - - r = tilcdc_verify_fb(crtc, fb); - if (r) -@@ -162,12 +170,21 @@ static int tilcdc_crtc_page_flip(struct drm_crtc *crtc, - - pm_runtime_get_sync(dev->dev); - -+ spin_lock_irqsave(&tilcdc_crtc->irq_lock, flags); -+ -+ next_vblank = ktime_add_us(tilcdc_crtc->last_vblank, -+ 1000000 / crtc->hwmode.vrefresh); - -- set_scanout(crtc, fb); -+ tdiff = ktime_to_us(ktime_sub(next_vblank, ktime_get())); -+ -+ if (tdiff >= TILCDC_VBLANK_SAFETY_THRESHOLD_US) -+ set_scanout(crtc, fb); -+ else -+ tilcdc_crtc->next_fb = fb; - -- spin_lock_irqsave(&dev->event_lock, flags); - tilcdc_crtc->event = event; -- spin_unlock_irqrestore(&dev->event_lock, flags); -+ -+ spin_unlock_irqrestore(&tilcdc_crtc->irq_lock, flags); - - pm_runtime_put_sync(dev->dev); - -@@ -211,6 +228,12 @@ void tilcdc_crtc_dpms(struct drm_crtc *crtc, int mode) - - pm_runtime_put_sync(dev->dev); - -+ if (tilcdc_crtc->next_fb) { -+ drm_flip_work_queue(&tilcdc_crtc->unref_work, -+ tilcdc_crtc->next_fb); -+ tilcdc_crtc->next_fb = NULL; -+ } -+ - if (tilcdc_crtc->curr_fb) { - drm_flip_work_queue(&tilcdc_crtc->unref_work, - tilcdc_crtc->curr_fb); -@@ -651,19 +674,39 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc) - - if (stat & LCDC_END_OF_FRAME0) { - unsigned long flags; -+ bool skip_event = false; -+ ktime_t now; -+ -+ now = ktime_get(); - - drm_flip_work_commit(&tilcdc_crtc->unref_work, priv->wq); - -+ spin_lock_irqsave(&tilcdc_crtc->irq_lock, flags); -+ -+ tilcdc_crtc->last_vblank = now; -+ -+ if (tilcdc_crtc->next_fb) { -+ set_scanout(crtc, tilcdc_crtc->next_fb); -+ tilcdc_crtc->next_fb = NULL; -+ skip_event = true; -+ } -+ -+ spin_unlock_irqrestore(&tilcdc_crtc->irq_lock, flags); -+ - drm_handle_vblank(dev, 0); - -- spin_lock_irqsave(&dev->event_lock, flags); -+ if (!skip_event) { -+ struct drm_pending_vblank_event *event; - -- if (tilcdc_crtc->event) { -- drm_send_vblank_event(dev, 0, tilcdc_crtc->event); -+ spin_lock_irqsave(&dev->event_lock, flags); -+ -+ event = tilcdc_crtc->event; - tilcdc_crtc->event = NULL; -- } -+ if (event) -+ drm_send_vblank_event(dev, 0, event); - -- spin_unlock_irqrestore(&dev->event_lock, flags); -+ spin_unlock_irqrestore(&dev->event_lock, flags); -+ } - } - - if (priv->rev == 2) { -@@ -697,6 +740,8 @@ struct drm_crtc *tilcdc_crtc_create(struct drm_device *dev) - drm_flip_work_init(&tilcdc_crtc->unref_work, - "unref", unref_worker); - -+ spin_lock_init(&tilcdc_crtc->irq_lock); -+ - ret = drm_crtc_init(dev, crtc, &tilcdc_crtc_funcs); - if (ret < 0) - goto fail; --- -2.7.0 - diff --git a/patches/beaglebone/tilcdc/0017-drm-tilcdc-Fix-interrupt-enable-disable-code-for-ver.patch b/patches/beaglebone/tilcdc/0017-drm-tilcdc-Fix-interrupt-enable-disable-code-for-ver.patch deleted file mode 100644 index a03b355fafe5169212fdc7100ba958f17774588d..0000000000000000000000000000000000000000 --- a/patches/beaglebone/tilcdc/0017-drm-tilcdc-Fix-interrupt-enable-disable-code-for-ver.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 947df7e3f019bba902a55485635060e5970fb9a2 Mon Sep 17 00:00:00 2001 -From: Jyri Sarha <jsarha@ti.com> -Date: Wed, 9 Dec 2015 12:16:11 +0200 -Subject: [PATCH] drm/tilcdc: Fix interrupt enable/disable code for version 2 - tilcdc - -Fix interrupt enable/disable code for version 2 tilcdc. In version 2 -tilcdc there is a separate register for disabling interrupts. Writing -0 to enable registers bits does not have any effect. The interrupt -clear register works the same way, writing 1 to specific bit disables -the interrupt and writing 0 does not have any effect. - -The "bug" that is fixed here does not really do any harm since the -interrupts are enabled only once in the power up and disabled before -power down. - -Signed-off-by: Jyri Sarha <jsarha@ti.com> -Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ti.com> ---- - drivers/gpu/drm/tilcdc/tilcdc_drv.c | 11 ++++++----- - 1 file changed, 6 insertions(+), 5 deletions(-) - -diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c -index c5d9e3a..964e192 100644 ---- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c -+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c -@@ -376,13 +376,14 @@ static int tilcdc_irq_postinstall(struct drm_device *dev) - struct tilcdc_drm_private *priv = dev->dev_private; - - /* enable FIFO underflow irq: */ -- if (priv->rev == 1) -+ if (priv->rev == 1) { - tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_V1_UNDERFLOW_INT_ENA); -- else -- tilcdc_set(dev, LCDC_INT_ENABLE_SET_REG, -+ } else { -+ tilcdc_write(dev, LCDC_INT_ENABLE_SET_REG, - LCDC_V2_UNDERFLOW_INT_ENA | - LCDC_V2_END_OF_FRAME0_INT_ENA | - LCDC_FRAME_DONE); -+ } - - return 0; - } -@@ -397,7 +398,7 @@ static void tilcdc_irq_uninstall(struct drm_device *dev) - LCDC_V1_UNDERFLOW_INT_ENA | LCDC_V1_PL_INT_ENA); - tilcdc_clear(dev, LCDC_DMA_CTRL_REG, LCDC_V1_END_OF_FRAME_INT_ENA); - } else { -- tilcdc_clear(dev, LCDC_INT_ENABLE_SET_REG, -+ tilcdc_write(dev, LCDC_INT_ENABLE_CLR_REG, - LCDC_V2_UNDERFLOW_INT_ENA | LCDC_V2_PL_INT_ENA | - LCDC_V2_END_OF_FRAME0_INT_ENA | - LCDC_FRAME_DONE); -@@ -442,7 +443,7 @@ static const struct { - REG(2, false, LCDC_INT_ENABLE_CLR_REG), - REG(2, false, LCDC_END_OF_INT_IND_REG), - REG(2, true, LCDC_CLK_ENABLE_REG), -- REG(2, true, LCDC_INT_ENABLE_SET_REG), -+ REG(2, true, LCDC_INT_ENABLE_SET_REG), - #undef REG - }; - --- -2.7.0 - diff --git a/patches/beaglebone/tilcdc/0018-drm-tilcdc-Remove-the-duplicate-LCDC_INT_ENABLE_SET_.patch b/patches/beaglebone/tilcdc/0018-drm-tilcdc-Remove-the-duplicate-LCDC_INT_ENABLE_SET_.patch deleted file mode 100644 index 005a1d87dc6aff59d7071859a5a15befb0ec9db7..0000000000000000000000000000000000000000 --- a/patches/beaglebone/tilcdc/0018-drm-tilcdc-Remove-the-duplicate-LCDC_INT_ENABLE_SET_.patch +++ /dev/null @@ -1,34 +0,0 @@ -From f3a99946a95b3482eabec63b9f662963d7d2e3c8 Mon Sep 17 00:00:00 2001 -From: Jyri Sarha <jsarha@ti.com> -Date: Fri, 8 Jan 2016 12:17:50 +0200 -Subject: [PATCH] drm/tilcdc: Remove the duplicate LCDC_INT_ENABLE_SET_REG in - registers[] - -Removes the duplicate LCDC_INT_ENABLE_SET_REG-entry in registers array. - -Signed-off-by: Jyri Sarha <jsarha@ti.com> -Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ti.com> ---- - drivers/gpu/drm/tilcdc/tilcdc_drv.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c -index 964e192..d96083d 100644 ---- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c -+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c -@@ -439,11 +439,10 @@ static const struct { - /* new in revision 2: */ - REG(2, false, LCDC_RAW_STAT_REG), - REG(2, false, LCDC_MASKED_STAT_REG), -- REG(2, false, LCDC_INT_ENABLE_SET_REG), -+ REG(2, true, LCDC_INT_ENABLE_SET_REG), - REG(2, false, LCDC_INT_ENABLE_CLR_REG), - REG(2, false, LCDC_END_OF_INT_IND_REG), - REG(2, true, LCDC_CLK_ENABLE_REG), -- REG(2, true, LCDC_INT_ENABLE_SET_REG), - #undef REG - }; - --- -2.7.0 - diff --git a/patches/beaglebone/tilcdc/0019-drm-tilcdc-Add-prints-on-sync-lost-and-FIFO-underrun.patch b/patches/beaglebone/tilcdc/0019-drm-tilcdc-Add-prints-on-sync-lost-and-FIFO-underrun.patch deleted file mode 100644 index dfe70c4d1dfc97955ea299895905a543e340c1d4..0000000000000000000000000000000000000000 --- a/patches/beaglebone/tilcdc/0019-drm-tilcdc-Add-prints-on-sync-lost-and-FIFO-underrun.patch +++ /dev/null @@ -1,59 +0,0 @@ -From c0c2baaab1b553df92a24e9175440f15e6ad3e2c Mon Sep 17 00:00:00 2001 -From: Jyri Sarha <jsarha@ti.com> -Date: Fri, 18 Dec 2015 13:07:52 +0200 -Subject: [PATCH] drm/tilcdc: Add prints on sync lost and FIFO underrun - interrupts - -Add ratelimited prints on sync lost and FIFO underrun interrupts. - -Signed-off-by: Jyri Sarha <jsarha@ti.com> -Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ti.com> ---- - drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 8 ++++++++ - drivers/gpu/drm/tilcdc/tilcdc_drv.c | 4 ++-- - 2 files changed, 10 insertions(+), 2 deletions(-) - -diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -index b1df046..5ee22c6 100644 ---- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -@@ -717,6 +717,14 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc) - tilcdc_write(dev, LCDC_END_OF_INT_IND_REG, 0); - } - -+ if (stat & LCDC_SYNC_LOST) -+ dev_err_ratelimited(dev->dev, "%s(0x%08x): Sync lost", -+ __func__, stat); -+ -+ if (stat & LCDC_FIFO_UNDERFLOW) -+ dev_err_ratelimited(dev->dev, "%s(0x%08x): FIFO underfow", -+ __func__, stat); -+ - return IRQ_HANDLED; - } - -diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c -index d96083d..41ec890 100644 ---- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c -+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c -@@ -382,7 +382,7 @@ static int tilcdc_irq_postinstall(struct drm_device *dev) - tilcdc_write(dev, LCDC_INT_ENABLE_SET_REG, - LCDC_V2_UNDERFLOW_INT_ENA | - LCDC_V2_END_OF_FRAME0_INT_ENA | -- LCDC_FRAME_DONE); -+ LCDC_FRAME_DONE | LCDC_SYNC_LOST); - } - - return 0; -@@ -401,7 +401,7 @@ static void tilcdc_irq_uninstall(struct drm_device *dev) - tilcdc_write(dev, LCDC_INT_ENABLE_CLR_REG, - LCDC_V2_UNDERFLOW_INT_ENA | LCDC_V2_PL_INT_ENA | - LCDC_V2_END_OF_FRAME0_INT_ENA | -- LCDC_FRAME_DONE); -+ LCDC_FRAME_DONE | LCDC_SYNC_LOST); - } - } - --- -2.7.0 - diff --git a/patches/beaglebone/tilcdc/0020-drm-tilcdc-Disable-sync-lost-interrupt-if-it-fires-o.patch b/patches/beaglebone/tilcdc/0020-drm-tilcdc-Disable-sync-lost-interrupt-if-it-fires-o.patch deleted file mode 100644 index ec791543bb163c19df20b20ee5dc367779e17329..0000000000000000000000000000000000000000 --- a/patches/beaglebone/tilcdc/0020-drm-tilcdc-Disable-sync-lost-interrupt-if-it-fires-o.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 5895d08f6ff2175dabc373dada7d1bfa26123fc9 Mon Sep 17 00:00:00 2001 -From: Jyri Sarha <jsarha@ti.com> -Date: Fri, 8 Jan 2016 14:33:09 +0200 -Subject: [PATCH] drm/tilcdc: Disable sync lost interrupt if it fires on every - frame - -Disable the sync lost interrupt if it fires on every frame for 50 -consecutive frames in a row. This is relatively sure sign of the sync -lost interrupt being stuck and firing on every frame even if the -display otherwise appears to work OK. - -Signed-off-by: Jyri Sarha <jsarha@ti.com> -Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ti.com> ---- - drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 21 ++++++++++++++++++++- - 1 file changed, 20 insertions(+), 1 deletion(-) - -diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -index 5ee22c6..248e3ea 100644 ---- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -@@ -43,6 +43,9 @@ struct tilcdc_crtc { - - /* Only set if an external encoder is connected */ - bool simulate_vesa_sync; -+ -+ int sync_lost_count; -+ bool frame_intact; - }; - #define to_tilcdc_crtc(x) container_of(x, struct tilcdc_crtc, base) - -@@ -662,6 +665,8 @@ out: - pm_runtime_put_sync(dev->dev); - } - -+#define SYNC_LOST_COUNT_LIMIT 50 -+ - irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc) - { - struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); -@@ -707,6 +712,11 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc) - - spin_unlock_irqrestore(&dev->event_lock, flags); - } -+ -+ if (tilcdc_crtc->frame_intact) -+ tilcdc_crtc->sync_lost_count = 0; -+ else -+ tilcdc_crtc->frame_intact = true; - } - - if (priv->rev == 2) { -@@ -717,9 +727,18 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc) - tilcdc_write(dev, LCDC_END_OF_INT_IND_REG, 0); - } - -- if (stat & LCDC_SYNC_LOST) -+ if (stat & LCDC_SYNC_LOST) { - dev_err_ratelimited(dev->dev, "%s(0x%08x): Sync lost", - __func__, stat); -+ tilcdc_crtc->frame_intact = false; -+ if (tilcdc_crtc->sync_lost_count++ > SYNC_LOST_COUNT_LIMIT) { -+ dev_err(dev->dev, -+ "%s(0x%08x): Sync lost flood detected, disabling the interrupt", -+ __func__, stat); -+ tilcdc_write(dev, LCDC_INT_ENABLE_CLR_REG, -+ LCDC_SYNC_LOST); -+ } -+ } - - if (stat & LCDC_FIFO_UNDERFLOW) - dev_err_ratelimited(dev->dev, "%s(0x%08x): FIFO underfow", --- -2.7.0 - diff --git a/patches/beaglebone/tilcdc/0021-drm-tilcdc-Initialize-crtc-port.patch b/patches/beaglebone/tilcdc/0021-drm-tilcdc-Initialize-crtc-port.patch deleted file mode 100644 index 211720d6148d35d7a055ebe8727cf446dd555de1..0000000000000000000000000000000000000000 --- a/patches/beaglebone/tilcdc/0021-drm-tilcdc-Initialize-crtc-port.patch +++ /dev/null @@ -1,66 +0,0 @@ -From d66284fba15014daacef64cfc610a249553534c6 Mon Sep 17 00:00:00 2001 -From: Jyri Sarha <jsarha@ti.com> -Date: Wed, 27 May 2015 11:58:37 +0300 -Subject: [PATCH] drm/tilcdc: Initialize crtc->port - -Initialize port device node pointer in the tilcdc crtc. Fixes "Falling -back to first CRTC" warning from tda998x driver. - -The tda998x encoder driver calls drm_of_find_possible_crtcs() to -initialize possible_crtcs of struct drm_encoder. The crtc->port needs -to be initialized for drm_of_find_possible_crtcs() to work. - -Signed-off-by: Jyri Sarha <jsarha@ti.com> -Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ti.com> ---- - drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 20 ++++++++++++++++++++ - 1 file changed, 20 insertions(+) - -diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -index 248e3ea..5f4da8c 100644 ---- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -@@ -124,6 +124,7 @@ static void tilcdc_crtc_destroy(struct drm_crtc *crtc) - - tilcdc_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); - -+ of_node_put(crtc->port); - drm_crtc_cleanup(crtc); - drm_flip_work_cleanup(&tilcdc_crtc->unref_work); - -@@ -749,6 +750,7 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc) - - struct drm_crtc *tilcdc_crtc_create(struct drm_device *dev) - { -+ struct tilcdc_drm_private *priv = dev->dev_private; - struct tilcdc_crtc *tilcdc_crtc; - struct drm_crtc *crtc; - int ret; -@@ -775,6 +777,24 @@ struct drm_crtc *tilcdc_crtc_create(struct drm_device *dev) - - drm_crtc_helper_add(crtc, &tilcdc_crtc_helper_funcs); - -+ if (priv->is_componentized) { -+ struct device_node *ports = -+ of_get_child_by_name(dev->dev->of_node, "ports"); -+ -+ if (ports) { -+ crtc->port = of_get_child_by_name(ports, "port"); -+ of_node_put(ports); -+ } else { -+ crtc->port = -+ of_get_child_by_name(dev->dev->of_node, "port"); -+ } -+ if (!crtc->port) { /* This should never happen */ -+ dev_err(dev->dev, "Port node not found in %s\n", -+ dev->dev->of_node->full_name); -+ goto fail; -+ } -+ } -+ - return crtc; - - fail: --- -2.7.0 - diff --git a/patches/beaglebone/tilcdc/0022-drm-tilcdc-Use-devm_kzalloc-and-devm_kcalloc-for-pri.patch b/patches/beaglebone/tilcdc/0022-drm-tilcdc-Use-devm_kzalloc-and-devm_kcalloc-for-pri.patch deleted file mode 100644 index 48a149b97948506c9ceaed298e3100ec7bbeadec..0000000000000000000000000000000000000000 --- a/patches/beaglebone/tilcdc/0022-drm-tilcdc-Use-devm_kzalloc-and-devm_kcalloc-for-pri.patch +++ /dev/null @@ -1,258 +0,0 @@ -From d0ec32caef0baa490b419895ef61c8481d49f7cd Mon Sep 17 00:00:00 2001 -From: Jyri Sarha <jsarha@ti.com> -Date: Tue, 23 Feb 2016 12:44:27 +0200 -Subject: [PATCH] drm/tilcdc: Use devm_kzalloc() and devm_kcalloc() for private - data - -Use devm_kzalloc() and devm_kcalloc() for private data allocation at -driver load time. - -Signed-off-by: Jyri Sarha <jsarha@ti.com> -Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ti.com> ---- - drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 4 +--- - drivers/gpu/drm/tilcdc/tilcdc_drv.c | 19 +++++++------------ - drivers/gpu/drm/tilcdc/tilcdc_panel.c | 20 ++++++-------------- - drivers/gpu/drm/tilcdc/tilcdc_tfp410.c | 24 +++++++----------------- - 4 files changed, 21 insertions(+), 46 deletions(-) - -diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -index 5f4da8c..051e5e1 100644 ---- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -@@ -127,8 +127,6 @@ static void tilcdc_crtc_destroy(struct drm_crtc *crtc) - of_node_put(crtc->port); - drm_crtc_cleanup(crtc); - drm_flip_work_cleanup(&tilcdc_crtc->unref_work); -- -- kfree(tilcdc_crtc); - } - - static int tilcdc_verify_fb(struct drm_crtc *crtc, struct drm_framebuffer *fb) -@@ -755,7 +753,7 @@ struct drm_crtc *tilcdc_crtc_create(struct drm_device *dev) - struct drm_crtc *crtc; - int ret; - -- tilcdc_crtc = kzalloc(sizeof(*tilcdc_crtc), GFP_KERNEL); -+ tilcdc_crtc = devm_kzalloc(dev->dev, sizeof(*tilcdc_crtc), GFP_KERNEL); - if (!tilcdc_crtc) { - dev_err(dev->dev, "allocation failed\n"); - return NULL; -diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c -index 41ec890..709bc90 100644 ---- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c -+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c -@@ -143,9 +143,6 @@ static int tilcdc_unload(struct drm_device *dev) - - pm_runtime_disable(dev->dev); - -- kfree(priv->saved_register); -- kfree(priv); -- - return 0; - } - -@@ -161,13 +158,12 @@ static int tilcdc_load(struct drm_device *dev, unsigned long flags) - u32 bpp = 0; - int ret; - -- priv = kzalloc(sizeof(*priv), GFP_KERNEL); -+ priv = devm_kzalloc(dev->dev, sizeof(*priv), GFP_KERNEL); - if (priv) -- priv->saved_register = kcalloc(tilcdc_num_regs(), -- sizeof(*priv->saved_register), -- GFP_KERNEL); -+ priv->saved_register = -+ devm_kcalloc(dev->dev, tilcdc_num_regs(), -+ sizeof(*priv->saved_register), GFP_KERNEL); - if (!priv || !priv->saved_register) { -- kfree(priv); - dev_err(dev->dev, "failed to allocate private data\n"); - return -ENOMEM; - } -@@ -180,7 +176,7 @@ static int tilcdc_load(struct drm_device *dev, unsigned long flags) - priv->wq = alloc_ordered_workqueue("tilcdc", 0); - if (!priv->wq) { - ret = -ENOMEM; -- goto fail_free_priv; -+ goto fail_unset_priv; - } - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -@@ -346,10 +342,9 @@ fail_free_wq: - flush_workqueue(priv->wq); - destroy_workqueue(priv->wq); - --fail_free_priv: -+fail_unset_priv: - dev->dev_private = NULL; -- kfree(priv->saved_register); -- kfree(priv); -+ - return ret; - } - -diff --git a/drivers/gpu/drm/tilcdc/tilcdc_panel.c b/drivers/gpu/drm/tilcdc/tilcdc_panel.c -index 8dcf02a..ff7774c 100644 ---- a/drivers/gpu/drm/tilcdc/tilcdc_panel.c -+++ b/drivers/gpu/drm/tilcdc/tilcdc_panel.c -@@ -45,14 +45,6 @@ struct panel_encoder { - }; - #define to_panel_encoder(x) container_of(x, struct panel_encoder, base) - -- --static void panel_encoder_destroy(struct drm_encoder *encoder) --{ -- struct panel_encoder *panel_encoder = to_panel_encoder(encoder); -- drm_encoder_cleanup(encoder); -- kfree(panel_encoder); --} -- - static void panel_encoder_dpms(struct drm_encoder *encoder, int mode) - { - struct panel_encoder *panel_encoder = to_panel_encoder(encoder); -@@ -90,7 +82,7 @@ static void panel_encoder_mode_set(struct drm_encoder *encoder, - } - - static const struct drm_encoder_funcs panel_encoder_funcs = { -- .destroy = panel_encoder_destroy, -+ .destroy = drm_encoder_cleanup, - }; - - static const struct drm_encoder_helper_funcs panel_encoder_helper_funcs = { -@@ -107,7 +99,8 @@ static struct drm_encoder *panel_encoder_create(struct drm_device *dev, - struct drm_encoder *encoder; - int ret; - -- panel_encoder = kzalloc(sizeof(*panel_encoder), GFP_KERNEL); -+ panel_encoder = devm_kzalloc(dev->dev, sizeof(*panel_encoder), -+ GFP_KERNEL); - if (!panel_encoder) { - dev_err(dev->dev, "allocation failed\n"); - return NULL; -@@ -128,7 +121,7 @@ static struct drm_encoder *panel_encoder_create(struct drm_device *dev, - return encoder; - - fail: -- panel_encoder_destroy(encoder); -+ drm_encoder_cleanup(encoder); - return NULL; - } - -@@ -147,10 +140,8 @@ struct panel_connector { - - static void panel_connector_destroy(struct drm_connector *connector) - { -- struct panel_connector *panel_connector = to_panel_connector(connector); - drm_connector_unregister(connector); - drm_connector_cleanup(connector); -- kfree(panel_connector); - } - - static enum drm_connector_status panel_connector_detect( -@@ -223,7 +214,8 @@ static struct drm_connector *panel_connector_create(struct drm_device *dev, - struct drm_connector *connector; - int ret; - -- panel_connector = kzalloc(sizeof(*panel_connector), GFP_KERNEL); -+ panel_connector = devm_kzalloc(dev->dev, sizeof(*panel_connector), -+ GFP_KERNEL); - if (!panel_connector) { - dev_err(dev->dev, "allocation failed\n"); - return NULL; -diff --git a/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c b/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c -index 1c23017..7716f42 100644 ---- a/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c -+++ b/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c -@@ -54,14 +54,6 @@ struct tfp410_encoder { - }; - #define to_tfp410_encoder(x) container_of(x, struct tfp410_encoder, base) - -- --static void tfp410_encoder_destroy(struct drm_encoder *encoder) --{ -- struct tfp410_encoder *tfp410_encoder = to_tfp410_encoder(encoder); -- drm_encoder_cleanup(encoder); -- kfree(tfp410_encoder); --} -- - static void tfp410_encoder_dpms(struct drm_encoder *encoder, int mode) - { - struct tfp410_encoder *tfp410_encoder = to_tfp410_encoder(encoder); -@@ -99,7 +91,7 @@ static void tfp410_encoder_mode_set(struct drm_encoder *encoder, - } - - static const struct drm_encoder_funcs tfp410_encoder_funcs = { -- .destroy = tfp410_encoder_destroy, -+ .destroy = drm_encoder_cleanup, - }; - - static const struct drm_encoder_helper_funcs tfp410_encoder_helper_funcs = { -@@ -116,7 +108,8 @@ static struct drm_encoder *tfp410_encoder_create(struct drm_device *dev, - struct drm_encoder *encoder; - int ret; - -- tfp410_encoder = kzalloc(sizeof(*tfp410_encoder), GFP_KERNEL); -+ tfp410_encoder = devm_kzalloc(dev->dev, sizeof(*tfp410_encoder), -+ GFP_KERNEL); - if (!tfp410_encoder) { - dev_err(dev->dev, "allocation failed\n"); - return NULL; -@@ -138,7 +131,7 @@ static struct drm_encoder *tfp410_encoder_create(struct drm_device *dev, - return encoder; - - fail: -- tfp410_encoder_destroy(encoder); -+ drm_encoder_cleanup(encoder); - return NULL; - } - -@@ -157,10 +150,8 @@ struct tfp410_connector { - - static void tfp410_connector_destroy(struct drm_connector *connector) - { -- struct tfp410_connector *tfp410_connector = to_tfp410_connector(connector); - drm_connector_unregister(connector); - drm_connector_cleanup(connector); -- kfree(tfp410_connector); - } - - static enum drm_connector_status tfp410_connector_detect( -@@ -228,7 +219,8 @@ static struct drm_connector *tfp410_connector_create(struct drm_device *dev, - struct drm_connector *connector; - int ret; - -- tfp410_connector = kzalloc(sizeof(*tfp410_connector), GFP_KERNEL); -+ tfp410_connector = devm_kzalloc(dev->dev, sizeof(*tfp410_connector), -+ GFP_KERNEL); - if (!tfp410_connector) { - dev_err(dev->dev, "allocation failed\n"); - return NULL; -@@ -313,7 +305,7 @@ static int tfp410_probe(struct platform_device *pdev) - return -ENXIO; - } - -- tfp410_mod = kzalloc(sizeof(*tfp410_mod), GFP_KERNEL); -+ tfp410_mod = devm_kzalloc(&pdev->dev, sizeof(*tfp410_mod), GFP_KERNEL); - if (!tfp410_mod) - return -ENOMEM; - -@@ -366,7 +358,6 @@ fail_adapter: - i2c_put_adapter(tfp410_mod->i2c); - - fail: -- kfree(tfp410_mod); - tilcdc_module_cleanup(mod); - return ret; - } -@@ -380,7 +371,6 @@ static int tfp410_remove(struct platform_device *pdev) - gpio_free(tfp410_mod->gpio); - - tilcdc_module_cleanup(mod); -- kfree(tfp410_mod); - - return 0; - } --- -2.7.0 - diff --git a/patches/defconfig b/patches/defconfig index a23f9112d6e1547054056ff5381b0342c96c8775..11c07f6b2e2b35ebbad5ecb7925d24b43957999f 100644 --- a/patches/defconfig +++ b/patches/defconfig @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/arm 4.6.0 Kernel Configuration +# Linux/arm 4.7.0-rc1 Kernel Configuration # CONFIG_ARM=y CONFIG_ARM_HAS_SG_CHAIN=y @@ -115,6 +115,7 @@ CONFIG_BUILD_BIN2C=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=17 +CONFIG_NMI_LOG_BUF_SHIFT=13 CONFIG_GENERIC_SCHED_CLOCK=y CONFIG_CGROUPS=y CONFIG_PAGE_COUNTER=y @@ -154,6 +155,7 @@ CONFIG_RD_LZMA=y CONFIG_RD_XZ=y CONFIG_RD_LZO=y CONFIG_RD_LZ4=y +CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -170,6 +172,7 @@ CONFIG_KALLSYMS_ALL=y # CONFIG_KALLSYMS_ABSOLUTE_PERCPU is not set CONFIG_KALLSYMS_BASE_RELATIVE=y CONFIG_PRINTK=y +CONFIG_PRINTK_NMI=y CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y @@ -198,6 +201,7 @@ CONFIG_VM_EVENT_COUNTERS=y CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set +# CONFIG_SLAB_FREELIST_RANDOM is not set # CONFIG_SYSTEM_DATA_VERIFICATION is not set CONFIG_PROFILING=y CONFIG_TRACEPOINTS=y @@ -214,6 +218,7 @@ CONFIG_ARCH_USE_BUILTIN_BSWAP=y CONFIG_KRETPROBES=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_NMI=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_CONTIGUOUS=y CONFIG_GENERIC_SMP_IDLE_THREAD=y @@ -240,12 +245,15 @@ 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_MIN=8 CONFIG_ARCH_MMAP_RND_BITS_MAX=16 CONFIG_ARCH_MMAP_RND_BITS=8 +# CONFIG_HAVE_ARCH_HASH is not set CONFIG_CLONE_BACKWARDS=y CONFIG_OLD_SIGSUSPEND3=y CONFIG_OLD_SIGACTION=y +# CONFIG_CPU_NO_EFFICIENT_FFS is not set # # GCOV-based kernel profiling @@ -264,6 +272,7 @@ CONFIG_MODVERSIONS=y # 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 @@ -499,12 +508,9 @@ CONFIG_VMSPLIT_3G=y CONFIG_PAGE_OFFSET=0xC0000000 CONFIG_ARM_PSCI=y CONFIG_ARCH_NR_GPIO=0 -CONFIG_HAVE_PREEMPT_LAZY=y # CONFIG_PREEMPT_NONE is not set CONFIG_PREEMPT_VOLUNTARY=y -# CONFIG_PREEMPT__LL is not set -# CONFIG_PREEMPT_RTB is not set -# CONFIG_PREEMPT_RT_FULL is not set +# CONFIG_PREEMPT is not set CONFIG_HZ_FIXED=0 # CONFIG_HZ_100 is not set # CONFIG_HZ_200 is not set @@ -541,7 +547,6 @@ CONFIG_BALLOON_COMPACTION=y CONFIG_COMPACTION=y CONFIG_MIGRATION=y # CONFIG_PHYS_ADDR_T_64BIT is not set -CONFIG_ZONE_DMA_FLAG=0 CONFIG_BOUNCE=y CONFIG_KSM=y CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -555,6 +560,7 @@ CONFIG_CMA_AREAS=7 CONFIG_ZSWAP=y CONFIG_ZPOOL=y CONFIG_ZBUD=y +# CONFIG_Z3FOLD is not set CONFIG_ZSMALLOC=m # CONFIG_PGTABLE_MAPPING is not set # CONFIG_ZSMALLOC_STAT is not set @@ -598,6 +604,7 @@ CONFIG_AUTO_ZRELADDR=y # CPU Frequency scaling # CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_GOV_ATTR_SET=y CONFIG_CPU_FREQ_GOV_COMMON=y CONFIG_CPU_FREQ_STAT=m CONFIG_CPU_FREQ_STAT_DETAILS=y @@ -616,8 +623,10 @@ CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m # CPU frequency scaling drivers # CONFIG_CPUFREQ_DT=m +CONFIG_CPUFREQ_DT_PLATDEV=y # CONFIG_ARM_KIRKWOOD_CPUFREQ is not set # CONFIG_ARM_OMAP2PLUS_CPUFREQ is not set +CONFIG_ARM_TI_CPUFREQ=y # CONFIG_QORIQ_CPUFREQ is not set # @@ -651,6 +660,7 @@ CONFIG_KERNEL_MODE_NEON=y # Userspace binary formats # CONFIG_BINFMT_ELF=y +CONFIG_ELFCORE=y CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y CONFIG_BINFMT_SCRIPT=y # CONFIG_HAVE_AOUT is not set @@ -1146,6 +1156,7 @@ CONFIG_SCTP_DEFAULT_COOKIE_HMAC_MD5=y # CONFIG_SCTP_DEFAULT_COOKIE_HMAC_NONE is not set CONFIG_SCTP_COOKIE_HMAC_MD5=y CONFIG_SCTP_COOKIE_HMAC_SHA1=y +CONFIG_INET_SCTP_DIAG=m CONFIG_RDS=m CONFIG_RDS_TCP=m # CONFIG_RDS_DEBUG is not set @@ -1173,7 +1184,6 @@ CONFIG_HAVE_NET_DSA=y CONFIG_NET_DSA=m CONFIG_NET_DSA_HWMON=y CONFIG_NET_DSA_TAG_BRCM=y -CONFIG_NET_DSA_TAG_DSA=y CONFIG_NET_DSA_TAG_EDSA=y CONFIG_NET_DSA_TAG_TRAILER=y CONFIG_VLAN_8021Q=m @@ -1428,7 +1438,7 @@ CONFIG_BT_ATH3K=m CONFIG_BT_WILINK=m CONFIG_AF_RXRPC=m # CONFIG_AF_RXRPC_DEBUG is not set -CONFIG_RXKAD=m +# CONFIG_RXKAD is not set # CONFIG_AF_KCM is not set CONFIG_FIB_RULES=y CONFIG_WIRELESS=y @@ -1489,7 +1499,6 @@ CONFIG_NFC_SHDLC=y # # Near Field Communication (NFC) devices # -CONFIG_NFC_PN533=m CONFIG_NFC_WILINK=m # CONFIG_NFC_TRF7970A is not set CONFIG_NFC_SIM=m @@ -1497,6 +1506,9 @@ CONFIG_NFC_PORT100=m # CONFIG_NFC_FDP is not set CONFIG_NFC_PN544=m CONFIG_NFC_PN544_I2C=m +CONFIG_NFC_PN533=m +CONFIG_NFC_PN533_USB=m +CONFIG_NFC_PN533_I2C=m CONFIG_NFC_MICROREAD=m CONFIG_NFC_MICROREAD_I2C=m # CONFIG_NFC_MRVL_USB is not set @@ -1510,7 +1522,7 @@ CONFIG_LWTUNNEL=y CONFIG_DST_CACHE=y # CONFIG_NET_DEVLINK is not set CONFIG_MAY_USE_DEVLINK=y -CONFIG_HAVE_BPF_JIT=y +CONFIG_HAVE_CBPF_JIT=y # # Device Drivers @@ -1723,7 +1735,6 @@ CONFIG_AD525X_DPOT=m CONFIG_AD525X_DPOT_I2C=m CONFIG_AD525X_DPOT_SPI=m # CONFIG_DUMMY_IRQ is not set -CONFIG_HWLAT_DETECTOR=m CONFIG_ICS932S401=m CONFIG_ENCLOSURE_SERVICES=m CONFIG_APDS9802ALS=m @@ -1887,6 +1898,7 @@ CONFIG_ATA_BMDMA=y # # SATA SFF controllers with BMDMA # +# CONFIG_SATA_DWC is not set # # PATA SFF controllers with BMDMA @@ -1969,6 +1981,7 @@ CONFIG_MACVTAP=m CONFIG_IPVLAN=m CONFIG_VXLAN=m CONFIG_GENEVE=m +# CONFIG_GTP is not set # CONFIG_MACSEC is not set CONFIG_NETCONSOLE=m CONFIG_NETCONSOLE_DYNAMIC=y @@ -1994,13 +2007,8 @@ CONFIG_ATM_DUMMY=m # # Distributed Switch Architecture drivers # -CONFIG_NET_DSA_MV88E6XXX=m CONFIG_NET_DSA_MV88E6060=m -CONFIG_NET_DSA_MV88E6XXX_NEED_PPU=y -CONFIG_NET_DSA_MV88E6131=m -# CONFIG_NET_DSA_MV88E6123 is not set -CONFIG_NET_DSA_MV88E6171=m -CONFIG_NET_DSA_MV88E6352=m +CONFIG_NET_DSA_MV88E6XXX=m CONFIG_NET_DSA_BCM_SF2=m CONFIG_ETHERNET=y # CONFIG_ALTERA_TSE is not set @@ -2618,6 +2626,7 @@ CONFIG_DEVKMEM=y CONFIG_SERIAL_EARLYCON=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y +# CONFIG_SERIAL_8250_FINTEK is not set CONFIG_SERIAL_8250_CONSOLE=y # CONFIG_SERIAL_8250_DMA is not set CONFIG_SERIAL_8250_NR_UARTS=6 @@ -2650,12 +2659,12 @@ CONFIG_CONSOLE_POLL=y # CONFIG_SERIAL_ALTERA_UART is not set # CONFIG_SERIAL_IFX6X60 is not set # CONFIG_SERIAL_XILINX_PS_UART is not set +# CONFIG_SERIAL_MPS2_UART is not set # CONFIG_SERIAL_ARC 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_STM32 is not set -# CONFIG_SERIAL_MVEBU_UART is not set CONFIG_TTY_PRINTK=m CONFIG_HVC_DRIVER=y # CONFIG_HVC_DCC is not set @@ -3027,6 +3036,7 @@ CONFIG_SENSORS_MAX16065=m CONFIG_SENSORS_MAX1619=m CONFIG_SENSORS_MAX1668=m CONFIG_SENSORS_MAX197=m +CONFIG_SENSORS_MAX31722=m CONFIG_SENSORS_MAX6639=m CONFIG_SENSORS_MAX6642=m CONFIG_SENSORS_MAX6650=m @@ -3133,11 +3143,16 @@ CONFIG_DEVFREQ_THERMAL=y # CONFIG_THERMAL_EMULATION is not set # CONFIG_IMX_THERMAL is not set +# +# ACPI INT340X thermal drivers +# + # # Texas Instruments thermal drivers # CONFIG_TI_SOC_THERMAL=y CONFIG_TI_THERMAL=y +CONFIG_GENERIC_ADC_THERMAL=m CONFIG_WATCHDOG=y CONFIG_WATCHDOG_CORE=y CONFIG_WATCHDOG_NOWAYOUT=y @@ -3226,6 +3241,7 @@ CONFIG_MFD_MC13XXX_I2C=m # 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 @@ -3327,6 +3343,7 @@ CONFIG_REGULATOR_PALMAS=y CONFIG_REGULATOR_PBIAS=y CONFIG_REGULATOR_PFUZE100=y # CONFIG_REGULATOR_PV88060 is not set +# CONFIG_REGULATOR_PV88080 is not set # CONFIG_REGULATOR_PV88090 is not set CONFIG_REGULATOR_PWM=y CONFIG_REGULATOR_S2MPA01=m @@ -3619,6 +3636,7 @@ CONFIG_DVB_B2C2_FLEXCOP=m CONFIG_SMS_SIANO_MDTV=m CONFIG_SMS_SIANO_RC=y # CONFIG_SMS_SIANO_DEBUGFS is not set +CONFIG_VIDEO_V4L2_TPG=m # # Media ancillary drivers (tuners, sensors, i2c, frontends) @@ -3733,6 +3751,7 @@ 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 @@ -3828,6 +3847,7 @@ CONFIG_DVB_MB86A20S=m # # ISDB-S (satellite) & ISDB-T (terrestrial) frontends # +CONFIG_DVB_TC90522=m # # Digital terrestrial only tuners/PLL @@ -3883,7 +3903,6 @@ CONFIG_DRM_I2C_NXP_TDA998X=m # # ACP (Audio CoProcessor) Configuration # -# CONFIG_DRM_AMD_ACP is not set CONFIG_DRM_VGEM=m # CONFIG_DRM_EXYNOS is not set CONFIG_DRM_UDL=m @@ -3898,9 +3917,11 @@ CONFIG_DRM_BRIDGE=y # # Display Interface Bridges # +CONFIG_DRM_ANALOGIX_ANX78XX=m # CONFIG_DRM_NXP_PTN3460 is not set # CONFIG_DRM_PARADE_PS8622 is not set # CONFIG_DRM_STI is not set +# CONFIG_DRM_ARCPGU is not set # # Frame buffer Devices @@ -4042,6 +4063,7 @@ CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y # CONFIG_SND_SOC_AMD_ACP is not set # CONFIG_SND_ATMEL_SOC is not set CONFIG_SND_EDMA_SOC=m +CONFIG_SND_DAVINCI_SOC_I2S=m CONFIG_SND_DAVINCI_SOC_MCASP=m CONFIG_SND_DAVINCI_SOC_GENERIC_EVM=m CONFIG_SND_AM33XX_SOC_EVM=m @@ -4122,6 +4144,7 @@ CONFIG_SND_SOC_SGTL5000=m # 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_TFA9879 is not set CONFIG_SND_SOC_TLV320AIC23=m CONFIG_SND_SOC_TLV320AIC23_I2C=m @@ -4145,6 +4168,7 @@ CONFIG_SND_SOC_TWL4030=m # CONFIG_SND_SOC_WM8804_I2C is not set # 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 @@ -4350,6 +4374,7 @@ CONFIG_USB_MICROTEK=m CONFIG_USBIP_CORE=m CONFIG_USBIP_VHCI_HCD=m CONFIG_USBIP_HOST=m +CONFIG_USBIP_VUDC=m # CONFIG_USBIP_DEBUG is not set CONFIG_USB_MUSB_HDRC=y # CONFIG_USB_MUSB_HOST is not set @@ -4601,6 +4626,8 @@ CONFIG_UWB_HWA=m CONFIG_UWB_I1480U=m CONFIG_MMC=y # CONFIG_MMC_DEBUG is not set +CONFIG_PWRSEQ_EMMC=y +CONFIG_PWRSEQ_SIMPLE=y # # MMC/SD/SDIO Card Drivers @@ -4691,6 +4718,7 @@ CONFIG_LEDS_IS31FL32XX=m CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_TIMER=y CONFIG_LEDS_TRIGGER_ONESHOT=y +# CONFIG_LEDS_TRIGGER_MTD is not set CONFIG_LEDS_TRIGGER_HEARTBEAT=y CONFIG_LEDS_TRIGGER_BACKLIGHT=y CONFIG_LEDS_TRIGGER_CPU=y @@ -4702,6 +4730,7 @@ CONFIG_LEDS_TRIGGER_DEFAULT_ON=y # CONFIG_LEDS_TRIGGER_TRANSIENT=m CONFIG_LEDS_TRIGGER_CAMERA=m +# CONFIG_LEDS_TRIGGER_PANIC is not set CONFIG_ACCESSIBILITY=y CONFIG_A11Y_BRAILLE_CONSOLE=y CONFIG_EDAC_ATOMIC_SCRUB=y @@ -4758,8 +4787,6 @@ CONFIG_RTC_DRV_RX8010=m CONFIG_RTC_DRV_RX8581=m CONFIG_RTC_DRV_RX8025=m CONFIG_RTC_DRV_EM3027=m -CONFIG_RTC_DRV_RV3029C2=m -CONFIG_RTC_DRV_RV3029_HWMON=y CONFIG_RTC_DRV_RV8803=m CONFIG_RTC_DRV_S5M=y @@ -4768,6 +4795,7 @@ CONFIG_RTC_DRV_S5M=y # CONFIG_RTC_DRV_M41T93=m CONFIG_RTC_DRV_M41T94=m +CONFIG_RTC_DRV_DS1302=m CONFIG_RTC_DRV_DS1305=m CONFIG_RTC_DRV_DS1343=m CONFIG_RTC_DRV_DS1347=m @@ -4786,6 +4814,8 @@ CONFIG_RTC_I2C_AND_SPI=y # CONFIG_RTC_DRV_DS3232=m CONFIG_RTC_DRV_PCF2127=m +CONFIG_RTC_DRV_RV3029C2=m +CONFIG_RTC_DRV_RV3029_HWMON=y # # Platform RTC drivers @@ -4854,6 +4884,11 @@ CONFIG_DW_DMAC=y # CONFIG_ASYNC_TX_DMA=y # CONFIG_DMATEST is not set + +# +# DMABUF options +# +CONFIG_SYNC_FILE=y # CONFIG_AUXDISPLAY is not set CONFIG_UIO=m CONFIG_UIO_PDRV_GENIRQ=m @@ -4896,9 +4931,7 @@ CONFIG_88EU_AP_MODE=y # CONFIG_ADIS16201=m CONFIG_ADIS16203=m -CONFIG_ADIS16204=m CONFIG_ADIS16209=m -CONFIG_ADIS16220=m CONFIG_ADIS16240=m CONFIG_LIS3L02DQ=m CONFIG_SCA3000=m @@ -4995,8 +5028,6 @@ CONFIG_SPEAKUP_SYNTH_DUMMY=m # Android # CONFIG_ASHMEM=y -CONFIG_ANDROID_TIMED_OUTPUT=y -CONFIG_ANDROID_TIMED_GPIO=m # CONFIG_ANDROID_LOW_MEMORY_KILLER is not set CONFIG_SYNC=y # CONFIG_SW_SYNC is not set @@ -5068,6 +5099,8 @@ CONFIG_CLK_TWL6040=y CONFIG_COMMON_CLK_PALMAS=y # CONFIG_COMMON_CLK_PWM is not set # CONFIG_COMMON_CLK_PXA is not set +# CONFIG_COMMON_CLK_PIC32 is not set +# CONFIG_COMMON_CLK_OXNAS is not set CONFIG_COMMON_CLK_TI_ADPLL=y CONFIG_HWSPINLOCK=y @@ -5138,6 +5171,7 @@ CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y CONFIG_DEVFREQ_GOV_PERFORMANCE=y CONFIG_DEVFREQ_GOV_POWERSAVE=y CONFIG_DEVFREQ_GOV_USERSPACE=y +# CONFIG_DEVFREQ_GOV_PASSIVE is not set # # DEVFREQ Drivers @@ -5150,6 +5184,9 @@ CONFIG_EXTCON=y # # CONFIG_EXTCON_ADC_JACK is not set # CONFIG_EXTCON_AXP288 is not set +CONFIG_EXTCON_DT_CON=y +CONFIG_EXTCON_DT_CON_PROXY=y +CONFIG_EXTCON_DT_CON_GPIO=y CONFIG_EXTCON_GPIO=y # CONFIG_EXTCON_MAX3355 is not set CONFIG_EXTCON_PALMAS=y @@ -5267,6 +5304,9 @@ CONFIG_AD5380=m CONFIG_AD5421=m CONFIG_AD5446=m CONFIG_AD5449=m +CONFIG_AD5592R_BASE=m +CONFIG_AD5592R=m +CONFIG_AD5593R=m CONFIG_AD5504=m CONFIG_AD5624R_SPI=m CONFIG_AD5686=m @@ -5332,6 +5372,7 @@ CONFIG_MAX30100=m # # Humidity sensors # +CONFIG_AM2315=m CONFIG_DHT11=m CONFIG_HDC100X=m CONFIG_HTU21=m @@ -5343,6 +5384,9 @@ CONFIG_SI7020=m # CONFIG_ADIS16400=m CONFIG_ADIS16480=m +CONFIG_BMI160=m +CONFIG_BMI160_I2C=m +CONFIG_BMI160_SPI=m CONFIG_KMX61=m CONFIG_INV_MPU6050_IIO=m CONFIG_INV_MPU6050_I2C=m @@ -5358,6 +5402,7 @@ CONFIG_AL3320A=m CONFIG_APDS9300=m CONFIG_APDS9960=m CONFIG_BH1750=m +CONFIG_BH1780=m CONFIG_CM32181=m CONFIG_CM3232=m CONFIG_CM3323=m @@ -5369,6 +5414,7 @@ CONFIG_HID_SENSOR_PROX=m CONFIG_JSA1212=m CONFIG_RPR0521=m CONFIG_LTR501=m +CONFIG_MAX44000=m CONFIG_OPT3001=m CONFIG_PA12203001=m CONFIG_STK3310=m @@ -5378,6 +5424,7 @@ CONFIG_SENSORS_TSL2563=m CONFIG_TSL4531=m CONFIG_US5182D=m CONFIG_VCNL4000=m +CONFIG_VEML6070=m # # Magnetometer sensors @@ -5385,6 +5432,8 @@ CONFIG_VCNL4000=m CONFIG_AK8975=m CONFIG_AK09911=m CONFIG_BMC150_MAGN=m +CONFIG_BMC150_MAGN_I2C=m +CONFIG_BMC150_MAGN_SPI=m CONFIG_MAG3110=m CONFIG_HID_SENSOR_MAGNETOMETER_3D=m CONFIG_MMC35240=m @@ -5410,6 +5459,8 @@ CONFIG_IIO_SYSFS_TRIGGER=m # # Digital potentiometers # +CONFIG_DS1803=m +CONFIG_MCP4131=m CONFIG_MCP4531=m CONFIG_TPL0102=m @@ -5418,6 +5469,7 @@ CONFIG_TPL0102=m # CONFIG_BMP280=m CONFIG_HID_SENSOR_PRESS=m +CONFIG_HP03=m CONFIG_MPL115=m CONFIG_MPL115_I2C=m CONFIG_MPL115_SPI=m @@ -5430,6 +5482,7 @@ CONFIG_IIO_ST_PRESS=m CONFIG_IIO_ST_PRESS_I2C=m CONFIG_IIO_ST_PRESS_SPI=m CONFIG_T5403=m +CONFIG_HP206C=m # # Lightning sensors @@ -5569,6 +5622,7 @@ CONFIG_F2FS_FS_SECURITY=y # CONFIG_F2FS_CHECK_FS is not set CONFIG_F2FS_FS_ENCRYPTION=y # CONFIG_F2FS_IO_TRACE is not set +# CONFIG_F2FS_FAULT_INJECTION is not set CONFIG_FS_POSIX_ACL=y CONFIG_EXPORTFS=y CONFIG_FILE_LOCKING=y @@ -5942,6 +5996,7 @@ CONFIG_DEBUG_LIST=y # CONFIG_PROVE_RCU is not set # CONFIG_SPARSE_RCU_POINTER is not set # CONFIG_TORTURE_TEST is not set +# CONFIG_RCU_PERF_TEST is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_RCU_TRACE is not set # CONFIG_RCU_EQS_DEBUG is not set @@ -5972,7 +6027,6 @@ CONFIG_FTRACE=y CONFIG_FUNCTION_TRACER=y # CONFIG_IRQSOFF_TRACER is not set # CONFIG_SCHED_TRACER is not set -# CONFIG_MISSED_TIMER_OFFSETS_HIST is not set CONFIG_FTRACE_SYSCALLS=y CONFIG_TRACER_SNAPSHOT=y # CONFIG_TRACER_SNAPSHOT_PER_CPU_SWAP is not set @@ -6013,6 +6067,7 @@ CONFIG_TRACING_EVENTS_GPIO=y # CONFIG_TEST_PRINTF is not set # CONFIG_TEST_BITMAP is not set # CONFIG_TEST_RHASHTABLE is not set +# CONFIG_TEST_HASH is not set # CONFIG_DMA_API_DEBUG is not set # CONFIG_TEST_LKM is not set CONFIG_TEST_USER_COPY=m @@ -6053,6 +6108,7 @@ CONFIG_KEYS=y # CONFIG_BIG_KEYS is not set # CONFIG_TRUSTED_KEYS is not set CONFIG_ENCRYPTED_KEYS=y +# CONFIG_KEY_DH_OPERATIONS is not set # CONFIG_SECURITY_DMESG_RESTRICT is not set CONFIG_SECURITY=y CONFIG_SECURITYFS=y @@ -6077,6 +6133,7 @@ CONFIG_SECURITY_TOMOYO_ACTIVATION_TRIGGER="/sbin/init" CONFIG_SECURITY_APPARMOR=y CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE=1 CONFIG_SECURITY_APPARMOR_HASH=y +# CONFIG_SECURITY_LOADPIN is not set CONFIG_SECURITY_YAMA=y CONFIG_INTEGRITY=y # CONFIG_INTEGRITY_SIGNATURE is not set @@ -6234,8 +6291,6 @@ 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 @@ -6334,5 +6389,6 @@ CONFIG_FONT_SUPPORT=y CONFIG_FONT_8x8=y CONFIG_FONT_8x16=y # CONFIG_SG_SPLIT is not set +CONFIG_SG_POOL=y CONFIG_ARCH_HAS_SG_CHAIN=y CONFIG_VIRTUALIZATION=y diff --git a/patches/defconfig-bone b/patches/defconfig-bone index baf9e0f3b9ff7f7d823e2af13d0b162ae29e44f4..a488e0d2d4409e08413ff3778908856233a13932 100644 --- a/patches/defconfig-bone +++ b/patches/defconfig-bone @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/arm 4.6.0 Kernel Configuration +# Linux/arm 4.7.0-rc1 Kernel Configuration # CONFIG_ARM=y CONFIG_ARM_HAS_SG_CHAIN=y @@ -115,6 +115,7 @@ CONFIG_BUILD_BIN2C=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=17 +CONFIG_NMI_LOG_BUF_SHIFT=13 CONFIG_GENERIC_SCHED_CLOCK=y CONFIG_CGROUPS=y CONFIG_PAGE_COUNTER=y @@ -154,6 +155,7 @@ CONFIG_RD_LZMA=y CONFIG_RD_XZ=y CONFIG_RD_LZO=y CONFIG_RD_LZ4=y +CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -170,6 +172,7 @@ CONFIG_KALLSYMS_ALL=y # CONFIG_KALLSYMS_ABSOLUTE_PERCPU is not set CONFIG_KALLSYMS_BASE_RELATIVE=y CONFIG_PRINTK=y +CONFIG_PRINTK_NMI=y CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y @@ -198,6 +201,7 @@ CONFIG_VM_EVENT_COUNTERS=y CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set +# CONFIG_SLAB_FREELIST_RANDOM is not set # CONFIG_SYSTEM_DATA_VERIFICATION is not set CONFIG_PROFILING=y CONFIG_TRACEPOINTS=y @@ -214,6 +218,7 @@ CONFIG_ARCH_USE_BUILTIN_BSWAP=y CONFIG_KRETPROBES=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_NMI=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_CONTIGUOUS=y CONFIG_GENERIC_SMP_IDLE_THREAD=y @@ -240,12 +245,15 @@ 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_MIN=8 CONFIG_ARCH_MMAP_RND_BITS_MAX=16 CONFIG_ARCH_MMAP_RND_BITS=8 +# CONFIG_HAVE_ARCH_HASH is not set CONFIG_CLONE_BACKWARDS=y CONFIG_OLD_SIGSUSPEND3=y CONFIG_OLD_SIGACTION=y +# CONFIG_CPU_NO_EFFICIENT_FFS is not set # # GCOV-based kernel profiling @@ -264,6 +272,7 @@ CONFIG_MODVERSIONS=y # 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 @@ -538,7 +547,6 @@ CONFIG_BALLOON_COMPACTION=y CONFIG_COMPACTION=y CONFIG_MIGRATION=y # CONFIG_PHYS_ADDR_T_64BIT is not set -CONFIG_ZONE_DMA_FLAG=0 CONFIG_BOUNCE=y CONFIG_KSM=y CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -552,6 +560,7 @@ CONFIG_CMA_AREAS=7 CONFIG_ZSWAP=y CONFIG_ZPOOL=y CONFIG_ZBUD=y +# CONFIG_Z3FOLD is not set CONFIG_ZSMALLOC=m # CONFIG_PGTABLE_MAPPING is not set # CONFIG_ZSMALLOC_STAT is not set @@ -585,8 +594,7 @@ CONFIG_KEXEC=y CONFIG_ATAGS_PROC=y # CONFIG_CRASH_DUMP is not set CONFIG_AUTO_ZRELADDR=y -CONFIG_EFI_STUB=y -CONFIG_EFI=y +# CONFIG_EFI is not set # # CPU Power Management @@ -596,6 +604,7 @@ CONFIG_EFI=y # CPU Frequency scaling # CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_GOV_ATTR_SET=y CONFIG_CPU_FREQ_GOV_COMMON=y CONFIG_CPU_FREQ_STAT=m CONFIG_CPU_FREQ_STAT_DETAILS=y @@ -614,8 +623,10 @@ CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m # CPU frequency scaling drivers # CONFIG_CPUFREQ_DT=m +CONFIG_CPUFREQ_DT_PLATDEV=y # CONFIG_ARM_KIRKWOOD_CPUFREQ is not set # CONFIG_ARM_OMAP2PLUS_CPUFREQ is not set +CONFIG_ARM_TI_CPUFREQ=y # CONFIG_QORIQ_CPUFREQ is not set # @@ -649,6 +660,7 @@ CONFIG_KERNEL_MODE_NEON=y # Userspace binary formats # CONFIG_BINFMT_ELF=y +CONFIG_ELFCORE=y CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y CONFIG_BINFMT_SCRIPT=y # CONFIG_HAVE_AOUT is not set @@ -1144,6 +1156,7 @@ CONFIG_SCTP_DEFAULT_COOKIE_HMAC_MD5=y # CONFIG_SCTP_DEFAULT_COOKIE_HMAC_NONE is not set CONFIG_SCTP_COOKIE_HMAC_MD5=y CONFIG_SCTP_COOKIE_HMAC_SHA1=y +CONFIG_INET_SCTP_DIAG=m CONFIG_RDS=m CONFIG_RDS_TCP=m # CONFIG_RDS_DEBUG is not set @@ -1171,7 +1184,6 @@ CONFIG_HAVE_NET_DSA=y CONFIG_NET_DSA=m CONFIG_NET_DSA_HWMON=y CONFIG_NET_DSA_TAG_BRCM=y -CONFIG_NET_DSA_TAG_DSA=y CONFIG_NET_DSA_TAG_EDSA=y CONFIG_NET_DSA_TAG_TRAILER=y CONFIG_VLAN_8021Q=m @@ -1426,7 +1438,7 @@ CONFIG_BT_ATH3K=m CONFIG_BT_WILINK=m CONFIG_AF_RXRPC=m # CONFIG_AF_RXRPC_DEBUG is not set -CONFIG_RXKAD=m +# CONFIG_RXKAD is not set # CONFIG_AF_KCM is not set CONFIG_FIB_RULES=y CONFIG_WIRELESS=y @@ -1487,7 +1499,6 @@ CONFIG_NFC_SHDLC=y # # Near Field Communication (NFC) devices # -CONFIG_NFC_PN533=m CONFIG_NFC_WILINK=m # CONFIG_NFC_TRF7970A is not set CONFIG_NFC_SIM=m @@ -1495,6 +1506,9 @@ CONFIG_NFC_PORT100=m # CONFIG_NFC_FDP is not set CONFIG_NFC_PN544=m CONFIG_NFC_PN544_I2C=m +CONFIG_NFC_PN533=m +CONFIG_NFC_PN533_USB=m +CONFIG_NFC_PN533_I2C=m CONFIG_NFC_MICROREAD=m CONFIG_NFC_MICROREAD_I2C=m # CONFIG_NFC_MRVL_USB is not set @@ -1508,7 +1522,7 @@ CONFIG_LWTUNNEL=y CONFIG_DST_CACHE=y # CONFIG_NET_DEVLINK is not set CONFIG_MAY_USE_DEVLINK=y -CONFIG_HAVE_BPF_JIT=y +CONFIG_HAVE_CBPF_JIT=y # # Device Drivers @@ -1884,6 +1898,7 @@ CONFIG_ATA_BMDMA=y # # SATA SFF controllers with BMDMA # +# CONFIG_SATA_DWC is not set # # PATA SFF controllers with BMDMA @@ -1966,6 +1981,7 @@ CONFIG_MACVTAP=m CONFIG_IPVLAN=m CONFIG_VXLAN=m CONFIG_GENEVE=m +# CONFIG_GTP is not set # CONFIG_MACSEC is not set CONFIG_NETCONSOLE=m CONFIG_NETCONSOLE_DYNAMIC=y @@ -1991,13 +2007,8 @@ CONFIG_ATM_DUMMY=m # # Distributed Switch Architecture drivers # -CONFIG_NET_DSA_MV88E6XXX=m CONFIG_NET_DSA_MV88E6060=m -CONFIG_NET_DSA_MV88E6XXX_NEED_PPU=y -CONFIG_NET_DSA_MV88E6131=m -# CONFIG_NET_DSA_MV88E6123 is not set -CONFIG_NET_DSA_MV88E6171=m -CONFIG_NET_DSA_MV88E6352=m +CONFIG_NET_DSA_MV88E6XXX=m CONFIG_NET_DSA_BCM_SF2=m CONFIG_ETHERNET=y # CONFIG_ALTERA_TSE is not set @@ -2615,6 +2626,7 @@ CONFIG_DEVKMEM=y CONFIG_SERIAL_EARLYCON=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y +# CONFIG_SERIAL_8250_FINTEK is not set CONFIG_SERIAL_8250_CONSOLE=y # CONFIG_SERIAL_8250_DMA is not set CONFIG_SERIAL_8250_NR_UARTS=6 @@ -2647,12 +2659,12 @@ CONFIG_CONSOLE_POLL=y # CONFIG_SERIAL_ALTERA_UART is not set # CONFIG_SERIAL_IFX6X60 is not set # CONFIG_SERIAL_XILINX_PS_UART is not set +# CONFIG_SERIAL_MPS2_UART is not set # CONFIG_SERIAL_ARC 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_STM32 is not set -# CONFIG_SERIAL_MVEBU_UART is not set CONFIG_TTY_PRINTK=m CONFIG_HVC_DRIVER=y # CONFIG_HVC_DCC is not set @@ -3024,6 +3036,7 @@ CONFIG_SENSORS_MAX16065=m CONFIG_SENSORS_MAX1619=m CONFIG_SENSORS_MAX1668=m CONFIG_SENSORS_MAX197=m +CONFIG_SENSORS_MAX31722=m CONFIG_SENSORS_MAX6639=m CONFIG_SENSORS_MAX6642=m CONFIG_SENSORS_MAX6650=m @@ -3130,11 +3143,16 @@ CONFIG_DEVFREQ_THERMAL=y # CONFIG_THERMAL_EMULATION is not set # CONFIG_IMX_THERMAL is not set +# +# ACPI INT340X thermal drivers +# + # # Texas Instruments thermal drivers # CONFIG_TI_SOC_THERMAL=y CONFIG_TI_THERMAL=y +CONFIG_GENERIC_ADC_THERMAL=m CONFIG_WATCHDOG=y CONFIG_WATCHDOG_CORE=y CONFIG_WATCHDOG_NOWAYOUT=y @@ -3223,6 +3241,7 @@ CONFIG_MFD_MC13XXX_I2C=m # 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 @@ -3324,6 +3343,7 @@ CONFIG_REGULATOR_PALMAS=y CONFIG_REGULATOR_PBIAS=y CONFIG_REGULATOR_PFUZE100=y # CONFIG_REGULATOR_PV88060 is not set +# CONFIG_REGULATOR_PV88080 is not set # CONFIG_REGULATOR_PV88090 is not set CONFIG_REGULATOR_PWM=y CONFIG_REGULATOR_S2MPA01=m @@ -3616,6 +3636,7 @@ CONFIG_DVB_B2C2_FLEXCOP=m CONFIG_SMS_SIANO_MDTV=m CONFIG_SMS_SIANO_RC=y # CONFIG_SMS_SIANO_DEBUGFS is not set +CONFIG_VIDEO_V4L2_TPG=m # # Media ancillary drivers (tuners, sensors, i2c, frontends) @@ -3730,6 +3751,7 @@ 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 @@ -3825,6 +3847,7 @@ CONFIG_DVB_MB86A20S=m # # ISDB-S (satellite) & ISDB-T (terrestrial) frontends # +CONFIG_DVB_TC90522=m # # Digital terrestrial only tuners/PLL @@ -3880,7 +3903,6 @@ CONFIG_DRM_I2C_NXP_TDA998X=m # # ACP (Audio CoProcessor) Configuration # -# CONFIG_DRM_AMD_ACP is not set CONFIG_DRM_VGEM=m # CONFIG_DRM_EXYNOS is not set CONFIG_DRM_UDL=m @@ -3895,9 +3917,11 @@ CONFIG_DRM_BRIDGE=y # # Display Interface Bridges # +CONFIG_DRM_ANALOGIX_ANX78XX=m # CONFIG_DRM_NXP_PTN3460 is not set # CONFIG_DRM_PARADE_PS8622 is not set # CONFIG_DRM_STI is not set +# CONFIG_DRM_ARCPGU is not set # # Frame buffer Devices @@ -4039,6 +4063,7 @@ CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y # CONFIG_SND_SOC_AMD_ACP is not set # CONFIG_SND_ATMEL_SOC is not set CONFIG_SND_EDMA_SOC=m +CONFIG_SND_DAVINCI_SOC_I2S=m CONFIG_SND_DAVINCI_SOC_MCASP=m CONFIG_SND_DAVINCI_SOC_GENERIC_EVM=m CONFIG_SND_AM33XX_SOC_EVM=m @@ -4119,6 +4144,7 @@ CONFIG_SND_SOC_SGTL5000=m # 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_TFA9879 is not set CONFIG_SND_SOC_TLV320AIC23=m CONFIG_SND_SOC_TLV320AIC23_I2C=m @@ -4142,6 +4168,7 @@ CONFIG_SND_SOC_TWL4030=m # CONFIG_SND_SOC_WM8804_I2C is not set # 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 @@ -4347,6 +4374,7 @@ CONFIG_USB_MICROTEK=m CONFIG_USBIP_CORE=m CONFIG_USBIP_VHCI_HCD=m CONFIG_USBIP_HOST=m +CONFIG_USBIP_VUDC=m # CONFIG_USBIP_DEBUG is not set CONFIG_USB_MUSB_HDRC=y # CONFIG_USB_MUSB_HOST is not set @@ -4599,6 +4627,8 @@ CONFIG_UWB_HWA=m CONFIG_UWB_I1480U=m CONFIG_MMC=y # CONFIG_MMC_DEBUG is not set +CONFIG_PWRSEQ_EMMC=y +CONFIG_PWRSEQ_SIMPLE=y # # MMC/SD/SDIO Card Drivers @@ -4689,6 +4719,7 @@ CONFIG_LEDS_IS31FL32XX=m CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_TIMER=y CONFIG_LEDS_TRIGGER_ONESHOT=y +# CONFIG_LEDS_TRIGGER_MTD is not set CONFIG_LEDS_TRIGGER_HEARTBEAT=y CONFIG_LEDS_TRIGGER_BACKLIGHT=y CONFIG_LEDS_TRIGGER_CPU=y @@ -4700,6 +4731,7 @@ CONFIG_LEDS_TRIGGER_DEFAULT_ON=y # CONFIG_LEDS_TRIGGER_TRANSIENT=m CONFIG_LEDS_TRIGGER_CAMERA=m +# CONFIG_LEDS_TRIGGER_PANIC is not set CONFIG_ACCESSIBILITY=y CONFIG_A11Y_BRAILLE_CONSOLE=y CONFIG_EDAC_ATOMIC_SCRUB=y @@ -4756,8 +4788,6 @@ CONFIG_RTC_DRV_RX8010=m CONFIG_RTC_DRV_RX8581=m CONFIG_RTC_DRV_RX8025=m CONFIG_RTC_DRV_EM3027=m -CONFIG_RTC_DRV_RV3029C2=m -CONFIG_RTC_DRV_RV3029_HWMON=y CONFIG_RTC_DRV_RV8803=m CONFIG_RTC_DRV_S5M=y @@ -4766,6 +4796,7 @@ CONFIG_RTC_DRV_S5M=y # CONFIG_RTC_DRV_M41T93=m CONFIG_RTC_DRV_M41T94=m +CONFIG_RTC_DRV_DS1302=m CONFIG_RTC_DRV_DS1305=m CONFIG_RTC_DRV_DS1343=m CONFIG_RTC_DRV_DS1347=m @@ -4784,6 +4815,8 @@ CONFIG_RTC_I2C_AND_SPI=y # CONFIG_RTC_DRV_DS3232=m CONFIG_RTC_DRV_PCF2127=m +CONFIG_RTC_DRV_RV3029C2=m +CONFIG_RTC_DRV_RV3029_HWMON=y # # Platform RTC drivers @@ -4805,7 +4838,6 @@ CONFIG_RTC_DRV_DS2404=m CONFIG_RTC_DRV_DA9052=y CONFIG_RTC_DRV_DA9055=m CONFIG_RTC_DRV_DA9063=m -CONFIG_RTC_DRV_EFI=y CONFIG_RTC_DRV_STK17TA8=m CONFIG_RTC_DRV_M48T86=m CONFIG_RTC_DRV_M48T35=m @@ -4853,6 +4885,11 @@ CONFIG_DW_DMAC=y # CONFIG_ASYNC_TX_DMA=y # CONFIG_DMATEST is not set + +# +# DMABUF options +# +CONFIG_SYNC_FILE=y # CONFIG_AUXDISPLAY is not set CONFIG_UIO=m CONFIG_UIO_PDRV_GENIRQ=m @@ -4895,9 +4932,7 @@ CONFIG_88EU_AP_MODE=y # CONFIG_ADIS16201=m CONFIG_ADIS16203=m -CONFIG_ADIS16204=m CONFIG_ADIS16209=m -CONFIG_ADIS16220=m CONFIG_ADIS16240=m CONFIG_LIS3L02DQ=m CONFIG_SCA3000=m @@ -4994,8 +5029,6 @@ CONFIG_SPEAKUP_SYNTH_DUMMY=m # Android # CONFIG_ASHMEM=y -CONFIG_ANDROID_TIMED_OUTPUT=y -CONFIG_ANDROID_TIMED_GPIO=m # CONFIG_ANDROID_LOW_MEMORY_KILLER is not set CONFIG_SYNC=y # CONFIG_SW_SYNC is not set @@ -5067,6 +5100,8 @@ CONFIG_CLK_TWL6040=y CONFIG_COMMON_CLK_PALMAS=y # CONFIG_COMMON_CLK_PWM is not set # CONFIG_COMMON_CLK_PXA is not set +# CONFIG_COMMON_CLK_PIC32 is not set +# CONFIG_COMMON_CLK_OXNAS is not set CONFIG_COMMON_CLK_TI_ADPLL=y CONFIG_HWSPINLOCK=y @@ -5137,6 +5172,7 @@ CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y CONFIG_DEVFREQ_GOV_PERFORMANCE=y CONFIG_DEVFREQ_GOV_POWERSAVE=y CONFIG_DEVFREQ_GOV_USERSPACE=y +# CONFIG_DEVFREQ_GOV_PASSIVE is not set # # DEVFREQ Drivers @@ -5149,6 +5185,9 @@ CONFIG_EXTCON=y # # CONFIG_EXTCON_ADC_JACK is not set # CONFIG_EXTCON_AXP288 is not set +CONFIG_EXTCON_DT_CON=y +CONFIG_EXTCON_DT_CON_PROXY=y +CONFIG_EXTCON_DT_CON_GPIO=y CONFIG_EXTCON_GPIO=y # CONFIG_EXTCON_MAX3355 is not set CONFIG_EXTCON_PALMAS=y @@ -5266,6 +5305,9 @@ CONFIG_AD5380=m CONFIG_AD5421=m CONFIG_AD5446=m CONFIG_AD5449=m +CONFIG_AD5592R_BASE=m +CONFIG_AD5592R=m +CONFIG_AD5593R=m CONFIG_AD5504=m CONFIG_AD5624R_SPI=m CONFIG_AD5686=m @@ -5331,6 +5373,7 @@ CONFIG_MAX30100=m # # Humidity sensors # +CONFIG_AM2315=m CONFIG_DHT11=m CONFIG_HDC100X=m CONFIG_HTU21=m @@ -5342,6 +5385,9 @@ CONFIG_SI7020=m # CONFIG_ADIS16400=m CONFIG_ADIS16480=m +CONFIG_BMI160=m +CONFIG_BMI160_I2C=m +CONFIG_BMI160_SPI=m CONFIG_KMX61=m CONFIG_INV_MPU6050_IIO=m CONFIG_INV_MPU6050_I2C=m @@ -5357,6 +5403,7 @@ CONFIG_AL3320A=m CONFIG_APDS9300=m CONFIG_APDS9960=m CONFIG_BH1750=m +CONFIG_BH1780=m CONFIG_CM32181=m CONFIG_CM3232=m CONFIG_CM3323=m @@ -5368,6 +5415,7 @@ CONFIG_HID_SENSOR_PROX=m CONFIG_JSA1212=m CONFIG_RPR0521=m CONFIG_LTR501=m +CONFIG_MAX44000=m CONFIG_OPT3001=m CONFIG_PA12203001=m CONFIG_STK3310=m @@ -5377,6 +5425,7 @@ CONFIG_SENSORS_TSL2563=m CONFIG_TSL4531=m CONFIG_US5182D=m CONFIG_VCNL4000=m +CONFIG_VEML6070=m # # Magnetometer sensors @@ -5384,6 +5433,8 @@ CONFIG_VCNL4000=m CONFIG_AK8975=m CONFIG_AK09911=m CONFIG_BMC150_MAGN=m +CONFIG_BMC150_MAGN_I2C=m +CONFIG_BMC150_MAGN_SPI=m CONFIG_MAG3110=m CONFIG_HID_SENSOR_MAGNETOMETER_3D=m CONFIG_MMC35240=m @@ -5409,6 +5460,8 @@ CONFIG_IIO_SYSFS_TRIGGER=m # # Digital potentiometers # +CONFIG_DS1803=m +CONFIG_MCP4131=m CONFIG_MCP4531=m CONFIG_TPL0102=m @@ -5417,6 +5470,7 @@ CONFIG_TPL0102=m # CONFIG_BMP280=m CONFIG_HID_SENSOR_PRESS=m +CONFIG_HP03=m CONFIG_MPL115=m CONFIG_MPL115_I2C=m CONFIG_MPL115_SPI=m @@ -5429,6 +5483,7 @@ CONFIG_IIO_ST_PRESS=m CONFIG_IIO_ST_PRESS_I2C=m CONFIG_IIO_ST_PRESS_SPI=m CONFIG_T5403=m +CONFIG_HP206C=m # # Lightning sensors @@ -5512,15 +5567,6 @@ CONFIG_ARM_PSCI_FW=y # CONFIG_FW_CFG_SYSFS is not set CONFIG_HAVE_ARM_SMCCC=y -# -# EFI (Extensible Firmware Interface) Support -# -CONFIG_EFI_VARS=m -CONFIG_EFI_ESRT=y -CONFIG_EFI_PARAMS_FROM_FDT=y -CONFIG_EFI_RUNTIME_WRAPPERS=y -CONFIG_EFI_ARMSTUB=y - # # File systems # @@ -5577,6 +5623,7 @@ CONFIG_F2FS_FS_SECURITY=y # CONFIG_F2FS_CHECK_FS is not set CONFIG_F2FS_FS_ENCRYPTION=y # CONFIG_F2FS_IO_TRACE is not set +# CONFIG_F2FS_FAULT_INJECTION is not set CONFIG_FS_POSIX_ACL=y CONFIG_EXPORTFS=y CONFIG_FILE_LOCKING=y @@ -5648,7 +5695,6 @@ CONFIG_TMPFS_POSIX_ACL=y CONFIG_TMPFS_XATTR=y # CONFIG_HUGETLB_PAGE is not set CONFIG_CONFIGFS_FS=y -CONFIG_EFIVAR_FS=m CONFIG_MISC_FILESYSTEMS=y CONFIG_ORANGEFS_FS=y CONFIG_ADFS_FS=m @@ -5951,6 +5997,7 @@ CONFIG_DEBUG_LIST=y # CONFIG_PROVE_RCU is not set # CONFIG_SPARSE_RCU_POINTER is not set # CONFIG_TORTURE_TEST is not set +# CONFIG_RCU_PERF_TEST is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_RCU_TRACE is not set # CONFIG_RCU_EQS_DEBUG is not set @@ -6021,6 +6068,7 @@ CONFIG_TRACING_EVENTS_GPIO=y # CONFIG_TEST_PRINTF is not set # CONFIG_TEST_BITMAP is not set # CONFIG_TEST_RHASHTABLE is not set +# CONFIG_TEST_HASH is not set # CONFIG_DMA_API_DEBUG is not set # CONFIG_TEST_LKM is not set CONFIG_TEST_USER_COPY=m @@ -6061,6 +6109,7 @@ CONFIG_KEYS=y # CONFIG_BIG_KEYS is not set # CONFIG_TRUSTED_KEYS is not set CONFIG_ENCRYPTED_KEYS=y +# CONFIG_KEY_DH_OPERATIONS is not set # CONFIG_SECURITY_DMESG_RESTRICT is not set CONFIG_SECURITY=y CONFIG_SECURITYFS=y @@ -6085,6 +6134,7 @@ CONFIG_SECURITY_TOMOYO_ACTIVATION_TRIGGER="/sbin/init" CONFIG_SECURITY_APPARMOR=y CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE=1 CONFIG_SECURITY_APPARMOR_HASH=y +# CONFIG_SECURITY_LOADPIN is not set CONFIG_SECURITY_YAMA=y CONFIG_INTEGRITY=y # CONFIG_INTEGRITY_SIGNATURE is not set @@ -6242,8 +6292,6 @@ 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 @@ -6337,11 +6385,11 @@ CONFIG_IRQ_POLL=y CONFIG_MPILIB=y CONFIG_LIBFDT=y CONFIG_OID_REGISTRY=y -CONFIG_UCS2_STRING=y CONFIG_FONT_SUPPORT=y # CONFIG_FONTS is not set CONFIG_FONT_8x8=y CONFIG_FONT_8x16=y # CONFIG_SG_SPLIT is not set +CONFIG_SG_POOL=y CONFIG_ARCH_HAS_SG_CHAIN=y CONFIG_VIRTUALIZATION=y diff --git a/patches/ref_omap2plus_defconfig b/patches/ref_omap2plus_defconfig index bfd3b073a8f34e72043628a23e247b068c5f1244..2917bc826ad5b3d0d62e16d0f358a8e12c290bf3 100644 --- a/patches/ref_omap2plus_defconfig +++ b/patches/ref_omap2plus_defconfig @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/arm 4.6.0 Kernel Configuration +# Linux/arm 4.7.0-rc1 Kernel Configuration # CONFIG_ARM=y CONFIG_ARM_HAS_SG_CHAIN=y @@ -116,6 +116,7 @@ CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=16 CONFIG_LOG_CPU_MAX_BUF_SHIFT=12 +CONFIG_NMI_LOG_BUF_SHIFT=13 CONFIG_GENERIC_SCHED_CLOCK=y CONFIG_CGROUPS=y CONFIG_PAGE_COUNTER=y @@ -155,6 +156,7 @@ CONFIG_RD_LZMA=y CONFIG_RD_XZ=y CONFIG_RD_LZO=y CONFIG_RD_LZ4=y +CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -171,6 +173,7 @@ CONFIG_KALLSYMS_ALL=y # CONFIG_KALLSYMS_ABSOLUTE_PERCPU is not set CONFIG_KALLSYMS_BASE_RELATIVE=y CONFIG_PRINTK=y +CONFIG_PRINTK_NMI=y CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y @@ -199,6 +202,7 @@ CONFIG_COMPAT_BRK=y CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set +# CONFIG_SLAB_FREELIST_RANDOM is not set # CONFIG_SYSTEM_DATA_VERIFICATION is not set CONFIG_PROFILING=y CONFIG_TRACEPOINTS=y @@ -216,6 +220,7 @@ 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 @@ -242,12 +247,15 @@ 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_MIN=8 CONFIG_ARCH_MMAP_RND_BITS_MAX=16 CONFIG_ARCH_MMAP_RND_BITS=8 +# CONFIG_HAVE_ARCH_HASH is not set CONFIG_CLONE_BACKWARDS=y CONFIG_OLD_SIGSUSPEND3=y CONFIG_OLD_SIGACTION=y +# CONFIG_CPU_NO_EFFICIENT_FFS is not set # # GCOV-based kernel profiling @@ -266,6 +274,7 @@ CONFIG_MODVERSIONS=y CONFIG_MODULE_SRCVERSION_ALL=y # 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 @@ -367,6 +376,7 @@ CONFIG_ARCH_MULTI_V6_V7=y # CONFIG_ARCH_INTEGRATOR is not set # CONFIG_ARCH_KEYSTONE is not set # CONFIG_ARCH_MESON is not set +# CONFIG_ARCH_ASPEED is not set # CONFIG_ARCH_MXC is not set # CONFIG_ARCH_MEDIATEK is not set CONFIG_ARCH_OMAP=y @@ -550,12 +560,9 @@ CONFIG_NR_CPUS=2 CONFIG_HOTPLUG_CPU=y # CONFIG_ARM_PSCI is not set CONFIG_ARCH_NR_GPIO=512 -CONFIG_HAVE_PREEMPT_LAZY=y CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT__LL is not set -# CONFIG_PREEMPT_RTB is not set -# CONFIG_PREEMPT_RT_FULL is not set +# CONFIG_PREEMPT is not set CONFIG_HZ_FIXED=0 CONFIG_HZ_100=y # CONFIG_HZ_200 is not set @@ -588,7 +595,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_COMPACTION=y CONFIG_MIGRATION=y # CONFIG_PHYS_ADDR_T_64BIT is not set -CONFIG_ZONE_DMA_FLAG=0 CONFIG_BOUNCE=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -643,6 +649,7 @@ CONFIG_AUTO_ZRELADDR=y # 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_STAT_DETAILS=y @@ -651,19 +658,23 @@ CONFIG_CPU_FREQ_STAT_DETAILS=y # 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=y CONFIG_CPU_FREQ_GOV_ONDEMAND=y CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +# CONFIG_CPU_FREQ_GOV_SCHEDUTIL is not set # # CPU frequency scaling drivers # CONFIG_CPUFREQ_DT=m +CONFIG_CPUFREQ_DT_PLATDEV=y # CONFIG_ARM_BIG_LITTLE_CPUFREQ is not set # CONFIG_ARM_KIRKWOOD_CPUFREQ is not set # CONFIG_ARM_OMAP2PLUS_CPUFREQ is not set +# CONFIG_ARM_TI_CPUFREQ is not set # CONFIG_QORIQ_CPUFREQ is not set # @@ -695,6 +706,7 @@ CONFIG_NEON=y # Userspace binary formats # CONFIG_BINFMT_ELF=y +CONFIG_ELFCORE=y CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y CONFIG_BINFMT_SCRIPT=y # CONFIG_HAVE_AOUT is not set @@ -794,7 +806,6 @@ CONFIG_IPV6_SIT=y # CONFIG_IPV6_SIT_6RD is not set CONFIG_IPV6_NDISC_NODETYPE=y # CONFIG_IPV6_TUNNEL is not set -# CONFIG_IPV6_GRE is not set # CONFIG_IPV6_MULTIPLE_TABLES is not set # CONFIG_IPV6_MROUTE is not set # CONFIG_NETLABEL is not set @@ -968,7 +979,7 @@ CONFIG_BT_MRVL_SDIO=m # CONFIG_BT_ATH3K is not set CONFIG_AF_RXRPC=m # CONFIG_AF_RXRPC_DEBUG is not set -CONFIG_RXKAD=m +CONFIG_RXKAD=y # CONFIG_AF_KCM is not set CONFIG_WIRELESS=y CONFIG_WIRELESS_EXT=y @@ -1010,7 +1021,7 @@ CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 CONFIG_DST_CACHE=y # CONFIG_NET_DEVLINK is not set CONFIG_MAY_USE_DEVLINK=y -CONFIG_HAVE_BPF_JIT=y +CONFIG_HAVE_CBPF_JIT=y # # Device Drivers @@ -1122,6 +1133,7 @@ CONFIG_MTD_CFI_UTIL=y CONFIG_MTD_PHYSMAP=y # CONFIG_MTD_PHYSMAP_COMPAT is not set CONFIG_MTD_PHYSMAP_OF=y +# CONFIG_MTD_PHYSMAP_OF_VERSATILE is not set # CONFIG_MTD_PLATRAM is not set # @@ -1214,7 +1226,6 @@ CONFIG_BLK_DEV_RAM_SIZE=16384 CONFIG_SENSORS_LIS3LV02D=m # CONFIG_AD525X_DPOT is not set # CONFIG_DUMMY_IRQ is not set -CONFIG_HWLAT_DETECTOR=m # CONFIG_ICS932S401 is not set # CONFIG_ENCLOSURE_SERVICES is not set # CONFIG_APDS9802ALS is not set @@ -1363,6 +1374,7 @@ CONFIG_ATA_BMDMA=y # # SATA SFF controllers with BMDMA # +# CONFIG_SATA_DWC is not set # # PATA SFF controllers with BMDMA @@ -1404,8 +1416,6 @@ CONFIG_NET_CORE=y # # Distributed Switch Architecture drivers # -# CONFIG_NET_DSA_MV88E6XXX is not set -# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set CONFIG_ETHERNET=y # CONFIG_ALTERA_TSE is not set # CONFIG_NET_VENDOR_ARC is not set @@ -1785,6 +1795,7 @@ CONFIG_DEVKMEM=y CONFIG_SERIAL_EARLYCON=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y +# CONFIG_SERIAL_8250_FINTEK is not set CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_DMA=y CONFIG_SERIAL_8250_NR_UARTS=32 @@ -1819,12 +1830,12 @@ CONFIG_SERIAL_OMAP_CONSOLE=y # CONFIG_SERIAL_ALTERA_UART is not set # CONFIG_SERIAL_IFX6X60 is not set # CONFIG_SERIAL_XILINX_PS_UART is not set +# CONFIG_SERIAL_MPS2_UART is not set # CONFIG_SERIAL_ARC 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_STM32 is not set -# CONFIG_SERIAL_MVEBU_UART is not set # CONFIG_TTY_PRINTK is not set # CONFIG_HVC_DCC is not set # CONFIG_IPMI_HANDLER is not set @@ -1921,7 +1932,6 @@ CONFIG_HSI_BOARDINFO=y # HSI controllers # CONFIG_OMAP_SSI=m -CONFIG_OMAP_SSI_PORT=m # # HSI clients @@ -2151,6 +2161,7 @@ CONFIG_SENSORS_GPIO_FAN=m # 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_MAX6639 is not set # CONFIG_SENSORS_MAX6642 is not set # CONFIG_SENSORS_MAX6650 is not set @@ -2239,6 +2250,10 @@ CONFIG_CPU_THERMAL=y # CONFIG_THERMAL_EMULATION is not set # CONFIG_IMX_THERMAL is not set +# +# ACPI INT340X thermal drivers +# + # # Texas Instruments thermal drivers # @@ -2248,6 +2263,7 @@ CONFIG_TI_THERMAL=y CONFIG_OMAP4_THERMAL=y CONFIG_OMAP5_THERMAL=y CONFIG_DRA752_THERMAL=y +# CONFIG_GENERIC_ADC_THERMAL is not set CONFIG_WATCHDOG=y CONFIG_WATCHDOG_CORE=y # CONFIG_WATCHDOG_NOWAYOUT is not set @@ -2319,6 +2335,7 @@ CONFIG_MFD_CORE=y # 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 @@ -2411,6 +2428,7 @@ CONFIG_REGULATOR_PALMAS=y CONFIG_REGULATOR_PBIAS=y # 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_TI_ABB=y @@ -2433,7 +2451,7 @@ CONFIG_MEDIA_CAMERA_SUPPORT=y # CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set # CONFIG_MEDIA_RADIO_SUPPORT is not set # CONFIG_MEDIA_SDR_SUPPORT is not set -# CONFIG_MEDIA_RC_SUPPORT is not set +CONFIG_MEDIA_RC_SUPPORT=y CONFIG_MEDIA_CONTROLLER=y # CONFIG_MEDIA_CONTROLLER_DVB is not set CONFIG_VIDEO_DEV=m @@ -2449,6 +2467,32 @@ CONFIG_VIDEOBUF2_DMA_CONTIG=m # # Media drivers # +CONFIG_RC_CORE=m +CONFIG_RC_MAP=m +CONFIG_RC_DECODERS=y +CONFIG_LIRC=m +CONFIG_IR_LIRC_CODEC=m +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_RC_DEVICES=y +# CONFIG_RC_ATI_REMOTE is not set +# CONFIG_IR_HIX5HD2 is not set +# CONFIG_IR_IMON is not set +# CONFIG_IR_MCEUSB is not set +# CONFIG_IR_REDRAT3 is not set +# CONFIG_IR_STREAMZAP is not set +# CONFIG_IR_IGORPLUGUSB is not set +# CONFIG_IR_IGUANA is not set +# CONFIG_IR_TTUSBIR is not set +# CONFIG_RC_LOOPBACK is not set +# CONFIG_IR_GPIO_CIR is not set # CONFIG_MEDIA_USB_SUPPORT is not set CONFIG_V4L_PLATFORM_DRIVERS=y # CONFIG_VIDEO_OMAP2_VOUT is not set @@ -2470,6 +2514,7 @@ CONFIG_VIDEO_OMAP3=m # Media ancillary drivers (tuners, sensors, i2c, frontends) # # CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set +CONFIG_VIDEO_IR_I2C=m # # Encoders, decoders, sensors and other helper chips @@ -2615,7 +2660,6 @@ CONFIG_DVB_TUNER_DIB0090=m # # ACP (Audio CoProcessor) Configuration # -# CONFIG_DRM_AMD_ACP is not set # # Frame buffer Devices @@ -2796,6 +2840,7 @@ CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y # CONFIG_SND_SOC_AMD_ACP is not set # CONFIG_SND_ATMEL_SOC is not set CONFIG_SND_EDMA_SOC=m +# CONFIG_SND_DAVINCI_SOC_I2S is not set CONFIG_SND_DAVINCI_SOC_MCASP=m CONFIG_SND_DAVINCI_SOC_GENERIC_EVM=m CONFIG_SND_AM33XX_SOC_EVM=m @@ -2883,6 +2928,7 @@ CONFIG_SND_SOC_DMIC=m # 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_TFA9879 is not set # CONFIG_SND_SOC_TLV320AIC23_I2C is not set # CONFIG_SND_SOC_TLV320AIC23_SPI is not set @@ -2906,6 +2952,7 @@ CONFIG_SND_SOC_TWL6040=m # CONFIG_SND_SOC_WM8804_I2C is not set # 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 @@ -3213,7 +3260,7 @@ CONFIG_USB_PHY=y CONFIG_NOP_USB_XCEIV=y CONFIG_AM335X_CONTROL_USB=y CONFIG_AM335X_PHY_USB=y -# CONFIG_TWL6030_USB is not set +CONFIG_TWL6030_USB=m # CONFIG_USB_GPIO_VBUS is not set # CONFIG_USB_ISP1301 is not set # CONFIG_USB_ULPI is not set @@ -3299,6 +3346,8 @@ CONFIG_USB_G_NOKIA=m # CONFIG_UWB is not set CONFIG_MMC=y # CONFIG_MMC_DEBUG is not set +CONFIG_PWRSEQ_EMMC=y +CONFIG_PWRSEQ_SIMPLE=y # # MMC/SD/SDIO Card Drivers @@ -3363,6 +3412,7 @@ CONFIG_LEDS_PWM=m CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_TIMER=m CONFIG_LEDS_TRIGGER_ONESHOT=m +# CONFIG_LEDS_TRIGGER_MTD is not set CONFIG_LEDS_TRIGGER_HEARTBEAT=m CONFIG_LEDS_TRIGGER_BACKLIGHT=m CONFIG_LEDS_TRIGGER_CPU=y @@ -3374,6 +3424,7 @@ CONFIG_LEDS_TRIGGER_DEFAULT_ON=m # # CONFIG_LEDS_TRIGGER_TRANSIENT is not set # CONFIG_LEDS_TRIGGER_CAMERA is not set +# CONFIG_LEDS_TRIGGER_PANIC is not set # CONFIG_ACCESSIBILITY is not set CONFIG_EDAC_ATOMIC_SCRUB=y CONFIG_EDAC_SUPPORT=y @@ -3427,7 +3478,6 @@ CONFIG_RTC_DRV_PALMAS=m # CONFIG_RTC_DRV_RX8581 is not set # CONFIG_RTC_DRV_RX8025 is not set # CONFIG_RTC_DRV_EM3027 is not set -# CONFIG_RTC_DRV_RV3029C2 is not set # CONFIG_RTC_DRV_RV8803 is not set # @@ -3435,6 +3485,7 @@ CONFIG_RTC_DRV_PALMAS=m # # 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 @@ -3453,6 +3504,7 @@ CONFIG_RTC_I2C_AND_SPI=y # # CONFIG_RTC_DRV_DS3232 is not set # CONFIG_RTC_DRV_PCF2127 is not set +# CONFIG_RTC_DRV_RV3029C2 is not set # # Platform RTC drivers @@ -3509,6 +3561,11 @@ CONFIG_TI_EDMA=y # # CONFIG_ASYNC_TX_DMA is not set # CONFIG_DMATEST is not set + +# +# DMABUF options +# +# CONFIG_SYNC_FILE is not set # CONFIG_AUXDISPLAY is not set # CONFIG_UIO is not set # CONFIG_VFIO is not set @@ -3544,6 +3601,8 @@ CONFIG_COMMON_CLK=y CONFIG_COMMON_CLK_PALMAS=m # CONFIG_COMMON_CLK_PWM is not set # CONFIG_COMMON_CLK_PXA is not set +# CONFIG_COMMON_CLK_PIC32 is not set +# CONFIG_COMMON_CLK_OXNAS is not set CONFIG_COMMON_CLK_TI_ADPLL=y # @@ -3604,6 +3663,8 @@ CONFIG_EXTCON=m # Extcon Device Drivers # # CONFIG_EXTCON_ADC_JACK is not set +# CONFIG_EXTCON_DT_CON_PROXY is not set +# CONFIG_EXTCON_DT_CON_GPIO is not set # CONFIG_EXTCON_GPIO is not set # CONFIG_EXTCON_MAX3355 is not set CONFIG_EXTCON_PALMAS=m @@ -3700,6 +3761,8 @@ CONFIG_TI_AM335X_ADC=m # CONFIG_AD5421 is not set # CONFIG_AD5446 is not set # CONFIG_AD5449 is not set +# CONFIG_AD5592R is not set +# CONFIG_AD5593R is not set # CONFIG_AD5504 is not set # CONFIG_AD5624R_SPI is not set # CONFIG_AD5686 is not set @@ -3760,6 +3823,7 @@ CONFIG_TI_AM335X_ADC=m # # Humidity sensors # +# CONFIG_AM2315 is not set # CONFIG_DHT11 is not set # CONFIG_HDC100X is not set # CONFIG_HTU21 is not set @@ -3771,6 +3835,8 @@ CONFIG_TI_AM335X_ADC=m # # CONFIG_ADIS16400 is not set # CONFIG_ADIS16480 is not set +# CONFIG_BMI160_I2C is not set +# CONFIG_BMI160_SPI is not set # CONFIG_KMX61 is not set # CONFIG_INV_MPU6050_SPI is not set @@ -3782,6 +3848,7 @@ CONFIG_TI_AM335X_ADC=m # CONFIG_APDS9300 is not set # CONFIG_APDS9960 is not set # CONFIG_BH1750 is not set +# CONFIG_BH1780 is not set # CONFIG_CM32181 is not set # CONFIG_CM3232 is not set # CONFIG_CM3323 is not set @@ -3791,6 +3858,7 @@ CONFIG_TI_AM335X_ADC=m # CONFIG_JSA1212 is not set # CONFIG_RPR0521 is not set # CONFIG_LTR501 is not set +# CONFIG_MAX44000 is not set # CONFIG_OPT3001 is not set # CONFIG_PA12203001 is not set # CONFIG_STK3310 is not set @@ -3800,13 +3868,15 @@ CONFIG_TI_AM335X_ADC=m # CONFIG_TSL4531 is not set # CONFIG_US5182D is not set # CONFIG_VCNL4000 is not set +# CONFIG_VEML6070 is not set # # Magnetometer sensors # # CONFIG_AK8975 is not set # CONFIG_AK09911 is not set -# CONFIG_BMC150_MAGN is not set +# CONFIG_BMC150_MAGN_I2C is not set +# CONFIG_BMC150_MAGN_SPI is not set # CONFIG_MAG3110 is not set # CONFIG_MMC35240 is not set # CONFIG_IIO_ST_MAGN_3AXIS is not set @@ -3820,13 +3890,15 @@ CONFIG_TI_AM335X_ADC=m # # Digital potentiometers # +# CONFIG_DS1803 is not set +# CONFIG_MCP4131 is not set # CONFIG_MCP4531 is not set # CONFIG_TPL0102 is not set # # Pressure sensors # -# CONFIG_BMP280 is not set +# CONFIG_HP03 is not set # CONFIG_MPL115_I2C is not set # CONFIG_MPL115_SPI is not set # CONFIG_MPL3115 is not set @@ -3834,6 +3906,7 @@ CONFIG_TI_AM335X_ADC=m # CONFIG_MS5637 is not set # CONFIG_IIO_ST_PRESS is not set # CONFIG_T5403 is not set +# CONFIG_HP206C is not set # # Lightning sensors @@ -3856,7 +3929,7 @@ CONFIG_TI_AM335X_ADC=m CONFIG_PWM=y CONFIG_PWM_SYSFS=y # CONFIG_PWM_FSL_FTM is not set -# CONFIG_PWM_OMAP_DMTIMER is not set +CONFIG_PWM_OMAP_DMTIMER=m # CONFIG_PWM_PCA9685 is not set CONFIG_PWM_TIECAP=m CONFIG_PWM_TIEHRPWM=m @@ -4221,6 +4294,7 @@ CONFIG_PROVE_RCU=y # CONFIG_PROVE_RCU_REPEATEDLY is not set # CONFIG_SPARSE_RCU_POINTER is not set # CONFIG_TORTURE_TEST is not set +# 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 @@ -4249,7 +4323,6 @@ CONFIG_FTRACE=y # CONFIG_FUNCTION_TRACER is not set # CONFIG_IRQSOFF_TRACER is not set # CONFIG_SCHED_TRACER is not set -# CONFIG_MISSED_TIMER_OFFSETS_HIST is not set # CONFIG_ENABLE_DEFAULT_TRACERS is not set # CONFIG_FTRACE_SYSCALLS is not set # CONFIG_TRACER_SNAPSHOT is not set @@ -4284,6 +4357,7 @@ CONFIG_TRACING_EVENTS_GPIO=y # CONFIG_TEST_PRINTF is not set # CONFIG_TEST_BITMAP is not set # CONFIG_TEST_RHASHTABLE is not set +# CONFIG_TEST_HASH is not set # CONFIG_DMA_API_DEBUG is not set # CONFIG_TEST_LKM is not set # CONFIG_TEST_USER_COPY is not set @@ -4317,6 +4391,7 @@ 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=y # CONFIG_SECURITYFS is not set @@ -4325,6 +4400,7 @@ CONFIG_SECURITY=y # CONFIG_SECURITY_SMACK is not set # CONFIG_SECURITY_TOMOYO is not set # CONFIG_SECURITY_APPARMOR is not set +# CONFIG_SECURITY_LOADPIN is not set # CONFIG_SECURITY_YAMA is not set CONFIG_INTEGRITY=y # CONFIG_INTEGRITY_SIGNATURE is not set @@ -4467,7 +4543,6 @@ CONFIG_CRYPTO_HW=y # # Certificates for signature checking # -# CONFIG_SYSTEM_TRUSTED_KEYRING is not set # CONFIG_ARM_CRYPTO is not set CONFIG_BINARY_PRINTF=y @@ -4551,5 +4626,6 @@ CONFIG_FONT_8x16=y # CONFIG_FONT_SUN12x22 is not set # CONFIG_FONT_10x18 is not set # CONFIG_SG_SPLIT is not set +CONFIG_SG_POOL=y CONFIG_ARCH_HAS_SG_CHAIN=y # CONFIG_VIRTUALIZATION is not set diff --git a/patches/rt/0001-merge-CONFIG_PREEMPT_RT-Patch-Set.patch b/patches/rt/0001-merge-CONFIG_PREEMPT_RT-Patch-Set.patch deleted file mode 100644 index 507c3d4447cf742f85239a59522ec7363c184fdf..0000000000000000000000000000000000000000 --- a/patches/rt/0001-merge-CONFIG_PREEMPT_RT-Patch-Set.patch +++ /dev/null @@ -1,25007 +0,0 @@ -From 2bc4f88abeeeb5ccdb414847ea84d3937746fa08 Mon Sep 17 00:00:00 2001 -From: Robert Nelson <robertcnelson@gmail.com> -Date: Sun, 15 May 2016 22:11:27 -0500 -Subject: [PATCH] merge: CONFIG_PREEMPT_RT Patch Set - -Signed-off-by: Robert Nelson <robertcnelson@gmail.com> ---- - Documentation/hwlat_detector.txt | 64 + - Documentation/sysrq.txt | 11 +- - Documentation/trace/histograms.txt | 186 +++ - arch/Kconfig | 2 + - arch/arm/Kconfig | 3 +- - arch/arm/include/asm/switch_to.h | 8 + - arch/arm/include/asm/thread_info.h | 8 +- - arch/arm/kernel/asm-offsets.c | 1 + - arch/arm/kernel/entry-armv.S | 13 +- - arch/arm/kernel/entry-common.S | 9 +- - arch/arm/kernel/process.c | 24 + - arch/arm/kernel/signal.c | 3 +- - arch/arm/kernel/smp.c | 5 +- - arch/arm/kernel/unwind.c | 14 +- - arch/arm/kvm/arm.c | 6 +- - arch/arm/mach-exynos/platsmp.c | 12 +- - arch/arm/mach-hisi/platmcpm.c | 22 +- - arch/arm/mach-imx/Kconfig | 2 +- - arch/arm/mach-omap2/omap-smp.c | 10 +- - arch/arm/mach-prima2/platsmp.c | 10 +- - arch/arm/mach-qcom/platsmp.c | 10 +- - arch/arm/mach-spear/platsmp.c | 10 +- - arch/arm/mach-sti/platsmp.c | 10 +- - arch/arm/mm/fault.c | 6 + - arch/arm/mm/highmem.c | 58 +- - arch/arm/plat-versatile/platsmp.c | 10 +- - arch/arm64/Kconfig | 3 +- - arch/arm64/include/asm/thread_info.h | 6 +- - arch/arm64/kernel/asm-offsets.c | 1 + - arch/arm64/kernel/entry.S | 13 +- - arch/mips/Kconfig | 2 +- - arch/powerpc/Kconfig | 6 +- - arch/powerpc/include/asm/thread_info.h | 11 +- - arch/powerpc/kernel/asm-offsets.c | 1 + - arch/powerpc/kernel/entry_32.S | 17 +- - arch/powerpc/kernel/entry_64.S | 14 +- - arch/powerpc/kernel/irq.c | 2 + - arch/powerpc/kernel/misc_32.S | 2 + - arch/powerpc/kernel/misc_64.S | 2 + - arch/powerpc/kvm/Kconfig | 1 + - arch/powerpc/platforms/ps3/device-init.c | 2 +- - arch/sh/kernel/irq.c | 2 + - arch/sparc/Kconfig | 6 +- - arch/sparc/kernel/irq_64.c | 2 + - arch/x86/Kconfig | 8 +- - arch/x86/crypto/aesni-intel_glue.c | 24 +- - arch/x86/crypto/cast5_avx_glue.c | 21 +- - arch/x86/crypto/glue_helper.c | 31 +- - arch/x86/entry/common.c | 11 +- - arch/x86/entry/entry_32.S | 16 + - arch/x86/entry/entry_64.S | 18 + - arch/x86/include/asm/preempt.h | 18 +- - arch/x86/include/asm/signal.h | 13 + - arch/x86/include/asm/stackprotector.h | 9 +- - arch/x86/include/asm/thread_info.h | 6 + - arch/x86/include/asm/uv/uv_bau.h | 14 +- - arch/x86/include/asm/uv/uv_hub.h | 2 +- - arch/x86/kernel/apic/io_apic.c | 3 +- - arch/x86/kernel/apic/x2apic_uv_x.c | 2 +- - arch/x86/kernel/asm-offsets.c | 2 + - arch/x86/kernel/cpu/mcheck/mce.c | 120 +- - arch/x86/kernel/dumpstack_32.c | 4 +- - arch/x86/kernel/dumpstack_64.c | 8 +- - arch/x86/kernel/irq_32.c | 2 + - arch/x86/kernel/process_32.c | 32 + - arch/x86/kvm/lapic.c | 1 + - arch/x86/kvm/x86.c | 7 + - arch/x86/mm/highmem_32.c | 13 +- - arch/x86/mm/iomap_32.c | 11 +- - arch/x86/platform/uv/tlb_uv.c | 26 +- - arch/x86/platform/uv/uv_time.c | 21 +- - block/blk-core.c | 23 +- - block/blk-ioc.c | 5 +- - block/blk-mq-cpu.c | 17 +- - block/blk-mq.c | 38 +- - block/blk-mq.h | 4 +- - block/blk-softirq.c | 3 + - block/bounce.c | 4 +- - crypto/algapi.c | 4 +- - crypto/api.c | 6 +- - crypto/internal.h | 4 +- - drivers/acpi/acpica/acglobal.h | 2 +- - drivers/acpi/acpica/hwregs.c | 4 +- - drivers/acpi/acpica/hwxface.c | 4 +- - drivers/acpi/acpica/utmutex.c | 4 +- - drivers/ata/libata-sff.c | 12 +- - drivers/block/zram/zram_drv.c | 30 +- - drivers/block/zram/zram_drv.h | 41 + - drivers/char/random.c | 14 +- - drivers/clocksource/tcb_clksrc.c | 69 +- - drivers/clocksource/timer-atmel-pit.c | 23 +- - drivers/clocksource/timer-atmel-st.c | 32 +- - drivers/cpufreq/Kconfig.x86 | 2 +- - drivers/crypto/ccp/ccp-dev.c | 1 - - drivers/gpu/drm/i915/i915_gem_execbuffer.c | 2 + - drivers/gpu/drm/i915/i915_gem_shrinker.c | 2 +- - drivers/gpu/drm/i915/i915_irq.c | 2 + - drivers/gpu/drm/i915/intel_display.c | 2 +- - drivers/gpu/drm/i915/intel_sprite.c | 11 +- - drivers/gpu/drm/radeon/radeon_display.c | 2 + - drivers/i2c/busses/i2c-omap.c | 5 +- - drivers/ide/alim15x3.c | 4 +- - drivers/ide/hpt366.c | 4 +- - drivers/ide/ide-io-std.c | 8 +- - drivers/ide/ide-io.c | 2 +- - drivers/ide/ide-iops.c | 4 +- - drivers/ide/ide-probe.c | 4 +- - drivers/ide/ide-taskfile.c | 6 +- - drivers/infiniband/ulp/ipoib/ipoib_ib.c | 2 - - drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 4 +- - drivers/input/gameport/gameport.c | 12 +- - drivers/iommu/amd_iommu.c | 12 +- - drivers/leds/trigger/Kconfig | 2 +- - drivers/md/bcache/Kconfig | 1 + - drivers/md/dm.c | 2 +- - drivers/md/raid5.c | 7 +- - drivers/md/raid5.h | 1 + - drivers/misc/Kconfig | 42 +- - drivers/misc/Makefile | 1 + - drivers/misc/hwlat_detector.c | 1240 ++++++++++++++++++++ - drivers/mmc/host/mmci.c | 5 - - drivers/net/ethernet/3com/3c59x.c | 8 +- - drivers/net/ethernet/atheros/atl1c/atl1c_main.c | 6 +- - drivers/net/ethernet/atheros/atl1e/atl1e_main.c | 3 +- - drivers/net/ethernet/chelsio/cxgb/sge.c | 3 +- - drivers/net/ethernet/neterion/s2io.c | 7 +- - .../net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c | 6 +- - drivers/net/ethernet/realtek/8139too.c | 2 +- - drivers/net/ethernet/tehuti/tehuti.c | 9 +- - drivers/net/rionet.c | 6 +- - .../net/wireless/intersil/orinoco/orinoco_usb.c | 2 +- - drivers/pci/access.c | 2 +- - drivers/scsi/fcoe/fcoe.c | 18 +- - drivers/scsi/fcoe/fcoe_ctlr.c | 4 +- - drivers/scsi/libfc/fc_exch.c | 4 +- - drivers/scsi/libsas/sas_ata.c | 4 +- - drivers/scsi/qla2xxx/qla_inline.h | 4 +- - drivers/thermal/x86_pkg_temp_thermal.c | 50 +- - drivers/tty/serial/8250/8250_core.c | 11 +- - drivers/tty/serial/8250/8250_port.c | 5 +- - drivers/tty/serial/amba-pl011.c | 15 +- - drivers/tty/serial/omap-serial.c | 12 +- - drivers/tty/serial/sc16is7xx.c | 2 +- - drivers/usb/core/hcd.c | 4 +- - drivers/usb/gadget/function/f_fs.c | 2 +- - drivers/usb/gadget/legacy/inode.c | 4 +- - fs/aio.c | 24 +- - fs/autofs4/autofs_i.h | 1 + - fs/autofs4/expire.c | 2 +- - fs/buffer.c | 21 +- - fs/dcache.c | 5 +- - fs/eventpoll.c | 4 +- - fs/exec.c | 2 + - fs/jbd2/checkpoint.c | 2 + - fs/namespace.c | 8 +- - fs/ntfs/aops.c | 18 +- - fs/timerfd.c | 5 +- - include/acpi/platform/aclinux.h | 15 + - include/asm-generic/bug.h | 14 + - include/linux/blk-mq.h | 1 + - include/linux/blkdev.h | 3 +- - include/linux/bottom_half.h | 34 + - include/linux/buffer_head.h | 42 + - include/linux/cgroup-defs.h | 2 + - include/linux/completion.h | 9 +- - include/linux/cpu.h | 4 + - include/linux/delay.h | 6 + - include/linux/highmem.h | 32 +- - include/linux/hrtimer.h | 27 +- - include/linux/idr.h | 4 + - include/linux/init_task.h | 7 + - include/linux/interrupt.h | 66 +- - include/linux/irq.h | 4 +- - include/linux/irq_work.h | 7 + - include/linux/irqdesc.h | 1 + - include/linux/irqflags.h | 29 +- - include/linux/jbd2.h | 24 + - include/linux/kdb.h | 2 + - include/linux/kernel.h | 5 + - include/linux/lglock.h | 24 + - include/linux/list_bl.h | 30 +- - include/linux/locallock.h | 272 +++++ - include/linux/mm_types.h | 4 + - include/linux/mutex.h | 20 +- - include/linux/mutex_rt.h | 84 ++ - include/linux/netdevice.h | 10 + - include/linux/netfilter/x_tables.h | 7 + - include/linux/notifier.h | 34 +- - include/linux/percpu.h | 29 + - include/linux/pid.h | 1 + - include/linux/preempt.h | 78 +- - include/linux/printk.h | 2 + - include/linux/radix-tree.h | 7 +- - include/linux/random.h | 2 +- - include/linux/rbtree.h | 11 +- - include/linux/rcupdate.h | 26 + - include/linux/rcutree.h | 18 +- - include/linux/rtmutex.h | 30 +- - include/linux/rwlock_rt.h | 99 ++ - include/linux/rwlock_types.h | 4 + - include/linux/rwlock_types_rt.h | 33 + - include/linux/rwsem.h | 6 + - include/linux/rwsem_rt.h | 152 +++ - include/linux/sched.h | 203 +++- - include/linux/seqlock.h | 56 +- - include/linux/signal.h | 1 + - include/linux/skbuff.h | 7 + - include/linux/smp.h | 3 + - include/linux/spinlock.h | 12 +- - include/linux/spinlock_api_smp.h | 4 +- - include/linux/spinlock_rt.h | 163 +++ - include/linux/spinlock_types.h | 79 +- - include/linux/spinlock_types_nort.h | 33 + - include/linux/spinlock_types_raw.h | 56 + - include/linux/spinlock_types_rt.h | 48 + - include/linux/srcu.h | 6 +- - include/linux/suspend.h | 6 + - include/linux/swait.h | 1 + - include/linux/swap.h | 5 +- - include/linux/thread_info.h | 12 +- - include/linux/timer.h | 2 +- - include/linux/trace_events.h | 3 + - include/linux/uaccess.h | 2 + - include/linux/uprobes.h | 1 + - include/linux/vmstat.h | 4 + - include/linux/wait.h | 1 + - include/linux/work-simple.h | 24 + - include/net/dst.h | 2 +- - include/net/neighbour.h | 4 +- - include/net/netns/ipv4.h | 1 + - include/trace/events/hist.h | 73 ++ - include/trace/events/latency_hist.h | 29 + - init/Kconfig | 11 +- - init/Makefile | 2 +- - init/main.c | 1 + - ipc/msg.c | 101 +- - ipc/sem.c | 10 + - kernel/Kconfig.locks | 4 +- - kernel/Kconfig.preempt | 33 +- - kernel/cgroup.c | 9 +- - kernel/cpu.c | 324 ++++- - kernel/debug/kdb/kdb_io.c | 6 +- - kernel/events/core.c | 2 + - kernel/exit.c | 2 +- - kernel/fork.c | 32 +- - kernel/futex.c | 89 +- - kernel/irq/handle.c | 8 +- - kernel/irq/manage.c | 102 +- - kernel/irq/settings.h | 12 + - kernel/irq/spurious.c | 8 + - kernel/irq_work.c | 56 +- - kernel/ksysfs.c | 12 + - kernel/locking/Makefile | 9 +- - kernel/locking/lglock.c | 91 +- - kernel/locking/lockdep.c | 2 + - kernel/locking/locktorture.c | 1 - - kernel/locking/rt.c | 474 ++++++++ - kernel/locking/rtmutex.c | 789 ++++++++++++- - kernel/locking/rtmutex_common.h | 17 +- - kernel/locking/spinlock.c | 7 + - kernel/locking/spinlock_debug.c | 5 + - kernel/panic.c | 2 + - kernel/power/hibernate.c | 14 + - kernel/power/suspend.c | 9 + - kernel/printk/printk.c | 137 ++- - kernel/ptrace.c | 9 +- - kernel/rcu/rcutorture.c | 7 + - kernel/rcu/tree.c | 146 ++- - kernel/rcu/tree.h | 7 +- - kernel/rcu/tree_plugin.h | 161 +-- - kernel/rcu/update.c | 2 + - kernel/relay.c | 14 +- - kernel/sched/Makefile | 2 +- - kernel/sched/completion.c | 32 +- - kernel/sched/core.c | 412 +++++-- - kernel/sched/cpudeadline.c | 4 +- - kernel/sched/cpupri.c | 4 +- - kernel/sched/deadline.c | 31 +- - kernel/sched/debug.c | 7 + - kernel/sched/fair.c | 16 +- - kernel/sched/features.h | 8 + - kernel/sched/rt.c | 26 +- - kernel/sched/sched.h | 10 + - kernel/sched/swait.c | 20 + - kernel/sched/work-simple.c | 173 +++ - kernel/signal.c | 120 +- - kernel/softirq.c | 780 +++++++++--- - kernel/stop_machine.c | 53 +- - kernel/time/hrtimer.c | 267 ++++- - kernel/time/itimer.c | 1 + - kernel/time/jiffies.c | 7 +- - kernel/time/ntp.c | 43 + - kernel/time/posix-cpu-timers.c | 193 ++- - kernel/time/posix-timers.c | 37 +- - kernel/time/tick-broadcast-hrtimer.c | 1 + - kernel/time/tick-common.c | 10 +- - kernel/time/tick-sched.c | 30 +- - kernel/time/timekeeping.c | 6 +- - kernel/time/timekeeping.h | 3 +- - kernel/time/timer.c | 104 +- - kernel/trace/Kconfig | 104 ++ - kernel/trace/Makefile | 4 + - kernel/trace/latency_hist.c | 1178 +++++++++++++++++++ - kernel/trace/trace.c | 38 +- - kernel/trace/trace.h | 2 + - kernel/trace/trace_events.c | 2 + - kernel/trace/trace_irqsoff.c | 11 + - kernel/trace/trace_output.c | 19 +- - kernel/user.c | 4 +- - kernel/watchdog.c | 11 + - kernel/workqueue.c | 229 ++-- - kernel/workqueue_internal.h | 5 +- - lib/Kconfig | 1 + - lib/debugobjects.c | 5 +- - lib/idr.c | 43 +- - lib/irq_poll.c | 5 + - lib/locking-selftest.c | 50 + - lib/percpu_ida.c | 20 +- - lib/radix-tree.c | 5 +- - lib/rbtree.c | 11 + - lib/scatterlist.c | 6 +- - lib/smp_processor_id.c | 5 +- - mm/Kconfig | 2 +- - mm/backing-dev.c | 4 +- - mm/compaction.c | 6 +- - mm/filemap.c | 11 +- - mm/highmem.c | 6 +- - mm/memcontrol.c | 31 +- - mm/mmu_context.c | 2 + - mm/page_alloc.c | 146 ++- - mm/slab.h | 4 + - mm/slub.c | 135 ++- - mm/swap.c | 39 +- - mm/truncate.c | 7 +- - mm/vmalloc.c | 13 +- - mm/vmstat.c | 6 + - mm/workingset.c | 23 +- - mm/zsmalloc.c | 4 +- - net/core/dev.c | 157 ++- - net/core/skbuff.c | 35 +- - net/core/sock.c | 3 +- - net/ipv4/icmp.c | 30 + - net/ipv4/sysctl_net_ipv4.c | 7 + - net/mac80211/rx.c | 2 +- - net/netfilter/core.c | 6 + - net/packet/af_packet.c | 5 +- - net/rds/ib_rdma.c | 3 +- - net/sched/sch_generic.c | 2 +- - net/sunrpc/svc_xprt.c | 6 +- - scripts/mkcompile_h | 4 +- - sound/core/pcm_native.c | 8 +- - 351 files changed, 11050 insertions(+), 1777 deletions(-) - create mode 100644 Documentation/hwlat_detector.txt - create mode 100644 Documentation/trace/histograms.txt - create mode 100644 drivers/misc/hwlat_detector.c - create mode 100644 include/linux/locallock.h - create mode 100644 include/linux/mutex_rt.h - create mode 100644 include/linux/rwlock_rt.h - create mode 100644 include/linux/rwlock_types_rt.h - create mode 100644 include/linux/rwsem_rt.h - create mode 100644 include/linux/spinlock_rt.h - create mode 100644 include/linux/spinlock_types_nort.h - create mode 100644 include/linux/spinlock_types_raw.h - create mode 100644 include/linux/spinlock_types_rt.h - create mode 100644 include/linux/work-simple.h - create mode 100644 include/trace/events/hist.h - create mode 100644 include/trace/events/latency_hist.h - create mode 100644 kernel/locking/rt.c - create mode 100644 kernel/sched/work-simple.c - create mode 100644 kernel/trace/latency_hist.c - -diff --git a/Documentation/hwlat_detector.txt b/Documentation/hwlat_detector.txt -new file mode 100644 -index 0000000..cb61516 ---- /dev/null -+++ b/Documentation/hwlat_detector.txt -@@ -0,0 +1,64 @@ -+Introduction: -+------------- -+ -+The module hwlat_detector is a special purpose kernel module that is used to -+detect large system latencies induced by the behavior of certain underlying -+hardware or firmware, independent of Linux itself. The code was developed -+originally to detect SMIs (System Management Interrupts) on x86 systems, -+however there is nothing x86 specific about this patchset. It was -+originally written for use by the "RT" patch since the Real Time -+kernel is highly latency sensitive. -+ -+SMIs are usually not serviced by the Linux kernel, which typically does not -+even know that they are occuring. SMIs are instead are set up by BIOS code -+and are serviced by BIOS code, usually for "critical" events such as -+management of thermal sensors and fans. Sometimes though, SMIs are used for -+other tasks and those tasks can spend an inordinate amount of time in the -+handler (sometimes measured in milliseconds). Obviously this is a problem if -+you are trying to keep event service latencies down in the microsecond range. -+ -+The hardware latency detector works by hogging all of the cpus for configurable -+amounts of time (by calling stop_machine()), polling the CPU Time Stamp Counter -+for some period, then looking for gaps in the TSC data. Any gap indicates a -+time when the polling was interrupted and since the machine is stopped and -+interrupts turned off the only thing that could do that would be an SMI. -+ -+Note that the SMI detector should *NEVER* be used in a production environment. -+It is intended to be run manually to determine if the hardware platform has a -+problem with long system firmware service routines. -+ -+Usage: -+------ -+ -+Loading the module hwlat_detector passing the parameter "enabled=1" (or by -+setting the "enable" entry in "hwlat_detector" debugfs toggled on) is the only -+step required to start the hwlat_detector. It is possible to redefine the -+threshold in microseconds (us) above which latency spikes will be taken -+into account (parameter "threshold="). -+ -+Example: -+ -+ # modprobe hwlat_detector enabled=1 threshold=100 -+ -+After the module is loaded, it creates a directory named "hwlat_detector" under -+the debugfs mountpoint, "/debug/hwlat_detector" for this text. It is necessary -+to have debugfs mounted, which might be on /sys/debug on your system. -+ -+The /debug/hwlat_detector interface contains the following files: -+ -+count - number of latency spikes observed since last reset -+enable - a global enable/disable toggle (0/1), resets count -+max - maximum hardware latency actually observed (usecs) -+sample - a pipe from which to read current raw sample data -+ in the format <timestamp> <latency observed usecs> -+ (can be opened O_NONBLOCK for a single sample) -+threshold - minimum latency value to be considered (usecs) -+width - time period to sample with CPUs held (usecs) -+ must be less than the total window size (enforced) -+window - total period of sampling, width being inside (usecs) -+ -+By default we will set width to 500,000 and window to 1,000,000, meaning that -+we will sample every 1,000,000 usecs (1s) for 500,000 usecs (0.5s). If we -+observe any latencies that exceed the threshold (initially 100 usecs), -+then we write to a global sample ring buffer of 8K samples, which is -+consumed by reading from the "sample" (pipe) debugfs file interface. -diff --git a/Documentation/sysrq.txt b/Documentation/sysrq.txt -index 13f5619..f64d075 100644 ---- a/Documentation/sysrq.txt -+++ b/Documentation/sysrq.txt -@@ -59,10 +59,17 @@ On PowerPC - Press 'ALT - Print Screen (or F13) - <command key>, - On other - If you know of the key combos for other architectures, please - let me know so I can add them to this section. - --On all - write a character to /proc/sysrq-trigger. e.g.: -- -+On all - write a character to /proc/sysrq-trigger, e.g.: - echo t > /proc/sysrq-trigger - -+On all - Enable network SysRq by writing a cookie to icmp_echo_sysrq, e.g. -+ echo 0x01020304 >/proc/sys/net/ipv4/icmp_echo_sysrq -+ Send an ICMP echo request with this pattern plus the particular -+ SysRq command key. Example: -+ # ping -c1 -s57 -p0102030468 -+ will trigger the SysRq-H (help) command. -+ -+ - * What are the 'command' keys? - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - 'b' - Will immediately reboot the system without syncing or unmounting -diff --git a/Documentation/trace/histograms.txt b/Documentation/trace/histograms.txt -new file mode 100644 -index 0000000..6f2aeab ---- /dev/null -+++ b/Documentation/trace/histograms.txt -@@ -0,0 +1,186 @@ -+ Using the Linux Kernel Latency Histograms -+ -+ -+This document gives a short explanation how to enable, configure and use -+latency histograms. Latency histograms are primarily relevant in the -+context of real-time enabled kernels (CONFIG_PREEMPT/CONFIG_PREEMPT_RT) -+and are used in the quality management of the Linux real-time -+capabilities. -+ -+ -+* Purpose of latency histograms -+ -+A latency histogram continuously accumulates the frequencies of latency -+data. There are two types of histograms -+- potential sources of latencies -+- effective latencies -+ -+ -+* Potential sources of latencies -+ -+Potential sources of latencies are code segments where interrupts, -+preemption or both are disabled (aka critical sections). To create -+histograms of potential sources of latency, the kernel stores the time -+stamp at the start of a critical section, determines the time elapsed -+when the end of the section is reached, and increments the frequency -+counter of that latency value - irrespective of whether any concurrently -+running process is affected by latency or not. -+- Configuration items (in the Kernel hacking/Tracers submenu) -+ CONFIG_INTERRUPT_OFF_LATENCY -+ CONFIG_PREEMPT_OFF_LATENCY -+ -+ -+* Effective latencies -+ -+Effective latencies are actually occuring during wakeup of a process. To -+determine effective latencies, the kernel stores the time stamp when a -+process is scheduled to be woken up, and determines the duration of the -+wakeup time shortly before control is passed over to this process. Note -+that the apparent latency in user space may be somewhat longer, since the -+process may be interrupted after control is passed over to it but before -+the execution in user space takes place. Simply measuring the interval -+between enqueuing and wakeup may also not appropriate in cases when a -+process is scheduled as a result of a timer expiration. The timer may have -+missed its deadline, e.g. due to disabled interrupts, but this latency -+would not be registered. Therefore, the offsets of missed timers are -+recorded in a separate histogram. If both wakeup latency and missed timer -+offsets are configured and enabled, a third histogram may be enabled that -+records the overall latency as a sum of the timer latency, if any, and the -+wakeup latency. This histogram is called "timerandwakeup". -+- Configuration items (in the Kernel hacking/Tracers submenu) -+ CONFIG_WAKEUP_LATENCY -+ CONFIG_MISSED_TIMER_OFSETS -+ -+ -+* Usage -+ -+The interface to the administration of the latency histograms is located -+in the debugfs file system. To mount it, either enter -+ -+mount -t sysfs nodev /sys -+mount -t debugfs nodev /sys/kernel/debug -+ -+from shell command line level, or add -+ -+nodev /sys sysfs defaults 0 0 -+nodev /sys/kernel/debug debugfs defaults 0 0 -+ -+to the file /etc/fstab. All latency histogram related files are then -+available in the directory /sys/kernel/debug/tracing/latency_hist. A -+particular histogram type is enabled by writing non-zero to the related -+variable in the /sys/kernel/debug/tracing/latency_hist/enable directory. -+Select "preemptirqsoff" for the histograms of potential sources of -+latencies and "wakeup" for histograms of effective latencies etc. The -+histogram data - one per CPU - are available in the files -+ -+/sys/kernel/debug/tracing/latency_hist/preemptoff/CPUx -+/sys/kernel/debug/tracing/latency_hist/irqsoff/CPUx -+/sys/kernel/debug/tracing/latency_hist/preemptirqsoff/CPUx -+/sys/kernel/debug/tracing/latency_hist/wakeup/CPUx -+/sys/kernel/debug/tracing/latency_hist/wakeup/sharedprio/CPUx -+/sys/kernel/debug/tracing/latency_hist/missed_timer_offsets/CPUx -+/sys/kernel/debug/tracing/latency_hist/timerandwakeup/CPUx -+ -+The histograms are reset by writing non-zero to the file "reset" in a -+particular latency directory. To reset all latency data, use -+ -+#!/bin/sh -+ -+TRACINGDIR=/sys/kernel/debug/tracing -+HISTDIR=$TRACINGDIR/latency_hist -+ -+if test -d $HISTDIR -+then -+ cd $HISTDIR -+ for i in `find . | grep /reset$` -+ do -+ echo 1 >$i -+ done -+fi -+ -+ -+* Data format -+ -+Latency data are stored with a resolution of one microsecond. The -+maximum latency is 10,240 microseconds. The data are only valid, if the -+overflow register is empty. Every output line contains the latency in -+microseconds in the first row and the number of samples in the second -+row. To display only lines with a positive latency count, use, for -+example, -+ -+grep -v " 0$" /sys/kernel/debug/tracing/latency_hist/preemptoff/CPU0 -+ -+#Minimum latency: 0 microseconds. -+#Average latency: 0 microseconds. -+#Maximum latency: 25 microseconds. -+#Total samples: 3104770694 -+#There are 0 samples greater or equal than 10240 microseconds -+#usecs samples -+ 0 2984486876 -+ 1 49843506 -+ 2 58219047 -+ 3 5348126 -+ 4 2187960 -+ 5 3388262 -+ 6 959289 -+ 7 208294 -+ 8 40420 -+ 9 4485 -+ 10 14918 -+ 11 18340 -+ 12 25052 -+ 13 19455 -+ 14 5602 -+ 15 969 -+ 16 47 -+ 17 18 -+ 18 14 -+ 19 1 -+ 20 3 -+ 21 2 -+ 22 5 -+ 23 2 -+ 25 1 -+ -+ -+* Wakeup latency of a selected process -+ -+To only collect wakeup latency data of a particular process, write the -+PID of the requested process to -+ -+/sys/kernel/debug/tracing/latency_hist/wakeup/pid -+ -+PIDs are not considered, if this variable is set to 0. -+ -+ -+* Details of the process with the highest wakeup latency so far -+ -+Selected data of the process that suffered from the highest wakeup -+latency that occurred in a particular CPU are available in the file -+ -+/sys/kernel/debug/tracing/latency_hist/wakeup/max_latency-CPUx. -+ -+In addition, other relevant system data at the time when the -+latency occurred are given. -+ -+The format of the data is (all in one line): -+<PID> <Priority> <Latency> (<Timeroffset>) <Command> \ -+<- <PID> <Priority> <Command> <Timestamp> -+ -+The value of <Timeroffset> is only relevant in the combined timer -+and wakeup latency recording. In the wakeup recording, it is -+always 0, in the missed_timer_offsets recording, it is the same -+as <Latency>. -+ -+When retrospectively searching for the origin of a latency and -+tracing was not enabled, it may be helpful to know the name and -+some basic data of the task that (finally) was switching to the -+late real-tlme task. In addition to the victim's data, also the -+data of the possible culprit are therefore displayed after the -+"<-" symbol. -+ -+Finally, the timestamp of the time when the latency occurred -+in <seconds>.<microseconds> after the most recent system boot -+is provided. -+ -+These data are also reset when the wakeup histogram is reset. -diff --git a/arch/Kconfig b/arch/Kconfig -index 81869a5..54cfbcb 100644 ---- a/arch/Kconfig -+++ b/arch/Kconfig -@@ -9,6 +9,7 @@ config OPROFILE - tristate "OProfile system profiling" - depends on PROFILING - depends on HAVE_OPROFILE -+ depends on !PREEMPT_RT_FULL - select RING_BUFFER - select RING_BUFFER_ALLOW_SWAP - help -@@ -52,6 +53,7 @@ config KPROBES - config JUMP_LABEL - bool "Optimize very unlikely/likely branches" - depends on HAVE_ARCH_JUMP_LABEL -+ depends on (!INTERRUPT_OFF_HIST && !PREEMPT_OFF_HIST && !WAKEUP_LATENCY_HIST && !MISSED_TIMER_OFFSETS_HIST) - help - This option enables a transparent branch optimization that - makes certain almost-always-true or almost-always-false branch -diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig -index cdfa6c2..fa885f5 100644 ---- a/arch/arm/Kconfig -+++ b/arch/arm/Kconfig -@@ -35,7 +35,7 @@ config ARM - select HARDIRQS_SW_RESEND - select HAVE_ARCH_AUDITSYSCALL if (AEABI && !OABI_COMPAT) - select HAVE_ARCH_BITREVERSE if (CPU_32v7M || CPU_32v7) && !CPU_32v6 -- select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL && !CPU_ENDIAN_BE32 && MMU -+ select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL && !CPU_ENDIAN_BE32 && MMU && !PREEMPT_RT_BASE - select HAVE_ARCH_KGDB if !CPU_ENDIAN_BE32 && MMU - select HAVE_ARCH_MMAP_RND_BITS if MMU - select HAVE_ARCH_SECCOMP_FILTER if (AEABI && !OABI_COMPAT) -@@ -71,6 +71,7 @@ config ARM - select HAVE_PERF_EVENTS - select HAVE_PERF_REGS - select HAVE_PERF_USER_STACK_DUMP -+ select HAVE_PREEMPT_LAZY - select HAVE_RCU_TABLE_FREE if (SMP && ARM_LPAE) - select HAVE_REGS_AND_STACK_ACCESS_API - select HAVE_SYSCALL_TRACEPOINTS -diff --git a/arch/arm/include/asm/switch_to.h b/arch/arm/include/asm/switch_to.h -index 12ebfcc..c962084 100644 ---- a/arch/arm/include/asm/switch_to.h -+++ b/arch/arm/include/asm/switch_to.h -@@ -3,6 +3,13 @@ - - #include <linux/thread_info.h> - -+#if defined CONFIG_PREEMPT_RT_FULL && defined CONFIG_HIGHMEM -+void switch_kmaps(struct task_struct *prev_p, struct task_struct *next_p); -+#else -+static inline void -+switch_kmaps(struct task_struct *prev_p, struct task_struct *next_p) { } -+#endif -+ - /* - * For v7 SMP cores running a preemptible kernel we may be pre-empted - * during a TLB maintenance operation, so execute an inner-shareable dsb -@@ -25,6 +32,7 @@ extern struct task_struct *__switch_to(struct task_struct *, struct thread_info - #define switch_to(prev,next,last) \ - do { \ - __complete_pending_tlbi(); \ -+ switch_kmaps(prev, next); \ - last = __switch_to(prev,task_thread_info(prev), task_thread_info(next)); \ - } while (0) - -diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h -index 776757d..1f36a4e 100644 ---- a/arch/arm/include/asm/thread_info.h -+++ b/arch/arm/include/asm/thread_info.h -@@ -49,6 +49,7 @@ struct cpu_context_save { - struct thread_info { - unsigned long flags; /* low level flags */ - int preempt_count; /* 0 => preemptable, <0 => bug */ -+ int preempt_lazy_count; /* 0 => preemptable, <0 => bug */ - mm_segment_t addr_limit; /* address limit */ - struct task_struct *task; /* main task structure */ - __u32 cpu; /* cpu */ -@@ -142,7 +143,8 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *, - #define TIF_SYSCALL_TRACE 4 /* syscall trace active */ - #define TIF_SYSCALL_AUDIT 5 /* syscall auditing active */ - #define TIF_SYSCALL_TRACEPOINT 6 /* syscall tracepoint instrumentation */ --#define TIF_SECCOMP 7 /* seccomp syscall filtering active */ -+#define TIF_SECCOMP 8 /* seccomp syscall filtering active */ -+#define TIF_NEED_RESCHED_LAZY 7 - - #define TIF_NOHZ 12 /* in adaptive nohz mode */ - #define TIF_USING_IWMMXT 17 -@@ -152,6 +154,7 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *, - #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) - #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) - #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) -+#define _TIF_NEED_RESCHED_LAZY (1 << TIF_NEED_RESCHED_LAZY) - #define _TIF_UPROBE (1 << TIF_UPROBE) - #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) - #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) -@@ -167,7 +170,8 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *, - * Change these and you break ASM code in entry-common.S - */ - #define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \ -- _TIF_NOTIFY_RESUME | _TIF_UPROBE) -+ _TIF_NOTIFY_RESUME | _TIF_UPROBE | \ -+ _TIF_NEED_RESCHED_LAZY) - - #endif /* __KERNEL__ */ - #endif /* __ASM_ARM_THREAD_INFO_H */ -diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c -index 27d0581..5a37422 100644 ---- a/arch/arm/kernel/asm-offsets.c -+++ b/arch/arm/kernel/asm-offsets.c -@@ -65,6 +65,7 @@ int main(void) - BLANK(); - DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); - DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count)); -+ DEFINE(TI_PREEMPT_LAZY, offsetof(struct thread_info, preempt_lazy_count)); - DEFINE(TI_ADDR_LIMIT, offsetof(struct thread_info, addr_limit)); - DEFINE(TI_TASK, offsetof(struct thread_info, task)); - DEFINE(TI_CPU, offsetof(struct thread_info, cpu)); -diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S -index e255050..1880275 100644 ---- a/arch/arm/kernel/entry-armv.S -+++ b/arch/arm/kernel/entry-armv.S -@@ -215,11 +215,18 @@ __irq_svc: - #ifdef CONFIG_PREEMPT - get_thread_info tsk - ldr r8, [tsk, #TI_PREEMPT] @ get preempt count -- ldr r0, [tsk, #TI_FLAGS] @ get flags - teq r8, #0 @ if preempt count != 0 -+ bne 1f @ return from exeption -+ ldr r0, [tsk, #TI_FLAGS] @ get flags -+ tst r0, #_TIF_NEED_RESCHED @ if NEED_RESCHED is set -+ blne svc_preempt @ preempt! -+ -+ ldr r8, [tsk, #TI_PREEMPT_LAZY] @ get preempt lazy count -+ teq r8, #0 @ if preempt lazy count != 0 - movne r0, #0 @ force flags to 0 -- tst r0, #_TIF_NEED_RESCHED -+ tst r0, #_TIF_NEED_RESCHED_LAZY - blne svc_preempt -+1: - #endif - - svc_exit r5, irq = 1 @ return from exception -@@ -234,6 +241,8 @@ svc_preempt: - 1: bl preempt_schedule_irq @ irq en/disable is done inside - ldr r0, [tsk, #TI_FLAGS] @ get new tasks TI_FLAGS - tst r0, #_TIF_NEED_RESCHED -+ bne 1b -+ tst r0, #_TIF_NEED_RESCHED_LAZY - reteq r8 @ go again - b 1b - #endif -diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S -index 30a7228..c3bd6cb 100644 ---- a/arch/arm/kernel/entry-common.S -+++ b/arch/arm/kernel/entry-common.S -@@ -36,7 +36,9 @@ ret_fast_syscall: - UNWIND(.cantunwind ) - disable_irq_notrace @ disable interrupts - ldr r1, [tsk, #TI_FLAGS] @ re-check for syscall tracing -- tst r1, #_TIF_SYSCALL_WORK | _TIF_WORK_MASK -+ tst r1, #((_TIF_SYSCALL_WORK | _TIF_WORK_MASK) & ~_TIF_SECCOMP) -+ bne fast_work_pending -+ tst r1, #_TIF_SECCOMP - bne fast_work_pending - - /* perform architecture specific actions before user return */ -@@ -62,8 +64,11 @@ ret_fast_syscall: - str r0, [sp, #S_R0 + S_OFF]! @ save returned r0 - disable_irq_notrace @ disable interrupts - ldr r1, [tsk, #TI_FLAGS] @ re-check for syscall tracing -- tst r1, #_TIF_SYSCALL_WORK | _TIF_WORK_MASK -+ tst r1, #((_TIF_SYSCALL_WORK | _TIF_WORK_MASK) & ~_TIF_SECCOMP) -+ bne do_slower_path -+ tst r1, #_TIF_SECCOMP - beq no_work_pending -+do_slower_path: - UNWIND(.fnend ) - ENDPROC(ret_fast_syscall) - -diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c -index 4adfb46..15f1d94 100644 ---- a/arch/arm/kernel/process.c -+++ b/arch/arm/kernel/process.c -@@ -319,6 +319,30 @@ unsigned long arch_randomize_brk(struct mm_struct *mm) - } - - #ifdef CONFIG_MMU -+/* -+ * CONFIG_SPLIT_PTLOCK_CPUS results in a page->ptl lock. If the lock is not -+ * initialized by pgtable_page_ctor() then a coredump of the vector page will -+ * fail. -+ */ -+static int __init vectors_user_mapping_init_page(void) -+{ -+ struct page *page; -+ unsigned long addr = 0xffff0000; -+ pgd_t *pgd; -+ pud_t *pud; -+ pmd_t *pmd; -+ -+ pgd = pgd_offset_k(addr); -+ pud = pud_offset(pgd, addr); -+ pmd = pmd_offset(pud, addr); -+ page = pmd_page(*(pmd)); -+ -+ pgtable_page_ctor(page); -+ -+ return 0; -+} -+late_initcall(vectors_user_mapping_init_page); -+ - #ifdef CONFIG_KUSER_HELPERS - /* - * The vectors page is always readable from user space for the -diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c -index 7b8f214..96541e0 100644 ---- a/arch/arm/kernel/signal.c -+++ b/arch/arm/kernel/signal.c -@@ -572,7 +572,8 @@ do_work_pending(struct pt_regs *regs, unsigned int thread_flags, int syscall) - */ - trace_hardirqs_off(); - do { -- if (likely(thread_flags & _TIF_NEED_RESCHED)) { -+ if (likely(thread_flags & (_TIF_NEED_RESCHED | -+ _TIF_NEED_RESCHED_LAZY))) { - schedule(); - } else { - if (unlikely(!user_mode(regs))) -diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c -index baee702..ad157ec 100644 ---- a/arch/arm/kernel/smp.c -+++ b/arch/arm/kernel/smp.c -@@ -234,8 +234,6 @@ int __cpu_disable(void) - flush_cache_louis(); - local_flush_tlb_all(); - -- clear_tasks_mm_cpumask(cpu); -- - return 0; - } - -@@ -251,6 +249,9 @@ void __cpu_die(unsigned int cpu) - pr_err("CPU%u: cpu didn't die\n", cpu); - return; - } -+ -+ clear_tasks_mm_cpumask(cpu); -+ - pr_notice("CPU%u: shutdown\n", cpu); - - /* -diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c -index 0bee233..314cfb2 100644 ---- a/arch/arm/kernel/unwind.c -+++ b/arch/arm/kernel/unwind.c -@@ -93,7 +93,7 @@ extern const struct unwind_idx __start_unwind_idx[]; - static const struct unwind_idx *__origin_unwind_idx; - extern const struct unwind_idx __stop_unwind_idx[]; - --static DEFINE_SPINLOCK(unwind_lock); -+static DEFINE_RAW_SPINLOCK(unwind_lock); - static LIST_HEAD(unwind_tables); - - /* Convert a prel31 symbol to an absolute address */ -@@ -201,7 +201,7 @@ static const struct unwind_idx *unwind_find_idx(unsigned long addr) - /* module unwind tables */ - struct unwind_table *table; - -- spin_lock_irqsave(&unwind_lock, flags); -+ raw_spin_lock_irqsave(&unwind_lock, flags); - list_for_each_entry(table, &unwind_tables, list) { - if (addr >= table->begin_addr && - addr < table->end_addr) { -@@ -213,7 +213,7 @@ static const struct unwind_idx *unwind_find_idx(unsigned long addr) - break; - } - } -- spin_unlock_irqrestore(&unwind_lock, flags); -+ raw_spin_unlock_irqrestore(&unwind_lock, flags); - } - - pr_debug("%s: idx = %p\n", __func__, idx); -@@ -529,9 +529,9 @@ struct unwind_table *unwind_table_add(unsigned long start, unsigned long size, - tab->begin_addr = text_addr; - tab->end_addr = text_addr + text_size; - -- spin_lock_irqsave(&unwind_lock, flags); -+ raw_spin_lock_irqsave(&unwind_lock, flags); - list_add_tail(&tab->list, &unwind_tables); -- spin_unlock_irqrestore(&unwind_lock, flags); -+ raw_spin_unlock_irqrestore(&unwind_lock, flags); - - return tab; - } -@@ -543,9 +543,9 @@ void unwind_table_del(struct unwind_table *tab) - if (!tab) - return; - -- spin_lock_irqsave(&unwind_lock, flags); -+ raw_spin_lock_irqsave(&unwind_lock, flags); - list_del(&tab->list); -- spin_unlock_irqrestore(&unwind_lock, flags); -+ raw_spin_unlock_irqrestore(&unwind_lock, flags); - - kfree(tab); - } -diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c -index dded1b7..893b934 100644 ---- a/arch/arm/kvm/arm.c -+++ b/arch/arm/kvm/arm.c -@@ -581,7 +581,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) - * involves poking the GIC, which must be done in a - * non-preemptible context. - */ -- preempt_disable(); -+ migrate_disable(); - kvm_pmu_flush_hwstate(vcpu); - kvm_timer_flush_hwstate(vcpu); - kvm_vgic_flush_hwstate(vcpu); -@@ -602,7 +602,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) - kvm_pmu_sync_hwstate(vcpu); - kvm_timer_sync_hwstate(vcpu); - kvm_vgic_sync_hwstate(vcpu); -- preempt_enable(); -+ migrate_enable(); - continue; - } - -@@ -658,7 +658,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) - - kvm_vgic_sync_hwstate(vcpu); - -- preempt_enable(); -+ migrate_enable(); - - ret = handle_exit(vcpu, run, ret); - } -diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c -index 85c3be6..8a950ae 100644 ---- a/arch/arm/mach-exynos/platsmp.c -+++ b/arch/arm/mach-exynos/platsmp.c -@@ -229,7 +229,7 @@ static void __iomem *scu_base_addr(void) - return (void __iomem *)(S5P_VA_SCU); - } - --static DEFINE_SPINLOCK(boot_lock); -+static DEFINE_RAW_SPINLOCK(boot_lock); - - static void exynos_secondary_init(unsigned int cpu) - { -@@ -242,8 +242,8 @@ static void exynos_secondary_init(unsigned int cpu) - /* - * Synchronise with the boot thread. - */ -- spin_lock(&boot_lock); -- spin_unlock(&boot_lock); -+ raw_spin_lock(&boot_lock); -+ raw_spin_unlock(&boot_lock); - } - - int exynos_set_boot_addr(u32 core_id, unsigned long boot_addr) -@@ -307,7 +307,7 @@ static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle) - * Set synchronisation state between this boot processor - * and the secondary one - */ -- spin_lock(&boot_lock); -+ raw_spin_lock(&boot_lock); - - /* - * The secondary processor is waiting to be released from -@@ -334,7 +334,7 @@ static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle) - - if (timeout == 0) { - printk(KERN_ERR "cpu1 power enable failed"); -- spin_unlock(&boot_lock); -+ raw_spin_unlock(&boot_lock); - return -ETIMEDOUT; - } - } -@@ -380,7 +380,7 @@ static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle) - * calibrations, then wait for it to finish - */ - fail: -- spin_unlock(&boot_lock); -+ raw_spin_unlock(&boot_lock); - - return pen_release != -1 ? ret : 0; - } -diff --git a/arch/arm/mach-hisi/platmcpm.c b/arch/arm/mach-hisi/platmcpm.c -index 4b653a8..b03d5a9 100644 ---- a/arch/arm/mach-hisi/platmcpm.c -+++ b/arch/arm/mach-hisi/platmcpm.c -@@ -61,7 +61,7 @@ - - static void __iomem *sysctrl, *fabric; - static int hip04_cpu_table[HIP04_MAX_CLUSTERS][HIP04_MAX_CPUS_PER_CLUSTER]; --static DEFINE_SPINLOCK(boot_lock); -+static DEFINE_RAW_SPINLOCK(boot_lock); - static u32 fabric_phys_addr; - /* - * [0]: bootwrapper physical address -@@ -113,7 +113,7 @@ static int hip04_boot_secondary(unsigned int l_cpu, struct task_struct *idle) - if (cluster >= HIP04_MAX_CLUSTERS || cpu >= HIP04_MAX_CPUS_PER_CLUSTER) - return -EINVAL; - -- spin_lock_irq(&boot_lock); -+ raw_spin_lock_irq(&boot_lock); - - if (hip04_cpu_table[cluster][cpu]) - goto out; -@@ -147,7 +147,7 @@ static int hip04_boot_secondary(unsigned int l_cpu, struct task_struct *idle) - - out: - hip04_cpu_table[cluster][cpu]++; -- spin_unlock_irq(&boot_lock); -+ raw_spin_unlock_irq(&boot_lock); - - return 0; - } -@@ -162,11 +162,11 @@ static void hip04_cpu_die(unsigned int l_cpu) - cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0); - cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1); - -- spin_lock(&boot_lock); -+ raw_spin_lock(&boot_lock); - hip04_cpu_table[cluster][cpu]--; - if (hip04_cpu_table[cluster][cpu] == 1) { - /* A power_up request went ahead of us. */ -- spin_unlock(&boot_lock); -+ raw_spin_unlock(&boot_lock); - return; - } else if (hip04_cpu_table[cluster][cpu] > 1) { - pr_err("Cluster %d CPU%d boots multiple times\n", cluster, cpu); -@@ -174,7 +174,7 @@ static void hip04_cpu_die(unsigned int l_cpu) - } - - last_man = hip04_cluster_is_down(cluster); -- spin_unlock(&boot_lock); -+ raw_spin_unlock(&boot_lock); - if (last_man) { - /* Since it's Cortex A15, disable L2 prefetching. */ - asm volatile( -@@ -203,7 +203,7 @@ static int hip04_cpu_kill(unsigned int l_cpu) - cpu >= HIP04_MAX_CPUS_PER_CLUSTER); - - count = TIMEOUT_MSEC / POLL_MSEC; -- spin_lock_irq(&boot_lock); -+ raw_spin_lock_irq(&boot_lock); - for (tries = 0; tries < count; tries++) { - if (hip04_cpu_table[cluster][cpu]) - goto err; -@@ -211,10 +211,10 @@ static int hip04_cpu_kill(unsigned int l_cpu) - data = readl_relaxed(sysctrl + SC_CPU_RESET_STATUS(cluster)); - if (data & CORE_WFI_STATUS(cpu)) - break; -- spin_unlock_irq(&boot_lock); -+ raw_spin_unlock_irq(&boot_lock); - /* Wait for clean L2 when the whole cluster is down. */ - msleep(POLL_MSEC); -- spin_lock_irq(&boot_lock); -+ raw_spin_lock_irq(&boot_lock); - } - if (tries >= count) - goto err; -@@ -231,10 +231,10 @@ static int hip04_cpu_kill(unsigned int l_cpu) - goto err; - if (hip04_cluster_is_down(cluster)) - hip04_set_snoop_filter(cluster, 0); -- spin_unlock_irq(&boot_lock); -+ raw_spin_unlock_irq(&boot_lock); - return 1; - err: -- spin_unlock_irq(&boot_lock); -+ raw_spin_unlock_irq(&boot_lock); - return 0; - } - #endif -diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig -index 8973fae..dd905b9 100644 ---- a/arch/arm/mach-imx/Kconfig -+++ b/arch/arm/mach-imx/Kconfig -@@ -526,7 +526,7 @@ config SOC_IMX6Q - bool "i.MX6 Quad/DualLite support" - select ARM_ERRATA_764369 if SMP - select HAVE_ARM_SCU if SMP -- select HAVE_ARM_TWD if SMP -+ select HAVE_ARM_TWD - select PCI_DOMAINS if PCI - select PINCTRL_IMX6Q - select SOC_IMX6 -diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c -index c625cc1..6cbad70 100644 ---- a/arch/arm/mach-omap2/omap-smp.c -+++ b/arch/arm/mach-omap2/omap-smp.c -@@ -43,7 +43,7 @@ - /* SCU base address */ - static void __iomem *scu_base; - --static DEFINE_SPINLOCK(boot_lock); -+static DEFINE_RAW_SPINLOCK(boot_lock); - - void __iomem *omap4_get_scu_base(void) - { -@@ -74,8 +74,8 @@ static void omap4_secondary_init(unsigned int cpu) - /* - * Synchronise with the boot thread. - */ -- spin_lock(&boot_lock); -- spin_unlock(&boot_lock); -+ raw_spin_lock(&boot_lock); -+ raw_spin_unlock(&boot_lock); - } - - static int omap4_boot_secondary(unsigned int cpu, struct task_struct *idle) -@@ -89,7 +89,7 @@ static int omap4_boot_secondary(unsigned int cpu, struct task_struct *idle) - * Set synchronisation state between this boot processor - * and the secondary one - */ -- spin_lock(&boot_lock); -+ raw_spin_lock(&boot_lock); - - /* - * Update the AuxCoreBoot0 with boot state for secondary core. -@@ -166,7 +166,7 @@ static int omap4_boot_secondary(unsigned int cpu, struct task_struct *idle) - * Now the secondary core is starting up let it run its - * calibrations, then wait for it to finish - */ -- spin_unlock(&boot_lock); -+ raw_spin_unlock(&boot_lock); - - return 0; - } -diff --git a/arch/arm/mach-prima2/platsmp.c b/arch/arm/mach-prima2/platsmp.c -index 0875b99..18b6d98 100644 ---- a/arch/arm/mach-prima2/platsmp.c -+++ b/arch/arm/mach-prima2/platsmp.c -@@ -22,7 +22,7 @@ - - static void __iomem *clk_base; - --static DEFINE_SPINLOCK(boot_lock); -+static DEFINE_RAW_SPINLOCK(boot_lock); - - static void sirfsoc_secondary_init(unsigned int cpu) - { -@@ -36,8 +36,8 @@ static void sirfsoc_secondary_init(unsigned int cpu) - /* - * Synchronise with the boot thread. - */ -- spin_lock(&boot_lock); -- spin_unlock(&boot_lock); -+ raw_spin_lock(&boot_lock); -+ raw_spin_unlock(&boot_lock); - } - - static const struct of_device_id clk_ids[] = { -@@ -75,7 +75,7 @@ static int sirfsoc_boot_secondary(unsigned int cpu, struct task_struct *idle) - /* make sure write buffer is drained */ - mb(); - -- spin_lock(&boot_lock); -+ raw_spin_lock(&boot_lock); - - /* - * The secondary processor is waiting to be released from -@@ -107,7 +107,7 @@ static int sirfsoc_boot_secondary(unsigned int cpu, struct task_struct *idle) - * now the secondary core is starting up let it run its - * calibrations, then wait for it to finish - */ -- spin_unlock(&boot_lock); -+ raw_spin_unlock(&boot_lock); - - return pen_release != -1 ? -ENOSYS : 0; - } -diff --git a/arch/arm/mach-qcom/platsmp.c b/arch/arm/mach-qcom/platsmp.c -index 5494c9e..e8ce157 100644 ---- a/arch/arm/mach-qcom/platsmp.c -+++ b/arch/arm/mach-qcom/platsmp.c -@@ -46,7 +46,7 @@ - - extern void secondary_startup_arm(void); - --static DEFINE_SPINLOCK(boot_lock); -+static DEFINE_RAW_SPINLOCK(boot_lock); - - #ifdef CONFIG_HOTPLUG_CPU - static void qcom_cpu_die(unsigned int cpu) -@@ -60,8 +60,8 @@ static void qcom_secondary_init(unsigned int cpu) - /* - * Synchronise with the boot thread. - */ -- spin_lock(&boot_lock); -- spin_unlock(&boot_lock); -+ raw_spin_lock(&boot_lock); -+ raw_spin_unlock(&boot_lock); - } - - static int scss_release_secondary(unsigned int cpu) -@@ -284,7 +284,7 @@ static int qcom_boot_secondary(unsigned int cpu, int (*func)(unsigned int)) - * set synchronisation state between this boot processor - * and the secondary one - */ -- spin_lock(&boot_lock); -+ raw_spin_lock(&boot_lock); - - /* - * Send the secondary CPU a soft interrupt, thereby causing -@@ -297,7 +297,7 @@ static int qcom_boot_secondary(unsigned int cpu, int (*func)(unsigned int)) - * now the secondary core is starting up let it run its - * calibrations, then wait for it to finish - */ -- spin_unlock(&boot_lock); -+ raw_spin_unlock(&boot_lock); - - return ret; - } -diff --git a/arch/arm/mach-spear/platsmp.c b/arch/arm/mach-spear/platsmp.c -index 8d1e2d5..7fa56cc 100644 ---- a/arch/arm/mach-spear/platsmp.c -+++ b/arch/arm/mach-spear/platsmp.c -@@ -32,7 +32,7 @@ static void write_pen_release(int val) - sync_cache_w(&pen_release); - } - --static DEFINE_SPINLOCK(boot_lock); -+static DEFINE_RAW_SPINLOCK(boot_lock); - - static void __iomem *scu_base = IOMEM(VA_SCU_BASE); - -@@ -47,8 +47,8 @@ static void spear13xx_secondary_init(unsigned int cpu) - /* - * Synchronise with the boot thread. - */ -- spin_lock(&boot_lock); -- spin_unlock(&boot_lock); -+ raw_spin_lock(&boot_lock); -+ raw_spin_unlock(&boot_lock); - } - - static int spear13xx_boot_secondary(unsigned int cpu, struct task_struct *idle) -@@ -59,7 +59,7 @@ static int spear13xx_boot_secondary(unsigned int cpu, struct task_struct *idle) - * set synchronisation state between this boot processor - * and the secondary one - */ -- spin_lock(&boot_lock); -+ raw_spin_lock(&boot_lock); - - /* - * The secondary processor is waiting to be released from -@@ -84,7 +84,7 @@ static int spear13xx_boot_secondary(unsigned int cpu, struct task_struct *idle) - * now the secondary core is starting up let it run its - * calibrations, then wait for it to finish - */ -- spin_unlock(&boot_lock); -+ raw_spin_unlock(&boot_lock); - - return pen_release != -1 ? -ENOSYS : 0; - } -diff --git a/arch/arm/mach-sti/platsmp.c b/arch/arm/mach-sti/platsmp.c -index ea5a227..b988e08 100644 ---- a/arch/arm/mach-sti/platsmp.c -+++ b/arch/arm/mach-sti/platsmp.c -@@ -35,7 +35,7 @@ static void write_pen_release(int val) - sync_cache_w(&pen_release); - } - --static DEFINE_SPINLOCK(boot_lock); -+static DEFINE_RAW_SPINLOCK(boot_lock); - - static void sti_secondary_init(unsigned int cpu) - { -@@ -48,8 +48,8 @@ static void sti_secondary_init(unsigned int cpu) - /* - * Synchronise with the boot thread. - */ -- spin_lock(&boot_lock); -- spin_unlock(&boot_lock); -+ raw_spin_lock(&boot_lock); -+ raw_spin_unlock(&boot_lock); - } - - static int sti_boot_secondary(unsigned int cpu, struct task_struct *idle) -@@ -60,7 +60,7 @@ static int sti_boot_secondary(unsigned int cpu, struct task_struct *idle) - * set synchronisation state between this boot processor - * and the secondary one - */ -- spin_lock(&boot_lock); -+ raw_spin_lock(&boot_lock); - - /* - * The secondary processor is waiting to be released from -@@ -91,7 +91,7 @@ static int sti_boot_secondary(unsigned int cpu, struct task_struct *idle) - * now the secondary core is starting up let it run its - * calibrations, then wait for it to finish - */ -- spin_unlock(&boot_lock); -+ raw_spin_unlock(&boot_lock); - - return pen_release != -1 ? -ENOSYS : 0; - } -diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c -index ad58418..7678f06 100644 ---- a/arch/arm/mm/fault.c -+++ b/arch/arm/mm/fault.c -@@ -430,6 +430,9 @@ do_translation_fault(unsigned long addr, unsigned int fsr, - if (addr < TASK_SIZE) - return do_page_fault(addr, fsr, regs); - -+ if (interrupts_enabled(regs)) -+ local_irq_enable(); -+ - if (user_mode(regs)) - goto bad_area; - -@@ -497,6 +500,9 @@ do_translation_fault(unsigned long addr, unsigned int fsr, - static int - do_sect_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) - { -+ if (interrupts_enabled(regs)) -+ local_irq_enable(); -+ - do_bad_area(addr, fsr, regs); - return 0; - } -diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c -index d02f818..542692d 100644 ---- a/arch/arm/mm/highmem.c -+++ b/arch/arm/mm/highmem.c -@@ -34,6 +34,11 @@ static inline pte_t get_fixmap_pte(unsigned long vaddr) - return *ptep; - } - -+static unsigned int fixmap_idx(int type) -+{ -+ return FIX_KMAP_BEGIN + type + KM_TYPE_NR * smp_processor_id(); -+} -+ - void *kmap(struct page *page) - { - might_sleep(); -@@ -54,12 +59,13 @@ EXPORT_SYMBOL(kunmap); - - void *kmap_atomic(struct page *page) - { -+ pte_t pte = mk_pte(page, kmap_prot); - unsigned int idx; - unsigned long vaddr; - void *kmap; - int type; - -- preempt_disable(); -+ preempt_disable_nort(); - pagefault_disable(); - if (!PageHighMem(page)) - return page_address(page); -@@ -79,7 +85,7 @@ void *kmap_atomic(struct page *page) - - type = kmap_atomic_idx_push(); - -- idx = FIX_KMAP_BEGIN + type + KM_TYPE_NR * smp_processor_id(); -+ idx = fixmap_idx(type); - vaddr = __fix_to_virt(idx); - #ifdef CONFIG_DEBUG_HIGHMEM - /* -@@ -93,7 +99,10 @@ void *kmap_atomic(struct page *page) - * in place, so the contained TLB flush ensures the TLB is updated - * with the new mapping. - */ -- set_fixmap_pte(idx, mk_pte(page, kmap_prot)); -+#ifdef CONFIG_PREEMPT_RT_FULL -+ current->kmap_pte[type] = pte; -+#endif -+ set_fixmap_pte(idx, pte); - - return (void *)vaddr; - } -@@ -106,44 +115,75 @@ void __kunmap_atomic(void *kvaddr) - - if (kvaddr >= (void *)FIXADDR_START) { - type = kmap_atomic_idx(); -- idx = FIX_KMAP_BEGIN + type + KM_TYPE_NR * smp_processor_id(); -+ idx = fixmap_idx(type); - - if (cache_is_vivt()) - __cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE); -+#ifdef CONFIG_PREEMPT_RT_FULL -+ current->kmap_pte[type] = __pte(0); -+#endif - #ifdef CONFIG_DEBUG_HIGHMEM - BUG_ON(vaddr != __fix_to_virt(idx)); -- set_fixmap_pte(idx, __pte(0)); - #else - (void) idx; /* to kill a warning */ - #endif -+ set_fixmap_pte(idx, __pte(0)); - kmap_atomic_idx_pop(); - } else if (vaddr >= PKMAP_ADDR(0) && vaddr < PKMAP_ADDR(LAST_PKMAP)) { - /* this address was obtained through kmap_high_get() */ - kunmap_high(pte_page(pkmap_page_table[PKMAP_NR(vaddr)])); - } - pagefault_enable(); -- preempt_enable(); -+ preempt_enable_nort(); - } - EXPORT_SYMBOL(__kunmap_atomic); - - void *kmap_atomic_pfn(unsigned long pfn) - { -+ pte_t pte = pfn_pte(pfn, kmap_prot); - unsigned long vaddr; - int idx, type; - struct page *page = pfn_to_page(pfn); - -- preempt_disable(); -+ preempt_disable_nort(); - pagefault_disable(); - if (!PageHighMem(page)) - return page_address(page); - - type = kmap_atomic_idx_push(); -- idx = FIX_KMAP_BEGIN + type + KM_TYPE_NR * smp_processor_id(); -+ idx = fixmap_idx(type); - vaddr = __fix_to_virt(idx); - #ifdef CONFIG_DEBUG_HIGHMEM - BUG_ON(!pte_none(get_fixmap_pte(vaddr))); - #endif -- set_fixmap_pte(idx, pfn_pte(pfn, kmap_prot)); -+#ifdef CONFIG_PREEMPT_RT_FULL -+ current->kmap_pte[type] = pte; -+#endif -+ set_fixmap_pte(idx, pte); - - return (void *)vaddr; - } -+#if defined CONFIG_PREEMPT_RT_FULL -+void switch_kmaps(struct task_struct *prev_p, struct task_struct *next_p) -+{ -+ int i; -+ -+ /* -+ * Clear @prev's kmap_atomic mappings -+ */ -+ for (i = 0; i < prev_p->kmap_idx; i++) { -+ int idx = fixmap_idx(i); -+ -+ set_fixmap_pte(idx, __pte(0)); -+ } -+ /* -+ * Restore @next_p's kmap_atomic mappings -+ */ -+ for (i = 0; i < next_p->kmap_idx; i++) { -+ int idx = fixmap_idx(i); -+ -+ if (!pte_none(next_p->kmap_pte[i])) -+ set_fixmap_pte(idx, next_p->kmap_pte[i]); -+ } -+} -+#endif -diff --git a/arch/arm/plat-versatile/platsmp.c b/arch/arm/plat-versatile/platsmp.c -index 53feb90..b4a8d54 100644 ---- a/arch/arm/plat-versatile/platsmp.c -+++ b/arch/arm/plat-versatile/platsmp.c -@@ -30,7 +30,7 @@ static void write_pen_release(int val) - sync_cache_w(&pen_release); - } - --static DEFINE_SPINLOCK(boot_lock); -+static DEFINE_RAW_SPINLOCK(boot_lock); - - void versatile_secondary_init(unsigned int cpu) - { -@@ -43,8 +43,8 @@ void versatile_secondary_init(unsigned int cpu) - /* - * Synchronise with the boot thread. - */ -- spin_lock(&boot_lock); -- spin_unlock(&boot_lock); -+ raw_spin_lock(&boot_lock); -+ raw_spin_unlock(&boot_lock); - } - - int versatile_boot_secondary(unsigned int cpu, struct task_struct *idle) -@@ -55,7 +55,7 @@ int versatile_boot_secondary(unsigned int cpu, struct task_struct *idle) - * Set synchronisation state between this boot processor - * and the secondary one - */ -- spin_lock(&boot_lock); -+ raw_spin_lock(&boot_lock); - - /* - * This is really belt and braces; we hold unintended secondary -@@ -85,7 +85,7 @@ int versatile_boot_secondary(unsigned int cpu, struct task_struct *idle) - * now the secondary core is starting up let it run its - * calibrations, then wait for it to finish - */ -- spin_unlock(&boot_lock); -+ raw_spin_unlock(&boot_lock); - - return pen_release != -1 ? -ENOSYS : 0; - } -diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig -index 4f43622..0d7f54c 100644 ---- a/arch/arm64/Kconfig -+++ b/arch/arm64/Kconfig -@@ -81,6 +81,7 @@ config ARM64 - select HAVE_PERF_REGS - select HAVE_PERF_USER_STACK_DUMP - select HAVE_RCU_TABLE_FREE -+ select HAVE_PREEMPT_LAZY - select HAVE_SYSCALL_TRACEPOINTS - select IOMMU_DMA if IOMMU_SUPPORT - select IRQ_DOMAIN -@@ -624,7 +625,7 @@ config XEN_DOM0 - - config XEN - bool "Xen guest support on ARM64" -- depends on ARM64 && OF -+ depends on ARM64 && OF && !PREEMPT_RT_FULL - select SWIOTLB_XEN - select PARAVIRT - help -diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h -index abd64bd..9170788 100644 ---- a/arch/arm64/include/asm/thread_info.h -+++ b/arch/arm64/include/asm/thread_info.h -@@ -49,6 +49,7 @@ struct thread_info { - mm_segment_t addr_limit; /* address limit */ - struct task_struct *task; /* main task structure */ - int preempt_count; /* 0 => preemptable, <0 => bug */ -+ int preempt_lazy_count; /* 0 => preemptable, <0 => bug */ - int cpu; /* cpu */ - }; - -@@ -109,6 +110,7 @@ static inline struct thread_info *current_thread_info(void) - #define TIF_NEED_RESCHED 1 - #define TIF_NOTIFY_RESUME 2 /* callback before returning to user */ - #define TIF_FOREIGN_FPSTATE 3 /* CPU's FP state is not current's */ -+#define TIF_NEED_RESCHED_LAZY 4 - #define TIF_NOHZ 7 - #define TIF_SYSCALL_TRACE 8 - #define TIF_SYSCALL_AUDIT 9 -@@ -124,6 +126,7 @@ static inline struct thread_info *current_thread_info(void) - #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) - #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) - #define _TIF_FOREIGN_FPSTATE (1 << TIF_FOREIGN_FPSTATE) -+#define _TIF_NEED_RESCHED_LAZY (1 << TIF_NEED_RESCHED_LAZY) - #define _TIF_NOHZ (1 << TIF_NOHZ) - #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) - #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) -@@ -132,7 +135,8 @@ static inline struct thread_info *current_thread_info(void) - #define _TIF_32BIT (1 << TIF_32BIT) - - #define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \ -- _TIF_NOTIFY_RESUME | _TIF_FOREIGN_FPSTATE) -+ _TIF_NOTIFY_RESUME | _TIF_FOREIGN_FPSTATE | \ -+ _TIF_NEED_RESCHED_LAZY) - - #define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \ - _TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP | \ -diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c -index 3ae6b31..c65de36 100644 ---- a/arch/arm64/kernel/asm-offsets.c -+++ b/arch/arm64/kernel/asm-offsets.c -@@ -36,6 +36,7 @@ int main(void) - BLANK(); - DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); - DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count)); -+ DEFINE(TI_PREEMPT_LAZY, offsetof(struct thread_info, preempt_lazy_count)); - DEFINE(TI_ADDR_LIMIT, offsetof(struct thread_info, addr_limit)); - DEFINE(TI_TASK, offsetof(struct thread_info, task)); - DEFINE(TI_CPU, offsetof(struct thread_info, cpu)); -diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S -index 12e8d2b..836cab9 100644 ---- a/arch/arm64/kernel/entry.S -+++ b/arch/arm64/kernel/entry.S -@@ -411,11 +411,16 @@ el1_irq: - - #ifdef CONFIG_PREEMPT - ldr w24, [tsk, #TI_PREEMPT] // get preempt count -- cbnz w24, 1f // preempt count != 0 -+ cbnz w24, 2f // preempt count != 0 - ldr x0, [tsk, #TI_FLAGS] // get flags -- tbz x0, #TIF_NEED_RESCHED, 1f // needs rescheduling? -- bl el1_preempt -+ tbnz x0, #TIF_NEED_RESCHED, 1f // needs rescheduling? -+ -+ ldr w24, [tsk, #TI_PREEMPT_LAZY] // get preempt lazy count -+ cbnz w24, 2f // preempt lazy count != 0 -+ tbz x0, #TIF_NEED_RESCHED_LAZY, 2f // needs rescheduling? - 1: -+ bl el1_preempt -+2: - #endif - #ifdef CONFIG_TRACE_IRQFLAGS - bl trace_hardirqs_on -@@ -429,6 +434,7 @@ el1_preempt: - 1: bl preempt_schedule_irq // irq en/disable is done inside - ldr x0, [tsk, #TI_FLAGS] // get new tasks TI_FLAGS - tbnz x0, #TIF_NEED_RESCHED, 1b // needs rescheduling? -+ tbnz x0, #TIF_NEED_RESCHED_LAZY, 1b // needs rescheduling? - ret x24 - #endif - -@@ -675,6 +681,7 @@ ret_fast_syscall_trace: - */ - work_pending: - tbnz x1, #TIF_NEED_RESCHED, work_resched -+ tbnz x1, #TIF_NEED_RESCHED_LAZY, work_resched - /* TIF_SIGPENDING, TIF_NOTIFY_RESUME or TIF_FOREIGN_FPSTATE case */ - mov x0, sp // 'regs' - enable_irq // enable interrupts for do_notify_resume() -diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig -index 2018c2b..3f3820f 100644 ---- a/arch/mips/Kconfig -+++ b/arch/mips/Kconfig -@@ -2416,7 +2416,7 @@ config CPU_R4400_WORKAROUNDS - # - config HIGHMEM - bool "High Memory Support" -- depends on 32BIT && CPU_SUPPORTS_HIGHMEM && SYS_SUPPORTS_HIGHMEM && !CPU_MIPS32_3_5_EVA -+ depends on 32BIT && CPU_SUPPORTS_HIGHMEM && SYS_SUPPORTS_HIGHMEM && !CPU_MIPS32_3_5_EVA && !PREEMPT_RT_FULL - - config CPU_SUPPORTS_HIGHMEM - bool -diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig -index 7cd32c0..69c3f4d 100644 ---- a/arch/powerpc/Kconfig -+++ b/arch/powerpc/Kconfig -@@ -57,10 +57,11 @@ config LOCKDEP_SUPPORT - - config RWSEM_GENERIC_SPINLOCK - bool -+ default y if PREEMPT_RT_FULL - - config RWSEM_XCHGADD_ALGORITHM - bool -- default y -+ default y if !PREEMPT_RT_FULL - - config GENERIC_LOCKBREAK - bool -@@ -138,6 +139,7 @@ config PPC - select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST - select GENERIC_STRNCPY_FROM_USER - select GENERIC_STRNLEN_USER -+ select HAVE_PREEMPT_LAZY - select HAVE_MOD_ARCH_SPECIFIC - select MODULES_USE_ELF_RELA - select CLONE_BACKWARDS -@@ -319,7 +321,7 @@ menu "Kernel options" - - config HIGHMEM - bool "High memory support" -- depends on PPC32 -+ depends on PPC32 && !PREEMPT_RT_FULL - - source kernel/Kconfig.hz - source kernel/Kconfig.preempt -diff --git a/arch/powerpc/include/asm/thread_info.h b/arch/powerpc/include/asm/thread_info.h -index 7efee4a..40e6fa1 100644 ---- a/arch/powerpc/include/asm/thread_info.h -+++ b/arch/powerpc/include/asm/thread_info.h -@@ -42,6 +42,8 @@ struct thread_info { - int cpu; /* cpu we're on */ - int preempt_count; /* 0 => preemptable, - <0 => BUG */ -+ int preempt_lazy_count; /* 0 => preemptable, -+ <0 => BUG */ - unsigned long local_flags; /* private flags for thread */ - - /* low level flags - has atomic operations done on it */ -@@ -82,8 +84,7 @@ static inline struct thread_info *current_thread_info(void) - #define TIF_SYSCALL_TRACE 0 /* syscall trace active */ - #define TIF_SIGPENDING 1 /* signal pending */ - #define TIF_NEED_RESCHED 2 /* rescheduling necessary */ --#define TIF_POLLING_NRFLAG 3 /* true if poll_idle() is polling -- TIF_NEED_RESCHED */ -+#define TIF_NEED_RESCHED_LAZY 3 /* lazy rescheduling necessary */ - #define TIF_32BIT 4 /* 32 bit binary */ - #define TIF_RESTORE_TM 5 /* need to restore TM FP/VEC/VSX */ - #define TIF_SYSCALL_AUDIT 7 /* syscall auditing active */ -@@ -101,6 +102,8 @@ static inline struct thread_info *current_thread_info(void) - #if defined(CONFIG_PPC64) - #define TIF_ELF2ABI 18 /* function descriptors must die! */ - #endif -+#define TIF_POLLING_NRFLAG 19 /* true if poll_idle() is polling -+ TIF_NEED_RESCHED */ - - /* as above, but as bit values */ - #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) -@@ -119,14 +122,16 @@ static inline struct thread_info *current_thread_info(void) - #define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT) - #define _TIF_EMULATE_STACK_STORE (1<<TIF_EMULATE_STACK_STORE) - #define _TIF_NOHZ (1<<TIF_NOHZ) -+#define _TIF_NEED_RESCHED_LAZY (1<<TIF_NEED_RESCHED_LAZY) - #define _TIF_SYSCALL_DOTRACE (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \ - _TIF_SECCOMP | _TIF_SYSCALL_TRACEPOINT | \ - _TIF_NOHZ) - - #define _TIF_USER_WORK_MASK (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \ - _TIF_NOTIFY_RESUME | _TIF_UPROBE | \ -- _TIF_RESTORE_TM) -+ _TIF_RESTORE_TM | _TIF_NEED_RESCHED_LAZY) - #define _TIF_PERSYSCALL_MASK (_TIF_RESTOREALL|_TIF_NOERROR) -+#define _TIF_NEED_RESCHED_MASK (_TIF_NEED_RESCHED | _TIF_NEED_RESCHED_LAZY) - - /* Bits in local_flags */ - /* Don't move TLF_NAPPING without adjusting the code in entry_32.S */ -diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c -index 0d0183d..476cf17 100644 ---- a/arch/powerpc/kernel/asm-offsets.c -+++ b/arch/powerpc/kernel/asm-offsets.c -@@ -162,6 +162,7 @@ int main(void) - DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); - DEFINE(TI_LOCAL_FLAGS, offsetof(struct thread_info, local_flags)); - DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count)); -+ DEFINE(TI_PREEMPT_LAZY, offsetof(struct thread_info, preempt_lazy_count)); - DEFINE(TI_TASK, offsetof(struct thread_info, task)); - DEFINE(TI_CPU, offsetof(struct thread_info, cpu)); - -diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S -index 2405631..c21b4b4 100644 ---- a/arch/powerpc/kernel/entry_32.S -+++ b/arch/powerpc/kernel/entry_32.S -@@ -818,7 +818,14 @@ resume_kernel: - cmpwi 0,r0,0 /* if non-zero, just restore regs and return */ - bne restore - andi. r8,r8,_TIF_NEED_RESCHED -+ bne+ 1f -+ lwz r0,TI_PREEMPT_LAZY(r9) -+ cmpwi 0,r0,0 /* if non-zero, just restore regs and return */ -+ bne restore -+ lwz r0,TI_FLAGS(r9) -+ andi. r0,r0,_TIF_NEED_RESCHED_LAZY - beq+ restore -+1: - lwz r3,_MSR(r1) - andi. r0,r3,MSR_EE /* interrupts off? */ - beq restore /* don't schedule if so */ -@@ -829,11 +836,11 @@ resume_kernel: - */ - bl trace_hardirqs_off - #endif --1: bl preempt_schedule_irq -+2: bl preempt_schedule_irq - CURRENT_THREAD_INFO(r9, r1) - lwz r3,TI_FLAGS(r9) -- andi. r0,r3,_TIF_NEED_RESCHED -- bne- 1b -+ andi. r0,r3,_TIF_NEED_RESCHED_MASK -+ bne- 2b - #ifdef CONFIG_TRACE_IRQFLAGS - /* And now, to properly rebalance the above, we tell lockdep they - * are being turned back on, which will happen when we return -@@ -1154,7 +1161,7 @@ global_dbcr0: - #endif /* !(CONFIG_4xx || CONFIG_BOOKE) */ - - do_work: /* r10 contains MSR_KERNEL here */ -- andi. r0,r9,_TIF_NEED_RESCHED -+ andi. r0,r9,_TIF_NEED_RESCHED_MASK - beq do_user_signal - - do_resched: /* r10 contains MSR_KERNEL here */ -@@ -1175,7 +1182,7 @@ recheck: - MTMSRD(r10) /* disable interrupts */ - CURRENT_THREAD_INFO(r9, r1) - lwz r9,TI_FLAGS(r9) -- andi. r0,r9,_TIF_NEED_RESCHED -+ andi. r0,r9,_TIF_NEED_RESCHED_MASK - bne- do_resched - andi. r0,r9,_TIF_USER_WORK_MASK - beq restore_user -diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S -index 9916d15..5dce935 100644 ---- a/arch/powerpc/kernel/entry_64.S -+++ b/arch/powerpc/kernel/entry_64.S -@@ -644,7 +644,7 @@ _GLOBAL(ret_from_except_lite) - bl restore_math - b restore - #endif --1: andi. r0,r4,_TIF_NEED_RESCHED -+1: andi. r0,r4,_TIF_NEED_RESCHED_MASK - beq 2f - bl restore_interrupts - SCHEDULE_USER -@@ -706,10 +706,18 @@ resume_kernel: - - #ifdef CONFIG_PREEMPT - /* Check if we need to preempt */ -+ lwz r8,TI_PREEMPT(r9) -+ cmpwi 0,r8,0 /* if non-zero, just restore regs and return */ -+ bne restore - andi. r0,r4,_TIF_NEED_RESCHED -+ bne+ check_count -+ -+ andi. r0,r4,_TIF_NEED_RESCHED_LAZY - beq+ restore -+ lwz r8,TI_PREEMPT_LAZY(r9) -+ - /* Check that preempt_count() == 0 and interrupts are enabled */ -- lwz r8,TI_PREEMPT(r9) -+check_count: - cmpwi cr1,r8,0 - ld r0,SOFTE(r1) - cmpdi r0,0 -@@ -726,7 +734,7 @@ resume_kernel: - /* Re-test flags and eventually loop */ - CURRENT_THREAD_INFO(r9, r1) - ld r4,TI_FLAGS(r9) -- andi. r0,r4,_TIF_NEED_RESCHED -+ andi. r0,r4,_TIF_NEED_RESCHED_MASK - bne 1b - - /* -diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c -index 290559d..070afa6 100644 ---- a/arch/powerpc/kernel/irq.c -+++ b/arch/powerpc/kernel/irq.c -@@ -614,6 +614,7 @@ void irq_ctx_init(void) - } - } - -+#ifndef CONFIG_PREEMPT_RT_FULL - void do_softirq_own_stack(void) - { - struct thread_info *curtp, *irqtp; -@@ -631,6 +632,7 @@ void do_softirq_own_stack(void) - if (irqtp->flags) - set_bits(irqtp->flags, &curtp->flags); - } -+#endif - - irq_hw_number_t virq_to_hw(unsigned int virq) - { -diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S -index bf5160f..e551d78 100644 ---- a/arch/powerpc/kernel/misc_32.S -+++ b/arch/powerpc/kernel/misc_32.S -@@ -40,6 +40,7 @@ - * We store the saved ksp_limit in the unused part - * of the STACK_FRAME_OVERHEAD - */ -+#ifndef CONFIG_PREEMPT_RT_FULL - _GLOBAL(call_do_softirq) - mflr r0 - stw r0,4(r1) -@@ -56,6 +57,7 @@ _GLOBAL(call_do_softirq) - stw r10,THREAD+KSP_LIMIT(r2) - mtlr r0 - blr -+#endif - - /* - * void call_do_irq(struct pt_regs *regs, struct thread_info *irqtp); -diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S -index f28754c..31ae513 100644 ---- a/arch/powerpc/kernel/misc_64.S -+++ b/arch/powerpc/kernel/misc_64.S -@@ -30,6 +30,7 @@ - - .text - -+#ifndef CONFIG_PREEMPT_RT_FULL - _GLOBAL(call_do_softirq) - mflr r0 - std r0,16(r1) -@@ -40,6 +41,7 @@ _GLOBAL(call_do_softirq) - ld r0,16(r1) - mtlr r0 - blr -+#endif - - _GLOBAL(call_do_irq) - mflr r0 -diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig -index c2024ac..2303788 100644 ---- a/arch/powerpc/kvm/Kconfig -+++ b/arch/powerpc/kvm/Kconfig -@@ -172,6 +172,7 @@ config KVM_E500MC - config KVM_MPIC - bool "KVM in-kernel MPIC emulation" - depends on KVM && E500 -+ depends on !PREEMPT_RT_FULL - select HAVE_KVM_IRQCHIP - select HAVE_KVM_IRQFD - select HAVE_KVM_IRQ_ROUTING -diff --git a/arch/powerpc/platforms/ps3/device-init.c b/arch/powerpc/platforms/ps3/device-init.c -index 3f175e8..c4c02f9 100644 ---- a/arch/powerpc/platforms/ps3/device-init.c -+++ b/arch/powerpc/platforms/ps3/device-init.c -@@ -752,7 +752,7 @@ static int ps3_notification_read_write(struct ps3_notification_device *dev, - } - pr_debug("%s:%u: notification %s issued\n", __func__, __LINE__, op); - -- res = wait_event_interruptible(dev->done.wait, -+ res = swait_event_interruptible(dev->done.wait, - dev->done.done || kthread_should_stop()); - if (kthread_should_stop()) - res = -EINTR; -diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c -index 6c0378c..abd58b4 100644 ---- a/arch/sh/kernel/irq.c -+++ b/arch/sh/kernel/irq.c -@@ -147,6 +147,7 @@ void irq_ctx_exit(int cpu) - hardirq_ctx[cpu] = NULL; - } - -+#ifndef CONFIG_PREEMPT_RT_FULL - void do_softirq_own_stack(void) - { - struct thread_info *curctx; -@@ -174,6 +175,7 @@ void do_softirq_own_stack(void) - "r5", "r6", "r7", "r8", "r9", "r15", "t", "pr" - ); - } -+#endif - #else - static inline void handle_one_irq(unsigned int irq) - { -diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig -index 57ffaf2..733c728 100644 ---- a/arch/sparc/Kconfig -+++ b/arch/sparc/Kconfig -@@ -184,12 +184,10 @@ config NR_CPUS - source kernel/Kconfig.hz - - config RWSEM_GENERIC_SPINLOCK -- bool -- default y if SPARC32 -+ def_bool PREEMPT_RT_FULL - - config RWSEM_XCHGADD_ALGORITHM -- bool -- default y if SPARC64 -+ def_bool !RWSEM_GENERIC_SPINLOCK && !PREEMPT_RT_FULL - - config GENERIC_HWEIGHT - bool -diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c -index e22416c..d359de7 100644 ---- a/arch/sparc/kernel/irq_64.c -+++ b/arch/sparc/kernel/irq_64.c -@@ -854,6 +854,7 @@ void __irq_entry handler_irq(int pil, struct pt_regs *regs) - set_irq_regs(old_regs); - } - -+#ifndef CONFIG_PREEMPT_RT_FULL - void do_softirq_own_stack(void) - { - void *orig_sp, *sp = softirq_stack[smp_processor_id()]; -@@ -868,6 +869,7 @@ void do_softirq_own_stack(void) - __asm__ __volatile__("mov %0, %%sp" - : : "r" (orig_sp)); - } -+#endif - - #ifdef CONFIG_HOTPLUG_CPU - void fixup_irqs(void) -diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig -index 2dc18605..ea65dc7 100644 ---- a/arch/x86/Kconfig -+++ b/arch/x86/Kconfig -@@ -17,6 +17,7 @@ config X86_64 - ### Arch settings - config X86 - def_bool y -+ select HAVE_PREEMPT_LAZY - select ACPI_LEGACY_TABLES_LOOKUP if ACPI - select ACPI_SYSTEM_POWER_STATES_SUPPORT if ACPI - select ANON_INODES -@@ -230,8 +231,11 @@ config ARCH_MAY_HAVE_PC_FDC - def_bool y - depends on ISA_DMA_API - -+config RWSEM_GENERIC_SPINLOCK -+ def_bool PREEMPT_RT_FULL -+ - config RWSEM_XCHGADD_ALGORITHM -- def_bool y -+ def_bool !RWSEM_GENERIC_SPINLOCK && !PREEMPT_RT_FULL - - config GENERIC_CALIBRATE_DELAY - def_bool y -@@ -889,7 +893,7 @@ config IOMMU_HELPER - config MAXSMP - bool "Enable Maximum number of SMP Processors and NUMA Nodes" - depends on X86_64 && SMP && DEBUG_KERNEL -- select CPUMASK_OFFSTACK -+ select CPUMASK_OFFSTACK if !PREEMPT_RT_FULL - ---help--- - Enable maximum number of CPUS and NUMA Nodes for this architecture. - If unsure, say N. -diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c -index 064c7e2..e400dd3 100644 ---- a/arch/x86/crypto/aesni-intel_glue.c -+++ b/arch/x86/crypto/aesni-intel_glue.c -@@ -383,14 +383,14 @@ static int ecb_encrypt(struct blkcipher_desc *desc, - err = blkcipher_walk_virt(desc, &walk); - desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; - -- kernel_fpu_begin(); - while ((nbytes = walk.nbytes)) { -+ kernel_fpu_begin(); - aesni_ecb_enc(ctx, walk.dst.virt.addr, walk.src.virt.addr, -- nbytes & AES_BLOCK_MASK); -+ nbytes & AES_BLOCK_MASK); -+ kernel_fpu_end(); - nbytes &= AES_BLOCK_SIZE - 1; - err = blkcipher_walk_done(desc, &walk, nbytes); - } -- kernel_fpu_end(); - - return err; - } -@@ -407,14 +407,14 @@ static int ecb_decrypt(struct blkcipher_desc *desc, - err = blkcipher_walk_virt(desc, &walk); - desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; - -- kernel_fpu_begin(); - while ((nbytes = walk.nbytes)) { -+ kernel_fpu_begin(); - aesni_ecb_dec(ctx, walk.dst.virt.addr, walk.src.virt.addr, - nbytes & AES_BLOCK_MASK); -+ kernel_fpu_end(); - nbytes &= AES_BLOCK_SIZE - 1; - err = blkcipher_walk_done(desc, &walk, nbytes); - } -- kernel_fpu_end(); - - return err; - } -@@ -431,14 +431,14 @@ static int cbc_encrypt(struct blkcipher_desc *desc, - err = blkcipher_walk_virt(desc, &walk); - desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; - -- kernel_fpu_begin(); - while ((nbytes = walk.nbytes)) { -+ kernel_fpu_begin(); - aesni_cbc_enc(ctx, walk.dst.virt.addr, walk.src.virt.addr, - nbytes & AES_BLOCK_MASK, walk.iv); -+ kernel_fpu_end(); - nbytes &= AES_BLOCK_SIZE - 1; - err = blkcipher_walk_done(desc, &walk, nbytes); - } -- kernel_fpu_end(); - - return err; - } -@@ -455,14 +455,14 @@ static int cbc_decrypt(struct blkcipher_desc *desc, - err = blkcipher_walk_virt(desc, &walk); - desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; - -- kernel_fpu_begin(); - while ((nbytes = walk.nbytes)) { -+ kernel_fpu_begin(); - aesni_cbc_dec(ctx, walk.dst.virt.addr, walk.src.virt.addr, - nbytes & AES_BLOCK_MASK, walk.iv); -+ kernel_fpu_end(); - nbytes &= AES_BLOCK_SIZE - 1; - err = blkcipher_walk_done(desc, &walk, nbytes); - } -- kernel_fpu_end(); - - return err; - } -@@ -514,18 +514,20 @@ static int ctr_crypt(struct blkcipher_desc *desc, - err = blkcipher_walk_virt_block(desc, &walk, AES_BLOCK_SIZE); - desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; - -- kernel_fpu_begin(); - while ((nbytes = walk.nbytes) >= AES_BLOCK_SIZE) { -+ kernel_fpu_begin(); - aesni_ctr_enc_tfm(ctx, walk.dst.virt.addr, walk.src.virt.addr, - nbytes & AES_BLOCK_MASK, walk.iv); -+ kernel_fpu_end(); - nbytes &= AES_BLOCK_SIZE - 1; - err = blkcipher_walk_done(desc, &walk, nbytes); - } - if (walk.nbytes) { -+ kernel_fpu_begin(); - ctr_crypt_final(ctx, &walk); -+ kernel_fpu_end(); - err = blkcipher_walk_done(desc, &walk, 0); - } -- kernel_fpu_end(); - - return err; - } -diff --git a/arch/x86/crypto/cast5_avx_glue.c b/arch/x86/crypto/cast5_avx_glue.c -index 8648158..d769913 100644 ---- a/arch/x86/crypto/cast5_avx_glue.c -+++ b/arch/x86/crypto/cast5_avx_glue.c -@@ -59,7 +59,7 @@ static inline void cast5_fpu_end(bool fpu_enabled) - static int ecb_crypt(struct blkcipher_desc *desc, struct blkcipher_walk *walk, - bool enc) - { -- bool fpu_enabled = false; -+ bool fpu_enabled; - struct cast5_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); - const unsigned int bsize = CAST5_BLOCK_SIZE; - unsigned int nbytes; -@@ -75,7 +75,7 @@ static int ecb_crypt(struct blkcipher_desc *desc, struct blkcipher_walk *walk, - u8 *wsrc = walk->src.virt.addr; - u8 *wdst = walk->dst.virt.addr; - -- fpu_enabled = cast5_fpu_begin(fpu_enabled, nbytes); -+ fpu_enabled = cast5_fpu_begin(false, nbytes); - - /* Process multi-block batch */ - if (nbytes >= bsize * CAST5_PARALLEL_BLOCKS) { -@@ -103,10 +103,9 @@ static int ecb_crypt(struct blkcipher_desc *desc, struct blkcipher_walk *walk, - } while (nbytes >= bsize); - - done: -+ cast5_fpu_end(fpu_enabled); - err = blkcipher_walk_done(desc, walk, nbytes); - } -- -- cast5_fpu_end(fpu_enabled); - return err; - } - -@@ -227,7 +226,7 @@ done: - static int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, - struct scatterlist *src, unsigned int nbytes) - { -- bool fpu_enabled = false; -+ bool fpu_enabled; - struct blkcipher_walk walk; - int err; - -@@ -236,12 +235,11 @@ static int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, - desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; - - while ((nbytes = walk.nbytes)) { -- fpu_enabled = cast5_fpu_begin(fpu_enabled, nbytes); -+ fpu_enabled = cast5_fpu_begin(false, nbytes); - nbytes = __cbc_decrypt(desc, &walk); -+ cast5_fpu_end(fpu_enabled); - err = blkcipher_walk_done(desc, &walk, nbytes); - } -- -- cast5_fpu_end(fpu_enabled); - return err; - } - -@@ -311,7 +309,7 @@ done: - static int ctr_crypt(struct blkcipher_desc *desc, struct scatterlist *dst, - struct scatterlist *src, unsigned int nbytes) - { -- bool fpu_enabled = false; -+ bool fpu_enabled; - struct blkcipher_walk walk; - int err; - -@@ -320,13 +318,12 @@ static int ctr_crypt(struct blkcipher_desc *desc, struct scatterlist *dst, - desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; - - while ((nbytes = walk.nbytes) >= CAST5_BLOCK_SIZE) { -- fpu_enabled = cast5_fpu_begin(fpu_enabled, nbytes); -+ fpu_enabled = cast5_fpu_begin(false, nbytes); - nbytes = __ctr_crypt(desc, &walk); -+ cast5_fpu_end(fpu_enabled); - err = blkcipher_walk_done(desc, &walk, nbytes); - } - -- cast5_fpu_end(fpu_enabled); -- - if (walk.nbytes) { - ctr_crypt_final(desc, &walk); - err = blkcipher_walk_done(desc, &walk, 0); -diff --git a/arch/x86/crypto/glue_helper.c b/arch/x86/crypto/glue_helper.c -index 6a85598..3a506ce 100644 ---- a/arch/x86/crypto/glue_helper.c -+++ b/arch/x86/crypto/glue_helper.c -@@ -39,7 +39,7 @@ static int __glue_ecb_crypt_128bit(const struct common_glue_ctx *gctx, - void *ctx = crypto_blkcipher_ctx(desc->tfm); - const unsigned int bsize = 128 / 8; - unsigned int nbytes, i, func_bytes; -- bool fpu_enabled = false; -+ bool fpu_enabled; - int err; - - err = blkcipher_walk_virt(desc, walk); -@@ -49,7 +49,7 @@ static int __glue_ecb_crypt_128bit(const struct common_glue_ctx *gctx, - u8 *wdst = walk->dst.virt.addr; - - fpu_enabled = glue_fpu_begin(bsize, gctx->fpu_blocks_limit, -- desc, fpu_enabled, nbytes); -+ desc, false, nbytes); - - for (i = 0; i < gctx->num_funcs; i++) { - func_bytes = bsize * gctx->funcs[i].num_blocks; -@@ -71,10 +71,10 @@ static int __glue_ecb_crypt_128bit(const struct common_glue_ctx *gctx, - } - - done: -+ glue_fpu_end(fpu_enabled); - err = blkcipher_walk_done(desc, walk, nbytes); - } - -- glue_fpu_end(fpu_enabled); - return err; - } - -@@ -194,7 +194,7 @@ int glue_cbc_decrypt_128bit(const struct common_glue_ctx *gctx, - struct scatterlist *src, unsigned int nbytes) - { - const unsigned int bsize = 128 / 8; -- bool fpu_enabled = false; -+ bool fpu_enabled; - struct blkcipher_walk walk; - int err; - -@@ -203,12 +203,12 @@ int glue_cbc_decrypt_128bit(const struct common_glue_ctx *gctx, - - while ((nbytes = walk.nbytes)) { - fpu_enabled = glue_fpu_begin(bsize, gctx->fpu_blocks_limit, -- desc, fpu_enabled, nbytes); -+ desc, false, nbytes); - nbytes = __glue_cbc_decrypt_128bit(gctx, desc, &walk); -+ glue_fpu_end(fpu_enabled); - err = blkcipher_walk_done(desc, &walk, nbytes); - } - -- glue_fpu_end(fpu_enabled); - return err; - } - EXPORT_SYMBOL_GPL(glue_cbc_decrypt_128bit); -@@ -277,7 +277,7 @@ int glue_ctr_crypt_128bit(const struct common_glue_ctx *gctx, - struct scatterlist *src, unsigned int nbytes) - { - const unsigned int bsize = 128 / 8; -- bool fpu_enabled = false; -+ bool fpu_enabled; - struct blkcipher_walk walk; - int err; - -@@ -286,13 +286,12 @@ int glue_ctr_crypt_128bit(const struct common_glue_ctx *gctx, - - while ((nbytes = walk.nbytes) >= bsize) { - fpu_enabled = glue_fpu_begin(bsize, gctx->fpu_blocks_limit, -- desc, fpu_enabled, nbytes); -+ desc, false, nbytes); - nbytes = __glue_ctr_crypt_128bit(gctx, desc, &walk); -+ glue_fpu_end(fpu_enabled); - err = blkcipher_walk_done(desc, &walk, nbytes); - } - -- glue_fpu_end(fpu_enabled); -- - if (walk.nbytes) { - glue_ctr_crypt_final_128bit( - gctx->funcs[gctx->num_funcs - 1].fn_u.ctr, desc, &walk); -@@ -347,7 +346,7 @@ int glue_xts_crypt_128bit(const struct common_glue_ctx *gctx, - void *tweak_ctx, void *crypt_ctx) - { - const unsigned int bsize = 128 / 8; -- bool fpu_enabled = false; -+ bool fpu_enabled; - struct blkcipher_walk walk; - int err; - -@@ -360,21 +359,21 @@ int glue_xts_crypt_128bit(const struct common_glue_ctx *gctx, - - /* set minimum length to bsize, for tweak_fn */ - fpu_enabled = glue_fpu_begin(bsize, gctx->fpu_blocks_limit, -- desc, fpu_enabled, -+ desc, false, - nbytes < bsize ? bsize : nbytes); -- - /* calculate first value of T */ - tweak_fn(tweak_ctx, walk.iv, walk.iv); -+ glue_fpu_end(fpu_enabled); - - while (nbytes) { -+ fpu_enabled = glue_fpu_begin(bsize, gctx->fpu_blocks_limit, -+ desc, false, nbytes); - nbytes = __glue_xts_crypt_128bit(gctx, crypt_ctx, desc, &walk); - -+ glue_fpu_end(fpu_enabled); - err = blkcipher_walk_done(desc, &walk, nbytes); - nbytes = walk.nbytes; - } -- -- glue_fpu_end(fpu_enabled); -- - return err; - } - EXPORT_SYMBOL_GPL(glue_xts_crypt_128bit); -diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c -index e79d93d..ef2564d 100644 ---- a/arch/x86/entry/common.c -+++ b/arch/x86/entry/common.c -@@ -202,7 +202,7 @@ long syscall_trace_enter(struct pt_regs *regs) - - #define EXIT_TO_USERMODE_LOOP_FLAGS \ - (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_UPROBE | \ -- _TIF_NEED_RESCHED | _TIF_USER_RETURN_NOTIFY) -+ _TIF_NEED_RESCHED_MASK | _TIF_USER_RETURN_NOTIFY) - - static void exit_to_usermode_loop(struct pt_regs *regs, u32 cached_flags) - { -@@ -218,9 +218,16 @@ static void exit_to_usermode_loop(struct pt_regs *regs, u32 cached_flags) - /* We have work to do. */ - local_irq_enable(); - -- if (cached_flags & _TIF_NEED_RESCHED) -+ if (cached_flags & _TIF_NEED_RESCHED_MASK) - schedule(); - -+#ifdef ARCH_RT_DELAYS_SIGNAL_SEND -+ if (unlikely(current->forced_info.si_signo)) { -+ struct task_struct *t = current; -+ force_sig_info(t->forced_info.si_signo, &t->forced_info, t); -+ t->forced_info.si_signo = 0; -+ } -+#endif - if (cached_flags & _TIF_UPROBE) - uprobe_notify_resume(regs); - -diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S -index 10868aa..7c7d308 100644 ---- a/arch/x86/entry/entry_32.S -+++ b/arch/x86/entry/entry_32.S -@@ -278,8 +278,24 @@ END(ret_from_exception) - ENTRY(resume_kernel) - DISABLE_INTERRUPTS(CLBR_ANY) - need_resched: -+ # preempt count == 0 + NEED_RS set? - cmpl $0, PER_CPU_VAR(__preempt_count) -+#ifndef CONFIG_PREEMPT_LAZY - jnz restore_all -+#else -+ jz test_int_off -+ -+ # atleast preempt count == 0 ? -+ cmpl $_PREEMPT_ENABLED,PER_CPU_VAR(__preempt_count) -+ jne restore_all -+ -+ cmpl $0,TI_preempt_lazy_count(%ebp) # non-zero preempt_lazy_count ? -+ jnz restore_all -+ -+ testl $_TIF_NEED_RESCHED_LAZY, TI_flags(%ebp) -+ jz restore_all -+test_int_off: -+#endif - testl $X86_EFLAGS_IF, PT_EFLAGS(%esp) # interrupts off (exception path) ? - jz restore_all - call preempt_schedule_irq -diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S -index 858b555..a93639d 100644 ---- a/arch/x86/entry/entry_64.S -+++ b/arch/x86/entry/entry_64.S -@@ -511,7 +511,23 @@ retint_kernel: - bt $9, EFLAGS(%rsp) /* were interrupts off? */ - jnc 1f - 0: cmpl $0, PER_CPU_VAR(__preempt_count) -+#ifndef CONFIG_PREEMPT_LAZY - jnz 1f -+#else -+ jz do_preempt_schedule_irq -+ -+ # atleast preempt count == 0 ? -+ cmpl $_PREEMPT_ENABLED,PER_CPU_VAR(__preempt_count) -+ jnz 1f -+ -+ GET_THREAD_INFO(%rcx) -+ cmpl $0, TI_preempt_lazy_count(%rcx) -+ jnz 1f -+ -+ bt $TIF_NEED_RESCHED_LAZY,TI_flags(%rcx) -+ jnc 1f -+do_preempt_schedule_irq: -+#endif - call preempt_schedule_irq - jmp 0b - 1: -@@ -799,6 +815,7 @@ bad_gs: - jmp 2b - .previous - -+#ifndef CONFIG_PREEMPT_RT_FULL - /* Call softirq on interrupt stack. Interrupts are off. */ - ENTRY(do_softirq_own_stack) - pushq %rbp -@@ -811,6 +828,7 @@ ENTRY(do_softirq_own_stack) - decl PER_CPU_VAR(irq_count) - ret - END(do_softirq_own_stack) -+#endif - - #ifdef CONFIG_XEN - idtentry xen_hypervisor_callback xen_do_hypervisor_callback has_error_code=0 -diff --git a/arch/x86/include/asm/preempt.h b/arch/x86/include/asm/preempt.h -index d397deb..190af42 100644 ---- a/arch/x86/include/asm/preempt.h -+++ b/arch/x86/include/asm/preempt.h -@@ -79,17 +79,33 @@ static __always_inline void __preempt_count_sub(int val) - * a decrement which hits zero means we have no preempt_count and should - * reschedule. - */ --static __always_inline bool __preempt_count_dec_and_test(void) -+static __always_inline bool ____preempt_count_dec_and_test(void) - { - GEN_UNARY_RMWcc("decl", __preempt_count, __percpu_arg(0), "e"); - } - -+static __always_inline bool __preempt_count_dec_and_test(void) -+{ -+ if (____preempt_count_dec_and_test()) -+ return true; -+#ifdef CONFIG_PREEMPT_LAZY -+ return test_thread_flag(TIF_NEED_RESCHED_LAZY); -+#else -+ return false; -+#endif -+} -+ - /* - * Returns true when we need to resched and can (barring IRQ state). - */ - static __always_inline bool should_resched(int preempt_offset) - { -+#ifdef CONFIG_PREEMPT_LAZY -+ return unlikely(raw_cpu_read_4(__preempt_count) == preempt_offset || -+ test_thread_flag(TIF_NEED_RESCHED_LAZY)); -+#else - return unlikely(raw_cpu_read_4(__preempt_count) == preempt_offset); -+#endif - } - - #ifdef CONFIG_PREEMPT -diff --git a/arch/x86/include/asm/signal.h b/arch/x86/include/asm/signal.h -index 2138c9a..3f5b4ee 100644 ---- a/arch/x86/include/asm/signal.h -+++ b/arch/x86/include/asm/signal.h -@@ -23,6 +23,19 @@ typedef struct { - unsigned long sig[_NSIG_WORDS]; - } sigset_t; - -+/* -+ * Because some traps use the IST stack, we must keep preemption -+ * disabled while calling do_trap(), but do_trap() may call -+ * force_sig_info() which will grab the signal spin_locks for the -+ * task, which in PREEMPT_RT_FULL are mutexes. By defining -+ * ARCH_RT_DELAYS_SIGNAL_SEND the force_sig_info() will set -+ * TIF_NOTIFY_RESUME and set up the signal to be sent on exit of the -+ * trap. -+ */ -+#if defined(CONFIG_PREEMPT_RT_FULL) -+#define ARCH_RT_DELAYS_SIGNAL_SEND -+#endif -+ - #ifndef CONFIG_COMPAT - typedef sigset_t compat_sigset_t; - #endif -diff --git a/arch/x86/include/asm/stackprotector.h b/arch/x86/include/asm/stackprotector.h -index 58505f0..02fa396 100644 ---- a/arch/x86/include/asm/stackprotector.h -+++ b/arch/x86/include/asm/stackprotector.h -@@ -59,7 +59,7 @@ - */ - static __always_inline void boot_init_stack_canary(void) - { -- u64 canary; -+ u64 uninitialized_var(canary); - u64 tsc; - - #ifdef CONFIG_X86_64 -@@ -70,8 +70,15 @@ static __always_inline void boot_init_stack_canary(void) - * of randomness. The TSC only matters for very early init, - * there it already has some randomness on most systems. Later - * on during the bootup the random pool has true entropy too. -+ * -+ * For preempt-rt we need to weaken the randomness a bit, as -+ * we can't call into the random generator from atomic context -+ * due to locking constraints. We just leave canary -+ * uninitialized and use the TSC based randomness on top of it. - */ -+#ifndef CONFIG_PREEMPT_RT_FULL - get_random_bytes(&canary, sizeof(canary)); -+#endif - tsc = rdtsc(); - canary += tsc + (tsc << 32UL); - -diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h -index ffae84d..b4575ba 100644 ---- a/arch/x86/include/asm/thread_info.h -+++ b/arch/x86/include/asm/thread_info.h -@@ -58,6 +58,8 @@ struct thread_info { - __u32 status; /* thread synchronous flags */ - __u32 cpu; /* current CPU */ - mm_segment_t addr_limit; -+ int preempt_lazy_count; /* 0 => lazy preemptable -+ <0 => BUG */ - unsigned int sig_on_uaccess_error:1; - unsigned int uaccess_err:1; /* uaccess failed */ - }; -@@ -95,6 +97,7 @@ struct thread_info { - #define TIF_SYSCALL_EMU 6 /* syscall emulation active */ - #define TIF_SYSCALL_AUDIT 7 /* syscall auditing active */ - #define TIF_SECCOMP 8 /* secure computing */ -+#define TIF_NEED_RESCHED_LAZY 9 /* lazy rescheduling necessary */ - #define TIF_USER_RETURN_NOTIFY 11 /* notify kernel of userspace return */ - #define TIF_UPROBE 12 /* breakpointed or singlestepping */ - #define TIF_NOTSC 16 /* TSC is not accessible in userland */ -@@ -119,6 +122,7 @@ struct thread_info { - #define _TIF_SYSCALL_EMU (1 << TIF_SYSCALL_EMU) - #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) - #define _TIF_SECCOMP (1 << TIF_SECCOMP) -+#define _TIF_NEED_RESCHED_LAZY (1 << TIF_NEED_RESCHED_LAZY) - #define _TIF_USER_RETURN_NOTIFY (1 << TIF_USER_RETURN_NOTIFY) - #define _TIF_UPROBE (1 << TIF_UPROBE) - #define _TIF_NOTSC (1 << TIF_NOTSC) -@@ -155,6 +159,8 @@ struct thread_info { - #define _TIF_WORK_CTXSW_PREV (_TIF_WORK_CTXSW|_TIF_USER_RETURN_NOTIFY) - #define _TIF_WORK_CTXSW_NEXT (_TIF_WORK_CTXSW) - -+#define _TIF_NEED_RESCHED_MASK (_TIF_NEED_RESCHED | _TIF_NEED_RESCHED_LAZY) -+ - #define STACK_WARN (THREAD_SIZE/8) - - /* -diff --git a/arch/x86/include/asm/uv/uv_bau.h b/arch/x86/include/asm/uv/uv_bau.h -index fc808b8..ebb4011 100644 ---- a/arch/x86/include/asm/uv/uv_bau.h -+++ b/arch/x86/include/asm/uv/uv_bau.h -@@ -615,9 +615,9 @@ struct bau_control { - cycles_t send_message; - cycles_t period_end; - cycles_t period_time; -- spinlock_t uvhub_lock; -- spinlock_t queue_lock; -- spinlock_t disable_lock; -+ raw_spinlock_t uvhub_lock; -+ raw_spinlock_t queue_lock; -+ raw_spinlock_t disable_lock; - /* tunables */ - int max_concurr; - int max_concurr_const; -@@ -776,15 +776,15 @@ static inline int atom_asr(short i, struct atomic_short *v) - * to be lowered below the current 'v'. atomic_add_unless can only stop - * on equal. - */ --static inline int atomic_inc_unless_ge(spinlock_t *lock, atomic_t *v, int u) -+static inline int atomic_inc_unless_ge(raw_spinlock_t *lock, atomic_t *v, int u) - { -- spin_lock(lock); -+ raw_spin_lock(lock); - if (atomic_read(v) >= u) { -- spin_unlock(lock); -+ raw_spin_unlock(lock); - return 0; - } - atomic_inc(v); -- spin_unlock(lock); -+ raw_spin_unlock(lock); - return 1; - } - -diff --git a/arch/x86/include/asm/uv/uv_hub.h b/arch/x86/include/asm/uv/uv_hub.h -index ea707478..01ec643 100644 ---- a/arch/x86/include/asm/uv/uv_hub.h -+++ b/arch/x86/include/asm/uv/uv_hub.h -@@ -492,7 +492,7 @@ struct uv_blade_info { - unsigned short nr_online_cpus; - unsigned short pnode; - short memory_nid; -- spinlock_t nmi_lock; /* obsolete, see uv_hub_nmi */ -+ raw_spinlock_t nmi_lock; /* obsolete, see uv_hub_nmi */ - unsigned long nmi_count; /* obsolete, see uv_hub_nmi */ - }; - extern struct uv_blade_info *uv_blade_info; -diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c -index fdb0fbf..678c711 100644 ---- a/arch/x86/kernel/apic/io_apic.c -+++ b/arch/x86/kernel/apic/io_apic.c -@@ -1711,7 +1711,8 @@ static bool io_apic_level_ack_pending(struct mp_chip_data *data) - static inline bool ioapic_irqd_mask(struct irq_data *data) - { - /* If we are moving the irq we need to mask it */ -- if (unlikely(irqd_is_setaffinity_pending(data))) { -+ if (unlikely(irqd_is_setaffinity_pending(data) && -+ !irqd_irq_inprogress(data))) { - mask_ioapic_irq(data); - return true; - } -diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c -index d7ce96a..57773fd 100644 ---- a/arch/x86/kernel/apic/x2apic_uv_x.c -+++ b/arch/x86/kernel/apic/x2apic_uv_x.c -@@ -950,7 +950,7 @@ void __init uv_system_init(void) - uv_blade_info[blade].pnode = pnode; - uv_blade_info[blade].nr_possible_cpus = 0; - uv_blade_info[blade].nr_online_cpus = 0; -- spin_lock_init(&uv_blade_info[blade].nmi_lock); -+ raw_spin_lock_init(&uv_blade_info[blade].nmi_lock); - min_pnode = min(pnode, min_pnode); - max_pnode = max(pnode, max_pnode); - blade++; -diff --git a/arch/x86/kernel/asm-offsets.c b/arch/x86/kernel/asm-offsets.c -index 5c04246..ea558b0 100644 ---- a/arch/x86/kernel/asm-offsets.c -+++ b/arch/x86/kernel/asm-offsets.c -@@ -32,6 +32,7 @@ void common(void) { - OFFSET(TI_flags, thread_info, flags); - OFFSET(TI_status, thread_info, status); - OFFSET(TI_addr_limit, thread_info, addr_limit); -+ OFFSET(TI_preempt_lazy_count, thread_info, preempt_lazy_count); - - BLANK(); - OFFSET(crypto_tfm_ctx_offset, crypto_tfm, __crt_ctx); -@@ -85,4 +86,5 @@ void common(void) { - - BLANK(); - DEFINE(PTREGS_SIZE, sizeof(struct pt_regs)); -+ DEFINE(_PREEMPT_ENABLED, PREEMPT_ENABLED); - } -diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c -index f0c921b..48aec5d 100644 ---- a/arch/x86/kernel/cpu/mcheck/mce.c -+++ b/arch/x86/kernel/cpu/mcheck/mce.c -@@ -41,6 +41,8 @@ - #include <linux/debugfs.h> - #include <linux/irq_work.h> - #include <linux/export.h> -+#include <linux/jiffies.h> -+#include <linux/work-simple.h> - - #include <asm/processor.h> - #include <asm/traps.h> -@@ -1240,7 +1242,7 @@ void mce_log_therm_throt_event(__u64 status) - static unsigned long check_interval = INITIAL_CHECK_INTERVAL; - - static DEFINE_PER_CPU(unsigned long, mce_next_interval); /* in jiffies */ --static DEFINE_PER_CPU(struct timer_list, mce_timer); -+static DEFINE_PER_CPU(struct hrtimer, mce_timer); - - static unsigned long mce_adjust_timer_default(unsigned long interval) - { -@@ -1249,32 +1251,18 @@ static unsigned long mce_adjust_timer_default(unsigned long interval) - - static unsigned long (*mce_adjust_timer)(unsigned long interval) = mce_adjust_timer_default; - --static void __restart_timer(struct timer_list *t, unsigned long interval) -+static enum hrtimer_restart __restart_timer(struct hrtimer *timer, unsigned long interval) - { -- unsigned long when = jiffies + interval; -- unsigned long flags; -- -- local_irq_save(flags); -- -- if (timer_pending(t)) { -- if (time_before(when, t->expires)) -- mod_timer_pinned(t, when); -- } else { -- t->expires = round_jiffies(when); -- add_timer_on(t, smp_processor_id()); -- } -- -- local_irq_restore(flags); -+ if (!interval) -+ return HRTIMER_NORESTART; -+ hrtimer_forward_now(timer, ns_to_ktime(jiffies_to_nsecs(interval))); -+ return HRTIMER_RESTART; - } - --static void mce_timer_fn(unsigned long data) -+static enum hrtimer_restart mce_timer_fn(struct hrtimer *timer) - { -- struct timer_list *t = this_cpu_ptr(&mce_timer); -- int cpu = smp_processor_id(); - unsigned long iv; - -- WARN_ON(cpu != data); -- - iv = __this_cpu_read(mce_next_interval); - - if (mce_available(this_cpu_ptr(&cpu_info))) { -@@ -1297,7 +1285,7 @@ static void mce_timer_fn(unsigned long data) - - done: - __this_cpu_write(mce_next_interval, iv); -- __restart_timer(t, iv); -+ return __restart_timer(timer, iv); - } - - /* -@@ -1305,7 +1293,7 @@ done: - */ - void mce_timer_kick(unsigned long interval) - { -- struct timer_list *t = this_cpu_ptr(&mce_timer); -+ struct hrtimer *t = this_cpu_ptr(&mce_timer); - unsigned long iv = __this_cpu_read(mce_next_interval); - - __restart_timer(t, interval); -@@ -1320,7 +1308,7 @@ static void mce_timer_delete_all(void) - int cpu; - - for_each_online_cpu(cpu) -- del_timer_sync(&per_cpu(mce_timer, cpu)); -+ hrtimer_cancel(&per_cpu(mce_timer, cpu)); - } - - static void mce_do_trigger(struct work_struct *work) -@@ -1330,6 +1318,56 @@ static void mce_do_trigger(struct work_struct *work) - - static DECLARE_WORK(mce_trigger_work, mce_do_trigger); - -+static void __mce_notify_work(struct swork_event *event) -+{ -+ /* Not more than two messages every minute */ -+ static DEFINE_RATELIMIT_STATE(ratelimit, 60*HZ, 2); -+ -+ /* wake processes polling /dev/mcelog */ -+ wake_up_interruptible(&mce_chrdev_wait); -+ -+ /* -+ * There is no risk of missing notifications because -+ * work_pending is always cleared before the function is -+ * executed. -+ */ -+ if (mce_helper[0] && !work_pending(&mce_trigger_work)) -+ schedule_work(&mce_trigger_work); -+ -+ if (__ratelimit(&ratelimit)) -+ pr_info(HW_ERR "Machine check events logged\n"); -+} -+ -+#ifdef CONFIG_PREEMPT_RT_FULL -+static bool notify_work_ready __read_mostly; -+static struct swork_event notify_work; -+ -+static int mce_notify_work_init(void) -+{ -+ int err; -+ -+ err = swork_get(); -+ if (err) -+ return err; -+ -+ INIT_SWORK(¬ify_work, __mce_notify_work); -+ notify_work_ready = true; -+ return 0; -+} -+ -+static void mce_notify_work(void) -+{ -+ if (notify_work_ready) -+ swork_queue(¬ify_work); -+} -+#else -+static void mce_notify_work(void) -+{ -+ __mce_notify_work(NULL); -+} -+static inline int mce_notify_work_init(void) { return 0; } -+#endif -+ - /* - * Notify the user(s) about new machine check events. - * Can be called from interrupt context, but not from machine check/NMI -@@ -1337,19 +1375,8 @@ static DECLARE_WORK(mce_trigger_work, mce_do_trigger); - */ - int mce_notify_irq(void) - { -- /* Not more than two messages every minute */ -- static DEFINE_RATELIMIT_STATE(ratelimit, 60*HZ, 2); -- - if (test_and_clear_bit(0, &mce_need_notify)) { -- /* wake processes polling /dev/mcelog */ -- wake_up_interruptible(&mce_chrdev_wait); -- -- if (mce_helper[0]) -- schedule_work(&mce_trigger_work); -- -- if (__ratelimit(&ratelimit)) -- pr_info(HW_ERR "Machine check events logged\n"); -- -+ mce_notify_work(); - return 1; - } - return 0; -@@ -1654,7 +1681,7 @@ static void __mcheck_cpu_clear_vendor(struct cpuinfo_x86 *c) - } - } - --static void mce_start_timer(unsigned int cpu, struct timer_list *t) -+static void mce_start_timer(unsigned int cpu, struct hrtimer *t) - { - unsigned long iv = check_interval * HZ; - -@@ -1663,16 +1690,17 @@ static void mce_start_timer(unsigned int cpu, struct timer_list *t) - - per_cpu(mce_next_interval, cpu) = iv; - -- t->expires = round_jiffies(jiffies + iv); -- add_timer_on(t, cpu); -+ hrtimer_start_range_ns(t, ns_to_ktime(jiffies_to_usecs(iv) * 1000ULL), -+ 0, HRTIMER_MODE_REL_PINNED); - } - - static void __mcheck_cpu_init_timer(void) - { -- struct timer_list *t = this_cpu_ptr(&mce_timer); -+ struct hrtimer *t = this_cpu_ptr(&mce_timer); - unsigned int cpu = smp_processor_id(); - -- setup_timer(t, mce_timer_fn, cpu); -+ hrtimer_init(t, CLOCK_MONOTONIC, HRTIMER_MODE_REL); -+ t->function = mce_timer_fn; - mce_start_timer(cpu, t); - } - -@@ -2393,6 +2421,8 @@ static void mce_disable_cpu(void *h) - if (!mce_available(raw_cpu_ptr(&cpu_info))) - return; - -+ hrtimer_cancel(this_cpu_ptr(&mce_timer)); -+ - if (!(action & CPU_TASKS_FROZEN)) - cmci_clear(); - -@@ -2415,6 +2445,7 @@ static void mce_reenable_cpu(void *h) - if (b->init) - wrmsrl(MSR_IA32_MCx_CTL(i), b->ctl); - } -+ __mcheck_cpu_init_timer(); - } - - /* Get notified when a cpu comes on/off. Be hotplug friendly. */ -@@ -2422,7 +2453,6 @@ static int - mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) - { - unsigned int cpu = (unsigned long)hcpu; -- struct timer_list *t = &per_cpu(mce_timer, cpu); - - switch (action & ~CPU_TASKS_FROZEN) { - case CPU_ONLINE: -@@ -2442,11 +2472,9 @@ mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) - break; - case CPU_DOWN_PREPARE: - smp_call_function_single(cpu, mce_disable_cpu, &action, 1); -- del_timer_sync(t); - break; - case CPU_DOWN_FAILED: - smp_call_function_single(cpu, mce_reenable_cpu, &action, 1); -- mce_start_timer(cpu, t); - break; - } - -@@ -2485,6 +2513,10 @@ static __init int mcheck_init_device(void) - goto err_out; - } - -+ err = mce_notify_work_init(); -+ if (err) -+ goto err_out; -+ - if (!zalloc_cpumask_var(&mce_device_initialized, GFP_KERNEL)) { - err = -ENOMEM; - goto err_out; -diff --git a/arch/x86/kernel/dumpstack_32.c b/arch/x86/kernel/dumpstack_32.c -index 464ffd6..00db1aa 100644 ---- a/arch/x86/kernel/dumpstack_32.c -+++ b/arch/x86/kernel/dumpstack_32.c -@@ -42,7 +42,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, - unsigned long *stack, unsigned long bp, - const struct stacktrace_ops *ops, void *data) - { -- const unsigned cpu = get_cpu(); -+ const unsigned cpu = get_cpu_light(); - int graph = 0; - u32 *prev_esp; - -@@ -86,7 +86,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, - break; - touch_nmi_watchdog(); - } -- put_cpu(); -+ put_cpu_light(); - } - EXPORT_SYMBOL(dump_trace); - -diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c -index 5f1c626..c331e3f 100644 ---- a/arch/x86/kernel/dumpstack_64.c -+++ b/arch/x86/kernel/dumpstack_64.c -@@ -152,7 +152,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, - unsigned long *stack, unsigned long bp, - const struct stacktrace_ops *ops, void *data) - { -- const unsigned cpu = get_cpu(); -+ const unsigned cpu = get_cpu_light(); - struct thread_info *tinfo; - unsigned long *irq_stack = (unsigned long *)per_cpu(irq_stack_ptr, cpu); - unsigned long dummy; -@@ -241,7 +241,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, - * This handles the process stack: - */ - bp = ops->walk_stack(tinfo, stack, bp, ops, data, NULL, &graph); -- put_cpu(); -+ put_cpu_light(); - } - EXPORT_SYMBOL(dump_trace); - -@@ -255,7 +255,7 @@ show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, - int cpu; - int i; - -- preempt_disable(); -+ migrate_disable(); - cpu = smp_processor_id(); - - irq_stack_end = (unsigned long *)(per_cpu(irq_stack_ptr, cpu)); -@@ -291,7 +291,7 @@ show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, - pr_cont(" %016lx", *stack++); - touch_nmi_watchdog(); - } -- preempt_enable(); -+ migrate_enable(); - - pr_cont("\n"); - show_trace_log_lvl(task, regs, sp, bp, log_lvl); -diff --git a/arch/x86/kernel/irq_32.c b/arch/x86/kernel/irq_32.c -index 38da8f2..ce71f70 100644 ---- a/arch/x86/kernel/irq_32.c -+++ b/arch/x86/kernel/irq_32.c -@@ -128,6 +128,7 @@ void irq_ctx_init(int cpu) - cpu, per_cpu(hardirq_stack, cpu), per_cpu(softirq_stack, cpu)); - } - -+#ifndef CONFIG_PREEMPT_RT_FULL - void do_softirq_own_stack(void) - { - struct thread_info *curstk; -@@ -146,6 +147,7 @@ void do_softirq_own_stack(void) - - call_on_stack(__do_softirq, isp); - } -+#endif - - bool handle_irq(struct irq_desc *desc, struct pt_regs *regs) - { -diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c -index 9f95091..4dd4bea 100644 ---- a/arch/x86/kernel/process_32.c -+++ b/arch/x86/kernel/process_32.c -@@ -35,6 +35,7 @@ - #include <linux/uaccess.h> - #include <linux/io.h> - #include <linux/kdebug.h> -+#include <linux/highmem.h> - - #include <asm/pgtable.h> - #include <asm/ldt.h> -@@ -210,6 +211,35 @@ start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp) - } - EXPORT_SYMBOL_GPL(start_thread); - -+#ifdef CONFIG_PREEMPT_RT_FULL -+static void switch_kmaps(struct task_struct *prev_p, struct task_struct *next_p) -+{ -+ int i; -+ -+ /* -+ * Clear @prev's kmap_atomic mappings -+ */ -+ for (i = 0; i < prev_p->kmap_idx; i++) { -+ int idx = i + KM_TYPE_NR * smp_processor_id(); -+ pte_t *ptep = kmap_pte - idx; -+ -+ kpte_clear_flush(ptep, __fix_to_virt(FIX_KMAP_BEGIN + idx)); -+ } -+ /* -+ * Restore @next_p's kmap_atomic mappings -+ */ -+ for (i = 0; i < next_p->kmap_idx; i++) { -+ int idx = i + KM_TYPE_NR * smp_processor_id(); -+ -+ if (!pte_none(next_p->kmap_pte[i])) -+ set_pte(kmap_pte - idx, next_p->kmap_pte[i]); -+ } -+} -+#else -+static inline void -+switch_kmaps(struct task_struct *prev_p, struct task_struct *next_p) { } -+#endif -+ - - /* - * switch_to(x,y) should switch tasks from x to y. -@@ -286,6 +316,8 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) - task_thread_info(next_p)->flags & _TIF_WORK_CTXSW_NEXT)) - __switch_to_xtra(prev_p, next_p, tss); - -+ switch_kmaps(prev_p, next_p); -+ - /* - * Leave lazy mode, flushing any hypercalls made here. - * This must be done before restoring TLS segments so -diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c -index 1a2da0e..a0c78a2 100644 ---- a/arch/x86/kvm/lapic.c -+++ b/arch/x86/kvm/lapic.c -@@ -1870,6 +1870,7 @@ int kvm_create_lapic(struct kvm_vcpu *vcpu) - hrtimer_init(&apic->lapic_timer.timer, CLOCK_MONOTONIC, - HRTIMER_MODE_ABS_PINNED); - apic->lapic_timer.timer.function = apic_timer_fn; -+ apic->lapic_timer.timer.irqsafe = 1; - - /* - * APIC is created enabled. This will prevent kvm_lapic_set_base from -diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c -index 9b7798c..1dc9be8 100644 ---- a/arch/x86/kvm/x86.c -+++ b/arch/x86/kvm/x86.c -@@ -5850,6 +5850,13 @@ int kvm_arch_init(void *opaque) - goto out; - } - -+#ifdef CONFIG_PREEMPT_RT_FULL -+ if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC)) { -+ printk(KERN_ERR "RT requires X86_FEATURE_CONSTANT_TSC\n"); -+ return -EOPNOTSUPP; -+ } -+#endif -+ - r = kvm_mmu_module_init(); - if (r) - goto out_free_percpu; -diff --git a/arch/x86/mm/highmem_32.c b/arch/x86/mm/highmem_32.c -index a6d7392..bd24ba1 100644 ---- a/arch/x86/mm/highmem_32.c -+++ b/arch/x86/mm/highmem_32.c -@@ -32,10 +32,11 @@ EXPORT_SYMBOL(kunmap); - */ - void *kmap_atomic_prot(struct page *page, pgprot_t prot) - { -+ pte_t pte = mk_pte(page, prot); - unsigned long vaddr; - int idx, type; - -- preempt_disable(); -+ preempt_disable_nort(); - pagefault_disable(); - - if (!PageHighMem(page)) -@@ -45,7 +46,10 @@ void *kmap_atomic_prot(struct page *page, pgprot_t prot) - idx = type + KM_TYPE_NR*smp_processor_id(); - vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); - BUG_ON(!pte_none(*(kmap_pte-idx))); -- set_pte(kmap_pte-idx, mk_pte(page, prot)); -+#ifdef CONFIG_PREEMPT_RT_FULL -+ current->kmap_pte[type] = pte; -+#endif -+ set_pte(kmap_pte-idx, pte); - arch_flush_lazy_mmu_mode(); - - return (void *)vaddr; -@@ -88,6 +92,9 @@ void __kunmap_atomic(void *kvaddr) - * is a bad idea also, in case the page changes cacheability - * attributes or becomes a protected page in a hypervisor. - */ -+#ifdef CONFIG_PREEMPT_RT_FULL -+ current->kmap_pte[type] = __pte(0); -+#endif - kpte_clear_flush(kmap_pte-idx, vaddr); - kmap_atomic_idx_pop(); - arch_flush_lazy_mmu_mode(); -@@ -100,7 +107,7 @@ void __kunmap_atomic(void *kvaddr) - #endif - - pagefault_enable(); -- preempt_enable(); -+ preempt_enable_nort(); - } - EXPORT_SYMBOL(__kunmap_atomic); - -diff --git a/arch/x86/mm/iomap_32.c b/arch/x86/mm/iomap_32.c -index 9c0ff04..dd25dd1 100644 ---- a/arch/x86/mm/iomap_32.c -+++ b/arch/x86/mm/iomap_32.c -@@ -56,6 +56,7 @@ EXPORT_SYMBOL_GPL(iomap_free); - - void *kmap_atomic_prot_pfn(unsigned long pfn, pgprot_t prot) - { -+ pte_t pte = pfn_pte(pfn, prot); - unsigned long vaddr; - int idx, type; - -@@ -65,7 +66,12 @@ void *kmap_atomic_prot_pfn(unsigned long pfn, pgprot_t prot) - type = kmap_atomic_idx_push(); - idx = type + KM_TYPE_NR * smp_processor_id(); - vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); -- set_pte(kmap_pte - idx, pfn_pte(pfn, prot)); -+ WARN_ON(!pte_none(*(kmap_pte - idx))); -+ -+#ifdef CONFIG_PREEMPT_RT_FULL -+ current->kmap_pte[type] = pte; -+#endif -+ set_pte(kmap_pte - idx, pte); - arch_flush_lazy_mmu_mode(); - - return (void *)vaddr; -@@ -113,6 +119,9 @@ iounmap_atomic(void __iomem *kvaddr) - * is a bad idea also, in case the page changes cacheability - * attributes or becomes a protected page in a hypervisor. - */ -+#ifdef CONFIG_PREEMPT_RT_FULL -+ current->kmap_pte[type] = __pte(0); -+#endif - kpte_clear_flush(kmap_pte-idx, vaddr); - kmap_atomic_idx_pop(); - } -diff --git a/arch/x86/platform/uv/tlb_uv.c b/arch/x86/platform/uv/tlb_uv.c -index 3b6ec42..7871083 100644 ---- a/arch/x86/platform/uv/tlb_uv.c -+++ b/arch/x86/platform/uv/tlb_uv.c -@@ -714,9 +714,9 @@ static void destination_plugged(struct bau_desc *bau_desc, - - quiesce_local_uvhub(hmaster); - -- spin_lock(&hmaster->queue_lock); -+ raw_spin_lock(&hmaster->queue_lock); - reset_with_ipi(&bau_desc->distribution, bcp); -- spin_unlock(&hmaster->queue_lock); -+ raw_spin_unlock(&hmaster->queue_lock); - - end_uvhub_quiesce(hmaster); - -@@ -736,9 +736,9 @@ static void destination_timeout(struct bau_desc *bau_desc, - - quiesce_local_uvhub(hmaster); - -- spin_lock(&hmaster->queue_lock); -+ raw_spin_lock(&hmaster->queue_lock); - reset_with_ipi(&bau_desc->distribution, bcp); -- spin_unlock(&hmaster->queue_lock); -+ raw_spin_unlock(&hmaster->queue_lock); - - end_uvhub_quiesce(hmaster); - -@@ -759,7 +759,7 @@ static void disable_for_period(struct bau_control *bcp, struct ptc_stats *stat) - cycles_t tm1; - - hmaster = bcp->uvhub_master; -- spin_lock(&hmaster->disable_lock); -+ raw_spin_lock(&hmaster->disable_lock); - if (!bcp->baudisabled) { - stat->s_bau_disabled++; - tm1 = get_cycles(); -@@ -772,7 +772,7 @@ static void disable_for_period(struct bau_control *bcp, struct ptc_stats *stat) - } - } - } -- spin_unlock(&hmaster->disable_lock); -+ raw_spin_unlock(&hmaster->disable_lock); - } - - static void count_max_concurr(int stat, struct bau_control *bcp, -@@ -835,7 +835,7 @@ static void record_send_stats(cycles_t time1, cycles_t time2, - */ - static void uv1_throttle(struct bau_control *hmaster, struct ptc_stats *stat) - { -- spinlock_t *lock = &hmaster->uvhub_lock; -+ raw_spinlock_t *lock = &hmaster->uvhub_lock; - atomic_t *v; - - v = &hmaster->active_descriptor_count; -@@ -968,7 +968,7 @@ static int check_enable(struct bau_control *bcp, struct ptc_stats *stat) - struct bau_control *hmaster; - - hmaster = bcp->uvhub_master; -- spin_lock(&hmaster->disable_lock); -+ raw_spin_lock(&hmaster->disable_lock); - if (bcp->baudisabled && (get_cycles() >= bcp->set_bau_on_time)) { - stat->s_bau_reenabled++; - for_each_present_cpu(tcpu) { -@@ -980,10 +980,10 @@ static int check_enable(struct bau_control *bcp, struct ptc_stats *stat) - tbcp->period_giveups = 0; - } - } -- spin_unlock(&hmaster->disable_lock); -+ raw_spin_unlock(&hmaster->disable_lock); - return 0; - } -- spin_unlock(&hmaster->disable_lock); -+ raw_spin_unlock(&hmaster->disable_lock); - return -1; - } - -@@ -1901,9 +1901,9 @@ static void __init init_per_cpu_tunables(void) - bcp->cong_reps = congested_reps; - bcp->disabled_period = sec_2_cycles(disabled_period); - bcp->giveup_limit = giveup_limit; -- spin_lock_init(&bcp->queue_lock); -- spin_lock_init(&bcp->uvhub_lock); -- spin_lock_init(&bcp->disable_lock); -+ raw_spin_lock_init(&bcp->queue_lock); -+ raw_spin_lock_init(&bcp->uvhub_lock); -+ raw_spin_lock_init(&bcp->disable_lock); - } - } - -diff --git a/arch/x86/platform/uv/uv_time.c b/arch/x86/platform/uv/uv_time.c -index 2b158a9..5e0b122 100644 ---- a/arch/x86/platform/uv/uv_time.c -+++ b/arch/x86/platform/uv/uv_time.c -@@ -57,7 +57,7 @@ static DEFINE_PER_CPU(struct clock_event_device, cpu_ced); - - /* There is one of these allocated per node */ - struct uv_rtc_timer_head { -- spinlock_t lock; -+ raw_spinlock_t lock; - /* next cpu waiting for timer, local node relative: */ - int next_cpu; - /* number of cpus on this node: */ -@@ -177,7 +177,7 @@ static __init int uv_rtc_allocate_timers(void) - uv_rtc_deallocate_timers(); - return -ENOMEM; - } -- spin_lock_init(&head->lock); -+ raw_spin_lock_init(&head->lock); - head->ncpus = uv_blade_nr_possible_cpus(bid); - head->next_cpu = -1; - blade_info[bid] = head; -@@ -231,7 +231,7 @@ static int uv_rtc_set_timer(int cpu, u64 expires) - unsigned long flags; - int next_cpu; - -- spin_lock_irqsave(&head->lock, flags); -+ raw_spin_lock_irqsave(&head->lock, flags); - - next_cpu = head->next_cpu; - *t = expires; -@@ -243,12 +243,12 @@ static int uv_rtc_set_timer(int cpu, u64 expires) - if (uv_setup_intr(cpu, expires)) { - *t = ULLONG_MAX; - uv_rtc_find_next_timer(head, pnode); -- spin_unlock_irqrestore(&head->lock, flags); -+ raw_spin_unlock_irqrestore(&head->lock, flags); - return -ETIME; - } - } - -- spin_unlock_irqrestore(&head->lock, flags); -+ raw_spin_unlock_irqrestore(&head->lock, flags); - return 0; - } - -@@ -267,7 +267,7 @@ static int uv_rtc_unset_timer(int cpu, int force) - unsigned long flags; - int rc = 0; - -- spin_lock_irqsave(&head->lock, flags); -+ raw_spin_lock_irqsave(&head->lock, flags); - - if ((head->next_cpu == bcpu && uv_read_rtc(NULL) >= *t) || force) - rc = 1; -@@ -279,7 +279,7 @@ static int uv_rtc_unset_timer(int cpu, int force) - uv_rtc_find_next_timer(head, pnode); - } - -- spin_unlock_irqrestore(&head->lock, flags); -+ raw_spin_unlock_irqrestore(&head->lock, flags); - - return rc; - } -@@ -299,13 +299,18 @@ static int uv_rtc_unset_timer(int cpu, int force) - static cycle_t uv_read_rtc(struct clocksource *cs) - { - unsigned long offset; -+ cycle_t cycles; - -+ preempt_disable(); - if (uv_get_min_hub_revision_id() == 1) - offset = 0; - else - offset = (uv_blade_processor_id() * L1_CACHE_BYTES) % PAGE_SIZE; - -- return (cycle_t)uv_read_local_mmr(UVH_RTC | offset); -+ cycles = (cycle_t)uv_read_local_mmr(UVH_RTC | offset); -+ preempt_enable(); -+ -+ return cycles; - } - - /* -diff --git a/block/blk-core.c b/block/blk-core.c -index b60537b..b9bdc9d 100644 ---- a/block/blk-core.c -+++ b/block/blk-core.c -@@ -125,6 +125,9 @@ void blk_rq_init(struct request_queue *q, struct request *rq) - - INIT_LIST_HEAD(&rq->queuelist); - INIT_LIST_HEAD(&rq->timeout_list); -+#ifdef CONFIG_PREEMPT_RT_FULL -+ INIT_WORK(&rq->work, __blk_mq_complete_request_remote_work); -+#endif - rq->cpu = -1; - rq->q = q; - rq->__sector = (sector_t) -1; -@@ -233,7 +236,7 @@ EXPORT_SYMBOL(blk_start_queue_async); - **/ - void blk_start_queue(struct request_queue *q) - { -- WARN_ON(!irqs_disabled()); -+ WARN_ON_NONRT(!irqs_disabled()); - - queue_flag_clear(QUEUE_FLAG_STOPPED, q); - __blk_run_queue(q); -@@ -657,7 +660,7 @@ int blk_queue_enter(struct request_queue *q, bool nowait) - if (nowait) - return -EBUSY; - -- ret = wait_event_interruptible(q->mq_freeze_wq, -+ ret = swait_event_interruptible(q->mq_freeze_wq, - !atomic_read(&q->mq_freeze_depth) || - blk_queue_dying(q)); - if (blk_queue_dying(q)) -@@ -677,7 +680,7 @@ static void blk_queue_usage_counter_release(struct percpu_ref *ref) - struct request_queue *q = - container_of(ref, struct request_queue, q_usage_counter); - -- wake_up_all(&q->mq_freeze_wq); -+ swake_up_all(&q->mq_freeze_wq); - } - - static void blk_rq_timed_out_timer(unsigned long data) -@@ -746,7 +749,7 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id) - q->bypass_depth = 1; - __set_bit(QUEUE_FLAG_BYPASS, &q->queue_flags); - -- init_waitqueue_head(&q->mq_freeze_wq); -+ init_swait_queue_head(&q->mq_freeze_wq); - - /* - * Init percpu_ref in atomic mode so that it's faster to shutdown. -@@ -3209,7 +3212,7 @@ static void queue_unplugged(struct request_queue *q, unsigned int depth, - blk_run_queue_async(q); - else - __blk_run_queue(q); -- spin_unlock(q->queue_lock); -+ spin_unlock_irq(q->queue_lock); - } - - static void flush_plug_callbacks(struct blk_plug *plug, bool from_schedule) -@@ -3257,7 +3260,6 @@ EXPORT_SYMBOL(blk_check_plugged); - void blk_flush_plug_list(struct blk_plug *plug, bool from_schedule) - { - struct request_queue *q; -- unsigned long flags; - struct request *rq; - LIST_HEAD(list); - unsigned int depth; -@@ -3277,11 +3279,6 @@ void blk_flush_plug_list(struct blk_plug *plug, bool from_schedule) - q = NULL; - depth = 0; - -- /* -- * Save and disable interrupts here, to avoid doing it for every -- * queue lock we have to take. -- */ -- local_irq_save(flags); - while (!list_empty(&list)) { - rq = list_entry_rq(list.next); - list_del_init(&rq->queuelist); -@@ -3294,7 +3291,7 @@ void blk_flush_plug_list(struct blk_plug *plug, bool from_schedule) - queue_unplugged(q, depth, from_schedule); - q = rq->q; - depth = 0; -- spin_lock(q->queue_lock); -+ spin_lock_irq(q->queue_lock); - } - - /* -@@ -3321,8 +3318,6 @@ void blk_flush_plug_list(struct blk_plug *plug, bool from_schedule) - */ - if (q) - queue_unplugged(q, depth, from_schedule); -- -- local_irq_restore(flags); - } - - void blk_finish_plug(struct blk_plug *plug) -diff --git a/block/blk-ioc.c b/block/blk-ioc.c -index 381cb50..dc87852 100644 ---- a/block/blk-ioc.c -+++ b/block/blk-ioc.c -@@ -7,6 +7,7 @@ - #include <linux/bio.h> - #include <linux/blkdev.h> - #include <linux/slab.h> -+#include <linux/delay.h> - - #include "blk.h" - -@@ -109,7 +110,7 @@ static void ioc_release_fn(struct work_struct *work) - spin_unlock(q->queue_lock); - } else { - spin_unlock_irqrestore(&ioc->lock, flags); -- cpu_relax(); -+ cpu_chill(); - spin_lock_irqsave_nested(&ioc->lock, flags, 1); - } - } -@@ -187,7 +188,7 @@ retry: - spin_unlock(icq->q->queue_lock); - } else { - spin_unlock_irqrestore(&ioc->lock, flags); -- cpu_relax(); -+ cpu_chill(); - goto retry; - } - } -diff --git a/block/blk-mq-cpu.c b/block/blk-mq-cpu.c -index bb3ed48..628c6c1 100644 ---- a/block/blk-mq-cpu.c -+++ b/block/blk-mq-cpu.c -@@ -16,7 +16,7 @@ - #include "blk-mq.h" - - static LIST_HEAD(blk_mq_cpu_notify_list); --static DEFINE_RAW_SPINLOCK(blk_mq_cpu_notify_lock); -+static DEFINE_SPINLOCK(blk_mq_cpu_notify_lock); - - static int blk_mq_main_cpu_notify(struct notifier_block *self, - unsigned long action, void *hcpu) -@@ -25,7 +25,10 @@ static int blk_mq_main_cpu_notify(struct notifier_block *self, - struct blk_mq_cpu_notifier *notify; - int ret = NOTIFY_OK; - -- raw_spin_lock(&blk_mq_cpu_notify_lock); -+ if (action != CPU_POST_DEAD) -+ return NOTIFY_OK; -+ -+ spin_lock(&blk_mq_cpu_notify_lock); - - list_for_each_entry(notify, &blk_mq_cpu_notify_list, list) { - ret = notify->notify(notify->data, action, cpu); -@@ -33,7 +36,7 @@ static int blk_mq_main_cpu_notify(struct notifier_block *self, - break; - } - -- raw_spin_unlock(&blk_mq_cpu_notify_lock); -+ spin_unlock(&blk_mq_cpu_notify_lock); - return ret; - } - -@@ -41,16 +44,16 @@ void blk_mq_register_cpu_notifier(struct blk_mq_cpu_notifier *notifier) - { - BUG_ON(!notifier->notify); - -- raw_spin_lock(&blk_mq_cpu_notify_lock); -+ spin_lock(&blk_mq_cpu_notify_lock); - list_add_tail(¬ifier->list, &blk_mq_cpu_notify_list); -- raw_spin_unlock(&blk_mq_cpu_notify_lock); -+ spin_unlock(&blk_mq_cpu_notify_lock); - } - - void blk_mq_unregister_cpu_notifier(struct blk_mq_cpu_notifier *notifier) - { -- raw_spin_lock(&blk_mq_cpu_notify_lock); -+ spin_lock(&blk_mq_cpu_notify_lock); - list_del(¬ifier->list); -- raw_spin_unlock(&blk_mq_cpu_notify_lock); -+ spin_unlock(&blk_mq_cpu_notify_lock); - } - - void blk_mq_init_cpu_notifier(struct blk_mq_cpu_notifier *notifier, -diff --git a/block/blk-mq.c b/block/blk-mq.c -index 1699baf..2a20060 100644 ---- a/block/blk-mq.c -+++ b/block/blk-mq.c -@@ -92,7 +92,7 @@ EXPORT_SYMBOL_GPL(blk_mq_freeze_queue_start); - - static void blk_mq_freeze_queue_wait(struct request_queue *q) - { -- wait_event(q->mq_freeze_wq, percpu_ref_is_zero(&q->q_usage_counter)); -+ swait_event(q->mq_freeze_wq, percpu_ref_is_zero(&q->q_usage_counter)); - } - - /* -@@ -130,7 +130,7 @@ void blk_mq_unfreeze_queue(struct request_queue *q) - WARN_ON_ONCE(freeze_depth < 0); - if (!freeze_depth) { - percpu_ref_reinit(&q->q_usage_counter); -- wake_up_all(&q->mq_freeze_wq); -+ swake_up_all(&q->mq_freeze_wq); - } - } - EXPORT_SYMBOL_GPL(blk_mq_unfreeze_queue); -@@ -149,7 +149,7 @@ void blk_mq_wake_waiters(struct request_queue *q) - * dying, we need to ensure that processes currently waiting on - * the queue are notified as well. - */ -- wake_up_all(&q->mq_freeze_wq); -+ swake_up_all(&q->mq_freeze_wq); - } - - bool blk_mq_can_queue(struct blk_mq_hw_ctx *hctx) -@@ -196,6 +196,9 @@ static void blk_mq_rq_ctx_init(struct request_queue *q, struct blk_mq_ctx *ctx, - rq->resid_len = 0; - rq->sense = NULL; - -+#ifdef CONFIG_PREEMPT_RT_FULL -+ INIT_WORK(&rq->work, __blk_mq_complete_request_remote_work); -+#endif - INIT_LIST_HEAD(&rq->timeout_list); - rq->timeout = 0; - -@@ -323,6 +326,17 @@ void blk_mq_end_request(struct request *rq, int error) - } - EXPORT_SYMBOL(blk_mq_end_request); - -+#ifdef CONFIG_PREEMPT_RT_FULL -+ -+void __blk_mq_complete_request_remote_work(struct work_struct *work) -+{ -+ struct request *rq = container_of(work, struct request, work); -+ -+ rq->q->softirq_done_fn(rq); -+} -+ -+#else -+ - static void __blk_mq_complete_request_remote(void *data) - { - struct request *rq = data; -@@ -330,6 +344,8 @@ static void __blk_mq_complete_request_remote(void *data) - rq->q->softirq_done_fn(rq); - } - -+#endif -+ - static void blk_mq_ipi_complete_request(struct request *rq) - { - struct blk_mq_ctx *ctx = rq->mq_ctx; -@@ -341,19 +357,23 @@ static void blk_mq_ipi_complete_request(struct request *rq) - return; - } - -- cpu = get_cpu(); -+ cpu = get_cpu_light(); - if (!test_bit(QUEUE_FLAG_SAME_FORCE, &rq->q->queue_flags)) - shared = cpus_share_cache(cpu, ctx->cpu); - - if (cpu != ctx->cpu && !shared && cpu_online(ctx->cpu)) { -+#ifdef CONFIG_PREEMPT_RT_FULL -+ schedule_work_on(ctx->cpu, &rq->work); -+#else - rq->csd.func = __blk_mq_complete_request_remote; - rq->csd.info = rq; - rq->csd.flags = 0; - smp_call_function_single_async(ctx->cpu, &rq->csd); -+#endif - } else { - rq->q->softirq_done_fn(rq); - } -- put_cpu(); -+ put_cpu_light(); - } - - static void __blk_mq_complete_request(struct request *rq) -@@ -868,14 +888,14 @@ void blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx, bool async) - return; - - if (!async) { -- int cpu = get_cpu(); -+ int cpu = get_cpu_light(); - if (cpumask_test_cpu(cpu, hctx->cpumask)) { - __blk_mq_run_hw_queue(hctx); -- put_cpu(); -+ put_cpu_light(); - return; - } - -- put_cpu(); -+ put_cpu_light(); - } - - kblockd_schedule_delayed_work_on(blk_mq_hctx_next_cpu(hctx), -@@ -1621,7 +1641,7 @@ static int blk_mq_hctx_notify(void *data, unsigned long action, - { - struct blk_mq_hw_ctx *hctx = data; - -- if (action == CPU_DEAD || action == CPU_DEAD_FROZEN) -+ if (action == CPU_POST_DEAD) - return blk_mq_hctx_cpu_offline(hctx, cpu); - - /* -diff --git a/block/blk-mq.h b/block/blk-mq.h -index 9087b11..0401d76 100644 ---- a/block/blk-mq.h -+++ b/block/blk-mq.h -@@ -86,12 +86,12 @@ static inline struct blk_mq_ctx *__blk_mq_get_ctx(struct request_queue *q, - */ - static inline struct blk_mq_ctx *blk_mq_get_ctx(struct request_queue *q) - { -- return __blk_mq_get_ctx(q, get_cpu()); -+ return __blk_mq_get_ctx(q, get_cpu_light()); - } - - static inline void blk_mq_put_ctx(struct blk_mq_ctx *ctx) - { -- put_cpu(); -+ put_cpu_light(); - } - - struct blk_mq_alloc_data { -diff --git a/block/blk-softirq.c b/block/blk-softirq.c -index 53b1737..81c3c0a 100644 ---- a/block/blk-softirq.c -+++ b/block/blk-softirq.c -@@ -51,6 +51,7 @@ static void trigger_softirq(void *data) - raise_softirq_irqoff(BLOCK_SOFTIRQ); - - local_irq_restore(flags); -+ preempt_check_resched_rt(); - } - - /* -@@ -93,6 +94,7 @@ static int blk_cpu_notify(struct notifier_block *self, unsigned long action, - this_cpu_ptr(&blk_cpu_done)); - raise_softirq_irqoff(BLOCK_SOFTIRQ); - local_irq_enable(); -+ preempt_check_resched_rt(); - } - - return NOTIFY_OK; -@@ -150,6 +152,7 @@ do_local: - goto do_local; - - local_irq_restore(flags); -+ preempt_check_resched_rt(); - } - - /** -diff --git a/block/bounce.c b/block/bounce.c -index 1cb5dd3..2f1ec8a 100644 ---- a/block/bounce.c -+++ b/block/bounce.c -@@ -55,11 +55,11 @@ static void bounce_copy_vec(struct bio_vec *to, unsigned char *vfrom) - unsigned long flags; - unsigned char *vto; - -- local_irq_save(flags); -+ local_irq_save_nort(flags); - vto = kmap_atomic(to->bv_page); - memcpy(vto + to->bv_offset, vfrom, to->bv_len); - kunmap_atomic(vto); -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - } - - #else /* CONFIG_HIGHMEM */ -diff --git a/crypto/algapi.c b/crypto/algapi.c -index 731255a..d338059 100644 ---- a/crypto/algapi.c -+++ b/crypto/algapi.c -@@ -718,13 +718,13 @@ EXPORT_SYMBOL_GPL(crypto_spawn_tfm2); - - int crypto_register_notifier(struct notifier_block *nb) - { -- return blocking_notifier_chain_register(&crypto_chain, nb); -+ return srcu_notifier_chain_register(&crypto_chain, nb); - } - EXPORT_SYMBOL_GPL(crypto_register_notifier); - - int crypto_unregister_notifier(struct notifier_block *nb) - { -- return blocking_notifier_chain_unregister(&crypto_chain, nb); -+ return srcu_notifier_chain_unregister(&crypto_chain, nb); - } - EXPORT_SYMBOL_GPL(crypto_unregister_notifier); - -diff --git a/crypto/api.c b/crypto/api.c -index bbc147c..bc1a848 100644 ---- a/crypto/api.c -+++ b/crypto/api.c -@@ -31,7 +31,7 @@ EXPORT_SYMBOL_GPL(crypto_alg_list); - DECLARE_RWSEM(crypto_alg_sem); - EXPORT_SYMBOL_GPL(crypto_alg_sem); - --BLOCKING_NOTIFIER_HEAD(crypto_chain); -+SRCU_NOTIFIER_HEAD(crypto_chain); - EXPORT_SYMBOL_GPL(crypto_chain); - - static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg); -@@ -236,10 +236,10 @@ int crypto_probing_notify(unsigned long val, void *v) - { - int ok; - -- ok = blocking_notifier_call_chain(&crypto_chain, val, v); -+ ok = srcu_notifier_call_chain(&crypto_chain, val, v); - if (ok == NOTIFY_DONE) { - request_module("cryptomgr"); -- ok = blocking_notifier_call_chain(&crypto_chain, val, v); -+ ok = srcu_notifier_call_chain(&crypto_chain, val, v); - } - - return ok; -diff --git a/crypto/internal.h b/crypto/internal.h -index 7eefcdb..0ecc7f5 100644 ---- a/crypto/internal.h -+++ b/crypto/internal.h -@@ -47,7 +47,7 @@ struct crypto_larval { - - extern struct list_head crypto_alg_list; - extern struct rw_semaphore crypto_alg_sem; --extern struct blocking_notifier_head crypto_chain; -+extern struct srcu_notifier_head crypto_chain; - - #ifdef CONFIG_PROC_FS - void __init crypto_init_proc(void); -@@ -146,7 +146,7 @@ static inline int crypto_is_moribund(struct crypto_alg *alg) - - static inline void crypto_notify(unsigned long val, void *v) - { -- blocking_notifier_call_chain(&crypto_chain, val, v); -+ srcu_notifier_call_chain(&crypto_chain, val, v); - } - - #endif /* _CRYPTO_INTERNAL_H */ -diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h -index 51b073b..2d38ca5 100644 ---- a/drivers/acpi/acpica/acglobal.h -+++ b/drivers/acpi/acpica/acglobal.h -@@ -116,7 +116,7 @@ ACPI_GLOBAL(u8, acpi_gbl_global_lock_pending); - * interrupt level - */ - ACPI_GLOBAL(acpi_spinlock, acpi_gbl_gpe_lock); /* For GPE data structs and registers */ --ACPI_GLOBAL(acpi_spinlock, acpi_gbl_hardware_lock); /* For ACPI H/W except GPE registers */ -+ACPI_GLOBAL(acpi_raw_spinlock, acpi_gbl_hardware_lock); /* For ACPI H/W except GPE registers */ - ACPI_GLOBAL(acpi_spinlock, acpi_gbl_reference_count_lock); - - /* Mutex for _OSI support */ -diff --git a/drivers/acpi/acpica/hwregs.c b/drivers/acpi/acpica/hwregs.c -index 5ba0498..ada4319 100644 ---- a/drivers/acpi/acpica/hwregs.c -+++ b/drivers/acpi/acpica/hwregs.c -@@ -269,14 +269,14 @@ acpi_status acpi_hw_clear_acpi_status(void) - ACPI_BITMASK_ALL_FIXED_STATUS, - ACPI_FORMAT_UINT64(acpi_gbl_xpm1a_status.address))); - -- lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); -+ raw_spin_lock_irqsave(acpi_gbl_hardware_lock, lock_flags); - - /* Clear the fixed events in PM1 A/B */ - - status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS, - ACPI_BITMASK_ALL_FIXED_STATUS); - -- acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags); -+ raw_spin_unlock_irqrestore(acpi_gbl_hardware_lock, lock_flags); - - if (ACPI_FAILURE(status)) { - goto exit; -diff --git a/drivers/acpi/acpica/hwxface.c b/drivers/acpi/acpica/hwxface.c -index a01ddb3..fb64afd 100644 ---- a/drivers/acpi/acpica/hwxface.c -+++ b/drivers/acpi/acpica/hwxface.c -@@ -374,7 +374,7 @@ acpi_status acpi_write_bit_register(u32 register_id, u32 value) - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - -- lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); -+ raw_spin_lock_irqsave(acpi_gbl_hardware_lock, lock_flags); - - /* - * At this point, we know that the parent register is one of the -@@ -435,7 +435,7 @@ acpi_status acpi_write_bit_register(u32 register_id, u32 value) - - unlock_and_exit: - -- acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags); -+ raw_spin_unlock_irqrestore(acpi_gbl_hardware_lock, lock_flags); - return_ACPI_STATUS(status); - } - -diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c -index 1507337..357e7ca 100644 ---- a/drivers/acpi/acpica/utmutex.c -+++ b/drivers/acpi/acpica/utmutex.c -@@ -88,7 +88,7 @@ acpi_status acpi_ut_mutex_initialize(void) - return_ACPI_STATUS (status); - } - -- status = acpi_os_create_lock (&acpi_gbl_hardware_lock); -+ status = acpi_os_create_raw_lock (&acpi_gbl_hardware_lock); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } -@@ -145,7 +145,7 @@ void acpi_ut_mutex_terminate(void) - /* Delete the spinlocks */ - - acpi_os_delete_lock(acpi_gbl_gpe_lock); -- acpi_os_delete_lock(acpi_gbl_hardware_lock); -+ acpi_os_delete_raw_lock(acpi_gbl_hardware_lock); - acpi_os_delete_lock(acpi_gbl_reference_count_lock); - - /* Delete the reader/writer lock */ -diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c -index 051b615..7ad293b 100644 ---- a/drivers/ata/libata-sff.c -+++ b/drivers/ata/libata-sff.c -@@ -678,9 +678,9 @@ unsigned int ata_sff_data_xfer_noirq(struct ata_device *dev, unsigned char *buf, - unsigned long flags; - unsigned int consumed; - -- local_irq_save(flags); -+ local_irq_save_nort(flags); - consumed = ata_sff_data_xfer32(dev, buf, buflen, rw); -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - - return consumed; - } -@@ -719,7 +719,7 @@ static void ata_pio_sector(struct ata_queued_cmd *qc) - unsigned long flags; - - /* FIXME: use a bounce buffer */ -- local_irq_save(flags); -+ local_irq_save_nort(flags); - buf = kmap_atomic(page); - - /* do the actual data transfer */ -@@ -727,7 +727,7 @@ static void ata_pio_sector(struct ata_queued_cmd *qc) - do_write); - - kunmap_atomic(buf); -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - } else { - buf = page_address(page); - ap->ops->sff_data_xfer(qc->dev, buf + offset, qc->sect_size, -@@ -864,7 +864,7 @@ next_sg: - unsigned long flags; - - /* FIXME: use bounce buffer */ -- local_irq_save(flags); -+ local_irq_save_nort(flags); - buf = kmap_atomic(page); - - /* do the actual data transfer */ -@@ -872,7 +872,7 @@ next_sg: - count, rw); - - kunmap_atomic(buf); -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - } else { - buf = page_address(page); - consumed = ap->ops->sff_data_xfer(dev, buf + offset, -diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c -index 370c2f7..65e0b37 100644 ---- a/drivers/block/zram/zram_drv.c -+++ b/drivers/block/zram/zram_drv.c -@@ -520,6 +520,8 @@ static struct zram_meta *zram_meta_alloc(char *pool_name, u64 disksize) - goto out_error; - } - -+ zram_meta_init_table_locks(meta, disksize); -+ - return meta; - - out_error: -@@ -568,12 +570,12 @@ static int zram_decompress_page(struct zram *zram, char *mem, u32 index) - unsigned long handle; - size_t size; - -- bit_spin_lock(ZRAM_ACCESS, &meta->table[index].value); -+ zram_lock_table(&meta->table[index]); - handle = meta->table[index].handle; - size = zram_get_obj_size(meta, index); - - if (!handle || zram_test_flag(meta, index, ZRAM_ZERO)) { -- bit_spin_unlock(ZRAM_ACCESS, &meta->table[index].value); -+ zram_unlock_table(&meta->table[index]); - clear_page(mem); - return 0; - } -@@ -584,7 +586,7 @@ static int zram_decompress_page(struct zram *zram, char *mem, u32 index) - else - ret = zcomp_decompress(zram->comp, cmem, size, mem); - zs_unmap_object(meta->mem_pool, handle); -- bit_spin_unlock(ZRAM_ACCESS, &meta->table[index].value); -+ zram_unlock_table(&meta->table[index]); - - /* Should NEVER happen. Return bio error if it does. */ - if (unlikely(ret)) { -@@ -604,14 +606,14 @@ static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec, - struct zram_meta *meta = zram->meta; - page = bvec->bv_page; - -- bit_spin_lock(ZRAM_ACCESS, &meta->table[index].value); -+ zram_lock_table(&meta->table[index]); - if (unlikely(!meta->table[index].handle) || - zram_test_flag(meta, index, ZRAM_ZERO)) { -- bit_spin_unlock(ZRAM_ACCESS, &meta->table[index].value); -+ zram_unlock_table(&meta->table[index]); - handle_zero_page(bvec); - return 0; - } -- bit_spin_unlock(ZRAM_ACCESS, &meta->table[index].value); -+ zram_unlock_table(&meta->table[index]); - - if (is_partial_io(bvec)) - /* Use a temporary buffer to decompress the page */ -@@ -689,10 +691,10 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, - if (user_mem) - kunmap_atomic(user_mem); - /* Free memory associated with this sector now. */ -- bit_spin_lock(ZRAM_ACCESS, &meta->table[index].value); -+ zram_lock_table(&meta->table[index]); - zram_free_page(zram, index); - zram_set_flag(meta, index, ZRAM_ZERO); -- bit_spin_unlock(ZRAM_ACCESS, &meta->table[index].value); -+ zram_unlock_table(&meta->table[index]); - - atomic64_inc(&zram->stats.zero_pages); - ret = 0; -@@ -752,12 +754,12 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, - * Free memory associated with this sector - * before overwriting unused sectors. - */ -- bit_spin_lock(ZRAM_ACCESS, &meta->table[index].value); -+ zram_lock_table(&meta->table[index]); - zram_free_page(zram, index); - - meta->table[index].handle = handle; - zram_set_obj_size(meta, index, clen); -- bit_spin_unlock(ZRAM_ACCESS, &meta->table[index].value); -+ zram_unlock_table(&meta->table[index]); - - /* Update stats */ - atomic64_add(clen, &zram->stats.compr_data_size); -@@ -800,9 +802,9 @@ static void zram_bio_discard(struct zram *zram, u32 index, - } - - while (n >= PAGE_SIZE) { -- bit_spin_lock(ZRAM_ACCESS, &meta->table[index].value); -+ zram_lock_table(&meta->table[index]); - zram_free_page(zram, index); -- bit_spin_unlock(ZRAM_ACCESS, &meta->table[index].value); -+ zram_unlock_table(&meta->table[index]); - atomic64_inc(&zram->stats.notify_free); - index++; - n -= PAGE_SIZE; -@@ -928,9 +930,9 @@ static void zram_slot_free_notify(struct block_device *bdev, - zram = bdev->bd_disk->private_data; - meta = zram->meta; - -- bit_spin_lock(ZRAM_ACCESS, &meta->table[index].value); -+ zram_lock_table(&meta->table[index]); - zram_free_page(zram, index); -- bit_spin_unlock(ZRAM_ACCESS, &meta->table[index].value); -+ zram_unlock_table(&meta->table[index]); - atomic64_inc(&zram->stats.notify_free); - } - -diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h -index 8e92339..9e3e953 100644 ---- a/drivers/block/zram/zram_drv.h -+++ b/drivers/block/zram/zram_drv.h -@@ -72,6 +72,9 @@ enum zram_pageflags { - struct zram_table_entry { - unsigned long handle; - unsigned long value; -+#ifdef CONFIG_PREEMPT_RT_BASE -+ spinlock_t lock; -+#endif - }; - - struct zram_stats { -@@ -119,4 +122,42 @@ struct zram { - */ - bool claim; /* Protected by bdev->bd_mutex */ - }; -+ -+#ifndef CONFIG_PREEMPT_RT_BASE -+static inline void zram_lock_table(struct zram_table_entry *table) -+{ -+ bit_spin_lock(ZRAM_ACCESS, &table->value); -+} -+ -+static inline void zram_unlock_table(struct zram_table_entry *table) -+{ -+ bit_spin_unlock(ZRAM_ACCESS, &table->value); -+} -+ -+static inline void zram_meta_init_table_locks(struct zram_meta *meta, u64 disksize) { } -+#else /* CONFIG_PREEMPT_RT_BASE */ -+static inline void zram_lock_table(struct zram_table_entry *table) -+{ -+ spin_lock(&table->lock); -+ __set_bit(ZRAM_ACCESS, &table->value); -+} -+ -+static inline void zram_unlock_table(struct zram_table_entry *table) -+{ -+ __clear_bit(ZRAM_ACCESS, &table->value); -+ spin_unlock(&table->lock); -+} -+ -+static inline void zram_meta_init_table_locks(struct zram_meta *meta, u64 disksize) -+{ -+ size_t num_pages = disksize >> PAGE_SHIFT; -+ size_t index; -+ -+ for (index = 0; index < num_pages; index++) { -+ spinlock_t *lock = &meta->table[index].lock; -+ spin_lock_init(lock); -+ } -+} -+#endif /* CONFIG_PREEMPT_RT_BASE */ -+ - #endif -diff --git a/drivers/char/random.c b/drivers/char/random.c -index b583e53..ac2bd8c 100644 ---- a/drivers/char/random.c -+++ b/drivers/char/random.c -@@ -796,8 +796,6 @@ static void add_timer_randomness(struct timer_rand_state *state, unsigned num) - } sample; - long delta, delta2, delta3; - -- preempt_disable(); -- - sample.jiffies = jiffies; - sample.cycles = random_get_entropy(); - sample.num = num; -@@ -838,7 +836,6 @@ static void add_timer_randomness(struct timer_rand_state *state, unsigned num) - */ - credit_entropy_bits(r, min_t(int, fls(delta>>1), 11)); - } -- preempt_enable(); - } - - void add_input_randomness(unsigned int type, unsigned int code, -@@ -891,28 +888,27 @@ static __u32 get_reg(struct fast_pool *f, struct pt_regs *regs) - return *(ptr + f->reg_idx++); - } - --void add_interrupt_randomness(int irq, int irq_flags) -+void add_interrupt_randomness(int irq, int irq_flags, __u64 ip) - { - struct entropy_store *r; - struct fast_pool *fast_pool = this_cpu_ptr(&irq_randomness); -- struct pt_regs *regs = get_irq_regs(); - unsigned long now = jiffies; - cycles_t cycles = random_get_entropy(); - __u32 c_high, j_high; -- __u64 ip; - unsigned long seed; - int credit = 0; - - if (cycles == 0) -- cycles = get_reg(fast_pool, regs); -+ cycles = get_reg(fast_pool, NULL); - c_high = (sizeof(cycles) > 4) ? cycles >> 32 : 0; - j_high = (sizeof(now) > 4) ? now >> 32 : 0; - fast_pool->pool[0] ^= cycles ^ j_high ^ irq; - fast_pool->pool[1] ^= now ^ c_high; -- ip = regs ? instruction_pointer(regs) : _RET_IP_; -+ if (!ip) -+ ip = _RET_IP_; - fast_pool->pool[2] ^= ip; - fast_pool->pool[3] ^= (sizeof(ip) > 4) ? ip >> 32 : -- get_reg(fast_pool, regs); -+ get_reg(fast_pool, NULL); - - fast_mix(fast_pool); - add_interrupt_bench(cycles); -diff --git a/drivers/clocksource/tcb_clksrc.c b/drivers/clocksource/tcb_clksrc.c -index 4da2af9..5b6f57f 100644 ---- a/drivers/clocksource/tcb_clksrc.c -+++ b/drivers/clocksource/tcb_clksrc.c -@@ -23,8 +23,7 @@ - * this 32 bit free-running counter. the second channel is not used. - * - * - The third channel may be used to provide a 16-bit clockevent -- * source, used in either periodic or oneshot mode. This runs -- * at 32 KiHZ, and can handle delays of up to two seconds. -+ * source, used in either periodic or oneshot mode. - * - * A boot clocksource and clockevent source are also currently needed, - * unless the relevant platforms (ARM/AT91, AVR32/AT32) are changed so -@@ -74,6 +73,8 @@ static struct clocksource clksrc = { - struct tc_clkevt_device { - struct clock_event_device clkevt; - struct clk *clk; -+ bool clk_enabled; -+ u32 freq; - void __iomem *regs; - }; - -@@ -82,15 +83,26 @@ static struct tc_clkevt_device *to_tc_clkevt(struct clock_event_device *clkevt) - return container_of(clkevt, struct tc_clkevt_device, clkevt); - } - --/* For now, we always use the 32K clock ... this optimizes for NO_HZ, -- * because using one of the divided clocks would usually mean the -- * tick rate can never be less than several dozen Hz (vs 0.5 Hz). -- * -- * A divided clock could be good for high resolution timers, since -- * 30.5 usec resolution can seem "low". -- */ - static u32 timer_clock; - -+static void tc_clk_disable(struct clock_event_device *d) -+{ -+ struct tc_clkevt_device *tcd = to_tc_clkevt(d); -+ -+ clk_disable(tcd->clk); -+ tcd->clk_enabled = false; -+} -+ -+static void tc_clk_enable(struct clock_event_device *d) -+{ -+ struct tc_clkevt_device *tcd = to_tc_clkevt(d); -+ -+ if (tcd->clk_enabled) -+ return; -+ clk_enable(tcd->clk); -+ tcd->clk_enabled = true; -+} -+ - static int tc_shutdown(struct clock_event_device *d) - { - struct tc_clkevt_device *tcd = to_tc_clkevt(d); -@@ -98,8 +110,14 @@ static int tc_shutdown(struct clock_event_device *d) - - __raw_writel(0xff, regs + ATMEL_TC_REG(2, IDR)); - __raw_writel(ATMEL_TC_CLKDIS, regs + ATMEL_TC_REG(2, CCR)); -+ return 0; -+} -+ -+static int tc_shutdown_clk_off(struct clock_event_device *d) -+{ -+ tc_shutdown(d); - if (!clockevent_state_detached(d)) -- clk_disable(tcd->clk); -+ tc_clk_disable(d); - - return 0; - } -@@ -112,9 +130,9 @@ static int tc_set_oneshot(struct clock_event_device *d) - if (clockevent_state_oneshot(d) || clockevent_state_periodic(d)) - tc_shutdown(d); - -- clk_enable(tcd->clk); -+ tc_clk_enable(d); - -- /* slow clock, count up to RC, then irq and stop */ -+ /* count up to RC, then irq and stop */ - __raw_writel(timer_clock | ATMEL_TC_CPCSTOP | ATMEL_TC_WAVE | - ATMEL_TC_WAVESEL_UP_AUTO, regs + ATMEL_TC_REG(2, CMR)); - __raw_writel(ATMEL_TC_CPCS, regs + ATMEL_TC_REG(2, IER)); -@@ -134,12 +152,12 @@ static int tc_set_periodic(struct clock_event_device *d) - /* By not making the gentime core emulate periodic mode on top - * of oneshot, we get lower overhead and improved accuracy. - */ -- clk_enable(tcd->clk); -+ tc_clk_enable(d); - -- /* slow clock, count up to RC, then irq and restart */ -+ /* count up to RC, then irq and restart */ - __raw_writel(timer_clock | ATMEL_TC_WAVE | ATMEL_TC_WAVESEL_UP_AUTO, - regs + ATMEL_TC_REG(2, CMR)); -- __raw_writel((32768 + HZ / 2) / HZ, tcaddr + ATMEL_TC_REG(2, RC)); -+ __raw_writel((tcd->freq + HZ / 2) / HZ, tcaddr + ATMEL_TC_REG(2, RC)); - - /* Enable clock and interrupts on RC compare */ - __raw_writel(ATMEL_TC_CPCS, regs + ATMEL_TC_REG(2, IER)); -@@ -166,9 +184,13 @@ static struct tc_clkevt_device clkevt = { - .features = CLOCK_EVT_FEAT_PERIODIC | - CLOCK_EVT_FEAT_ONESHOT, - /* Should be lower than at91rm9200's system timer */ -+#ifdef CONFIG_ATMEL_TCB_CLKSRC_USE_SLOW_CLOCK - .rating = 125, -+#else -+ .rating = 200, -+#endif - .set_next_event = tc_next_event, -- .set_state_shutdown = tc_shutdown, -+ .set_state_shutdown = tc_shutdown_clk_off, - .set_state_periodic = tc_set_periodic, - .set_state_oneshot = tc_set_oneshot, - }, -@@ -188,8 +210,9 @@ static irqreturn_t ch2_irq(int irq, void *handle) - return IRQ_NONE; - } - --static int __init setup_clkevents(struct atmel_tc *tc, int clk32k_divisor_idx) -+static int __init setup_clkevents(struct atmel_tc *tc, int divisor_idx) - { -+ unsigned divisor = atmel_tc_divisors[divisor_idx]; - int ret; - struct clk *t2_clk = tc->clk[2]; - int irq = tc->irq[2]; -@@ -210,7 +233,11 @@ static int __init setup_clkevents(struct atmel_tc *tc, int clk32k_divisor_idx) - clkevt.regs = tc->regs; - clkevt.clk = t2_clk; - -- timer_clock = clk32k_divisor_idx; -+ timer_clock = divisor_idx; -+ if (!divisor) -+ clkevt.freq = 32768; -+ else -+ clkevt.freq = clk_get_rate(t2_clk) / divisor; - - clkevt.clkevt.cpumask = cpumask_of(0); - -@@ -221,7 +248,7 @@ static int __init setup_clkevents(struct atmel_tc *tc, int clk32k_divisor_idx) - return ret; - } - -- clockevents_config_and_register(&clkevt.clkevt, 32768, 1, 0xffff); -+ clockevents_config_and_register(&clkevt.clkevt, clkevt.freq, 1, 0xffff); - - return ret; - } -@@ -358,7 +385,11 @@ static int __init tcb_clksrc_init(void) - goto err_disable_t1; - - /* channel 2: periodic and oneshot timer support */ -+#ifdef CONFIG_ATMEL_TCB_CLKSRC_USE_SLOW_CLOCK - ret = setup_clkevents(tc, clk32k_divisor_idx); -+#else -+ ret = setup_clkevents(tc, best_divisor_idx); -+#endif - if (ret) - goto err_unregister_clksrc; - -diff --git a/drivers/clocksource/timer-atmel-pit.c b/drivers/clocksource/timer-atmel-pit.c -index d911c5d..7a40f7e 100644 ---- a/drivers/clocksource/timer-atmel-pit.c -+++ b/drivers/clocksource/timer-atmel-pit.c -@@ -46,6 +46,7 @@ struct pit_data { - u32 cycle; - u32 cnt; - unsigned int irq; -+ bool irq_requested; - struct clk *mck; - }; - -@@ -96,15 +97,29 @@ static int pit_clkevt_shutdown(struct clock_event_device *dev) - - /* disable irq, leaving the clocksource active */ - pit_write(data->base, AT91_PIT_MR, (data->cycle - 1) | AT91_PIT_PITEN); -+ if (data->irq_requested) { -+ free_irq(data->irq, data); -+ data->irq_requested = false; -+ } - return 0; - } - -+static irqreturn_t at91sam926x_pit_interrupt(int irq, void *dev_id); - /* - * Clockevent device: interrupts every 1/HZ (== pit_cycles * MCK/16) - */ - static int pit_clkevt_set_periodic(struct clock_event_device *dev) - { - struct pit_data *data = clkevt_to_pit_data(dev); -+ int ret; -+ -+ ret = request_irq(data->irq, at91sam926x_pit_interrupt, -+ IRQF_SHARED | IRQF_TIMER | IRQF_IRQPOLL, -+ "at91_tick", data); -+ if (ret) -+ panic(pr_fmt("Unable to setup IRQ\n")); -+ -+ data->irq_requested = true; - - /* update clocksource counter */ - data->cnt += data->cycle * PIT_PICNT(pit_read(data->base, AT91_PIT_PIVR)); -@@ -181,7 +196,6 @@ static void __init at91sam926x_pit_common_init(struct pit_data *data) - { - unsigned long pit_rate; - unsigned bits; -- int ret; - - /* - * Use our actual MCK to figure out how many MCK/16 ticks per -@@ -206,13 +220,6 @@ static void __init at91sam926x_pit_common_init(struct pit_data *data) - data->clksrc.flags = CLOCK_SOURCE_IS_CONTINUOUS; - clocksource_register_hz(&data->clksrc, pit_rate); - -- /* Set up irq handler */ -- ret = request_irq(data->irq, at91sam926x_pit_interrupt, -- IRQF_SHARED | IRQF_TIMER | IRQF_IRQPOLL, -- "at91_tick", data); -- if (ret) -- panic(pr_fmt("Unable to setup IRQ\n")); -- - /* Set up and register clockevents */ - data->clkevt.name = "pit"; - data->clkevt.features = CLOCK_EVT_FEAT_PERIODIC; -diff --git a/drivers/clocksource/timer-atmel-st.c b/drivers/clocksource/timer-atmel-st.c -index 29d21d6..103d0fd 100644 ---- a/drivers/clocksource/timer-atmel-st.c -+++ b/drivers/clocksource/timer-atmel-st.c -@@ -115,18 +115,29 @@ static void clkdev32k_disable_and_flush_irq(void) - last_crtr = read_CRTR(); - } - -+static int atmel_st_irq; -+ - static int clkevt32k_shutdown(struct clock_event_device *evt) - { - clkdev32k_disable_and_flush_irq(); - irqmask = 0; - regmap_write(regmap_st, AT91_ST_IER, irqmask); -+ free_irq(atmel_st_irq, regmap_st); - return 0; - } - - static int clkevt32k_set_oneshot(struct clock_event_device *dev) - { -+ int ret; -+ - clkdev32k_disable_and_flush_irq(); - -+ ret = request_irq(atmel_st_irq, at91rm9200_timer_interrupt, -+ IRQF_SHARED | IRQF_TIMER | IRQF_IRQPOLL, -+ "at91_tick", regmap_st); -+ if (ret) -+ panic(pr_fmt("Unable to setup IRQ\n")); -+ - /* - * ALM for oneshot irqs, set by next_event() - * before 32 seconds have passed. -@@ -139,8 +150,16 @@ static int clkevt32k_set_oneshot(struct clock_event_device *dev) - - static int clkevt32k_set_periodic(struct clock_event_device *dev) - { -+ int ret; -+ - clkdev32k_disable_and_flush_irq(); - -+ ret = request_irq(atmel_st_irq, at91rm9200_timer_interrupt, -+ IRQF_SHARED | IRQF_TIMER | IRQF_IRQPOLL, -+ "at91_tick", regmap_st); -+ if (ret) -+ panic(pr_fmt("Unable to setup IRQ\n")); -+ - /* PIT for periodic irqs; fixed rate of 1/HZ */ - irqmask = AT91_ST_PITS; - regmap_write(regmap_st, AT91_ST_PIMR, timer_latch); -@@ -198,7 +217,7 @@ static void __init atmel_st_timer_init(struct device_node *node) - { - struct clk *sclk; - unsigned int sclk_rate, val; -- int irq, ret; -+ int ret; - - regmap_st = syscon_node_to_regmap(node); - if (IS_ERR(regmap_st)) -@@ -210,17 +229,10 @@ static void __init atmel_st_timer_init(struct device_node *node) - regmap_read(regmap_st, AT91_ST_SR, &val); - - /* Get the interrupts property */ -- irq = irq_of_parse_and_map(node, 0); -- if (!irq) -+ atmel_st_irq = irq_of_parse_and_map(node, 0); -+ if (!atmel_st_irq) - panic(pr_fmt("Unable to get IRQ from DT\n")); - -- /* Make IRQs happen for the system timer */ -- ret = request_irq(irq, at91rm9200_timer_interrupt, -- IRQF_SHARED | IRQF_TIMER | IRQF_IRQPOLL, -- "at91_tick", regmap_st); -- if (ret) -- panic(pr_fmt("Unable to setup IRQ\n")); -- - sclk = of_clk_get(node, 0); - if (IS_ERR(sclk)) - panic(pr_fmt("Unable to get slow clock\n")); -diff --git a/drivers/cpufreq/Kconfig.x86 b/drivers/cpufreq/Kconfig.x86 -index c59bdcb..8f23161 100644 ---- a/drivers/cpufreq/Kconfig.x86 -+++ b/drivers/cpufreq/Kconfig.x86 -@@ -123,7 +123,7 @@ config X86_POWERNOW_K7_ACPI - - config X86_POWERNOW_K8 - tristate "AMD Opteron/Athlon64 PowerNow!" -- depends on ACPI && ACPI_PROCESSOR && X86_ACPI_CPUFREQ -+ depends on ACPI && ACPI_PROCESSOR && X86_ACPI_CPUFREQ && !PREEMPT_RT_BASE - help - This adds the CPUFreq driver for K8/early Opteron/Athlon64 processors. - Support for K10 and newer processors is now in acpi-cpufreq. -diff --git a/drivers/crypto/ccp/ccp-dev.c b/drivers/crypto/ccp/ccp-dev.c -index 4dbc187..2a8ad71 100644 ---- a/drivers/crypto/ccp/ccp-dev.c -+++ b/drivers/crypto/ccp/ccp-dev.c -@@ -16,7 +16,6 @@ - #include <linux/sched.h> - #include <linux/interrupt.h> - #include <linux/spinlock.h> --#include <linux/rwlock_types.h> - #include <linux/types.h> - #include <linux/mutex.h> - #include <linux/delay.h> -diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c -index 1328bc5..6210366 100644 ---- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c -+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c -@@ -1314,7 +1314,9 @@ i915_gem_ringbuffer_submission(struct i915_execbuffer_params *params, - if (ret) - return ret; - -+#ifndef CONFIG_PREEMPT_RT_BASE - trace_i915_gem_ring_dispatch(params->request, params->dispatch_flags); -+#endif - - i915_gem_execbuffer_move_to_active(vmas, params->request); - i915_gem_execbuffer_retire_commands(params); -diff --git a/drivers/gpu/drm/i915/i915_gem_shrinker.c b/drivers/gpu/drm/i915/i915_gem_shrinker.c -index d3c473f..6d543e2 100644 ---- a/drivers/gpu/drm/i915/i915_gem_shrinker.c -+++ b/drivers/gpu/drm/i915/i915_gem_shrinker.c -@@ -39,7 +39,7 @@ static bool mutex_is_locked_by(struct mutex *mutex, struct task_struct *task) - if (!mutex_is_locked(mutex)) - return false; - --#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_MUTEXES) -+#if (defined(CONFIG_SMP) || defined(CONFIG_DEBUG_MUTEXES)) && !defined(CONFIG_PREEMPT_RT_BASE) - return mutex->owner == task; - #else - /* Since UP may be pre-empted, we cannot assume that we own the lock */ -diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c -index 1c21220..8984996 100644 ---- a/drivers/gpu/drm/i915/i915_irq.c -+++ b/drivers/gpu/drm/i915/i915_irq.c -@@ -830,6 +830,7 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, - spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); - - /* preempt_disable_rt() should go right here in PREEMPT_RT patchset. */ -+ preempt_disable_rt(); - - /* Get optional system timestamp before query. */ - if (stime) -@@ -881,6 +882,7 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, - *etime = ktime_get(); - - /* preempt_enable_rt() should go right here in PREEMPT_RT patchset. */ -+ preempt_enable_rt(); - - spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); - -diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c -index 0104a06..623261d 100644 ---- a/drivers/gpu/drm/i915/intel_display.c -+++ b/drivers/gpu/drm/i915/intel_display.c -@@ -11475,7 +11475,7 @@ void intel_check_page_flip(struct drm_device *dev, int pipe) - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct intel_unpin_work *work; - -- WARN_ON(!in_interrupt()); -+ WARN_ON_NONRT(!in_interrupt()); - - if (crtc == NULL) - return; -diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c -index a2582c4..c459b91 100644 ---- a/drivers/gpu/drm/i915/intel_sprite.c -+++ b/drivers/gpu/drm/i915/intel_sprite.c -@@ -38,6 +38,7 @@ - #include "intel_drv.h" - #include <drm/i915_drm.h> - #include "i915_drv.h" -+#include <linux/locallock.h> - - static bool - format_is_yuv(uint32_t format) -@@ -64,6 +65,8 @@ static int usecs_to_scanlines(const struct drm_display_mode *adjusted_mode, - 1000 * adjusted_mode->crtc_htotal); - } - -+static DEFINE_LOCAL_IRQ_LOCK(pipe_update_lock); -+ - /** - * intel_pipe_update_start() - start update of a set of display registers - * @crtc: the crtc of which the registers are going to be updated -@@ -96,7 +99,7 @@ void intel_pipe_update_start(struct intel_crtc *crtc) - min = vblank_start - usecs_to_scanlines(adjusted_mode, 100); - max = vblank_start - 1; - -- local_irq_disable(); -+ local_lock_irq(pipe_update_lock); - - if (min <= 0 || max <= 0) - return; -@@ -126,11 +129,11 @@ void intel_pipe_update_start(struct intel_crtc *crtc) - break; - } - -- local_irq_enable(); -+ local_unlock_irq(pipe_update_lock); - - timeout = schedule_timeout(timeout); - -- local_irq_disable(); -+ local_lock_irq(pipe_update_lock); - } - - finish_wait(wq, &wait); -@@ -164,7 +167,7 @@ void intel_pipe_update_end(struct intel_crtc *crtc) - - trace_i915_pipe_update_end(crtc, end_vbl_count, scanline_end); - -- local_irq_enable(); -+ local_unlock_irq(pipe_update_lock); - - if (crtc->debug.start_vbl_count && - crtc->debug.start_vbl_count != end_vbl_count) { -diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c -index fcc7483..dc44af5 100644 ---- a/drivers/gpu/drm/radeon/radeon_display.c -+++ b/drivers/gpu/drm/radeon/radeon_display.c -@@ -1863,6 +1863,7 @@ int radeon_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, - struct radeon_device *rdev = dev->dev_private; - - /* preempt_disable_rt() should go right here in PREEMPT_RT patchset. */ -+ preempt_disable_rt(); - - /* Get optional system timestamp before query. */ - if (stime) -@@ -1955,6 +1956,7 @@ int radeon_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, - *etime = ktime_get(); - - /* preempt_enable_rt() should go right here in PREEMPT_RT patchset. */ -+ preempt_enable_rt(); - - /* Decode into vertical and horizontal scanout position. */ - *vpos = position & 0x1fff; -diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c -index 13c4529..50c035c 100644 ---- a/drivers/i2c/busses/i2c-omap.c -+++ b/drivers/i2c/busses/i2c-omap.c -@@ -995,15 +995,12 @@ omap_i2c_isr(int irq, void *dev_id) - u16 mask; - u16 stat; - -- spin_lock(&omap->lock); -- mask = omap_i2c_read_reg(omap, OMAP_I2C_IE_REG); - stat = omap_i2c_read_reg(omap, OMAP_I2C_STAT_REG); -+ mask = omap_i2c_read_reg(omap, OMAP_I2C_IE_REG); - - if (stat & mask) - ret = IRQ_WAKE_THREAD; - -- spin_unlock(&omap->lock); -- - return ret; - } - -diff --git a/drivers/ide/alim15x3.c b/drivers/ide/alim15x3.c -index 36f76e2..394f142f 100644 ---- a/drivers/ide/alim15x3.c -+++ b/drivers/ide/alim15x3.c -@@ -234,7 +234,7 @@ static int init_chipset_ali15x3(struct pci_dev *dev) - - isa_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL); - -- local_irq_save(flags); -+ local_irq_save_nort(flags); - - if (m5229_revision < 0xC2) { - /* -@@ -325,7 +325,7 @@ out: - } - pci_dev_put(north); - pci_dev_put(isa_dev); -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - return 0; - } - -diff --git a/drivers/ide/hpt366.c b/drivers/ide/hpt366.c -index f94baad..71c41cf 100644 ---- a/drivers/ide/hpt366.c -+++ b/drivers/ide/hpt366.c -@@ -1236,7 +1236,7 @@ static int init_dma_hpt366(ide_hwif_t *hwif, - - dma_old = inb(base + 2); - -- local_irq_save(flags); -+ local_irq_save_nort(flags); - - dma_new = dma_old; - pci_read_config_byte(dev, hwif->channel ? 0x4b : 0x43, &masterdma); -@@ -1247,7 +1247,7 @@ static int init_dma_hpt366(ide_hwif_t *hwif, - if (dma_new != dma_old) - outb(dma_new, base + 2); - -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - - printk(KERN_INFO " %s: BM-DMA at 0x%04lx-0x%04lx\n", - hwif->name, base, base + 7); -diff --git a/drivers/ide/ide-io-std.c b/drivers/ide/ide-io-std.c -index 1976397..4169433 100644 ---- a/drivers/ide/ide-io-std.c -+++ b/drivers/ide/ide-io-std.c -@@ -175,7 +175,7 @@ void ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf, - unsigned long uninitialized_var(flags); - - if ((io_32bit & 2) && !mmio) { -- local_irq_save(flags); -+ local_irq_save_nort(flags); - ata_vlb_sync(io_ports->nsect_addr); - } - -@@ -186,7 +186,7 @@ void ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf, - insl(data_addr, buf, words); - - if ((io_32bit & 2) && !mmio) -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - - if (((len + 1) & 3) < 2) - return; -@@ -219,7 +219,7 @@ void ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf, - unsigned long uninitialized_var(flags); - - if ((io_32bit & 2) && !mmio) { -- local_irq_save(flags); -+ local_irq_save_nort(flags); - ata_vlb_sync(io_ports->nsect_addr); - } - -@@ -230,7 +230,7 @@ void ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf, - outsl(data_addr, buf, words); - - if ((io_32bit & 2) && !mmio) -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - - if (((len + 1) & 3) < 2) - return; -diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c -index 669ea1e..e12e43e 100644 ---- a/drivers/ide/ide-io.c -+++ b/drivers/ide/ide-io.c -@@ -659,7 +659,7 @@ void ide_timer_expiry (unsigned long data) - /* disable_irq_nosync ?? */ - disable_irq(hwif->irq); - /* local CPU only, as if we were handling an interrupt */ -- local_irq_disable(); -+ local_irq_disable_nort(); - if (hwif->polling) { - startstop = handler(drive); - } else if (drive_is_ready(drive)) { -diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c -index 376f2dc..f014dd1 100644 ---- a/drivers/ide/ide-iops.c -+++ b/drivers/ide/ide-iops.c -@@ -129,12 +129,12 @@ int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, - if ((stat & ATA_BUSY) == 0) - break; - -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - *rstat = stat; - return -EBUSY; - } - } -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - } - /* - * Allow status to settle, then read it again. -diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c -index 0b63fac..4ceba37 100644 ---- a/drivers/ide/ide-probe.c -+++ b/drivers/ide/ide-probe.c -@@ -196,10 +196,10 @@ static void do_identify(ide_drive_t *drive, u8 cmd, u16 *id) - int bswap = 1; - - /* local CPU only; some systems need this */ -- local_irq_save(flags); -+ local_irq_save_nort(flags); - /* read 512 bytes of id info */ - hwif->tp_ops->input_data(drive, NULL, id, SECTOR_SIZE); -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - - drive->dev_flags |= IDE_DFLAG_ID_READ; - #ifdef DEBUG -diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c -index a716693..be0568c 100644 ---- a/drivers/ide/ide-taskfile.c -+++ b/drivers/ide/ide-taskfile.c -@@ -250,7 +250,7 @@ void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd, - - page_is_high = PageHighMem(page); - if (page_is_high) -- local_irq_save(flags); -+ local_irq_save_nort(flags); - - buf = kmap_atomic(page) + offset; - -@@ -271,7 +271,7 @@ void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd, - kunmap_atomic(buf); - - if (page_is_high) -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - - len -= nr_bytes; - } -@@ -414,7 +414,7 @@ static ide_startstop_t pre_task_out_intr(ide_drive_t *drive, - } - - if ((drive->dev_flags & IDE_DFLAG_UNMASK) == 0) -- local_irq_disable(); -+ local_irq_disable_nort(); - - ide_set_handler(drive, &task_pio_intr, WAIT_WORSTCASE); - -diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c -index f0e55e4..da5f28c 100644 ---- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c -+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c -@@ -51,8 +51,6 @@ MODULE_PARM_DESC(data_debug_level, - "Enable data path debug tracing if > 0"); - #endif - --static DEFINE_MUTEX(pkey_mutex); -- - struct ipoib_ah *ipoib_create_ah(struct net_device *dev, - struct ib_pd *pd, struct ib_ah_attr *attr) - { -diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c -index 2588931..7fe9dd2 100644 ---- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c -+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c -@@ -883,7 +883,7 @@ void ipoib_mcast_restart_task(struct work_struct *work) - - ipoib_dbg_mcast(priv, "restarting multicast task\n"); - -- local_irq_save(flags); -+ local_irq_save_nort(flags); - netif_addr_lock(dev); - spin_lock(&priv->lock); - -@@ -965,7 +965,7 @@ void ipoib_mcast_restart_task(struct work_struct *work) - - spin_unlock(&priv->lock); - netif_addr_unlock(dev); -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - - /* - * make sure the in-flight joins have finished before we attempt -diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c -index 4a2a9e3..e970d9a 100644 ---- a/drivers/input/gameport/gameport.c -+++ b/drivers/input/gameport/gameport.c -@@ -91,13 +91,13 @@ static int gameport_measure_speed(struct gameport *gameport) - tx = ~0; - - for (i = 0; i < 50; i++) { -- local_irq_save(flags); -+ local_irq_save_nort(flags); - t1 = ktime_get_ns(); - for (t = 0; t < 50; t++) - gameport_read(gameport); - t2 = ktime_get_ns(); - t3 = ktime_get_ns(); -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - udelay(i * 10); - t = (t2 - t1) - (t3 - t2); - if (t < tx) -@@ -124,12 +124,12 @@ static int old_gameport_measure_speed(struct gameport *gameport) - tx = 1 << 30; - - for(i = 0; i < 50; i++) { -- local_irq_save(flags); -+ local_irq_save_nort(flags); - GET_TIME(t1); - for (t = 0; t < 50; t++) gameport_read(gameport); - GET_TIME(t2); - GET_TIME(t3); -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - udelay(i * 10); - if ((t = DELTA(t2,t1) - DELTA(t3,t2)) < tx) tx = t; - } -@@ -148,11 +148,11 @@ static int old_gameport_measure_speed(struct gameport *gameport) - tx = 1 << 30; - - for(i = 0; i < 50; i++) { -- local_irq_save(flags); -+ local_irq_save_nort(flags); - t1 = rdtsc(); - for (t = 0; t < 50; t++) gameport_read(gameport); - t2 = rdtsc(); -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - udelay(i * 10); - if (t2 - t1 < tx) tx = t2 - t1; - } -diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c -index 5efadad..42fc628 100644 ---- a/drivers/iommu/amd_iommu.c -+++ b/drivers/iommu/amd_iommu.c -@@ -2165,10 +2165,10 @@ static int __attach_device(struct iommu_dev_data *dev_data, - int ret; - - /* -- * Must be called with IRQs disabled. Warn here to detect early -- * when its not. -+ * Must be called with IRQs disabled on a non RT kernel. Warn here to -+ * detect early when its not. - */ -- WARN_ON(!irqs_disabled()); -+ WARN_ON_NONRT(!irqs_disabled()); - - /* lock domain */ - spin_lock(&domain->lock); -@@ -2331,10 +2331,10 @@ static void __detach_device(struct iommu_dev_data *dev_data) - struct protection_domain *domain; - - /* -- * Must be called with IRQs disabled. Warn here to detect early -- * when its not. -+ * Must be called with IRQs disabled on a non RT kernel. Warn here to -+ * detect early when its not. - */ -- WARN_ON(!irqs_disabled()); -+ WARN_ON_NONRT(!irqs_disabled()); - - if (WARN_ON(!dev_data->domain)) - return; -diff --git a/drivers/leds/trigger/Kconfig b/drivers/leds/trigger/Kconfig -index 5bda6a9..d628658 100644 ---- a/drivers/leds/trigger/Kconfig -+++ b/drivers/leds/trigger/Kconfig -@@ -61,7 +61,7 @@ config LEDS_TRIGGER_BACKLIGHT - - config LEDS_TRIGGER_CPU - bool "LED CPU Trigger" -- depends on LEDS_TRIGGERS -+ depends on LEDS_TRIGGERS && !PREEMPT_RT_BASE - help - This allows LEDs to be controlled by active CPUs. This shows - the active CPUs across an array of LEDs so you can see which -diff --git a/drivers/md/bcache/Kconfig b/drivers/md/bcache/Kconfig -index 4d20088..98b64ed 100644 ---- a/drivers/md/bcache/Kconfig -+++ b/drivers/md/bcache/Kconfig -@@ -1,6 +1,7 @@ - - config BCACHE - tristate "Block device as cache" -+ depends on !PREEMPT_RT_FULL - ---help--- - Allows a block device to be used as cache for other devices; uses - a btree for indexing and the layout is optimized for SSDs. -diff --git a/drivers/md/dm.c b/drivers/md/dm.c -index 3d3ac13..b931c7b 100644 ---- a/drivers/md/dm.c -+++ b/drivers/md/dm.c -@@ -2187,7 +2187,7 @@ static void dm_request_fn(struct request_queue *q) - /* Establish tio->ti before queuing work (map_tio_request) */ - tio->ti = ti; - queue_kthread_work(&md->kworker, &tio->work); -- BUG_ON(!irqs_disabled()); -+ BUG_ON_NONRT(!irqs_disabled()); - } - } - -diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c -index e48c262..25b8221 100644 ---- a/drivers/md/raid5.c -+++ b/drivers/md/raid5.c -@@ -1918,8 +1918,9 @@ static void raid_run_ops(struct stripe_head *sh, unsigned long ops_request) - struct raid5_percpu *percpu; - unsigned long cpu; - -- cpu = get_cpu(); -+ cpu = get_cpu_light(); - percpu = per_cpu_ptr(conf->percpu, cpu); -+ spin_lock(&percpu->lock); - if (test_bit(STRIPE_OP_BIOFILL, &ops_request)) { - ops_run_biofill(sh); - overlap_clear++; -@@ -1975,7 +1976,8 @@ static void raid_run_ops(struct stripe_head *sh, unsigned long ops_request) - if (test_and_clear_bit(R5_Overlap, &dev->flags)) - wake_up(&sh->raid_conf->wait_for_overlap); - } -- put_cpu(); -+ spin_unlock(&percpu->lock); -+ put_cpu_light(); - } - - static struct stripe_head *alloc_stripe(struct kmem_cache *sc, gfp_t gfp) -@@ -6415,6 +6417,7 @@ static int raid5_alloc_percpu(struct r5conf *conf) - __func__, cpu); - break; - } -+ spin_lock_init(&per_cpu_ptr(conf->percpu, cpu)->lock); - } - put_online_cpus(); - -diff --git a/drivers/md/raid5.h b/drivers/md/raid5.h -index 517d4b6..efe9188 100644 ---- a/drivers/md/raid5.h -+++ b/drivers/md/raid5.h -@@ -504,6 +504,7 @@ struct r5conf { - int recovery_disabled; - /* per cpu variables */ - struct raid5_percpu { -+ spinlock_t lock; /* Protection for -RT */ - struct page *spare_page; /* Used when checking P/Q in raid6 */ - struct flex_array *scribble; /* space for constructing buffer - * lists and performing address -diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig -index a216b46..cea7320 100644 ---- a/drivers/misc/Kconfig -+++ b/drivers/misc/Kconfig -@@ -54,6 +54,7 @@ config AD525X_DPOT_SPI - config ATMEL_TCLIB - bool "Atmel AT32/AT91 Timer/Counter Library" - depends on (AVR32 || ARCH_AT91) -+ default y if PREEMPT_RT_FULL - help - Select this if you want a library to allocate the Timer/Counter - blocks found on many Atmel processors. This facilitates using -@@ -69,8 +70,7 @@ config ATMEL_TCB_CLKSRC - are combined to make a single 32-bit timer. - - When GENERIC_CLOCKEVENTS is defined, the third timer channel -- may be used as a clock event device supporting oneshot mode -- (delays of up to two seconds) based on the 32 KiHz clock. -+ may be used as a clock event device supporting oneshot mode. - - config ATMEL_TCB_CLKSRC_BLOCK - int -@@ -84,6 +84,15 @@ config ATMEL_TCB_CLKSRC_BLOCK - TC can be used for other purposes, such as PWM generation and - interval timing. - -+config ATMEL_TCB_CLKSRC_USE_SLOW_CLOCK -+ bool "TC Block use 32 KiHz clock" -+ depends on ATMEL_TCB_CLKSRC -+ default y if !PREEMPT_RT_FULL -+ help -+ Select this to use 32 KiHz base clock rate as TC block clock -+ source for clock events. -+ -+ - config DUMMY_IRQ - tristate "Dummy IRQ handler" - default n -@@ -114,6 +123,35 @@ config IBM_ASM - for information on the specific driver level and support statement - for your IBM server. - -+config HWLAT_DETECTOR -+ tristate "Testing module to detect hardware-induced latencies" -+ depends on DEBUG_FS -+ depends on RING_BUFFER -+ default m -+ ---help--- -+ A simple hardware latency detector. Use this module to detect -+ large latencies introduced by the behavior of the underlying -+ system firmware external to Linux. We do this using periodic -+ use of stop_machine to grab all available CPUs and measure -+ for unexplainable gaps in the CPU timestamp counter(s). By -+ default, the module is not enabled until the "enable" file -+ within the "hwlat_detector" debugfs directory is toggled. -+ -+ This module is often used to detect SMI (System Management -+ Interrupts) on x86 systems, though is not x86 specific. To -+ this end, we default to using a sample window of 1 second, -+ during which we will sample for 0.5 seconds. If an SMI or -+ similar event occurs during that time, it is recorded -+ into an 8K samples global ring buffer until retreived. -+ -+ WARNING: This software should never be enabled (it can be built -+ but should not be turned on after it is loaded) in a production -+ environment where high latencies are a concern since the -+ sampling mechanism actually introduces latencies for -+ regular tasks while the CPU(s) are being held. -+ -+ If unsure, say N -+ - config PHANTOM - tristate "Sensable PHANToM (PCI)" - depends on PCI -diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile -index b2fb6dbf..22827d5 100644 ---- a/drivers/misc/Makefile -+++ b/drivers/misc/Makefile -@@ -39,6 +39,7 @@ obj-$(CONFIG_C2PORT) += c2port/ - obj-$(CONFIG_HMC6352) += hmc6352.o - obj-y += eeprom/ - obj-y += cb710/ -+obj-$(CONFIG_HWLAT_DETECTOR) += hwlat_detector.o - obj-$(CONFIG_SPEAR13XX_PCIE_GADGET) += spear13xx_pcie_gadget.o - obj-$(CONFIG_VMWARE_BALLOON) += vmw_balloon.o - obj-$(CONFIG_ARM_CHARLCD) += arm-charlcd.o -diff --git a/drivers/misc/hwlat_detector.c b/drivers/misc/hwlat_detector.c -new file mode 100644 -index 0000000..52f5ad5 ---- /dev/null -+++ b/drivers/misc/hwlat_detector.c -@@ -0,0 +1,1240 @@ -+/* -+ * hwlat_detector.c - A simple Hardware Latency detector. -+ * -+ * Use this module to detect large system latencies induced by the behavior of -+ * certain underlying system hardware or firmware, independent of Linux itself. -+ * The code was developed originally to detect the presence of SMIs on Intel -+ * and AMD systems, although there is no dependency upon x86 herein. -+ * -+ * The classical example usage of this module is in detecting the presence of -+ * SMIs or System Management Interrupts on Intel and AMD systems. An SMI is a -+ * somewhat special form of hardware interrupt spawned from earlier CPU debug -+ * modes in which the (BIOS/EFI/etc.) firmware arranges for the South Bridge -+ * LPC (or other device) to generate a special interrupt under certain -+ * circumstances, for example, upon expiration of a special SMI timer device, -+ * due to certain external thermal readings, on certain I/O address accesses, -+ * and other situations. An SMI hits a special CPU pin, triggers a special -+ * SMI mode (complete with special memory map), and the OS is unaware. -+ * -+ * Although certain hardware-inducing latencies are necessary (for example, -+ * a modern system often requires an SMI handler for correct thermal control -+ * and remote management) they can wreak havoc upon any OS-level performance -+ * guarantees toward low-latency, especially when the OS is not even made -+ * aware of the presence of these interrupts. For this reason, we need a -+ * somewhat brute force mechanism to detect these interrupts. In this case, -+ * we do it by hogging all of the CPU(s) for configurable timer intervals, -+ * sampling the built-in CPU timer, looking for discontiguous readings. -+ * -+ * WARNING: This implementation necessarily introduces latencies. Therefore, -+ * you should NEVER use this module in a production environment -+ * requiring any kind of low-latency performance guarantee(s). -+ * -+ * Copyright (C) 2008-2009 Jon Masters, Red Hat, Inc. <jcm@redhat.com> -+ * -+ * Includes useful feedback from Clark Williams <clark@redhat.com> -+ * -+ * This file is licensed under the terms of the GNU General Public -+ * License version 2. This program is licensed "as is" without any -+ * warranty of any kind, whether express or implied. -+ */ -+ -+#include <linux/module.h> -+#include <linux/init.h> -+#include <linux/ring_buffer.h> -+#include <linux/time.h> -+#include <linux/hrtimer.h> -+#include <linux/kthread.h> -+#include <linux/debugfs.h> -+#include <linux/seq_file.h> -+#include <linux/uaccess.h> -+#include <linux/version.h> -+#include <linux/delay.h> -+#include <linux/slab.h> -+#include <linux/trace_clock.h> -+ -+#define BUF_SIZE_DEFAULT 262144UL /* 8K*(sizeof(entry)) */ -+#define BUF_FLAGS (RB_FL_OVERWRITE) /* no block on full */ -+#define U64STR_SIZE 22 /* 20 digits max */ -+ -+#define VERSION "1.0.0" -+#define BANNER "hwlat_detector: " -+#define DRVNAME "hwlat_detector" -+#define DEFAULT_SAMPLE_WINDOW 1000000 /* 1s */ -+#define DEFAULT_SAMPLE_WIDTH 500000 /* 0.5s */ -+#define DEFAULT_LAT_THRESHOLD 10 /* 10us */ -+ -+/* Module metadata */ -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Jon Masters <jcm@redhat.com>"); -+MODULE_DESCRIPTION("A simple hardware latency detector"); -+MODULE_VERSION(VERSION); -+ -+/* Module parameters */ -+ -+static int debug; -+static int enabled; -+static int threshold; -+ -+module_param(debug, int, 0); /* enable debug */ -+module_param(enabled, int, 0); /* enable detector */ -+module_param(threshold, int, 0); /* latency threshold */ -+ -+/* Buffering and sampling */ -+ -+static struct ring_buffer *ring_buffer; /* sample buffer */ -+static DEFINE_MUTEX(ring_buffer_mutex); /* lock changes */ -+static unsigned long buf_size = BUF_SIZE_DEFAULT; -+static struct task_struct *kthread; /* sampling thread */ -+ -+/* DebugFS filesystem entries */ -+ -+static struct dentry *debug_dir; /* debugfs directory */ -+static struct dentry *debug_max; /* maximum TSC delta */ -+static struct dentry *debug_count; /* total detect count */ -+static struct dentry *debug_sample_width; /* sample width us */ -+static struct dentry *debug_sample_window; /* sample window us */ -+static struct dentry *debug_sample; /* raw samples us */ -+static struct dentry *debug_threshold; /* threshold us */ -+static struct dentry *debug_enable; /* enable/disable */ -+ -+/* Individual samples and global state */ -+ -+struct sample; /* latency sample */ -+struct data; /* Global state */ -+ -+/* Sampling functions */ -+static int __buffer_add_sample(struct sample *sample); -+static struct sample *buffer_get_sample(struct sample *sample); -+ -+/* Threading and state */ -+static int kthread_fn(void *unused); -+static int start_kthread(void); -+static int stop_kthread(void); -+static void __reset_stats(void); -+static int init_stats(void); -+ -+/* Debugfs interface */ -+static ssize_t simple_data_read(struct file *filp, char __user *ubuf, -+ size_t cnt, loff_t *ppos, const u64 *entry); -+static ssize_t simple_data_write(struct file *filp, const char __user *ubuf, -+ size_t cnt, loff_t *ppos, u64 *entry); -+static int debug_sample_fopen(struct inode *inode, struct file *filp); -+static ssize_t debug_sample_fread(struct file *filp, char __user *ubuf, -+ size_t cnt, loff_t *ppos); -+static int debug_sample_release(struct inode *inode, struct file *filp); -+static int debug_enable_fopen(struct inode *inode, struct file *filp); -+static ssize_t debug_enable_fread(struct file *filp, char __user *ubuf, -+ size_t cnt, loff_t *ppos); -+static ssize_t debug_enable_fwrite(struct file *file, -+ const char __user *user_buffer, -+ size_t user_size, loff_t *offset); -+ -+/* Initialization functions */ -+static int init_debugfs(void); -+static void free_debugfs(void); -+static int detector_init(void); -+static void detector_exit(void); -+ -+/* Individual latency samples are stored here when detected and packed into -+ * the ring_buffer circular buffer, where they are overwritten when -+ * more than buf_size/sizeof(sample) samples are received. */ -+struct sample { -+ u64 seqnum; /* unique sequence */ -+ u64 duration; /* ktime delta */ -+ u64 outer_duration; /* ktime delta (outer loop) */ -+ struct timespec timestamp; /* wall time */ -+ unsigned long lost; -+}; -+ -+/* keep the global state somewhere. */ -+static struct data { -+ -+ struct mutex lock; /* protect changes */ -+ -+ u64 count; /* total since reset */ -+ u64 max_sample; /* max hardware latency */ -+ u64 threshold; /* sample threshold level */ -+ -+ u64 sample_window; /* total sampling window (on+off) */ -+ u64 sample_width; /* active sampling portion of window */ -+ -+ atomic_t sample_open; /* whether the sample file is open */ -+ -+ wait_queue_head_t wq; /* waitqeue for new sample values */ -+ -+} data; -+ -+/** -+ * __buffer_add_sample - add a new latency sample recording to the ring buffer -+ * @sample: The new latency sample value -+ * -+ * This receives a new latency sample and records it in a global ring buffer. -+ * No additional locking is used in this case. -+ */ -+static int __buffer_add_sample(struct sample *sample) -+{ -+ return ring_buffer_write(ring_buffer, -+ sizeof(struct sample), sample); -+} -+ -+/** -+ * buffer_get_sample - remove a hardware latency sample from the ring buffer -+ * @sample: Pre-allocated storage for the sample -+ * -+ * This retrieves a hardware latency sample from the global circular buffer -+ */ -+static struct sample *buffer_get_sample(struct sample *sample) -+{ -+ struct ring_buffer_event *e = NULL; -+ struct sample *s = NULL; -+ unsigned int cpu = 0; -+ -+ if (!sample) -+ return NULL; -+ -+ mutex_lock(&ring_buffer_mutex); -+ for_each_online_cpu(cpu) { -+ e = ring_buffer_consume(ring_buffer, cpu, NULL, &sample->lost); -+ if (e) -+ break; -+ } -+ -+ if (e) { -+ s = ring_buffer_event_data(e); -+ memcpy(sample, s, sizeof(struct sample)); -+ } else -+ sample = NULL; -+ mutex_unlock(&ring_buffer_mutex); -+ -+ return sample; -+} -+ -+#ifndef CONFIG_TRACING -+#define time_type ktime_t -+#define time_get() ktime_get() -+#define time_to_us(x) ktime_to_us(x) -+#define time_sub(a, b) ktime_sub(a, b) -+#define init_time(a, b) (a).tv64 = b -+#define time_u64(a) ((a).tv64) -+#else -+#define time_type u64 -+#define time_get() trace_clock_local() -+#define time_to_us(x) div_u64(x, 1000) -+#define time_sub(a, b) ((a) - (b)) -+#define init_time(a, b) (a = b) -+#define time_u64(a) a -+#endif -+/** -+ * get_sample - sample the CPU TSC and look for likely hardware latencies -+ * -+ * Used to repeatedly capture the CPU TSC (or similar), looking for potential -+ * hardware-induced latency. Called with interrupts disabled and with -+ * data.lock held. -+ */ -+static int get_sample(void) -+{ -+ time_type start, t1, t2, last_t2; -+ s64 diff, total = 0; -+ u64 sample = 0; -+ u64 outer_sample = 0; -+ int ret = -1; -+ -+ init_time(last_t2, 0); -+ start = time_get(); /* start timestamp */ -+ -+ do { -+ -+ t1 = time_get(); /* we'll look for a discontinuity */ -+ t2 = time_get(); -+ -+ if (time_u64(last_t2)) { -+ /* Check the delta from outer loop (t2 to next t1) */ -+ diff = time_to_us(time_sub(t1, last_t2)); -+ /* This shouldn't happen */ -+ if (diff < 0) { -+ pr_err(BANNER "time running backwards\n"); -+ goto out; -+ } -+ if (diff > outer_sample) -+ outer_sample = diff; -+ } -+ last_t2 = t2; -+ -+ total = time_to_us(time_sub(t2, start)); /* sample width */ -+ -+ /* This checks the inner loop (t1 to t2) */ -+ diff = time_to_us(time_sub(t2, t1)); /* current diff */ -+ -+ /* This shouldn't happen */ -+ if (diff < 0) { -+ pr_err(BANNER "time running backwards\n"); -+ goto out; -+ } -+ -+ if (diff > sample) -+ sample = diff; /* only want highest value */ -+ -+ } while (total <= data.sample_width); -+ -+ ret = 0; -+ -+ /* If we exceed the threshold value, we have found a hardware latency */ -+ if (sample > data.threshold || outer_sample > data.threshold) { -+ struct sample s; -+ -+ ret = 1; -+ -+ data.count++; -+ s.seqnum = data.count; -+ s.duration = sample; -+ s.outer_duration = outer_sample; -+ s.timestamp = CURRENT_TIME; -+ __buffer_add_sample(&s); -+ -+ /* Keep a running maximum ever recorded hardware latency */ -+ if (sample > data.max_sample) -+ data.max_sample = sample; -+ } -+ -+out: -+ return ret; -+} -+ -+/* -+ * kthread_fn - The CPU time sampling/hardware latency detection kernel thread -+ * @unused: A required part of the kthread API. -+ * -+ * Used to periodically sample the CPU TSC via a call to get_sample. We -+ * disable interrupts, which does (intentionally) introduce latency since we -+ * need to ensure nothing else might be running (and thus pre-empting). -+ * Obviously this should never be used in production environments. -+ * -+ * Currently this runs on which ever CPU it was scheduled on, but most -+ * real-worald hardware latency situations occur across several CPUs, -+ * but we might later generalize this if we find there are any actualy -+ * systems with alternate SMI delivery or other hardware latencies. -+ */ -+static int kthread_fn(void *unused) -+{ -+ int ret; -+ u64 interval; -+ -+ while (!kthread_should_stop()) { -+ -+ mutex_lock(&data.lock); -+ -+ local_irq_disable(); -+ ret = get_sample(); -+ local_irq_enable(); -+ -+ if (ret > 0) -+ wake_up(&data.wq); /* wake up reader(s) */ -+ -+ interval = data.sample_window - data.sample_width; -+ do_div(interval, USEC_PER_MSEC); /* modifies interval value */ -+ -+ mutex_unlock(&data.lock); -+ -+ if (msleep_interruptible(interval)) -+ break; -+ } -+ -+ return 0; -+} -+ -+/** -+ * start_kthread - Kick off the hardware latency sampling/detector kthread -+ * -+ * This starts a kernel thread that will sit and sample the CPU timestamp -+ * counter (TSC or similar) and look for potential hardware latencies. -+ */ -+static int start_kthread(void) -+{ -+ kthread = kthread_run(kthread_fn, NULL, -+ DRVNAME); -+ if (IS_ERR(kthread)) { -+ pr_err(BANNER "could not start sampling thread\n"); -+ enabled = 0; -+ return -ENOMEM; -+ } -+ -+ return 0; -+} -+ -+/** -+ * stop_kthread - Inform the hardware latency samping/detector kthread to stop -+ * -+ * This kicks the running hardware latency sampling/detector kernel thread and -+ * tells it to stop sampling now. Use this on unload and at system shutdown. -+ */ -+static int stop_kthread(void) -+{ -+ int ret; -+ -+ ret = kthread_stop(kthread); -+ -+ return ret; -+} -+ -+/** -+ * __reset_stats - Reset statistics for the hardware latency detector -+ * -+ * We use data to store various statistics and global state. We call this -+ * function in order to reset those when "enable" is toggled on or off, and -+ * also at initialization. Should be called with data.lock held. -+ */ -+static void __reset_stats(void) -+{ -+ data.count = 0; -+ data.max_sample = 0; -+ ring_buffer_reset(ring_buffer); /* flush out old sample entries */ -+} -+ -+/** -+ * init_stats - Setup global state statistics for the hardware latency detector -+ * -+ * We use data to store various statistics and global state. We also use -+ * a global ring buffer (ring_buffer) to keep raw samples of detected hardware -+ * induced system latencies. This function initializes these structures and -+ * allocates the global ring buffer also. -+ */ -+static int init_stats(void) -+{ -+ int ret = -ENOMEM; -+ -+ mutex_init(&data.lock); -+ init_waitqueue_head(&data.wq); -+ atomic_set(&data.sample_open, 0); -+ -+ ring_buffer = ring_buffer_alloc(buf_size, BUF_FLAGS); -+ -+ if (WARN(!ring_buffer, KERN_ERR BANNER -+ "failed to allocate ring buffer!\n")) -+ goto out; -+ -+ __reset_stats(); -+ data.threshold = threshold ?: DEFAULT_LAT_THRESHOLD; /* threshold us */ -+ data.sample_window = DEFAULT_SAMPLE_WINDOW; /* window us */ -+ data.sample_width = DEFAULT_SAMPLE_WIDTH; /* width us */ -+ -+ ret = 0; -+ -+out: -+ return ret; -+ -+} -+ -+/* -+ * simple_data_read - Wrapper read function for global state debugfs entries -+ * @filp: The active open file structure for the debugfs "file" -+ * @ubuf: The userspace provided buffer to read value into -+ * @cnt: The maximum number of bytes to read -+ * @ppos: The current "file" position -+ * @entry: The entry to read from -+ * -+ * This function provides a generic read implementation for the global state -+ * "data" structure debugfs filesystem entries. It would be nice to use -+ * simple_attr_read directly, but we need to make sure that the data.lock -+ * is held during the actual read. -+ */ -+static ssize_t simple_data_read(struct file *filp, char __user *ubuf, -+ size_t cnt, loff_t *ppos, const u64 *entry) -+{ -+ char buf[U64STR_SIZE]; -+ u64 val = 0; -+ int len = 0; -+ -+ memset(buf, 0, sizeof(buf)); -+ -+ if (!entry) -+ return -EFAULT; -+ -+ mutex_lock(&data.lock); -+ val = *entry; -+ mutex_unlock(&data.lock); -+ -+ len = snprintf(buf, sizeof(buf), "%llu\n", (unsigned long long)val); -+ -+ return simple_read_from_buffer(ubuf, cnt, ppos, buf, len); -+ -+} -+ -+/* -+ * simple_data_write - Wrapper write function for global state debugfs entries -+ * @filp: The active open file structure for the debugfs "file" -+ * @ubuf: The userspace provided buffer to write value from -+ * @cnt: The maximum number of bytes to write -+ * @ppos: The current "file" position -+ * @entry: The entry to write to -+ * -+ * This function provides a generic write implementation for the global state -+ * "data" structure debugfs filesystem entries. It would be nice to use -+ * simple_attr_write directly, but we need to make sure that the data.lock -+ * is held during the actual write. -+ */ -+static ssize_t simple_data_write(struct file *filp, const char __user *ubuf, -+ size_t cnt, loff_t *ppos, u64 *entry) -+{ -+ char buf[U64STR_SIZE]; -+ int csize = min(cnt, sizeof(buf)); -+ u64 val = 0; -+ int err = 0; -+ -+ memset(buf, '\0', sizeof(buf)); -+ if (copy_from_user(buf, ubuf, csize)) -+ return -EFAULT; -+ -+ buf[U64STR_SIZE-1] = '\0'; /* just in case */ -+ err = kstrtoull(buf, 10, &val); -+ if (err) -+ return -EINVAL; -+ -+ mutex_lock(&data.lock); -+ *entry = val; -+ mutex_unlock(&data.lock); -+ -+ return csize; -+} -+ -+/** -+ * debug_count_fopen - Open function for "count" debugfs entry -+ * @inode: The in-kernel inode representation of the debugfs "file" -+ * @filp: The active open file structure for the debugfs "file" -+ * -+ * This function provides an open implementation for the "count" debugfs -+ * interface to the hardware latency detector. -+ */ -+static int debug_count_fopen(struct inode *inode, struct file *filp) -+{ -+ return 0; -+} -+ -+/** -+ * debug_count_fread - Read function for "count" debugfs entry -+ * @filp: The active open file structure for the debugfs "file" -+ * @ubuf: The userspace provided buffer to read value into -+ * @cnt: The maximum number of bytes to read -+ * @ppos: The current "file" position -+ * -+ * This function provides a read implementation for the "count" debugfs -+ * interface to the hardware latency detector. Can be used to read the -+ * number of latency readings exceeding the configured threshold since -+ * the detector was last reset (e.g. by writing a zero into "count"). -+ */ -+static ssize_t debug_count_fread(struct file *filp, char __user *ubuf, -+ size_t cnt, loff_t *ppos) -+{ -+ return simple_data_read(filp, ubuf, cnt, ppos, &data.count); -+} -+ -+/** -+ * debug_count_fwrite - Write function for "count" debugfs entry -+ * @filp: The active open file structure for the debugfs "file" -+ * @ubuf: The user buffer that contains the value to write -+ * @cnt: The maximum number of bytes to write to "file" -+ * @ppos: The current position in the debugfs "file" -+ * -+ * This function provides a write implementation for the "count" debugfs -+ * interface to the hardware latency detector. Can be used to write a -+ * desired value, especially to zero the total count. -+ */ -+static ssize_t debug_count_fwrite(struct file *filp, -+ const char __user *ubuf, -+ size_t cnt, -+ loff_t *ppos) -+{ -+ return simple_data_write(filp, ubuf, cnt, ppos, &data.count); -+} -+ -+/** -+ * debug_enable_fopen - Dummy open function for "enable" debugfs interface -+ * @inode: The in-kernel inode representation of the debugfs "file" -+ * @filp: The active open file structure for the debugfs "file" -+ * -+ * This function provides an open implementation for the "enable" debugfs -+ * interface to the hardware latency detector. -+ */ -+static int debug_enable_fopen(struct inode *inode, struct file *filp) -+{ -+ return 0; -+} -+ -+/** -+ * debug_enable_fread - Read function for "enable" debugfs interface -+ * @filp: The active open file structure for the debugfs "file" -+ * @ubuf: The userspace provided buffer to read value into -+ * @cnt: The maximum number of bytes to read -+ * @ppos: The current "file" position -+ * -+ * This function provides a read implementation for the "enable" debugfs -+ * interface to the hardware latency detector. Can be used to determine -+ * whether the detector is currently enabled ("0\n" or "1\n" returned). -+ */ -+static ssize_t debug_enable_fread(struct file *filp, char __user *ubuf, -+ size_t cnt, loff_t *ppos) -+{ -+ char buf[4]; -+ -+ if ((cnt < sizeof(buf)) || (*ppos)) -+ return 0; -+ -+ buf[0] = enabled ? '1' : '0'; -+ buf[1] = '\n'; -+ buf[2] = '\0'; -+ if (copy_to_user(ubuf, buf, strlen(buf))) -+ return -EFAULT; -+ return *ppos = strlen(buf); -+} -+ -+/** -+ * debug_enable_fwrite - Write function for "enable" debugfs interface -+ * @filp: The active open file structure for the debugfs "file" -+ * @ubuf: The user buffer that contains the value to write -+ * @cnt: The maximum number of bytes to write to "file" -+ * @ppos: The current position in the debugfs "file" -+ * -+ * This function provides a write implementation for the "enable" debugfs -+ * interface to the hardware latency detector. Can be used to enable or -+ * disable the detector, which will have the side-effect of possibly -+ * also resetting the global stats and kicking off the measuring -+ * kthread (on an enable) or the converse (upon a disable). -+ */ -+static ssize_t debug_enable_fwrite(struct file *filp, -+ const char __user *ubuf, -+ size_t cnt, -+ loff_t *ppos) -+{ -+ char buf[4]; -+ int csize = min(cnt, sizeof(buf)); -+ long val = 0; -+ int err = 0; -+ -+ memset(buf, '\0', sizeof(buf)); -+ if (copy_from_user(buf, ubuf, csize)) -+ return -EFAULT; -+ -+ buf[sizeof(buf)-1] = '\0'; /* just in case */ -+ err = kstrtoul(buf, 10, &val); -+ if (err) -+ return -EINVAL; -+ -+ if (val) { -+ if (enabled) -+ goto unlock; -+ enabled = 1; -+ __reset_stats(); -+ if (start_kthread()) -+ return -EFAULT; -+ } else { -+ if (!enabled) -+ goto unlock; -+ enabled = 0; -+ err = stop_kthread(); -+ if (err) { -+ pr_err(BANNER "cannot stop kthread\n"); -+ return -EFAULT; -+ } -+ wake_up(&data.wq); /* reader(s) should return */ -+ } -+unlock: -+ return csize; -+} -+ -+/** -+ * debug_max_fopen - Open function for "max" debugfs entry -+ * @inode: The in-kernel inode representation of the debugfs "file" -+ * @filp: The active open file structure for the debugfs "file" -+ * -+ * This function provides an open implementation for the "max" debugfs -+ * interface to the hardware latency detector. -+ */ -+static int debug_max_fopen(struct inode *inode, struct file *filp) -+{ -+ return 0; -+} -+ -+/** -+ * debug_max_fread - Read function for "max" debugfs entry -+ * @filp: The active open file structure for the debugfs "file" -+ * @ubuf: The userspace provided buffer to read value into -+ * @cnt: The maximum number of bytes to read -+ * @ppos: The current "file" position -+ * -+ * This function provides a read implementation for the "max" debugfs -+ * interface to the hardware latency detector. Can be used to determine -+ * the maximum latency value observed since it was last reset. -+ */ -+static ssize_t debug_max_fread(struct file *filp, char __user *ubuf, -+ size_t cnt, loff_t *ppos) -+{ -+ return simple_data_read(filp, ubuf, cnt, ppos, &data.max_sample); -+} -+ -+/** -+ * debug_max_fwrite - Write function for "max" debugfs entry -+ * @filp: The active open file structure for the debugfs "file" -+ * @ubuf: The user buffer that contains the value to write -+ * @cnt: The maximum number of bytes to write to "file" -+ * @ppos: The current position in the debugfs "file" -+ * -+ * This function provides a write implementation for the "max" debugfs -+ * interface to the hardware latency detector. Can be used to reset the -+ * maximum or set it to some other desired value - if, then, subsequent -+ * measurements exceed this value, the maximum will be updated. -+ */ -+static ssize_t debug_max_fwrite(struct file *filp, -+ const char __user *ubuf, -+ size_t cnt, -+ loff_t *ppos) -+{ -+ return simple_data_write(filp, ubuf, cnt, ppos, &data.max_sample); -+} -+ -+ -+/** -+ * debug_sample_fopen - An open function for "sample" debugfs interface -+ * @inode: The in-kernel inode representation of this debugfs "file" -+ * @filp: The active open file structure for the debugfs "file" -+ * -+ * This function handles opening the "sample" file within the hardware -+ * latency detector debugfs directory interface. This file is used to read -+ * raw samples from the global ring_buffer and allows the user to see a -+ * running latency history. Can be opened blocking or non-blocking, -+ * affecting whether it behaves as a buffer read pipe, or does not. -+ * Implements simple locking to prevent multiple simultaneous use. -+ */ -+static int debug_sample_fopen(struct inode *inode, struct file *filp) -+{ -+ if (!atomic_add_unless(&data.sample_open, 1, 1)) -+ return -EBUSY; -+ else -+ return 0; -+} -+ -+/** -+ * debug_sample_fread - A read function for "sample" debugfs interface -+ * @filp: The active open file structure for the debugfs "file" -+ * @ubuf: The user buffer that will contain the samples read -+ * @cnt: The maximum bytes to read from the debugfs "file" -+ * @ppos: The current position in the debugfs "file" -+ * -+ * This function handles reading from the "sample" file within the hardware -+ * latency detector debugfs directory interface. This file is used to read -+ * raw samples from the global ring_buffer and allows the user to see a -+ * running latency history. By default this will block pending a new -+ * value written into the sample buffer, unless there are already a -+ * number of value(s) waiting in the buffer, or the sample file was -+ * previously opened in a non-blocking mode of operation. -+ */ -+static ssize_t debug_sample_fread(struct file *filp, char __user *ubuf, -+ size_t cnt, loff_t *ppos) -+{ -+ int len = 0; -+ char buf[64]; -+ struct sample *sample = NULL; -+ -+ if (!enabled) -+ return 0; -+ -+ sample = kzalloc(sizeof(struct sample), GFP_KERNEL); -+ if (!sample) -+ return -ENOMEM; -+ -+ while (!buffer_get_sample(sample)) { -+ -+ DEFINE_WAIT(wait); -+ -+ if (filp->f_flags & O_NONBLOCK) { -+ len = -EAGAIN; -+ goto out; -+ } -+ -+ prepare_to_wait(&data.wq, &wait, TASK_INTERRUPTIBLE); -+ schedule(); -+ finish_wait(&data.wq, &wait); -+ -+ if (signal_pending(current)) { -+ len = -EINTR; -+ goto out; -+ } -+ -+ if (!enabled) { /* enable was toggled */ -+ len = 0; -+ goto out; -+ } -+ } -+ -+ len = snprintf(buf, sizeof(buf), "%010lu.%010lu\t%llu\t%llu\n", -+ sample->timestamp.tv_sec, -+ sample->timestamp.tv_nsec, -+ sample->duration, -+ sample->outer_duration); -+ -+ -+ /* handling partial reads is more trouble than it's worth */ -+ if (len > cnt) -+ goto out; -+ -+ if (copy_to_user(ubuf, buf, len)) -+ len = -EFAULT; -+ -+out: -+ kfree(sample); -+ return len; -+} -+ -+/** -+ * debug_sample_release - Release function for "sample" debugfs interface -+ * @inode: The in-kernel inode represenation of the debugfs "file" -+ * @filp: The active open file structure for the debugfs "file" -+ * -+ * This function completes the close of the debugfs interface "sample" file. -+ * Frees the sample_open "lock" so that other users may open the interface. -+ */ -+static int debug_sample_release(struct inode *inode, struct file *filp) -+{ -+ atomic_dec(&data.sample_open); -+ -+ return 0; -+} -+ -+/** -+ * debug_threshold_fopen - Open function for "threshold" debugfs entry -+ * @inode: The in-kernel inode representation of the debugfs "file" -+ * @filp: The active open file structure for the debugfs "file" -+ * -+ * This function provides an open implementation for the "threshold" debugfs -+ * interface to the hardware latency detector. -+ */ -+static int debug_threshold_fopen(struct inode *inode, struct file *filp) -+{ -+ return 0; -+} -+ -+/** -+ * debug_threshold_fread - Read function for "threshold" debugfs entry -+ * @filp: The active open file structure for the debugfs "file" -+ * @ubuf: The userspace provided buffer to read value into -+ * @cnt: The maximum number of bytes to read -+ * @ppos: The current "file" position -+ * -+ * This function provides a read implementation for the "threshold" debugfs -+ * interface to the hardware latency detector. It can be used to determine -+ * the current threshold level at which a latency will be recorded in the -+ * global ring buffer, typically on the order of 10us. -+ */ -+static ssize_t debug_threshold_fread(struct file *filp, char __user *ubuf, -+ size_t cnt, loff_t *ppos) -+{ -+ return simple_data_read(filp, ubuf, cnt, ppos, &data.threshold); -+} -+ -+/** -+ * debug_threshold_fwrite - Write function for "threshold" debugfs entry -+ * @filp: The active open file structure for the debugfs "file" -+ * @ubuf: The user buffer that contains the value to write -+ * @cnt: The maximum number of bytes to write to "file" -+ * @ppos: The current position in the debugfs "file" -+ * -+ * This function provides a write implementation for the "threshold" debugfs -+ * interface to the hardware latency detector. It can be used to configure -+ * the threshold level at which any subsequently detected latencies will -+ * be recorded into the global ring buffer. -+ */ -+static ssize_t debug_threshold_fwrite(struct file *filp, -+ const char __user *ubuf, -+ size_t cnt, -+ loff_t *ppos) -+{ -+ int ret; -+ -+ ret = simple_data_write(filp, ubuf, cnt, ppos, &data.threshold); -+ -+ if (enabled) -+ wake_up_process(kthread); -+ -+ return ret; -+} -+ -+/** -+ * debug_width_fopen - Open function for "width" debugfs entry -+ * @inode: The in-kernel inode representation of the debugfs "file" -+ * @filp: The active open file structure for the debugfs "file" -+ * -+ * This function provides an open implementation for the "width" debugfs -+ * interface to the hardware latency detector. -+ */ -+static int debug_width_fopen(struct inode *inode, struct file *filp) -+{ -+ return 0; -+} -+ -+/** -+ * debug_width_fread - Read function for "width" debugfs entry -+ * @filp: The active open file structure for the debugfs "file" -+ * @ubuf: The userspace provided buffer to read value into -+ * @cnt: The maximum number of bytes to read -+ * @ppos: The current "file" position -+ * -+ * This function provides a read implementation for the "width" debugfs -+ * interface to the hardware latency detector. It can be used to determine -+ * for how many us of the total window us we will actively sample for any -+ * hardware-induced latecy periods. Obviously, it is not possible to -+ * sample constantly and have the system respond to a sample reader, or, -+ * worse, without having the system appear to have gone out to lunch. -+ */ -+static ssize_t debug_width_fread(struct file *filp, char __user *ubuf, -+ size_t cnt, loff_t *ppos) -+{ -+ return simple_data_read(filp, ubuf, cnt, ppos, &data.sample_width); -+} -+ -+/** -+ * debug_width_fwrite - Write function for "width" debugfs entry -+ * @filp: The active open file structure for the debugfs "file" -+ * @ubuf: The user buffer that contains the value to write -+ * @cnt: The maximum number of bytes to write to "file" -+ * @ppos: The current position in the debugfs "file" -+ * -+ * This function provides a write implementation for the "width" debugfs -+ * interface to the hardware latency detector. It can be used to configure -+ * for how many us of the total window us we will actively sample for any -+ * hardware-induced latency periods. Obviously, it is not possible to -+ * sample constantly and have the system respond to a sample reader, or, -+ * worse, without having the system appear to have gone out to lunch. It -+ * is enforced that width is less that the total window size. -+ */ -+static ssize_t debug_width_fwrite(struct file *filp, -+ const char __user *ubuf, -+ size_t cnt, -+ loff_t *ppos) -+{ -+ char buf[U64STR_SIZE]; -+ int csize = min(cnt, sizeof(buf)); -+ u64 val = 0; -+ int err = 0; -+ -+ memset(buf, '\0', sizeof(buf)); -+ if (copy_from_user(buf, ubuf, csize)) -+ return -EFAULT; -+ -+ buf[U64STR_SIZE-1] = '\0'; /* just in case */ -+ err = kstrtoull(buf, 10, &val); -+ if (err) -+ return -EINVAL; -+ -+ mutex_lock(&data.lock); -+ if (val < data.sample_window) -+ data.sample_width = val; -+ else { -+ mutex_unlock(&data.lock); -+ return -EINVAL; -+ } -+ mutex_unlock(&data.lock); -+ -+ if (enabled) -+ wake_up_process(kthread); -+ -+ return csize; -+} -+ -+/** -+ * debug_window_fopen - Open function for "window" debugfs entry -+ * @inode: The in-kernel inode representation of the debugfs "file" -+ * @filp: The active open file structure for the debugfs "file" -+ * -+ * This function provides an open implementation for the "window" debugfs -+ * interface to the hardware latency detector. The window is the total time -+ * in us that will be considered one sample period. Conceptually, windows -+ * occur back-to-back and contain a sample width period during which -+ * actual sampling occurs. -+ */ -+static int debug_window_fopen(struct inode *inode, struct file *filp) -+{ -+ return 0; -+} -+ -+/** -+ * debug_window_fread - Read function for "window" debugfs entry -+ * @filp: The active open file structure for the debugfs "file" -+ * @ubuf: The userspace provided buffer to read value into -+ * @cnt: The maximum number of bytes to read -+ * @ppos: The current "file" position -+ * -+ * This function provides a read implementation for the "window" debugfs -+ * interface to the hardware latency detector. The window is the total time -+ * in us that will be considered one sample period. Conceptually, windows -+ * occur back-to-back and contain a sample width period during which -+ * actual sampling occurs. Can be used to read the total window size. -+ */ -+static ssize_t debug_window_fread(struct file *filp, char __user *ubuf, -+ size_t cnt, loff_t *ppos) -+{ -+ return simple_data_read(filp, ubuf, cnt, ppos, &data.sample_window); -+} -+ -+/** -+ * debug_window_fwrite - Write function for "window" debugfs entry -+ * @filp: The active open file structure for the debugfs "file" -+ * @ubuf: The user buffer that contains the value to write -+ * @cnt: The maximum number of bytes to write to "file" -+ * @ppos: The current position in the debugfs "file" -+ * -+ * This function provides a write implementation for the "window" debufds -+ * interface to the hardware latency detetector. The window is the total time -+ * in us that will be considered one sample period. Conceptually, windows -+ * occur back-to-back and contain a sample width period during which -+ * actual sampling occurs. Can be used to write a new total window size. It -+ * is enfoced that any value written must be greater than the sample width -+ * size, or an error results. -+ */ -+static ssize_t debug_window_fwrite(struct file *filp, -+ const char __user *ubuf, -+ size_t cnt, -+ loff_t *ppos) -+{ -+ char buf[U64STR_SIZE]; -+ int csize = min(cnt, sizeof(buf)); -+ u64 val = 0; -+ int err = 0; -+ -+ memset(buf, '\0', sizeof(buf)); -+ if (copy_from_user(buf, ubuf, csize)) -+ return -EFAULT; -+ -+ buf[U64STR_SIZE-1] = '\0'; /* just in case */ -+ err = kstrtoull(buf, 10, &val); -+ if (err) -+ return -EINVAL; -+ -+ mutex_lock(&data.lock); -+ if (data.sample_width < val) -+ data.sample_window = val; -+ else { -+ mutex_unlock(&data.lock); -+ return -EINVAL; -+ } -+ mutex_unlock(&data.lock); -+ -+ return csize; -+} -+ -+/* -+ * Function pointers for the "count" debugfs file operations -+ */ -+static const struct file_operations count_fops = { -+ .open = debug_count_fopen, -+ .read = debug_count_fread, -+ .write = debug_count_fwrite, -+ .owner = THIS_MODULE, -+}; -+ -+/* -+ * Function pointers for the "enable" debugfs file operations -+ */ -+static const struct file_operations enable_fops = { -+ .open = debug_enable_fopen, -+ .read = debug_enable_fread, -+ .write = debug_enable_fwrite, -+ .owner = THIS_MODULE, -+}; -+ -+/* -+ * Function pointers for the "max" debugfs file operations -+ */ -+static const struct file_operations max_fops = { -+ .open = debug_max_fopen, -+ .read = debug_max_fread, -+ .write = debug_max_fwrite, -+ .owner = THIS_MODULE, -+}; -+ -+/* -+ * Function pointers for the "sample" debugfs file operations -+ */ -+static const struct file_operations sample_fops = { -+ .open = debug_sample_fopen, -+ .read = debug_sample_fread, -+ .release = debug_sample_release, -+ .owner = THIS_MODULE, -+}; -+ -+/* -+ * Function pointers for the "threshold" debugfs file operations -+ */ -+static const struct file_operations threshold_fops = { -+ .open = debug_threshold_fopen, -+ .read = debug_threshold_fread, -+ .write = debug_threshold_fwrite, -+ .owner = THIS_MODULE, -+}; -+ -+/* -+ * Function pointers for the "width" debugfs file operations -+ */ -+static const struct file_operations width_fops = { -+ .open = debug_width_fopen, -+ .read = debug_width_fread, -+ .write = debug_width_fwrite, -+ .owner = THIS_MODULE, -+}; -+ -+/* -+ * Function pointers for the "window" debugfs file operations -+ */ -+static const struct file_operations window_fops = { -+ .open = debug_window_fopen, -+ .read = debug_window_fread, -+ .write = debug_window_fwrite, -+ .owner = THIS_MODULE, -+}; -+ -+/** -+ * init_debugfs - A function to initialize the debugfs interface files -+ * -+ * This function creates entries in debugfs for "hwlat_detector", including -+ * files to read values from the detector, current samples, and the -+ * maximum sample that has been captured since the hardware latency -+ * dectector was started. -+ */ -+static int init_debugfs(void) -+{ -+ int ret = -ENOMEM; -+ -+ debug_dir = debugfs_create_dir(DRVNAME, NULL); -+ if (!debug_dir) -+ goto err_debug_dir; -+ -+ debug_sample = debugfs_create_file("sample", 0444, -+ debug_dir, NULL, -+ &sample_fops); -+ if (!debug_sample) -+ goto err_sample; -+ -+ debug_count = debugfs_create_file("count", 0444, -+ debug_dir, NULL, -+ &count_fops); -+ if (!debug_count) -+ goto err_count; -+ -+ debug_max = debugfs_create_file("max", 0444, -+ debug_dir, NULL, -+ &max_fops); -+ if (!debug_max) -+ goto err_max; -+ -+ debug_sample_window = debugfs_create_file("window", 0644, -+ debug_dir, NULL, -+ &window_fops); -+ if (!debug_sample_window) -+ goto err_window; -+ -+ debug_sample_width = debugfs_create_file("width", 0644, -+ debug_dir, NULL, -+ &width_fops); -+ if (!debug_sample_width) -+ goto err_width; -+ -+ debug_threshold = debugfs_create_file("threshold", 0644, -+ debug_dir, NULL, -+ &threshold_fops); -+ if (!debug_threshold) -+ goto err_threshold; -+ -+ debug_enable = debugfs_create_file("enable", 0644, -+ debug_dir, &enabled, -+ &enable_fops); -+ if (!debug_enable) -+ goto err_enable; -+ -+ else { -+ ret = 0; -+ goto out; -+ } -+ -+err_enable: -+ debugfs_remove(debug_threshold); -+err_threshold: -+ debugfs_remove(debug_sample_width); -+err_width: -+ debugfs_remove(debug_sample_window); -+err_window: -+ debugfs_remove(debug_max); -+err_max: -+ debugfs_remove(debug_count); -+err_count: -+ debugfs_remove(debug_sample); -+err_sample: -+ debugfs_remove(debug_dir); -+err_debug_dir: -+out: -+ return ret; -+} -+ -+/** -+ * free_debugfs - A function to cleanup the debugfs file interface -+ */ -+static void free_debugfs(void) -+{ -+ /* could also use a debugfs_remove_recursive */ -+ debugfs_remove(debug_enable); -+ debugfs_remove(debug_threshold); -+ debugfs_remove(debug_sample_width); -+ debugfs_remove(debug_sample_window); -+ debugfs_remove(debug_max); -+ debugfs_remove(debug_count); -+ debugfs_remove(debug_sample); -+ debugfs_remove(debug_dir); -+} -+ -+/** -+ * detector_init - Standard module initialization code -+ */ -+static int detector_init(void) -+{ -+ int ret = -ENOMEM; -+ -+ pr_info(BANNER "version %s\n", VERSION); -+ -+ ret = init_stats(); -+ if (ret) -+ goto out; -+ -+ ret = init_debugfs(); -+ if (ret) -+ goto err_stats; -+ -+ if (enabled) -+ ret = start_kthread(); -+ -+ goto out; -+ -+err_stats: -+ ring_buffer_free(ring_buffer); -+out: -+ return ret; -+ -+} -+ -+/** -+ * detector_exit - Standard module cleanup code -+ */ -+static void detector_exit(void) -+{ -+ int err; -+ -+ if (enabled) { -+ enabled = 0; -+ err = stop_kthread(); -+ if (err) -+ pr_err(BANNER "cannot stop kthread\n"); -+ } -+ -+ free_debugfs(); -+ ring_buffer_free(ring_buffer); /* free up the ring buffer */ -+ -+} -+ -+module_init(detector_init); -+module_exit(detector_exit); -diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c -index 2e6c968..578ddbe 100644 ---- a/drivers/mmc/host/mmci.c -+++ b/drivers/mmc/host/mmci.c -@@ -1155,15 +1155,12 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id) - struct sg_mapping_iter *sg_miter = &host->sg_miter; - struct variant_data *variant = host->variant; - void __iomem *base = host->base; -- unsigned long flags; - u32 status; - - status = readl(base + MMCISTATUS); - - dev_dbg(mmc_dev(host->mmc), "irq1 (pio) %08x\n", status); - -- local_irq_save(flags); -- - do { - unsigned int remain, len; - char *buffer; -@@ -1203,8 +1200,6 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id) - - sg_miter_stop(sg_miter); - -- local_irq_restore(flags); -- - /* - * If we have less than the fifo 'half-full' threshold to transfer, - * trigger a PIO interrupt as soon as any data is available. -diff --git a/drivers/net/ethernet/3com/3c59x.c b/drivers/net/ethernet/3com/3c59x.c -index d81fced..dbcecb8 100644 ---- a/drivers/net/ethernet/3com/3c59x.c -+++ b/drivers/net/ethernet/3com/3c59x.c -@@ -842,9 +842,9 @@ static void poll_vortex(struct net_device *dev) - { - struct vortex_private *vp = netdev_priv(dev); - unsigned long flags; -- local_irq_save(flags); -+ local_irq_save_nort(flags); - (vp->full_bus_master_rx ? boomerang_interrupt:vortex_interrupt)(dev->irq,dev); -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - } - #endif - -@@ -1910,12 +1910,12 @@ static void vortex_tx_timeout(struct net_device *dev) - * Block interrupts because vortex_interrupt does a bare spin_lock() - */ - unsigned long flags; -- local_irq_save(flags); -+ local_irq_save_nort(flags); - if (vp->full_bus_master_tx) - boomerang_interrupt(dev->irq, dev); - else - vortex_interrupt(dev->irq, dev); -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - } - } - -diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c -index d0084d4..3837077 100644 ---- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c -+++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c -@@ -2217,11 +2217,7 @@ static netdev_tx_t atl1c_xmit_frame(struct sk_buff *skb, - } - - tpd_req = atl1c_cal_tpd_req(skb); -- if (!spin_trylock_irqsave(&adapter->tx_lock, flags)) { -- if (netif_msg_pktdata(adapter)) -- dev_info(&adapter->pdev->dev, "tx locked\n"); -- return NETDEV_TX_LOCKED; -- } -+ spin_lock_irqsave(&adapter->tx_lock, flags); - - if (atl1c_tpd_avail(adapter, type) < tpd_req) { - /* no enough descriptor, just stop queue */ -diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c -index 59a03a1..734f7a7 100644 ---- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c -+++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c -@@ -1880,8 +1880,7 @@ static netdev_tx_t atl1e_xmit_frame(struct sk_buff *skb, - return NETDEV_TX_OK; - } - tpd_req = atl1e_cal_tdp_req(skb); -- if (!spin_trylock_irqsave(&adapter->tx_lock, flags)) -- return NETDEV_TX_LOCKED; -+ spin_lock_irqsave(&adapter->tx_lock, flags); - - if (atl1e_tpd_avail(adapter) < tpd_req) { - /* no enough descriptor, just stop queue */ -diff --git a/drivers/net/ethernet/chelsio/cxgb/sge.c b/drivers/net/ethernet/chelsio/cxgb/sge.c -index 526ea74..86f467a 100644 ---- a/drivers/net/ethernet/chelsio/cxgb/sge.c -+++ b/drivers/net/ethernet/chelsio/cxgb/sge.c -@@ -1664,8 +1664,7 @@ static int t1_sge_tx(struct sk_buff *skb, struct adapter *adapter, - struct cmdQ *q = &sge->cmdQ[qid]; - unsigned int credits, pidx, genbit, count, use_sched_skb = 0; - -- if (!spin_trylock(&q->lock)) -- return NETDEV_TX_LOCKED; -+ spin_lock(&q->lock); - - reclaim_completed_tx(sge, q); - -diff --git a/drivers/net/ethernet/neterion/s2io.c b/drivers/net/ethernet/neterion/s2io.c -index 9ba9758..813cfa6 100644 ---- a/drivers/net/ethernet/neterion/s2io.c -+++ b/drivers/net/ethernet/neterion/s2io.c -@@ -4084,12 +4084,7 @@ static netdev_tx_t s2io_xmit(struct sk_buff *skb, struct net_device *dev) - [skb->priority & (MAX_TX_FIFOS - 1)]; - fifo = &mac_control->fifos[queue]; - -- if (do_spin_lock) -- spin_lock_irqsave(&fifo->tx_lock, flags); -- else { -- if (unlikely(!spin_trylock_irqsave(&fifo->tx_lock, flags))) -- return NETDEV_TX_LOCKED; -- } -+ spin_lock_irqsave(&fifo->tx_lock, flags); - - if (sp->config.multiq) { - if (__netif_subqueue_stopped(dev, fifo->fifo_no)) { -diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c -index 3b98b263b..ca4add7 100644 ---- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c -+++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c -@@ -2137,10 +2137,8 @@ static int pch_gbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev) - struct pch_gbe_tx_ring *tx_ring = adapter->tx_ring; - unsigned long flags; - -- if (!spin_trylock_irqsave(&tx_ring->tx_lock, flags)) { -- /* Collision - tell upper layer to requeue */ -- return NETDEV_TX_LOCKED; -- } -+ spin_lock_irqsave(&tx_ring->tx_lock, flags); -+ - if (unlikely(!PCH_GBE_DESC_UNUSED(tx_ring))) { - netif_stop_queue(netdev); - spin_unlock_irqrestore(&tx_ring->tx_lock, flags); -diff --git a/drivers/net/ethernet/realtek/8139too.c b/drivers/net/ethernet/realtek/8139too.c -index ef668d3..d987d57 100644 ---- a/drivers/net/ethernet/realtek/8139too.c -+++ b/drivers/net/ethernet/realtek/8139too.c -@@ -2229,7 +2229,7 @@ static void rtl8139_poll_controller(struct net_device *dev) - struct rtl8139_private *tp = netdev_priv(dev); - const int irq = tp->pci_dev->irq; - -- disable_irq(irq); -+ disable_irq_nosync(irq); - rtl8139_interrupt(irq, dev); - enable_irq(irq); - } -diff --git a/drivers/net/ethernet/tehuti/tehuti.c b/drivers/net/ethernet/tehuti/tehuti.c -index 14c9d1b..e1a5305 100644 ---- a/drivers/net/ethernet/tehuti/tehuti.c -+++ b/drivers/net/ethernet/tehuti/tehuti.c -@@ -1629,13 +1629,8 @@ static netdev_tx_t bdx_tx_transmit(struct sk_buff *skb, - unsigned long flags; - - ENTER; -- local_irq_save(flags); -- if (!spin_trylock(&priv->tx_lock)) { -- local_irq_restore(flags); -- DBG("%s[%s]: TX locked, returning NETDEV_TX_LOCKED\n", -- BDX_DRV_NAME, ndev->name); -- return NETDEV_TX_LOCKED; -- } -+ -+ spin_lock_irqsave(&priv->tx_lock, flags); - - /* build tx descriptor */ - BDX_ASSERT(f->m.wptr >= f->m.memsz); /* started with valid wptr */ -diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c -index 9cfe6ae..a31f461 100644 ---- a/drivers/net/rionet.c -+++ b/drivers/net/rionet.c -@@ -179,11 +179,7 @@ static int rionet_start_xmit(struct sk_buff *skb, struct net_device *ndev) - unsigned long flags; - int add_num = 1; - -- local_irq_save(flags); -- if (!spin_trylock(&rnet->tx_lock)) { -- local_irq_restore(flags); -- return NETDEV_TX_LOCKED; -- } -+ spin_lock_irqsave(&rnet->tx_lock, flags); - - if (is_multicast_ether_addr(eth->h_dest)) - add_num = nets[rnet->mport->id].nact; -diff --git a/drivers/net/wireless/intersil/orinoco/orinoco_usb.c b/drivers/net/wireless/intersil/orinoco/orinoco_usb.c -index f2cd513..6c0f4c9 100644 ---- a/drivers/net/wireless/intersil/orinoco/orinoco_usb.c -+++ b/drivers/net/wireless/intersil/orinoco/orinoco_usb.c -@@ -697,7 +697,7 @@ static void ezusb_req_ctx_wait(struct ezusb_priv *upriv, - while (!ctx->done.done && msecs--) - udelay(1000); - } else { -- wait_event_interruptible(ctx->done.wait, -+ swait_event_interruptible(ctx->done.wait, - ctx->done.done); - } - break; -diff --git a/drivers/pci/access.c b/drivers/pci/access.c -index d11cdbb..223bbb9 100644 ---- a/drivers/pci/access.c -+++ b/drivers/pci/access.c -@@ -672,7 +672,7 @@ void pci_cfg_access_unlock(struct pci_dev *dev) - WARN_ON(!dev->block_cfg_access); - - dev->block_cfg_access = 0; -- wake_up_all(&pci_cfg_wait); -+ wake_up_all_locked(&pci_cfg_wait); - raw_spin_unlock_irqrestore(&pci_lock, flags); - } - EXPORT_SYMBOL_GPL(pci_cfg_access_unlock); -diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c -index 0efe711..3d23265 100644 ---- a/drivers/scsi/fcoe/fcoe.c -+++ b/drivers/scsi/fcoe/fcoe.c -@@ -1286,7 +1286,7 @@ static void fcoe_percpu_thread_destroy(unsigned int cpu) - struct sk_buff *skb; - #ifdef CONFIG_SMP - struct fcoe_percpu_s *p0; -- unsigned targ_cpu = get_cpu(); -+ unsigned targ_cpu = get_cpu_light(); - #endif /* CONFIG_SMP */ - - FCOE_DBG("Destroying receive thread for CPU %d\n", cpu); -@@ -1342,7 +1342,7 @@ static void fcoe_percpu_thread_destroy(unsigned int cpu) - kfree_skb(skb); - spin_unlock_bh(&p->fcoe_rx_list.lock); - } -- put_cpu(); -+ put_cpu_light(); - #else - /* - * This a non-SMP scenario where the singular Rx thread is -@@ -1566,11 +1566,11 @@ err2: - static int fcoe_alloc_paged_crc_eof(struct sk_buff *skb, int tlen) - { - struct fcoe_percpu_s *fps; -- int rc; -+ int rc, cpu = get_cpu_light(); - -- fps = &get_cpu_var(fcoe_percpu); -+ fps = &per_cpu(fcoe_percpu, cpu); - rc = fcoe_get_paged_crc_eof(skb, tlen, fps); -- put_cpu_var(fcoe_percpu); -+ put_cpu_light(); - - return rc; - } -@@ -1766,11 +1766,11 @@ static inline int fcoe_filter_frames(struct fc_lport *lport, - return 0; - } - -- stats = per_cpu_ptr(lport->stats, get_cpu()); -+ stats = per_cpu_ptr(lport->stats, get_cpu_light()); - stats->InvalidCRCCount++; - if (stats->InvalidCRCCount < 5) - printk(KERN_WARNING "fcoe: dropping frame with CRC error\n"); -- put_cpu(); -+ put_cpu_light(); - return -EINVAL; - } - -@@ -1846,13 +1846,13 @@ static void fcoe_recv_frame(struct sk_buff *skb) - goto drop; - - if (!fcoe_filter_frames(lport, fp)) { -- put_cpu(); -+ put_cpu_light(); - fc_exch_recv(lport, fp); - return; - } - drop: - stats->ErrorFrames++; -- put_cpu(); -+ put_cpu_light(); - kfree_skb(skb); - } - -diff --git a/drivers/scsi/fcoe/fcoe_ctlr.c b/drivers/scsi/fcoe/fcoe_ctlr.c -index 3e83d48..bc69ff9 100644 ---- a/drivers/scsi/fcoe/fcoe_ctlr.c -+++ b/drivers/scsi/fcoe/fcoe_ctlr.c -@@ -831,7 +831,7 @@ static unsigned long fcoe_ctlr_age_fcfs(struct fcoe_ctlr *fip) - - INIT_LIST_HEAD(&del_list); - -- stats = per_cpu_ptr(fip->lp->stats, get_cpu()); -+ stats = per_cpu_ptr(fip->lp->stats, get_cpu_light()); - - list_for_each_entry_safe(fcf, next, &fip->fcfs, list) { - deadline = fcf->time + fcf->fka_period + fcf->fka_period / 2; -@@ -867,7 +867,7 @@ static unsigned long fcoe_ctlr_age_fcfs(struct fcoe_ctlr *fip) - sel_time = fcf->time; - } - } -- put_cpu(); -+ put_cpu_light(); - - list_for_each_entry_safe(fcf, next, &del_list, list) { - /* Removes fcf from current list */ -diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c -index 30f9ef0..6c686bc 100644 ---- a/drivers/scsi/libfc/fc_exch.c -+++ b/drivers/scsi/libfc/fc_exch.c -@@ -814,10 +814,10 @@ static struct fc_exch *fc_exch_em_alloc(struct fc_lport *lport, - } - memset(ep, 0, sizeof(*ep)); - -- cpu = get_cpu(); -+ cpu = get_cpu_light(); - pool = per_cpu_ptr(mp->pool, cpu); - spin_lock_bh(&pool->lock); -- put_cpu(); -+ put_cpu_light(); - - /* peek cache of free slot */ - if (pool->left != FC_XID_UNKNOWN) { -diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c -index 9c706d8..d968ffc 100644 ---- a/drivers/scsi/libsas/sas_ata.c -+++ b/drivers/scsi/libsas/sas_ata.c -@@ -190,7 +190,7 @@ static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc) - /* TODO: audit callers to ensure they are ready for qc_issue to - * unconditionally re-enable interrupts - */ -- local_irq_save(flags); -+ local_irq_save_nort(flags); - spin_unlock(ap->lock); - - /* If the device fell off, no sense in issuing commands */ -@@ -255,7 +255,7 @@ static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc) - - out: - spin_lock(ap->lock); -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - return ret; - } - -diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h -index edc48f3..ee5c6f9 100644 ---- a/drivers/scsi/qla2xxx/qla_inline.h -+++ b/drivers/scsi/qla2xxx/qla_inline.h -@@ -59,12 +59,12 @@ qla2x00_poll(struct rsp_que *rsp) - { - unsigned long flags; - struct qla_hw_data *ha = rsp->hw; -- local_irq_save(flags); -+ local_irq_save_nort(flags); - if (IS_P3P_TYPE(ha)) - qla82xx_poll(0, rsp); - else - ha->isp_ops->intr_handler(0, rsp); -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - } - - static inline uint8_t * -diff --git a/drivers/thermal/x86_pkg_temp_thermal.c b/drivers/thermal/x86_pkg_temp_thermal.c -index 7fc919f..a774f0c 100644 ---- a/drivers/thermal/x86_pkg_temp_thermal.c -+++ b/drivers/thermal/x86_pkg_temp_thermal.c -@@ -29,6 +29,7 @@ - #include <linux/pm.h> - #include <linux/thermal.h> - #include <linux/debugfs.h> -+#include <linux/work-simple.h> - #include <asm/cpu_device_id.h> - #include <asm/mce.h> - -@@ -352,7 +353,7 @@ static void pkg_temp_thermal_threshold_work_fn(struct work_struct *work) - } - } - --static int pkg_temp_thermal_platform_thermal_notify(__u64 msr_val) -+static void platform_thermal_notify_work(struct swork_event *event) - { - unsigned long flags; - int cpu = smp_processor_id(); -@@ -369,7 +370,7 @@ static int pkg_temp_thermal_platform_thermal_notify(__u64 msr_val) - pkg_work_scheduled[phy_id]) { - disable_pkg_thres_interrupt(); - spin_unlock_irqrestore(&pkg_work_lock, flags); -- return -EINVAL; -+ return; - } - pkg_work_scheduled[phy_id] = 1; - spin_unlock_irqrestore(&pkg_work_lock, flags); -@@ -378,9 +379,48 @@ static int pkg_temp_thermal_platform_thermal_notify(__u64 msr_val) - schedule_delayed_work_on(cpu, - &per_cpu(pkg_temp_thermal_threshold_work, cpu), - msecs_to_jiffies(notify_delay_ms)); -+} -+ -+#ifdef CONFIG_PREEMPT_RT_FULL -+static struct swork_event notify_work; -+ -+static int thermal_notify_work_init(void) -+{ -+ int err; -+ -+ err = swork_get(); -+ if (err) -+ return err; -+ -+ INIT_SWORK(¬ify_work, platform_thermal_notify_work); - return 0; - } - -+static void thermal_notify_work_cleanup(void) -+{ -+ swork_put(); -+} -+ -+static int pkg_temp_thermal_platform_thermal_notify(__u64 msr_val) -+{ -+ swork_queue(¬ify_work); -+ return 0; -+} -+ -+#else /* !CONFIG_PREEMPT_RT_FULL */ -+ -+static int thermal_notify_work_init(void) { return 0; } -+ -+static void thermal_notify_work_cleanup(void) { } -+ -+static int pkg_temp_thermal_platform_thermal_notify(__u64 msr_val) -+{ -+ platform_thermal_notify_work(NULL); -+ -+ return 0; -+} -+#endif /* CONFIG_PREEMPT_RT_FULL */ -+ - static int find_siblings_cpu(int cpu) - { - int i; -@@ -584,6 +624,9 @@ static int __init pkg_temp_thermal_init(void) - if (!x86_match_cpu(pkg_temp_thermal_ids)) - return -ENODEV; - -+ if (!thermal_notify_work_init()) -+ return -ENODEV; -+ - spin_lock_init(&pkg_work_lock); - platform_thermal_package_notify = - pkg_temp_thermal_platform_thermal_notify; -@@ -608,7 +651,7 @@ err_ret: - kfree(pkg_work_scheduled); - platform_thermal_package_notify = NULL; - platform_thermal_package_rate_control = NULL; -- -+ thermal_notify_work_cleanup(); - return -ENODEV; - } - -@@ -633,6 +676,7 @@ static void __exit pkg_temp_thermal_exit(void) - mutex_unlock(&phy_dev_list_mutex); - platform_thermal_package_notify = NULL; - platform_thermal_package_rate_control = NULL; -+ thermal_notify_work_cleanup(); - for_each_online_cpu(i) - cancel_delayed_work_sync( - &per_cpu(pkg_temp_thermal_threshold_work, i)); -diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c -index 2f4f5ee..6ea6a31 100644 ---- a/drivers/tty/serial/8250/8250_core.c -+++ b/drivers/tty/serial/8250/8250_core.c -@@ -58,7 +58,16 @@ static struct uart_driver serial8250_reg; - - static unsigned int skip_txen_test; /* force skip of txen test at init time */ - --#define PASS_LIMIT 512 -+/* -+ * On -rt we can have a more delays, and legitimately -+ * so - so don't drop work spuriously and spam the -+ * syslog: -+ */ -+#ifdef CONFIG_PREEMPT_RT_FULL -+# define PASS_LIMIT 1000000 -+#else -+# define PASS_LIMIT 512 -+#endif - - #include <asm/serial.h> - /* -diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c -index 00ad263..c9f6a49 100644 ---- a/drivers/tty/serial/8250/8250_port.c -+++ b/drivers/tty/serial/8250/8250_port.c -@@ -35,6 +35,7 @@ - #include <linux/nmi.h> - #include <linux/mutex.h> - #include <linux/slab.h> -+#include <linux/kdb.h> - #include <linux/uaccess.h> - #include <linux/pm_runtime.h> - #include <linux/timer.h> -@@ -3092,9 +3093,9 @@ void serial8250_console_write(struct uart_8250_port *up, const char *s, - - serial8250_rpm_get(up); - -- if (port->sysrq) -+ if (port->sysrq || oops_in_progress) - locked = 0; -- else if (oops_in_progress) -+ else if (in_kdb_printk()) - locked = spin_trylock_irqsave(&port->lock, flags); - else - spin_lock_irqsave(&port->lock, flags); -diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c -index 7c198e0..a26b81c 100644 ---- a/drivers/tty/serial/amba-pl011.c -+++ b/drivers/tty/serial/amba-pl011.c -@@ -2166,13 +2166,19 @@ pl011_console_write(struct console *co, const char *s, unsigned int count) - - clk_enable(uap->clk); - -- local_irq_save(flags); -+ /* -+ * local_irq_save(flags); -+ * -+ * This local_irq_save() is nonsense. If we come in via sysrq -+ * handling then interrupts are already disabled. Aside of -+ * that the port.sysrq check is racy on SMP regardless. -+ */ - if (uap->port.sysrq) - locked = 0; - else if (oops_in_progress) -- locked = spin_trylock(&uap->port.lock); -+ locked = spin_trylock_irqsave(&uap->port.lock, flags); - else -- spin_lock(&uap->port.lock); -+ spin_lock_irqsave(&uap->port.lock, flags); - - /* - * First save the CR then disable the interrupts -@@ -2196,8 +2202,7 @@ pl011_console_write(struct console *co, const char *s, unsigned int count) - pl011_write(old_cr, uap, REG_CR); - - if (locked) -- spin_unlock(&uap->port.lock); -- local_irq_restore(flags); -+ spin_unlock_irqrestore(&uap->port.lock, flags); - - clk_disable(uap->clk); - } -diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c -index a2a5299..0ee7c4c 100644 ---- a/drivers/tty/serial/omap-serial.c -+++ b/drivers/tty/serial/omap-serial.c -@@ -1257,13 +1257,10 @@ serial_omap_console_write(struct console *co, const char *s, - - pm_runtime_get_sync(up->dev); - -- local_irq_save(flags); -- if (up->port.sysrq) -- locked = 0; -- else if (oops_in_progress) -- locked = spin_trylock(&up->port.lock); -+ if (up->port.sysrq || oops_in_progress) -+ locked = spin_trylock_irqsave(&up->port.lock, flags); - else -- spin_lock(&up->port.lock); -+ spin_lock_irqsave(&up->port.lock, flags); - - /* - * First save the IER then disable the interrupts -@@ -1292,8 +1289,7 @@ serial_omap_console_write(struct console *co, const char *s, - pm_runtime_mark_last_busy(up->dev); - pm_runtime_put_autosuspend(up->dev); - if (locked) -- spin_unlock(&up->port.lock); -- local_irq_restore(flags); -+ spin_unlock_irqrestore(&up->port.lock, flags); - } - - static int __init -diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c -index 025a426..73d46e2 100644 ---- a/drivers/tty/serial/sc16is7xx.c -+++ b/drivers/tty/serial/sc16is7xx.c -@@ -1251,7 +1251,7 @@ static int sc16is7xx_probe(struct device *dev, - - /* Setup interrupt */ - ret = devm_request_irq(dev, irq, sc16is7xx_irq, -- IRQF_ONESHOT | flags, dev_name(dev), s); -+ flags, dev_name(dev), s); - if (!ret) - return 0; - -diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c -index 2ca2cef..38af561 100644 ---- a/drivers/usb/core/hcd.c -+++ b/drivers/usb/core/hcd.c -@@ -1759,9 +1759,9 @@ static void __usb_hcd_giveback_urb(struct urb *urb) - * and no one may trigger the above deadlock situation when - * running complete() in tasklet. - */ -- local_irq_save(flags); -+ local_irq_save_nort(flags); - urb->complete(urb); -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - - usb_anchor_resume_wakeups(anchor); - atomic_dec(&urb->use_count); -diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c -index 15b648c..d369e0a 100644 ---- a/drivers/usb/gadget/function/f_fs.c -+++ b/drivers/usb/gadget/function/f_fs.c -@@ -1393,7 +1393,7 @@ static void ffs_data_put(struct ffs_data *ffs) - pr_info("%s(): freeing\n", __func__); - ffs_data_clear(ffs); - BUG_ON(waitqueue_active(&ffs->ev.waitq) || -- waitqueue_active(&ffs->ep0req_completion.wait)); -+ swait_active(&ffs->ep0req_completion.wait)); - kfree(ffs->dev_name); - kfree(ffs); - } -diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c -index e64479f..892bcb6 100644 ---- a/drivers/usb/gadget/legacy/inode.c -+++ b/drivers/usb/gadget/legacy/inode.c -@@ -346,7 +346,7 @@ ep_io (struct ep_data *epdata, void *buf, unsigned len) - spin_unlock_irq (&epdata->dev->lock); - - if (likely (value == 0)) { -- value = wait_event_interruptible (done.wait, done.done); -+ value = swait_event_interruptible (done.wait, done.done); - if (value != 0) { - spin_lock_irq (&epdata->dev->lock); - if (likely (epdata->ep != NULL)) { -@@ -355,7 +355,7 @@ ep_io (struct ep_data *epdata, void *buf, unsigned len) - usb_ep_dequeue (epdata->ep, epdata->req); - spin_unlock_irq (&epdata->dev->lock); - -- wait_event (done.wait, done.done); -+ swait_event (done.wait, done.done); - if (epdata->status == -ECONNRESET) - epdata->status = -EINTR; - } else { -diff --git a/fs/aio.c b/fs/aio.c -index 155f842..14af015 100644 ---- a/fs/aio.c -+++ b/fs/aio.c -@@ -40,6 +40,7 @@ - #include <linux/ramfs.h> - #include <linux/percpu-refcount.h> - #include <linux/mount.h> -+#include <linux/work-simple.h> - - #include <asm/kmap_types.h> - #include <asm/uaccess.h> -@@ -115,7 +116,7 @@ struct kioctx { - struct page **ring_pages; - long nr_pages; - -- struct work_struct free_work; -+ struct swork_event free_work; - - /* - * signals when all in-flight requests are done -@@ -253,6 +254,7 @@ static int __init aio_setup(void) - .mount = aio_mount, - .kill_sb = kill_anon_super, - }; -+ BUG_ON(swork_get()); - aio_mnt = kern_mount(&aio_fs); - if (IS_ERR(aio_mnt)) - panic("Failed to create aio fs mount."); -@@ -568,9 +570,9 @@ static int kiocb_cancel(struct aio_kiocb *kiocb) - return cancel(&kiocb->common); - } - --static void free_ioctx(struct work_struct *work) -+static void free_ioctx(struct swork_event *sev) - { -- struct kioctx *ctx = container_of(work, struct kioctx, free_work); -+ struct kioctx *ctx = container_of(sev, struct kioctx, free_work); - - pr_debug("freeing %p\n", ctx); - -@@ -589,8 +591,8 @@ static void free_ioctx_reqs(struct percpu_ref *ref) - if (ctx->rq_wait && atomic_dec_and_test(&ctx->rq_wait->count)) - complete(&ctx->rq_wait->comp); - -- INIT_WORK(&ctx->free_work, free_ioctx); -- schedule_work(&ctx->free_work); -+ INIT_SWORK(&ctx->free_work, free_ioctx); -+ swork_queue(&ctx->free_work); - } - - /* -@@ -598,9 +600,9 @@ static void free_ioctx_reqs(struct percpu_ref *ref) - * and ctx->users has dropped to 0, so we know no more kiocbs can be submitted - - * now it's safe to cancel any that need to be. - */ --static void free_ioctx_users(struct percpu_ref *ref) -+static void free_ioctx_users_work(struct swork_event *sev) - { -- struct kioctx *ctx = container_of(ref, struct kioctx, users); -+ struct kioctx *ctx = container_of(sev, struct kioctx, free_work); - struct aio_kiocb *req; - - spin_lock_irq(&ctx->ctx_lock); -@@ -619,6 +621,14 @@ static void free_ioctx_users(struct percpu_ref *ref) - percpu_ref_put(&ctx->reqs); - } - -+static void free_ioctx_users(struct percpu_ref *ref) -+{ -+ struct kioctx *ctx = container_of(ref, struct kioctx, users); -+ -+ INIT_SWORK(&ctx->free_work, free_ioctx_users_work); -+ swork_queue(&ctx->free_work); -+} -+ - static int ioctx_add_table(struct kioctx *ctx, struct mm_struct *mm) - { - unsigned i, new_nr; -diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h -index f0d268b..dfbccae 100644 ---- a/fs/autofs4/autofs_i.h -+++ b/fs/autofs4/autofs_i.h -@@ -30,6 +30,7 @@ - #include <linux/sched.h> - #include <linux/mount.h> - #include <linux/namei.h> -+#include <linux/delay.h> - #include <asm/current.h> - #include <linux/uaccess.h> - -diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c -index 9510d8d..893c87d 100644 ---- a/fs/autofs4/expire.c -+++ b/fs/autofs4/expire.c -@@ -148,7 +148,7 @@ again: - parent = p->d_parent; - if (!spin_trylock(&parent->d_lock)) { - spin_unlock(&p->d_lock); -- cpu_relax(); -+ cpu_chill(); - goto relock; - } - spin_unlock(&p->d_lock); -diff --git a/fs/buffer.c b/fs/buffer.c -index af0d9a8..370df12 100644 ---- a/fs/buffer.c -+++ b/fs/buffer.c -@@ -300,8 +300,7 @@ static void end_buffer_async_read(struct buffer_head *bh, int uptodate) - * decide that the page is now completely done. - */ - first = page_buffers(page); -- local_irq_save(flags); -- bit_spin_lock(BH_Uptodate_Lock, &first->b_state); -+ flags = bh_uptodate_lock_irqsave(first); - clear_buffer_async_read(bh); - unlock_buffer(bh); - tmp = bh; -@@ -314,8 +313,7 @@ static void end_buffer_async_read(struct buffer_head *bh, int uptodate) - } - tmp = tmp->b_this_page; - } while (tmp != bh); -- bit_spin_unlock(BH_Uptodate_Lock, &first->b_state); -- local_irq_restore(flags); -+ bh_uptodate_unlock_irqrestore(first, flags); - - /* - * If none of the buffers had errors and they are all -@@ -327,9 +325,7 @@ static void end_buffer_async_read(struct buffer_head *bh, int uptodate) - return; - - still_busy: -- bit_spin_unlock(BH_Uptodate_Lock, &first->b_state); -- local_irq_restore(flags); -- return; -+ bh_uptodate_unlock_irqrestore(first, flags); - } - - /* -@@ -357,8 +353,7 @@ void end_buffer_async_write(struct buffer_head *bh, int uptodate) - } - - first = page_buffers(page); -- local_irq_save(flags); -- bit_spin_lock(BH_Uptodate_Lock, &first->b_state); -+ flags = bh_uptodate_lock_irqsave(first); - - clear_buffer_async_write(bh); - unlock_buffer(bh); -@@ -370,15 +365,12 @@ void end_buffer_async_write(struct buffer_head *bh, int uptodate) - } - tmp = tmp->b_this_page; - } -- bit_spin_unlock(BH_Uptodate_Lock, &first->b_state); -- local_irq_restore(flags); -+ bh_uptodate_unlock_irqrestore(first, flags); - end_page_writeback(page); - return; - - still_busy: -- bit_spin_unlock(BH_Uptodate_Lock, &first->b_state); -- local_irq_restore(flags); -- return; -+ bh_uptodate_unlock_irqrestore(first, flags); - } - EXPORT_SYMBOL(end_buffer_async_write); - -@@ -3314,6 +3306,7 @@ struct buffer_head *alloc_buffer_head(gfp_t gfp_flags) - struct buffer_head *ret = kmem_cache_zalloc(bh_cachep, gfp_flags); - if (ret) { - INIT_LIST_HEAD(&ret->b_assoc_buffers); -+ buffer_head_init_locks(ret); - preempt_disable(); - __this_cpu_inc(bh_accounting.nr); - recalc_bh_state(); -diff --git a/fs/dcache.c b/fs/dcache.c -index d5ecc6e..4c88ca8 100644 ---- a/fs/dcache.c -+++ b/fs/dcache.c -@@ -19,6 +19,7 @@ - #include <linux/mm.h> - #include <linux/fs.h> - #include <linux/fsnotify.h> -+#include <linux/delay.h> - #include <linux/slab.h> - #include <linux/init.h> - #include <linux/hash.h> -@@ -578,7 +579,7 @@ static struct dentry *dentry_kill(struct dentry *dentry) - - failed: - spin_unlock(&dentry->d_lock); -- cpu_relax(); -+ cpu_chill(); - return dentry; /* try again with same dentry */ - } - -@@ -2316,7 +2317,7 @@ again: - if (dentry->d_lockref.count == 1) { - if (!spin_trylock(&inode->i_lock)) { - spin_unlock(&dentry->d_lock); -- cpu_relax(); -+ cpu_chill(); - goto again; - } - dentry->d_flags &= ~DCACHE_CANT_MOUNT; -diff --git a/fs/eventpoll.c b/fs/eventpoll.c -index 8a74a2a..b92f911 100644 ---- a/fs/eventpoll.c -+++ b/fs/eventpoll.c -@@ -510,12 +510,12 @@ static int ep_poll_wakeup_proc(void *priv, void *cookie, int call_nests) - */ - static void ep_poll_safewake(wait_queue_head_t *wq) - { -- int this_cpu = get_cpu(); -+ int this_cpu = get_cpu_light(); - - ep_call_nested(&poll_safewake_ncalls, EP_MAX_NESTS, - ep_poll_wakeup_proc, NULL, wq, (void *) (long) this_cpu); - -- put_cpu(); -+ put_cpu_light(); - } - - static void ep_remove_wait_queue(struct eppoll_entry *pwq) -diff --git a/fs/exec.c b/fs/exec.c -index c4010b8..879fd07 100644 ---- a/fs/exec.c -+++ b/fs/exec.c -@@ -961,12 +961,14 @@ static int exec_mmap(struct mm_struct *mm) - } - } - task_lock(tsk); -+ preempt_disable_rt(); - active_mm = tsk->active_mm; - tsk->mm = mm; - tsk->active_mm = mm; - activate_mm(active_mm, mm); - tsk->mm->vmacache_seqnum = 0; - vmacache_flush(tsk); -+ preempt_enable_rt(); - task_unlock(tsk); - if (old_mm) { - up_read(&old_mm->mmap_sem); -diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c -index 684996c..6e18a06 100644 ---- a/fs/jbd2/checkpoint.c -+++ b/fs/jbd2/checkpoint.c -@@ -116,6 +116,8 @@ void __jbd2_log_wait_for_space(journal_t *journal) - nblocks = jbd2_space_needed(journal); - while (jbd2_log_space_left(journal) < nblocks) { - write_unlock(&journal->j_state_lock); -+ if (current->plug) -+ io_schedule(); - mutex_lock(&journal->j_checkpoint_mutex); - - /* -diff --git a/fs/namespace.c b/fs/namespace.c -index 4fb1691..8f79b5d 100644 ---- a/fs/namespace.c -+++ b/fs/namespace.c -@@ -14,6 +14,7 @@ - #include <linux/mnt_namespace.h> - #include <linux/user_namespace.h> - #include <linux/namei.h> -+#include <linux/delay.h> - #include <linux/security.h> - #include <linux/idr.h> - #include <linux/init.h> /* init_rootfs */ -@@ -353,8 +354,11 @@ int __mnt_want_write(struct vfsmount *m) - * incremented count after it has set MNT_WRITE_HOLD. - */ - smp_mb(); -- while (ACCESS_ONCE(mnt->mnt.mnt_flags) & MNT_WRITE_HOLD) -- cpu_relax(); -+ while (ACCESS_ONCE(mnt->mnt.mnt_flags) & MNT_WRITE_HOLD) { -+ preempt_enable(); -+ cpu_chill(); -+ preempt_disable(); -+ } - /* - * After the slowpath clears MNT_WRITE_HOLD, mnt_is_readonly will - * be set to match its requirements. So we must not load that until -diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c -index 97768a1..6d2ea1a 100644 ---- a/fs/ntfs/aops.c -+++ b/fs/ntfs/aops.c -@@ -92,13 +92,13 @@ static void ntfs_end_buffer_async_read(struct buffer_head *bh, int uptodate) - ofs = 0; - if (file_ofs < init_size) - ofs = init_size - file_ofs; -- local_irq_save(flags); -+ local_irq_save_nort(flags); - kaddr = kmap_atomic(page); - memset(kaddr + bh_offset(bh) + ofs, 0, - bh->b_size - ofs); - flush_dcache_page(page); - kunmap_atomic(kaddr); -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - } - } else { - clear_buffer_uptodate(bh); -@@ -107,8 +107,7 @@ static void ntfs_end_buffer_async_read(struct buffer_head *bh, int uptodate) - "0x%llx.", (unsigned long long)bh->b_blocknr); - } - first = page_buffers(page); -- local_irq_save(flags); -- bit_spin_lock(BH_Uptodate_Lock, &first->b_state); -+ flags = bh_uptodate_lock_irqsave(first); - clear_buffer_async_read(bh); - unlock_buffer(bh); - tmp = bh; -@@ -123,8 +122,7 @@ static void ntfs_end_buffer_async_read(struct buffer_head *bh, int uptodate) - } - tmp = tmp->b_this_page; - } while (tmp != bh); -- bit_spin_unlock(BH_Uptodate_Lock, &first->b_state); -- local_irq_restore(flags); -+ bh_uptodate_unlock_irqrestore(first, flags); - /* - * If none of the buffers had errors then we can set the page uptodate, - * but we first have to perform the post read mst fixups, if the -@@ -145,13 +143,13 @@ static void ntfs_end_buffer_async_read(struct buffer_head *bh, int uptodate) - recs = PAGE_SIZE / rec_size; - /* Should have been verified before we got here... */ - BUG_ON(!recs); -- local_irq_save(flags); -+ local_irq_save_nort(flags); - kaddr = kmap_atomic(page); - for (i = 0; i < recs; i++) - post_read_mst_fixup((NTFS_RECORD*)(kaddr + - i * rec_size), rec_size); - kunmap_atomic(kaddr); -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - flush_dcache_page(page); - if (likely(page_uptodate && !PageError(page))) - SetPageUptodate(page); -@@ -159,9 +157,7 @@ static void ntfs_end_buffer_async_read(struct buffer_head *bh, int uptodate) - unlock_page(page); - return; - still_busy: -- bit_spin_unlock(BH_Uptodate_Lock, &first->b_state); -- local_irq_restore(flags); -- return; -+ bh_uptodate_unlock_irqrestore(first, flags); - } - - /** -diff --git a/fs/timerfd.c b/fs/timerfd.c -index 053818d..c4bc14f 100644 ---- a/fs/timerfd.c -+++ b/fs/timerfd.c -@@ -450,7 +450,10 @@ static int do_timerfd_settime(int ufd, int flags, - break; - } - spin_unlock_irq(&ctx->wqh.lock); -- cpu_relax(); -+ if (isalarm(ctx)) -+ hrtimer_wait_for_timer(&ctx->t.alarm.timer); -+ else -+ hrtimer_wait_for_timer(&ctx->t.tmr); - } - - /* -diff --git a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h -index 45c2d65..794eead 100644 ---- a/include/acpi/platform/aclinux.h -+++ b/include/acpi/platform/aclinux.h -@@ -127,6 +127,7 @@ - - #define acpi_cache_t struct kmem_cache - #define acpi_spinlock spinlock_t * -+#define acpi_raw_spinlock raw_spinlock_t * - #define acpi_cpu_flags unsigned long - - /* Use native linux version of acpi_os_allocate_zeroed */ -@@ -145,6 +146,20 @@ - #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_get_thread_id - #define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_create_lock - -+#define acpi_os_create_raw_lock(__handle) \ -+({ \ -+ raw_spinlock_t *lock = ACPI_ALLOCATE(sizeof(*lock)); \ -+ \ -+ if (lock) { \ -+ *(__handle) = lock; \ -+ raw_spin_lock_init(*(__handle)); \ -+ } \ -+ lock ? AE_OK : AE_NO_MEMORY; \ -+ }) -+ -+#define acpi_os_delete_raw_lock(__handle) kfree(__handle) -+ -+ - /* - * OSL interfaces used by debugger/disassembler - */ -diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h -index 6f96247..fa53a21 100644 ---- a/include/asm-generic/bug.h -+++ b/include/asm-generic/bug.h -@@ -215,6 +215,20 @@ void __warn(const char *file, int line, void *caller, unsigned taint, - # define WARN_ON_SMP(x) ({0;}) - #endif - -+#ifdef CONFIG_PREEMPT_RT_BASE -+# define BUG_ON_RT(c) BUG_ON(c) -+# define BUG_ON_NONRT(c) do { } while (0) -+# define WARN_ON_RT(condition) WARN_ON(condition) -+# define WARN_ON_NONRT(condition) do { } while (0) -+# define WARN_ON_ONCE_NONRT(condition) do { } while (0) -+#else -+# define BUG_ON_RT(c) do { } while (0) -+# define BUG_ON_NONRT(c) BUG_ON(c) -+# define WARN_ON_RT(condition) do { } while (0) -+# define WARN_ON_NONRT(condition) WARN_ON(condition) -+# define WARN_ON_ONCE_NONRT(condition) WARN_ON_ONCE(condition) -+#endif -+ - #endif /* __ASSEMBLY__ */ - - #endif -diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h -index 9ac9799..05fc249 100644 ---- a/include/linux/blk-mq.h -+++ b/include/linux/blk-mq.h -@@ -218,6 +218,7 @@ static inline u16 blk_mq_unique_tag_to_tag(u32 unique_tag) - - struct blk_mq_hw_ctx *blk_mq_map_queue(struct request_queue *, const int ctx_index); - struct blk_mq_hw_ctx *blk_mq_alloc_single_hw_queue(struct blk_mq_tag_set *, unsigned int, int); -+void __blk_mq_complete_request_remote_work(struct work_struct *work); - - int blk_mq_request_started(struct request *rq); - void blk_mq_start_request(struct request *rq); -diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h -index 669e419..6678028 100644 ---- a/include/linux/blkdev.h -+++ b/include/linux/blkdev.h -@@ -90,6 +90,7 @@ struct request { - struct list_head queuelist; - union { - struct call_single_data csd; -+ struct work_struct work; - unsigned long fifo_time; - }; - -@@ -457,7 +458,7 @@ struct request_queue { - struct throtl_data *td; - #endif - struct rcu_head rcu_head; -- wait_queue_head_t mq_freeze_wq; -+ struct swait_queue_head mq_freeze_wq; - struct percpu_ref q_usage_counter; - struct list_head all_q_node; - -diff --git a/include/linux/bottom_half.h b/include/linux/bottom_half.h -index 8fdcb78..d07dbee 100644 ---- a/include/linux/bottom_half.h -+++ b/include/linux/bottom_half.h -@@ -3,6 +3,39 @@ - - #include <linux/preempt.h> - -+#ifdef CONFIG_PREEMPT_RT_FULL -+ -+extern void __local_bh_disable(void); -+extern void _local_bh_enable(void); -+extern void __local_bh_enable(void); -+ -+static inline void local_bh_disable(void) -+{ -+ __local_bh_disable(); -+} -+ -+static inline void __local_bh_disable_ip(unsigned long ip, unsigned int cnt) -+{ -+ __local_bh_disable(); -+} -+ -+static inline void local_bh_enable(void) -+{ -+ __local_bh_enable(); -+} -+ -+static inline void __local_bh_enable_ip(unsigned long ip, unsigned int cnt) -+{ -+ __local_bh_enable(); -+} -+ -+static inline void local_bh_enable_ip(unsigned long ip) -+{ -+ __local_bh_enable(); -+} -+ -+#else -+ - #ifdef CONFIG_TRACE_IRQFLAGS - extern void __local_bh_disable_ip(unsigned long ip, unsigned int cnt); - #else -@@ -30,5 +63,6 @@ static inline void local_bh_enable(void) - { - __local_bh_enable_ip(_THIS_IP_, SOFTIRQ_DISABLE_OFFSET); - } -+#endif - - #endif /* _LINUX_BH_H */ -diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h -index d48daa3..91588cd 100644 ---- a/include/linux/buffer_head.h -+++ b/include/linux/buffer_head.h -@@ -75,8 +75,50 @@ struct buffer_head { - struct address_space *b_assoc_map; /* mapping this buffer is - associated with */ - atomic_t b_count; /* users using this buffer_head */ -+#ifdef CONFIG_PREEMPT_RT_BASE -+ spinlock_t b_uptodate_lock; -+#if IS_ENABLED(CONFIG_JBD2) -+ spinlock_t b_state_lock; -+ spinlock_t b_journal_head_lock; -+#endif -+#endif - }; - -+static inline unsigned long bh_uptodate_lock_irqsave(struct buffer_head *bh) -+{ -+ unsigned long flags; -+ -+#ifndef CONFIG_PREEMPT_RT_BASE -+ local_irq_save(flags); -+ bit_spin_lock(BH_Uptodate_Lock, &bh->b_state); -+#else -+ spin_lock_irqsave(&bh->b_uptodate_lock, flags); -+#endif -+ return flags; -+} -+ -+static inline void -+bh_uptodate_unlock_irqrestore(struct buffer_head *bh, unsigned long flags) -+{ -+#ifndef CONFIG_PREEMPT_RT_BASE -+ bit_spin_unlock(BH_Uptodate_Lock, &bh->b_state); -+ local_irq_restore(flags); -+#else -+ spin_unlock_irqrestore(&bh->b_uptodate_lock, flags); -+#endif -+} -+ -+static inline void buffer_head_init_locks(struct buffer_head *bh) -+{ -+#ifdef CONFIG_PREEMPT_RT_BASE -+ spin_lock_init(&bh->b_uptodate_lock); -+#if IS_ENABLED(CONFIG_JBD2) -+ spin_lock_init(&bh->b_state_lock); -+ spin_lock_init(&bh->b_journal_head_lock); -+#endif -+#endif -+} -+ - /* - * macro tricks to expand the set_buffer_foo(), clear_buffer_foo() - * and buffer_foo() functions. -diff --git a/include/linux/cgroup-defs.h b/include/linux/cgroup-defs.h -index 5b17de6..c311309 100644 ---- a/include/linux/cgroup-defs.h -+++ b/include/linux/cgroup-defs.h -@@ -16,6 +16,7 @@ - #include <linux/percpu-refcount.h> - #include <linux/percpu-rwsem.h> - #include <linux/workqueue.h> -+#include <linux/work-simple.h> - - #ifdef CONFIG_CGROUPS - -@@ -137,6 +138,7 @@ struct cgroup_subsys_state { - /* percpu_ref killing and RCU release */ - struct rcu_head rcu_head; - struct work_struct destroy_work; -+ struct swork_event destroy_swork; - }; - - /* -diff --git a/include/linux/completion.h b/include/linux/completion.h -index 5d5aaae..3bca159 100644 ---- a/include/linux/completion.h -+++ b/include/linux/completion.h -@@ -7,8 +7,7 @@ - * Atomic wait-for-completion handler data structures. - * See kernel/sched/completion.c for details. - */ -- --#include <linux/wait.h> -+#include <linux/swait.h> - - /* - * struct completion - structure used to maintain state for a "completion" -@@ -24,11 +23,11 @@ - */ - struct completion { - unsigned int done; -- wait_queue_head_t wait; -+ struct swait_queue_head wait; - }; - - #define COMPLETION_INITIALIZER(work) \ -- { 0, __WAIT_QUEUE_HEAD_INITIALIZER((work).wait) } -+ { 0, __SWAIT_QUEUE_HEAD_INITIALIZER((work).wait) } - - #define COMPLETION_INITIALIZER_ONSTACK(work) \ - ({ init_completion(&work); work; }) -@@ -73,7 +72,7 @@ struct completion { - static inline void init_completion(struct completion *x) - { - x->done = 0; -- init_waitqueue_head(&x->wait); -+ init_swait_queue_head(&x->wait); - } - - /** -diff --git a/include/linux/cpu.h b/include/linux/cpu.h -index f9b1fab..d4cc481 100644 ---- a/include/linux/cpu.h -+++ b/include/linux/cpu.h -@@ -230,6 +230,8 @@ extern void get_online_cpus(void); - extern void put_online_cpus(void); - extern void cpu_hotplug_disable(void); - extern void cpu_hotplug_enable(void); -+extern void pin_current_cpu(void); -+extern void unpin_current_cpu(void); - #define hotcpu_notifier(fn, pri) cpu_notifier(fn, pri) - #define __hotcpu_notifier(fn, pri) __cpu_notifier(fn, pri) - #define register_hotcpu_notifier(nb) register_cpu_notifier(nb) -@@ -247,6 +249,8 @@ static inline void cpu_hotplug_done(void) {} - #define put_online_cpus() do { } while (0) - #define cpu_hotplug_disable() do { } while (0) - #define cpu_hotplug_enable() do { } while (0) -+static inline void pin_current_cpu(void) { } -+static inline void unpin_current_cpu(void) { } - #define hotcpu_notifier(fn, pri) do { (void)(fn); } while (0) - #define __hotcpu_notifier(fn, pri) do { (void)(fn); } while (0) - /* These aren't inline functions due to a GCC bug. */ -diff --git a/include/linux/delay.h b/include/linux/delay.h -index a6ecb34..37caab3 100644 ---- a/include/linux/delay.h -+++ b/include/linux/delay.h -@@ -52,4 +52,10 @@ static inline void ssleep(unsigned int seconds) - msleep(seconds * 1000); - } - -+#ifdef CONFIG_PREEMPT_RT_FULL -+extern void cpu_chill(void); -+#else -+# define cpu_chill() cpu_relax() -+#endif -+ - #endif /* defined(_LINUX_DELAY_H) */ -diff --git a/include/linux/highmem.h b/include/linux/highmem.h -index bb3f329..a117a33 100644 ---- a/include/linux/highmem.h -+++ b/include/linux/highmem.h -@@ -7,6 +7,7 @@ - #include <linux/mm.h> - #include <linux/uaccess.h> - #include <linux/hardirq.h> -+#include <linux/sched.h> - - #include <asm/cacheflush.h> - -@@ -65,7 +66,7 @@ static inline void kunmap(struct page *page) - - static inline void *kmap_atomic(struct page *page) - { -- preempt_disable(); -+ preempt_disable_nort(); - pagefault_disable(); - return page_address(page); - } -@@ -74,7 +75,7 @@ static inline void *kmap_atomic(struct page *page) - static inline void __kunmap_atomic(void *addr) - { - pagefault_enable(); -- preempt_enable(); -+ preempt_enable_nort(); - } - - #define kmap_atomic_pfn(pfn) kmap_atomic(pfn_to_page(pfn)) -@@ -86,32 +87,51 @@ static inline void __kunmap_atomic(void *addr) - - #if defined(CONFIG_HIGHMEM) || defined(CONFIG_X86_32) - -+#ifndef CONFIG_PREEMPT_RT_FULL - DECLARE_PER_CPU(int, __kmap_atomic_idx); -+#endif - - static inline int kmap_atomic_idx_push(void) - { -+#ifndef CONFIG_PREEMPT_RT_FULL - int idx = __this_cpu_inc_return(__kmap_atomic_idx) - 1; - --#ifdef CONFIG_DEBUG_HIGHMEM -+# ifdef CONFIG_DEBUG_HIGHMEM - WARN_ON_ONCE(in_irq() && !irqs_disabled()); - BUG_ON(idx >= KM_TYPE_NR); --#endif -+# endif - return idx; -+#else -+ current->kmap_idx++; -+ BUG_ON(current->kmap_idx > KM_TYPE_NR); -+ return current->kmap_idx - 1; -+#endif - } - - static inline int kmap_atomic_idx(void) - { -+#ifndef CONFIG_PREEMPT_RT_FULL - return __this_cpu_read(__kmap_atomic_idx) - 1; -+#else -+ return current->kmap_idx - 1; -+#endif - } - - static inline void kmap_atomic_idx_pop(void) - { --#ifdef CONFIG_DEBUG_HIGHMEM -+#ifndef CONFIG_PREEMPT_RT_FULL -+# ifdef CONFIG_DEBUG_HIGHMEM - int idx = __this_cpu_dec_return(__kmap_atomic_idx); - - BUG_ON(idx < 0); --#else -+# else - __this_cpu_dec(__kmap_atomic_idx); -+# endif -+#else -+ current->kmap_idx--; -+# ifdef CONFIG_DEBUG_HIGHMEM -+ BUG_ON(current->kmap_idx < 0); -+# endif - #endif - } - -diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h -index c98c653..573ffbc 100644 ---- a/include/linux/hrtimer.h -+++ b/include/linux/hrtimer.h -@@ -87,6 +87,9 @@ enum hrtimer_restart { - * @function: timer expiry callback function - * @base: pointer to the timer base (per cpu and per clock) - * @state: state information (See bit values above) -+ * @cb_entry: list entry to defer timers from hardirq context -+ * @irqsafe: timer can run in hardirq context -+ * @praecox: timer expiry time if expired at the time of programming - * @is_rel: Set if the timer was armed relative - * @start_pid: timer statistics field to store the pid of the task which - * started the timer -@@ -103,6 +106,11 @@ struct hrtimer { - enum hrtimer_restart (*function)(struct hrtimer *); - struct hrtimer_clock_base *base; - u8 state; -+ struct list_head cb_entry; -+ int irqsafe; -+#ifdef CONFIG_MISSED_TIMER_OFFSETS_HIST -+ ktime_t praecox; -+#endif - u8 is_rel; - #ifdef CONFIG_TIMER_STATS - int start_pid; -@@ -123,11 +131,7 @@ struct hrtimer_sleeper { - struct task_struct *task; - }; - --#ifdef CONFIG_64BIT - # define HRTIMER_CLOCK_BASE_ALIGN 64 --#else --# define HRTIMER_CLOCK_BASE_ALIGN 32 --#endif - - /** - * struct hrtimer_clock_base - the timer base for a specific clock -@@ -136,6 +140,7 @@ struct hrtimer_sleeper { - * timer to a base on another cpu. - * @clockid: clock id for per_cpu support - * @active: red black tree root node for the active timers -+ * @expired: list head for deferred timers. - * @get_time: function to retrieve the current time of the clock - * @offset: offset of this clock to the monotonic base - */ -@@ -144,6 +149,7 @@ struct hrtimer_clock_base { - int index; - clockid_t clockid; - struct timerqueue_head active; -+ struct list_head expired; - ktime_t (*get_time)(void); - ktime_t offset; - } __attribute__((__aligned__(HRTIMER_CLOCK_BASE_ALIGN))); -@@ -187,6 +193,7 @@ struct hrtimer_cpu_base { - raw_spinlock_t lock; - seqcount_t seq; - struct hrtimer *running; -+ struct hrtimer *running_soft; - unsigned int cpu; - unsigned int active_bases; - unsigned int clock_was_set_seq; -@@ -203,6 +210,9 @@ struct hrtimer_cpu_base { - unsigned int nr_hangs; - unsigned int max_hang_time; - #endif -+#ifdef CONFIG_PREEMPT_RT_BASE -+ wait_queue_head_t wait; -+#endif - struct hrtimer_clock_base clock_base[HRTIMER_MAX_CLOCK_BASES]; - } ____cacheline_aligned; - -@@ -412,6 +422,13 @@ static inline void hrtimer_restart(struct hrtimer *timer) - hrtimer_start_expires(timer, HRTIMER_MODE_ABS); - } - -+/* Softirq preemption could deadlock timer removal */ -+#ifdef CONFIG_PREEMPT_RT_BASE -+ extern void hrtimer_wait_for_timer(const struct hrtimer *timer); -+#else -+# define hrtimer_wait_for_timer(timer) do { cpu_relax(); } while (0) -+#endif -+ - /* Query timers: */ - extern ktime_t __hrtimer_get_remaining(const struct hrtimer *timer, bool adjust); - -@@ -436,7 +453,7 @@ static inline int hrtimer_is_queued(struct hrtimer *timer) - * Helper function to check, whether the timer is running the callback - * function - */ --static inline int hrtimer_callback_running(struct hrtimer *timer) -+static inline int hrtimer_callback_running(const struct hrtimer *timer) - { - return timer->base->cpu_base->running == timer; - } -diff --git a/include/linux/idr.h b/include/linux/idr.h -index 083d61e..5899796 100644 ---- a/include/linux/idr.h -+++ b/include/linux/idr.h -@@ -95,10 +95,14 @@ bool idr_is_empty(struct idr *idp); - * Each idr_preload() should be matched with an invocation of this - * function. See idr_preload() for details. - */ -+#ifdef CONFIG_PREEMPT_RT_FULL -+void idr_preload_end(void); -+#else - static inline void idr_preload_end(void) - { - preempt_enable(); - } -+#endif - - /** - * idr_find - return pointer for given id -diff --git a/include/linux/init_task.h b/include/linux/init_task.h -index f2cb8d4..60fadde 100644 ---- a/include/linux/init_task.h -+++ b/include/linux/init_task.h -@@ -148,6 +148,12 @@ extern struct task_group root_task_group; - # define INIT_PERF_EVENTS(tsk) - #endif - -+#ifdef CONFIG_PREEMPT_RT_BASE -+# define INIT_TIMER_LIST .posix_timer_list = NULL, -+#else -+# define INIT_TIMER_LIST -+#endif -+ - #ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN - # define INIT_VTIME(tsk) \ - .vtime_seqcount = SEQCNT_ZERO(tsk.vtime_seqcount), \ -@@ -239,6 +245,7 @@ extern struct task_group root_task_group; - .cpu_timers = INIT_CPU_TIMERS(tsk.cpu_timers), \ - .pi_lock = __RAW_SPIN_LOCK_UNLOCKED(tsk.pi_lock), \ - .timer_slack_ns = 50000, /* 50 usec default slack */ \ -+ INIT_TIMER_LIST \ - .pids = { \ - [PIDTYPE_PID] = INIT_PID_LINK(PIDTYPE_PID), \ - [PIDTYPE_PGID] = INIT_PID_LINK(PIDTYPE_PGID), \ -diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h -index 9fcabeb..e6f7e42 100644 ---- a/include/linux/interrupt.h -+++ b/include/linux/interrupt.h -@@ -61,6 +61,7 @@ - * interrupt handler after suspending interrupts. For system - * wakeup devices users need to implement wakeup detection in - * their interrupt handlers. -+ * IRQF_NO_SOFTIRQ_CALL - Do not process softirqs in the irq thread context (RT) - */ - #define IRQF_SHARED 0x00000080 - #define IRQF_PROBE_SHARED 0x00000100 -@@ -74,6 +75,7 @@ - #define IRQF_NO_THREAD 0x00010000 - #define IRQF_EARLY_RESUME 0x00020000 - #define IRQF_COND_SUSPEND 0x00040000 -+#define IRQF_NO_SOFTIRQ_CALL 0x00080000 - - #define IRQF_TIMER (__IRQF_TIMER | IRQF_NO_SUSPEND | IRQF_NO_THREAD) - -@@ -196,7 +198,7 @@ extern void devm_free_irq(struct device *dev, unsigned int irq, void *dev_id); - #ifdef CONFIG_LOCKDEP - # define local_irq_enable_in_hardirq() do { } while (0) - #else --# define local_irq_enable_in_hardirq() local_irq_enable() -+# define local_irq_enable_in_hardirq() local_irq_enable_nort() - #endif - - extern void disable_irq_nosync(unsigned int irq); -@@ -217,6 +219,7 @@ extern void resume_device_irqs(void); - * @irq: Interrupt to which notification applies - * @kref: Reference count, for internal use - * @work: Work item, for internal use -+ * @list: List item for deferred callbacks - * @notify: Function to be called on change. This will be - * called in process context. - * @release: Function to be called on release. This will be -@@ -228,6 +231,7 @@ struct irq_affinity_notify { - unsigned int irq; - struct kref kref; - struct work_struct work; -+ struct list_head list; - void (*notify)(struct irq_affinity_notify *, const cpumask_t *mask); - void (*release)(struct kref *ref); - }; -@@ -390,9 +394,13 @@ extern int irq_set_irqchip_state(unsigned int irq, enum irqchip_irq_state which, - bool state); - - #ifdef CONFIG_IRQ_FORCED_THREADING -+# ifndef CONFIG_PREEMPT_RT_BASE - extern bool force_irqthreads; -+# else -+# define force_irqthreads (true) -+# endif - #else --#define force_irqthreads (0) -+#define force_irqthreads (false) - #endif - - #ifndef __ARCH_SET_SOFTIRQ_PENDING -@@ -449,9 +457,10 @@ struct softirq_action - void (*action)(struct softirq_action *); - }; - -+#ifndef CONFIG_PREEMPT_RT_FULL - asmlinkage void do_softirq(void); - asmlinkage void __do_softirq(void); -- -+static inline void thread_do_softirq(void) { do_softirq(); } - #ifdef __ARCH_HAS_DO_SOFTIRQ - void do_softirq_own_stack(void); - #else -@@ -460,13 +469,25 @@ static inline void do_softirq_own_stack(void) - __do_softirq(); - } - #endif -+#else -+extern void thread_do_softirq(void); -+#endif - - extern void open_softirq(int nr, void (*action)(struct softirq_action *)); - extern void softirq_init(void); - extern void __raise_softirq_irqoff(unsigned int nr); -+#ifdef CONFIG_PREEMPT_RT_FULL -+extern void __raise_softirq_irqoff_ksoft(unsigned int nr); -+#else -+static inline void __raise_softirq_irqoff_ksoft(unsigned int nr) -+{ -+ __raise_softirq_irqoff(nr); -+} -+#endif - - extern void raise_softirq_irqoff(unsigned int nr); - extern void raise_softirq(unsigned int nr); -+extern void softirq_check_pending_idle(void); - - DECLARE_PER_CPU(struct task_struct *, ksoftirqd); - -@@ -488,8 +509,9 @@ static inline struct task_struct *this_cpu_ksoftirqd(void) - to be executed on some cpu at least once after this. - * If the tasklet is already scheduled, but its execution is still not - started, it will be executed only once. -- * If this tasklet is already running on another CPU (or schedule is called -- from tasklet itself), it is rescheduled for later. -+ * If this tasklet is already running on another CPU, it is rescheduled -+ for later. -+ * Schedule must not be called from the tasklet itself (a lockup occurs) - * Tasklet is strictly serialized wrt itself, but not - wrt another tasklets. If client needs some intertask synchronization, - he makes it with spinlocks. -@@ -514,27 +536,36 @@ struct tasklet_struct name = { NULL, 0, ATOMIC_INIT(1), func, data } - enum - { - TASKLET_STATE_SCHED, /* Tasklet is scheduled for execution */ -- TASKLET_STATE_RUN /* Tasklet is running (SMP only) */ -+ TASKLET_STATE_RUN, /* Tasklet is running (SMP only) */ -+ TASKLET_STATE_PENDING /* Tasklet is pending */ - }; - --#ifdef CONFIG_SMP -+#define TASKLET_STATEF_SCHED (1 << TASKLET_STATE_SCHED) -+#define TASKLET_STATEF_RUN (1 << TASKLET_STATE_RUN) -+#define TASKLET_STATEF_PENDING (1 << TASKLET_STATE_PENDING) -+ -+#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT_RT_FULL) - static inline int tasklet_trylock(struct tasklet_struct *t) - { - return !test_and_set_bit(TASKLET_STATE_RUN, &(t)->state); - } - -+static inline int tasklet_tryunlock(struct tasklet_struct *t) -+{ -+ return cmpxchg(&t->state, TASKLET_STATEF_RUN, 0) == TASKLET_STATEF_RUN; -+} -+ - static inline void tasklet_unlock(struct tasklet_struct *t) - { - smp_mb__before_atomic(); - clear_bit(TASKLET_STATE_RUN, &(t)->state); - } - --static inline void tasklet_unlock_wait(struct tasklet_struct *t) --{ -- while (test_bit(TASKLET_STATE_RUN, &(t)->state)) { barrier(); } --} -+extern void tasklet_unlock_wait(struct tasklet_struct *t); -+ - #else - #define tasklet_trylock(t) 1 -+#define tasklet_tryunlock(t) 1 - #define tasklet_unlock_wait(t) do { } while (0) - #define tasklet_unlock(t) do { } while (0) - #endif -@@ -583,12 +614,7 @@ static inline void tasklet_disable(struct tasklet_struct *t) - smp_mb(); - } - --static inline void tasklet_enable(struct tasklet_struct *t) --{ -- smp_mb__before_atomic(); -- atomic_dec(&t->count); --} -- -+extern void tasklet_enable(struct tasklet_struct *t); - extern void tasklet_kill(struct tasklet_struct *t); - extern void tasklet_kill_immediate(struct tasklet_struct *t, unsigned int cpu); - extern void tasklet_init(struct tasklet_struct *t, -@@ -619,6 +645,12 @@ void tasklet_hrtimer_cancel(struct tasklet_hrtimer *ttimer) - tasklet_kill(&ttimer->tasklet); - } - -+#ifdef CONFIG_PREEMPT_RT_FULL -+extern void softirq_early_init(void); -+#else -+static inline void softirq_early_init(void) { } -+#endif -+ - /* - * Autoprobing for irqs: - * -diff --git a/include/linux/irq.h b/include/linux/irq.h -index c4de623..7432b5e 100644 ---- a/include/linux/irq.h -+++ b/include/linux/irq.h -@@ -72,6 +72,7 @@ enum irqchip_irq_state; - * IRQ_IS_POLLED - Always polled by another interrupt. Exclude - * it from the spurious interrupt detection - * mechanism and from core side polling. -+ * IRQ_NO_SOFTIRQ_CALL - No softirq processing in the irq thread context (RT) - * IRQ_DISABLE_UNLAZY - Disable lazy irq disable - */ - enum { -@@ -99,13 +100,14 @@ enum { - IRQ_PER_CPU_DEVID = (1 << 17), - IRQ_IS_POLLED = (1 << 18), - IRQ_DISABLE_UNLAZY = (1 << 19), -+ IRQ_NO_SOFTIRQ_CALL = (1 << 20), - }; - - #define IRQF_MODIFY_MASK \ - (IRQ_TYPE_SENSE_MASK | IRQ_NOPROBE | IRQ_NOREQUEST | \ - IRQ_NOAUTOEN | IRQ_MOVE_PCNTXT | IRQ_LEVEL | IRQ_NO_BALANCING | \ - IRQ_PER_CPU | IRQ_NESTED_THREAD | IRQ_NOTHREAD | IRQ_PER_CPU_DEVID | \ -- IRQ_IS_POLLED | IRQ_DISABLE_UNLAZY) -+ IRQ_IS_POLLED | IRQ_DISABLE_UNLAZY | IRQ_NO_SOFTIRQ_CALL) - - #define IRQ_NO_BALANCING_MASK (IRQ_PER_CPU | IRQ_NO_BALANCING) - -diff --git a/include/linux/irq_work.h b/include/linux/irq_work.h -index 47b9ebd..2543aab 100644 ---- a/include/linux/irq_work.h -+++ b/include/linux/irq_work.h -@@ -16,6 +16,7 @@ - #define IRQ_WORK_BUSY 2UL - #define IRQ_WORK_FLAGS 3UL - #define IRQ_WORK_LAZY 4UL /* Doesn't want IPI, wait for tick */ -+#define IRQ_WORK_HARD_IRQ 8UL /* Run hard IRQ context, even on RT */ - - struct irq_work { - unsigned long flags; -@@ -51,4 +52,10 @@ static inline bool irq_work_needs_cpu(void) { return false; } - static inline void irq_work_run(void) { } - #endif - -+#if defined(CONFIG_IRQ_WORK) && defined(CONFIG_PREEMPT_RT_FULL) -+void irq_work_tick_soft(void); -+#else -+static inline void irq_work_tick_soft(void) { } -+#endif -+ - #endif /* _LINUX_IRQ_WORK_H */ -diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h -index dcca77c..edb6573 100644 ---- a/include/linux/irqdesc.h -+++ b/include/linux/irqdesc.h -@@ -64,6 +64,7 @@ struct irq_desc { - unsigned int irqs_unhandled; - atomic_t threads_handled; - int threads_handled_last; -+ u64 random_ip; - raw_spinlock_t lock; - struct cpumask *percpu_enabled; - #ifdef CONFIG_SMP -diff --git a/include/linux/irqflags.h b/include/linux/irqflags.h -index 5dd1272..9b77034 100644 ---- a/include/linux/irqflags.h -+++ b/include/linux/irqflags.h -@@ -25,8 +25,6 @@ - # define trace_softirqs_enabled(p) ((p)->softirqs_enabled) - # define trace_hardirq_enter() do { current->hardirq_context++; } while (0) - # define trace_hardirq_exit() do { current->hardirq_context--; } while (0) --# define lockdep_softirq_enter() do { current->softirq_context++; } while (0) --# define lockdep_softirq_exit() do { current->softirq_context--; } while (0) - # define INIT_TRACE_IRQFLAGS .softirqs_enabled = 1, - #else - # define trace_hardirqs_on() do { } while (0) -@@ -39,9 +37,15 @@ - # define trace_softirqs_enabled(p) 0 - # define trace_hardirq_enter() do { } while (0) - # define trace_hardirq_exit() do { } while (0) -+# define INIT_TRACE_IRQFLAGS -+#endif -+ -+#if defined(CONFIG_TRACE_IRQFLAGS) && !defined(CONFIG_PREEMPT_RT_FULL) -+# define lockdep_softirq_enter() do { current->softirq_context++; } while (0) -+# define lockdep_softirq_exit() do { current->softirq_context--; } while (0) -+#else - # define lockdep_softirq_enter() do { } while (0) - # define lockdep_softirq_exit() do { } while (0) --# define INIT_TRACE_IRQFLAGS - #endif - - #if defined(CONFIG_IRQSOFF_TRACER) || \ -@@ -148,4 +152,23 @@ - - #define irqs_disabled_flags(flags) raw_irqs_disabled_flags(flags) - -+/* -+ * local_irq* variants depending on RT/!RT -+ */ -+#ifdef CONFIG_PREEMPT_RT_FULL -+# define local_irq_disable_nort() do { } while (0) -+# define local_irq_enable_nort() do { } while (0) -+# define local_irq_save_nort(flags) local_save_flags(flags) -+# define local_irq_restore_nort(flags) (void)(flags) -+# define local_irq_disable_rt() local_irq_disable() -+# define local_irq_enable_rt() local_irq_enable() -+#else -+# define local_irq_disable_nort() local_irq_disable() -+# define local_irq_enable_nort() local_irq_enable() -+# define local_irq_save_nort(flags) local_irq_save(flags) -+# define local_irq_restore_nort(flags) local_irq_restore(flags) -+# define local_irq_disable_rt() do { } while (0) -+# define local_irq_enable_rt() do { } while (0) -+#endif -+ - #endif -diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h -index fd1083c..1485e18 100644 ---- a/include/linux/jbd2.h -+++ b/include/linux/jbd2.h -@@ -347,32 +347,56 @@ static inline struct journal_head *bh2jh(struct buffer_head *bh) - - static inline void jbd_lock_bh_state(struct buffer_head *bh) - { -+#ifndef CONFIG_PREEMPT_RT_BASE - bit_spin_lock(BH_State, &bh->b_state); -+#else -+ spin_lock(&bh->b_state_lock); -+#endif - } - - static inline int jbd_trylock_bh_state(struct buffer_head *bh) - { -+#ifndef CONFIG_PREEMPT_RT_BASE - return bit_spin_trylock(BH_State, &bh->b_state); -+#else -+ return spin_trylock(&bh->b_state_lock); -+#endif - } - - static inline int jbd_is_locked_bh_state(struct buffer_head *bh) - { -+#ifndef CONFIG_PREEMPT_RT_BASE - return bit_spin_is_locked(BH_State, &bh->b_state); -+#else -+ return spin_is_locked(&bh->b_state_lock); -+#endif - } - - static inline void jbd_unlock_bh_state(struct buffer_head *bh) - { -+#ifndef CONFIG_PREEMPT_RT_BASE - bit_spin_unlock(BH_State, &bh->b_state); -+#else -+ spin_unlock(&bh->b_state_lock); -+#endif - } - - static inline void jbd_lock_bh_journal_head(struct buffer_head *bh) - { -+#ifndef CONFIG_PREEMPT_RT_BASE - bit_spin_lock(BH_JournalHead, &bh->b_state); -+#else -+ spin_lock(&bh->b_journal_head_lock); -+#endif - } - - static inline void jbd_unlock_bh_journal_head(struct buffer_head *bh) - { -+#ifndef CONFIG_PREEMPT_RT_BASE - bit_spin_unlock(BH_JournalHead, &bh->b_state); -+#else -+ spin_unlock(&bh->b_journal_head_lock); -+#endif - } - - #define J_ASSERT(assert) BUG_ON(!(assert)) -diff --git a/include/linux/kdb.h b/include/linux/kdb.h -index a19bcf9..8974953 100644 ---- a/include/linux/kdb.h -+++ b/include/linux/kdb.h -@@ -167,6 +167,7 @@ extern __printf(2, 0) int vkdb_printf(enum kdb_msgsrc src, const char *fmt, - extern __printf(1, 2) int kdb_printf(const char *, ...); - typedef __printf(1, 2) int (*kdb_printf_t)(const char *, ...); - -+#define in_kdb_printk() (kdb_trap_printk) - extern void kdb_init(int level); - - /* Access to kdb specific polling devices */ -@@ -201,6 +202,7 @@ extern int kdb_register_flags(char *, kdb_func_t, char *, char *, - extern int kdb_unregister(char *); - #else /* ! CONFIG_KGDB_KDB */ - static inline __printf(1, 2) int kdb_printf(const char *fmt, ...) { return 0; } -+#define in_kdb_printk() (0) - static inline void kdb_init(int level) {} - static inline int kdb_register(char *cmd, kdb_func_t func, char *usage, - char *help, short minlen) { return 0; } -diff --git a/include/linux/kernel.h b/include/linux/kernel.h -index 2f7775e..a7f8e26 100644 ---- a/include/linux/kernel.h -+++ b/include/linux/kernel.h -@@ -188,6 +188,9 @@ extern int _cond_resched(void); - */ - # define might_sleep() \ - do { __might_sleep(__FILE__, __LINE__, 0); might_resched(); } while (0) -+ -+# define might_sleep_no_state_check() \ -+ do { ___might_sleep(__FILE__, __LINE__, 0); might_resched(); } while (0) - # define sched_annotate_sleep() (current->task_state_change = 0) - #else - static inline void ___might_sleep(const char *file, int line, -@@ -195,6 +198,7 @@ extern int _cond_resched(void); - static inline void __might_sleep(const char *file, int line, - int preempt_offset) { } - # define might_sleep() do { might_resched(); } while (0) -+# define might_sleep_no_state_check() do { might_resched(); } while (0) - # define sched_annotate_sleep() do { } while (0) - #endif - -@@ -484,6 +488,7 @@ extern enum system_states { - SYSTEM_HALT, - SYSTEM_POWER_OFF, - SYSTEM_RESTART, -+ SYSTEM_SUSPEND, - } system_state; - - #define TAINT_PROPRIETARY_MODULE 0 -diff --git a/include/linux/lglock.h b/include/linux/lglock.h -index c92ebd1..6f035f6 100644 ---- a/include/linux/lglock.h -+++ b/include/linux/lglock.h -@@ -34,13 +34,30 @@ - #endif - - struct lglock { -+#ifdef CONFIG_PREEMPT_RT_FULL -+ struct rt_mutex __percpu *lock; -+#else - arch_spinlock_t __percpu *lock; -+#endif - #ifdef CONFIG_DEBUG_LOCK_ALLOC - struct lock_class_key lock_key; - struct lockdep_map lock_dep_map; - #endif - }; - -+#ifdef CONFIG_PREEMPT_RT_FULL -+# define DEFINE_LGLOCK(name) \ -+ static DEFINE_PER_CPU(struct rt_mutex, name ## _lock) \ -+ = __RT_MUTEX_INITIALIZER( name ## _lock); \ -+ struct lglock name = { .lock = &name ## _lock } -+ -+# define DEFINE_STATIC_LGLOCK(name) \ -+ static DEFINE_PER_CPU(struct rt_mutex, name ## _lock) \ -+ = __RT_MUTEX_INITIALIZER( name ## _lock); \ -+ static struct lglock name = { .lock = &name ## _lock } -+ -+#else -+ - #define DEFINE_LGLOCK(name) \ - static DEFINE_PER_CPU(arch_spinlock_t, name ## _lock) \ - = __ARCH_SPIN_LOCK_UNLOCKED; \ -@@ -50,6 +67,7 @@ struct lglock { - static DEFINE_PER_CPU(arch_spinlock_t, name ## _lock) \ - = __ARCH_SPIN_LOCK_UNLOCKED; \ - static struct lglock name = { .lock = &name ## _lock } -+#endif - - void lg_lock_init(struct lglock *lg, char *name); - -@@ -64,6 +82,12 @@ void lg_double_unlock(struct lglock *lg, int cpu1, int cpu2); - void lg_global_lock(struct lglock *lg); - void lg_global_unlock(struct lglock *lg); - -+#ifndef CONFIG_PREEMPT_RT_FULL -+#define lg_global_trylock_relax(name) lg_global_lock(name) -+#else -+void lg_global_trylock_relax(struct lglock *lg); -+#endif -+ - #else - /* When !CONFIG_SMP, map lglock to spinlock */ - #define lglock spinlock -diff --git a/include/linux/list_bl.h b/include/linux/list_bl.h -index cb48330..4e50623 100644 ---- a/include/linux/list_bl.h -+++ b/include/linux/list_bl.h -@@ -2,6 +2,7 @@ - #define _LINUX_LIST_BL_H - - #include <linux/list.h> -+#include <linux/spinlock.h> - #include <linux/bit_spinlock.h> - - /* -@@ -32,13 +33,24 @@ - - struct hlist_bl_head { - struct hlist_bl_node *first; -+#ifdef CONFIG_PREEMPT_RT_BASE -+ raw_spinlock_t lock; -+#endif - }; - - struct hlist_bl_node { - struct hlist_bl_node *next, **pprev; - }; --#define INIT_HLIST_BL_HEAD(ptr) \ -- ((ptr)->first = NULL) -+ -+#ifdef CONFIG_PREEMPT_RT_BASE -+#define INIT_HLIST_BL_HEAD(h) \ -+do { \ -+ (h)->first = NULL; \ -+ raw_spin_lock_init(&(h)->lock); \ -+} while (0) -+#else -+#define INIT_HLIST_BL_HEAD(h) (h)->first = NULL -+#endif - - static inline void INIT_HLIST_BL_NODE(struct hlist_bl_node *h) - { -@@ -118,12 +130,26 @@ static inline void hlist_bl_del_init(struct hlist_bl_node *n) - - static inline void hlist_bl_lock(struct hlist_bl_head *b) - { -+#ifndef CONFIG_PREEMPT_RT_BASE - bit_spin_lock(0, (unsigned long *)b); -+#else -+ raw_spin_lock(&b->lock); -+#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) -+ __set_bit(0, (unsigned long *)b); -+#endif -+#endif - } - - static inline void hlist_bl_unlock(struct hlist_bl_head *b) - { -+#ifndef CONFIG_PREEMPT_RT_BASE - __bit_spin_unlock(0, (unsigned long *)b); -+#else -+#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) -+ __clear_bit(0, (unsigned long *)b); -+#endif -+ raw_spin_unlock(&b->lock); -+#endif - } - - static inline bool hlist_bl_is_locked(struct hlist_bl_head *b) -diff --git a/include/linux/locallock.h b/include/linux/locallock.h -new file mode 100644 -index 0000000..493e801 ---- /dev/null -+++ b/include/linux/locallock.h -@@ -0,0 +1,272 @@ -+#ifndef _LINUX_LOCALLOCK_H -+#define _LINUX_LOCALLOCK_H -+ -+#include <linux/percpu.h> -+#include <linux/spinlock.h> -+ -+#ifdef CONFIG_PREEMPT_RT_BASE -+ -+#ifdef CONFIG_DEBUG_SPINLOCK -+# define LL_WARN(cond) WARN_ON(cond) -+#else -+# define LL_WARN(cond) do { } while (0) -+#endif -+ -+/* -+ * per cpu lock based substitute for local_irq_*() -+ */ -+struct local_irq_lock { -+ spinlock_t lock; -+ struct task_struct *owner; -+ int nestcnt; -+ unsigned long flags; -+}; -+ -+#define DEFINE_LOCAL_IRQ_LOCK(lvar) \ -+ DEFINE_PER_CPU(struct local_irq_lock, lvar) = { \ -+ .lock = __SPIN_LOCK_UNLOCKED((lvar).lock) } -+ -+#define DECLARE_LOCAL_IRQ_LOCK(lvar) \ -+ DECLARE_PER_CPU(struct local_irq_lock, lvar) -+ -+#define local_irq_lock_init(lvar) \ -+ do { \ -+ int __cpu; \ -+ for_each_possible_cpu(__cpu) \ -+ spin_lock_init(&per_cpu(lvar, __cpu).lock); \ -+ } while (0) -+ -+/* -+ * spin_lock|trylock|unlock_local flavour that does not migrate disable -+ * used for __local_lock|trylock|unlock where get_local_var/put_local_var -+ * already takes care of the migrate_disable/enable -+ * for CONFIG_PREEMPT_BASE map to the normal spin_* calls. -+ */ -+#ifdef CONFIG_PREEMPT_RT_FULL -+# define spin_lock_local(lock) rt_spin_lock__no_mg(lock) -+# define spin_trylock_local(lock) rt_spin_trylock__no_mg(lock) -+# define spin_unlock_local(lock) rt_spin_unlock__no_mg(lock) -+#else -+# define spin_lock_local(lock) spin_lock(lock) -+# define spin_trylock_local(lock) spin_trylock(lock) -+# define spin_unlock_local(lock) spin_unlock(lock) -+#endif -+ -+static inline void __local_lock(struct local_irq_lock *lv) -+{ -+ if (lv->owner != current) { -+ spin_lock_local(&lv->lock); -+ LL_WARN(lv->owner); -+ LL_WARN(lv->nestcnt); -+ lv->owner = current; -+ } -+ lv->nestcnt++; -+} -+ -+#define local_lock(lvar) \ -+ do { __local_lock(&get_local_var(lvar)); } while (0) -+ -+static inline int __local_trylock(struct local_irq_lock *lv) -+{ -+ if (lv->owner != current && spin_trylock_local(&lv->lock)) { -+ LL_WARN(lv->owner); -+ LL_WARN(lv->nestcnt); -+ lv->owner = current; -+ lv->nestcnt = 1; -+ return 1; -+ } -+ return 0; -+} -+ -+#define local_trylock(lvar) \ -+ ({ \ -+ int __locked; \ -+ __locked = __local_trylock(&get_local_var(lvar)); \ -+ if (!__locked) \ -+ put_local_var(lvar); \ -+ __locked; \ -+ }) -+ -+static inline void __local_unlock(struct local_irq_lock *lv) -+{ -+ LL_WARN(lv->nestcnt == 0); -+ LL_WARN(lv->owner != current); -+ if (--lv->nestcnt) -+ return; -+ -+ lv->owner = NULL; -+ spin_unlock_local(&lv->lock); -+} -+ -+#define local_unlock(lvar) \ -+ do { \ -+ __local_unlock(this_cpu_ptr(&lvar)); \ -+ put_local_var(lvar); \ -+ } while (0) -+ -+static inline void __local_lock_irq(struct local_irq_lock *lv) -+{ -+ spin_lock_irqsave(&lv->lock, lv->flags); -+ LL_WARN(lv->owner); -+ LL_WARN(lv->nestcnt); -+ lv->owner = current; -+ lv->nestcnt = 1; -+} -+ -+#define local_lock_irq(lvar) \ -+ do { __local_lock_irq(&get_local_var(lvar)); } while (0) -+ -+#define local_lock_irq_on(lvar, cpu) \ -+ do { __local_lock_irq(&per_cpu(lvar, cpu)); } while (0) -+ -+static inline void __local_unlock_irq(struct local_irq_lock *lv) -+{ -+ LL_WARN(!lv->nestcnt); -+ LL_WARN(lv->owner != current); -+ lv->owner = NULL; -+ lv->nestcnt = 0; -+ spin_unlock_irq(&lv->lock); -+} -+ -+#define local_unlock_irq(lvar) \ -+ do { \ -+ __local_unlock_irq(this_cpu_ptr(&lvar)); \ -+ put_local_var(lvar); \ -+ } while (0) -+ -+#define local_unlock_irq_on(lvar, cpu) \ -+ do { \ -+ __local_unlock_irq(&per_cpu(lvar, cpu)); \ -+ } while (0) -+ -+static inline int __local_lock_irqsave(struct local_irq_lock *lv) -+{ -+ if (lv->owner != current) { -+ __local_lock_irq(lv); -+ return 0; -+ } else { -+ lv->nestcnt++; -+ return 1; -+ } -+} -+ -+#define local_lock_irqsave(lvar, _flags) \ -+ do { \ -+ if (__local_lock_irqsave(&get_local_var(lvar))) \ -+ put_local_var(lvar); \ -+ _flags = __this_cpu_read(lvar.flags); \ -+ } while (0) -+ -+#define local_lock_irqsave_on(lvar, _flags, cpu) \ -+ do { \ -+ __local_lock_irqsave(&per_cpu(lvar, cpu)); \ -+ _flags = per_cpu(lvar, cpu).flags; \ -+ } while (0) -+ -+static inline int __local_unlock_irqrestore(struct local_irq_lock *lv, -+ unsigned long flags) -+{ -+ LL_WARN(!lv->nestcnt); -+ LL_WARN(lv->owner != current); -+ if (--lv->nestcnt) -+ return 0; -+ -+ lv->owner = NULL; -+ spin_unlock_irqrestore(&lv->lock, lv->flags); -+ return 1; -+} -+ -+#define local_unlock_irqrestore(lvar, flags) \ -+ do { \ -+ if (__local_unlock_irqrestore(this_cpu_ptr(&lvar), flags)) \ -+ put_local_var(lvar); \ -+ } while (0) -+ -+#define local_unlock_irqrestore_on(lvar, flags, cpu) \ -+ do { \ -+ __local_unlock_irqrestore(&per_cpu(lvar, cpu), flags); \ -+ } while (0) -+ -+#define local_spin_trylock_irq(lvar, lock) \ -+ ({ \ -+ int __locked; \ -+ local_lock_irq(lvar); \ -+ __locked = spin_trylock(lock); \ -+ if (!__locked) \ -+ local_unlock_irq(lvar); \ -+ __locked; \ -+ }) -+ -+#define local_spin_lock_irq(lvar, lock) \ -+ do { \ -+ local_lock_irq(lvar); \ -+ spin_lock(lock); \ -+ } while (0) -+ -+#define local_spin_unlock_irq(lvar, lock) \ -+ do { \ -+ spin_unlock(lock); \ -+ local_unlock_irq(lvar); \ -+ } while (0) -+ -+#define local_spin_lock_irqsave(lvar, lock, flags) \ -+ do { \ -+ local_lock_irqsave(lvar, flags); \ -+ spin_lock(lock); \ -+ } while (0) -+ -+#define local_spin_unlock_irqrestore(lvar, lock, flags) \ -+ do { \ -+ spin_unlock(lock); \ -+ local_unlock_irqrestore(lvar, flags); \ -+ } while (0) -+ -+#define get_locked_var(lvar, var) \ -+ (*({ \ -+ local_lock(lvar); \ -+ this_cpu_ptr(&var); \ -+ })) -+ -+#define put_locked_var(lvar, var) local_unlock(lvar); -+ -+#define local_lock_cpu(lvar) \ -+ ({ \ -+ local_lock(lvar); \ -+ smp_processor_id(); \ -+ }) -+ -+#define local_unlock_cpu(lvar) local_unlock(lvar) -+ -+#else /* PREEMPT_RT_BASE */ -+ -+#define DEFINE_LOCAL_IRQ_LOCK(lvar) __typeof__(const int) lvar -+#define DECLARE_LOCAL_IRQ_LOCK(lvar) extern __typeof__(const int) lvar -+ -+static inline void local_irq_lock_init(int lvar) { } -+ -+#define local_lock(lvar) preempt_disable() -+#define local_unlock(lvar) preempt_enable() -+#define local_lock_irq(lvar) local_irq_disable() -+#define local_lock_irq_on(lvar, cpu) local_irq_disable() -+#define local_unlock_irq(lvar) local_irq_enable() -+#define local_unlock_irq_on(lvar, cpu) local_irq_enable() -+#define local_lock_irqsave(lvar, flags) local_irq_save(flags) -+#define local_unlock_irqrestore(lvar, flags) local_irq_restore(flags) -+ -+#define local_spin_trylock_irq(lvar, lock) spin_trylock_irq(lock) -+#define local_spin_lock_irq(lvar, lock) spin_lock_irq(lock) -+#define local_spin_unlock_irq(lvar, lock) spin_unlock_irq(lock) -+#define local_spin_lock_irqsave(lvar, lock, flags) \ -+ spin_lock_irqsave(lock, flags) -+#define local_spin_unlock_irqrestore(lvar, lock, flags) \ -+ spin_unlock_irqrestore(lock, flags) -+ -+#define get_locked_var(lvar, var) get_cpu_var(var) -+#define put_locked_var(lvar, var) put_cpu_var(var) -+ -+#define local_lock_cpu(lvar) get_cpu() -+#define local_unlock_cpu(lvar) put_cpu() -+ -+#endif -+ -+#endif -diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h -index c2d75b4..8349504 100644 ---- a/include/linux/mm_types.h -+++ b/include/linux/mm_types.h -@@ -11,6 +11,7 @@ - #include <linux/completion.h> - #include <linux/cpumask.h> - #include <linux/uprobes.h> -+#include <linux/rcupdate.h> - #include <linux/page-flags-layout.h> - #include <asm/page.h> - #include <asm/mmu.h> -@@ -502,6 +503,9 @@ struct mm_struct { - bool tlb_flush_pending; - #endif - struct uprobes_state uprobes_state; -+#ifdef CONFIG_PREEMPT_RT_BASE -+ struct rcu_head delayed_drop; -+#endif - #ifdef CONFIG_X86_INTEL_MPX - /* address of the bounds directory */ - void __user *bd_addr; -diff --git a/include/linux/mutex.h b/include/linux/mutex.h -index 2cb7531..b3fdfc8 100644 ---- a/include/linux/mutex.h -+++ b/include/linux/mutex.h -@@ -19,6 +19,17 @@ - #include <asm/processor.h> - #include <linux/osq_lock.h> - -+#ifdef CONFIG_DEBUG_LOCK_ALLOC -+# define __DEP_MAP_MUTEX_INITIALIZER(lockname) \ -+ , .dep_map = { .name = #lockname } -+#else -+# define __DEP_MAP_MUTEX_INITIALIZER(lockname) -+#endif -+ -+#ifdef CONFIG_PREEMPT_RT_FULL -+# include <linux/mutex_rt.h> -+#else -+ - /* - * Simple, straightforward mutexes with strict semantics: - * -@@ -99,13 +110,6 @@ do { \ - static inline void mutex_destroy(struct mutex *lock) {} - #endif - --#ifdef CONFIG_DEBUG_LOCK_ALLOC --# define __DEP_MAP_MUTEX_INITIALIZER(lockname) \ -- , .dep_map = { .name = #lockname } --#else --# define __DEP_MAP_MUTEX_INITIALIZER(lockname) --#endif -- - #define __MUTEX_INITIALIZER(lockname) \ - { .count = ATOMIC_INIT(1) \ - , .wait_lock = __SPIN_LOCK_UNLOCKED(lockname.wait_lock) \ -@@ -173,6 +177,8 @@ extern int __must_check mutex_lock_killable(struct mutex *lock); - extern int mutex_trylock(struct mutex *lock); - extern void mutex_unlock(struct mutex *lock); - -+#endif /* !PREEMPT_RT_FULL */ -+ - extern int atomic_dec_and_mutex_lock(atomic_t *cnt, struct mutex *lock); - - #endif /* __LINUX_MUTEX_H */ -diff --git a/include/linux/mutex_rt.h b/include/linux/mutex_rt.h -new file mode 100644 -index 0000000..c38a44b ---- /dev/null -+++ b/include/linux/mutex_rt.h -@@ -0,0 +1,84 @@ -+#ifndef __LINUX_MUTEX_RT_H -+#define __LINUX_MUTEX_RT_H -+ -+#ifndef __LINUX_MUTEX_H -+#error "Please include mutex.h" -+#endif -+ -+#include <linux/rtmutex.h> -+ -+/* FIXME: Just for __lockfunc */ -+#include <linux/spinlock.h> -+ -+struct mutex { -+ struct rt_mutex lock; -+#ifdef CONFIG_DEBUG_LOCK_ALLOC -+ struct lockdep_map dep_map; -+#endif -+}; -+ -+#define __MUTEX_INITIALIZER(mutexname) \ -+ { \ -+ .lock = __RT_MUTEX_INITIALIZER(mutexname.lock) \ -+ __DEP_MAP_MUTEX_INITIALIZER(mutexname) \ -+ } -+ -+#define DEFINE_MUTEX(mutexname) \ -+ struct mutex mutexname = __MUTEX_INITIALIZER(mutexname) -+ -+extern void __mutex_do_init(struct mutex *lock, const char *name, struct lock_class_key *key); -+extern void __lockfunc _mutex_lock(struct mutex *lock); -+extern int __lockfunc _mutex_lock_interruptible(struct mutex *lock); -+extern int __lockfunc _mutex_lock_killable(struct mutex *lock); -+extern void __lockfunc _mutex_lock_nested(struct mutex *lock, int subclass); -+extern void __lockfunc _mutex_lock_nest_lock(struct mutex *lock, struct lockdep_map *nest_lock); -+extern int __lockfunc _mutex_lock_interruptible_nested(struct mutex *lock, int subclass); -+extern int __lockfunc _mutex_lock_killable_nested(struct mutex *lock, int subclass); -+extern int __lockfunc _mutex_trylock(struct mutex *lock); -+extern void __lockfunc _mutex_unlock(struct mutex *lock); -+ -+#define mutex_is_locked(l) rt_mutex_is_locked(&(l)->lock) -+#define mutex_lock(l) _mutex_lock(l) -+#define mutex_lock_interruptible(l) _mutex_lock_interruptible(l) -+#define mutex_lock_killable(l) _mutex_lock_killable(l) -+#define mutex_trylock(l) _mutex_trylock(l) -+#define mutex_unlock(l) _mutex_unlock(l) -+#define mutex_destroy(l) rt_mutex_destroy(&(l)->lock) -+ -+#ifdef CONFIG_DEBUG_LOCK_ALLOC -+# define mutex_lock_nested(l, s) _mutex_lock_nested(l, s) -+# define mutex_lock_interruptible_nested(l, s) \ -+ _mutex_lock_interruptible_nested(l, s) -+# define mutex_lock_killable_nested(l, s) \ -+ _mutex_lock_killable_nested(l, s) -+ -+# define mutex_lock_nest_lock(lock, nest_lock) \ -+do { \ -+ typecheck(struct lockdep_map *, &(nest_lock)->dep_map); \ -+ _mutex_lock_nest_lock(lock, &(nest_lock)->dep_map); \ -+} while (0) -+ -+#else -+# define mutex_lock_nested(l, s) _mutex_lock(l) -+# define mutex_lock_interruptible_nested(l, s) \ -+ _mutex_lock_interruptible(l) -+# define mutex_lock_killable_nested(l, s) \ -+ _mutex_lock_killable(l) -+# define mutex_lock_nest_lock(lock, nest_lock) mutex_lock(lock) -+#endif -+ -+# define mutex_init(mutex) \ -+do { \ -+ static struct lock_class_key __key; \ -+ \ -+ rt_mutex_init(&(mutex)->lock); \ -+ __mutex_do_init((mutex), #mutex, &__key); \ -+} while (0) -+ -+# define __mutex_init(mutex, name, key) \ -+do { \ -+ rt_mutex_init(&(mutex)->lock); \ -+ __mutex_do_init((mutex), name, key); \ -+} while (0) -+ -+#endif -diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h -index 78181a8..06863e4 100644 ---- a/include/linux/netdevice.h -+++ b/include/linux/netdevice.h -@@ -2396,11 +2396,20 @@ void netdev_freemem(struct net_device *dev); - void synchronize_net(void); - int init_dummy_netdev(struct net_device *dev); - -+#ifdef CONFIG_PREEMPT_RT_FULL -+static inline int dev_recursion_level(void) -+{ -+ return current->xmit_recursion; -+} -+ -+#else -+ - DECLARE_PER_CPU(int, xmit_recursion); - static inline int dev_recursion_level(void) - { - return this_cpu_read(xmit_recursion); - } -+#endif - - struct net_device *dev_get_by_index(struct net *net, int ifindex); - struct net_device *__dev_get_by_index(struct net *net, int ifindex); -@@ -2776,6 +2785,7 @@ struct softnet_data { - unsigned int dropped; - struct sk_buff_head input_pkt_queue; - struct napi_struct backlog; -+ struct sk_buff_head tofree_queue; - - }; - -diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h -index 80a305b..fa30ec5 100644 ---- a/include/linux/netfilter/x_tables.h -+++ b/include/linux/netfilter/x_tables.h -@@ -4,6 +4,7 @@ - - #include <linux/netdevice.h> - #include <linux/static_key.h> -+#include <linux/locallock.h> - #include <uapi/linux/netfilter/x_tables.h> - - /** -@@ -285,6 +286,8 @@ void xt_free_table_info(struct xt_table_info *info); - */ - DECLARE_PER_CPU(seqcount_t, xt_recseq); - -+DECLARE_LOCAL_IRQ_LOCK(xt_write_lock); -+ - /* xt_tee_enabled - true if x_tables needs to handle reentrancy - * - * Enabled if current ip(6)tables ruleset has at least one -j TEE rule. -@@ -305,6 +308,9 @@ static inline unsigned int xt_write_recseq_begin(void) - { - unsigned int addend; - -+ /* RT protection */ -+ local_lock(xt_write_lock); -+ - /* - * Low order bit of sequence is set if we already - * called xt_write_recseq_begin(). -@@ -335,6 +341,7 @@ static inline void xt_write_recseq_end(unsigned int addend) - /* this is kind of a write_seqcount_end(), but addend is 0 or 1 */ - smp_wmb(); - __this_cpu_add(xt_recseq.sequence, addend); -+ local_unlock(xt_write_lock); - } - - /* -diff --git a/include/linux/notifier.h b/include/linux/notifier.h -index 4149868..babe5b9 100644 ---- a/include/linux/notifier.h -+++ b/include/linux/notifier.h -@@ -6,7 +6,7 @@ - * - * Alan Cox <Alan.Cox@linux.org> - */ -- -+ - #ifndef _LINUX_NOTIFIER_H - #define _LINUX_NOTIFIER_H - #include <linux/errno.h> -@@ -42,9 +42,7 @@ - * in srcu_notifier_call_chain(): no cache bounces and no memory barriers. - * As compensation, srcu_notifier_chain_unregister() is rather expensive. - * SRCU notifier chains should be used when the chain will be called very -- * often but notifier_blocks will seldom be removed. Also, SRCU notifier -- * chains are slightly more difficult to use because they require special -- * runtime initialization. -+ * often but notifier_blocks will seldom be removed. - */ - - struct notifier_block; -@@ -90,7 +88,7 @@ struct srcu_notifier_head { - (name)->head = NULL; \ - } while (0) - --/* srcu_notifier_heads must be initialized and cleaned up dynamically */ -+/* srcu_notifier_heads must be cleaned up dynamically */ - extern void srcu_init_notifier_head(struct srcu_notifier_head *nh); - #define srcu_cleanup_notifier_head(name) \ - cleanup_srcu_struct(&(name)->srcu); -@@ -103,7 +101,13 @@ extern void srcu_init_notifier_head(struct srcu_notifier_head *nh); - .head = NULL } - #define RAW_NOTIFIER_INIT(name) { \ - .head = NULL } --/* srcu_notifier_heads cannot be initialized statically */ -+ -+#define SRCU_NOTIFIER_INIT(name, pcpu) \ -+ { \ -+ .mutex = __MUTEX_INITIALIZER(name.mutex), \ -+ .head = NULL, \ -+ .srcu = __SRCU_STRUCT_INIT(name.srcu, pcpu), \ -+ } - - #define ATOMIC_NOTIFIER_HEAD(name) \ - struct atomic_notifier_head name = \ -@@ -115,6 +119,18 @@ extern void srcu_init_notifier_head(struct srcu_notifier_head *nh); - struct raw_notifier_head name = \ - RAW_NOTIFIER_INIT(name) - -+#define _SRCU_NOTIFIER_HEAD(name, mod) \ -+ static DEFINE_PER_CPU(struct srcu_struct_array, \ -+ name##_head_srcu_array); \ -+ mod struct srcu_notifier_head name = \ -+ SRCU_NOTIFIER_INIT(name, name##_head_srcu_array) -+ -+#define SRCU_NOTIFIER_HEAD(name) \ -+ _SRCU_NOTIFIER_HEAD(name, ) -+ -+#define SRCU_NOTIFIER_HEAD_STATIC(name) \ -+ _SRCU_NOTIFIER_HEAD(name, static) -+ - #ifdef __KERNEL__ - - extern int atomic_notifier_chain_register(struct atomic_notifier_head *nh, -@@ -184,12 +200,12 @@ static inline int notifier_to_errno(int ret) - - /* - * Declared notifiers so far. I can imagine quite a few more chains -- * over time (eg laptop power reset chains, reboot chain (to clean -+ * over time (eg laptop power reset chains, reboot chain (to clean - * device units up), device [un]mount chain, module load/unload chain, -- * low memory chain, screenblank chain (for plug in modular screenblankers) -+ * low memory chain, screenblank chain (for plug in modular screenblankers) - * VC switch chains (for loadable kernel svgalib VC switch helpers) etc... - */ -- -+ - /* CPU notfiers are defined in include/linux/cpu.h. */ - - /* netdevice notifiers are defined in include/linux/netdevice.h */ -diff --git a/include/linux/percpu.h b/include/linux/percpu.h -index 4bc6daf..c0b6779 100644 ---- a/include/linux/percpu.h -+++ b/include/linux/percpu.h -@@ -18,6 +18,35 @@ - #define PERCPU_MODULE_RESERVE 0 - #endif - -+#ifdef CONFIG_PREEMPT_RT_FULL -+ -+#define get_local_var(var) (*({ \ -+ migrate_disable(); \ -+ this_cpu_ptr(&var); })) -+ -+#define put_local_var(var) do { \ -+ (void)&(var); \ -+ migrate_enable(); \ -+} while (0) -+ -+# define get_local_ptr(var) ({ \ -+ migrate_disable(); \ -+ this_cpu_ptr(var); }) -+ -+# define put_local_ptr(var) do { \ -+ (void)(var); \ -+ migrate_enable(); \ -+} while (0) -+ -+#else -+ -+#define get_local_var(var) get_cpu_var(var) -+#define put_local_var(var) put_cpu_var(var) -+#define get_local_ptr(var) get_cpu_ptr(var) -+#define put_local_ptr(var) put_cpu_ptr(var) -+ -+#endif -+ - /* minimum unit size, also is the maximum supported allocation size */ - #define PCPU_MIN_UNIT_SIZE PFN_ALIGN(32 << 10) - -diff --git a/include/linux/pid.h b/include/linux/pid.h -index 23705a5..2cc64b7 100644 ---- a/include/linux/pid.h -+++ b/include/linux/pid.h -@@ -2,6 +2,7 @@ - #define _LINUX_PID_H - - #include <linux/rcupdate.h> -+#include <linux/atomic.h> - - enum pid_type - { -diff --git a/include/linux/preempt.h b/include/linux/preempt.h -index 75e4e30..1cfb1cb 100644 ---- a/include/linux/preempt.h -+++ b/include/linux/preempt.h -@@ -50,7 +50,11 @@ - #define HARDIRQ_OFFSET (1UL << HARDIRQ_SHIFT) - #define NMI_OFFSET (1UL << NMI_SHIFT) - --#define SOFTIRQ_DISABLE_OFFSET (2 * SOFTIRQ_OFFSET) -+#ifndef CONFIG_PREEMPT_RT_FULL -+# define SOFTIRQ_DISABLE_OFFSET (2 * SOFTIRQ_OFFSET) -+#else -+# define SOFTIRQ_DISABLE_OFFSET (0) -+#endif - - /* We use the MSB mostly because its available */ - #define PREEMPT_NEED_RESCHED 0x80000000 -@@ -59,9 +63,15 @@ - #include <asm/preempt.h> - - #define hardirq_count() (preempt_count() & HARDIRQ_MASK) --#define softirq_count() (preempt_count() & SOFTIRQ_MASK) - #define irq_count() (preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK \ - | NMI_MASK)) -+#ifndef CONFIG_PREEMPT_RT_FULL -+# define softirq_count() (preempt_count() & SOFTIRQ_MASK) -+# define in_serving_softirq() (softirq_count() & SOFTIRQ_OFFSET) -+#else -+# define softirq_count() (0UL) -+extern int in_serving_softirq(void); -+#endif - - /* - * Are we doing bottom half or hardware interrupt processing? -@@ -72,7 +82,6 @@ - #define in_irq() (hardirq_count()) - #define in_softirq() (softirq_count()) - #define in_interrupt() (irq_count()) --#define in_serving_softirq() (softirq_count() & SOFTIRQ_OFFSET) - - /* - * Are we in NMI context? -@@ -91,7 +100,11 @@ - /* - * The preempt_count offset after spin_lock() - */ -+#if !defined(CONFIG_PREEMPT_RT_FULL) - #define PREEMPT_LOCK_OFFSET PREEMPT_DISABLE_OFFSET -+#else -+#define PREEMPT_LOCK_OFFSET 0 -+#endif - - /* - * The preempt_count offset needed for things like: -@@ -140,6 +153,20 @@ extern void preempt_count_sub(int val); - #define preempt_count_inc() preempt_count_add(1) - #define preempt_count_dec() preempt_count_sub(1) - -+#ifdef CONFIG_PREEMPT_LAZY -+#define add_preempt_lazy_count(val) do { preempt_lazy_count() += (val); } while (0) -+#define sub_preempt_lazy_count(val) do { preempt_lazy_count() -= (val); } while (0) -+#define inc_preempt_lazy_count() add_preempt_lazy_count(1) -+#define dec_preempt_lazy_count() sub_preempt_lazy_count(1) -+#define preempt_lazy_count() (current_thread_info()->preempt_lazy_count) -+#else -+#define add_preempt_lazy_count(val) do { } while (0) -+#define sub_preempt_lazy_count(val) do { } while (0) -+#define inc_preempt_lazy_count() do { } while (0) -+#define dec_preempt_lazy_count() do { } while (0) -+#define preempt_lazy_count() (0) -+#endif -+ - #ifdef CONFIG_PREEMPT_COUNT - - #define preempt_disable() \ -@@ -148,13 +175,25 @@ do { \ - barrier(); \ - } while (0) - -+#define preempt_lazy_disable() \ -+do { \ -+ inc_preempt_lazy_count(); \ -+ barrier(); \ -+} while (0) -+ - #define sched_preempt_enable_no_resched() \ - do { \ - barrier(); \ - preempt_count_dec(); \ - } while (0) - --#define preempt_enable_no_resched() sched_preempt_enable_no_resched() -+#ifdef CONFIG_PREEMPT_RT_BASE -+# define preempt_enable_no_resched() sched_preempt_enable_no_resched() -+# define preempt_check_resched_rt() preempt_check_resched() -+#else -+# define preempt_enable_no_resched() preempt_enable() -+# define preempt_check_resched_rt() barrier(); -+#endif - - #define preemptible() (preempt_count() == 0 && !irqs_disabled()) - -@@ -179,6 +218,13 @@ do { \ - __preempt_schedule(); \ - } while (0) - -+#define preempt_lazy_enable() \ -+do { \ -+ dec_preempt_lazy_count(); \ -+ barrier(); \ -+ preempt_check_resched(); \ -+} while (0) -+ - #else /* !CONFIG_PREEMPT */ - #define preempt_enable() \ - do { \ -@@ -224,6 +270,7 @@ do { \ - #define preempt_disable_notrace() barrier() - #define preempt_enable_no_resched_notrace() barrier() - #define preempt_enable_notrace() barrier() -+#define preempt_check_resched_rt() barrier() - #define preemptible() 0 - - #endif /* CONFIG_PREEMPT_COUNT */ -@@ -244,10 +291,31 @@ do { \ - } while (0) - #define preempt_fold_need_resched() \ - do { \ -- if (tif_need_resched()) \ -+ if (tif_need_resched_now()) \ - set_preempt_need_resched(); \ - } while (0) - -+#ifdef CONFIG_PREEMPT_RT_FULL -+# define preempt_disable_rt() preempt_disable() -+# define preempt_enable_rt() preempt_enable() -+# define preempt_disable_nort() barrier() -+# define preempt_enable_nort() barrier() -+# ifdef CONFIG_SMP -+ extern void migrate_disable(void); -+ extern void migrate_enable(void); -+# else /* CONFIG_SMP */ -+# define migrate_disable() barrier() -+# define migrate_enable() barrier() -+# endif /* CONFIG_SMP */ -+#else -+# define preempt_disable_rt() barrier() -+# define preempt_enable_rt() barrier() -+# define preempt_disable_nort() preempt_disable() -+# define preempt_enable_nort() preempt_enable() -+# define migrate_disable() preempt_disable() -+# define migrate_enable() preempt_enable() -+#endif -+ - #ifdef CONFIG_PREEMPT_NOTIFIERS - - struct preempt_notifier; -diff --git a/include/linux/printk.h b/include/linux/printk.h -index 9ccbdf2..428d6a7 100644 ---- a/include/linux/printk.h -+++ b/include/linux/printk.h -@@ -117,9 +117,11 @@ do { \ - #ifdef CONFIG_EARLY_PRINTK - extern asmlinkage __printf(1, 2) - void early_printk(const char *fmt, ...); -+extern void printk_kill(void); - #else - static inline __printf(1, 2) __cold - void early_printk(const char *s, ...) { } -+static inline void printk_kill(void) { } - #endif - - typedef __printf(1, 0) int (*printk_func_t)(const char *fmt, va_list args); -diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h -index 51a97ac..0608483 100644 ---- a/include/linux/radix-tree.h -+++ b/include/linux/radix-tree.h -@@ -294,8 +294,13 @@ radix_tree_gang_lookup(struct radix_tree_root *root, void **results, - unsigned int radix_tree_gang_lookup_slot(struct radix_tree_root *root, - void ***results, unsigned long *indices, - unsigned long first_index, unsigned int max_items); -+#ifndef CONFIG_PREEMPT_RT_FULL - int radix_tree_preload(gfp_t gfp_mask); - int radix_tree_maybe_preload(gfp_t gfp_mask); -+#else -+static inline int radix_tree_preload(gfp_t gm) { return 0; } -+static inline int radix_tree_maybe_preload(gfp_t gfp_mask) { return 0; } -+#endif - void radix_tree_init(void); - void *radix_tree_tag_set(struct radix_tree_root *root, - unsigned long index, unsigned int tag); -@@ -320,7 +325,7 @@ unsigned long radix_tree_locate_item(struct radix_tree_root *root, void *item); - - static inline void radix_tree_preload_end(void) - { -- preempt_enable(); -+ preempt_enable_nort(); - } - - /** -diff --git a/include/linux/random.h b/include/linux/random.h -index 9c29122..e7f2f86 100644 ---- a/include/linux/random.h -+++ b/include/linux/random.h -@@ -20,7 +20,7 @@ struct random_ready_callback { - extern void add_device_randomness(const void *, unsigned int); - extern void add_input_randomness(unsigned int type, unsigned int code, - unsigned int value); --extern void add_interrupt_randomness(int irq, int irq_flags); -+extern void add_interrupt_randomness(int irq, int irq_flags, __u64 ip); - - extern void get_random_bytes(void *buf, int nbytes); - extern int add_random_ready_callback(struct random_ready_callback *rdy); -diff --git a/include/linux/rbtree.h b/include/linux/rbtree.h -index b690009..fdc2e95 100644 ---- a/include/linux/rbtree.h -+++ b/include/linux/rbtree.h -@@ -31,7 +31,6 @@ - - #include <linux/kernel.h> - #include <linux/stddef.h> --#include <linux/rcupdate.h> - - struct rb_node { - unsigned long __rb_parent_color; -@@ -86,14 +85,8 @@ static inline void rb_link_node(struct rb_node *node, struct rb_node *parent, - *rb_link = node; - } - --static inline void rb_link_node_rcu(struct rb_node *node, struct rb_node *parent, -- struct rb_node **rb_link) --{ -- node->__rb_parent_color = (unsigned long)parent; -- node->rb_left = node->rb_right = NULL; -- -- rcu_assign_pointer(*rb_link, node); --} -+void rb_link_node_rcu(struct rb_node *node, struct rb_node *parent, -+ struct rb_node **rb_link); - - #define rb_entry_safe(ptr, type, member) \ - ({ typeof(ptr) ____ptr = (ptr); \ -diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h -index 2657aff..ea90179 100644 ---- a/include/linux/rcupdate.h -+++ b/include/linux/rcupdate.h -@@ -177,6 +177,9 @@ void call_rcu(struct rcu_head *head, - - #endif /* #else #ifdef CONFIG_PREEMPT_RCU */ - -+#ifdef CONFIG_PREEMPT_RT_FULL -+#define call_rcu_bh call_rcu -+#else - /** - * call_rcu_bh() - Queue an RCU for invocation after a quicker grace period. - * @head: structure to be used for queueing the RCU updates. -@@ -200,6 +203,7 @@ void call_rcu(struct rcu_head *head, - */ - void call_rcu_bh(struct rcu_head *head, - rcu_callback_t func); -+#endif - - /** - * call_rcu_sched() - Queue an RCU for invocation after sched grace period. -@@ -300,6 +304,11 @@ void synchronize_rcu(void); - * types of kernel builds, the rcu_read_lock() nesting depth is unknowable. - */ - #define rcu_preempt_depth() (current->rcu_read_lock_nesting) -+#ifndef CONFIG_PREEMPT_RT_FULL -+#define sched_rcu_preempt_depth() rcu_preempt_depth() -+#else -+static inline int sched_rcu_preempt_depth(void) { return 0; } -+#endif - - #else /* #ifdef CONFIG_PREEMPT_RCU */ - -@@ -325,6 +334,8 @@ static inline int rcu_preempt_depth(void) - return 0; - } - -+#define sched_rcu_preempt_depth() rcu_preempt_depth() -+ - #endif /* #else #ifdef CONFIG_PREEMPT_RCU */ - - /* Internal to kernel */ -@@ -498,7 +509,14 @@ extern struct lockdep_map rcu_callback_map; - int debug_lockdep_rcu_enabled(void); - - int rcu_read_lock_held(void); -+#ifdef CONFIG_PREEMPT_RT_FULL -+static inline int rcu_read_lock_bh_held(void) -+{ -+ return rcu_read_lock_held(); -+} -+#else - int rcu_read_lock_bh_held(void); -+#endif - - /** - * rcu_read_lock_sched_held() - might we be in RCU-sched read-side critical section? -@@ -946,10 +964,14 @@ static inline void rcu_read_unlock(void) - static inline void rcu_read_lock_bh(void) - { - local_bh_disable(); -+#ifdef CONFIG_PREEMPT_RT_FULL -+ rcu_read_lock(); -+#else - __acquire(RCU_BH); - rcu_lock_acquire(&rcu_bh_lock_map); - RCU_LOCKDEP_WARN(!rcu_is_watching(), - "rcu_read_lock_bh() used illegally while idle"); -+#endif - } - - /* -@@ -959,10 +981,14 @@ static inline void rcu_read_lock_bh(void) - */ - static inline void rcu_read_unlock_bh(void) - { -+#ifdef CONFIG_PREEMPT_RT_FULL -+ rcu_read_unlock(); -+#else - RCU_LOCKDEP_WARN(!rcu_is_watching(), - "rcu_read_unlock_bh() used illegally while idle"); - rcu_lock_release(&rcu_bh_lock_map); - __release(RCU_BH); -+#endif - local_bh_enable(); - } - -diff --git a/include/linux/rcutree.h b/include/linux/rcutree.h -index ad1eda9..732192c 100644 ---- a/include/linux/rcutree.h -+++ b/include/linux/rcutree.h -@@ -44,7 +44,11 @@ static inline void rcu_virt_note_context_switch(int cpu) - rcu_note_context_switch(); - } - -+#ifdef CONFIG_PREEMPT_RT_FULL -+# define synchronize_rcu_bh synchronize_rcu -+#else - void synchronize_rcu_bh(void); -+#endif - void synchronize_sched_expedited(void); - void synchronize_rcu_expedited(void); - -@@ -72,7 +76,11 @@ static inline void synchronize_rcu_bh_expedited(void) - } - - void rcu_barrier(void); -+#ifdef CONFIG_PREEMPT_RT_FULL -+# define rcu_barrier_bh rcu_barrier -+#else - void rcu_barrier_bh(void); -+#endif - void rcu_barrier_sched(void); - unsigned long get_state_synchronize_rcu(void); - void cond_synchronize_rcu(unsigned long oldstate); -@@ -85,12 +93,10 @@ unsigned long rcu_batches_started(void); - unsigned long rcu_batches_started_bh(void); - unsigned long rcu_batches_started_sched(void); - unsigned long rcu_batches_completed(void); --unsigned long rcu_batches_completed_bh(void); - unsigned long rcu_batches_completed_sched(void); - void show_rcu_gp_kthreads(void); - - void rcu_force_quiescent_state(void); --void rcu_bh_force_quiescent_state(void); - void rcu_sched_force_quiescent_state(void); - - void rcu_idle_enter(void); -@@ -107,6 +113,14 @@ extern int rcu_scheduler_active __read_mostly; - - bool rcu_is_watching(void); - -+#ifndef CONFIG_PREEMPT_RT_FULL -+void rcu_bh_force_quiescent_state(void); -+unsigned long rcu_batches_completed_bh(void); -+#else -+# define rcu_bh_force_quiescent_state rcu_force_quiescent_state -+# define rcu_batches_completed_bh rcu_batches_completed -+#endif -+ - void rcu_all_qs(void); - - #endif /* __LINUX_RCUTREE_H */ -diff --git a/include/linux/rtmutex.h b/include/linux/rtmutex.h -index 1abba5c..30211c62 100644 ---- a/include/linux/rtmutex.h -+++ b/include/linux/rtmutex.h -@@ -13,11 +13,15 @@ - #define __LINUX_RT_MUTEX_H - - #include <linux/linkage.h> -+#include <linux/spinlock_types_raw.h> - #include <linux/rbtree.h> --#include <linux/spinlock_types.h> - - extern int max_lock_depth; /* for sysctl */ - -+#ifdef CONFIG_DEBUG_MUTEXES -+#include <linux/debug_locks.h> -+#endif -+ - /** - * The rt_mutex structure - * -@@ -31,8 +35,8 @@ struct rt_mutex { - struct rb_root waiters; - struct rb_node *waiters_leftmost; - struct task_struct *owner; --#ifdef CONFIG_DEBUG_RT_MUTEXES - int save_state; -+#ifdef CONFIG_DEBUG_RT_MUTEXES - const char *name, *file; - int line; - void *magic; -@@ -55,22 +59,33 @@ struct hrtimer_sleeper; - # define rt_mutex_debug_check_no_locks_held(task) do { } while (0) - #endif - -+# define rt_mutex_init(mutex) \ -+ do { \ -+ raw_spin_lock_init(&(mutex)->wait_lock); \ -+ __rt_mutex_init(mutex, #mutex); \ -+ } while (0) -+ - #ifdef CONFIG_DEBUG_RT_MUTEXES - # define __DEBUG_RT_MUTEX_INITIALIZER(mutexname) \ - , .name = #mutexname, .file = __FILE__, .line = __LINE__ --# define rt_mutex_init(mutex) __rt_mutex_init(mutex, __func__) - extern void rt_mutex_debug_task_free(struct task_struct *tsk); - #else - # define __DEBUG_RT_MUTEX_INITIALIZER(mutexname) --# define rt_mutex_init(mutex) __rt_mutex_init(mutex, NULL) - # define rt_mutex_debug_task_free(t) do { } while (0) - #endif - --#define __RT_MUTEX_INITIALIZER(mutexname) \ -- { .wait_lock = __RAW_SPIN_LOCK_UNLOCKED(mutexname.wait_lock) \ -+#define __RT_MUTEX_INITIALIZER_PLAIN(mutexname) \ -+ .wait_lock = __RAW_SPIN_LOCK_UNLOCKED(mutexname.wait_lock) \ - , .waiters = RB_ROOT \ - , .owner = NULL \ -- __DEBUG_RT_MUTEX_INITIALIZER(mutexname)} -+ __DEBUG_RT_MUTEX_INITIALIZER(mutexname) -+ -+#define __RT_MUTEX_INITIALIZER(mutexname) \ -+ { __RT_MUTEX_INITIALIZER_PLAIN(mutexname) } -+ -+#define __RT_MUTEX_INITIALIZER_SAVE_STATE(mutexname) \ -+ { __RT_MUTEX_INITIALIZER_PLAIN(mutexname) \ -+ , .save_state = 1 } - - #define DEFINE_RT_MUTEX(mutexname) \ - struct rt_mutex mutexname = __RT_MUTEX_INITIALIZER(mutexname) -@@ -91,6 +106,7 @@ extern void rt_mutex_destroy(struct rt_mutex *lock); - - extern void rt_mutex_lock(struct rt_mutex *lock); - extern int rt_mutex_lock_interruptible(struct rt_mutex *lock); -+extern int rt_mutex_lock_killable(struct rt_mutex *lock); - extern int rt_mutex_timed_lock(struct rt_mutex *lock, - struct hrtimer_sleeper *timeout); - -diff --git a/include/linux/rwlock_rt.h b/include/linux/rwlock_rt.h -new file mode 100644 -index 0000000..49ed2d4 ---- /dev/null -+++ b/include/linux/rwlock_rt.h -@@ -0,0 +1,99 @@ -+#ifndef __LINUX_RWLOCK_RT_H -+#define __LINUX_RWLOCK_RT_H -+ -+#ifndef __LINUX_SPINLOCK_H -+#error Do not include directly. Use spinlock.h -+#endif -+ -+#define rwlock_init(rwl) \ -+do { \ -+ static struct lock_class_key __key; \ -+ \ -+ rt_mutex_init(&(rwl)->lock); \ -+ __rt_rwlock_init(rwl, #rwl, &__key); \ -+} while (0) -+ -+extern void __lockfunc rt_write_lock(rwlock_t *rwlock); -+extern void __lockfunc rt_read_lock(rwlock_t *rwlock); -+extern int __lockfunc rt_write_trylock(rwlock_t *rwlock); -+extern int __lockfunc rt_write_trylock_irqsave(rwlock_t *trylock, unsigned long *flags); -+extern int __lockfunc rt_read_trylock(rwlock_t *rwlock); -+extern void __lockfunc rt_write_unlock(rwlock_t *rwlock); -+extern void __lockfunc rt_read_unlock(rwlock_t *rwlock); -+extern unsigned long __lockfunc rt_write_lock_irqsave(rwlock_t *rwlock); -+extern unsigned long __lockfunc rt_read_lock_irqsave(rwlock_t *rwlock); -+extern void __rt_rwlock_init(rwlock_t *rwlock, char *name, struct lock_class_key *key); -+ -+#define read_trylock(lock) __cond_lock(lock, rt_read_trylock(lock)) -+#define write_trylock(lock) __cond_lock(lock, rt_write_trylock(lock)) -+ -+#define write_trylock_irqsave(lock, flags) \ -+ __cond_lock(lock, rt_write_trylock_irqsave(lock, &flags)) -+ -+#define read_lock_irqsave(lock, flags) \ -+ do { \ -+ typecheck(unsigned long, flags); \ -+ flags = rt_read_lock_irqsave(lock); \ -+ } while (0) -+ -+#define write_lock_irqsave(lock, flags) \ -+ do { \ -+ typecheck(unsigned long, flags); \ -+ flags = rt_write_lock_irqsave(lock); \ -+ } while (0) -+ -+#define read_lock(lock) rt_read_lock(lock) -+ -+#define read_lock_bh(lock) \ -+ do { \ -+ local_bh_disable(); \ -+ rt_read_lock(lock); \ -+ } while (0) -+ -+#define read_lock_irq(lock) read_lock(lock) -+ -+#define write_lock(lock) rt_write_lock(lock) -+ -+#define write_lock_bh(lock) \ -+ do { \ -+ local_bh_disable(); \ -+ rt_write_lock(lock); \ -+ } while (0) -+ -+#define write_lock_irq(lock) write_lock(lock) -+ -+#define read_unlock(lock) rt_read_unlock(lock) -+ -+#define read_unlock_bh(lock) \ -+ do { \ -+ rt_read_unlock(lock); \ -+ local_bh_enable(); \ -+ } while (0) -+ -+#define read_unlock_irq(lock) read_unlock(lock) -+ -+#define write_unlock(lock) rt_write_unlock(lock) -+ -+#define write_unlock_bh(lock) \ -+ do { \ -+ rt_write_unlock(lock); \ -+ local_bh_enable(); \ -+ } while (0) -+ -+#define write_unlock_irq(lock) write_unlock(lock) -+ -+#define read_unlock_irqrestore(lock, flags) \ -+ do { \ -+ typecheck(unsigned long, flags); \ -+ (void) flags; \ -+ rt_read_unlock(lock); \ -+ } while (0) -+ -+#define write_unlock_irqrestore(lock, flags) \ -+ do { \ -+ typecheck(unsigned long, flags); \ -+ (void) flags; \ -+ rt_write_unlock(lock); \ -+ } while (0) -+ -+#endif -diff --git a/include/linux/rwlock_types.h b/include/linux/rwlock_types.h -index cc0072e..5317cd9 100644 ---- a/include/linux/rwlock_types.h -+++ b/include/linux/rwlock_types.h -@@ -1,6 +1,10 @@ - #ifndef __LINUX_RWLOCK_TYPES_H - #define __LINUX_RWLOCK_TYPES_H - -+#if !defined(__LINUX_SPINLOCK_TYPES_H) -+# error "Do not include directly, include spinlock_types.h" -+#endif -+ - /* - * include/linux/rwlock_types.h - generic rwlock type definitions - * and initializers -diff --git a/include/linux/rwlock_types_rt.h b/include/linux/rwlock_types_rt.h -new file mode 100644 -index 0000000..51b28d77 ---- /dev/null -+++ b/include/linux/rwlock_types_rt.h -@@ -0,0 +1,33 @@ -+#ifndef __LINUX_RWLOCK_TYPES_RT_H -+#define __LINUX_RWLOCK_TYPES_RT_H -+ -+#ifndef __LINUX_SPINLOCK_TYPES_H -+#error "Do not include directly. Include spinlock_types.h instead" -+#endif -+ -+/* -+ * rwlocks - rtmutex which allows single reader recursion -+ */ -+typedef struct { -+ struct rt_mutex lock; -+ int read_depth; -+ unsigned int break_lock; -+#ifdef CONFIG_DEBUG_LOCK_ALLOC -+ struct lockdep_map dep_map; -+#endif -+} rwlock_t; -+ -+#ifdef CONFIG_DEBUG_LOCK_ALLOC -+# define RW_DEP_MAP_INIT(lockname) .dep_map = { .name = #lockname } -+#else -+# define RW_DEP_MAP_INIT(lockname) -+#endif -+ -+#define __RW_LOCK_UNLOCKED(name) \ -+ { .lock = __RT_MUTEX_INITIALIZER_SAVE_STATE(name.lock), \ -+ RW_DEP_MAP_INIT(name) } -+ -+#define DEFINE_RWLOCK(name) \ -+ rwlock_t name = __RW_LOCK_UNLOCKED(name) -+ -+#endif -diff --git a/include/linux/rwsem.h b/include/linux/rwsem.h -index 8f498cd..2b21484 100644 ---- a/include/linux/rwsem.h -+++ b/include/linux/rwsem.h -@@ -18,6 +18,10 @@ - #include <linux/osq_lock.h> - #endif - -+#ifdef CONFIG_PREEMPT_RT_FULL -+#include <linux/rwsem_rt.h> -+#else /* PREEMPT_RT_FULL */ -+ - struct rw_semaphore; - - #ifdef CONFIG_RWSEM_GENERIC_SPINLOCK -@@ -177,4 +181,6 @@ extern void up_read_non_owner(struct rw_semaphore *sem); - # define up_read_non_owner(sem) up_read(sem) - #endif - -+#endif /* !PREEMPT_RT_FULL */ -+ - #endif /* _LINUX_RWSEM_H */ -diff --git a/include/linux/rwsem_rt.h b/include/linux/rwsem_rt.h -new file mode 100644 -index 0000000..f97860b ---- /dev/null -+++ b/include/linux/rwsem_rt.h -@@ -0,0 +1,152 @@ -+#ifndef _LINUX_RWSEM_RT_H -+#define _LINUX_RWSEM_RT_H -+ -+#ifndef _LINUX_RWSEM_H -+#error "Include rwsem.h" -+#endif -+ -+/* -+ * RW-semaphores are a spinlock plus a reader-depth count. -+ * -+ * Note that the semantics are different from the usual -+ * Linux rw-sems, in PREEMPT_RT mode we do not allow -+ * multiple readers to hold the lock at once, we only allow -+ * a read-lock owner to read-lock recursively. This is -+ * better for latency, makes the implementation inherently -+ * fair and makes it simpler as well. -+ */ -+ -+#include <linux/rtmutex.h> -+ -+struct rw_semaphore { -+ struct rt_mutex lock; -+ int read_depth; -+#ifdef CONFIG_DEBUG_LOCK_ALLOC -+ struct lockdep_map dep_map; -+#endif -+}; -+ -+#define __RWSEM_INITIALIZER(name) \ -+ { .lock = __RT_MUTEX_INITIALIZER(name.lock), \ -+ RW_DEP_MAP_INIT(name) } -+ -+#define DECLARE_RWSEM(lockname) \ -+ struct rw_semaphore lockname = __RWSEM_INITIALIZER(lockname) -+ -+extern void __rt_rwsem_init(struct rw_semaphore *rwsem, const char *name, -+ struct lock_class_key *key); -+ -+#define __rt_init_rwsem(sem, name, key) \ -+ do { \ -+ rt_mutex_init(&(sem)->lock); \ -+ __rt_rwsem_init((sem), (name), (key));\ -+ } while (0) -+ -+#define __init_rwsem(sem, name, key) __rt_init_rwsem(sem, name, key) -+ -+# define rt_init_rwsem(sem) \ -+do { \ -+ static struct lock_class_key __key; \ -+ \ -+ __rt_init_rwsem((sem), #sem, &__key); \ -+} while (0) -+ -+extern void rt_down_write(struct rw_semaphore *rwsem); -+extern void rt_down_read_nested(struct rw_semaphore *rwsem, int subclass); -+extern void rt_down_write_nested(struct rw_semaphore *rwsem, int subclass); -+extern void rt_down_write_nested_lock(struct rw_semaphore *rwsem, -+ struct lockdep_map *nest); -+extern void rt__down_read(struct rw_semaphore *rwsem); -+extern void rt_down_read(struct rw_semaphore *rwsem); -+extern int rt_down_write_trylock(struct rw_semaphore *rwsem); -+extern int rt__down_read_trylock(struct rw_semaphore *rwsem); -+extern int rt_down_read_trylock(struct rw_semaphore *rwsem); -+extern void __rt_up_read(struct rw_semaphore *rwsem); -+extern void rt_up_read(struct rw_semaphore *rwsem); -+extern void rt_up_write(struct rw_semaphore *rwsem); -+extern void rt_downgrade_write(struct rw_semaphore *rwsem); -+ -+#define init_rwsem(sem) rt_init_rwsem(sem) -+#define rwsem_is_locked(s) rt_mutex_is_locked(&(s)->lock) -+ -+static inline int rwsem_is_contended(struct rw_semaphore *sem) -+{ -+ /* rt_mutex_has_waiters() */ -+ return !RB_EMPTY_ROOT(&sem->lock.waiters); -+} -+ -+static inline void __down_read(struct rw_semaphore *sem) -+{ -+ rt__down_read(sem); -+} -+ -+static inline void down_read(struct rw_semaphore *sem) -+{ -+ rt_down_read(sem); -+} -+ -+static inline int __down_read_trylock(struct rw_semaphore *sem) -+{ -+ return rt__down_read_trylock(sem); -+} -+ -+static inline int down_read_trylock(struct rw_semaphore *sem) -+{ -+ return rt_down_read_trylock(sem); -+} -+ -+static inline void down_write(struct rw_semaphore *sem) -+{ -+ rt_down_write(sem); -+} -+ -+static inline int down_write_trylock(struct rw_semaphore *sem) -+{ -+ return rt_down_write_trylock(sem); -+} -+ -+static inline void __up_read(struct rw_semaphore *sem) -+{ -+ __rt_up_read(sem); -+} -+ -+static inline void up_read(struct rw_semaphore *sem) -+{ -+ rt_up_read(sem); -+} -+ -+static inline void up_write(struct rw_semaphore *sem) -+{ -+ rt_up_write(sem); -+} -+ -+static inline void downgrade_write(struct rw_semaphore *sem) -+{ -+ rt_downgrade_write(sem); -+} -+ -+static inline void down_read_nested(struct rw_semaphore *sem, int subclass) -+{ -+ return rt_down_read_nested(sem, subclass); -+} -+ -+static inline void down_write_nested(struct rw_semaphore *sem, int subclass) -+{ -+ rt_down_write_nested(sem, subclass); -+} -+#ifdef CONFIG_DEBUG_LOCK_ALLOC -+static inline void down_write_nest_lock(struct rw_semaphore *sem, -+ struct rw_semaphore *nest_lock) -+{ -+ rt_down_write_nested_lock(sem, &nest_lock->dep_map); -+} -+ -+#else -+ -+static inline void down_write_nest_lock(struct rw_semaphore *sem, -+ struct rw_semaphore *nest_lock) -+{ -+ rt_down_write_nested_lock(sem, NULL); -+} -+#endif -+#endif -diff --git a/include/linux/sched.h b/include/linux/sched.h -index 52c4847..c242cbd 100644 ---- a/include/linux/sched.h -+++ b/include/linux/sched.h -@@ -26,6 +26,7 @@ struct sched_param { - #include <linux/nodemask.h> - #include <linux/mm_types.h> - #include <linux/preempt.h> -+#include <asm/kmap_types.h> - - #include <asm/page.h> - #include <asm/ptrace.h> -@@ -241,10 +242,7 @@ extern char ___assert_task_state[1 - 2*!!( - TASK_UNINTERRUPTIBLE | __TASK_STOPPED | \ - __TASK_TRACED | EXIT_ZOMBIE | EXIT_DEAD) - --#define task_is_traced(task) ((task->state & __TASK_TRACED) != 0) - #define task_is_stopped(task) ((task->state & __TASK_STOPPED) != 0) --#define task_is_stopped_or_traced(task) \ -- ((task->state & (__TASK_STOPPED | __TASK_TRACED)) != 0) - #define task_contributes_to_load(task) \ - ((task->state & TASK_UNINTERRUPTIBLE) != 0 && \ - (task->flags & PF_FROZEN) == 0 && \ -@@ -310,6 +308,11 @@ extern char ___assert_task_state[1 - 2*!!( - - #endif - -+#define __set_current_state_no_track(state_value) \ -+ do { current->state = (state_value); } while (0) -+#define set_current_state_no_track(state_value) \ -+ set_mb(current->state, (state_value)) -+ - /* Task command name length */ - #define TASK_COMM_LEN 16 - -@@ -981,8 +984,18 @@ struct wake_q_head { - struct wake_q_head name = { WAKE_Q_TAIL, &name.first } - - extern void wake_q_add(struct wake_q_head *head, -- struct task_struct *task); --extern void wake_up_q(struct wake_q_head *head); -+ struct task_struct *task); -+extern void __wake_up_q(struct wake_q_head *head, bool sleeper); -+ -+static inline void wake_up_q(struct wake_q_head *head) -+{ -+ __wake_up_q(head, false); -+} -+ -+static inline void wake_up_q_sleeper(struct wake_q_head *head) -+{ -+ __wake_up_q(head, true); -+} - - /* - * sched-domains (multiprocessor balancing) declarations: -@@ -1393,6 +1406,7 @@ struct tlbflush_unmap_batch { - - struct task_struct { - volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */ -+ volatile long saved_state; /* saved state for "spinlock sleepers" */ - void *stack; - atomic_t usage; - unsigned int flags; /* per process flags, defined below */ -@@ -1429,6 +1443,12 @@ struct task_struct { - #endif - - unsigned int policy; -+#ifdef CONFIG_PREEMPT_RT_FULL -+ int migrate_disable; -+# ifdef CONFIG_SCHED_DEBUG -+ int migrate_disable_atomic; -+# endif -+#endif - int nr_cpus_allowed; - cpumask_t cpus_allowed; - -@@ -1559,6 +1579,9 @@ struct task_struct { - - struct task_cputime cputime_expires; - struct list_head cpu_timers[3]; -+#ifdef CONFIG_PREEMPT_RT_BASE -+ struct task_struct *posix_timer_list; -+#endif - - /* process credentials */ - const struct cred __rcu *real_cred; /* objective and real subjective task -@@ -1589,10 +1612,15 @@ struct task_struct { - /* signal handlers */ - struct signal_struct *signal; - struct sighand_struct *sighand; -+ struct sigqueue *sigqueue_cache; - - sigset_t blocked, real_blocked; - sigset_t saved_sigmask; /* restored if set_restore_sigmask() was used */ - struct sigpending pending; -+#ifdef CONFIG_PREEMPT_RT_FULL -+ /* TODO: move me into ->restart_block ? */ -+ struct siginfo forced_info; -+#endif - - unsigned long sas_ss_sp; - size_t sas_ss_size; -@@ -1820,6 +1848,12 @@ struct task_struct { - /* bitmask and counter of trace recursion */ - unsigned long trace_recursion; - #endif /* CONFIG_TRACING */ -+#ifdef CONFIG_WAKEUP_LATENCY_HIST -+ u64 preempt_timestamp_hist; -+#ifdef CONFIG_MISSED_TIMER_OFFSETS_HIST -+ long timer_offset; -+#endif -+#endif - #ifdef CONFIG_KCOV - /* Coverage collection mode enabled for this task (0 if disabled). */ - enum kcov_mode kcov_mode; -@@ -1845,9 +1879,23 @@ struct task_struct { - unsigned int sequential_io; - unsigned int sequential_io_avg; - #endif -+#ifdef CONFIG_PREEMPT_RT_BASE -+ struct rcu_head put_rcu; -+ int softirq_nestcnt; -+ unsigned int softirqs_raised; -+#endif -+#ifdef CONFIG_PREEMPT_RT_FULL -+# if defined CONFIG_HIGHMEM || defined CONFIG_X86_32 -+ int kmap_idx; -+ pte_t kmap_pte[KM_TYPE_NR]; -+# endif -+#endif - #ifdef CONFIG_DEBUG_ATOMIC_SLEEP - unsigned long task_state_change; - #endif -+#ifdef CONFIG_PREEMPT_RT_FULL -+ int xmit_recursion; -+#endif - int pagefault_disabled; - #ifdef CONFIG_MMU - struct task_struct *oom_reaper_list; -@@ -1868,9 +1916,6 @@ extern int arch_task_struct_size __read_mostly; - # define arch_task_struct_size (sizeof(struct task_struct)) - #endif - --/* Future-safe accessor for struct task_struct's cpus_allowed. */ --#define tsk_cpus_allowed(tsk) (&(tsk)->cpus_allowed) -- - #define TNF_MIGRATED 0x01 - #define TNF_NO_GROUP 0x02 - #define TNF_SHARED 0x04 -@@ -2060,6 +2105,15 @@ extern struct pid *cad_pid; - extern void free_task(struct task_struct *tsk); - #define get_task_struct(tsk) do { atomic_inc(&(tsk)->usage); } while(0) - -+#ifdef CONFIG_PREEMPT_RT_BASE -+extern void __put_task_struct_cb(struct rcu_head *rhp); -+ -+static inline void put_task_struct(struct task_struct *t) -+{ -+ if (atomic_dec_and_test(&t->usage)) -+ call_rcu(&t->put_rcu, __put_task_struct_cb); -+} -+#else - extern void __put_task_struct(struct task_struct *t); - - static inline void put_task_struct(struct task_struct *t) -@@ -2067,6 +2121,7 @@ static inline void put_task_struct(struct task_struct *t) - if (atomic_dec_and_test(&t->usage)) - __put_task_struct(t); - } -+#endif - - #ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN - extern void task_cputime(struct task_struct *t, -@@ -2105,6 +2160,7 @@ extern void thread_group_cputime_adjusted(struct task_struct *p, cputime_t *ut, - /* - * Per process flags - */ -+#define PF_IN_SOFTIRQ 0x00000001 /* Task is serving softirq */ - #define PF_EXITING 0x00000004 /* getting shut down */ - #define PF_EXITPIDONE 0x00000008 /* pi exit done on shut down */ - #define PF_VCPU 0x00000010 /* I'm a virtual CPU */ -@@ -2269,6 +2325,10 @@ extern void do_set_cpus_allowed(struct task_struct *p, - - extern int set_cpus_allowed_ptr(struct task_struct *p, - const struct cpumask *new_mask); -+int migrate_me(void); -+void tell_sched_cpu_down_begin(int cpu); -+void tell_sched_cpu_down_done(int cpu); -+ - #else - static inline void do_set_cpus_allowed(struct task_struct *p, - const struct cpumask *new_mask) -@@ -2281,6 +2341,9 @@ static inline int set_cpus_allowed_ptr(struct task_struct *p, - return -EINVAL; - return 0; - } -+static inline int migrate_me(void) { return 0; } -+static inline void tell_sched_cpu_down_begin(int cpu) { } -+static inline void tell_sched_cpu_down_done(int cpu) { } - #endif - - #ifdef CONFIG_NO_HZ_COMMON -@@ -2487,6 +2550,7 @@ extern void xtime_update(unsigned long ticks); - - extern int wake_up_state(struct task_struct *tsk, unsigned int state); - extern int wake_up_process(struct task_struct *tsk); -+extern int wake_up_lock_sleeper(struct task_struct * tsk); - extern void wake_up_new_task(struct task_struct *tsk); - #ifdef CONFIG_SMP - extern void kick_process(struct task_struct *tsk); -@@ -2610,12 +2674,24 @@ extern struct mm_struct * mm_alloc(void); - - /* mmdrop drops the mm and the page tables */ - extern void __mmdrop(struct mm_struct *); -+ - static inline void mmdrop(struct mm_struct * mm) - { - if (unlikely(atomic_dec_and_test(&mm->mm_count))) - __mmdrop(mm); - } - -+#ifdef CONFIG_PREEMPT_RT_BASE -+extern void __mmdrop_delayed(struct rcu_head *rhp); -+static inline void mmdrop_delayed(struct mm_struct *mm) -+{ -+ if (atomic_dec_and_test(&mm->mm_count)) -+ call_rcu(&mm->delayed_drop, __mmdrop_delayed); -+} -+#else -+# define mmdrop_delayed(mm) mmdrop(mm) -+#endif -+ - /* mmput gets rid of the mappings and all user-space */ - extern void mmput(struct mm_struct *); - /* Grab a reference to a task's mm, if it is not already going away */ -@@ -2933,6 +3009,43 @@ static inline int test_tsk_need_resched(struct task_struct *tsk) - return unlikely(test_tsk_thread_flag(tsk,TIF_NEED_RESCHED)); - } - -+#ifdef CONFIG_PREEMPT_LAZY -+static inline void set_tsk_need_resched_lazy(struct task_struct *tsk) -+{ -+ set_tsk_thread_flag(tsk,TIF_NEED_RESCHED_LAZY); -+} -+ -+static inline void clear_tsk_need_resched_lazy(struct task_struct *tsk) -+{ -+ clear_tsk_thread_flag(tsk,TIF_NEED_RESCHED_LAZY); -+} -+ -+static inline int test_tsk_need_resched_lazy(struct task_struct *tsk) -+{ -+ return unlikely(test_tsk_thread_flag(tsk,TIF_NEED_RESCHED_LAZY)); -+} -+ -+static inline int need_resched_lazy(void) -+{ -+ return test_thread_flag(TIF_NEED_RESCHED_LAZY); -+} -+ -+static inline int need_resched_now(void) -+{ -+ return test_thread_flag(TIF_NEED_RESCHED); -+} -+ -+#else -+static inline void clear_tsk_need_resched_lazy(struct task_struct *tsk) { } -+static inline int need_resched_lazy(void) { return 0; } -+ -+static inline int need_resched_now(void) -+{ -+ return test_thread_flag(TIF_NEED_RESCHED); -+} -+ -+#endif -+ - static inline int restart_syscall(void) - { - set_tsk_thread_flag(current, TIF_SIGPENDING); -@@ -2964,6 +3077,51 @@ static inline int signal_pending_state(long state, struct task_struct *p) - return (state & TASK_INTERRUPTIBLE) || __fatal_signal_pending(p); - } - -+static inline bool __task_is_stopped_or_traced(struct task_struct *task) -+{ -+ if (task->state & (__TASK_STOPPED | __TASK_TRACED)) -+ return true; -+#ifdef CONFIG_PREEMPT_RT_FULL -+ if (task->saved_state & (__TASK_STOPPED | __TASK_TRACED)) -+ return true; -+#endif -+ return false; -+} -+ -+static inline bool task_is_stopped_or_traced(struct task_struct *task) -+{ -+ bool traced_stopped; -+ -+#ifdef CONFIG_PREEMPT_RT_FULL -+ unsigned long flags; -+ -+ raw_spin_lock_irqsave(&task->pi_lock, flags); -+ traced_stopped = __task_is_stopped_or_traced(task); -+ raw_spin_unlock_irqrestore(&task->pi_lock, flags); -+#else -+ traced_stopped = __task_is_stopped_or_traced(task); -+#endif -+ return traced_stopped; -+} -+ -+static inline bool task_is_traced(struct task_struct *task) -+{ -+ bool traced = false; -+ -+ if (task->state & __TASK_TRACED) -+ return true; -+#ifdef CONFIG_PREEMPT_RT_FULL -+ /* in case the task is sleeping on tasklist_lock */ -+ raw_spin_lock_irq(&task->pi_lock); -+ if (task->state & __TASK_TRACED) -+ traced = true; -+ else if (task->saved_state & __TASK_TRACED) -+ traced = true; -+ raw_spin_unlock_irq(&task->pi_lock); -+#endif -+ return traced; -+} -+ - /* - * cond_resched() and cond_resched_lock(): latency reduction via - * explicit rescheduling in places that are safe. The return -@@ -2985,12 +3143,16 @@ extern int __cond_resched_lock(spinlock_t *lock); - __cond_resched_lock(lock); \ - }) - -+#ifndef CONFIG_PREEMPT_RT_FULL - extern int __cond_resched_softirq(void); - - #define cond_resched_softirq() ({ \ - ___might_sleep(__FILE__, __LINE__, SOFTIRQ_DISABLE_OFFSET); \ - __cond_resched_softirq(); \ - }) -+#else -+# define cond_resched_softirq() cond_resched() -+#endif - - static inline void cond_resched_rcu(void) - { -@@ -3152,6 +3314,31 @@ static inline void set_task_cpu(struct task_struct *p, unsigned int cpu) - - #endif /* CONFIG_SMP */ - -+static inline int __migrate_disabled(struct task_struct *p) -+{ -+#ifdef CONFIG_PREEMPT_RT_FULL -+ return p->migrate_disable; -+#else -+ return 0; -+#endif -+} -+ -+/* Future-safe accessor for struct task_struct's cpus_allowed. */ -+static inline const struct cpumask *tsk_cpus_allowed(struct task_struct *p) -+{ -+ if (__migrate_disabled(p)) -+ return cpumask_of(task_cpu(p)); -+ -+ return &p->cpus_allowed; -+} -+ -+static inline int tsk_nr_cpus_allowed(struct task_struct *p) -+{ -+ if (__migrate_disabled(p)) -+ return 1; -+ return p->nr_cpus_allowed; -+} -+ - extern long sched_setaffinity(pid_t pid, const struct cpumask *new_mask); - extern long sched_getaffinity(pid_t pid, struct cpumask *mask); - -diff --git a/include/linux/seqlock.h b/include/linux/seqlock.h -index e058210..b14f4d2 100644 ---- a/include/linux/seqlock.h -+++ b/include/linux/seqlock.h -@@ -220,20 +220,30 @@ static inline int read_seqcount_retry(const seqcount_t *s, unsigned start) - return __read_seqcount_retry(s, start); - } - -- -- --static inline void raw_write_seqcount_begin(seqcount_t *s) -+static inline void __raw_write_seqcount_begin(seqcount_t *s) - { - s->sequence++; - smp_wmb(); - } - --static inline void raw_write_seqcount_end(seqcount_t *s) -+static inline void raw_write_seqcount_begin(seqcount_t *s) -+{ -+ preempt_disable_rt(); -+ __raw_write_seqcount_begin(s); -+} -+ -+static inline void __raw_write_seqcount_end(seqcount_t *s) - { - smp_wmb(); - s->sequence++; - } - -+static inline void raw_write_seqcount_end(seqcount_t *s) -+{ -+ __raw_write_seqcount_end(s); -+ preempt_enable_rt(); -+} -+ - /** - * raw_write_seqcount_barrier - do a seq write barrier - * @s: pointer to seqcount_t -@@ -425,10 +435,32 @@ typedef struct { - /* - * Read side functions for starting and finalizing a read side section. - */ -+#ifndef CONFIG_PREEMPT_RT_FULL - static inline unsigned read_seqbegin(const seqlock_t *sl) - { - return read_seqcount_begin(&sl->seqcount); - } -+#else -+/* -+ * Starvation safe read side for RT -+ */ -+static inline unsigned read_seqbegin(seqlock_t *sl) -+{ -+ unsigned ret; -+ -+repeat: -+ ret = ACCESS_ONCE(sl->seqcount.sequence); -+ if (unlikely(ret & 1)) { -+ /* -+ * Take the lock and let the writer proceed (i.e. evtl -+ * boost it), otherwise we could loop here forever. -+ */ -+ spin_unlock_wait(&sl->lock); -+ goto repeat; -+ } -+ return ret; -+} -+#endif - - static inline unsigned read_seqretry(const seqlock_t *sl, unsigned start) - { -@@ -443,36 +475,36 @@ static inline unsigned read_seqretry(const seqlock_t *sl, unsigned start) - static inline void write_seqlock(seqlock_t *sl) - { - spin_lock(&sl->lock); -- write_seqcount_begin(&sl->seqcount); -+ __raw_write_seqcount_begin(&sl->seqcount); - } - - static inline void write_sequnlock(seqlock_t *sl) - { -- write_seqcount_end(&sl->seqcount); -+ __raw_write_seqcount_end(&sl->seqcount); - spin_unlock(&sl->lock); - } - - static inline void write_seqlock_bh(seqlock_t *sl) - { - spin_lock_bh(&sl->lock); -- write_seqcount_begin(&sl->seqcount); -+ __raw_write_seqcount_begin(&sl->seqcount); - } - - static inline void write_sequnlock_bh(seqlock_t *sl) - { -- write_seqcount_end(&sl->seqcount); -+ __raw_write_seqcount_end(&sl->seqcount); - spin_unlock_bh(&sl->lock); - } - - static inline void write_seqlock_irq(seqlock_t *sl) - { - spin_lock_irq(&sl->lock); -- write_seqcount_begin(&sl->seqcount); -+ __raw_write_seqcount_begin(&sl->seqcount); - } - - static inline void write_sequnlock_irq(seqlock_t *sl) - { -- write_seqcount_end(&sl->seqcount); -+ __raw_write_seqcount_end(&sl->seqcount); - spin_unlock_irq(&sl->lock); - } - -@@ -481,7 +513,7 @@ static inline unsigned long __write_seqlock_irqsave(seqlock_t *sl) - unsigned long flags; - - spin_lock_irqsave(&sl->lock, flags); -- write_seqcount_begin(&sl->seqcount); -+ __raw_write_seqcount_begin(&sl->seqcount); - return flags; - } - -@@ -491,7 +523,7 @@ static inline unsigned long __write_seqlock_irqsave(seqlock_t *sl) - static inline void - write_sequnlock_irqrestore(seqlock_t *sl, unsigned long flags) - { -- write_seqcount_end(&sl->seqcount); -+ __raw_write_seqcount_end(&sl->seqcount); - spin_unlock_irqrestore(&sl->lock, flags); - } - -diff --git a/include/linux/signal.h b/include/linux/signal.h -index 92557bb..561a128 100644 ---- a/include/linux/signal.h -+++ b/include/linux/signal.h -@@ -218,6 +218,7 @@ static inline void init_sigpending(struct sigpending *sig) - } - - extern void flush_sigqueue(struct sigpending *queue); -+extern void flush_task_sigqueue(struct task_struct *tsk); - - /* Test if 'sig' is valid signal. Use this instead of testing _NSIG directly */ - static inline int valid_signal(unsigned long sig) -diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h -index 15d0df9..2cb9633 100644 ---- a/include/linux/skbuff.h -+++ b/include/linux/skbuff.h -@@ -283,6 +283,7 @@ struct sk_buff_head { - - __u32 qlen; - spinlock_t lock; -+ raw_spinlock_t raw_lock; - }; - - struct sk_buff; -@@ -1537,6 +1538,12 @@ static inline void skb_queue_head_init(struct sk_buff_head *list) - __skb_queue_head_init(list); - } - -+static inline void skb_queue_head_init_raw(struct sk_buff_head *list) -+{ -+ raw_spin_lock_init(&list->raw_lock); -+ __skb_queue_head_init(list); -+} -+ - static inline void skb_queue_head_init_class(struct sk_buff_head *list, - struct lock_class_key *class) - { -diff --git a/include/linux/smp.h b/include/linux/smp.h -index c441407..e6ab36a 100644 ---- a/include/linux/smp.h -+++ b/include/linux/smp.h -@@ -185,6 +185,9 @@ static inline void smp_init(void) { } - #define get_cpu() ({ preempt_disable(); smp_processor_id(); }) - #define put_cpu() preempt_enable() - -+#define get_cpu_light() ({ migrate_disable(); smp_processor_id(); }) -+#define put_cpu_light() migrate_enable() -+ - /* - * Callback to arch code if there's nosmp or maxcpus=0 on the - * boot command line: -diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h -index 47dd0ce..b241cc0 100644 ---- a/include/linux/spinlock.h -+++ b/include/linux/spinlock.h -@@ -271,7 +271,11 @@ static inline void do_raw_spin_unlock(raw_spinlock_t *lock) __releases(lock) - #define raw_spin_can_lock(lock) (!raw_spin_is_locked(lock)) - - /* Include rwlock functions */ --#include <linux/rwlock.h> -+#ifdef CONFIG_PREEMPT_RT_FULL -+# include <linux/rwlock_rt.h> -+#else -+# include <linux/rwlock.h> -+#endif - - /* - * Pull the _spin_*()/_read_*()/_write_*() functions/declarations: -@@ -282,6 +286,10 @@ static inline void do_raw_spin_unlock(raw_spinlock_t *lock) __releases(lock) - # include <linux/spinlock_api_up.h> - #endif - -+#ifdef CONFIG_PREEMPT_RT_FULL -+# include <linux/spinlock_rt.h> -+#else /* PREEMPT_RT_FULL */ -+ - /* - * Map the spin_lock functions to the raw variants for PREEMPT_RT=n - */ -@@ -416,4 +424,6 @@ extern int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock); - #define atomic_dec_and_lock(atomic, lock) \ - __cond_lock(lock, _atomic_dec_and_lock(atomic, lock)) - -+#endif /* !PREEMPT_RT_FULL */ -+ - #endif /* __LINUX_SPINLOCK_H */ -diff --git a/include/linux/spinlock_api_smp.h b/include/linux/spinlock_api_smp.h -index 5344268..043263f 100644 ---- a/include/linux/spinlock_api_smp.h -+++ b/include/linux/spinlock_api_smp.h -@@ -189,6 +189,8 @@ static inline int __raw_spin_trylock_bh(raw_spinlock_t *lock) - return 0; - } - --#include <linux/rwlock_api_smp.h> -+#ifndef CONFIG_PREEMPT_RT_FULL -+# include <linux/rwlock_api_smp.h> -+#endif - - #endif /* __LINUX_SPINLOCK_API_SMP_H */ -diff --git a/include/linux/spinlock_rt.h b/include/linux/spinlock_rt.h -new file mode 100644 -index 0000000..3b28255 ---- /dev/null -+++ b/include/linux/spinlock_rt.h -@@ -0,0 +1,163 @@ -+#ifndef __LINUX_SPINLOCK_RT_H -+#define __LINUX_SPINLOCK_RT_H -+ -+#ifndef __LINUX_SPINLOCK_H -+#error Do not include directly. Use spinlock.h -+#endif -+ -+#include <linux/bug.h> -+ -+extern void -+__rt_spin_lock_init(spinlock_t *lock, char *name, struct lock_class_key *key); -+ -+#define spin_lock_init(slock) \ -+do { \ -+ static struct lock_class_key __key; \ -+ \ -+ rt_mutex_init(&(slock)->lock); \ -+ __rt_spin_lock_init(slock, #slock, &__key); \ -+} while (0) -+ -+void __lockfunc rt_spin_lock__no_mg(spinlock_t *lock); -+void __lockfunc rt_spin_unlock__no_mg(spinlock_t *lock); -+int __lockfunc rt_spin_trylock__no_mg(spinlock_t *lock); -+ -+extern void __lockfunc rt_spin_lock(spinlock_t *lock); -+extern unsigned long __lockfunc rt_spin_lock_trace_flags(spinlock_t *lock); -+extern void __lockfunc rt_spin_lock_nested(spinlock_t *lock, int subclass); -+extern void __lockfunc rt_spin_unlock(spinlock_t *lock); -+extern void __lockfunc rt_spin_unlock_wait(spinlock_t *lock); -+extern int __lockfunc rt_spin_trylock_irqsave(spinlock_t *lock, unsigned long *flags); -+extern int __lockfunc rt_spin_trylock_bh(spinlock_t *lock); -+extern int __lockfunc rt_spin_trylock(spinlock_t *lock); -+extern int atomic_dec_and_spin_lock(atomic_t *atomic, spinlock_t *lock); -+ -+/* -+ * lockdep-less calls, for derived types like rwlock: -+ * (for trylock they can use rt_mutex_trylock() directly. -+ */ -+extern void __lockfunc __rt_spin_lock__no_mg(struct rt_mutex *lock); -+extern void __lockfunc __rt_spin_lock(struct rt_mutex *lock); -+extern void __lockfunc __rt_spin_unlock(struct rt_mutex *lock); -+extern int __lockfunc __rt_spin_trylock(struct rt_mutex *lock); -+ -+#define spin_lock(lock) rt_spin_lock(lock) -+ -+#define spin_lock_bh(lock) \ -+ do { \ -+ local_bh_disable(); \ -+ rt_spin_lock(lock); \ -+ } while (0) -+ -+#define spin_lock_irq(lock) spin_lock(lock) -+ -+#define spin_do_trylock(lock) __cond_lock(lock, rt_spin_trylock(lock)) -+ -+#define spin_trylock(lock) \ -+({ \ -+ int __locked; \ -+ __locked = spin_do_trylock(lock); \ -+ __locked; \ -+}) -+ -+#ifdef CONFIG_LOCKDEP -+# define spin_lock_nested(lock, subclass) \ -+ do { \ -+ rt_spin_lock_nested(lock, subclass); \ -+ } while (0) -+ -+#define spin_lock_bh_nested(lock, subclass) \ -+ do { \ -+ local_bh_disable(); \ -+ rt_spin_lock_nested(lock, subclass); \ -+ } while (0) -+ -+# define spin_lock_irqsave_nested(lock, flags, subclass) \ -+ do { \ -+ typecheck(unsigned long, flags); \ -+ flags = 0; \ -+ rt_spin_lock_nested(lock, subclass); \ -+ } while (0) -+#else -+# define spin_lock_nested(lock, subclass) spin_lock(lock) -+# define spin_lock_bh_nested(lock, subclass) spin_lock_bh(lock) -+ -+# define spin_lock_irqsave_nested(lock, flags, subclass) \ -+ do { \ -+ typecheck(unsigned long, flags); \ -+ flags = 0; \ -+ spin_lock(lock); \ -+ } while (0) -+#endif -+ -+#define spin_lock_irqsave(lock, flags) \ -+ do { \ -+ typecheck(unsigned long, flags); \ -+ flags = 0; \ -+ spin_lock(lock); \ -+ } while (0) -+ -+static inline unsigned long spin_lock_trace_flags(spinlock_t *lock) -+{ -+ unsigned long flags = 0; -+#ifdef CONFIG_TRACE_IRQFLAGS -+ flags = rt_spin_lock_trace_flags(lock); -+#else -+ spin_lock(lock); /* lock_local */ -+#endif -+ return flags; -+} -+ -+/* FIXME: we need rt_spin_lock_nest_lock */ -+#define spin_lock_nest_lock(lock, nest_lock) spin_lock_nested(lock, 0) -+ -+#define spin_unlock(lock) rt_spin_unlock(lock) -+ -+#define spin_unlock_bh(lock) \ -+ do { \ -+ rt_spin_unlock(lock); \ -+ local_bh_enable(); \ -+ } while (0) -+ -+#define spin_unlock_irq(lock) spin_unlock(lock) -+ -+#define spin_unlock_irqrestore(lock, flags) \ -+ do { \ -+ typecheck(unsigned long, flags); \ -+ (void) flags; \ -+ spin_unlock(lock); \ -+ } while (0) -+ -+#define spin_trylock_bh(lock) __cond_lock(lock, rt_spin_trylock_bh(lock)) -+#define spin_trylock_irq(lock) spin_trylock(lock) -+ -+#define spin_trylock_irqsave(lock, flags) \ -+ rt_spin_trylock_irqsave(lock, &(flags)) -+ -+#define spin_unlock_wait(lock) rt_spin_unlock_wait(lock) -+ -+#ifdef CONFIG_GENERIC_LOCKBREAK -+# define spin_is_contended(lock) ((lock)->break_lock) -+#else -+# define spin_is_contended(lock) (((void)(lock), 0)) -+#endif -+ -+static inline int spin_can_lock(spinlock_t *lock) -+{ -+ return !rt_mutex_is_locked(&lock->lock); -+} -+ -+static inline int spin_is_locked(spinlock_t *lock) -+{ -+ return rt_mutex_is_locked(&lock->lock); -+} -+ -+static inline void assert_spin_locked(spinlock_t *lock) -+{ -+ BUG_ON(!spin_is_locked(lock)); -+} -+ -+#define atomic_dec_and_lock(atomic, lock) \ -+ atomic_dec_and_spin_lock(atomic, lock) -+ -+#endif -diff --git a/include/linux/spinlock_types.h b/include/linux/spinlock_types.h -index 73548eb..10bac71 100644 ---- a/include/linux/spinlock_types.h -+++ b/include/linux/spinlock_types.h -@@ -9,80 +9,15 @@ - * Released under the General Public License (GPL). - */ - --#if defined(CONFIG_SMP) --# include <asm/spinlock_types.h> --#else --# include <linux/spinlock_types_up.h> --#endif -- --#include <linux/lockdep.h> -- --typedef struct raw_spinlock { -- arch_spinlock_t raw_lock; --#ifdef CONFIG_GENERIC_LOCKBREAK -- unsigned int break_lock; --#endif --#ifdef CONFIG_DEBUG_SPINLOCK -- unsigned int magic, owner_cpu; -- void *owner; --#endif --#ifdef CONFIG_DEBUG_LOCK_ALLOC -- struct lockdep_map dep_map; --#endif --} raw_spinlock_t; -- --#define SPINLOCK_MAGIC 0xdead4ead -- --#define SPINLOCK_OWNER_INIT ((void *)-1L) -- --#ifdef CONFIG_DEBUG_LOCK_ALLOC --# define SPIN_DEP_MAP_INIT(lockname) .dep_map = { .name = #lockname } --#else --# define SPIN_DEP_MAP_INIT(lockname) --#endif -+#include <linux/spinlock_types_raw.h> - --#ifdef CONFIG_DEBUG_SPINLOCK --# define SPIN_DEBUG_INIT(lockname) \ -- .magic = SPINLOCK_MAGIC, \ -- .owner_cpu = -1, \ -- .owner = SPINLOCK_OWNER_INIT, -+#ifndef CONFIG_PREEMPT_RT_FULL -+# include <linux/spinlock_types_nort.h> -+# include <linux/rwlock_types.h> - #else --# define SPIN_DEBUG_INIT(lockname) -+# include <linux/rtmutex.h> -+# include <linux/spinlock_types_rt.h> -+# include <linux/rwlock_types_rt.h> - #endif - --#define __RAW_SPIN_LOCK_INITIALIZER(lockname) \ -- { \ -- .raw_lock = __ARCH_SPIN_LOCK_UNLOCKED, \ -- SPIN_DEBUG_INIT(lockname) \ -- SPIN_DEP_MAP_INIT(lockname) } -- --#define __RAW_SPIN_LOCK_UNLOCKED(lockname) \ -- (raw_spinlock_t) __RAW_SPIN_LOCK_INITIALIZER(lockname) -- --#define DEFINE_RAW_SPINLOCK(x) raw_spinlock_t x = __RAW_SPIN_LOCK_UNLOCKED(x) -- --typedef struct spinlock { -- union { -- struct raw_spinlock rlock; -- --#ifdef CONFIG_DEBUG_LOCK_ALLOC --# define LOCK_PADSIZE (offsetof(struct raw_spinlock, dep_map)) -- struct { -- u8 __padding[LOCK_PADSIZE]; -- struct lockdep_map dep_map; -- }; --#endif -- }; --} spinlock_t; -- --#define __SPIN_LOCK_INITIALIZER(lockname) \ -- { { .rlock = __RAW_SPIN_LOCK_INITIALIZER(lockname) } } -- --#define __SPIN_LOCK_UNLOCKED(lockname) \ -- (spinlock_t ) __SPIN_LOCK_INITIALIZER(lockname) -- --#define DEFINE_SPINLOCK(x) spinlock_t x = __SPIN_LOCK_UNLOCKED(x) -- --#include <linux/rwlock_types.h> -- - #endif /* __LINUX_SPINLOCK_TYPES_H */ -diff --git a/include/linux/spinlock_types_nort.h b/include/linux/spinlock_types_nort.h -new file mode 100644 -index 0000000..f1dac1f ---- /dev/null -+++ b/include/linux/spinlock_types_nort.h -@@ -0,0 +1,33 @@ -+#ifndef __LINUX_SPINLOCK_TYPES_NORT_H -+#define __LINUX_SPINLOCK_TYPES_NORT_H -+ -+#ifndef __LINUX_SPINLOCK_TYPES_H -+#error "Do not include directly. Include spinlock_types.h instead" -+#endif -+ -+/* -+ * The non RT version maps spinlocks to raw_spinlocks -+ */ -+typedef struct spinlock { -+ union { -+ struct raw_spinlock rlock; -+ -+#ifdef CONFIG_DEBUG_LOCK_ALLOC -+# define LOCK_PADSIZE (offsetof(struct raw_spinlock, dep_map)) -+ struct { -+ u8 __padding[LOCK_PADSIZE]; -+ struct lockdep_map dep_map; -+ }; -+#endif -+ }; -+} spinlock_t; -+ -+#define __SPIN_LOCK_INITIALIZER(lockname) \ -+ { { .rlock = __RAW_SPIN_LOCK_INITIALIZER(lockname) } } -+ -+#define __SPIN_LOCK_UNLOCKED(lockname) \ -+ (spinlock_t ) __SPIN_LOCK_INITIALIZER(lockname) -+ -+#define DEFINE_SPINLOCK(x) spinlock_t x = __SPIN_LOCK_UNLOCKED(x) -+ -+#endif -diff --git a/include/linux/spinlock_types_raw.h b/include/linux/spinlock_types_raw.h -new file mode 100644 -index 0000000..edffc4d ---- /dev/null -+++ b/include/linux/spinlock_types_raw.h -@@ -0,0 +1,56 @@ -+#ifndef __LINUX_SPINLOCK_TYPES_RAW_H -+#define __LINUX_SPINLOCK_TYPES_RAW_H -+ -+#if defined(CONFIG_SMP) -+# include <asm/spinlock_types.h> -+#else -+# include <linux/spinlock_types_up.h> -+#endif -+ -+#include <linux/lockdep.h> -+ -+typedef struct raw_spinlock { -+ arch_spinlock_t raw_lock; -+#ifdef CONFIG_GENERIC_LOCKBREAK -+ unsigned int break_lock; -+#endif -+#ifdef CONFIG_DEBUG_SPINLOCK -+ unsigned int magic, owner_cpu; -+ void *owner; -+#endif -+#ifdef CONFIG_DEBUG_LOCK_ALLOC -+ struct lockdep_map dep_map; -+#endif -+} raw_spinlock_t; -+ -+#define SPINLOCK_MAGIC 0xdead4ead -+ -+#define SPINLOCK_OWNER_INIT ((void *)-1L) -+ -+#ifdef CONFIG_DEBUG_LOCK_ALLOC -+# define SPIN_DEP_MAP_INIT(lockname) .dep_map = { .name = #lockname } -+#else -+# define SPIN_DEP_MAP_INIT(lockname) -+#endif -+ -+#ifdef CONFIG_DEBUG_SPINLOCK -+# define SPIN_DEBUG_INIT(lockname) \ -+ .magic = SPINLOCK_MAGIC, \ -+ .owner_cpu = -1, \ -+ .owner = SPINLOCK_OWNER_INIT, -+#else -+# define SPIN_DEBUG_INIT(lockname) -+#endif -+ -+#define __RAW_SPIN_LOCK_INITIALIZER(lockname) \ -+ { \ -+ .raw_lock = __ARCH_SPIN_LOCK_UNLOCKED, \ -+ SPIN_DEBUG_INIT(lockname) \ -+ SPIN_DEP_MAP_INIT(lockname) } -+ -+#define __RAW_SPIN_LOCK_UNLOCKED(lockname) \ -+ (raw_spinlock_t) __RAW_SPIN_LOCK_INITIALIZER(lockname) -+ -+#define DEFINE_RAW_SPINLOCK(x) raw_spinlock_t x = __RAW_SPIN_LOCK_UNLOCKED(x) -+ -+#endif -diff --git a/include/linux/spinlock_types_rt.h b/include/linux/spinlock_types_rt.h -new file mode 100644 -index 0000000..3e3d8c5 ---- /dev/null -+++ b/include/linux/spinlock_types_rt.h -@@ -0,0 +1,48 @@ -+#ifndef __LINUX_SPINLOCK_TYPES_RT_H -+#define __LINUX_SPINLOCK_TYPES_RT_H -+ -+#ifndef __LINUX_SPINLOCK_TYPES_H -+#error "Do not include directly. Include spinlock_types.h instead" -+#endif -+ -+#include <linux/cache.h> -+ -+/* -+ * PREEMPT_RT: spinlocks - an RT mutex plus lock-break field: -+ */ -+typedef struct spinlock { -+ struct rt_mutex lock; -+ unsigned int break_lock; -+#ifdef CONFIG_DEBUG_LOCK_ALLOC -+ struct lockdep_map dep_map; -+#endif -+} spinlock_t; -+ -+#ifdef CONFIG_DEBUG_RT_MUTEXES -+# define __RT_SPIN_INITIALIZER(name) \ -+ { \ -+ .wait_lock = __RAW_SPIN_LOCK_UNLOCKED(name.wait_lock), \ -+ .save_state = 1, \ -+ .file = __FILE__, \ -+ .line = __LINE__ , \ -+ } -+#else -+# define __RT_SPIN_INITIALIZER(name) \ -+ { \ -+ .wait_lock = __RAW_SPIN_LOCK_UNLOCKED(name.wait_lock), \ -+ .save_state = 1, \ -+ } -+#endif -+ -+/* -+.wait_list = PLIST_HEAD_INIT_RAW((name).lock.wait_list, (name).lock.wait_lock) -+*/ -+ -+#define __SPIN_LOCK_UNLOCKED(name) \ -+ { .lock = __RT_SPIN_INITIALIZER(name.lock), \ -+ SPIN_DEP_MAP_INIT(name) } -+ -+#define DEFINE_SPINLOCK(name) \ -+ spinlock_t name = __SPIN_LOCK_UNLOCKED(name) -+ -+#endif -diff --git a/include/linux/srcu.h b/include/linux/srcu.h -index dc8eb63..e793d3a 100644 ---- a/include/linux/srcu.h -+++ b/include/linux/srcu.h -@@ -84,10 +84,10 @@ int init_srcu_struct(struct srcu_struct *sp); - - void process_srcu(struct work_struct *work); - --#define __SRCU_STRUCT_INIT(name) \ -+#define __SRCU_STRUCT_INIT(name, pcpu_name) \ - { \ - .completed = -300, \ -- .per_cpu_ref = &name##_srcu_array, \ -+ .per_cpu_ref = &pcpu_name, \ - .queue_lock = __SPIN_LOCK_UNLOCKED(name.queue_lock), \ - .running = false, \ - .batch_queue = RCU_BATCH_INIT(name.batch_queue), \ -@@ -119,7 +119,7 @@ void process_srcu(struct work_struct *work); - */ - #define __DEFINE_SRCU(name, is_static) \ - static DEFINE_PER_CPU(struct srcu_struct_array, name##_srcu_array);\ -- is_static struct srcu_struct name = __SRCU_STRUCT_INIT(name) -+ is_static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name##_srcu_array) - #define DEFINE_SRCU(name) __DEFINE_SRCU(name, /* not static */) - #define DEFINE_STATIC_SRCU(name) __DEFINE_SRCU(name, static) - -diff --git a/include/linux/suspend.h b/include/linux/suspend.h -index 8b6ec7e..9b77d4c 100644 ---- a/include/linux/suspend.h -+++ b/include/linux/suspend.h -@@ -194,6 +194,12 @@ struct platform_freeze_ops { - void (*end)(void); - }; - -+#if defined(CONFIG_SUSPEND) || defined(CONFIG_HIBERNATION) -+extern bool pm_in_action; -+#else -+# define pm_in_action false -+#endif -+ - #ifdef CONFIG_SUSPEND - /** - * suspend_set_ops - set platform dependent suspend operations -diff --git a/include/linux/swait.h b/include/linux/swait.h -index c1f9c62..83f004a 100644 ---- a/include/linux/swait.h -+++ b/include/linux/swait.h -@@ -87,6 +87,7 @@ static inline int swait_active(struct swait_queue_head *q) - extern void swake_up(struct swait_queue_head *q); - extern void swake_up_all(struct swait_queue_head *q); - extern void swake_up_locked(struct swait_queue_head *q); -+extern void swake_up_all_locked(struct swait_queue_head *q); - - extern void __prepare_to_swait(struct swait_queue_head *q, struct swait_queue *wait); - extern void prepare_to_swait(struct swait_queue_head *q, struct swait_queue *wait, int state); -diff --git a/include/linux/swap.h b/include/linux/swap.h -index ad22035..2b77219 100644 ---- a/include/linux/swap.h -+++ b/include/linux/swap.h -@@ -11,6 +11,7 @@ - #include <linux/fs.h> - #include <linux/atomic.h> - #include <linux/page-flags.h> -+#include <linux/locallock.h> - #include <asm/page.h> - - struct notifier_block; -@@ -252,7 +253,8 @@ struct swap_info_struct { - void *workingset_eviction(struct address_space *mapping, struct page *page); - bool workingset_refault(void *shadow); - void workingset_activation(struct page *page); --extern struct list_lru workingset_shadow_nodes; -+extern struct list_lru __workingset_shadow_nodes; -+DECLARE_LOCAL_IRQ_LOCK(workingset_shadow_lock); - - static inline unsigned int workingset_node_pages(struct radix_tree_node *node) - { -@@ -295,6 +297,7 @@ extern unsigned long nr_free_pagecache_pages(void); - - - /* linux/mm/swap.c */ -+DECLARE_LOCAL_IRQ_LOCK(swapvec_lock); - extern void lru_cache_add(struct page *); - extern void lru_cache_add_anon(struct page *page); - extern void lru_cache_add_file(struct page *page); -diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h -index b4c2a48..5580c2c 100644 ---- a/include/linux/thread_info.h -+++ b/include/linux/thread_info.h -@@ -103,7 +103,17 @@ static inline int test_ti_thread_flag(struct thread_info *ti, int flag) - #define test_thread_flag(flag) \ - test_ti_thread_flag(current_thread_info(), flag) - --#define tif_need_resched() test_thread_flag(TIF_NEED_RESCHED) -+#ifdef CONFIG_PREEMPT_LAZY -+#define tif_need_resched() (test_thread_flag(TIF_NEED_RESCHED) || \ -+ test_thread_flag(TIF_NEED_RESCHED_LAZY)) -+#define tif_need_resched_now() (test_thread_flag(TIF_NEED_RESCHED)) -+#define tif_need_resched_lazy() test_thread_flag(TIF_NEED_RESCHED_LAZY)) -+ -+#else -+#define tif_need_resched() test_thread_flag(TIF_NEED_RESCHED) -+#define tif_need_resched_now() test_thread_flag(TIF_NEED_RESCHED) -+#define tif_need_resched_lazy() 0 -+#endif - - #if defined TIF_RESTORE_SIGMASK && !defined HAVE_SET_RESTORE_SIGMASK - /* -diff --git a/include/linux/timer.h b/include/linux/timer.h -index 61aa61d..299d2b7 100644 ---- a/include/linux/timer.h -+++ b/include/linux/timer.h -@@ -225,7 +225,7 @@ extern void add_timer(struct timer_list *timer); - - extern int try_to_del_timer_sync(struct timer_list *timer); - --#ifdef CONFIG_SMP -+#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT_RT_FULL) - extern int del_timer_sync(struct timer_list *timer); - #else - # define del_timer_sync(t) del_timer(t) -diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h -index 0810f81b..682bfdf 100644 ---- a/include/linux/trace_events.h -+++ b/include/linux/trace_events.h -@@ -56,6 +56,9 @@ struct trace_entry { - unsigned char flags; - unsigned char preempt_count; - int pid; -+ unsigned short migrate_disable; -+ unsigned short padding; -+ unsigned char preempt_lazy_count; - }; - - #define TRACE_EVENT_TYPE_MAX \ -diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h -index 3495578..1d65e4f 100644 ---- a/include/linux/uaccess.h -+++ b/include/linux/uaccess.h -@@ -24,6 +24,7 @@ static __always_inline void pagefault_disabled_dec(void) - */ - static inline void pagefault_disable(void) - { -+ migrate_disable(); - pagefault_disabled_inc(); - /* - * make sure to have issued the store before a pagefault -@@ -40,6 +41,7 @@ static inline void pagefault_enable(void) - */ - barrier(); - pagefault_disabled_dec(); -+ migrate_enable(); - } - - /* -diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h -index 4a29c75..0a294e9 100644 ---- a/include/linux/uprobes.h -+++ b/include/linux/uprobes.h -@@ -27,6 +27,7 @@ - #include <linux/errno.h> - #include <linux/rbtree.h> - #include <linux/types.h> -+#include <linux/wait.h> - - struct vm_area_struct; - struct mm_struct; -diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h -index 73fae8c..de8a124 100644 ---- a/include/linux/vmstat.h -+++ b/include/linux/vmstat.h -@@ -33,7 +33,9 @@ DECLARE_PER_CPU(struct vm_event_state, vm_event_states); - */ - static inline void __count_vm_event(enum vm_event_item item) - { -+ preempt_disable_rt(); - raw_cpu_inc(vm_event_states.event[item]); -+ preempt_enable_rt(); - } - - static inline void count_vm_event(enum vm_event_item item) -@@ -43,7 +45,9 @@ static inline void count_vm_event(enum vm_event_item item) - - static inline void __count_vm_events(enum vm_event_item item, long delta) - { -+ preempt_disable_rt(); - raw_cpu_add(vm_event_states.event[item], delta); -+ preempt_enable_rt(); - } - - static inline void count_vm_events(enum vm_event_item item, long delta) -diff --git a/include/linux/wait.h b/include/linux/wait.h -index 27d7a0a..7b3542d 100644 ---- a/include/linux/wait.h -+++ b/include/linux/wait.h -@@ -8,6 +8,7 @@ - #include <linux/spinlock.h> - #include <asm/current.h> - #include <uapi/linux/wait.h> -+#include <linux/atomic.h> - - typedef struct __wait_queue wait_queue_t; - typedef int (*wait_queue_func_t)(wait_queue_t *wait, unsigned mode, int flags, void *key); -diff --git a/include/linux/work-simple.h b/include/linux/work-simple.h -new file mode 100644 -index 0000000..f175fa9 ---- /dev/null -+++ b/include/linux/work-simple.h -@@ -0,0 +1,24 @@ -+#ifndef _LINUX_SWORK_H -+#define _LINUX_SWORK_H -+ -+#include <linux/list.h> -+ -+struct swork_event { -+ struct list_head item; -+ unsigned long flags; -+ void (*func)(struct swork_event *); -+}; -+ -+static inline void INIT_SWORK(struct swork_event *event, -+ void (*func)(struct swork_event *)) -+{ -+ event->flags = 0; -+ event->func = func; -+} -+ -+bool swork_queue(struct swork_event *sev); -+ -+int swork_get(void); -+void swork_put(void); -+ -+#endif /* _LINUX_SWORK_H */ -diff --git a/include/net/dst.h b/include/net/dst.h -index 5c98443..22b81c7 100644 ---- a/include/net/dst.h -+++ b/include/net/dst.h -@@ -449,7 +449,7 @@ static inline void dst_confirm(struct dst_entry *dst) - static inline int dst_neigh_output(struct dst_entry *dst, struct neighbour *n, - struct sk_buff *skb) - { -- const struct hh_cache *hh; -+ struct hh_cache *hh; - - if (dst->pending_confirm) { - unsigned long now = jiffies; -diff --git a/include/net/neighbour.h b/include/net/neighbour.h -index 8b68384..bf65600 100644 ---- a/include/net/neighbour.h -+++ b/include/net/neighbour.h -@@ -446,7 +446,7 @@ static inline int neigh_hh_bridge(struct hh_cache *hh, struct sk_buff *skb) - } - #endif - --static inline int neigh_hh_output(const struct hh_cache *hh, struct sk_buff *skb) -+static inline int neigh_hh_output(struct hh_cache *hh, struct sk_buff *skb) - { - unsigned int seq; - int hh_len; -@@ -501,7 +501,7 @@ struct neighbour_cb { - - #define NEIGH_CB(skb) ((struct neighbour_cb *)(skb)->cb) - --static inline void neigh_ha_snapshot(char *dst, const struct neighbour *n, -+static inline void neigh_ha_snapshot(char *dst, struct neighbour *n, - const struct net_device *dev) - { - unsigned int seq; -diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h -index a69cde3..bee40aa 100644 ---- a/include/net/netns/ipv4.h -+++ b/include/net/netns/ipv4.h -@@ -70,6 +70,7 @@ struct netns_ipv4 { - - int sysctl_icmp_echo_ignore_all; - int sysctl_icmp_echo_ignore_broadcasts; -+ int sysctl_icmp_echo_sysrq; - int sysctl_icmp_ignore_bogus_error_responses; - int sysctl_icmp_ratelimit; - int sysctl_icmp_ratemask; -diff --git a/include/trace/events/hist.h b/include/trace/events/hist.h -new file mode 100644 -index 0000000..f7710de ---- /dev/null -+++ b/include/trace/events/hist.h -@@ -0,0 +1,73 @@ -+#undef TRACE_SYSTEM -+#define TRACE_SYSTEM hist -+ -+#if !defined(_TRACE_HIST_H) || defined(TRACE_HEADER_MULTI_READ) -+#define _TRACE_HIST_H -+ -+#include "latency_hist.h" -+#include <linux/tracepoint.h> -+ -+#if !defined(CONFIG_PREEMPT_OFF_HIST) && !defined(CONFIG_INTERRUPT_OFF_HIST) -+#define trace_preemptirqsoff_hist(a, b) -+#define trace_preemptirqsoff_hist_rcuidle(a, b) -+#else -+TRACE_EVENT(preemptirqsoff_hist, -+ -+ TP_PROTO(int reason, int starthist), -+ -+ TP_ARGS(reason, starthist), -+ -+ TP_STRUCT__entry( -+ __field(int, reason) -+ __field(int, starthist) -+ ), -+ -+ TP_fast_assign( -+ __entry->reason = reason; -+ __entry->starthist = starthist; -+ ), -+ -+ TP_printk("reason=%s starthist=%s", getaction(__entry->reason), -+ __entry->starthist ? "start" : "stop") -+); -+#endif -+ -+#ifndef CONFIG_MISSED_TIMER_OFFSETS_HIST -+#define trace_hrtimer_interrupt(a, b, c, d) -+#else -+TRACE_EVENT(hrtimer_interrupt, -+ -+ TP_PROTO(int cpu, long long offset, struct task_struct *curr, -+ struct task_struct *task), -+ -+ TP_ARGS(cpu, offset, curr, task), -+ -+ TP_STRUCT__entry( -+ __field(int, cpu) -+ __field(long long, offset) -+ __array(char, ccomm, TASK_COMM_LEN) -+ __field(int, cprio) -+ __array(char, tcomm, TASK_COMM_LEN) -+ __field(int, tprio) -+ ), -+ -+ TP_fast_assign( -+ __entry->cpu = cpu; -+ __entry->offset = offset; -+ memcpy(__entry->ccomm, curr->comm, TASK_COMM_LEN); -+ __entry->cprio = curr->prio; -+ memcpy(__entry->tcomm, task != NULL ? task->comm : "<none>", -+ task != NULL ? TASK_COMM_LEN : 7); -+ __entry->tprio = task != NULL ? task->prio : -1; -+ ), -+ -+ TP_printk("cpu=%d offset=%lld curr=%s[%d] thread=%s[%d]", -+ __entry->cpu, __entry->offset, __entry->ccomm, -+ __entry->cprio, __entry->tcomm, __entry->tprio) -+); -+#endif -+ -+#endif /* _TRACE_HIST_H */ -+ -+/* This part must be outside protection */ -+#include <trace/define_trace.h> -diff --git a/include/trace/events/latency_hist.h b/include/trace/events/latency_hist.h -new file mode 100644 -index 0000000..d3f2fbd ---- /dev/null -+++ b/include/trace/events/latency_hist.h -@@ -0,0 +1,29 @@ -+#ifndef _LATENCY_HIST_H -+#define _LATENCY_HIST_H -+ -+enum hist_action { -+ IRQS_ON, -+ PREEMPT_ON, -+ TRACE_STOP, -+ IRQS_OFF, -+ PREEMPT_OFF, -+ TRACE_START, -+}; -+ -+static char *actions[] = { -+ "IRQS_ON", -+ "PREEMPT_ON", -+ "TRACE_STOP", -+ "IRQS_OFF", -+ "PREEMPT_OFF", -+ "TRACE_START", -+}; -+ -+static inline char *getaction(int action) -+{ -+ if (action >= 0 && action <= sizeof(actions)/sizeof(actions[0])) -+ return actions[action]; -+ return "unknown"; -+} -+ -+#endif /* _LATENCY_HIST_H */ -diff --git a/init/Kconfig b/init/Kconfig -index 0dfd09d..a74c5a0 100644 ---- a/init/Kconfig -+++ b/init/Kconfig -@@ -494,7 +494,7 @@ config TINY_RCU - - config RCU_EXPERT - bool "Make expert-level adjustments to RCU configuration" -- default n -+ default y if PREEMPT_RT_FULL - help - This option needs to be enabled if you wish to make - expert-level adjustments to RCU configuration. By default, -@@ -610,7 +610,7 @@ config RCU_FANOUT_LEAF - - config RCU_FAST_NO_HZ - bool "Accelerate last non-dyntick-idle CPU's grace periods" -- depends on NO_HZ_COMMON && SMP && RCU_EXPERT -+ depends on NO_HZ_COMMON && SMP && RCU_EXPERT && !PREEMPT_RT_FULL - default n - help - This option permits CPUs to enter dynticks-idle state even if -@@ -637,7 +637,7 @@ config TREE_RCU_TRACE - config RCU_BOOST - bool "Enable RCU priority boosting" - depends on RT_MUTEXES && PREEMPT_RCU && RCU_EXPERT -- default n -+ default y if PREEMPT_RT_FULL - help - This option boosts the priority of preempted RCU readers that - block the current preemptible RCU grace period for too long. -@@ -1029,6 +1029,7 @@ config CFS_BANDWIDTH - config RT_GROUP_SCHED - bool "Group scheduling for SCHED_RR/FIFO" - depends on CGROUP_SCHED -+ depends on !PREEMPT_RT_FULL - default n - help - This feature lets you explicitly allocate real CPU bandwidth -@@ -1717,6 +1718,7 @@ choice - - config SLAB - bool "SLAB" -+ depends on !PREEMPT_RT_FULL - help - The regular slab allocator that is established and known to work - well in all environments. It organizes cache hot objects in -@@ -1735,6 +1737,7 @@ config SLUB - config SLOB - depends on EXPERT - bool "SLOB (Simple Allocator)" -+ depends on !PREEMPT_RT_FULL - help - SLOB replaces the stock allocator with a drastically simpler - allocator. SLOB is generally more space efficient but -@@ -1744,7 +1747,7 @@ endchoice - - config SLUB_CPU_PARTIAL - default y -- depends on SLUB && SMP -+ depends on SLUB && SMP && !PREEMPT_RT_FULL - bool "SLUB per cpu partial cache" - help - Per cpu partial caches accellerate objects allocation and freeing -diff --git a/init/Makefile b/init/Makefile -index 7bc47ee..88cf473 100644 ---- a/init/Makefile -+++ b/init/Makefile -@@ -33,4 +33,4 @@ silent_chk_compile.h = : - include/generated/compile.h: FORCE - @$($(quiet)chk_compile.h) - $(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkcompile_h $@ \ -- "$(UTS_MACHINE)" "$(CONFIG_SMP)" "$(CONFIG_PREEMPT)" "$(CC) $(KBUILD_CFLAGS)" -+ "$(UTS_MACHINE)" "$(CONFIG_SMP)" "$(CONFIG_PREEMPT)" "$(CONFIG_PREEMPT_RT_FULL)" "$(CC) $(KBUILD_CFLAGS)" -diff --git a/init/main.c b/init/main.c -index b3c6e36..920f9eb 100644 ---- a/init/main.c -+++ b/init/main.c -@@ -507,6 +507,7 @@ asmlinkage __visible void __init start_kernel(void) - setup_command_line(command_line); - setup_nr_cpu_ids(); - setup_per_cpu_areas(); -+ softirq_early_init(); - boot_cpu_state_init(); - smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */ - -diff --git a/ipc/msg.c b/ipc/msg.c -index 1471db9..b8c5e7f 100644 ---- a/ipc/msg.c -+++ b/ipc/msg.c -@@ -183,20 +183,14 @@ static void ss_wakeup(struct list_head *h, int kill) - } - } - --static void expunge_all(struct msg_queue *msq, int res) -+static void expunge_all(struct msg_queue *msq, int res, -+ struct wake_q_head *wake_q) - { - struct msg_receiver *msr, *t; - - list_for_each_entry_safe(msr, t, &msq->q_receivers, r_list) { -- msr->r_msg = NULL; /* initialize expunge ordering */ -- wake_up_process(msr->r_tsk); -- /* -- * Ensure that the wakeup is visible before setting r_msg as -- * the receiving end depends on it: either spinning on a nil, -- * or dealing with -EAGAIN cases. See lockless receive part 1 -- * and 2 in do_msgrcv(). -- */ -- smp_wmb(); /* barrier (B) */ -+ -+ wake_q_add(wake_q, msr->r_tsk); - msr->r_msg = ERR_PTR(res); - } - } -@@ -213,11 +207,13 @@ static void freeque(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp) - { - struct msg_msg *msg, *t; - struct msg_queue *msq = container_of(ipcp, struct msg_queue, q_perm); -+ WAKE_Q(wake_q); - -- expunge_all(msq, -EIDRM); -+ expunge_all(msq, -EIDRM, &wake_q); - ss_wakeup(&msq->q_senders, 1); - msg_rmid(ns, msq); - ipc_unlock_object(&msq->q_perm); -+ wake_up_q(&wake_q); - rcu_read_unlock(); - - list_for_each_entry_safe(msg, t, &msq->q_messages, m_list) { -@@ -342,6 +338,7 @@ static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd, - struct kern_ipc_perm *ipcp; - struct msqid64_ds uninitialized_var(msqid64); - struct msg_queue *msq; -+ WAKE_Q(wake_q); - int err; - - if (cmd == IPC_SET) { -@@ -389,7 +386,7 @@ static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd, - /* sleeping receivers might be excluded by - * stricter permissions. - */ -- expunge_all(msq, -EAGAIN); -+ expunge_all(msq, -EAGAIN, &wake_q); - /* sleeping senders might be able to send - * due to a larger queue size. - */ -@@ -402,6 +399,7 @@ static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd, - - out_unlock0: - ipc_unlock_object(&msq->q_perm); -+ wake_up_q(&wake_q); - out_unlock1: - rcu_read_unlock(); - out_up: -@@ -566,7 +564,8 @@ static int testmsg(struct msg_msg *msg, long type, int mode) - return 0; - } - --static inline int pipelined_send(struct msg_queue *msq, struct msg_msg *msg) -+static inline int pipelined_send(struct msg_queue *msq, struct msg_msg *msg, -+ struct wake_q_head *wake_q) - { - struct msg_receiver *msr, *t; - -@@ -577,27 +576,13 @@ static inline int pipelined_send(struct msg_queue *msq, struct msg_msg *msg) - - list_del(&msr->r_list); - if (msr->r_maxsize < msg->m_ts) { -- /* initialize pipelined send ordering */ -- msr->r_msg = NULL; -- wake_up_process(msr->r_tsk); -- /* barrier (B) see barrier comment below */ -- smp_wmb(); -+ wake_q_add(wake_q, msr->r_tsk); - msr->r_msg = ERR_PTR(-E2BIG); - } else { -- msr->r_msg = NULL; - msq->q_lrpid = task_pid_vnr(msr->r_tsk); - msq->q_rtime = get_seconds(); -- wake_up_process(msr->r_tsk); -- /* -- * Ensure that the wakeup is visible before -- * setting r_msg, as the receiving can otherwise -- * exit - once r_msg is set, the receiver can -- * continue. See lockless receive part 1 and 2 -- * in do_msgrcv(). Barrier (B). -- */ -- smp_wmb(); -+ wake_q_add(wake_q, msr->r_tsk); - msr->r_msg = msg; -- - return 1; - } - } -@@ -613,6 +598,7 @@ long do_msgsnd(int msqid, long mtype, void __user *mtext, - struct msg_msg *msg; - int err; - struct ipc_namespace *ns; -+ WAKE_Q(wake_q); - - ns = current->nsproxy->ipc_ns; - -@@ -698,7 +684,7 @@ long do_msgsnd(int msqid, long mtype, void __user *mtext, - msq->q_lspid = task_tgid_vnr(current); - msq->q_stime = get_seconds(); - -- if (!pipelined_send(msq, msg)) { -+ if (!pipelined_send(msq, msg, &wake_q)) { - /* no one is waiting for this message, enqueue it */ - list_add_tail(&msg->m_list, &msq->q_messages); - msq->q_cbytes += msgsz; -@@ -712,6 +698,7 @@ long do_msgsnd(int msqid, long mtype, void __user *mtext, - - out_unlock0: - ipc_unlock_object(&msq->q_perm); -+ wake_up_q(&wake_q); - out_unlock1: - rcu_read_unlock(); - if (msg != NULL) -@@ -932,57 +919,25 @@ long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, int msgfl - rcu_read_lock(); - - /* Lockless receive, part 2: -- * Wait until pipelined_send or expunge_all are outside of -- * wake_up_process(). There is a race with exit(), see -- * ipc/mqueue.c for the details. The correct serialization -- * ensures that a receiver cannot continue without the wakeup -- * being visibible _before_ setting r_msg: -+ * The work in pipelined_send() and expunge_all(): -+ * - Set pointer to message -+ * - Queue the receiver task for later wakeup -+ * - Wake up the process after the lock is dropped. - * -- * CPU 0 CPU 1 -- * <loop receiver> -- * smp_rmb(); (A) <-- pair -. <waker thread> -- * <load ->r_msg> | msr->r_msg = NULL; -- * | wake_up_process(); -- * <continue> `------> smp_wmb(); (B) -- * msr->r_msg = msg; -- * -- * Where (A) orders the message value read and where (B) orders -- * the write to the r_msg -- done in both pipelined_send and -- * expunge_all. -+ * Should the process wake up before this wakeup (due to a -+ * signal) it will either see the message and continue … - */ -- for (;;) { -- /* -- * Pairs with writer barrier in pipelined_send -- * or expunge_all. -- */ -- smp_rmb(); /* barrier (A) */ -- msg = (struct msg_msg *)msr_d.r_msg; -- if (msg) -- break; - -- /* -- * The cpu_relax() call is a compiler barrier -- * which forces everything in this loop to be -- * re-loaded. -- */ -- cpu_relax(); -- } -- -- /* Lockless receive, part 3: -- * If there is a message or an error then accept it without -- * locking. -- */ -+ msg = (struct msg_msg *)msr_d.r_msg; - if (msg != ERR_PTR(-EAGAIN)) - goto out_unlock1; - -- /* Lockless receive, part 3: -- * Acquire the queue spinlock. -- */ -+ /* -+ * … or see -EAGAIN, acquire the lock to check the message -+ * again. -+ */ - ipc_lock_object(&msq->q_perm); - -- /* Lockless receive, part 4: -- * Repeat test after acquiring the spinlock. -- */ - msg = (struct msg_msg *)msr_d.r_msg; - if (msg != ERR_PTR(-EAGAIN)) - goto out_unlock0; -diff --git a/ipc/sem.c b/ipc/sem.c -index b3757ea..981a60a 100644 ---- a/ipc/sem.c -+++ b/ipc/sem.c -@@ -697,6 +697,13 @@ undo: - static void wake_up_sem_queue_prepare(struct list_head *pt, - struct sem_queue *q, int error) - { -+#ifdef CONFIG_PREEMPT_RT_BASE -+ struct task_struct *p = q->sleeper; -+ get_task_struct(p); -+ q->status = error; -+ wake_up_process(p); -+ put_task_struct(p); -+#else - if (list_empty(pt)) { - /* - * Hold preempt off so that we don't get preempted and have the -@@ -708,6 +715,7 @@ static void wake_up_sem_queue_prepare(struct list_head *pt, - q->pid = error; - - list_add_tail(&q->list, pt); -+#endif - } - - /** -@@ -721,6 +729,7 @@ static void wake_up_sem_queue_prepare(struct list_head *pt, - */ - static void wake_up_sem_queue_do(struct list_head *pt) - { -+#ifndef CONFIG_PREEMPT_RT_BASE - struct sem_queue *q, *t; - int did_something; - -@@ -733,6 +742,7 @@ static void wake_up_sem_queue_do(struct list_head *pt) - } - if (did_something) - preempt_enable(); -+#endif - } - - static void unlink_queue(struct sem_array *sma, struct sem_queue *q) -diff --git a/kernel/Kconfig.locks b/kernel/Kconfig.locks -index ebdb004..b9e6aa7 100644 ---- a/kernel/Kconfig.locks -+++ b/kernel/Kconfig.locks -@@ -225,11 +225,11 @@ config ARCH_SUPPORTS_ATOMIC_RMW - - config MUTEX_SPIN_ON_OWNER - def_bool y -- depends on SMP && !DEBUG_MUTEXES && ARCH_SUPPORTS_ATOMIC_RMW -+ depends on SMP && !DEBUG_MUTEXES && ARCH_SUPPORTS_ATOMIC_RMW && !PREEMPT_RT_FULL - - config RWSEM_SPIN_ON_OWNER - def_bool y -- depends on SMP && RWSEM_XCHGADD_ALGORITHM && ARCH_SUPPORTS_ATOMIC_RMW -+ depends on SMP && RWSEM_XCHGADD_ALGORITHM && ARCH_SUPPORTS_ATOMIC_RMW && !PREEMPT_RT_FULL - - config LOCK_SPIN_ON_OWNER - def_bool y -diff --git a/kernel/Kconfig.preempt b/kernel/Kconfig.preempt -index 3f9c974..11dbe26 100644 ---- a/kernel/Kconfig.preempt -+++ b/kernel/Kconfig.preempt -@@ -1,3 +1,16 @@ -+config PREEMPT -+ bool -+ select PREEMPT_COUNT -+ -+config PREEMPT_RT_BASE -+ bool -+ select PREEMPT -+ -+config HAVE_PREEMPT_LAZY -+ bool -+ -+config PREEMPT_LAZY -+ def_bool y if HAVE_PREEMPT_LAZY && PREEMPT_RT_FULL - - choice - prompt "Preemption Model" -@@ -33,9 +46,9 @@ config PREEMPT_VOLUNTARY - - Select this if you are building a kernel for a desktop system. - --config PREEMPT -+config PREEMPT__LL - bool "Preemptible Kernel (Low-Latency Desktop)" -- select PREEMPT_COUNT -+ select PREEMPT - select UNINLINE_SPIN_UNLOCK if !ARCH_INLINE_SPIN_UNLOCK - help - This option reduces the latency of the kernel by making -@@ -52,6 +65,22 @@ config PREEMPT - embedded system with latency requirements in the milliseconds - range. - -+config PREEMPT_RTB -+ bool "Preemptible Kernel (Basic RT)" -+ select PREEMPT_RT_BASE -+ help -+ This option is basically the same as (Low-Latency Desktop) but -+ enables changes which are preliminary for the full preemptible -+ RT kernel. -+ -+config PREEMPT_RT_FULL -+ bool "Fully Preemptible Kernel (RT)" -+ depends on IRQ_FORCED_THREADING -+ select PREEMPT_RT_BASE -+ select PREEMPT_RCU -+ help -+ All and everything -+ - endchoice - - config PREEMPT_COUNT -diff --git a/kernel/cgroup.c b/kernel/cgroup.c -index 86cb5c6..3920f49 100644 ---- a/kernel/cgroup.c -+++ b/kernel/cgroup.c -@@ -5005,10 +5005,10 @@ static void css_free_rcu_fn(struct rcu_head *rcu_head) - queue_work(cgroup_destroy_wq, &css->destroy_work); - } - --static void css_release_work_fn(struct work_struct *work) -+static void css_release_work_fn(struct swork_event *sev) - { - struct cgroup_subsys_state *css = -- container_of(work, struct cgroup_subsys_state, destroy_work); -+ container_of(sev, struct cgroup_subsys_state, destroy_swork); - struct cgroup_subsys *ss = css->ss; - struct cgroup *cgrp = css->cgroup; - -@@ -5049,8 +5049,8 @@ static void css_release(struct percpu_ref *ref) - struct cgroup_subsys_state *css = - container_of(ref, struct cgroup_subsys_state, refcnt); - -- INIT_WORK(&css->destroy_work, css_release_work_fn); -- queue_work(cgroup_destroy_wq, &css->destroy_work); -+ INIT_SWORK(&css->destroy_swork, css_release_work_fn); -+ swork_queue(&css->destroy_swork); - } - - static void init_and_link_css(struct cgroup_subsys_state *css, -@@ -5694,6 +5694,7 @@ static int __init cgroup_wq_init(void) - */ - cgroup_destroy_wq = alloc_workqueue("cgroup_destroy", 0, 1); - BUG_ON(!cgroup_destroy_wq); -+ BUG_ON(swork_get()); - - /* - * Used to destroy pidlists and separate to serve as flush domain. -diff --git a/kernel/cpu.c b/kernel/cpu.c -index 3e3f6e4..e4d7491 100644 ---- a/kernel/cpu.c -+++ b/kernel/cpu.c -@@ -152,8 +152,8 @@ static struct { - #endif - } cpu_hotplug = { - .active_writer = NULL, -- .wq = __WAIT_QUEUE_HEAD_INITIALIZER(cpu_hotplug.wq), - .lock = __MUTEX_INITIALIZER(cpu_hotplug.lock), -+ .wq = __WAIT_QUEUE_HEAD_INITIALIZER(cpu_hotplug.wq), - #ifdef CONFIG_DEBUG_LOCK_ALLOC - .dep_map = {.name = "cpu_hotplug.lock" }, - #endif -@@ -166,6 +166,289 @@ static struct { - #define cpuhp_lock_acquire() lock_map_acquire(&cpu_hotplug.dep_map) - #define cpuhp_lock_release() lock_map_release(&cpu_hotplug.dep_map) - -+/** -+ * hotplug_pcp - per cpu hotplug descriptor -+ * @unplug: set when pin_current_cpu() needs to sync tasks -+ * @sync_tsk: the task that waits for tasks to finish pinned sections -+ * @refcount: counter of tasks in pinned sections -+ * @grab_lock: set when the tasks entering pinned sections should wait -+ * @synced: notifier for @sync_tsk to tell cpu_down it's finished -+ * @mutex: the mutex to make tasks wait (used when @grab_lock is true) -+ * @mutex_init: zero if the mutex hasn't been initialized yet. -+ * -+ * Although @unplug and @sync_tsk may point to the same task, the @unplug -+ * is used as a flag and still exists after @sync_tsk has exited and -+ * @sync_tsk set to NULL. -+ */ -+struct hotplug_pcp { -+ struct task_struct *unplug; -+ struct task_struct *sync_tsk; -+ int refcount; -+ int grab_lock; -+ struct completion synced; -+ struct completion unplug_wait; -+#ifdef CONFIG_PREEMPT_RT_FULL -+ /* -+ * Note, on PREEMPT_RT, the hotplug lock must save the state of -+ * the task, otherwise the mutex will cause the task to fail -+ * to sleep when required. (Because it's called from migrate_disable()) -+ * -+ * The spinlock_t on PREEMPT_RT is a mutex that saves the task's -+ * state. -+ */ -+ spinlock_t lock; -+#else -+ struct mutex mutex; -+#endif -+ int mutex_init; -+}; -+ -+#ifdef CONFIG_PREEMPT_RT_FULL -+# define hotplug_lock(hp) rt_spin_lock__no_mg(&(hp)->lock) -+# define hotplug_unlock(hp) rt_spin_unlock__no_mg(&(hp)->lock) -+#else -+# define hotplug_lock(hp) mutex_lock(&(hp)->mutex) -+# define hotplug_unlock(hp) mutex_unlock(&(hp)->mutex) -+#endif -+ -+static DEFINE_PER_CPU(struct hotplug_pcp, hotplug_pcp); -+ -+/** -+ * pin_current_cpu - Prevent the current cpu from being unplugged -+ * -+ * Lightweight version of get_online_cpus() to prevent cpu from being -+ * unplugged when code runs in a migration disabled region. -+ * -+ * Must be called with preemption disabled (preempt_count = 1)! -+ */ -+void pin_current_cpu(void) -+{ -+ struct hotplug_pcp *hp; -+ int force = 0; -+ -+retry: -+ hp = this_cpu_ptr(&hotplug_pcp); -+ -+ if (!hp->unplug || hp->refcount || force || preempt_count() > 1 || -+ hp->unplug == current) { -+ hp->refcount++; -+ return; -+ } -+ if (hp->grab_lock) { -+ preempt_enable(); -+ hotplug_lock(hp); -+ hotplug_unlock(hp); -+ } else { -+ preempt_enable(); -+ /* -+ * Try to push this task off of this CPU. -+ */ -+ if (!migrate_me()) { -+ preempt_disable(); -+ hp = this_cpu_ptr(&hotplug_pcp); -+ if (!hp->grab_lock) { -+ /* -+ * Just let it continue it's already pinned -+ * or about to sleep. -+ */ -+ force = 1; -+ goto retry; -+ } -+ preempt_enable(); -+ } -+ } -+ preempt_disable(); -+ goto retry; -+} -+ -+/** -+ * unpin_current_cpu - Allow unplug of current cpu -+ * -+ * Must be called with preemption or interrupts disabled! -+ */ -+void unpin_current_cpu(void) -+{ -+ struct hotplug_pcp *hp = this_cpu_ptr(&hotplug_pcp); -+ -+ WARN_ON(hp->refcount <= 0); -+ -+ /* This is safe. sync_unplug_thread is pinned to this cpu */ -+ if (!--hp->refcount && hp->unplug && hp->unplug != current) -+ wake_up_process(hp->unplug); -+} -+ -+static void wait_for_pinned_cpus(struct hotplug_pcp *hp) -+{ -+ set_current_state(TASK_UNINTERRUPTIBLE); -+ while (hp->refcount) { -+ schedule_preempt_disabled(); -+ set_current_state(TASK_UNINTERRUPTIBLE); -+ } -+} -+ -+static int sync_unplug_thread(void *data) -+{ -+ struct hotplug_pcp *hp = data; -+ -+ wait_for_completion(&hp->unplug_wait); -+ preempt_disable(); -+ hp->unplug = current; -+ wait_for_pinned_cpus(hp); -+ -+ /* -+ * This thread will synchronize the cpu_down() with threads -+ * that have pinned the CPU. When the pinned CPU count reaches -+ * zero, we inform the cpu_down code to continue to the next step. -+ */ -+ set_current_state(TASK_UNINTERRUPTIBLE); -+ preempt_enable(); -+ complete(&hp->synced); -+ -+ /* -+ * If all succeeds, the next step will need tasks to wait till -+ * the CPU is offline before continuing. To do this, the grab_lock -+ * is set and tasks going into pin_current_cpu() will block on the -+ * mutex. But we still need to wait for those that are already in -+ * pinned CPU sections. If the cpu_down() failed, the kthread_should_stop() -+ * will kick this thread out. -+ */ -+ while (!hp->grab_lock && !kthread_should_stop()) { -+ schedule(); -+ set_current_state(TASK_UNINTERRUPTIBLE); -+ } -+ -+ /* Make sure grab_lock is seen before we see a stale completion */ -+ smp_mb(); -+ -+ /* -+ * Now just before cpu_down() enters stop machine, we need to make -+ * sure all tasks that are in pinned CPU sections are out, and new -+ * tasks will now grab the lock, keeping them from entering pinned -+ * CPU sections. -+ */ -+ if (!kthread_should_stop()) { -+ preempt_disable(); -+ wait_for_pinned_cpus(hp); -+ preempt_enable(); -+ complete(&hp->synced); -+ } -+ -+ set_current_state(TASK_UNINTERRUPTIBLE); -+ while (!kthread_should_stop()) { -+ schedule(); -+ set_current_state(TASK_UNINTERRUPTIBLE); -+ } -+ set_current_state(TASK_RUNNING); -+ -+ /* -+ * Force this thread off this CPU as it's going down and -+ * we don't want any more work on this CPU. -+ */ -+ current->flags &= ~PF_NO_SETAFFINITY; -+ set_cpus_allowed_ptr(current, cpu_present_mask); -+ migrate_me(); -+ return 0; -+} -+ -+static void __cpu_unplug_sync(struct hotplug_pcp *hp) -+{ -+ wake_up_process(hp->sync_tsk); -+ wait_for_completion(&hp->synced); -+} -+ -+static void __cpu_unplug_wait(unsigned int cpu) -+{ -+ struct hotplug_pcp *hp = &per_cpu(hotplug_pcp, cpu); -+ -+ complete(&hp->unplug_wait); -+ wait_for_completion(&hp->synced); -+} -+ -+/* -+ * Start the sync_unplug_thread on the target cpu and wait for it to -+ * complete. -+ */ -+static int cpu_unplug_begin(unsigned int cpu) -+{ -+ struct hotplug_pcp *hp = &per_cpu(hotplug_pcp, cpu); -+ int err; -+ -+ /* Protected by cpu_hotplug.lock */ -+ if (!hp->mutex_init) { -+#ifdef CONFIG_PREEMPT_RT_FULL -+ spin_lock_init(&hp->lock); -+#else -+ mutex_init(&hp->mutex); -+#endif -+ hp->mutex_init = 1; -+ } -+ -+ /* Inform the scheduler to migrate tasks off this CPU */ -+ tell_sched_cpu_down_begin(cpu); -+ -+ init_completion(&hp->synced); -+ init_completion(&hp->unplug_wait); -+ -+ hp->sync_tsk = kthread_create(sync_unplug_thread, hp, "sync_unplug/%d", cpu); -+ if (IS_ERR(hp->sync_tsk)) { -+ err = PTR_ERR(hp->sync_tsk); -+ hp->sync_tsk = NULL; -+ return err; -+ } -+ kthread_bind(hp->sync_tsk, cpu); -+ -+ /* -+ * Wait for tasks to get out of the pinned sections, -+ * it's still OK if new tasks enter. Some CPU notifiers will -+ * wait for tasks that are going to enter these sections and -+ * we must not have them block. -+ */ -+ wake_up_process(hp->sync_tsk); -+ return 0; -+} -+ -+static void cpu_unplug_sync(unsigned int cpu) -+{ -+ struct hotplug_pcp *hp = &per_cpu(hotplug_pcp, cpu); -+ -+ init_completion(&hp->synced); -+ /* The completion needs to be initialzied before setting grab_lock */ -+ smp_wmb(); -+ -+ /* Grab the mutex before setting grab_lock */ -+ hotplug_lock(hp); -+ hp->grab_lock = 1; -+ -+ /* -+ * The CPU notifiers have been completed. -+ * Wait for tasks to get out of pinned CPU sections and have new -+ * tasks block until the CPU is completely down. -+ */ -+ __cpu_unplug_sync(hp); -+ -+ /* All done with the sync thread */ -+ kthread_stop(hp->sync_tsk); -+ hp->sync_tsk = NULL; -+} -+ -+static void cpu_unplug_done(unsigned int cpu) -+{ -+ struct hotplug_pcp *hp = &per_cpu(hotplug_pcp, cpu); -+ -+ hp->unplug = NULL; -+ /* Let all tasks know cpu unplug is finished before cleaning up */ -+ smp_wmb(); -+ -+ if (hp->sync_tsk) -+ kthread_stop(hp->sync_tsk); -+ -+ if (hp->grab_lock) { -+ hotplug_unlock(hp); -+ /* protected by cpu_hotplug.lock */ -+ hp->grab_lock = 0; -+ } -+ tell_sched_cpu_down_done(cpu); -+} - - void get_online_cpus(void) - { -@@ -718,10 +1001,14 @@ static int takedown_cpu(unsigned int cpu) - else - synchronize_rcu(); - -+ __cpu_unplug_wait(cpu); - /* Park the smpboot threads */ - kthread_park(per_cpu_ptr(&cpuhp_state, cpu)->thread); - smpboot_park_threads(cpu); - -+ /* Notifiers are done. Don't let any more tasks pin this CPU. */ -+ cpu_unplug_sync(cpu); -+ - /* - * Prevent irq alloc/free while the dying cpu reorganizes the - * interrupt affinities. -@@ -807,6 +1094,9 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen, - struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu); - int prev_state, ret = 0; - bool hasdied = false; -+ int mycpu; -+ cpumask_var_t cpumask; -+ cpumask_var_t cpumask_org; - - if (num_online_cpus() == 1) - return -EBUSY; -@@ -814,7 +1104,34 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen, - if (!cpu_present(cpu)) - return -EINVAL; - -+ /* Move the downtaker off the unplug cpu */ -+ if (!alloc_cpumask_var(&cpumask, GFP_KERNEL)) -+ return -ENOMEM; -+ if (!alloc_cpumask_var(&cpumask_org, GFP_KERNEL)) { -+ free_cpumask_var(cpumask); -+ return -ENOMEM; -+ } -+ -+ cpumask_copy(cpumask_org, tsk_cpus_allowed(current)); -+ cpumask_andnot(cpumask, cpu_online_mask, cpumask_of(cpu)); -+ set_cpus_allowed_ptr(current, cpumask); -+ free_cpumask_var(cpumask); -+ migrate_disable(); -+ mycpu = smp_processor_id(); -+ if (mycpu == cpu) { -+ printk(KERN_ERR "Yuck! Still on unplug CPU\n!"); -+ migrate_enable(); -+ ret = -EBUSY; -+ goto restore_cpus; -+ } -+ -+ migrate_enable(); - cpu_hotplug_begin(); -+ ret = cpu_unplug_begin(cpu); -+ if (ret) { -+ printk("cpu_unplug_begin(%d) failed\n", cpu); -+ goto out_cancel; -+ } - - cpuhp_tasks_frozen = tasks_frozen; - -@@ -853,10 +1170,15 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen, - - hasdied = prev_state != st->state && st->state == CPUHP_OFFLINE; - out: -+ cpu_unplug_done(cpu); -+out_cancel: - cpu_hotplug_done(); - /* This post dead nonsense must die */ - if (!ret && hasdied) - cpu_notify_nofail(CPU_POST_DEAD, cpu); -+restore_cpus: -+ set_cpus_allowed_ptr(current, cpumask_org); -+ free_cpumask_var(cpumask_org); - return ret; - } - -diff --git a/kernel/debug/kdb/kdb_io.c b/kernel/debug/kdb/kdb_io.c -index fc1ef73..83c6665 100644 ---- a/kernel/debug/kdb/kdb_io.c -+++ b/kernel/debug/kdb/kdb_io.c -@@ -554,7 +554,6 @@ int vkdb_printf(enum kdb_msgsrc src, const char *fmt, va_list ap) - int linecount; - int colcount; - int logging, saved_loglevel = 0; -- int saved_trap_printk; - int got_printf_lock = 0; - int retlen = 0; - int fnd, len; -@@ -565,8 +564,6 @@ int vkdb_printf(enum kdb_msgsrc src, const char *fmt, va_list ap) - unsigned long uninitialized_var(flags); - - preempt_disable(); -- saved_trap_printk = kdb_trap_printk; -- kdb_trap_printk = 0; - - /* Serialize kdb_printf if multiple cpus try to write at once. - * But if any cpu goes recursive in kdb, just print the output, -@@ -855,7 +852,6 @@ kdb_print_out: - } else { - __release(kdb_printf_lock); - } -- kdb_trap_printk = saved_trap_printk; - preempt_enable(); - return retlen; - } -@@ -865,9 +861,11 @@ int kdb_printf(const char *fmt, ...) - va_list ap; - int r; - -+ kdb_trap_printk++; - va_start(ap, fmt); - r = vkdb_printf(KDB_MSGSRC_INTERNAL, fmt, ap); - va_end(ap); -+ kdb_trap_printk--; - - return r; - } -diff --git a/kernel/events/core.c b/kernel/events/core.c -index c0ded24..55397ba 100644 ---- a/kernel/events/core.c -+++ b/kernel/events/core.c -@@ -963,6 +963,7 @@ static void __perf_mux_hrtimer_init(struct perf_cpu_context *cpuctx, int cpu) - raw_spin_lock_init(&cpuctx->hrtimer_lock); - hrtimer_init(timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_PINNED); - timer->function = perf_mux_hrtimer_handler; -+ timer->irqsafe = 1; - } - - static int perf_mux_hrtimer_restart(struct perf_cpu_context *cpuctx) -@@ -7261,6 +7262,7 @@ static void perf_swevent_init_hrtimer(struct perf_event *event) - - hrtimer_init(&hwc->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - hwc->hrtimer.function = perf_swevent_hrtimer; -+ hwc->hrtimer.irqsafe = 1; - - /* - * Since hrtimers have a fixed rate, we can do a static freq->period -diff --git a/kernel/exit.c b/kernel/exit.c -index fd90195..18269f0 100644 ---- a/kernel/exit.c -+++ b/kernel/exit.c -@@ -143,7 +143,7 @@ static void __exit_signal(struct task_struct *tsk) - * Do this under ->siglock, we can race with another thread - * doing sigqueue_free() if we have SIGQUEUE_PREALLOC signals. - */ -- flush_sigqueue(&tsk->pending); -+ flush_task_sigqueue(tsk); - tsk->sighand = NULL; - spin_unlock(&sighand->siglock); - -diff --git a/kernel/fork.c b/kernel/fork.c -index d277e83..18cc630 100644 ---- a/kernel/fork.c -+++ b/kernel/fork.c -@@ -253,7 +253,9 @@ static inline void put_signal_struct(struct signal_struct *sig) - if (atomic_dec_and_test(&sig->sigcnt)) - free_signal_struct(sig); - } -- -+#ifdef CONFIG_PREEMPT_RT_BASE -+static -+#endif - void __put_task_struct(struct task_struct *tsk) - { - WARN_ON(!tsk->exit_state); -@@ -270,7 +272,18 @@ void __put_task_struct(struct task_struct *tsk) - if (!profile_handoff_task(tsk)) - free_task(tsk); - } -+#ifndef CONFIG_PREEMPT_RT_BASE - EXPORT_SYMBOL_GPL(__put_task_struct); -+#else -+void __put_task_struct_cb(struct rcu_head *rhp) -+{ -+ struct task_struct *tsk = container_of(rhp, struct task_struct, put_rcu); -+ -+ __put_task_struct(tsk); -+ -+} -+EXPORT_SYMBOL_GPL(__put_task_struct_cb); -+#endif - - void __init __weak arch_task_cache_init(void) { } - -@@ -699,6 +712,19 @@ void __mmdrop(struct mm_struct *mm) - } - EXPORT_SYMBOL_GPL(__mmdrop); - -+#ifdef CONFIG_PREEMPT_RT_BASE -+/* -+ * RCU callback for delayed mm drop. Not strictly rcu, but we don't -+ * want another facility to make this work. -+ */ -+void __mmdrop_delayed(struct rcu_head *rhp) -+{ -+ struct mm_struct *mm = container_of(rhp, struct mm_struct, delayed_drop); -+ -+ __mmdrop(mm); -+} -+#endif -+ - /* - * Decrement the use count and release all resources for an mm. - */ -@@ -1228,6 +1254,9 @@ static void rt_mutex_init_task(struct task_struct *p) - */ - static void posix_cpu_timers_init(struct task_struct *tsk) - { -+#ifdef CONFIG_PREEMPT_RT_BASE -+ tsk->posix_timer_list = NULL; -+#endif - tsk->cputime_expires.prof_exp = 0; - tsk->cputime_expires.virt_exp = 0; - tsk->cputime_expires.sched_exp = 0; -@@ -1352,6 +1381,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, - spin_lock_init(&p->alloc_lock); - - init_sigpending(&p->pending); -+ p->sigqueue_cache = NULL; - - p->utime = p->stime = p->gtime = 0; - p->utimescaled = p->stimescaled = 0; -diff --git a/kernel/futex.c b/kernel/futex.c -index c20f06f..8256f45 100644 ---- a/kernel/futex.c -+++ b/kernel/futex.c -@@ -866,7 +866,9 @@ void exit_pi_state_list(struct task_struct *curr) - * task still owns the PI-state: - */ - if (head->next != next) { -+ raw_spin_unlock_irq(&curr->pi_lock); - spin_unlock(&hb->lock); -+ raw_spin_lock_irq(&curr->pi_lock); - continue; - } - -@@ -1261,6 +1263,7 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_q *this, - struct futex_pi_state *pi_state = this->pi_state; - u32 uninitialized_var(curval), newval; - WAKE_Q(wake_q); -+ WAKE_Q(wake_sleeper_q); - bool deboost; - int ret = 0; - -@@ -1327,7 +1330,8 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_q *this, - - raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock); - -- deboost = rt_mutex_futex_unlock(&pi_state->pi_mutex, &wake_q); -+ deboost = rt_mutex_futex_unlock(&pi_state->pi_mutex, &wake_q, -+ &wake_sleeper_q); - - /* - * First unlock HB so the waiter does not spin on it once he got woken -@@ -1337,6 +1341,7 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_q *this, - */ - spin_unlock(&hb->lock); - wake_up_q(&wake_q); -+ wake_up_q_sleeper(&wake_sleeper_q); - if (deboost) - rt_mutex_adjust_prio(current); - -@@ -1886,6 +1891,16 @@ retry_private: - requeue_pi_wake_futex(this, &key2, hb2); - drop_count++; - continue; -+ } else if (ret == -EAGAIN) { -+ /* -+ * Waiter was woken by timeout or -+ * signal and has set pi_blocked_on to -+ * PI_WAKEUP_INPROGRESS before we -+ * tried to enqueue it on the rtmutex. -+ */ -+ this->pi_state = NULL; -+ put_pi_state(pi_state); -+ continue; - } else if (ret) { - /* - * rt_mutex_start_proxy_lock() detected a -@@ -2776,7 +2791,7 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, - struct hrtimer_sleeper timeout, *to = NULL; - struct rt_mutex_waiter rt_waiter; - struct rt_mutex *pi_mutex = NULL; -- struct futex_hash_bucket *hb; -+ struct futex_hash_bucket *hb, *hb2; - union futex_key key2 = FUTEX_KEY_INIT; - struct futex_q q = futex_q_init; - int res, ret; -@@ -2801,10 +2816,7 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, - * The waiter is allocated on our stack, manipulated by the requeue - * code while we sleep on uaddr. - */ -- debug_rt_mutex_init_waiter(&rt_waiter); -- RB_CLEAR_NODE(&rt_waiter.pi_tree_entry); -- RB_CLEAR_NODE(&rt_waiter.tree_entry); -- rt_waiter.task = NULL; -+ rt_mutex_init_waiter(&rt_waiter, false); - - ret = get_futex_key(uaddr2, flags & FLAGS_SHARED, &key2, VERIFY_WRITE); - if (unlikely(ret != 0)) -@@ -2835,20 +2847,55 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, - /* Queue the futex_q, drop the hb lock, wait for wakeup. */ - futex_wait_queue_me(hb, &q, to); - -- spin_lock(&hb->lock); -- ret = handle_early_requeue_pi_wakeup(hb, &q, &key2, to); -- spin_unlock(&hb->lock); -- if (ret) -- goto out_put_keys; -+ /* -+ * On RT we must avoid races with requeue and trying to block -+ * on two mutexes (hb->lock and uaddr2's rtmutex) by -+ * serializing access to pi_blocked_on with pi_lock. -+ */ -+ raw_spin_lock_irq(¤t->pi_lock); -+ if (current->pi_blocked_on) { -+ /* -+ * We have been requeued or are in the process of -+ * being requeued. -+ */ -+ raw_spin_unlock_irq(¤t->pi_lock); -+ } else { -+ /* -+ * Setting pi_blocked_on to PI_WAKEUP_INPROGRESS -+ * prevents a concurrent requeue from moving us to the -+ * uaddr2 rtmutex. After that we can safely acquire -+ * (and possibly block on) hb->lock. -+ */ -+ current->pi_blocked_on = PI_WAKEUP_INPROGRESS; -+ raw_spin_unlock_irq(¤t->pi_lock); -+ -+ spin_lock(&hb->lock); -+ -+ /* -+ * Clean up pi_blocked_on. We might leak it otherwise -+ * when we succeeded with the hb->lock in the fast -+ * path. -+ */ -+ raw_spin_lock_irq(¤t->pi_lock); -+ current->pi_blocked_on = NULL; -+ raw_spin_unlock_irq(¤t->pi_lock); -+ -+ ret = handle_early_requeue_pi_wakeup(hb, &q, &key2, to); -+ spin_unlock(&hb->lock); -+ if (ret) -+ goto out_put_keys; -+ } - - /* -- * In order for us to be here, we know our q.key == key2, and since -- * we took the hb->lock above, we also know that futex_requeue() has -- * completed and we no longer have to concern ourselves with a wakeup -- * race with the atomic proxy lock acquisition by the requeue code. The -- * futex_requeue dropped our key1 reference and incremented our key2 -- * reference count. -+ * In order to be here, we have either been requeued, are in -+ * the process of being requeued, or requeue successfully -+ * acquired uaddr2 on our behalf. If pi_blocked_on was -+ * non-null above, we may be racing with a requeue. Do not -+ * rely on q->lock_ptr to be hb2->lock until after blocking on -+ * hb->lock or hb2->lock. The futex_requeue dropped our key1 -+ * reference and incremented our key2 reference count. - */ -+ hb2 = hash_futex(&key2); - - /* Check if the requeue code acquired the second futex for us. */ - if (!q.rt_waiter) { -@@ -2857,14 +2904,15 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, - * did a lock-steal - fix up the PI-state in that case. - */ - if (q.pi_state && (q.pi_state->owner != current)) { -- spin_lock(q.lock_ptr); -+ spin_lock(&hb2->lock); -+ BUG_ON(&hb2->lock != q.lock_ptr); - ret = fixup_pi_state_owner(uaddr2, &q, current); - /* - * Drop the reference to the pi state which - * the requeue_pi() code acquired for us. - */ - put_pi_state(q.pi_state); -- spin_unlock(q.lock_ptr); -+ spin_unlock(&hb2->lock); - } - } else { - /* -@@ -2877,7 +2925,8 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, - ret = rt_mutex_finish_proxy_lock(pi_mutex, to, &rt_waiter); - debug_rt_mutex_free_waiter(&rt_waiter); - -- spin_lock(q.lock_ptr); -+ spin_lock(&hb2->lock); -+ BUG_ON(&hb2->lock != q.lock_ptr); - /* - * Fixup the pi_state owner and possibly acquire the lock if we - * haven't already. -diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c -index a15b548..28c39c1 100644 ---- a/kernel/irq/handle.c -+++ b/kernel/irq/handle.c -@@ -134,6 +134,8 @@ void __irq_wake_thread(struct irq_desc *desc, struct irqaction *action) - - irqreturn_t handle_irq_event_percpu(struct irq_desc *desc) - { -+ struct pt_regs *regs = get_irq_regs(); -+ u64 ip = regs ? instruction_pointer(regs) : 0; - irqreturn_t retval = IRQ_NONE; - unsigned int flags = 0, irq = desc->irq_data.irq; - struct irqaction *action; -@@ -174,7 +176,11 @@ irqreturn_t handle_irq_event_percpu(struct irq_desc *desc) - retval |= res; - } - -- add_interrupt_randomness(irq, flags); -+#ifdef CONFIG_PREEMPT_RT_FULL -+ desc->random_ip = ip; -+#else -+ add_interrupt_randomness(irq, flags, ip); -+#endif - - if (!noirqdebug) - note_interrupt(desc, retval); -diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c -index cc1cc64..f5e9fd5 100644 ---- a/kernel/irq/manage.c -+++ b/kernel/irq/manage.c -@@ -22,6 +22,7 @@ - #include "internals.h" - - #ifdef CONFIG_IRQ_FORCED_THREADING -+# ifndef CONFIG_PREEMPT_RT_BASE - __read_mostly bool force_irqthreads; - - static int __init setup_forced_irqthreads(char *arg) -@@ -30,6 +31,7 @@ static int __init setup_forced_irqthreads(char *arg) - return 0; - } - early_param("threadirqs", setup_forced_irqthreads); -+# endif - #endif - - static void __synchronize_hardirq(struct irq_desc *desc) -@@ -179,6 +181,62 @@ static inline void - irq_get_pending(struct cpumask *mask, struct irq_desc *desc) { } - #endif - -+#ifdef CONFIG_PREEMPT_RT_FULL -+static void _irq_affinity_notify(struct irq_affinity_notify *notify); -+static struct task_struct *set_affinity_helper; -+static LIST_HEAD(affinity_list); -+static DEFINE_RAW_SPINLOCK(affinity_list_lock); -+ -+static int set_affinity_thread(void *unused) -+{ -+ while (1) { -+ struct irq_affinity_notify *notify; -+ int empty; -+ -+ set_current_state(TASK_INTERRUPTIBLE); -+ -+ raw_spin_lock_irq(&affinity_list_lock); -+ empty = list_empty(&affinity_list); -+ raw_spin_unlock_irq(&affinity_list_lock); -+ -+ if (empty) -+ schedule(); -+ if (kthread_should_stop()) -+ break; -+ set_current_state(TASK_RUNNING); -+try_next: -+ notify = NULL; -+ -+ raw_spin_lock_irq(&affinity_list_lock); -+ if (!list_empty(&affinity_list)) { -+ notify = list_first_entry(&affinity_list, -+ struct irq_affinity_notify, list); -+ list_del_init(¬ify->list); -+ } -+ raw_spin_unlock_irq(&affinity_list_lock); -+ -+ if (!notify) -+ continue; -+ _irq_affinity_notify(notify); -+ goto try_next; -+ } -+ return 0; -+} -+ -+static void init_helper_thread(void) -+{ -+ if (set_affinity_helper) -+ return; -+ set_affinity_helper = kthread_run(set_affinity_thread, NULL, -+ "affinity-cb"); -+ WARN_ON(IS_ERR(set_affinity_helper)); -+} -+#else -+ -+static inline void init_helper_thread(void) { } -+ -+#endif -+ - int irq_do_set_affinity(struct irq_data *data, const struct cpumask *mask, - bool force) - { -@@ -218,7 +276,17 @@ int irq_set_affinity_locked(struct irq_data *data, const struct cpumask *mask, - - if (desc->affinity_notify) { - kref_get(&desc->affinity_notify->kref); -+ -+#ifdef CONFIG_PREEMPT_RT_FULL -+ raw_spin_lock(&affinity_list_lock); -+ if (list_empty(&desc->affinity_notify->list)) -+ list_add_tail(&affinity_list, -+ &desc->affinity_notify->list); -+ raw_spin_unlock(&affinity_list_lock); -+ wake_up_process(set_affinity_helper); -+#else - schedule_work(&desc->affinity_notify->work); -+#endif - } - irqd_set(data, IRQD_AFFINITY_SET); - -@@ -256,10 +324,8 @@ int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m) - } - EXPORT_SYMBOL_GPL(irq_set_affinity_hint); - --static void irq_affinity_notify(struct work_struct *work) -+static void _irq_affinity_notify(struct irq_affinity_notify *notify) - { -- struct irq_affinity_notify *notify = -- container_of(work, struct irq_affinity_notify, work); - struct irq_desc *desc = irq_to_desc(notify->irq); - cpumask_var_t cpumask; - unsigned long flags; -@@ -281,6 +347,13 @@ out: - kref_put(¬ify->kref, notify->release); - } - -+static void irq_affinity_notify(struct work_struct *work) -+{ -+ struct irq_affinity_notify *notify = -+ container_of(work, struct irq_affinity_notify, work); -+ _irq_affinity_notify(notify); -+} -+ - /** - * irq_set_affinity_notifier - control notification of IRQ affinity changes - * @irq: Interrupt for which to enable/disable notification -@@ -310,6 +383,8 @@ irq_set_affinity_notifier(unsigned int irq, struct irq_affinity_notify *notify) - notify->irq = irq; - kref_init(¬ify->kref); - INIT_WORK(¬ify->work, irq_affinity_notify); -+ INIT_LIST_HEAD(¬ify->list); -+ init_helper_thread(); - } - - raw_spin_lock_irqsave(&desc->lock, flags); -@@ -863,7 +938,15 @@ irq_forced_thread_fn(struct irq_desc *desc, struct irqaction *action) - local_bh_disable(); - ret = action->thread_fn(action->irq, action->dev_id); - irq_finalize_oneshot(desc, action); -- local_bh_enable(); -+ /* -+ * Interrupts which have real time requirements can be set up -+ * to avoid softirq processing in the thread handler. This is -+ * safe as these interrupts do not raise soft interrupts. -+ */ -+ if (irq_settings_no_softirq_call(desc)) -+ _local_bh_enable(); -+ else -+ local_bh_enable(); - return ret; - } - -@@ -960,6 +1043,12 @@ static int irq_thread(void *data) - if (action_ret == IRQ_WAKE_THREAD) - irq_wake_secondary(desc, action); - -+#ifdef CONFIG_PREEMPT_RT_FULL -+ migrate_disable(); -+ add_interrupt_randomness(action->irq, 0, -+ desc->random_ip ^ (unsigned long) action); -+ migrate_enable(); -+#endif - wake_threads_waitq(desc); - } - -@@ -1313,6 +1402,9 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) - irqd_set(&desc->irq_data, IRQD_NO_BALANCING); - } - -+ if (new->flags & IRQF_NO_SOFTIRQ_CALL) -+ irq_settings_set_no_softirq_call(desc); -+ - /* Set default affinity mask once everything is setup */ - setup_affinity(desc, mask); - -@@ -1998,7 +2090,7 @@ EXPORT_SYMBOL_GPL(irq_get_irqchip_state); - * This call sets the internal irqchip state of an interrupt, - * depending on the value of @which. - * -- * This function should be called with preemption disabled if the -+ * This function should be called with migration disabled if the - * interrupt controller has per-cpu registers. - */ - int irq_set_irqchip_state(unsigned int irq, enum irqchip_irq_state which, -diff --git a/kernel/irq/settings.h b/kernel/irq/settings.h -index 320579d..2df2d44 100644 ---- a/kernel/irq/settings.h -+++ b/kernel/irq/settings.h -@@ -16,6 +16,7 @@ enum { - _IRQ_PER_CPU_DEVID = IRQ_PER_CPU_DEVID, - _IRQ_IS_POLLED = IRQ_IS_POLLED, - _IRQ_DISABLE_UNLAZY = IRQ_DISABLE_UNLAZY, -+ _IRQ_NO_SOFTIRQ_CALL = IRQ_NO_SOFTIRQ_CALL, - _IRQF_MODIFY_MASK = IRQF_MODIFY_MASK, - }; - -@@ -30,6 +31,7 @@ enum { - #define IRQ_PER_CPU_DEVID GOT_YOU_MORON - #define IRQ_IS_POLLED GOT_YOU_MORON - #define IRQ_DISABLE_UNLAZY GOT_YOU_MORON -+#define IRQ_NO_SOFTIRQ_CALL GOT_YOU_MORON - #undef IRQF_MODIFY_MASK - #define IRQF_MODIFY_MASK GOT_YOU_MORON - -@@ -40,6 +42,16 @@ irq_settings_clr_and_set(struct irq_desc *desc, u32 clr, u32 set) - desc->status_use_accessors |= (set & _IRQF_MODIFY_MASK); - } - -+static inline bool irq_settings_no_softirq_call(struct irq_desc *desc) -+{ -+ return desc->status_use_accessors & _IRQ_NO_SOFTIRQ_CALL; -+} -+ -+static inline void irq_settings_set_no_softirq_call(struct irq_desc *desc) -+{ -+ desc->status_use_accessors |= _IRQ_NO_SOFTIRQ_CALL; -+} -+ - static inline bool irq_settings_is_per_cpu(struct irq_desc *desc) - { - return desc->status_use_accessors & _IRQ_PER_CPU; -diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c -index 5707f97..73f38dc 100644 ---- a/kernel/irq/spurious.c -+++ b/kernel/irq/spurious.c -@@ -442,6 +442,10 @@ MODULE_PARM_DESC(noirqdebug, "Disable irq lockup detection when true"); - - static int __init irqfixup_setup(char *str) - { -+#ifdef CONFIG_PREEMPT_RT_BASE -+ pr_warn("irqfixup boot option not supported w/ CONFIG_PREEMPT_RT_BASE\n"); -+ return 1; -+#endif - irqfixup = 1; - printk(KERN_WARNING "Misrouted IRQ fixup support enabled.\n"); - printk(KERN_WARNING "This may impact system performance.\n"); -@@ -454,6 +458,10 @@ module_param(irqfixup, int, 0644); - - static int __init irqpoll_setup(char *str) - { -+#ifdef CONFIG_PREEMPT_RT_BASE -+ pr_warn("irqpoll boot option not supported w/ CONFIG_PREEMPT_RT_BASE\n"); -+ return 1; -+#endif - irqfixup = 2; - printk(KERN_WARNING "Misrouted IRQ fixup and polling support " - "enabled\n"); -diff --git a/kernel/irq_work.c b/kernel/irq_work.c -index bcf107c..2899ba0 100644 ---- a/kernel/irq_work.c -+++ b/kernel/irq_work.c -@@ -17,6 +17,7 @@ - #include <linux/cpu.h> - #include <linux/notifier.h> - #include <linux/smp.h> -+#include <linux/interrupt.h> - #include <asm/processor.h> - - -@@ -65,6 +66,8 @@ void __weak arch_irq_work_raise(void) - */ - bool irq_work_queue_on(struct irq_work *work, int cpu) - { -+ struct llist_head *list; -+ - /* All work should have been flushed before going offline */ - WARN_ON_ONCE(cpu_is_offline(cpu)); - -@@ -75,7 +78,12 @@ bool irq_work_queue_on(struct irq_work *work, int cpu) - if (!irq_work_claim(work)) - return false; - -- if (llist_add(&work->llnode, &per_cpu(raised_list, cpu))) -+ if (IS_ENABLED(CONFIG_PREEMPT_RT_FULL) && !(work->flags & IRQ_WORK_HARD_IRQ)) -+ list = &per_cpu(lazy_list, cpu); -+ else -+ list = &per_cpu(raised_list, cpu); -+ -+ if (llist_add(&work->llnode, list)) - arch_send_call_function_single_ipi(cpu); - - return true; -@@ -86,6 +94,9 @@ EXPORT_SYMBOL_GPL(irq_work_queue_on); - /* Enqueue the irq work @work on the current CPU */ - bool irq_work_queue(struct irq_work *work) - { -+ struct llist_head *list; -+ bool lazy_work, realtime = IS_ENABLED(CONFIG_PREEMPT_RT_FULL); -+ - /* Only queue if not already pending */ - if (!irq_work_claim(work)) - return false; -@@ -93,13 +104,15 @@ bool irq_work_queue(struct irq_work *work) - /* Queue the entry and raise the IPI if needed. */ - preempt_disable(); - -- /* If the work is "lazy", handle it from next tick if any */ -- if (work->flags & IRQ_WORK_LAZY) { -- if (llist_add(&work->llnode, this_cpu_ptr(&lazy_list)) && -- tick_nohz_tick_stopped()) -- arch_irq_work_raise(); -- } else { -- if (llist_add(&work->llnode, this_cpu_ptr(&raised_list))) -+ lazy_work = work->flags & IRQ_WORK_LAZY; -+ -+ if (lazy_work || (realtime && !(work->flags & IRQ_WORK_HARD_IRQ))) -+ list = this_cpu_ptr(&lazy_list); -+ else -+ list = this_cpu_ptr(&raised_list); -+ -+ if (llist_add(&work->llnode, list)) { -+ if (!lazy_work || tick_nohz_tick_stopped()) - arch_irq_work_raise(); - } - -@@ -116,9 +129,8 @@ bool irq_work_needs_cpu(void) - raised = this_cpu_ptr(&raised_list); - lazy = this_cpu_ptr(&lazy_list); - -- if (llist_empty(raised) || arch_irq_work_has_interrupt()) -- if (llist_empty(lazy)) -- return false; -+ if (llist_empty(raised) && llist_empty(lazy)) -+ return false; - - /* All work should have been flushed before going offline */ - WARN_ON_ONCE(cpu_is_offline(smp_processor_id())); -@@ -132,7 +144,7 @@ static void irq_work_run_list(struct llist_head *list) - struct irq_work *work; - struct llist_node *llnode; - -- BUG_ON(!irqs_disabled()); -+ BUG_ON_NONRT(!irqs_disabled()); - - if (llist_empty(list)) - return; -@@ -169,7 +181,16 @@ static void irq_work_run_list(struct llist_head *list) - void irq_work_run(void) - { - irq_work_run_list(this_cpu_ptr(&raised_list)); -- irq_work_run_list(this_cpu_ptr(&lazy_list)); -+ if (IS_ENABLED(CONFIG_PREEMPT_RT_FULL)) { -+ /* -+ * NOTE: we raise softirq via IPI for safety, -+ * and execute in irq_work_tick() to move the -+ * overhead from hard to soft irq context. -+ */ -+ if (!llist_empty(this_cpu_ptr(&lazy_list))) -+ raise_softirq(TIMER_SOFTIRQ); -+ } else -+ irq_work_run_list(this_cpu_ptr(&lazy_list)); - } - EXPORT_SYMBOL_GPL(irq_work_run); - -@@ -179,8 +200,17 @@ void irq_work_tick(void) - - if (!llist_empty(raised) && !arch_irq_work_has_interrupt()) - irq_work_run_list(raised); -+ -+ if (!IS_ENABLED(CONFIG_PREEMPT_RT_FULL)) -+ irq_work_run_list(this_cpu_ptr(&lazy_list)); -+} -+ -+#if defined(CONFIG_IRQ_WORK) && defined(CONFIG_PREEMPT_RT_FULL) -+void irq_work_tick_soft(void) -+{ - irq_work_run_list(this_cpu_ptr(&lazy_list)); - } -+#endif - - /* - * Synchronize against the irq_work @entry, ensures the entry is not -diff --git a/kernel/ksysfs.c b/kernel/ksysfs.c -index 152da4a..9fe4635 100644 ---- a/kernel/ksysfs.c -+++ b/kernel/ksysfs.c -@@ -136,6 +136,15 @@ KERNEL_ATTR_RO(vmcoreinfo); - - #endif /* CONFIG_KEXEC_CORE */ - -+#if defined(CONFIG_PREEMPT_RT_FULL) -+static ssize_t realtime_show(struct kobject *kobj, -+ struct kobj_attribute *attr, char *buf) -+{ -+ return sprintf(buf, "%d\n", 1); -+} -+KERNEL_ATTR_RO(realtime); -+#endif -+ - /* whether file capabilities are enabled */ - static ssize_t fscaps_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) -@@ -225,6 +234,9 @@ static struct attribute * kernel_attrs[] = { - &rcu_expedited_attr.attr, - &rcu_normal_attr.attr, - #endif -+#ifdef CONFIG_PREEMPT_RT_FULL -+ &realtime_attr.attr, -+#endif - NULL - }; - -diff --git a/kernel/locking/Makefile b/kernel/locking/Makefile -index 31322a4..c6bba92 100644 ---- a/kernel/locking/Makefile -+++ b/kernel/locking/Makefile -@@ -2,7 +2,7 @@ - # and is generally not a function of system call inputs. - KCOV_INSTRUMENT := n - --obj-y += mutex.o semaphore.o rwsem.o percpu-rwsem.o -+obj-y += semaphore.o percpu-rwsem.o - - ifdef CONFIG_FUNCTION_TRACER - CFLAGS_REMOVE_lockdep.o = $(CC_FLAGS_FTRACE) -@@ -11,7 +11,11 @@ CFLAGS_REMOVE_mutex-debug.o = $(CC_FLAGS_FTRACE) - CFLAGS_REMOVE_rtmutex-debug.o = $(CC_FLAGS_FTRACE) - endif - -+ifneq ($(CONFIG_PREEMPT_RT_FULL),y) -+obj-y += mutex.o - obj-$(CONFIG_DEBUG_MUTEXES) += mutex-debug.o -+obj-y += rwsem.o -+endif - obj-$(CONFIG_LOCKDEP) += lockdep.o - ifeq ($(CONFIG_PROC_FS),y) - obj-$(CONFIG_LOCKDEP) += lockdep_proc.o -@@ -25,7 +29,10 @@ obj-$(CONFIG_RT_MUTEXES) += rtmutex.o - obj-$(CONFIG_DEBUG_RT_MUTEXES) += rtmutex-debug.o - obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock.o - obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock_debug.o -+ifneq ($(CONFIG_PREEMPT_RT_FULL),y) - obj-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o - obj-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem-xadd.o -+endif -+obj-$(CONFIG_PREEMPT_RT_FULL) += rt.o - obj-$(CONFIG_QUEUED_RWLOCKS) += qrwlock.o - obj-$(CONFIG_LOCK_TORTURE_TEST) += locktorture.o -diff --git a/kernel/locking/lglock.c b/kernel/locking/lglock.c -index 951cfcd..57e0ea7 100644 ---- a/kernel/locking/lglock.c -+++ b/kernel/locking/lglock.c -@@ -4,6 +4,15 @@ - #include <linux/cpu.h> - #include <linux/string.h> - -+#ifndef CONFIG_PREEMPT_RT_FULL -+# define lg_lock_ptr arch_spinlock_t -+# define lg_do_lock(l) arch_spin_lock(l) -+# define lg_do_unlock(l) arch_spin_unlock(l) -+#else -+# define lg_lock_ptr struct rt_mutex -+# define lg_do_lock(l) __rt_spin_lock__no_mg(l) -+# define lg_do_unlock(l) __rt_spin_unlock(l) -+#endif - /* - * Note there is no uninit, so lglocks cannot be defined in - * modules (but it's fine to use them from there) -@@ -12,51 +21,60 @@ - - void lg_lock_init(struct lglock *lg, char *name) - { -+#ifdef CONFIG_PREEMPT_RT_FULL -+ int i; -+ -+ for_each_possible_cpu(i) { -+ struct rt_mutex *lock = per_cpu_ptr(lg->lock, i); -+ -+ rt_mutex_init(lock); -+ } -+#endif - LOCKDEP_INIT_MAP(&lg->lock_dep_map, name, &lg->lock_key, 0); - } - EXPORT_SYMBOL(lg_lock_init); - - void lg_local_lock(struct lglock *lg) - { -- arch_spinlock_t *lock; -+ lg_lock_ptr *lock; - -- preempt_disable(); -+ migrate_disable(); - lock_acquire_shared(&lg->lock_dep_map, 0, 0, NULL, _RET_IP_); - lock = this_cpu_ptr(lg->lock); -- arch_spin_lock(lock); -+ lg_do_lock(lock); - } - EXPORT_SYMBOL(lg_local_lock); - - void lg_local_unlock(struct lglock *lg) - { -- arch_spinlock_t *lock; -+ lg_lock_ptr *lock; - - lock_release(&lg->lock_dep_map, 1, _RET_IP_); - lock = this_cpu_ptr(lg->lock); -- arch_spin_unlock(lock); -- preempt_enable(); -+ lg_do_unlock(lock); -+ migrate_enable(); - } - EXPORT_SYMBOL(lg_local_unlock); - - void lg_local_lock_cpu(struct lglock *lg, int cpu) - { -- arch_spinlock_t *lock; -+ lg_lock_ptr *lock; - -- preempt_disable(); -+ preempt_disable_nort(); - lock_acquire_shared(&lg->lock_dep_map, 0, 0, NULL, _RET_IP_); - lock = per_cpu_ptr(lg->lock, cpu); -- arch_spin_lock(lock); -+ lg_do_lock(lock); - } - EXPORT_SYMBOL(lg_local_lock_cpu); - - void lg_local_unlock_cpu(struct lglock *lg, int cpu) - { -- arch_spinlock_t *lock; -+ lg_lock_ptr *lock; - - lock_release(&lg->lock_dep_map, 1, _RET_IP_); - lock = per_cpu_ptr(lg->lock, cpu); -- arch_spin_unlock(lock); -- preempt_enable(); -+ lg_do_unlock(lock); -+ preempt_enable_nort(); - } - EXPORT_SYMBOL(lg_local_unlock_cpu); - -@@ -68,30 +86,30 @@ void lg_double_lock(struct lglock *lg, int cpu1, int cpu2) - if (cpu2 < cpu1) - swap(cpu1, cpu2); - -- preempt_disable(); -+ preempt_disable_nort(); - lock_acquire_shared(&lg->lock_dep_map, 0, 0, NULL, _RET_IP_); -- arch_spin_lock(per_cpu_ptr(lg->lock, cpu1)); -- arch_spin_lock(per_cpu_ptr(lg->lock, cpu2)); -+ lg_do_lock(per_cpu_ptr(lg->lock, cpu1)); -+ lg_do_lock(per_cpu_ptr(lg->lock, cpu2)); - } - - void lg_double_unlock(struct lglock *lg, int cpu1, int cpu2) - { - lock_release(&lg->lock_dep_map, 1, _RET_IP_); -- arch_spin_unlock(per_cpu_ptr(lg->lock, cpu1)); -- arch_spin_unlock(per_cpu_ptr(lg->lock, cpu2)); -- preempt_enable(); -+ lg_do_unlock(per_cpu_ptr(lg->lock, cpu1)); -+ lg_do_unlock(per_cpu_ptr(lg->lock, cpu2)); -+ preempt_enable_nort(); - } - - void lg_global_lock(struct lglock *lg) - { - int i; - -- preempt_disable(); -+ preempt_disable_nort(); - lock_acquire_exclusive(&lg->lock_dep_map, 0, 0, NULL, _RET_IP_); - for_each_possible_cpu(i) { -- arch_spinlock_t *lock; -+ lg_lock_ptr *lock; - lock = per_cpu_ptr(lg->lock, i); -- arch_spin_lock(lock); -+ lg_do_lock(lock); - } - } - EXPORT_SYMBOL(lg_global_lock); -@@ -102,10 +120,35 @@ void lg_global_unlock(struct lglock *lg) - - lock_release(&lg->lock_dep_map, 1, _RET_IP_); - for_each_possible_cpu(i) { -- arch_spinlock_t *lock; -+ lg_lock_ptr *lock; - lock = per_cpu_ptr(lg->lock, i); -- arch_spin_unlock(lock); -+ lg_do_unlock(lock); - } -- preempt_enable(); -+ preempt_enable_nort(); - } - EXPORT_SYMBOL(lg_global_unlock); -+ -+#ifdef CONFIG_PREEMPT_RT_FULL -+/* -+ * HACK: If you use this, you get to keep the pieces. -+ * Used in queue_stop_cpus_work() when stop machinery -+ * is called from inactive CPU, so we can't schedule. -+ */ -+# define lg_do_trylock_relax(l) \ -+ do { \ -+ while (!__rt_spin_trylock(l)) \ -+ cpu_relax(); \ -+ } while (0) -+ -+void lg_global_trylock_relax(struct lglock *lg) -+{ -+ int i; -+ -+ lock_acquire_exclusive(&lg->lock_dep_map, 0, 0, NULL, _RET_IP_); -+ for_each_possible_cpu(i) { -+ lg_lock_ptr *lock; -+ lock = per_cpu_ptr(lg->lock, i); -+ lg_do_trylock_relax(lock); -+ } -+} -+#endif -diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c -index 78c1c0e..839175a 100644 ---- a/kernel/locking/lockdep.c -+++ b/kernel/locking/lockdep.c -@@ -3648,6 +3648,7 @@ static void check_flags(unsigned long flags) - } - } - -+#ifndef CONFIG_PREEMPT_RT_FULL - /* - * We dont accurately track softirq state in e.g. - * hardirq contexts (such as on 4KSTACKS), so only -@@ -3662,6 +3663,7 @@ static void check_flags(unsigned long flags) - DEBUG_LOCKS_WARN_ON(!current->softirqs_enabled); - } - } -+#endif - - if (!debug_locks) - print_irqtrace_events(current); -diff --git a/kernel/locking/locktorture.c b/kernel/locking/locktorture.c -index 8ef1919..291fc19 100644 ---- a/kernel/locking/locktorture.c -+++ b/kernel/locking/locktorture.c -@@ -26,7 +26,6 @@ - #include <linux/kthread.h> - #include <linux/sched/rt.h> - #include <linux/spinlock.h> --#include <linux/rwlock.h> - #include <linux/mutex.h> - #include <linux/rwsem.h> - #include <linux/smp.h> -diff --git a/kernel/locking/rt.c b/kernel/locking/rt.c -new file mode 100644 -index 0000000..d4ab61c ---- /dev/null -+++ b/kernel/locking/rt.c -@@ -0,0 +1,474 @@ -+/* -+ * kernel/rt.c -+ * -+ * Real-Time Preemption Support -+ * -+ * started by Ingo Molnar: -+ * -+ * Copyright (C) 2004-2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com> -+ * Copyright (C) 2006, Timesys Corp., Thomas Gleixner <tglx@timesys.com> -+ * -+ * historic credit for proving that Linux spinlocks can be implemented via -+ * RT-aware mutexes goes to many people: The Pmutex project (Dirk Grambow -+ * and others) who prototyped it on 2.4 and did lots of comparative -+ * research and analysis; TimeSys, for proving that you can implement a -+ * fully preemptible kernel via the use of IRQ threading and mutexes; -+ * Bill Huey for persuasively arguing on lkml that the mutex model is the -+ * right one; and to MontaVista, who ported pmutexes to 2.6. -+ * -+ * This code is a from-scratch implementation and is not based on pmutexes, -+ * but the idea of converting spinlocks to mutexes is used here too. -+ * -+ * lock debugging, locking tree, deadlock detection: -+ * -+ * Copyright (C) 2004, LynuxWorks, Inc., Igor Manyilov, Bill Huey -+ * Released under the General Public License (GPL). -+ * -+ * Includes portions of the generic R/W semaphore implementation from: -+ * -+ * Copyright (c) 2001 David Howells (dhowells@redhat.com). -+ * - Derived partially from idea by Andrea Arcangeli <andrea@suse.de> -+ * - Derived also from comments by Linus -+ * -+ * Pending ownership of locks and ownership stealing: -+ * -+ * Copyright (C) 2005, Kihon Technologies Inc., Steven Rostedt -+ * -+ * (also by Steven Rostedt) -+ * - Converted single pi_lock to individual task locks. -+ * -+ * By Esben Nielsen: -+ * Doing priority inheritance with help of the scheduler. -+ * -+ * Copyright (C) 2006, Timesys Corp., Thomas Gleixner <tglx@timesys.com> -+ * - major rework based on Esben Nielsens initial patch -+ * - replaced thread_info references by task_struct refs -+ * - removed task->pending_owner dependency -+ * - BKL drop/reacquire for semaphore style locks to avoid deadlocks -+ * in the scheduler return path as discussed with Steven Rostedt -+ * -+ * Copyright (C) 2006, Kihon Technologies Inc. -+ * Steven Rostedt <rostedt@goodmis.org> -+ * - debugged and patched Thomas Gleixner's rework. -+ * - added back the cmpxchg to the rework. -+ * - turned atomic require back on for SMP. -+ */ -+ -+#include <linux/spinlock.h> -+#include <linux/rtmutex.h> -+#include <linux/sched.h> -+#include <linux/delay.h> -+#include <linux/module.h> -+#include <linux/kallsyms.h> -+#include <linux/syscalls.h> -+#include <linux/interrupt.h> -+#include <linux/plist.h> -+#include <linux/fs.h> -+#include <linux/futex.h> -+#include <linux/hrtimer.h> -+ -+#include "rtmutex_common.h" -+ -+/* -+ * struct mutex functions -+ */ -+void __mutex_do_init(struct mutex *mutex, const char *name, -+ struct lock_class_key *key) -+{ -+#ifdef CONFIG_DEBUG_LOCK_ALLOC -+ /* -+ * Make sure we are not reinitializing a held lock: -+ */ -+ debug_check_no_locks_freed((void *)mutex, sizeof(*mutex)); -+ lockdep_init_map(&mutex->dep_map, name, key, 0); -+#endif -+ mutex->lock.save_state = 0; -+} -+EXPORT_SYMBOL(__mutex_do_init); -+ -+void __lockfunc _mutex_lock(struct mutex *lock) -+{ -+ mutex_acquire(&lock->dep_map, 0, 0, _RET_IP_); -+ rt_mutex_lock(&lock->lock); -+} -+EXPORT_SYMBOL(_mutex_lock); -+ -+int __lockfunc _mutex_lock_interruptible(struct mutex *lock) -+{ -+ int ret; -+ -+ mutex_acquire(&lock->dep_map, 0, 0, _RET_IP_); -+ ret = rt_mutex_lock_interruptible(&lock->lock); -+ if (ret) -+ mutex_release(&lock->dep_map, 1, _RET_IP_); -+ return ret; -+} -+EXPORT_SYMBOL(_mutex_lock_interruptible); -+ -+int __lockfunc _mutex_lock_killable(struct mutex *lock) -+{ -+ int ret; -+ -+ mutex_acquire(&lock->dep_map, 0, 0, _RET_IP_); -+ ret = rt_mutex_lock_killable(&lock->lock); -+ if (ret) -+ mutex_release(&lock->dep_map, 1, _RET_IP_); -+ return ret; -+} -+EXPORT_SYMBOL(_mutex_lock_killable); -+ -+#ifdef CONFIG_DEBUG_LOCK_ALLOC -+void __lockfunc _mutex_lock_nested(struct mutex *lock, int subclass) -+{ -+ mutex_acquire_nest(&lock->dep_map, subclass, 0, NULL, _RET_IP_); -+ rt_mutex_lock(&lock->lock); -+} -+EXPORT_SYMBOL(_mutex_lock_nested); -+ -+void __lockfunc _mutex_lock_nest_lock(struct mutex *lock, struct lockdep_map *nest) -+{ -+ mutex_acquire_nest(&lock->dep_map, 0, 0, nest, _RET_IP_); -+ rt_mutex_lock(&lock->lock); -+} -+EXPORT_SYMBOL(_mutex_lock_nest_lock); -+ -+int __lockfunc _mutex_lock_interruptible_nested(struct mutex *lock, int subclass) -+{ -+ int ret; -+ -+ mutex_acquire_nest(&lock->dep_map, subclass, 0, NULL, _RET_IP_); -+ ret = rt_mutex_lock_interruptible(&lock->lock); -+ if (ret) -+ mutex_release(&lock->dep_map, 1, _RET_IP_); -+ return ret; -+} -+EXPORT_SYMBOL(_mutex_lock_interruptible_nested); -+ -+int __lockfunc _mutex_lock_killable_nested(struct mutex *lock, int subclass) -+{ -+ int ret; -+ -+ mutex_acquire(&lock->dep_map, subclass, 0, _RET_IP_); -+ ret = rt_mutex_lock_killable(&lock->lock); -+ if (ret) -+ mutex_release(&lock->dep_map, 1, _RET_IP_); -+ return ret; -+} -+EXPORT_SYMBOL(_mutex_lock_killable_nested); -+#endif -+ -+int __lockfunc _mutex_trylock(struct mutex *lock) -+{ -+ int ret = rt_mutex_trylock(&lock->lock); -+ -+ if (ret) -+ mutex_acquire(&lock->dep_map, 0, 1, _RET_IP_); -+ -+ return ret; -+} -+EXPORT_SYMBOL(_mutex_trylock); -+ -+void __lockfunc _mutex_unlock(struct mutex *lock) -+{ -+ mutex_release(&lock->dep_map, 1, _RET_IP_); -+ rt_mutex_unlock(&lock->lock); -+} -+EXPORT_SYMBOL(_mutex_unlock); -+ -+/* -+ * rwlock_t functions -+ */ -+int __lockfunc rt_write_trylock(rwlock_t *rwlock) -+{ -+ int ret; -+ -+ migrate_disable(); -+ ret = rt_mutex_trylock(&rwlock->lock); -+ if (ret) -+ rwlock_acquire(&rwlock->dep_map, 0, 1, _RET_IP_); -+ else -+ migrate_enable(); -+ -+ return ret; -+} -+EXPORT_SYMBOL(rt_write_trylock); -+ -+int __lockfunc rt_write_trylock_irqsave(rwlock_t *rwlock, unsigned long *flags) -+{ -+ int ret; -+ -+ *flags = 0; -+ ret = rt_write_trylock(rwlock); -+ return ret; -+} -+EXPORT_SYMBOL(rt_write_trylock_irqsave); -+ -+int __lockfunc rt_read_trylock(rwlock_t *rwlock) -+{ -+ struct rt_mutex *lock = &rwlock->lock; -+ int ret = 1; -+ -+ /* -+ * recursive read locks succeed when current owns the lock, -+ * but not when read_depth == 0 which means that the lock is -+ * write locked. -+ */ -+ if (rt_mutex_owner(lock) != current) { -+ migrate_disable(); -+ ret = rt_mutex_trylock(lock); -+ if (ret) -+ rwlock_acquire(&rwlock->dep_map, 0, 1, _RET_IP_); -+ else -+ migrate_enable(); -+ -+ } else if (!rwlock->read_depth) { -+ ret = 0; -+ } -+ -+ if (ret) -+ rwlock->read_depth++; -+ -+ return ret; -+} -+EXPORT_SYMBOL(rt_read_trylock); -+ -+void __lockfunc rt_write_lock(rwlock_t *rwlock) -+{ -+ rwlock_acquire(&rwlock->dep_map, 0, 0, _RET_IP_); -+ __rt_spin_lock(&rwlock->lock); -+} -+EXPORT_SYMBOL(rt_write_lock); -+ -+void __lockfunc rt_read_lock(rwlock_t *rwlock) -+{ -+ struct rt_mutex *lock = &rwlock->lock; -+ -+ -+ /* -+ * recursive read locks succeed when current owns the lock -+ */ -+ if (rt_mutex_owner(lock) != current) { -+ rwlock_acquire(&rwlock->dep_map, 0, 0, _RET_IP_); -+ __rt_spin_lock(lock); -+ } -+ rwlock->read_depth++; -+} -+ -+EXPORT_SYMBOL(rt_read_lock); -+ -+void __lockfunc rt_write_unlock(rwlock_t *rwlock) -+{ -+ /* NOTE: we always pass in '1' for nested, for simplicity */ -+ rwlock_release(&rwlock->dep_map, 1, _RET_IP_); -+ __rt_spin_unlock(&rwlock->lock); -+ migrate_enable(); -+} -+EXPORT_SYMBOL(rt_write_unlock); -+ -+void __lockfunc rt_read_unlock(rwlock_t *rwlock) -+{ -+ /* Release the lock only when read_depth is down to 0 */ -+ if (--rwlock->read_depth == 0) { -+ rwlock_release(&rwlock->dep_map, 1, _RET_IP_); -+ __rt_spin_unlock(&rwlock->lock); -+ migrate_enable(); -+ } -+} -+EXPORT_SYMBOL(rt_read_unlock); -+ -+unsigned long __lockfunc rt_write_lock_irqsave(rwlock_t *rwlock) -+{ -+ rt_write_lock(rwlock); -+ -+ return 0; -+} -+EXPORT_SYMBOL(rt_write_lock_irqsave); -+ -+unsigned long __lockfunc rt_read_lock_irqsave(rwlock_t *rwlock) -+{ -+ rt_read_lock(rwlock); -+ -+ return 0; -+} -+EXPORT_SYMBOL(rt_read_lock_irqsave); -+ -+void __rt_rwlock_init(rwlock_t *rwlock, char *name, struct lock_class_key *key) -+{ -+#ifdef CONFIG_DEBUG_LOCK_ALLOC -+ /* -+ * Make sure we are not reinitializing a held lock: -+ */ -+ debug_check_no_locks_freed((void *)rwlock, sizeof(*rwlock)); -+ lockdep_init_map(&rwlock->dep_map, name, key, 0); -+#endif -+ rwlock->lock.save_state = 1; -+ rwlock->read_depth = 0; -+} -+EXPORT_SYMBOL(__rt_rwlock_init); -+ -+/* -+ * rw_semaphores -+ */ -+ -+void rt_up_write(struct rw_semaphore *rwsem) -+{ -+ rwsem_release(&rwsem->dep_map, 1, _RET_IP_); -+ rt_mutex_unlock(&rwsem->lock); -+} -+EXPORT_SYMBOL(rt_up_write); -+ -+void __rt_up_read(struct rw_semaphore *rwsem) -+{ -+ if (--rwsem->read_depth == 0) -+ rt_mutex_unlock(&rwsem->lock); -+} -+ -+void rt_up_read(struct rw_semaphore *rwsem) -+{ -+ rwsem_release(&rwsem->dep_map, 1, _RET_IP_); -+ __rt_up_read(rwsem); -+} -+EXPORT_SYMBOL(rt_up_read); -+ -+/* -+ * downgrade a write lock into a read lock -+ * - just wake up any readers at the front of the queue -+ */ -+void rt_downgrade_write(struct rw_semaphore *rwsem) -+{ -+ BUG_ON(rt_mutex_owner(&rwsem->lock) != current); -+ rwsem->read_depth = 1; -+} -+EXPORT_SYMBOL(rt_downgrade_write); -+ -+int rt_down_write_trylock(struct rw_semaphore *rwsem) -+{ -+ int ret = rt_mutex_trylock(&rwsem->lock); -+ -+ if (ret) -+ rwsem_acquire(&rwsem->dep_map, 0, 1, _RET_IP_); -+ return ret; -+} -+EXPORT_SYMBOL(rt_down_write_trylock); -+ -+void rt_down_write(struct rw_semaphore *rwsem) -+{ -+ rwsem_acquire(&rwsem->dep_map, 0, 0, _RET_IP_); -+ rt_mutex_lock(&rwsem->lock); -+} -+EXPORT_SYMBOL(rt_down_write); -+ -+void rt_down_write_nested(struct rw_semaphore *rwsem, int subclass) -+{ -+ rwsem_acquire(&rwsem->dep_map, subclass, 0, _RET_IP_); -+ rt_mutex_lock(&rwsem->lock); -+} -+EXPORT_SYMBOL(rt_down_write_nested); -+ -+void rt_down_write_nested_lock(struct rw_semaphore *rwsem, -+ struct lockdep_map *nest) -+{ -+ rwsem_acquire_nest(&rwsem->dep_map, 0, 0, nest, _RET_IP_); -+ rt_mutex_lock(&rwsem->lock); -+} -+EXPORT_SYMBOL(rt_down_write_nested_lock); -+ -+int rt__down_read_trylock(struct rw_semaphore *rwsem) -+{ -+ struct rt_mutex *lock = &rwsem->lock; -+ int ret = 1; -+ -+ /* -+ * recursive read locks succeed when current owns the rwsem, -+ * but not when read_depth == 0 which means that the rwsem is -+ * write locked. -+ */ -+ if (rt_mutex_owner(lock) != current) -+ ret = rt_mutex_trylock(&rwsem->lock); -+ else if (!rwsem->read_depth) -+ ret = 0; -+ -+ if (ret) -+ rwsem->read_depth++; -+ return ret; -+ -+} -+ -+int rt_down_read_trylock(struct rw_semaphore *rwsem) -+{ -+ int ret; -+ -+ ret = rt__down_read_trylock(rwsem); -+ if (ret) -+ rwsem_acquire(&rwsem->dep_map, 0, 1, _RET_IP_); -+ -+ return ret; -+} -+EXPORT_SYMBOL(rt_down_read_trylock); -+ -+void rt__down_read(struct rw_semaphore *rwsem) -+{ -+ struct rt_mutex *lock = &rwsem->lock; -+ -+ if (rt_mutex_owner(lock) != current) -+ rt_mutex_lock(&rwsem->lock); -+ rwsem->read_depth++; -+} -+EXPORT_SYMBOL(rt__down_read); -+ -+static void __rt_down_read(struct rw_semaphore *rwsem, int subclass) -+{ -+ rwsem_acquire_read(&rwsem->dep_map, subclass, 0, _RET_IP_); -+ rt__down_read(rwsem); -+} -+ -+void rt_down_read(struct rw_semaphore *rwsem) -+{ -+ __rt_down_read(rwsem, 0); -+} -+EXPORT_SYMBOL(rt_down_read); -+ -+void rt_down_read_nested(struct rw_semaphore *rwsem, int subclass) -+{ -+ __rt_down_read(rwsem, subclass); -+} -+EXPORT_SYMBOL(rt_down_read_nested); -+ -+void __rt_rwsem_init(struct rw_semaphore *rwsem, const char *name, -+ struct lock_class_key *key) -+{ -+#ifdef CONFIG_DEBUG_LOCK_ALLOC -+ /* -+ * Make sure we are not reinitializing a held lock: -+ */ -+ debug_check_no_locks_freed((void *)rwsem, sizeof(*rwsem)); -+ lockdep_init_map(&rwsem->dep_map, name, key, 0); -+#endif -+ rwsem->read_depth = 0; -+ rwsem->lock.save_state = 0; -+} -+EXPORT_SYMBOL(__rt_rwsem_init); -+ -+/** -+ * atomic_dec_and_mutex_lock - return holding mutex if we dec to 0 -+ * @cnt: the atomic which we are to dec -+ * @lock: the mutex to return holding if we dec to 0 -+ * -+ * return true and hold lock if we dec to 0, return false otherwise -+ */ -+int atomic_dec_and_mutex_lock(atomic_t *cnt, struct mutex *lock) -+{ -+ /* dec if we can't possibly hit 0 */ -+ if (atomic_add_unless(cnt, -1, 1)) -+ return 0; -+ /* we might hit 0, so take the lock */ -+ mutex_lock(lock); -+ if (!atomic_dec_and_test(cnt)) { -+ /* when we actually did the dec, we didn't hit 0 */ -+ mutex_unlock(lock); -+ return 0; -+ } -+ /* we hit 0, and we hold the lock */ -+ return 1; -+} -+EXPORT_SYMBOL(atomic_dec_and_mutex_lock); -diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c -index 3e74660..6697100 100644 ---- a/kernel/locking/rtmutex.c -+++ b/kernel/locking/rtmutex.c -@@ -7,6 +7,11 @@ - * Copyright (C) 2005-2006 Timesys Corp., Thomas Gleixner <tglx@timesys.com> - * Copyright (C) 2005 Kihon Technologies Inc., Steven Rostedt - * Copyright (C) 2006 Esben Nielsen -+ * Adaptive Spinlocks: -+ * Copyright (C) 2008 Novell, Inc., Gregory Haskins, Sven Dietrich, -+ * and Peter Morreale, -+ * Adaptive Spinlocks simplification: -+ * Copyright (C) 2008 Red Hat, Inc., Steven Rostedt <srostedt@redhat.com> - * - * See Documentation/locking/rt-mutex-design.txt for details. - */ -@@ -16,6 +21,7 @@ - #include <linux/sched/rt.h> - #include <linux/sched/deadline.h> - #include <linux/timer.h> -+#include <linux/ww_mutex.h> - - #include "rtmutex_common.h" - -@@ -69,6 +75,12 @@ static void fixup_rt_mutex_waiters(struct rt_mutex *lock) - clear_rt_mutex_waiters(lock); - } - -+static int rt_mutex_real_waiter(struct rt_mutex_waiter *waiter) -+{ -+ return waiter && waiter != PI_WAKEUP_INPROGRESS && -+ waiter != PI_REQUEUE_INPROGRESS; -+} -+ - /* - * We can speed up the acquire/release, if there's no debugging state to be - * set up. -@@ -350,6 +362,14 @@ static bool rt_mutex_cond_detect_deadlock(struct rt_mutex_waiter *waiter, - return debug_rt_mutex_detect_deadlock(waiter, chwalk); - } - -+static void rt_mutex_wake_waiter(struct rt_mutex_waiter *waiter) -+{ -+ if (waiter->savestate) -+ wake_up_lock_sleeper(waiter->task); -+ else -+ wake_up_process(waiter->task); -+} -+ - /* - * Max number of times we'll walk the boosting chain: - */ -@@ -357,7 +377,8 @@ int max_lock_depth = 1024; - - static inline struct rt_mutex *task_blocked_on_lock(struct task_struct *p) - { -- return p->pi_blocked_on ? p->pi_blocked_on->lock : NULL; -+ return rt_mutex_real_waiter(p->pi_blocked_on) ? -+ p->pi_blocked_on->lock : NULL; - } - - /* -@@ -493,7 +514,7 @@ static int rt_mutex_adjust_prio_chain(struct task_struct *task, - * reached or the state of the chain has changed while we - * dropped the locks. - */ -- if (!waiter) -+ if (!rt_mutex_real_waiter(waiter)) - goto out_unlock_pi; - - /* -@@ -655,13 +676,16 @@ static int rt_mutex_adjust_prio_chain(struct task_struct *task, - * follow here. This is the end of the chain we are walking. - */ - if (!rt_mutex_owner(lock)) { -+ struct rt_mutex_waiter *lock_top_waiter; -+ - /* - * If the requeue [7] above changed the top waiter, - * then we need to wake the new top waiter up to try - * to get the lock. - */ -- if (prerequeue_top_waiter != rt_mutex_top_waiter(lock)) -- wake_up_process(rt_mutex_top_waiter(lock)->task); -+ lock_top_waiter = rt_mutex_top_waiter(lock); -+ if (prerequeue_top_waiter != lock_top_waiter) -+ rt_mutex_wake_waiter(lock_top_waiter); - raw_spin_unlock_irq(&lock->wait_lock); - return 0; - } -@@ -754,6 +778,25 @@ static int rt_mutex_adjust_prio_chain(struct task_struct *task, - return ret; - } - -+ -+#define STEAL_NORMAL 0 -+#define STEAL_LATERAL 1 -+ -+/* -+ * Note that RT tasks are excluded from lateral-steals to prevent the -+ * introduction of an unbounded latency -+ */ -+static inline int lock_is_stealable(struct task_struct *task, -+ struct task_struct *pendowner, int mode) -+{ -+ if (mode == STEAL_NORMAL || rt_task(task)) { -+ if (task->prio >= pendowner->prio) -+ return 0; -+ } else if (task->prio > pendowner->prio) -+ return 0; -+ return 1; -+} -+ - /* - * Try to take an rt-mutex - * -@@ -764,8 +807,9 @@ static int rt_mutex_adjust_prio_chain(struct task_struct *task, - * @waiter: The waiter that is queued to the lock's wait tree if the - * callsite called task_blocked_on_lock(), otherwise NULL - */ --static int try_to_take_rt_mutex(struct rt_mutex *lock, struct task_struct *task, -- struct rt_mutex_waiter *waiter) -+static int __try_to_take_rt_mutex(struct rt_mutex *lock, -+ struct task_struct *task, -+ struct rt_mutex_waiter *waiter, int mode) - { - /* - * Before testing whether we can acquire @lock, we set the -@@ -802,8 +846,10 @@ static int try_to_take_rt_mutex(struct rt_mutex *lock, struct task_struct *task, - * If waiter is not the highest priority waiter of - * @lock, give up. - */ -- if (waiter != rt_mutex_top_waiter(lock)) -+ if (waiter != rt_mutex_top_waiter(lock)) { -+ /* XXX lock_is_stealable() ? */ - return 0; -+ } - - /* - * We can acquire the lock. Remove the waiter from the -@@ -821,14 +867,10 @@ static int try_to_take_rt_mutex(struct rt_mutex *lock, struct task_struct *task, - * not need to be dequeued. - */ - if (rt_mutex_has_waiters(lock)) { -- /* -- * If @task->prio is greater than or equal to -- * the top waiter priority (kernel view), -- * @task lost. -- */ -- if (task->prio >= rt_mutex_top_waiter(lock)->prio) -- return 0; -+ struct task_struct *pown = rt_mutex_top_waiter(lock)->task; - -+ if (task != pown && !lock_is_stealable(task, pown, mode)) -+ return 0; - /* - * The current top waiter stays enqueued. We - * don't have to change anything in the lock -@@ -877,6 +919,399 @@ takeit: - return 1; - } - -+#ifdef CONFIG_PREEMPT_RT_FULL -+/* -+ * preemptible spin_lock functions: -+ */ -+static inline void rt_spin_lock_fastlock(struct rt_mutex *lock, -+ void (*slowfn)(struct rt_mutex *lock, -+ bool mg_off), -+ bool do_mig_dis) -+{ -+ might_sleep_no_state_check(); -+ -+ if (do_mig_dis) -+ migrate_disable(); -+ -+ if (likely(rt_mutex_cmpxchg_acquire(lock, NULL, current))) -+ rt_mutex_deadlock_account_lock(lock, current); -+ else -+ slowfn(lock, do_mig_dis); -+} -+ -+static inline void rt_spin_lock_fastunlock(struct rt_mutex *lock, -+ void (*slowfn)(struct rt_mutex *lock)) -+{ -+ if (likely(rt_mutex_cmpxchg_release(lock, current, NULL))) -+ rt_mutex_deadlock_account_unlock(current); -+ else -+ slowfn(lock); -+} -+#ifdef CONFIG_SMP -+/* -+ * Note that owner is a speculative pointer and dereferencing relies -+ * on rcu_read_lock() and the check against the lock owner. -+ */ -+static int adaptive_wait(struct rt_mutex *lock, -+ struct task_struct *owner) -+{ -+ int res = 0; -+ -+ rcu_read_lock(); -+ for (;;) { -+ if (owner != rt_mutex_owner(lock)) -+ break; -+ /* -+ * Ensure that owner->on_cpu is dereferenced _after_ -+ * checking the above to be valid. -+ */ -+ barrier(); -+ if (!owner->on_cpu) { -+ res = 1; -+ break; -+ } -+ cpu_relax(); -+ } -+ rcu_read_unlock(); -+ return res; -+} -+#else -+static int adaptive_wait(struct rt_mutex *lock, -+ struct task_struct *orig_owner) -+{ -+ return 1; -+} -+#endif -+ -+static int task_blocks_on_rt_mutex(struct rt_mutex *lock, -+ struct rt_mutex_waiter *waiter, -+ struct task_struct *task, -+ enum rtmutex_chainwalk chwalk); -+/* -+ * Slow path lock function spin_lock style: this variant is very -+ * careful not to miss any non-lock wakeups. -+ * -+ * We store the current state under p->pi_lock in p->saved_state and -+ * the try_to_wake_up() code handles this accordingly. -+ */ -+static void noinline __sched rt_spin_lock_slowlock(struct rt_mutex *lock, -+ bool mg_off) -+{ -+ struct task_struct *lock_owner, *self = current; -+ struct rt_mutex_waiter waiter, *top_waiter; -+ unsigned long flags; -+ int ret; -+ -+ rt_mutex_init_waiter(&waiter, true); -+ -+ raw_spin_lock_irqsave(&lock->wait_lock, flags); -+ -+ if (__try_to_take_rt_mutex(lock, self, NULL, STEAL_LATERAL)) { -+ raw_spin_unlock_irqrestore(&lock->wait_lock, flags); -+ return; -+ } -+ -+ BUG_ON(rt_mutex_owner(lock) == self); -+ -+ /* -+ * We save whatever state the task is in and we'll restore it -+ * after acquiring the lock taking real wakeups into account -+ * as well. We are serialized via pi_lock against wakeups. See -+ * try_to_wake_up(). -+ */ -+ raw_spin_lock(&self->pi_lock); -+ self->saved_state = self->state; -+ __set_current_state_no_track(TASK_UNINTERRUPTIBLE); -+ raw_spin_unlock(&self->pi_lock); -+ -+ ret = task_blocks_on_rt_mutex(lock, &waiter, self, RT_MUTEX_MIN_CHAINWALK); -+ BUG_ON(ret); -+ -+ for (;;) { -+ /* Try to acquire the lock again. */ -+ if (__try_to_take_rt_mutex(lock, self, &waiter, STEAL_LATERAL)) -+ break; -+ -+ top_waiter = rt_mutex_top_waiter(lock); -+ lock_owner = rt_mutex_owner(lock); -+ -+ raw_spin_unlock_irqrestore(&lock->wait_lock, flags); -+ -+ debug_rt_mutex_print_deadlock(&waiter); -+ -+ if (top_waiter != &waiter || adaptive_wait(lock, lock_owner)) { -+ if (mg_off) -+ migrate_enable(); -+ schedule(); -+ if (mg_off) -+ migrate_disable(); -+ } -+ -+ raw_spin_lock_irqsave(&lock->wait_lock, flags); -+ -+ raw_spin_lock(&self->pi_lock); -+ __set_current_state_no_track(TASK_UNINTERRUPTIBLE); -+ raw_spin_unlock(&self->pi_lock); -+ } -+ -+ /* -+ * Restore the task state to current->saved_state. We set it -+ * to the original state above and the try_to_wake_up() code -+ * has possibly updated it when a real (non-rtmutex) wakeup -+ * happened while we were blocked. Clear saved_state so -+ * try_to_wakeup() does not get confused. -+ */ -+ raw_spin_lock(&self->pi_lock); -+ __set_current_state_no_track(self->saved_state); -+ self->saved_state = TASK_RUNNING; -+ raw_spin_unlock(&self->pi_lock); -+ -+ /* -+ * try_to_take_rt_mutex() sets the waiter bit -+ * unconditionally. We might have to fix that up: -+ */ -+ fixup_rt_mutex_waiters(lock); -+ -+ BUG_ON(rt_mutex_has_waiters(lock) && &waiter == rt_mutex_top_waiter(lock)); -+ BUG_ON(!RB_EMPTY_NODE(&waiter.tree_entry)); -+ -+ raw_spin_unlock_irqrestore(&lock->wait_lock, flags); -+ -+ debug_rt_mutex_free_waiter(&waiter); -+} -+ -+static void mark_wakeup_next_waiter(struct wake_q_head *wake_q, -+ struct wake_q_head *wake_sleeper_q, -+ struct rt_mutex *lock); -+/* -+ * Slow path to release a rt_mutex spin_lock style -+ */ -+static void noinline __sched rt_spin_lock_slowunlock(struct rt_mutex *lock) -+{ -+ unsigned long flags; -+ WAKE_Q(wake_q); -+ WAKE_Q(wake_sleeper_q); -+ -+ raw_spin_lock_irqsave(&lock->wait_lock, flags); -+ -+ debug_rt_mutex_unlock(lock); -+ -+ rt_mutex_deadlock_account_unlock(current); -+ -+ if (!rt_mutex_has_waiters(lock)) { -+ lock->owner = NULL; -+ raw_spin_unlock_irqrestore(&lock->wait_lock, flags); -+ return; -+ } -+ -+ mark_wakeup_next_waiter(&wake_q, &wake_sleeper_q, lock); -+ -+ raw_spin_unlock_irqrestore(&lock->wait_lock, flags); -+ wake_up_q(&wake_q); -+ wake_up_q_sleeper(&wake_sleeper_q); -+ -+ /* Undo pi boosting.when necessary */ -+ rt_mutex_adjust_prio(current); -+} -+ -+void __lockfunc rt_spin_lock__no_mg(spinlock_t *lock) -+{ -+ rt_spin_lock_fastlock(&lock->lock, rt_spin_lock_slowlock, false); -+ spin_acquire(&lock->dep_map, 0, 0, _RET_IP_); -+} -+EXPORT_SYMBOL(rt_spin_lock__no_mg); -+ -+void __lockfunc rt_spin_lock(spinlock_t *lock) -+{ -+ rt_spin_lock_fastlock(&lock->lock, rt_spin_lock_slowlock, true); -+ spin_acquire(&lock->dep_map, 0, 0, _RET_IP_); -+} -+EXPORT_SYMBOL(rt_spin_lock); -+ -+void __lockfunc __rt_spin_lock(struct rt_mutex *lock) -+{ -+ rt_spin_lock_fastlock(lock, rt_spin_lock_slowlock, true); -+} -+EXPORT_SYMBOL(__rt_spin_lock); -+ -+void __lockfunc __rt_spin_lock__no_mg(struct rt_mutex *lock) -+{ -+ rt_spin_lock_fastlock(lock, rt_spin_lock_slowlock, false); -+} -+EXPORT_SYMBOL(__rt_spin_lock__no_mg); -+ -+#ifdef CONFIG_DEBUG_LOCK_ALLOC -+void __lockfunc rt_spin_lock_nested(spinlock_t *lock, int subclass) -+{ -+ spin_acquire(&lock->dep_map, subclass, 0, _RET_IP_); -+ rt_spin_lock_fastlock(&lock->lock, rt_spin_lock_slowlock, true); -+} -+EXPORT_SYMBOL(rt_spin_lock_nested); -+#endif -+ -+void __lockfunc rt_spin_unlock__no_mg(spinlock_t *lock) -+{ -+ /* NOTE: we always pass in '1' for nested, for simplicity */ -+ spin_release(&lock->dep_map, 1, _RET_IP_); -+ rt_spin_lock_fastunlock(&lock->lock, rt_spin_lock_slowunlock); -+} -+EXPORT_SYMBOL(rt_spin_unlock__no_mg); -+ -+void __lockfunc rt_spin_unlock(spinlock_t *lock) -+{ -+ /* NOTE: we always pass in '1' for nested, for simplicity */ -+ spin_release(&lock->dep_map, 1, _RET_IP_); -+ rt_spin_lock_fastunlock(&lock->lock, rt_spin_lock_slowunlock); -+ migrate_enable(); -+} -+EXPORT_SYMBOL(rt_spin_unlock); -+ -+void __lockfunc __rt_spin_unlock(struct rt_mutex *lock) -+{ -+ rt_spin_lock_fastunlock(lock, rt_spin_lock_slowunlock); -+} -+EXPORT_SYMBOL(__rt_spin_unlock); -+ -+/* -+ * Wait for the lock to get unlocked: instead of polling for an unlock -+ * (like raw spinlocks do), we lock and unlock, to force the kernel to -+ * schedule if there's contention: -+ */ -+void __lockfunc rt_spin_unlock_wait(spinlock_t *lock) -+{ -+ spin_lock(lock); -+ spin_unlock(lock); -+} -+EXPORT_SYMBOL(rt_spin_unlock_wait); -+ -+int __lockfunc __rt_spin_trylock(struct rt_mutex *lock) -+{ -+ return rt_mutex_trylock(lock); -+} -+ -+int __lockfunc rt_spin_trylock__no_mg(spinlock_t *lock) -+{ -+ int ret; -+ -+ ret = rt_mutex_trylock(&lock->lock); -+ if (ret) -+ spin_acquire(&lock->dep_map, 0, 1, _RET_IP_); -+ return ret; -+} -+EXPORT_SYMBOL(rt_spin_trylock__no_mg); -+ -+int __lockfunc rt_spin_trylock(spinlock_t *lock) -+{ -+ int ret; -+ -+ migrate_disable(); -+ ret = rt_mutex_trylock(&lock->lock); -+ if (ret) -+ spin_acquire(&lock->dep_map, 0, 1, _RET_IP_); -+ else -+ migrate_enable(); -+ return ret; -+} -+EXPORT_SYMBOL(rt_spin_trylock); -+ -+int __lockfunc rt_spin_trylock_bh(spinlock_t *lock) -+{ -+ int ret; -+ -+ local_bh_disable(); -+ ret = rt_mutex_trylock(&lock->lock); -+ if (ret) { -+ migrate_disable(); -+ spin_acquire(&lock->dep_map, 0, 1, _RET_IP_); -+ } else -+ local_bh_enable(); -+ return ret; -+} -+EXPORT_SYMBOL(rt_spin_trylock_bh); -+ -+int __lockfunc rt_spin_trylock_irqsave(spinlock_t *lock, unsigned long *flags) -+{ -+ int ret; -+ -+ *flags = 0; -+ ret = rt_mutex_trylock(&lock->lock); -+ if (ret) { -+ migrate_disable(); -+ spin_acquire(&lock->dep_map, 0, 1, _RET_IP_); -+ } -+ return ret; -+} -+EXPORT_SYMBOL(rt_spin_trylock_irqsave); -+ -+int atomic_dec_and_spin_lock(atomic_t *atomic, spinlock_t *lock) -+{ -+ /* Subtract 1 from counter unless that drops it to 0 (ie. it was 1) */ -+ if (atomic_add_unless(atomic, -1, 1)) -+ return 0; -+ rt_spin_lock(lock); -+ if (atomic_dec_and_test(atomic)) -+ return 1; -+ rt_spin_unlock(lock); -+ return 0; -+} -+EXPORT_SYMBOL(atomic_dec_and_spin_lock); -+ -+ void -+__rt_spin_lock_init(spinlock_t *lock, char *name, struct lock_class_key *key) -+{ -+#ifdef CONFIG_DEBUG_LOCK_ALLOC -+ /* -+ * Make sure we are not reinitializing a held lock: -+ */ -+ debug_check_no_locks_freed((void *)lock, sizeof(*lock)); -+ lockdep_init_map(&lock->dep_map, name, key, 0); -+#endif -+} -+EXPORT_SYMBOL(__rt_spin_lock_init); -+ -+#endif /* PREEMPT_RT_FULL */ -+ -+#ifdef CONFIG_PREEMPT_RT_FULL -+ static inline int __sched -+__mutex_lock_check_stamp(struct rt_mutex *lock, struct ww_acquire_ctx *ctx) -+{ -+ struct ww_mutex *ww = container_of(lock, struct ww_mutex, base.lock); -+ struct ww_acquire_ctx *hold_ctx = ACCESS_ONCE(ww->ctx); -+ -+ if (!hold_ctx) -+ return 0; -+ -+ if (unlikely(ctx == hold_ctx)) -+ return -EALREADY; -+ -+ if (ctx->stamp - hold_ctx->stamp <= LONG_MAX && -+ (ctx->stamp != hold_ctx->stamp || ctx > hold_ctx)) { -+#ifdef CONFIG_DEBUG_MUTEXES -+ DEBUG_LOCKS_WARN_ON(ctx->contending_lock); -+ ctx->contending_lock = ww; -+#endif -+ return -EDEADLK; -+ } -+ -+ return 0; -+} -+#else -+ static inline int __sched -+__mutex_lock_check_stamp(struct rt_mutex *lock, struct ww_acquire_ctx *ctx) -+{ -+ BUG(); -+ return 0; -+} -+ -+#endif -+ -+static inline int -+try_to_take_rt_mutex(struct rt_mutex *lock, struct task_struct *task, -+ struct rt_mutex_waiter *waiter) -+{ -+ return __try_to_take_rt_mutex(lock, task, waiter, STEAL_NORMAL); -+} -+ - /* - * Task blocks on lock. - * -@@ -907,6 +1342,23 @@ static int task_blocks_on_rt_mutex(struct rt_mutex *lock, - return -EDEADLK; - - raw_spin_lock(&task->pi_lock); -+ -+ /* -+ * In the case of futex requeue PI, this will be a proxy -+ * lock. The task will wake unaware that it is enqueueed on -+ * this lock. Avoid blocking on two locks and corrupting -+ * pi_blocked_on via the PI_WAKEUP_INPROGRESS -+ * flag. futex_wait_requeue_pi() sets this when it wakes up -+ * before requeue (due to a signal or timeout). Do not enqueue -+ * the task if PI_WAKEUP_INPROGRESS is set. -+ */ -+ if (task != current && task->pi_blocked_on == PI_WAKEUP_INPROGRESS) { -+ raw_spin_unlock(&task->pi_lock); -+ return -EAGAIN; -+ } -+ -+ BUG_ON(rt_mutex_real_waiter(task->pi_blocked_on)); -+ - __rt_mutex_adjust_prio(task); - waiter->task = task; - waiter->lock = lock; -@@ -930,7 +1382,7 @@ static int task_blocks_on_rt_mutex(struct rt_mutex *lock, - rt_mutex_enqueue_pi(owner, waiter); - - __rt_mutex_adjust_prio(owner); -- if (owner->pi_blocked_on) -+ if (rt_mutex_real_waiter(owner->pi_blocked_on)) - chain_walk = 1; - } else if (rt_mutex_cond_detect_deadlock(waiter, chwalk)) { - chain_walk = 1; -@@ -972,6 +1424,7 @@ static int task_blocks_on_rt_mutex(struct rt_mutex *lock, - * Called with lock->wait_lock held and interrupts disabled. - */ - static void mark_wakeup_next_waiter(struct wake_q_head *wake_q, -+ struct wake_q_head *wake_sleeper_q, - struct rt_mutex *lock) - { - struct rt_mutex_waiter *waiter; -@@ -1000,7 +1453,10 @@ static void mark_wakeup_next_waiter(struct wake_q_head *wake_q, - - raw_spin_unlock(¤t->pi_lock); - -- wake_q_add(wake_q, waiter->task); -+ if (waiter->savestate) -+ wake_q_add(wake_sleeper_q, waiter->task); -+ else -+ wake_q_add(wake_q, waiter->task); - } - - /* -@@ -1014,7 +1470,7 @@ static void remove_waiter(struct rt_mutex *lock, - { - bool is_top_waiter = (waiter == rt_mutex_top_waiter(lock)); - struct task_struct *owner = rt_mutex_owner(lock); -- struct rt_mutex *next_lock; -+ struct rt_mutex *next_lock = NULL; - - raw_spin_lock(¤t->pi_lock); - rt_mutex_dequeue(lock, waiter); -@@ -1038,7 +1494,8 @@ static void remove_waiter(struct rt_mutex *lock, - __rt_mutex_adjust_prio(owner); - - /* Store the lock on which owner is blocked or NULL */ -- next_lock = task_blocked_on_lock(owner); -+ if (rt_mutex_real_waiter(owner->pi_blocked_on)) -+ next_lock = task_blocked_on_lock(owner); - - raw_spin_unlock(&owner->pi_lock); - -@@ -1074,17 +1531,17 @@ void rt_mutex_adjust_pi(struct task_struct *task) - raw_spin_lock_irqsave(&task->pi_lock, flags); - - waiter = task->pi_blocked_on; -- if (!waiter || (waiter->prio == task->prio && -+ if (!rt_mutex_real_waiter(waiter) || (waiter->prio == task->prio && - !dl_prio(task->prio))) { - raw_spin_unlock_irqrestore(&task->pi_lock, flags); - return; - } - next_lock = waiter->lock; -- raw_spin_unlock_irqrestore(&task->pi_lock, flags); - - /* gets dropped in rt_mutex_adjust_prio_chain()! */ - get_task_struct(task); - -+ raw_spin_unlock_irqrestore(&task->pi_lock, flags); - rt_mutex_adjust_prio_chain(task, RT_MUTEX_MIN_CHAINWALK, NULL, - next_lock, NULL, task); - } -@@ -1102,7 +1559,8 @@ void rt_mutex_adjust_pi(struct task_struct *task) - static int __sched - __rt_mutex_slowlock(struct rt_mutex *lock, int state, - struct hrtimer_sleeper *timeout, -- struct rt_mutex_waiter *waiter) -+ struct rt_mutex_waiter *waiter, -+ struct ww_acquire_ctx *ww_ctx) - { - int ret = 0; - -@@ -1125,6 +1583,12 @@ __rt_mutex_slowlock(struct rt_mutex *lock, int state, - break; - } - -+ if (ww_ctx && ww_ctx->acquired > 0) { -+ ret = __mutex_lock_check_stamp(lock, ww_ctx); -+ if (ret) -+ break; -+ } -+ - raw_spin_unlock_irq(&lock->wait_lock); - - debug_rt_mutex_print_deadlock(waiter); -@@ -1159,21 +1623,96 @@ static void rt_mutex_handle_deadlock(int res, int detect_deadlock, - } - } - -+static __always_inline void ww_mutex_lock_acquired(struct ww_mutex *ww, -+ struct ww_acquire_ctx *ww_ctx) -+{ -+#ifdef CONFIG_DEBUG_MUTEXES -+ /* -+ * If this WARN_ON triggers, you used ww_mutex_lock to acquire, -+ * but released with a normal mutex_unlock in this call. -+ * -+ * This should never happen, always use ww_mutex_unlock. -+ */ -+ DEBUG_LOCKS_WARN_ON(ww->ctx); -+ -+ /* -+ * Not quite done after calling ww_acquire_done() ? -+ */ -+ DEBUG_LOCKS_WARN_ON(ww_ctx->done_acquire); -+ -+ if (ww_ctx->contending_lock) { -+ /* -+ * After -EDEADLK you tried to -+ * acquire a different ww_mutex? Bad! -+ */ -+ DEBUG_LOCKS_WARN_ON(ww_ctx->contending_lock != ww); -+ -+ /* -+ * You called ww_mutex_lock after receiving -EDEADLK, -+ * but 'forgot' to unlock everything else first? -+ */ -+ DEBUG_LOCKS_WARN_ON(ww_ctx->acquired > 0); -+ ww_ctx->contending_lock = NULL; -+ } -+ -+ /* -+ * Naughty, using a different class will lead to undefined behavior! -+ */ -+ DEBUG_LOCKS_WARN_ON(ww_ctx->ww_class != ww->ww_class); -+#endif -+ ww_ctx->acquired++; -+} -+ -+#ifdef CONFIG_PREEMPT_RT_FULL -+static void ww_mutex_account_lock(struct rt_mutex *lock, -+ struct ww_acquire_ctx *ww_ctx) -+{ -+ struct ww_mutex *ww = container_of(lock, struct ww_mutex, base.lock); -+ struct rt_mutex_waiter *waiter, *n; -+ -+ /* -+ * This branch gets optimized out for the common case, -+ * and is only important for ww_mutex_lock. -+ */ -+ ww_mutex_lock_acquired(ww, ww_ctx); -+ ww->ctx = ww_ctx; -+ -+ /* -+ * Give any possible sleeping processes the chance to wake up, -+ * so they can recheck if they have to back off. -+ */ -+ rbtree_postorder_for_each_entry_safe(waiter, n, &lock->waiters, -+ tree_entry) { -+ /* XXX debug rt mutex waiter wakeup */ -+ -+ BUG_ON(waiter->lock != lock); -+ rt_mutex_wake_waiter(waiter); -+ } -+} -+ -+#else -+ -+static void ww_mutex_account_lock(struct rt_mutex *lock, -+ struct ww_acquire_ctx *ww_ctx) -+{ -+ BUG(); -+} -+#endif -+ - /* - * Slow path lock function: - */ - static int __sched - rt_mutex_slowlock(struct rt_mutex *lock, int state, - struct hrtimer_sleeper *timeout, -- enum rtmutex_chainwalk chwalk) -+ enum rtmutex_chainwalk chwalk, -+ struct ww_acquire_ctx *ww_ctx) - { - struct rt_mutex_waiter waiter; - unsigned long flags; - int ret = 0; - -- debug_rt_mutex_init_waiter(&waiter); -- RB_CLEAR_NODE(&waiter.pi_tree_entry); -- RB_CLEAR_NODE(&waiter.tree_entry); -+ rt_mutex_init_waiter(&waiter, false); - - /* - * Technically we could use raw_spin_[un]lock_irq() here, but this can -@@ -1187,6 +1726,8 @@ rt_mutex_slowlock(struct rt_mutex *lock, int state, - - /* Try to acquire the lock again: */ - if (try_to_take_rt_mutex(lock, current, NULL)) { -+ if (ww_ctx) -+ ww_mutex_account_lock(lock, ww_ctx); - raw_spin_unlock_irqrestore(&lock->wait_lock, flags); - return 0; - } -@@ -1201,13 +1742,23 @@ rt_mutex_slowlock(struct rt_mutex *lock, int state, - - if (likely(!ret)) - /* sleep on the mutex */ -- ret = __rt_mutex_slowlock(lock, state, timeout, &waiter); -+ ret = __rt_mutex_slowlock(lock, state, timeout, &waiter, -+ ww_ctx); -+ else if (ww_ctx) { -+ /* ww_mutex received EDEADLK, let it become EALREADY */ -+ ret = __mutex_lock_check_stamp(lock, ww_ctx); -+ BUG_ON(!ret); -+ } - - if (unlikely(ret)) { - __set_current_state(TASK_RUNNING); - if (rt_mutex_has_waiters(lock)) - remove_waiter(lock, &waiter); -- rt_mutex_handle_deadlock(ret, chwalk, &waiter); -+ /* ww_mutex want to report EDEADLK/EALREADY, let them */ -+ if (!ww_ctx) -+ rt_mutex_handle_deadlock(ret, chwalk, &waiter); -+ } else if (ww_ctx) { -+ ww_mutex_account_lock(lock, ww_ctx); - } - - /* -@@ -1267,7 +1818,8 @@ static inline int rt_mutex_slowtrylock(struct rt_mutex *lock) - * Return whether the current task needs to undo a potential priority boosting. - */ - static bool __sched rt_mutex_slowunlock(struct rt_mutex *lock, -- struct wake_q_head *wake_q) -+ struct wake_q_head *wake_q, -+ struct wake_q_head *wake_sleeper_q) - { - unsigned long flags; - -@@ -1323,7 +1875,7 @@ static bool __sched rt_mutex_slowunlock(struct rt_mutex *lock, - * - * Queue the next waiter for wakeup once we release the wait_lock. - */ -- mark_wakeup_next_waiter(wake_q, lock); -+ mark_wakeup_next_waiter(wake_q, wake_sleeper_q, lock); - - raw_spin_unlock_irqrestore(&lock->wait_lock, flags); - -@@ -1339,31 +1891,36 @@ static bool __sched rt_mutex_slowunlock(struct rt_mutex *lock, - */ - static inline int - rt_mutex_fastlock(struct rt_mutex *lock, int state, -+ struct ww_acquire_ctx *ww_ctx, - int (*slowfn)(struct rt_mutex *lock, int state, - struct hrtimer_sleeper *timeout, -- enum rtmutex_chainwalk chwalk)) -+ enum rtmutex_chainwalk chwalk, -+ struct ww_acquire_ctx *ww_ctx)) - { - if (likely(rt_mutex_cmpxchg_acquire(lock, NULL, current))) { - rt_mutex_deadlock_account_lock(lock, current); - return 0; - } else -- return slowfn(lock, state, NULL, RT_MUTEX_MIN_CHAINWALK); -+ return slowfn(lock, state, NULL, RT_MUTEX_MIN_CHAINWALK, -+ ww_ctx); - } - - static inline int - rt_mutex_timed_fastlock(struct rt_mutex *lock, int state, - struct hrtimer_sleeper *timeout, - enum rtmutex_chainwalk chwalk, -+ struct ww_acquire_ctx *ww_ctx, - int (*slowfn)(struct rt_mutex *lock, int state, - struct hrtimer_sleeper *timeout, -- enum rtmutex_chainwalk chwalk)) -+ enum rtmutex_chainwalk chwalk, -+ struct ww_acquire_ctx *ww_ctx)) - { - if (chwalk == RT_MUTEX_MIN_CHAINWALK && - likely(rt_mutex_cmpxchg_acquire(lock, NULL, current))) { - rt_mutex_deadlock_account_lock(lock, current); - return 0; - } else -- return slowfn(lock, state, timeout, chwalk); -+ return slowfn(lock, state, timeout, chwalk, ww_ctx); - } - - static inline int -@@ -1380,17 +1937,20 @@ rt_mutex_fasttrylock(struct rt_mutex *lock, - static inline void - rt_mutex_fastunlock(struct rt_mutex *lock, - bool (*slowfn)(struct rt_mutex *lock, -- struct wake_q_head *wqh)) -+ struct wake_q_head *wqh, -+ struct wake_q_head *wq_sleeper)) - { - WAKE_Q(wake_q); -+ WAKE_Q(wake_sleeper_q); - - if (likely(rt_mutex_cmpxchg_release(lock, current, NULL))) { - rt_mutex_deadlock_account_unlock(current); - - } else { -- bool deboost = slowfn(lock, &wake_q); -+ bool deboost = slowfn(lock, &wake_q, &wake_sleeper_q); - - wake_up_q(&wake_q); -+ wake_up_q_sleeper(&wake_sleeper_q); - - /* Undo pi boosting if necessary: */ - if (deboost) -@@ -1407,7 +1967,7 @@ void __sched rt_mutex_lock(struct rt_mutex *lock) - { - might_sleep(); - -- rt_mutex_fastlock(lock, TASK_UNINTERRUPTIBLE, rt_mutex_slowlock); -+ rt_mutex_fastlock(lock, TASK_UNINTERRUPTIBLE, NULL, rt_mutex_slowlock); - } - EXPORT_SYMBOL_GPL(rt_mutex_lock); - -@@ -1424,7 +1984,7 @@ int __sched rt_mutex_lock_interruptible(struct rt_mutex *lock) - { - might_sleep(); - -- return rt_mutex_fastlock(lock, TASK_INTERRUPTIBLE, rt_mutex_slowlock); -+ return rt_mutex_fastlock(lock, TASK_INTERRUPTIBLE, NULL, rt_mutex_slowlock); - } - EXPORT_SYMBOL_GPL(rt_mutex_lock_interruptible); - -@@ -1437,11 +1997,30 @@ int rt_mutex_timed_futex_lock(struct rt_mutex *lock, - might_sleep(); - - return rt_mutex_timed_fastlock(lock, TASK_INTERRUPTIBLE, timeout, -- RT_MUTEX_FULL_CHAINWALK, -+ RT_MUTEX_FULL_CHAINWALK, NULL, - rt_mutex_slowlock); - } - - /** -+ * rt_mutex_lock_killable - lock a rt_mutex killable -+ * -+ * @lock: the rt_mutex to be locked -+ * @detect_deadlock: deadlock detection on/off -+ * -+ * Returns: -+ * 0 on success -+ * -EINTR when interrupted by a signal -+ * -EDEADLK when the lock would deadlock (when deadlock detection is on) -+ */ -+int __sched rt_mutex_lock_killable(struct rt_mutex *lock) -+{ -+ might_sleep(); -+ -+ return rt_mutex_fastlock(lock, TASK_KILLABLE, NULL, rt_mutex_slowlock); -+} -+EXPORT_SYMBOL_GPL(rt_mutex_lock_killable); -+ -+/** - * rt_mutex_timed_lock - lock a rt_mutex interruptible - * the timeout structure is provided - * by the caller -@@ -1461,6 +2040,7 @@ rt_mutex_timed_lock(struct rt_mutex *lock, struct hrtimer_sleeper *timeout) - - return rt_mutex_timed_fastlock(lock, TASK_INTERRUPTIBLE, timeout, - RT_MUTEX_MIN_CHAINWALK, -+ NULL, - rt_mutex_slowlock); - } - EXPORT_SYMBOL_GPL(rt_mutex_timed_lock); -@@ -1478,7 +2058,11 @@ EXPORT_SYMBOL_GPL(rt_mutex_timed_lock); - */ - int __sched rt_mutex_trylock(struct rt_mutex *lock) - { -+#ifdef CONFIG_PREEMPT_RT_FULL -+ if (WARN_ON(in_irq() || in_nmi())) -+#else - if (WARN_ON(in_irq() || in_nmi() || in_serving_softirq())) -+#endif - return 0; - - return rt_mutex_fasttrylock(lock, rt_mutex_slowtrylock); -@@ -1504,13 +2088,14 @@ EXPORT_SYMBOL_GPL(rt_mutex_unlock); - * required or not. - */ - bool __sched rt_mutex_futex_unlock(struct rt_mutex *lock, -- struct wake_q_head *wqh) -+ struct wake_q_head *wqh, -+ struct wake_q_head *wq_sleeper) - { - if (likely(rt_mutex_cmpxchg_release(lock, current, NULL))) { - rt_mutex_deadlock_account_unlock(current); - return false; - } -- return rt_mutex_slowunlock(lock, wqh); -+ return rt_mutex_slowunlock(lock, wqh, wq_sleeper); - } - - /** -@@ -1543,13 +2128,12 @@ EXPORT_SYMBOL_GPL(rt_mutex_destroy); - void __rt_mutex_init(struct rt_mutex *lock, const char *name) - { - lock->owner = NULL; -- raw_spin_lock_init(&lock->wait_lock); - lock->waiters = RB_ROOT; - lock->waiters_leftmost = NULL; - - debug_rt_mutex_init(lock, name); - } --EXPORT_SYMBOL_GPL(__rt_mutex_init); -+EXPORT_SYMBOL(__rt_mutex_init); - - /** - * rt_mutex_init_proxy_locked - initialize and lock a rt_mutex on behalf of a -@@ -1564,7 +2148,7 @@ EXPORT_SYMBOL_GPL(__rt_mutex_init); - void rt_mutex_init_proxy_locked(struct rt_mutex *lock, - struct task_struct *proxy_owner) - { -- __rt_mutex_init(lock, NULL); -+ rt_mutex_init(lock); - debug_rt_mutex_proxy_lock(lock, proxy_owner); - rt_mutex_set_owner(lock, proxy_owner); - rt_mutex_deadlock_account_lock(lock, proxy_owner); -@@ -1612,6 +2196,35 @@ int rt_mutex_start_proxy_lock(struct rt_mutex *lock, - return 1; - } - -+#ifdef CONFIG_PREEMPT_RT_FULL -+ /* -+ * In PREEMPT_RT there's an added race. -+ * If the task, that we are about to requeue, times out, -+ * it can set the PI_WAKEUP_INPROGRESS. This tells the requeue -+ * to skip this task. But right after the task sets -+ * its pi_blocked_on to PI_WAKEUP_INPROGRESS it can then -+ * block on the spin_lock(&hb->lock), which in RT is an rtmutex. -+ * This will replace the PI_WAKEUP_INPROGRESS with the actual -+ * lock that it blocks on. We *must not* place this task -+ * on this proxy lock in that case. -+ * -+ * To prevent this race, we first take the task's pi_lock -+ * and check if it has updated its pi_blocked_on. If it has, -+ * we assume that it woke up and we return -EAGAIN. -+ * Otherwise, we set the task's pi_blocked_on to -+ * PI_REQUEUE_INPROGRESS, so that if the task is waking up -+ * it will know that we are in the process of requeuing it. -+ */ -+ raw_spin_lock(&task->pi_lock); -+ if (task->pi_blocked_on) { -+ raw_spin_unlock(&task->pi_lock); -+ raw_spin_unlock_irq(&lock->wait_lock); -+ return -EAGAIN; -+ } -+ task->pi_blocked_on = PI_REQUEUE_INPROGRESS; -+ raw_spin_unlock(&task->pi_lock); -+#endif -+ - /* We enforce deadlock detection for futexes */ - ret = task_blocks_on_rt_mutex(lock, waiter, task, - RT_MUTEX_FULL_CHAINWALK); -@@ -1626,7 +2239,7 @@ int rt_mutex_start_proxy_lock(struct rt_mutex *lock, - ret = 0; - } - -- if (unlikely(ret)) -+ if (ret && rt_mutex_has_waiters(lock)) - remove_waiter(lock, waiter); - - raw_spin_unlock_irq(&lock->wait_lock); -@@ -1682,7 +2295,7 @@ int rt_mutex_finish_proxy_lock(struct rt_mutex *lock, - set_current_state(TASK_INTERRUPTIBLE); - - /* sleep on the mutex */ -- ret = __rt_mutex_slowlock(lock, TASK_INTERRUPTIBLE, to, waiter); -+ ret = __rt_mutex_slowlock(lock, TASK_INTERRUPTIBLE, to, waiter, NULL); - - if (unlikely(ret)) - remove_waiter(lock, waiter); -@@ -1697,3 +2310,89 @@ int rt_mutex_finish_proxy_lock(struct rt_mutex *lock, - - return ret; - } -+ -+static inline int -+ww_mutex_deadlock_injection(struct ww_mutex *lock, struct ww_acquire_ctx *ctx) -+{ -+#ifdef CONFIG_DEBUG_WW_MUTEX_SLOWPATH -+ unsigned tmp; -+ -+ if (ctx->deadlock_inject_countdown-- == 0) { -+ tmp = ctx->deadlock_inject_interval; -+ if (tmp > UINT_MAX/4) -+ tmp = UINT_MAX; -+ else -+ tmp = tmp*2 + tmp + tmp/2; -+ -+ ctx->deadlock_inject_interval = tmp; -+ ctx->deadlock_inject_countdown = tmp; -+ ctx->contending_lock = lock; -+ -+ ww_mutex_unlock(lock); -+ -+ return -EDEADLK; -+ } -+#endif -+ -+ return 0; -+} -+ -+#ifdef CONFIG_PREEMPT_RT_FULL -+int __sched -+__ww_mutex_lock_interruptible(struct ww_mutex *lock, struct ww_acquire_ctx *ww_ctx) -+{ -+ int ret; -+ -+ might_sleep(); -+ -+ mutex_acquire_nest(&lock->base.dep_map, 0, 0, &ww_ctx->dep_map, _RET_IP_); -+ ret = rt_mutex_slowlock(&lock->base.lock, TASK_INTERRUPTIBLE, NULL, 0, ww_ctx); -+ if (ret) -+ mutex_release(&lock->base.dep_map, 1, _RET_IP_); -+ else if (!ret && ww_ctx->acquired > 1) -+ return ww_mutex_deadlock_injection(lock, ww_ctx); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(__ww_mutex_lock_interruptible); -+ -+int __sched -+__ww_mutex_lock(struct ww_mutex *lock, struct ww_acquire_ctx *ww_ctx) -+{ -+ int ret; -+ -+ might_sleep(); -+ -+ mutex_acquire_nest(&lock->base.dep_map, 0, 0, &ww_ctx->dep_map, _RET_IP_); -+ ret = rt_mutex_slowlock(&lock->base.lock, TASK_UNINTERRUPTIBLE, NULL, 0, ww_ctx); -+ if (ret) -+ mutex_release(&lock->base.dep_map, 1, _RET_IP_); -+ else if (!ret && ww_ctx->acquired > 1) -+ return ww_mutex_deadlock_injection(lock, ww_ctx); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(__ww_mutex_lock); -+ -+void __sched ww_mutex_unlock(struct ww_mutex *lock) -+{ -+ int nest = !!lock->ctx; -+ -+ /* -+ * The unlocking fastpath is the 0->1 transition from 'locked' -+ * into 'unlocked' state: -+ */ -+ if (nest) { -+#ifdef CONFIG_DEBUG_MUTEXES -+ DEBUG_LOCKS_WARN_ON(!lock->ctx->acquired); -+#endif -+ if (lock->ctx->acquired > 0) -+ lock->ctx->acquired--; -+ lock->ctx = NULL; -+ } -+ -+ mutex_release(&lock->base.dep_map, nest, _RET_IP_); -+ rt_mutex_unlock(&lock->base.lock); -+} -+EXPORT_SYMBOL(ww_mutex_unlock); -+#endif -diff --git a/kernel/locking/rtmutex_common.h b/kernel/locking/rtmutex_common.h -index 4f5f83c..289f062 100644 ---- a/kernel/locking/rtmutex_common.h -+++ b/kernel/locking/rtmutex_common.h -@@ -27,6 +27,7 @@ struct rt_mutex_waiter { - struct rb_node pi_tree_entry; - struct task_struct *task; - struct rt_mutex *lock; -+ bool savestate; - #ifdef CONFIG_DEBUG_RT_MUTEXES - unsigned long ip; - struct pid *deadlock_task_pid; -@@ -97,6 +98,9 @@ enum rtmutex_chainwalk { - /* - * PI-futex support (proxy locking functions, etc.): - */ -+#define PI_WAKEUP_INPROGRESS ((struct rt_mutex_waiter *) 1) -+#define PI_REQUEUE_INPROGRESS ((struct rt_mutex_waiter *) 2) -+ - extern struct task_struct *rt_mutex_next_owner(struct rt_mutex *lock); - extern void rt_mutex_init_proxy_locked(struct rt_mutex *lock, - struct task_struct *proxy_owner); -@@ -110,7 +114,8 @@ extern int rt_mutex_finish_proxy_lock(struct rt_mutex *lock, - struct rt_mutex_waiter *waiter); - extern int rt_mutex_timed_futex_lock(struct rt_mutex *l, struct hrtimer_sleeper *to); - extern bool rt_mutex_futex_unlock(struct rt_mutex *lock, -- struct wake_q_head *wqh); -+ struct wake_q_head *wqh, -+ struct wake_q_head *wq_sleeper); - extern void rt_mutex_adjust_prio(struct task_struct *task); - - #ifdef CONFIG_DEBUG_RT_MUTEXES -@@ -119,4 +124,14 @@ extern void rt_mutex_adjust_prio(struct task_struct *task); - # include "rtmutex.h" - #endif - -+static inline void -+rt_mutex_init_waiter(struct rt_mutex_waiter *waiter, bool savestate) -+{ -+ debug_rt_mutex_init_waiter(waiter); -+ waiter->task = NULL; -+ waiter->savestate = savestate; -+ RB_CLEAR_NODE(&waiter->pi_tree_entry); -+ RB_CLEAR_NODE(&waiter->tree_entry); -+} -+ - #endif -diff --git a/kernel/locking/spinlock.c b/kernel/locking/spinlock.c -index db3ccb1..9097796 100644 ---- a/kernel/locking/spinlock.c -+++ b/kernel/locking/spinlock.c -@@ -124,8 +124,11 @@ void __lockfunc __raw_##op##_lock_bh(locktype##_t *lock) \ - * __[spin|read|write]_lock_bh() - */ - BUILD_LOCK_OPS(spin, raw_spinlock); -+ -+#ifndef CONFIG_PREEMPT_RT_FULL - BUILD_LOCK_OPS(read, rwlock); - BUILD_LOCK_OPS(write, rwlock); -+#endif - - #endif - -@@ -209,6 +212,8 @@ void __lockfunc _raw_spin_unlock_bh(raw_spinlock_t *lock) - EXPORT_SYMBOL(_raw_spin_unlock_bh); - #endif - -+#ifndef CONFIG_PREEMPT_RT_FULL -+ - #ifndef CONFIG_INLINE_READ_TRYLOCK - int __lockfunc _raw_read_trylock(rwlock_t *lock) - { -@@ -353,6 +358,8 @@ void __lockfunc _raw_write_unlock_bh(rwlock_t *lock) - EXPORT_SYMBOL(_raw_write_unlock_bh); - #endif - -+#endif /* !PREEMPT_RT_FULL */ -+ - #ifdef CONFIG_DEBUG_LOCK_ALLOC - - void __lockfunc _raw_spin_lock_nested(raw_spinlock_t *lock, int subclass) -diff --git a/kernel/locking/spinlock_debug.c b/kernel/locking/spinlock_debug.c -index 0374a59..9497033 100644 ---- a/kernel/locking/spinlock_debug.c -+++ b/kernel/locking/spinlock_debug.c -@@ -31,6 +31,7 @@ void __raw_spin_lock_init(raw_spinlock_t *lock, const char *name, - - EXPORT_SYMBOL(__raw_spin_lock_init); - -+#ifndef CONFIG_PREEMPT_RT_FULL - void __rwlock_init(rwlock_t *lock, const char *name, - struct lock_class_key *key) - { -@@ -48,6 +49,7 @@ void __rwlock_init(rwlock_t *lock, const char *name, - } - - EXPORT_SYMBOL(__rwlock_init); -+#endif - - static void spin_dump(raw_spinlock_t *lock, const char *msg) - { -@@ -159,6 +161,7 @@ void do_raw_spin_unlock(raw_spinlock_t *lock) - arch_spin_unlock(&lock->raw_lock); - } - -+#ifndef CONFIG_PREEMPT_RT_FULL - static void rwlock_bug(rwlock_t *lock, const char *msg) - { - if (!debug_locks_off()) -@@ -300,3 +303,5 @@ void do_raw_write_unlock(rwlock_t *lock) - debug_write_unlock(lock); - arch_write_unlock(&lock->raw_lock); - } -+ -+#endif -diff --git a/kernel/panic.c b/kernel/panic.c -index 535c965..3373a70 100644 ---- a/kernel/panic.c -+++ b/kernel/panic.c -@@ -444,9 +444,11 @@ static u64 oops_id; - - static int init_oops_id(void) - { -+#ifndef CONFIG_PREEMPT_RT_FULL - if (!oops_id) - get_random_bytes(&oops_id, sizeof(oops_id)); - else -+#endif - oops_id++; - - return 0; -diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c -index fca9254..4e4063e 100644 ---- a/kernel/power/hibernate.c -+++ b/kernel/power/hibernate.c -@@ -285,6 +285,8 @@ static int create_image(int platform_mode) - - local_irq_disable(); - -+ system_state = SYSTEM_SUSPEND; -+ - error = syscore_suspend(); - if (error) { - printk(KERN_ERR "PM: Some system devices failed to power down, " -@@ -314,6 +316,7 @@ static int create_image(int platform_mode) - syscore_resume(); - - Enable_irqs: -+ system_state = SYSTEM_RUNNING; - local_irq_enable(); - - Enable_cpus: -@@ -438,6 +441,7 @@ static int resume_target_kernel(bool platform_mode) - goto Enable_cpus; - - local_irq_disable(); -+ system_state = SYSTEM_SUSPEND; - - error = syscore_suspend(); - if (error) -@@ -471,6 +475,7 @@ static int resume_target_kernel(bool platform_mode) - syscore_resume(); - - Enable_irqs: -+ system_state = SYSTEM_RUNNING; - local_irq_enable(); - - Enable_cpus: -@@ -556,6 +561,7 @@ int hibernation_platform_enter(void) - goto Enable_cpus; - - local_irq_disable(); -+ system_state = SYSTEM_SUSPEND; - syscore_suspend(); - if (pm_wakeup_pending()) { - error = -EAGAIN; -@@ -568,6 +574,7 @@ int hibernation_platform_enter(void) - - Power_up: - syscore_resume(); -+ system_state = SYSTEM_RUNNING; - local_irq_enable(); - - Enable_cpus: -@@ -642,6 +649,10 @@ static void power_down(void) - cpu_relax(); - } - -+#ifndef CONFIG_SUSPEND -+bool pm_in_action; -+#endif -+ - /** - * hibernate - Carry out system hibernation, including saving the image. - */ -@@ -654,6 +665,8 @@ int hibernate(void) - return -EPERM; - } - -+ pm_in_action = true; -+ - lock_system_sleep(); - /* The snapshot device should not be opened while we're running */ - if (!atomic_add_unless(&snapshot_device_available, -1, 0)) { -@@ -719,6 +732,7 @@ int hibernate(void) - atomic_inc(&snapshot_device_available); - Unlock: - unlock_system_sleep(); -+ pm_in_action = false; - return error; - } - -diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c -index 5b70d64..e25382c 100644 ---- a/kernel/power/suspend.c -+++ b/kernel/power/suspend.c -@@ -359,6 +359,8 @@ static int suspend_enter(suspend_state_t state, bool *wakeup) - arch_suspend_disable_irqs(); - BUG_ON(!irqs_disabled()); - -+ system_state = SYSTEM_SUSPEND; -+ - error = syscore_suspend(); - if (!error) { - *wakeup = pm_wakeup_pending(); -@@ -375,6 +377,8 @@ static int suspend_enter(suspend_state_t state, bool *wakeup) - syscore_resume(); - } - -+ system_state = SYSTEM_RUNNING; -+ - arch_suspend_enable_irqs(); - BUG_ON(irqs_disabled()); - -@@ -517,6 +521,8 @@ static int enter_state(suspend_state_t state) - return error; - } - -+bool pm_in_action; -+ - /** - * pm_suspend - Externally visible function for suspending the system. - * @state: System sleep state to enter. -@@ -531,6 +537,8 @@ int pm_suspend(suspend_state_t state) - if (state <= PM_SUSPEND_ON || state >= PM_SUSPEND_MAX) - return -EINVAL; - -+ pm_in_action = true; -+ - error = enter_state(state); - if (error) { - suspend_stats.fail++; -@@ -538,6 +546,7 @@ int pm_suspend(suspend_state_t state) - } else { - suspend_stats.success++; - } -+ pm_in_action = false; - return error; - } - EXPORT_SYMBOL(pm_suspend); -diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c -index bfbf284..723bcab 100644 ---- a/kernel/printk/printk.c -+++ b/kernel/printk/printk.c -@@ -246,6 +246,65 @@ __packed __aligned(4) - */ - static DEFINE_RAW_SPINLOCK(logbuf_lock); - -+#ifdef CONFIG_EARLY_PRINTK -+struct console *early_console; -+ -+static void early_vprintk(const char *fmt, va_list ap) -+{ -+ if (early_console) { -+ char buf[512]; -+ int n = vscnprintf(buf, sizeof(buf), fmt, ap); -+ -+ early_console->write(early_console, buf, n); -+ } -+} -+ -+asmlinkage void early_printk(const char *fmt, ...) -+{ -+ va_list ap; -+ -+ va_start(ap, fmt); -+ early_vprintk(fmt, ap); -+ va_end(ap); -+} -+ -+/* -+ * This is independent of any log levels - a global -+ * kill switch that turns off all of printk. -+ * -+ * Used by the NMI watchdog if early-printk is enabled. -+ */ -+static bool __read_mostly printk_killswitch; -+ -+static int __init force_early_printk_setup(char *str) -+{ -+ printk_killswitch = true; -+ return 0; -+} -+early_param("force_early_printk", force_early_printk_setup); -+ -+void printk_kill(void) -+{ -+ printk_killswitch = true; -+} -+ -+#ifdef CONFIG_PRINTK -+static int forced_early_printk(const char *fmt, va_list ap) -+{ -+ if (!printk_killswitch) -+ return 0; -+ early_vprintk(fmt, ap); -+ return 1; -+} -+#endif -+ -+#else -+static inline int forced_early_printk(const char *fmt, va_list ap) -+{ -+ return 0; -+} -+#endif -+ - #ifdef CONFIG_PRINTK - DECLARE_WAIT_QUEUE_HEAD(log_wait); - /* the next printk record to read by syslog(READ) or /proc/kmsg */ -@@ -1209,6 +1268,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear) - { - char *text; - int len = 0; -+ int attempts = 0; - - text = kmalloc(LOG_LINE_MAX + PREFIX_MAX, GFP_KERNEL); - if (!text) -@@ -1220,6 +1280,14 @@ static int syslog_print_all(char __user *buf, int size, bool clear) - u64 seq; - u32 idx; - enum log_flags prev; -+ int num_msg; -+try_again: -+ attempts++; -+ if (attempts > 10) { -+ len = -EBUSY; -+ goto out; -+ } -+ num_msg = 0; - - /* - * Find first record that fits, including all following records, -@@ -1235,6 +1303,14 @@ static int syslog_print_all(char __user *buf, int size, bool clear) - prev = msg->flags; - idx = log_next(idx); - seq++; -+ num_msg++; -+ if (num_msg > 5) { -+ num_msg = 0; -+ raw_spin_unlock_irq(&logbuf_lock); -+ raw_spin_lock_irq(&logbuf_lock); -+ if (clear_seq < log_first_seq) -+ goto try_again; -+ } - } - - /* move first record forward until length fits into the buffer */ -@@ -1248,6 +1324,14 @@ static int syslog_print_all(char __user *buf, int size, bool clear) - prev = msg->flags; - idx = log_next(idx); - seq++; -+ num_msg++; -+ if (num_msg > 5) { -+ num_msg = 0; -+ raw_spin_unlock_irq(&logbuf_lock); -+ raw_spin_lock_irq(&logbuf_lock); -+ if (clear_seq < log_first_seq) -+ goto try_again; -+ } - } - - /* last message fitting into this dump */ -@@ -1288,6 +1372,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear) - clear_seq = log_next_seq; - clear_idx = log_next_idx; - } -+out: - raw_spin_unlock_irq(&logbuf_lock); - - kfree(text); -@@ -1443,6 +1528,7 @@ static void call_console_drivers(int level, - if (!console_drivers) - return; - -+ migrate_disable(); - for_each_console(con) { - if (exclusive_console && con != exclusive_console) - continue; -@@ -1458,6 +1544,7 @@ static void call_console_drivers(int level, - else - con->write(con, text, len); - } -+ migrate_enable(); - } - - /* -@@ -1620,6 +1707,13 @@ asmlinkage int vprintk_emit(int facility, int level, - /* cpu currently holding logbuf_lock in this function */ - static unsigned int logbuf_cpu = UINT_MAX; - -+ /* -+ * Fall back to early_printk if a debugging subsystem has -+ * killed printk output -+ */ -+ if (unlikely(forced_early_printk(fmt, args))) -+ return 1; -+ - if (level == LOGLEVEL_SCHED) { - level = LOGLEVEL_DEFAULT; - in_sched = true; -@@ -1755,13 +1849,23 @@ asmlinkage int vprintk_emit(int facility, int level, - - /* If called from the scheduler, we can not call up(). */ - if (!in_sched) { -+ int may_trylock = 1; -+ - lockdep_off(); -+#ifdef CONFIG_PREEMPT_RT_FULL -+ /* -+ * we can't take a sleeping lock with IRQs or preeption disabled -+ * so we can't print in these contexts -+ */ -+ if (!(preempt_count() == 0 && !irqs_disabled())) -+ may_trylock = 0; -+#endif - /* - * Try to acquire and then immediately release the console - * semaphore. The release will print out buffers and wake up - * /dev/kmsg and syslog() users. - */ -- if (console_trylock()) -+ if (may_trylock && console_trylock()) - console_unlock(); - lockdep_on(); - } -@@ -1901,26 +2005,6 @@ DEFINE_PER_CPU(printk_func_t, printk_func); - - #endif /* CONFIG_PRINTK */ - --#ifdef CONFIG_EARLY_PRINTK --struct console *early_console; -- --asmlinkage __visible void early_printk(const char *fmt, ...) --{ -- va_list ap; -- char buf[512]; -- int n; -- -- if (!early_console) -- return; -- -- va_start(ap, fmt); -- n = vscnprintf(buf, sizeof(buf), fmt, ap); -- va_end(ap); -- -- early_console->write(early_console, buf, n); --} --#endif -- - static int __add_preferred_console(char *name, int idx, char *options, - char *brl_options) - { -@@ -2183,11 +2267,16 @@ static void console_cont_flush(char *text, size_t size) - goto out; - - len = cont_print_text(text, size); -+#ifdef CONFIG_PREEMPT_RT_FULL -+ raw_spin_unlock_irqrestore(&logbuf_lock, flags); -+ call_console_drivers(cont.level, NULL, 0, text, len); -+#else - raw_spin_unlock(&logbuf_lock); - stop_critical_timings(); - call_console_drivers(cont.level, NULL, 0, text, len); - start_critical_timings(); - local_irq_restore(flags); -+#endif - return; - out: - raw_spin_unlock_irqrestore(&logbuf_lock, flags); -@@ -2309,13 +2398,17 @@ skip: - console_idx = log_next(console_idx); - console_seq++; - console_prev = msg->flags; -+#ifdef CONFIG_PREEMPT_RT_FULL -+ raw_spin_unlock_irqrestore(&logbuf_lock, flags); -+ call_console_drivers(level, ext_text, ext_len, text, len); -+#else - raw_spin_unlock(&logbuf_lock); - - stop_critical_timings(); /* don't trace print latency */ - call_console_drivers(level, ext_text, ext_len, text, len); - start_critical_timings(); - local_irq_restore(flags); -- -+#endif - if (do_cond_resched) - cond_resched(); - } -diff --git a/kernel/ptrace.c b/kernel/ptrace.c -index d49bfa1..b8cf7a8 100644 ---- a/kernel/ptrace.c -+++ b/kernel/ptrace.c -@@ -128,7 +128,14 @@ static bool ptrace_freeze_traced(struct task_struct *task) - - spin_lock_irq(&task->sighand->siglock); - if (task_is_traced(task) && !__fatal_signal_pending(task)) { -- task->state = __TASK_TRACED; -+ unsigned long flags; -+ -+ raw_spin_lock_irqsave(&task->pi_lock, flags); -+ if (task->state & __TASK_TRACED) -+ task->state = __TASK_TRACED; -+ else -+ task->saved_state = __TASK_TRACED; -+ raw_spin_unlock_irqrestore(&task->pi_lock, flags); - ret = true; - } - spin_unlock_irq(&task->sighand->siglock); -diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c -index 250ea67..6349c9a 100644 ---- a/kernel/rcu/rcutorture.c -+++ b/kernel/rcu/rcutorture.c -@@ -409,6 +409,7 @@ static struct rcu_torture_ops rcu_ops = { - .name = "rcu" - }; - -+#ifndef CONFIG_PREEMPT_RT_FULL - /* - * Definitions for rcu_bh torture testing. - */ -@@ -448,6 +449,12 @@ static struct rcu_torture_ops rcu_bh_ops = { - .name = "rcu_bh" - }; - -+#else -+static struct rcu_torture_ops rcu_bh_ops = { -+ .ttype = INVALID_RCU_FLAVOR, -+}; -+#endif -+ - /* - * Don't even think about trying any of these in real life!!! - * The names includes "busted", and they really means it! -diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c -index 9a535a8..ae568fd 100644 ---- a/kernel/rcu/tree.c -+++ b/kernel/rcu/tree.c -@@ -56,6 +56,11 @@ - #include <linux/random.h> - #include <linux/trace_events.h> - #include <linux/suspend.h> -+#include <linux/delay.h> -+#include <linux/gfp.h> -+#include <linux/oom.h> -+#include <linux/smpboot.h> -+#include "../time/tick-internal.h" - - #include "tree.h" - #include "rcu.h" -@@ -254,6 +259,19 @@ void rcu_sched_qs(void) - this_cpu_ptr(&rcu_sched_data), true); - } - -+#ifdef CONFIG_PREEMPT_RT_FULL -+static void rcu_preempt_qs(void); -+ -+void rcu_bh_qs(void) -+{ -+ unsigned long flags; -+ -+ /* Callers to this function, rcu_preempt_qs(), must disable irqs. */ -+ local_irq_save(flags); -+ rcu_preempt_qs(); -+ local_irq_restore(flags); -+} -+#else - void rcu_bh_qs(void) - { - if (__this_cpu_read(rcu_bh_data.cpu_no_qs.s)) { -@@ -263,6 +281,7 @@ void rcu_bh_qs(void) - __this_cpu_write(rcu_bh_data.cpu_no_qs.b.norm, false); - } - } -+#endif - - static DEFINE_PER_CPU(int, rcu_sched_qs_mask); - -@@ -426,11 +445,13 @@ EXPORT_SYMBOL_GPL(rcu_batches_started_sched); - /* - * Return the number of RCU BH batches started thus far for debug & stats. - */ -+#ifndef CONFIG_PREEMPT_RT_FULL - unsigned long rcu_batches_started_bh(void) - { - return rcu_bh_state.gpnum; - } - EXPORT_SYMBOL_GPL(rcu_batches_started_bh); -+#endif - - /* - * Return the number of RCU batches completed thus far for debug & stats. -@@ -450,6 +471,7 @@ unsigned long rcu_batches_completed_sched(void) - } - EXPORT_SYMBOL_GPL(rcu_batches_completed_sched); - -+#ifndef CONFIG_PREEMPT_RT_FULL - /* - * Return the number of RCU BH batches completed thus far for debug & stats. - */ -@@ -477,6 +499,13 @@ void rcu_bh_force_quiescent_state(void) - } - EXPORT_SYMBOL_GPL(rcu_bh_force_quiescent_state); - -+#else -+void rcu_force_quiescent_state(void) -+{ -+} -+EXPORT_SYMBOL_GPL(rcu_force_quiescent_state); -+#endif -+ - /* - * Force a quiescent state for RCU-sched. - */ -@@ -527,9 +556,11 @@ void rcutorture_get_gp_data(enum rcutorture_type test_type, int *flags, - case RCU_FLAVOR: - rsp = rcu_state_p; - break; -+#ifndef CONFIG_PREEMPT_RT_FULL - case RCU_BH_FLAVOR: - rsp = &rcu_bh_state; - break; -+#endif - case RCU_SCHED_FLAVOR: - rsp = &rcu_sched_state; - break; -@@ -2920,18 +2951,17 @@ __rcu_process_callbacks(struct rcu_state *rsp) - /* - * Do RCU core processing for the current CPU. - */ --static void rcu_process_callbacks(struct softirq_action *unused) -+static void rcu_process_callbacks(void) - { - struct rcu_state *rsp; - - if (cpu_is_offline(smp_processor_id())) - return; -- trace_rcu_utilization(TPS("Start RCU core")); - for_each_rcu_flavor(rsp) - __rcu_process_callbacks(rsp); -- trace_rcu_utilization(TPS("End RCU core")); - } - -+static DEFINE_PER_CPU(struct task_struct *, rcu_cpu_kthread_task); - /* - * Schedule RCU callback invocation. If the specified type of RCU - * does not support RCU priority boosting, just do a direct call, -@@ -2943,18 +2973,105 @@ static void invoke_rcu_callbacks(struct rcu_state *rsp, struct rcu_data *rdp) - { - if (unlikely(!READ_ONCE(rcu_scheduler_fully_active))) - return; -- if (likely(!rsp->boost)) { -- rcu_do_batch(rsp, rdp); -- return; -- } -- invoke_rcu_callbacks_kthread(); -+ rcu_do_batch(rsp, rdp); - } - -+static void rcu_wake_cond(struct task_struct *t, int status) -+{ -+ /* -+ * If the thread is yielding, only wake it when this -+ * is invoked from idle -+ */ -+ if (t && (status != RCU_KTHREAD_YIELDING || is_idle_task(current))) -+ wake_up_process(t); -+} -+ -+/* -+ * Wake up this CPU's rcuc kthread to do RCU core processing. -+ */ - static void invoke_rcu_core(void) - { -- if (cpu_online(smp_processor_id())) -- raise_softirq(RCU_SOFTIRQ); -+ unsigned long flags; -+ struct task_struct *t; -+ -+ if (!cpu_online(smp_processor_id())) -+ return; -+ local_irq_save(flags); -+ __this_cpu_write(rcu_cpu_has_work, 1); -+ t = __this_cpu_read(rcu_cpu_kthread_task); -+ if (t != NULL && current != t) -+ rcu_wake_cond(t, __this_cpu_read(rcu_cpu_kthread_status)); -+ local_irq_restore(flags); -+} -+ -+static void rcu_cpu_kthread_park(unsigned int cpu) -+{ -+ per_cpu(rcu_cpu_kthread_status, cpu) = RCU_KTHREAD_OFFCPU; -+} -+ -+static int rcu_cpu_kthread_should_run(unsigned int cpu) -+{ -+ return __this_cpu_read(rcu_cpu_has_work); -+} -+ -+/* -+ * Per-CPU kernel thread that invokes RCU callbacks. This replaces the -+ * RCU softirq used in flavors and configurations of RCU that do not -+ * support RCU priority boosting. -+ */ -+static void rcu_cpu_kthread(unsigned int cpu) -+{ -+ unsigned int *statusp = this_cpu_ptr(&rcu_cpu_kthread_status); -+ char work, *workp = this_cpu_ptr(&rcu_cpu_has_work); -+ int spincnt; -+ -+ for (spincnt = 0; spincnt < 10; spincnt++) { -+ trace_rcu_utilization(TPS("Start CPU kthread@rcu_wait")); -+ local_bh_disable(); -+ *statusp = RCU_KTHREAD_RUNNING; -+ this_cpu_inc(rcu_cpu_kthread_loops); -+ local_irq_disable(); -+ work = *workp; -+ *workp = 0; -+ local_irq_enable(); -+ if (work) -+ rcu_process_callbacks(); -+ local_bh_enable(); -+ if (*workp == 0) { -+ trace_rcu_utilization(TPS("End CPU kthread@rcu_wait")); -+ *statusp = RCU_KTHREAD_WAITING; -+ return; -+ } -+ } -+ *statusp = RCU_KTHREAD_YIELDING; -+ trace_rcu_utilization(TPS("Start CPU kthread@rcu_yield")); -+ schedule_timeout_interruptible(2); -+ trace_rcu_utilization(TPS("End CPU kthread@rcu_yield")); -+ *statusp = RCU_KTHREAD_WAITING; -+} -+ -+static struct smp_hotplug_thread rcu_cpu_thread_spec = { -+ .store = &rcu_cpu_kthread_task, -+ .thread_should_run = rcu_cpu_kthread_should_run, -+ .thread_fn = rcu_cpu_kthread, -+ .thread_comm = "rcuc/%u", -+ .setup = rcu_cpu_kthread_setup, -+ .park = rcu_cpu_kthread_park, -+}; -+ -+/* -+ * Spawn per-CPU RCU core processing kthreads. -+ */ -+static int __init rcu_spawn_core_kthreads(void) -+{ -+ int cpu; -+ -+ for_each_possible_cpu(cpu) -+ per_cpu(rcu_cpu_has_work, cpu) = 0; -+ BUG_ON(smpboot_register_percpu_thread(&rcu_cpu_thread_spec)); -+ return 0; - } -+early_initcall(rcu_spawn_core_kthreads); - - /* - * Handle any core-RCU processing required by a call_rcu() invocation. -@@ -3099,6 +3216,7 @@ void call_rcu_sched(struct rcu_head *head, rcu_callback_t func) - } - EXPORT_SYMBOL_GPL(call_rcu_sched); - -+#ifndef CONFIG_PREEMPT_RT_FULL - /* - * Queue an RCU callback for invocation after a quicker grace period. - */ -@@ -3107,6 +3225,7 @@ void call_rcu_bh(struct rcu_head *head, rcu_callback_t func) - __call_rcu(head, func, &rcu_bh_state, -1, 0); - } - EXPORT_SYMBOL_GPL(call_rcu_bh); -+#endif - - /* - * Queue an RCU callback for lazy invocation after a grace period. -@@ -3198,6 +3317,7 @@ void synchronize_sched(void) - } - EXPORT_SYMBOL_GPL(synchronize_sched); - -+#ifndef CONFIG_PREEMPT_RT_FULL - /** - * synchronize_rcu_bh - wait until an rcu_bh grace period has elapsed. - * -@@ -3224,6 +3344,7 @@ void synchronize_rcu_bh(void) - wait_rcu_gp(call_rcu_bh); - } - EXPORT_SYMBOL_GPL(synchronize_rcu_bh); -+#endif - - /** - * get_state_synchronize_rcu - Snapshot current RCU state -@@ -4104,6 +4225,7 @@ static void _rcu_barrier(struct rcu_state *rsp) - mutex_unlock(&rsp->barrier_mutex); - } - -+#ifndef CONFIG_PREEMPT_RT_FULL - /** - * rcu_barrier_bh - Wait until all in-flight call_rcu_bh() callbacks complete. - */ -@@ -4112,6 +4234,7 @@ void rcu_barrier_bh(void) - _rcu_barrier(&rcu_bh_state); - } - EXPORT_SYMBOL_GPL(rcu_barrier_bh); -+#endif - - /** - * rcu_barrier_sched - Wait for in-flight call_rcu_sched() callbacks. -@@ -4609,12 +4732,13 @@ void __init rcu_init(void) - - rcu_bootup_announce(); - rcu_init_geometry(); -+#ifndef CONFIG_PREEMPT_RT_FULL - rcu_init_one(&rcu_bh_state); -+#endif - rcu_init_one(&rcu_sched_state); - if (dump_tree) - rcu_dump_rcu_node_tree(&rcu_sched_state); - __rcu_init_preempt(); -- open_softirq(RCU_SOFTIRQ, rcu_process_callbacks); - - /* - * We don't need protection against CPU-hotplug here because -diff --git a/kernel/rcu/tree.h b/kernel/rcu/tree.h -index df668c0..dd3efa3 100644 ---- a/kernel/rcu/tree.h -+++ b/kernel/rcu/tree.h -@@ -572,18 +572,18 @@ extern struct list_head rcu_struct_flavors; - */ - extern struct rcu_state rcu_sched_state; - -+#ifndef CONFIG_PREEMPT_RT_FULL - extern struct rcu_state rcu_bh_state; -+#endif - - #ifdef CONFIG_PREEMPT_RCU - extern struct rcu_state rcu_preempt_state; - #endif /* #ifdef CONFIG_PREEMPT_RCU */ - --#ifdef CONFIG_RCU_BOOST - DECLARE_PER_CPU(unsigned int, rcu_cpu_kthread_status); - DECLARE_PER_CPU(int, rcu_cpu_kthread_cpu); - DECLARE_PER_CPU(unsigned int, rcu_cpu_kthread_loops); - DECLARE_PER_CPU(char, rcu_cpu_has_work); --#endif /* #ifdef CONFIG_RCU_BOOST */ - - #ifndef RCU_TREE_NONCORE - -@@ -603,10 +603,9 @@ void call_rcu(struct rcu_head *head, rcu_callback_t func); - static void __init __rcu_init_preempt(void); - static void rcu_initiate_boost(struct rcu_node *rnp, unsigned long flags); - static void rcu_preempt_boost_start_gp(struct rcu_node *rnp); --static void invoke_rcu_callbacks_kthread(void); - static bool rcu_is_callbacks_kthread(void); -+static void rcu_cpu_kthread_setup(unsigned int cpu); - #ifdef CONFIG_RCU_BOOST --static void rcu_preempt_do_callbacks(void); - static int rcu_spawn_one_boost_kthread(struct rcu_state *rsp, - struct rcu_node *rnp); - #endif /* #ifdef CONFIG_RCU_BOOST */ -diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h -index efdf7b6..6a4158a 100644 ---- a/kernel/rcu/tree_plugin.h -+++ b/kernel/rcu/tree_plugin.h -@@ -24,25 +24,10 @@ - * Paul E. McKenney <paulmck@linux.vnet.ibm.com> - */ - --#include <linux/delay.h> --#include <linux/gfp.h> --#include <linux/oom.h> --#include <linux/smpboot.h> --#include "../time/tick-internal.h" -- - #ifdef CONFIG_RCU_BOOST - - #include "../locking/rtmutex_common.h" - --/* -- * Control variables for per-CPU and per-rcu_node kthreads. These -- * handle all flavors of RCU. -- */ --static DEFINE_PER_CPU(struct task_struct *, rcu_cpu_kthread_task); --DEFINE_PER_CPU(unsigned int, rcu_cpu_kthread_status); --DEFINE_PER_CPU(unsigned int, rcu_cpu_kthread_loops); --DEFINE_PER_CPU(char, rcu_cpu_has_work); -- - #else /* #ifdef CONFIG_RCU_BOOST */ - - /* -@@ -55,6 +40,14 @@ DEFINE_PER_CPU(char, rcu_cpu_has_work); - - #endif /* #else #ifdef CONFIG_RCU_BOOST */ - -+/* -+ * Control variables for per-CPU and per-rcu_node kthreads. These -+ * handle all flavors of RCU. -+ */ -+DEFINE_PER_CPU(unsigned int, rcu_cpu_kthread_status); -+DEFINE_PER_CPU(unsigned int, rcu_cpu_kthread_loops); -+DEFINE_PER_CPU(char, rcu_cpu_has_work); -+ - #ifdef CONFIG_RCU_NOCB_CPU - static cpumask_var_t rcu_nocb_mask; /* CPUs to have callbacks offloaded. */ - static bool have_rcu_nocb_mask; /* Was rcu_nocb_mask allocated? */ -@@ -428,7 +421,7 @@ void rcu_read_unlock_special(struct task_struct *t) - } - - /* Hardware IRQ handlers cannot block, complain if they get here. */ -- if (in_irq() || in_serving_softirq()) { -+ if (preempt_count() & (HARDIRQ_MASK | SOFTIRQ_OFFSET)) { - lockdep_rcu_suspicious(__FILE__, __LINE__, - "rcu_read_unlock() from irq or softirq with blocking in critical section!!!\n"); - pr_alert("->rcu_read_unlock_special: %#x (b: %d, enq: %d nq: %d)\n", -@@ -634,15 +627,6 @@ static void rcu_preempt_check_callbacks(void) - t->rcu_read_unlock_special.b.need_qs = true; - } - --#ifdef CONFIG_RCU_BOOST -- --static void rcu_preempt_do_callbacks(void) --{ -- rcu_do_batch(rcu_state_p, this_cpu_ptr(rcu_data_p)); --} -- --#endif /* #ifdef CONFIG_RCU_BOOST */ -- - /* - * Queue a preemptible-RCU callback for invocation after a grace period. - */ -@@ -924,6 +908,19 @@ void exit_rcu(void) - - #endif /* #else #ifdef CONFIG_PREEMPT_RCU */ - -+/* -+ * If boosting, set rcuc kthreads to realtime priority. -+ */ -+static void rcu_cpu_kthread_setup(unsigned int cpu) -+{ -+#ifdef CONFIG_RCU_BOOST -+ struct sched_param sp; -+ -+ sp.sched_priority = kthread_prio; -+ sched_setscheduler_nocheck(current, SCHED_FIFO, &sp); -+#endif /* #ifdef CONFIG_RCU_BOOST */ -+} -+ - #ifdef CONFIG_RCU_BOOST - - #include "../locking/rtmutex_common.h" -@@ -955,16 +952,6 @@ static void rcu_initiate_boost_trace(struct rcu_node *rnp) - - #endif /* #else #ifdef CONFIG_RCU_TRACE */ - --static void rcu_wake_cond(struct task_struct *t, int status) --{ -- /* -- * If the thread is yielding, only wake it when this -- * is invoked from idle -- */ -- if (status != RCU_KTHREAD_YIELDING || is_idle_task(current)) -- wake_up_process(t); --} -- - /* - * Carry out RCU priority boosting on the task indicated by ->exp_tasks - * or ->boost_tasks, advancing the pointer to the next task in the -@@ -1108,23 +1095,6 @@ static void rcu_initiate_boost(struct rcu_node *rnp, unsigned long flags) - } - - /* -- * Wake up the per-CPU kthread to invoke RCU callbacks. -- */ --static void invoke_rcu_callbacks_kthread(void) --{ -- unsigned long flags; -- -- local_irq_save(flags); -- __this_cpu_write(rcu_cpu_has_work, 1); -- if (__this_cpu_read(rcu_cpu_kthread_task) != NULL && -- current != __this_cpu_read(rcu_cpu_kthread_task)) { -- rcu_wake_cond(__this_cpu_read(rcu_cpu_kthread_task), -- __this_cpu_read(rcu_cpu_kthread_status)); -- } -- local_irq_restore(flags); --} -- --/* - * Is the current CPU running the RCU-callbacks kthread? - * Caller must have preemption disabled. - */ -@@ -1178,67 +1148,6 @@ static int rcu_spawn_one_boost_kthread(struct rcu_state *rsp, - return 0; - } - --static void rcu_kthread_do_work(void) --{ -- rcu_do_batch(&rcu_sched_state, this_cpu_ptr(&rcu_sched_data)); -- rcu_do_batch(&rcu_bh_state, this_cpu_ptr(&rcu_bh_data)); -- rcu_preempt_do_callbacks(); --} -- --static void rcu_cpu_kthread_setup(unsigned int cpu) --{ -- struct sched_param sp; -- -- sp.sched_priority = kthread_prio; -- sched_setscheduler_nocheck(current, SCHED_FIFO, &sp); --} -- --static void rcu_cpu_kthread_park(unsigned int cpu) --{ -- per_cpu(rcu_cpu_kthread_status, cpu) = RCU_KTHREAD_OFFCPU; --} -- --static int rcu_cpu_kthread_should_run(unsigned int cpu) --{ -- return __this_cpu_read(rcu_cpu_has_work); --} -- --/* -- * Per-CPU kernel thread that invokes RCU callbacks. This replaces the -- * RCU softirq used in flavors and configurations of RCU that do not -- * support RCU priority boosting. -- */ --static void rcu_cpu_kthread(unsigned int cpu) --{ -- unsigned int *statusp = this_cpu_ptr(&rcu_cpu_kthread_status); -- char work, *workp = this_cpu_ptr(&rcu_cpu_has_work); -- int spincnt; -- -- for (spincnt = 0; spincnt < 10; spincnt++) { -- trace_rcu_utilization(TPS("Start CPU kthread@rcu_wait")); -- local_bh_disable(); -- *statusp = RCU_KTHREAD_RUNNING; -- this_cpu_inc(rcu_cpu_kthread_loops); -- local_irq_disable(); -- work = *workp; -- *workp = 0; -- local_irq_enable(); -- if (work) -- rcu_kthread_do_work(); -- local_bh_enable(); -- if (*workp == 0) { -- trace_rcu_utilization(TPS("End CPU kthread@rcu_wait")); -- *statusp = RCU_KTHREAD_WAITING; -- return; -- } -- } -- *statusp = RCU_KTHREAD_YIELDING; -- trace_rcu_utilization(TPS("Start CPU kthread@rcu_yield")); -- schedule_timeout_interruptible(2); -- trace_rcu_utilization(TPS("End CPU kthread@rcu_yield")); -- *statusp = RCU_KTHREAD_WAITING; --} -- - /* - * Set the per-rcu_node kthread's affinity to cover all CPUs that are - * served by the rcu_node in question. The CPU hotplug lock is still -@@ -1268,26 +1177,12 @@ static void rcu_boost_kthread_setaffinity(struct rcu_node *rnp, int outgoingcpu) - free_cpumask_var(cm); - } - --static struct smp_hotplug_thread rcu_cpu_thread_spec = { -- .store = &rcu_cpu_kthread_task, -- .thread_should_run = rcu_cpu_kthread_should_run, -- .thread_fn = rcu_cpu_kthread, -- .thread_comm = "rcuc/%u", -- .setup = rcu_cpu_kthread_setup, -- .park = rcu_cpu_kthread_park, --}; -- - /* - * Spawn boost kthreads -- called as soon as the scheduler is running. - */ - static void __init rcu_spawn_boost_kthreads(void) - { - struct rcu_node *rnp; -- int cpu; -- -- for_each_possible_cpu(cpu) -- per_cpu(rcu_cpu_has_work, cpu) = 0; -- BUG_ON(smpboot_register_percpu_thread(&rcu_cpu_thread_spec)); - rcu_for_each_leaf_node(rcu_state_p, rnp) - (void)rcu_spawn_one_boost_kthread(rcu_state_p, rnp); - } -@@ -1310,11 +1205,6 @@ static void rcu_initiate_boost(struct rcu_node *rnp, unsigned long flags) - raw_spin_unlock_irqrestore_rcu_node(rnp, flags); - } - --static void invoke_rcu_callbacks_kthread(void) --{ -- WARN_ON_ONCE(1); --} -- - static bool rcu_is_callbacks_kthread(void) - { - return false; -@@ -1338,7 +1228,7 @@ static void rcu_prepare_kthreads(int cpu) - - #endif /* #else #ifdef CONFIG_RCU_BOOST */ - --#if !defined(CONFIG_RCU_FAST_NO_HZ) -+#if !defined(CONFIG_RCU_FAST_NO_HZ) || defined(CONFIG_PREEMPT_RT_FULL) - - /* - * Check to see if any future RCU-related work will need to be done -@@ -1355,7 +1245,9 @@ int rcu_needs_cpu(u64 basemono, u64 *nextevt) - return IS_ENABLED(CONFIG_RCU_NOCB_CPU_ALL) - ? 0 : rcu_cpu_has_callbacks(NULL); - } -+#endif /* !defined(CONFIG_RCU_FAST_NO_HZ) || defined(CONFIG_PREEMPT_RT_FULL) */ - -+#if !defined(CONFIG_RCU_FAST_NO_HZ) - /* - * Because we do not have RCU_FAST_NO_HZ, don't bother cleaning up - * after it. -@@ -1451,6 +1343,8 @@ static bool __maybe_unused rcu_try_advance_all_cbs(void) - return cbs_ready; - } - -+#ifndef CONFIG_PREEMPT_RT_FULL -+ - /* - * Allow the CPU to enter dyntick-idle mode unless it has callbacks ready - * to invoke. If the CPU has callbacks, try to advance them. Tell the -@@ -1496,6 +1390,7 @@ int rcu_needs_cpu(u64 basemono, u64 *nextevt) - *nextevt = basemono + dj * TICK_NSEC; - return 0; - } -+#endif /* #ifndef CONFIG_PREEMPT_RT_FULL */ - - /* - * Prepare a CPU for idle from an RCU perspective. The first major task -diff --git a/kernel/rcu/update.c b/kernel/rcu/update.c -index ca828b4..6cbf7a9 100644 ---- a/kernel/rcu/update.c -+++ b/kernel/rcu/update.c -@@ -295,6 +295,7 @@ int rcu_read_lock_held(void) - } - EXPORT_SYMBOL_GPL(rcu_read_lock_held); - -+#ifndef CONFIG_PREEMPT_RT_FULL - /** - * rcu_read_lock_bh_held() - might we be in RCU-bh read-side critical section? - * -@@ -321,6 +322,7 @@ int rcu_read_lock_bh_held(void) - return in_softirq() || irqs_disabled(); - } - EXPORT_SYMBOL_GPL(rcu_read_lock_bh_held); -+#endif - - #endif /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */ - -diff --git a/kernel/relay.c b/kernel/relay.c -index 074994b..7206cef 100644 ---- a/kernel/relay.c -+++ b/kernel/relay.c -@@ -336,6 +336,10 @@ static void wakeup_readers(unsigned long data) - { - struct rchan_buf *buf = (struct rchan_buf *)data; - wake_up_interruptible(&buf->read_wait); -+ /* -+ * Stupid polling for now: -+ */ -+ mod_timer(&buf->timer, jiffies + 1); - } - - /** -@@ -353,6 +357,7 @@ static void __relay_reset(struct rchan_buf *buf, unsigned int init) - init_waitqueue_head(&buf->read_wait); - kref_init(&buf->kref); - setup_timer(&buf->timer, wakeup_readers, (unsigned long)buf); -+ mod_timer(&buf->timer, jiffies + 1); - } else - del_timer_sync(&buf->timer); - -@@ -736,15 +741,6 @@ size_t relay_switch_subbuf(struct rchan_buf *buf, size_t length) - else - buf->early_bytes += buf->chan->subbuf_size - - buf->padding[old_subbuf]; -- smp_mb(); -- if (waitqueue_active(&buf->read_wait)) -- /* -- * Calling wake_up_interruptible() from here -- * will deadlock if we happen to be logging -- * from the scheduler (trying to re-grab -- * rq->lock), so defer it. -- */ -- mod_timer(&buf->timer, jiffies + 1); - } - - old = buf->data; -diff --git a/kernel/sched/Makefile b/kernel/sched/Makefile -index 414d9c1..b9e72e2 100644 ---- a/kernel/sched/Makefile -+++ b/kernel/sched/Makefile -@@ -17,7 +17,7 @@ endif - - obj-y += core.o loadavg.o clock.o cputime.o - obj-y += idle_task.o fair.o rt.o deadline.o stop_task.o --obj-y += wait.o swait.o completion.o idle.o -+obj-y += wait.o swait.o work-simple.o completion.o idle.o - obj-$(CONFIG_SMP) += cpupri.o cpudeadline.o - obj-$(CONFIG_SCHED_AUTOGROUP) += auto_group.o - obj-$(CONFIG_SCHEDSTATS) += stats.o -diff --git a/kernel/sched/completion.c b/kernel/sched/completion.c -index 8d0f35d..b62cf64 100644 ---- a/kernel/sched/completion.c -+++ b/kernel/sched/completion.c -@@ -30,10 +30,10 @@ void complete(struct completion *x) - { - unsigned long flags; - -- spin_lock_irqsave(&x->wait.lock, flags); -+ raw_spin_lock_irqsave(&x->wait.lock, flags); - x->done++; -- __wake_up_locked(&x->wait, TASK_NORMAL, 1); -- spin_unlock_irqrestore(&x->wait.lock, flags); -+ swake_up_locked(&x->wait); -+ raw_spin_unlock_irqrestore(&x->wait.lock, flags); - } - EXPORT_SYMBOL(complete); - -@@ -50,10 +50,10 @@ void complete_all(struct completion *x) - { - unsigned long flags; - -- spin_lock_irqsave(&x->wait.lock, flags); -+ raw_spin_lock_irqsave(&x->wait.lock, flags); - x->done += UINT_MAX/2; -- __wake_up_locked(&x->wait, TASK_NORMAL, 0); -- spin_unlock_irqrestore(&x->wait.lock, flags); -+ swake_up_all_locked(&x->wait); -+ raw_spin_unlock_irqrestore(&x->wait.lock, flags); - } - EXPORT_SYMBOL(complete_all); - -@@ -62,20 +62,20 @@ do_wait_for_common(struct completion *x, - long (*action)(long), long timeout, int state) - { - if (!x->done) { -- DECLARE_WAITQUEUE(wait, current); -+ DECLARE_SWAITQUEUE(wait); - -- __add_wait_queue_tail_exclusive(&x->wait, &wait); -+ __prepare_to_swait(&x->wait, &wait); - do { - if (signal_pending_state(state, current)) { - timeout = -ERESTARTSYS; - break; - } - __set_current_state(state); -- spin_unlock_irq(&x->wait.lock); -+ raw_spin_unlock_irq(&x->wait.lock); - timeout = action(timeout); -- spin_lock_irq(&x->wait.lock); -+ raw_spin_lock_irq(&x->wait.lock); - } while (!x->done && timeout); -- __remove_wait_queue(&x->wait, &wait); -+ __finish_swait(&x->wait, &wait); - if (!x->done) - return timeout; - } -@@ -89,9 +89,9 @@ __wait_for_common(struct completion *x, - { - might_sleep(); - -- spin_lock_irq(&x->wait.lock); -+ raw_spin_lock_irq(&x->wait.lock); - timeout = do_wait_for_common(x, action, timeout, state); -- spin_unlock_irq(&x->wait.lock); -+ raw_spin_unlock_irq(&x->wait.lock); - return timeout; - } - -@@ -277,12 +277,12 @@ bool try_wait_for_completion(struct completion *x) - if (!READ_ONCE(x->done)) - return 0; - -- spin_lock_irqsave(&x->wait.lock, flags); -+ raw_spin_lock_irqsave(&x->wait.lock, flags); - if (!x->done) - ret = 0; - else - x->done--; -- spin_unlock_irqrestore(&x->wait.lock, flags); -+ raw_spin_unlock_irqrestore(&x->wait.lock, flags); - return ret; - } - EXPORT_SYMBOL(try_wait_for_completion); -@@ -311,7 +311,7 @@ bool completion_done(struct completion *x) - * after it's acquired the lock. - */ - smp_rmb(); -- spin_unlock_wait(&x->wait.lock); -+ raw_spin_unlock_wait(&x->wait.lock); - return true; - } - EXPORT_SYMBOL(completion_done); -diff --git a/kernel/sched/core.c b/kernel/sched/core.c -index d1f7149..826ed90 100644 ---- a/kernel/sched/core.c -+++ b/kernel/sched/core.c -@@ -128,7 +128,11 @@ const_debug unsigned int sysctl_sched_features = - * Number of tasks to iterate in a single balance run. - * Limited because this is done with IRQs disabled. - */ -+#ifndef CONFIG_PREEMPT_RT_FULL - const_debug unsigned int sysctl_sched_nr_migrate = 32; -+#else -+const_debug unsigned int sysctl_sched_nr_migrate = 8; -+#endif - - /* - * period over which we average the RT time consumption, measured -@@ -306,6 +310,7 @@ static void init_rq_hrtick(struct rq *rq) - - hrtimer_init(&rq->hrtick_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - rq->hrtick_timer.function = hrtick; -+ rq->hrtick_timer.irqsafe = 1; - } - #else /* CONFIG_SCHED_HRTICK */ - static inline void hrtick_clear(struct rq *rq) -@@ -414,7 +419,7 @@ void wake_q_add(struct wake_q_head *head, struct task_struct *task) - head->lastp = &node->next; - } - --void wake_up_q(struct wake_q_head *head) -+void __wake_up_q(struct wake_q_head *head, bool sleeper) - { - struct wake_q_node *node = head->first; - -@@ -431,7 +436,10 @@ void wake_up_q(struct wake_q_head *head) - * wake_up_process() implies a wmb() to pair with the queueing - * in wake_q_add() so as not to miss wakeups. - */ -- wake_up_process(task); -+ if (sleeper) -+ wake_up_lock_sleeper(task); -+ else -+ wake_up_process(task); - put_task_struct(task); - } - } -@@ -467,6 +475,38 @@ void resched_curr(struct rq *rq) - trace_sched_wake_idle_without_ipi(cpu); - } - -+#ifdef CONFIG_PREEMPT_LAZY -+void resched_curr_lazy(struct rq *rq) -+{ -+ struct task_struct *curr = rq->curr; -+ int cpu; -+ -+ if (!sched_feat(PREEMPT_LAZY)) { -+ resched_curr(rq); -+ return; -+ } -+ -+ lockdep_assert_held(&rq->lock); -+ -+ if (test_tsk_need_resched(curr)) -+ return; -+ -+ if (test_tsk_need_resched_lazy(curr)) -+ return; -+ -+ set_tsk_need_resched_lazy(curr); -+ -+ cpu = cpu_of(rq); -+ if (cpu == smp_processor_id()) -+ return; -+ -+ /* NEED_RESCHED_LAZY must be visible before we test polling */ -+ smp_mb(); -+ if (!tsk_is_polling(curr)) -+ smp_send_reschedule(cpu); -+} -+#endif -+ - void resched_cpu(int cpu) - { - struct rq *rq = cpu_rq(cpu); -@@ -490,11 +530,14 @@ void resched_cpu(int cpu) - */ - int get_nohz_timer_target(void) - { -- int i, cpu = smp_processor_id(); -+ int i, cpu; - struct sched_domain *sd; - -+ preempt_disable_rt(); -+ cpu = smp_processor_id(); -+ - if (!idle_cpu(cpu) && is_housekeeping_cpu(cpu)) -- return cpu; -+ goto preempt_en_rt; - - rcu_read_lock(); - for_each_domain(cpu, sd) { -@@ -510,6 +553,8 @@ int get_nohz_timer_target(void) - cpu = housekeeping_any_cpu(); - unlock: - rcu_read_unlock(); -+preempt_en_rt: -+ preempt_enable_rt(); - return cpu; - } - /* -@@ -1051,6 +1096,11 @@ void do_set_cpus_allowed(struct task_struct *p, const struct cpumask *new_mask) - - lockdep_assert_held(&p->pi_lock); - -+ if (__migrate_disabled(p)) { -+ cpumask_copy(&p->cpus_allowed, new_mask); -+ return; -+ } -+ - queued = task_on_rq_queued(p); - running = task_current(rq, p); - -@@ -1073,6 +1123,84 @@ void do_set_cpus_allowed(struct task_struct *p, const struct cpumask *new_mask) - enqueue_task(rq, p, ENQUEUE_RESTORE); - } - -+static DEFINE_PER_CPU(struct cpumask, sched_cpumasks); -+static DEFINE_MUTEX(sched_down_mutex); -+static cpumask_t sched_down_cpumask; -+ -+void tell_sched_cpu_down_begin(int cpu) -+{ -+ mutex_lock(&sched_down_mutex); -+ cpumask_set_cpu(cpu, &sched_down_cpumask); -+ mutex_unlock(&sched_down_mutex); -+} -+ -+void tell_sched_cpu_down_done(int cpu) -+{ -+ mutex_lock(&sched_down_mutex); -+ cpumask_clear_cpu(cpu, &sched_down_cpumask); -+ mutex_unlock(&sched_down_mutex); -+} -+ -+/** -+ * migrate_me - try to move the current task off this cpu -+ * -+ * Used by the pin_current_cpu() code to try to get tasks -+ * to move off the current CPU as it is going down. -+ * It will only move the task if the task isn't pinned to -+ * the CPU (with migrate_disable, affinity or NO_SETAFFINITY) -+ * and the task has to be in a RUNNING state. Otherwise the -+ * movement of the task will wake it up (change its state -+ * to running) when the task did not expect it. -+ * -+ * Returns 1 if it succeeded in moving the current task -+ * 0 otherwise. -+ */ -+int migrate_me(void) -+{ -+ struct task_struct *p = current; -+ struct migration_arg arg; -+ struct cpumask *cpumask; -+ struct cpumask *mask; -+ unsigned long flags; -+ unsigned int dest_cpu; -+ struct rq *rq; -+ -+ /* -+ * We can not migrate tasks bounded to a CPU or tasks not -+ * running. The movement of the task will wake it up. -+ */ -+ if (p->flags & PF_NO_SETAFFINITY || p->state) -+ return 0; -+ -+ mutex_lock(&sched_down_mutex); -+ rq = task_rq_lock(p, &flags); -+ -+ cpumask = this_cpu_ptr(&sched_cpumasks); -+ mask = &p->cpus_allowed; -+ -+ cpumask_andnot(cpumask, mask, &sched_down_cpumask); -+ -+ if (!cpumask_weight(cpumask)) { -+ /* It's only on this CPU? */ -+ task_rq_unlock(rq, p, &flags); -+ mutex_unlock(&sched_down_mutex); -+ return 0; -+ } -+ -+ dest_cpu = cpumask_any_and(cpu_active_mask, cpumask); -+ -+ arg.task = p; -+ arg.dest_cpu = dest_cpu; -+ -+ task_rq_unlock(rq, p, &flags); -+ -+ stop_one_cpu(cpu_of(rq), migration_cpu_stop, &arg); -+ tlb_migrate_finish(p->mm); -+ mutex_unlock(&sched_down_mutex); -+ -+ return 1; -+} -+ - /* - * Change a given task's CPU affinity. Migrate the thread to a - * proper CPU and schedule it away if the CPU it's executing on -@@ -1112,7 +1240,7 @@ static int __set_cpus_allowed_ptr(struct task_struct *p, - do_set_cpus_allowed(p, new_mask); - - /* Can the task run on the task's current CPU? If so, we're done */ -- if (cpumask_test_cpu(task_cpu(p), new_mask)) -+ if (cpumask_test_cpu(task_cpu(p), new_mask) || __migrate_disabled(p)) - goto out; - - dest_cpu = cpumask_any_and(cpu_active_mask, new_mask); -@@ -1299,6 +1427,18 @@ out: - return ret; - } - -+static bool check_task_state(struct task_struct *p, long match_state) -+{ -+ bool match = false; -+ -+ raw_spin_lock_irq(&p->pi_lock); -+ if (p->state == match_state || p->saved_state == match_state) -+ match = true; -+ raw_spin_unlock_irq(&p->pi_lock); -+ -+ return match; -+} -+ - /* - * wait_task_inactive - wait for a thread to unschedule. - * -@@ -1343,7 +1483,7 @@ unsigned long wait_task_inactive(struct task_struct *p, long match_state) - * is actually now running somewhere else! - */ - while (task_running(rq, p)) { -- if (match_state && unlikely(p->state != match_state)) -+ if (match_state && !check_task_state(p, match_state)) - return 0; - cpu_relax(); - } -@@ -1358,7 +1498,8 @@ unsigned long wait_task_inactive(struct task_struct *p, long match_state) - running = task_running(rq, p); - queued = task_on_rq_queued(p); - ncsw = 0; -- if (!match_state || p->state == match_state) -+ if (!match_state || p->state == match_state || -+ p->saved_state == match_state) - ncsw = p->nvcsw | LONG_MIN; /* sets MSB */ - task_rq_unlock(rq, p, &flags); - -@@ -1515,7 +1656,7 @@ int select_task_rq(struct task_struct *p, int cpu, int sd_flags, int wake_flags) - { - lockdep_assert_held(&p->pi_lock); - -- if (p->nr_cpus_allowed > 1) -+ if (tsk_nr_cpus_allowed(p) > 1) - cpu = p->sched_class->select_task_rq(p, cpu, sd_flags, wake_flags); - - /* -@@ -1595,10 +1736,6 @@ static inline void ttwu_activate(struct rq *rq, struct task_struct *p, int en_fl - { - activate_task(rq, p, en_flags); - p->on_rq = TASK_ON_RQ_QUEUED; -- -- /* if a worker is waking up, notify workqueue */ -- if (p->flags & PF_WQ_WORKER) -- wq_worker_waking_up(p, cpu_of(rq)); - } - - /* -@@ -1916,8 +2053,27 @@ try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags) - */ - smp_mb__before_spinlock(); - raw_spin_lock_irqsave(&p->pi_lock, flags); -- if (!(p->state & state)) -+ if (!(p->state & state)) { -+ /* -+ * The task might be running due to a spinlock sleeper -+ * wakeup. Check the saved state and set it to running -+ * if the wakeup condition is true. -+ */ -+ if (!(wake_flags & WF_LOCK_SLEEPER)) { -+ if (p->saved_state & state) { -+ p->saved_state = TASK_RUNNING; -+ success = 1; -+ } -+ } - goto out; -+ } -+ -+ /* -+ * If this is a regular wakeup, then we can unconditionally -+ * clear the saved state of a "lock sleeper". -+ */ -+ if (!(wake_flags & WF_LOCK_SLEEPER)) -+ p->saved_state = TASK_RUNNING; - - trace_sched_waking(p); - -@@ -1982,53 +2138,6 @@ out: - } - - /** -- * try_to_wake_up_local - try to wake up a local task with rq lock held -- * @p: the thread to be awakened -- * -- * Put @p on the run-queue if it's not already there. The caller must -- * ensure that this_rq() is locked, @p is bound to this_rq() and not -- * the current task. -- */ --static void try_to_wake_up_local(struct task_struct *p) --{ -- struct rq *rq = task_rq(p); -- -- if (WARN_ON_ONCE(rq != this_rq()) || -- WARN_ON_ONCE(p == current)) -- return; -- -- lockdep_assert_held(&rq->lock); -- -- if (!raw_spin_trylock(&p->pi_lock)) { -- /* -- * This is OK, because current is on_cpu, which avoids it being -- * picked for load-balance and preemption/IRQs are still -- * disabled avoiding further scheduler activity on it and we've -- * not yet picked a replacement task. -- */ -- lockdep_unpin_lock(&rq->lock); -- raw_spin_unlock(&rq->lock); -- raw_spin_lock(&p->pi_lock); -- raw_spin_lock(&rq->lock); -- lockdep_pin_lock(&rq->lock); -- } -- -- if (!(p->state & TASK_NORMAL)) -- goto out; -- -- trace_sched_waking(p); -- -- if (!task_on_rq_queued(p)) -- ttwu_activate(rq, p, ENQUEUE_WAKEUP); -- -- ttwu_do_wakeup(rq, p, 0); -- if (schedstat_enabled()) -- ttwu_stat(p, smp_processor_id(), 0); --out: -- raw_spin_unlock(&p->pi_lock); --} -- --/** - * wake_up_process - Wake up a specific process - * @p: The process to be woken up. - * -@@ -2046,6 +2155,18 @@ int wake_up_process(struct task_struct *p) - } - EXPORT_SYMBOL(wake_up_process); - -+/** -+ * wake_up_lock_sleeper - Wake up a specific process blocked on a "sleeping lock" -+ * @p: The process to be woken up. -+ * -+ * Same as wake_up_process() above, but wake_flags=WF_LOCK_SLEEPER to indicate -+ * the nature of the wakeup. -+ */ -+int wake_up_lock_sleeper(struct task_struct *p) -+{ -+ return try_to_wake_up(p, TASK_ALL, WF_LOCK_SLEEPER); -+} -+ - int wake_up_state(struct task_struct *p, unsigned int state) - { - return try_to_wake_up(p, state, 0); -@@ -2303,6 +2424,9 @@ int sched_fork(unsigned long clone_flags, struct task_struct *p) - p->on_cpu = 0; - #endif - init_task_preempt_count(p); -+#ifdef CONFIG_HAVE_PREEMPT_LAZY -+ task_thread_info(p)->preempt_lazy_count = 0; -+#endif - #ifdef CONFIG_SMP - plist_node_init(&p->pushable_tasks, MAX_PRIO); - RB_CLEAR_NODE(&p->pushable_dl_tasks); -@@ -2627,8 +2751,12 @@ static struct rq *finish_task_switch(struct task_struct *prev) - finish_arch_post_lock_switch(); - - fire_sched_in_preempt_notifiers(current); -+ /* -+ * We use mmdrop_delayed() here so we don't have to do the -+ * full __mmdrop() when we are the last user. -+ */ - if (mm) -- mmdrop(mm); -+ mmdrop_delayed(mm); - if (unlikely(prev_state == TASK_DEAD)) { - if (prev->sched_class->task_dead) - prev->sched_class->task_dead(prev); -@@ -3061,6 +3189,77 @@ static inline void schedule_debug(struct task_struct *prev) - schedstat_inc(this_rq(), sched_count); - } - -+#if defined(CONFIG_PREEMPT_RT_FULL) && defined(CONFIG_SMP) -+ -+void migrate_disable(void) -+{ -+ struct task_struct *p = current; -+ -+ if (in_atomic() || irqs_disabled()) { -+#ifdef CONFIG_SCHED_DEBUG -+ p->migrate_disable_atomic++; -+#endif -+ return; -+ } -+ -+#ifdef CONFIG_SCHED_DEBUG -+ if (unlikely(p->migrate_disable_atomic)) { -+ tracing_off(); -+ WARN_ON_ONCE(1); -+ } -+#endif -+ -+ if (p->migrate_disable) { -+ p->migrate_disable++; -+ return; -+ } -+ -+ preempt_disable(); -+ preempt_lazy_disable(); -+ pin_current_cpu(); -+ p->migrate_disable = 1; -+ preempt_enable(); -+} -+EXPORT_SYMBOL(migrate_disable); -+ -+void migrate_enable(void) -+{ -+ struct task_struct *p = current; -+ -+ if (in_atomic() || irqs_disabled()) { -+#ifdef CONFIG_SCHED_DEBUG -+ p->migrate_disable_atomic--; -+#endif -+ return; -+ } -+ -+#ifdef CONFIG_SCHED_DEBUG -+ if (unlikely(p->migrate_disable_atomic)) { -+ tracing_off(); -+ WARN_ON_ONCE(1); -+ } -+#endif -+ WARN_ON_ONCE(p->migrate_disable <= 0); -+ -+ if (p->migrate_disable > 1) { -+ p->migrate_disable--; -+ return; -+ } -+ -+ preempt_disable(); -+ /* -+ * Clearing migrate_disable causes tsk_cpus_allowed to -+ * show the tasks original cpu affinity. -+ */ -+ p->migrate_disable = 0; -+ -+ unpin_current_cpu(); -+ preempt_enable(); -+ preempt_lazy_enable(); -+} -+EXPORT_SYMBOL(migrate_enable); -+#endif -+ - /* - * Pick up the highest-prio task: - */ -@@ -3187,19 +3386,6 @@ static void __sched notrace __schedule(bool preempt) - } else { - deactivate_task(rq, prev, DEQUEUE_SLEEP); - prev->on_rq = 0; -- -- /* -- * If a worker went to sleep, notify and ask workqueue -- * whether it wants to wake up a task to maintain -- * concurrency. -- */ -- if (prev->flags & PF_WQ_WORKER) { -- struct task_struct *to_wakeup; -- -- to_wakeup = wq_worker_sleeping(prev); -- if (to_wakeup) -- try_to_wake_up_local(to_wakeup); -- } - } - switch_count = &prev->nvcsw; - } -@@ -3209,6 +3395,7 @@ static void __sched notrace __schedule(bool preempt) - - next = pick_next_task(rq, prev); - clear_tsk_need_resched(prev); -+ clear_tsk_need_resched_lazy(prev); - clear_preempt_need_resched(); - rq->clock_skip_update = 0; - -@@ -3230,9 +3417,20 @@ STACK_FRAME_NON_STANDARD(__schedule); /* switch_to() */ - - static inline void sched_submit_work(struct task_struct *tsk) - { -- if (!tsk->state || tsk_is_pi_blocked(tsk)) -+ if (!tsk->state) - return; - /* -+ * If a worker went to sleep, notify and ask workqueue whether -+ * it wants to wake up a task to maintain concurrency. -+ */ -+ if (tsk->flags & PF_WQ_WORKER) -+ wq_worker_sleeping(tsk); -+ -+ -+ if (tsk_is_pi_blocked(tsk)) -+ return; -+ -+ /* - * If we are going to sleep and we have plugged IO queued, - * make sure to submit it to avoid deadlocks. - */ -@@ -3240,6 +3438,12 @@ static inline void sched_submit_work(struct task_struct *tsk) - blk_schedule_flush_plug(tsk); - } - -+static void sched_update_worker(struct task_struct *tsk) -+{ -+ if (tsk->flags & PF_WQ_WORKER) -+ wq_worker_running(tsk); -+} -+ - asmlinkage __visible void __sched schedule(void) - { - struct task_struct *tsk = current; -@@ -3250,6 +3454,7 @@ asmlinkage __visible void __sched schedule(void) - __schedule(false); - sched_preempt_enable_no_resched(); - } while (need_resched()); -+ sched_update_worker(tsk); - } - EXPORT_SYMBOL(schedule); - -@@ -3298,6 +3503,30 @@ static void __sched notrace preempt_schedule_common(void) - } while (need_resched()); - } - -+#ifdef CONFIG_PREEMPT_LAZY -+/* -+ * If TIF_NEED_RESCHED is then we allow to be scheduled away since this is -+ * set by a RT task. Oterwise we try to avoid beeing scheduled out as long as -+ * preempt_lazy_count counter >0. -+ */ -+static __always_inline int preemptible_lazy(void) -+{ -+ if (test_thread_flag(TIF_NEED_RESCHED)) -+ return 1; -+ if (current_thread_info()->preempt_lazy_count) -+ return 0; -+ return 1; -+} -+ -+#else -+ -+static int preemptible_lazy(void) -+{ -+ return 1; -+} -+ -+#endif -+ - #ifdef CONFIG_PREEMPT - /* - * this is the entry point to schedule() from in-kernel preemption -@@ -3312,6 +3541,8 @@ asmlinkage __visible void __sched notrace preempt_schedule(void) - */ - if (likely(!preemptible())) - return; -+ if (!preemptible_lazy()) -+ return; - - preempt_schedule_common(); - } -@@ -3338,6 +3569,8 @@ asmlinkage __visible void __sched notrace preempt_schedule_notrace(void) - - if (likely(!preemptible())) - return; -+ if (!preemptible_lazy()) -+ return; - - do { - preempt_disable_notrace(); -@@ -3347,7 +3580,16 @@ asmlinkage __visible void __sched notrace preempt_schedule_notrace(void) - * an infinite recursion. - */ - prev_ctx = exception_enter(); -+ /* -+ * The add/subtract must not be traced by the function -+ * tracer. But we still want to account for the -+ * preempt off latency tracer. Since the _notrace versions -+ * of add/subtract skip the accounting for latency tracer -+ * we must force it manually. -+ */ -+ start_critical_timings(); - __schedule(true); -+ stop_critical_timings(); - exception_exit(prev_ctx); - - preempt_enable_no_resched_notrace(); -@@ -4692,6 +4934,7 @@ int __cond_resched_lock(spinlock_t *lock) - } - EXPORT_SYMBOL(__cond_resched_lock); - -+#ifndef CONFIG_PREEMPT_RT_FULL - int __sched __cond_resched_softirq(void) - { - BUG_ON(!in_softirq()); -@@ -4705,6 +4948,7 @@ int __sched __cond_resched_softirq(void) - return 0; - } - EXPORT_SYMBOL(__cond_resched_softirq); -+#endif - - /** - * yield - yield the current processor to other threads. -@@ -5071,7 +5315,9 @@ void init_idle(struct task_struct *idle, int cpu) - - /* Set the preempt count _outside_ the spinlocks! */ - init_idle_preempt_count(idle, cpu); -- -+#ifdef CONFIG_HAVE_PREEMPT_LAZY -+ task_thread_info(idle)->preempt_lazy_count = 0; -+#endif - /* - * The idle tasks have their own, simple scheduling class: - */ -@@ -5212,6 +5458,8 @@ void sched_setnuma(struct task_struct *p, int nid) - #endif /* CONFIG_NUMA_BALANCING */ - - #ifdef CONFIG_HOTPLUG_CPU -+static DEFINE_PER_CPU(struct mm_struct *, idle_last_mm); -+ - /* - * Ensures that the idle task is using init_mm right before its cpu goes - * offline. -@@ -5226,7 +5474,11 @@ void idle_task_exit(void) - switch_mm(mm, &init_mm, current); - finish_arch_post_lock_switch(); - } -- mmdrop(mm); -+ /* -+ * Defer the cleanup to an alive cpu. On RT we can neither -+ * call mmdrop() nor mmdrop_delayed() from here. -+ */ -+ per_cpu(idle_last_mm, smp_processor_id()) = mm; - } - - /* -@@ -5422,6 +5674,10 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu) - - case CPU_DEAD: - calc_load_migrate(rq); -+ if (per_cpu(idle_last_mm, cpu)) { -+ mmdrop(per_cpu(idle_last_mm, cpu)); -+ per_cpu(idle_last_mm, cpu) = NULL; -+ } - break; - #endif - } -@@ -7404,7 +7660,7 @@ void __init sched_init(void) - #ifdef CONFIG_DEBUG_ATOMIC_SLEEP - static inline int preempt_count_equals(int preempt_offset) - { -- int nested = preempt_count() + rcu_preempt_depth(); -+ int nested = preempt_count() + sched_rcu_preempt_depth(); - - return (nested == preempt_offset); - } -diff --git a/kernel/sched/cpudeadline.c b/kernel/sched/cpudeadline.c -index 5a75b08..5be5882 100644 ---- a/kernel/sched/cpudeadline.c -+++ b/kernel/sched/cpudeadline.c -@@ -103,10 +103,10 @@ int cpudl_find(struct cpudl *cp, struct task_struct *p, - const struct sched_dl_entity *dl_se = &p->dl; - - if (later_mask && -- cpumask_and(later_mask, cp->free_cpus, &p->cpus_allowed)) { -+ cpumask_and(later_mask, cp->free_cpus, tsk_cpus_allowed(p))) { - best_cpu = cpumask_any(later_mask); - goto out; -- } else if (cpumask_test_cpu(cpudl_maximum(cp), &p->cpus_allowed) && -+ } else if (cpumask_test_cpu(cpudl_maximum(cp), tsk_cpus_allowed(p)) && - dl_time_before(dl_se->deadline, cp->elements[0].dl)) { - best_cpu = cpudl_maximum(cp); - if (later_mask) -diff --git a/kernel/sched/cpupri.c b/kernel/sched/cpupri.c -index 981fcd7..11e9705 100644 ---- a/kernel/sched/cpupri.c -+++ b/kernel/sched/cpupri.c -@@ -103,11 +103,11 @@ int cpupri_find(struct cpupri *cp, struct task_struct *p, - if (skip) - continue; - -- if (cpumask_any_and(&p->cpus_allowed, vec->mask) >= nr_cpu_ids) -+ if (cpumask_any_and(tsk_cpus_allowed(p), vec->mask) >= nr_cpu_ids) - continue; - - if (lowest_mask) { -- cpumask_and(lowest_mask, &p->cpus_allowed, vec->mask); -+ cpumask_and(lowest_mask, tsk_cpus_allowed(p), vec->mask); - - /* - * We have to ensure that we have at least one bit -diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c -index 686ec8a..2badfda 100644 ---- a/kernel/sched/deadline.c -+++ b/kernel/sched/deadline.c -@@ -134,7 +134,7 @@ static void inc_dl_migration(struct sched_dl_entity *dl_se, struct dl_rq *dl_rq) - { - struct task_struct *p = dl_task_of(dl_se); - -- if (p->nr_cpus_allowed > 1) -+ if (tsk_nr_cpus_allowed(p) > 1) - dl_rq->dl_nr_migratory++; - - update_dl_migration(dl_rq); -@@ -144,7 +144,7 @@ static void dec_dl_migration(struct sched_dl_entity *dl_se, struct dl_rq *dl_rq) - { - struct task_struct *p = dl_task_of(dl_se); - -- if (p->nr_cpus_allowed > 1) -+ if (tsk_nr_cpus_allowed(p) > 1) - dl_rq->dl_nr_migratory--; - - update_dl_migration(dl_rq); -@@ -694,6 +694,7 @@ void init_dl_task_timer(struct sched_dl_entity *dl_se) - - hrtimer_init(timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - timer->function = dl_task_timer; -+ timer->irqsafe = 1; - } - - static -@@ -966,7 +967,7 @@ static void enqueue_task_dl(struct rq *rq, struct task_struct *p, int flags) - - enqueue_dl_entity(&p->dl, pi_se, flags); - -- if (!task_current(rq, p) && p->nr_cpus_allowed > 1) -+ if (!task_current(rq, p) && tsk_nr_cpus_allowed(p) > 1) - enqueue_pushable_dl_task(rq, p); - } - -@@ -1040,9 +1041,9 @@ select_task_rq_dl(struct task_struct *p, int cpu, int sd_flag, int flags) - * try to make it stay here, it might be important. - */ - if (unlikely(dl_task(curr)) && -- (curr->nr_cpus_allowed < 2 || -+ (tsk_nr_cpus_allowed(curr) < 2 || - !dl_entity_preempt(&p->dl, &curr->dl)) && -- (p->nr_cpus_allowed > 1)) { -+ (tsk_nr_cpus_allowed(p) > 1)) { - int target = find_later_rq(p); - - if (target != -1 && -@@ -1063,7 +1064,7 @@ static void check_preempt_equal_dl(struct rq *rq, struct task_struct *p) - * Current can't be migrated, useless to reschedule, - * let's hope p can move out. - */ -- if (rq->curr->nr_cpus_allowed == 1 || -+ if (tsk_nr_cpus_allowed(rq->curr) == 1 || - cpudl_find(&rq->rd->cpudl, rq->curr, NULL) == -1) - return; - -@@ -1071,7 +1072,7 @@ static void check_preempt_equal_dl(struct rq *rq, struct task_struct *p) - * p is migratable, so let's not schedule it and - * see if it is pushed or pulled somewhere else. - */ -- if (p->nr_cpus_allowed != 1 && -+ if (tsk_nr_cpus_allowed(p) != 1 && - cpudl_find(&rq->rd->cpudl, p, NULL) != -1) - return; - -@@ -1185,7 +1186,7 @@ static void put_prev_task_dl(struct rq *rq, struct task_struct *p) - { - update_curr_dl(rq); - -- if (on_dl_rq(&p->dl) && p->nr_cpus_allowed > 1) -+ if (on_dl_rq(&p->dl) && tsk_nr_cpus_allowed(p) > 1) - enqueue_pushable_dl_task(rq, p); - } - -@@ -1286,7 +1287,7 @@ static int find_later_rq(struct task_struct *task) - if (unlikely(!later_mask)) - return -1; - -- if (task->nr_cpus_allowed == 1) -+ if (tsk_nr_cpus_allowed(task) == 1) - return -1; - - /* -@@ -1392,7 +1393,7 @@ static struct rq *find_lock_later_rq(struct task_struct *task, struct rq *rq) - if (double_lock_balance(rq, later_rq)) { - if (unlikely(task_rq(task) != rq || - !cpumask_test_cpu(later_rq->cpu, -- &task->cpus_allowed) || -+ tsk_cpus_allowed(task)) || - task_running(rq, task) || - !dl_task(task) || - !task_on_rq_queued(task))) { -@@ -1432,7 +1433,7 @@ static struct task_struct *pick_next_pushable_dl_task(struct rq *rq) - - BUG_ON(rq->cpu != task_cpu(p)); - BUG_ON(task_current(rq, p)); -- BUG_ON(p->nr_cpus_allowed <= 1); -+ BUG_ON(tsk_nr_cpus_allowed(p) <= 1); - - BUG_ON(!task_on_rq_queued(p)); - BUG_ON(!dl_task(p)); -@@ -1471,7 +1472,7 @@ retry: - */ - if (dl_task(rq->curr) && - dl_time_before(next_task->dl.deadline, rq->curr->dl.deadline) && -- rq->curr->nr_cpus_allowed > 1) { -+ tsk_nr_cpus_allowed(rq->curr) > 1) { - resched_curr(rq); - return 0; - } -@@ -1618,9 +1619,9 @@ static void task_woken_dl(struct rq *rq, struct task_struct *p) - { - if (!task_running(rq, p) && - !test_tsk_need_resched(rq->curr) && -- p->nr_cpus_allowed > 1 && -+ tsk_nr_cpus_allowed(p) > 1 && - dl_task(rq->curr) && -- (rq->curr->nr_cpus_allowed < 2 || -+ (tsk_nr_cpus_allowed(rq->curr) < 2 || - !dl_entity_preempt(&p->dl, &rq->curr->dl))) { - push_dl_tasks(rq); - } -@@ -1724,7 +1725,7 @@ static void switched_to_dl(struct rq *rq, struct task_struct *p) - - if (task_on_rq_queued(p) && rq->curr != p) { - #ifdef CONFIG_SMP -- if (p->nr_cpus_allowed > 1 && rq->dl.overloaded) -+ if (tsk_nr_cpus_allowed(p) > 1 && rq->dl.overloaded) - queue_push_tasks(rq); - #else - if (dl_task(rq->curr)) -diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c -index 4fbc3bd..5503c1f 100644 ---- a/kernel/sched/debug.c -+++ b/kernel/sched/debug.c -@@ -559,6 +559,9 @@ void print_rt_rq(struct seq_file *m, int cpu, struct rt_rq *rt_rq) - P(rt_throttled); - PN(rt_time); - PN(rt_runtime); -+#ifdef CONFIG_SMP -+ P(rt_nr_migratory); -+#endif - - #undef PN - #undef P -@@ -954,6 +957,10 @@ void proc_sched_show_task(struct task_struct *p, struct seq_file *m) - #endif - P(policy); - P(prio); -+#ifdef CONFIG_PREEMPT_RT_FULL -+ P(migrate_disable); -+#endif -+ P(nr_cpus_allowed); - #undef PN - #undef __PN - #undef P -diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c -index e7dd0ec..7908774 100644 ---- a/kernel/sched/fair.c -+++ b/kernel/sched/fair.c -@@ -3318,7 +3318,7 @@ check_preempt_tick(struct cfs_rq *cfs_rq, struct sched_entity *curr) - ideal_runtime = sched_slice(cfs_rq, curr); - delta_exec = curr->sum_exec_runtime - curr->prev_sum_exec_runtime; - if (delta_exec > ideal_runtime) { -- resched_curr(rq_of(cfs_rq)); -+ resched_curr_lazy(rq_of(cfs_rq)); - /* - * The current task ran long enough, ensure it doesn't get - * re-elected due to buddy favours. -@@ -3342,7 +3342,7 @@ check_preempt_tick(struct cfs_rq *cfs_rq, struct sched_entity *curr) - return; - - if (delta > ideal_runtime) -- resched_curr(rq_of(cfs_rq)); -+ resched_curr_lazy(rq_of(cfs_rq)); - } - - static void -@@ -3487,7 +3487,7 @@ entity_tick(struct cfs_rq *cfs_rq, struct sched_entity *curr, int queued) - * validating it and just reschedule. - */ - if (queued) { -- resched_curr(rq_of(cfs_rq)); -+ resched_curr_lazy(rq_of(cfs_rq)); - return; - } - /* -@@ -3669,7 +3669,7 @@ static void __account_cfs_rq_runtime(struct cfs_rq *cfs_rq, u64 delta_exec) - * hierarchy can be throttled - */ - if (!assign_cfs_rq_runtime(cfs_rq) && likely(cfs_rq->curr)) -- resched_curr(rq_of(cfs_rq)); -+ resched_curr_lazy(rq_of(cfs_rq)); - } - - static __always_inline -@@ -4281,7 +4281,7 @@ static void hrtick_start_fair(struct rq *rq, struct task_struct *p) - - if (delta < 0) { - if (rq->curr == p) -- resched_curr(rq); -+ resched_curr_lazy(rq); - return; - } - hrtick_start(rq, delta); -@@ -5421,7 +5421,7 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int wake_ - return; - - preempt: -- resched_curr(rq); -+ resched_curr_lazy(rq); - /* - * Only set the backward buddy when the current task is still - * on the rq. This can happen when a wakeup gets interleaved -@@ -8172,7 +8172,7 @@ static void task_fork_fair(struct task_struct *p) - * 'current' within the tree based on its new key value. - */ - swap(curr->vruntime, se->vruntime); -- resched_curr(rq); -+ resched_curr_lazy(rq); - } - - se->vruntime -= cfs_rq->min_vruntime; -@@ -8197,7 +8197,7 @@ prio_changed_fair(struct rq *rq, struct task_struct *p, int oldprio) - */ - if (rq->curr == p) { - if (p->prio > oldprio) -- resched_curr(rq); -+ resched_curr_lazy(rq); - } else - check_preempt_curr(rq, p, 0); - } -diff --git a/kernel/sched/features.h b/kernel/sched/features.h -index 69631fa..6d28fcd 100644 ---- a/kernel/sched/features.h -+++ b/kernel/sched/features.h -@@ -45,11 +45,19 @@ SCHED_FEAT(LB_BIAS, true) - */ - SCHED_FEAT(NONTASK_CAPACITY, true) - -+#ifdef CONFIG_PREEMPT_RT_FULL -+SCHED_FEAT(TTWU_QUEUE, false) -+# ifdef CONFIG_PREEMPT_LAZY -+SCHED_FEAT(PREEMPT_LAZY, true) -+# endif -+#else -+ - /* - * Queue remote wakeups on the target CPU and process them - * using the scheduler IPI. Reduces rq->lock contention/bounces. - */ - SCHED_FEAT(TTWU_QUEUE, true) -+#endif - - #ifdef HAVE_RT_PUSH_IPI - /* -diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c -index ec4f538d..f7b2810 100644 ---- a/kernel/sched/rt.c -+++ b/kernel/sched/rt.c -@@ -47,6 +47,7 @@ void init_rt_bandwidth(struct rt_bandwidth *rt_b, u64 period, u64 runtime) - - hrtimer_init(&rt_b->rt_period_timer, - CLOCK_MONOTONIC, HRTIMER_MODE_REL); -+ rt_b->rt_period_timer.irqsafe = 1; - rt_b->rt_period_timer.function = sched_rt_period_timer; - } - -@@ -101,6 +102,7 @@ void init_rt_rq(struct rt_rq *rt_rq) - rt_rq->push_cpu = nr_cpu_ids; - raw_spin_lock_init(&rt_rq->push_lock); - init_irq_work(&rt_rq->push_work, push_irq_work_func); -+ rt_rq->push_work.flags |= IRQ_WORK_HARD_IRQ; - #endif - #endif /* CONFIG_SMP */ - /* We start is dequeued state, because no RT tasks are queued */ -@@ -334,7 +336,7 @@ static void inc_rt_migration(struct sched_rt_entity *rt_se, struct rt_rq *rt_rq) - rt_rq = &rq_of_rt_rq(rt_rq)->rt; - - rt_rq->rt_nr_total++; -- if (p->nr_cpus_allowed > 1) -+ if (tsk_nr_cpus_allowed(p) > 1) - rt_rq->rt_nr_migratory++; - - update_rt_migration(rt_rq); -@@ -351,7 +353,7 @@ static void dec_rt_migration(struct sched_rt_entity *rt_se, struct rt_rq *rt_rq) - rt_rq = &rq_of_rt_rq(rt_rq)->rt; - - rt_rq->rt_nr_total--; -- if (p->nr_cpus_allowed > 1) -+ if (tsk_nr_cpus_allowed(p) > 1) - rt_rq->rt_nr_migratory--; - - update_rt_migration(rt_rq); -@@ -1324,7 +1326,7 @@ enqueue_task_rt(struct rq *rq, struct task_struct *p, int flags) - - enqueue_rt_entity(rt_se, flags); - -- if (!task_current(rq, p) && p->nr_cpus_allowed > 1) -+ if (!task_current(rq, p) && tsk_nr_cpus_allowed(p) > 1) - enqueue_pushable_task(rq, p); - } - -@@ -1413,7 +1415,7 @@ select_task_rq_rt(struct task_struct *p, int cpu, int sd_flag, int flags) - * will have to sort it out. - */ - if (curr && unlikely(rt_task(curr)) && -- (curr->nr_cpus_allowed < 2 || -+ (tsk_nr_cpus_allowed(curr) < 2 || - curr->prio <= p->prio)) { - int target = find_lowest_rq(p); - -@@ -1437,7 +1439,7 @@ static void check_preempt_equal_prio(struct rq *rq, struct task_struct *p) - * Current can't be migrated, useless to reschedule, - * let's hope p can move out. - */ -- if (rq->curr->nr_cpus_allowed == 1 || -+ if (tsk_nr_cpus_allowed(rq->curr) == 1 || - !cpupri_find(&rq->rd->cpupri, rq->curr, NULL)) - return; - -@@ -1445,7 +1447,7 @@ static void check_preempt_equal_prio(struct rq *rq, struct task_struct *p) - * p is migratable, so let's not schedule it and - * see if it is pushed or pulled somewhere else. - */ -- if (p->nr_cpus_allowed != 1 -+ if (tsk_nr_cpus_allowed(p) != 1 - && cpupri_find(&rq->rd->cpupri, p, NULL)) - return; - -@@ -1579,7 +1581,7 @@ static void put_prev_task_rt(struct rq *rq, struct task_struct *p) - * The previous task needs to be made eligible for pushing - * if it is still active - */ -- if (on_rt_rq(&p->rt) && p->nr_cpus_allowed > 1) -+ if (on_rt_rq(&p->rt) && tsk_nr_cpus_allowed(p) > 1) - enqueue_pushable_task(rq, p); - } - -@@ -1629,7 +1631,7 @@ static int find_lowest_rq(struct task_struct *task) - if (unlikely(!lowest_mask)) - return -1; - -- if (task->nr_cpus_allowed == 1) -+ if (tsk_nr_cpus_allowed(task) == 1) - return -1; /* No other targets possible */ - - if (!cpupri_find(&task_rq(task)->rd->cpupri, task, lowest_mask)) -@@ -1762,7 +1764,7 @@ static struct task_struct *pick_next_pushable_task(struct rq *rq) - - BUG_ON(rq->cpu != task_cpu(p)); - BUG_ON(task_current(rq, p)); -- BUG_ON(p->nr_cpus_allowed <= 1); -+ BUG_ON(tsk_nr_cpus_allowed(p) <= 1); - - BUG_ON(!task_on_rq_queued(p)); - BUG_ON(!rt_task(p)); -@@ -2122,9 +2124,9 @@ static void task_woken_rt(struct rq *rq, struct task_struct *p) - { - if (!task_running(rq, p) && - !test_tsk_need_resched(rq->curr) && -- p->nr_cpus_allowed > 1 && -+ tsk_nr_cpus_allowed(p) > 1 && - (dl_task(rq->curr) || rt_task(rq->curr)) && -- (rq->curr->nr_cpus_allowed < 2 || -+ (tsk_nr_cpus_allowed(rq->curr) < 2 || - rq->curr->prio <= p->prio)) - push_rt_tasks(rq); - } -@@ -2197,7 +2199,7 @@ static void switched_to_rt(struct rq *rq, struct task_struct *p) - */ - if (task_on_rq_queued(p) && rq->curr != p) { - #ifdef CONFIG_SMP -- if (p->nr_cpus_allowed > 1 && rq->rt.overloaded) -+ if (tsk_nr_cpus_allowed(p) > 1 && rq->rt.overloaded) - queue_push_tasks(rq); - #else - if (p->prio < rq->curr->prio) -diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h -index ec2e8d2..93c999c 100644 ---- a/kernel/sched/sched.h -+++ b/kernel/sched/sched.h -@@ -1128,6 +1128,7 @@ static inline void finish_lock_switch(struct rq *rq, struct task_struct *prev) - #define WF_SYNC 0x01 /* waker goes to sleep after wakeup */ - #define WF_FORK 0x02 /* child wakeup after fork */ - #define WF_MIGRATED 0x4 /* internal use, task got migrated */ -+#define WF_LOCK_SLEEPER 0x08 /* wakeup spinlock "sleeper" */ - - /* - * To aid in avoiding the subversion of "niceness" due to uneven distribution -@@ -1303,6 +1304,15 @@ extern void init_sched_fair_class(void); - extern void resched_curr(struct rq *rq); - extern void resched_cpu(int cpu); - -+#ifdef CONFIG_PREEMPT_LAZY -+extern void resched_curr_lazy(struct rq *rq); -+#else -+static inline void resched_curr_lazy(struct rq *rq) -+{ -+ resched_curr(rq); -+} -+#endif -+ - extern struct rt_bandwidth def_rt_bandwidth; - extern void init_rt_bandwidth(struct rt_bandwidth *rt_b, u64 period, u64 runtime); - -diff --git a/kernel/sched/swait.c b/kernel/sched/swait.c -index 82f0dff..e2e224c 100644 ---- a/kernel/sched/swait.c -+++ b/kernel/sched/swait.c -@@ -1,5 +1,6 @@ - #include <linux/sched.h> - #include <linux/swait.h> -+#include <linux/suspend.h> - - void __init_swait_queue_head(struct swait_queue_head *q, const char *name, - struct lock_class_key *key) -@@ -29,6 +30,25 @@ void swake_up_locked(struct swait_queue_head *q) - } - EXPORT_SYMBOL(swake_up_locked); - -+void swake_up_all_locked(struct swait_queue_head *q) -+{ -+ struct swait_queue *curr; -+ int wakes = 0; -+ -+ while (!list_empty(&q->task_list)) { -+ -+ curr = list_first_entry(&q->task_list, typeof(*curr), -+ task_list); -+ wake_up_process(curr->task); -+ list_del_init(&curr->task_list); -+ wakes++; -+ } -+ if (pm_in_action) -+ return; -+ WARN(wakes > 2, "complete_all() with %d waiters\n", wakes); -+} -+EXPORT_SYMBOL(swake_up_all_locked); -+ - void swake_up(struct swait_queue_head *q) - { - unsigned long flags; -diff --git a/kernel/sched/work-simple.c b/kernel/sched/work-simple.c -new file mode 100644 -index 0000000..9ffe405 ---- /dev/null -+++ b/kernel/sched/work-simple.c -@@ -0,0 +1,173 @@ -+/* -+ * Copyright (C) 2014 BMW Car IT GmbH, Daniel Wagner daniel.wagner@bmw-carit.de -+ * -+ * Provides a framework for enqueuing callbacks from irq context -+ * PREEMPT_RT_FULL safe. The callbacks are executed in kthread context. -+ */ -+ -+#include <linux/swait.h> -+#include <linux/work-simple.h> -+#include <linux/kthread.h> -+#include <linux/slab.h> -+#include <linux/spinlock.h> -+#include <linux/export.h> -+ -+#define SWORK_EVENT_PENDING (1 << 0) -+ -+static DEFINE_MUTEX(worker_mutex); -+static struct sworker *glob_worker; -+ -+struct sworker { -+ struct list_head events; -+ struct swait_queue_head wq; -+ -+ raw_spinlock_t lock; -+ -+ struct task_struct *task; -+ int refs; -+}; -+ -+static bool swork_readable(struct sworker *worker) -+{ -+ bool r; -+ -+ if (kthread_should_stop()) -+ return true; -+ -+ raw_spin_lock_irq(&worker->lock); -+ r = !list_empty(&worker->events); -+ raw_spin_unlock_irq(&worker->lock); -+ -+ return r; -+} -+ -+static int swork_kthread(void *arg) -+{ -+ struct sworker *worker = arg; -+ -+ for (;;) { -+ swait_event_interruptible(worker->wq, -+ swork_readable(worker)); -+ if (kthread_should_stop()) -+ break; -+ -+ raw_spin_lock_irq(&worker->lock); -+ while (!list_empty(&worker->events)) { -+ struct swork_event *sev; -+ -+ sev = list_first_entry(&worker->events, -+ struct swork_event, item); -+ list_del(&sev->item); -+ raw_spin_unlock_irq(&worker->lock); -+ -+ WARN_ON_ONCE(!test_and_clear_bit(SWORK_EVENT_PENDING, -+ &sev->flags)); -+ sev->func(sev); -+ raw_spin_lock_irq(&worker->lock); -+ } -+ raw_spin_unlock_irq(&worker->lock); -+ } -+ return 0; -+} -+ -+static struct sworker *swork_create(void) -+{ -+ struct sworker *worker; -+ -+ worker = kzalloc(sizeof(*worker), GFP_KERNEL); -+ if (!worker) -+ return ERR_PTR(-ENOMEM); -+ -+ INIT_LIST_HEAD(&worker->events); -+ raw_spin_lock_init(&worker->lock); -+ init_swait_queue_head(&worker->wq); -+ -+ worker->task = kthread_run(swork_kthread, worker, "kswork"); -+ if (IS_ERR(worker->task)) { -+ kfree(worker); -+ return ERR_PTR(-ENOMEM); -+ } -+ -+ return worker; -+} -+ -+static void swork_destroy(struct sworker *worker) -+{ -+ kthread_stop(worker->task); -+ -+ WARN_ON(!list_empty(&worker->events)); -+ kfree(worker); -+} -+ -+/** -+ * swork_queue - queue swork -+ * -+ * Returns %false if @work was already on a queue, %true otherwise. -+ * -+ * The work is queued and processed on a random CPU -+ */ -+bool swork_queue(struct swork_event *sev) -+{ -+ unsigned long flags; -+ -+ if (test_and_set_bit(SWORK_EVENT_PENDING, &sev->flags)) -+ return false; -+ -+ raw_spin_lock_irqsave(&glob_worker->lock, flags); -+ list_add_tail(&sev->item, &glob_worker->events); -+ raw_spin_unlock_irqrestore(&glob_worker->lock, flags); -+ -+ swake_up(&glob_worker->wq); -+ return true; -+} -+EXPORT_SYMBOL_GPL(swork_queue); -+ -+/** -+ * swork_get - get an instance of the sworker -+ * -+ * Returns an negative error code if the initialization if the worker did not -+ * work, %0 otherwise. -+ * -+ */ -+int swork_get(void) -+{ -+ struct sworker *worker; -+ -+ mutex_lock(&worker_mutex); -+ if (!glob_worker) { -+ worker = swork_create(); -+ if (IS_ERR(worker)) { -+ mutex_unlock(&worker_mutex); -+ return -ENOMEM; -+ } -+ -+ glob_worker = worker; -+ } -+ -+ glob_worker->refs++; -+ mutex_unlock(&worker_mutex); -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(swork_get); -+ -+/** -+ * swork_put - puts an instance of the sworker -+ * -+ * Will destroy the sworker thread. This function must not be called until all -+ * queued events have been completed. -+ */ -+void swork_put(void) -+{ -+ mutex_lock(&worker_mutex); -+ -+ glob_worker->refs--; -+ if (glob_worker->refs > 0) -+ goto out; -+ -+ swork_destroy(glob_worker); -+ glob_worker = NULL; -+out: -+ mutex_unlock(&worker_mutex); -+} -+EXPORT_SYMBOL_GPL(swork_put); -diff --git a/kernel/signal.c b/kernel/signal.c -index aa9bf00..cacc654 100644 ---- a/kernel/signal.c -+++ b/kernel/signal.c -@@ -14,6 +14,7 @@ - #include <linux/export.h> - #include <linux/init.h> - #include <linux/sched.h> -+#include <linux/sched/rt.h> - #include <linux/fs.h> - #include <linux/tty.h> - #include <linux/binfmts.h> -@@ -352,13 +353,30 @@ static bool task_participate_group_stop(struct task_struct *task) - return false; - } - -+static inline struct sigqueue *get_task_cache(struct task_struct *t) -+{ -+ struct sigqueue *q = t->sigqueue_cache; -+ -+ if (cmpxchg(&t->sigqueue_cache, q, NULL) != q) -+ return NULL; -+ return q; -+} -+ -+static inline int put_task_cache(struct task_struct *t, struct sigqueue *q) -+{ -+ if (cmpxchg(&t->sigqueue_cache, NULL, q) == NULL) -+ return 0; -+ return 1; -+} -+ - /* - * allocate a new signal queue record - * - this may be called without locks if and only if t == current, otherwise an - * appropriate lock must be held to stop the target task from exiting - */ - static struct sigqueue * --__sigqueue_alloc(int sig, struct task_struct *t, gfp_t flags, int override_rlimit) -+__sigqueue_do_alloc(int sig, struct task_struct *t, gfp_t flags, -+ int override_rlimit, int fromslab) - { - struct sigqueue *q = NULL; - struct user_struct *user; -@@ -375,7 +393,10 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t flags, int override_rlimi - if (override_rlimit || - atomic_read(&user->sigpending) <= - task_rlimit(t, RLIMIT_SIGPENDING)) { -- q = kmem_cache_alloc(sigqueue_cachep, flags); -+ if (!fromslab) -+ q = get_task_cache(t); -+ if (!q) -+ q = kmem_cache_alloc(sigqueue_cachep, flags); - } else { - print_dropped_signal(sig); - } -@@ -392,6 +413,13 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t flags, int override_rlimi - return q; - } - -+static struct sigqueue * -+__sigqueue_alloc(int sig, struct task_struct *t, gfp_t flags, -+ int override_rlimit) -+{ -+ return __sigqueue_do_alloc(sig, t, flags, override_rlimit, 0); -+} -+ - static void __sigqueue_free(struct sigqueue *q) - { - if (q->flags & SIGQUEUE_PREALLOC) -@@ -401,6 +429,21 @@ static void __sigqueue_free(struct sigqueue *q) - kmem_cache_free(sigqueue_cachep, q); - } - -+static void sigqueue_free_current(struct sigqueue *q) -+{ -+ struct user_struct *up; -+ -+ if (q->flags & SIGQUEUE_PREALLOC) -+ return; -+ -+ up = q->user; -+ if (rt_prio(current->normal_prio) && !put_task_cache(current, q)) { -+ atomic_dec(&up->sigpending); -+ free_uid(up); -+ } else -+ __sigqueue_free(q); -+} -+ - void flush_sigqueue(struct sigpending *queue) - { - struct sigqueue *q; -@@ -414,6 +457,21 @@ void flush_sigqueue(struct sigpending *queue) - } - - /* -+ * Called from __exit_signal. Flush tsk->pending and -+ * tsk->sigqueue_cache -+ */ -+void flush_task_sigqueue(struct task_struct *tsk) -+{ -+ struct sigqueue *q; -+ -+ flush_sigqueue(&tsk->pending); -+ -+ q = get_task_cache(tsk); -+ if (q) -+ kmem_cache_free(sigqueue_cachep, q); -+} -+ -+/* - * Flush all pending signals for this kthread. - */ - void flush_signals(struct task_struct *t) -@@ -525,7 +583,7 @@ static void collect_signal(int sig, struct sigpending *list, siginfo_t *info) - still_pending: - list_del_init(&first->list); - copy_siginfo(info, &first->info); -- __sigqueue_free(first); -+ sigqueue_free_current(first); - } else { - /* - * Ok, it wasn't in the queue. This must be -@@ -560,6 +618,8 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info) - { - int signr; - -+ WARN_ON_ONCE(tsk != current); -+ - /* We only dequeue private signals from ourselves, we don't let - * signalfd steal them - */ -@@ -1156,8 +1216,8 @@ int do_send_sig_info(int sig, struct siginfo *info, struct task_struct *p, - * We don't want to have recursive SIGSEGV's etc, for example, - * that is why we also clear SIGNAL_UNKILLABLE. - */ --int --force_sig_info(int sig, struct siginfo *info, struct task_struct *t) -+static int -+do_force_sig_info(int sig, struct siginfo *info, struct task_struct *t) - { - unsigned long int flags; - int ret, blocked, ignored; -@@ -1182,6 +1242,39 @@ force_sig_info(int sig, struct siginfo *info, struct task_struct *t) - return ret; - } - -+int force_sig_info(int sig, struct siginfo *info, struct task_struct *t) -+{ -+/* -+ * On some archs, PREEMPT_RT has to delay sending a signal from a trap -+ * since it can not enable preemption, and the signal code's spin_locks -+ * turn into mutexes. Instead, it must set TIF_NOTIFY_RESUME which will -+ * send the signal on exit of the trap. -+ */ -+#ifdef ARCH_RT_DELAYS_SIGNAL_SEND -+ if (in_atomic()) { -+ if (WARN_ON_ONCE(t != current)) -+ return 0; -+ if (WARN_ON_ONCE(t->forced_info.si_signo)) -+ return 0; -+ -+ if (is_si_special(info)) { -+ WARN_ON_ONCE(info != SEND_SIG_PRIV); -+ t->forced_info.si_signo = sig; -+ t->forced_info.si_errno = 0; -+ t->forced_info.si_code = SI_KERNEL; -+ t->forced_info.si_pid = 0; -+ t->forced_info.si_uid = 0; -+ } else { -+ t->forced_info = *info; -+ } -+ -+ set_tsk_thread_flag(t, TIF_NOTIFY_RESUME); -+ return 0; -+ } -+#endif -+ return do_force_sig_info(sig, info, t); -+} -+ - /* - * Nuke all other threads in the group. - */ -@@ -1216,12 +1309,12 @@ struct sighand_struct *__lock_task_sighand(struct task_struct *tsk, - * Disable interrupts early to avoid deadlocks. - * See rcu_read_unlock() comment header for details. - */ -- local_irq_save(*flags); -+ local_irq_save_nort(*flags); - rcu_read_lock(); - sighand = rcu_dereference(tsk->sighand); - if (unlikely(sighand == NULL)) { - rcu_read_unlock(); -- local_irq_restore(*flags); -+ local_irq_restore_nort(*flags); - break; - } - /* -@@ -1242,7 +1335,7 @@ struct sighand_struct *__lock_task_sighand(struct task_struct *tsk, - } - spin_unlock(&sighand->siglock); - rcu_read_unlock(); -- local_irq_restore(*flags); -+ local_irq_restore_nort(*flags); - } - - return sighand; -@@ -1485,7 +1578,8 @@ EXPORT_SYMBOL(kill_pid); - */ - struct sigqueue *sigqueue_alloc(void) - { -- struct sigqueue *q = __sigqueue_alloc(-1, current, GFP_KERNEL, 0); -+ /* Preallocated sigqueue objects always from the slabcache ! */ -+ struct sigqueue *q = __sigqueue_do_alloc(-1, current, GFP_KERNEL, 0, 1); - - if (q) - q->flags |= SIGQUEUE_PREALLOC; -@@ -1846,15 +1940,7 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info) - if (gstop_done && ptrace_reparented(current)) - do_notify_parent_cldstop(current, false, why); - -- /* -- * Don't want to allow preemption here, because -- * sys_ptrace() needs this task to be inactive. -- * -- * XXX: implement read_unlock_no_resched(). -- */ -- preempt_disable(); - read_unlock(&tasklist_lock); -- preempt_enable_no_resched(); - freezable_schedule(); - } else { - /* -diff --git a/kernel/softirq.c b/kernel/softirq.c -index 17caf4b..a602b71 100644 ---- a/kernel/softirq.c -+++ b/kernel/softirq.c -@@ -21,10 +21,12 @@ - #include <linux/freezer.h> - #include <linux/kthread.h> - #include <linux/rcupdate.h> -+#include <linux/delay.h> - #include <linux/ftrace.h> - #include <linux/smp.h> - #include <linux/smpboot.h> - #include <linux/tick.h> -+#include <linux/locallock.h> - #include <linux/irq.h> - - #define CREATE_TRACE_POINTS -@@ -56,12 +58,108 @@ EXPORT_SYMBOL(irq_stat); - static struct softirq_action softirq_vec[NR_SOFTIRQS] __cacheline_aligned_in_smp; - - DEFINE_PER_CPU(struct task_struct *, ksoftirqd); -+#ifdef CONFIG_PREEMPT_RT_FULL -+#define TIMER_SOFTIRQS ((1 << TIMER_SOFTIRQ) | (1 << HRTIMER_SOFTIRQ)) -+DEFINE_PER_CPU(struct task_struct *, ktimer_softirqd); -+#endif - - const char * const softirq_to_name[NR_SOFTIRQS] = { - "HI", "TIMER", "NET_TX", "NET_RX", "BLOCK", "BLOCK_IOPOLL", - "TASKLET", "SCHED", "HRTIMER", "RCU" - }; - -+#ifdef CONFIG_NO_HZ_COMMON -+# ifdef CONFIG_PREEMPT_RT_FULL -+ -+struct softirq_runner { -+ struct task_struct *runner[NR_SOFTIRQS]; -+}; -+ -+static DEFINE_PER_CPU(struct softirq_runner, softirq_runners); -+ -+static inline void softirq_set_runner(unsigned int sirq) -+{ -+ struct softirq_runner *sr = this_cpu_ptr(&softirq_runners); -+ -+ sr->runner[sirq] = current; -+} -+ -+static inline void softirq_clr_runner(unsigned int sirq) -+{ -+ struct softirq_runner *sr = this_cpu_ptr(&softirq_runners); -+ -+ sr->runner[sirq] = NULL; -+} -+ -+/* -+ * On preempt-rt a softirq running context might be blocked on a -+ * lock. There might be no other runnable task on this CPU because the -+ * lock owner runs on some other CPU. So we have to go into idle with -+ * the pending bit set. Therefor we need to check this otherwise we -+ * warn about false positives which confuses users and defeats the -+ * whole purpose of this test. -+ * -+ * This code is called with interrupts disabled. -+ */ -+void softirq_check_pending_idle(void) -+{ -+ static int rate_limit; -+ struct softirq_runner *sr = this_cpu_ptr(&softirq_runners); -+ u32 warnpending; -+ int i; -+ -+ if (rate_limit >= 10) -+ return; -+ -+ warnpending = local_softirq_pending() & SOFTIRQ_STOP_IDLE_MASK; -+ for (i = 0; i < NR_SOFTIRQS; i++) { -+ struct task_struct *tsk = sr->runner[i]; -+ -+ /* -+ * The wakeup code in rtmutex.c wakes up the task -+ * _before_ it sets pi_blocked_on to NULL under -+ * tsk->pi_lock. So we need to check for both: state -+ * and pi_blocked_on. -+ */ -+ if (tsk) { -+ raw_spin_lock(&tsk->pi_lock); -+ if (tsk->pi_blocked_on || tsk->state == TASK_RUNNING) { -+ /* Clear all bits pending in that task */ -+ warnpending &= ~(tsk->softirqs_raised); -+ warnpending &= ~(1 << i); -+ } -+ raw_spin_unlock(&tsk->pi_lock); -+ } -+ } -+ -+ if (warnpending) { -+ printk(KERN_ERR "NOHZ: local_softirq_pending %02x\n", -+ warnpending); -+ rate_limit++; -+ } -+} -+# else -+/* -+ * On !PREEMPT_RT we just printk rate limited: -+ */ -+void softirq_check_pending_idle(void) -+{ -+ static int rate_limit; -+ -+ if (rate_limit < 10 && -+ (local_softirq_pending() & SOFTIRQ_STOP_IDLE_MASK)) { -+ printk(KERN_ERR "NOHZ: local_softirq_pending %02x\n", -+ local_softirq_pending()); -+ rate_limit++; -+ } -+} -+# endif -+ -+#else /* !CONFIG_NO_HZ_COMMON */ -+static inline void softirq_set_runner(unsigned int sirq) { } -+static inline void softirq_clr_runner(unsigned int sirq) { } -+#endif -+ - /* - * we cannot loop indefinitely here to avoid userspace starvation, - * but we also don't want to introduce a worst case 1/HZ latency -@@ -77,6 +175,79 @@ static void wakeup_softirqd(void) - wake_up_process(tsk); - } - -+#ifdef CONFIG_PREEMPT_RT_FULL -+static void wakeup_timer_softirqd(void) -+{ -+ /* Interrupts are disabled: no need to stop preemption */ -+ struct task_struct *tsk = __this_cpu_read(ktimer_softirqd); -+ -+ if (tsk && tsk->state != TASK_RUNNING) -+ wake_up_process(tsk); -+} -+#endif -+ -+static void handle_softirq(unsigned int vec_nr) -+{ -+ struct softirq_action *h = softirq_vec + vec_nr; -+ int prev_count; -+ -+ prev_count = preempt_count(); -+ -+ kstat_incr_softirqs_this_cpu(vec_nr); -+ -+ trace_softirq_entry(vec_nr); -+ h->action(h); -+ trace_softirq_exit(vec_nr); -+ if (unlikely(prev_count != preempt_count())) { -+ pr_err("huh, entered softirq %u %s %p with preempt_count %08x, exited with %08x?\n", -+ vec_nr, softirq_to_name[vec_nr], h->action, -+ prev_count, preempt_count()); -+ preempt_count_set(prev_count); -+ } -+} -+ -+#ifndef CONFIG_PREEMPT_RT_FULL -+static inline int ksoftirqd_softirq_pending(void) -+{ -+ return local_softirq_pending(); -+} -+ -+static void handle_pending_softirqs(u32 pending) -+{ -+ struct softirq_action *h = softirq_vec; -+ int softirq_bit; -+ -+ local_irq_enable(); -+ -+ h = softirq_vec; -+ -+ while ((softirq_bit = ffs(pending))) { -+ unsigned int vec_nr; -+ -+ h += softirq_bit - 1; -+ vec_nr = h - softirq_vec; -+ handle_softirq(vec_nr); -+ -+ h++; -+ pending >>= softirq_bit; -+ } -+ -+ rcu_bh_qs(); -+ local_irq_disable(); -+} -+ -+static void run_ksoftirqd(unsigned int cpu) -+{ -+ local_irq_disable(); -+ if (ksoftirqd_softirq_pending()) { -+ __do_softirq(); -+ local_irq_enable(); -+ cond_resched_rcu_qs(); -+ return; -+ } -+ local_irq_enable(); -+} -+ - /* - * preempt_count and SOFTIRQ_OFFSET usage: - * - preempt_count is changed by SOFTIRQ_OFFSET on entering or leaving -@@ -232,10 +403,8 @@ asmlinkage __visible void __softirq_entry __do_softirq(void) - unsigned long end = jiffies + MAX_SOFTIRQ_TIME; - unsigned long old_flags = current->flags; - int max_restart = MAX_SOFTIRQ_RESTART; -- struct softirq_action *h; - bool in_hardirq; - __u32 pending; -- int softirq_bit; - - /* - * Mask out PF_MEMALLOC s current task context is borrowed for the -@@ -254,36 +423,7 @@ restart: - /* Reset the pending bitmask before enabling irqs */ - set_softirq_pending(0); - -- local_irq_enable(); -- -- h = softirq_vec; -- -- while ((softirq_bit = ffs(pending))) { -- unsigned int vec_nr; -- int prev_count; -- -- h += softirq_bit - 1; -- -- vec_nr = h - softirq_vec; -- prev_count = preempt_count(); -- -- kstat_incr_softirqs_this_cpu(vec_nr); -- -- trace_softirq_entry(vec_nr); -- h->action(h); -- trace_softirq_exit(vec_nr); -- if (unlikely(prev_count != preempt_count())) { -- pr_err("huh, entered softirq %u %s %p with preempt_count %08x, exited with %08x?\n", -- vec_nr, softirq_to_name[vec_nr], h->action, -- prev_count, preempt_count()); -- preempt_count_set(prev_count); -- } -- h++; -- pending >>= softirq_bit; -- } -- -- rcu_bh_qs(); -- local_irq_disable(); -+ handle_pending_softirqs(pending); - - pending = local_softirq_pending(); - if (pending) { -@@ -320,6 +460,310 @@ asmlinkage __visible void do_softirq(void) - } - - /* -+ * This function must run with irqs disabled! -+ */ -+void raise_softirq_irqoff(unsigned int nr) -+{ -+ __raise_softirq_irqoff(nr); -+ -+ /* -+ * If we're in an interrupt or softirq, we're done -+ * (this also catches softirq-disabled code). We will -+ * actually run the softirq once we return from -+ * the irq or softirq. -+ * -+ * Otherwise we wake up ksoftirqd to make sure we -+ * schedule the softirq soon. -+ */ -+ if (!in_interrupt()) -+ wakeup_softirqd(); -+} -+ -+void __raise_softirq_irqoff(unsigned int nr) -+{ -+ trace_softirq_raise(nr); -+ or_softirq_pending(1UL << nr); -+} -+ -+static inline void local_bh_disable_nort(void) { local_bh_disable(); } -+static inline void _local_bh_enable_nort(void) { _local_bh_enable(); } -+static void ksoftirqd_set_sched_params(unsigned int cpu) { } -+ -+#else /* !PREEMPT_RT_FULL */ -+ -+/* -+ * On RT we serialize softirq execution with a cpu local lock per softirq -+ */ -+static DEFINE_PER_CPU(struct local_irq_lock [NR_SOFTIRQS], local_softirq_locks); -+ -+void __init softirq_early_init(void) -+{ -+ int i; -+ -+ for (i = 0; i < NR_SOFTIRQS; i++) -+ local_irq_lock_init(local_softirq_locks[i]); -+} -+ -+static void lock_softirq(int which) -+{ -+ local_lock(local_softirq_locks[which]); -+} -+ -+static void unlock_softirq(int which) -+{ -+ local_unlock(local_softirq_locks[which]); -+} -+ -+static void do_single_softirq(int which) -+{ -+ unsigned long old_flags = current->flags; -+ -+ current->flags &= ~PF_MEMALLOC; -+ vtime_account_irq_enter(current); -+ current->flags |= PF_IN_SOFTIRQ; -+ lockdep_softirq_enter(); -+ local_irq_enable(); -+ handle_softirq(which); -+ local_irq_disable(); -+ lockdep_softirq_exit(); -+ current->flags &= ~PF_IN_SOFTIRQ; -+ vtime_account_irq_enter(current); -+ tsk_restore_flags(current, old_flags, PF_MEMALLOC); -+} -+ -+/* -+ * Called with interrupts disabled. Process softirqs which were raised -+ * in current context (or on behalf of ksoftirqd). -+ */ -+static void do_current_softirqs(void) -+{ -+ while (current->softirqs_raised) { -+ int i = __ffs(current->softirqs_raised); -+ unsigned int pending, mask = (1U << i); -+ -+ current->softirqs_raised &= ~mask; -+ local_irq_enable(); -+ -+ /* -+ * If the lock is contended, we boost the owner to -+ * process the softirq or leave the critical section -+ * now. -+ */ -+ lock_softirq(i); -+ local_irq_disable(); -+ softirq_set_runner(i); -+ /* -+ * Check with the local_softirq_pending() bits, -+ * whether we need to process this still or if someone -+ * else took care of it. -+ */ -+ pending = local_softirq_pending(); -+ if (pending & mask) { -+ set_softirq_pending(pending & ~mask); -+ do_single_softirq(i); -+ } -+ softirq_clr_runner(i); -+ WARN_ON(current->softirq_nestcnt != 1); -+ local_irq_enable(); -+ unlock_softirq(i); -+ local_irq_disable(); -+ } -+} -+ -+void __local_bh_disable(void) -+{ -+ if (++current->softirq_nestcnt == 1) -+ migrate_disable(); -+} -+EXPORT_SYMBOL(__local_bh_disable); -+ -+void __local_bh_enable(void) -+{ -+ if (WARN_ON(current->softirq_nestcnt == 0)) -+ return; -+ -+ local_irq_disable(); -+ if (current->softirq_nestcnt == 1 && current->softirqs_raised) -+ do_current_softirqs(); -+ local_irq_enable(); -+ -+ if (--current->softirq_nestcnt == 0) -+ migrate_enable(); -+} -+EXPORT_SYMBOL(__local_bh_enable); -+ -+void _local_bh_enable(void) -+{ -+ if (WARN_ON(current->softirq_nestcnt == 0)) -+ return; -+ if (--current->softirq_nestcnt == 0) -+ migrate_enable(); -+} -+EXPORT_SYMBOL(_local_bh_enable); -+ -+int in_serving_softirq(void) -+{ -+ return current->flags & PF_IN_SOFTIRQ; -+} -+EXPORT_SYMBOL(in_serving_softirq); -+ -+/* Called with preemption disabled */ -+static void run_ksoftirqd(unsigned int cpu) -+{ -+ local_irq_disable(); -+ current->softirq_nestcnt++; -+ -+ do_current_softirqs(); -+ current->softirq_nestcnt--; -+ local_irq_enable(); -+ cond_resched_rcu_qs(); -+} -+ -+/* -+ * Called from netif_rx_ni(). Preemption enabled, but migration -+ * disabled. So the cpu can't go away under us. -+ */ -+void thread_do_softirq(void) -+{ -+ if (!in_serving_softirq() && current->softirqs_raised) { -+ current->softirq_nestcnt++; -+ do_current_softirqs(); -+ current->softirq_nestcnt--; -+ } -+} -+ -+static void do_raise_softirq_irqoff(unsigned int nr) -+{ -+ unsigned int mask; -+ -+ mask = 1UL << nr; -+ -+ trace_softirq_raise(nr); -+ or_softirq_pending(mask); -+ -+ /* -+ * If we are not in a hard interrupt and inside a bh disabled -+ * region, we simply raise the flag on current. local_bh_enable() -+ * will make sure that the softirq is executed. Otherwise we -+ * delegate it to ksoftirqd. -+ */ -+ if (!in_irq() && current->softirq_nestcnt) -+ current->softirqs_raised |= mask; -+ else if (!__this_cpu_read(ksoftirqd) || !__this_cpu_read(ktimer_softirqd)) -+ return; -+ -+ if (mask & TIMER_SOFTIRQS) -+ __this_cpu_read(ktimer_softirqd)->softirqs_raised |= mask; -+ else -+ __this_cpu_read(ksoftirqd)->softirqs_raised |= mask; -+} -+ -+static void wakeup_proper_softirq(unsigned int nr) -+{ -+ if ((1UL << nr) & TIMER_SOFTIRQS) -+ wakeup_timer_softirqd(); -+ else -+ wakeup_softirqd(); -+} -+ -+ -+void __raise_softirq_irqoff(unsigned int nr) -+{ -+ do_raise_softirq_irqoff(nr); -+ if (!in_irq() && !current->softirq_nestcnt) -+ wakeup_proper_softirq(nr); -+} -+ -+/* -+ * Same as __raise_softirq_irqoff() but will process them in ksoftirqd -+ */ -+void __raise_softirq_irqoff_ksoft(unsigned int nr) -+{ -+ unsigned int mask; -+ -+ if (WARN_ON_ONCE(!__this_cpu_read(ksoftirqd) || -+ !__this_cpu_read(ktimer_softirqd))) -+ return; -+ mask = 1UL << nr; -+ -+ trace_softirq_raise(nr); -+ or_softirq_pending(mask); -+ if (mask & TIMER_SOFTIRQS) -+ __this_cpu_read(ktimer_softirqd)->softirqs_raised |= mask; -+ else -+ __this_cpu_read(ksoftirqd)->softirqs_raised |= mask; -+ wakeup_proper_softirq(nr); -+} -+ -+/* -+ * This function must run with irqs disabled! -+ */ -+void raise_softirq_irqoff(unsigned int nr) -+{ -+ do_raise_softirq_irqoff(nr); -+ -+ /* -+ * If we're in an hard interrupt we let irq return code deal -+ * with the wakeup of ksoftirqd. -+ */ -+ if (in_irq()) -+ return; -+ /* -+ * If we are in thread context but outside of a bh disabled -+ * region, we need to wake ksoftirqd as well. -+ * -+ * CHECKME: Some of the places which do that could be wrapped -+ * into local_bh_disable/enable pairs. Though it's unclear -+ * whether this is worth the effort. To find those places just -+ * raise a WARN() if the condition is met. -+ */ -+ if (!current->softirq_nestcnt) -+ wakeup_proper_softirq(nr); -+} -+ -+static inline int ksoftirqd_softirq_pending(void) -+{ -+ return current->softirqs_raised; -+} -+ -+static inline void local_bh_disable_nort(void) { } -+static inline void _local_bh_enable_nort(void) { } -+ -+static inline void ksoftirqd_set_sched_params(unsigned int cpu) -+{ -+ /* Take over all but timer pending softirqs when starting */ -+ local_irq_disable(); -+ current->softirqs_raised = local_softirq_pending() & ~TIMER_SOFTIRQS; -+ local_irq_enable(); -+} -+ -+static inline void ktimer_softirqd_set_sched_params(unsigned int cpu) -+{ -+ struct sched_param param = { .sched_priority = 1 }; -+ -+ sched_setscheduler(current, SCHED_FIFO, ¶m); -+ -+ /* Take over timer pending softirqs when starting */ -+ local_irq_disable(); -+ current->softirqs_raised = local_softirq_pending() & TIMER_SOFTIRQS; -+ local_irq_enable(); -+} -+ -+static inline void ktimer_softirqd_clr_sched_params(unsigned int cpu, -+ bool online) -+{ -+ struct sched_param param = { .sched_priority = 0 }; -+ -+ sched_setscheduler(current, SCHED_NORMAL, ¶m); -+} -+ -+static int ktimer_softirqd_should_run(unsigned int cpu) -+{ -+ return current->softirqs_raised; -+} -+ -+#endif /* PREEMPT_RT_FULL */ -+/* - * Enter an interrupt context. - */ - void irq_enter(void) -@@ -330,9 +774,9 @@ void irq_enter(void) - * Prevent raise_softirq from needlessly waking up ksoftirqd - * here, as softirq will be serviced on return from interrupt. - */ -- local_bh_disable(); -+ local_bh_disable_nort(); - tick_irq_enter(); -- _local_bh_enable(); -+ _local_bh_enable_nort(); - } - - __irq_enter(); -@@ -340,6 +784,7 @@ void irq_enter(void) - - static inline void invoke_softirq(void) - { -+#ifndef CONFIG_PREEMPT_RT_FULL - if (!force_irqthreads) { - #ifdef CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK - /* -@@ -359,6 +804,18 @@ static inline void invoke_softirq(void) - } else { - wakeup_softirqd(); - } -+#else /* PREEMPT_RT_FULL */ -+ unsigned long flags; -+ -+ local_irq_save(flags); -+ if (__this_cpu_read(ksoftirqd) && -+ __this_cpu_read(ksoftirqd)->softirqs_raised) -+ wakeup_softirqd(); -+ if (__this_cpu_read(ktimer_softirqd) && -+ __this_cpu_read(ktimer_softirqd)->softirqs_raised) -+ wakeup_timer_softirqd(); -+ local_irq_restore(flags); -+#endif - } - - static inline void tick_irq_exit(void) -@@ -395,26 +852,6 @@ void irq_exit(void) - trace_hardirq_exit(); /* must be last! */ - } - --/* -- * This function must run with irqs disabled! -- */ --inline void raise_softirq_irqoff(unsigned int nr) --{ -- __raise_softirq_irqoff(nr); -- -- /* -- * If we're in an interrupt or softirq, we're done -- * (this also catches softirq-disabled code). We will -- * actually run the softirq once we return from -- * the irq or softirq. -- * -- * Otherwise we wake up ksoftirqd to make sure we -- * schedule the softirq soon. -- */ -- if (!in_interrupt()) -- wakeup_softirqd(); --} -- - void raise_softirq(unsigned int nr) - { - unsigned long flags; -@@ -424,12 +861,6 @@ void raise_softirq(unsigned int nr) - local_irq_restore(flags); - } - --void __raise_softirq_irqoff(unsigned int nr) --{ -- trace_softirq_raise(nr); -- or_softirq_pending(1UL << nr); --} -- - void open_softirq(int nr, void (*action)(struct softirq_action *)) - { - softirq_vec[nr].action = action; -@@ -446,15 +877,45 @@ struct tasklet_head { - static DEFINE_PER_CPU(struct tasklet_head, tasklet_vec); - static DEFINE_PER_CPU(struct tasklet_head, tasklet_hi_vec); - -+static void inline -+__tasklet_common_schedule(struct tasklet_struct *t, struct tasklet_head *head, unsigned int nr) -+{ -+ if (tasklet_trylock(t)) { -+again: -+ /* We may have been preempted before tasklet_trylock -+ * and __tasklet_action may have already run. -+ * So double check the sched bit while the takslet -+ * is locked before adding it to the list. -+ */ -+ if (test_bit(TASKLET_STATE_SCHED, &t->state)) { -+ t->next = NULL; -+ *head->tail = t; -+ head->tail = &(t->next); -+ raise_softirq_irqoff(nr); -+ tasklet_unlock(t); -+ } else { -+ /* This is subtle. If we hit the corner case above -+ * It is possible that we get preempted right here, -+ * and another task has successfully called -+ * tasklet_schedule(), then this function, and -+ * failed on the trylock. Thus we must be sure -+ * before releasing the tasklet lock, that the -+ * SCHED_BIT is clear. Otherwise the tasklet -+ * may get its SCHED_BIT set, but not added to the -+ * list -+ */ -+ if (!tasklet_tryunlock(t)) -+ goto again; -+ } -+ } -+} -+ - void __tasklet_schedule(struct tasklet_struct *t) - { - unsigned long flags; - - local_irq_save(flags); -- t->next = NULL; -- *__this_cpu_read(tasklet_vec.tail) = t; -- __this_cpu_write(tasklet_vec.tail, &(t->next)); -- raise_softirq_irqoff(TASKLET_SOFTIRQ); -+ __tasklet_common_schedule(t, this_cpu_ptr(&tasklet_vec), TASKLET_SOFTIRQ); - local_irq_restore(flags); - } - EXPORT_SYMBOL(__tasklet_schedule); -@@ -464,10 +925,7 @@ void __tasklet_hi_schedule(struct tasklet_struct *t) - unsigned long flags; - - local_irq_save(flags); -- t->next = NULL; -- *__this_cpu_read(tasklet_hi_vec.tail) = t; -- __this_cpu_write(tasklet_hi_vec.tail, &(t->next)); -- raise_softirq_irqoff(HI_SOFTIRQ); -+ __tasklet_common_schedule(t, this_cpu_ptr(&tasklet_hi_vec), HI_SOFTIRQ); - local_irq_restore(flags); - } - EXPORT_SYMBOL(__tasklet_hi_schedule); -@@ -476,82 +934,122 @@ void __tasklet_hi_schedule_first(struct tasklet_struct *t) - { - BUG_ON(!irqs_disabled()); - -- t->next = __this_cpu_read(tasklet_hi_vec.head); -- __this_cpu_write(tasklet_hi_vec.head, t); -- __raise_softirq_irqoff(HI_SOFTIRQ); -+ __tasklet_hi_schedule(t); - } - EXPORT_SYMBOL(__tasklet_hi_schedule_first); - --static void tasklet_action(struct softirq_action *a) -+void tasklet_enable(struct tasklet_struct *t) - { -- struct tasklet_struct *list; -+ if (!atomic_dec_and_test(&t->count)) -+ return; -+ if (test_and_clear_bit(TASKLET_STATE_PENDING, &t->state)) -+ tasklet_schedule(t); -+} -+EXPORT_SYMBOL(tasklet_enable); - -- local_irq_disable(); -- list = __this_cpu_read(tasklet_vec.head); -- __this_cpu_write(tasklet_vec.head, NULL); -- __this_cpu_write(tasklet_vec.tail, this_cpu_ptr(&tasklet_vec.head)); -- local_irq_enable(); -+static void __tasklet_action(struct softirq_action *a, -+ struct tasklet_struct *list) -+{ -+ int loops = 1000000; - - while (list) { - struct tasklet_struct *t = list; - - list = list->next; - -- if (tasklet_trylock(t)) { -- if (!atomic_read(&t->count)) { -- if (!test_and_clear_bit(TASKLET_STATE_SCHED, -- &t->state)) -- BUG(); -- t->func(t->data); -- tasklet_unlock(t); -- continue; -- } -- tasklet_unlock(t); -+ /* -+ * Should always succeed - after a tasklist got on the -+ * list (after getting the SCHED bit set from 0 to 1), -+ * nothing but the tasklet softirq it got queued to can -+ * lock it: -+ */ -+ if (!tasklet_trylock(t)) { -+ WARN_ON(1); -+ continue; - } - -- local_irq_disable(); - t->next = NULL; -- *__this_cpu_read(tasklet_vec.tail) = t; -- __this_cpu_write(tasklet_vec.tail, &(t->next)); -- __raise_softirq_irqoff(TASKLET_SOFTIRQ); -- local_irq_enable(); -+ -+ /* -+ * If we cannot handle the tasklet because it's disabled, -+ * mark it as pending. tasklet_enable() will later -+ * re-schedule the tasklet. -+ */ -+ if (unlikely(atomic_read(&t->count))) { -+out_disabled: -+ /* implicit unlock: */ -+ wmb(); -+ t->state = TASKLET_STATEF_PENDING; -+ continue; -+ } -+ -+ /* -+ * After this point on the tasklet might be rescheduled -+ * on another CPU, but it can only be added to another -+ * CPU's tasklet list if we unlock the tasklet (which we -+ * dont do yet). -+ */ -+ if (!test_and_clear_bit(TASKLET_STATE_SCHED, &t->state)) -+ WARN_ON(1); -+ -+again: -+ t->func(t->data); -+ -+ /* -+ * Try to unlock the tasklet. We must use cmpxchg, because -+ * another CPU might have scheduled or disabled the tasklet. -+ * We only allow the STATE_RUN -> 0 transition here. -+ */ -+ while (!tasklet_tryunlock(t)) { -+ /* -+ * If it got disabled meanwhile, bail out: -+ */ -+ if (atomic_read(&t->count)) -+ goto out_disabled; -+ /* -+ * If it got scheduled meanwhile, re-execute -+ * the tasklet function: -+ */ -+ if (test_and_clear_bit(TASKLET_STATE_SCHED, &t->state)) -+ goto again; -+ if (!--loops) { -+ printk("hm, tasklet state: %08lx\n", t->state); -+ WARN_ON(1); -+ tasklet_unlock(t); -+ break; -+ } -+ } - } - } - -+static void tasklet_action(struct softirq_action *a) -+{ -+ struct tasklet_struct *list; -+ -+ local_irq_disable(); -+ -+ list = __this_cpu_read(tasklet_vec.head); -+ __this_cpu_write(tasklet_vec.head, NULL); -+ __this_cpu_write(tasklet_vec.tail, this_cpu_ptr(&tasklet_vec.head)); -+ -+ local_irq_enable(); -+ -+ __tasklet_action(a, list); -+} -+ - static void tasklet_hi_action(struct softirq_action *a) - { - struct tasklet_struct *list; - - local_irq_disable(); -+ - list = __this_cpu_read(tasklet_hi_vec.head); - __this_cpu_write(tasklet_hi_vec.head, NULL); - __this_cpu_write(tasklet_hi_vec.tail, this_cpu_ptr(&tasklet_hi_vec.head)); -- local_irq_enable(); - -- while (list) { -- struct tasklet_struct *t = list; -- -- list = list->next; -- -- if (tasklet_trylock(t)) { -- if (!atomic_read(&t->count)) { -- if (!test_and_clear_bit(TASKLET_STATE_SCHED, -- &t->state)) -- BUG(); -- t->func(t->data); -- tasklet_unlock(t); -- continue; -- } -- tasklet_unlock(t); -- } -+ local_irq_enable(); - -- local_irq_disable(); -- t->next = NULL; -- *__this_cpu_read(tasklet_hi_vec.tail) = t; -- __this_cpu_write(tasklet_hi_vec.tail, &(t->next)); -- __raise_softirq_irqoff(HI_SOFTIRQ); -- local_irq_enable(); -- } -+ __tasklet_action(a, list); - } - - void tasklet_init(struct tasklet_struct *t, -@@ -572,7 +1070,7 @@ void tasklet_kill(struct tasklet_struct *t) - - while (test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) { - do { -- yield(); -+ msleep(1); - } while (test_bit(TASKLET_STATE_SCHED, &t->state)); - } - tasklet_unlock_wait(t); -@@ -646,25 +1144,26 @@ void __init softirq_init(void) - open_softirq(HI_SOFTIRQ, tasklet_hi_action); - } - --static int ksoftirqd_should_run(unsigned int cpu) --{ -- return local_softirq_pending(); --} -- --static void run_ksoftirqd(unsigned int cpu) -+#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT_RT_FULL) -+void tasklet_unlock_wait(struct tasklet_struct *t) - { -- local_irq_disable(); -- if (local_softirq_pending()) { -+ while (test_bit(TASKLET_STATE_RUN, &(t)->state)) { - /* -- * We can safely run softirq on inline stack, as we are not deep -- * in the task stack here. -+ * Hack for now to avoid this busy-loop: - */ -- __do_softirq(); -- local_irq_enable(); -- cond_resched_rcu_qs(); -- return; -+#ifdef CONFIG_PREEMPT_RT_FULL -+ msleep(1); -+#else -+ barrier(); -+#endif - } -- local_irq_enable(); -+} -+EXPORT_SYMBOL(tasklet_unlock_wait); -+#endif -+ -+static int ksoftirqd_should_run(unsigned int cpu) -+{ -+ return ksoftirqd_softirq_pending(); - } - - #ifdef CONFIG_HOTPLUG_CPU -@@ -746,16 +1245,31 @@ static struct notifier_block cpu_nfb = { - - static struct smp_hotplug_thread softirq_threads = { - .store = &ksoftirqd, -+ .setup = ksoftirqd_set_sched_params, - .thread_should_run = ksoftirqd_should_run, - .thread_fn = run_ksoftirqd, - .thread_comm = "ksoftirqd/%u", - }; - -+#ifdef CONFIG_PREEMPT_RT_FULL -+static struct smp_hotplug_thread softirq_timer_threads = { -+ .store = &ktimer_softirqd, -+ .setup = ktimer_softirqd_set_sched_params, -+ .cleanup = ktimer_softirqd_clr_sched_params, -+ .thread_should_run = ktimer_softirqd_should_run, -+ .thread_fn = run_ksoftirqd, -+ .thread_comm = "ktimersoftd/%u", -+}; -+#endif -+ - static __init int spawn_ksoftirqd(void) - { - register_cpu_notifier(&cpu_nfb); - - BUG_ON(smpboot_register_percpu_thread(&softirq_threads)); -+#ifdef CONFIG_PREEMPT_RT_FULL -+ BUG_ON(smpboot_register_percpu_thread(&softirq_timer_threads)); -+#endif - - return 0; - } -diff --git a/kernel/stop_machine.c b/kernel/stop_machine.c -index a467e6c..d01a511 100644 ---- a/kernel/stop_machine.c -+++ b/kernel/stop_machine.c -@@ -36,7 +36,7 @@ struct cpu_stop_done { - struct cpu_stopper { - struct task_struct *thread; - -- spinlock_t lock; -+ raw_spinlock_t lock; - bool enabled; /* is this stopper enabled? */ - struct list_head works; /* list of pending works */ - -@@ -82,14 +82,14 @@ static bool cpu_stop_queue_work(unsigned int cpu, struct cpu_stop_work *work) - unsigned long flags; - bool enabled; - -- spin_lock_irqsave(&stopper->lock, flags); -+ raw_spin_lock_irqsave(&stopper->lock, flags); - enabled = stopper->enabled; - if (enabled) - __cpu_stop_queue_work(stopper, work); - else if (work->done) - cpu_stop_signal_done(work->done); -- spin_unlock_irqrestore(&stopper->lock, flags); - -+ raw_spin_unlock_irqrestore(&stopper->lock, flags); - return enabled; - } - -@@ -224,8 +224,8 @@ static int cpu_stop_queue_two_works(int cpu1, struct cpu_stop_work *work1, - int err; - - lg_double_lock(&stop_cpus_lock, cpu1, cpu2); -- spin_lock_irq(&stopper1->lock); -- spin_lock_nested(&stopper2->lock, SINGLE_DEPTH_NESTING); -+ raw_spin_lock_irq(&stopper1->lock); -+ raw_spin_lock_nested(&stopper2->lock, SINGLE_DEPTH_NESTING); - - err = -ENOENT; - if (!stopper1->enabled || !stopper2->enabled) -@@ -235,8 +235,8 @@ static int cpu_stop_queue_two_works(int cpu1, struct cpu_stop_work *work1, - __cpu_stop_queue_work(stopper1, work1); - __cpu_stop_queue_work(stopper2, work2); - unlock: -- spin_unlock(&stopper2->lock); -- spin_unlock_irq(&stopper1->lock); -+ raw_spin_unlock(&stopper2->lock); -+ raw_spin_unlock_irq(&stopper1->lock); - lg_double_unlock(&stop_cpus_lock, cpu1, cpu2); - - return err; -@@ -313,18 +313,21 @@ static DEFINE_MUTEX(stop_cpus_mutex); - - static bool queue_stop_cpus_work(const struct cpumask *cpumask, - cpu_stop_fn_t fn, void *arg, -- struct cpu_stop_done *done) -+ struct cpu_stop_done *done, bool inactive) - { - struct cpu_stop_work *work; - unsigned int cpu; - bool queued = false; - - /* -- * Disable preemption while queueing to avoid getting -- * preempted by a stopper which might wait for other stoppers -- * to enter @fn which can lead to deadlock. -+ * Make sure that all work is queued on all cpus before -+ * any of the cpus can execute it. - */ -- lg_global_lock(&stop_cpus_lock); -+ if (!inactive) -+ lg_global_lock(&stop_cpus_lock); -+ else -+ lg_global_trylock_relax(&stop_cpus_lock); -+ - for_each_cpu(cpu, cpumask) { - work = &per_cpu(cpu_stopper.stop_work, cpu); - work->fn = fn; -@@ -344,7 +347,7 @@ static int __stop_cpus(const struct cpumask *cpumask, - struct cpu_stop_done done; - - cpu_stop_init_done(&done, cpumask_weight(cpumask)); -- if (!queue_stop_cpus_work(cpumask, fn, arg, &done)) -+ if (!queue_stop_cpus_work(cpumask, fn, arg, &done, false)) - return -ENOENT; - wait_for_completion(&done.completion); - return done.ret; -@@ -425,9 +428,9 @@ static int cpu_stop_should_run(unsigned int cpu) - unsigned long flags; - int run; - -- spin_lock_irqsave(&stopper->lock, flags); -+ raw_spin_lock_irqsave(&stopper->lock, flags); - run = !list_empty(&stopper->works); -- spin_unlock_irqrestore(&stopper->lock, flags); -+ raw_spin_unlock_irqrestore(&stopper->lock, flags); - return run; - } - -@@ -438,13 +441,13 @@ static void cpu_stopper_thread(unsigned int cpu) - - repeat: - work = NULL; -- spin_lock_irq(&stopper->lock); -+ raw_spin_lock_irq(&stopper->lock); - if (!list_empty(&stopper->works)) { - work = list_first_entry(&stopper->works, - struct cpu_stop_work, list); - list_del_init(&work->list); - } -- spin_unlock_irq(&stopper->lock); -+ raw_spin_unlock_irq(&stopper->lock); - - if (work) { - cpu_stop_fn_t fn = work->fn; -@@ -452,6 +455,16 @@ repeat: - struct cpu_stop_done *done = work->done; - int ret; - -+ /* -+ * Wait until the stopper finished scheduling on all -+ * cpus -+ */ -+ lg_global_lock(&stop_cpus_lock); -+ /* -+ * Let other cpu threads continue as well -+ */ -+ lg_global_unlock(&stop_cpus_lock); -+ - /* cpu stop callbacks must not sleep, make in_atomic() == T */ - preempt_count_inc(); - ret = fn(arg); -@@ -518,10 +531,12 @@ static int __init cpu_stop_init(void) - for_each_possible_cpu(cpu) { - struct cpu_stopper *stopper = &per_cpu(cpu_stopper, cpu); - -- spin_lock_init(&stopper->lock); -+ raw_spin_lock_init(&stopper->lock); - INIT_LIST_HEAD(&stopper->works); - } - -+ lg_lock_init(&stop_cpus_lock, "stop_cpus_lock"); -+ - BUG_ON(smpboot_register_percpu_thread(&cpu_stop_threads)); - stop_machine_unpark(raw_smp_processor_id()); - stop_machine_initialized = true; -@@ -616,7 +631,7 @@ int stop_machine_from_inactive_cpu(cpu_stop_fn_t fn, void *data, - set_state(&msdata, MULTI_STOP_PREPARE); - cpu_stop_init_done(&done, num_active_cpus()); - queue_stop_cpus_work(cpu_active_mask, multi_cpu_stop, &msdata, -- &done); -+ &done, true); - ret = multi_cpu_stop(&msdata); - - /* Busy wait for completion. */ -diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c -index fa0b983..ab846ab 100644 ---- a/kernel/time/hrtimer.c -+++ b/kernel/time/hrtimer.c -@@ -48,11 +48,13 @@ - #include <linux/sched/rt.h> - #include <linux/sched/deadline.h> - #include <linux/timer.h> -+#include <linux/kthread.h> - #include <linux/freezer.h> - - #include <asm/uaccess.h> - - #include <trace/events/timer.h> -+#include <trace/events/hist.h> - - #include "tick-internal.h" - -@@ -706,6 +708,44 @@ static void clock_was_set_work(struct work_struct *work) - - static DECLARE_WORK(hrtimer_work, clock_was_set_work); - -+#ifdef CONFIG_PREEMPT_RT_FULL -+/* -+ * RT can not call schedule_work from real interrupt context. -+ * Need to make a thread to do the real work. -+ */ -+static struct task_struct *clock_set_delay_thread; -+static bool do_clock_set_delay; -+ -+static int run_clock_set_delay(void *ignore) -+{ -+ while (!kthread_should_stop()) { -+ set_current_state(TASK_INTERRUPTIBLE); -+ if (do_clock_set_delay) { -+ do_clock_set_delay = false; -+ schedule_work(&hrtimer_work); -+ } -+ schedule(); -+ } -+ __set_current_state(TASK_RUNNING); -+ return 0; -+} -+ -+void clock_was_set_delayed(void) -+{ -+ do_clock_set_delay = true; -+ /* Make visible before waking up process */ -+ smp_wmb(); -+ wake_up_process(clock_set_delay_thread); -+} -+ -+static __init int create_clock_set_delay_thread(void) -+{ -+ clock_set_delay_thread = kthread_run(run_clock_set_delay, NULL, "kclksetdelayd"); -+ BUG_ON(!clock_set_delay_thread); -+ return 0; -+} -+early_initcall(create_clock_set_delay_thread); -+#else /* PREEMPT_RT_FULL */ - /* - * Called from timekeeping and resume code to reprogramm the hrtimer - * interrupt device on all cpus. -@@ -714,6 +754,7 @@ void clock_was_set_delayed(void) - { - schedule_work(&hrtimer_work); - } -+#endif - - #else - -@@ -723,11 +764,8 @@ static inline int hrtimer_is_hres_enabled(void) { return 0; } - static inline void hrtimer_switch_to_hres(void) { } - static inline void - hrtimer_force_reprogram(struct hrtimer_cpu_base *base, int skip_equal) { } --static inline int hrtimer_reprogram(struct hrtimer *timer, -- struct hrtimer_clock_base *base) --{ -- return 0; --} -+static inline void hrtimer_reprogram(struct hrtimer *timer, -+ struct hrtimer_clock_base *base) { } - static inline void hrtimer_init_hres(struct hrtimer_cpu_base *base) { } - static inline void retrigger_next_event(void *arg) { } - -@@ -859,6 +897,32 @@ u64 hrtimer_forward(struct hrtimer *timer, ktime_t now, ktime_t interval) - } - EXPORT_SYMBOL_GPL(hrtimer_forward); - -+#ifdef CONFIG_PREEMPT_RT_BASE -+# define wake_up_timer_waiters(b) wake_up(&(b)->wait) -+ -+/** -+ * hrtimer_wait_for_timer - Wait for a running timer -+ * -+ * @timer: timer to wait for -+ * -+ * The function waits in case the timers callback function is -+ * currently executed on the waitqueue of the timer base. The -+ * waitqueue is woken up after the timer callback function has -+ * finished execution. -+ */ -+void hrtimer_wait_for_timer(const struct hrtimer *timer) -+{ -+ struct hrtimer_clock_base *base = timer->base; -+ -+ if (base && base->cpu_base && !timer->irqsafe) -+ wait_event(base->cpu_base->wait, -+ !(hrtimer_callback_running(timer))); -+} -+ -+#else -+# define wake_up_timer_waiters(b) do { } while (0) -+#endif -+ - /* - * enqueue_hrtimer - internal function to (re)start a timer - * -@@ -900,6 +964,11 @@ static void __remove_hrtimer(struct hrtimer *timer, - if (!(state & HRTIMER_STATE_ENQUEUED)) - return; - -+ if (unlikely(!list_empty(&timer->cb_entry))) { -+ list_del_init(&timer->cb_entry); -+ return; -+ } -+ - if (!timerqueue_del(&base->active, &timer->node)) - cpu_base->active_bases &= ~(1 << base->index); - -@@ -995,7 +1064,16 @@ void hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim, - new_base = switch_hrtimer_base(timer, base, mode & HRTIMER_MODE_PINNED); - - timer_stats_hrtimer_set_start_info(timer); -+#ifdef CONFIG_MISSED_TIMER_OFFSETS_HIST -+ { -+ ktime_t now = new_base->get_time(); - -+ if (ktime_to_ns(tim) < ktime_to_ns(now)) -+ timer->praecox = now; -+ else -+ timer->praecox = ktime_set(0, 0); -+ } -+#endif - leftmost = enqueue_hrtimer(timer, new_base); - if (!leftmost) - goto unlock; -@@ -1067,7 +1145,7 @@ int hrtimer_cancel(struct hrtimer *timer) - - if (ret >= 0) - return ret; -- cpu_relax(); -+ hrtimer_wait_for_timer(timer); - } - } - EXPORT_SYMBOL_GPL(hrtimer_cancel); -@@ -1131,6 +1209,7 @@ static void __hrtimer_init(struct hrtimer *timer, clockid_t clock_id, - - base = hrtimer_clockid_to_base(clock_id); - timer->base = &cpu_base->clock_base[base]; -+ INIT_LIST_HEAD(&timer->cb_entry); - timerqueue_init(&timer->node); - - #ifdef CONFIG_TIMER_STATS -@@ -1171,6 +1250,7 @@ bool hrtimer_active(const struct hrtimer *timer) - seq = raw_read_seqcount_begin(&cpu_base->seq); - - if (timer->state != HRTIMER_STATE_INACTIVE || -+ cpu_base->running_soft == timer || - cpu_base->running == timer) - return true; - -@@ -1269,10 +1349,112 @@ static void __run_hrtimer(struct hrtimer_cpu_base *cpu_base, - cpu_base->running = NULL; - } - -+#ifdef CONFIG_PREEMPT_RT_BASE -+static void hrtimer_rt_reprogram(int restart, struct hrtimer *timer, -+ struct hrtimer_clock_base *base) -+{ -+ int leftmost; -+ -+ if (restart != HRTIMER_NORESTART && -+ !(timer->state & HRTIMER_STATE_ENQUEUED)) { -+ -+ leftmost = enqueue_hrtimer(timer, base); -+ if (!leftmost) -+ return; -+#ifdef CONFIG_HIGH_RES_TIMERS -+ if (!hrtimer_is_hres_active(timer)) { -+ /* -+ * Kick to reschedule the next tick to handle the new timer -+ * on dynticks target. -+ */ -+ if (base->cpu_base->nohz_active) -+ wake_up_nohz_cpu(base->cpu_base->cpu); -+ } else { -+ -+ hrtimer_reprogram(timer, base); -+ } -+#endif -+ } -+} -+ -+/* -+ * The changes in mainline which removed the callback modes from -+ * hrtimer are not yet working with -rt. The non wakeup_process() -+ * based callbacks which involve sleeping locks need to be treated -+ * seperately. -+ */ -+static void hrtimer_rt_run_pending(void) -+{ -+ enum hrtimer_restart (*fn)(struct hrtimer *); -+ struct hrtimer_cpu_base *cpu_base; -+ struct hrtimer_clock_base *base; -+ struct hrtimer *timer; -+ int index, restart; -+ -+ local_irq_disable(); -+ cpu_base = &per_cpu(hrtimer_bases, smp_processor_id()); -+ -+ raw_spin_lock(&cpu_base->lock); -+ -+ for (index = 0; index < HRTIMER_MAX_CLOCK_BASES; index++) { -+ base = &cpu_base->clock_base[index]; -+ -+ while (!list_empty(&base->expired)) { -+ timer = list_first_entry(&base->expired, -+ struct hrtimer, cb_entry); -+ -+ /* -+ * Same as the above __run_hrtimer function -+ * just we run with interrupts enabled. -+ */ -+ debug_deactivate(timer); -+ cpu_base->running_soft = timer; -+ raw_write_seqcount_barrier(&cpu_base->seq); -+ -+ __remove_hrtimer(timer, base, HRTIMER_STATE_INACTIVE, 0); -+ timer_stats_account_hrtimer(timer); -+ fn = timer->function; -+ -+ raw_spin_unlock_irq(&cpu_base->lock); -+ restart = fn(timer); -+ raw_spin_lock_irq(&cpu_base->lock); -+ -+ hrtimer_rt_reprogram(restart, timer, base); -+ raw_write_seqcount_barrier(&cpu_base->seq); -+ -+ WARN_ON_ONCE(cpu_base->running_soft != timer); -+ cpu_base->running_soft = NULL; -+ } -+ } -+ -+ raw_spin_unlock_irq(&cpu_base->lock); -+ -+ wake_up_timer_waiters(cpu_base); -+} -+ -+static int hrtimer_rt_defer(struct hrtimer *timer) -+{ -+ if (timer->irqsafe) -+ return 0; -+ -+ __remove_hrtimer(timer, timer->base, timer->state, 0); -+ list_add_tail(&timer->cb_entry, &timer->base->expired); -+ return 1; -+} -+ -+#else -+ -+static inline int hrtimer_rt_defer(struct hrtimer *timer) { return 0; } -+ -+#endif -+ -+static enum hrtimer_restart hrtimer_wakeup(struct hrtimer *timer); -+ - static void __hrtimer_run_queues(struct hrtimer_cpu_base *cpu_base, ktime_t now) - { - struct hrtimer_clock_base *base = cpu_base->clock_base; - unsigned int active = cpu_base->active_bases; -+ int raise = 0; - - for (; active; base++, active >>= 1) { - struct timerqueue_node *node; -@@ -1288,6 +1470,15 @@ static void __hrtimer_run_queues(struct hrtimer_cpu_base *cpu_base, ktime_t now) - - timer = container_of(node, struct hrtimer, node); - -+ trace_hrtimer_interrupt(raw_smp_processor_id(), -+ ktime_to_ns(ktime_sub(ktime_to_ns(timer->praecox) ? -+ timer->praecox : hrtimer_get_expires(timer), -+ basenow)), -+ current, -+ timer->function == hrtimer_wakeup ? -+ container_of(timer, struct hrtimer_sleeper, -+ timer)->task : NULL); -+ - /* - * The immediate goal for using the softexpires is - * minimizing wakeups, not running timers at the -@@ -1303,9 +1494,14 @@ static void __hrtimer_run_queues(struct hrtimer_cpu_base *cpu_base, ktime_t now) - if (basenow.tv64 < hrtimer_get_softexpires_tv64(timer)) - break; - -- __run_hrtimer(cpu_base, base, timer, &basenow); -+ if (!hrtimer_rt_defer(timer)) -+ __run_hrtimer(cpu_base, base, timer, &basenow); -+ else -+ raise = 1; - } - } -+ if (raise) -+ raise_softirq_irqoff(HRTIMER_SOFTIRQ); - } - - #ifdef CONFIG_HIGH_RES_TIMERS -@@ -1468,16 +1664,18 @@ static enum hrtimer_restart hrtimer_wakeup(struct hrtimer *timer) - void hrtimer_init_sleeper(struct hrtimer_sleeper *sl, struct task_struct *task) - { - sl->timer.function = hrtimer_wakeup; -+ sl->timer.irqsafe = 1; - sl->task = task; - } - EXPORT_SYMBOL_GPL(hrtimer_init_sleeper); - --static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mode) -+static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mode, -+ unsigned long state) - { - hrtimer_init_sleeper(t, current); - - do { -- set_current_state(TASK_INTERRUPTIBLE); -+ set_current_state(state); - hrtimer_start_expires(&t->timer, mode); - - if (likely(t->task)) -@@ -1519,7 +1717,8 @@ long __sched hrtimer_nanosleep_restart(struct restart_block *restart) - HRTIMER_MODE_ABS); - hrtimer_set_expires_tv64(&t.timer, restart->nanosleep.expires); - -- if (do_nanosleep(&t, HRTIMER_MODE_ABS)) -+ /* cpu_chill() does not care about restart state. */ -+ if (do_nanosleep(&t, HRTIMER_MODE_ABS, TASK_INTERRUPTIBLE)) - goto out; - - rmtp = restart->nanosleep.rmtp; -@@ -1536,8 +1735,10 @@ out: - return ret; - } - --long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp, -- const enum hrtimer_mode mode, const clockid_t clockid) -+static long -+__hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp, -+ const enum hrtimer_mode mode, const clockid_t clockid, -+ unsigned long state) - { - struct restart_block *restart; - struct hrtimer_sleeper t; -@@ -1550,7 +1751,7 @@ long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp, - - hrtimer_init_on_stack(&t.timer, clockid, mode); - hrtimer_set_expires_range_ns(&t.timer, timespec_to_ktime(*rqtp), slack); -- if (do_nanosleep(&t, mode)) -+ if (do_nanosleep(&t, mode, state)) - goto out; - - /* Absolute timers do not update the rmtp value and restart: */ -@@ -1577,6 +1778,12 @@ out: - return ret; - } - -+long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp, -+ const enum hrtimer_mode mode, const clockid_t clockid) -+{ -+ return __hrtimer_nanosleep(rqtp, rmtp, mode, clockid, TASK_INTERRUPTIBLE); -+} -+ - SYSCALL_DEFINE2(nanosleep, struct timespec __user *, rqtp, - struct timespec __user *, rmtp) - { -@@ -1591,6 +1798,26 @@ SYSCALL_DEFINE2(nanosleep, struct timespec __user *, rqtp, - return hrtimer_nanosleep(&tu, rmtp, HRTIMER_MODE_REL, CLOCK_MONOTONIC); - } - -+#ifdef CONFIG_PREEMPT_RT_FULL -+/* -+ * Sleep for 1 ms in hope whoever holds what we want will let it go. -+ */ -+void cpu_chill(void) -+{ -+ struct timespec tu = { -+ .tv_nsec = NSEC_PER_MSEC, -+ }; -+ unsigned int freeze_flag = current->flags & PF_NOFREEZE; -+ -+ current->flags |= PF_NOFREEZE; -+ __hrtimer_nanosleep(&tu, NULL, HRTIMER_MODE_REL, CLOCK_MONOTONIC, -+ TASK_UNINTERRUPTIBLE); -+ if (!freeze_flag) -+ current->flags &= ~PF_NOFREEZE; -+} -+EXPORT_SYMBOL(cpu_chill); -+#endif -+ - /* - * Functions related to boot-time initialization: - */ -@@ -1602,10 +1829,14 @@ static void init_hrtimers_cpu(int cpu) - for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++) { - cpu_base->clock_base[i].cpu_base = cpu_base; - timerqueue_init_head(&cpu_base->clock_base[i].active); -+ INIT_LIST_HEAD(&cpu_base->clock_base[i].expired); - } - - cpu_base->cpu = cpu; - hrtimer_init_hres(cpu_base); -+#ifdef CONFIG_PREEMPT_RT_BASE -+ init_waitqueue_head(&cpu_base->wait); -+#endif - } - - #ifdef CONFIG_HOTPLUG_CPU -@@ -1703,11 +1934,21 @@ static struct notifier_block hrtimers_nb = { - .notifier_call = hrtimer_cpu_notify, - }; - -+#ifdef CONFIG_PREEMPT_RT_BASE -+static void run_hrtimer_softirq(struct softirq_action *h) -+{ -+ hrtimer_rt_run_pending(); -+} -+#endif -+ - void __init hrtimers_init(void) - { - hrtimer_cpu_notify(&hrtimers_nb, (unsigned long)CPU_UP_PREPARE, - (void *)(long)smp_processor_id()); - register_cpu_notifier(&hrtimers_nb); -+#ifdef CONFIG_PREEMPT_RT_BASE -+ open_softirq(HRTIMER_SOFTIRQ, run_hrtimer_softirq); -+#endif - } - - /** -diff --git a/kernel/time/itimer.c b/kernel/time/itimer.c -index 1d5c720..184de67 100644 ---- a/kernel/time/itimer.c -+++ b/kernel/time/itimer.c -@@ -213,6 +213,7 @@ again: - /* We are sharing ->siglock with it_real_fn() */ - if (hrtimer_try_to_cancel(timer) < 0) { - spin_unlock_irq(&tsk->sighand->siglock); -+ hrtimer_wait_for_timer(&tsk->signal->real_timer); - goto again; - } - expires = timeval_to_ktime(value->it_value); -diff --git a/kernel/time/jiffies.c b/kernel/time/jiffies.c -index 555e21f..a5d6435 100644 ---- a/kernel/time/jiffies.c -+++ b/kernel/time/jiffies.c -@@ -74,7 +74,8 @@ static struct clocksource clocksource_jiffies = { - .max_cycles = 10, - }; - --__cacheline_aligned_in_smp DEFINE_SEQLOCK(jiffies_lock); -+__cacheline_aligned_in_smp DEFINE_RAW_SPINLOCK(jiffies_lock); -+__cacheline_aligned_in_smp seqcount_t jiffies_seq; - - #if (BITS_PER_LONG < 64) - u64 get_jiffies_64(void) -@@ -83,9 +84,9 @@ u64 get_jiffies_64(void) - u64 ret; - - do { -- seq = read_seqbegin(&jiffies_lock); -+ seq = read_seqcount_begin(&jiffies_seq); - ret = jiffies_64; -- } while (read_seqretry(&jiffies_lock, seq)); -+ } while (read_seqcount_retry(&jiffies_seq, seq)); - return ret; - } - EXPORT_SYMBOL(get_jiffies_64); -diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c -index 6df8927..6b4c19f 100644 ---- a/kernel/time/ntp.c -+++ b/kernel/time/ntp.c -@@ -10,6 +10,7 @@ - #include <linux/workqueue.h> - #include <linux/hrtimer.h> - #include <linux/jiffies.h> -+#include <linux/kthread.h> - #include <linux/math64.h> - #include <linux/timex.h> - #include <linux/time.h> -@@ -568,10 +569,52 @@ static void sync_cmos_clock(struct work_struct *work) - &sync_cmos_work, timespec64_to_jiffies(&next)); - } - -+#ifdef CONFIG_PREEMPT_RT_FULL -+/* -+ * RT can not call schedule_delayed_work from real interrupt context. -+ * Need to make a thread to do the real work. -+ */ -+static struct task_struct *cmos_delay_thread; -+static bool do_cmos_delay; -+ -+static int run_cmos_delay(void *ignore) -+{ -+ while (!kthread_should_stop()) { -+ set_current_state(TASK_INTERRUPTIBLE); -+ if (do_cmos_delay) { -+ do_cmos_delay = false; -+ queue_delayed_work(system_power_efficient_wq, -+ &sync_cmos_work, 0); -+ } -+ schedule(); -+ } -+ __set_current_state(TASK_RUNNING); -+ return 0; -+} -+ -+void ntp_notify_cmos_timer(void) -+{ -+ do_cmos_delay = true; -+ /* Make visible before waking up process */ -+ smp_wmb(); -+ wake_up_process(cmos_delay_thread); -+} -+ -+static __init int create_cmos_delay_thread(void) -+{ -+ cmos_delay_thread = kthread_run(run_cmos_delay, NULL, "kcmosdelayd"); -+ BUG_ON(!cmos_delay_thread); -+ return 0; -+} -+early_initcall(create_cmos_delay_thread); -+ -+#else -+ - void ntp_notify_cmos_timer(void) - { - queue_delayed_work(system_power_efficient_wq, &sync_cmos_work, 0); - } -+#endif /* CONFIG_PREEMPT_RT_FULL */ - - #else - void ntp_notify_cmos_timer(void) { } -diff --git a/kernel/time/posix-cpu-timers.c b/kernel/time/posix-cpu-timers.c -index 1cafba8..5f16807 100644 ---- a/kernel/time/posix-cpu-timers.c -+++ b/kernel/time/posix-cpu-timers.c -@@ -3,6 +3,7 @@ - */ - - #include <linux/sched.h> -+#include <linux/sched/rt.h> - #include <linux/posix-timers.h> - #include <linux/errno.h> - #include <linux/math64.h> -@@ -620,7 +621,7 @@ static int posix_cpu_timer_set(struct k_itimer *timer, int timer_flags, - /* - * Disarm any old timer after extracting its expiry time. - */ -- WARN_ON_ONCE(!irqs_disabled()); -+ WARN_ON_ONCE_NONRT(!irqs_disabled()); - - ret = 0; - old_incr = timer->it.cpu.incr; -@@ -1063,7 +1064,7 @@ void posix_cpu_timer_schedule(struct k_itimer *timer) - /* - * Now re-arm for the new expiry time. - */ -- WARN_ON_ONCE(!irqs_disabled()); -+ WARN_ON_ONCE_NONRT(!irqs_disabled()); - arm_timer(timer); - unlock_task_sighand(p, &flags); - -@@ -1152,13 +1153,13 @@ static inline int fastpath_timer_check(struct task_struct *tsk) - * already updated our counts. We need to check if any timers fire now. - * Interrupts are disabled. - */ --void run_posix_cpu_timers(struct task_struct *tsk) -+static void __run_posix_cpu_timers(struct task_struct *tsk) - { - LIST_HEAD(firing); - struct k_itimer *timer, *next; - unsigned long flags; - -- WARN_ON_ONCE(!irqs_disabled()); -+ WARN_ON_ONCE_NONRT(!irqs_disabled()); - - /* - * The fast path checks that there are no expired thread or thread -@@ -1212,6 +1213,190 @@ void run_posix_cpu_timers(struct task_struct *tsk) - } - } - -+#ifdef CONFIG_PREEMPT_RT_BASE -+#include <linux/kthread.h> -+#include <linux/cpu.h> -+DEFINE_PER_CPU(struct task_struct *, posix_timer_task); -+DEFINE_PER_CPU(struct task_struct *, posix_timer_tasklist); -+ -+static int posix_cpu_timers_thread(void *data) -+{ -+ int cpu = (long)data; -+ -+ BUG_ON(per_cpu(posix_timer_task,cpu) != current); -+ -+ while (!kthread_should_stop()) { -+ struct task_struct *tsk = NULL; -+ struct task_struct *next = NULL; -+ -+ if (cpu_is_offline(cpu)) -+ goto wait_to_die; -+ -+ /* grab task list */ -+ raw_local_irq_disable(); -+ tsk = per_cpu(posix_timer_tasklist, cpu); -+ per_cpu(posix_timer_tasklist, cpu) = NULL; -+ raw_local_irq_enable(); -+ -+ /* its possible the list is empty, just return */ -+ if (!tsk) { -+ set_current_state(TASK_INTERRUPTIBLE); -+ schedule(); -+ __set_current_state(TASK_RUNNING); -+ continue; -+ } -+ -+ /* Process task list */ -+ while (1) { -+ /* save next */ -+ next = tsk->posix_timer_list; -+ -+ /* run the task timers, clear its ptr and -+ * unreference it -+ */ -+ __run_posix_cpu_timers(tsk); -+ tsk->posix_timer_list = NULL; -+ put_task_struct(tsk); -+ -+ /* check if this is the last on the list */ -+ if (next == tsk) -+ break; -+ tsk = next; -+ } -+ } -+ return 0; -+ -+wait_to_die: -+ /* Wait for kthread_stop */ -+ set_current_state(TASK_INTERRUPTIBLE); -+ while (!kthread_should_stop()) { -+ schedule(); -+ set_current_state(TASK_INTERRUPTIBLE); -+ } -+ __set_current_state(TASK_RUNNING); -+ return 0; -+} -+ -+static inline int __fastpath_timer_check(struct task_struct *tsk) -+{ -+ /* tsk == current, ensure it is safe to use ->signal/sighand */ -+ if (unlikely(tsk->exit_state)) -+ return 0; -+ -+ if (!task_cputime_zero(&tsk->cputime_expires)) -+ return 1; -+ -+ if (!task_cputime_zero(&tsk->signal->cputime_expires)) -+ return 1; -+ -+ return 0; -+} -+ -+void run_posix_cpu_timers(struct task_struct *tsk) -+{ -+ unsigned long cpu = smp_processor_id(); -+ struct task_struct *tasklist; -+ -+ BUG_ON(!irqs_disabled()); -+ if(!per_cpu(posix_timer_task, cpu)) -+ return; -+ /* get per-cpu references */ -+ tasklist = per_cpu(posix_timer_tasklist, cpu); -+ -+ /* check to see if we're already queued */ -+ if (!tsk->posix_timer_list && __fastpath_timer_check(tsk)) { -+ get_task_struct(tsk); -+ if (tasklist) { -+ tsk->posix_timer_list = tasklist; -+ } else { -+ /* -+ * The list is terminated by a self-pointing -+ * task_struct -+ */ -+ tsk->posix_timer_list = tsk; -+ } -+ per_cpu(posix_timer_tasklist, cpu) = tsk; -+ -+ wake_up_process(per_cpu(posix_timer_task, cpu)); -+ } -+} -+ -+/* -+ * posix_cpu_thread_call - callback that gets triggered when a CPU is added. -+ * Here we can start up the necessary migration thread for the new CPU. -+ */ -+static int posix_cpu_thread_call(struct notifier_block *nfb, -+ unsigned long action, void *hcpu) -+{ -+ int cpu = (long)hcpu; -+ struct task_struct *p; -+ struct sched_param param; -+ -+ switch (action) { -+ case CPU_UP_PREPARE: -+ p = kthread_create(posix_cpu_timers_thread, hcpu, -+ "posixcputmr/%d",cpu); -+ if (IS_ERR(p)) -+ return NOTIFY_BAD; -+ p->flags |= PF_NOFREEZE; -+ kthread_bind(p, cpu); -+ /* Must be high prio to avoid getting starved */ -+ param.sched_priority = MAX_RT_PRIO-1; -+ sched_setscheduler(p, SCHED_FIFO, ¶m); -+ per_cpu(posix_timer_task,cpu) = p; -+ break; -+ case CPU_ONLINE: -+ /* Strictly unneccessary, as first user will wake it. */ -+ wake_up_process(per_cpu(posix_timer_task,cpu)); -+ break; -+#ifdef CONFIG_HOTPLUG_CPU -+ case CPU_UP_CANCELED: -+ /* Unbind it from offline cpu so it can run. Fall thru. */ -+ kthread_bind(per_cpu(posix_timer_task, cpu), -+ cpumask_any(cpu_online_mask)); -+ kthread_stop(per_cpu(posix_timer_task,cpu)); -+ per_cpu(posix_timer_task,cpu) = NULL; -+ break; -+ case CPU_DEAD: -+ kthread_stop(per_cpu(posix_timer_task,cpu)); -+ per_cpu(posix_timer_task,cpu) = NULL; -+ break; -+#endif -+ } -+ return NOTIFY_OK; -+} -+ -+/* Register at highest priority so that task migration (migrate_all_tasks) -+ * happens before everything else. -+ */ -+static struct notifier_block posix_cpu_thread_notifier = { -+ .notifier_call = posix_cpu_thread_call, -+ .priority = 10 -+}; -+ -+static int __init posix_cpu_thread_init(void) -+{ -+ void *hcpu = (void *)(long)smp_processor_id(); -+ /* Start one for boot CPU. */ -+ unsigned long cpu; -+ -+ /* init the per-cpu posix_timer_tasklets */ -+ for_each_possible_cpu(cpu) -+ per_cpu(posix_timer_tasklist, cpu) = NULL; -+ -+ posix_cpu_thread_call(&posix_cpu_thread_notifier, CPU_UP_PREPARE, hcpu); -+ posix_cpu_thread_call(&posix_cpu_thread_notifier, CPU_ONLINE, hcpu); -+ register_cpu_notifier(&posix_cpu_thread_notifier); -+ return 0; -+} -+early_initcall(posix_cpu_thread_init); -+#else /* CONFIG_PREEMPT_RT_BASE */ -+void run_posix_cpu_timers(struct task_struct *tsk) -+{ -+ __run_posix_cpu_timers(tsk); -+} -+#endif /* CONFIG_PREEMPT_RT_BASE */ -+ - /* - * Set one of the process-wide special case CPU timers or RLIMIT_CPU. - * The tsk->sighand->siglock must be held by the caller. -diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c -index f2826c3..464a981 100644 ---- a/kernel/time/posix-timers.c -+++ b/kernel/time/posix-timers.c -@@ -506,6 +506,7 @@ static enum hrtimer_restart posix_timer_fn(struct hrtimer *timer) - static struct pid *good_sigevent(sigevent_t * event) - { - struct task_struct *rtn = current->group_leader; -+ int sig = event->sigev_signo; - - if ((event->sigev_notify & SIGEV_THREAD_ID ) && - (!(rtn = find_task_by_vpid(event->sigev_notify_thread_id)) || -@@ -514,7 +515,8 @@ static struct pid *good_sigevent(sigevent_t * event) - return NULL; - - if (((event->sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE) && -- ((event->sigev_signo <= 0) || (event->sigev_signo > SIGRTMAX))) -+ (sig <= 0 || sig > SIGRTMAX || sig_kernel_only(sig) || -+ sig_kernel_coredump(sig))) - return NULL; - - return task_pid(rtn); -@@ -826,6 +828,20 @@ SYSCALL_DEFINE1(timer_getoverrun, timer_t, timer_id) - return overrun; - } - -+/* -+ * Protected by RCU! -+ */ -+static void timer_wait_for_callback(struct k_clock *kc, struct k_itimer *timr) -+{ -+#ifdef CONFIG_PREEMPT_RT_FULL -+ if (kc->timer_set == common_timer_set) -+ hrtimer_wait_for_timer(&timr->it.real.timer); -+ else -+ /* FIXME: Whacky hack for posix-cpu-timers */ -+ schedule_timeout(1); -+#endif -+} -+ - /* Set a POSIX.1b interval timer. */ - /* timr->it_lock is taken. */ - static int -@@ -903,6 +919,7 @@ retry: - if (!timr) - return -EINVAL; - -+ rcu_read_lock(); - kc = clockid_to_kclock(timr->it_clock); - if (WARN_ON_ONCE(!kc || !kc->timer_set)) - error = -EINVAL; -@@ -911,9 +928,12 @@ retry: - - unlock_timer(timr, flag); - if (error == TIMER_RETRY) { -+ timer_wait_for_callback(kc, timr); - rtn = NULL; // We already got the old time... -+ rcu_read_unlock(); - goto retry; - } -+ rcu_read_unlock(); - - if (old_setting && !error && - copy_to_user(old_setting, &old_spec, sizeof (old_spec))) -@@ -951,10 +971,15 @@ retry_delete: - if (!timer) - return -EINVAL; - -+ rcu_read_lock(); - if (timer_delete_hook(timer) == TIMER_RETRY) { - unlock_timer(timer, flags); -+ timer_wait_for_callback(clockid_to_kclock(timer->it_clock), -+ timer); -+ rcu_read_unlock(); - goto retry_delete; - } -+ rcu_read_unlock(); - - spin_lock(¤t->sighand->siglock); - list_del(&timer->list); -@@ -980,8 +1005,18 @@ static void itimer_delete(struct k_itimer *timer) - retry_delete: - spin_lock_irqsave(&timer->it_lock, flags); - -+ /* On RT we can race with a deletion */ -+ if (!timer->it_signal) { -+ unlock_timer(timer, flags); -+ return; -+ } -+ - if (timer_delete_hook(timer) == TIMER_RETRY) { -+ rcu_read_lock(); - unlock_timer(timer, flags); -+ timer_wait_for_callback(clockid_to_kclock(timer->it_clock), -+ timer); -+ rcu_read_unlock(); - goto retry_delete; - } - list_del(&timer->list); -diff --git a/kernel/time/tick-broadcast-hrtimer.c b/kernel/time/tick-broadcast-hrtimer.c -index 53d7184..1b4ac33 100644 ---- a/kernel/time/tick-broadcast-hrtimer.c -+++ b/kernel/time/tick-broadcast-hrtimer.c -@@ -106,5 +106,6 @@ void tick_setup_hrtimer_broadcast(void) - { - hrtimer_init(&bctimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); - bctimer.function = bc_handler; -+ bctimer.irqsafe = true; - clockevents_register_device(&ce_broadcast_hrtimer); - } -diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c -index 4fcd99e..5a47f2e 100644 ---- a/kernel/time/tick-common.c -+++ b/kernel/time/tick-common.c -@@ -79,13 +79,15 @@ int tick_is_oneshot_available(void) - static void tick_periodic(int cpu) - { - if (tick_do_timer_cpu == cpu) { -- write_seqlock(&jiffies_lock); -+ raw_spin_lock(&jiffies_lock); -+ write_seqcount_begin(&jiffies_seq); - - /* Keep track of the next tick event */ - tick_next_period = ktime_add(tick_next_period, tick_period); - - do_timer(1); -- write_sequnlock(&jiffies_lock); -+ write_seqcount_end(&jiffies_seq); -+ raw_spin_unlock(&jiffies_lock); - update_wall_time(); - } - -@@ -157,9 +159,9 @@ void tick_setup_periodic(struct clock_event_device *dev, int broadcast) - ktime_t next; - - do { -- seq = read_seqbegin(&jiffies_lock); -+ seq = read_seqcount_begin(&jiffies_seq); - next = tick_next_period; -- } while (read_seqretry(&jiffies_lock, seq)); -+ } while (read_seqcount_retry(&jiffies_seq, seq)); - - clockevents_switch_state(dev, CLOCK_EVT_STATE_ONESHOT); - -diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c -index 58e3310..8b005db 100644 ---- a/kernel/time/tick-sched.c -+++ b/kernel/time/tick-sched.c -@@ -62,7 +62,8 @@ static void tick_do_update_jiffies64(ktime_t now) - return; - - /* Reevalute with jiffies_lock held */ -- write_seqlock(&jiffies_lock); -+ raw_spin_lock(&jiffies_lock); -+ write_seqcount_begin(&jiffies_seq); - - delta = ktime_sub(now, last_jiffies_update); - if (delta.tv64 >= tick_period.tv64) { -@@ -85,10 +86,12 @@ static void tick_do_update_jiffies64(ktime_t now) - /* Keep the tick_next_period variable up to date */ - tick_next_period = ktime_add(last_jiffies_update, tick_period); - } else { -- write_sequnlock(&jiffies_lock); -+ write_seqcount_end(&jiffies_seq); -+ raw_spin_unlock(&jiffies_lock); - return; - } -- write_sequnlock(&jiffies_lock); -+ write_seqcount_end(&jiffies_seq); -+ raw_spin_unlock(&jiffies_lock); - update_wall_time(); - } - -@@ -99,12 +102,14 @@ static ktime_t tick_init_jiffy_update(void) - { - ktime_t period; - -- write_seqlock(&jiffies_lock); -+ raw_spin_lock(&jiffies_lock); -+ write_seqcount_begin(&jiffies_seq); - /* Did we start the jiffies update yet ? */ - if (last_jiffies_update.tv64 == 0) - last_jiffies_update = tick_next_period; - period = last_jiffies_update; -- write_sequnlock(&jiffies_lock); -+ write_seqcount_end(&jiffies_seq); -+ raw_spin_unlock(&jiffies_lock); - return period; - } - -@@ -212,6 +217,7 @@ static void nohz_full_kick_func(struct irq_work *work) - - static DEFINE_PER_CPU(struct irq_work, nohz_full_kick_work) = { - .func = nohz_full_kick_func, -+ .flags = IRQ_WORK_HARD_IRQ, - }; - - /* -@@ -670,10 +676,10 @@ static ktime_t tick_nohz_stop_sched_tick(struct tick_sched *ts, - - /* Read jiffies and the time when jiffies were updated last */ - do { -- seq = read_seqbegin(&jiffies_lock); -+ seq = read_seqcount_begin(&jiffies_seq); - basemono = last_jiffies_update.tv64; - basejiff = jiffies; -- } while (read_seqretry(&jiffies_lock, seq)); -+ } while (read_seqcount_retry(&jiffies_seq, seq)); - ts->last_jiffies = basejiff; - - if (rcu_needs_cpu(basemono, &next_rcu) || -@@ -861,14 +867,7 @@ static bool can_stop_idle_tick(int cpu, struct tick_sched *ts) - return false; - - if (unlikely(local_softirq_pending() && cpu_online(cpu))) { -- static int ratelimit; -- -- if (ratelimit < 10 && -- (local_softirq_pending() & SOFTIRQ_STOP_IDLE_MASK)) { -- pr_warn("NOHZ: local_softirq_pending %02x\n", -- (unsigned int) local_softirq_pending()); -- ratelimit++; -- } -+ softirq_check_pending_idle(); - return false; - } - -@@ -1208,6 +1207,7 @@ void tick_setup_sched_timer(void) - * Emulate tick processing via per-CPU hrtimers: - */ - hrtimer_init(&ts->sched_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); -+ ts->sched_timer.irqsafe = 1; - ts->sched_timer.function = tick_sched_timer; - - /* Get the next period (per cpu) */ -diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c -index 479d25c..410c04b 100644 ---- a/kernel/time/timekeeping.c -+++ b/kernel/time/timekeeping.c -@@ -2319,8 +2319,10 @@ EXPORT_SYMBOL(hardpps); - */ - void xtime_update(unsigned long ticks) - { -- write_seqlock(&jiffies_lock); -+ raw_spin_lock(&jiffies_lock); -+ write_seqcount_begin(&jiffies_seq); - do_timer(ticks); -- write_sequnlock(&jiffies_lock); -+ write_seqcount_end(&jiffies_seq); -+ raw_spin_unlock(&jiffies_lock); - update_wall_time(); - } -diff --git a/kernel/time/timekeeping.h b/kernel/time/timekeeping.h -index 704f595..763a3e5 100644 ---- a/kernel/time/timekeeping.h -+++ b/kernel/time/timekeeping.h -@@ -19,7 +19,8 @@ extern void timekeeping_resume(void); - extern void do_timer(unsigned long ticks); - extern void update_wall_time(void); - --extern seqlock_t jiffies_lock; -+extern raw_spinlock_t jiffies_lock; -+extern seqcount_t jiffies_seq; - - #define CS_NAME_LEN 32 - -diff --git a/kernel/time/timer.c b/kernel/time/timer.c -index 73164c3..5f9d359 100644 ---- a/kernel/time/timer.c -+++ b/kernel/time/timer.c -@@ -80,6 +80,9 @@ struct tvec_root { - struct tvec_base { - spinlock_t lock; - struct timer_list *running_timer; -+#ifdef CONFIG_PREEMPT_RT_FULL -+ wait_queue_head_t wait_for_running_timer; -+#endif - unsigned long timer_jiffies; - unsigned long next_timer; - unsigned long active_timers; -@@ -777,6 +780,39 @@ static struct tvec_base *lock_timer_base(struct timer_list *timer, - cpu_relax(); - } - } -+#ifdef CONFIG_PREEMPT_RT_FULL -+static inline struct tvec_base *switch_timer_base(struct timer_list *timer, -+ struct tvec_base *old, -+ struct tvec_base *new) -+{ -+ /* -+ * We cannot do the below because we might be preempted and -+ * then the preempter would see NULL and loop forever. -+ */ -+ if (spin_trylock(&new->lock)) { -+ WRITE_ONCE(timer->flags, -+ (timer->flags & ~TIMER_BASEMASK) | new->cpu); -+ spin_unlock(&old->lock); -+ return new; -+ } -+ return old; -+} -+ -+#else -+static inline struct tvec_base *switch_timer_base(struct timer_list *timer, -+ struct tvec_base *old, -+ struct tvec_base *new) -+{ -+ /* See the comment in lock_timer_base() */ -+ timer->flags |= TIMER_MIGRATING; -+ -+ spin_unlock(&old->lock); -+ spin_lock(&new->lock); -+ WRITE_ONCE(timer->flags, -+ (timer->flags & ~TIMER_BASEMASK) | new->cpu); -+ return new; -+} -+#endif - - static inline int - __mod_timer(struct timer_list *timer, unsigned long expires, -@@ -807,16 +843,8 @@ __mod_timer(struct timer_list *timer, unsigned long expires, - * handler yet has not finished. This also guarantees that - * the timer is serialized wrt itself. - */ -- if (likely(base->running_timer != timer)) { -- /* See the comment in lock_timer_base() */ -- timer->flags |= TIMER_MIGRATING; -- -- spin_unlock(&base->lock); -- base = new_base; -- spin_lock(&base->lock); -- WRITE_ONCE(timer->flags, -- (timer->flags & ~TIMER_BASEMASK) | base->cpu); -- } -+ if (likely(base->running_timer != timer)) -+ base = switch_timer_base(timer, base, new_base); - } - - timer->expires = expires; -@@ -1006,6 +1034,33 @@ void add_timer_on(struct timer_list *timer, int cpu) - } - EXPORT_SYMBOL_GPL(add_timer_on); - -+#ifdef CONFIG_PREEMPT_RT_FULL -+/* -+ * Wait for a running timer -+ */ -+static void wait_for_running_timer(struct timer_list *timer) -+{ -+ struct tvec_base *base; -+ u32 tf = timer->flags; -+ -+ if (tf & TIMER_MIGRATING) -+ return; -+ -+ base = per_cpu_ptr(&tvec_bases, tf & TIMER_CPUMASK); -+ wait_event(base->wait_for_running_timer, -+ base->running_timer != timer); -+} -+ -+# define wakeup_timer_waiters(b) wake_up(&(b)->wait_for_running_timer) -+#else -+static inline void wait_for_running_timer(struct timer_list *timer) -+{ -+ cpu_relax(); -+} -+ -+# define wakeup_timer_waiters(b) do { } while (0) -+#endif -+ - /** - * del_timer - deactive a timer. - * @timer: the timer to be deactivated -@@ -1063,7 +1118,7 @@ int try_to_del_timer_sync(struct timer_list *timer) - } - EXPORT_SYMBOL(try_to_del_timer_sync); - --#ifdef CONFIG_SMP -+#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT_RT_FULL) - /** - * del_timer_sync - deactivate a timer and wait for the handler to finish. - * @timer: the timer to be deactivated -@@ -1123,7 +1178,7 @@ int del_timer_sync(struct timer_list *timer) - int ret = try_to_del_timer_sync(timer); - if (ret >= 0) - return ret; -- cpu_relax(); -+ wait_for_running_timer(timer); - } - } - EXPORT_SYMBOL(del_timer_sync); -@@ -1248,15 +1303,17 @@ static inline void __run_timers(struct tvec_base *base) - if (irqsafe) { - spin_unlock(&base->lock); - call_timer_fn(timer, fn, data); -+ base->running_timer = NULL; - spin_lock(&base->lock); - } else { - spin_unlock_irq(&base->lock); - call_timer_fn(timer, fn, data); -+ base->running_timer = NULL; - spin_lock_irq(&base->lock); - } - } - } -- base->running_timer = NULL; -+ wakeup_timer_waiters(base); - spin_unlock_irq(&base->lock); - } - -@@ -1390,6 +1447,14 @@ u64 get_next_timer_interrupt(unsigned long basej, u64 basem) - if (cpu_is_offline(smp_processor_id())) - return expires; - -+#ifdef CONFIG_PREEMPT_RT_FULL -+ /* -+ * On PREEMPT_RT we cannot sleep here. As a result we can't take -+ * the base lock to check when the next timer is pending and so -+ * we assume the next jiffy. -+ */ -+ return basem + TICK_NSEC; -+#endif - spin_lock(&base->lock); - if (base->active_timers) { - if (time_before_eq(base->next_timer, base->timer_jiffies)) -@@ -1416,13 +1481,13 @@ void update_process_times(int user_tick) - - /* Note: this timer irq context must be accounted for as well. */ - account_process_tick(p, user_tick); -+ scheduler_tick(); - run_local_timers(); - rcu_check_callbacks(user_tick); --#ifdef CONFIG_IRQ_WORK -+#if defined(CONFIG_IRQ_WORK) - if (in_irq()) - irq_work_tick(); - #endif -- scheduler_tick(); - run_posix_cpu_timers(p); - } - -@@ -1433,6 +1498,8 @@ static void run_timer_softirq(struct softirq_action *h) - { - struct tvec_base *base = this_cpu_ptr(&tvec_bases); - -+ irq_work_tick_soft(); -+ - if (time_after_eq(jiffies, base->timer_jiffies)) - __run_timers(base); - } -@@ -1600,7 +1667,7 @@ static void migrate_timers(int cpu) - - BUG_ON(cpu_online(cpu)); - old_base = per_cpu_ptr(&tvec_bases, cpu); -- new_base = get_cpu_ptr(&tvec_bases); -+ new_base = get_local_ptr(&tvec_bases); - /* - * The caller is globally serialized and nobody else - * takes two locks at once, deadlock is not possible. -@@ -1624,7 +1691,7 @@ static void migrate_timers(int cpu) - - spin_unlock(&old_base->lock); - spin_unlock_irq(&new_base->lock); -- put_cpu_ptr(&tvec_bases); -+ put_local_ptr(&tvec_bases); - } - - static int timer_cpu_notify(struct notifier_block *self, -@@ -1656,6 +1723,9 @@ static void __init init_timer_cpu(int cpu) - - base->cpu = cpu; - spin_lock_init(&base->lock); -+#ifdef CONFIG_PREEMPT_RT_FULL -+ init_waitqueue_head(&base->wait_for_running_timer); -+#endif - - base->timer_jiffies = jiffies; - base->next_timer = base->timer_jiffies; -diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig -index e45db6b..364ccd0 100644 ---- a/kernel/trace/Kconfig -+++ b/kernel/trace/Kconfig -@@ -187,6 +187,24 @@ config IRQSOFF_TRACER - enabled. This option and the preempt-off timing option can be - used together or separately.) - -+config INTERRUPT_OFF_HIST -+ bool "Interrupts-off Latency Histogram" -+ depends on IRQSOFF_TRACER -+ help -+ This option generates continuously updated histograms (one per cpu) -+ of the duration of time periods with interrupts disabled. The -+ histograms are disabled by default. To enable them, write a non-zero -+ number to -+ -+ /sys/kernel/debug/tracing/latency_hist/enable/preemptirqsoff -+ -+ If PREEMPT_OFF_HIST is also selected, additional histograms (one -+ per cpu) are generated that accumulate the duration of time periods -+ when both interrupts and preemption are disabled. The histogram data -+ will be located in the debug file system at -+ -+ /sys/kernel/debug/tracing/latency_hist/irqsoff -+ - config PREEMPT_TRACER - bool "Preemption-off Latency Tracer" - default n -@@ -211,6 +229,24 @@ config PREEMPT_TRACER - enabled. This option and the irqs-off timing option can be - used together or separately.) - -+config PREEMPT_OFF_HIST -+ bool "Preemption-off Latency Histogram" -+ depends on PREEMPT_TRACER -+ help -+ This option generates continuously updated histograms (one per cpu) -+ of the duration of time periods with preemption disabled. The -+ histograms are disabled by default. To enable them, write a non-zero -+ number to -+ -+ /sys/kernel/debug/tracing/latency_hist/enable/preemptirqsoff -+ -+ If INTERRUPT_OFF_HIST is also selected, additional histograms (one -+ per cpu) are generated that accumulate the duration of time periods -+ when both interrupts and preemption are disabled. The histogram data -+ will be located in the debug file system at -+ -+ /sys/kernel/debug/tracing/latency_hist/preemptoff -+ - config SCHED_TRACER - bool "Scheduling Latency Tracer" - select GENERIC_TRACER -@@ -221,6 +257,74 @@ config SCHED_TRACER - This tracer tracks the latency of the highest priority task - to be scheduled in, starting from the point it has woken up. - -+config WAKEUP_LATENCY_HIST -+ bool "Scheduling Latency Histogram" -+ depends on SCHED_TRACER -+ help -+ This option generates continuously updated histograms (one per cpu) -+ of the scheduling latency of the highest priority task. -+ The histograms are disabled by default. To enable them, write a -+ non-zero number to -+ -+ /sys/kernel/debug/tracing/latency_hist/enable/wakeup -+ -+ Two different algorithms are used, one to determine the latency of -+ processes that exclusively use the highest priority of the system and -+ another one to determine the latency of processes that share the -+ highest system priority with other processes. The former is used to -+ improve hardware and system software, the latter to optimize the -+ priority design of a given system. The histogram data will be -+ located in the debug file system at -+ -+ /sys/kernel/debug/tracing/latency_hist/wakeup -+ -+ and -+ -+ /sys/kernel/debug/tracing/latency_hist/wakeup/sharedprio -+ -+ If both Scheduling Latency Histogram and Missed Timer Offsets -+ Histogram are selected, additional histogram data will be collected -+ that contain, in addition to the wakeup latency, the timer latency, in -+ case the wakeup was triggered by an expired timer. These histograms -+ are available in the -+ -+ /sys/kernel/debug/tracing/latency_hist/timerandwakeup -+ -+ directory. They reflect the apparent interrupt and scheduling latency -+ and are best suitable to determine the worst-case latency of a given -+ system. To enable these histograms, write a non-zero number to -+ -+ /sys/kernel/debug/tracing/latency_hist/enable/timerandwakeup -+ -+config MISSED_TIMER_OFFSETS_HIST -+ depends on HIGH_RES_TIMERS -+ select GENERIC_TRACER -+ bool "Missed Timer Offsets Histogram" -+ help -+ Generate a histogram of missed timer offsets in microseconds. The -+ histograms are disabled by default. To enable them, write a non-zero -+ number to -+ -+ /sys/kernel/debug/tracing/latency_hist/enable/missed_timer_offsets -+ -+ The histogram data will be located in the debug file system at -+ -+ /sys/kernel/debug/tracing/latency_hist/missed_timer_offsets -+ -+ If both Scheduling Latency Histogram and Missed Timer Offsets -+ Histogram are selected, additional histogram data will be collected -+ that contain, in addition to the wakeup latency, the timer latency, in -+ case the wakeup was triggered by an expired timer. These histograms -+ are available in the -+ -+ /sys/kernel/debug/tracing/latency_hist/timerandwakeup -+ -+ directory. They reflect the apparent interrupt and scheduling latency -+ and are best suitable to determine the worst-case latency of a given -+ system. To enable these histograms, write a non-zero number to -+ -+ /sys/kernel/debug/tracing/latency_hist/enable/timerandwakeup -+ - config ENABLE_DEFAULT_TRACERS - bool "Trace process context switches and events" - depends on !GENERIC_TRACER -diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile -index 9b1044e..3bbaea0 100644 ---- a/kernel/trace/Makefile -+++ b/kernel/trace/Makefile -@@ -36,6 +36,10 @@ obj-$(CONFIG_FUNCTION_TRACER) += trace_functions.o - obj-$(CONFIG_IRQSOFF_TRACER) += trace_irqsoff.o - obj-$(CONFIG_PREEMPT_TRACER) += trace_irqsoff.o - obj-$(CONFIG_SCHED_TRACER) += trace_sched_wakeup.o -+obj-$(CONFIG_INTERRUPT_OFF_HIST) += latency_hist.o -+obj-$(CONFIG_PREEMPT_OFF_HIST) += latency_hist.o -+obj-$(CONFIG_WAKEUP_LATENCY_HIST) += latency_hist.o -+obj-$(CONFIG_MISSED_TIMER_OFFSETS_HIST) += latency_hist.o - obj-$(CONFIG_NOP_TRACER) += trace_nop.o - obj-$(CONFIG_STACK_TRACER) += trace_stack.o - obj-$(CONFIG_MMIOTRACE) += trace_mmiotrace.o -diff --git a/kernel/trace/latency_hist.c b/kernel/trace/latency_hist.c -new file mode 100644 -index 0000000..7f6ee70 ---- /dev/null -+++ b/kernel/trace/latency_hist.c -@@ -0,0 +1,1178 @@ -+/* -+ * kernel/trace/latency_hist.c -+ * -+ * Add support for histograms of preemption-off latency and -+ * interrupt-off latency and wakeup latency, it depends on -+ * Real-Time Preemption Support. -+ * -+ * Copyright (C) 2005 MontaVista Software, Inc. -+ * Yi Yang <yyang@ch.mvista.com> -+ * -+ * Converted to work with the new latency tracer. -+ * Copyright (C) 2008 Red Hat, Inc. -+ * Steven Rostedt <srostedt@redhat.com> -+ * -+ */ -+#include <linux/module.h> -+#include <linux/debugfs.h> -+#include <linux/seq_file.h> -+#include <linux/percpu.h> -+#include <linux/kallsyms.h> -+#include <linux/uaccess.h> -+#include <linux/sched.h> -+#include <linux/sched/rt.h> -+#include <linux/slab.h> -+#include <linux/atomic.h> -+#include <asm/div64.h> -+ -+#include "trace.h" -+#include <trace/events/sched.h> -+ -+#define NSECS_PER_USECS 1000L -+ -+#define CREATE_TRACE_POINTS -+#include <trace/events/hist.h> -+ -+enum { -+ IRQSOFF_LATENCY = 0, -+ PREEMPTOFF_LATENCY, -+ PREEMPTIRQSOFF_LATENCY, -+ WAKEUP_LATENCY, -+ WAKEUP_LATENCY_SHAREDPRIO, -+ MISSED_TIMER_OFFSETS, -+ TIMERANDWAKEUP_LATENCY, -+ MAX_LATENCY_TYPE, -+}; -+ -+#define MAX_ENTRY_NUM 10240 -+ -+struct hist_data { -+ atomic_t hist_mode; /* 0 log, 1 don't log */ -+ long offset; /* set it to MAX_ENTRY_NUM/2 for a bipolar scale */ -+ long min_lat; -+ long max_lat; -+ unsigned long long below_hist_bound_samples; -+ unsigned long long above_hist_bound_samples; -+ long long accumulate_lat; -+ unsigned long long total_samples; -+ unsigned long long hist_array[MAX_ENTRY_NUM]; -+}; -+ -+struct enable_data { -+ int latency_type; -+ int enabled; -+}; -+ -+static char *latency_hist_dir_root = "latency_hist"; -+ -+#ifdef CONFIG_INTERRUPT_OFF_HIST -+static DEFINE_PER_CPU(struct hist_data, irqsoff_hist); -+static char *irqsoff_hist_dir = "irqsoff"; -+static DEFINE_PER_CPU(cycles_t, hist_irqsoff_start); -+static DEFINE_PER_CPU(int, hist_irqsoff_counting); -+#endif -+ -+#ifdef CONFIG_PREEMPT_OFF_HIST -+static DEFINE_PER_CPU(struct hist_data, preemptoff_hist); -+static char *preemptoff_hist_dir = "preemptoff"; -+static DEFINE_PER_CPU(cycles_t, hist_preemptoff_start); -+static DEFINE_PER_CPU(int, hist_preemptoff_counting); -+#endif -+ -+#if defined(CONFIG_PREEMPT_OFF_HIST) && defined(CONFIG_INTERRUPT_OFF_HIST) -+static DEFINE_PER_CPU(struct hist_data, preemptirqsoff_hist); -+static char *preemptirqsoff_hist_dir = "preemptirqsoff"; -+static DEFINE_PER_CPU(cycles_t, hist_preemptirqsoff_start); -+static DEFINE_PER_CPU(int, hist_preemptirqsoff_counting); -+#endif -+ -+#if defined(CONFIG_PREEMPT_OFF_HIST) || defined(CONFIG_INTERRUPT_OFF_HIST) -+static notrace void probe_preemptirqsoff_hist(void *v, int reason, int start); -+static struct enable_data preemptirqsoff_enabled_data = { -+ .latency_type = PREEMPTIRQSOFF_LATENCY, -+ .enabled = 0, -+}; -+#endif -+ -+#if defined(CONFIG_WAKEUP_LATENCY_HIST) || \ -+ defined(CONFIG_MISSED_TIMER_OFFSETS_HIST) -+struct maxlatproc_data { -+ char comm[FIELD_SIZEOF(struct task_struct, comm)]; -+ char current_comm[FIELD_SIZEOF(struct task_struct, comm)]; -+ int pid; -+ int current_pid; -+ int prio; -+ int current_prio; -+ long latency; -+ long timeroffset; -+ cycle_t timestamp; -+}; -+#endif -+ -+#ifdef CONFIG_WAKEUP_LATENCY_HIST -+static DEFINE_PER_CPU(struct hist_data, wakeup_latency_hist); -+static DEFINE_PER_CPU(struct hist_data, wakeup_latency_hist_sharedprio); -+static char *wakeup_latency_hist_dir = "wakeup"; -+static char *wakeup_latency_hist_dir_sharedprio = "sharedprio"; -+static notrace void probe_wakeup_latency_hist_start(void *v, -+ struct task_struct *p); -+static notrace void probe_wakeup_latency_hist_stop(void *v, -+ bool preempt, struct task_struct *prev, struct task_struct *next); -+static notrace void probe_sched_migrate_task(void *, -+ struct task_struct *task, int cpu); -+static struct enable_data wakeup_latency_enabled_data = { -+ .latency_type = WAKEUP_LATENCY, -+ .enabled = 0, -+}; -+static DEFINE_PER_CPU(struct maxlatproc_data, wakeup_maxlatproc); -+static DEFINE_PER_CPU(struct maxlatproc_data, wakeup_maxlatproc_sharedprio); -+static DEFINE_PER_CPU(struct task_struct *, wakeup_task); -+static DEFINE_PER_CPU(int, wakeup_sharedprio); -+static unsigned long wakeup_pid; -+#endif -+ -+#ifdef CONFIG_MISSED_TIMER_OFFSETS_HIST -+static DEFINE_PER_CPU(struct hist_data, missed_timer_offsets); -+static char *missed_timer_offsets_dir = "missed_timer_offsets"; -+static notrace void probe_hrtimer_interrupt(void *v, int cpu, -+ long long offset, struct task_struct *curr, struct task_struct *task); -+static struct enable_data missed_timer_offsets_enabled_data = { -+ .latency_type = MISSED_TIMER_OFFSETS, -+ .enabled = 0, -+}; -+static DEFINE_PER_CPU(struct maxlatproc_data, missed_timer_offsets_maxlatproc); -+static unsigned long missed_timer_offsets_pid; -+#endif -+ -+#if defined(CONFIG_WAKEUP_LATENCY_HIST) && \ -+ defined(CONFIG_MISSED_TIMER_OFFSETS_HIST) -+static DEFINE_PER_CPU(struct hist_data, timerandwakeup_latency_hist); -+static char *timerandwakeup_latency_hist_dir = "timerandwakeup"; -+static struct enable_data timerandwakeup_enabled_data = { -+ .latency_type = TIMERANDWAKEUP_LATENCY, -+ .enabled = 0, -+}; -+static DEFINE_PER_CPU(struct maxlatproc_data, timerandwakeup_maxlatproc); -+#endif -+ -+void notrace latency_hist(int latency_type, int cpu, long latency, -+ long timeroffset, cycle_t stop, -+ struct task_struct *p) -+{ -+ struct hist_data *my_hist; -+#if defined(CONFIG_WAKEUP_LATENCY_HIST) || \ -+ defined(CONFIG_MISSED_TIMER_OFFSETS_HIST) -+ struct maxlatproc_data *mp = NULL; -+#endif -+ -+ if (!cpu_possible(cpu) || latency_type < 0 || -+ latency_type >= MAX_LATENCY_TYPE) -+ return; -+ -+ switch (latency_type) { -+#ifdef CONFIG_INTERRUPT_OFF_HIST -+ case IRQSOFF_LATENCY: -+ my_hist = &per_cpu(irqsoff_hist, cpu); -+ break; -+#endif -+#ifdef CONFIG_PREEMPT_OFF_HIST -+ case PREEMPTOFF_LATENCY: -+ my_hist = &per_cpu(preemptoff_hist, cpu); -+ break; -+#endif -+#if defined(CONFIG_PREEMPT_OFF_HIST) && defined(CONFIG_INTERRUPT_OFF_HIST) -+ case PREEMPTIRQSOFF_LATENCY: -+ my_hist = &per_cpu(preemptirqsoff_hist, cpu); -+ break; -+#endif -+#ifdef CONFIG_WAKEUP_LATENCY_HIST -+ case WAKEUP_LATENCY: -+ my_hist = &per_cpu(wakeup_latency_hist, cpu); -+ mp = &per_cpu(wakeup_maxlatproc, cpu); -+ break; -+ case WAKEUP_LATENCY_SHAREDPRIO: -+ my_hist = &per_cpu(wakeup_latency_hist_sharedprio, cpu); -+ mp = &per_cpu(wakeup_maxlatproc_sharedprio, cpu); -+ break; -+#endif -+#ifdef CONFIG_MISSED_TIMER_OFFSETS_HIST -+ case MISSED_TIMER_OFFSETS: -+ my_hist = &per_cpu(missed_timer_offsets, cpu); -+ mp = &per_cpu(missed_timer_offsets_maxlatproc, cpu); -+ break; -+#endif -+#if defined(CONFIG_WAKEUP_LATENCY_HIST) && \ -+ defined(CONFIG_MISSED_TIMER_OFFSETS_HIST) -+ case TIMERANDWAKEUP_LATENCY: -+ my_hist = &per_cpu(timerandwakeup_latency_hist, cpu); -+ mp = &per_cpu(timerandwakeup_maxlatproc, cpu); -+ break; -+#endif -+ -+ default: -+ return; -+ } -+ -+ latency += my_hist->offset; -+ -+ if (atomic_read(&my_hist->hist_mode) == 0) -+ return; -+ -+ if (latency < 0 || latency >= MAX_ENTRY_NUM) { -+ if (latency < 0) -+ my_hist->below_hist_bound_samples++; -+ else -+ my_hist->above_hist_bound_samples++; -+ } else -+ my_hist->hist_array[latency]++; -+ -+ if (unlikely(latency > my_hist->max_lat || -+ my_hist->min_lat == LONG_MAX)) { -+#if defined(CONFIG_WAKEUP_LATENCY_HIST) || \ -+ defined(CONFIG_MISSED_TIMER_OFFSETS_HIST) -+ if (latency_type == WAKEUP_LATENCY || -+ latency_type == WAKEUP_LATENCY_SHAREDPRIO || -+ latency_type == MISSED_TIMER_OFFSETS || -+ latency_type == TIMERANDWAKEUP_LATENCY) { -+ strncpy(mp->comm, p->comm, sizeof(mp->comm)); -+ strncpy(mp->current_comm, current->comm, -+ sizeof(mp->current_comm)); -+ mp->pid = task_pid_nr(p); -+ mp->current_pid = task_pid_nr(current); -+ mp->prio = p->prio; -+ mp->current_prio = current->prio; -+ mp->latency = latency; -+ mp->timeroffset = timeroffset; -+ mp->timestamp = stop; -+ } -+#endif -+ my_hist->max_lat = latency; -+ } -+ if (unlikely(latency < my_hist->min_lat)) -+ my_hist->min_lat = latency; -+ my_hist->total_samples++; -+ my_hist->accumulate_lat += latency; -+} -+ -+static void *l_start(struct seq_file *m, loff_t *pos) -+{ -+ loff_t *index_ptr = NULL; -+ loff_t index = *pos; -+ struct hist_data *my_hist = m->private; -+ -+ if (index == 0) { -+ char minstr[32], avgstr[32], maxstr[32]; -+ -+ atomic_dec(&my_hist->hist_mode); -+ -+ if (likely(my_hist->total_samples)) { -+ long avg = (long) div64_s64(my_hist->accumulate_lat, -+ my_hist->total_samples); -+ snprintf(minstr, sizeof(minstr), "%ld", -+ my_hist->min_lat - my_hist->offset); -+ snprintf(avgstr, sizeof(avgstr), "%ld", -+ avg - my_hist->offset); -+ snprintf(maxstr, sizeof(maxstr), "%ld", -+ my_hist->max_lat - my_hist->offset); -+ } else { -+ strcpy(minstr, "<undef>"); -+ strcpy(avgstr, minstr); -+ strcpy(maxstr, minstr); -+ } -+ -+ seq_printf(m, "#Minimum latency: %s microseconds\n" -+ "#Average latency: %s microseconds\n" -+ "#Maximum latency: %s microseconds\n" -+ "#Total samples: %llu\n" -+ "#There are %llu samples lower than %ld" -+ " microseconds.\n" -+ "#There are %llu samples greater or equal" -+ " than %ld microseconds.\n" -+ "#usecs\t%16s\n", -+ minstr, avgstr, maxstr, -+ my_hist->total_samples, -+ my_hist->below_hist_bound_samples, -+ -my_hist->offset, -+ my_hist->above_hist_bound_samples, -+ MAX_ENTRY_NUM - my_hist->offset, -+ "samples"); -+ } -+ if (index < MAX_ENTRY_NUM) { -+ index_ptr = kmalloc(sizeof(loff_t), GFP_KERNEL); -+ if (index_ptr) -+ *index_ptr = index; -+ } -+ -+ return index_ptr; -+} -+ -+static void *l_next(struct seq_file *m, void *p, loff_t *pos) -+{ -+ loff_t *index_ptr = p; -+ struct hist_data *my_hist = m->private; -+ -+ if (++*pos >= MAX_ENTRY_NUM) { -+ atomic_inc(&my_hist->hist_mode); -+ return NULL; -+ } -+ *index_ptr = *pos; -+ return index_ptr; -+} -+ -+static void l_stop(struct seq_file *m, void *p) -+{ -+ kfree(p); -+} -+ -+static int l_show(struct seq_file *m, void *p) -+{ -+ int index = *(loff_t *) p; -+ struct hist_data *my_hist = m->private; -+ -+ seq_printf(m, "%6ld\t%16llu\n", index - my_hist->offset, -+ my_hist->hist_array[index]); -+ return 0; -+} -+ -+static const struct seq_operations latency_hist_seq_op = { -+ .start = l_start, -+ .next = l_next, -+ .stop = l_stop, -+ .show = l_show -+}; -+ -+static int latency_hist_open(struct inode *inode, struct file *file) -+{ -+ int ret; -+ -+ ret = seq_open(file, &latency_hist_seq_op); -+ if (!ret) { -+ struct seq_file *seq = file->private_data; -+ seq->private = inode->i_private; -+ } -+ return ret; -+} -+ -+static const struct file_operations latency_hist_fops = { -+ .open = latency_hist_open, -+ .read = seq_read, -+ .llseek = seq_lseek, -+ .release = seq_release, -+}; -+ -+#if defined(CONFIG_WAKEUP_LATENCY_HIST) || \ -+ defined(CONFIG_MISSED_TIMER_OFFSETS_HIST) -+static void clear_maxlatprocdata(struct maxlatproc_data *mp) -+{ -+ mp->comm[0] = mp->current_comm[0] = '\0'; -+ mp->prio = mp->current_prio = mp->pid = mp->current_pid = -+ mp->latency = mp->timeroffset = -1; -+ mp->timestamp = 0; -+} -+#endif -+ -+static void hist_reset(struct hist_data *hist) -+{ -+ atomic_dec(&hist->hist_mode); -+ -+ memset(hist->hist_array, 0, sizeof(hist->hist_array)); -+ hist->below_hist_bound_samples = 0ULL; -+ hist->above_hist_bound_samples = 0ULL; -+ hist->min_lat = LONG_MAX; -+ hist->max_lat = LONG_MIN; -+ hist->total_samples = 0ULL; -+ hist->accumulate_lat = 0LL; -+ -+ atomic_inc(&hist->hist_mode); -+} -+ -+static ssize_t -+latency_hist_reset(struct file *file, const char __user *a, -+ size_t size, loff_t *off) -+{ -+ int cpu; -+ struct hist_data *hist = NULL; -+#if defined(CONFIG_WAKEUP_LATENCY_HIST) || \ -+ defined(CONFIG_MISSED_TIMER_OFFSETS_HIST) -+ struct maxlatproc_data *mp = NULL; -+#endif -+ off_t latency_type = (off_t) file->private_data; -+ -+ for_each_online_cpu(cpu) { -+ -+ switch (latency_type) { -+#ifdef CONFIG_PREEMPT_OFF_HIST -+ case PREEMPTOFF_LATENCY: -+ hist = &per_cpu(preemptoff_hist, cpu); -+ break; -+#endif -+#ifdef CONFIG_INTERRUPT_OFF_HIST -+ case IRQSOFF_LATENCY: -+ hist = &per_cpu(irqsoff_hist, cpu); -+ break; -+#endif -+#if defined(CONFIG_INTERRUPT_OFF_HIST) && defined(CONFIG_PREEMPT_OFF_HIST) -+ case PREEMPTIRQSOFF_LATENCY: -+ hist = &per_cpu(preemptirqsoff_hist, cpu); -+ break; -+#endif -+#ifdef CONFIG_WAKEUP_LATENCY_HIST -+ case WAKEUP_LATENCY: -+ hist = &per_cpu(wakeup_latency_hist, cpu); -+ mp = &per_cpu(wakeup_maxlatproc, cpu); -+ break; -+ case WAKEUP_LATENCY_SHAREDPRIO: -+ hist = &per_cpu(wakeup_latency_hist_sharedprio, cpu); -+ mp = &per_cpu(wakeup_maxlatproc_sharedprio, cpu); -+ break; -+#endif -+#ifdef CONFIG_MISSED_TIMER_OFFSETS_HIST -+ case MISSED_TIMER_OFFSETS: -+ hist = &per_cpu(missed_timer_offsets, cpu); -+ mp = &per_cpu(missed_timer_offsets_maxlatproc, cpu); -+ break; -+#endif -+#if defined(CONFIG_WAKEUP_LATENCY_HIST) && \ -+ defined(CONFIG_MISSED_TIMER_OFFSETS_HIST) -+ case TIMERANDWAKEUP_LATENCY: -+ hist = &per_cpu(timerandwakeup_latency_hist, cpu); -+ mp = &per_cpu(timerandwakeup_maxlatproc, cpu); -+ break; -+#endif -+ } -+ -+ hist_reset(hist); -+#if defined(CONFIG_WAKEUP_LATENCY_HIST) || \ -+ defined(CONFIG_MISSED_TIMER_OFFSETS_HIST) -+ if (latency_type == WAKEUP_LATENCY || -+ latency_type == WAKEUP_LATENCY_SHAREDPRIO || -+ latency_type == MISSED_TIMER_OFFSETS || -+ latency_type == TIMERANDWAKEUP_LATENCY) -+ clear_maxlatprocdata(mp); -+#endif -+ } -+ -+ return size; -+} -+ -+#if defined(CONFIG_WAKEUP_LATENCY_HIST) || \ -+ defined(CONFIG_MISSED_TIMER_OFFSETS_HIST) -+static ssize_t -+show_pid(struct file *file, char __user *ubuf, size_t cnt, loff_t *ppos) -+{ -+ char buf[64]; -+ int r; -+ unsigned long *this_pid = file->private_data; -+ -+ r = snprintf(buf, sizeof(buf), "%lu\n", *this_pid); -+ return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); -+} -+ -+static ssize_t do_pid(struct file *file, const char __user *ubuf, -+ size_t cnt, loff_t *ppos) -+{ -+ char buf[64]; -+ unsigned long pid; -+ unsigned long *this_pid = file->private_data; -+ -+ if (cnt >= sizeof(buf)) -+ return -EINVAL; -+ -+ if (copy_from_user(&buf, ubuf, cnt)) -+ return -EFAULT; -+ -+ buf[cnt] = '\0'; -+ -+ if (kstrtoul(buf, 10, &pid)) -+ return -EINVAL; -+ -+ *this_pid = pid; -+ -+ return cnt; -+} -+#endif -+ -+#if defined(CONFIG_WAKEUP_LATENCY_HIST) || \ -+ defined(CONFIG_MISSED_TIMER_OFFSETS_HIST) -+static ssize_t -+show_maxlatproc(struct file *file, char __user *ubuf, size_t cnt, loff_t *ppos) -+{ -+ int r; -+ struct maxlatproc_data *mp = file->private_data; -+ int strmaxlen = (TASK_COMM_LEN * 2) + (8 * 8); -+ unsigned long long t; -+ unsigned long usecs, secs; -+ char *buf; -+ -+ if (mp->pid == -1 || mp->current_pid == -1) { -+ buf = "(none)\n"; -+ return simple_read_from_buffer(ubuf, cnt, ppos, buf, -+ strlen(buf)); -+ } -+ -+ buf = kmalloc(strmaxlen, GFP_KERNEL); -+ if (buf == NULL) -+ return -ENOMEM; -+ -+ t = ns2usecs(mp->timestamp); -+ usecs = do_div(t, USEC_PER_SEC); -+ secs = (unsigned long) t; -+ r = snprintf(buf, strmaxlen, -+ "%d %d %ld (%ld) %s <- %d %d %s %lu.%06lu\n", mp->pid, -+ MAX_RT_PRIO-1 - mp->prio, mp->latency, mp->timeroffset, mp->comm, -+ mp->current_pid, MAX_RT_PRIO-1 - mp->current_prio, mp->current_comm, -+ secs, usecs); -+ r = simple_read_from_buffer(ubuf, cnt, ppos, buf, r); -+ kfree(buf); -+ return r; -+} -+#endif -+ -+static ssize_t -+show_enable(struct file *file, char __user *ubuf, size_t cnt, loff_t *ppos) -+{ -+ char buf[64]; -+ struct enable_data *ed = file->private_data; -+ int r; -+ -+ r = snprintf(buf, sizeof(buf), "%d\n", ed->enabled); -+ return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); -+} -+ -+static ssize_t -+do_enable(struct file *file, const char __user *ubuf, size_t cnt, loff_t *ppos) -+{ -+ char buf[64]; -+ long enable; -+ struct enable_data *ed = file->private_data; -+ -+ if (cnt >= sizeof(buf)) -+ return -EINVAL; -+ -+ if (copy_from_user(&buf, ubuf, cnt)) -+ return -EFAULT; -+ -+ buf[cnt] = 0; -+ -+ if (kstrtoul(buf, 10, &enable)) -+ return -EINVAL; -+ -+ if ((enable && ed->enabled) || (!enable && !ed->enabled)) -+ return cnt; -+ -+ if (enable) { -+ int ret; -+ -+ switch (ed->latency_type) { -+#if defined(CONFIG_INTERRUPT_OFF_HIST) || defined(CONFIG_PREEMPT_OFF_HIST) -+ case PREEMPTIRQSOFF_LATENCY: -+ ret = register_trace_preemptirqsoff_hist( -+ probe_preemptirqsoff_hist, NULL); -+ if (ret) { -+ pr_info("wakeup trace: Couldn't assign " -+ "probe_preemptirqsoff_hist " -+ "to trace_preemptirqsoff_hist\n"); -+ return ret; -+ } -+ break; -+#endif -+#ifdef CONFIG_WAKEUP_LATENCY_HIST -+ case WAKEUP_LATENCY: -+ ret = register_trace_sched_wakeup( -+ probe_wakeup_latency_hist_start, NULL); -+ if (ret) { -+ pr_info("wakeup trace: Couldn't assign " -+ "probe_wakeup_latency_hist_start " -+ "to trace_sched_wakeup\n"); -+ return ret; -+ } -+ ret = register_trace_sched_wakeup_new( -+ probe_wakeup_latency_hist_start, NULL); -+ if (ret) { -+ pr_info("wakeup trace: Couldn't assign " -+ "probe_wakeup_latency_hist_start " -+ "to trace_sched_wakeup_new\n"); -+ unregister_trace_sched_wakeup( -+ probe_wakeup_latency_hist_start, NULL); -+ return ret; -+ } -+ ret = register_trace_sched_switch( -+ probe_wakeup_latency_hist_stop, NULL); -+ if (ret) { -+ pr_info("wakeup trace: Couldn't assign " -+ "probe_wakeup_latency_hist_stop " -+ "to trace_sched_switch\n"); -+ unregister_trace_sched_wakeup( -+ probe_wakeup_latency_hist_start, NULL); -+ unregister_trace_sched_wakeup_new( -+ probe_wakeup_latency_hist_start, NULL); -+ return ret; -+ } -+ ret = register_trace_sched_migrate_task( -+ probe_sched_migrate_task, NULL); -+ if (ret) { -+ pr_info("wakeup trace: Couldn't assign " -+ "probe_sched_migrate_task " -+ "to trace_sched_migrate_task\n"); -+ unregister_trace_sched_wakeup( -+ probe_wakeup_latency_hist_start, NULL); -+ unregister_trace_sched_wakeup_new( -+ probe_wakeup_latency_hist_start, NULL); -+ unregister_trace_sched_switch( -+ probe_wakeup_latency_hist_stop, NULL); -+ return ret; -+ } -+ break; -+#endif -+#ifdef CONFIG_MISSED_TIMER_OFFSETS_HIST -+ case MISSED_TIMER_OFFSETS: -+ ret = register_trace_hrtimer_interrupt( -+ probe_hrtimer_interrupt, NULL); -+ if (ret) { -+ pr_info("wakeup trace: Couldn't assign " -+ "probe_hrtimer_interrupt " -+ "to trace_hrtimer_interrupt\n"); -+ return ret; -+ } -+ break; -+#endif -+#if defined(CONFIG_WAKEUP_LATENCY_HIST) && \ -+ defined(CONFIG_MISSED_TIMER_OFFSETS_HIST) -+ case TIMERANDWAKEUP_LATENCY: -+ if (!wakeup_latency_enabled_data.enabled || -+ !missed_timer_offsets_enabled_data.enabled) -+ return -EINVAL; -+ break; -+#endif -+ default: -+ break; -+ } -+ } else { -+ switch (ed->latency_type) { -+#if defined(CONFIG_INTERRUPT_OFF_HIST) || defined(CONFIG_PREEMPT_OFF_HIST) -+ case PREEMPTIRQSOFF_LATENCY: -+ { -+ int cpu; -+ -+ unregister_trace_preemptirqsoff_hist( -+ probe_preemptirqsoff_hist, NULL); -+ for_each_online_cpu(cpu) { -+#ifdef CONFIG_INTERRUPT_OFF_HIST -+ per_cpu(hist_irqsoff_counting, -+ cpu) = 0; -+#endif -+#ifdef CONFIG_PREEMPT_OFF_HIST -+ per_cpu(hist_preemptoff_counting, -+ cpu) = 0; -+#endif -+#if defined(CONFIG_INTERRUPT_OFF_HIST) && defined(CONFIG_PREEMPT_OFF_HIST) -+ per_cpu(hist_preemptirqsoff_counting, -+ cpu) = 0; -+#endif -+ } -+ } -+ break; -+#endif -+#ifdef CONFIG_WAKEUP_LATENCY_HIST -+ case WAKEUP_LATENCY: -+ { -+ int cpu; -+ -+ unregister_trace_sched_wakeup( -+ probe_wakeup_latency_hist_start, NULL); -+ unregister_trace_sched_wakeup_new( -+ probe_wakeup_latency_hist_start, NULL); -+ unregister_trace_sched_switch( -+ probe_wakeup_latency_hist_stop, NULL); -+ unregister_trace_sched_migrate_task( -+ probe_sched_migrate_task, NULL); -+ -+ for_each_online_cpu(cpu) { -+ per_cpu(wakeup_task, cpu) = NULL; -+ per_cpu(wakeup_sharedprio, cpu) = 0; -+ } -+ } -+#ifdef CONFIG_MISSED_TIMER_OFFSETS_HIST -+ timerandwakeup_enabled_data.enabled = 0; -+#endif -+ break; -+#endif -+#ifdef CONFIG_MISSED_TIMER_OFFSETS_HIST -+ case MISSED_TIMER_OFFSETS: -+ unregister_trace_hrtimer_interrupt( -+ probe_hrtimer_interrupt, NULL); -+#ifdef CONFIG_WAKEUP_LATENCY_HIST -+ timerandwakeup_enabled_data.enabled = 0; -+#endif -+ break; -+#endif -+ default: -+ break; -+ } -+ } -+ ed->enabled = enable; -+ return cnt; -+} -+ -+static const struct file_operations latency_hist_reset_fops = { -+ .open = tracing_open_generic, -+ .write = latency_hist_reset, -+}; -+ -+static const struct file_operations enable_fops = { -+ .open = tracing_open_generic, -+ .read = show_enable, -+ .write = do_enable, -+}; -+ -+#if defined(CONFIG_WAKEUP_LATENCY_HIST) || \ -+ defined(CONFIG_MISSED_TIMER_OFFSETS_HIST) -+static const struct file_operations pid_fops = { -+ .open = tracing_open_generic, -+ .read = show_pid, -+ .write = do_pid, -+}; -+ -+static const struct file_operations maxlatproc_fops = { -+ .open = tracing_open_generic, -+ .read = show_maxlatproc, -+}; -+#endif -+ -+#if defined(CONFIG_INTERRUPT_OFF_HIST) || defined(CONFIG_PREEMPT_OFF_HIST) -+static notrace void probe_preemptirqsoff_hist(void *v, int reason, -+ int starthist) -+{ -+ int cpu = raw_smp_processor_id(); -+ int time_set = 0; -+ -+ if (starthist) { -+ cycle_t uninitialized_var(start); -+ -+ if (!preempt_count() && !irqs_disabled()) -+ return; -+ -+#ifdef CONFIG_INTERRUPT_OFF_HIST -+ if ((reason == IRQS_OFF || reason == TRACE_START) && -+ !per_cpu(hist_irqsoff_counting, cpu)) { -+ per_cpu(hist_irqsoff_counting, cpu) = 1; -+ start = ftrace_now(cpu); -+ time_set++; -+ per_cpu(hist_irqsoff_start, cpu) = start; -+ } -+#endif -+ -+#ifdef CONFIG_PREEMPT_OFF_HIST -+ if ((reason == PREEMPT_OFF || reason == TRACE_START) && -+ !per_cpu(hist_preemptoff_counting, cpu)) { -+ per_cpu(hist_preemptoff_counting, cpu) = 1; -+ if (!(time_set++)) -+ start = ftrace_now(cpu); -+ per_cpu(hist_preemptoff_start, cpu) = start; -+ } -+#endif -+ -+#if defined(CONFIG_INTERRUPT_OFF_HIST) && defined(CONFIG_PREEMPT_OFF_HIST) -+ if (per_cpu(hist_irqsoff_counting, cpu) && -+ per_cpu(hist_preemptoff_counting, cpu) && -+ !per_cpu(hist_preemptirqsoff_counting, cpu)) { -+ per_cpu(hist_preemptirqsoff_counting, cpu) = 1; -+ if (!time_set) -+ start = ftrace_now(cpu); -+ per_cpu(hist_preemptirqsoff_start, cpu) = start; -+ } -+#endif -+ } else { -+ cycle_t uninitialized_var(stop); -+ -+#ifdef CONFIG_INTERRUPT_OFF_HIST -+ if ((reason == IRQS_ON || reason == TRACE_STOP) && -+ per_cpu(hist_irqsoff_counting, cpu)) { -+ cycle_t start = per_cpu(hist_irqsoff_start, cpu); -+ -+ stop = ftrace_now(cpu); -+ time_set++; -+ if (start) { -+ long latency = ((long) (stop - start)) / -+ NSECS_PER_USECS; -+ -+ latency_hist(IRQSOFF_LATENCY, cpu, latency, 0, -+ stop, NULL); -+ } -+ per_cpu(hist_irqsoff_counting, cpu) = 0; -+ } -+#endif -+ -+#ifdef CONFIG_PREEMPT_OFF_HIST -+ if ((reason == PREEMPT_ON || reason == TRACE_STOP) && -+ per_cpu(hist_preemptoff_counting, cpu)) { -+ cycle_t start = per_cpu(hist_preemptoff_start, cpu); -+ -+ if (!(time_set++)) -+ stop = ftrace_now(cpu); -+ if (start) { -+ long latency = ((long) (stop - start)) / -+ NSECS_PER_USECS; -+ -+ latency_hist(PREEMPTOFF_LATENCY, cpu, latency, -+ 0, stop, NULL); -+ } -+ per_cpu(hist_preemptoff_counting, cpu) = 0; -+ } -+#endif -+ -+#if defined(CONFIG_INTERRUPT_OFF_HIST) && defined(CONFIG_PREEMPT_OFF_HIST) -+ if ((!per_cpu(hist_irqsoff_counting, cpu) || -+ !per_cpu(hist_preemptoff_counting, cpu)) && -+ per_cpu(hist_preemptirqsoff_counting, cpu)) { -+ cycle_t start = per_cpu(hist_preemptirqsoff_start, cpu); -+ -+ if (!time_set) -+ stop = ftrace_now(cpu); -+ if (start) { -+ long latency = ((long) (stop - start)) / -+ NSECS_PER_USECS; -+ -+ latency_hist(PREEMPTIRQSOFF_LATENCY, cpu, -+ latency, 0, stop, NULL); -+ } -+ per_cpu(hist_preemptirqsoff_counting, cpu) = 0; -+ } -+#endif -+ } -+} -+#endif -+ -+#ifdef CONFIG_WAKEUP_LATENCY_HIST -+static DEFINE_RAW_SPINLOCK(wakeup_lock); -+static notrace void probe_sched_migrate_task(void *v, struct task_struct *task, -+ int cpu) -+{ -+ int old_cpu = task_cpu(task); -+ -+ if (cpu != old_cpu) { -+ unsigned long flags; -+ struct task_struct *cpu_wakeup_task; -+ -+ raw_spin_lock_irqsave(&wakeup_lock, flags); -+ -+ cpu_wakeup_task = per_cpu(wakeup_task, old_cpu); -+ if (task == cpu_wakeup_task) { -+ put_task_struct(cpu_wakeup_task); -+ per_cpu(wakeup_task, old_cpu) = NULL; -+ cpu_wakeup_task = per_cpu(wakeup_task, cpu) = task; -+ get_task_struct(cpu_wakeup_task); -+ } -+ -+ raw_spin_unlock_irqrestore(&wakeup_lock, flags); -+ } -+} -+ -+static notrace void probe_wakeup_latency_hist_start(void *v, -+ struct task_struct *p) -+{ -+ unsigned long flags; -+ struct task_struct *curr = current; -+ int cpu = task_cpu(p); -+ struct task_struct *cpu_wakeup_task; -+ -+ raw_spin_lock_irqsave(&wakeup_lock, flags); -+ -+ cpu_wakeup_task = per_cpu(wakeup_task, cpu); -+ -+ if (wakeup_pid) { -+ if ((cpu_wakeup_task && p->prio == cpu_wakeup_task->prio) || -+ p->prio == curr->prio) -+ per_cpu(wakeup_sharedprio, cpu) = 1; -+ if (likely(wakeup_pid != task_pid_nr(p))) -+ goto out; -+ } else { -+ if (likely(!rt_task(p)) || -+ (cpu_wakeup_task && p->prio > cpu_wakeup_task->prio) || -+ p->prio > curr->prio) -+ goto out; -+ if ((cpu_wakeup_task && p->prio == cpu_wakeup_task->prio) || -+ p->prio == curr->prio) -+ per_cpu(wakeup_sharedprio, cpu) = 1; -+ } -+ -+ if (cpu_wakeup_task) -+ put_task_struct(cpu_wakeup_task); -+ cpu_wakeup_task = per_cpu(wakeup_task, cpu) = p; -+ get_task_struct(cpu_wakeup_task); -+ cpu_wakeup_task->preempt_timestamp_hist = -+ ftrace_now(raw_smp_processor_id()); -+out: -+ raw_spin_unlock_irqrestore(&wakeup_lock, flags); -+} -+ -+static notrace void probe_wakeup_latency_hist_stop(void *v, -+ bool preempt, struct task_struct *prev, struct task_struct *next) -+{ -+ unsigned long flags; -+ int cpu = task_cpu(next); -+ long latency; -+ cycle_t stop; -+ struct task_struct *cpu_wakeup_task; -+ -+ raw_spin_lock_irqsave(&wakeup_lock, flags); -+ -+ cpu_wakeup_task = per_cpu(wakeup_task, cpu); -+ -+ if (cpu_wakeup_task == NULL) -+ goto out; -+ -+ /* Already running? */ -+ if (unlikely(current == cpu_wakeup_task)) -+ goto out_reset; -+ -+ if (next != cpu_wakeup_task) { -+ if (next->prio < cpu_wakeup_task->prio) -+ goto out_reset; -+ -+ if (next->prio == cpu_wakeup_task->prio) -+ per_cpu(wakeup_sharedprio, cpu) = 1; -+ -+ goto out; -+ } -+ -+ if (current->prio == cpu_wakeup_task->prio) -+ per_cpu(wakeup_sharedprio, cpu) = 1; -+ -+ /* -+ * The task we are waiting for is about to be switched to. -+ * Calculate latency and store it in histogram. -+ */ -+ stop = ftrace_now(raw_smp_processor_id()); -+ -+ latency = ((long) (stop - next->preempt_timestamp_hist)) / -+ NSECS_PER_USECS; -+ -+ if (per_cpu(wakeup_sharedprio, cpu)) { -+ latency_hist(WAKEUP_LATENCY_SHAREDPRIO, cpu, latency, 0, stop, -+ next); -+ per_cpu(wakeup_sharedprio, cpu) = 0; -+ } else { -+ latency_hist(WAKEUP_LATENCY, cpu, latency, 0, stop, next); -+#ifdef CONFIG_MISSED_TIMER_OFFSETS_HIST -+ if (timerandwakeup_enabled_data.enabled) { -+ latency_hist(TIMERANDWAKEUP_LATENCY, cpu, -+ next->timer_offset + latency, next->timer_offset, -+ stop, next); -+ } -+#endif -+ } -+ -+out_reset: -+#ifdef CONFIG_MISSED_TIMER_OFFSETS_HIST -+ next->timer_offset = 0; -+#endif -+ put_task_struct(cpu_wakeup_task); -+ per_cpu(wakeup_task, cpu) = NULL; -+out: -+ raw_spin_unlock_irqrestore(&wakeup_lock, flags); -+} -+#endif -+ -+#ifdef CONFIG_MISSED_TIMER_OFFSETS_HIST -+static notrace void probe_hrtimer_interrupt(void *v, int cpu, -+ long long latency_ns, struct task_struct *curr, -+ struct task_struct *task) -+{ -+ if (latency_ns <= 0 && task != NULL && rt_task(task) && -+ (task->prio < curr->prio || -+ (task->prio == curr->prio && -+ !cpumask_test_cpu(cpu, &task->cpus_allowed)))) { -+ long latency; -+ cycle_t now; -+ -+ if (missed_timer_offsets_pid) { -+ if (likely(missed_timer_offsets_pid != -+ task_pid_nr(task))) -+ return; -+ } -+ -+ now = ftrace_now(cpu); -+ latency = (long) div_s64(-latency_ns, NSECS_PER_USECS); -+ latency_hist(MISSED_TIMER_OFFSETS, cpu, latency, latency, now, -+ task); -+#ifdef CONFIG_WAKEUP_LATENCY_HIST -+ task->timer_offset = latency; -+#endif -+ } -+} -+#endif -+ -+static __init int latency_hist_init(void) -+{ -+ struct dentry *latency_hist_root = NULL; -+ struct dentry *dentry; -+#ifdef CONFIG_WAKEUP_LATENCY_HIST -+ struct dentry *dentry_sharedprio; -+#endif -+ struct dentry *entry; -+ struct dentry *enable_root; -+ int i = 0; -+ struct hist_data *my_hist; -+ char name[64]; -+ char *cpufmt = "CPU%d"; -+#if defined(CONFIG_WAKEUP_LATENCY_HIST) || \ -+ defined(CONFIG_MISSED_TIMER_OFFSETS_HIST) -+ char *cpufmt_maxlatproc = "max_latency-CPU%d"; -+ struct maxlatproc_data *mp = NULL; -+#endif -+ -+ dentry = tracing_init_dentry(); -+ latency_hist_root = debugfs_create_dir(latency_hist_dir_root, dentry); -+ enable_root = debugfs_create_dir("enable", latency_hist_root); -+ -+#ifdef CONFIG_INTERRUPT_OFF_HIST -+ dentry = debugfs_create_dir(irqsoff_hist_dir, latency_hist_root); -+ for_each_possible_cpu(i) { -+ sprintf(name, cpufmt, i); -+ entry = debugfs_create_file(name, 0444, dentry, -+ &per_cpu(irqsoff_hist, i), &latency_hist_fops); -+ my_hist = &per_cpu(irqsoff_hist, i); -+ atomic_set(&my_hist->hist_mode, 1); -+ my_hist->min_lat = LONG_MAX; -+ } -+ entry = debugfs_create_file("reset", 0644, dentry, -+ (void *)IRQSOFF_LATENCY, &latency_hist_reset_fops); -+#endif -+ -+#ifdef CONFIG_PREEMPT_OFF_HIST -+ dentry = debugfs_create_dir(preemptoff_hist_dir, -+ latency_hist_root); -+ for_each_possible_cpu(i) { -+ sprintf(name, cpufmt, i); -+ entry = debugfs_create_file(name, 0444, dentry, -+ &per_cpu(preemptoff_hist, i), &latency_hist_fops); -+ my_hist = &per_cpu(preemptoff_hist, i); -+ atomic_set(&my_hist->hist_mode, 1); -+ my_hist->min_lat = LONG_MAX; -+ } -+ entry = debugfs_create_file("reset", 0644, dentry, -+ (void *)PREEMPTOFF_LATENCY, &latency_hist_reset_fops); -+#endif -+ -+#if defined(CONFIG_INTERRUPT_OFF_HIST) && defined(CONFIG_PREEMPT_OFF_HIST) -+ dentry = debugfs_create_dir(preemptirqsoff_hist_dir, -+ latency_hist_root); -+ for_each_possible_cpu(i) { -+ sprintf(name, cpufmt, i); -+ entry = debugfs_create_file(name, 0444, dentry, -+ &per_cpu(preemptirqsoff_hist, i), &latency_hist_fops); -+ my_hist = &per_cpu(preemptirqsoff_hist, i); -+ atomic_set(&my_hist->hist_mode, 1); -+ my_hist->min_lat = LONG_MAX; -+ } -+ entry = debugfs_create_file("reset", 0644, dentry, -+ (void *)PREEMPTIRQSOFF_LATENCY, &latency_hist_reset_fops); -+#endif -+ -+#if defined(CONFIG_INTERRUPT_OFF_HIST) || defined(CONFIG_PREEMPT_OFF_HIST) -+ entry = debugfs_create_file("preemptirqsoff", 0644, -+ enable_root, (void *)&preemptirqsoff_enabled_data, -+ &enable_fops); -+#endif -+ -+#ifdef CONFIG_WAKEUP_LATENCY_HIST -+ dentry = debugfs_create_dir(wakeup_latency_hist_dir, -+ latency_hist_root); -+ dentry_sharedprio = debugfs_create_dir( -+ wakeup_latency_hist_dir_sharedprio, dentry); -+ for_each_possible_cpu(i) { -+ sprintf(name, cpufmt, i); -+ -+ entry = debugfs_create_file(name, 0444, dentry, -+ &per_cpu(wakeup_latency_hist, i), -+ &latency_hist_fops); -+ my_hist = &per_cpu(wakeup_latency_hist, i); -+ atomic_set(&my_hist->hist_mode, 1); -+ my_hist->min_lat = LONG_MAX; -+ -+ entry = debugfs_create_file(name, 0444, dentry_sharedprio, -+ &per_cpu(wakeup_latency_hist_sharedprio, i), -+ &latency_hist_fops); -+ my_hist = &per_cpu(wakeup_latency_hist_sharedprio, i); -+ atomic_set(&my_hist->hist_mode, 1); -+ my_hist->min_lat = LONG_MAX; -+ -+ sprintf(name, cpufmt_maxlatproc, i); -+ -+ mp = &per_cpu(wakeup_maxlatproc, i); -+ entry = debugfs_create_file(name, 0444, dentry, mp, -+ &maxlatproc_fops); -+ clear_maxlatprocdata(mp); -+ -+ mp = &per_cpu(wakeup_maxlatproc_sharedprio, i); -+ entry = debugfs_create_file(name, 0444, dentry_sharedprio, mp, -+ &maxlatproc_fops); -+ clear_maxlatprocdata(mp); -+ } -+ entry = debugfs_create_file("pid", 0644, dentry, -+ (void *)&wakeup_pid, &pid_fops); -+ entry = debugfs_create_file("reset", 0644, dentry, -+ (void *)WAKEUP_LATENCY, &latency_hist_reset_fops); -+ entry = debugfs_create_file("reset", 0644, dentry_sharedprio, -+ (void *)WAKEUP_LATENCY_SHAREDPRIO, &latency_hist_reset_fops); -+ entry = debugfs_create_file("wakeup", 0644, -+ enable_root, (void *)&wakeup_latency_enabled_data, -+ &enable_fops); -+#endif -+ -+#ifdef CONFIG_MISSED_TIMER_OFFSETS_HIST -+ dentry = debugfs_create_dir(missed_timer_offsets_dir, -+ latency_hist_root); -+ for_each_possible_cpu(i) { -+ sprintf(name, cpufmt, i); -+ entry = debugfs_create_file(name, 0444, dentry, -+ &per_cpu(missed_timer_offsets, i), &latency_hist_fops); -+ my_hist = &per_cpu(missed_timer_offsets, i); -+ atomic_set(&my_hist->hist_mode, 1); -+ my_hist->min_lat = LONG_MAX; -+ -+ sprintf(name, cpufmt_maxlatproc, i); -+ mp = &per_cpu(missed_timer_offsets_maxlatproc, i); -+ entry = debugfs_create_file(name, 0444, dentry, mp, -+ &maxlatproc_fops); -+ clear_maxlatprocdata(mp); -+ } -+ entry = debugfs_create_file("pid", 0644, dentry, -+ (void *)&missed_timer_offsets_pid, &pid_fops); -+ entry = debugfs_create_file("reset", 0644, dentry, -+ (void *)MISSED_TIMER_OFFSETS, &latency_hist_reset_fops); -+ entry = debugfs_create_file("missed_timer_offsets", 0644, -+ enable_root, (void *)&missed_timer_offsets_enabled_data, -+ &enable_fops); -+#endif -+ -+#if defined(CONFIG_WAKEUP_LATENCY_HIST) && \ -+ defined(CONFIG_MISSED_TIMER_OFFSETS_HIST) -+ dentry = debugfs_create_dir(timerandwakeup_latency_hist_dir, -+ latency_hist_root); -+ for_each_possible_cpu(i) { -+ sprintf(name, cpufmt, i); -+ entry = debugfs_create_file(name, 0444, dentry, -+ &per_cpu(timerandwakeup_latency_hist, i), -+ &latency_hist_fops); -+ my_hist = &per_cpu(timerandwakeup_latency_hist, i); -+ atomic_set(&my_hist->hist_mode, 1); -+ my_hist->min_lat = LONG_MAX; -+ -+ sprintf(name, cpufmt_maxlatproc, i); -+ mp = &per_cpu(timerandwakeup_maxlatproc, i); -+ entry = debugfs_create_file(name, 0444, dentry, mp, -+ &maxlatproc_fops); -+ clear_maxlatprocdata(mp); -+ } -+ entry = debugfs_create_file("reset", 0644, dentry, -+ (void *)TIMERANDWAKEUP_LATENCY, &latency_hist_reset_fops); -+ entry = debugfs_create_file("timerandwakeup", 0644, -+ enable_root, (void *)&timerandwakeup_enabled_data, -+ &enable_fops); -+#endif -+ return 0; -+} -+ -+device_initcall(latency_hist_init); -diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c -index a2f0b9f..3ffea48 100644 ---- a/kernel/trace/trace.c -+++ b/kernel/trace/trace.c -@@ -1657,6 +1657,7 @@ tracing_generic_entry_update(struct trace_entry *entry, unsigned long flags, - struct task_struct *tsk = current; - - entry->preempt_count = pc & 0xff; -+ entry->preempt_lazy_count = preempt_lazy_count(); - entry->pid = (tsk) ? tsk->pid : 0; - entry->flags = - #ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT -@@ -1667,8 +1668,11 @@ tracing_generic_entry_update(struct trace_entry *entry, unsigned long flags, - ((pc & NMI_MASK ) ? TRACE_FLAG_NMI : 0) | - ((pc & HARDIRQ_MASK) ? TRACE_FLAG_HARDIRQ : 0) | - ((pc & SOFTIRQ_MASK) ? TRACE_FLAG_SOFTIRQ : 0) | -- (tif_need_resched() ? TRACE_FLAG_NEED_RESCHED : 0) | -+ (tif_need_resched_now() ? TRACE_FLAG_NEED_RESCHED : 0) | -+ (need_resched_lazy() ? TRACE_FLAG_NEED_RESCHED_LAZY : 0) | - (test_preempt_need_resched() ? TRACE_FLAG_PREEMPT_RESCHED : 0); -+ -+ entry->migrate_disable = (tsk) ? __migrate_disabled(tsk) & 0xFF : 0; - } - EXPORT_SYMBOL_GPL(tracing_generic_entry_update); - -@@ -2561,14 +2565,17 @@ get_total_entries(struct trace_buffer *buf, - - static void print_lat_help_header(struct seq_file *m) - { -- seq_puts(m, "# _------=> CPU# \n" -- "# / _-----=> irqs-off \n" -- "# | / _----=> need-resched \n" -- "# || / _---=> hardirq/softirq \n" -- "# ||| / _--=> preempt-depth \n" -- "# |||| / delay \n" -- "# cmd pid ||||| time | caller \n" -- "# \\ / ||||| \\ | / \n"); -+ seq_puts(m, "# _--------=> CPU# \n" -+ "# / _-------=> irqs-off \n" -+ "# | / _------=> need-resched \n" -+ "# || / _-----=> need-resched_lazy \n" -+ "# ||| / _----=> hardirq/softirq \n" -+ "# |||| / _---=> preempt-depth \n" -+ "# ||||| / _--=> preempt-lazy-depth\n" -+ "# |||||| / _-=> migrate-disable \n" -+ "# ||||||| / delay \n" -+ "# cmd pid |||||||| time | caller \n" -+ "# \\ / |||||||| \\ | / \n"); - } - - static void print_event_info(struct trace_buffer *buf, struct seq_file *m) -@@ -2594,11 +2601,14 @@ static void print_func_help_header_irq(struct trace_buffer *buf, struct seq_file - print_event_info(buf, m); - seq_puts(m, "# _-----=> irqs-off\n" - "# / _----=> need-resched\n" -- "# | / _---=> hardirq/softirq\n" -- "# || / _--=> preempt-depth\n" -- "# ||| / delay\n" -- "# TASK-PID CPU# |||| TIMESTAMP FUNCTION\n" -- "# | | | |||| | |\n"); -+ "# |/ _-----=> need-resched_lazy\n" -+ "# || / _---=> hardirq/softirq\n" -+ "# ||| / _--=> preempt-depth\n" -+ "# |||| /_--=> preempt-lazy-depth\n" -+ "# ||||| _-=> migrate-disable \n" -+ "# ||||| / delay\n" -+ "# TASK-PID CPU# |||||| TIMESTAMP FUNCTION\n" -+ "# | | | |||||| | |\n"); - } - - void -diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h -index 3fff4ad..acb00bc 100644 ---- a/kernel/trace/trace.h -+++ b/kernel/trace/trace.h -@@ -117,6 +117,7 @@ struct kretprobe_trace_entry_head { - * NEED_RESCHED - reschedule is requested - * HARDIRQ - inside an interrupt handler - * SOFTIRQ - inside a softirq handler -+ * NEED_RESCHED_LAZY - lazy reschedule is requested - */ - enum trace_flag_type { - TRACE_FLAG_IRQS_OFF = 0x01, -@@ -126,6 +127,7 @@ enum trace_flag_type { - TRACE_FLAG_SOFTIRQ = 0x10, - TRACE_FLAG_PREEMPT_RESCHED = 0x20, - TRACE_FLAG_NMI = 0x40, -+ TRACE_FLAG_NEED_RESCHED_LAZY = 0x80, - }; - - #define TRACE_BUF_SIZE 1024 -diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c -index 6f96586..52c4fff 100644 ---- a/kernel/trace/trace_events.c -+++ b/kernel/trace/trace_events.c -@@ -188,6 +188,8 @@ static int trace_define_common_fields(void) - __common_field(unsigned char, flags); - __common_field(unsigned char, preempt_count); - __common_field(int, pid); -+ __common_field(unsigned short, migrate_disable); -+ __common_field(unsigned short, padding); - - return ret; - } -diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c -index 03cdff8..940bd10 100644 ---- a/kernel/trace/trace_irqsoff.c -+++ b/kernel/trace/trace_irqsoff.c -@@ -13,6 +13,7 @@ - #include <linux/uaccess.h> - #include <linux/module.h> - #include <linux/ftrace.h> -+#include <trace/events/hist.h> - - #include "trace.h" - -@@ -424,11 +425,13 @@ void start_critical_timings(void) - { - if (preempt_trace() || irq_trace()) - start_critical_timing(CALLER_ADDR0, CALLER_ADDR1); -+ trace_preemptirqsoff_hist_rcuidle(TRACE_START, 1); - } - EXPORT_SYMBOL_GPL(start_critical_timings); - - void stop_critical_timings(void) - { -+ trace_preemptirqsoff_hist_rcuidle(TRACE_STOP, 0); - if (preempt_trace() || irq_trace()) - stop_critical_timing(CALLER_ADDR0, CALLER_ADDR1); - } -@@ -438,6 +441,7 @@ EXPORT_SYMBOL_GPL(stop_critical_timings); - #ifdef CONFIG_PROVE_LOCKING - void time_hardirqs_on(unsigned long a0, unsigned long a1) - { -+ trace_preemptirqsoff_hist_rcuidle(IRQS_ON, 0); - if (!preempt_trace() && irq_trace()) - stop_critical_timing(a0, a1); - } -@@ -446,6 +450,7 @@ void time_hardirqs_off(unsigned long a0, unsigned long a1) - { - if (!preempt_trace() && irq_trace()) - start_critical_timing(a0, a1); -+ trace_preemptirqsoff_hist_rcuidle(IRQS_OFF, 1); - } - - #else /* !CONFIG_PROVE_LOCKING */ -@@ -471,6 +476,7 @@ inline void print_irqtrace_events(struct task_struct *curr) - */ - void trace_hardirqs_on(void) - { -+ trace_preemptirqsoff_hist(IRQS_ON, 0); - if (!preempt_trace() && irq_trace()) - stop_critical_timing(CALLER_ADDR0, CALLER_ADDR1); - } -@@ -480,11 +486,13 @@ void trace_hardirqs_off(void) - { - if (!preempt_trace() && irq_trace()) - start_critical_timing(CALLER_ADDR0, CALLER_ADDR1); -+ trace_preemptirqsoff_hist(IRQS_OFF, 1); - } - EXPORT_SYMBOL(trace_hardirqs_off); - - __visible void trace_hardirqs_on_caller(unsigned long caller_addr) - { -+ trace_preemptirqsoff_hist(IRQS_ON, 0); - if (!preempt_trace() && irq_trace()) - stop_critical_timing(CALLER_ADDR0, caller_addr); - } -@@ -494,6 +502,7 @@ __visible void trace_hardirqs_off_caller(unsigned long caller_addr) - { - if (!preempt_trace() && irq_trace()) - start_critical_timing(CALLER_ADDR0, caller_addr); -+ trace_preemptirqsoff_hist(IRQS_OFF, 1); - } - EXPORT_SYMBOL(trace_hardirqs_off_caller); - -@@ -503,12 +512,14 @@ EXPORT_SYMBOL(trace_hardirqs_off_caller); - #ifdef CONFIG_PREEMPT_TRACER - void trace_preempt_on(unsigned long a0, unsigned long a1) - { -+ trace_preemptirqsoff_hist(PREEMPT_ON, 0); - if (preempt_trace() && !irq_trace()) - stop_critical_timing(a0, a1); - } - - void trace_preempt_off(unsigned long a0, unsigned long a1) - { -+ trace_preemptirqsoff_hist(PREEMPT_ON, 1); - if (preempt_trace() && !irq_trace()) - start_critical_timing(a0, a1); - } -diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c -index 0bb9cf2..455a746 100644 ---- a/kernel/trace/trace_output.c -+++ b/kernel/trace/trace_output.c -@@ -386,6 +386,7 @@ int trace_print_lat_fmt(struct trace_seq *s, struct trace_entry *entry) - { - char hardsoft_irq; - char need_resched; -+ char need_resched_lazy; - char irqs_off; - int hardirq; - int softirq; -@@ -416,6 +417,9 @@ int trace_print_lat_fmt(struct trace_seq *s, struct trace_entry *entry) - break; - } - -+ need_resched_lazy = -+ (entry->flags & TRACE_FLAG_NEED_RESCHED_LAZY) ? 'L' : '.'; -+ - hardsoft_irq = - (nmi && hardirq) ? 'Z' : - nmi ? 'z' : -@@ -424,14 +428,25 @@ int trace_print_lat_fmt(struct trace_seq *s, struct trace_entry *entry) - softirq ? 's' : - '.' ; - -- trace_seq_printf(s, "%c%c%c", -- irqs_off, need_resched, hardsoft_irq); -+ trace_seq_printf(s, "%c%c%c%c", -+ irqs_off, need_resched, need_resched_lazy, -+ hardsoft_irq); - - if (entry->preempt_count) - trace_seq_printf(s, "%x", entry->preempt_count); - else - trace_seq_putc(s, '.'); - -+ if (entry->preempt_lazy_count) -+ trace_seq_printf(s, "%x", entry->preempt_lazy_count); -+ else -+ trace_seq_putc(s, '.'); -+ -+ if (entry->migrate_disable) -+ trace_seq_printf(s, "%x", entry->migrate_disable); -+ else -+ trace_seq_putc(s, '.'); -+ - return !trace_seq_has_overflowed(s); - } - -diff --git a/kernel/user.c b/kernel/user.c -index b069ccb..1a2e88e 100644 ---- a/kernel/user.c -+++ b/kernel/user.c -@@ -161,11 +161,11 @@ void free_uid(struct user_struct *up) - if (!up) - return; - -- local_irq_save(flags); -+ local_irq_save_nort(flags); - if (atomic_dec_and_lock(&up->__count, &uidhash_lock)) - free_user(up, flags); - else -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - } - - struct user_struct *alloc_uid(kuid_t uid) -diff --git a/kernel/watchdog.c b/kernel/watchdog.c -index 9acb29f..caba620 100644 ---- a/kernel/watchdog.c -+++ b/kernel/watchdog.c -@@ -315,6 +315,8 @@ static int is_softlockup(unsigned long touch_ts) - - #ifdef CONFIG_HARDLOCKUP_DETECTOR - -+static DEFINE_RAW_SPINLOCK(watchdog_output_lock); -+ - static struct perf_event_attr wd_hw_attr = { - .type = PERF_TYPE_HARDWARE, - .config = PERF_COUNT_HW_CPU_CYCLES, -@@ -349,6 +351,13 @@ static void watchdog_overflow_callback(struct perf_event *event, - /* only print hardlockups once */ - if (__this_cpu_read(hard_watchdog_warn) == true) - return; -+ /* -+ * If early-printk is enabled then make sure we do not -+ * lock up in printk() and kill console logging: -+ */ -+ printk_kill(); -+ -+ raw_spin_lock(&watchdog_output_lock); - - pr_emerg("Watchdog detected hard LOCKUP on cpu %d", this_cpu); - print_modules(); -@@ -366,6 +375,7 @@ static void watchdog_overflow_callback(struct perf_event *event, - !test_and_set_bit(0, &hardlockup_allcpu_dumped)) - trigger_allbutself_cpu_backtrace(); - -+ raw_spin_unlock(&watchdog_output_lock); - if (hardlockup_panic) - nmi_panic(regs, "Hard LOCKUP"); - -@@ -513,6 +523,7 @@ static void watchdog_enable(unsigned int cpu) - /* kick off the timer for the hardlockup detector */ - hrtimer_init(hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - hrtimer->function = watchdog_timer_fn; -+ hrtimer->irqsafe = 1; - - /* Enable the perf event */ - watchdog_nmi_enable(cpu); -diff --git a/kernel/workqueue.c b/kernel/workqueue.c -index 5f5068e..54fd5df 100644 ---- a/kernel/workqueue.c -+++ b/kernel/workqueue.c -@@ -48,6 +48,8 @@ - #include <linux/nodemask.h> - #include <linux/moduleparam.h> - #include <linux/uaccess.h> -+#include <linux/locallock.h> -+#include <linux/delay.h> - - #include "workqueue_internal.h" - -@@ -121,11 +123,16 @@ enum { - * cpu or grabbing pool->lock is enough for read access. If - * POOL_DISASSOCIATED is set, it's identical to L. - * -+ * On RT we need the extra protection via rt_lock_idle_list() for -+ * the list manipulations against read access from -+ * wq_worker_sleeping(). All other places are nicely serialized via -+ * pool->lock. -+ * - * A: pool->attach_mutex protected. - * - * PL: wq_pool_mutex protected. - * -- * PR: wq_pool_mutex protected for writes. Sched-RCU protected for reads. -+ * PR: wq_pool_mutex protected for writes. RCU protected for reads. - * - * PW: wq_pool_mutex and wq->mutex protected for writes. Either for reads. - * -@@ -134,7 +141,7 @@ enum { - * - * WQ: wq->mutex protected. - * -- * WR: wq->mutex protected for writes. Sched-RCU protected for reads. -+ * WR: wq->mutex protected for writes. RCU protected for reads. - * - * MD: wq_mayday_lock protected. - */ -@@ -185,7 +192,7 @@ struct worker_pool { - atomic_t nr_running ____cacheline_aligned_in_smp; - - /* -- * Destruction of pool is sched-RCU protected to allow dereferences -+ * Destruction of pool is RCU protected to allow dereferences - * from get_work_pool(). - */ - struct rcu_head rcu; -@@ -214,7 +221,7 @@ struct pool_workqueue { - /* - * Release of unbound pwq is punted to system_wq. See put_pwq() - * and pwq_unbound_release_workfn() for details. pool_workqueue -- * itself is also sched-RCU protected so that the first pwq can be -+ * itself is also RCU protected so that the first pwq can be - * determined without grabbing wq->mutex. - */ - struct work_struct unbound_release_work; -@@ -348,6 +355,8 @@ EXPORT_SYMBOL_GPL(system_power_efficient_wq); - struct workqueue_struct *system_freezable_power_efficient_wq __read_mostly; - EXPORT_SYMBOL_GPL(system_freezable_power_efficient_wq); - -+static DEFINE_LOCAL_IRQ_LOCK(pendingb_lock); -+ - static int worker_thread(void *__worker); - static void workqueue_sysfs_unregister(struct workqueue_struct *wq); - -@@ -355,20 +364,20 @@ static void workqueue_sysfs_unregister(struct workqueue_struct *wq); - #include <trace/events/workqueue.h> - - #define assert_rcu_or_pool_mutex() \ -- RCU_LOCKDEP_WARN(!rcu_read_lock_sched_held() && \ -+ RCU_LOCKDEP_WARN(!rcu_read_lock_held() && \ - !lockdep_is_held(&wq_pool_mutex), \ -- "sched RCU or wq_pool_mutex should be held") -+ "RCU or wq_pool_mutex should be held") - - #define assert_rcu_or_wq_mutex(wq) \ -- RCU_LOCKDEP_WARN(!rcu_read_lock_sched_held() && \ -+ RCU_LOCKDEP_WARN(!rcu_read_lock_held() && \ - !lockdep_is_held(&wq->mutex), \ -- "sched RCU or wq->mutex should be held") -+ "RCU or wq->mutex should be held") - - #define assert_rcu_or_wq_mutex_or_pool_mutex(wq) \ -- RCU_LOCKDEP_WARN(!rcu_read_lock_sched_held() && \ -+ RCU_LOCKDEP_WARN(!rcu_read_lock_held() && \ - !lockdep_is_held(&wq->mutex) && \ - !lockdep_is_held(&wq_pool_mutex), \ -- "sched RCU, wq->mutex or wq_pool_mutex should be held") -+ "RCU, wq->mutex or wq_pool_mutex should be held") - - #define for_each_cpu_worker_pool(pool, cpu) \ - for ((pool) = &per_cpu(cpu_worker_pools, cpu)[0]; \ -@@ -380,7 +389,7 @@ static void workqueue_sysfs_unregister(struct workqueue_struct *wq); - * @pool: iteration cursor - * @pi: integer used for iteration - * -- * This must be called either with wq_pool_mutex held or sched RCU read -+ * This must be called either with wq_pool_mutex held or RCU read - * locked. If the pool needs to be used beyond the locking in effect, the - * caller is responsible for guaranteeing that the pool stays online. - * -@@ -412,7 +421,7 @@ static void workqueue_sysfs_unregister(struct workqueue_struct *wq); - * @pwq: iteration cursor - * @wq: the target workqueue - * -- * This must be called either with wq->mutex held or sched RCU read locked. -+ * This must be called either with wq->mutex held or RCU read locked. - * If the pwq needs to be used beyond the locking in effect, the caller is - * responsible for guaranteeing that the pwq stays online. - * -@@ -424,6 +433,31 @@ static void workqueue_sysfs_unregister(struct workqueue_struct *wq); - if (({ assert_rcu_or_wq_mutex(wq); false; })) { } \ - else - -+#ifdef CONFIG_PREEMPT_RT_BASE -+static inline void rt_lock_idle_list(struct worker_pool *pool) -+{ -+ preempt_disable(); -+} -+static inline void rt_unlock_idle_list(struct worker_pool *pool) -+{ -+ preempt_enable(); -+} -+static inline void sched_lock_idle_list(struct worker_pool *pool) { } -+static inline void sched_unlock_idle_list(struct worker_pool *pool) { } -+#else -+static inline void rt_lock_idle_list(struct worker_pool *pool) { } -+static inline void rt_unlock_idle_list(struct worker_pool *pool) { } -+static inline void sched_lock_idle_list(struct worker_pool *pool) -+{ -+ spin_lock_irq(&pool->lock); -+} -+static inline void sched_unlock_idle_list(struct worker_pool *pool) -+{ -+ spin_unlock_irq(&pool->lock); -+} -+#endif -+ -+ - #ifdef CONFIG_DEBUG_OBJECTS_WORK - - static struct debug_obj_descr work_debug_descr; -@@ -574,7 +608,7 @@ static int worker_pool_assign_id(struct worker_pool *pool) - * @wq: the target workqueue - * @node: the node ID - * -- * This must be called with any of wq_pool_mutex, wq->mutex or sched RCU -+ * This must be called with any of wq_pool_mutex, wq->mutex or RCU - * read locked. - * If the pwq needs to be used beyond the locking in effect, the caller is - * responsible for guaranteeing that the pwq stays online. -@@ -718,8 +752,8 @@ static struct pool_workqueue *get_work_pwq(struct work_struct *work) - * @work: the work item of interest - * - * Pools are created and destroyed under wq_pool_mutex, and allows read -- * access under sched-RCU read lock. As such, this function should be -- * called under wq_pool_mutex or with preemption disabled. -+ * access under RCU read lock. As such, this function should be -+ * called under wq_pool_mutex or inside of a rcu_read_lock() region. - * - * All fields of the returned pool are accessible as long as the above - * mentioned locking is in effect. If the returned pool needs to be used -@@ -856,50 +890,45 @@ static struct worker *first_idle_worker(struct worker_pool *pool) - */ - static void wake_up_worker(struct worker_pool *pool) - { -- struct worker *worker = first_idle_worker(pool); -+ struct worker *worker; -+ -+ rt_lock_idle_list(pool); -+ -+ worker = first_idle_worker(pool); - - if (likely(worker)) - wake_up_process(worker->task); -+ -+ rt_unlock_idle_list(pool); - } - - /** -- * wq_worker_waking_up - a worker is waking up -- * @task: task waking up -+ * wq_worker_running - a worker is running again - * @cpu: CPU @task is waking up to - * -- * This function is called during try_to_wake_up() when a worker is -- * being awoken. -- * -- * CONTEXT: -- * spin_lock_irq(rq->lock) -+ * This function is called when a worker returns from schedule() - */ --void wq_worker_waking_up(struct task_struct *task, int cpu) -+void wq_worker_running(struct task_struct *task) - { - struct worker *worker = kthread_data(task); - -- if (!(worker->flags & WORKER_NOT_RUNNING)) { -- WARN_ON_ONCE(worker->pool->cpu != cpu); -+ if (!worker->sleeping) -+ return; -+ if (!(worker->flags & WORKER_NOT_RUNNING)) - atomic_inc(&worker->pool->nr_running); -- } -+ worker->sleeping = 0; - } - - /** - * wq_worker_sleeping - a worker is going to sleep - * @task: task going to sleep - * -- * This function is called during schedule() when a busy worker is -- * going to sleep. Worker on the same cpu can be woken up by -- * returning pointer to its task. -- * -- * CONTEXT: -- * spin_lock_irq(rq->lock) -- * -- * Return: -- * Worker task on @cpu to wake up, %NULL if none. -+ * This function is called from schedule() when a busy worker is -+ * going to sleep. - */ --struct task_struct *wq_worker_sleeping(struct task_struct *task) -+void wq_worker_sleeping(struct task_struct *task) - { -- struct worker *worker = kthread_data(task), *to_wakeup = NULL; -+ struct worker *worker = kthread_data(task); - struct worker_pool *pool; - - /* -@@ -908,29 +937,26 @@ struct task_struct *wq_worker_sleeping(struct task_struct *task) - * checking NOT_RUNNING. - */ - if (worker->flags & WORKER_NOT_RUNNING) -- return NULL; -+ return; - - pool = worker->pool; - -- /* this can only happen on the local cpu */ -- if (WARN_ON_ONCE(pool->cpu != raw_smp_processor_id())) -- return NULL; -+ if (WARN_ON_ONCE(worker->sleeping)) -+ return; -+ -+ worker->sleeping = 1; - - /* - * The counterpart of the following dec_and_test, implied mb, - * worklist not empty test sequence is in insert_work(). - * Please read comment there. -- * -- * NOT_RUNNING is clear. This means that we're bound to and -- * running on the local cpu w/ rq lock held and preemption -- * disabled, which in turn means that none else could be -- * manipulating idle_list, so dereferencing idle_list without pool -- * lock is safe. - */ - if (atomic_dec_and_test(&pool->nr_running) && -- !list_empty(&pool->worklist)) -- to_wakeup = first_idle_worker(pool); -- return to_wakeup ? to_wakeup->task : NULL; -+ !list_empty(&pool->worklist)) { -+ sched_lock_idle_list(pool); -+ wake_up_worker(pool); -+ sched_unlock_idle_list(pool); -+ } - } - - /** -@@ -1124,12 +1150,12 @@ static void put_pwq_unlocked(struct pool_workqueue *pwq) - { - if (pwq) { - /* -- * As both pwqs and pools are sched-RCU protected, the -+ * As both pwqs and pools are RCU protected, the - * following lock operations are safe. - */ -- spin_lock_irq(&pwq->pool->lock); -+ local_spin_lock_irq(pendingb_lock, &pwq->pool->lock); - put_pwq(pwq); -- spin_unlock_irq(&pwq->pool->lock); -+ local_spin_unlock_irq(pendingb_lock, &pwq->pool->lock); - } - } - -@@ -1233,7 +1259,7 @@ static int try_to_grab_pending(struct work_struct *work, bool is_dwork, - struct worker_pool *pool; - struct pool_workqueue *pwq; - -- local_irq_save(*flags); -+ local_lock_irqsave(pendingb_lock, *flags); - - /* try to steal the timer if it exists */ - if (is_dwork) { -@@ -1252,6 +1278,7 @@ static int try_to_grab_pending(struct work_struct *work, bool is_dwork, - if (!test_and_set_bit(WORK_STRUCT_PENDING_BIT, work_data_bits(work))) - return 0; - -+ rcu_read_lock(); - /* - * The queueing is in progress, or it is already queued. Try to - * steal it from ->worklist without clearing WORK_STRUCT_PENDING. -@@ -1290,14 +1317,16 @@ static int try_to_grab_pending(struct work_struct *work, bool is_dwork, - set_work_pool_and_keep_pending(work, pool->id); - - spin_unlock(&pool->lock); -+ rcu_read_unlock(); - return 1; - } - spin_unlock(&pool->lock); - fail: -- local_irq_restore(*flags); -+ rcu_read_unlock(); -+ local_unlock_irqrestore(pendingb_lock, *flags); - if (work_is_canceling(work)) - return -ENOENT; -- cpu_relax(); -+ cpu_chill(); - return -EAGAIN; - } - -@@ -1399,7 +1428,7 @@ static void __queue_work(int cpu, struct workqueue_struct *wq, - * queued or lose PENDING. Grabbing PENDING and queueing should - * happen with IRQ disabled. - */ -- WARN_ON_ONCE(!irqs_disabled()); -+ WARN_ON_ONCE_NONRT(!irqs_disabled()); - - debug_work_activate(work); - -@@ -1407,6 +1436,7 @@ static void __queue_work(int cpu, struct workqueue_struct *wq, - if (unlikely(wq->flags & __WQ_DRAINING) && - WARN_ON_ONCE(!is_chained_work(wq))) - return; -+ rcu_read_lock(); - retry: - if (req_cpu == WORK_CPU_UNBOUND) - cpu = wq_select_unbound_cpu(raw_smp_processor_id()); -@@ -1463,10 +1493,8 @@ retry: - /* pwq determined, queue */ - trace_workqueue_queue_work(req_cpu, pwq, work); - -- if (WARN_ON(!list_empty(&work->entry))) { -- spin_unlock(&pwq->pool->lock); -- return; -- } -+ if (WARN_ON(!list_empty(&work->entry))) -+ goto out; - - pwq->nr_in_flight[pwq->work_color]++; - work_flags = work_color_to_flags(pwq->work_color); -@@ -1484,7 +1512,9 @@ retry: - - insert_work(pwq, work, worklist, work_flags); - -+out: - spin_unlock(&pwq->pool->lock); -+ rcu_read_unlock(); - } - - /** -@@ -1504,14 +1534,14 @@ bool queue_work_on(int cpu, struct workqueue_struct *wq, - bool ret = false; - unsigned long flags; - -- local_irq_save(flags); -+ local_lock_irqsave(pendingb_lock,flags); - - if (!test_and_set_bit(WORK_STRUCT_PENDING_BIT, work_data_bits(work))) { - __queue_work(cpu, wq, work); - ret = true; - } - -- local_irq_restore(flags); -+ local_unlock_irqrestore(pendingb_lock, flags); - return ret; - } - EXPORT_SYMBOL(queue_work_on); -@@ -1578,14 +1608,14 @@ bool queue_delayed_work_on(int cpu, struct workqueue_struct *wq, - unsigned long flags; - - /* read the comment in __queue_work() */ -- local_irq_save(flags); -+ local_lock_irqsave(pendingb_lock, flags); - - if (!test_and_set_bit(WORK_STRUCT_PENDING_BIT, work_data_bits(work))) { - __queue_delayed_work(cpu, wq, dwork, delay); - ret = true; - } - -- local_irq_restore(flags); -+ local_unlock_irqrestore(pendingb_lock, flags); - return ret; - } - EXPORT_SYMBOL(queue_delayed_work_on); -@@ -1620,7 +1650,7 @@ bool mod_delayed_work_on(int cpu, struct workqueue_struct *wq, - - if (likely(ret >= 0)) { - __queue_delayed_work(cpu, wq, dwork, delay); -- local_irq_restore(flags); -+ local_unlock_irqrestore(pendingb_lock, flags); - } - - /* -ENOENT from try_to_grab_pending() becomes %true */ -@@ -1653,7 +1683,9 @@ static void worker_enter_idle(struct worker *worker) - worker->last_active = jiffies; - - /* idle_list is LIFO */ -+ rt_lock_idle_list(pool); - list_add(&worker->entry, &pool->idle_list); -+ rt_unlock_idle_list(pool); - - if (too_many_workers(pool) && !timer_pending(&pool->idle_timer)) - mod_timer(&pool->idle_timer, jiffies + IDLE_WORKER_TIMEOUT); -@@ -1686,7 +1718,9 @@ static void worker_leave_idle(struct worker *worker) - return; - worker_clr_flags(worker, WORKER_IDLE); - pool->nr_idle--; -+ rt_lock_idle_list(pool); - list_del_init(&worker->entry); -+ rt_unlock_idle_list(pool); - } - - static struct worker *alloc_worker(int node) -@@ -1852,7 +1886,9 @@ static void destroy_worker(struct worker *worker) - pool->nr_workers--; - pool->nr_idle--; - -+ rt_lock_idle_list(pool); - list_del_init(&worker->entry); -+ rt_unlock_idle_list(pool); - worker->flags |= WORKER_DIE; - wake_up_process(worker->task); - } -@@ -2811,14 +2847,14 @@ static bool start_flush_work(struct work_struct *work, struct wq_barrier *barr) - - might_sleep(); - -- local_irq_disable(); -+ rcu_read_lock(); - pool = get_work_pool(work); - if (!pool) { -- local_irq_enable(); -+ rcu_read_unlock(); - return false; - } - -- spin_lock(&pool->lock); -+ spin_lock_irq(&pool->lock); - /* see the comment in try_to_grab_pending() with the same code */ - pwq = get_work_pwq(work); - if (pwq) { -@@ -2847,10 +2883,11 @@ static bool start_flush_work(struct work_struct *work, struct wq_barrier *barr) - else - lock_map_acquire_read(&pwq->wq->lockdep_map); - lock_map_release(&pwq->wq->lockdep_map); -- -+ rcu_read_unlock(); - return true; - already_gone: - spin_unlock_irq(&pool->lock); -+ rcu_read_unlock(); - return false; - } - -@@ -2937,7 +2974,7 @@ static bool __cancel_work_timer(struct work_struct *work, bool is_dwork) - - /* tell other tasks trying to grab @work to back off */ - mark_work_canceling(work); -- local_irq_restore(flags); -+ local_unlock_irqrestore(pendingb_lock, flags); - - flush_work(work); - clear_work_data(work); -@@ -2992,10 +3029,10 @@ EXPORT_SYMBOL_GPL(cancel_work_sync); - */ - bool flush_delayed_work(struct delayed_work *dwork) - { -- local_irq_disable(); -+ local_lock_irq(pendingb_lock); - if (del_timer_sync(&dwork->timer)) - __queue_work(dwork->cpu, dwork->wq, &dwork->work); -- local_irq_enable(); -+ local_unlock_irq(pendingb_lock); - return flush_work(&dwork->work); - } - EXPORT_SYMBOL(flush_delayed_work); -@@ -3030,7 +3067,7 @@ bool cancel_delayed_work(struct delayed_work *dwork) - - set_work_pool_and_clear_pending(&dwork->work, - get_work_pool_id(&dwork->work)); -- local_irq_restore(flags); -+ local_unlock_irqrestore(pendingb_lock, flags); - return ret; - } - EXPORT_SYMBOL(cancel_delayed_work); -@@ -3259,7 +3296,7 @@ static void rcu_free_pool(struct rcu_head *rcu) - * put_unbound_pool - put a worker_pool - * @pool: worker_pool to put - * -- * Put @pool. If its refcnt reaches zero, it gets destroyed in sched-RCU -+ * Put @pool. If its refcnt reaches zero, it gets destroyed in RCU - * safe manner. get_unbound_pool() calls this function on its failure path - * and this function should be able to release pools which went through, - * successfully or not, init_worker_pool(). -@@ -3313,8 +3350,8 @@ static void put_unbound_pool(struct worker_pool *pool) - del_timer_sync(&pool->idle_timer); - del_timer_sync(&pool->mayday_timer); - -- /* sched-RCU protected to allow dereferences from get_work_pool() */ -- call_rcu_sched(&pool->rcu, rcu_free_pool); -+ /* RCU protected to allow dereferences from get_work_pool() */ -+ call_rcu(&pool->rcu, rcu_free_pool); - } - - /** -@@ -3421,14 +3458,14 @@ static void pwq_unbound_release_workfn(struct work_struct *work) - put_unbound_pool(pool); - mutex_unlock(&wq_pool_mutex); - -- call_rcu_sched(&pwq->rcu, rcu_free_pwq); -+ call_rcu(&pwq->rcu, rcu_free_pwq); - - /* - * If we're the last pwq going away, @wq is already dead and no one - * is gonna access it anymore. Schedule RCU free. - */ - if (is_last) -- call_rcu_sched(&wq->rcu, rcu_free_wq); -+ call_rcu(&wq->rcu, rcu_free_wq); - } - - /** -@@ -4078,7 +4115,7 @@ void destroy_workqueue(struct workqueue_struct *wq) - * The base ref is never dropped on per-cpu pwqs. Directly - * schedule RCU free. - */ -- call_rcu_sched(&wq->rcu, rcu_free_wq); -+ call_rcu(&wq->rcu, rcu_free_wq); - } else { - /* - * We're the sole accessor of @wq at this point. Directly -@@ -4171,7 +4208,8 @@ bool workqueue_congested(int cpu, struct workqueue_struct *wq) - struct pool_workqueue *pwq; - bool ret; - -- rcu_read_lock_sched(); -+ rcu_read_lock(); -+ preempt_disable(); - - if (cpu == WORK_CPU_UNBOUND) - cpu = smp_processor_id(); -@@ -4182,7 +4220,8 @@ bool workqueue_congested(int cpu, struct workqueue_struct *wq) - pwq = unbound_pwq_by_node(wq, cpu_to_node(cpu)); - - ret = !list_empty(&pwq->delayed_works); -- rcu_read_unlock_sched(); -+ preempt_enable(); -+ rcu_read_unlock(); - - return ret; - } -@@ -4208,15 +4247,15 @@ unsigned int work_busy(struct work_struct *work) - if (work_pending(work)) - ret |= WORK_BUSY_PENDING; - -- local_irq_save(flags); -+ rcu_read_lock(); - pool = get_work_pool(work); - if (pool) { -- spin_lock(&pool->lock); -+ spin_lock_irqsave(&pool->lock, flags); - if (find_worker_executing_work(pool, work)) - ret |= WORK_BUSY_RUNNING; -- spin_unlock(&pool->lock); -+ spin_unlock_irqrestore(&pool->lock, flags); - } -- local_irq_restore(flags); -+ rcu_read_unlock(); - - return ret; - } -@@ -4405,7 +4444,7 @@ void show_workqueue_state(void) - unsigned long flags; - int pi; - -- rcu_read_lock_sched(); -+ rcu_read_lock(); - - pr_info("Showing busy workqueues and worker pools:\n"); - -@@ -4458,7 +4497,7 @@ void show_workqueue_state(void) - spin_unlock_irqrestore(&pool->lock, flags); - } - -- rcu_read_unlock_sched(); -+ rcu_read_unlock(); - } - - /* -@@ -4819,16 +4858,16 @@ bool freeze_workqueues_busy(void) - * nr_active is monotonically decreasing. It's safe - * to peek without lock. - */ -- rcu_read_lock_sched(); -+ rcu_read_lock(); - for_each_pwq(pwq, wq) { - WARN_ON_ONCE(pwq->nr_active < 0); - if (pwq->nr_active) { - busy = true; -- rcu_read_unlock_sched(); -+ rcu_read_unlock(); - goto out_unlock; - } - } -- rcu_read_unlock_sched(); -+ rcu_read_unlock(); - } - out_unlock: - mutex_unlock(&wq_pool_mutex); -@@ -5018,7 +5057,8 @@ static ssize_t wq_pool_ids_show(struct device *dev, - const char *delim = ""; - int node, written = 0; - -- rcu_read_lock_sched(); -+ get_online_cpus(); -+ rcu_read_lock(); - for_each_node(node) { - written += scnprintf(buf + written, PAGE_SIZE - written, - "%s%d:%d", delim, node, -@@ -5026,7 +5066,8 @@ static ssize_t wq_pool_ids_show(struct device *dev, - delim = " "; - } - written += scnprintf(buf + written, PAGE_SIZE - written, "\n"); -- rcu_read_unlock_sched(); -+ rcu_read_unlock(); -+ put_online_cpus(); - - return written; - } -diff --git a/kernel/workqueue_internal.h b/kernel/workqueue_internal.h -index 8635417..f000c4d 100644 ---- a/kernel/workqueue_internal.h -+++ b/kernel/workqueue_internal.h -@@ -43,6 +43,7 @@ struct worker { - unsigned long last_active; /* L: last active timestamp */ - unsigned int flags; /* X: flags */ - int id; /* I: worker id */ -+ int sleeping; /* None */ - - /* - * Opaque string set with work_set_desc(). Printed out with task -@@ -68,7 +69,7 @@ static inline struct worker *current_wq_worker(void) - * Scheduler hooks for concurrency managed workqueue. Only to be used from - * sched/core.c and workqueue.c. - */ --void wq_worker_waking_up(struct task_struct *task, int cpu); --struct task_struct *wq_worker_sleeping(struct task_struct *task); -+void wq_worker_running(struct task_struct *task); -+void wq_worker_sleeping(struct task_struct *task); - - #endif /* _KERNEL_WORKQUEUE_INTERNAL_H */ -diff --git a/lib/Kconfig b/lib/Kconfig -index 3cca122..b89fc37 100644 ---- a/lib/Kconfig -+++ b/lib/Kconfig -@@ -397,6 +397,7 @@ config CHECK_SIGNATURE - - config CPUMASK_OFFSTACK - bool "Force CPU masks off stack" if DEBUG_PER_CPU_MAPS -+ depends on !PREEMPT_RT_FULL - help - Use dynamic allocation for cpumask_var_t, instead of putting - them on the stack. This is a bit more expensive, but avoids -diff --git a/lib/debugobjects.c b/lib/debugobjects.c -index 519b5a1..5970701 100644 ---- a/lib/debugobjects.c -+++ b/lib/debugobjects.c -@@ -309,7 +309,10 @@ __debug_object_init(void *addr, struct debug_obj_descr *descr, int onstack) - struct debug_obj *obj; - unsigned long flags; - -- fill_pool(); -+#ifdef CONFIG_PREEMPT_RT_FULL -+ if (preempt_count() == 0 && !irqs_disabled()) -+#endif -+ fill_pool(); - - db = get_bucket((unsigned long) addr); - -diff --git a/lib/idr.c b/lib/idr.c -index 6098336..9decbe9 100644 ---- a/lib/idr.c -+++ b/lib/idr.c -@@ -30,6 +30,7 @@ - #include <linux/idr.h> - #include <linux/spinlock.h> - #include <linux/percpu.h> -+#include <linux/locallock.h> - - #define MAX_IDR_SHIFT (sizeof(int) * 8 - 1) - #define MAX_IDR_BIT (1U << MAX_IDR_SHIFT) -@@ -45,6 +46,37 @@ static DEFINE_PER_CPU(struct idr_layer *, idr_preload_head); - static DEFINE_PER_CPU(int, idr_preload_cnt); - static DEFINE_SPINLOCK(simple_ida_lock); - -+#ifdef CONFIG_PREEMPT_RT_FULL -+static DEFINE_LOCAL_IRQ_LOCK(idr_lock); -+ -+static inline void idr_preload_lock(void) -+{ -+ local_lock(idr_lock); -+} -+ -+static inline void idr_preload_unlock(void) -+{ -+ local_unlock(idr_lock); -+} -+ -+void idr_preload_end(void) -+{ -+ idr_preload_unlock(); -+} -+EXPORT_SYMBOL(idr_preload_end); -+#else -+static inline void idr_preload_lock(void) -+{ -+ preempt_disable(); -+} -+ -+static inline void idr_preload_unlock(void) -+{ -+ preempt_enable(); -+} -+#endif -+ -+ - /* the maximum ID which can be allocated given idr->layers */ - static int idr_max(int layers) - { -@@ -115,14 +147,14 @@ static struct idr_layer *idr_layer_alloc(gfp_t gfp_mask, struct idr *layer_idr) - * context. See idr_preload() for details. - */ - if (!in_interrupt()) { -- preempt_disable(); -+ idr_preload_lock(); - new = __this_cpu_read(idr_preload_head); - if (new) { - __this_cpu_write(idr_preload_head, new->ary[0]); - __this_cpu_dec(idr_preload_cnt); - new->ary[0] = NULL; - } -- preempt_enable(); -+ idr_preload_unlock(); - if (new) - return new; - } -@@ -366,7 +398,6 @@ static void idr_fill_slot(struct idr *idr, void *ptr, int id, - idr_mark_full(pa, id); - } - -- - /** - * idr_preload - preload for idr_alloc() - * @gfp_mask: allocation mask to use for preloading -@@ -401,7 +432,7 @@ void idr_preload(gfp_t gfp_mask) - WARN_ON_ONCE(in_interrupt()); - might_sleep_if(gfpflags_allow_blocking(gfp_mask)); - -- preempt_disable(); -+ idr_preload_lock(); - - /* - * idr_alloc() is likely to succeed w/o full idr_layer buffer and -@@ -413,9 +444,9 @@ void idr_preload(gfp_t gfp_mask) - while (__this_cpu_read(idr_preload_cnt) < MAX_IDR_FREE) { - struct idr_layer *new; - -- preempt_enable(); -+ idr_preload_unlock(); - new = kmem_cache_zalloc(idr_layer_cache, gfp_mask); -- preempt_disable(); -+ idr_preload_lock(); - if (!new) - break; - -diff --git a/lib/irq_poll.c b/lib/irq_poll.c -index 836f7db..709d4ee 100644 ---- a/lib/irq_poll.c -+++ b/lib/irq_poll.c -@@ -36,6 +36,7 @@ void irq_poll_sched(struct irq_poll *iop) - list_add_tail(&iop->list, this_cpu_ptr(&blk_cpu_iopoll)); - __raise_softirq_irqoff(IRQ_POLL_SOFTIRQ); - local_irq_restore(flags); -+ preempt_check_resched_rt(); - } - EXPORT_SYMBOL(irq_poll_sched); - -@@ -71,6 +72,7 @@ void irq_poll_complete(struct irq_poll *iop) - local_irq_save(flags); - __irq_poll_complete(iop); - local_irq_restore(flags); -+ preempt_check_resched_rt(); - } - EXPORT_SYMBOL(irq_poll_complete); - -@@ -95,6 +97,7 @@ static void irq_poll_softirq(struct softirq_action *h) - } - - local_irq_enable(); -+ preempt_check_resched_rt(); - - /* Even though interrupts have been re-enabled, this - * access is safe because interrupts can only add new -@@ -132,6 +135,7 @@ static void irq_poll_softirq(struct softirq_action *h) - __raise_softirq_irqoff(IRQ_POLL_SOFTIRQ); - - local_irq_enable(); -+ preempt_check_resched_rt(); - } - - /** -@@ -199,6 +203,7 @@ static int irq_poll_cpu_notify(struct notifier_block *self, - this_cpu_ptr(&blk_cpu_iopoll)); - __raise_softirq_irqoff(IRQ_POLL_SOFTIRQ); - local_irq_enable(); -+ preempt_check_resched_rt(); - } - - return NOTIFY_OK; -diff --git a/lib/locking-selftest.c b/lib/locking-selftest.c -index 872a15a..b93a610 100644 ---- a/lib/locking-selftest.c -+++ b/lib/locking-selftest.c -@@ -590,6 +590,8 @@ GENERATE_TESTCASE(init_held_rsem) - #include "locking-selftest-spin-hardirq.h" - GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_spin) - -+#ifndef CONFIG_PREEMPT_RT_FULL -+ - #include "locking-selftest-rlock-hardirq.h" - GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_rlock) - -@@ -605,9 +607,12 @@ GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_soft_rlock) - #include "locking-selftest-wlock-softirq.h" - GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_soft_wlock) - -+#endif -+ - #undef E1 - #undef E2 - -+#ifndef CONFIG_PREEMPT_RT_FULL - /* - * Enabling hardirqs with a softirq-safe lock held: - */ -@@ -640,6 +645,8 @@ GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2A_rlock) - #undef E1 - #undef E2 - -+#endif -+ - /* - * Enabling irqs with an irq-safe lock held: - */ -@@ -663,6 +670,8 @@ GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2A_rlock) - #include "locking-selftest-spin-hardirq.h" - GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_spin) - -+#ifndef CONFIG_PREEMPT_RT_FULL -+ - #include "locking-selftest-rlock-hardirq.h" - GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_rlock) - -@@ -678,6 +687,8 @@ GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_rlock) - #include "locking-selftest-wlock-softirq.h" - GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_wlock) - -+#endif -+ - #undef E1 - #undef E2 - -@@ -709,6 +720,8 @@ GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_wlock) - #include "locking-selftest-spin-hardirq.h" - GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_spin) - -+#ifndef CONFIG_PREEMPT_RT_FULL -+ - #include "locking-selftest-rlock-hardirq.h" - GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_rlock) - -@@ -724,6 +737,8 @@ GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_rlock) - #include "locking-selftest-wlock-softirq.h" - GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_wlock) - -+#endif -+ - #undef E1 - #undef E2 - #undef E3 -@@ -757,6 +772,8 @@ GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_wlock) - #include "locking-selftest-spin-hardirq.h" - GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_spin) - -+#ifndef CONFIG_PREEMPT_RT_FULL -+ - #include "locking-selftest-rlock-hardirq.h" - GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_rlock) - -@@ -772,10 +789,14 @@ GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_soft_rlock) - #include "locking-selftest-wlock-softirq.h" - GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_soft_wlock) - -+#endif -+ - #undef E1 - #undef E2 - #undef E3 - -+#ifndef CONFIG_PREEMPT_RT_FULL -+ - /* - * read-lock / write-lock irq inversion. - * -@@ -838,6 +859,10 @@ GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_soft_wlock) - #undef E2 - #undef E3 - -+#endif -+ -+#ifndef CONFIG_PREEMPT_RT_FULL -+ - /* - * read-lock / write-lock recursion that is actually safe. - */ -@@ -876,6 +901,8 @@ GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_soft) - #undef E2 - #undef E3 - -+#endif -+ - /* - * read-lock / write-lock recursion that is unsafe. - */ -@@ -1858,6 +1885,7 @@ void locking_selftest(void) - - printk(" --------------------------------------------------------------------------\n"); - -+#ifndef CONFIG_PREEMPT_RT_FULL - /* - * irq-context testcases: - */ -@@ -1870,6 +1898,28 @@ void locking_selftest(void) - - DO_TESTCASE_6x2("irq read-recursion", irq_read_recursion); - // DO_TESTCASE_6x2B("irq read-recursion #2", irq_read_recursion2); -+#else -+ /* On -rt, we only do hardirq context test for raw spinlock */ -+ DO_TESTCASE_1B("hard-irqs-on + irq-safe-A", irqsafe1_hard_spin, 12); -+ DO_TESTCASE_1B("hard-irqs-on + irq-safe-A", irqsafe1_hard_spin, 21); -+ -+ DO_TESTCASE_1B("hard-safe-A + irqs-on", irqsafe2B_hard_spin, 12); -+ DO_TESTCASE_1B("hard-safe-A + irqs-on", irqsafe2B_hard_spin, 21); -+ -+ DO_TESTCASE_1B("hard-safe-A + unsafe-B #1", irqsafe3_hard_spin, 123); -+ DO_TESTCASE_1B("hard-safe-A + unsafe-B #1", irqsafe3_hard_spin, 132); -+ DO_TESTCASE_1B("hard-safe-A + unsafe-B #1", irqsafe3_hard_spin, 213); -+ DO_TESTCASE_1B("hard-safe-A + unsafe-B #1", irqsafe3_hard_spin, 231); -+ DO_TESTCASE_1B("hard-safe-A + unsafe-B #1", irqsafe3_hard_spin, 312); -+ DO_TESTCASE_1B("hard-safe-A + unsafe-B #1", irqsafe3_hard_spin, 321); -+ -+ DO_TESTCASE_1B("hard-safe-A + unsafe-B #2", irqsafe4_hard_spin, 123); -+ DO_TESTCASE_1B("hard-safe-A + unsafe-B #2", irqsafe4_hard_spin, 132); -+ DO_TESTCASE_1B("hard-safe-A + unsafe-B #2", irqsafe4_hard_spin, 213); -+ DO_TESTCASE_1B("hard-safe-A + unsafe-B #2", irqsafe4_hard_spin, 231); -+ DO_TESTCASE_1B("hard-safe-A + unsafe-B #2", irqsafe4_hard_spin, 312); -+ DO_TESTCASE_1B("hard-safe-A + unsafe-B #2", irqsafe4_hard_spin, 321); -+#endif - - ww_tests(); - -diff --git a/lib/percpu_ida.c b/lib/percpu_ida.c -index 6d40944..822a2c0 100644 ---- a/lib/percpu_ida.c -+++ b/lib/percpu_ida.c -@@ -26,6 +26,9 @@ - #include <linux/string.h> - #include <linux/spinlock.h> - #include <linux/percpu_ida.h> -+#include <linux/locallock.h> -+ -+static DEFINE_LOCAL_IRQ_LOCK(irq_off_lock); - - struct percpu_ida_cpu { - /* -@@ -148,13 +151,13 @@ int percpu_ida_alloc(struct percpu_ida *pool, int state) - unsigned long flags; - int tag; - -- local_irq_save(flags); -+ local_lock_irqsave(irq_off_lock, flags); - tags = this_cpu_ptr(pool->tag_cpu); - - /* Fastpath */ - tag = alloc_local_tag(tags); - if (likely(tag >= 0)) { -- local_irq_restore(flags); -+ local_unlock_irqrestore(irq_off_lock, flags); - return tag; - } - -@@ -173,6 +176,7 @@ int percpu_ida_alloc(struct percpu_ida *pool, int state) - - if (!tags->nr_free) - alloc_global_tags(pool, tags); -+ - if (!tags->nr_free) - steal_tags(pool, tags); - -@@ -184,7 +188,7 @@ int percpu_ida_alloc(struct percpu_ida *pool, int state) - } - - spin_unlock(&pool->lock); -- local_irq_restore(flags); -+ local_unlock_irqrestore(irq_off_lock, flags); - - if (tag >= 0 || state == TASK_RUNNING) - break; -@@ -196,7 +200,7 @@ int percpu_ida_alloc(struct percpu_ida *pool, int state) - - schedule(); - -- local_irq_save(flags); -+ local_lock_irqsave(irq_off_lock, flags); - tags = this_cpu_ptr(pool->tag_cpu); - } - if (state != TASK_RUNNING) -@@ -221,7 +225,7 @@ void percpu_ida_free(struct percpu_ida *pool, unsigned tag) - - BUG_ON(tag >= pool->nr_tags); - -- local_irq_save(flags); -+ local_lock_irqsave(irq_off_lock, flags); - tags = this_cpu_ptr(pool->tag_cpu); - - spin_lock(&tags->lock); -@@ -253,7 +257,7 @@ void percpu_ida_free(struct percpu_ida *pool, unsigned tag) - spin_unlock(&pool->lock); - } - -- local_irq_restore(flags); -+ local_unlock_irqrestore(irq_off_lock, flags); - } - EXPORT_SYMBOL_GPL(percpu_ida_free); - -@@ -345,7 +349,7 @@ int percpu_ida_for_each_free(struct percpu_ida *pool, percpu_ida_cb fn, - struct percpu_ida_cpu *remote; - unsigned cpu, i, err = 0; - -- local_irq_save(flags); -+ local_lock_irqsave(irq_off_lock, flags); - for_each_possible_cpu(cpu) { - remote = per_cpu_ptr(pool->tag_cpu, cpu); - spin_lock(&remote->lock); -@@ -367,7 +371,7 @@ int percpu_ida_for_each_free(struct percpu_ida *pool, percpu_ida_cb fn, - } - spin_unlock(&pool->lock); - out: -- local_irq_restore(flags); -+ local_unlock_irqrestore(irq_off_lock, flags); - return err; - } - EXPORT_SYMBOL_GPL(percpu_ida_for_each_free); -diff --git a/lib/radix-tree.c b/lib/radix-tree.c -index 1624c41..5f53e83 100644 ---- a/lib/radix-tree.c -+++ b/lib/radix-tree.c -@@ -240,13 +240,14 @@ radix_tree_node_alloc(struct radix_tree_root *root) - * succeed in getting a node here (and never reach - * kmem_cache_alloc) - */ -- rtp = this_cpu_ptr(&radix_tree_preloads); -+ rtp = &get_cpu_var(radix_tree_preloads); - if (rtp->nr) { - ret = rtp->nodes; - rtp->nodes = ret->private_data; - ret->private_data = NULL; - rtp->nr--; - } -+ put_cpu_var(radix_tree_preloads); - /* - * Update the allocation stack trace as this is more useful - * for debugging. -@@ -287,6 +288,7 @@ radix_tree_node_free(struct radix_tree_node *node) - call_rcu(&node->rcu_head, radix_tree_node_rcu_free); - } - -+#ifndef CONFIG_PREEMPT_RT_FULL - /* - * Load up this CPU's radix_tree_node buffer with sufficient objects to - * ensure that the addition of a single element in the tree cannot fail. On -@@ -355,6 +357,7 @@ int radix_tree_maybe_preload(gfp_t gfp_mask) - return 0; - } - EXPORT_SYMBOL(radix_tree_maybe_preload); -+#endif - - /* - * Return the maximum key which can be store into a -diff --git a/lib/rbtree.c b/lib/rbtree.c -index 1356454..d15d6c4 100644 ---- a/lib/rbtree.c -+++ b/lib/rbtree.c -@@ -23,6 +23,7 @@ - - #include <linux/rbtree_augmented.h> - #include <linux/export.h> -+#include <linux/rcupdate.h> - - /* - * red-black trees properties: http://en.wikipedia.org/wiki/Rbtree -@@ -590,3 +591,13 @@ struct rb_node *rb_first_postorder(const struct rb_root *root) - return rb_left_deepest_node(root->rb_node); - } - EXPORT_SYMBOL(rb_first_postorder); -+ -+void rb_link_node_rcu(struct rb_node *node, struct rb_node *parent, -+ struct rb_node **rb_link) -+{ -+ node->__rb_parent_color = (unsigned long)parent; -+ node->rb_left = node->rb_right = NULL; -+ -+ rcu_assign_pointer(*rb_link, node); -+} -+EXPORT_SYMBOL(rb_link_node_rcu); -diff --git a/lib/scatterlist.c b/lib/scatterlist.c -index 004fc70..ccc4699 100644 ---- a/lib/scatterlist.c -+++ b/lib/scatterlist.c -@@ -620,7 +620,7 @@ void sg_miter_stop(struct sg_mapping_iter *miter) - flush_kernel_dcache_page(miter->page); - - if (miter->__flags & SG_MITER_ATOMIC) { -- WARN_ON_ONCE(preemptible()); -+ WARN_ON_ONCE(!pagefault_disabled()); - kunmap_atomic(miter->addr); - } else - kunmap(miter->page); -@@ -664,7 +664,7 @@ size_t sg_copy_buffer(struct scatterlist *sgl, unsigned int nents, void *buf, - if (!sg_miter_skip(&miter, skip)) - return false; - -- local_irq_save(flags); -+ local_irq_save_nort(flags); - - while (sg_miter_next(&miter) && offset < buflen) { - unsigned int len; -@@ -681,7 +681,7 @@ size_t sg_copy_buffer(struct scatterlist *sgl, unsigned int nents, void *buf, - - sg_miter_stop(&miter); - -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - return offset; - } - EXPORT_SYMBOL(sg_copy_buffer); -diff --git a/lib/smp_processor_id.c b/lib/smp_processor_id.c -index 1afec32..11fa431 100644 ---- a/lib/smp_processor_id.c -+++ b/lib/smp_processor_id.c -@@ -39,8 +39,9 @@ notrace static unsigned int check_preemption_disabled(const char *what1, - if (!printk_ratelimit()) - goto out_enable; - -- printk(KERN_ERR "BUG: using %s%s() in preemptible [%08x] code: %s/%d\n", -- what1, what2, preempt_count() - 1, current->comm, current->pid); -+ printk(KERN_ERR "BUG: using %s%s() in preemptible [%08x %08x] code: %s/%d\n", -+ what1, what2, preempt_count() - 1, __migrate_disabled(current), -+ current->comm, current->pid); - - print_symbol("caller is %s\n", (long)__builtin_return_address(0)); - dump_stack(); -diff --git a/mm/Kconfig b/mm/Kconfig -index 989f8f3..1df53d6 100644 ---- a/mm/Kconfig -+++ b/mm/Kconfig -@@ -391,7 +391,7 @@ config NOMMU_INITIAL_TRIM_EXCESS - - config TRANSPARENT_HUGEPAGE - bool "Transparent Hugepage Support" -- depends on HAVE_ARCH_TRANSPARENT_HUGEPAGE -+ depends on HAVE_ARCH_TRANSPARENT_HUGEPAGE && !PREEMPT_RT_FULL - select COMPACTION - help - Transparent Hugepages allows the kernel to use huge pages and -diff --git a/mm/backing-dev.c b/mm/backing-dev.c -index 0c6317b..1e6ab5f 100644 ---- a/mm/backing-dev.c -+++ b/mm/backing-dev.c -@@ -457,9 +457,9 @@ void wb_congested_put(struct bdi_writeback_congested *congested) - { - unsigned long flags; - -- local_irq_save(flags); -+ local_irq_save_nort(flags); - if (!atomic_dec_and_lock(&congested->refcnt, &cgwb_lock)) { -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - return; - } - -diff --git a/mm/compaction.c b/mm/compaction.c -index 8fa2540..852cc96 100644 ---- a/mm/compaction.c -+++ b/mm/compaction.c -@@ -1414,10 +1414,12 @@ check_drain: - cc->migrate_pfn & ~((1UL << cc->order) - 1); - - if (cc->last_migrated_pfn < current_block_start) { -- cpu = get_cpu(); -+ cpu = get_cpu_light(); -+ local_lock_irq(swapvec_lock); - lru_add_drain_cpu(cpu); -+ local_unlock_irq(swapvec_lock); - drain_local_pages(zone); -- put_cpu(); -+ put_cpu_light(); - /* No more flushing until we migrate again */ - cc->last_migrated_pfn = 0; - } -diff --git a/mm/filemap.c b/mm/filemap.c -index f2479af..a87b65c 100644 ---- a/mm/filemap.c -+++ b/mm/filemap.c -@@ -169,7 +169,9 @@ static void page_cache_tree_delete(struct address_space *mapping, - if (!workingset_node_pages(node) && - list_empty(&node->private_list)) { - node->private_data = mapping; -- list_lru_add(&workingset_shadow_nodes, &node->private_list); -+ local_lock(workingset_shadow_lock); -+ list_lru_add(&__workingset_shadow_nodes, &node->private_list); -+ local_unlock(workingset_shadow_lock); - } - } - -@@ -618,9 +620,12 @@ static int page_cache_tree_insert(struct address_space *mapping, - * node->private_list is protected by - * mapping->tree_lock. - */ -- if (!list_empty(&node->private_list)) -- list_lru_del(&workingset_shadow_nodes, -+ if (!list_empty(&node->private_list)) { -+ local_lock(workingset_shadow_lock); -+ list_lru_del(&__workingset_shadow_nodes, - &node->private_list); -+ local_unlock(workingset_shadow_lock); -+ } - } - return 0; - } -diff --git a/mm/highmem.c b/mm/highmem.c -index 123bcd3..16e8cf2 100644 ---- a/mm/highmem.c -+++ b/mm/highmem.c -@@ -29,10 +29,11 @@ - #include <linux/kgdb.h> - #include <asm/tlbflush.h> - -- -+#ifndef CONFIG_PREEMPT_RT_FULL - #if defined(CONFIG_HIGHMEM) || defined(CONFIG_X86_32) - DEFINE_PER_CPU(int, __kmap_atomic_idx); - #endif -+#endif - - /* - * Virtual_count is not a pure "count". -@@ -107,8 +108,9 @@ static inline wait_queue_head_t *get_pkmap_wait_queue_head(unsigned int color) - unsigned long totalhigh_pages __read_mostly; - EXPORT_SYMBOL(totalhigh_pages); - -- -+#ifndef CONFIG_PREEMPT_RT_FULL - EXPORT_PER_CPU_SYMBOL(__kmap_atomic_idx); -+#endif - - unsigned int nr_free_highpages (void) - { -diff --git a/mm/memcontrol.c b/mm/memcontrol.c -index fe787f5..74c500e 100644 ---- a/mm/memcontrol.c -+++ b/mm/memcontrol.c -@@ -67,6 +67,7 @@ - #include <net/sock.h> - #include <net/ip.h> - #include "slab.h" -+#include <linux/locallock.h> - - #include <asm/uaccess.h> - -@@ -92,6 +93,8 @@ int do_swap_account __read_mostly; - #define do_swap_account 0 - #endif - -+static DEFINE_LOCAL_IRQ_LOCK(event_lock); -+ - /* Whether legacy memory+swap accounting is active */ - static bool do_memsw_account(void) - { -@@ -1825,14 +1828,17 @@ static void drain_local_stock(struct work_struct *dummy) - */ - static void refill_stock(struct mem_cgroup *memcg, unsigned int nr_pages) - { -- struct memcg_stock_pcp *stock = &get_cpu_var(memcg_stock); -+ struct memcg_stock_pcp *stock; -+ int cpu = get_cpu_light(); -+ -+ stock = &per_cpu(memcg_stock, cpu); - - if (stock->cached != memcg) { /* reset if necessary */ - drain_stock(stock); - stock->cached = memcg; - } - stock->nr_pages += nr_pages; -- put_cpu_var(memcg_stock); -+ put_cpu_light(); - } - - /* -@@ -1848,7 +1854,7 @@ static void drain_all_stock(struct mem_cgroup *root_memcg) - return; - /* Notify other cpus that system-wide "drain" is running */ - get_online_cpus(); -- curcpu = get_cpu(); -+ curcpu = get_cpu_light(); - for_each_online_cpu(cpu) { - struct memcg_stock_pcp *stock = &per_cpu(memcg_stock, cpu); - struct mem_cgroup *memcg; -@@ -1865,7 +1871,7 @@ static void drain_all_stock(struct mem_cgroup *root_memcg) - schedule_work_on(cpu, &stock->work); - } - } -- put_cpu(); -+ put_cpu_light(); - put_online_cpus(); - mutex_unlock(&percpu_charge_mutex); - } -@@ -4484,12 +4490,12 @@ static int mem_cgroup_move_account(struct page *page, - - ret = 0; - -- local_irq_disable(); -+ local_lock_irq(event_lock); - mem_cgroup_charge_statistics(to, page, compound, nr_pages); - memcg_check_events(to, page); - mem_cgroup_charge_statistics(from, page, compound, -nr_pages); - memcg_check_events(from, page); -- local_irq_enable(); -+ local_unlock_irq(event_lock); - out_unlock: - unlock_page(page); - out: -@@ -5339,10 +5345,10 @@ void mem_cgroup_commit_charge(struct page *page, struct mem_cgroup *memcg, - - commit_charge(page, memcg, lrucare); - -- local_irq_disable(); -+ local_lock_irq(event_lock); - mem_cgroup_charge_statistics(memcg, page, compound, nr_pages); - memcg_check_events(memcg, page); -- local_irq_enable(); -+ local_unlock_irq(event_lock); - - if (do_memsw_account() && PageSwapCache(page)) { - swp_entry_t entry = { .val = page_private(page) }; -@@ -5394,14 +5400,14 @@ static void uncharge_batch(struct mem_cgroup *memcg, unsigned long pgpgout, - memcg_oom_recover(memcg); - } - -- local_irq_save(flags); -+ local_lock_irqsave(event_lock, flags); - __this_cpu_sub(memcg->stat->count[MEM_CGROUP_STAT_RSS], nr_anon); - __this_cpu_sub(memcg->stat->count[MEM_CGROUP_STAT_CACHE], nr_file); - __this_cpu_sub(memcg->stat->count[MEM_CGROUP_STAT_RSS_HUGE], nr_huge); - __this_cpu_add(memcg->stat->events[MEM_CGROUP_EVENTS_PGPGOUT], pgpgout); - __this_cpu_add(memcg->stat->nr_page_events, nr_pages); - memcg_check_events(memcg, dummy_page); -- local_irq_restore(flags); -+ local_unlock_irqrestore(event_lock, flags); - - if (!mem_cgroup_is_root(memcg)) - css_put_many(&memcg->css, nr_pages); -@@ -5719,6 +5725,7 @@ void mem_cgroup_swapout(struct page *page, swp_entry_t entry) - { - struct mem_cgroup *memcg; - unsigned short oldid; -+ unsigned long flags; - - VM_BUG_ON_PAGE(PageLRU(page), page); - VM_BUG_ON_PAGE(page_count(page), page); -@@ -5747,9 +5754,13 @@ void mem_cgroup_swapout(struct page *page, swp_entry_t entry) - * important here to have the interrupts disabled because it is the - * only synchronisation we have for udpating the per-CPU variables. - */ -+ local_lock_irqsave(event_lock, flags); -+#ifndef CONFIG_PREEMPT_RT_BASE - VM_BUG_ON(!irqs_disabled()); -+#endif - mem_cgroup_charge_statistics(memcg, page, false, -1); - memcg_check_events(memcg, page); -+ local_unlock_irqrestore(event_lock, flags); - } - - /* -diff --git a/mm/mmu_context.c b/mm/mmu_context.c -index f802c2d..b1b6f23 100644 ---- a/mm/mmu_context.c -+++ b/mm/mmu_context.c -@@ -23,6 +23,7 @@ void use_mm(struct mm_struct *mm) - struct task_struct *tsk = current; - - task_lock(tsk); -+ preempt_disable_rt(); - active_mm = tsk->active_mm; - if (active_mm != mm) { - atomic_inc(&mm->mm_count); -@@ -30,6 +31,7 @@ void use_mm(struct mm_struct *mm) - } - tsk->mm = mm; - switch_mm(active_mm, mm, tsk); -+ preempt_enable_rt(); - task_unlock(tsk); - #ifdef finish_arch_post_lock_switch - finish_arch_post_lock_switch(); -diff --git a/mm/page_alloc.c b/mm/page_alloc.c -index c1069ef..2ec2148 100644 ---- a/mm/page_alloc.c -+++ b/mm/page_alloc.c -@@ -61,6 +61,7 @@ - #include <linux/page_ext.h> - #include <linux/hugetlb.h> - #include <linux/sched/rt.h> -+#include <linux/locallock.h> - #include <linux/page_owner.h> - #include <linux/kthread.h> - -@@ -275,6 +276,18 @@ EXPORT_SYMBOL(nr_node_ids); - EXPORT_SYMBOL(nr_online_nodes); - #endif - -+static DEFINE_LOCAL_IRQ_LOCK(pa_lock); -+ -+#ifdef CONFIG_PREEMPT_RT_BASE -+# define cpu_lock_irqsave(cpu, flags) \ -+ local_lock_irqsave_on(pa_lock, flags, cpu) -+# define cpu_unlock_irqrestore(cpu, flags) \ -+ local_unlock_irqrestore_on(pa_lock, flags, cpu) -+#else -+# define cpu_lock_irqsave(cpu, flags) local_irq_save(flags) -+# define cpu_unlock_irqrestore(cpu, flags) local_irq_restore(flags) -+#endif -+ - int page_group_by_mobility_disabled __read_mostly; - - #ifdef CONFIG_DEFERRED_STRUCT_PAGE_INIT -@@ -814,7 +827,7 @@ static inline int free_pages_check(struct page *page) - } - - /* -- * Frees a number of pages from the PCP lists -+ * Frees a number of pages which have been collected from the pcp lists. - * Assumes all pages on list are in same zone, and of same order. - * count is the number of pages to free. - * -@@ -825,18 +838,53 @@ static inline int free_pages_check(struct page *page) - * pinned" detection logic. - */ - static void free_pcppages_bulk(struct zone *zone, int count, -- struct per_cpu_pages *pcp) -+ struct list_head *list) - { -- int migratetype = 0; -- int batch_free = 0; - int to_free = count; - unsigned long nr_scanned; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&zone->lock, flags); - -- spin_lock(&zone->lock); - nr_scanned = zone_page_state(zone, NR_PAGES_SCANNED); - if (nr_scanned) - __mod_zone_page_state(zone, NR_PAGES_SCANNED, -nr_scanned); - -+ while (!list_empty(list)) { -+ struct page *page = list_first_entry(list, struct page, lru); -+ int mt; /* migratetype of the to-be-freed page */ -+ -+ /* must delete as __free_one_page list manipulates */ -+ list_del(&page->lru); -+ -+ mt = get_pcppage_migratetype(page); -+ /* MIGRATE_ISOLATE page should not go to pcplists */ -+ VM_BUG_ON_PAGE(is_migrate_isolate(mt), page); -+ /* Pageblock could have been isolated meanwhile */ -+ if (unlikely(has_isolate_pageblock(zone))) -+ mt = get_pageblock_migratetype(page); -+ -+ __free_one_page(page, page_to_pfn(page), zone, 0, mt); -+ trace_mm_page_pcpu_drain(page, 0, mt); -+ to_free--; -+ } -+ WARN_ON(to_free != 0); -+ spin_unlock_irqrestore(&zone->lock, flags); -+} -+ -+/* -+ * Moves a number of pages from the PCP lists to free list which -+ * is freed outside of the locked region. -+ * -+ * Assumes all pages on list are in same zone, and of same order. -+ * count is the number of pages to free. -+ */ -+static void isolate_pcp_pages(int to_free, struct per_cpu_pages *src, -+ struct list_head *dst) -+{ -+ int migratetype = 0; -+ int batch_free = 0; -+ - while (to_free) { - struct page *page; - struct list_head *list; -@@ -852,7 +900,7 @@ static void free_pcppages_bulk(struct zone *zone, int count, - batch_free++; - if (++migratetype == MIGRATE_PCPTYPES) - migratetype = 0; -- list = &pcp->lists[migratetype]; -+ list = &src->lists[migratetype]; - } while (list_empty(list)); - - /* This is the only non-empty list. Free them all. */ -@@ -860,24 +908,12 @@ static void free_pcppages_bulk(struct zone *zone, int count, - batch_free = to_free; - - do { -- int mt; /* migratetype of the to-be-freed page */ -- - page = list_last_entry(list, struct page, lru); -- /* must delete as __free_one_page list manipulates */ - list_del(&page->lru); - -- mt = get_pcppage_migratetype(page); -- /* MIGRATE_ISOLATE page should not go to pcplists */ -- VM_BUG_ON_PAGE(is_migrate_isolate(mt), page); -- /* Pageblock could have been isolated meanwhile */ -- if (unlikely(has_isolate_pageblock(zone))) -- mt = get_pageblock_migratetype(page); -- -- __free_one_page(page, page_to_pfn(page), zone, 0, mt); -- trace_mm_page_pcpu_drain(page, 0, mt); -+ list_add(&page->lru, dst); - } while (--to_free && --batch_free && !list_empty(list)); - } -- spin_unlock(&zone->lock); - } - - static void free_one_page(struct zone *zone, -@@ -886,7 +922,9 @@ static void free_one_page(struct zone *zone, - int migratetype) - { - unsigned long nr_scanned; -- spin_lock(&zone->lock); -+ unsigned long flags; -+ -+ spin_lock_irqsave(&zone->lock, flags); - nr_scanned = zone_page_state(zone, NR_PAGES_SCANNED); - if (nr_scanned) - __mod_zone_page_state(zone, NR_PAGES_SCANNED, -nr_scanned); -@@ -896,7 +934,7 @@ static void free_one_page(struct zone *zone, - migratetype = get_pfnblock_migratetype(page, pfn); - } - __free_one_page(page, pfn, zone, order, migratetype); -- spin_unlock(&zone->lock); -+ spin_unlock_irqrestore(&zone->lock, flags); - } - - static int free_tail_pages_check(struct page *head_page, struct page *page) -@@ -1070,10 +1108,10 @@ static void __free_pages_ok(struct page *page, unsigned int order) - return; - - migratetype = get_pfnblock_migratetype(page, pfn); -- local_irq_save(flags); -+ local_lock_irqsave(pa_lock, flags); - __count_vm_events(PGFREE, 1 << order); - free_one_page(page_zone(page), page, pfn, order, migratetype); -- local_irq_restore(flags); -+ local_unlock_irqrestore(pa_lock, flags); - } - - static void __init __free_pages_boot_core(struct page *page, -@@ -2015,16 +2053,18 @@ static int rmqueue_bulk(struct zone *zone, unsigned int order, - void drain_zone_pages(struct zone *zone, struct per_cpu_pages *pcp) - { - unsigned long flags; -+ LIST_HEAD(dst); - int to_drain, batch; - -- local_irq_save(flags); -+ local_lock_irqsave(pa_lock, flags); - batch = READ_ONCE(pcp->batch); - to_drain = min(pcp->count, batch); - if (to_drain > 0) { -- free_pcppages_bulk(zone, to_drain, pcp); -+ isolate_pcp_pages(to_drain, pcp, &dst); - pcp->count -= to_drain; - } -- local_irq_restore(flags); -+ local_unlock_irqrestore(pa_lock, flags); -+ free_pcppages_bulk(zone, to_drain, &dst); - } - #endif - -@@ -2040,16 +2080,21 @@ static void drain_pages_zone(unsigned int cpu, struct zone *zone) - unsigned long flags; - struct per_cpu_pageset *pset; - struct per_cpu_pages *pcp; -+ LIST_HEAD(dst); -+ int count; - -- local_irq_save(flags); -+ cpu_lock_irqsave(cpu, flags); - pset = per_cpu_ptr(zone->pageset, cpu); - - pcp = &pset->pcp; -- if (pcp->count) { -- free_pcppages_bulk(zone, pcp->count, pcp); -+ count = pcp->count; -+ if (count) { -+ isolate_pcp_pages(count, pcp, &dst); - pcp->count = 0; - } -- local_irq_restore(flags); -+ cpu_unlock_irqrestore(cpu, flags); -+ if (count) -+ free_pcppages_bulk(zone, count, &dst); - } - - /* -@@ -2135,8 +2180,17 @@ void drain_all_pages(struct zone *zone) - else - cpumask_clear_cpu(cpu, &cpus_with_pcps); - } -+#ifndef CONFIG_PREEMPT_RT_BASE - on_each_cpu_mask(&cpus_with_pcps, (smp_call_func_t) drain_local_pages, - zone, 1); -+#else -+ for_each_cpu(cpu, &cpus_with_pcps) { -+ if (zone) -+ drain_pages_zone(cpu, zone); -+ else -+ drain_pages(cpu); -+ } -+#endif - } - - #ifdef CONFIG_HIBERNATION -@@ -2192,7 +2246,7 @@ void free_hot_cold_page(struct page *page, bool cold) - - migratetype = get_pfnblock_migratetype(page, pfn); - set_pcppage_migratetype(page, migratetype); -- local_irq_save(flags); -+ local_lock_irqsave(pa_lock, flags); - __count_vm_event(PGFREE); - - /* -@@ -2218,12 +2272,17 @@ void free_hot_cold_page(struct page *page, bool cold) - pcp->count++; - if (pcp->count >= pcp->high) { - unsigned long batch = READ_ONCE(pcp->batch); -- free_pcppages_bulk(zone, batch, pcp); -+ LIST_HEAD(dst); -+ -+ isolate_pcp_pages(batch, pcp, &dst); - pcp->count -= batch; -+ local_unlock_irqrestore(pa_lock, flags); -+ free_pcppages_bulk(zone, batch, &dst); -+ return; - } - - out: -- local_irq_restore(flags); -+ local_unlock_irqrestore(pa_lock, flags); - } - - /* -@@ -2358,7 +2417,7 @@ struct page *buffered_rmqueue(struct zone *preferred_zone, - struct per_cpu_pages *pcp; - struct list_head *list; - -- local_irq_save(flags); -+ local_lock_irqsave(pa_lock, flags); - pcp = &this_cpu_ptr(zone->pageset)->pcp; - list = &pcp->lists[migratetype]; - if (list_empty(list)) { -@@ -2382,7 +2441,7 @@ struct page *buffered_rmqueue(struct zone *preferred_zone, - * allocate greater than order-1 page units with __GFP_NOFAIL. - */ - WARN_ON_ONCE((gfp_flags & __GFP_NOFAIL) && (order > 1)); -- spin_lock_irqsave(&zone->lock, flags); -+ local_spin_lock_irqsave(pa_lock, &zone->lock, flags); - - page = NULL; - if (alloc_flags & ALLOC_HARDER) { -@@ -2392,11 +2451,13 @@ struct page *buffered_rmqueue(struct zone *preferred_zone, - } - if (!page) - page = __rmqueue(zone, order, migratetype); -- spin_unlock(&zone->lock); -- if (!page) -+ if (!page) { -+ spin_unlock(&zone->lock); - goto failed; -+ } - __mod_zone_freepage_state(zone, -(1 << order), - get_pcppage_migratetype(page)); -+ spin_unlock(&zone->lock); - } - - __mod_zone_page_state(zone, NR_ALLOC_BATCH, -(1 << order)); -@@ -2406,13 +2467,13 @@ struct page *buffered_rmqueue(struct zone *preferred_zone, - - __count_zone_vm_events(PGALLOC, zone, 1 << order); - zone_statistics(preferred_zone, zone, gfp_flags); -- local_irq_restore(flags); -+ local_unlock_irqrestore(pa_lock, flags); - - VM_BUG_ON_PAGE(bad_range(zone, page), page); - return page; - - failed: -- local_irq_restore(flags); -+ local_unlock_irqrestore(pa_lock, flags); - return NULL; - } - -@@ -6213,7 +6274,9 @@ static int page_alloc_cpu_notify(struct notifier_block *self, - int cpu = (unsigned long)hcpu; - - if (action == CPU_DEAD || action == CPU_DEAD_FROZEN) { -+ local_lock_irq_on(swapvec_lock, cpu); - lru_add_drain_cpu(cpu); -+ local_unlock_irq_on(swapvec_lock, cpu); - drain_pages(cpu); - - /* -@@ -6239,6 +6302,7 @@ static int page_alloc_cpu_notify(struct notifier_block *self, - void __init page_alloc_init(void) - { - hotcpu_notifier(page_alloc_cpu_notify, 0); -+ local_irq_lock_init(pa_lock); - } - - /* -@@ -7163,7 +7227,7 @@ void zone_pcp_reset(struct zone *zone) - struct per_cpu_pageset *pset; - - /* avoid races with drain_pages() */ -- local_irq_save(flags); -+ local_lock_irqsave(pa_lock, flags); - if (zone->pageset != &boot_pageset) { - for_each_online_cpu(cpu) { - pset = per_cpu_ptr(zone->pageset, cpu); -@@ -7172,7 +7236,7 @@ void zone_pcp_reset(struct zone *zone) - free_percpu(zone->pageset); - zone->pageset = &boot_pageset; - } -- local_irq_restore(flags); -+ local_unlock_irqrestore(pa_lock, flags); - } - - #ifdef CONFIG_MEMORY_HOTREMOVE -diff --git a/mm/slab.h b/mm/slab.h -index 5969769..b85c60f 100644 ---- a/mm/slab.h -+++ b/mm/slab.h -@@ -415,7 +415,11 @@ static inline void slab_post_alloc_hook(struct kmem_cache *s, gfp_t flags, - * The slab lists for all objects. - */ - struct kmem_cache_node { -+#ifdef CONFIG_SLUB -+ raw_spinlock_t list_lock; -+#else - spinlock_t list_lock; -+#endif - - #ifdef CONFIG_SLAB - struct list_head slabs_partial; /* partial list first, better asm code */ -diff --git a/mm/slub.c b/mm/slub.c -index 4dbb109e..2d10cc5 100644 ---- a/mm/slub.c -+++ b/mm/slub.c -@@ -1143,7 +1143,7 @@ static noinline int free_debug_processing( - unsigned long uninitialized_var(flags); - int ret = 0; - -- spin_lock_irqsave(&n->list_lock, flags); -+ raw_spin_lock_irqsave(&n->list_lock, flags); - slab_lock(page); - - if (s->flags & SLAB_CONSISTENCY_CHECKS) { -@@ -1178,7 +1178,7 @@ out: - bulk_cnt, cnt); - - slab_unlock(page); -- spin_unlock_irqrestore(&n->list_lock, flags); -+ raw_spin_unlock_irqrestore(&n->list_lock, flags); - if (!ret) - slab_fix(s, "Object at 0x%p not freed", object); - return ret; -@@ -1306,6 +1306,12 @@ static inline void dec_slabs_node(struct kmem_cache *s, int node, - - #endif /* CONFIG_SLUB_DEBUG */ - -+struct slub_free_list { -+ raw_spinlock_t lock; -+ struct list_head list; -+}; -+static DEFINE_PER_CPU(struct slub_free_list, slub_free_list); -+ - /* - * Hooks for other subsystems that check memory allocations. In a typical - * production configuration these hooks all should produce no code at all. -@@ -1412,10 +1418,17 @@ static struct page *allocate_slab(struct kmem_cache *s, gfp_t flags, int node) - gfp_t alloc_gfp; - void *start, *p; - int idx, order; -+ bool enableirqs = false; - - flags &= gfp_allowed_mask; - - if (gfpflags_allow_blocking(flags)) -+ enableirqs = true; -+#ifdef CONFIG_PREEMPT_RT_FULL -+ if (system_state == SYSTEM_RUNNING) -+ enableirqs = true; -+#endif -+ if (enableirqs) - local_irq_enable(); - - flags |= s->allocflags; -@@ -1486,7 +1499,7 @@ static struct page *allocate_slab(struct kmem_cache *s, gfp_t flags, int node) - page->frozen = 1; - - out: -- if (gfpflags_allow_blocking(flags)) -+ if (enableirqs) - local_irq_disable(); - if (!page) - return NULL; -@@ -1543,6 +1556,16 @@ static void __free_slab(struct kmem_cache *s, struct page *page) - __free_pages(page, order); - } - -+static void free_delayed(struct list_head *h) -+{ -+ while(!list_empty(h)) { -+ struct page *page = list_first_entry(h, struct page, lru); -+ -+ list_del(&page->lru); -+ __free_slab(page->slab_cache, page); -+ } -+} -+ - #define need_reserve_slab_rcu \ - (sizeof(((struct page *)NULL)->lru) < sizeof(struct rcu_head)) - -@@ -1574,6 +1597,12 @@ static void free_slab(struct kmem_cache *s, struct page *page) - } - - call_rcu(head, rcu_free_slab); -+ } else if (irqs_disabled()) { -+ struct slub_free_list *f = this_cpu_ptr(&slub_free_list); -+ -+ raw_spin_lock(&f->lock); -+ list_add(&page->lru, &f->list); -+ raw_spin_unlock(&f->lock); - } else - __free_slab(s, page); - } -@@ -1681,7 +1710,7 @@ static void *get_partial_node(struct kmem_cache *s, struct kmem_cache_node *n, - if (!n || !n->nr_partial) - return NULL; - -- spin_lock(&n->list_lock); -+ raw_spin_lock(&n->list_lock); - list_for_each_entry_safe(page, page2, &n->partial, lru) { - void *t; - -@@ -1706,7 +1735,7 @@ static void *get_partial_node(struct kmem_cache *s, struct kmem_cache_node *n, - break; - - } -- spin_unlock(&n->list_lock); -+ raw_spin_unlock(&n->list_lock); - return object; - } - -@@ -1952,7 +1981,7 @@ redo: - * that acquire_slab() will see a slab page that - * is frozen - */ -- spin_lock(&n->list_lock); -+ raw_spin_lock(&n->list_lock); - } - } else { - m = M_FULL; -@@ -1963,7 +1992,7 @@ redo: - * slabs from diagnostic functions will not see - * any frozen slabs. - */ -- spin_lock(&n->list_lock); -+ raw_spin_lock(&n->list_lock); - } - } - -@@ -1998,7 +2027,7 @@ redo: - goto redo; - - if (lock) -- spin_unlock(&n->list_lock); -+ raw_spin_unlock(&n->list_lock); - - if (m == M_FREE) { - stat(s, DEACTIVATE_EMPTY); -@@ -2030,10 +2059,10 @@ static void unfreeze_partials(struct kmem_cache *s, - n2 = get_node(s, page_to_nid(page)); - if (n != n2) { - if (n) -- spin_unlock(&n->list_lock); -+ raw_spin_unlock(&n->list_lock); - - n = n2; -- spin_lock(&n->list_lock); -+ raw_spin_lock(&n->list_lock); - } - - do { -@@ -2062,7 +2091,7 @@ static void unfreeze_partials(struct kmem_cache *s, - } - - if (n) -- spin_unlock(&n->list_lock); -+ raw_spin_unlock(&n->list_lock); - - while (discard_page) { - page = discard_page; -@@ -2101,14 +2130,21 @@ static void put_cpu_partial(struct kmem_cache *s, struct page *page, int drain) - pobjects = oldpage->pobjects; - pages = oldpage->pages; - if (drain && pobjects > s->cpu_partial) { -+ struct slub_free_list *f; - unsigned long flags; -+ LIST_HEAD(tofree); - /* - * partial array is full. Move the existing - * set to the per node partial list. - */ - local_irq_save(flags); - unfreeze_partials(s, this_cpu_ptr(s->cpu_slab)); -+ f = this_cpu_ptr(&slub_free_list); -+ raw_spin_lock(&f->lock); -+ list_splice_init(&f->list, &tofree); -+ raw_spin_unlock(&f->lock); - local_irq_restore(flags); -+ free_delayed(&tofree); - oldpage = NULL; - pobjects = 0; - pages = 0; -@@ -2180,7 +2216,22 @@ static bool has_cpu_slab(int cpu, void *info) - - static void flush_all(struct kmem_cache *s) - { -+ LIST_HEAD(tofree); -+ int cpu; -+ - on_each_cpu_cond(has_cpu_slab, flush_cpu_slab, s, 1, GFP_ATOMIC); -+ for_each_online_cpu(cpu) { -+ struct slub_free_list *f; -+ -+ if (!has_cpu_slab(cpu, s)) -+ continue; -+ -+ f = &per_cpu(slub_free_list, cpu); -+ raw_spin_lock_irq(&f->lock); -+ list_splice_init(&f->list, &tofree); -+ raw_spin_unlock_irq(&f->lock); -+ free_delayed(&tofree); -+ } - } - - /* -@@ -2216,10 +2267,10 @@ static unsigned long count_partial(struct kmem_cache_node *n, - unsigned long x = 0; - struct page *page; - -- spin_lock_irqsave(&n->list_lock, flags); -+ raw_spin_lock_irqsave(&n->list_lock, flags); - list_for_each_entry(page, &n->partial, lru) - x += get_count(page); -- spin_unlock_irqrestore(&n->list_lock, flags); -+ raw_spin_unlock_irqrestore(&n->list_lock, flags); - return x; - } - #endif /* CONFIG_SLUB_DEBUG || CONFIG_SYSFS */ -@@ -2357,8 +2408,10 @@ static inline void *get_freelist(struct kmem_cache *s, struct page *page) - * already disabled (which is the case for bulk allocation). - */ - static void *___slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node, -- unsigned long addr, struct kmem_cache_cpu *c) -+ unsigned long addr, struct kmem_cache_cpu *c, -+ struct list_head *to_free) - { -+ struct slub_free_list *f; - void *freelist; - struct page *page; - -@@ -2418,6 +2471,13 @@ load_freelist: - VM_BUG_ON(!c->page->frozen); - c->freelist = get_freepointer(s, freelist); - c->tid = next_tid(c->tid); -+ -+out: -+ f = this_cpu_ptr(&slub_free_list); -+ raw_spin_lock(&f->lock); -+ list_splice_init(&f->list, to_free); -+ raw_spin_unlock(&f->lock); -+ - return freelist; - - new_slab: -@@ -2449,7 +2509,7 @@ new_slab: - deactivate_slab(s, page, get_freepointer(s, freelist)); - c->page = NULL; - c->freelist = NULL; -- return freelist; -+ goto out; - } - - /* -@@ -2461,6 +2521,7 @@ static void *__slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node, - { - void *p; - unsigned long flags; -+ LIST_HEAD(tofree); - - local_irq_save(flags); - #ifdef CONFIG_PREEMPT -@@ -2472,8 +2533,9 @@ static void *__slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node, - c = this_cpu_ptr(s->cpu_slab); - #endif - -- p = ___slab_alloc(s, gfpflags, node, addr, c); -+ p = ___slab_alloc(s, gfpflags, node, addr, c, &tofree); - local_irq_restore(flags); -+ free_delayed(&tofree); - return p; - } - -@@ -2659,7 +2721,7 @@ static void __slab_free(struct kmem_cache *s, struct page *page, - - do { - if (unlikely(n)) { -- spin_unlock_irqrestore(&n->list_lock, flags); -+ raw_spin_unlock_irqrestore(&n->list_lock, flags); - n = NULL; - } - prior = page->freelist; -@@ -2691,7 +2753,7 @@ static void __slab_free(struct kmem_cache *s, struct page *page, - * Otherwise the list_lock will synchronize with - * other processors updating the list of slabs. - */ -- spin_lock_irqsave(&n->list_lock, flags); -+ raw_spin_lock_irqsave(&n->list_lock, flags); - - } - } -@@ -2733,7 +2795,7 @@ static void __slab_free(struct kmem_cache *s, struct page *page, - add_partial(n, page, DEACTIVATE_TO_TAIL); - stat(s, FREE_ADD_PARTIAL); - } -- spin_unlock_irqrestore(&n->list_lock, flags); -+ raw_spin_unlock_irqrestore(&n->list_lock, flags); - return; - - slab_empty: -@@ -2748,7 +2810,7 @@ slab_empty: - remove_full(s, n, page); - } - -- spin_unlock_irqrestore(&n->list_lock, flags); -+ raw_spin_unlock_irqrestore(&n->list_lock, flags); - stat(s, FREE_SLAB); - discard_slab(s, page); - } -@@ -2935,6 +2997,7 @@ int kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t size, - void **p) - { - struct kmem_cache_cpu *c; -+ LIST_HEAD(to_free); - int i; - - /* memcg and kmem_cache debug support */ -@@ -2958,7 +3021,7 @@ int kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t size, - * of re-populating per CPU c->freelist - */ - p[i] = ___slab_alloc(s, flags, NUMA_NO_NODE, -- _RET_IP_, c); -+ _RET_IP_, c, &to_free); - if (unlikely(!p[i])) - goto error; - -@@ -2970,6 +3033,7 @@ int kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t size, - } - c->tid = next_tid(c->tid); - local_irq_enable(); -+ free_delayed(&to_free); - - /* Clear memory outside IRQ disabled fastpath loop */ - if (unlikely(flags & __GFP_ZERO)) { -@@ -3117,7 +3181,7 @@ static void - init_kmem_cache_node(struct kmem_cache_node *n) - { - n->nr_partial = 0; -- spin_lock_init(&n->list_lock); -+ raw_spin_lock_init(&n->list_lock); - INIT_LIST_HEAD(&n->partial); - #ifdef CONFIG_SLUB_DEBUG - atomic_long_set(&n->nr_slabs, 0); -@@ -3450,6 +3514,10 @@ static void list_slab_objects(struct kmem_cache *s, struct page *page, - const char *text) - { - #ifdef CONFIG_SLUB_DEBUG -+#ifdef CONFIG_PREEMPT_RT_BASE -+ /* XXX move out of irq-off section */ -+ slab_err(s, page, text, s->name); -+#else - void *addr = page_address(page); - void *p; - unsigned long *map = kzalloc(BITS_TO_LONGS(page->objects) * -@@ -3470,6 +3538,7 @@ static void list_slab_objects(struct kmem_cache *s, struct page *page, - slab_unlock(page); - kfree(map); - #endif -+#endif - } - - /* -@@ -3482,7 +3551,7 @@ static void free_partial(struct kmem_cache *s, struct kmem_cache_node *n) - struct page *page, *h; - - BUG_ON(irqs_disabled()); -- spin_lock_irq(&n->list_lock); -+ raw_spin_lock_irq(&n->list_lock); - list_for_each_entry_safe(page, h, &n->partial, lru) { - if (!page->inuse) { - remove_partial(n, page); -@@ -3492,7 +3561,7 @@ static void free_partial(struct kmem_cache *s, struct kmem_cache_node *n) - "Objects remaining in %s on __kmem_cache_shutdown()"); - } - } -- spin_unlock_irq(&n->list_lock); -+ raw_spin_unlock_irq(&n->list_lock); - } - - /* -@@ -3706,7 +3775,7 @@ int __kmem_cache_shrink(struct kmem_cache *s, bool deactivate) - for (i = 0; i < SHRINK_PROMOTE_MAX; i++) - INIT_LIST_HEAD(promote + i); - -- spin_lock_irqsave(&n->list_lock, flags); -+ raw_spin_lock_irqsave(&n->list_lock, flags); - - /* - * Build lists of slabs to discard or promote. -@@ -3737,7 +3806,7 @@ int __kmem_cache_shrink(struct kmem_cache *s, bool deactivate) - for (i = SHRINK_PROMOTE_MAX - 1; i >= 0; i--) - list_splice(promote + i, &n->partial); - -- spin_unlock_irqrestore(&n->list_lock, flags); -+ raw_spin_unlock_irqrestore(&n->list_lock, flags); - - /* Release empty slabs */ - list_for_each_entry_safe(page, t, &discard, lru) -@@ -3913,6 +3982,12 @@ void __init kmem_cache_init(void) - { - static __initdata struct kmem_cache boot_kmem_cache, - boot_kmem_cache_node; -+ int cpu; -+ -+ for_each_possible_cpu(cpu) { -+ raw_spin_lock_init(&per_cpu(slub_free_list, cpu).lock); -+ INIT_LIST_HEAD(&per_cpu(slub_free_list, cpu).list); -+ } - - if (debug_guardpage_minorder()) - slub_max_order = 0; -@@ -4156,7 +4231,7 @@ static int validate_slab_node(struct kmem_cache *s, - struct page *page; - unsigned long flags; - -- spin_lock_irqsave(&n->list_lock, flags); -+ raw_spin_lock_irqsave(&n->list_lock, flags); - - list_for_each_entry(page, &n->partial, lru) { - validate_slab_slab(s, page, map); -@@ -4178,7 +4253,7 @@ static int validate_slab_node(struct kmem_cache *s, - s->name, count, atomic_long_read(&n->nr_slabs)); - - out: -- spin_unlock_irqrestore(&n->list_lock, flags); -+ raw_spin_unlock_irqrestore(&n->list_lock, flags); - return count; - } - -@@ -4366,12 +4441,12 @@ static int list_locations(struct kmem_cache *s, char *buf, - if (!atomic_long_read(&n->nr_slabs)) - continue; - -- spin_lock_irqsave(&n->list_lock, flags); -+ raw_spin_lock_irqsave(&n->list_lock, flags); - list_for_each_entry(page, &n->partial, lru) - process_slab(&t, s, page, alloc, map); - list_for_each_entry(page, &n->full, lru) - process_slab(&t, s, page, alloc, map); -- spin_unlock_irqrestore(&n->list_lock, flags); -+ raw_spin_unlock_irqrestore(&n->list_lock, flags); - } - - for (i = 0; i < t.count; i++) { -diff --git a/mm/swap.c b/mm/swap.c -index 03aacbc..8927472 100644 ---- a/mm/swap.c -+++ b/mm/swap.c -@@ -32,6 +32,7 @@ - #include <linux/memcontrol.h> - #include <linux/gfp.h> - #include <linux/uio.h> -+#include <linux/locallock.h> - #include <linux/hugetlb.h> - #include <linux/page_idle.h> - -@@ -48,6 +49,9 @@ static DEFINE_PER_CPU(struct pagevec, lru_rotate_pvecs); - static DEFINE_PER_CPU(struct pagevec, lru_deactivate_file_pvecs); - static DEFINE_PER_CPU(struct pagevec, lru_deactivate_pvecs); - -+static DEFINE_LOCAL_IRQ_LOCK(rotate_lock); -+DEFINE_LOCAL_IRQ_LOCK(swapvec_lock); -+ - /* - * This path almost never happens for VM activity - pages are normally - * freed via pagevecs. But it gets used by networking. -@@ -237,11 +241,11 @@ void rotate_reclaimable_page(struct page *page) - unsigned long flags; - - get_page(page); -- local_irq_save(flags); -+ local_lock_irqsave(rotate_lock, flags); - pvec = this_cpu_ptr(&lru_rotate_pvecs); - if (!pagevec_add(pvec, page)) - pagevec_move_tail(pvec); -- local_irq_restore(flags); -+ local_unlock_irqrestore(rotate_lock, flags); - } - } - -@@ -292,12 +296,13 @@ static bool need_activate_page_drain(int cpu) - void activate_page(struct page *page) - { - if (PageLRU(page) && !PageActive(page) && !PageUnevictable(page)) { -- struct pagevec *pvec = &get_cpu_var(activate_page_pvecs); -+ struct pagevec *pvec = &get_locked_var(swapvec_lock, -+ activate_page_pvecs); - - get_page(page); - if (!pagevec_add(pvec, page)) - pagevec_lru_move_fn(pvec, __activate_page, NULL); -- put_cpu_var(activate_page_pvecs); -+ put_locked_var(swapvec_lock, activate_page_pvecs); - } - } - -@@ -323,7 +328,7 @@ void activate_page(struct page *page) - - static void __lru_cache_activate_page(struct page *page) - { -- struct pagevec *pvec = &get_cpu_var(lru_add_pvec); -+ struct pagevec *pvec = &get_locked_var(swapvec_lock, lru_add_pvec); - int i; - - /* -@@ -345,7 +350,7 @@ static void __lru_cache_activate_page(struct page *page) - } - } - -- put_cpu_var(lru_add_pvec); -+ put_locked_var(swapvec_lock, lru_add_pvec); - } - - /* -@@ -387,13 +392,13 @@ EXPORT_SYMBOL(mark_page_accessed); - - static void __lru_cache_add(struct page *page) - { -- struct pagevec *pvec = &get_cpu_var(lru_add_pvec); -+ struct pagevec *pvec = &get_locked_var(swapvec_lock, lru_add_pvec); - - get_page(page); - if (!pagevec_space(pvec)) - __pagevec_lru_add(pvec); - pagevec_add(pvec, page); -- put_cpu_var(lru_add_pvec); -+ put_locked_var(swapvec_lock, lru_add_pvec); - } - - /** -@@ -591,9 +596,9 @@ void lru_add_drain_cpu(int cpu) - unsigned long flags; - - /* No harm done if a racing interrupt already did this */ -- local_irq_save(flags); -+ local_lock_irqsave(rotate_lock, flags); - pagevec_move_tail(pvec); -- local_irq_restore(flags); -+ local_unlock_irqrestore(rotate_lock, flags); - } - - pvec = &per_cpu(lru_deactivate_file_pvecs, cpu); -@@ -625,11 +630,12 @@ void deactivate_file_page(struct page *page) - return; - - if (likely(get_page_unless_zero(page))) { -- struct pagevec *pvec = &get_cpu_var(lru_deactivate_file_pvecs); -+ struct pagevec *pvec = &get_locked_var(swapvec_lock, -+ lru_deactivate_file_pvecs); - - if (!pagevec_add(pvec, page)) - pagevec_lru_move_fn(pvec, lru_deactivate_file_fn, NULL); -- put_cpu_var(lru_deactivate_file_pvecs); -+ put_locked_var(swapvec_lock, lru_deactivate_file_pvecs); - } - } - -@@ -644,19 +650,20 @@ void deactivate_file_page(struct page *page) - void deactivate_page(struct page *page) - { - if (PageLRU(page) && PageActive(page) && !PageUnevictable(page)) { -- struct pagevec *pvec = &get_cpu_var(lru_deactivate_pvecs); -+ struct pagevec *pvec = &get_locked_var(swapvec_lock, -+ lru_deactivate_pvecs); - - get_page(page); - if (!pagevec_add(pvec, page)) - pagevec_lru_move_fn(pvec, lru_deactivate_fn, NULL); -- put_cpu_var(lru_deactivate_pvecs); -+ put_locked_var(swapvec_lock, lru_deactivate_pvecs); - } - } - - void lru_add_drain(void) - { -- lru_add_drain_cpu(get_cpu()); -- put_cpu(); -+ lru_add_drain_cpu(local_lock_cpu(swapvec_lock)); -+ local_unlock_cpu(swapvec_lock); - } - - static void lru_add_drain_per_cpu(struct work_struct *dummy) -diff --git a/mm/truncate.c b/mm/truncate.c -index b002728..dcc445a 100644 ---- a/mm/truncate.c -+++ b/mm/truncate.c -@@ -63,9 +63,12 @@ static void clear_exceptional_entry(struct address_space *mapping, - * protected by mapping->tree_lock. - */ - if (!workingset_node_shadows(node) && -- !list_empty(&node->private_list)) -- list_lru_del(&workingset_shadow_nodes, -+ !list_empty(&node->private_list)) { -+ local_lock(workingset_shadow_lock); -+ list_lru_del(&__workingset_shadow_nodes, - &node->private_list); -+ local_unlock(workingset_shadow_lock); -+ } - __radix_tree_delete_node(&mapping->page_tree, node); - } - unlock: -diff --git a/mm/vmalloc.c b/mm/vmalloc.c -index ae7d20b..b7d6f72 100644 ---- a/mm/vmalloc.c -+++ b/mm/vmalloc.c -@@ -819,7 +819,7 @@ static void *new_vmap_block(unsigned int order, gfp_t gfp_mask) - struct vmap_block *vb; - struct vmap_area *va; - unsigned long vb_idx; -- int node, err; -+ int node, err, cpu; - void *vaddr; - - node = numa_node_id(); -@@ -862,11 +862,12 @@ static void *new_vmap_block(unsigned int order, gfp_t gfp_mask) - BUG_ON(err); - radix_tree_preload_end(); - -- vbq = &get_cpu_var(vmap_block_queue); -+ cpu = get_cpu_light(); -+ vbq = this_cpu_ptr(&vmap_block_queue); - spin_lock(&vbq->lock); - list_add_tail_rcu(&vb->free_list, &vbq->free); - spin_unlock(&vbq->lock); -- put_cpu_var(vmap_block_queue); -+ put_cpu_light(); - - return vaddr; - } -@@ -935,6 +936,7 @@ static void *vb_alloc(unsigned long size, gfp_t gfp_mask) - struct vmap_block *vb; - void *vaddr = NULL; - unsigned int order; -+ int cpu; - - BUG_ON(offset_in_page(size)); - BUG_ON(size > PAGE_SIZE*VMAP_MAX_ALLOC); -@@ -949,7 +951,8 @@ static void *vb_alloc(unsigned long size, gfp_t gfp_mask) - order = get_order(size); - - rcu_read_lock(); -- vbq = &get_cpu_var(vmap_block_queue); -+ cpu = get_cpu_light(); -+ vbq = this_cpu_ptr(&vmap_block_queue); - list_for_each_entry_rcu(vb, &vbq->free, free_list) { - unsigned long pages_off; - -@@ -972,7 +975,7 @@ static void *vb_alloc(unsigned long size, gfp_t gfp_mask) - break; - } - -- put_cpu_var(vmap_block_queue); -+ put_cpu_light(); - rcu_read_unlock(); - - /* Allocate new block if nothing was found */ -diff --git a/mm/vmstat.c b/mm/vmstat.c -index 5e43004..1ae7431 100644 ---- a/mm/vmstat.c -+++ b/mm/vmstat.c -@@ -226,6 +226,7 @@ void __mod_zone_page_state(struct zone *zone, enum zone_stat_item item, - long x; - long t; - -+ preempt_disable_rt(); - x = delta + __this_cpu_read(*p); - - t = __this_cpu_read(pcp->stat_threshold); -@@ -235,6 +236,7 @@ void __mod_zone_page_state(struct zone *zone, enum zone_stat_item item, - x = 0; - } - __this_cpu_write(*p, x); -+ preempt_enable_rt(); - } - EXPORT_SYMBOL(__mod_zone_page_state); - -@@ -267,6 +269,7 @@ void __inc_zone_state(struct zone *zone, enum zone_stat_item item) - s8 __percpu *p = pcp->vm_stat_diff + item; - s8 v, t; - -+ preempt_disable_rt(); - v = __this_cpu_inc_return(*p); - t = __this_cpu_read(pcp->stat_threshold); - if (unlikely(v > t)) { -@@ -275,6 +278,7 @@ void __inc_zone_state(struct zone *zone, enum zone_stat_item item) - zone_page_state_add(v + overstep, zone, item); - __this_cpu_write(*p, -overstep); - } -+ preempt_enable_rt(); - } - - void __inc_zone_page_state(struct page *page, enum zone_stat_item item) -@@ -289,6 +293,7 @@ void __dec_zone_state(struct zone *zone, enum zone_stat_item item) - s8 __percpu *p = pcp->vm_stat_diff + item; - s8 v, t; - -+ preempt_disable_rt(); - v = __this_cpu_dec_return(*p); - t = __this_cpu_read(pcp->stat_threshold); - if (unlikely(v < - t)) { -@@ -297,6 +302,7 @@ void __dec_zone_state(struct zone *zone, enum zone_stat_item item) - zone_page_state_add(v - overstep, zone, item); - __this_cpu_write(*p, overstep); - } -+ preempt_enable_rt(); - } - - void __dec_zone_page_state(struct page *page, enum zone_stat_item item) -diff --git a/mm/workingset.c b/mm/workingset.c -index 8a75f8d..00a38f9 100644 ---- a/mm/workingset.c -+++ b/mm/workingset.c -@@ -335,7 +335,8 @@ out: - * point where they would still be useful. - */ - --struct list_lru workingset_shadow_nodes; -+struct list_lru __workingset_shadow_nodes; -+DEFINE_LOCAL_IRQ_LOCK(workingset_shadow_lock); - - static unsigned long count_shadow_nodes(struct shrinker *shrinker, - struct shrink_control *sc) -@@ -345,9 +346,9 @@ static unsigned long count_shadow_nodes(struct shrinker *shrinker, - unsigned long pages; - - /* list_lru lock nests inside IRQ-safe mapping->tree_lock */ -- local_irq_disable(); -- shadow_nodes = list_lru_shrink_count(&workingset_shadow_nodes, sc); -- local_irq_enable(); -+ local_lock_irq(workingset_shadow_lock); -+ shadow_nodes = list_lru_shrink_count(&__workingset_shadow_nodes, sc); -+ local_unlock_irq(workingset_shadow_lock); - - if (memcg_kmem_enabled()) - pages = mem_cgroup_node_nr_lru_pages(sc->memcg, sc->nid, -@@ -440,9 +441,9 @@ static enum lru_status shadow_lru_isolate(struct list_head *item, - spin_unlock(&mapping->tree_lock); - ret = LRU_REMOVED_RETRY; - out: -- local_irq_enable(); -+ local_unlock_irq(workingset_shadow_lock); - cond_resched(); -- local_irq_disable(); -+ local_lock_irq(workingset_shadow_lock); - spin_lock(lru_lock); - return ret; - } -@@ -453,10 +454,10 @@ static unsigned long scan_shadow_nodes(struct shrinker *shrinker, - unsigned long ret; - - /* list_lru lock nests inside IRQ-safe mapping->tree_lock */ -- local_irq_disable(); -- ret = list_lru_shrink_walk(&workingset_shadow_nodes, sc, -+ local_lock_irq(workingset_shadow_lock); -+ ret = list_lru_shrink_walk(&__workingset_shadow_nodes, sc, - shadow_lru_isolate, NULL); -- local_irq_enable(); -+ local_unlock_irq(workingset_shadow_lock); - return ret; - } - -@@ -494,7 +495,7 @@ static int __init workingset_init(void) - printk("workingset: timestamp_bits=%d max_order=%d bucket_order=%u\n", - timestamp_bits, max_order, bucket_order); - -- ret = list_lru_init_key(&workingset_shadow_nodes, &shadow_nodes_key); -+ ret = list_lru_init_key(&__workingset_shadow_nodes, &shadow_nodes_key); - if (ret) - goto err; - ret = register_shrinker(&workingset_shadow_shrinker); -@@ -502,7 +503,7 @@ static int __init workingset_init(void) - goto err_list_lru; - return 0; - err_list_lru: -- list_lru_destroy(&workingset_shadow_nodes); -+ list_lru_destroy(&__workingset_shadow_nodes); - err: - return ret; - } -diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c -index fe47fbb..e46d7bc 100644 ---- a/mm/zsmalloc.c -+++ b/mm/zsmalloc.c -@@ -1292,7 +1292,7 @@ void *zs_map_object(struct zs_pool *pool, unsigned long handle, - class = pool->size_class[class_idx]; - off = obj_idx_to_offset(page, obj_idx, class->size); - -- area = &get_cpu_var(zs_map_area); -+ area = per_cpu_ptr(&zs_map_area, get_cpu_light()); - area->vm_mm = mm; - if (off + class->size <= PAGE_SIZE) { - /* this object is contained entirely within a page */ -@@ -1345,7 +1345,7 @@ void zs_unmap_object(struct zs_pool *pool, unsigned long handle) - - __zs_unmap_object(area, pages, off, class->size); - } -- put_cpu_var(zs_map_area); -+ put_cpu_light(); - unpin_tag(handle); - } - EXPORT_SYMBOL_GPL(zs_unmap_object); -diff --git a/net/core/dev.c b/net/core/dev.c -index 5c925ac..a8fedf8 100644 ---- a/net/core/dev.c -+++ b/net/core/dev.c -@@ -188,6 +188,7 @@ static unsigned int napi_gen_id = NR_CPUS; - static DEFINE_READ_MOSTLY_HASHTABLE(napi_hash, 8); - - static seqcount_t devnet_rename_seq; -+static DEFINE_MUTEX(devnet_rename_mutex); - - static inline void dev_base_seq_inc(struct net *net) - { -@@ -209,14 +210,14 @@ static inline struct hlist_head *dev_index_hash(struct net *net, int ifindex) - static inline void rps_lock(struct softnet_data *sd) - { - #ifdef CONFIG_RPS -- spin_lock(&sd->input_pkt_queue.lock); -+ raw_spin_lock(&sd->input_pkt_queue.raw_lock); - #endif - } - - static inline void rps_unlock(struct softnet_data *sd) - { - #ifdef CONFIG_RPS -- spin_unlock(&sd->input_pkt_queue.lock); -+ raw_spin_unlock(&sd->input_pkt_queue.raw_lock); - #endif - } - -@@ -886,7 +887,8 @@ retry: - strcpy(name, dev->name); - rcu_read_unlock(); - if (read_seqcount_retry(&devnet_rename_seq, seq)) { -- cond_resched(); -+ mutex_lock(&devnet_rename_mutex); -+ mutex_unlock(&devnet_rename_mutex); - goto retry; - } - -@@ -1155,20 +1157,17 @@ int dev_change_name(struct net_device *dev, const char *newname) - if (dev->flags & IFF_UP) - return -EBUSY; - -- write_seqcount_begin(&devnet_rename_seq); -+ mutex_lock(&devnet_rename_mutex); -+ __raw_write_seqcount_begin(&devnet_rename_seq); - -- if (strncmp(newname, dev->name, IFNAMSIZ) == 0) { -- write_seqcount_end(&devnet_rename_seq); -- return 0; -- } -+ if (strncmp(newname, dev->name, IFNAMSIZ) == 0) -+ goto outunlock; - - memcpy(oldname, dev->name, IFNAMSIZ); - - err = dev_get_valid_name(net, dev, newname); -- if (err < 0) { -- write_seqcount_end(&devnet_rename_seq); -- return err; -- } -+ if (err < 0) -+ goto outunlock; - - if (oldname[0] && !strchr(oldname, '%')) - netdev_info(dev, "renamed from %s\n", oldname); -@@ -1181,11 +1180,12 @@ rollback: - if (ret) { - memcpy(dev->name, oldname, IFNAMSIZ); - dev->name_assign_type = old_assign_type; -- write_seqcount_end(&devnet_rename_seq); -- return ret; -+ err = ret; -+ goto outunlock; - } - -- write_seqcount_end(&devnet_rename_seq); -+ __raw_write_seqcount_end(&devnet_rename_seq); -+ mutex_unlock(&devnet_rename_mutex); - - netdev_adjacent_rename_links(dev, oldname); - -@@ -1206,7 +1206,8 @@ rollback: - /* err >= 0 after dev_alloc_name() or stores the first errno */ - if (err >= 0) { - err = ret; -- write_seqcount_begin(&devnet_rename_seq); -+ mutex_lock(&devnet_rename_mutex); -+ __raw_write_seqcount_begin(&devnet_rename_seq); - memcpy(dev->name, oldname, IFNAMSIZ); - memcpy(oldname, newname, IFNAMSIZ); - dev->name_assign_type = old_assign_type; -@@ -1219,6 +1220,11 @@ rollback: - } - - return err; -+ -+outunlock: -+ __raw_write_seqcount_end(&devnet_rename_seq); -+ mutex_unlock(&devnet_rename_mutex); -+ return err; - } - - /** -@@ -2264,6 +2270,7 @@ static inline void __netif_reschedule(struct Qdisc *q) - sd->output_queue_tailp = &q->next_sched; - raise_softirq_irqoff(NET_TX_SOFTIRQ); - local_irq_restore(flags); -+ preempt_check_resched_rt(); - } - - void __netif_schedule(struct Qdisc *q) -@@ -2345,6 +2352,7 @@ void __dev_kfree_skb_irq(struct sk_buff *skb, enum skb_free_reason reason) - __this_cpu_write(softnet_data.completion_queue, skb); - raise_softirq_irqoff(NET_TX_SOFTIRQ); - local_irq_restore(flags); -+ preempt_check_resched_rt(); - } - EXPORT_SYMBOL(__dev_kfree_skb_irq); - -@@ -3035,7 +3043,11 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q, - * This permits __QDISC___STATE_RUNNING owner to get the lock more - * often and dequeue packets faster. - */ -+#ifdef CONFIG_PREEMPT_RT_FULL -+ contended = true; -+#else - contended = qdisc_is_running(q); -+#endif - if (unlikely(contended)) - spin_lock(&q->busylock); - -@@ -3096,9 +3108,44 @@ static void skb_update_prio(struct sk_buff *skb) - #define skb_update_prio(skb) - #endif - -+#ifdef CONFIG_PREEMPT_RT_FULL -+ -+static inline int xmit_rec_read(void) -+{ -+ return current->xmit_recursion; -+} -+ -+static inline void xmit_rec_inc(void) -+{ -+ current->xmit_recursion++; -+} -+ -+static inline void xmit_rec_dec(void) -+{ -+ current->xmit_recursion--; -+} -+ -+#else -+ - DEFINE_PER_CPU(int, xmit_recursion); - EXPORT_SYMBOL(xmit_recursion); - -+static inline int xmit_rec_read(void) -+{ -+ return __this_cpu_read(xmit_recursion); -+} -+ -+static inline void xmit_rec_inc(void) -+{ -+ __this_cpu_inc(xmit_recursion); -+} -+ -+static inline void xmit_rec_dec(void) -+{ -+ __this_cpu_dec(xmit_recursion); -+} -+#endif -+ - #define RECURSION_LIMIT 10 - - /** -@@ -3344,7 +3391,7 @@ static int __dev_queue_xmit(struct sk_buff *skb, void *accel_priv) - - if (txq->xmit_lock_owner != cpu) { - -- if (__this_cpu_read(xmit_recursion) > RECURSION_LIMIT) -+ if (xmit_rec_read() > RECURSION_LIMIT) - goto recursion_alert; - - skb = validate_xmit_skb(skb, dev); -@@ -3354,9 +3401,9 @@ static int __dev_queue_xmit(struct sk_buff *skb, void *accel_priv) - HARD_TX_LOCK(dev, txq, cpu); - - if (!netif_xmit_stopped(txq)) { -- __this_cpu_inc(xmit_recursion); -+ xmit_rec_inc(); - skb = dev_hard_start_xmit(skb, dev, txq, &rc); -- __this_cpu_dec(xmit_recursion); -+ xmit_rec_dec(); - if (dev_xmit_complete(rc)) { - HARD_TX_UNLOCK(dev, txq); - goto out; -@@ -3730,6 +3777,7 @@ drop: - rps_unlock(sd); - - local_irq_restore(flags); -+ preempt_check_resched_rt(); - - atomic_long_inc(&skb->dev->rx_dropped); - kfree_skb(skb); -@@ -3748,7 +3796,7 @@ static int netif_rx_internal(struct sk_buff *skb) - struct rps_dev_flow voidflow, *rflow = &voidflow; - int cpu; - -- preempt_disable(); -+ migrate_disable(); - rcu_read_lock(); - - cpu = get_rps_cpu(skb->dev, skb, &rflow); -@@ -3758,13 +3806,13 @@ static int netif_rx_internal(struct sk_buff *skb) - ret = enqueue_to_backlog(skb, cpu, &rflow->last_qtail); - - rcu_read_unlock(); -- preempt_enable(); -+ migrate_enable(); - } else - #endif - { - unsigned int qtail; -- ret = enqueue_to_backlog(skb, get_cpu(), &qtail); -- put_cpu(); -+ ret = enqueue_to_backlog(skb, get_cpu_light(), &qtail); -+ put_cpu_light(); - } - return ret; - } -@@ -3798,16 +3846,44 @@ int netif_rx_ni(struct sk_buff *skb) - - trace_netif_rx_ni_entry(skb); - -- preempt_disable(); -+ local_bh_disable(); - err = netif_rx_internal(skb); -- if (local_softirq_pending()) -- do_softirq(); -- preempt_enable(); -+ local_bh_enable(); - - return err; - } - EXPORT_SYMBOL(netif_rx_ni); - -+#ifdef CONFIG_PREEMPT_RT_FULL -+/* -+ * RT runs ksoftirqd as a real time thread and the root_lock is a -+ * "sleeping spinlock". If the trylock fails then we can go into an -+ * infinite loop when ksoftirqd preempted the task which actually -+ * holds the lock, because we requeue q and raise NET_TX softirq -+ * causing ksoftirqd to loop forever. -+ * -+ * It's safe to use spin_lock on RT here as softirqs run in thread -+ * context and cannot deadlock against the thread which is holding -+ * root_lock. -+ * -+ * On !RT the trylock might fail, but there we bail out from the -+ * softirq loop after 10 attempts which we can't do on RT. And the -+ * task holding root_lock cannot be preempted, so the only downside of -+ * that trylock is that we need 10 loops to decide that we should have -+ * given up in the first one :) -+ */ -+static inline int take_root_lock(spinlock_t *lock) -+{ -+ spin_lock(lock); -+ return 1; -+} -+#else -+static inline int take_root_lock(spinlock_t *lock) -+{ -+ return spin_trylock(lock); -+} -+#endif -+ - static void net_tx_action(struct softirq_action *h) - { - struct softnet_data *sd = this_cpu_ptr(&softnet_data); -@@ -3855,7 +3931,7 @@ static void net_tx_action(struct softirq_action *h) - head = head->next_sched; - - root_lock = qdisc_lock(q); -- if (spin_trylock(root_lock)) { -+ if (take_root_lock(root_lock)) { - smp_mb__before_atomic(); - clear_bit(__QDISC_STATE_SCHED, - &q->state); -@@ -4264,7 +4340,7 @@ static void flush_backlog(void *arg) - skb_queue_walk_safe(&sd->input_pkt_queue, skb, tmp) { - if (skb->dev == dev) { - __skb_unlink(skb, &sd->input_pkt_queue); -- kfree_skb(skb); -+ __skb_queue_tail(&sd->tofree_queue, skb); - input_queue_head_incr(sd); - } - } -@@ -4273,10 +4349,13 @@ static void flush_backlog(void *arg) - skb_queue_walk_safe(&sd->process_queue, skb, tmp) { - if (skb->dev == dev) { - __skb_unlink(skb, &sd->process_queue); -- kfree_skb(skb); -+ __skb_queue_tail(&sd->tofree_queue, skb); - input_queue_head_incr(sd); - } - } -+ -+ if (!skb_queue_empty(&sd->tofree_queue)) -+ raise_softirq_irqoff(NET_RX_SOFTIRQ); - } - - static int napi_gro_complete(struct sk_buff *skb) -@@ -4735,6 +4814,7 @@ static void net_rps_action_and_irq_enable(struct softnet_data *sd) - sd->rps_ipi_list = NULL; - - local_irq_enable(); -+ preempt_check_resched_rt(); - - /* Send pending IPI's to kick RPS processing on remote cpus. */ - while (remsd) { -@@ -4748,6 +4828,7 @@ static void net_rps_action_and_irq_enable(struct softnet_data *sd) - } else - #endif - local_irq_enable(); -+ preempt_check_resched_rt(); - } - - static bool sd_has_rps_ipi_waiting(struct softnet_data *sd) -@@ -4829,6 +4910,7 @@ void __napi_schedule(struct napi_struct *n) - local_irq_save(flags); - ____napi_schedule(this_cpu_ptr(&softnet_data), n); - local_irq_restore(flags); -+ preempt_check_resched_rt(); - } - EXPORT_SYMBOL(__napi_schedule); - -@@ -5169,7 +5251,7 @@ static void net_rx_action(struct softirq_action *h) - list_splice_tail(&repoll, &list); - list_splice(&list, &sd->poll_list); - if (!list_empty(&sd->poll_list)) -- __raise_softirq_irqoff(NET_RX_SOFTIRQ); -+ __raise_softirq_irqoff_ksoft(NET_RX_SOFTIRQ); - - net_rps_action_and_irq_enable(sd); - } -@@ -7534,7 +7616,7 @@ EXPORT_SYMBOL(free_netdev); - void synchronize_net(void) - { - might_sleep(); -- if (rtnl_is_locked()) -+ if (rtnl_is_locked() && !IS_ENABLED(CONFIG_PREEMPT_RT_FULL)) - synchronize_rcu_expedited(); - else - synchronize_rcu(); -@@ -7775,16 +7857,20 @@ static int dev_cpu_callback(struct notifier_block *nfb, - - raise_softirq_irqoff(NET_TX_SOFTIRQ); - local_irq_enable(); -+ preempt_check_resched_rt(); - - /* Process offline CPU's input_pkt_queue */ - while ((skb = __skb_dequeue(&oldsd->process_queue))) { - netif_rx_ni(skb); - input_queue_head_incr(oldsd); - } -- while ((skb = skb_dequeue(&oldsd->input_pkt_queue))) { -+ while ((skb = __skb_dequeue(&oldsd->input_pkt_queue))) { - netif_rx_ni(skb); - input_queue_head_incr(oldsd); - } -+ while ((skb = __skb_dequeue(&oldsd->tofree_queue))) { -+ kfree_skb(skb); -+ } - - return NOTIFY_OK; - } -@@ -8086,8 +8172,9 @@ static int __init net_dev_init(void) - for_each_possible_cpu(i) { - struct softnet_data *sd = &per_cpu(softnet_data, i); - -- skb_queue_head_init(&sd->input_pkt_queue); -- skb_queue_head_init(&sd->process_queue); -+ skb_queue_head_init_raw(&sd->input_pkt_queue); -+ skb_queue_head_init_raw(&sd->process_queue); -+ skb_queue_head_init_raw(&sd->tofree_queue); - INIT_LIST_HEAD(&sd->poll_list); - sd->output_queue_tailp = &sd->output_queue; - #ifdef CONFIG_RPS -diff --git a/net/core/skbuff.c b/net/core/skbuff.c -index e561f9f..eeb08db 100644 ---- a/net/core/skbuff.c -+++ b/net/core/skbuff.c -@@ -63,6 +63,7 @@ - #include <linux/errqueue.h> - #include <linux/prefetch.h> - #include <linux/if_vlan.h> -+#include <linux/locallock.h> - - #include <net/protocol.h> - #include <net/dst.h> -@@ -359,6 +360,8 @@ struct napi_alloc_cache { - - static DEFINE_PER_CPU(struct page_frag_cache, netdev_alloc_cache); - static DEFINE_PER_CPU(struct napi_alloc_cache, napi_alloc_cache); -+static DEFINE_LOCAL_IRQ_LOCK(netdev_alloc_lock); -+static DEFINE_LOCAL_IRQ_LOCK(napi_alloc_cache_lock); - - static void *__netdev_alloc_frag(unsigned int fragsz, gfp_t gfp_mask) - { -@@ -366,10 +369,10 @@ static void *__netdev_alloc_frag(unsigned int fragsz, gfp_t gfp_mask) - unsigned long flags; - void *data; - -- local_irq_save(flags); -+ local_lock_irqsave(netdev_alloc_lock, flags); - nc = this_cpu_ptr(&netdev_alloc_cache); - data = __alloc_page_frag(nc, fragsz, gfp_mask); -- local_irq_restore(flags); -+ local_unlock_irqrestore(netdev_alloc_lock, flags); - return data; - } - -@@ -388,9 +391,13 @@ EXPORT_SYMBOL(netdev_alloc_frag); - - static void *__napi_alloc_frag(unsigned int fragsz, gfp_t gfp_mask) - { -- struct napi_alloc_cache *nc = this_cpu_ptr(&napi_alloc_cache); -+ struct napi_alloc_cache *nc; -+ void *data; - -- return __alloc_page_frag(&nc->page, fragsz, gfp_mask); -+ nc = &get_locked_var(napi_alloc_cache_lock, napi_alloc_cache); -+ data = __alloc_page_frag(&nc->page, fragsz, gfp_mask); -+ put_locked_var(napi_alloc_cache_lock, napi_alloc_cache); -+ return data; - } - - void *napi_alloc_frag(unsigned int fragsz) -@@ -437,13 +444,13 @@ struct sk_buff *__netdev_alloc_skb(struct net_device *dev, unsigned int len, - if (sk_memalloc_socks()) - gfp_mask |= __GFP_MEMALLOC; - -- local_irq_save(flags); -+ local_lock_irqsave(netdev_alloc_lock, flags); - - nc = this_cpu_ptr(&netdev_alloc_cache); - data = __alloc_page_frag(nc, len, gfp_mask); - pfmemalloc = nc->pfmemalloc; - -- local_irq_restore(flags); -+ local_unlock_irqrestore(netdev_alloc_lock, flags); - - if (unlikely(!data)) - return NULL; -@@ -484,9 +491,10 @@ EXPORT_SYMBOL(__netdev_alloc_skb); - struct sk_buff *__napi_alloc_skb(struct napi_struct *napi, unsigned int len, - gfp_t gfp_mask) - { -- struct napi_alloc_cache *nc = this_cpu_ptr(&napi_alloc_cache); -+ struct napi_alloc_cache *nc; - struct sk_buff *skb; - void *data; -+ bool pfmemalloc; - - len += NET_SKB_PAD + NET_IP_ALIGN; - -@@ -504,7 +512,10 @@ struct sk_buff *__napi_alloc_skb(struct napi_struct *napi, unsigned int len, - if (sk_memalloc_socks()) - gfp_mask |= __GFP_MEMALLOC; - -+ nc = &get_locked_var(napi_alloc_cache_lock, napi_alloc_cache); - data = __alloc_page_frag(&nc->page, len, gfp_mask); -+ pfmemalloc = nc->page.pfmemalloc; -+ put_locked_var(napi_alloc_cache_lock, napi_alloc_cache); - if (unlikely(!data)) - return NULL; - -@@ -515,7 +526,7 @@ struct sk_buff *__napi_alloc_skb(struct napi_struct *napi, unsigned int len, - } - - /* use OR instead of assignment to avoid clearing of bits in mask */ -- if (nc->page.pfmemalloc) -+ if (pfmemalloc) - skb->pfmemalloc = 1; - skb->head_frag = 1; - -@@ -759,23 +770,26 @@ EXPORT_SYMBOL(consume_skb); - - void __kfree_skb_flush(void) - { -- struct napi_alloc_cache *nc = this_cpu_ptr(&napi_alloc_cache); -+ struct napi_alloc_cache *nc; - -+ nc = &get_locked_var(napi_alloc_cache_lock, napi_alloc_cache); - /* flush skb_cache if containing objects */ - if (nc->skb_count) { - kmem_cache_free_bulk(skbuff_head_cache, nc->skb_count, - nc->skb_cache); - nc->skb_count = 0; - } -+ put_locked_var(napi_alloc_cache_lock, napi_alloc_cache); - } - - static inline void _kfree_skb_defer(struct sk_buff *skb) - { -- struct napi_alloc_cache *nc = this_cpu_ptr(&napi_alloc_cache); -+ struct napi_alloc_cache *nc; - - /* drop skb->head and call any destructors for packet */ - skb_release_all(skb); - -+ nc = &get_locked_var(napi_alloc_cache_lock, napi_alloc_cache); - /* record skb to CPU local list */ - nc->skb_cache[nc->skb_count++] = skb; - -@@ -790,6 +804,7 @@ static inline void _kfree_skb_defer(struct sk_buff *skb) - nc->skb_cache); - nc->skb_count = 0; - } -+ put_locked_var(napi_alloc_cache_lock, napi_alloc_cache); - } - void __kfree_skb_defer(struct sk_buff *skb) - { -diff --git a/net/core/sock.c b/net/core/sock.c -index 7e73c26..885fe2e 100644 ---- a/net/core/sock.c -+++ b/net/core/sock.c -@@ -2421,12 +2421,11 @@ void lock_sock_nested(struct sock *sk, int subclass) - if (sk->sk_lock.owned) - __lock_sock(sk); - sk->sk_lock.owned = 1; -- spin_unlock(&sk->sk_lock.slock); -+ spin_unlock_bh(&sk->sk_lock.slock); - /* - * The sk_lock has mutex_lock() semantics here: - */ - mutex_acquire(&sk->sk_lock.dep_map, subclass, 0, _RET_IP_); -- local_bh_enable(); - } - EXPORT_SYMBOL(lock_sock_nested); - -diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c -index 6333489..c1f1d50 100644 ---- a/net/ipv4/icmp.c -+++ b/net/ipv4/icmp.c -@@ -69,6 +69,7 @@ - #include <linux/jiffies.h> - #include <linux/kernel.h> - #include <linux/fcntl.h> -+#include <linux/sysrq.h> - #include <linux/socket.h> - #include <linux/in.h> - #include <linux/inet.h> -@@ -891,6 +892,30 @@ static bool icmp_redirect(struct sk_buff *skb) - } - - /* -+ * 32bit and 64bit have different timestamp length, so we check for -+ * the cookie at offset 20 and verify it is repeated at offset 50 -+ */ -+#define CO_POS0 20 -+#define CO_POS1 50 -+#define CO_SIZE sizeof(int) -+#define ICMP_SYSRQ_SIZE 57 -+ -+/* -+ * We got a ICMP_SYSRQ_SIZE sized ping request. Check for the cookie -+ * pattern and if it matches send the next byte as a trigger to sysrq. -+ */ -+static void icmp_check_sysrq(struct net *net, struct sk_buff *skb) -+{ -+ int cookie = htonl(net->ipv4.sysctl_icmp_echo_sysrq); -+ char *p = skb->data; -+ -+ if (!memcmp(&cookie, p + CO_POS0, CO_SIZE) && -+ !memcmp(&cookie, p + CO_POS1, CO_SIZE) && -+ p[CO_POS0 + CO_SIZE] == p[CO_POS1 + CO_SIZE]) -+ handle_sysrq(p[CO_POS0 + CO_SIZE]); -+} -+ -+/* - * Handle ICMP_ECHO ("ping") requests. - * - * RFC 1122: 3.2.2.6 MUST have an echo server that answers ICMP echo -@@ -917,6 +942,11 @@ static bool icmp_echo(struct sk_buff *skb) - icmp_param.data_len = skb->len; - icmp_param.head_len = sizeof(struct icmphdr); - icmp_reply(&icmp_param, skb); -+ -+ if (skb->len == ICMP_SYSRQ_SIZE && -+ net->ipv4.sysctl_icmp_echo_sysrq) { -+ icmp_check_sysrq(net, skb); -+ } - } - /* should there be an ICMP stat for ignored echos? */ - return true; -diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c -index 1e1fe60..b1275e2 100644 ---- a/net/ipv4/sysctl_net_ipv4.c -+++ b/net/ipv4/sysctl_net_ipv4.c -@@ -681,6 +681,13 @@ static struct ctl_table ipv4_net_table[] = { - .proc_handler = proc_dointvec - }, - { -+ .procname = "icmp_echo_sysrq", -+ .data = &init_net.ipv4.sysctl_icmp_echo_sysrq, -+ .maxlen = sizeof(int), -+ .mode = 0644, -+ .proc_handler = proc_dointvec -+ }, -+ { - .procname = "icmp_ignore_bogus_error_responses", - .data = &init_net.ipv4.sysctl_icmp_ignore_bogus_error_responses, - .maxlen = sizeof(int), -diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c -index dc27bec..7815f28 100644 ---- a/net/mac80211/rx.c -+++ b/net/mac80211/rx.c -@@ -3679,7 +3679,7 @@ void ieee80211_rx_napi(struct ieee80211_hw *hw, struct sk_buff *skb, - struct ieee80211_supported_band *sband; - struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); - -- WARN_ON_ONCE(softirq_count() == 0); -+ WARN_ON_ONCE_NONRT(softirq_count() == 0); - - if (WARN_ON(status->band >= IEEE80211_NUM_BANDS)) - goto drop; -diff --git a/net/netfilter/core.c b/net/netfilter/core.c -index f39276d..10880c8 100644 ---- a/net/netfilter/core.c -+++ b/net/netfilter/core.c -@@ -22,11 +22,17 @@ - #include <linux/proc_fs.h> - #include <linux/mutex.h> - #include <linux/slab.h> -+#include <linux/locallock.h> - #include <net/net_namespace.h> - #include <net/sock.h> - - #include "nf_internals.h" - -+#ifdef CONFIG_PREEMPT_RT_BASE -+DEFINE_LOCAL_IRQ_LOCK(xt_write_lock); -+EXPORT_PER_CPU_SYMBOL(xt_write_lock); -+#endif -+ - static DEFINE_MUTEX(afinfo_mutex); - - const struct nf_afinfo __rcu *nf_afinfo[NFPROTO_NUMPROTO] __read_mostly; -diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c -index 18d0bec..e79c841 100644 ---- a/net/packet/af_packet.c -+++ b/net/packet/af_packet.c -@@ -63,6 +63,7 @@ - #include <linux/if_packet.h> - #include <linux/wireless.h> - #include <linux/kernel.h> -+#include <linux/delay.h> - #include <linux/kmod.h> - #include <linux/slab.h> - #include <linux/vmalloc.h> -@@ -694,7 +695,7 @@ static void prb_retire_rx_blk_timer_expired(unsigned long data) - if (BLOCK_NUM_PKTS(pbd)) { - while (atomic_read(&pkc->blk_fill_in_prog)) { - /* Waiting for skb_copy_bits to finish... */ -- cpu_relax(); -+ cpu_chill(); - } - } - -@@ -956,7 +957,7 @@ static void prb_retire_current_block(struct tpacket_kbdq_core *pkc, - if (!(status & TP_STATUS_BLK_TMO)) { - while (atomic_read(&pkc->blk_fill_in_prog)) { - /* Waiting for skb_copy_bits to finish... */ -- cpu_relax(); -+ cpu_chill(); - } - } - prb_close_block(pkc, pbd, po, status); -diff --git a/net/rds/ib_rdma.c b/net/rds/ib_rdma.c -index f7164ac..6f37dd5 100644 ---- a/net/rds/ib_rdma.c -+++ b/net/rds/ib_rdma.c -@@ -34,6 +34,7 @@ - #include <linux/slab.h> - #include <linux/rculist.h> - #include <linux/llist.h> -+#include <linux/delay.h> - - #include "ib_mr.h" - -@@ -209,7 +210,7 @@ static inline void wait_clean_list_grace(void) - for_each_online_cpu(cpu) { - flag = &per_cpu(clean_list_grace, cpu); - while (test_bit(CLEAN_LIST_BUSY_BIT, flag)) -- cpu_relax(); -+ cpu_chill(); - } - } - -diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c -index 80742ed..31f70ee 100644 ---- a/net/sched/sch_generic.c -+++ b/net/sched/sch_generic.c -@@ -894,7 +894,7 @@ void dev_deactivate_many(struct list_head *head) - /* Wait for outstanding qdisc_run calls. */ - list_for_each_entry(dev, head, close_list) - while (some_qdisc_is_busy(dev)) -- yield(); -+ msleep(1); - } - - void dev_deactivate(struct net_device *dev) -diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c -index 7422f28..6954c4f 100644 ---- a/net/sunrpc/svc_xprt.c -+++ b/net/sunrpc/svc_xprt.c -@@ -342,7 +342,7 @@ void svc_xprt_do_enqueue(struct svc_xprt *xprt) - goto out; - } - -- cpu = get_cpu(); -+ cpu = get_cpu_light(); - pool = svc_pool_for_cpu(xprt->xpt_server, cpu); - - atomic_long_inc(&pool->sp_stats.packets); -@@ -378,7 +378,7 @@ redo_search: - - atomic_long_inc(&pool->sp_stats.threads_woken); - wake_up_process(rqstp->rq_task); -- put_cpu(); -+ put_cpu_light(); - goto out; - } - rcu_read_unlock(); -@@ -399,7 +399,7 @@ redo_search: - goto redo_search; - } - rqstp = NULL; -- put_cpu(); -+ put_cpu_light(); - out: - trace_svc_xprt_do_enqueue(xprt, rqstp); - } -diff --git a/scripts/mkcompile_h b/scripts/mkcompile_h -index 6fdc97e..523e042 100755 ---- a/scripts/mkcompile_h -+++ b/scripts/mkcompile_h -@@ -4,7 +4,8 @@ TARGET=$1 - ARCH=$2 - SMP=$3 - PREEMPT=$4 --CC=$5 -+RT=$5 -+CC=$6 - - vecho() { [ "${quiet}" = "silent_" ] || echo "$@" ; } - -@@ -57,6 +58,7 @@ UTS_VERSION="#$VERSION" - CONFIG_FLAGS="" - if [ -n "$SMP" ] ; then CONFIG_FLAGS="SMP"; fi - if [ -n "$PREEMPT" ] ; then CONFIG_FLAGS="$CONFIG_FLAGS PREEMPT"; fi -+if [ -n "$RT" ] ; then CONFIG_FLAGS="$CONFIG_FLAGS RT"; fi - UTS_VERSION="$UTS_VERSION $CONFIG_FLAGS $TIMESTAMP" - - # Truncate to maximum length -diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c -index 9106d8e..6c55707 100644 ---- a/sound/core/pcm_native.c -+++ b/sound/core/pcm_native.c -@@ -135,7 +135,7 @@ EXPORT_SYMBOL_GPL(snd_pcm_stream_unlock); - void snd_pcm_stream_lock_irq(struct snd_pcm_substream *substream) - { - if (!substream->pcm->nonatomic) -- local_irq_disable(); -+ local_irq_disable_nort(); - snd_pcm_stream_lock(substream); - } - EXPORT_SYMBOL_GPL(snd_pcm_stream_lock_irq); -@@ -150,7 +150,7 @@ void snd_pcm_stream_unlock_irq(struct snd_pcm_substream *substream) - { - snd_pcm_stream_unlock(substream); - if (!substream->pcm->nonatomic) -- local_irq_enable(); -+ local_irq_enable_nort(); - } - EXPORT_SYMBOL_GPL(snd_pcm_stream_unlock_irq); - -@@ -158,7 +158,7 @@ unsigned long _snd_pcm_stream_lock_irqsave(struct snd_pcm_substream *substream) - { - unsigned long flags = 0; - if (!substream->pcm->nonatomic) -- local_irq_save(flags); -+ local_irq_save_nort(flags); - snd_pcm_stream_lock(substream); - return flags; - } -@@ -176,7 +176,7 @@ void snd_pcm_stream_unlock_irqrestore(struct snd_pcm_substream *substream, - { - snd_pcm_stream_unlock(substream); - if (!substream->pcm->nonatomic) -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - } - EXPORT_SYMBOL_GPL(snd_pcm_stream_unlock_irqrestore); - --- -2.8.1 - diff --git a/patches/sgx-blob/0001-NFM-TI-es8-merge-in-5.00.00.01-kernel-modules.patch b/patches/sgx-blob/0001-NFM-TI-es8-merge-in-5.00.00.01-kernel-modules.patch deleted file mode 100644 index 6ef5a173443c66eec493b7bd2de63dc0169a2a8f..0000000000000000000000000000000000000000 --- a/patches/sgx-blob/0001-NFM-TI-es8-merge-in-5.00.00.01-kernel-modules.patch +++ /dev/null @@ -1,132862 +0,0 @@ -From 842b02b77af4042d211a6c6e23bcd3ad314ab6a2 Mon Sep 17 00:00:00 2001 -From: Robert Nelson <robertcnelson@gmail.com> -Date: Wed, 18 Dec 2013 15:52:48 -0600 -Subject: [PATCH 1/2] NFM: TI: es8: merge in 5.00.00.01 kernel modules - -Signed-off-by: Robert Nelson <robertcnelson@gmail.com> ---- - drivers/staging/ti-es8-sgx/COPYING | 350 ++ - drivers/staging/ti-es8-sgx/GPL-COPYING | 343 ++ - drivers/staging/ti-es8-sgx/INSTALL | 72 + - drivers/staging/ti-es8-sgx/Kbuild | 127 + - drivers/staging/ti-es8-sgx/MIT-COPYING | 41 + - drivers/staging/ti-es8-sgx/Makefile | 486 ++ - drivers/staging/ti-es8-sgx/README | 49 + - .../ti-es8-sgx/eurasiacon/build/linux2/bits.mk | 114 + - .../eurasiacon/build/linux2/buildvars.mk | 217 + - .../ti-es8-sgx/eurasiacon/build/linux2/commands.mk | 237 + - .../eurasiacon/build/linux2/common/apis/xorg.mk | 48 + - .../eurasiacon/build/linux2/common/dridrm.mk | 60 + - .../eurasiacon/build/linux2/common/omap4.mk | 43 + - .../eurasiacon/build/linux2/common/opencl.mk | 39 + - .../eurasiacon/build/linux2/common/xorg.mk | 47 + - .../eurasiacon/build/linux2/common/xorg_test.mk | 48 + - .../eurasiacon/build/linux2/config/core.mk | 642 +++ - .../ti-es8-sgx/eurasiacon/build/linux2/defs.mk | 144 + - .../build/linux2/kbuild/Makefile.template | 92 + - .../build/linux2/kbuild/external_tarball.mk | 49 + - .../eurasiacon/build/linux2/kbuild/kbuild.mk | 91 + - .../eurasiacon/build/linux2/kernel_module.mk | 75 + - .../eurasiacon/build/linux2/kernel_version.mk | 100 + - .../eurasiacon/build/linux2/moduledefs.mk | 100 + - .../ti-es8-sgx/eurasiacon/build/linux2/modules.mk | 49 + - .../build/linux2/omap4430_linux/Makefile | 187 + - .../eurasiacon/build/linux2/omap_linux/Makefile | 234 + - .../eurasiacon/build/linux2/prepare_tree.mk | 56 + - .../eurasiacon/build/linux2/this_makefile.mk | 68 + - .../eurasiacon/build/linux2/tools/cc-check.sh | 99 + - .../ti-es8-sgx/eurasiacon/build/linux2/toplevel.mk | 230 + - drivers/staging/ti-es8-sgx/include4/dbgdrvif.h | 381 ++ - drivers/staging/ti-es8-sgx/include4/img_defs.h | 218 + - drivers/staging/ti-es8-sgx/include4/img_types.h | 230 + - drivers/staging/ti-es8-sgx/include4/pdumpdefs.h | 126 + - drivers/staging/ti-es8-sgx/include4/pvr_debug.h | 239 + - drivers/staging/ti-es8-sgx/include4/pvrmodule.h | 48 + - drivers/staging/ti-es8-sgx/include4/pvrversion.h | 68 + - drivers/staging/ti-es8-sgx/include4/services.h | 1571 +++++++ - drivers/staging/ti-es8-sgx/include4/servicesext.h | 961 ++++ - drivers/staging/ti-es8-sgx/include4/sgx_options.h | 252 ++ - drivers/staging/ti-es8-sgx/include4/sgxapi_km.h | 537 +++ - drivers/staging/ti-es8-sgx/include4/sgxscript.h | 106 + - .../3rdparty/bufferclass_example/Kbuild.mk | 45 + - .../3rdparty/bufferclass_example/Linux.mk | 45 + - .../bufferclass_example/bufferclass_example.c | 626 +++ - .../bufferclass_example/bufferclass_example.h | 237 + - .../bufferclass_example_linux.c | 609 +++ - .../bufferclass_example_linux.h | 66 + - .../bufferclass_example_private.c | 432 ++ - .../bufferclass_example_private.h | 49 + - .../services4/3rdparty/bufferclass_ti/Kbuild | 10 + - .../services4/3rdparty/bufferclass_ti/Makefile | 25 + - .../services4/3rdparty/bufferclass_ti/bc_cat.c | 1157 +++++ - .../services4/3rdparty/bufferclass_ti/bc_cat.h | 88 + - .../dc_omapfb3_linux/3rdparty_dc_drm_shared.h | 64 + - .../services4/3rdparty/dc_omapfb3_linux/Kbuild | 34 + - .../services4/3rdparty/dc_omapfb3_linux/Kbuild.mk | 48 + - .../services4/3rdparty/dc_omapfb3_linux/Linux.mk | 45 + - .../services4/3rdparty/dc_omapfb3_linux/omaplfb.h | 331 ++ - .../dc_omapfb3_linux/omaplfb_displayclass.c | 1878 ++++++++ - .../3rdparty/dc_omapfb3_linux/omaplfb_linux.c | 1303 ++++++ - .../dc_ti335x_linux/3rdparty_dc_drm_shared.h | 64 + - .../services4/3rdparty/dc_ti335x_linux/Kbuild | 32 + - .../services4/3rdparty/dc_ti335x_linux/Kbuild.mk | 48 + - .../services4/3rdparty/dc_ti335x_linux/Linux.mk | 45 + - .../services4/3rdparty/dc_ti335x_linux/omaplfb.h | 331 ++ - .../dc_ti335x_linux/omaplfb_displayclass.c | 1876 ++++++++ - .../3rdparty/dc_ti335x_linux/omaplfb_linux.c | 1344 ++++++ - .../dc_ti43xx_linux/3rdparty_dc_drm_shared.h | 64 + - .../services4/3rdparty/dc_ti43xx_linux/Kbuild | 32 + - .../services4/3rdparty/dc_ti43xx_linux/Kbuild.mk | 48 + - .../services4/3rdparty/dc_ti43xx_linux/Linux.mk | 45 + - .../services4/3rdparty/dc_ti43xx_linux/omaplfb.h | 331 ++ - .../dc_ti43xx_linux/omaplfb_displayclass.c | 1878 ++++++++ - .../3rdparty/dc_ti43xx_linux/omaplfb_linux.c | 1304 ++++++ - .../dc_ti81xx_linux/3rdparty_dc_drm_shared.h | 65 + - .../services4/3rdparty/dc_ti81xx_linux/Kbuild | 32 + - .../services4/3rdparty/dc_ti81xx_linux/Kbuild.mk | 49 + - .../services4/3rdparty/dc_ti81xx_linux/Linux.mk | 46 + - .../services4/3rdparty/dc_ti81xx_linux/omaplfb.h | 323 ++ - .../dc_ti81xx_linux/omaplfb_displayclass.c | 1748 ++++++++ - .../3rdparty/dc_ti81xx_linux/omaplfb_linux.c | 1214 +++++ - .../ti-es8-sgx/services4/3rdparty/linux_drm/Kbuild | 69 + - .../services4/3rdparty/linux_drm/Kbuild.mk | 86 + - .../services4/3rdparty/linux_drm/Linux.mk | 45 + - .../services4/3rdparty/linux_drm/pvr_drm_mod.h | 49 + - .../services4/3rdparty/linux_drm/pvr_drm_stubs.c | 228 + - .../services4/include/env/linux/pvr_drm_shared.h | 68 + - .../ti-es8-sgx/services4/include/kernelbuffer.h | 97 + - .../ti-es8-sgx/services4/include/kerneldisplay.h | 238 + - .../staging/ti-es8-sgx/services4/include/pdump.h | 50 + - .../ti-es8-sgx/services4/include/pvr_bridge.h | 1851 ++++++++ - .../ti-es8-sgx/services4/include/pvr_bridge_km.h | 395 ++ - .../staging/ti-es8-sgx/services4/include/pvrmmap.h | 72 + - .../ti-es8-sgx/services4/include/pvrsrv_errors.h | 311 ++ - .../ti-es8-sgx/services4/include/servicesint.h | 554 +++ - .../ti-es8-sgx/services4/include/sgx_bridge.h | 608 +++ - .../ti-es8-sgx/services4/include/sgx_mkif_km.h | 473 ++ - .../services4/include/sgx_ukernel_status_codes.h | 984 ++++ - .../staging/ti-es8-sgx/services4/include/sgxinfo.h | 347 ++ - .../services4/srvkm/bridged/bridged_pvr_bridge.c | 4721 ++++++++++++++++++++ - .../services4/srvkm/bridged/bridged_pvr_bridge.h | 257 ++ - .../services4/srvkm/bridged/bridged_support.c | 113 + - .../services4/srvkm/bridged/bridged_support.h | 68 + - .../srvkm/bridged/sgx/bridged_sgx_bridge.c | 3156 +++++++++++++ - .../srvkm/bridged/sgx/bridged_sgx_bridge.h | 61 + - .../services4/srvkm/common/buffer_manager.c | 3406 ++++++++++++++ - .../services4/srvkm/common/deviceclass.c | 2926 ++++++++++++ - .../ti-es8-sgx/services4/srvkm/common/deviceid.h | 51 + - .../ti-es8-sgx/services4/srvkm/common/devicemem.c | 2645 +++++++++++ - .../ti-es8-sgx/services4/srvkm/common/handle.c | 2548 +++++++++++ - .../ti-es8-sgx/services4/srvkm/common/hash.c | 738 +++ - .../ti-es8-sgx/services4/srvkm/common/lists.c | 156 + - .../ti-es8-sgx/services4/srvkm/common/mem.c | 175 + - .../ti-es8-sgx/services4/srvkm/common/mem_debug.c | 276 ++ - .../ti-es8-sgx/services4/srvkm/common/metrics.c | 208 + - .../services4/srvkm/common/osfunc_common.c | 46 + - .../services4/srvkm/common/pdump_common.c | 3056 +++++++++++++ - .../ti-es8-sgx/services4/srvkm/common/perproc.c | 398 ++ - .../ti-es8-sgx/services4/srvkm/common/power.c | 996 +++++ - .../ti-es8-sgx/services4/srvkm/common/pvrsrv.c | 1836 ++++++++ - .../ti-es8-sgx/services4/srvkm/common/queue.c | 1585 +++++++ - .../staging/ti-es8-sgx/services4/srvkm/common/ra.c | 2208 +++++++++ - .../ti-es8-sgx/services4/srvkm/common/refcount.c | 675 +++ - .../ti-es8-sgx/services4/srvkm/common/resman.c | 987 ++++ - .../ti-es8-sgx/services4/srvkm/common/ttrace.c | 597 +++ - .../ti-es8-sgx/services4/srvkm/devices/sgx/mmu.c | 4661 +++++++++++++++++++ - .../ti-es8-sgx/services4/srvkm/devices/sgx/mmu.h | 501 +++ - .../ti-es8-sgx/services4/srvkm/devices/sgx/pb.c | 493 ++ - .../services4/srvkm/devices/sgx/sgx_bridge_km.h | 254 ++ - .../services4/srvkm/devices/sgx/sgxconfig.h | 457 ++ - .../services4/srvkm/devices/sgx/sgxinfokm.h | 594 +++ - .../services4/srvkm/devices/sgx/sgxinit.c | 3388 ++++++++++++++ - .../services4/srvkm/devices/sgx/sgxkick.c | 839 ++++ - .../services4/srvkm/devices/sgx/sgxpower.c | 650 +++ - .../services4/srvkm/devices/sgx/sgxreset.c | 818 ++++ - .../services4/srvkm/devices/sgx/sgxtransfer.c | 897 ++++ - .../services4/srvkm/devices/sgx/sgxutils.c | 1919 ++++++++ - .../services4/srvkm/devices/sgx/sgxutils.h | 195 + - .../ti-es8-sgx/services4/srvkm/env/linux/Kbuild.mk | 168 + - .../ti-es8-sgx/services4/srvkm/env/linux/Linux.mk | 45 + - .../services4/srvkm/env/linux/env_data.h | 93 + - .../services4/srvkm/env/linux/env_perproc.h | 79 + - .../ti-es8-sgx/services4/srvkm/env/linux/event.c | 413 ++ - .../ti-es8-sgx/services4/srvkm/env/linux/event.h | 48 + - .../ti-es8-sgx/services4/srvkm/env/linux/ion.c | 423 ++ - .../ti-es8-sgx/services4/srvkm/env/linux/ion.h | 83 + - .../ti-es8-sgx/services4/srvkm/env/linux/linkage.h | 72 + - .../ti-es8-sgx/services4/srvkm/env/linux/lock.h | 56 + - .../ti-es8-sgx/services4/srvkm/env/linux/mm.c | 2868 ++++++++++++ - .../ti-es8-sgx/services4/srvkm/env/linux/mm.h | 733 +++ - .../ti-es8-sgx/services4/srvkm/env/linux/mmap.c | 1653 +++++++ - .../ti-es8-sgx/services4/srvkm/env/linux/mmap.h | 231 + - .../ti-es8-sgx/services4/srvkm/env/linux/module.c | 1311 ++++++ - .../ti-es8-sgx/services4/srvkm/env/linux/mutex.c | 162 + - .../ti-es8-sgx/services4/srvkm/env/linux/mutex.h | 99 + - .../ti-es8-sgx/services4/srvkm/env/linux/mutils.c | 165 + - .../ti-es8-sgx/services4/srvkm/env/linux/mutils.h | 118 + - .../ti-es8-sgx/services4/srvkm/env/linux/osfunc.c | 4630 +++++++++++++++++++ - .../services4/srvkm/env/linux/osperproc.c | 154 + - .../ti-es8-sgx/services4/srvkm/env/linux/pdump.c | 855 ++++ - .../services4/srvkm/env/linux/private_data.h | 90 + - .../ti-es8-sgx/services4/srvkm/env/linux/proc.c | 1493 +++++++ - .../ti-es8-sgx/services4/srvkm/env/linux/proc.h | 139 + - .../services4/srvkm/env/linux/pvr_bridge_k.c | 524 +++ - .../services4/srvkm/env/linux/pvr_debug.c | 506 +++ - .../ti-es8-sgx/services4/srvkm/env/linux/pvr_drm.c | 742 +++ - .../ti-es8-sgx/services4/srvkm/env/linux/pvr_drm.h | 158 + - .../services4/srvkm/env/linux/pvr_uaccess.h | 87 + - .../ti-es8-sgx/services4/srvkm/hwdefs/ocpdefs.h | 308 ++ - .../ti-es8-sgx/services4/srvkm/hwdefs/sgx530defs.h | 541 +++ - .../ti-es8-sgx/services4/srvkm/hwdefs/sgx540defs.h | 604 +++ - .../ti-es8-sgx/services4/srvkm/hwdefs/sgx544defs.h | 1486 ++++++ - .../ti-es8-sgx/services4/srvkm/hwdefs/sgxdefs.h | 112 + - .../ti-es8-sgx/services4/srvkm/hwdefs/sgxerrata.h | 480 ++ - .../services4/srvkm/hwdefs/sgxfeaturedefs.h | 270 ++ - .../ti-es8-sgx/services4/srvkm/hwdefs/sgxmmu.h | 99 + - .../ti-es8-sgx/services4/srvkm/hwdefs/sgxmpdefs.h | 364 ++ - .../services4/srvkm/include/buffer_manager.h | 623 +++ - .../ti-es8-sgx/services4/srvkm/include/device.h | 409 ++ - .../ti-es8-sgx/services4/srvkm/include/devicemem.h | 52 + - .../ti-es8-sgx/services4/srvkm/include/handle.h | 547 +++ - .../ti-es8-sgx/services4/srvkm/include/hash.h | 275 ++ - .../ti-es8-sgx/services4/srvkm/include/lists.h | 349 ++ - .../ti-es8-sgx/services4/srvkm/include/metrics.h | 146 + - .../ti-es8-sgx/services4/srvkm/include/osfunc.h | 785 ++++ - .../ti-es8-sgx/services4/srvkm/include/osperproc.h | 94 + - .../ti-es8-sgx/services4/srvkm/include/pdump_int.h | 99 + - .../ti-es8-sgx/services4/srvkm/include/pdump_km.h | 444 ++ - .../services4/srvkm/include/pdump_osfunc.h | 385 ++ - .../ti-es8-sgx/services4/srvkm/include/perfkm.h | 53 + - .../ti-es8-sgx/services4/srvkm/include/perproc.h | 141 + - .../ti-es8-sgx/services4/srvkm/include/power.h | 140 + - .../ti-es8-sgx/services4/srvkm/include/queue.h | 151 + - .../ti-es8-sgx/services4/srvkm/include/ra.h | 289 ++ - .../ti-es8-sgx/services4/srvkm/include/refcount.h | 246 + - .../ti-es8-sgx/services4/srvkm/include/resman.h | 151 + - .../services4/srvkm/include/services_headers.h | 67 + - .../ti-es8-sgx/services4/srvkm/include/srvkm.h | 129 + - .../ti-es8-sgx/services4/srvkm/include/ttrace.h | 200 + - .../services4/srvkm/include/ttrace_common.h | 146 + - .../services4/srvkm/include/ttrace_tokens.h | 119 + - .../services4/system/include/syscommon.h | 391 ++ - .../ti-es8-sgx/services4/system/omap/oemfuncs.h | 78 + - .../ti-es8-sgx/services4/system/omap/sysconfig.c | 1274 ++++++ - .../ti-es8-sgx/services4/system/omap/sysconfig.h | 105 + - .../ti-es8-sgx/services4/system/omap/sysinfo.h | 70 + - .../ti-es8-sgx/services4/system/omap/syslocal.h | 259 ++ - .../ti-es8-sgx/services4/system/omap/sysutils.c | 47 + - .../services4/system/omap/sysutils_linux.c | 865 ++++ - .../ti-es8-sgx/services4/system/omap3/oemfuncs.h | 78 + - .../ti-es8-sgx/services4/system/omap3/sysconfig.c | 1274 ++++++ - .../ti-es8-sgx/services4/system/omap3/sysconfig.h | 109 + - .../ti-es8-sgx/services4/system/omap3/sysinfo.h | 70 + - .../ti-es8-sgx/services4/system/omap3/syslocal.h | 264 ++ - .../ti-es8-sgx/services4/system/omap3/sysutils.c | 47 + - .../services4/system/omap3/sysutils_linux.c | 958 ++++ - .../services4/system/omap3630/oemfuncs.h | 78 + - .../services4/system/omap3630/sysconfig.c | 1274 ++++++ - .../services4/system/omap3630/sysconfig.h | 109 + - .../ti-es8-sgx/services4/system/omap3630/sysinfo.h | 70 + - .../services4/system/omap3630/syslocal.h | 264 ++ - .../services4/system/omap3630/sysutils.c | 47 + - .../services4/system/omap3630/sysutils_linux.c | 958 ++++ - .../ti-es8-sgx/services4/system/omap4/oemfuncs.h | 78 + - .../ti-es8-sgx/services4/system/omap4/sysconfig.c | 1298 ++++++ - .../ti-es8-sgx/services4/system/omap4/sysconfig.h | 110 + - .../ti-es8-sgx/services4/system/omap4/sysinfo.h | 64 + - .../ti-es8-sgx/services4/system/omap4/syslocal.h | 256 ++ - .../ti-es8-sgx/services4/system/omap4/sysutils.c | 47 + - .../services4/system/omap4/sysutils_linux.c | 849 ++++ - .../ti-es8-sgx/services4/system/ti335x/oemfuncs.h | 78 + - .../ti-es8-sgx/services4/system/ti335x/sysconfig.c | 1274 ++++++ - .../ti-es8-sgx/services4/system/ti335x/sysconfig.h | 109 + - .../ti-es8-sgx/services4/system/ti335x/sysinfo.h | 70 + - .../ti-es8-sgx/services4/system/ti335x/syslocal.h | 264 ++ - .../ti-es8-sgx/services4/system/ti335x/sysutils.c | 47 + - .../services4/system/ti335x/sysutils_linux.c | 963 ++++ - .../ti-es8-sgx/services4/system/ti43xx/oemfuncs.h | 78 + - .../ti-es8-sgx/services4/system/ti43xx/sysconfig.c | 1274 ++++++ - .../ti-es8-sgx/services4/system/ti43xx/sysconfig.h | 109 + - .../ti-es8-sgx/services4/system/ti43xx/sysinfo.h | 70 + - .../ti-es8-sgx/services4/system/ti43xx/syslocal.h | 264 ++ - .../ti-es8-sgx/services4/system/ti43xx/sysutils.c | 47 + - .../services4/system/ti43xx/sysutils_linux.c | 982 ++++ - .../ti-es8-sgx/services4/system/ti81xx/oemfuncs.h | 55 + - .../ti-es8-sgx/services4/system/ti81xx/sysconfig.c | 969 ++++ - .../ti-es8-sgx/services4/system/ti81xx/sysconfig.h | 59 + - .../ti-es8-sgx/services4/system/ti81xx/sysinfo.h | 41 + - .../ti-es8-sgx/services4/system/ti81xx/syslocal.h | 210 + - .../ti-es8-sgx/services4/system/ti81xx/sysutils.c | 29 + - .../services4/system/ti81xx/sysutils_linux.c | 576 +++ - 253 files changed, 130826 insertions(+) - create mode 100644 drivers/staging/ti-es8-sgx/COPYING - create mode 100644 drivers/staging/ti-es8-sgx/GPL-COPYING - create mode 100644 drivers/staging/ti-es8-sgx/INSTALL - create mode 100644 drivers/staging/ti-es8-sgx/Kbuild - create mode 100644 drivers/staging/ti-es8-sgx/MIT-COPYING - create mode 100644 drivers/staging/ti-es8-sgx/Makefile - create mode 100644 drivers/staging/ti-es8-sgx/README - create mode 100644 drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/bits.mk - create mode 100644 drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/buildvars.mk - create mode 100644 drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/commands.mk - create mode 100644 drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/common/apis/xorg.mk - create mode 100644 drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/common/dridrm.mk - create mode 100644 drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/common/omap4.mk - create mode 100644 drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/common/opencl.mk - create mode 100644 drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/common/xorg.mk - create mode 100644 drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/common/xorg_test.mk - create mode 100644 drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/config/core.mk - create mode 100644 drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/defs.mk - create mode 100644 drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/kbuild/Makefile.template - create mode 100644 drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/kbuild/external_tarball.mk - create mode 100644 drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/kbuild/kbuild.mk - create mode 100644 drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/kernel_module.mk - create mode 100644 drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/kernel_version.mk - create mode 100644 drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/moduledefs.mk - create mode 100644 drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/modules.mk - create mode 100644 drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/omap4430_linux/Makefile - create mode 100644 drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/omap_linux/Makefile - create mode 100644 drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/prepare_tree.mk - create mode 100644 drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/this_makefile.mk - create mode 100644 drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/tools/cc-check.sh - create mode 100644 drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/toplevel.mk - create mode 100644 drivers/staging/ti-es8-sgx/include4/dbgdrvif.h - create mode 100644 drivers/staging/ti-es8-sgx/include4/img_defs.h - create mode 100644 drivers/staging/ti-es8-sgx/include4/img_types.h - create mode 100644 drivers/staging/ti-es8-sgx/include4/pdumpdefs.h - create mode 100644 drivers/staging/ti-es8-sgx/include4/pvr_debug.h - create mode 100644 drivers/staging/ti-es8-sgx/include4/pvrmodule.h - create mode 100644 drivers/staging/ti-es8-sgx/include4/pvrversion.h - create mode 100644 drivers/staging/ti-es8-sgx/include4/services.h - create mode 100644 drivers/staging/ti-es8-sgx/include4/servicesext.h - create mode 100644 drivers/staging/ti-es8-sgx/include4/sgx_options.h - create mode 100644 drivers/staging/ti-es8-sgx/include4/sgxapi_km.h - create mode 100644 drivers/staging/ti-es8-sgx/include4/sgxscript.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_example/Kbuild.mk - create mode 100644 drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_example/Linux.mk - create mode 100644 drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_example/bufferclass_example.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_example/bufferclass_example.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_example/bufferclass_example_linux.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_example/bufferclass_example_linux.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_example/bufferclass_example_private.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_example/bufferclass_example_private.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_ti/Kbuild - create mode 100644 drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_ti/Makefile - create mode 100644 drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_ti/bc_cat.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_ti/bc_cat.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/3rdparty/dc_omapfb3_linux/3rdparty_dc_drm_shared.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/3rdparty/dc_omapfb3_linux/Kbuild - create mode 100644 drivers/staging/ti-es8-sgx/services4/3rdparty/dc_omapfb3_linux/Kbuild.mk - create mode 100644 drivers/staging/ti-es8-sgx/services4/3rdparty/dc_omapfb3_linux/Linux.mk - create mode 100644 drivers/staging/ti-es8-sgx/services4/3rdparty/dc_omapfb3_linux/omaplfb.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/3rdparty/dc_omapfb3_linux/omaplfb_displayclass.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/3rdparty/dc_omapfb3_linux/omaplfb_linux.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti335x_linux/3rdparty_dc_drm_shared.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti335x_linux/Kbuild - create mode 100644 drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti335x_linux/Kbuild.mk - create mode 100644 drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti335x_linux/Linux.mk - create mode 100644 drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti335x_linux/omaplfb.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti335x_linux/omaplfb_displayclass.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti335x_linux/omaplfb_linux.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti43xx_linux/3rdparty_dc_drm_shared.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti43xx_linux/Kbuild - create mode 100644 drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti43xx_linux/Kbuild.mk - create mode 100644 drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti43xx_linux/Linux.mk - create mode 100644 drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti43xx_linux/omaplfb.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti43xx_linux/omaplfb_displayclass.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti43xx_linux/omaplfb_linux.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti81xx_linux/3rdparty_dc_drm_shared.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti81xx_linux/Kbuild - create mode 100644 drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti81xx_linux/Kbuild.mk - create mode 100644 drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti81xx_linux/Linux.mk - create mode 100644 drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti81xx_linux/omaplfb.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti81xx_linux/omaplfb_displayclass.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti81xx_linux/omaplfb_linux.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/3rdparty/linux_drm/Kbuild - create mode 100644 drivers/staging/ti-es8-sgx/services4/3rdparty/linux_drm/Kbuild.mk - create mode 100644 drivers/staging/ti-es8-sgx/services4/3rdparty/linux_drm/Linux.mk - create mode 100644 drivers/staging/ti-es8-sgx/services4/3rdparty/linux_drm/pvr_drm_mod.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/3rdparty/linux_drm/pvr_drm_stubs.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/include/env/linux/pvr_drm_shared.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/include/kernelbuffer.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/include/kerneldisplay.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/include/pdump.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/include/pvr_bridge.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/include/pvr_bridge_km.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/include/pvrmmap.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/include/pvrsrv_errors.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/include/servicesint.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/include/sgx_bridge.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/include/sgx_mkif_km.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/include/sgx_ukernel_status_codes.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/include/sgxinfo.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/bridged/bridged_pvr_bridge.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/bridged/bridged_pvr_bridge.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/bridged/bridged_support.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/bridged/bridged_support.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/bridged/sgx/bridged_sgx_bridge.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/bridged/sgx/bridged_sgx_bridge.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/common/buffer_manager.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/common/deviceclass.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/common/deviceid.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/common/devicemem.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/common/handle.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/common/hash.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/common/lists.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/common/mem.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/common/mem_debug.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/common/metrics.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/common/osfunc_common.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/common/pdump_common.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/common/perproc.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/common/power.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/common/pvrsrv.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/common/queue.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/common/ra.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/common/refcount.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/common/resman.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/common/ttrace.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/mmu.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/mmu.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/pb.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/sgx_bridge_km.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/sgxconfig.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/sgxinfokm.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/sgxinit.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/sgxkick.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/sgxpower.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/sgxreset.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/sgxtransfer.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/sgxutils.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/sgxutils.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/Kbuild.mk - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/Linux.mk - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/env_data.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/env_perproc.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/event.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/event.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/ion.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/ion.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/linkage.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/lock.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/mm.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/mm.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/mmap.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/mmap.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/module.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/mutex.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/mutex.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/mutils.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/mutils.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/osfunc.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/osperproc.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/pdump.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/private_data.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/proc.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/proc.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/pvr_bridge_k.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/pvr_debug.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/pvr_drm.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/pvr_drm.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/pvr_uaccess.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/hwdefs/ocpdefs.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/hwdefs/sgx530defs.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/hwdefs/sgx540defs.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/hwdefs/sgx544defs.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/hwdefs/sgxdefs.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/hwdefs/sgxerrata.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/hwdefs/sgxfeaturedefs.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/hwdefs/sgxmmu.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/hwdefs/sgxmpdefs.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/include/buffer_manager.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/include/device.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/include/devicemem.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/include/handle.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/include/hash.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/include/lists.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/include/metrics.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/include/osfunc.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/include/osperproc.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/include/pdump_int.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/include/pdump_km.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/include/pdump_osfunc.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/include/perfkm.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/include/perproc.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/include/power.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/include/queue.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/include/ra.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/include/refcount.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/include/resman.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/include/services_headers.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/include/srvkm.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/include/ttrace.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/include/ttrace_common.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/srvkm/include/ttrace_tokens.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/include/syscommon.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/omap/oemfuncs.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/omap/sysconfig.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/omap/sysconfig.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/omap/sysinfo.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/omap/syslocal.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/omap/sysutils.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/omap/sysutils_linux.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/omap3/oemfuncs.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/omap3/sysconfig.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/omap3/sysconfig.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/omap3/sysinfo.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/omap3/syslocal.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/omap3/sysutils.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/omap3/sysutils_linux.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/omap3630/oemfuncs.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/omap3630/sysconfig.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/omap3630/sysconfig.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/omap3630/sysinfo.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/omap3630/syslocal.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/omap3630/sysutils.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/omap3630/sysutils_linux.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/omap4/oemfuncs.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/omap4/sysconfig.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/omap4/sysconfig.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/omap4/sysinfo.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/omap4/syslocal.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/omap4/sysutils.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/omap4/sysutils_linux.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/ti335x/oemfuncs.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/ti335x/sysconfig.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/ti335x/sysconfig.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/ti335x/sysinfo.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/ti335x/syslocal.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/ti335x/sysutils.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/ti335x/sysutils_linux.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/ti43xx/oemfuncs.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/ti43xx/sysconfig.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/ti43xx/sysconfig.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/ti43xx/sysinfo.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/ti43xx/syslocal.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/ti43xx/sysutils.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/ti43xx/sysutils_linux.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/ti81xx/oemfuncs.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/ti81xx/sysconfig.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/ti81xx/sysconfig.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/ti81xx/sysinfo.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/ti81xx/syslocal.h - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/ti81xx/sysutils.c - create mode 100644 drivers/staging/ti-es8-sgx/services4/system/ti81xx/sysutils_linux.c - -diff --git a/drivers/staging/ti-es8-sgx/COPYING b/drivers/staging/ti-es8-sgx/COPYING -new file mode 100644 -index 0000000..21aa193 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/COPYING -@@ -0,0 +1,350 @@ -+ -+This software is Copyright (C) Imagination Technologies Ltd. -+ All rights reserved. -+ -+You may use, distribute and copy this software under the terms of -+GNU General Public License version 2, which is displayed below. -+ -+------------------------------------------------------------------------- -+ -+ GNU GENERAL PUBLIC LICENSE -+ Version 2, June 1991 -+ -+ Copyright (C) 1989, 1991 Free Software Foundation, Inc. -+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ Everyone is permitted to copy and distribute verbatim copies -+ of this license document, but changing it is not allowed. -+ -+ Preamble -+ -+ The licenses for most software are designed to take away your -+freedom to share and change it. By contrast, the GNU General Public -+License is intended to guarantee your freedom to share and change free -+software--to make sure the software is free for all its users. This -+General Public License applies to most of the Free Software -+Foundation's software and to any other program whose authors commit to -+using it. (Some other Free Software Foundation software is covered by -+the GNU Library General Public License instead.) You can apply it to -+your programs, too. -+ -+ When we speak of free software, we are referring to freedom, not -+price. Our General Public Licenses are designed to make sure that you -+have the freedom to distribute copies of free software (and charge for -+this service if you wish), that you receive source code or can get it -+if you want it, that you can change the software or use pieces of it -+in new free programs; and that you know you can do these things. -+ -+ To protect your rights, we need to make restrictions that forbid -+anyone to deny you these rights or to ask you to surrender the rights. -+These restrictions translate to certain responsibilities for you if you -+distribute copies of the software, or if you modify it. -+ -+ For example, if you distribute copies of such a program, whether -+gratis or for a fee, you must give the recipients all the rights that -+you have. You must make sure that they, too, receive or can get the -+source code. And you must show them these terms so they know their -+rights. -+ -+ We protect your rights with two steps: (1) copyright the software, and -+(2) offer you this license which gives you legal permission to copy, -+distribute and/or modify the software. -+ -+ Also, for each author's protection and ours, we want to make certain -+that everyone understands that there is no warranty for this free -+software. If the software is modified by someone else and passed on, we -+want its recipients to know that what they have is not the original, so -+that any problems introduced by others will not reflect on the original -+authors' reputations. -+ -+ Finally, any free program is threatened constantly by software -+patents. We wish to avoid the danger that redistributors of a free -+program will individually obtain patent licenses, in effect making the -+program proprietary. To prevent this, we have made it clear that any -+patent must be licensed for everyone's free use or not licensed at all. -+ -+ The precise terms and conditions for copying, distribution and -+modification follow. -+ -+ GNU GENERAL PUBLIC LICENSE -+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION -+ -+ 0. This License applies to any program or other work which contains -+a notice placed by the copyright holder saying it may be distributed -+under the terms of this General Public License. The "Program", below, -+refers to any such program or work, and a "work based on the Program" -+means either the Program or any derivative work under copyright law: -+that is to say, a work containing the Program or a portion of it, -+either verbatim or with modifications and/or translated into another -+language. (Hereinafter, translation is included without limitation in -+the term "modification".) Each licensee is addressed as "you". -+ -+Activities other than copying, distribution and modification are not -+covered by this License; they are outside its scope. The act of -+running the Program is not restricted, and the output from the Program -+is covered only if its contents constitute a work based on the -+Program (independent of having been made by running the Program). -+Whether that is true depends on what the Program does. -+ -+ 1. You may copy and distribute verbatim copies of the Program's -+source code as you receive it, in any medium, provided that you -+conspicuously and appropriately publish on each copy an appropriate -+copyright notice and disclaimer of warranty; keep intact all the -+notices that refer to this License and to the absence of any warranty; -+and give any other recipients of the Program a copy of this License -+along with the Program. -+ -+You may charge a fee for the physical act of transferring a copy, and -+you may at your option offer warranty protection in exchange for a fee. -+ -+ 2. You may modify your copy or copies of the Program or any portion -+of it, thus forming a work based on the Program, and copy and -+distribute such modifications or work under the terms of Section 1 -+above, provided that you also meet all of these conditions: -+ -+ a) You must cause the modified files to carry prominent notices -+ stating that you changed the files and the date of any change. -+ -+ b) You must cause any work that you distribute or publish, that in -+ whole or in part contains or is derived from the Program or any -+ part thereof, to be licensed as a whole at no charge to all third -+ parties under the terms of this License. -+ -+ c) If the modified program normally reads commands interactively -+ when run, you must cause it, when started running for such -+ interactive use in the most ordinary way, to print or display an -+ announcement including an appropriate copyright notice and a -+ notice that there is no warranty (or else, saying that you provide -+ a warranty) and that users may redistribute the program under -+ these conditions, and telling the user how to view a copy of this -+ License. (Exception: if the Program itself is interactive but -+ does not normally print such an announcement, your work based on -+ the Program is not required to print an announcement.) -+ -+These requirements apply to the modified work as a whole. If -+identifiable sections of that work are not derived from the Program, -+and can be reasonably considered independent and separate works in -+themselves, then this License, and its terms, do not apply to those -+sections when you distribute them as separate works. But when you -+distribute the same sections as part of a whole which is a work based -+on the Program, the distribution of the whole must be on the terms of -+this License, whose permissions for other licensees extend to the -+entire whole, and thus to each and every part regardless of who wrote it. -+ -+Thus, it is not the intent of this section to claim rights or contest -+your rights to work written entirely by you; rather, the intent is to -+exercise the right to control the distribution of derivative or -+collective works based on the Program. -+ -+In addition, mere aggregation of another work not based on the Program -+with the Program (or with a work based on the Program) on a volume of -+a storage or distribution medium does not bring the other work under -+the scope of this License. -+ -+ 3. You may copy and distribute the Program (or a work based on it, -+under Section 2) in object code or executable form under the terms of -+Sections 1 and 2 above provided that you also do one of the following: -+ -+ a) Accompany it with the complete corresponding machine-readable -+ source code, which must be distributed under the terms of Sections -+ 1 and 2 above on a medium customarily used for software interchange; or, -+ -+ b) Accompany it with a written offer, valid for at least three -+ years, to give any third party, for a charge no more than your -+ cost of physically performing source distribution, a complete -+ machine-readable copy of the corresponding source code, to be -+ distributed under the terms of Sections 1 and 2 above on a medium -+ customarily used for software interchange; or, -+ -+ c) Accompany it with the information you received as to the offer -+ to distribute corresponding source code. (This alternative is -+ allowed only for noncommercial distribution and only if you -+ received the program in object code or executable form with such -+ an offer, in accord with Subsection b above.) -+ -+The source code for a work means the preferred form of the work for -+making modifications to it. For an executable work, complete source -+code means all the source code for all modules it contains, plus any -+associated interface definition files, plus the scripts used to -+control compilation and installation of the executable. However, as a -+special exception, the source code distributed need not include -+anything that is normally distributed (in either source or binary -+form) with the major components (compiler, kernel, and so on) of the -+operating system on which the executable runs, unless that component -+itself accompanies the executable. -+ -+If distribution of executable or object code is made by offering -+access to copy from a designated place, then offering equivalent -+access to copy the source code from the same place counts as -+distribution of the source code, even though third parties are not -+compelled to copy the source along with the object code. -+ -+ 4. You may not copy, modify, sublicense, or distribute the Program -+except as expressly provided under this License. Any attempt -+otherwise to copy, modify, sublicense or distribute the Program is -+void, and will automatically terminate your rights under this License. -+However, parties who have received copies, or rights, from you under -+this License will not have their licenses terminated so long as such -+parties remain in full compliance. -+ -+ 5. You are not required to accept this License, since you have not -+signed it. However, nothing else grants you permission to modify or -+distribute the Program or its derivative works. These actions are -+prohibited by law if you do not accept this License. Therefore, by -+modifying or distributing the Program (or any work based on the -+Program), you indicate your acceptance of this License to do so, and -+all its terms and conditions for copying, distributing or modifying -+the Program or works based on it. -+ -+ 6. Each time you redistribute the Program (or any work based on the -+Program), the recipient automatically receives a license from the -+original licensor to copy, distribute or modify the Program subject to -+these terms and conditions. You may not impose any further -+restrictions on the recipients' exercise of the rights granted herein. -+You are not responsible for enforcing compliance by third parties to -+this License. -+ -+ 7. If, as a consequence of a court judgment or allegation of patent -+infringement or for any other reason (not limited to patent issues), -+conditions are imposed on you (whether by court order, agreement or -+otherwise) that contradict the conditions of this License, they do not -+excuse you from the conditions of this License. If you cannot -+distribute so as to satisfy simultaneously your obligations under this -+License and any other pertinent obligations, then as a consequence you -+may not distribute the Program at all. For example, if a patent -+license would not permit royalty-free redistribution of the Program by -+all those who receive copies directly or indirectly through you, then -+the only way you could satisfy both it and this License would be to -+refrain entirely from distribution of the Program. -+ -+If any portion of this section is held invalid or unenforceable under -+any particular circumstance, the balance of the section is intended to -+apply and the section as a whole is intended to apply in other -+circumstances. -+ -+It is not the purpose of this section to induce you to infringe any -+patents or other property right claims or to contest validity of any -+such claims; this section has the sole purpose of protecting the -+integrity of the free software distribution system, which is -+implemented by public license practices. Many people have made -+generous contributions to the wide range of software distributed -+through that system in reliance on consistent application of that -+system; it is up to the author/donor to decide if he or she is willing -+to distribute software through any other system and a licensee cannot -+impose that choice. -+ -+This section is intended to make thoroughly clear what is believed to -+be a consequence of the rest of this License. -+ -+ 8. If the distribution and/or use of the Program is restricted in -+certain countries either by patents or by copyrighted interfaces, the -+original copyright holder who places the Program under this License -+may add an explicit geographical distribution limitation excluding -+those countries, so that distribution is permitted only in or among -+countries not thus excluded. In such case, this License incorporates -+the limitation as if written in the body of this License. -+ -+ 9. The Free Software Foundation may publish revised and/or new versions -+of the General Public License from time to time. Such new versions will -+be similar in spirit to the present version, but may differ in detail to -+address new problems or concerns. -+ -+Each version is given a distinguishing version number. If the Program -+specifies a version number of this License which applies to it and "any -+later version", you have the option of following the terms and conditions -+either of that version or of any later version published by the Free -+Software Foundation. If the Program does not specify a version number of -+this License, you may choose any version ever published by the Free Software -+Foundation. -+ -+ 10. If you wish to incorporate parts of the Program into other free -+programs whose distribution conditions are different, write to the author -+to ask for permission. For software which is copyrighted by the Free -+Software Foundation, write to the Free Software Foundation; we sometimes -+make exceptions for this. Our decision will be guided by the two goals -+of preserving the free status of all derivatives of our free software and -+of promoting the sharing and reuse of software generally. -+ -+ NO WARRANTY -+ -+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -+REPAIR OR CORRECTION. -+ -+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -+POSSIBILITY OF SUCH DAMAGES. -+ -+ END OF TERMS AND CONDITIONS -+ -+ Appendix: How to Apply These Terms to Your New Programs -+ -+ If you develop a new program, and you want it to be of the greatest -+possible use to the public, the best way to achieve this is to make it -+free software which everyone can redistribute and change under these terms. -+ -+ To do so, attach the following notices to the program. It is safest -+to attach them to the start of each source file to most effectively -+convey the exclusion of warranty; and each file should have at least -+the "copyright" line and a pointer to where the full notice is found. -+ -+ <one line to give the program's name and a brief idea of what it does.> -+ Copyright (C) 19yy <name of author> -+ -+ This program is free software; you can redistribute it and/or modify -+ it under the terms of the GNU General Public License as published by -+ the Free Software Foundation; either version 2 of the License, or -+ (at your option) any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; if not, write to the Free Software -+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ -+Also add information on how to contact you by electronic and paper mail. -+ -+If the program is interactive, make it output a short notice like this -+when it starts in an interactive mode: -+ -+ Gnomovision version 69, Copyright (C) 19yy name of author -+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. -+ This is free software, and you are welcome to redistribute it -+ under certain conditions; type `show c' for details. -+ -+The hypothetical commands `show w' and `show c' should show the appropriate -+parts of the General Public License. Of course, the commands you use may -+be called something other than `show w' and `show c'; they could even be -+mouse-clicks or menu items--whatever suits your program. -+ -+You should also get your employer (if you work as a programmer) or your -+school, if any, to sign a "copyright disclaimer" for the program, if -+necessary. Here is a sample; alter the names: -+ -+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program -+ `Gnomovision' (which makes passes at compilers) written by James Hacker. -+ -+ <signature of Ty Coon>, 1 April 1989 -+ Ty Coon, President of Vice -+ -+This General Public License does not permit incorporating your program into -+proprietary programs. If your program is a subroutine library, you may -+consider it more useful to permit linking proprietary applications with the -+library. If this is what you want to do, use the GNU Library General -+Public License instead of this License. -+ -+------------------------------------------------------------------------- -diff --git a/drivers/staging/ti-es8-sgx/GPL-COPYING b/drivers/staging/ti-es8-sgx/GPL-COPYING -new file mode 100644 -index 0000000..79bf23e ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/GPL-COPYING -@@ -0,0 +1,343 @@ -+------------------------------------------------------------------------- -+ -+ GNU GENERAL PUBLIC LICENSE -+ Version 2, June 1991 -+ -+ Copyright (C) 1989, 1991 Free Software Foundation, Inc. -+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ Everyone is permitted to copy and distribute verbatim copies -+ of this license document, but changing it is not allowed. -+ -+ Preamble -+ -+ The licenses for most software are designed to take away your -+freedom to share and change it. By contrast, the GNU General Public -+License is intended to guarantee your freedom to share and change free -+software--to make sure the software is free for all its users. This -+General Public License applies to most of the Free Software -+Foundation's software and to any other program whose authors commit to -+using it. (Some other Free Software Foundation software is covered by -+the GNU Library General Public License instead.) You can apply it to -+your programs, too. -+ -+ When we speak of free software, we are referring to freedom, not -+price. Our General Public Licenses are designed to make sure that you -+have the freedom to distribute copies of free software (and charge for -+this service if you wish), that you receive source code or can get it -+if you want it, that you can change the software or use pieces of it -+in new free programs; and that you know you can do these things. -+ -+ To protect your rights, we need to make restrictions that forbid -+anyone to deny you these rights or to ask you to surrender the rights. -+These restrictions translate to certain responsibilities for you if you -+distribute copies of the software, or if you modify it. -+ -+ For example, if you distribute copies of such a program, whether -+gratis or for a fee, you must give the recipients all the rights that -+you have. You must make sure that they, too, receive or can get the -+source code. And you must show them these terms so they know their -+rights. -+ -+ We protect your rights with two steps: (1) copyright the software, and -+(2) offer you this license which gives you legal permission to copy, -+distribute and/or modify the software. -+ -+ Also, for each author's protection and ours, we want to make certain -+that everyone understands that there is no warranty for this free -+software. If the software is modified by someone else and passed on, we -+want its recipients to know that what they have is not the original, so -+that any problems introduced by others will not reflect on the original -+authors' reputations. -+ -+ Finally, any free program is threatened constantly by software -+patents. We wish to avoid the danger that redistributors of a free -+program will individually obtain patent licenses, in effect making the -+program proprietary. To prevent this, we have made it clear that any -+patent must be licensed for everyone's free use or not licensed at all. -+ -+ The precise terms and conditions for copying, distribution and -+modification follow. -+ -+ GNU GENERAL PUBLIC LICENSE -+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION -+ -+ 0. This License applies to any program or other work which contains -+a notice placed by the copyright holder saying it may be distributed -+under the terms of this General Public License. The "Program", below, -+refers to any such program or work, and a "work based on the Program" -+means either the Program or any derivative work under copyright law: -+that is to say, a work containing the Program or a portion of it, -+either verbatim or with modifications and/or translated into another -+language. (Hereinafter, translation is included without limitation in -+the term "modification".) Each licensee is addressed as "you". -+ -+Activities other than copying, distribution and modification are not -+covered by this License; they are outside its scope. The act of -+running the Program is not restricted, and the output from the Program -+is covered only if its contents constitute a work based on the -+Program (independent of having been made by running the Program). -+Whether that is true depends on what the Program does. -+ -+ 1. You may copy and distribute verbatim copies of the Program's -+source code as you receive it, in any medium, provided that you -+conspicuously and appropriately publish on each copy an appropriate -+copyright notice and disclaimer of warranty; keep intact all the -+notices that refer to this License and to the absence of any warranty; -+and give any other recipients of the Program a copy of this License -+along with the Program. -+ -+You may charge a fee for the physical act of transferring a copy, and -+you may at your option offer warranty protection in exchange for a fee. -+ -+ 2. You may modify your copy or copies of the Program or any portion -+of it, thus forming a work based on the Program, and copy and -+distribute such modifications or work under the terms of Section 1 -+above, provided that you also meet all of these conditions: -+ -+ a) You must cause the modified files to carry prominent notices -+ stating that you changed the files and the date of any change. -+ -+ b) You must cause any work that you distribute or publish, that in -+ whole or in part contains or is derived from the Program or any -+ part thereof, to be licensed as a whole at no charge to all third -+ parties under the terms of this License. -+ -+ c) If the modified program normally reads commands interactively -+ when run, you must cause it, when started running for such -+ interactive use in the most ordinary way, to print or display an -+ announcement including an appropriate copyright notice and a -+ notice that there is no warranty (or else, saying that you provide -+ a warranty) and that users may redistribute the program under -+ these conditions, and telling the user how to view a copy of this -+ License. (Exception: if the Program itself is interactive but -+ does not normally print such an announcement, your work based on -+ the Program is not required to print an announcement.) -+ -+These requirements apply to the modified work as a whole. If -+identifiable sections of that work are not derived from the Program, -+and can be reasonably considered independent and separate works in -+themselves, then this License, and its terms, do not apply to those -+sections when you distribute them as separate works. But when you -+distribute the same sections as part of a whole which is a work based -+on the Program, the distribution of the whole must be on the terms of -+this License, whose permissions for other licensees extend to the -+entire whole, and thus to each and every part regardless of who wrote it. -+ -+Thus, it is not the intent of this section to claim rights or contest -+your rights to work written entirely by you; rather, the intent is to -+exercise the right to control the distribution of derivative or -+collective works based on the Program. -+ -+In addition, mere aggregation of another work not based on the Program -+with the Program (or with a work based on the Program) on a volume of -+a storage or distribution medium does not bring the other work under -+the scope of this License. -+ -+ 3. You may copy and distribute the Program (or a work based on it, -+under Section 2) in object code or executable form under the terms of -+Sections 1 and 2 above provided that you also do one of the following: -+ -+ a) Accompany it with the complete corresponding machine-readable -+ source code, which must be distributed under the terms of Sections -+ 1 and 2 above on a medium customarily used for software interchange; or, -+ -+ b) Accompany it with a written offer, valid for at least three -+ years, to give any third party, for a charge no more than your -+ cost of physically performing source distribution, a complete -+ machine-readable copy of the corresponding source code, to be -+ distributed under the terms of Sections 1 and 2 above on a medium -+ customarily used for software interchange; or, -+ -+ c) Accompany it with the information you received as to the offer -+ to distribute corresponding source code. (This alternative is -+ allowed only for noncommercial distribution and only if you -+ received the program in object code or executable form with such -+ an offer, in accord with Subsection b above.) -+ -+The source code for a work means the preferred form of the work for -+making modifications to it. For an executable work, complete source -+code means all the source code for all modules it contains, plus any -+associated interface definition files, plus the scripts used to -+control compilation and installation of the executable. However, as a -+special exception, the source code distributed need not include -+anything that is normally distributed (in either source or binary -+form) with the major components (compiler, kernel, and so on) of the -+operating system on which the executable runs, unless that component -+itself accompanies the executable. -+ -+If distribution of executable or object code is made by offering -+access to copy from a designated place, then offering equivalent -+access to copy the source code from the same place counts as -+distribution of the source code, even though third parties are not -+compelled to copy the source along with the object code. -+ -+ 4. You may not copy, modify, sublicense, or distribute the Program -+except as expressly provided under this License. Any attempt -+otherwise to copy, modify, sublicense or distribute the Program is -+void, and will automatically terminate your rights under this License. -+However, parties who have received copies, or rights, from you under -+this License will not have their licenses terminated so long as such -+parties remain in full compliance. -+ -+ 5. You are not required to accept this License, since you have not -+signed it. However, nothing else grants you permission to modify or -+distribute the Program or its derivative works. These actions are -+prohibited by law if you do not accept this License. Therefore, by -+modifying or distributing the Program (or any work based on the -+Program), you indicate your acceptance of this License to do so, and -+all its terms and conditions for copying, distributing or modifying -+the Program or works based on it. -+ -+ 6. Each time you redistribute the Program (or any work based on the -+Program), the recipient automatically receives a license from the -+original licensor to copy, distribute or modify the Program subject to -+these terms and conditions. You may not impose any further -+restrictions on the recipients' exercise of the rights granted herein. -+You are not responsible for enforcing compliance by third parties to -+this License. -+ -+ 7. If, as a consequence of a court judgment or allegation of patent -+infringement or for any other reason (not limited to patent issues), -+conditions are imposed on you (whether by court order, agreement or -+otherwise) that contradict the conditions of this License, they do not -+excuse you from the conditions of this License. If you cannot -+distribute so as to satisfy simultaneously your obligations under this -+License and any other pertinent obligations, then as a consequence you -+may not distribute the Program at all. For example, if a patent -+license would not permit royalty-free redistribution of the Program by -+all those who receive copies directly or indirectly through you, then -+the only way you could satisfy both it and this License would be to -+refrain entirely from distribution of the Program. -+ -+If any portion of this section is held invalid or unenforceable under -+any particular circumstance, the balance of the section is intended to -+apply and the section as a whole is intended to apply in other -+circumstances. -+ -+It is not the purpose of this section to induce you to infringe any -+patents or other property right claims or to contest validity of any -+such claims; this section has the sole purpose of protecting the -+integrity of the free software distribution system, which is -+implemented by public license practices. Many people have made -+generous contributions to the wide range of software distributed -+through that system in reliance on consistent application of that -+system; it is up to the author/donor to decide if he or she is willing -+to distribute software through any other system and a licensee cannot -+impose that choice. -+ -+This section is intended to make thoroughly clear what is believed to -+be a consequence of the rest of this License. -+ -+ 8. If the distribution and/or use of the Program is restricted in -+certain countries either by patents or by copyrighted interfaces, the -+original copyright holder who places the Program under this License -+may add an explicit geographical distribution limitation excluding -+those countries, so that distribution is permitted only in or among -+countries not thus excluded. In such case, this License incorporates -+the limitation as if written in the body of this License. -+ -+ 9. The Free Software Foundation may publish revised and/or new versions -+of the General Public License from time to time. Such new versions will -+be similar in spirit to the present version, but may differ in detail to -+address new problems or concerns. -+ -+Each version is given a distinguishing version number. If the Program -+specifies a version number of this License which applies to it and "any -+later version", you have the option of following the terms and conditions -+either of that version or of any later version published by the Free -+Software Foundation. If the Program does not specify a version number of -+this License, you may choose any version ever published by the Free Software -+Foundation. -+ -+ 10. If you wish to incorporate parts of the Program into other free -+programs whose distribution conditions are different, write to the author -+to ask for permission. For software which is copyrighted by the Free -+Software Foundation, write to the Free Software Foundation; we sometimes -+make exceptions for this. Our decision will be guided by the two goals -+of preserving the free status of all derivatives of our free software and -+of promoting the sharing and reuse of software generally. -+ -+ NO WARRANTY -+ -+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -+REPAIR OR CORRECTION. -+ -+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -+POSSIBILITY OF SUCH DAMAGES. -+ -+ END OF TERMS AND CONDITIONS -+ -+ Appendix: How to Apply These Terms to Your New Programs -+ -+ If you develop a new program, and you want it to be of the greatest -+possible use to the public, the best way to achieve this is to make it -+free software which everyone can redistribute and change under these terms. -+ -+ To do so, attach the following notices to the program. It is safest -+to attach them to the start of each source file to most effectively -+convey the exclusion of warranty; and each file should have at least -+the "copyright" line and a pointer to where the full notice is found. -+ -+ <one line to give the program's name and a brief idea of what it does.> -+ Copyright (C) 19yy <name of author> -+ -+ This program is free software; you can redistribute it and/or modify -+ it under the terms of the GNU General Public License as published by -+ the Free Software Foundation; either version 2 of the License, or -+ (at your option) any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; if not, write to the Free Software -+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ -+Also add information on how to contact you by electronic and paper mail. -+ -+If the program is interactive, make it output a short notice like this -+when it starts in an interactive mode: -+ -+ Gnomovision version 69, Copyright (C) 19yy name of author -+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. -+ This is free software, and you are welcome to redistribute it -+ under certain conditions; type `show c' for details. -+ -+The hypothetical commands `show w' and `show c' should show the appropriate -+parts of the General Public License. Of course, the commands you use may -+be called something other than `show w' and `show c'; they could even be -+mouse-clicks or menu items--whatever suits your program. -+ -+You should also get your employer (if you work as a programmer) or your -+school, if any, to sign a "copyright disclaimer" for the program, if -+necessary. Here is a sample; alter the names: -+ -+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program -+ `Gnomovision' (which makes passes at compilers) written by James Hacker. -+ -+ <signature of Ty Coon>, 1 April 1989 -+ Ty Coon, President of Vice -+ -+This General Public License does not permit incorporating your program into -+proprietary programs. If your program is a subroutine library, you may -+consider it more useful to permit linking proprietary applications with the -+library. If this is what you want to do, use the GNU Library General -+Public License instead of this License. -+ -+------------------------------------------------------------------------- -diff --git a/drivers/staging/ti-es8-sgx/INSTALL b/drivers/staging/ti-es8-sgx/INSTALL -new file mode 100644 -index 0000000..aefa6c3 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/INSTALL -@@ -0,0 +1,72 @@ -+ -+SGX Embedded Systems DDK for the Linux kernel. -+Copyright (C) Imagination Technologies Ltd. All rights reserved. -+====================================================================== -+ -+This file covers how to build and install the Imagination Technologies -+SGX DDK for the Linux kernel. -+ -+ -+Build System Environment Variables -+------------------------------------------- -+ -+The SGX DDK Build scripts depend on a number of environment variables -+being setup before compilation or installation of DDK software can -+commence: -+ -+$DISCIMAGE -+The DDK Build scripts install files to the location specified by the -+DISCIMAGE environment variable, when the make install target is used. -+This should point to the target filesystem. -+$ export DISCIMAGE=/path/to/filesystem -+ -+$KERNELDIR -+When building the SGX DDK kernel module, the build needs access -+to the headers of the Linux kernel -+$ export KERNELDIR=/path/to/kernel -+ -+$PATH -+If a cross compiler is being used make sure the PATH environment variable -+includes the path to the toolchain -+$ export PATH=$PATH:/path/to/toolchain -+ -+$CROSS_COMPILE -+Since the SGX DDK Build scripts are geared toward a cross-compilation -+workflow, the CROSS_COMPILE environment variable needs to be set -+$ export CROSS_COMPILE=toolchain-prefix- -+ -+ -+Build and Install Instructions -+------------------------------------------- -+ -+The SGX DDK configures different target builds within directories under -+eurasiacon/build/linux/. -+ -+The supported build targets are: -+ -+ all Makes everything -+ clean Removes all intermediate files created by a build. -+ clobber Removes all binaries for all builds as well. -+ install Runs the install script generated by the build. -+ -+The following variables may be set on the command line to influence a build. -+ -+ BUILD The type of build being performed. -+ Alternatives are release, timing or debug. -+ CFLAGS Build dependent optimisations and debug information flags. -+ SILENT Determines whether text of commands is produced during build. -+ -+To build for, change to the appropriate target directory, e.g.: -+$ cd eurasiacon/build/linux/platform/kbuild -+ -+Issue the make command: -+$ make BUILD=debug all -+ -+The DDK software must be installed by the root user. Become the root user: -+$ su -+ -+Install the DDK software: -+$ make install -+ -+Become an ordinary user again: -+$ exit -diff --git a/drivers/staging/ti-es8-sgx/Kbuild b/drivers/staging/ti-es8-sgx/Kbuild -new file mode 100644 -index 0000000..3098a8d ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/Kbuild -@@ -0,0 +1,127 @@ -+obj-m := pvrsrvkm.o -+ -+FILES := \ -+services4/srvkm/common/queue.c \ -+services4/srvkm/common/hash.c \ -+services4/srvkm/common/perproc.c \ -+services4/srvkm/common/mem.c \ -+services4/srvkm/common/power.c \ -+services4/srvkm/common/deviceclass.c \ -+services4/srvkm/common/metrics.c \ -+services4/srvkm/common/resman.c \ -+services4/srvkm/common/buffer_manager.c \ -+services4/srvkm/common/pvrsrv.c \ -+services4/srvkm/common/handle.c \ -+services4/srvkm/common/lists.c \ -+services4/srvkm/common/ra.c \ -+services4/srvkm/common/devicemem.c \ -+services4/srvkm/env/linux/pvr_debug.c \ -+services4/srvkm/env/linux/mm.c \ -+services4/srvkm/env/linux/mutex.c \ -+services4/srvkm/env/linux/mmap.c \ -+services4/srvkm/env/linux/module.c \ -+services4/srvkm/env/linux/proc.c \ -+services4/srvkm/env/linux/event.c \ -+services4/srvkm/env/linux/osfunc.c \ -+services4/srvkm/env/linux/pvr_bridge_k.c \ -+services4/srvkm/env/linux/pdump.c \ -+services4/srvkm/env/linux/mutils.c \ -+services4/srvkm/env/linux/osperproc.c \ -+services4/srvkm/devices/sgx/sgxtransfer.c \ -+services4/srvkm/devices/sgx/sgxinit.c \ -+services4/srvkm/devices/sgx/sgxutils.c \ -+services4/srvkm/devices/sgx/pb.c \ -+services4/srvkm/devices/sgx/sgxkick.c \ -+services4/srvkm/devices/sgx/mmu.c \ -+services4/srvkm/devices/sgx/sgxreset.c \ -+services4/srvkm/devices/sgx/sgxpower.c \ -+services4/srvkm/bridged/bridged_pvr_bridge.c \ -+services4/srvkm/bridged/bridged_support.c \ -+services4/srvkm/bridged/sgx/bridged_sgx_bridge.c \ -+services4/system/$(TI_PLATFORM)/sysutils.c \ -+services4/system/$(TI_PLATFORM)/sysconfig.c \ -+ -+ifneq ($(FBDEV),no) -+EXTRA_CFLAGS += -DFBDEV_PRESENT -+endif -+ -+ifeq ($(TI_PLATFORM),ti43xx) -+ifneq ($(PM_RUNTIME),no) -+EXTRA_CFLAGS += -DPM_RUNTIME_SUPPORT -+endif -+endif -+ -+ifeq ($(TI_PLATFORM),ti335x) -+ifneq ($(SUPPORT_XORG),1) -+ifneq ($(PM_RUNTIME),no) -+EXTRA_CFLAGS += -DPM_RUNTIME_SUPPORT -+endif -+endif -+endif -+ -+ifeq ($(TI_PLATFORM),ti43xx) -+DRIFILES = services4/srvkm/env/linux/pvr_drm.c services4/3rdparty/dc_ti43xx_linux/omaplfb_linux.c services4/3rdparty/dc_ti43xx_linux/omaplfb_displayclass.c -+else -+ifeq ($(TI_PLATFORM),ti335x) -+DRIFILES = services4/srvkm/env/linux/pvr_drm.c services4/3rdparty/dc_ti335x_linux/omaplfb_linux.c services4/3rdparty/dc_ti335x_linux/omaplfb_displayclass.c -+else -+ifeq ($(TI_PLATFORM),ti81xx) -+DRIFILES = services4/srvkm/env/linux/pvr_drm.c services4/3rdparty/dc_ti81xx_linux/omaplfb_linux.c services4/3rdparty/dc_ti81xx_linux/omaplfb_displayclass.c -+else -+DRIFILES = services4/srvkm/env/linux/pvr_drm.c services4/3rdparty/dc_omapfb3_linux/omaplfb_linux.c services4/3rdparty/dc_omapfb3_linux/omaplfb_displayclass.c -+endif -+endif -+endif -+ -+EXTRA_CFLAGS += -I$(src)/include4 -+EXTRA_CFLAGS += -I$(src)/services4/include -+EXTRA_CFLAGS += -I$(src)/services4/srvkm/include -+EXTRA_CFLAGS += -I$(src)/services4/srvkm/hwdefs -+EXTRA_CFLAGS += -I$(src)/services4/srvkm/bridged -+EXTRA_CFLAGS += -I$(src)/services4/srvkm/devices/sgx -+EXTRA_CFLAGS += -I$(src)/services4/srvkm/env/linux -+EXTRA_CFLAGS += -I$(src)/services4/system/include -+EXTRA_CFLAGS += -I$(src)/services4/system/$(TI_PLATFORM) -+EXTRA_CFLAGS += -I$(src)/services4/srvkm/bridged/sgx -+EXTRA_CFLAGS += -I$(KERNELDIR)/arch/arm/mach-omap2 -+ -+ifeq ($(SUPPORT_XORG),1) -+EXTRA_CFLAGS += -I$(KERNELDIR)/include/drm -+EXTRA_CFLAGS += -I$(src)/services4/3rdparty/linux_drm -+EXTRA_CFLAGS += -I$(src)/services4/include/env/linux -+EXTRA_CFLAGS += -I$(KERNELDIR)/drivers/video/omap2 -+EXTRA_CFLAGS += -I$(KERNELDIR)/arch/arm/plat-omap/include -+ifeq ($(TI_PLATFORM),omap4) -+EXTRA_CFLAGS += -DCONFIG_SLOW_WORK -+endif -+endif -+ -+EXTRA_CFLAGS += $(ALL_CFLAGS) -+ -+pvrsrvkm-y := $(FILES:.c=.o) -+ -+ifeq ($(SUPPORT_XORG),1) -+pvrsrvkm-y += $(DRIFILES:.c=.o) -+endif -+ -+ifneq ($(SUPPORT_XORG),1) -+ifeq ($(TI_PLATFORM),ti43xx) -+obj-y := services4/3rdparty/dc_ti43xx_linux/ -+else -+ifeq ($(TI_PLATFORM),ti335x) -+obj-y := services4/3rdparty/dc_ti335x_linux/ -+else -+ifeq ($(TI_PLATFORM),ti81xx) -+obj-y := services4/3rdparty/dc_ti81xx_linux/ -+else -+obj-y := services4/3rdparty/dc_omapfb3_linux/ -+endif -+endif -+endif -+endif -+obj-y += services4/3rdparty/bufferclass_ti/ -+#obj-y += services4/3rdparty/bufferclass_example/ -+ -+ifeq ($(SUPPORT_XORG),1) -+obj-y += services4/3rdparty/linux_drm/ -+endif -diff --git a/drivers/staging/ti-es8-sgx/MIT-COPYING b/drivers/staging/ti-es8-sgx/MIT-COPYING -new file mode 100644 -index 0000000..0cbd14e ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/MIT-COPYING -@@ -0,0 +1,41 @@ -+ -+This software is Copyright (C) Imagination Technologies Ltd. -+ -+You may use, distribute and copy this software under the terms of the MIT -+license displayed below. -+ -+----------------------------------------------------------------------------- -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, this Software may be used under the terms of the GNU General -+Public License Version 2 ("GPL") in which case the provisions of GPL are -+applicable instead of those above. -+ -+If you wish to allow use of your version of this Software only under the terms -+of GPL, and not to allow others to use your version of this file under the -+terms of the MIT license, indicate your decision by deleting from each file -+the provisions above and replace them with the notice and other provisions -+required by GPL as set out in the file called "GPL-COPYING" included in this -+distribution. If you do not delete the provisions above, a recipient may use -+your version of this file under the terms of either the MIT license or GPL. -+ -+----------------------------------------------------------------------------- -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+ -+----------------------------------------------------------------------------- -diff --git a/drivers/staging/ti-es8-sgx/Makefile b/drivers/staging/ti-es8-sgx/Makefile -new file mode 100644 -index 0000000..ff0391f ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/Makefile -@@ -0,0 +1,486 @@ -+export KERNELDIR = /opt/oe/stuff/build/tmp/work/beagleboard-angstrom-linux-gnueabi/linux-omap-2.6.29-r44/git/ -+ -+export KERNEL_PATH=$(KERNELDIR) -+export KERNEL_SRC=$(KERNELDIR) -+export KDIR=$(KERNELDIR) -+ -+export BUILD = release -+ -+export KBUILD_EXTRA_SYMBOLS = `pwd`/services4/srvkm/env/linux/kbuild/Module.symvers -+ -+OMAP_KERNEL_VER := $(shell grep "^VERSION = " \ -+ $(KERNELDIR)/Makefile | cut -f3 -d' ') -+OMAP_KERNEL_REL := $(shell grep "^PATCHLEVEL = " \ -+ $(KERNELDIR)/Makefile | cut -f3 -d' ') -+OMAP_KERNEL_SUBREL := $(shell grep "^SUBLEVEL = " \ -+ $(KERNELDIR)/Makefile | cut -f3 -d' ') -+ -+OMAP_KERNEL_AT_LEAST_2_6_29 := $(shell test $(OMAP_KERNEL_VER) -ge 2 -a \ -+ $(OMAP_KERNEL_REL) -ge 6 -a \ -+ $(OMAP_KERNEL_SUBREL) -ge 29 && echo 1 || echo 0) -+ -+ifeq ($(OMAP_KERNEL_AT_LEAST_2_6_29),1) -+SUPPORT_OMAP3430_OMAPFB3 = 1 -+SUPPORT_LINUX_USING_WORKQUEUES = 1 -+SYS_CFLAGS += -DPVR_HAS_BROKEN_OMAPFB_H -+endif -+OPTIM = -Os -+ -+ifeq ($(TI_PLATFORM),omap4) -+SGXCORE = 540 -+else -+SGXCORE = 530 -+endif -+ -+ifeq ($(TI_PLATFORM),ti43xx) -+CORE = -DSGX530 -DSUPPORT_SGX530 -DSGX_CORE_REV=125 -+else -+ifeq ($(TI_PLATFORM),ti335x) -+CORE = -DSGX530 -DSUPPORT_SGX530 -DSGX_CORE_REV=125 -+else -+ifeq ($(TI_PLATFORM),omap4) -+CORE = -DSGX540 -DSUPPORT_SGX540 -DSGX_CORE_REV=120 -+else -+ifeq ($(TI_PLATFORM),ti81xx) -+CORE = -DPLAT_TI81xx -DSGX530 -DSUPPORT_SGX530 -DSGX_CORE_REV=125 -+else -+ifeq ($(TI_PLATFORM),omap3630) -+CORE = -DSGX530 -DSUPPORT_SGX530 -DSGX_CORE_REV=125 -+else -+ifeq ($(TI_PLATFORM),omap3) -+ifeq ($(OMAPES),3.x) -+CORE = -DSGX530 -DSUPPORT_SGX530 -DSGX_CORE_REV=121 -+else -+CORE = -DSGX530 -DSUPPORT_SGX530 -DSGX_CORE_REV=103 -+endif -+endif -+endif -+endif -+endif -+endif -+endif -+ -+SUPPORT_SGX = 1 -+SUPPORT_HW_RECOVERY = 1 -+SUPPORT_SGX_HWPERF = 1 -+SYS_USING_INTERRUPTS = 1 -+SUPPORT_TI_PM = 0 -+ -+PVR2D_ALT_2DHW = 1 -+ -+LDM_PLATFORM ?= 1 -+SUPPORT_XORG ?=0 -+SUPPORT_DRI_DRM_NOT_PCI ?= 0 -+ -+ifeq ($(SUPPORT_XORG),1) -+SUPPORT_DRI_DRM = 1 -+SUPPORT_DRI_DRM_NOT_PCI = 1 -+endif -+ -+ -+ifeq ($(SUPPORT_DRI_DRM_NOT_PCI),1) -+KBUILD_EXTRA_SYMBOLS = `pwd`/services4/3rdparty/linux_drm/kbuild/Module.symvers -+endif -+ -+SUPPORT_DRI_DRM ?= $(SUPPORT_XORG) -+SUPPORT_DRI_DRM_EXT ?= 0 -+SUPPORT_DRI_DRM_NO_DROPMASTER ?= 0 -+#SUPPORT_SECURE_DRM_AUTH_EXPORT ?= $(SUPPORT_XORG) -+ -+SUPPORT_DRI_DRM_NO_LIBDRM ?= 0 -+ifneq ($(SUPPORT_XORG),1) -+ifeq ($(SUPPORT_DRI_DRM),1) -+SUPPORT_DRI_DRM_NO_LIBDRM = 1 -+endif -+endif -+ -+ -+ -+# Only enable active power management if passive power management is -+# enabled, as indicated by LDM_PLATFORM being set to 1. On OMAP, -+# the system can suspend in the case where active power management is -+# enabled in the SGX driver, but passive power management isn't. As -+# passive power management isn't enabled, the driver won't see the -+# system suspend/resume events, and so won't take appropriate action. -+ifeq ($(LDM_PLATFORM),1) -+ifeq ($(TI_PLATFORM),ti335x) -+SUPPORT_ACTIVE_POWER_MANAGEMENT ?= 0 -+else -+ifeq ($(TI_PLATFORM),ti43xx) -+SUPPORT_ACTIVE_POWER_MANAGEMENT ?= 0 -+else -+ifeq ($(TI_PLATFORM),ti81xx) -+SUPPORT_ACTIVE_POWER_MANAGEMENT ?= 0 -+else -+SUPPORT_ACTIVE_POWER_MANAGEMENT = 1 -+endif -+endif -+endif -+else -+SUPPORT_ACTIVE_POWER_MANAGEMENT = 0 -+endif -+ -+ -+#if 0 -+ifeq ($(LDM_PLATFORM),1) -+DISPLAY_CONTROLLER = omaplfb -+OMAP_NON_FLIP_DISPLAY = 0 -+else -+DISPLAY_CONTROLLER = pvrlfb -+DISPLAY_CONTROLLER_DIR = 3rdparty/linux_framebuffer -+OMAP_NON_FLIP_DISPLAY = 1 -+endif -+#endif -+ -+PVR_NO_FULL_CACHE_OPS := 1 -+SGX_DYNAMIC_TIMING_INFO := 1 -+SYS_CUSTOM_POWERLOCK_WRAP := 1 -+PVR_LDM_PLATFORM_PRE_REGISTERED := 0 -+PVR_SECURE_HANDLES :=1 -+DEBUGLINK :=1 -+PVRSRV_MODNAME ?= pvrsrvkm -+ -+SYS_CFLAGS += -DPVRSRV_MODNAME="\"$(PVRSRV_MODNAME)"\" -+ -+#ARCH_CFLAGS += -ftree-vectorize -mfpu=neon -mfloat-abi=hard -+ARCH_CFLAGS += -Wno-sign-conversion -+ -+ -+export PVR_BUILD_DIR := $(shell pwd) -+ -+DATE := $(shell date "+%a %B %d %Z %Y" ) -+ -+CBUILD = -DPVR_BUILD_DIR="\"$(PVR_BUILD_DIR)\"" \ -+ -DPVR_BUILD_DATE="\"$(DATE)\"" \ -+ -DPVR_BUILD_TYPE="\"$(BUILD)\"" -+ -+# Don't support HW recovery on debug builds -+CBUILD.debug = -DDEBUG -+CBUILD.timing = -DTIMING -+CBUILD.release = -DRELEASE -+CFLAGS.debug = -g -O0 -DDLL_METRIC=1 -+CFLAGS.timing = $(OPTIM) -g -DDLL_METRIC=1 -DTIMING -+CFLAGS.release = $(OPTIM) -g -+CFLAGS = $(CFLAGS.$(BUILD)) -+ -+ifeq ($(EXTRA_EXTRA_WARNINGS),1) -+EXTRA_WARNINGS=1 -+endif -+ifeq ($(EXTRA_WARNINGS),1) -+CCFLAGS_KERNEL += -+ifeq ($(EXTRA_EXTRA_WARNINGS),1) -+CCFLAGS_KERNEL += -Wwrite-strings -+endif -+endif -+ -+CCFLAGS_KERNEL += -Wall -Wdeclaration-after-statement -Wpointer-arith -+CCFLAGS_KERNEL += -Wmissing-format-attribute -Wno-format-zero-length -+CCFLAGS_KERNEL += -Wmissing-prototypes -Wstrict-prototypes -+ -+ -+CCFLAGS := $(CCFLAGS_KERNEL) -Wunused-parameter -+ -+ -+CCFLAGS_HOST := $(CCFLAGS) -+CCFLAGS += -W -Wno-missing-field-initializers -+CCFLAGS_KERNEL += -Wno-unused-parameter -Wno-sign-compare -+ -+ifneq ($(SUPPORT_DRI_DRM_EXT),1) -+ifeq ($(EXTRA_WARNINGS),1) -+SYS_CFLAGS += -Wno-error -+else -+CCFLAGS_KERNEL += -Werror -+endif -+endif -+ -+CPPFLAGS = -W -Wall -Wmissing-format-attribute -Wpointer-arith -+CPPFLAGS += -Wno-missing-field-initializers -+ -+ -+ -+ -+ifeq ("$(BUILD)", "debug") -+DEBUG_LINUX_MEMORY_ALLOCATIONS ?= 1 -+DEBUG_LINUX_MEM_AREAS ?= 1 -+DEBUG_LINUX_MMAP_AREAS ?= 1 -+DEBUG_LINUX_XML_PROC_FILES ?= 0 -+DEBUG_LINUX_SLAB_ALLOCATIONS ?= 0 -+DEBUG_BRIDGE_KM ?= 1 -+DEBUG_TRACE_BRIDGE_KM ?= 0 -+DEBUG_BRIDGE_KM_DISPATCH_TABLE ?= 0 -+PVRSRV_LOG_MEMORY_ALLOCS ?= 0 -+PVRSRV_DEBUG_OS_MEMORY ?= 0 -+endif -+ -+ifneq ($(SUPPORT_XORG),1) -+SUPPORT_XWS ?= 1 -+XWS_SERVER_ONLY ?= 0 -+else -+SUPPORT_XWS = 0 -+XWS_SERVER_ONLY = 0 -+SUPPORT_EWS = 0 -+endif -+ -+SUPPORT_DRI_DRM ?= $(SUPPORT_XORG) -+SUPPORT_SECURE_DRM_AUTH_EXPORT ?= $(SUPPORT_XORG) -+SUPPORT_DRI_DRM_EXT ?= 0 -+SUPPORT_LIBDRM_LITE ?= 0 -+ -+ifeq ($(SUPPORT_EWS),1) -+SUPPORT_SECURE_FD_EXPORT ?= 1 -+else -+SUPPORT_SECURE_FD_EXPORT ?= 0 -+endif -+ -+SUPPORT_DRI_DRM_NO_LIBDRM ?= 0 -+ -+TRANSFER_QUEUE ?= 1 -+SUPPORT_SGX_EVENT_OBJECT ?= 1 -+SUPPORT_SECURE_HANDLES = 1 -+SUPPORT_SRVINIT = 1 -+SUPPORT_PERCONTEXT_PB = 1 -+DISABLE_SGX_PB_GROW_SHRINK ?= 1 -+SUPPORT_LINUX_X86_PAT ?=1 -+SUPPORT_LINUX_X86_WRITECOMBINE ?=1 -+SUPPORT_SGX_LOW_LATENCY_SCHEDULING ?=1 -+SUPPORT_PVRSRV_GET_DC_SYSTEM_BUFFER ?=1 -+ -+ifeq ($(SUPPORT_XORG),1) -+SUPPORT_PDUMP_MULTI_PROCESS = 1 -+endif -+ -+ -+SUPPORT_OMAP3430_SGXFCLK_96M ?= 0 -+SUPPORT_OMAP3430_OMAPFB3 ?= 0 -+ -+SUPPORT_MEMINFO_IDS ?= 0 -+ -+SUPPORT_PVR_PDP_LINUX_FB ?= $(SUPPORT_XWS) -+ -+SUPPORT_LINUX_USING_WORKQUEUES ?= 1 -+ifeq ($(SUPPORT_OMAP3430_OMAPFB3),1) -+SUPPORT_LINUX_USING_WORKQUEUES = 1 -+endif -+ -+SUPPORT_SGX_NEW_STATUS_VALS ?= 1 -+ -+PVR_LINUX_USING_WORKQUEUES := 1 -+PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE := 1 -+PVR_LINUX_TIMERS_USING_WORKQUEUES := 1 -+SYS_CUSTOM_POWERLOCK_WRAP := 1 -+ -+ -+DC_NOHW_WIDTH ?= 640 -+DC_NOHW_HEIGHT ?= 480 -+ -+DISPLAY_CONTROLLER ?= -+ -+SYS_CFLAGS += -DSERVICES4 -D_XOPEN_SOURCE=600 -D_POSIX_C_SOURCE=199309 -DPVR2D_VALIDATE_INPUT_PARAMS -+ -+#SYS_CFLAGS += -DSERVICES4 -D_XOPEN_SOURCE=600 -DPVR2D_VALIDATE_INPUT_PARAMS -+ -+# Thread support -+USE_PTHREADS ?= 1 -+USE_GCC__thread_KEYWORD ?= 0 -+OPTIMISE_NON_NPTL_SINGLE_THREAD_TLS_LOOKUP ?= 0 -+DISABLE_THREADS ?= 0 -+ -+#PVRSRV_USSE_EDM_STATUS_DEBUG := 1 -+#PVRSRV_DUMP_MK_TRACE := 1 -+ -+# Automatically define C compiler macros for features possible (or not) in use. -+ -+SYS_CFLAGS.$(SUPPORT_SRVINIT) += -DSUPPORT_SRVINIT -+SYS_CFLAGS.$(SUPPORT_VGX) += -DSUPPORT_VGX -+SYS_CFLAGS.$(SUPPORT_SGX) += -DSUPPORT_SGX -+SYS_CFLAGS.$(SUPPORT_XWS) += -DSUPPORT_XWS -+SYS_CFLAGS.$(PDUMP) += -DPDUMP -+SYS_CFLAGS.$(VGX_PDUMP_FROM_FIRMWARE) += -DVGX_PDUMP_FROM_FIRMWARE -+SYS_CFLAGS.$(OVG_ALWAYS_CONVERT_DATA) += -DOVG_ALWAYS_CONVERT_DATA -+ -+SYS_CFLAGS.$(SUPPORT_POWER_MANAGEMENT) += -DSUPPORT_POWER_MANAGEMENT -+SYS_CFLAGS.$(SUPPORT_BUFFER_CLASS) += -DSUPPORT_BUFFER_CLASS -+ -+SYS_CFLAGS.$(SUPPORT_PERCONTEXT_PB) += -DSUPPORT_PERCONTEXT_PB -+SYS_CFLAGS.$(SUPPORT_DYNAMIC_PBRESIZE) += -DSUPPORT_DYNAMIC_PBRESIZE -+SYS_CFLAGS.$(DISABLE_SGX_PB_GROW_SHRINK) += -DDISABLE_SGX_PB_GROW_SHRINK -+SYS_CFLAGS.$(SUPPORT_PVRSRV_GET_DC_SYSTEM_BUFFER) += -DSUPPORT_PVRSRV_GET_DC_SYSTEM_BUFFER -+ -+SYS_CFLAGS.$(USE_FBDEV) += -DUSE_FBDEV -+SYS_CFLAGS.$(USE_FBDEV) += -DFBDEV_NAME="\"$(FBDEV_NAME)\"" -+SYS_CFLAGS.$(SUPPORT_DYNAMIC_3DCLOCKGATING) += -DSUPPORT_DYNAMIC_3DCLOCKGATING -+SYS_CFLAGS.$(REENTRANCY_PROTECTION) += -DREENTRANCY_PROTECTION -+SYS_CFLAGS.$(SCHEDULER_CONTROL_SUPPORT) += -DSCHEDULER_CONTROL_SUPPORT -+SYS_CFLAGS.$(USE_IMG_POWER_DOMAIN_FUNCTION) += -DUSE_IMG_POWER_DOMAIN_FUNCTION -+ -+SYS_CFLAGS.$(USE_DMALLOC) += -DDMALLOC -+ -+SYS_CFLAGS.$(DEBUG_LINUX_MEMORY_ALLOCATIONS) += -DDEBUG_LINUX_MEMORY_ALLOCATIONS -+SYS_CFLAGS.$(DEBUG_LINUX_MEM_AREAS) += -DDEBUG_LINUX_MEM_AREAS -+SYS_CFLAGS.$(DEBUG_LINUX_MMAP_AREAS) += -DDEBUG_LINUX_MMAP_AREAS -+SYS_CFLAGS.$(DEBUG_LINUX_XML_PROC_FILES) += -DDEBUG_LINUX_XML_PROC_FILES -+SYS_CFLAGS.$(DEBUG_LINUX_SLAB_ALLOCATIONS) += -DDEBUG_LINUX_SLAB_ALLOCATIONS -+SYS_CFLAGS.$(DEBUG_BRIDGE_KM) += -DDEBUG_BRIDGE_KM -+SYS_CFLAGS.$(DEBUG_TRACE_BRIDGE_KM) += -DDEBUG_TRACE_BRIDGE_KM -+SYS_CFLAGS.$(DEBUG_BRIDGE_KM_DISPATCH_TABLE) += -DDEBUG_BRIDGE_KM_DISPATCH_TABLE -+ -+SYS_CFLAGS.$(PVRSRV_LOG_MEMORY_ALLOCS) += -DPVRSRV_LOG_MEMORY_ALLOCS -+SYS_CFLAGS.$(PVRSRV_DEBUG_OS_MEMORY) += -DPVRSRV_DEBUG_OS_MEMORY -+SYS_CFLAGS.$(DEBUG_MESA_OGL_TRACE) += -DDEBUG_MESA_OGL_TRACE -+ -+ -+SYS_CFLAGS.$(SUPPORT_LINUX_X86_WRITECOMBINE) += -DSUPPORT_LINUX_X86_WRITECOMBINE -+ -+SYS_CFLAGS.$(SGX_PDS_EVENTS_DISABLED) += -DSGX_PDS_EVENTS_DISABLED -+SYS_CFLAGS.$(USE_SUPPORT_NO_TA3D_OVERLAP) += -DUSE_SUPPORT_NO_TA3D_OVERLAP -+SYS_CFLAGS.$(SUPPORT_SGX_TILING) += -DSUPPORT_SGX_TILING -+SYS_CFLAGS.$(TRANSFER_QUEUE) += -DTRANSFER_QUEUE -+ -+SYS_CFLAGS.$(SUPPORT_SGX_MMU_DUMMY_PAGE) += -DSUPPORT_SGX_MMU_DUMMY_PAGE -+SYS_CFLAGS.$(PVRSRV_DUMP_MK_TRACE) += -DPVRSRV_DUMP_MK_TRACE -+SYS_CFLAGS.$(PVRSRV_DUMP_KERNEL_CCB) += -DPVRSRV_DUMP_KERNEL_CCB -+SYS_CFLAGS.$(EDM_USSE_HWDEBUG) += -DEDM_USSE_HWDEBUG -+ -+ -+ -+SYS_CFLAGS.$(PVRSRV_USSE_EDM_STATUS_DEBUG) += -DPVRSRV_USSE_EDM_STATUS_DEBUG -+SYS_CFLAGS.$(USE_SUPPORT_STATUSVALS_DEBUG) += -DUSE_SUPPORT_STATUSVALS_DEBUG -+SYS_CFLAGS.$(SGX_FAST_DPM_INIT) += -DSGX_FAST_DPM_INIT -+SYS_CFLAGS.$(SGX_DISABLE_UKERNEL_SECONDARY_STATE) += -DSGX_DISABLE_UKERNEL_SECONDARY_STATE -+SYS_CFLAGS.$(DBGBREAK_ON_SPM) += -DDBGBREAK_ON_SPM -+SYS_CFLAGS.$(PVR_DBG_BREAK_ASSERT_FAIL) += -DPVR_DBG_BREAK_ASSERT_FAIL -+ -+SYS_CFLAGS.$(PVRSRV_RESET_ON_HWTIMEOUT) += -DPVRSRV_RESET_ON_HWTIMEOUT -+SYS_CFLAGS.$(PVRSRV_CLIENT_RESET_ON_HWTIMEOUT) += -DPVRSRV_CLIENT_RESET_ON_HWTIMEOUT -+SYS_CFLAGS.$(NO_HARDWARE) += -DNO_HARDWARE -+ -+SYS_CFLAGS.$(SUPPORT_DRI_DRM) += -DSUPPORT_DRI_DRM -+SYS_CFLAGS.$(SUPPORT_DRI_DRM_EXT) += -DSUPPORT_DRI_DRM_EXT -+SYS_CFLAGS.$(SUPPORT_DRI_DRM_NOT_PCI) += -DPVR_DRI_DRM_NOT_PCI -+SYS_CFLAGS.$(SUPPORT_DRI_DRM_NO_DROPMASTER) += -DSUPPORT_DRI_DRM_NO_DROPMASTER -+SYS_CFLAGS.$(SUPPORT_DRI_DRM_NO_LIBDRM) += -DSUPPORT_DRI_DRM_NO_LIBDRM -+SYS_CFLAGS.$(DRM_PVR_RESERVED_INTEL_ORDER) += -DDRM_PVR_RESERVED_INTEL_ORDER -+SYS_CFLAGS.$(DRM_PVR_USE_INTEL_FB) += -DDRM_PVR_USE_INTEL_FB -+ -+ -+ -+ -+SYS_CFLAGS.$(SUPPORT_LIBDRM_LITE) += -DSUPPORT_LIBDRM_LITE -+ -+ifneq ("$(NO_HARDWARE)", "1") -+SYS_CFLAGS.$(SYS_USING_INTERRUPTS) += -DSYS_USING_INTERRUPTS -+SYS_CFLAGS.$(SUPPORT_HW_RECOVERY) += -DSUPPORT_HW_RECOVERY -+SYS_CFLAGS.$(SUPPORT_ACTIVE_POWER_MANAGEMENT) += -DSUPPORT_ACTIVE_POWER_MANAGEMENT -+endif -+ -+ifeq ("$(PDUMP)", "1") -+SUPPORT_DBGDRV_EVENT_OBJECTS ?=1 -+SYS_CFLAGS.$(SUPPORT_DBGDRV_EVENT_OBJECTS) += -DSUPPORT_DBGDRV_EVENT_OBJECTS -+SYS_CFLAGS.$(PDUMP_DEBUG_OUTFILES) += -DPDUMP_DEBUG_OUTFILES -+endif -+ -+ -+ -+SYS_CFLAGS.$(SYS_USING_INTERRUPTS) += -DSYS_USING_INTERRUPTS -+SYS_CFLAGS.$(SUPPORT_HW_RECOVERY) += -DSUPPORT_HW_RECOVERY -+SYS_CFLAGS.$(SUPPORT_ACTIVE_POWER_MANAGEMENT) += -DSUPPORT_ACTIVE_POWER_MANAGEMENT -+ -+SYS_CFLAGS.$(SUPPORT_SECURE_HANDLES) += -DPVR_SECURE_HANDLES -+SYS_CFLAGS.$(SUPPORT_SECURE_FD_EXPORT) += -DPVR_SECURE_FD_EXPORT -+SYS_CFLAGS.$(SUPPORT_SECURE_DRM_AUTH_EXPORT) += -DPVR_SECURE_DRM_AUTH_EXPORT -+ -+SYS_CFLAGS.$(USE_PTHREADS) += -DUSE_PTHREADS -+SYS_CFLAGS.$(USE_GCC__thread_KEYWORD) += -DUSE_GCC__thread_KEYWORD -+SYS_CFLAGS.$(OPTIMISE_NON_NPTL_SINGLE_THREAD_TLS_LOOKUP) += -DOPTIMISE_NON_NPTL_SINGLE_THREAD_TLS_LOOKUP -+SYS_CFLAGS.$(DISABLE_THREADS) += -DDISABLE_THREADS -+SYS_CFLAGS.$(SUPPORT_SGX_EVENT_OBJECT) += -DSUPPORT_SGX_EVENT_OBJECT -+SYS_CFLAGS.$(LDM_PLATFORM) += -DLDM_PLATFORM -+SYS_CFLAGS.$(LDM_PCI) += -DLDM_PCI -+SYS_CFLAGS.$(PVR_MANUAL_POWER_CONTROL) += -DPVR_MANUAL_POWER_CONTROL -+ -+SYS_CFLAGS.$(PVR2D_ALT_2DHW) += -DPVR2D_ALT_2DHW -+ -+SYS_CFLAGS.$(SUPPORT_SGX_HWPERF) += -DSUPPORT_SGX_HWPERF -+ -+SYS_CFLAGS.$(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) += -DSUPPORT_SGX_LOW_LATENCY_SCHEDULING -+ -+SYS_CFLAGS.$(SUPPORT_SLC) += -DSGX_FEATURE_SYSTEM_CACHE -+SYS_CFLAGS.$(BYPASS_SLC) += -DSGX_BYPASS_SYSTEM_CACHE -+SYS_CFLAGS.$(BYPASS_DCU) += -DSGX_BYPASS_DCU -+SYS_CFLAGS.$(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) += -DSUPPORT_SGX_LOW_LATENCY_SCHEDULING -+SYS_CFLAGS.$(SGX_SUPPORT_VDM_TIMER_BASED_SWITCHING) += -DSGX_SUPPORT_VDM_TIMER_BASED_SWITCHING -+SYS_CFLAGS.$(SGX_SUPPORT_ISP_TIMER_BASED_SWITCHING) += -DSGX_SUPPORT_ISP_TIMER_BASED_SWITCHING -+ -+ -+ -+SYS_CFLAGS.$(SUPPORT_LINUX_X86_PAT) += -DSUPPORT_LINUX_X86_PAT -+ -+ -+SYS_CFLAGS.$(SUPPORT_TI_PM) += -DSUPPORT_TI_PM -+ -+SYS_CFLAGS.$(SUPPORT_OMAP3430_SGXFCLK_96M) += -DSUPPORT_OMAP3430_SGXFCLK_96M -+SYS_CFLAGS.$(SUPPORT_OMAP3430_OMAPFB3) += -DSUPPORT_OMAP3430_OMAPFB3 -+ -+SYS_CFLAGS.$(SUPPORT_CACHEFLUSH_ON_ALLOC) += -DSUPPORT_CACHEFLUSH_ON_ALLOC -+SYS_CFLAGS.$(SUPPORT_MEMINFO_IDS) += -DSUPPORT_MEMINFO_IDS -+ -+SYS_CFLAGS.$(SUPPORT_SGX_EDM_MEMORY_DEBUG) += -DSUPPORT_SGX_EDM_MEMORY_DEBUG -+ -+SYS_CFLAGS.$(SUPPORT_GRAPHICS_HAL) += -DSUPPORT_GRAPHICS_HAL -+SYS_CFLAGS.$(SUPPORT_GRAPHICS_HAL) += -DGRALLOC_VARIANT="\"$(GRALLOC_VARIANT)\"" -+ -+SYS_CFLAGS.$(SUPPORT_EGL_IMAGE_SYNC_DEPENDENCY) += -DSUPPORT_EGL_IMAGE_SYNC_DEPENDENCY -+SYS_CFLAGS.$(SUPPORT_PVR_PDP_LINUX_FB) += -DPVR_PDP_LINUX_FB -+ -+#SYS_CFLAGS.$(SUPPORT_LINUX_USING_WORKQUEUES) += -DPVR_LINUX_USING_WORKQUEUES \ -+ -DPVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE -+SYS_CFLAGS.$(SUPPORT_LINUX_USING_WORKQUEUES) += -DPVR_LINUX_USING_WORKQUEUES \ -+ -DPVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE \ -+ -DPVR_LINUX_TIMERS_USING_WORKQUEUES \ -+ -DSYS_CUSTOM_POWERLOCK_WRAP \ -+ -DPVR_NO_FULL_CACHE_OPS \ -+ -DSGX_CLK_CORE_DIV5 -+ -+ -+SYS_CFLAGS.$(SUPPORT_SGX_NEW_STATUS_VALS) += -DSUPPORT_SGX_NEW_STATUS_VALS -+ -+ifneq ("$(DISPLAY_CONTROLLER)", "") -+SYS_CFLAGS += -DDISPLAY_CONTROLLER=$(DISPLAY_CONTROLLER) -+endif -+ -+ifeq ("$(PVR_SYSTEM)", "sgx_nohw") -+ifndef RTSIM -+SYS_CFLAGS += -DNO_HARDWARE -+endif -+SYS_CFLAGS += -DDC_NOHW_BUFFER_WIDTH=$(DC_NOHW_WIDTH) -DDC_NOHW_BUFFER_HEIGHT=$(DC_NOHW_HEIGHT) -+endif -+ -+ifeq ("$(PVR_SYSTEM)", "vgx_nohw") -+SYS_CFLAGS += -DNO_HARDWARE -DDC_NOHW_BUFFER_WIDTH=$(DC_NOHW_WIDTH) -DDC_NOHW_BUFFER_HEIGHT=$(DC_NOHW_HEIGHT) -+endif -+ -+SYS_CFLAGS += -DDEBUG_LOG_PATH_TRUNCATE=\"$(EURASIAROOT)\" -+ -+SYS_INCLUDES = -I$(EURASIAROOT)/include4 \ -+ -I$(EURASIAROOT)/eurasiacon/includeext \ -+ -I$(SYSBIN) \ -+ -isystem $(KERNELDIR)/include -+ -+ -+ -+export ALL_CFLAGS = -DLINUX \ -+ $(CBUILD) $(CBUILD.$(BUILD)) \ -+ $(SYS_CFLAGS) $(SYS_CFLAGS.1) \ -+ $(MODULE_CFLAGS) $(MODULE_CFLAGS.$(BUILD)) \ -+ $(CORE) -fno-strict-aliasing -Wno-pointer-arith \ -+ $(CFLAGS) $(ARCH_CFLAGS) -+ifdef SUPPORT_DRI_DRM_NO_TTM -+export SUPPORT_DRI_DRM_NO_TTM -+endif -+ -+all: -+ $(MAKE) -C $(KERNELDIR) M=`pwd` $* -+ -+clean: -+ @find . -name "*.o" -exec rm -r {} \; -+ @find . -name "*.ko" -exec rm -r {} \; -diff --git a/drivers/staging/ti-es8-sgx/README b/drivers/staging/ti-es8-sgx/README -new file mode 100644 -index 0000000..6a9f4a28 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/README -@@ -0,0 +1,49 @@ -+ -+SGX Embedded Systems DDK for Linux kernel. -+Copyright (C) Imagination Technologies Ltd. All rights reserved. -+====================================================================== -+ -+ -+About -+------------------------------------------- -+ -+This is the Imagination Technologies SGX DDK for the Linux kernel. -+ -+ -+License -+------------------------------------------- -+ -+You may use, distribute and copy this software under the terms of the MIT -+license. Details of this license can be found in the file "MIT-COPYING". -+ -+Alternatively, you may use, distribute and copy this software under the terms -+of the GNU General Public License version 2. The full GNU General Public -+License version 2 can be found in the file "GPL-COPYING". -+ -+ -+Build and Install Instructions -+------------------------------------------- -+ -+For details see the "INSTALL" file. -+ -+To build for, change to the appropriate target directory, e.g.: -+$ cd eurasiacon/build/linux/platform/kbuild -+ -+Issue the make command: -+$ make BUILD=debug all -+ -+The DDK software must be installed by the root user. Become the root user: -+$ su -+ -+Install the DDK software: -+# make install -+ -+Become an ordinary user again: -+$ exit -+ -+ -+Contact information: -+------------------------------------------- -+ -+Imagination Technologies Ltd. <gpl-support@imgtec.com> -+Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK -diff --git a/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/bits.mk b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/bits.mk -new file mode 100644 -index 0000000..e67f2cf ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/bits.mk -@@ -0,0 +1,114 @@ -+########################################################################### ### -+#@Title Useful special targets which don't build anything -+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+#@License Dual MIT/GPLv2 -+# -+# The contents of this file are subject to the MIT license as set out below. -+# -+# Permission is hereby granted, free of charge, to any person obtaining a copy -+# of this software and associated documentation files (the "Software"), to deal -+# in the Software without restriction, including without limitation the rights -+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+# copies of the Software, and to permit persons to whom the Software is -+# furnished to do so, subject to the following conditions: -+# -+# The above copyright notice and this permission notice shall be included in -+# all copies or substantial portions of the Software. -+# -+# Alternatively, the contents of this file may be used under the terms of -+# the GNU General Public License Version 2 ("GPL") in which case the provisions -+# of GPL are applicable instead of those above. -+# -+# If you wish to allow use of your version of this file only under the terms of -+# GPL, and not to allow others to use your version of this file under the terms -+# of the MIT license, indicate your decision by deleting the provisions above -+# and replace them with the notice and other provisions required by GPL as set -+# out in the file called "GPL-COPYING" included in this distribution. If you do -+# not delete the provisions above, a recipient may use your version of this file -+# under the terms of either the MIT license or GPL. -+# -+# This License is also included in this distribution in the file called -+# "MIT-COPYING". -+# -+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+### ########################################################################### -+ -+ifneq ($(filter dumpvar-%,$(MAKECMDGOALS)),) -+dumpvar-%: ; -+$(foreach _var_to_dump,$(patsubst dumpvar-%,%,$(filter dumpvar-%,$(MAKECMDGOALS))),$(info $(if $(filter undefined,$(origin $(_var_to_dump))),# $$($(_var_to_dump)) is not set,$(_var_to_dump) := $($(_var_to_dump))))) -+endif -+ -+ifneq ($(filter whereis-%,$(MAKECMDGOALS)),) -+whereis-%: ; -+$(foreach _module_to_find,$(patsubst whereis-%,%,$(filter whereis-%,$(MAKECMDGOALS))),$(info $(if $(INTERNAL_MAKEFILE_FOR_MODULE_$(_module_to_find)),$(INTERNAL_MAKEFILE_FOR_MODULE_$(_module_to_find)),# No module $(_module_to_find)))) -+endif -+ -+ifneq ($(filter whatis-%,$(MAKECMDGOALS)),) -+whatis-$(RELATIVE_OUT)/target/%: ; -+whatis-$(RELATIVE_OUT)/host/%: ; -+$(foreach _file_to_find,$(patsubst whatis-%,%,$(filter whatis-%,$(MAKECMDGOALS))),$(info $(strip $(foreach _m,$(ALL_MODULES),$(if $(filter $(_file_to_find),$(INTERNAL_TARGETS_FOR_$(_m))),$(_file_to_find) is in $(_m) which is defined in $(INTERNAL_MAKEFILE_FOR_MODULE_$(_m)),))))) -+endif -+ -+.PHONY: ls-modules -+ls-modules: -+ @: $(foreach _m,$(ALL_MODULES),$(info $($(_m)_type) $(_m) $(patsubst $(TOP)/%,%,$(INTERNAL_MAKEFILE_FOR_MODULE_$(_m))))) -+ -+ifeq ($(strip $(MAKECMDGOALS)),visualise) -+FORMAT ?= xlib -+GRAPHVIZ ?= neato -+visualise: $(OUT)/MAKE_RULES.dot -+ $(GRAPHVIZ) -T$(FORMAT) -o $(OUT)/MAKE_RULES.$(FORMAT) $< -+$(OUT)/MAKE_RULES.dot: $(OUT)/MAKE_RULES -+ perl $(MAKE_TOP)/tools/depgraph.pl -t $(TOP) -g $(firstword $(GRAPHVIZ)) $(OUT)/MAKE_RULES >$(OUT)/MAKE_RULES.dot -+$(OUT)/MAKE_RULES: $(ALL_MAKEFILES) -+ -$(MAKE) -C $(TOP) -f $(MAKE_TOP)/toplevel.mk TOP=$(TOP) OUT=$(OUT) ls-modules -qp >$(OUT)/MAKE_RULES 2>&1 -+else -+visualise: -+ @: $(error visualise specified along with other goals. This is not supported) -+endif -+ -+.PHONY: help -+help: -+ @echo 'Build targets' -+ @echo ' make, make build Build all components of the build' -+ @echo ' make components Build only the user-mode components' -+ @echo ' make kbuild Build only the kernel-mode components' -+ @echo ' make MODULE Build the module MODULE and all of its dependencies' -+ @echo ' make eurasiacon/binary2_.../target/libsomething.so' -+ @echo ' Build a particular file (including intermediates)' -+ @echo 'Variables' -+ @echo ' make V=1 ... Print the commands that are executed' -+ @echo ' make W=1 ... Enable extra compiler warnings' -+ @echo ' make D=opt ... Set build system debug option (D=help for a list)' -+ @echo ' make OUT=dir ... Place output+intermediates in specified directory' -+ @echo ' EXCLUDED_APIS=... List of APIs to remove from the build' -+ @echo ' make SOMEOPTION=1 ... Set configuration options (see config/core.mk)' -+ @echo ' Defaults are set by $(PVR_BUILD_DIR)/Makefile' -+ @echo 'Clean targets' -+ @echo ' make clean Remove only intermediates for the current build' -+ @echo ' make clobber As "make clean", but remove output files too' -+ @echo ' make clean-MODULE Clean (or clobber) only files for MODULE' -+ @echo '' -+ @echo 'Special targets' -+ @echo ' make whereis-MODULE Show the path to the Linux.mk defining MODULE' -+ @echo ' make whatis-FILE Show which module builds an output FILE' -+ @echo ' make ls-modules List all modules defined by makefiles' -+ -+ifneq ($(filter help,$(D)),) -+empty := -+space := $(empty) $(empty) -+$(info Debug options) -+$(info $(space)D=modules dump module info) -+$(info $(space)D=config dump all config options + type and origin) -+$(info $(space)D=freeze-config prevent config changes) -+$(info $(space)D=config-changes dump diffs when config changes) -+$(info $(space)D=nobuild stop before running the main build) -+$(info Options can be combined: make D=freeze-config,config-changes) -+$(error D=help given) -+endif -diff --git a/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/buildvars.mk b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/buildvars.mk -new file mode 100644 -index 0000000..352138e ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/buildvars.mk -@@ -0,0 +1,217 @@ -+########################################################################### ### -+#@Title Define global variables -+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+#@Description This file is read once at the start of the build, after reading -+# in config.mk. It should define the non-MODULE_* variables used -+# in commands, like ALL_CFLAGS -+#@License Dual MIT/GPLv2 -+# -+# The contents of this file are subject to the MIT license as set out below. -+# -+# Permission is hereby granted, free of charge, to any person obtaining a copy -+# of this software and associated documentation files (the "Software"), to deal -+# in the Software without restriction, including without limitation the rights -+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+# copies of the Software, and to permit persons to whom the Software is -+# furnished to do so, subject to the following conditions: -+# -+# The above copyright notice and this permission notice shall be included in -+# all copies or substantial portions of the Software. -+# -+# Alternatively, the contents of this file may be used under the terms of -+# the GNU General Public License Version 2 ("GPL") in which case the provisions -+# of GPL are applicable instead of those above. -+# -+# If you wish to allow use of your version of this file only under the terms of -+# GPL, and not to allow others to use your version of this file under the terms -+# of the MIT license, indicate your decision by deleting the provisions above -+# and replace them with the notice and other provisions required by GPL as set -+# out in the file called "GPL-COPYING" included in this distribution. If you do -+# not delete the provisions above, a recipient may use your version of this file -+# under the terms of either the MIT license or GPL. -+# -+# This License is also included in this distribution in the file called -+# "MIT-COPYING". -+# -+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+### ########################################################################### -+ -+ifeq ($(BUILD),debug) -+COMMON_USER_FLAGS := -O0 -+else -+OPTIM ?= -O2 -+COMMON_USER_FLAGS := $(OPTIM) -+endif -+ -+# FIXME: We should probably audit the driver for aliasing -+# -+COMMON_USER_FLAGS += -fno-strict-aliasing -+ -+# We always enable debugging. Either the release binaries are stripped -+# and the symbols put in the symbolpackage, or we're building debug. -+# -+COMMON_USER_FLAGS += -g -+ -+# These flags are used for kernel, User C and User C++ -+# -+COMMON_FLAGS = -W -Wall -+ -+# Some GCC warnings are C only, so we must mask them from C++ -+# -+COMMON_CFLAGS := $(COMMON_FLAGS) \ -+ -Wdeclaration-after-statement -Wno-format-zero-length \ -+ -Wmissing-prototypes -Wstrict-prototypes -+ -+# Additional warnings, and optional warnings. -+# -+WARNING_CFLAGS := \ -+ -Wpointer-arith -Wunused-parameter \ -+ -Wmissing-format-attribute \ -+ $(call cc-option,-Wno-missing-field-initializers) \ -+ $(call cc-option,-fdiagnostics-show-option) -+ -+ifeq ($(W),1) -+WARNING_CFLAGS += \ -+ $(call cc-option,-Wbad-function-cast) \ -+ $(call cc-option,-Wcast-qual) \ -+ $(call cc-option,-Wcast-align) \ -+ $(call cc-option,-Wconversion) \ -+ $(call cc-option,-Wdisabled-optimization) \ -+ $(call cc-option,-Wlogical-op) \ -+ $(call cc-option,-Wmissing-declarations) \ -+ $(call cc-option,-Wmissing-include-dirs) \ -+ $(call cc-option,-Wnested-externs) \ -+ $(call cc-option,-Wold-style-definition) \ -+ $(call cc-option,-Woverlength-strings) \ -+ $(call cc-option,-Wpacked) \ -+ $(call cc-option,-Wpacked-bitfield-compat) \ -+ $(call cc-option,-Wpadded) \ -+ $(call cc-option,-Wredundant-decls) \ -+ $(call cc-option,-Wshadow) \ -+ $(call cc-option,-Wswitch-default) \ -+ $(call cc-option,-Wvla) \ -+ $(call cc-option,-Wwrite-strings) -+endif -+ -+WARNING_CFLAGS += \ -+ $(call cc-optional-warning,-Wunused-but-set-variable) -+ -+HOST_WARNING_CFLAGS := \ -+ -Wpointer-arith -Wunused-parameter \ -+ -Wmissing-format-attribute \ -+ $(call host-cc-option,-Wno-missing-field-initializers) \ -+ $(call host-cc-option,-fdiagnostics-show-option) -+ -+ifeq ($(W),1) -+HOST_WARNING_CFLAGS += \ -+ $(call host-cc-option,-Wbad-function-cast) \ -+ $(call host-cc-option,-Wcast-qual) \ -+ $(call host-cc-option,-Wcast-align) \ -+ $(call host-cc-option,-Wconversion) \ -+ $(call host-cc-option,-Wdisabled-optimization) \ -+ $(call host-cc-option,-Wlogical-op) \ -+ $(call host-cc-option,-Wmissing-declarations) \ -+ $(call host-cc-option,-Wmissing-include-dirs) \ -+ $(call host-cc-option,-Wnested-externs) \ -+ $(call host-cc-option,-Wold-style-definition) \ -+ $(call host-cc-option,-Woverlength-strings) \ -+ $(call host-cc-option,-Wpacked) \ -+ $(call host-cc-option,-Wpacked-bitfield-compat) \ -+ $(call host-cc-option,-Wpadded) \ -+ $(call host-cc-option,-Wredundant-decls) \ -+ $(call host-cc-option,-Wshadow) \ -+ $(call host-cc-option,-Wswitch-default) \ -+ $(call host-cc-option,-Wvla) \ -+ $(call host-cc-option,-Wwrite-strings) -+endif -+ -+HOST_WARNING_CFLAGS += \ -+ $(call host-cc-optional-warning,-Wunused-but-set-variable) -+ -+KBUILD_WARNING_CFLAGS := \ -+ -Wno-unused-parameter -Wno-sign-compare -+KBUILD_WARNING_CFLAGS += \ -+ $(call kernel-cc-optional-warning,-Wbad-function-cast) \ -+ $(call kernel-cc-optional-warning,-Wcast-qual) \ -+ $(call kernel-cc-optional-warning,-Wcast-align) \ -+ $(call kernel-cc-optional-warning,-Wconversion) \ -+ $(call kernel-cc-optional-warning,-Wdisabled-optimization) \ -+ $(call kernel-cc-optional-warning,-Wlogical-op) \ -+ $(call kernel-cc-optional-warning,-Wmissing-declarations) \ -+ $(call kernel-cc-optional-warning,-Wmissing-include-dirs) \ -+ $(call kernel-cc-optional-warning,-Wnested-externs) \ -+ $(call kernel-cc-optional-warning,-Wno-missing-field-initializers) \ -+ $(call kernel-cc-optional-warning,-Wold-style-definition) \ -+ $(call kernel-cc-optional-warning,-Woverlength-strings) \ -+ $(call kernel-cc-optional-warning,-Wpacked) \ -+ $(call kernel-cc-optional-warning,-Wpacked-bitfield-compat) \ -+ $(call kernel-cc-optional-warning,-Wpadded) \ -+ $(call kernel-cc-optional-warning,-Wredundant-decls) \ -+ $(call kernel-cc-optional-warning,-Wshadow) \ -+ $(call kernel-cc-optional-warning,-Wswitch-default) \ -+ $(call kernel-cc-optional-warning,-Wvla) \ -+ $(call kernel-cc-optional-warning,-Wwrite-strings) -+ -+# User C only -+# -+ALL_CFLAGS := \ -+ $(COMMON_USER_FLAGS) $(COMMON_CFLAGS) $(WARNING_CFLAGS) \ -+ $(SYS_CFLAGS) -+ -+ALL_HOST_CFLAGS := \ -+ $(COMMON_USER_FLAGS) $(COMMON_CFLAGS) $(HOST_WARNING_CFLAGS) -+ -+# User C++ only -+# -+ALL_CXXFLAGS := \ -+ $(COMMON_USER_FLAGS) $(COMMON_FLAGS) \ -+ -fno-rtti -fno-exceptions \ -+ -Wpointer-arith -Wunused-parameter \ -+ $(SYS_CXXFLAGS) -+ -+ALL_HOST_CXXFLAGS := \ -+ $(COMMON_USER_FLAGS) $(COMMON_CFLAGS) -+ -+# User C and C++ -+# -+# NOTE: ALL_HOST_LDFLAGS should probably be using -rpath-link too, and if we -+# ever need to support building host shared libraries, it's required. -+# -+# We can't use it right now because we want to support non-GNU-compatible -+# linkers like the Darwin 'ld' which doesn't support -rpath-link. -+# -+ALL_HOST_LDFLAGS := -L$(HOST_OUT) -+ALL_LDFLAGS := -L$(TARGET_OUT) -Xlinker -rpath-link=$(TARGET_OUT) -+ -+ifneq ($(strip $(TOOLCHAIN)),) -+ALL_LDFLAGS += -L$(TOOLCHAIN)/lib -Xlinker -rpath-link=$(TOOLCHAIN)/lib -+endif -+ -+ifneq ($(strip $(LINKER_RPATH)),) -+ALL_LDFLAGS += $(addprefix -Xlinker -rpath=,$(LINKER_RPATH)) -+endif -+ -+ALL_LDFLAGS += $(SYS_LDFLAGS) -+ -+# Kernel C only -+# -+ALL_KBUILD_CFLAGS := $(COMMON_CFLAGS) $(KBUILD_WARNING_CFLAGS) \ -+ $(call kernel-cc-option,-Wno-type-limits) \ -+ $(call kernel-cc-option,-Wno-pointer-arith) \ -+ $(call kernel-cc-option,-Wno-aggregate-return) \ -+ $(call kernel-cc-option,-Wno-unused-but-set-variable) -+ -+# This variable contains a list of all modules built by kbuild -+ALL_KBUILD_MODULES := -+ -+# This variable contains a list of all modules which contain C++ source files -+ALL_CXX_MODULES := -+ -+# Toolchain triple for cross environment -+CROSS_TRIPLE := $(patsubst %-,%,$(CROSS_COMPILE)) -diff --git a/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/commands.mk b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/commands.mk -new file mode 100644 -index 0000000..f72baf5 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/commands.mk -@@ -0,0 +1,237 @@ -+########################################################################### ### -+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+#@License Dual MIT/GPLv2 -+# -+# The contents of this file are subject to the MIT license as set out below. -+# -+# Permission is hereby granted, free of charge, to any person obtaining a copy -+# of this software and associated documentation files (the "Software"), to deal -+# in the Software without restriction, including without limitation the rights -+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+# copies of the Software, and to permit persons to whom the Software is -+# furnished to do so, subject to the following conditions: -+# -+# The above copyright notice and this permission notice shall be included in -+# all copies or substantial portions of the Software. -+# -+# Alternatively, the contents of this file may be used under the terms of -+# the GNU General Public License Version 2 ("GPL") in which case the provisions -+# of GPL are applicable instead of those above. -+# -+# If you wish to allow use of your version of this file only under the terms of -+# GPL, and not to allow others to use your version of this file under the terms -+# of the MIT license, indicate your decision by deleting the provisions above -+# and replace them with the notice and other provisions required by GPL as set -+# out in the file called "GPL-COPYING" included in this distribution. If you do -+# not delete the provisions above, a recipient may use your version of this file -+# under the terms of either the MIT license or GPL. -+# -+# This License is also included in this distribution in the file called -+# "MIT-COPYING". -+# -+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+### ########################################################################### -+ -+# from-one-* recipes make a thing from one source file, so they use $<. Others -+# use $(MODULE_something) instead of $^ -+ -+# We expect that MODULE_*FLAGS contains all the flags we need, including the -+# flags for all modules (like $(ALL_CFLAGS) and $(ALL_HOST_CFLAGS)), and -+# excluding flags for include search dirs or for linking libraries. The -+# exceptions are ALL_EXE_LDFLAGS and ALL_LIB_LDFLAGS, since they depend on the -+# type of thing being linked, so they appear in the commands below -+ -+define host-o-from-one-c -+$(if $(V),,@echo " HOST_CC " $(call relative-to-top,$<)) -+$(HOST_CC) -MD -c $(MODULE_HOST_CFLAGS) $(MODULE_INCLUDE_FLAGS) \ -+ -include $(CONFIG_H) $< -o $@ -+endef -+ -+define target-o-from-one-c -+$(if $(V),,@echo " CC " $(call relative-to-top,$<)) -+$(CC) -MD -c $(MODULE_CFLAGS) $(MODULE_INCLUDE_FLAGS) \ -+ -include $(CONFIG_H) $< -o $@ -+endef -+ -+# We use $(CC) to compile C++ files, and expect it to detect that it's -+# compiling C++ -+define host-o-from-one-cxx -+$(if $(V),,@echo " HOST_CC " $(call relative-to-top,$<)) -+$(HOST_CC) -MD -c $(MODULE_HOST_CXXFLAGS) $(MODULE_INCLUDE_FLAGS) \ -+ -include $(CONFIG_H) $< -o $@ -+endef -+ -+define target-o-from-one-cxx -+$(if $(V),,@echo " CC " $(call relative-to-top,$<)) -+$(CC) -MD -c $(MODULE_CXXFLAGS) $(MODULE_INCLUDE_FLAGS) \ -+ -include $(CONFIG_H) $< -o $@ -+endef -+ -+define host-executable-from-o -+$(if $(V),,@echo " HOST_LD " $(call relative-to-top,$@)) -+$(HOST_CC) $(MODULE_HOST_LDFLAGS) \ -+ -o $@ $(sort $(MODULE_ALL_OBJECTS)) $(MODULE_LIBRARY_DIR_FLAGS) \ -+ $(MODULE_LIBRARY_FLAGS) -+endef -+ -+define host-executable-cxx-from-o -+$(if $(V),,@echo " HOST_LD " $(call relative-to-top,$@)) -+$(HOST_CXX) $(MODULE_HOST_LDFLAGS) \ -+ -o $@ $(sort $(MODULE_ALL_OBJECTS)) $(MODULE_LIBRARY_DIR_FLAGS) \ -+ $(MODULE_LIBRARY_FLAGS) -+endef -+ -+define target-executable-from-o -+$(if $(V),,@echo " LD " $(call relative-to-top,$@)) -+$(CC) \ -+ $(SYS_EXE_LDFLAGS) $(MODULE_LDFLAGS) -o $@ \ -+ $(SYS_EXE_CRTBEGIN) $(sort $(MODULE_ALL_OBJECTS)) $(SYS_EXE_CRTEND) \ -+ $(MODULE_LIBRARY_DIR_FLAGS) $(MODULE_LIBRARY_FLAGS) $(LIBGCC) -+endef -+ -+define target-executable-cxx-from-o -+$(if $(V),,@echo " LD " $(call relative-to-top,$@)) -+$(CXX) \ -+ $(SYS_EXE_LDFLAGS_CXX) $(SYS_EXE_LDFLAGS) $(MODULE_LDFLAGS) -o $@ \ -+ $(SYS_EXE_CRTBEGIN) $(sort $(MODULE_ALL_OBJECTS)) $(SYS_EXE_CRTEND) \ -+ $(MODULE_LIBRARY_DIR_FLAGS) $(MODULE_LIBRARY_FLAGS) $(LIBGCC) -+endef -+ -+define target-shared-library-from-o -+$(if $(V),,@echo " LD " $(call relative-to-top,$@)) -+$(CC) -shared -Wl,-Bsymbolic \ -+ $(SYS_LIB_LDFLAGS) $(MODULE_LDFLAGS) -o $@ \ -+ $(SYS_LIB_CRTBEGIN) $(sort $(MODULE_ALL_OBJECTS)) $(SYS_LIB_CRTEND) \ -+ $(MODULE_LIBRARY_DIR_FLAGS) $(MODULE_LIBRARY_FLAGS) $(LIBGCC) -+endef -+ -+# If there were any C++ source files in a shared library, we use this recipe, -+# which runs the C++ compiler to link the final library -+define target-shared-library-cxx-from-o -+$(if $(V),,@echo " LD " $(call relative-to-top,$@)) -+$(CXX) -shared -Wl,-Bsymbolic \ -+ $(SYS_LIB_LDFLAGS_CXX) $(SYS_LIB_LDFLAGS) $(MODULE_LDFLAGS) -o $@ \ -+ $(SYS_LIB_CRTBEGIN) $(sort $(MODULE_ALL_OBJECTS)) $(SYS_LIB_CRTEND) \ -+ $(MODULE_LIBRARY_DIR_FLAGS) $(MODULE_LIBRARY_FLAGS) $(LIBGCC) -+endef -+ -+define host-shared-library-from-o -+$(if $(V),,@echo " HOST_LD " $(call relative-to-top,$@)) -+$(HOST_CC) -shared -Wl,-Bsymbolic \ -+ $(MODULE_HOST_LDFLAGS) -o $@ \ -+ $(sort $(MODULE_ALL_OBJECTS)) \ -+ $(MODULE_LIBRARY_DIR_FLAGS) $(MODULE_LIBRARY_FLAGS) -+endef -+ -+# If there were any C++ source files in a shared library, we use this recipe, -+# which runs the C++ compiler to link the final library -+define host-shared-library-cxx-from-o -+$(if $(V),,@echo " HOST_LD " $(call relative-to-top,$@)) -+$(HOST_CXX) -shared -Wl,-Bsymbolic \ -+ $(MODULE_HOST_LDFLAGS) -o $@ \ -+ $(sort $(MODULE_ALL_OBJECTS)) \ -+ $(MODULE_LIBRARY_DIR_FLAGS) $(MODULE_LIBRARY_FLAGS) -+endef -+ -+define target-copy-debug-information -+$(OBJCOPY) --only-keep-debug $@ $(basename $@).dbg -+endef -+ -+define host-strip-debug-information -+$(HOST_STRIP) --strip-unneeded $@ -+endef -+ -+define target-strip-debug-information -+$(STRIP) --strip-unneeded $@ -+endef -+ -+define target-add-debuglink -+$(if $(V),,@echo " DBGLINK " $(call relative-to-top,$(basename $@).dbg)) -+$(OBJCOPY) --add-gnu-debuglink=$(basename $@).dbg $@ -+endef -+ -+define host-static-library-from-o -+$(if $(V),,@echo " HOST_AR " $(call relative-to-top,$@)) -+$(HOST_AR) cru $@ $(sort $(MODULE_ALL_OBJECTS)) -+endef -+ -+define target-static-library-from-o -+$(if $(V),,@echo " AR " $(call relative-to-top,$@)) -+$(AR) cru $@ $(sort $(MODULE_ALL_OBJECTS)) -+endef -+ -+define tab-c-from-y -+$(if $(V),,@echo " BISON " $(call relative-to-top,$<)) -+$(BISON) $(MODULE_BISON_FLAGS) -o $@ -d $< -+endef -+ -+define l-c-from-l -+$(if $(V),,@echo " FLEX " $(call relative-to-top,$<)) -+$(FLEX) $(MODULE_FLEX_FLAGS) -o$@ $< -+endef -+ -+define clean-dirs -+$(if $(V),,@echo " RM " $(call relative-to-top,$(MODULE_DIRS_TO_REMOVE))) -+$(RM) -rf $(MODULE_DIRS_TO_REMOVE) -+endef -+ -+define make-directory -+$(MKDIR) -p $@ -+endef -+ -+define check-exports -+endef -+ -+# Programs used in recipes -+ -+BISON ?= bison -+CC ?= gcc -+CXX ?= g++ -+HOST_CC ?= gcc -+HOST_CXX ?= g++ -+JAR ?= jar -+JAVA ?= java -+JAVAC ?= javac -+ZIP ?= zip -+ -+override AR := $(if $(V),,@)$(CROSS_COMPILE)ar -+override BISON := $(if $(V),,@)$(BISON) -+override BZIP2 := $(if $(V),,@)bzip2 -9 -+override CC := $(if $(V),,@)$(CROSS_COMPILE)$(CC) -+override CC_CHECK := $(if $(V),,@)$(MAKE_TOP)/tools/cc-check.sh -+override CXX := $(if $(V),,@)$(CROSS_COMPILE)$(CXX) -+override CHMOD := $(if $(V),,@)chmod -+override CP := $(if $(V),,@)cp -+override ECHO := $(if $(V),,@)echo -+override FLEX := $(if $(V),,@)flex -+override GAWK := $(if $(V),,@)gawk -+override GREP := $(if $(V),,@)grep -+override HOST_AR := $(if $(V),,@)ar -+override HOST_CC := $(if $(V),,@)$(HOST_CC) -+override HOST_CXX := $(if $(V),,@)$(HOST_CXX) -+override HOST_STRIP := $(if $(V),,@)strip -+override INSTALL := $(if $(V),,@)install -+override JAR := $(if $(V),,@)$(JAR) -+override JAVA := $(if $(V),,@)$(JAVA) -+override JAVAC := $(if $(V),,@)$(JAVAC) -+override M4 := $(if $(V),,@)m4 -+override MKDIR := $(if $(V),,@)mkdir -+override MV := $(if $(V),,@)mv -+override OBJCOPY := $(if $(V),,@)$(CROSS_COMPILE)objcopy -+override PDSASM := $(if $(V),,@)$(HOST_OUT)/pdsasm -+override RANLIB := $(if $(V),,@)$(CROSS_COMPILE)ranlib -+override RM := $(if $(V),,@)rm -f -+override SED := $(if $(V),,@)sed -+override STRIP := $(if $(V),,@)$(CROSS_COMPILE)strip -+override TAR := $(if $(V),,@)tar -+override TOUCH := $(if $(V),,@)touch -+override USEASM := $(if $(V),,@)$(HOST_OUT)/useasm -+override USELINK := $(if $(V),,@)$(HOST_OUT)/uselink -+override VHD2INC := $(if $(V),,@)$(HOST_OUT)/vhd2inc -+override ZIP := $(if $(V),,@)$(ZIP) -diff --git a/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/common/apis/xorg.mk b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/common/apis/xorg.mk -new file mode 100644 -index 0000000..7a15ab1 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/common/apis/xorg.mk -@@ -0,0 +1,48 @@ -+########################################################################### ### -+#@Title XOrg root makefile -+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+#@License Dual MIT/GPLv2 -+# -+# The contents of this file are subject to the MIT license as set out below. -+# -+# Permission is hereby granted, free of charge, to any person obtaining a copy -+# of this software and associated documentation files (the "Software"), to deal -+# in the Software without restriction, including without limitation the rights -+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+# copies of the Software, and to permit persons to whom the Software is -+# furnished to do so, subject to the following conditions: -+# -+# The above copyright notice and this permission notice shall be included in -+# all copies or substantial portions of the Software. -+# -+# Alternatively, the contents of this file may be used under the terms of -+# the GNU General Public License Version 2 ("GPL") in which case the provisions -+# of GPL are applicable instead of those above. -+# -+# If you wish to allow use of your version of this file only under the terms of -+# GPL, and not to allow others to use your version of this file under the terms -+# of the MIT license, indicate your decision by deleting the provisions above -+# and replace them with the notice and other provisions required by GPL as set -+# out in the file called "GPL-COPYING" included in this distribution. If you do -+# not delete the provisions above, a recipient may use your version of this file -+# under the terms of either the MIT license or GPL. -+# -+# This License is also included in this distribution in the file called -+# "MIT-COPYING". -+# -+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+### ########################################################################### -+ -+ifeq ($(filter xorg,$(EXCLUDED_APIS)),) -+ COMPONENTS += xorg pvr_conf pvr_video pvr_video_bin wsegl_dri2_linux -+ -include ../common/apis/xorg_opengl.mk -+ifeq ($(SUPPORT_PVR_REMOTE),1) -+ COMPONENTS += pvr_input -+endif -+endif -diff --git a/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/common/dridrm.mk b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/common/dridrm.mk -new file mode 100644 -index 0000000..e358f57 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/common/dridrm.mk -@@ -0,0 +1,60 @@ -+########################################################################### ### -+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+#@License Dual MIT/GPLv2 -+# -+# The contents of this file are subject to the MIT license as set out below. -+# -+# Permission is hereby granted, free of charge, to any person obtaining a copy -+# of this software and associated documentation files (the "Software"), to deal -+# in the Software without restriction, including without limitation the rights -+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+# copies of the Software, and to permit persons to whom the Software is -+# furnished to do so, subject to the following conditions: -+# -+# The above copyright notice and this permission notice shall be included in -+# all copies or substantial portions of the Software. -+# -+# Alternatively, the contents of this file may be used under the terms of -+# the GNU General Public License Version 2 ("GPL") in which case the provisions -+# of GPL are applicable instead of those above. -+# -+# If you wish to allow use of your version of this file only under the terms of -+# GPL, and not to allow others to use your version of this file under the terms -+# of the MIT license, indicate your decision by deleting the provisions above -+# and replace them with the notice and other provisions required by GPL as set -+# out in the file called "GPL-COPYING" included in this distribution. If you do -+# not delete the provisions above, a recipient may use your version of this file -+# under the terms of either the MIT license or GPL. -+# -+# This License is also included in this distribution in the file called -+# "MIT-COPYING". -+# -+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+### ########################################################################### -+ -+$(eval $(call TunableBothConfigC,SUPPORT_DRI_DRM,)) -+$(eval $(call TunableBothConfigC,SUPPORT_DRI_DRM_EXT,)) -+$(eval $(call TunableKernelConfigC,SUPPORT_DRI_DRM_PLUGIN,)) -+ -+ -+$(eval $(call TunableBothConfigMake,SUPPORT_DRI_DRM,)) -+ -+ifeq ($(SUPPORT_DRI_DRM),1) -+ifeq ($(SUPPORT_DRI_DRM_NO_LIBDRM),1) -+endif -+$(eval $(call TunableKernelConfigC,PVR_SECURE_DRM_AUTH_EXPORT,)) -+$(eval $(call TunableKernelConfigC,SUPPORT_DRM_MODESET,)) -+endif -+ -+$(eval $(call TunableKernelConfigC,PVR_DISPLAY_CONTROLLER_DRM_IOCTL,)) -+ -+$(eval $(call TunableBothConfigC,PVR_DRI_DRM_NOT_PCI)) -+$(eval $(call TunableBothConfigMake,PVR_DRI_DRM_NOT_PCI)) -+ -+$(eval $(call TunableKernelConfigC,PVR_DRI_DRM_PLATFORM_DEV,)) -diff --git a/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/common/omap4.mk b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/common/omap4.mk -new file mode 100644 -index 0000000..c7a218f ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/common/omap4.mk -@@ -0,0 +1,43 @@ -+########################################################################### ### -+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+#@License Dual MIT/GPLv2 -+# -+# The contents of this file are subject to the MIT license as set out below. -+# -+# Permission is hereby granted, free of charge, to any person obtaining a copy -+# of this software and associated documentation files (the "Software"), to deal -+# in the Software without restriction, including without limitation the rights -+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+# copies of the Software, and to permit persons to whom the Software is -+# furnished to do so, subject to the following conditions: -+# -+# The above copyright notice and this permission notice shall be included in -+# all copies or substantial portions of the Software. -+# -+# Alternatively, the contents of this file may be used under the terms of -+# the GNU General Public License Version 2 ("GPL") in which case the provisions -+# of GPL are applicable instead of those above. -+# -+# If you wish to allow use of your version of this file only under the terms of -+# GPL, and not to allow others to use your version of this file under the terms -+# of the MIT license, indicate your decision by deleting the provisions above -+# and replace them with the notice and other provisions required by GPL as set -+# out in the file called "GPL-COPYING" included in this distribution. If you do -+# not delete the provisions above, a recipient may use your version of this file -+# under the terms of either the MIT license or GPL. -+# -+# This License is also included in this distribution in the file called -+# "MIT-COPYING". -+# -+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+### ########################################################################### -+ -+$(eval $(call TunableKernelConfigC,PVR_NO_OMAP_TIMER,)) -+$(eval $(call TunableKernelConfigC,PVR_OMAPLFB_DONT_USE_FB_PAN_DISPLAY,)) -+$(eval $(call TunableKernelConfigC,PVR_OMAPLFB_DRM_FB,)) -diff --git a/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/common/opencl.mk b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/common/opencl.mk -new file mode 100644 -index 0000000..2e895ca ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/common/opencl.mk -@@ -0,0 +1,39 @@ -+########################################################################### ### -+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+#@License Dual MIT/GPLv2 -+# -+# The contents of this file are subject to the MIT license as set out below. -+# -+# Permission is hereby granted, free of charge, to any person obtaining a copy -+# of this software and associated documentation files (the "Software"), to deal -+# in the Software without restriction, including without limitation the rights -+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+# copies of the Software, and to permit persons to whom the Software is -+# furnished to do so, subject to the following conditions: -+# -+# The above copyright notice and this permission notice shall be included in -+# all copies or substantial portions of the Software. -+# -+# Alternatively, the contents of this file may be used under the terms of -+# the GNU General Public License Version 2 ("GPL") in which case the provisions -+# of GPL are applicable instead of those above. -+# -+# If you wish to allow use of your version of this file only under the terms of -+# GPL, and not to allow others to use your version of this file under the terms -+# of the MIT license, indicate your decision by deleting the provisions above -+# and replace them with the notice and other provisions required by GPL as set -+# out in the file called "GPL-COPYING" included in this distribution. If you do -+# not delete the provisions above, a recipient may use your version of this file -+# under the terms of either the MIT license or GPL. -+# -+# This License is also included in this distribution in the file called -+# "MIT-COPYING". -+# -+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+### ########################################################################### -diff --git a/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/common/xorg.mk b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/common/xorg.mk -new file mode 100644 -index 0000000..e4b972a ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/common/xorg.mk -@@ -0,0 +1,47 @@ -+########################################################################### ### -+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+#@License Dual MIT/GPLv2 -+# -+# The contents of this file are subject to the MIT license as set out below. -+# -+# Permission is hereby granted, free of charge, to any person obtaining a copy -+# of this software and associated documentation files (the "Software"), to deal -+# in the Software without restriction, including without limitation the rights -+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+# copies of the Software, and to permit persons to whom the Software is -+# furnished to do so, subject to the following conditions: -+# -+# The above copyright notice and this permission notice shall be included in -+# all copies or substantial portions of the Software. -+# -+# Alternatively, the contents of this file may be used under the terms of -+# the GNU General Public License Version 2 ("GPL") in which case the provisions -+# of GPL are applicable instead of those above. -+# -+# If you wish to allow use of your version of this file only under the terms of -+# GPL, and not to allow others to use your version of this file under the terms -+# of the MIT license, indicate your decision by deleting the provisions above -+# and replace them with the notice and other provisions required by GPL as set -+# out in the file called "GPL-COPYING" included in this distribution. If you do -+# not delete the provisions above, a recipient may use your version of this file -+# under the terms of either the MIT license or GPL. -+# -+# This License is also included in this distribution in the file called -+# "MIT-COPYING". -+# -+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+### ########################################################################### -+ -+PVR_SECURE_DRM_AUTH_EXPORT := 1 -+ -+$(eval $(call TunableKernelConfigC,XPROC_WORKAROUND_NUM_SHAREABLES,4095)) -+ -+ifeq ($(SUPPORT_PVR_REMOTE),1) -+else -+endif -diff --git a/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/common/xorg_test.mk b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/common/xorg_test.mk -new file mode 100644 -index 0000000..31e7ff5 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/common/xorg_test.mk -@@ -0,0 +1,48 @@ -+########################################################################### ### -+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+#@License Dual MIT/GPLv2 -+# -+# The contents of this file are subject to the MIT license as set out below. -+# -+# Permission is hereby granted, free of charge, to any person obtaining a copy -+# of this software and associated documentation files (the "Software"), to deal -+# in the Software without restriction, including without limitation the rights -+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+# copies of the Software, and to permit persons to whom the Software is -+# furnished to do so, subject to the following conditions: -+# -+# The above copyright notice and this permission notice shall be included in -+# all copies or substantial portions of the Software. -+# -+# Alternatively, the contents of this file may be used under the terms of -+# the GNU General Public License Version 2 ("GPL") in which case the provisions -+# of GPL are applicable instead of those above. -+# -+# If you wish to allow use of your version of this file only under the terms of -+# GPL, and not to allow others to use your version of this file under the terms -+# of the MIT license, indicate your decision by deleting the provisions above -+# and replace them with the notice and other provisions required by GPL as set -+# out in the file called "GPL-COPYING" included in this distribution. If you do -+# not delete the provisions above, a recipient may use your version of this file -+# under the terms of either the MIT license or GPL. -+# -+# This License is also included in this distribution in the file called -+# "MIT-COPYING". -+# -+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+### ########################################################################### -+ -+# FIXME: Will go away when SUPPORT_DRI_DRM is untangled from -+# the old meaning of SUPPORT_XORG=1. -+ -+ifeq ($(filter xorg,$(EXCLUDED_APIS)),) -+ifneq ($(wildcard ../common/apis/xorg.mk),) -+want_xorg := 1 -+endif -+endif -diff --git a/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/config/core.mk b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/config/core.mk -new file mode 100644 -index 0000000..3d30223 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/config/core.mk -@@ -0,0 +1,642 @@ -+########################################################################### ### -+#@Title Root build configuration. -+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+#@License Dual MIT/GPLv2 -+# -+# The contents of this file are subject to the MIT license as set out below. -+# -+# Permission is hereby granted, free of charge, to any person obtaining a copy -+# of this software and associated documentation files (the "Software"), to deal -+# in the Software without restriction, including without limitation the rights -+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+# copies of the Software, and to permit persons to whom the Software is -+# furnished to do so, subject to the following conditions: -+# -+# The above copyright notice and this permission notice shall be included in -+# all copies or substantial portions of the Software. -+# -+# Alternatively, the contents of this file may be used under the terms of -+# the GNU General Public License Version 2 ("GPL") in which case the provisions -+# of GPL are applicable instead of those above. -+# -+# If you wish to allow use of your version of this file only under the terms of -+# GPL, and not to allow others to use your version of this file under the terms -+# of the MIT license, indicate your decision by deleting the provisions above -+# and replace them with the notice and other provisions required by GPL as set -+# out in the file called "GPL-COPYING" included in this distribution. If you do -+# not delete the provisions above, a recipient may use your version of this file -+# under the terms of either the MIT license or GPL. -+# -+# This License is also included in this distribution in the file called -+# "MIT-COPYING". -+# -+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+### ########################################################################### -+ -+# Configuration wrapper for new build system. This file deals with -+# configuration of the build. Add to this file anything that deals -+# with switching driver options on/off and altering the defines or -+# objects the build uses. -+# -+# At the end of this file is an exhaustive list of all variables -+# that are passed between the platform/config stage and the generic -+# build. PLEASE refrain from adding more variables than necessary -+# to this stage -- almost all options can go through config.h. -+# -+ -+################################# MACROS #################################### -+ -+# Write out a kernel GNU make option. -+# -+define KernelConfigMake -+$$(shell echo "override $(1) := $(2)" >>$(CONFIG_KERNEL_MK).new) -+$(if $(filter config,$(D)),$(info KernelConfigMake $(1) := $(2) # $(if $($(1)),$(origin $(1)),default))) -+endef -+ -+# Write out a GNU make option for both user & kernel -+# -+define BothConfigMake -+$$(eval $$(call KernelConfigMake,$(1),$(2))) -+endef -+ -+# Conditionally write out a kernel GNU make option -+# -+define TunableKernelConfigMake -+ifneq ($$($(1)),) -+ifneq ($$($(1)),0) -+$$(eval $$(call KernelConfigMake,$(1),$$($(1)))) -+endif -+else -+ifneq ($(2),) -+$$(eval $$(call KernelConfigMake,$(1),$(2))) -+endif -+endif -+endef -+ -+# Conditionally write out a GNU make option for both user & kernel -+# -+define TunableBothConfigMake -+$$(eval $$(call TunableKernelConfigMake,$(1),$(2))) -+endef -+ -+# Write out a kernel-only option -+# -+define KernelConfigC -+$$(shell echo "#define $(1) $(2)" >>$(CONFIG_KERNEL_H).new) -+$(if $(filter config,$(D)),$(info KernelConfigC #define $(1) $(2) /* $(if $($(1)),$(origin $(1)),default) */),) -+endef -+ -+# Write out an option for both user & kernel -+# -+define BothConfigC -+$$(eval $$(call KernelConfigC,$(1),$(2))) -+endef -+ -+# Conditionally write out a kernel-only option -+# -+define TunableKernelConfigC -+ifneq ($$($(1)),) -+ifneq ($$($(1)),0) -+ifeq ($$($(1)),1) -+$$(eval $$(call KernelConfigC,$(1),)) -+else -+$$(eval $$(call KernelConfigC,$(1),$$($(1)))) -+endif -+endif -+else -+ifneq ($(2),) -+ifeq ($(2),1) -+$$(eval $$(call KernelConfigC,$(1),)) -+else -+$$(eval $$(call KernelConfigC,$(1),$(2))) -+endif -+endif -+endif -+endef -+ -+# Conditionally write out an option for both user & kernel -+# -+define TunableBothConfigC -+$$(eval $$(call TunableKernelConfigC,$(1),$(2))) -+endef -+ -+############################### END MACROS ################################## -+ -+# Check we have a new enough version of GNU make. -+# -+need := 3.81 -+ifeq ($(filter $(need),$(firstword $(sort $(MAKE_VERSION) $(need)))),) -+$(error A version of GNU make >= $(need) is required - this is version $(MAKE_VERSION)) -+endif -+ -+# Try to guess EURASIAROOT if it wasn't set. Check this location. -+# -+_GUESSED_EURASIAROOT := $(abspath ../../../..) -+ifneq ($(strip $(EURASIAROOT)),) -+# We don't want to warn about EURASIAROOT if it's empty: this might mean that -+# it's not set at all anywhere, but it could also mean that it's set like -+# "export EURASIAROOT=" or "make EURASIAROOT= sometarget". If it is set but -+# empty, we'll act as if it's unset and not warn. -+ifneq ($(strip $(EURASIAROOT)),$(_GUESSED_EURASIAROOT)) -+nothing := -+space := $(nothing) $(nothing) -+$(warning EURASIAROOT is set (via: $(origin EURASIAROOT)), but its value does not) -+$(warning match the root of this source tree, so it is being ignored) -+$(warning EURASIAROOT is set to: $(EURASIAROOT)) -+$(warning $(space)The detected root is: $(_GUESSED_EURASIAROOT)) -+$(warning To suppress this message, unset EURASIAROOT or set it empty) -+endif -+# else, EURASIAROOT matched the actual root of the source tree: don't warn -+endif -+override EURASIAROOT := $(_GUESSED_EURASIAROOT) -+TOP := $(EURASIAROOT) -+ -+ifneq ($(words $(TOP)),1) -+$(warning This source tree is located in a path which contains whitespace,) -+$(warning which is not supported.) -+$(warning $(space)The root is: $(TOP)) -+$(error Whitespace found in $$(TOP)) -+endif -+ -+$(call directory-must-exist,$(TOP)) -+ -+include ../defs.mk -+ -+# Infer PVR_BUILD_DIR from the directory configuration is launched from. -+# Check anyway that such a directory exists. -+# -+PVR_BUILD_DIR := $(notdir $(abspath .)) -+$(call directory-must-exist,$(TOP)/eurasiacon/build/linux2/$(PVR_BUILD_DIR)) -+ -+# Output directory for configuration, object code, -+# final programs/libraries, and install/rc scripts. -+# -+BUILD ?= release -+OUT ?= $(TOP)/eurasiacon/binary2_$(PVR_BUILD_DIR)_$(BUILD) -+override OUT := $(if $(filter /%,$(OUT)),$(OUT),$(TOP)/$(OUT)) -+ -+CONFIG_MK := $(OUT)/config.mk -+CONFIG_H := $(OUT)/config.h -+CONFIG_KERNEL_MK := $(OUT)/config_kernel.mk -+CONFIG_KERNEL_H := $(OUT)/config_kernel.h -+ -+# Convert commas to spaces in $(D). This is so you can say "make -+# D=config-changes,freeze-config" and have $(filter config-changes,$(D)) -+# still work. -+comma := , -+empty := -+space := $(empty) $(empty) -+override D := $(subst $(comma),$(space),$(D)) -+ -+# Create the OUT directory and delete any previous intermediary files -+# -+$(shell mkdir -p $(OUT)) -+$(shell \ -+ for file in $(CONFIG_MK).new $(CONFIG_H).new \ -+ $(CONFIG_KERNEL_MK).new $(CONFIG_KERNEL_H).new; do \ -+ rm -f $$file; \ -+ done) -+ -+# Some targets don't need information about any modules. If we only specify -+# these targets on the make command line, set INTERNAL_CLOBBER_ONLY to -+# indicate that toplevel.mk shouldn't read any makefiles -+CLOBBER_ONLY_TARGETS := clean clobber help install -+INTERNAL_CLOBBER_ONLY := -+ifneq ($(strip $(MAKECMDGOALS)),) -+INTERNAL_CLOBBER_ONLY := \ -+$(if \ -+ $(strip $(foreach _cmdgoal,$(MAKECMDGOALS),\ -+ $(if $(filter $(_cmdgoal),$(CLOBBER_ONLY_TARGETS)),,x))),,true) -+endif -+ -+# For a clobber-only build, we shouldn't regenerate any config files, or -+# require things like SGXCORE to be set -+ifneq ($(INTERNAL_CLOBBER_ONLY),true) -+ -+# These are defined by the core build system, but we might need them -+# earlier to feature-check the compilers -+# -+_CC := $(CROSS_COMPILE)$(if $(filter default,$(origin CC)),gcc,$(CC)) -+HOST_CC ?= gcc -+ -+-include ../config/user-defs.mk -+ -+# FIXME: Backwards compatibility remaps. -+# -+ifeq ($(SUPPORT_SLC),1) -+SGX_FEATURE_SYSTEM_CACHE := 1 -+endif -+ifeq ($(BYPASS_SLC),1) -+SGX_BYPASS_SYSTEM_CACHE := 1 -+endif -+ifeq ($(BYPASS_DCU),1) -+SGX_BYPASS_DCU := 1 -+endif -+ifneq ($(SGXCOREREV),) -+SGX_CORE_REV := $(SGXCOREREV) -+endif -+ -+# Core handling -+# -+ifeq ($(SGXCORE),) -+$(error Must specify SGXCORE) -+endif -+ifeq ($(SGX_CORE_REV),) -+override USE_SGX_CORE_REV_HEAD := 1 -+else ifeq ($(SGX_CORE_REV),000) -+override USE_SGX_CORE_REV_HEAD := 1 -+override SGX_CORE_REV := -+else -+override USE_SGX_CORE_REV_HEAD := 0 -+endif -+ -+# Enforced dependencies. Move this to an include. -+# -+ifeq ($(SUPPORT_LINUX_USING_WORKQUEUES),1) -+override PVR_LINUX_USING_WORKQUEUES := 1 -+override PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE := 1 -+override PVR_LINUX_TIMERS_USING_WORKQUEUES := 1 -+override SYS_CUSTOM_POWERLOCK_WRAP := 1 -+else ifeq ($(SUPPORT_LINUX_USING_SHARED_WORKQUEUES),1) -+override PVR_LINUX_USING_WORKQUEUES := 1 -+override PVR_LINUX_MISR_USING_WORKQUEUE := 1 -+override PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE := 1 -+override SYS_CUSTOM_POWERLOCK_WRAP := 1 -+endif -+ -+ifneq ($(PDUMP),1) -+override SUPPORT_PDUMP_MULTI_PROCESS := 0 -+endif -+ -+ifeq ($(SUPPORT_HYBRID_PB),1) -+override SUPPORT_SHARED_PB := 1 -+override SUPPORT_PERCONTEXT_PB := 1 -+else ifeq ($(SUPPORT_PERCONTEXT_PB),1) -+override SUPPORT_SHARED_PB := 0 -+endif -+ -+ifeq ($(NO_HARDWARE),1) -+override SYS_USING_INTERRUPTS := 0 -+override SUPPORT_HW_RECOVERY := 0 -+override SUPPORT_ACTIVE_POWER_MANAGEMENT := 0 -+endif -+ -+ifeq ($(SGX_FEATURE_36BIT_MMU),1) -+override IMG_ADDRSPACE_PHYSADDR_BITS := 64 -+else -+override IMG_ADDRSPACE_PHYSADDR_BITS := 32 -+endif -+ -+ifeq ($(SGXCORE),535) -+ifeq ($(PVRSRV_USSE_EDM_STATUS_DEBUG),1) -+SUPPORT_SGX_HWPERF ?= not-overridden -+ifeq ($(SUPPORT_SGX_HWPERF),not-overridden) -+$(warning Setting SUPPORT_SGX_HWPERF=0 because PVRSRV_USSE_EDM_STATUS_DEBUG=1) -+SUPPORT_SGX_HWPERF := 0 -+endif -+endif -+PVR2D_ALT_2DHW ?= 0 -+endif -+ -+# Multi-core handling must be done separately to other options -+# Also do some sanity checks -+# -+ifeq ($(SGX_FEATURE_MP),1) -+ifeq ($(SGX_FEATURE_MP_CORE_COUNT),) -+ifeq ($(SGX_FEATURE_MP_CORE_COUNT_TA),) -+$(error Must specify SGX_FEATURE_MP_CORE_COUNT or both SGX_FEATURE_MP_CORE_COUNT_TA and SGX_FEATURE_MP_CORE_COUNT_3D with SGX_FEATURE_MP) -+else -+$(eval $(call BothConfigC,SGX_FEATURE_MP_CORE_COUNT_TA,$(SGX_FEATURE_MP_CORE_COUNT_TA))) -+endif -+ifeq ($(SGX_FEATURE_MP_CORE_COUNT_3D),) -+$(error Must specify SGX_FEATURE_MP_CORE_COUNT or both SGX_FEATURE_MP_CORE_COUNT_TA and SGX_FEATURE_MP_CORE_COUNT_3D with SGX_FEATURE_MP) -+else -+$(eval $(call BothConfigC,SGX_FEATURE_MP_CORE_COUNT_3D,$(SGX_FEATURE_MP_CORE_COUNT_3D))) -+endif -+else -+$(eval $(call BothConfigC,SGX_FEATURE_MP_CORE_COUNT,$(SGX_FEATURE_MP_CORE_COUNT))) -+endif -+endif -+ -+# Rather than requiring the user to have to define two variables (one quoted, -+# one not), make PVRSRV_MODNAME a non-tunable and give it an overridable -+# default here. -+# -+PVRSRV_MODNAME ?= pvrsrvkm -+ -+# The user didn't set CROSS_COMPILE. There's probably nothing wrong -+# with that, but we'll let them know anyway. -+# -+ifeq ($(CROSS_COMPILE),) -+$(warning CROSS_COMPILE is not set. Target components will be built with the host compiler) -+endif -+ -+# The user is trying to set one of the old SUPPORT_ options on the -+# command line or in the environment. This isn't supported any more -+# and will often break the build. The user is generally only trying -+# to remove a component from the list of targets to build, so we'll -+# point them at the new way of doing this. -+define sanity-check-support-option-origin -+ifeq ($$(filter undefined file,$$(origin $(1))),) -+$$(warning *** Setting $(1) via $$(origin $(1)) is deprecated) -+$$(error If you are trying to disable a component, use e.g. EXCLUDED_APIS="opengles1 opengl") -+endif -+endef -+$(foreach _o,SYS_CFLAGS SYS_CXXFLAGS SYS_EXE_LDFLAGS SYS_LIB_LDFLAGS SYS_EXE_LDFLAGS_CXX SYS_LIB_LDFLAGS_CXX SUPPORT_EWS SUPPORT_OPENGLES1 SUPPORT_OPENGLES2 SUPPORT_OPENCL SUPPORT_RSCOMPUTE SUPPORT_OPENGL SUPPORT_UNITTESTS SUPPORT_XORG,$(eval $(call sanity-check-support-option-origin,$(_o)))) -+ -+# Check for words in EXCLUDED_APIS that aren't understood by the -+# common/apis/*.mk files. This should be kept in sync with all the tests on -+# EXCLUDED_APIS in those files -+_excludable_apis := rscompute opencl opengl opengles1 opengles2 openvg ews unittests xorg xorg_unittests scripts -+_unrecognised := $(strip $(filter-out $(_excludable_apis),$(EXCLUDED_APIS))) -+ifneq ($(_unrecognised),) -+$(warning *** Unrecognised entries in EXCLUDED_APIS: $(_unrecognised)) -+$(warning *** EXCLUDED_APIS was set via: $(origin EXCLUDED_APIS)) -+$(error Excludable APIs are: $(_excludable_apis)) -+endif -+ -+# Build's selected list of components -+# -+-include components.mk -+ -+# PDUMP needs extra components -+# -+ifeq ($(PDUMP),1) -+ifneq ($(COMPONENTS),) -+COMPONENTS += pdump -+endif -+ifeq ($(SUPPORT_DRI_DRM),1) -+EXTRA_PVRSRVKM_COMPONENTS += dbgdrv -+else -+KERNEL_COMPONENTS += dbgdrv -+endif -+endif -+ -+ifeq ($(SUPPORT_PVR_REMOTE),1) -+ifneq ($(filter pvr2d,$(COMPONENTS)),) -+COMPONENTS += null_pvr2d_remote -+endif -+COMPONENTS += pvrvncsrv -+COMPONENTS += pvrvncinput -+endif -+ -+$(if $(filter config,$(D)),$(info Build configuration:)) -+ -+################################# CONFIG #################################### -+ -+# If KERNELDIR is set, write it out to the config.mk, with -+# KERNEL_COMPONENTS and KERNEL_ID -+# -+ifneq ($(strip $(KERNELDIR)),) -+include ../kernel_version.mk -+PVRSRV_MODULE_BASEDIR ?= /lib/modules/$(KERNEL_ID)/extra/ -+$(eval $(call KernelConfigMake,KERNELDIR,$(KERNELDIR))) -+# Needed only by install script -+$(eval $(call KernelConfigMake,KERNEL_COMPONENTS,$(KERNEL_COMPONENTS))) -+$(eval $(call TunableKernelConfigMake,EXTRA_PVRSRVKM_COMPONENTS,)) -+$(eval $(call TunableKernelConfigMake,EXTRA_KBUILD_SOURCE,)) -+ -+# If KERNEL_CROSS_COMPILE is set to "undef", this is magically -+# equivalent to being unset. If it is unset, we use CROSS_COMPILE -+# (which might also be unset). If it is set, use it directly. -+ifneq ($(KERNEL_CROSS_COMPILE),undef) -+KERNEL_CROSS_COMPILE ?= $(CROSS_COMPILE) -+$(eval $(call TunableBothConfigMake,KERNEL_CROSS_COMPILE,)) -+endif -+ -+# Check the KERNELDIR has a kernel built. -+VMLINUX := $(strip $(wildcard $(KERNELDIR)/vmlinux)) -+LINUXCFG := $(strip $(wildcard $(KERNELDIR)/.config)) -+ -+ifneq ($(VMLINUX),) -+ifneq ($(shell file $(KERNELDIR)/vmlinux | grep 64-bit >/dev/null && echo 1),$(shell $(_CC) -dM -E - </dev/null | grep __x86_64__ >/dev/null && echo 1)) -+$(error Attempting to build 64-bit DDK against 32-bit kernel, or 32-bit DDK against 64-bit kernel. This is not allowed.) -+endif -+VMLINUX_IS_64BIT := $(shell file $(VMLINUX) | grep 64-bit >/dev/null || echo false) -+VMLINUX_HAS_PAE36 := $(shell cat $(LINUXCFG) | grep CONFIG_X86_PAE=y >/dev/null || echo false) -+VMLINUX_HAS_PAE40 := $(shell cat $(LINUXCFG) | grep CONFIG_ARM_LPAE=y >/dev/null || echo false) -+VMLINUX_HAS_DMA32 := $(shell cat $(LINUXCFG) | grep CONFIG_ZONE_DMA32=y >/dev/null || echo false) -+ -+# $(error 64BIT=$(VMLINUX_IS_64BIT) PAE36=$(VMLINUX_HAS_PAE36) PAE40=$(VMLINUX_HAS_PAE40) DMA32=$(VMLINUX_HAS_DMA32) MMU36=$(SGX_FEATURE_36BIT_MMU)) -+ -+ifneq ($(VMLINUX_IS_64BIT),false) -+$(warning $$(KERNELDIR)/vmlinux: Note: vmlinux is 64-bit, which is supported but currently experimental.) -+endif -+else -+$(warning $$(KERNELDIR)/vmlinux does not exist. Kbuild may fail.) -+endif -+endif -+ -+ifneq ($(VMLINUX_HAS_PAE40),false) -+ifeq ($(VMLINUX_HAS_DMA32),false) -+$(warning SGX MMUs are currently supported up to only 36 bits max. Your Kernel is built with 40-bit PAE but does not have CONFIG_ZONE_DMA32.) -+$(warning This means you must ensure the runtime system has <= 4GB of RAM, or there will be BIG problems...) -+endif -+endif -+ -+ifneq ($(SGX_FEATURE_36BIT_MMU),1) -+ifneq ($(VMLINUX_IS_64BIT),false) -+# Kernel is 64-bit -+ifeq ($(VMLINUX_HAS_DMA32),false) -+$(warning SGX is configured with 32-bit MMU. Your Kernel is 64-bit but does not have CONFIG_ZONE_DMA32.) -+$(warning This means you must ensure the runtime system has <= 4GB of RAM, or there will be BIG problems...) -+endif -+else -+ # Kernel is 32-bit -+ifneq ($(VMLINUX_HAS_PAE36),false) -+ifeq ($(VMLINUX_HAS_DMA32),false) -+$(warning SGX is configured with 32-bit MMU. Your Kernel is 32-bit PAE, but does not have CONFIG_ZONE_DMA32. ) -+$(warning This means you must ensure the runtime system has <= 4GB of RAM, or there will be BIG problems...) -+endif -+endif -+endif -+endif -+ -+ -+# Ideally configured by platform Makefiles, as necessary -+# -+ -+# Invariant options for Linux -+# -+$(eval $(call BothConfigC,LINUX,)) -+ -+$(eval $(call BothConfigC,PVR_BUILD_DIR,"\"$(PVR_BUILD_DIR)\"")) -+$(eval $(call BothConfigC,PVR_BUILD_TYPE,"\"$(BUILD)\"")) -+$(eval $(call BothConfigC,PVRSRV_MODNAME,"\"$(PVRSRV_MODNAME)\"")) -+ -+$(eval $(call TunableBothConfigC,SGXCORE,)) -+$(eval $(call BothConfigC,SGX$(SGXCORE),)) -+$(eval $(call BothConfigC,SUPPORT_SGX$(SGXCORE),)) -+ -+$(eval $(call TunableBothConfigC,SUPPORT_SGX,1)) -+$(eval $(call TunableBothConfigC,SGX_CORE_REV,)) -+$(eval $(call TunableBothConfigC,USE_SGX_CORE_REV_HEAD,)) -+ -+$(eval $(call BothConfigC,TRANSFER_QUEUE,)) -+$(eval $(call BothConfigC,PVR_SECURE_HANDLES,)) -+ -+ifneq ($(DISPLAY_CONTROLLER),) -+$(eval $(call BothConfigC,DISPLAY_CONTROLLER,$(DISPLAY_CONTROLLER))) -+endif -+ -+PVR_LINUX_MEM_AREA_POOL_MAX_PAGES ?= 0 -+ifneq ($(PVR_LINUX_MEM_AREA_POOL_MAX_PAGES),0) -+PVR_LINUX_MEM_AREA_USE_VMAP ?= 1 -+include ../kernel_version.mk -+ifeq ($(call kernel-version-at-least,3,0),true) -+PVR_LINUX_MEM_AREA_POOL_ALLOW_SHRINK ?= 1 -+endif -+endif -+$(eval $(call KernelConfigC,PVR_LINUX_MEM_AREA_POOL_MAX_PAGES,$(PVR_LINUX_MEM_AREA_POOL_MAX_PAGES))) -+$(eval $(call TunableKernelConfigC,PVR_LINUX_MEM_AREA_USE_VMAP,)) -+$(eval $(call TunableKernelConfigC,PVR_LINUX_MEM_AREA_POOL_ALLOW_SHRINK,)) -+ -+ -+$(eval $(call BothConfigMake,PVR_SYSTEM,$(PVR_SYSTEM))) -+ -+ -+# Build-type dependent options -+# -+$(eval $(call BothConfigMake,BUILD,$(BUILD))) -+ -+ifeq ($(BUILD),debug) -+$(eval $(call BothConfigC,DEBUG,)) -+$(eval $(call KernelConfigC,DEBUG_LINUX_MEMORY_ALLOCATIONS,)) -+$(eval $(call KernelConfigC,DEBUG_LINUX_MEM_AREAS,)) -+$(eval $(call KernelConfigC,DEBUG_LINUX_MMAP_AREAS,)) -+$(eval $(call KernelConfigC,DEBUG_BRIDGE_KM,)) -+else ifeq ($(BUILD),release) -+$(eval $(call BothConfigC,RELEASE,)) -+$(eval $(call TunableBothConfigMake,DEBUGLINK,1)) -+else ifeq ($(BUILD),timing) -+$(eval $(call BothConfigC,TIMING,)) -+$(eval $(call TunableBothConfigMake,DEBUGLINK,1)) -+else -+$(error BUILD= must be either debug, release or timing) -+endif -+ -+# User-configurable options -+# -+$(eval $(call TunableBothConfigC,SUPPORT_PERCONTEXT_PB,1)) -+$(eval $(call TunableBothConfigC,SUPPORT_SHARED_PB,)) -+$(eval $(call TunableBothConfigC,SUPPORT_HYBRID_PB,)) -+$(eval $(call TunableBothConfigC,SUPPORT_HW_RECOVERY,1)) -+$(eval $(call TunableBothConfigC,SUPPORT_ACTIVE_POWER_MANAGEMENT,1)) -+$(eval $(call TunableBothConfigC,SUPPORT_SGX_HWPERF,1)) -+$(eval $(call TunableBothConfigC,SUPPORT_SGX_LOW_LATENCY_SCHEDULING,1)) -+$(eval $(call TunableBothConfigC,SUPPORT_MEMINFO_IDS,)) -+$(eval $(call TunableBothConfigC,SUPPORT_SGX_NEW_STATUS_VALS,1)) -+$(eval $(call TunableBothConfigC,SUPPORT_PDUMP_MULTI_PROCESS,)) -+$(eval $(call TunableBothConfigC,SUPPORT_DBGDRV_EVENT_OBJECTS,1)) -+$(eval $(call TunableBothConfigC,SGX_FEATURE_SYSTEM_CACHE,)) -+$(eval $(call TunableBothConfigC,SGX_BYPASS_SYSTEM_CACHE,)) -+$(eval $(call TunableBothConfigC,SGX_BYPASS_DCU,)) -+$(eval $(call TunableBothConfigC,SGX_FAST_DPM_INIT,)) -+$(eval $(call TunableBothConfigC,SGX_FEATURE_MP,)) -+$(eval $(call TunableBothConfigC,SGX_FEATURE_MP_PLUS,)) -+$(eval $(call TunableBothConfigC,FPGA,)) -+$(eval $(call TunableBothConfigC,PDUMP,)) -+$(eval $(call TunableBothConfigC,NO_HARDWARE,)) -+$(eval $(call TunableBothConfigC,PDUMP_DEBUG_OUTFILES,)) -+$(eval $(call TunableBothConfigC,PVRSRV_USSE_EDM_STATUS_DEBUG,)) -+$(eval $(call TunableBothConfigC,PVRSRV_RESET_ON_HWTIMEOUT,)) -+$(eval $(call TunableBothConfigC,SYS_USING_INTERRUPTS,1)) -+$(eval $(call TunableBothConfigC,SUPPORT_EXTERNAL_SYSTEM_CACHE,)) -+$(eval $(call TunableBothConfigC,PVRSRV_NEW_PVR_DPF,)) -+$(eval $(call TunableBothConfigC,PVRSRV_NEED_PVR_DPF,)) -+$(eval $(call TunableBothConfigC,PVRSRV_NEED_PVR_ASSERT,)) -+$(eval $(call TunableBothConfigC,PVRSRV_NEED_PVR_TRACE,)) -+$(eval $(call TunableBothConfigC,SUPPORT_SECURE_33657_FIX,)) -+$(eval $(call TunableBothConfigC,SUPPORT_ION,)) -+$(eval $(call TunableBothConfigC,SUPPORT_HWRECOVERY_TRACE_LIMIT,)) -+$(eval $(call TunableBothConfigC,SUPPORT_PVRSRV_GET_DC_SYSTEM_BUFFER,1)) -+$(eval $(call TunableBothConfigC,SUPPORT_NV12_FROM_2_HWADDRS,)) -+$(eval $(call TunableBothConfigC,SGX_FEATURE_36BIT_MMU,)) -+$(eval $(call TunableBothConfigC,IMG_ADDRSPACE_PHYSADDR_BITS,)) -+ -+$(eval $(call TunableKernelConfigC,SUPPORT_LINUX_X86_WRITECOMBINE,1)) -+$(eval $(call TunableKernelConfigC,SUPPORT_LINUX_X86_PAT,1)) -+$(eval $(call TunableKernelConfigC,SGX_DYNAMIC_TIMING_INFO,)) -+$(eval $(call TunableKernelConfigC,SYS_SGX_ACTIVE_POWER_LATENCY_MS,)) -+$(eval $(call TunableKernelConfigC,SYS_CUSTOM_POWERLOCK_WRAP,)) -+$(eval $(call TunableKernelConfigC,SYS_SUPPORTS_SGX_IDLE_CALLBACK,)) -+$(eval $(call TunableKernelConfigC,PVR_LINUX_USING_WORKQUEUES,)) -+$(eval $(call TunableKernelConfigC,PVR_LINUX_MISR_USING_WORKQUEUE,)) -+$(eval $(call TunableKernelConfigC,PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE,)) -+$(eval $(call TunableKernelConfigC,PVR_LINUX_TIMERS_USING_WORKQUEUES,)) -+$(eval $(call TunableKernelConfigC,PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE,)) -+$(eval $(call TunableKernelConfigC,LDM_PLATFORM,)) -+$(eval $(call TunableKernelConfigC,PVR_LDM_PLATFORM_PRE_REGISTERED,)) -+$(eval $(call TunableKernelConfigC,PVR_LDM_PLATFORM_PRE_REGISTERED_DEV,)) -+$(eval $(call TunableKernelConfigC,PVR_LDM_DRIVER_REGISTRATION_NAME,"\"$(PVRSRV_MODNAME)\"")) -+$(eval $(call TunableKernelConfigC,LDM_PCI,)) -+$(eval $(call TunableKernelConfigC,PVRSRV_DUMP_MK_TRACE,)) -+$(eval $(call TunableKernelConfigC,PVRSRV_DUMP_KERNEL_CCB,)) -+$(eval $(call TunableKernelConfigC,PVRSRV_REFCOUNT_DEBUG,)) -+$(eval $(call TunableKernelConfigC,PVRSRV_MMU_MAKE_READWRITE_ON_DEMAND,)) -+$(eval $(call TunableKernelConfigC,HYBRID_SHARED_PB_SIZE,)) -+$(eval $(call TunableKernelConfigC,SUPPORT_LARGE_GENERAL_HEAP,)) -+$(eval $(call TunableKernelConfigC,TTRACE,)) -+ -+ -+$(eval $(call TunableBothConfigMake,SUPPORT_ION,)) -+ -+ -+$(eval $(call TunableBothConfigMake,OPTIM,)) -+ -+ -+$(eval $(call TunableKernelConfigMake,TTRACE,)) -+ -+endif # INTERNAL_CLOBBER_ONLY -+ -+export INTERNAL_CLOBBER_ONLY -+export TOP -+export OUT -+ -+MAKE_ETC := -Rr --no-print-directory -C $(TOP) TOP=$(TOP) OUT=$(OUT) \ -+ -f eurasiacon/build/linux2/toplevel.mk -+ -+# This must match the default value of MAKECMDGOALS below, and the default -+# goal in toplevel.mk -+.DEFAULT_GOAL := build -+ -+ifeq ($(MAKECMDGOALS),) -+MAKECMDGOALS := build -+else -+# We can't pass autogen to toplevel.mk -+MAKECMDGOALS := $(filter-out autogen,$(MAKECMDGOALS)) -+endif -+ -+.PHONY: autogen -+autogen: -+ifeq ($(INTERNAL_CLOBBER_ONLY),) -+ @$(MAKE) -s --no-print-directory -C $(EURASIAROOT) \ -+ -f eurasiacon/build/linux2/prepare_tree.mk \ -+ LDM_PCI=$(LDM_PCI) LDM_PLATFORM=$(LDM_PLATFORM) -+else -+ @: -+endif -+ -+# This deletes built-in suffix rules. Otherwise the submake isn't run when -+# saying e.g. "make thingy.a" -+.SUFFIXES: -+ -+# Because we have a match-anything rule below, we'll run the main build when -+# we're actually trying to remake various makefiles after they're read in. -+# These rules try to prevent that -+%.mk: ; -+Makefile%: ; -+Makefile: ; -+ -+.PHONY: build kbuild install -+build kbuild install: autogen -+ @$(if $(MAKECMDGOALS),$(MAKE) $(MAKE_ETC) $(MAKECMDGOALS) $(eval MAKECMDGOALS :=),:) -+ -+%: autogen -+ @$(if $(MAKECMDGOALS),$(MAKE) $(MAKE_ETC) $(MAKECMDGOALS) $(eval MAKECMDGOALS :=),:) -diff --git a/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/defs.mk b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/defs.mk -new file mode 100644 -index 0000000..84602d9 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/defs.mk -@@ -0,0 +1,144 @@ -+########################################################################### ### -+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+#@License Dual MIT/GPLv2 -+# -+# The contents of this file are subject to the MIT license as set out below. -+# -+# Permission is hereby granted, free of charge, to any person obtaining a copy -+# of this software and associated documentation files (the "Software"), to deal -+# in the Software without restriction, including without limitation the rights -+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+# copies of the Software, and to permit persons to whom the Software is -+# furnished to do so, subject to the following conditions: -+# -+# The above copyright notice and this permission notice shall be included in -+# all copies or substantial portions of the Software. -+# -+# Alternatively, the contents of this file may be used under the terms of -+# the GNU General Public License Version 2 ("GPL") in which case the provisions -+# of GPL are applicable instead of those above. -+# -+# If you wish to allow use of your version of this file only under the terms of -+# GPL, and not to allow others to use your version of this file under the terms -+# of the MIT license, indicate your decision by deleting the provisions above -+# and replace them with the notice and other provisions required by GPL as set -+# out in the file called "GPL-COPYING" included in this distribution. If you do -+# not delete the provisions above, a recipient may use your version of this file -+# under the terms of either the MIT license or GPL. -+# -+# This License is also included in this distribution in the file called -+# "MIT-COPYING". -+# -+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+### ########################################################################### -+ -+define must-be-defined -+$(if $(filter undefined,$(origin $(1))),$(error In makefile $(THIS_MAKEFILE): $$($(1)) must be defined),) -+endef -+ -+define must-be-nonempty -+$(if $(strip $($(1))),,$(error In makefile $(THIS_MAKEFILE): $$($(1)) must contain a value)) -+endef -+ -+define directory-must-exist -+$(if $(wildcard $(abspath $(1)/)),,$(error Directory $(1) must exist)) -+endef -+ -+define one-word-only -+$(if $(filter-out $(firstword $($(1))),$($(1))),$(error In makefile $(THIS_MAKEFILE): $$($(1)) must contain only one word),) -+endef -+ -+define target-intermediates-of -+$(addprefix $(TARGET_OUT)/intermediates/$(1)/,$(2)) -+endef -+ -+define host-intermediates-of -+$(addprefix $(HOST_OUT)/intermediates/$(1)/,$(2)) -+endef -+ -+define module-library -+$(patsubst lib%.so,%,$(if $($(1)_target),$($(1)_target),$(1).so)) -+endef -+ -+# This is done to allow module type makefiles to use $(THIS_MAKEFILE) -+define register-module -+INTERNAL_MAKEFILE_FOR_MODULE_$(1) := $(THIS_MAKEFILE) -+endef -+ -+define process-module -+THIS_MODULE := $(1) -+THIS_MAKEFILE := $(INTERNAL_MAKEFILE_FOR_MODULE_$(1)) -+include $$(MAKE_TOP)/this_makefile.mk -+$$(call must-be-nonempty,THIS_MAKEFILE) -+$$(call must-be-nonempty,$(1)_type) -+MODULE_HOST_BUILD := $$(if $(filter host_%,$($(1)_type)),true,) -+include $$(MAKE_TOP)/moduledefs.mk -+include $$(MAKE_TOP)/$$(patsubst host_%,%,$($(1)_type)).mk -+INTERNAL_TARGETS_FOR_$(THIS_MODULE) := $(MODULE_TARGETS) -+endef -+ -+# This can be used by module_type.mk files to indicate that they can't be -+# built as host_module_type -+define target-build-only -+$(if $(filter true,$(MODULE_HOST_BUILD)),$(error In makefile $(THIS_MAKEFILE): Module $(THIS_MODULE) attempted to build a host $(1), which is not supported)) -+endef -+ -+define relative-to-top -+$(patsubst $(TOP)/%,%,$(1)) -+endef -+ -+define cc-check -+$(shell \ -+ CC_CHECK=$(patsubst @%,%,$(CC_CHECK)) && \ -+ $(patsubst @%,%,$(CHMOD)) +x $$CC_CHECK && \ -+ $$CC_CHECK --cc "$(1)" --out "$(2)" $(3)) -+endef -+ -+define cc-is-64bit -+$(call cc-check,$(1),$(OUT),--64) -+endef -+ -+define cc-option -+$(call cc-check,$(patsubst @%,%,$(CC)),$(OUT),$(1)) -+endef -+ -+define cxx-option -+$(call cc-check,$(patsubst @%,%,$(CXX)),$(OUT),$(1)) -+endef -+ -+define host-cc-option -+$(call cc-check,$(patsubst @%,%,$(HOST_CC)),$(OUT),$(1)) -+endef -+ -+define host-cxx-option -+$(call cc-check,$(patsubst @%,%,$(HOST_CXX)),$(OUT),$(1)) -+endef -+ -+define kernel-cc-option -+$(call cc-check,$(KERNEL_CROSS_COMPILE)gcc,$(OUT),$(1)) -+endef -+ -+# Turn a particular warning on, or explicitly turn it off, depending on -+# the value of W. The "-W" or "-Wno-" part of the warning need not be -+# specified. -+define cc-optional-warning -+$(call cc-option,-W$(if $(W),,no-)$(patsubst -W%,%,$(patsubst -Wno-%,%,$(1)))) -+endef -+ -+define host-cc-optional-warning -+$(call host-cc-option,-W$(if $(W),,no-)$(patsubst -W%,%,$(patsubst -Wno-%,%,$(1)))) -+endef -+ -+define kernel-cc-optional-warning -+$(call kernel-cc-option,-W$(if $(W),,no-)$(patsubst -W%,%,$(patsubst -Wno-%,%,$(1)))) -+endef -+ -+define module-info-line -+$(if $(filter modules,$(D)),$(info $(1)),) -+endef -diff --git a/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/kbuild/Makefile.template b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/kbuild/Makefile.template -new file mode 100644 -index 0000000..d1cc8fc ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/kbuild/Makefile.template -@@ -0,0 +1,92 @@ -+########################################################################### ### -+#@Title Root kernel makefile -+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+#@License Dual MIT/GPLv2 -+# -+# The contents of this file are subject to the MIT license as set out below. -+# -+# Permission is hereby granted, free of charge, to any person obtaining a copy -+# of this software and associated documentation files (the "Software"), to deal -+# in the Software without restriction, including without limitation the rights -+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+# copies of the Software, and to permit persons to whom the Software is -+# furnished to do so, subject to the following conditions: -+# -+# The above copyright notice and this permission notice shall be included in -+# all copies or substantial portions of the Software. -+# -+# Alternatively, the contents of this file may be used under the terms of -+# the GNU General Public License Version 2 ("GPL") in which case the provisions -+# of GPL are applicable instead of those above. -+# -+# If you wish to allow use of your version of this file only under the terms of -+# GPL, and not to allow others to use your version of this file under the terms -+# of the MIT license, indicate your decision by deleting the provisions above -+# and replace them with the notice and other provisions required by GPL as set -+# out in the file called "GPL-COPYING" included in this distribution. If you do -+# not delete the provisions above, a recipient may use your version of this file -+# under the terms of either the MIT license or GPL. -+# -+# This License is also included in this distribution in the file called -+# "MIT-COPYING". -+# -+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+### ########################################################################### -+ -+# This top-level kbuild makefile builds all the Linux kernel modules in the -+# DDK. To run kbuild, this makefile is copied to $(TARGET_OUT)/kbuild/Makefile -+# and make is invoked in $(TARGET_OUT)/kbuild. -+ -+# This makefile doesn't define any kbuild special variables apart from -+# ccflags-y and obj-m. The variables for objects are picked up by including -+# the kbuild makefile fragments named in $(INTERNAL_KBUILD_MAKEFILES). The -+# list of objects that these fragments make is collected in -+# $(INTERNAL_KBUILD_OBJECTS) and $(INTERNAL_EXTRA_KBUILD_OBJECTS). These -+# variables are set according to the build's $(KERNEL_COMPONENTS) and -+# $(EXTRA_PVRSRVKM_COMPONENTS). To add a new kernel module to the build, edit -+# these variables in the per-build Makefile. -+ -+include $(OUT)/config_kernel.mk -+ -+.SECONDARY: -+ -+$(OUT)/target/kbuild/external/%.c: $(EXTRA_KBUILD_SOURCE)/%.c -+ @if [ ! -e $(dir $@) ]; then mkdir -p $(dir $@); fi -+ @if [ ! -h $@ ]; then ln -sf $< $@; fi -+ -+$(OUT)/target/kbuild/%.c: $(TOP)/%.c -+ @if [ ! -e $(dir $@) ]; then mkdir -p $(dir $@); fi -+ @if [ ! -h $@ ]; then ln -sf $< $@; fi -+ -+ccflags-y += -D__linux__ -include $(OUT)/config_kernel.h \ -+ -DDEBUG_LOG_PATH_TRUNCATE="\"$(OUT)/target/kbuild\"" \ -+ -I$(OUT)/include \ -+ -I$(TOP)/include4 \ -+ -I$(TOP)/services4/include \ -+ -I$(TOP)/services4/system/$(PVR_SYSTEM) \ -+ -I$(TOP)/services4/system/include \ -+ -I$(TOP)/services4/srvkm/bridged \ -+ -I$(TOP)/services4/srvkm/bridged/sgx \ -+ -I$(TOP)/services4/srvkm/common \ -+ -I$(TOP)/services4/srvkm/devices/sgx \ -+ -I$(TOP)/services4/srvkm/env/linux \ -+ -I$(TOP)/services4/srvkm/include -+ -+ifeq ($(PVR_LOCAL_HWDEFS),) -+ccflags-y += -I$(TOP)/services4/srvkm/hwdefs -+else -+ccflags-y += -I$(TOP)/hwdefs -+endif -+ -+include $(INTERNAL_KBUILD_MAKEFILES) -+ -+$(if $(pvrsrvkm-y),,$(error pvrsrvkm-y was empty, which could mean that srvkm is missing from $$(KERNEL_COMPONENTS))) -+pvrsrvkm-y += $(foreach _m,$(INTERNAL_EXTRA_KBUILD_OBJECTS:.o=),$($(_m)-y)) -+ -+obj-m += $(INTERNAL_KBUILD_OBJECTS) -diff --git a/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/kbuild/external_tarball.mk b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/kbuild/external_tarball.mk -new file mode 100644 -index 0000000..766f6b9 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/kbuild/external_tarball.mk -@@ -0,0 +1,49 @@ -+########################################################################### ### -+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+#@License Dual MIT/GPLv2 -+# -+# The contents of this file are subject to the MIT license as set out below. -+# -+# Permission is hereby granted, free of charge, to any person obtaining a copy -+# of this software and associated documentation files (the "Software"), to deal -+# in the Software without restriction, including without limitation the rights -+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+# copies of the Software, and to permit persons to whom the Software is -+# furnished to do so, subject to the following conditions: -+# -+# The above copyright notice and this permission notice shall be included in -+# all copies or substantial portions of the Software. -+# -+# Alternatively, the contents of this file may be used under the terms of -+# the GNU General Public License Version 2 ("GPL") in which case the provisions -+# of GPL are applicable instead of those above. -+# -+# If you wish to allow use of your version of this file only under the terms of -+# GPL, and not to allow others to use your version of this file under the terms -+# of the MIT license, indicate your decision by deleting the provisions above -+# and replace them with the notice and other provisions required by GPL as set -+# out in the file called "GPL-COPYING" included in this distribution. If you do -+# not delete the provisions above, a recipient may use your version of this file -+# under the terms of either the MIT license or GPL. -+# -+# This License is also included in this distribution in the file called -+# "MIT-COPYING". -+# -+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+### ########################################################################### -+ -+ifneq ($(EXTERNAL_3PDD_TARBALL),) -+TAR_OPT_STRIP_COMPONENTS ?= --strip-components -+prepare_tree: $(OUT)/target/kbuild/external -+$(OUT)/target/kbuild/external: eurasiacon/external/$(EXTERNAL_3PDD_TARBALL) -+ @echo "Extracting $<.." -+ @mkdir -p $@ -+ @tar $(TAR_OPT_STRIP_COMPONENTS) 1 --touch -jxf $< -C $@ -+ @touch $(OUT)/target/kbuild/external -+endif -diff --git a/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/kbuild/kbuild.mk b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/kbuild/kbuild.mk -new file mode 100644 -index 0000000..34526c0 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/kbuild/kbuild.mk -@@ -0,0 +1,91 @@ -+########################################################################### ### -+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+#@License Dual MIT/GPLv2 -+# -+# The contents of this file are subject to the MIT license as set out below. -+# -+# Permission is hereby granted, free of charge, to any person obtaining a copy -+# of this software and associated documentation files (the "Software"), to deal -+# in the Software without restriction, including without limitation the rights -+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+# copies of the Software, and to permit persons to whom the Software is -+# furnished to do so, subject to the following conditions: -+# -+# The above copyright notice and this permission notice shall be included in -+# all copies or substantial portions of the Software. -+# -+# Alternatively, the contents of this file may be used under the terms of -+# the GNU General Public License Version 2 ("GPL") in which case the provisions -+# of GPL are applicable instead of those above. -+# -+# If you wish to allow use of your version of this file only under the terms of -+# GPL, and not to allow others to use your version of this file under the terms -+# of the MIT license, indicate your decision by deleting the provisions above -+# and replace them with the notice and other provisions required by GPL as set -+# out in the file called "GPL-COPYING" included in this distribution. If you do -+# not delete the provisions above, a recipient may use your version of this file -+# under the terms of either the MIT license or GPL. -+# -+# This License is also included in this distribution in the file called -+# "MIT-COPYING". -+# -+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+### ########################################################################### -+ -+$(if $(strip $(KERNELDIR)),,$(error KERNELDIR must be set)) -+$(call directory-must-exist,$(KERNELDIR)) -+ -+$(TARGET_OUT)/kbuild/Makefile: $(MAKE_TOP)/kbuild/Makefile.template -+ @[ ! -e $(dir $@) ] && mkdir -p $(dir $@) || true -+ $(CP) -f $< $@ -+ -+# We need to make INTERNAL_KBUILD_MAKEFILES absolute because the files will be -+# read while chdir'd into $(KERNELDIR) -+INTERNAL_KBUILD_MAKEFILES := $(abspath $(foreach _m,$(KERNEL_COMPONENTS) $(EXTRA_PVRSRVKM_COMPONENTS),$(if $(INTERNAL_KBUILD_MAKEFILE_FOR_$(_m)),$(INTERNAL_KBUILD_MAKEFILE_FOR_$(_m)),$(error Unknown kbuild module "$(_m)")))) -+INTERNAL_KBUILD_OBJECTS := $(foreach _m,$(KERNEL_COMPONENTS),$(if $(INTERNAL_KBUILD_OBJECTS_FOR_$(_m)),$(INTERNAL_KBUILD_OBJECTS_FOR_$(_m)),$(error BUG: Unknown kbuild module "$(_m)" should have been caught earlier))) -+INTERNAL_EXTRA_KBUILD_OBJECTS := $(foreach _m,$(EXTRA_PVRSRVKM_COMPONENTS),$(if $(INTERNAL_KBUILD_OBJECTS_FOR_$(_m)),$(INTERNAL_KBUILD_OBJECTS_FOR_$(_m)),$(error BUG: Unknown kbuild module "$(_m)" should have been caught earlier))) -+.PHONY: kbuild kbuild_clean -+ -+kbuild: $(TARGET_OUT)/kbuild/Makefile -+ @$(MAKE) -Rr --no-print-directory -C $(KERNELDIR) M=$(abspath $(TARGET_OUT)/kbuild) \ -+ INTERNAL_KBUILD_MAKEFILES="$(INTERNAL_KBUILD_MAKEFILES)" \ -+ INTERNAL_KBUILD_OBJECTS="$(INTERNAL_KBUILD_OBJECTS)" \ -+ INTERNAL_EXTRA_KBUILD_OBJECTS="$(INTERNAL_EXTRA_KBUILD_OBJECTS)" \ -+ EXTRA_KBUILD_SOURCE="$(EXTRA_KBUILD_SOURCE)" \ -+ CROSS_COMPILE="$(KERNEL_CROSS_COMPILE)" \ -+ EXTRA_CFLAGS="$(ALL_KBUILD_CFLAGS)" \ -+ V=$(V) W=$(W) \ -+ TOP=$(TOP) -+ @for kernel_module in $(addprefix $(TARGET_OUT)/kbuild/,$(INTERNAL_KBUILD_OBJECTS:.o=.ko)); do \ -+ cp $$kernel_module $(TARGET_OUT); \ -+ done -+ -+kbuild_clean: $(TARGET_OUT)/kbuild/Makefile -+ @$(MAKE) -Rr --no-print-directory -C $(KERNELDIR) M=$(abspath $(TARGET_OUT)/kbuild) \ -+ INTERNAL_KBUILD_MAKEFILES="$(INTERNAL_KBUILD_MAKEFILES)" \ -+ INTERNAL_KBUILD_OBJECTS="$(INTERNAL_KBUILD_OBJECTS)" \ -+ INTERNAL_EXTRA_KBUILD_OBJECTS="$(INTERNAL_EXTRA_KBUILD_OBJECTS)" \ -+ EXTRA_KBUILD_SOURCE="$(EXTRA_KBUILD_SOURCE)" \ -+ CROSS_COMPILE="$(KERNEL_CROSS_COMPILE)" \ -+ EXTRA_CFLAGS="$(ALL_KBUILD_CFLAGS)" \ -+ V=$(V) W=$(W) \ -+ TOP=$(TOP) clean -+ -+kbuild_install: $(TARGET_OUT)/kbuild/Makefile -+ @: $(if $(strip $(DISCIMAGE)),,$(error $$(DISCIMAGE) was empty or unset while trying to use it to set INSTALL_MOD_PATH for modules_install)) -+ @$(MAKE) -Rr --no-print-directory -C $(KERNELDIR) M=$(abspath $(TARGET_OUT)/kbuild) \ -+ INTERNAL_KBUILD_MAKEFILES="$(INTERNAL_KBUILD_MAKEFILES)" \ -+ INTERNAL_KBUILD_OBJECTS="$(INTERNAL_KBUILD_OBJECTS)" \ -+ INTERNAL_EXTRA_KBUILD_OBJECTS="$(INTERNAL_EXTRA_KBUILD_OBJECTS)" \ -+ EXTRA_KBUILD_SOURCE="$(EXTRA_KBUILD_SOURCE)" \ -+ CROSS_COMPILE="$(KERNEL_CROSS_COMPILE)" \ -+ EXTRA_CFLAGS="$(ALL_KBUILD_CFLAGS)" \ -+ INSTALL_MOD_PATH="$(DISCIMAGE)" \ -+ V=$(V) W=$(W) \ -+ TOP=$(TOP) modules_install -diff --git a/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/kernel_module.mk b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/kernel_module.mk -new file mode 100644 -index 0000000..a9c2207 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/kernel_module.mk -@@ -0,0 +1,75 @@ -+########################################################################### ### -+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+#@License Dual MIT/GPLv2 -+# -+# The contents of this file are subject to the MIT license as set out below. -+# -+# Permission is hereby granted, free of charge, to any person obtaining a copy -+# of this software and associated documentation files (the "Software"), to deal -+# in the Software without restriction, including without limitation the rights -+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+# copies of the Software, and to permit persons to whom the Software is -+# furnished to do so, subject to the following conditions: -+# -+# The above copyright notice and this permission notice shall be included in -+# all copies or substantial portions of the Software. -+# -+# Alternatively, the contents of this file may be used under the terms of -+# the GNU General Public License Version 2 ("GPL") in which case the provisions -+# of GPL are applicable instead of those above. -+# -+# If you wish to allow use of your version of this file only under the terms of -+# GPL, and not to allow others to use your version of this file under the terms -+# of the MIT license, indicate your decision by deleting the provisions above -+# and replace them with the notice and other provisions required by GPL as set -+# out in the file called "GPL-COPYING" included in this distribution. If you do -+# not delete the provisions above, a recipient may use your version of this file -+# under the terms of either the MIT license or GPL. -+# -+# This License is also included in this distribution in the file called -+# "MIT-COPYING". -+# -+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+### ########################################################################### -+ -+# Rules for making kernel modules with kbuild. This makefile doesn't define -+# any rules that build the modules, it only copies the kbuild Makefile into -+# the right place and then invokes kbuild to do the actual build -+ -+$(call target-build-only,kernel module) -+ -+MODULE_KBUILD_DIR := $(MODULE_OUT)/kbuild -+ -+# $(THIS_MODULE)_makefile names the kbuild makefile fragment used to build -+# this module's objects -+$(call must-be-nonempty,$(THIS_MODULE)_makefile) -+MODULE_KBUILD_MAKEFILE := $($(THIS_MODULE)_makefile) -+$(if $(wildcard $(abspath $(MODULE_KBUILD_MAKEFILE))),,$(error In makefile $(THIS_MAKEFILE): Module $(THIS_MODULE) requires kbuild makefile $(MODULE_KBUILD_MAKEFILE), which is missing)) -+ -+# $(THIS_MODULE)_target specifies the name of the kernel module -+$(call must-be-nonempty,$(THIS_MODULE)_target) -+MODULE_KBUILD_OBJECTS := $($(THIS_MODULE)_target:.ko=.o) -+ -+# Here we could maybe include $(MODULE_KBUILD_MAKEFILE) and look at -+# $(MODULE_KBUILD_OBJECTS)-y to see which source files might be built -+ -+.PHONY: $(THIS_MODULE) -+$(THIS_MODULE): MODULE_KBUILD_MAKEFILE := $(MODULE_KBUILD_MAKEFILE) -+$(THIS_MODULE): MODULE_KBUILD_OBJECTS := $(MODULE_KBUILD_OBJECTS) -+$(THIS_MODULE): -+ @echo "kbuild module '$@'" -+ @echo " MODULE_KBUILD_MAKEFILE := $(MODULE_KBUILD_MAKEFILE)" -+ @echo " MODULE_KBUILD_OBJECTS := $(MODULE_KBUILD_OBJECTS)" -+ @echo ' Being built:' $(if $(filter $@,$(KERNEL_COMPONENTS)),"yes (separate module)",$(if $(filter $@,$(EXTRA_PVRSRVKM_COMPONENTS)),"yes (into pvrsrvkm)","no")) -+ @echo "Module $@ is a kbuild module. Run 'make kbuild' to make it" -+ @false -+ -+ALL_KBUILD_MODULES += $(THIS_MODULE) -+INTERNAL_KBUILD_MAKEFILE_FOR_$(THIS_MODULE) := $(MODULE_KBUILD_MAKEFILE) -+INTERNAL_KBUILD_OBJECTS_FOR_$(THIS_MODULE) := $(MODULE_KBUILD_OBJECTS) -diff --git a/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/kernel_version.mk b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/kernel_version.mk -new file mode 100644 -index 0000000..c269794 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/kernel_version.mk -@@ -0,0 +1,100 @@ -+########################################################################### ### -+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+#@License Dual MIT/GPLv2 -+# -+# The contents of this file are subject to the MIT license as set out below. -+# -+# Permission is hereby granted, free of charge, to any person obtaining a copy -+# of this software and associated documentation files (the "Software"), to deal -+# in the Software without restriction, including without limitation the rights -+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+# copies of the Software, and to permit persons to whom the Software is -+# furnished to do so, subject to the following conditions: -+# -+# The above copyright notice and this permission notice shall be included in -+# all copies or substantial portions of the Software. -+# -+# Alternatively, the contents of this file may be used under the terms of -+# the GNU General Public License Version 2 ("GPL") in which case the provisions -+# of GPL are applicable instead of those above. -+# -+# If you wish to allow use of your version of this file only under the terms of -+# GPL, and not to allow others to use your version of this file under the terms -+# of the MIT license, indicate your decision by deleting the provisions above -+# and replace them with the notice and other provisions required by GPL as set -+# out in the file called "GPL-COPYING" included in this distribution. If you do -+# not delete the provisions above, a recipient may use your version of this file -+# under the terms of either the MIT license or GPL. -+# -+# This License is also included in this distribution in the file called -+# "MIT-COPYING". -+# -+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+### ########################################################################### -+ -+$(if $(KERNELDIR),,$(error KERNELDIR must be set to obtain a version)) -+ -+override KERNEL_VERSION := \ -+ $(shell grep "^VERSION = " $(KERNELDIR)/Makefile | cut -f3 -d' ') -+override KERNEL_PATCHLEVEL := \ -+ $(shell grep "^PATCHLEVEL = " $(KERNELDIR)/Makefile | cut -f3 -d' ') -+override KERNEL_SUBLEVEL := \ -+ $(shell grep "^SUBLEVEL = " $(KERNELDIR)/Makefile | cut -f3 -d' ') -+override KERNEL_EXTRAVERSION := \ -+ $(shell grep "^EXTRAVERSION = " $(KERNELDIR)/Makefile | cut -f3 -d' ') -+ -+# Break the kernel version up into a space separated list -+kernel_version_as_list := $(KERNEL_VERSION) \ -+ $(KERNEL_PATCHLEVEL) \ -+ $(KERNEL_SUBLEVEL) \ -+ $(patsubst .%,%,$(KERNEL_EXTRAVERSION)) -+ -+# The base ID doesn't have to be accurate; we only use it for -+# feature checks which will not care about extraversion bits -+# -+override KERNEL_BASE_ID := \ -+ $(KERNEL_VERSION).$(KERNEL_PATCHLEVEL).$(KERNEL_SUBLEVEL) -+ -+# Try to get the kernel ID from the kernel.release file. -+# -+KERNEL_ID ?= \ -+ $(shell cat $(KERNELDIR)/include/config/kernel.release 2>/dev/null) -+ -+# If the kernel ID isn't set yet, try to set it from the UTS_RELEASE -+# macro. -+# -+ifeq ($(strip $(KERNEL_ID)),) -+KERNEL_ID := \ -+ $(shell grep -h '\#define UTS_RELEASE' \ -+ $(KERNELDIR)/include/linux/* | cut -f3 -d' ' | sed s/\"//g) -+endif -+ -+ifeq ($(strip $(KERNEL_ID)),) -+KERNEL_ID := \ -+ $(KERNEL_VERSION).$(KERNEL_PATCHLEVEL).$(KERNEL_SUBLEVEL)$(KERNEL_EXTRAVERSION) -+endif -+ -+# Return 1 if the kernel version is at least the value passed to the -+# function, else return nothing. -+# Examples -+# $(call kernel-version-at-least,2,6,35) -+# $(call kernel-version-at-least,2,6,35,7) -+# -+define kernel-version-at-least -+$(shell set -- $(kernel_version_as_list) 0 0 0 0; \ -+ Y=true; \ -+ for D in $1 $2 $3 $4; \ -+ do \ -+ [ $$1 ] || break; \ -+ [ $$1 -eq $$D ] && { shift; continue; };\ -+ [ $$1 -lt $$D ] && Y=; \ -+ break; \ -+ done; \ -+ echo $$Y) -+endef -diff --git a/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/moduledefs.mk b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/moduledefs.mk -new file mode 100644 -index 0000000..29a3886 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/moduledefs.mk -@@ -0,0 +1,100 @@ -+########################################################################### ### -+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+#@License Dual MIT/GPLv2 -+# -+# The contents of this file are subject to the MIT license as set out below. -+# -+# Permission is hereby granted, free of charge, to any person obtaining a copy -+# of this software and associated documentation files (the "Software"), to deal -+# in the Software without restriction, including without limitation the rights -+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+# copies of the Software, and to permit persons to whom the Software is -+# furnished to do so, subject to the following conditions: -+# -+# The above copyright notice and this permission notice shall be included in -+# all copies or substantial portions of the Software. -+# -+# Alternatively, the contents of this file may be used under the terms of -+# the GNU General Public License Version 2 ("GPL") in which case the provisions -+# of GPL are applicable instead of those above. -+# -+# If you wish to allow use of your version of this file only under the terms of -+# GPL, and not to allow others to use your version of this file under the terms -+# of the MIT license, indicate your decision by deleting the provisions above -+# and replace them with the notice and other provisions required by GPL as set -+# out in the file called "GPL-COPYING" included in this distribution. If you do -+# not delete the provisions above, a recipient may use your version of this file -+# under the terms of either the MIT license or GPL. -+# -+# This License is also included in this distribution in the file called -+# "MIT-COPYING". -+# -+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+### ########################################################################### -+ -+MODULE_TARGETS := -+MODULE_CFLAGS := $(ALL_CFLAGS) $($(THIS_MODULE)_cflags) -+MODULE_CXXFLAGS := $(ALL_CXXFLAGS) $($(THIS_MODULE)_cxxflags) -+MODULE_HOST_CFLAGS := $(ALL_HOST_CFLAGS) $($(THIS_MODULE)_cflags) -+MODULE_HOST_CXXFLAGS := $(ALL_HOST_CXXFLAGS) $($(THIS_MODULE)_cxxflags) -+MODULE_LDFLAGS := $(ALL_LDFLAGS) $($(THIS_MODULE)_ldflags) -+MODULE_HOST_LDFLAGS := $(ALL_HOST_LDFLAGS) $($(THIS_MODULE)_ldflags) -+MODULE_BISON_FLAGS := $(ALL_BISON_FLAGS) $($(THIS_MODULE)_bisonflags) -+MODULE_FLEX_FLAGS := $(ALL_FLEX_FLAGS) $($(THIS_MODULE)_flexflags) -+ -+# -L flags for library search dirs -+MODULE_LIBRARY_DIR_FLAGS := $(foreach _path,$($(THIS_MODULE)_libpaths),$(if $(filter /%,$(_path)),-L$(call relative-to-top,$(_path)),-L$(_path))) -+# -I flags for header search dirs -+MODULE_INCLUDE_FLAGS := $(foreach _path,$($(THIS_MODULE)_includes),$(if $(filter /%,$(_path)),-I$(call relative-to-top,$(_path)),-I$(_path))) -+ -+# Variables used to differentiate between host/target builds -+MODULE_OUT := $(if $(MODULE_HOST_BUILD),$(HOST_OUT),$(TARGET_OUT)) -+MODULE_INTERMEDIATES_DIR := $(if $(MODULE_HOST_BUILD),$(HOST_INTERMEDIATES)/$(THIS_MODULE),$(TARGET_INTERMEDIATES)/$(THIS_MODULE)) -+ -+.SECONDARY: $(MODULE_INTERMEDIATES_DIR) -+$(MODULE_INTERMEDIATES_DIR): -+ $(make-directory) -+ -+# These are used for messages and variable names where we need to say "host" -+# or "target" according to the module build type. -+Host_or_target := $(if $(MODULE_HOST_BUILD),Host,Target) -+host_or_target := $(if $(MODULE_HOST_BUILD),host,target) -+HOST_OR_TARGET := $(if $(MODULE_HOST_BUILD),HOST,TARGET) -+ -+# These define the rules for finding source files. -+# - If a name begins with a slash, we strip $(TOP) off the front if it begins -+# with $(TOP). This is so that we don't get really long error messages from -+# the compiler if the source tree is in a deeply nested directory, but we -+# still do get absolute paths if you say "make OUT=/tmp/somewhere" -+# - Otherwise, if a name contains a slash and begins with $(OUT), we leave it -+# as it is. This is so you can say "module_src := -+# $(TARGET_INTERMEDIATES)/something/generated.c" -+# - Otherwise, we assume it's a path referring to somewhere under the -+# directory containing Linux.mk, and add $(THIS_DIR) to it -+_SOURCES_WITHOUT_SLASH := $(strip $(foreach _s,$($(THIS_MODULE)_src),$(if $(findstring /,$(_s)),,$(_s)))) -+_SOURCES_WITH_SLASH := $(strip $(foreach _s,$($(THIS_MODULE)_src),$(if $(findstring /,$(_s)),$(_s),))) -+MODULE_SOURCES := $(addprefix $(THIS_DIR)/,$(_SOURCES_WITHOUT_SLASH)) -+MODULE_SOURCES += $(call relative-to-top,$(filter /%,$(_SOURCES_WITH_SLASH))) -+_RELATIVE_SOURCES_WITH_SLASH := $(filter-out /%,$(_SOURCES_WITH_SLASH)) -+_OUTDIR_RELATIVE_SOURCES_WITH_SLASH := $(filter $(RELATIVE_OUT)/%,$(_RELATIVE_SOURCES_WITH_SLASH)) -+_THISDIR_RELATIVE_SOURCES_WITH_SLASH := $(filter-out $(RELATIVE_OUT)/%,$(_RELATIVE_SOURCES_WITH_SLASH)) -+MODULE_SOURCES += $(_OUTDIR_RELATIVE_SOURCES_WITH_SLASH) -+MODULE_SOURCES += $(addprefix $(THIS_DIR)/,$(_THISDIR_RELATIVE_SOURCES_WITH_SLASH)) -+MODULE_SOURCES += $(addprefix $(MODULE_OUT)/intermediates/,$($(THIS_MODULE)_gensrc)) -+MODULE_GENERATED_HEADERS := $(addprefix $(MODULE_OUT)/intermediates/,$($(THIS_MODULE)_genheaders)) -+ -+# -l flags for each library -+MODULE_LIBRARY_FLAGS := $(addprefix -l, $($(THIS_MODULE)_staticlibs)) $(addprefix -l,$($(THIS_MODULE)_libs)) $(foreach _lib,$($(THIS_MODULE)_extlibs),$(if $(filter undefined,$(origin lib$(_lib)_ldflags)),-l$(_lib),$(lib$(_lib)_ldflags))) -+ -+# pkg-config integration; primarily used by X.org -+# FIXME: We don't support arbitrary CFLAGS yet (just includes) -+$(foreach _package,$($(THIS_MODULE)_packages),\ -+ $(eval MODULE_INCLUDE_FLAGS += `pkg-config --cflags-only-I $(_package)`)\ -+ $(eval MODULE_LIBRARY_FLAGS += `pkg-config --libs-only-l $(_package)`)\ -+ $(eval MODULE_LIBRARY_DIR_FLAGS += `pkg-config --libs-only-L $(_package)`)) -diff --git a/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/modules.mk b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/modules.mk -new file mode 100644 -index 0000000..7ad5a0b ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/modules.mk -@@ -0,0 +1,49 @@ -+########################################################################### ### -+#@Title Module processing -+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+#@License Dual MIT/GPLv2 -+# -+# The contents of this file are subject to the MIT license as set out below. -+# -+# Permission is hereby granted, free of charge, to any person obtaining a copy -+# of this software and associated documentation files (the "Software"), to deal -+# in the Software without restriction, including without limitation the rights -+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+# copies of the Software, and to permit persons to whom the Software is -+# furnished to do so, subject to the following conditions: -+# -+# The above copyright notice and this permission notice shall be included in -+# all copies or substantial portions of the Software. -+# -+# Alternatively, the contents of this file may be used under the terms of -+# the GNU General Public License Version 2 ("GPL") in which case the provisions -+# of GPL are applicable instead of those above. -+# -+# If you wish to allow use of your version of this file only under the terms of -+# GPL, and not to allow others to use your version of this file under the terms -+# of the MIT license, indicate your decision by deleting the provisions above -+# and replace them with the notice and other provisions required by GPL as set -+# out in the file called "GPL-COPYING" included in this distribution. If you do -+# not delete the provisions above, a recipient may use your version of this file -+# under the terms of either the MIT license or GPL. -+# -+# This License is also included in this distribution in the file called -+# "MIT-COPYING". -+# -+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+### ########################################################################### -+ -+# Bits for processing $(modules) after reading in each Linux.mk -+ -+#$(info ---- $(modules) ----) -+$(call must-be-nonempty,modules) -+ -+$(foreach _m,$(modules),$(if $(filter $(_m),$(ALL_MODULES)),$(error In makefile $(THIS_MAKEFILE): Duplicate module $(_m) (first seen in $(INTERNAL_MAKEFILE_FOR_MODULE_$(_m))) listed in $$(modules)),$(eval $(call register-module,$(_m))))) -+ -+ALL_MODULES += $(modules) -diff --git a/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/omap4430_linux/Makefile b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/omap4430_linux/Makefile -new file mode 100644 -index 0000000..e37821d ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/omap4430_linux/Makefile -@@ -0,0 +1,187 @@ -+########################################################################### ### -+#@Title Root makefile for OMAP4430 Linux. Builds everything else. -+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+#@License Dual MIT/GPLv2 -+# -+# The contents of this file are subject to the MIT license as set out below. -+# -+# Permission is hereby granted, free of charge, to any person obtaining a copy -+# of this software and associated documentation files (the "Software"), to deal -+# in the Software without restriction, including without limitation the rights -+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+# copies of the Software, and to permit persons to whom the Software is -+# furnished to do so, subject to the following conditions: -+# -+# The above copyright notice and this permission notice shall be included in -+# all copies or substantial portions of the Software. -+# -+# Alternatively, the contents of this file may be used under the terms of -+# the GNU General Public License Version 2 ("GPL") in which case the provisions -+# of GPL are applicable instead of those above. -+# -+# If you wish to allow use of your version of this file only under the terms of -+# GPL, and not to allow others to use your version of this file under the terms -+# of the MIT license, indicate your decision by deleting the provisions above -+# and replace them with the notice and other provisions required by GPL as set -+# out in the file called "GPL-COPYING" included in this distribution. If you do -+# not delete the provisions above, a recipient may use your version of this file -+# under the terms of either the MIT license or GPL. -+# -+# This License is also included in this distribution in the file called -+# "MIT-COPYING". -+# -+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+### ########################################################################### -+ -+PVR_SYSTEM := omap4 -+ -+KERNEL_COMPONENTS := srvkm bufferclass_example -+ -+include ../kernel_version.mk -+ -+# Only enable active power management if passive power management is -+# enabled, as indicated by LDM_PLATFORM being set to 1. On OMAP, -+# the system can suspend in the case where active power management is -+# enabled in the SGX driver, but passive power management isn't. As -+# passive power management isn't enabled, the driver won't see the -+# system suspend/resume events, and so won't take appropriate action. -+LDM_PLATFORM ?= 1 -+ -+ifeq ($(LDM_PLATFORM),1) -+SUPPORT_LINUX_USING_WORKQUEUES := 1 -+DISPLAY_CONTROLLER_COMPONENT += dc_omapfb3_linux -+DISPLAY_CONTROLLER := omaplfb -+else -+SUPPORT_LINUX_USING_SHARED_WORKQUEUES := 1 -+OMAP_NON_FLIP_DISPLAY := 1 -+DISPLAY_CONTROLLER_COMPONENT += linux_framebuffer -+DISPLAY_CONTROLLER := pvrlfb -+endif -+ -+OPTIM := -Os -+ -+SYS_CFLAGS := -march=armv7-a -+ -+ifneq ($(CROSS_COMPILE),) -+SYS_CFLAGS += -mtls-dialect=arm -+endif -+ -+SUPPORT_OMAP4430_NEON ?= 1 -+ -+ifeq ($(SUPPORT_OMAP4430_NEON),1) -+SYS_CFLAGS += -ftree-vectorize -mfpu=neon -mfloat-abi=softfp -+endif -+ -+LIBGCC := $(shell $(CROSS_COMPILE)gcc -print-libgcc-file-name) -+ -+SGXCORE := 540 -+SGX_CORE_REV := 120 -+ -+SGX_DYNAMIC_TIMING_INFO := 1 -+SYS_CUSTOM_POWERLOCK_WRAP := 1 -+ -+ifeq ($(OMAP_NON_FLIP_DISPLAY),1) -+OPK_DEFAULT := libpvrPVR2D_BLITWSEGL.so -+else -+OPK_DEFAULT := libpvrPVR2D_FLIPWSEGL.so -+endif -+ -+ifeq ($(call kernel-version-at-least,2,6,35),true) -+# Work around flipping problems seen with the Taal LCDs on Blaze. -+# The work around is safe to use with other types of screen on Blaze -+# (e.g. HDMI) and on other platforms (e.g. Panda board). -+PVR_OMAPLFB_DONT_USE_FB_PAN_DISPLAY := 1 -+ifeq ($(LDM_PLATFORM),1) -+PVR_LDM_PLATFORM_PRE_REGISTERED := 1 -+ifeq ($(call kernel-version-at-least,2,6,35,7),true) -+# Not all variants of the OMAP4 kernel have a DRM based framebuffer. -+# Note that a non-X.Org version of the driver does not have to be built -+# with DRM support if the kernel has a DRM based framebuffer. -+PVR_OMAPLFB_DRM_FB ?= 1 -+ifeq ($(PVR_OMAPLFB_DRM_FB),1) -+PVR_LDM_PLATFORM_PRE_REGISTERED_DEV := "\"pvrsrvkm_pvr\"" -+# There is already a "pvrsrvkm" driver (part of the DRM framebuffer code), -+# so use the pre-registered device name instead. -+PVR_LDM_DRIVER_REGISTRATION_NAME := "\"pvrsrvkm_pvr"\" -+# The DRM library will not load the Services module on behalf of the X Server, -+# as a DRM module has already been loaded (the DRM based framebuffer), so -+# load the Services module before starting the X Server. -+XORG_EXPLICIT_PVR_SERVICES_LOAD := 1 -+else -+PVR_LDM_PLATFORM_PRE_REGISTERED_DEV := "\"pvrsrvkm\"" -+endif -+endif -+endif -+endif -+ -+include ../common/xorg_test.mk -+ifeq ($(want_xorg),1) -+ -+SUPPORT_DRI_DRM := 1 -+ -+ifeq ($(call kernel-version-at-least,2,6,35),true) -+PVR_DRI_DRM_PLATFORM_DEV := 1 -+PVR_DRI_DRM_STATIC_BUS_ID := 1 -+ifeq ($(call kernel-version-at-least,2,6,35,7),true) -+ifeq ($(PVR_OMAPLFB_DRM_FB),1) -+SUPPORT_DRI_DRM_PLUGIN := 1 -+endif -+ifeq ($(call kernel-version-at-least,2,6,36),true) -+PVR_DRI_DRM_DEV_BUS_ID := "\"platform:pvrsrvkm"\" -+else -+PVR_DRI_DRM_DEV_BUS_ID := "\"platform:pvrsrvkm:00"\" -+endif -+# A client DRI authorisation failure, whilst switched away from the X Server -+# VT, prevents all other attempts at DRI authorisation, even after -+# switching back to the X server VT, so don't perform a DRM drop master -+# call. -+PVR_XORG_DONT_DROP_MASTER_IN_LEAVE_VT := 1 -+endif -+else -+PVR_DRI_DRM_NOT_PCI := 1 -+endif -+ -+XORG_TOOLCHAIN ?= tarballs-omap4-ubuntu-10.10-cross -+XORG_PVR_CONF := omap4 -+XORG_PVR_VIDEO := omap4 -+ -+OPK_FALLBACK := libpvrPVR2D_DRIWSEGL.so -+ -+ifneq ($(OMAP_NON_FLIP_DISPLAY),1) -+XORG_PVR_VIDEO ?= $(PVR_SYSTEM) -+PVR_DISPLAY_CONTROLLER_DRM_IOCTL := 1 -+endif -+ -+else # xorg isn't excluded -+ -+OPK_FALLBACK := libpvrPVR2D_BLITWSEGL.so -+ -+endif # xorg isn't excluded -+ -+ifeq ($(SUPPORT_DRI_DRM),1) -+ifeq ($(PVR_DRI_DRM_NOT_PCI),1) -+KERNEL_COMPONENTS += linux_drm -+EXTRA_KBUILD_SOURCE := $(KERNELDIR) -+endif -+EXTRA_PVRSRVKM_COMPONENTS += $(DISPLAY_CONTROLLER_COMPONENT) -+else -+KERNEL_COMPONENTS += $(DISPLAY_CONTROLLER_COMPONENT) -+endif -+ -+include ../config/core.mk -+include ../common/xorg.mk -+include ../common/dridrm.mk -+include ../common/opencl.mk -+include ../common/omap4.mk -+ -+# We only need this for pvr_video's includes, which should -+# really be done differently, as DISPLAY_CONTROLLER_DIR is -+# now obsolete.. -+# -+$(eval $(call UserConfigMake,DISPLAY_CONTROLLER_DIR,3rdparty/$(DISPLAY_CONTROLLER_COMPONENT))) -diff --git a/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/omap_linux/Makefile b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/omap_linux/Makefile -new file mode 100644 -index 0000000..614346a ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/omap_linux/Makefile -@@ -0,0 +1,234 @@ -+########################################################################### ### -+#@Title Root makefile for OMAP4430 Linux. Builds everything else. -+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+#@License Dual MIT/GPLv2 -+# -+# The contents of this file are subject to the MIT license as set out below. -+# -+# Permission is hereby granted, free of charge, to any person obtaining a copy -+# of this software and associated documentation files (the "Software"), to deal -+# in the Software without restriction, including without limitation the rights -+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+# copies of the Software, and to permit persons to whom the Software is -+# furnished to do so, subject to the following conditions: -+# -+# The above copyright notice and this permission notice shall be included in -+# all copies or substantial portions of the Software. -+# -+# Alternatively, the contents of this file may be used under the terms of -+# the GNU General Public License Version 2 ("GPL") in which case the provisions -+# of GPL are applicable instead of those above. -+# -+# If you wish to allow use of your version of this file only under the terms of -+# GPL, and not to allow others to use your version of this file under the terms -+# of the MIT license, indicate your decision by deleting the provisions above -+# and replace them with the notice and other provisions required by GPL as set -+# out in the file called "GPL-COPYING" included in this distribution. If you do -+# not delete the provisions above, a recipient may use your version of this file -+# under the terms of either the MIT license or GPL. -+# -+# This License is also included in this distribution in the file called -+# "MIT-COPYING". -+# -+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+### ########################################################################### -+ -+# If a product wasn't specified, we're an OMAP4430 blaze. -+# -+TARGET_PRODUCT ?= blaze -+ -+# Customize this build as per the TARGET_PRODUCT setting -+# -+ifneq ($(filter blaze blaze_tablet panda,$(TARGET_PRODUCT)),) -+SGXCORE := 540 -+SGX_CORE_REV := 120 -+XORG_TOOLCHAIN ?= tarballs-omap4-ubuntu-10.10-cross -+endif -+ifneq ($(filter blaze.4470 blaze_tablet.4470,$(TARGET_PRODUCT)),) -+SGXCORE := 544 -+SGX_CORE_REV := 112 -+endif -+ifneq ($(filter omap5sevm panda5,$(TARGET_PRODUCT)),) -+SGXCORE := 544 -+SGX_CORE_REV := 105 -+SGX_FEATURE_MP := 1 -+SGX_FEATURE_SYSTEM_CACHE := 1 -+SGX_FEATURE_MP_CORE_COUNT := 2 -+PVR_OMAPLFB_DRM_FB := 0 -+ -+# FIXME: Re-enable this ASAP -+SUPPORT_ACTIVE_POWER_MANAGEMENT := 0 -+endif -+ -+PVR_SYSTEM := omap -+ -+KERNEL_COMPONENTS := srvkm bufferclass_example -+ -+include ../kernel_version.mk -+ -+# Only enable active power management if passive power management is -+# enabled, as indicated by LDM_PLATFORM being set to 1. On OMAP, -+# the system can suspend in the case where active power management is -+# enabled in the SGX driver, but passive power management isn't. As -+# passive power management isn't enabled, the driver won't see the -+# system suspend/resume events, and so won't take appropriate action. -+LDM_PLATFORM ?= 1 -+ -+ifeq ($(LDM_PLATFORM),1) -+SUPPORT_LINUX_USING_WORKQUEUES := 1 -+DISPLAY_CONTROLLER_COMPONENT += dc_omapfb3_linux -+DISPLAY_CONTROLLER := omaplfb -+else -+SUPPORT_LINUX_USING_SHARED_WORKQUEUES := 1 -+OMAP_NON_FLIP_DISPLAY := 1 -+DISPLAY_CONTROLLER_COMPONENT += linux_framebuffer -+DISPLAY_CONTROLLER := pvrlfb -+endif -+ -+SYS_CFLAGS := -march=armv7-a -+ -+# Ubuntu ARM compilers need an explicit -marm option to build native ARM code, -+# rather than ARM thumb code. -+UBUNTU_TOOLCHAIN := -+ifeq ($(CROSS_COMPILE),) -+UBUNTU_TOOLCHAIN = 1 -+endif -+ifeq ($(CROSS_COMPILE),arm-linux-gnueabi-) -+UBUNTU_TOOLCHAIN = 1 -+endif -+ifeq ($(CROSS_COMPILE),arm-linux-gnueabihf-) -+UBUNTU_TOOLCHAIN = 1 -+endif -+ -+ifneq ($(UBUNTU_TOOLCHAIN),) -+SYS_CFLAGS += -marm -+else -+OPTIM := -Os -+ -+ifneq ($(CROSS_COMPILE),) -+SYS_CFLAGS += -mtls-dialect=arm -+endif -+ -+SUPPORT_OMAP4430_NEON ?= 1 -+ -+ifeq ($(SUPPORT_OMAP4430_NEON),1) -+SYS_CFLAGS += -ftree-vectorize -mfpu=neon -mfloat-abi=softfp -+endif -+endif # UBUNTU_TOOLCHAIN -+ -+LIBGCC := $(shell $(CROSS_COMPILE)gcc -print-libgcc-file-name) -+ -+SGX_DYNAMIC_TIMING_INFO := 1 -+SYS_CUSTOM_POWERLOCK_WRAP := 1 -+ -+ifeq ($(OMAP_NON_FLIP_DISPLAY),1) -+OPK_DEFAULT := libpvrPVR2D_BLITWSEGL.so -+else -+OPK_DEFAULT := libpvrPVR2D_FLIPWSEGL.so -+endif -+ -+ifeq ($(call kernel-version-at-least,2,6,35),true) -+# Work around flipping problems seen with the Taal LCDs on Blaze. -+# The work around is safe to use with other types of screen on Blaze -+# (e.g. HDMI) and on other platforms (e.g. Panda board). -+PVR_OMAPLFB_DONT_USE_FB_PAN_DISPLAY := 1 -+ifeq ($(LDM_PLATFORM),1) -+PVR_LDM_PLATFORM_PRE_REGISTERED := 1 -+ifeq ($(call kernel-version-at-least,2,6,35,7),true) -+# Not all variants of the OMAP4 kernel have a DRM based framebuffer. -+# Note that a non-X.Org version of the driver does not have to be built -+# with DRM support if the kernel has a DRM based framebuffer. -+PVR_OMAPLFB_DRM_FB ?= 1 -+ifeq ($(PVR_OMAPLFB_DRM_FB),1) -+PVR_LDM_PLATFORM_PRE_REGISTERED_DEV := "\"pvrsrvkm_pvr\"" -+# There is already a "pvrsrvkm" driver (part of the DRM framebuffer code), -+# so use the pre-registered device name instead. -+PVR_LDM_DRIVER_REGISTRATION_NAME := "\"pvrsrvkm_pvr"\" -+# The DRM library will not load the Services module on behalf of the X Server, -+# as a DRM module has already been loaded (the DRM based framebuffer), so -+# load the Services module before starting the X Server. -+XORG_EXPLICIT_PVR_SERVICES_LOAD := 1 -+else -+PVR_LDM_PLATFORM_PRE_REGISTERED_DEV := "\"pvrsrvkm\"" -+endif -+endif -+endif -+endif -+ -+include ../common/xorg_test.mk -+ifeq ($(want_xorg),1) -+SUPPORT_DRI_DRM := 1 -+endif -+ -+ifeq ($(SUPPORT_DRI_DRM),1) -+ifeq ($(call kernel-version-at-least,2,6,35),true) -+PVR_DRI_DRM_PLATFORM_DEV := 1 -+PVR_DRI_DRM_STATIC_BUS_ID := 1 -+ifeq ($(call kernel-version-at-least,2,6,35,7),true) -+ifeq ($(PVR_OMAPLFB_DRM_FB),1) -+SUPPORT_DRI_DRM_PLUGIN := 1 -+endif -+ifeq ($(call kernel-version-at-least,2,6,36),true) -+PVR_DRI_DRM_DEV_BUS_ID := "\"platform:pvrsrvkm"\" -+else -+PVR_DRI_DRM_DEV_BUS_ID := "\"platform:pvrsrvkm:00"\" -+endif # kernel-version-at-least,2,6,36 -+endif # kernel-version-at-least,2,6,35,7 -+else # kernel-version-at-least,2,6,35 -+PVR_DRI_DRM_NOT_PCI := 1 -+endif # kernel-version-at-least,2,6,35 -+endif # SUPPORT_DRI_DRM -+ -+ifeq ($(want_xorg),1) -+ifeq ($(call kernel-version-at-least,2,6,35,7),true) -+# A client DRI authorisation failure, whilst switched away from the X Server -+# VT, prevents all other attempts at DRI authorisation, even after -+# switching back to the X server VT, so don't perform a DRM drop master -+# call. -+PVR_XORG_DONT_DROP_MASTER_IN_LEAVE_VT := 1 -+endif -+XORG_PVR_CONF := omap4 -+XORG_PVR_VIDEO := omap4 -+ -+OPK_FALLBACK := libpvrPVR2D_DRIWSEGL.so -+ -+ifneq ($(OMAP_NON_FLIP_DISPLAY),1) -+XORG_PVR_VIDEO ?= omap4 -+PVR_DISPLAY_CONTROLLER_DRM_IOCTL := 1 -+endif -+ -+else # xorg isn't excluded -+ -+OPK_FALLBACK := libpvrPVR2D_BLITWSEGL.so -+ -+endif # xorg isn't excluded -+ -+ifeq ($(SUPPORT_DRI_DRM),1) -+ifeq ($(PVR_DRI_DRM_NOT_PCI),1) -+KERNEL_COMPONENTS += linux_drm -+EXTRA_KBUILD_SOURCE := $(KERNELDIR) -+endif -+EXTRA_PVRSRVKM_COMPONENTS += $(DISPLAY_CONTROLLER_COMPONENT) -+else -+KERNEL_COMPONENTS += $(DISPLAY_CONTROLLER_COMPONENT) -+endif -+ -+FORCE_ENABLE_GROW_SHRINK ?= 1 -+ -+include ../config/core.mk -+include ../common/xorg.mk -+include ../common/dridrm.mk -+include ../common/opencl.mk -+include ../common/omap4.mk -+ -+# We only need this for pvr_video's includes, which should -+# really be done differently, as DISPLAY_CONTROLLER_DIR is -+# now obsolete.. -+# -+$(eval $(call UserConfigMake,DISPLAY_CONTROLLER_DIR,3rdparty/$(DISPLAY_CONTROLLER_COMPONENT))) -diff --git a/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/prepare_tree.mk b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/prepare_tree.mk -new file mode 100644 -index 0000000..6c2a573 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/prepare_tree.mk -@@ -0,0 +1,56 @@ -+########################################################################### ### -+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+#@License Dual MIT/GPLv2 -+# -+# The contents of this file are subject to the MIT license as set out below. -+# -+# Permission is hereby granted, free of charge, to any person obtaining a copy -+# of this software and associated documentation files (the "Software"), to deal -+# in the Software without restriction, including without limitation the rights -+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+# copies of the Software, and to permit persons to whom the Software is -+# furnished to do so, subject to the following conditions: -+# -+# The above copyright notice and this permission notice shall be included in -+# all copies or substantial portions of the Software. -+# -+# Alternatively, the contents of this file may be used under the terms of -+# the GNU General Public License Version 2 ("GPL") in which case the provisions -+# of GPL are applicable instead of those above. -+# -+# If you wish to allow use of your version of this file only under the terms of -+# GPL, and not to allow others to use your version of this file under the terms -+# of the MIT license, indicate your decision by deleting the provisions above -+# and replace them with the notice and other provisions required by GPL as set -+# out in the file called "GPL-COPYING" included in this distribution. If you do -+# not delete the provisions above, a recipient may use your version of this file -+# under the terms of either the MIT license or GPL. -+# -+# This License is also included in this distribution in the file called -+# "MIT-COPYING". -+# -+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+### ########################################################################### -+ -+.PHONY: prepare_tree -+ -+prepare_tree: -+ -+INTERNAL_INCLUDED_PREPARE_HEADERS := -+-include eurasiacon/build/linux2/prepare_headers.mk -+ifneq ($(INTERNAL_INCLUDED_PREPARE_HEADERS),true) -+missing_headers := $(strip $(shell test ! -e include4/pvrversion.h && echo true)) -+ifdef missing_headers -+$(info ) -+$(info ** include4/pvrversion.h is missing, and cannot be rebuilt.) -+$(info ** Cannot continue.) -+$(info ) -+$(error Missing headers) -+endif -+endif -diff --git a/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/this_makefile.mk b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/this_makefile.mk -new file mode 100644 -index 0000000..17abc71 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/this_makefile.mk -@@ -0,0 +1,68 @@ -+########################################################################### ### -+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+#@License Dual MIT/GPLv2 -+# -+# The contents of this file are subject to the MIT license as set out below. -+# -+# Permission is hereby granted, free of charge, to any person obtaining a copy -+# of this software and associated documentation files (the "Software"), to deal -+# in the Software without restriction, including without limitation the rights -+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+# copies of the Software, and to permit persons to whom the Software is -+# furnished to do so, subject to the following conditions: -+# -+# The above copyright notice and this permission notice shall be included in -+# all copies or substantial portions of the Software. -+# -+# Alternatively, the contents of this file may be used under the terms of -+# the GNU General Public License Version 2 ("GPL") in which case the provisions -+# of GPL are applicable instead of those above. -+# -+# If you wish to allow use of your version of this file only under the terms of -+# GPL, and not to allow others to use your version of this file under the terms -+# of the MIT license, indicate your decision by deleting the provisions above -+# and replace them with the notice and other provisions required by GPL as set -+# out in the file called "GPL-COPYING" included in this distribution. If you do -+# not delete the provisions above, a recipient may use your version of this file -+# under the terms of either the MIT license or GPL. -+# -+# This License is also included in this distribution in the file called -+# "MIT-COPYING". -+# -+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+### ########################################################################### -+ -+# Find out the path of the Linux.mk makefile currently being processed, and -+# set paths used by the build rules -+ -+# This magic is used so we can use this_makefile.mk twice: first when reading -+# in each Linux.mk, and then again when generating rules. There we set -+# $(THIS_MAKEFILE), and $(REMAINING_MAKEFILES) should be empty -+ifneq ($(strip $(REMAINING_MAKEFILES)),) -+ -+# Absolute path to the Linux.mk being processed -+THIS_MAKEFILE := $(firstword $(REMAINING_MAKEFILES)) -+ -+# The list of makefiles left to process -+REMAINING_MAKEFILES := $(wordlist 2,$(words $(REMAINING_MAKEFILES)),$(REMAINING_MAKEFILES)) -+ -+else -+ -+# When generating rules, we should have read in every Linux.mk -+$(if $(INTERNAL_INCLUDED_ALL_MAKEFILES),,$(error No makefiles left in $$(REMAINING_MAKEFILES), but $$(INTERNAL_INCLUDED_ALL_MAKEFILES) is not set)) -+ -+endif -+ -+# Path to the directory containing Linux.mk -+THIS_DIR := $(patsubst %/,%,$(dir $(THIS_MAKEFILE))) -+ifeq ($(strip $(THIS_DIR)),) -+$(error Empty $$(THIS_DIR) for makefile "$(THIS_MAKEFILE)") -+endif -+ -+modules := -diff --git a/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/tools/cc-check.sh b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/tools/cc-check.sh -new file mode 100644 -index 0000000..415ad94 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/tools/cc-check.sh -@@ -0,0 +1,99 @@ -+#!/bin/sh -+########################################################################### ### -+#@Title Test the nature of the C compiler. -+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+#@License Dual MIT/GPLv2 -+# -+# The contents of this file are subject to the MIT license as set out below. -+# -+# Permission is hereby granted, free of charge, to any person obtaining a copy -+# of this software and associated documentation files (the "Software"), to deal -+# in the Software without restriction, including without limitation the rights -+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+# copies of the Software, and to permit persons to whom the Software is -+# furnished to do so, subject to the following conditions: -+# -+# The above copyright notice and this permission notice shall be included in -+# all copies or substantial portions of the Software. -+# -+# Alternatively, the contents of this file may be used under the terms of -+# the GNU General Public License Version 2 ("GPL") in which case the provisions -+# of GPL are applicable instead of those above. -+# -+# If you wish to allow use of your version of this file only under the terms of -+# GPL, and not to allow others to use your version of this file under the terms -+# of the MIT license, indicate your decision by deleting the provisions above -+# and replace them with the notice and other provisions required by GPL as set -+# out in the file called "GPL-COPYING" included in this distribution. If you do -+# not delete the provisions above, a recipient may use your version of this file -+# under the terms of either the MIT license or GPL. -+# -+# This License is also included in this distribution in the file called -+# "MIT-COPYING". -+# -+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+### ########################################################################### -+ -+LANG=C -+export LANG -+ -+usage() { -+ echo "usage: $0 [--64] --cc CC --out OUT [cflag]" -+ exit 1 -+} -+ -+# NOTE: The program passed to the compiler is deliberately incorrect -+# (`return;' should be `return 0;') but we do this to emit a warning. -+# -+# Emitting a warning is necessary to get GCC to print out additional -+# warnings about any unsupported -Wno options, so we can handle these -+# as unsupported by the build. -+# -+do_cc() { -+ echo "int main(void){return;}" | $CC -W -Wall $3 -xc -c - -o $1 >$2 2>&1 -+} -+ -+while [ 1 ]; do -+ if [ "$1" = "--64" ]; then -+ BIT_CHECK=1 -+ elif [ "$1" = "--cc" ]; then -+ [ "x$2" = "x" ] && usage -+ CC="$2" && shift -+ elif [ "$1" = "--out" ]; then -+ [ "x$2" = "x" ] && usage -+ OUT="$2" && shift -+ elif [ "${1#--}" != "$1" ]; then -+ usage -+ else -+ break -+ fi -+ shift -+done -+ -+[ "x$CC" = "x" ] && usage -+[ "x$OUT" = "x" ] && usage -+ccof=$OUT/cc-sanity-check -+log=${ccof}.log -+ -+if [ "x$BIT_CHECK" = "x1" ]; then -+ do_cc $ccof $log "" -+ file $ccof | grep 64-bit >/dev/null 2>&1 -+ [ "$?" = "0" ] && echo true || echo false -+else -+ [ "x$1" = "x" ] && usage -+ do_cc $ccof $log $1 -+ if [ "$?" = "0" ]; then -+ # compile passed, but was the warning unrecognized? -+ grep -q "^cc1: warning: unrecognized command line option \"$1\"" $log -+ [ "$?" = "1" ] && echo $1 -+ fi -+fi -+ -+rm -f $ccof $log -+exit 0 -diff --git a/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/toplevel.mk b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/toplevel.mk -new file mode 100644 -index 0000000..e652477 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/eurasiacon/build/linux2/toplevel.mk -@@ -0,0 +1,230 @@ -+########################################################################### ### -+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+#@License Dual MIT/GPLv2 -+# -+# The contents of this file are subject to the MIT license as set out below. -+# -+# Permission is hereby granted, free of charge, to any person obtaining a copy -+# of this software and associated documentation files (the "Software"), to deal -+# in the Software without restriction, including without limitation the rights -+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+# copies of the Software, and to permit persons to whom the Software is -+# furnished to do so, subject to the following conditions: -+# -+# The above copyright notice and this permission notice shall be included in -+# all copies or substantial portions of the Software. -+# -+# Alternatively, the contents of this file may be used under the terms of -+# the GNU General Public License Version 2 ("GPL") in which case the provisions -+# of GPL are applicable instead of those above. -+# -+# If you wish to allow use of your version of this file only under the terms of -+# GPL, and not to allow others to use your version of this file under the terms -+# of the MIT license, indicate your decision by deleting the provisions above -+# and replace them with the notice and other provisions required by GPL as set -+# out in the file called "GPL-COPYING" included in this distribution. If you do -+# not delete the provisions above, a recipient may use your version of this file -+# under the terms of either the MIT license or GPL. -+# -+# This License is also included in this distribution in the file called -+# "MIT-COPYING". -+# -+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+### ########################################################################### -+ -+# Define the default goal. This masks a previous definition of the default -+# goal in Makefile.config, which must match this one -+.PHONY: build -+build: components kbuild -+ -+ifeq ($(OUT),) -+$(error "Must specify output directory with OUT=") -+endif -+ -+ifeq ($(TOP),) -+$(error "Must specify root of source tree with TOP=") -+endif -+$(call directory-must-exist,$(TOP)) -+ -+# Output directory for configuration, object code, -+# final programs/libraries, and install/rc scripts. -+# -+ -+# RELATIVE_OUT is relative only if it's under $(TOP) -+RELATIVE_OUT := $(patsubst $(TOP)/%,%,$(OUT)) -+HOST_OUT := $(RELATIVE_OUT)/host -+TARGET_OUT := $(RELATIVE_OUT)/target -+CONFIG_MK := $(RELATIVE_OUT)/config.mk -+CONFIG_H := $(RELATIVE_OUT)/config.h -+CONFIG_KERNEL_MK := $(RELATIVE_OUT)/config_kernel.mk -+CONFIG_KERNEL_H := $(RELATIVE_OUT)/config_kernel.h -+MAKE_TOP := eurasiacon/build/linux2 -+THIS_MAKEFILE := (top-level makefiles) -+ -+# Convert commas to spaces in $(D). This is so you can say "make -+# D=config-changes,freeze-config" and have $(filter config-changes,$(D)) -+# still work. -+comma := , -+empty := -+space := $(empty) $(empty) -+override D := $(subst $(comma),$(space),$(D)) -+ -+include $(MAKE_TOP)/defs.mk -+ -+ifneq ($(INTERNAL_CLOBBER_ONLY),true) -+# Create the out directory -+# -+$(shell mkdir -p $(OUT)) -+ -+# Provide rules to create $(HOST_OUT) and $(TARGET_OUT) -+.SECONDARY: $(HOST_OUT) $(TARGET_OUT) -+$(HOST_OUT) $(TARGET_OUT): -+ $(make-directory) -+ -+# If these generated files differ from any pre-existing ones, -+# replace them, causing affected parts of the driver to rebuild. -+# -+_want_config_diff := $(filter config-changes,$(D)) -+_freeze_config := $(strip $(filter freeze-config,$(D))) -+_updated_config_files := $(shell \ -+ $(if $(_want_config_diff),rm -f $(OUT)/config.diff;,) \ -+ for file in $(CONFIG_MK) $(CONFIG_H) \ -+ $(CONFIG_KERNEL_MK) $(CONFIG_KERNEL_H); do \ -+ diff -U 0 $$file $$file.new \ -+ >>$(if $(_want_config_diff),$(OUT)/config.diff,/dev/null) 2>/dev/null \ -+ && rm -f $$file.new \ -+ || echo $$file; \ -+ done) -+ -+ifneq ($(_want_config_diff),) -+# We send the diff to stderr so it isn't captured by $(shell) -+$(shell [ -s $(OUT)/config.diff ] && echo >&2 "Configuration changed in $(RELATIVE_OUT):" && cat >&2 $(OUT)/config.diff) -+endif -+ -+ifneq ($(_freeze_config),) -+$(if $(_updated_config_files),$(error Configuration change in $(RELATIVE_OUT) prevented by D=freeze-config),) -+endif -+ -+# Update the config, if changed -+$(foreach _f,$(_updated_config_files), \ -+ $(shell mv -f $(_f).new $(_f) >/dev/null 2>/dev/null)) -+ -+endif # INTERNAL_CLOBBER_ONLY -+ -+MAKEFLAGS := -Rr --no-print-directory -+ -+ifneq ($(INTERNAL_CLOBBER_ONLY),true) -+ -+# This is so you can say "find $(TOP) -name Linux.mk > /tmp/something; export -+# ALL_MAKEFILES=/tmp/something; make" and avoid having to run find. This is -+# handy if your source tree is mounted over NFS or something -+override ALL_MAKEFILES := $(call relative-to-top,$(if $(strip $(ALL_MAKEFILES)),$(shell cat $(ALL_MAKEFILES)),$(shell find $(TOP) -type f -name Linux.mk -print -o -type d -name '.*' -prune))) -+ifeq ($(strip $(ALL_MAKEFILES)),) -+$(info ** Unable to find any Linux.mk files under $$(TOP). This could mean that) -+$(info ** there are no makefiles, or that ALL_MAKEFILES is set in the environment) -+$(info ** and points to a nonexistent or empty file.) -+$(error No makefiles) -+endif -+ -+else # clobber-only -+ALL_MAKEFILES := -+endif -+ -+unexport ALL_MAKEFILES -+ -+REMAINING_MAKEFILES := $(ALL_MAKEFILES) -+ALL_MODULES := -+INTERNAL_INCLUDED_ALL_MAKEFILES := -+ -+ifneq ($(INTERNAL_CLOBBER_ONLY),true) -+# Please do not change the format of the following lines -+-include $(CONFIG_KERNEL_MK) -+# These files may not exist in GPL km source packages -+-include $(MAKE_TOP)/xorgconf.mk -+-include $(MAKE_TOP)/llvm.mk -+endif -+ -+include $(MAKE_TOP)/commands.mk -+include $(MAKE_TOP)/buildvars.mk -+ -+HOST_INTERMEDIATES := $(HOST_OUT)/intermediates -+TARGET_INTERMEDIATES := $(TARGET_OUT)/intermediates -+ -+# Include each Linux.mk, then include modules.mk to save some information -+# about each module -+include $(foreach _Linux.mk,$(ALL_MAKEFILES),$(MAKE_TOP)/this_makefile.mk $(_Linux.mk) $(MAKE_TOP)/modules.mk) -+ -+ifeq ($(strip $(REMAINING_MAKEFILES)),) -+INTERNAL_INCLUDED_ALL_MAKEFILES := true -+else -+$(error Impossible: $(words $(REMAINING_MAKEFILES)) makefiles were mysteriously ignored when reading $$(ALL_MAKEFILES)) -+endif -+ -+# At this point, all Linux.mks have been included. Now generate rules to build -+# each module: for each module in $(ALL_MODULES), set per-makefile variables -+$(foreach _m,$(ALL_MODULES),$(eval $(call process-module,$(_m)))) -+ -+.PHONY: kbuild install -+kbuild install: -+ -+ifneq ($(INTERNAL_CLOBBER_ONLY),true) -+-include $(MAKE_TOP)/scripts.mk -+-include $(MAKE_TOP)/kbuild/kbuild.mk -+else -+# We won't depend on 'build' here so that people can build subsets of -+# components and still have the install script attempt to install the -+# subset. -+install: -+ @if [ ! -d "$(DISCIMAGE)" ]; then \ -+ echo; \ -+ echo "** DISCIMAGE was not set or does not point to a valid directory."; \ -+ echo "** Cannot continue with install."; \ -+ echo; \ -+ exit 1; \ -+ fi -+ @if [ ! -f $(TARGET_OUT)/install.sh ]; then \ -+ echo; \ -+ echo "** install.sh not found in $(TARGET_OUT)."; \ -+ echo "** Cannot continue with install."; \ -+ echo; \ -+ exit 1; \ -+ fi -+ @cd $(TARGET_OUT) && ./install.sh -+endif -+ -+# You can say 'make all_modules' to attempt to make everything, or 'make -+# components' to only make the things which are listed (in the per-build -+# makefiles) as components of the build. -+.PHONY: all_modules components -+all_modules: $(ALL_MODULES) -+components: $(COMPONENTS) -+ -+# Cleaning -+.PHONY: clean clobber -+clean: MODULE_DIRS_TO_REMOVE := $(OUT)/host/intermediates $(OUT)/target/intermediates $(OUT)/target/kbuild -+clean: -+ $(clean-dirs) -+clobber: MODULE_DIRS_TO_REMOVE := $(OUT) -+clobber: -+ $(clean-dirs) -+ -+# Saying 'make clean-MODULE' removes the intermediates for MODULE. -+# clobber-MODULE deletes the output files as well -+clean-%: -+ $(if $(V),,@echo " RM " $(call relative-to-top,$(OUT)/host/intermediates/$* $(OUT)/target/intermediates/$*)) -+ $(RM) -rf $(OUT)/host/intermediates/$*/* $(OUT)/target/intermediates/$*/* -+clobber-%: -+ $(if $(V),,@echo " RM " $(call relative-to-top,$(OUT)/host/intermediates/$* $(OUT)/target/intermediates/$* $(INTERNAL_TARGETS_FOR_$*))) -+ $(RM) -rf $(OUT)/host/intermediates/$* $(OUT)/target/intermediates/$* $(INTERNAL_TARGETS_FOR_$*) -+ -+include $(MAKE_TOP)/bits.mk -+ -+# D=nobuild stops the build before any recipes are run. This line should -+# come at the end of this makefile. -+$(if $(filter nobuild,$(D)),$(error D=nobuild given),) -diff --git a/drivers/staging/ti-es8-sgx/include4/dbgdrvif.h b/drivers/staging/ti-es8-sgx/include4/dbgdrvif.h -new file mode 100644 -index 0000000..e735037 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/include4/dbgdrvif.h -@@ -0,0 +1,381 @@ -+/*************************************************************************/ /*! -+@Title Debug driver -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Debug Driver Interface -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#ifndef _DBGDRVIF_ -+#define _DBGDRVIF_ -+ -+ -+#if defined(__linux__) -+ -+#define FILE_DEVICE_UNKNOWN 0 -+#define METHOD_BUFFERED 0 -+#define FILE_ANY_ACCESS 0 -+ -+#define CTL_CODE( DeviceType, Function, Method, Access ) (Function) -+#define MAKEIOCTLINDEX(i) ((i) & 0xFFF) -+ -+#else -+ -+#include "ioctldef.h" -+ -+#endif -+ -+/***************************************************************************** -+ Stream mode stuff. -+*****************************************************************************/ -+#define DEBUG_CAPMODE_FRAMED 0x00000001UL -+#define DEBUG_CAPMODE_CONTINUOUS 0x00000002UL -+#define DEBUG_CAPMODE_HOTKEY 0x00000004UL -+ -+#define DEBUG_OUTMODE_STANDARDDBG 0x00000001UL -+#define DEBUG_OUTMODE_MONO 0x00000002UL -+#define DEBUG_OUTMODE_STREAMENABLE 0x00000004UL -+#define DEBUG_OUTMODE_ASYNC 0x00000008UL -+#define DEBUG_OUTMODE_SGXVGA 0x00000010UL -+ -+#define DEBUG_FLAGS_USE_NONPAGED_MEM 0x00000001UL -+#define DEBUG_FLAGS_NO_BUF_EXPANDSION 0x00000002UL -+#define DEBUG_FLAGS_ENABLESAMPLE 0x00000004UL -+#define DEBUG_FLAGS_READONLY 0x00000008UL -+#define DEBUG_FLAGS_WRITEONLY 0x00000010UL -+ -+#define DEBUG_FLAGS_TEXTSTREAM 0x80000000UL -+ -+/***************************************************************************** -+ Debug level control. Only bothered with the first 12 levels, I suspect you -+ get the idea... -+*****************************************************************************/ -+#define DEBUG_LEVEL_0 0x00000001UL -+#define DEBUG_LEVEL_1 0x00000003UL -+#define DEBUG_LEVEL_2 0x00000007UL -+#define DEBUG_LEVEL_3 0x0000000FUL -+#define DEBUG_LEVEL_4 0x0000001FUL -+#define DEBUG_LEVEL_5 0x0000003FUL -+#define DEBUG_LEVEL_6 0x0000007FUL -+#define DEBUG_LEVEL_7 0x000000FFUL -+#define DEBUG_LEVEL_8 0x000001FFUL -+#define DEBUG_LEVEL_9 0x000003FFUL -+#define DEBUG_LEVEL_10 0x000007FFUL -+#define DEBUG_LEVEL_11 0x00000FFFUL -+ -+#define DEBUG_LEVEL_SEL0 0x00000001UL -+#define DEBUG_LEVEL_SEL1 0x00000002UL -+#define DEBUG_LEVEL_SEL2 0x00000004UL -+#define DEBUG_LEVEL_SEL3 0x00000008UL -+#define DEBUG_LEVEL_SEL4 0x00000010UL -+#define DEBUG_LEVEL_SEL5 0x00000020UL -+#define DEBUG_LEVEL_SEL6 0x00000040UL -+#define DEBUG_LEVEL_SEL7 0x00000080UL -+#define DEBUG_LEVEL_SEL8 0x00000100UL -+#define DEBUG_LEVEL_SEL9 0x00000200UL -+#define DEBUG_LEVEL_SEL10 0x00000400UL -+#define DEBUG_LEVEL_SEL11 0x00000800UL -+ -+/***************************************************************************** -+ IOCTL values. -+*****************************************************************************/ -+#define DEBUG_SERVICE_IOCTL_BASE 0x800UL -+#define DEBUG_SERVICE_CREATESTREAM CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x01, METHOD_BUFFERED, FILE_ANY_ACCESS) -+#define DEBUG_SERVICE_DESTROYSTREAM CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x02, METHOD_BUFFERED, FILE_ANY_ACCESS) -+#define DEBUG_SERVICE_GETSTREAM CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x03, METHOD_BUFFERED, FILE_ANY_ACCESS) -+#define DEBUG_SERVICE_WRITESTRING CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x04, METHOD_BUFFERED, FILE_ANY_ACCESS) -+#define DEBUG_SERVICE_READSTRING CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x05, METHOD_BUFFERED, FILE_ANY_ACCESS) -+#define DEBUG_SERVICE_WRITE CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x06, METHOD_BUFFERED, FILE_ANY_ACCESS) -+#define DEBUG_SERVICE_READ CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x07, METHOD_BUFFERED, FILE_ANY_ACCESS) -+#define DEBUG_SERVICE_SETDEBUGMODE CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x08, METHOD_BUFFERED, FILE_ANY_ACCESS) -+#define DEBUG_SERVICE_SETDEBUGOUTMODE CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x09, METHOD_BUFFERED, FILE_ANY_ACCESS) -+#define DEBUG_SERVICE_SETDEBUGLEVEL CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x0A, METHOD_BUFFERED, FILE_ANY_ACCESS) -+#define DEBUG_SERVICE_SETFRAME CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x0B, METHOD_BUFFERED, FILE_ANY_ACCESS) -+#define DEBUG_SERVICE_GETFRAME CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x0C, METHOD_BUFFERED, FILE_ANY_ACCESS) -+#define DEBUG_SERVICE_OVERRIDEMODE CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x0D, METHOD_BUFFERED, FILE_ANY_ACCESS) -+#define DEBUG_SERVICE_DEFAULTMODE CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x0E, METHOD_BUFFERED, FILE_ANY_ACCESS) -+#define DEBUG_SERVICE_GETSERVICETABLE CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x0F, METHOD_BUFFERED, FILE_ANY_ACCESS) -+#define DEBUG_SERVICE_WRITE2 CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x10, METHOD_BUFFERED, FILE_ANY_ACCESS) -+#define DEBUG_SERVICE_WRITESTRINGCM CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x11, METHOD_BUFFERED, FILE_ANY_ACCESS) -+#define DEBUG_SERVICE_WRITECM CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x12, METHOD_BUFFERED, FILE_ANY_ACCESS) -+#define DEBUG_SERVICE_SETMARKER CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x13, METHOD_BUFFERED, FILE_ANY_ACCESS) -+#define DEBUG_SERVICE_GETMARKER CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x14, METHOD_BUFFERED, FILE_ANY_ACCESS) -+#define DEBUG_SERVICE_ISCAPTUREFRAME CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x15, METHOD_BUFFERED, FILE_ANY_ACCESS) -+#define DEBUG_SERVICE_WRITELF CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x16, METHOD_BUFFERED, FILE_ANY_ACCESS) -+#define DEBUG_SERVICE_READLF CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x17, METHOD_BUFFERED, FILE_ANY_ACCESS) -+#define DEBUG_SERVICE_WAITFOREVENT CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x18, METHOD_BUFFERED, FILE_ANY_ACCESS) -+#define DEBUG_SERVICE_SETCONNNOTIFY CTL_CODE(FILE_DEVICE_UNKNOWN, DEBUG_SERVICE_IOCTL_BASE + 0x19, METHOD_BUFFERED, FILE_ANY_ACCESS) -+ -+ -+typedef enum _DBG_EVENT_ -+{ -+ DBG_EVENT_STREAM_DATA = 1 -+} DBG_EVENT; -+ -+ -+/***************************************************************************** -+ In/Out Structures -+*****************************************************************************/ -+typedef struct _DBG_IN_CREATESTREAM_ -+{ -+ union -+ { -+ IMG_CHAR *pszName; -+ IMG_UINT64 ui64Name; -+ } u; -+ IMG_UINT32 ui32Pages; -+ IMG_UINT32 ui32CapMode; -+ IMG_UINT32 ui32OutMode; -+}DBG_IN_CREATESTREAM, *PDBG_IN_CREATESTREAM; -+ -+typedef struct _DBG_IN_FINDSTREAM_ -+{ -+ union -+ { -+ IMG_CHAR *pszName; -+ IMG_UINT64 ui64Name; -+ }u; -+ IMG_BOOL bResetStream; -+}DBG_IN_FINDSTREAM, *PDBG_IN_FINDSTREAM; -+ -+typedef struct _DBG_IN_WRITESTRING_ -+{ -+ union -+ { -+ IMG_CHAR *pszString; -+ IMG_UINT64 ui64String; -+ } u; -+ IMG_SID hStream; -+ IMG_UINT32 ui32Level; -+}DBG_IN_WRITESTRING, *PDBG_IN_WRITESTRING; -+ -+typedef struct _DBG_IN_READSTRING_ -+{ -+ union -+ { -+ IMG_CHAR *pszString; -+ IMG_UINT64 ui64String; -+ } u; -+ IMG_SID hStream; -+ IMG_UINT32 ui32StringLen; -+} DBG_IN_READSTRING, *PDBG_IN_READSTRING; -+ -+typedef struct _DBG_IN_SETDEBUGMODE_ -+{ -+ IMG_SID hStream; -+ IMG_UINT32 ui32Mode; -+ IMG_UINT32 ui32Start; -+ IMG_UINT32 ui32End; -+ IMG_UINT32 ui32SampleRate; -+} DBG_IN_SETDEBUGMODE, *PDBG_IN_SETDEBUGMODE; -+ -+typedef struct _DBG_IN_SETDEBUGOUTMODE_ -+{ -+ IMG_SID hStream; -+ IMG_UINT32 ui32Mode; -+} DBG_IN_SETDEBUGOUTMODE, *PDBG_IN_SETDEBUGOUTMODE; -+ -+typedef struct _DBG_IN_SETDEBUGLEVEL_ -+{ -+ IMG_SID hStream; -+ IMG_UINT32 ui32Level; -+} DBG_IN_SETDEBUGLEVEL, *PDBG_IN_SETDEBUGLEVEL; -+ -+typedef struct _DBG_IN_SETFRAME_ -+{ -+ IMG_SID hStream; -+ IMG_UINT32 ui32Frame; -+} DBG_IN_SETFRAME, *PDBG_IN_SETFRAME; -+ -+typedef struct _DBG_IN_WRITE_ -+{ -+ union -+ { -+ IMG_UINT8 *pui8InBuffer; -+ IMG_UINT64 ui64InBuffer; -+ } u; -+ IMG_SID hStream; -+ IMG_UINT32 ui32Level; -+ IMG_UINT32 ui32TransferSize; -+} DBG_IN_WRITE, *PDBG_IN_WRITE; -+ -+typedef struct _DBG_IN_READ_ -+{ -+ union -+ { -+ IMG_UINT8 *pui8OutBuffer; -+ IMG_UINT64 ui64OutBuffer; -+ } u; -+ IMG_SID hStream; -+ IMG_BOOL bReadInitBuffer; -+ IMG_UINT32 ui32OutBufferSize; -+} DBG_IN_READ, *PDBG_IN_READ; -+ -+typedef struct _DBG_IN_OVERRIDEMODE_ -+{ -+ IMG_SID hStream; -+ IMG_UINT32 ui32Mode; -+} DBG_IN_OVERRIDEMODE, *PDBG_IN_OVERRIDEMODE; -+ -+typedef struct _DBG_IN_ISCAPTUREFRAME_ -+{ -+ IMG_SID hStream; -+ IMG_BOOL bCheckPreviousFrame; -+} DBG_IN_ISCAPTUREFRAME, *PDBG_IN_ISCAPTUREFRAME; -+ -+typedef struct _DBG_IN_SETMARKER_ -+{ -+ IMG_SID hStream; -+ IMG_UINT32 ui32Marker; -+} DBG_IN_SETMARKER, *PDBG_IN_SETMARKER; -+ -+typedef struct _DBG_IN_WRITE_LF_ -+{ -+ union -+ { -+ IMG_UINT8 *pui8InBuffer; -+ IMG_UINT64 ui64InBuffer; -+ } u; -+ IMG_UINT32 ui32Flags; -+ IMG_SID hStream; -+ IMG_UINT32 ui32Level; -+ IMG_UINT32 ui32BufferSize; -+} DBG_IN_WRITE_LF, *PDBG_IN_WRITE_LF; -+ -+/* -+ Flags for above struct -+*/ -+#define WRITELF_FLAGS_RESETBUF 0x00000001UL -+ -+/* -+ Common control structure (don't duplicate control in main stream -+ and init phase stream). -+*/ -+typedef struct _DBG_STREAM_CONTROL_ -+{ -+ IMG_BOOL bInitPhaseComplete; /*!< init phase has finished */ -+ IMG_UINT32 ui32Flags; /*!< flags (see DEBUG_FLAGS above) */ -+ -+ IMG_UINT32 ui32CapMode; /*!< capturing mode framed/hot key */ -+ IMG_UINT32 ui32OutMode; /*!< output mode, e.g. files */ -+ IMG_UINT32 ui32DebugLevel; -+ IMG_UINT32 ui32DefaultMode; -+ IMG_UINT32 ui32Start; /*!< first capture frame */ -+ IMG_UINT32 ui32End; /*!< last frame */ -+ IMG_UINT32 ui32Current; /*!< current frame */ -+ IMG_UINT32 ui32SampleRate; /*!< capture frequency */ -+ IMG_UINT32 ui32Reserved; -+} DBG_STREAM_CONTROL, *PDBG_STREAM_CONTROL; -+/* -+ Per-buffer control structure. -+*/ -+typedef struct _DBG_STREAM_ -+{ -+ struct _DBG_STREAM_ *psNext; -+ struct _DBG_STREAM_ *psInitStream; -+ DBG_STREAM_CONTROL *psCtrl; -+ IMG_BOOL bCircularAllowed; -+ IMG_PVOID pvBase; -+ IMG_UINT32 ui32Size; -+ IMG_UINT32 ui32RPtr; -+ IMG_UINT32 ui32WPtr; -+ IMG_UINT32 ui32DataWritten; -+ IMG_UINT32 ui32Marker; /*!< marker for file splitting */ -+ IMG_UINT32 ui32InitPhaseWOff; /*!< snapshot offset for init phase end for follow-on pdump */ -+ IMG_CHAR szName[30]; /* Give this a size, some compilers don't like [] */ -+} DBG_STREAM,*PDBG_STREAM; -+ -+/* -+ * Allows dbgdrv to notify services when events happen, e.g. pdump.exe starts. -+ * (better than resetting psDevInfo->psKernelCCBInfo->ui32CCBDumpWOff = 0 -+ * in SGXGetClientInfoKM.) -+ */ -+typedef struct _DBGKM_CONNECT_NOTIFIER_ -+{ -+ IMG_VOID (IMG_CALLCONV *pfnConnectNotifier) (IMG_VOID); -+} DBGKM_CONNECT_NOTIFIER, *PDBGKM_CONNECT_NOTIFIER; -+ -+/***************************************************************************** -+ Kernel mode service table -+*****************************************************************************/ -+typedef struct _DBGKM_SERVICE_TABLE_ -+{ -+ IMG_UINT32 ui32Size; -+ IMG_VOID * (IMG_CALLCONV *pfnCreateStream) (IMG_CHAR * pszName,IMG_UINT32 ui32CapMode,IMG_UINT32 ui32OutMode,IMG_UINT32 ui32Flags,IMG_UINT32 ui32Pages); -+ IMG_VOID (IMG_CALLCONV *pfnDestroyStream) (PDBG_STREAM psStream); -+ IMG_VOID * (IMG_CALLCONV *pfnFindStream) (IMG_CHAR * pszName, IMG_BOOL bResetInitBuffer); -+ IMG_UINT32 (IMG_CALLCONV *pfnWriteString) (PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Level); -+ IMG_UINT32 (IMG_CALLCONV *pfnReadString) (PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Limit); -+ IMG_UINT32 (IMG_CALLCONV *pfnWriteBIN) (PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level); -+ IMG_UINT32 (IMG_CALLCONV *pfnReadBIN) (PDBG_STREAM psStream,IMG_BOOL bReadInitBuffer, IMG_UINT32 ui32OutBufferSize,IMG_UINT8 *pui8OutBuf); -+ IMG_VOID (IMG_CALLCONV *pfnSetCaptureMode) (PDBG_STREAM psStream,IMG_UINT32 ui32CapMode,IMG_UINT32 ui32Start,IMG_UINT32 ui32Stop,IMG_UINT32 ui32SampleRate); -+ IMG_VOID (IMG_CALLCONV *pfnSetOutputMode) (PDBG_STREAM psStream,IMG_UINT32 ui32OutMode); -+ IMG_VOID (IMG_CALLCONV *pfnSetDebugLevel) (PDBG_STREAM psStream,IMG_UINT32 ui32DebugLevel); -+ IMG_VOID (IMG_CALLCONV *pfnSetFrame) (PDBG_STREAM psStream,IMG_UINT32 ui32Frame); -+ IMG_UINT32 (IMG_CALLCONV *pfnGetFrame) (PDBG_STREAM psStream); -+ IMG_VOID (IMG_CALLCONV *pfnOverrideMode) (PDBG_STREAM psStream,IMG_UINT32 ui32Mode); -+ IMG_VOID (IMG_CALLCONV *pfnDefaultMode) (PDBG_STREAM psStream); -+ IMG_UINT32 (IMG_CALLCONV *pfnDBGDrivWrite2) (PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level); -+ IMG_UINT32 (IMG_CALLCONV *pfnWriteStringCM) (PDBG_STREAM psStream,IMG_CHAR * pszString,IMG_UINT32 ui32Level); -+ IMG_UINT32 (IMG_CALLCONV *pfnWriteBINCM) (PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level); -+ IMG_VOID (IMG_CALLCONV *pfnSetMarker) (PDBG_STREAM psStream,IMG_UINT32 ui32Marker); -+ IMG_UINT32 (IMG_CALLCONV *pfnGetMarker) (PDBG_STREAM psStream); -+ IMG_VOID (IMG_CALLCONV *pfnStartInitPhase) (PDBG_STREAM psStream); -+ IMG_VOID (IMG_CALLCONV *pfnStopInitPhase) (PDBG_STREAM psStream); -+ IMG_BOOL (IMG_CALLCONV *pfnIsCaptureFrame) (PDBG_STREAM psStream, IMG_BOOL bCheckPreviousFrame); -+ IMG_UINT32 (IMG_CALLCONV *pfnWriteLF) (PDBG_STREAM psStream, IMG_UINT8 *pui8InBuf, IMG_UINT32 ui32InBuffSize, IMG_UINT32 ui32Level, IMG_UINT32 ui32Flags); -+ IMG_UINT32 (IMG_CALLCONV *pfnReadLF) (PDBG_STREAM psStream, IMG_UINT32 ui32OutBuffSize, IMG_UINT8 *pui8OutBuf); -+ IMG_UINT32 (IMG_CALLCONV *pfnGetStreamOffset) (PDBG_STREAM psStream); -+ IMG_VOID (IMG_CALLCONV *pfnSetStreamOffset) (PDBG_STREAM psStream, IMG_UINT32 ui32StreamOffset); -+ IMG_BOOL (IMG_CALLCONV *pfnIsLastCaptureFrame) (PDBG_STREAM psStream); -+ IMG_VOID (IMG_CALLCONV *pfnWaitForEvent) (DBG_EVENT eEvent); -+ IMG_VOID (IMG_CALLCONV *pfnSetConnectNotifier) (DBGKM_CONNECT_NOTIFIER fn_notifier); -+ IMG_UINT32 (IMG_CALLCONV *pfnWritePersist) (PDBG_STREAM psStream,IMG_UINT8 *pui8InBuf,IMG_UINT32 ui32InBuffSize,IMG_UINT32 ui32Level); -+} DBGKM_SERVICE_TABLE, *PDBGKM_SERVICE_TABLE; -+ -+#if defined(__linux__) -+/***************************************************************************** -+ Function to export service table from debug driver to the PDUMP component. -+*****************************************************************************/ -+IMG_VOID DBGDrvGetServiceTable(DBGKM_SERVICE_TABLE **fn_table); -+#endif -+ -+ -+#endif -+/***************************************************************************** -+ End of file (DBGDRVIF.H) -+*****************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/include4/img_defs.h b/drivers/staging/ti-es8-sgx/include4/img_defs.h -new file mode 100644 -index 0000000..74fd8f3 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/include4/img_defs.h -@@ -0,0 +1,218 @@ -+/*************************************************************************/ /*! -+@Title Common header containing type definitions for portability -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Contains variable and structure definitions. Any platform -+ specific types should be defined in this file. -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+#if !defined (__IMG_DEFS_H__) -+#define __IMG_DEFS_H__ -+ -+#include "img_types.h" -+ -+typedef enum img_tag_TriStateSwitch -+{ -+ IMG_ON = 0x00, -+ IMG_OFF, -+ IMG_IGNORE -+ -+} img_TriStateSwitch, * img_pTriStateSwitch; -+ -+#define IMG_SUCCESS 0 -+ -+#define IMG_NO_REG 1 -+ -+#if defined (NO_INLINE_FUNCS) -+ #define INLINE -+ #define FORCE_INLINE -+#else -+#if defined (__cplusplus) -+ #define INLINE inline -+ #define FORCE_INLINE inline -+#else -+#if !defined(INLINE) -+ #define INLINE __inline -+#endif -+ #define FORCE_INLINE static __inline -+#endif -+#endif -+ -+ -+/* Use this in any file, or use attributes under GCC - see below */ -+#ifndef PVR_UNREFERENCED_PARAMETER -+#define PVR_UNREFERENCED_PARAMETER(param) (param) = (param) -+#endif -+ -+/* The best way to supress unused parameter warnings using GCC is to use a -+ * variable attribute. Place the unref__ between the type and name of an -+ * unused parameter in a function parameter list, eg `int unref__ var'. This -+ * should only be used in GCC build environments, for example, in files that -+ * compile only on Linux. Other files should use UNREFERENCED_PARAMETER */ -+#ifdef __GNUC__ -+#define unref__ __attribute__ ((unused)) -+#else -+#define unref__ -+#endif -+ -+/* -+ Wide character definitions -+*/ -+#ifndef _TCHAR_DEFINED -+#if defined(UNICODE) -+typedef unsigned short TCHAR, *PTCHAR, *PTSTR; -+#else /* #if defined(UNICODE) */ -+typedef char TCHAR, *PTCHAR, *PTSTR; -+#endif /* #if defined(UNICODE) */ -+#define _TCHAR_DEFINED -+#endif /* #ifndef _TCHAR_DEFINED */ -+ -+ -+ #if defined(__linux__) || defined(__QNXNTO__) || defined(__METAG) -+ -+ #define IMG_CALLCONV -+ #define IMG_INTERNAL __attribute__((visibility("hidden"))) -+ #define IMG_EXPORT __attribute__((visibility("default"))) -+ #define IMG_IMPORT -+ #define IMG_RESTRICT __restrict__ -+ -+ #else -+ #error("define an OS") -+ #endif -+ -+// Use default definition if not overridden -+#ifndef IMG_ABORT -+ #define IMG_ABORT() abort() -+#endif -+ -+#ifndef IMG_MALLOC -+ #define IMG_MALLOC(A) malloc (A) -+#endif -+ -+#ifndef IMG_FREE -+ #define IMG_FREE(A) free (A) -+#endif -+ -+#define IMG_CONST const -+ -+#if defined(__GNUC__) -+#define IMG_FORMAT_PRINTF(x,y) __attribute__((format(printf,x,y))) -+#else -+#define IMG_FORMAT_PRINTF(x,y) -+#endif -+ -+/* -+ * Cleanup request defines -+ */ -+#define CLEANUP_WITH_POLL IMG_FALSE -+#define FORCE_CLEANUP IMG_TRUE -+ -+#if defined (_WIN64) -+#define IMG_UNDEF (~0ULL) -+#else -+#define IMG_UNDEF (~0UL) -+#endif -+ -+/* -+ Do the right thing when using printf to output cpu addresses, -+ depending on architecture. -+ */ -+#if defined (_WIN64) -+ #define UINTPTR_FMT "%016llX" -+#else -+ #if defined (__x86_64__) -+ #define UINTPTR_FMT "%016lX" -+ #else -+ #define UINTPTR_FMT "%08lX" -+ #endif -+#endif -+ -+/* -+ Similarly for DEV_ and SYS_ PHYSADDRs, but this is dependent on 32/36-bit MMU -+ capability, in addition to host architecture. -+ */ -+#if IMG_ADDRSPACE_PHYSADDR_BITS == 32 -+ #if defined(IMG_UINT32_IS_ULONG) -+ #define CPUPADDR_FMT "%08lX" -+ #define DEVPADDR_FMT "%08lX" -+ #define SYSPADDR_FMT "%08lX" -+ #else -+ #define CPUPADDR_FMT "%08X" -+ #define DEVPADDR_FMT "%08X" -+ #define SYSPADDR_FMT "%08X" -+ #endif -+#else -+ #if defined(__x86_64__) -+ #define CPUPADDR_FMT "%016lX" -+ #define DEVPADDR_FMT "%016lX" -+ #define SYSPADDR_FMT "%016lX" -+ #else -+ -+ #define CPUPADDR_FMT "%016llX" -+ #define DEVPADDR_FMT "%016llX" -+ #define SYSPADDR_FMT "%016llX" -+ #endif -+#endif -+ -+/* -+ Define a printf format macro for the length property of the format-specifier -+ for size_t, that allows avoidance of C99 dependency on compilers that don't -+ support this, while still ensuring that whatever the size of size_t (eg 32, -+ 64 bit Linux builds, or Win32/64 builds), a size_t (or IMG_SIZE_T) can be -+ passed to printf-type functions without a cast. -+*/ -+#if defined LINUX -+ /* Use C99 format specifier where possible */ -+ #define SIZE_T_FMT_LEN "z" -+#elif defined _WIN64 -+ #define SIZE_T_FMT_LEN "I" -+#else -+ #define SIZE_T_FMT_LEN "l" /* May need to be updated as required, for other OSs */ -+#endif -+ -+ -+#if defined (__x86_64__) -+ #define IMG_UINT64_FMT "l" -+#else -+ #define IMG_UINT64_FMT "ll" /* May need to be updated as required, for other OSs */ -+#endif -+ -+ -+#endif /* #if !defined (__IMG_DEFS_H__) */ -+/***************************************************************************** -+ End of file (IMG_DEFS.H) -+*****************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/include4/img_types.h b/drivers/staging/ti-es8-sgx/include4/img_types.h -new file mode 100644 -index 0000000..8f409c7 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/include4/img_types.h -@@ -0,0 +1,230 @@ -+/*************************************************************************/ /*! -+@Title Global types for use by IMG APIs -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Defines type aliases for use by IMG APIs. -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+#ifndef __IMG_TYPES_H__ -+#define __IMG_TYPES_H__ -+ -+/* define all address space bit depths: */ -+/* CPU virtual address space defaults to 32bits */ -+#if !defined(IMG_ADDRSPACE_CPUVADDR_BITS) -+#define IMG_ADDRSPACE_CPUVADDR_BITS 32 -+#endif -+ -+/* Physical address space defaults to 32bits */ -+#if !defined(IMG_ADDRSPACE_PHYSADDR_BITS) -+#define IMG_ADDRSPACE_PHYSADDR_BITS 32 -+#endif -+ -+typedef unsigned int IMG_UINT, *IMG_PUINT; -+typedef signed int IMG_INT, *IMG_PINT; -+ -+typedef unsigned char IMG_UINT8, *IMG_PUINT8; -+typedef unsigned char IMG_BYTE, *IMG_PBYTE; -+typedef signed char IMG_INT8, *IMG_PINT8; -+typedef char IMG_CHAR, *IMG_PCHAR; -+ -+typedef unsigned short IMG_UINT16, *IMG_PUINT16; -+typedef signed short IMG_INT16, *IMG_PINT16; -+#if !defined(IMG_UINT32_IS_ULONG) -+typedef unsigned int IMG_UINT32, *IMG_PUINT32; -+typedef signed int IMG_INT32, *IMG_PINT32; -+#else -+typedef unsigned long IMG_UINT32, *IMG_PUINT32; -+typedef signed long IMG_INT32, *IMG_PINT32; -+#endif -+#if !defined(IMG_UINT32_MAX) -+ #define IMG_UINT32_MAX 0xFFFFFFFFUL -+#endif -+ -+#if defined(USE_CODE) -+ typedef unsigned __int64 IMG_UINT64, *IMG_PUINT64; -+ typedef __int64 IMG_INT64, *IMG_PINT64; -+#elif defined(LINUX) && defined (__x86_64) -+ typedef unsigned long IMG_UINT64, *IMG_PUINT64; -+ typedef long IMG_INT64, *IMG_PINT64; -+#elif defined(LINUX) || defined(__METAG) || defined (__QNXNTO__) -+ typedef unsigned long long IMG_UINT64, *IMG_PUINT64; -+ typedef long long IMG_INT64, *IMG_PINT64; -+#else -+ #error("define an OS") -+#endif -+ -+#if !(defined(LINUX) && defined (__KERNEL__)) -+/* Linux kernel mode does not use floating point */ -+typedef float IMG_FLOAT, *IMG_PFLOAT; -+typedef double IMG_DOUBLE, *IMG_PDOUBLE; -+#endif -+ -+typedef enum tag_img_bool -+{ -+ IMG_FALSE = 0, -+ IMG_TRUE = 1, -+ IMG_FORCE_ALIGN = 0x7FFFFFFF -+} IMG_BOOL, *IMG_PBOOL; -+ -+typedef void IMG_VOID, *IMG_PVOID; -+ -+typedef IMG_INT32 IMG_RESULT; -+ -+#if defined(_WIN64) -+ typedef unsigned __int64 IMG_UINTPTR_T; -+ typedef signed __int64 IMG_INTPTR_T; -+ typedef signed __int64 IMG_PTRDIFF_T; -+ typedef IMG_UINT64 IMG_SIZE_T; -+#else -+ #if defined (__x86_64__) -+ typedef IMG_UINT64 IMG_SIZE_T; -+ typedef unsigned long IMG_UINTPTR_T; -+ typedef signed long IMG_INTPTR_T; -+ #else -+ typedef IMG_UINT32 IMG_SIZE_T; -+ typedef unsigned long IMG_UINTPTR_T; -+ typedef signed long IMG_INTPTR_T; -+ #endif -+#endif -+ -+typedef IMG_PVOID IMG_HANDLE; -+ -+typedef void** IMG_HVOID, * IMG_PHVOID; -+ -+#define IMG_NULL 0 -+ -+/* services/stream ID */ -+typedef IMG_UINTPTR_T IMG_SID; -+ -+typedef IMG_UINTPTR_T IMG_EVENTSID; -+ -+/* -+ * Address types. -+ * All types used to refer to a block of memory are wrapped in structures -+ * to enforce some degree of type safety, i.e. a IMG_DEV_VIRTADDR cannot -+ * be assigned to a variable of type IMG_DEV_PHYADDR because they are not the -+ * same thing. -+ * -+ * There is an assumption that the system contains at most one non-cpu mmu, -+ * and a memory block is only mapped by the MMU once. -+ * -+ * Different devices could have offset views of the physical address space. -+ * -+ */ -+ -+ -+/* -+ * -+ * +------------+ +------------+ +------------+ +------------+ -+ * | CPU | | DEV | | DEV | | DEV | -+ * +------------+ +------------+ +------------+ +------------+ -+ * | | | | -+ * | PVOID |IMG_DEV_VIRTADDR |IMG_DEV_VIRTADDR | -+ * | \-------------------/ | -+ * | | | -+ * +------------+ +------------+ | -+ * | MMU | | MMU | | -+ * +------------+ +------------+ | -+ * | | | -+ * | | | -+ * | | | -+ * +--------+ +---------+ +--------+ -+ * | Offset | | (Offset)| | Offset | -+ * +--------+ +---------+ +--------+ -+ * | | IMG_DEV_PHYADDR | -+ * | | | -+ * | | IMG_DEV_PHYADDR | -+ * +---------------------------------------------------------------------+ -+ * | System Address bus | -+ * +---------------------------------------------------------------------+ -+ * -+ */ -+ -+typedef IMG_PVOID IMG_CPU_VIRTADDR; -+ -+/* device virtual address */ -+typedef struct _IMG_DEV_VIRTADDR -+{ -+ /* device virtual addresses are 32bit for now */ -+ IMG_UINT32 uiAddr; -+#define IMG_CAST_TO_DEVVADDR_UINT(var) (IMG_UINT32)(var) -+ -+} IMG_DEV_VIRTADDR; -+ -+typedef IMG_UINT32 IMG_DEVMEM_SIZE_T; -+ -+/* cpu physical address */ -+typedef struct _IMG_CPU_PHYADDR -+{ -+ /* variable sized type (32,64) */ -+#if IMG_ADDRSPACE_PHYSADDR_BITS == 32 -+ /* variable sized type (32,64) */ -+ IMG_UINT32 uiAddr; -+#else -+ IMG_UINT64 uiAddr; -+#endif -+} IMG_CPU_PHYADDR; -+ -+/* device physical address */ -+typedef struct _IMG_DEV_PHYADDR -+{ -+#if IMG_ADDRSPACE_PHYSADDR_BITS == 32 -+ /* variable sized type (32,64) */ -+ IMG_UINT32 uiAddr; -+#else -+ IMG_UINT64 uiAddr; -+#endif -+} IMG_DEV_PHYADDR; -+ -+/* system physical address */ -+typedef struct _IMG_SYS_PHYADDR -+{ -+ /* variable sized type (32,64) */ -+#if IMG_ADDRSPACE_PHYSADDR_BITS == 32 -+ /* variable sized type (32,64) */ -+ IMG_UINT32 uiAddr; -+#else -+ IMG_UINT64 uiAddr; -+#endif -+} IMG_SYS_PHYADDR; -+ -+#include "img_defs.h" -+ -+#endif /* __IMG_TYPES_H__ */ -+/****************************************************************************** -+ End of file (img_types.h) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/include4/pdumpdefs.h b/drivers/staging/ti-es8-sgx/include4/pdumpdefs.h -new file mode 100644 -index 0000000..328d616 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/include4/pdumpdefs.h -@@ -0,0 +1,126 @@ -+/*************************************************************************/ /*! -+@Title PDUMP definitions header -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description PDUMP definitions header -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+#if !defined (__PDUMPDEFS_H__) -+#define __PDUMPDEFS_H__ -+ -+typedef enum _PDUMP_PIXEL_FORMAT_ -+{ -+ PVRSRV_PDUMP_PIXEL_FORMAT_UNSUPPORTED = 0, -+ PVRSRV_PDUMP_PIXEL_FORMAT_RGB8 = 1, -+ PVRSRV_PDUMP_PIXEL_FORMAT_RGB332 = 2, -+ PVRSRV_PDUMP_PIXEL_FORMAT_KRGB555 = 3, -+ PVRSRV_PDUMP_PIXEL_FORMAT_RGB565 = 4, -+ PVRSRV_PDUMP_PIXEL_FORMAT_ARGB4444 = 5, -+ PVRSRV_PDUMP_PIXEL_FORMAT_ARGB1555 = 6, -+ PVRSRV_PDUMP_PIXEL_FORMAT_RGB888 = 7, -+ PVRSRV_PDUMP_PIXEL_FORMAT_ARGB8888 = 8, -+ PVRSRV_PDUMP_PIXEL_FORMAT_YUV8 = 9, -+ PVRSRV_PDUMP_PIXEL_FORMAT_AYUV4444 = 10, -+ PVRSRV_PDUMP_PIXEL_FORMAT_VY0UY1_8888 = 11, -+ PVRSRV_PDUMP_PIXEL_FORMAT_UY0VY1_8888 = 12, -+ PVRSRV_PDUMP_PIXEL_FORMAT_Y0UY1V_8888 = 13, -+ PVRSRV_PDUMP_PIXEL_FORMAT_Y0VY1U_8888 = 14, -+ PVRSRV_PDUMP_PIXEL_FORMAT_YUV888 = 15, -+ PVRSRV_PDUMP_PIXEL_FORMAT_UYVY10101010 = 16, -+ PVRSRV_PDUMP_PIXEL_FORMAT_VYAUYA8888 = 17, -+ PVRSRV_PDUMP_PIXEL_FORMAT_AYUV8888 = 18, -+ PVRSRV_PDUMP_PIXEL_FORMAT_AYUV2101010 = 19, -+ PVRSRV_PDUMP_PIXEL_FORMAT_YUV101010 = 20, -+ PVRSRV_PDUMP_PIXEL_FORMAT_PL12Y8 = 21, -+ PVRSRV_PDUMP_PIXEL_FORMAT_YUV_IMC2 = 22, -+ PVRSRV_PDUMP_PIXEL_FORMAT_YUV_YV12 = 23, -+ PVRSRV_PDUMP_PIXEL_FORMAT_YUV_PL8 = 24, -+ PVRSRV_PDUMP_PIXEL_FORMAT_YUV_PL12 = 25, -+ PVRSRV_PDUMP_PIXEL_FORMAT_422PL12YUV8 = 26, -+ PVRSRV_PDUMP_PIXEL_FORMAT_420PL12YUV8 = 27, -+ PVRSRV_PDUMP_PIXEL_FORMAT_PL12Y10 = 28, -+ PVRSRV_PDUMP_PIXEL_FORMAT_422PL12YUV10 = 29, -+ PVRSRV_PDUMP_PIXEL_FORMAT_420PL12YUV10 = 30, -+ PVRSRV_PDUMP_PIXEL_FORMAT_ABGR8888 = 31, -+ PVRSRV_PDUMP_PIXEL_FORMAT_BGRA8888 = 32, -+ PVRSRV_PDUMP_PIXEL_FORMAT_ARGB8332 = 33, -+ PVRSRV_PDUMP_PIXEL_FORMAT_RGB555 = 34, -+ PVRSRV_PDUMP_PIXEL_FORMAT_F16 = 35, -+ PVRSRV_PDUMP_PIXEL_FORMAT_F32 = 36, -+ PVRSRV_PDUMP_PIXEL_FORMAT_L16 = 37, -+ PVRSRV_PDUMP_PIXEL_FORMAT_L32 = 38, -+ PVRSRV_PDUMP_PIXEL_FORMAT_RGBA8888 = 39, -+ PVRSRV_PDUMP_PIXEL_FORMAT_ABGR4444 = 40, -+ PVRSRV_PDUMP_PIXEL_FORMAT_RGBA4444 = 41, -+ PVRSRV_PDUMP_PIXEL_FORMAT_BGRA4444 = 42, -+ PVRSRV_PDUMP_PIXEL_FORMAT_ABGR1555 = 43, -+ PVRSRV_PDUMP_PIXEL_FORMAT_RGBA5551 = 44, -+ PVRSRV_PDUMP_PIXEL_FORMAT_BGRA5551 = 45, -+ PVRSRV_PDUMP_PIXEL_FORMAT_BGR565 = 46, -+ PVRSRV_PDUMP_PIXEL_FORMAT_A8 = 47, -+ -+ PVRSRV_PDUMP_PIXEL_FORMAT_FORCE_I32 = 0x7fffffff -+ -+} PDUMP_PIXEL_FORMAT; -+ -+typedef enum _PDUMP_MEM_FORMAT_ -+{ -+ PVRSRV_PDUMP_MEM_FORMAT_STRIDE = 0, -+ PVRSRV_PDUMP_MEM_FORMAT_RESERVED = 1, -+ PVRSRV_PDUMP_MEM_FORMAT_TILED = 8, -+ PVRSRV_PDUMP_MEM_FORMAT_TWIDDLED = 9, -+ PVRSRV_PDUMP_MEM_FORMAT_HYBRID = 10, -+ -+ PVRSRV_PDUMP_MEM_FORMAT_FORCE_I32 = 0x7fffffff -+} PDUMP_MEM_FORMAT; -+ -+typedef enum _PDUMP_POLL_OPERATOR -+{ -+ PDUMP_POLL_OPERATOR_EQUAL = 0, -+ PDUMP_POLL_OPERATOR_LESS = 1, -+ PDUMP_POLL_OPERATOR_LESSEQUAL = 2, -+ PDUMP_POLL_OPERATOR_GREATER = 3, -+ PDUMP_POLL_OPERATOR_GREATEREQUAL = 4, -+ PDUMP_POLL_OPERATOR_NOTEQUAL = 5, -+} PDUMP_POLL_OPERATOR; -+ -+ -+#endif /* __PDUMPDEFS_H__ */ -+ -+/***************************************************************************** -+ End of file (pdumpdefs.h) -+*****************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/include4/pvr_debug.h b/drivers/staging/ti-es8-sgx/include4/pvr_debug.h -new file mode 100644 -index 0000000..d394eaf ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/include4/pvr_debug.h -@@ -0,0 +1,239 @@ -+/*************************************************************************/ /*! -+@Title PVR Debug Declarations -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Provides debug functionality -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+#ifndef __PVR_DEBUG_H__ -+#define __PVR_DEBUG_H__ -+ -+ -+#include "img_types.h" -+ -+ -+#if defined (__cplusplus) -+extern "C" { -+#endif -+ -+#define PVR_MAX_DEBUG_MESSAGE_LEN (512) -+ -+/* These are privately used by pvr_debug, use the PVR_DBG_ defines instead */ -+#define DBGPRIV_FATAL 0x001UL -+#define DBGPRIV_ERROR 0x002UL -+#define DBGPRIV_WARNING 0x004UL -+#define DBGPRIV_MESSAGE 0x008UL -+#define DBGPRIV_VERBOSE 0x010UL -+#define DBGPRIV_CALLTRACE 0x020UL -+#define DBGPRIV_ALLOC 0x040UL -+#define DBGPRIV_BUFFERED 0x080UL -+#define DBGPRIV_DBGDRV_MESSAGE 0x100UL -+ -+#define DBGPRIV_DBGLEVEL_COUNT 9 -+ -+#if !defined(PVRSRV_NEED_PVR_ASSERT) && defined(DEBUG) -+#define PVRSRV_NEED_PVR_ASSERT -+#endif -+ -+#if defined(PVRSRV_NEED_PVR_ASSERT) && !defined(PVRSRV_NEED_PVR_DPF) -+#define PVRSRV_NEED_PVR_DPF -+#endif -+ -+#if !defined(PVRSRV_NEED_PVR_TRACE) && (defined(DEBUG) || defined(TIMING)) -+#define PVRSRV_NEED_PVR_TRACE -+#endif -+ -+/* PVR_ASSERT() and PVR_DBG_BREAK handling */ -+ -+#if defined(PVRSRV_NEED_PVR_ASSERT) -+ -+#if defined(LINUX) && defined(__KERNEL__) -+/* In Linux kernel mode, use BUG() directly. This produces the correct -+ filename and line number in the panic message. */ -+#define PVR_ASSERT(EXPR) do \ -+ { \ -+ if (!(EXPR)) \ -+ { \ -+ PVRSRVDebugPrintf(DBGPRIV_FATAL, __FILE__, __LINE__, \ -+ "Debug assertion failed!"); \ -+ BUG(); \ -+ } \ -+ } while (0) -+ -+#else /* defined(LINUX) && defined(__KERNEL__) */ -+ -+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVDebugAssertFail(const IMG_CHAR *pszFile, -+ IMG_UINT32 ui32Line); -+ -+#if defined(LINUX) -+ #define PVR_ASSERT(EXPR) do \ -+ { \ -+ if (!(EXPR)) \ -+ PVRSRVDebugAssertFail(__FILE__, __LINE__); \ -+ } while (0) -+#else -+ #if defined (__QNXNTO__) -+ #define PVR_ASSERT(EXPR) if (!(EXPR)) PVRSRVDebugAssertFail(__FILE__, __LINE__); -+ #else -+ #define PVR_ASSERT(EXPR) if (!(EXPR)) PVRSRVDebugAssertFail(__FILE__, __LINE__) -+ #endif -+#endif -+ -+#endif /* defined(LINUX) && defined(__KERNEL__) */ -+ -+ -+ #if defined(LINUX) && defined(__KERNEL__) -+ #define PVR_DBG_BREAK BUG() -+ #else -+ #define PVR_DBG_BREAK PVRSRVDebugAssertFail(__FILE__, __LINE__) -+ #endif -+ -+#else /* defined(PVRSRV_NEED_PVR_ASSERT) */ -+ -+ #define PVR_ASSERT(EXPR) -+ #define PVR_DBG_BREAK -+ -+#endif /* defined(PVRSRV_NEED_PVR_ASSERT) */ -+ -+ -+/* PVR_DPF() handling */ -+ -+#if defined(PVRSRV_NEED_PVR_DPF) -+ -+#if defined(PVRSRV_NEW_PVR_DPF) -+ -+ /* New logging mechanism */ -+ #define PVR_DBG_FATAL DBGPRIV_FATAL -+ #define PVR_DBG_ERROR DBGPRIV_ERROR -+ #define PVR_DBG_WARNING DBGPRIV_WARNING -+ #define PVR_DBG_MESSAGE DBGPRIV_MESSAGE -+ #define PVR_DBG_VERBOSE DBGPRIV_VERBOSE -+ #define PVR_DBG_CALLTRACE DBGPRIV_CALLTRACE -+ #define PVR_DBG_ALLOC DBGPRIV_ALLOC -+ #define PVR_DBG_BUFFERED DBGPRIV_BUFFERED -+ #define PVR_DBGDRIV_MESSAGE DBGPRIV_DBGDRV_MESSAGE -+ -+ /* These levels are always on with PVRSRV_NEED_PVR_DPF */ -+ #define __PVR_DPF_0x001UL(x...) PVRSRVDebugPrintf(DBGPRIV_FATAL, x) -+ #define __PVR_DPF_0x002UL(x...) PVRSRVDebugPrintf(DBGPRIV_ERROR, x) -+ #define __PVR_DPF_0x080UL(x...) PVRSRVDebugPrintf(DBGPRIV_BUFFERED, x) -+ -+ /* Some are compiled out completely in release builds */ -+#if defined(DEBUG) -+ #define __PVR_DPF_0x004UL(x...) PVRSRVDebugPrintf(DBGPRIV_WARNING, x) -+ #define __PVR_DPF_0x008UL(x...) PVRSRVDebugPrintf(DBGPRIV_MESSAGE, x) -+ #define __PVR_DPF_0x010UL(x...) PVRSRVDebugPrintf(DBGPRIV_VERBOSE, x) -+ #define __PVR_DPF_0x020UL(x...) PVRSRVDebugPrintf(DBGPRIV_CALLTRACE, x) -+ #define __PVR_DPF_0x040UL(x...) PVRSRVDebugPrintf(DBGPRIV_ALLOC, x) -+ #define __PVR_DPF_0x100UL(x...) PVRSRVDebugPrintf(DBGPRIV_DBGDRV_MESSAGE, x) -+#else -+ #define __PVR_DPF_0x004UL(x...) -+ #define __PVR_DPF_0x008UL(x...) -+ #define __PVR_DPF_0x010UL(x...) -+ #define __PVR_DPF_0x020UL(x...) -+ #define __PVR_DPF_0x040UL(x...) -+ #define __PVR_DPF_0x100UL(x...) -+#endif -+ -+ /* Translate the different log levels to separate macros -+ * so they can each be compiled out. -+ */ -+#if defined(DEBUG) -+ #define __PVR_DPF(lvl, x...) __PVR_DPF_ ## lvl (__FILE__, __LINE__, x) -+#else -+ #define __PVR_DPF(lvl, x...) __PVR_DPF_ ## lvl ("", 0, x) -+#endif -+ -+ /* Get rid of the double bracketing */ -+ #define PVR_DPF(x) __PVR_DPF x -+ -+#else /* defined(PVRSRV_NEW_PVR_DPF) */ -+ -+ /* Old logging mechanism */ -+ #define PVR_DBG_FATAL DBGPRIV_FATAL,__FILE__, __LINE__ -+ #define PVR_DBG_ERROR DBGPRIV_ERROR,__FILE__, __LINE__ -+ #define PVR_DBG_WARNING DBGPRIV_WARNING,__FILE__, __LINE__ -+ #define PVR_DBG_MESSAGE DBGPRIV_MESSAGE,__FILE__, __LINE__ -+ #define PVR_DBG_VERBOSE DBGPRIV_VERBOSE,__FILE__, __LINE__ -+ #define PVR_DBG_CALLTRACE DBGPRIV_CALLTRACE,__FILE__, __LINE__ -+ #define PVR_DBG_ALLOC DBGPRIV_ALLOC,__FILE__, __LINE__ -+ #define PVR_DBG_BUFFERED DBGPRIV_BUFFERED,__FILE__, __LINE__ -+ #define PVR_DBGDRIV_MESSAGE DBGPRIV_DBGDRV_MESSAGE, "", 0 -+ -+ #define PVR_DPF(X) PVRSRVDebugPrintf X -+ -+#endif /* defined(PVRSRV_NEW_PVR_DPF) */ -+ -+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVDebugPrintf(IMG_UINT32 ui32DebugLevel, -+ const IMG_CHAR *pszFileName, -+ IMG_UINT32 ui32Line, -+ const IMG_CHAR *pszFormat, -+ ...) IMG_FORMAT_PRINTF(4, 5); -+ -+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVDebugPrintfDumpCCB(void); -+ -+#else /* defined(PVRSRV_NEED_PVR_DPF) */ -+ -+ #define PVR_DPF(X) -+ -+#endif /* defined(PVRSRV_NEED_PVR_DPF) */ -+ -+/* PVR_TRACE() handling */ -+ -+#if defined(PVRSRV_NEED_PVR_TRACE) -+ -+ #define PVR_TRACE(X) PVRSRVTrace X -+ -+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVTrace(const IMG_CHAR* pszFormat, ... ) -+ IMG_FORMAT_PRINTF(1, 2); -+ -+#else /* defined(PVRSRV_NEED_PVR_TRACE) */ -+ -+ #define PVR_TRACE(X) -+ -+#endif /* defined(PVRSRV_NEED_PVR_TRACE) */ -+ -+ -+#if defined (__cplusplus) -+} -+#endif -+ -+#endif /* __PVR_DEBUG_H__ */ -+ -+/****************************************************************************** -+ End of file (pvr_debug.h) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/include4/pvrmodule.h b/drivers/staging/ti-es8-sgx/include4/pvrmodule.h -new file mode 100644 -index 0000000..267c7b6 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/include4/pvrmodule.h -@@ -0,0 +1,48 @@ -+/*************************************************************************/ /*! -+@Title Module Author and License. -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#ifndef _PVRMODULE_H_ -+#define _PVRMODULE_H_ -+ -+MODULE_AUTHOR("Imagination Technologies Ltd. <gpl-support@imgtec.com>"); -+MODULE_LICENSE("Dual MIT/GPL"); -+ -+#endif /* _PVRMODULE_H_ */ -diff --git a/drivers/staging/ti-es8-sgx/include4/pvrversion.h b/drivers/staging/ti-es8-sgx/include4/pvrversion.h -new file mode 100644 -index 0000000..0e4b5c2 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/include4/pvrversion.h -@@ -0,0 +1,68 @@ -+/*************************************************************************/ /*! -+@File -+@Title Version numbers and strings. -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Version numbers and strings for PVR Consumer services -+ components. -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#ifndef _PVRVERSION_H_ -+#define _PVRVERSION_H_ -+ -+#define PVR_STR(X) #X -+#define PVR_STR2(X) PVR_STR(X) -+ -+#define PVRVERSION_MAJ 1 -+#define PVRVERSION_MIN 10 -+ -+#define PVRVERSION_FAMILY "sgxddk" -+#define PVRVERSION_BRANCHNAME "1.10" -+#define PVRVERSION_BUILD 2359475 -+#define PVRVERSION_BSCONTROL "SGX_DDK_Linux_CustomerTI" -+ -+#define PVRVERSION_STRING "SGX_DDK_Linux_CustomerTI sgxddk 1.10@" PVR_STR2(PVRVERSION_BUILD) -+#define PVRVERSION_STRING_SHORT "1.10@" PVR_STR2(PVRVERSION_BUILD) -+ -+#define COPYRIGHT_TXT "Copyright (c) Imagination Technologies Ltd. All Rights Reserved." -+ -+#define PVRVERSION_BUILD_HI 235 -+#define PVRVERSION_BUILD_LO 9475 -+#define PVRVERSION_STRING_NUMERIC PVR_STR2(PVRVERSION_MAJ) "." PVR_STR2(PVRVERSION_MIN) "." PVR_STR2(PVRVERSION_BUILD_HI) "." PVR_STR2(PVRVERSION_BUILD_LO) -+ -+#endif /* _PVRVERSION_H_ */ -diff --git a/drivers/staging/ti-es8-sgx/include4/services.h b/drivers/staging/ti-es8-sgx/include4/services.h -new file mode 100644 -index 0000000..5d55222 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/include4/services.h -@@ -0,0 +1,1571 @@ -+/*************************************************************************/ /*! -+@Title Services API Header -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Exported services API details -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#ifndef __SERVICES_H__ -+#define __SERVICES_H__ -+ -+#if defined (__cplusplus) -+extern "C" { -+#endif -+ -+#include "img_defs.h" -+#include "servicesext.h" -+#include "pdumpdefs.h" -+ -+ -+/* The comment below is the front page for code-generated doxygen documentation */ -+/*! -+ ****************************************************************************** -+ @mainpage -+ This document details the APIs and implementation of the Consumer Services. -+ It is intended to be used in conjunction with the Consumer Services -+ Software Architectural Specification and the Consumer Services Software -+ Functional Specification. -+ *****************************************************************************/ -+ -+/****************************************************************************** -+ * #defines -+ *****************************************************************************/ -+ -+/* 4k page size definition */ -+#define PVRSRV_4K_PAGE_SIZE 4096UL -+ -+#define PVRSRV_MAX_CMD_SIZE 1024/*!< max size in bytes of a command */ -+ -+#define PVRSRV_MAX_DEVICES 16 /*!< Largest supported number of devices on the system */ -+ -+#define EVENTOBJNAME_MAXLENGTH (50) -+ -+/* -+ Flags associated with memory allocation -+ (bits 0-11) -+*/ -+#define PVRSRV_MEM_READ (1U<<0) -+#define PVRSRV_MEM_WRITE (1U<<1) -+#define PVRSRV_MEM_CACHE_CONSISTENT (1U<<2) -+#define PVRSRV_MEM_NO_SYNCOBJ (1U<<3) -+#define PVRSRV_MEM_INTERLEAVED (1U<<4) -+#define PVRSRV_MEM_DUMMY (1U<<5) -+#define PVRSRV_MEM_EDM_PROTECT (1U<<6) -+#define PVRSRV_MEM_ZERO (1U<<7) -+#define PVRSRV_MEM_USER_SUPPLIED_DEVVADDR (1U<<8) -+#define PVRSRV_MEM_RAM_BACKED_ALLOCATION (1U<<9) -+#define PVRSRV_MEM_NO_RESMAN (1U<<10) -+#define PVRSRV_MEM_EXPORTED (1U<<11) -+ -+ -+/* -+ Heap Attribute flags -+ (bits 12-23) -+*/ -+#define PVRSRV_HAP_CACHED (1U<<12) -+#define PVRSRV_HAP_UNCACHED (1U<<13) -+#define PVRSRV_HAP_WRITECOMBINE (1U<<14) -+#define PVRSRV_HAP_CACHETYPE_MASK (PVRSRV_HAP_CACHED|PVRSRV_HAP_UNCACHED|PVRSRV_HAP_WRITECOMBINE) -+#define PVRSRV_HAP_KERNEL_ONLY (1U<<15) -+#define PVRSRV_HAP_SINGLE_PROCESS (1U<<16) -+#define PVRSRV_HAP_MULTI_PROCESS (1U<<17) -+#define PVRSRV_HAP_FROM_EXISTING_PROCESS (1U<<18) -+#define PVRSRV_HAP_NO_CPU_VIRTUAL (1U<<19) -+#define PVRSRV_HAP_MAPTYPE_MASK (PVRSRV_HAP_KERNEL_ONLY \ -+ |PVRSRV_HAP_SINGLE_PROCESS \ -+ |PVRSRV_HAP_MULTI_PROCESS \ -+ |PVRSRV_HAP_FROM_EXISTING_PROCESS \ -+ |PVRSRV_HAP_NO_CPU_VIRTUAL) -+ -+/* -+ Allows user allocations to override heap attributes -+ (Bits shared with heap flags) -+*/ -+#define PVRSRV_MEM_CACHED PVRSRV_HAP_CACHED -+#define PVRSRV_MEM_UNCACHED PVRSRV_HAP_UNCACHED -+#define PVRSRV_MEM_WRITECOMBINE PVRSRV_HAP_WRITECOMBINE -+ -+/* -+ Backing store flags (defined internally) -+ (bits 24-26) -+*/ -+#define PVRSRV_MEM_BACKINGSTORE_FIELD_SHIFT (24) -+ -+/* -+ Per allocation/mapping flags -+ (bits 27-30) -+ */ -+#define PVRSRV_MAP_NOUSERVIRTUAL (1UL<<27) -+#define PVRSRV_MEM_XPROC (1U<<28) -+#define PVRSRV_MEM_ION (1U<<29) -+#define PVRSRV_MEM_ALLOCATENONCACHEDMEM (1UL<<30) -+ -+/* -+ Internal allocation/mapping flags -+ (bit 31) -+*/ -+#define PVRSRV_MEM_SPARSE (1U<<31) -+ -+ -+/* -+ * How much context we lose on a (power) mode change -+ */ -+#define PVRSRV_NO_CONTEXT_LOSS 0 /*!< Do not lose state on power down */ -+#define PVRSRV_SEVERE_LOSS_OF_CONTEXT 1 /*!< lose state on power down */ -+#define PVRSRV_PRE_STATE_CHANGE_MASK 0x80 /*!< power state change mask */ -+ -+ -+/* -+ * Device cookie defines -+ */ -+#define PVRSRV_DEFAULT_DEV_COOKIE (1) /*!< default device cookie */ -+ -+ -+/* -+ * Misc Info. present flags -+ */ -+#define PVRSRV_MISC_INFO_TIMER_PRESENT (1U<<0) -+#define PVRSRV_MISC_INFO_CLOCKGATE_PRESENT (1U<<1) -+#define PVRSRV_MISC_INFO_MEMSTATS_PRESENT (1U<<2) -+#define PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT (1U<<3) -+#define PVRSRV_MISC_INFO_DDKVERSION_PRESENT (1U<<4) -+#define PVRSRV_MISC_INFO_CPUCACHEOP_PRESENT (1U<<5) -+#define PVRSRV_MISC_INFO_FREEMEM_PRESENT (1U<<6) -+#define PVRSRV_MISC_INFO_GET_REF_COUNT_PRESENT (1U<<7) -+#define PVRSRV_MISC_INFO_GET_PAGE_SIZE_PRESENT (1U<<8) -+#define PVRSRV_MISC_INFO_FORCE_SWAP_TO_SYSTEM_PRESENT (1U<<9) -+ -+#define PVRSRV_MISC_INFO_RESET_PRESENT (1U<<31) -+ -+/* PDUMP defines */ -+#define PVRSRV_PDUMP_MAX_FILENAME_SIZE 20 -+#define PVRSRV_PDUMP_MAX_COMMENT_SIZE 200 -+ -+ -+/* -+ Flags for PVRSRVChangeDeviceMemoryAttributes call. -+*/ -+#define PVRSRV_CHANGEDEVMEM_ATTRIBS_CACHECOHERENT 0x00000001 -+ -+/* -+ Flags for PVRSRVMapExtMemory and PVRSRVUnmapExtMemory -+ ALTERNATEVA - Used when mapping multiple virtual addresses to the same physical address. Set this flag on extra maps. -+ PHYSCONTIG - Physical pages are contiguous (unused) -+*/ -+#define PVRSRV_MAPEXTMEMORY_FLAGS_ALTERNATEVA 0x00000001 -+#define PVRSRV_MAPEXTMEMORY_FLAGS_PHYSCONTIG 0x00000002 -+ -+/* -+ Flags for PVRSRVModifySyncOps -+ WO_INC - Used to increment "WriteOpsPending/complete of sync info" -+ RO_INC - Used to increment "ReadOpsPending/complete of sync info" -+*/ -+#define PVRSRV_MODIFYSYNCOPS_FLAGS_WO_INC 0x00000001 -+#define PVRSRV_MODIFYSYNCOPS_FLAGS_RO_INC 0x00000002 -+ -+/* -+ Flags for Services connection. -+ Allows to define per-client policy for Services -+*/ -+#define SRV_FLAGS_PERSIST 0x1 -+#define SRV_FLAGS_PDUMP_ACTIVE 0x2 -+ -+/* -+ Pdump flags which are accessible to Services clients -+*/ -+#define PVRSRV_PDUMP_FLAGS_CONTINUOUS 0x1 -+ -+ -+/****************************************************************************** -+ * Enums -+ *****************************************************************************/ -+ -+/*! -+ ****************************************************************************** -+ * List of known device types. -+ *****************************************************************************/ -+typedef enum _PVRSRV_DEVICE_TYPE_ -+{ -+ PVRSRV_DEVICE_TYPE_UNKNOWN = 0 , -+ PVRSRV_DEVICE_TYPE_MBX1 = 1 , -+ PVRSRV_DEVICE_TYPE_MBX1_LITE = 2 , -+ -+ PVRSRV_DEVICE_TYPE_M24VA = 3, -+ PVRSRV_DEVICE_TYPE_MVDA2 = 4, -+ PVRSRV_DEVICE_TYPE_MVED1 = 5, -+ PVRSRV_DEVICE_TYPE_MSVDX = 6, -+ -+ PVRSRV_DEVICE_TYPE_SGX = 7, -+ -+ PVRSRV_DEVICE_TYPE_VGX = 8, -+ -+ /* 3rd party devices take ext type */ -+ PVRSRV_DEVICE_TYPE_EXT = 9, -+ -+ PVRSRV_DEVICE_TYPE_LAST = 9, -+ -+ PVRSRV_DEVICE_TYPE_FORCE_I32 = 0x7fffffff -+ -+} PVRSRV_DEVICE_TYPE; -+ -+#define HEAP_ID( _dev_ , _dev_heap_idx_ ) ( ((_dev_)<<24) | ((_dev_heap_idx_)&((1<<24)-1)) ) -+#define HEAP_IDX( _heap_id_ ) ( (_heap_id_)&((1<<24) - 1 ) ) -+#define HEAP_DEV( _heap_id_ ) ( (_heap_id_)>>24 ) -+ -+/* common undefined heap ID define */ -+#define PVRSRV_UNDEFINED_HEAP_ID (~0LU) -+ -+/*! -+ ****************************************************************************** -+ * User Module type -+ *****************************************************************************/ -+typedef enum -+{ -+ IMG_EGL = 0x00000001, -+ IMG_OPENGLES1 = 0x00000002, -+ IMG_OPENGLES2 = 0x00000003, -+ IMG_D3DM = 0x00000004, -+ IMG_SRV_UM = 0x00000005, -+ IMG_OPENVG = 0x00000006, -+ IMG_SRVCLIENT = 0x00000007, -+ IMG_VISTAKMD = 0x00000008, -+ IMG_VISTA3DNODE = 0x00000009, -+ IMG_VISTAMVIDEONODE = 0x0000000A, -+ IMG_VISTAVPBNODE = 0x0000000B, -+ IMG_OPENGL = 0x0000000C, -+ IMG_D3D = 0x0000000D, -+#if defined(SUPPORT_GRAPHICS_HAL) || defined(SUPPORT_COMPOSER_HAL) -+ IMG_ANDROID_HAL = 0x0000000E, -+#endif -+#if defined(SUPPORT_OPENCL) -+ IMG_OPENCL = 0x0000000F, -+#endif -+ -+} IMG_MODULE_ID; -+ -+ -+#define APPHINT_MAX_STRING_SIZE 256 -+ -+/*! -+ ****************************************************************************** -+ * IMG data types -+ *****************************************************************************/ -+typedef enum -+{ -+ IMG_STRING_TYPE = 1, -+ IMG_FLOAT_TYPE , -+ IMG_UINT_TYPE , -+ IMG_INT_TYPE , -+ IMG_FLAG_TYPE -+}IMG_DATA_TYPE; -+ -+ -+/****************************************************************************** -+ * Structure definitions. -+ *****************************************************************************/ -+ -+/*! -+ * Forward declaration -+ */ -+typedef struct _PVRSRV_DEV_DATA_ *PPVRSRV_DEV_DATA; -+ -+/*! -+ ****************************************************************************** -+ * Device identifier structure -+ *****************************************************************************/ -+typedef struct _PVRSRV_DEVICE_IDENTIFIER_ -+{ -+ PVRSRV_DEVICE_TYPE eDeviceType; /*!< Identifies the type of the device */ -+ PVRSRV_DEVICE_CLASS eDeviceClass; /*!< Identifies more general class of device - display/3d/mpeg etc */ -+ IMG_UINT32 ui32DeviceIndex; /*!< Index of the device within the system */ -+ IMG_CHAR *pszPDumpDevName; /*!< Pdump memory bank name */ -+ IMG_CHAR *pszPDumpRegName; /*!< Pdump register bank name */ -+ -+} PVRSRV_DEVICE_IDENTIFIER; -+ -+ -+/****************************************************************************** -+ * Client dev info -+ ****************************************************************************** -+ */ -+typedef struct _PVRSRV_CLIENT_DEV_DATA_ -+{ -+ IMG_UINT32 ui32NumDevices; /*!< Number of services-managed devices connected */ -+ PVRSRV_DEVICE_IDENTIFIER asDevID[PVRSRV_MAX_DEVICES]; /*!< Device identifiers */ -+ PVRSRV_ERROR (*apfnDevConnect[PVRSRV_MAX_DEVICES])(PPVRSRV_DEV_DATA); /*< device-specific connection callback */ -+ PVRSRV_ERROR (*apfnDumpTrace[PVRSRV_MAX_DEVICES])(PPVRSRV_DEV_DATA); /*!< device-specific debug trace callback */ -+ -+} PVRSRV_CLIENT_DEV_DATA; -+ -+ -+/*! -+ ****************************************************************************** -+ * Kernel Services connection structure -+ *****************************************************************************/ -+typedef struct _PVRSRV_CONNECTION_ -+{ -+ IMG_HANDLE hServices; /*!< UM IOCTL handle */ -+ IMG_UINT32 ui32ProcessID; /*!< Process ID for resource locking */ -+ PVRSRV_CLIENT_DEV_DATA sClientDevData; /*!< Client device data */ -+ IMG_UINT32 ui32SrvFlags; /*!< Per-client Services flags */ -+}PVRSRV_CONNECTION; -+ -+ -+/*! -+ ****************************************************************************** -+ * This structure allows the user mode glue code to have an OS independent -+ * set of prototypes. -+ *****************************************************************************/ -+typedef struct _PVRSRV_DEV_DATA_ -+{ -+ IMG_CONST PVRSRV_CONNECTION *psConnection; /*!< Services connection info */ -+ IMG_HANDLE hDevCookie; /*!< Dev cookie */ -+ -+} PVRSRV_DEV_DATA; -+ -+/*! -+ ****************************************************************************** -+ * address:value update structure -+ *****************************************************************************/ -+typedef struct _PVRSRV_MEMUPDATE_ -+{ -+ IMG_UINT32 ui32UpdateAddr; /*!< Address */ -+ IMG_UINT32 ui32UpdateVal; /*!< value */ -+} PVRSRV_MEMUPDATE; -+ -+/*! -+ ****************************************************************************** -+ * address:value register structure -+ *****************************************************************************/ -+typedef struct _PVRSRV_HWREG_ -+{ -+ IMG_UINT32 ui32RegAddr; /*!< Address */ -+ IMG_UINT32 ui32RegVal; /*!< value */ -+} PVRSRV_HWREG; -+ -+/*! -+ ****************************************************************************** -+ * Implementation details for memory handling -+ *****************************************************************************/ -+typedef struct _PVRSRV_MEMBLK_ -+{ -+ IMG_DEV_VIRTADDR sDevVirtAddr; /*!< Address of the memory in the IMG MMUs address space */ -+ IMG_HANDLE hOSMemHandle; /*!< Stores the underlying memory allocation handle */ -+ IMG_HANDLE hOSWrapMem; /*!< FIXME: better way to solve this problem */ -+ IMG_HANDLE hBuffer; /*!< Stores the BM_HANDLE for the underlying memory management */ -+ IMG_HANDLE hResItem; /*!< handle to resource item for allocate */ -+ IMG_SYS_PHYADDR *psIntSysPAddr; -+ -+} PVRSRV_MEMBLK; -+ -+/*! -+ ****************************************************************************** -+ * Memory Management (externel interface) -+ *****************************************************************************/ -+typedef struct _PVRSRV_KERNEL_MEM_INFO_ *PPVRSRV_KERNEL_MEM_INFO; -+ -+typedef struct _PVRSRV_CLIENT_MEM_INFO_ -+{ -+ /* CPU Virtual Address */ -+ IMG_PVOID pvLinAddr; -+ -+ /* CPU Virtual Address (for kernel mode) */ -+ IMG_PVOID pvLinAddrKM; -+ -+ /* Device Virtual Address */ -+ IMG_DEV_VIRTADDR sDevVAddr; -+ -+ /* allocation flags */ -+ IMG_UINT32 ui32Flags; -+ -+ /* client allocation flags */ -+ IMG_UINT32 ui32ClientFlags; -+ -+ /* allocation size in bytes */ -+ IMG_SIZE_T uAllocSize; -+ -+ -+ /* ptr to associated client sync info - NULL if no sync */ -+ struct _PVRSRV_CLIENT_SYNC_INFO_ *psClientSyncInfo; -+ -+ /* handle to client mapping data (OS specific) */ -+ IMG_HANDLE hMappingInfo; -+ -+ /* handle to kernel mem info */ -+ IMG_HANDLE hKernelMemInfo; -+ -+ /* resman handle for UM mapping clean-up */ -+ IMG_HANDLE hResItem; -+ -+#if defined(SUPPORT_MEMINFO_IDS) -+ #if !defined(USE_CODE) -+ /* Globally unique "stamp" for allocation (not re-used until wrap) */ -+ IMG_UINT64 ui64Stamp; -+ #else /* !defined(USE_CODE) */ -+ IMG_UINT32 dummy1; -+ IMG_UINT32 dummy2; -+ #endif /* !defined(USE_CODE) */ -+#endif /* defined(SUPPORT_MEMINFO_IDS) */ -+#if defined(SUPPORT_ION) -+ IMG_SIZE_T uiIonBufferSize; -+#endif /* defined(SUPPORT_ION) */ -+ -+ /* -+ ptr to next mem info -+ D3D uses psNext for mid-scene texture reload. -+ */ -+ struct _PVRSRV_CLIENT_MEM_INFO_ *psNext; -+ -+} PVRSRV_CLIENT_MEM_INFO, *PPVRSRV_CLIENT_MEM_INFO; -+ -+ -+/*! -+ ****************************************************************************** -+ * Memory Heap Information -+ *****************************************************************************/ -+#define PVRSRV_MAX_CLIENT_HEAPS (32) -+typedef struct _PVRSRV_HEAP_INFO_ -+{ -+ IMG_UINT32 ui32HeapID; -+ IMG_HANDLE hDevMemHeap; -+ IMG_DEV_VIRTADDR sDevVAddrBase; -+ IMG_UINT32 ui32HeapByteSize; -+ IMG_UINT32 ui32Attribs; -+ IMG_UINT32 ui32XTileStride; -+}PVRSRV_HEAP_INFO; -+ -+ -+ -+ -+/* -+ Event Object information structure -+*/ -+typedef struct _PVRSRV_EVENTOBJECT_ -+{ -+ /* globally unique name of the event object */ -+ IMG_CHAR szName[EVENTOBJNAME_MAXLENGTH]; -+ /* kernel specific handle for the event object */ -+ IMG_HANDLE hOSEventKM; -+ -+} PVRSRV_EVENTOBJECT; -+ -+/* -+ Cache operation type -+*/ -+typedef enum -+{ -+ PVRSRV_MISC_INFO_CPUCACHEOP_NONE = 0, -+ PVRSRV_MISC_INFO_CPUCACHEOP_CLEAN, -+ PVRSRV_MISC_INFO_CPUCACHEOP_FLUSH -+} PVRSRV_MISC_INFO_CPUCACHEOP_TYPE; -+ -+/*! -+ ****************************************************************************** -+ * Structure to retrieve misc. information from services -+ *****************************************************************************/ -+typedef struct _PVRSRV_MISC_INFO_ -+{ -+ IMG_UINT32 ui32StateRequest; /*!< requested State Flags */ -+ IMG_UINT32 ui32StatePresent; /*!< Present/Valid State Flags */ -+ -+ /*!< SOC Timer register */ -+ IMG_VOID *pvSOCTimerRegisterKM; -+ IMG_VOID *pvSOCTimerRegisterUM; -+ IMG_HANDLE hSOCTimerRegisterOSMemHandle; -+ IMG_HANDLE hSOCTimerRegisterMappingInfo; -+ -+ /*!< SOC Clock Gating registers */ -+ IMG_VOID *pvSOCClockGateRegs; -+ IMG_UINT32 ui32SOCClockGateRegsSize; -+ -+ /* Memory Stats/DDK version string depending on ui32StateRequest flags */ -+ IMG_CHAR *pszMemoryStr; -+ IMG_UINT32 ui32MemoryStrLen; -+ -+ /* global event object */ -+ PVRSRV_EVENTOBJECT sGlobalEventObject;//FIXME: should be private to services -+ IMG_HANDLE hOSGlobalEvent; -+ -+ /* Note: add misc. items as required */ -+ IMG_UINT32 aui32DDKVersion[4]; -+ -+ /*!< CPU cache flush controls: */ -+ struct -+ { -+ /*!< Defer the CPU cache op to the next HW op to be submitted (else flush now) */ -+ IMG_BOOL bDeferOp; -+ -+ /*!< Type of cache operation to perform */ -+ PVRSRV_MISC_INFO_CPUCACHEOP_TYPE eCacheOpType; -+ -+ /* This union is a bit unsightly. We need it because we'll use the psMemInfo -+ * directly in the srvclient PVRSRVGetMiscInfo code, and then convert it -+ * to a kernel meminfo if required. Try to not waste space. -+ */ -+ union -+ { -+ /*!< Input client meminfo (UM side) */ -+ PVRSRV_CLIENT_MEM_INFO *psClientMemInfo; -+ -+ /*!< Output kernel meminfo (Bridge+KM side) */ -+ struct _PVRSRV_KERNEL_MEM_INFO_ *psKernelMemInfo; -+ } u; -+ -+ /*!< Offset in MemInfo to start cache op */ -+ IMG_VOID *pvBaseVAddr; -+ -+ /*!< Length of range to perform cache op */ -+ IMG_UINT32 ui32Length; -+ } sCacheOpCtl; -+ -+ /*!< Meminfo refcount controls: */ -+ struct -+ { -+ /* This union is a bit unsightly. We need it because we'll use the psMemInfo -+ * directly in the srvclient PVRSRVGetMiscInfo code, and then convert it -+ * to a kernel meminfo if required. Try to not waste space. -+ */ -+ union -+ { -+ /*!< Input client meminfo (UM side) */ -+ PVRSRV_CLIENT_MEM_INFO *psClientMemInfo; -+ -+ /*!< Output kernel meminfo (Bridge+KM side) */ -+ struct _PVRSRV_KERNEL_MEM_INFO_ *psKernelMemInfo; -+ } u; -+ -+ /*!< Resulting refcount */ -+ IMG_UINT32 ui32RefCount; -+ } sGetRefCountCtl; -+ -+ IMG_UINT32 ui32PageSize; -+} PVRSRV_MISC_INFO; -+ -+/*! -+ ****************************************************************************** -+ * Synchronisation token -+ *****************************************************************************/ -+typedef struct _PVRSRV_SYNC_TOKEN_ -+{ -+ /* This token is supposed to be passed around as an opaque object -+ - caller should not rely on the internal fields staying the same. -+ The fields are hidden in sPrivate in order to reinforce this. */ -+ struct -+ { -+ IMG_HANDLE hKernelSyncInfo; -+ IMG_UINT32 ui32ReadOpsPendingSnapshot; -+ IMG_UINT32 ui32WriteOpsPendingSnapshot; -+ IMG_UINT32 ui32ReadOps2PendingSnapshot; -+ } sPrivate; -+} PVRSRV_SYNC_TOKEN; -+ -+ -+/****************************************************************************** -+ * PVR Client Event handling in Services -+ *****************************************************************************/ -+typedef enum _PVRSRV_CLIENT_EVENT_ -+{ -+ PVRSRV_CLIENT_EVENT_HWTIMEOUT = 0, -+} PVRSRV_CLIENT_EVENT; -+ -+typedef IMG_VOID (*PFN_QUEUE_COMMAND_COMPLETE)(IMG_HANDLE hCallbackData); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVClientEvent(IMG_CONST PVRSRV_CLIENT_EVENT eEvent, -+ PVRSRV_DEV_DATA *psDevData, -+ IMG_PVOID pvData); -+ -+/****************************************************************************** -+ * PVR Services API prototypes. -+ *****************************************************************************/ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVConnect(PVRSRV_CONNECTION **ppsConnection, IMG_UINT32 ui32SrvFlags); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVDisconnect(IMG_CONST PVRSRV_CONNECTION *psConnection); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumerateDevices(IMG_CONST PVRSRV_CONNECTION *psConnection, -+ IMG_UINT32 *puiNumDevices, -+ PVRSRV_DEVICE_IDENTIFIER *puiDevIDs); -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVAcquireDeviceData(IMG_CONST PVRSRV_CONNECTION *psConnection, -+ IMG_UINT32 uiDevIndex, -+ PVRSRV_DEV_DATA *psDevData, -+ PVRSRV_DEVICE_TYPE eDeviceType); -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetMiscInfo (IMG_CONST PVRSRV_CONNECTION *psConnection, PVRSRV_MISC_INFO *psMiscInfo); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVReleaseMiscInfo (IMG_CONST PVRSRV_CONNECTION *psConnection, PVRSRV_MISC_INFO *psMiscInfo); -+ -+IMG_IMPORT -+PVRSRV_ERROR PVRSRVPollForValue ( const PVRSRV_CONNECTION *psConnection, -+ IMG_HANDLE hOSEvent, -+ volatile IMG_UINT32 *pui32LinMemAddr, -+ IMG_UINT32 ui32Value, -+ IMG_UINT32 ui32Mask, -+ IMG_UINT32 ui32Waitus, -+ IMG_UINT32 ui32Tries); -+ -+/* memory APIs */ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateDeviceMemContext(IMG_CONST PVRSRV_DEV_DATA *psDevData, -+ IMG_HANDLE *phDevMemContext, -+ IMG_UINT32 *pui32SharedHeapCount, -+ PVRSRV_HEAP_INFO *psHeapInfo); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyDeviceMemContext(IMG_CONST PVRSRV_DEV_DATA *psDevData, -+ IMG_HANDLE hDevMemContext -+ ); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDeviceMemHeapInfo(IMG_CONST PVRSRV_DEV_DATA *psDevData, -+ IMG_HANDLE hDevMemContext, -+ IMG_UINT32 *pui32SharedHeapCount, -+ PVRSRV_HEAP_INFO *psHeapInfo); -+ -+#if defined(PVRSRV_LOG_MEMORY_ALLOCS) -+ #define PVRSRVAllocDeviceMem_log(psDevData, hDevMemHeap, ui32Attribs, ui32Size, ui32Alignment, ppsMemInfo, logStr) \ -+ (PVR_TRACE(("PVRSRVAllocDeviceMem(" #psDevData "," #hDevMemHeap "," #ui32Attribs "," #ui32Size "," #ui32Alignment "," #ppsMemInfo ")" \ -+ ": " logStr " (size = 0x%lx)", ui32Size)), \ -+ PVRSRVAllocDeviceMem(psDevData, hDevMemHeap, ui32Attribs, ui32Size, ui32Alignment, ppsMemInfo)) -+#else -+ #define PVRSRVAllocDeviceMem_log(psDevData, hDevMemHeap, ui32Attribs, ui32Size, ui32Alignment, ppsMemInfo, logStr) \ -+ PVRSRVAllocDeviceMem(psDevData, hDevMemHeap, ui32Attribs, ui32Size, ui32Alignment, ppsMemInfo) -+#endif -+ -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVAllocDeviceMem2(IMG_CONST PVRSRV_DEV_DATA *psDevData, -+ IMG_HANDLE hDevMemHeap, -+ IMG_UINT32 ui32Attribs, -+ IMG_SIZE_T ui32Size, -+ IMG_SIZE_T ui32Alignment, -+ IMG_PVOID pvPrivData, -+ IMG_UINT32 ui32PrivDataLength, -+ PVRSRV_CLIENT_MEM_INFO **ppsMemInfo); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVAllocDeviceMem(IMG_CONST PVRSRV_DEV_DATA *psDevData, -+ IMG_HANDLE hDevMemHeap, -+ IMG_UINT32 ui32Attribs, -+ IMG_SIZE_T ui32Size, -+ IMG_SIZE_T ui32Alignment, -+ PVRSRV_CLIENT_MEM_INFO **ppsMemInfo); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeDeviceMem(IMG_CONST PVRSRV_DEV_DATA *psDevData, -+ PVRSRV_CLIENT_MEM_INFO *psMemInfo); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVExportDeviceMem(IMG_CONST PVRSRV_DEV_DATA *psDevData, -+ PVRSRV_CLIENT_MEM_INFO *psMemInfo, -+ IMG_HANDLE *phMemInfo -+ ); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVReserveDeviceVirtualMem(IMG_CONST PVRSRV_DEV_DATA *psDevData, -+ IMG_HANDLE hDevMemHeap, -+ IMG_DEV_VIRTADDR *psDevVAddr, -+ IMG_SIZE_T ui32Size, -+ IMG_SIZE_T ui32Alignment, -+ PVRSRV_CLIENT_MEM_INFO **ppsMemInfo); -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeDeviceVirtualMem(IMG_CONST PVRSRV_DEV_DATA *psDevData, -+ PVRSRV_CLIENT_MEM_INFO *psMemInfo); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceMemory (IMG_CONST PVRSRV_DEV_DATA *psDevData, -+ IMG_HANDLE hKernelMemInfo, -+ IMG_HANDLE hDstDevMemHeap, -+ PVRSRV_CLIENT_MEM_INFO **ppsDstMemInfo); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapDeviceMemory (IMG_CONST PVRSRV_DEV_DATA *psDevData, -+ PVRSRV_CLIENT_MEM_INFO *psMemInfo); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVMapExtMemory (IMG_CONST PVRSRV_DEV_DATA *psDevData, -+ PVRSRV_CLIENT_MEM_INFO *psMemInfo, -+ IMG_SYS_PHYADDR *psSysPAddr, -+ IMG_UINT32 ui32Flags); -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapExtMemory (IMG_CONST PVRSRV_DEV_DATA *psDevData, -+ PVRSRV_CLIENT_MEM_INFO *psMemInfo, -+ IMG_UINT32 ui32Flags); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVWrapExtMemory(IMG_CONST PVRSRV_DEV_DATA *psDevData, -+ IMG_HANDLE hDevMemContext, -+ IMG_SIZE_T ui32ByteSize, -+ IMG_SIZE_T ui32PageOffset, -+ IMG_BOOL bPhysContig, -+ IMG_SYS_PHYADDR *psSysPAddr, -+ IMG_VOID *pvLinAddr, -+ IMG_UINT32 ui32Flags, -+ PVRSRV_CLIENT_MEM_INFO **ppsMemInfo); -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVUnwrapExtMemory (IMG_CONST PVRSRV_DEV_DATA *psDevData, -+ PVRSRV_CLIENT_MEM_INFO *psMemInfo); -+ -+PVRSRV_ERROR PVRSRVChangeDeviceMemoryAttributes(IMG_CONST PVRSRV_DEV_DATA *psDevData, -+ PVRSRV_CLIENT_MEM_INFO *psClientMemInfo, -+ IMG_UINT32 ui32Attribs); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceClassMemory (IMG_CONST PVRSRV_DEV_DATA *psDevData, -+ IMG_HANDLE hDevMemContext, -+ IMG_HANDLE hDeviceClassBuffer, -+ PVRSRV_CLIENT_MEM_INFO **ppsMemInfo); -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapDeviceClassMemory (IMG_CONST PVRSRV_DEV_DATA *psDevData, -+ PVRSRV_CLIENT_MEM_INFO *psMemInfo); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVMapPhysToUserSpace(IMG_CONST PVRSRV_DEV_DATA *psDevData, -+ IMG_SYS_PHYADDR sSysPhysAddr, -+ IMG_UINT32 uiSizeInBytes, -+ IMG_PVOID *ppvUserAddr, -+ IMG_UINT32 *puiActualSize, -+ IMG_PVOID *ppvProcess); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapPhysToUserSpace(IMG_CONST PVRSRV_DEV_DATA *psDevData, -+ IMG_PVOID pvUserAddr, -+ IMG_PVOID pvProcess); -+ -+#if defined(LINUX) -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVExportDeviceMem2(IMG_CONST PVRSRV_DEV_DATA *psDevData, -+ PVRSRV_CLIENT_MEM_INFO *psMemInfo, -+ IMG_INT *iFd); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceMemory2(IMG_CONST PVRSRV_DEV_DATA *psDevData, -+ IMG_INT iFd, -+ IMG_HANDLE hDstDevMemHeap, -+ PVRSRV_CLIENT_MEM_INFO **ppsDstMemInfo); -+#endif /* defined(LINUX) */ -+ -+#if defined(SUPPORT_ION) -+PVRSRV_ERROR PVRSRVMapIonHandle(const PVRSRV_DEV_DATA *psDevData, -+ IMG_HANDLE hDevMemHeap, -+ IMG_UINT32 ui32NumFDs, -+ IMG_INT *paiBufferFDs, -+ IMG_UINT32 ui32ChunkCount, -+ IMG_SIZE_T *pauiOffset, -+ IMG_SIZE_T *pauiSize, -+ IMG_UINT32 ui32Attribs, -+ PVRSRV_CLIENT_MEM_INFO **ppsMemInfo); -+ -+PVRSRV_ERROR PVRSRVUnmapIonHandle(const PVRSRV_DEV_DATA *psDevData, -+ PVRSRV_CLIENT_MEM_INFO *psMemInfo); -+#endif /* defined (SUPPORT_ION) */ -+ -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVAllocDeviceMemSparse(const PVRSRV_DEV_DATA *psDevData, -+ IMG_HANDLE hDevMemHeap, -+ IMG_UINT32 ui32Attribs, -+ IMG_SIZE_T uAlignment, -+ IMG_UINT32 ui32ChunkSize, -+ IMG_UINT32 ui32NumVirtChunks, -+ IMG_UINT32 ui32NumPhysChunks, -+ IMG_BOOL *pabMapChunk, -+ PVRSRV_CLIENT_MEM_INFO **ppsMemInfo); -+ -+/****************************************************************************** -+ * PVR Allocation Synchronisation Functionality... -+ *****************************************************************************/ -+ -+typedef enum _PVRSRV_SYNCVAL_MODE_ -+{ -+ PVRSRV_SYNCVAL_READ = IMG_TRUE, -+ PVRSRV_SYNCVAL_WRITE = IMG_FALSE, -+ -+} PVRSRV_SYNCVAL_MODE, *PPVRSRV_SYNCVAL_MODE; -+ -+typedef IMG_UINT32 PVRSRV_SYNCVAL; -+ -+IMG_IMPORT PVRSRV_ERROR PVRSRVWaitForOpsComplete(PPVRSRV_CLIENT_MEM_INFO psMemInfo, -+ PVRSRV_SYNCVAL_MODE eMode, PVRSRV_SYNCVAL OpRequired); -+ -+IMG_IMPORT PVRSRV_ERROR PVRSRVWaitForAllOpsComplete(PPVRSRV_CLIENT_MEM_INFO psMemInfo, -+ PVRSRV_SYNCVAL_MODE eMode); -+ -+IMG_IMPORT IMG_BOOL PVRSRVTestOpsComplete(PPVRSRV_CLIENT_MEM_INFO psMemInfo, -+ PVRSRV_SYNCVAL_MODE eMode, PVRSRV_SYNCVAL OpRequired); -+ -+IMG_IMPORT IMG_BOOL PVRSRVTestAllOpsComplete(PPVRSRV_CLIENT_MEM_INFO psMemInfo, -+ PVRSRV_SYNCVAL_MODE eMode); -+ -+IMG_IMPORT IMG_BOOL PVRSRVTestOpsNotComplete(PPVRSRV_CLIENT_MEM_INFO psMemInfo, -+ PVRSRV_SYNCVAL_MODE eMode, PVRSRV_SYNCVAL OpRequired); -+ -+IMG_IMPORT IMG_BOOL PVRSRVTestAllOpsNotComplete(PPVRSRV_CLIENT_MEM_INFO psMemInfo, -+ PVRSRV_SYNCVAL_MODE eMode); -+ -+IMG_IMPORT PVRSRV_SYNCVAL PVRSRVGetPendingOpSyncVal(PPVRSRV_CLIENT_MEM_INFO psMemInfo, -+ PVRSRV_SYNCVAL_MODE eMode); -+ -+ -+/****************************************************************************** -+ * Common Device Class Enumeration -+ *****************************************************************************/ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumerateDeviceClass(IMG_CONST PVRSRV_CONNECTION *psConnection, -+ PVRSRV_DEVICE_CLASS DeviceClass, -+ IMG_UINT32 *pui32DevCount, -+ IMG_UINT32 *pui32DevID); -+ -+/****************************************************************************** -+ * Display Device Class API definition -+ *****************************************************************************/ -+IMG_IMPORT -+IMG_HANDLE IMG_CALLCONV PVRSRVOpenDCDevice(IMG_CONST PVRSRV_DEV_DATA *psDevData, -+ IMG_UINT32 ui32DeviceID); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVCloseDCDevice(IMG_CONST PVRSRV_CONNECTION *psConnection, IMG_HANDLE hDevice); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumDCFormats (IMG_HANDLE hDevice, -+ IMG_UINT32 *pui32Count, -+ DISPLAY_FORMAT *psFormat); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumDCDims (IMG_HANDLE hDevice, -+ IMG_UINT32 *pui32Count, -+ DISPLAY_FORMAT *psFormat, -+ DISPLAY_DIMS *psDims); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDCSystemBuffer(IMG_HANDLE hDevice, -+ IMG_HANDLE *phBuffer -+ ); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDCInfo(IMG_HANDLE hDevice, -+ DISPLAY_INFO* psDisplayInfo); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateDCSwapChain (IMG_HANDLE hDevice, -+ IMG_UINT32 ui32Flags, -+ DISPLAY_SURF_ATTRIBUTES *psDstSurfAttrib, -+ DISPLAY_SURF_ATTRIBUTES *psSrcSurfAttrib, -+ IMG_UINT32 ui32BufferCount, -+ IMG_UINT32 ui32OEMFlags, -+ IMG_UINT32 *pui32SwapChainID, -+ IMG_HANDLE *phSwapChain -+ ); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyDCSwapChain (IMG_HANDLE hDevice, -+ IMG_HANDLE hSwapChain -+ ); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVSetDCDstRect (IMG_HANDLE hDevice, -+ IMG_HANDLE hSwapChain, -+ IMG_RECT *psDstRect); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVSetDCSrcRect (IMG_HANDLE hDevice, -+ IMG_HANDLE hSwapChain, -+ IMG_RECT *psSrcRect); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVSetDCDstColourKey (IMG_HANDLE hDevice, -+ IMG_HANDLE hSwapChain, -+ IMG_UINT32 ui32CKColour); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVSetDCSrcColourKey (IMG_HANDLE hDevice, -+ IMG_HANDLE hSwapChain, -+ IMG_UINT32 ui32CKColour); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDCBuffers(IMG_HANDLE hDevice, -+ IMG_HANDLE hSwapChain, -+ IMG_HANDLE *phBuffer -+ ); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDCBuffers2(IMG_HANDLE hDevice, -+ IMG_HANDLE hSwapChain, -+ IMG_HANDLE *phBuffer, -+ IMG_SYS_PHYADDR *psPhyAddr); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVSwapToDCBuffer (IMG_HANDLE hDevice, -+ IMG_HANDLE hBuffer, -+ IMG_UINT32 ui32ClipRectCount, -+ IMG_RECT *psClipRect, -+ IMG_UINT32 ui32SwapInterval, -+ IMG_HANDLE hPrivateTag -+ ); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVSwapToDCBuffer2 (IMG_HANDLE hDevice, -+ IMG_HANDLE hBuffer, -+ IMG_UINT32 ui32SwapInterval, -+ PVRSRV_CLIENT_MEM_INFO **ppsMemInfos, -+ PVRSRV_CLIENT_SYNC_INFO **ppsSyncInfos, -+ IMG_UINT32 ui32NumMemSyncInfos, -+ IMG_PVOID pvPrivData, -+ IMG_UINT32 ui32PrivDataLength, -+ IMG_HANDLE *phFence); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVSwapToDCSystem (IMG_HANDLE hDevice, -+ IMG_HANDLE hSwapChain -+ ); -+ -+/****************************************************************************** -+ * Buffer Device Class API definition -+ *****************************************************************************/ -+IMG_IMPORT -+IMG_HANDLE IMG_CALLCONV PVRSRVOpenBCDevice(IMG_CONST PVRSRV_DEV_DATA *psDevData, -+ IMG_UINT32 ui32DeviceID); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVCloseBCDevice(IMG_CONST PVRSRV_CONNECTION *psConnection, -+ IMG_HANDLE hDevice); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetBCBufferInfo(IMG_HANDLE hDevice, -+ BUFFER_INFO *psBuffer); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetBCBuffer(IMG_HANDLE hDevice, -+ IMG_UINT32 ui32BufferIndex, -+ IMG_HANDLE *phBuffer -+ ); -+ -+ -+/****************************************************************************** -+ * PDUMP Function prototypes... -+ *****************************************************************************/ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpInit(IMG_CONST PVRSRV_CONNECTION *psConnection); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpStartInitPhase(IMG_CONST PVRSRV_CONNECTION *psConnection); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpStopInitPhase(IMG_CONST PVRSRV_CONNECTION *psConnection); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpMemPol(IMG_CONST PVRSRV_CONNECTION *psConnection, -+ PVRSRV_CLIENT_MEM_INFO *psMemInfo, -+ IMG_UINT32 ui32Offset, -+ IMG_UINT32 ui32Value, -+ IMG_UINT32 ui32Mask, -+ PDUMP_POLL_OPERATOR eOperator, -+ IMG_UINT32 ui32Flags); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpSyncPol(IMG_CONST PVRSRV_CONNECTION *psConnection, -+ PVRSRV_CLIENT_SYNC_INFO *psClientSyncInfo, -+ IMG_BOOL bIsRead, -+ IMG_UINT32 ui32Value, -+ IMG_UINT32 ui32Mask); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpSyncPol2(IMG_CONST PVRSRV_CONNECTION *psConnection, -+ PVRSRV_CLIENT_SYNC_INFO *psClientSyncInfo, -+ IMG_BOOL bIsRead); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpMem(IMG_CONST PVRSRV_CONNECTION *psConnection, -+ IMG_PVOID pvAltLinAddr, -+ PVRSRV_CLIENT_MEM_INFO *psMemInfo, -+ IMG_UINT32 ui32Offset, -+ IMG_UINT32 ui32Bytes, -+ IMG_UINT32 ui32Flags); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpSync(IMG_CONST PVRSRV_CONNECTION *psConnection, -+ IMG_PVOID pvAltLinAddr, -+ PVRSRV_CLIENT_SYNC_INFO *psClientSyncInfo, -+ IMG_UINT32 ui32Offset, -+ IMG_UINT32 ui32Bytes); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpReg(IMG_CONST PVRSRV_DEV_DATA *psDevData, -+ IMG_CHAR *pszRegRegion, -+ IMG_UINT32 ui32RegAddr, -+ IMG_UINT32 ui32RegValue, -+ IMG_UINT32 ui32Flags); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpRegPolWithFlags(const PVRSRV_DEV_DATA *psDevData, -+ IMG_CHAR *pszRegRegion, -+ IMG_UINT32 ui32RegAddr, -+ IMG_UINT32 ui32RegValue, -+ IMG_UINT32 ui32Mask, -+ IMG_UINT32 ui32Flags); -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpRegPol(const PVRSRV_DEV_DATA *psDevData, -+ IMG_CHAR *pszRegRegion, -+ IMG_UINT32 ui32RegAddr, -+ IMG_UINT32 ui32RegValue, -+ IMG_UINT32 ui32Mask); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpPDReg(IMG_CONST PVRSRV_CONNECTION *psConnection, -+ IMG_UINT32 ui32RegAddr, -+ IMG_UINT32 ui32RegValue); -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpPDDevPAddr(IMG_CONST PVRSRV_CONNECTION *psConnection, -+ PVRSRV_CLIENT_MEM_INFO *psMemInfo, -+ IMG_UINT32 ui32Offset, -+ IMG_DEV_PHYADDR sPDDevPAddr); -+ -+#if !defined(USE_CODE) -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpMemPages(IMG_CONST PVRSRV_DEV_DATA *psDevData, -+ IMG_HANDLE hKernelMemInfo, -+ IMG_DEV_PHYADDR *pPages, -+ IMG_UINT32 ui32NumPages, -+ IMG_DEV_VIRTADDR sDevVAddr, -+ IMG_UINT32 ui32Start, -+ IMG_UINT32 ui32Length, -+ IMG_UINT32 ui32Flags); -+#endif -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpSetFrame(IMG_CONST PVRSRV_CONNECTION *psConnection, -+ IMG_UINT32 ui32Frame); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpComment(IMG_CONST PVRSRV_CONNECTION *psConnection, -+ IMG_CONST IMG_CHAR *pszComment, -+ IMG_BOOL bContinuous); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpCommentf(IMG_CONST PVRSRV_CONNECTION *psConnection, -+ IMG_BOOL bContinuous, -+ IMG_CONST IMG_CHAR *pszFormat, ...) -+#if !defined(USE_CODE) -+ IMG_FORMAT_PRINTF(3, 4) -+#endif -+; -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpCommentWithFlagsf(IMG_CONST PVRSRV_CONNECTION *psConnection, -+ IMG_UINT32 ui32Flags, -+ IMG_CONST IMG_CHAR *pszFormat, ...) -+#if !defined(USE_CODE) -+ IMG_FORMAT_PRINTF(3, 4) -+#endif -+; -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpDriverInfo(IMG_CONST PVRSRV_CONNECTION *psConnection, -+ IMG_CHAR *pszString, -+ IMG_BOOL bContinuous); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpIsCapturing(IMG_CONST PVRSRV_CONNECTION *psConnection, -+ IMG_BOOL *pbIsCapturing); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpBitmap(IMG_CONST PVRSRV_DEV_DATA *psDevData, -+ IMG_CHAR *pszFileName, -+ IMG_UINT32 ui32FileOffset, -+ IMG_UINT32 ui32Width, -+ IMG_UINT32 ui32Height, -+ IMG_UINT32 ui32StrideInBytes, -+ IMG_DEV_VIRTADDR sDevBaseAddr, -+ IMG_HANDLE hDevMemContext, -+ IMG_UINT32 ui32Size, -+ PDUMP_PIXEL_FORMAT ePixelFormat, -+ PDUMP_MEM_FORMAT eMemFormat, -+ IMG_UINT32 ui32PDumpFlags); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpRegRead(IMG_CONST PVRSRV_DEV_DATA *psDevData, -+ IMG_CONST IMG_CHAR *pszRegRegion, -+ IMG_CONST IMG_CHAR *pszFileName, -+ IMG_UINT32 ui32FileOffset, -+ IMG_UINT32 ui32Address, -+ IMG_UINT32 ui32Size, -+ IMG_UINT32 ui32PDumpFlags); -+ -+ -+IMG_IMPORT -+IMG_BOOL IMG_CALLCONV PVRSRVPDumpIsCapturingTest(IMG_CONST PVRSRV_CONNECTION *psConnection); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVPDumpCycleCountRegRead(IMG_CONST PVRSRV_DEV_DATA *psDevData, -+ IMG_UINT32 ui32RegOffset, -+ IMG_BOOL bLastFrame); -+ -+IMG_IMPORT IMG_HANDLE PVRSRVLoadLibrary(const IMG_CHAR *pszLibraryName); -+IMG_IMPORT PVRSRV_ERROR PVRSRVUnloadLibrary(IMG_HANDLE hExtDrv); -+IMG_IMPORT PVRSRV_ERROR PVRSRVGetLibFuncAddr(IMG_HANDLE hExtDrv, const IMG_CHAR *pszFunctionName, IMG_VOID **ppvFuncAddr); -+ -+IMG_IMPORT IMG_UINT32 PVRSRVClockus (void); -+IMG_IMPORT IMG_VOID PVRSRVWaitus (IMG_UINT32 ui32Timeus); -+IMG_IMPORT IMG_VOID PVRSRVReleaseThreadQuanta (void); -+IMG_IMPORT IMG_UINT32 IMG_CALLCONV PVRSRVGetCurrentProcessID(void); -+IMG_IMPORT IMG_CHAR * IMG_CALLCONV PVRSRVSetLocale(const IMG_CHAR *pszLocale); -+ -+ -+ -+ -+ -+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVCreateAppHintState(IMG_MODULE_ID eModuleID, -+ const IMG_CHAR *pszAppName, -+ IMG_VOID **ppvState); -+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVFreeAppHintState(IMG_MODULE_ID eModuleID, -+ IMG_VOID *pvHintState); -+ -+IMG_IMPORT IMG_BOOL IMG_CALLCONV PVRSRVGetAppHint(IMG_VOID *pvHintState, -+ const IMG_CHAR *pszHintName, -+ IMG_DATA_TYPE eDataType, -+ const IMG_VOID *pvDefault, -+ IMG_VOID *pvReturn); -+ -+/****************************************************************************** -+ * Memory API(s) -+ *****************************************************************************/ -+ -+/* Exported APIs */ -+IMG_IMPORT IMG_PVOID IMG_CALLCONV PVRSRVAllocUserModeMem (IMG_SIZE_T uiSize); -+IMG_IMPORT IMG_PVOID IMG_CALLCONV PVRSRVCallocUserModeMem (IMG_SIZE_T uiSize); -+IMG_IMPORT IMG_PVOID IMG_CALLCONV PVRSRVReallocUserModeMem (IMG_PVOID pvBase, IMG_SIZE_T uiNewSize); -+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVFreeUserModeMem (IMG_PVOID pvMem); -+IMG_IMPORT IMG_VOID PVRSRVMemCopy(IMG_VOID *pvDst, const IMG_VOID *pvSrc, IMG_SIZE_T uiSize); -+IMG_IMPORT IMG_VOID PVRSRVMemSet(IMG_VOID *pvDest, IMG_UINT8 ui8Value, IMG_SIZE_T uiSize); -+ -+struct _PVRSRV_MUTEX_OPAQUE_STRUCT_; -+typedef struct _PVRSRV_MUTEX_OPAQUE_STRUCT_ *PVRSRV_MUTEX_HANDLE; -+ -+ -+#if defined(PVR_DEBUG_MUTEXES) -+ -+IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateMutex(PVRSRV_MUTEX_HANDLE *phMutex, -+ IMG_CHAR pszMutexName[], -+ IMG_CHAR pszFilename[], -+ IMG_INT iLine); -+IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyMutex(PVRSRV_MUTEX_HANDLE hMutex, -+ IMG_CHAR pszMutexName[], -+ IMG_CHAR pszFilename[], -+ IMG_INT iLine); -+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVLockMutex(PVRSRV_MUTEX_HANDLE hMutex, -+ IMG_CHAR pszMutexName[], -+ IMG_CHAR pszFilename[], -+ IMG_INT iLine); -+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVUnlockMutex(PVRSRV_MUTEX_HANDLE hMutex, -+ IMG_CHAR pszMutexName[], -+ IMG_CHAR pszFilename[], -+ IMG_INT iLine); -+ -+#define PVRSRVCreateMutex(phMutex) PVRSRVCreateMutex(phMutex, #phMutex, __FILE__, __LINE__) -+#define PVRSRVDestroyMutex(hMutex) PVRSRVDestroyMutex(hMutex, #hMutex, __FILE__, __LINE__) -+#define PVRSRVLockMutex(hMutex) PVRSRVLockMutex(hMutex, #hMutex, __FILE__, __LINE__) -+#define PVRSRVUnlockMutex(hMutex) PVRSRVUnlockMutex(hMutex, #hMutex, __FILE__, __LINE__) -+ -+#else /* defined(PVR_DEBUG_MUTEXES) */ -+ -+IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateMutex(PVRSRV_MUTEX_HANDLE *phMutex); -+IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyMutex(PVRSRV_MUTEX_HANDLE hMutex); -+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVLockMutex(PVRSRV_MUTEX_HANDLE hMutex); -+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVUnlockMutex(PVRSRV_MUTEX_HANDLE hMutex); -+ -+#endif /* defined(PVR_DEBUG_MUTEXES) */ -+ -+ -+struct _PVRSRV_RECMUTEX_OPAQUE_STRUCT_; -+typedef struct _PVRSRV_RECMUTEX_OPAQUE_STRUCT_ *PVRSRV_RECMUTEX_HANDLE; -+ -+ -+#if defined(PVR_DEBUG_MUTEXES) -+ -+IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateRecursiveMutex(PVRSRV_RECMUTEX_HANDLE *phMutex, -+ IMG_CHAR pszMutexName[], -+ IMG_CHAR pszFilename[], -+ IMG_INT iLine); -+IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyRecursiveMutex(PVRSRV_RECMUTEX_HANDLE hMutex, -+ IMG_CHAR pszMutexName[], -+ IMG_CHAR pszFilename[], -+ IMG_INT iLine); -+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVLockRecursiveMutex(PVRSRV_RECMUTEX_HANDLE hMutex, -+ IMG_CHAR pszMutexName[], -+ IMG_CHAR pszFilename[], -+ IMG_INT iLine); -+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVUnlockRecursiveMutex(PVRSRV_RECMUTEX_HANDLE hMutex, -+ IMG_CHAR pszMutexName[], -+ IMG_CHAR pszFilename[], -+ IMG_INT iLine); -+ -+#define PVRSRVCreateRecursiveMutex(phMutex) PVRSRVCreateRecursiveMutex(phMutex, #phMutex, __FILE__, __LINE__) -+#define PVRSRVDestroyRecursiveMutex(hMutex) PVRSRVDestroyRecursiveMutex(hMutex, #hMutex, __FILE__, __LINE__) -+#define PVRSRVLockRecursiveMutex(hMutex) PVRSRVLockRecursiveMutex(hMutex, #hMutex, __FILE__, __LINE__) -+#define PVRSRVUnlockRecursiveMutex(hMutex) PVRSRVUnlockRecursiveMutex(hMutex, #hMutex, __FILE__, __LINE__) -+ -+#else /* defined(PVR_DEBUG_MUTEXES) */ -+ -+IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateRecursiveMutex(PVRSRV_RECMUTEX_HANDLE *phMutex); -+IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyRecursiveMutex(PVRSRV_RECMUTEX_HANDLE hMutex); -+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVLockRecursiveMutex(PVRSRV_RECMUTEX_HANDLE hMutex); -+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVUnlockRecursiveMutex(PVRSRV_RECMUTEX_HANDLE hMutex); -+ -+#endif /* defined(PVR_DEBUG_MUTEXES) */ -+ -+/* Non-recursive coarse-grained mutex shared between all threads in a proccess */ -+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVLockProcessGlobalMutex(void); -+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVUnlockProcessGlobalMutex(void); -+ -+ -+struct _PVRSRV_SEMAPHORE_OPAQUE_STRUCT_; -+typedef struct _PVRSRV_SEMAPHORE_OPAQUE_STRUCT_ *PVRSRV_SEMAPHORE_HANDLE; -+ -+ -+ #define IMG_SEMAPHORE_WAIT_INFINITE ((IMG_UINT64)0xFFFFFFFFFFFFFFFFull) -+ -+ -+#if !defined(USE_CODE) -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(PVRSRVCreateSemaphore) -+#endif -+static INLINE PVRSRV_ERROR PVRSRVCreateSemaphore(PVRSRV_SEMAPHORE_HANDLE *phSemaphore, IMG_INT iInitialCount) -+{ -+ PVR_UNREFERENCED_PARAMETER(iInitialCount); -+ *phSemaphore = 0; -+ return PVRSRV_OK; -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(PVRSRVDestroySemaphore) -+#endif -+static INLINE PVRSRV_ERROR PVRSRVDestroySemaphore(PVRSRV_SEMAPHORE_HANDLE hSemaphore) -+{ -+ PVR_UNREFERENCED_PARAMETER(hSemaphore); -+ return PVRSRV_OK; -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(PVRSRVWaitSemaphore) -+#endif -+static INLINE PVRSRV_ERROR PVRSRVWaitSemaphore(PVRSRV_SEMAPHORE_HANDLE hSemaphore, IMG_UINT64 ui64TimeoutMicroSeconds) -+{ -+ PVR_UNREFERENCED_PARAMETER(hSemaphore); -+ PVR_UNREFERENCED_PARAMETER(ui64TimeoutMicroSeconds); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(PVRSRVPostSemaphore) -+#endif -+static INLINE IMG_VOID PVRSRVPostSemaphore(PVRSRV_SEMAPHORE_HANDLE hSemaphore, IMG_INT iPostCount) -+{ -+ PVR_UNREFERENCED_PARAMETER(hSemaphore); -+ PVR_UNREFERENCED_PARAMETER(iPostCount); -+} -+ -+#endif /* !defined(USE_CODE) */ -+ -+ -+/* Non-exported APIs */ -+#if defined(DEBUG) && (defined(__linux__) || defined(__QNXNTO__) ) -+IMG_IMPORT IMG_PVOID IMG_CALLCONV PVRSRVAllocUserModeMemTracking(IMG_SIZE_T ui32Size, IMG_CHAR *pszFileName, IMG_UINT32 ui32LineNumber); -+ -+IMG_IMPORT IMG_PVOID IMG_CALLCONV PVRSRVCallocUserModeMemTracking(IMG_SIZE_T ui32Size, IMG_CHAR *pszFileName, IMG_UINT32 ui32LineNumber); -+ -+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVFreeUserModeMemTracking(IMG_VOID *pvMem); -+ -+IMG_IMPORT IMG_PVOID IMG_CALLCONV PVRSRVReallocUserModeMemTracking(IMG_VOID *pvMem, IMG_SIZE_T ui32NewSize, -+ IMG_CHAR *pszFileName, IMG_UINT32 ui32LineNumber); -+#endif -+ -+/****************************************************************************** -+ * PVR Event Object API(s) -+ *****************************************************************************/ -+ -+IMG_IMPORT PVRSRV_ERROR PVRSRVEventObjectWait(const PVRSRV_CONNECTION *psConnection, -+ IMG_HANDLE hOSEvent -+ ); -+ -+/*! -+ ****************************************************************************** -+ -+ @Function PVRSRVCreateSyncInfoModObj -+ -+ @Description Creates an empty Modification object to be later used by PVRSRVModifyPendingSyncOps -+ -+ ******************************************************************************/ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateSyncInfoModObj(const PVRSRV_CONNECTION *psConnection, -+ IMG_HANDLE *phKernelSyncInfoModObj -+ ); -+ -+/*! -+ ****************************************************************************** -+ -+ @Function PVRSRVDestroySyncInfoModObj -+ -+ @Description Destroys a Modification object. Must be empty. -+ -+ ******************************************************************************/ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroySyncInfoModObj(const PVRSRV_CONNECTION *psConnection, -+ IMG_HANDLE hKernelSyncInfoModObj -+ ); -+ -+ -+ -+/*! -+ ****************************************************************************** -+ -+ @Function PVRSRVModifyPendingSyncOps -+ -+ @Description Returns PRE-INCREMENTED sync op values. Performs thread safe increment -+ of sync ops values as specified by ui32ModifyFlags. -+ -+ PVRSRV_ERROR_RETRY is returned if the supplied modification object -+ is not empty. This is on the assumption that a different thread -+ will imminently call PVRSRVModifyCompleteSyncOps. This thread should -+ sleep before retrying. It should be regarded as an error if no such -+ other thread exists. -+ -+ Note that this API has implied locking semantics, as follows: -+ -+ PVRSRVModifyPendingSyncOps() -+ - announces an operation on the buffer is "pending", and -+ conceptually takes a ticket to represent your place in the queue. -+ - NB: ** exclusive access to the resource is _NOT_ granted at this time ** -+ PVRSRVSyncOpsFlushToModObj() -+ - ensures you have exclusive access to the resource (conceptually, a LOCK) -+ - the previously "pending" operation can now be regarded as "in progress" -+ PVRSRVModifyCompleteSyncOps() -+ - declares that the previously "in progress" operation is now complete. (UNLOCK) -+ -+ -+ ******************************************************************************/ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVModifyPendingSyncOps(const PVRSRV_CONNECTION *psConnection, -+ IMG_HANDLE hKernelSyncInfoModObj, -+ PVRSRV_CLIENT_SYNC_INFO *psSyncInfo, -+ IMG_UINT32 ui32ModifyFlags, -+ IMG_UINT32 *pui32ReadOpsPending, -+ IMG_UINT32 *pui32WriteOpsPending); -+ -+/*! -+ ****************************************************************************** -+ -+ @Function PVRSRVModifyCompleteSyncOps -+ -+ @Description Performs thread safe increment of sync ops values as specified -+ by the ui32ModifyFlags that were given to PVRSRVModifyPendingSyncOps. -+ The supplied Modification Object will become empty. -+ -+ Note that this API has implied locking semantics, as -+ described above in PVRSRVModifyPendingSyncOps -+ -+ ******************************************************************************/ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVModifyCompleteSyncOps(const PVRSRV_CONNECTION *psConnection, -+ IMG_HANDLE hKernelSyncInfoModObj -+ ); -+ -+/*! -+ ****************************************************************************** -+ -+ @Function PVRSRVSyncOpsTakeToken -+ -+ @Description Takes a "deli-counter" style token for future use with -+ PVRSRVSyncOpsFlushToToken(). In practice this means -+ recording a snapshot of the current "pending" values. A -+ future PVRSRVSyncOpsFlushToToken() will ensure that all -+ operations that were pending at the time of this -+ PVRSRVSyncOpsTakeToken() call will be flushed. -+ Operations may be subsequently queued after this call -+ and would not be flushed. The caller is required to -+ provide storage for the token. The token is disposable -+ - i.e. the caller can simply let the token go out of -+ scope without telling us... in particular, there is no -+ obligation to call PVRSRVSyncOpsFlushToToken(). -+ Multiple tokens may be taken. There is no implied -+ locking with this API. -+ -+ ******************************************************************************/ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVSyncOpsTakeToken(const PVRSRV_CONNECTION *psConnection, -+ const PVRSRV_CLIENT_SYNC_INFO *psSyncInfo, -+ PVRSRV_SYNC_TOKEN *psSyncToken); -+/*! -+ ****************************************************************************** -+ -+ @Function PVRSRVSyncOpsFlushToToken -+ -+ @Description Tests whether the dependencies for a pending sync op modification -+ have been satisfied. If this function returns PVRSRV_OK, then the -+ "complete" counts have caught up with the snapshot of the "pending" -+ values taken when PVRSRVSyncOpsTakeToken() was called. -+ In the event that the dependencies are not (yet) met, -+ this call will auto-retry if bWait is specified, otherwise, it will -+ return PVRSRV_ERROR_RETRY. (Not really an "error") -+ -+ (auto-retry behaviour not implemented) -+ -+ ******************************************************************************/ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVSyncOpsFlushToToken(const PVRSRV_CONNECTION *psConnection, -+ const PVRSRV_CLIENT_SYNC_INFO *psSyncInfo, -+ const PVRSRV_SYNC_TOKEN *psSyncToken, -+ IMG_BOOL bWait); -+/*! -+ ****************************************************************************** -+ -+ @Function PVRSRVSyncOpsFlushToModObj -+ -+ @Description Tests whether the dependencies for a pending sync op modification -+ have been satisfied. If this function returns PVRSRV_OK, then the -+ "complete" counts have caught up with the snapshot of the "pending" -+ values taken when PVRSRVModifyPendingSyncOps() was called. -+ PVRSRVModifyCompleteSyncOps() can then be called without risk of -+ stalling. In the event that the dependencies are not (yet) met, -+ this call will auto-retry if bWait is specified, otherwise, it will -+ return PVRSRV_ERROR_RETRY. (Not really an "error") -+ -+ Note that this API has implied locking semantics, as -+ described above in PVRSRVModifyPendingSyncOps -+ -+ ******************************************************************************/ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVSyncOpsFlushToModObj(const PVRSRV_CONNECTION *psConnection, -+ IMG_HANDLE hKernelSyncInfoModObj, -+ IMG_BOOL bWait); -+ -+/*! -+ ****************************************************************************** -+ -+ @Function PVRSRVSyncOpsFlushToDelta -+ -+ @Description Compares the number of outstanding operations (pending count minus -+ complete count) with the limit specified. If no more than ui32Delta -+ operations are outstanding, this function returns PVRSRV_OK. -+ In the event that there are too many outstanding operations, -+ this call will auto-retry if bWait is specified, otherwise, it will -+ return PVRSRV_ERROR_RETRY. (Not really an "error") -+ -+ ******************************************************************************/ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVSyncOpsFlushToDelta(const PVRSRV_CONNECTION *psConnection, -+ PVRSRV_CLIENT_SYNC_INFO *psClientSyncInfo, -+ IMG_UINT32 ui32Delta, -+ IMG_BOOL bWait); -+ -+/*! -+ ****************************************************************************** -+ -+ @Function PVRSRVAllocSyncInfo -+ -+ @Description Creates a Sync Object. Unlike the sync objects created -+ automatically with "PVRSRVAllocDeviceMem", the sync objects -+ returned by this function do _not_ have a UM mapping to the -+ sync data and they do _not_ have the device virtual address -+ of the "opscomplete" fields. These data are to be deprecated. -+ -+ ******************************************************************************/ -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVAllocSyncInfo(IMG_CONST PVRSRV_DEV_DATA *psDevData, -+ PVRSRV_CLIENT_SYNC_INFO **ppsSyncInfo); -+ -+/*! -+ ****************************************************************************** -+ -+ @Function PVRSRVFreeSyncInfo -+ -+ @Description Destroys a Sync Object created via -+ PVRSRVAllocSyncInfo. -+ -+ ******************************************************************************/ -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeSyncInfo(IMG_CONST PVRSRV_DEV_DATA *psDevData, -+ PVRSRV_CLIENT_SYNC_INFO *psSyncInfo); -+ -+/*! -+ ****************************************************************************** -+ -+ @Function PVRSRVGetErrorString -+ -+ @Description Returns a text string relating to the PVRSRV_ERROR enum. -+ -+ ******************************************************************************/ -+IMG_IMPORT -+const IMG_CHAR *PVRSRVGetErrorString(PVRSRV_ERROR eError); -+ -+ -+/*! -+ ****************************************************************************** -+ -+ @Function PVRSRVCacheInvalidate -+ -+ @Description Invalidate the CPU cache for a specified memory -+ area. Note that PVRSRVGetMiscInfo provides similar cpu -+ cache flush/invalidate functionality for some platforms. -+ -+ ******************************************************************************/ -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVCacheInvalidate(const PVRSRV_CONNECTION *psConnection, -+ IMG_PVOID pvLinearAddress, -+ IMG_UINT32 ui32Size); -+ -+/****************************************************************************** -+ Time wrapping macro -+******************************************************************************/ -+#define TIME_NOT_PASSED_UINT32(a,b,c) (((a) - (b)) < (c)) -+ -+#if defined (__cplusplus) -+} -+#endif -+#endif /* __SERVICES_H__ */ -+ -+/****************************************************************************** -+ End of file (services.h) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/include4/servicesext.h b/drivers/staging/ti-es8-sgx/include4/servicesext.h -new file mode 100644 -index 0000000..ea06f66 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/include4/servicesext.h -@@ -0,0 +1,961 @@ -+/*************************************************************************/ /*! -+@Title Services definitions required by external drivers -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Provides services data structures, defines and prototypes -+ required by external drivers. -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#if !defined (__SERVICESEXT_H__) -+#define __SERVICESEXT_H__ -+ -+/* -+ * Lock buffer read/write flags -+ */ -+#define PVRSRV_LOCKFLG_READONLY (1) /*!< The locking process will only read the locked surface */ -+ -+/*! -+ ***************************************************************************** -+ * Error values -+ * -+ * NOTE: If you change this, make sure you update the error texts in -+ * services4/include/pvrsrv_errors.h to match. -+ * -+ *****************************************************************************/ -+typedef enum _PVRSRV_ERROR_ -+{ -+ PVRSRV_OK = 0, -+ PVRSRV_ERROR_OUT_OF_MEMORY, -+ PVRSRV_ERROR_TOO_FEW_BUFFERS, -+ PVRSRV_ERROR_INVALID_PARAMS, -+ PVRSRV_ERROR_INIT_FAILURE, -+ PVRSRV_ERROR_CANT_REGISTER_CALLBACK, -+ PVRSRV_ERROR_INVALID_DEVICE, -+ PVRSRV_ERROR_NOT_OWNER, -+ PVRSRV_ERROR_BAD_MAPPING, -+ PVRSRV_ERROR_TIMEOUT, -+ PVRSRV_ERROR_FLIP_CHAIN_EXISTS, -+ PVRSRV_ERROR_INVALID_SWAPINTERVAL, -+ PVRSRV_ERROR_SCENE_INVALID, -+ PVRSRV_ERROR_STREAM_ERROR, -+ PVRSRV_ERROR_FAILED_DEPENDENCIES, -+ PVRSRV_ERROR_CMD_NOT_PROCESSED, -+ PVRSRV_ERROR_CMD_TOO_BIG, -+ PVRSRV_ERROR_DEVICE_REGISTER_FAILED, -+ PVRSRV_ERROR_TOOMANYBUFFERS, -+ PVRSRV_ERROR_NOT_SUPPORTED, -+ PVRSRV_ERROR_PROCESSING_BLOCKED, -+ -+ PVRSRV_ERROR_CANNOT_FLUSH_QUEUE, -+ PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE, -+ PVRSRV_ERROR_CANNOT_GET_RENDERDETAILS, -+ PVRSRV_ERROR_RETRY, -+ -+ PVRSRV_ERROR_DDK_VERSION_MISMATCH, -+ PVRSRV_ERROR_BUILD_MISMATCH, -+ PVRSRV_ERROR_CORE_REVISION_MISMATCH, -+ -+ PVRSRV_ERROR_UPLOAD_TOO_BIG, -+ -+ PVRSRV_ERROR_INVALID_FLAGS, -+ PVRSRV_ERROR_FAILED_TO_REGISTER_PROCESS, -+ -+ PVRSRV_ERROR_UNABLE_TO_LOAD_LIBRARY, -+ PVRSRV_ERROR_UNABLE_GET_FUNC_ADDR, -+ PVRSRV_ERROR_UNLOAD_LIBRARY_FAILED, -+ -+ PVRSRV_ERROR_BRIDGE_CALL_FAILED, -+ PVRSRV_ERROR_IOCTL_CALL_FAILED, -+ -+ PVRSRV_ERROR_MMU_CONTEXT_NOT_FOUND, -+ PVRSRV_ERROR_BUFFER_DEVICE_NOT_FOUND, -+ PVRSRV_ERROR_BUFFER_DEVICE_ALREADY_PRESENT, -+ -+ PVRSRV_ERROR_PCI_DEVICE_NOT_FOUND, -+ PVRSRV_ERROR_PCI_CALL_FAILED, -+ PVRSRV_ERROR_PCI_REGION_TOO_SMALL, -+ PVRSRV_ERROR_PCI_REGION_UNAVAILABLE, -+ PVRSRV_ERROR_BAD_REGION_SIZE_MISMATCH, -+ -+ PVRSRV_ERROR_REGISTER_BASE_NOT_SET, -+ -+ PVRSRV_ERROR_BM_BAD_SHAREMEM_HANDLE, -+ -+ PVRSRV_ERROR_FAILED_TO_ALLOC_USER_MEM, -+ PVRSRV_ERROR_FAILED_TO_ALLOC_VP_MEMORY, -+ PVRSRV_ERROR_FAILED_TO_MAP_SHARED_PBDESC, -+ PVRSRV_ERROR_FAILED_TO_GET_PHYS_ADDR, -+ -+ PVRSRV_ERROR_FAILED_TO_ALLOC_VIRT_MEMORY, -+ PVRSRV_ERROR_FAILED_TO_COPY_VIRT_MEMORY, -+ -+ PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES, -+ PVRSRV_ERROR_FAILED_TO_FREE_PAGES, -+ PVRSRV_ERROR_FAILED_TO_COPY_PAGES, -+ PVRSRV_ERROR_UNABLE_TO_LOCK_PAGES, -+ PVRSRV_ERROR_UNABLE_TO_UNLOCK_PAGES, -+ PVRSRV_ERROR_STILL_MAPPED, -+ PVRSRV_ERROR_MAPPING_NOT_FOUND, -+ PVRSRV_ERROR_PHYS_ADDRESS_EXCEEDS_32BIT, -+ PVRSRV_ERROR_FAILED_TO_MAP_PAGE_TABLE, -+ -+ PVRSRV_ERROR_INVALID_SEGMENT_BLOCK, -+ PVRSRV_ERROR_INVALID_SGXDEVDATA, -+ PVRSRV_ERROR_INVALID_DEVINFO, -+ PVRSRV_ERROR_INVALID_MEMINFO, -+ PVRSRV_ERROR_INVALID_MISCINFO, -+ PVRSRV_ERROR_UNKNOWN_IOCTL, -+ PVRSRV_ERROR_INVALID_CONTEXT, -+ PVRSRV_ERROR_UNABLE_TO_DESTROY_CONTEXT, -+ PVRSRV_ERROR_INVALID_HEAP, -+ PVRSRV_ERROR_INVALID_KERNELINFO, -+ PVRSRV_ERROR_UNKNOWN_POWER_STATE, -+ PVRSRV_ERROR_INVALID_HANDLE_TYPE, -+ PVRSRV_ERROR_INVALID_WRAP_TYPE, -+ PVRSRV_ERROR_INVALID_PHYS_ADDR, -+ PVRSRV_ERROR_INVALID_CPU_ADDR, -+ PVRSRV_ERROR_INVALID_HEAPINFO, -+ PVRSRV_ERROR_INVALID_PERPROC, -+ PVRSRV_ERROR_FAILED_TO_RETRIEVE_HEAPINFO, -+ PVRSRV_ERROR_INVALID_MAP_REQUEST, -+ PVRSRV_ERROR_INVALID_UNMAP_REQUEST, -+ PVRSRV_ERROR_UNABLE_TO_FIND_MAPPING_HEAP, -+ PVRSRV_ERROR_MAPPING_STILL_IN_USE, -+ -+ PVRSRV_ERROR_EXCEEDED_HW_LIMITS, -+ PVRSRV_ERROR_NO_STAGING_BUFFER_ALLOCATED, -+ -+ PVRSRV_ERROR_UNABLE_TO_CREATE_PERPROC_AREA, -+ PVRSRV_ERROR_UNABLE_TO_CREATE_EVENT, -+ PVRSRV_ERROR_UNABLE_TO_ENABLE_EVENT, -+ PVRSRV_ERROR_UNABLE_TO_REGISTER_EVENT, -+ PVRSRV_ERROR_UNABLE_TO_DESTROY_EVENT, -+ PVRSRV_ERROR_UNABLE_TO_CREATE_THREAD, -+ PVRSRV_ERROR_UNABLE_TO_CLOSE_THREAD, -+ PVRSRV_ERROR_THREAD_READ_ERROR, -+ PVRSRV_ERROR_UNABLE_TO_REGISTER_ISR_HANDLER, -+ PVRSRV_ERROR_UNABLE_TO_INSTALL_ISR, -+ PVRSRV_ERROR_UNABLE_TO_UNINSTALL_ISR, -+ PVRSRV_ERROR_ISR_ALREADY_INSTALLED, -+ PVRSRV_ERROR_ISR_NOT_INSTALLED, -+ PVRSRV_ERROR_UNABLE_TO_INITIALISE_INTERRUPT, -+ PVRSRV_ERROR_UNABLE_TO_RETRIEVE_INFO, -+ PVRSRV_ERROR_UNABLE_TO_DO_BACKWARDS_BLIT, -+ PVRSRV_ERROR_UNABLE_TO_CLOSE_SERVICES, -+ PVRSRV_ERROR_UNABLE_TO_REGISTER_CONTEXT, -+ PVRSRV_ERROR_UNABLE_TO_REGISTER_RESOURCE, -+ PVRSRV_ERROR_UNABLE_TO_CLOSE_HANDLE, -+ -+ PVRSRV_ERROR_INVALID_CCB_COMMAND, -+ -+ PVRSRV_ERROR_UNABLE_TO_LOCK_RESOURCE, -+ PVRSRV_ERROR_INVALID_LOCK_ID, -+ PVRSRV_ERROR_RESOURCE_NOT_LOCKED, -+ -+ PVRSRV_ERROR_FLIP_FAILED, -+ PVRSRV_ERROR_UNBLANK_DISPLAY_FAILED, -+ -+ PVRSRV_ERROR_TIMEOUT_POLLING_FOR_VALUE, -+ -+ PVRSRV_ERROR_CREATE_RENDER_CONTEXT_FAILED, -+ PVRSRV_ERROR_UNKNOWN_PRIMARY_FRAG, -+ PVRSRV_ERROR_UNEXPECTED_SECONDARY_FRAG, -+ PVRSRV_ERROR_UNEXPECTED_PRIMARY_FRAG, -+ -+ PVRSRV_ERROR_UNABLE_TO_INSERT_FENCE_ID, -+ -+ PVRSRV_ERROR_BLIT_SETUP_FAILED, -+ -+ PVRSRV_ERROR_PDUMP_NOT_AVAILABLE, -+ PVRSRV_ERROR_PDUMP_BUFFER_FULL, -+ PVRSRV_ERROR_PDUMP_BUF_OVERFLOW, -+ PVRSRV_ERROR_PDUMP_NOT_ACTIVE, -+ PVRSRV_ERROR_INCOMPLETE_LINE_OVERLAPS_PAGES, -+ -+ PVRSRV_ERROR_MUTEX_DESTROY_FAILED, -+ PVRSRV_ERROR_MUTEX_INTERRUPTIBLE_ERROR, -+ -+ PVRSRV_ERROR_INSUFFICIENT_SCRIPT_SPACE, -+ PVRSRV_ERROR_INSUFFICIENT_SPACE_FOR_COMMAND, -+ -+ PVRSRV_ERROR_PROCESS_NOT_INITIALISED, -+ PVRSRV_ERROR_PROCESS_NOT_FOUND, -+ PVRSRV_ERROR_SRV_CONNECT_FAILED, -+ PVRSRV_ERROR_SRV_DISCONNECT_FAILED, -+ PVRSRV_ERROR_DEINT_PHASE_FAILED, -+ PVRSRV_ERROR_INIT2_PHASE_FAILED, -+ -+ PVRSRV_ERROR_UNABLE_TO_FIND_RESOURCE, -+ -+ PVRSRV_ERROR_NO_DC_DEVICES_FOUND, -+ PVRSRV_ERROR_UNABLE_TO_OPEN_DC_DEVICE, -+ PVRSRV_ERROR_UNABLE_TO_REMOVE_DEVICE, -+ PVRSRV_ERROR_NO_DEVICEDATA_FOUND, -+ PVRSRV_ERROR_NO_DEVICENODE_FOUND, -+ PVRSRV_ERROR_NO_CLIENTNODE_FOUND, -+ PVRSRV_ERROR_FAILED_TO_PROCESS_QUEUE, -+ -+ PVRSRV_ERROR_UNABLE_TO_INIT_TASK, -+ PVRSRV_ERROR_UNABLE_TO_SCHEDULE_TASK, -+ PVRSRV_ERROR_UNABLE_TO_KILL_TASK, -+ -+ PVRSRV_ERROR_UNABLE_TO_ENABLE_TIMER, -+ PVRSRV_ERROR_UNABLE_TO_DISABLE_TIMER, -+ PVRSRV_ERROR_UNABLE_TO_REMOVE_TIMER, -+ -+ PVRSRV_ERROR_UNKNOWN_PIXEL_FORMAT, -+ PVRSRV_ERROR_UNKNOWN_SCRIPT_OPERATION, -+ -+ PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE, -+ PVRSRV_ERROR_HANDLE_NOT_ALLOCATED, -+ PVRSRV_ERROR_HANDLE_TYPE_MISMATCH, -+ PVRSRV_ERROR_UNABLE_TO_ADD_HANDLE, -+ PVRSRV_ERROR_HANDLE_NOT_SHAREABLE, -+ PVRSRV_ERROR_HANDLE_NOT_FOUND, -+ PVRSRV_ERROR_INVALID_SUBHANDLE, -+ PVRSRV_ERROR_HANDLE_BATCH_IN_USE, -+ PVRSRV_ERROR_HANDLE_BATCH_COMMIT_FAILURE, -+ -+ PVRSRV_ERROR_UNABLE_TO_CREATE_HASH_TABLE, -+ PVRSRV_ERROR_INSERT_HASH_TABLE_DATA_FAILED, -+ -+ PVRSRV_ERROR_UNSUPPORTED_BACKING_STORE, -+ PVRSRV_ERROR_UNABLE_TO_DESTROY_BM_HEAP, -+ -+ PVRSRV_ERROR_UNKNOWN_INIT_SERVER_STATE, -+ -+ PVRSRV_ERROR_NO_FREE_DEVICEIDS_AVALIABLE, -+ PVRSRV_ERROR_INVALID_DEVICEID, -+ PVRSRV_ERROR_DEVICEID_NOT_FOUND, -+ -+ PVRSRV_ERROR_MEMORY_TEST_FAILED, -+ PVRSRV_ERROR_CPUPADDR_TEST_FAILED, -+ PVRSRV_ERROR_COPY_TEST_FAILED, -+ -+ PVRSRV_ERROR_SEMAPHORE_NOT_INITIALISED, -+ -+ PVRSRV_ERROR_UNABLE_TO_RELEASE_CLOCK, -+ PVRSRV_ERROR_CLOCK_REQUEST_FAILED, -+ PVRSRV_ERROR_DISABLE_CLOCK_FAILURE, -+ PVRSRV_ERROR_UNABLE_TO_SET_CLOCK_RATE, -+ PVRSRV_ERROR_UNABLE_TO_ROUND_CLOCK_RATE, -+ PVRSRV_ERROR_UNABLE_TO_ENABLE_CLOCK, -+ PVRSRV_ERROR_UNABLE_TO_GET_CLOCK, -+ PVRSRV_ERROR_UNABLE_TO_GET_PARENT_CLOCK, -+ PVRSRV_ERROR_UNABLE_TO_GET_SYSTEM_CLOCK, -+ -+ PVRSRV_ERROR_UNKNOWN_SGL_ERROR, -+ -+ PVRSRV_ERROR_SYSTEM_POWER_CHANGE_FAILURE, -+ PVRSRV_ERROR_DEVICE_POWER_CHANGE_FAILURE, -+ -+ PVRSRV_ERROR_BAD_SYNC_STATE, -+ -+ PVRSRV_ERROR_CACHEOP_FAILED, -+ -+ PVRSRV_ERROR_CACHE_INVALIDATE_FAILED, -+ -+ PVRSRV_ERROR_FORCE_I32 = 0x7fffffff -+ -+} PVRSRV_ERROR; -+ -+ -+/*! -+ ***************************************************************************** -+ * List of known device classes. -+ *****************************************************************************/ -+typedef enum _PVRSRV_DEVICE_CLASS_ -+{ -+ PVRSRV_DEVICE_CLASS_3D = 0 , -+ PVRSRV_DEVICE_CLASS_DISPLAY = 1 , -+ PVRSRV_DEVICE_CLASS_BUFFER = 2 , -+ PVRSRV_DEVICE_CLASS_VIDEO = 3 , -+ -+ PVRSRV_DEVICE_CLASS_FORCE_I32 = 0x7fffffff -+ -+} PVRSRV_DEVICE_CLASS; -+ -+ -+/*! -+ ***************************************************************************** -+ * States for power management -+ *****************************************************************************/ -+typedef enum _PVRSRV_SYS_POWER_STATE_ -+{ -+ PVRSRV_SYS_POWER_STATE_Unspecified = -1, /*!< Unspecified : Uninitialised */ -+ PVRSRV_SYS_POWER_STATE_D0 = 0, /*!< On */ -+ PVRSRV_SYS_POWER_STATE_D1 = 1, /*!< User Idle */ -+ PVRSRV_SYS_POWER_STATE_D2 = 2, /*!< System Idle / sleep */ -+ PVRSRV_SYS_POWER_STATE_D3 = 3, /*!< Suspend / Hibernate */ -+ PVRSRV_SYS_POWER_STATE_D4 = 4, /*!< shutdown */ -+ -+ PVRSRV_SYS_POWER_STATE_FORCE_I32 = 0x7fffffff -+ -+} PVRSRV_SYS_POWER_STATE, *PPVRSRV_SYS_POWER_STATE; -+ -+ -+typedef enum _PVRSRV_DEV_POWER_STATE_ -+{ -+ PVRSRV_DEV_POWER_STATE_DEFAULT = -1, /*!< Default state for the device */ -+ PVRSRV_DEV_POWER_STATE_ON = 0, /*!< Running */ -+ PVRSRV_DEV_POWER_STATE_IDLE = 1, /*!< Powered but operation paused */ -+ PVRSRV_DEV_POWER_STATE_OFF = 2, /*!< Unpowered */ -+ -+ PVRSRV_DEV_POWER_STATE_FORCE_I32 = 0x7fffffff -+ -+} PVRSRV_DEV_POWER_STATE, *PPVRSRV_DEV_POWER_STATE; /* PRQA S 3205 */ -+ -+ -+/* Power transition handler prototypes */ -+typedef PVRSRV_ERROR (*PFN_PRE_POWER) (IMG_HANDLE hDevHandle, -+ PVRSRV_DEV_POWER_STATE eNewPowerState, -+ PVRSRV_DEV_POWER_STATE eCurrentPowerState); -+typedef PVRSRV_ERROR (*PFN_POST_POWER) (IMG_HANDLE hDevHandle, -+ PVRSRV_DEV_POWER_STATE eNewPowerState, -+ PVRSRV_DEV_POWER_STATE eCurrentPowerState); -+ -+/* Clock speed handler prototypes */ -+typedef PVRSRV_ERROR (*PFN_PRE_CLOCKSPEED_CHANGE) (IMG_HANDLE hDevHandle, -+ IMG_BOOL bIdleDevice, -+ PVRSRV_DEV_POWER_STATE eCurrentPowerState); -+typedef PVRSRV_ERROR (*PFN_POST_CLOCKSPEED_CHANGE) (IMG_HANDLE hDevHandle, -+ IMG_BOOL bIdleDevice, -+ PVRSRV_DEV_POWER_STATE eCurrentPowerState); -+ -+ -+/***************************************************************************** -+ * Enumeration of all possible pixel types. Where applicable, Ordering of name -+ * is in reverse order of memory bytes (i.e. as a word in little endian). -+ * e.g. A8R8G8B8 is in memory as 4 bytes in order: BB GG RR AA -+ * -+ * NOTE: When modifying this structure please update the client driver format -+ * tables located in %WORKROOT%/eurasia/codegen/pixfmts using the tool -+ * located in %WORKROOT%/eurasia/tools/intern/TextureFormatParser. -+ * -+ *****************************************************************************/ -+typedef enum _PVRSRV_PIXEL_FORMAT_ { -+ /* Basic types */ -+ PVRSRV_PIXEL_FORMAT_UNKNOWN = 0, -+ PVRSRV_PIXEL_FORMAT_RGB565 = 1, -+ PVRSRV_PIXEL_FORMAT_RGB555 = 2, -+ PVRSRV_PIXEL_FORMAT_RGB888 = 3, /*!< 24bit */ -+ PVRSRV_PIXEL_FORMAT_BGR888 = 4, /*!< 24bit */ -+ PVRSRV_PIXEL_FORMAT_GREY_SCALE = 8, -+ PVRSRV_PIXEL_FORMAT_PAL12 = 13, -+ PVRSRV_PIXEL_FORMAT_PAL8 = 14, -+ PVRSRV_PIXEL_FORMAT_PAL4 = 15, -+ PVRSRV_PIXEL_FORMAT_PAL2 = 16, -+ PVRSRV_PIXEL_FORMAT_PAL1 = 17, -+ PVRSRV_PIXEL_FORMAT_ARGB1555 = 18, -+ PVRSRV_PIXEL_FORMAT_ARGB4444 = 19, -+ PVRSRV_PIXEL_FORMAT_ARGB8888 = 20, -+ PVRSRV_PIXEL_FORMAT_ABGR8888 = 21, -+ PVRSRV_PIXEL_FORMAT_YV12 = 22, -+ PVRSRV_PIXEL_FORMAT_I420 = 23, -+ PVRSRV_PIXEL_FORMAT_IMC2 = 25, -+ PVRSRV_PIXEL_FORMAT_XRGB8888 = 26, -+ PVRSRV_PIXEL_FORMAT_XBGR8888 = 27, -+ PVRSRV_PIXEL_FORMAT_BGRA8888 = 28, -+ PVRSRV_PIXEL_FORMAT_XRGB4444 = 29, -+ PVRSRV_PIXEL_FORMAT_ARGB8332 = 30, -+ PVRSRV_PIXEL_FORMAT_A2RGB10 = 31, /*!< 32bpp, 10 bits for R, G, B, 2 bits for A */ -+ PVRSRV_PIXEL_FORMAT_A2BGR10 = 32, /*!< 32bpp, 10 bits for B, G, R, 2 bits for A */ -+ PVRSRV_PIXEL_FORMAT_P8 = 33, -+ PVRSRV_PIXEL_FORMAT_L8 = 34, -+ PVRSRV_PIXEL_FORMAT_A8L8 = 35, -+ PVRSRV_PIXEL_FORMAT_A4L4 = 36, -+ PVRSRV_PIXEL_FORMAT_L16 = 37, -+ PVRSRV_PIXEL_FORMAT_L6V5U5 = 38, -+ PVRSRV_PIXEL_FORMAT_V8U8 = 39, -+ PVRSRV_PIXEL_FORMAT_V16U16 = 40, -+ PVRSRV_PIXEL_FORMAT_QWVU8888 = 41, -+ PVRSRV_PIXEL_FORMAT_XLVU8888 = 42, -+ PVRSRV_PIXEL_FORMAT_QWVU16 = 43, -+ PVRSRV_PIXEL_FORMAT_D16 = 44, -+ PVRSRV_PIXEL_FORMAT_D24S8 = 45, -+ PVRSRV_PIXEL_FORMAT_D24X8 = 46, -+ -+ /* Added to ensure TQ build */ -+ PVRSRV_PIXEL_FORMAT_ABGR16 = 47, -+ PVRSRV_PIXEL_FORMAT_ABGR16F = 48, -+ PVRSRV_PIXEL_FORMAT_ABGR32 = 49, -+ PVRSRV_PIXEL_FORMAT_ABGR32F = 50, -+ PVRSRV_PIXEL_FORMAT_B10GR11 = 51, -+ PVRSRV_PIXEL_FORMAT_GR88 = 52, -+ PVRSRV_PIXEL_FORMAT_BGR32 = 53, -+ PVRSRV_PIXEL_FORMAT_GR32 = 54, -+ PVRSRV_PIXEL_FORMAT_E5BGR9 = 55, -+ -+ /* reserved types */ -+ PVRSRV_PIXEL_FORMAT_RESERVED1 = 56, -+ PVRSRV_PIXEL_FORMAT_RESERVED2 = 57, -+ PVRSRV_PIXEL_FORMAT_RESERVED3 = 58, -+ PVRSRV_PIXEL_FORMAT_RESERVED4 = 59, -+ PVRSRV_PIXEL_FORMAT_RESERVED5 = 60, -+ -+ /* RGB space packed formats */ -+ PVRSRV_PIXEL_FORMAT_R8G8_B8G8 = 61, -+ PVRSRV_PIXEL_FORMAT_G8R8_G8B8 = 62, -+ -+ /* YUV space planar formats */ -+ PVRSRV_PIXEL_FORMAT_NV11 = 63, -+ PVRSRV_PIXEL_FORMAT_NV12 = 64, -+ -+ /* YUV space packed formats */ -+ PVRSRV_PIXEL_FORMAT_YUY2 = 65, -+ PVRSRV_PIXEL_FORMAT_YUV420 = 66, -+ PVRSRV_PIXEL_FORMAT_YUV444 = 67, -+ PVRSRV_PIXEL_FORMAT_VUY444 = 68, -+ PVRSRV_PIXEL_FORMAT_YUYV = 69, -+ PVRSRV_PIXEL_FORMAT_YVYU = 70, -+ PVRSRV_PIXEL_FORMAT_UYVY = 71, -+ PVRSRV_PIXEL_FORMAT_VYUY = 72, -+ -+ PVRSRV_PIXEL_FORMAT_FOURCC_ORG_UYVY = 73, /*!< See http://www.fourcc.org/yuv.php#UYVY */ -+ PVRSRV_PIXEL_FORMAT_FOURCC_ORG_YUYV = 74, /*!< See http://www.fourcc.org/yuv.php#YUYV */ -+ PVRSRV_PIXEL_FORMAT_FOURCC_ORG_YVYU = 75, /*!< See http://www.fourcc.org/yuv.php#YVYU */ -+ PVRSRV_PIXEL_FORMAT_FOURCC_ORG_VYUY = 76, /*!< No fourcc.org link */ -+ PVRSRV_PIXEL_FORMAT_FOURCC_ORG_AYUV = 77, /*!< See http://www.fourcc.org/yuv.php#AYUV */ -+ -+ /* 4 component, 32 bits per component types */ -+ PVRSRV_PIXEL_FORMAT_A32B32G32R32 = 78, /*!< type unspecified */ -+ PVRSRV_PIXEL_FORMAT_A32B32G32R32F = 79, /*!< float type */ -+ PVRSRV_PIXEL_FORMAT_A32B32G32R32_UINT = 80, /*!< uint type */ -+ PVRSRV_PIXEL_FORMAT_A32B32G32R32_SINT = 81, /*!< sint type */ -+ -+ /* 3 component, 32 bits per component types */ -+ PVRSRV_PIXEL_FORMAT_B32G32R32 = 82, /*!< type unspecified */ -+ PVRSRV_PIXEL_FORMAT_B32G32R32F = 83, /*!< float data */ -+ PVRSRV_PIXEL_FORMAT_B32G32R32_UINT = 84, /*!< uint data */ -+ PVRSRV_PIXEL_FORMAT_B32G32R32_SINT = 85, /*!< signed int data */ -+ -+ /* 2 component, 32 bits per component types */ -+ PVRSRV_PIXEL_FORMAT_G32R32 = 86, /*!< type unspecified */ -+ PVRSRV_PIXEL_FORMAT_G32R32F = 87, /*!< float */ -+ PVRSRV_PIXEL_FORMAT_G32R32_UINT = 88, /*!< uint */ -+ PVRSRV_PIXEL_FORMAT_G32R32_SINT = 89, /*!< signed int */ -+ -+ /* 1 component, 32 bits per component types */ -+ PVRSRV_PIXEL_FORMAT_D32F = 90, /*!< float depth */ -+ PVRSRV_PIXEL_FORMAT_R32 = 91, /*!< type unspecified */ -+ PVRSRV_PIXEL_FORMAT_R32F = 92, /*!< float type */ -+ PVRSRV_PIXEL_FORMAT_R32_UINT = 93, /*!< unsigned int type */ -+ PVRSRV_PIXEL_FORMAT_R32_SINT = 94, /*!< signed int type */ -+ -+ /* 4 component, 16 bits per component types */ -+ PVRSRV_PIXEL_FORMAT_A16B16G16R16 = 95, /*!< type unspecified */ -+ PVRSRV_PIXEL_FORMAT_A16B16G16R16F = 96, /*!< type float */ -+ PVRSRV_PIXEL_FORMAT_A16B16G16R16_SINT = 97, /*!< signed ints */ -+ PVRSRV_PIXEL_FORMAT_A16B16G16R16_SNORM = 98, /*!< signed normalised int */ -+ PVRSRV_PIXEL_FORMAT_A16B16G16R16_UINT = 99, /*!< unsigned ints */ -+ PVRSRV_PIXEL_FORMAT_A16B16G16R16_UNORM = 100, /*!< normalised unsigned int */ -+ -+ /* 2 component, 16 bits per component types */ -+ PVRSRV_PIXEL_FORMAT_G16R16 = 101, /*!< unspecified type */ -+ PVRSRV_PIXEL_FORMAT_G16R16F = 102, /*!< float type */ -+ PVRSRV_PIXEL_FORMAT_G16R16_UINT = 103, /*!< unsigned int type */ -+ PVRSRV_PIXEL_FORMAT_G16R16_UNORM = 104, /*!< unsigned normalised */ -+ PVRSRV_PIXEL_FORMAT_G16R16_SINT = 105, /*!< signed int */ -+ PVRSRV_PIXEL_FORMAT_G16R16_SNORM = 106, /*!< signed normalised */ -+ -+ /* 1 component, 16 bits per component types */ -+ PVRSRV_PIXEL_FORMAT_R16 = 107, /*!< type unspecified */ -+ PVRSRV_PIXEL_FORMAT_R16F = 108, /*!< float type */ -+ PVRSRV_PIXEL_FORMAT_R16_UINT = 109, /*!< unsigned int type */ -+ PVRSRV_PIXEL_FORMAT_R16_UNORM = 110, /*!< unsigned normalised int type */ -+ PVRSRV_PIXEL_FORMAT_R16_SINT = 111, /*!< signed int type */ -+ PVRSRV_PIXEL_FORMAT_R16_SNORM = 112, /*!< signed normalised int type */ -+ -+ /* 4 component, 8 bits per component types */ -+ PVRSRV_PIXEL_FORMAT_X8R8G8B8 = 113, /*!< type unspecified */ -+ PVRSRV_PIXEL_FORMAT_X8R8G8B8_UNORM = 114, /*!< normalised unsigned int */ -+ PVRSRV_PIXEL_FORMAT_X8R8G8B8_UNORM_SRGB = 115, /*!< normalised uint with sRGB */ -+ -+ PVRSRV_PIXEL_FORMAT_A8R8G8B8 = 116, /*!< type unspecified */ -+ PVRSRV_PIXEL_FORMAT_A8R8G8B8_UNORM = 117, /*!< normalised unsigned int */ -+ PVRSRV_PIXEL_FORMAT_A8R8G8B8_UNORM_SRGB = 118, /*!< normalised uint with sRGB */ -+ -+ PVRSRV_PIXEL_FORMAT_A8B8G8R8 = 119, /*!< type unspecified */ -+ PVRSRV_PIXEL_FORMAT_A8B8G8R8_UINT = 120, /*!< unsigned int */ -+ PVRSRV_PIXEL_FORMAT_A8B8G8R8_UNORM = 121, /*!< normalised unsigned int */ -+ PVRSRV_PIXEL_FORMAT_A8B8G8R8_UNORM_SRGB = 122, /*!< normalised unsigned int */ -+ PVRSRV_PIXEL_FORMAT_A8B8G8R8_SINT = 123, /*!< signed int */ -+ PVRSRV_PIXEL_FORMAT_A8B8G8R8_SNORM = 124, /*!< normalised signed int */ -+ -+ /* 2 component, 8 bits per component types */ -+ PVRSRV_PIXEL_FORMAT_G8R8 = 125, /*!< type unspecified */ -+ PVRSRV_PIXEL_FORMAT_G8R8_UINT = 126, /*!< unsigned int type */ -+ PVRSRV_PIXEL_FORMAT_G8R8_UNORM = 127, /*!< unsigned int normalised */ -+ PVRSRV_PIXEL_FORMAT_G8R8_SINT = 128, /*!< signed int type */ -+ PVRSRV_PIXEL_FORMAT_G8R8_SNORM = 129, /*!< signed int normalised */ -+ -+ /* 1 component, 8 bits per component types */ -+ PVRSRV_PIXEL_FORMAT_A8 = 130, /*!< type unspecified, alpha channel */ -+ PVRSRV_PIXEL_FORMAT_R8 = 131, /*!< type unspecified */ -+ PVRSRV_PIXEL_FORMAT_R8_UINT = 132, /*!< unsigned int */ -+ PVRSRV_PIXEL_FORMAT_R8_UNORM = 133, /*!< unsigned normalised int */ -+ PVRSRV_PIXEL_FORMAT_R8_SINT = 134, /*!< signed int */ -+ PVRSRV_PIXEL_FORMAT_R8_SNORM = 135, /*!< signed normalised int */ -+ -+ /* A2RGB10 types */ -+ PVRSRV_PIXEL_FORMAT_A2B10G10R10 = 136, /*!< Type unspecified */ -+ PVRSRV_PIXEL_FORMAT_A2B10G10R10_UNORM = 137, /*!< normalised unsigned int */ -+ PVRSRV_PIXEL_FORMAT_A2B10G10R10_UINT = 138, /*!< unsigned int */ -+ -+ /* F11F11F10 types */ -+ PVRSRV_PIXEL_FORMAT_B10G11R11 = 139, /*!< type unspecified */ -+ PVRSRV_PIXEL_FORMAT_B10G11R11F = 140, /*!< float type */ -+ -+ /* esoteric types */ -+ PVRSRV_PIXEL_FORMAT_X24G8R32 = 141, /*!< 64 bit, type unspecified (Usually typed to D32S8 style) */ -+ PVRSRV_PIXEL_FORMAT_G8R24 = 142, /*!< 32 bit, type unspecified (Usually typed to D24S8 style) */ -+ PVRSRV_PIXEL_FORMAT_X8R24 = 143, -+ PVRSRV_PIXEL_FORMAT_E5B9G9R9 = 144, /*!< 32 bit, shared exponent (RGBE). */ -+ PVRSRV_PIXEL_FORMAT_R1 = 145, /*!< 1 bit monochrome */ -+ -+ PVRSRV_PIXEL_FORMAT_RESERVED6 = 146, -+ PVRSRV_PIXEL_FORMAT_RESERVED7 = 147, -+ PVRSRV_PIXEL_FORMAT_RESERVED8 = 148, -+ PVRSRV_PIXEL_FORMAT_RESERVED9 = 149, -+ PVRSRV_PIXEL_FORMAT_RESERVED10 = 150, -+ PVRSRV_PIXEL_FORMAT_RESERVED11 = 151, -+ PVRSRV_PIXEL_FORMAT_RESERVED12 = 152, -+ PVRSRV_PIXEL_FORMAT_RESERVED13 = 153, -+ PVRSRV_PIXEL_FORMAT_RESERVED14 = 154, -+ PVRSRV_PIXEL_FORMAT_RESERVED15 = 155, -+ PVRSRV_PIXEL_FORMAT_RESERVED16 = 156, -+ PVRSRV_PIXEL_FORMAT_RESERVED17 = 157, -+ PVRSRV_PIXEL_FORMAT_RESERVED18 = 158, -+ PVRSRV_PIXEL_FORMAT_RESERVED19 = 159, -+ PVRSRV_PIXEL_FORMAT_RESERVED20 = 160, -+ -+ /* DXLegacy vertex types */ -+ PVRSRV_PIXEL_FORMAT_UBYTE4 = 161, /*!< 4 channels, 1 byte per channel, normalised */ -+ PVRSRV_PIXEL_FORMAT_SHORT4 = 162, /*!< 4 signed channels, 16 bits each, unnormalised */ -+ PVRSRV_PIXEL_FORMAT_SHORT4N = 163, /*!< 4 signed channels, 16 bits each, normalised */ -+ PVRSRV_PIXEL_FORMAT_USHORT4N = 164, /*!< 4 unsigned channels, 16 bits each, normalised */ -+ PVRSRV_PIXEL_FORMAT_SHORT2N = 165, /*!< 2 signed channels, 16 bits each, normalised */ -+ PVRSRV_PIXEL_FORMAT_SHORT2 = 166, /*!< 2 signed channels, 16 bits each, unnormalised */ -+ PVRSRV_PIXEL_FORMAT_USHORT2N = 167, /*!< 2 unsigned channels, 16 bits each, normalised */ -+ PVRSRV_PIXEL_FORMAT_UDEC3 = 168, /*!< 3 10-bit channels, unnormalised, unsigned*/ -+ PVRSRV_PIXEL_FORMAT_DEC3N = 169, /*!< 3 10-bit channels, signed normalised */ -+ PVRSRV_PIXEL_FORMAT_F16_2 = 170, /*!< 2 F16 channels */ -+ PVRSRV_PIXEL_FORMAT_F16_4 = 171, /*!< 4 F16 channels */ -+ -+ /* misc float types */ -+ PVRSRV_PIXEL_FORMAT_L_F16 = 172, -+ PVRSRV_PIXEL_FORMAT_L_F16_REP = 173, -+ PVRSRV_PIXEL_FORMAT_L_F16_A_F16 = 174, -+ PVRSRV_PIXEL_FORMAT_A_F16 = 175, -+ PVRSRV_PIXEL_FORMAT_B16G16R16F = 176, -+ -+ PVRSRV_PIXEL_FORMAT_L_F32 = 177, -+ PVRSRV_PIXEL_FORMAT_A_F32 = 178, -+ PVRSRV_PIXEL_FORMAT_L_F32_A_F32 = 179, -+ -+ /* powervr types */ -+ PVRSRV_PIXEL_FORMAT_PVRTC2 = 180, -+ PVRSRV_PIXEL_FORMAT_PVRTC4 = 181, -+ PVRSRV_PIXEL_FORMAT_PVRTCII2 = 182, -+ PVRSRV_PIXEL_FORMAT_PVRTCII4 = 183, -+ PVRSRV_PIXEL_FORMAT_PVRTCIII = 184, -+ PVRSRV_PIXEL_FORMAT_PVRO8 = 185, -+ PVRSRV_PIXEL_FORMAT_PVRO88 = 186, -+ PVRSRV_PIXEL_FORMAT_PT1 = 187, -+ PVRSRV_PIXEL_FORMAT_PT2 = 188, -+ PVRSRV_PIXEL_FORMAT_PT4 = 189, -+ PVRSRV_PIXEL_FORMAT_PT8 = 190, -+ PVRSRV_PIXEL_FORMAT_PTW = 191, -+ PVRSRV_PIXEL_FORMAT_PTB = 192, -+ PVRSRV_PIXEL_FORMAT_MONO8 = 193, -+ PVRSRV_PIXEL_FORMAT_MONO16 = 194, -+ -+ /* additional YUV types */ -+ PVRSRV_PIXEL_FORMAT_C0_YUYV = 195, -+ PVRSRV_PIXEL_FORMAT_C0_UYVY = 196, -+ PVRSRV_PIXEL_FORMAT_C0_YVYU = 197, -+ PVRSRV_PIXEL_FORMAT_C0_VYUY = 198, -+ PVRSRV_PIXEL_FORMAT_C1_YUYV = 199, -+ PVRSRV_PIXEL_FORMAT_C1_UYVY = 200, -+ PVRSRV_PIXEL_FORMAT_C1_YVYU = 201, -+ PVRSRV_PIXEL_FORMAT_C1_VYUY = 202, -+ -+ /* planar YUV types */ -+ PVRSRV_PIXEL_FORMAT_C0_YUV420_2P_UV = 203, -+ PVRSRV_PIXEL_FORMAT_C0_YUV420_2P_VU = 204, -+ PVRSRV_PIXEL_FORMAT_C0_YUV420_3P = 205, -+ PVRSRV_PIXEL_FORMAT_C1_YUV420_2P_UV = 206, -+ PVRSRV_PIXEL_FORMAT_C1_YUV420_2P_VU = 207, -+ PVRSRV_PIXEL_FORMAT_C1_YUV420_3P = 208, -+ -+ PVRSRV_PIXEL_FORMAT_A2B10G10R10F = 209, -+ PVRSRV_PIXEL_FORMAT_B8G8R8_SINT = 210, -+ PVRSRV_PIXEL_FORMAT_PVRF32SIGNMASK = 211, -+ -+ PVRSRV_PIXEL_FORMAT_ABGR4444 = 212, -+ PVRSRV_PIXEL_FORMAT_ABGR1555 = 213, -+ PVRSRV_PIXEL_FORMAT_BGR565 = 214, -+ -+ /* 4k aligned planar YUV */ -+ PVRSRV_PIXEL_FORMAT_C0_4KYUV420_2P_UV = 215, -+ PVRSRV_PIXEL_FORMAT_C0_4KYUV420_2P_VU = 216, -+ PVRSRV_PIXEL_FORMAT_C1_4KYUV420_2P_UV = 217, -+ PVRSRV_PIXEL_FORMAT_C1_4KYUV420_2P_VU = 218, -+ PVRSRV_PIXEL_FORMAT_P208 = 219, -+ PVRSRV_PIXEL_FORMAT_A8P8 = 220, -+ -+ PVRSRV_PIXEL_FORMAT_A4 = 221, -+ PVRSRV_PIXEL_FORMAT_AYUV8888 = 222, -+ PVRSRV_PIXEL_FORMAT_RAW256 = 223, -+ PVRSRV_PIXEL_FORMAT_RAW512 = 224, -+ PVRSRV_PIXEL_FORMAT_RAW1024 = 225, -+ -+ /* Same as NV12 but with interleaved VU rather than interleaved UV */ -+ PVRSRV_PIXEL_FORMAT_NV21 = 226, -+ -+ PVRSRV_PIXEL_FORMAT_FORCE_I32 = 0x7fffffff -+ -+} PVRSRV_PIXEL_FORMAT; -+ -+/*! -+ ***************************************************************************** -+ * Enumeration of possible alpha types. -+ *****************************************************************************/ -+typedef enum _PVRSRV_ALPHA_FORMAT_ { -+ PVRSRV_ALPHA_FORMAT_UNKNOWN = 0x00000000, -+ PVRSRV_ALPHA_FORMAT_PRE = 0x00000001, -+ PVRSRV_ALPHA_FORMAT_NONPRE = 0x00000002, -+ PVRSRV_ALPHA_FORMAT_MASK = 0x0000000F, -+} PVRSRV_ALPHA_FORMAT; -+ -+/*! -+ ***************************************************************************** -+ * Enumeration of possible alpha types. -+ *****************************************************************************/ -+typedef enum _PVRSRV_COLOURSPACE_FORMAT_ { -+ PVRSRV_COLOURSPACE_FORMAT_UNKNOWN = 0x00000000, -+ PVRSRV_COLOURSPACE_FORMAT_LINEAR = 0x00010000, -+ PVRSRV_COLOURSPACE_FORMAT_NONLINEAR = 0x00020000, -+ PVRSRV_COLOURSPACE_FORMAT_MASK = 0x000F0000, -+} PVRSRV_COLOURSPACE_FORMAT; -+ -+ -+/* -+ * Drawable orientation (in degrees clockwise). -+ * Opposite sense from WSEGL. -+ */ -+typedef enum _PVRSRV_ROTATION_ { -+ PVRSRV_ROTATE_0 = 0, -+ PVRSRV_ROTATE_90 = 1, -+ PVRSRV_ROTATE_180 = 2, -+ PVRSRV_ROTATE_270 = 3, -+ PVRSRV_FLIP_Y -+ -+} PVRSRV_ROTATION; -+ -+/*! -+ * Flags for DisplayClassCreateSwapChain. -+ */ -+#define PVRSRV_CREATE_SWAPCHAIN_SHARED (1<<0) -+#define PVRSRV_CREATE_SWAPCHAIN_QUERY (1<<1) -+#define PVRSRV_CREATE_SWAPCHAIN_OEMOVERLAY (1<<2) -+ -+/*! -+ ***************************************************************************** -+ * Structure providing implementation details for serialisation and -+ * synchronisation of operations. This is the fundamental unit on which operations -+ * are synced, and would typically be included in any data structures that require -+ * serialised accesses etc. e.g. MEM_INFO structures -+ * -+ *****************************************************************************/ -+/* -+ Sync Data to be shared/mapped between user/kernel -+*/ -+typedef struct _PVRSRV_SYNC_DATA_ -+{ -+ /* CPU accessible WriteOp Info */ -+ IMG_UINT32 ui32WriteOpsPending; -+ volatile IMG_UINT32 ui32WriteOpsComplete; -+ -+ /* CPU accessible ReadOp Info */ -+ IMG_UINT32 ui32ReadOpsPending; -+ volatile IMG_UINT32 ui32ReadOpsComplete; -+ -+ /* CPU accessible ReadOp2 Info */ -+ IMG_UINT32 ui32ReadOps2Pending; -+ volatile IMG_UINT32 ui32ReadOps2Complete; -+ -+ /* pdump specific value */ -+ IMG_UINT32 ui32LastOpDumpVal; -+ IMG_UINT32 ui32LastReadOpDumpVal; -+ -+ /* Last write oprtation on this sync */ -+ IMG_UINT64 ui64LastWrite; -+ -+} PVRSRV_SYNC_DATA; -+ -+/* -+ Client Sync Info structure -+*/ -+typedef struct _PVRSRV_CLIENT_SYNC_INFO_ -+{ -+ /* mapping of the kernel sync data */ -+ PVRSRV_SYNC_DATA *psSyncData; -+ -+ /* Device accessible WriteOp Info */ -+ IMG_DEV_VIRTADDR sWriteOpsCompleteDevVAddr; -+ -+ /* Device accessible ReadOp Info */ -+ IMG_DEV_VIRTADDR sReadOpsCompleteDevVAddr; -+ -+ /* Device accessible ReadOp2 Info */ -+ IMG_DEV_VIRTADDR sReadOps2CompleteDevVAddr; -+ -+ /* handle to client mapping data (OS specific) */ -+ IMG_HANDLE hMappingInfo; -+ -+ /* handle to kernel sync info */ -+ IMG_HANDLE hKernelSyncInfo; -+ -+} PVRSRV_CLIENT_SYNC_INFO, *PPVRSRV_CLIENT_SYNC_INFO; -+ -+/*! -+ ***************************************************************************** -+ * Resource locking structure -+ *****************************************************************************/ -+typedef struct PVRSRV_RESOURCE_TAG -+{ -+ volatile IMG_UINT32 ui32Lock; -+ IMG_UINT32 ui32ID; -+}PVRSRV_RESOURCE; -+typedef PVRSRV_RESOURCE PVRSRV_RES_HANDLE; -+ -+ -+/* command complete callback pfn prototype */ -+typedef IMG_VOID (*PFN_CMD_COMPLETE) (IMG_HANDLE); -+typedef IMG_VOID (**PPFN_CMD_COMPLETE) (IMG_HANDLE); -+ -+/* private command handler prototype */ -+typedef IMG_BOOL (*PFN_CMD_PROC) (IMG_HANDLE, IMG_UINT32, IMG_VOID*); -+typedef IMG_BOOL (**PPFN_CMD_PROC) (IMG_HANDLE, IMG_UINT32, IMG_VOID*); -+ -+ -+/* -+ rectangle structure required by Lock API -+*/ -+typedef struct _IMG_RECT_ -+{ -+ IMG_INT32 x0; -+ IMG_INT32 y0; -+ IMG_INT32 x1; -+ IMG_INT32 y1; -+}IMG_RECT; -+ -+typedef struct _IMG_RECT_16_ -+{ -+ IMG_INT16 x0; -+ IMG_INT16 y0; -+ IMG_INT16 x1; -+ IMG_INT16 y1; -+}IMG_RECT_16; -+ -+ -+/* common pfn between BC/DC */ -+typedef PVRSRV_ERROR (*PFN_GET_BUFFER_ADDR)(IMG_HANDLE, -+ IMG_HANDLE, -+ IMG_SYS_PHYADDR**, -+ IMG_UINT32*, -+ IMG_VOID**, -+ IMG_HANDLE*, -+ IMG_BOOL*, -+ IMG_UINT32*); -+ -+ -+/* -+ Display dimension structure definition -+*/ -+typedef struct DISPLAY_DIMS_TAG -+{ -+ IMG_UINT32 ui32ByteStride; -+ IMG_UINT32 ui32Width; -+ IMG_UINT32 ui32Height; -+} DISPLAY_DIMS; -+ -+ -+/* -+ Display format structure definition -+*/ -+typedef struct DISPLAY_FORMAT_TAG -+{ -+ /* pixel format type */ -+ PVRSRV_PIXEL_FORMAT pixelformat; -+} DISPLAY_FORMAT; -+ -+/* -+ Display Surface Attributes structure definition -+*/ -+typedef struct DISPLAY_SURF_ATTRIBUTES_TAG -+{ -+ /* pixel format type */ -+ PVRSRV_PIXEL_FORMAT pixelformat; -+ /* dimensions information structure array */ -+ DISPLAY_DIMS sDims; -+} DISPLAY_SURF_ATTRIBUTES; -+ -+ -+/* -+ Display Mode information structure definition -+*/ -+typedef struct DISPLAY_MODE_INFO_TAG -+{ -+ /* pixel format type */ -+ PVRSRV_PIXEL_FORMAT pixelformat; -+ /* dimensions information structure array */ -+ DISPLAY_DIMS sDims; -+ /* refresh rate of the display */ -+ IMG_UINT32 ui32RefreshHZ; -+ /* OEM specific flags */ -+ IMG_UINT32 ui32OEMFlags; -+} DISPLAY_MODE_INFO; -+ -+ -+ -+#define MAX_DISPLAY_NAME_SIZE (50) /* arbitrary choice! */ -+ -+/* -+ Display info structure definition -+*/ -+typedef struct DISPLAY_INFO_TAG -+{ -+ /* max swapchains supported */ -+ IMG_UINT32 ui32MaxSwapChains; -+ /* max buffers in a swapchain */ -+ IMG_UINT32 ui32MaxSwapChainBuffers; -+ /* min swap interval supported */ -+ IMG_UINT32 ui32MinSwapInterval; -+ /* max swap interval supported */ -+ IMG_UINT32 ui32MaxSwapInterval; -+ /* physical dimensions of the display required for DPI calc. */ -+ IMG_UINT32 ui32PhysicalWidthmm; -+ IMG_UINT32 ui32PhysicalHeightmm; -+ /* display name */ -+ IMG_CHAR szDisplayName[MAX_DISPLAY_NAME_SIZE]; -+#if defined(SUPPORT_HW_CURSOR) -+ /* cursor dimensions */ -+ IMG_UINT16 ui32CursorWidth; -+ IMG_UINT16 ui32CursorHeight; -+#endif -+} DISPLAY_INFO; -+ -+typedef struct ACCESS_INFO_TAG -+{ -+ IMG_UINT32 ui32Size; -+ IMG_UINT32 ui32FBPhysBaseAddress; -+ IMG_UINT32 ui32FBMemAvailable; /* size of usable FB memory */ -+ IMG_UINT32 ui32SysPhysBaseAddress; -+ IMG_UINT32 ui32SysSize; -+ IMG_UINT32 ui32DevIRQ; -+}ACCESS_INFO; -+ -+ -+ -+#if defined(PDUMP_SUSPEND_IS_PER_THREAD) -+/** Present only on WinMobile 6.5 */ -+ -+typedef struct { -+ IMG_UINT32 threadId; -+ IMG_INT suspendCount; -+} PVRSRV_THREAD_SUSPEND_COUNT; -+ -+#define PVRSRV_PDUMP_SUSPEND_Q_NAME "PVRSRVPDumpSuspendMsgQ" -+#define PVRSRV_PDUMP_SUSPEND_Q_LENGTH 8 -+ -+#endif /* defined(PDUMP_SUSPEND_IS_PER_THREAD) */ -+ -+ -+/*! -+ ***************************************************************************** -+ * This structure is used for OS independent registry (profile) access -+ *****************************************************************************/ -+typedef struct _PVRSRV_REGISTRY_INFO_ -+{ -+ IMG_UINT32 ui32DevCookie; -+ IMG_PCHAR pszKey; -+ IMG_PCHAR pszValue; -+ IMG_PCHAR pszBuf; -+ IMG_UINT32 ui32BufSize; -+} PVRSRV_REGISTRY_INFO, *PPVRSRV_REGISTRY_INFO; -+ -+ -+PVRSRV_ERROR IMG_CALLCONV PVRSRVReadRegistryString (PPVRSRV_REGISTRY_INFO psRegInfo); -+PVRSRV_ERROR IMG_CALLCONV PVRSRVWriteRegistryString (PPVRSRV_REGISTRY_INFO psRegInfo); -+ -+ -+#define PVRSRV_BC_FLAGS_YUVCSC_CONFORMANT_RANGE (0 << 0) -+#define PVRSRV_BC_FLAGS_YUVCSC_FULL_RANGE (1 << 0) -+ -+#define PVRSRV_BC_FLAGS_YUVCSC_BT601 (0 << 1) -+#define PVRSRV_BC_FLAGS_YUVCSC_BT709 (1 << 1) -+ -+#define MAX_BUFFER_DEVICE_NAME_SIZE (50) /* arbitrary choice! */ -+ -+/* buffer information structure */ -+typedef struct BUFFER_INFO_TAG -+{ -+ IMG_UINT32 ui32BufferCount; -+ IMG_UINT32 ui32BufferDeviceID; -+ PVRSRV_PIXEL_FORMAT pixelformat; -+ IMG_UINT32 ui32ByteStride; -+ IMG_UINT32 ui32Width; -+ IMG_UINT32 ui32Height; -+ IMG_UINT32 ui32Flags; -+ IMG_CHAR szDeviceName[MAX_BUFFER_DEVICE_NAME_SIZE]; -+} BUFFER_INFO; -+ -+typedef enum _OVERLAY_DEINTERLACE_MODE_ -+{ -+ WEAVE=0x0, -+ BOB_ODD, -+ BOB_EVEN, -+ BOB_EVEN_NONINTERLEAVED -+} OVERLAY_DEINTERLACE_MODE; -+ -+#endif /* __SERVICESEXT_H__ */ -+/***************************************************************************** -+ End of file (servicesext.h) -+*****************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/include4/sgx_options.h b/drivers/staging/ti-es8-sgx/include4/sgx_options.h -new file mode 100644 -index 0000000..6cf1d9b ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/include4/sgx_options.h -@@ -0,0 +1,252 @@ -+/*************************************************************************/ /*! -+@Title -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+/* Each build option listed here is packed into a dword which -+ * provides up to 32 flags (or up to 28 flags plus a numeric -+ * value in the range 0-15 which corresponds to the number of -+ * cores minus one if SGX_FEATURE_MP is defined). The corresponding -+ * bit is set if the build option was enabled at compile time. -+ * -+ * In order to extract the enabled build flags the INTERNAL_TEST -+ * switch should be enabled in a client program which includes this -+ * header. Then the client can test specific build flags by reading -+ * the bit value at ##OPTIONNAME##_SET_OFFSET in SGX_BUILD_OPTIONS. -+ * -+ * IMPORTANT: add new options to unused bits or define a new dword -+ * (e.g. SGX_BUILD_OPTIONS2) so that the bitfield remains backwards -+ * compatible. -+ */ -+ -+ -+#if defined(DEBUG) || defined (INTERNAL_TEST) -+#define DEBUG_SET_OFFSET OPTIONS_BIT0 -+#define OPTIONS_BIT0 0x1U -+#else -+#define OPTIONS_BIT0 0x0 -+#endif /* DEBUG */ -+ -+#if defined(PDUMP) || defined (INTERNAL_TEST) -+#define PDUMP_SET_OFFSET OPTIONS_BIT1 -+#define OPTIONS_BIT1 (0x1U << 1) -+#else -+#define OPTIONS_BIT1 0x0 -+#endif /* PDUMP */ -+ -+#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG) || defined (INTERNAL_TEST) -+#define PVRSRV_USSE_EDM_STATUS_DEBUG_SET_OFFSET OPTIONS_BIT2 -+#define OPTIONS_BIT2 (0x1U << 2) -+#else -+#define OPTIONS_BIT2 0x0 -+#endif /* PVRSRV_USSE_EDM_STATUS_DEBUG */ -+ -+#if defined(SUPPORT_HW_RECOVERY) || defined (INTERNAL_TEST) -+#define SUPPORT_HW_RECOVERY_SET_OFFSET OPTIONS_BIT3 -+#define OPTIONS_BIT3 (0x1U << 3) -+#else -+#define OPTIONS_BIT3 0x0 -+#endif /* SUPPORT_HW_RECOVERY */ -+ -+ -+ -+#if defined(PVR_SECURE_HANDLES) || defined (INTERNAL_TEST) -+#define PVR_SECURE_HANDLES_SET_OFFSET OPTIONS_BIT4 -+#define OPTIONS_BIT4 (0x1U << 4) -+#else -+#define OPTIONS_BIT4 0x0 -+#endif /* PVR_SECURE_HANDLES */ -+ -+#if defined(SGX_BYPASS_SYSTEM_CACHE) || defined (INTERNAL_TEST) -+#define SGX_BYPASS_SYSTEM_CACHE_SET_OFFSET OPTIONS_BIT5 -+#define OPTIONS_BIT5 (0x1U << 5) -+#else -+#define OPTIONS_BIT5 0x0 -+#endif /* SGX_BYPASS_SYSTEM_CACHE */ -+ -+#if defined(SGX_DMS_AGE_ENABLE) || defined (INTERNAL_TEST) -+#define SGX_DMS_AGE_ENABLE_SET_OFFSET OPTIONS_BIT6 -+#define OPTIONS_BIT6 (0x1U << 6) -+#else -+#define OPTIONS_BIT6 0x0 -+#endif /* SGX_DMS_AGE_ENABLE */ -+ -+#if defined(SGX_FAST_DPM_INIT) || defined (INTERNAL_TEST) -+#define SGX_FAST_DPM_INIT_SET_OFFSET OPTIONS_BIT8 -+#define OPTIONS_BIT8 (0x1U << 8) -+#else -+#define OPTIONS_BIT8 0x0 -+#endif /* SGX_FAST_DPM_INIT */ -+ -+#if defined(SGX_FEATURE_WRITEBACK_DCU) || defined (INTERNAL_TEST) -+#define SGX_FEATURE_DCU_SET_OFFSET OPTIONS_BIT9 -+#define OPTIONS_BIT9 (0x1U << 9) -+#else -+#define OPTIONS_BIT9 0x0 -+#endif /* SGX_FEATURE_WRITEBACK_DCU */ -+ -+#if defined(SGX_FEATURE_MP) || defined (INTERNAL_TEST) -+#define SGX_FEATURE_MP_SET_OFFSET OPTIONS_BIT10 -+#define OPTIONS_BIT10 (0x1U << 10) -+#else -+#define OPTIONS_BIT10 0x0 -+#endif /* SGX_FEATURE_MP */ -+ -+#define OPTIONS_BIT11 0x0 -+ -+#define OPTIONS_BIT12 0x0 -+ -+ -+#if defined(SGX_FEATURE_SYSTEM_CACHE) || defined (INTERNAL_TEST) -+#define SGX_FEATURE_SYSTEM_CACHE_SET_OFFSET OPTIONS_BIT13 -+#define OPTIONS_BIT13 (0x1U << 13) -+#else -+#define OPTIONS_BIT13 0x0 -+#endif /* SGX_FEATURE_SYSTEM_CACHE */ -+ -+#if defined(SGX_SUPPORT_HWPROFILING) || defined (INTERNAL_TEST) -+#define SGX_SUPPORT_HWPROFILING_SET_OFFSET OPTIONS_BIT14 -+#define OPTIONS_BIT14 (0x1U << 14) -+#else -+#define OPTIONS_BIT14 0x0 -+#endif /* SGX_SUPPORT_HWPROFILING */ -+ -+ -+ -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) || defined (INTERNAL_TEST) -+#define SUPPORT_ACTIVE_POWER_MANAGEMENT_SET_OFFSET OPTIONS_BIT15 -+#define OPTIONS_BIT15 (0x1U << 15) -+#else -+#define OPTIONS_BIT15 0x0 -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ -+#if defined(SUPPORT_DISPLAYCONTROLLER_TILING) || defined (INTERNAL_TEST) -+#define SUPPORT_DISPLAYCONTROLLER_TILING_SET_OFFSET OPTIONS_BIT16 -+#define OPTIONS_BIT16 (0x1U << 16) -+#else -+#define OPTIONS_BIT16 0x0 -+#endif /* SUPPORT_DISPLAYCONTROLLER_TILING */ -+ -+#if defined(SUPPORT_PERCONTEXT_PB) || defined (INTERNAL_TEST) -+#define SUPPORT_PERCONTEXT_PB_SET_OFFSET OPTIONS_BIT17 -+#define OPTIONS_BIT17 (0x1U << 17) -+#else -+#define OPTIONS_BIT17 0x0 -+#endif /* SUPPORT_PERCONTEXT_PB */ -+ -+#if defined(SUPPORT_SGX_HWPERF) || defined (INTERNAL_TEST) -+#define SUPPORT_SGX_HWPERF_SET_OFFSET OPTIONS_BIT18 -+#define OPTIONS_BIT18 (0x1U << 18) -+#else -+#define OPTIONS_BIT18 0x0 -+#endif /* SUPPORT_SGX_HWPERF */ -+ -+ -+ -+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) || defined (INTERNAL_TEST) -+#define SUPPORT_SGX_MMU_DUMMY_PAGE_SET_OFFSET OPTIONS_BIT19 -+#define OPTIONS_BIT19 (0x1U << 19) -+#else -+#define OPTIONS_BIT19 0x0 -+#endif /* SUPPORT_SGX_MMU_DUMMY_PAGE */ -+ -+#if defined(SUPPORT_SGX_PRIORITY_SCHEDULING) || defined (INTERNAL_TEST) -+#define SUPPORT_SGX_PRIORITY_SCHEDULING_SET_OFFSET OPTIONS_BIT20 -+#define OPTIONS_BIT20 (0x1U << 20) -+#else -+#define OPTIONS_BIT20 0x0 -+#endif /* SUPPORT_SGX_PRIORITY_SCHEDULING */ -+ -+#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) || defined (INTERNAL_TEST) -+#define SUPPORT_SGX_LOW_LATENCY_SCHEDULING_SET_OFFSET OPTIONS_BIT21 -+#define OPTIONS_BIT21 (0x1U << 21) -+#else -+#define OPTIONS_BIT21 0x0 -+#endif /* SUPPORT_SGX_LOW_LATENCY_SCHEDULING */ -+ -+#if defined(USE_SUPPORT_NO_TA3D_OVERLAP) || defined (INTERNAL_TEST) -+#define USE_SUPPORT_NO_TA3D_OVERLAP_SET_OFFSET OPTIONS_BIT22 -+#define OPTIONS_BIT22 (0x1U << 22) -+#else -+#define OPTIONS_BIT22 0x0 -+#endif /* USE_SUPPORT_NO_TA3D_OVERLAP */ -+ -+#if defined(SGX_FEATURE_MP) || defined (INTERNAL_TEST) -+#if defined(SGX_FEATURE_MP_CORE_COUNT) -+#define OPTIONS_HIGHBYTE ((SGX_FEATURE_MP_CORE_COUNT-1) << SGX_FEATURE_MP_CORE_COUNT_SET_OFFSET) -+#define SGX_FEATURE_MP_CORE_COUNT_SET_OFFSET 28UL -+#define SGX_FEATURE_MP_CORE_COUNT_SET_MASK 0xFF -+#else -+#define OPTIONS_HIGHBYTE (((SGX_FEATURE_MP_CORE_COUNT_TA-1) << SGX_FEATURE_MP_CORE_COUNT_SET_OFFSET) |\ -+ ((SGX_FEATURE_MP_CORE_COUNT_3D-1) << SGX_FEATURE_MP_CORE_COUNT_SET_OFFSET_3D)) -+#define SGX_FEATURE_MP_CORE_COUNT_SET_OFFSET 24UL -+#define SGX_FEATURE_MP_CORE_COUNT_SET_OFFSET_3D 28UL -+#define SGX_FEATURE_MP_CORE_COUNT_SET_MASK 0xFF -+#endif -+#else /* SGX_FEATURE_MP */ -+#define OPTIONS_HIGHBYTE 0x0 -+#endif /* SGX_FEATURE_MP */ -+ -+ -+ -+#define SGX_BUILD_OPTIONS \ -+ OPTIONS_BIT0 |\ -+ OPTIONS_BIT1 |\ -+ OPTIONS_BIT2 |\ -+ OPTIONS_BIT3 |\ -+ OPTIONS_BIT4 |\ -+ OPTIONS_BIT5 |\ -+ OPTIONS_BIT6 |\ -+ OPTIONS_BIT8 |\ -+ OPTIONS_BIT9 |\ -+ OPTIONS_BIT10 |\ -+ OPTIONS_BIT11 |\ -+ OPTIONS_BIT12 |\ -+ OPTIONS_BIT13 |\ -+ OPTIONS_BIT14 |\ -+ OPTIONS_BIT15 |\ -+ OPTIONS_BIT16 |\ -+ OPTIONS_BIT17 |\ -+ OPTIONS_BIT18 |\ -+ OPTIONS_BIT19 |\ -+ OPTIONS_BIT20 |\ -+ OPTIONS_BIT21 |\ -+ OPTIONS_BIT22 |\ -+ OPTIONS_HIGHBYTE -diff --git a/drivers/staging/ti-es8-sgx/include4/sgxapi_km.h b/drivers/staging/ti-es8-sgx/include4/sgxapi_km.h -new file mode 100644 -index 0000000..47e56a7 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/include4/sgxapi_km.h -@@ -0,0 +1,537 @@ -+/*************************************************************************/ /*! -+@Title SGX KM API Header -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Exported SGX API details -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#ifndef __SGXAPI_KM_H__ -+#define __SGXAPI_KM_H__ -+ -+#if defined (__cplusplus) -+extern "C" { -+#endif -+ -+#include "sgxdefs.h" -+ -+#if (defined(__linux__) || defined(__QNXNTO__)) && !defined(USE_CODE) -+ #if defined(__KERNEL__) -+ #include <asm/unistd.h> -+ #else -+ #include <unistd.h> -+ #endif -+#endif -+ -+/****************************************************************************** -+ Some defines... -+******************************************************************************/ -+ -+/* SGX Heap IDs, note: not all heaps are available to clients */ -+#define SGX_UNDEFINED_HEAP_ID (~0LU) -+#define SGX_GENERAL_HEAP_ID 0 -+#define SGX_TADATA_HEAP_ID 1 -+#define SGX_KERNEL_CODE_HEAP_ID 2 -+#define SGX_KERNEL_DATA_HEAP_ID 3 -+#define SGX_PIXELSHADER_HEAP_ID 4 -+#define SGX_VERTEXSHADER_HEAP_ID 5 -+#define SGX_PDSPIXEL_CODEDATA_HEAP_ID 6 -+#define SGX_PDSVERTEX_CODEDATA_HEAP_ID 7 -+#define SGX_SYNCINFO_HEAP_ID 8 -+#define SGX_SHARED_3DPARAMETERS_HEAP_ID 9 -+#define SGX_PERCONTEXT_3DPARAMETERS_HEAP_ID 10 -+#if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP) -+#define SGX_GENERAL_MAPPING_HEAP_ID 11 -+#endif -+#if defined(SGX_FEATURE_2D_HARDWARE) -+#define SGX_2D_HEAP_ID 12 -+#endif -+#if defined(SUPPORT_MEMORY_TILING) -+#define SGX_VPB_TILED_HEAP_ID 14 -+#endif -+ -+#define SGX_MAX_HEAP_ID 15 -+ -+/* -+ * Keep SGX_3DPARAMETERS_HEAP_ID as TQ full custom -+ * shaders need it to select which heap to write -+ * their ISP controll stream to. -+ */ -+#if (defined(SUPPORT_PERCONTEXT_PB) || defined(SUPPORT_HYBRID_PB)) -+#define SGX_3DPARAMETERS_HEAP_ID SGX_PERCONTEXT_3DPARAMETERS_HEAP_ID -+#else -+#define SGX_3DPARAMETERS_HEAP_ID SGX_SHARED_3DPARAMETERS_HEAP_ID -+#endif -+/* Define for number of bytes between consecutive code base registers */ -+#if defined(SGX543) || defined(SGX544) || defined(SGX554) -+#define SGX_USE_CODE_SEGMENT_RANGE_BITS 23 -+#else -+#define SGX_USE_CODE_SEGMENT_RANGE_BITS 19 -+#endif -+ -+#define SGX_MAX_TA_STATUS_VALS 32 -+#define SGX_MAX_3D_STATUS_VALS 4 -+ -+#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS) -+/* sync info structure array size */ -+#define SGX_MAX_TA_DST_SYNCS 1 -+#define SGX_MAX_TA_SRC_SYNCS 1 -+#define SGX_MAX_3D_SRC_SYNCS 4 -+/* note: there is implicitly 1 3D Dst Sync */ -+#else -+/* sync info structure array size */ -+#define SGX_MAX_SRC_SYNCS_TA 32 -+#define SGX_MAX_DST_SYNCS_TA 1 -+/* note: there is implicitly 1 3D Dst Sync */ -+#if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) -+/* note: only one dst sync is supported by the 2D paths */ -+#define SGX_MAX_SRC_SYNCS_TQ 6 -+#define SGX_MAX_DST_SYNCS_TQ 2 -+#else /* defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) */ -+#define SGX_MAX_SRC_SYNCS_TQ 8 -+#define SGX_MAX_DST_SYNCS_TQ 1 -+#endif /* defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) */ -+#endif -+ -+ -+#if defined(SGX_FEATURE_EXTENDED_PERF_COUNTERS) -+#define PVRSRV_SGX_HWPERF_NUM_COUNTERS 8 -+#define PVRSRV_SGX_HWPERF_NUM_MISC_COUNTERS 11 -+#else -+#define PVRSRV_SGX_HWPERF_NUM_COUNTERS 9 -+#define PVRSRV_SGX_HWPERF_NUM_MISC_COUNTERS 8 -+#endif /* SGX543 */ -+ -+#define PVRSRV_SGX_HWPERF_INVALID 0x1 -+ -+#define PVRSRV_SGX_HWPERF_TRANSFER 0x2 -+#define PVRSRV_SGX_HWPERF_TA 0x3 -+#define PVRSRV_SGX_HWPERF_3D 0x4 -+#define PVRSRV_SGX_HWPERF_2D 0x5 -+#define PVRSRV_SGX_HWPERF_POWER 0x6 -+#define PVRSRV_SGX_HWPERF_PERIODIC 0x7 -+#define PVRSRV_SGX_HWPERF_3DSPM 0x8 -+ -+#define PVRSRV_SGX_HWPERF_MK_EVENT 0x101 -+#define PVRSRV_SGX_HWPERF_MK_TA 0x102 -+#define PVRSRV_SGX_HWPERF_MK_3D 0x103 -+#define PVRSRV_SGX_HWPERF_MK_2D 0x104 -+#define PVRSRV_SGX_HWPERF_MK_TRANSFER_DUMMY 0x105 -+#define PVRSRV_SGX_HWPERF_MK_TA_DUMMY 0x106 -+#define PVRSRV_SGX_HWPERF_MK_3D_DUMMY 0x107 -+#define PVRSRV_SGX_HWPERF_MK_2D_DUMMY 0x108 -+#define PVRSRV_SGX_HWPERF_MK_TA_LOCKUP 0x109 -+#define PVRSRV_SGX_HWPERF_MK_3D_LOCKUP 0x10A -+#define PVRSRV_SGX_HWPERF_MK_2D_LOCKUP 0x10B -+ -+#define PVRSRV_SGX_HWPERF_TYPE_STARTEND_BIT 28 -+#define PVRSRV_SGX_HWPERF_TYPE_OP_MASK ((1UL << PVRSRV_SGX_HWPERF_TYPE_STARTEND_BIT) - 1) -+#define PVRSRV_SGX_HWPERF_TYPE_OP_START (0UL << PVRSRV_SGX_HWPERF_TYPE_STARTEND_BIT) -+#define PVRSRV_SGX_HWPERF_TYPE_OP_END (1Ul << PVRSRV_SGX_HWPERF_TYPE_STARTEND_BIT) -+ -+#define PVRSRV_SGX_HWPERF_TYPE_TRANSFER_START (PVRSRV_SGX_HWPERF_TRANSFER | PVRSRV_SGX_HWPERF_TYPE_OP_START) -+#define PVRSRV_SGX_HWPERF_TYPE_TRANSFER_END (PVRSRV_SGX_HWPERF_TRANSFER | PVRSRV_SGX_HWPERF_TYPE_OP_END) -+#define PVRSRV_SGX_HWPERF_TYPE_TA_START (PVRSRV_SGX_HWPERF_TA | PVRSRV_SGX_HWPERF_TYPE_OP_START) -+#define PVRSRV_SGX_HWPERF_TYPE_TA_END (PVRSRV_SGX_HWPERF_TA | PVRSRV_SGX_HWPERF_TYPE_OP_END) -+#define PVRSRV_SGX_HWPERF_TYPE_3D_START (PVRSRV_SGX_HWPERF_3D | PVRSRV_SGX_HWPERF_TYPE_OP_START) -+#define PVRSRV_SGX_HWPERF_TYPE_3D_END (PVRSRV_SGX_HWPERF_3D | PVRSRV_SGX_HWPERF_TYPE_OP_END) -+#define PVRSRV_SGX_HWPERF_TYPE_2D_START (PVRSRV_SGX_HWPERF_2D | PVRSRV_SGX_HWPERF_TYPE_OP_START) -+#define PVRSRV_SGX_HWPERF_TYPE_2D_END (PVRSRV_SGX_HWPERF_2D | PVRSRV_SGX_HWPERF_TYPE_OP_END) -+#define PVRSRV_SGX_HWPERF_TYPE_POWER_START (PVRSRV_SGX_HWPERF_POWER | PVRSRV_SGX_HWPERF_TYPE_OP_START) -+#define PVRSRV_SGX_HWPERF_TYPE_POWER_END (PVRSRV_SGX_HWPERF_POWER | PVRSRV_SGX_HWPERF_TYPE_OP_END) -+#define PVRSRV_SGX_HWPERF_TYPE_PERIODIC (PVRSRV_SGX_HWPERF_PERIODIC) -+#define PVRSRV_SGX_HWPERF_TYPE_3DSPM_START (PVRSRV_SGX_HWPERF_3DSPM | PVRSRV_SGX_HWPERF_TYPE_OP_START) -+#define PVRSRV_SGX_HWPERF_TYPE_3DSPM_END (PVRSRV_SGX_HWPERF_3DSPM | PVRSRV_SGX_HWPERF_TYPE_OP_END) -+#define PVRSRV_SGX_HWPERF_TYPE_MK_TRANSFER_DUMMY_START (PVRSRV_SGX_HWPERF_MK_TRANSFER_DUMMY | PVRSRV_SGX_HWPERF_TYPE_OP_START) -+#define PVRSRV_SGX_HWPERF_TYPE_MK_TRANSFER_DUMMY_END (PVRSRV_SGX_HWPERF_MK_TRANSFER_DUMMY | PVRSRV_SGX_HWPERF_TYPE_OP_END) -+#define PVRSRV_SGX_HWPERF_TYPE_MK_TA_DUMMY_START (PVRSRV_SGX_HWPERF_MK_TA_DUMMY | PVRSRV_SGX_HWPERF_TYPE_OP_START) -+#define PVRSRV_SGX_HWPERF_TYPE_MK_TA_DUMMY_END (PVRSRV_SGX_HWPERF_MK_TA_DUMMY | PVRSRV_SGX_HWPERF_TYPE_OP_END) -+#define PVRSRV_SGX_HWPERF_TYPE_MK_3D_DUMMY_START (PVRSRV_SGX_HWPERF_MK_3D_DUMMY | PVRSRV_SGX_HWPERF_TYPE_OP_START) -+#define PVRSRV_SGX_HWPERF_TYPE_MK_3D_DUMMY_END (PVRSRV_SGX_HWPERF_MK_3D_DUMMY | PVRSRV_SGX_HWPERF_TYPE_OP_END) -+#define PVRSRV_SGX_HWPERF_TYPE_MK_2D_DUMMY_START (PVRSRV_SGX_HWPERF_MK_2D_DUMMY | PVRSRV_SGX_HWPERF_TYPE_OP_START) -+#define PVRSRV_SGX_HWPERF_TYPE_MK_2D_DUMMY_END (PVRSRV_SGX_HWPERF_MK_2D_DUMMY | PVRSRV_SGX_HWPERF_TYPE_OP_END) -+#define PVRSRV_SGX_HWPERF_TYPE_MK_TA_LOCKUP (PVRSRV_SGX_HWPERF_MK_TA_LOCKUP) -+#define PVRSRV_SGX_HWPERF_TYPE_MK_3D_LOCKUP (PVRSRV_SGX_HWPERF_MK_3D_LOCKUP) -+#define PVRSRV_SGX_HWPERF_TYPE_MK_2D_LOCKUP (PVRSRV_SGX_HWPERF_MK_2D_LOCKUP) -+ -+#define PVRSRV_SGX_HWPERF_TYPE_MK_EVENT_START (PVRSRV_SGX_HWPERF_MK_EVENT | PVRSRV_SGX_HWPERF_TYPE_OP_START) -+#define PVRSRV_SGX_HWPERF_TYPE_MK_EVENT_END (PVRSRV_SGX_HWPERF_MK_EVENT | PVRSRV_SGX_HWPERF_TYPE_OP_END) -+#define PVRSRV_SGX_HWPERF_TYPE_MK_TA_START (PVRSRV_SGX_HWPERF_MK_TA | PVRSRV_SGX_HWPERF_TYPE_OP_START) -+#define PVRSRV_SGX_HWPERF_TYPE_MK_TA_END (PVRSRV_SGX_HWPERF_MK_TA | PVRSRV_SGX_HWPERF_TYPE_OP_END) -+#define PVRSRV_SGX_HWPERF_TYPE_MK_3D_START (PVRSRV_SGX_HWPERF_MK_3D | PVRSRV_SGX_HWPERF_TYPE_OP_START) -+#define PVRSRV_SGX_HWPERF_TYPE_MK_3D_END (PVRSRV_SGX_HWPERF_MK_3D | PVRSRV_SGX_HWPERF_TYPE_OP_END) -+#define PVRSRV_SGX_HWPERF_TYPE_MK_2D_START (PVRSRV_SGX_HWPERF_MK_2D | PVRSRV_SGX_HWPERF_TYPE_OP_START) -+#define PVRSRV_SGX_HWPERF_TYPE_MK_2D_END (PVRSRV_SGX_HWPERF_MK_2D | PVRSRV_SGX_HWPERF_TYPE_OP_END) -+ -+#define PVRSRV_SGX_HWPERF_STATUS_OFF (0x0) -+#define PVRSRV_SGX_HWPERF_STATUS_RESET_COUNTERS (1UL << 0) -+#define PVRSRV_SGX_HWPERF_STATUS_GRAPHICS_ON (1UL << 1) -+#define PVRSRV_SGX_HWPERF_STATUS_PERIODIC_ON (1UL << 2) -+#define PVRSRV_SGX_HWPERF_STATUS_MK_EXECUTION_ON (1UL << 3) -+ -+ -+/*! -+ ***************************************************************************** -+ * One entry in the HWPerf Circular Buffer. -+ *****************************************************************************/ -+typedef struct _PVRSRV_SGX_HWPERF_CB_ENTRY_ -+{ -+ IMG_UINT32 ui32FrameNo; -+ IMG_UINT32 ui32PID; -+ IMG_UINT32 ui32RTData; -+ IMG_UINT32 ui32Type; -+ IMG_UINT32 ui32Ordinal; -+ IMG_UINT32 ui32Info; -+ IMG_UINT32 ui32Clocksx16; -+ /* NOTE: There should always be at least as many 3D cores as TA cores. */ -+ IMG_UINT32 ui32Counters[SGX_FEATURE_MP_CORE_COUNT_3D][PVRSRV_SGX_HWPERF_NUM_COUNTERS]; -+ IMG_UINT32 ui32MiscCounters[SGX_FEATURE_MP_CORE_COUNT_3D][PVRSRV_SGX_HWPERF_NUM_MISC_COUNTERS]; -+} PVRSRV_SGX_HWPERF_CB_ENTRY; -+ -+ -+/* -+ Status values control structure -+*/ -+typedef struct _CTL_STATUS_ -+{ -+ IMG_DEV_VIRTADDR sStatusDevAddr; -+ IMG_UINT32 ui32StatusValue; -+} CTL_STATUS; -+ -+ -+/*! -+ List of possible requests/commands to SGXGetMiscInfo() -+*/ -+typedef enum _SGX_MISC_INFO_REQUEST_ -+{ -+ SGX_MISC_INFO_REQUEST_CLOCKSPEED = 0, -+ SGX_MISC_INFO_REQUEST_CLOCKSPEED_SLCSIZE, -+ SGX_MISC_INFO_REQUEST_SGXREV, -+ SGX_MISC_INFO_REQUEST_DRIVER_SGXREV, -+#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG) -+ SGX_MISC_INFO_REQUEST_MEMREAD, -+ SGX_MISC_INFO_REQUEST_MEMCOPY, -+#endif /* SUPPORT_SGX_EDM_MEMORY_DEBUG */ -+ SGX_MISC_INFO_REQUEST_SET_HWPERF_STATUS, -+#if defined(SGX_FEATURE_DATA_BREAKPOINTS) -+ SGX_MISC_INFO_REQUEST_SET_BREAKPOINT, -+ SGX_MISC_INFO_REQUEST_POLL_BREAKPOINT, -+ SGX_MISC_INFO_REQUEST_RESUME_BREAKPOINT, -+#endif /* SGX_FEATURE_DATA_BREAKPOINTS */ -+ SGX_MISC_INFO_DUMP_DEBUG_INFO, -+ SGX_MISC_INFO_DUMP_DEBUG_INFO_FORCE_REGS, -+ SGX_MISC_INFO_PANIC, -+ SGX_MISC_INFO_REQUEST_SPM, -+ SGX_MISC_INFO_REQUEST_ACTIVEPOWER, -+ SGX_MISC_INFO_REQUEST_LOCKUPS, -+#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG) -+ SGX_MISC_INFO_REQUEST_EDM_STATUS_BUFFER_INFO, -+#endif -+ SGX_MISC_INFO_REQUEST_FORCE_I16 = 0x7fff -+} SGX_MISC_INFO_REQUEST; -+ -+ -+/****************************************************************************** -+ * Struct for passing SGX core rev/features from ukernel to driver. -+ * This is accessed from the kernel part of the driver and microkernel; it is -+ * only accessed in user space during buffer allocation in srvinit. -+ ******************************************************************************/ -+typedef struct _PVRSRV_SGX_MISCINFO_FEATURES -+{ -+ IMG_UINT32 ui32CoreRev; /*!< SGX Core revision from HW register */ -+ IMG_UINT32 ui32CoreID; /*!< SGX Core ID from HW register */ -+ IMG_UINT32 ui32DDKVersion; /*!< software DDK version */ -+ IMG_UINT32 ui32DDKBuild; /*!< software DDK build no. */ -+ IMG_UINT32 ui32CoreIdSW; /*!< software core version (ID), e.g. SGX535, SGX540 */ -+ IMG_UINT32 ui32CoreRevSW; /*!< software core revision */ -+ IMG_UINT32 ui32BuildOptions; /*!< build options bit-field */ -+#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG) -+ IMG_UINT32 ui32DeviceMemValue; /*!< device mem value read from ukernel */ -+#endif -+} PVRSRV_SGX_MISCINFO_FEATURES; -+ -+typedef struct _PVRSRV_SGX_MISCINFO_QUERY_CLOCKSPEED_SLCSIZE -+{ -+ IMG_UINT32 ui32SGXClockSpeed; -+ IMG_UINT32 ui32SGXSLCSize; -+} PVRSRV_SGX_MISCINFO_QUERY_CLOCKSPEED_SLCSIZE; -+ -+#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG) -+/****************************************************************************** -+ * Struct for getting access to the EDM Status Buffer -+ ******************************************************************************/ -+typedef struct _PVRSRV_SGX_MISCINFO_EDM_STATUS_BUFFER_INFO -+{ -+ IMG_DEV_VIRTADDR sDevVAEDMStatusBuffer; /*!< DevVAddr of the EDM status buffer */ -+ IMG_PVOID pvEDMStatusBuffer; /*!< CPUVAddr of the EDM status buffer */ -+} PVRSRV_SGX_MISCINFO_EDM_STATUS_BUFFER_INFO; -+#endif -+ -+ -+/****************************************************************************** -+ * Struct for getting lock-up stats from the kernel driver -+ ******************************************************************************/ -+typedef struct _PVRSRV_SGX_MISCINFO_LOCKUPS -+{ -+ IMG_UINT32 ui32HostDetectedLockups; /*!< Host timer detected lockups */ -+ IMG_UINT32 ui32uKernelDetectedLockups; /*!< Microkernel detected lockups */ -+} PVRSRV_SGX_MISCINFO_LOCKUPS; -+ -+ -+/****************************************************************************** -+ * Struct for getting lock-up stats from the kernel driver -+ ******************************************************************************/ -+typedef struct _PVRSRV_SGX_MISCINFO_ACTIVEPOWER -+{ -+ IMG_UINT32 ui32NumActivePowerEvents; /*!< active power events */ -+} PVRSRV_SGX_MISCINFO_ACTIVEPOWER; -+ -+ -+/****************************************************************************** -+ * Struct for getting SPM stats fro the kernel driver -+ ******************************************************************************/ -+typedef struct _PVRSRV_SGX_MISCINFO_SPM -+{ -+ IMG_HANDLE hRTDataSet; /*!< render target data set handle returned from SGXAddRenderTarget */ -+ IMG_UINT32 ui32NumOutOfMemSignals; /*!< Number of Out of Mem Signals */ -+ IMG_UINT32 ui32NumSPMRenders; /*!< Number of SPM renders */ -+} PVRSRV_SGX_MISCINFO_SPM; -+ -+ -+#if defined(SGX_FEATURE_DATA_BREAKPOINTS) -+/*! -+ ****************************************************************************** -+ * Structure for SGX break points control -+ *****************************************************************************/ -+typedef struct _SGX_BREAKPOINT_INFO -+{ -+ /* set/clear BP boolean */ -+ IMG_BOOL bBPEnable; -+ /* Index of BP to set */ -+ IMG_UINT32 ui32BPIndex; -+ /* On which DataMaster(s) should the breakpoint fire? */ -+ IMG_UINT32 ui32DataMasterMask; -+ /* DevVAddr of BP to set */ -+ IMG_DEV_VIRTADDR sBPDevVAddr, sBPDevVAddrEnd; -+ /* Whether or not the desired breakpoint will be trapped */ -+ IMG_BOOL bTrapped; -+ /* Will the requested breakpoint fire for reads? */ -+ IMG_BOOL bRead; -+ /* Will the requested breakpoint fire for writes? */ -+ IMG_BOOL bWrite; -+ /* Has a breakpoint been trapped? */ -+ IMG_BOOL bTrappedBP; -+ /* Extra information recorded about a trapped breakpoint */ -+ IMG_UINT32 ui32CoreNum; -+ IMG_DEV_VIRTADDR sTrappedBPDevVAddr; -+ IMG_UINT32 ui32TrappedBPBurstLength; -+ IMG_BOOL bTrappedBPRead; -+ IMG_UINT32 ui32TrappedBPDataMaster; -+ IMG_UINT32 ui32TrappedBPTag; -+} SGX_BREAKPOINT_INFO; -+#endif /* SGX_FEATURE_DATA_BREAKPOINTS */ -+ -+ -+/*! -+ ****************************************************************************** -+ * Structure for setting the hardware performance status -+ *****************************************************************************/ -+typedef struct _PVRSRV_SGX_MISCINFO_SET_HWPERF_STATUS -+{ -+ /* See PVRSRV_SGX_HWPERF_STATUS_* */ -+ IMG_UINT32 ui32NewHWPerfStatus; -+ -+ #if defined(SGX_FEATURE_EXTENDED_PERF_COUNTERS) -+ /* Specifies the HW's active group selectors */ -+ IMG_UINT32 aui32PerfGroup[PVRSRV_SGX_HWPERF_NUM_COUNTERS]; -+ /* Specifies the HW's active bit selectors */ -+ IMG_UINT32 aui32PerfBit[PVRSRV_SGX_HWPERF_NUM_COUNTERS]; -+ /* Specifies the HW's counter bit selectors */ -+ IMG_UINT32 ui32PerfCounterBitSelect; -+ /* Specifies the HW's sum_mux selectors */ -+ IMG_UINT32 ui32PerfSumMux; -+ #else -+ /* Specifies the HW's active group */ -+ IMG_UINT32 ui32PerfGroup; -+ #endif /* SGX_FEATURE_EXTENDED_PERF_COUNTERS */ -+} PVRSRV_SGX_MISCINFO_SET_HWPERF_STATUS; -+ -+ -+/*! -+ ****************************************************************************** -+ * Structure for misc SGX commands in services -+ *****************************************************************************/ -+typedef struct _SGX_MISC_INFO_ -+{ -+ SGX_MISC_INFO_REQUEST eRequest; /*!< Command request to SGXGetMiscInfo() */ -+ IMG_UINT32 ui32Padding; -+#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG) -+ IMG_DEV_VIRTADDR sDevVAddrSrc; /*!< dev virtual addr for mem read */ -+ IMG_DEV_VIRTADDR sDevVAddrDest; /*!< dev virtual addr for mem write */ -+ IMG_HANDLE hDevMemContext; /*!< device memory context for mem debug */ -+#endif -+ union -+ { -+ IMG_UINT32 reserved; /*!< Unused: ensures valid code in the case everything else is compiled out */ -+ PVRSRV_SGX_MISCINFO_FEATURES sSGXFeatures; -+ IMG_UINT32 ui32SGXClockSpeed; -+ PVRSRV_SGX_MISCINFO_QUERY_CLOCKSPEED_SLCSIZE sQueryClockSpeedSLCSize; -+ PVRSRV_SGX_MISCINFO_ACTIVEPOWER sActivePower; -+ PVRSRV_SGX_MISCINFO_LOCKUPS sLockups; -+ PVRSRV_SGX_MISCINFO_SPM sSPM; -+#if defined(SGX_FEATURE_DATA_BREAKPOINTS) -+ SGX_BREAKPOINT_INFO sSGXBreakpointInfo; -+#endif -+ PVRSRV_SGX_MISCINFO_SET_HWPERF_STATUS sSetHWPerfStatus; -+ -+#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG) -+ PVRSRV_SGX_MISCINFO_EDM_STATUS_BUFFER_INFO sEDMStatusBufferInfo; -+#endif -+ } uData; -+} SGX_MISC_INFO; -+ -+#if defined(SGX_FEATURE_2D_HARDWARE) -+/* -+ * The largest number of source sync objects that can be associated with a blit -+ * command. Allows for src, pattern, and mask -+ */ -+#define PVRSRV_MAX_BLT_SRC_SYNCS 3 -+#endif -+ -+ -+#define SGX_KICKTA_DUMPBITMAP_MAX_NAME_LENGTH 256 -+ -+/* -+ Structure for dumping bitmaps -+*/ -+typedef struct _SGX_KICKTA_DUMPBITMAP_ -+{ -+ IMG_DEV_VIRTADDR sDevBaseAddr; -+ IMG_UINT32 ui32Flags; -+ IMG_UINT32 ui32Width; -+ IMG_UINT32 ui32Height; -+ IMG_UINT32 ui32Stride; -+ IMG_UINT32 ui32PDUMPFormat; -+ IMG_UINT32 ui32BytesPP; -+ IMG_CHAR pszName[SGX_KICKTA_DUMPBITMAP_MAX_NAME_LENGTH]; -+} SGX_KICKTA_DUMPBITMAP, *PSGX_KICKTA_DUMPBITMAP; -+ -+#define PVRSRV_SGX_PDUMP_CONTEXT_MAX_BITMAP_ARRAY_SIZE (16) -+ -+/*! -+ ****************************************************************************** -+ * Data required only when dumping parameters -+ *****************************************************************************/ -+typedef struct _PVRSRV_SGX_PDUMP_CONTEXT_ -+{ -+ /* cache control word for micro kernel cache flush/invalidates */ -+ IMG_UINT32 ui32CacheControl; -+ -+} PVRSRV_SGX_PDUMP_CONTEXT; -+ -+ -+typedef struct _SGX_KICKTA_DUMP_ROFF_ -+{ -+ IMG_HANDLE hKernelMemInfo; /*< Buffer handle */ -+ IMG_UINT32 uiAllocIndex; /*< Alloc index for LDDM */ -+ IMG_UINT32 ui32Offset; /*< Byte offset to value to dump */ -+ IMG_UINT32 ui32Value; /*< Actual value to dump */ -+ IMG_PCHAR pszName; /*< Name of buffer */ -+} SGX_KICKTA_DUMP_ROFF, *PSGX_KICKTA_DUMP_ROFF; -+ -+typedef struct _SGX_KICKTA_DUMP_BUFFER_ -+{ -+ IMG_UINT32 ui32SpaceUsed; -+ IMG_UINT32 ui32Start; /*< Byte offset of start to dump */ -+ IMG_UINT32 ui32End; /*< Byte offset of end of dump (non-inclusive) */ -+ IMG_UINT32 ui32BufferSize; /*< Size of buffer */ -+ IMG_UINT32 ui32BackEndLength; /*< Size of back end portion, if End < Start */ -+ IMG_UINT32 uiAllocIndex; -+ IMG_HANDLE hKernelMemInfo; /*< MemInfo handle for the circular buffer */ -+ IMG_PVOID pvLinAddr; -+#if defined(SUPPORT_SGX_NEW_STATUS_VALS) -+ IMG_HANDLE hCtrlKernelMemInfo; /*< MemInfo handle for the control structure of the -+ circular buffer */ -+ IMG_DEV_VIRTADDR sCtrlDevVAddr; /*< Device virtual address of the memory in the -+ control structure to be checked */ -+#endif -+ IMG_PCHAR pszName; /*< Name of buffer */ -+ -+#if defined (__QNXNTO__) -+ IMG_UINT32 ui32NameLength; /*< Number of characters in buffer name */ -+#endif -+} SGX_KICKTA_DUMP_BUFFER, *PSGX_KICKTA_DUMP_BUFFER; -+ -+#ifdef PDUMP -+/* -+ PDUMP version of above kick structure -+*/ -+typedef struct _SGX_KICKTA_PDUMP_ -+{ -+ // Bitmaps to dump -+ PSGX_KICKTA_DUMPBITMAP psPDumpBitmapArray; -+ IMG_UINT32 ui32PDumpBitmapSize; -+ -+ // Misc buffers to dump (e.g. TA, PDS etc..) -+ PSGX_KICKTA_DUMP_BUFFER psBufferArray; -+ IMG_UINT32 ui32BufferArraySize; -+ -+ // Roffs to dump -+ PSGX_KICKTA_DUMP_ROFF psROffArray; -+ IMG_UINT32 ui32ROffArraySize; -+} SGX_KICKTA_PDUMP, *PSGX_KICKTA_PDUMP; -+#endif /* PDUMP */ -+ -+#if defined(TRANSFER_QUEUE) -+#if defined(SGX_FEATURE_2D_HARDWARE) -+/* Maximum size of ctrl stream for 2d blit command (in 32 bit words) */ -+#define SGX_MAX_2D_BLIT_CMD_SIZE 26 -+#define SGX_MAX_2D_SRC_SYNC_OPS 3 -+#endif -+#define SGX_MAX_TRANSFER_STATUS_VALS 2 -+#define SGX_MAX_TRANSFER_SYNC_OPS 5 -+#endif -+ -+#if defined (__cplusplus) -+} -+#endif -+ -+#endif /* __SGXAPI_KM_H__ */ -+ -+/****************************************************************************** -+ End of file (sgxapi_km.h) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/include4/sgxscript.h b/drivers/staging/ti-es8-sgx/include4/sgxscript.h -new file mode 100644 -index 0000000..2a3a846 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/include4/sgxscript.h -@@ -0,0 +1,106 @@ -+/*************************************************************************/ /*! -+@Title SGX kernel services structues/functions -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description SGX initialisation script definitions. -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+#ifndef __SGXSCRIPT_H__ -+#define __SGXSCRIPT_H__ -+ -+#include "sgxfeaturedefs.h" -+#if defined (__cplusplus) -+extern "C" { -+#endif -+ -+#define SGX_MAX_INIT_COMMANDS 64 -+#define SGX_MAX_PRINT_COMMANDS 96 -+#define SGX_MAX_DEINIT_COMMANDS 16 -+ -+typedef enum _SGX_INIT_OPERATION -+{ -+ SGX_INIT_OP_ILLEGAL = 0, -+ SGX_INIT_OP_WRITE_HW_REG, -+ SGX_INIT_OP_READ_HW_REG, -+ SGX_INIT_OP_PRINT_HW_REG, -+#if defined(PDUMP) -+ SGX_INIT_OP_PDUMP_HW_REG, -+#endif -+ SGX_INIT_OP_HALT -+} SGX_INIT_OPERATION; -+ -+typedef union _SGX_INIT_COMMAND -+{ -+ SGX_INIT_OPERATION eOp; -+ struct { -+ SGX_INIT_OPERATION eOp; -+ IMG_UINT32 ui32Offset; -+ IMG_UINT32 ui32Value; -+ } sWriteHWReg; -+ struct { -+ SGX_INIT_OPERATION eOp; -+ IMG_UINT32 ui32Offset; -+ } sReadHWReg; -+#if defined(PDUMP) -+ struct { -+ SGX_INIT_OPERATION eOp; -+ IMG_UINT32 ui32Offset; -+ IMG_UINT32 ui32Value; -+ } sPDumpHWReg; -+#endif -+} SGX_INIT_COMMAND; -+ -+typedef struct _SGX_INIT_SCRIPTS_ -+{ -+ SGX_INIT_COMMAND asInitCommandsPart1[SGX_MAX_INIT_COMMANDS]; -+ SGX_INIT_COMMAND asInitCommandsPart2[SGX_MAX_INIT_COMMANDS]; -+ SGX_INIT_COMMAND asDeinitCommands[SGX_MAX_DEINIT_COMMANDS]; -+#if defined(SGX_FEATURE_MP) -+ SGX_INIT_COMMAND asSGXREGDebugCommandsPart1[SGX_MAX_PRINT_COMMANDS]; -+#endif -+ SGX_INIT_COMMAND *apsSGXREGDebugCommandsPart2[SGX_FEATURE_MP_CORE_COUNT_3D]; -+} SGX_INIT_SCRIPTS; -+ -+#if defined(__cplusplus) -+} -+#endif -+ -+#endif /* __SGXSCRIPT_H__ */ -+ -+/***************************************************************************** -+ End of file (sgxscript.h) -+*****************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_example/Kbuild.mk b/drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_example/Kbuild.mk -new file mode 100644 -index 0000000..e016d23 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_example/Kbuild.mk -@@ -0,0 +1,45 @@ -+########################################################################### ### -+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+#@License Dual MIT/GPLv2 -+# -+# The contents of this file are subject to the MIT license as set out below. -+# -+# Permission is hereby granted, free of charge, to any person obtaining a copy -+# of this software and associated documentation files (the "Software"), to deal -+# in the Software without restriction, including without limitation the rights -+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+# copies of the Software, and to permit persons to whom the Software is -+# furnished to do so, subject to the following conditions: -+# -+# The above copyright notice and this permission notice shall be included in -+# all copies or substantial portions of the Software. -+# -+# Alternatively, the contents of this file may be used under the terms of -+# the GNU General Public License Version 2 ("GPL") in which case the provisions -+# of GPL are applicable instead of those above. -+# -+# If you wish to allow use of your version of this file only under the terms of -+# GPL, and not to allow others to use your version of this file under the terms -+# of the MIT license, indicate your decision by deleting the provisions above -+# and replace them with the notice and other provisions required by GPL as set -+# out in the file called "GPL-COPYING" included in this distribution. If you do -+# not delete the provisions above, a recipient may use your version of this file -+# under the terms of either the MIT license or GPL. -+# -+# This License is also included in this distribution in the file called -+# "MIT-COPYING". -+# -+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+### ########################################################################### -+ccflags-y += -I$(TOP)/services4/3rdparty/bufferclass_example -+ -+bc_example-y += \ -+ services4/3rdparty/bufferclass_example/bufferclass_example.o \ -+ services4/3rdparty/bufferclass_example/bufferclass_example_linux.o \ -+ services4/3rdparty/bufferclass_example/bufferclass_example_private.o -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_example/Linux.mk b/drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_example/Linux.mk -new file mode 100644 -index 0000000..0f03c09 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_example/Linux.mk -@@ -0,0 +1,45 @@ -+########################################################################### ### -+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+#@License Dual MIT/GPLv2 -+# -+# The contents of this file are subject to the MIT license as set out below. -+# -+# Permission is hereby granted, free of charge, to any person obtaining a copy -+# of this software and associated documentation files (the "Software"), to deal -+# in the Software without restriction, including without limitation the rights -+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+# copies of the Software, and to permit persons to whom the Software is -+# furnished to do so, subject to the following conditions: -+# -+# The above copyright notice and this permission notice shall be included in -+# all copies or substantial portions of the Software. -+# -+# Alternatively, the contents of this file may be used under the terms of -+# the GNU General Public License Version 2 ("GPL") in which case the provisions -+# of GPL are applicable instead of those above. -+# -+# If you wish to allow use of your version of this file only under the terms of -+# GPL, and not to allow others to use your version of this file under the terms -+# of the MIT license, indicate your decision by deleting the provisions above -+# and replace them with the notice and other provisions required by GPL as set -+# out in the file called "GPL-COPYING" included in this distribution. If you do -+# not delete the provisions above, a recipient may use your version of this file -+# under the terms of either the MIT license or GPL. -+# -+# This License is also included in this distribution in the file called -+# "MIT-COPYING". -+# -+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+### ########################################################################### -+ -+modules := bufferclass_example -+ -+bufferclass_example_type := kernel_module -+bufferclass_example_target := bc_example.ko -+bufferclass_example_makefile := $(THIS_DIR)/Kbuild.mk -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_example/bufferclass_example.c b/drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_example/bufferclass_example.c -new file mode 100644 -index 0000000..889030b ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_example/bufferclass_example.c -@@ -0,0 +1,626 @@ -+/*************************************************************************/ /*! -+@Title bufferclass_example kernel driver -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+/************************************************************************** -+ The 3rd party driver is a specification of an API to integrate the IMG POWERVR -+ Services driver with a 3rd Party 'buffer device'. It is NOT a specification for -+ a 'buffer device' driver, rather a specification to extend the API for a -+ pre-existing driver for the 'buffer device' hardware. -+ -+ The 3rd party driver interface provides IMG POWERVR client drivers (e.g. PVR2D) -+ with an API abstraction of the system's underlying buffer device hardware, -+ allowing the client drivers to indirectly control the buffer device hardware -+ and access its associated memory. -+ -+ Functions of the API include -+ - query buffer device surface attributes (width, height, stride, pixel format, -+ CPU physical and virtual address) -+ -+ Note: having queried surface attributes the client drivers are able to map the -+ buffer device memory to any IMG POWERVR Services device by calling -+ PVRSRVMapDeviceClassMemory with the buffer device surface handle. -+ -+ This code is intended to be an example of how a pre-existing buffer device -+ driver may be extended to support the 3rd Party buffer device interface to -+ POWERVR Services -+ - IMG is not providing a buffer device driver implementation. -+ **************************************************************************/ -+#if defined(__linux__) -+#include <linux/string.h> -+#else -+#include <string.h> -+#endif -+ -+#include "bufferclass_example.h" -+ -+ -+ -+#define BUFFERCLASS_DEVICE_NAME "Example Bufferclass Device (SW)" -+ -+/* top level 'hook ptr' */ -+static void *gpvAnchor = NULL; -+static PFN_BC_GET_PVRJTABLE pfnGetPVRJTable = IMG_NULL; -+ -+/* -+ Kernel services is a kernel module and must be loaded first. -+ This driver is also a kernel module and must be loaded after the pvr services module. -+ This driver should be able to retrieve the -+ address of the services PVRGetBufferClassJTable from (the already loaded) -+ kernel services module. -+*/ -+ -+/* returns anchor pointer */ -+BC_EXAMPLE_DEVINFO * GetAnchorPtr(void) -+{ -+ return (BC_EXAMPLE_DEVINFO *)gpvAnchor; -+} -+ -+/* sets anchor pointer */ -+static void SetAnchorPtr(BC_EXAMPLE_DEVINFO *psDevInfo) -+{ -+ gpvAnchor = (void *)psDevInfo; -+} -+ -+ -+/* Open device function, called from services */ -+static PVRSRV_ERROR OpenBCDevice(IMG_UINT32 ui32DeviceID, IMG_HANDLE *phDevice) -+{ -+ BC_EXAMPLE_DEVINFO *psDevInfo; -+ -+ /* -+ bufferclass_example manages only one BufferClass device -+ therefore there is no need to track ID numbers. -+ */ -+ UNREFERENCED_PARAMETER(ui32DeviceID); -+ -+ psDevInfo = GetAnchorPtr(); -+ -+ /* return handle to the devinfo */ -+ *phDevice = (IMG_HANDLE)psDevInfo; -+ -+ return (PVRSRV_OK); -+} -+ -+ -+/* Close device function, called from services */ -+static PVRSRV_ERROR CloseBCDevice(IMG_UINT32 ui32DeviceID, IMG_HANDLE hDevice) -+{ -+ UNREFERENCED_PARAMETER(hDevice); -+ -+ return (PVRSRV_OK); -+} -+ -+/* Passes in the sync data for a buffer, and returns the handle */ -+/* called from services */ -+static PVRSRV_ERROR GetBCBuffer(IMG_HANDLE hDevice, -+ IMG_UINT32 ui32BufferNumber, -+ PVRSRV_SYNC_DATA *psSyncData, -+ IMG_HANDLE *phBuffer) -+{ -+ BC_EXAMPLE_DEVINFO *psDevInfo; -+ -+ if(!hDevice || !phBuffer) -+ { -+ return (PVRSRV_ERROR_INVALID_PARAMS); -+ } -+ -+ psDevInfo = (BC_EXAMPLE_DEVINFO*)hDevice; -+ -+ if( ui32BufferNumber < psDevInfo->sBufferInfo.ui32BufferCount ) -+ { -+ psDevInfo->psSystemBuffer[ui32BufferNumber].psSyncData = psSyncData; -+ *phBuffer = (IMG_HANDLE)&psDevInfo->psSystemBuffer[ui32BufferNumber]; -+ } -+ else -+ { -+ return (PVRSRV_ERROR_INVALID_PARAMS); -+ } -+ -+ return (PVRSRV_OK); -+} -+ -+ -+/* get buffer info function, called from services */ -+static PVRSRV_ERROR GetBCInfo(IMG_HANDLE hDevice, BUFFER_INFO *psBCInfo) -+{ -+ BC_EXAMPLE_DEVINFO *psDevInfo; -+ -+ if(!hDevice || !psBCInfo) -+ { -+ return (PVRSRV_ERROR_INVALID_PARAMS); -+ } -+ -+ psDevInfo = (BC_EXAMPLE_DEVINFO*)hDevice; -+ -+ *psBCInfo = psDevInfo->sBufferInfo; -+ -+ return (PVRSRV_OK); -+} -+ -+ -+/* get buffer address function, called from services */ -+static PVRSRV_ERROR GetBCBufferAddr(IMG_HANDLE hDevice, -+ IMG_HANDLE hBuffer, -+ IMG_SYS_PHYADDR **ppsSysAddr, -+ IMG_UINT32 *pui32ByteSize, -+ IMG_VOID **ppvCpuVAddr, -+ IMG_HANDLE *phOSMapInfo, -+ IMG_BOOL *pbIsContiguous, -+ IMG_UINT32 *pui32TilingStride) -+{ -+ BC_EXAMPLE_BUFFER *psBuffer; -+ -+ PVR_UNREFERENCED_PARAMETER(pui32TilingStride); -+ -+ if(!hDevice || !hBuffer || !ppsSysAddr || !pui32ByteSize) -+ { -+ return (PVRSRV_ERROR_INVALID_PARAMS); -+ } -+ -+ psBuffer = (BC_EXAMPLE_BUFFER *) hBuffer; -+ -+ *ppvCpuVAddr = psBuffer->sCPUVAddr; -+ -+ *phOSMapInfo = IMG_NULL; -+ *pui32ByteSize = (IMG_UINT32)psBuffer->ulSize; -+ -+#if defined(BC_DISCONTIG_BUFFERS) -+ *ppsSysAddr = psBuffer->psSysAddr; -+ *pbIsContiguous = IMG_FALSE; -+#else -+ *ppsSysAddr = &psBuffer->sPageAlignSysAddr; -+ *pbIsContiguous = IMG_TRUE; -+#endif -+ -+ return (PVRSRV_OK); -+} -+ -+ -+/* -+ * Register the device with services module srvkm. -+ * This should only be done once at boot time. -+ */ -+BCE_ERROR BC_Example_Register(void) -+{ -+ BC_EXAMPLE_DEVINFO *psDevInfo; -+ -+ /* -+ - connect to services -+ - register with services -+ - allocate and setup private data structure -+ */ -+ -+ -+ /* -+ in kernel driver, data structures must be anchored to something for subsequent retrieval -+ this may be a single global pointer or TLS or something else - up to you -+ call API to retrieve this ptr -+ */ -+ -+ /* -+ get the anchor pointer -+ */ -+ psDevInfo = GetAnchorPtr(); -+ -+ if (psDevInfo == NULL) -+ { -+ /* allocate device info. structure */ -+ psDevInfo = (BC_EXAMPLE_DEVINFO *)BCAllocKernelMem(sizeof(BC_EXAMPLE_DEVINFO)); -+ -+ if(!psDevInfo) -+ { -+ return (BCE_ERROR_OUT_OF_MEMORY);/* failure */ -+ } -+ -+ /* set the top-level anchor */ -+ SetAnchorPtr((void*)psDevInfo); -+ -+ /* set ref count */ -+ psDevInfo->ulRefCount = 0; -+ -+ -+ if(BCOpenPVRServices(&psDevInfo->hPVRServices) != BCE_OK) -+ { -+ return (BCE_ERROR_INIT_FAILURE);/* failure */ -+ } -+ if(BCGetLibFuncAddr (psDevInfo->hPVRServices, "PVRGetBufferClassJTable", &pfnGetPVRJTable) != BCE_OK) -+ { -+ return (BCE_ERROR_INIT_FAILURE);/* failure */ -+ } -+ -+ /* got the kernel services function table */ -+ if(!(*pfnGetPVRJTable)(&psDevInfo->sPVRJTable)) -+ { -+ return (BCE_ERROR_INIT_FAILURE);/* failure */ -+ } -+ -+ /* -+ Setup the devinfo -+ */ -+ -+ psDevInfo->ulNumBuffers = 0; -+ -+ psDevInfo->psSystemBuffer = BCAllocKernelMem(sizeof(BC_EXAMPLE_BUFFER) * BC_EXAMPLE_NUM_BUFFERS); -+ -+ if(!psDevInfo->psSystemBuffer) -+ { -+ return (BCE_ERROR_OUT_OF_MEMORY);/* failure */ -+ } -+ -+ /* Setup Buffer Info */ -+ psDevInfo->sBufferInfo.pixelformat = PVRSRV_PIXEL_FORMAT_UNKNOWN; -+ psDevInfo->sBufferInfo.ui32Width = 0; -+ psDevInfo->sBufferInfo.ui32Height = 0; -+ psDevInfo->sBufferInfo.ui32ByteStride = 0; -+ psDevInfo->sBufferInfo.ui32BufferDeviceID = BC_EXAMPLE_DEVICEID; -+ psDevInfo->sBufferInfo.ui32Flags = 0; -+ psDevInfo->sBufferInfo.ui32BufferCount = (IMG_UINT32)psDevInfo->ulNumBuffers; -+ -+ strncpy(psDevInfo->sBufferInfo.szDeviceName, BUFFERCLASS_DEVICE_NAME, MAX_BUFFER_DEVICE_NAME_SIZE); -+ -+ /* -+ Bsetup the BC Jtable so SRVKM can call into this driver -+ */ -+ psDevInfo->sBCJTable.ui32TableSize = sizeof(PVRSRV_BC_SRV2BUFFER_KMJTABLE); -+ psDevInfo->sBCJTable.pfnOpenBCDevice = OpenBCDevice; -+ psDevInfo->sBCJTable.pfnCloseBCDevice = CloseBCDevice; -+ psDevInfo->sBCJTable.pfnGetBCBuffer = GetBCBuffer; -+ psDevInfo->sBCJTable.pfnGetBCInfo = GetBCInfo; -+ psDevInfo->sBCJTable.pfnGetBufferAddr = GetBCBufferAddr; -+ -+ -+ /* register device with services and retrieve device index */ -+ /* This example only registers 1 device, but for multiple buffer streams, register more devices */ -+ if(psDevInfo->sPVRJTable.pfnPVRSRVRegisterBCDevice (&psDevInfo->sBCJTable, -+ (IMG_UINT32*)&psDevInfo->ulDeviceID ) != PVRSRV_OK) -+ { -+ return (BCE_ERROR_DEVICE_REGISTER_FAILED);/* failure */ -+ } -+ } -+ -+ /* increment the ref count */ -+ psDevInfo->ulRefCount++; -+ -+ /* return success */ -+ return (BCE_OK); -+} -+ -+/* -+ * Unregister the device with services module srvkm. -+ */ -+BCE_ERROR BC_Example_Unregister(void) -+{ -+ BC_EXAMPLE_DEVINFO *psDevInfo; -+ -+ psDevInfo = GetAnchorPtr(); -+ -+ /* check DevInfo has been setup */ -+ if (psDevInfo == NULL) -+ { -+ return (BCE_ERROR_GENERIC);/* failure */ -+ } -+ /* decrement ref count */ -+ psDevInfo->ulRefCount--; -+ -+ if (psDevInfo->ulRefCount == 0) -+ { -+ /* all references gone - de-init device information */ -+ PVRSRV_BC_BUFFER2SRV_KMJTABLE *psJTable = &psDevInfo->sPVRJTable; -+ -+ -+ /* Remove the device from kernel services device register */ -+ if (psJTable->pfnPVRSRVRemoveBCDevice(psDevInfo->ulDeviceID) != PVRSRV_OK) -+ { -+ return (BCE_ERROR_GENERIC);/* failure */ -+ } -+ -+ if (BCClosePVRServices(psDevInfo->hPVRServices) != BCE_OK) -+ { -+ psDevInfo->hPVRServices = NULL; -+ return (BCE_ERROR_GENERIC);/* failure */ -+ } -+ -+ if (psDevInfo->psSystemBuffer) -+ { -+ BCFreeKernelMem(psDevInfo->psSystemBuffer); -+ } -+ -+ /* de-allocate data structure */ -+ BCFreeKernelMem(psDevInfo); -+ -+ /* clear the top-level anchor */ -+ SetAnchorPtr(NULL); -+ } -+ -+ /* return success */ -+ return (BCE_OK); -+} -+ -+ -+/* -+ * Create shared buffers. -+ */ -+BCE_ERROR BC_Example_Buffers_Create(void) -+{ -+ BC_EXAMPLE_DEVINFO *psDevInfo; -+ unsigned long i; -+#if !defined(BC_DISCONTIG_BUFFERS) -+ IMG_CPU_PHYADDR sSystemBufferCPUPAddr; -+#endif -+ PVRSRV_PIXEL_FORMAT pixelformat = BC_EXAMPLE_PIXELFORMAT; -+ static IMG_UINT32 ui32Width = BC_EXAMPLE_WIDTH; -+ static IMG_UINT32 ui32Height = BC_EXAMPLE_HEIGHT; -+ static IMG_UINT32 ui32ByteStride = BC_EXAMPLE_STRIDE; -+ -+ IMG_UINT32 ui32MaxWidth = 320 * 4; -+ -+ /* -+ get the anchor pointer -+ */ -+ psDevInfo = GetAnchorPtr(); -+ if (psDevInfo == NULL) -+ { -+ /* -+ * This device was not correctly registered/created. -+ */ -+ return (BCE_ERROR_DEVICE_REGISTER_FAILED); -+ } -+ if (psDevInfo->ulNumBuffers) -+ { -+ /* Buffers already allocated */ -+ return (BCE_ERROR_GENERIC); -+ } -+ -+ /* Setup Buffer Info */ -+ psDevInfo->sBufferInfo.pixelformat = BC_EXAMPLE_PIXELFORMAT; -+ psDevInfo->sBufferInfo.ui32Width = ui32Width; -+ psDevInfo->sBufferInfo.ui32Height = ui32Height; -+ psDevInfo->sBufferInfo.ui32ByteStride = ui32ByteStride; -+ psDevInfo->sBufferInfo.ui32BufferDeviceID = BC_EXAMPLE_DEVICEID; -+ psDevInfo->sBufferInfo.ui32Flags = PVRSRV_BC_FLAGS_YUVCSC_FULL_RANGE | PVRSRV_BC_FLAGS_YUVCSC_BT601; -+ -+ for(i=psDevInfo->ulNumBuffers; i < BC_EXAMPLE_NUM_BUFFERS; i++) -+ { -+ unsigned long ulSize = (unsigned long)(ui32Height * ui32ByteStride); -+ -+ if(psDevInfo->sBufferInfo.pixelformat == PVRSRV_PIXEL_FORMAT_NV12) -+ { -+ /* Second plane is quarter size, but 2bytes per pixel */ -+ ulSize += ((ui32ByteStride >> 1) * (ui32Height >> 1) << 1); -+ } -+ else if(psDevInfo->sBufferInfo.pixelformat == PVRSRV_PIXEL_FORMAT_YV12) -+ { -+ /* Second plane is quarter size, but 1byte per pixel */ -+ ulSize += (ui32ByteStride >> 1) * (ui32Height >> 1); -+ -+ /* third plane is quarter size, but 1byte per pixel */ -+ ulSize += (ui32ByteStride >> 1) * (ui32Height >> 1); -+ } -+ -+#if defined(BC_DISCONTIG_BUFFERS) -+ if (BCAllocDiscontigMemory(ulSize, -+ &psDevInfo->psSystemBuffer[i].hMemHandle, -+ &psDevInfo->psSystemBuffer[i].sCPUVAddr, -+ &psDevInfo->psSystemBuffer[i].psSysAddr) != BCE_OK) -+ { -+ break; -+ } -+#else -+ /* Setup system buffer */ -+ if (BCAllocContigMemory(ulSize, -+ &psDevInfo->psSystemBuffer[i].hMemHandle, -+ &psDevInfo->psSystemBuffer[i].sCPUVAddr, -+ &sSystemBufferCPUPAddr) != BCE_OK) -+ { -+ break; -+ } -+ psDevInfo->psSystemBuffer[i].sSysAddr = CpuPAddrToSysPAddrBC(sSystemBufferCPUPAddr); -+ psDevInfo->psSystemBuffer[i].sPageAlignSysAddr.uiAddr = (psDevInfo->psSystemBuffer[i].sSysAddr.uiAddr & 0xFFFFF000); -+#endif -+ -+ psDevInfo->ulNumBuffers++; -+ -+ psDevInfo->psSystemBuffer[i].ulSize = ulSize; -+ psDevInfo->psSystemBuffer[i].psSyncData = NULL; -+ } -+ -+ psDevInfo->sBufferInfo.ui32BufferCount = (IMG_UINT32)psDevInfo->ulNumBuffers; -+ -+ /* -+ Bsetup the BC Jtable so SRVKM can call into this driver -+ */ -+ psDevInfo->sBCJTable.ui32TableSize = sizeof(PVRSRV_BC_SRV2BUFFER_KMJTABLE); -+ psDevInfo->sBCJTable.pfnOpenBCDevice = OpenBCDevice; -+ psDevInfo->sBCJTable.pfnCloseBCDevice = CloseBCDevice; -+ psDevInfo->sBCJTable.pfnGetBCBuffer = GetBCBuffer; -+ psDevInfo->sBCJTable.pfnGetBCInfo = GetBCInfo; -+ psDevInfo->sBCJTable.pfnGetBufferAddr = GetBCBufferAddr; -+ -+ -+ -+ /* Update buffer's parameters for reconfiguration next time */ -+ if (ui32Width < ui32MaxWidth) -+ { -+ switch(pixelformat) -+ { -+ case PVRSRV_PIXEL_FORMAT_NV12: -+ case PVRSRV_PIXEL_FORMAT_YV12: -+ { -+ ui32Width += 320; -+ ui32Height += 160; -+ ui32ByteStride = ui32Width; -+ break; -+ } -+ case PVRSRV_PIXEL_FORMAT_FOURCC_ORG_VYUY: -+ case PVRSRV_PIXEL_FORMAT_FOURCC_ORG_UYVY: -+ case PVRSRV_PIXEL_FORMAT_FOURCC_ORG_YUYV: -+ case PVRSRV_PIXEL_FORMAT_FOURCC_ORG_YVYU: -+ { -+ ui32Width += 320; -+ ui32Height += 160; -+ ui32ByteStride = ui32Width*2; -+ break; -+ } -+ case PVRSRV_PIXEL_FORMAT_RGB565: -+ { -+ ui32Width += 320; -+ ui32Height += 160; -+ ui32ByteStride = ui32Width*2; -+ break; -+ } -+ default: -+ { -+ return (BCE_ERROR_INVALID_PARAMS); -+ } -+ } -+ } -+ else -+ { -+ ui32Width = BC_EXAMPLE_WIDTH; -+ ui32Height = BC_EXAMPLE_HEIGHT; -+ ui32ByteStride = BC_EXAMPLE_STRIDE; -+ } -+ -+ /* return success */ -+ return (BCE_OK); -+} -+ -+ -+/* -+ * Destroy shared buffers. -+ */ -+BCE_ERROR BC_Example_Buffers_Destroy(void) -+{ -+ BC_EXAMPLE_DEVINFO *psDevInfo; -+ unsigned long i; -+ -+ psDevInfo = GetAnchorPtr(); -+ -+ /* check DevInfo has been setup */ -+ if (psDevInfo == NULL) -+ { -+ /* -+ This device was not correctly registered/created. -+ */ -+ return (BCE_ERROR_DEVICE_REGISTER_FAILED); -+ } -+ -+ /* -+ Free all allocated surfaces -+ */ -+ for(i = 0; i < psDevInfo->ulNumBuffers; i++) -+ { -+#if defined(BC_DISCONTIG_BUFFERS) -+ BCFreeDiscontigMemory(psDevInfo->psSystemBuffer[i].ulSize, -+ psDevInfo->psSystemBuffer[i].hMemHandle, -+ psDevInfo->psSystemBuffer[i].sCPUVAddr, -+ psDevInfo->psSystemBuffer[i].psSysAddr); -+#else -+ BCFreeContigMemory(psDevInfo->psSystemBuffer[i].ulSize, -+ psDevInfo->psSystemBuffer[i].hMemHandle, -+ psDevInfo->psSystemBuffer[i].sCPUVAddr, -+ SysPAddrToCpuPAddrBC(psDevInfo->psSystemBuffer[i].sSysAddr)); -+#endif -+ } -+ psDevInfo->ulNumBuffers = 0; -+ -+ /* Reset buffer info */ -+ psDevInfo->sBufferInfo.pixelformat = PVRSRV_PIXEL_FORMAT_UNKNOWN; -+ psDevInfo->sBufferInfo.ui32Width = 0; -+ psDevInfo->sBufferInfo.ui32Height = 0; -+ psDevInfo->sBufferInfo.ui32ByteStride = 0; -+ psDevInfo->sBufferInfo.ui32BufferDeviceID = BC_EXAMPLE_DEVICEID; -+ psDevInfo->sBufferInfo.ui32Flags = 0; -+ psDevInfo->sBufferInfo.ui32BufferCount = (IMG_UINT32)psDevInfo->ulNumBuffers; -+ -+ /* return success */ -+ return (BCE_OK); -+} -+ -+ -+/* -+ * This function does both registration and buffer allocation at -+ * boot time. -+ */ -+BCE_ERROR BC_Example_Init(void) -+{ -+ BCE_ERROR eError; -+ -+ eError = BC_Example_Register(); -+ if (eError != BCE_OK) -+ { -+ return eError; -+ } -+ -+ eError = BC_Example_Buffers_Create(); -+ if (eError != BCE_OK) -+ { -+ return eError; -+ } -+ -+ return (BCE_OK); -+} -+ -+/* -+ * Destroy buffers and unregister device. -+ */ -+BCE_ERROR BC_Example_Deinit(void) -+{ -+ BCE_ERROR eError; -+ -+ eError = BC_Example_Buffers_Destroy(); -+ if (eError != BCE_OK) -+ { -+ return eError; -+ } -+ -+ eError = BC_Example_Unregister(); -+ if (eError != BCE_OK) -+ { -+ return eError; -+ } -+ -+ return (BCE_OK); -+} -+ -+/****************************************************************************** -+ End of file (bufferclass_example.c) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_example/bufferclass_example.h b/drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_example/bufferclass_example.h -new file mode 100644 -index 0000000..3dbf3f1 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_example/bufferclass_example.h -@@ -0,0 +1,237 @@ -+/*************************************************************************/ /*! -+@Title bufferclass_example kernel driver structures and prototypes -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+#ifndef __BC_EXAMPLE_H__ -+#define __BC_EXAMPLE_H__ -+ -+/* IMG services headers */ -+#include "img_defs.h" -+#include "servicesext.h" -+#include "kernelbuffer.h" -+ -+#if defined(__cplusplus) -+extern "C" { -+#endif -+ -+#define BC_EXAMPLE_NUM_BUFFERS 3 -+ -+#define NV12 1 -+//#define YV12 1 -+//#define YUV422 1 -+ -+#ifdef NV12 -+ -+#define BC_EXAMPLE_WIDTH (320) -+#define BC_EXAMPLE_HEIGHT (160) -+#define BC_EXAMPLE_STRIDE (320) -+#define BC_EXAMPLE_PIXELFORMAT (PVRSRV_PIXEL_FORMAT_NV12) -+ -+#else -+#ifdef YV12 -+ -+#define BC_EXAMPLE_WIDTH (320) -+#define BC_EXAMPLE_HEIGHT (160) -+#define BC_EXAMPLE_STRIDE (320) -+#define BC_EXAMPLE_PIXELFORMAT (PVRSRV_PIXEL_FORMAT_YV12) -+ -+#else -+#ifdef YUV422 -+ -+#define BC_EXAMPLE_WIDTH (320) -+#define BC_EXAMPLE_HEIGHT (160) -+#define BC_EXAMPLE_STRIDE (320*2) -+#define BC_EXAMPLE_PIXELFORMAT (PVRSRV_PIXEL_FORMAT_FOURCC_ORG_UYVY) -+ -+#else -+ -+#define BC_EXAMPLE_WIDTH (320) -+#define BC_EXAMPLE_HEIGHT (160) -+#define BC_EXAMPLE_STRIDE (320*2) -+#define BC_EXAMPLE_PIXELFORMAT (PVRSRV_PIXEL_FORMAT_RGB565) -+ -+#endif -+#endif -+#endif -+ -+#define BC_EXAMPLE_DEVICEID 0 -+ -+typedef void * BCE_HANDLE; -+ -+typedef enum tag_bce_bool -+{ -+ BCE_FALSE = 0, -+ BCE_TRUE = 1, -+} BCE_BOOL, *BCE_PBOOL; -+ -+/* BC_NOHW buffer structure */ -+typedef struct BC_EXAMPLE_BUFFER_TAG -+{ -+ unsigned long ulSize; -+ BCE_HANDLE hMemHandle; -+ -+ /* IMG structures used, to minimise API function code */ -+ /* replace with own structures where necessary */ -+#if defined(BC_DISCONTIG_BUFFERS) -+ IMG_SYS_PHYADDR *psSysAddr; -+#else -+ IMG_SYS_PHYADDR sSysAddr; -+ IMG_SYS_PHYADDR sPageAlignSysAddr; -+#endif -+ IMG_CPU_VIRTADDR sCPUVAddr; -+ PVRSRV_SYNC_DATA *psSyncData; -+ -+ struct BC_EXAMPLE_BUFFER_TAG *psNext; -+} BC_EXAMPLE_BUFFER; -+ -+ -+/* kernel device information structure */ -+typedef struct BC_EXAMPLE_DEVINFO_TAG -+{ -+ unsigned long ulDeviceID; -+ -+ BC_EXAMPLE_BUFFER *psSystemBuffer; -+ -+ /* number of supported buffers */ -+ unsigned long ulNumBuffers; -+ -+ /* jump table into PVR services */ -+ PVRSRV_BC_BUFFER2SRV_KMJTABLE sPVRJTable; -+ -+ /* jump table into BC */ -+ PVRSRV_BC_SRV2BUFFER_KMJTABLE sBCJTable; -+ -+ /* -+ handle for connection to kernel services -+ - OS specific - may not be required -+ */ -+ BCE_HANDLE hPVRServices; -+ -+ /* ref count */ -+ unsigned long ulRefCount; -+ -+ /* IMG structures used, to minimise API function code */ -+ /* replace with own structures where necessary */ -+ BUFFER_INFO sBufferInfo; -+ -+} BC_EXAMPLE_DEVINFO; -+ -+ -+/*! -+ ***************************************************************************** -+ * Error values -+ *****************************************************************************/ -+typedef enum _BCE_ERROR_ -+{ -+ BCE_OK = 0, -+ BCE_ERROR_GENERIC = 1, -+ BCE_ERROR_OUT_OF_MEMORY = 2, -+ BCE_ERROR_TOO_FEW_BUFFERS = 3, -+ BCE_ERROR_INVALID_PARAMS = 4, -+ BCE_ERROR_INIT_FAILURE = 5, -+ BCE_ERROR_CANT_REGISTER_CALLBACK = 6, -+ BCE_ERROR_INVALID_DEVICE = 7, -+ BCE_ERROR_DEVICE_REGISTER_FAILED = 8, -+ BCE_ERROR_NO_PRIMARY = 9 -+} BCE_ERROR; -+ -+ -+#ifndef UNREFERENCED_PARAMETER -+#define UNREFERENCED_PARAMETER(param) (param) = (param) -+#endif -+ -+#ifndef NULL -+#define NULL 0 -+#endif -+ -+BCE_ERROR BC_Example_Register(void); -+BCE_ERROR BC_Example_Unregister(void); -+BCE_ERROR BC_Example_Buffers_Create(void); -+BCE_ERROR BC_Example_Buffers_Destroy(void); -+BCE_ERROR BC_Example_Init(void); -+BCE_ERROR BC_Example_Deinit(void); -+ -+/* OS Specific APIs */ -+BCE_ERROR BCOpenPVRServices(BCE_HANDLE *phPVRServices); -+BCE_ERROR BCClosePVRServices(BCE_HANDLE hPVRServices); -+ -+void *BCAllocKernelMem(unsigned long ulSize); -+void BCFreeKernelMem(void *pvMem); -+#if defined(BC_DISCONTIG_BUFFERS) -+BCE_ERROR BCAllocDiscontigMemory(unsigned long ulSize, -+ BCE_HANDLE unref__ *phMemHandle, -+ IMG_CPU_VIRTADDR *pLinAddr, -+ IMG_SYS_PHYADDR **ppPhysAddr); -+ -+void BCFreeDiscontigMemory(unsigned long ulSize, -+ BCE_HANDLE unref__ hMemHandle, -+ IMG_CPU_VIRTADDR LinAddr, -+ IMG_SYS_PHYADDR *pPhysAddr); -+ -+#else -+ -+BCE_ERROR BCAllocContigMemory(unsigned long ulSize, -+ BCE_HANDLE *phMemHandle, -+ IMG_CPU_VIRTADDR *pLinAddr, -+ IMG_CPU_PHYADDR *pPhysAddr); -+ -+void BCFreeContigMemory(unsigned long ulSize, -+ BCE_HANDLE hMemHandle, -+ IMG_CPU_VIRTADDR LinAddr, -+ IMG_CPU_PHYADDR PhysAddr); -+#endif -+ -+IMG_SYS_PHYADDR CpuPAddrToSysPAddrBC(IMG_CPU_PHYADDR cpu_paddr); -+IMG_CPU_PHYADDR SysPAddrToCpuPAddrBC(IMG_SYS_PHYADDR sys_paddr); -+ -+void *MapPhysAddr(IMG_SYS_PHYADDR sSysAddr, unsigned long ulSize); -+void UnMapPhysAddr(void *pvAddr, unsigned long ulSize); -+ -+BCE_ERROR BCGetLibFuncAddr (BCE_HANDLE hExtDrv, char *szFunctionName, PFN_BC_GET_PVRJTABLE *ppfnFuncTable); -+BC_EXAMPLE_DEVINFO * GetAnchorPtr(void); -+ -+#if defined(__cplusplus) -+} -+#endif -+ -+#endif /* __BC_EXAMPLE_H__ */ -+ -+/****************************************************************************** -+ End of file (bufferclass_example.h) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_example/bufferclass_example_linux.c b/drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_example/bufferclass_example_linux.c -new file mode 100644 -index 0000000..b1da897 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_example/bufferclass_example_linux.c -@@ -0,0 +1,609 @@ -+/*************************************************************************/ /*! -+@Title bufferclass example linux specific implementations -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+/************************************************************************** -+ The 3rd party driver is a specification of an API to integrate the IMG POWERVR -+ Services driver with 3rd Party display hardware. It is NOT a specification for -+ a display controller driver, rather a specification to extend the API for a -+ pre-existing driver for the display hardware. -+ -+ The 3rd party driver interface provides IMG POWERVR client drivers (e.g. PVR2D) -+ with an API abstraction of the system's underlying display hardware, allowing -+ the client drivers to indirectly control the display hardware and access its -+ associated memory. -+ -+ Functions of the API include -+ - query primary surface attributes (width, height, stride, pixel format, CPU -+ physical and virtual address) -+ - swap/flip chain creation and subsequent query of surface attributes -+ - asynchronous display surface flipping, taking account of asynchronous read -+ (flip) and write (render) operations to the display surface -+ -+ Note: having queried surface attributes the client drivers are able to map the -+ display memory to any IMG POWERVR Services device by calling -+ PVRSRVMapDeviceClassMemory with the display surface handle. -+ -+ This code is intended to be an example of how a pre-existing display driver may -+ be extended to support the 3rd Party Display interface to POWERVR Services -+ - IMG is not providing a display driver implementation. -+ **************************************************************************/ -+ -+#include <linux/version.h> -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/slab.h> -+#include <linux/fs.h> -+#include <asm/uaccess.h> -+#include <asm/io.h> -+ -+#if defined(LMA) -+#include <linux/pci.h> -+#else -+#include <linux/dma-mapping.h> -+#endif -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)) -+#include <linux/mutex.h> -+#endif -+ -+#if defined(BC_DISCONTIG_BUFFERS) -+#include <linux/vmalloc.h> -+#endif -+ -+#include "bufferclass_example.h" -+#include "bufferclass_example_linux.h" -+#include "bufferclass_example_private.h" -+ -+#include "pvrmodule.h" -+ -+#define DEVNAME "bc_example" -+#define DRVNAME DEVNAME -+ -+#if defined(BCE_USE_SET_MEMORY) -+#undef BCE_USE_SET_MEMORY -+#endif -+ -+#if (defined(__i386__) || defined(__x86_64__)) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)) && defined(SUPPORT_LINUX_X86_PAT) && defined(SUPPORT_LINUX_X86_WRITECOMBINE) -+#include <asm/cacheflush.h> -+#define BCE_USE_SET_MEMORY -+#endif -+ -+MODULE_SUPPORTED_DEVICE(DEVNAME); -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)) -+static long BC_Example_Bridge_Unlocked(struct file *file, unsigned int cmd, unsigned long arg); -+#else -+static int BC_Example_Bridge(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); -+#endif -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)) -+static DEFINE_MUTEX(sBCExampleBridgeMutex); -+#endif -+ -+#if defined(LDM_PLATFORM) || defined(LDM_PCI) -+/* -+ * Device class used for /sys entries (and udev device node creation) -+ */ -+static struct class *psPvrClass; -+#endif -+ -+/* -+ * This is the major number we use for all nodes in /dev. -+ */ -+static int AssignedMajorNumber; -+ -+static struct file_operations bufferclass_example_fops = { -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)) -+ .unlocked_ioctl = BC_Example_Bridge_Unlocked -+#else -+ .ioctl = BC_Example_Bridge -+#endif -+}; -+ -+ -+#define unref__ __attribute__ ((unused)) -+ -+#if defined(LMA) -+#define PVR_BUFFERCLASS_MEMOFFSET (220 * 1024 * 1024) /* Must be after services localmem region */ -+#define PVR_BUFFERCLASS_MEMSIZE (4 * 1024 * 1024) /* Must be before displayclass localmem region */ -+ -+unsigned long g_ulMemBase = 0; -+unsigned long g_ulMemCurrent = 0; -+ -+/* PVR device vendor ID */ -+#define VENDOR_ID_PVR 0x1010 -+#define DEVICE_ID_PVR 0x1CF1 -+ -+#define DEVICE_ID1_PVR 0x1CF2 -+ -+ -+/* PDP mem (including HP mapping) on base register 2 */ -+#define PVR_MEM_PCI_BASENUM 2 -+#endif -+ -+ -+/***************************************************************************** -+ Function Name: BC_Example_ModInit -+ Description : Insert the driver into the kernel. -+ -+ The device major number is allocated by the kernel dynamically -+ if AssignedMajorNumber is zero on entry. This means that the -+ device node (nominally /dev/bc_example) may need to be re-made if -+ the kernel varies the major number it assigns. The number -+ does seem to stay constant between runs, but I don't think -+ this is guaranteed. The node is made as root on the shell -+ with: -+ -+ mknod /dev/bc_example c ? 0 -+ -+ where ? is the major number reported by the printk() - look -+ at the boot log using `dmesg' to see this). -+ -+ __init places the function in a special memory section that -+ the kernel frees once the function has been run. Refer also -+ to module_init() macro call below. -+ -+*****************************************************************************/ -+static int __init BC_Example_ModInit(void) -+{ -+#if defined(LDM_PLATFORM) || defined(LDM_PCI) -+ struct device *psDev; -+#endif -+ -+#if defined(LMA) -+ struct pci_dev *psPCIDev; -+ int error; -+#endif -+ -+#if defined(LMA) -+ psPCIDev = pci_get_device(VENDOR_ID_PVR, DEVICE_ID_PVR, NULL); -+ if (psPCIDev == NULL) -+ { -+ /* Try an alternative PCI ID */ -+ psPCIDev = pci_get_device(VENDOR_ID_PVR, DEVICE_ID1_PVR, NULL); -+ } -+ -+ if (psPCIDev == NULL) -+ { -+ printk(KERN_ERR DRVNAME ": BC_Example_ModInit: pci_get_device failed\n"); -+ -+ goto ExitError; -+ } -+ -+ if ((error = pci_enable_device(psPCIDev)) != 0) -+ { -+ printk(KERN_ERR DRVNAME ": BC_Example_ModInit: pci_enable_device failed (%d)\n", error); -+ goto ExitError; -+ } -+#endif -+ -+ AssignedMajorNumber = register_chrdev(0, DEVNAME, &bufferclass_example_fops); -+ -+ if (AssignedMajorNumber <= 0) -+ { -+ printk(KERN_ERR DRVNAME ": BC_Example_ModInit: unable to get major number\n"); -+ -+ goto ExitDisable; -+ } -+ -+#if defined(DEBUG) -+ printk(KERN_ERR DRVNAME ": BC_Example_ModInit: major device %d\n", AssignedMajorNumber); -+#endif -+ -+#if defined(LDM_PLATFORM) || defined(LDM_PCI) -+ /* -+ * This code (using GPL symbols) facilitates automatic device -+ * node creation on platforms with udev (or similar). -+ */ -+ psPvrClass = class_create(THIS_MODULE, "bc_example"); -+ -+ if (IS_ERR(psPvrClass)) -+ { -+ printk(KERN_ERR DRVNAME ": BC_Example_ModInit: unable to create class (%ld)", PTR_ERR(psPvrClass)); -+ goto ExitUnregister; -+ } -+ -+ psDev = device_create(psPvrClass, NULL, MKDEV(AssignedMajorNumber, 0), -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)) -+ NULL, -+#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)) */ -+ DEVNAME); -+ if (IS_ERR(psDev)) -+ { -+ printk(KERN_ERR DRVNAME ": BC_Example_ModInit: unable to create device (%ld)", PTR_ERR(psDev)); -+ goto ExitDestroyClass; -+ } -+#endif /* defined(LDM_PLATFORM) || defined(LDM_PCI) */ -+ -+#if defined(LMA) -+ /* -+ * We don't do a pci_request_region for PVR_MEM_PCI_BASENUM, -+ * we assume the SGX driver has done this already. -+ */ -+ g_ulMemBase = pci_resource_start(psPCIDev, PVR_MEM_PCI_BASENUM) + PVR_BUFFERCLASS_MEMOFFSET; -+#endif -+ -+ if(BC_Example_Init() != BCE_OK) -+ { -+ printk (KERN_ERR DRVNAME ": BC_Example_ModInit: can't init device\n"); -+ goto ExitUnregister; -+ } -+ -+#if defined(LMA) -+ /* -+ * To prevent possible problems with system suspend/resume, we don't -+ * keep the device enabled, but rely on the fact that the SGX driver -+ * will have done a pci_enable_device. -+ */ -+ pci_disable_device(psPCIDev); -+#endif -+ -+ return 0; -+ -+#if defined(LDM_PLATFORM) || defined(LDM_PCI) -+ExitDestroyClass: -+ class_destroy(psPvrClass); -+#endif -+ExitUnregister: -+ unregister_chrdev(AssignedMajorNumber, DEVNAME); -+ExitDisable: -+#if defined(LMA) -+ pci_disable_device(psPCIDev); -+ExitError: -+#endif -+ return -EBUSY; -+} /*BC_Example_ModInit*/ -+ -+/***************************************************************************** -+ Function Name: BC_Example_ModInit -+ Description : Remove the driver from the kernel. -+ -+ __exit places the function in a special memory section that -+ the kernel frees once the function has been run. Refer also -+ to module_exit() macro call below. -+ -+*****************************************************************************/ -+static void __exit BC_Example_ModCleanup(void) -+{ -+#if defined(LDM_PLATFORM) || defined(LDM_PCI) -+ device_destroy(psPvrClass, MKDEV(AssignedMajorNumber, 0)); -+ class_destroy(psPvrClass); -+#endif -+ -+ unregister_chrdev(AssignedMajorNumber, DEVNAME); -+ -+ if(BC_Example_Deinit() != BCE_OK) -+ { -+ printk (KERN_ERR DRVNAME ": BC_Example_ModCleanup: can't deinit device\n"); -+ } -+ -+} /*BC_Example_ModCleanup*/ -+ -+ -+void *BCAllocKernelMem(unsigned long ulSize) -+{ -+ return kmalloc(ulSize, GFP_KERNEL); -+} -+ -+void BCFreeKernelMem(void *pvMem) -+{ -+ kfree(pvMem); -+} -+ -+#if defined(BC_DISCONTIG_BUFFERS) -+ -+#define RANGE_TO_PAGES(range) (((range) + (PAGE_SIZE - 1)) >> PAGE_SHIFT) -+#define VMALLOC_TO_PAGE_PHYS(vAddr) page_to_phys(vmalloc_to_page(vAddr)) -+ -+BCE_ERROR BCAllocDiscontigMemory(unsigned long ulSize, -+ BCE_HANDLE unref__ *phMemHandle, -+ IMG_CPU_VIRTADDR *pLinAddr, -+ IMG_SYS_PHYADDR **ppPhysAddr) -+{ -+ unsigned long ulPages = RANGE_TO_PAGES(ulSize); -+ IMG_SYS_PHYADDR *pPhysAddr; -+ unsigned long ulPage; -+ IMG_CPU_VIRTADDR LinAddr; -+ -+ LinAddr = __vmalloc(ulSize, GFP_KERNEL | __GFP_HIGHMEM, pgprot_noncached(PAGE_KERNEL)); -+ if (!LinAddr) -+ { -+ return BCE_ERROR_OUT_OF_MEMORY; -+ } -+ -+ pPhysAddr = kmalloc(ulPages * sizeof(IMG_SYS_PHYADDR), GFP_KERNEL); -+ if (!pPhysAddr) -+ { -+ vfree(LinAddr); -+ return BCE_ERROR_OUT_OF_MEMORY; -+ } -+ -+ *pLinAddr = LinAddr; -+ -+ for (ulPage = 0; ulPage < ulPages; ulPage++) -+ { -+ pPhysAddr[ulPage].uiAddr = VMALLOC_TO_PAGE_PHYS(LinAddr); -+ -+ LinAddr += PAGE_SIZE; -+ } -+ -+ *ppPhysAddr = pPhysAddr; -+ -+ return BCE_OK; -+} -+ -+void BCFreeDiscontigMemory(unsigned long ulSize, -+ BCE_HANDLE unref__ hMemHandle, -+ IMG_CPU_VIRTADDR LinAddr, -+ IMG_SYS_PHYADDR *pPhysAddr) -+{ -+ kfree(pPhysAddr); -+ -+ vfree(LinAddr); -+} -+#else /* defined(BC_DISCONTIG_BUFFERS) */ -+ -+BCE_ERROR BCAllocContigMemory(unsigned long ulSize, -+ BCE_HANDLE unref__ *phMemHandle, -+ IMG_CPU_VIRTADDR *pLinAddr, -+ IMG_CPU_PHYADDR *pPhysAddr) -+{ -+#if defined(LMA) -+ void *pvLinAddr; -+ -+ /* Only allowed a certain amount of memory for bufferclass buffers */ -+ if(g_ulMemCurrent + ulSize >= PVR_BUFFERCLASS_MEMSIZE) -+ { -+ return (BCE_ERROR_OUT_OF_MEMORY); -+ } -+ -+ pvLinAddr = ioremap(g_ulMemBase + g_ulMemCurrent, ulSize); -+ -+ if(pvLinAddr) -+ { -+ pPhysAddr->uiAddr = g_ulMemBase + g_ulMemCurrent; -+ *pLinAddr = pvLinAddr; -+ -+ /* Not a real allocator; just increment the current address */ -+ g_ulMemCurrent += ulSize; -+ return (BCE_OK); -+ } -+ return (BCE_ERROR_OUT_OF_MEMORY); -+#else /* defined(LMA) */ -+#if defined(BCE_USE_SET_MEMORY) -+ void *pvLinAddr; -+ unsigned long ulAlignedSize = PAGE_ALIGN(ulSize); -+ int iPages = (int)(ulAlignedSize >> PAGE_SHIFT); -+ int iError; -+ -+ pvLinAddr = kmalloc(ulAlignedSize, GFP_KERNEL); -+ BUG_ON(((unsigned long)pvLinAddr) & ~PAGE_MASK); -+ -+ iError = set_memory_wc((unsigned long)pvLinAddr, iPages); -+ if (iError != 0) -+ { -+ printk(KERN_ERR DRVNAME ": BCAllocContigMemory: set_memory_wc failed (%d)\n", iError); -+ return (BCE_ERROR_OUT_OF_MEMORY); -+ } -+ -+ pPhysAddr->uiAddr = virt_to_phys(pvLinAddr); -+ *pLinAddr = pvLinAddr; -+ -+ return (BCE_OK); -+#else /* BCE_USE_SET_MEMORY */ -+ dma_addr_t dma; -+ void *pvLinAddr; -+ -+ pvLinAddr = dma_alloc_coherent(NULL, ulSize, &dma, GFP_KERNEL); -+ if (pvLinAddr == NULL) -+ { -+ return (BCE_ERROR_OUT_OF_MEMORY); -+ } -+ -+ pPhysAddr->uiAddr = dma; -+ *pLinAddr = pvLinAddr; -+ -+ return (BCE_OK); -+#endif /* BCE_USE_SET_MEMORY */ -+#endif /* defined(LMA) */ -+} -+ -+void BCFreeContigMemory(unsigned long ulSize, -+ BCE_HANDLE unref__ hMemHandle, -+ IMG_CPU_VIRTADDR LinAddr, -+ IMG_CPU_PHYADDR PhysAddr) -+{ -+#if defined(LMA) -+ g_ulMemCurrent -= ulSize; -+ iounmap(LinAddr); -+#else /* defined(LMA) */ -+#if defined(BCE_USE_SET_MEMORY) -+ unsigned long ulAlignedSize = PAGE_ALIGN(ulSize); -+ int iError; -+ int iPages = (int)(ulAlignedSize >> PAGE_SHIFT); -+ -+ iError = set_memory_wb((unsigned long)LinAddr, iPages); -+ if (iError != 0) -+ { -+ printk(KERN_ERR DRVNAME ": BCFreeContigMemory: set_memory_wb failed (%d)\n", iError); -+ } -+ kfree(LinAddr); -+#else /* BCE_USE_SET_MEMORY */ -+ dma_free_coherent(NULL, ulSize, LinAddr, (dma_addr_t)PhysAddr.uiAddr); -+#endif /* BCE_USE_SET_MEMORY */ -+#endif /* defined(LMA) */ -+} -+#endif /* defined(BC_DISCONTIG_BUFFERS) */ -+ -+/************************************************************************** -+ FUNCTION: CpuPAddrToSysPAddrBC -+ PURPOSE: Compute a system physical address from a cpu physical -+ address. -+ PARAMETERS: In: cpu_paddr - cpu physical address. -+ RETURNS: system physical address. -+ **************************************************************************/ -+IMG_SYS_PHYADDR CpuPAddrToSysPAddrBC(IMG_CPU_PHYADDR cpu_paddr) -+{ -+ IMG_SYS_PHYADDR sys_paddr; -+ -+ /* This would only be an inequality if the CPU's MMU did not point to sys address 0, -+ ie. multi CPU system */ -+ sys_paddr.uiAddr = cpu_paddr.uiAddr; -+ return sys_paddr; -+} -+ -+/************************************************************************** -+ FUNCTION: SysPAddrToCpuPAddrBC -+ PURPOSE: Compute a cpu physical address -+ from a system physical address. -+ PARAMETERS: In: cpu_paddr - system physical address. -+ RETURNS: cpu physical address. -+ **************************************************************************/ -+IMG_CPU_PHYADDR SysPAddrToCpuPAddrBC(IMG_SYS_PHYADDR sys_paddr) -+{ -+ -+ IMG_CPU_PHYADDR cpu_paddr; -+ /* This would only be an inequality if the CPU's MMU did not point to sys address 0, -+ ie. multi CPU system */ -+ cpu_paddr.uiAddr = sys_paddr.uiAddr; -+ return cpu_paddr; -+} -+ -+BCE_ERROR BCOpenPVRServices (BCE_HANDLE *phPVRServices) -+{ -+ /* Nothing to do - we have already checked services module insertion */ -+ *phPVRServices = 0; -+ return (BCE_OK); -+} -+ -+ -+BCE_ERROR BCClosePVRServices (BCE_HANDLE unref__ hPVRServices) -+{ -+ /* Nothing to do */ -+ return (BCE_OK); -+} -+ -+BCE_ERROR BCGetLibFuncAddr (BCE_HANDLE unref__ hExtDrv, char *szFunctionName, PFN_BC_GET_PVRJTABLE *ppfnFuncTable) -+{ -+ if(strcmp("PVRGetBufferClassJTable", szFunctionName) != 0) -+ { -+ return (BCE_ERROR_INVALID_PARAMS); -+ } -+ -+ /* Nothing to do - should be exported from pvrsrv.ko */ -+ *ppfnFuncTable = PVRGetBufferClassJTable; -+ -+ return (BCE_OK); -+} -+ -+ -+static int BC_Example_Bridge(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) -+{ -+ int err = -EFAULT; -+ int command = _IOC_NR(cmd); -+ BC_Example_ioctl_package sBridge; -+ -+ PVR_UNREFERENCED_PARAMETER(inode); -+ -+ if (copy_from_user(&sBridge, (void *)arg, sizeof(sBridge)) != 0) -+ { -+ return err; -+ } -+ -+ switch(command) -+ { -+ case _IOC_NR(BC_Example_ioctl_fill_buffer): -+ { -+ if(FillBuffer(sBridge.inputparam) == -1) -+ { -+ return err; -+ } -+ break; -+ } -+ case _IOC_NR(BC_Example_ioctl_get_buffer_count): -+ { -+ if(GetBufferCount(&sBridge.outputparam) == -1) -+ { -+ return err; -+ } -+ break; -+ } -+ case _IOC_NR(BC_Example_ioctl_reconfigure_buffer): -+ { -+ if(ReconfigureBuffer(&sBridge.outputparam) == -1) -+ { -+ return err; -+ } -+ break; -+ } -+ default: -+ return err; -+ } -+ -+ if (copy_to_user((void *)arg, &sBridge, sizeof(sBridge)) != 0) -+ { -+ return err; -+ } -+ -+ return 0; -+} -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)) -+static long BC_Example_Bridge_Unlocked(struct file *file, unsigned int cmd, unsigned long arg) -+{ -+ int res; -+ -+ mutex_lock(&sBCExampleBridgeMutex); -+ res = BC_Example_Bridge(NULL, file, cmd, arg); -+ mutex_unlock(&sBCExampleBridgeMutex); -+ -+ return res; -+} -+#endif -+ -+/* -+ These macro calls define the initialisation and removal functions of the -+ driver. Although they are prefixed `module_', they apply when compiling -+ statically as well; in both cases they define the function the kernel will -+ run to start/stop the driver. -+*/ -+module_init(BC_Example_ModInit); -+module_exit(BC_Example_ModCleanup); -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_example/bufferclass_example_linux.h b/drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_example/bufferclass_example_linux.h -new file mode 100644 -index 0000000..890a679 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_example/bufferclass_example_linux.h -@@ -0,0 +1,66 @@ -+/*************************************************************************/ /*! -+@Title bufferclass_example kernel driver interface -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+#ifndef __BC_EXAMPLE_LINUX_H__ -+#define __BC_EXAMPLE_LINUX_H__ -+ -+#include <linux/ioctl.h> -+ -+typedef struct BC_Example_ioctl_package_TAG -+{ -+ int inputparam; -+ int outputparam; -+ -+}BC_Example_ioctl_package; -+ -+/*!< Nov 2006: according to ioctl-number.txt 'g' wasn't in use. */ -+#define BC_EXAMPLE_IOC_GID 'g' -+ -+#define BC_EXAMPLE_IOWR(INDEX) _IOWR(BC_EXAMPLE_IOC_GID, INDEX, BC_Example_ioctl_package) -+ -+#define BC_Example_ioctl_fill_buffer BC_EXAMPLE_IOWR(0) -+#define BC_Example_ioctl_get_buffer_count BC_EXAMPLE_IOWR(1) -+#define BC_Example_ioctl_reconfigure_buffer BC_EXAMPLE_IOWR(2) -+ -+#endif /* __BC_EXAMPLE_H__ */ -+ -+/****************************************************************************** -+ End of file (bufferclass_example.h) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_example/bufferclass_example_private.c b/drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_example/bufferclass_example_private.c -new file mode 100644 -index 0000000..c7604ae ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_example/bufferclass_example_private.c -@@ -0,0 +1,432 @@ -+/*************************************************************************/ /*! -+@Title Bufferclass example private functions. -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+/************************************************************************** -+ The 3rd party driver is a specification of an API to integrate the IMG POWERVR -+ Services driver with 3rd Party display hardware. It is NOT a specification for -+ a display controller driver, rather a specification to extend the API for a -+ pre-existing driver for the display hardware. -+ -+ The 3rd party driver interface provides IMG POWERVR client drivers (e.g. PVR2D) -+ with an API abstraction of the system's underlying display hardware, allowing -+ the client drivers to indirectly control the display hardware and access its -+ associated memory. -+ -+ Functions of the API include -+ - query primary surface attributes (width, height, stride, pixel format, CPU -+ physical and virtual address) -+ - swap/flip chain creation and subsequent query of surface attributes -+ - asynchronous display surface flipping, taking account of asynchronous read -+ (flip) and write (render) operations to the display surface -+ -+ Note: having queried surface attributes the client drivers are able to map the -+ display memory to any IMG POWERVR Services device by calling -+ PVRSRVMapDeviceClassMemory with the display surface handle. -+ -+ This code is intended to be an example of how a pre-existing display driver may -+ be extended to support the 3rd Party Display interface to POWERVR Services -+ - IMG is not providing a display driver implementation. -+ **************************************************************************/ -+ -+#include "bufferclass_example.h" -+#include "bufferclass_example_private.h" -+ -+#define MIN(a,b) ((a)<(b)?(a):(b)) -+ -+static void FillNV12Image(void *pvDest, int width, int height, int bytestride) -+{ -+ static int iPhase = 0; -+ int i, j; -+ unsigned char u,v,y; -+ unsigned char *pui8y = (unsigned char *)pvDest; -+ unsigned short *pui16uv; -+ unsigned int count = 0; -+ -+ for(j=0;j<height;j++) -+ { -+ pui8y = (unsigned char *)pvDest + j * bytestride; -+ count = 0; -+ -+ for(i=0;i<width;i++) -+ { -+ y = (((i+iPhase)>>6)%(2)==0)? 0x7f:0x00; -+ -+ pui8y[count++] = y; -+ } -+ } -+ -+ for(j=0;j<height;j+=2) -+ { -+ pui16uv = (unsigned short *)((unsigned char *)pvDest + height * bytestride + (j / 2) * bytestride); -+ count = 0; -+ -+ for(i=0;i<width;i+=2) -+ { -+ u = (j<(height/2))? ((i<(width/2))? 0xFF:0x33) : ((i<(width/2))? 0x33:0xAA); -+ v = (j<(height/2))? ((i<(width/2))? 0xAC:0x0) : ((i<(width/2))? 0x03:0xEE); -+ -+ /* Byte order is VU */ -+ pui16uv[count++] = (v << 8) | u; -+ -+ } -+ } -+ -+ iPhase++; -+} -+ -+static void FillYV12Image(void *pvDest, int width, int height, int bytestride) -+{ -+ static int iPhase = 0; -+ int i, j; -+ unsigned char u,v,y; -+ unsigned char *pui8y = (unsigned char *)pvDest; -+ unsigned char *pui8u, *pui8v; -+ unsigned int count = 0; -+ int uvplanestride = bytestride / 2; -+ int uvplaneheight = height / 2; -+ -+ for(j=0;j<height;j++) -+ { -+ pui8y = (unsigned char *)pvDest + j * bytestride; -+ count = 0; -+ -+ for(i=0;i<width;i++) -+ { -+ y = (((i+iPhase)>>6)%(2)==0)? 0x7f:0x00; -+ -+ pui8y[count++] = y; -+ } -+ } -+ -+ for(j=0;j<height;j+=2) -+ { -+ pui8v = (unsigned char *)pvDest + (height * bytestride) + ((j / 2) * uvplanestride); -+ count = 0; -+ -+ for(i=0;i<width;i+=2) -+ { -+ v = (j<(height/2))? ((i<(width/2))? 0xAC:0x0) : ((i<(width/2))? 0x03:0xEE); -+ -+ pui8v[count++] = v; -+ } -+ } -+ -+ for(j=0;j<height;j+=2) -+ { -+ pui8u = (unsigned char *)pvDest + (height * bytestride) + (uvplaneheight * uvplanestride) + (j / 2) * uvplanestride; -+ count = 0; -+ -+ for(i=0;i<width;i+=2) -+ { -+ u = (j<(height/2))? ((i<(width/2))? 0xFF:0x33) : ((i<(width/2))? 0x33:0xAA); -+ -+ pui8u[count++] = u; -+ -+ } -+ } -+ -+ iPhase++; -+} -+ -+static void FillYUV422Image(void *pvDest, int width, int height, int bytestride, PVRSRV_PIXEL_FORMAT pixelformat) -+{ -+ static int iPhase = 0; -+ int x, y; -+ unsigned char u,v,y0,y1; -+ unsigned long *pui32yuv = (unsigned long *)pvDest; -+ unsigned int count = 0; -+ -+ for(y=0;y<height;y++) -+ { -+ pui32yuv = (unsigned long *)((unsigned char *)pvDest + y * bytestride); -+ count = 0; -+ -+ for(x=0;x<width; x+=2) -+ { -+ u = (y<(height/2))? ((x<(width/2))? 0xFF:0x33) : ((x<(width/2))? 0x33:0xAA); -+ v = (y<(height/2))? ((x<(width/2))? 0xAA:0x0) : ((x<(width/2))? 0x03:0xEE); -+ -+ y0 = y1 = (((x+iPhase)>>6)%(2)==0)? 0x7f:0x00; -+ -+ switch(pixelformat) -+ { -+ case PVRSRV_PIXEL_FORMAT_FOURCC_ORG_VYUY: -+ pui32yuv[count++] = (y1 << 24) | (u << 16) | (y0 << 8) | v; -+ break; -+ case PVRSRV_PIXEL_FORMAT_FOURCC_ORG_UYVY: -+ pui32yuv[count++] = (y1 << 24) | (v << 16) | (y0 << 8) | u; -+ break; -+ case PVRSRV_PIXEL_FORMAT_FOURCC_ORG_YUYV: -+ pui32yuv[count++] = (v << 24) | (y1 << 16) | (u << 8) | y0; -+ break; -+ case PVRSRV_PIXEL_FORMAT_FOURCC_ORG_YVYU: -+ pui32yuv[count++] = (u << 24) | (y1 << 16) | (v << 8) | y0; -+ break; -+ -+ default: -+ break; -+ -+ } -+ -+ } -+ } -+ -+ iPhase++; -+} -+ -+static void FillRGB565Image(void *pvDest, int width, int height, int bytestride) -+{ -+ int i, Count; -+ unsigned long *pui32Addr = (unsigned long *)pvDest; -+ unsigned short *pui16Addr = (unsigned short *)pvDest; -+ unsigned long Colour32; -+ unsigned short Colour16; -+ static unsigned char Colour8 = 0;//debug colour -+ -+ Colour16 = (Colour8>>3) | ((Colour8>>2)<<5) | ((Colour8>>3)<<11); -+ Colour32 = Colour16 | Colour16 << 16; -+ -+ Count = (height * bytestride)>>2; -+ -+ for(i=0; i<Count; i++) -+ { -+ pui32Addr[i] = Colour32; -+ } -+ -+ Count = height; -+ -+ pui16Addr = (unsigned short *)((unsigned char *)pvDest + (2 * Colour8)); -+ -+ for(i=0; i<Count; i++) -+ { -+ *pui16Addr = 0xF800U; -+ -+ pui16Addr = (unsigned short *)((unsigned char *)pui16Addr + bytestride); -+ } -+ Count = bytestride >> 2; -+ -+ pui32Addr = (unsigned long *)((unsigned char *)pvDest + (bytestride * (MIN(height - 1, 0xFF) - Colour8))); -+ -+ for(i=0; i<Count; i++) -+ { -+ pui32Addr[i] = 0x001F001FUL; -+ } -+ -+ /* advance the colour */ -+ Colour8 = (Colour8 + 1) % MIN(height - 1, 0xFFU); -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function FillBuffer -+ -+ @Description -+ -+ Fills pixels into a buffer specified by index -+ -+ @Input ui32BufferIndex - buffer index -+ -+ @Return 0 - success, -1 - failure -+ -+******************************************************************************/ -+int FillBuffer(unsigned int uiBufferIndex) -+{ -+ BC_EXAMPLE_DEVINFO *psDevInfo = GetAnchorPtr(); -+ BC_EXAMPLE_BUFFER *psBuffer; -+ BUFFER_INFO *psBufferInfo; -+ PVRSRV_SYNC_DATA *psSyncData; -+ -+ /* check DevInfo has been setup */ -+ if(psDevInfo == NULL) -+ { -+ return -1;/* failure */ -+ } -+ -+ psBuffer = &psDevInfo->psSystemBuffer[uiBufferIndex]; -+ psBufferInfo = &psDevInfo->sBufferInfo; -+ -+ /* This may be NULL, as it is only registered once texture streaming starts. */ -+ psSyncData = psBuffer->psSyncData; -+ -+ if(psSyncData) -+ { -+ /* ensure all reads have flushed on the buffer */ -+ if(psSyncData->ui32ReadOpsPending != psSyncData->ui32ReadOpsComplete) -+ { -+ return -1;/* failure */ -+ } -+ -+ /* take a write-lock on the new buffer to capture to */ -+ psSyncData->ui32WriteOpsPending++; -+ } -+ -+ switch(psBufferInfo->pixelformat) -+ { -+ case PVRSRV_PIXEL_FORMAT_RGB565: -+ default: -+ { -+ FillRGB565Image(psBuffer->sCPUVAddr, -+ psBufferInfo->ui32Width, -+ psBufferInfo->ui32Height, -+ psBufferInfo->ui32ByteStride); -+ break; -+ } -+ case PVRSRV_PIXEL_FORMAT_FOURCC_ORG_VYUY: -+ case PVRSRV_PIXEL_FORMAT_FOURCC_ORG_UYVY: -+ case PVRSRV_PIXEL_FORMAT_FOURCC_ORG_YUYV: -+ case PVRSRV_PIXEL_FORMAT_FOURCC_ORG_YVYU: -+ { -+ FillYUV422Image(psBuffer->sCPUVAddr, -+ psBufferInfo->ui32Width, -+ psBufferInfo->ui32Height, -+ psBufferInfo->ui32ByteStride, -+ psBufferInfo->pixelformat); -+ break; -+ } -+ case PVRSRV_PIXEL_FORMAT_NV12: -+ { -+ FillNV12Image(psBuffer->sCPUVAddr, -+ psBufferInfo->ui32Width, -+ psBufferInfo->ui32Height, -+ psBufferInfo->ui32ByteStride); -+ break; -+ } -+ case PVRSRV_PIXEL_FORMAT_YV12: -+ { -+ FillYV12Image(psBuffer->sCPUVAddr, -+ psBufferInfo->ui32Width, -+ psBufferInfo->ui32Height, -+ psBufferInfo->ui32ByteStride); -+ break; -+ } -+ } -+ -+ /* unlock the buffer, signalling the writes are complete */ -+ if(psSyncData) -+ { -+ psSyncData->ui32WriteOpsComplete++; -+ -+ if (NULL != psDevInfo->sPVRJTable.pfnPVRSRVScheduleDevices) -+ { -+ (*psDevInfo->sPVRJTable.pfnPVRSRVScheduleDevices)(); -+ } -+ } -+ -+ return 0; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function GetBufferCount -+ -+ @Description -+ -+ returns buffer count -+ -+ @Output pulBufferCount - buffer count -+ -+ @Return 0 - success, -1 - failure -+ -+******************************************************************************/ -+int GetBufferCount(unsigned int *puiBufferCount) -+{ -+ BC_EXAMPLE_DEVINFO *psDevInfo = GetAnchorPtr(); -+ -+ /* check DevInfo has been setup */ -+ if(psDevInfo == IMG_NULL) -+ { -+ return -1;/* failure */ -+ } -+ -+ /* return buffer count */ -+ *puiBufferCount = (unsigned int)psDevInfo->sBufferInfo.ui32BufferCount; -+ -+ return 0; -+} -+ -+ -+ -+/****************************************************************************** -+ -+ @Function ReconfigureBuffer -+ -+ @Description -+ -+ returns whether reconfiguration succeeds or not -+ -+ @Output uiSucceed : 1 - succeeded, 0 - failed -+ -+ @Return 0 - success, -1 - failure -+ -+******************************************************************************/ -+int ReconfigureBuffer(unsigned int *uiSucceed) -+{ -+ BCE_ERROR eError; -+ -+ /* Destroy the shared buffers of the current buffer class device */ -+ eError = BC_Example_Buffers_Destroy(); -+ -+ if (eError != BCE_OK) -+ { -+ *uiSucceed = 0; -+ return -1; -+ } -+ -+ /* No need to un-register and then re-register the device with services module srvkm */ -+ -+ -+ /* Recreate shared buffers with reconfigured parameters */ -+ eError = BC_Example_Buffers_Create(); -+ -+ if (eError != BCE_OK) -+ { -+ *uiSucceed = 0; -+ return -1; -+ } -+ -+ /* return uiSucceed as succeeded 1 */ -+ *uiSucceed = 1; -+ return 0; -+} -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_example/bufferclass_example_private.h b/drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_example/bufferclass_example_private.h -new file mode 100644 -index 0000000..8d95e2b ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_example/bufferclass_example_private.h -@@ -0,0 +1,49 @@ -+/*************************************************************************/ /*! -+@Title Bufferclass example internal interfaces. -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#ifndef _BUFFERCLASS_EXAMPLE_PRIVATE_H_ -+#define _BUFFERCLASS_EXAMPLE_PRIVATE_H_ -+ -+int FillBuffer(unsigned int uiBufferIndex); -+int GetBufferCount(unsigned int *puiBufferCount); -+int ReconfigureBuffer(unsigned int *uiSucceed); -+ -+#endif /* _BUFFERCLASS_EXAMPLE_PRIVATE_H_ */ -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_ti/Kbuild b/drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_ti/Kbuild -new file mode 100644 -index 0000000..c6f3b93 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_ti/Kbuild -@@ -0,0 +1,10 @@ -+EXTRA_CFLAGS = -DLINUX \ -+ -I$(PVR_BUILD_DIR)/include4 \ -+ -I$(PVR_BUILD_DIR)/services4/include -+ -+ifeq ($(TI_PLATFORM),ti81xx) -+EXTRA_CFLAGS += -DPLAT_TI81xx -+endif -+ -+obj-m := bufferclass_ti.o -+bufferclass_ti-y := bc_cat.o -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_ti/Makefile b/drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_ti/Makefile -new file mode 100644 -index 0000000..f261a6b ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_ti/Makefile -@@ -0,0 +1,25 @@ -+.PHONY: all linstall clean -+ -+-include ../rules.make -+ -+INCS ?= -I$(GSDK_KM_DIR)/include4 \ -+ -I$(GSDK_KM_DIR)/services4/include -+ -+KBUILD_EXTRA_SYMBOLS ?= $(GSDK_KM_DIR)/Module.symvers -+ -+ -+CFLAGS = -DLINUX $(INCS) -+ifeq ($(OMAP3_ES2x),1) -+ CFLAGS += -DOMAP3_ES2x -+endif -+ -+export CROSS_COMPILE KBUILD_EXTRA_SYMBOLS -+ -+all: -+ $(MAKE) -C $(KERNEL_DIR) M=`pwd` EXTRA_CFLAGS="$(CFLAGS)" modules -+ -+clean: -+ $(MAKE) -C $(KERNEL_DIR) M=`pwd` clean -+ -+install: -+ $(MAKE) -C $(KERNEL_DIR) M=`pwd` INSTALL_MOD_PATH=$(TGTFS_PATH) modules_install -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_ti/bc_cat.c b/drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_ti/bc_cat.c -new file mode 100644 -index 0000000..62814cd ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_ti/bc_cat.c -@@ -0,0 +1,1157 @@ -+/********************************************************************** -+ * -+ * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ -+ * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful but, except -+ * as otherwise stated in writing, without any warranty; without even the -+ * implied warranty of merchantability or fitness for a particular purpose. -+ * See the GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -+ * -+ * The full GNU General Public License is included in this distribution in -+ * the file called "COPYING". -+ * -+ * Contact Information: -+ * Imagination Technologies Ltd. <gpl-support@imgtec.com> -+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK -+ * -+ ******************************************************************************/ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/fs.h> -+#include <linux/version.h> -+#include <asm/uaccess.h> -+#include <asm/io.h> -+#include <img_defs.h> -+#include <servicesext.h> -+#include <kernelbuffer.h> -+#include "bc_cat.h" -+#include <linux/slab.h> -+#include <linux/dma-mapping.h> -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)) -+#include <linux/mutex.h> -+#endif -+ -+#if defined(BC_DISCONTIG_BUFFERS) -+#include <linux/vmalloc.h> -+#endif -+ -+#define DEVNAME "bccat" -+#define DRVNAME DEVNAME -+#define DEVICE_COUNT 10 -+#define BC_EXAMPLE_NUM_BUFFERS 3 -+#define BUFFERCLASS_DEVICE_NAME "Example Bufferclass Device (SW)" -+ -+#ifndef UNREFERENCED_PARAMETER -+#define UNREFERENCED_PARAMETER(param) (param) = (param) -+#endif -+ -+ -+MODULE_SUPPORTED_DEVICE(DEVNAME); -+ -+#define unref__ __attribute__ ((unused)) -+ -+typedef struct BC_CAT_BUFFER_TAG -+{ -+ unsigned long ulSize; -+ IMG_HANDLE hMemHandle; -+#if defined(BC_DISCONTIG_BUFFERS) -+ IMG_SYS_PHYADDR *psSysAddr; -+#else -+ -+ IMG_SYS_PHYADDR sSysAddr; -+ IMG_SYS_PHYADDR sPageAlignSysAddr; -+#endif -+ IMG_CPU_VIRTADDR sCPUVAddr; -+ PVRSRV_SYNC_DATA *psSyncData; -+ struct BC_CAT_BUFFER_TAG *psNext; -+} BC_CAT_BUFFER; -+ -+ -+typedef struct BC_CAT_DEVINFO_TAG -+{ -+ int ref; -+ unsigned long ulDeviceID; -+ BC_CAT_BUFFER *psSystemBuffer; -+ unsigned long ulNumBuffers; -+ PVRSRV_BC_BUFFER2SRV_KMJTABLE sPVRJTable; -+ PVRSRV_BC_SRV2BUFFER_KMJTABLE sBCJTable; -+ IMG_HANDLE hPVRServices; -+ unsigned long ulRefCount; -+ BUFFER_INFO sBufferInfo; -+ enum BC_memory buf_type; -+} BC_CAT_DEVINFO; -+ -+ -+typedef enum _BCE_ERROR_ -+{ -+ BCE_OK = 0, -+ BCE_ERROR_GENERIC = 1, -+ BCE_ERROR_OUT_OF_MEMORY = 2, -+ BCE_ERROR_TOO_FEW_BUFFERS = 3, -+ BCE_ERROR_INVALID_PARAMS = 4, -+ BCE_ERROR_INIT_FAILURE = 5, -+ BCE_ERROR_CANT_REGISTER_CALLBACK = 6, -+ BCE_ERROR_INVALID_DEVICE = 7, -+ BCE_ERROR_DEVICE_REGISTER_FAILED = 8, -+ BCE_ERROR_NO_PRIMARY = 9 -+} BCE_ERROR; -+ -+ -+ -+extern IMG_IMPORT IMG_BOOL PVRGetBufferClassJTable( -+ PVRSRV_BC_BUFFER2SRV_KMJTABLE *psJTable); -+ -+static int bc_open(struct inode *i, struct file *f); -+static int bc_release(struct inode *i, struct file *f); -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) -+static int bc_ioctl(struct inode *inode, struct file *file, -+ unsigned int cmd, unsigned long arg); -+#else -+static long bc_ioctl(struct file *file, -+ unsigned int cmd, unsigned long arg); -+static long bc_ioctl_unlocked(struct file *file, -+ unsigned int cmd, unsigned long arg); -+#endif -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)) -+static DEFINE_MUTEX(sBCExampleBridgeMutex); -+#endif -+static int bc_mmap(struct file *filp, struct vm_area_struct *vma); -+ -+static int BC_CreateBuffers(int id, bc_buf_params_t *p); -+static PVRSRV_ERROR BC_DestroyBuffers(int id); -+static PVRSRV_ERROR BC_Register(int id); -+static PVRSRV_ERROR BC_Unregister(int id); -+ -+static PVRSRV_ERROR BCOpenPVRServices(IMG_HANDLE *phPVRServices); -+static PVRSRV_ERROR BCClosePVRServices(IMG_HANDLE hPVRServices); -+ -+static IMG_VOID *BCAllocKernelMem(unsigned long ulSize); -+static IMG_VOID BCFreeKernelMem(IMG_VOID *pvMem); -+ -+static BCE_ERROR BCAllocContigMemory(unsigned long ulSize, -+ IMG_HANDLE * phMemHandle, -+ IMG_CPU_VIRTADDR *pLinAddr, -+ IMG_CPU_PHYADDR *pPhysAddr); -+static IMG_VOID BCFreeContigMemory(unsigned long ulSize, -+ IMG_HANDLE hMemHandle, -+ IMG_CPU_VIRTADDR LinAddr, -+ IMG_CPU_PHYADDR PhysAddr); -+ -+static IMG_SYS_PHYADDR CpuPAddrToSysPAddrBC(IMG_CPU_PHYADDR cpu_paddr); -+static IMG_CPU_PHYADDR SysPAddrToCpuPAddrBC(IMG_SYS_PHYADDR sys_paddr); -+ -+static PVRSRV_ERROR BCGetLibFuncAddr(IMG_HANDLE hExtDrv, -+ IMG_CHAR *szFunctionName, -+ PFN_BC_GET_PVRJTABLE *ppfnFuncTable); -+static BC_CAT_DEVINFO * GetAnchorPtr(int id); -+ -+ -+static int major; -+static struct class *bc_class; -+static IMG_VOID *device[DEVICE_COUNT] = { 0 }; -+static PFN_BC_GET_PVRJTABLE pfnGetPVRJTable = IMG_NULL; -+static int width_align; -+ -+static struct file_operations bc_cat_fops = { -+ .open = bc_open, -+ .release = bc_release, -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) -+ .ioctl = bc_ioctl, -+#else -+ .unlocked_ioctl = bc_ioctl_unlocked, -+#ifdef CONFIG_COMPAT -+ .compat_ioctl = bc_ioctl, -+#endif -+#endif -+ .mmap = bc_mmap, -+}; -+ -+ -+/***************************************************************************** -+ * func implementation -+ * **************************************************************************/ -+ -+#define file_to_id(file) (iminor(file->f_path.dentry->d_inode)) -+ -+static BC_CAT_DEVINFO * GetAnchorPtr(int id) -+{ -+ return (BC_CAT_DEVINFO *)device[id]; -+} -+ -+static IMG_VOID SetAnchorPtr(int id, BC_CAT_DEVINFO *psDevInfo) -+{ -+ device[id] = (IMG_VOID*)psDevInfo; -+} -+ -+ -+#if 0 -+static PVRSRV_ERROR OpenBCDevice(IMG_HANDLE *phDevice) -+{ -+ BC_CAT_DEVINFO *psDevInfo; -+ -+ psDevInfo = GetAnchorPtr(id); -+ *phDevice = (IMG_HANDLE)psDevInfo; -+ -+ return PVRSRV_OK; -+} -+#else -+ -+#define OPEN_FXN(id) \ -+static PVRSRV_ERROR OpenBCDevice##id(IMG_UINT32 ui32DeviceID, IMG_HANDLE *phDevice)\ -+{ \ -+ BC_CAT_DEVINFO *psDevInfo; \ -+UNREFERENCED_PARAMETER(ui32DeviceID); \ -+ psDevInfo = GetAnchorPtr (id); \ -+ *phDevice = (IMG_HANDLE) psDevInfo; \ -+ return PVRSRV_OK; \ -+} -+ -+OPEN_FXN(0) -+OPEN_FXN(1) -+OPEN_FXN(2) -+OPEN_FXN(3) -+OPEN_FXN(4) -+OPEN_FXN(5) -+OPEN_FXN(6) -+OPEN_FXN(7) -+OPEN_FXN(8) -+OPEN_FXN(9) -+#endif -+ -+static PVRSRV_ERROR CloseBCDevice(IMG_UINT32 handle , IMG_HANDLE hDevice) -+{ -+ PVR_UNREFERENCED_PARAMETER(hDevice); -+ -+ return PVRSRV_OK; -+} -+ -+static PVRSRV_ERROR GetBCBuffer(IMG_HANDLE hDevice, -+ IMG_UINT32 ui32BufferNumber, -+ PVRSRV_SYNC_DATA *psSyncData, -+ IMG_HANDLE *phBuffer) -+{ -+ BC_CAT_DEVINFO *psDevInfo; -+ -+ if (!hDevice || !phBuffer) -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ -+ psDevInfo = (BC_CAT_DEVINFO*)hDevice; -+ -+ if (ui32BufferNumber < psDevInfo->sBufferInfo.ui32BufferCount) { -+ psDevInfo->psSystemBuffer[ui32BufferNumber].psSyncData = psSyncData; -+ *phBuffer = (IMG_HANDLE)&psDevInfo->psSystemBuffer[ui32BufferNumber]; -+ } else { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ return PVRSRV_OK; -+} -+ -+ -+static PVRSRV_ERROR GetBCInfo(IMG_HANDLE hDevice, BUFFER_INFO *psBCInfo) -+{ -+ BC_CAT_DEVINFO *psDevInfo; -+ -+ if (!hDevice || !psBCInfo) -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ -+ psDevInfo = (BC_CAT_DEVINFO*)hDevice; -+ *psBCInfo = psDevInfo->sBufferInfo; -+ -+ return PVRSRV_OK; -+} -+ -+ -+static PVRSRV_ERROR GetBCBufferAddr(IMG_HANDLE hDevice, -+ IMG_HANDLE hBuffer, -+ IMG_SYS_PHYADDR **ppsSysAddr, -+ IMG_UINT32 *pui32ByteSize, -+ IMG_VOID **ppvCpuVAddr, -+ IMG_HANDLE *phOSMapInfo, -+ IMG_BOOL *pbIsContiguous, -+ IMG_UINT32 *pui32TilingStride) -+{ -+ BC_CAT_BUFFER *psBuffer; -+ PVR_UNREFERENCED_PARAMETER(pui32TilingStride); -+ -+ if (!hDevice || !hBuffer || !ppsSysAddr || !pui32ByteSize) -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ -+ psBuffer = (BC_CAT_BUFFER *) hBuffer; -+ -+ *ppvCpuVAddr = psBuffer->sCPUVAddr; -+ -+ *phOSMapInfo = IMG_NULL; -+ *pui32ByteSize = (IMG_UINT32)psBuffer->ulSize; -+ -+#if defined(BC_DISCONTIG_BUFFERS) -+ *ppsSysAddr = psBuffer->psSysAddr; -+ *pbIsContiguous = IMG_FALSE; -+#else -+ *ppsSysAddr = &psBuffer->sPageAlignSysAddr; -+ *pbIsContiguous = IMG_TRUE; -+#endif -+ -+ -+ return PVRSRV_OK; -+} -+ -+ -+static int BC_CreateBuffers(int id, bc_buf_params_t *p) -+{ -+ BC_CAT_DEVINFO *psDevInfo; -+#if !defined(BC_DISCONTIG_BUFFERS) -+ IMG_CPU_PHYADDR paddr; -+#endif -+ IMG_UINT32 i, stride; -+ unsigned long ulSize; -+ PVRSRV_PIXEL_FORMAT pixel_fmt; -+//IMG_UINT32 ui32MaxWidth = 320 * 4; -+ if (p->count <= 0) -+ return -EINVAL; -+ -+ if (p->width <= 1 || p->width % width_align || p->height <= 1) -+ return -EINVAL; -+ -+ switch (p->fourcc) { -+ case BC_PIX_FMT_YV12: -+ pixel_fmt = PVRSRV_PIXEL_FORMAT_YV12; -+ stride = p->width; -+ break; -+ case BC_PIX_FMT_I420: -+ pixel_fmt = PVRSRV_PIXEL_FORMAT_I420; -+ stride = p->width; -+ break; -+ -+ case BC_PIX_FMT_NV12: -+ pixel_fmt = PVRSRV_PIXEL_FORMAT_NV12; -+ stride = p->width; -+ break; -+ case BC_PIX_FMT_UYVY: -+ pixel_fmt = PVRSRV_PIXEL_FORMAT_FOURCC_ORG_UYVY; -+ stride = p->width << 1; -+ break; -+ case BC_PIX_FMT_RGB565: -+ pixel_fmt = PVRSRV_PIXEL_FORMAT_RGB565; -+ stride = p->width << 1; -+ break; -+ case BC_PIX_FMT_YUYV: -+ pixel_fmt = PVRSRV_PIXEL_FORMAT_FOURCC_ORG_YUYV; -+ stride = p->width << 1; -+ break; -+ -+ case BC_PIX_FMT_ARGB: -+ pixel_fmt = PVRSRV_PIXEL_FORMAT_ARGB8888; -+ stride = p->width << 2; -+ break; -+ -+ default: -+ return -EINVAL; -+ break; -+ } -+ -+ if (p->type != BC_MEMORY_MMAP && p->type != BC_MEMORY_USERPTR) -+ return -EINVAL; -+ -+ psDevInfo = GetAnchorPtr(id); -+ if (psDevInfo == NULL) -+ { -+ -+ return (BCE_ERROR_DEVICE_REGISTER_FAILED); -+ } -+ if (psDevInfo->ulNumBuffers) -+ { -+ -+ return (BCE_ERROR_GENERIC); -+ } -+ -+ -+ -+ psDevInfo->buf_type = p->type; -+ psDevInfo->psSystemBuffer = -+ BCAllocKernelMem(sizeof(BC_CAT_BUFFER) * p->count); -+ -+ if (!psDevInfo->psSystemBuffer) -+ return -ENOMEM; -+ -+ memset(psDevInfo->psSystemBuffer, 0, sizeof(BC_CAT_BUFFER) * p->count); -+ -+ ulSize = p->height * stride; -+ if (pixel_fmt == PVRSRV_PIXEL_FORMAT_NV12) -+ ulSize += (stride >> 1) * (p->height >> 1) << 1; -+ -+ if ((pixel_fmt == PVRSRV_PIXEL_FORMAT_I420) || (pixel_fmt == PVRSRV_PIXEL_FORMAT_YV12) ) -+ { -+ ulSize += (stride >> 1) * (p->height >> 1); -+ ulSize += (stride >> 1) * (p->height >> 1); -+ } -+ -+ for (i=0; i < p->count; i++) { -+ if (psDevInfo->buf_type == BC_MEMORY_MMAP) { -+ -+#if defined(BC_DISCONTIG_BUFFERS) -+ if (BCAllocDiscontigMemory(ulSize, -+ &psDevInfo->psSystemBuffer[i].hMemHandle, -+ &psDevInfo->psSystemBuffer[i].sCPUVAddr, -+ &psDevInfo->psSystemBuffer[i].psSysAddr) != BCE_OK) -+ { -+ break; -+ } -+#else -+ -+ if (BCAllocContigMemory(ulSize, -+ &psDevInfo->psSystemBuffer[i].hMemHandle, -+ &psDevInfo->psSystemBuffer[i].sCPUVAddr, -+ &paddr) != BCE_OK) -+{ -+ /*TODO should free() and return failure*/ -+ break; -+} -+ -+ psDevInfo->psSystemBuffer[i].sSysAddr = CpuPAddrToSysPAddrBC(paddr); -+ psDevInfo->psSystemBuffer[i].sPageAlignSysAddr.uiAddr = -+ psDevInfo->psSystemBuffer[i].sSysAddr.uiAddr & 0xFFFFF000; -+ } -+#endif -+ psDevInfo->ulNumBuffers++; -+ psDevInfo->psSystemBuffer[i].ulSize = ulSize; -+ psDevInfo->psSystemBuffer[i].psSyncData = NULL; -+ } -+ p->count = psDevInfo->ulNumBuffers; -+ -+ psDevInfo->sBufferInfo.ui32BufferCount = (IMG_UINT32)psDevInfo->ulNumBuffers; -+ psDevInfo->sBufferInfo.pixelformat = pixel_fmt; -+ psDevInfo->sBufferInfo.ui32Width = p->width; -+ psDevInfo->sBufferInfo.ui32Height = p->height; -+ psDevInfo->sBufferInfo.ui32ByteStride = stride; -+ psDevInfo->sBufferInfo.ui32BufferDeviceID = id; -+ psDevInfo->sBufferInfo.ui32Flags = PVRSRV_BC_FLAGS_YUVCSC_FULL_RANGE | -+ PVRSRV_BC_FLAGS_YUVCSC_BT601; -+ -+psDevInfo->sBCJTable.ui32TableSize = sizeof(PVRSRV_BC_SRV2BUFFER_KMJTABLE); -+ psDevInfo->sBCJTable.pfnOpenBCDevice = OpenBCDevice0; -+ psDevInfo->sBCJTable.pfnCloseBCDevice = CloseBCDevice; -+ psDevInfo->sBCJTable.pfnGetBCBuffer = GetBCBuffer; -+ psDevInfo->sBCJTable.pfnGetBCInfo = GetBCInfo; -+ psDevInfo->sBCJTable.pfnGetBufferAddr = GetBCBufferAddr; -+/* -+if (psDevInfo->sBufferInfo.ui32Width < ui32MaxWidth) -+ { -+ switch(pixel_fmt) -+ { -+ case PVRSRV_PIXEL_FORMAT_NV12: -+ case PVRSRV_PIXEL_FORMAT_I420: -+ { -+ psDevInfo->sBufferInfo.ui32Width += 320; -+ psDevInfo->sBufferInfo.ui32Height += 160; -+ psDevInfo->sBufferInfo.ui32ByteStride = psDevInfo->sBufferInfo.ui32Width; -+ break; -+ } -+ case PVRSRV_PIXEL_FORMAT_FOURCC_ORG_VYUY: -+ case PVRSRV_PIXEL_FORMAT_FOURCC_ORG_UYVY: -+ case PVRSRV_PIXEL_FORMAT_FOURCC_ORG_YUYV: -+ case PVRSRV_PIXEL_FORMAT_FOURCC_ORG_YVYU: -+ { -+ psDevInfo->sBufferInfo.ui32Width += 320; -+ psDevInfo->sBufferInfo.ui32Height += 160; -+ psDevInfo->sBufferInfo.ui32ByteStride = ui32Width*2; -+ break; -+ } -+ case PVRSRV_PIXEL_FORMAT_RGB565: -+ { -+ psDevInfo->sBufferInfo.ui32Width += 320; -+ psDevInfo->sBufferInfo.ui32Height += 160; -+ psDevInfo->sBufferInfo.ui32ByteStride = ui32Width*2; -+ break; -+ } -+ default: -+ { -+ return (BCE_ERROR_INVALID_PARAMS); -+ } -+ } -+ } -+ else -+ { -+ psDevInfo->sBufferInfo.ui32Width = BC_EXAMPLE_WIDTH; -+ psDevInfo->sBufferInfo.ui32Height = BC_EXAMPLE_HEIGHT; -+ psDevInfo->sBufferInfo.ui32ByteStride = BC_EXAMPLE_STRIDE; -+ } -+*/ -+ return (BCE_OK); -+ -+} -+ -+ -+static PVRSRV_ERROR BC_DestroyBuffers(int id) -+{ -+ BC_CAT_DEVINFO *psDevInfo; -+ IMG_UINT32 i; -+ -+ psDevInfo = GetAnchorPtr(id); -+ -+ -+ if (psDevInfo == NULL) -+ { -+ -+ -+ return (BCE_ERROR_DEVICE_REGISTER_FAILED); -+ } -+ -+ if (psDevInfo->buf_type == BC_MEMORY_MMAP) -+ for (i = 0; i < psDevInfo->ulNumBuffers; i++) { -+#if defined(BC_DISCONTIG_BUFFERS) -+ BCFreeDiscontigMemory(psDevInfo->psSystemBuffer[i].ulSize, -+ psDevInfo->psSystemBuffer[i].hMemHandle, -+ psDevInfo->psSystemBuffer[i].sCPUVAddr, -+ psDevInfo->psSystemBuffer[i].psSysAddr); -+#else -+ -+ BCFreeContigMemory(psDevInfo->psSystemBuffer[i].ulSize, -+ psDevInfo->psSystemBuffer[i].hMemHandle, -+ psDevInfo->psSystemBuffer[i].sCPUVAddr, -+ SysPAddrToCpuPAddrBC(psDevInfo->psSystemBuffer[i].sSysAddr)); -+#endif -+ } -+ -+ // BCFreeKernelMem(psDevInfo->psSystemBuffer); -+ -+ psDevInfo->ulNumBuffers = 0; -+ psDevInfo->sBufferInfo.pixelformat = PVRSRV_PIXEL_FORMAT_UNKNOWN; -+ psDevInfo->sBufferInfo.ui32Width = 0; -+ psDevInfo->sBufferInfo.ui32Height = 0; -+ psDevInfo->sBufferInfo.ui32ByteStride = 0; -+ psDevInfo->sBufferInfo.ui32BufferDeviceID = id; -+ psDevInfo->sBufferInfo.ui32Flags = 0; -+ psDevInfo->sBufferInfo.ui32BufferCount = (IMG_UINT32)psDevInfo->ulNumBuffers; -+ -+ return PVRSRV_OK; -+} -+ -+ -+static PVRSRV_ERROR BC_Register(id) -+{ -+ BC_CAT_DEVINFO *psDevInfo; -+ -+//psDevInfo = GetAnchorPtr(); -+ psDevInfo = GetAnchorPtr(id); -+ -+ if (psDevInfo == NULL) -+ { -+ psDevInfo = (BC_CAT_DEVINFO *)BCAllocKernelMem(sizeof(BC_CAT_DEVINFO)); -+ -+ if (!psDevInfo) -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ -+ psDevInfo->ref = 0; -+ psDevInfo->ulRefCount = 0; -+ SetAnchorPtr(id, (IMG_VOID*)psDevInfo); -+ -+ if (BCOpenPVRServices(&psDevInfo->hPVRServices) != PVRSRV_OK) -+ return PVRSRV_ERROR_INIT_FAILURE; -+ -+ if (BCGetLibFuncAddr(psDevInfo->hPVRServices, "PVRGetBufferClassJTable", -+ &pfnGetPVRJTable) != PVRSRV_OK) -+ return PVRSRV_ERROR_INIT_FAILURE; -+ -+ if (!(*pfnGetPVRJTable)(&psDevInfo->sPVRJTable)) -+ return PVRSRV_ERROR_INIT_FAILURE; -+ -+ psDevInfo->ulNumBuffers = 0; -+ -+ psDevInfo->psSystemBuffer = BCAllocKernelMem(sizeof(BC_CAT_BUFFER) * BC_EXAMPLE_NUM_BUFFERS); -+ -+ psDevInfo->sBufferInfo.pixelformat = PVRSRV_PIXEL_FORMAT_UNKNOWN; -+ psDevInfo->sBufferInfo.ui32Width = 0; -+ psDevInfo->sBufferInfo.ui32Height = 0; -+ psDevInfo->sBufferInfo.ui32ByteStride = 0; -+ psDevInfo->sBufferInfo.ui32BufferDeviceID = id; -+ psDevInfo->sBufferInfo.ui32Flags = 0; -+ psDevInfo->sBufferInfo.ui32BufferCount = (IMG_UINT32)psDevInfo->ulNumBuffers; -+ -+ psDevInfo->sBCJTable.ui32TableSize = sizeof(PVRSRV_BC_SRV2BUFFER_KMJTABLE); -+ -+strncpy(psDevInfo->sBufferInfo.szDeviceName, BUFFERCLASS_DEVICE_NAME, MAX_BUFFER_DEVICE_NAME_SIZE); -+#if 0 -+ psDevInfo->sBCJTable.pfnOpenBCDevice = OpenBCDevice; -+#else -+ if (id == 0) { -+ psDevInfo->sBCJTable.pfnOpenBCDevice = OpenBCDevice0; -+ } else if (id == 1) { -+ psDevInfo->sBCJTable.pfnOpenBCDevice = OpenBCDevice1; -+ } else if (id == 2) { -+ psDevInfo->sBCJTable.pfnOpenBCDevice = OpenBCDevice2; -+ } else if (id == 3) { -+ psDevInfo->sBCJTable.pfnOpenBCDevice = OpenBCDevice3; -+ } else if (id == 4) { -+ psDevInfo->sBCJTable.pfnOpenBCDevice = OpenBCDevice4; -+ } else if (id == 5) { -+ psDevInfo->sBCJTable.pfnOpenBCDevice = OpenBCDevice5; -+ } else if (id == 6) { -+ psDevInfo->sBCJTable.pfnOpenBCDevice = OpenBCDevice6; -+ } else if (id == 7) { -+ psDevInfo->sBCJTable.pfnOpenBCDevice = OpenBCDevice7; -+ } else if (id == 8) { -+ psDevInfo->sBCJTable.pfnOpenBCDevice = OpenBCDevice8; -+ } else if (id == 9) { -+ psDevInfo->sBCJTable.pfnOpenBCDevice = OpenBCDevice9; -+ } else { -+ printk("bad device id: %d\n", id); -+ return PVRSRV_ERROR_DEVICE_REGISTER_FAILED; -+ } -+#endif -+ psDevInfo->sBCJTable.pfnCloseBCDevice = CloseBCDevice; -+ psDevInfo->sBCJTable.pfnGetBCBuffer = GetBCBuffer; -+ psDevInfo->sBCJTable.pfnGetBCInfo = GetBCInfo; -+ psDevInfo->sBCJTable.pfnGetBufferAddr = GetBCBufferAddr; -+ -+ if (psDevInfo->sPVRJTable.pfnPVRSRVRegisterBCDevice( -+ &psDevInfo->sBCJTable, -+ (IMG_UINT32*)&psDevInfo->ulDeviceID) != PVRSRV_OK) -+ return PVRSRV_ERROR_DEVICE_REGISTER_FAILED; -+} -+ psDevInfo->ulRefCount++; -+ -+ return PVRSRV_OK; -+} -+ -+ -+static PVRSRV_ERROR BC_Unregister(int id) -+{ -+ BC_CAT_DEVINFO *psDevInfo; -+// PVRSRV_BC_BUFFER2SRV_KMJTABLE *psJTable; -+ -+ if ((psDevInfo = GetAnchorPtr(id)) == IMG_NULL) -+ return PVRSRV_ERROR_DEVICE_REGISTER_FAILED; -+ -+ psDevInfo->ulRefCount--; -+ -+ if (psDevInfo->ulRefCount) -+ return PVRSRV_ERROR_RETRY; -+ -+ -+ if (psDevInfo->ulRefCount == 0) -+ { -+ -+ PVRSRV_BC_BUFFER2SRV_KMJTABLE *psJTable = &psDevInfo->sPVRJTable; -+ -+ -+ if (psJTable->pfnPVRSRVRemoveBCDevice(psDevInfo->ulDeviceID) != PVRSRV_OK) -+ //return PVRSRV_ERROR_GENERIC; -+ return 1; -+ -+ if (BCClosePVRServices(psDevInfo->hPVRServices) != PVRSRV_OK) { -+ psDevInfo->hPVRServices = IMG_NULL; -+ //return PVRSRV_ERROR_GENERIC; -+ return 1; -+ } -+if (psDevInfo->psSystemBuffer) -+ { -+ BCFreeKernelMem(psDevInfo->psSystemBuffer); -+ } -+ -+ BCFreeKernelMem(psDevInfo); -+ SetAnchorPtr(id, IMG_NULL); -+} -+ return PVRSRV_OK; -+} -+ -+ -+static int __init bc_cat_init(void) -+{ -+ struct device *bc_dev; -+ int id; -+ -+ /* texture buffer width should be multiple of 8 for OMAP3 ES3.x, -+ * or 32 for ES2.x */ -+ -+#ifdef PLAT_TI8168 -+ width_align = 8; -+#else -+ width_align = 8; -+ //width_align = cpu_is_omap3530() && ( omap_rev() < OMAP3430_REV_ES3_0 ) ? 32 : 8; -+#endif -+ -+ major = register_chrdev(0, DEVNAME, &bc_cat_fops); -+ -+ if (major <= 0) { -+ printk(KERN_ERR DRVNAME ": unable to get major number\n"); -+ goto ExitDisable; -+ } -+ -+ bc_class = class_create(THIS_MODULE, DEVNAME); -+ -+ if (IS_ERR(bc_class)) { -+ printk(KERN_ERR DRVNAME ": upable to create device class\n"); -+ goto ExitUnregister; -+ } -+ -+ for (id = 0; id < DEVICE_COUNT; id++) { -+ bc_dev = device_create(bc_class, NULL, MKDEV(major, id), NULL, -+ DEVNAME "%d", id); -+ -+ if (IS_ERR(bc_dev)) { -+ printk(KERN_ERR DRVNAME ": unable to create device %d\n", id); -+ goto ExitDestroyClass; -+ } -+ -+ if (BC_Register(id) != PVRSRV_OK) { -+ printk (KERN_ERR DRVNAME ": can't register BC service %d\n", id); -+ if (id > 0) { -+ /* lets live with the drivers that we were able to create soi -+ * far, even though it isn't as many as we'd like -+ */ -+ break; -+ } -+ goto ExitUnregister; -+ } -+ } -+ -+ return 0; -+ -+ExitDestroyClass: -+ class_destroy(bc_class); -+ExitUnregister: -+ unregister_chrdev(major, DEVNAME); -+ExitDisable: -+ return -EBUSY; -+} -+ -+static void __exit bc_cat_cleanup(void) -+{ -+ int id=0; -+ -+ for (id = 0; id < DEVICE_COUNT; id++) { -+device_destroy(bc_class, MKDEV(major, id)); -+} -+ -+ class_destroy(bc_class); -+ -+ unregister_chrdev(major, DEVNAME); -+ -+ for (id = 0; id < DEVICE_COUNT; id++) { -+ if (BC_DestroyBuffers(id) != PVRSRV_OK) { -+ printk(KERN_ERR DRVNAME ": can't free texture buffers\n"); -+ return; -+ } -+ if (BC_Unregister(id) != PVRSRV_OK) { -+ printk(KERN_ERR DRVNAME ": can't un-register BC service\n"); -+ return; -+ } -+ } -+} -+ -+ -+static IMG_VOID *BCAllocKernelMem(unsigned long ulSize) -+{ -+ return kmalloc(ulSize, GFP_KERNEL); -+} -+ -+static IMG_VOID BCFreeKernelMem(IMG_VOID *pvMem) -+{ -+ kfree(pvMem); -+} -+ -+#if defined(BC_DISCONTIG_BUFFERS) -+ -+#define RANGE_TO_PAGES(range) (((range) + (PAGE_SIZE - 1)) >> PAGE_SHIFT) -+#define VMALLOC_TO_PAGE_PHYS(vAddr) page_to_phys(vmalloc_to_page(vAddr)) -+ -+BCE_ERROR BCAllocDiscontigMemory(unsigned long ulSize, -+ BCE_HANDLE unref__ *phMemHandle, -+ IMG_CPU_VIRTADDR *pLinAddr, -+ IMG_SYS_PHYADDR **ppPhysAddr) -+{ -+ unsigned long ulPages = RANGE_TO_PAGES(ulSize); -+ IMG_SYS_PHYADDR *pPhysAddr; -+ unsigned long ulPage; -+ IMG_CPU_VIRTADDR LinAddr; -+ -+ LinAddr = __vmalloc(ulSize, GFP_KERNEL | __GFP_HIGHMEM, pgprot_noncached(PAGE_KERNEL)); -+ if (!LinAddr) -+ { -+ return BCE_ERROR_OUT_OF_MEMORY; -+ } -+ -+ pPhysAddr = kmalloc(ulPages * sizeof(IMG_SYS_PHYADDR), GFP_KERNEL); -+ if (!pPhysAddr) -+ { -+ vfree(LinAddr); -+ return BCE_ERROR_OUT_OF_MEMORY; -+ } -+ -+ *pLinAddr = LinAddr; -+ -+ for (ulPage = 0; ulPage < ulPages; ulPage++) -+ { -+ pPhysAddr[ulPage].uiAddr = VMALLOC_TO_PAGE_PHYS(LinAddr); -+ -+ LinAddr += PAGE_SIZE; -+ } -+ -+ *ppPhysAddr = pPhysAddr; -+ -+ return BCE_OK; -+} -+ -+void BCFreeDiscontigMemory(unsigned long ulSize, -+ BCE_HANDLE unref__ hMemHandle, -+ IMG_CPU_VIRTADDR LinAddr, -+ IMG_SYS_PHYADDR *pPhysAddr) -+{ -+ kfree(pPhysAddr); -+ -+ vfree(LinAddr); -+} -+#else -+ -+BCE_ERROR BCAllocContigMemory(unsigned long ulSize, -+ IMG_HANDLE unref__ *phMemHandle, -+ IMG_CPU_VIRTADDR *pLinAddr, -+ IMG_CPU_PHYADDR *pPhysAddr) -+{ -+ -+#if defined(BCE_USE_SET_MEMORY) -+ void *pvLinAddr; -+ unsigned long ulAlignedSize = PAGE_ALIGN(ulSize); -+ int iPages = (int)(ulAlignedSize >> PAGE_SHIFT); -+ int iError; -+ -+ pvLinAddr = kmalloc(ulAlignedSize, GFP_KERNEL); -+ BUG_ON(((unsigned long)pvLinAddr) & ~PAGE_MASK); -+ -+ iError = set_memory_wc((unsigned long)pvLinAddr, iPages); -+ if (iError != 0) -+ { -+ printk(KERN_ERR DRVNAME ": BCAllocContigMemory: set_memory_wc failed (%d)\n", iError); -+ return (BCE_ERROR_OUT_OF_MEMORY); -+ } -+ -+ pPhysAddr->uiAddr = virt_to_phys(pvLinAddr); -+ *pLinAddr = pvLinAddr; -+ -+ return (BCE_OK); -+#else -+ dma_addr_t dma; -+ void *pvLinAddr; -+ -+ pvLinAddr = dma_alloc_coherent(NULL, ulSize, &dma, GFP_KERNEL); -+ if (pvLinAddr == NULL) -+ { -+ return (BCE_ERROR_OUT_OF_MEMORY); -+ } -+ -+ pPhysAddr->uiAddr = dma; -+ *pLinAddr = pvLinAddr; -+ -+ return (BCE_OK); -+#endif -+#if 0 -+ IMG_VOID *pvLinAddr; -+ gfp_t mask = GFP_KERNEL; -+ -+ pvLinAddr = alloc_pages_exact(ui32Size, mask); -+ -+ if (pvLinAddr == IMG_NULL) -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ -+ pPhysAddr->uiAddr = virt_to_phys(pvLinAddr); -+ -+ *pLinAddr = pvLinAddr; -+#endif -+ // return PVRSRV_OK; -+} -+ -+static IMG_VOID BCFreeContigMemory(unsigned long ulSize, -+ IMG_HANDLE unref__ hMemHandle, -+ IMG_CPU_VIRTADDR LinAddr, -+ IMG_CPU_PHYADDR PhysAddr) -+{ -+ // free_pages_exact(LinAddr, ui32Size); -+#if defined(BCE_USE_SET_MEMORY) -+ unsigned long ulAlignedSize = PAGE_ALIGN(ulSize); -+ int iError; -+ int iPages = (int)(ulAlignedSize >> PAGE_SHIFT); -+ -+ iError = set_memory_wb((unsigned long)LinAddr, iPages); -+ if (iError != 0) -+ { -+ printk(KERN_ERR DRVNAME ": BCFreeContigMemory: set_memory_wb failed (%d)\n", iError); -+ } -+ kfree(LinAddr); -+#else -+ dma_free_coherent(NULL, ulSize, LinAddr, (dma_addr_t)PhysAddr.uiAddr); -+#endif -+ -+} -+ -+#endif -+static IMG_SYS_PHYADDR CpuPAddrToSysPAddrBC(IMG_CPU_PHYADDR cpu_paddr) -+{ -+ IMG_SYS_PHYADDR sys_paddr; -+ -+ sys_paddr.uiAddr = cpu_paddr.uiAddr; -+ return sys_paddr; -+} -+ -+static IMG_CPU_PHYADDR SysPAddrToCpuPAddrBC(IMG_SYS_PHYADDR sys_paddr) -+{ -+ IMG_CPU_PHYADDR cpu_paddr; -+ -+ cpu_paddr.uiAddr = sys_paddr.uiAddr; -+ return cpu_paddr; -+} -+ -+static PVRSRV_ERROR BCOpenPVRServices (IMG_HANDLE *phPVRServices) -+{ -+ *phPVRServices = 0; -+ return PVRSRV_OK; -+} -+ -+ -+static PVRSRV_ERROR BCClosePVRServices (IMG_HANDLE unref__ hPVRServices) -+{ -+ return PVRSRV_OK; -+} -+ -+static PVRSRV_ERROR BCGetLibFuncAddr(IMG_HANDLE unref__ hExtDrv, -+ IMG_CHAR *szFunctionName, -+ PFN_BC_GET_PVRJTABLE *ppfnFuncTable) -+{ -+ if (strcmp("PVRGetBufferClassJTable", szFunctionName) != 0) -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ -+ *ppfnFuncTable = PVRGetBufferClassJTable; -+ return PVRSRV_OK; -+} -+ -+ -+static int bc_open(struct inode *i, struct file *f) -+{ -+ BC_CAT_DEVINFO *devinfo; -+ int id = file_to_id(f); -+ -+ if ((devinfo = GetAnchorPtr(id)) == IMG_NULL) { -+ printk("no device %d\n", id); -+ return -ENODEV; -+ } -+ -+ if (devinfo->ref) { -+ printk("device %d busy\n", id); -+ return -EBUSY; -+ } -+ -+ devinfo->ref++; -+ return 0; -+} -+ -+ -+static int bc_release(struct inode *i, struct file *f) -+{ -+ BC_CAT_DEVINFO *devinfo; -+ int id = file_to_id(f); -+ -+ if ((devinfo = GetAnchorPtr(id)) == IMG_NULL) -+ return -ENODEV; -+ -+ for (id = 0; id < DEVICE_COUNT; id++) { -+ if (BC_DestroyBuffers(id) != PVRSRV_OK) { -+ printk(KERN_ERR DRVNAME ": can't free texture buffer \n"); -+ } -+ } -+ -+ if (devinfo->ref) -+ devinfo->ref--; -+ return 0; -+} -+ -+ -+static int bc_mmap(struct file *filp, struct vm_area_struct *vma) -+{ -+#if defined(DEBUG) -+ printk("bc_mmap: vma->vm_start = %#lx\n", vma->vm_start); -+ printk("bc_mmap: vma->vm_pgoff = %#lx\n", vma->vm_pgoff); -+ printk("bc_mmap: size = %#lx\n", vma->vm_end - vma->vm_start); -+#endif -+ -+ /*FIXME check start & size*/ -+ if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, -+ vma->vm_end - vma->vm_start, -+ vma->vm_page_prot)) { -+ printk("bc_mmap: failed remap_pfn_range\n"); -+ return -EAGAIN; -+ } -+ return 0; -+} -+ -+int ReconfigureBuffer(int id, bc_buf_params_t *p, unsigned int *uiSucceed) -+{ -+ BCE_ERROR eError; -+ -+ -+ eError = BC_DestroyBuffers(id); -+ -+ if (eError != BCE_OK) -+ { -+ *uiSucceed = 0; -+ return -1; -+ } -+ -+ -+ -+ -+ -+ eError = BC_CreateBuffers(id,p); -+ -+ if (eError != BCE_OK) -+ { -+ *uiSucceed = 0; -+ return -1; -+ } -+ -+ -+ *uiSucceed = 1; -+ return 0; -+} -+ -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) -+static int bc_ioctl(struct inode *inode, struct file *file, -+ unsigned int cmd, unsigned long arg) -+#else -+static long bc_ioctl(struct file *file, -+ unsigned int cmd, unsigned long arg) -+#endif -+{ -+ BC_CAT_DEVINFO *devinfo; -+//PVR_UNREFERENCED_PARAMETER(inode); -+ int id = file_to_id (file); -+ -+ if ((devinfo = GetAnchorPtr(id)) == IMG_NULL) -+ return -ENODEV; -+ -+ switch(_IOC_NR(cmd)) { -+ case _IOC_NR(BCIOGET_BUFFERCOUNT): -+ { -+ BCIO_package *params = (BCIO_package *)arg; -+ -+ if (!access_ok(VERIFY_WRITE, params, sizeof(BCIO_package))) -+ return -EFAULT; -+ -+ params->output = devinfo->sBufferInfo.ui32BufferCount; -+ break; -+ } -+ case _IOC_NR(BCIOGET_BUFFERPHYADDR): -+ { -+ int idx; -+ BCIO_package *params = (BCIO_package *)arg; -+ -+ if (!access_ok(VERIFY_WRITE, params, sizeof(BCIO_package))) -+ return -EFAULT; -+ -+ idx = params->input; -+ if (idx < 0 || idx > devinfo->ulNumBuffers) { -+ printk(KERN_ERR DRVNAME -+ ": BCIOGET_BUFFERADDR - idx out of range\n"); -+ return -EINVAL; -+ } -+ params->output = devinfo->psSystemBuffer[idx].sSysAddr.uiAddr; -+ break; -+ } -+ case _IOC_NR(BCIOGET_BUFFERIDX): -+ { -+ int idx; -+ BC_CAT_BUFFER *buffer; -+ BCIO_package *params = (BCIO_package *)arg; -+ -+ if (!access_ok(VERIFY_WRITE, params, sizeof(BCIO_package))) -+ return -EFAULT; -+ -+ for (idx = 0; idx < devinfo->ulNumBuffers; idx++) { -+ buffer = &devinfo->psSystemBuffer[idx]; -+ -+ if (params->input == (int)buffer->sSysAddr.uiAddr) { -+ params->output = idx; -+ return 0; -+ } -+ } -+ printk(KERN_ERR DRVNAME ": BCIOGET_BUFFERIDX- buffer not found\n"); -+ return -EINVAL; -+ break; -+ } -+ case _IOC_NR(BCIOREQ_BUFFERS): -+ { -+ bc_buf_params_t *p = (bc_buf_params_t *) arg; -+ -+ if (!access_ok(VERIFY_WRITE, p, sizeof(bc_buf_params_t))) -+ return -EFAULT; -+ -+ return BC_CreateBuffers(id, p); -+ break; -+ } -+ case _IOC_NR(BCIOSET_BUFFERPHYADDR): -+ { -+ bc_buf_ptr_t p; -+ IMG_CPU_PHYADDR img_pa; -+ -+ if (copy_from_user(&p, (void __user *)arg, sizeof(p))) -+ return -EFAULT; -+ -+ if (p.index >= devinfo->ulNumBuffers || !p.pa) -+ return -EINVAL; -+ -+ /*TODO check buffer size*/ -+ -+ img_pa.uiAddr = p.pa; -+ -+ devinfo->psSystemBuffer[p.index].sCPUVAddr = phys_to_virt(p.pa); -+ devinfo->psSystemBuffer[p.index].sSysAddr = -+ CpuPAddrToSysPAddrBC(img_pa); -+ devinfo->psSystemBuffer[p.index].sPageAlignSysAddr.uiAddr = -+ devinfo->psSystemBuffer[p.index].sSysAddr.uiAddr & -+ 0xFFFFF000; -+ break; -+ } -+ case _IOC_NR(BCIORECONFIGURE_BUFFERS): -+ { -+ unsigned int outputparam; -+ bc_buf_params_t *p = (bc_buf_params_t *) arg; -+ if(ReconfigureBuffer(id,p,&outputparam) == -1) -+ { -+ return -EFAULT; -+ } -+ break; -+ } -+ default: -+ return -EFAULT; -+ } -+ return 0; -+} -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)) -+static long bc_ioctl_unlocked(struct file *file, unsigned int cmd, unsigned long arg) -+{ -+ int res; -+ -+ mutex_lock(&sBCExampleBridgeMutex); -+ res = bc_ioctl(file, cmd, arg); -+ mutex_unlock(&sBCExampleBridgeMutex); -+ -+ return res; -+} -+#endif -+ -+ -+module_init(bc_cat_init); -+module_exit(bc_cat_cleanup); -+ -+MODULE_LICENSE("GPL v2"); -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_ti/bc_cat.h b/drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_ti/bc_cat.h -new file mode 100644 -index 0000000..d5255a0 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_ti/bc_cat.h -@@ -0,0 +1,88 @@ -+/********************************************************************** -+ * -+ * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ -+ * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful but, except -+ * as otherwise stated in writing, without any warranty; without even the -+ * implied warranty of merchantability or fitness for a particular purpose. -+ * See the GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -+ * -+ * The full GNU General Public License is included in this distribution in -+ * the file called "COPYING". -+ * -+ * Contact Information: -+ * Imagination Technologies Ltd. <gpl-support@imgtec.com> -+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK -+ * -+ ******************************************************************************/ -+ -+#ifndef __BC_CAT_H__ -+#define __BC_CAT_H__ -+ -+#include <linux/ioctl.h> -+ -+#define BC_FOURCC(a,b,c,d) \ -+ ((unsigned long) ((a) | (b)<<8 | (c)<<16 | (d)<<24)) -+ -+#define BC_PIX_FMT_I420 BC_FOURCC('I', '4', '2', '0') /*YUV 4:2:0*/ -+#define BC_PIX_FMT_YV12 BC_FOURCC('Y', 'V', '1', '2') /*YUV 4:2:0*/ -+#define BC_PIX_FMT_NV12 BC_FOURCC('N', 'V', '1', '2') /*YUV 4:2:0*/ -+#define BC_PIX_FMT_UYVY BC_FOURCC('U', 'Y', 'V', 'Y') /*YUV 4:2:2*/ -+#define BC_PIX_FMT_YUYV BC_FOURCC('Y', 'U', 'Y', 'V') /*YUV 4:2:2*/ -+#define BC_PIX_FMT_RGB565 BC_FOURCC('R', 'G', 'B', 'P') /*RGB 5:6:5*/ -+#define BC_PIX_FMT_ARGB BC_FOURCC('A', 'R', 'G', 'B') /*ARGB 8:8:8:8*/ -+ -+enum BC_memory { -+ BC_MEMORY_MMAP = 1, -+ BC_MEMORY_USERPTR = 2, -+}; -+ -+typedef struct BCIO_package_TAG { -+ int input; -+ int output; -+}BCIO_package; -+ -+/* -+ * the following types are tested for fourcc in struct bc_buf_params_t -+ * NV12 -+ * UYVY -+ * RGB565 - not tested yet -+ * YUYV -+ */ -+typedef struct bc_buf_params { -+ int count; /*number of buffers, [in/out]*/ -+ int width; /*buffer width in pixel, multiple of 8 or 32*/ -+ int height; /*buffer height in pixel*/ -+ unsigned int fourcc; /*buffer pixel format*/ -+ enum BC_memory type; -+} bc_buf_params_t; -+ -+typedef struct bc_buf_ptr { -+ unsigned int index; -+ int size; -+ unsigned long pa; -+} bc_buf_ptr_t; -+int ReconfigureBuffer(int id, bc_buf_params_t *p,unsigned int *uiSucceed); -+ -+#define BCIO_GID 'g' -+#define BC_IOWR(INDEX) _IOWR(BCIO_GID, INDEX, BCIO_package) -+ -+#define BCIOGET_BUFFERCOUNT BC_IOWR(0) /*obsolete, since BCIOREQ_BUFFERS -+ return the number of buffers*/ -+#define BCIOGET_BUFFERPHYADDR BC_IOWR(1) /*get physical address by index*/ -+#define BCIOGET_BUFFERIDX BC_IOWR(2) /*get index by physical address*/ -+ -+#define BCIOREQ_BUFFERS BC_IOWR(3) -+#define BCIOSET_BUFFERPHYADDR BC_IOWR(4) -+#define BCIORECONFIGURE_BUFFERS BC_IOWR(5) -+ -+#endif -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_omapfb3_linux/3rdparty_dc_drm_shared.h b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_omapfb3_linux/3rdparty_dc_drm_shared.h -new file mode 100644 -index 0000000..b522c41 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_omapfb3_linux/3rdparty_dc_drm_shared.h -@@ -0,0 +1,64 @@ -+/*************************************************************************/ /*! -+@Title OMAP Linux display driver shared DRM structures -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description OMAP Linux display driver DRM structures shared between -+ kernel and user space. -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+#ifndef __3RDPARTY_DC_DRM_SHARED_H__ -+#define __3RDPARTY_DC_DRM_SHARED_H__ -+#if defined(SUPPORT_DRI_DRM) -+ -+#define PVR_DRM_DISP_CMD_ENTER_VT 1 -+#define PVR_DRM_DISP_CMD_LEAVE_VT 2 -+ -+#define PVR_DRM_DISP_CMD_ON 3 -+#define PVR_DRM_DISP_CMD_STANDBY 4 -+#define PVR_DRM_DISP_CMD_SUSPEND 5 -+#define PVR_DRM_DISP_CMD_OFF 6 -+ -+#define PVR_DRM_DISP_ARG_CMD 0 -+#define PVR_DRM_DISP_ARG_DEV 1 -+#define PVR_DRM_DISP_NUM_ARGS 2 -+ -+#endif /* defined(SUPPORT_DRI_DRM) */ -+#endif /* __3RDPARTY_DC_DRM_SHARED_H__ */ -+ -+/****************************************************************************** -+ End of file (3rdparty_dc_drm_shared.h) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_omapfb3_linux/Kbuild b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_omapfb3_linux/Kbuild -new file mode 100644 -index 0000000..c610eee ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_omapfb3_linux/Kbuild -@@ -0,0 +1,34 @@ -+SYS_USING_INTERRUPTS = 1 -+SUPPORT_OMAP3430_OMAPFB3 =1 -+SUPPORT_TI_DSS_FW = 0 -+PVR_LINUX_USING_WORKQUEUES = 1 -+SYS_CFLAGS.$(SYS_USING_INTERRUPTS) += -DSYS_USING_INTERRUPTS -+SYS_CFLAGS.$(SUPPORT_OMAP3430_OMAPFB3) += -DSUPPORT_OMAP3430_OMAPFB3 -+SYS_CFLAGS.$(SUPPORT_TI_DSS_FW) += -DSUPPORT_TI_DSS_FW -+SYS_CFLAGS.$(PVR_LINUX_USING_WORKQUEUES) += -DPVR_LINUX_USING_WORKQUEUES -+SYS_CFLAGS += -DDISPLAY_CONTROLLER=omaplfb -+ -+ -+EXTRA_CFLAGS = -DLINUX \ -+ -I$(PVR_BUILD_DIR)/include4 \ -+ -I$(PVR_BUILD_DIR)/services4/include \ -+ -I$(PVR_BUILD_DIR)/services4/system/$(PVR_SYSTEM) \ -+ -I$(PVR_BUILD_DIR)/services4/srvkm/env/linux \ -+ -I$(PVR_BUILD_DIR)/services4/include/env/linux \ -+ -I$(PVR_BUILD_DIR)/services4/system/include \ -+ -I$(KERNELDIR)/drivers/video/omap2 \ -+ -I$(KERNELDIR)/arch/arm/plat-omap/include \ -+ $(SYS_CFLAGS.1) \ -+ -+ifneq ($(FBDEV),no) -+EXTRA_CFLAGS += -DFBDEV_PRESENT -+endif -+ -+ -+ifeq ($(SUPPORT_XORG),1) -+EXTRA_CFLAGS += -DSUPPORT_DRI_DRM -+EXTRA_CFLAGS += -DPVR_DISPLAY_CONTROLLER_DRM_IOCTL -+endif -+ -+obj-m := omaplfb.o -+omaplfb-y := omaplfb_displayclass.o omaplfb_linux.o -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_omapfb3_linux/Kbuild.mk b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_omapfb3_linux/Kbuild.mk -new file mode 100644 -index 0000000..0310b95 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_omapfb3_linux/Kbuild.mk -@@ -0,0 +1,48 @@ -+########################################################################### ### -+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+#@License Dual MIT/GPLv2 -+# -+# The contents of this file are subject to the MIT license as set out below. -+# -+# Permission is hereby granted, free of charge, to any person obtaining a copy -+# of this software and associated documentation files (the "Software"), to deal -+# in the Software without restriction, including without limitation the rights -+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+# copies of the Software, and to permit persons to whom the Software is -+# furnished to do so, subject to the following conditions: -+# -+# The above copyright notice and this permission notice shall be included in -+# all copies or substantial portions of the Software. -+# -+# Alternatively, the contents of this file may be used under the terms of -+# the GNU General Public License Version 2 ("GPL") in which case the provisions -+# of GPL are applicable instead of those above. -+# -+# If you wish to allow use of your version of this file only under the terms of -+# GPL, and not to allow others to use your version of this file under the terms -+# of the MIT license, indicate your decision by deleting the provisions above -+# and replace them with the notice and other provisions required by GPL as set -+# out in the file called "GPL-COPYING" included in this distribution. If you do -+# not delete the provisions above, a recipient may use your version of this file -+# under the terms of either the MIT license or GPL. -+# -+# This License is also included in this distribution in the file called -+# "MIT-COPYING". -+# -+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+### ########################################################################### -+ -+ccflags-y += \ -+ -I$(TOP)/services4/3rdparty/dc_omapfb3_linux \ -+ -Idrivers/video/omap2 \ -+ -Iarch/arm/plat-omap/include -+ -+omaplfb-y += \ -+ services4/3rdparty/dc_omapfb3_linux/omaplfb_displayclass.o \ -+ services4/3rdparty/dc_omapfb3_linux/omaplfb_linux.o -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_omapfb3_linux/Linux.mk b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_omapfb3_linux/Linux.mk -new file mode 100644 -index 0000000..4008b4d ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_omapfb3_linux/Linux.mk -@@ -0,0 +1,45 @@ -+########################################################################### ### -+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+#@License Dual MIT/GPLv2 -+# -+# The contents of this file are subject to the MIT license as set out below. -+# -+# Permission is hereby granted, free of charge, to any person obtaining a copy -+# of this software and associated documentation files (the "Software"), to deal -+# in the Software without restriction, including without limitation the rights -+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+# copies of the Software, and to permit persons to whom the Software is -+# furnished to do so, subject to the following conditions: -+# -+# The above copyright notice and this permission notice shall be included in -+# all copies or substantial portions of the Software. -+# -+# Alternatively, the contents of this file may be used under the terms of -+# the GNU General Public License Version 2 ("GPL") in which case the provisions -+# of GPL are applicable instead of those above. -+# -+# If you wish to allow use of your version of this file only under the terms of -+# GPL, and not to allow others to use your version of this file under the terms -+# of the MIT license, indicate your decision by deleting the provisions above -+# and replace them with the notice and other provisions required by GPL as set -+# out in the file called "GPL-COPYING" included in this distribution. If you do -+# not delete the provisions above, a recipient may use your version of this file -+# under the terms of either the MIT license or GPL. -+# -+# This License is also included in this distribution in the file called -+# "MIT-COPYING". -+# -+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+### ########################################################################### -+ -+modules := dc_omapfb3_linux -+ -+dc_omapfb3_linux_type := kernel_module -+dc_omapfb3_linux_target := omaplfb.ko -+dc_omapfb3_linux_makefile := $(THIS_DIR)/Kbuild.mk -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_omapfb3_linux/omaplfb.h b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_omapfb3_linux/omaplfb.h -new file mode 100644 -index 0000000..e7b4fa2 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_omapfb3_linux/omaplfb.h -@@ -0,0 +1,331 @@ -+/*************************************************************************/ /*! -+@Title OMAP Linux display driver structures and prototypes -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+#ifndef __OMAPLFB_H__ -+#define __OMAPLFB_H__ -+ -+#include <linux/version.h> -+ -+#include <asm/atomic.h> -+ -+#include <linux/kernel.h> -+#include <linux/console.h> -+#include <linux/fb.h> -+#include <linux/module.h> -+#include <linux/string.h> -+#include <linux/notifier.h> -+#include <linux/mutex.h> -+ -+#ifdef CONFIG_HAS_EARLYSUSPEND -+#include <linux/earlysuspend.h> -+#endif -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) -+#define OMAPLFB_CONSOLE_LOCK() console_lock() -+#define OMAPLFB_CONSOLE_UNLOCK() console_unlock() -+#else -+#define OMAPLFB_CONSOLE_LOCK() acquire_console_sem() -+#define OMAPLFB_CONSOLE_UNLOCK() release_console_sem() -+#endif -+ -+#if defined(CONFIG_ION_OMAP) -+#include <linux/ion.h> -+#include <linux/omap_ion.h> -+#endif /* defined(CONFIG_ION_OMAP) */ -+ -+#define unref__ __attribute__ ((unused)) -+ -+typedef void * OMAPLFB_HANDLE; -+ -+typedef bool OMAPLFB_BOOL, *OMAPLFB_PBOOL; -+#define OMAPLFB_FALSE false -+#define OMAPLFB_TRUE true -+ -+typedef atomic_t OMAPLFB_ATOMIC_BOOL; -+ -+typedef atomic_t OMAPLFB_ATOMIC_INT; -+ -+/* OMAPLFB buffer structure */ -+typedef struct OMAPLFB_BUFFER_TAG -+{ -+ struct OMAPLFB_BUFFER_TAG *psNext; -+ struct OMAPLFB_DEVINFO_TAG *psDevInfo; -+ -+ struct work_struct sWork; -+ -+ /* Position of this buffer in the virtual framebuffer */ -+ unsigned long ulYOffset; -+ -+ /* IMG structures used, to minimise API function code */ -+ /* replace with own structures where necessary */ -+ IMG_SYS_PHYADDR sSysAddr; -+ IMG_CPU_VIRTADDR sCPUVAddr; -+ PVRSRV_SYNC_DATA *psSyncData; -+ -+ OMAPLFB_HANDLE hCmdComplete; -+ unsigned long ulSwapInterval; -+} OMAPLFB_BUFFER; -+ -+/* OMAPLFB swapchain structure */ -+typedef struct OMAPLFB_SWAPCHAIN_TAG -+{ -+ /* Swap chain ID */ -+ unsigned int uiSwapChainID; -+ -+ /* number of buffers in swapchain */ -+ unsigned long ulBufferCount; -+ -+ /* list of buffers in the swapchain */ -+ OMAPLFB_BUFFER *psBuffer; -+ -+ /* Swap chain work queue */ -+ struct workqueue_struct *psWorkQueue; -+ -+ /* -+ * Set if we didn't manage to wait for VSync on last swap, -+ * or if we think we need to wait for VSync on the next flip. -+ * The flag helps to avoid jitter when the screen is -+ * unblanked, by forcing an extended wait for VSync before -+ * attempting the next flip. -+ */ -+ OMAPLFB_BOOL bNotVSynced; -+ -+ /* Previous number of blank events */ -+ int iBlankEvents; -+ -+ /* Framebuffer Device ID for messages (e.g. printk) */ -+ unsigned int uiFBDevID; -+} OMAPLFB_SWAPCHAIN; -+ -+typedef struct OMAPLFB_FBINFO_TAG -+{ -+ unsigned long ulFBSize; -+ unsigned long ulBufferSize; -+ unsigned long ulRoundedBufferSize; -+ unsigned long ulWidth; -+ unsigned long ulHeight; -+ unsigned long ulByteStride; -+ unsigned long ulPhysicalWidthmm; -+ unsigned long ulPhysicalHeightmm; -+ -+ /* IMG structures used, to minimise API function code */ -+ /* replace with own structures where necessary */ -+ IMG_SYS_PHYADDR sSysAddr;//system physical address -+ IMG_CPU_VIRTADDR sCPUVAddr; -+ -+ /* pixelformat of system/primary surface */ -+ PVRSRV_PIXEL_FORMAT ePixelFormat; -+ -+#if defined(CONFIG_DSSCOMP) -+ OMAPLFB_BOOL bIs2D; -+ IMG_SYS_PHYADDR *psPageList; -+ struct ion_handle *psIONHandle; -+ IMG_UINT32 uiBytesPerPixel; -+#endif -+} OMAPLFB_FBINFO; -+ -+/* kernel device information structure */ -+typedef struct OMAPLFB_DEVINFO_TAG -+{ -+ /* Framebuffer Device ID */ -+ unsigned int uiFBDevID; -+ -+ /* PVR Device ID */ -+ unsigned int uiPVRDevID; -+ -+ /* Swapchain create/destroy mutex */ -+ struct mutex sCreateSwapChainMutex; -+ -+ /* system surface info */ -+ OMAPLFB_BUFFER sSystemBuffer; -+ -+ /* jump table into PVR services */ -+ PVRSRV_DC_DISP2SRV_KMJTABLE sPVRJTable; -+ -+ /* jump table into DC */ -+ PVRSRV_DC_SRV2DISP_KMJTABLE sDCJTable; -+ -+ /* fb info structure */ -+ OMAPLFB_FBINFO sFBInfo; -+ -+ /* Only one swapchain supported by this device so hang it here */ -+ OMAPLFB_SWAPCHAIN *psSwapChain; -+ -+ /* Swap chain ID */ -+ unsigned int uiSwapChainID; -+ -+ /* True if PVR Services is flushing its command queues */ -+ OMAPLFB_ATOMIC_BOOL sFlushCommands; -+ -+ /* pointer to linux frame buffer information structure */ -+ struct fb_info *psLINFBInfo; -+ -+ /* Linux Framebuffer event notification block */ -+ struct notifier_block sLINNotifBlock; -+ -+ /* IMG structures used, to minimise API function code */ -+ /* replace with own structures where necessary */ -+ -+ /* Address of the surface being displayed */ -+ IMG_DEV_VIRTADDR sDisplayDevVAddr; -+ -+ DISPLAY_INFO sDisplayInfo; -+ -+ /* Display format */ -+ DISPLAY_FORMAT sDisplayFormat; -+ -+ /* Display dimensions */ -+ DISPLAY_DIMS sDisplayDim; -+ -+ /* True if screen is blanked */ -+ OMAPLFB_ATOMIC_BOOL sBlanked; -+ -+ /* Number of blank/unblank events */ -+ OMAPLFB_ATOMIC_INT sBlankEvents; -+ -+#ifdef CONFIG_HAS_EARLYSUSPEND -+ /* Set by early suspend */ -+ OMAPLFB_ATOMIC_BOOL sEarlySuspendFlag; -+ -+ struct early_suspend sEarlySuspend; -+#endif -+ -+#if defined(SUPPORT_DRI_DRM) -+ OMAPLFB_ATOMIC_BOOL sLeaveVT; -+#endif -+ -+#if defined(CONFIG_ION_OMAP) -+ struct ion_client *psIONClient; -+#endif -+ -+} OMAPLFB_DEVINFO; -+ -+#define OMAPLFB_PAGE_SIZE 4096 -+ -+/* DEBUG only printk */ -+#ifdef DEBUG -+#define DEBUG_PRINTK(x) printk x -+#else -+#define DEBUG_PRINTK(x) -+#endif -+ -+#define DISPLAY_DEVICE_NAME "PowerVR OMAP Linux Display Driver" -+#define DRVNAME "omaplfb" -+#define DEVNAME DRVNAME -+#define DRIVER_PREFIX DRVNAME -+ -+/*! -+ ***************************************************************************** -+ * Error values -+ *****************************************************************************/ -+typedef enum _OMAPLFB_ERROR_ -+{ -+ OMAPLFB_OK = 0, -+ OMAPLFB_ERROR_GENERIC = 1, -+ OMAPLFB_ERROR_OUT_OF_MEMORY = 2, -+ OMAPLFB_ERROR_TOO_FEW_BUFFERS = 3, -+ OMAPLFB_ERROR_INVALID_PARAMS = 4, -+ OMAPLFB_ERROR_INIT_FAILURE = 5, -+ OMAPLFB_ERROR_CANT_REGISTER_CALLBACK = 6, -+ OMAPLFB_ERROR_INVALID_DEVICE = 7, -+ OMAPLFB_ERROR_DEVICE_REGISTER_FAILED = 8, -+ OMAPLFB_ERROR_SET_UPDATE_MODE_FAILED = 9 -+} OMAPLFB_ERROR; -+ -+typedef enum _OMAPLFB_UPDATE_MODE_ -+{ -+ OMAPLFB_UPDATE_MODE_UNDEFINED = 0, -+ OMAPLFB_UPDATE_MODE_MANUAL = 1, -+ OMAPLFB_UPDATE_MODE_AUTO = 2, -+ OMAPLFB_UPDATE_MODE_DISABLED = 3 -+} OMAPLFB_UPDATE_MODE; -+ -+#ifndef UNREFERENCED_PARAMETER -+#define UNREFERENCED_PARAMETER(param) (param) = (param) -+#endif -+ -+OMAPLFB_ERROR OMAPLFBInit(void); -+OMAPLFB_ERROR OMAPLFBDeInit(void); -+ -+/* OS Specific APIs */ -+OMAPLFB_DEVINFO *OMAPLFBGetDevInfoPtr(unsigned uiFBDevID); -+unsigned OMAPLFBMaxFBDevIDPlusOne(void); -+void *OMAPLFBAllocKernelMem(unsigned long ulSize); -+void OMAPLFBFreeKernelMem(void *pvMem); -+OMAPLFB_ERROR OMAPLFBGetLibFuncAddr(char *szFunctionName, PFN_DC_GET_PVRJTABLE *ppfnFuncTable); -+OMAPLFB_ERROR OMAPLFBCreateSwapQueue (OMAPLFB_SWAPCHAIN *psSwapChain); -+void OMAPLFBDestroySwapQueue(OMAPLFB_SWAPCHAIN *psSwapChain); -+void OMAPLFBInitBufferForSwap(OMAPLFB_BUFFER *psBuffer); -+void OMAPLFBSwapHandler(OMAPLFB_BUFFER *psBuffer); -+void OMAPLFBQueueBufferForSwap(OMAPLFB_SWAPCHAIN *psSwapChain, OMAPLFB_BUFFER *psBuffer); -+void OMAPLFBFlip(OMAPLFB_DEVINFO *psDevInfo, OMAPLFB_BUFFER *psBuffer); -+OMAPLFB_UPDATE_MODE OMAPLFBGetUpdateMode(OMAPLFB_DEVINFO *psDevInfo); -+OMAPLFB_BOOL OMAPLFBSetUpdateMode(OMAPLFB_DEVINFO *psDevInfo, OMAPLFB_UPDATE_MODE eMode); -+OMAPLFB_BOOL OMAPLFBWaitForVSync(OMAPLFB_DEVINFO *psDevInfo); -+OMAPLFB_BOOL OMAPLFBManualSync(OMAPLFB_DEVINFO *psDevInfo); -+OMAPLFB_BOOL OMAPLFBCheckModeAndSync(OMAPLFB_DEVINFO *psDevInfo); -+OMAPLFB_ERROR OMAPLFBUnblankDisplay(OMAPLFB_DEVINFO *psDevInfo); -+OMAPLFB_ERROR OMAPLFBEnableLFBEventNotification(OMAPLFB_DEVINFO *psDevInfo); -+OMAPLFB_ERROR OMAPLFBDisableLFBEventNotification(OMAPLFB_DEVINFO *psDevInfo); -+void OMAPLFBCreateSwapChainLockInit(OMAPLFB_DEVINFO *psDevInfo); -+void OMAPLFBCreateSwapChainLockDeInit(OMAPLFB_DEVINFO *psDevInfo); -+void OMAPLFBCreateSwapChainLock(OMAPLFB_DEVINFO *psDevInfo); -+void OMAPLFBCreateSwapChainUnLock(OMAPLFB_DEVINFO *psDevInfo); -+void OMAPLFBAtomicBoolInit(OMAPLFB_ATOMIC_BOOL *psAtomic, OMAPLFB_BOOL bVal); -+void OMAPLFBAtomicBoolDeInit(OMAPLFB_ATOMIC_BOOL *psAtomic); -+void OMAPLFBAtomicBoolSet(OMAPLFB_ATOMIC_BOOL *psAtomic, OMAPLFB_BOOL bVal); -+OMAPLFB_BOOL OMAPLFBAtomicBoolRead(OMAPLFB_ATOMIC_BOOL *psAtomic); -+void OMAPLFBAtomicIntInit(OMAPLFB_ATOMIC_INT *psAtomic, int iVal); -+void OMAPLFBAtomicIntDeInit(OMAPLFB_ATOMIC_INT *psAtomic); -+void OMAPLFBAtomicIntSet(OMAPLFB_ATOMIC_INT *psAtomic, int iVal); -+int OMAPLFBAtomicIntRead(OMAPLFB_ATOMIC_INT *psAtomic); -+void OMAPLFBAtomicIntInc(OMAPLFB_ATOMIC_INT *psAtomic); -+ -+#if defined(DEBUG) -+void OMAPLFBPrintInfo(OMAPLFB_DEVINFO *psDevInfo); -+#else -+#define OMAPLFBPrintInfo(psDevInfo) -+#endif -+ -+#endif /* __OMAPLFB_H__ */ -+ -+/****************************************************************************** -+ End of file (omaplfb.h) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_omapfb3_linux/omaplfb_displayclass.c b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_omapfb3_linux/omaplfb_displayclass.c -new file mode 100644 -index 0000000..c3820ff ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_omapfb3_linux/omaplfb_displayclass.c -@@ -0,0 +1,1878 @@ -+/*************************************************************************/ /*! -+@Title OMAP common display driver components -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+/************************************************************************** -+ The 3rd party driver is a specification of an API to integrate the IMG POWERVR -+ Services driver with 3rd Party display hardware. It is NOT a specification for -+ a display controller driver, rather a specification to extend the API for a -+ pre-existing driver for the display hardware. -+ -+ The 3rd party driver interface provides IMG POWERVR client drivers (e.g. PVR2D) -+ with an API abstraction of the system's underlying display hardware, allowing -+ the client drivers to indirectly control the display hardware and access its -+ associated memory. -+ -+ Functions of the API include -+ - query primary surface attributes (width, height, stride, pixel format, CPU -+ physical and virtual address) -+ - swap/flip chain creation and subsequent query of surface attributes -+ - asynchronous display surface flipping, taking account of asynchronous read -+ (flip) and write (render) operations to the display surface -+ -+ Note: having queried surface attributes the client drivers are able to map the -+ display memory to any IMG POWERVR Services device by calling -+ PVRSRVMapDeviceClassMemory with the display surface handle. -+ -+ This code is intended to be an example of how a pre-existing display driver may -+ be extended to support the 3rd Party Display interface to POWERVR Services -+ - IMG is not providing a display driver implementation. -+ **************************************************************************/ -+ -+/* -+ * OMAP Linux 3rd party display driver. -+ * This is based on the Generic PVR Linux Framebuffer 3rd party display -+ * driver, with OMAP specific extensions to support flipping. -+ */ -+ -+#include <linux/version.h> -+#include <linux/kernel.h> -+#include <linux/console.h> -+#include <linux/fb.h> -+#include <linux/module.h> -+#include <linux/string.h> -+#include <linux/notifier.h> -+ -+/* IMG services headers */ -+#include "img_defs.h" -+#include "servicesext.h" -+#include "kerneldisplay.h" -+#include "omaplfb.h" -+ -+#if defined(CONFIG_DSSCOMP) -+#if defined(CONFIG_ION_OMAP) -+extern struct ion_device *omap_ion_device; -+#else /* defined(CONFIG_ION_OMAP) */ -+#error CONFIG_DSSCOMP support requires CONFIG_ION_OMAP -+#endif /* defined(CONFIG_ION_OMAP) */ -+#if defined(CONFIG_DRM_OMAP_DMM_TILER) -+#include <../drivers/staging/omapdrm/omap_dmm_tiler.h> -+#include <../drivers/video/omap2/dsscomp/tiler-utils.h> -+#elif defined(CONFIG_TI_TILER) -+#include <mach/tiler.h> -+#else /* defined(CONFIG_DRM_OMAP_DMM_TILER) */ -+#error CONFIG_DSSCOMP support requires either \ -+ CONFIG_DRM_OMAP_DMM_TILER or CONFIG_TI_TILER -+#endif /* defined(CONFIG_DRM_OMAP_DMM_TILER) */ -+#include <video/dsscomp.h> -+#include <plat/dsscomp.h> -+#endif /* defined(CONFIG_DSSCOMP) */ -+ -+#define OMAPLFB_COMMAND_COUNT 1 -+ -+#define OMAPLFB_VSYNC_SETTLE_COUNT 5 -+ -+//#define OMAPLFB_MAX_NUM_DEVICES FB_MAX -+#define OMAPLFB_MAX_NUM_DEVICES 1 -+#if (OMAPLFB_MAX_NUM_DEVICES > FB_MAX) -+#error "OMAPLFB_MAX_NUM_DEVICES must not be greater than FB_MAX" -+#endif -+ -+static OMAPLFB_DEVINFO *gapsDevInfo[OMAPLFB_MAX_NUM_DEVICES]; -+ -+/* Top level 'hook ptr' */ -+static PFN_DC_GET_PVRJTABLE gpfnGetPVRJTable = NULL; -+ -+#if !defined(CONFIG_DSSCOMP) -+/* Round x up to a multiple of y */ -+static inline unsigned long RoundUpToMultiple(unsigned long x, unsigned long y) -+{ -+ unsigned long div = x / y; -+ unsigned long rem = x % y; -+ -+ return (div + ((rem == 0) ? 0 : 1)) * y; -+} -+ -+/* Greatest common divisor of x and y */ -+static unsigned long GCD(unsigned long x, unsigned long y) -+{ -+ while (y != 0) -+ { -+ unsigned long r = x % y; -+ x = y; -+ y = r; -+ } -+ -+ return x; -+} -+ -+/* Least common multiple of x and y */ -+static unsigned long LCM(unsigned long x, unsigned long y) -+{ -+ unsigned long gcd = GCD(x, y); -+ -+ return (gcd == 0) ? 0 : ((x / gcd) * y); -+} -+#endif -+ -+unsigned OMAPLFBMaxFBDevIDPlusOne(void) -+{ -+ return OMAPLFB_MAX_NUM_DEVICES; -+} -+ -+/* Returns DevInfo pointer for a given device */ -+OMAPLFB_DEVINFO *OMAPLFBGetDevInfoPtr(unsigned uiFBDevID) -+{ -+ WARN_ON(uiFBDevID >= OMAPLFBMaxFBDevIDPlusOne()); -+ -+ if (uiFBDevID >= OMAPLFB_MAX_NUM_DEVICES) -+ { -+ return NULL; -+ } -+ -+ return gapsDevInfo[uiFBDevID]; -+} -+ -+/* Sets the DevInfo pointer for a given device */ -+static inline void OMAPLFBSetDevInfoPtr(unsigned uiFBDevID, OMAPLFB_DEVINFO *psDevInfo) -+{ -+ WARN_ON(uiFBDevID >= OMAPLFB_MAX_NUM_DEVICES); -+ -+ if (uiFBDevID < OMAPLFB_MAX_NUM_DEVICES) -+ { -+ gapsDevInfo[uiFBDevID] = psDevInfo; -+ } -+} -+ -+static inline OMAPLFB_BOOL SwapChainHasChanged(OMAPLFB_DEVINFO *psDevInfo, OMAPLFB_SWAPCHAIN *psSwapChain) -+{ -+ return (psDevInfo->psSwapChain != psSwapChain) || -+ (psDevInfo->uiSwapChainID != psSwapChain->uiSwapChainID); -+} -+ -+/* Don't wait for vertical sync */ -+static inline OMAPLFB_BOOL DontWaitForVSync(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ OMAPLFB_BOOL bDontWait; -+ -+ bDontWait = OMAPLFBAtomicBoolRead(&psDevInfo->sBlanked) || -+ OMAPLFBAtomicBoolRead(&psDevInfo->sFlushCommands); -+ -+#if defined(CONFIG_HAS_EARLYSUSPEND) -+ bDontWait = bDontWait || OMAPLFBAtomicBoolRead(&psDevInfo->sEarlySuspendFlag); -+#endif -+#if defined(SUPPORT_DRI_DRM) -+ bDontWait = bDontWait || OMAPLFBAtomicBoolRead(&psDevInfo->sLeaveVT); -+#endif -+ return bDontWait; -+} -+ -+/* -+ * SetDCState -+ * Called from services. -+ */ -+static IMG_VOID SetDCState(IMG_HANDLE hDevice, IMG_UINT32 ui32State) -+{ -+ OMAPLFB_DEVINFO *psDevInfo = (OMAPLFB_DEVINFO *)hDevice; -+ -+ switch (ui32State) -+ { -+ case DC_STATE_FLUSH_COMMANDS: -+ OMAPLFBAtomicBoolSet(&psDevInfo->sFlushCommands, OMAPLFB_TRUE); -+ break; -+ case DC_STATE_NO_FLUSH_COMMANDS: -+ OMAPLFBAtomicBoolSet(&psDevInfo->sFlushCommands, OMAPLFB_FALSE); -+ break; -+ case DC_STATE_FORCE_SWAP_TO_SYSTEM: -+ OMAPLFBFlip(psDevInfo, &psDevInfo->sSystemBuffer); -+ break; -+ default: -+ break; -+ } -+} -+ -+/* -+ * OpenDCDevice -+ * Called from services. -+ */ -+static PVRSRV_ERROR OpenDCDevice(IMG_UINT32 uiPVRDevID, -+ IMG_HANDLE *phDevice, -+ PVRSRV_SYNC_DATA* psSystemBufferSyncData) -+{ -+ OMAPLFB_DEVINFO *psDevInfo; -+ OMAPLFB_ERROR eError; -+ unsigned uiMaxFBDevIDPlusOne; -+ unsigned i; -+ -+ if (!try_module_get(THIS_MODULE)) -+ { -+ return PVRSRV_ERROR_UNABLE_TO_OPEN_DC_DEVICE; -+ } -+ -+ uiMaxFBDevIDPlusOne = OMAPLFBMaxFBDevIDPlusOne(); -+ -+ for (i = 0; i < uiMaxFBDevIDPlusOne; i++) -+ { -+ psDevInfo = OMAPLFBGetDevInfoPtr(i); -+ if (psDevInfo != NULL && psDevInfo->uiPVRDevID == uiPVRDevID) -+ { -+ break; -+ } -+ } -+ if (i == uiMaxFBDevIDPlusOne) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX -+ ": %s: PVR Device %u not found\n", __FUNCTION__, uiPVRDevID)); -+ eError = PVRSRV_ERROR_INVALID_DEVICE; -+ goto ErrorModulePut; -+ } -+ -+ /* store the system surface sync data */ -+ psDevInfo->sSystemBuffer.psSyncData = psSystemBufferSyncData; -+ -+ eError = OMAPLFBUnblankDisplay(psDevInfo); -+ if (eError != OMAPLFB_OK) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX -+ ": %s: Device %u: OMAPLFBUnblankDisplay failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, eError)); -+ eError = PVRSRV_ERROR_UNBLANK_DISPLAY_FAILED; -+ goto ErrorModulePut; -+ } -+ -+ /* return handle to the devinfo */ -+ *phDevice = (IMG_HANDLE)psDevInfo; -+ -+ return PVRSRV_OK; -+ -+ErrorModulePut: -+ module_put(THIS_MODULE); -+ -+ return eError; -+} -+ -+/* -+ * CloseDCDevice -+ * Called from services. -+ */ -+static PVRSRV_ERROR CloseDCDevice(IMG_HANDLE hDevice) -+{ -+#if defined(SUPPORT_DRI_DRM) -+ OMAPLFB_DEVINFO *psDevInfo = (OMAPLFB_DEVINFO *)hDevice; -+ -+ OMAPLFBAtomicBoolSet(&psDevInfo->sLeaveVT, OMAPLFB_FALSE); -+ (void) OMAPLFBUnblankDisplay(psDevInfo); -+#else -+ UNREFERENCED_PARAMETER(hDevice); -+#endif -+ module_put(THIS_MODULE); -+ -+ return PVRSRV_OK; -+} -+ -+/* -+ * EnumDCFormats -+ * Called from services. -+ */ -+static PVRSRV_ERROR EnumDCFormats(IMG_HANDLE hDevice, -+ IMG_UINT32 *pui32NumFormats, -+ DISPLAY_FORMAT *psFormat) -+{ -+ OMAPLFB_DEVINFO *psDevInfo; -+ -+ if(!hDevice || !pui32NumFormats) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psDevInfo = (OMAPLFB_DEVINFO*)hDevice; -+ -+ *pui32NumFormats = 1; -+ -+ if(psFormat) -+ { -+ psFormat[0] = psDevInfo->sDisplayFormat; -+ } -+ -+ return PVRSRV_OK; -+} -+ -+/* -+ * EnumDCDims -+ * Called from services. -+ */ -+static PVRSRV_ERROR EnumDCDims(IMG_HANDLE hDevice, -+ DISPLAY_FORMAT *psFormat, -+ IMG_UINT32 *pui32NumDims, -+ DISPLAY_DIMS *psDim) -+{ -+ OMAPLFB_DEVINFO *psDevInfo; -+ -+ if(!hDevice || !psFormat || !pui32NumDims) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psDevInfo = (OMAPLFB_DEVINFO*)hDevice; -+ -+ *pui32NumDims = 1; -+ -+ /* No need to look at psFormat; there is only one */ -+ if(psDim) -+ { -+ psDim[0] = psDevInfo->sDisplayDim; -+ } -+ -+ return PVRSRV_OK; -+} -+ -+ -+/* -+ * GetDCSystemBuffer -+ * Called from services. -+ */ -+static PVRSRV_ERROR GetDCSystemBuffer(IMG_HANDLE hDevice, IMG_HANDLE *phBuffer) -+{ -+ OMAPLFB_DEVINFO *psDevInfo; -+ -+ if(!hDevice || !phBuffer) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psDevInfo = (OMAPLFB_DEVINFO*)hDevice; -+ -+ *phBuffer = (IMG_HANDLE)&psDevInfo->sSystemBuffer; -+ -+ return PVRSRV_OK; -+} -+ -+ -+/* -+ * GetDCInfo -+ * Called from services. -+ */ -+static PVRSRV_ERROR GetDCInfo(IMG_HANDLE hDevice, DISPLAY_INFO *psDCInfo) -+{ -+ OMAPLFB_DEVINFO *psDevInfo; -+ -+ if(!hDevice || !psDCInfo) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psDevInfo = (OMAPLFB_DEVINFO*)hDevice; -+ -+ *psDCInfo = psDevInfo->sDisplayInfo; -+ -+ return PVRSRV_OK; -+} -+ -+/* -+ * GetDCBufferAddr -+ * Called from services. -+ */ -+static PVRSRV_ERROR GetDCBufferAddr(IMG_HANDLE hDevice, -+ IMG_HANDLE hBuffer, -+ IMG_SYS_PHYADDR **ppsSysAddr, -+ IMG_UINT32 *pui32ByteSize, -+ IMG_VOID **ppvCpuVAddr, -+ IMG_HANDLE *phOSMapInfo, -+ IMG_BOOL *pbIsContiguous, -+ IMG_UINT32 *pui32TilingStride) -+{ -+ OMAPLFB_DEVINFO *psDevInfo; -+ OMAPLFB_BUFFER *psSystemBuffer; -+ -+ UNREFERENCED_PARAMETER(pui32TilingStride); -+ -+ if(!hDevice) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ if(!hBuffer) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ if (!ppsSysAddr) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ if (!pui32ByteSize) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psDevInfo = (OMAPLFB_DEVINFO*)hDevice; -+ -+ psSystemBuffer = (OMAPLFB_BUFFER *)hBuffer; -+ -+ *ppsSysAddr = &psSystemBuffer->sSysAddr; -+ -+ *pui32ByteSize = (IMG_UINT32)psDevInfo->sFBInfo.ulBufferSize; -+ -+ if (ppvCpuVAddr) -+ { -+#if defined(CONFIG_DSSCOMP) -+ *ppvCpuVAddr = psDevInfo->sFBInfo.bIs2D ? NULL : psSystemBuffer->sCPUVAddr; -+#else -+ *ppvCpuVAddr = psSystemBuffer->sCPUVAddr; -+#endif -+ } -+ -+ if (phOSMapInfo) -+ { -+ *phOSMapInfo = (IMG_HANDLE)0; -+ } -+ -+ if (pbIsContiguous) -+ { -+#if defined(CONFIG_DSSCOMP) -+ *pbIsContiguous = !psDevInfo->sFBInfo.bIs2D; -+#else -+ *pbIsContiguous = IMG_TRUE; -+#endif -+ } -+ -+#if defined(CONFIG_DSSCOMP) -+ if (psDevInfo->sFBInfo.bIs2D) -+ { -+ int i = (psSystemBuffer->sSysAddr.uiAddr - psDevInfo->sFBInfo.psPageList->uiAddr) >> PAGE_SHIFT; -+ *ppsSysAddr = psDevInfo->sFBInfo.psPageList + psDevInfo->sFBInfo.ulHeight * i; -+ } -+#endif -+ -+ return PVRSRV_OK; -+} -+ -+/* -+ * CreateDCSwapChain -+ * Called from services. -+ */ -+static PVRSRV_ERROR CreateDCSwapChain(IMG_HANDLE hDevice, -+ IMG_UINT32 ui32Flags, -+ DISPLAY_SURF_ATTRIBUTES *psDstSurfAttrib, -+ DISPLAY_SURF_ATTRIBUTES *psSrcSurfAttrib, -+ IMG_UINT32 ui32BufferCount, -+ PVRSRV_SYNC_DATA **ppsSyncData, -+ IMG_UINT32 ui32OEMFlags, -+ IMG_HANDLE *phSwapChain, -+ IMG_UINT32 *pui32SwapChainID) -+{ -+ OMAPLFB_SWAPCHAIN *psSwapChain; -+ OMAPLFB_DEVINFO *psDevInfo; -+ PVRSRV_ERROR eError; -+ IMG_UINT32 i; -+ -+ UNREFERENCED_PARAMETER(ui32OEMFlags); -+ UNREFERENCED_PARAMETER(ui32Flags); -+ -+ /* Check parameters */ -+ if(!hDevice -+ || !psDstSurfAttrib -+ || !psSrcSurfAttrib -+ || !ppsSyncData -+ || !phSwapChain) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psDevInfo = (OMAPLFB_DEVINFO*)hDevice; -+ -+ /* Do we support swap chains? */ -+ if (psDevInfo->sDisplayInfo.ui32MaxSwapChains == 0) -+ { -+ return PVRSRV_ERROR_NOT_SUPPORTED; -+ } -+ -+ OMAPLFBCreateSwapChainLock(psDevInfo); -+ -+ /* The driver only supports a single swapchain */ -+ if(psDevInfo->psSwapChain != NULL) -+ { -+ eError = PVRSRV_ERROR_FLIP_CHAIN_EXISTS; -+ goto ExitUnLock; -+ } -+ -+ /* create a swapchain structure */ -+ psSwapChain = (OMAPLFB_SWAPCHAIN*)OMAPLFBAllocKernelMem(sizeof(OMAPLFB_SWAPCHAIN)); -+ if(!psSwapChain) -+ { -+ eError = PVRSRV_ERROR_OUT_OF_MEMORY; -+ goto ExitUnLock; -+ } -+ -+ /* If services asks for a 0-length swap chain, it's probably Android. -+ * -+ * This will use only non-display memory posting via PVRSRVSwapToDCBuffers2(), -+ * and we can skip some useless sanity checking. -+ */ -+ if(ui32BufferCount > 0) -+ { -+ IMG_UINT32 ui32BuffersToSkip; -+ -+ /* Check the buffer count */ -+ if(ui32BufferCount > psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers) -+ { -+ eError = PVRSRV_ERROR_TOOMANYBUFFERS; -+ goto ErrorFreeSwapChain; -+ } -+ -+ if ((psDevInfo->sFBInfo.ulRoundedBufferSize * (unsigned long)ui32BufferCount) > psDevInfo->sFBInfo.ulFBSize) -+ { -+ eError = PVRSRV_ERROR_TOOMANYBUFFERS; -+ goto ErrorFreeSwapChain; -+ } -+ -+ /* -+ * We will allocate the swap chain buffers at the back of the frame -+ * buffer area. This preserves the front portion, which may be being -+ * used by other Linux Framebuffer based applications. -+ */ -+ ui32BuffersToSkip = psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers - ui32BufferCount; -+ -+ /* -+ * Verify the DST/SRC attributes, -+ * SRC/DST must match the current display mode config -+ */ -+ if(psDstSurfAttrib->pixelformat != psDevInfo->sDisplayFormat.pixelformat -+ || psDstSurfAttrib->sDims.ui32ByteStride != psDevInfo->sDisplayDim.ui32ByteStride -+ || psDstSurfAttrib->sDims.ui32Width != psDevInfo->sDisplayDim.ui32Width -+ || psDstSurfAttrib->sDims.ui32Height != psDevInfo->sDisplayDim.ui32Height) -+ { -+ /* DST doesn't match the current mode */ -+ eError = PVRSRV_ERROR_INVALID_PARAMS; -+ goto ErrorFreeSwapChain; -+ } -+ -+ if(psDstSurfAttrib->pixelformat != psSrcSurfAttrib->pixelformat -+ || psDstSurfAttrib->sDims.ui32ByteStride != psSrcSurfAttrib->sDims.ui32ByteStride -+ || psDstSurfAttrib->sDims.ui32Width != psSrcSurfAttrib->sDims.ui32Width -+ || psDstSurfAttrib->sDims.ui32Height != psSrcSurfAttrib->sDims.ui32Height) -+ { -+ /* DST doesn't match the SRC */ -+ eError = PVRSRV_ERROR_INVALID_PARAMS; -+ goto ErrorFreeSwapChain; -+ } -+ -+ psSwapChain->psBuffer = (OMAPLFB_BUFFER*)OMAPLFBAllocKernelMem(sizeof(OMAPLFB_BUFFER) * ui32BufferCount); -+ if(!psSwapChain->psBuffer) -+ { -+ eError = PVRSRV_ERROR_OUT_OF_MEMORY; -+ goto ErrorFreeSwapChain; -+ } -+ -+ /* Link the buffers */ -+ for(i = 0; i < ui32BufferCount - 1; i++) -+ { -+ psSwapChain->psBuffer[i].psNext = &psSwapChain->psBuffer[i + 1]; -+ } -+ -+ /* and link last to first */ -+ psSwapChain->psBuffer[i].psNext = &psSwapChain->psBuffer[0]; -+ -+ /* Configure the swapchain buffers */ -+ for(i = 0; i < ui32BufferCount; i++) -+ { -+ IMG_UINT32 ui32SwapBuffer = i + ui32BuffersToSkip; -+ IMG_UINT32 ui32BufferOffset = ui32SwapBuffer * (IMG_UINT32)psDevInfo->sFBInfo.ulRoundedBufferSize; -+ -+#if defined(CONFIG_DSSCOMP) -+ if (psDevInfo->sFBInfo.bIs2D) -+ { -+ ui32BufferOffset = 0; -+ } -+#endif /* defined(CONFIG_DSSCOMP) */ -+ -+ psSwapChain->psBuffer[i].psSyncData = ppsSyncData[i]; -+ -+ psSwapChain->psBuffer[i].sSysAddr.uiAddr = psDevInfo->sFBInfo.sSysAddr.uiAddr + ui32BufferOffset; -+ psSwapChain->psBuffer[i].sCPUVAddr = psDevInfo->sFBInfo.sCPUVAddr + ui32BufferOffset; -+ psSwapChain->psBuffer[i].ulYOffset = ui32BufferOffset / psDevInfo->sFBInfo.ulByteStride; -+ psSwapChain->psBuffer[i].psDevInfo = psDevInfo; -+ -+#if defined(CONFIG_DSSCOMP) -+ if (psDevInfo->sFBInfo.bIs2D) -+ { -+ psSwapChain->psBuffer[i].sSysAddr.uiAddr += ui32SwapBuffer * -+ ALIGN((IMG_UINT32)psDevInfo->sFBInfo.ulWidth * psDevInfo->sFBInfo.uiBytesPerPixel, PAGE_SIZE); -+ } -+#endif /* defined(CONFIG_DSSCOMP) */ -+ -+ OMAPLFBInitBufferForSwap(&psSwapChain->psBuffer[i]); -+ } -+ } -+ else -+ { -+ psSwapChain->psBuffer = NULL; -+ } -+ -+#if defined(PVR_OMAPFB3_UPDATE_MODE) -+ if (!OMAPLFBSetUpdateMode(psDevInfo, PVR_OMAPFB3_UPDATE_MODE)) -+ { -+ printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Couldn't set frame buffer update mode %d\n", __FUNCTION__, psDevInfo->uiFBDevID, PVR_OMAPFB3_UPDATE_MODE); -+ } -+#endif /* defined(PVR_OMAPFB3_UPDATE_MODE) */ -+ -+ psSwapChain->ulBufferCount = (unsigned long)ui32BufferCount; -+ psSwapChain->bNotVSynced = OMAPLFB_TRUE; -+ psSwapChain->uiFBDevID = psDevInfo->uiFBDevID; -+ -+ if (OMAPLFBCreateSwapQueue(psSwapChain) != OMAPLFB_OK) -+ { -+ printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Failed to create workqueue\n", __FUNCTION__, psDevInfo->uiFBDevID); -+ eError = PVRSRV_ERROR_UNABLE_TO_INSTALL_ISR; -+ goto ErrorFreeBuffers; -+ } -+ -+ if (OMAPLFBEnableLFBEventNotification(psDevInfo)!= OMAPLFB_OK) -+ { -+ eError = PVRSRV_ERROR_UNABLE_TO_ENABLE_EVENT; -+ printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Couldn't enable framebuffer event notification\n", __FUNCTION__, psDevInfo->uiFBDevID); -+ goto ErrorDestroySwapQueue; -+ } -+ -+ psDevInfo->uiSwapChainID++; -+ if (psDevInfo->uiSwapChainID == 0) -+ { -+ psDevInfo->uiSwapChainID++; -+ } -+ -+ psSwapChain->uiSwapChainID = psDevInfo->uiSwapChainID; -+ -+ psDevInfo->psSwapChain = psSwapChain; -+ -+ *pui32SwapChainID = psDevInfo->uiSwapChainID; -+ -+ *phSwapChain = (IMG_HANDLE)psSwapChain; -+ -+ eError = PVRSRV_OK; -+ goto ExitUnLock; -+ -+ErrorDestroySwapQueue: -+ OMAPLFBDestroySwapQueue(psSwapChain); -+ErrorFreeBuffers: -+ if(psSwapChain->psBuffer) -+ { -+ OMAPLFBFreeKernelMem(psSwapChain->psBuffer); -+ } -+ErrorFreeSwapChain: -+ OMAPLFBFreeKernelMem(psSwapChain); -+ExitUnLock: -+ OMAPLFBCreateSwapChainUnLock(psDevInfo); -+ return eError; -+} -+ -+/* -+ * DestroyDCSwapChain -+ * Called from services. -+ */ -+static PVRSRV_ERROR DestroyDCSwapChain(IMG_HANDLE hDevice, -+ IMG_HANDLE hSwapChain) -+{ -+ OMAPLFB_DEVINFO *psDevInfo; -+ OMAPLFB_SWAPCHAIN *psSwapChain; -+ OMAPLFB_ERROR eError; -+ -+ /* Check parameters */ -+ if(!hDevice || !hSwapChain) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psDevInfo = (OMAPLFB_DEVINFO*)hDevice; -+ psSwapChain = (OMAPLFB_SWAPCHAIN*)hSwapChain; -+ -+ OMAPLFBCreateSwapChainLock(psDevInfo); -+ -+ if (SwapChainHasChanged(psDevInfo, psSwapChain)) -+ { -+ printk(KERN_WARNING DRIVER_PREFIX -+ ": %s: Device %u: Swap chain mismatch\n", __FUNCTION__, psDevInfo->uiFBDevID); -+ -+ eError = PVRSRV_ERROR_INVALID_PARAMS; -+ goto ExitUnLock; -+ } -+ -+ /* The swap queue is flushed before being destroyed */ -+ OMAPLFBDestroySwapQueue(psSwapChain); -+ -+ eError = OMAPLFBDisableLFBEventNotification(psDevInfo); -+ if (eError != OMAPLFB_OK) -+ { -+ printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Couldn't disable framebuffer event notification\n", __FUNCTION__, psDevInfo->uiFBDevID); -+ } -+ -+ /* Free resources */ -+ if (psSwapChain->psBuffer) -+ { -+ OMAPLFBFreeKernelMem(psSwapChain->psBuffer); -+ } -+ OMAPLFBFreeKernelMem(psSwapChain); -+ -+ psDevInfo->psSwapChain = NULL; -+ -+ OMAPLFBFlip(psDevInfo, &psDevInfo->sSystemBuffer); -+ (void) OMAPLFBCheckModeAndSync(psDevInfo); -+ -+ eError = PVRSRV_OK; -+ -+ExitUnLock: -+ OMAPLFBCreateSwapChainUnLock(psDevInfo); -+ -+ return eError; -+} -+ -+/* -+ * SetDCDstRect -+ * Called from services. -+ */ -+static PVRSRV_ERROR SetDCDstRect(IMG_HANDLE hDevice, -+ IMG_HANDLE hSwapChain, -+ IMG_RECT *psRect) -+{ -+ UNREFERENCED_PARAMETER(hDevice); -+ UNREFERENCED_PARAMETER(hSwapChain); -+ UNREFERENCED_PARAMETER(psRect); -+ -+ /* Only full display swapchains on this device */ -+ -+ return PVRSRV_ERROR_NOT_SUPPORTED; -+} -+ -+/* -+ * SetDCSrcRect -+ * Called from services. -+ */ -+static PVRSRV_ERROR SetDCSrcRect(IMG_HANDLE hDevice, -+ IMG_HANDLE hSwapChain, -+ IMG_RECT *psRect) -+{ -+ UNREFERENCED_PARAMETER(hDevice); -+ UNREFERENCED_PARAMETER(hSwapChain); -+ UNREFERENCED_PARAMETER(psRect); -+ -+ /* Only full display swapchains on this device */ -+ -+ return PVRSRV_ERROR_NOT_SUPPORTED; -+} -+ -+/* -+ * SetDCDstColourKey -+ * Called from services. -+ */ -+static PVRSRV_ERROR SetDCDstColourKey(IMG_HANDLE hDevice, -+ IMG_HANDLE hSwapChain, -+ IMG_UINT32 ui32CKColour) -+{ -+ UNREFERENCED_PARAMETER(hDevice); -+ UNREFERENCED_PARAMETER(hSwapChain); -+ UNREFERENCED_PARAMETER(ui32CKColour); -+ -+ /* Don't support DST CK on this device */ -+ -+ return PVRSRV_ERROR_NOT_SUPPORTED; -+} -+ -+/* -+ * SetDCSrcColourKey -+ * Called from services. -+ */ -+static PVRSRV_ERROR SetDCSrcColourKey(IMG_HANDLE hDevice, -+ IMG_HANDLE hSwapChain, -+ IMG_UINT32 ui32CKColour) -+{ -+ UNREFERENCED_PARAMETER(hDevice); -+ UNREFERENCED_PARAMETER(hSwapChain); -+ UNREFERENCED_PARAMETER(ui32CKColour); -+ -+ /* Don't support SRC CK on this device */ -+ -+ return PVRSRV_ERROR_NOT_SUPPORTED; -+} -+ -+/* -+ * GetDCBuffers -+ * Called from services. -+ */ -+static PVRSRV_ERROR GetDCBuffers(IMG_HANDLE hDevice, -+ IMG_HANDLE hSwapChain, -+ IMG_UINT32 *pui32BufferCount, -+ IMG_HANDLE *phBuffer) -+{ -+ OMAPLFB_DEVINFO *psDevInfo; -+ OMAPLFB_SWAPCHAIN *psSwapChain; -+ PVRSRV_ERROR eError; -+ unsigned i; -+ -+ /* Check parameters */ -+ if(!hDevice -+ || !hSwapChain -+ || !pui32BufferCount -+ || !phBuffer) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psDevInfo = (OMAPLFB_DEVINFO*)hDevice; -+ psSwapChain = (OMAPLFB_SWAPCHAIN*)hSwapChain; -+ -+ OMAPLFBCreateSwapChainLock(psDevInfo); -+ -+ if (SwapChainHasChanged(psDevInfo, psSwapChain)) -+ { -+ printk(KERN_WARNING DRIVER_PREFIX -+ ": %s: Device %u: Swap chain mismatch\n", __FUNCTION__, psDevInfo->uiFBDevID); -+ -+ eError = PVRSRV_ERROR_INVALID_PARAMS; -+ goto Exit; -+ } -+ -+ /* Return the buffer count */ -+ *pui32BufferCount = (IMG_UINT32)psSwapChain->ulBufferCount; -+ -+ /* Return the buffers */ -+ for(i=0; i<psSwapChain->ulBufferCount; i++) -+ { -+ phBuffer[i] = (IMG_HANDLE)&psSwapChain->psBuffer[i]; -+ } -+ -+ eError = PVRSRV_OK; -+ -+Exit: -+ OMAPLFBCreateSwapChainUnLock(psDevInfo); -+ -+ return eError; -+} -+ -+/* -+ * SwapToDCBuffer -+ * Called from services. -+ */ -+static PVRSRV_ERROR SwapToDCBuffer(IMG_HANDLE hDevice, -+ IMG_HANDLE hBuffer, -+ IMG_UINT32 ui32SwapInterval, -+ IMG_HANDLE hPrivateTag, -+ IMG_UINT32 ui32ClipRectCount, -+ IMG_RECT *psClipRect) -+{ -+ UNREFERENCED_PARAMETER(hDevice); -+ UNREFERENCED_PARAMETER(hBuffer); -+ UNREFERENCED_PARAMETER(ui32SwapInterval); -+ UNREFERENCED_PARAMETER(hPrivateTag); -+ UNREFERENCED_PARAMETER(ui32ClipRectCount); -+ UNREFERENCED_PARAMETER(psClipRect); -+ -+ /* * Nothing to do since Services common code does the work */ -+ -+ return PVRSRV_OK; -+} -+ -+/* -+ * Called after the screen has unblanked, or after any other occasion -+ * when we didn't wait for vsync, but now need to. Not doing this after -+ * unblank leads to screen jitter on some screens. -+ * Returns true if the screen has been deemed to have settled. -+ */ -+static OMAPLFB_BOOL WaitForVSyncSettle(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ unsigned i; -+ for(i = 0; i < OMAPLFB_VSYNC_SETTLE_COUNT; i++) -+ { -+ if (DontWaitForVSync(psDevInfo) || !OMAPLFBWaitForVSync(psDevInfo)) -+ { -+ return OMAPLFB_FALSE; -+ } -+ } -+ -+ return OMAPLFB_TRUE; -+} -+ -+/* -+ * Swap handler. -+ * Called from the swap chain work queue handler. -+ * There is no need to take the swap chain creation lock in here, or use -+ * some other method of stopping the swap chain from being destroyed. -+ * This is because the swap chain creation lock is taken when queueing work, -+ * and the work queue is flushed before the swap chain is destroyed. -+ */ -+void OMAPLFBSwapHandler(OMAPLFB_BUFFER *psBuffer) -+{ -+ OMAPLFB_DEVINFO *psDevInfo = psBuffer->psDevInfo; -+ OMAPLFB_SWAPCHAIN *psSwapChain = psDevInfo->psSwapChain; -+ OMAPLFB_BOOL bPreviouslyNotVSynced; -+ -+#if defined(SUPPORT_DRI_DRM) -+ if (!OMAPLFBAtomicBoolRead(&psDevInfo->sLeaveVT)) -+#endif -+ { -+ OMAPLFBFlip(psDevInfo, psBuffer); -+ } -+ -+ bPreviouslyNotVSynced = psSwapChain->bNotVSynced; -+ psSwapChain->bNotVSynced = OMAPLFB_TRUE; -+ -+ -+ if (!DontWaitForVSync(psDevInfo)) -+ { -+ OMAPLFB_UPDATE_MODE eMode = OMAPLFBGetUpdateMode(psDevInfo); -+ int iBlankEvents = OMAPLFBAtomicIntRead(&psDevInfo->sBlankEvents); -+ -+ switch(eMode) -+ { -+ case OMAPLFB_UPDATE_MODE_AUTO: -+ psSwapChain->bNotVSynced = OMAPLFB_FALSE; -+ -+ if (bPreviouslyNotVSynced || psSwapChain->iBlankEvents != iBlankEvents) -+ { -+ psSwapChain->iBlankEvents = iBlankEvents; -+ psSwapChain->bNotVSynced = !WaitForVSyncSettle(psDevInfo); -+ } else if (psBuffer->ulSwapInterval != 0) -+ { -+ psSwapChain->bNotVSynced = !OMAPLFBWaitForVSync(psDevInfo); -+ } -+ break; -+#if defined(PVR_OMAPFB3_MANUAL_UPDATE_SYNC_IN_SWAP) -+ case OMAPLFB_UPDATE_MODE_MANUAL: -+ if (psBuffer->ulSwapInterval != 0) -+ { -+ (void) OMAPLFBManualSync(psDevInfo); -+ } -+ break; -+#endif -+ default: -+ break; -+ } -+ } -+ -+ psDevInfo->sPVRJTable.pfnPVRSRVCmdComplete((IMG_HANDLE)psBuffer->hCmdComplete, IMG_TRUE); -+} -+ -+/* Triggered by PVRSRVSwapToDCBuffer */ -+static IMG_BOOL ProcessFlipV1(IMG_HANDLE hCmdCookie, -+ OMAPLFB_DEVINFO *psDevInfo, -+ OMAPLFB_SWAPCHAIN *psSwapChain, -+ OMAPLFB_BUFFER *psBuffer, -+ unsigned long ulSwapInterval) -+{ -+ OMAPLFBCreateSwapChainLock(psDevInfo); -+ -+ /* The swap chain has been destroyed */ -+ if (SwapChainHasChanged(psDevInfo, psSwapChain)) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX -+ ": %s: Device %u (PVR Device ID %u): The swap chain has been destroyed\n", -+ __FUNCTION__, psDevInfo->uiFBDevID, psDevInfo->uiPVRDevID)); -+ } -+ else -+ { -+ psBuffer->hCmdComplete = (OMAPLFB_HANDLE)hCmdCookie; -+ psBuffer->ulSwapInterval = ulSwapInterval; -+#if defined(CONFIG_DSSCOMP) -+ if (is_tiler_addr(psBuffer->sSysAddr.uiAddr)) -+ { -+ int res; -+ IMG_UINT32 w = psBuffer->psDevInfo->sDisplayDim.ui32Width; -+ IMG_UINT32 h = psBuffer->psDevInfo->sDisplayDim.ui32Height; -+ struct dsscomp_setup_dispc_data comp = { -+ .num_mgrs = 1, -+ .mgrs[0].alpha_blending = 1, -+ .num_ovls = 1, -+ .ovls[0].cfg = -+ { -+ .width = w, -+ .win.w = w, -+ .crop.w = w, -+ .height = h, -+ .win.h = h, -+ .crop.h = h, -+ .stride = psBuffer->psDevInfo->sDisplayDim.ui32ByteStride, -+ .color_mode = OMAP_DSS_COLOR_ARGB32, -+ .enabled = 1, -+ .global_alpha = 255, -+ }, -+ .mode = DSSCOMP_SETUP_DISPLAY, -+ }; -+ struct tiler_pa_info *pas[1] = { NULL }; -+ comp.ovls[0].ba = (u32) psBuffer->sSysAddr.uiAddr; -+ res = dsscomp_gralloc_queue(&comp, pas, true, -+ (void *) psDevInfo->sPVRJTable.pfnPVRSRVCmdComplete, -+ (void *) psBuffer->hCmdComplete); -+ if (res != 0) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: dsscomp_gralloc_queue failed (Y Offset: %lu, Error: %d)\n", __FUNCTION__, psDevInfo->uiFBDevID, psBuffer->ulYOffset, res)); -+ } -+ } -+ else -+#endif /* defined(CONFIG_DSSCOMP) */ -+ { -+ OMAPLFBQueueBufferForSwap(psSwapChain, psBuffer); -+ } -+ } -+ -+ OMAPLFBCreateSwapChainUnLock(psDevInfo); -+ -+ return IMG_TRUE; -+} -+ -+#if defined(CONFIG_DSSCOMP) -+ -+/* Triggered by PVRSRVSwapToDCBuffer2 */ -+static IMG_BOOL ProcessFlipV2(IMG_HANDLE hCmdCookie, -+ OMAPLFB_DEVINFO *psDevInfo, -+ PDC_MEM_INFO *ppsMemInfos, -+ IMG_UINT32 ui32NumMemInfos, -+ struct dsscomp_setup_dispc_data *psDssData, -+ IMG_UINT32 ui32DssDataLength) -+{ -+ struct tiler_pa_info *apsTilerPAs[5]; -+ IMG_UINT32 i, k; -+ struct -+ { -+ IMG_UINTPTR_T uiAddr; -+ IMG_UINTPTR_T uiUVAddr; -+ struct tiler_pa_info *psTilerInfo; -+ } -+ asMemInfo[5] = {}; -+ int res; -+ -+ if(ui32DssDataLength != sizeof(*psDssData)) -+ { -+ WARN(1, "invalid size of private data (%d vs %d)", -+ ui32DssDataLength, sizeof(*psDssData)); -+ return IMG_FALSE; -+ } -+ -+ if(psDssData->num_ovls == 0 || ui32NumMemInfos == 0) -+ { -+ WARN(1, "must have at least one layer"); -+ return IMG_FALSE; -+ } -+ -+ for(i = k = 0; i < ui32NumMemInfos && k < ARRAY_SIZE(asMemInfo); i++, k++) -+ { -+ struct tiler_pa_info *psTilerInfo; -+ IMG_CPU_VIRTADDR virtAddr; -+ IMG_CPU_PHYADDR phyAddr; -+ IMG_UINT32 ui32NumPages; -+ IMG_SIZE_T uByteSize; -+ int j; -+ -+ psDevInfo->sPVRJTable.pfnPVRSRVDCMemInfoGetByteSize(ppsMemInfos[i], &uByteSize); -+ ui32NumPages = (uByteSize + PAGE_SIZE - 1) >> PAGE_SHIFT; -+ -+ psDevInfo->sPVRJTable.pfnPVRSRVDCMemInfoGetCpuPAddr(ppsMemInfos[i], 0, &phyAddr); -+ -+ /* TILER buffers do not need meminfos */ -+ if(is_tiler_addr((u32)phyAddr.uiAddr)) -+ { -+#ifdef CONFIG_DRM_OMAP_DMM_TILER -+ enum tiler_fmt fmt; -+#endif -+ asMemInfo[k].uiAddr = phyAddr.uiAddr; -+#ifdef CONFIG_DRM_OMAP_DMM_TILER -+ if(tiler_get_fmt((u32)phyAddr.uiAddr, &fmt) && fmt == TILFMT_8BIT) -+#else -+ if(tiler_fmt((u32)phyAddr.uiAddr) == TILFMT_8BIT) -+#endif -+ { -+ psDevInfo->sPVRJTable.pfnPVRSRVDCMemInfoGetCpuPAddr(ppsMemInfos[i], (uByteSize * 2) / 3, &phyAddr); -+ asMemInfo[k].uiUVAddr = phyAddr.uiAddr; -+ } -+ continue; -+ } -+ -+ /* normal gralloc layer */ -+ psTilerInfo = kzalloc(sizeof(*psTilerInfo), GFP_KERNEL); -+ if(!psTilerInfo) -+ { -+ continue; -+ } -+ -+ psTilerInfo->mem = kzalloc(sizeof(*psTilerInfo->mem) * ui32NumPages, GFP_KERNEL); -+ if(!psTilerInfo->mem) -+ { -+ kfree(psTilerInfo); -+ continue; -+ } -+ -+ psTilerInfo->num_pg = ui32NumPages; -+ psTilerInfo->memtype = TILER_MEM_USING; -+ for(j = 0; j < ui32NumPages; j++) -+ { -+ psDevInfo->sPVRJTable.pfnPVRSRVDCMemInfoGetCpuPAddr(ppsMemInfos[i], j << PAGE_SHIFT, &phyAddr); -+ psTilerInfo->mem[j] = (u32)phyAddr.uiAddr; -+ } -+ -+ /* need base address for in-page offset */ -+ psDevInfo->sPVRJTable.pfnPVRSRVDCMemInfoGetCpuVAddr(ppsMemInfos[i], &virtAddr); -+ asMemInfo[k].uiAddr = (IMG_UINTPTR_T) virtAddr; -+ asMemInfo[k].psTilerInfo = psTilerInfo; -+ } -+ -+ for(i = 0; i < psDssData->num_ovls; i++) -+ { -+ unsigned int ix; -+ apsTilerPAs[i] = NULL; -+ -+ /* only supporting Post2, cloned and fbmem layers */ -+ if (psDssData->ovls[i].addressing != OMAP_DSS_BUFADDR_LAYER_IX && -+ psDssData->ovls[i].addressing != OMAP_DSS_BUFADDR_OVL_IX && -+ psDssData->ovls[i].addressing != OMAP_DSS_BUFADDR_FB) -+ { -+ psDssData->ovls[i].cfg.enabled = false; -+ } -+ -+ if (psDssData->ovls[i].addressing != OMAP_DSS_BUFADDR_LAYER_IX) -+ { -+ continue; -+ } -+ -+ /* Post2 layers */ -+ ix = psDssData->ovls[i].ba; -+ if (ix >= k) -+ { -+ WARN(1, "Invalid Post2 layer (%u)", ix); -+ psDssData->ovls[i].cfg.enabled = false; -+ continue; -+ } -+ -+ psDssData->ovls[i].addressing = OMAP_DSS_BUFADDR_DIRECT; -+ psDssData->ovls[i].ba = (u32) asMemInfo[ix].uiAddr; -+ psDssData->ovls[i].uv = (u32) asMemInfo[ix].uiUVAddr; -+ apsTilerPAs[i] = asMemInfo[ix].psTilerInfo; -+ } -+ -+ res = dsscomp_gralloc_queue(psDssData, apsTilerPAs, false, -+ (void *)psDevInfo->sPVRJTable.pfnPVRSRVCmdComplete, -+ (void *)hCmdCookie); -+ if (res != 0) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: dsscomp_gralloc_queue failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, res)); -+ } -+ -+ for(i = 0; i < k; i++) -+ { -+ tiler_pa_free(apsTilerPAs[i]); -+ } -+ -+ return IMG_TRUE; -+} -+ -+#endif /* defined(CONFIG_DSSCOMP) */ -+ -+/* Command processing flip handler function. Called from services. */ -+static IMG_BOOL ProcessFlip(IMG_HANDLE hCmdCookie, -+ IMG_UINT32 ui32DataSize, -+ IMG_VOID *pvData) -+{ -+ DISPLAYCLASS_FLIP_COMMAND *psFlipCmd; -+ OMAPLFB_DEVINFO *psDevInfo; -+ -+ /* Check parameters */ -+ if(!hCmdCookie || !pvData) -+ { -+ return IMG_FALSE; -+ } -+ -+ /* Validate data packet */ -+ psFlipCmd = (DISPLAYCLASS_FLIP_COMMAND*)pvData; -+ -+ if (psFlipCmd == IMG_NULL) -+ { -+ return IMG_FALSE; -+ } -+ -+ psDevInfo = (OMAPLFB_DEVINFO*)psFlipCmd->hExtDevice; -+ -+ if(psFlipCmd->hExtBuffer) -+ { -+ return ProcessFlipV1(hCmdCookie, -+ psDevInfo, -+ psFlipCmd->hExtSwapChain, -+ psFlipCmd->hExtBuffer, -+ psFlipCmd->ui32SwapInterval); -+ } -+ else -+ { -+#if defined(CONFIG_DSSCOMP) -+ DISPLAYCLASS_FLIP_COMMAND2 *psFlipCmd2; -+ psFlipCmd2 = (DISPLAYCLASS_FLIP_COMMAND2 *)pvData; -+ return ProcessFlipV2(hCmdCookie, -+ psDevInfo, -+ psFlipCmd2->ppsMemInfos, -+ psFlipCmd2->ui32NumMemInfos, -+ psFlipCmd2->pvPrivData, -+ psFlipCmd2->ui32PrivDataLength); -+#else -+ BUG(); -+#endif -+ } -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function OMAPLFBInitFBDev -+ -+ @Description specifies devices in the systems memory map -+ -+ @Input psSysData - sys data -+ -+ @Return OMAPLFB_ERROR : -+ -+******************************************************************************/ -+static OMAPLFB_ERROR OMAPLFBInitFBDev(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ struct fb_info *psLINFBInfo; -+ struct module *psLINFBOwner; -+ OMAPLFB_FBINFO *psPVRFBInfo = &psDevInfo->sFBInfo; -+ OMAPLFB_ERROR eError = OMAPLFB_ERROR_GENERIC; -+ unsigned uiFBDevID = psDevInfo->uiFBDevID; -+ -+ OMAPLFB_CONSOLE_LOCK(); -+ -+ psLINFBInfo = registered_fb[uiFBDevID]; -+ if (psLINFBInfo == NULL) -+ { -+ eError = OMAPLFB_ERROR_INVALID_DEVICE; -+ goto ErrorRelSem; -+ } -+ -+ psLINFBOwner = psLINFBInfo->fbops->owner; -+ if (!try_module_get(psLINFBOwner)) -+ { -+ printk(KERN_INFO DRIVER_PREFIX -+ ": %s: Device %u: Couldn't get framebuffer module\n", __FUNCTION__, uiFBDevID); -+ -+ goto ErrorRelSem; -+ } -+ -+ if (psLINFBInfo->fbops->fb_open != NULL) -+ { -+ int res; -+ -+ res = psLINFBInfo->fbops->fb_open(psLINFBInfo, 0); -+ if (res != 0) -+ { -+ printk(KERN_INFO DRIVER_PREFIX -+ " %s: Device %u: Couldn't open framebuffer(%d)\n", __FUNCTION__, uiFBDevID, res); -+ -+ goto ErrorModPut; -+ } -+ } -+ -+ psDevInfo->psLINFBInfo = psLINFBInfo; -+ -+ psPVRFBInfo->ulWidth = psLINFBInfo->var.xres; -+ psPVRFBInfo->ulHeight = psLINFBInfo->var.yres; -+ -+ if (psPVRFBInfo->ulWidth == 0 || psPVRFBInfo->ulHeight == 0) -+ { -+ eError = OMAPLFB_ERROR_INVALID_DEVICE; -+ goto ErrorFBRel; -+ } -+ -+#if !defined(CONFIG_DSSCOMP) -+ psPVRFBInfo->ulFBSize = (psLINFBInfo->screen_size) != 0 ? -+ psLINFBInfo->screen_size : -+ psLINFBInfo->fix.smem_len; -+ -+ /* -+ * Try and filter out invalid FB info structures (a problem -+ * seen on some OMAP3 systems). -+ */ -+ if (psPVRFBInfo->ulFBSize == 0 || psLINFBInfo->fix.line_length == 0) -+ { -+ eError = OMAPLFB_ERROR_INVALID_DEVICE; -+ goto ErrorFBRel; -+ } -+ -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX -+ ": Device %u: Framebuffer size: %lu\n", -+ psDevInfo->uiFBDevID, psPVRFBInfo->ulFBSize)); -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX -+ ": Device %u: Framebuffer virtual width: %u\n", -+ psDevInfo->uiFBDevID, psLINFBInfo->var.xres_virtual)); -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX -+ ": Device %u: Framebuffer virtual height: %u\n", -+ psDevInfo->uiFBDevID, psLINFBInfo->var.yres_virtual)); -+#endif -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX -+ ": Device %u: Framebuffer width: %lu\n", -+ psDevInfo->uiFBDevID, psPVRFBInfo->ulWidth)); -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX -+ ": Device %u: Framebuffer height: %lu\n", -+ psDevInfo->uiFBDevID, psPVRFBInfo->ulHeight)); -+ -+#if defined(CONFIG_DSSCOMP) -+ { -+#if defined(SUPPORT_PVRSRV_GET_DC_SYSTEM_BUFFER) -+ /* -+ * Assume we need 3 swap buffers, and a separate system -+ * buffer. -+ */ -+ int n = 4; -+#else -+ /* -+ * Assume we need just 3 swap buffers, and no separate -+ * system buffer. -+ */ -+ int n = 3; -+#endif -+ int res; -+ int i, x, y, w; -+ ion_phys_addr_t phys; -+ size_t size; -+ struct tiler_view_t view; -+ -+ struct omap_ion_tiler_alloc_data sAllocData = -+ { -+ /* TILER will align width to 128-bytes */ -+ /* however, SGX must have full page width */ -+ .w = ALIGN(psPVRFBInfo->ulWidth, PAGE_SIZE / (psLINFBInfo->var.bits_per_pixel / 8)), -+ .h = psPVRFBInfo->ulHeight, -+ .fmt = psLINFBInfo->var.bits_per_pixel == 16 ? TILER_PIXEL_FMT_16BIT : TILER_PIXEL_FMT_32BIT, -+ .flags = 0, -+ }; -+ -+ printk(KERN_DEBUG DRIVER_PREFIX -+ " %s: Device %u: Requesting %d TILER 2D framebuffers\n", -+ __FUNCTION__, uiFBDevID, n); -+ -+ sAllocData.w *= n; -+ -+ psPVRFBInfo->uiBytesPerPixel = psLINFBInfo->var.bits_per_pixel >> 3; -+ psPVRFBInfo->bIs2D = OMAPLFB_TRUE; -+ -+ res = omap_ion_tiler_alloc(psDevInfo->psIONClient, &sAllocData); -+ psPVRFBInfo->psIONHandle = sAllocData.handle; -+ if (res < 0) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ " %s: Device %u: Could not allocate 2D framebuffer(%d)\n", -+ __FUNCTION__, uiFBDevID, res); -+ goto ErrorFBRel; -+ } -+ -+ res = ion_phys(psDevInfo->psIONClient, sAllocData.handle, &phys, &size); -+ if (res < 0) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ " %s: Device %u: Could not get 2D framebufferphysical address (%d)\n", -+ __FUNCTION__, uiFBDevID, res); -+ goto ErrorFBRel; -+ } -+ -+ psPVRFBInfo->sSysAddr.uiAddr = phys; -+ psPVRFBInfo->sCPUVAddr = 0; -+ -+ psPVRFBInfo->ulByteStride = PAGE_ALIGN(psPVRFBInfo->ulWidth * psPVRFBInfo->uiBytesPerPixel); -+ w = psPVRFBInfo->ulByteStride >> PAGE_SHIFT; -+ -+ psPVRFBInfo->ulFBSize = sAllocData.h * n * psPVRFBInfo->ulByteStride; -+ psPVRFBInfo->psPageList = kzalloc(w * n * psPVRFBInfo->ulHeight * sizeof(*psPVRFBInfo->psPageList), GFP_KERNEL); -+ if (!psPVRFBInfo->psPageList) -+ { -+ printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Could not allocate page list\n", __FUNCTION__, psDevInfo->uiFBDevID); -+ ion_free(psDevInfo->psIONClient, sAllocData.handle); -+ goto ErrorFBRel; -+ } -+ -+ tilview_create(&view, phys, psDevInfo->sFBInfo.ulWidth, psDevInfo->sFBInfo.ulHeight); -+ for(i = 0; i < n; i++) -+ { -+ for(y = 0; y < psDevInfo->sFBInfo.ulHeight; y++) -+ { -+ for(x = 0; x < w; x++) -+ { -+ psPVRFBInfo->psPageList[i * psDevInfo->sFBInfo.ulHeight * w + y * w + x].uiAddr = -+ phys + view.v_inc * y + ((x + i * w) << PAGE_SHIFT); -+ } -+ } -+ } -+ } -+#else /* defined(CONFIG_DSSCOMP) */ -+ /* System Surface */ -+ psPVRFBInfo->sSysAddr.uiAddr = psLINFBInfo->fix.smem_start; -+ psPVRFBInfo->sCPUVAddr = psLINFBInfo->screen_base; -+ -+ psPVRFBInfo->ulByteStride = psLINFBInfo->fix.line_length; -+#endif /* defined(CONFIG_DSSCOMP) */ -+ -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX -+ ": Device %u: Framebuffer physical address: 0x%x\n", -+ psDevInfo->uiFBDevID, psPVRFBInfo->sSysAddr.uiAddr)); -+ -+ if (psPVRFBInfo->sCPUVAddr != NULL) -+ { -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX -+ ": Device %u: Framebuffer virtual address: %p\n", -+ psDevInfo->uiFBDevID, psPVRFBInfo->sCPUVAddr)); -+ } -+ -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX -+ ": Device %u: Framebuffer stride: %lu\n", -+ psDevInfo->uiFBDevID, psPVRFBInfo->ulByteStride)); -+ -+ /* Additional implementation specific information */ -+ OMAPLFBPrintInfo(psDevInfo); -+ -+ psPVRFBInfo->ulBufferSize = psPVRFBInfo->ulHeight * psPVRFBInfo->ulByteStride; -+ -+#if defined(CONFIG_DSSCOMP) -+ psPVRFBInfo->ulRoundedBufferSize = psPVRFBInfo->ulBufferSize; -+#else -+ { -+ unsigned long ulLCM; -+ ulLCM = LCM(psPVRFBInfo->ulByteStride, OMAPLFB_PAGE_SIZE); -+ -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX -+ ": Device %u: LCM of stride and page size: %lu\n", -+ psDevInfo->uiFBDevID, ulLCM)); -+ -+ /* Round the buffer size up to a multiple of the number of pages -+ * and the byte stride. -+ * This is used internally, to ensure buffers start on page -+ * boundaries, for the benefit of PVR Services. -+ */ -+ psPVRFBInfo->ulRoundedBufferSize = RoundUpToMultiple(psPVRFBInfo->ulBufferSize, ulLCM); -+ } -+#endif -+ if(psLINFBInfo->var.bits_per_pixel == 16) -+ { -+ if((psLINFBInfo->var.red.length == 5) && -+ (psLINFBInfo->var.green.length == 6) && -+ (psLINFBInfo->var.blue.length == 5) && -+ (psLINFBInfo->var.red.offset == 11) && -+ (psLINFBInfo->var.green.offset == 5) && -+ (psLINFBInfo->var.blue.offset == 0) && -+ (psLINFBInfo->var.red.msb_right == 0)) -+ { -+ psPVRFBInfo->ePixelFormat = PVRSRV_PIXEL_FORMAT_RGB565; -+ } -+ else -+ { -+ printk(KERN_INFO DRIVER_PREFIX ": %s: Device %u: Unknown FB format\n", __FUNCTION__, uiFBDevID); -+ } -+ } -+ else if(psLINFBInfo->var.bits_per_pixel == 32) -+ { -+ if((psLINFBInfo->var.red.length == 8) && -+ (psLINFBInfo->var.green.length == 8) && -+ (psLINFBInfo->var.blue.length == 8) && -+ (psLINFBInfo->var.red.offset == 16) && -+ (psLINFBInfo->var.green.offset == 8) && -+ (psLINFBInfo->var.blue.offset == 0) && -+ (psLINFBInfo->var.red.msb_right == 0)) -+ { -+ psPVRFBInfo->ePixelFormat = PVRSRV_PIXEL_FORMAT_ARGB8888; -+ } -+ else -+ { -+ printk(KERN_INFO DRIVER_PREFIX ": %s: Device %u: Unknown FB format\n", __FUNCTION__, uiFBDevID); -+ } -+ } -+ else -+ { -+ printk(KERN_INFO DRIVER_PREFIX ": %s: Device %u: Unknown FB format\n", __FUNCTION__, uiFBDevID); -+ } -+ -+ psDevInfo->sFBInfo.ulPhysicalWidthmm = -+ ((int)psLINFBInfo->var.width > 0) ? psLINFBInfo->var.width : 90; -+ -+ psDevInfo->sFBInfo.ulPhysicalHeightmm = -+ ((int)psLINFBInfo->var.height > 0) ? psLINFBInfo->var.height : 54; -+ -+ /* System Surface */ -+ psDevInfo->sFBInfo.sSysAddr.uiAddr = psPVRFBInfo->sSysAddr.uiAddr; -+ psDevInfo->sFBInfo.sCPUVAddr = psPVRFBInfo->sCPUVAddr; -+ -+ eError = OMAPLFB_OK; -+ goto ErrorRelSem; -+ -+ErrorFBRel: -+ if (psLINFBInfo->fbops->fb_release != NULL) -+ { -+ (void) psLINFBInfo->fbops->fb_release(psLINFBInfo, 0); -+ } -+ErrorModPut: -+ module_put(psLINFBOwner); -+ErrorRelSem: -+ OMAPLFB_CONSOLE_UNLOCK(); -+ -+ return eError; -+} -+ -+static void OMAPLFBDeInitFBDev(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ struct fb_info *psLINFBInfo = psDevInfo->psLINFBInfo; -+ struct module *psLINFBOwner; -+ -+ OMAPLFB_CONSOLE_LOCK(); -+ -+#if defined(CONFIG_DSSCOMP) -+ { -+ OMAPLFB_FBINFO *psPVRFBInfo = &psDevInfo->sFBInfo; -+ kfree(psPVRFBInfo->psPageList); -+ if (psPVRFBInfo->psIONHandle) -+ { -+ ion_free(psDevInfo->psIONClient, psPVRFBInfo->psIONHandle); -+ } -+ } -+#endif /* defined(CONFIG_DSSCOMP) */ -+ -+ psLINFBOwner = psLINFBInfo->fbops->owner; -+ -+ if (psLINFBInfo->fbops->fb_release != NULL) -+ { -+ (void) psLINFBInfo->fbops->fb_release(psLINFBInfo, 0); -+ } -+ -+ module_put(psLINFBOwner); -+ -+ OMAPLFB_CONSOLE_UNLOCK(); -+} -+ -+static OMAPLFB_DEVINFO *OMAPLFBInitDev(unsigned uiFBDevID) -+{ -+ PFN_CMD_PROC pfnCmdProcList[OMAPLFB_COMMAND_COUNT]; -+ IMG_UINT32 aui32SyncCountList[OMAPLFB_COMMAND_COUNT][2]; -+ OMAPLFB_DEVINFO *psDevInfo = NULL; -+ -+ /* Allocate device info. structure */ -+ psDevInfo = (OMAPLFB_DEVINFO *)OMAPLFBAllocKernelMem(sizeof(OMAPLFB_DEVINFO)); -+ -+ if(psDevInfo == NULL) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ ": %s: Device %u: Couldn't allocate device information structure\n", __FUNCTION__, uiFBDevID); -+ -+ goto ErrorExit; -+ } -+ -+ /* Any fields not set will be zero */ -+ memset(psDevInfo, 0, sizeof(OMAPLFB_DEVINFO)); -+ -+ psDevInfo->uiFBDevID = uiFBDevID; -+ -+ /* Get the kernel services function table */ -+ if(!(*gpfnGetPVRJTable)(&psDevInfo->sPVRJTable)) -+ { -+ goto ErrorFreeDevInfo; -+ } -+ -+#if defined(CONFIG_ION_OMAP) -+ psDevInfo->psIONClient = -+ ion_client_create(omap_ion_device, -+ 1 << ION_HEAP_TYPE_CARVEOUT | -+ 1 << OMAP_ION_HEAP_TYPE_TILER, -+ "dc_omapfb3_linux"); -+ if (IS_ERR_OR_NULL(psDevInfo->psIONClient)) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ ": %s: Device %u: Failed to create ion client\n", __FUNCTION__, uiFBDevID); -+ -+ goto ErrorFreeDevInfo; -+ } -+#endif /* defined(CONFIG_ION_OMAP) */ -+ -+#ifdef FBDEV_PRESENT -+ /* Save private fbdev information structure in the dev. info. */ -+ if(OMAPLFBInitFBDev(psDevInfo) != OMAPLFB_OK) -+ { -+ /* -+ * Leave it to OMAPLFBInitFBDev to print an error message, if -+ * required. The function may have failed because -+ * there is no Linux framebuffer device corresponding -+ * to the device ID. -+ */ -+ goto ErrorIonClientDestroy; -+ } -+ -+ psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers = (IMG_UINT32)(psDevInfo->sFBInfo.ulFBSize / psDevInfo->sFBInfo.ulRoundedBufferSize); -+ if (psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers != 0) -+ { -+ psDevInfo->sDisplayInfo.ui32MaxSwapChains = 1; -+ psDevInfo->sDisplayInfo.ui32MaxSwapInterval = 1; -+#if defined(CONFIG_DSSCOMP) -+ psDevInfo->sDisplayInfo.ui32MinSwapInterval = 1; -+#endif -+ } -+ -+ psDevInfo->sDisplayInfo.ui32PhysicalWidthmm = psDevInfo->sFBInfo.ulPhysicalWidthmm; -+ psDevInfo->sDisplayInfo.ui32PhysicalHeightmm = psDevInfo->sFBInfo.ulPhysicalHeightmm; -+ -+ strncpy(psDevInfo->sDisplayInfo.szDisplayName, DISPLAY_DEVICE_NAME, MAX_DISPLAY_NAME_SIZE); -+ -+ psDevInfo->sDisplayFormat.pixelformat = psDevInfo->sFBInfo.ePixelFormat; -+ psDevInfo->sDisplayDim.ui32Width = (IMG_UINT32)psDevInfo->sFBInfo.ulWidth; -+ psDevInfo->sDisplayDim.ui32Height = (IMG_UINT32)psDevInfo->sFBInfo.ulHeight; -+ psDevInfo->sDisplayDim.ui32ByteStride = (IMG_UINT32)psDevInfo->sFBInfo.ulByteStride; -+ -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX -+ ": Device %u: Maximum number of swap chain buffers: %u\n", -+ psDevInfo->uiFBDevID, psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers)); -+ -+ /* Setup system buffer */ -+ psDevInfo->sSystemBuffer.sSysAddr = psDevInfo->sFBInfo.sSysAddr; -+ psDevInfo->sSystemBuffer.sCPUVAddr = psDevInfo->sFBInfo.sCPUVAddr; -+ psDevInfo->sSystemBuffer.psDevInfo = psDevInfo; -+ -+ OMAPLFBInitBufferForSwap(&psDevInfo->sSystemBuffer); -+#else -+psDevInfo->sSystemBuffer.sCPUVAddr = 0x100; -+// psDevInfo->sSystemBuffer.ulBufferSize = 600*3200; -+ -+ psDevInfo->sDisplayFormat.pixelformat = 20; -+ psDevInfo->sFBInfo.ulWidth = 800; -+ psDevInfo->sFBInfo.ulHeight = 600; -+ psDevInfo->sFBInfo.ulByteStride = 3200; -+ psDevInfo->sFBInfo.ulFBSize = 8388608; -+ psDevInfo->sFBInfo.ulBufferSize = 600*3200; -+#endif -+ -+#if defined(CONFIG_DSSCOMP) && defined(SUPPORT_PVRSRV_GET_DC_SYSTEM_BUFFER) -+ OMAPLFBFlip(psDevInfo, &psDevInfo->sSystemBuffer); -+#endif -+ -+ /* -+ Setup the DC Jtable so SRVKM can call into this driver -+ */ -+ psDevInfo->sDCJTable.ui32TableSize = sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE); -+ psDevInfo->sDCJTable.pfnOpenDCDevice = OpenDCDevice; -+ psDevInfo->sDCJTable.pfnCloseDCDevice = CloseDCDevice; -+ psDevInfo->sDCJTable.pfnEnumDCFormats = EnumDCFormats; -+ psDevInfo->sDCJTable.pfnEnumDCDims = EnumDCDims; -+ psDevInfo->sDCJTable.pfnGetDCSystemBuffer = GetDCSystemBuffer; -+ psDevInfo->sDCJTable.pfnGetDCInfo = GetDCInfo; -+ psDevInfo->sDCJTable.pfnGetBufferAddr = GetDCBufferAddr; -+ psDevInfo->sDCJTable.pfnCreateDCSwapChain = CreateDCSwapChain; -+ psDevInfo->sDCJTable.pfnDestroyDCSwapChain = DestroyDCSwapChain; -+ psDevInfo->sDCJTable.pfnSetDCDstRect = SetDCDstRect; -+ psDevInfo->sDCJTable.pfnSetDCSrcRect = SetDCSrcRect; -+ psDevInfo->sDCJTable.pfnSetDCDstColourKey = SetDCDstColourKey; -+ psDevInfo->sDCJTable.pfnSetDCSrcColourKey = SetDCSrcColourKey; -+ psDevInfo->sDCJTable.pfnGetDCBuffers = GetDCBuffers; -+ psDevInfo->sDCJTable.pfnSwapToDCBuffer = SwapToDCBuffer; -+ psDevInfo->sDCJTable.pfnSetDCState = SetDCState; -+ -+ /* Register device with services and retrieve device index */ -+ if(psDevInfo->sPVRJTable.pfnPVRSRVRegisterDCDevice( -+ &psDevInfo->sDCJTable, -+ &psDevInfo->uiPVRDevID) != PVRSRV_OK) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ ": %s: Device %u: PVR Services device registration failed\n", __FUNCTION__, uiFBDevID); -+ -+ goto ErrorDeInitFBDev; -+ } -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX -+ ": Device %u: PVR Device ID: %u\n", -+ psDevInfo->uiFBDevID, psDevInfo->uiPVRDevID)); -+ -+ /* Setup private command processing function table ... */ -+ pfnCmdProcList[DC_FLIP_COMMAND] = ProcessFlip; -+ -+ /* ... and associated sync count(s) */ -+ aui32SyncCountList[DC_FLIP_COMMAND][0] = 0; /* writes */ -+ aui32SyncCountList[DC_FLIP_COMMAND][1] = 10; /* reads */ -+ -+ /* -+ Register private command processing functions with -+ the Command Queue Manager and setup the general -+ command complete function in the devinfo. -+ */ -+ if (psDevInfo->sPVRJTable.pfnPVRSRVRegisterCmdProcList(psDevInfo->uiPVRDevID, -+ &pfnCmdProcList[0], -+ aui32SyncCountList, -+ OMAPLFB_COMMAND_COUNT) != PVRSRV_OK) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ ": %s: Device %u: Couldn't register command processing functions with PVR Services\n", __FUNCTION__, uiFBDevID); -+ goto ErrorUnregisterDevice; -+ } -+ -+ OMAPLFBCreateSwapChainLockInit(psDevInfo); -+ -+ OMAPLFBAtomicBoolInit(&psDevInfo->sBlanked, OMAPLFB_FALSE); -+ OMAPLFBAtomicIntInit(&psDevInfo->sBlankEvents, 0); -+ OMAPLFBAtomicBoolInit(&psDevInfo->sFlushCommands, OMAPLFB_FALSE); -+#if defined(CONFIG_HAS_EARLYSUSPEND) -+ OMAPLFBAtomicBoolInit(&psDevInfo->sEarlySuspendFlag, OMAPLFB_FALSE); -+#endif -+#if defined(SUPPORT_DRI_DRM) -+ OMAPLFBAtomicBoolInit(&psDevInfo->sLeaveVT, OMAPLFB_FALSE); -+#endif -+ -+ return psDevInfo; -+ -+ErrorUnregisterDevice: -+ (void)psDevInfo->sPVRJTable.pfnPVRSRVRemoveDCDevice(psDevInfo->uiPVRDevID); -+ErrorDeInitFBDev: -+ OMAPLFBDeInitFBDev(psDevInfo); -+ErrorIonClientDestroy: -+#if defined(CONFIG_ION_OMAP) -+ ion_client_destroy(psDevInfo->psIONClient); -+#endif /* defined(CONFIG_ION_OMAP) */ -+ErrorFreeDevInfo: -+ OMAPLFBFreeKernelMem(psDevInfo); -+ErrorExit: -+ return NULL; -+} -+ -+OMAPLFB_ERROR OMAPLFBInit(void) -+{ -+ unsigned uiMaxFBDevIDPlusOne = OMAPLFBMaxFBDevIDPlusOne(); -+ unsigned i; -+ unsigned uiDevicesFound = 0; -+ -+ if(OMAPLFBGetLibFuncAddr ("PVRGetDisplayClassJTable", &gpfnGetPVRJTable) != OMAPLFB_OK) -+ { -+ return OMAPLFB_ERROR_INIT_FAILURE; -+ } -+ -+ /* -+ * We search for frame buffer devices backwards, as the last device -+ * registered with PVR Services will be the first device enumerated -+ * by PVR Services. -+ */ -+ for(i = uiMaxFBDevIDPlusOne; i-- != 0;) -+ { -+ OMAPLFB_DEVINFO *psDevInfo = OMAPLFBInitDev(i); -+ -+ if (psDevInfo != NULL) -+ { -+ /* Set the top-level anchor */ -+ OMAPLFBSetDevInfoPtr(psDevInfo->uiFBDevID, psDevInfo); -+ uiDevicesFound++; -+ } -+ } -+ -+ return (uiDevicesFound != 0) ? OMAPLFB_OK : OMAPLFB_ERROR_INIT_FAILURE; -+} -+ -+/* -+ * OMAPLFBDeInitDev -+ * DeInitialises one device -+ */ -+static OMAPLFB_BOOL OMAPLFBDeInitDev(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ PVRSRV_DC_DISP2SRV_KMJTABLE *psPVRJTable = &psDevInfo->sPVRJTable; -+ -+ if (psPVRJTable->pfnPVRSRVRemoveCmdProcList (psDevInfo->uiPVRDevID, OMAPLFB_COMMAND_COUNT) != PVRSRV_OK) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ ": %s: Device %u: PVR Device %u: Couldn't unregister command processing functions\n", __FUNCTION__, psDevInfo->uiFBDevID, psDevInfo->uiPVRDevID); -+ return OMAPLFB_FALSE; -+ } -+ -+ /* -+ * Remove display class device from kernel services device -+ * register. -+ */ -+ if (psPVRJTable->pfnPVRSRVRemoveDCDevice(psDevInfo->uiPVRDevID) != PVRSRV_OK) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ ": %s: Device %u: PVR Device %u: Couldn't remove device from PVR Services\n", __FUNCTION__, psDevInfo->uiFBDevID, psDevInfo->uiPVRDevID); -+ return OMAPLFB_FALSE; -+ } -+ -+#if defined(CONFIG_DSSCOMP) -+ /* Disable the overlay, as we will be freeing the display buffers */ -+ psDevInfo->sSystemBuffer.sSysAddr.uiAddr = 0; -+ OMAPLFBFlip(psDevInfo, &psDevInfo->sSystemBuffer); -+#endif /* defined(CONFIG_DSSCOMP) */ -+ -+ OMAPLFBCreateSwapChainLockDeInit(psDevInfo); -+ -+ OMAPLFBAtomicBoolDeInit(&psDevInfo->sBlanked); -+ OMAPLFBAtomicIntDeInit(&psDevInfo->sBlankEvents); -+ OMAPLFBAtomicBoolDeInit(&psDevInfo->sFlushCommands); -+#if defined(CONFIG_HAS_EARLYSUSPEND) -+ OMAPLFBAtomicBoolDeInit(&psDevInfo->sEarlySuspendFlag); -+#endif -+#if defined(SUPPORT_DRI_DRM) -+ OMAPLFBAtomicBoolDeInit(&psDevInfo->sLeaveVT); -+#endif -+ -+#ifdef FBDEV_PRESENT -+ OMAPLFBDeInitFBDev(psDevInfo); -+#endif -+#if defined(CONFIG_ION_OMAP) -+ ion_client_destroy(psDevInfo->psIONClient); -+#endif -+ -+ OMAPLFBSetDevInfoPtr(psDevInfo->uiFBDevID, NULL); -+ -+ /* De-allocate data structure */ -+ OMAPLFBFreeKernelMem(psDevInfo); -+ -+ return OMAPLFB_TRUE; -+} -+ -+/* -+ * OMAPLFBDeInit -+ * Deinitialises the display class device component of the FBDev -+ */ -+OMAPLFB_ERROR OMAPLFBDeInit(void) -+{ -+ unsigned uiMaxFBDevIDPlusOne = OMAPLFBMaxFBDevIDPlusOne(); -+ unsigned i; -+ OMAPLFB_BOOL bError = OMAPLFB_FALSE; -+ -+ for(i = 0; i < uiMaxFBDevIDPlusOne; i++) -+ { -+ OMAPLFB_DEVINFO *psDevInfo = OMAPLFBGetDevInfoPtr(i); -+ -+ if (psDevInfo != NULL) -+ { -+ bError |= !OMAPLFBDeInitDev(psDevInfo); -+ } -+ } -+ -+ return (bError) ? OMAPLFB_ERROR_INIT_FAILURE : OMAPLFB_OK; -+} -+ -+/****************************************************************************** -+ End of file (omaplfb_displayclass.c) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_omapfb3_linux/omaplfb_linux.c b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_omapfb3_linux/omaplfb_linux.c -new file mode 100644 -index 0000000..3e2bc69 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_omapfb3_linux/omaplfb_linux.c -@@ -0,0 +1,1303 @@ -+/*************************************************************************/ /*! -+@Title OMAP linux display driver components -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+/************************************************************************** -+ The 3rd party driver is a specification of an API to integrate the IMG POWERVR -+ Services driver with 3rd Party display hardware. It is NOT a specification for -+ a display controller driver, rather a specification to extend the API for a -+ pre-existing driver for the display hardware. -+ -+ The 3rd party driver interface provides IMG POWERVR client drivers (e.g. PVR2D) -+ with an API abstraction of the system's underlying display hardware, allowing -+ the client drivers to indirectly control the display hardware and access its -+ associated memory. -+ -+ Functions of the API include -+ - query primary surface attributes (width, height, stride, pixel format, CPU -+ physical and virtual address) -+ - swap/flip chain creation and subsequent query of surface attributes -+ - asynchronous display surface flipping, taking account of asynchronous read -+ (flip) and write (render) operations to the display surface -+ -+ Note: having queried surface attributes the client drivers are able to map the -+ display memory to any IMG POWERVR Services device by calling -+ PVRSRVMapDeviceClassMemory with the display surface handle. -+ -+ This code is intended to be an example of how a pre-existing display driver may -+ be extended to support the 3rd Party Display interface to POWERVR Services -+ - IMG is not providing a display driver implementation. -+ **************************************************************************/ -+ -+#include <linux/version.h> -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)) -+#ifndef AUTOCONF_INCLUDED -+#include <linux/config.h> -+#endif -+#endif -+ -+#include <asm/atomic.h> -+ -+#if defined(SUPPORT_DRI_DRM) -+#include <drm/drmP.h> -+#else -+#include <linux/module.h> -+#endif -+ -+#include <linux/kernel.h> -+#include <linux/slab.h> -+#include <linux/hardirq.h> -+#include <linux/mutex.h> -+#include <linux/workqueue.h> -+#include <linux/fb.h> -+#include <linux/console.h> -+#include <linux/omapfb.h> -+#include <linux/mutex.h> -+ -+#if defined(PVR_OMAPLFB_DRM_FB) -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0)) -+#include <plat/display.h> -+#else -+#include <video/omapdss.h> -+#endif -+#include <linux/omap_gpu.h> -+#else /* defined(PVR_OMAPLFB_DRM_FB) */ -+/* OmapZoom.org OMAP3 2.6.29 kernel tree - Needs mach/vrfb.h -+ * OmapZoom.org OMAP3 2.6.32 kernel tree - No additional header required -+ * OmapZoom.org OMAP4 2.6.33 kernel tree - No additional header required -+ * OmapZoom.org OMAP4 2.6.34 kernel tree - Needs plat/vrfb.h -+ * Sholes 2.6.32 kernel tree - Needs plat/vrfb.h -+ */ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34)) -+#define PVR_OMAPFB3_NEEDS_PLAT_VRFB_H -+#endif -+ -+#if defined(PVR_OMAPFB3_NEEDS_PLAT_VRFB_H) -+#ifdef FBDEV_PRESENT -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) -+#include <plat/vrfb.h> -+#else -+#include <video/omapvrfb.h> -+#endif -+#endif -+ -+#else -+#if defined(PVR_OMAPFB3_NEEDS_MACH_VRFB_H) -+#include <mach/vrfb.h> -+#endif -+#endif -+ -+#if defined(DEBUG) -+#define PVR_DEBUG DEBUG -+#undef DEBUG -+#endif -+#ifdef FBDEV_PRESENT -+#include <omapfb/omapfb.h> -+#endif -+#if defined(DEBUG) -+#undef DEBUG -+#endif -+#if defined(PVR_DEBUG) -+#define DEBUG PVR_DEBUG -+#undef PVR_DEBUG -+#endif -+#endif /* defined(PVR_OMAPLFB_DRM_FB) */ -+ -+#if defined(CONFIG_DSSCOMP) -+#if defined(CONFIG_DRM_OMAP_DMM_TILER) -+#include <../drivers/staging/omapdrm/omap_dmm_tiler.h> -+#include <../drivers/video/omap2/dsscomp/tiler-utils.h> -+#elif defined(CONFIG_TI_TILER) -+#include <mach/tiler.h> -+#else /* defined(CONFIG_DRM_OMAP_DMM_TILER) */ -+#error CONFIG_DSSCOMP support requires either \ -+ CONFIG_DRM_OMAP_DMM_TILER or CONFIG_TI_TILER -+#endif /* defined(CONFIG_DRM_OMAP_DMM_TILER) */ -+#include <video/dsscomp.h> -+#include <plat/dsscomp.h> -+#endif /* defined(CONFIG_DSSCOMP) */ -+ -+#include "img_defs.h" -+#include "servicesext.h" -+#include "kerneldisplay.h" -+#include "omaplfb.h" -+#include "pvrmodule.h" -+#if defined(SUPPORT_DRI_DRM) -+#include "pvr_drm.h" -+#include "3rdparty_dc_drm_shared.h" -+#endif -+ -+#if !defined(PVR_LINUX_USING_WORKQUEUES) -+#error "PVR_LINUX_USING_WORKQUEUES must be defined" -+#endif -+ -+MODULE_SUPPORTED_DEVICE(DEVNAME); -+ -+#if !defined(PVR_OMAPLFB_DRM_FB) -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34)) -+#define OMAP_DSS_DRIVER(drv, dev) struct omap_dss_driver *drv = (dev) != NULL ? (dev)->driver : NULL -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0)) -+#define OMAP_DSS_MANAGER(man, dev) struct omap_overlay_manager *man = (dev) != NULL ? (dev)->manager : NULL -+#else -+#define OMAP_DSS_MANAGER(man, dev) struct omap_overlay_manager *man = (dev) != NULL ? (dev)->output->manager : NULL -+#endif -+ -+#define WAIT_FOR_VSYNC(man) ((man)->wait_for_vsync) -+#else -+#define OMAP_DSS_DRIVER(drv, dev) struct omap_dss_device *drv = (dev) -+#define OMAP_DSS_MANAGER(man, dev) struct omap_dss_device *man = (dev) -+#define WAIT_FOR_VSYNC(man) ((man)->wait_vsync) -+#endif -+#endif /* !defined(PVR_OMAPLFB_DRM_FB) */ -+ -+void *OMAPLFBAllocKernelMem(unsigned long ulSize) -+{ -+ return kmalloc(ulSize, GFP_KERNEL); -+} -+ -+void OMAPLFBFreeKernelMem(void *pvMem) -+{ -+ kfree(pvMem); -+} -+ -+void OMAPLFBCreateSwapChainLockInit(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ mutex_init(&psDevInfo->sCreateSwapChainMutex); -+} -+ -+void OMAPLFBCreateSwapChainLockDeInit(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ mutex_destroy(&psDevInfo->sCreateSwapChainMutex); -+} -+ -+void OMAPLFBCreateSwapChainLock(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ mutex_lock(&psDevInfo->sCreateSwapChainMutex); -+} -+ -+void OMAPLFBCreateSwapChainUnLock(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ mutex_unlock(&psDevInfo->sCreateSwapChainMutex); -+} -+ -+void OMAPLFBAtomicBoolInit(OMAPLFB_ATOMIC_BOOL *psAtomic, OMAPLFB_BOOL bVal) -+{ -+ atomic_set(psAtomic, (int)bVal); -+} -+ -+void OMAPLFBAtomicBoolDeInit(OMAPLFB_ATOMIC_BOOL *psAtomic) -+{ -+} -+ -+void OMAPLFBAtomicBoolSet(OMAPLFB_ATOMIC_BOOL *psAtomic, OMAPLFB_BOOL bVal) -+{ -+ atomic_set(psAtomic, (int)bVal); -+} -+ -+OMAPLFB_BOOL OMAPLFBAtomicBoolRead(OMAPLFB_ATOMIC_BOOL *psAtomic) -+{ -+ return (OMAPLFB_BOOL)atomic_read(psAtomic); -+} -+ -+void OMAPLFBAtomicIntInit(OMAPLFB_ATOMIC_INT *psAtomic, int iVal) -+{ -+ atomic_set(psAtomic, iVal); -+} -+ -+void OMAPLFBAtomicIntDeInit(OMAPLFB_ATOMIC_INT *psAtomic) -+{ -+} -+ -+void OMAPLFBAtomicIntSet(OMAPLFB_ATOMIC_INT *psAtomic, int iVal) -+{ -+ atomic_set(psAtomic, iVal); -+} -+ -+int OMAPLFBAtomicIntRead(OMAPLFB_ATOMIC_INT *psAtomic) -+{ -+ return atomic_read(psAtomic); -+} -+ -+void OMAPLFBAtomicIntInc(OMAPLFB_ATOMIC_INT *psAtomic) -+{ -+ atomic_inc(psAtomic); -+} -+ -+OMAPLFB_ERROR OMAPLFBGetLibFuncAddr (char *szFunctionName, PFN_DC_GET_PVRJTABLE *ppfnFuncTable) -+{ -+ if(strcmp("PVRGetDisplayClassJTable", szFunctionName) != 0) -+ { -+ return (OMAPLFB_ERROR_INVALID_PARAMS); -+ } -+ -+ /* Nothing to do - should be exported from pvrsrv.ko */ -+ *ppfnFuncTable = PVRGetDisplayClassJTable; -+ -+ return (OMAPLFB_OK); -+} -+ -+/* Inset a swap buffer into the swap chain work queue */ -+void OMAPLFBQueueBufferForSwap(OMAPLFB_SWAPCHAIN *psSwapChain, OMAPLFB_BUFFER *psBuffer) -+{ -+ int res = queue_work(psSwapChain->psWorkQueue, &psBuffer->sWork); -+ -+ if (res == 0) -+ { -+ printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Buffer already on work queue\n", __FUNCTION__, psSwapChain->uiFBDevID); -+ } -+} -+ -+/* Process an item on a swap chain work queue */ -+static void WorkQueueHandler(struct work_struct *psWork) -+{ -+ OMAPLFB_BUFFER *psBuffer = container_of(psWork, OMAPLFB_BUFFER, sWork); -+ -+ OMAPLFBSwapHandler(psBuffer); -+} -+ -+/* Create a swap chain work queue */ -+OMAPLFB_ERROR OMAPLFBCreateSwapQueue(OMAPLFB_SWAPCHAIN *psSwapChain) -+{ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) -+#if (LINUX_VERSION_CODE == KERNEL_VERSION(2,6,37)) -+#define WQ_FREEZABLE WQ_FREEZEABLE -+#endif -+ /* -+ * Calling alloc_ordered_workqueue with the WQ_FREEZABLE and -+ * WQ_MEM_RECLAIM flags set, (currently) has the same effect as -+ * calling create_freezable_workqueue. None of the other WQ -+ * flags are valid. Setting WQ_MEM_RECLAIM should allow the -+ * workqueue to continue to service the swap chain in low memory -+ * conditions, preventing the driver from holding on to -+ * resources longer than it needs to. -+ */ -+ psSwapChain->psWorkQueue = alloc_ordered_workqueue(DEVNAME, WQ_FREEZABLE | WQ_MEM_RECLAIM); -+#else -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)) -+ psSwapChain->psWorkQueue = create_freezable_workqueue(DEVNAME); -+#else -+ /* -+ * Create a single-threaded, freezable, rt-prio workqueue. -+ * Such workqueues are frozen with user threads when a system -+ * suspends, before driver suspend entry points are called. -+ * This ensures this driver will not call into the Linux -+ * framebuffer driver after the latter is suspended. -+ */ -+ psSwapChain->psWorkQueue = __create_workqueue(DEVNAME, 1, 1, 1); -+#endif -+#endif -+ if (psSwapChain->psWorkQueue == NULL) -+ { -+ printk(KERN_ERR DRIVER_PREFIX ": %s: Device %u: Couldn't create workqueue\n", __FUNCTION__, psSwapChain->uiFBDevID); -+ -+ return (OMAPLFB_ERROR_INIT_FAILURE); -+ } -+ -+ return (OMAPLFB_OK); -+} -+ -+/* Prepare buffer for insertion into a swap chain work queue */ -+void OMAPLFBInitBufferForSwap(OMAPLFB_BUFFER *psBuffer) -+{ -+ INIT_WORK(&psBuffer->sWork, WorkQueueHandler); -+} -+ -+/* Destroy a swap chain work queue */ -+void OMAPLFBDestroySwapQueue(OMAPLFB_SWAPCHAIN *psSwapChain) -+{ -+ destroy_workqueue(psSwapChain->psWorkQueue); -+} -+ -+/* Flip display to given buffer */ -+void OMAPLFBFlip(OMAPLFB_DEVINFO *psDevInfo, OMAPLFB_BUFFER *psBuffer) -+{ -+ struct fb_var_screeninfo sFBVar; -+ int res; -+ -+ if (!lock_fb_info(psDevInfo->psLINFBInfo)) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX -+ ": %s: Device %u: Couldn't lock FB info\n", __FUNCTION__, psDevInfo->uiFBDevID)); -+ return; -+ } -+ OMAPLFB_CONSOLE_LOCK(); -+ -+ sFBVar = psDevInfo->psLINFBInfo->var; -+ -+ sFBVar.xoffset = 0; -+ sFBVar.yoffset = psBuffer->ulYOffset; -+ -+#if defined(CONFIG_DSSCOMP) -+ /* -+ * If flipping to a NULL buffer, blank the screen to prevent -+ * warnings/errors from the display subsystem. -+ */ -+ if (psBuffer->sSysAddr.uiAddr == 0) -+ { -+ struct omap_dss_device *psDSSDev = fb2display(psDevInfo->psLINFBInfo); -+ OMAP_DSS_MANAGER(psDSSMan, psDSSDev); -+ -+ if (psDSSMan != NULL && psDSSMan->blank != NULL) -+ { -+ res = psDSSMan->blank(psDSSMan, false); -+ if (res != 0) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: DSS manager blank call failed (Y Offset: %lu, Error: %d)\n", __FUNCTION__, psDevInfo->uiFBDevID, psBuffer->ulYOffset, res)); -+ } -+ } -+ } -+ -+ { -+ /* -+ * If using DSSCOMP, we need to use dsscomp queuing for normal -+ * framebuffer updates, so that previously used overlays get -+ * automatically disabled, and manager gets dirtied. We can -+ * do that because DSSCOMP takes ownership of all pipelines on -+ * a manager. -+ */ -+ struct fb_fix_screeninfo sFBFix = psDevInfo->psLINFBInfo->fix; -+ struct dsscomp_setup_dispc_data d = -+ { -+ .num_ovls = 1, -+ .num_mgrs = 1, -+ .mgrs[0].alpha_blending = 1, -+ .ovls[0] = -+ { -+ .cfg = -+ { -+ .win.w = sFBVar.xres, -+ .win.h = sFBVar.yres, -+ .crop.x = sFBVar.xoffset, -+ .crop.y = sFBVar.yoffset, -+ .crop.w = sFBVar.xres, -+ .crop.h = sFBVar.yres, -+ .width = sFBVar.xres_virtual, -+ .height = sFBVar.yres_virtual, -+ .stride = sFBFix.line_length, -+ .enabled = (psBuffer->sSysAddr.uiAddr != 0), -+ .global_alpha = 255, -+ }, -+ }, -+ }; -+ -+ /* do not map buffer into TILER1D as it is contiguous */ -+ struct tiler_pa_info *pas[] = { NULL }; -+ -+ d.ovls[0].ba = (u32) psBuffer->sSysAddr.uiAddr; -+ -+ omapfb_mode_to_dss_mode(&sFBVar, &d.ovls[0].cfg.color_mode); -+ -+ res = dsscomp_gralloc_queue(&d, pas, true, NULL, NULL); -+ if (res != 0) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: dsscomp_gralloc_queue failed (Y Offset: %lu, Error: %d)\n", __FUNCTION__, psDevInfo->uiFBDevID, psBuffer->ulYOffset, res)); -+ } -+ } -+#else /* defined(CONFIG_DSSCOMP) */ -+ { -+ unsigned long ulYResVirtual = psBuffer->ulYOffset + sFBVar.yres; -+ -+ /* -+ * PVR_OMAPLFB_DONT_USE_FB_PAN_DISPLAY should be defined to -+ * work around flipping problems seen with the Taal LCDs on -+ * Blaze. -+ * The work around is safe to use with other types of screen -+ * on Blaze (e.g. HDMI) and on other platforms (e.g. Panda -+ * board). -+ */ -+#if !defined(PVR_OMAPLFB_DONT_USE_FB_PAN_DISPLAY) -+ /* -+ * Attempt to change the virtual screen resolution if it is too -+ * small. Note that fb_set_var also pans the display. -+ */ -+ if (sFBVar.xres_virtual != sFBVar.xres || sFBVar.yres_virtual < ulYResVirtual) -+#endif /* !defined(PVR_OMAPLFB_DONT_USE_FB_PAN_DISPLAY) */ -+ { -+ sFBVar.xres_virtual = sFBVar.xres; -+ sFBVar.yres_virtual = ulYResVirtual; -+ -+ sFBVar.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE; -+ -+ res = fb_set_var(psDevInfo->psLINFBInfo, &sFBVar); -+ if (res != 0) -+ { -+ printk(KERN_ERR DRIVER_PREFIX ": %s: Device %u: fb_set_var failed (Y Offset: %lu, Error: %d)\n", __FUNCTION__, psDevInfo->uiFBDevID, psBuffer->ulYOffset, res); -+ } -+ } -+#if !defined(PVR_OMAPLFB_DONT_USE_FB_PAN_DISPLAY) -+ else -+ { -+ res = fb_pan_display(psDevInfo->psLINFBInfo, &sFBVar); -+ if (res != 0) -+ { -+ printk(KERN_ERR DRIVER_PREFIX ": %s: Device %u: fb_pan_display failed (Y Offset: %lu, Error: %d)\n", __FUNCTION__, psDevInfo->uiFBDevID, psBuffer->ulYOffset, res); -+ } -+ } -+#endif /* !defined(PVR_OMAPLFB_DONT_USE_FB_PAN_DISPLAY) */ -+ } -+#endif /* defined(CONFIG_DSSCOMP) */ -+ -+ OMAPLFB_CONSOLE_UNLOCK(); -+ unlock_fb_info(psDevInfo->psLINFBInfo); -+} -+ -+/* Newer kernels don't have any update mode capability */ -+ -+//#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) -+//#define PVR_OMAPLFB_HAS_UPDATE_MODE -+//#endif -+ -+//#if defined(PVR_OMAPLFB_HAS_UPDATE_MODE) -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0) -+#if !defined(PVR_OMAPLFB_DRM_FB) || defined(DEBUG) -+static OMAPLFB_BOOL OMAPLFBValidateDSSUpdateMode(enum omap_dss_update_mode eMode) -+{ -+ switch (eMode) -+ { -+ case OMAP_DSS_UPDATE_AUTO: -+ case OMAP_DSS_UPDATE_MANUAL: -+ case OMAP_DSS_UPDATE_DISABLED: -+ return OMAPLFB_TRUE; -+ default: -+ break; -+ } -+ -+ return OMAPLFB_FALSE; -+} -+ -+static OMAPLFB_UPDATE_MODE OMAPLFBFromDSSUpdateMode(enum omap_dss_update_mode eMode) -+{ -+ switch (eMode) -+ { -+ case OMAP_DSS_UPDATE_AUTO: -+ return OMAPLFB_UPDATE_MODE_AUTO; -+ case OMAP_DSS_UPDATE_MANUAL: -+ return OMAPLFB_UPDATE_MODE_MANUAL; -+ case OMAP_DSS_UPDATE_DISABLED: -+ return OMAPLFB_UPDATE_MODE_DISABLED; -+ default: -+ break; -+ } -+ -+ return OMAPLFB_UPDATE_MODE_UNDEFINED; -+} -+#endif -+ -+static OMAPLFB_BOOL OMAPLFBValidateUpdateMode(OMAPLFB_UPDATE_MODE eMode) -+{ -+ switch(eMode) -+ { -+ case OMAPLFB_UPDATE_MODE_AUTO: -+ case OMAPLFB_UPDATE_MODE_MANUAL: -+ case OMAPLFB_UPDATE_MODE_DISABLED: -+ return OMAPLFB_TRUE; -+ default: -+ break; -+ } -+ -+ return OMAPLFB_FALSE; -+} -+ -+static enum omap_dss_update_mode OMAPLFBToDSSUpdateMode(OMAPLFB_UPDATE_MODE eMode) -+{ -+ switch(eMode) -+ { -+ case OMAPLFB_UPDATE_MODE_AUTO: -+ return OMAP_DSS_UPDATE_AUTO; -+ case OMAPLFB_UPDATE_MODE_MANUAL: -+ return OMAP_DSS_UPDATE_MANUAL; -+ case OMAPLFB_UPDATE_MODE_DISABLED: -+ return OMAP_DSS_UPDATE_DISABLED; -+ default: -+ break; -+ } -+ -+ return -1; -+} -+#endif -+#if defined(DEBUG) -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0) -+static const char *OMAPLFBUpdateModeToString(OMAPLFB_UPDATE_MODE eMode) -+{ -+ switch(eMode) -+ { -+ case OMAPLFB_UPDATE_MODE_AUTO: -+ return "Auto Update Mode"; -+ case OMAPLFB_UPDATE_MODE_MANUAL: -+ return "Manual Update Mode"; -+ case OMAPLFB_UPDATE_MODE_DISABLED: -+ return "Update Mode Disabled"; -+ case OMAPLFB_UPDATE_MODE_UNDEFINED: -+ return "Update Mode Undefined"; -+ default: -+ break; -+ } -+ -+ return "Unknown Update Mode"; -+} -+ -+static const char *OMAPLFBDSSUpdateModeToString(enum omap_dss_update_mode eMode) -+{ -+ if (!OMAPLFBValidateDSSUpdateMode(eMode)) -+ { -+ return "Unknown Update Mode"; -+ } -+ -+ return OMAPLFBUpdateModeToString(OMAPLFBFromDSSUpdateMode(eMode)); -+} -+#endif -+#endif /* defined(DEBUG) */ -+ -+/* -+ * Get display update mode. -+ * If the mode is AUTO, we can wait for VSync, if desired. -+ */ -+OMAPLFB_UPDATE_MODE OMAPLFBGetUpdateMode(OMAPLFB_DEVINFO *psDevInfo) -+{ -+#if defined(PVR_OMAPLFB_DRM_FB) -+ struct drm_connector *psConnector; -+ OMAPLFB_UPDATE_MODE eMode = OMAPLFB_UPDATE_MODE_UNDEFINED; -+ -+ /* -+ * There may be multiple displays connected. If at least one -+ * display is manual update mode, report all screens as being -+ * in that mode. -+ */ -+ for (psConnector = NULL; -+ (psConnector = omap_fbdev_get_next_connector(psDevInfo->psLINFBInfo, psConnector)) != NULL;) -+ { -+ switch(omap_connector_get_update_mode(psConnector)) -+ { -+ case OMAP_DSS_UPDATE_MANUAL: -+ eMode = OMAPLFB_UPDATE_MODE_MANUAL; -+ break; -+ case OMAP_DSS_UPDATE_DISABLED: -+ if (eMode == OMAPLFB_UPDATE_MODE_UNDEFINED) -+ { -+ eMode = OMAPLFB_UPDATE_MODE_DISABLED; -+ } -+ break; -+ case OMAP_DSS_UPDATE_AUTO: -+ /* Fall through to default case */ -+ default: -+ /* Asssume auto update is possible */ -+ if (eMode != OMAPLFB_UPDATE_MODE_MANUAL) -+ { -+ eMode = OMAPLFB_UPDATE_MODE_AUTO; -+ } -+ break; -+ } -+ } -+ -+ return eMode; -+#else /* defined(PVR_OMAPLFB_DRM_FB) */ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0) -+ struct omap_dss_device *psDSSDev = fb2display(psDevInfo->psLINFBInfo); -+ OMAP_DSS_DRIVER(psDSSDrv, psDSSDev); -+ -+ enum omap_dss_update_mode eMode; -+ -+ if (psDSSDrv == NULL) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: No DSS device\n", __FUNCTION__, psDevInfo->uiFBDevID)); -+ return OMAPLFB_UPDATE_MODE_UNDEFINED; -+ } -+ -+ if (psDSSDrv->get_update_mode == NULL) -+ { -+ if (strcmp(psDSSDev->name, "hdmi") == 0) -+ { -+ return OMAPLFB_UPDATE_MODE_AUTO; -+ } -+// DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: No get_update_mode function\n", __FUNCTION__, psDevInfo->uiFBDevID)); -+// return OMAPLFB_UPDATE_MODE_UNDEFINED; -+ return OMAPLFB_UPDATE_MODE_AUTO; -+ } -+ -+ eMode = psDSSDrv->get_update_mode(psDSSDev); -+ if (!OMAPLFBValidateDSSUpdateMode(eMode)) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Unknown update mode (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, (int)eMode)); -+ } -+ -+ return OMAPLFBFromDSSUpdateMode(eMode); -+#else -+ return OMAPLFB_UPDATE_MODE_AUTO; -+#endif -+#endif /* defined(PVR_OMAPLFB_DRM_FB) */ -+} -+ -+/* Set display update mode */ -+OMAPLFB_BOOL OMAPLFBSetUpdateMode(OMAPLFB_DEVINFO *psDevInfo, OMAPLFB_UPDATE_MODE eMode) -+{ -+#if defined(PVR_OMAPLFB_DRM_FB) -+ struct drm_connector *psConnector; -+ enum omap_dss_update_mode eDSSMode; -+ OMAPLFB_BOOL bSuccess = OMAPLFB_FALSE; -+ OMAPLFB_BOOL bFailure = OMAPLFB_FALSE; -+ -+ if (!OMAPLFBValidateUpdateMode(eMode)) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Unknown update mode (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, (int)eMode)); -+ return OMAPLFB_FALSE; -+ } -+ eDSSMode = OMAPLFBToDSSUpdateMode(eMode); -+ -+ for (psConnector = NULL; -+ (psConnector = omap_fbdev_get_next_connector(psDevInfo->psLINFBInfo, psConnector)) != NULL;) -+ { -+ int iRes = omap_connector_set_update_mode(psConnector, eDSSMode); -+ OMAPLFB_BOOL bRes = (iRes == 0); -+ -+ -+ bSuccess |= bRes; -+ bFailure |= !bRes; -+ } -+ -+ if (!bFailure) -+ { -+ if (!bSuccess) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: No screens\n", __FUNCTION__, psDevInfo->uiFBDevID)); -+ } -+ -+ return OMAPLFB_TRUE; -+ } -+ -+ if (!bSuccess) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Couldn't set %s for any screen\n", __FUNCTION__, psDevInfo->uiFBDevID, OMAPLFBUpdateModeToString(eMode))); -+ return OMAPLFB_FALSE; -+ } -+ -+ if (eMode == OMAPLFB_UPDATE_MODE_AUTO) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Couldn't set %s for all screens\n", __FUNCTION__, psDevInfo->uiFBDevID, OMAPLFBUpdateModeToString(eMode))); -+ return OMAPLFB_FALSE; -+ } -+ -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": %s: Device %u: %s set for some screens\n", __FUNCTION__, psDevInfo->uiFBDevID, OMAPLFBUpdateModeToString(eMode))); -+ -+ return OMAPLFB_TRUE; -+#else /* defined(PVR_OMAPLFB_DRM_FB) */ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0) -+ struct omap_dss_device *psDSSDev = fb2display(psDevInfo->psLINFBInfo); -+ OMAP_DSS_DRIVER(psDSSDrv, psDSSDev); -+ enum omap_dss_update_mode eDSSMode; -+ int res; -+ -+ if (psDSSDrv == NULL || psDSSDrv->set_update_mode == NULL) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Can't set update mode\n", __FUNCTION__, psDevInfo->uiFBDevID)); -+ return OMAPLFB_FALSE; -+ } -+ -+ if (!OMAPLFBValidateUpdateMode(eMode)) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Unknown update mode (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, (int)eMode)); -+ return OMAPLFB_FALSE; -+ } -+ eDSSMode = OMAPLFBToDSSUpdateMode(eMode); -+ -+ res = psDSSDrv->set_update_mode(psDSSDev, eDSSMode); -+ if (res != 0) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: set_update_mode (%s) failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, OMAPLFBDSSUpdateModeToString(eDSSMode), res)); -+ } -+ -+ return (res == 0); -+#else -+return 1; -+#endif -+#endif /* defined(PVR_OMAPLFB_DRM_FB) */ -+ -+} -+//#else /* defined(PVR_OMAPLFB_HAS_UPDATE_MODE) */ -+ -+//OMAPLFB_UPDATE_MODE OMAPLFBGetUpdateMode(OMAPLFB_DEVINFO *psDevInfo) -+//{ -+// return OMAPLFB_UPDATE_MODE_UNDEFINED; -+//} -+ -+//#endif /* defined(PVR_OMAPLFB_HAS_UPDATE_MODE) */ -+ -+#if defined(DEBUG) -+void OMAPLFBPrintInfo(OMAPLFB_DEVINFO *psDevInfo) -+{ -+#if defined(PVR_OMAPLFB_DRM_FB) -+ struct drm_connector *psConnector; -+ unsigned uConnectors; -+ unsigned uConnector; -+ -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": Device %u: DRM framebuffer\n", psDevInfo->uiFBDevID)); -+ -+ for (psConnector = NULL, uConnectors = 0; -+ (psConnector = omap_fbdev_get_next_connector(psDevInfo->psLINFBInfo, psConnector)) != NULL;) -+ { -+ uConnectors++; -+ } -+ -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": Device %u: Number of screens (DRM connectors): %u\n", psDevInfo->uiFBDevID, uConnectors)); -+ -+ if (uConnectors == 0) -+ { -+ return; -+ } -+ -+ for (psConnector = NULL, uConnector = 0; -+ (psConnector = omap_fbdev_get_next_connector(psDevInfo->psLINFBInfo, psConnector)) != NULL; uConnector++) -+ { -+ enum omap_dss_update_mode eMode = omap_connector_get_update_mode(psConnector); -+ -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": Device %u: Screen %u: %s (%d)\n", psDevInfo->uiFBDevID, uConnector, OMAPLFBDSSUpdateModeToString(eMode), (int)eMode)); -+ -+ } -+#else /* defined(PVR_OMAPLFB_DRM_FB) */ -+//#if defined(PVR_OMAPLFB_HAS_UPDATE_MODE) -+ OMAPLFB_UPDATE_MODE eMode = OMAPLFBGetUpdateMode(psDevInfo); -+ -+ //DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": Device %u: %s\n", psDevInfo->uiFBDevID, OMAPLFBUpdateModeToString(eMode))); -+//#endif -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": Device %u: non-DRM framebuffer\n", psDevInfo->uiFBDevID)); -+ -+#endif /* defined(PVR_OMAPLFB_DRM_FB) */ -+} -+#endif /* defined(DEBUG) */ -+ -+/* Wait for VSync */ -+OMAPLFB_BOOL OMAPLFBWaitForVSync(OMAPLFB_DEVINFO *psDevInfo) -+{ -+#if defined(PVR_OMAPLFB_DRM_FB) -+ struct drm_connector *psConnector; -+ -+ for (psConnector = NULL; -+ (psConnector = omap_fbdev_get_next_connector(psDevInfo->psLINFBInfo, psConnector)) != NULL;) -+ { -+ (void) omap_encoder_wait_for_vsync(psConnector->encoder); -+ } -+ -+ return OMAPLFB_TRUE; -+#else /* defined(PVR_OMAPLFB_DRM_FB) */ -+#if FBDEV_PRESENT -+ struct omap_dss_device *psDSSDev = fb2display(psDevInfo->psLINFBInfo); -+ OMAP_DSS_MANAGER(psDSSMan, psDSSDev); -+ -+ if (psDSSMan != NULL && WAIT_FOR_VSYNC(psDSSMan) != NULL) -+ { -+ int res = WAIT_FOR_VSYNC(psDSSMan)(psDSSMan); -+ if (res != 0) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Wait for vsync failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, res)); -+ return OMAPLFB_FALSE; -+ } -+ } -+#endif -+ return OMAPLFB_TRUE; -+#endif /* defined(PVR_OMAPLFB_DRM_FB) */ -+} -+ -+/* -+ * Wait for screen to update. If the screen is in manual or auto update -+ * mode, we can call this function to wait for the screen to update. -+ */ -+OMAPLFB_BOOL OMAPLFBManualSync(OMAPLFB_DEVINFO *psDevInfo) -+{ -+#if defined(PVR_OMAPLFB_DRM_FB) -+ struct drm_connector *psConnector; -+ -+ for (psConnector = NULL; -+ (psConnector = omap_fbdev_get_next_connector(psDevInfo->psLINFBInfo, psConnector)) != NULL; ) -+ { -+ /* Try manual sync first, then try wait for vsync */ -+ if (omap_connector_sync(psConnector) != 0) -+ { -+ (void) omap_encoder_wait_for_vsync(psConnector->encoder); -+ } -+ } -+ -+ return OMAPLFB_TRUE; -+#else /* defined(PVR_OMAPLFB_DRM_FB) */ -+ -+#if 0 -+ struct omap_dss_device *psDSSDev = fb2display(psDevInfo->psLINFBInfo); -+ OMAP_DSS_DRIVER(psDSSDrv, psDSSDev); -+ -+ if (psDSSDrv != NULL && psDSSDrv->sync != NULL) -+ { -+ int res = psDSSDrv->sync(psDSSDev); -+ if (res != 0) -+ { -+ printk(KERN_ERR DRIVER_PREFIX ": %s: Device %u: Sync failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, res); -+ return OMAPLFB_FALSE; -+ } -+ } -+#endif -+ return OMAPLFB_TRUE; -+#endif /* defined(PVR_OMAPLFB_DRM_FB) */ -+} -+ -+/* -+ * If the screen is manual or auto update mode, wait for the screen to -+ * update. -+ */ -+OMAPLFB_BOOL OMAPLFBCheckModeAndSync(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ OMAPLFB_UPDATE_MODE eMode = OMAPLFBGetUpdateMode(psDevInfo); -+ -+ switch(eMode) -+ { -+ case OMAPLFB_UPDATE_MODE_AUTO: -+ case OMAPLFB_UPDATE_MODE_MANUAL: -+ return OMAPLFBManualSync(psDevInfo); -+ default: -+ break; -+ } -+ -+ return OMAPLFB_TRUE; -+} -+ -+/* Linux Framebuffer event notification handler */ -+static int OMAPLFBFrameBufferEvents(struct notifier_block *psNotif, -+ unsigned long event, void *data) -+{ -+ OMAPLFB_DEVINFO *psDevInfo; -+ struct fb_event *psFBEvent = (struct fb_event *)data; -+ struct fb_info *psFBInfo = psFBEvent->info; -+ OMAPLFB_BOOL bBlanked; -+ -+ /* Only interested in blanking events */ -+ if (event != FB_EVENT_BLANK) -+ { -+ return 0; -+ } -+ -+ bBlanked = (*(IMG_INT *)psFBEvent->data != 0) ? OMAPLFB_TRUE: OMAPLFB_FALSE; -+ -+ psDevInfo = OMAPLFBGetDevInfoPtr(psFBInfo->node); -+ -+#if 0 -+ if (psDevInfo != NULL) -+ { -+ if (bBlanked) -+ { -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": %s: Device %u: Blank event received\n", __FUNCTION__, psDevInfo->uiFBDevID)); -+ } -+ else -+ { -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": %s: Device %u: Unblank event received\n", __FUNCTION__, psDevInfo->uiFBDevID)); -+ } -+ } -+ else -+ { -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": %s: Device %u: Blank/Unblank event for unknown framebuffer\n", __FUNCTION__, psFBInfo->node)); -+ } -+#endif -+ -+ if (psDevInfo != NULL) -+ { -+ OMAPLFBAtomicBoolSet(&psDevInfo->sBlanked, bBlanked); -+ OMAPLFBAtomicIntInc(&psDevInfo->sBlankEvents); -+ } -+ -+ return 0; -+} -+ -+/* Unblank the screen */ -+/* -+ * Blank or Unblank the screen. To be called where the unblank is being done -+ * in user context. -+ */ -+static OMAPLFB_ERROR OMAPLFBBlankOrUnblankDisplay(OMAPLFB_DEVINFO *psDevInfo, IMG_BOOL bBlank) -+{ -+#ifdef FBDEV_PRESENT -+ int res; -+ if (!lock_fb_info(psDevInfo->psLINFBInfo)) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ ": %s: Device %u: Couldn't lock FB info\n", __FUNCTION__, psDevInfo->uiFBDevID); -+ return (OMAPLFB_ERROR_GENERIC); -+ } -+ /* -+ * FBINFO_MISC_USEREVENT is set to avoid a deadlock resulting from -+ * fb_blank being called recursively due from within the fb_blank event -+ * notification. -+ */ -+ -+ OMAPLFB_CONSOLE_LOCK(); -+ psDevInfo->psLINFBInfo->flags |= FBINFO_MISC_USEREVENT; -+ res = fb_blank(psDevInfo->psLINFBInfo, bBlank ? 1 : 0); -+ psDevInfo->psLINFBInfo->flags &= ~FBINFO_MISC_USEREVENT; -+ -+ OMAPLFB_CONSOLE_UNLOCK(); -+ unlock_fb_info(psDevInfo->psLINFBInfo); -+ if (res != 0 && res != -EINVAL) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ ": %s: Device %u: fb_blank failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, res); -+ return (OMAPLFB_ERROR_GENERIC); -+ } -+#endif -+ return (OMAPLFB_OK); -+} -+ -+/* Unblank the screen */ -+OMAPLFB_ERROR OMAPLFBUnblankDisplay(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ return OMAPLFBBlankOrUnblankDisplay(psDevInfo, IMG_FALSE); -+} -+ -+#ifdef CONFIG_HAS_EARLYSUSPEND -+static void OMAPLFBEarlyUnblankDisplay(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ OMAPLFB_CONSOLE_LOCK(); -+ fb_blank(psDevInfo->psLINFBInfo, 0); -+ OMAPLFB_CONSOLE_UNLOCK(); -+} -+ -+ -+/* Blank the screen */ -+static void OMAPLFBEarlyBlankDisplay(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ OMAPLFB_CONSOLE_LOCK(); -+ fb_blank(psDevInfo->psLINFBInfo, 1); -+ OMAPLFB_CONSOLE_UNLOCK(); -+} -+ -+static void OMAPLFBEarlySuspendHandler(struct early_suspend *h) -+{ -+ unsigned uiMaxFBDevIDPlusOne = OMAPLFBMaxFBDevIDPlusOne(); -+ unsigned i; -+ -+ for (i=0; i < uiMaxFBDevIDPlusOne; i++) -+ { -+ OMAPLFB_DEVINFO *psDevInfo = OMAPLFBGetDevInfoPtr(i); -+ -+ if (psDevInfo != NULL) -+ { -+ OMAPLFBAtomicBoolSet(&psDevInfo->sEarlySuspendFlag, OMAPLFB_TRUE); -+ OMAPLFBEarlyBlankDisplay(psDevInfo); -+ } -+ } -+} -+ -+static void OMAPLFBEarlyResumeHandler(struct early_suspend *h) -+{ -+ unsigned uiMaxFBDevIDPlusOne = OMAPLFBMaxFBDevIDPlusOne(); -+ unsigned i; -+ -+ for (i=0; i < uiMaxFBDevIDPlusOne; i++) -+ { -+ OMAPLFB_DEVINFO *psDevInfo = OMAPLFBGetDevInfoPtr(i); -+ -+ if (psDevInfo != NULL) -+ { -+ OMAPLFBEarlyUnblankDisplay(psDevInfo); -+ OMAPLFBAtomicBoolSet(&psDevInfo->sEarlySuspendFlag, OMAPLFB_FALSE); -+ } -+ } -+} -+ -+#endif /* CONFIG_HAS_EARLYSUSPEND */ -+ -+/* Set up Linux Framebuffer event notification */ -+OMAPLFB_ERROR OMAPLFBEnableLFBEventNotification(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ int res; -+ OMAPLFB_ERROR eError; -+ -+ /* Set up Linux Framebuffer event notification */ -+ memset(&psDevInfo->sLINNotifBlock, 0, sizeof(psDevInfo->sLINNotifBlock)); -+ -+ psDevInfo->sLINNotifBlock.notifier_call = OMAPLFBFrameBufferEvents; -+ -+ OMAPLFBAtomicBoolSet(&psDevInfo->sBlanked, OMAPLFB_FALSE); -+ OMAPLFBAtomicIntSet(&psDevInfo->sBlankEvents, 0); -+ -+ res = fb_register_client(&psDevInfo->sLINNotifBlock); -+ if (res != 0) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ ": %s: Device %u: fb_register_client failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, res); -+ -+ return (OMAPLFB_ERROR_GENERIC); -+ } -+ -+ eError = OMAPLFBUnblankDisplay(psDevInfo); -+ if (eError != OMAPLFB_OK) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ ": %s: Device %u: UnblankDisplay failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, eError); -+ return eError; -+ } -+ -+#ifdef CONFIG_HAS_EARLYSUSPEND -+ psDevInfo->sEarlySuspend.suspend = OMAPLFBEarlySuspendHandler; -+ psDevInfo->sEarlySuspend.resume = OMAPLFBEarlyResumeHandler; -+ psDevInfo->sEarlySuspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB + 1; -+ register_early_suspend(&psDevInfo->sEarlySuspend); -+#endif -+ -+ return (OMAPLFB_OK); -+} -+ -+/* Disable Linux Framebuffer event notification */ -+OMAPLFB_ERROR OMAPLFBDisableLFBEventNotification(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ int res; -+ -+#ifdef CONFIG_HAS_EARLYSUSPEND -+ unregister_early_suspend(&psDevInfo->sEarlySuspend); -+#endif -+ -+ /* Unregister for Framebuffer events */ -+ res = fb_unregister_client(&psDevInfo->sLINNotifBlock); -+ if (res != 0) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ ": %s: Device %u: fb_unregister_client failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, res); -+ return (OMAPLFB_ERROR_GENERIC); -+ } -+ -+ OMAPLFBAtomicBoolSet(&psDevInfo->sBlanked, OMAPLFB_FALSE); -+ -+ return (OMAPLFB_OK); -+} -+ -+#if defined(SUPPORT_DRI_DRM) && defined(PVR_DISPLAY_CONTROLLER_DRM_IOCTL) -+static OMAPLFB_DEVINFO *OMAPLFBPVRDevIDToDevInfo(unsigned uiPVRDevID) -+{ -+ unsigned uiMaxFBDevIDPlusOne = OMAPLFBMaxFBDevIDPlusOne(); -+ unsigned i; -+ -+ for (i=0; i < uiMaxFBDevIDPlusOne; i++) -+ { -+ OMAPLFB_DEVINFO *psDevInfo = OMAPLFBGetDevInfoPtr(i); -+ -+ if (psDevInfo->uiPVRDevID == uiPVRDevID) -+ { -+ return psDevInfo; -+ } -+ } -+ -+ printk(KERN_ERR DRIVER_PREFIX -+ ": %s: PVR Device %u: Couldn't find device\n", __FUNCTION__, uiPVRDevID); -+ -+ return NULL; -+} -+ -+int PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Ioctl)(struct drm_device unref__ *dev, void *arg, struct drm_file unref__ *pFile) -+{ -+ uint32_t *puiArgs; -+ uint32_t uiCmd; -+ unsigned uiPVRDevID; -+ int ret = 0; -+ OMAPLFB_DEVINFO *psDevInfo; -+ -+ if (arg == NULL) -+ { -+ return -EFAULT; -+ } -+ -+ puiArgs = (uint32_t *)arg; -+ uiCmd = puiArgs[PVR_DRM_DISP_ARG_CMD]; -+ uiPVRDevID = puiArgs[PVR_DRM_DISP_ARG_DEV]; -+ -+ psDevInfo = OMAPLFBPVRDevIDToDevInfo(uiPVRDevID); -+ if (psDevInfo == NULL) -+ { -+ return -EINVAL; -+ } -+ -+ -+ switch (uiCmd) -+ { -+ case PVR_DRM_DISP_CMD_LEAVE_VT: -+ case PVR_DRM_DISP_CMD_ENTER_VT: -+ { -+ OMAPLFB_BOOL bLeaveVT = (uiCmd == PVR_DRM_DISP_CMD_LEAVE_VT); -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: PVR Device %u: %s\n", -+ __FUNCTION__, uiPVRDevID, -+ bLeaveVT ? "Leave VT" : "Enter VT")); -+ -+ OMAPLFBCreateSwapChainLock(psDevInfo); -+ -+ OMAPLFBAtomicBoolSet(&psDevInfo->sLeaveVT, bLeaveVT); -+ if (psDevInfo->psSwapChain != NULL) -+ { -+ flush_workqueue(psDevInfo->psSwapChain->psWorkQueue); -+ -+ if (bLeaveVT) -+ { -+ OMAPLFBFlip(psDevInfo, &psDevInfo->sSystemBuffer); -+ (void) OMAPLFBCheckModeAndSync(psDevInfo); -+ } -+ } -+ -+ OMAPLFBCreateSwapChainUnLock(psDevInfo); -+ (void) OMAPLFBUnblankDisplay(psDevInfo); -+ break; -+ } -+ case PVR_DRM_DISP_CMD_ON: -+ case PVR_DRM_DISP_CMD_STANDBY: -+ case PVR_DRM_DISP_CMD_SUSPEND: -+ case PVR_DRM_DISP_CMD_OFF: -+ { -+ int iFBMode; -+#if defined(DEBUG) -+ { -+ const char *pszMode; -+ switch(uiCmd) -+ { -+ case PVR_DRM_DISP_CMD_ON: -+ pszMode = "On"; -+ break; -+ case PVR_DRM_DISP_CMD_STANDBY: -+ pszMode = "Standby"; -+ break; -+ case PVR_DRM_DISP_CMD_SUSPEND: -+ pszMode = "Suspend"; -+ break; -+ case PVR_DRM_DISP_CMD_OFF: -+ pszMode = "Off"; -+ break; -+ default: -+ pszMode = "(Unknown Mode)"; -+ break; -+ } -+ printk(KERN_WARNING DRIVER_PREFIX ": %s: PVR Device %u: Display %s\n", -+ __FUNCTION__, uiPVRDevID, pszMode); -+ } -+#endif -+ switch(uiCmd) -+ { -+ case PVR_DRM_DISP_CMD_ON: -+ iFBMode = FB_BLANK_UNBLANK; -+ break; -+ case PVR_DRM_DISP_CMD_STANDBY: -+ iFBMode = FB_BLANK_HSYNC_SUSPEND; -+ break; -+ case PVR_DRM_DISP_CMD_SUSPEND: -+ iFBMode = FB_BLANK_VSYNC_SUSPEND; -+ break; -+ case PVR_DRM_DISP_CMD_OFF: -+ iFBMode = FB_BLANK_POWERDOWN; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ OMAPLFBCreateSwapChainLock(psDevInfo); -+ -+ if (psDevInfo->psSwapChain != NULL) -+ { -+ flush_workqueue(psDevInfo->psSwapChain->psWorkQueue); -+ } -+ -+ if (!lock_fb_info(psDevInfo->psLINFBInfo)) -+ { -+ ret = -ENODEV; -+ } -+ else -+ { -+ OMAPLFB_CONSOLE_LOCK(); -+ psDevInfo->psLINFBInfo->flags |= FBINFO_MISC_USEREVENT; -+ ret = fb_blank(psDevInfo->psLINFBInfo, iFBMode); -+ psDevInfo->psLINFBInfo->flags &= ~FBINFO_MISC_USEREVENT; -+ OMAPLFB_CONSOLE_UNLOCK(); -+ unlock_fb_info(psDevInfo->psLINFBInfo); -+ } -+ -+ OMAPLFBCreateSwapChainUnLock(psDevInfo); -+ -+ break; -+ } -+ default: -+ { -+ ret = -EINVAL; -+ break; -+ } -+ } -+ -+ return ret; -+} -+#endif -+ -+/* Insert the driver into the kernel */ -+#if defined(SUPPORT_DRI_DRM) -+int PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Init)(struct drm_device unref__ *dev) -+#else -+static int __init OMAPLFB_Init(void) -+#endif -+{ -+ -+ if(OMAPLFBInit() != OMAPLFB_OK) -+ { -+ printk(KERN_ERR DRIVER_PREFIX ": %s: OMAPLFBInit failed\n", __FUNCTION__); -+ return -ENODEV; -+ } -+ -+ return 0; -+ -+} -+ -+/* Remove the driver from the kernel */ -+#if defined(SUPPORT_DRI_DRM) -+void PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Cleanup)(struct drm_device unref__ *dev) -+#else -+static void __exit OMAPLFB_Cleanup(void) -+#endif -+{ -+ if(OMAPLFBDeInit() != OMAPLFB_OK) -+ { -+ printk(KERN_ERR DRIVER_PREFIX ": %s: OMAPLFBDeInit failed\n", __FUNCTION__); -+ } -+} -+ -+#if !defined(SUPPORT_DRI_DRM) -+/* -+ These macro calls define the initialisation and removal functions of the -+ driver. Although they are prefixed `module_', they apply when compiling -+ statically as well; in both cases they define the function the kernel will -+ run to start/stop the driver. -+*/ -+late_initcall(OMAPLFB_Init); -+module_exit(OMAPLFB_Cleanup); -+#endif -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti335x_linux/3rdparty_dc_drm_shared.h b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti335x_linux/3rdparty_dc_drm_shared.h -new file mode 100644 -index 0000000..b522c41 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti335x_linux/3rdparty_dc_drm_shared.h -@@ -0,0 +1,64 @@ -+/*************************************************************************/ /*! -+@Title OMAP Linux display driver shared DRM structures -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description OMAP Linux display driver DRM structures shared between -+ kernel and user space. -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+#ifndef __3RDPARTY_DC_DRM_SHARED_H__ -+#define __3RDPARTY_DC_DRM_SHARED_H__ -+#if defined(SUPPORT_DRI_DRM) -+ -+#define PVR_DRM_DISP_CMD_ENTER_VT 1 -+#define PVR_DRM_DISP_CMD_LEAVE_VT 2 -+ -+#define PVR_DRM_DISP_CMD_ON 3 -+#define PVR_DRM_DISP_CMD_STANDBY 4 -+#define PVR_DRM_DISP_CMD_SUSPEND 5 -+#define PVR_DRM_DISP_CMD_OFF 6 -+ -+#define PVR_DRM_DISP_ARG_CMD 0 -+#define PVR_DRM_DISP_ARG_DEV 1 -+#define PVR_DRM_DISP_NUM_ARGS 2 -+ -+#endif /* defined(SUPPORT_DRI_DRM) */ -+#endif /* __3RDPARTY_DC_DRM_SHARED_H__ */ -+ -+/****************************************************************************** -+ End of file (3rdparty_dc_drm_shared.h) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti335x_linux/Kbuild b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti335x_linux/Kbuild -new file mode 100644 -index 0000000..1ae23593 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti335x_linux/Kbuild -@@ -0,0 +1,32 @@ -+SYS_USING_INTERRUPTS = 1 -+SUPPORT_OMAP3430_OMAPFB3 =1 -+SUPPORT_TI_DSS_FW = 0 -+PVR_LINUX_USING_WORKQUEUES = 1 -+ -+SYS_CFLAGS.$(SYS_USING_INTERRUPTS) += -DSYS_USING_INTERRUPTS -+SYS_CFLAGS.$(SUPPORT_OMAP3430_OMAPFB3) += -DSUPPORT_OMAP3430_OMAPFB3 -+SYS_CFLAGS.$(SUPPORT_TI_DSS_FW) += -DSUPPORT_TI_DSS_FW -+SYS_CFLAGS.$(PVR_LINUX_USING_WORKQUEUES) += -DPVR_LINUX_USING_WORKQUEUES -+SYS_CFLAGS += -DDISPLAY_CONTROLLER=omaplfb -+ -+EXTRA_CFLAGS = -DLINUX \ -+ -DCONFIG_OMAP2_DSS \ -+ -I$(PVR_BUILD_DIR)/include4 \ -+ -I$(PVR_BUILD_DIR)/services4/include \ -+ -I$(PVR_BUILD_DIR)/services4/system/$(PVR_SYSTEM) \ -+ -I$(KERNELDIR)/drivers/video/omap2 \ -+ -I$(PVR_BUILD_DIR)/services4/system/include \ -+ $(SYS_CFLAGS.1) \ -+ -+ifneq ($(FBDEV),no) -+EXTRA_CFLAGS += -DFBDEV_PRESENT -+endif -+ -+ifeq ($(SUPPORT_XORG),1) -+EXTRA_CFLAGS += -DSUPPORT_DRI_DRM -+EXTRA_CFLAGS += -DPVR_DISPLAY_CONTROLLER_DRM_IOCTL -+endif -+ -+ -+obj-m := omaplfb.o -+omaplfb-y := omaplfb_displayclass.o omaplfb_linux.o -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti335x_linux/Kbuild.mk b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti335x_linux/Kbuild.mk -new file mode 100644 -index 0000000..0310b95 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti335x_linux/Kbuild.mk -@@ -0,0 +1,48 @@ -+########################################################################### ### -+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+#@License Dual MIT/GPLv2 -+# -+# The contents of this file are subject to the MIT license as set out below. -+# -+# Permission is hereby granted, free of charge, to any person obtaining a copy -+# of this software and associated documentation files (the "Software"), to deal -+# in the Software without restriction, including without limitation the rights -+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+# copies of the Software, and to permit persons to whom the Software is -+# furnished to do so, subject to the following conditions: -+# -+# The above copyright notice and this permission notice shall be included in -+# all copies or substantial portions of the Software. -+# -+# Alternatively, the contents of this file may be used under the terms of -+# the GNU General Public License Version 2 ("GPL") in which case the provisions -+# of GPL are applicable instead of those above. -+# -+# If you wish to allow use of your version of this file only under the terms of -+# GPL, and not to allow others to use your version of this file under the terms -+# of the MIT license, indicate your decision by deleting the provisions above -+# and replace them with the notice and other provisions required by GPL as set -+# out in the file called "GPL-COPYING" included in this distribution. If you do -+# not delete the provisions above, a recipient may use your version of this file -+# under the terms of either the MIT license or GPL. -+# -+# This License is also included in this distribution in the file called -+# "MIT-COPYING". -+# -+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+### ########################################################################### -+ -+ccflags-y += \ -+ -I$(TOP)/services4/3rdparty/dc_omapfb3_linux \ -+ -Idrivers/video/omap2 \ -+ -Iarch/arm/plat-omap/include -+ -+omaplfb-y += \ -+ services4/3rdparty/dc_omapfb3_linux/omaplfb_displayclass.o \ -+ services4/3rdparty/dc_omapfb3_linux/omaplfb_linux.o -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti335x_linux/Linux.mk b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti335x_linux/Linux.mk -new file mode 100644 -index 0000000..4008b4d ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti335x_linux/Linux.mk -@@ -0,0 +1,45 @@ -+########################################################################### ### -+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+#@License Dual MIT/GPLv2 -+# -+# The contents of this file are subject to the MIT license as set out below. -+# -+# Permission is hereby granted, free of charge, to any person obtaining a copy -+# of this software and associated documentation files (the "Software"), to deal -+# in the Software without restriction, including without limitation the rights -+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+# copies of the Software, and to permit persons to whom the Software is -+# furnished to do so, subject to the following conditions: -+# -+# The above copyright notice and this permission notice shall be included in -+# all copies or substantial portions of the Software. -+# -+# Alternatively, the contents of this file may be used under the terms of -+# the GNU General Public License Version 2 ("GPL") in which case the provisions -+# of GPL are applicable instead of those above. -+# -+# If you wish to allow use of your version of this file only under the terms of -+# GPL, and not to allow others to use your version of this file under the terms -+# of the MIT license, indicate your decision by deleting the provisions above -+# and replace them with the notice and other provisions required by GPL as set -+# out in the file called "GPL-COPYING" included in this distribution. If you do -+# not delete the provisions above, a recipient may use your version of this file -+# under the terms of either the MIT license or GPL. -+# -+# This License is also included in this distribution in the file called -+# "MIT-COPYING". -+# -+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+### ########################################################################### -+ -+modules := dc_omapfb3_linux -+ -+dc_omapfb3_linux_type := kernel_module -+dc_omapfb3_linux_target := omaplfb.ko -+dc_omapfb3_linux_makefile := $(THIS_DIR)/Kbuild.mk -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti335x_linux/omaplfb.h b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti335x_linux/omaplfb.h -new file mode 100644 -index 0000000..e7b4fa2 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti335x_linux/omaplfb.h -@@ -0,0 +1,331 @@ -+/*************************************************************************/ /*! -+@Title OMAP Linux display driver structures and prototypes -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+#ifndef __OMAPLFB_H__ -+#define __OMAPLFB_H__ -+ -+#include <linux/version.h> -+ -+#include <asm/atomic.h> -+ -+#include <linux/kernel.h> -+#include <linux/console.h> -+#include <linux/fb.h> -+#include <linux/module.h> -+#include <linux/string.h> -+#include <linux/notifier.h> -+#include <linux/mutex.h> -+ -+#ifdef CONFIG_HAS_EARLYSUSPEND -+#include <linux/earlysuspend.h> -+#endif -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) -+#define OMAPLFB_CONSOLE_LOCK() console_lock() -+#define OMAPLFB_CONSOLE_UNLOCK() console_unlock() -+#else -+#define OMAPLFB_CONSOLE_LOCK() acquire_console_sem() -+#define OMAPLFB_CONSOLE_UNLOCK() release_console_sem() -+#endif -+ -+#if defined(CONFIG_ION_OMAP) -+#include <linux/ion.h> -+#include <linux/omap_ion.h> -+#endif /* defined(CONFIG_ION_OMAP) */ -+ -+#define unref__ __attribute__ ((unused)) -+ -+typedef void * OMAPLFB_HANDLE; -+ -+typedef bool OMAPLFB_BOOL, *OMAPLFB_PBOOL; -+#define OMAPLFB_FALSE false -+#define OMAPLFB_TRUE true -+ -+typedef atomic_t OMAPLFB_ATOMIC_BOOL; -+ -+typedef atomic_t OMAPLFB_ATOMIC_INT; -+ -+/* OMAPLFB buffer structure */ -+typedef struct OMAPLFB_BUFFER_TAG -+{ -+ struct OMAPLFB_BUFFER_TAG *psNext; -+ struct OMAPLFB_DEVINFO_TAG *psDevInfo; -+ -+ struct work_struct sWork; -+ -+ /* Position of this buffer in the virtual framebuffer */ -+ unsigned long ulYOffset; -+ -+ /* IMG structures used, to minimise API function code */ -+ /* replace with own structures where necessary */ -+ IMG_SYS_PHYADDR sSysAddr; -+ IMG_CPU_VIRTADDR sCPUVAddr; -+ PVRSRV_SYNC_DATA *psSyncData; -+ -+ OMAPLFB_HANDLE hCmdComplete; -+ unsigned long ulSwapInterval; -+} OMAPLFB_BUFFER; -+ -+/* OMAPLFB swapchain structure */ -+typedef struct OMAPLFB_SWAPCHAIN_TAG -+{ -+ /* Swap chain ID */ -+ unsigned int uiSwapChainID; -+ -+ /* number of buffers in swapchain */ -+ unsigned long ulBufferCount; -+ -+ /* list of buffers in the swapchain */ -+ OMAPLFB_BUFFER *psBuffer; -+ -+ /* Swap chain work queue */ -+ struct workqueue_struct *psWorkQueue; -+ -+ /* -+ * Set if we didn't manage to wait for VSync on last swap, -+ * or if we think we need to wait for VSync on the next flip. -+ * The flag helps to avoid jitter when the screen is -+ * unblanked, by forcing an extended wait for VSync before -+ * attempting the next flip. -+ */ -+ OMAPLFB_BOOL bNotVSynced; -+ -+ /* Previous number of blank events */ -+ int iBlankEvents; -+ -+ /* Framebuffer Device ID for messages (e.g. printk) */ -+ unsigned int uiFBDevID; -+} OMAPLFB_SWAPCHAIN; -+ -+typedef struct OMAPLFB_FBINFO_TAG -+{ -+ unsigned long ulFBSize; -+ unsigned long ulBufferSize; -+ unsigned long ulRoundedBufferSize; -+ unsigned long ulWidth; -+ unsigned long ulHeight; -+ unsigned long ulByteStride; -+ unsigned long ulPhysicalWidthmm; -+ unsigned long ulPhysicalHeightmm; -+ -+ /* IMG structures used, to minimise API function code */ -+ /* replace with own structures where necessary */ -+ IMG_SYS_PHYADDR sSysAddr;//system physical address -+ IMG_CPU_VIRTADDR sCPUVAddr; -+ -+ /* pixelformat of system/primary surface */ -+ PVRSRV_PIXEL_FORMAT ePixelFormat; -+ -+#if defined(CONFIG_DSSCOMP) -+ OMAPLFB_BOOL bIs2D; -+ IMG_SYS_PHYADDR *psPageList; -+ struct ion_handle *psIONHandle; -+ IMG_UINT32 uiBytesPerPixel; -+#endif -+} OMAPLFB_FBINFO; -+ -+/* kernel device information structure */ -+typedef struct OMAPLFB_DEVINFO_TAG -+{ -+ /* Framebuffer Device ID */ -+ unsigned int uiFBDevID; -+ -+ /* PVR Device ID */ -+ unsigned int uiPVRDevID; -+ -+ /* Swapchain create/destroy mutex */ -+ struct mutex sCreateSwapChainMutex; -+ -+ /* system surface info */ -+ OMAPLFB_BUFFER sSystemBuffer; -+ -+ /* jump table into PVR services */ -+ PVRSRV_DC_DISP2SRV_KMJTABLE sPVRJTable; -+ -+ /* jump table into DC */ -+ PVRSRV_DC_SRV2DISP_KMJTABLE sDCJTable; -+ -+ /* fb info structure */ -+ OMAPLFB_FBINFO sFBInfo; -+ -+ /* Only one swapchain supported by this device so hang it here */ -+ OMAPLFB_SWAPCHAIN *psSwapChain; -+ -+ /* Swap chain ID */ -+ unsigned int uiSwapChainID; -+ -+ /* True if PVR Services is flushing its command queues */ -+ OMAPLFB_ATOMIC_BOOL sFlushCommands; -+ -+ /* pointer to linux frame buffer information structure */ -+ struct fb_info *psLINFBInfo; -+ -+ /* Linux Framebuffer event notification block */ -+ struct notifier_block sLINNotifBlock; -+ -+ /* IMG structures used, to minimise API function code */ -+ /* replace with own structures where necessary */ -+ -+ /* Address of the surface being displayed */ -+ IMG_DEV_VIRTADDR sDisplayDevVAddr; -+ -+ DISPLAY_INFO sDisplayInfo; -+ -+ /* Display format */ -+ DISPLAY_FORMAT sDisplayFormat; -+ -+ /* Display dimensions */ -+ DISPLAY_DIMS sDisplayDim; -+ -+ /* True if screen is blanked */ -+ OMAPLFB_ATOMIC_BOOL sBlanked; -+ -+ /* Number of blank/unblank events */ -+ OMAPLFB_ATOMIC_INT sBlankEvents; -+ -+#ifdef CONFIG_HAS_EARLYSUSPEND -+ /* Set by early suspend */ -+ OMAPLFB_ATOMIC_BOOL sEarlySuspendFlag; -+ -+ struct early_suspend sEarlySuspend; -+#endif -+ -+#if defined(SUPPORT_DRI_DRM) -+ OMAPLFB_ATOMIC_BOOL sLeaveVT; -+#endif -+ -+#if defined(CONFIG_ION_OMAP) -+ struct ion_client *psIONClient; -+#endif -+ -+} OMAPLFB_DEVINFO; -+ -+#define OMAPLFB_PAGE_SIZE 4096 -+ -+/* DEBUG only printk */ -+#ifdef DEBUG -+#define DEBUG_PRINTK(x) printk x -+#else -+#define DEBUG_PRINTK(x) -+#endif -+ -+#define DISPLAY_DEVICE_NAME "PowerVR OMAP Linux Display Driver" -+#define DRVNAME "omaplfb" -+#define DEVNAME DRVNAME -+#define DRIVER_PREFIX DRVNAME -+ -+/*! -+ ***************************************************************************** -+ * Error values -+ *****************************************************************************/ -+typedef enum _OMAPLFB_ERROR_ -+{ -+ OMAPLFB_OK = 0, -+ OMAPLFB_ERROR_GENERIC = 1, -+ OMAPLFB_ERROR_OUT_OF_MEMORY = 2, -+ OMAPLFB_ERROR_TOO_FEW_BUFFERS = 3, -+ OMAPLFB_ERROR_INVALID_PARAMS = 4, -+ OMAPLFB_ERROR_INIT_FAILURE = 5, -+ OMAPLFB_ERROR_CANT_REGISTER_CALLBACK = 6, -+ OMAPLFB_ERROR_INVALID_DEVICE = 7, -+ OMAPLFB_ERROR_DEVICE_REGISTER_FAILED = 8, -+ OMAPLFB_ERROR_SET_UPDATE_MODE_FAILED = 9 -+} OMAPLFB_ERROR; -+ -+typedef enum _OMAPLFB_UPDATE_MODE_ -+{ -+ OMAPLFB_UPDATE_MODE_UNDEFINED = 0, -+ OMAPLFB_UPDATE_MODE_MANUAL = 1, -+ OMAPLFB_UPDATE_MODE_AUTO = 2, -+ OMAPLFB_UPDATE_MODE_DISABLED = 3 -+} OMAPLFB_UPDATE_MODE; -+ -+#ifndef UNREFERENCED_PARAMETER -+#define UNREFERENCED_PARAMETER(param) (param) = (param) -+#endif -+ -+OMAPLFB_ERROR OMAPLFBInit(void); -+OMAPLFB_ERROR OMAPLFBDeInit(void); -+ -+/* OS Specific APIs */ -+OMAPLFB_DEVINFO *OMAPLFBGetDevInfoPtr(unsigned uiFBDevID); -+unsigned OMAPLFBMaxFBDevIDPlusOne(void); -+void *OMAPLFBAllocKernelMem(unsigned long ulSize); -+void OMAPLFBFreeKernelMem(void *pvMem); -+OMAPLFB_ERROR OMAPLFBGetLibFuncAddr(char *szFunctionName, PFN_DC_GET_PVRJTABLE *ppfnFuncTable); -+OMAPLFB_ERROR OMAPLFBCreateSwapQueue (OMAPLFB_SWAPCHAIN *psSwapChain); -+void OMAPLFBDestroySwapQueue(OMAPLFB_SWAPCHAIN *psSwapChain); -+void OMAPLFBInitBufferForSwap(OMAPLFB_BUFFER *psBuffer); -+void OMAPLFBSwapHandler(OMAPLFB_BUFFER *psBuffer); -+void OMAPLFBQueueBufferForSwap(OMAPLFB_SWAPCHAIN *psSwapChain, OMAPLFB_BUFFER *psBuffer); -+void OMAPLFBFlip(OMAPLFB_DEVINFO *psDevInfo, OMAPLFB_BUFFER *psBuffer); -+OMAPLFB_UPDATE_MODE OMAPLFBGetUpdateMode(OMAPLFB_DEVINFO *psDevInfo); -+OMAPLFB_BOOL OMAPLFBSetUpdateMode(OMAPLFB_DEVINFO *psDevInfo, OMAPLFB_UPDATE_MODE eMode); -+OMAPLFB_BOOL OMAPLFBWaitForVSync(OMAPLFB_DEVINFO *psDevInfo); -+OMAPLFB_BOOL OMAPLFBManualSync(OMAPLFB_DEVINFO *psDevInfo); -+OMAPLFB_BOOL OMAPLFBCheckModeAndSync(OMAPLFB_DEVINFO *psDevInfo); -+OMAPLFB_ERROR OMAPLFBUnblankDisplay(OMAPLFB_DEVINFO *psDevInfo); -+OMAPLFB_ERROR OMAPLFBEnableLFBEventNotification(OMAPLFB_DEVINFO *psDevInfo); -+OMAPLFB_ERROR OMAPLFBDisableLFBEventNotification(OMAPLFB_DEVINFO *psDevInfo); -+void OMAPLFBCreateSwapChainLockInit(OMAPLFB_DEVINFO *psDevInfo); -+void OMAPLFBCreateSwapChainLockDeInit(OMAPLFB_DEVINFO *psDevInfo); -+void OMAPLFBCreateSwapChainLock(OMAPLFB_DEVINFO *psDevInfo); -+void OMAPLFBCreateSwapChainUnLock(OMAPLFB_DEVINFO *psDevInfo); -+void OMAPLFBAtomicBoolInit(OMAPLFB_ATOMIC_BOOL *psAtomic, OMAPLFB_BOOL bVal); -+void OMAPLFBAtomicBoolDeInit(OMAPLFB_ATOMIC_BOOL *psAtomic); -+void OMAPLFBAtomicBoolSet(OMAPLFB_ATOMIC_BOOL *psAtomic, OMAPLFB_BOOL bVal); -+OMAPLFB_BOOL OMAPLFBAtomicBoolRead(OMAPLFB_ATOMIC_BOOL *psAtomic); -+void OMAPLFBAtomicIntInit(OMAPLFB_ATOMIC_INT *psAtomic, int iVal); -+void OMAPLFBAtomicIntDeInit(OMAPLFB_ATOMIC_INT *psAtomic); -+void OMAPLFBAtomicIntSet(OMAPLFB_ATOMIC_INT *psAtomic, int iVal); -+int OMAPLFBAtomicIntRead(OMAPLFB_ATOMIC_INT *psAtomic); -+void OMAPLFBAtomicIntInc(OMAPLFB_ATOMIC_INT *psAtomic); -+ -+#if defined(DEBUG) -+void OMAPLFBPrintInfo(OMAPLFB_DEVINFO *psDevInfo); -+#else -+#define OMAPLFBPrintInfo(psDevInfo) -+#endif -+ -+#endif /* __OMAPLFB_H__ */ -+ -+/****************************************************************************** -+ End of file (omaplfb.h) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti335x_linux/omaplfb_displayclass.c b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti335x_linux/omaplfb_displayclass.c -new file mode 100644 -index 0000000..6bf410e ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti335x_linux/omaplfb_displayclass.c -@@ -0,0 +1,1876 @@ -+/*************************************************************************/ /*! -+@Title OMAP common display driver components -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+/************************************************************************** -+ The 3rd party driver is a specification of an API to integrate the IMG POWERVR -+ Services driver with 3rd Party display hardware. It is NOT a specification for -+ a display controller driver, rather a specification to extend the API for a -+ pre-existing driver for the display hardware. -+ -+ The 3rd party driver interface provides IMG POWERVR client drivers (e.g. PVR2D) -+ with an API abstraction of the system's underlying display hardware, allowing -+ the client drivers to indirectly control the display hardware and access its -+ associated memory. -+ -+ Functions of the API include -+ - query primary surface attributes (width, height, stride, pixel format, CPU -+ physical and virtual address) -+ - swap/flip chain creation and subsequent query of surface attributes -+ - asynchronous display surface flipping, taking account of asynchronous read -+ (flip) and write (render) operations to the display surface -+ -+ Note: having queried surface attributes the client drivers are able to map the -+ display memory to any IMG POWERVR Services device by calling -+ PVRSRVMapDeviceClassMemory with the display surface handle. -+ -+ This code is intended to be an example of how a pre-existing display driver may -+ be extended to support the 3rd Party Display interface to POWERVR Services -+ - IMG is not providing a display driver implementation. -+ **************************************************************************/ -+ -+/* -+ * OMAP Linux 3rd party display driver. -+ * This is based on the Generic PVR Linux Framebuffer 3rd party display -+ * driver, with OMAP specific extensions to support flipping. -+ */ -+ -+#include <linux/version.h> -+#include <linux/kernel.h> -+#include <linux/console.h> -+#include <linux/fb.h> -+#include <linux/module.h> -+#include <linux/string.h> -+#include <linux/notifier.h> -+ -+/* IMG services headers */ -+#include "img_defs.h" -+#include "servicesext.h" -+#include "kerneldisplay.h" -+#include "omaplfb.h" -+ -+#if defined(CONFIG_DSSCOMP) -+#if defined(CONFIG_ION_OMAP) -+extern struct ion_device *omap_ion_device; -+#else /* defined(CONFIG_ION_OMAP) */ -+#error CONFIG_DSSCOMP support requires CONFIG_ION_OMAP -+#endif /* defined(CONFIG_ION_OMAP) */ -+#if defined(CONFIG_DRM_OMAP_DMM_TILER) -+#include <../drivers/staging/omapdrm/omap_dmm_tiler.h> -+#include <../drivers/video/omap2/dsscomp/tiler-utils.h> -+#elif defined(CONFIG_TI_TILER) -+#include <mach/tiler.h> -+#else /* defined(CONFIG_DRM_OMAP_DMM_TILER) */ -+#error CONFIG_DSSCOMP support requires either \ -+ CONFIG_DRM_OMAP_DMM_TILER or CONFIG_TI_TILER -+#endif /* defined(CONFIG_DRM_OMAP_DMM_TILER) */ -+#include <video/dsscomp.h> -+#include <plat/dsscomp.h> -+#endif /* defined(CONFIG_DSSCOMP) */ -+ -+#define OMAPLFB_COMMAND_COUNT 1 -+ -+#define OMAPLFB_VSYNC_SETTLE_COUNT 5 -+ -+//#define OMAPLFB_MAX_NUM_DEVICES FB_MAX -+#define OMAPLFB_MAX_NUM_DEVICES 1 -+#if (OMAPLFB_MAX_NUM_DEVICES > FB_MAX) -+#error "OMAPLFB_MAX_NUM_DEVICES must not be greater than FB_MAX" -+#endif -+ -+static OMAPLFB_DEVINFO *gapsDevInfo[OMAPLFB_MAX_NUM_DEVICES]; -+ -+/* Top level 'hook ptr' */ -+static PFN_DC_GET_PVRJTABLE gpfnGetPVRJTable = NULL; -+ -+#if !defined(CONFIG_DSSCOMP) -+/* Round x up to a multiple of y */ -+static inline unsigned long RoundUpToMultiple(unsigned long x, unsigned long y) -+{ -+ unsigned long div = x / y; -+ unsigned long rem = x % y; -+ -+ return (div + ((rem == 0) ? 0 : 1)) * y; -+} -+ -+/* Greatest common divisor of x and y */ -+static unsigned long GCD(unsigned long x, unsigned long y) -+{ -+ while (y != 0) -+ { -+ unsigned long r = x % y; -+ x = y; -+ y = r; -+ } -+ -+ return x; -+} -+ -+/* Least common multiple of x and y */ -+static unsigned long LCM(unsigned long x, unsigned long y) -+{ -+ unsigned long gcd = GCD(x, y); -+ -+ return (gcd == 0) ? 0 : ((x / gcd) * y); -+} -+#endif -+ -+unsigned OMAPLFBMaxFBDevIDPlusOne(void) -+{ -+ return OMAPLFB_MAX_NUM_DEVICES; -+} -+ -+/* Returns DevInfo pointer for a given device */ -+OMAPLFB_DEVINFO *OMAPLFBGetDevInfoPtr(unsigned uiFBDevID) -+{ -+ WARN_ON(uiFBDevID >= OMAPLFBMaxFBDevIDPlusOne()); -+ -+ if (uiFBDevID >= OMAPLFB_MAX_NUM_DEVICES) -+ { -+ return NULL; -+ } -+ -+ return gapsDevInfo[uiFBDevID]; -+} -+ -+/* Sets the DevInfo pointer for a given device */ -+static inline void OMAPLFBSetDevInfoPtr(unsigned uiFBDevID, OMAPLFB_DEVINFO *psDevInfo) -+{ -+ WARN_ON(uiFBDevID >= OMAPLFB_MAX_NUM_DEVICES); -+ -+ if (uiFBDevID < OMAPLFB_MAX_NUM_DEVICES) -+ { -+ gapsDevInfo[uiFBDevID] = psDevInfo; -+ } -+} -+ -+static inline OMAPLFB_BOOL SwapChainHasChanged(OMAPLFB_DEVINFO *psDevInfo, OMAPLFB_SWAPCHAIN *psSwapChain) -+{ -+ return (psDevInfo->psSwapChain != psSwapChain) || -+ (psDevInfo->uiSwapChainID != psSwapChain->uiSwapChainID); -+} -+ -+/* Don't wait for vertical sync */ -+static inline OMAPLFB_BOOL DontWaitForVSync(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ OMAPLFB_BOOL bDontWait; -+ -+ bDontWait = OMAPLFBAtomicBoolRead(&psDevInfo->sBlanked) || -+ OMAPLFBAtomicBoolRead(&psDevInfo->sFlushCommands); -+ -+#if defined(CONFIG_HAS_EARLYSUSPEND) -+ bDontWait = bDontWait || OMAPLFBAtomicBoolRead(&psDevInfo->sEarlySuspendFlag); -+#endif -+#if defined(SUPPORT_DRI_DRM) -+ bDontWait = bDontWait || OMAPLFBAtomicBoolRead(&psDevInfo->sLeaveVT); -+#endif -+ return bDontWait; -+} -+ -+/* -+ * SetDCState -+ * Called from services. -+ */ -+static IMG_VOID SetDCState(IMG_HANDLE hDevice, IMG_UINT32 ui32State) -+{ -+ OMAPLFB_DEVINFO *psDevInfo = (OMAPLFB_DEVINFO *)hDevice; -+ -+ switch (ui32State) -+ { -+ case DC_STATE_FLUSH_COMMANDS: -+ OMAPLFBAtomicBoolSet(&psDevInfo->sFlushCommands, OMAPLFB_TRUE); -+ break; -+ case DC_STATE_NO_FLUSH_COMMANDS: -+ OMAPLFBAtomicBoolSet(&psDevInfo->sFlushCommands, OMAPLFB_FALSE); -+ break; -+ case DC_STATE_FORCE_SWAP_TO_SYSTEM: -+ OMAPLFBFlip(psDevInfo, &psDevInfo->sSystemBuffer); -+ break; -+ default: -+ break; -+ } -+} -+ -+/* -+ * OpenDCDevice -+ * Called from services. -+ */ -+static PVRSRV_ERROR OpenDCDevice(IMG_UINT32 uiPVRDevID, -+ IMG_HANDLE *phDevice, -+ PVRSRV_SYNC_DATA* psSystemBufferSyncData) -+{ -+ OMAPLFB_DEVINFO *psDevInfo; -+ OMAPLFB_ERROR eError; -+ unsigned uiMaxFBDevIDPlusOne; -+ unsigned i; -+ -+ if (!try_module_get(THIS_MODULE)) -+ { -+ return PVRSRV_ERROR_UNABLE_TO_OPEN_DC_DEVICE; -+ } -+ uiMaxFBDevIDPlusOne = OMAPLFBMaxFBDevIDPlusOne(); -+ -+ for (i = 0; i < uiMaxFBDevIDPlusOne; i++) -+ { -+ psDevInfo = OMAPLFBGetDevInfoPtr(i); -+ if (psDevInfo != NULL && psDevInfo->uiPVRDevID == uiPVRDevID) -+ { -+ break; -+ } -+ } -+ if (i == uiMaxFBDevIDPlusOne) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX -+ ": %s: PVR Device %u not found\n", __FUNCTION__, uiPVRDevID)); -+ eError = PVRSRV_ERROR_INVALID_DEVICE; -+ goto ErrorModulePut; -+ } -+ -+ /* store the system surface sync data */ -+ psDevInfo->sSystemBuffer.psSyncData = psSystemBufferSyncData; -+ -+ eError = OMAPLFBUnblankDisplay(psDevInfo); -+ if (eError != OMAPLFB_OK) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX -+ ": %s: Device %u: OMAPLFBUnblankDisplay failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, eError)); -+ eError = PVRSRV_ERROR_UNBLANK_DISPLAY_FAILED; -+ goto ErrorModulePut; -+ } -+ -+ /* return handle to the devinfo */ -+ *phDevice = (IMG_HANDLE)psDevInfo; -+ -+ return PVRSRV_OK; -+ -+ErrorModulePut: -+ module_put(THIS_MODULE); -+ return eError; -+} -+ -+/* -+ * CloseDCDevice -+ * Called from services. -+ */ -+static PVRSRV_ERROR CloseDCDevice(IMG_HANDLE hDevice) -+{ -+#if defined(SUPPORT_DRI_DRM) -+ OMAPLFB_DEVINFO *psDevInfo = (OMAPLFB_DEVINFO *)hDevice; -+ -+ OMAPLFBAtomicBoolSet(&psDevInfo->sLeaveVT, OMAPLFB_FALSE); -+ (void) OMAPLFBUnblankDisplay(psDevInfo); -+#else -+ UNREFERENCED_PARAMETER(hDevice); -+#endif -+ module_put(THIS_MODULE); -+ return PVRSRV_OK; -+} -+ -+/* -+ * EnumDCFormats -+ * Called from services. -+ */ -+static PVRSRV_ERROR EnumDCFormats(IMG_HANDLE hDevice, -+ IMG_UINT32 *pui32NumFormats, -+ DISPLAY_FORMAT *psFormat) -+{ -+ OMAPLFB_DEVINFO *psDevInfo; -+ -+ if(!hDevice || !pui32NumFormats) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psDevInfo = (OMAPLFB_DEVINFO*)hDevice; -+ -+ *pui32NumFormats = 1; -+ -+ if(psFormat) -+ { -+ psFormat[0] = psDevInfo->sDisplayFormat; -+ } -+ -+ return PVRSRV_OK; -+} -+ -+/* -+ * EnumDCDims -+ * Called from services. -+ */ -+static PVRSRV_ERROR EnumDCDims(IMG_HANDLE hDevice, -+ DISPLAY_FORMAT *psFormat, -+ IMG_UINT32 *pui32NumDims, -+ DISPLAY_DIMS *psDim) -+{ -+ OMAPLFB_DEVINFO *psDevInfo; -+ -+ if(!hDevice || !psFormat || !pui32NumDims) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psDevInfo = (OMAPLFB_DEVINFO*)hDevice; -+ -+ *pui32NumDims = 1; -+ -+ /* No need to look at psFormat; there is only one */ -+ if(psDim) -+ { -+ psDim[0] = psDevInfo->sDisplayDim; -+ } -+ -+ return PVRSRV_OK; -+} -+ -+ -+/* -+ * GetDCSystemBuffer -+ * Called from services. -+ */ -+static PVRSRV_ERROR GetDCSystemBuffer(IMG_HANDLE hDevice, IMG_HANDLE *phBuffer) -+{ -+ OMAPLFB_DEVINFO *psDevInfo; -+ -+ if(!hDevice || !phBuffer) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psDevInfo = (OMAPLFB_DEVINFO*)hDevice; -+ -+ *phBuffer = (IMG_HANDLE)&psDevInfo->sSystemBuffer; -+ -+ return PVRSRV_OK; -+} -+ -+ -+/* -+ * GetDCInfo -+ * Called from services. -+ */ -+static PVRSRV_ERROR GetDCInfo(IMG_HANDLE hDevice, DISPLAY_INFO *psDCInfo) -+{ -+ OMAPLFB_DEVINFO *psDevInfo; -+ -+ if(!hDevice || !psDCInfo) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psDevInfo = (OMAPLFB_DEVINFO*)hDevice; -+ -+ *psDCInfo = psDevInfo->sDisplayInfo; -+ -+ return PVRSRV_OK; -+} -+ -+/* -+ * GetDCBufferAddr -+ * Called from services. -+ */ -+static PVRSRV_ERROR GetDCBufferAddr(IMG_HANDLE hDevice, -+ IMG_HANDLE hBuffer, -+ IMG_SYS_PHYADDR **ppsSysAddr, -+ IMG_UINT32 *pui32ByteSize, -+ IMG_VOID **ppvCpuVAddr, -+ IMG_HANDLE *phOSMapInfo, -+ IMG_BOOL *pbIsContiguous, -+ IMG_UINT32 *pui32TilingStride) -+{ -+ OMAPLFB_DEVINFO *psDevInfo; -+ OMAPLFB_BUFFER *psSystemBuffer; -+ -+ UNREFERENCED_PARAMETER(pui32TilingStride); -+ -+ if(!hDevice) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ if(!hBuffer) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ if (!ppsSysAddr) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ if (!pui32ByteSize) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psDevInfo = (OMAPLFB_DEVINFO*)hDevice; -+ -+ psSystemBuffer = (OMAPLFB_BUFFER *)hBuffer; -+ -+ *ppsSysAddr = &psSystemBuffer->sSysAddr; -+ -+ *pui32ByteSize = (IMG_UINT32)psDevInfo->sFBInfo.ulBufferSize; -+ -+ if (ppvCpuVAddr) -+ { -+#if defined(CONFIG_DSSCOMP) -+ *ppvCpuVAddr = psDevInfo->sFBInfo.bIs2D ? NULL : psSystemBuffer->sCPUVAddr; -+#else -+ *ppvCpuVAddr = psSystemBuffer->sCPUVAddr; -+#endif -+ } -+ -+ if (phOSMapInfo) -+ { -+ *phOSMapInfo = (IMG_HANDLE)0; -+ } -+ -+ if (pbIsContiguous) -+ { -+#if defined(CONFIG_DSSCOMP) -+ *pbIsContiguous = !psDevInfo->sFBInfo.bIs2D; -+#else -+ *pbIsContiguous = IMG_TRUE; -+#endif -+ } -+ -+#if defined(CONFIG_DSSCOMP) -+ if (psDevInfo->sFBInfo.bIs2D) -+ { -+ int i = (psSystemBuffer->sSysAddr.uiAddr - psDevInfo->sFBInfo.psPageList->uiAddr) >> PAGE_SHIFT; -+ *ppsSysAddr = psDevInfo->sFBInfo.psPageList + psDevInfo->sFBInfo.ulHeight * i; -+ } -+#endif -+ -+ return PVRSRV_OK; -+} -+ -+/* -+ * CreateDCSwapChain -+ * Called from services. -+ */ -+static PVRSRV_ERROR CreateDCSwapChain(IMG_HANDLE hDevice, -+ IMG_UINT32 ui32Flags, -+ DISPLAY_SURF_ATTRIBUTES *psDstSurfAttrib, -+ DISPLAY_SURF_ATTRIBUTES *psSrcSurfAttrib, -+ IMG_UINT32 ui32BufferCount, -+ PVRSRV_SYNC_DATA **ppsSyncData, -+ IMG_UINT32 ui32OEMFlags, -+ IMG_HANDLE *phSwapChain, -+ IMG_UINT32 *pui32SwapChainID) -+{ -+ OMAPLFB_SWAPCHAIN *psSwapChain; -+ OMAPLFB_DEVINFO *psDevInfo; -+ PVRSRV_ERROR eError; -+ IMG_UINT32 i; -+ -+ UNREFERENCED_PARAMETER(ui32OEMFlags); -+ UNREFERENCED_PARAMETER(ui32Flags); -+ -+ /* Check parameters */ -+ if(!hDevice -+ || !psDstSurfAttrib -+ || !psSrcSurfAttrib -+ || !ppsSyncData -+ || !phSwapChain) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psDevInfo = (OMAPLFB_DEVINFO*)hDevice; -+ -+ /* Do we support swap chains? */ -+ if (psDevInfo->sDisplayInfo.ui32MaxSwapChains == 0) -+ { -+ return PVRSRV_ERROR_NOT_SUPPORTED; -+ } -+ -+ OMAPLFBCreateSwapChainLock(psDevInfo); -+ -+ /* The driver only supports a single swapchain */ -+ if(psDevInfo->psSwapChain != NULL) -+ { -+ eError = PVRSRV_ERROR_FLIP_CHAIN_EXISTS; -+ goto ExitUnLock; -+ } -+ -+ /* create a swapchain structure */ -+ psSwapChain = (OMAPLFB_SWAPCHAIN*)OMAPLFBAllocKernelMem(sizeof(OMAPLFB_SWAPCHAIN)); -+ if(!psSwapChain) -+ { -+ eError = PVRSRV_ERROR_OUT_OF_MEMORY; -+ goto ExitUnLock; -+ } -+ -+ /* If services asks for a 0-length swap chain, it's probably Android. -+ * -+ * This will use only non-display memory posting via PVRSRVSwapToDCBuffers2(), -+ * and we can skip some useless sanity checking. -+ */ -+ if(ui32BufferCount > 0) -+ { -+ IMG_UINT32 ui32BuffersToSkip; -+ -+ /* Check the buffer count */ -+ if(ui32BufferCount > psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers) -+ { -+ eError = PVRSRV_ERROR_TOOMANYBUFFERS; -+ goto ErrorFreeSwapChain; -+ } -+ -+ if ((psDevInfo->sFBInfo.ulRoundedBufferSize * (unsigned long)ui32BufferCount) > psDevInfo->sFBInfo.ulFBSize) -+ { -+ eError = PVRSRV_ERROR_TOOMANYBUFFERS; -+ goto ErrorFreeSwapChain; -+ } -+ -+ /* -+ * We will allocate the swap chain buffers at the back of the frame -+ * buffer area. This preserves the front portion, which may be being -+ * used by other Linux Framebuffer based applications. -+ */ -+ ui32BuffersToSkip = psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers - ui32BufferCount; -+ -+ /* -+ * Verify the DST/SRC attributes, -+ * SRC/DST must match the current display mode config -+ */ -+ if(psDstSurfAttrib->pixelformat != psDevInfo->sDisplayFormat.pixelformat -+ || psDstSurfAttrib->sDims.ui32ByteStride != psDevInfo->sDisplayDim.ui32ByteStride -+ || psDstSurfAttrib->sDims.ui32Width != psDevInfo->sDisplayDim.ui32Width -+ || psDstSurfAttrib->sDims.ui32Height != psDevInfo->sDisplayDim.ui32Height) -+ { -+ /* DST doesn't match the current mode */ -+ eError = PVRSRV_ERROR_INVALID_PARAMS; -+ goto ErrorFreeSwapChain; -+ } -+ -+ if(psDstSurfAttrib->pixelformat != psSrcSurfAttrib->pixelformat -+ || psDstSurfAttrib->sDims.ui32ByteStride != psSrcSurfAttrib->sDims.ui32ByteStride -+ || psDstSurfAttrib->sDims.ui32Width != psSrcSurfAttrib->sDims.ui32Width -+ || psDstSurfAttrib->sDims.ui32Height != psSrcSurfAttrib->sDims.ui32Height) -+ { -+ /* DST doesn't match the SRC */ -+ eError = PVRSRV_ERROR_INVALID_PARAMS; -+ goto ErrorFreeSwapChain; -+ } -+ -+ psSwapChain->psBuffer = (OMAPLFB_BUFFER*)OMAPLFBAllocKernelMem(sizeof(OMAPLFB_BUFFER) * ui32BufferCount); -+ if(!psSwapChain->psBuffer) -+ { -+ eError = PVRSRV_ERROR_OUT_OF_MEMORY; -+ goto ErrorFreeSwapChain; -+ } -+ -+ /* Link the buffers */ -+ for(i = 0; i < ui32BufferCount - 1; i++) -+ { -+ psSwapChain->psBuffer[i].psNext = &psSwapChain->psBuffer[i + 1]; -+ } -+ -+ /* and link last to first */ -+ psSwapChain->psBuffer[i].psNext = &psSwapChain->psBuffer[0]; -+ -+ /* Configure the swapchain buffers */ -+ for(i = 0; i < ui32BufferCount; i++) -+ { -+ IMG_UINT32 ui32SwapBuffer = i + ui32BuffersToSkip; -+ IMG_UINT32 ui32BufferOffset = ui32SwapBuffer * (IMG_UINT32)psDevInfo->sFBInfo.ulRoundedBufferSize; -+ -+#if defined(CONFIG_DSSCOMP) -+ if (psDevInfo->sFBInfo.bIs2D) -+ { -+ ui32BufferOffset = 0; -+ } -+#endif /* defined(CONFIG_DSSCOMP) */ -+ -+ psSwapChain->psBuffer[i].psSyncData = ppsSyncData[i]; -+ -+ psSwapChain->psBuffer[i].sSysAddr.uiAddr = psDevInfo->sFBInfo.sSysAddr.uiAddr + ui32BufferOffset; -+ psSwapChain->psBuffer[i].sCPUVAddr = psDevInfo->sFBInfo.sCPUVAddr + ui32BufferOffset; -+ psSwapChain->psBuffer[i].ulYOffset = ui32BufferOffset / psDevInfo->sFBInfo.ulByteStride; -+ psSwapChain->psBuffer[i].psDevInfo = psDevInfo; -+ -+#if defined(CONFIG_DSSCOMP) -+ if (psDevInfo->sFBInfo.bIs2D) -+ { -+ psSwapChain->psBuffer[i].sSysAddr.uiAddr += ui32SwapBuffer * -+ ALIGN((IMG_UINT32)psDevInfo->sFBInfo.ulWidth * psDevInfo->sFBInfo.uiBytesPerPixel, PAGE_SIZE); -+ } -+#endif /* defined(CONFIG_DSSCOMP) */ -+ -+ OMAPLFBInitBufferForSwap(&psSwapChain->psBuffer[i]); -+ } -+ } -+ else -+ { -+ psSwapChain->psBuffer = NULL; -+ } -+ -+#if defined(PVR_OMAPFB3_UPDATE_MODE) -+ if (!OMAPLFBSetUpdateMode(psDevInfo, PVR_OMAPFB3_UPDATE_MODE)) -+ { -+ printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Couldn't set frame buffer update mode %d\n", __FUNCTION__, psDevInfo->uiFBDevID, PVR_OMAPFB3_UPDATE_MODE); -+ } -+#endif /* defined(PVR_OMAPFB3_UPDATE_MODE) */ -+ -+ psSwapChain->ulBufferCount = (unsigned long)ui32BufferCount; -+ psSwapChain->bNotVSynced = OMAPLFB_TRUE; -+ psSwapChain->uiFBDevID = psDevInfo->uiFBDevID; -+ -+ if (OMAPLFBCreateSwapQueue(psSwapChain) != OMAPLFB_OK) -+ { -+ printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Failed to create workqueue\n", __FUNCTION__, psDevInfo->uiFBDevID); -+ eError = PVRSRV_ERROR_UNABLE_TO_INSTALL_ISR; -+ goto ErrorFreeBuffers; -+ } -+ -+ if (OMAPLFBEnableLFBEventNotification(psDevInfo)!= OMAPLFB_OK) -+ { -+ eError = PVRSRV_ERROR_UNABLE_TO_ENABLE_EVENT; -+ printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Couldn't enable framebuffer event notification\n", __FUNCTION__, psDevInfo->uiFBDevID); -+ goto ErrorDestroySwapQueue; -+ } -+ -+ psDevInfo->uiSwapChainID++; -+ if (psDevInfo->uiSwapChainID == 0) -+ { -+ psDevInfo->uiSwapChainID++; -+ } -+ -+ psSwapChain->uiSwapChainID = psDevInfo->uiSwapChainID; -+ -+ psDevInfo->psSwapChain = psSwapChain; -+ -+ *pui32SwapChainID = psDevInfo->uiSwapChainID; -+ -+ *phSwapChain = (IMG_HANDLE)psSwapChain; -+ -+ eError = PVRSRV_OK; -+ goto ExitUnLock; -+ -+ErrorDestroySwapQueue: -+ OMAPLFBDestroySwapQueue(psSwapChain); -+ErrorFreeBuffers: -+ if(psSwapChain->psBuffer) -+ { -+ OMAPLFBFreeKernelMem(psSwapChain->psBuffer); -+ } -+ErrorFreeSwapChain: -+ OMAPLFBFreeKernelMem(psSwapChain); -+ExitUnLock: -+ OMAPLFBCreateSwapChainUnLock(psDevInfo); -+ return eError; -+} -+ -+/* -+ * DestroyDCSwapChain -+ * Called from services. -+ */ -+static PVRSRV_ERROR DestroyDCSwapChain(IMG_HANDLE hDevice, -+ IMG_HANDLE hSwapChain) -+{ -+ OMAPLFB_DEVINFO *psDevInfo; -+ OMAPLFB_SWAPCHAIN *psSwapChain; -+ OMAPLFB_ERROR eError; -+ -+ /* Check parameters */ -+ if(!hDevice || !hSwapChain) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psDevInfo = (OMAPLFB_DEVINFO*)hDevice; -+ psSwapChain = (OMAPLFB_SWAPCHAIN*)hSwapChain; -+ -+ OMAPLFBCreateSwapChainLock(psDevInfo); -+ -+ if (SwapChainHasChanged(psDevInfo, psSwapChain)) -+ { -+ printk(KERN_WARNING DRIVER_PREFIX -+ ": %s: Device %u: Swap chain mismatch\n", __FUNCTION__, psDevInfo->uiFBDevID); -+ -+ eError = PVRSRV_ERROR_INVALID_PARAMS; -+ goto ExitUnLock; -+ } -+ -+ /* The swap queue is flushed before being destroyed */ -+ OMAPLFBDestroySwapQueue(psSwapChain); -+ -+ eError = OMAPLFBDisableLFBEventNotification(psDevInfo); -+ if (eError != OMAPLFB_OK) -+ { -+ printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Couldn't disable framebuffer event notification\n", __FUNCTION__, psDevInfo->uiFBDevID); -+ } -+ -+ /* Free resources */ -+ if (psSwapChain->psBuffer) -+ { -+ OMAPLFBFreeKernelMem(psSwapChain->psBuffer); -+ } -+ OMAPLFBFreeKernelMem(psSwapChain); -+ -+ psDevInfo->psSwapChain = NULL; -+ -+ OMAPLFBFlip(psDevInfo, &psDevInfo->sSystemBuffer); -+ (void) OMAPLFBCheckModeAndSync(psDevInfo); -+ -+ eError = PVRSRV_OK; -+ -+ExitUnLock: -+ OMAPLFBCreateSwapChainUnLock(psDevInfo); -+ -+ return eError; -+} -+ -+/* -+ * SetDCDstRect -+ * Called from services. -+ */ -+static PVRSRV_ERROR SetDCDstRect(IMG_HANDLE hDevice, -+ IMG_HANDLE hSwapChain, -+ IMG_RECT *psRect) -+{ -+ UNREFERENCED_PARAMETER(hDevice); -+ UNREFERENCED_PARAMETER(hSwapChain); -+ UNREFERENCED_PARAMETER(psRect); -+ -+ /* Only full display swapchains on this device */ -+ -+ return PVRSRV_ERROR_NOT_SUPPORTED; -+} -+ -+/* -+ * SetDCSrcRect -+ * Called from services. -+ */ -+static PVRSRV_ERROR SetDCSrcRect(IMG_HANDLE hDevice, -+ IMG_HANDLE hSwapChain, -+ IMG_RECT *psRect) -+{ -+ UNREFERENCED_PARAMETER(hDevice); -+ UNREFERENCED_PARAMETER(hSwapChain); -+ UNREFERENCED_PARAMETER(psRect); -+ -+ /* Only full display swapchains on this device */ -+ -+ return PVRSRV_ERROR_NOT_SUPPORTED; -+} -+ -+/* -+ * SetDCDstColourKey -+ * Called from services. -+ */ -+static PVRSRV_ERROR SetDCDstColourKey(IMG_HANDLE hDevice, -+ IMG_HANDLE hSwapChain, -+ IMG_UINT32 ui32CKColour) -+{ -+ UNREFERENCED_PARAMETER(hDevice); -+ UNREFERENCED_PARAMETER(hSwapChain); -+ UNREFERENCED_PARAMETER(ui32CKColour); -+ -+ /* Don't support DST CK on this device */ -+ -+ return PVRSRV_ERROR_NOT_SUPPORTED; -+} -+ -+/* -+ * SetDCSrcColourKey -+ * Called from services. -+ */ -+static PVRSRV_ERROR SetDCSrcColourKey(IMG_HANDLE hDevice, -+ IMG_HANDLE hSwapChain, -+ IMG_UINT32 ui32CKColour) -+{ -+ UNREFERENCED_PARAMETER(hDevice); -+ UNREFERENCED_PARAMETER(hSwapChain); -+ UNREFERENCED_PARAMETER(ui32CKColour); -+ -+ /* Don't support SRC CK on this device */ -+ -+ return PVRSRV_ERROR_NOT_SUPPORTED; -+} -+ -+/* -+ * GetDCBuffers -+ * Called from services. -+ */ -+static PVRSRV_ERROR GetDCBuffers(IMG_HANDLE hDevice, -+ IMG_HANDLE hSwapChain, -+ IMG_UINT32 *pui32BufferCount, -+ IMG_HANDLE *phBuffer) -+{ -+ OMAPLFB_DEVINFO *psDevInfo; -+ OMAPLFB_SWAPCHAIN *psSwapChain; -+ PVRSRV_ERROR eError; -+ unsigned i; -+ -+ /* Check parameters */ -+ if(!hDevice -+ || !hSwapChain -+ || !pui32BufferCount -+ || !phBuffer) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psDevInfo = (OMAPLFB_DEVINFO*)hDevice; -+ psSwapChain = (OMAPLFB_SWAPCHAIN*)hSwapChain; -+ -+ OMAPLFBCreateSwapChainLock(psDevInfo); -+ -+ if (SwapChainHasChanged(psDevInfo, psSwapChain)) -+ { -+ printk(KERN_WARNING DRIVER_PREFIX -+ ": %s: Device %u: Swap chain mismatch\n", __FUNCTION__, psDevInfo->uiFBDevID); -+ -+ eError = PVRSRV_ERROR_INVALID_PARAMS; -+ goto Exit; -+ } -+ -+ /* Return the buffer count */ -+ *pui32BufferCount = (IMG_UINT32)psSwapChain->ulBufferCount; -+ -+ /* Return the buffers */ -+ for(i=0; i<psSwapChain->ulBufferCount; i++) -+ { -+ phBuffer[i] = (IMG_HANDLE)&psSwapChain->psBuffer[i]; -+ } -+ -+ eError = PVRSRV_OK; -+ -+Exit: -+ OMAPLFBCreateSwapChainUnLock(psDevInfo); -+ -+ return eError; -+} -+ -+/* -+ * SwapToDCBuffer -+ * Called from services. -+ */ -+static PVRSRV_ERROR SwapToDCBuffer(IMG_HANDLE hDevice, -+ IMG_HANDLE hBuffer, -+ IMG_UINT32 ui32SwapInterval, -+ IMG_HANDLE hPrivateTag, -+ IMG_UINT32 ui32ClipRectCount, -+ IMG_RECT *psClipRect) -+{ -+ UNREFERENCED_PARAMETER(hDevice); -+ UNREFERENCED_PARAMETER(hBuffer); -+ UNREFERENCED_PARAMETER(ui32SwapInterval); -+ UNREFERENCED_PARAMETER(hPrivateTag); -+ UNREFERENCED_PARAMETER(ui32ClipRectCount); -+ UNREFERENCED_PARAMETER(psClipRect); -+ -+ /* * Nothing to do since Services common code does the work */ -+ -+ return PVRSRV_OK; -+} -+ -+/* -+ * Called after the screen has unblanked, or after any other occasion -+ * when we didn't wait for vsync, but now need to. Not doing this after -+ * unblank leads to screen jitter on some screens. -+ * Returns true if the screen has been deemed to have settled. -+ */ -+static OMAPLFB_BOOL WaitForVSyncSettle(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ unsigned i; -+ for(i = 0; i < OMAPLFB_VSYNC_SETTLE_COUNT; i++) -+ { -+ if (DontWaitForVSync(psDevInfo) || !OMAPLFBWaitForVSync(psDevInfo)) -+ { -+ return OMAPLFB_FALSE; -+ } -+ } -+ -+ return OMAPLFB_TRUE; -+} -+ -+/* -+ * Swap handler. -+ * Called from the swap chain work queue handler. -+ * There is no need to take the swap chain creation lock in here, or use -+ * some other method of stopping the swap chain from being destroyed. -+ * This is because the swap chain creation lock is taken when queueing work, -+ * and the work queue is flushed before the swap chain is destroyed. -+ */ -+void OMAPLFBSwapHandler(OMAPLFB_BUFFER *psBuffer) -+{ -+ OMAPLFB_DEVINFO *psDevInfo = psBuffer->psDevInfo; -+ OMAPLFB_SWAPCHAIN *psSwapChain = psDevInfo->psSwapChain; -+ OMAPLFB_BOOL bPreviouslyNotVSynced; -+ -+#if defined(SUPPORT_DRI_DRM) -+ if (!OMAPLFBAtomicBoolRead(&psDevInfo->sLeaveVT)) -+#endif -+ { -+ OMAPLFBFlip(psDevInfo, psBuffer); -+ } -+ -+ bPreviouslyNotVSynced = psSwapChain->bNotVSynced; -+ psSwapChain->bNotVSynced = OMAPLFB_TRUE; -+ -+ -+ if (!DontWaitForVSync(psDevInfo)) -+ { -+ OMAPLFB_UPDATE_MODE eMode = OMAPLFBGetUpdateMode(psDevInfo); -+ int iBlankEvents = OMAPLFBAtomicIntRead(&psDevInfo->sBlankEvents); -+ -+ switch(eMode) -+ { -+ case OMAPLFB_UPDATE_MODE_AUTO: -+ psSwapChain->bNotVSynced = OMAPLFB_FALSE; -+ -+ if (bPreviouslyNotVSynced || psSwapChain->iBlankEvents != iBlankEvents) -+ { -+ psSwapChain->iBlankEvents = iBlankEvents; -+ psSwapChain->bNotVSynced = !WaitForVSyncSettle(psDevInfo); -+ } else if (psBuffer->ulSwapInterval != 0) -+ { -+ psSwapChain->bNotVSynced = !OMAPLFBWaitForVSync(psDevInfo); -+ } -+ break; -+#if defined(PVR_OMAPFB3_MANUAL_UPDATE_SYNC_IN_SWAP) -+ case OMAPLFB_UPDATE_MODE_MANUAL: -+ if (psBuffer->ulSwapInterval != 0) -+ { -+ (void) OMAPLFBManualSync(psDevInfo); -+ } -+ break; -+#endif -+ default: -+ break; -+ } -+ } -+ -+ psDevInfo->sPVRJTable.pfnPVRSRVCmdComplete((IMG_HANDLE)psBuffer->hCmdComplete, IMG_TRUE); -+} -+ -+/* Triggered by PVRSRVSwapToDCBuffer */ -+static IMG_BOOL ProcessFlipV1(IMG_HANDLE hCmdCookie, -+ OMAPLFB_DEVINFO *psDevInfo, -+ OMAPLFB_SWAPCHAIN *psSwapChain, -+ OMAPLFB_BUFFER *psBuffer, -+ unsigned long ulSwapInterval) -+{ -+ OMAPLFBCreateSwapChainLock(psDevInfo); -+ -+ /* The swap chain has been destroyed */ -+ if (SwapChainHasChanged(psDevInfo, psSwapChain)) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX -+ ": %s: Device %u (PVR Device ID %u): The swap chain has been destroyed\n", -+ __FUNCTION__, psDevInfo->uiFBDevID, psDevInfo->uiPVRDevID)); -+ } -+ else -+ { -+ psBuffer->hCmdComplete = (OMAPLFB_HANDLE)hCmdCookie; -+ psBuffer->ulSwapInterval = ulSwapInterval; -+#if defined(CONFIG_DSSCOMP) -+ if (is_tiler_addr(psBuffer->sSysAddr.uiAddr)) -+ { -+ int res; -+ IMG_UINT32 w = psBuffer->psDevInfo->sDisplayDim.ui32Width; -+ IMG_UINT32 h = psBuffer->psDevInfo->sDisplayDim.ui32Height; -+ struct dsscomp_setup_dispc_data comp = { -+ .num_mgrs = 1, -+ .mgrs[0].alpha_blending = 1, -+ .num_ovls = 1, -+ .ovls[0].cfg = -+ { -+ .width = w, -+ .win.w = w, -+ .crop.w = w, -+ .height = h, -+ .win.h = h, -+ .crop.h = h, -+ .stride = psBuffer->psDevInfo->sDisplayDim.ui32ByteStride, -+ .color_mode = OMAP_DSS_COLOR_ARGB32, -+ .enabled = 1, -+ .global_alpha = 255, -+ }, -+ .mode = DSSCOMP_SETUP_DISPLAY, -+ }; -+ struct tiler_pa_info *pas[1] = { NULL }; -+ comp.ovls[0].ba = (u32) psBuffer->sSysAddr.uiAddr; -+ res = dsscomp_gralloc_queue(&comp, pas, true, -+ (void *) psDevInfo->sPVRJTable.pfnPVRSRVCmdComplete, -+ (void *) psBuffer->hCmdComplete); -+ if (res != 0) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: dsscomp_gralloc_queue failed (Y Offset: %lu, Error: %d)\n", __FUNCTION__, psDevInfo->uiFBDevID, psBuffer->ulYOffset, res)); -+ } -+ } -+ else -+#endif /* defined(CONFIG_DSSCOMP) */ -+ { -+ OMAPLFBQueueBufferForSwap(psSwapChain, psBuffer); -+ } -+ } -+ -+ OMAPLFBCreateSwapChainUnLock(psDevInfo); -+ -+ return IMG_TRUE; -+} -+ -+#if defined(CONFIG_DSSCOMP) -+ -+/* Triggered by PVRSRVSwapToDCBuffer2 */ -+static IMG_BOOL ProcessFlipV2(IMG_HANDLE hCmdCookie, -+ OMAPLFB_DEVINFO *psDevInfo, -+ PDC_MEM_INFO *ppsMemInfos, -+ IMG_UINT32 ui32NumMemInfos, -+ struct dsscomp_setup_dispc_data *psDssData, -+ IMG_UINT32 ui32DssDataLength) -+{ -+ struct tiler_pa_info *apsTilerPAs[5]; -+ IMG_UINT32 i, k; -+ struct -+ { -+ IMG_UINTPTR_T uiAddr; -+ IMG_UINTPTR_T uiUVAddr; -+ struct tiler_pa_info *psTilerInfo; -+ } -+ asMemInfo[5] = {}; -+ int res; -+ -+ if(ui32DssDataLength != sizeof(*psDssData)) -+ { -+ WARN(1, "invalid size of private data (%d vs %d)", -+ ui32DssDataLength, sizeof(*psDssData)); -+ return IMG_FALSE; -+ } -+ -+ if(psDssData->num_ovls == 0 || ui32NumMemInfos == 0) -+ { -+ WARN(1, "must have at least one layer"); -+ return IMG_FALSE; -+ } -+ -+ for(i = k = 0; i < ui32NumMemInfos && k < ARRAY_SIZE(asMemInfo); i++, k++) -+ { -+ struct tiler_pa_info *psTilerInfo; -+ IMG_CPU_VIRTADDR virtAddr; -+ IMG_CPU_PHYADDR phyAddr; -+ IMG_UINT32 ui32NumPages; -+ IMG_SIZE_T uByteSize; -+ int j; -+ -+ psDevInfo->sPVRJTable.pfnPVRSRVDCMemInfoGetByteSize(ppsMemInfos[i], &uByteSize); -+ ui32NumPages = (uByteSize + PAGE_SIZE - 1) >> PAGE_SHIFT; -+ -+ psDevInfo->sPVRJTable.pfnPVRSRVDCMemInfoGetCpuPAddr(ppsMemInfos[i], 0, &phyAddr); -+ -+ /* TILER buffers do not need meminfos */ -+ if(is_tiler_addr((u32)phyAddr.uiAddr)) -+ { -+#ifdef CONFIG_DRM_OMAP_DMM_TILER -+ enum tiler_fmt fmt; -+#endif -+ asMemInfo[k].uiAddr = phyAddr.uiAddr; -+#ifdef CONFIG_DRM_OMAP_DMM_TILER -+ if(tiler_get_fmt((u32)phyAddr.uiAddr, &fmt) && fmt == TILFMT_8BIT) -+#else -+ if(tiler_fmt((u32)phyAddr.uiAddr) == TILFMT_8BIT) -+#endif -+ { -+ psDevInfo->sPVRJTable.pfnPVRSRVDCMemInfoGetCpuPAddr(ppsMemInfos[i], (uByteSize * 2) / 3, &phyAddr); -+ asMemInfo[k].uiUVAddr = phyAddr.uiAddr; -+ } -+ continue; -+ } -+ -+ /* normal gralloc layer */ -+ psTilerInfo = kzalloc(sizeof(*psTilerInfo), GFP_KERNEL); -+ if(!psTilerInfo) -+ { -+ continue; -+ } -+ -+ psTilerInfo->mem = kzalloc(sizeof(*psTilerInfo->mem) * ui32NumPages, GFP_KERNEL); -+ if(!psTilerInfo->mem) -+ { -+ kfree(psTilerInfo); -+ continue; -+ } -+ -+ psTilerInfo->num_pg = ui32NumPages; -+ psTilerInfo->memtype = TILER_MEM_USING; -+ for(j = 0; j < ui32NumPages; j++) -+ { -+ psDevInfo->sPVRJTable.pfnPVRSRVDCMemInfoGetCpuPAddr(ppsMemInfos[i], j << PAGE_SHIFT, &phyAddr); -+ psTilerInfo->mem[j] = (u32)phyAddr.uiAddr; -+ } -+ -+ /* need base address for in-page offset */ -+ psDevInfo->sPVRJTable.pfnPVRSRVDCMemInfoGetCpuVAddr(ppsMemInfos[i], &virtAddr); -+ asMemInfo[k].uiAddr = (IMG_UINTPTR_T) virtAddr; -+ asMemInfo[k].psTilerInfo = psTilerInfo; -+ } -+ -+ for(i = 0; i < psDssData->num_ovls; i++) -+ { -+ unsigned int ix; -+ apsTilerPAs[i] = NULL; -+ -+ /* only supporting Post2, cloned and fbmem layers */ -+ if (psDssData->ovls[i].addressing != OMAP_DSS_BUFADDR_LAYER_IX && -+ psDssData->ovls[i].addressing != OMAP_DSS_BUFADDR_OVL_IX && -+ psDssData->ovls[i].addressing != OMAP_DSS_BUFADDR_FB) -+ { -+ psDssData->ovls[i].cfg.enabled = false; -+ } -+ -+ if (psDssData->ovls[i].addressing != OMAP_DSS_BUFADDR_LAYER_IX) -+ { -+ continue; -+ } -+ -+ /* Post2 layers */ -+ ix = psDssData->ovls[i].ba; -+ if (ix >= k) -+ { -+ WARN(1, "Invalid Post2 layer (%u)", ix); -+ psDssData->ovls[i].cfg.enabled = false; -+ continue; -+ } -+ -+ psDssData->ovls[i].addressing = OMAP_DSS_BUFADDR_DIRECT; -+ psDssData->ovls[i].ba = (u32) asMemInfo[ix].uiAddr; -+ psDssData->ovls[i].uv = (u32) asMemInfo[ix].uiUVAddr; -+ apsTilerPAs[i] = asMemInfo[ix].psTilerInfo; -+ } -+ -+ res = dsscomp_gralloc_queue(psDssData, apsTilerPAs, false, -+ (void *)psDevInfo->sPVRJTable.pfnPVRSRVCmdComplete, -+ (void *)hCmdCookie); -+ if (res != 0) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: dsscomp_gralloc_queue failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, res)); -+ } -+ -+ for(i = 0; i < k; i++) -+ { -+ tiler_pa_free(apsTilerPAs[i]); -+ } -+ -+ return IMG_TRUE; -+} -+ -+#endif /* defined(CONFIG_DSSCOMP) */ -+ -+/* Command processing flip handler function. Called from services. */ -+static IMG_BOOL ProcessFlip(IMG_HANDLE hCmdCookie, -+ IMG_UINT32 ui32DataSize, -+ IMG_VOID *pvData) -+{ -+ DISPLAYCLASS_FLIP_COMMAND *psFlipCmd; -+ OMAPLFB_DEVINFO *psDevInfo; -+ -+ /* Check parameters */ -+ if(!hCmdCookie || !pvData) -+ { -+ return IMG_FALSE; -+ } -+ -+ /* Validate data packet */ -+ psFlipCmd = (DISPLAYCLASS_FLIP_COMMAND*)pvData; -+ -+ if (psFlipCmd == IMG_NULL) -+ { -+ return IMG_FALSE; -+ } -+ -+ psDevInfo = (OMAPLFB_DEVINFO*)psFlipCmd->hExtDevice; -+ -+ if(psFlipCmd->hExtBuffer) -+ { -+ return ProcessFlipV1(hCmdCookie, -+ psDevInfo, -+ psFlipCmd->hExtSwapChain, -+ psFlipCmd->hExtBuffer, -+ psFlipCmd->ui32SwapInterval); -+ } -+ else -+ { -+#if defined(CONFIG_DSSCOMP) -+ DISPLAYCLASS_FLIP_COMMAND2 *psFlipCmd2; -+ psFlipCmd2 = (DISPLAYCLASS_FLIP_COMMAND2 *)pvData; -+ return ProcessFlipV2(hCmdCookie, -+ psDevInfo, -+ psFlipCmd2->ppsMemInfos, -+ psFlipCmd2->ui32NumMemInfos, -+ psFlipCmd2->pvPrivData, -+ psFlipCmd2->ui32PrivDataLength); -+#else -+ BUG(); -+#endif -+ } -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function OMAPLFBInitFBDev -+ -+ @Description specifies devices in the systems memory map -+ -+ @Input psSysData - sys data -+ -+ @Return OMAPLFB_ERROR : -+ -+******************************************************************************/ -+static OMAPLFB_ERROR OMAPLFBInitFBDev(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ struct fb_info *psLINFBInfo; -+ struct module *psLINFBOwner; -+ OMAPLFB_FBINFO *psPVRFBInfo = &psDevInfo->sFBInfo; -+ OMAPLFB_ERROR eError = OMAPLFB_ERROR_GENERIC; -+ unsigned uiFBDevID = psDevInfo->uiFBDevID; -+ -+ OMAPLFB_CONSOLE_LOCK(); -+ -+ psLINFBInfo = registered_fb[uiFBDevID]; -+ if (psLINFBInfo == NULL) -+ { -+ eError = OMAPLFB_ERROR_INVALID_DEVICE; -+ goto ErrorRelSem; -+ } -+ -+ psLINFBOwner = psLINFBInfo->fbops->owner; -+ if (!try_module_get(psLINFBOwner)) -+ { -+ printk(KERN_INFO DRIVER_PREFIX -+ ": %s: Device %u: Couldn't get framebuffer module\n", __FUNCTION__, uiFBDevID); -+ -+ goto ErrorRelSem; -+ } -+ -+ if (psLINFBInfo->fbops->fb_open != NULL) -+ { -+ int res; -+ -+ res = psLINFBInfo->fbops->fb_open(psLINFBInfo, 0); -+ if (res != 0) -+ { -+ printk(KERN_INFO DRIVER_PREFIX -+ " %s: Device %u: Couldn't open framebuffer(%d)\n", __FUNCTION__, uiFBDevID, res); -+ -+ goto ErrorModPut; -+ } -+ } -+ -+ psDevInfo->psLINFBInfo = psLINFBInfo; -+ -+ psPVRFBInfo->ulWidth = psLINFBInfo->var.xres; -+ psPVRFBInfo->ulHeight = psLINFBInfo->var.yres; -+ -+ if (psPVRFBInfo->ulWidth == 0 || psPVRFBInfo->ulHeight == 0) -+ { -+ eError = OMAPLFB_ERROR_INVALID_DEVICE; -+ goto ErrorFBRel; -+ } -+ -+#if !defined(CONFIG_DSSCOMP) -+ psPVRFBInfo->ulFBSize = (psLINFBInfo->screen_size) != 0 ? -+ psLINFBInfo->screen_size : -+ psLINFBInfo->fix.smem_len; -+ -+ /* -+ * Try and filter out invalid FB info structures (a problem -+ * seen on some OMAP3 systems). -+ */ -+ if (psPVRFBInfo->ulFBSize == 0 || psLINFBInfo->fix.line_length == 0) -+ { -+ eError = OMAPLFB_ERROR_INVALID_DEVICE; -+ goto ErrorFBRel; -+ } -+ -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX -+ ": Device %u: Framebuffer size: %lu\n", -+ psDevInfo->uiFBDevID, psPVRFBInfo->ulFBSize)); -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX -+ ": Device %u: Framebuffer virtual width: %u\n", -+ psDevInfo->uiFBDevID, psLINFBInfo->var.xres_virtual)); -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX -+ ": Device %u: Framebuffer virtual height: %u\n", -+ psDevInfo->uiFBDevID, psLINFBInfo->var.yres_virtual)); -+#endif -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX -+ ": Device %u: Framebuffer width: %lu\n", -+ psDevInfo->uiFBDevID, psPVRFBInfo->ulWidth)); -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX -+ ": Device %u: Framebuffer height: %lu\n", -+ psDevInfo->uiFBDevID, psPVRFBInfo->ulHeight)); -+ -+#if defined(CONFIG_DSSCOMP) -+ { -+#if defined(SUPPORT_PVRSRV_GET_DC_SYSTEM_BUFFER) -+ /* -+ * Assume we need 3 swap buffers, and a separate system -+ * buffer. -+ */ -+ int n = 4; -+#else -+ /* -+ * Assume we need just 3 swap buffers, and no separate -+ * system buffer. -+ */ -+ int n = 3; -+#endif -+ int res; -+ int i, x, y, w; -+ ion_phys_addr_t phys; -+ size_t size; -+ struct tiler_view_t view; -+ -+ struct omap_ion_tiler_alloc_data sAllocData = -+ { -+ /* TILER will align width to 128-bytes */ -+ /* however, SGX must have full page width */ -+ .w = ALIGN(psPVRFBInfo->ulWidth, PAGE_SIZE / (psLINFBInfo->var.bits_per_pixel / 8)), -+ .h = psPVRFBInfo->ulHeight, -+ .fmt = psLINFBInfo->var.bits_per_pixel == 16 ? TILER_PIXEL_FMT_16BIT : TILER_PIXEL_FMT_32BIT, -+ .flags = 0, -+ }; -+ -+ printk(KERN_DEBUG DRIVER_PREFIX -+ " %s: Device %u: Requesting %d TILER 2D framebuffers\n", -+ __FUNCTION__, uiFBDevID, n); -+ -+ sAllocData.w *= n; -+ -+ psPVRFBInfo->uiBytesPerPixel = psLINFBInfo->var.bits_per_pixel >> 3; -+ psPVRFBInfo->bIs2D = OMAPLFB_TRUE; -+ -+ res = omap_ion_tiler_alloc(psDevInfo->psIONClient, &sAllocData); -+ psPVRFBInfo->psIONHandle = sAllocData.handle; -+ if (res < 0) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ " %s: Device %u: Could not allocate 2D framebuffer(%d)\n", -+ __FUNCTION__, uiFBDevID, res); -+ goto ErrorFBRel; -+ } -+ -+ res = ion_phys(psDevInfo->psIONClient, sAllocData.handle, &phys, &size); -+ if (res < 0) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ " %s: Device %u: Could not get 2D framebufferphysical address (%d)\n", -+ __FUNCTION__, uiFBDevID, res); -+ goto ErrorFBRel; -+ } -+ -+ psPVRFBInfo->sSysAddr.uiAddr = phys; -+ psPVRFBInfo->sCPUVAddr = 0; -+ -+ psPVRFBInfo->ulByteStride = PAGE_ALIGN(psPVRFBInfo->ulWidth * psPVRFBInfo->uiBytesPerPixel); -+ w = psPVRFBInfo->ulByteStride >> PAGE_SHIFT; -+ -+ psPVRFBInfo->ulFBSize = sAllocData.h * n * psPVRFBInfo->ulByteStride; -+ psPVRFBInfo->psPageList = kzalloc(w * n * psPVRFBInfo->ulHeight * sizeof(*psPVRFBInfo->psPageList), GFP_KERNEL); -+ if (!psPVRFBInfo->psPageList) -+ { -+ printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Could not allocate page list\n", __FUNCTION__, psDevInfo->uiFBDevID); -+ ion_free(psDevInfo->psIONClient, sAllocData.handle); -+ goto ErrorFBRel; -+ } -+ -+ tilview_create(&view, phys, psDevInfo->sFBInfo.ulWidth, psDevInfo->sFBInfo.ulHeight); -+ for(i = 0; i < n; i++) -+ { -+ for(y = 0; y < psDevInfo->sFBInfo.ulHeight; y++) -+ { -+ for(x = 0; x < w; x++) -+ { -+ psPVRFBInfo->psPageList[i * psDevInfo->sFBInfo.ulHeight * w + y * w + x].uiAddr = -+ phys + view.v_inc * y + ((x + i * w) << PAGE_SHIFT); -+ } -+ } -+ } -+ } -+#else /* defined(CONFIG_DSSCOMP) */ -+ /* System Surface */ -+ psPVRFBInfo->sSysAddr.uiAddr = psLINFBInfo->fix.smem_start; -+ psPVRFBInfo->sCPUVAddr = psLINFBInfo->screen_base; -+ -+ psPVRFBInfo->ulByteStride = psLINFBInfo->fix.line_length; -+#endif /* defined(CONFIG_DSSCOMP) */ -+ -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX -+ ": Device %u: Framebuffer physical address: 0x%x\n", -+ psDevInfo->uiFBDevID, psPVRFBInfo->sSysAddr.uiAddr)); -+ -+ if (psPVRFBInfo->sCPUVAddr != NULL) -+ { -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX -+ ": Device %u: Framebuffer virtual address: %p\n", -+ psDevInfo->uiFBDevID, psPVRFBInfo->sCPUVAddr)); -+ } -+ -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX -+ ": Device %u: Framebuffer stride: %lu\n", -+ psDevInfo->uiFBDevID, psPVRFBInfo->ulByteStride)); -+ -+ /* Additional implementation specific information */ -+ OMAPLFBPrintInfo(psDevInfo); -+ -+ psPVRFBInfo->ulBufferSize = psPVRFBInfo->ulHeight * psPVRFBInfo->ulByteStride; -+ -+#if defined(CONFIG_DSSCOMP) -+ psPVRFBInfo->ulRoundedBufferSize = psPVRFBInfo->ulBufferSize; -+#else -+ { -+ unsigned long ulLCM; -+ ulLCM = LCM(psPVRFBInfo->ulByteStride, OMAPLFB_PAGE_SIZE); -+ -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX -+ ": Device %u: LCM of stride and page size: %lu\n", -+ psDevInfo->uiFBDevID, ulLCM)); -+ -+ /* Round the buffer size up to a multiple of the number of pages -+ * and the byte stride. -+ * This is used internally, to ensure buffers start on page -+ * boundaries, for the benefit of PVR Services. -+ */ -+ psPVRFBInfo->ulRoundedBufferSize = RoundUpToMultiple(psPVRFBInfo->ulBufferSize, ulLCM); -+ } -+#endif -+ if(psLINFBInfo->var.bits_per_pixel == 16) -+ { -+ if((psLINFBInfo->var.red.length == 5) && -+ (psLINFBInfo->var.green.length == 6) && -+ (psLINFBInfo->var.blue.length == 5) && -+ (psLINFBInfo->var.red.offset == 11) && -+ (psLINFBInfo->var.green.offset == 5) && -+ (psLINFBInfo->var.blue.offset == 0) && -+ (psLINFBInfo->var.red.msb_right == 0)) -+ { -+ psPVRFBInfo->ePixelFormat = PVRSRV_PIXEL_FORMAT_RGB565; -+ } -+ else -+ { -+ printk(KERN_INFO DRIVER_PREFIX ": %s: Device %u: Unknown FB format\n", __FUNCTION__, uiFBDevID); -+ } -+ } -+ else if(psLINFBInfo->var.bits_per_pixel == 32) -+ { -+ if((psLINFBInfo->var.red.length == 8) && -+ (psLINFBInfo->var.green.length == 8) && -+ (psLINFBInfo->var.blue.length == 8) && -+ (psLINFBInfo->var.red.offset == 16) && -+ (psLINFBInfo->var.green.offset == 8) && -+ (psLINFBInfo->var.blue.offset == 0) && -+ (psLINFBInfo->var.red.msb_right == 0)) -+ { -+ psPVRFBInfo->ePixelFormat = PVRSRV_PIXEL_FORMAT_ARGB8888; -+ } -+ else -+ { -+ printk(KERN_INFO DRIVER_PREFIX ": %s: Device %u: Unknown FB format\n", __FUNCTION__, uiFBDevID); -+ } -+ } -+ else -+ { -+ printk(KERN_INFO DRIVER_PREFIX ": %s: Device %u: Unknown FB format\n", __FUNCTION__, uiFBDevID); -+ } -+ -+ psDevInfo->sFBInfo.ulPhysicalWidthmm = -+ ((int)psLINFBInfo->var.width > 0) ? psLINFBInfo->var.width : 90; -+ -+ psDevInfo->sFBInfo.ulPhysicalHeightmm = -+ ((int)psLINFBInfo->var.height > 0) ? psLINFBInfo->var.height : 54; -+ -+ /* System Surface */ -+ psDevInfo->sFBInfo.sSysAddr.uiAddr = psPVRFBInfo->sSysAddr.uiAddr; -+ psDevInfo->sFBInfo.sCPUVAddr = psPVRFBInfo->sCPUVAddr; -+ -+ eError = OMAPLFB_OK; -+ goto ErrorRelSem; -+ -+ErrorFBRel: -+ if (psLINFBInfo->fbops->fb_release != NULL) -+ { -+ (void) psLINFBInfo->fbops->fb_release(psLINFBInfo, 0); -+ } -+ErrorModPut: -+ module_put(psLINFBOwner); -+ErrorRelSem: -+ OMAPLFB_CONSOLE_UNLOCK(); -+ -+ return eError; -+} -+ -+static void OMAPLFBDeInitFBDev(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ struct fb_info *psLINFBInfo = psDevInfo->psLINFBInfo; -+ struct module *psLINFBOwner; -+ -+ OMAPLFB_CONSOLE_LOCK(); -+ -+#if defined(CONFIG_DSSCOMP) -+ { -+ OMAPLFB_FBINFO *psPVRFBInfo = &psDevInfo->sFBInfo; -+ kfree(psPVRFBInfo->psPageList); -+ if (psPVRFBInfo->psIONHandle) -+ { -+ ion_free(psDevInfo->psIONClient, psPVRFBInfo->psIONHandle); -+ } -+ } -+#endif /* defined(CONFIG_DSSCOMP) */ -+ -+ psLINFBOwner = psLINFBInfo->fbops->owner; -+ -+ if (psLINFBInfo->fbops->fb_release != NULL) -+ { -+ (void) psLINFBInfo->fbops->fb_release(psLINFBInfo, 0); -+ } -+ -+ module_put(psLINFBOwner); -+ -+ OMAPLFB_CONSOLE_UNLOCK(); -+} -+ -+static OMAPLFB_DEVINFO *OMAPLFBInitDev(unsigned uiFBDevID) -+{ -+ PFN_CMD_PROC pfnCmdProcList[OMAPLFB_COMMAND_COUNT]; -+ IMG_UINT32 aui32SyncCountList[OMAPLFB_COMMAND_COUNT][2]; -+ OMAPLFB_DEVINFO *psDevInfo = NULL; -+ -+ /* Allocate device info. structure */ -+ psDevInfo = (OMAPLFB_DEVINFO *)OMAPLFBAllocKernelMem(sizeof(OMAPLFB_DEVINFO)); -+ -+ if(psDevInfo == NULL) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ ": %s: Device %u: Couldn't allocate device information structure\n", __FUNCTION__, uiFBDevID); -+ -+ goto ErrorExit; -+ } -+ -+ /* Any fields not set will be zero */ -+ memset(psDevInfo, 0, sizeof(OMAPLFB_DEVINFO)); -+ -+ psDevInfo->uiFBDevID = uiFBDevID; -+ -+ /* Get the kernel services function table */ -+ if(!(*gpfnGetPVRJTable)(&psDevInfo->sPVRJTable)) -+ { -+ goto ErrorFreeDevInfo; -+ } -+ -+#if defined(CONFIG_ION_OMAP) -+ psDevInfo->psIONClient = -+ ion_client_create(omap_ion_device, -+ 1 << ION_HEAP_TYPE_CARVEOUT | -+ 1 << OMAP_ION_HEAP_TYPE_TILER, -+ "dc_omapfb3_linux"); -+ if (IS_ERR_OR_NULL(psDevInfo->psIONClient)) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ ": %s: Device %u: Failed to create ion client\n", __FUNCTION__, uiFBDevID); -+ -+ goto ErrorFreeDevInfo; -+ } -+#endif /* defined(CONFIG_ION_OMAP) */ -+#ifdef FBDEV_PRESENT -+ /* Save private fbdev information structure in the dev. info. */ -+ if(OMAPLFBInitFBDev(psDevInfo) != OMAPLFB_OK) -+ { -+ /* -+ * Leave it to OMAPLFBInitFBDev to print an error message, if -+ * required. The function may have failed because -+ * there is no Linux framebuffer device corresponding -+ * to the device ID. -+ */ -+ goto ErrorIonClientDestroy; -+ } -+ -+ psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers = (IMG_UINT32)(psDevInfo->sFBInfo.ulFBSize / psDevInfo->sFBInfo.ulRoundedBufferSize); -+ if (psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers != 0) -+ { -+ psDevInfo->sDisplayInfo.ui32MaxSwapChains = 1; -+ psDevInfo->sDisplayInfo.ui32MaxSwapInterval = 1; -+#if defined(CONFIG_DSSCOMP) -+ psDevInfo->sDisplayInfo.ui32MinSwapInterval = 1; -+#endif -+ } -+ -+ psDevInfo->sDisplayInfo.ui32PhysicalWidthmm = psDevInfo->sFBInfo.ulPhysicalWidthmm; -+ psDevInfo->sDisplayInfo.ui32PhysicalHeightmm = psDevInfo->sFBInfo.ulPhysicalHeightmm; -+ -+ strncpy(psDevInfo->sDisplayInfo.szDisplayName, DISPLAY_DEVICE_NAME, MAX_DISPLAY_NAME_SIZE); -+ -+ psDevInfo->sDisplayFormat.pixelformat = psDevInfo->sFBInfo.ePixelFormat; -+ psDevInfo->sDisplayDim.ui32Width = (IMG_UINT32)psDevInfo->sFBInfo.ulWidth; -+ psDevInfo->sDisplayDim.ui32Height = (IMG_UINT32)psDevInfo->sFBInfo.ulHeight; -+ psDevInfo->sDisplayDim.ui32ByteStride = (IMG_UINT32)psDevInfo->sFBInfo.ulByteStride; -+ -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX -+ ": Device %u: Maximum number of swap chain buffers: %u\n", -+ psDevInfo->uiFBDevID, psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers)); -+ -+ /* Setup system buffer */ -+ psDevInfo->sSystemBuffer.sSysAddr = psDevInfo->sFBInfo.sSysAddr; -+ psDevInfo->sSystemBuffer.sCPUVAddr = psDevInfo->sFBInfo.sCPUVAddr; -+ psDevInfo->sSystemBuffer.psDevInfo = psDevInfo; -+ -+ OMAPLFBInitBufferForSwap(&psDevInfo->sSystemBuffer); -+#else -+psDevInfo->sSystemBuffer.sCPUVAddr = 0x100; -+// psDevInfo->sSystemBuffer.ulBufferSize = 600*3200; -+ -+ psDevInfo->sDisplayFormat.pixelformat = 20; -+ psDevInfo->sFBInfo.ulWidth = 800; -+ psDevInfo->sFBInfo.ulHeight = 600; -+ psDevInfo->sFBInfo.ulByteStride = 3200; -+ psDevInfo->sFBInfo.ulFBSize = 8388608; -+ psDevInfo->sFBInfo.ulBufferSize = 600*3200; -+#endif -+ -+ -+#if defined(CONFIG_DSSCOMP) && defined(SUPPORT_PVRSRV_GET_DC_SYSTEM_BUFFER) -+ OMAPLFBFlip(psDevInfo, &psDevInfo->sSystemBuffer); -+#endif -+ -+ /* -+ Setup the DC Jtable so SRVKM can call into this driver -+ */ -+ psDevInfo->sDCJTable.ui32TableSize = sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE); -+ psDevInfo->sDCJTable.pfnOpenDCDevice = OpenDCDevice; -+ psDevInfo->sDCJTable.pfnCloseDCDevice = CloseDCDevice; -+ psDevInfo->sDCJTable.pfnEnumDCFormats = EnumDCFormats; -+ psDevInfo->sDCJTable.pfnEnumDCDims = EnumDCDims; -+ psDevInfo->sDCJTable.pfnGetDCSystemBuffer = GetDCSystemBuffer; -+ psDevInfo->sDCJTable.pfnGetDCInfo = GetDCInfo; -+ psDevInfo->sDCJTable.pfnGetBufferAddr = GetDCBufferAddr; -+ psDevInfo->sDCJTable.pfnCreateDCSwapChain = CreateDCSwapChain; -+ psDevInfo->sDCJTable.pfnDestroyDCSwapChain = DestroyDCSwapChain; -+ psDevInfo->sDCJTable.pfnSetDCDstRect = SetDCDstRect; -+ psDevInfo->sDCJTable.pfnSetDCSrcRect = SetDCSrcRect; -+ psDevInfo->sDCJTable.pfnSetDCDstColourKey = SetDCDstColourKey; -+ psDevInfo->sDCJTable.pfnSetDCSrcColourKey = SetDCSrcColourKey; -+ psDevInfo->sDCJTable.pfnGetDCBuffers = GetDCBuffers; -+ psDevInfo->sDCJTable.pfnSwapToDCBuffer = SwapToDCBuffer; -+ psDevInfo->sDCJTable.pfnSetDCState = SetDCState; -+ -+ /* Register device with services and retrieve device index */ -+ if(psDevInfo->sPVRJTable.pfnPVRSRVRegisterDCDevice( -+ &psDevInfo->sDCJTable, -+ &psDevInfo->uiPVRDevID) != PVRSRV_OK) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ ": %s: Device %u: PVR Services device registration failed\n", __FUNCTION__, uiFBDevID); -+ -+ goto ErrorDeInitFBDev; -+ } -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX -+ ": Device %u: PVR Device ID: %u\n", -+ psDevInfo->uiFBDevID, psDevInfo->uiPVRDevID)); -+ -+ /* Setup private command processing function table ... */ -+ pfnCmdProcList[DC_FLIP_COMMAND] = ProcessFlip; -+ -+ /* ... and associated sync count(s) */ -+ aui32SyncCountList[DC_FLIP_COMMAND][0] = 0; /* writes */ -+ aui32SyncCountList[DC_FLIP_COMMAND][1] = 10; /* reads */ -+ -+ /* -+ Register private command processing functions with -+ the Command Queue Manager and setup the general -+ command complete function in the devinfo. -+ */ -+ if (psDevInfo->sPVRJTable.pfnPVRSRVRegisterCmdProcList(psDevInfo->uiPVRDevID, -+ &pfnCmdProcList[0], -+ aui32SyncCountList, -+ OMAPLFB_COMMAND_COUNT) != PVRSRV_OK) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ ": %s: Device %u: Couldn't register command processing functions with PVR Services\n", __FUNCTION__, uiFBDevID); -+ goto ErrorUnregisterDevice; -+ } -+ -+ OMAPLFBCreateSwapChainLockInit(psDevInfo); -+ -+ OMAPLFBAtomicBoolInit(&psDevInfo->sBlanked, OMAPLFB_FALSE); -+ OMAPLFBAtomicIntInit(&psDevInfo->sBlankEvents, 0); -+ OMAPLFBAtomicBoolInit(&psDevInfo->sFlushCommands, OMAPLFB_FALSE); -+#if defined(CONFIG_HAS_EARLYSUSPEND) -+ OMAPLFBAtomicBoolInit(&psDevInfo->sEarlySuspendFlag, OMAPLFB_FALSE); -+#endif -+#if defined(SUPPORT_DRI_DRM) -+ OMAPLFBAtomicBoolInit(&psDevInfo->sLeaveVT, OMAPLFB_FALSE); -+#endif -+ -+ return psDevInfo; -+ -+ErrorUnregisterDevice: -+ (void)psDevInfo->sPVRJTable.pfnPVRSRVRemoveDCDevice(psDevInfo->uiPVRDevID); -+ErrorDeInitFBDev: -+ OMAPLFBDeInitFBDev(psDevInfo); -+ErrorIonClientDestroy: -+#if defined(CONFIG_ION_OMAP) -+ ion_client_destroy(psDevInfo->psIONClient); -+#endif /* defined(CONFIG_ION_OMAP) */ -+ErrorFreeDevInfo: -+ OMAPLFBFreeKernelMem(psDevInfo); -+ErrorExit: -+ return NULL; -+} -+ -+OMAPLFB_ERROR OMAPLFBInit(void) -+{ -+ unsigned uiMaxFBDevIDPlusOne = OMAPLFBMaxFBDevIDPlusOne(); -+ unsigned i; -+ unsigned uiDevicesFound = 0; -+ -+ if(OMAPLFBGetLibFuncAddr ("PVRGetDisplayClassJTable", &gpfnGetPVRJTable) != OMAPLFB_OK) -+ { -+ return OMAPLFB_ERROR_INIT_FAILURE; -+ } -+ -+ /* -+ * We search for frame buffer devices backwards, as the last device -+ * registered with PVR Services will be the first device enumerated -+ * by PVR Services. -+ */ -+ for(i = uiMaxFBDevIDPlusOne; i-- != 0;) -+ { -+ OMAPLFB_DEVINFO *psDevInfo = OMAPLFBInitDev(i); -+ -+ if (psDevInfo != NULL) -+ { -+ /* Set the top-level anchor */ -+ OMAPLFBSetDevInfoPtr(psDevInfo->uiFBDevID, psDevInfo); -+ uiDevicesFound++; -+ } -+ } -+ -+ return (uiDevicesFound != 0) ? OMAPLFB_OK : OMAPLFB_ERROR_INIT_FAILURE; -+} -+ -+/* -+ * OMAPLFBDeInitDev -+ * DeInitialises one device -+ */ -+static OMAPLFB_BOOL OMAPLFBDeInitDev(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ PVRSRV_DC_DISP2SRV_KMJTABLE *psPVRJTable = &psDevInfo->sPVRJTable; -+ -+ if (psPVRJTable->pfnPVRSRVRemoveCmdProcList (psDevInfo->uiPVRDevID, OMAPLFB_COMMAND_COUNT) != PVRSRV_OK) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ ": %s: Device %u: PVR Device %u: Couldn't unregister command processing functions\n", __FUNCTION__, psDevInfo->uiFBDevID, psDevInfo->uiPVRDevID); -+ return OMAPLFB_FALSE; -+ } -+ -+ /* -+ * Remove display class device from kernel services device -+ * register. -+ */ -+ if (psPVRJTable->pfnPVRSRVRemoveDCDevice(psDevInfo->uiPVRDevID) != PVRSRV_OK) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ ": %s: Device %u: PVR Device %u: Couldn't remove device from PVR Services\n", __FUNCTION__, psDevInfo->uiFBDevID, psDevInfo->uiPVRDevID); -+ return OMAPLFB_FALSE; -+ } -+ -+#if defined(CONFIG_DSSCOMP) -+ /* Disable the overlay, as we will be freeing the display buffers */ -+ psDevInfo->sSystemBuffer.sSysAddr.uiAddr = 0; -+ OMAPLFBFlip(psDevInfo, &psDevInfo->sSystemBuffer); -+#endif /* defined(CONFIG_DSSCOMP) */ -+ -+ OMAPLFBCreateSwapChainLockDeInit(psDevInfo); -+ -+ OMAPLFBAtomicBoolDeInit(&psDevInfo->sBlanked); -+ OMAPLFBAtomicIntDeInit(&psDevInfo->sBlankEvents); -+ OMAPLFBAtomicBoolDeInit(&psDevInfo->sFlushCommands); -+#if defined(CONFIG_HAS_EARLYSUSPEND) -+ OMAPLFBAtomicBoolDeInit(&psDevInfo->sEarlySuspendFlag); -+#endif -+#if defined(SUPPORT_DRI_DRM) -+ OMAPLFBAtomicBoolDeInit(&psDevInfo->sLeaveVT); -+#endif -+ -+#ifdef FBDEV_PRESENT -+ OMAPLFBDeInitFBDev(psDevInfo); -+#endif -+ -+#if defined(CONFIG_ION_OMAP) -+ ion_client_destroy(psDevInfo->psIONClient); -+#endif -+ -+ OMAPLFBSetDevInfoPtr(psDevInfo->uiFBDevID, NULL); -+ -+ /* De-allocate data structure */ -+ OMAPLFBFreeKernelMem(psDevInfo); -+ -+ return OMAPLFB_TRUE; -+} -+ -+/* -+ * OMAPLFBDeInit -+ * Deinitialises the display class device component of the FBDev -+ */ -+OMAPLFB_ERROR OMAPLFBDeInit(void) -+{ -+ unsigned uiMaxFBDevIDPlusOne = OMAPLFBMaxFBDevIDPlusOne(); -+ unsigned i; -+ OMAPLFB_BOOL bError = OMAPLFB_FALSE; -+ -+ for(i = 0; i < uiMaxFBDevIDPlusOne; i++) -+ { -+ OMAPLFB_DEVINFO *psDevInfo = OMAPLFBGetDevInfoPtr(i); -+ -+ if (psDevInfo != NULL) -+ { -+ bError |= !OMAPLFBDeInitDev(psDevInfo); -+ } -+ } -+ -+ return (bError) ? OMAPLFB_ERROR_INIT_FAILURE : OMAPLFB_OK; -+} -+ -+/****************************************************************************** -+ End of file (omaplfb_displayclass.c) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti335x_linux/omaplfb_linux.c b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti335x_linux/omaplfb_linux.c -new file mode 100644 -index 0000000..92c5574 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti335x_linux/omaplfb_linux.c -@@ -0,0 +1,1344 @@ -+/*************************************************************************/ /*! -+@Title OMAP linux display driver components -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+/************************************************************************** -+ The 3rd party driver is a specification of an API to integrate the IMG POWERVR -+ Services driver with 3rd Party display hardware. It is NOT a specification for -+ a display controller driver, rather a specification to extend the API for a -+ pre-existing driver for the display hardware. -+ -+ The 3rd party driver interface provides IMG POWERVR client drivers (e.g. PVR2D) -+ with an API abstraction of the system's underlying display hardware, allowing -+ the client drivers to indirectly control the display hardware and access its -+ associated memory. -+ -+ Functions of the API include -+ - query primary surface attributes (width, height, stride, pixel format, CPU -+ physical and virtual address) -+ - swap/flip chain creation and subsequent query of surface attributes -+ - asynchronous display surface flipping, taking account of asynchronous read -+ (flip) and write (render) operations to the display surface -+ -+ Note: having queried surface attributes the client drivers are able to map the -+ display memory to any IMG POWERVR Services device by calling -+ PVRSRVMapDeviceClassMemory with the display surface handle. -+ -+ This code is intended to be an example of how a pre-existing display driver may -+ be extended to support the 3rd Party Display interface to POWERVR Services -+ - IMG is not providing a display driver implementation. -+ **************************************************************************/ -+ -+#include <linux/version.h> -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)) -+#ifndef AUTOCONF_INCLUDED -+#include <linux/config.h> -+#endif -+#endif -+ -+#include <asm/atomic.h> -+ -+#if defined(SUPPORT_DRI_DRM) -+#include <drm/drmP.h> -+#else -+#include <linux/module.h> -+#endif -+ -+#include <linux/kernel.h> -+#include <linux/slab.h> -+#include <linux/hardirq.h> -+#include <linux/mutex.h> -+#include <linux/workqueue.h> -+#include <linux/fb.h> -+#include <linux/console.h> -+#include <linux/omapfb.h> -+#include <linux/mutex.h> -+ -+#include <video/da8xx-fb.h> -+#if defined(PVR_OMAPLFB_DRM_FB) -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0)) -+#include <plat/display.h> -+#else -+#include <video/omapdss.h> -+#endif -+#include <linux/omap_gpu.h> -+#else /* defined(PVR_OMAPLFB_DRM_FB) */ -+/* OmapZoom.org OMAP3 2.6.29 kernel tree - Needs mach/vrfb.h -+ * OmapZoom.org OMAP3 2.6.32 kernel tree - No additional header required -+ * OmapZoom.org OMAP4 2.6.33 kernel tree - No additional header required -+ * OmapZoom.org OMAP4 2.6.34 kernel tree - Needs plat/vrfb.h -+ * Sholes 2.6.32 kernel tree - Needs plat/vrfb.h -+ */ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34)) -+#define PVR_OMAPFB3_NEEDS_PLAT_VRFB_H -+#endif -+ -+#if defined(PVR_OMAPFB3_NEEDS_PLAT_VRFB_H) -+#ifdef FBDEV_PRESENT -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) -+#include <plat/vrfb.h> -+#else -+#include <video/omapvrfb.h> -+#endif -+#endif -+ -+#else -+#if defined(PVR_OMAPFB3_NEEDS_MACH_VRFB_H) -+#include <mach/vrfb.h> -+#endif -+#endif -+ -+#if defined(DEBUG) -+#define PVR_DEBUG DEBUG -+#undef DEBUG -+#endif -+#ifdef FBDEV_PRESENT -+#include <omapfb/omapfb.h> -+#endif -+#if defined(DEBUG) -+#undef DEBUG -+#endif -+#if defined(PVR_DEBUG) -+#define DEBUG PVR_DEBUG -+#undef PVR_DEBUG -+#endif -+#endif /* defined(PVR_OMAPLFB_DRM_FB) */ -+ -+#if defined(CONFIG_DSSCOMP) -+#if defined(CONFIG_DRM_OMAP_DMM_TILER) -+#include <../drivers/staging/omapdrm/omap_dmm_tiler.h> -+#include <../drivers/video/omap2/dsscomp/tiler-utils.h> -+#elif defined(CONFIG_TI_TILER) -+#include <mach/tiler.h> -+#else /* defined(CONFIG_DRM_OMAP_DMM_TILER) */ -+#error CONFIG_DSSCOMP support requires either \ -+ CONFIG_DRM_OMAP_DMM_TILER or CONFIG_TI_TILER -+#endif /* defined(CONFIG_DRM_OMAP_DMM_TILER) */ -+#include <video/dsscomp.h> -+#include <plat/dsscomp.h> -+#endif /* defined(CONFIG_DSSCOMP) */ -+ -+#include "img_defs.h" -+#include "servicesext.h" -+#include "kerneldisplay.h" -+#include "omaplfb.h" -+#include "pvrmodule.h" -+#if defined(SUPPORT_DRI_DRM) -+#include "pvr_drm.h" -+#include "3rdparty_dc_drm_shared.h" -+#endif -+ -+#if !defined(PVR_LINUX_USING_WORKQUEUES) -+#error "PVR_LINUX_USING_WORKQUEUES must be defined" -+#endif -+ -+MODULE_SUPPORTED_DEVICE(DEVNAME); -+ -+#if !defined(PVR_OMAPLFB_DRM_FB) -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34)) -+#define OMAP_DSS_DRIVER(drv, dev) struct omap_dss_driver *drv = (dev) != NULL ? (dev)->driver : NULL -+//#define OMAP_DSS_MANAGER(man, dev) struct omap_overlay_manager *man = (dev) != NULL ? (dev)->manager : NULL -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0)) -+#define OMAP_DSS_MANAGER(man, dev) struct omap_overlay_manager *man = (dev) != NULL ? (dev)->manager : NULL -+#else -+#define OMAP_DSS_MANAGER(man, dev) struct omap_overlay_manager *man = (dev) != NULL ? (dev)->output->manager : NULL -+#endif -+#define WAIT_FOR_VSYNC(man) ((man)->wait_for_vsync) -+#else -+#define OMAP_DSS_DRIVER(drv, dev) struct omap_dss_device *drv = (dev) -+#define OMAP_DSS_MANAGER(man, dev) struct omap_dss_device *man = (dev) -+#define WAIT_FOR_VSYNC(man) ((man)->wait_vsync) -+#endif -+#endif /* !defined(PVR_OMAPLFB_DRM_FB) */ -+ -+void *OMAPLFBAllocKernelMem(unsigned long ulSize) -+{ -+ return kmalloc(ulSize, GFP_KERNEL); -+} -+ -+void OMAPLFBFreeKernelMem(void *pvMem) -+{ -+ kfree(pvMem); -+} -+ -+void OMAPLFBCreateSwapChainLockInit(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ mutex_init(&psDevInfo->sCreateSwapChainMutex); -+} -+ -+void OMAPLFBCreateSwapChainLockDeInit(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ mutex_destroy(&psDevInfo->sCreateSwapChainMutex); -+} -+ -+void OMAPLFBCreateSwapChainLock(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ mutex_lock(&psDevInfo->sCreateSwapChainMutex); -+} -+ -+void OMAPLFBCreateSwapChainUnLock(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ mutex_unlock(&psDevInfo->sCreateSwapChainMutex); -+} -+ -+void OMAPLFBAtomicBoolInit(OMAPLFB_ATOMIC_BOOL *psAtomic, OMAPLFB_BOOL bVal) -+{ -+ atomic_set(psAtomic, (int)bVal); -+} -+ -+void OMAPLFBAtomicBoolDeInit(OMAPLFB_ATOMIC_BOOL *psAtomic) -+{ -+} -+ -+void OMAPLFBAtomicBoolSet(OMAPLFB_ATOMIC_BOOL *psAtomic, OMAPLFB_BOOL bVal) -+{ -+ atomic_set(psAtomic, (int)bVal); -+} -+ -+OMAPLFB_BOOL OMAPLFBAtomicBoolRead(OMAPLFB_ATOMIC_BOOL *psAtomic) -+{ -+ return (OMAPLFB_BOOL)atomic_read(psAtomic); -+} -+ -+void OMAPLFBAtomicIntInit(OMAPLFB_ATOMIC_INT *psAtomic, int iVal) -+{ -+ atomic_set(psAtomic, iVal); -+} -+ -+void OMAPLFBAtomicIntDeInit(OMAPLFB_ATOMIC_INT *psAtomic) -+{ -+} -+ -+void OMAPLFBAtomicIntSet(OMAPLFB_ATOMIC_INT *psAtomic, int iVal) -+{ -+ atomic_set(psAtomic, iVal); -+} -+ -+int OMAPLFBAtomicIntRead(OMAPLFB_ATOMIC_INT *psAtomic) -+{ -+ return atomic_read(psAtomic); -+} -+ -+void OMAPLFBAtomicIntInc(OMAPLFB_ATOMIC_INT *psAtomic) -+{ -+ atomic_inc(psAtomic); -+} -+ -+OMAPLFB_ERROR OMAPLFBGetLibFuncAddr (char *szFunctionName, PFN_DC_GET_PVRJTABLE *ppfnFuncTable) -+{ -+ if(strcmp("PVRGetDisplayClassJTable", szFunctionName) != 0) -+ { -+ return (OMAPLFB_ERROR_INVALID_PARAMS); -+ } -+ -+ /* Nothing to do - should be exported from pvrsrv.ko */ -+ *ppfnFuncTable = PVRGetDisplayClassJTable; -+ -+ return (OMAPLFB_OK); -+} -+ -+/* Inset a swap buffer into the swap chain work queue */ -+void OMAPLFBQueueBufferForSwap(OMAPLFB_SWAPCHAIN *psSwapChain, OMAPLFB_BUFFER *psBuffer) -+{ -+ int res = queue_work(psSwapChain->psWorkQueue, &psBuffer->sWork); -+ -+ if (res == 0) -+ { -+ printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Buffer already on work queue\n", __FUNCTION__, psSwapChain->uiFBDevID); -+ } -+} -+ -+/* Process an item on a swap chain work queue */ -+static void WorkQueueHandler(struct work_struct *psWork) -+{ -+ OMAPLFB_BUFFER *psBuffer = container_of(psWork, OMAPLFB_BUFFER, sWork); -+ -+ OMAPLFBSwapHandler(psBuffer); -+} -+ -+/* Create a swap chain work queue */ -+OMAPLFB_ERROR OMAPLFBCreateSwapQueue(OMAPLFB_SWAPCHAIN *psSwapChain) -+{ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) -+#if (LINUX_VERSION_CODE == KERNEL_VERSION(2,6,37)) -+#define WQ_FREEZABLE WQ_FREEZEABLE -+#endif -+ /* -+ * Calling alloc_ordered_workqueue with the WQ_FREEZABLE and -+ * WQ_MEM_RECLAIM flags set, (currently) has the same effect as -+ * calling create_freezable_workqueue. None of the other WQ -+ * flags are valid. Setting WQ_MEM_RECLAIM should allow the -+ * workqueue to continue to service the swap chain in low memory -+ * conditions, preventing the driver from holding on to -+ * resources longer than it needs to. -+ */ -+ psSwapChain->psWorkQueue = alloc_ordered_workqueue(DEVNAME, WQ_FREEZABLE | WQ_MEM_RECLAIM); -+#else -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)) -+ psSwapChain->psWorkQueue = create_freezable_workqueue(DEVNAME); -+#else -+ /* -+ * Create a single-threaded, freezable, rt-prio workqueue. -+ * Such workqueues are frozen with user threads when a system -+ * suspends, before driver suspend entry points are called. -+ * This ensures this driver will not call into the Linux -+ * framebuffer driver after the latter is suspended. -+ */ -+ psSwapChain->psWorkQueue = __create_workqueue(DEVNAME, 1, 1, 1); -+#endif -+#endif -+ if (psSwapChain->psWorkQueue == NULL) -+ { -+ printk(KERN_ERR DRIVER_PREFIX ": %s: Device %u: Couldn't create workqueue\n", __FUNCTION__, psSwapChain->uiFBDevID); -+ -+ return (OMAPLFB_ERROR_INIT_FAILURE); -+ } -+ -+ return (OMAPLFB_OK); -+} -+ -+/* Prepare buffer for insertion into a swap chain work queue */ -+void OMAPLFBInitBufferForSwap(OMAPLFB_BUFFER *psBuffer) -+{ -+ INIT_WORK(&psBuffer->sWork, WorkQueueHandler); -+} -+ -+/* Destroy a swap chain work queue */ -+void OMAPLFBDestroySwapQueue(OMAPLFB_SWAPCHAIN *psSwapChain) -+{ -+ destroy_workqueue(psSwapChain->psWorkQueue); -+} -+ -+/* Flip display to given buffer */ -+void OMAPLFBFlip(OMAPLFB_DEVINFO *psDevInfo, OMAPLFB_BUFFER *psBuffer) -+{ -+ struct fb_var_screeninfo sFBVar; -+ int res; -+ -+ if (!lock_fb_info(psDevInfo->psLINFBInfo)) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX -+ ": %s: Device %u: Couldn't lock FB info\n", __FUNCTION__, psDevInfo->uiFBDevID)); -+ return; -+ } -+ -+ -+ OMAPLFB_CONSOLE_LOCK(); -+ -+ sFBVar = psDevInfo->psLINFBInfo->var; -+ -+ sFBVar.xoffset = 0; -+ sFBVar.yoffset = psBuffer->ulYOffset; -+ -+#if defined(CONFIG_DSSCOMP) -+ /* -+ * If flipping to a NULL buffer, blank the screen to prevent -+ * warnings/errors from the display subsystem. -+ */ -+ if (psBuffer->sSysAddr.uiAddr == 0) -+ { -+ struct omap_dss_device *psDSSDev = fb2display(psDevInfo->psLINFBInfo); -+ OMAP_DSS_MANAGER(psDSSMan, psDSSDev); -+ -+ if (psDSSMan != NULL && psDSSMan->blank != NULL) -+ { -+ res = psDSSMan->blank(psDSSMan, false); -+ if (res != 0) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: DSS manager blank call failed (Y Offset: %lu, Error: %d)\n", __FUNCTION__, psDevInfo->uiFBDevID, psBuffer->ulYOffset, res)); -+ } -+ } -+ } -+ -+ { -+ /* -+ * If using DSSCOMP, we need to use dsscomp queuing for normal -+ * framebuffer updates, so that previously used overlays get -+ * automatically disabled, and manager gets dirtied. We can -+ * do that because DSSCOMP takes ownership of all pipelines on -+ * a manager. -+ */ -+ struct fb_fix_screeninfo sFBFix = psDevInfo->psLINFBInfo->fix; -+ struct dsscomp_setup_dispc_data d = -+ { -+ .num_ovls = 1, -+ .num_mgrs = 1, -+ .mgrs[0].alpha_blending = 1, -+ .ovls[0] = -+ { -+ .cfg = -+ { -+ .win.w = sFBVar.xres, -+ .win.h = sFBVar.yres, -+ .crop.x = sFBVar.xoffset, -+ .crop.y = sFBVar.yoffset, -+ .crop.w = sFBVar.xres, -+ .crop.h = sFBVar.yres, -+ .width = sFBVar.xres_virtual, -+ .height = sFBVar.yres_virtual, -+ .stride = sFBFix.line_length, -+ .enabled = (psBuffer->sSysAddr.uiAddr != 0), -+ .global_alpha = 255, -+ }, -+ }, -+ }; -+ -+ /* do not map buffer into TILER1D as it is contiguous */ -+ struct tiler_pa_info *pas[] = { NULL }; -+ -+ d.ovls[0].ba = (u32) psBuffer->sSysAddr.uiAddr; -+ -+ omapfb_mode_to_dss_mode(&sFBVar, &d.ovls[0].cfg.color_mode); -+ -+ res = dsscomp_gralloc_queue(&d, pas, true, NULL, NULL); -+ if (res != 0) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: dsscomp_gralloc_queue failed (Y Offset: %lu, Error: %d)\n", __FUNCTION__, psDevInfo->uiFBDevID, psBuffer->ulYOffset, res)); -+ } -+ } -+#else /* defined(CONFIG_DSSCOMP) */ -+ { -+ unsigned long ulYResVirtual = psBuffer->ulYOffset + sFBVar.yres; -+ -+ /* -+ * PVR_OMAPLFB_DONT_USE_FB_PAN_DISPLAY should be defined to -+ * work around flipping problems seen with the Taal LCDs on -+ * Blaze. -+ * The work around is safe to use with other types of screen -+ * on Blaze (e.g. HDMI) and on other platforms (e.g. Panda -+ * board). -+ */ -+#if !defined(PVR_OMAPLFB_DONT_USE_FB_PAN_DISPLAY) -+ /* -+ * Attempt to change the virtual screen resolution if it is too -+ * small. Note that fb_set_var also pans the display. -+ */ -+ if (sFBVar.xres_virtual != sFBVar.xres || sFBVar.yres_virtual < ulYResVirtual) -+#endif /* !defined(PVR_OMAPLFB_DONT_USE_FB_PAN_DISPLAY) */ -+ { -+ sFBVar.xres_virtual = sFBVar.xres; -+ sFBVar.yres_virtual = ulYResVirtual; -+ -+ sFBVar.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE; -+ -+ res = fb_set_var(psDevInfo->psLINFBInfo, &sFBVar); -+ if (res != 0) -+ { -+ printk(KERN_ERR DRIVER_PREFIX ": %s: Device %u: fb_set_var failed (Y Offset: %lu, Error: %d)\n", __FUNCTION__, psDevInfo->uiFBDevID, psBuffer->ulYOffset, res); -+ } -+ } -+#if !defined(PVR_OMAPLFB_DONT_USE_FB_PAN_DISPLAY) -+ else -+ { -+ res = fb_pan_display(psDevInfo->psLINFBInfo, &sFBVar); -+ if (res != 0) -+ { -+ printk(KERN_ERR DRIVER_PREFIX ": %s: Device %u: fb_pan_display failed (Y Offset: %lu, Error: %d)\n", __FUNCTION__, psDevInfo->uiFBDevID, psBuffer->ulYOffset, res); -+ } -+ } -+#endif /* !defined(PVR_OMAPLFB_DONT_USE_FB_PAN_DISPLAY) */ -+ } -+#endif /* defined(CONFIG_DSSCOMP) */ -+ -+ OMAPLFB_CONSOLE_UNLOCK(); -+ unlock_fb_info(psDevInfo->psLINFBInfo); -+} -+ -+/* Newer kernels don't have any update mode capability */ -+ -+//#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) -+//#define PVR_OMAPLFB_HAS_UPDATE_MODE -+//#endif -+ -+//#if defined(PVR_OMAPLFB_HAS_UPDATE_MODE) -+#if !defined(PVR_OMAPLFB_DRM_FB) || defined(DEBUG) -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0) -+static OMAPLFB_BOOL OMAPLFBValidateDSSUpdateMode(enum omap_dss_update_mode eMode) -+{ -+ switch (eMode) -+ { -+ case OMAP_DSS_UPDATE_AUTO: -+ case OMAP_DSS_UPDATE_MANUAL: -+ case OMAP_DSS_UPDATE_DISABLED: -+ return OMAPLFB_TRUE; -+ default: -+ break; -+ } -+ -+ return OMAPLFB_FALSE; -+} -+ -+static OMAPLFB_UPDATE_MODE OMAPLFBFromDSSUpdateMode(enum omap_dss_update_mode eMode) -+{ -+ switch (eMode) -+ { -+ case OMAP_DSS_UPDATE_AUTO: -+ return OMAPLFB_UPDATE_MODE_AUTO; -+ case OMAP_DSS_UPDATE_MANUAL: -+ return OMAPLFB_UPDATE_MODE_MANUAL; -+ case OMAP_DSS_UPDATE_DISABLED: -+ return OMAPLFB_UPDATE_MODE_DISABLED; -+ default: -+ break; -+ } -+ -+ return OMAPLFB_UPDATE_MODE_UNDEFINED; -+} -+#endif -+#endif -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0) -+static OMAPLFB_BOOL OMAPLFBValidateUpdateMode(OMAPLFB_UPDATE_MODE eMode) -+{ -+ switch(eMode) -+ { -+ case OMAPLFB_UPDATE_MODE_AUTO: -+ case OMAPLFB_UPDATE_MODE_MANUAL: -+ case OMAPLFB_UPDATE_MODE_DISABLED: -+ return OMAPLFB_TRUE; -+ default: -+ break; -+ } -+ -+ return OMAPLFB_FALSE; -+} -+#endif -+ -+#if 0 -+static enum omap_dss_update_mode OMAPLFBToDSSUpdateMode(OMAPLFB_UPDATE_MODE eMode) -+{ -+ switch(eMode) -+ { -+ case OMAPLFB_UPDATE_MODE_AUTO: -+ return OMAP_DSS_UPDATE_AUTO; -+ case OMAPLFB_UPDATE_MODE_MANUAL: -+ return OMAP_DSS_UPDATE_MANUAL; -+ case OMAPLFB_UPDATE_MODE_DISABLED: -+ return OMAP_DSS_UPDATE_DISABLED; -+ default: -+ break; -+ } -+ -+ return -1; -+} -+#endif -+#if defined(DEBUG) -+static const char *OMAPLFBUpdateModeToString(OMAPLFB_UPDATE_MODE eMode) -+{ -+ switch(eMode) -+ { -+ case OMAPLFB_UPDATE_MODE_AUTO: -+ return "Auto Update Mode"; -+ case OMAPLFB_UPDATE_MODE_MANUAL: -+ return "Manual Update Mode"; -+ case OMAPLFB_UPDATE_MODE_DISABLED: -+ return "Update Mode Disabled"; -+ case OMAPLFB_UPDATE_MODE_UNDEFINED: -+ return "Update Mode Undefined"; -+ default: -+ break; -+ } -+ -+ return "Unknown Update Mode"; -+} -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0) -+static const char *OMAPLFBDSSUpdateModeToString(enum omap_dss_update_mode eMode) -+{ -+ if (!OMAPLFBValidateDSSUpdateMode(eMode)) -+ { -+ return "Unknown Update Mode"; -+ } -+ -+ return OMAPLFBUpdateModeToString(OMAPLFBFromDSSUpdateMode(eMode)); -+} -+#endif -+#endif /* defined(DEBUG) */ -+ -+/* -+ * Get display update mode. -+ * If the mode is AUTO, we can wait for VSync, if desired. -+ */ -+OMAPLFB_UPDATE_MODE OMAPLFBGetUpdateMode(OMAPLFB_DEVINFO *psDevInfo) -+{ -+#if defined(PVR_OMAPLFB_DRM_FB) -+ struct drm_connector *psConnector; -+ OMAPLFB_UPDATE_MODE eMode = OMAPLFB_UPDATE_MODE_UNDEFINED; -+ -+ /* -+ * There may be multiple displays connected. If at least one -+ * display is manual update mode, report all screens as being -+ * in that mode. -+ */ -+ for (psConnector = NULL; -+ (psConnector = omap_fbdev_get_next_connector(psDevInfo->psLINFBInfo, psConnector)) != NULL;) -+ { -+ switch(omap_connector_get_update_mode(psConnector)) -+ { -+ case OMAP_DSS_UPDATE_MANUAL: -+ eMode = OMAPLFB_UPDATE_MODE_MANUAL; -+ break; -+ case OMAP_DSS_UPDATE_DISABLED: -+ if (eMode == OMAPLFB_UPDATE_MODE_UNDEFINED) -+ { -+ eMode = OMAPLFB_UPDATE_MODE_DISABLED; -+ } -+ break; -+ case OMAP_DSS_UPDATE_AUTO: -+ /* Fall through to default case */ -+ default: -+ /* Asssume auto update is possible */ -+ if (eMode != OMAPLFB_UPDATE_MODE_MANUAL) -+ { -+ eMode = OMAPLFB_UPDATE_MODE_AUTO; -+ } -+ break; -+ } -+ } -+ -+ return eMode; -+#else /* defined(PVR_OMAPLFB_DRM_FB) */ -+#if 0 -+ struct omap_dss_device *psDSSDev = fb2display(psDevInfo->psLINFBInfo); -+ OMAP_DSS_DRIVER(psDSSDrv, psDSSDev); -+ -+ enum omap_dss_update_mode eMode; -+ -+ if (psDSSDrv == NULL) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: No DSS device\n", __FUNCTION__, psDevInfo->uiFBDevID)); -+ return OMAPLFB_UPDATE_MODE_UNDEFINED; -+ } -+ -+ if (psDSSDrv->get_update_mode == NULL) -+ { -+ if (strcmp(psDSSDev->name, "hdmi") == 0) -+ { -+ return OMAPLFB_UPDATE_MODE_AUTO; -+ } -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: No get_update_mode function\n", __FUNCTION__, psDevInfo->uiFBDevID)); -+ return OMAPLFB_UPDATE_MODE_UNDEFINED; -+ } -+ -+ eMode = psDSSDrv->get_update_mode(psDSSDev); -+ if (!OMAPLFBValidateDSSUpdateMode(eMode)) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Unknown update mode (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, (int)eMode)); -+ } -+ -+ return OMAPLFBFromDSSUpdateMode(eMode); -+#endif -+return OMAPLFB_UPDATE_MODE_AUTO; -+#endif /* defined(PVR_OMAPLFB_DRM_FB) */ -+} -+ -+/* Set display update mode */ -+OMAPLFB_BOOL OMAPLFBSetUpdateMode(OMAPLFB_DEVINFO *psDevInfo, OMAPLFB_UPDATE_MODE eMode) -+{ -+#if defined(PVR_OMAPLFB_DRM_FB) -+ struct drm_connector *psConnector; -+ enum omap_dss_update_mode eDSSMode; -+ OMAPLFB_BOOL bSuccess = OMAPLFB_FALSE; -+ OMAPLFB_BOOL bFailure = OMAPLFB_FALSE; -+ -+ if (!OMAPLFBValidateUpdateMode(eMode)) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Unknown update mode (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, (int)eMode)); -+ return OMAPLFB_FALSE; -+ } -+ eDSSMode = OMAPLFBToDSSUpdateMode(eMode); -+ -+ for (psConnector = NULL; -+ (psConnector = omap_fbdev_get_next_connector(psDevInfo->psLINFBInfo, psConnector)) != NULL;) -+ { -+ int iRes = omap_connector_set_update_mode(psConnector, eDSSMode); -+ OMAPLFB_BOOL bRes = (iRes == 0); -+ -+ -+ bSuccess |= bRes; -+ bFailure |= !bRes; -+ } -+ -+ if (!bFailure) -+ { -+ if (!bSuccess) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: No screens\n", __FUNCTION__, psDevInfo->uiFBDevID)); -+ } -+ -+ return OMAPLFB_TRUE; -+ } -+ -+ if (!bSuccess) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Couldn't set %s for any screen\n", __FUNCTION__, psDevInfo->uiFBDevID, OMAPLFBUpdateModeToString(eMode))); -+ return OMAPLFB_FALSE; -+ } -+ -+ if (eMode == OMAPLFB_UPDATE_MODE_AUTO) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Couldn't set %s for all screens\n", __FUNCTION__, psDevInfo->uiFBDevID, OMAPLFBUpdateModeToString(eMode))); -+ return OMAPLFB_FALSE; -+ } -+ -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": %s: Device %u: %s set for some screens\n", __FUNCTION__, psDevInfo->uiFBDevID, OMAPLFBUpdateModeToString(eMode))); -+ -+ return OMAPLFB_TRUE; -+#else /* defined(PVR_OMAPLFB_DRM_FB) */ -+#if 0 -+ struct omap_dss_device *psDSSDev = fb2display(psDevInfo->psLINFBInfo); -+ OMAP_DSS_DRIVER(psDSSDrv, psDSSDev); -+ enum omap_dss_update_mode eDSSMode; -+ int res; -+ -+ if (psDSSDrv == NULL || psDSSDrv->set_update_mode == NULL) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Can't set update mode\n", __FUNCTION__, psDevInfo->uiFBDevID)); -+ return OMAPLFB_FALSE; -+ } -+ -+ if (!OMAPLFBValidateUpdateMode(eMode)) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Unknown update mode (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, (int)eMode)); -+ return OMAPLFB_FALSE; -+ } -+ eDSSMode = OMAPLFBToDSSUpdateMode(eMode); -+ -+ res = psDSSDrv->set_update_mode(psDSSDev, eDSSMode); -+ if (res != 0) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: set_update_mode (%s) failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, OMAPLFBDSSUpdateModeToString(eDSSMode), res)); -+ } -+ -+ return (res == 0); -+#endif -+return 1; -+#endif /* defined(PVR_OMAPLFB_DRM_FB) */ -+} -+//#else /* defined(PVR_OMAPLFB_HAS_UPDATE_MODE) */ -+ -+//OMAPLFB_UPDATE_MODE OMAPLFBGetUpdateMode(OMAPLFB_DEVINFO *psDevInfo) -+//{ -+// return OMAPLFB_UPDATE_MODE_UNDEFINED; -+//} -+ -+//#endif /* defined(PVR_OMAPLFB_HAS_UPDATE_MODE) */ -+ -+#if defined(DEBUG) -+void OMAPLFBPrintInfo(OMAPLFB_DEVINFO *psDevInfo) -+{ -+#if defined(PVR_OMAPLFB_DRM_FB) -+ struct drm_connector *psConnector; -+ unsigned uConnectors; -+ unsigned uConnector; -+ -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": Device %u: DRM framebuffer\n", psDevInfo->uiFBDevID)); -+ -+ for (psConnector = NULL, uConnectors = 0; -+ (psConnector = omap_fbdev_get_next_connector(psDevInfo->psLINFBInfo, psConnector)) != NULL;) -+ { -+ uConnectors++; -+ } -+ -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": Device %u: Number of screens (DRM connectors): %u\n", psDevInfo->uiFBDevID, uConnectors)); -+ -+ if (uConnectors == 0) -+ { -+ return; -+ } -+ -+ for (psConnector = NULL, uConnector = 0; -+ (psConnector = omap_fbdev_get_next_connector(psDevInfo->psLINFBInfo, psConnector)) != NULL; uConnector++) -+ { -+ enum omap_dss_update_mode eMode = omap_connector_get_update_mode(psConnector); -+ -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": Device %u: Screen %u: %s (%d)\n", psDevInfo->uiFBDevID, uConnector, OMAPLFBDSSUpdateModeToString(eMode), (int)eMode)); -+ -+ } -+#else /* defined(PVR_OMAPLFB_DRM_FB) */ -+//#if defined(PVR_OMAPLFB_HAS_UPDATE_MODE) -+ OMAPLFB_UPDATE_MODE eMode = OMAPLFBGetUpdateMode(psDevInfo); -+ -+// DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": Device %u: %s\n", psDevInfo->uiFBDevID, OMAPLFBUpdateModeToString(eMode))); -+//#endif -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": Device %u: non-DRM framebuffer\n", psDevInfo->uiFBDevID)); -+ -+#endif /* defined(PVR_OMAPLFB_DRM_FB) */ -+} -+#endif /* defined(DEBUG) */ -+ -+/* Wait for VSync */ -+OMAPLFB_BOOL OMAPLFBWaitForVSync(OMAPLFB_DEVINFO *psDevInfo) -+{ -+#if defined(PVR_OMAPLFB_DRM_FB) -+ struct drm_connector *psConnector; -+ -+ for (psConnector = NULL; -+ (psConnector = omap_fbdev_get_next_connector(psDevInfo->psLINFBInfo, psConnector)) != NULL;) -+ { -+ (void) omap_encoder_wait_for_vsync(psConnector->encoder); -+ } -+ -+ return OMAPLFB_TRUE; -+#else /* defined(PVR_OMAPLFB_DRM_FB) */ -+#if 0 -+ struct omap_dss_device *psDSSDev = fb2display(psDevInfo->psLINFBInfo); -+ OMAP_DSS_MANAGER(psDSSMan, psDSSDev); -+ -+ if (psDSSMan != NULL && WAIT_FOR_VSYNC(psDSSMan) != NULL) -+ { -+ int res = WAIT_FOR_VSYNC(psDSSMan)(psDSSMan); -+ if (res != 0) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Wait for vsync failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, res)); -+ return OMAPLFB_FALSE; -+ } -+ } -+ -+ return OMAPLFB_TRUE; -+#endif -+#endif /* defined(PVR_OMAPLFB_DRM_FB) */ -+#if FBDEV_PRESENT -+ int r; -+ -+ void grpx_irq_wait_handler(void *data) -+ { -+ if (data != NULL) -+ complete((struct completion *)data); -+// do_gettimeofday(&tv); -+ // curtime=tv.tv_usec; -+//printk("The time in handler is %ld\n",curtime); -+ } -+ DECLARE_COMPLETION_ONSTACK(completion); -+ -+ if (register_vsync_cb((vsync_callback_t)grpx_irq_wait_handler, &completion, psDevInfo->uiFBDevID) != 0) -+ { -+ printk (KERN_WARNING DRIVER_PREFIX ": Failed to register for vsync call back\n"); -+ return OMAPLFB_FALSE; -+ } -+//do_gettimeofday(&tv); -+//curtime=tv.tv_usec; -+//printk("The time is %ld\n",curtime); -+// timeout = wait_for_completion_interruptible_timeout(&completion, timeout); -+ r = wait_for_completion_interruptible(&completion); -+ if (unregister_vsync_cb((vsync_callback_t)grpx_irq_wait_handler , &completion, psDevInfo->uiFBDevID) != 0) -+ { -+ printk (KERN_WARNING DRIVER_PREFIX ": Failed to un-register for vsync call back\n"); -+ return OMAPLFB_FALSE; -+ } -+#endif -+ return OMAPLFB_TRUE; -+ -+ -+} -+ -+/* -+ * Wait for screen to update. If the screen is in manual or auto update -+ * mode, we can call this function to wait for the screen to update. -+ */ -+OMAPLFB_BOOL OMAPLFBManualSync(OMAPLFB_DEVINFO *psDevInfo) -+{ -+#if defined(PVR_OMAPLFB_DRM_FB) -+ struct drm_connector *psConnector; -+ -+ for (psConnector = NULL; -+ (psConnector = omap_fbdev_get_next_connector(psDevInfo->psLINFBInfo, psConnector)) != NULL; ) -+ { -+ /* Try manual sync first, then try wait for vsync */ -+ if (omap_connector_sync(psConnector) != 0) -+ { -+ (void) omap_encoder_wait_for_vsync(psConnector->encoder); -+ } -+ } -+ -+ return OMAPLFB_TRUE; -+#else /* defined(PVR_OMAPLFB_DRM_FB) */ -+#if 0 -+ struct omap_dss_device *psDSSDev = fb2display(psDevInfo->psLINFBInfo); -+ OMAP_DSS_DRIVER(psDSSDrv, psDSSDev); -+ -+ if (psDSSDrv != NULL && psDSSDrv->sync != NULL) -+ { -+ int res = psDSSDrv->sync(psDSSDev); -+ if (res != 0) -+ { -+ printk(KERN_ERR DRIVER_PREFIX ": %s: Device %u: Sync failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, res); -+ return OMAPLFB_FALSE; -+ } -+ } -+ -+ return OMAPLFB_TRUE; -+#endif -+ return OMAPLFB_TRUE; -+#endif /* defined(PVR_OMAPLFB_DRM_FB) */ -+} -+ -+/* -+ * If the screen is manual or auto update mode, wait for the screen to -+ * update. -+ */ -+OMAPLFB_BOOL OMAPLFBCheckModeAndSync(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ OMAPLFB_UPDATE_MODE eMode = OMAPLFBGetUpdateMode(psDevInfo); -+ -+ switch(eMode) -+ { -+ case OMAPLFB_UPDATE_MODE_AUTO: -+ case OMAPLFB_UPDATE_MODE_MANUAL: -+ return OMAPLFBManualSync(psDevInfo); -+ default: -+ break; -+ } -+ -+ return OMAPLFB_TRUE; -+} -+ -+/* Linux Framebuffer event notification handler */ -+static int OMAPLFBFrameBufferEvents(struct notifier_block *psNotif, -+ unsigned long event, void *data) -+{ -+ OMAPLFB_DEVINFO *psDevInfo; -+ struct fb_event *psFBEvent = (struct fb_event *)data; -+ struct fb_info *psFBInfo = psFBEvent->info; -+ OMAPLFB_BOOL bBlanked; -+ -+ /* Only interested in blanking events */ -+ if (event != FB_EVENT_BLANK) -+ { -+ return 0; -+ } -+ -+ bBlanked = (*(IMG_INT *)psFBEvent->data != 0) ? OMAPLFB_TRUE: OMAPLFB_FALSE; -+ -+ psDevInfo = OMAPLFBGetDevInfoPtr(psFBInfo->node); -+ -+#if 0 -+ if (psDevInfo != NULL) -+ { -+ if (bBlanked) -+ { -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": %s: Device %u: Blank event received\n", __FUNCTION__, psDevInfo->uiFBDevID)); -+ } -+ else -+ { -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": %s: Device %u: Unblank event received\n", __FUNCTION__, psDevInfo->uiFBDevID)); -+ } -+ } -+ else -+ { -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": %s: Device %u: Blank/Unblank event for unknown framebuffer\n", __FUNCTION__, psFBInfo->node)); -+ } -+#endif -+ -+ if (psDevInfo != NULL) -+ { -+ OMAPLFBAtomicBoolSet(&psDevInfo->sBlanked, bBlanked); -+ OMAPLFBAtomicIntInc(&psDevInfo->sBlankEvents); -+ } -+ -+ return 0; -+} -+ -+/* Unblank the screen */ -+/* -+ * Blank or Unblank the screen. To be called where the unblank is being done -+ * in user context. -+ */ -+static OMAPLFB_ERROR OMAPLFBBlankOrUnblankDisplay(OMAPLFB_DEVINFO *psDevInfo, IMG_BOOL bBlank) -+{ -+#ifdef FBDEV_PRESENT -+ int res; -+ if (!lock_fb_info(psDevInfo->psLINFBInfo)) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ ": %s: Device %u: Couldn't lock FB info\n", __FUNCTION__, psDevInfo->uiFBDevID); -+ return (OMAPLFB_ERROR_GENERIC); -+ } -+ -+ /* -+ * FBINFO_MISC_USEREVENT is set to avoid a deadlock resulting from -+ * fb_blank being called recursively due from within the fb_blank event -+ * notification. -+ */ -+ -+ -+ OMAPLFB_CONSOLE_LOCK(); -+ psDevInfo->psLINFBInfo->flags |= FBINFO_MISC_USEREVENT; -+ res = fb_blank(psDevInfo->psLINFBInfo, bBlank ? 1 : 0); -+ psDevInfo->psLINFBInfo->flags &= ~FBINFO_MISC_USEREVENT; -+ -+ OMAPLFB_CONSOLE_UNLOCK(); -+ unlock_fb_info(psDevInfo->psLINFBInfo); -+ if (res != 0 && res != -EINVAL) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ ": %s: Device %u: fb_blank failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, res); -+ return (OMAPLFB_ERROR_GENERIC); -+ } -+#endif -+ return (OMAPLFB_OK); -+} -+ -+/* Unblank the screen */ -+OMAPLFB_ERROR OMAPLFBUnblankDisplay(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ return OMAPLFBBlankOrUnblankDisplay(psDevInfo, IMG_FALSE); -+} -+ -+ -+ -+#ifdef CONFIG_HAS_EARLYSUSPEND -+ -+static void OMAPLFBEarlyUnblankDisplay(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ OMAPLFB_CONSOLE_LOCK(); -+ fb_blank(psDevInfo->psLINFBInfo, 0); -+ OMAPLFB_CONSOLE_UNLOCK(); -+} -+ -+ -+/* Blank the screen */ -+static void OMAPLFBEarlyBlankDisplay(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ OMAPLFB_CONSOLE_LOCK(); -+ fb_blank(psDevInfo->psLINFBInfo, 1); -+ OMAPLFB_CONSOLE_UNLOCK(); -+} -+ -+static void OMAPLFBEarlySuspendHandler(struct early_suspend *h) -+{ -+ unsigned uiMaxFBDevIDPlusOne = OMAPLFBMaxFBDevIDPlusOne(); -+ unsigned i; -+ -+ for (i=0; i < uiMaxFBDevIDPlusOne; i++) -+ { -+ OMAPLFB_DEVINFO *psDevInfo = OMAPLFBGetDevInfoPtr(i); -+ -+ if (psDevInfo != NULL) -+ { -+ OMAPLFBAtomicBoolSet(&psDevInfo->sEarlySuspendFlag, OMAPLFB_TRUE); -+ OMAPLFBEarlyBlankDisplay(psDevInfo); -+ } -+ } -+} -+ -+static void OMAPLFBEarlyResumeHandler(struct early_suspend *h) -+{ -+ unsigned uiMaxFBDevIDPlusOne = OMAPLFBMaxFBDevIDPlusOne(); -+ unsigned i; -+ -+ for (i=0; i < uiMaxFBDevIDPlusOne; i++) -+ { -+ OMAPLFB_DEVINFO *psDevInfo = OMAPLFBGetDevInfoPtr(i); -+ -+ if (psDevInfo != NULL) -+ { -+ OMAPLFBEarlyUnblankDisplay(psDevInfo); -+ OMAPLFBAtomicBoolSet(&psDevInfo->sEarlySuspendFlag, OMAPLFB_FALSE); -+ } -+ } -+} -+ -+#endif /* CONFIG_HAS_EARLYSUSPEND */ -+ -+/* Set up Linux Framebuffer event notification */ -+OMAPLFB_ERROR OMAPLFBEnableLFBEventNotification(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ int res; -+ OMAPLFB_ERROR eError; -+ -+ /* Set up Linux Framebuffer event notification */ -+ memset(&psDevInfo->sLINNotifBlock, 0, sizeof(psDevInfo->sLINNotifBlock)); -+ -+ psDevInfo->sLINNotifBlock.notifier_call = OMAPLFBFrameBufferEvents; -+ -+ OMAPLFBAtomicBoolSet(&psDevInfo->sBlanked, OMAPLFB_FALSE); -+ OMAPLFBAtomicIntSet(&psDevInfo->sBlankEvents, 0); -+ -+ res = fb_register_client(&psDevInfo->sLINNotifBlock); -+ if (res != 0) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ ": %s: Device %u: fb_register_client failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, res); -+ -+ return (OMAPLFB_ERROR_GENERIC); -+ } -+ -+ eError = OMAPLFBUnblankDisplay(psDevInfo); -+ if (eError != OMAPLFB_OK) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ ": %s: Device %u: UnblankDisplay failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, eError); -+ return eError; -+ } -+ -+#ifdef CONFIG_HAS_EARLYSUSPEND -+ psDevInfo->sEarlySuspend.suspend = OMAPLFBEarlySuspendHandler; -+ psDevInfo->sEarlySuspend.resume = OMAPLFBEarlyResumeHandler; -+ psDevInfo->sEarlySuspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB + 1; -+ register_early_suspend(&psDevInfo->sEarlySuspend); -+#endif -+ -+ return (OMAPLFB_OK); -+} -+ -+/* Disable Linux Framebuffer event notification */ -+OMAPLFB_ERROR OMAPLFBDisableLFBEventNotification(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ int res; -+ -+#ifdef CONFIG_HAS_EARLYSUSPEND -+ unregister_early_suspend(&psDevInfo->sEarlySuspend); -+#endif -+ -+ /* Unregister for Framebuffer events */ -+ res = fb_unregister_client(&psDevInfo->sLINNotifBlock); -+ if (res != 0) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ ": %s: Device %u: fb_unregister_client failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, res); -+ return (OMAPLFB_ERROR_GENERIC); -+ } -+ -+ OMAPLFBAtomicBoolSet(&psDevInfo->sBlanked, OMAPLFB_FALSE); -+ -+ return (OMAPLFB_OK); -+} -+ -+#if defined(SUPPORT_DRI_DRM) && defined(PVR_DISPLAY_CONTROLLER_DRM_IOCTL) -+static OMAPLFB_DEVINFO *OMAPLFBPVRDevIDToDevInfo(unsigned uiPVRDevID) -+{ -+ unsigned uiMaxFBDevIDPlusOne = OMAPLFBMaxFBDevIDPlusOne(); -+ unsigned i; -+ -+ for (i=0; i < uiMaxFBDevIDPlusOne; i++) -+ { -+ OMAPLFB_DEVINFO *psDevInfo = OMAPLFBGetDevInfoPtr(i); -+ -+ if (psDevInfo->uiPVRDevID == uiPVRDevID) -+ { -+ return psDevInfo; -+ } -+ } -+ -+ printk(KERN_ERR DRIVER_PREFIX -+ ": %s: PVR Device %u: Couldn't find device\n", __FUNCTION__, uiPVRDevID); -+ -+ return NULL; -+} -+ -+int PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Ioctl)(struct drm_device unref__ *dev, void *arg, struct drm_file unref__ *pFile) -+{ -+ uint32_t *puiArgs; -+ uint32_t uiCmd; -+ unsigned uiPVRDevID; -+ int ret = 0; -+ OMAPLFB_DEVINFO *psDevInfo; -+ -+ if (arg == NULL) -+ { -+ return -EFAULT; -+ } -+ -+ puiArgs = (uint32_t *)arg; -+ uiCmd = puiArgs[PVR_DRM_DISP_ARG_CMD]; -+ uiPVRDevID = puiArgs[PVR_DRM_DISP_ARG_DEV]; -+ -+ psDevInfo = OMAPLFBPVRDevIDToDevInfo(uiPVRDevID); -+ if (psDevInfo == NULL) -+ { -+ return -EINVAL; -+ } -+ -+ -+ switch (uiCmd) -+ { -+ case PVR_DRM_DISP_CMD_LEAVE_VT: -+ case PVR_DRM_DISP_CMD_ENTER_VT: -+ { -+ OMAPLFB_BOOL bLeaveVT = (uiCmd == PVR_DRM_DISP_CMD_LEAVE_VT); -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: PVR Device %u: %s\n", -+ __FUNCTION__, uiPVRDevID, -+ bLeaveVT ? "Leave VT" : "Enter VT")); -+ -+ OMAPLFBCreateSwapChainLock(psDevInfo); -+ -+ OMAPLFBAtomicBoolSet(&psDevInfo->sLeaveVT, bLeaveVT); -+ if (psDevInfo->psSwapChain != NULL) -+ { -+ flush_workqueue(psDevInfo->psSwapChain->psWorkQueue); -+ -+ if (bLeaveVT) -+ { -+ OMAPLFBFlip(psDevInfo, &psDevInfo->sSystemBuffer); -+ (void) OMAPLFBCheckModeAndSync(psDevInfo); -+ } -+ } -+ -+ OMAPLFBCreateSwapChainUnLock(psDevInfo); -+ (void) OMAPLFBUnblankDisplay(psDevInfo); -+ break; -+ } -+ case PVR_DRM_DISP_CMD_ON: -+ case PVR_DRM_DISP_CMD_STANDBY: -+ case PVR_DRM_DISP_CMD_SUSPEND: -+ case PVR_DRM_DISP_CMD_OFF: -+ { -+ int iFBMode; -+#if defined(DEBUG) -+ { -+ const char *pszMode; -+ switch(uiCmd) -+ { -+ case PVR_DRM_DISP_CMD_ON: -+ pszMode = "On"; -+ break; -+ case PVR_DRM_DISP_CMD_STANDBY: -+ pszMode = "Standby"; -+ break; -+ case PVR_DRM_DISP_CMD_SUSPEND: -+ pszMode = "Suspend"; -+ break; -+ case PVR_DRM_DISP_CMD_OFF: -+ pszMode = "Off"; -+ break; -+ default: -+ pszMode = "(Unknown Mode)"; -+ break; -+ } -+ printk(KERN_WARNING DRIVER_PREFIX ": %s: PVR Device %u: Display %s\n", -+ __FUNCTION__, uiPVRDevID, pszMode); -+ } -+#endif -+ switch(uiCmd) -+ { -+ case PVR_DRM_DISP_CMD_ON: -+ iFBMode = FB_BLANK_UNBLANK; -+ break; -+ case PVR_DRM_DISP_CMD_STANDBY: -+ iFBMode = FB_BLANK_HSYNC_SUSPEND; -+ break; -+ case PVR_DRM_DISP_CMD_SUSPEND: -+ iFBMode = FB_BLANK_VSYNC_SUSPEND; -+ break; -+ case PVR_DRM_DISP_CMD_OFF: -+ iFBMode = FB_BLANK_POWERDOWN; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ OMAPLFBCreateSwapChainLock(psDevInfo); -+ -+ if (psDevInfo->psSwapChain != NULL) -+ { -+ flush_workqueue(psDevInfo->psSwapChain->psWorkQueue); -+ } -+ -+ if (!lock_fb_info(psDevInfo->psLINFBInfo)) -+ { -+ ret = -ENODEV; -+ } -+ else -+ { -+ OMAPLFB_CONSOLE_LOCK(); -+ psDevInfo->psLINFBInfo->flags |= FBINFO_MISC_USEREVENT; -+ ret = fb_blank(psDevInfo->psLINFBInfo, iFBMode); -+ psDevInfo->psLINFBInfo->flags &= ~FBINFO_MISC_USEREVENT; -+ OMAPLFB_CONSOLE_UNLOCK(); -+ unlock_fb_info(psDevInfo->psLINFBInfo); -+ } -+ -+ -+ OMAPLFBCreateSwapChainUnLock(psDevInfo); -+ -+ break; -+ } -+ default: -+ { -+ ret = -EINVAL; -+ break; -+ } -+ } -+ -+ return ret; -+} -+#endif -+ -+/* Insert the driver into the kernel */ -+#if defined(SUPPORT_DRI_DRM) -+int PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Init)(struct drm_device unref__ *dev) -+#else -+static int __init OMAPLFB_Init(void) -+#endif -+{ -+ -+ if(OMAPLFBInit() != OMAPLFB_OK) -+ { -+ printk(KERN_ERR DRIVER_PREFIX ": %s: OMAPLFBInit failed\n", __FUNCTION__); -+ return -ENODEV; -+ } -+ -+ return 0; -+ -+} -+ -+/* Remove the driver from the kernel */ -+#if defined(SUPPORT_DRI_DRM) -+void PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Cleanup)(struct drm_device unref__ *dev) -+#else -+static void __exit OMAPLFB_Cleanup(void) -+#endif -+{ -+ if(OMAPLFBDeInit() != OMAPLFB_OK) -+ { -+ printk(KERN_ERR DRIVER_PREFIX ": %s: OMAPLFBDeInit failed\n", __FUNCTION__); -+ } -+} -+ -+#if !defined(SUPPORT_DRI_DRM) -+/* -+ These macro calls define the initialisation and removal functions of the -+ driver. Although they are prefixed `module_', they apply when compiling -+ statically as well; in both cases they define the function the kernel will -+ run to start/stop the driver. -+*/ -+late_initcall(OMAPLFB_Init); -+module_exit(OMAPLFB_Cleanup); -+#endif -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti43xx_linux/3rdparty_dc_drm_shared.h b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti43xx_linux/3rdparty_dc_drm_shared.h -new file mode 100644 -index 0000000..b522c41 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti43xx_linux/3rdparty_dc_drm_shared.h -@@ -0,0 +1,64 @@ -+/*************************************************************************/ /*! -+@Title OMAP Linux display driver shared DRM structures -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description OMAP Linux display driver DRM structures shared between -+ kernel and user space. -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+#ifndef __3RDPARTY_DC_DRM_SHARED_H__ -+#define __3RDPARTY_DC_DRM_SHARED_H__ -+#if defined(SUPPORT_DRI_DRM) -+ -+#define PVR_DRM_DISP_CMD_ENTER_VT 1 -+#define PVR_DRM_DISP_CMD_LEAVE_VT 2 -+ -+#define PVR_DRM_DISP_CMD_ON 3 -+#define PVR_DRM_DISP_CMD_STANDBY 4 -+#define PVR_DRM_DISP_CMD_SUSPEND 5 -+#define PVR_DRM_DISP_CMD_OFF 6 -+ -+#define PVR_DRM_DISP_ARG_CMD 0 -+#define PVR_DRM_DISP_ARG_DEV 1 -+#define PVR_DRM_DISP_NUM_ARGS 2 -+ -+#endif /* defined(SUPPORT_DRI_DRM) */ -+#endif /* __3RDPARTY_DC_DRM_SHARED_H__ */ -+ -+/****************************************************************************** -+ End of file (3rdparty_dc_drm_shared.h) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti43xx_linux/Kbuild b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti43xx_linux/Kbuild -new file mode 100644 -index 0000000..1ae23593 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti43xx_linux/Kbuild -@@ -0,0 +1,32 @@ -+SYS_USING_INTERRUPTS = 1 -+SUPPORT_OMAP3430_OMAPFB3 =1 -+SUPPORT_TI_DSS_FW = 0 -+PVR_LINUX_USING_WORKQUEUES = 1 -+ -+SYS_CFLAGS.$(SYS_USING_INTERRUPTS) += -DSYS_USING_INTERRUPTS -+SYS_CFLAGS.$(SUPPORT_OMAP3430_OMAPFB3) += -DSUPPORT_OMAP3430_OMAPFB3 -+SYS_CFLAGS.$(SUPPORT_TI_DSS_FW) += -DSUPPORT_TI_DSS_FW -+SYS_CFLAGS.$(PVR_LINUX_USING_WORKQUEUES) += -DPVR_LINUX_USING_WORKQUEUES -+SYS_CFLAGS += -DDISPLAY_CONTROLLER=omaplfb -+ -+EXTRA_CFLAGS = -DLINUX \ -+ -DCONFIG_OMAP2_DSS \ -+ -I$(PVR_BUILD_DIR)/include4 \ -+ -I$(PVR_BUILD_DIR)/services4/include \ -+ -I$(PVR_BUILD_DIR)/services4/system/$(PVR_SYSTEM) \ -+ -I$(KERNELDIR)/drivers/video/omap2 \ -+ -I$(PVR_BUILD_DIR)/services4/system/include \ -+ $(SYS_CFLAGS.1) \ -+ -+ifneq ($(FBDEV),no) -+EXTRA_CFLAGS += -DFBDEV_PRESENT -+endif -+ -+ifeq ($(SUPPORT_XORG),1) -+EXTRA_CFLAGS += -DSUPPORT_DRI_DRM -+EXTRA_CFLAGS += -DPVR_DISPLAY_CONTROLLER_DRM_IOCTL -+endif -+ -+ -+obj-m := omaplfb.o -+omaplfb-y := omaplfb_displayclass.o omaplfb_linux.o -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti43xx_linux/Kbuild.mk b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti43xx_linux/Kbuild.mk -new file mode 100644 -index 0000000..0310b95 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti43xx_linux/Kbuild.mk -@@ -0,0 +1,48 @@ -+########################################################################### ### -+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+#@License Dual MIT/GPLv2 -+# -+# The contents of this file are subject to the MIT license as set out below. -+# -+# Permission is hereby granted, free of charge, to any person obtaining a copy -+# of this software and associated documentation files (the "Software"), to deal -+# in the Software without restriction, including without limitation the rights -+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+# copies of the Software, and to permit persons to whom the Software is -+# furnished to do so, subject to the following conditions: -+# -+# The above copyright notice and this permission notice shall be included in -+# all copies or substantial portions of the Software. -+# -+# Alternatively, the contents of this file may be used under the terms of -+# the GNU General Public License Version 2 ("GPL") in which case the provisions -+# of GPL are applicable instead of those above. -+# -+# If you wish to allow use of your version of this file only under the terms of -+# GPL, and not to allow others to use your version of this file under the terms -+# of the MIT license, indicate your decision by deleting the provisions above -+# and replace them with the notice and other provisions required by GPL as set -+# out in the file called "GPL-COPYING" included in this distribution. If you do -+# not delete the provisions above, a recipient may use your version of this file -+# under the terms of either the MIT license or GPL. -+# -+# This License is also included in this distribution in the file called -+# "MIT-COPYING". -+# -+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+### ########################################################################### -+ -+ccflags-y += \ -+ -I$(TOP)/services4/3rdparty/dc_omapfb3_linux \ -+ -Idrivers/video/omap2 \ -+ -Iarch/arm/plat-omap/include -+ -+omaplfb-y += \ -+ services4/3rdparty/dc_omapfb3_linux/omaplfb_displayclass.o \ -+ services4/3rdparty/dc_omapfb3_linux/omaplfb_linux.o -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti43xx_linux/Linux.mk b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti43xx_linux/Linux.mk -new file mode 100644 -index 0000000..4008b4d ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti43xx_linux/Linux.mk -@@ -0,0 +1,45 @@ -+########################################################################### ### -+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+#@License Dual MIT/GPLv2 -+# -+# The contents of this file are subject to the MIT license as set out below. -+# -+# Permission is hereby granted, free of charge, to any person obtaining a copy -+# of this software and associated documentation files (the "Software"), to deal -+# in the Software without restriction, including without limitation the rights -+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+# copies of the Software, and to permit persons to whom the Software is -+# furnished to do so, subject to the following conditions: -+# -+# The above copyright notice and this permission notice shall be included in -+# all copies or substantial portions of the Software. -+# -+# Alternatively, the contents of this file may be used under the terms of -+# the GNU General Public License Version 2 ("GPL") in which case the provisions -+# of GPL are applicable instead of those above. -+# -+# If you wish to allow use of your version of this file only under the terms of -+# GPL, and not to allow others to use your version of this file under the terms -+# of the MIT license, indicate your decision by deleting the provisions above -+# and replace them with the notice and other provisions required by GPL as set -+# out in the file called "GPL-COPYING" included in this distribution. If you do -+# not delete the provisions above, a recipient may use your version of this file -+# under the terms of either the MIT license or GPL. -+# -+# This License is also included in this distribution in the file called -+# "MIT-COPYING". -+# -+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+### ########################################################################### -+ -+modules := dc_omapfb3_linux -+ -+dc_omapfb3_linux_type := kernel_module -+dc_omapfb3_linux_target := omaplfb.ko -+dc_omapfb3_linux_makefile := $(THIS_DIR)/Kbuild.mk -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti43xx_linux/omaplfb.h b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti43xx_linux/omaplfb.h -new file mode 100644 -index 0000000..e7b4fa2 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti43xx_linux/omaplfb.h -@@ -0,0 +1,331 @@ -+/*************************************************************************/ /*! -+@Title OMAP Linux display driver structures and prototypes -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+#ifndef __OMAPLFB_H__ -+#define __OMAPLFB_H__ -+ -+#include <linux/version.h> -+ -+#include <asm/atomic.h> -+ -+#include <linux/kernel.h> -+#include <linux/console.h> -+#include <linux/fb.h> -+#include <linux/module.h> -+#include <linux/string.h> -+#include <linux/notifier.h> -+#include <linux/mutex.h> -+ -+#ifdef CONFIG_HAS_EARLYSUSPEND -+#include <linux/earlysuspend.h> -+#endif -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) -+#define OMAPLFB_CONSOLE_LOCK() console_lock() -+#define OMAPLFB_CONSOLE_UNLOCK() console_unlock() -+#else -+#define OMAPLFB_CONSOLE_LOCK() acquire_console_sem() -+#define OMAPLFB_CONSOLE_UNLOCK() release_console_sem() -+#endif -+ -+#if defined(CONFIG_ION_OMAP) -+#include <linux/ion.h> -+#include <linux/omap_ion.h> -+#endif /* defined(CONFIG_ION_OMAP) */ -+ -+#define unref__ __attribute__ ((unused)) -+ -+typedef void * OMAPLFB_HANDLE; -+ -+typedef bool OMAPLFB_BOOL, *OMAPLFB_PBOOL; -+#define OMAPLFB_FALSE false -+#define OMAPLFB_TRUE true -+ -+typedef atomic_t OMAPLFB_ATOMIC_BOOL; -+ -+typedef atomic_t OMAPLFB_ATOMIC_INT; -+ -+/* OMAPLFB buffer structure */ -+typedef struct OMAPLFB_BUFFER_TAG -+{ -+ struct OMAPLFB_BUFFER_TAG *psNext; -+ struct OMAPLFB_DEVINFO_TAG *psDevInfo; -+ -+ struct work_struct sWork; -+ -+ /* Position of this buffer in the virtual framebuffer */ -+ unsigned long ulYOffset; -+ -+ /* IMG structures used, to minimise API function code */ -+ /* replace with own structures where necessary */ -+ IMG_SYS_PHYADDR sSysAddr; -+ IMG_CPU_VIRTADDR sCPUVAddr; -+ PVRSRV_SYNC_DATA *psSyncData; -+ -+ OMAPLFB_HANDLE hCmdComplete; -+ unsigned long ulSwapInterval; -+} OMAPLFB_BUFFER; -+ -+/* OMAPLFB swapchain structure */ -+typedef struct OMAPLFB_SWAPCHAIN_TAG -+{ -+ /* Swap chain ID */ -+ unsigned int uiSwapChainID; -+ -+ /* number of buffers in swapchain */ -+ unsigned long ulBufferCount; -+ -+ /* list of buffers in the swapchain */ -+ OMAPLFB_BUFFER *psBuffer; -+ -+ /* Swap chain work queue */ -+ struct workqueue_struct *psWorkQueue; -+ -+ /* -+ * Set if we didn't manage to wait for VSync on last swap, -+ * or if we think we need to wait for VSync on the next flip. -+ * The flag helps to avoid jitter when the screen is -+ * unblanked, by forcing an extended wait for VSync before -+ * attempting the next flip. -+ */ -+ OMAPLFB_BOOL bNotVSynced; -+ -+ /* Previous number of blank events */ -+ int iBlankEvents; -+ -+ /* Framebuffer Device ID for messages (e.g. printk) */ -+ unsigned int uiFBDevID; -+} OMAPLFB_SWAPCHAIN; -+ -+typedef struct OMAPLFB_FBINFO_TAG -+{ -+ unsigned long ulFBSize; -+ unsigned long ulBufferSize; -+ unsigned long ulRoundedBufferSize; -+ unsigned long ulWidth; -+ unsigned long ulHeight; -+ unsigned long ulByteStride; -+ unsigned long ulPhysicalWidthmm; -+ unsigned long ulPhysicalHeightmm; -+ -+ /* IMG structures used, to minimise API function code */ -+ /* replace with own structures where necessary */ -+ IMG_SYS_PHYADDR sSysAddr;//system physical address -+ IMG_CPU_VIRTADDR sCPUVAddr; -+ -+ /* pixelformat of system/primary surface */ -+ PVRSRV_PIXEL_FORMAT ePixelFormat; -+ -+#if defined(CONFIG_DSSCOMP) -+ OMAPLFB_BOOL bIs2D; -+ IMG_SYS_PHYADDR *psPageList; -+ struct ion_handle *psIONHandle; -+ IMG_UINT32 uiBytesPerPixel; -+#endif -+} OMAPLFB_FBINFO; -+ -+/* kernel device information structure */ -+typedef struct OMAPLFB_DEVINFO_TAG -+{ -+ /* Framebuffer Device ID */ -+ unsigned int uiFBDevID; -+ -+ /* PVR Device ID */ -+ unsigned int uiPVRDevID; -+ -+ /* Swapchain create/destroy mutex */ -+ struct mutex sCreateSwapChainMutex; -+ -+ /* system surface info */ -+ OMAPLFB_BUFFER sSystemBuffer; -+ -+ /* jump table into PVR services */ -+ PVRSRV_DC_DISP2SRV_KMJTABLE sPVRJTable; -+ -+ /* jump table into DC */ -+ PVRSRV_DC_SRV2DISP_KMJTABLE sDCJTable; -+ -+ /* fb info structure */ -+ OMAPLFB_FBINFO sFBInfo; -+ -+ /* Only one swapchain supported by this device so hang it here */ -+ OMAPLFB_SWAPCHAIN *psSwapChain; -+ -+ /* Swap chain ID */ -+ unsigned int uiSwapChainID; -+ -+ /* True if PVR Services is flushing its command queues */ -+ OMAPLFB_ATOMIC_BOOL sFlushCommands; -+ -+ /* pointer to linux frame buffer information structure */ -+ struct fb_info *psLINFBInfo; -+ -+ /* Linux Framebuffer event notification block */ -+ struct notifier_block sLINNotifBlock; -+ -+ /* IMG structures used, to minimise API function code */ -+ /* replace with own structures where necessary */ -+ -+ /* Address of the surface being displayed */ -+ IMG_DEV_VIRTADDR sDisplayDevVAddr; -+ -+ DISPLAY_INFO sDisplayInfo; -+ -+ /* Display format */ -+ DISPLAY_FORMAT sDisplayFormat; -+ -+ /* Display dimensions */ -+ DISPLAY_DIMS sDisplayDim; -+ -+ /* True if screen is blanked */ -+ OMAPLFB_ATOMIC_BOOL sBlanked; -+ -+ /* Number of blank/unblank events */ -+ OMAPLFB_ATOMIC_INT sBlankEvents; -+ -+#ifdef CONFIG_HAS_EARLYSUSPEND -+ /* Set by early suspend */ -+ OMAPLFB_ATOMIC_BOOL sEarlySuspendFlag; -+ -+ struct early_suspend sEarlySuspend; -+#endif -+ -+#if defined(SUPPORT_DRI_DRM) -+ OMAPLFB_ATOMIC_BOOL sLeaveVT; -+#endif -+ -+#if defined(CONFIG_ION_OMAP) -+ struct ion_client *psIONClient; -+#endif -+ -+} OMAPLFB_DEVINFO; -+ -+#define OMAPLFB_PAGE_SIZE 4096 -+ -+/* DEBUG only printk */ -+#ifdef DEBUG -+#define DEBUG_PRINTK(x) printk x -+#else -+#define DEBUG_PRINTK(x) -+#endif -+ -+#define DISPLAY_DEVICE_NAME "PowerVR OMAP Linux Display Driver" -+#define DRVNAME "omaplfb" -+#define DEVNAME DRVNAME -+#define DRIVER_PREFIX DRVNAME -+ -+/*! -+ ***************************************************************************** -+ * Error values -+ *****************************************************************************/ -+typedef enum _OMAPLFB_ERROR_ -+{ -+ OMAPLFB_OK = 0, -+ OMAPLFB_ERROR_GENERIC = 1, -+ OMAPLFB_ERROR_OUT_OF_MEMORY = 2, -+ OMAPLFB_ERROR_TOO_FEW_BUFFERS = 3, -+ OMAPLFB_ERROR_INVALID_PARAMS = 4, -+ OMAPLFB_ERROR_INIT_FAILURE = 5, -+ OMAPLFB_ERROR_CANT_REGISTER_CALLBACK = 6, -+ OMAPLFB_ERROR_INVALID_DEVICE = 7, -+ OMAPLFB_ERROR_DEVICE_REGISTER_FAILED = 8, -+ OMAPLFB_ERROR_SET_UPDATE_MODE_FAILED = 9 -+} OMAPLFB_ERROR; -+ -+typedef enum _OMAPLFB_UPDATE_MODE_ -+{ -+ OMAPLFB_UPDATE_MODE_UNDEFINED = 0, -+ OMAPLFB_UPDATE_MODE_MANUAL = 1, -+ OMAPLFB_UPDATE_MODE_AUTO = 2, -+ OMAPLFB_UPDATE_MODE_DISABLED = 3 -+} OMAPLFB_UPDATE_MODE; -+ -+#ifndef UNREFERENCED_PARAMETER -+#define UNREFERENCED_PARAMETER(param) (param) = (param) -+#endif -+ -+OMAPLFB_ERROR OMAPLFBInit(void); -+OMAPLFB_ERROR OMAPLFBDeInit(void); -+ -+/* OS Specific APIs */ -+OMAPLFB_DEVINFO *OMAPLFBGetDevInfoPtr(unsigned uiFBDevID); -+unsigned OMAPLFBMaxFBDevIDPlusOne(void); -+void *OMAPLFBAllocKernelMem(unsigned long ulSize); -+void OMAPLFBFreeKernelMem(void *pvMem); -+OMAPLFB_ERROR OMAPLFBGetLibFuncAddr(char *szFunctionName, PFN_DC_GET_PVRJTABLE *ppfnFuncTable); -+OMAPLFB_ERROR OMAPLFBCreateSwapQueue (OMAPLFB_SWAPCHAIN *psSwapChain); -+void OMAPLFBDestroySwapQueue(OMAPLFB_SWAPCHAIN *psSwapChain); -+void OMAPLFBInitBufferForSwap(OMAPLFB_BUFFER *psBuffer); -+void OMAPLFBSwapHandler(OMAPLFB_BUFFER *psBuffer); -+void OMAPLFBQueueBufferForSwap(OMAPLFB_SWAPCHAIN *psSwapChain, OMAPLFB_BUFFER *psBuffer); -+void OMAPLFBFlip(OMAPLFB_DEVINFO *psDevInfo, OMAPLFB_BUFFER *psBuffer); -+OMAPLFB_UPDATE_MODE OMAPLFBGetUpdateMode(OMAPLFB_DEVINFO *psDevInfo); -+OMAPLFB_BOOL OMAPLFBSetUpdateMode(OMAPLFB_DEVINFO *psDevInfo, OMAPLFB_UPDATE_MODE eMode); -+OMAPLFB_BOOL OMAPLFBWaitForVSync(OMAPLFB_DEVINFO *psDevInfo); -+OMAPLFB_BOOL OMAPLFBManualSync(OMAPLFB_DEVINFO *psDevInfo); -+OMAPLFB_BOOL OMAPLFBCheckModeAndSync(OMAPLFB_DEVINFO *psDevInfo); -+OMAPLFB_ERROR OMAPLFBUnblankDisplay(OMAPLFB_DEVINFO *psDevInfo); -+OMAPLFB_ERROR OMAPLFBEnableLFBEventNotification(OMAPLFB_DEVINFO *psDevInfo); -+OMAPLFB_ERROR OMAPLFBDisableLFBEventNotification(OMAPLFB_DEVINFO *psDevInfo); -+void OMAPLFBCreateSwapChainLockInit(OMAPLFB_DEVINFO *psDevInfo); -+void OMAPLFBCreateSwapChainLockDeInit(OMAPLFB_DEVINFO *psDevInfo); -+void OMAPLFBCreateSwapChainLock(OMAPLFB_DEVINFO *psDevInfo); -+void OMAPLFBCreateSwapChainUnLock(OMAPLFB_DEVINFO *psDevInfo); -+void OMAPLFBAtomicBoolInit(OMAPLFB_ATOMIC_BOOL *psAtomic, OMAPLFB_BOOL bVal); -+void OMAPLFBAtomicBoolDeInit(OMAPLFB_ATOMIC_BOOL *psAtomic); -+void OMAPLFBAtomicBoolSet(OMAPLFB_ATOMIC_BOOL *psAtomic, OMAPLFB_BOOL bVal); -+OMAPLFB_BOOL OMAPLFBAtomicBoolRead(OMAPLFB_ATOMIC_BOOL *psAtomic); -+void OMAPLFBAtomicIntInit(OMAPLFB_ATOMIC_INT *psAtomic, int iVal); -+void OMAPLFBAtomicIntDeInit(OMAPLFB_ATOMIC_INT *psAtomic); -+void OMAPLFBAtomicIntSet(OMAPLFB_ATOMIC_INT *psAtomic, int iVal); -+int OMAPLFBAtomicIntRead(OMAPLFB_ATOMIC_INT *psAtomic); -+void OMAPLFBAtomicIntInc(OMAPLFB_ATOMIC_INT *psAtomic); -+ -+#if defined(DEBUG) -+void OMAPLFBPrintInfo(OMAPLFB_DEVINFO *psDevInfo); -+#else -+#define OMAPLFBPrintInfo(psDevInfo) -+#endif -+ -+#endif /* __OMAPLFB_H__ */ -+ -+/****************************************************************************** -+ End of file (omaplfb.h) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti43xx_linux/omaplfb_displayclass.c b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti43xx_linux/omaplfb_displayclass.c -new file mode 100644 -index 0000000..456ed04 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti43xx_linux/omaplfb_displayclass.c -@@ -0,0 +1,1878 @@ -+/*************************************************************************/ /*! -+@Title OMAP common display driver components -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+/************************************************************************** -+ The 3rd party driver is a specification of an API to integrate the IMG POWERVR -+ Services driver with 3rd Party display hardware. It is NOT a specification for -+ a display controller driver, rather a specification to extend the API for a -+ pre-existing driver for the display hardware. -+ -+ The 3rd party driver interface provides IMG POWERVR client drivers (e.g. PVR2D) -+ with an API abstraction of the system's underlying display hardware, allowing -+ the client drivers to indirectly control the display hardware and access its -+ associated memory. -+ -+ Functions of the API include -+ - query primary surface attributes (width, height, stride, pixel format, CPU -+ physical and virtual address) -+ - swap/flip chain creation and subsequent query of surface attributes -+ - asynchronous display surface flipping, taking account of asynchronous read -+ (flip) and write (render) operations to the display surface -+ -+ Note: having queried surface attributes the client drivers are able to map the -+ display memory to any IMG POWERVR Services device by calling -+ PVRSRVMapDeviceClassMemory with the display surface handle. -+ -+ This code is intended to be an example of how a pre-existing display driver may -+ be extended to support the 3rd Party Display interface to POWERVR Services -+ - IMG is not providing a display driver implementation. -+ **************************************************************************/ -+ -+/* -+ * OMAP Linux 3rd party display driver. -+ * This is based on the Generic PVR Linux Framebuffer 3rd party display -+ * driver, with OMAP specific extensions to support flipping. -+ */ -+ -+#include <linux/version.h> -+#include <linux/kernel.h> -+#include <linux/console.h> -+#include <linux/fb.h> -+#include <linux/module.h> -+#include <linux/string.h> -+#include <linux/notifier.h> -+ -+/* IMG services headers */ -+#include "img_defs.h" -+#include "servicesext.h" -+#include "kerneldisplay.h" -+#include "omaplfb.h" -+ -+#if defined(CONFIG_DSSCOMP) -+#if defined(CONFIG_ION_OMAP) -+extern struct ion_device *omap_ion_device; -+#else /* defined(CONFIG_ION_OMAP) */ -+#error CONFIG_DSSCOMP support requires CONFIG_ION_OMAP -+#endif /* defined(CONFIG_ION_OMAP) */ -+#if defined(CONFIG_DRM_OMAP_DMM_TILER) -+#include <../drivers/staging/omapdrm/omap_dmm_tiler.h> -+#include <../drivers/video/omap2/dsscomp/tiler-utils.h> -+#elif defined(CONFIG_TI_TILER) -+#include <mach/tiler.h> -+#else /* defined(CONFIG_DRM_OMAP_DMM_TILER) */ -+#error CONFIG_DSSCOMP support requires either \ -+ CONFIG_DRM_OMAP_DMM_TILER or CONFIG_TI_TILER -+#endif /* defined(CONFIG_DRM_OMAP_DMM_TILER) */ -+#include <video/dsscomp.h> -+#include <plat/dsscomp.h> -+#endif /* defined(CONFIG_DSSCOMP) */ -+ -+#define OMAPLFB_COMMAND_COUNT 1 -+ -+#define OMAPLFB_VSYNC_SETTLE_COUNT 5 -+ -+//#define OMAPLFB_MAX_NUM_DEVICES FB_MAX -+#define OMAPLFB_MAX_NUM_DEVICES 1 -+#if (OMAPLFB_MAX_NUM_DEVICES > FB_MAX) -+#error "OMAPLFB_MAX_NUM_DEVICES must not be greater than FB_MAX" -+#endif -+ -+static OMAPLFB_DEVINFO *gapsDevInfo[OMAPLFB_MAX_NUM_DEVICES]; -+ -+/* Top level 'hook ptr' */ -+static PFN_DC_GET_PVRJTABLE gpfnGetPVRJTable = NULL; -+ -+#if !defined(CONFIG_DSSCOMP) -+/* Round x up to a multiple of y */ -+static inline unsigned long RoundUpToMultiple(unsigned long x, unsigned long y) -+{ -+ unsigned long div = x / y; -+ unsigned long rem = x % y; -+ -+ return (div + ((rem == 0) ? 0 : 1)) * y; -+} -+ -+/* Greatest common divisor of x and y */ -+static unsigned long GCD(unsigned long x, unsigned long y) -+{ -+ while (y != 0) -+ { -+ unsigned long r = x % y; -+ x = y; -+ y = r; -+ } -+ -+ return x; -+} -+ -+/* Least common multiple of x and y */ -+static unsigned long LCM(unsigned long x, unsigned long y) -+{ -+ unsigned long gcd = GCD(x, y); -+ -+ return (gcd == 0) ? 0 : ((x / gcd) * y); -+} -+#endif -+ -+unsigned OMAPLFBMaxFBDevIDPlusOne(void) -+{ -+ return OMAPLFB_MAX_NUM_DEVICES; -+} -+ -+/* Returns DevInfo pointer for a given device */ -+OMAPLFB_DEVINFO *OMAPLFBGetDevInfoPtr(unsigned uiFBDevID) -+{ -+ WARN_ON(uiFBDevID >= OMAPLFBMaxFBDevIDPlusOne()); -+ -+ if (uiFBDevID >= OMAPLFB_MAX_NUM_DEVICES) -+ { -+ return NULL; -+ } -+ -+ return gapsDevInfo[uiFBDevID]; -+} -+ -+/* Sets the DevInfo pointer for a given device */ -+static inline void OMAPLFBSetDevInfoPtr(unsigned uiFBDevID, OMAPLFB_DEVINFO *psDevInfo) -+{ -+ WARN_ON(uiFBDevID >= OMAPLFB_MAX_NUM_DEVICES); -+ -+ if (uiFBDevID < OMAPLFB_MAX_NUM_DEVICES) -+ { -+ gapsDevInfo[uiFBDevID] = psDevInfo; -+ } -+} -+ -+static inline OMAPLFB_BOOL SwapChainHasChanged(OMAPLFB_DEVINFO *psDevInfo, OMAPLFB_SWAPCHAIN *psSwapChain) -+{ -+ return (psDevInfo->psSwapChain != psSwapChain) || -+ (psDevInfo->uiSwapChainID != psSwapChain->uiSwapChainID); -+} -+ -+/* Don't wait for vertical sync */ -+static inline OMAPLFB_BOOL DontWaitForVSync(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ OMAPLFB_BOOL bDontWait; -+ -+ bDontWait = OMAPLFBAtomicBoolRead(&psDevInfo->sBlanked) || -+ OMAPLFBAtomicBoolRead(&psDevInfo->sFlushCommands); -+ -+#if defined(CONFIG_HAS_EARLYSUSPEND) -+ bDontWait = bDontWait || OMAPLFBAtomicBoolRead(&psDevInfo->sEarlySuspendFlag); -+#endif -+#if defined(SUPPORT_DRI_DRM) -+ bDontWait = bDontWait || OMAPLFBAtomicBoolRead(&psDevInfo->sLeaveVT); -+#endif -+ return bDontWait; -+} -+ -+/* -+ * SetDCState -+ * Called from services. -+ */ -+static IMG_VOID SetDCState(IMG_HANDLE hDevice, IMG_UINT32 ui32State) -+{ -+ OMAPLFB_DEVINFO *psDevInfo = (OMAPLFB_DEVINFO *)hDevice; -+ -+ switch (ui32State) -+ { -+ case DC_STATE_FLUSH_COMMANDS: -+ OMAPLFBAtomicBoolSet(&psDevInfo->sFlushCommands, OMAPLFB_TRUE); -+ break; -+ case DC_STATE_NO_FLUSH_COMMANDS: -+ OMAPLFBAtomicBoolSet(&psDevInfo->sFlushCommands, OMAPLFB_FALSE); -+ break; -+ case DC_STATE_FORCE_SWAP_TO_SYSTEM: -+ OMAPLFBFlip(psDevInfo, &psDevInfo->sSystemBuffer); -+ break; -+ default: -+ break; -+ } -+} -+ -+/* -+ * OpenDCDevice -+ * Called from services. -+ */ -+static PVRSRV_ERROR OpenDCDevice(IMG_UINT32 uiPVRDevID, -+ IMG_HANDLE *phDevice, -+ PVRSRV_SYNC_DATA* psSystemBufferSyncData) -+{ -+ OMAPLFB_DEVINFO *psDevInfo; -+ OMAPLFB_ERROR eError; -+ unsigned uiMaxFBDevIDPlusOne; -+ -+ unsigned i; -+ if (!try_module_get(THIS_MODULE)) -+ { -+ return PVRSRV_ERROR_UNABLE_TO_OPEN_DC_DEVICE; -+ } -+ -+ uiMaxFBDevIDPlusOne = OMAPLFBMaxFBDevIDPlusOne(); -+ -+ -+ -+ for (i = 0; i < uiMaxFBDevIDPlusOne; i++) -+ { -+ psDevInfo = OMAPLFBGetDevInfoPtr(i); -+ if (psDevInfo != NULL && psDevInfo->uiPVRDevID == uiPVRDevID) -+ { -+ break; -+ } -+ } -+ if (i == uiMaxFBDevIDPlusOne) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX -+ ": %s: PVR Device %u not found\n", __FUNCTION__, uiPVRDevID)); -+ eError = PVRSRV_ERROR_INVALID_DEVICE; -+ goto ErrorModulePut; -+ } -+ -+ /* store the system surface sync data */ -+ psDevInfo->sSystemBuffer.psSyncData = psSystemBufferSyncData; -+ -+ eError = OMAPLFBUnblankDisplay(psDevInfo); -+ if (eError != OMAPLFB_OK) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX -+ ": %s: Device %u: OMAPLFBUnblankDisplay failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, eError)); -+ eError = PVRSRV_ERROR_UNBLANK_DISPLAY_FAILED; -+ goto ErrorModulePut; -+ } -+ -+ /* return handle to the devinfo */ -+ *phDevice = (IMG_HANDLE)psDevInfo; -+ -+ return PVRSRV_OK; -+ -+ErrorModulePut: -+ module_put(THIS_MODULE); -+ return eError; -+} -+ -+/* -+ * CloseDCDevice -+ * Called from services. -+ */ -+static PVRSRV_ERROR CloseDCDevice(IMG_HANDLE hDevice) -+{ -+#if defined(SUPPORT_DRI_DRM) -+ OMAPLFB_DEVINFO *psDevInfo = (OMAPLFB_DEVINFO *)hDevice; -+ -+ OMAPLFBAtomicBoolSet(&psDevInfo->sLeaveVT, OMAPLFB_FALSE); -+ (void) OMAPLFBUnblankDisplay(psDevInfo); -+#else -+ UNREFERENCED_PARAMETER(hDevice); -+#endif -+ module_put(THIS_MODULE); -+ return PVRSRV_OK; -+} -+ -+/* -+ * EnumDCFormats -+ * Called from services. -+ */ -+static PVRSRV_ERROR EnumDCFormats(IMG_HANDLE hDevice, -+ IMG_UINT32 *pui32NumFormats, -+ DISPLAY_FORMAT *psFormat) -+{ -+ OMAPLFB_DEVINFO *psDevInfo; -+ -+ if(!hDevice || !pui32NumFormats) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psDevInfo = (OMAPLFB_DEVINFO*)hDevice; -+ -+ *pui32NumFormats = 1; -+ -+ if(psFormat) -+ { -+ psFormat[0] = psDevInfo->sDisplayFormat; -+ } -+ -+ return PVRSRV_OK; -+} -+ -+/* -+ * EnumDCDims -+ * Called from services. -+ */ -+static PVRSRV_ERROR EnumDCDims(IMG_HANDLE hDevice, -+ DISPLAY_FORMAT *psFormat, -+ IMG_UINT32 *pui32NumDims, -+ DISPLAY_DIMS *psDim) -+{ -+ OMAPLFB_DEVINFO *psDevInfo; -+ -+ if(!hDevice || !psFormat || !pui32NumDims) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psDevInfo = (OMAPLFB_DEVINFO*)hDevice; -+ -+ *pui32NumDims = 1; -+ -+ /* No need to look at psFormat; there is only one */ -+ if(psDim) -+ { -+ psDim[0] = psDevInfo->sDisplayDim; -+ } -+ -+ return PVRSRV_OK; -+} -+ -+ -+/* -+ * GetDCSystemBuffer -+ * Called from services. -+ */ -+static PVRSRV_ERROR GetDCSystemBuffer(IMG_HANDLE hDevice, IMG_HANDLE *phBuffer) -+{ -+ OMAPLFB_DEVINFO *psDevInfo; -+ -+ if(!hDevice || !phBuffer) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psDevInfo = (OMAPLFB_DEVINFO*)hDevice; -+ -+ *phBuffer = (IMG_HANDLE)&psDevInfo->sSystemBuffer; -+ -+ return PVRSRV_OK; -+} -+ -+ -+/* -+ * GetDCInfo -+ * Called from services. -+ */ -+static PVRSRV_ERROR GetDCInfo(IMG_HANDLE hDevice, DISPLAY_INFO *psDCInfo) -+{ -+ OMAPLFB_DEVINFO *psDevInfo; -+ -+ if(!hDevice || !psDCInfo) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psDevInfo = (OMAPLFB_DEVINFO*)hDevice; -+ -+ *psDCInfo = psDevInfo->sDisplayInfo; -+ -+ return PVRSRV_OK; -+} -+ -+/* -+ * GetDCBufferAddr -+ * Called from services. -+ */ -+static PVRSRV_ERROR GetDCBufferAddr(IMG_HANDLE hDevice, -+ IMG_HANDLE hBuffer, -+ IMG_SYS_PHYADDR **ppsSysAddr, -+ IMG_UINT32 *pui32ByteSize, -+ IMG_VOID **ppvCpuVAddr, -+ IMG_HANDLE *phOSMapInfo, -+ IMG_BOOL *pbIsContiguous, -+ IMG_UINT32 *pui32TilingStride) -+{ -+ OMAPLFB_DEVINFO *psDevInfo; -+ OMAPLFB_BUFFER *psSystemBuffer; -+ -+ UNREFERENCED_PARAMETER(pui32TilingStride); -+ -+ if(!hDevice) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ if(!hBuffer) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ if (!ppsSysAddr) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ if (!pui32ByteSize) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psDevInfo = (OMAPLFB_DEVINFO*)hDevice; -+ -+ psSystemBuffer = (OMAPLFB_BUFFER *)hBuffer; -+ -+ *ppsSysAddr = &psSystemBuffer->sSysAddr; -+ -+ *pui32ByteSize = (IMG_UINT32)psDevInfo->sFBInfo.ulBufferSize; -+ -+ if (ppvCpuVAddr) -+ { -+#if defined(CONFIG_DSSCOMP) -+ *ppvCpuVAddr = psDevInfo->sFBInfo.bIs2D ? NULL : psSystemBuffer->sCPUVAddr; -+#else -+ *ppvCpuVAddr = psSystemBuffer->sCPUVAddr; -+#endif -+ } -+ -+ if (phOSMapInfo) -+ { -+ *phOSMapInfo = (IMG_HANDLE)0; -+ } -+ -+ if (pbIsContiguous) -+ { -+#if defined(CONFIG_DSSCOMP) -+ *pbIsContiguous = !psDevInfo->sFBInfo.bIs2D; -+#else -+ *pbIsContiguous = IMG_TRUE; -+#endif -+ } -+ -+#if defined(CONFIG_DSSCOMP) -+ if (psDevInfo->sFBInfo.bIs2D) -+ { -+ int i = (psSystemBuffer->sSysAddr.uiAddr - psDevInfo->sFBInfo.psPageList->uiAddr) >> PAGE_SHIFT; -+ *ppsSysAddr = psDevInfo->sFBInfo.psPageList + psDevInfo->sFBInfo.ulHeight * i; -+ } -+#endif -+ -+ return PVRSRV_OK; -+} -+ -+/* -+ * CreateDCSwapChain -+ * Called from services. -+ */ -+static PVRSRV_ERROR CreateDCSwapChain(IMG_HANDLE hDevice, -+ IMG_UINT32 ui32Flags, -+ DISPLAY_SURF_ATTRIBUTES *psDstSurfAttrib, -+ DISPLAY_SURF_ATTRIBUTES *psSrcSurfAttrib, -+ IMG_UINT32 ui32BufferCount, -+ PVRSRV_SYNC_DATA **ppsSyncData, -+ IMG_UINT32 ui32OEMFlags, -+ IMG_HANDLE *phSwapChain, -+ IMG_UINT32 *pui32SwapChainID) -+{ -+ OMAPLFB_SWAPCHAIN *psSwapChain; -+ OMAPLFB_DEVINFO *psDevInfo; -+ PVRSRV_ERROR eError; -+ IMG_UINT32 i; -+ -+ UNREFERENCED_PARAMETER(ui32OEMFlags); -+ UNREFERENCED_PARAMETER(ui32Flags); -+ -+ /* Check parameters */ -+ if(!hDevice -+ || !psDstSurfAttrib -+ || !psSrcSurfAttrib -+ || !ppsSyncData -+ || !phSwapChain) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psDevInfo = (OMAPLFB_DEVINFO*)hDevice; -+ -+ /* Do we support swap chains? */ -+ if (psDevInfo->sDisplayInfo.ui32MaxSwapChains == 0) -+ { -+ return PVRSRV_ERROR_NOT_SUPPORTED; -+ } -+ -+ OMAPLFBCreateSwapChainLock(psDevInfo); -+ -+ /* The driver only supports a single swapchain */ -+ if(psDevInfo->psSwapChain != NULL) -+ { -+ eError = PVRSRV_ERROR_FLIP_CHAIN_EXISTS; -+ goto ExitUnLock; -+ } -+ -+ /* create a swapchain structure */ -+ psSwapChain = (OMAPLFB_SWAPCHAIN*)OMAPLFBAllocKernelMem(sizeof(OMAPLFB_SWAPCHAIN)); -+ if(!psSwapChain) -+ { -+ eError = PVRSRV_ERROR_OUT_OF_MEMORY; -+ goto ExitUnLock; -+ } -+ -+ /* If services asks for a 0-length swap chain, it's probably Android. -+ * -+ * This will use only non-display memory posting via PVRSRVSwapToDCBuffers2(), -+ * and we can skip some useless sanity checking. -+ */ -+ if(ui32BufferCount > 0) -+ { -+ IMG_UINT32 ui32BuffersToSkip; -+ -+ /* Check the buffer count */ -+ if(ui32BufferCount > psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers) -+ { -+ eError = PVRSRV_ERROR_TOOMANYBUFFERS; -+ goto ErrorFreeSwapChain; -+ } -+ -+ if ((psDevInfo->sFBInfo.ulRoundedBufferSize * (unsigned long)ui32BufferCount) > psDevInfo->sFBInfo.ulFBSize) -+ { -+ eError = PVRSRV_ERROR_TOOMANYBUFFERS; -+ goto ErrorFreeSwapChain; -+ } -+ -+ /* -+ * We will allocate the swap chain buffers at the back of the frame -+ * buffer area. This preserves the front portion, which may be being -+ * used by other Linux Framebuffer based applications. -+ */ -+ ui32BuffersToSkip = psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers - ui32BufferCount; -+ -+ /* -+ * Verify the DST/SRC attributes, -+ * SRC/DST must match the current display mode config -+ */ -+ if(psDstSurfAttrib->pixelformat != psDevInfo->sDisplayFormat.pixelformat -+ || psDstSurfAttrib->sDims.ui32ByteStride != psDevInfo->sDisplayDim.ui32ByteStride -+ || psDstSurfAttrib->sDims.ui32Width != psDevInfo->sDisplayDim.ui32Width -+ || psDstSurfAttrib->sDims.ui32Height != psDevInfo->sDisplayDim.ui32Height) -+ { -+ /* DST doesn't match the current mode */ -+ eError = PVRSRV_ERROR_INVALID_PARAMS; -+ goto ErrorFreeSwapChain; -+ } -+ -+ if(psDstSurfAttrib->pixelformat != psSrcSurfAttrib->pixelformat -+ || psDstSurfAttrib->sDims.ui32ByteStride != psSrcSurfAttrib->sDims.ui32ByteStride -+ || psDstSurfAttrib->sDims.ui32Width != psSrcSurfAttrib->sDims.ui32Width -+ || psDstSurfAttrib->sDims.ui32Height != psSrcSurfAttrib->sDims.ui32Height) -+ { -+ /* DST doesn't match the SRC */ -+ eError = PVRSRV_ERROR_INVALID_PARAMS; -+ goto ErrorFreeSwapChain; -+ } -+ -+ psSwapChain->psBuffer = (OMAPLFB_BUFFER*)OMAPLFBAllocKernelMem(sizeof(OMAPLFB_BUFFER) * ui32BufferCount); -+ if(!psSwapChain->psBuffer) -+ { -+ eError = PVRSRV_ERROR_OUT_OF_MEMORY; -+ goto ErrorFreeSwapChain; -+ } -+ -+ /* Link the buffers */ -+ for(i = 0; i < ui32BufferCount - 1; i++) -+ { -+ psSwapChain->psBuffer[i].psNext = &psSwapChain->psBuffer[i + 1]; -+ } -+ -+ /* and link last to first */ -+ psSwapChain->psBuffer[i].psNext = &psSwapChain->psBuffer[0]; -+ -+ /* Configure the swapchain buffers */ -+ for(i = 0; i < ui32BufferCount; i++) -+ { -+ IMG_UINT32 ui32SwapBuffer = i + ui32BuffersToSkip; -+ IMG_UINT32 ui32BufferOffset = ui32SwapBuffer * (IMG_UINT32)psDevInfo->sFBInfo.ulRoundedBufferSize; -+ -+#if defined(CONFIG_DSSCOMP) -+ if (psDevInfo->sFBInfo.bIs2D) -+ { -+ ui32BufferOffset = 0; -+ } -+#endif /* defined(CONFIG_DSSCOMP) */ -+ -+ psSwapChain->psBuffer[i].psSyncData = ppsSyncData[i]; -+ -+ psSwapChain->psBuffer[i].sSysAddr.uiAddr = psDevInfo->sFBInfo.sSysAddr.uiAddr + ui32BufferOffset; -+ psSwapChain->psBuffer[i].sCPUVAddr = psDevInfo->sFBInfo.sCPUVAddr + ui32BufferOffset; -+ psSwapChain->psBuffer[i].ulYOffset = ui32BufferOffset / psDevInfo->sFBInfo.ulByteStride; -+ psSwapChain->psBuffer[i].psDevInfo = psDevInfo; -+ -+#if defined(CONFIG_DSSCOMP) -+ if (psDevInfo->sFBInfo.bIs2D) -+ { -+ psSwapChain->psBuffer[i].sSysAddr.uiAddr += ui32SwapBuffer * -+ ALIGN((IMG_UINT32)psDevInfo->sFBInfo.ulWidth * psDevInfo->sFBInfo.uiBytesPerPixel, PAGE_SIZE); -+ } -+#endif /* defined(CONFIG_DSSCOMP) */ -+ -+ OMAPLFBInitBufferForSwap(&psSwapChain->psBuffer[i]); -+ } -+ } -+ else -+ { -+ psSwapChain->psBuffer = NULL; -+ } -+ -+#if defined(PVR_OMAPFB3_UPDATE_MODE) -+ if (!OMAPLFBSetUpdateMode(psDevInfo, PVR_OMAPFB3_UPDATE_MODE)) -+ { -+ printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Couldn't set frame buffer update mode %d\n", __FUNCTION__, psDevInfo->uiFBDevID, PVR_OMAPFB3_UPDATE_MODE); -+ } -+#endif /* defined(PVR_OMAPFB3_UPDATE_MODE) */ -+ -+ psSwapChain->ulBufferCount = (unsigned long)ui32BufferCount; -+ psSwapChain->bNotVSynced = OMAPLFB_TRUE; -+ psSwapChain->uiFBDevID = psDevInfo->uiFBDevID; -+ -+ if (OMAPLFBCreateSwapQueue(psSwapChain) != OMAPLFB_OK) -+ { -+ printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Failed to create workqueue\n", __FUNCTION__, psDevInfo->uiFBDevID); -+ eError = PVRSRV_ERROR_UNABLE_TO_INSTALL_ISR; -+ goto ErrorFreeBuffers; -+ } -+ -+ if (OMAPLFBEnableLFBEventNotification(psDevInfo)!= OMAPLFB_OK) -+ { -+ eError = PVRSRV_ERROR_UNABLE_TO_ENABLE_EVENT; -+ printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Couldn't enable framebuffer event notification\n", __FUNCTION__, psDevInfo->uiFBDevID); -+ goto ErrorDestroySwapQueue; -+ } -+ -+ psDevInfo->uiSwapChainID++; -+ if (psDevInfo->uiSwapChainID == 0) -+ { -+ psDevInfo->uiSwapChainID++; -+ } -+ -+ psSwapChain->uiSwapChainID = psDevInfo->uiSwapChainID; -+ -+ psDevInfo->psSwapChain = psSwapChain; -+ -+ *pui32SwapChainID = psDevInfo->uiSwapChainID; -+ -+ *phSwapChain = (IMG_HANDLE)psSwapChain; -+ -+ eError = PVRSRV_OK; -+ goto ExitUnLock; -+ -+ErrorDestroySwapQueue: -+ OMAPLFBDestroySwapQueue(psSwapChain); -+ErrorFreeBuffers: -+ if(psSwapChain->psBuffer) -+ { -+ OMAPLFBFreeKernelMem(psSwapChain->psBuffer); -+ } -+ErrorFreeSwapChain: -+ OMAPLFBFreeKernelMem(psSwapChain); -+ExitUnLock: -+ OMAPLFBCreateSwapChainUnLock(psDevInfo); -+ return eError; -+} -+ -+/* -+ * DestroyDCSwapChain -+ * Called from services. -+ */ -+static PVRSRV_ERROR DestroyDCSwapChain(IMG_HANDLE hDevice, -+ IMG_HANDLE hSwapChain) -+{ -+ OMAPLFB_DEVINFO *psDevInfo; -+ OMAPLFB_SWAPCHAIN *psSwapChain; -+ OMAPLFB_ERROR eError; -+ -+ /* Check parameters */ -+ if(!hDevice || !hSwapChain) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psDevInfo = (OMAPLFB_DEVINFO*)hDevice; -+ psSwapChain = (OMAPLFB_SWAPCHAIN*)hSwapChain; -+ -+ OMAPLFBCreateSwapChainLock(psDevInfo); -+ -+ if (SwapChainHasChanged(psDevInfo, psSwapChain)) -+ { -+ printk(KERN_WARNING DRIVER_PREFIX -+ ": %s: Device %u: Swap chain mismatch\n", __FUNCTION__, psDevInfo->uiFBDevID); -+ -+ eError = PVRSRV_ERROR_INVALID_PARAMS; -+ goto ExitUnLock; -+ } -+ -+ /* The swap queue is flushed before being destroyed */ -+ OMAPLFBDestroySwapQueue(psSwapChain); -+ -+ eError = OMAPLFBDisableLFBEventNotification(psDevInfo); -+ if (eError != OMAPLFB_OK) -+ { -+ printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Couldn't disable framebuffer event notification\n", __FUNCTION__, psDevInfo->uiFBDevID); -+ } -+ -+ /* Free resources */ -+ if (psSwapChain->psBuffer) -+ { -+ OMAPLFBFreeKernelMem(psSwapChain->psBuffer); -+ } -+ OMAPLFBFreeKernelMem(psSwapChain); -+ -+ psDevInfo->psSwapChain = NULL; -+ -+ OMAPLFBFlip(psDevInfo, &psDevInfo->sSystemBuffer); -+ (void) OMAPLFBCheckModeAndSync(psDevInfo); -+ -+ eError = PVRSRV_OK; -+ -+ExitUnLock: -+ OMAPLFBCreateSwapChainUnLock(psDevInfo); -+ -+ return eError; -+} -+ -+/* -+ * SetDCDstRect -+ * Called from services. -+ */ -+static PVRSRV_ERROR SetDCDstRect(IMG_HANDLE hDevice, -+ IMG_HANDLE hSwapChain, -+ IMG_RECT *psRect) -+{ -+ UNREFERENCED_PARAMETER(hDevice); -+ UNREFERENCED_PARAMETER(hSwapChain); -+ UNREFERENCED_PARAMETER(psRect); -+ -+ /* Only full display swapchains on this device */ -+ -+ return PVRSRV_ERROR_NOT_SUPPORTED; -+} -+ -+/* -+ * SetDCSrcRect -+ * Called from services. -+ */ -+static PVRSRV_ERROR SetDCSrcRect(IMG_HANDLE hDevice, -+ IMG_HANDLE hSwapChain, -+ IMG_RECT *psRect) -+{ -+ UNREFERENCED_PARAMETER(hDevice); -+ UNREFERENCED_PARAMETER(hSwapChain); -+ UNREFERENCED_PARAMETER(psRect); -+ -+ /* Only full display swapchains on this device */ -+ -+ return PVRSRV_ERROR_NOT_SUPPORTED; -+} -+ -+/* -+ * SetDCDstColourKey -+ * Called from services. -+ */ -+static PVRSRV_ERROR SetDCDstColourKey(IMG_HANDLE hDevice, -+ IMG_HANDLE hSwapChain, -+ IMG_UINT32 ui32CKColour) -+{ -+ UNREFERENCED_PARAMETER(hDevice); -+ UNREFERENCED_PARAMETER(hSwapChain); -+ UNREFERENCED_PARAMETER(ui32CKColour); -+ -+ /* Don't support DST CK on this device */ -+ -+ return PVRSRV_ERROR_NOT_SUPPORTED; -+} -+ -+/* -+ * SetDCSrcColourKey -+ * Called from services. -+ */ -+static PVRSRV_ERROR SetDCSrcColourKey(IMG_HANDLE hDevice, -+ IMG_HANDLE hSwapChain, -+ IMG_UINT32 ui32CKColour) -+{ -+ UNREFERENCED_PARAMETER(hDevice); -+ UNREFERENCED_PARAMETER(hSwapChain); -+ UNREFERENCED_PARAMETER(ui32CKColour); -+ -+ /* Don't support SRC CK on this device */ -+ -+ return PVRSRV_ERROR_NOT_SUPPORTED; -+} -+ -+/* -+ * GetDCBuffers -+ * Called from services. -+ */ -+static PVRSRV_ERROR GetDCBuffers(IMG_HANDLE hDevice, -+ IMG_HANDLE hSwapChain, -+ IMG_UINT32 *pui32BufferCount, -+ IMG_HANDLE *phBuffer) -+{ -+ OMAPLFB_DEVINFO *psDevInfo; -+ OMAPLFB_SWAPCHAIN *psSwapChain; -+ PVRSRV_ERROR eError; -+ unsigned i; -+ -+ /* Check parameters */ -+ if(!hDevice -+ || !hSwapChain -+ || !pui32BufferCount -+ || !phBuffer) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psDevInfo = (OMAPLFB_DEVINFO*)hDevice; -+ psSwapChain = (OMAPLFB_SWAPCHAIN*)hSwapChain; -+ -+ OMAPLFBCreateSwapChainLock(psDevInfo); -+ -+ if (SwapChainHasChanged(psDevInfo, psSwapChain)) -+ { -+ printk(KERN_WARNING DRIVER_PREFIX -+ ": %s: Device %u: Swap chain mismatch\n", __FUNCTION__, psDevInfo->uiFBDevID); -+ -+ eError = PVRSRV_ERROR_INVALID_PARAMS; -+ goto Exit; -+ } -+ -+ /* Return the buffer count */ -+ *pui32BufferCount = (IMG_UINT32)psSwapChain->ulBufferCount; -+ -+ /* Return the buffers */ -+ for(i=0; i<psSwapChain->ulBufferCount; i++) -+ { -+ phBuffer[i] = (IMG_HANDLE)&psSwapChain->psBuffer[i]; -+ } -+ -+ eError = PVRSRV_OK; -+ -+Exit: -+ OMAPLFBCreateSwapChainUnLock(psDevInfo); -+ -+ return eError; -+} -+ -+/* -+ * SwapToDCBuffer -+ * Called from services. -+ */ -+static PVRSRV_ERROR SwapToDCBuffer(IMG_HANDLE hDevice, -+ IMG_HANDLE hBuffer, -+ IMG_UINT32 ui32SwapInterval, -+ IMG_HANDLE hPrivateTag, -+ IMG_UINT32 ui32ClipRectCount, -+ IMG_RECT *psClipRect) -+{ -+ UNREFERENCED_PARAMETER(hDevice); -+ UNREFERENCED_PARAMETER(hBuffer); -+ UNREFERENCED_PARAMETER(ui32SwapInterval); -+ UNREFERENCED_PARAMETER(hPrivateTag); -+ UNREFERENCED_PARAMETER(ui32ClipRectCount); -+ UNREFERENCED_PARAMETER(psClipRect); -+ -+ /* * Nothing to do since Services common code does the work */ -+ -+ return PVRSRV_OK; -+} -+ -+/* -+ * Called after the screen has unblanked, or after any other occasion -+ * when we didn't wait for vsync, but now need to. Not doing this after -+ * unblank leads to screen jitter on some screens. -+ * Returns true if the screen has been deemed to have settled. -+ */ -+static OMAPLFB_BOOL WaitForVSyncSettle(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ unsigned i; -+ for(i = 0; i < OMAPLFB_VSYNC_SETTLE_COUNT; i++) -+ { -+ if (DontWaitForVSync(psDevInfo) || !OMAPLFBWaitForVSync(psDevInfo)) -+ { -+ return OMAPLFB_FALSE; -+ } -+ } -+ -+ return OMAPLFB_TRUE; -+} -+ -+/* -+ * Swap handler. -+ * Called from the swap chain work queue handler. -+ * There is no need to take the swap chain creation lock in here, or use -+ * some other method of stopping the swap chain from being destroyed. -+ * This is because the swap chain creation lock is taken when queueing work, -+ * and the work queue is flushed before the swap chain is destroyed. -+ */ -+void OMAPLFBSwapHandler(OMAPLFB_BUFFER *psBuffer) -+{ -+ OMAPLFB_DEVINFO *psDevInfo = psBuffer->psDevInfo; -+ OMAPLFB_SWAPCHAIN *psSwapChain = psDevInfo->psSwapChain; -+ OMAPLFB_BOOL bPreviouslyNotVSynced; -+ -+#if defined(SUPPORT_DRI_DRM) -+ if (!OMAPLFBAtomicBoolRead(&psDevInfo->sLeaveVT)) -+#endif -+ { -+ OMAPLFBFlip(psDevInfo, psBuffer); -+ } -+ -+ bPreviouslyNotVSynced = psSwapChain->bNotVSynced; -+ psSwapChain->bNotVSynced = OMAPLFB_TRUE; -+ -+ -+ if (!DontWaitForVSync(psDevInfo)) -+ { -+ OMAPLFB_UPDATE_MODE eMode = OMAPLFBGetUpdateMode(psDevInfo); -+ int iBlankEvents = OMAPLFBAtomicIntRead(&psDevInfo->sBlankEvents); -+ -+ switch(eMode) -+ { -+ case OMAPLFB_UPDATE_MODE_AUTO: -+ psSwapChain->bNotVSynced = OMAPLFB_FALSE; -+ -+ if (bPreviouslyNotVSynced || psSwapChain->iBlankEvents != iBlankEvents) -+ { -+ psSwapChain->iBlankEvents = iBlankEvents; -+ psSwapChain->bNotVSynced = !WaitForVSyncSettle(psDevInfo); -+ } else if (psBuffer->ulSwapInterval != 0) -+ { -+ psSwapChain->bNotVSynced = !OMAPLFBWaitForVSync(psDevInfo); -+ } -+ break; -+#if defined(PVR_OMAPFB3_MANUAL_UPDATE_SYNC_IN_SWAP) -+ case OMAPLFB_UPDATE_MODE_MANUAL: -+ if (psBuffer->ulSwapInterval != 0) -+ { -+ (void) OMAPLFBManualSync(psDevInfo); -+ } -+ break; -+#endif -+ default: -+ break; -+ } -+ } -+ -+ psDevInfo->sPVRJTable.pfnPVRSRVCmdComplete((IMG_HANDLE)psBuffer->hCmdComplete, IMG_TRUE); -+} -+ -+/* Triggered by PVRSRVSwapToDCBuffer */ -+static IMG_BOOL ProcessFlipV1(IMG_HANDLE hCmdCookie, -+ OMAPLFB_DEVINFO *psDevInfo, -+ OMAPLFB_SWAPCHAIN *psSwapChain, -+ OMAPLFB_BUFFER *psBuffer, -+ unsigned long ulSwapInterval) -+{ -+ OMAPLFBCreateSwapChainLock(psDevInfo); -+ -+ /* The swap chain has been destroyed */ -+ if (SwapChainHasChanged(psDevInfo, psSwapChain)) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX -+ ": %s: Device %u (PVR Device ID %u): The swap chain has been destroyed\n", -+ __FUNCTION__, psDevInfo->uiFBDevID, psDevInfo->uiPVRDevID)); -+ } -+ else -+ { -+ psBuffer->hCmdComplete = (OMAPLFB_HANDLE)hCmdCookie; -+ psBuffer->ulSwapInterval = ulSwapInterval; -+#if defined(CONFIG_DSSCOMP) -+ if (is_tiler_addr(psBuffer->sSysAddr.uiAddr)) -+ { -+ int res; -+ IMG_UINT32 w = psBuffer->psDevInfo->sDisplayDim.ui32Width; -+ IMG_UINT32 h = psBuffer->psDevInfo->sDisplayDim.ui32Height; -+ struct dsscomp_setup_dispc_data comp = { -+ .num_mgrs = 1, -+ .mgrs[0].alpha_blending = 1, -+ .num_ovls = 1, -+ .ovls[0].cfg = -+ { -+ .width = w, -+ .win.w = w, -+ .crop.w = w, -+ .height = h, -+ .win.h = h, -+ .crop.h = h, -+ .stride = psBuffer->psDevInfo->sDisplayDim.ui32ByteStride, -+ .color_mode = OMAP_DSS_COLOR_ARGB32, -+ .enabled = 1, -+ .global_alpha = 255, -+ }, -+ .mode = DSSCOMP_SETUP_DISPLAY, -+ }; -+ struct tiler_pa_info *pas[1] = { NULL }; -+ comp.ovls[0].ba = (u32) psBuffer->sSysAddr.uiAddr; -+ res = dsscomp_gralloc_queue(&comp, pas, true, -+ (void *) psDevInfo->sPVRJTable.pfnPVRSRVCmdComplete, -+ (void *) psBuffer->hCmdComplete); -+ if (res != 0) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: dsscomp_gralloc_queue failed (Y Offset: %lu, Error: %d)\n", __FUNCTION__, psDevInfo->uiFBDevID, psBuffer->ulYOffset, res)); -+ } -+ } -+ else -+#endif /* defined(CONFIG_DSSCOMP) */ -+ { -+ OMAPLFBQueueBufferForSwap(psSwapChain, psBuffer); -+ } -+ } -+ -+ OMAPLFBCreateSwapChainUnLock(psDevInfo); -+ -+ return IMG_TRUE; -+} -+ -+#if defined(CONFIG_DSSCOMP) -+ -+/* Triggered by PVRSRVSwapToDCBuffer2 */ -+static IMG_BOOL ProcessFlipV2(IMG_HANDLE hCmdCookie, -+ OMAPLFB_DEVINFO *psDevInfo, -+ PDC_MEM_INFO *ppsMemInfos, -+ IMG_UINT32 ui32NumMemInfos, -+ struct dsscomp_setup_dispc_data *psDssData, -+ IMG_UINT32 ui32DssDataLength) -+{ -+ struct tiler_pa_info *apsTilerPAs[5]; -+ IMG_UINT32 i, k; -+ struct -+ { -+ IMG_UINTPTR_T uiAddr; -+ IMG_UINTPTR_T uiUVAddr; -+ struct tiler_pa_info *psTilerInfo; -+ } -+ asMemInfo[5] = {}; -+ int res; -+ -+ if(ui32DssDataLength != sizeof(*psDssData)) -+ { -+ WARN(1, "invalid size of private data (%d vs %d)", -+ ui32DssDataLength, sizeof(*psDssData)); -+ return IMG_FALSE; -+ } -+ -+ if(psDssData->num_ovls == 0 || ui32NumMemInfos == 0) -+ { -+ WARN(1, "must have at least one layer"); -+ return IMG_FALSE; -+ } -+ -+ for(i = k = 0; i < ui32NumMemInfos && k < ARRAY_SIZE(asMemInfo); i++, k++) -+ { -+ struct tiler_pa_info *psTilerInfo; -+ IMG_CPU_VIRTADDR virtAddr; -+ IMG_CPU_PHYADDR phyAddr; -+ IMG_UINT32 ui32NumPages; -+ IMG_SIZE_T uByteSize; -+ int j; -+ -+ psDevInfo->sPVRJTable.pfnPVRSRVDCMemInfoGetByteSize(ppsMemInfos[i], &uByteSize); -+ ui32NumPages = (uByteSize + PAGE_SIZE - 1) >> PAGE_SHIFT; -+ -+ psDevInfo->sPVRJTable.pfnPVRSRVDCMemInfoGetCpuPAddr(ppsMemInfos[i], 0, &phyAddr); -+ -+ /* TILER buffers do not need meminfos */ -+ if(is_tiler_addr((u32)phyAddr.uiAddr)) -+ { -+#ifdef CONFIG_DRM_OMAP_DMM_TILER -+ enum tiler_fmt fmt; -+#endif -+ asMemInfo[k].uiAddr = phyAddr.uiAddr; -+#ifdef CONFIG_DRM_OMAP_DMM_TILER -+ if(tiler_get_fmt((u32)phyAddr.uiAddr, &fmt) && fmt == TILFMT_8BIT) -+#else -+ if(tiler_fmt((u32)phyAddr.uiAddr) == TILFMT_8BIT) -+#endif -+ { -+ psDevInfo->sPVRJTable.pfnPVRSRVDCMemInfoGetCpuPAddr(ppsMemInfos[i], (uByteSize * 2) / 3, &phyAddr); -+ asMemInfo[k].uiUVAddr = phyAddr.uiAddr; -+ } -+ continue; -+ } -+ -+ /* normal gralloc layer */ -+ psTilerInfo = kzalloc(sizeof(*psTilerInfo), GFP_KERNEL); -+ if(!psTilerInfo) -+ { -+ continue; -+ } -+ -+ psTilerInfo->mem = kzalloc(sizeof(*psTilerInfo->mem) * ui32NumPages, GFP_KERNEL); -+ if(!psTilerInfo->mem) -+ { -+ kfree(psTilerInfo); -+ continue; -+ } -+ -+ psTilerInfo->num_pg = ui32NumPages; -+ psTilerInfo->memtype = TILER_MEM_USING; -+ for(j = 0; j < ui32NumPages; j++) -+ { -+ psDevInfo->sPVRJTable.pfnPVRSRVDCMemInfoGetCpuPAddr(ppsMemInfos[i], j << PAGE_SHIFT, &phyAddr); -+ psTilerInfo->mem[j] = (u32)phyAddr.uiAddr; -+ } -+ -+ /* need base address for in-page offset */ -+ psDevInfo->sPVRJTable.pfnPVRSRVDCMemInfoGetCpuVAddr(ppsMemInfos[i], &virtAddr); -+ asMemInfo[k].uiAddr = (IMG_UINTPTR_T) virtAddr; -+ asMemInfo[k].psTilerInfo = psTilerInfo; -+ } -+ -+ for(i = 0; i < psDssData->num_ovls; i++) -+ { -+ unsigned int ix; -+ apsTilerPAs[i] = NULL; -+ -+ /* only supporting Post2, cloned and fbmem layers */ -+ if (psDssData->ovls[i].addressing != OMAP_DSS_BUFADDR_LAYER_IX && -+ psDssData->ovls[i].addressing != OMAP_DSS_BUFADDR_OVL_IX && -+ psDssData->ovls[i].addressing != OMAP_DSS_BUFADDR_FB) -+ { -+ psDssData->ovls[i].cfg.enabled = false; -+ } -+ -+ if (psDssData->ovls[i].addressing != OMAP_DSS_BUFADDR_LAYER_IX) -+ { -+ continue; -+ } -+ -+ /* Post2 layers */ -+ ix = psDssData->ovls[i].ba; -+ if (ix >= k) -+ { -+ WARN(1, "Invalid Post2 layer (%u)", ix); -+ psDssData->ovls[i].cfg.enabled = false; -+ continue; -+ } -+ -+ psDssData->ovls[i].addressing = OMAP_DSS_BUFADDR_DIRECT; -+ psDssData->ovls[i].ba = (u32) asMemInfo[ix].uiAddr; -+ psDssData->ovls[i].uv = (u32) asMemInfo[ix].uiUVAddr; -+ apsTilerPAs[i] = asMemInfo[ix].psTilerInfo; -+ } -+ -+ res = dsscomp_gralloc_queue(psDssData, apsTilerPAs, false, -+ (void *)psDevInfo->sPVRJTable.pfnPVRSRVCmdComplete, -+ (void *)hCmdCookie); -+ if (res != 0) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: dsscomp_gralloc_queue failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, res)); -+ } -+ -+ for(i = 0; i < k; i++) -+ { -+ tiler_pa_free(apsTilerPAs[i]); -+ } -+ -+ return IMG_TRUE; -+} -+ -+#endif /* defined(CONFIG_DSSCOMP) */ -+ -+/* Command processing flip handler function. Called from services. */ -+static IMG_BOOL ProcessFlip(IMG_HANDLE hCmdCookie, -+ IMG_UINT32 ui32DataSize, -+ IMG_VOID *pvData) -+{ -+ DISPLAYCLASS_FLIP_COMMAND *psFlipCmd; -+ OMAPLFB_DEVINFO *psDevInfo; -+ -+ /* Check parameters */ -+ if(!hCmdCookie || !pvData) -+ { -+ return IMG_FALSE; -+ } -+ -+ /* Validate data packet */ -+ psFlipCmd = (DISPLAYCLASS_FLIP_COMMAND*)pvData; -+ -+ if (psFlipCmd == IMG_NULL) -+ { -+ return IMG_FALSE; -+ } -+ -+ psDevInfo = (OMAPLFB_DEVINFO*)psFlipCmd->hExtDevice; -+ -+ if(psFlipCmd->hExtBuffer) -+ { -+ return ProcessFlipV1(hCmdCookie, -+ psDevInfo, -+ psFlipCmd->hExtSwapChain, -+ psFlipCmd->hExtBuffer, -+ psFlipCmd->ui32SwapInterval); -+ } -+ else -+ { -+#if defined(CONFIG_DSSCOMP) -+ DISPLAYCLASS_FLIP_COMMAND2 *psFlipCmd2; -+ psFlipCmd2 = (DISPLAYCLASS_FLIP_COMMAND2 *)pvData; -+ return ProcessFlipV2(hCmdCookie, -+ psDevInfo, -+ psFlipCmd2->ppsMemInfos, -+ psFlipCmd2->ui32NumMemInfos, -+ psFlipCmd2->pvPrivData, -+ psFlipCmd2->ui32PrivDataLength); -+#else -+ BUG(); -+#endif -+ } -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function OMAPLFBInitFBDev -+ -+ @Description specifies devices in the systems memory map -+ -+ @Input psSysData - sys data -+ -+ @Return OMAPLFB_ERROR : -+ -+******************************************************************************/ -+static OMAPLFB_ERROR OMAPLFBInitFBDev(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ struct fb_info *psLINFBInfo; -+ struct module *psLINFBOwner; -+ OMAPLFB_FBINFO *psPVRFBInfo = &psDevInfo->sFBInfo; -+ OMAPLFB_ERROR eError = OMAPLFB_ERROR_GENERIC; -+ unsigned uiFBDevID = psDevInfo->uiFBDevID; -+ -+ OMAPLFB_CONSOLE_LOCK(); -+ -+ psLINFBInfo = registered_fb[uiFBDevID]; -+ if (psLINFBInfo == NULL) -+ { -+ eError = OMAPLFB_ERROR_INVALID_DEVICE; -+ goto ErrorRelSem; -+ } -+ -+ psLINFBOwner = psLINFBInfo->fbops->owner; -+ if (!try_module_get(psLINFBOwner)) -+ { -+ printk(KERN_INFO DRIVER_PREFIX -+ ": %s: Device %u: Couldn't get framebuffer module\n", __FUNCTION__, uiFBDevID); -+ -+ goto ErrorRelSem; -+ } -+ -+ if (psLINFBInfo->fbops->fb_open != NULL) -+ { -+ int res; -+ -+ res = psLINFBInfo->fbops->fb_open(psLINFBInfo, 0); -+ if (res != 0) -+ { -+ printk(KERN_INFO DRIVER_PREFIX -+ " %s: Device %u: Couldn't open framebuffer(%d)\n", __FUNCTION__, uiFBDevID, res); -+ -+ goto ErrorModPut; -+ } -+ } -+ -+ psDevInfo->psLINFBInfo = psLINFBInfo; -+ -+ psPVRFBInfo->ulWidth = psLINFBInfo->var.xres; -+ psPVRFBInfo->ulHeight = psLINFBInfo->var.yres; -+ -+ if (psPVRFBInfo->ulWidth == 0 || psPVRFBInfo->ulHeight == 0) -+ { -+ eError = OMAPLFB_ERROR_INVALID_DEVICE; -+ goto ErrorFBRel; -+ } -+ -+#if !defined(CONFIG_DSSCOMP) -+ psPVRFBInfo->ulFBSize = (psLINFBInfo->screen_size) != 0 ? -+ psLINFBInfo->screen_size : -+ psLINFBInfo->fix.smem_len; -+ -+ /* -+ * Try and filter out invalid FB info structures (a problem -+ * seen on some OMAP3 systems). -+ */ -+ if (psPVRFBInfo->ulFBSize == 0 || psLINFBInfo->fix.line_length == 0) -+ { -+ eError = OMAPLFB_ERROR_INVALID_DEVICE; -+ goto ErrorFBRel; -+ } -+ -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX -+ ": Device %u: Framebuffer size: %lu\n", -+ psDevInfo->uiFBDevID, psPVRFBInfo->ulFBSize)); -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX -+ ": Device %u: Framebuffer virtual width: %u\n", -+ psDevInfo->uiFBDevID, psLINFBInfo->var.xres_virtual)); -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX -+ ": Device %u: Framebuffer virtual height: %u\n", -+ psDevInfo->uiFBDevID, psLINFBInfo->var.yres_virtual)); -+#endif -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX -+ ": Device %u: Framebuffer width: %lu\n", -+ psDevInfo->uiFBDevID, psPVRFBInfo->ulWidth)); -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX -+ ": Device %u: Framebuffer height: %lu\n", -+ psDevInfo->uiFBDevID, psPVRFBInfo->ulHeight)); -+ -+#if defined(CONFIG_DSSCOMP) -+ { -+#if defined(SUPPORT_PVRSRV_GET_DC_SYSTEM_BUFFER) -+ /* -+ * Assume we need 3 swap buffers, and a separate system -+ * buffer. -+ */ -+ int n = 4; -+#else -+ /* -+ * Assume we need just 3 swap buffers, and no separate -+ * system buffer. -+ */ -+ int n = 3; -+#endif -+ int res; -+ int i, x, y, w; -+ ion_phys_addr_t phys; -+ size_t size; -+ struct tiler_view_t view; -+ -+ struct omap_ion_tiler_alloc_data sAllocData = -+ { -+ /* TILER will align width to 128-bytes */ -+ /* however, SGX must have full page width */ -+ .w = ALIGN(psPVRFBInfo->ulWidth, PAGE_SIZE / (psLINFBInfo->var.bits_per_pixel / 8)), -+ .h = psPVRFBInfo->ulHeight, -+ .fmt = psLINFBInfo->var.bits_per_pixel == 16 ? TILER_PIXEL_FMT_16BIT : TILER_PIXEL_FMT_32BIT, -+ .flags = 0, -+ }; -+ -+ printk(KERN_DEBUG DRIVER_PREFIX -+ " %s: Device %u: Requesting %d TILER 2D framebuffers\n", -+ __FUNCTION__, uiFBDevID, n); -+ -+ sAllocData.w *= n; -+ -+ psPVRFBInfo->uiBytesPerPixel = psLINFBInfo->var.bits_per_pixel >> 3; -+ psPVRFBInfo->bIs2D = OMAPLFB_TRUE; -+ -+ res = omap_ion_tiler_alloc(psDevInfo->psIONClient, &sAllocData); -+ psPVRFBInfo->psIONHandle = sAllocData.handle; -+ if (res < 0) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ " %s: Device %u: Could not allocate 2D framebuffer(%d)\n", -+ __FUNCTION__, uiFBDevID, res); -+ goto ErrorFBRel; -+ } -+ -+ res = ion_phys(psDevInfo->psIONClient, sAllocData.handle, &phys, &size); -+ if (res < 0) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ " %s: Device %u: Could not get 2D framebufferphysical address (%d)\n", -+ __FUNCTION__, uiFBDevID, res); -+ goto ErrorFBRel; -+ } -+ -+ psPVRFBInfo->sSysAddr.uiAddr = phys; -+ psPVRFBInfo->sCPUVAddr = 0; -+ -+ psPVRFBInfo->ulByteStride = PAGE_ALIGN(psPVRFBInfo->ulWidth * psPVRFBInfo->uiBytesPerPixel); -+ w = psPVRFBInfo->ulByteStride >> PAGE_SHIFT; -+ -+ psPVRFBInfo->ulFBSize = sAllocData.h * n * psPVRFBInfo->ulByteStride; -+ psPVRFBInfo->psPageList = kzalloc(w * n * psPVRFBInfo->ulHeight * sizeof(*psPVRFBInfo->psPageList), GFP_KERNEL); -+ if (!psPVRFBInfo->psPageList) -+ { -+ printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Could not allocate page list\n", __FUNCTION__, psDevInfo->uiFBDevID); -+ ion_free(psDevInfo->psIONClient, sAllocData.handle); -+ goto ErrorFBRel; -+ } -+ -+ tilview_create(&view, phys, psDevInfo->sFBInfo.ulWidth, psDevInfo->sFBInfo.ulHeight); -+ for(i = 0; i < n; i++) -+ { -+ for(y = 0; y < psDevInfo->sFBInfo.ulHeight; y++) -+ { -+ for(x = 0; x < w; x++) -+ { -+ psPVRFBInfo->psPageList[i * psDevInfo->sFBInfo.ulHeight * w + y * w + x].uiAddr = -+ phys + view.v_inc * y + ((x + i * w) << PAGE_SHIFT); -+ } -+ } -+ } -+ } -+#else /* defined(CONFIG_DSSCOMP) */ -+ /* System Surface */ -+ psPVRFBInfo->sSysAddr.uiAddr = psLINFBInfo->fix.smem_start; -+ psPVRFBInfo->sCPUVAddr = psLINFBInfo->screen_base; -+ -+ psPVRFBInfo->ulByteStride = psLINFBInfo->fix.line_length; -+#endif /* defined(CONFIG_DSSCOMP) */ -+ -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX -+ ": Device %u: Framebuffer physical address: 0x%x\n", -+ psDevInfo->uiFBDevID, psPVRFBInfo->sSysAddr.uiAddr)); -+ -+ if (psPVRFBInfo->sCPUVAddr != NULL) -+ { -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX -+ ": Device %u: Framebuffer virtual address: %p\n", -+ psDevInfo->uiFBDevID, psPVRFBInfo->sCPUVAddr)); -+ } -+ -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX -+ ": Device %u: Framebuffer stride: %lu\n", -+ psDevInfo->uiFBDevID, psPVRFBInfo->ulByteStride)); -+ -+ /* Additional implementation specific information */ -+ OMAPLFBPrintInfo(psDevInfo); -+ -+ psPVRFBInfo->ulBufferSize = psPVRFBInfo->ulHeight * psPVRFBInfo->ulByteStride; -+ -+#if defined(CONFIG_DSSCOMP) -+ psPVRFBInfo->ulRoundedBufferSize = psPVRFBInfo->ulBufferSize; -+#else -+ { -+ unsigned long ulLCM; -+ ulLCM = LCM(psPVRFBInfo->ulByteStride, OMAPLFB_PAGE_SIZE); -+ -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX -+ ": Device %u: LCM of stride and page size: %lu\n", -+ psDevInfo->uiFBDevID, ulLCM)); -+ -+ /* Round the buffer size up to a multiple of the number of pages -+ * and the byte stride. -+ * This is used internally, to ensure buffers start on page -+ * boundaries, for the benefit of PVR Services. -+ */ -+ psPVRFBInfo->ulRoundedBufferSize = RoundUpToMultiple(psPVRFBInfo->ulBufferSize, ulLCM); -+ } -+#endif -+ if(psLINFBInfo->var.bits_per_pixel == 16) -+ { -+ if((psLINFBInfo->var.red.length == 5) && -+ (psLINFBInfo->var.green.length == 6) && -+ (psLINFBInfo->var.blue.length == 5) && -+ (psLINFBInfo->var.red.offset == 11) && -+ (psLINFBInfo->var.green.offset == 5) && -+ (psLINFBInfo->var.blue.offset == 0) && -+ (psLINFBInfo->var.red.msb_right == 0)) -+ { -+ psPVRFBInfo->ePixelFormat = PVRSRV_PIXEL_FORMAT_RGB565; -+ } -+ else -+ { -+ printk(KERN_INFO DRIVER_PREFIX ": %s: Device %u: Unknown FB format\n", __FUNCTION__, uiFBDevID); -+ } -+ } -+ else if(psLINFBInfo->var.bits_per_pixel == 32) -+ { -+ if((psLINFBInfo->var.red.length == 8) && -+ (psLINFBInfo->var.green.length == 8) && -+ (psLINFBInfo->var.blue.length == 8) && -+ (psLINFBInfo->var.red.offset == 16) && -+ (psLINFBInfo->var.green.offset == 8) && -+ (psLINFBInfo->var.blue.offset == 0) && -+ (psLINFBInfo->var.red.msb_right == 0)) -+ { -+ psPVRFBInfo->ePixelFormat = PVRSRV_PIXEL_FORMAT_ARGB8888; -+ } -+ else -+ { -+ printk(KERN_INFO DRIVER_PREFIX ": %s: Device %u: Unknown FB format\n", __FUNCTION__, uiFBDevID); -+ } -+ } -+ else -+ { -+ printk(KERN_INFO DRIVER_PREFIX ": %s: Device %u: Unknown FB format\n", __FUNCTION__, uiFBDevID); -+ } -+ -+ psDevInfo->sFBInfo.ulPhysicalWidthmm = -+ ((int)psLINFBInfo->var.width > 0) ? psLINFBInfo->var.width : 90; -+ -+ psDevInfo->sFBInfo.ulPhysicalHeightmm = -+ ((int)psLINFBInfo->var.height > 0) ? psLINFBInfo->var.height : 54; -+ -+ /* System Surface */ -+ psDevInfo->sFBInfo.sSysAddr.uiAddr = psPVRFBInfo->sSysAddr.uiAddr; -+ psDevInfo->sFBInfo.sCPUVAddr = psPVRFBInfo->sCPUVAddr; -+ -+ eError = OMAPLFB_OK; -+ goto ErrorRelSem; -+ -+ErrorFBRel: -+ if (psLINFBInfo->fbops->fb_release != NULL) -+ { -+ (void) psLINFBInfo->fbops->fb_release(psLINFBInfo, 0); -+ } -+ErrorModPut: -+ module_put(psLINFBOwner); -+ErrorRelSem: -+ OMAPLFB_CONSOLE_UNLOCK(); -+ -+ return eError; -+} -+ -+static void OMAPLFBDeInitFBDev(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ struct fb_info *psLINFBInfo = psDevInfo->psLINFBInfo; -+ struct module *psLINFBOwner; -+ -+ OMAPLFB_CONSOLE_LOCK(); -+ -+#if defined(CONFIG_DSSCOMP) -+ { -+ OMAPLFB_FBINFO *psPVRFBInfo = &psDevInfo->sFBInfo; -+ kfree(psPVRFBInfo->psPageList); -+ if (psPVRFBInfo->psIONHandle) -+ { -+ ion_free(psDevInfo->psIONClient, psPVRFBInfo->psIONHandle); -+ } -+ } -+#endif /* defined(CONFIG_DSSCOMP) */ -+ -+ psLINFBOwner = psLINFBInfo->fbops->owner; -+ -+ if (psLINFBInfo->fbops->fb_release != NULL) -+ { -+ (void) psLINFBInfo->fbops->fb_release(psLINFBInfo, 0); -+ } -+ -+ module_put(psLINFBOwner); -+ -+ OMAPLFB_CONSOLE_UNLOCK(); -+} -+ -+static OMAPLFB_DEVINFO *OMAPLFBInitDev(unsigned uiFBDevID) -+{ -+ PFN_CMD_PROC pfnCmdProcList[OMAPLFB_COMMAND_COUNT]; -+ IMG_UINT32 aui32SyncCountList[OMAPLFB_COMMAND_COUNT][2]; -+ OMAPLFB_DEVINFO *psDevInfo = NULL; -+ -+ /* Allocate device info. structure */ -+ psDevInfo = (OMAPLFB_DEVINFO *)OMAPLFBAllocKernelMem(sizeof(OMAPLFB_DEVINFO)); -+ -+ if(psDevInfo == NULL) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ ": %s: Device %u: Couldn't allocate device information structure\n", __FUNCTION__, uiFBDevID); -+ -+ goto ErrorExit; -+ } -+ -+ /* Any fields not set will be zero */ -+ memset(psDevInfo, 0, sizeof(OMAPLFB_DEVINFO)); -+ -+ psDevInfo->uiFBDevID = uiFBDevID; -+ -+ /* Get the kernel services function table */ -+ if(!(*gpfnGetPVRJTable)(&psDevInfo->sPVRJTable)) -+ { -+ goto ErrorFreeDevInfo; -+ } -+ -+#if defined(CONFIG_ION_OMAP) -+ psDevInfo->psIONClient = -+ ion_client_create(omap_ion_device, -+ 1 << ION_HEAP_TYPE_CARVEOUT | -+ 1 << OMAP_ION_HEAP_TYPE_TILER, -+ "dc_omapfb3_linux"); -+ if (IS_ERR_OR_NULL(psDevInfo->psIONClient)) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ ": %s: Device %u: Failed to create ion client\n", __FUNCTION__, uiFBDevID); -+ -+ goto ErrorFreeDevInfo; -+ } -+#endif /* defined(CONFIG_ION_OMAP) */ -+ -+#ifdef FBDEV_PRESENT -+ /* Save private fbdev information structure in the dev. info. */ -+ if(OMAPLFBInitFBDev(psDevInfo) != OMAPLFB_OK) -+ { -+ /* -+ * Leave it to OMAPLFBInitFBDev to print an error message, if -+ * required. The function may have failed because -+ * there is no Linux framebuffer device corresponding -+ * to the device ID. -+ */ -+ goto ErrorIonClientDestroy; -+ } -+ -+ psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers = (IMG_UINT32)(psDevInfo->sFBInfo.ulFBSize / psDevInfo->sFBInfo.ulRoundedBufferSize); -+ if (psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers != 0) -+ { -+ psDevInfo->sDisplayInfo.ui32MaxSwapChains = 1; -+ psDevInfo->sDisplayInfo.ui32MaxSwapInterval = 1; -+#if defined(CONFIG_DSSCOMP) -+ psDevInfo->sDisplayInfo.ui32MinSwapInterval = 1; -+#endif -+ } -+ -+ psDevInfo->sDisplayInfo.ui32PhysicalWidthmm = psDevInfo->sFBInfo.ulPhysicalWidthmm; -+ psDevInfo->sDisplayInfo.ui32PhysicalHeightmm = psDevInfo->sFBInfo.ulPhysicalHeightmm; -+ -+ strncpy(psDevInfo->sDisplayInfo.szDisplayName, DISPLAY_DEVICE_NAME, MAX_DISPLAY_NAME_SIZE); -+ -+ psDevInfo->sDisplayFormat.pixelformat = psDevInfo->sFBInfo.ePixelFormat; -+ psDevInfo->sDisplayDim.ui32Width = (IMG_UINT32)psDevInfo->sFBInfo.ulWidth; -+ psDevInfo->sDisplayDim.ui32Height = (IMG_UINT32)psDevInfo->sFBInfo.ulHeight; -+ psDevInfo->sDisplayDim.ui32ByteStride = (IMG_UINT32)psDevInfo->sFBInfo.ulByteStride; -+ -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX -+ ": Device %u: Maximum number of swap chain buffers: %u\n", -+ psDevInfo->uiFBDevID, psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers)); -+ -+ /* Setup system buffer */ -+ psDevInfo->sSystemBuffer.sSysAddr = psDevInfo->sFBInfo.sSysAddr; -+ psDevInfo->sSystemBuffer.sCPUVAddr = psDevInfo->sFBInfo.sCPUVAddr; -+ psDevInfo->sSystemBuffer.psDevInfo = psDevInfo; -+ -+ OMAPLFBInitBufferForSwap(&psDevInfo->sSystemBuffer); -+#else -+psDevInfo->sSystemBuffer.sCPUVAddr = 0x100; -+// psDevInfo->sSystemBuffer.ulBufferSize = 600*3200; -+ -+ psDevInfo->sDisplayFormat.pixelformat = 20; -+ psDevInfo->sFBInfo.ulWidth = 800; -+ psDevInfo->sFBInfo.ulHeight = 600; -+ psDevInfo->sFBInfo.ulByteStride = 3200; -+ psDevInfo->sFBInfo.ulFBSize = 8388608; -+ psDevInfo->sFBInfo.ulBufferSize = 600*3200; -+#endif -+ -+#if defined(CONFIG_DSSCOMP) && defined(SUPPORT_PVRSRV_GET_DC_SYSTEM_BUFFER) -+ OMAPLFBFlip(psDevInfo, &psDevInfo->sSystemBuffer); -+#endif -+ -+ /* -+ Setup the DC Jtable so SRVKM can call into this driver -+ */ -+ psDevInfo->sDCJTable.ui32TableSize = sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE); -+ psDevInfo->sDCJTable.pfnOpenDCDevice = OpenDCDevice; -+ psDevInfo->sDCJTable.pfnCloseDCDevice = CloseDCDevice; -+ psDevInfo->sDCJTable.pfnEnumDCFormats = EnumDCFormats; -+ psDevInfo->sDCJTable.pfnEnumDCDims = EnumDCDims; -+ psDevInfo->sDCJTable.pfnGetDCSystemBuffer = GetDCSystemBuffer; -+ psDevInfo->sDCJTable.pfnGetDCInfo = GetDCInfo; -+ psDevInfo->sDCJTable.pfnGetBufferAddr = GetDCBufferAddr; -+ psDevInfo->sDCJTable.pfnCreateDCSwapChain = CreateDCSwapChain; -+ psDevInfo->sDCJTable.pfnDestroyDCSwapChain = DestroyDCSwapChain; -+ psDevInfo->sDCJTable.pfnSetDCDstRect = SetDCDstRect; -+ psDevInfo->sDCJTable.pfnSetDCSrcRect = SetDCSrcRect; -+ psDevInfo->sDCJTable.pfnSetDCDstColourKey = SetDCDstColourKey; -+ psDevInfo->sDCJTable.pfnSetDCSrcColourKey = SetDCSrcColourKey; -+ psDevInfo->sDCJTable.pfnGetDCBuffers = GetDCBuffers; -+ psDevInfo->sDCJTable.pfnSwapToDCBuffer = SwapToDCBuffer; -+ psDevInfo->sDCJTable.pfnSetDCState = SetDCState; -+ -+ /* Register device with services and retrieve device index */ -+ if(psDevInfo->sPVRJTable.pfnPVRSRVRegisterDCDevice( -+ &psDevInfo->sDCJTable, -+ &psDevInfo->uiPVRDevID) != PVRSRV_OK) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ ": %s: Device %u: PVR Services device registration failed\n", __FUNCTION__, uiFBDevID); -+ -+ goto ErrorDeInitFBDev; -+ } -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX -+ ": Device %u: PVR Device ID: %u\n", -+ psDevInfo->uiFBDevID, psDevInfo->uiPVRDevID)); -+ -+ /* Setup private command processing function table ... */ -+ pfnCmdProcList[DC_FLIP_COMMAND] = ProcessFlip; -+ -+ /* ... and associated sync count(s) */ -+ aui32SyncCountList[DC_FLIP_COMMAND][0] = 0; /* writes */ -+ aui32SyncCountList[DC_FLIP_COMMAND][1] = 10; /* reads */ -+ -+ /* -+ Register private command processing functions with -+ the Command Queue Manager and setup the general -+ command complete function in the devinfo. -+ */ -+ if (psDevInfo->sPVRJTable.pfnPVRSRVRegisterCmdProcList(psDevInfo->uiPVRDevID, -+ &pfnCmdProcList[0], -+ aui32SyncCountList, -+ OMAPLFB_COMMAND_COUNT) != PVRSRV_OK) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ ": %s: Device %u: Couldn't register command processing functions with PVR Services\n", __FUNCTION__, uiFBDevID); -+ goto ErrorUnregisterDevice; -+ } -+ -+ OMAPLFBCreateSwapChainLockInit(psDevInfo); -+ -+ OMAPLFBAtomicBoolInit(&psDevInfo->sBlanked, OMAPLFB_FALSE); -+ OMAPLFBAtomicIntInit(&psDevInfo->sBlankEvents, 0); -+ OMAPLFBAtomicBoolInit(&psDevInfo->sFlushCommands, OMAPLFB_FALSE); -+#if defined(CONFIG_HAS_EARLYSUSPEND) -+ OMAPLFBAtomicBoolInit(&psDevInfo->sEarlySuspendFlag, OMAPLFB_FALSE); -+#endif -+#if defined(SUPPORT_DRI_DRM) -+ OMAPLFBAtomicBoolInit(&psDevInfo->sLeaveVT, OMAPLFB_FALSE); -+#endif -+ -+ return psDevInfo; -+ -+ErrorUnregisterDevice: -+ (void)psDevInfo->sPVRJTable.pfnPVRSRVRemoveDCDevice(psDevInfo->uiPVRDevID); -+ErrorDeInitFBDev: -+ OMAPLFBDeInitFBDev(psDevInfo); -+ErrorIonClientDestroy: -+#if defined(CONFIG_ION_OMAP) -+ ion_client_destroy(psDevInfo->psIONClient); -+#endif /* defined(CONFIG_ION_OMAP) */ -+ErrorFreeDevInfo: -+ OMAPLFBFreeKernelMem(psDevInfo); -+ErrorExit: -+ return NULL; -+} -+ -+OMAPLFB_ERROR OMAPLFBInit(void) -+{ -+ unsigned uiMaxFBDevIDPlusOne = OMAPLFBMaxFBDevIDPlusOne(); -+ unsigned i; -+ unsigned uiDevicesFound = 0; -+ -+ if(OMAPLFBGetLibFuncAddr ("PVRGetDisplayClassJTable", &gpfnGetPVRJTable) != OMAPLFB_OK) -+ { -+ return OMAPLFB_ERROR_INIT_FAILURE; -+ } -+ -+ /* -+ * We search for frame buffer devices backwards, as the last device -+ * registered with PVR Services will be the first device enumerated -+ * by PVR Services. -+ */ -+ for(i = uiMaxFBDevIDPlusOne; i-- != 0;) -+ { -+ OMAPLFB_DEVINFO *psDevInfo = OMAPLFBInitDev(i); -+ -+ if (psDevInfo != NULL) -+ { -+ /* Set the top-level anchor */ -+ OMAPLFBSetDevInfoPtr(psDevInfo->uiFBDevID, psDevInfo); -+ uiDevicesFound++; -+ } -+ } -+ -+ return (uiDevicesFound != 0) ? OMAPLFB_OK : OMAPLFB_ERROR_INIT_FAILURE; -+} -+ -+/* -+ * OMAPLFBDeInitDev -+ * DeInitialises one device -+ */ -+static OMAPLFB_BOOL OMAPLFBDeInitDev(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ PVRSRV_DC_DISP2SRV_KMJTABLE *psPVRJTable = &psDevInfo->sPVRJTable; -+ -+ if (psPVRJTable->pfnPVRSRVRemoveCmdProcList (psDevInfo->uiPVRDevID, OMAPLFB_COMMAND_COUNT) != PVRSRV_OK) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ ": %s: Device %u: PVR Device %u: Couldn't unregister command processing functions\n", __FUNCTION__, psDevInfo->uiFBDevID, psDevInfo->uiPVRDevID); -+ return OMAPLFB_FALSE; -+ } -+ -+ /* -+ * Remove display class device from kernel services device -+ * register. -+ */ -+ if (psPVRJTable->pfnPVRSRVRemoveDCDevice(psDevInfo->uiPVRDevID) != PVRSRV_OK) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ ": %s: Device %u: PVR Device %u: Couldn't remove device from PVR Services\n", __FUNCTION__, psDevInfo->uiFBDevID, psDevInfo->uiPVRDevID); -+ return OMAPLFB_FALSE; -+ } -+ -+#if defined(CONFIG_DSSCOMP) -+ /* Disable the overlay, as we will be freeing the display buffers */ -+ psDevInfo->sSystemBuffer.sSysAddr.uiAddr = 0; -+ OMAPLFBFlip(psDevInfo, &psDevInfo->sSystemBuffer); -+#endif /* defined(CONFIG_DSSCOMP) */ -+ -+ OMAPLFBCreateSwapChainLockDeInit(psDevInfo); -+ -+ OMAPLFBAtomicBoolDeInit(&psDevInfo->sBlanked); -+ OMAPLFBAtomicIntDeInit(&psDevInfo->sBlankEvents); -+ OMAPLFBAtomicBoolDeInit(&psDevInfo->sFlushCommands); -+#if defined(CONFIG_HAS_EARLYSUSPEND) -+ OMAPLFBAtomicBoolDeInit(&psDevInfo->sEarlySuspendFlag); -+#endif -+#if defined(SUPPORT_DRI_DRM) -+ OMAPLFBAtomicBoolDeInit(&psDevInfo->sLeaveVT); -+#endif -+ -+#ifdef FBDEV_PRESENT -+ OMAPLFBDeInitFBDev(psDevInfo); -+#endif -+#if defined(CONFIG_ION_OMAP) -+ ion_client_destroy(psDevInfo->psIONClient); -+#endif -+ -+ OMAPLFBSetDevInfoPtr(psDevInfo->uiFBDevID, NULL); -+ -+ /* De-allocate data structure */ -+ OMAPLFBFreeKernelMem(psDevInfo); -+ -+ return OMAPLFB_TRUE; -+} -+ -+/* -+ * OMAPLFBDeInit -+ * Deinitialises the display class device component of the FBDev -+ */ -+OMAPLFB_ERROR OMAPLFBDeInit(void) -+{ -+ unsigned uiMaxFBDevIDPlusOne = OMAPLFBMaxFBDevIDPlusOne(); -+ unsigned i; -+ OMAPLFB_BOOL bError = OMAPLFB_FALSE; -+ -+ for(i = 0; i < uiMaxFBDevIDPlusOne; i++) -+ { -+ OMAPLFB_DEVINFO *psDevInfo = OMAPLFBGetDevInfoPtr(i); -+ -+ if (psDevInfo != NULL) -+ { -+ bError |= !OMAPLFBDeInitDev(psDevInfo); -+ } -+ } -+ -+ return (bError) ? OMAPLFB_ERROR_INIT_FAILURE : OMAPLFB_OK; -+} -+ -+/****************************************************************************** -+ End of file (omaplfb_displayclass.c) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti43xx_linux/omaplfb_linux.c b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti43xx_linux/omaplfb_linux.c -new file mode 100644 -index 0000000..c9620e6 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti43xx_linux/omaplfb_linux.c -@@ -0,0 +1,1304 @@ -+/*************************************************************************/ /*! -+@Title OMAP linux display driver components -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+/************************************************************************** -+ The 3rd party driver is a specification of an API to integrate the IMG POWERVR -+ Services driver with 3rd Party display hardware. It is NOT a specification for -+ a display controller driver, rather a specification to extend the API for a -+ pre-existing driver for the display hardware. -+ -+ The 3rd party driver interface provides IMG POWERVR client drivers (e.g. PVR2D) -+ with an API abstraction of the system's underlying display hardware, allowing -+ the client drivers to indirectly control the display hardware and access its -+ associated memory. -+ -+ Functions of the API include -+ - query primary surface attributes (width, height, stride, pixel format, CPU -+ physical and virtual address) -+ - swap/flip chain creation and subsequent query of surface attributes -+ - asynchronous display surface flipping, taking account of asynchronous read -+ (flip) and write (render) operations to the display surface -+ -+ Note: having queried surface attributes the client drivers are able to map the -+ display memory to any IMG POWERVR Services device by calling -+ PVRSRVMapDeviceClassMemory with the display surface handle. -+ -+ This code is intended to be an example of how a pre-existing display driver may -+ be extended to support the 3rd Party Display interface to POWERVR Services -+ - IMG is not providing a display driver implementation. -+ **************************************************************************/ -+ -+#include <linux/version.h> -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)) -+#ifndef AUTOCONF_INCLUDED -+#include <linux/config.h> -+#endif -+#endif -+ -+#include <asm/atomic.h> -+ -+#if defined(SUPPORT_DRI_DRM) -+#include <drm/drmP.h> -+#else -+#include <linux/module.h> -+#endif -+ -+#include <linux/kernel.h> -+#include <linux/slab.h> -+#include <linux/hardirq.h> -+#include <linux/mutex.h> -+#include <linux/workqueue.h> -+#include <linux/fb.h> -+#include <linux/console.h> -+#include <linux/omapfb.h> -+#include <linux/mutex.h> -+ -+#if defined(PVR_OMAPLFB_DRM_FB) -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0)) -+#include <plat/display.h> -+#else -+#include <video/omapdss.h> -+#endif -+#include <linux/omap_gpu.h> -+#else /* defined(PVR_OMAPLFB_DRM_FB) */ -+/* OmapZoom.org OMAP3 2.6.29 kernel tree - Needs mach/vrfb.h -+ * OmapZoom.org OMAP3 2.6.32 kernel tree - No additional header required -+ * OmapZoom.org OMAP4 2.6.33 kernel tree - No additional header required -+ * OmapZoom.org OMAP4 2.6.34 kernel tree - Needs plat/vrfb.h -+ * Sholes 2.6.32 kernel tree - Needs plat/vrfb.h -+ */ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34)) -+#define PVR_OMAPFB3_NEEDS_PLAT_VRFB_H -+#endif -+ -+#if defined(PVR_OMAPFB3_NEEDS_PLAT_VRFB_H) -+#ifdef FBDEV_PRESENT -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) -+#include <plat/vrfb.h> -+#else -+#include <video/omapvrfb.h> -+#endif -+#endif -+ -+#else -+#if defined(PVR_OMAPFB3_NEEDS_MACH_VRFB_H) -+#include <mach/vrfb.h> -+#endif -+#endif -+ -+#if defined(DEBUG) -+#define PVR_DEBUG DEBUG -+#undef DEBUG -+#endif -+#ifdef FBDEV_PRESENT -+#include <omapfb/omapfb.h> -+#endif -+#if defined(DEBUG) -+#undef DEBUG -+#endif -+#if defined(PVR_DEBUG) -+#define DEBUG PVR_DEBUG -+#undef PVR_DEBUG -+#endif -+#endif /* defined(PVR_OMAPLFB_DRM_FB) */ -+ -+#if defined(CONFIG_DSSCOMP) -+#if defined(CONFIG_DRM_OMAP_DMM_TILER) -+#include <../drivers/staging/omapdrm/omap_dmm_tiler.h> -+#include <../drivers/video/omap2/dsscomp/tiler-utils.h> -+#elif defined(CONFIG_TI_TILER) -+#include <mach/tiler.h> -+#else /* defined(CONFIG_DRM_OMAP_DMM_TILER) */ -+#error CONFIG_DSSCOMP support requires either \ -+ CONFIG_DRM_OMAP_DMM_TILER or CONFIG_TI_TILER -+#endif /* defined(CONFIG_DRM_OMAP_DMM_TILER) */ -+#include <video/dsscomp.h> -+#include <plat/dsscomp.h> -+#endif /* defined(CONFIG_DSSCOMP) */ -+ -+#include "img_defs.h" -+#include "servicesext.h" -+#include "kerneldisplay.h" -+#include "omaplfb.h" -+#include "pvrmodule.h" -+#if defined(SUPPORT_DRI_DRM) -+#include "pvr_drm.h" -+#include "3rdparty_dc_drm_shared.h" -+#endif -+ -+#if !defined(PVR_LINUX_USING_WORKQUEUES) -+#error "PVR_LINUX_USING_WORKQUEUES must be defined" -+#endif -+ -+MODULE_SUPPORTED_DEVICE(DEVNAME); -+ -+#if !defined(PVR_OMAPLFB_DRM_FB) -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34)) -+#define OMAP_DSS_DRIVER(drv, dev) struct omap_dss_driver *drv = (dev) != NULL ? (dev)->driver : NULL -+#define OMAP_DSS_MANAGER(man, dev) struct omap_overlay_manager *man = (dev) != NULL ? (dev)->managers[0] : NULL -+ -+#define WAIT_FOR_VSYNC(man) ((man)->wait_for_vsync) -+#else -+#define OMAP_DSS_DRIVER(drv, dev) struct omap_dss_device *drv = (dev) -+#define OMAP_DSS_MANAGER(man, dev) struct omap_dss_device *man = (dev) -+#define WAIT_FOR_VSYNC(man) ((man)->wait_vsync) -+#endif -+#endif /* !defined(PVR_OMAPLFB_DRM_FB) */ -+ -+void *OMAPLFBAllocKernelMem(unsigned long ulSize) -+{ -+ return kmalloc(ulSize, GFP_KERNEL); -+} -+ -+void OMAPLFBFreeKernelMem(void *pvMem) -+{ -+ kfree(pvMem); -+} -+ -+void OMAPLFBCreateSwapChainLockInit(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ mutex_init(&psDevInfo->sCreateSwapChainMutex); -+} -+ -+void OMAPLFBCreateSwapChainLockDeInit(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ mutex_destroy(&psDevInfo->sCreateSwapChainMutex); -+} -+ -+void OMAPLFBCreateSwapChainLock(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ mutex_lock(&psDevInfo->sCreateSwapChainMutex); -+} -+ -+void OMAPLFBCreateSwapChainUnLock(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ mutex_unlock(&psDevInfo->sCreateSwapChainMutex); -+} -+ -+void OMAPLFBAtomicBoolInit(OMAPLFB_ATOMIC_BOOL *psAtomic, OMAPLFB_BOOL bVal) -+{ -+ atomic_set(psAtomic, (int)bVal); -+} -+ -+void OMAPLFBAtomicBoolDeInit(OMAPLFB_ATOMIC_BOOL *psAtomic) -+{ -+} -+ -+void OMAPLFBAtomicBoolSet(OMAPLFB_ATOMIC_BOOL *psAtomic, OMAPLFB_BOOL bVal) -+{ -+ atomic_set(psAtomic, (int)bVal); -+} -+ -+OMAPLFB_BOOL OMAPLFBAtomicBoolRead(OMAPLFB_ATOMIC_BOOL *psAtomic) -+{ -+ return (OMAPLFB_BOOL)atomic_read(psAtomic); -+} -+ -+void OMAPLFBAtomicIntInit(OMAPLFB_ATOMIC_INT *psAtomic, int iVal) -+{ -+ atomic_set(psAtomic, iVal); -+} -+ -+void OMAPLFBAtomicIntDeInit(OMAPLFB_ATOMIC_INT *psAtomic) -+{ -+} -+ -+void OMAPLFBAtomicIntSet(OMAPLFB_ATOMIC_INT *psAtomic, int iVal) -+{ -+ atomic_set(psAtomic, iVal); -+} -+ -+int OMAPLFBAtomicIntRead(OMAPLFB_ATOMIC_INT *psAtomic) -+{ -+ return atomic_read(psAtomic); -+} -+ -+void OMAPLFBAtomicIntInc(OMAPLFB_ATOMIC_INT *psAtomic) -+{ -+ atomic_inc(psAtomic); -+} -+ -+OMAPLFB_ERROR OMAPLFBGetLibFuncAddr (char *szFunctionName, PFN_DC_GET_PVRJTABLE *ppfnFuncTable) -+{ -+ if(strcmp("PVRGetDisplayClassJTable", szFunctionName) != 0) -+ { -+ return (OMAPLFB_ERROR_INVALID_PARAMS); -+ } -+ -+ /* Nothing to do - should be exported from pvrsrv.ko */ -+ *ppfnFuncTable = PVRGetDisplayClassJTable; -+ -+ return (OMAPLFB_OK); -+} -+ -+/* Inset a swap buffer into the swap chain work queue */ -+void OMAPLFBQueueBufferForSwap(OMAPLFB_SWAPCHAIN *psSwapChain, OMAPLFB_BUFFER *psBuffer) -+{ -+ int res = queue_work(psSwapChain->psWorkQueue, &psBuffer->sWork); -+ -+ if (res == 0) -+ { -+ printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Buffer already on work queue\n", __FUNCTION__, psSwapChain->uiFBDevID); -+ } -+} -+ -+/* Process an item on a swap chain work queue */ -+static void WorkQueueHandler(struct work_struct *psWork) -+{ -+ OMAPLFB_BUFFER *psBuffer = container_of(psWork, OMAPLFB_BUFFER, sWork); -+ -+ OMAPLFBSwapHandler(psBuffer); -+} -+ -+/* Create a swap chain work queue */ -+OMAPLFB_ERROR OMAPLFBCreateSwapQueue(OMAPLFB_SWAPCHAIN *psSwapChain) -+{ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) -+#if (LINUX_VERSION_CODE == KERNEL_VERSION(2,6,37)) -+#define WQ_FREEZABLE WQ_FREEZEABLE -+#endif -+ /* -+ * Calling alloc_ordered_workqueue with the WQ_FREEZABLE and -+ * WQ_MEM_RECLAIM flags set, (currently) has the same effect as -+ * calling create_freezable_workqueue. None of the other WQ -+ * flags are valid. Setting WQ_MEM_RECLAIM should allow the -+ * workqueue to continue to service the swap chain in low memory -+ * conditions, preventing the driver from holding on to -+ * resources longer than it needs to. -+ */ -+ psSwapChain->psWorkQueue = alloc_ordered_workqueue(DEVNAME, WQ_FREEZABLE | WQ_MEM_RECLAIM); -+#else -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)) -+ psSwapChain->psWorkQueue = create_freezable_workqueue(DEVNAME); -+#else -+ /* -+ * Create a single-threaded, freezable, rt-prio workqueue. -+ * Such workqueues are frozen with user threads when a system -+ * suspends, before driver suspend entry points are called. -+ * This ensures this driver will not call into the Linux -+ * framebuffer driver after the latter is suspended. -+ */ -+ psSwapChain->psWorkQueue = __create_workqueue(DEVNAME, 1, 1, 1); -+#endif -+#endif -+ if (psSwapChain->psWorkQueue == NULL) -+ { -+ printk(KERN_ERR DRIVER_PREFIX ": %s: Device %u: Couldn't create workqueue\n", __FUNCTION__, psSwapChain->uiFBDevID); -+ -+ return (OMAPLFB_ERROR_INIT_FAILURE); -+ } -+ -+ return (OMAPLFB_OK); -+} -+ -+/* Prepare buffer for insertion into a swap chain work queue */ -+void OMAPLFBInitBufferForSwap(OMAPLFB_BUFFER *psBuffer) -+{ -+ INIT_WORK(&psBuffer->sWork, WorkQueueHandler); -+} -+ -+/* Destroy a swap chain work queue */ -+void OMAPLFBDestroySwapQueue(OMAPLFB_SWAPCHAIN *psSwapChain) -+{ -+ destroy_workqueue(psSwapChain->psWorkQueue); -+} -+ -+/* Flip display to given buffer */ -+void OMAPLFBFlip(OMAPLFB_DEVINFO *psDevInfo, OMAPLFB_BUFFER *psBuffer) -+{ -+ struct fb_var_screeninfo sFBVar; -+ int res; -+ -+ if (!lock_fb_info(psDevInfo->psLINFBInfo)) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX -+ ": %s: Device %u: Couldn't lock FB info\n", __FUNCTION__, psDevInfo->uiFBDevID)); -+ return; -+ } -+ -+ -+ OMAPLFB_CONSOLE_LOCK(); -+ -+ sFBVar = psDevInfo->psLINFBInfo->var; -+ -+ sFBVar.xoffset = 0; -+ sFBVar.yoffset = psBuffer->ulYOffset; -+ -+#if defined(CONFIG_DSSCOMP) -+ /* -+ * If flipping to a NULL buffer, blank the screen to prevent -+ * warnings/errors from the display subsystem. -+ */ -+ if (psBuffer->sSysAddr.uiAddr == 0) -+ { -+ struct omap_dss_device *psDSSDev = fb2display(psDevInfo->psLINFBInfo); -+ OMAP_DSS_MANAGER(psDSSMan, psDSSDev); -+ -+ if (psDSSMan != NULL && psDSSMan->blank != NULL) -+ { -+ res = psDSSMan->blank(psDSSMan, false); -+ if (res != 0) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: DSS manager blank call failed (Y Offset: %lu, Error: %d)\n", __FUNCTION__, psDevInfo->uiFBDevID, psBuffer->ulYOffset, res)); -+ } -+ } -+ } -+ -+ { -+ /* -+ * If using DSSCOMP, we need to use dsscomp queuing for normal -+ * framebuffer updates, so that previously used overlays get -+ * automatically disabled, and manager gets dirtied. We can -+ * do that because DSSCOMP takes ownership of all pipelines on -+ * a manager. -+ */ -+ struct fb_fix_screeninfo sFBFix = psDevInfo->psLINFBInfo->fix; -+ struct dsscomp_setup_dispc_data d = -+ { -+ .num_ovls = 1, -+ .num_mgrs = 1, -+ .mgrs[0].alpha_blending = 1, -+ .ovls[0] = -+ { -+ .cfg = -+ { -+ .win.w = sFBVar.xres, -+ .win.h = sFBVar.yres, -+ .crop.x = sFBVar.xoffset, -+ .crop.y = sFBVar.yoffset, -+ .crop.w = sFBVar.xres, -+ .crop.h = sFBVar.yres, -+ .width = sFBVar.xres_virtual, -+ .height = sFBVar.yres_virtual, -+ .stride = sFBFix.line_length, -+ .enabled = (psBuffer->sSysAddr.uiAddr != 0), -+ .global_alpha = 255, -+ }, -+ }, -+ }; -+ -+ /* do not map buffer into TILER1D as it is contiguous */ -+ struct tiler_pa_info *pas[] = { NULL }; -+ -+ d.ovls[0].ba = (u32) psBuffer->sSysAddr.uiAddr; -+ -+ omapfb_mode_to_dss_mode(&sFBVar, &d.ovls[0].cfg.color_mode); -+ -+ res = dsscomp_gralloc_queue(&d, pas, true, NULL, NULL); -+ if (res != 0) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: dsscomp_gralloc_queue failed (Y Offset: %lu, Error: %d)\n", __FUNCTION__, psDevInfo->uiFBDevID, psBuffer->ulYOffset, res)); -+ } -+ } -+#else /* defined(CONFIG_DSSCOMP) */ -+ { -+ unsigned long ulYResVirtual = psBuffer->ulYOffset + sFBVar.yres; -+ -+ /* -+ * PVR_OMAPLFB_DONT_USE_FB_PAN_DISPLAY should be defined to -+ * work around flipping problems seen with the Taal LCDs on -+ * Blaze. -+ * The work around is safe to use with other types of screen -+ * on Blaze (e.g. HDMI) and on other platforms (e.g. Panda -+ * board). -+ */ -+#if !defined(PVR_OMAPLFB_DONT_USE_FB_PAN_DISPLAY) -+ /* -+ * Attempt to change the virtual screen resolution if it is too -+ * small. Note that fb_set_var also pans the display. -+ */ -+ if (sFBVar.xres_virtual != sFBVar.xres || sFBVar.yres_virtual < ulYResVirtual) -+#endif /* !defined(PVR_OMAPLFB_DONT_USE_FB_PAN_DISPLAY) */ -+ { -+ sFBVar.xres_virtual = sFBVar.xres; -+ sFBVar.yres_virtual = ulYResVirtual; -+ -+ sFBVar.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE; -+ -+ res = fb_set_var(psDevInfo->psLINFBInfo, &sFBVar); -+ if (res != 0) -+ { -+ printk(KERN_ERR DRIVER_PREFIX ": %s: Device %u: fb_set_var failed (Y Offset: %lu, Error: %d)\n", __FUNCTION__, psDevInfo->uiFBDevID, psBuffer->ulYOffset, res); -+ } -+ } -+#if !defined(PVR_OMAPLFB_DONT_USE_FB_PAN_DISPLAY) -+ else -+ { -+ res = fb_pan_display(psDevInfo->psLINFBInfo, &sFBVar); -+ if (res != 0) -+ { -+ printk(KERN_ERR DRIVER_PREFIX ": %s: Device %u: fb_pan_display failed (Y Offset: %lu, Error: %d)\n", __FUNCTION__, psDevInfo->uiFBDevID, psBuffer->ulYOffset, res); -+ } -+ } -+#endif /* !defined(PVR_OMAPLFB_DONT_USE_FB_PAN_DISPLAY) */ -+ } -+#endif /* defined(CONFIG_DSSCOMP) */ -+ -+ OMAPLFB_CONSOLE_UNLOCK(); -+ unlock_fb_info(psDevInfo->psLINFBInfo); -+} -+ -+/* Newer kernels don't have any update mode capability */ -+ -+//#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) -+//#define PVR_OMAPLFB_HAS_UPDATE_MODE -+//#endif -+ -+//#if defined(PVR_OMAPLFB_HAS_UPDATE_MODE) -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0) -+#if !defined(PVR_OMAPLFB_DRM_FB) || defined(DEBUG) -+static OMAPLFB_BOOL OMAPLFBValidateDSSUpdateMode(enum omap_dss_update_mode eMode) -+{ -+ switch (eMode) -+ { -+ case OMAP_DSS_UPDATE_AUTO: -+ case OMAP_DSS_UPDATE_MANUAL: -+ case OMAP_DSS_UPDATE_DISABLED: -+ return OMAPLFB_TRUE; -+ default: -+ break; -+ } -+ -+ return OMAPLFB_FALSE; -+} -+ -+static OMAPLFB_UPDATE_MODE OMAPLFBFromDSSUpdateMode(enum omap_dss_update_mode eMode) -+{ -+ switch (eMode) -+ { -+ case OMAP_DSS_UPDATE_AUTO: -+ return OMAPLFB_UPDATE_MODE_AUTO; -+ case OMAP_DSS_UPDATE_MANUAL: -+ return OMAPLFB_UPDATE_MODE_MANUAL; -+ case OMAP_DSS_UPDATE_DISABLED: -+ return OMAPLFB_UPDATE_MODE_DISABLED; -+ default: -+ break; -+ } -+ -+ return OMAPLFB_UPDATE_MODE_UNDEFINED; -+} -+#endif -+ -+static OMAPLFB_BOOL OMAPLFBValidateUpdateMode(OMAPLFB_UPDATE_MODE eMode) -+{ -+ switch(eMode) -+ { -+ case OMAPLFB_UPDATE_MODE_AUTO: -+ case OMAPLFB_UPDATE_MODE_MANUAL: -+ case OMAPLFB_UPDATE_MODE_DISABLED: -+ return OMAPLFB_TRUE; -+ default: -+ break; -+ } -+ -+ return OMAPLFB_FALSE; -+} -+ -+static enum omap_dss_update_mode OMAPLFBToDSSUpdateMode(OMAPLFB_UPDATE_MODE eMode) -+{ -+ switch(eMode) -+ { -+ case OMAPLFB_UPDATE_MODE_AUTO: -+ return OMAP_DSS_UPDATE_AUTO; -+ case OMAPLFB_UPDATE_MODE_MANUAL: -+ return OMAP_DSS_UPDATE_MANUAL; -+ case OMAPLFB_UPDATE_MODE_DISABLED: -+ return OMAP_DSS_UPDATE_DISABLED; -+ default: -+ break; -+ } -+ -+ return -1; -+} -+#endif -+#if defined(DEBUG) -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0) -+static const char *OMAPLFBUpdateModeToString(OMAPLFB_UPDATE_MODE eMode) -+{ -+ switch(eMode) -+ { -+ case OMAPLFB_UPDATE_MODE_AUTO: -+ return "Auto Update Mode"; -+ case OMAPLFB_UPDATE_MODE_MANUAL: -+ return "Manual Update Mode"; -+ case OMAPLFB_UPDATE_MODE_DISABLED: -+ return "Update Mode Disabled"; -+ case OMAPLFB_UPDATE_MODE_UNDEFINED: -+ return "Update Mode Undefined"; -+ default: -+ break; -+ } -+ -+ return "Unknown Update Mode"; -+} -+ -+static const char *OMAPLFBDSSUpdateModeToString(enum omap_dss_update_mode eMode) -+{ -+ if (!OMAPLFBValidateDSSUpdateMode(eMode)) -+ { -+ return "Unknown Update Mode"; -+ } -+ -+ return OMAPLFBUpdateModeToString(OMAPLFBFromDSSUpdateMode(eMode)); -+} -+#endif -+#endif /* defined(DEBUG) */ -+ -+/* -+ * Get display update mode. -+ * If the mode is AUTO, we can wait for VSync, if desired. -+ */ -+OMAPLFB_UPDATE_MODE OMAPLFBGetUpdateMode(OMAPLFB_DEVINFO *psDevInfo) -+{ -+#if defined(PVR_OMAPLFB_DRM_FB) -+ struct drm_connector *psConnector; -+ OMAPLFB_UPDATE_MODE eMode = OMAPLFB_UPDATE_MODE_UNDEFINED; -+ -+ /* -+ * There may be multiple displays connected. If at least one -+ * display is manual update mode, report all screens as being -+ * in that mode. -+ */ -+ for (psConnector = NULL; -+ (psConnector = omap_fbdev_get_next_connector(psDevInfo->psLINFBInfo, psConnector)) != NULL;) -+ { -+ switch(omap_connector_get_update_mode(psConnector)) -+ { -+ case OMAP_DSS_UPDATE_MANUAL: -+ eMode = OMAPLFB_UPDATE_MODE_MANUAL; -+ break; -+ case OMAP_DSS_UPDATE_DISABLED: -+ if (eMode == OMAPLFB_UPDATE_MODE_UNDEFINED) -+ { -+ eMode = OMAPLFB_UPDATE_MODE_DISABLED; -+ } -+ break; -+ case OMAP_DSS_UPDATE_AUTO: -+ /* Fall through to default case */ -+ default: -+ /* Asssume auto update is possible */ -+ if (eMode != OMAPLFB_UPDATE_MODE_MANUAL) -+ { -+ eMode = OMAPLFB_UPDATE_MODE_AUTO; -+ } -+ break; -+ } -+ } -+ -+ return eMode; -+#else /* defined(PVR_OMAPLFB_DRM_FB) */ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0) -+ struct omap_dss_device *psDSSDev = fb2display(psDevInfo->psLINFBInfo); -+ OMAP_DSS_DRIVER(psDSSDrv, psDSSDev); -+ -+ enum omap_dss_update_mode eMode; -+ -+ if (psDSSDrv == NULL) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: No DSS device\n", __FUNCTION__, psDevInfo->uiFBDevID)); -+ return OMAPLFB_UPDATE_MODE_UNDEFINED; -+ } -+ -+ if (psDSSDrv->get_update_mode == NULL) -+ { -+ if (strcmp(psDSSDev->name, "hdmi") == 0) -+ { -+ return OMAPLFB_UPDATE_MODE_AUTO; -+ } -+// DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: No get_update_mode function\n", __FUNCTION__, psDevInfo->uiFBDevID)); -+// return OMAPLFB_UPDATE_MODE_UNDEFINED; -+ return OMAPLFB_UPDATE_MODE_AUTO; -+ } -+ -+ eMode = psDSSDrv->get_update_mode(psDSSDev); -+ if (!OMAPLFBValidateDSSUpdateMode(eMode)) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Unknown update mode (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, (int)eMode)); -+ } -+ -+ return OMAPLFBFromDSSUpdateMode(eMode); -+#else -+ return OMAPLFB_UPDATE_MODE_AUTO; -+#endif -+#endif /* defined(PVR_OMAPLFB_DRM_FB) */ -+} -+ -+/* Set display update mode */ -+OMAPLFB_BOOL OMAPLFBSetUpdateMode(OMAPLFB_DEVINFO *psDevInfo, OMAPLFB_UPDATE_MODE eMode) -+{ -+#if defined(PVR_OMAPLFB_DRM_FB) -+ struct drm_connector *psConnector; -+ enum omap_dss_update_mode eDSSMode; -+ OMAPLFB_BOOL bSuccess = OMAPLFB_FALSE; -+ OMAPLFB_BOOL bFailure = OMAPLFB_FALSE; -+ -+ if (!OMAPLFBValidateUpdateMode(eMode)) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Unknown update mode (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, (int)eMode)); -+ return OMAPLFB_FALSE; -+ } -+ eDSSMode = OMAPLFBToDSSUpdateMode(eMode); -+ -+ for (psConnector = NULL; -+ (psConnector = omap_fbdev_get_next_connector(psDevInfo->psLINFBInfo, psConnector)) != NULL;) -+ { -+ int iRes = omap_connector_set_update_mode(psConnector, eDSSMode); -+ OMAPLFB_BOOL bRes = (iRes == 0); -+ -+ -+ bSuccess |= bRes; -+ bFailure |= !bRes; -+ } -+ -+ if (!bFailure) -+ { -+ if (!bSuccess) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: No screens\n", __FUNCTION__, psDevInfo->uiFBDevID)); -+ } -+ -+ return OMAPLFB_TRUE; -+ } -+ -+ if (!bSuccess) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Couldn't set %s for any screen\n", __FUNCTION__, psDevInfo->uiFBDevID, OMAPLFBUpdateModeToString(eMode))); -+ return OMAPLFB_FALSE; -+ } -+ -+ if (eMode == OMAPLFB_UPDATE_MODE_AUTO) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Couldn't set %s for all screens\n", __FUNCTION__, psDevInfo->uiFBDevID, OMAPLFBUpdateModeToString(eMode))); -+ return OMAPLFB_FALSE; -+ } -+ -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": %s: Device %u: %s set for some screens\n", __FUNCTION__, psDevInfo->uiFBDevID, OMAPLFBUpdateModeToString(eMode))); -+ -+ return OMAPLFB_TRUE; -+#else /* defined(PVR_OMAPLFB_DRM_FB) */ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0) -+ struct omap_dss_device *psDSSDev = fb2display(psDevInfo->psLINFBInfo); -+ OMAP_DSS_DRIVER(psDSSDrv, psDSSDev); -+ enum omap_dss_update_mode eDSSMode; -+ int res; -+ -+ if (psDSSDrv == NULL || psDSSDrv->set_update_mode == NULL) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Can't set update mode\n", __FUNCTION__, psDevInfo->uiFBDevID)); -+ return OMAPLFB_FALSE; -+ } -+ -+ if (!OMAPLFBValidateUpdateMode(eMode)) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Unknown update mode (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, (int)eMode)); -+ return OMAPLFB_FALSE; -+ } -+ eDSSMode = OMAPLFBToDSSUpdateMode(eMode); -+ -+ res = psDSSDrv->set_update_mode(psDSSDev, eDSSMode); -+ if (res != 0) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: set_update_mode (%s) failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, OMAPLFBDSSUpdateModeToString(eDSSMode), res)); -+ } -+ -+ return (res == 0); -+#else -+return 1; -+#endif -+#endif /* defined(PVR_OMAPLFB_DRM_FB) */ -+ -+} -+//#else /* defined(PVR_OMAPLFB_HAS_UPDATE_MODE) */ -+ -+//OMAPLFB_UPDATE_MODE OMAPLFBGetUpdateMode(OMAPLFB_DEVINFO *psDevInfo) -+//{ -+// return OMAPLFB_UPDATE_MODE_UNDEFINED; -+//} -+ -+//#endif /* defined(PVR_OMAPLFB_HAS_UPDATE_MODE) */ -+ -+#if defined(DEBUG) -+void OMAPLFBPrintInfo(OMAPLFB_DEVINFO *psDevInfo) -+{ -+#if defined(PVR_OMAPLFB_DRM_FB) -+ struct drm_connector *psConnector; -+ unsigned uConnectors; -+ unsigned uConnector; -+ -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": Device %u: DRM framebuffer\n", psDevInfo->uiFBDevID)); -+ -+ for (psConnector = NULL, uConnectors = 0; -+ (psConnector = omap_fbdev_get_next_connector(psDevInfo->psLINFBInfo, psConnector)) != NULL;) -+ { -+ uConnectors++; -+ } -+ -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": Device %u: Number of screens (DRM connectors): %u\n", psDevInfo->uiFBDevID, uConnectors)); -+ -+ if (uConnectors == 0) -+ { -+ return; -+ } -+ -+ for (psConnector = NULL, uConnector = 0; -+ (psConnector = omap_fbdev_get_next_connector(psDevInfo->psLINFBInfo, psConnector)) != NULL; uConnector++) -+ { -+ enum omap_dss_update_mode eMode = omap_connector_get_update_mode(psConnector); -+ -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": Device %u: Screen %u: %s (%d)\n", psDevInfo->uiFBDevID, uConnector, OMAPLFBDSSUpdateModeToString(eMode), (int)eMode)); -+ -+ } -+#else /* defined(PVR_OMAPLFB_DRM_FB) */ -+//#if defined(PVR_OMAPLFB_HAS_UPDATE_MODE) -+ OMAPLFB_UPDATE_MODE eMode = OMAPLFBGetUpdateMode(psDevInfo); -+ -+ //DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": Device %u: %s\n", psDevInfo->uiFBDevID, OMAPLFBUpdateModeToString(eMode))); -+//#endif -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": Device %u: non-DRM framebuffer\n", psDevInfo->uiFBDevID)); -+ -+#endif /* defined(PVR_OMAPLFB_DRM_FB) */ -+} -+#endif /* defined(DEBUG) */ -+ -+/* Wait for VSync */ -+OMAPLFB_BOOL OMAPLFBWaitForVSync(OMAPLFB_DEVINFO *psDevInfo) -+{ -+#if defined(PVR_OMAPLFB_DRM_FB) -+ struct drm_connector *psConnector; -+ -+ for (psConnector = NULL; -+ (psConnector = omap_fbdev_get_next_connector(psDevInfo->psLINFBInfo, psConnector)) != NULL;) -+ { -+ (void) omap_encoder_wait_for_vsync(psConnector->encoder); -+ } -+ -+ return OMAPLFB_TRUE; -+#else /* defined(PVR_OMAPLFB_DRM_FB) */ -+#if FBDEV_PRESENT -+ struct omapfb_info *ofbi = FB2OFB(psDevInfo->psLINFBInfo); -+ struct omapfb2_device *psDSSDev = ofbi->fbdev; -+ OMAP_DSS_MANAGER(psDSSMan, psDSSDev); -+ -+ if (psDSSMan != NULL && WAIT_FOR_VSYNC(psDSSMan) != NULL) -+ { -+ int res = WAIT_FOR_VSYNC(psDSSMan)(psDSSMan); -+ if (res != 0) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Wait for vsync failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, res)); -+ return OMAPLFB_FALSE; -+ } -+ } -+#endif -+ return OMAPLFB_TRUE; -+#endif /* defined(PVR_OMAPLFB_DRM_FB) */ -+} -+ -+/* -+ * Wait for screen to update. If the screen is in manual or auto update -+ * mode, we can call this function to wait for the screen to update. -+ */ -+OMAPLFB_BOOL OMAPLFBManualSync(OMAPLFB_DEVINFO *psDevInfo) -+{ -+#if defined(PVR_OMAPLFB_DRM_FB) -+ struct drm_connector *psConnector; -+ -+ for (psConnector = NULL; -+ (psConnector = omap_fbdev_get_next_connector(psDevInfo->psLINFBInfo, psConnector)) != NULL; ) -+ { -+ /* Try manual sync first, then try wait for vsync */ -+ if (omap_connector_sync(psConnector) != 0) -+ { -+ (void) omap_encoder_wait_for_vsync(psConnector->encoder); -+ } -+ } -+ -+ return OMAPLFB_TRUE; -+#else /* defined(PVR_OMAPLFB_DRM_FB) */ -+ -+#if 0 -+ struct omap_dss_device *psDSSDev = fb2display(psDevInfo->psLINFBInfo); -+ OMAP_DSS_DRIVER(psDSSDrv, psDSSDev); -+ -+ if (psDSSDrv != NULL && psDSSDrv->sync != NULL) -+ { -+ int res = psDSSDrv->sync(psDSSDev); -+ if (res != 0) -+ { -+ printk(KERN_ERR DRIVER_PREFIX ": %s: Device %u: Sync failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, res); -+ return OMAPLFB_FALSE; -+ } -+ } -+#endif -+ return OMAPLFB_TRUE; -+#endif /* defined(PVR_OMAPLFB_DRM_FB) */ -+} -+ -+/* -+ * If the screen is manual or auto update mode, wait for the screen to -+ * update. -+ */ -+OMAPLFB_BOOL OMAPLFBCheckModeAndSync(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ OMAPLFB_UPDATE_MODE eMode = OMAPLFBGetUpdateMode(psDevInfo); -+ -+ switch(eMode) -+ { -+ case OMAPLFB_UPDATE_MODE_AUTO: -+ case OMAPLFB_UPDATE_MODE_MANUAL: -+ return OMAPLFBManualSync(psDevInfo); -+ default: -+ break; -+ } -+ -+ return OMAPLFB_TRUE; -+} -+ -+/* Linux Framebuffer event notification handler */ -+static int OMAPLFBFrameBufferEvents(struct notifier_block *psNotif, -+ unsigned long event, void *data) -+{ -+ OMAPLFB_DEVINFO *psDevInfo; -+ struct fb_event *psFBEvent = (struct fb_event *)data; -+ struct fb_info *psFBInfo = psFBEvent->info; -+ OMAPLFB_BOOL bBlanked; -+ -+ /* Only interested in blanking events */ -+ if (event != FB_EVENT_BLANK) -+ { -+ return 0; -+ } -+ -+ bBlanked = (*(IMG_INT *)psFBEvent->data != 0) ? OMAPLFB_TRUE: OMAPLFB_FALSE; -+ -+ psDevInfo = OMAPLFBGetDevInfoPtr(psFBInfo->node); -+ -+#if 0 -+ if (psDevInfo != NULL) -+ { -+ if (bBlanked) -+ { -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": %s: Device %u: Blank event received\n", __FUNCTION__, psDevInfo->uiFBDevID)); -+ } -+ else -+ { -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": %s: Device %u: Unblank event received\n", __FUNCTION__, psDevInfo->uiFBDevID)); -+ } -+ } -+ else -+ { -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": %s: Device %u: Blank/Unblank event for unknown framebuffer\n", __FUNCTION__, psFBInfo->node)); -+ } -+#endif -+ -+ if (psDevInfo != NULL) -+ { -+ OMAPLFBAtomicBoolSet(&psDevInfo->sBlanked, bBlanked); -+ OMAPLFBAtomicIntInc(&psDevInfo->sBlankEvents); -+ } -+ -+ return 0; -+} -+ -+/* Unblank the screen */ -+/* -+ * Blank or Unblank the screen. To be called where the unblank is being done -+ * in user context. -+ */ -+static OMAPLFB_ERROR OMAPLFBBlankOrUnblankDisplay(OMAPLFB_DEVINFO *psDevInfo, IMG_BOOL bBlank) -+{ -+#ifdef FBDEV_PRESENT -+ int res; -+ if (!lock_fb_info(psDevInfo->psLINFBInfo)) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ ": %s: Device %u: Couldn't lock FB info\n", __FUNCTION__, psDevInfo->uiFBDevID); -+ return (OMAPLFB_ERROR_GENERIC); -+ } -+ -+ /* -+ * FBINFO_MISC_USEREVENT is set to avoid a deadlock resulting from -+ * fb_blank being called recursively due from within the fb_blank event -+ * notification. -+ */ -+ -+ OMAPLFB_CONSOLE_LOCK(); -+ psDevInfo->psLINFBInfo->flags |= FBINFO_MISC_USEREVENT; -+ res = fb_blank(psDevInfo->psLINFBInfo, bBlank ? 1 : 0); -+ psDevInfo->psLINFBInfo->flags &= ~FBINFO_MISC_USEREVENT; -+ -+ OMAPLFB_CONSOLE_UNLOCK(); -+ unlock_fb_info(psDevInfo->psLINFBInfo); -+ if (res != 0 && res != -EINVAL) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ ": %s: Device %u: fb_blank failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, res); -+ return (OMAPLFB_ERROR_GENERIC); -+ } -+#endif -+ return (OMAPLFB_OK); -+} -+ -+/* Unblank the screen */ -+OMAPLFB_ERROR OMAPLFBUnblankDisplay(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ return OMAPLFBBlankOrUnblankDisplay(psDevInfo, IMG_FALSE); -+} -+ -+ -+ -+#ifdef CONFIG_HAS_EARLYSUSPEND -+static void OMAPLFBEarlyUnblankDisplay(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ OMAPLFB_CONSOLE_LOCK(); -+ fb_blank(psDevInfo->psLINFBInfo, 0); -+ OMAPLFB_CONSOLE_UNLOCK(); -+} -+ -+/* Blank the screen */ -+static void OMAPLFBEarlyBlankDisplay(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ OMAPLFB_CONSOLE_LOCK(); -+ fb_blank(psDevInfo->psLINFBInfo, 1); -+ OMAPLFB_CONSOLE_UNLOCK(); -+} -+ -+static void OMAPLFBEarlySuspendHandler(struct early_suspend *h) -+{ -+ unsigned uiMaxFBDevIDPlusOne = OMAPLFBMaxFBDevIDPlusOne(); -+ unsigned i; -+ -+ for (i=0; i < uiMaxFBDevIDPlusOne; i++) -+ { -+ OMAPLFB_DEVINFO *psDevInfo = OMAPLFBGetDevInfoPtr(i); -+ -+ if (psDevInfo != NULL) -+ { -+ OMAPLFBAtomicBoolSet(&psDevInfo->sEarlySuspendFlag, OMAPLFB_TRUE); -+ OMAPLFBEarlyBlankDisplay(psDevInfo); -+ } -+ } -+} -+ -+static void OMAPLFBEarlyResumeHandler(struct early_suspend *h) -+{ -+ unsigned uiMaxFBDevIDPlusOne = OMAPLFBMaxFBDevIDPlusOne(); -+ unsigned i; -+ -+ for (i=0; i < uiMaxFBDevIDPlusOne; i++) -+ { -+ OMAPLFB_DEVINFO *psDevInfo = OMAPLFBGetDevInfoPtr(i); -+ -+ if (psDevInfo != NULL) -+ { -+ OMAPLFBEarlyUnblankDisplay(psDevInfo); -+ OMAPLFBAtomicBoolSet(&psDevInfo->sEarlySuspendFlag, OMAPLFB_FALSE); -+ } -+ } -+} -+ -+#endif /* CONFIG_HAS_EARLYSUSPEND */ -+ -+/* Set up Linux Framebuffer event notification */ -+OMAPLFB_ERROR OMAPLFBEnableLFBEventNotification(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ int res; -+ OMAPLFB_ERROR eError; -+ -+ /* Set up Linux Framebuffer event notification */ -+ memset(&psDevInfo->sLINNotifBlock, 0, sizeof(psDevInfo->sLINNotifBlock)); -+ -+ psDevInfo->sLINNotifBlock.notifier_call = OMAPLFBFrameBufferEvents; -+ -+ OMAPLFBAtomicBoolSet(&psDevInfo->sBlanked, OMAPLFB_FALSE); -+ OMAPLFBAtomicIntSet(&psDevInfo->sBlankEvents, 0); -+ -+ res = fb_register_client(&psDevInfo->sLINNotifBlock); -+ if (res != 0) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ ": %s: Device %u: fb_register_client failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, res); -+ -+ return (OMAPLFB_ERROR_GENERIC); -+ } -+ -+ eError = OMAPLFBUnblankDisplay(psDevInfo); -+ if (eError != OMAPLFB_OK) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ ": %s: Device %u: UnblankDisplay failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, eError); -+ return eError; -+ } -+ -+#ifdef CONFIG_HAS_EARLYSUSPEND -+ psDevInfo->sEarlySuspend.suspend = OMAPLFBEarlySuspendHandler; -+ psDevInfo->sEarlySuspend.resume = OMAPLFBEarlyResumeHandler; -+ psDevInfo->sEarlySuspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB + 1; -+ register_early_suspend(&psDevInfo->sEarlySuspend); -+#endif -+ -+ return (OMAPLFB_OK); -+} -+ -+/* Disable Linux Framebuffer event notification */ -+OMAPLFB_ERROR OMAPLFBDisableLFBEventNotification(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ int res; -+ -+#ifdef CONFIG_HAS_EARLYSUSPEND -+ unregister_early_suspend(&psDevInfo->sEarlySuspend); -+#endif -+ -+ /* Unregister for Framebuffer events */ -+ res = fb_unregister_client(&psDevInfo->sLINNotifBlock); -+ if (res != 0) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ ": %s: Device %u: fb_unregister_client failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, res); -+ return (OMAPLFB_ERROR_GENERIC); -+ } -+ -+ OMAPLFBAtomicBoolSet(&psDevInfo->sBlanked, OMAPLFB_FALSE); -+ -+ return (OMAPLFB_OK); -+} -+ -+#if defined(SUPPORT_DRI_DRM) && defined(PVR_DISPLAY_CONTROLLER_DRM_IOCTL) -+static OMAPLFB_DEVINFO *OMAPLFBPVRDevIDToDevInfo(unsigned uiPVRDevID) -+{ -+ unsigned uiMaxFBDevIDPlusOne = OMAPLFBMaxFBDevIDPlusOne(); -+ unsigned i; -+ -+ for (i=0; i < uiMaxFBDevIDPlusOne; i++) -+ { -+ OMAPLFB_DEVINFO *psDevInfo = OMAPLFBGetDevInfoPtr(i); -+ -+ if (psDevInfo->uiPVRDevID == uiPVRDevID) -+ { -+ return psDevInfo; -+ } -+ } -+ -+ printk(KERN_ERR DRIVER_PREFIX -+ ": %s: PVR Device %u: Couldn't find device\n", __FUNCTION__, uiPVRDevID); -+ -+ return NULL; -+} -+ -+int PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Ioctl)(struct drm_device unref__ *dev, void *arg, struct drm_file unref__ *pFile) -+{ -+ uint32_t *puiArgs; -+ uint32_t uiCmd; -+ unsigned uiPVRDevID; -+ int ret = 0; -+ OMAPLFB_DEVINFO *psDevInfo; -+ -+ if (arg == NULL) -+ { -+ return -EFAULT; -+ } -+ -+ puiArgs = (uint32_t *)arg; -+ uiCmd = puiArgs[PVR_DRM_DISP_ARG_CMD]; -+ uiPVRDevID = puiArgs[PVR_DRM_DISP_ARG_DEV]; -+ -+ psDevInfo = OMAPLFBPVRDevIDToDevInfo(uiPVRDevID); -+ if (psDevInfo == NULL) -+ { -+ return -EINVAL; -+ } -+ -+ -+ switch (uiCmd) -+ { -+ case PVR_DRM_DISP_CMD_LEAVE_VT: -+ case PVR_DRM_DISP_CMD_ENTER_VT: -+ { -+ OMAPLFB_BOOL bLeaveVT = (uiCmd == PVR_DRM_DISP_CMD_LEAVE_VT); -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: PVR Device %u: %s\n", -+ __FUNCTION__, uiPVRDevID, -+ bLeaveVT ? "Leave VT" : "Enter VT")); -+ -+ OMAPLFBCreateSwapChainLock(psDevInfo); -+ -+ OMAPLFBAtomicBoolSet(&psDevInfo->sLeaveVT, bLeaveVT); -+ if (psDevInfo->psSwapChain != NULL) -+ { -+ flush_workqueue(psDevInfo->psSwapChain->psWorkQueue); -+ -+ if (bLeaveVT) -+ { -+ OMAPLFBFlip(psDevInfo, &psDevInfo->sSystemBuffer); -+ (void) OMAPLFBCheckModeAndSync(psDevInfo); -+ } -+ } -+ -+ OMAPLFBCreateSwapChainUnLock(psDevInfo); -+ (void) OMAPLFBUnblankDisplay(psDevInfo); -+ break; -+ } -+ case PVR_DRM_DISP_CMD_ON: -+ case PVR_DRM_DISP_CMD_STANDBY: -+ case PVR_DRM_DISP_CMD_SUSPEND: -+ case PVR_DRM_DISP_CMD_OFF: -+ { -+ int iFBMode; -+#if defined(DEBUG) -+ { -+ const char *pszMode; -+ switch(uiCmd) -+ { -+ case PVR_DRM_DISP_CMD_ON: -+ pszMode = "On"; -+ break; -+ case PVR_DRM_DISP_CMD_STANDBY: -+ pszMode = "Standby"; -+ break; -+ case PVR_DRM_DISP_CMD_SUSPEND: -+ pszMode = "Suspend"; -+ break; -+ case PVR_DRM_DISP_CMD_OFF: -+ pszMode = "Off"; -+ break; -+ default: -+ pszMode = "(Unknown Mode)"; -+ break; -+ } -+ printk(KERN_WARNING DRIVER_PREFIX ": %s: PVR Device %u: Display %s\n", -+ __FUNCTION__, uiPVRDevID, pszMode); -+ } -+#endif -+ switch(uiCmd) -+ { -+ case PVR_DRM_DISP_CMD_ON: -+ iFBMode = FB_BLANK_UNBLANK; -+ break; -+ case PVR_DRM_DISP_CMD_STANDBY: -+ iFBMode = FB_BLANK_HSYNC_SUSPEND; -+ break; -+ case PVR_DRM_DISP_CMD_SUSPEND: -+ iFBMode = FB_BLANK_VSYNC_SUSPEND; -+ break; -+ case PVR_DRM_DISP_CMD_OFF: -+ iFBMode = FB_BLANK_POWERDOWN; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ OMAPLFBCreateSwapChainLock(psDevInfo); -+ -+ if (psDevInfo->psSwapChain != NULL) -+ { -+ flush_workqueue(psDevInfo->psSwapChain->psWorkQueue); -+ } -+ -+ if (!lock_fb_info(psDevInfo->psLINFBInfo)) -+ { -+ ret = -ENODEV; -+ } -+ else -+ { -+ OMAPLFB_CONSOLE_LOCK(); -+ psDevInfo->psLINFBInfo->flags |= FBINFO_MISC_USEREVENT; -+ ret = fb_blank(psDevInfo->psLINFBInfo, iFBMode); -+ psDevInfo->psLINFBInfo->flags &= ~FBINFO_MISC_USEREVENT; -+ OMAPLFB_CONSOLE_UNLOCK(); -+ unlock_fb_info(psDevInfo->psLINFBInfo); -+ } -+ -+ OMAPLFBCreateSwapChainUnLock(psDevInfo); -+ -+ break; -+ } -+ default: -+ { -+ ret = -EINVAL; -+ break; -+ } -+ } -+ -+ return ret; -+} -+#endif -+ -+/* Insert the driver into the kernel */ -+#if defined(SUPPORT_DRI_DRM) -+int PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Init)(struct drm_device unref__ *dev) -+#else -+static int __init OMAPLFB_Init(void) -+#endif -+{ -+ -+ if(OMAPLFBInit() != OMAPLFB_OK) -+ { -+ printk(KERN_ERR DRIVER_PREFIX ": %s: OMAPLFBInit failed\n", __FUNCTION__); -+ return -ENODEV; -+ } -+ -+ return 0; -+ -+} -+ -+/* Remove the driver from the kernel */ -+#if defined(SUPPORT_DRI_DRM) -+void PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Cleanup)(struct drm_device unref__ *dev) -+#else -+static void __exit OMAPLFB_Cleanup(void) -+#endif -+{ -+ if(OMAPLFBDeInit() != OMAPLFB_OK) -+ { -+ printk(KERN_ERR DRIVER_PREFIX ": %s: OMAPLFBDeInit failed\n", __FUNCTION__); -+ } -+} -+ -+#if !defined(SUPPORT_DRI_DRM) -+/* -+ These macro calls define the initialisation and removal functions of the -+ driver. Although they are prefixed `module_', they apply when compiling -+ statically as well; in both cases they define the function the kernel will -+ run to start/stop the driver. -+*/ -+late_initcall(OMAPLFB_Init); -+module_exit(OMAPLFB_Cleanup); -+#endif -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti81xx_linux/3rdparty_dc_drm_shared.h b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti81xx_linux/3rdparty_dc_drm_shared.h -new file mode 100644 -index 0000000..3aebfaf ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti81xx_linux/3rdparty_dc_drm_shared.h -@@ -0,0 +1,65 @@ -+/*************************************************************************/ /*! -+@Title OMAP Linux display driver shared DRM structures -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description OMAP Linux display driver DRM structures shared between -+ kernel and user space. -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+ -+*/ /**************************************************************************/ -+#ifndef __3RDPARTY_DC_DRM_SHARED_H__ -+#define __3RDPARTY_DC_DRM_SHARED_H__ -+#if defined(SUPPORT_DRI_DRM) -+ -+#define PVR_DRM_DISP_CMD_ENTER_VT 1 -+#define PVR_DRM_DISP_CMD_LEAVE_VT 2 -+ -+#define PVR_DRM_DISP_CMD_ON 3 -+#define PVR_DRM_DISP_CMD_STANDBY 4 -+#define PVR_DRM_DISP_CMD_SUSPEND 5 -+#define PVR_DRM_DISP_CMD_OFF 6 -+ -+#define PVR_DRM_DISP_ARG_CMD 0 -+#define PVR_DRM_DISP_ARG_DEV 1 -+#define PVR_DRM_DISP_NUM_ARGS 2 -+ -+#endif /* defined(SUPPORT_DRI_DRM) */ -+#endif /* __3RDPARTY_DC_DRM_SHARED_H__ */ -+ -+/****************************************************************************** -+ End of file (3rdparty_dc_drm_shared.h) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti81xx_linux/Kbuild b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti81xx_linux/Kbuild -new file mode 100644 -index 0000000..1ae23593 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti81xx_linux/Kbuild -@@ -0,0 +1,32 @@ -+SYS_USING_INTERRUPTS = 1 -+SUPPORT_OMAP3430_OMAPFB3 =1 -+SUPPORT_TI_DSS_FW = 0 -+PVR_LINUX_USING_WORKQUEUES = 1 -+ -+SYS_CFLAGS.$(SYS_USING_INTERRUPTS) += -DSYS_USING_INTERRUPTS -+SYS_CFLAGS.$(SUPPORT_OMAP3430_OMAPFB3) += -DSUPPORT_OMAP3430_OMAPFB3 -+SYS_CFLAGS.$(SUPPORT_TI_DSS_FW) += -DSUPPORT_TI_DSS_FW -+SYS_CFLAGS.$(PVR_LINUX_USING_WORKQUEUES) += -DPVR_LINUX_USING_WORKQUEUES -+SYS_CFLAGS += -DDISPLAY_CONTROLLER=omaplfb -+ -+EXTRA_CFLAGS = -DLINUX \ -+ -DCONFIG_OMAP2_DSS \ -+ -I$(PVR_BUILD_DIR)/include4 \ -+ -I$(PVR_BUILD_DIR)/services4/include \ -+ -I$(PVR_BUILD_DIR)/services4/system/$(PVR_SYSTEM) \ -+ -I$(KERNELDIR)/drivers/video/omap2 \ -+ -I$(PVR_BUILD_DIR)/services4/system/include \ -+ $(SYS_CFLAGS.1) \ -+ -+ifneq ($(FBDEV),no) -+EXTRA_CFLAGS += -DFBDEV_PRESENT -+endif -+ -+ifeq ($(SUPPORT_XORG),1) -+EXTRA_CFLAGS += -DSUPPORT_DRI_DRM -+EXTRA_CFLAGS += -DPVR_DISPLAY_CONTROLLER_DRM_IOCTL -+endif -+ -+ -+obj-m := omaplfb.o -+omaplfb-y := omaplfb_displayclass.o omaplfb_linux.o -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti81xx_linux/Kbuild.mk b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti81xx_linux/Kbuild.mk -new file mode 100644 -index 0000000..e8a99c3 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti81xx_linux/Kbuild.mk -@@ -0,0 +1,49 @@ -+########################################################################### ### -+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+#@License Dual MIT/GPLv2 -+# -+# The contents of this file are subject to the MIT license as set out below. -+# -+# Permission is hereby granted, free of charge, to any person obtaining a copy -+# of this software and associated documentation files (the "Software"), to deal -+# in the Software without restriction, including without limitation the rights -+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+# copies of the Software, and to permit persons to whom the Software is -+# furnished to do so, subject to the following conditions: -+# -+# The above copyright notice and this permission notice shall be included in -+# all copies or substantial portions of the Software. -+# -+# Alternatively, the contents of this file may be used under the terms of -+# the GNU General Public License Version 2 ("GPL") in which case the provisions -+# of GPL are applicable instead of those above. -+# -+# If you wish to allow use of your version of this file only under the terms of -+# GPL, and not to allow others to use your version of this file under the terms -+# of the MIT license, indicate your decision by deleting the provisions above -+# and replace them with the notice and other provisions required by GPL as set -+# out in the file called "GPL-COPYING" included in this distribution. If you do -+# not delete the provisions above, a recipient may use your version of this file -+# under the terms of either the MIT license or GPL. -+# -+# This License is also included in this distribution in the file called -+# "MIT-COPYING". -+# -+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+# -+### ########################################################################### -+ -+ccflags-y += \ -+ -I$(TOP)/services4/3rdparty/dc_omapfb3_linux \ -+ -I$(KERNELDIR)/drivers/video/omap2 \ -+ -I$(KERNELDIR)/arch/arm/plat-omap/include -+ -+omaplfb-y += \ -+ services4/3rdparty/dc_omapfb3_linux/omaplfb_displayclass.o \ -+ services4/3rdparty/dc_omapfb3_linux/omaplfb_linux.o -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti81xx_linux/Linux.mk b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti81xx_linux/Linux.mk -new file mode 100644 -index 0000000..612b422 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti81xx_linux/Linux.mk -@@ -0,0 +1,46 @@ -+########################################################################### ### -+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+#@License Dual MIT/GPLv2 -+# -+# The contents of this file are subject to the MIT license as set out below. -+# -+# Permission is hereby granted, free of charge, to any person obtaining a copy -+# of this software and associated documentation files (the "Software"), to deal -+# in the Software without restriction, including without limitation the rights -+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+# copies of the Software, and to permit persons to whom the Software is -+# furnished to do so, subject to the following conditions: -+# -+# The above copyright notice and this permission notice shall be included in -+# all copies or substantial portions of the Software. -+# -+# Alternatively, the contents of this file may be used under the terms of -+# the GNU General Public License Version 2 ("GPL") in which case the provisions -+# of GPL are applicable instead of those above. -+# -+# If you wish to allow use of your version of this file only under the terms of -+# GPL, and not to allow others to use your version of this file under the terms -+# of the MIT license, indicate your decision by deleting the provisions above -+# and replace them with the notice and other provisions required by GPL as set -+# out in the file called "GPL-COPYING" included in this distribution. If you do -+# not delete the provisions above, a recipient may use your version of this file -+# under the terms of either the MIT license or GPL. -+# -+# This License is also included in this distribution in the file called -+# "MIT-COPYING". -+# -+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+# -+### ########################################################################### -+ -+modules := dc_omapfb3_linux -+ -+dc_omapfb3_linux_type := kernel_module -+dc_omapfb3_linux_target := omaplfb.ko -+dc_omapfb3_linux_makefile := $(THIS_DIR)/Kbuild.mk -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti81xx_linux/omaplfb.h b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti81xx_linux/omaplfb.h -new file mode 100644 -index 0000000..b7aed03 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti81xx_linux/omaplfb.h -@@ -0,0 +1,323 @@ -+/*************************************************************************/ /*! -+@Title OMAP Linux display driver structures and prototypes -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+ -+*/ /**************************************************************************/ -+#ifndef __OMAPLFB_H__ -+#define __OMAPLFB_H__ -+ -+#include <linux/version.h> -+ -+#include <asm/atomic.h> -+ -+#include <linux/kernel.h> -+#include <linux/console.h> -+#include <linux/fb.h> -+#include <linux/module.h> -+#include <linux/string.h> -+#include <linux/notifier.h> -+#include <linux/mutex.h> -+ -+#ifdef CONFIG_HAS_EARLYSUSPEND -+#include <linux/earlysuspend.h> -+#endif -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) -+#define OMAPLFB_CONSOLE_LOCK() console_lock() -+#define OMAPLFB_CONSOLE_UNLOCK() console_unlock() -+#else -+#define OMAPLFB_CONSOLE_LOCK() acquire_console_sem() -+#define OMAPLFB_CONSOLE_UNLOCK() release_console_sem() -+#endif -+ -+#define unref__ __attribute__ ((unused)) -+ -+typedef void * OMAPLFB_HANDLE; -+ -+typedef bool OMAPLFB_BOOL, *OMAPLFB_PBOOL; -+#define OMAPLFB_FALSE false -+#define OMAPLFB_TRUE true -+ -+typedef atomic_t OMAPLFB_ATOMIC_BOOL; -+ -+typedef atomic_t OMAPLFB_ATOMIC_INT; -+ -+/* OMAPLFB buffer structure */ -+typedef struct OMAPLFB_BUFFER_TAG -+{ -+ struct OMAPLFB_BUFFER_TAG *psNext; -+ struct OMAPLFB_DEVINFO_TAG *psDevInfo; -+ -+ struct work_struct sWork; -+ -+ /* Position of this buffer in the virtual framebuffer */ -+ unsigned long ulYOffset; -+ -+ /* IMG structures used, to minimise API function code */ -+ /* replace with own structures where necessary */ -+ IMG_SYS_PHYADDR sSysAddr; -+ IMG_CPU_VIRTADDR sCPUVAddr; -+ PVRSRV_SYNC_DATA *psSyncData; -+ -+ OMAPLFB_HANDLE hCmdComplete; -+ unsigned long ulSwapInterval; -+} OMAPLFB_BUFFER; -+ -+/* OMAPLFB swapchain structure */ -+typedef struct OMAPLFB_SWAPCHAIN_TAG -+{ -+ /* Swap chain ID */ -+ unsigned int uiSwapChainID; -+ -+ /* number of buffers in swapchain */ -+ unsigned long ulBufferCount; -+ -+ /* list of buffers in the swapchain */ -+ OMAPLFB_BUFFER *psBuffer; -+ -+ /* Swap chain work queue */ -+ struct workqueue_struct *psWorkQueue; -+ -+ /* -+ * Set if we didn't manage to wait for VSync on last swap, -+ * or if we think we need to wait for VSync on the next flip. -+ * The flag helps to avoid jitter when the screen is -+ * unblanked, by forcing an extended wait for VSync before -+ * attempting the next flip. -+ */ -+ OMAPLFB_BOOL bNotVSynced; -+ -+ /* Previous number of blank events */ -+ int iBlankEvents; -+ -+ /* Framebuffer Device ID for messages (e.g. printk) */ -+ unsigned int uiFBDevID; -+} OMAPLFB_SWAPCHAIN; -+ -+typedef struct OMAPLFB_FBINFO_TAG -+{ -+ unsigned long ulFBSize; -+ unsigned long ulBufferSize; -+ unsigned long ulRoundedBufferSize; -+ unsigned long ulWidth; -+ unsigned long ulHeight; -+ unsigned long ulByteStride; -+ unsigned long ulPhysicalWidthmm; -+ unsigned long ulPhysicalHeightmm; -+ -+ /* IMG structures used, to minimise API function code */ -+ /* replace with own structures where necessary */ -+ IMG_SYS_PHYADDR sSysAddr;//system physical address -+ IMG_CPU_VIRTADDR sCPUVAddr; -+ -+ /* pixelformat of system/primary surface */ -+ PVRSRV_PIXEL_FORMAT ePixelFormat; -+ -+#if defined(CONFIG_DSSCOMP) -+ OMAPLFB_BOOL bIs2D; -+ IMG_SYS_PHYADDR *psPageList; -+ struct ion_handle *psIONHandle; -+ IMG_UINT32 uiBytesPerPixel; -+#endif -+} OMAPLFB_FBINFO; -+ -+/* kernel device information structure */ -+typedef struct OMAPLFB_DEVINFO_TAG -+{ -+ /* Framebuffer Device ID */ -+ unsigned int uiFBDevID; -+ -+ /* PVR Device ID */ -+ unsigned int uiPVRDevID; -+ -+ /* Swapchain create/destroy mutex */ -+ struct mutex sCreateSwapChainMutex; -+ -+ /* system surface info */ -+ OMAPLFB_BUFFER sSystemBuffer; -+ -+ /* jump table into PVR services */ -+ PVRSRV_DC_DISP2SRV_KMJTABLE sPVRJTable; -+ -+ /* jump table into DC */ -+ PVRSRV_DC_SRV2DISP_KMJTABLE sDCJTable; -+ -+ /* fb info structure */ -+ OMAPLFB_FBINFO sFBInfo; -+ -+ /* Only one swapchain supported by this device so hang it here */ -+ OMAPLFB_SWAPCHAIN *psSwapChain; -+ -+ /* Swap chain ID */ -+ unsigned int uiSwapChainID; -+ -+ /* True if PVR Services is flushing its command queues */ -+ OMAPLFB_ATOMIC_BOOL sFlushCommands; -+ -+ /* pointer to linux frame buffer information structure */ -+ struct fb_info *psLINFBInfo; -+ -+ /* Linux Framebuffer event notification block */ -+ struct notifier_block sLINNotifBlock; -+ -+ /* IMG structures used, to minimise API function code */ -+ /* replace with own structures where necessary */ -+ -+ /* Address of the surface being displayed */ -+ IMG_DEV_VIRTADDR sDisplayDevVAddr; -+ -+ DISPLAY_INFO sDisplayInfo; -+ -+ /* Display format */ -+ DISPLAY_FORMAT sDisplayFormat; -+ -+ /* Display dimensions */ -+ DISPLAY_DIMS sDisplayDim; -+ -+ /* True if screen is blanked */ -+ OMAPLFB_ATOMIC_BOOL sBlanked; -+ -+ /* Number of blank/unblank events */ -+ OMAPLFB_ATOMIC_INT sBlankEvents; -+ -+#ifdef CONFIG_HAS_EARLYSUSPEND -+ /* Set by early suspend */ -+ OMAPLFB_ATOMIC_BOOL sEarlySuspendFlag; -+ -+ struct early_suspend sEarlySuspend; -+#endif -+ -+#if defined(SUPPORT_DRI_DRM) -+ OMAPLFB_ATOMIC_BOOL sLeaveVT; -+#endif -+ -+} OMAPLFB_DEVINFO; -+ -+#define OMAPLFB_PAGE_SIZE 4096 -+ -+/* DEBUG only printk */ -+#ifdef DEBUG -+#define DEBUG_PRINTK(x) printk x -+#else -+#define DEBUG_PRINTK(x) -+#endif -+ -+#define DISPLAY_DEVICE_NAME "PowerVR OMAP Linux Display Driver" -+#define DRVNAME "omaplfb" -+#define DEVNAME DRVNAME -+#define DRIVER_PREFIX DRVNAME -+ -+/*! -+ ***************************************************************************** -+ * Error values -+ *****************************************************************************/ -+typedef enum _OMAPLFB_ERROR_ -+{ -+ OMAPLFB_OK = 0, -+ OMAPLFB_ERROR_GENERIC = 1, -+ OMAPLFB_ERROR_OUT_OF_MEMORY = 2, -+ OMAPLFB_ERROR_TOO_FEW_BUFFERS = 3, -+ OMAPLFB_ERROR_INVALID_PARAMS = 4, -+ OMAPLFB_ERROR_INIT_FAILURE = 5, -+ OMAPLFB_ERROR_CANT_REGISTER_CALLBACK = 6, -+ OMAPLFB_ERROR_INVALID_DEVICE = 7, -+ OMAPLFB_ERROR_DEVICE_REGISTER_FAILED = 8, -+ OMAPLFB_ERROR_SET_UPDATE_MODE_FAILED = 9 -+} OMAPLFB_ERROR; -+ -+typedef enum _OMAPLFB_UPDATE_MODE_ -+{ -+ OMAPLFB_UPDATE_MODE_UNDEFINED = 0, -+ OMAPLFB_UPDATE_MODE_MANUAL = 1, -+ OMAPLFB_UPDATE_MODE_AUTO = 2, -+ OMAPLFB_UPDATE_MODE_DISABLED = 3 -+} OMAPLFB_UPDATE_MODE; -+ -+#ifndef UNREFERENCED_PARAMETER -+#define UNREFERENCED_PARAMETER(param) (param) = (param) -+#endif -+ -+OMAPLFB_ERROR OMAPLFBInit(void); -+OMAPLFB_ERROR OMAPLFBDeInit(void); -+ -+/* OS Specific APIs */ -+OMAPLFB_DEVINFO *OMAPLFBGetDevInfoPtr(unsigned uiFBDevID); -+unsigned OMAPLFBMaxFBDevIDPlusOne(void); -+void *OMAPLFBAllocKernelMem(unsigned long ulSize); -+void OMAPLFBFreeKernelMem(void *pvMem); -+OMAPLFB_ERROR OMAPLFBGetLibFuncAddr(char *szFunctionName, PFN_DC_GET_PVRJTABLE *ppfnFuncTable); -+OMAPLFB_ERROR OMAPLFBCreateSwapQueue (OMAPLFB_SWAPCHAIN *psSwapChain); -+void OMAPLFBDestroySwapQueue(OMAPLFB_SWAPCHAIN *psSwapChain); -+void OMAPLFBInitBufferForSwap(OMAPLFB_BUFFER *psBuffer); -+void OMAPLFBSwapHandler(OMAPLFB_BUFFER *psBuffer); -+void OMAPLFBQueueBufferForSwap(OMAPLFB_SWAPCHAIN *psSwapChain, OMAPLFB_BUFFER *psBuffer); -+void OMAPLFBFlip(OMAPLFB_DEVINFO *psDevInfo, OMAPLFB_BUFFER *psBuffer); -+OMAPLFB_UPDATE_MODE OMAPLFBGetUpdateMode(OMAPLFB_DEVINFO *psDevInfo); -+OMAPLFB_BOOL OMAPLFBSetUpdateMode(OMAPLFB_DEVINFO *psDevInfo, OMAPLFB_UPDATE_MODE eMode); -+OMAPLFB_BOOL OMAPLFBWaitForVSync(OMAPLFB_DEVINFO *psDevInfo); -+OMAPLFB_BOOL OMAPLFBManualSync(OMAPLFB_DEVINFO *psDevInfo); -+OMAPLFB_BOOL OMAPLFBCheckModeAndSync(OMAPLFB_DEVINFO *psDevInfo); -+OMAPLFB_ERROR OMAPLFBUnblankDisplay(OMAPLFB_DEVINFO *psDevInfo); -+OMAPLFB_ERROR OMAPLFBEnableLFBEventNotification(OMAPLFB_DEVINFO *psDevInfo); -+OMAPLFB_ERROR OMAPLFBDisableLFBEventNotification(OMAPLFB_DEVINFO *psDevInfo); -+void OMAPLFBCreateSwapChainLockInit(OMAPLFB_DEVINFO *psDevInfo); -+void OMAPLFBCreateSwapChainLockDeInit(OMAPLFB_DEVINFO *psDevInfo); -+void OMAPLFBCreateSwapChainLock(OMAPLFB_DEVINFO *psDevInfo); -+void OMAPLFBCreateSwapChainUnLock(OMAPLFB_DEVINFO *psDevInfo); -+void OMAPLFBAtomicBoolInit(OMAPLFB_ATOMIC_BOOL *psAtomic, OMAPLFB_BOOL bVal); -+void OMAPLFBAtomicBoolDeInit(OMAPLFB_ATOMIC_BOOL *psAtomic); -+void OMAPLFBAtomicBoolSet(OMAPLFB_ATOMIC_BOOL *psAtomic, OMAPLFB_BOOL bVal); -+OMAPLFB_BOOL OMAPLFBAtomicBoolRead(OMAPLFB_ATOMIC_BOOL *psAtomic); -+void OMAPLFBAtomicIntInit(OMAPLFB_ATOMIC_INT *psAtomic, int iVal); -+void OMAPLFBAtomicIntDeInit(OMAPLFB_ATOMIC_INT *psAtomic); -+void OMAPLFBAtomicIntSet(OMAPLFB_ATOMIC_INT *psAtomic, int iVal); -+int OMAPLFBAtomicIntRead(OMAPLFB_ATOMIC_INT *psAtomic); -+void OMAPLFBAtomicIntInc(OMAPLFB_ATOMIC_INT *psAtomic); -+ -+#if defined(DEBUG) -+void OMAPLFBPrintInfo(OMAPLFB_DEVINFO *psDevInfo); -+#else -+#define OMAPLFBPrintInfo(psDevInfo) -+#endif -+ -+#endif /* __OMAPLFB_H__ */ -+ -+/****************************************************************************** -+ End of file (omaplfb.h) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti81xx_linux/omaplfb_displayclass.c b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti81xx_linux/omaplfb_displayclass.c -new file mode 100644 -index 0000000..915bc3c ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti81xx_linux/omaplfb_displayclass.c -@@ -0,0 +1,1748 @@ -+/*************************************************************************/ /*! -+@Title OMAP common display driver components -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+ -+*/ /**************************************************************************/ -+ -+/************************************************************************** -+ The 3rd party driver is a specification of an API to integrate the IMG POWERVR -+ Services driver with 3rd Party display hardware. It is NOT a specification for -+ a display controller driver, rather a specification to extend the API for a -+ pre-existing driver for the display hardware. -+ -+ The 3rd party driver interface provides IMG POWERVR client drivers (e.g. PVR2D) -+ with an API abstraction of the system's underlying display hardware, allowing -+ the client drivers to indirectly control the display hardware and access its -+ associated memory. -+ -+ Functions of the API include -+ - query primary surface attributes (width, height, stride, pixel format, CPU -+ physical and virtual address) -+ - swap/flip chain creation and subsequent query of surface attributes -+ - asynchronous display surface flipping, taking account of asynchronous read -+ (flip) and write (render) operations to the display surface -+ -+ Note: having queried surface attributes the client drivers are able to map the -+ display memory to any IMG POWERVR Services device by calling -+ PVRSRVMapDeviceClassMemory with the display surface handle. -+ -+ This code is intended to be an example of how a pre-existing display driver may -+ be extended to support the 3rd Party Display interface to POWERVR Services -+ - IMG is not providing a display driver implementation. -+ **************************************************************************/ -+ -+/* -+ * OMAP Linux 3rd party display driver. -+ * This is based on the Generic PVR Linux Framebuffer 3rd party display -+ * driver, with OMAP specific extensions to support flipping. -+ */ -+ -+#include <linux/version.h> -+#include <linux/kernel.h> -+#include <linux/console.h> -+#include <linux/fb.h> -+#include <linux/module.h> -+#include <linux/string.h> -+#include <linux/notifier.h> -+ -+/* IMG services headers */ -+#include "img_defs.h" -+#include "servicesext.h" -+#include "kerneldisplay.h" -+#include "omaplfb.h" -+ -+#if defined(CONFIG_DSSCOMP) -+ -+#if !defined(CONFIG_ION_OMAP) -+#error CONFIG_DSSCOMP support requires CONFIG_ION_OMAP -+#endif -+ -+#include <linux/ion.h> -+#include <linux/omap_ion.h> -+ -+extern struct ion_client *gpsIONClient; -+ -+#include <mach/tiler.h> -+#include <video/dsscomp.h> -+#include <plat/dsscomp.h> -+ -+#endif /* defined(CONFIG_DSSCOMP) */ -+ -+#define OMAPLFB_COMMAND_COUNT 1 -+ -+#define OMAPLFB_VSYNC_SETTLE_COUNT 5 -+ -+//#define OMAPLFB_MAX_NUM_DEVICES FB_MAX -+#define OMAPLFB_MAX_NUM_DEVICES 1 -+#if (OMAPLFB_MAX_NUM_DEVICES > FB_MAX) -+#error "OMAPLFB_MAX_NUM_DEVICES must not be greater than FB_MAX" -+#endif -+ -+static OMAPLFB_DEVINFO *gapsDevInfo[OMAPLFB_MAX_NUM_DEVICES]; -+ -+/* Top level 'hook ptr' */ -+static PFN_DC_GET_PVRJTABLE gpfnGetPVRJTable = NULL; -+ -+/* Round x up to a multiple of y */ -+static inline unsigned long RoundUpToMultiple(unsigned long x, unsigned long y) -+{ -+ unsigned long div = x / y; -+ unsigned long rem = x % y; -+ -+ return (div + ((rem == 0) ? 0 : 1)) * y; -+} -+ -+/* Greatest common divisor of x and y */ -+static unsigned long GCD(unsigned long x, unsigned long y) -+{ -+ while (y != 0) -+ { -+ unsigned long r = x % y; -+ x = y; -+ y = r; -+ } -+ -+ return x; -+} -+ -+/* Least common multiple of x and y */ -+static unsigned long LCM(unsigned long x, unsigned long y) -+{ -+ unsigned long gcd = GCD(x, y); -+ -+ return (gcd == 0) ? 0 : ((x / gcd) * y); -+} -+ -+unsigned OMAPLFBMaxFBDevIDPlusOne(void) -+{ -+ return OMAPLFB_MAX_NUM_DEVICES; -+} -+ -+/* Returns DevInfo pointer for a given device */ -+OMAPLFB_DEVINFO *OMAPLFBGetDevInfoPtr(unsigned uiFBDevID) -+{ -+ WARN_ON(uiFBDevID >= OMAPLFBMaxFBDevIDPlusOne()); -+ -+ if (uiFBDevID >= OMAPLFB_MAX_NUM_DEVICES) -+ { -+ return NULL; -+ } -+ -+ return gapsDevInfo[uiFBDevID]; -+} -+ -+/* Sets the DevInfo pointer for a given device */ -+static inline void OMAPLFBSetDevInfoPtr(unsigned uiFBDevID, OMAPLFB_DEVINFO *psDevInfo) -+{ -+ WARN_ON(uiFBDevID >= OMAPLFB_MAX_NUM_DEVICES); -+ -+ if (uiFBDevID < OMAPLFB_MAX_NUM_DEVICES) -+ { -+ gapsDevInfo[uiFBDevID] = psDevInfo; -+ } -+} -+ -+static inline OMAPLFB_BOOL SwapChainHasChanged(OMAPLFB_DEVINFO *psDevInfo, OMAPLFB_SWAPCHAIN *psSwapChain) -+{ -+ return (psDevInfo->psSwapChain != psSwapChain) || -+ (psDevInfo->uiSwapChainID != psSwapChain->uiSwapChainID); -+} -+ -+/* Don't wait for vertical sync */ -+static inline OMAPLFB_BOOL DontWaitForVSync(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ OMAPLFB_BOOL bDontWait; -+ -+ bDontWait = OMAPLFBAtomicBoolRead(&psDevInfo->sBlanked) || -+ OMAPLFBAtomicBoolRead(&psDevInfo->sFlushCommands); -+ -+#if defined(CONFIG_HAS_EARLYSUSPEND) -+ bDontWait = bDontWait || OMAPLFBAtomicBoolRead(&psDevInfo->sEarlySuspendFlag); -+#endif -+#if defined(SUPPORT_DRI_DRM) -+ bDontWait = bDontWait || OMAPLFBAtomicBoolRead(&psDevInfo->sLeaveVT); -+#endif -+ return bDontWait; -+} -+ -+/* -+ * SetDCState -+ * Called from services. -+ */ -+static IMG_VOID SetDCState(IMG_HANDLE hDevice, IMG_UINT32 ui32State) -+{ -+ OMAPLFB_DEVINFO *psDevInfo = (OMAPLFB_DEVINFO *)hDevice; -+ -+ switch (ui32State) -+ { -+ case DC_STATE_FLUSH_COMMANDS: -+ OMAPLFBAtomicBoolSet(&psDevInfo->sFlushCommands, OMAPLFB_TRUE); -+ break; -+ case DC_STATE_NO_FLUSH_COMMANDS: -+ OMAPLFBAtomicBoolSet(&psDevInfo->sFlushCommands, OMAPLFB_FALSE); -+ break; -+ case DC_STATE_FORCE_SWAP_TO_SYSTEM: -+ OMAPLFBFlip(psDevInfo, &psDevInfo->sSystemBuffer); -+ break; -+ default: -+ break; -+ } -+} -+ -+/* -+ * OpenDCDevice -+ * Called from services. -+ */ -+static PVRSRV_ERROR OpenDCDevice(IMG_UINT32 uiPVRDevID, -+ IMG_HANDLE *phDevice, -+ PVRSRV_SYNC_DATA* psSystemBufferSyncData) -+{ -+ OMAPLFB_DEVINFO *psDevInfo; -+ OMAPLFB_ERROR eError; -+ unsigned uiMaxFBDevIDPlusOne; -+ unsigned i; -+ -+ if (!try_module_get(THIS_MODULE)) -+ { -+ return PVRSRV_ERROR_UNABLE_TO_OPEN_DC_DEVICE; -+ } -+ uiMaxFBDevIDPlusOne = OMAPLFBMaxFBDevIDPlusOne(); -+ -+ for (i = 0; i < uiMaxFBDevIDPlusOne; i++) -+ { -+ psDevInfo = OMAPLFBGetDevInfoPtr(i); -+ if (psDevInfo != NULL && psDevInfo->uiPVRDevID == uiPVRDevID) -+ { -+ break; -+ } -+ } -+ if (i == uiMaxFBDevIDPlusOne) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX -+ ": %s: PVR Device %u not found\n", __FUNCTION__, uiPVRDevID)); -+ eError = PVRSRV_ERROR_INVALID_DEVICE; -+ goto ErrorModulePut; -+ } -+ -+ /* store the system surface sync data */ -+ psDevInfo->sSystemBuffer.psSyncData = psSystemBufferSyncData; -+ -+ eError = OMAPLFBUnblankDisplay(psDevInfo); -+ if (eError != OMAPLFB_OK) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX -+ ": %s: Device %u: OMAPLFBUnblankDisplay failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, eError)); -+ eError = PVRSRV_ERROR_UNBLANK_DISPLAY_FAILED; -+ goto ErrorModulePut; -+ } -+ -+ /* return handle to the devinfo */ -+ *phDevice = (IMG_HANDLE)psDevInfo; -+ -+ return PVRSRV_OK; -+ -+ErrorModulePut: -+ module_put(THIS_MODULE); -+ return eError; -+} -+ -+/* -+ * CloseDCDevice -+ * Called from services. -+ */ -+static PVRSRV_ERROR CloseDCDevice(IMG_HANDLE hDevice) -+{ -+#if defined(SUPPORT_DRI_DRM) -+ OMAPLFB_DEVINFO *psDevInfo = (OMAPLFB_DEVINFO *)hDevice; -+ -+ OMAPLFBAtomicBoolSet(&psDevInfo->sLeaveVT, OMAPLFB_FALSE); -+ (void) OMAPLFBUnblankDisplay(psDevInfo); -+#else -+ UNREFERENCED_PARAMETER(hDevice); -+#endif -+ module_put(THIS_MODULE); -+ return PVRSRV_OK; -+} -+ -+/* -+ * EnumDCFormats -+ * Called from services. -+ */ -+static PVRSRV_ERROR EnumDCFormats(IMG_HANDLE hDevice, -+ IMG_UINT32 *pui32NumFormats, -+ DISPLAY_FORMAT *psFormat) -+{ -+ OMAPLFB_DEVINFO *psDevInfo; -+ -+ if(!hDevice || !pui32NumFormats) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psDevInfo = (OMAPLFB_DEVINFO*)hDevice; -+ -+ *pui32NumFormats = 1; -+ -+ if(psFormat) -+ { -+ psFormat[0] = psDevInfo->sDisplayFormat; -+ } -+ -+ return PVRSRV_OK; -+} -+ -+/* -+ * EnumDCDims -+ * Called from services. -+ */ -+static PVRSRV_ERROR EnumDCDims(IMG_HANDLE hDevice, -+ DISPLAY_FORMAT *psFormat, -+ IMG_UINT32 *pui32NumDims, -+ DISPLAY_DIMS *psDim) -+{ -+ OMAPLFB_DEVINFO *psDevInfo; -+ -+ if(!hDevice || !psFormat || !pui32NumDims) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psDevInfo = (OMAPLFB_DEVINFO*)hDevice; -+ -+ *pui32NumDims = 1; -+ -+ /* No need to look at psFormat; there is only one */ -+ if(psDim) -+ { -+ psDim[0] = psDevInfo->sDisplayDim; -+ } -+ -+ return PVRSRV_OK; -+} -+ -+ -+/* -+ * GetDCSystemBuffer -+ * Called from services. -+ */ -+static PVRSRV_ERROR GetDCSystemBuffer(IMG_HANDLE hDevice, IMG_HANDLE *phBuffer) -+{ -+ OMAPLFB_DEVINFO *psDevInfo; -+ -+ if(!hDevice || !phBuffer) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psDevInfo = (OMAPLFB_DEVINFO*)hDevice; -+ -+ *phBuffer = (IMG_HANDLE)&psDevInfo->sSystemBuffer; -+ -+ return PVRSRV_OK; -+} -+ -+ -+/* -+ * GetDCInfo -+ * Called from services. -+ */ -+static PVRSRV_ERROR GetDCInfo(IMG_HANDLE hDevice, DISPLAY_INFO *psDCInfo) -+{ -+ OMAPLFB_DEVINFO *psDevInfo; -+ -+ if(!hDevice || !psDCInfo) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psDevInfo = (OMAPLFB_DEVINFO*)hDevice; -+ -+ *psDCInfo = psDevInfo->sDisplayInfo; -+ -+ return PVRSRV_OK; -+} -+ -+/* -+ * GetDCBufferAddr -+ * Called from services. -+ */ -+static PVRSRV_ERROR GetDCBufferAddr(IMG_HANDLE hDevice, -+ IMG_HANDLE hBuffer, -+ IMG_SYS_PHYADDR **ppsSysAddr, -+ IMG_UINT32 *pui32ByteSize, -+ IMG_VOID **ppvCpuVAddr, -+ IMG_HANDLE *phOSMapInfo, -+ IMG_BOOL *pbIsContiguous, -+ IMG_UINT32 *pui32TilingStride) -+{ -+ OMAPLFB_DEVINFO *psDevInfo; -+ OMAPLFB_BUFFER *psSystemBuffer; -+ -+ UNREFERENCED_PARAMETER(pui32TilingStride); -+ -+ if(!hDevice) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ if(!hBuffer) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ if (!ppsSysAddr) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ if (!pui32ByteSize) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psDevInfo = (OMAPLFB_DEVINFO*)hDevice; -+ -+ psSystemBuffer = (OMAPLFB_BUFFER *)hBuffer; -+ -+ *ppsSysAddr = &psSystemBuffer->sSysAddr; -+ -+ *pui32ByteSize = (IMG_UINT32)psDevInfo->sFBInfo.ulBufferSize; -+ -+ if (ppvCpuVAddr) -+ { -+#if defined(CONFIG_DSSCOMP) -+ *ppvCpuVAddr = psDevInfo->sFBInfo.bIs2D ? NULL : psSystemBuffer->sCPUVAddr; -+#else -+ *ppvCpuVAddr = psSystemBuffer->sCPUVAddr; -+#endif -+ } -+ -+ if (phOSMapInfo) -+ { -+ *phOSMapInfo = (IMG_HANDLE)0; -+ } -+ -+ if (pbIsContiguous) -+ { -+#if defined(CONFIG_DSSCOMP) -+ *pbIsContiguous = !psDevInfo->sFBInfo.bIs2D; -+#else -+ *pbIsContiguous = IMG_TRUE; -+#endif -+ } -+ -+#if defined(CONFIG_DSSCOMP) -+ if (psDevInfo->sFBInfo.bIs2D) -+ { -+ int i = (psSystemBuffer->sSysAddr.uiAddr - psDevInfo->sFBInfo.psPageList->uiAddr) >> PAGE_SHIFT; -+ *ppsSysAddr = psDevInfo->sFBInfo.psPageList + psDevInfo->sFBInfo.ulHeight * i; -+ } -+#endif -+ -+ return PVRSRV_OK; -+} -+ -+/* -+ * CreateDCSwapChain -+ * Called from services. -+ */ -+static PVRSRV_ERROR CreateDCSwapChain(IMG_HANDLE hDevice, -+ IMG_UINT32 ui32Flags, -+ DISPLAY_SURF_ATTRIBUTES *psDstSurfAttrib, -+ DISPLAY_SURF_ATTRIBUTES *psSrcSurfAttrib, -+ IMG_UINT32 ui32BufferCount, -+ PVRSRV_SYNC_DATA **ppsSyncData, -+ IMG_UINT32 ui32OEMFlags, -+ IMG_HANDLE *phSwapChain, -+ IMG_UINT32 *pui32SwapChainID) -+{ -+ OMAPLFB_DEVINFO *psDevInfo; -+ OMAPLFB_SWAPCHAIN *psSwapChain; -+ OMAPLFB_BUFFER *psBuffer; -+ IMG_UINT32 i; -+ PVRSRV_ERROR eError; -+ IMG_UINT32 ui32BuffersToSkip; -+ -+ UNREFERENCED_PARAMETER(ui32OEMFlags); -+ -+ /* Check parameters */ -+ if(!hDevice -+ || !psDstSurfAttrib -+ || !psSrcSurfAttrib -+ || !ppsSyncData -+ || !phSwapChain) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psDevInfo = (OMAPLFB_DEVINFO*)hDevice; -+ -+ /* Do we support swap chains? */ -+ if (psDevInfo->sDisplayInfo.ui32MaxSwapChains == 0) -+ { -+ return PVRSRV_ERROR_NOT_SUPPORTED; -+ } -+ -+ OMAPLFBCreateSwapChainLock(psDevInfo); -+ -+ /* The driver only supports a single swapchain */ -+ if(psDevInfo->psSwapChain != NULL) -+ { -+ eError = PVRSRV_ERROR_FLIP_CHAIN_EXISTS; -+ goto ExitUnLock; -+ } -+ -+ /* Check the buffer count */ -+ if(ui32BufferCount > psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers) -+ { -+ eError = PVRSRV_ERROR_TOOMANYBUFFERS; -+ goto ExitUnLock; -+ } -+ -+ if ((psDevInfo->sFBInfo.ulRoundedBufferSize * (unsigned long)ui32BufferCount) > psDevInfo->sFBInfo.ulFBSize) -+ { -+ eError = PVRSRV_ERROR_TOOMANYBUFFERS; -+ goto ExitUnLock; -+ } -+ -+ /* -+ * We will allocate the swap chain buffers at the back of the frame -+ * buffer area. This preserves the front portion, which may be being -+ * used by other Linux Framebuffer based applications. -+ */ -+ ui32BuffersToSkip = psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers - ui32BufferCount; -+ -+ /* -+ * Verify the DST/SRC attributes, -+ * SRC/DST must match the current display mode config -+ */ -+ if(psDstSurfAttrib->pixelformat != psDevInfo->sDisplayFormat.pixelformat -+ || psDstSurfAttrib->sDims.ui32ByteStride != psDevInfo->sDisplayDim.ui32ByteStride -+ || psDstSurfAttrib->sDims.ui32Width != psDevInfo->sDisplayDim.ui32Width -+ || psDstSurfAttrib->sDims.ui32Height != psDevInfo->sDisplayDim.ui32Height) -+ { -+ /* DST doesn't match the current mode */ -+ eError = PVRSRV_ERROR_INVALID_PARAMS; -+ goto ExitUnLock; -+ } -+ -+ if(psDstSurfAttrib->pixelformat != psSrcSurfAttrib->pixelformat -+ || psDstSurfAttrib->sDims.ui32ByteStride != psSrcSurfAttrib->sDims.ui32ByteStride -+ || psDstSurfAttrib->sDims.ui32Width != psSrcSurfAttrib->sDims.ui32Width -+ || psDstSurfAttrib->sDims.ui32Height != psSrcSurfAttrib->sDims.ui32Height) -+ { -+ /* DST doesn't match the SRC */ -+ eError = PVRSRV_ERROR_INVALID_PARAMS; -+ goto ExitUnLock; -+ } -+ -+ /* check flags if implementation requires them */ -+ UNREFERENCED_PARAMETER(ui32Flags); -+ -+#if defined(PVR_OMAPFB3_UPDATE_MODE) -+ if (!OMAPLFBSetUpdateMode(psDevInfo, PVR_OMAPFB3_UPDATE_MODE)) -+ { -+ printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Couldn't set frame buffer update mode %d\n", __FUNCTION__, psDevInfo->uiFBDevID, PVR_OMAPFB3_UPDATE_MODE); -+ } -+#endif -+ /* create a swapchain structure */ -+ psSwapChain = (OMAPLFB_SWAPCHAIN*)OMAPLFBAllocKernelMem(sizeof(OMAPLFB_SWAPCHAIN)); -+ if(!psSwapChain) -+ { -+ eError = PVRSRV_ERROR_OUT_OF_MEMORY; -+ goto ExitUnLock; -+ } -+ -+ psBuffer = (OMAPLFB_BUFFER*)OMAPLFBAllocKernelMem(sizeof(OMAPLFB_BUFFER) * ui32BufferCount); -+ if(!psBuffer) -+ { -+ eError = PVRSRV_ERROR_OUT_OF_MEMORY; -+ goto ErrorFreeSwapChain; -+ } -+ -+ psSwapChain->ulBufferCount = (unsigned long)ui32BufferCount; -+ psSwapChain->psBuffer = psBuffer; -+ psSwapChain->bNotVSynced = OMAPLFB_TRUE; -+ psSwapChain->uiFBDevID = psDevInfo->uiFBDevID; -+ -+ /* Link the buffers */ -+ for(i=0; i<ui32BufferCount-1; i++) -+ { -+ psBuffer[i].psNext = &psBuffer[i+1]; -+ } -+ /* and link last to first */ -+ psBuffer[i].psNext = &psBuffer[0]; -+ -+ /* Configure the swapchain buffers */ -+ for(i=0; i<ui32BufferCount; i++) -+ { -+ IMG_UINT32 ui32SwapBuffer = i + ui32BuffersToSkip; -+ IMG_UINT32 ui32BufferOffset = ui32SwapBuffer * (IMG_UINT32)psDevInfo->sFBInfo.ulRoundedBufferSize; -+ -+#if defined(CONFIG_DSSCOMP) -+ if (psDevInfo->sFBInfo.bIs2D) -+ { -+ ui32BufferOffset = 0; -+ } -+#endif /* defined(CONFIG_DSSCOMP) */ -+ -+ psBuffer[i].psSyncData = ppsSyncData[i]; -+ -+ psBuffer[i].sSysAddr.uiAddr = psDevInfo->sFBInfo.sSysAddr.uiAddr + ui32BufferOffset; -+ psBuffer[i].sCPUVAddr = psDevInfo->sFBInfo.sCPUVAddr + ui32BufferOffset; -+ psBuffer[i].ulYOffset = ui32BufferOffset / psDevInfo->sFBInfo.ulByteStride; -+ psBuffer[i].psDevInfo = psDevInfo; -+ -+#if defined(CONFIG_DSSCOMP) -+ if (psDevInfo->sFBInfo.bIs2D) -+ { -+ psBuffer[i].sSysAddr.uiAddr += ui32SwapBuffer * -+ ALIGN((IMG_UINT32)psDevInfo->sFBInfo.ulWidth * psDevInfo->sFBInfo.uiBytesPerPixel, PAGE_SIZE); -+ } -+#endif /* defined(CONFIG_DSSCOMP) */ -+ -+ OMAPLFBInitBufferForSwap(&psBuffer[i]); -+ } -+ -+ if (OMAPLFBCreateSwapQueue(psSwapChain) != OMAPLFB_OK) -+ { -+ printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Failed to create workqueue\n", __FUNCTION__, psDevInfo->uiFBDevID); -+ eError = PVRSRV_ERROR_UNABLE_TO_INSTALL_ISR; -+ goto ErrorFreeBuffers; -+ } -+ -+ if (OMAPLFBEnableLFBEventNotification(psDevInfo)!= OMAPLFB_OK) -+ { -+ eError = PVRSRV_ERROR_UNABLE_TO_ENABLE_EVENT; -+ printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Couldn't enable framebuffer event notification\n", __FUNCTION__, psDevInfo->uiFBDevID); -+ goto ErrorDestroySwapQueue; -+ } -+ -+ psDevInfo->uiSwapChainID++; -+ if (psDevInfo->uiSwapChainID == 0) -+ { -+ psDevInfo->uiSwapChainID++; -+ } -+ -+ psSwapChain->uiSwapChainID = psDevInfo->uiSwapChainID; -+ -+ psDevInfo->psSwapChain = psSwapChain; -+ -+ *pui32SwapChainID = psDevInfo->uiSwapChainID; -+ -+ *phSwapChain = (IMG_HANDLE)psSwapChain; -+ -+ eError = PVRSRV_OK; -+ goto ExitUnLock; -+ -+ErrorDestroySwapQueue: -+ OMAPLFBDestroySwapQueue(psSwapChain); -+ErrorFreeBuffers: -+ OMAPLFBFreeKernelMem(psBuffer); -+ErrorFreeSwapChain: -+ OMAPLFBFreeKernelMem(psSwapChain); -+ExitUnLock: -+ OMAPLFBCreateSwapChainUnLock(psDevInfo); -+ return eError; -+} -+ -+/* -+ * DestroyDCSwapChain -+ * Called from services. -+ */ -+static PVRSRV_ERROR DestroyDCSwapChain(IMG_HANDLE hDevice, -+ IMG_HANDLE hSwapChain) -+{ -+ OMAPLFB_DEVINFO *psDevInfo; -+ OMAPLFB_SWAPCHAIN *psSwapChain; -+ OMAPLFB_ERROR eError; -+ -+ /* Check parameters */ -+ if(!hDevice || !hSwapChain) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psDevInfo = (OMAPLFB_DEVINFO*)hDevice; -+ psSwapChain = (OMAPLFB_SWAPCHAIN*)hSwapChain; -+ -+ OMAPLFBCreateSwapChainLock(psDevInfo); -+ -+ if (SwapChainHasChanged(psDevInfo, psSwapChain)) -+ { -+ printk(KERN_WARNING DRIVER_PREFIX -+ ": %s: Device %u: Swap chain mismatch\n", __FUNCTION__, psDevInfo->uiFBDevID); -+ -+ eError = PVRSRV_ERROR_INVALID_PARAMS; -+ goto ExitUnLock; -+ } -+ -+ /* The swap queue is flushed before being destroyed */ -+ OMAPLFBDestroySwapQueue(psSwapChain); -+ -+ eError = OMAPLFBDisableLFBEventNotification(psDevInfo); -+ if (eError != OMAPLFB_OK) -+ { -+ printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Couldn't disable framebuffer event notification\n", __FUNCTION__, psDevInfo->uiFBDevID); -+ } -+ -+ /* Free resources */ -+ OMAPLFBFreeKernelMem(psSwapChain->psBuffer); -+ OMAPLFBFreeKernelMem(psSwapChain); -+ -+ psDevInfo->psSwapChain = NULL; -+ -+ OMAPLFBFlip(psDevInfo, &psDevInfo->sSystemBuffer); -+ (void) OMAPLFBCheckModeAndSync(psDevInfo); -+ -+ eError = PVRSRV_OK; -+ -+ExitUnLock: -+ OMAPLFBCreateSwapChainUnLock(psDevInfo); -+ -+ return eError; -+} -+ -+/* -+ * SetDCDstRect -+ * Called from services. -+ */ -+static PVRSRV_ERROR SetDCDstRect(IMG_HANDLE hDevice, -+ IMG_HANDLE hSwapChain, -+ IMG_RECT *psRect) -+{ -+ UNREFERENCED_PARAMETER(hDevice); -+ UNREFERENCED_PARAMETER(hSwapChain); -+ UNREFERENCED_PARAMETER(psRect); -+ -+ /* Only full display swapchains on this device */ -+ -+ return PVRSRV_ERROR_NOT_SUPPORTED; -+} -+ -+/* -+ * SetDCSrcRect -+ * Called from services. -+ */ -+static PVRSRV_ERROR SetDCSrcRect(IMG_HANDLE hDevice, -+ IMG_HANDLE hSwapChain, -+ IMG_RECT *psRect) -+{ -+ UNREFERENCED_PARAMETER(hDevice); -+ UNREFERENCED_PARAMETER(hSwapChain); -+ UNREFERENCED_PARAMETER(psRect); -+ -+ /* Only full display swapchains on this device */ -+ -+ return PVRSRV_ERROR_NOT_SUPPORTED; -+} -+ -+/* -+ * SetDCDstColourKey -+ * Called from services. -+ */ -+static PVRSRV_ERROR SetDCDstColourKey(IMG_HANDLE hDevice, -+ IMG_HANDLE hSwapChain, -+ IMG_UINT32 ui32CKColour) -+{ -+ UNREFERENCED_PARAMETER(hDevice); -+ UNREFERENCED_PARAMETER(hSwapChain); -+ UNREFERENCED_PARAMETER(ui32CKColour); -+ -+ /* Don't support DST CK on this device */ -+ -+ return PVRSRV_ERROR_NOT_SUPPORTED; -+} -+ -+/* -+ * SetDCSrcColourKey -+ * Called from services. -+ */ -+static PVRSRV_ERROR SetDCSrcColourKey(IMG_HANDLE hDevice, -+ IMG_HANDLE hSwapChain, -+ IMG_UINT32 ui32CKColour) -+{ -+ UNREFERENCED_PARAMETER(hDevice); -+ UNREFERENCED_PARAMETER(hSwapChain); -+ UNREFERENCED_PARAMETER(ui32CKColour); -+ -+ /* Don't support SRC CK on this device */ -+ -+ return PVRSRV_ERROR_NOT_SUPPORTED; -+} -+ -+/* -+ * GetDCBuffers -+ * Called from services. -+ */ -+static PVRSRV_ERROR GetDCBuffers(IMG_HANDLE hDevice, -+ IMG_HANDLE hSwapChain, -+ IMG_UINT32 *pui32BufferCount, -+ IMG_HANDLE *phBuffer) -+{ -+ OMAPLFB_DEVINFO *psDevInfo; -+ OMAPLFB_SWAPCHAIN *psSwapChain; -+ PVRSRV_ERROR eError; -+ unsigned i; -+ -+ /* Check parameters */ -+ if(!hDevice -+ || !hSwapChain -+ || !pui32BufferCount -+ || !phBuffer) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psDevInfo = (OMAPLFB_DEVINFO*)hDevice; -+ psSwapChain = (OMAPLFB_SWAPCHAIN*)hSwapChain; -+ -+ OMAPLFBCreateSwapChainLock(psDevInfo); -+ -+ if (SwapChainHasChanged(psDevInfo, psSwapChain)) -+ { -+ printk(KERN_WARNING DRIVER_PREFIX -+ ": %s: Device %u: Swap chain mismatch\n", __FUNCTION__, psDevInfo->uiFBDevID); -+ -+ eError = PVRSRV_ERROR_INVALID_PARAMS; -+ goto Exit; -+ } -+ -+ /* Return the buffer count */ -+ *pui32BufferCount = (IMG_UINT32)psSwapChain->ulBufferCount; -+ -+ /* Return the buffers */ -+ for(i=0; i<psSwapChain->ulBufferCount; i++) -+ { -+ phBuffer[i] = (IMG_HANDLE)&psSwapChain->psBuffer[i]; -+ } -+ -+ eError = PVRSRV_OK; -+ -+Exit: -+ OMAPLFBCreateSwapChainUnLock(psDevInfo); -+ -+ return eError; -+} -+ -+/* -+ * SwapToDCBuffer -+ * Called from services. -+ */ -+static PVRSRV_ERROR SwapToDCBuffer(IMG_HANDLE hDevice, -+ IMG_HANDLE hBuffer, -+ IMG_UINT32 ui32SwapInterval, -+ IMG_HANDLE hPrivateTag, -+ IMG_UINT32 ui32ClipRectCount, -+ IMG_RECT *psClipRect) -+{ -+ UNREFERENCED_PARAMETER(hDevice); -+ UNREFERENCED_PARAMETER(hBuffer); -+ UNREFERENCED_PARAMETER(ui32SwapInterval); -+ UNREFERENCED_PARAMETER(hPrivateTag); -+ UNREFERENCED_PARAMETER(ui32ClipRectCount); -+ UNREFERENCED_PARAMETER(psClipRect); -+ -+ /* * Nothing to do since Services common code does the work */ -+ -+ return PVRSRV_OK; -+} -+ -+/* -+ * Called after the screen has unblanked, or after any other occasion -+ * when we didn't wait for vsync, but now need to. Not doing this after -+ * unblank leads to screen jitter on some screens. -+ * Returns true if the screen has been deemed to have settled. -+ */ -+static OMAPLFB_BOOL WaitForVSyncSettle(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ unsigned i; -+ for(i = 0; i < OMAPLFB_VSYNC_SETTLE_COUNT; i++) -+ { -+ if (DontWaitForVSync(psDevInfo) || !OMAPLFBWaitForVSync(psDevInfo)) -+ { -+ return OMAPLFB_FALSE; -+ } -+ } -+ -+ return OMAPLFB_TRUE; -+} -+ -+/* -+ * Swap handler. -+ * Called from the swap chain work queue handler. -+ * There is no need to take the swap chain creation lock in here, or use -+ * some other method of stopping the swap chain from being destroyed. -+ * This is because the swap chain creation lock is taken when queueing work, -+ * and the work queue is flushed before the swap chain is destroyed. -+ */ -+void OMAPLFBSwapHandler(OMAPLFB_BUFFER *psBuffer) -+{ -+ OMAPLFB_DEVINFO *psDevInfo = psBuffer->psDevInfo; -+ OMAPLFB_SWAPCHAIN *psSwapChain = psDevInfo->psSwapChain; -+ OMAPLFB_BOOL bPreviouslyNotVSynced; -+ -+#if defined(SUPPORT_DRI_DRM) -+ if (!OMAPLFBAtomicBoolRead(&psDevInfo->sLeaveVT)) -+#endif -+ { -+ OMAPLFBFlip(psDevInfo, psBuffer); -+ } -+ -+ bPreviouslyNotVSynced = psSwapChain->bNotVSynced; -+ psSwapChain->bNotVSynced = OMAPLFB_TRUE; -+ -+ -+ if (!DontWaitForVSync(psDevInfo)) -+ { -+ OMAPLFB_UPDATE_MODE eMode = OMAPLFBGetUpdateMode(psDevInfo); -+ int iBlankEvents = OMAPLFBAtomicIntRead(&psDevInfo->sBlankEvents); -+ -+ switch(eMode) -+ { -+ case OMAPLFB_UPDATE_MODE_AUTO: -+ psSwapChain->bNotVSynced = OMAPLFB_FALSE; -+ -+ if (bPreviouslyNotVSynced || psSwapChain->iBlankEvents != iBlankEvents) -+ { -+ psSwapChain->iBlankEvents = iBlankEvents; -+ psSwapChain->bNotVSynced = !WaitForVSyncSettle(psDevInfo); -+ } else if (psBuffer->ulSwapInterval != 0) -+ { -+ psSwapChain->bNotVSynced = !OMAPLFBWaitForVSync(psDevInfo); -+ } -+ break; -+#if defined(PVR_OMAPFB3_MANUAL_UPDATE_SYNC_IN_SWAP) -+ case OMAPLFB_UPDATE_MODE_MANUAL: -+ if (psBuffer->ulSwapInterval != 0) -+ { -+ (void) OMAPLFBManualSync(psDevInfo); -+ } -+ break; -+#endif -+ default: -+ break; -+ } -+ } -+ -+ psDevInfo->sPVRJTable.pfnPVRSRVCmdComplete((IMG_HANDLE)psBuffer->hCmdComplete, IMG_TRUE); -+} -+ -+/* Triggered by PVRSRVSwapToDCBuffer */ -+static IMG_BOOL ProcessFlipV1(IMG_HANDLE hCmdCookie, -+ OMAPLFB_DEVINFO *psDevInfo, -+ OMAPLFB_SWAPCHAIN *psSwapChain, -+ OMAPLFB_BUFFER *psBuffer, -+ unsigned long ulSwapInterval) -+{ -+ OMAPLFBCreateSwapChainLock(psDevInfo); -+ -+ /* The swap chain has been destroyed */ -+ if (SwapChainHasChanged(psDevInfo, psSwapChain)) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX -+ ": %s: Device %u (PVR Device ID %u): The swap chain has been destroyed\n", -+ __FUNCTION__, psDevInfo->uiFBDevID, psDevInfo->uiPVRDevID)); -+ } -+ else -+ { -+ psBuffer->hCmdComplete = (OMAPLFB_HANDLE)hCmdCookie; -+ psBuffer->ulSwapInterval = ulSwapInterval; -+#if defined(CONFIG_DSSCOMP) -+ if (is_tiler_addr(psBuffer->sSysAddr.uiAddr)) -+ { -+ IMG_UINT32 w = psBuffer->psDevInfo->sDisplayDim.ui32Width; -+ IMG_UINT32 h = psBuffer->psDevInfo->sDisplayDim.ui32Height; -+ struct dsscomp_setup_dispc_data comp = { -+ .num_mgrs = 1, -+ .mgrs[0].alpha_blending = 1, -+ .num_ovls = 1, -+ .ovls[0].cfg = -+ { -+ .width = w, -+ .win.w = w, -+ .crop.w = w, -+ .height = h, -+ .win.h = h, -+ .crop.h = h, -+ .stride = psBuffer->psDevInfo->sDisplayDim.ui32ByteStride, -+ .color_mode = OMAP_DSS_COLOR_ARGB32, -+ .enabled = 1, -+ .global_alpha = 255, -+ }, -+ .mode = DSSCOMP_SETUP_DISPLAY, -+ }; -+ struct tiler_pa_info *pas[1] = { NULL }; -+ comp.ovls[0].ba = (u32) psBuffer->sSysAddr.uiAddr; -+ dsscomp_gralloc_queue(&comp, pas, true, -+ (void *) psDevInfo->sPVRJTable.pfnPVRSRVCmdComplete, -+ (void *) psBuffer->hCmdComplete); -+ } -+ else -+#endif /* defined(CONFIG_DSSCOMP) */ -+ { -+ OMAPLFBQueueBufferForSwap(psSwapChain, psBuffer); -+ } -+ } -+ -+ OMAPLFBCreateSwapChainUnLock(psDevInfo); -+ -+ return IMG_TRUE; -+} -+ -+#if defined(CONFIG_DSSCOMP) -+ -+/* Triggered by PVRSRVSwapToDCBuffer2 */ -+static IMG_BOOL ProcessFlipV2(IMG_HANDLE hCmdCookie, -+ OMAPLFB_DEVINFO *psDevInfo, -+ PDC_MEM_INFO *ppsMemInfos, -+ IMG_UINT32 ui32NumMemInfos, -+ struct dsscomp_setup_dispc_data *psDssData, -+ IMG_UINT32 ui32DssDataLength) -+{ -+ struct tiler_pa_info *apsTilerPAs[5]; -+ IMG_UINT32 i, k; -+ -+ if(ui32DssDataLength != sizeof(*psDssData)) -+ { -+ WARN(1, "invalid size of private data (%d vs %d)", -+ ui32DssDataLength, sizeof(*psDssData)); -+ return IMG_FALSE; -+ } -+ -+ if(psDssData->num_ovls == 0 || ui32NumMemInfos == 0) -+ { -+ WARN(1, "must have at least one layer"); -+ return IMG_FALSE; -+ } -+ -+ for(i = k = 0; i < ui32NumMemInfos && k < ARRAY_SIZE(apsTilerPAs); i++, k++) -+ { -+ struct tiler_pa_info *psTilerInfo; -+ IMG_CPU_VIRTADDR virtAddr; -+ IMG_CPU_PHYADDR phyAddr; -+ IMG_UINT32 ui32NumPages; -+ IMG_SIZE_T uByteSize; -+ int j; -+ -+ psDevInfo->sPVRJTable.pfnPVRSRVDCMemInfoGetByteSize(ppsMemInfos[i], &uByteSize); -+ ui32NumPages = (uByteSize + PAGE_SIZE - 1) >> PAGE_SHIFT; -+ -+ apsTilerPAs[k] = NULL; -+ -+ psDevInfo->sPVRJTable.pfnPVRSRVDCMemInfoGetCpuPAddr(ppsMemInfos[i], 0, &phyAddr); -+ -+ /* NV12 buffers are already mapped to tiler */ -+ if(psDssData->ovls[k].cfg.color_mode == OMAP_DSS_COLOR_NV12) -+ { -+ psDssData->ovls[k].ba = (u32)phyAddr.uiAddr; -+ -+ psDevInfo->sPVRJTable.pfnPVRSRVDCMemInfoGetCpuPAddr(ppsMemInfos[i], (uByteSize * 2) / 3, &phyAddr); -+ psDssData->ovls[k].uv = (u32)phyAddr.uiAddr; -+ continue; -+ } -+ -+ /* Other kinds of buffer may also already be mapped to tiler */ -+ if(is_tiler_addr((u32)phyAddr.uiAddr)) -+ { -+ psDssData->ovls[k].ba = (u32)phyAddr.uiAddr; -+ continue; -+ } -+ -+ psTilerInfo = kzalloc(sizeof(*psTilerInfo), GFP_KERNEL); -+ if(!psTilerInfo) -+ { -+ continue; -+ } -+ -+ psTilerInfo->mem = kzalloc(sizeof(*psTilerInfo->mem) * ui32NumPages, GFP_KERNEL); -+ if(!psTilerInfo->mem) -+ { -+ kfree(psTilerInfo); -+ continue; -+ } -+ -+ psTilerInfo->num_pg = ui32NumPages; -+ psTilerInfo->memtype = TILER_MEM_USING; -+ -+ for(j = 0; j < ui32NumPages; j++) -+ { -+ psDevInfo->sPVRJTable.pfnPVRSRVDCMemInfoGetCpuPAddr(ppsMemInfos[i], j << PAGE_SHIFT, &phyAddr); -+ psTilerInfo->mem[j] = (u32)phyAddr.uiAddr; -+ } -+ -+ /* Need base address for in-page offset */ -+ psDevInfo->sPVRJTable.pfnPVRSRVDCMemInfoGetCpuVAddr(ppsMemInfos[i], &virtAddr); -+ psDssData->ovls[k].ba = (u32)virtAddr; -+ apsTilerPAs[k] = psTilerInfo; -+ } -+ -+ /* Set up cloned layer addresses (but don't duplicate tiler_pas) */ -+ for(i = k; i < psDssData->num_ovls && i < ARRAY_SIZE(apsTilerPAs); i++) -+ { -+ unsigned int ix = psDssData->ovls[i].ba; -+ if(ix >= ARRAY_SIZE(apsTilerPAs)) -+ { -+ WARN(1, "Invalid clone layer (%u); skipping all cloned layers", ix); -+ psDssData->num_ovls = k; -+ break; -+ } -+ apsTilerPAs[i] = apsTilerPAs[ix]; -+ psDssData->ovls[i].ba = psDssData->ovls[ix].ba; -+ psDssData->ovls[i].uv = psDssData->ovls[ix].uv; -+ } -+ -+ dsscomp_gralloc_queue(psDssData, apsTilerPAs, false, -+ (void *)psDevInfo->sPVRJTable.pfnPVRSRVCmdComplete, -+ (void *)hCmdCookie); -+ -+ for(i = 0; i < k; i++) -+ { -+ tiler_pa_free(apsTilerPAs[i]); -+ } -+ -+ return IMG_TRUE; -+} -+ -+#endif /* defined(CONFIG_DSSCOMP) */ -+ -+/* Command processing flip handler function. Called from services. */ -+static IMG_BOOL ProcessFlip(IMG_HANDLE hCmdCookie, -+ IMG_UINT32 ui32DataSize, -+ IMG_VOID *pvData) -+{ -+ DISPLAYCLASS_FLIP_COMMAND *psFlipCmd; -+ OMAPLFB_DEVINFO *psDevInfo; -+ -+ /* Check parameters */ -+ if(!hCmdCookie || !pvData) -+ { -+ return IMG_FALSE; -+ } -+ -+ /* Validate data packet */ -+ psFlipCmd = (DISPLAYCLASS_FLIP_COMMAND*)pvData; -+ -+ if (psFlipCmd == IMG_NULL) -+ { -+ return IMG_FALSE; -+ } -+ -+ psDevInfo = (OMAPLFB_DEVINFO*)psFlipCmd->hExtDevice; -+ -+ if(psFlipCmd->hExtBuffer) -+ { -+ return ProcessFlipV1(hCmdCookie, -+ psDevInfo, -+ psFlipCmd->hExtSwapChain, -+ psFlipCmd->hExtBuffer, -+ psFlipCmd->ui32SwapInterval); -+ } -+ else -+ { -+#if defined(CONFIG_DSSCOMP) -+ DISPLAYCLASS_FLIP_COMMAND2 *psFlipCmd2; -+ psFlipCmd2 = (DISPLAYCLASS_FLIP_COMMAND2 *)pvData; -+ return ProcessFlipV2(hCmdCookie, -+ psDevInfo, -+ psFlipCmd2->ppsMemInfos, -+ psFlipCmd2->ui32NumMemInfos, -+ psFlipCmd2->pvPrivData, -+ psFlipCmd2->ui32PrivDataLength); -+#else -+ BUG(); -+#endif -+ } -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function OMAPLFBInitFBDev -+ -+ @Description specifies devices in the systems memory map -+ -+ @Input psSysData - sys data -+ -+ @Return OMAPLFB_ERROR : -+ -+******************************************************************************/ -+static OMAPLFB_ERROR OMAPLFBInitFBDev(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ struct fb_info *psLINFBInfo; -+ struct module *psLINFBOwner; -+ OMAPLFB_FBINFO *psPVRFBInfo = &psDevInfo->sFBInfo; -+ OMAPLFB_ERROR eError = OMAPLFB_ERROR_GENERIC; -+ unsigned long FBSize; -+ unsigned long ulLCM; -+ unsigned uiFBDevID = psDevInfo->uiFBDevID; -+ -+ OMAPLFB_CONSOLE_LOCK(); -+ -+ psLINFBInfo = registered_fb[uiFBDevID]; -+ if (psLINFBInfo == NULL) -+ { -+ eError = OMAPLFB_ERROR_INVALID_DEVICE; -+ goto ErrorRelSem; -+ } -+ -+ FBSize = (psLINFBInfo->screen_size) != 0 ? -+ psLINFBInfo->screen_size : -+ psLINFBInfo->fix.smem_len; -+ -+ /* -+ * Try and filter out invalid FB info structures (a problem -+ * seen on some OMAP3 systems). -+ */ -+ if (FBSize == 0 || psLINFBInfo->fix.line_length == 0) -+ { -+ eError = OMAPLFB_ERROR_INVALID_DEVICE; -+ goto ErrorRelSem; -+ } -+ -+ psLINFBOwner = psLINFBInfo->fbops->owner; -+ if (!try_module_get(psLINFBOwner)) -+ { -+ printk(KERN_INFO DRIVER_PREFIX -+ ": %s: Device %u: Couldn't get framebuffer module\n", __FUNCTION__, uiFBDevID); -+ -+ goto ErrorRelSem; -+ } -+ -+ if (psLINFBInfo->fbops->fb_open != NULL) -+ { -+ int res; -+ -+ res = psLINFBInfo->fbops->fb_open(psLINFBInfo, 0); -+ if (res != 0) -+ { -+ printk(KERN_INFO DRIVER_PREFIX -+ " %s: Device %u: Couldn't open framebuffer(%d)\n", __FUNCTION__, uiFBDevID, res); -+ -+ goto ErrorModPut; -+ } -+ } -+ -+ psDevInfo->psLINFBInfo = psLINFBInfo; -+ -+ ulLCM = LCM(psLINFBInfo->fix.line_length, OMAPLFB_PAGE_SIZE); -+ -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX -+ ": Device %u: Framebuffer physical address: 0x%lx\n", -+ psDevInfo->uiFBDevID, psLINFBInfo->fix.smem_start)); -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX -+ ": Device %u: Framebuffer virtual address: 0x%lx\n", -+ psDevInfo->uiFBDevID, (unsigned long)psLINFBInfo->screen_base)); -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX -+ ": Device %u: Framebuffer size: %lu\n", -+ psDevInfo->uiFBDevID, FBSize)); -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX -+ ": Device %u: Framebuffer virtual width: %u\n", -+ psDevInfo->uiFBDevID, psLINFBInfo->var.xres_virtual)); -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX -+ ": Device %u: Framebuffer virtual height: %u\n", -+ psDevInfo->uiFBDevID, psLINFBInfo->var.yres_virtual)); -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX -+ ": Device %u: Framebuffer width: %u\n", -+ psDevInfo->uiFBDevID, psLINFBInfo->var.xres)); -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX -+ ": Device %u: Framebuffer height: %u\n", -+ psDevInfo->uiFBDevID, psLINFBInfo->var.yres)); -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX -+ ": Device %u: Framebuffer stride: %u\n", -+ psDevInfo->uiFBDevID, psLINFBInfo->fix.line_length)); -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX -+ ": Device %u: LCM of stride and page size: %lu\n", -+ psDevInfo->uiFBDevID, ulLCM)); -+ -+ /* Additional implementation specific information */ -+ OMAPLFBPrintInfo(psDevInfo); -+ -+#if defined(CONFIG_DSSCOMP) -+ { -+ /* for some reason we need at least 3 buffers in the swap chain */ -+ int n = FBSize / RoundUpToMultiple(psLINFBInfo->fix.line_length * psLINFBInfo->var.yres, ulLCM); -+ int res; -+ int i, x, y, w; -+ ion_phys_addr_t phys; -+ size_t size; -+ struct tiler_view_t view; -+ -+ struct omap_ion_tiler_alloc_data sAllocData = -+ { -+ /* TILER will align width to 128-bytes */ -+ /* however, SGX must have full page width */ -+ .w = ALIGN(psLINFBInfo->var.xres, PAGE_SIZE / (psLINFBInfo->var.bits_per_pixel / 8)), -+ .h = psLINFBInfo->var.yres, -+ .fmt = psLINFBInfo->var.bits_per_pixel == 16 ? TILER_PIXEL_FMT_16BIT : TILER_PIXEL_FMT_32BIT, -+ .flags = 0, -+ }; -+ -+ printk(KERN_DEBUG DRIVER_PREFIX -+ " %s: Device %u: Requesting %d TILER 2D framebuffers\n", -+ __FUNCTION__, uiFBDevID, n); -+ -+ /* INTEGRATION_POINT: limit to MAX 3 FBs to save TILER container space */ -+ if (n != 3) -+ n = 3; -+ -+ sAllocData.w *= n; -+ -+ psPVRFBInfo->uiBytesPerPixel = psLINFBInfo->var.bits_per_pixel >> 3; -+ psPVRFBInfo->bIs2D = OMAPLFB_TRUE; -+ -+ res = omap_ion_tiler_alloc(gpsIONClient, &sAllocData); -+ psPVRFBInfo->psIONHandle = sAllocData.handle; -+ if (res < 0) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ " %s: Device %u: Could not allocate 2D framebuffer(%d)\n", -+ __FUNCTION__, uiFBDevID, res); -+ goto ErrorModPut; -+ } -+ -+ psLINFBInfo->fix.smem_start = ion_phys(gpsIONClient, sAllocData.handle, &phys, &size); -+ -+ psPVRFBInfo->sSysAddr.uiAddr = phys; -+ psPVRFBInfo->sCPUVAddr = 0; -+ psPVRFBInfo->ulWidth = psLINFBInfo->var.xres; -+ psPVRFBInfo->ulHeight = psLINFBInfo->var.yres; -+ -+ psPVRFBInfo->ulByteStride = PAGE_ALIGN(psPVRFBInfo->ulWidth * psPVRFBInfo->uiBytesPerPixel); -+ w = psPVRFBInfo->ulByteStride >> PAGE_SHIFT; -+ -+ /* this is an "effective" FB size to get correct number of buffers */ -+ psPVRFBInfo->ulFBSize = sAllocData.h * n * psPVRFBInfo->ulByteStride; -+ psPVRFBInfo->psPageList = kzalloc(w * n * psPVRFBInfo->ulHeight * sizeof(*psPVRFBInfo->psPageList), GFP_KERNEL); -+ if (!psPVRFBInfo->psPageList) -+ { -+ printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Could not allocate page list\n", __FUNCTION__, psDevInfo->uiFBDevID); -+ ion_free(gpsIONClient, sAllocData.handle); -+ goto ErrorModPut; -+ } -+ -+ tilview_create(&view, phys, psDevInfo->sFBInfo.ulWidth, psDevInfo->sFBInfo.ulHeight); -+ for(i = 0; i < n; i++) -+ { -+ for(y = 0; y < psDevInfo->sFBInfo.ulHeight; y++) -+ { -+ for(x = 0; x < w; x++) -+ { -+ psPVRFBInfo->psPageList[i * psDevInfo->sFBInfo.ulHeight * w + y * w + x].uiAddr = -+ phys + view.v_inc * y + ((x + i * w) << PAGE_SHIFT); -+ } -+ } -+ } -+ } -+#else /* defined(CONFIG_DSSCOMP) */ -+ /* System Surface */ -+ psPVRFBInfo->sSysAddr.uiAddr = psLINFBInfo->fix.smem_start; -+ psPVRFBInfo->sCPUVAddr = psLINFBInfo->screen_base; -+ -+ psPVRFBInfo->ulWidth = psLINFBInfo->var.xres; -+ psPVRFBInfo->ulHeight = psLINFBInfo->var.yres; -+ psPVRFBInfo->ulByteStride = psLINFBInfo->fix.line_length; -+ psPVRFBInfo->ulFBSize = FBSize; -+#endif /* defined(CONFIG_DSSCOMP) */ -+ -+ psPVRFBInfo->ulBufferSize = psPVRFBInfo->ulHeight * psPVRFBInfo->ulByteStride; -+ -+ /* Round the buffer size up to a multiple of the number of pages -+ * and the byte stride. -+ * This is used internally, to ensure buffers start on page -+ * boundaries, for the benefit of PVR Services. -+ */ -+ psPVRFBInfo->ulRoundedBufferSize = RoundUpToMultiple(psPVRFBInfo->ulBufferSize, ulLCM); -+ -+ if(psLINFBInfo->var.bits_per_pixel == 16) -+ { -+ if((psLINFBInfo->var.red.length == 5) && -+ (psLINFBInfo->var.green.length == 6) && -+ (psLINFBInfo->var.blue.length == 5) && -+ (psLINFBInfo->var.red.offset == 11) && -+ (psLINFBInfo->var.green.offset == 5) && -+ (psLINFBInfo->var.blue.offset == 0) && -+ (psLINFBInfo->var.red.msb_right == 0)) -+ { -+ psPVRFBInfo->ePixelFormat = PVRSRV_PIXEL_FORMAT_RGB565; -+ } -+ else -+ { -+ printk(KERN_INFO DRIVER_PREFIX ": %s: Device %u: Unknown FB format\n", __FUNCTION__, uiFBDevID); -+ } -+ } -+ else if(psLINFBInfo->var.bits_per_pixel == 32) -+ { -+ if((psLINFBInfo->var.red.length == 8) && -+ (psLINFBInfo->var.green.length == 8) && -+ (psLINFBInfo->var.blue.length == 8) && -+ (psLINFBInfo->var.red.offset == 16) && -+ (psLINFBInfo->var.green.offset == 8) && -+ (psLINFBInfo->var.blue.offset == 0) && -+ (psLINFBInfo->var.red.msb_right == 0)) -+ { -+ psPVRFBInfo->ePixelFormat = PVRSRV_PIXEL_FORMAT_ARGB8888; -+ } -+ else -+ { -+ printk(KERN_INFO DRIVER_PREFIX ": %s: Device %u: Unknown FB format\n", __FUNCTION__, uiFBDevID); -+ } -+ } -+ else -+ { -+ printk(KERN_INFO DRIVER_PREFIX ": %s: Device %u: Unknown FB format\n", __FUNCTION__, uiFBDevID); -+ } -+ -+ psDevInfo->sFBInfo.ulPhysicalWidthmm = -+ ((int)psLINFBInfo->var.width > 0) ? psLINFBInfo->var.width : 90; -+ -+ psDevInfo->sFBInfo.ulPhysicalHeightmm = -+ ((int)psLINFBInfo->var.height > 0) ? psLINFBInfo->var.height : 54; -+ -+ /* System Surface */ -+ psDevInfo->sFBInfo.sSysAddr.uiAddr = psPVRFBInfo->sSysAddr.uiAddr; -+ psDevInfo->sFBInfo.sCPUVAddr = psPVRFBInfo->sCPUVAddr; -+ -+ eError = OMAPLFB_OK; -+ goto ErrorRelSem; -+ -+ErrorModPut: -+ module_put(psLINFBOwner); -+ErrorRelSem: -+ OMAPLFB_CONSOLE_UNLOCK(); -+ -+ return eError; -+} -+ -+static void OMAPLFBDeInitFBDev(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ struct fb_info *psLINFBInfo = psDevInfo->psLINFBInfo; -+ struct module *psLINFBOwner; -+ -+ OMAPLFB_CONSOLE_LOCK(); -+ -+#if defined(CONFIG_DSSCOMP) -+ { -+ OMAPLFB_FBINFO *psPVRFBInfo = &psDevInfo->sFBInfo; -+ kfree(psPVRFBInfo->psPageList); -+ if (psPVRFBInfo->psIONHandle) -+ { -+ ion_free(gpsIONClient, psPVRFBInfo->psIONHandle); -+ } -+ } -+#endif /* defined(CONFIG_DSSCOMP) */ -+ -+ psLINFBOwner = psLINFBInfo->fbops->owner; -+ -+ if (psLINFBInfo->fbops->fb_release != NULL) -+ { -+ (void) psLINFBInfo->fbops->fb_release(psLINFBInfo, 0); -+ } -+ -+ module_put(psLINFBOwner); -+ -+ OMAPLFB_CONSOLE_UNLOCK(); -+} -+ -+static OMAPLFB_DEVINFO *OMAPLFBInitDev(unsigned uiFBDevID) -+{ -+ PFN_CMD_PROC pfnCmdProcList[OMAPLFB_COMMAND_COUNT]; -+ IMG_UINT32 aui32SyncCountList[OMAPLFB_COMMAND_COUNT][2]; -+ OMAPLFB_DEVINFO *psDevInfo = NULL; -+ -+ /* Allocate device info. structure */ -+ psDevInfo = (OMAPLFB_DEVINFO *)OMAPLFBAllocKernelMem(sizeof(OMAPLFB_DEVINFO)); -+ -+ if(psDevInfo == NULL) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ ": %s: Device %u: Couldn't allocate device information structure\n", __FUNCTION__, uiFBDevID); -+ -+ goto ErrorExit; -+ } -+ -+ /* Any fields not set will be zero */ -+ memset(psDevInfo, 0, sizeof(OMAPLFB_DEVINFO)); -+ -+ psDevInfo->uiFBDevID = uiFBDevID; -+ -+ /* Get the kernel services function table */ -+ if(!(*gpfnGetPVRJTable)(&psDevInfo->sPVRJTable)) -+ { -+ goto ErrorFreeDevInfo; -+ } -+#ifdef FBDEV_PRESENT -+ /* Save private fbdev information structure in the dev. info. */ -+ if(OMAPLFBInitFBDev(psDevInfo) != OMAPLFB_OK) -+ { -+ /* -+ * Leave it to OMAPLFBInitFBDev to print an error message, if -+ * required. The function may have failed because -+ * there is no Linux framebuffer device corresponding -+ * to the device ID. -+ */ -+ goto ErrorFreeDevInfo; -+ } -+ -+ psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers = (IMG_UINT32)(psDevInfo->sFBInfo.ulFBSize / psDevInfo->sFBInfo.ulRoundedBufferSize); -+ if (psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers != 0) -+ { -+ psDevInfo->sDisplayInfo.ui32MaxSwapChains = 1; -+ psDevInfo->sDisplayInfo.ui32MaxSwapInterval = 1; -+ } -+ -+ psDevInfo->sDisplayInfo.ui32PhysicalWidthmm = psDevInfo->sFBInfo.ulPhysicalWidthmm; -+ psDevInfo->sDisplayInfo.ui32PhysicalHeightmm = psDevInfo->sFBInfo.ulPhysicalHeightmm; -+ -+ strncpy(psDevInfo->sDisplayInfo.szDisplayName, DISPLAY_DEVICE_NAME, MAX_DISPLAY_NAME_SIZE); -+ -+ psDevInfo->sDisplayFormat.pixelformat = psDevInfo->sFBInfo.ePixelFormat; -+ psDevInfo->sDisplayDim.ui32Width = (IMG_UINT32)psDevInfo->sFBInfo.ulWidth; -+ psDevInfo->sDisplayDim.ui32Height = (IMG_UINT32)psDevInfo->sFBInfo.ulHeight; -+ psDevInfo->sDisplayDim.ui32ByteStride = (IMG_UINT32)psDevInfo->sFBInfo.ulByteStride; -+ -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX -+ ": Device %u: Maximum number of swap chain buffers: %u\n", -+ psDevInfo->uiFBDevID, psDevInfo->sDisplayInfo.ui32MaxSwapChainBuffers)); -+ -+ /* Setup system buffer */ -+ psDevInfo->sSystemBuffer.sSysAddr = psDevInfo->sFBInfo.sSysAddr; -+ psDevInfo->sSystemBuffer.sCPUVAddr = psDevInfo->sFBInfo.sCPUVAddr; -+ psDevInfo->sSystemBuffer.psDevInfo = psDevInfo; -+ -+ OMAPLFBInitBufferForSwap(&psDevInfo->sSystemBuffer); -+#else -+psDevInfo->sSystemBuffer.sCPUVAddr = 0x100; -+// psDevInfo->sSystemBuffer.ulBufferSize = 600*3200; -+ -+ psDevInfo->sDisplayFormat.pixelformat = 20; -+ psDevInfo->sFBInfo.ulWidth = 800; -+ psDevInfo->sFBInfo.ulHeight = 600; -+ psDevInfo->sFBInfo.ulByteStride = 3200; -+ psDevInfo->sFBInfo.ulFBSize = 8388608; -+ psDevInfo->sFBInfo.ulBufferSize = 600*3200; -+#endif -+ -+ -+ /* -+ Setup the DC Jtable so SRVKM can call into this driver -+ */ -+ psDevInfo->sDCJTable.ui32TableSize = sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE); -+ psDevInfo->sDCJTable.pfnOpenDCDevice = OpenDCDevice; -+ psDevInfo->sDCJTable.pfnCloseDCDevice = CloseDCDevice; -+ psDevInfo->sDCJTable.pfnEnumDCFormats = EnumDCFormats; -+ psDevInfo->sDCJTable.pfnEnumDCDims = EnumDCDims; -+ psDevInfo->sDCJTable.pfnGetDCSystemBuffer = GetDCSystemBuffer; -+ psDevInfo->sDCJTable.pfnGetDCInfo = GetDCInfo; -+ psDevInfo->sDCJTable.pfnGetBufferAddr = GetDCBufferAddr; -+ psDevInfo->sDCJTable.pfnCreateDCSwapChain = CreateDCSwapChain; -+ psDevInfo->sDCJTable.pfnDestroyDCSwapChain = DestroyDCSwapChain; -+ psDevInfo->sDCJTable.pfnSetDCDstRect = SetDCDstRect; -+ psDevInfo->sDCJTable.pfnSetDCSrcRect = SetDCSrcRect; -+ psDevInfo->sDCJTable.pfnSetDCDstColourKey = SetDCDstColourKey; -+ psDevInfo->sDCJTable.pfnSetDCSrcColourKey = SetDCSrcColourKey; -+ psDevInfo->sDCJTable.pfnGetDCBuffers = GetDCBuffers; -+ psDevInfo->sDCJTable.pfnSwapToDCBuffer = SwapToDCBuffer; -+ psDevInfo->sDCJTable.pfnSetDCState = SetDCState; -+ -+ /* Register device with services and retrieve device index */ -+ if(psDevInfo->sPVRJTable.pfnPVRSRVRegisterDCDevice( -+ &psDevInfo->sDCJTable, -+ &psDevInfo->uiPVRDevID) != PVRSRV_OK) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ ": %s: Device %u: PVR Services device registration failed\n", __FUNCTION__, uiFBDevID); -+ -+ goto ErrorDeInitFBDev; -+ } -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX -+ ": Device %u: PVR Device ID: %u\n", -+ psDevInfo->uiFBDevID, psDevInfo->uiPVRDevID)); -+ -+ /* Setup private command processing function table ... */ -+ pfnCmdProcList[DC_FLIP_COMMAND] = ProcessFlip; -+ -+ /* ... and associated sync count(s) */ -+ aui32SyncCountList[DC_FLIP_COMMAND][0] = 0; /* writes */ -+ aui32SyncCountList[DC_FLIP_COMMAND][1] = 10; /* reads */ -+ -+ /* -+ Register private command processing functions with -+ the Command Queue Manager and setup the general -+ command complete function in the devinfo. -+ */ -+ if (psDevInfo->sPVRJTable.pfnPVRSRVRegisterCmdProcList(psDevInfo->uiPVRDevID, -+ &pfnCmdProcList[0], -+ aui32SyncCountList, -+ OMAPLFB_COMMAND_COUNT) != PVRSRV_OK) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ ": %s: Device %u: Couldn't register command processing functions with PVR Services\n", __FUNCTION__, uiFBDevID); -+ goto ErrorUnregisterDevice; -+ } -+ -+ OMAPLFBCreateSwapChainLockInit(psDevInfo); -+ -+ OMAPLFBAtomicBoolInit(&psDevInfo->sBlanked, OMAPLFB_FALSE); -+ OMAPLFBAtomicIntInit(&psDevInfo->sBlankEvents, 0); -+ OMAPLFBAtomicBoolInit(&psDevInfo->sFlushCommands, OMAPLFB_FALSE); -+#if defined(CONFIG_HAS_EARLYSUSPEND) -+ OMAPLFBAtomicBoolInit(&psDevInfo->sEarlySuspendFlag, OMAPLFB_FALSE); -+#endif -+#if defined(SUPPORT_DRI_DRM) -+ OMAPLFBAtomicBoolInit(&psDevInfo->sLeaveVT, OMAPLFB_FALSE); -+#endif -+ return psDevInfo; -+ -+ErrorUnregisterDevice: -+ (void)psDevInfo->sPVRJTable.pfnPVRSRVRemoveDCDevice(psDevInfo->uiPVRDevID); -+ErrorDeInitFBDev: -+ OMAPLFBDeInitFBDev(psDevInfo); -+ErrorFreeDevInfo: -+ OMAPLFBFreeKernelMem(psDevInfo); -+ErrorExit: -+ return NULL; -+} -+ -+OMAPLFB_ERROR OMAPLFBInit(void) -+{ -+ unsigned uiMaxFBDevIDPlusOne = OMAPLFBMaxFBDevIDPlusOne(); -+ unsigned i; -+ unsigned uiDevicesFound = 0; -+ -+ if(OMAPLFBGetLibFuncAddr ("PVRGetDisplayClassJTable", &gpfnGetPVRJTable) != OMAPLFB_OK) -+ { -+ return OMAPLFB_ERROR_INIT_FAILURE; -+ } -+ -+ /* -+ * We search for frame buffer devices backwards, as the last device -+ * registered with PVR Services will be the first device enumerated -+ * by PVR Services. -+ */ -+ for(i = uiMaxFBDevIDPlusOne; i-- != 0;) -+ { -+ OMAPLFB_DEVINFO *psDevInfo = OMAPLFBInitDev(i); -+ -+ if (psDevInfo != NULL) -+ { -+ /* Set the top-level anchor */ -+ OMAPLFBSetDevInfoPtr(psDevInfo->uiFBDevID, psDevInfo); -+ uiDevicesFound++; -+ } -+ } -+ -+ return (uiDevicesFound != 0) ? OMAPLFB_OK : OMAPLFB_ERROR_INIT_FAILURE; -+} -+ -+/* -+ * OMAPLFBDeInitDev -+ * DeInitialises one device -+ */ -+static OMAPLFB_BOOL OMAPLFBDeInitDev(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ PVRSRV_DC_DISP2SRV_KMJTABLE *psPVRJTable = &psDevInfo->sPVRJTable; -+ -+ OMAPLFBCreateSwapChainLockDeInit(psDevInfo); -+ -+ OMAPLFBAtomicBoolDeInit(&psDevInfo->sBlanked); -+ OMAPLFBAtomicIntDeInit(&psDevInfo->sBlankEvents); -+ OMAPLFBAtomicBoolDeInit(&psDevInfo->sFlushCommands); -+#if defined(CONFIG_HAS_EARLYSUSPEND) -+ OMAPLFBAtomicBoolDeInit(&psDevInfo->sEarlySuspendFlag); -+#endif -+#if defined(SUPPORT_DRI_DRM) -+ OMAPLFBAtomicBoolDeInit(&psDevInfo->sLeaveVT); -+#endif -+ psPVRJTable = &psDevInfo->sPVRJTable; -+ -+ if (psPVRJTable->pfnPVRSRVRemoveCmdProcList (psDevInfo->uiPVRDevID, OMAPLFB_COMMAND_COUNT) != PVRSRV_OK) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ ": %s: Device %u: PVR Device %u: Couldn't unregister command processing functions\n", __FUNCTION__, psDevInfo->uiFBDevID, psDevInfo->uiPVRDevID); -+ return OMAPLFB_FALSE; -+ } -+ -+ /* -+ * Remove display class device from kernel services device -+ * register. -+ */ -+ if (psPVRJTable->pfnPVRSRVRemoveDCDevice(psDevInfo->uiPVRDevID) != PVRSRV_OK) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ ": %s: Device %u: PVR Device %u: Couldn't remove device from PVR Services\n", __FUNCTION__, psDevInfo->uiFBDevID, psDevInfo->uiPVRDevID); -+ return OMAPLFB_FALSE; -+ } -+ -+ OMAPLFBDeInitFBDev(psDevInfo); -+ -+ OMAPLFBSetDevInfoPtr(psDevInfo->uiFBDevID, NULL); -+ -+ /* De-allocate data structure */ -+ OMAPLFBFreeKernelMem(psDevInfo); -+ -+ return OMAPLFB_TRUE; -+} -+ -+/* -+ * OMAPLFBDeInit -+ * Deinitialises the display class device component of the FBDev -+ */ -+OMAPLFB_ERROR OMAPLFBDeInit(void) -+{ -+ unsigned uiMaxFBDevIDPlusOne = OMAPLFBMaxFBDevIDPlusOne(); -+ unsigned i; -+ OMAPLFB_BOOL bError = OMAPLFB_FALSE; -+ -+ for(i = 0; i < uiMaxFBDevIDPlusOne; i++) -+ { -+ OMAPLFB_DEVINFO *psDevInfo = OMAPLFBGetDevInfoPtr(i); -+ -+ if (psDevInfo != NULL) -+ { -+ bError |= !OMAPLFBDeInitDev(psDevInfo); -+ } -+ } -+ -+ return (bError) ? OMAPLFB_ERROR_INIT_FAILURE : OMAPLFB_OK; -+} -+ -+/****************************************************************************** -+ End of file (omaplfb_displayclass.c) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti81xx_linux/omaplfb_linux.c b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti81xx_linux/omaplfb_linux.c -new file mode 100644 -index 0000000..8d60356 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti81xx_linux/omaplfb_linux.c -@@ -0,0 +1,1214 @@ -+/*************************************************************************/ /*! -+@Title OMAP linux display driver components -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+ -+*/ /**************************************************************************/ -+ -+/************************************************************************** -+ The 3rd party driver is a specification of an API to integrate the IMG POWERVR -+ Services driver with 3rd Party display hardware. It is NOT a specification for -+ a display controller driver, rather a specification to extend the API for a -+ pre-existing driver for the display hardware. -+ -+ The 3rd party driver interface provides IMG POWERVR client drivers (e.g. PVR2D) -+ with an API abstraction of the system's underlying display hardware, allowing -+ the client drivers to indirectly control the display hardware and access its -+ associated memory. -+ -+ Functions of the API include -+ - query primary surface attributes (width, height, stride, pixel format, CPU -+ physical and virtual address) -+ - swap/flip chain creation and subsequent query of surface attributes -+ - asynchronous display surface flipping, taking account of asynchronous read -+ (flip) and write (render) operations to the display surface -+ -+ Note: having queried surface attributes the client drivers are able to map the -+ display memory to any IMG POWERVR Services device by calling -+ PVRSRVMapDeviceClassMemory with the display surface handle. -+ -+ This code is intended to be an example of how a pre-existing display driver may -+ be extended to support the 3rd Party Display interface to POWERVR Services -+ - IMG is not providing a display driver implementation. -+ **************************************************************************/ -+ -+#include <linux/version.h> -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)) -+#ifndef AUTOCONF_INCLUDED -+#include <linux/config.h> -+#endif -+#endif -+ -+#include <asm/atomic.h> -+ -+#if defined(SUPPORT_DRI_DRM) -+#include <drm/drmP.h> -+#else -+#include <linux/module.h> -+#endif -+ -+#include <linux/kernel.h> -+#include <linux/slab.h> -+#include <linux/hardirq.h> -+#include <linux/mutex.h> -+#include <linux/workqueue.h> -+#include <linux/fb.h> -+#include <linux/console.h> -+#include <linux/omapfb.h> -+#include <linux/mutex.h> -+ -+# include <plat/ti81xx-vpss.h> -+#if defined(PVR_OMAPLFB_DRM_FB) -+#include <plat/display.h> -+#include <linux/omap_gpu.h> -+#else /* defined(PVR_OMAPLFB_DRM_FB) */ -+/* OmapZoom.org OMAP3 2.6.29 kernel tree - Needs mach/vrfb.h -+ * OmapZoom.org OMAP3 2.6.32 kernel tree - No additional header required -+ * OmapZoom.org OMAP4 2.6.33 kernel tree - No additional header required -+ * OmapZoom.org OMAP4 2.6.34 kernel tree - Needs plat/vrfb.h -+ * Sholes 2.6.32 kernel tree - Needs plat/vrfb.h -+ */ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34)) -+#define PVR_OMAPFB3_NEEDS_PLAT_VRFB_H -+#endif -+ -+#if defined(PVR_OMAPFB3_NEEDS_PLAT_VRFB_H) -+#include <plat/vrfb.h> -+#else -+#if defined(PVR_OMAPFB3_NEEDS_MACH_VRFB_H) -+#include <mach/vrfb.h> -+#endif -+#endif -+ -+#if defined(DEBUG) -+#define PVR_DEBUG DEBUG -+#undef DEBUG -+#endif -+#include <omapfb/omapfb.h> -+#if defined(DEBUG) -+#undef DEBUG -+#endif -+#if defined(PVR_DEBUG) -+#define DEBUG PVR_DEBUG -+#undef PVR_DEBUG -+#endif -+#endif /* defined(PVR_OMAPLFB_DRM_FB) */ -+ -+#if defined(CONFIG_DSSCOMP) -+#include <mach/tiler.h> -+#include <video/dsscomp.h> -+#include <plat/dsscomp.h> -+#endif /* defined(CONFIG_DSSCOMP) */ -+ -+#include "img_defs.h" -+#include "servicesext.h" -+#include "kerneldisplay.h" -+#include "omaplfb.h" -+#include "pvrmodule.h" -+#if defined(SUPPORT_DRI_DRM) -+#include "pvr_drm.h" -+#include "3rdparty_dc_drm_shared.h" -+#endif -+ -+#if !defined(PVR_LINUX_USING_WORKQUEUES) -+#error "PVR_LINUX_USING_WORKQUEUES must be defined" -+#endif -+ -+MODULE_SUPPORTED_DEVICE(DEVNAME); -+ -+#if !defined(PVR_OMAPLFB_DRM_FB) -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34)) -+#define OMAP_DSS_DRIVER(drv, dev) struct omap_dss_driver *drv = (dev) != NULL ? (dev)->driver : NULL -+#define OMAP_DSS_MANAGER(man, dev) struct omap_overlay_manager *man = (dev) != NULL ? (dev)->manager : NULL -+#define WAIT_FOR_VSYNC(man) ((man)->wait_for_vsync) -+#else -+#define OMAP_DSS_DRIVER(drv, dev) struct omap_dss_device *drv = (dev) -+#define OMAP_DSS_MANAGER(man, dev) struct omap_dss_device *man = (dev) -+#define WAIT_FOR_VSYNC(man) ((man)->wait_vsync) -+#endif -+#endif /* !defined(PVR_OMAPLFB_DRM_FB) */ -+ -+void *OMAPLFBAllocKernelMem(unsigned long ulSize) -+{ -+ return kmalloc(ulSize, GFP_KERNEL); -+} -+ -+void OMAPLFBFreeKernelMem(void *pvMem) -+{ -+ kfree(pvMem); -+} -+ -+void OMAPLFBCreateSwapChainLockInit(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ mutex_init(&psDevInfo->sCreateSwapChainMutex); -+} -+ -+void OMAPLFBCreateSwapChainLockDeInit(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ mutex_destroy(&psDevInfo->sCreateSwapChainMutex); -+} -+ -+void OMAPLFBCreateSwapChainLock(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ mutex_lock(&psDevInfo->sCreateSwapChainMutex); -+} -+ -+void OMAPLFBCreateSwapChainUnLock(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ mutex_unlock(&psDevInfo->sCreateSwapChainMutex); -+} -+ -+void OMAPLFBAtomicBoolInit(OMAPLFB_ATOMIC_BOOL *psAtomic, OMAPLFB_BOOL bVal) -+{ -+ atomic_set(psAtomic, (int)bVal); -+} -+ -+void OMAPLFBAtomicBoolDeInit(OMAPLFB_ATOMIC_BOOL *psAtomic) -+{ -+} -+ -+void OMAPLFBAtomicBoolSet(OMAPLFB_ATOMIC_BOOL *psAtomic, OMAPLFB_BOOL bVal) -+{ -+ atomic_set(psAtomic, (int)bVal); -+} -+ -+OMAPLFB_BOOL OMAPLFBAtomicBoolRead(OMAPLFB_ATOMIC_BOOL *psAtomic) -+{ -+ return (OMAPLFB_BOOL)atomic_read(psAtomic); -+} -+ -+void OMAPLFBAtomicIntInit(OMAPLFB_ATOMIC_INT *psAtomic, int iVal) -+{ -+ atomic_set(psAtomic, iVal); -+} -+ -+void OMAPLFBAtomicIntDeInit(OMAPLFB_ATOMIC_INT *psAtomic) -+{ -+} -+ -+void OMAPLFBAtomicIntSet(OMAPLFB_ATOMIC_INT *psAtomic, int iVal) -+{ -+ atomic_set(psAtomic, iVal); -+} -+ -+int OMAPLFBAtomicIntRead(OMAPLFB_ATOMIC_INT *psAtomic) -+{ -+ return atomic_read(psAtomic); -+} -+ -+void OMAPLFBAtomicIntInc(OMAPLFB_ATOMIC_INT *psAtomic) -+{ -+ atomic_inc(psAtomic); -+} -+ -+OMAPLFB_ERROR OMAPLFBGetLibFuncAddr (char *szFunctionName, PFN_DC_GET_PVRJTABLE *ppfnFuncTable) -+{ -+ if(strcmp("PVRGetDisplayClassJTable", szFunctionName) != 0) -+ { -+ return (OMAPLFB_ERROR_INVALID_PARAMS); -+ } -+ -+ /* Nothing to do - should be exported from pvrsrv.ko */ -+ *ppfnFuncTable = PVRGetDisplayClassJTable; -+ -+ return (OMAPLFB_OK); -+} -+ -+/* Inset a swap buffer into the swap chain work queue */ -+void OMAPLFBQueueBufferForSwap(OMAPLFB_SWAPCHAIN *psSwapChain, OMAPLFB_BUFFER *psBuffer) -+{ -+ int res = queue_work(psSwapChain->psWorkQueue, &psBuffer->sWork); -+ -+ if (res == 0) -+ { -+ printk(KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Buffer already on work queue\n", __FUNCTION__, psSwapChain->uiFBDevID); -+ } -+} -+ -+/* Process an item on a swap chain work queue */ -+static void WorkQueueHandler(struct work_struct *psWork) -+{ -+ OMAPLFB_BUFFER *psBuffer = container_of(psWork, OMAPLFB_BUFFER, sWork); -+ -+ OMAPLFBSwapHandler(psBuffer); -+} -+ -+/* Create a swap chain work queue */ -+OMAPLFB_ERROR OMAPLFBCreateSwapQueue(OMAPLFB_SWAPCHAIN *psSwapChain) -+{ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) -+ /* -+ * Calling alloc_ordered_workqueue with the WQ_FREEZABLE and -+ * WQ_MEM_RECLAIM flags set, (currently) has the same effect as -+ * calling create_freezable_workqueue. None of the other WQ -+ * flags are valid. Setting WQ_MEM_RECLAIM should allow the -+ * workqueue to continue to service the swap chain in low memory -+ * conditions, preventing the driver from holding on to -+ * resources longer than it needs to. -+ */ -+#if (LINUX_VERSION_CODE == KERNEL_VERSION(2,6,37)) -+ psSwapChain->psWorkQueue = alloc_ordered_workqueue(DEVNAME, WQ_FREEZEABLE | WQ_MEM_RECLAIM); -+#else -+ psSwapChain->psWorkQueue = alloc_ordered_workqueue(DEVNAME, WQ_FREEZABLE | WQ_MEM_RECLAIM); -+#endif -+ -+#else -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)) -+ psSwapChain->psWorkQueue = create_freezable_workqueue(DEVNAME); -+#else -+ /* -+ * Create a single-threaded, freezable, rt-prio workqueue. -+ * Such workqueues are frozen with user threads when a system -+ * suspends, before driver suspend entry points are called. -+ * This ensures this driver will not call into the Linux -+ * framebuffer driver after the latter is suspended. -+ */ -+ psSwapChain->psWorkQueue = __create_workqueue(DEVNAME, 1, 1, 1); -+#endif -+#endif -+ if (psSwapChain->psWorkQueue == NULL) -+ { -+ printk(KERN_ERR DRIVER_PREFIX ": %s: Device %u: Couldn't create workqueue\n", __FUNCTION__, psSwapChain->uiFBDevID); -+ -+ return (OMAPLFB_ERROR_INIT_FAILURE); -+ } -+ -+ return (OMAPLFB_OK); -+} -+ -+/* Prepare buffer for insertion into a swap chain work queue */ -+void OMAPLFBInitBufferForSwap(OMAPLFB_BUFFER *psBuffer) -+{ -+ INIT_WORK(&psBuffer->sWork, WorkQueueHandler); -+} -+ -+/* Destroy a swap chain work queue */ -+void OMAPLFBDestroySwapQueue(OMAPLFB_SWAPCHAIN *psSwapChain) -+{ -+ destroy_workqueue(psSwapChain->psWorkQueue); -+} -+ -+/* Flip display to given buffer */ -+void OMAPLFBFlip(OMAPLFB_DEVINFO *psDevInfo, OMAPLFB_BUFFER *psBuffer) -+{ -+ struct fb_var_screeninfo sFBVar; -+ int res; -+ unsigned long ulYResVirtual; -+ -+ OMAPLFB_CONSOLE_LOCK(); -+ -+ sFBVar = psDevInfo->psLINFBInfo->var; -+ -+ sFBVar.xoffset = 0; -+ sFBVar.yoffset = psBuffer->ulYOffset; -+ -+ ulYResVirtual = psBuffer->ulYOffset + sFBVar.yres; -+ -+#if defined(CONFIG_DSSCOMP) -+ { -+ /* -+ * If using DSSCOMP, we need to use dsscomp queuing for normal -+ * framebuffer updates, so that previously used overlays get -+ * automatically disabled, and manager gets dirtied. We can -+ * do that because DSSCOMP takes ownership of all pipelines on -+ * a manager. -+ */ -+ struct fb_fix_screeninfo sFBFix = psDevInfo->psLINFBInfo->fix; -+ struct dsscomp_setup_dispc_data d = -+ { -+ .num_ovls = 1, -+ .num_mgrs = 1, -+ .mgrs[0].alpha_blending = 1, -+ .ovls[0] = -+ { -+ .cfg = -+ { -+ .win.w = sFBVar.xres, -+ .win.h = sFBVar.yres, -+ .crop.x = sFBVar.xoffset, -+ .crop.y = sFBVar.yoffset, -+ .crop.w = sFBVar.xres, -+ .crop.h = sFBVar.yres, -+ .width = sFBVar.xres_virtual, -+ .height = sFBVar.yres_virtual, -+ .stride = sFBFix.line_length, -+ .enabled = 1, -+ .global_alpha = 255, -+ }, -+ }, -+ }; -+ -+ /* do not map buffer into TILER1D as it is contiguous */ -+ struct tiler_pa_info *pas[] = { NULL }; -+ -+ d.ovls[0].ba = sFBFix.smem_start; -+ omapfb_mode_to_dss_mode(&sFBVar, &d.ovls[0].cfg.color_mode); -+ -+ res = dsscomp_gralloc_queue(&d, pas, true, NULL, NULL); -+ } -+#else /* defined(CONFIG_DSSCOMP) */ -+ /* -+ * PVR_OMAPLFB_DONT_USE_FB_PAN_DISPLAY should be defined to work -+ * around flipping problems seen with the Taal LCDs on Blaze. -+ * The work around is safe to use with other types of screen on Blaze -+ * (e.g. HDMI) and on other platforms (e.g. Panda board). -+ */ -+#if !defined(PVR_OMAPLFB_DONT_USE_FB_PAN_DISPLAY) -+ /* -+ * Attempt to change the virtual screen resolution if it is too -+ * small. Note that fb_set_var also pans the display. -+ */ -+ if (sFBVar.xres_virtual != sFBVar.xres || sFBVar.yres_virtual < ulYResVirtual) -+#endif /* !defined(PVR_OMAPLFB_DONT_USE_FB_PAN_DISPLAY) */ -+ { -+ sFBVar.xres_virtual = sFBVar.xres; -+ sFBVar.yres_virtual = ulYResVirtual; -+ -+ sFBVar.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE; -+ -+ res = fb_set_var(psDevInfo->psLINFBInfo, &sFBVar); -+ if (res != 0) -+ { -+ printk(KERN_ERR DRIVER_PREFIX ": %s: Device %u: fb_set_var failed (Y Offset: %lu, Error: %d)\n", __FUNCTION__, psDevInfo->uiFBDevID, psBuffer->ulYOffset, res); -+ } -+ } -+#if !defined(PVR_OMAPLFB_DONT_USE_FB_PAN_DISPLAY) -+ else -+ { -+ res = fb_pan_display(psDevInfo->psLINFBInfo, &sFBVar); -+ if (res != 0) -+ { -+ printk(KERN_ERR DRIVER_PREFIX ": %s: Device %u: fb_pan_display failed (Y Offset: %lu, Error: %d)\n", __FUNCTION__, psDevInfo->uiFBDevID, psBuffer->ulYOffset, res); -+ } -+ } -+#endif /* !defined(PVR_OMAPLFB_DONT_USE_FB_PAN_DISPLAY) */ -+#endif /* defined(CONFIG_DSSCOMP) */ -+ -+ OMAPLFB_CONSOLE_UNLOCK(); -+} -+ -+#if 0 -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0) -+#if !defined(PVR_OMAPLFB_DRM_FB) || defined(DEBUG) -+static OMAPLFB_BOOL OMAPLFBValidateDSSUpdateMode(enum omap_dss_update_mode eMode) -+{ -+ switch (eMode) -+ { -+ case OMAP_DSS_UPDATE_AUTO: -+ case OMAP_DSS_UPDATE_MANUAL: -+ case OMAP_DSS_UPDATE_DISABLED: -+ return OMAPLFB_TRUE; -+ default: -+ break; -+ } -+ -+ return OMAPLFB_FALSE; -+} -+ -+static OMAPLFB_UPDATE_MODE OMAPLFBFromDSSUpdateMode(enum omap_dss_update_mode eMode) -+{ -+ switch (eMode) -+ { -+ case OMAP_DSS_UPDATE_AUTO: -+ return OMAPLFB_UPDATE_MODE_AUTO; -+ case OMAP_DSS_UPDATE_MANUAL: -+ return OMAPLFB_UPDATE_MODE_MANUAL; -+ case OMAP_DSS_UPDATE_DISABLED: -+ return OMAPLFB_UPDATE_MODE_DISABLED; -+ default: -+ break; -+ } -+ -+ return OMAPLFB_UPDATE_MODE_UNDEFINED; -+} -+#endif -+#endif -+ -+static OMAPLFB_BOOL OMAPLFBValidateUpdateMode(OMAPLFB_UPDATE_MODE eMode) -+{ -+ switch(eMode) -+ { -+ case OMAPLFB_UPDATE_MODE_AUTO: -+ case OMAPLFB_UPDATE_MODE_MANUAL: -+ case OMAPLFB_UPDATE_MODE_DISABLED: -+ return OMAPLFB_TRUE; -+ default: -+ break; -+ } -+ -+ return OMAPLFB_FALSE; -+} -+static enum omap_dss_update_mode OMAPLFBToDSSUpdateMode(OMAPLFB_UPDATE_MODE eMode) -+{ -+ switch(eMode) -+ { -+ case OMAPLFB_UPDATE_MODE_AUTO: -+ return OMAP_DSS_UPDATE_AUTO; -+ case OMAPLFB_UPDATE_MODE_MANUAL: -+ return OMAP_DSS_UPDATE_MANUAL; -+ case OMAPLFB_UPDATE_MODE_DISABLED: -+ return OMAP_DSS_UPDATE_DISABLED; -+ default: -+ break; -+ } -+ -+ return -1; -+} -+#endif -+#if defined(DEBUG) -+static const char *OMAPLFBUpdateModeToString(OMAPLFB_UPDATE_MODE eMode) -+{ -+ switch(eMode) -+ { -+ case OMAPLFB_UPDATE_MODE_AUTO: -+ return "Auto Update Mode"; -+ case OMAPLFB_UPDATE_MODE_MANUAL: -+ return "Manual Update Mode"; -+ case OMAPLFB_UPDATE_MODE_DISABLED: -+ return "Update Mode Disabled"; -+ case OMAPLFB_UPDATE_MODE_UNDEFINED: -+ return "Update Mode Undefined"; -+ default: -+ break; -+ } -+ -+ return "Unknown Update Mode"; -+} -+#if 0 -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0) -+static const char *OMAPLFBDSSUpdateModeToString(enum omap_dss_update_mode eMode) -+{ -+ -+ if (!OMAPLFBValidateDSSUpdateMode(eMode)) -+ { -+ return "Unknown Update Mode"; -+ } -+ -+ return OMAPLFBUpdateModeToString(OMAPLFBFromDSSUpdateMode(eMode)); -+} -+#endif -+#endif -+void OMAPLFBPrintInfo(OMAPLFB_DEVINFO *psDevInfo) -+{ -+#if defined(PVR_OMAPLFB_DRM_FB) -+ struct drm_connector *psConnector; -+ unsigned uConnectors; -+ unsigned uConnector; -+ -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": Device %u: DRM framebuffer\n", psDevInfo->uiFBDevID)); -+ -+ for (psConnector = NULL, uConnectors = 0; -+ (psConnector = omap_fbdev_get_next_connector(psDevInfo->psLINFBInfo, psConnector)) != NULL;) -+ { -+ uConnectors++; -+ } -+ -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": Device %u: Number of screens (DRM connectors): %u\n", psDevInfo->uiFBDevID, uConnectors)); -+ -+ if (uConnectors == 0) -+ { -+ return; -+ } -+ -+ for (psConnector = NULL, uConnector = 0; -+ (psConnector = omap_fbdev_get_next_connector(psDevInfo->psLINFBInfo, psConnector)) != NULL; uConnector++) -+ { -+ enum omap_dss_update_mode eMode = omap_connector_get_update_mode(psConnector); -+ -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": Device %u: Screen %u: %s (%d)\n", psDevInfo->uiFBDevID, uConnector, OMAPLFBDSSUpdateModeToString(eMode), (int)eMode)); -+ -+ } -+#else /* defined(PVR_OMAPLFB_DRM_FB) */ -+ OMAPLFB_UPDATE_MODE eMode = OMAPLFBGetUpdateMode(psDevInfo); -+ -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": Device %u: non-DRM framebuffer\n", psDevInfo->uiFBDevID)); -+ -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": Device %u: %s\n", psDevInfo->uiFBDevID, OMAPLFBUpdateModeToString(eMode))); -+#endif /* defined(PVR_OMAPLFB_DRM_FB) */ -+} -+#endif /* defined(DEBUG) */ -+ -+/* -+ * Get display update mode. -+ * If the mode is AUTO, we can wait for VSync, if desired. -+ */ -+OMAPLFB_UPDATE_MODE OMAPLFBGetUpdateMode(OMAPLFB_DEVINFO *psDevInfo) -+{ -+#if 0 -+#if defined(PVR_OMAPLFB_DRM_FB) -+ struct drm_connector *psConnector; -+ OMAPLFB_UPDATE_MODE eMode = OMAPLFB_UPDATE_MODE_UNDEFINED; -+ -+ /* -+ * There may be multiple displays connected. If at least one -+ * display is manual update mode, report all screens as being -+ * in that mode. -+ */ -+ for (psConnector = NULL; -+ (psConnector = omap_fbdev_get_next_connector(psDevInfo->psLINFBInfo, psConnector)) != NULL;) -+ { -+ switch(omap_connector_get_update_mode(psConnector)) -+ { -+ case OMAP_DSS_UPDATE_MANUAL: -+ eMode = OMAPLFB_UPDATE_MODE_MANUAL; -+ break; -+ case OMAP_DSS_UPDATE_DISABLED: -+ if (eMode == OMAPLFB_UPDATE_MODE_UNDEFINED) -+ { -+ eMode = OMAPLFB_UPDATE_MODE_DISABLED; -+ } -+ break; -+ case OMAP_DSS_UPDATE_AUTO: -+ /* Fall through to default case */ -+ default: -+ /* Asssume auto update is possible */ -+ if (eMode != OMAPLFB_UPDATE_MODE_MANUAL) -+ { -+ eMode = OMAPLFB_UPDATE_MODE_AUTO; -+ } -+ break; -+ } -+ } -+ -+ return eMode; -+#else /* defined(PVR_OMAPLFB_DRM_FB) */ -+ -+ struct omap_dss_device *psDSSDev = fb2display(psDevInfo->psLINFBInfo); -+ OMAP_DSS_DRIVER(psDSSDrv, psDSSDev); -+ -+ enum omap_dss_update_mode eMode; -+ -+ if (psDSSDrv == NULL) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: No DSS device\n", __FUNCTION__, psDevInfo->uiFBDevID)); -+ return OMAPLFB_UPDATE_MODE_UNDEFINED; -+ } -+ -+ if (psDSSDrv->get_update_mode == NULL) -+ { -+ if (strcmp(psDSSDev->name, "hdmi") == 0) -+ { -+ return OMAPLFB_UPDATE_MODE_AUTO; -+ } -+// DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: No get_update_mode function\n", __FUNCTION__, psDevInfo->uiFBDevID)); -+// return OMAPLFB_UPDATE_MODE_UNDEFINED; -+ return OMAPLFB_UPDATE_MODE_AUTO; -+ } -+ -+ eMode = psDSSDrv->get_update_mode(psDSSDev); -+ if (!OMAPLFBValidateDSSUpdateMode(eMode)) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Unknown update mode (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, (int)eMode)); -+ } -+ -+ return OMAPLFBFromDSSUpdateMode(eMode); -+#endif /* defined(PVR_OMAPLFB_DRM_FB) */ -+#endif -+return OMAPLFB_UPDATE_MODE_AUTO; -+} -+ -+/* Set display update mode */ -+OMAPLFB_BOOL OMAPLFBSetUpdateMode(OMAPLFB_DEVINFO *psDevInfo, OMAPLFB_UPDATE_MODE eMode) -+{ -+#if 0 -+#if defined(PVR_OMAPLFB_DRM_FB) -+ struct drm_connector *psConnector; -+ enum omap_dss_update_mode eDSSMode; -+ OMAPLFB_BOOL bSuccess = OMAPLFB_FALSE; -+ OMAPLFB_BOOL bFailure = OMAPLFB_FALSE; -+ -+ if (!OMAPLFBValidateUpdateMode(eMode)) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Unknown update mode (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, (int)eMode)); -+ return OMAPLFB_FALSE; -+ } -+ eDSSMode = OMAPLFBToDSSUpdateMode(eMode); -+ -+ for (psConnector = NULL; -+ (psConnector = omap_fbdev_get_next_connector(psDevInfo->psLINFBInfo, psConnector)) != NULL;) -+ { -+ int iRes = omap_connector_set_update_mode(psConnector, eDSSMode); -+ OMAPLFB_BOOL bRes = (iRes == 0); -+ -+ -+ bSuccess |= bRes; -+ bFailure |= !bRes; -+ } -+ -+ if (!bFailure) -+ { -+ if (!bSuccess) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: No screens\n", __FUNCTION__, psDevInfo->uiFBDevID)); -+ } -+ -+ return OMAPLFB_TRUE; -+ } -+ -+ if (!bSuccess) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Couldn't set %s for any screen\n", __FUNCTION__, psDevInfo->uiFBDevID, OMAPLFBUpdateModeToString(eMode))); -+ return OMAPLFB_FALSE; -+ } -+ -+ if (eMode == OMAPLFB_UPDATE_MODE_AUTO) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Couldn't set %s for all screens\n", __FUNCTION__, psDevInfo->uiFBDevID, OMAPLFBUpdateModeToString(eMode))); -+ return OMAPLFB_FALSE; -+ } -+ -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": %s: Device %u: %s set for some screens\n", __FUNCTION__, psDevInfo->uiFBDevID, OMAPLFBUpdateModeToString(eMode))); -+ -+ return OMAPLFB_TRUE; -+#else /* defined(PVR_OMAPLFB_DRM_FB) */ -+ struct omap_dss_device *psDSSDev = fb2display(psDevInfo->psLINFBInfo); -+ OMAP_DSS_DRIVER(psDSSDrv, psDSSDev); -+ enum omap_dss_update_mode eDSSMode; -+ int res; -+ -+ if (psDSSDrv == NULL || psDSSDrv->set_update_mode == NULL) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Can't set update mode\n", __FUNCTION__, psDevInfo->uiFBDevID)); -+ return OMAPLFB_FALSE; -+ } -+ -+ if (!OMAPLFBValidateUpdateMode(eMode)) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Unknown update mode (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, (int)eMode)); -+ return OMAPLFB_FALSE; -+ } -+ eDSSMode = OMAPLFBToDSSUpdateMode(eMode); -+ -+ res = psDSSDrv->set_update_mode(psDSSDev, eDSSMode); -+ if (res != 0) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: set_update_mode (%s) failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, OMAPLFBDSSUpdateModeToString(eDSSMode), res)); -+ } -+ -+ return (res == 0); -+#endif /* defined(PVR_OMAPLFB_DRM_FB) */ -+#endif -+return 1; -+} -+ -+/* Wait for VSync */ -+OMAPLFB_BOOL OMAPLFBWaitForVSync(OMAPLFB_DEVINFO *psDevInfo) -+{ -+#if 0 -+#if defined(PVR_OMAPLFB_DRM_FB) -+ struct drm_connector *psConnector; -+ -+ for (psConnector = NULL; -+ (psConnector = omap_fbdev_get_next_connector(psDevInfo->psLINFBInfo, psConnector)) != NULL;) -+ { -+ (void) omap_encoder_wait_for_vsync(psConnector->encoder); -+ } -+ -+ return OMAPLFB_TRUE; -+#else /* defined(PVR_OMAPLFB_DRM_FB) */ -+ struct omap_dss_device *psDSSDev = fb2display(psDevInfo->psLINFBInfo); -+ OMAP_DSS_MANAGER(psDSSMan, psDSSDev); -+ -+ if (psDSSMan != NULL && WAIT_FOR_VSYNC(psDSSMan) != NULL) -+ { -+ int res = WAIT_FOR_VSYNC(psDSSMan)(psDSSMan); -+ if (res != 0) -+ { -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: Device %u: Wait for vsync failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, res)); -+ return OMAPLFB_FALSE; -+ } -+ } -+ -+ return OMAPLFB_TRUE; -+#endif /* defined(PVR_OMAPLFB_DRM_FB) */ -+#endif -+ -+#if FBDEV_PRESENT -+ int r; -+ -+ void grpx_irq_wait_handler(void *data) -+ { -+ complete((struct completion *)data); -+ } -+ DECLARE_COMPLETION_ONSTACK(completion); -+ -+ if (vps_grpx_register_isr ((vsync_callback_t)grpx_irq_wait_handler, &completion, psDevInfo->uiFBDevID) != 0) -+ { -+ printk (KERN_WARNING DRIVER_PREFIX ": Failed to register for vsync call back\n"); -+ return OMAPLFB_FALSE; -+ } -+// timeout = wait_for_completion_interruptible_timeout(&completion, timeout); -+ r = wait_for_completion_interruptible(&completion); -+ if (vps_grpx_unregister_isr((vsync_callback_t)grpx_irq_wait_handler , &completion, psDevInfo->uiFBDevID) != 0) -+ { -+ printk (KERN_WARNING DRIVER_PREFIX ": Failed to un-register for vsync call back\n"); -+ return OMAPLFB_FALSE; -+ } -+#endif -+ -+ return OMAPLFB_TRUE; -+ -+} -+ -+/* -+ * Wait for screen to update. If the screen is in manual or auto update -+ * mode, we can call this function to wait for the screen to update. -+ */ -+OMAPLFB_BOOL OMAPLFBManualSync(OMAPLFB_DEVINFO *psDevInfo) -+{ -+#if 0 -+#if defined(PVR_OMAPLFB_DRM_FB) -+ struct drm_connector *psConnector; -+ -+ for (psConnector = NULL; -+ (psConnector = omap_fbdev_get_next_connector(psDevInfo->psLINFBInfo, psConnector)) != NULL; ) -+ { -+ /* Try manual sync first, then try wait for vsync */ -+ if (omap_connector_sync(psConnector) != 0) -+ { -+ (void) omap_encoder_wait_for_vsync(psConnector->encoder); -+ } -+ } -+ -+ return OMAPLFB_TRUE; -+#else /* defined(PVR_OMAPLFB_DRM_FB) */ -+ struct omap_dss_device *psDSSDev = fb2display(psDevInfo->psLINFBInfo); -+ OMAP_DSS_DRIVER(psDSSDrv, psDSSDev); -+ -+ if (psDSSDrv != NULL && psDSSDrv->sync != NULL) -+ { -+ int res = psDSSDrv->sync(psDSSDev); -+ if (res != 0) -+ { -+ printk(KERN_ERR DRIVER_PREFIX ": %s: Device %u: Sync failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, res); -+ return OMAPLFB_FALSE; -+ } -+ } -+ -+ return OMAPLFB_TRUE; -+#endif /* defined(PVR_OMAPLFB_DRM_FB) */ -+#endif -+return OMAPLFB_TRUE; -+} -+ -+/* -+ * If the screen is manual or auto update mode, wait for the screen to -+ * update. -+ */ -+OMAPLFB_BOOL OMAPLFBCheckModeAndSync(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ OMAPLFB_UPDATE_MODE eMode = OMAPLFBGetUpdateMode(psDevInfo); -+ -+ switch(eMode) -+ { -+ case OMAPLFB_UPDATE_MODE_AUTO: -+ case OMAPLFB_UPDATE_MODE_MANUAL: -+ return OMAPLFBManualSync(psDevInfo); -+ default: -+ break; -+ } -+ -+ return OMAPLFB_TRUE; -+} -+ -+/* Linux Framebuffer event notification handler */ -+static int OMAPLFBFrameBufferEvents(struct notifier_block *psNotif, -+ unsigned long event, void *data) -+{ -+ OMAPLFB_DEVINFO *psDevInfo; -+ struct fb_event *psFBEvent = (struct fb_event *)data; -+ struct fb_info *psFBInfo = psFBEvent->info; -+ OMAPLFB_BOOL bBlanked; -+ -+ /* Only interested in blanking events */ -+ if (event != FB_EVENT_BLANK) -+ { -+ return 0; -+ } -+ -+ bBlanked = (*(IMG_INT *)psFBEvent->data != 0) ? OMAPLFB_TRUE: OMAPLFB_FALSE; -+ -+ psDevInfo = OMAPLFBGetDevInfoPtr(psFBInfo->node); -+ -+#if 0 -+ if (psDevInfo != NULL) -+ { -+ if (bBlanked) -+ { -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": %s: Device %u: Blank event received\n", __FUNCTION__, psDevInfo->uiFBDevID)); -+ } -+ else -+ { -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": %s: Device %u: Unblank event received\n", __FUNCTION__, psDevInfo->uiFBDevID)); -+ } -+ } -+ else -+ { -+ DEBUG_PRINTK((KERN_INFO DRIVER_PREFIX ": %s: Device %u: Blank/Unblank event for unknown framebuffer\n", __FUNCTION__, psFBInfo->node)); -+ } -+#endif -+ -+ if (psDevInfo != NULL) -+ { -+ OMAPLFBAtomicBoolSet(&psDevInfo->sBlanked, bBlanked); -+ OMAPLFBAtomicIntInc(&psDevInfo->sBlankEvents); -+ } -+ -+ return 0; -+} -+ -+/* Unblank the screen */ -+OMAPLFB_ERROR OMAPLFBUnblankDisplay(OMAPLFB_DEVINFO *psDevInfo) -+{ -+#ifdef FBDEV_PRESENT -+ int res; -+ -+ OMAPLFB_CONSOLE_LOCK(); -+ res = fb_blank(psDevInfo->psLINFBInfo, 0); -+ OMAPLFB_CONSOLE_UNLOCK(); -+ if (res != 0 && res != -EINVAL) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ ": %s: Device %u: fb_blank failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, res); -+ return (OMAPLFB_ERROR_GENERIC); -+ } -+#endif -+ return (OMAPLFB_OK); -+} -+ -+#ifdef CONFIG_HAS_EARLYSUSPEND -+ -+/* Blank the screen */ -+static void OMAPLFBBlankDisplay(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ OMAPLFB_CONSOLE_LOCK(); -+ fb_blank(psDevInfo->psLINFBInfo, 1); -+ OMAPLFB_CONSOLE_UNLOCK(); -+} -+ -+static void OMAPLFBEarlySuspendHandler(struct early_suspend *h) -+{ -+ unsigned uiMaxFBDevIDPlusOne = OMAPLFBMaxFBDevIDPlusOne(); -+ unsigned i; -+ -+ for (i=0; i < uiMaxFBDevIDPlusOne; i++) -+ { -+ OMAPLFB_DEVINFO *psDevInfo = OMAPLFBGetDevInfoPtr(i); -+ -+ if (psDevInfo != NULL) -+ { -+ OMAPLFBAtomicBoolSet(&psDevInfo->sEarlySuspendFlag, OMAPLFB_TRUE); -+ OMAPLFBBlankDisplay(psDevInfo); -+ } -+ } -+} -+ -+static void OMAPLFBEarlyResumeHandler(struct early_suspend *h) -+{ -+ unsigned uiMaxFBDevIDPlusOne = OMAPLFBMaxFBDevIDPlusOne(); -+ unsigned i; -+ -+ for (i=0; i < uiMaxFBDevIDPlusOne; i++) -+ { -+ OMAPLFB_DEVINFO *psDevInfo = OMAPLFBGetDevInfoPtr(i); -+ -+ if (psDevInfo != NULL) -+ { -+ OMAPLFBUnblankDisplay(psDevInfo); -+ OMAPLFBAtomicBoolSet(&psDevInfo->sEarlySuspendFlag, OMAPLFB_FALSE); -+ } -+ } -+} -+ -+#endif /* CONFIG_HAS_EARLYSUSPEND */ -+ -+/* Set up Linux Framebuffer event notification */ -+OMAPLFB_ERROR OMAPLFBEnableLFBEventNotification(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ int res; -+ OMAPLFB_ERROR eError; -+ -+ /* Set up Linux Framebuffer event notification */ -+ memset(&psDevInfo->sLINNotifBlock, 0, sizeof(psDevInfo->sLINNotifBlock)); -+ -+ psDevInfo->sLINNotifBlock.notifier_call = OMAPLFBFrameBufferEvents; -+ -+ OMAPLFBAtomicBoolSet(&psDevInfo->sBlanked, OMAPLFB_FALSE); -+ OMAPLFBAtomicIntSet(&psDevInfo->sBlankEvents, 0); -+ -+ res = fb_register_client(&psDevInfo->sLINNotifBlock); -+ if (res != 0) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ ": %s: Device %u: fb_register_client failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, res); -+ -+ return (OMAPLFB_ERROR_GENERIC); -+ } -+ -+ eError = OMAPLFBUnblankDisplay(psDevInfo); -+ if (eError != OMAPLFB_OK) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ ": %s: Device %u: UnblankDisplay failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, eError); -+ return eError; -+ } -+ -+#ifdef CONFIG_HAS_EARLYSUSPEND -+ psDevInfo->sEarlySuspend.suspend = OMAPLFBEarlySuspendHandler; -+ psDevInfo->sEarlySuspend.resume = OMAPLFBEarlyResumeHandler; -+ psDevInfo->sEarlySuspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB + 1; -+ register_early_suspend(&psDevInfo->sEarlySuspend); -+#endif -+ -+ return (OMAPLFB_OK); -+} -+ -+/* Disable Linux Framebuffer event notification */ -+OMAPLFB_ERROR OMAPLFBDisableLFBEventNotification(OMAPLFB_DEVINFO *psDevInfo) -+{ -+ int res; -+ -+#ifdef CONFIG_HAS_EARLYSUSPEND -+ unregister_early_suspend(&psDevInfo->sEarlySuspend); -+#endif -+ -+ /* Unregister for Framebuffer events */ -+ res = fb_unregister_client(&psDevInfo->sLINNotifBlock); -+ if (res != 0) -+ { -+ printk(KERN_ERR DRIVER_PREFIX -+ ": %s: Device %u: fb_unregister_client failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, res); -+ return (OMAPLFB_ERROR_GENERIC); -+ } -+ -+ OMAPLFBAtomicBoolSet(&psDevInfo->sBlanked, OMAPLFB_FALSE); -+ -+ return (OMAPLFB_OK); -+} -+ -+#if defined(SUPPORT_DRI_DRM) && defined(PVR_DISPLAY_CONTROLLER_DRM_IOCTL) -+static OMAPLFB_DEVINFO *OMAPLFBPVRDevIDToDevInfo(unsigned uiPVRDevID) -+{ -+ unsigned uiMaxFBDevIDPlusOne = OMAPLFBMaxFBDevIDPlusOne(); -+ unsigned i; -+ -+ for (i=0; i < uiMaxFBDevIDPlusOne; i++) -+ { -+ OMAPLFB_DEVINFO *psDevInfo = OMAPLFBGetDevInfoPtr(i); -+ -+ if (psDevInfo->uiPVRDevID == uiPVRDevID) -+ { -+ return psDevInfo; -+ } -+ } -+ -+ printk(KERN_ERR DRIVER_PREFIX -+ ": %s: PVR Device %u: Couldn't find device\n", __FUNCTION__, uiPVRDevID); -+ -+ return NULL; -+} -+ -+int PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Ioctl)(struct drm_device unref__ *dev, void *arg, struct drm_file unref__ *pFile) -+{ -+ uint32_t *puiArgs; -+ uint32_t uiCmd; -+ unsigned uiPVRDevID; -+ int ret = 0; -+ OMAPLFB_DEVINFO *psDevInfo; -+ -+ if (arg == NULL) -+ { -+ return -EFAULT; -+ } -+ -+ puiArgs = (uint32_t *)arg; -+ uiCmd = puiArgs[PVR_DRM_DISP_ARG_CMD]; -+ uiPVRDevID = puiArgs[PVR_DRM_DISP_ARG_DEV]; -+ -+ psDevInfo = OMAPLFBPVRDevIDToDevInfo(uiPVRDevID); -+ if (psDevInfo == NULL) -+ { -+ return -EINVAL; -+ } -+ -+ -+ switch (uiCmd) -+ { -+ case PVR_DRM_DISP_CMD_LEAVE_VT: -+ case PVR_DRM_DISP_CMD_ENTER_VT: -+ { -+ OMAPLFB_BOOL bLeaveVT = (uiCmd == PVR_DRM_DISP_CMD_LEAVE_VT); -+ DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": %s: PVR Device %u: %s\n", -+ __FUNCTION__, uiPVRDevID, -+ bLeaveVT ? "Leave VT" : "Enter VT")); -+ -+ OMAPLFBCreateSwapChainLock(psDevInfo); -+ -+ OMAPLFBAtomicBoolSet(&psDevInfo->sLeaveVT, bLeaveVT); -+ if (psDevInfo->psSwapChain != NULL) -+ { -+ flush_workqueue(psDevInfo->psSwapChain->psWorkQueue); -+ -+ if (bLeaveVT) -+ { -+ OMAPLFBFlip(psDevInfo, &psDevInfo->sSystemBuffer); -+ (void) OMAPLFBCheckModeAndSync(psDevInfo); -+ } -+ } -+ -+ OMAPLFBCreateSwapChainUnLock(psDevInfo); -+ (void) OMAPLFBUnblankDisplay(psDevInfo); -+ break; -+ } -+ case PVR_DRM_DISP_CMD_ON: -+ case PVR_DRM_DISP_CMD_STANDBY: -+ case PVR_DRM_DISP_CMD_SUSPEND: -+ case PVR_DRM_DISP_CMD_OFF: -+ { -+ int iFBMode; -+#if defined(DEBUG) -+ { -+ const char *pszMode; -+ switch(uiCmd) -+ { -+ case PVR_DRM_DISP_CMD_ON: -+ pszMode = "On"; -+ break; -+ case PVR_DRM_DISP_CMD_STANDBY: -+ pszMode = "Standby"; -+ break; -+ case PVR_DRM_DISP_CMD_SUSPEND: -+ pszMode = "Suspend"; -+ break; -+ case PVR_DRM_DISP_CMD_OFF: -+ pszMode = "Off"; -+ break; -+ default: -+ pszMode = "(Unknown Mode)"; -+ break; -+ } -+ printk(KERN_WARNING DRIVER_PREFIX ": %s: PVR Device %u: Display %s\n", -+ __FUNCTION__, uiPVRDevID, pszMode); -+ } -+#endif -+ switch(uiCmd) -+ { -+ case PVR_DRM_DISP_CMD_ON: -+ iFBMode = FB_BLANK_UNBLANK; -+ break; -+ case PVR_DRM_DISP_CMD_STANDBY: -+ iFBMode = FB_BLANK_HSYNC_SUSPEND; -+ break; -+ case PVR_DRM_DISP_CMD_SUSPEND: -+ iFBMode = FB_BLANK_VSYNC_SUSPEND; -+ break; -+ case PVR_DRM_DISP_CMD_OFF: -+ iFBMode = FB_BLANK_POWERDOWN; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ OMAPLFBCreateSwapChainLock(psDevInfo); -+ -+ if (psDevInfo->psSwapChain != NULL) -+ { -+ flush_workqueue(psDevInfo->psSwapChain->psWorkQueue); -+ } -+ -+ OMAPLFB_CONSOLE_LOCK(); -+ ret = fb_blank(psDevInfo->psLINFBInfo, iFBMode); -+ OMAPLFB_CONSOLE_UNLOCK(); -+ -+ OMAPLFBCreateSwapChainUnLock(psDevInfo); -+ -+ break; -+ } -+ default: -+ { -+ ret = -EINVAL; -+ break; -+ } -+ } -+ -+ return ret; -+} -+#endif -+ -+/* Insert the driver into the kernel */ -+#if defined(SUPPORT_DRI_DRM) -+int PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Init)(struct drm_device unref__ *dev) -+#else -+static int __init OMAPLFB_Init(void) -+#endif -+{ -+ -+ if(OMAPLFBInit() != OMAPLFB_OK) -+ { -+ printk(KERN_ERR DRIVER_PREFIX ": %s: OMAPLFBInit failed\n", __FUNCTION__); -+ return -ENODEV; -+ } -+ -+ return 0; -+ -+} -+ -+/* Remove the driver from the kernel */ -+#if defined(SUPPORT_DRI_DRM) -+void PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Cleanup)(struct drm_device unref__ *dev) -+#else -+static void __exit OMAPLFB_Cleanup(void) -+#endif -+{ -+ if(OMAPLFBDeInit() != OMAPLFB_OK) -+ { -+ printk(KERN_ERR DRIVER_PREFIX ": %s: OMAPLFBDeInit failed\n", __FUNCTION__); -+ } -+} -+ -+#if !defined(SUPPORT_DRI_DRM) -+/* -+ These macro calls define the initialisation and removal functions of the -+ driver. Although they are prefixed `module_', they apply when compiling -+ statically as well; in both cases they define the function the kernel will -+ run to start/stop the driver. -+*/ -+late_initcall(OMAPLFB_Init); -+module_exit(OMAPLFB_Cleanup); -+#endif -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/linux_drm/Kbuild b/drivers/staging/ti-es8-sgx/services4/3rdparty/linux_drm/Kbuild -new file mode 100644 -index 0000000..d01ef39 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/linux_drm/Kbuild -@@ -0,0 +1,69 @@ -+SYS_USING_INTERRUPTS = 1 -+SUPPORT_OMAP3430_OMAPFB3 =1 -+SUPPORT_TI_DSS_FW = 0 -+PVR_LINUX_USING_WORKQUEUES = 1 -+SUPPORT_DRI_DRM =1 -+SYS_CFLAGS.$(SYS_USING_INTERRUPTS) += -DSYS_USING_INTERRUPTS -+SYS_CFLAGS.$(SUPPORT_OMAP3430_OMAPFB3) += -DSUPPORT_OMAP3430_OMAPFB3 -+SYS_CFLAGS.$(SUPPORT_TI_DSS_FW) += -DSUPPORT_TI_DSS_FW -+SYS_CFLAGS.$(PVR_LINUX_USING_WORKQUEUES) += -DPVR_LINUX_USING_WORKQUEUES -+ -+EXT_SOURCE_DIR := $(KERNELDIR)/drivers/gpu/drm -+ -+EXTRA_CFLAGS = -DLINUX \ -+ -DCONFIG_PCI \ -+ -Wno-error \ -+ -I$(KERNELDIR)/include/drm \ -+ -I$(KERNELDIR)/include/linux \ -+ -I$(EXT_SOURCE_DIR) \ -+ $(SYS_CFLAGS.1) \ -+ -+ifeq ($(SUPPORT_DRI_DRM),1) -+EXTRA_CFLAGS += -DPVR_DISPLAY_CONTROLLER_DRM_IOCTL -+ifeq ($(TI_PLATFORM),omap4) -+EXTRA_CFLAGS += -DCONFIG_SLOW_WORK -+endif -+endif -+ -+obj-m := drm.o -+ifeq ($(TI_PLATFORM),omap4) -+drm-y := pvr_drm_stubs.o drm_auth.o drm_bufs.o drm_cache.o drm_context.o drm_dma.o drm_drawable.o drm_drv.o drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \ -+ drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \ -+ drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \ -+ drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o \ -+ drm_crtc.o drm_modes.o drm_edid.o \ -+ drm_info.o drm_debugfs.o drm_encoder_slave.o -+else -+# Works for 2.6.37 till 3.2 kernel -+drm-y := pvr_drm_stubs.o drm_auth.o drm_bufs.o drm_cache.o drm_context.o drm_dma.o drm_drv.o drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \ -+ drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \ -+ drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \ -+ drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o \ -+ drm_crtc.o drm_modes.o drm_edid.o \ -+ drm_info.o drm_debugfs.o drm_encoder_slave.o drm_global.o drm_platform.o drm_trace_points.o -+endif -+ -+# For 3.3 kernel only -+#drm-y := pvr_drm_stubs.o drm_auth.o drm_bufs.o drm_cache.o drm_context.o drm_dma.o drm_drv.o drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \ -+# drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \ -+# drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \ -+# drm_sysfs.o drm_hashtab.o drm_mm.o \ -+# drm_crtc.o drm_modes.o drm_edid.o \ -+# drm_info.o drm_debugfs.o drm_encoder_slave.o drm_global.o drm_platform.o drm_trace_points.o -+ -+# For greater than/equal to 3.4 till 3.8 kernel -+#drm-y := pvr_drm_stubs.o drm_auth.o drm_bufs.o drm_cache.o drm_context.o drm_dma.o drm_drv.o drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \ -+# drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \ -+# drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \ -+# drm_sysfs.o drm_hashtab.o drm_mm.o \ -+# drm_crtc.o drm_modes.o drm_edid.o \ -+# drm_info.o drm_debugfs.o drm_encoder_slave.o drm_global.o drm_platform.o drm_trace_points.o drm_prime.o -+ -+# less than 2.6.32 kernel -+ -+#drm-y := pvr_drm_stubs.o drm_auth.o drm_bufs.o drm_cache.o drm_context.o drm_dma.o drm_drawable.o drm_drv.o drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \ -+# drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \ -+# drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \ -+# drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o \ -+# drm_crtc.o drm_modes.o drm_edid.o \ -+# drm_info.o drm_debugfs.o drm_encoder_slave.o -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/linux_drm/Kbuild.mk b/drivers/staging/ti-es8-sgx/services4/3rdparty/linux_drm/Kbuild.mk -new file mode 100644 -index 0000000..fa91c2d ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/linux_drm/Kbuild.mk -@@ -0,0 +1,86 @@ -+########################################################################### ### -+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+#@License Dual MIT/GPLv2 -+# -+# The contents of this file are subject to the MIT license as set out below. -+# -+# Permission is hereby granted, free of charge, to any person obtaining a copy -+# of this software and associated documentation files (the "Software"), to deal -+# in the Software without restriction, including without limitation the rights -+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+# copies of the Software, and to permit persons to whom the Software is -+# furnished to do so, subject to the following conditions: -+# -+# The above copyright notice and this permission notice shall be included in -+# all copies or substantial portions of the Software. -+# -+# Alternatively, the contents of this file may be used under the terms of -+# the GNU General Public License Version 2 ("GPL") in which case the provisions -+# of GPL are applicable instead of those above. -+# -+# If you wish to allow use of your version of this file only under the terms of -+# GPL, and not to allow others to use your version of this file under the terms -+# of the MIT license, indicate your decision by deleting the provisions above -+# and replace them with the notice and other provisions required by GPL as set -+# out in the file called "GPL-COPYING" included in this distribution. If you do -+# not delete the provisions above, a recipient may use your version of this file -+# under the terms of either the MIT license or GPL. -+# -+# This License is also included in this distribution in the file called -+# "MIT-COPYING". -+# -+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+### ########################################################################### -+ -+$(call must-be-defined,$(SUPPORT_DRI_DRM)) -+ -+DRM_SOURCE_DIR := drivers/gpu/drm -+ -+ccflags-y += \ -+ -Iinclude/drm \ -+ -I$(DRM_SOURCE_DIR) -+ -+drm-y += \ -+ services4/3rdparty/linux_drm/pvr_drm_stubs.o \ -+ external/$(DRM_SOURCE_DIR)/drm_auth.o \ -+ external/$(DRM_SOURCE_DIR)/drm_bufs.o \ -+ external/$(DRM_SOURCE_DIR)/drm_cache.o \ -+ external/$(DRM_SOURCE_DIR)/drm_context.o \ -+ external/$(DRM_SOURCE_DIR)/drm_dma.o \ -+ external/$(DRM_SOURCE_DIR)/drm_drawable.o \ -+ external/$(DRM_SOURCE_DIR)/drm_drv.o \ -+ external/$(DRM_SOURCE_DIR)/drm_fops.o \ -+ external/$(DRM_SOURCE_DIR)/drm_gem.o \ -+ external/$(DRM_SOURCE_DIR)/drm_ioctl.o \ -+ external/$(DRM_SOURCE_DIR)/drm_irq.o \ -+ external/$(DRM_SOURCE_DIR)/drm_lock.o \ -+ external/$(DRM_SOURCE_DIR)/drm_memory.o \ -+ external/$(DRM_SOURCE_DIR)/drm_proc.o \ -+ external/$(DRM_SOURCE_DIR)/drm_stub.o \ -+ external/$(DRM_SOURCE_DIR)/drm_vm.o \ -+ external/$(DRM_SOURCE_DIR)/drm_agpsupport.o \ -+ external/$(DRM_SOURCE_DIR)/drm_scatter.o \ -+ external/$(DRM_SOURCE_DIR)/ati_pcigart.o \ -+ external/$(DRM_SOURCE_DIR)/drm_pci.o \ -+ external/$(DRM_SOURCE_DIR)/drm_sysfs.o \ -+ external/$(DRM_SOURCE_DIR)/drm_hashtab.o \ -+ external/$(DRM_SOURCE_DIR)/drm_sman.o \ -+ external/$(DRM_SOURCE_DIR)/drm_mm.o \ -+ external/$(DRM_SOURCE_DIR)/drm_crtc.o \ -+ external/$(DRM_SOURCE_DIR)/drm_modes.o \ -+ external/$(DRM_SOURCE_DIR)/drm_edid.o \ -+ external/$(DRM_SOURCE_DIR)/drm_info.o \ -+ external/$(DRM_SOURCE_DIR)/drm_debugfs.o \ -+ external/$(DRM_SOURCE_DIR)/drm_encoder_slave.o -+ -+# extra flags for some files -+CFLAGS_pvr_drm_stubs.o := -DCONFIG_PCI -+CFLAGS_drm_drv.o := -DCONFIG_PCI -+CFLAGS_drm_stub.o := -DCONFIG_PCI -+CFLAGS_ati_pcigart.o := -DCONFIG_PCI -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/linux_drm/Linux.mk b/drivers/staging/ti-es8-sgx/services4/3rdparty/linux_drm/Linux.mk -new file mode 100644 -index 0000000..f27c8e7 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/linux_drm/Linux.mk -@@ -0,0 +1,45 @@ -+########################################################################### ### -+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+#@License Dual MIT/GPLv2 -+# -+# The contents of this file are subject to the MIT license as set out below. -+# -+# Permission is hereby granted, free of charge, to any person obtaining a copy -+# of this software and associated documentation files (the "Software"), to deal -+# in the Software without restriction, including without limitation the rights -+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+# copies of the Software, and to permit persons to whom the Software is -+# furnished to do so, subject to the following conditions: -+# -+# The above copyright notice and this permission notice shall be included in -+# all copies or substantial portions of the Software. -+# -+# Alternatively, the contents of this file may be used under the terms of -+# the GNU General Public License Version 2 ("GPL") in which case the provisions -+# of GPL are applicable instead of those above. -+# -+# If you wish to allow use of your version of this file only under the terms of -+# GPL, and not to allow others to use your version of this file under the terms -+# of the MIT license, indicate your decision by deleting the provisions above -+# and replace them with the notice and other provisions required by GPL as set -+# out in the file called "GPL-COPYING" included in this distribution. If you do -+# not delete the provisions above, a recipient may use your version of this file -+# under the terms of either the MIT license or GPL. -+# -+# This License is also included in this distribution in the file called -+# "MIT-COPYING". -+# -+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+### ########################################################################### -+ -+modules := linux_drm -+ -+linux_drm_type := kernel_module -+linux_drm_target := drm.ko -+linux_drm_makefile := $(THIS_DIR)/Kbuild.mk -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/linux_drm/pvr_drm_mod.h b/drivers/staging/ti-es8-sgx/services4/3rdparty/linux_drm/pvr_drm_mod.h -new file mode 100644 -index 0000000..096f11f ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/linux_drm/pvr_drm_mod.h -@@ -0,0 +1,49 @@ -+/*************************************************************************/ /*! -+@Title DRM stub functions -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#ifndef __PVR_DRM_MOD_H__ -+#define __PVR_DRM_MOD_H__ -+ -+int drm_pvr_dev_add(void); -+ -+void drm_pvr_dev_remove(void); -+ -+#endif /* __PVR_DRM_MOD_H__ */ -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/linux_drm/pvr_drm_stubs.c b/drivers/staging/ti-es8-sgx/services4/3rdparty/linux_drm/pvr_drm_stubs.c -new file mode 100644 -index 0000000..4d74af8 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/linux_drm/pvr_drm_stubs.c -@@ -0,0 +1,228 @@ -+/*************************************************************************/ /*! -+@Title DRM stub functions -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+/* -+ * Emulate enough of the PCI layer to allow the Linux DRM module to be used -+ * with a non-PCI device. -+ * Only one device is supported at present. -+ */ -+ -+#include <linux/version.h> -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/pci.h> -+#include <asm/system.h> -+ -+#include "pvr_drm_mod.h" -+ -+#define DRV_MSG_PREFIX_STR "pvr drm: " -+ -+#define SGX_VENDOR_ID 1 -+#define SGX_DEVICE_ID 1 -+#define SGX_SUB_VENDOR_ID 1 -+#define SGX_SUB_DEVICE_ID 1 -+ -+#if defined(DEBUG) -+#define DEBUG_PRINTK(format, args...) printk(format, ## args) -+#else -+#define DEBUG_PRINTK(format, args...) -+#endif -+ -+#define CLEAR_STRUCT(x) memset(&(x), 0, sizeof(x)) -+ -+/* -+ * Don't specify any initialisers for pvr_pci_bus and pvr_pci_dev, as they -+ * will be cleared to zero on unregister. This has to be done for -+ * pvr_pci_dev to prevent a warning from the kernel if the device is -+ * re-registered without unloading the DRM module. -+ */ -+static struct pci_bus pvr_pci_bus; -+static struct pci_dev pvr_pci_dev; -+ -+static bool bDeviceIsRegistered; -+ -+static void -+release_device(struct device *dev) -+{ -+} -+ -+int pci_bus_read_config_dword(struct pci_bus *bus, unsigned int devfn,int where, u32 *val) -+{ -+ return 0; -+ -+} -+ -+ -+ -+int -+drm_pvr_dev_add(void) -+{ -+ int ret; -+ -+ DEBUG_PRINTK(KERN_INFO DRV_MSG_PREFIX_STR "%s\n", __FUNCTION__); -+ -+ if (bDeviceIsRegistered) -+ { -+ DEBUG_PRINTK(KERN_WARNING DRV_MSG_PREFIX_STR "%s: Device already registered\n", __FUNCTION__); -+ return 0; -+ } -+ -+ /* Set the device ID */ -+ pvr_pci_dev.vendor = SGX_VENDOR_ID; -+ pvr_pci_dev.device = SGX_DEVICE_ID; -+ pvr_pci_dev.subsystem_vendor = SGX_SUB_VENDOR_ID; -+ pvr_pci_dev.subsystem_device = SGX_SUB_DEVICE_ID; -+ -+ /* drm_set_busid needs the bus number */ -+ pvr_pci_dev.bus = &pvr_pci_bus; -+ -+ dev_set_name(&pvr_pci_dev.dev, "%s", "SGX"); -+ pvr_pci_dev.dev.release = release_device; -+ -+ ret = device_register(&pvr_pci_dev.dev); -+ if (ret != 0) -+ { -+ printk(KERN_ERR DRV_MSG_PREFIX_STR "%s: device_register failed (%d)\n", __FUNCTION__, ret); -+ } -+ -+ bDeviceIsRegistered = true; -+ -+ return ret; -+} -+EXPORT_SYMBOL(drm_pvr_dev_add); -+ -+void -+drm_pvr_dev_remove(void) -+{ -+ DEBUG_PRINTK(KERN_INFO DRV_MSG_PREFIX_STR "%s\n", __FUNCTION__); -+ -+ if (bDeviceIsRegistered) -+ { -+ DEBUG_PRINTK(KERN_INFO DRV_MSG_PREFIX_STR "%s: Unregistering device\n", __FUNCTION__); -+ -+ device_unregister(&pvr_pci_dev.dev); -+ bDeviceIsRegistered = false; -+ -+ /* Prevent kernel warnings on re-register */ -+ CLEAR_STRUCT(pvr_pci_dev); -+ CLEAR_STRUCT(pvr_pci_bus); -+ } -+ else -+ { -+ DEBUG_PRINTK(KERN_WARNING DRV_MSG_PREFIX_STR "%s: Device not registered\n", __FUNCTION__); -+ } -+} -+EXPORT_SYMBOL(drm_pvr_dev_remove); -+ -+void -+pci_disable_device(struct pci_dev *dev) -+{ -+} -+ -+struct pci_dev * -+pci_dev_get(struct pci_dev *dev) -+{ -+ return dev; -+} -+ -+void -+pci_set_master(struct pci_dev *dev) -+{ -+} -+ -+#define PCI_ID_COMP(field, value) (((value) == PCI_ANY_ID) || \ -+ ((field) == (value))) -+ -+struct pci_dev * -+pci_get_subsys(unsigned int vendor, unsigned int device, -+ unsigned int ss_vendor, unsigned int ss_device, struct pci_dev *from) -+{ -+ if (from == NULL && -+ PCI_ID_COMP(pvr_pci_dev.vendor, vendor) && -+ PCI_ID_COMP(pvr_pci_dev.device, device) && -+ PCI_ID_COMP(pvr_pci_dev.subsystem_vendor, ss_vendor) && -+ PCI_ID_COMP(pvr_pci_dev.subsystem_device, ss_device)) -+ { -+ DEBUG_PRINTK(KERN_INFO DRV_MSG_PREFIX_STR "%s: Found %x %x %x %x\n", __FUNCTION__, vendor, device, ss_vendor, ss_device); -+ -+ return &pvr_pci_dev; -+ } -+ -+ if (from == NULL) -+ { -+ DEBUG_PRINTK(KERN_INFO DRV_MSG_PREFIX_STR "%s: Couldn't find %x %x %x %x\n", __FUNCTION__, vendor, device, ss_vendor, ss_device); -+ } -+ -+ return NULL; -+} -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34)) -+int -+pci_set_dma_mask(struct pci_dev *dev, u64 mask) -+{ -+ return 0; -+} -+#endif -+ -+void -+pci_unregister_driver(struct pci_driver *drv) -+{ -+} -+ -+int -+__pci_register_driver(struct pci_driver *drv, struct module *owner, -+ const char *mod_name) -+{ -+ return 0; -+} -+ -+int -+pci_enable_device(struct pci_dev *dev) -+{ -+ return 0; -+} -+ -+void -+__bad_cmpxchg(volatile void *ptr, int size) -+{ -+ printk(KERN_ERR DRV_MSG_PREFIX_STR "%s: ptr %p size %u\n", -+ __FUNCTION__, ptr, size); -+} -diff --git a/drivers/staging/ti-es8-sgx/services4/include/env/linux/pvr_drm_shared.h b/drivers/staging/ti-es8-sgx/services4/include/env/linux/pvr_drm_shared.h -new file mode 100644 -index 0000000..6ec27dc ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/include/env/linux/pvr_drm_shared.h -@@ -0,0 +1,68 @@ -+/*************************************************************************/ /*! -+@Title PowerVR drm driver shared definitions -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+#if !defined(__PVR_DRM_SHARED_H__) -+#define __PVR_DRM_SHARED_H__ -+ -+#if defined(SUPPORT_DRI_DRM) -+ -+/* DRM command numbers, relative to DRM_COMMAND_BASE */ -+#if defined(SUPPORT_DRI_DRM_EXT) -+#define PVR_DRM_SRVKM_CMD DRM_PVR_RESERVED1 /* Used for PVR Services ioctls */ -+#define PVR_DRM_DISP_CMD DRM_PVR_RESERVED2 /* Reserved for display class driver */ -+#define PVR_DRM_BC_CMD DRM_PVR_RESERVED3 /* Reserved for buffer class driver */ -+#define PVR_DRM_IS_MASTER_CMD DRM_PVR_RESERVED4 /* Are we the DRM master? */ -+#define PVR_DRM_UNPRIV_CMD DRM_PVR_RESERVED5 /* PVR driver unprivileged ioctls */ -+#define PVR_DRM_DBGDRV_CMD DRM_PVR_RESERVED6 /* Debug driver (PDUMP) ioctls */ -+#else /* defined(SUPPORT_DRI_DRM_EXT) */ -+#define PVR_DRM_SRVKM_CMD 0 /* Used for PVR Services ioctls */ -+#define PVR_DRM_DISP_CMD 1 /* Reserved for display class driver */ -+#define PVR_DRM_BC_CMD 2 /* Reserved for buffer class driver */ -+#define PVR_DRM_IS_MASTER_CMD 3 /* Are we the DRM master? */ -+#define PVR_DRM_UNPRIV_CMD 4 /* PVR driver unprivileged ioctls */ -+#define PVR_DRM_DBGDRV_CMD 5 /* Debug driver (PDUMP) ioctls */ -+#endif /* defined(SUPPORT_DRI_DRM_EXT) */ -+ -+/* Subcommands of PVR_DRM_UNPRIV_CMD */ -+#define PVR_DRM_UNPRIV_INIT_SUCCESFUL 0 /* PVR Services init succesful */ -+ -+#endif -+ -+#endif /* defined(__PVR_DRM_SHARED_H__) */ -diff --git a/drivers/staging/ti-es8-sgx/services4/include/kernelbuffer.h b/drivers/staging/ti-es8-sgx/services4/include/kernelbuffer.h -new file mode 100644 -index 0000000..87a17fc ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/include/kernelbuffer.h -@@ -0,0 +1,97 @@ -+/*************************************************************************/ /*! -+@Title buffer device class API structures and prototypes -+ for kernel services to kernel 3rd party buffer device driver -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description provides display device class API structures and prototypes -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#if !defined (__KERNELBUFFER_H__) -+#define __KERNELBUFFER_H__ -+ -+#if defined (__cplusplus) -+extern "C" { -+#endif -+ -+/* -+ Function table and pointers for SRVKM->BUFFER -+*/ -+typedef PVRSRV_ERROR (*PFN_OPEN_BC_DEVICE)(IMG_UINT32, IMG_HANDLE*); -+typedef PVRSRV_ERROR (*PFN_CLOSE_BC_DEVICE)(IMG_UINT32, IMG_HANDLE); -+typedef PVRSRV_ERROR (*PFN_GET_BC_INFO)(IMG_HANDLE, BUFFER_INFO*); -+typedef PVRSRV_ERROR (*PFN_GET_BC_BUFFER)(IMG_HANDLE, IMG_UINT32, PVRSRV_SYNC_DATA*, IMG_HANDLE*); -+ -+typedef struct PVRSRV_BC_SRV2BUFFER_KMJTABLE_TAG -+{ -+ IMG_UINT32 ui32TableSize; -+ PFN_OPEN_BC_DEVICE pfnOpenBCDevice; -+ PFN_CLOSE_BC_DEVICE pfnCloseBCDevice; -+ PFN_GET_BC_INFO pfnGetBCInfo; -+ PFN_GET_BC_BUFFER pfnGetBCBuffer; -+ PFN_GET_BUFFER_ADDR pfnGetBufferAddr; -+ -+} PVRSRV_BC_SRV2BUFFER_KMJTABLE; -+ -+ -+/* -+ Function table and pointers for BUFFER->SRVKM -+*/ -+typedef PVRSRV_ERROR (*PFN_BC_REGISTER_BUFFER_DEV)(PVRSRV_BC_SRV2BUFFER_KMJTABLE*, IMG_UINT32*); -+typedef IMG_VOID (*PFN_BC_SCHEDULE_DEVICES)(IMG_VOID); -+typedef PVRSRV_ERROR (*PFN_BC_REMOVE_BUFFER_DEV)(IMG_UINT32); -+ -+typedef struct PVRSRV_BC_BUFFER2SRV_KMJTABLE_TAG -+{ -+ IMG_UINT32 ui32TableSize; -+ PFN_BC_REGISTER_BUFFER_DEV pfnPVRSRVRegisterBCDevice; -+ PFN_BC_SCHEDULE_DEVICES pfnPVRSRVScheduleDevices; -+ PFN_BC_REMOVE_BUFFER_DEV pfnPVRSRVRemoveBCDevice; -+ -+} PVRSRV_BC_BUFFER2SRV_KMJTABLE, *PPVRSRV_BC_BUFFER2SRV_KMJTABLE; -+ -+/* function to retrieve kernel services function table from kernel services */ -+typedef IMG_BOOL (*PFN_BC_GET_PVRJTABLE) (PPVRSRV_BC_BUFFER2SRV_KMJTABLE); -+ -+/* Prototype for platforms that access the JTable via linkage */ -+IMG_IMPORT IMG_BOOL PVRGetBufferClassJTable(PVRSRV_BC_BUFFER2SRV_KMJTABLE *psJTable); -+ -+#if defined (__cplusplus) -+} -+#endif -+ -+#endif/* #if !defined (__KERNELBUFFER_H__) */ -diff --git a/drivers/staging/ti-es8-sgx/services4/include/kerneldisplay.h b/drivers/staging/ti-es8-sgx/services4/include/kerneldisplay.h -new file mode 100644 -index 0000000..3ebb5db ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/include/kerneldisplay.h -@@ -0,0 +1,238 @@ -+/*************************************************************************/ /*! -+@Title Display device class API structures and prototypes -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Provides display device class API structures and prototypes -+ for kernel services to kernel 3rd party display. -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#if !defined (__KERNELDISPLAY_H__) -+#define __KERNELDISPLAY_H__ -+ -+#if defined (__cplusplus) -+extern "C" { -+#endif -+ -+typedef PVRSRV_ERROR (*PFN_OPEN_DC_DEVICE)(IMG_UINT32, IMG_HANDLE*, PVRSRV_SYNC_DATA*); -+typedef PVRSRV_ERROR (*PFN_CLOSE_DC_DEVICE)(IMG_HANDLE); -+typedef PVRSRV_ERROR (*PFN_ENUM_DC_FORMATS)(IMG_HANDLE, IMG_UINT32*, DISPLAY_FORMAT*); -+typedef PVRSRV_ERROR (*PFN_ENUM_DC_DIMS)(IMG_HANDLE, -+ DISPLAY_FORMAT*, -+ IMG_UINT32*, -+ DISPLAY_DIMS*); -+typedef PVRSRV_ERROR (*PFN_GET_DC_SYSTEMBUFFER)(IMG_HANDLE, IMG_HANDLE*); -+typedef PVRSRV_ERROR (*PFN_GET_DC_INFO)(IMG_HANDLE, DISPLAY_INFO*); -+typedef PVRSRV_ERROR (*PFN_CREATE_DC_SWAPCHAIN)(IMG_HANDLE, -+ IMG_UINT32, -+ DISPLAY_SURF_ATTRIBUTES*, -+ DISPLAY_SURF_ATTRIBUTES*, -+ IMG_UINT32, -+ PVRSRV_SYNC_DATA**, -+ IMG_UINT32, -+ IMG_HANDLE*, -+ IMG_UINT32*); -+typedef PVRSRV_ERROR (*PFN_DESTROY_DC_SWAPCHAIN)(IMG_HANDLE, -+ IMG_HANDLE); -+typedef PVRSRV_ERROR (*PFN_SET_DC_DSTRECT)(IMG_HANDLE, IMG_HANDLE, IMG_RECT*); -+typedef PVRSRV_ERROR (*PFN_SET_DC_SRCRECT)(IMG_HANDLE, IMG_HANDLE, IMG_RECT*); -+typedef PVRSRV_ERROR (*PFN_SET_DC_DSTCK)(IMG_HANDLE, IMG_HANDLE, IMG_UINT32); -+typedef PVRSRV_ERROR (*PFN_SET_DC_SRCCK)(IMG_HANDLE, IMG_HANDLE, IMG_UINT32); -+typedef PVRSRV_ERROR (*PFN_GET_DC_BUFFERS)(IMG_HANDLE, -+ IMG_HANDLE, -+ IMG_UINT32*, -+ IMG_HANDLE*); -+typedef PVRSRV_ERROR (*PFN_SWAP_TO_DC_BUFFER)(IMG_HANDLE, -+ IMG_HANDLE, -+ IMG_UINT32, -+ IMG_HANDLE, -+ IMG_UINT32, -+ IMG_RECT*); -+typedef IMG_VOID (*PFN_QUERY_SWAP_COMMAND_ID)(IMG_HANDLE, IMG_HANDLE, IMG_HANDLE, IMG_HANDLE, IMG_UINT16*, IMG_BOOL*); -+typedef IMG_VOID (*PFN_SET_DC_STATE)(IMG_HANDLE, IMG_UINT32); -+ -+/* -+ Function table for SRVKM->DISPLAY -+*/ -+typedef struct PVRSRV_DC_SRV2DISP_KMJTABLE_TAG -+{ -+ IMG_UINT32 ui32TableSize; -+ PFN_OPEN_DC_DEVICE pfnOpenDCDevice; -+ PFN_CLOSE_DC_DEVICE pfnCloseDCDevice; -+ PFN_ENUM_DC_FORMATS pfnEnumDCFormats; -+ PFN_ENUM_DC_DIMS pfnEnumDCDims; -+ PFN_GET_DC_SYSTEMBUFFER pfnGetDCSystemBuffer; -+ PFN_GET_DC_INFO pfnGetDCInfo; -+ PFN_GET_BUFFER_ADDR pfnGetBufferAddr; -+ PFN_CREATE_DC_SWAPCHAIN pfnCreateDCSwapChain; -+ PFN_DESTROY_DC_SWAPCHAIN pfnDestroyDCSwapChain; -+ PFN_SET_DC_DSTRECT pfnSetDCDstRect; -+ PFN_SET_DC_SRCRECT pfnSetDCSrcRect; -+ PFN_SET_DC_DSTCK pfnSetDCDstColourKey; -+ PFN_SET_DC_SRCCK pfnSetDCSrcColourKey; -+ PFN_GET_DC_BUFFERS pfnGetDCBuffers; -+ PFN_SWAP_TO_DC_BUFFER pfnSwapToDCBuffer; -+ PFN_SET_DC_STATE pfnSetDCState; -+ PFN_QUERY_SWAP_COMMAND_ID pfnQuerySwapCommandID; -+ -+} PVRSRV_DC_SRV2DISP_KMJTABLE; -+ -+/* ISR callback pfn prototype */ -+typedef IMG_BOOL (*PFN_ISR_HANDLER)(IMG_VOID*); -+ -+/* -+ functions exported by kernel services for use by 3rd party kernel display class device driver -+*/ -+typedef PVRSRV_ERROR (*PFN_DC_REGISTER_DISPLAY_DEV)(PVRSRV_DC_SRV2DISP_KMJTABLE*, IMG_UINT32*); -+typedef PVRSRV_ERROR (*PFN_DC_REMOVE_DISPLAY_DEV)(IMG_UINT32); -+typedef PVRSRV_ERROR (*PFN_DC_OEM_FUNCTION)(IMG_UINT32, IMG_VOID*, IMG_UINT32, IMG_VOID*, IMG_UINT32); -+typedef PVRSRV_ERROR (*PFN_DC_REGISTER_COMMANDPROCLIST)(IMG_UINT32, PPFN_CMD_PROC,IMG_UINT32[][2], IMG_UINT32); -+typedef PVRSRV_ERROR (*PFN_DC_REMOVE_COMMANDPROCLIST)(IMG_UINT32, IMG_UINT32); -+typedef IMG_VOID (*PFN_DC_CMD_COMPLETE)(IMG_HANDLE, IMG_BOOL); -+typedef PVRSRV_ERROR (*PFN_DC_REGISTER_SYS_ISR)(PFN_ISR_HANDLER, IMG_VOID*, IMG_UINT32, IMG_UINT32); -+typedef PVRSRV_ERROR (*PFN_DC_REGISTER_POWER)(IMG_UINT32, PFN_PRE_POWER, PFN_POST_POWER, -+ PFN_PRE_CLOCKSPEED_CHANGE, PFN_POST_CLOCKSPEED_CHANGE, -+ IMG_HANDLE, PVRSRV_DEV_POWER_STATE, PVRSRV_DEV_POWER_STATE); -+ -+typedef struct _PVRSRV_KERNEL_MEM_INFO_* PDC_MEM_INFO; -+ -+typedef PVRSRV_ERROR (*PFN_DC_MEMINFO_GET_CPU_VADDR)(PDC_MEM_INFO, IMG_CPU_VIRTADDR *pVAddr); -+typedef PVRSRV_ERROR (*PFN_DC_MEMINFO_GET_CPU_PADDR)(PDC_MEM_INFO, IMG_SIZE_T uByteOffset, IMG_CPU_PHYADDR *pPAddr); -+typedef PVRSRV_ERROR (*PFN_DC_MEMINFO_GET_BYTE_SIZE)(PDC_MEM_INFO, IMG_SIZE_T *uByteSize); -+typedef IMG_BOOL (*PFN_DC_MEMINFO_IS_PHYS_CONTIG)(PDC_MEM_INFO); -+ -+/* -+ Function table for DISPLAY->SRVKM -+*/ -+typedef struct PVRSRV_DC_DISP2SRV_KMJTABLE_TAG -+{ -+ IMG_UINT32 ui32TableSize; -+ PFN_DC_REGISTER_DISPLAY_DEV pfnPVRSRVRegisterDCDevice; -+ PFN_DC_REMOVE_DISPLAY_DEV pfnPVRSRVRemoveDCDevice; -+ PFN_DC_OEM_FUNCTION pfnPVRSRVOEMFunction; -+ PFN_DC_REGISTER_COMMANDPROCLIST pfnPVRSRVRegisterCmdProcList; -+ PFN_DC_REMOVE_COMMANDPROCLIST pfnPVRSRVRemoveCmdProcList; -+ PFN_DC_CMD_COMPLETE pfnPVRSRVCmdComplete; -+ PFN_DC_REGISTER_SYS_ISR pfnPVRSRVRegisterSystemISRHandler; -+ PFN_DC_REGISTER_POWER pfnPVRSRVRegisterPowerDevice; -+ PFN_DC_CMD_COMPLETE pfnPVRSRVFreeCmdCompletePacket; -+ PFN_DC_MEMINFO_GET_CPU_VADDR pfnPVRSRVDCMemInfoGetCpuVAddr; -+ PFN_DC_MEMINFO_GET_CPU_PADDR pfnPVRSRVDCMemInfoGetCpuPAddr; -+ PFN_DC_MEMINFO_GET_BYTE_SIZE pfnPVRSRVDCMemInfoGetByteSize; -+ PFN_DC_MEMINFO_IS_PHYS_CONTIG pfnPVRSRVDCMemInfoIsPhysContig; -+ -+} PVRSRV_DC_DISP2SRV_KMJTABLE, *PPVRSRV_DC_DISP2SRV_KMJTABLE; -+ -+ -+typedef struct DISPLAYCLASS_FLIP_COMMAND_TAG -+{ -+ /* Ext Device Handle */ -+ IMG_HANDLE hExtDevice; -+ -+ /* Ext SwapChain Handle */ -+ IMG_HANDLE hExtSwapChain; -+ -+ /* Ext Buffer Handle (Buffer to Flip to) */ -+ IMG_HANDLE hExtBuffer; -+ -+ /* private tag */ -+ IMG_HANDLE hPrivateTag; -+ -+ /* number of clip rects */ -+ IMG_UINT32 ui32ClipRectCount; -+ -+ /* clip rects */ -+ IMG_RECT *psClipRect; -+ -+ /* number of vsync intervals between successive flips */ -+ IMG_UINT32 ui32SwapInterval; -+ -+} DISPLAYCLASS_FLIP_COMMAND; -+ -+ -+typedef struct DISPLAYCLASS_FLIP_COMMAND2_TAG -+{ -+ /* Ext Device Handle */ -+ IMG_HANDLE hExtDevice; -+ -+ /* Ext SwapChain Handle */ -+ IMG_HANDLE hExtSwapChain; -+ -+ /* Unused field, padding for compatibility with above structure */ -+ IMG_HANDLE hUnused; -+ -+ /* number of vsync intervals between successive flips */ -+ IMG_UINT32 ui32SwapInterval; -+ -+ /* private data from userspace */ -+ IMG_PVOID pvPrivData; -+ -+ /* length of private data in bytes */ -+ IMG_UINT32 ui32PrivDataLength; -+ -+ /* meminfos */ -+ PDC_MEM_INFO *ppsMemInfos; -+ -+ /* number of meminfos */ -+ IMG_UINT32 ui32NumMemInfos; -+ -+} DISPLAYCLASS_FLIP_COMMAND2; -+ -+/* start command IDs from 0 */ -+#define DC_FLIP_COMMAND 0 -+ -+/* States used in PFN_SET_DC_STATE */ -+#define DC_STATE_NO_FLUSH_COMMANDS 0 -+#define DC_STATE_FLUSH_COMMANDS 1 -+#define DC_STATE_FORCE_SWAP_TO_SYSTEM 2 -+ -+/* function to retrieve kernel services function table from kernel services */ -+typedef IMG_BOOL (*PFN_DC_GET_PVRJTABLE)(PPVRSRV_DC_DISP2SRV_KMJTABLE); -+ -+/* Prototype for platforms that access the JTable via linkage */ -+IMG_IMPORT IMG_BOOL PVRGetDisplayClassJTable(PVRSRV_DC_DISP2SRV_KMJTABLE *psJTable); -+ -+ -+#if defined (__cplusplus) -+} -+#endif -+ -+#endif/* #if !defined (__KERNELDISPLAY_H__) */ -+ -+/****************************************************************************** -+ End of file (kerneldisplay.h) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/include/pdump.h b/drivers/staging/ti-es8-sgx/services4/include/pdump.h -new file mode 100644 -index 0000000..3341040 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/include/pdump.h -@@ -0,0 +1,50 @@ -+/*************************************************************************/ /*! -+@Title PDUMP flags definitions. -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+#ifndef _SERVICES_PDUMP_H_ -+#define _SERVICES_PDUMP_H_ -+ -+#define PDUMP_FLAGS_NEVER 0x08000000U -+#define PDUMP_FLAGS_LASTFRAME 0x10000000U -+#define PDUMP_FLAGS_RESETLFBUFFER 0x20000000U -+#define PDUMP_FLAGS_CONTINUOUS 0x40000000U -+#define PDUMP_FLAGS_PERSISTENT 0x80000000U -+ -+#endif /* _SERVICES_PDUMP_H_ */ -diff --git a/drivers/staging/ti-es8-sgx/services4/include/pvr_bridge.h b/drivers/staging/ti-es8-sgx/services4/include/pvr_bridge.h -new file mode 100644 -index 0000000..ebf4846 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/include/pvr_bridge.h -@@ -0,0 +1,1851 @@ -+/*************************************************************************/ /*! -+@Title PVR Bridge Functionality -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Header for the PVR Bridge code -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#ifndef __PVR_BRIDGE_H__ -+#define __PVR_BRIDGE_H__ -+ -+#if defined (__cplusplus) -+extern "C" { -+#endif -+ -+#include "servicesint.h" -+ -+/* -+ * Bridge Cmd Ids -+ */ -+ -+ -+#ifdef __linux__ -+ -+ #include <linux/ioctl.h> -+ /*!< Nov 2006: according to ioctl-number.txt 'g' wasn't in use. */ -+ #define PVRSRV_IOC_GID 'g' -+ #define PVRSRV_IO(INDEX) _IO(PVRSRV_IOC_GID, INDEX, PVRSRV_BRIDGE_PACKAGE) -+ #define PVRSRV_IOW(INDEX) _IOW(PVRSRV_IOC_GID, INDEX, PVRSRV_BRIDGE_PACKAGE) -+ #define PVRSRV_IOR(INDEX) _IOR(PVRSRV_IOC_GID, INDEX, PVRSRV_BRIDGE_PACKAGE) -+ #define PVRSRV_IOWR(INDEX) _IOWR(PVRSRV_IOC_GID, INDEX, PVRSRV_BRIDGE_PACKAGE) -+ -+#else /* __linux__ */ -+ -+ #if defined(__QNXNTO__) -+ #define PVRSRV_IOC_GID (0x0UL) -+ #else -+ #error Unknown platform: Cannot define ioctls -+ #endif -+ -+ #define PVRSRV_IO(INDEX) (PVRSRV_IOC_GID + (INDEX)) -+ #define PVRSRV_IOW(INDEX) (PVRSRV_IOC_GID + (INDEX)) -+ #define PVRSRV_IOR(INDEX) (PVRSRV_IOC_GID + (INDEX)) -+ #define PVRSRV_IOWR(INDEX) (PVRSRV_IOC_GID + (INDEX)) -+ -+ #define PVRSRV_BRIDGE_BASE PVRSRV_IOC_GID -+#endif /* __linux__ */ -+ -+ -+/* -+ * Note *REMEMBER* to update PVRSRV_BRIDGE_LAST_CMD (below) if you add any new -+ * bridge commands! -+ */ -+ -+#define PVRSRV_BRIDGE_CORE_CMD_FIRST 0UL -+#define PVRSRV_BRIDGE_ENUM_DEVICES PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+0) /*!< enumerate device bridge index */ -+#define PVRSRV_BRIDGE_ACQUIRE_DEVICEINFO PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+1) /*!< acquire device data bridge index */ -+#define PVRSRV_BRIDGE_RELEASE_DEVICEINFO PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+2) /*!< release device data bridge index */ -+#define PVRSRV_BRIDGE_CREATE_DEVMEMCONTEXT PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+3) /*!< create device addressable memory context */ -+#define PVRSRV_BRIDGE_DESTROY_DEVMEMCONTEXT PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+4) /*!< destroy device addressable memory context */ -+#define PVRSRV_BRIDGE_GET_DEVMEM_HEAPINFO PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+5) /*!< get device memory heap info */ -+#define PVRSRV_BRIDGE_ALLOC_DEVICEMEM PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+6) /*!< alloc device memory bridge index */ -+#define PVRSRV_BRIDGE_FREE_DEVICEMEM PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+7) /*!< free device memory bridge index */ -+#define PVRSRV_BRIDGE_GETFREE_DEVICEMEM PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+8) /*!< get free device memory bridge index */ -+#define PVRSRV_BRIDGE_CREATE_COMMANDQUEUE PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+9) /*!< create Cmd Q bridge index */ -+#define PVRSRV_BRIDGE_DESTROY_COMMANDQUEUE PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+10) /*!< destroy Cmd Q bridge index */ -+#define PVRSRV_BRIDGE_MHANDLE_TO_MMAP_DATA PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+11) /*!< generate mmap data from a memory handle */ -+#define PVRSRV_BRIDGE_CONNECT_SERVICES PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+12) /*!< services connect bridge index */ -+#define PVRSRV_BRIDGE_DISCONNECT_SERVICES PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+13) /*!< services disconnect bridge index */ -+#define PVRSRV_BRIDGE_WRAP_DEVICE_MEM PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+14) /*!< wrap device memory bridge index */ -+#define PVRSRV_BRIDGE_GET_DEVICEMEMINFO PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+15) /*!< read the kernel meminfo record */ -+#define PVRSRV_BRIDGE_RESERVE_DEV_VIRTMEM PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+16) -+#define PVRSRV_BRIDGE_FREE_DEV_VIRTMEM PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+17) -+#define PVRSRV_BRIDGE_MAP_EXT_MEMORY PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+18) -+#define PVRSRV_BRIDGE_UNMAP_EXT_MEMORY PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+19) -+#define PVRSRV_BRIDGE_MAP_DEV_MEMORY PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+20) -+#define PVRSRV_BRIDGE_UNMAP_DEV_MEMORY PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+21) -+#define PVRSRV_BRIDGE_MAP_DEVICECLASS_MEMORY PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+22) -+#define PVRSRV_BRIDGE_UNMAP_DEVICECLASS_MEMORY PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+23) -+#define PVRSRV_BRIDGE_MAP_MEM_INFO_TO_USER PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+24) -+#define PVRSRV_BRIDGE_UNMAP_MEM_INFO_FROM_USER PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+25) -+#define PVRSRV_BRIDGE_EXPORT_DEVICEMEM PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+26) -+#define PVRSRV_BRIDGE_RELEASE_MMAP_DATA PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+27) -+#define PVRSRV_BRIDGE_CHG_DEV_MEM_ATTRIBS PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+28) -+#define PVRSRV_BRIDGE_MAP_DEV_MEMORY_2 PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+29) -+#define PVRSRV_BRIDGE_EXPORT_DEVICEMEM_2 PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+30) -+#if defined (SUPPORT_ION) -+#define PVRSRV_BRIDGE_MAP_ION_HANDLE PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+31) -+#define PVRSRV_BRIDGE_UNMAP_ION_HANDLE PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST+32) -+#define PVRSRV_BRIDGE_CORE_CMD_LAST (PVRSRV_BRIDGE_CORE_CMD_FIRST+32) -+#else -+#define PVRSRV_BRIDGE_CORE_CMD_LAST (PVRSRV_BRIDGE_CORE_CMD_FIRST+30) -+#endif -+/* SIM */ -+#define PVRSRV_BRIDGE_SIM_CMD_FIRST (PVRSRV_BRIDGE_CORE_CMD_LAST+1) -+#define PVRSRV_BRIDGE_PROCESS_SIMISR_EVENT PVRSRV_IOWR(PVRSRV_BRIDGE_SIM_CMD_FIRST+0) /*!< RTSIM pseudo ISR */ -+#define PVRSRV_BRIDGE_REGISTER_SIM_PROCESS PVRSRV_IOWR(PVRSRV_BRIDGE_SIM_CMD_FIRST+1) /*!< Register RTSIM process thread */ -+#define PVRSRV_BRIDGE_UNREGISTER_SIM_PROCESS PVRSRV_IOWR(PVRSRV_BRIDGE_SIM_CMD_FIRST+2) /*!< Unregister RTSIM process thread */ -+#define PVRSRV_BRIDGE_SIM_CMD_LAST (PVRSRV_BRIDGE_SIM_CMD_FIRST+2) -+ -+/* User Mapping */ -+#define PVRSRV_BRIDGE_MAPPING_CMD_FIRST (PVRSRV_BRIDGE_SIM_CMD_LAST+1) -+#define PVRSRV_BRIDGE_MAPPHYSTOUSERSPACE PVRSRV_IOWR(PVRSRV_BRIDGE_MAPPING_CMD_FIRST+0) /*!< map CPU phys to user space */ -+#define PVRSRV_BRIDGE_UNMAPPHYSTOUSERSPACE PVRSRV_IOWR(PVRSRV_BRIDGE_MAPPING_CMD_FIRST+1) /*!< unmap CPU phys to user space */ -+#define PVRSRV_BRIDGE_GETPHYSTOUSERSPACEMAP PVRSRV_IOWR(PVRSRV_BRIDGE_MAPPING_CMD_FIRST+2) /*!< get user copy of Phys to Lin loopup table */ -+#define PVRSRV_BRIDGE_MAPPING_CMD_LAST (PVRSRV_BRIDGE_MAPPING_CMD_FIRST+2) -+ -+#define PVRSRV_BRIDGE_STATS_CMD_FIRST (PVRSRV_BRIDGE_MAPPING_CMD_LAST+1) -+#define PVRSRV_BRIDGE_GET_FB_STATS PVRSRV_IOWR(PVRSRV_BRIDGE_STATS_CMD_FIRST+0) /*!< Get FB memory stats */ -+#define PVRSRV_BRIDGE_STATS_CMD_LAST (PVRSRV_BRIDGE_STATS_CMD_FIRST+0) -+ -+/* API to retrieve misc. info. from services */ -+#define PVRSRV_BRIDGE_MISC_CMD_FIRST (PVRSRV_BRIDGE_STATS_CMD_LAST+1) -+#define PVRSRV_BRIDGE_GET_MISC_INFO PVRSRV_IOWR(PVRSRV_BRIDGE_MISC_CMD_FIRST+0) /*!< misc. info. */ -+#define PVRSRV_BRIDGE_RELEASE_MISC_INFO PVRSRV_IOWR(PVRSRV_BRIDGE_MISC_CMD_FIRST+1) /*!< misc. info. */ -+#define PVRSRV_BRIDGE_MISC_CMD_LAST (PVRSRV_BRIDGE_MISC_CMD_FIRST+1) -+ -+/* Overlay ioctls */ -+ -+#if defined (SUPPORT_OVERLAY_ROTATE_BLIT) -+#define PVRSRV_BRIDGE_OVERLAY_CMD_FIRST (PVRSRV_BRIDGE_MISC_CMD_LAST+1) -+#define PVRSRV_BRIDGE_INIT_3D_OVL_BLT_RES PVRSRV_IOWR(PVRSRV_BRIDGE_OVERLAY_CMD_FIRST+0) /*!< 3D Overlay rotate blit init */ -+#define PVRSRV_BRIDGE_DEINIT_3D_OVL_BLT_RES PVRSRV_IOWR(PVRSRV_BRIDGE_OVERLAY_CMD_FIRST+1) /*!< 3D Overlay rotate blit deinit */ -+#define PVRSRV_BRIDGE_OVERLAY_CMD_LAST (PVRSRV_BRIDGE_OVERLAY_CMD_FIRST+1) -+#else -+#define PVRSRV_BRIDGE_OVERLAY_CMD_LAST PVRSRV_BRIDGE_MISC_CMD_LAST -+#endif -+ -+/* PDUMP */ -+#if defined(PDUMP) -+#define PVRSRV_BRIDGE_PDUMP_CMD_FIRST (PVRSRV_BRIDGE_OVERLAY_CMD_LAST+1) -+#define PVRSRV_BRIDGE_PDUMP_INIT PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+0) /*!< pdump command structure */ -+#define PVRSRV_BRIDGE_PDUMP_MEMPOL PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+1) /*!< pdump command structure */ -+#define PVRSRV_BRIDGE_PDUMP_DUMPMEM PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+2) /*!< pdump command structure */ -+#define PVRSRV_BRIDGE_PDUMP_REG PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+3) /*!< pdump command structure */ -+#define PVRSRV_BRIDGE_PDUMP_REGPOL PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+4) /*!< pdump command structure */ -+#define PVRSRV_BRIDGE_PDUMP_COMMENT PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+5) /*!< pdump command structure */ -+#define PVRSRV_BRIDGE_PDUMP_SETFRAME PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+6) /*!< pdump command structure */ -+#define PVRSRV_BRIDGE_PDUMP_ISCAPTURING PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+7) /*!< pdump command structure */ -+#define PVRSRV_BRIDGE_PDUMP_DUMPBITMAP PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+8) /*!< pdump command structure */ -+#define PVRSRV_BRIDGE_PDUMP_DUMPREADREG PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+9) /*!< pdump command structure */ -+#define PVRSRV_BRIDGE_PDUMP_SYNCPOL PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+10) /*!< pdump command structure */ -+#define PVRSRV_BRIDGE_PDUMP_DUMPSYNC PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+11) /*!< pdump command structure */ -+#define PVRSRV_BRIDGE_PDUMP_MEMPAGES PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+12) /*!< pdump command structure */ -+#define PVRSRV_BRIDGE_PDUMP_DRIVERINFO PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+13) /*!< pdump command structure */ -+#define PVRSRV_BRIDGE_PDUMP_DUMPPDDEVPADDR PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+15) /*!< pdump command structure */ -+#define PVRSRV_BRIDGE_PDUMP_CYCLE_COUNT_REG_READ PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+16) -+#define PVRSRV_BRIDGE_PDUMP_STARTINITPHASE PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+17) -+#define PVRSRV_BRIDGE_PDUMP_STOPINITPHASE PVRSRV_IOWR(PVRSRV_BRIDGE_PDUMP_CMD_FIRST+18) -+#define PVRSRV_BRIDGE_PDUMP_CMD_LAST (PVRSRV_BRIDGE_PDUMP_CMD_FIRST+18) -+#else -+/* Note we are carefull here not to leave a large gap in the ioctl numbers. -+ * (Some ports may use these values to index into an array where large gaps can -+ * waste memory) */ -+#define PVRSRV_BRIDGE_PDUMP_CMD_LAST PVRSRV_BRIDGE_OVERLAY_CMD_LAST -+#endif -+ -+/* DisplayClass APIs */ -+#define PVRSRV_BRIDGE_OEM_CMD_FIRST (PVRSRV_BRIDGE_PDUMP_CMD_LAST+1) -+#define PVRSRV_BRIDGE_GET_OEMJTABLE PVRSRV_IOWR(PVRSRV_BRIDGE_OEM_CMD_FIRST+0) /*!< Get OEM Jtable */ -+#define PVRSRV_BRIDGE_OEM_CMD_LAST (PVRSRV_BRIDGE_OEM_CMD_FIRST+0) -+ -+/* device class enum */ -+#define PVRSRV_BRIDGE_DEVCLASS_CMD_FIRST (PVRSRV_BRIDGE_OEM_CMD_LAST+1) -+#define PVRSRV_BRIDGE_ENUM_CLASS PVRSRV_IOWR(PVRSRV_BRIDGE_DEVCLASS_CMD_FIRST+0) -+#define PVRSRV_BRIDGE_DEVCLASS_CMD_LAST (PVRSRV_BRIDGE_DEVCLASS_CMD_FIRST+0) -+ -+/* display class API */ -+#define PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST (PVRSRV_BRIDGE_DEVCLASS_CMD_LAST+1) -+#define PVRSRV_BRIDGE_OPEN_DISPCLASS_DEVICE PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+0) -+#define PVRSRV_BRIDGE_CLOSE_DISPCLASS_DEVICE PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+1) -+#define PVRSRV_BRIDGE_ENUM_DISPCLASS_FORMATS PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+2) -+#define PVRSRV_BRIDGE_ENUM_DISPCLASS_DIMS PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+3) -+#define PVRSRV_BRIDGE_GET_DISPCLASS_SYSBUFFER PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+4) -+#define PVRSRV_BRIDGE_GET_DISPCLASS_INFO PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+5) -+#define PVRSRV_BRIDGE_CREATE_DISPCLASS_SWAPCHAIN PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+6) -+#define PVRSRV_BRIDGE_DESTROY_DISPCLASS_SWAPCHAIN PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+7) -+#define PVRSRV_BRIDGE_SET_DISPCLASS_DSTRECT PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+8) -+#define PVRSRV_BRIDGE_SET_DISPCLASS_SRCRECT PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+9) -+#define PVRSRV_BRIDGE_SET_DISPCLASS_DSTCOLOURKEY PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+10) -+#define PVRSRV_BRIDGE_SET_DISPCLASS_SRCCOLOURKEY PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+11) -+#define PVRSRV_BRIDGE_GET_DISPCLASS_BUFFERS PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+12) -+#define PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_BUFFER PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+13) -+#define PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_BUFFER2 PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+14) -+#define PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_SYSTEM PVRSRV_IOWR(PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+15) -+#define PVRSRV_BRIDGE_DISPCLASS_CMD_LAST (PVRSRV_BRIDGE_DISPCLASS_CMD_FIRST+15) -+ -+/* buffer class API */ -+#define PVRSRV_BRIDGE_BUFCLASS_CMD_FIRST (PVRSRV_BRIDGE_DISPCLASS_CMD_LAST+1) -+#define PVRSRV_BRIDGE_OPEN_BUFFERCLASS_DEVICE PVRSRV_IOWR(PVRSRV_BRIDGE_BUFCLASS_CMD_FIRST+0) -+#define PVRSRV_BRIDGE_CLOSE_BUFFERCLASS_DEVICE PVRSRV_IOWR(PVRSRV_BRIDGE_BUFCLASS_CMD_FIRST+1) -+#define PVRSRV_BRIDGE_GET_BUFFERCLASS_INFO PVRSRV_IOWR(PVRSRV_BRIDGE_BUFCLASS_CMD_FIRST+2) -+#define PVRSRV_BRIDGE_GET_BUFFERCLASS_BUFFER PVRSRV_IOWR(PVRSRV_BRIDGE_BUFCLASS_CMD_FIRST+3) -+#define PVRSRV_BRIDGE_BUFCLASS_CMD_LAST (PVRSRV_BRIDGE_BUFCLASS_CMD_FIRST+3) -+ -+/* Wrap/Unwrap external memory */ -+#define PVRSRV_BRIDGE_WRAP_CMD_FIRST (PVRSRV_BRIDGE_BUFCLASS_CMD_LAST+1) -+#define PVRSRV_BRIDGE_WRAP_EXT_MEMORY PVRSRV_IOWR(PVRSRV_BRIDGE_WRAP_CMD_FIRST+0) -+#define PVRSRV_BRIDGE_UNWRAP_EXT_MEMORY PVRSRV_IOWR(PVRSRV_BRIDGE_WRAP_CMD_FIRST+1) -+#define PVRSRV_BRIDGE_WRAP_CMD_LAST (PVRSRV_BRIDGE_WRAP_CMD_FIRST+1) -+ -+/* Shared memory */ -+#define PVRSRV_BRIDGE_SHAREDMEM_CMD_FIRST (PVRSRV_BRIDGE_WRAP_CMD_LAST+1) -+#define PVRSRV_BRIDGE_ALLOC_SHARED_SYS_MEM PVRSRV_IOWR(PVRSRV_BRIDGE_SHAREDMEM_CMD_FIRST+0) -+#define PVRSRV_BRIDGE_FREE_SHARED_SYS_MEM PVRSRV_IOWR(PVRSRV_BRIDGE_SHAREDMEM_CMD_FIRST+1) -+#define PVRSRV_BRIDGE_MAP_MEMINFO_MEM PVRSRV_IOWR(PVRSRV_BRIDGE_SHAREDMEM_CMD_FIRST+2) -+#define PVRSRV_BRIDGE_UNMAP_MEMINFO_MEM PVRSRV_IOWR(PVRSRV_BRIDGE_SHAREDMEM_CMD_FIRST+3) -+#define PVRSRV_BRIDGE_SHAREDMEM_CMD_LAST (PVRSRV_BRIDGE_SHAREDMEM_CMD_FIRST+3) -+ -+/* Intialisation Service support */ -+#define PVRSRV_BRIDGE_INITSRV_CMD_FIRST (PVRSRV_BRIDGE_SHAREDMEM_CMD_LAST+1) -+#define PVRSRV_BRIDGE_INITSRV_CONNECT PVRSRV_IOWR(PVRSRV_BRIDGE_INITSRV_CMD_FIRST+0) -+#define PVRSRV_BRIDGE_INITSRV_DISCONNECT PVRSRV_IOWR(PVRSRV_BRIDGE_INITSRV_CMD_FIRST+1) -+#define PVRSRV_BRIDGE_INITSRV_CMD_LAST (PVRSRV_BRIDGE_INITSRV_CMD_FIRST+1) -+ -+/* Event Objects */ -+#define PVRSRV_BRIDGE_EVENT_OBJECT_CMD_FIRST (PVRSRV_BRIDGE_INITSRV_CMD_LAST+1) -+#define PVRSRV_BRIDGE_EVENT_OBJECT_WAIT PVRSRV_IOWR(PVRSRV_BRIDGE_EVENT_OBJECT_CMD_FIRST+0) -+#define PVRSRV_BRIDGE_EVENT_OBJECT_OPEN PVRSRV_IOWR(PVRSRV_BRIDGE_EVENT_OBJECT_CMD_FIRST+1) -+#define PVRSRV_BRIDGE_EVENT_OBJECT_CLOSE PVRSRV_IOWR(PVRSRV_BRIDGE_EVENT_OBJECT_CMD_FIRST+2) -+#define PVRSRV_BRIDGE_EVENT_OBJECT_CMD_LAST (PVRSRV_BRIDGE_EVENT_OBJECT_CMD_FIRST+2) -+ -+/* Sync ops */ -+#define PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST (PVRSRV_BRIDGE_EVENT_OBJECT_CMD_LAST+1) -+#define PVRSRV_BRIDGE_CREATE_SYNC_INFO_MOD_OBJ PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+0) -+#define PVRSRV_BRIDGE_DESTROY_SYNC_INFO_MOD_OBJ PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+1) -+#define PVRSRV_BRIDGE_MODIFY_PENDING_SYNC_OPS PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+2) -+#define PVRSRV_BRIDGE_MODIFY_COMPLETE_SYNC_OPS PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+3) -+#define PVRSRV_BRIDGE_SYNC_OPS_TAKE_TOKEN PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+4) -+#define PVRSRV_BRIDGE_SYNC_OPS_FLUSH_TO_TOKEN PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+5) -+#define PVRSRV_BRIDGE_SYNC_OPS_FLUSH_TO_MOD_OBJ PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+6) -+#define PVRSRV_BRIDGE_SYNC_OPS_FLUSH_TO_DELTA PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+7) -+#define PVRSRV_BRIDGE_ALLOC_SYNC_INFO PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+8) -+#define PVRSRV_BRIDGE_FREE_SYNC_INFO PVRSRV_IOWR(PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+9) -+#define PVRSRV_BRIDGE_SYNC_OPS_CMD_LAST (PVRSRV_BRIDGE_SYNC_OPS_CMD_FIRST+9) -+ -+/* For sgx_bridge.h (msvdx_bridge.h should probably use these defines too) */ -+#define PVRSRV_BRIDGE_LAST_NON_DEVICE_CMD (PVRSRV_BRIDGE_SYNC_OPS_CMD_LAST+1) -+ -+ -+/****************************************************************************** -+ * Bridge flags -+ *****************************************************************************/ -+#define PVRSRV_KERNEL_MODE_CLIENT 1 -+ -+/****************************************************************************** -+ * Generic bridge structures -+ *****************************************************************************/ -+ -+/****************************************************************************** -+ * bridge return structure -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_RETURN_TAG -+{ -+ PVRSRV_ERROR eError; -+ IMG_VOID *pvData; -+ -+}PVRSRV_BRIDGE_RETURN; -+ -+ -+/****************************************************************************** -+ * bridge packaging structure -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_PACKAGE_TAG -+{ -+ IMG_UINT32 ui32BridgeID; /*!< ioctl/drvesc index */ -+ IMG_UINT32 ui32Size; /*!< size of structure */ -+ IMG_VOID *pvParamIn; /*!< input data buffer */ -+ IMG_UINT32 ui32InBufferSize; /*!< size of input data buffer */ -+ IMG_VOID *pvParamOut; /*!< output data buffer */ -+ IMG_UINT32 ui32OutBufferSize; /*!< size of output data buffer */ -+ -+ IMG_HANDLE hKernelServices; /*!< kernel servcies handle */ -+}PVRSRV_BRIDGE_PACKAGE; -+ -+ -+/****************************************************************************** -+ * Input structures for IOCTL/DRVESC -+ *****************************************************************************/ -+ -+ -+/****************************************************************************** -+ * 'bridge in' connect to services -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_CONNECT_SERVICES_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_UINT32 ui32Flags; -+} PVRSRV_BRIDGE_IN_CONNECT_SERVICES; -+ -+/****************************************************************************** -+ * 'bridge in' acquire device info -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_ACQUIRE_DEVICEINFO_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_UINT32 uiDevIndex; -+ PVRSRV_DEVICE_TYPE eDeviceType; -+ -+} PVRSRV_BRIDGE_IN_ACQUIRE_DEVICEINFO; -+ -+ -+/****************************************************************************** -+ * 'bridge in' enum class -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_ENUMCLASS_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ PVRSRV_DEVICE_CLASS sDeviceClass; -+} PVRSRV_BRIDGE_IN_ENUMCLASS; -+ -+ -+/****************************************************************************** -+ * 'bridge in' close display class device -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_CLOSE_DISPCLASS_DEVICE_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDeviceKM; -+} PVRSRV_BRIDGE_IN_CLOSE_DISPCLASS_DEVICE; -+ -+ -+/****************************************************************************** -+ * 'bridge in' enum display class formats -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_ENUM_DISPCLASS_FORMATS_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDeviceKM; -+} PVRSRV_BRIDGE_IN_ENUM_DISPCLASS_FORMATS; -+ -+ -+/****************************************************************************** -+ * 'bridge in' get display class sysbuffer -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_GET_DISPCLASS_SYSBUFFER_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDeviceKM; -+} PVRSRV_BRIDGE_IN_GET_DISPCLASS_SYSBUFFER; -+ -+ -+/****************************************************************************** -+ * 'bridge in' display class info -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_GET_DISPCLASS_INFO_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDeviceKM; -+} PVRSRV_BRIDGE_IN_GET_DISPCLASS_INFO; -+ -+ -+/****************************************************************************** -+ * 'bridge in' close buffer class device -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_CLOSE_BUFFERCLASS_DEVICE_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDeviceKM; -+} PVRSRV_BRIDGE_IN_CLOSE_BUFFERCLASS_DEVICE; -+ -+ -+/****************************************************************************** -+ * 'bridge in' close buffer class device -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_GET_BUFFERCLASS_INFO_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDeviceKM; -+} PVRSRV_BRIDGE_IN_GET_BUFFERCLASS_INFO; -+ -+ -+/****************************************************************************** -+ * 'bridge out' acquire device info -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_RELEASE_DEVICEINFO_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevCookie; -+ -+} PVRSRV_BRIDGE_IN_RELEASE_DEVICEINFO; -+ -+ -+/****************************************************************************** -+ * 'bridge in' free class devices info. -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_FREE_CLASSDEVICEINFO_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ PVRSRV_DEVICE_CLASS DeviceClass; -+ IMG_VOID* pvDevInfo; -+ -+}PVRSRV_BRIDGE_IN_FREE_CLASSDEVICEINFO; -+ -+ -+/****************************************************************************** -+ * 'bridge in' get device memory heap info -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_GET_DEVMEM_HEAPINFO_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevCookie; -+ IMG_HANDLE hDevMemContext; -+ -+}PVRSRV_BRIDGE_IN_GET_DEVMEM_HEAPINFO; -+ -+ -+/****************************************************************************** -+ * 'bridge in' create device memory context -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_CREATE_DEVMEMCONTEXT_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevCookie; -+ -+}PVRSRV_BRIDGE_IN_CREATE_DEVMEMCONTEXT; -+ -+ -+/****************************************************************************** -+ * 'bridge in' destroy device memory context -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_DESTROY_DEVMEMCONTEXT_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevCookie; -+ IMG_HANDLE hDevMemContext; -+ -+}PVRSRV_BRIDGE_IN_DESTROY_DEVMEMCONTEXT; -+ -+ -+/****************************************************************************** -+ * 'bridge in' alloc device memory -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_ALLOCDEVICEMEM_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevCookie; -+ IMG_HANDLE hDevMemHeap; -+ IMG_UINT32 ui32Attribs; -+ IMG_SIZE_T uSize; -+ IMG_SIZE_T uAlignment; -+ IMG_PVOID pvPrivData; -+ IMG_UINT32 ui32PrivDataLength; -+ -+ IMG_UINT32 ui32ChunkSize; -+ IMG_UINT32 ui32NumVirtChunks; -+ IMG_UINT32 ui32NumPhysChunks; -+ IMG_BOOL *pabMapChunk; -+}PVRSRV_BRIDGE_IN_ALLOCDEVICEMEM; -+ -+/****************************************************************************** -+ * 'bridge in' map meminfo to user mode -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_MAPMEMINFOTOUSER_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; -+ -+}PVRSRV_BRIDGE_IN_MAPMEMINFOTOUSER; -+ -+/****************************************************************************** -+ * 'bridge in' unmap meminfo from user mode -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_UNMAPMEMINFOFROMUSER_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; -+ IMG_PVOID pvLinAddr; -+ IMG_HANDLE hMappingInfo; -+ -+}PVRSRV_BRIDGE_IN_UNMAPMEMINFOFROMUSER; -+ -+/****************************************************************************** -+ * 'bridge in' free device memory -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_FREEDEVICEMEM_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevCookie; -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; -+ PVRSRV_CLIENT_MEM_INFO sClientMemInfo; -+ -+}PVRSRV_BRIDGE_IN_FREEDEVICEMEM; -+ -+/****************************************************************************** -+ * 'bridge in' export device memory -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_EXPORTDEVICEMEM_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevCookie; -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; -+ -+}PVRSRV_BRIDGE_IN_EXPORTDEVICEMEM; -+ -+/****************************************************************************** -+ * 'bridge in' map ion handle -+ *****************************************************************************/ -+#define ION_IMPORT_MAX_FDS 3 -+#define ION_IMPORT_MAX_CHUNK_COUNT 3 -+typedef struct _PVRSRV_BRIDGE_IN_MAP_ION_HANDLE_ -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_UINT32 ui32NumFDs; -+ IMG_INT32 ai32BufferFDs[ION_IMPORT_MAX_FDS]; -+ IMG_UINT32 ui32Attribs; -+ IMG_UINT32 ui32ChunkCount; -+ IMG_SIZE_T auiOffset[ION_IMPORT_MAX_CHUNK_COUNT]; -+ IMG_SIZE_T auiSize[ION_IMPORT_MAX_CHUNK_COUNT]; -+ IMG_HANDLE hDevCookie; -+ IMG_HANDLE hDevMemHeap; -+} PVRSRV_BRIDGE_IN_MAP_ION_HANDLE; -+ -+/****************************************************************************** -+ * 'bridge in' unmap ion handle -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_UNMAP_ION_HANDLE_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; -+}PVRSRV_BRIDGE_IN_UNMAP_ION_HANDLE; -+ -+/****************************************************************************** -+ * 'bridge in' get free device memory -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_GETFREEDEVICEMEM_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_UINT32 ui32Flags; -+ -+} PVRSRV_BRIDGE_IN_GETFREEDEVICEMEM; -+ -+/****************************************************************************** -+ * 'bridge in' create Cmd Q -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_CREATECOMMANDQUEUE_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevCookie; -+ IMG_SIZE_T uQueueSize; -+ -+}PVRSRV_BRIDGE_IN_CREATECOMMANDQUEUE; -+ -+ -+/****************************************************************************** -+ * 'bridge in' destroy Cmd Q -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_DESTROYCOMMANDQUEUE_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevCookie; -+ PVRSRV_QUEUE_INFO *psQueueInfo; -+ -+}PVRSRV_BRIDGE_IN_DESTROYCOMMANDQUEUE; -+ -+ -+/****************************************************************************** -+ * 'bridge in' get full map data -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_MHANDLE_TO_MMAP_DATA_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hMHandle; /* Handle associated with the memory that needs to be mapped */ -+} PVRSRV_BRIDGE_IN_MHANDLE_TO_MMAP_DATA; -+ -+ -+/****************************************************************************** -+ * 'bridge in' get full map data -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_RELEASE_MMAP_DATA_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hMHandle; /* Handle associated with the memory that needs to be mapped */ -+} PVRSRV_BRIDGE_IN_RELEASE_MMAP_DATA; -+ -+ -+/****************************************************************************** -+ * 'bridge in' reserve vm -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_RESERVE_DEV_VIRTMEM_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevMemHeap; -+ IMG_DEV_VIRTADDR *psDevVAddr; -+ IMG_SIZE_T uSize; -+ IMG_SIZE_T uAlignment; -+ -+}PVRSRV_BRIDGE_IN_RESERVE_DEV_VIRTMEM; -+ -+/****************************************************************************** -+ * 'bridge out' connect to services -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_OUT_CONNECT_SERVICES_TAG -+{ -+ PVRSRV_ERROR eError; -+ IMG_HANDLE hKernelServices; -+}PVRSRV_BRIDGE_OUT_CONNECT_SERVICES; -+ -+/****************************************************************************** -+ * 'bridge out' reserve vm -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_OUT_RESERVE_DEV_VIRTMEM_TAG -+{ -+ PVRSRV_ERROR eError; -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; -+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo; -+ PVRSRV_CLIENT_MEM_INFO sClientMemInfo; -+ PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo; -+ -+}PVRSRV_BRIDGE_OUT_RESERVE_DEV_VIRTMEM; -+ -+ -+/****************************************************************************** -+ * 'bridge in' free vm -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_FREE_DEV_VIRTMEM_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; -+ PVRSRV_CLIENT_MEM_INFO sClientMemInfo; -+ PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo; -+ -+}PVRSRV_BRIDGE_IN_FREE_DEV_VIRTMEM; -+ -+ -+/****************************************************************************** -+ * 'bridge in' map dev memory allocation to another heap -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_MAP_DEV_MEMORY_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hKernelMemInfo; -+ IMG_HANDLE hDstDevMemHeap; -+ -+}PVRSRV_BRIDGE_IN_MAP_DEV_MEMORY; -+ -+ -+/****************************************************************************** -+ * 'bridge out' map dev memory allocation to another heap -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_OUT_MAP_DEV_MEMORY_TAG -+{ -+ PVRSRV_ERROR eError; -+ PVRSRV_KERNEL_MEM_INFO *psDstKernelMemInfo; -+ PVRSRV_CLIENT_MEM_INFO sDstClientMemInfo; -+ PVRSRV_CLIENT_SYNC_INFO sDstClientSyncInfo; -+ -+}PVRSRV_BRIDGE_OUT_MAP_DEV_MEMORY; -+ -+ -+/****************************************************************************** -+ * 'bridge in' unmap dev memory allocation -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_UNMAP_DEV_MEMORY_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; -+ PVRSRV_CLIENT_MEM_INFO sClientMemInfo; -+ PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo; -+ -+}PVRSRV_BRIDGE_IN_UNMAP_DEV_MEMORY; -+ -+ -+/****************************************************************************** -+ * 'bridge in' map pages -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_MAP_EXT_MEMORY_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; -+ IMG_SYS_PHYADDR *psSysPAddr; -+ IMG_UINT32 ui32Flags; -+ -+}PVRSRV_BRIDGE_IN_MAP_EXT_MEMORY; -+ -+/****************************************************************************** -+ * 'bridge in' unmap pages -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_UNMAP_EXT_MEMORY_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ PVRSRV_CLIENT_MEM_INFO sClientMemInfo; -+ PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo; -+ IMG_UINT32 ui32Flags; -+ -+}PVRSRV_BRIDGE_IN_UNMAP_EXT_MEMORY; -+ -+/****************************************************************************** -+ * 'bridge in' map device class buffer pages -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_MAP_DEVICECLASS_MEMORY_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDeviceClassBuffer; -+ IMG_HANDLE hDevMemContext; -+ -+}PVRSRV_BRIDGE_IN_MAP_DEVICECLASS_MEMORY; -+ -+ -+/****************************************************************************** -+ * 'bridge out' map device class buffer pages -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_OUT_MAP_DEVICECLASS_MEMORY_TAG -+{ -+ PVRSRV_ERROR eError; -+ PVRSRV_CLIENT_MEM_INFO sClientMemInfo; -+ PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo; -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; -+ IMG_HANDLE hMappingInfo; -+ -+}PVRSRV_BRIDGE_OUT_MAP_DEVICECLASS_MEMORY; -+ -+ -+/****************************************************************************** -+ * 'bridge in' unmap device class buffer pages -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_UNMAP_DEVICECLASS_MEMORY_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; -+ PVRSRV_CLIENT_MEM_INFO sClientMemInfo; -+ PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo; -+ -+}PVRSRV_BRIDGE_IN_UNMAP_DEVICECLASS_MEMORY; -+ -+ -+/****************************************************************************** -+ * 'bridge in' pdump memory poll -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_PDUMP_MEMPOL_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; -+ IMG_UINT32 ui32Offset; -+ IMG_UINT32 ui32Value; -+ IMG_UINT32 ui32Mask; -+ PDUMP_POLL_OPERATOR eOperator; -+ IMG_UINT32 ui32Flags; -+ -+}PVRSRV_BRIDGE_IN_PDUMP_MEMPOL; -+ -+/****************************************************************************** -+ * 'bridge in' pdump sync poll -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_PDUMP_SYNCPOL_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo; -+ IMG_BOOL bIsRead; -+ IMG_BOOL bUseLastOpDumpVal; -+ IMG_UINT32 ui32Value; -+ IMG_UINT32 ui32Mask; -+ -+}PVRSRV_BRIDGE_IN_PDUMP_SYNCPOL; -+ -+ -+/****************************************************************************** -+ * 'bridge in' pdump dump memory -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_PDUMP_DUMPMEM_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_PVOID pvLinAddr; -+ IMG_PVOID pvAltLinAddr; -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; -+ IMG_UINT32 ui32Offset; -+ IMG_UINT32 ui32Bytes; -+ IMG_UINT32 ui32Flags; -+ -+}PVRSRV_BRIDGE_IN_PDUMP_DUMPMEM; -+ -+ -+/****************************************************************************** -+ * 'bridge in' pdump dump sync -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_PDUMP_DUMPSYNC_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_PVOID pvAltLinAddr; -+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo; -+ IMG_UINT32 ui32Offset; -+ IMG_UINT32 ui32Bytes; -+ -+}PVRSRV_BRIDGE_IN_PDUMP_DUMPSYNC; -+ -+ -+/****************************************************************************** -+ * 'bridge in' pdump dump reg -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_PDUMP_DUMPREG_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevCookie; -+ PVRSRV_HWREG sHWReg; -+ IMG_UINT32 ui32Flags; -+ IMG_CHAR szRegRegion[32]; -+ -+}PVRSRV_BRIDGE_IN_PDUMP_DUMPREG; -+ -+/****************************************************************************** -+ * 'bridge in' pdump dump reg -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_PDUMP_REGPOL_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevCookie; -+ PVRSRV_HWREG sHWReg; -+ IMG_UINT32 ui32Mask; -+ IMG_UINT32 ui32Flags; -+ IMG_CHAR szRegRegion[32]; -+}PVRSRV_BRIDGE_IN_PDUMP_REGPOL; -+ -+/****************************************************************************** -+ * 'bridge in' pdump dump PD reg -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_PDUMP_DUMPPDREG_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ PVRSRV_HWREG sHWReg; -+ IMG_UINT32 ui32Flags; -+ -+}PVRSRV_BRIDGE_IN_PDUMP_DUMPPDREG; -+ -+/****************************************************************************** -+ * 'bridge in' pdump dump mem pages -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_PDUMP_MEMPAGES_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevCookie; -+ IMG_HANDLE hKernelMemInfo; -+ IMG_DEV_PHYADDR *pPages; -+ IMG_UINT32 ui32NumPages; -+ IMG_DEV_VIRTADDR sDevVAddr; -+ IMG_UINT32 ui32Start; -+ IMG_UINT32 ui32Length; -+ IMG_UINT32 ui32Flags; -+ -+}PVRSRV_BRIDGE_IN_PDUMP_MEMPAGES; -+ -+/****************************************************************************** -+ * 'bridge in' pdump dump comment -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_PDUMP_COMMENT_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_CHAR szComment[PVRSRV_PDUMP_MAX_COMMENT_SIZE]; -+ IMG_UINT32 ui32Flags; -+ -+}PVRSRV_BRIDGE_IN_PDUMP_COMMENT; -+ -+ -+/****************************************************************************** -+ * 'bridge in' pdump set frame -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_PDUMP_SETFRAME_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_UINT32 ui32Frame; -+ -+}PVRSRV_BRIDGE_IN_PDUMP_SETFRAME; -+ -+ -+/****************************************************************************** -+ * 'bridge in' pdump dump bitmap -+ *****************************************************************************/ -+ -+typedef struct PVRSRV_BRIDGE_IN_PDUMP_BITMAP_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevCookie; -+ IMG_CHAR szFileName[PVRSRV_PDUMP_MAX_FILENAME_SIZE]; -+ IMG_UINT32 ui32FileOffset; -+ IMG_UINT32 ui32Width; -+ IMG_UINT32 ui32Height; -+ IMG_UINT32 ui32StrideInBytes; -+ IMG_DEV_VIRTADDR sDevBaseAddr; -+ IMG_HANDLE hDevMemContext; -+ IMG_UINT32 ui32Size; -+ PDUMP_PIXEL_FORMAT ePixelFormat; -+ PDUMP_MEM_FORMAT eMemFormat; -+ IMG_UINT32 ui32Flags; -+ -+}PVRSRV_BRIDGE_IN_PDUMP_BITMAP; -+ -+ -+/****************************************************************************** -+ * 'bridge in' pdump dump read reg -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_PDUMP_READREG_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevCookie; -+ IMG_CHAR szFileName[PVRSRV_PDUMP_MAX_FILENAME_SIZE]; -+ IMG_UINT32 ui32FileOffset; -+ IMG_UINT32 ui32Address; -+ IMG_UINT32 ui32Size; -+ IMG_UINT32 ui32Flags; -+ IMG_CHAR szRegRegion[32]; -+ -+}PVRSRV_BRIDGE_IN_PDUMP_READREG; -+ -+/****************************************************************************** -+ * 'bridge in' pdump dump driver-info -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_PDUMP_DRIVERINFO_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_CHAR szString[PVRSRV_PDUMP_MAX_COMMENT_SIZE]; -+ IMG_BOOL bContinuous; -+ -+}PVRSRV_BRIDGE_IN_PDUMP_DRIVERINFO; -+ -+typedef struct PVRSRV_BRIDGE_IN_PDUMP_DUMPPDDEVPADDR_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hKernelMemInfo; -+ IMG_UINT32 ui32Offset; -+ IMG_DEV_PHYADDR sPDDevPAddr; -+}PVRSRV_BRIDGE_IN_PDUMP_DUMPPDDEVPADDR; -+ -+/****************************************************************************** -+ * 'bridge in' pdump cycle count register read -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_PDUM_IN_CYCLE_COUNT_REG_READ_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevCookie; -+ IMG_UINT32 ui32RegOffset; -+ IMG_BOOL bLastFrame; -+}PVRSRV_BRIDGE_IN_PDUMP_CYCLE_COUNT_REG_READ; -+ -+/***************************************************************************** -+ * Output structures for BRIDGEs -+ ****************************************************************************/ -+ -+/****************************************************************************** -+ * 'bridge out' enum. devices -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_OUT_ENUMDEVICE_TAG -+{ -+ PVRSRV_ERROR eError; -+ IMG_UINT32 ui32NumDevices; -+ PVRSRV_DEVICE_IDENTIFIER asDeviceIdentifier[PVRSRV_MAX_DEVICES]; -+ -+}PVRSRV_BRIDGE_OUT_ENUMDEVICE; -+ -+ -+/****************************************************************************** -+ * 'bridge out' acquire device info -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_OUT_ACQUIRE_DEVICEINFO_TAG -+{ -+ -+ PVRSRV_ERROR eError; -+ IMG_HANDLE hDevCookie; -+ -+} PVRSRV_BRIDGE_OUT_ACQUIRE_DEVICEINFO; -+ -+ -+/****************************************************************************** -+ * 'bridge out' enum. class devices -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_OUT_ENUMCLASS_TAG -+{ -+ PVRSRV_ERROR eError; -+ IMG_UINT32 ui32NumDevices; -+ IMG_UINT32 ui32DevID[PVRSRV_MAX_DEVICES]; -+ -+}PVRSRV_BRIDGE_OUT_ENUMCLASS; -+ -+ -+/****************************************************************************** -+ * 'bridge in' open display class devices -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_OPEN_DISPCLASS_DEVICE_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_UINT32 ui32DeviceID; -+ IMG_HANDLE hDevCookie; -+ -+}PVRSRV_BRIDGE_IN_OPEN_DISPCLASS_DEVICE; -+ -+/****************************************************************************** -+ * 'bridge out' open display class devices -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_OUT_OPEN_DISPCLASS_DEVICE_TAG -+{ -+ PVRSRV_ERROR eError; -+ IMG_HANDLE hDeviceKM; -+ -+}PVRSRV_BRIDGE_OUT_OPEN_DISPCLASS_DEVICE; -+ -+ -+/****************************************************************************** -+ * 'bridge in' wrap pages -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_WRAP_EXT_MEMORY_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevCookie; -+ IMG_HANDLE hDevMemContext; -+ IMG_VOID *pvLinAddr; -+ IMG_SIZE_T uByteSize; -+ IMG_SIZE_T uPageOffset; -+ IMG_BOOL bPhysContig; -+ IMG_UINT32 ui32NumPageTableEntries; -+ IMG_SYS_PHYADDR *psSysPAddr; -+ IMG_UINT32 ui32Flags; -+ -+}PVRSRV_BRIDGE_IN_WRAP_EXT_MEMORY; -+ -+/****************************************************************************** -+ * 'bridge out' wrap pages -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_OUT_WRAP_EXT_MEMORY_TAG -+{ -+ PVRSRV_ERROR eError; -+ PVRSRV_CLIENT_MEM_INFO sClientMemInfo; -+ PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo; -+ -+}PVRSRV_BRIDGE_OUT_WRAP_EXT_MEMORY; -+ -+/****************************************************************************** -+ * 'bridge in' unwrap pages -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_UNWRAP_EXT_MEMORY_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hKernelMemInfo; -+ PVRSRV_CLIENT_MEM_INFO sClientMemInfo; -+ PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo; -+ -+}PVRSRV_BRIDGE_IN_UNWRAP_EXT_MEMORY; -+ -+ -+#define PVRSRV_MAX_DC_DISPLAY_FORMATS 10 -+#define PVRSRV_MAX_DC_DISPLAY_DIMENSIONS 10 -+#define PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS 4 -+#define PVRSRV_MAX_DC_CLIP_RECTS 32 -+ -+/****************************************************************************** -+ * 'bridge out' enum display class formats -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_OUT_ENUM_DISPCLASS_FORMATS_TAG -+{ -+ PVRSRV_ERROR eError; -+ IMG_UINT32 ui32Count; -+ DISPLAY_FORMAT asFormat[PVRSRV_MAX_DC_DISPLAY_FORMATS]; -+ -+}PVRSRV_BRIDGE_OUT_ENUM_DISPCLASS_FORMATS; -+ -+ -+/****************************************************************************** -+ * 'bridge in' enum display class dims -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_ENUM_DISPCLASS_DIMS_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDeviceKM; -+ DISPLAY_FORMAT sFormat; -+ -+}PVRSRV_BRIDGE_IN_ENUM_DISPCLASS_DIMS; -+ -+ -+/****************************************************************************** -+ * 'bridge out' enum display class dims -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_OUT_ENUM_DISPCLASS_DIMS_TAG -+{ -+ PVRSRV_ERROR eError; -+ IMG_UINT32 ui32Count; -+ DISPLAY_DIMS asDim[PVRSRV_MAX_DC_DISPLAY_DIMENSIONS]; -+ -+}PVRSRV_BRIDGE_OUT_ENUM_DISPCLASS_DIMS; -+ -+ -+/****************************************************************************** -+ * 'bridge out' enum display class dims -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_OUT_GET_DISPCLASS_INFO_TAG -+{ -+ PVRSRV_ERROR eError; -+ DISPLAY_INFO sDisplayInfo; -+ -+}PVRSRV_BRIDGE_OUT_GET_DISPCLASS_INFO; -+ -+ -+/****************************************************************************** -+ * 'bridge out' get display class system buffer -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_OUT_GET_DISPCLASS_SYSBUFFER_TAG -+{ -+ PVRSRV_ERROR eError; -+ IMG_HANDLE hBuffer; -+ -+}PVRSRV_BRIDGE_OUT_GET_DISPCLASS_SYSBUFFER; -+ -+ -+/****************************************************************************** -+ * 'bridge in' create swap chain -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_CREATE_DISPCLASS_SWAPCHAIN_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDeviceKM; -+ IMG_UINT32 ui32Flags; -+ DISPLAY_SURF_ATTRIBUTES sDstSurfAttrib; -+ DISPLAY_SURF_ATTRIBUTES sSrcSurfAttrib; -+ IMG_UINT32 ui32BufferCount; -+ IMG_UINT32 ui32OEMFlags; -+ IMG_UINT32 ui32SwapChainID; -+ -+} PVRSRV_BRIDGE_IN_CREATE_DISPCLASS_SWAPCHAIN; -+ -+ -+/****************************************************************************** -+ * 'bridge out' create swap chain -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_OUT_CREATE_DISPCLASS_SWAPCHAIN_TAG -+{ -+ PVRSRV_ERROR eError; -+ IMG_HANDLE hSwapChain; -+ IMG_UINT32 ui32SwapChainID; -+ -+} PVRSRV_BRIDGE_OUT_CREATE_DISPCLASS_SWAPCHAIN; -+ -+ -+/****************************************************************************** -+ * 'bridge in' destroy swap chain -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_DESTROY_DISPCLASS_SWAPCHAIN_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDeviceKM; -+ IMG_HANDLE hSwapChain; -+ -+} PVRSRV_BRIDGE_IN_DESTROY_DISPCLASS_SWAPCHAIN; -+ -+ -+/****************************************************************************** -+ * 'bridge in' set DST/SRC rect -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_SET_DISPCLASS_RECT_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDeviceKM; -+ IMG_HANDLE hSwapChain; -+ IMG_RECT sRect; -+ -+} PVRSRV_BRIDGE_IN_SET_DISPCLASS_RECT; -+ -+ -+/****************************************************************************** -+ * 'bridge in' set DST/SRC colourkey -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_SET_DISPCLASS_COLOURKEY_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDeviceKM; -+ IMG_HANDLE hSwapChain; -+ IMG_UINT32 ui32CKColour; -+ -+} PVRSRV_BRIDGE_IN_SET_DISPCLASS_COLOURKEY; -+ -+ -+/****************************************************************************** -+ * 'bridge in' get buffers (from swapchain) -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_GET_DISPCLASS_BUFFERS_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDeviceKM; -+ IMG_HANDLE hSwapChain; -+ -+} PVRSRV_BRIDGE_IN_GET_DISPCLASS_BUFFERS; -+ -+ -+/****************************************************************************** -+ * 'bridge out' get buffers (from swapchain) -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_OUT_GET_DISPCLASS_BUFFERS_TAG -+{ -+ PVRSRV_ERROR eError; -+ IMG_UINT32 ui32BufferCount; -+ IMG_HANDLE ahBuffer[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS]; -+ IMG_SYS_PHYADDR asPhyAddr[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS]; -+} PVRSRV_BRIDGE_OUT_GET_DISPCLASS_BUFFERS; -+ -+ -+/****************************************************************************** -+ * 'bridge in' swap to buffer -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_BUFFER_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDeviceKM; -+ IMG_HANDLE hBuffer; -+ IMG_UINT32 ui32SwapInterval; -+ IMG_HANDLE hPrivateTag; -+ IMG_UINT32 ui32ClipRectCount; -+ IMG_RECT sClipRect[PVRSRV_MAX_DC_CLIP_RECTS]; -+ -+} PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_BUFFER; -+ -+ -+/****************************************************************************** -+ * 'bridge in' swap to buffer 2 -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_BUFFER2_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDeviceKM; -+ IMG_HANDLE hSwapChain; -+ IMG_UINT32 ui32SwapInterval; -+ -+ IMG_UINT32 ui32NumMemInfos; -+ PVRSRV_KERNEL_MEM_INFO **ppsKernelMemInfos; -+ PVRSRV_KERNEL_SYNC_INFO **ppsKernelSyncInfos; -+ -+ IMG_UINT32 ui32PrivDataLength; -+ IMG_PVOID pvPrivData; -+ -+} PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_BUFFER2; -+ -+ -+/****************************************************************************** -+ * 'bridge out' swap to buffer 2 -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_OUT_SWAP_DISPCLASS_TO_BUFFER2_TAG -+{ -+ PVRSRV_ERROR eError; -+ IMG_HANDLE hFence; -+ -+} PVRSRV_BRIDGE_OUT_SWAP_DISPCLASS_TO_BUFFER2; -+ -+ -+/****************************************************************************** -+ * 'bridge in' swap to system buffer (primary) -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_SYSTEM_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDeviceKM; -+ IMG_HANDLE hSwapChain; -+ -+} PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_SYSTEM; -+ -+ -+/****************************************************************************** -+ * 'bridge in' open buffer class device -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_OPEN_BUFFERCLASS_DEVICE_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_UINT32 ui32DeviceID; -+ IMG_HANDLE hDevCookie; -+ -+} PVRSRV_BRIDGE_IN_OPEN_BUFFERCLASS_DEVICE; -+ -+ -+/****************************************************************************** -+ * 'bridge out' open buffer class device -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_OUT_OPEN_BUFFERCLASS_DEVICE_TAG -+{ -+ PVRSRV_ERROR eError; -+ IMG_HANDLE hDeviceKM; -+ -+} PVRSRV_BRIDGE_OUT_OPEN_BUFFERCLASS_DEVICE; -+ -+ -+/****************************************************************************** -+ * 'bridge out' get buffer class info -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_OUT_GET_BUFFERCLASS_INFO_TAG -+{ -+ PVRSRV_ERROR eError; -+ BUFFER_INFO sBufferInfo; -+ -+} PVRSRV_BRIDGE_OUT_GET_BUFFERCLASS_INFO; -+ -+ -+/****************************************************************************** -+ * 'bridge in' get buffer class buffer -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_GET_BUFFERCLASS_BUFFER_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDeviceKM; -+ IMG_UINT32 ui32BufferIndex; -+ -+} PVRSRV_BRIDGE_IN_GET_BUFFERCLASS_BUFFER; -+ -+ -+/****************************************************************************** -+ * 'bridge out' get buffer class buffer -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_OUT_GET_BUFFERCLASS_BUFFER_TAG -+{ -+ PVRSRV_ERROR eError; -+ IMG_HANDLE hBuffer; -+ -+} PVRSRV_BRIDGE_OUT_GET_BUFFERCLASS_BUFFER; -+ -+ -+/****************************************************************************** -+ * 'bridge out' get heap info -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_OUT_GET_DEVMEM_HEAPINFO_TAG -+{ -+ PVRSRV_ERROR eError; -+ IMG_UINT32 ui32ClientHeapCount; -+ PVRSRV_HEAP_INFO sHeapInfo[PVRSRV_MAX_CLIENT_HEAPS]; -+ -+} PVRSRV_BRIDGE_OUT_GET_DEVMEM_HEAPINFO; -+ -+ -+/****************************************************************************** -+ * 'bridge out' create device memory context -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_OUT_CREATE_DEVMEMCONTEXT_TAG -+{ -+ PVRSRV_ERROR eError; -+ IMG_HANDLE hDevMemContext; -+ IMG_UINT32 ui32ClientHeapCount; -+ PVRSRV_HEAP_INFO sHeapInfo[PVRSRV_MAX_CLIENT_HEAPS]; -+ -+} PVRSRV_BRIDGE_OUT_CREATE_DEVMEMCONTEXT; -+ -+ -+/****************************************************************************** -+ * 'bridge out' create device memory context -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_OUT_CREATE_DEVMEMHEAP_TAG -+{ -+ PVRSRV_ERROR eError; -+ IMG_HANDLE hDevMemHeap; -+ -+} PVRSRV_BRIDGE_OUT_CREATE_DEVMEMHEAP; -+ -+ -+/****************************************************************************** -+ * 'bridge out' alloc device memory -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_OUT_ALLOCDEVICEMEM_TAG -+{ -+ PVRSRV_ERROR eError; -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; -+ PVRSRV_CLIENT_MEM_INFO sClientMemInfo; -+ PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo; -+ -+} PVRSRV_BRIDGE_OUT_ALLOCDEVICEMEM; -+ -+ -+/****************************************************************************** -+ * 'bridge out' export device memory -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_OUT_EXPORTDEVICEMEM_TAG -+{ -+ PVRSRV_ERROR eError; -+ IMG_HANDLE hMemInfo; -+#if defined(SUPPORT_MEMINFO_IDS) -+ IMG_UINT64 ui64Stamp; -+#endif -+ -+} PVRSRV_BRIDGE_OUT_EXPORTDEVICEMEM; -+ -+ -+/****************************************************************************** -+ * 'bridge out' map ion handle -+ *****************************************************************************/ -+typedef struct _PVRSRV_BRIDGE_OUT_MAP_ION_HANDLE_ -+{ -+ PVRSRV_ERROR eError; -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; -+ PVRSRV_CLIENT_MEM_INFO sClientMemInfo; -+ PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo; -+ IMG_SIZE_T uiIonBufferSize; -+ -+} PVRSRV_BRIDGE_OUT_MAP_ION_HANDLE; -+ -+ -+/****************************************************************************** -+ * 'bridge out' map meminfo to user mode -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_OUT_MAPMEMINFOTOUSER_TAG -+{ -+ PVRSRV_ERROR eError; -+ IMG_PVOID pvLinAddr; -+ IMG_HANDLE hMappingInfo; -+ -+}PVRSRV_BRIDGE_OUT_MAPMEMINFOTOUSER; -+ -+ -+/****************************************************************************** -+ * 'bridge out' get free device memory -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_OUT_GETFREEDEVICEMEM_TAG -+{ -+ PVRSRV_ERROR eError; -+ IMG_SIZE_T uTotal; -+ IMG_SIZE_T uFree; -+ IMG_SIZE_T uLargestBlock; -+ -+} PVRSRV_BRIDGE_OUT_GETFREEDEVICEMEM; -+ -+ -+//#ifdef LINUX -+/****************************************************************************** -+ * 'bridge out' get full map data -+ *****************************************************************************/ -+#include "pvrmmap.h" -+typedef struct PVRSRV_BRIDGE_OUT_MHANDLE_TO_MMAP_DATA_TAG -+{ -+ PVRSRV_ERROR eError; -+ -+ /* This is a the offset you should pass to mmap(2) so that -+ * the driver can look up the full details for the mapping -+ * request. */ -+ IMG_UINTPTR_T uiMMapOffset; -+ -+ /* This is the byte offset you should add to the mapping you -+ * get from mmap */ -+ IMG_UINTPTR_T uiByteOffset; -+ -+ /* This is the real size of the mapping that will be created -+ * which should be passed to mmap _and_ munmap. */ -+ IMG_SIZE_T uiRealByteSize; -+ -+ /* User mode address associated with mapping */ -+ IMG_UINTPTR_T uiUserVAddr; -+ -+} PVRSRV_BRIDGE_OUT_MHANDLE_TO_MMAP_DATA; -+ -+typedef struct PVRSRV_BRIDGE_OUT_RELEASE_MMAP_DATA_TAG -+{ -+ PVRSRV_ERROR eError; -+ -+ /* Flag that indicates whether the mapping should be destroyed */ -+ IMG_BOOL bMUnmap; -+ -+ /* User mode address associated with mapping */ -+ IMG_UINTPTR_T uiUserVAddr; -+ -+ /* Size of mapping */ -+ IMG_SIZE_T uiRealByteSize; -+} PVRSRV_BRIDGE_OUT_RELEASE_MMAP_DATA; -+//#endif -+ -+ -+/****************************************************************************** -+ * 'bridge in' get misc info -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_GET_MISC_INFO_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ PVRSRV_MISC_INFO sMiscInfo; -+ -+}PVRSRV_BRIDGE_IN_GET_MISC_INFO; -+ -+ -+/****************************************************************************** -+ * 'bridge out' get misc info -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_OUT_GET_MISC_INFO_TAG -+{ -+ PVRSRV_ERROR eError; -+ PVRSRV_MISC_INFO sMiscInfo; -+ -+}PVRSRV_BRIDGE_OUT_GET_MISC_INFO; -+ -+ -+/****************************************************************************** -+ * 'bridge in' get misc info -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_RELEASE_MISC_INFO_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ PVRSRV_MISC_INFO sMiscInfo; -+ -+}PVRSRV_BRIDGE_IN_RELEASE_MISC_INFO; -+ -+ -+/****************************************************************************** -+ * 'bridge out' get misc info -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_OUT_RELEASE_MISC_INFO_TAG -+{ -+ PVRSRV_ERROR eError; -+ PVRSRV_MISC_INFO sMiscInfo; -+ -+}PVRSRV_BRIDGE_OUT_RELEASE_MISC_INFO; -+ -+ -+/****************************************************************************** -+ * 'bridge out' PDUMP is capturing -+ *****************************************************************************/ -+ -+typedef struct PVRSRV_BRIDGE_OUT_PDUMP_ISCAPTURING_TAG -+{ -+ PVRSRV_ERROR eError; -+ IMG_BOOL bIsCapturing; -+ -+} PVRSRV_BRIDGE_OUT_PDUMP_ISCAPTURING; -+ -+/****************************************************************************** -+ * 'bridge in' get FB mem stats -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_GET_FB_STATS_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_SIZE_T uTotal; -+ IMG_SIZE_T uAvailable; -+ -+} PVRSRV_BRIDGE_IN_GET_FB_STATS; -+ -+ -+/****************************************************************************** -+ * 'bridge in' Map CPU Physical to User Space -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_MAPPHYSTOUSERSPACE_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevCookie; -+ IMG_SYS_PHYADDR sSysPhysAddr; -+ IMG_UINT32 uiSizeInBytes; -+ -+} PVRSRV_BRIDGE_IN_MAPPHYSTOUSERSPACE; -+ -+ -+/****************************************************************************** -+ * 'bridge out' Map CPU Physical to User Space -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_OUT_MAPPHYSTOUSERSPACE_TAG -+{ -+ IMG_PVOID pvUserAddr; -+ IMG_UINT32 uiActualSize; -+ IMG_PVOID pvProcess; -+ -+} PVRSRV_BRIDGE_OUT_MAPPHYSTOUSERSPACE; -+ -+ -+/****************************************************************************** -+ * 'bridge in' Unmap CPU Physical to User Space -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_UNMAPPHYSTOUSERSPACE_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevCookie; -+ IMG_PVOID pvUserAddr; -+ IMG_PVOID pvProcess; -+ -+} PVRSRV_BRIDGE_IN_UNMAPPHYSTOUSERSPACE; -+ -+ -+/****************************************************************************** -+ * 'bridge out' Get user space pointer to Phys to Lin lookup table -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_OUT_GETPHYSTOUSERSPACEMAP_TAG -+{ -+ IMG_PVOID *ppvTbl; -+ IMG_UINT32 uiTblSize; -+ -+} PVRSRV_BRIDGE_OUT_GETPHYSTOUSERSPACEMAP; -+ -+ -+/****************************************************************************** -+ * 'bridge in' Register RTSIM process thread -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_REGISTER_SIM_PROCESS_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevCookie; -+ IMG_PVOID pvProcess; -+ -+} PVRSRV_BRIDGE_IN_REGISTER_SIM_PROCESS; -+ -+ -+/****************************************************************************** -+ * 'bridge out' Register RTSIM process thread -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_OUT_REGISTER_SIM_PROCESS_TAG -+{ -+ IMG_SYS_PHYADDR sRegsPhysBase; /*!< Physical address of current device register */ -+ IMG_VOID *pvRegsBase; /*!< User mode linear address of SGX device registers */ -+ IMG_PVOID pvProcess; -+ IMG_UINT32 ulNoOfEntries; -+ IMG_PVOID pvTblLinAddr; -+ -+} PVRSRV_BRIDGE_OUT_REGISTER_SIM_PROCESS; -+ -+ -+/****************************************************************************** -+ * 'bridge in' Unregister RTSIM process thread -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_UNREGISTER_SIM_PROCESS_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevCookie; -+ IMG_PVOID pvProcess; -+ IMG_VOID *pvRegsBase; /*!< User mode linear address of SGX device registers */ -+ -+} PVRSRV_BRIDGE_IN_UNREGISTER_SIM_PROCESS; -+ -+/****************************************************************************** -+ * 'bridge in' process simulator ISR event -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_PROCESS_SIMISR_EVENT_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevCookie; -+ IMG_UINT32 ui32StatusAndMask; -+ PVRSRV_ERROR eError; -+ -+} PVRSRV_BRIDGE_IN_PROCESS_SIMISR_EVENT; -+ -+/****************************************************************************** -+ * 'bridge in' initialisation server disconnect -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_INITSRV_DISCONNECT_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_BOOL bInitSuccesful; -+} PVRSRV_BRIDGE_IN_INITSRV_DISCONNECT; -+ -+ -+typedef struct PVRSRV_BRIDGE_IN_ALLOC_SHARED_SYS_MEM_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_UINT32 ui32Flags; -+ IMG_SIZE_T uSize; -+}PVRSRV_BRIDGE_IN_ALLOC_SHARED_SYS_MEM; -+ -+typedef struct PVRSRV_BRIDGE_OUT_ALLOC_SHARED_SYS_MEM_TAG -+{ -+ PVRSRV_ERROR eError; -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; -+ PVRSRV_CLIENT_MEM_INFO sClientMemInfo; -+}PVRSRV_BRIDGE_OUT_ALLOC_SHARED_SYS_MEM; -+ -+typedef struct PVRSRV_BRIDGE_IN_FREE_SHARED_SYS_MEM_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; -+ PVRSRV_CLIENT_MEM_INFO sClientMemInfo; -+}PVRSRV_BRIDGE_IN_FREE_SHARED_SYS_MEM; -+ -+typedef struct PVRSRV_BRIDGE_OUT_FREE_SHARED_SYS_MEM_TAG -+{ -+ PVRSRV_ERROR eError; -+}PVRSRV_BRIDGE_OUT_FREE_SHARED_SYS_MEM; -+ -+typedef struct PVRSRV_BRIDGE_IN_MAP_MEMINFO_MEM_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hKernelMemInfo; -+}PVRSRV_BRIDGE_IN_MAP_MEMINFO_MEM; -+ -+typedef struct PVRSRV_BRIDGE_OUT_MAP_MEMINFO_MEM_TAG -+{ -+ PVRSRV_CLIENT_MEM_INFO sClientMemInfo; -+ PVRSRV_CLIENT_SYNC_INFO sClientSyncInfo; -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; -+ PVRSRV_ERROR eError; -+}PVRSRV_BRIDGE_OUT_MAP_MEMINFO_MEM; -+ -+typedef struct PVRSRV_BRIDGE_IN_UNMAP_MEMINFO_MEM_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ PVRSRV_CLIENT_MEM_INFO sClientMemInfo; -+}PVRSRV_BRIDGE_IN_UNMAP_MEMINFO_MEM; -+ -+typedef struct PVRSRV_BRIDGE_OUT_UNMAP_MEMINFO_MEM_TAG -+{ -+ PVRSRV_ERROR eError; -+}PVRSRV_BRIDGE_OUT_UNMAP_MEMINFO_MEM; -+ -+typedef struct PVRSRV_BRIDGE_IN_EVENT_OBJECT_WAI_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hOSEventKM; -+} PVRSRV_BRIDGE_IN_EVENT_OBJECT_WAIT; -+ -+typedef struct PVRSRV_BRIDGE_IN_EVENT_OBJECT_OPEN_TAG -+{ -+ PVRSRV_EVENTOBJECT sEventObject; -+} PVRSRV_BRIDGE_IN_EVENT_OBJECT_OPEN; -+ -+typedef struct PVRSRV_BRIDGE_OUT_EVENT_OBJECT_OPEN_TAG -+{ -+ IMG_HANDLE hOSEvent; -+ PVRSRV_ERROR eError; -+} PVRSRV_BRIDGE_OUT_EVENT_OBJECT_OPEN; -+ -+typedef struct PVRSRV_BRIDGE_IN_EVENT_OBJECT_CLOSE_TAG -+{ -+ PVRSRV_EVENTOBJECT sEventObject; -+ IMG_HANDLE hOSEventKM; -+} PVRSRV_BRIDGE_IN_EVENT_OBJECT_CLOSE; -+ -+typedef struct PVRSRV_BRIDGE_OUT_CREATE_SYNC_INFO_MOD_OBJ_TAG -+{ -+ PVRSRV_ERROR eError; -+ -+ IMG_HANDLE hKernelSyncInfoModObj; -+ -+} PVRSRV_BRIDGE_OUT_CREATE_SYNC_INFO_MOD_OBJ; -+ -+typedef struct PVRSRV_BRIDGE_IN_DESTROY_SYNC_INFO_MOD_OBJ -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hKernelSyncInfoModObj; -+} PVRSRV_BRIDGE_IN_DESTROY_SYNC_INFO_MOD_OBJ; -+ -+typedef struct PVRSRV_BRIDGE_IN_MODIFY_PENDING_SYNC_OPS_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hKernelSyncInfoModObj; -+ IMG_HANDLE hKernelSyncInfo; -+ IMG_UINT32 ui32ModifyFlags; -+ -+} PVRSRV_BRIDGE_IN_MODIFY_PENDING_SYNC_OPS; -+ -+typedef struct PVRSRV_BRIDGE_IN_MODIFY_COMPLETE_SYNC_OPS_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hKernelSyncInfoModObj; -+} PVRSRV_BRIDGE_IN_MODIFY_COMPLETE_SYNC_OPS; -+ -+typedef struct PVRSRV_BRIDGE_OUT_MODIFY_PENDING_SYNC_OPS_TAG -+{ -+ PVRSRV_ERROR eError; -+ -+ /* The following variable are used to return the PRE-INCREMENTED op vals */ -+ IMG_UINT32 ui32ReadOpsPending; -+ IMG_UINT32 ui32WriteOpsPending; -+ IMG_UINT32 ui32ReadOps2Pending; -+ -+} PVRSRV_BRIDGE_OUT_MODIFY_PENDING_SYNC_OPS; -+ -+typedef struct PVRSRV_BRIDGE_IN_SYNC_OPS_TAKE_TOKEN_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hKernelSyncInfo; -+ -+} PVRSRV_BRIDGE_IN_SYNC_OPS_TAKE_TOKEN; -+ -+typedef struct PVRSRV_BRIDGE_OUT_SYNC_OPS_TAKE_TOKEN_TAG -+{ -+ PVRSRV_ERROR eError; -+ -+ IMG_UINT32 ui32ReadOpsPending; -+ IMG_UINT32 ui32WriteOpsPending; -+ IMG_UINT32 ui32ReadOps2Pending; -+ -+} PVRSRV_BRIDGE_OUT_SYNC_OPS_TAKE_TOKEN; -+ -+typedef struct PVRSRV_BRIDGE_IN_SYNC_OPS_FLUSH_TO_TOKEN_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hKernelSyncInfo; -+ IMG_UINT32 ui32ReadOpsPendingSnapshot; -+ IMG_UINT32 ui32WriteOpsPendingSnapshot; -+ IMG_UINT32 ui32ReadOps2PendingSnapshot; -+} PVRSRV_BRIDGE_IN_SYNC_OPS_FLUSH_TO_TOKEN; -+ -+typedef struct PVRSRV_BRIDGE_IN_SYNC_OPS_FLUSH_TO_MOD_OBJ_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hKernelSyncInfoModObj; -+} PVRSRV_BRIDGE_IN_SYNC_OPS_FLUSH_TO_MOD_OBJ; -+ -+typedef struct PVRSRV_BRIDGE_IN_SYNC_OPS_FLUSH_TO_DELTA_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hKernelSyncInfo; -+ IMG_UINT32 ui32Delta; -+} PVRSRV_BRIDGE_IN_SYNC_OPS_FLUSH_TO_DELTA; -+ -+typedef struct PVRSRV_BRIDGE_IN_ALLOC_SYNC_INFO_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ -+ IMG_HANDLE hDevCookie; -+} PVRSRV_BRIDGE_IN_ALLOC_SYNC_INFO; -+ -+typedef struct PVRSRV_BRIDGE_OUT_ALLOC_SYNC_INFO_TAG -+{ -+ PVRSRV_ERROR eError; -+ -+ IMG_HANDLE hKernelSyncInfo; -+} PVRSRV_BRIDGE_OUT_ALLOC_SYNC_INFO; -+ -+typedef struct PVRSRV_BRIDGE_IN_FREE_SYNC_INFO_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ -+ IMG_HANDLE hKernelSyncInfo; -+} PVRSRV_BRIDGE_IN_FREE_SYNC_INFO; -+ -+typedef struct PVRSRV_BRIDGE_IN_CHG_DEV_MEM_ATTRIBS_TAG -+{ -+ IMG_SID hKernelMemInfo; -+ IMG_UINT32 ui32Attribs; -+} PVRSRV_BRIDGE_IN_CHG_DEV_MEM_ATTRIBS; -+ -+ -+#if defined (__cplusplus) -+} -+#endif -+ -+#endif /* __PVR_BRIDGE_H__ */ -+ -+/****************************************************************************** -+ End of file (pvr_bridge.h) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/include/pvr_bridge_km.h b/drivers/staging/ti-es8-sgx/services4/include/pvr_bridge_km.h -new file mode 100644 -index 0000000..2c30e02 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/include/pvr_bridge_km.h -@@ -0,0 +1,395 @@ -+/*************************************************************************/ /*! -+@Title PVR Bridge Functionality -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Header for the PVR Bridge code -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#ifndef __PVR_BRIDGE_KM_H_ -+#define __PVR_BRIDGE_KM_H_ -+ -+#if defined (__cplusplus) -+extern "C" { -+#endif -+ -+#include "pvr_bridge.h" -+#include "perproc.h" -+ -+/****************************************************************************** -+ * Function prototypes -+ *****************************************************************************/ -+#if defined(__linux__) -+PVRSRV_ERROR LinuxBridgeInit(IMG_VOID); -+IMG_VOID LinuxBridgeDeInit(IMG_VOID); -+ -+#if defined(SUPPORT_MEMINFO_IDS) -+extern IMG_UINT64 g_ui64MemInfoID; -+#endif -+ -+#endif -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumerateDevicesKM(IMG_UINT32 *pui32NumDevices, -+ PVRSRV_DEVICE_IDENTIFIER *psDevIdList); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVAcquireDeviceDataKM(IMG_UINT32 uiDevIndex, -+ PVRSRV_DEVICE_TYPE eDeviceType, -+ IMG_HANDLE *phDevCookie); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateCommandQueueKM(IMG_SIZE_T uQueueSize, -+ PVRSRV_QUEUE_INFO **ppsQueueInfo); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyCommandQueueKM(PVRSRV_QUEUE_INFO *psQueueInfo); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDeviceMemHeapsKM(IMG_HANDLE hDevCookie, -+ PVRSRV_HEAP_INFO *psHeapInfo); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateDeviceMemContextKM(IMG_HANDLE hDevCookie, -+ PVRSRV_PER_PROCESS_DATA *psPerProc, -+ IMG_HANDLE *phDevMemContext, -+ IMG_UINT32 *pui32ClientHeapCount, -+ PVRSRV_HEAP_INFO *psHeapInfo, -+ IMG_BOOL *pbCreated, -+ IMG_BOOL *pbShared); -+ -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyDeviceMemContextKM(IMG_HANDLE hDevCookie, -+ IMG_HANDLE hDevMemContext, -+ IMG_BOOL *pbDestroyed); -+ -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDeviceMemHeapInfoKM(IMG_HANDLE hDevCookie, -+ IMG_HANDLE hDevMemContext, -+ IMG_UINT32 *pui32ClientHeapCount, -+ PVRSRV_HEAP_INFO *psHeapInfo, -+ IMG_BOOL *pbShared -+ ); -+ -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV _PVRSRVAllocDeviceMemKM(IMG_HANDLE hDevCookie, -+ PVRSRV_PER_PROCESS_DATA *psPerProc, -+ IMG_HANDLE hDevMemHeap, -+ IMG_UINT32 ui32Flags, -+ IMG_SIZE_T ui32Size, -+ IMG_SIZE_T ui32Alignment, -+ IMG_PVOID pvPrivData, -+ IMG_UINT32 ui32PrivDataLength, -+ IMG_UINT32 ui32ChunkSize, -+ IMG_UINT32 ui32NumVirtChunks, -+ IMG_UINT32 ui32NumPhysChunks, -+ IMG_BOOL *pabMapChunk, -+ PVRSRV_KERNEL_MEM_INFO **ppsMemInfo); -+ -+ -+#if defined(PVRSRV_LOG_MEMORY_ALLOCS) -+ #define PVRSRVAllocDeviceMemKM(devCookie, perProc, devMemHeap, flags, size, alignment, privdata, privdatalength, \ -+ chunksize, numvirtchunks, numphyschunks, mapchunk, memInfo, logStr) \ -+ (PVR_TRACE(("PVRSRVAllocDeviceMemKM(" #devCookie ", " #perProc ", " #devMemHeap ", " #flags ", " #size \ -+ ", " #alignment "," #memInfo "): " logStr " (size = 0x%x)", size)),\ -+ _PVRSRVAllocDeviceMemKM(devCookie, perProc, devMemHeap, flags, size, alignment, privdata, privdatalength, \ -+ chunksize, numvirtchunks, numphyschunks, mapchunk, memInfo)) -+#else -+ #define PVRSRVAllocDeviceMemKM(devCookie, perProc, devMemHeap, flags, size, alignment, privdata, privdatalength, \ -+ chunksize, numvirtchunks, numphyschunks, mapchunk, memInfo, logStr) \ -+ _PVRSRVAllocDeviceMemKM(devCookie, perProc, devMemHeap, flags, size, alignment, privdata, privdatalength, \ -+ chunksize, numvirtchunks, numphyschunks, mapchunk, memInfo) -+#endif -+ -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeDeviceMemKM(IMG_HANDLE hDevCookie, -+ PVRSRV_KERNEL_MEM_INFO *psMemInfo); -+ -+#if defined(SUPPORT_ION) -+IMG_IMPORT -+PVRSRV_ERROR PVRSRVMapIonHandleKM(PVRSRV_PER_PROCESS_DATA *psPerProc, -+ IMG_HANDLE hDevCookie, -+ IMG_HANDLE hDevMemHeap, -+ IMG_UINT32 ui32NumFDs, -+ IMG_INT32 *pai32BufferFDs, -+ IMG_UINT32 ui32Flags, -+ IMG_UINT32 ui32ChunkCount, -+ IMG_SIZE_T *pauiOffset, -+ IMG_SIZE_T *pauiSize, -+ IMG_SIZE_T *puiIonBufferSize, -+ PVRSRV_KERNEL_MEM_INFO **ppsKernelMemInfo, -+ IMG_UINT64 *pui64Stamp); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapIonHandleKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo); -+#endif /* SUPPORT_ION */ -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVDissociateDeviceMemKM(IMG_HANDLE hDevCookie, -+ PVRSRV_KERNEL_MEM_INFO *psMemInfo); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVReserveDeviceVirtualMemKM(IMG_HANDLE hDevMemHeap, -+ IMG_DEV_VIRTADDR *psDevVAddr, -+ IMG_SIZE_T ui32Size, -+ IMG_SIZE_T ui32Alignment, -+ PVRSRV_KERNEL_MEM_INFO **ppsMemInfo); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeDeviceVirtualMemKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceMemoryKM(PVRSRV_PER_PROCESS_DATA *psPerProc, -+ PVRSRV_KERNEL_MEM_INFO *psSrcMemInfo, -+ IMG_HANDLE hDstDevMemHeap, -+ PVRSRV_KERNEL_MEM_INFO **ppsDstMemInfo); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapDeviceMemoryKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVWrapExtMemoryKM(IMG_HANDLE hDevCookie, -+ PVRSRV_PER_PROCESS_DATA *psPerProc, -+ IMG_HANDLE hDevMemContext, -+ IMG_SIZE_T ui32ByteSize, -+ IMG_SIZE_T ui32PageOffset, -+ IMG_BOOL bPhysContig, -+ IMG_SYS_PHYADDR *psSysAddr, -+ IMG_VOID *pvLinAddr, -+ IMG_UINT32 ui32Flags, -+ PVRSRV_KERNEL_MEM_INFO **ppsMemInfo); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVUnwrapExtMemoryKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo); -+ -+IMG_IMPORT -+PVRSRV_ERROR PVRSRVEnumerateDCKM(PVRSRV_DEVICE_CLASS DeviceClass, -+ IMG_UINT32 *pui32DevCount, -+ IMG_UINT32 *pui32DevID ); -+ -+IMG_IMPORT -+PVRSRV_ERROR PVRSRVOpenDCDeviceKM(PVRSRV_PER_PROCESS_DATA *psPerProc, -+ IMG_UINT32 ui32DeviceID, -+ IMG_HANDLE hDevCookie, -+ IMG_HANDLE *phDeviceKM); -+ -+IMG_IMPORT -+PVRSRV_ERROR PVRSRVCloseDCDeviceKM(IMG_HANDLE hDeviceKM); -+ -+IMG_IMPORT -+PVRSRV_ERROR PVRSRVEnumDCFormatsKM(IMG_HANDLE hDeviceKM, -+ IMG_UINT32 *pui32Count, -+ DISPLAY_FORMAT *psFormat); -+ -+IMG_IMPORT -+PVRSRV_ERROR PVRSRVEnumDCDimsKM(IMG_HANDLE hDeviceKM, -+ DISPLAY_FORMAT *psFormat, -+ IMG_UINT32 *pui32Count, -+ DISPLAY_DIMS *psDim); -+ -+IMG_IMPORT -+PVRSRV_ERROR PVRSRVGetDCSystemBufferKM(IMG_HANDLE hDeviceKM, -+ IMG_HANDLE *phBuffer); -+ -+IMG_IMPORT -+PVRSRV_ERROR PVRSRVGetDCInfoKM(IMG_HANDLE hDeviceKM, -+ DISPLAY_INFO *psDisplayInfo); -+IMG_IMPORT -+PVRSRV_ERROR PVRSRVCreateDCSwapChainKM(PVRSRV_PER_PROCESS_DATA *psPerProc, -+ IMG_HANDLE hDeviceKM, -+ IMG_UINT32 ui32Flags, -+ DISPLAY_SURF_ATTRIBUTES *psDstSurfAttrib, -+ DISPLAY_SURF_ATTRIBUTES *psSrcSurfAttrib, -+ IMG_UINT32 ui32BufferCount, -+ IMG_UINT32 ui32OEMFlags, -+ IMG_HANDLE *phSwapChain, -+ IMG_UINT32 *pui32SwapChainID); -+IMG_IMPORT -+PVRSRV_ERROR PVRSRVDestroyDCSwapChainKM(IMG_HANDLE hSwapChain); -+IMG_IMPORT -+PVRSRV_ERROR PVRSRVSetDCDstRectKM(IMG_HANDLE hDeviceKM, -+ IMG_HANDLE hSwapChain, -+ IMG_RECT *psRect); -+IMG_IMPORT -+PVRSRV_ERROR PVRSRVSetDCSrcRectKM(IMG_HANDLE hDeviceKM, -+ IMG_HANDLE hSwapChain, -+ IMG_RECT *psRect); -+IMG_IMPORT -+PVRSRV_ERROR PVRSRVSetDCDstColourKeyKM(IMG_HANDLE hDeviceKM, -+ IMG_HANDLE hSwapChain, -+ IMG_UINT32 ui32CKColour); -+IMG_IMPORT -+PVRSRV_ERROR PVRSRVSetDCSrcColourKeyKM(IMG_HANDLE hDeviceKM, -+ IMG_HANDLE hSwapChain, -+ IMG_UINT32 ui32CKColour); -+IMG_IMPORT -+PVRSRV_ERROR PVRSRVGetDCBuffersKM(IMG_HANDLE hDeviceKM, -+ IMG_HANDLE hSwapChain, -+ IMG_UINT32 *pui32BufferCount, -+ IMG_HANDLE *phBuffer, -+ IMG_SYS_PHYADDR *psPhyAddr); -+IMG_IMPORT -+PVRSRV_ERROR PVRSRVSwapToDCBufferKM(IMG_HANDLE hDeviceKM, -+ IMG_HANDLE hBuffer, -+ IMG_UINT32 ui32SwapInterval, -+ IMG_HANDLE hPrivateTag, -+ IMG_UINT32 ui32ClipRectCount, -+ IMG_RECT *psClipRect); -+IMG_IMPORT -+PVRSRV_ERROR PVRSRVSwapToDCBuffer2KM(IMG_HANDLE hDeviceKM, -+ IMG_HANDLE hBuffer, -+ IMG_UINT32 ui32SwapInterval, -+ PVRSRV_KERNEL_MEM_INFO **ppsMemInfos, -+ PVRSRV_KERNEL_SYNC_INFO **ppsSyncInfos, -+ IMG_UINT32 ui32NumMemSyncInfos, -+ IMG_PVOID pvPrivData, -+ IMG_UINT32 ui32PrivDataLength, -+ IMG_HANDLE *phFence); -+IMG_IMPORT -+PVRSRV_ERROR PVRSRVSwapToDCSystemKM(IMG_HANDLE hDeviceKM, -+ IMG_HANDLE hSwapChain); -+ -+IMG_IMPORT -+PVRSRV_ERROR PVRSRVOpenBCDeviceKM(PVRSRV_PER_PROCESS_DATA *psPerProc, -+ IMG_UINT32 ui32DeviceID, -+ IMG_HANDLE hDevCookie, -+ IMG_HANDLE *phDeviceKM); -+IMG_IMPORT -+PVRSRV_ERROR PVRSRVCloseBCDeviceKM(IMG_HANDLE hDeviceKM); -+ -+IMG_IMPORT -+PVRSRV_ERROR PVRSRVGetBCInfoKM(IMG_HANDLE hDeviceKM, -+ BUFFER_INFO *psBufferInfo); -+IMG_IMPORT -+PVRSRV_ERROR PVRSRVGetBCBufferKM(IMG_HANDLE hDeviceKM, -+ IMG_UINT32 ui32BufferIndex, -+ IMG_HANDLE *phBuffer); -+ -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceClassMemoryKM(PVRSRV_PER_PROCESS_DATA *psPerProc, -+ IMG_HANDLE hDevMemContext, -+ IMG_HANDLE hDeviceClassBuffer, -+ PVRSRV_KERNEL_MEM_INFO **ppsMemInfo, -+ IMG_HANDLE *phOSMapInfo); -+ -+IMG_EXPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVChangeDeviceMemoryAttributesKM(IMG_HANDLE hKernelMemInfo, -+ IMG_UINT32 ui32Attribs); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapDeviceClassMemoryKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetFreeDeviceMemKM(IMG_UINT32 ui32Flags, -+ IMG_SIZE_T *pui32Total, -+ IMG_SIZE_T *pui32Free, -+ IMG_SIZE_T *pui32LargestBlock); -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVAllocSyncInfoKM(IMG_HANDLE hDevCookie, -+ IMG_HANDLE hDevMemContext, -+ PVRSRV_KERNEL_SYNC_INFO **ppsKernelSyncInfo); -+IMG_IMPORT -+IMG_VOID IMG_CALLCONV PVRSRVAcquireSyncInfoKM(PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo); -+IMG_IMPORT -+IMG_VOID IMG_CALLCONV PVRSRVReleaseSyncInfoKM(PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetMiscInfoKM(PVRSRV_MISC_INFO *psMiscInfo); -+ -+/*! -+ * ***************************************************************************** -+ * @brief Allocates memory on behalf of a userspace process that is addressable -+ * by ther kernel. The memory is suitable for mapping into -+ * user space and it is possible to entirely dissociate the memory -+ * from the userspace process via PVRSRVDissociateSharedSysMemoryKM. -+ * -+ * @param psPerProc -+ * @param ui32Flags -+ * @param ui32Size -+ * @param ppsKernelMemInfo -+ * -+ * @return PVRSRV_ERROR -+ ********************************************************************************/ -+IMG_IMPORT PVRSRV_ERROR -+PVRSRVAllocSharedSysMemoryKM(PVRSRV_PER_PROCESS_DATA *psPerProc, -+ IMG_UINT32 ui32Flags, -+ IMG_SIZE_T ui32Size, -+ PVRSRV_KERNEL_MEM_INFO **ppsKernelMemInfo); -+ -+/*! -+ * ***************************************************************************** -+ * @brief Frees memory allocated via PVRSRVAllocSharedSysMemoryKM (Note you must -+ * be sure any additional kernel references you created have been -+ * removed before freeing the memory) -+ * -+ * @param psKernelMemInfo -+ * -+ * @return PVRSRV_ERROR -+ ********************************************************************************/ -+IMG_IMPORT PVRSRV_ERROR -+PVRSRVFreeSharedSysMemoryKM(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo); -+ -+/*! -+****************************************************************************** -+ -+ @brief Dissociates memory from the process that allocates it. Intended for -+ transfering the ownership of system memory from a particular process -+ to the kernel. Unlike PVRSRVDissociateDeviceMemKM, ownership is not -+ transfered to the kernel context, so the Resource Manager will not -+ automatically clean up such memory. -+ -+ @param psKernelMemInfo: -+ -+ @return PVRSRV_ERROR: -+******************************************************************************/ -+IMG_IMPORT PVRSRV_ERROR -+PVRSRVDissociateMemFromResmanKM(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo); -+ -+#if defined (__cplusplus) -+} -+#endif -+ -+#endif /* __PVR_BRIDGE_KM_H_ */ -+ -+/****************************************************************************** -+ End of file (pvr_bridge_km.h) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/include/pvrmmap.h b/drivers/staging/ti-es8-sgx/services4/include/pvrmmap.h -new file mode 100644 -index 0000000..cbccb90 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/include/pvrmmap.h -@@ -0,0 +1,72 @@ -+/*************************************************************************/ /*! -+@Title Main include file for PVRMMAP library. -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+#ifndef __PVRMMAP_H__ -+#define __PVRMMAP_H__ -+ -+/*! -+ ************************************************************************** -+ @brief map kernel memory into user memory. -+ -+ @param hModule - a handle to the device supplying the kernel memory -+ @param ppvLinAddr - pointer to where the user mode address should be placed -+ @param pvLinAddrKM - the base of kernel address range to map -+ @param phMappingInfo - pointer to mapping information handle -+ @param hMHandle - handle associated with memory to be mapped -+ -+ @return PVRSRV_OK, or error code. -+ ***************************************************************************/ -+ -+PVRSRV_ERROR PVRPMapKMem(IMG_HANDLE hModule, IMG_VOID **ppvLinAddr, IMG_VOID *pvLinAddrKM, IMG_HANDLE *phMappingInfo, IMG_HANDLE hMHandle); -+ -+ -+/*! -+ ************************************************************************** -+ @brief Removes a kernel to userspace memory mapping. -+ -+ @param hModule - a handle to the device supplying the kernel memory -+ @param hMappingInfo - mapping information handle -+ @param hMHandle - handle associated with memory to be mapped -+ -+ @return IMG_BOOL indicating success or otherwise. -+ ***************************************************************************/ -+IMG_BOOL PVRUnMapKMem(IMG_HANDLE hModule, IMG_HANDLE hMappingInfo, IMG_HANDLE hMHandle); -+ -+#endif /* _PVRMMAP_H_ */ -diff --git a/drivers/staging/ti-es8-sgx/services4/include/pvrsrv_errors.h b/drivers/staging/ti-es8-sgx/services4/include/pvrsrv_errors.h -new file mode 100644 -index 0000000..2e95810 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/include/pvrsrv_errors.h -@@ -0,0 +1,311 @@ -+/*************************************************************************/ /*! -+@Title error code to string translation utility -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description error code to string translation utility -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#if !defined (__PVRSRV_ERRORS_H__) -+#define __PVRSRV_ERRORS_H__ -+ -+#if defined (__cplusplus) -+extern "C" { -+#endif -+ -+/* -+ NOTE: TO BE INCLUDED ONLY ONCE IN THE UM AND KM SERVICES MODULES -+ PROVIDES IMPLEMENTATIONS OF -+ -+ MUST BE KEPT IN SYNC WITH SERVICESEXT.H -+ -+ PVRSRVGetErrorString -+ PVRSRVGetErrorStringKM -+ Specifically, we have -+ -+ resources.c: -+ IMG_EXPORT -+ const IMG_CHAR *PVRSRVGetErrorString(PVRSRV_ERROR eError) -+ { -+ #include "pvrsrv_errors.h" -+ } -+ -+ pvrsrv.c: -+ IMG_EXPORT -+ const IMG_CHAR *PVRSRVGetErrorStringKM(PVRSRV_ERROR eError) -+ { -+ #include "pvrsrv_errors.h" -+ } -+*/ -+ switch (eError) -+ { -+ case PVRSRV_OK: return "No Errors"; -+ case PVRSRV_ERROR_OUT_OF_MEMORY: return "PVRSRV_ERROR_OUT_OF_MEMORY - Unable to allocate required memory"; -+ case PVRSRV_ERROR_TOO_FEW_BUFFERS: return "PVRSRV_ERROR_TOO_FEW_BUFFERS"; -+ case PVRSRV_ERROR_INVALID_PARAMS: return "PVRSRV_ERROR_INVALID_PARAMS"; -+ case PVRSRV_ERROR_INIT_FAILURE: return "PVRSRV_ERROR_INIT_FAILURE"; -+ case PVRSRV_ERROR_CANT_REGISTER_CALLBACK: return "PVRSRV_ERROR_CANT_REGISTER_CALLBACK"; -+ case PVRSRV_ERROR_INVALID_DEVICE: return "PVRSRV_ERROR_INVALID_DEVICE"; -+ case PVRSRV_ERROR_NOT_OWNER: return "PVRSRV_ERROR_NOT_OWNER"; -+ case PVRSRV_ERROR_BAD_MAPPING: return "PVRSRV_ERROR_BAD_MAPPING"; -+ case PVRSRV_ERROR_TIMEOUT: return "PVRSRV_ERROR_TIMEOUT"; -+ case PVRSRV_ERROR_FLIP_CHAIN_EXISTS: return "PVRSRV_ERROR_FLIP_CHAIN_EXISTS"; -+ case PVRSRV_ERROR_INVALID_SWAPINTERVAL: return "PVRSRV_ERROR_INVALID_SWAPINTERVAL"; -+ case PVRSRV_ERROR_SCENE_INVALID: return "PVRSRV_ERROR_SCENE_INVALID"; -+ case PVRSRV_ERROR_STREAM_ERROR: return "PVRSRV_ERROR_STREAM_ERROR"; -+ case PVRSRV_ERROR_FAILED_DEPENDENCIES: return "PVRSRV_ERROR_FAILED_DEPENDENCIES"; -+ case PVRSRV_ERROR_CMD_NOT_PROCESSED: return "PVRSRV_ERROR_CMD_NOT_PROCESSED"; -+ case PVRSRV_ERROR_CMD_TOO_BIG: return "PVRSRV_ERROR_CMD_TOO_BIG"; -+ case PVRSRV_ERROR_DEVICE_REGISTER_FAILED: return "PVRSRV_ERROR_DEVICE_REGISTER_FAILED"; -+ case PVRSRV_ERROR_TOOMANYBUFFERS: return "PVRSRV_ERROR_TOOMANYBUFFERS"; -+ case PVRSRV_ERROR_NOT_SUPPORTED: return "PVRSRV_ERROR_NOT_SUPPORTED - fix"; -+ case PVRSRV_ERROR_PROCESSING_BLOCKED: return "PVRSRV_ERROR_PROCESSING_BLOCKED"; -+ -+ case PVRSRV_ERROR_CANNOT_FLUSH_QUEUE: return "PVRSRV_ERROR_CANNOT_FLUSH_QUEUE"; -+ case PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE: return "PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE"; -+ case PVRSRV_ERROR_CANNOT_GET_RENDERDETAILS: return "PVRSRV_ERROR_CANNOT_GET_RENDERDETAILS"; -+ case PVRSRV_ERROR_RETRY: return "PVRSRV_ERROR_RETRY"; -+ -+ case PVRSRV_ERROR_DDK_VERSION_MISMATCH: return "PVRSRV_ERROR_DDK_VERSION_MISMATCH"; -+ case PVRSRV_ERROR_BUILD_MISMATCH: return "PVRSRV_ERROR_BUILD_MISMATCH"; -+ case PVRSRV_ERROR_CORE_REVISION_MISMATCH: return "PVRSRV_ERROR_CORE_REVISION_MISMATCH"; -+ -+ case PVRSRV_ERROR_UPLOAD_TOO_BIG: return "PVRSRV_ERROR_UPLOAD_TOO_BIG"; -+ -+ case PVRSRV_ERROR_INVALID_FLAGS: return "PVRSRV_ERROR_INVALID_FLAGS"; -+ case PVRSRV_ERROR_FAILED_TO_REGISTER_PROCESS: return "PVRSRV_ERROR_FAILED_TO_REGISTER_PROCESS"; -+ -+ case PVRSRV_ERROR_UNABLE_TO_LOAD_LIBRARY: return "PVRSRV_ERROR_UNABLE_TO_LOAD_LIBRARY"; -+ case PVRSRV_ERROR_UNABLE_GET_FUNC_ADDR: return "PVRSRV_ERROR_UNABLE_GET_FUNC_ADDR"; -+ case PVRSRV_ERROR_UNLOAD_LIBRARY_FAILED: return "PVRSRV_ERROR_UNLOAD_LIBRARY_FAILED"; -+ -+ case PVRSRV_ERROR_BRIDGE_CALL_FAILED: return "PVRSRV_ERROR_BRIDGE_CALL_FAILED"; -+ case PVRSRV_ERROR_IOCTL_CALL_FAILED: return "PVRSRV_ERROR_IOCTL_CALL_FAILED"; -+ -+ case PVRSRV_ERROR_MMU_CONTEXT_NOT_FOUND: return "PVRSRV_ERROR_MMU_CONTEXT_NOT_FOUND"; -+ case PVRSRV_ERROR_BUFFER_DEVICE_NOT_FOUND: return "PVRSRV_ERROR_BUFFER_DEVICE_NOT_FOUND"; -+ case PVRSRV_ERROR_BUFFER_DEVICE_ALREADY_PRESENT:return "PVRSRV_ERROR_BUFFER_DEVICE_ALREADY_PRESENT"; -+ -+ case PVRSRV_ERROR_PCI_DEVICE_NOT_FOUND: return "PVRSRV_ERROR_PCI_DEVICE_NOT_FOUND"; -+ case PVRSRV_ERROR_PCI_CALL_FAILED: return "PVRSRV_ERROR_PCI_CALL_FAILED"; -+ case PVRSRV_ERROR_PCI_REGION_TOO_SMALL: return "PVRSRV_ERROR_PCI_REGION_TOO_SMALL"; -+ case PVRSRV_ERROR_PCI_REGION_UNAVAILABLE: return "PVRSRV_ERROR_PCI_REGION_UNAVAILABLE"; -+ case PVRSRV_ERROR_BAD_REGION_SIZE_MISMATCH: return "PVRSRV_ERROR_BAD_REGION_SIZE_MISMATCH"; -+ -+ case PVRSRV_ERROR_REGISTER_BASE_NOT_SET: return "PVRSRV_ERROR_REGISTER_BASE_NOT_SET"; -+ -+ case PVRSRV_ERROR_BM_BAD_SHAREMEM_HANDLE: return "PVRSRV_ERROR_BM_BAD_SHAREMEM_HANDLE"; -+ -+ case PVRSRV_ERROR_FAILED_TO_ALLOC_USER_MEM: return "PVRSRV_ERROR_FAILED_TO_ALLOC_USER_MEM"; -+ case PVRSRV_ERROR_FAILED_TO_ALLOC_VP_MEMORY: return "PVRSRV_ERROR_FAILED_TO_ALLOC_VP_MEMORY"; -+ case PVRSRV_ERROR_FAILED_TO_MAP_SHARED_PBDESC: return "PVRSRV_ERROR_FAILED_TO_MAP_SHARED_PBDESC"; -+ case PVRSRV_ERROR_FAILED_TO_GET_PHYS_ADDR: return "PVRSRV_ERROR_FAILED_TO_GET_PHYS_ADDR"; -+ -+ case PVRSRV_ERROR_FAILED_TO_ALLOC_VIRT_MEMORY: return "PVRSRV_ERROR_FAILED_TO_ALLOC_VIRT_MEMORY"; -+ case PVRSRV_ERROR_FAILED_TO_COPY_VIRT_MEMORY: return "PVRSRV_ERROR_FAILED_TO_COPY_VIRT_MEMORY"; -+ -+ case PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES: return "PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES"; -+ case PVRSRV_ERROR_FAILED_TO_FREE_PAGES: return "PVRSRV_ERROR_FAILED_TO_FREE_PAGES"; -+ case PVRSRV_ERROR_FAILED_TO_COPY_PAGES: return "PVRSRV_ERROR_FAILED_TO_COPY_PAGES"; -+ case PVRSRV_ERROR_UNABLE_TO_LOCK_PAGES: return "PVRSRV_ERROR_UNABLE_TO_LOCK_PAGES"; -+ case PVRSRV_ERROR_UNABLE_TO_UNLOCK_PAGES: return "PVRSRV_ERROR_UNABLE_TO_UNLOCK_PAGES"; -+ case PVRSRV_ERROR_STILL_MAPPED: return "PVRSRV_ERROR_STILL_MAPPED"; -+ case PVRSRV_ERROR_MAPPING_NOT_FOUND: return "PVRSRV_ERROR_MAPPING_NOT_FOUND"; -+ case PVRSRV_ERROR_PHYS_ADDRESS_EXCEEDS_32BIT: return "PVRSRV_ERROR_PHYS_ADDRESS_EXCEEDS_32BIT"; -+ case PVRSRV_ERROR_FAILED_TO_MAP_PAGE_TABLE: return "PVRSRV_ERROR_FAILED_TO_MAP_PAGE_TABLE"; -+ -+ case PVRSRV_ERROR_INVALID_SEGMENT_BLOCK: return "PVRSRV_ERROR_INVALID_SEGMENT_BLOCK"; -+ case PVRSRV_ERROR_INVALID_SGXDEVDATA: return "PVRSRV_ERROR_INVALID_SGXDEVDATA"; -+ case PVRSRV_ERROR_INVALID_DEVINFO: return "PVRSRV_ERROR_INVALID_DEVINFO"; -+ case PVRSRV_ERROR_INVALID_MEMINFO: return "PVRSRV_ERROR_INVALID_MEMINFO"; -+ case PVRSRV_ERROR_INVALID_MISCINFO: return "PVRSRV_ERROR_INVALID_MISCINFO"; -+ case PVRSRV_ERROR_UNKNOWN_IOCTL: return "PVRSRV_ERROR_UNKNOWN_IOCTL"; -+ case PVRSRV_ERROR_INVALID_CONTEXT: return "PVRSRV_ERROR_INVALID_CONTEXT"; -+ case PVRSRV_ERROR_UNABLE_TO_DESTROY_CONTEXT: return "PVRSRV_ERROR_UNABLE_TO_DESTROY_CONTEXT"; -+ case PVRSRV_ERROR_INVALID_HEAP: return "PVRSRV_ERROR_INVALID_HEAP"; -+ case PVRSRV_ERROR_INVALID_KERNELINFO: return "PVRSRV_ERROR_INVALID_KERNELINFO"; -+ case PVRSRV_ERROR_UNKNOWN_POWER_STATE: return "PVRSRV_ERROR_UNKNOWN_POWER_STATE"; -+ case PVRSRV_ERROR_INVALID_HANDLE_TYPE: return "PVRSRV_ERROR_INVALID_HANDLE_TYPE"; -+ case PVRSRV_ERROR_INVALID_WRAP_TYPE: return "PVRSRV_ERROR_INVALID_WRAP_TYPE"; -+ case PVRSRV_ERROR_INVALID_PHYS_ADDR: return "PVRSRV_ERROR_INVALID_PHYS_ADDR"; -+ case PVRSRV_ERROR_INVALID_CPU_ADDR: return "PVRSRV_ERROR_INVALID_CPU_ADDR"; -+ case PVRSRV_ERROR_INVALID_HEAPINFO: return "PVRSRV_ERROR_INVALID_HEAPINFO"; -+ case PVRSRV_ERROR_INVALID_PERPROC: return "PVRSRV_ERROR_INVALID_PERPROC"; -+ case PVRSRV_ERROR_FAILED_TO_RETRIEVE_HEAPINFO: return "PVRSRV_ERROR_FAILED_TO_RETRIEVE_HEAPINFO"; -+ case PVRSRV_ERROR_INVALID_MAP_REQUEST: return "PVRSRV_ERROR_INVALID_MAP_REQUEST"; -+ case PVRSRV_ERROR_INVALID_UNMAP_REQUEST: return "PVRSRV_ERROR_INVALID_UNMAP_REQUEST"; -+ case PVRSRV_ERROR_UNABLE_TO_FIND_MAPPING_HEAP: return "PVRSRV_ERROR_UNABLE_TO_FIND_MAPPING_HEAP"; -+ case PVRSRV_ERROR_MAPPING_STILL_IN_USE: return "PVRSRV_ERROR_MAPPING_STILL_IN_USE"; -+ -+ case PVRSRV_ERROR_EXCEEDED_HW_LIMITS: return "PVRSRV_ERROR_EXCEEDED_HW_LIMITS"; -+ case PVRSRV_ERROR_NO_STAGING_BUFFER_ALLOCATED: return "PVRSRV_ERROR_NO_STAGING_BUFFER_ALLOCATED"; -+ -+ case PVRSRV_ERROR_UNABLE_TO_CREATE_PERPROC_AREA:return "PVRSRV_ERROR_UNABLE_TO_CREATE_PERPROC_AREA"; -+ case PVRSRV_ERROR_UNABLE_TO_CREATE_EVENT: return "PVRSRV_ERROR_UNABLE_TO_CREATE_EVENT"; -+ case PVRSRV_ERROR_UNABLE_TO_ENABLE_EVENT: return "PVRSRV_ERROR_UNABLE_TO_ENABLE_EVENT"; -+ case PVRSRV_ERROR_UNABLE_TO_REGISTER_EVENT: return "PVRSRV_ERROR_UNABLE_TO_REGISTER_EVENT"; -+ case PVRSRV_ERROR_UNABLE_TO_DESTROY_EVENT: return "PVRSRV_ERROR_UNABLE_TO_DESTROY_EVENT"; -+ case PVRSRV_ERROR_UNABLE_TO_CREATE_THREAD: return "PVRSRV_ERROR_UNABLE_TO_CREATE_THREAD"; -+ case PVRSRV_ERROR_UNABLE_TO_CLOSE_THREAD: return "PVRSRV_ERROR_UNABLE_TO_CLOSE_THREAD"; -+ case PVRSRV_ERROR_THREAD_READ_ERROR: return "PVRSRV_ERROR_THREAD_READ_ERROR"; -+ case PVRSRV_ERROR_UNABLE_TO_REGISTER_ISR_HANDLER:return "PVRSRV_ERROR_UNABLE_TO_REGISTER_ISR_HANDLER"; -+ case PVRSRV_ERROR_UNABLE_TO_INSTALL_ISR: return "PVRSRV_ERROR_UNABLE_TO_INSTALL_ISR"; -+ case PVRSRV_ERROR_UNABLE_TO_UNINSTALL_ISR: return "PVRSRV_ERROR_UNABLE_TO_UNINSTALL_ISR"; -+ case PVRSRV_ERROR_ISR_ALREADY_INSTALLED: return "PVRSRV_ERROR_ISR_ALREADY_INSTALLED"; -+ case PVRSRV_ERROR_ISR_NOT_INSTALLED: return "PVRSRV_ERROR_ISR_NOT_INSTALLED"; -+ case PVRSRV_ERROR_UNABLE_TO_INITIALISE_INTERRUPT:return "PVRSRV_ERROR_UNABLE_TO_INITIALISE_INTERRUPT"; -+ case PVRSRV_ERROR_UNABLE_TO_RETRIEVE_INFO: return "PVRSRV_ERROR_UNABLE_TO_RETRIEVE_INFO"; -+ case PVRSRV_ERROR_UNABLE_TO_DO_BACKWARDS_BLIT: return "PVRSRV_ERROR_UNABLE_TO_DO_BACKWARDS_BLIT"; -+ case PVRSRV_ERROR_UNABLE_TO_CLOSE_SERVICES: return "PVRSRV_ERROR_UNABLE_TO_CLOSE_SERVICES"; -+ case PVRSRV_ERROR_UNABLE_TO_REGISTER_CONTEXT: return "PVRSRV_ERROR_UNABLE_TO_REGISTER_CONTEXT"; -+ case PVRSRV_ERROR_UNABLE_TO_REGISTER_RESOURCE: return "PVRSRV_ERROR_UNABLE_TO_REGISTER_RESOURCE"; -+ -+ case PVRSRV_ERROR_INVALID_CCB_COMMAND: return "PVRSRV_ERROR_INVALID_CCB_COMMAND"; -+ -+ case PVRSRV_ERROR_UNABLE_TO_LOCK_RESOURCE: return "PVRSRV_ERROR_UNABLE_TO_LOCK_RESOURCE"; -+ case PVRSRV_ERROR_INVALID_LOCK_ID: return "PVRSRV_ERROR_INVALID_LOCK_ID"; -+ case PVRSRV_ERROR_RESOURCE_NOT_LOCKED: return "PVRSRV_ERROR_RESOURCE_NOT_LOCKED"; -+ -+ case PVRSRV_ERROR_FLIP_FAILED: return "PVRSRV_ERROR_FLIP_FAILED"; -+ case PVRSRV_ERROR_UNBLANK_DISPLAY_FAILED: return "PVRSRV_ERROR_UNBLANK_DISPLAY_FAILED"; -+ -+ case PVRSRV_ERROR_TIMEOUT_POLLING_FOR_VALUE: return "PVRSRV_ERROR_TIMEOUT_POLLING_FOR_VALUE"; -+ -+ case PVRSRV_ERROR_CREATE_RENDER_CONTEXT_FAILED: return "PVRSRV_ERROR_CREATE_RENDER_CONTEXT_FAILED"; -+ case PVRSRV_ERROR_UNKNOWN_PRIMARY_FRAG: return "PVRSRV_ERROR_UNKNOWN_PRIMARY_FRAG"; -+ case PVRSRV_ERROR_UNEXPECTED_SECONDARY_FRAG: return "PVRSRV_ERROR_UNEXPECTED_SECONDARY_FRAG"; -+ case PVRSRV_ERROR_UNEXPECTED_PRIMARY_FRAG: return "PVRSRV_ERROR_UNEXPECTED_PRIMARY_FRAG"; -+ -+ case PVRSRV_ERROR_UNABLE_TO_INSERT_FENCE_ID: return "PVRSRV_ERROR_UNABLE_TO_INSERT_FENCE_ID"; -+ -+ case PVRSRV_ERROR_BLIT_SETUP_FAILED: return "PVRSRV_ERROR_BLIT_SETUP_FAILED"; -+ -+ case PVRSRV_ERROR_PDUMP_NOT_AVAILABLE: return "PVRSRV_ERROR_PDUMP_NOT_AVAILABLE"; -+ case PVRSRV_ERROR_PDUMP_BUFFER_FULL: return "PVRSRV_ERROR_PDUMP_BUFFER_FULL"; -+ case PVRSRV_ERROR_PDUMP_BUF_OVERFLOW: return "PVRSRV_ERROR_PDUMP_BUF_OVERFLOW"; -+ case PVRSRV_ERROR_PDUMP_NOT_ACTIVE: return "PVRSRV_ERROR_PDUMP_NOT_ACTIVE"; -+ case PVRSRV_ERROR_INCOMPLETE_LINE_OVERLAPS_PAGES:return "PVRSRV_ERROR_INCOMPLETE_LINE_OVERLAPS_PAGES"; -+ -+ case PVRSRV_ERROR_MUTEX_DESTROY_FAILED: return "PVRSRV_ERROR_MUTEX_DESTROY_FAILED"; -+ case PVRSRV_ERROR_MUTEX_INTERRUPTIBLE_ERROR: return "PVRSRV_ERROR_MUTEX_INTERRUPTIBLE_ERROR"; -+ -+ case PVRSRV_ERROR_INSUFFICIENT_SCRIPT_SPACE: return "PVRSRV_ERROR_INSUFFICIENT_SCRIPT_SPACE"; -+ case PVRSRV_ERROR_INSUFFICIENT_SPACE_FOR_COMMAND:return "PVRSRV_ERROR_INSUFFICIENT_SPACE_FOR_COMMAND"; -+ -+ case PVRSRV_ERROR_PROCESS_NOT_INITIALISED: return "PVRSRV_ERROR_PROCESS_NOT_INITIALISED"; -+ case PVRSRV_ERROR_PROCESS_NOT_FOUND: return "PVRSRV_ERROR_PROCESS_NOT_FOUND"; -+ case PVRSRV_ERROR_SRV_CONNECT_FAILED: return "PVRSRV_ERROR_SRV_CONNECT_FAILED"; -+ case PVRSRV_ERROR_SRV_DISCONNECT_FAILED: return "PVRSRV_ERROR_SRV_DISCONNECT_FAILED"; -+ case PVRSRV_ERROR_DEINT_PHASE_FAILED: return "PVRSRV_ERROR_DEINT_PHASE_FAILED"; -+ case PVRSRV_ERROR_INIT2_PHASE_FAILED: return "PVRSRV_ERROR_INIT2_PHASE_FAILED"; -+ -+ case PVRSRV_ERROR_NO_DC_DEVICES_FOUND: return "PVRSRV_ERROR_NO_DC_DEVICES_FOUND"; -+ case PVRSRV_ERROR_UNABLE_TO_OPEN_DC_DEVICE: return "PVRSRV_ERROR_UNABLE_TO_OPEN_DC_DEVICE"; -+ case PVRSRV_ERROR_UNABLE_TO_REMOVE_DEVICE: return "PVRSRV_ERROR_UNABLE_TO_REMOVE_DEVICE"; -+ case PVRSRV_ERROR_NO_DEVICEDATA_FOUND: return "PVRSRV_ERROR_NO_DEVICEDATA_FOUND"; -+ case PVRSRV_ERROR_NO_DEVICENODE_FOUND: return "PVRSRV_ERROR_NO_DEVICENODE_FOUND"; -+ case PVRSRV_ERROR_NO_CLIENTNODE_FOUND: return "PVRSRV_ERROR_NO_CLIENTNODE_FOUND"; -+ case PVRSRV_ERROR_FAILED_TO_PROCESS_QUEUE: return "PVRSRV_ERROR_FAILED_TO_PROCESS_QUEUE"; -+ -+ case PVRSRV_ERROR_UNABLE_TO_INIT_TASK: return "PVRSRV_ERROR_UNABLE_TO_INIT_TASK"; -+ case PVRSRV_ERROR_UNABLE_TO_SCHEDULE_TASK: return "PVRSRV_ERROR_UNABLE_TO_SCHEDULE_TASK"; -+ case PVRSRV_ERROR_UNABLE_TO_KILL_TASK: return "PVRSRV_ERROR_UNABLE_TO_KILL_TASK"; -+ -+ case PVRSRV_ERROR_UNABLE_TO_ENABLE_TIMER: return "PVRSRV_ERROR_UNABLE_TO_ENABLE_TIMER"; -+ case PVRSRV_ERROR_UNABLE_TO_DISABLE_TIMER: return "PVRSRV_ERROR_UNABLE_TO_DISABLE_TIMER"; -+ case PVRSRV_ERROR_UNABLE_TO_REMOVE_TIMER: return "PVRSRV_ERROR_UNABLE_TO_REMOVE_TIMER"; -+ -+ case PVRSRV_ERROR_UNKNOWN_PIXEL_FORMAT: return "PVRSRV_ERROR_UNKNOWN_PIXEL_FORMAT"; -+ case PVRSRV_ERROR_UNKNOWN_SCRIPT_OPERATION: return "PVRSRV_ERROR_UNKNOWN_SCRIPT_OPERATION"; -+ -+ case PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE: return "PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE"; -+ case PVRSRV_ERROR_HANDLE_NOT_ALLOCATED: return "PVRSRV_ERROR_HANDLE_NOT_ALLOCATED"; -+ case PVRSRV_ERROR_HANDLE_TYPE_MISMATCH: return "PVRSRV_ERROR_HANDLE_TYPE_MISMATCH"; -+ case PVRSRV_ERROR_UNABLE_TO_ADD_HANDLE: return "PVRSRV_ERROR_UNABLE_TO_ADD_HANDLE"; -+ case PVRSRV_ERROR_HANDLE_NOT_SHAREABLE: return "PVRSRV_ERROR_HANDLE_NOT_SHAREABLE"; -+ case PVRSRV_ERROR_HANDLE_NOT_FOUND: return "PVRSRV_ERROR_HANDLE_NOT_FOUND"; -+ case PVRSRV_ERROR_INVALID_SUBHANDLE: return "PVRSRV_ERROR_INVALID_SUBHANDLE"; -+ case PVRSRV_ERROR_HANDLE_BATCH_IN_USE: return "PVRSRV_ERROR_HANDLE_BATCH_IN_USE"; -+ case PVRSRV_ERROR_HANDLE_BATCH_COMMIT_FAILURE: return "PVRSRV_ERROR_HANDLE_BATCH_COMMIT_FAILURE"; -+ -+ case PVRSRV_ERROR_UNABLE_TO_CREATE_HASH_TABLE: return "PVRSRV_ERROR_UNABLE_TO_CREATE_HASH_TABLE"; -+ case PVRSRV_ERROR_INSERT_HASH_TABLE_DATA_FAILED:return "PVRSRV_ERROR_INSERT_HASH_TABLE_DATA_FAILED"; -+ -+ case PVRSRV_ERROR_UNSUPPORTED_BACKING_STORE: return "PVRSRV_ERROR_UNSUPPORTED_BACKING_STORE"; -+ case PVRSRV_ERROR_UNABLE_TO_DESTROY_BM_HEAP: return "PVRSRV_ERROR_UNABLE_TO_DESTROY_BM_HEAP"; -+ -+ case PVRSRV_ERROR_UNKNOWN_INIT_SERVER_STATE: return "PVRSRV_ERROR_UNKNOWN_INIT_SERVER_STATE"; -+ -+ case PVRSRV_ERROR_NO_FREE_DEVICEIDS_AVALIABLE: return "PVRSRV_ERROR_NO_FREE_DEVICEIDS_AVALIABLE"; -+ case PVRSRV_ERROR_INVALID_DEVICEID: return "PVRSRV_ERROR_INVALID_DEVICEID"; -+ case PVRSRV_ERROR_DEVICEID_NOT_FOUND: return "PVRSRV_ERROR_DEVICEID_NOT_FOUND"; -+ -+ case PVRSRV_ERROR_MEMORY_TEST_FAILED: return "PVRSRV_ERROR_MEMORY_TEST_FAILED"; -+ case PVRSRV_ERROR_CPUPADDR_TEST_FAILED: return "PVRSRV_ERROR_CPUPADDR_TEST_FAILED"; -+ case PVRSRV_ERROR_COPY_TEST_FAILED: return "PVRSRV_ERROR_COPY_TEST_FAILED"; -+ -+ case PVRSRV_ERROR_SEMAPHORE_NOT_INITIALISED: return "PVRSRV_ERROR_SEMAPHORE_NOT_INITIALISED"; -+ -+ case PVRSRV_ERROR_UNABLE_TO_RELEASE_CLOCK: return "PVRSRV_ERROR_UNABLE_TO_RELEASE_CLOCK"; -+ case PVRSRV_ERROR_CLOCK_REQUEST_FAILED: return "PVRSRV_ERROR_CLOCK_REQUEST_FAILED"; -+ case PVRSRV_ERROR_DISABLE_CLOCK_FAILURE: return "PVRSRV_ERROR_DISABLE_CLOCK_FAILURE"; -+ case PVRSRV_ERROR_UNABLE_TO_SET_CLOCK_RATE: return "PVRSRV_ERROR_UNABLE_TO_SET_CLOCK_RATE"; -+ case PVRSRV_ERROR_UNABLE_TO_ROUND_CLOCK_RATE: return "PVRSRV_ERROR_UNABLE_TO_ROUND_CLOCK_RATE"; -+ case PVRSRV_ERROR_UNABLE_TO_ENABLE_CLOCK: return "PVRSRV_ERROR_UNABLE_TO_ENABLE_CLOCK"; -+ case PVRSRV_ERROR_UNABLE_TO_GET_CLOCK: return "PVRSRV_ERROR_UNABLE_TO_GET_CLOCK"; -+ case PVRSRV_ERROR_UNABLE_TO_GET_PARENT_CLOCK: return "PVRSRV_ERROR_UNABLE_TO_GET_PARENT_CLOCK"; -+ case PVRSRV_ERROR_UNABLE_TO_GET_SYSTEM_CLOCK: return "PVRSRV_ERROR_UNABLE_TO_GET_SYSTEM_CLOCK"; -+ -+ case PVRSRV_ERROR_UNKNOWN_SGL_ERROR: return "PVRSRV_ERROR_UNKNOWN_SGL_ERROR"; -+ case PVRSRV_ERROR_BAD_SYNC_STATE: return "PVRSRV_ERROR_BAD_SYNC_STATE"; -+ -+ case PVRSRV_ERROR_CACHE_INVALIDATE_FAILED: return "PVRSRV_ERROR_CACHE_INVALIDATE_FAILED"; -+ -+ case PVRSRV_ERROR_FORCE_I32: return "PVRSRV_ERROR_FORCE_I32"; -+ -+ default: -+ return "Unknown PVRSRV error number"; -+ } -+ -+#if defined (__cplusplus) -+} -+#endif -+#endif /* __PVRSRV_ERRORS_H__ */ -+ -+/***************************************************************************** -+ End of file (pvrsrv_errors.h) -+*****************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/include/servicesint.h b/drivers/staging/ti-es8-sgx/services4/include/servicesint.h -new file mode 100644 -index 0000000..0058ad1 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/include/servicesint.h -@@ -0,0 +1,554 @@ -+/*************************************************************************/ /*! -+@Title Services Internal Header -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description services internal details -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#if !defined (__SERVICESINT_H__) -+#define __SERVICESINT_H__ -+ -+#if defined (__cplusplus) -+extern "C" { -+#endif -+ -+#include "services.h" -+#include "sysinfo.h" -+ -+#define HWREC_DEFAULT_TIMEOUT (500) -+ -+#define DRIVERNAME_MAXLENGTH (100) -+ -+/* -+ helper macros: -+*/ -+#define ALIGNSIZE(size, alignshift) (((size) + ((1UL << (alignshift))-1)) & ~((1UL << (alignshift))-1)) -+ -+#ifndef MAX -+#define MAX(a,b) (((a) > (b)) ? (a) : (b)) -+#endif -+#ifndef MIN -+#define MIN(a,b) (((a) < (b)) ? (a) : (b)) -+#endif -+ -+/* -+ Note: -+ MAX_CLEANUP_TRYS is set to try and be around the frame rate -+ as for every try we will kick the uKernel which we want to avoid -+ doing too often (as we risk flooding the uKernel trace buffer -+ with requests and losing important information from before the -+ cleanup requests started). -+*/ -+#define MAX_CLEANUP_TIME_US (MAX_HW_TIME_US * 4) -+#define MAX_CLEANUP_TRYS 100 -+#define MAX_CLEANUP_TIME_WAIT_US (MAX_CLEANUP_TIME_US/MAX_CLEANUP_TRYS) -+ -+typedef enum _PVRSRV_MEMTYPE_ -+{ -+ PVRSRV_MEMTYPE_UNKNOWN = 0, -+ PVRSRV_MEMTYPE_DEVICE = 1, -+ PVRSRV_MEMTYPE_DEVICECLASS = 2, -+ PVRSRV_MEMTYPE_WRAPPED = 3, -+ PVRSRV_MEMTYPE_MAPPED = 4, -+ PVRSRV_MEMTYPE_ION = 5, -+} PVRSRV_MEMTYPE; -+ -+/* -+ Kernel Memory Information structure -+*/ -+typedef struct _PVRSRV_KERNEL_MEM_INFO_ -+{ -+ /* Kernel Mode CPU Virtual address */ -+ IMG_PVOID pvLinAddrKM; -+ -+ /* Device Virtual Address */ -+ IMG_DEV_VIRTADDR sDevVAddr; -+ -+ /* allocation flags */ -+ IMG_UINT32 ui32Flags; -+ -+ /* Size of the allocated buffer in bytes */ -+ IMG_SIZE_T uAllocSize; -+ -+ /* Internal implementation details. Do not use outside services code. */ -+ PVRSRV_MEMBLK sMemBlk; -+ -+ /* Address of the backup buffer used in a save/restore of the surface */ -+ IMG_PVOID pvSysBackupBuffer; -+ -+ /* refcount for allocation, wrapping and mapping */ -+ IMG_UINT32 ui32RefCount; -+ -+ /* Set when free call ocured and a mapping was still open */ -+ IMG_BOOL bPendingFree; -+ -+ -+#if defined(SUPPORT_MEMINFO_IDS) -+ #if !defined(USE_CODE) -+ /* Globally unique "stamp" for allocation (not re-used until wrap) */ -+ IMG_UINT64 ui64Stamp; -+ #else /* !defined(USE_CODE) */ -+ IMG_UINT32 dummy1; -+ IMG_UINT32 dummy2; -+ #endif /* !defined(USE_CODE) */ -+#endif /* defined(SUPPORT_MEMINFO_IDS) */ -+ -+ /* ptr to associated kernel sync info - NULL if no sync */ -+ struct _PVRSRV_KERNEL_SYNC_INFO_ *psKernelSyncInfo; -+ -+ IMG_HANDLE hIonSyncInfo; -+ -+ PVRSRV_MEMTYPE memType; -+ -+ /* -+ To activate the "share mem workaround", add PVRSRV_MEM_XPROC to -+ the flags for the allocation. This will cause the "map" API to -+ call use Alloc Device Mem but will share the underlying memory -+ block and sync data. -+ */ -+ struct { -+ /* Record whether the workaround is active for this -+ allocation. The rest of the fields in this struct are -+ undefined unless this is true */ -+ IMG_BOOL bInUse; -+ -+ /* Store the device cookie handle from the original -+ allocation, as it is not present on the "Map" API. */ -+ IMG_HANDLE hDevCookieInt; -+ -+ /* This is an index into a static array which store -+ information about the underlying allocation */ -+ IMG_UINT32 ui32ShareIndex; -+ -+ /* Original arguments as supplied to original -+ "PVRSRVAllocDeviceMem" call, such that a new call to this -+ function can be later constructed */ -+ IMG_UINT32 ui32OrigReqAttribs; -+ IMG_UINT32 ui32OrigReqSize; -+ IMG_UINT32 ui32OrigReqAlignment; -+ } sShareMemWorkaround; -+} PVRSRV_KERNEL_MEM_INFO; -+ -+ -+/* -+ Kernel Sync Info structure -+*/ -+typedef struct _PVRSRV_KERNEL_SYNC_INFO_ -+{ -+ /* kernel sync data */ -+ PVRSRV_SYNC_DATA *psSyncData; -+ -+ /* Device accessible WriteOp Info */ -+ IMG_DEV_VIRTADDR sWriteOpsCompleteDevVAddr; -+ -+ /* Device accessible ReadOp Info */ -+ IMG_DEV_VIRTADDR sReadOpsCompleteDevVAddr; -+ -+ /* Device accessible ReadOp Info */ -+ IMG_DEV_VIRTADDR sReadOps2CompleteDevVAddr; -+ -+ /* meminfo for sync data */ -+ PVRSRV_KERNEL_MEM_INFO *psSyncDataMemInfoKM; -+ -+ /* Reference count for deferring destruction of syncinfo when it is shared */ -+ /* NB: This is only done for devicemem.c (alloc/map/wrap etc), and -+ not (presently) for deviceclass memory */ -+ IMG_PVOID pvRefCount; -+ -+ /* Resman cleanup, for those created with explicit API */ -+ IMG_HANDLE hResItem; -+ -+ /* Unique ID of the sync object */ -+ IMG_UINT32 ui32UID; -+} PVRSRV_KERNEL_SYNC_INFO; -+ -+/*! -+ ***************************************************************************** -+ * This is a device addressable version of a pvrsrv_sync_oject -+ * - any hw cmd may have an unlimited number of these -+ ****************************************************************************/ -+typedef struct _PVRSRV_DEVICE_SYNC_OBJECT_ -+{ -+ /* KEEP THESE 6 VARIABLES TOGETHER FOR UKERNEL BLOCK LOAD */ -+ IMG_UINT32 ui32ReadOpsPendingVal; -+ IMG_DEV_VIRTADDR sReadOpsCompleteDevVAddr; -+ IMG_UINT32 ui32WriteOpsPendingVal; -+ IMG_DEV_VIRTADDR sWriteOpsCompleteDevVAddr; -+ IMG_UINT32 ui32ReadOps2PendingVal; -+ IMG_DEV_VIRTADDR sReadOps2CompleteDevVAddr; -+} PVRSRV_DEVICE_SYNC_OBJECT; -+ -+/*! -+ ***************************************************************************** -+ * encapsulates a single sync object -+ * - any cmd may have an unlimited number of these -+ ****************************************************************************/ -+typedef struct _PVRSRV_SYNC_OBJECT -+{ -+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfoKM; -+ IMG_UINT32 ui32WriteOpsPending; -+ IMG_UINT32 ui32ReadOpsPending; -+ IMG_UINT32 ui32ReadOps2Pending; -+ -+}PVRSRV_SYNC_OBJECT, *PPVRSRV_SYNC_OBJECT; -+ -+/*! -+ ***************************************************************************** -+ * The `one size fits all' generic command. -+ ****************************************************************************/ -+typedef struct _PVRSRV_COMMAND -+{ -+ IMG_SIZE_T uCmdSize; /*!< total size of command */ -+ IMG_UINT32 ui32DevIndex; /*!< device type - 16bit enum (exported by system) */ -+ IMG_UINT32 CommandType; /*!< command type */ -+ IMG_UINT32 ui32DstSyncCount; /*!< number of dst sync objects */ -+ IMG_UINT32 ui32SrcSyncCount; /*!< number of src sync objects */ -+ PVRSRV_SYNC_OBJECT *psDstSync; /*!< dst sync ptr list, allocated on -+ back of this structure, i.e. is resident in Q */ -+ PVRSRV_SYNC_OBJECT *psSrcSync; /*!< src sync ptr list, allocated on -+ back of this structure, i.e. is resident in Q */ -+ IMG_SIZE_T uDataSize; /*!< Size of Cmd Data Packet -+ - only required in terms of allocating Q space */ -+ IMG_UINT32 ui32ProcessID; /*!< Process ID for debugging */ -+ IMG_VOID *pvData; /*!< data to be passed to Cmd Handler function, -+ allocated on back of this structure, i.e. is resident in Q */ -+ PFN_QUEUE_COMMAND_COMPLETE pfnCommandComplete; /*!< Command complete callback */ -+ IMG_HANDLE hCallbackData; /*!< Command complete callback data */ -+ -+#if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) -+ IMG_VOID *pvCleanupFence; /*!< Sync fence to 'put' after timeline inc() */ -+ IMG_VOID *pvTimeline; /*!< Android sync timeline to inc() */ -+#endif -+}PVRSRV_COMMAND, *PPVRSRV_COMMAND; -+ -+ -+/*! -+ ***************************************************************************** -+ * Circular command buffer structure forming the queue of pending commands. -+ * -+ * Queues are implemented as circular comamnd buffers (CCBs). -+ * The buffer is allocated as a specified size, plus the size of the largest supported command. -+ * The extra size allows commands to be added without worrying about wrapping around at the end. -+ * -+ * Commands are added to the CCB by client processes and consumed within -+ * kernel mode code running from within an L/MISR typically. -+ * -+ * The process of adding a command to a queue is as follows:- -+ * - A `lock' is acquired to prevent other processes from adding commands to a queue -+ * - Data representing the command to be executed, along with it's PVRSRV_SYNC_INFO -+ * dependencies is written to the buffer representing the queue at the queues -+ * current WriteOffset. -+ * - The PVRSRV_SYNC_INFO that the command depends on are updated to reflect -+ * the addition of the new command. -+ * - The WriteOffset is incremented by the size of the command added. -+ * - If the WriteOffset now lies beyound the declared buffer size, it is -+ * reset to zero. -+ * - The semaphore is released. -+ * -+ *****************************************************************************/ -+typedef struct _PVRSRV_QUEUE_INFO_ -+{ -+ IMG_VOID *pvLinQueueKM; /*!< Pointer to the command buffer in the kernel's -+ address space */ -+ -+ IMG_VOID *pvLinQueueUM; /*!< Pointer to the command buffer in the user's -+ address space */ -+ -+ volatile IMG_SIZE_T uReadOffset; /*!< Index into the buffer at which commands are being -+ consumed */ -+ -+ volatile IMG_SIZE_T uWriteOffset; /*!< Index into the buffer at which commands are being -+ added */ -+ -+ IMG_UINT32 *pui32KickerAddrKM; /*!< kicker address in the kernel's -+ address space*/ -+ -+ IMG_UINT32 *pui32KickerAddrUM; /*!< kicker address in the user's -+ address space */ -+ -+ IMG_SIZE_T uQueueSize; /*!< Size in bytes of the buffer - excluding the safety allocation */ -+ -+ IMG_UINT32 ui32ProcessID; /*!< Process ID required by resource locking */ -+ -+ IMG_HANDLE hMemBlock[2]; -+ -+#if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) -+ IMG_UINT32 ui32FenceValue; /*!< 'Target' timeline value when fence signals */ -+ IMG_VOID *pvTimeline; /*!< Android struct sync_timeline object */ -+#endif -+ -+ struct _PVRSRV_QUEUE_INFO_ *psNextKM; /*!< The next queue in the system */ -+}PVRSRV_QUEUE_INFO; -+ -+ -+typedef struct _PVRSRV_HEAP_INFO_KM_ -+{ -+ IMG_UINT32 ui32HeapID; -+ IMG_DEV_VIRTADDR sDevVAddrBase; -+ -+ IMG_HANDLE hDevMemHeap; -+ IMG_UINT32 ui32HeapByteSize; -+ IMG_UINT32 ui32Attribs; -+ IMG_UINT32 ui32XTileStride; -+}PVRSRV_HEAP_INFO_KM; -+ -+ -+/* -+ Event Object information structure -+*/ -+typedef struct _PVRSRV_EVENTOBJECT_KM_ -+{ -+ /* globally unique name of the event object */ -+ IMG_CHAR szName[EVENTOBJNAME_MAXLENGTH]; -+ /* kernel specific handle for the event object */ -+ IMG_HANDLE hOSEventKM; -+ -+} PVRSRV_EVENTOBJECT_KM; -+ -+ -+/*! -+ ****************************************************************************** -+ * Structure to retrieve misc. information from services -+ *****************************************************************************/ -+typedef struct _PVRSRV_MISC_INFO_KM_ -+{ -+ IMG_UINT32 ui32StateRequest; /*!< requested State Flags */ -+ IMG_UINT32 ui32StatePresent; /*!< Present/Valid State Flags */ -+ -+ /*!< SOC Timer register */ -+ IMG_VOID *pvSOCTimerRegisterKM; -+ IMG_VOID *pvSOCTimerRegisterUM; -+ IMG_HANDLE hSOCTimerRegisterOSMemHandle; -+ IMG_HANDLE hSOCTimerRegisterMappingInfo; -+ -+ /*!< SOC Clock Gating registers */ -+ IMG_VOID *pvSOCClockGateRegs; -+ IMG_UINT32 ui32SOCClockGateRegsSize; -+ -+ /* Memory Stats/DDK version string depending on ui32StateRequest flags */ -+ IMG_CHAR *pszMemoryStr; -+ IMG_UINT32 ui32MemoryStrLen; -+ -+ /* global event object */ -+ PVRSRV_EVENTOBJECT_KM sGlobalEventObject;//FIXME: should be private to services -+ IMG_HANDLE hOSGlobalEvent; -+ -+ /* Note: add misc. items as required */ -+ IMG_UINT32 aui32DDKVersion[4]; -+ -+ /*!< CPU cache flush controls: */ -+ struct -+ { -+ /*!< Defer the CPU cache op to the next HW op to be submitted (else flush now) */ -+ IMG_BOOL bDeferOp; -+ -+ /*!< Type of cache operation to perform */ -+ PVRSRV_MISC_INFO_CPUCACHEOP_TYPE eCacheOpType; -+ -+ /*!< Meminfo (or meminfo handle) to flush */ -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; -+ -+ /*!< Offset in MemInfo to start cache op */ -+ IMG_VOID *pvBaseVAddr; -+ -+ /*!< Length of range to perform cache op */ -+ IMG_UINT32 ui32Length; -+ } sCacheOpCtl; -+ -+ /*!< Meminfo refcount controls: */ -+ struct -+ { -+ /*!< Meminfo (or meminfo handle) to get refcount for */ -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; -+ -+ /*!< Resulting refcount */ -+ IMG_UINT32 ui32RefCount; -+ } sGetRefCountCtl; -+} PVRSRV_MISC_INFO_KM; -+ -+ -+/* insert command function pointer */ -+typedef PVRSRV_ERROR (*PFN_INSERT_CMD) (PVRSRV_QUEUE_INFO*, -+ PVRSRV_COMMAND**, -+ IMG_UINT32, -+ IMG_UINT16, -+ IMG_UINT32, -+ PVRSRV_KERNEL_SYNC_INFO*[], -+ IMG_UINT32, -+ PVRSRV_KERNEL_SYNC_INFO*[], -+ IMG_UINT32); -+/* submit command function pointer */ -+typedef PVRSRV_ERROR (*PFN_SUBMIT_CMD) (PVRSRV_QUEUE_INFO*, PVRSRV_COMMAND*, IMG_BOOL); -+ -+ -+/*********************************************************************** -+ Device Class Structures -+***********************************************************************/ -+ -+/* -+ Generic Device Class Buffer -+ - details common between DC and BC -+*/ -+typedef struct PVRSRV_DEVICECLASS_BUFFER_TAG -+{ -+ PFN_GET_BUFFER_ADDR pfnGetBufferAddr; -+ IMG_HANDLE hDevMemContext; -+ IMG_HANDLE hExtDevice; -+ IMG_HANDLE hExtBuffer; -+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo; -+ IMG_UINT32 ui32MemMapRefCount; -+} PVRSRV_DEVICECLASS_BUFFER; -+ -+ -+/* -+ Common Device Class client services information structure -+*/ -+typedef struct PVRSRV_CLIENT_DEVICECLASS_INFO_TAG -+{ -+ IMG_HANDLE hDeviceKM; -+ IMG_HANDLE hServices; -+} PVRSRV_CLIENT_DEVICECLASS_INFO; -+ -+ -+typedef enum -+{ -+ PVRSRV_FREE_CALLBACK_ORIGIN_ALLOCATOR, -+ PVRSRV_FREE_CALLBACK_ORIGIN_IMPORTER, -+ PVRSRV_FREE_CALLBACK_ORIGIN_EXTERNAL, -+} -+PVRSRV_FREE_CALLBACK_ORIGIN; -+ -+ -+IMG_IMPORT -+PVRSRV_ERROR FreeMemCallBackCommon(PVRSRV_KERNEL_MEM_INFO *psMemInfo, -+ IMG_UINT32 ui32Param, -+ PVRSRV_FREE_CALLBACK_ORIGIN eCallbackOrigin); -+ -+ -+IMG_IMPORT -+PVRSRV_ERROR PVRSRVQueueCommand(IMG_HANDLE hQueueInfo, -+ PVRSRV_COMMAND *psCommand); -+ -+ -+/*! -+ * ***************************************************************************** -+ * @Description Allocates system memory on behalf of a userspace process that is -+ * addressable by the kernel; suitable for mapping into the current -+ * user space process; suitable for mapping into other userspace -+ * processes and it is possible to entirely disassociate the system -+ * memory from the current userspace process via a call to -+ * PVRSRVDissociateSharedSysMemoryKM. -+ * -+ * @Input psConnection -+ * @Input ui32Flags -+ * @Input ui32Size -+ * @Output ppsClientMemInfo -+ * -+ * @Return PVRSRV_ERROR -+ ********************************************************************************/ -+IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV -+PVRSRVAllocSharedSysMem(const PVRSRV_CONNECTION *psConnection, -+ IMG_UINT32 ui32Flags, -+ IMG_SIZE_T uSize, -+ PVRSRV_CLIENT_MEM_INFO **ppsClientMemInfo); -+ -+/*! -+ * ***************************************************************************** -+ * @Description Frees memory allocated via PVRSRVAllocSharedMemory (Note you must -+ * be sure any additional kernel references you created have been -+ * removed before freeing the memory) -+ * -+ * @Input psConnection -+ * @Input psClientMemInfo -+ * -+ * @Return PVRSRV_ERROR -+ ********************************************************************************/ -+IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV -+PVRSRVFreeSharedSysMem(const PVRSRV_CONNECTION *psConnection, -+ PVRSRV_CLIENT_MEM_INFO *psClientMemInfo); -+ -+/*! -+ * ***************************************************************************** -+ * @Description Removes any userspace reference to the shared system memory, except -+ * that the memory will remain registered with the services resource -+ * manager so if the process dies/exits the actuall shared memory will -+ * still be freed. -+ * If you need to move ownership of shared memory from userspace -+ * to kernel space then before unrefing a shared piece of memory you can -+ * take a copy of psClientMemInfo->hKernelMemInfo; call -+ * PVRSRVUnrefSharedSysMem; then use some mechanism (specialised bridge -+ * function) to request that the kernel remove any resource manager -+ * reference to the shared memory and assume responsaility for the meminfo -+ * in one atomic operation. (Note to aid with such a kernel space bridge -+ * function see PVRSRVDissociateSharedSysMemoryKM) -+ * -+ * @Input psConnection -+ * @Input psClientMemInfo -+ * -+ * @Return PVRSRV_ERROR -+ ********************************************************************************/ -+IMG_IMPORT PVRSRV_ERROR -+PVRSRVUnrefSharedSysMem(const PVRSRV_CONNECTION *psConnection, -+ PVRSRV_CLIENT_MEM_INFO *psClientMemInfo); -+ -+/*! -+ * ***************************************************************************** -+ * @Description For shared system or device memory that is owned by the kernel, you can -+ * use this function to map the underlying memory into a client using a -+ * handle for the KernelMemInfo. -+ * -+ * @Input psConnection -+ * @Input hKernelMemInfo -+ * @Output ppsClientMemInfo -+ * -+ * @Return PVRSRV_ERROR -+ ********************************************************************************/ -+IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV -+PVRSRVMapMemInfoMem(const PVRSRV_CONNECTION *psConnection, -+ IMG_HANDLE hKernelMemInfo, -+ PVRSRV_CLIENT_MEM_INFO **ppsClientMemInfo); -+ -+ -+#if defined (__cplusplus) -+} -+#endif -+#endif /* __SERVICESINT_H__ */ -+ -+/***************************************************************************** -+ End of file (servicesint.h) -+*****************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/include/sgx_bridge.h b/drivers/staging/ti-es8-sgx/services4/include/sgx_bridge.h -new file mode 100644 -index 0000000..65deae5 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/include/sgx_bridge.h -@@ -0,0 +1,608 @@ -+/*************************************************************************/ /*! -+@Title SGX Bridge Functionality -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Header for the sgx Brdige code -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#if !defined(__SGX_BRIDGE_H__) -+#define __SGX_BRIDGE_H__ -+ -+#include "sgxapi_km.h" -+#include "sgxinfo.h" -+#include "pvr_bridge.h" -+ -+#if defined (__cplusplus) -+extern "C" { -+#endif -+ -+ -+/* -+ * Bridge Cmd Ids -+ */ -+ -+/* *REMEMBER* to update PVRSRV_BRIDGE_LAST_SGX_CMD if you add/remove a command! -+ * Also you need to ensure all PVRSRV_BRIDGE_SGX_CMD_BASE+ offsets are sequential! -+ */ -+ -+#define PVRSRV_BRIDGE_SGX_CMD_BASE (PVRSRV_BRIDGE_LAST_NON_DEVICE_CMD+1) -+#define PVRSRV_BRIDGE_SGX_GETCLIENTINFO PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+0) -+#define PVRSRV_BRIDGE_SGX_RELEASECLIENTINFO PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+1) -+#define PVRSRV_BRIDGE_SGX_GETINTERNALDEVINFO PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+2) -+#define PVRSRV_BRIDGE_SGX_DOKICK PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+3) -+#define PVRSRV_BRIDGE_SGX_GETPHYSPAGEADDR PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+4) -+#define PVRSRV_BRIDGE_SGX_READREGISTRYDWORD PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+5) -+ -+#define PVRSRV_BRIDGE_SGX_2DQUERYBLTSCOMPLETE PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+9) -+ -+#if defined(TRANSFER_QUEUE) -+#define PVRSRV_BRIDGE_SGX_SUBMITTRANSFER PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+13) -+#endif -+#define PVRSRV_BRIDGE_SGX_GETMISCINFO PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+14) -+#define PVRSRV_BRIDGE_SGXINFO_FOR_SRVINIT PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+15) -+#define PVRSRV_BRIDGE_SGX_DEVINITPART2 PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+16) -+ -+#define PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+17) -+#define PVRSRV_BRIDGE_SGX_UNREFSHAREDPBDESC PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+18) -+#define PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+19) -+#define PVRSRV_BRIDGE_SGX_REGISTER_HW_RENDER_CONTEXT PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+20) -+#define PVRSRV_BRIDGE_SGX_FLUSH_HW_RENDER_TARGET PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+21) -+#define PVRSRV_BRIDGE_SGX_UNREGISTER_HW_RENDER_CONTEXT PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+22) -+#if defined(SGX_FEATURE_2D_HARDWARE) -+#define PVRSRV_BRIDGE_SGX_SUBMIT2D PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+23) -+#define PVRSRV_BRIDGE_SGX_REGISTER_HW_2D_CONTEXT PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+24) -+#define PVRSRV_BRIDGE_SGX_UNREGISTER_HW_2D_CONTEXT PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+25) -+#endif -+#define PVRSRV_BRIDGE_SGX_REGISTER_HW_TRANSFER_CONTEXT PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+26) -+#define PVRSRV_BRIDGE_SGX_UNREGISTER_HW_TRANSFER_CONTEXT PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+27) -+ -+#define PVRSRV_BRIDGE_SGX_SCHEDULE_PROCESS_QUEUES PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+28) -+ -+#define PVRSRV_BRIDGE_SGX_READ_HWPERF_CB PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+29) -+#define PVRSRV_BRIDGE_SGX_SET_RENDER_CONTEXT_PRIORITY PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+30) -+#define PVRSRV_BRIDGE_SGX_SET_TRANSFER_CONTEXT_PRIORITY PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+31) -+ -+#if defined(PDUMP) -+#define PVRSRV_BRIDGE_SGX_PDUMP_BUFFER_ARRAY PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+32) -+#define PVRSRV_BRIDGE_SGX_PDUMP_3D_SIGNATURE_REGISTERS PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+33) -+#define PVRSRV_BRIDGE_SGX_PDUMP_COUNTER_REGISTERS PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+34) -+#define PVRSRV_BRIDGE_SGX_PDUMP_TA_SIGNATURE_REGISTERS PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+35) -+#define PVRSRV_BRIDGE_SGX_PDUMP_HWPERFCB PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+36) -+#define PVRSRV_BRIDGE_SGX_PDUMP_SAVEMEM PVRSRV_IOWR(PVRSRV_BRIDGE_SGX_CMD_BASE+37) -+#endif -+ -+ -+ -+/* *REMEMBER* to update PVRSRV_BRIDGE_LAST_SGX_CMD if you add/remove a command! -+ * You need to ensure all PVRSRV_BRIDGE_SGX_CMD_BASE+ offsets are sequential! -+ */ -+#define PVRSRV_BRIDGE_LAST_SGX_CMD (PVRSRV_BRIDGE_SGX_CMD_BASE+37) -+ -+/***************************************************************************** -+ * Input structures for IOCTL/DRVESC -+ *****************************************************************************/ -+ -+/*! -+ ***************************************************************************** -+ * `bridge in' SGX Get Phys Page Addr -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_GETPHYSPAGEADDR -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevMemHeap; -+ IMG_DEV_VIRTADDR sDevVAddr; -+}PVRSRV_BRIDGE_IN_GETPHYSPAGEADDR; -+ -+/*! -+ ***************************************************************************** -+ * `bridge out' SGX Get Phys Page Addr -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_OUT_GETPHYSPAGEADDR -+{ -+ PVRSRV_ERROR eError; -+ IMG_DEV_PHYADDR DevPAddr; -+ IMG_CPU_PHYADDR CpuPAddr; -+}PVRSRV_BRIDGE_OUT_GETPHYSPAGEADDR; -+ -+/*! -+ ***************************************************************************** -+ * `bridge in' set transfer context priority -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_SGX_SET_TRANSFER_CONTEXT_PRIORITY_TAG -+ { -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevCookie; -+ IMG_HANDLE hHWTransferContext; -+ IMG_UINT32 ui32Priority; -+ IMG_UINT32 ui32OffsetOfPriorityField; -+}PVRSRV_BRIDGE_IN_SGX_SET_TRANSFER_CONTEXT_PRIORITY; -+ -+/*! -+ ***************************************************************************** -+ * `bridge in' set render context priority -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_SGX_SET_RENDER_CONTEXT_PRIORITY_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevCookie; -+ IMG_HANDLE hHWRenderContext; -+ IMG_UINT32 ui32Priority; -+ IMG_UINT32 ui32OffsetOfPriorityField; -+}PVRSRV_BRIDGE_IN_SGX_SET_RENDER_CONTEXT_PRIORITY; -+ -+/*! -+ ***************************************************************************** -+ * `bridge in' Get Client Info -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_GETCLIENTINFO_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevCookie; -+}PVRSRV_BRIDGE_IN_GETCLIENTINFO; -+ -+/*! -+ ***************************************************************************** -+ * `bridge out' Get internal device info -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_OUT_GETINTERNALDEVINFO_TAG -+{ -+ SGX_INTERNAL_DEVINFO sSGXInternalDevInfo; -+ PVRSRV_ERROR eError; -+}PVRSRV_BRIDGE_OUT_GETINTERNALDEVINFO; -+ -+/*! -+ ***************************************************************************** -+ * `bridge in' Get internal device info -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_GETINTERNALDEVINFO_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevCookie; -+}PVRSRV_BRIDGE_IN_GETINTERNALDEVINFO; -+ -+/*! -+ ***************************************************************************** -+ * `bridge out' Get Client Info -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_OUT_GETCLIENTINFO_TAG -+{ -+ SGX_CLIENT_INFO sClientInfo; -+ PVRSRV_ERROR eError; -+}PVRSRV_BRIDGE_OUT_GETCLIENTINFO; -+ -+/*! -+ ***************************************************************************** -+ * `bridge in' Release Client Info -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_RELEASECLIENTINFO_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevCookie; -+ SGX_CLIENT_INFO sClientInfo; -+}PVRSRV_BRIDGE_IN_RELEASECLIENTINFO; -+ -+/*! -+ ***************************************************************************** -+ * `bridge in' Pdump ISP mem Pol -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_ISPBREAKPOLL_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevCookie; -+}PVRSRV_BRIDGE_IN_ISPBREAKPOLL; -+ -+/*! -+ ***************************************************************************** -+ * `bridge in' KickTA -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_DOKICK_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevCookie; -+ SGX_CCB_KICK sCCBKick; -+}PVRSRV_BRIDGE_IN_DOKICK; -+ -+/*! -+ ***************************************************************************** -+ * `bridge in' SGXScheduleProcessQueues -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_SGX_SCHEDULE_PROCESS_QUEUES_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevCookie; -+}PVRSRV_BRIDGE_IN_SGX_SCHEDULE_PROCESS_QUEUES; -+ -+ -+#if defined(TRANSFER_QUEUE) -+/*! -+ ***************************************************************************** -+ * `bridge in' SubmitTransfer -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_SUBMITTRANSFER_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevCookie; -+ PVRSRV_TRANSFER_SGX_KICK sKick; -+}PVRSRV_BRIDGE_IN_SUBMITTRANSFER; -+ -+#if defined(SGX_FEATURE_2D_HARDWARE) -+/*! -+ ***************************************************************************** -+ * `bridge in' Submit2D -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_SUBMIT2D_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevCookie; -+ PVRSRV_2D_SGX_KICK sKick; -+} PVRSRV_BRIDGE_IN_SUBMIT2D; -+#endif -+#endif -+ -+/*! -+ ***************************************************************************** -+ * `bridge in' ReadRegistryString -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_READREGDWORD_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevCookie; -+ IMG_PCHAR pszKey; -+ IMG_PCHAR pszValue; -+}PVRSRV_BRIDGE_IN_READREGDWORD; -+ -+/*! -+ ***************************************************************************** -+ * `bridge out' ReadRegistryString -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_OUT_READREGDWORD_TAG -+{ -+ PVRSRV_ERROR eError; -+ IMG_UINT32 ui32Data; -+}PVRSRV_BRIDGE_OUT_READREGDWORD; -+ -+ -+/*! -+ ***************************************************************************** -+ * `bridge in' SGXGetMiscInfo -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_SGXGETMISCINFO_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevCookie; -+ SGX_MISC_INFO *psMiscInfo; -+}PVRSRV_BRIDGE_IN_SGXGETMISCINFO; -+ -+/*! -+ ***************************************************************************** -+ * `bridge in' SGXGetInfoForSrvInit -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_SGXINFO_FOR_SRVINIT_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevCookie; -+}PVRSRV_BRIDGE_IN_SGXINFO_FOR_SRVINIT; -+ -+/*! -+ ***************************************************************************** -+ * `bridge out' SGXGetInfoForSrvInit -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_OUT_SGXINFO_FOR_SRVINIT_TAG -+{ -+ PVRSRV_ERROR eError; -+ SGX_BRIDGE_INFO_FOR_SRVINIT sInitInfo; -+}PVRSRV_BRIDGE_OUT_SGXINFO_FOR_SRVINIT; -+ -+/*! -+ ***************************************************************************** -+ * `bridge in' SGXDevInitPart2 -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_SGXDEVINITPART2_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevCookie; -+ SGX_BRIDGE_INIT_INFO sInitInfo; -+}PVRSRV_BRIDGE_IN_SGXDEVINITPART2; -+ -+/*! -+ ***************************************************************************** -+ * `bridge out' SGXDevInitPart2 -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_OUT_SGXDEVINITPART2_TAG -+{ -+ PVRSRV_ERROR eError; -+ IMG_UINT32 ui32KMBuildOptions; -+ -+}PVRSRV_BRIDGE_OUT_SGXDEVINITPART2; -+ -+/*! -+ ***************************************************************************** -+ * `bridge in' 2D query blits complete -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_2DQUERYBLTSCOMPLETE_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevCookie; -+ IMG_HANDLE hKernSyncInfo; -+ IMG_BOOL bWaitForComplete; -+}PVRSRV_BRIDGE_IN_2DQUERYBLTSCOMPLETE; -+ -+ -+#define PVRSRV_BRIDGE_SGX_SHAREDPBDESC_MAX_SUBMEMINFOS 10 -+ -+typedef struct PVRSRV_BRIDGE_IN_SGXFINDSHAREDPBDESC_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevCookie; -+ IMG_BOOL bLockOnFailure; -+ IMG_UINT32 ui32TotalPBSize; -+}PVRSRV_BRIDGE_IN_SGXFINDSHAREDPBDESC; -+ -+typedef struct PVRSRV_BRIDGE_OUT_SGXFINDSHAREDPBDESC_TAG -+{ -+ IMG_HANDLE hKernelMemInfo; -+ IMG_HANDLE hSharedPBDesc; -+ IMG_HANDLE hSharedPBDescKernelMemInfoHandle; -+ IMG_HANDLE hHWPBDescKernelMemInfoHandle; -+ IMG_HANDLE hBlockKernelMemInfoHandle; -+ IMG_HANDLE hHWBlockKernelMemInfoHandle; -+ IMG_HANDLE ahSharedPBDescSubKernelMemInfoHandles[PVRSRV_BRIDGE_SGX_SHAREDPBDESC_MAX_SUBMEMINFOS]; -+ IMG_UINT32 ui32SharedPBDescSubKernelMemInfoHandlesCount; -+ PVRSRV_ERROR eError; -+}PVRSRV_BRIDGE_OUT_SGXFINDSHAREDPBDESC; -+ -+typedef struct PVRSRV_BRIDGE_IN_SGXUNREFSHAREDPBDESC_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hSharedPBDesc; -+}PVRSRV_BRIDGE_IN_SGXUNREFSHAREDPBDESC; -+ -+typedef struct PVRSRV_BRIDGE_OUT_SGXUNREFSHAREDPBDESC_TAG -+{ -+ PVRSRV_ERROR eError; -+}PVRSRV_BRIDGE_OUT_SGXUNREFSHAREDPBDESC; -+ -+ -+typedef struct PVRSRV_BRIDGE_IN_SGXADDSHAREDPBDESC_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_UINT32 ui32TotalPBSize; -+ IMG_HANDLE hDevCookie; -+ IMG_HANDLE hSharedPBDescKernelMemInfo; -+ IMG_HANDLE hHWPBDescKernelMemInfo; -+ IMG_HANDLE hBlockKernelMemInfo; -+ IMG_HANDLE hHWBlockKernelMemInfo; -+ IMG_HANDLE *phKernelMemInfoHandles; -+ IMG_UINT32 ui32KernelMemInfoHandlesCount; -+ IMG_DEV_VIRTADDR sHWPBDescDevVAddr; -+}PVRSRV_BRIDGE_IN_SGXADDSHAREDPBDESC; -+ -+typedef struct PVRSRV_BRIDGE_OUT_SGXADDSHAREDPBDESC_TAG -+{ -+ PVRSRV_ERROR eError; -+ IMG_HANDLE hSharedPBDesc; -+}PVRSRV_BRIDGE_OUT_SGXADDSHAREDPBDESC; -+ -+ -+#ifdef PDUMP -+typedef struct PVRSRV_BRIDGE_IN_PDUMP_BUFFER_ARRAY_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ SGX_KICKTA_DUMP_BUFFER *psBufferArray; -+ IMG_UINT32 ui32BufferArrayLength; -+ IMG_BOOL bDumpPolls; -+} PVRSRV_BRIDGE_IN_PDUMP_BUFFER_ARRAY; -+ -+typedef struct PVRSRV_BRIDGE_IN_PDUMP_3D_SIGNATURE_REGISTERS_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevCookie; -+ IMG_HANDLE hDevMemContext; -+ IMG_UINT32 ui32DumpFrameNum; -+ IMG_BOOL bLastFrame; -+ IMG_UINT32 *pui32Registers; -+ IMG_UINT32 ui32NumRegisters; -+}PVRSRV_BRIDGE_IN_PDUMP_3D_SIGNATURE_REGISTERS; -+ -+typedef struct PVRSRV_BRIDGE_IN_PDUMPCOUNTER_REGISTERS_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevCookie; -+ IMG_UINT32 ui32DumpFrameNum; -+ IMG_BOOL bLastFrame; -+ IMG_UINT32 *pui32Registers; -+ IMG_UINT32 ui32NumRegisters; -+}PVRSRV_BRIDGE_IN_PDUMP_COUNTER_REGISTERS; -+ -+typedef struct PVRSRV_BRIDGE_IN_PDUMP_TA_SIGNATURE_REGISTERS_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevCookie; -+ IMG_UINT32 ui32DumpFrameNum; -+ IMG_UINT32 ui32TAKickCount; -+ IMG_BOOL bLastFrame; -+ IMG_UINT32 *pui32Registers; -+ IMG_UINT32 ui32NumRegisters; -+}PVRSRV_BRIDGE_IN_PDUMP_TA_SIGNATURE_REGISTERS; -+ -+typedef struct PVRSRV_BRIDGE_IN_PDUMP_HWPERFCB_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevCookie; -+ IMG_HANDLE hDevMemContext; -+ IMG_CHAR szFileName[PVRSRV_PDUMP_MAX_FILENAME_SIZE]; -+ IMG_UINT32 ui32FileOffset; -+ IMG_UINT32 ui32PDumpFlags; -+ -+}PVRSRV_BRIDGE_IN_PDUMP_HWPERFCB; -+ -+typedef struct PVRSRV_BRIDGE_IN_PDUMP_SAVEMEM -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevCookie; -+ IMG_CHAR szFileName[PVRSRV_PDUMP_MAX_FILENAME_SIZE]; -+ IMG_UINT32 ui32FileOffset; -+ IMG_DEV_VIRTADDR sDevVAddr; -+ IMG_UINT32 ui32Size; -+ IMG_HANDLE hDevMemContext; -+ IMG_UINT32 ui32PDumpFlags; -+ -+}PVRSRV_BRIDGE_IN_PDUMP_SAVEMEM; -+ -+#endif -+ -+typedef struct PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_RENDER_CONTEXT_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevCookie; -+ IMG_CPU_VIRTADDR pHWRenderContextCpuVAddr; -+ IMG_UINT32 ui32HWRenderContextSize; -+ IMG_UINT32 ui32OffsetToPDDevPAddr; -+ IMG_HANDLE hDevMemContext; -+}PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_RENDER_CONTEXT; -+ -+typedef struct PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_RENDER_CONTEXT_TAG -+{ -+ PVRSRV_ERROR eError; -+ IMG_HANDLE hHWRenderContext; -+ IMG_DEV_VIRTADDR sHWRenderContextDevVAddr; -+}PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_RENDER_CONTEXT; -+ -+typedef struct PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_RENDER_CONTEXT_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_BOOL bForceCleanup; -+ IMG_HANDLE hDevCookie; -+ IMG_HANDLE hHWRenderContext; -+}PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_RENDER_CONTEXT; -+ -+typedef struct PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_TRANSFER_CONTEXT_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevCookie; -+ IMG_CPU_VIRTADDR pHWTransferContextCpuVAddr; -+ IMG_UINT32 ui32HWTransferContextSize; -+ IMG_UINT32 ui32OffsetToPDDevPAddr; -+ IMG_HANDLE hDevMemContext; -+}PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_TRANSFER_CONTEXT; -+ -+typedef struct PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_TRANSFER_CONTEXT_TAG -+{ -+ PVRSRV_ERROR eError; -+ IMG_HANDLE hHWTransferContext; -+ IMG_DEV_VIRTADDR sHWTransferContextDevVAddr; -+}PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_TRANSFER_CONTEXT; -+ -+typedef struct PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_TRANSFER_CONTEXT_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_BOOL bForceCleanup; -+ IMG_HANDLE hDevCookie; -+ IMG_HANDLE hHWTransferContext; -+}PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_TRANSFER_CONTEXT; -+ -+typedef struct PVRSRV_BRIDGE_IN_SGX_FLUSH_HW_RENDER_TARGET_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevCookie; -+ IMG_DEV_VIRTADDR sHWRTDataSetDevVAddr; -+}PVRSRV_BRIDGE_IN_SGX_FLUSH_HW_RENDER_TARGET; -+ -+/*! -+ ***************************************************************************** -+ * SGX 2D specific defines -+ *****************************************************************************/ -+#if defined(SGX_FEATURE_2D_HARDWARE) -+typedef struct PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_2D_CONTEXT_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevCookie; -+ IMG_CPU_VIRTADDR pHW2DContextCpuVAddr; -+ IMG_UINT32 ui32HW2DContextSize; -+ IMG_UINT32 ui32OffsetToPDDevPAddr; -+ IMG_HANDLE hDevMemContext; -+}PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_2D_CONTEXT; -+ -+typedef struct PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_2D_CONTEXT_TAG -+{ -+ PVRSRV_ERROR eError; -+ IMG_HANDLE hHW2DContext; -+ IMG_DEV_VIRTADDR sHW2DContextDevVAddr; -+}PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_2D_CONTEXT; -+ -+typedef struct PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_2D_CONTEXT_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_BOOL bForceCleanup; -+ IMG_HANDLE hDevCookie; -+ IMG_HANDLE hHW2DContext; -+}PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_2D_CONTEXT; -+ -+#define SGX2D_MAX_BLT_CMD_SIZ 256 /* Maximum size of a blit command, in bytes */ -+#endif /* SGX_FEATURE_2D_HARDWARE */ -+ -+ -+/*! -+ ***************************************************************************** -+ * `bridge in' SGXReadHWPerfCB -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_IN_SGX_READ_HWPERF_CB_TAG -+{ -+ IMG_UINT32 ui32BridgeFlags; /* Must be first member of structure */ -+ IMG_HANDLE hDevCookie; -+ IMG_UINT32 ui32ArraySize; -+ PVRSRV_SGX_HWPERF_CB_ENTRY *psHWPerfCBData; -+} PVRSRV_BRIDGE_IN_SGX_READ_HWPERF_CB; -+ -+/*! -+ ***************************************************************************** -+ * `bridge out' SGXReadHWPerfCB -+ *****************************************************************************/ -+typedef struct PVRSRV_BRIDGE_OUT_SGX_READ_HWPERF_CB_TAG -+{ -+ PVRSRV_ERROR eError; -+ IMG_UINT32 ui32DataCount; -+ IMG_UINT32 ui32ClockSpeed; -+ IMG_UINT32 ui32HostTimeStamp; -+} PVRSRV_BRIDGE_OUT_SGX_READ_HWPERF_CB; -+ -+#if defined (__cplusplus) -+} -+#endif -+ -+#endif /* __SGX_BRIDGE_H__ */ -diff --git a/drivers/staging/ti-es8-sgx/services4/include/sgx_mkif_km.h b/drivers/staging/ti-es8-sgx/services4/include/sgx_mkif_km.h -new file mode 100644 -index 0000000..6a5cb92 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/include/sgx_mkif_km.h -@@ -0,0 +1,473 @@ -+/*************************************************************************/ /*! -+@Title SGX microkernel interface structures used by srvkm -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description SGX microkernel interface structures used by srvkm -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#if !defined (__SGX_MKIF_KM_H__) -+#define __SGX_MKIF_KM_H__ -+ -+#include "img_types.h" -+#include "servicesint.h" -+#include "sgxapi_km.h" -+ -+ -+#if !defined (SGX_MP_CORE_SELECT) -+/* MP register control macros */ -+#if defined(SGX_FEATURE_MP) -+ #define SGX_REG_BANK_SHIFT (14) -+ #define SGX_REG_BANK_SIZE (1 << SGX_REG_BANK_SHIFT) -+ #define SGX_REG_BANK_BASE_INDEX (2) -+ #define SGX_REG_BANK_MASTER_INDEX (1) -+ #define SGX_MP_CORE_SELECT(x,i) (x + ((i + SGX_REG_BANK_BASE_INDEX) * SGX_REG_BANK_SIZE)) -+ #define SGX_MP_MASTER_SELECT(x) (x + (SGX_REG_BANK_MASTER_INDEX * SGX_REG_BANK_SIZE)) -+#else -+ #define SGX_MP_CORE_SELECT(x,i) (x) -+#endif /* SGX_FEATURE_MP */ -+#endif -+ -+ -+/*! -+ ****************************************************************************** -+ * CCB command structure for SGX -+ *****************************************************************************/ -+typedef struct _SGXMKIF_COMMAND_ -+{ -+ IMG_UINT32 ui32ServiceAddress; /*!< address of the USE command handler */ -+ IMG_UINT32 ui32CacheControl; /*!< See SGXMKIF_CC_INVAL_* */ -+ IMG_UINT32 ui32Data[6]; /*!< array of other command control words */ -+} SGXMKIF_COMMAND; -+ -+ -+/*! -+ ****************************************************************************** -+ * CCB array of commands for SGX -+ *****************************************************************************/ -+typedef struct _PVRSRV_SGX_KERNEL_CCB_ -+{ -+ SGXMKIF_COMMAND asCommands[256]; /*!< array of commands */ -+} PVRSRV_SGX_KERNEL_CCB; -+ -+ -+/*! -+ ****************************************************************************** -+ * CCB control for SGX -+ *****************************************************************************/ -+typedef struct _PVRSRV_SGX_CCB_CTL_ -+{ -+ IMG_UINT32 ui32WriteOffset; /*!< write offset into array of commands (MUST be alligned to 16 bytes!) */ -+ IMG_UINT32 ui32ReadOffset; /*!< read offset into array of commands */ -+} PVRSRV_SGX_CCB_CTL; -+ -+ -+/*! -+ ***************************************************************************** -+ * Control data for SGX -+ *****************************************************************************/ -+typedef struct _SGXMKIF_HOST_CTL_ -+{ -+#if defined(PVRSRV_USSE_EDM_BREAKPOINTS) -+ IMG_UINT32 ui32BreakpointDisable; -+ IMG_UINT32 ui32Continue; -+#endif -+ -+ volatile IMG_UINT32 ui32InitStatus; /*!< Microkernel Initialisation status */ -+ volatile IMG_UINT32 ui32PowerStatus; /*!< Microkernel Power Management status */ -+ volatile IMG_UINT32 ui32CleanupStatus; /*!< Microkernel Resource Management status */ -+#if defined(FIX_HW_BRN_28889) -+ volatile IMG_UINT32 ui32InvalStatus; /*!< Microkernel BIF Cache Invalidate status */ -+#endif -+#if defined(SUPPORT_HW_RECOVERY) -+ IMG_UINT32 ui32uKernelDetectedLockups; /*!< counter relating to the number of lockups the uKernel has detected */ -+ IMG_UINT32 ui32HostDetectedLockups; /*!< counter relating to the number of lockups the host has detected */ -+ IMG_UINT32 ui32HWRecoverySampleRate; /*!< SGX lockup detection rate (in multiples of the timer period) */ -+#endif /* SUPPORT_HW_RECOVERY*/ -+ IMG_UINT32 ui32uKernelTimerClock; /*!< SGX ukernel timer period (in clocks) */ -+ IMG_UINT32 ui32ActivePowManSampleRate; /*!< SGX Active Power latency period (in multiples of the timer period) */ -+ IMG_UINT32 ui32InterruptFlags; /*!< Interrupt flags - PVRSRV_USSE_EDM_INTERRUPT_xxx */ -+ IMG_UINT32 ui32InterruptClearFlags; /*!< Interrupt clear flags - PVRSRV_USSE_EDM_INTERRUPT_xxx */ -+ IMG_UINT32 ui32BPSetClearSignal; /*!< Breakpoint set/cear signal */ -+ -+ IMG_UINT32 ui32NumActivePowerEvents; /*!< counter for the number of active power events */ -+ -+ IMG_UINT32 ui32TimeWraps; /*!< to count time wraps in the Timer task*/ -+ IMG_UINT32 ui32HostClock; /*!< Host clock value at microkernel power-up time */ -+ IMG_UINT32 ui32AssertFail; /*!< Microkernel assert failure code */ -+ -+#if defined(SGX_FEATURE_EXTENDED_PERF_COUNTERS) -+ IMG_UINT32 aui32PerfGroup[PVRSRV_SGX_HWPERF_NUM_COUNTERS]; /*!< Specifies the HW's active group selectors */ -+ IMG_UINT32 aui32PerfBit[PVRSRV_SGX_HWPERF_NUM_COUNTERS]; /*!< Specifies the HW's active bit selectors */ -+ IMG_UINT32 ui32PerfCounterBitSelect; /*!< Specifies the HW's counter bit selectors */ -+ IMG_UINT32 ui32PerfSumMux; /*!< Specifies the HW's sum_mux selectors */ -+#else -+ IMG_UINT32 ui32PerfGroup; /*!< Specifies the HW's active group */ -+#endif /* SGX_FEATURE_EXTENDED_PERF_COUNTERS */ -+ -+ IMG_UINT32 ui32OpenCLDelayCount; /* Counter to keep track OpenCL task completion time in units of regular task time out events */ -+ IMG_UINT32 ui32InterruptCount; -+} SGXMKIF_HOST_CTL; -+ -+/* -+ * TA queue Kick flags -+ */ -+/* Set in DoKickKM to indicate the command is ready to be processed */ -+#define SGXMKIF_CMDTA_CTRLFLAGS_READY 0x00000001 -+/*! -+ ****************************************************************************** -+ * Shared TA command structure. -+ * This structure is part of the TA command structure proper (SGXMKIF_CMDTA), -+ * and is accessed from the kernel part of the driver and the microkernel. -+ * There shouldn't be a need to access it from user space. -+ *****************************************************************************/ -+typedef struct _SGXMKIF_CMDTA_SHARED_ -+{ -+ IMG_UINT32 ui32CtrlFlags; -+ -+ IMG_UINT32 ui32NumTAStatusVals; -+ IMG_UINT32 ui32Num3DStatusVals; -+ -+ /* KEEP THESE 4 VARIABLES TOGETHER FOR UKERNEL BLOCK LOAD */ -+ IMG_UINT32 ui32TATQSyncWriteOpsPendingVal; -+ IMG_DEV_VIRTADDR sTATQSyncWriteOpsCompleteDevVAddr; -+ IMG_UINT32 ui32TATQSyncReadOpsPendingVal; -+ IMG_DEV_VIRTADDR sTATQSyncReadOpsCompleteDevVAddr; -+ -+ /* KEEP THESE 4 VARIABLES TOGETHER FOR UKERNEL BLOCK LOAD */ -+ IMG_UINT32 ui323DTQSyncWriteOpsPendingVal; -+ IMG_DEV_VIRTADDR s3DTQSyncWriteOpsCompleteDevVAddr; -+ IMG_UINT32 ui323DTQSyncReadOpsPendingVal; -+ IMG_DEV_VIRTADDR s3DTQSyncReadOpsCompleteDevVAddr; -+ -+ /* sync criteria used for TA/3D dependency synchronisation */ -+ PVRSRV_DEVICE_SYNC_OBJECT sTA3DDependency; -+ -+#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS) -+ /* SRC and DST syncs */ -+ IMG_UINT32 ui32NumTASrcSyncs; -+ PVRSRV_DEVICE_SYNC_OBJECT asTASrcSyncs[SGX_MAX_TA_SRC_SYNCS]; -+ IMG_UINT32 ui32NumTADstSyncs; -+ PVRSRV_DEVICE_SYNC_OBJECT asTADstSyncs[SGX_MAX_TA_DST_SYNCS]; -+ IMG_UINT32 ui32Num3DSrcSyncs; -+ PVRSRV_DEVICE_SYNC_OBJECT as3DSrcSyncs[SGX_MAX_3D_SRC_SYNCS]; -+#else -+ /* source dependency details */ -+ IMG_UINT32 ui32NumSrcSyncs; -+ PVRSRV_DEVICE_SYNC_OBJECT asSrcSyncs[SGX_MAX_SRC_SYNCS_TA]; -+#endif -+ -+ CTL_STATUS sCtlTAStatusInfo[SGX_MAX_TA_STATUS_VALS]; -+ CTL_STATUS sCtl3DStatusInfo[SGX_MAX_3D_STATUS_VALS]; -+ -+} SGXMKIF_CMDTA_SHARED; -+ -+/* -+ * Services internal TQ limits -+ */ -+#define SGXTQ_MAX_STATUS SGX_MAX_TRANSFER_STATUS_VALS + 2 -+ -+/* -+ * Transfer queue Kick flags -+ */ -+/* if set the uKernel won't update the sync objects on completion*/ -+#define SGXMKIF_TQFLAGS_NOSYNCUPDATE 0x00000001 -+/* if set the kernel won't advance the pending values*/ -+#define SGXMKIF_TQFLAGS_KEEPPENDING 0x00000002 -+/* in services equivalent for the same client flags*/ -+#define SGXMKIF_TQFLAGS_TATQ_SYNC 0x00000004 -+#define SGXMKIF_TQFLAGS_3DTQ_SYNC 0x00000008 -+#if defined(SGX_FEATURE_FAST_RENDER_CONTEXT_SWITCH) -+#define SGXMKIF_TQFLAGS_CTXSWITCH 0x00000010 -+#endif -+/* if set uKernel only updates syncobjects / status values*/ -+#define SGXMKIF_TQFLAGS_DUMMYTRANSFER 0x00000020 -+ -+/*! -+ ****************************************************************************** -+ * Shared Transfer Queue command structure. -+ * This structure is placed at the start of the TQ command structure proper -+ * (SGXMKIF_TRANSFERCMD), and is accessed from the kernel part of the driver -+ * and the microkernel. -+ *****************************************************************************/ -+typedef struct _SGXMKIF_TRANSFERCMD_SHARED_ -+{ -+ /* need to be able to check read and write ops on src, and update reads */ -+ -+ IMG_UINT32 ui32NumSrcSyncs; -+ PVRSRV_DEVICE_SYNC_OBJECT asSrcSyncs[SGX_MAX_SRC_SYNCS_TQ]; -+ /* need to be able to check reads and writes on dest, and update writes */ -+ -+ IMG_UINT32 ui32NumDstSyncs; -+ PVRSRV_DEVICE_SYNC_OBJECT asDstSyncs[SGX_MAX_DST_SYNCS_TQ]; -+ /* KEEP THESE 4 VARIABLES TOGETHER FOR UKERNEL BLOCK LOAD */ -+ IMG_UINT32 ui32TASyncWriteOpsPendingVal; -+ IMG_DEV_VIRTADDR sTASyncWriteOpsCompleteDevVAddr; -+ IMG_UINT32 ui32TASyncReadOpsPendingVal; -+ IMG_DEV_VIRTADDR sTASyncReadOpsCompleteDevVAddr; -+ -+ /* KEEP THESE 4 VARIABLES TOGETHER FOR UKERNEL BLOCK LOAD */ -+ IMG_UINT32 ui323DSyncWriteOpsPendingVal; -+ IMG_DEV_VIRTADDR s3DSyncWriteOpsCompleteDevVAddr; -+ IMG_UINT32 ui323DSyncReadOpsPendingVal; -+ IMG_DEV_VIRTADDR s3DSyncReadOpsCompleteDevVAddr; -+ -+ IMG_UINT32 ui32NumStatusVals; -+ CTL_STATUS sCtlStatusInfo[SGXTQ_MAX_STATUS]; -+} SGXMKIF_TRANSFERCMD_SHARED, *PSGXMKIF_TRANSFERCMD_SHARED; -+ -+ -+#if defined(SGX_FEATURE_2D_HARDWARE) -+typedef struct _SGXMKIF_2DCMD_SHARED_ { -+ /* need to be able to check read and write ops on src, and update reads */ -+ IMG_UINT32 ui32NumSrcSync; -+ PVRSRV_DEVICE_SYNC_OBJECT sSrcSyncData[SGX_MAX_2D_SRC_SYNC_OPS]; -+ -+ /* need to be able to check reads and writes on dest, and update writes */ -+ PVRSRV_DEVICE_SYNC_OBJECT sDstSyncData; -+ -+ /* need to be able to check reads and writes on TA ops, and update writes */ -+ PVRSRV_DEVICE_SYNC_OBJECT sTASyncData; -+ -+ /* need to be able to check reads and writes on 2D ops, and update writes */ -+ PVRSRV_DEVICE_SYNC_OBJECT s3DSyncData; -+ -+ IMG_UINT32 ui32NumStatusVals; -+ CTL_STATUS sCtlStatusInfo[SGXTQ_MAX_STATUS]; -+} SGXMKIF_2DCMD_SHARED, *PSGXMKIF_2DCMD_SHARED; -+#endif /* SGX_FEATURE_2D_HARDWARE */ -+ -+ -+typedef struct _SGXMKIF_HWDEVICE_SYNC_LIST_ -+{ -+ IMG_DEV_VIRTADDR sAccessDevAddr; -+ IMG_UINT32 ui32NumSyncObjects; -+ /* Must be the last variable in the structure */ -+ PVRSRV_DEVICE_SYNC_OBJECT asSyncData[1]; -+} SGXMKIF_HWDEVICE_SYNC_LIST, *PSGXMKIF_HWDEVICE_SYNC_LIST; -+ -+ -+/*! -+ ***************************************************************************** -+ * Microkernel initialisation status -+ *****************************************************************************/ -+#define PVRSRV_USSE_EDM_INIT_COMPLETE (1UL << 0) /*!< ukernel initialisation complete */ -+ -+/*! -+ ***************************************************************************** -+ * Microkernel power status definitions -+ *****************************************************************************/ -+#define PVRSRV_USSE_EDM_POWMAN_IDLE_COMPLETE (1UL << 2) /*!< Signal from ukernel->Host indicating SGX is idle */ -+#define PVRSRV_USSE_EDM_POWMAN_POWEROFF_COMPLETE (1UL << 3) /*!< Signal from ukernel->Host indicating SGX can be powered down */ -+#define PVRSRV_USSE_EDM_POWMAN_POWEROFF_RESTART_IMMEDIATE (1UL << 4) /*!< Signal from ukernel->Host indicating there is work to do immediately */ -+#define PVRSRV_USSE_EDM_POWMAN_NO_WORK (1UL << 5) /*!< Signal from ukernel->Host indicating no work to do */ -+ -+/*! -+ ***************************************************************************** -+ * EDM interrupt defines -+ *****************************************************************************/ -+#define PVRSRV_USSE_EDM_INTERRUPT_HWR (1UL << 0) /*!< EDM requesting hardware recovery */ -+#define PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER (1UL << 1) /*!< EDM requesting to be powered down */ -+#define PVRSRV_USSE_EDM_INTERRUPT_IDLE (1UL << 2) /*!< EDM indicating SGX idle */ -+ -+/*! -+ ***************************************************************************** -+ * EDM Resource management defines -+ *****************************************************************************/ -+#define PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE (1UL << 0) /*!< Signal from EDM->Host indicating clean-up request completion */ -+#define PVRSRV_USSE_EDM_CLEANUPCMD_BUSY (1UL << 1) /*!< Signal from EDM->Host indicating clean-up is blocked as the resource is busy */ -+#define PVRSRV_USSE_EDM_CLEANUPCMD_DONE (1UL << 2) /*!< Signal from EDM->Host indicating clean-up has been done */ -+ -+#if defined(FIX_HW_BRN_28889) -+/*! -+ ***************************************************************************** -+ * EDM BIF Cache Invalidate defines -+ *****************************************************************************/ -+#define PVRSRV_USSE_EDM_BIF_INVAL_COMPLETE (1UL << 0) /*!< Signal from EDM->Host indicating the BIF invalidate has started */ -+#endif -+ -+/*! -+ **************************************************************************** -+ * EDM / uKernel Get misc info defines -+ **************************************************************************** -+ */ -+#define PVRSRV_USSE_MISCINFO_READY 0x1UL -+#define PVRSRV_USSE_MISCINFO_GET_STRUCT_SIZES 0x2UL /*!< If set, getmiscinfo ukernel func returns structure sizes */ -+#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG) -+#define PVRSRV_USSE_MISCINFO_MEMREAD 0x4UL /*!< If set, getmiscinfo ukernel func reads arbitrary device mem */ -+#define PVRSRV_USSE_MISCINFO_MEMWRITE 0x8UL /*!< If set, getmiscinfo ukernel func writes arbitrary device mem */ -+#if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) -+#define PVRSRV_USSE_MISCINFO_MEMREAD_FAIL 0x1UL << 31 /* If set, ukernel was unable to read from the mem context */ -+#endif -+#endif -+ -+ -+/* Cleanup command control word */ -+#define PVRSRV_CLEANUPCMD_RT 0x1U -+#define PVRSRV_CLEANUPCMD_RC 0x2U -+#define PVRSRV_CLEANUPCMD_TC 0x3U -+#define PVRSRV_CLEANUPCMD_2DC 0x4U -+#define PVRSRV_CLEANUPCMD_PB 0x5U -+ -+/* Power command control word */ -+#define PVRSRV_POWERCMD_POWEROFF 0x1U -+#define PVRSRV_POWERCMD_IDLE 0x2U -+#define PVRSRV_POWERCMD_RESUME 0x3U -+ -+/* Context suspend command control word */ -+#define PVRSRV_CTXSUSPCMD_SUSPEND 0x1U -+#define PVRSRV_CTXSUSPCMD_RESUME 0x2U -+ -+ -+#if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) -+#define SGX_BIF_DIR_LIST_INDEX_EDM (SGX_FEATURE_BIF_NUM_DIRLISTS - 1) -+#else -+#define SGX_BIF_DIR_LIST_INDEX_EDM (0) -+#endif -+ -+/*! -+ ****************************************************************************** -+ * microkernel cache control requests -+ ******************************************************************************/ -+#define SGXMKIF_CC_INVAL_BIF_PT 0x1 -+#define SGXMKIF_CC_INVAL_BIF_PD 0x2 -+#define SGXMKIF_CC_INVAL_BIF_SL 0x4 -+#define SGXMKIF_CC_INVAL_DATA 0x8 -+ -+ -+/*! -+ ****************************************************************************** -+ * SGX microkernel interface structure sizes -+ ******************************************************************************/ -+typedef struct _SGX_MISCINFO_STRUCT_SIZES_ -+{ -+#if defined (SGX_FEATURE_2D_HARDWARE) -+ IMG_UINT32 ui32Sizeof_2DCMD; -+ IMG_UINT32 ui32Sizeof_2DCMD_SHARED; -+#endif -+ IMG_UINT32 ui32Sizeof_CMDTA; -+ IMG_UINT32 ui32Sizeof_CMDTA_SHARED; -+ IMG_UINT32 ui32Sizeof_TRANSFERCMD; -+ IMG_UINT32 ui32Sizeof_TRANSFERCMD_SHARED; -+ IMG_UINT32 ui32Sizeof_3DREGISTERS; -+ IMG_UINT32 ui32Sizeof_HWPBDESC; -+ IMG_UINT32 ui32Sizeof_HWRENDERCONTEXT; -+ IMG_UINT32 ui32Sizeof_HWRENDERDETAILS; -+ IMG_UINT32 ui32Sizeof_HWRTDATA; -+ IMG_UINT32 ui32Sizeof_HWRTDATASET; -+ IMG_UINT32 ui32Sizeof_HWTRANSFERCONTEXT; -+ IMG_UINT32 ui32Sizeof_HOST_CTL; -+ IMG_UINT32 ui32Sizeof_COMMAND; -+} SGX_MISCINFO_STRUCT_SIZES; -+ -+ -+#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG) -+/*! -+ ***************************************************************************** -+ * SGX misc info for accessing device memory from ukernel -+ ***************************************************************************** -+ */ -+typedef struct _PVRSRV_SGX_MISCINFO_MEMACCESS -+{ -+ IMG_DEV_VIRTADDR sDevVAddr; /*!< dev virtual addr for mem access */ -+ IMG_DEV_PHYADDR sPDDevPAddr; /*!< device physical addr of PD for the mem heap */ -+} PVRSRV_SGX_MISCINFO_MEMACCESS; -+#endif -+ -+/*! -+ ***************************************************************************** -+ * SGX Misc Info structure used in the microkernel -+ * PVRSRV_SGX_MISCINFO_FEATURES is defined in sgxapi_km.h -+ ****************************************************************************/ -+typedef struct _PVRSRV_SGX_MISCINFO_INFO -+{ -+ IMG_UINT32 ui32MiscInfoFlags; -+ PVRSRV_SGX_MISCINFO_FEATURES sSGXFeatures; /*!< external info for client */ -+ SGX_MISCINFO_STRUCT_SIZES sSGXStructSizes; /*!< internal info: microkernel structure sizes */ -+#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG) -+ PVRSRV_SGX_MISCINFO_MEMACCESS sSGXMemAccessSrc; /*!< internal info: for reading dev memory */ -+ PVRSRV_SGX_MISCINFO_MEMACCESS sSGXMemAccessDest; /*!< internal info: for writing dev memory */ -+#endif -+} PVRSRV_SGX_MISCINFO_INFO; -+ -+#ifdef PVRSRV_USSE_EDM_STATUS_DEBUG -+/*! -+ ***************************************************************************** -+ * Number of entries in the microkernel status buffer -+ *****************************************************************************/ -+#define SGXMK_TRACE_BUFFER_SIZE 512 -+#endif /* PVRSRV_USSE_EDM_STATUS_DEBUG */ -+ -+#define SGXMKIF_HWPERF_CB_SIZE 0x100 /* must be 2^n*/ -+ -+/*! -+ ***************************************************************************** -+ * One entry in the HWPerf Circular Buffer. -+ *****************************************************************************/ -+typedef struct _SGXMKIF_HWPERF_CB_ENTRY_ -+{ -+ IMG_UINT32 ui32FrameNo; -+ IMG_UINT32 ui32PID; -+ IMG_UINT32 ui32RTData; -+ IMG_UINT32 ui32Type; -+ IMG_UINT32 ui32Ordinal; -+ IMG_UINT32 ui32Info; -+ IMG_UINT32 ui32TimeWraps; -+ IMG_UINT32 ui32Time; -+ /* NOTE: There should always be at least as many 3D cores as TA cores. */ -+ IMG_UINT32 ui32Counters[SGX_FEATURE_MP_CORE_COUNT_3D][PVRSRV_SGX_HWPERF_NUM_COUNTERS]; -+ IMG_UINT32 ui32MiscCounters[SGX_FEATURE_MP_CORE_COUNT_3D][PVRSRV_SGX_HWPERF_NUM_MISC_COUNTERS]; -+} SGXMKIF_HWPERF_CB_ENTRY; -+ -+/*! -+ ***************************************************************************** -+ * The HWPerf Circular Buffer. -+ *****************************************************************************/ -+typedef struct _SGXMKIF_HWPERF_CB_ -+{ -+ IMG_UINT32 ui32Woff; -+ IMG_UINT32 ui32Roff; -+ IMG_UINT32 ui32Ordinal; -+ SGXMKIF_HWPERF_CB_ENTRY psHWPerfCBData[SGXMKIF_HWPERF_CB_SIZE]; -+} SGXMKIF_HWPERF_CB; -+ -+ -+#endif /* __SGX_MKIF_KM_H__ */ -+ -+/****************************************************************************** -+ End of file (sgx_mkif_km.h) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/include/sgx_ukernel_status_codes.h b/drivers/staging/ti-es8-sgx/services4/include/sgx_ukernel_status_codes.h -new file mode 100644 -index 0000000..141a917 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/include/sgx_ukernel_status_codes.h -@@ -0,0 +1,984 @@ -+/*************************************************************************/ /*! -+@File sgx_ukernel_status_codes.h -+@Title SGX microkernel debug status codes -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description SGX microkernel debug status codes -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#ifndef __SGX_UKERNEL_STATUS_CODES_H__ -+#define __SGX_UKERNEL_STATUS_CODES_H__ -+ -+/* -+ NOTE: Do not add any conditional macros to this file! There must be -+ no use of #if defined(). This file is included in srvkm to print -+ stringified ukernel status codes, it must build identically to -+ srvinit. -+*/ -+ -+/* -+ Users of this header might define this macro to do something -+ clever; the primary use right now is to generate a switch/case -+ LUT for debugging in srvkm. If you add a new code, make sure it -+ has a corresponding MKTC_ST. -+*/ -+#ifndef MKTC_ST -+#define MKTC_ST(x) -+#endif -+ -+/* -+ It would be nice to put these definitions into an enumeration, but USEASM -+ only has access to the C preprocessor so macros are required. -+*/ -+ -+/* -+ Bits 24-31 of these codes (0xAD) are a magic number used to help -+ distinguish between them and other debug information which can be -+ optionally dumped into the status buffer, e.g. sync object values. -+*/ -+ -+/* -+ Microkernel trace codes -+*/ -+#define MKTC_EHEVENT_3DMEMFREE 0xAD000001 -+MKTC_ST(MKTC_EHEVENT_3DMEMFREE) -+#define MKTC_EHEVENT_PIXELENDRENDER 0xAD000002 -+MKTC_ST(MKTC_EHEVENT_PIXELENDRENDER) -+#define MKTC_EHEVENT_ISPBREAKPOINT 0xAD000004 -+MKTC_ST(MKTC_EHEVENT_ISPBREAKPOINT) -+#define MKTC_EHEVENT_TAFINISHED 0xAD000005 -+MKTC_ST(MKTC_EHEVENT_TAFINISHED) -+#define MKTC_EHEVENT_OUTOFMEM 0xAD000007 -+MKTC_ST(MKTC_EHEVENT_OUTOFMEM) -+#define MKTC_EHEVENT_TATERMINATE 0xAD000008 -+MKTC_ST(MKTC_EHEVENT_TATERMINATE) -+#define MKTC_EHEVENT_TIMER 0xAD000009 -+MKTC_ST(MKTC_EHEVENT_TIMER) -+#define MKTC_EHEVENT_SWEVENT 0xAD00000A -+MKTC_ST(MKTC_EHEVENT_SWEVENT) -+#define MKTC_EHEVENT_2DCOMPLETE 0xAD00000B -+MKTC_ST(MKTC_EHEVENT_2DCOMPLETE) -+ -+#define MKTC_3DEVENT_3DMEMFREE 0xAD000100 -+MKTC_ST(MKTC_3DEVENT_3DMEMFREE) -+#define MKTC_3DEVENT_PIXELENDRENDER 0xAD000101 -+MKTC_ST(MKTC_3DEVENT_PIXELENDRENDER) -+#define MKTC_3DEVENT_ISPBREAKPOINT 0xAD000102 -+MKTC_ST(MKTC_3DEVENT_ISPBREAKPOINT) -+#define MKTC_3DEVENT_END 0xAD000104 -+MKTC_ST(MKTC_3DEVENT_END) -+#define MKTC_3DLB_3DMEMFREE 0xAD000180 -+MKTC_ST(MKTC_3DLB_3DMEMFREE) -+#define MKTC_3DLB_PIXELENDRENDER 0xAD000181 -+MKTC_ST(MKTC_3DLB_PIXELENDRENDER) -+#define MKTC_3DLB_ISPBREAKPOINT 0xAD000182 -+MKTC_ST(MKTC_3DLB_ISPBREAKPOINT) -+#define MKTC_3DLB_FIND3D 0xAD000183 -+MKTC_ST(MKTC_3DLB_FIND3D) -+#define MKTC_3DLB_END 0xAD000184 -+MKTC_ST(MKTC_3DLB_END) -+ -+#define MKTC_TAEVENT_TAFINISHED 0xAD000200 -+MKTC_ST(MKTC_TAEVENT_TAFINISHED) -+#define MKTC_TAEVENT_END 0xAD000202 -+MKTC_ST(MKTC_TAEVENT_END) -+#define MKTC_TALB_TAFINISHED 0xAD000280 -+MKTC_ST(MKTC_TALB_TAFINISHED) -+#define MKTC_TALB_FINDTA 0xAD000281 -+MKTC_ST(MKTC_TALB_FINDTA) -+#define MKTC_TALB_END 0xAD000282 -+MKTC_ST(MKTC_TALB_END) -+ -+#define MKTC_CRRL_WRITEOPSBLOCKED 0xAD000300 -+MKTC_ST(MKTC_CRRL_WRITEOPSBLOCKED) -+#define MKTC_CRRL_READOPSBLOCKED 0xAD000301 -+MKTC_ST(MKTC_CRRL_READOPSBLOCKED) -+#define MKTC_CRRL_FOUNDRENDER 0xAD000302 -+MKTC_ST(MKTC_CRRL_FOUNDRENDER) -+#define MKTC_CRRL_NORENDER 0xAD000303 -+MKTC_ST(MKTC_CRRL_NORENDER) -+#define MKTC_CRRL_TARC_DIFFERENT 0xAD000304 -+MKTC_ST(MKTC_CRRL_TARC_DIFFERENT) -+#define MKTC_CRRL_BLOCKEDRC 0xAD000309 -+MKTC_ST(MKTC_CRRL_BLOCKEDRC) -+#define MKTC_CRRL_BLOCKEDRTDATA 0xAD00030A -+MKTC_ST(MKTC_CRRL_BLOCKEDRTDATA) -+#define MKTC_CRRL_CONTEXT_SUSPENDED 0xAD00030B -+MKTC_ST(MKTC_CRRL_CONTEXT_SUSPENDED) -+#define MKTC_CRRL_TAWAITINGFORMEM 0xAD00030C -+MKTC_ST(MKTC_CRRL_TAWAITINGFORMEM) -+#define MKTC_CRRL_TAOOMBUTPRIOINV 0xAD00030D -+MKTC_ST(MKTC_CRRL_TAOOMBUTPRIOINV) -+#define MKTC_CRRL_READOPS2BLOCKED 0xAD00030E -+MKTC_ST(MKTC_CRRL_READOPS2BLOCKED) -+#define MKTC_CRRL_SRC_WRITEOPSBLOCKED 0xAD00030F -+MKTC_ST(MKTC_CRRL_SRC_WRITEOPSBLOCKED) -+#define MKTC_CRRL_SRC_READOPSBLOCKED 0xAD000310 -+MKTC_ST(MKTC_CRRL_SRC_READOPSBLOCKED) -+#define MKTC_CRRL_TQ_WRITEOPSBLOCKED 0xAD000311 -+MKTC_ST(MKTC_CRRL_TQ_WRITEOPSBLOCKED) -+#define MKTC_CRRL_TQ_READOPSBLOCKED 0xAD000312 -+MKTC_ST(MKTC_CRRL_TQ_READOPSBLOCKED) -+ -+#define MKTC_KICKRENDER_START 0xAD000400 -+MKTC_ST(MKTC_KICKRENDER_START) -+#define MKTC_KICKRENDER_OVERLAP 0xAD000401 -+MKTC_ST(MKTC_KICKRENDER_OVERLAP) -+#define MKTC_KICKRENDER_ISP_START 0xAD000402 -+MKTC_ST(MKTC_KICKRENDER_ISP_START) -+#define MKTC_KICKRENDER_RESUME 0xAD000403 -+MKTC_ST(MKTC_KICKRENDER_RESUME) -+#define MKTC_KICKRENDER_CONFIG_REGION_HDRS 0xAD000404 -+MKTC_ST(MKTC_KICKRENDER_CONFIG_REGION_HDRS) -+#define MKTC_KICKRENDER_END 0xAD000408 -+MKTC_ST(MKTC_KICKRENDER_END) -+#define MKTC_KICKRENDER_RENDERCONTEXT 0xAD000409 -+MKTC_ST(MKTC_KICKRENDER_RENDERCONTEXT) -+#define MKTC_KICKRENDER_RTDATA 0xAD00040A -+MKTC_ST(MKTC_KICKRENDER_RTDATA) -+#define MKTC_KICKRENDER_PID 0xAD00040B -+MKTC_ST(MKTC_KICKRENDER_PID) -+ -+#define MKTC_RENDERFINISHED_START 0xAD000500 -+MKTC_ST(MKTC_RENDERFINISHED_START) -+#define MKTC_RF_START_NEXT_MT 0xAD000501 -+MKTC_ST(MKTC_RF_START_NEXT_MT) -+#define MKTC_RF_ALL_MTS_DONE 0xAD000502 -+MKTC_ST(MKTC_RF_ALL_MTS_DONE) -+#define MKTC_RENDERFINISHED_END 0xAD000503 -+MKTC_ST(MKTC_RENDERFINISHED_END) -+#define MKTC_VISQUERY_START 0xAD000504 -+MKTC_ST(MKTC_VISQUERY_START) -+#define MKTC_VISQUERY_END 0xAD000505 -+MKTC_ST(MKTC_VISQUERY_END) -+#define MKTC_TRANSFERRENDERFINISHED_START 0xAD000508 -+MKTC_ST(MKTC_TRANSFERRENDERFINISHED_START) -+#define MKTC_TRANSFERRENDERFINISHED_END 0xAD000509 -+MKTC_ST(MKTC_TRANSFERRENDERFINISHED_END) -+#define MKTC_TRF_UPDATESTATUSVALS 0xAD00050A -+MKTC_ST(MKTC_TRF_UPDATESTATUSVALS) -+#define MKTC_TRF_UPDATESTATUSVALS_DONE 0xAD00050B -+MKTC_ST(MKTC_TRF_UPDATESTATUSVALS_DONE) -+ -+#define MKTC_PIXELENDRENDER_START 0xAD000600 -+MKTC_ST(MKTC_PIXELENDRENDER_START) -+#define MKTC_PIXELENDRENDER_AFTERLOCK 0xAD000601 -+MKTC_ST(MKTC_PIXELENDRENDER_AFTERLOCK) -+#define MKTC_PIXELENDRENDER_END 0xAD000602 -+MKTC_ST(MKTC_PIXELENDRENDER_END) -+#define MKTC_PIXELENDRENDER_TLQEND 0xAD000603 -+MKTC_ST(MKTC_PIXELENDRENDER_TLQEND) -+ -+#define MKTC_3DMEMFREE_START 0xAD000700 -+MKTC_ST(MKTC_3DMEMFREE_START) -+#define MKTC_3DMEMFREE_AFTERLOCK 0xAD000701 -+MKTC_ST(MKTC_3DMEMFREE_AFTERLOCK) -+#define MKTC_3DMEMFREE_TESTEOR 0xAD000702 -+MKTC_ST(MKTC_3DMEMFREE_TESTEOR) -+#define MKTC_3DMEMFREE_END 0xAD000703 -+MKTC_ST(MKTC_3DMEMFREE_END) -+ -+#define MKTC_KICKTA_START 0xAD000800 -+MKTC_ST(MKTC_KICKTA_START) -+#define MKTC_KICKTA_OVERLAP 0xAD000801 -+MKTC_ST(MKTC_KICKTA_OVERLAP) -+#define MKTC_KICKTA_RESETCONTEXT 0xAD000802 -+MKTC_ST(MKTC_KICKTA_RESETCONTEXT) -+#define MKTC_KICKTA_VDM_START 0xAD000803 -+MKTC_ST(MKTC_KICKTA_VDM_START) -+#define MKTC_KICKTA_END 0xAD000804 -+MKTC_ST(MKTC_KICKTA_END) -+#define MKTC_KICKTA_RENDERCONTEXT 0xAD000805 -+MKTC_ST(MKTC_KICKTA_RENDERCONTEXT) -+#define MKTC_KICKTA_RTDATA 0xAD000806 -+MKTC_ST(MKTC_KICKTA_RTDATA) -+#define MKTC_KICKTA_RESET_VDMCSSTATUS 0xAD000807 -+MKTC_ST(MKTC_KICKTA_RESET_VDMCSSTATUS) -+#define MKTC_KICKTA_RESET_BUFFERS 0xAD000808 -+MKTC_ST(MKTC_KICKTA_RESET_BUFFERS) -+#define MKTC_KICKTA_PID 0xAD000809 -+MKTC_ST(MKTC_KICKTA_PID) -+#define MKTC_KICKTA_TACMD_DEBUG 0xAD00080A -+MKTC_ST(MKTC_KICKTA_TACMD_DEBUG) -+#define MKTC_KICKTA_FREECONTEXT 0xAD00080B -+MKTC_ST(MKTC_KICKTA_FREECONTEXT) -+#define MKTC_KICKTA_PIM_PATCHING 0xAD00080C -+MKTC_ST(MKTC_KICKTA_PIM_PATCHING) -+#define MKTC_KICKTA_TPC_CHECK_START 0xAD00080D -+MKTC_ST(MKTC_KICKTA_TPC_CHECK_START) -+#define MKTC_KICKTA_TPC_CHECK_END 0xAD00080E -+MKTC_ST(MKTC_KICKTA_TPC_CHECK_END) -+#define MKTC_KICKTA_TPC_CHECK_CORE 0xAD00080F -+MKTC_ST(MKTC_KICKTA_TPC_CHECK_CORE) -+#define MKTC_KICKTA_TPC_CHECK_FAIL 0xAD000810 -+MKTC_ST(MKTC_KICKTA_TPC_CHECK_FAIL) -+ -+#define MKTC_KICKTA_CHKPT_START_DUMMY_CS 0xAD0008A1 -+MKTC_ST(MKTC_KICKTA_CHKPT_START_DUMMY_CS) -+#define MKTC_KICKTA_CHKPT_START_DUMMY_TAK 0xAD0008A2 -+MKTC_ST(MKTC_KICKTA_CHKPT_START_DUMMY_TAK) -+#define MKTC_KICKTA_CHKPT_WAIT_FOR_DUMMY_KICK 0xAD0008A3 -+MKTC_ST(MKTC_KICKTA_CHKPT_WAIT_FOR_DUMMY_KICK) -+#define MKTC_KICKTA_CHKPT_WAIT_NEXT_CORE 0xAD0008A4 -+MKTC_ST(MKTC_KICKTA_CHKPT_WAIT_NEXT_CORE) -+#define MKTC_KICKTA_CHKPT_RESET_COMPLETE 0xAD0008A5 -+MKTC_ST(MKTC_KICKTA_CHKPT_RESET_COMPLETE) -+#define MKTC_KICKTA_CHKPT_CHECK_SWITCH 0xAD0008A6 -+MKTC_ST(MKTC_KICKTA_CHKPT_CHECK_SWITCH) -+ -+#define MKTC_HOSTKICK_START 0xAD000900 -+MKTC_ST(MKTC_HOSTKICK_START) -+#define MKTC_HOSTKICK_END 0xAD000901 -+MKTC_ST(MKTC_HOSTKICK_END) -+#define MKTC_HOSTKICK_PROCESS_QUEUES_END 0xAD000902 -+MKTC_ST(MKTC_HOSTKICK_PROCESS_QUEUES_END) -+#define MKTC_HOSTKICK_2D 0xAD000903 -+MKTC_ST(MKTC_HOSTKICK_2D) -+#define MKTC_HOSTKICK_TRANSFER 0xAD000904 -+MKTC_ST(MKTC_HOSTKICK_TRANSFER) -+#define MKTC_HOSTKICK_TA 0xAD000905 -+MKTC_ST(MKTC_HOSTKICK_TA) -+#define MKTC_HOSTKICK_PROCESS_QUEUES 0xAD000906 -+MKTC_ST(MKTC_HOSTKICK_PROCESS_QUEUES) -+#define MKTC_HOSTKICK_RESUME 0xAD000908 -+MKTC_ST(MKTC_HOSTKICK_RESUME) -+#define MKTC_HOSTKICK_POWEROFF 0xAD000909 -+MKTC_ST(MKTC_HOSTKICK_POWEROFF) -+#define MKTC_HOSTKICK_IDLE 0xAD00090A -+MKTC_ST(MKTC_HOSTKICK_IDLE) -+#define MKTC_HOSTKICK_CTXSUSPEND 0xAD00090B -+MKTC_ST(MKTC_HOSTKICK_CTXSUSPEND) -+#define MKTC_HOSTKICK_CTXRESUME 0xAD00090C -+MKTC_ST(MKTC_HOSTKICK_CTXRESUME) -+ -+#define MKTC_TIMER_POTENTIAL_TA_LOCKUP 0xAD000A00 -+MKTC_ST(MKTC_TIMER_POTENTIAL_TA_LOCKUP) -+#define MKTC_TIMER_POTENTIAL_3D_LOCKUP 0xAD000A01 -+MKTC_ST(MKTC_TIMER_POTENTIAL_3D_LOCKUP) -+#define MKTC_TIMER_CTAL_START 0xAD000A02 -+MKTC_ST(MKTC_TIMER_CTAL_START) -+#define MKTC_TIMER_CTAL_END 0xAD000A03 -+MKTC_ST(MKTC_TIMER_CTAL_END) -+#define MKTC_TIMER_C3DL_START 0xAD000A04 -+MKTC_ST(MKTC_TIMER_C3DL_START) -+#define MKTC_TIMER_C3DL_END 0xAD000A05 -+MKTC_ST(MKTC_TIMER_C3DL_END) -+#define MKTC_TIMER_LOCKUP 0xAD000A0A -+MKTC_ST(MKTC_TIMER_LOCKUP) -+#define MKTC_TIMER_NOT_TA_LOCKUP 0xAD000A0B -+MKTC_ST(MKTC_TIMER_NOT_TA_LOCKUP) -+#define MKTC_TIMER_NOT_3D_LOCKUP 0xAD000A0C -+MKTC_ST(MKTC_TIMER_NOT_3D_LOCKUP) -+#define MKTC_TIMER_2D_LOCKUP 0xAD000A0D -+MKTC_ST(MKTC_TIMER_2D_LOCKUP) -+#define MKTC_TIMER_POTENTIAL_2D_LOCKUP 0xAD000A10 -+MKTC_ST(MKTC_TIMER_POTENTIAL_2D_LOCKUP) -+#define MKTC_TIMER_C2DL_START 0xAD000A11 -+MKTC_ST(MKTC_TIMER_C2DL_START) -+#define MKTC_TIMER_C2DL_END 0xAD000A12 -+MKTC_ST(MKTC_TIMER_C2DL_END) -+#define MKTC_TIMER_NOT_2D_LOCKUP 0xAD000A13 -+MKTC_ST(MKTC_TIMER_NOT_2D_LOCKUP) -+#define MKTC_TIMER_ABORTALL 0xAD000A0E -+MKTC_ST(MKTC_TIMER_ABORTALL) -+#define MKTC_TIMER_END 0xAD000A0F -+MKTC_ST(MKTC_TIMER_END) -+ -+#define MKTC_HWR_START 0xAD000B00 -+MKTC_ST(MKTC_HWR_START) -+#define MKTC_HWR_END 0xAD000B01 -+MKTC_ST(MKTC_HWR_END) -+#define MKTC_HWR_HKS 0xAD000B02 -+MKTC_ST(MKTC_HWR_HKS) -+#define MKTC_HWR_PRL 0xAD000B03 -+MKTC_ST(MKTC_HWR_PRL) -+#define MKTC_HWR_PRL_DP 0xAD000B04 -+MKTC_ST(MKTC_HWR_PRL_DP) -+#define MKTC_HWR_CRL 0xAD000B05 -+MKTC_ST(MKTC_HWR_CRL) -+#define MKTC_HWR_CRL_DP 0xAD000B06 -+MKTC_ST(MKTC_HWR_CRL_DP) -+#define MKTC_HWR_TRL 0xAD000B07 -+MKTC_ST(MKTC_HWR_TRL) -+#define MKTC_HWR_TRL_DP 0xAD000B08 -+MKTC_ST(MKTC_HWR_TRL_DP) -+#define MKTC_HWR_ISC 0xAD000B09 -+MKTC_ST(MKTC_HWR_ISC) -+#define MKTC_HWR_2DL 0xAD000B0A -+MKTC_ST(MKTC_HWR_2DL) -+#define MKTC_HWR_CLEANUP 0xAD000B0B -+MKTC_ST(MKTC_HWR_CLEANUP) -+ -+#define MKTC_URSV_START 0xAD000C00 -+MKTC_ST(MKTC_URSV_START) -+#define MKTC_URSV_UPDATEWRITEOPS 0xAD000C01 -+MKTC_ST(MKTC_URSV_UPDATEWRITEOPS) -+#define MKTC_URSV_UPDATESTATUSVALS 0xAD000C03 -+MKTC_ST(MKTC_URSV_UPDATESTATUSVALS) -+#define MKTC_URSV_UPDATESTATUSVALS_DONE 0xAD000C04 -+MKTC_ST(MKTC_URSV_UPDATESTATUSVALS_DONE) -+#define MKTC_URSV_END 0xAD000C05 -+MKTC_ST(MKTC_URSV_END) -+ -+#define MKTC_STORETACONTEXT_START 0xAD000D00 -+MKTC_ST(MKTC_STORETACONTEXT_START) -+#define MKTC_STORETACONTEXT_END 0xAD000D01 -+MKTC_ST(MKTC_STORETACONTEXT_END) -+#define MKTC_LOADTACONTEXT_START 0xAD000D02 -+MKTC_ST(MKTC_LOADTACONTEXT_START) -+#define MKTC_LOADTACONTEXT_END 0xAD000D03 -+MKTC_ST(MKTC_LOADTACONTEXT_END) -+#define MKTC_STORE3DCONTEXT_START 0xAD000D04 -+MKTC_ST(MKTC_STORE3DCONTEXT_START) -+#define MKTC_STORE3DCONTEXT_END 0xAD000D05 -+MKTC_ST(MKTC_STORE3DCONTEXT_END) -+#define MKTC_LOAD3DCONTEXT_START 0xAD000D06 -+MKTC_ST(MKTC_LOAD3DCONTEXT_START) -+#define MKTC_LOAD3DCONTEXT_END 0xAD000D07 -+MKTC_ST(MKTC_LOAD3DCONTEXT_END) -+ -+#define MKTC_FINDTA_POWERREQUEST 0xAD000E00 -+MKTC_ST(MKTC_FINDTA_POWERREQUEST) -+#define MKTC_FINDTA_TA3D_OVERLAP_BLOCKED 0xAD000E01 -+MKTC_ST(MKTC_FINDTA_TA3D_OVERLAP_BLOCKED) -+#define MKTC_FINDTA_RTDATA_RENDERING 0xAD000E02 -+MKTC_ST(MKTC_FINDTA_RTDATA_RENDERING) -+#define MKTC_FINDTA_3DRC_DIFFERENT 0xAD000E03 -+MKTC_ST(MKTC_FINDTA_3DRC_DIFFERENT) -+#define MKTC_FINDTA_WRITEOPSBLOCKED 0xAD000E04 -+MKTC_ST(MKTC_FINDTA_WRITEOPSBLOCKED) -+#define MKTC_FINDTA_READOPSBLOCKED 0xAD000E05 -+MKTC_ST(MKTC_FINDTA_READOPSBLOCKED) -+#define MKTC_FINDTA_RESIZE_PB 0xAD000E06 -+MKTC_ST(MKTC_FINDTA_RESIZE_PB) -+#define MKTC_FINDTA_RESIZE_PB_BLOCKED 0xAD000E07 -+MKTC_ST(MKTC_FINDTA_RESIZE_PB_BLOCKED) -+#define MKTC_FINDTA_SHRINK_PB 0xAD000E08 -+MKTC_ST(MKTC_FINDTA_SHRINK_PB) -+#define MKTC_FINDTA_TAPB_DIFFERENT 0xAD000E09 -+MKTC_ST(MKTC_FINDTA_TAPB_DIFFERENT) -+#define MKTC_FINDTA_TACONTEXT_DIFFERENT 0xAD000E0A -+MKTC_ST(MKTC_FINDTA_TACONTEXT_DIFFERENT) -+#define MKTC_FINDTA_TA2D_OVERLAP_BLOCKED 0xAD000E0B -+MKTC_ST(MKTC_FINDTA_TA2D_OVERLAP_BLOCKED) -+#define MKTC_FINDTA_CONTEXT_SUSPENDED 0xAD000E0C -+MKTC_ST(MKTC_FINDTA_CONTEXT_SUSPENDED) -+#define MKTC_FINDTA_SRC_READOPSBLOCKED 0xAD000E0D -+MKTC_ST(MKTC_FINDTA_SRC_READOPSBLOCKED) -+#define MKTC_FINDTA_SRC_WRITEOPSBLOCKED 0xAD000E0E -+MKTC_ST(MKTC_FINDTA_SRC_WRITEOPSBLOCKED) -+#define MKTC_FINDTA_READOPS2BLOCKED 0xAD000E0F -+MKTC_ST(MKTC_FINDTA_READOPS2BLOCKED) -+ -+#define MKTC_CTRL_SRCREADOPSBLOCKED 0xAD000F00 -+MKTC_ST(MKTC_CTRL_SRCREADOPSBLOCKED) -+#define MKTC_CTRL_SRCWRITEOPSBLOCKED 0xAD000F01 -+MKTC_ST(MKTC_CTRL_SRCWRITEOPSBLOCKED) -+#define MKTC_CTRL_DSTREADOPSBLOCKED 0xAD000F02 -+MKTC_ST(MKTC_CTRL_DSTREADOPSBLOCKED) -+#define MKTC_CTRL_DSTWRITEOPSBLOCKED 0xAD000F03 -+MKTC_ST(MKTC_CTRL_DSTWRITEOPSBLOCKED) -+#define MKTC_CTRL_TARC_DIFFERENT 0xAD000F04 -+MKTC_ST(MKTC_CTRL_TARC_DIFFERENT) -+#define MKTC_CTRL_CONTEXT_SUSPENDED 0xAD000F05 -+MKTC_ST(MKTC_CTRL_CONTEXT_SUSPENDED) -+#define MKTC_CTRL_SRCREADOPS2BLOCKED 0xAD000F06 -+MKTC_ST(MKTC_CTRL_SRCREADOPS2BLOCKED) -+#define MKTC_CTRL_3D_WRITEOPSBLOCKED 0xAD000F07 -+MKTC_ST(MKTC_CTRL_3D_WRITEOPSBLOCKED) -+#define MKTC_CTRL_3D_READOPSBLOCKED 0xAD000F08 -+MKTC_ST(MKTC_CTRL_3D_READOPSBLOCKED) -+ -+#define MKTC_DPTA_START 0xAD001000 -+MKTC_ST(MKTC_DPTA_START) -+#define MKTC_DPTA_UPDATESTATUSVALS 0xAD001001 -+MKTC_ST(MKTC_DPTA_UPDATESTATUSVALS) -+#define MKTC_DPTA_UPDATESTATUSVALS_DONE 0xAD001002 -+MKTC_ST(MKTC_DPTA_UPDATESTATUSVALS_DONE) -+#define MKTC_DPTA_NORENDER 0xAD001003 -+MKTC_ST(MKTC_DPTA_NORENDER) -+#define MKTC_DPTA_MEMFREE 0xAD001004 -+MKTC_ST(MKTC_DPTA_MEMFREE) -+#define MKTC_DPTA_INC_COMPLETECOUNT 0xAD001005 -+MKTC_ST(MKTC_DPTA_INC_COMPLETECOUNT) -+ -+#define MKTC_INVALDC 0xAD001100 -+MKTC_ST(MKTC_INVALDC) -+#define MKTC_INVALPT 0xAD001101 -+MKTC_ST(MKTC_INVALPT) -+#define MKTC_INVALSLC 0xAD001102 -+MKTC_ST(MKTC_INVALSLC) -+#define MKTC_INVALDATA 0xAD001103 -+MKTC_ST(MKTC_INVALDATA) -+ -+#define MKTC_RESTARTTA 0xAD001200 -+MKTC_ST(MKTC_RESTARTTA) -+#define MKTC_CSABORTNONGBL 0xAD001201 -+MKTC_ST(MKTC_CSABORTNONGBL) -+#define MKTC_CSABORTALL 0xAD001202 -+MKTC_ST(MKTC_CSABORTALL) -+#define MKTC_CSRENDERINPROGRESS 0xAD001203 -+MKTC_ST(MKTC_CSRENDERINPROGRESS) -+#define MKTC_TATERMRENDERINPROGRESS 0xAD001204 -+MKTC_ST(MKTC_TATERMRENDERINPROGRESS) -+#define MKTC_RESTARTTANORENDER 0xAD001205 -+MKTC_ST(MKTC_RESTARTTANORENDER) -+#define MKTC_SPM_KICKRENDER 0xAD001206 -+MKTC_ST(MKTC_SPM_KICKRENDER) -+#define MKTC_SPM_RESUME_ABORTCOMPLETE 0xAD001208 -+MKTC_ST(MKTC_SPM_RESUME_ABORTCOMPLETE) -+#define MKTC_RESUMEVDM 0xAD001209 -+MKTC_ST(MKTC_RESUMEVDM) -+#define MKTC_REMOVE_RESERVE_MEM 0xAD00120A -+MKTC_ST(MKTC_REMOVE_RESERVE_MEM) -+#define MKTC_INCREASEZLSTHRESHOLD 0xAD00120B -+MKTC_ST(MKTC_INCREASEZLSTHRESHOLD) -+#define MKTC_CSFORCEABORTALL 0xAD00120C -+MKTC_ST(MKTC_CSFORCEABORTALL) -+ -+#define MKTC_DUMMY_DEPTH 0xAD00120D -+MKTC_ST(MKTC_DUMMY_DEPTH) -+#define MKTC_DUMMY_DEPTH_CS 0xAD00120E -+MKTC_ST(MKTC_DUMMY_DEPTH_CS) -+ -+#define MKTC_MTETE_OOM 0xAD00120F -+MKTC_ST(MKTC_MTETE_OOM) -+#define MKTC_MTETE_OOM_FIRST_STORE_REF 0xAD001210 -+MKTC_ST(MKTC_MTETE_OOM_FIRST_STORE_REF) -+#define MKTC_MERGE_STATE_TABLES 0xAD001211 -+MKTC_ST(MKTC_MERGE_STATE_TABLES) -+#define MKTC_NO_PAGES_LEFT_FOR_23055 0xAD001212 -+MKTC_ST(MKTC_NO_PAGES_LEFT_FOR_23055) -+#define MKTC_NO_STATE_MODS 0xAD001213 -+MKTC_ST(MKTC_NO_STATE_MODS) -+#define MKTC_FIND_MTE_PAGE_IN_STATE 0xAD001214 -+MKTC_ST(MKTC_FIND_MTE_PAGE_IN_STATE) -+#define MKTC_MTE_PAGE_FOUND 0xAD001215 -+MKTC_ST(MKTC_MTE_PAGE_FOUND) -+#define MKTC_MOVE_MTE_PAGE_TO_TA_STATE 0xAD001216 -+MKTC_ST(MKTC_MOVE_MTE_PAGE_TO_TA_STATE) -+#define MKTC_MOVE_MTE_PAGE_TO_TA_STATE_END 0xAD001217 -+MKTC_ST(MKTC_MOVE_MTE_PAGE_TO_TA_STATE_END) -+#define MKTC_ZERO_ZLS_THRESHOLD 0xAD001218 -+MKTC_ST(MKTC_ZERO_ZLS_THRESHOLD) -+#define MKTC_RESTORE_ZLS_THRESHOLD 0xAD001219 -+MKTC_ST(MKTC_RESTORE_ZLS_THRESHOLD) -+#define MKTC_FIND_MTE_PAGE_IN_CSM 0xAD00121A -+MKTC_ST(MKTC_FIND_MTE_PAGE_IN_CSM) -+#define MKTC_REISSUE_MTE_PAGE 0xAD00121B -+MKTC_ST(MKTC_REISSUE_MTE_PAGE) -+#define MKTC_REISSUE_MTE_PAGE_REQUIRED 0xAD00121C -+MKTC_ST(MKTC_REISSUE_MTE_PAGE_REQUIRED) -+#define MKTC_REISSUE_MTE_PAGE_END 0xAD00121D -+MKTC_ST(MKTC_REISSUE_MTE_PAGE_END) -+#define MKTC_RESET_TE_PSG 0xAD00121E -+MKTC_ST(MKTC_RESET_TE_PSG) -+ -+#define MKTC_OOM_WRITEOPSBLOCKED 0xAD00121F -+MKTC_ST(MKTC_OOM_WRITEOPSBLOCKED) -+#define MKTC_OOM_READOPSBLOCKED 0xAD001220 -+MKTC_ST(MKTC_OOM_READOPSBLOCKED) -+#define MKTC_OOM_SRC_WRITEOPSBLOCKED 0xAD001221 -+MKTC_ST(MKTC_OOM_SRC_WRITEOPSBLOCKED) -+#define MKTC_OOM_SRC_READOPSBLOCKED 0xAD001222 -+MKTC_ST(MKTC_OOM_SRC_READOPSBLOCKED) -+#define MKTC_OOM_SPM_DEADLOCK 0xAD001223 -+MKTC_ST(MKTC_OOM_SPM_DEADLOCK) -+#define MKTC_OOM_SPM_DEADLOCK_MEM_ADDED 0xAD001224 -+MKTC_ST(MKTC_OOM_SPM_DEADLOCK_MEM_ADDED) -+#define MKTC_RESET 0xAD001225 -+MKTC_ST(MKTC_RESET) -+#define MKTC_SPM_INVALID_ZLSCONFIG 0xAD001226 -+MKTC_ST(MKTC_SPM_INVALID_ZLSCONFIG) -+ -+#define MKTC_OOM_TYPE_MT 0xAD00122A -+MKTC_ST(MKTC_OOM_TYPE_MT) -+#define MKTC_OOM_TYPE_GLOBAL 0xAD001230 -+MKTC_ST(MKTC_OOM_TYPE_GLOBAL) -+#define MKTC_OOM_CAUSE_GBL_OOM 0xAD001231 -+MKTC_ST(MKTC_OOM_CAUSE_GBL_OOM) -+#define MKTC_OOM_RESTORE_LIST_SIZE 0xAD001232 -+MKTC_ST(MKTC_OOM_RESTORE_LIST_SIZE) -+ -+#define MKTC_CHECK_MTE_PAGE_REISSUE 0xAD001240 -+MKTC_ST(MKTC_CHECK_MTE_PAGE_REISSUE) -+#define MKTC_CPRI_VALID_ENTRIES 0xAD001241 -+MKTC_ST(MKTC_CPRI_VALID_ENTRIES) -+#define MKTC_CPRI_STORE_DPLIST 0xAD001242 -+MKTC_ST(MKTC_CPRI_STORE_DPLIST) -+#define MKTC_CPRI_STORE_OTPM_CSM 0xAD001243 -+MKTC_ST(MKTC_CPRI_STORE_OTPM_CSM) -+#define MKTC_CPRI_ABORT_MT_IDX 0xAD001244 -+MKTC_ST(MKTC_CPRI_ABORT_MT_IDX) -+#define MKTC_CPRI_ABORT_CORE_IDX 0xAD001245 -+MKTC_ST(MKTC_CPRI_ABORT_CORE_IDX) -+#define MKTC_CPRI_CSM_TABLE_DATA 0xAD001246 -+MKTC_ST(MKTC_CPRI_CSM_TABLE_DATA) -+#define MKTC_CPRI_PIM_DATA 0xAD001247 -+MKTC_ST(MKTC_CPRI_PIM_DATA) -+#define MKTC_CPRI_DO_CIRCULAR_TEST 0xAD001248 -+MKTC_ST(MKTC_CPRI_DO_CIRCULAR_TEST) -+#define MKTC_CPRI_WRITE_ENTRIES 0xAD001249 -+MKTC_ST(MKTC_CPRI_WRITE_ENTRIES) -+ -+#define MKTC_MTE_ENTRY_NOT_IN_ANY_LIST 0xAD001250 -+MKTC_ST(MKTC_MTE_ENTRY_NOT_IN_ANY_LIST) -+ -+#define MKTC_SPMAC_IGNORE_TERMINATE 0xAD001251 -+MKTC_ST(MKTC_SPMAC_IGNORE_TERMINATE) -+ -+#define MKTC_SPMAC_REQUEST_3D_TIMEOUT 0xAD001252 -+MKTC_ST(MKTC_SPMAC_REQUEST_3D_TIMEOUT) -+#define MKTC_SPMAC_3D_TIMEOUT_COMPLETE 0xAD001253 -+MKTC_ST(MKTC_SPMAC_3D_TIMEOUT_COMPLETE) -+#define MKTC_OOM_READOPS2BLOCKED 0xAD001254 -+MKTC_ST(MKTC_OOM_READOPS2BLOCKED) -+ -+/* PB Load/store status */ -+#define MKTC_LOADTAPB_START 0xAD001300 -+MKTC_ST(MKTC_LOADTAPB_START) -+#define MKTC_LOADTAPB_END 0xAD001301 -+MKTC_ST(MKTC_LOADTAPB_END) -+#define MKTC_STORETAPB_START 0xAD001302 -+MKTC_ST(MKTC_STORETAPB_START) -+#define MKTC_STORETAPB_END 0xAD001303 -+MKTC_ST(MKTC_STORETAPB_END) -+#define MKTC_LOAD3DPB_START 0xAD001304 -+MKTC_ST(MKTC_LOAD3DPB_START) -+#define MKTC_LOAD3DPB_END 0xAD001305 -+MKTC_ST(MKTC_LOAD3DPB_END) -+#define MKTC_STORE3DPB_START 0xAD001306 -+MKTC_ST(MKTC_STORE3DPB_START) -+#define MKTC_STORE3DPB_END 0xAD001307 -+MKTC_ST(MKTC_STORE3DPB_END) -+#define MKTC_LOADTAPB_PAGETABLE_DONE 0xAD001308 -+MKTC_ST(MKTC_LOADTAPB_PAGETABLE_DONE) -+#define MKTC_LOAD3DPB_PAGETABLE_DONE 0xAD001309 -+MKTC_ST(MKTC_LOAD3DPB_PAGETABLE_DONE) -+ -+#define MKTC_TIMER_RC_CLEANUP 0xAD001400 -+MKTC_ST(MKTC_TIMER_RC_CLEANUP) -+#define MKTC_TIMER_RC_CLEANUP_DONE 0xAD001401 -+MKTC_ST(MKTC_TIMER_RC_CLEANUP_DONE) -+#define MKTC_TIMER_RC_CLEANUP_BUSY 0xAD001402 -+MKTC_ST(MKTC_TIMER_RC_CLEANUP_BUSY) -+#define MKTC_TIMER_RT_CLEANUP 0xAD001410 -+MKTC_ST(MKTC_TIMER_RT_CLEANUP) -+#define MKTC_TIMER_RT_CLEANUP_DONE 0xAD001411 -+MKTC_ST(MKTC_TIMER_RT_CLEANUP_DONE) -+#define MKTC_TIMER_RT_CLEANUP_PENDING 0xAD001412 -+MKTC_ST(MKTC_TIMER_RT_CLEANUP_PENDING) -+#define MKTC_TIMER_RT_CLEANUP_TIDYPARTIALLIST 0xAD001413 -+MKTC_ST(MKTC_TIMER_RT_CLEANUP_TIDYPARTIALLIST) -+#define MKTC_TIMER_RT_CLEANUP_BUSY 0xAD001414 -+MKTC_ST(MKTC_TIMER_RT_CLEANUP_BUSY) -+#define MKTC_TIMER_TC_CLEANUP 0xAD001420 -+MKTC_ST(MKTC_TIMER_TC_CLEANUP) -+#define MKTC_TIMER_TC_CLEANUP_DONE 0xAD001421 -+MKTC_ST(MKTC_TIMER_TC_CLEANUP_DONE) -+#define MKTC_TIMER_TC_CLEANUP_BUSY 0xAD001422 -+MKTC_ST(MKTC_TIMER_TC_CLEANUP_BUSY) -+#define MKTC_TIMER_2DC_CLEANUP 0xAD001430 -+MKTC_ST(MKTC_TIMER_2DC_CLEANUP) -+#define MKTC_TIMER_2DC_CLEANUP_DONE 0xAD001431 -+MKTC_ST(MKTC_TIMER_2DC_CLEANUP_DONE) -+#define MKTC_TIMER_2DC_CLEANUP_BUSY 0xAD001432 -+MKTC_ST(MKTC_TIMER_2DC_CLEANUP_BUSY) -+#define MKTC_TIMER_SHAREDPBDESC_CLEANUP 0xAD001440 -+MKTC_ST(MKTC_TIMER_SHAREDPBDESC_CLEANUP) -+ -+ -+#define MKTC_TIMER_ISP_SWITCH_POTENTIAL_LOCKUP 0xAD001450 -+MKTC_ST(MKTC_TIMER_ISP_SWITCH_POTENTIAL_LOCKUP) -+#define MKTC_TIMER_ISP_SWITCH_FORCE_SWITCH 0xAD001451 -+MKTC_ST(MKTC_TIMER_ISP_SWITCH_FORCE_SWITCH) -+ -+#define MKTC_UTSO_UPDATEREADOPS 0xAD001600 -+MKTC_ST(MKTC_UTSO_UPDATEREADOPS) -+#define MKTC_UTSO_UPDATEWRITEOPS 0xAD001601 -+MKTC_ST(MKTC_UTSO_UPDATEWRITEOPS) -+ -+#define MKTC_TAFINISHED_UPDATESTATUSVALS 0xAD001700 -+MKTC_ST(MKTC_TAFINISHED_UPDATESTATUSVALS) -+#define MKTC_TAFINISHED_UPDATESTATUSVALS_DONE 0xAD001701 -+MKTC_ST(MKTC_TAFINISHED_UPDATESTATUSVALS_DONE) -+#define MKTC_TAFINISHED_NORENDER 0xAD001702 -+MKTC_ST(MKTC_TAFINISHED_NORENDER) -+#define MKTC_TAFINISHED_LASTKICK 0xAD001703 -+MKTC_ST(MKTC_TAFINISHED_LASTKICK) -+#define MKTC_TAFINISHED_FINDRENDER 0xAD001704 -+MKTC_ST(MKTC_TAFINISHED_FINDRENDER) -+#define MKTC_TAFINISHED_FINDTA 0xAD001705 -+MKTC_ST(MKTC_TAFINISHED_FINDTA) -+#define MKTC_TAFINISHED_END 0xAD001706 -+MKTC_ST(MKTC_TAFINISHED_END) -+#define MKTC_TAF_SPM_DEADLOCK_MEM_REMOVED 0xAD001707 -+MKTC_ST(MKTC_TAF_SPM_DEADLOCK_MEM_REMOVED) -+#define MKTC_TAF_RESERVE_MEM 0xAD001708 -+MKTC_ST(MKTC_TAF_RESERVE_MEM) -+#define MKTC_TAF_RESERVE_MEM_REQUEST_RENDER 0xAD001709 -+MKTC_ST(MKTC_TAF_RESERVE_MEM_REQUEST_RENDER) -+#define MKTC_TAF_RESERVE_FREE_RENDER_FINISHED 0xAD00170A -+MKTC_ST(MKTC_TAF_RESERVE_FREE_RENDER_FINISHED) -+#define MKTC_TAF_RESERVE_FREE_DUMMY_RENDER 0xAD00170B -+MKTC_ST(MKTC_TAF_RESERVE_FREE_DUMMY_RENDER) -+#define MKTC_TAF_DEBUG_SAS 0xAD00170C -+MKTC_ST(MKTC_TAF_DEBUG_SAS) -+#define MKTC_TAFINISHED_NOCONTEXTSWITCH 0xAD00170D -+MKTC_ST(MKTC_TAFINISHED_NOCONTEXTSWITCH) -+ -+#define MKTC_TAFINISHED_TERM_COMPLETE_START 0xAD001710 -+MKTC_ST(MKTC_TAFINISHED_TERM_COMPLETE_START) -+#define MKTC_TAFINISHED_TERM_COMPLETE_END 0xAD001711 -+MKTC_ST(MKTC_TAFINISHED_TERM_COMPLETE_END) -+ -+#define MKTC_TAFINISHED_DPMPAGERECYCLING 0xAD001720 -+MKTC_ST(MKTC_TAFINISHED_DPMPAGERECYCLING) -+ -+#define MKTC_2DEVENT_2DCOMPLETE 0xAD001800 -+MKTC_ST(MKTC_2DEVENT_2DCOMPLETE) -+#define MKTC_2DEVENT_END 0xAD001801 -+MKTC_ST(MKTC_2DEVENT_END) -+#define MKTC_2DLB_2DCOMPLETE 0xAD001802 -+MKTC_ST(MKTC_2DLB_2DCOMPLETE) -+#define MKTC_2DLB_FIND2D 0xAD001803 -+MKTC_ST(MKTC_2DLB_FIND2D) -+#define MKTC_2DLB_END 0xAD001804 -+MKTC_ST(MKTC_2DLB_END) -+#define MKTC_2DCOMPLETE_START 0xAD001805 -+MKTC_ST(MKTC_2DCOMPLETE_START) -+#define MKTC_2DCOMPLETE_END 0xAD001806 -+MKTC_ST(MKTC_2DCOMPLETE_END) -+#define MKTC_KICK2D_START 0xAD001807 -+MKTC_ST(MKTC_KICK2D_START) -+#define MKTC_KICK2D_END 0xAD001808 -+MKTC_ST(MKTC_KICK2D_END) -+#define MKTC_DUMMYPROC2D 0xAD001809 -+MKTC_ST(MKTC_DUMMYPROC2D) -+#define MKTC_FTD_SRCREADOPSBLOCKED 0xAD00180A -+MKTC_ST(MKTC_FTD_SRCREADOPSBLOCKED) -+#define MKTC_FTD_SRCWRITEOPSBLOCKED 0xAD00180B -+MKTC_ST(MKTC_FTD_SRCWRITEOPSBLOCKED) -+#define MKTC_FTD_DSTREADOPSBLOCKED 0xAD00180C -+MKTC_ST(MKTC_FTD_DSTREADOPSBLOCKED) -+#define MKTC_FTD_DSTWRITEOPSBLOCKED 0xAD00180D -+MKTC_ST(MKTC_FTD_DSTWRITEOPSBLOCKED) -+#define MKTC_FTD_TA2D_OVERLAP_BLOCKED 0xAD00180E -+MKTC_ST(MKTC_FTD_TA2D_OVERLAP_BLOCKED) -+#define MKTC_U2DSO_UPDATEREADOPS 0xAD00180F -+MKTC_ST(MKTC_U2DSO_UPDATEREADOPS) -+#define MKTC_U2DSO_UPDATEWRITEOPS 0xAD001810 -+MKTC_ST(MKTC_U2DSO_UPDATEWRITEOPS) -+#define MKTC_FTD_TAOPSBLOCKED 0xAD001811 -+MKTC_ST(MKTC_FTD_TAOPSBLOCKED) -+#define MKTC_KICK2D_2DSLAVEPORT 0xAD001812 -+MKTC_ST(MKTC_KICK2D_2DSLAVEPORT) -+#define MKTC_KICK2D_2DSLAVEPORT_DONE 0xAD001813 -+MKTC_ST(MKTC_KICK2D_2DSLAVEPORT_DONE) -+#define MKTC_FTD_CONTEXT_SUSPENDED 0xAD001814 -+MKTC_ST(MKTC_FTD_CONTEXT_SUSPENDED) -+#define MKTC_KICK2D_PID 0xAD001815 -+MKTC_ST(MKTC_KICK2D_PID) -+#define MKTC_FIND2D_ADDR_SPACE_DIFFERENT 0xAD001816 -+MKTC_ST(MKTC_FIND2D_ADDR_SPACE_DIFFERENT) -+#define MKTC_FTD_3DOPSBLOCKED 0xAD001817 -+MKTC_ST(MKTC_FTD_3DOPSBLOCKED) -+#define MKTC_FTD_DSTREADOPS2BLOCKED 0xAD001818 -+MKTC_ST(MKTC_FTD_DSTREADOPS2BLOCKED) -+#define MKTC_U2DSO_UPDATESTATUSVALS 0xAD001819 -+MKTC_ST(MKTC_U2DSO_UPDATESTATUSVALS) -+#define MKTC_U2DSO_UPDATESTATUSVALS_DONE 0xAD00181A -+MKTC_ST(MKTC_U2DSO_UPDATESTATUSVALS_DONE) -+ -+#define MKTC_FCM_START 0xAD001900 -+MKTC_ST(MKTC_FCM_START) -+#define MKTC_FCM_END 0xAD001901 -+MKTC_ST(MKTC_FCM_END) -+#define MKTC_FCM_PB_SAME 0xAD001902 -+MKTC_ST(MKTC_FCM_PB_SAME) -+#define MKTC_FCM_TQ_IN_PROGESS 0xAD001903 -+MKTC_ST(MKTC_FCM_TQ_IN_PROGESS) -+#define MKTC_FCM_TQ_MEMCONTEXT_DIFFERENT 0xAD001904 -+MKTC_ST(MKTC_FCM_TQ_MEMCONTEXT_DIFFERENT) -+ -+#define MKTC_TIMER_ACTIVE_POWER 0xAD001A00 -+MKTC_ST(MKTC_TIMER_ACTIVE_POWER) -+#define MKTC_TIMER_POWER_3D_ACTIVE 0xAD001A01 -+MKTC_ST(MKTC_TIMER_POWER_3D_ACTIVE) -+#define MKTC_TIMER_POWER_TA_ACTIVE 0xAD001A02 -+MKTC_ST(MKTC_TIMER_POWER_TA_ACTIVE) -+#define MKTC_TIMER_POWER_2D_ACTIVE 0xAD001A03 -+MKTC_ST(MKTC_TIMER_POWER_2D_ACTIVE) -+#define MKTC_TIMER_POWER_PENDING_EVENTS 0xAD001A04 -+MKTC_ST(MKTC_TIMER_POWER_PENDING_EVENTS) -+#define MKTC_TIMER_POWER_IDLE 0xAD001A05 -+MKTC_ST(MKTC_TIMER_POWER_IDLE) -+#define MKTC_TIMER_POWER_OFF 0xAD001A06 -+MKTC_ST(MKTC_TIMER_POWER_OFF) -+#define MKTC_TIMER_POWER_CCB_ERROR 0xAD001A07 -+MKTC_ST(MKTC_TIMER_POWER_CCB_ERROR) -+#define MKTC_TIMER_POWER_RESTART_IMMEDIATE 0xAD001A08 -+MKTC_ST(MKTC_TIMER_POWER_RESTART_IMMEDIATE) -+ -+#define MKTC_3DCONTEXT_SWITCH 0xAD001B00 -+MKTC_ST(MKTC_3DCONTEXT_SWITCH) -+#define MKTC_3DCONTEXT_SWITCH_END 0xAD001B01 -+MKTC_ST(MKTC_3DCONTEXT_SWITCH_END) -+ -+#define MKTC_TACONTEXT_SWITCH 0xAD001C00 -+MKTC_ST(MKTC_TACONTEXT_SWITCH) -+#define MKTC_TACONTEXT_SWITCH_END 0xAD001C02 -+MKTC_ST(MKTC_TACONTEXT_SWITCH_END) -+ -+#define MKTC_GETMISCINFO_MEMREAD_START 0xAD001D00 -+MKTC_ST(MKTC_GETMISCINFO_MEMREAD_START) -+#define MKTC_GETMISCINFO_MEMREAD_END 0xAD001D01 -+MKTC_ST(MKTC_GETMISCINFO_MEMREAD_END) -+#define MKTC_GETMISCINFO_MEMWRITE_START 0xAD001D02 -+MKTC_ST(MKTC_GETMISCINFO_MEMWRITE_START) -+#define MKTC_GETMISCINFO_MEMWRITE_END 0xAD001D03 -+MKTC_ST(MKTC_GETMISCINFO_MEMWRITE_END) -+ -+#define MKTC_HALTTA 0xAD001E00 -+MKTC_ST(MKTC_HALTTA) -+#define MKTC_HTA_SET_FLAG 0xAD001E01 -+MKTC_ST(MKTC_HTA_SET_FLAG) -+#define MKTC_HTA_SAVE_COMPLEX_PTR 0xAD001E02 -+MKTC_ST(MKTC_HTA_SAVE_COMPLEX_PTR) -+#define MKTC_HALTTA_END 0xAD001E03 -+MKTC_ST(MKTC_HALTTA_END) -+ -+#define MKTC_RESUMETA 0xAD001F00 -+MKTC_ST(MKTC_RESUMETA) -+#define MKTC_RTA_CONTEXT_LOADED 0xAD001F01 -+MKTC_ST(MKTC_RTA_CONTEXT_LOADED) -+#define MKTC_RTA_MTE_STATE_KICKED 0xAD001F02 -+MKTC_ST(MKTC_RTA_MTE_STATE_KICKED) -+#define MKTC_RTA_CMPLX_GEOM_PRESENT 0xAD001F03 -+MKTC_ST(MKTC_RTA_CMPLX_GEOM_PRESENT) -+#define MKTC_RTA_CMPLX_STATE_KICKED 0xAD001F04 -+MKTC_ST(MKTC_RTA_CMPLX_STATE_KICKED) -+#define MKTC_RTA_CHECK_NEXT_SA_PROG 0xAD001F05 -+MKTC_ST(MKTC_RTA_CHECK_NEXT_SA_PROG) -+#define MKTC_RTA_CORE_COMPLETED 0xAD001F06 -+MKTC_ST(MKTC_RTA_CORE_COMPLETED) -+#define MKTC_RTA_DEBUG_SAS 0xAD001F07 -+MKTC_ST(MKTC_RTA_DEBUG_SAS) -+#define MKTC_RESUMETA_END 0xAD001F0F -+MKTC_ST(MKTC_RESUMETA_END) -+ -+#define MKTC_RENDERHALT 0xAD002000 -+MKTC_ST(MKTC_RENDERHALT) -+#define MKTC_RH_CLEARFLAGS 0xAD002001 -+MKTC_ST(MKTC_RH_CLEARFLAGS) -+#define MKTC_RH_CTRL_ADDR 0xAD002002 -+MKTC_ST(MKTC_RH_CTRL_ADDR) -+#define MKTC_RH_RGN_ADDR 0xAD002003 -+MKTC_ST(MKTC_RH_RGN_ADDR) -+#define MKTC_RH_EMPTY_TILE 0xAD002004 -+MKTC_ST(MKTC_RH_EMPTY_TILE) -+#define MKTC_RH_EMPTY_LAST_TILE 0xAD002005 -+MKTC_ST(MKTC_RH_EMPTY_LAST_TILE) -+#define MKTC_RH_3D_TIMEOUT 0xAD002006 -+MKTC_ST(MKTC_RH_3D_TIMEOUT) -+#define MKTC_RH_NOT_EMPTY 0xAD002007 -+MKTC_ST(MKTC_RH_NOT_EMPTY) -+#define MKTC_RH_OBJECT_COMPLETE 0xAD002008 -+MKTC_ST(MKTC_RH_OBJECT_COMPLETE) -+#define MKTC_RH_STREAM_LINK 0xAD002009 -+MKTC_ST(MKTC_RH_STREAM_LINK) -+#define MKTC_RH_OBJECT_INCOMPLETE 0xAD00200A -+MKTC_ST(MKTC_RH_OBJECT_INCOMPLETE) -+#define MKTC_RH_PRIM_MASK_PRESENT 0xAD00200B -+MKTC_ST(MKTC_RH_PRIM_MASK_PRESENT) -+#define MKTC_RH_BYTE_MASK_PRESENT 0xAD00200C -+MKTC_ST(MKTC_RH_BYTE_MASK_PRESENT) -+#define MKTC_RH_BYTE_MASK_ZERO 0xAD00200D -+MKTC_ST(MKTC_RH_BYTE_MASK_ZERO) -+#define MKTC_RH_PRIM_MASK_ZERO 0xAD00200E -+MKTC_ST(MKTC_RH_PRIM_MASK_ZERO) -+#define MKTC_RH_INVALIDATE_OBJECTS 0xAD00200F -+MKTC_ST(MKTC_RH_INVALIDATE_OBJECTS) -+#define MKTC_RH_OBJECTS_INVALIDATED 0xAD002010 -+MKTC_ST(MKTC_RH_OBJECTS_INVALIDATED) -+#define MKTC_RH_DPM_RGN_PARSER_IDLE 0xAD002011 -+MKTC_ST(MKTC_RH_DPM_RGN_PARSER_IDLE) -+#define MKTC_RH_NEXT_RGN_BASE 0xAD002012 -+MKTC_ST(MKTC_RH_NEXT_RGN_BASE) -+#define MKTC_RH_OCC_EXIT 0xAD002013 -+MKTC_ST(MKTC_RH_OCC_EXIT) -+#define MKTC_RH_STILL_RUNNING 0xAD002020 -+MKTC_ST(MKTC_RH_STILL_RUNNING) -+#define MKTC_RH_CLEARMCI 0xAD002021 -+MKTC_ST(MKTC_RH_CLEARMCI) -+#define MKTC_RH_EOR 0xAD002022 -+MKTC_ST(MKTC_RH_EOR) -+#define MKTC_RENDERHALT_END 0xAD002030 -+MKTC_ST(MKTC_RENDERHALT_END) -+ -+#define MKTC_FIND3D_POWERREQUEST 0xAD002100 -+MKTC_ST(MKTC_FIND3D_POWERREQUEST) -+ -+#define MKTC_FIND2D_POWERREQUEST 0xAD002200 -+MKTC_ST(MKTC_FIND2D_POWERREQUEST) -+ -+#define MKTC_UKERNEL_INIT 0xAD002300 -+MKTC_ST(MKTC_UKERNEL_INIT) -+#define MKTC_UKERNEL_INIT_DCS_COMPLETE 0xAD002301 -+MKTC_ST(MKTC_UKERNEL_INIT_DCS_COMPLETE) -+#define MKTC_UKERNEL_INIT_VDMKICK_COMPLETE 0xAD002303 -+MKTC_ST(MKTC_UKERNEL_INIT_VDMKICK_COMPLETE) -+ -+#define MKTC_KICKTRANSFERRENDER_START 0xAD002400 -+MKTC_ST(MKTC_KICKTRANSFERRENDER_START) -+#define MKTC_KICKTRANSFERRENDER_ISP_START 0xAD002401 -+MKTC_ST(MKTC_KICKTRANSFERRENDER_ISP_START) -+#define MKTC_KICKTRANSFERRENDER_END 0xAD002402 -+MKTC_ST(MKTC_KICKTRANSFERRENDER_END) -+#define MKTC_DUMMYPROCTRANSFER 0xAD002403 -+MKTC_ST(MKTC_DUMMYPROCTRANSFER) -+#define MKTC_KTR_TQFENCE 0xAD002404 -+MKTC_ST(MKTC_KTR_TQFENCE) -+#define MKTC_KICKTRANSFERRENDER_PID 0xAD002405 -+MKTC_ST(MKTC_KICKTRANSFERRENDER_PID) -+ -+#define MKTC_HOSTKICK_CLEANUP_RT 0xAD002500 -+MKTC_ST(MKTC_HOSTKICK_CLEANUP_RT) -+#define MKTC_HOSTKICK_CLEANUP_RC 0xAD002501 -+MKTC_ST(MKTC_HOSTKICK_CLEANUP_RC) -+#define MKTC_HOSTKICK_CLEANUP_TC 0xAD002502 -+MKTC_ST(MKTC_HOSTKICK_CLEANUP_TC) -+#define MKTC_HOSTKICK_CLEANUP_2DC 0xAD002503 -+MKTC_ST(MKTC_HOSTKICK_CLEANUP_2DC) -+#define MKTC_HOSTKICK_CLEANUP_PB 0xAD002504 -+MKTC_ST(MKTC_HOSTKICK_CLEANUP_PB) -+#define MKTC_HOSTKICK_GETMISCINFO 0xAD002505 -+MKTC_ST(MKTC_HOSTKICK_GETMISCINFO) -+#define MKTC_HOSTKICK_DATABREAKPOINT 0xAD002506 -+MKTC_ST(MKTC_HOSTKICK_DATABREAKPOINT) -+#define MKTC_HOSTKICK_SETHWPERFSTATUS 0xAD002507 -+MKTC_ST(MKTC_HOSTKICK_SETHWPERFSTATUS) -+ -+#define MKTC_ZEROPC 0xAD002600 -+MKTC_ST(MKTC_ZEROPC) -+ -+#define MKTC_ASSERT_FAIL 0xAD002700 -+MKTC_ST(MKTC_ASSERT_FAIL) -+ -+#define MKTC_SDLB_ILLEGAL 0xAD002800 -+MKTC_ST(MKTC_SDLB_ILLEGAL) -+ -+#define MKTC_SPMEVENT_OUTOFMEM 0xAD002901 -+MKTC_ST(MKTC_SPMEVENT_OUTOFMEM) -+#define MKTC_SPMEVENT_TATERMINATE 0xAD002902 -+MKTC_ST(MKTC_SPMEVENT_TATERMINATE) -+#define MKTC_SPMEVENT_END 0xAD002904 -+MKTC_ST(MKTC_SPMEVENT_END) -+ -+#define MKTC_SPMLB_OUTOFMEM 0xAD002981 -+MKTC_ST(MKTC_SPMLB_OUTOFMEM) -+#define MKTC_SPMLB_TATERMINATE 0xAD002982 -+MKTC_ST(MKTC_SPMLB_TATERMINATE) -+#define MKTC_SPMLB_SPMRENDERFINSHED 0xAD002983 -+MKTC_ST(MKTC_SPMLB_SPMRENDERFINSHED) -+#define MKTC_SPMLB_END 0xAD002985 -+MKTC_ST(MKTC_SPMLB_END) -+ -+#define MKTC_SPM_CHECK_MT_DEADLOCK 0xAD002991 -+MKTC_ST(MKTC_SPM_CHECK_MT_DEADLOCK) -+#define MKTC_SPM_CHECK_GLOBAL_DEADLOCK 0xAD002992 -+MKTC_ST(MKTC_SPM_CHECK_GLOBAL_DEADLOCK) -+#define MKTC_SPM_RESERVE_ADDED 0xAD002993 -+MKTC_ST(MKTC_SPM_RESERVE_ADDED) -+#define MKTC_SPM_FORCE_GLOBAL_OOM_FAILED 0xAD00299E -+MKTC_ST(MKTC_SPM_FORCE_GLOBAL_OOM_FAILED) -+#define MKTC_SPM_DEADLOCK_MEM_FAILED 0xAD00299F -+MKTC_ST(MKTC_SPM_DEADLOCK_MEM_FAILED) -+ -+#define MKTC_IBC_ILLEGAL 0xAD002A00 -+MKTC_ST(MKTC_IBC_ILLEGAL) -+ -+#define MKTC_HWP_CLEARCOUNTERS 0xAD002B00 -+MKTC_ST(MKTC_HWP_CLEARCOUNTERS) -+ -+#define MKTC_TA_FRAMENUM 0xAD002C00 -+MKTC_ST(MKTC_TA_FRAMENUM) -+#define MKTC_3D_FRAMENUM 0xAD002C01 -+MKTC_ST(MKTC_3D_FRAMENUM) -+#define MKTC_SPM3D_FRAMENUM 0xAD002C02 -+MKTC_ST(MKTC_SPM3D_FRAMENUM) -+ -+#define MKTC_HKTA_RENDERCONTEXT 0xAD002D00 -+MKTC_ST(MKTC_HKTA_RENDERCONTEXT) -+#define MKTC_IDLECORE_REFCOUNT_FAIL 0xAD002E00 -+MKTC_ST(MKTC_IDLECORE_REFCOUNT_FAIL) -+ -+#define MKTC_MCISTATE_NOT_CLEARED 0xAD002F00 -+MKTC_ST(MKTC_MCISTATE_NOT_CLEARED) -+ -+#define MKTC_LOWERED_TO_PDS_THRESHOLD 0xAD003000 -+MKTC_ST(MKTC_LOWERED_TO_PDS_THRESHOLD) -+#define MKTC_REDUCE_MAX_VTX_PARTITIONS 0xAD003001 -+MKTC_ST(MKTC_REDUCE_MAX_VTX_PARTITIONS) -+#define MKTC_KTAOVERRIDE_MAX_VTX_PARTITIONS 0xAD003002 -+MKTC_ST(MKTC_KTAOVERRIDE_MAX_VTX_PARTITIONS) -+#define MKTC_KTANOOVERRIDE_MAX_VTX_PARTITIONS 0xAD003003 -+MKTC_ST(MKTC_KTANOOVERRIDE_MAX_VTX_PARTITIONS) -+ -+#define MKTC_IPRB_NORENDERDETAILS 0xAD003010 -+MKTC_ST(MKTC_IPRB_NORENDERDETAILS) -+#define MKTC_IPRB_HAVERENDERDETAILS 0xAD003011 -+MKTC_ST(MKTC_IPRB_HAVERENDERDETAILS) -+ -+#define MKTC_RENDER_OUT_OF_ORDER 0xAD003020 -+MKTC_ST(MKTC_RENDER_OUT_OF_ORDER) -+#define MKTC_RENDER_NOT_OUT_OF_ORDER 0xAD003021 -+MKTC_ST(MKTC_RENDER_NOT_OUT_OF_ORDER) -+ -+#define MKTC_ZLS_IDLE_BEGIN 0xAD003030 -+MKTC_ST(MKTC_ZLS_IDLE_BEGIN) -+#define MKTC_ZLS_ISP_CLK_GATING_EN 0xAD003031 -+MKTC_ST(MKTC_ZLS_ISP_CLK_GATING_EN) -+#define MKTC_ZLS_IDLE_END 0xAD003032 -+MKTC_ST(MKTC_ZLS_IDLE_END) -+ -+#endif /* __SGX_UKERNEL_STATUS_CODES_H__ */ -+ -+/****************************************************************************** -+ End of file (sgx_ukernel_status_codes.h) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/include/sgxinfo.h b/drivers/staging/ti-es8-sgx/services4/include/sgxinfo.h -new file mode 100644 -index 0000000..a5bb642 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/include/sgxinfo.h -@@ -0,0 +1,347 @@ -+/*************************************************************************/ /*! -+@Title sgx services structures/functions -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description inline functions/structures shared across UM and KM services components -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+#if !defined (__SGXINFO_H__) -+#define __SGXINFO_H__ -+ -+#include "sgxscript.h" -+#include "servicesint.h" -+#include "services.h" -+#include "sgxapi_km.h" -+#include "sgx_mkif_km.h" -+ -+ -+#define SGX_MAX_DEV_DATA 24 -+#define SGX_MAX_INIT_MEM_HANDLES 18 -+ -+ -+typedef struct _SGX_BRIDGE_INFO_FOR_SRVINIT -+{ -+ IMG_DEV_PHYADDR sPDDevPAddr; -+ PVRSRV_HEAP_INFO asHeapInfo[PVRSRV_MAX_CLIENT_HEAPS]; -+} SGX_BRIDGE_INFO_FOR_SRVINIT; -+ -+ -+typedef enum _SGXMKIF_CMD_TYPE_ -+{ -+ SGXMKIF_CMD_TA = 0, -+ SGXMKIF_CMD_TRANSFER = 1, -+ SGXMKIF_CMD_2D = 2, -+ SGXMKIF_CMD_POWER = 3, -+ SGXMKIF_CMD_CONTEXTSUSPEND = 4, -+ SGXMKIF_CMD_CLEANUP = 5, -+ SGXMKIF_CMD_GETMISCINFO = 6, -+ SGXMKIF_CMD_PROCESS_QUEUES = 7, -+ SGXMKIF_CMD_DATABREAKPOINT = 8, -+ SGXMKIF_CMD_SETHWPERFSTATUS = 9, -+ SGXMKIF_CMD_FLUSHPDCACHE = 10, -+ SGXMKIF_CMD_MAX = 11, -+ -+ SGXMKIF_CMD_FORCE_I32 = -1, -+ -+} SGXMKIF_CMD_TYPE; -+ -+ -+typedef struct _SGX_BRIDGE_INIT_INFO_ -+{ -+ IMG_HANDLE hKernelCCBMemInfo; -+ IMG_HANDLE hKernelCCBCtlMemInfo; -+ IMG_HANDLE hKernelCCBEventKickerMemInfo; -+ IMG_HANDLE hKernelSGXHostCtlMemInfo; -+ IMG_HANDLE hKernelSGXTA3DCtlMemInfo; -+#if defined(FIX_HW_BRN_31272) || defined(FIX_HW_BRN_31780) || defined(FIX_HW_BRN_33920) -+ IMG_HANDLE hKernelSGXPTLAWriteBackMemInfo; -+#endif -+ IMG_HANDLE hKernelSGXMiscMemInfo; -+ -+ IMG_UINT32 aui32HostKickAddr[SGXMKIF_CMD_MAX]; -+ -+ SGX_INIT_SCRIPTS sScripts; -+ -+ IMG_UINT32 ui32ClientBuildOptions; -+ SGX_MISCINFO_STRUCT_SIZES sSGXStructSizes; -+ -+#if defined(SGX_SUPPORT_HWPROFILING) -+ IMG_HANDLE hKernelHWProfilingMemInfo; -+#endif -+#if defined(SUPPORT_SGX_HWPERF) -+ IMG_HANDLE hKernelHWPerfCBMemInfo; -+#endif -+ IMG_HANDLE hKernelTASigBufferMemInfo; -+ IMG_HANDLE hKernel3DSigBufferMemInfo; -+ -+ -+#if defined(FIX_HW_BRN_31542) || defined(FIX_HW_BRN_36513) -+ IMG_HANDLE hKernelClearClipWAVDMStreamMemInfo; -+ IMG_HANDLE hKernelClearClipWAIndexStreamMemInfo; -+ IMG_HANDLE hKernelClearClipWAPDSMemInfo; -+ IMG_HANDLE hKernelClearClipWAUSEMemInfo; -+ IMG_HANDLE hKernelClearClipWAParamMemInfo; -+ IMG_HANDLE hKernelClearClipWAPMPTMemInfo; -+ IMG_HANDLE hKernelClearClipWATPCMemInfo; -+ IMG_HANDLE hKernelClearClipWAPSGRgnHdrMemInfo; -+#endif -+ -+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && \ -+ defined(FIX_HW_BRN_33657) && defined(SUPPORT_SECURE_33657_FIX) -+ IMG_HANDLE hKernelVDMStateUpdateBufferMemInfo; -+#endif -+#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG) -+ IMG_HANDLE hKernelEDMStatusBufferMemInfo; -+#endif -+ -+ IMG_UINT32 ui32EDMTaskReg0; -+ IMG_UINT32 ui32EDMTaskReg1; -+ -+ IMG_UINT32 ui32ClkGateCtl; -+ IMG_UINT32 ui32ClkGateCtl2; -+ IMG_UINT32 ui32ClkGateStatusReg; -+ IMG_UINT32 ui32ClkGateStatusMask; -+#if defined(SGX_FEATURE_MP) -+ IMG_UINT32 ui32MasterClkGateStatusReg; -+ IMG_UINT32 ui32MasterClkGateStatusMask; -+ IMG_UINT32 ui32MasterClkGateStatus2Reg; -+ IMG_UINT32 ui32MasterClkGateStatus2Mask; -+#endif /* SGX_FEATURE_MP */ -+ -+ IMG_UINT32 ui32CacheControl; -+ -+ IMG_UINT32 asInitDevData[SGX_MAX_DEV_DATA]; -+ IMG_HANDLE asInitMemHandles[SGX_MAX_INIT_MEM_HANDLES]; -+ -+} SGX_BRIDGE_INIT_INFO; -+ -+ -+typedef struct _SGX_DEVICE_SYNC_LIST_ -+{ -+ PSGXMKIF_HWDEVICE_SYNC_LIST psHWDeviceSyncList; -+ -+ IMG_HANDLE hKernelHWSyncListMemInfo; -+ PVRSRV_CLIENT_MEM_INFO *psHWDeviceSyncListClientMemInfo; -+ PVRSRV_CLIENT_MEM_INFO *psAccessResourceClientMemInfo; -+ -+ volatile IMG_UINT32 *pui32Lock; -+ -+ struct _SGX_DEVICE_SYNC_LIST_ *psNext; -+ -+ /* Must be the last variable in the structure */ -+ IMG_UINT32 ui32NumSyncObjects; -+ IMG_HANDLE ahSyncHandles[1]; -+} SGX_DEVICE_SYNC_LIST, *PSGX_DEVICE_SYNC_LIST; -+ -+ -+typedef struct _SGX_INTERNEL_STATUS_UPDATE_ -+{ -+ CTL_STATUS sCtlStatus; -+ IMG_HANDLE hKernelMemInfo; -+} SGX_INTERNEL_STATUS_UPDATE; -+ -+ -+typedef struct _SGX_CCB_KICK_ -+{ -+ SGXMKIF_COMMAND sCommand; -+ IMG_HANDLE hCCBKernelMemInfo; -+ -+ IMG_UINT32 ui32NumDstSyncObjects; -+ IMG_HANDLE hKernelHWSyncListMemInfo; -+ -+ /* DST syncs */ -+ IMG_HANDLE *pahDstSyncHandles; -+ -+ IMG_UINT32 ui32NumTAStatusVals; -+ IMG_UINT32 ui32Num3DStatusVals; -+ -+#if defined(SUPPORT_SGX_NEW_STATUS_VALS) -+ SGX_INTERNEL_STATUS_UPDATE asTAStatusUpdate[SGX_MAX_TA_STATUS_VALS]; -+ SGX_INTERNEL_STATUS_UPDATE as3DStatusUpdate[SGX_MAX_3D_STATUS_VALS]; -+#else -+ IMG_HANDLE ahTAStatusSyncInfo[SGX_MAX_TA_STATUS_VALS]; -+ IMG_HANDLE ah3DStatusSyncInfo[SGX_MAX_3D_STATUS_VALS]; -+#endif -+ -+ IMG_BOOL bFirstKickOrResume; -+#if defined(NO_HARDWARE) || defined(PDUMP) -+ IMG_BOOL bTerminateOrAbort; -+#endif -+ IMG_BOOL bLastInScene; -+ -+ /* CCB offset of data structure associated with this kick */ -+ IMG_UINT32 ui32CCBOffset; -+ -+#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS) -+ /* SRC and DST syncs */ -+ IMG_UINT32 ui32NumTASrcSyncs; -+ IMG_HANDLE ahTASrcKernelSyncInfo[SGX_MAX_TA_SRC_SYNCS]; -+ IMG_UINT32 ui32NumTADstSyncs; -+ IMG_HANDLE ahTADstKernelSyncInfo[SGX_MAX_TA_DST_SYNCS]; -+ IMG_UINT32 ui32Num3DSrcSyncs; -+ IMG_HANDLE ah3DSrcKernelSyncInfo[SGX_MAX_3D_SRC_SYNCS]; -+#else -+ /* SRC syncs */ -+ IMG_UINT32 ui32NumSrcSyncs; -+ IMG_HANDLE ahSrcKernelSyncInfo[SGX_MAX_SRC_SYNCS_TA]; -+#endif -+ -+ /* TA/3D dependency data */ -+ IMG_BOOL bTADependency; -+ IMG_HANDLE hTA3DSyncInfo; -+ -+ IMG_HANDLE hTASyncInfo; -+ IMG_HANDLE h3DSyncInfo; -+#if defined(PDUMP) -+ IMG_UINT32 ui32CCBDumpWOff; -+#endif -+#if defined(NO_HARDWARE) -+ IMG_UINT32 ui32WriteOpsPendingVal; -+#endif -+ IMG_HANDLE hDevMemContext; -+} SGX_CCB_KICK; -+ -+ -+/*! -+ ****************************************************************************** -+ * shared client/kernel device information structure for SGX -+ *****************************************************************************/ -+#define SGX_KERNEL_USE_CODE_BASE_INDEX 15 -+ -+ -+/*! -+ ****************************************************************************** -+ * Client device information structure for SGX -+ *****************************************************************************/ -+typedef struct _SGX_CLIENT_INFO_ -+{ -+ IMG_UINT32 ui32ProcessID; /*!< ID of process controlling SGX device */ -+ IMG_VOID *pvProcess; /*!< pointer to OS specific 'process' structure */ -+ PVRSRV_MISC_INFO sMiscInfo; /*!< Misc. Information, inc. SOC specifics */ -+ -+ IMG_UINT32 asDevData[SGX_MAX_DEV_DATA]; -+ -+} SGX_CLIENT_INFO; -+ -+/*! -+ ****************************************************************************** -+ * Internal device information structure for SGX -+ *****************************************************************************/ -+typedef struct _SGX_INTERNAL_DEVINFO_ -+{ -+ IMG_UINT32 ui32Flags; -+ IMG_HANDLE hHostCtlKernelMemInfoHandle; -+ IMG_BOOL bForcePTOff; -+} SGX_INTERNAL_DEVINFO; -+ -+ -+typedef struct _SGX_INTERNAL_DEVINFO_KM_ -+{ -+ IMG_UINT32 ui32Flags; -+ IMG_HANDLE hHostCtlKernelMemInfoHandle; -+ IMG_BOOL bForcePTOff; -+} SGX_INTERNAL_DEVINFO_KM; -+ -+ -+#if defined(TRANSFER_QUEUE) -+typedef struct _PVRSRV_TRANSFER_SGX_KICK_ -+{ -+ IMG_HANDLE hCCBMemInfo; -+ IMG_UINT32 ui32SharedCmdCCBOffset; -+ -+ IMG_DEV_VIRTADDR sHWTransferContextDevVAddr; -+ -+ IMG_HANDLE hTASyncInfo; -+ IMG_HANDLE h3DSyncInfo; -+ -+ IMG_UINT32 ui32NumSrcSync; -+ IMG_HANDLE ahSrcSyncInfo[SGX_MAX_TRANSFER_SYNC_OPS]; -+ -+ IMG_UINT32 ui32NumDstSync; -+ IMG_HANDLE ahDstSyncInfo[SGX_MAX_TRANSFER_SYNC_OPS]; -+ -+ IMG_UINT32 ui32Flags; -+ -+ IMG_UINT32 ui32PDumpFlags; -+#if defined(PDUMP) -+ IMG_UINT32 ui32CCBDumpWOff; -+#endif -+ IMG_HANDLE hDevMemContext; -+#if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) -+ /* Android >JB MR1 doesn't use ahSrcSyncInfo for synchronization */ -+ IMG_INT iFenceFd; -+#endif -+} PVRSRV_TRANSFER_SGX_KICK, *PPVRSRV_TRANSFER_SGX_KICK; -+ -+#if defined(SGX_FEATURE_2D_HARDWARE) -+typedef struct _PVRSRV_2D_SGX_KICK_ -+{ -+ IMG_HANDLE hCCBMemInfo; -+ IMG_UINT32 ui32SharedCmdCCBOffset; -+ -+ IMG_DEV_VIRTADDR sHW2DContextDevVAddr; -+ -+ IMG_UINT32 ui32NumSrcSync; -+ IMG_HANDLE ahSrcSyncInfo[SGX_MAX_2D_SRC_SYNC_OPS]; -+ -+ /* need to be able to check reads and writes on dest, and update writes */ -+ IMG_HANDLE hDstSyncInfo; -+ -+ /* need to be able to check reads and writes on TA ops, and update writes */ -+ IMG_HANDLE hTASyncInfo; -+ -+ /* need to be able to check reads and writes on 2D ops, and update writes */ -+ IMG_HANDLE h3DSyncInfo; -+ -+ IMG_UINT32 ui32PDumpFlags; -+#if defined(PDUMP) -+ IMG_UINT32 ui32CCBDumpWOff; -+#endif -+ IMG_HANDLE hDevMemContext; -+#if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) -+ /* Android >JB MR1 doesn't use ahSrcSyncInfo for synchronization */ -+ IMG_INT iFenceFd; -+#endif -+} PVRSRV_2D_SGX_KICK, *PPVRSRV_2D_SGX_KICK; -+#endif /* defined(SGX_FEATURE_2D_HARDWARE) */ -+#endif /* defined(TRANSFER_QUEUE) */ -+ -+ -+#endif /* __SGXINFO_H__ */ -+/****************************************************************************** -+ End of file (sgxinfo.h) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/bridged/bridged_pvr_bridge.c b/drivers/staging/ti-es8-sgx/services4/srvkm/bridged/bridged_pvr_bridge.c -new file mode 100644 -index 0000000..e3bc356 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/bridged/bridged_pvr_bridge.c -@@ -0,0 +1,4721 @@ -+/*************************************************************************/ /*! -+@Title PVR Common Bridge Module (kernel side) -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Receives calls from the user portion of services and -+ despatches them to functions in the kernel portion. -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+ -+ -+#include <stddef.h> -+ -+#include "img_defs.h" -+#include "services.h" -+#include "pvr_bridge_km.h" -+#include "pvr_debug.h" -+#include "ra.h" -+#include "pvr_bridge.h" -+#if defined(SUPPORT_SGX) -+#include "sgx_bridge.h" -+#endif -+#if defined(SUPPORT_VGX) -+#include "vgx_bridge.h" -+#endif -+#if defined(SUPPORT_MSVDX) -+#include "msvdx_bridge.h" -+#endif -+#include "perproc.h" -+#include "device.h" -+#include "buffer_manager.h" -+#include "refcount.h" -+ -+#include "pdump_km.h" -+#include "syscommon.h" -+ -+#include "bridged_pvr_bridge.h" -+#if defined(SUPPORT_SGX) -+#include "bridged_sgx_bridge.h" -+#endif -+#if defined(SUPPORT_VGX) -+#include "bridged_vgx_bridge.h" -+#endif -+#if defined(SUPPORT_MSVDX) -+#include "bridged_msvdx_bridge.h" -+#endif -+ -+#include "env_data.h" -+ -+#if defined (__linux__) || defined(__QNXNTO__) -+#include "mmap.h" -+#endif -+ -+ -+#if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) -+#include <linux/file.h> -+#include <linux/sync.h> -+#endif -+ -+#include "srvkm.h" -+ -+/* FIXME: we should include an OS specific header here to allow configuration of -+ * which functions should be excluded (like the shared srvclient bridge code) -+ * so that ports may choose to override certain things. */ -+ -+/* For the purpose of maintainability, it is intended that this file should not -+ * contain large amounts of OS specific #ifdefs. Headers are fine, and perhaps -+ * a few one liners, but for anything more, please find a way to add e.g. -+ * an osfunc.c abstraction or override the entire function in question within -+ * env,*,pvr_bridge_k.c -+ */ -+ -+ -+PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY g_BridgeDispatchTable[BRIDGE_DISPATCH_TABLE_ENTRY_COUNT]; -+ -+#if defined(DEBUG_BRIDGE_KM) -+PVRSRV_BRIDGE_GLOBAL_STATS g_BridgeGlobalStats; -+#endif -+ -+#if defined(PVR_SECURE_HANDLES) -+static IMG_BOOL abSharedDeviceMemHeap[PVRSRV_MAX_CLIENT_HEAPS]; -+static IMG_BOOL *pbSharedDeviceMemHeap = abSharedDeviceMemHeap; -+#else -+static IMG_BOOL *pbSharedDeviceMemHeap = (IMG_BOOL*)IMG_NULL; -+#endif -+ -+ -+#if defined(DEBUG_BRIDGE_KM) -+PVRSRV_ERROR -+CopyFromUserWrapper(PVRSRV_PER_PROCESS_DATA *pProcData, -+ IMG_UINT32 ui32BridgeID, -+ IMG_VOID *pvDest, -+ IMG_VOID *pvSrc, -+ IMG_UINT32 ui32Size) -+{ -+ g_BridgeDispatchTable[ui32BridgeID].ui32CopyFromUserTotalBytes+=ui32Size; -+ g_BridgeGlobalStats.ui32TotalCopyFromUserBytes+=ui32Size; -+ return OSCopyFromUser(pProcData, pvDest, pvSrc, ui32Size); -+} -+PVRSRV_ERROR -+CopyToUserWrapper(PVRSRV_PER_PROCESS_DATA *pProcData, -+ IMG_UINT32 ui32BridgeID, -+ IMG_VOID *pvDest, -+ IMG_VOID *pvSrc, -+ IMG_UINT32 ui32Size) -+{ -+ g_BridgeDispatchTable[ui32BridgeID].ui32CopyToUserTotalBytes+=ui32Size; -+ g_BridgeGlobalStats.ui32TotalCopyToUserBytes+=ui32Size; -+ return OSCopyToUser(pProcData, pvDest, pvSrc, ui32Size); -+} -+#endif -+ -+ -+static IMG_INT -+PVRSRVEnumerateDevicesBW(IMG_UINT32 ui32BridgeID, -+ IMG_VOID *psBridgeIn, -+ PVRSRV_BRIDGE_OUT_ENUMDEVICE *psEnumDeviceOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ENUM_DEVICES); -+ -+ PVR_UNREFERENCED_PARAMETER(psPerProc); -+ PVR_UNREFERENCED_PARAMETER(psBridgeIn); -+ -+ psEnumDeviceOUT->eError = -+ PVRSRVEnumerateDevicesKM(&psEnumDeviceOUT->ui32NumDevices, -+ psEnumDeviceOUT->asDeviceIdentifier); -+ -+ return 0; -+} -+ -+static IMG_INT -+PVRSRVAcquireDeviceDataBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_ACQUIRE_DEVICEINFO *psAcquireDevInfoIN, -+ PVRSRV_BRIDGE_OUT_ACQUIRE_DEVICEINFO *psAcquireDevInfoOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_HANDLE hDevCookieInt; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ACQUIRE_DEVICEINFO); -+ -+ psAcquireDevInfoOUT->eError = -+ PVRSRVAcquireDeviceDataKM(psAcquireDevInfoIN->uiDevIndex, -+ psAcquireDevInfoIN->eDeviceType, -+ &hDevCookieInt); -+ if(psAcquireDevInfoOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ /* -+ * Handle is not allocated in batch mode, as there is no resource -+ * allocation to undo if the handle allocation fails. -+ */ -+ psAcquireDevInfoOUT->eError = -+ PVRSRVAllocHandle(psPerProc->psHandleBase, -+ &psAcquireDevInfoOUT->hDevCookie, -+ hDevCookieInt, -+ PVRSRV_HANDLE_TYPE_DEV_NODE, -+ PVRSRV_HANDLE_ALLOC_FLAG_SHARED); -+ -+ return 0; -+} -+ -+ -+static IMG_INT -+PVRSRVCreateDeviceMemContextBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_CREATE_DEVMEMCONTEXT *psCreateDevMemContextIN, -+ PVRSRV_BRIDGE_OUT_CREATE_DEVMEMCONTEXT *psCreateDevMemContextOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_HANDLE hDevCookieInt; -+ IMG_HANDLE hDevMemContextInt; -+ IMG_UINT32 i; -+ IMG_BOOL bCreated; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CREATE_DEVMEMCONTEXT); -+ -+ /* -+ * We potentially need one handle for the device memory context, -+ * and one handle for each client heap. -+ */ -+ NEW_HANDLE_BATCH_OR_ERROR(psCreateDevMemContextOUT->eError, psPerProc, PVRSRV_MAX_CLIENT_HEAPS + 1) -+ -+ psCreateDevMemContextOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt, -+ psCreateDevMemContextIN->hDevCookie, -+ PVRSRV_HANDLE_TYPE_DEV_NODE); -+ -+ if(psCreateDevMemContextOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psCreateDevMemContextOUT->eError = -+ PVRSRVCreateDeviceMemContextKM(hDevCookieInt, -+ psPerProc, -+ &hDevMemContextInt, -+ &psCreateDevMemContextOUT->ui32ClientHeapCount, -+ &psCreateDevMemContextOUT->sHeapInfo[0], -+ &bCreated, -+ pbSharedDeviceMemHeap); -+ -+ if(psCreateDevMemContextOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ /* -+ * Only allocate a handle if the device memory context was created. -+ * If an existing context was returned, lookup the existing -+ * handle. -+ */ -+ if(bCreated) -+ { -+ PVRSRVAllocHandleNR(psPerProc->psHandleBase, -+ &psCreateDevMemContextOUT->hDevMemContext, -+ hDevMemContextInt, -+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT, -+ PVRSRV_HANDLE_ALLOC_FLAG_NONE); -+ } -+ else -+ { -+ psCreateDevMemContextOUT->eError = -+ PVRSRVFindHandle(psPerProc->psHandleBase, -+ &psCreateDevMemContextOUT->hDevMemContext, -+ hDevMemContextInt, -+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT); -+ if(psCreateDevMemContextOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ } -+ -+ for(i = 0; i < psCreateDevMemContextOUT->ui32ClientHeapCount; i++) -+ { -+ IMG_HANDLE hDevMemHeapExt; -+ -+#if defined(PVR_SECURE_HANDLES) -+ if(abSharedDeviceMemHeap[i]) -+#endif -+ { -+ /* -+ * Heaps shared by everybody. These heaps are not -+ * created as part of the device memory context -+ * creation, and exist for the lifetime of the -+ * driver, hence, we use shared handles for these -+ * heaps. -+ */ -+ PVRSRVAllocHandleNR(psPerProc->psHandleBase, &hDevMemHeapExt, -+ psCreateDevMemContextOUT->sHeapInfo[i].hDevMemHeap, -+ PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP, -+ PVRSRV_HANDLE_ALLOC_FLAG_SHARED); -+ } -+#if defined(PVR_SECURE_HANDLES) -+ else -+ { -+ /* -+ * Heaps belonging to this context. The handles for -+ * these are made subhandles of the memory context -+ * handle, so that they are automatically deallocated -+ * when the memory context handle is deallocated. -+ */ -+ if(bCreated) -+ { -+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, &hDevMemHeapExt, -+ psCreateDevMemContextOUT->sHeapInfo[i].hDevMemHeap, -+ PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP, -+ PVRSRV_HANDLE_ALLOC_FLAG_NONE, -+ psCreateDevMemContextOUT->hDevMemContext); -+ } -+ else -+ { -+ psCreateDevMemContextOUT->eError = -+ PVRSRVFindHandle(psPerProc->psHandleBase, -+ &hDevMemHeapExt, -+ psCreateDevMemContextOUT->sHeapInfo[i].hDevMemHeap, -+ PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP); -+ if(psCreateDevMemContextOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ } -+ } -+#endif -+ psCreateDevMemContextOUT->sHeapInfo[i].hDevMemHeap = hDevMemHeapExt; -+ } -+ -+ COMMIT_HANDLE_BATCH_OR_ERROR(psCreateDevMemContextOUT->eError, psPerProc) -+ -+ return 0; -+} -+ -+static IMG_INT -+PVRSRVDestroyDeviceMemContextBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_DESTROY_DEVMEMCONTEXT *psDestroyDevMemContextIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_HANDLE hDevCookieInt; -+ IMG_HANDLE hDevMemContextInt; -+ IMG_BOOL bDestroyed; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_DESTROY_DEVMEMCONTEXT); -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt, -+ psDestroyDevMemContextIN->hDevCookie, -+ PVRSRV_HANDLE_TYPE_DEV_NODE); -+ -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevMemContextInt, -+ psDestroyDevMemContextIN->hDevMemContext, -+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT); -+ -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = -+ PVRSRVDestroyDeviceMemContextKM(hDevCookieInt, hDevMemContextInt, &bDestroyed); -+ -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ if(bDestroyed) -+ { -+ psRetOUT->eError = -+ PVRSRVReleaseHandle(psPerProc->psHandleBase, -+ psDestroyDevMemContextIN->hDevMemContext, -+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT); -+ } -+ -+ return 0; -+} -+ -+ -+static IMG_INT -+PVRSRVGetDeviceMemHeapInfoBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_GET_DEVMEM_HEAPINFO *psGetDevMemHeapInfoIN, -+ PVRSRV_BRIDGE_OUT_GET_DEVMEM_HEAPINFO *psGetDevMemHeapInfoOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_HANDLE hDevCookieInt; -+ IMG_HANDLE hDevMemContextInt; -+ IMG_UINT32 i; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_DEVMEM_HEAPINFO); -+ -+ NEW_HANDLE_BATCH_OR_ERROR(psGetDevMemHeapInfoOUT->eError, psPerProc, PVRSRV_MAX_CLIENT_HEAPS) -+ -+ psGetDevMemHeapInfoOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt, -+ psGetDevMemHeapInfoIN->hDevCookie, -+ PVRSRV_HANDLE_TYPE_DEV_NODE); -+ -+ if(psGetDevMemHeapInfoOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psGetDevMemHeapInfoOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevMemContextInt, -+ psGetDevMemHeapInfoIN->hDevMemContext, -+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT); -+ -+ if(psGetDevMemHeapInfoOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psGetDevMemHeapInfoOUT->eError = -+ PVRSRVGetDeviceMemHeapInfoKM(hDevCookieInt, -+ hDevMemContextInt, -+ &psGetDevMemHeapInfoOUT->ui32ClientHeapCount, -+ &psGetDevMemHeapInfoOUT->sHeapInfo[0], -+ pbSharedDeviceMemHeap); -+ -+ if(psGetDevMemHeapInfoOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ for(i = 0; i < psGetDevMemHeapInfoOUT->ui32ClientHeapCount; i++) -+ { -+ IMG_HANDLE hDevMemHeapExt; -+ -+#if defined(PVR_SECURE_HANDLES) -+ if(abSharedDeviceMemHeap[i]) -+#endif -+ { -+ /* -+ * Heaps shared by everybody. These heaps are not -+ * created as part of the device memory context -+ * creation, and exist for the lifetime of the -+ * driver, hence, we use shared handles for these -+ * heaps. -+ */ -+ PVRSRVAllocHandleNR(psPerProc->psHandleBase, &hDevMemHeapExt, -+ psGetDevMemHeapInfoOUT->sHeapInfo[i].hDevMemHeap, -+ PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP, -+ PVRSRV_HANDLE_ALLOC_FLAG_SHARED); -+ } -+#if defined(PVR_SECURE_HANDLES) -+ else -+ { -+ /* -+ * Heaps belonging to this context. The handles for -+ * these are made subhandles of the memory context -+ * handle, so that they are automatically deallocated -+ * when the memory context handle is deallocated. -+ */ -+ psGetDevMemHeapInfoOUT->eError = -+ PVRSRVFindHandle(psPerProc->psHandleBase, -+ &hDevMemHeapExt, -+ psGetDevMemHeapInfoOUT->sHeapInfo[i].hDevMemHeap, -+ PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP); -+ if(psGetDevMemHeapInfoOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ } -+#endif -+ psGetDevMemHeapInfoOUT->sHeapInfo[i].hDevMemHeap = hDevMemHeapExt; -+ } -+ -+ COMMIT_HANDLE_BATCH_OR_ERROR(psGetDevMemHeapInfoOUT->eError, psPerProc) -+ -+ return 0; -+} -+ -+ -+#if defined(OS_PVRSRV_ALLOC_DEVICE_MEM_BW) -+/* customised version */ -+IMG_INT -+PVRSRVAllocDeviceMemBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_ALLOCDEVICEMEM *psAllocDeviceMemIN, -+ PVRSRV_BRIDGE_OUT_ALLOCDEVICEMEM *psAllocDeviceMemOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc); -+#else -+static IMG_INT -+PVRSRVAllocDeviceMemBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_ALLOCDEVICEMEM *psAllocDeviceMemIN, -+ PVRSRV_BRIDGE_OUT_ALLOCDEVICEMEM *psAllocDeviceMemOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ PVRSRV_KERNEL_MEM_INFO *psMemInfo; -+ IMG_HANDLE hDevCookieInt; -+ IMG_HANDLE hDevMemHeapInt; -+ IMG_UINT32 ui32ShareIndex; -+ IMG_BOOL bUseShareMemWorkaround; -+ IMG_BOOL *pabMapChunk = IMG_NULL; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ALLOC_DEVICEMEM); -+ -+ NEW_HANDLE_BATCH_OR_ERROR(psAllocDeviceMemOUT->eError, psPerProc, 2) -+ -+ /* Do same sanity checking */ -+ if (psAllocDeviceMemIN->ui32Attribs & PVRSRV_MEM_SPARSE) -+ { -+ if (psAllocDeviceMemIN->ui32NumPhysChunks > psAllocDeviceMemIN->ui32NumVirtChunks) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocDeviceMemBW: more physical chunks then virtual space")); -+ psAllocDeviceMemOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; -+ return 0; -+ } -+ -+ if (psAllocDeviceMemIN->pabMapChunk == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocDeviceMemBW: Called in sparse mapping mode but without MapChunk array")); -+ psAllocDeviceMemOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; -+ return 0; -+ } -+ } -+ -+ psAllocDeviceMemOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt, -+ psAllocDeviceMemIN->hDevCookie, -+ PVRSRV_HANDLE_TYPE_DEV_NODE); -+ -+ if(psAllocDeviceMemOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psAllocDeviceMemOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevMemHeapInt, -+ psAllocDeviceMemIN->hDevMemHeap, -+ PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP); -+ -+ if(psAllocDeviceMemOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ /* Memory sharing workaround, version 2 */ -+ -+ bUseShareMemWorkaround = ((psAllocDeviceMemIN->ui32Attribs & PVRSRV_MEM_XPROC) != 0) ? IMG_TRUE : IMG_FALSE; -+ ui32ShareIndex = 7654321; /* stops MSVC compiler warning */ -+ -+ if (bUseShareMemWorkaround) -+ { -+ /* allocate a shared-surface ID, prior to the call to AllocDeviceMem */ -+ /* We could plumb in an extra argument, but for now, we'll keep the -+ shared-surface ID as a piece of global state, and rely upon the -+ bridge mutex to make it safe for us */ -+ -+ psAllocDeviceMemOUT->eError = -+ BM_XProcWorkaroundFindNewBufferAndSetShareIndex(&ui32ShareIndex); -+ if(psAllocDeviceMemOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ } -+ -+ /* Check access to private data, if provided */ -+ if(psAllocDeviceMemIN->pvPrivData) -+ { -+ if(!OSAccessOK(PVR_VERIFY_READ, -+ psAllocDeviceMemIN->pvPrivData, -+ psAllocDeviceMemIN->ui32PrivDataLength)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocDeviceMemBW: Access check failed for pvPrivData")); -+ return -EFAULT; -+ } -+ } -+ -+ if (psAllocDeviceMemIN->ui32Attribs & PVRSRV_MEM_SPARSE) -+ { -+ /* Check access to the sparse mapping table, if provided */ -+ if(!OSAccessOK(PVR_VERIFY_READ, -+ psAllocDeviceMemIN->pabMapChunk, -+ psAllocDeviceMemIN->ui32NumVirtChunks)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocDeviceMemBW: Access check failed for pabMapChunk")); -+ return -EFAULT; -+ } -+ -+ psAllocDeviceMemOUT->eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(IMG_BOOL) * psAllocDeviceMemIN->ui32NumVirtChunks, -+ (IMG_VOID **) &pabMapChunk, -+ 0, -+ "MapChunk kernel copy"); -+ if (psAllocDeviceMemOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psAllocDeviceMemOUT->eError = OSCopyFromUser(psPerProc, -+ pabMapChunk, -+ psAllocDeviceMemIN->pabMapChunk, -+ sizeof(IMG_BOOL) * psAllocDeviceMemIN->ui32NumVirtChunks); -+ if (psAllocDeviceMemOUT->eError != PVRSRV_OK) -+ { -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(IMG_BOOL) * psAllocDeviceMemIN->ui32NumVirtChunks, -+ pabMapChunk, -+ 0); -+ return 0; -+ } -+ } -+ -+ -+ psAllocDeviceMemOUT->eError = -+ PVRSRVAllocDeviceMemKM(hDevCookieInt, -+ psPerProc, -+ hDevMemHeapInt, -+ psAllocDeviceMemIN->ui32Attribs, -+ psAllocDeviceMemIN->uSize, -+ psAllocDeviceMemIN->uAlignment, -+ psAllocDeviceMemIN->pvPrivData, -+ psAllocDeviceMemIN->ui32PrivDataLength, -+ psAllocDeviceMemIN->ui32ChunkSize, -+ psAllocDeviceMemIN->ui32NumVirtChunks, -+ psAllocDeviceMemIN->ui32NumPhysChunks, -+ pabMapChunk, -+ &psMemInfo, -+ "" /*FIXME: add something meaningful*/); -+ -+ if (bUseShareMemWorkaround) -+ { -+ PVR_ASSERT(ui32ShareIndex != 7654321); -+ BM_XProcWorkaroundUnsetShareIndex(ui32ShareIndex); -+ } -+ -+ if(psAllocDeviceMemOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psMemInfo->sShareMemWorkaround.bInUse = bUseShareMemWorkaround; -+ if (bUseShareMemWorkaround) -+ { -+ PVR_ASSERT(ui32ShareIndex != 7654321); -+ psMemInfo->sShareMemWorkaround.ui32ShareIndex = ui32ShareIndex; -+ psMemInfo->sShareMemWorkaround.hDevCookieInt = hDevCookieInt; -+ psMemInfo->sShareMemWorkaround.ui32OrigReqAttribs = psAllocDeviceMemIN->ui32Attribs; -+ psMemInfo->sShareMemWorkaround.ui32OrigReqSize = (IMG_UINT32)psAllocDeviceMemIN->uSize; -+ psMemInfo->sShareMemWorkaround.ui32OrigReqAlignment = (IMG_UINT32)psAllocDeviceMemIN->uAlignment; -+ } -+ -+ OSMemSet(&psAllocDeviceMemOUT->sClientMemInfo, -+ 0, -+ sizeof(psAllocDeviceMemOUT->sClientMemInfo)); -+ -+ psAllocDeviceMemOUT->sClientMemInfo.pvLinAddrKM = -+ psMemInfo->pvLinAddrKM; -+ -+#if defined (__linux__) -+ psAllocDeviceMemOUT->sClientMemInfo.pvLinAddr = 0; -+#else -+ psAllocDeviceMemOUT->sClientMemInfo.pvLinAddr = psMemInfo->pvLinAddrKM; -+#endif -+ psAllocDeviceMemOUT->sClientMemInfo.sDevVAddr = psMemInfo->sDevVAddr; -+ psAllocDeviceMemOUT->sClientMemInfo.ui32Flags = psMemInfo->ui32Flags; -+ psAllocDeviceMemOUT->sClientMemInfo.uAllocSize = psMemInfo->uAllocSize; -+ psAllocDeviceMemOUT->sClientMemInfo.hMappingInfo = psMemInfo->sMemBlk.hOSMemHandle; -+ -+ PVRSRVAllocHandleNR(psPerProc->psHandleBase, -+ &psAllocDeviceMemOUT->sClientMemInfo.hKernelMemInfo, -+ psMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO, -+ PVRSRV_HANDLE_ALLOC_FLAG_NONE); -+ -+ -+ if(psAllocDeviceMemIN->ui32Attribs & PVRSRV_MEM_NO_SYNCOBJ) -+ { -+ /* signal no syncinfo */ -+ OSMemSet(&psAllocDeviceMemOUT->sClientSyncInfo, -+ 0, -+ sizeof (PVRSRV_CLIENT_SYNC_INFO)); -+ psAllocDeviceMemOUT->sClientMemInfo.psClientSyncInfo = IMG_NULL; -+ } -+ else -+ { -+ /* and setup the sync info */ -+ -+#if !defined(PVRSRV_DISABLE_UM_SYNCOBJ_MAPPINGS) -+ psAllocDeviceMemOUT->sClientSyncInfo.psSyncData = -+ psMemInfo->psKernelSyncInfo->psSyncData; -+ psAllocDeviceMemOUT->sClientSyncInfo.sWriteOpsCompleteDevVAddr = -+ psMemInfo->psKernelSyncInfo->sWriteOpsCompleteDevVAddr; -+ psAllocDeviceMemOUT->sClientSyncInfo.sReadOpsCompleteDevVAddr = -+ psMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr; -+ psAllocDeviceMemOUT->sClientSyncInfo.sReadOps2CompleteDevVAddr = -+ psMemInfo->psKernelSyncInfo->sReadOps2CompleteDevVAddr; -+ -+ psAllocDeviceMemOUT->sClientSyncInfo.hMappingInfo = -+ psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle; -+#endif -+ -+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, -+ &psAllocDeviceMemOUT->sClientSyncInfo.hKernelSyncInfo, -+ psMemInfo->psKernelSyncInfo, -+ PVRSRV_HANDLE_TYPE_SYNC_INFO, -+ PVRSRV_HANDLE_ALLOC_FLAG_NONE, -+ psAllocDeviceMemOUT->sClientMemInfo.hKernelMemInfo); -+ -+ psAllocDeviceMemOUT->sClientMemInfo.psClientSyncInfo = -+ &psAllocDeviceMemOUT->sClientSyncInfo; -+ } -+ -+ COMMIT_HANDLE_BATCH_OR_ERROR(psAllocDeviceMemOUT->eError, psPerProc) -+ -+ return 0; -+} -+ -+#endif /* OS_PVRSRV_ALLOC_DEVICE_MEM_BW */ -+ -+static IMG_INT -+PVRSRVFreeDeviceMemBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_FREEDEVICEMEM *psFreeDeviceMemIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_HANDLE hDevCookieInt; -+ IMG_VOID *pvKernelMemInfo; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_FREE_DEVICEMEM); -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt, -+ psFreeDeviceMemIN->hDevCookie, -+ PVRSRV_HANDLE_TYPE_DEV_NODE); -+ -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &pvKernelMemInfo, -+ psFreeDeviceMemIN->psKernelMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = PVRSRVFreeDeviceMemKM(hDevCookieInt, pvKernelMemInfo); -+ -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = -+ PVRSRVReleaseHandle(psPerProc->psHandleBase, -+ psFreeDeviceMemIN->psKernelMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ -+ return 0; -+} -+ -+ -+static IMG_INT -+PVRSRVExportDeviceMemBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_EXPORTDEVICEMEM *psExportDeviceMemIN, -+ PVRSRV_BRIDGE_OUT_EXPORTDEVICEMEM *psExportDeviceMemOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_HANDLE hDevCookieInt; -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; -+ -+ PVR_ASSERT(ui32BridgeID == PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_EXPORT_DEVICEMEM) || -+ ui32BridgeID == PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_EXPORT_DEVICEMEM_2)); -+ PVR_UNREFERENCED_PARAMETER(ui32BridgeID); -+ -+ /* find the device cookie */ -+ psExportDeviceMemOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDevCookieInt, -+ psExportDeviceMemIN->hDevCookie, -+ PVRSRV_HANDLE_TYPE_DEV_NODE); -+ -+ if(psExportDeviceMemOUT->eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVExportDeviceMemBW: can't find devcookie")); -+ return 0; -+ } -+ -+ /* find the kernel meminfo from the process handle list */ -+ psExportDeviceMemOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ (IMG_PVOID *)&psKernelMemInfo, -+ psExportDeviceMemIN->psKernelMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ -+ if(psExportDeviceMemOUT->eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVExportDeviceMemBW: can't find kernel meminfo")); -+ return 0; -+ } -+ -+ /* see if it's already exported */ -+ psExportDeviceMemOUT->eError = -+ PVRSRVFindHandle(KERNEL_HANDLE_BASE, -+ &psExportDeviceMemOUT->hMemInfo, -+ psKernelMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if(psExportDeviceMemOUT->eError == PVRSRV_OK) -+ { -+ /* it's already exported */ -+ PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVExportDeviceMemBW: allocation is already exported")); -+ return 0; -+ } -+ -+ /* export the allocation */ -+ psExportDeviceMemOUT->eError = PVRSRVAllocHandle(KERNEL_HANDLE_BASE, -+ &psExportDeviceMemOUT->hMemInfo, -+ psKernelMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO, -+ PVRSRV_HANDLE_ALLOC_FLAG_NONE); -+ if (psExportDeviceMemOUT->eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVExportDeviceMemBW: failed to allocate handle from global handle list")); -+ return 0; -+ } -+ -+ /* mark the meminfo as 'exported' */ -+ psKernelMemInfo->ui32Flags |= PVRSRV_MEM_EXPORTED; -+ -+ return 0; -+} -+ -+ -+static IMG_INT -+PVRSRVMapDeviceMemoryBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_MAP_DEV_MEMORY *psMapDevMemIN, -+ PVRSRV_BRIDGE_OUT_MAP_DEV_MEMORY *psMapDevMemOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ PVRSRV_KERNEL_MEM_INFO *psSrcKernelMemInfo = IMG_NULL; -+ PVRSRV_KERNEL_MEM_INFO *psDstKernelMemInfo = IMG_NULL; -+ IMG_HANDLE hDstDevMemHeap = IMG_NULL; -+ -+ PVR_ASSERT(ui32BridgeID == PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_MAP_DEV_MEMORY) || -+ ui32BridgeID == PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_MAP_DEV_MEMORY_2)); -+ PVR_UNREFERENCED_PARAMETER(ui32BridgeID); -+ -+ NEW_HANDLE_BATCH_OR_ERROR(psMapDevMemOUT->eError, psPerProc, 2) -+ -+ /* lookup srcmeminfo handle */ -+ psMapDevMemOUT->eError = PVRSRVLookupHandle(KERNEL_HANDLE_BASE, -+ (IMG_VOID**)&psSrcKernelMemInfo, -+ psMapDevMemIN->hKernelMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if(psMapDevMemOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ /* lookup dev mem heap handle */ -+ psMapDevMemOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDstDevMemHeap, -+ psMapDevMemIN->hDstDevMemHeap, -+ PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP); -+ if(psMapDevMemOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ /* check for workaround */ -+ if (psSrcKernelMemInfo->sShareMemWorkaround.bInUse) -+ { -+ PVR_DPF((PVR_DBG_MESSAGE, "using the mem wrap workaround.")); -+ -+ /* Ensure we get the same ID for this allocation, such that it -+ inherits the same physical block. Rather than add a lot of -+ plumbing to several APIs, we call into buffer manager directly -+ to set "global" state. This works only if we make -+ this allocation while holding the bridge mutex and don't -+ make any other allocations (because the state persists and -+ would affect other device memory allocations too). It is -+ important that we bracket the PVRSRVAllocDeviceMemKM() call -+ with this Set/Unset pair. */ -+ psMapDevMemOUT->eError = BM_XProcWorkaroundSetShareIndex(psSrcKernelMemInfo->sShareMemWorkaround.ui32ShareIndex); -+ if(psMapDevMemOUT->eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVMapDeviceMemoryBW(): failed to recycle shared buffer")); -+ return 0; -+ } -+ -+ psMapDevMemOUT->eError = -+ PVRSRVAllocDeviceMemKM(psSrcKernelMemInfo->sShareMemWorkaround.hDevCookieInt, -+ psPerProc, -+ hDstDevMemHeap, -+ psSrcKernelMemInfo->sShareMemWorkaround.ui32OrigReqAttribs | PVRSRV_MEM_NO_SYNCOBJ, -+ psSrcKernelMemInfo->sShareMemWorkaround.ui32OrigReqSize, -+ psSrcKernelMemInfo->sShareMemWorkaround.ui32OrigReqAlignment, -+ IMG_NULL, -+ 0, -+ /* FIXME: Do we need to be able to export sparse memory? */ -+ 0,0,0,IMG_NULL, /* No sparse mapping data */ -+ &psDstKernelMemInfo, -+ "" /*FIXME: add something meaningful*/); -+ /* counterpart of the above "SetShareIndex". NB: this must be -+ done in both the success and failure paths of the -+ AllocDeviceMemKM() call */ -+ BM_XProcWorkaroundUnsetShareIndex(psSrcKernelMemInfo->sShareMemWorkaround.ui32ShareIndex); -+ if(psMapDevMemOUT->eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVMapDeviceMemoryBW: Failed to create allocation for cross-process memory map")); -+ return 0; -+ } -+ -+ if(psSrcKernelMemInfo->psKernelSyncInfo) -+ { -+ PVRSRVKernelSyncInfoIncRef(psSrcKernelMemInfo->psKernelSyncInfo, psSrcKernelMemInfo); -+ } -+ -+ psDstKernelMemInfo->psKernelSyncInfo = psSrcKernelMemInfo->psKernelSyncInfo; -+ } -+ else -+ { -+ /* map the meminfo to the target heap and memory context */ -+ psMapDevMemOUT->eError = PVRSRVMapDeviceMemoryKM(psPerProc, -+ psSrcKernelMemInfo, -+ hDstDevMemHeap, -+ &psDstKernelMemInfo); -+ if(psMapDevMemOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ } -+ -+ /* copy the workaround info */ -+ psDstKernelMemInfo->sShareMemWorkaround = psSrcKernelMemInfo->sShareMemWorkaround; -+ -+ OSMemSet(&psMapDevMemOUT->sDstClientMemInfo, -+ 0, -+ sizeof(psMapDevMemOUT->sDstClientMemInfo)); -+ OSMemSet(&psMapDevMemOUT->sDstClientSyncInfo, -+ 0, -+ sizeof(psMapDevMemOUT->sDstClientSyncInfo)); -+ -+ psMapDevMemOUT->sDstClientMemInfo.pvLinAddrKM = -+ psDstKernelMemInfo->pvLinAddrKM; -+ -+ psMapDevMemOUT->sDstClientMemInfo.pvLinAddr = 0; -+ psMapDevMemOUT->sDstClientMemInfo.sDevVAddr = psDstKernelMemInfo->sDevVAddr; -+ psMapDevMemOUT->sDstClientMemInfo.ui32Flags = psDstKernelMemInfo->ui32Flags; -+ psMapDevMemOUT->sDstClientMemInfo.uAllocSize = psDstKernelMemInfo->uAllocSize; -+ psMapDevMemOUT->sDstClientMemInfo.hMappingInfo = psDstKernelMemInfo->sMemBlk.hOSMemHandle; -+ -+ /* allocate handle to the DST kernel meminfo */ -+ PVRSRVAllocHandleNR(psPerProc->psHandleBase, -+ &psMapDevMemOUT->sDstClientMemInfo.hKernelMemInfo, -+ psDstKernelMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO, -+ PVRSRV_HANDLE_ALLOC_FLAG_NONE); -+ psMapDevMemOUT->sDstClientSyncInfo.hKernelSyncInfo = IMG_NULL; -+ -+ -+ /* and setup the sync info */ -+ if(psDstKernelMemInfo->psKernelSyncInfo) -+ { -+#if !defined(PVRSRV_DISABLE_UM_SYNCOBJ_MAPPINGS) -+ psMapDevMemOUT->sDstClientSyncInfo.psSyncData = -+ psDstKernelMemInfo->psKernelSyncInfo->psSyncData; -+ psMapDevMemOUT->sDstClientSyncInfo.sWriteOpsCompleteDevVAddr = -+ psDstKernelMemInfo->psKernelSyncInfo->sWriteOpsCompleteDevVAddr; -+ psMapDevMemOUT->sDstClientSyncInfo.sReadOpsCompleteDevVAddr = -+ psDstKernelMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr; -+ psMapDevMemOUT->sDstClientSyncInfo.sReadOps2CompleteDevVAddr = -+ psDstKernelMemInfo->psKernelSyncInfo->sReadOps2CompleteDevVAddr; -+ -+ psMapDevMemOUT->sDstClientSyncInfo.hMappingInfo = -+ psDstKernelMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle; -+#endif -+ -+ psMapDevMemOUT->sDstClientMemInfo.psClientSyncInfo = &psMapDevMemOUT->sDstClientSyncInfo; -+ /* -+ * The sync info is associated with the device buffer, -+ * and not allocated here. It isn't exported when created, -+ * hence the handle allocation rather than a lookup. -+ */ -+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, -+ &psMapDevMemOUT->sDstClientSyncInfo.hKernelSyncInfo, -+ psDstKernelMemInfo->psKernelSyncInfo, -+ PVRSRV_HANDLE_TYPE_SYNC_INFO, -+ PVRSRV_HANDLE_ALLOC_FLAG_MULTI, -+ psMapDevMemOUT->sDstClientMemInfo.hKernelMemInfo); -+ } -+ -+ COMMIT_HANDLE_BATCH_OR_ERROR(psMapDevMemOUT->eError, psPerProc) -+ -+ return 0; -+} -+ -+ -+static IMG_INT -+PVRSRVUnmapDeviceMemoryBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_UNMAP_DEV_MEMORY *psUnmapDevMemIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = IMG_NULL; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_UNMAP_DEV_MEMORY); -+ -+ psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ (IMG_VOID**)&psKernelMemInfo, -+ psUnmapDevMemIN->psKernelMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ if (psKernelMemInfo->sShareMemWorkaround.bInUse) -+ { -+ psRetOUT->eError = PVRSRVFreeDeviceMemKM(psKernelMemInfo->sShareMemWorkaround.hDevCookieInt, psKernelMemInfo); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVUnmapDeviceMemoryBW: internal error, should expect FreeDeviceMem to fail")); -+ return 0; -+ } -+ } -+ else -+ { -+ psRetOUT->eError = PVRSRVUnmapDeviceMemoryKM(psKernelMemInfo); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ } -+ -+ psRetOUT->eError = PVRSRVReleaseHandle(psPerProc->psHandleBase, -+ psUnmapDevMemIN->psKernelMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ -+ return 0; -+} -+ -+ -+ -+static IMG_INT -+PVRSRVMapDeviceClassMemoryBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_MAP_DEVICECLASS_MEMORY *psMapDevClassMemIN, -+ PVRSRV_BRIDGE_OUT_MAP_DEVICECLASS_MEMORY *psMapDevClassMemOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ PVRSRV_KERNEL_MEM_INFO *psMemInfo; -+ IMG_HANDLE hOSMapInfo; -+ IMG_HANDLE hDeviceClassBufferInt; -+ IMG_HANDLE hDevMemContextInt; -+ PVRSRV_HANDLE_TYPE eHandleType; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MAP_DEVICECLASS_MEMORY); -+ -+ NEW_HANDLE_BATCH_OR_ERROR(psMapDevClassMemOUT->eError, psPerProc, 2) -+ -+ /* -+ * The buffer to be mapped can belong to a 3rd party display or -+ * buffer driver, and we don't know which type we have at this -+ * point. -+ */ -+ psMapDevClassMemOUT->eError = -+ PVRSRVLookupHandleAnyType(psPerProc->psHandleBase, -+ &hDeviceClassBufferInt, -+ &eHandleType, -+ psMapDevClassMemIN->hDeviceClassBuffer); -+ -+ if(psMapDevClassMemOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ /* get the device memory context */ -+ psMapDevClassMemOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDevMemContextInt, -+ psMapDevClassMemIN->hDevMemContext, -+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT); -+ -+ if(psMapDevClassMemOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ /* Having looked up the handle, now check its type */ -+ switch(eHandleType) -+ { -+#if defined(PVR_SECURE_HANDLES) -+ case PVRSRV_HANDLE_TYPE_DISP_BUFFER: -+ case PVRSRV_HANDLE_TYPE_BUF_BUFFER: -+#else -+ case PVRSRV_HANDLE_TYPE_NONE: -+#endif -+ break; -+ default: -+ psMapDevClassMemOUT->eError = PVRSRV_ERROR_INVALID_HANDLE_TYPE; -+ return 0; -+ } -+ -+ psMapDevClassMemOUT->eError = -+ PVRSRVMapDeviceClassMemoryKM(psPerProc, -+ hDevMemContextInt, -+ hDeviceClassBufferInt, -+ &psMemInfo, -+ &hOSMapInfo); -+ if(psMapDevClassMemOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ OSMemSet(&psMapDevClassMemOUT->sClientMemInfo, -+ 0, -+ sizeof(psMapDevClassMemOUT->sClientMemInfo)); -+ OSMemSet(&psMapDevClassMemOUT->sClientSyncInfo, -+ 0, -+ sizeof(psMapDevClassMemOUT->sClientSyncInfo)); -+ -+ psMapDevClassMemOUT->sClientMemInfo.pvLinAddrKM = -+ psMemInfo->pvLinAddrKM; -+ -+ psMapDevClassMemOUT->sClientMemInfo.pvLinAddr = 0; -+ psMapDevClassMemOUT->sClientMemInfo.sDevVAddr = psMemInfo->sDevVAddr; -+ psMapDevClassMemOUT->sClientMemInfo.ui32Flags = psMemInfo->ui32Flags; -+ psMapDevClassMemOUT->sClientMemInfo.uAllocSize = psMemInfo->uAllocSize; -+ psMapDevClassMemOUT->sClientMemInfo.hMappingInfo = psMemInfo->sMemBlk.hOSMemHandle; -+ -+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, -+ &psMapDevClassMemOUT->sClientMemInfo.hKernelMemInfo, -+ psMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO, -+ PVRSRV_HANDLE_ALLOC_FLAG_NONE, -+ psMapDevClassMemIN->hDeviceClassBuffer); -+ -+ psMapDevClassMemOUT->sClientSyncInfo.hKernelSyncInfo = IMG_NULL; -+ -+ /* and setup the sync info */ -+ if(psMemInfo->psKernelSyncInfo) -+ { -+#if !defined(PVRSRV_DISABLE_UM_SYNCOBJ_MAPPINGS) -+ psMapDevClassMemOUT->sClientSyncInfo.psSyncData = -+ psMemInfo->psKernelSyncInfo->psSyncData; -+ psMapDevClassMemOUT->sClientSyncInfo.sWriteOpsCompleteDevVAddr = -+ psMemInfo->psKernelSyncInfo->sWriteOpsCompleteDevVAddr; -+ psMapDevClassMemOUT->sClientSyncInfo.sReadOpsCompleteDevVAddr = -+ psMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr; -+ psMapDevClassMemOUT->sClientSyncInfo.sReadOps2CompleteDevVAddr = -+ psMemInfo->psKernelSyncInfo->sReadOps2CompleteDevVAddr; -+ -+ psMapDevClassMemOUT->sClientSyncInfo.hMappingInfo = -+ psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle; -+#endif -+ -+ psMapDevClassMemOUT->sClientMemInfo.psClientSyncInfo = &psMapDevClassMemOUT->sClientSyncInfo; -+ /* -+ * The sync info is associated with the device buffer, -+ * and not allocated here. It isn't exported when -+ * created, hence the handle allocation rather than a -+ * lookup. -+ */ -+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, -+ &psMapDevClassMemOUT->sClientSyncInfo.hKernelSyncInfo, -+ psMemInfo->psKernelSyncInfo, -+ PVRSRV_HANDLE_TYPE_SYNC_INFO, -+ PVRSRV_HANDLE_ALLOC_FLAG_MULTI, -+ psMapDevClassMemOUT->sClientMemInfo.hKernelMemInfo); -+ } -+ -+ COMMIT_HANDLE_BATCH_OR_ERROR(psMapDevClassMemOUT->eError, psPerProc) -+ -+ return 0; -+} -+ -+static IMG_INT -+PVRSRVUnmapDeviceClassMemoryBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_UNMAP_DEVICECLASS_MEMORY *psUnmapDevClassMemIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_VOID *pvKernelMemInfo; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_UNMAP_DEVICECLASS_MEMORY); -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, &pvKernelMemInfo, -+ psUnmapDevClassMemIN->psKernelMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = PVRSRVUnmapDeviceClassMemoryKM(pvKernelMemInfo); -+ -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = -+ PVRSRVReleaseHandle(psPerProc->psHandleBase, -+ psUnmapDevClassMemIN->psKernelMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ -+ return 0; -+} -+ -+ -+#if defined(OS_PVRSRV_WRAP_EXT_MEM_BW) -+IMG_INT -+PVRSRVWrapExtMemoryBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_WRAP_EXT_MEMORY *psWrapExtMemIN, -+ PVRSRV_BRIDGE_OUT_WRAP_EXT_MEMORY *psWrapExtMemOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc); -+#else /* OS_PVRSRV_WRAP_EXT_MEM_BW */ -+static IMG_INT -+PVRSRVWrapExtMemoryBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_WRAP_EXT_MEMORY *psWrapExtMemIN, -+ PVRSRV_BRIDGE_OUT_WRAP_EXT_MEMORY *psWrapExtMemOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_HANDLE hDevCookieInt; -+ IMG_HANDLE hDevMemContextInt; -+ PVRSRV_KERNEL_MEM_INFO *psMemInfo; -+ IMG_SYS_PHYADDR *psSysPAddr = IMG_NULL; -+ IMG_UINT32 ui32PageTableSize = 0; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_WRAP_EXT_MEMORY); -+ -+ NEW_HANDLE_BATCH_OR_ERROR(psWrapExtMemOUT->eError, psPerProc, 2) -+ -+ /* -+ * FIXME: This needs reworking - don't use the user supplied page -+ * table list, get the list from the OS. -+ */ -+ psWrapExtMemOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt, -+ psWrapExtMemIN->hDevCookie, -+ PVRSRV_HANDLE_TYPE_DEV_NODE); -+ if(psWrapExtMemOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ /* get the device memory context */ -+ psWrapExtMemOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevMemContextInt, -+ psWrapExtMemIN->hDevMemContext, -+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT); -+ -+ if(psWrapExtMemOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ if(psWrapExtMemIN->ui32NumPageTableEntries) -+ { -+ ui32PageTableSize = psWrapExtMemIN->ui32NumPageTableEntries -+ * sizeof(IMG_SYS_PHYADDR); -+ -+ ASSIGN_AND_EXIT_ON_ERROR(psWrapExtMemOUT->eError, -+ OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ ui32PageTableSize, -+ (IMG_VOID **)&psSysPAddr, 0, -+ "Page Table")); -+ -+ if(CopyFromUserWrapper(psPerProc, -+ ui32BridgeID, -+ psSysPAddr, -+ psWrapExtMemIN->psSysPAddr, -+ ui32PageTableSize) != PVRSRV_OK) -+ { -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32PageTableSize, (IMG_VOID *)psSysPAddr, 0); -+ /*not nulling pointer, out of scope*/ -+ return -EFAULT; -+ } -+ } -+ -+ psWrapExtMemOUT->eError = -+ PVRSRVWrapExtMemoryKM(hDevCookieInt, -+ psPerProc, -+ hDevMemContextInt, -+ psWrapExtMemIN->uByteSize, -+ psWrapExtMemIN->uPageOffset, -+ psWrapExtMemIN->bPhysContig, -+ psSysPAddr, -+ psWrapExtMemIN->pvLinAddr, -+ psWrapExtMemIN->ui32Flags, -+ &psMemInfo); -+ -+ if(psWrapExtMemIN->ui32NumPageTableEntries) -+ { -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, -+ ui32PageTableSize, -+ (IMG_VOID *)psSysPAddr, 0); -+ /*not nulling pointer, out of scope*/ -+ } -+ -+ if(psWrapExtMemOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psWrapExtMemOUT->sClientMemInfo.pvLinAddrKM = -+ psMemInfo->pvLinAddrKM; -+ -+ /* setup the mem info */ -+ psWrapExtMemOUT->sClientMemInfo.pvLinAddr = 0; -+ psWrapExtMemOUT->sClientMemInfo.sDevVAddr = psMemInfo->sDevVAddr; -+ psWrapExtMemOUT->sClientMemInfo.ui32Flags = psMemInfo->ui32Flags; -+ psWrapExtMemOUT->sClientMemInfo.uAllocSize = psMemInfo->uAllocSize; -+ psWrapExtMemOUT->sClientMemInfo.hMappingInfo = psMemInfo->sMemBlk.hOSMemHandle; -+ -+ PVRSRVAllocHandleNR(psPerProc->psHandleBase, -+ &psWrapExtMemOUT->sClientMemInfo.hKernelMemInfo, -+ psMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO, -+ PVRSRV_HANDLE_ALLOC_FLAG_NONE); -+ -+ -+ /* setup the sync info */ -+#if !defined(PVRSRV_DISABLE_UM_SYNCOBJ_MAPPINGS) -+ psWrapExtMemOUT->sClientSyncInfo.psSyncData = -+ psMemInfo->psKernelSyncInfo->psSyncData; -+ psWrapExtMemOUT->sClientSyncInfo.sWriteOpsCompleteDevVAddr = -+ psMemInfo->psKernelSyncInfo->sWriteOpsCompleteDevVAddr; -+ psWrapExtMemOUT->sClientSyncInfo.sReadOpsCompleteDevVAddr = -+ psMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr; -+ psWrapExtMemOUT->sClientSyncInfo.sReadOps2CompleteDevVAddr = -+ psMemInfo->psKernelSyncInfo->sReadOps2CompleteDevVAddr; -+ -+ psWrapExtMemOUT->sClientSyncInfo.hMappingInfo = -+ psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle; -+#endif -+ -+ psWrapExtMemOUT->sClientMemInfo.psClientSyncInfo = &psWrapExtMemOUT->sClientSyncInfo; -+ -+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, -+ &psWrapExtMemOUT->sClientSyncInfo.hKernelSyncInfo, -+ (IMG_HANDLE)psMemInfo->psKernelSyncInfo, -+ PVRSRV_HANDLE_TYPE_SYNC_INFO, -+ PVRSRV_HANDLE_ALLOC_FLAG_NONE, -+ psWrapExtMemOUT->sClientMemInfo.hKernelMemInfo); -+ -+ COMMIT_HANDLE_BATCH_OR_ERROR(psWrapExtMemOUT->eError, psPerProc) -+ -+ return 0; -+} -+#endif /* OS_PVRSRV_WRAP_EXT_MEM_BW */ -+ -+static IMG_INT -+PVRSRVUnwrapExtMemoryBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_UNWRAP_EXT_MEMORY *psUnwrapExtMemIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_VOID *pvMemInfo; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_UNWRAP_EXT_MEMORY); -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &pvMemInfo, -+ psUnwrapExtMemIN->hKernelMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = -+ PVRSRVUnwrapExtMemoryKM((PVRSRV_KERNEL_MEM_INFO *)pvMemInfo); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = -+ PVRSRVReleaseHandle(psPerProc->psHandleBase, -+ psUnwrapExtMemIN->hKernelMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ -+ return 0; -+} -+ -+#if defined(SUPPORT_ION) -+static IMG_INT -+PVRSRVMapIonHandleBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_MAP_ION_HANDLE *psMapIonIN, -+ PVRSRV_BRIDGE_OUT_MAP_ION_HANDLE *psMapIonOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; -+ IMG_UINT64 ui64Stamp; -+ -+ psMapIonOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &psMapIonIN->hDevCookie, -+ psMapIonIN->hDevCookie, -+ PVRSRV_HANDLE_TYPE_DEV_NODE); -+ if (psMapIonOUT->eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: Failed to lookup device node handle", __FUNCTION__)); -+ return 0; -+ } -+ -+ psMapIonOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &psMapIonIN->hDevMemHeap, -+ psMapIonIN->hDevMemHeap, -+ PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP); -+ if (psMapIonOUT->eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: Failed to lookup memory context handle", __FUNCTION__)); -+ return 0; -+ } -+ -+ psMapIonOUT->eError = PVRSRVMapIonHandleKM(psPerProc, -+ psMapIonIN->hDevCookie, -+ psMapIonIN->hDevMemHeap, -+ psMapIonIN->ui32NumFDs, -+ psMapIonIN->ai32BufferFDs, -+ psMapIonIN->ui32Attribs, -+ psMapIonIN->ui32ChunkCount, -+ psMapIonIN->auiOffset, -+ psMapIonIN->auiSize, -+ &psMapIonOUT->uiIonBufferSize, -+ &psKernelMemInfo, -+ &ui64Stamp); -+ if (psMapIonOUT->eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: Failed to map ion handle", __FUNCTION__)); -+ return 0; -+ } -+ -+ OSMemSet(&psMapIonOUT->sClientMemInfo, -+ 0, -+ sizeof(psMapIonOUT->sClientMemInfo)); -+ -+ psMapIonOUT->sClientMemInfo.pvLinAddrKM = -+ psKernelMemInfo->pvLinAddrKM; -+ -+ psMapIonOUT->sClientMemInfo.pvLinAddr = 0; -+ psMapIonOUT->sClientMemInfo.sDevVAddr = psKernelMemInfo->sDevVAddr; -+ psMapIonOUT->sClientMemInfo.ui32Flags = psKernelMemInfo->ui32Flags; -+ psMapIonOUT->sClientMemInfo.uAllocSize = psKernelMemInfo->uAllocSize; -+ -+ /* No mapping info, we map through ion */ -+ psMapIonOUT->sClientMemInfo.hMappingInfo = IMG_NULL; -+ -+#if defined(SUPPORT_MEMINFO_IDS) -+ psMapIonOUT->sClientMemInfo.ui64Stamp = ui64Stamp; -+#endif -+ -+ PVRSRVAllocHandleNR(psPerProc->psHandleBase, -+ &psMapIonOUT->sClientMemInfo.hKernelMemInfo, -+ psKernelMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO, -+ PVRSRV_HANDLE_ALLOC_FLAG_NONE); -+ -+ if(psMapIonIN->ui32Attribs & PVRSRV_MEM_NO_SYNCOBJ) -+ { -+ /* signal no syncinfo */ -+ OSMemSet(&psMapIonOUT->sClientSyncInfo, -+ 0, -+ sizeof (PVRSRV_CLIENT_SYNC_INFO)); -+ psMapIonOUT->sClientMemInfo.psClientSyncInfo = IMG_NULL; -+ } -+ else -+ { -+ /* and setup the sync info */ -+#if !defined(PVRSRV_DISABLE_UM_SYNCOBJ_MAPPINGS) -+ psMapIonOUT->sClientSyncInfo.psSyncData = -+ psKernelMemInfo->psKernelSyncInfo->psSyncData; -+ psMapIonOUT->sClientSyncInfo.sWriteOpsCompleteDevVAddr = -+ psKernelMemInfo->psKernelSyncInfo->sWriteOpsCompleteDevVAddr; -+ psMapIonOUT->sClientSyncInfo.sReadOpsCompleteDevVAddr = -+ psKernelMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr; -+ psMapIonOUT->sClientSyncInfo.sReadOps2CompleteDevVAddr = -+ psKernelMemInfo->psKernelSyncInfo->sReadOps2CompleteDevVAddr; -+ -+ psMapIonOUT->sClientSyncInfo.hMappingInfo = -+ psKernelMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle; -+#endif -+ -+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, -+ &psMapIonOUT->sClientSyncInfo.hKernelSyncInfo, -+ psKernelMemInfo->psKernelSyncInfo, -+ PVRSRV_HANDLE_TYPE_SYNC_INFO, -+ PVRSRV_HANDLE_ALLOC_FLAG_NONE, -+ psMapIonOUT->sClientMemInfo.hKernelMemInfo); -+ -+ psMapIonOUT->sClientMemInfo.psClientSyncInfo = -+ &psMapIonOUT->sClientSyncInfo; -+ } -+ return 0; -+} -+ -+static IMG_INT -+PVRSRVUnmapIonHandleBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_UNMAP_ION_HANDLE *psUnmapIonIN, -+ PVRSRV_BRIDGE_RETURN *psUnmapIonOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_VOID *pvKernelMemInfo; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_UNMAP_ION_HANDLE); -+ -+ psUnmapIonOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &pvKernelMemInfo, -+ psUnmapIonIN->psKernelMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ -+ if(psUnmapIonOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psUnmapIonOUT->eError = PVRSRVUnmapIonHandleKM(pvKernelMemInfo); -+ -+ if(psUnmapIonOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psUnmapIonOUT->eError = -+ PVRSRVReleaseHandle(psPerProc->psHandleBase, -+ psUnmapIonIN->psKernelMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ -+ return 0; -+} -+#endif /* SUPPORT_ION */ -+ -+static IMG_INT -+PVRSRVGetFreeDeviceMemBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_GETFREEDEVICEMEM *psGetFreeDeviceMemIN, -+ PVRSRV_BRIDGE_OUT_GETFREEDEVICEMEM *psGetFreeDeviceMemOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GETFREE_DEVICEMEM); -+ -+ PVR_UNREFERENCED_PARAMETER(psPerProc); -+ -+ psGetFreeDeviceMemOUT->eError = -+ PVRSRVGetFreeDeviceMemKM(psGetFreeDeviceMemIN->ui32Flags, -+ &psGetFreeDeviceMemOUT->uTotal, -+ &psGetFreeDeviceMemOUT->uFree, -+ &psGetFreeDeviceMemOUT->uLargestBlock); -+ -+ return 0; -+} -+ -+static IMG_INT -+PVRMMapOSMemHandleToMMapDataBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_MHANDLE_TO_MMAP_DATA *psMMapDataIN, -+ PVRSRV_BRIDGE_OUT_MHANDLE_TO_MMAP_DATA *psMMapDataOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MHANDLE_TO_MMAP_DATA); -+ -+#if defined (__linux__) || defined (__QNXNTO__) -+ psMMapDataOUT->eError = -+ PVRMMapOSMemHandleToMMapData(psPerProc, -+ psMMapDataIN->hMHandle, -+ &psMMapDataOUT->uiMMapOffset, -+ &psMMapDataOUT->uiByteOffset, -+ &psMMapDataOUT->uiRealByteSize, -+ &psMMapDataOUT->uiUserVAddr); -+#else -+ PVR_UNREFERENCED_PARAMETER(psPerProc); -+ PVR_UNREFERENCED_PARAMETER(psMMapDataIN); -+ -+ psMMapDataOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED; -+#endif -+ return 0; -+} -+ -+ -+static IMG_INT -+PVRMMapReleaseMMapDataBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_RELEASE_MMAP_DATA *psMMapDataIN, -+ PVRSRV_BRIDGE_OUT_RELEASE_MMAP_DATA *psMMapDataOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_RELEASE_MMAP_DATA); -+ -+#if defined (__linux__) || defined (__QNXNTO__) -+ psMMapDataOUT->eError = -+ PVRMMapReleaseMMapData(psPerProc, -+ psMMapDataIN->hMHandle, -+ &psMMapDataOUT->bMUnmap, -+ &psMMapDataOUT->uiRealByteSize, -+ &psMMapDataOUT->uiUserVAddr); -+#else -+ -+ PVR_UNREFERENCED_PARAMETER(psPerProc); -+ PVR_UNREFERENCED_PARAMETER(psMMapDataIN); -+ -+ psMMapDataOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED; -+#endif -+ return 0; -+} -+ -+ -+static IMG_INT -+PVRSRVChangeDeviceMemoryAttributesBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_CHG_DEV_MEM_ATTRIBS *psChgMemAttribIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ PVR_UNREFERENCED_PARAMETER(ui32BridgeID); -+ PVR_UNREFERENCED_PARAMETER(psChgMemAttribIN); -+ PVR_UNREFERENCED_PARAMETER(psRetOUT); -+ PVR_UNREFERENCED_PARAMETER(psPerProc); -+ -+ return 0; -+} -+ -+#ifdef PDUMP -+static IMG_INT -+PDumpIsCaptureFrameBW(IMG_UINT32 ui32BridgeID, -+ IMG_VOID *psBridgeIn, -+ PVRSRV_BRIDGE_OUT_PDUMP_ISCAPTURING *psPDumpIsCapturingOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_ISCAPTURING); -+ PVR_UNREFERENCED_PARAMETER(psBridgeIn); -+ PVR_UNREFERENCED_PARAMETER(psPerProc); -+ -+ psPDumpIsCapturingOUT->bIsCapturing = PDumpIsCaptureFrameKM(); -+ psPDumpIsCapturingOUT->eError = PVRSRV_OK; -+ -+ return 0; -+} -+ -+static IMG_INT -+PDumpCommentBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_PDUMP_COMMENT *psPDumpCommentIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_COMMENT); -+ PVR_UNREFERENCED_PARAMETER(psPerProc); -+ -+ psRetOUT->eError = PDumpCommentKM(&psPDumpCommentIN->szComment[0], -+ psPDumpCommentIN->ui32Flags); -+ return 0; -+} -+ -+static IMG_INT -+PDumpSetFrameBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_PDUMP_SETFRAME *psPDumpSetFrameIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_SETFRAME); -+ PVR_UNREFERENCED_PARAMETER(psPerProc); -+ -+ psRetOUT->eError = PDumpSetFrameKM(psPDumpSetFrameIN->ui32Frame); -+ -+ return 0; -+} -+ -+static IMG_INT -+PDumpRegWithFlagsBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_PDUMP_DUMPREG *psPDumpRegDumpIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_REG); -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ (IMG_VOID **)&psDeviceNode, -+ psPDumpRegDumpIN->hDevCookie, -+ PVRSRV_HANDLE_TYPE_DEV_NODE); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = PDumpRegWithFlagsKM (psPDumpRegDumpIN->szRegRegion, -+ psPDumpRegDumpIN->sHWReg.ui32RegAddr, -+ psPDumpRegDumpIN->sHWReg.ui32RegVal, -+ psPDumpRegDumpIN->ui32Flags); -+ -+ return 0; -+} -+ -+static IMG_INT -+PDumpRegPolBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_PDUMP_REGPOL *psPDumpRegPolIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_REGPOL); -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ (IMG_VOID **)&psDeviceNode, -+ psPDumpRegPolIN->hDevCookie, -+ PVRSRV_HANDLE_TYPE_DEV_NODE); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ -+ psRetOUT->eError = -+ PDumpRegPolWithFlagsKM(psPDumpRegPolIN->szRegRegion, -+ psPDumpRegPolIN->sHWReg.ui32RegAddr, -+ psPDumpRegPolIN->sHWReg.ui32RegVal, -+ psPDumpRegPolIN->ui32Mask, -+ psPDumpRegPolIN->ui32Flags, -+ PDUMP_POLL_OPERATOR_EQUAL); -+ -+ return 0; -+} -+ -+static IMG_INT -+PDumpMemPolBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_PDUMP_MEMPOL *psPDumpMemPolIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_VOID *pvMemInfo; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_MEMPOL); -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &pvMemInfo, -+ psPDumpMemPolIN->psKernelMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = -+ PDumpMemPolKM(((PVRSRV_KERNEL_MEM_INFO *)pvMemInfo), -+ psPDumpMemPolIN->ui32Offset, -+ psPDumpMemPolIN->ui32Value, -+ psPDumpMemPolIN->ui32Mask, -+ psPDumpMemPolIN->eOperator, -+ psPDumpMemPolIN->ui32Flags, -+ MAKEUNIQUETAG(pvMemInfo)); -+ -+ return 0; -+} -+ -+static IMG_INT -+PDumpMemBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_PDUMP_DUMPMEM *psPDumpMemDumpIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_VOID *pvMemInfo; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_DUMPMEM); -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &pvMemInfo, -+ psPDumpMemDumpIN->psKernelMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = -+ PDumpMemUM(psPerProc, -+ psPDumpMemDumpIN->pvAltLinAddr, -+ psPDumpMemDumpIN->pvLinAddr, -+ pvMemInfo, -+ psPDumpMemDumpIN->ui32Offset, -+ psPDumpMemDumpIN->ui32Bytes, -+ psPDumpMemDumpIN->ui32Flags, -+ MAKEUNIQUETAG(pvMemInfo)); -+ -+ return 0; -+} -+ -+static IMG_INT -+PDumpBitmapBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_PDUMP_BITMAP *psPDumpBitmapIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+ IMG_HANDLE hDevMemContextInt; -+ -+ PVR_UNREFERENCED_PARAMETER(ui32BridgeID); -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, (IMG_VOID **)&psDeviceNode, -+ psPDumpBitmapIN->hDevCookie, -+ PVRSRV_HANDLE_TYPE_DEV_NODE); -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle( psPerProc->psHandleBase, -+ &hDevMemContextInt, -+ psPDumpBitmapIN->hDevMemContext, -+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT); -+ -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = -+ PDumpBitmapKM(psDeviceNode, -+ &psPDumpBitmapIN->szFileName[0], -+ psPDumpBitmapIN->ui32FileOffset, -+ psPDumpBitmapIN->ui32Width, -+ psPDumpBitmapIN->ui32Height, -+ psPDumpBitmapIN->ui32StrideInBytes, -+ psPDumpBitmapIN->sDevBaseAddr, -+ hDevMemContextInt, -+ psPDumpBitmapIN->ui32Size, -+ psPDumpBitmapIN->ePixelFormat, -+ psPDumpBitmapIN->eMemFormat, -+ psPDumpBitmapIN->ui32Flags); -+ -+ return 0; -+} -+ -+static IMG_INT -+PDumpReadRegBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_PDUMP_READREG *psPDumpReadRegIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_DUMPREADREG); -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, (IMG_VOID **)&psDeviceNode, -+ psPDumpReadRegIN->hDevCookie, -+ PVRSRV_HANDLE_TYPE_DEV_NODE); -+ -+ psRetOUT->eError = -+ PDumpReadRegKM(&psPDumpReadRegIN->szRegRegion[0], -+ &psPDumpReadRegIN->szFileName[0], -+ psPDumpReadRegIN->ui32FileOffset, -+ psPDumpReadRegIN->ui32Address, -+ psPDumpReadRegIN->ui32Size, -+ psPDumpReadRegIN->ui32Flags); -+ -+ return 0; -+} -+ -+static IMG_INT -+PDumpMemPagesBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_PDUMP_MEMPAGES *psPDumpMemPagesIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_MEMPAGES); -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ (IMG_VOID **)&psDeviceNode, -+ psPDumpMemPagesIN->hDevCookie, -+ PVRSRV_HANDLE_TYPE_DEV_NODE); -+ -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ -+ return 0; -+} -+ -+static IMG_INT -+PDumpDriverInfoBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_PDUMP_DRIVERINFO *psPDumpDriverInfoIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_UINT32 ui32PDumpFlags; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_DRIVERINFO); -+ PVR_UNREFERENCED_PARAMETER(psPerProc); -+ -+ ui32PDumpFlags = 0; -+ if(psPDumpDriverInfoIN->bContinuous) -+ { -+ ui32PDumpFlags |= PDUMP_FLAGS_CONTINUOUS; -+ } -+ psRetOUT->eError = -+ PDumpDriverInfoKM(&psPDumpDriverInfoIN->szString[0], -+ ui32PDumpFlags); -+ -+ return 0; -+} -+ -+static IMG_INT -+PDumpSyncDumpBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_PDUMP_DUMPSYNC *psPDumpSyncDumpIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_UINT32 ui32Bytes = psPDumpSyncDumpIN->ui32Bytes; -+ IMG_VOID *pvSyncInfo; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_DUMPSYNC); -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, &pvSyncInfo, -+ psPDumpSyncDumpIN->psKernelSyncInfo, -+ PVRSRV_HANDLE_TYPE_SYNC_INFO); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = -+ PDumpMemUM(psPerProc, -+ psPDumpSyncDumpIN->pvAltLinAddr, -+ IMG_NULL, -+ ((PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)->psSyncDataMemInfoKM, -+ psPDumpSyncDumpIN->ui32Offset, -+ ui32Bytes, -+ 0, -+ MAKEUNIQUETAG(((PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)->psSyncDataMemInfoKM)); -+ -+ return 0; -+} -+ -+static IMG_INT -+PDumpSyncPolBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_PDUMP_SYNCPOL *psPDumpSyncPolIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_UINT32 ui32Offset; -+ IMG_VOID *pvSyncInfo; -+ IMG_UINT32 ui32Value; -+ IMG_UINT32 ui32Mask; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_SYNCPOL); -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &pvSyncInfo, -+ psPDumpSyncPolIN->psKernelSyncInfo, -+ PVRSRV_HANDLE_TYPE_SYNC_INFO); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ if(psPDumpSyncPolIN->bIsRead) -+ { -+ ui32Offset = offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete); -+ } -+ else -+ { -+ ui32Offset = offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete); -+ } -+ -+ /* FIXME: Move this code to somewhere outside of the bridge */ -+ if (psPDumpSyncPolIN->bUseLastOpDumpVal) -+ { -+ if(psPDumpSyncPolIN->bIsRead) -+ { -+ ui32Value = ((PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)->psSyncData->ui32LastReadOpDumpVal; -+ } -+ else -+ { -+ ui32Value = ((PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)->psSyncData->ui32LastOpDumpVal; -+ } -+ ui32Mask = 0xffffffff; -+ } -+ else -+ { -+ ui32Value = psPDumpSyncPolIN->ui32Value; -+ ui32Mask = psPDumpSyncPolIN->ui32Mask; -+ } -+ -+ psRetOUT->eError = -+ PDumpMemPolKM(((PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)->psSyncDataMemInfoKM, -+ ui32Offset, -+ ui32Value, -+ ui32Mask, -+ PDUMP_POLL_OPERATOR_EQUAL, -+ 0, -+ MAKEUNIQUETAG(((PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)->psSyncDataMemInfoKM)); -+ -+ return 0; -+} -+ -+ -+static IMG_INT -+PDumpCycleCountRegReadBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_PDUMP_CYCLE_COUNT_REG_READ *psPDumpCycleCountRegReadIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_CYCLE_COUNT_REG_READ); -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ (IMG_VOID **)&psDeviceNode, -+ psPDumpCycleCountRegReadIN->hDevCookie, -+ PVRSRV_HANDLE_TYPE_DEV_NODE); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ PDumpCycleCountRegRead(&psDeviceNode->sDevId, -+ psPDumpCycleCountRegReadIN->ui32RegOffset, -+ psPDumpCycleCountRegReadIN->bLastFrame); -+ -+ psRetOUT->eError = PVRSRV_OK; -+ -+ return 0; -+} -+ -+static IMG_INT -+PDumpPDDevPAddrBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_PDUMP_DUMPPDDEVPADDR *psPDumpPDDevPAddrIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_VOID *pvMemInfo; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_DUMPPDDEVPADDR); -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, &pvMemInfo, -+ psPDumpPDDevPAddrIN->hKernelMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = -+ PDumpPDDevPAddrKM((PVRSRV_KERNEL_MEM_INFO *)pvMemInfo, -+ psPDumpPDDevPAddrIN->ui32Offset, -+ psPDumpPDDevPAddrIN->sPDDevPAddr, -+ MAKEUNIQUETAG(pvMemInfo), -+ PDUMP_PD_UNIQUETAG); -+ return 0; -+} -+ -+static IMG_INT -+PDumpStartInitPhaseBW(IMG_UINT32 ui32BridgeID, -+ IMG_VOID *psBridgeIn, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_STARTINITPHASE); -+ PVR_UNREFERENCED_PARAMETER(psBridgeIn); -+ PVR_UNREFERENCED_PARAMETER(psPerProc); -+ -+ psRetOUT->eError = PDumpStartInitPhaseKM(); -+ -+ return 0; -+} -+ -+static IMG_INT -+PDumpStopInitPhaseBW(IMG_UINT32 ui32BridgeID, -+ IMG_VOID *psBridgeIn, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_STOPINITPHASE); -+ PVR_UNREFERENCED_PARAMETER(psBridgeIn); -+ PVR_UNREFERENCED_PARAMETER(psPerProc); -+ -+ psRetOUT->eError = PDumpStopInitPhaseKM(); -+ -+ return 0; -+} -+ -+#endif /* PDUMP */ -+ -+ -+static IMG_INT -+PVRSRVGetMiscInfoBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_GET_MISC_INFO *psGetMiscInfoIN, -+ PVRSRV_BRIDGE_OUT_GET_MISC_INFO *psGetMiscInfoOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ PVRSRV_ERROR eError; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_MISC_INFO); -+ -+ OSMemCopy(&psGetMiscInfoOUT->sMiscInfo, -+ &psGetMiscInfoIN->sMiscInfo, -+ sizeof(PVRSRV_MISC_INFO)); -+ -+ if (((psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_MEMSTATS_PRESENT) != 0) && -+ ((psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_DDKVERSION_PRESENT) != 0) && -+ ((psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_FREEMEM_PRESENT) != 0)) -+ { -+ /* Client must choose which of memstats and DDK version will be written to -+ * kernel side buffer */ -+ psGetMiscInfoOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; -+ return 0; -+ } -+ -+ if (((psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_MEMSTATS_PRESENT) != 0) || -+ ((psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_DDKVERSION_PRESENT) != 0) || -+ ((psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_FREEMEM_PRESENT) != 0)) -+ { -+ /* Alloc kernel side buffer to write into */ -+ ASSIGN_AND_EXIT_ON_ERROR(psGetMiscInfoOUT->eError, -+ OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ psGetMiscInfoOUT->sMiscInfo.ui32MemoryStrLen, -+ (IMG_VOID **)&psGetMiscInfoOUT->sMiscInfo.pszMemoryStr, 0, -+ "Output string buffer")); -+ -+ psGetMiscInfoOUT->eError = PVRSRVGetMiscInfoKM(&psGetMiscInfoOUT->sMiscInfo); -+ -+ /* Copy result to user */ -+ eError = CopyToUserWrapper(psPerProc, ui32BridgeID, -+ psGetMiscInfoIN->sMiscInfo.pszMemoryStr, -+ psGetMiscInfoOUT->sMiscInfo.pszMemoryStr, -+ psGetMiscInfoOUT->sMiscInfo.ui32MemoryStrLen); -+ -+ /* Free kernel side buffer again */ -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, -+ psGetMiscInfoOUT->sMiscInfo.ui32MemoryStrLen, -+ (IMG_VOID *)psGetMiscInfoOUT->sMiscInfo.pszMemoryStr, 0); -+ -+ /* Replace output buffer pointer with input pointer, as both are expected -+ * to point to the same userspace memory. -+ */ -+ psGetMiscInfoOUT->sMiscInfo.pszMemoryStr = psGetMiscInfoIN->sMiscInfo.pszMemoryStr; -+ -+ if(eError != PVRSRV_OK) -+ { -+ /* Do error check at the end as we always have to free and reset the -+ * pointer. -+ */ -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetMiscInfoBW Error copy to user")); -+ return -EFAULT; -+ } -+ } -+ else -+ { -+ psGetMiscInfoOUT->eError = PVRSRVGetMiscInfoKM(&psGetMiscInfoOUT->sMiscInfo); -+ } -+ -+ /* Return on error so exit status of PVRSRVGetMiscInfoKM is propagated to client. -+ * Don't alloc handles for event object or timer; if error exit status is returned -+ * the handles should not be used (even if not null) */ -+ if (psGetMiscInfoOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ /* -+ * The handles are not allocated in batch mode as they are shared -+ * (a shared handle is allocated at most once), and there is no -+ * resource allocation to undo if the handle allocation fails. -+ */ -+ if (psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT) -+ { -+ psGetMiscInfoOUT->eError = PVRSRVAllocHandle(psPerProc->psHandleBase, -+ &psGetMiscInfoOUT->sMiscInfo.sGlobalEventObject.hOSEventKM, -+ psGetMiscInfoOUT->sMiscInfo.sGlobalEventObject.hOSEventKM, -+ PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT, -+ PVRSRV_HANDLE_ALLOC_FLAG_SHARED); -+ -+ if (psGetMiscInfoOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ } -+ -+ if (psGetMiscInfoOUT->sMiscInfo.hSOCTimerRegisterOSMemHandle) -+ { -+ /* Allocate handle for SOC OSMemHandle */ -+ psGetMiscInfoOUT->eError = PVRSRVAllocHandle(psPerProc->psHandleBase, -+ &psGetMiscInfoOUT->sMiscInfo.hSOCTimerRegisterOSMemHandle, -+ psGetMiscInfoOUT->sMiscInfo.hSOCTimerRegisterOSMemHandle, -+ PVRSRV_HANDLE_TYPE_SOC_TIMER, -+ PVRSRV_HANDLE_ALLOC_FLAG_SHARED); -+ -+ if (psGetMiscInfoOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ } -+ -+ return 0; -+} -+ -+static IMG_INT -+PVRSRVConnectBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_CONNECT_SERVICES *psConnectServicesIN, -+ PVRSRV_BRIDGE_OUT_CONNECT_SERVICES *psConnectServicesOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CONNECT_SERVICES); -+ -+#if defined(PDUMP) -+ /* Store the per process connection info. -+ * The Xserver initially connects via PVR2D which sets the persistent flag. -+ * But, later the Xserver may connect via SGL which doesn't carry the flag (in -+ * general SGL clients aren't persistent). So we OR in the flag so if it was set -+ * before it remains set. -+ */ -+ if ((psConnectServicesIN->ui32Flags & SRV_FLAGS_PERSIST) != 0) -+ { -+ psPerProc->bPDumpPersistent = IMG_TRUE; -+ } -+ -+#if defined(SUPPORT_PDUMP_MULTI_PROCESS) -+ /* Select whether this client is our 'active' target for pdumping in a -+ * multi-process environment. -+ * NOTE: only 1 active target is supported at present. -+ */ -+ if ((psConnectServicesIN->ui32Flags & SRV_FLAGS_PDUMP_ACTIVE) != 0) -+ { -+ psPerProc->bPDumpActive = IMG_TRUE; -+ } -+#endif /* SUPPORT_PDUMP_MULTI_PROCESS */ -+#else -+ PVR_UNREFERENCED_PARAMETER(psConnectServicesIN); -+#endif -+ psConnectServicesOUT->hKernelServices = psPerProc->hPerProcData; -+ psConnectServicesOUT->eError = PVRSRV_OK; -+ -+ return 0; -+} -+ -+static IMG_INT -+PVRSRVDisconnectBW(IMG_UINT32 ui32BridgeID, -+ IMG_VOID *psBridgeIn, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ PVR_UNREFERENCED_PARAMETER(psPerProc); -+ PVR_UNREFERENCED_PARAMETER(psBridgeIn); -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_DISCONNECT_SERVICES); -+ -+ /* just return OK, per-process data is cleaned up by resmgr */ -+ psRetOUT->eError = PVRSRV_OK; -+ -+ return 0; -+} -+ -+static IMG_INT -+PVRSRVEnumerateDCBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_ENUMCLASS *psEnumDispClassIN, -+ PVRSRV_BRIDGE_OUT_ENUMCLASS *psEnumDispClassOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ PVR_UNREFERENCED_PARAMETER(psPerProc); -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ENUM_CLASS); -+ -+ psEnumDispClassOUT->eError = -+ PVRSRVEnumerateDCKM(psEnumDispClassIN->sDeviceClass, -+ &psEnumDispClassOUT->ui32NumDevices, -+ &psEnumDispClassOUT->ui32DevID[0]); -+ -+ return 0; -+} -+ -+static IMG_INT -+PVRSRVOpenDCDeviceBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_OPEN_DISPCLASS_DEVICE *psOpenDispClassDeviceIN, -+ PVRSRV_BRIDGE_OUT_OPEN_DISPCLASS_DEVICE *psOpenDispClassDeviceOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_HANDLE hDevCookieInt; -+ IMG_HANDLE hDispClassInfoInt; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_OPEN_DISPCLASS_DEVICE); -+ -+ NEW_HANDLE_BATCH_OR_ERROR(psOpenDispClassDeviceOUT->eError, psPerProc, 1) -+ -+ psOpenDispClassDeviceOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDevCookieInt, -+ psOpenDispClassDeviceIN->hDevCookie, -+ PVRSRV_HANDLE_TYPE_DEV_NODE); -+ if(psOpenDispClassDeviceOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psOpenDispClassDeviceOUT->eError = -+ PVRSRVOpenDCDeviceKM(psPerProc, -+ psOpenDispClassDeviceIN->ui32DeviceID, -+ hDevCookieInt, -+ &hDispClassInfoInt); -+ -+ if(psOpenDispClassDeviceOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ PVRSRVAllocHandleNR(psPerProc->psHandleBase, -+ &psOpenDispClassDeviceOUT->hDeviceKM, -+ hDispClassInfoInt, -+ PVRSRV_HANDLE_TYPE_DISP_INFO, -+ PVRSRV_HANDLE_ALLOC_FLAG_NONE); -+ COMMIT_HANDLE_BATCH_OR_ERROR(psOpenDispClassDeviceOUT->eError, psPerProc) -+ -+ return 0; -+} -+ -+static IMG_INT -+PVRSRVCloseDCDeviceBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_CLOSE_DISPCLASS_DEVICE *psCloseDispClassDeviceIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_VOID *pvDispClassInfoInt; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CLOSE_DISPCLASS_DEVICE); -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &pvDispClassInfoInt, -+ psCloseDispClassDeviceIN->hDeviceKM, -+ PVRSRV_HANDLE_TYPE_DISP_INFO); -+ -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = PVRSRVCloseDCDeviceKM(pvDispClassInfoInt); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = -+ PVRSRVReleaseHandle(psPerProc->psHandleBase, -+ psCloseDispClassDeviceIN->hDeviceKM, -+ PVRSRV_HANDLE_TYPE_DISP_INFO); -+ return 0; -+} -+ -+static IMG_INT -+PVRSRVEnumDCFormatsBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_ENUM_DISPCLASS_FORMATS *psEnumDispClassFormatsIN, -+ PVRSRV_BRIDGE_OUT_ENUM_DISPCLASS_FORMATS *psEnumDispClassFormatsOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_VOID *pvDispClassInfoInt; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ENUM_DISPCLASS_FORMATS); -+ -+ psEnumDispClassFormatsOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &pvDispClassInfoInt, -+ psEnumDispClassFormatsIN->hDeviceKM, -+ PVRSRV_HANDLE_TYPE_DISP_INFO); -+ if(psEnumDispClassFormatsOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psEnumDispClassFormatsOUT->eError = -+ PVRSRVEnumDCFormatsKM(pvDispClassInfoInt, -+ &psEnumDispClassFormatsOUT->ui32Count, -+ psEnumDispClassFormatsOUT->asFormat); -+ -+ return 0; -+} -+ -+static IMG_INT -+PVRSRVEnumDCDimsBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_ENUM_DISPCLASS_DIMS *psEnumDispClassDimsIN, -+ PVRSRV_BRIDGE_OUT_ENUM_DISPCLASS_DIMS *psEnumDispClassDimsOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_VOID *pvDispClassInfoInt; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ENUM_DISPCLASS_DIMS); -+ -+ psEnumDispClassDimsOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &pvDispClassInfoInt, -+ psEnumDispClassDimsIN->hDeviceKM, -+ PVRSRV_HANDLE_TYPE_DISP_INFO); -+ -+ if(psEnumDispClassDimsOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psEnumDispClassDimsOUT->eError = -+ PVRSRVEnumDCDimsKM(pvDispClassInfoInt, -+ &psEnumDispClassDimsIN->sFormat, -+ &psEnumDispClassDimsOUT->ui32Count, -+ psEnumDispClassDimsOUT->asDim); -+ -+ return 0; -+} -+ -+#if defined(SUPPORT_PVRSRV_GET_DC_SYSTEM_BUFFER) -+static IMG_INT -+PVRSRVGetDCSystemBufferBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_GET_DISPCLASS_SYSBUFFER *psGetDispClassSysBufferIN, //IMG_HANDLE *phGetDispClassSysBufferIN, -+ PVRSRV_BRIDGE_OUT_GET_DISPCLASS_SYSBUFFER *psGetDispClassSysBufferOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_HANDLE hBufferInt; -+ IMG_VOID *pvDispClassInfoInt; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_DISPCLASS_SYSBUFFER); -+ -+ NEW_HANDLE_BATCH_OR_ERROR(psGetDispClassSysBufferOUT->eError, psPerProc, 1) -+ -+ psGetDispClassSysBufferOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &pvDispClassInfoInt, -+ psGetDispClassSysBufferIN->hDeviceKM, -+ PVRSRV_HANDLE_TYPE_DISP_INFO); -+ if(psGetDispClassSysBufferOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psGetDispClassSysBufferOUT->eError = -+ PVRSRVGetDCSystemBufferKM(pvDispClassInfoInt, -+ &hBufferInt); -+ -+ if(psGetDispClassSysBufferOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ /* PRQA S 1461 6 */ /* ignore warning about enum type being converted */ -+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, -+ &psGetDispClassSysBufferOUT->hBuffer, -+ hBufferInt, -+ PVRSRV_HANDLE_TYPE_DISP_BUFFER, -+ (PVRSRV_HANDLE_ALLOC_FLAG)(PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE | PVRSRV_HANDLE_ALLOC_FLAG_SHARED), -+ psGetDispClassSysBufferIN->hDeviceKM); -+ -+ COMMIT_HANDLE_BATCH_OR_ERROR(psGetDispClassSysBufferOUT->eError, psPerProc) -+ -+ return 0; -+} -+#endif -+ -+static IMG_INT -+PVRSRVGetDCInfoBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_GET_DISPCLASS_INFO *psGetDispClassInfoIN, -+ PVRSRV_BRIDGE_OUT_GET_DISPCLASS_INFO *psGetDispClassInfoOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_VOID *pvDispClassInfo; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_DISPCLASS_INFO); -+ -+ psGetDispClassInfoOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &pvDispClassInfo, -+ psGetDispClassInfoIN->hDeviceKM, -+ PVRSRV_HANDLE_TYPE_DISP_INFO); -+ if(psGetDispClassInfoOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psGetDispClassInfoOUT->eError = -+ PVRSRVGetDCInfoKM(pvDispClassInfo, -+ &psGetDispClassInfoOUT->sDisplayInfo); -+ -+ return 0; -+} -+ -+static IMG_INT -+PVRSRVCreateDCSwapChainBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_CREATE_DISPCLASS_SWAPCHAIN *psCreateDispClassSwapChainIN, -+ PVRSRV_BRIDGE_OUT_CREATE_DISPCLASS_SWAPCHAIN *psCreateDispClassSwapChainOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_VOID *pvDispClassInfo; -+ IMG_HANDLE hSwapChainInt; -+ IMG_UINT32 ui32SwapChainID; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CREATE_DISPCLASS_SWAPCHAIN); -+ -+ NEW_HANDLE_BATCH_OR_ERROR(psCreateDispClassSwapChainOUT->eError, psPerProc, 1) -+ -+ psCreateDispClassSwapChainOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &pvDispClassInfo, -+ psCreateDispClassSwapChainIN->hDeviceKM, -+ PVRSRV_HANDLE_TYPE_DISP_INFO); -+ -+ if(psCreateDispClassSwapChainOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ /* Get ui32SwapChainID from input */ -+ ui32SwapChainID = psCreateDispClassSwapChainIN->ui32SwapChainID; -+ -+ psCreateDispClassSwapChainOUT->eError = -+ PVRSRVCreateDCSwapChainKM(psPerProc, pvDispClassInfo, -+ psCreateDispClassSwapChainIN->ui32Flags, -+ &psCreateDispClassSwapChainIN->sDstSurfAttrib, -+ &psCreateDispClassSwapChainIN->sSrcSurfAttrib, -+ psCreateDispClassSwapChainIN->ui32BufferCount, -+ psCreateDispClassSwapChainIN->ui32OEMFlags, -+ &hSwapChainInt, -+ &ui32SwapChainID); -+ -+ if(psCreateDispClassSwapChainOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ /* Pass ui32SwapChainID to output */ -+ psCreateDispClassSwapChainOUT->ui32SwapChainID = ui32SwapChainID; -+ -+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, -+ &psCreateDispClassSwapChainOUT->hSwapChain, -+ hSwapChainInt, -+ PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN, -+ PVRSRV_HANDLE_ALLOC_FLAG_NONE, -+ psCreateDispClassSwapChainIN->hDeviceKM); -+ -+ COMMIT_HANDLE_BATCH_OR_ERROR(psCreateDispClassSwapChainOUT->eError, psPerProc) -+ -+ return 0; -+} -+ -+static IMG_INT -+PVRSRVDestroyDCSwapChainBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_DESTROY_DISPCLASS_SWAPCHAIN *psDestroyDispClassSwapChainIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_VOID *pvSwapChain; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_DESTROY_DISPCLASS_SWAPCHAIN); -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, &pvSwapChain, -+ psDestroyDispClassSwapChainIN->hSwapChain, -+ PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = -+ PVRSRVDestroyDCSwapChainKM(pvSwapChain); -+ -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = -+ PVRSRVReleaseHandle(psPerProc->psHandleBase, -+ psDestroyDispClassSwapChainIN->hSwapChain, -+ PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN); -+ -+ return 0; -+} -+ -+static IMG_INT -+PVRSRVSetDCDstRectBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_SET_DISPCLASS_RECT *psSetDispClassDstRectIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_VOID *pvDispClassInfo; -+ IMG_VOID *pvSwapChain; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SET_DISPCLASS_DSTRECT); -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &pvDispClassInfo, -+ psSetDispClassDstRectIN->hDeviceKM, -+ PVRSRV_HANDLE_TYPE_DISP_INFO); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &pvSwapChain, -+ psSetDispClassDstRectIN->hSwapChain, -+ PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN); -+ -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = -+ PVRSRVSetDCDstRectKM(pvDispClassInfo, -+ pvSwapChain, -+ &psSetDispClassDstRectIN->sRect); -+ -+ return 0; -+} -+ -+static IMG_INT -+PVRSRVSetDCSrcRectBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_SET_DISPCLASS_RECT *psSetDispClassSrcRectIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_VOID *pvDispClassInfo; -+ IMG_VOID *pvSwapChain; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SET_DISPCLASS_SRCRECT); -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &pvDispClassInfo, -+ psSetDispClassSrcRectIN->hDeviceKM, -+ PVRSRV_HANDLE_TYPE_DISP_INFO); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &pvSwapChain, -+ psSetDispClassSrcRectIN->hSwapChain, -+ PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = -+ PVRSRVSetDCSrcRectKM(pvDispClassInfo, -+ pvSwapChain, -+ &psSetDispClassSrcRectIN->sRect); -+ -+ return 0; -+} -+ -+static IMG_INT -+PVRSRVSetDCDstColourKeyBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_SET_DISPCLASS_COLOURKEY *psSetDispClassColKeyIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_VOID *pvDispClassInfo; -+ IMG_VOID *pvSwapChain; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SET_DISPCLASS_DSTCOLOURKEY); -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &pvDispClassInfo, -+ psSetDispClassColKeyIN->hDeviceKM, -+ PVRSRV_HANDLE_TYPE_DISP_INFO); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &pvSwapChain, -+ psSetDispClassColKeyIN->hSwapChain, -+ PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = -+ PVRSRVSetDCDstColourKeyKM(pvDispClassInfo, -+ pvSwapChain, -+ psSetDispClassColKeyIN->ui32CKColour); -+ -+ return 0; -+} -+ -+static IMG_INT -+PVRSRVSetDCSrcColourKeyBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_SET_DISPCLASS_COLOURKEY *psSetDispClassColKeyIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_VOID *pvDispClassInfo; -+ IMG_VOID *pvSwapChain; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SET_DISPCLASS_SRCCOLOURKEY); -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &pvDispClassInfo, -+ psSetDispClassColKeyIN->hDeviceKM, -+ PVRSRV_HANDLE_TYPE_DISP_INFO); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &pvSwapChain, -+ psSetDispClassColKeyIN->hSwapChain, -+ PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = -+ PVRSRVSetDCSrcColourKeyKM(pvDispClassInfo, -+ pvSwapChain, -+ psSetDispClassColKeyIN->ui32CKColour); -+ -+ return 0; -+} -+ -+static IMG_INT -+PVRSRVGetDCBuffersBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_GET_DISPCLASS_BUFFERS *psGetDispClassBuffersIN, -+ PVRSRV_BRIDGE_OUT_GET_DISPCLASS_BUFFERS *psGetDispClassBuffersOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_VOID *pvDispClassInfo; -+ IMG_VOID *pvSwapChain; -+ IMG_UINT32 i; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_DISPCLASS_BUFFERS); -+ -+ NEW_HANDLE_BATCH_OR_ERROR(psGetDispClassBuffersOUT->eError, psPerProc, PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS) -+ -+ psGetDispClassBuffersOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &pvDispClassInfo, -+ psGetDispClassBuffersIN->hDeviceKM, -+ PVRSRV_HANDLE_TYPE_DISP_INFO); -+ if(psGetDispClassBuffersOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psGetDispClassBuffersOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &pvSwapChain, -+ psGetDispClassBuffersIN->hSwapChain, -+ PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN); -+ if(psGetDispClassBuffersOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ -+ psGetDispClassBuffersOUT->eError = -+ PVRSRVGetDCBuffersKM(pvDispClassInfo, -+ pvSwapChain, -+ &psGetDispClassBuffersOUT->ui32BufferCount, -+ psGetDispClassBuffersOUT->ahBuffer, -+ psGetDispClassBuffersOUT->asPhyAddr); -+ if (psGetDispClassBuffersOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ PVR_ASSERT(psGetDispClassBuffersOUT->ui32BufferCount <= PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS); -+ -+ for(i = 0; i < psGetDispClassBuffersOUT->ui32BufferCount; i++) -+ { -+ IMG_HANDLE hBufferExt; -+ -+ /* PRQA S 1461 15 */ /* ignore warning about enum type being converted */ -+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, -+ &hBufferExt, -+ psGetDispClassBuffersOUT->ahBuffer[i], -+ PVRSRV_HANDLE_TYPE_DISP_BUFFER, -+ (PVRSRV_HANDLE_ALLOC_FLAG)(PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE | PVRSRV_HANDLE_ALLOC_FLAG_SHARED), -+ psGetDispClassBuffersIN->hSwapChain); -+ -+ psGetDispClassBuffersOUT->ahBuffer[i] = hBufferExt; -+ } -+ -+ -+ COMMIT_HANDLE_BATCH_OR_ERROR(psGetDispClassBuffersOUT->eError, psPerProc) -+ -+ return 0; -+} -+ -+static IMG_INT -+PVRSRVSwapToDCBufferBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_BUFFER *psSwapDispClassBufferIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_VOID *pvDispClassInfo; -+ IMG_VOID *pvSwapChainBuf; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_BUFFER); -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &pvDispClassInfo, -+ psSwapDispClassBufferIN->hDeviceKM, -+ PVRSRV_HANDLE_TYPE_DISP_INFO); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = -+ PVRSRVLookupSubHandle(psPerProc->psHandleBase, -+ &pvSwapChainBuf, -+ psSwapDispClassBufferIN->hBuffer, -+ PVRSRV_HANDLE_TYPE_DISP_BUFFER, -+ psSwapDispClassBufferIN->hDeviceKM); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ -+ psRetOUT->eError = -+ PVRSRVSwapToDCBufferKM(pvDispClassInfo, -+ pvSwapChainBuf, -+ psSwapDispClassBufferIN->ui32SwapInterval, -+ psSwapDispClassBufferIN->hPrivateTag, -+ psSwapDispClassBufferIN->ui32ClipRectCount, -+ psSwapDispClassBufferIN->sClipRect); -+ -+ return 0; -+} -+ -+static IMG_INT -+PVRSRVSwapToDCBuffer2BW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_BUFFER2 *psSwapDispClassBufferIN, -+ PVRSRV_BRIDGE_OUT_SWAP_DISPCLASS_TO_BUFFER2 *psSwapDispClassBufferOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_VOID *pvPrivData = IMG_NULL; -+ IMG_HANDLE hFence = IMG_NULL; -+ IMG_VOID *pvDispClassInfo; -+ IMG_VOID *pvSwapChain; -+ IMG_UINT32 i; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_BUFFER2); -+ -+ psSwapDispClassBufferOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &pvDispClassInfo, -+ psSwapDispClassBufferIN->hDeviceKM, -+ PVRSRV_HANDLE_TYPE_DISP_INFO); -+ if(psSwapDispClassBufferOUT->eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSwapToDCBuffer2BW: Failed to look up DISP_INFO handle")); -+ return 0; -+ } -+ -+ psSwapDispClassBufferOUT->eError = -+ PVRSRVLookupSubHandle(psPerProc->psHandleBase, -+ &pvSwapChain, -+ psSwapDispClassBufferIN->hSwapChain, -+ PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN, -+ psSwapDispClassBufferIN->hDeviceKM); -+ if(psSwapDispClassBufferOUT->eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSwapToDCBuffer2BW: Failed to look up DISP_BUFFER handle")); -+ return 0; -+ } -+ -+ if(!OSAccessOK(PVR_VERIFY_WRITE, -+ psSwapDispClassBufferIN->ppsKernelMemInfos, -+ sizeof(IMG_HANDLE) * psSwapDispClassBufferIN->ui32NumMemInfos)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSwapToDCBuffer2BW: Access check failed for ppsKernelMemInfos")); -+ return -EFAULT; -+ } -+ -+ if(!OSAccessOK(PVR_VERIFY_WRITE, -+ psSwapDispClassBufferIN->ppsKernelSyncInfos, -+ sizeof(IMG_HANDLE) * psSwapDispClassBufferIN->ui32NumMemInfos)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSwapToDCBuffer2BW: Access check failed for ppsKernelSyncInfos")); -+ return -EFAULT; -+ } -+ -+ for (i = 0; i < psSwapDispClassBufferIN->ui32NumMemInfos; i++) -+ { -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; -+ -+ psSwapDispClassBufferOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ (IMG_PVOID *)&psKernelMemInfo, -+ psSwapDispClassBufferIN->ppsKernelMemInfos[i], -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if(psSwapDispClassBufferOUT->eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSwapToDCBuffer2BW: Failed to look up MEM_INFO handle")); -+ return 0; -+ } -+ psSwapDispClassBufferIN->ppsKernelMemInfos[i] = psKernelMemInfo; -+ -+#if !defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) -+ { -+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo; -+ -+ psSwapDispClassBufferOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ (IMG_PVOID *)&psKernelSyncInfo, -+ psSwapDispClassBufferIN->ppsKernelSyncInfos[i], -+ PVRSRV_HANDLE_TYPE_SYNC_INFO); -+ if(psSwapDispClassBufferOUT->eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSwapToDCBuffer2BW: Failed to look up SYNC_INFO handle")); -+ return 0; -+ } -+ psSwapDispClassBufferIN->ppsKernelSyncInfos[i] = psKernelSyncInfo; -+ } -+#endif /* !defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) */ -+ } -+ -+ if(psSwapDispClassBufferIN->ui32PrivDataLength > 0) -+ { -+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ psSwapDispClassBufferIN->ui32PrivDataLength, -+ (IMG_VOID **)&pvPrivData, IMG_NULL, -+ "Swap Command Private Data") != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBuffer2BW: Failed to allocate private data space")); -+ return -ENOMEM; -+ } -+ -+ if(CopyFromUserWrapper(psPerProc, -+ ui32BridgeID, -+ pvPrivData, -+ psSwapDispClassBufferIN->pvPrivData, -+ psSwapDispClassBufferIN->ui32PrivDataLength) != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSwapToDCBuffer2BW: Failed to copy private data")); -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, -+ psSwapDispClassBufferIN->ui32PrivDataLength, -+ pvPrivData, IMG_NULL); -+ return -EFAULT; -+ } -+ } -+ -+ psSwapDispClassBufferOUT->eError = -+ PVRSRVSwapToDCBuffer2KM(pvDispClassInfo, -+ pvSwapChain, -+ psSwapDispClassBufferIN->ui32SwapInterval, -+ psSwapDispClassBufferIN->ppsKernelMemInfos, -+ psSwapDispClassBufferIN->ppsKernelSyncInfos, -+ psSwapDispClassBufferIN->ui32NumMemInfos, -+ pvPrivData, -+ psSwapDispClassBufferIN->ui32PrivDataLength, -+ &hFence); -+ -+ if(psSwapDispClassBufferOUT->eError != PVRSRV_OK) -+ { -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, -+ psSwapDispClassBufferIN->ui32PrivDataLength, -+ pvPrivData, IMG_NULL); -+ } -+ -+#if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) -+ if(hFence) -+ { -+ struct sync_fence *psFence = hFence; -+ int fd = get_unused_fd(); -+ -+ sync_fence_install(psFence, fd); -+ psSwapDispClassBufferOUT->hFence = (IMG_HANDLE)fd; -+ } -+ else -+#endif /* defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) */ -+ { -+ psSwapDispClassBufferOUT->hFence = (IMG_HANDLE)-1; -+ } -+ -+ return 0; -+} -+ -+ -+ -+static IMG_INT -+PVRSRVSwapToDCSystemBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_SYSTEM *psSwapDispClassSystemIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_VOID *pvDispClassInfo; -+ IMG_VOID *pvSwapChain; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_SYSTEM); -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &pvDispClassInfo, -+ psSwapDispClassSystemIN->hDeviceKM, -+ PVRSRV_HANDLE_TYPE_DISP_INFO); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = -+ PVRSRVLookupSubHandle(psPerProc->psHandleBase, -+ &pvSwapChain, -+ psSwapDispClassSystemIN->hSwapChain, -+ PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN, -+ psSwapDispClassSystemIN->hDeviceKM); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ psRetOUT->eError = -+ PVRSRVSwapToDCSystemKM(pvDispClassInfo, -+ pvSwapChain); -+ -+ return 0; -+} -+ -+static IMG_INT -+PVRSRVOpenBCDeviceBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_OPEN_BUFFERCLASS_DEVICE *psOpenBufferClassDeviceIN, -+ PVRSRV_BRIDGE_OUT_OPEN_BUFFERCLASS_DEVICE *psOpenBufferClassDeviceOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_HANDLE hDevCookieInt; -+ IMG_HANDLE hBufClassInfo; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_OPEN_BUFFERCLASS_DEVICE); -+ -+ NEW_HANDLE_BATCH_OR_ERROR(psOpenBufferClassDeviceOUT->eError, psPerProc, 1) -+ -+ psOpenBufferClassDeviceOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDevCookieInt, -+ psOpenBufferClassDeviceIN->hDevCookie, -+ PVRSRV_HANDLE_TYPE_DEV_NODE); -+ if(psOpenBufferClassDeviceOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psOpenBufferClassDeviceOUT->eError = -+ PVRSRVOpenBCDeviceKM(psPerProc, -+ psOpenBufferClassDeviceIN->ui32DeviceID, -+ hDevCookieInt, -+ &hBufClassInfo); -+ if(psOpenBufferClassDeviceOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ PVRSRVAllocHandleNR(psPerProc->psHandleBase, -+ &psOpenBufferClassDeviceOUT->hDeviceKM, -+ hBufClassInfo, -+ PVRSRV_HANDLE_TYPE_BUF_INFO, -+ PVRSRV_HANDLE_ALLOC_FLAG_NONE); -+ -+ COMMIT_HANDLE_BATCH_OR_ERROR(psOpenBufferClassDeviceOUT->eError, psPerProc) -+ -+ return 0; -+} -+ -+static IMG_INT -+PVRSRVCloseBCDeviceBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_CLOSE_BUFFERCLASS_DEVICE *psCloseBufferClassDeviceIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_VOID *pvBufClassInfo; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CLOSE_BUFFERCLASS_DEVICE); -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &pvBufClassInfo, -+ psCloseBufferClassDeviceIN->hDeviceKM, -+ PVRSRV_HANDLE_TYPE_BUF_INFO); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = -+ PVRSRVCloseBCDeviceKM(pvBufClassInfo); -+ -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = PVRSRVReleaseHandle(psPerProc->psHandleBase, -+ psCloseBufferClassDeviceIN->hDeviceKM, -+ PVRSRV_HANDLE_TYPE_BUF_INFO); -+ -+ return 0; -+} -+ -+static IMG_INT -+PVRSRVGetBCInfoBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_GET_BUFFERCLASS_INFO *psGetBufferClassInfoIN, -+ PVRSRV_BRIDGE_OUT_GET_BUFFERCLASS_INFO *psGetBufferClassInfoOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_VOID *pvBufClassInfo; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_BUFFERCLASS_INFO); -+ -+ psGetBufferClassInfoOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &pvBufClassInfo, -+ psGetBufferClassInfoIN->hDeviceKM, -+ PVRSRV_HANDLE_TYPE_BUF_INFO); -+ if(psGetBufferClassInfoOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psGetBufferClassInfoOUT->eError = -+ PVRSRVGetBCInfoKM(pvBufClassInfo, -+ &psGetBufferClassInfoOUT->sBufferInfo); -+ return 0; -+} -+ -+static IMG_INT -+PVRSRVGetBCBufferBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_GET_BUFFERCLASS_BUFFER *psGetBufferClassBufferIN, -+ PVRSRV_BRIDGE_OUT_GET_BUFFERCLASS_BUFFER *psGetBufferClassBufferOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_VOID *pvBufClassInfo; -+ IMG_HANDLE hBufferInt; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_BUFFERCLASS_BUFFER); -+ -+ NEW_HANDLE_BATCH_OR_ERROR(psGetBufferClassBufferOUT->eError, psPerProc, 1) -+ -+ psGetBufferClassBufferOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &pvBufClassInfo, -+ psGetBufferClassBufferIN->hDeviceKM, -+ PVRSRV_HANDLE_TYPE_BUF_INFO); -+ if(psGetBufferClassBufferOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psGetBufferClassBufferOUT->eError = -+ PVRSRVGetBCBufferKM(pvBufClassInfo, -+ psGetBufferClassBufferIN->ui32BufferIndex, -+ &hBufferInt); -+ -+ if(psGetBufferClassBufferOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ /* PRQA S 1461 6 */ /* ignore warning about enum type being converted */ -+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, -+ &psGetBufferClassBufferOUT->hBuffer, -+ hBufferInt, -+ PVRSRV_HANDLE_TYPE_BUF_BUFFER, -+ (PVRSRV_HANDLE_ALLOC_FLAG)(PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE | PVRSRV_HANDLE_ALLOC_FLAG_SHARED), -+ psGetBufferClassBufferIN->hDeviceKM); -+ -+ COMMIT_HANDLE_BATCH_OR_ERROR(psGetBufferClassBufferOUT->eError, psPerProc) -+ -+ return 0; -+} -+ -+ -+static IMG_INT -+PVRSRVAllocSharedSysMemoryBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_ALLOC_SHARED_SYS_MEM *psAllocSharedSysMemIN, -+ PVRSRV_BRIDGE_OUT_ALLOC_SHARED_SYS_MEM *psAllocSharedSysMemOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ALLOC_SHARED_SYS_MEM); -+ -+ NEW_HANDLE_BATCH_OR_ERROR(psAllocSharedSysMemOUT->eError, psPerProc, 1) -+ -+ psAllocSharedSysMemOUT->eError = -+ PVRSRVAllocSharedSysMemoryKM(psPerProc, -+ psAllocSharedSysMemIN->ui32Flags, -+ psAllocSharedSysMemIN->uSize, -+ &psKernelMemInfo); -+ if(psAllocSharedSysMemOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ OSMemSet(&psAllocSharedSysMemOUT->sClientMemInfo, -+ 0, -+ sizeof(psAllocSharedSysMemOUT->sClientMemInfo)); -+ -+ psAllocSharedSysMemOUT->sClientMemInfo.pvLinAddrKM = -+ psKernelMemInfo->pvLinAddrKM; -+ -+ psAllocSharedSysMemOUT->sClientMemInfo.pvLinAddr = 0; -+ psAllocSharedSysMemOUT->sClientMemInfo.ui32Flags = -+ psKernelMemInfo->ui32Flags; -+ psAllocSharedSysMemOUT->sClientMemInfo.uAllocSize = -+ psKernelMemInfo->uAllocSize; -+ psAllocSharedSysMemOUT->sClientMemInfo.hMappingInfo = psKernelMemInfo->sMemBlk.hOSMemHandle; -+ -+ PVRSRVAllocHandleNR(psPerProc->psHandleBase, -+ &psAllocSharedSysMemOUT->sClientMemInfo.hKernelMemInfo, -+ psKernelMemInfo, -+ PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO, -+ PVRSRV_HANDLE_ALLOC_FLAG_NONE); -+ -+ COMMIT_HANDLE_BATCH_OR_ERROR(psAllocSharedSysMemOUT->eError, psPerProc) -+ -+ return 0; -+} -+ -+static IMG_INT -+PVRSRVFreeSharedSysMemoryBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_FREE_SHARED_SYS_MEM *psFreeSharedSysMemIN, -+ PVRSRV_BRIDGE_OUT_FREE_SHARED_SYS_MEM *psFreeSharedSysMemOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_FREE_SHARED_SYS_MEM); -+ -+ psFreeSharedSysMemOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ (IMG_VOID **)&psKernelMemInfo, -+ psFreeSharedSysMemIN->psKernelMemInfo, -+ PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO); -+ -+ if(psFreeSharedSysMemOUT->eError != PVRSRV_OK) -+ return 0; -+ -+ psFreeSharedSysMemOUT->eError = -+ PVRSRVFreeSharedSysMemoryKM(psKernelMemInfo); -+ if(psFreeSharedSysMemOUT->eError != PVRSRV_OK) -+ return 0; -+ -+ psFreeSharedSysMemOUT->eError = -+ PVRSRVReleaseHandle(psPerProc->psHandleBase, -+ psFreeSharedSysMemIN->psKernelMemInfo, -+ PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO); -+ return 0; -+} -+ -+static IMG_INT -+PVRSRVMapMemInfoMemBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_MAP_MEMINFO_MEM *psMapMemInfoMemIN, -+ PVRSRV_BRIDGE_OUT_MAP_MEMINFO_MEM *psMapMemInfoMemOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; -+ PVRSRV_HANDLE_TYPE eHandleType; -+ IMG_HANDLE hParent; -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MAP_MEMINFO_MEM); -+ -+ NEW_HANDLE_BATCH_OR_ERROR(psMapMemInfoMemOUT->eError, psPerProc, 2) -+ -+ psMapMemInfoMemOUT->eError = -+ PVRSRVLookupHandleAnyType(psPerProc->psHandleBase, -+ (IMG_VOID **)&psKernelMemInfo, -+ &eHandleType, -+ psMapMemInfoMemIN->hKernelMemInfo); -+ if(psMapMemInfoMemOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ switch (eHandleType) -+ { -+#if defined(PVR_SECURE_HANDLES) -+ case PVRSRV_HANDLE_TYPE_MEM_INFO: -+ case PVRSRV_HANDLE_TYPE_MEM_INFO_REF: -+ case PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO: -+#else -+ case PVRSRV_HANDLE_TYPE_NONE: -+#endif -+ break; -+ default: -+ psMapMemInfoMemOUT->eError = PVRSRV_ERROR_INVALID_HANDLE_TYPE; -+ return 0; -+ } -+ -+ /* -+ * To prevent the building up of deep chains of subhandles, parent -+ * the new meminfo off the parent of the input meminfo, if it has -+ * a parent. -+ */ -+ psMapMemInfoMemOUT->eError = -+ PVRSRVGetParentHandle(psPerProc->psHandleBase, -+ &hParent, -+ psMapMemInfoMemIN->hKernelMemInfo, -+ eHandleType); -+ if (psMapMemInfoMemOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ if (hParent == IMG_NULL) -+ { -+ hParent = psMapMemInfoMemIN->hKernelMemInfo; -+ } -+ -+ OSMemSet(&psMapMemInfoMemOUT->sClientMemInfo, -+ 0, -+ sizeof(psMapMemInfoMemOUT->sClientMemInfo)); -+ -+ psMapMemInfoMemOUT->sClientMemInfo.pvLinAddrKM = -+ psKernelMemInfo->pvLinAddrKM; -+ -+ psMapMemInfoMemOUT->sClientMemInfo.pvLinAddr = 0; -+ psMapMemInfoMemOUT->sClientMemInfo.sDevVAddr = -+ psKernelMemInfo->sDevVAddr; -+ psMapMemInfoMemOUT->sClientMemInfo.ui32Flags = -+ psKernelMemInfo->ui32Flags; -+ psMapMemInfoMemOUT->sClientMemInfo.uAllocSize = -+ psKernelMemInfo->uAllocSize; -+ psMapMemInfoMemOUT->sClientMemInfo.hMappingInfo = psKernelMemInfo->sMemBlk.hOSMemHandle; -+ -+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, -+ &psMapMemInfoMemOUT->sClientMemInfo.hKernelMemInfo, -+ psKernelMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO_REF, -+ PVRSRV_HANDLE_ALLOC_FLAG_MULTI, -+ hParent); -+ -+ if(psKernelMemInfo->ui32Flags & PVRSRV_MEM_NO_SYNCOBJ) -+ { -+ /* signal no syncinfo */ -+ OSMemSet(&psMapMemInfoMemOUT->sClientSyncInfo, -+ 0, -+ sizeof (PVRSRV_CLIENT_SYNC_INFO)); -+ } -+ else -+ { -+ /* and setup the sync info */ -+#if !defined(PVRSRV_DISABLE_UM_SYNCOBJ_MAPPINGS) -+ psMapMemInfoMemOUT->sClientSyncInfo.psSyncData = -+ psKernelMemInfo->psKernelSyncInfo->psSyncData; -+ psMapMemInfoMemOUT->sClientSyncInfo.sWriteOpsCompleteDevVAddr = -+ psKernelMemInfo->psKernelSyncInfo->sWriteOpsCompleteDevVAddr; -+ psMapMemInfoMemOUT->sClientSyncInfo.sReadOpsCompleteDevVAddr = -+ psKernelMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr; -+ psMapMemInfoMemOUT->sClientSyncInfo.sReadOps2CompleteDevVAddr = -+ psKernelMemInfo->psKernelSyncInfo->sReadOps2CompleteDevVAddr; -+ -+ psMapMemInfoMemOUT->sClientSyncInfo.hMappingInfo = -+ psKernelMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle; -+#endif -+ -+ psMapMemInfoMemOUT->sClientMemInfo.psClientSyncInfo = &psMapMemInfoMemOUT->sClientSyncInfo; -+ -+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, -+ &psMapMemInfoMemOUT->sClientSyncInfo.hKernelSyncInfo, -+ psKernelMemInfo->psKernelSyncInfo, -+ PVRSRV_HANDLE_TYPE_SYNC_INFO, -+ PVRSRV_HANDLE_ALLOC_FLAG_MULTI, -+ psMapMemInfoMemOUT->sClientMemInfo.hKernelMemInfo); -+ } -+ -+ COMMIT_HANDLE_BATCH_OR_ERROR(psMapMemInfoMemOUT->eError, psPerProc) -+ -+ return 0; -+} -+ -+ -+ -+IMG_INT -+DummyBW(IMG_UINT32 ui32BridgeID, -+ IMG_VOID *psBridgeIn, -+ IMG_VOID *psBridgeOut, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+#if !defined(DEBUG) -+ PVR_UNREFERENCED_PARAMETER(ui32BridgeID); -+#endif -+ PVR_UNREFERENCED_PARAMETER(psBridgeIn); -+ PVR_UNREFERENCED_PARAMETER(psBridgeOut); -+ PVR_UNREFERENCED_PARAMETER(psPerProc); -+ -+#if defined(DEBUG_BRIDGE_KM) -+ PVR_DPF((PVR_DBG_ERROR, "%s: BRIDGE ERROR: BridgeID %u (%s) mapped to " -+ "Dummy Wrapper (probably not what you want!)", -+ __FUNCTION__, ui32BridgeID, g_BridgeDispatchTable[ui32BridgeID].pszIOCName)); -+#else -+ PVR_DPF((PVR_DBG_ERROR, "%s: BRIDGE ERROR: BridgeID %u mapped to " -+ "Dummy Wrapper (probably not what you want!)", -+ __FUNCTION__, ui32BridgeID)); -+#endif -+ return -ENOTTY; -+} -+ -+ -+/*! -+ * ***************************************************************************** -+ * @brief A wrapper for filling in the g_BridgeDispatchTable array that does -+ * error checking. -+ * -+ * @param ui32Index -+ * @param pszIOCName -+ * @param pfFunction -+ * @param pszFunctionName -+ * -+ * @return -+ ********************************************************************************/ -+IMG_VOID -+_SetDispatchTableEntry(IMG_UINT32 ui32Index, -+ const IMG_CHAR *pszIOCName, -+ BridgeWrapperFunction pfFunction, -+ const IMG_CHAR *pszFunctionName) -+{ -+ static IMG_UINT uiPrevIndex = ~0U; /* -1 */ -+#if !defined(DEBUG) -+ PVR_UNREFERENCED_PARAMETER(pszIOCName); -+#endif -+#if !defined(DEBUG_BRIDGE_KM_DISPATCH_TABLE) && !defined(DEBUG_BRIDGE_KM) -+ PVR_UNREFERENCED_PARAMETER(pszFunctionName); -+#endif -+ -+#if defined(DEBUG_BRIDGE_KM_DISPATCH_TABLE) -+ /* INTEGRATION_POINT: Enable this to dump out the dispatch table entries */ -+ PVR_DPF((PVR_DBG_WARNING, "%s: %d %s %s", __FUNCTION__, ui32Index, pszIOCName, pszFunctionName)); -+#endif -+ -+ /* We should never be over-writing a previous entry. -+ * If we are, tell the world about it. -+ * NOTE: This shouldn't be debug only since switching from debug->release -+ * etc is likly to modify the available ioctls and thus be a point where -+ * mistakes are exposed. This isn't run at at a performance critical time. -+ */ -+ if(g_BridgeDispatchTable[ui32Index].pfFunction) -+ { -+#if defined(DEBUG_BRIDGE_KM) -+ PVR_DPF((PVR_DBG_ERROR, -+ "%s: BUG!: Adding dispatch table entry for %s clobbers an existing entry for %s", -+ __FUNCTION__, pszIOCName, g_BridgeDispatchTable[ui32Index].pszIOCName)); -+#else -+ PVR_DPF((PVR_DBG_ERROR, -+ "%s: BUG!: Adding dispatch table entry for %s clobbers an existing entry (index=%u)", -+ __FUNCTION__, pszIOCName, ui32Index)); -+#endif -+ PVR_DPF((PVR_DBG_ERROR, "NOTE: Enabling DEBUG_BRIDGE_KM_DISPATCH_TABLE may help debug this issue.")); -+ } -+ -+ /* Any gaps are sub-optimal in-terms of memory usage, but we are mainly -+ * interested in spotting any large gap of wasted memory that could be -+ * accidentally introduced. -+ * -+ * This will currently flag up any gaps > 5 entries. -+ * -+ * NOTE: This shouldn't be debug only since switching from debug->release -+ * etc is likly to modify the available ioctls and thus be a point where -+ * mistakes are exposed. This isn't run at at a performance critical time. -+ */ -+// if((uiPrevIndex != (IMG_UINT)-1) && -+ if((uiPrevIndex != ~0U) && -+ ((ui32Index >= uiPrevIndex + DISPATCH_TABLE_GAP_THRESHOLD) || -+ (ui32Index <= uiPrevIndex))) -+ { -+#if defined(DEBUG_BRIDGE_KM) -+ PVR_DPF((PVR_DBG_WARNING, -+ "%s: There is a gap in the dispatch table between indices %u (%s) and %u (%s)", -+ __FUNCTION__, uiPrevIndex, g_BridgeDispatchTable[uiPrevIndex].pszIOCName, -+ ui32Index, pszIOCName)); -+#else -+ PVR_DPF((PVR_DBG_WARNING, -+ "%s: There is a gap in the dispatch table between indices %u and %u (%s)", -+ __FUNCTION__, (IMG_UINT)uiPrevIndex, (IMG_UINT)ui32Index, pszIOCName)); -+#endif -+ PVR_DPF((PVR_DBG_ERROR, "NOTE: Enabling DEBUG_BRIDGE_KM_DISPATCH_TABLE may help debug this issue.")); -+ } -+ -+ g_BridgeDispatchTable[ui32Index].pfFunction = pfFunction; -+#if defined(DEBUG_BRIDGE_KM) -+ g_BridgeDispatchTable[ui32Index].pszIOCName = pszIOCName; -+ g_BridgeDispatchTable[ui32Index].pszFunctionName = pszFunctionName; -+ g_BridgeDispatchTable[ui32Index].ui32CallCount = 0; -+ g_BridgeDispatchTable[ui32Index].ui32CopyFromUserTotalBytes = 0; -+#endif -+ -+ uiPrevIndex = ui32Index; -+} -+ -+static IMG_INT -+PVRSRVInitSrvConnectBW(IMG_UINT32 ui32BridgeID, -+ IMG_VOID *psBridgeIn, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ PVR_UNREFERENCED_PARAMETER(psBridgeIn); -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_INITSRV_CONNECT); -+ PVR_UNREFERENCED_PARAMETER(psBridgeIn); -+ -+ /* PRQA S 3415 1 */ /* side effects needed - if any step fails */ -+ if((OSProcHasPrivSrvInit() == IMG_FALSE) || PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RUNNING) || PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RAN)) -+ { -+ psRetOUT->eError = PVRSRV_ERROR_SRV_CONNECT_FAILED; -+ return 0; -+ } -+ -+#if defined (__linux__) || defined (__QNXNTO__) -+ PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_RUNNING, IMG_TRUE); -+#endif -+ psPerProc->bInitProcess = IMG_TRUE; -+ -+ psRetOUT->eError = PVRSRV_OK; -+ -+ return 0; -+} -+ -+ -+static IMG_INT -+PVRSRVInitSrvDisconnectBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_INITSRV_DISCONNECT *psInitSrvDisconnectIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_INITSRV_DISCONNECT); -+ -+ if(!psPerProc->bInitProcess) -+ { -+ psRetOUT->eError = PVRSRV_ERROR_SRV_DISCONNECT_FAILED; -+ return 0; -+ } -+ -+ psPerProc->bInitProcess = IMG_FALSE; -+ -+#if defined(SUPPORT_PDUMP_MULTI_PROCESS) -+ psPerProc->bPDumpActive = IMG_FALSE; -+#endif -+ -+ PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_RUNNING, IMG_FALSE); -+ PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_RAN, IMG_TRUE); -+ -+ psRetOUT->eError = PVRSRVFinaliseSystem(psInitSrvDisconnectIN->bInitSuccesful); -+ -+ PVRSRVSetInitServerState( PVRSRV_INIT_SERVER_SUCCESSFUL , -+ ((psRetOUT->eError == PVRSRV_OK) && (psInitSrvDisconnectIN->bInitSuccesful)) -+ ? IMG_TRUE : IMG_FALSE); -+ -+ return 0; -+} -+ -+ -+static IMG_INT -+PVRSRVEventObjectWaitBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_EVENT_OBJECT_WAIT *psEventObjectWaitIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_HANDLE hOSEventKM; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_EVENT_OBJECT_WAIT); -+ -+ psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hOSEventKM, -+ psEventObjectWaitIN->hOSEventKM, -+ PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT); -+ -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = OSEventObjectWaitKM(hOSEventKM); -+ -+ return 0; -+} -+ -+ -+static IMG_INT -+PVRSRVEventObjectOpenBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_EVENT_OBJECT_OPEN *psEventObjectOpenIN, -+ PVRSRV_BRIDGE_OUT_EVENT_OBJECT_OPEN *psEventObjectOpenOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_EVENT_OBJECT_OPEN); -+ -+ NEW_HANDLE_BATCH_OR_ERROR(psEventObjectOpenOUT->eError, psPerProc, 1) -+ -+ psEventObjectOpenOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &psEventObjectOpenIN->sEventObject.hOSEventKM, -+ psEventObjectOpenIN->sEventObject.hOSEventKM, -+ PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT); -+ -+ if(psEventObjectOpenOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psEventObjectOpenOUT->eError = OSEventObjectOpenKM(&psEventObjectOpenIN->sEventObject, &psEventObjectOpenOUT->hOSEvent); -+ -+ if(psEventObjectOpenOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ PVRSRVAllocHandleNR(psPerProc->psHandleBase, -+ &psEventObjectOpenOUT->hOSEvent, -+ psEventObjectOpenOUT->hOSEvent, -+ PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT, -+ PVRSRV_HANDLE_ALLOC_FLAG_MULTI); -+ -+ COMMIT_HANDLE_BATCH_OR_ERROR(psEventObjectOpenOUT->eError, psPerProc) -+ -+ return 0; -+} -+ -+ -+static IMG_INT -+PVRSRVEventObjectCloseBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_EVENT_OBJECT_CLOSE *psEventObjectCloseIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_HANDLE hOSEventKM; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_EVENT_OBJECT_CLOSE); -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &psEventObjectCloseIN->sEventObject.hOSEventKM, -+ psEventObjectCloseIN->sEventObject.hOSEventKM, -+ PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, -+ &hOSEventKM, -+ psEventObjectCloseIN->hOSEventKM, -+ PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT); -+ -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = OSEventObjectCloseKM(&psEventObjectCloseIN->sEventObject, hOSEventKM); -+ -+ return 0; -+} -+ -+ -+typedef struct _MODIFY_SYNC_OP_INFO -+{ -+ IMG_HANDLE hResItem; -+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo; -+ IMG_UINT32 ui32ModifyFlags; -+ IMG_UINT32 ui32ReadOpsPendingSnapShot; -+ IMG_UINT32 ui32WriteOpsPendingSnapShot; -+ IMG_UINT32 ui32ReadOps2PendingSnapShot; -+} MODIFY_SYNC_OP_INFO; -+ -+ -+static PVRSRV_ERROR DoQuerySyncOpsSatisfied(PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo, -+ IMG_UINT32 ui32ReadOpsPendingSnapShot, -+ IMG_UINT32 ui32WriteOpsPendingSnapShot, -+ IMG_UINT32 ui32ReadOps2PendingSnapShot) -+{ -+ IMG_UINT32 ui32WriteOpsPending; -+ IMG_UINT32 ui32ReadOpsPending; -+ IMG_UINT32 ui32ReadOps2Pending; -+ -+ /* -+ * -+ * We wait until the complete count reaches _or_moves_past_ the -+ * snapshot value. -+ * -+ */ -+ -+ if (!psKernelSyncInfo) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ /* -+ let p be the pending ops count -+ let c be the complete ops count -+ let p' be the previously taken snapshot -+ -+ if p exceeds c by an amount greater than that by which -+ p exceeds p', then the condition is not yet satisfied. -+ -+ Note that (p - c) can never be negative, and neither can (p - p') -+ so we can do the comparison using unsigned arithmetic -+ */ -+ ui32WriteOpsPending = psKernelSyncInfo->psSyncData->ui32WriteOpsPending; -+ ui32ReadOpsPending = psKernelSyncInfo->psSyncData->ui32ReadOpsPending; -+ ui32ReadOps2Pending = psKernelSyncInfo->psSyncData->ui32ReadOps2Pending; -+ -+ if((ui32WriteOpsPending - ui32WriteOpsPendingSnapShot >= -+ ui32WriteOpsPending - psKernelSyncInfo->psSyncData->ui32WriteOpsComplete) && -+ (ui32ReadOpsPending - ui32ReadOpsPendingSnapShot >= -+ ui32ReadOpsPending - psKernelSyncInfo->psSyncData->ui32ReadOpsComplete) && -+ (ui32ReadOps2Pending - ui32ReadOps2PendingSnapShot >= -+ ui32ReadOps2Pending - psKernelSyncInfo->psSyncData->ui32ReadOps2Complete)) -+ { -+#if defined(PDUMP) && !defined(SUPPORT_VGX) -+ /* pdump the sync pol: reads */ -+ PDumpComment("Poll for read ops complete to reach value (pdump: %u, actual snapshot: %u)", -+ psKernelSyncInfo->psSyncData->ui32LastReadOpDumpVal, -+ ui32ReadOpsPendingSnapShot); -+ PDumpMemPolKM(psKernelSyncInfo->psSyncDataMemInfoKM, -+ offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete), -+ psKernelSyncInfo->psSyncData->ui32LastReadOpDumpVal, -+ 0xFFFFFFFF, -+ PDUMP_POLL_OPERATOR_EQUAL, /* * see "NB" below */ -+ 0, -+ MAKEUNIQUETAG(psKernelSyncInfo->psSyncDataMemInfoKM)); -+ -+ /* pdump the sync pol: writes */ -+ PDumpComment("Poll for write ops complete to reach value (pdump: %u, actual snapshot: %u)", -+ psKernelSyncInfo->psSyncData->ui32LastOpDumpVal, -+ ui32WriteOpsPendingSnapShot); -+ PDumpMemPolKM(psKernelSyncInfo->psSyncDataMemInfoKM, -+ offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete), -+ psKernelSyncInfo->psSyncData->ui32LastOpDumpVal, -+ 0xFFFFFFFF, -+ PDUMP_POLL_OPERATOR_EQUAL, /* * see "NB" below */ -+ 0, -+ MAKEUNIQUETAG(psKernelSyncInfo->psSyncDataMemInfoKM)); -+ /* NB: FIXME -- really need to POL on an expression to -+ accurately reflect the condition we need to check. How to -+ do this in PDUMP? */ -+#endif -+ return PVRSRV_OK; -+ } -+ else -+ { -+ return PVRSRV_ERROR_RETRY; -+ } -+} -+ -+ -+static PVRSRV_ERROR DoModifyCompleteSyncOps(MODIFY_SYNC_OP_INFO *psModSyncOpInfo) -+{ -+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo; -+ -+ psKernelSyncInfo = psModSyncOpInfo->psKernelSyncInfo; -+ -+ if (!psKernelSyncInfo) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ /* If user has used the API correctly, we will always have reached the pending snapshot. -+ We should catch this error on the client side of the bridge and report it in an obvious way */ -+ if((psModSyncOpInfo->ui32WriteOpsPendingSnapShot != psKernelSyncInfo->psSyncData->ui32WriteOpsComplete) -+ || (psModSyncOpInfo->ui32ReadOpsPendingSnapShot != psKernelSyncInfo->psSyncData->ui32ReadOpsComplete)) -+ { -+ return PVRSRV_ERROR_BAD_SYNC_STATE; -+ } -+ -+ /* update the WOpComplete */ -+ if(psModSyncOpInfo->ui32ModifyFlags & PVRSRV_MODIFYSYNCOPS_FLAGS_WO_INC) -+ { -+ psKernelSyncInfo->psSyncData->ui32WriteOpsComplete++; -+ } -+ -+ /* update the ROpComplete */ -+ if(psModSyncOpInfo->ui32ModifyFlags & PVRSRV_MODIFYSYNCOPS_FLAGS_RO_INC) -+ { -+ psKernelSyncInfo->psSyncData->ui32ReadOpsComplete++; -+ } -+ -+ return PVRSRV_OK; -+} -+ -+ -+static PVRSRV_ERROR ModifyCompleteSyncOpsCallBack(IMG_PVOID pvParam, -+ IMG_UINT32 ui32Param, -+ IMG_BOOL bDummy) -+{ -+ MODIFY_SYNC_OP_INFO *psModSyncOpInfo; -+ -+ PVR_UNREFERENCED_PARAMETER(ui32Param); -+ PVR_UNREFERENCED_PARAMETER(bDummy); -+ -+ if (!pvParam) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "ModifyCompleteSyncOpsCallBack: invalid parameter")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psModSyncOpInfo = (MODIFY_SYNC_OP_INFO*)pvParam; -+ -+ if (psModSyncOpInfo->psKernelSyncInfo) -+ { -+ LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) -+ { -+ if (DoQuerySyncOpsSatisfied(psModSyncOpInfo->psKernelSyncInfo, -+ psModSyncOpInfo->ui32ReadOpsPendingSnapShot, -+ psModSyncOpInfo->ui32WriteOpsPendingSnapShot, -+ psModSyncOpInfo->ui32ReadOps2PendingSnapShot) == PVRSRV_OK) -+ { -+ goto OpFlushedComplete; -+ } -+ PVR_DPF((PVR_DBG_WARNING, "ModifyCompleteSyncOpsCallBack: waiting for current Ops to flush")); -+ OSSleepms(1); -+ } END_LOOP_UNTIL_TIMEOUT(); -+ -+ PVR_DPF((PVR_DBG_ERROR, "ModifyCompleteSyncOpsCallBack: timeout whilst waiting for current Ops to flush.")); -+ PVR_DPF((PVR_DBG_ERROR, " Write ops pending snapshot = %d, write ops complete = %d", -+ psModSyncOpInfo->ui32WriteOpsPendingSnapShot, -+ psModSyncOpInfo->psKernelSyncInfo->psSyncData->ui32WriteOpsComplete)); -+ PVR_DPF((PVR_DBG_ERROR, " Read ops pending snapshot = %d, read ops complete = %d", -+ psModSyncOpInfo->ui32ReadOpsPendingSnapShot, -+ psModSyncOpInfo->psKernelSyncInfo->psSyncData->ui32ReadOpsComplete)); -+ PVR_DPF((PVR_DBG_ERROR, " Read ops pending snapshot = %d, read ops2 complete = %d", -+ psModSyncOpInfo->ui32ReadOps2PendingSnapShot, -+ psModSyncOpInfo->psKernelSyncInfo->psSyncData->ui32ReadOps2Complete)); -+ return PVRSRV_ERROR_TIMEOUT; -+ -+OpFlushedComplete: -+ DoModifyCompleteSyncOps(psModSyncOpInfo); -+ PVRSRVKernelSyncInfoDecRef(psModSyncOpInfo->psKernelSyncInfo, IMG_NULL); -+ } -+ -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(MODIFY_SYNC_OP_INFO), (IMG_VOID *)psModSyncOpInfo, 0); -+ -+ /* re-kick all services managed devices */ -+ PVRSRVScheduleDeviceCallbacks(); -+ -+ return PVRSRV_OK; -+} -+ -+ -+static IMG_INT -+PVRSRVCreateSyncInfoModObjBW(IMG_UINT32 ui32BridgeID, -+ IMG_VOID *psBridgeIn, -+ PVRSRV_BRIDGE_OUT_CREATE_SYNC_INFO_MOD_OBJ *psCreateSyncInfoModObjOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ MODIFY_SYNC_OP_INFO *psModSyncOpInfo; -+ -+ PVR_UNREFERENCED_PARAMETER(psBridgeIn); -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CREATE_SYNC_INFO_MOD_OBJ); -+ -+ NEW_HANDLE_BATCH_OR_ERROR(psCreateSyncInfoModObjOUT->eError, psPerProc, 1) -+ -+ ASSIGN_AND_EXIT_ON_ERROR(psCreateSyncInfoModObjOUT->eError, -+ OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(MODIFY_SYNC_OP_INFO), -+ (IMG_VOID **)&psModSyncOpInfo, 0, -+ "ModSyncOpInfo (MODIFY_SYNC_OP_INFO)")); -+ -+ psModSyncOpInfo->psKernelSyncInfo = IMG_NULL; /* mark it as empty */ -+ -+ psCreateSyncInfoModObjOUT->eError = PVRSRVAllocHandle(psPerProc->psHandleBase, -+ &psCreateSyncInfoModObjOUT->hKernelSyncInfoModObj, -+ psModSyncOpInfo, -+ PVRSRV_HANDLE_TYPE_SYNC_INFO_MOD_OBJ, -+ PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE); -+ -+ if (psCreateSyncInfoModObjOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psModSyncOpInfo->hResItem = ResManRegisterRes(psPerProc->hResManContext, -+ RESMAN_TYPE_MODIFY_SYNC_OPS, -+ psModSyncOpInfo, -+ 0, -+ &ModifyCompleteSyncOpsCallBack); -+ -+ COMMIT_HANDLE_BATCH_OR_ERROR(psCreateSyncInfoModObjOUT->eError, psPerProc) -+ -+ return 0; -+} -+ -+ -+static IMG_INT -+PVRSRVDestroySyncInfoModObjBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_DESTROY_SYNC_INFO_MOD_OBJ *psDestroySyncInfoModObjIN, -+ PVRSRV_BRIDGE_RETURN *psDestroySyncInfoModObjOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ MODIFY_SYNC_OP_INFO *psModSyncOpInfo; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_DESTROY_SYNC_INFO_MOD_OBJ); -+ -+ psDestroySyncInfoModObjOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ (IMG_VOID**)&psModSyncOpInfo, -+ psDestroySyncInfoModObjIN->hKernelSyncInfoModObj, -+ PVRSRV_HANDLE_TYPE_SYNC_INFO_MOD_OBJ); -+ if (psDestroySyncInfoModObjOUT->eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVDestroySyncInfoModObjBW: PVRSRVLookupHandle failed")); -+ return 0; -+ } -+ -+ if(psModSyncOpInfo->psKernelSyncInfo != IMG_NULL) -+ { -+ /* Not empty */ -+ psDestroySyncInfoModObjOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; -+ return 0; -+ } -+ -+ PVRSRVKernelSyncInfoDecRef(psModSyncOpInfo->psKernelSyncInfo, IMG_NULL); -+ -+ psDestroySyncInfoModObjOUT->eError = PVRSRVReleaseHandle(psPerProc->psHandleBase, -+ psDestroySyncInfoModObjIN->hKernelSyncInfoModObj, -+ PVRSRV_HANDLE_TYPE_SYNC_INFO_MOD_OBJ); -+ -+ if (psDestroySyncInfoModObjOUT->eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVDestroySyncInfoModObjBW: PVRSRVReleaseHandle failed")); -+ return 0; -+ } -+ -+ psDestroySyncInfoModObjOUT->eError = ResManFreeResByPtr(psModSyncOpInfo->hResItem, CLEANUP_WITH_POLL); -+ if (psDestroySyncInfoModObjOUT->eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVDestroySyncInfoModObjBW: ResManFreeResByPtr failed")); -+ return 0; -+ } -+ -+ return 0; -+} -+ -+ -+static IMG_INT -+PVRSRVModifyPendingSyncOpsBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_MODIFY_PENDING_SYNC_OPS *psModifySyncOpsIN, -+ PVRSRV_BRIDGE_OUT_MODIFY_PENDING_SYNC_OPS *psModifySyncOpsOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo; -+ MODIFY_SYNC_OP_INFO *psModSyncOpInfo; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MODIFY_PENDING_SYNC_OPS); -+ -+ psModifySyncOpsOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ (IMG_VOID**)&psModSyncOpInfo, -+ psModifySyncOpsIN->hKernelSyncInfoModObj, -+ PVRSRV_HANDLE_TYPE_SYNC_INFO_MOD_OBJ); -+ if (psModifySyncOpsOUT->eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVModifyPendingSyncOpsBW: PVRSRVLookupHandle failed")); -+ return 0; -+ } -+ -+ psModifySyncOpsOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ (IMG_VOID**)&psKernelSyncInfo, -+ psModifySyncOpsIN->hKernelSyncInfo, -+ PVRSRV_HANDLE_TYPE_SYNC_INFO); -+ if (psModifySyncOpsOUT->eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVModifyPendingSyncOpsBW: PVRSRVLookupHandle failed")); -+ return 0; -+ } -+ -+ if(psModSyncOpInfo->psKernelSyncInfo) -+ { -+ /* SyncInfoModification is not empty */ -+ psModifySyncOpsOUT->eError = PVRSRV_ERROR_RETRY; -+ PVR_DPF((PVR_DBG_VERBOSE, "PVRSRVModifyPendingSyncOpsBW: SyncInfo Modification object is not empty")); -+ return 0; -+ } -+ -+ /* Should never happen, but check to be sure */ -+ if (psKernelSyncInfo == IMG_NULL) -+ { -+ psModifySyncOpsOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; -+ PVR_DPF((PVR_DBG_VERBOSE, "PVRSRVModifyPendingSyncOpsBW: SyncInfo bad handle")); -+ return 0; -+ } -+ -+ PVRSRVKernelSyncInfoIncRef(psKernelSyncInfo, IMG_NULL); -+ /* setup info to store in resman */ -+ psModSyncOpInfo->psKernelSyncInfo = psKernelSyncInfo; -+ psModSyncOpInfo->ui32ModifyFlags = psModifySyncOpsIN->ui32ModifyFlags; -+ psModSyncOpInfo->ui32ReadOpsPendingSnapShot = psKernelSyncInfo->psSyncData->ui32ReadOpsPending; -+ psModSyncOpInfo->ui32WriteOpsPendingSnapShot = psKernelSyncInfo->psSyncData->ui32WriteOpsPending; -+ psModSyncOpInfo->ui32ReadOps2PendingSnapShot = psKernelSyncInfo->psSyncData->ui32ReadOps2Pending; -+ -+ /* We return PRE-INCREMENTED versions of all sync Op Values */ -+ -+ psModifySyncOpsOUT->ui32ReadOpsPending = psKernelSyncInfo->psSyncData->ui32ReadOpsPending; -+ psModifySyncOpsOUT->ui32WriteOpsPending = psKernelSyncInfo->psSyncData->ui32WriteOpsPending; -+ psModifySyncOpsOUT->ui32ReadOps2Pending = psKernelSyncInfo->psSyncData->ui32ReadOps2Pending; -+ -+ if(psModifySyncOpsIN->ui32ModifyFlags & PVRSRV_MODIFYSYNCOPS_FLAGS_WO_INC) -+ { -+ psKernelSyncInfo->psSyncData->ui32WriteOpsPending++; -+ } -+ -+ if(psModifySyncOpsIN->ui32ModifyFlags & PVRSRV_MODIFYSYNCOPS_FLAGS_RO_INC) -+ { -+ psKernelSyncInfo->psSyncData->ui32ReadOpsPending++; -+ } -+ -+ /* pull the resman item to the front of the list */ -+ psModifySyncOpsOUT->eError = ResManDissociateRes(psModSyncOpInfo->hResItem, -+ psPerProc->hResManContext); -+ -+ if (psModifySyncOpsOUT->eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVModifyPendingSyncOpsBW: PVRSRVLookupHandle failed")); -+ return 0; -+ } -+ -+ return 0; -+} -+ -+ -+static IMG_INT -+PVRSRVModifyCompleteSyncOpsBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_MODIFY_COMPLETE_SYNC_OPS *psModifySyncOpsIN, -+ PVRSRV_BRIDGE_RETURN *psModifySyncOpsOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ MODIFY_SYNC_OP_INFO *psModSyncOpInfo; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MODIFY_COMPLETE_SYNC_OPS); -+ -+ psModifySyncOpsOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ (IMG_VOID**)&psModSyncOpInfo, -+ psModifySyncOpsIN->hKernelSyncInfoModObj, -+ PVRSRV_HANDLE_TYPE_SYNC_INFO_MOD_OBJ); -+ if (psModifySyncOpsOUT->eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVModifyCompleteSyncOpsBW: PVRSRVLookupHandle failed")); -+ return 0; -+ } -+ -+ if(psModSyncOpInfo->psKernelSyncInfo == IMG_NULL) -+ { -+ /* Empty */ -+ psModifySyncOpsOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; -+ return 0; -+ } -+ -+ psModifySyncOpsOUT->eError = DoModifyCompleteSyncOps(psModSyncOpInfo); -+ -+ if (psModifySyncOpsOUT->eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVModifyCompleteSyncOpsBW: DoModifyCompleteSyncOps failed")); -+ return 0; -+ } -+ -+ PVRSRVKernelSyncInfoDecRef(psModSyncOpInfo->psKernelSyncInfo, IMG_NULL); -+ psModSyncOpInfo->psKernelSyncInfo = IMG_NULL; -+ -+ /* re-kick all services managed devices */ -+ PVRSRVScheduleDeviceCallbacks(); -+ -+ return 0; -+} -+ -+ -+static IMG_INT -+PVRSRVSyncOpsTakeTokenBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_SYNC_OPS_TAKE_TOKEN *psSyncOpsTakeTokenIN, -+ PVRSRV_BRIDGE_OUT_SYNC_OPS_TAKE_TOKEN *psSyncOpsTakeTokenOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SYNC_OPS_TAKE_TOKEN); -+ -+ psSyncOpsTakeTokenOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ (IMG_VOID**)&psKernelSyncInfo, -+ psSyncOpsTakeTokenIN->hKernelSyncInfo, -+ PVRSRV_HANDLE_TYPE_SYNC_INFO); -+ if (psSyncOpsTakeTokenOUT->eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSyncOpsTakeTokenBW: PVRSRVLookupHandle failed")); -+ return 0; -+ } -+ -+ /* We return PRE-INCREMENTED versions of all sync Op Values */ -+ -+ psSyncOpsTakeTokenOUT->ui32ReadOpsPending = psKernelSyncInfo->psSyncData->ui32ReadOpsPending; -+ psSyncOpsTakeTokenOUT->ui32WriteOpsPending = psKernelSyncInfo->psSyncData->ui32WriteOpsPending; -+ psSyncOpsTakeTokenOUT->ui32ReadOps2Pending = psKernelSyncInfo->psSyncData->ui32ReadOps2Pending; -+ -+ return 0; -+} -+ -+ -+static IMG_INT -+PVRSRVSyncOpsFlushToTokenBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_SYNC_OPS_FLUSH_TO_TOKEN *psSyncOpsFlushToTokenIN, -+ PVRSRV_BRIDGE_RETURN *psSyncOpsFlushToTokenOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo; -+ IMG_UINT32 ui32ReadOpsPendingSnapshot; -+ IMG_UINT32 ui32WriteOpsPendingSnapshot; -+ IMG_UINT32 ui32ReadOps2PendingSnapshot; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SYNC_OPS_FLUSH_TO_TOKEN); -+ -+ psSyncOpsFlushToTokenOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ (IMG_VOID**)&psKernelSyncInfo, -+ psSyncOpsFlushToTokenIN->hKernelSyncInfo, -+ PVRSRV_HANDLE_TYPE_SYNC_INFO); -+ if (psSyncOpsFlushToTokenOUT->eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSyncOpsFlushToTokenBW: PVRSRVLookupHandle failed")); -+ return 0; -+ } -+ -+ ui32ReadOpsPendingSnapshot = psSyncOpsFlushToTokenIN->ui32ReadOpsPendingSnapshot; -+ ui32WriteOpsPendingSnapshot = psSyncOpsFlushToTokenIN->ui32WriteOpsPendingSnapshot; -+ ui32ReadOps2PendingSnapshot = psSyncOpsFlushToTokenIN->ui32ReadOps2PendingSnapshot; -+ -+ psSyncOpsFlushToTokenOUT->eError = DoQuerySyncOpsSatisfied(psKernelSyncInfo, -+ ui32ReadOpsPendingSnapshot, -+ ui32WriteOpsPendingSnapshot, -+ ui32ReadOps2PendingSnapshot); -+ -+ if (psSyncOpsFlushToTokenOUT->eError != PVRSRV_OK && psSyncOpsFlushToTokenOUT->eError != PVRSRV_ERROR_RETRY) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSyncOpsFlushToTokenBW: DoQuerySyncOpsSatisfied failed")); -+ return 0; -+ } -+ -+ return 0; -+} -+ -+ -+static IMG_INT -+PVRSRVSyncOpsFlushToModObjBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_SYNC_OPS_FLUSH_TO_MOD_OBJ *psSyncOpsFlushToModObjIN, -+ PVRSRV_BRIDGE_RETURN *psSyncOpsFlushToModObjOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ MODIFY_SYNC_OP_INFO *psModSyncOpInfo; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SYNC_OPS_FLUSH_TO_MOD_OBJ); -+ -+ psSyncOpsFlushToModObjOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ (IMG_VOID**)&psModSyncOpInfo, -+ psSyncOpsFlushToModObjIN->hKernelSyncInfoModObj, -+ PVRSRV_HANDLE_TYPE_SYNC_INFO_MOD_OBJ); -+ if (psSyncOpsFlushToModObjOUT->eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSyncOpsFlushToModObjBW: PVRSRVLookupHandle failed")); -+ return 0; -+ } -+ -+ if(psModSyncOpInfo->psKernelSyncInfo == IMG_NULL) -+ { -+ /* Empty */ -+ psSyncOpsFlushToModObjOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; -+ return 0; -+ } -+ -+ psSyncOpsFlushToModObjOUT->eError = DoQuerySyncOpsSatisfied(psModSyncOpInfo->psKernelSyncInfo, -+ psModSyncOpInfo->ui32ReadOpsPendingSnapShot, -+ psModSyncOpInfo->ui32WriteOpsPendingSnapShot, -+ psModSyncOpInfo->ui32ReadOps2PendingSnapShot); -+ -+ if (psSyncOpsFlushToModObjOUT->eError != PVRSRV_OK && psSyncOpsFlushToModObjOUT->eError != PVRSRV_ERROR_RETRY) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSyncOpsFlushToModObjBW: DoQuerySyncOpsSatisfied failed")); -+ return 0; -+ } -+ -+ return 0; -+} -+ -+ -+static IMG_INT -+PVRSRVSyncOpsFlushToDeltaBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_SYNC_OPS_FLUSH_TO_DELTA *psSyncOpsFlushToDeltaIN, -+ PVRSRV_BRIDGE_RETURN *psSyncOpsFlushToDeltaOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ PVRSRV_KERNEL_SYNC_INFO *psSyncInfo; -+ IMG_UINT32 ui32DeltaRead; -+ IMG_UINT32 ui32DeltaWrite; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SYNC_OPS_FLUSH_TO_DELTA); -+ -+ psSyncOpsFlushToDeltaOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ (IMG_VOID**)&psSyncInfo, -+ psSyncOpsFlushToDeltaIN->hKernelSyncInfo, -+ PVRSRV_HANDLE_TYPE_SYNC_INFO); -+ if (psSyncOpsFlushToDeltaOUT->eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSyncOpsFlushToDeltaBW: PVRSRVLookupHandle failed")); -+ return 0; -+ } -+ -+ /* FIXME: there's logic here in the bridge-wrapper - this needs to be moved to -+ a better place */ -+ -+ ui32DeltaRead = psSyncInfo->psSyncData->ui32ReadOpsPending - psSyncInfo->psSyncData->ui32ReadOpsComplete; -+ ui32DeltaWrite = psSyncInfo->psSyncData->ui32WriteOpsPending - psSyncInfo->psSyncData->ui32WriteOpsComplete; -+ -+ if (ui32DeltaRead <= psSyncOpsFlushToDeltaIN->ui32Delta && ui32DeltaWrite <= psSyncOpsFlushToDeltaIN->ui32Delta) -+ { -+#if defined(PDUMP) && !defined(SUPPORT_VGX) -+ /* pdump the sync pol: reads */ -+ PDumpComment("Poll for read ops complete to delta (%u)", -+ psSyncOpsFlushToDeltaIN->ui32Delta); -+ psSyncOpsFlushToDeltaOUT->eError = -+ PDumpMemPolKM(psSyncInfo->psSyncDataMemInfoKM, -+ offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete), -+ psSyncInfo->psSyncData->ui32LastReadOpDumpVal, -+ 0xFFFFFFFF, -+ PDUMP_POLL_OPERATOR_GREATEREQUAL, -+ 0, -+ MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM)); -+ -+ /* pdump the sync pol: writes */ -+ PDumpComment("Poll for write ops complete to delta (%u)", -+ psSyncOpsFlushToDeltaIN->ui32Delta); -+ psSyncOpsFlushToDeltaOUT->eError = -+ PDumpMemPolKM(psSyncInfo->psSyncDataMemInfoKM, -+ offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete), -+ psSyncInfo->psSyncData->ui32LastOpDumpVal, -+ 0xFFFFFFFF, -+ PDUMP_POLL_OPERATOR_GREATEREQUAL, -+ 0, -+ MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM)); -+#endif -+ -+ psSyncOpsFlushToDeltaOUT->eError = PVRSRV_OK; -+ } -+ else -+ { -+ psSyncOpsFlushToDeltaOUT->eError = PVRSRV_ERROR_RETRY; -+ } -+ -+ return 0; -+} -+ -+ -+static PVRSRV_ERROR -+FreeSyncInfoCallback(IMG_PVOID pvParam, -+ IMG_UINT32 ui32Param, -+ IMG_BOOL bDummy) -+{ -+ PVRSRV_KERNEL_SYNC_INFO *psSyncInfo; -+ -+ PVR_UNREFERENCED_PARAMETER(ui32Param); -+ PVR_UNREFERENCED_PARAMETER(bDummy); -+ -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)pvParam; -+ -+ PVRSRVKernelSyncInfoDecRef(psSyncInfo, IMG_NULL); -+ -+ return PVRSRV_OK; -+} -+ -+ -+static IMG_INT -+PVRSRVAllocSyncInfoBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_ALLOC_SYNC_INFO *psAllocSyncInfoIN, -+ PVRSRV_BRIDGE_OUT_ALLOC_SYNC_INFO *psAllocSyncInfoOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ PVRSRV_KERNEL_SYNC_INFO *psSyncInfo; -+ PVRSRV_ERROR eError; -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+ IMG_HANDLE hDevMemContext; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ALLOC_SYNC_INFO); -+ -+ NEW_HANDLE_BATCH_OR_ERROR(psAllocSyncInfoOUT->eError, psPerProc, 1) -+ -+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ (IMG_HANDLE *)&psDeviceNode, -+ psAllocSyncInfoIN->hDevCookie, -+ PVRSRV_HANDLE_TYPE_DEV_NODE); -+ if(eError != PVRSRV_OK) -+ { -+ goto allocsyncinfo_errorexit; -+ } -+ -+ hDevMemContext = psDeviceNode->sDevMemoryInfo.pBMKernelContext; -+ -+ eError = PVRSRVAllocSyncInfoKM(psDeviceNode, -+ hDevMemContext, -+ &psSyncInfo); -+ -+ if (eError != PVRSRV_OK) -+ { -+ goto allocsyncinfo_errorexit; -+ } -+ -+ eError = PVRSRVAllocHandle(psPerProc->psHandleBase, -+ &psAllocSyncInfoOUT->hKernelSyncInfo, -+ psSyncInfo, -+ PVRSRV_HANDLE_TYPE_SYNC_INFO, -+ PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE); -+ -+ if(eError != PVRSRV_OK) -+ { -+ goto allocsyncinfo_errorexit_freesyncinfo; -+ } -+ -+ psSyncInfo->hResItem = ResManRegisterRes(psPerProc->hResManContext, -+ RESMAN_TYPE_SYNC_INFO, -+ psSyncInfo, -+ 0, -+ &FreeSyncInfoCallback); -+ -+ /* Success */ -+ goto allocsyncinfo_commit; -+ -+ /* Error handling */ -+ allocsyncinfo_errorexit_freesyncinfo: -+ PVRSRVKernelSyncInfoDecRef(psSyncInfo, IMG_NULL); -+ -+ allocsyncinfo_errorexit: -+ -+ /* Common exit */ -+ allocsyncinfo_commit: -+ psAllocSyncInfoOUT->eError = eError; -+ COMMIT_HANDLE_BATCH_OR_ERROR(eError, psPerProc); -+ -+ return 0; -+} -+ -+ -+static IMG_INT -+PVRSRVFreeSyncInfoBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_FREE_SYNC_INFO *psFreeSyncInfoIN, -+ PVRSRV_BRIDGE_RETURN *psFreeSyncInfoOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ PVRSRV_KERNEL_SYNC_INFO *psSyncInfo; -+ PVRSRV_ERROR eError; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_FREE_SYNC_INFO); -+ -+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ (IMG_VOID**)&psSyncInfo, -+ psFreeSyncInfoIN->hKernelSyncInfo, -+ PVRSRV_HANDLE_TYPE_SYNC_INFO); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVFreeSyncInfoBW: PVRSRVLookupHandle failed")); -+ psFreeSyncInfoOUT->eError = eError; -+ return 0; -+ } -+ -+ eError = PVRSRVReleaseHandle(psPerProc->psHandleBase, -+ psFreeSyncInfoIN->hKernelSyncInfo, -+ PVRSRV_HANDLE_TYPE_SYNC_INFO); -+ -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVFreeSyncInfoBW: PVRSRVReleaseHandle failed")); -+ psFreeSyncInfoOUT->eError = eError; -+ return 0; -+ } -+ -+ eError = ResManFreeResByPtr(psSyncInfo->hResItem, CLEANUP_WITH_POLL); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVFreeSyncInfoBW: ResManFreeResByPtr failed")); -+ psFreeSyncInfoOUT->eError = eError; -+ return 0; -+ } -+ -+ return 0; -+} -+ -+ -+PVRSRV_ERROR -+CommonBridgeInit(IMG_VOID) -+{ -+ IMG_UINT32 i; -+ -+ SetDispatchTableEntry(PVRSRV_BRIDGE_ENUM_DEVICES, PVRSRVEnumerateDevicesBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_ACQUIRE_DEVICEINFO, PVRSRVAcquireDeviceDataBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_RELEASE_DEVICEINFO, DummyBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_CREATE_DEVMEMCONTEXT, PVRSRVCreateDeviceMemContextBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_DESTROY_DEVMEMCONTEXT, PVRSRVDestroyDeviceMemContextBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_GET_DEVMEM_HEAPINFO, PVRSRVGetDeviceMemHeapInfoBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_ALLOC_DEVICEMEM, PVRSRVAllocDeviceMemBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_FREE_DEVICEMEM, PVRSRVFreeDeviceMemBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_GETFREE_DEVICEMEM, PVRSRVGetFreeDeviceMemBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_CREATE_COMMANDQUEUE, DummyBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_DESTROY_COMMANDQUEUE, DummyBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_MHANDLE_TO_MMAP_DATA, PVRMMapOSMemHandleToMMapDataBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_CONNECT_SERVICES, PVRSRVConnectBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_DISCONNECT_SERVICES, PVRSRVDisconnectBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_WRAP_DEVICE_MEM, DummyBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_GET_DEVICEMEMINFO, DummyBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_RESERVE_DEV_VIRTMEM , DummyBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_FREE_DEV_VIRTMEM, DummyBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_EXT_MEMORY, DummyBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_UNMAP_EXT_MEMORY, DummyBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_DEV_MEMORY, PVRSRVMapDeviceMemoryBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_UNMAP_DEV_MEMORY, PVRSRVUnmapDeviceMemoryBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_DEVICECLASS_MEMORY, PVRSRVMapDeviceClassMemoryBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_UNMAP_DEVICECLASS_MEMORY, PVRSRVUnmapDeviceClassMemoryBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_MEM_INFO_TO_USER, DummyBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_UNMAP_MEM_INFO_FROM_USER, DummyBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_EXPORT_DEVICEMEM, PVRSRVExportDeviceMemBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_RELEASE_MMAP_DATA, PVRMMapReleaseMMapDataBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_CHG_DEV_MEM_ATTRIBS, PVRSRVChangeDeviceMemoryAttributesBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_DEV_MEMORY_2, PVRSRVMapDeviceMemoryBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_EXPORT_DEVICEMEM_2, PVRSRVExportDeviceMemBW); -+#if defined(SUPPORT_ION) -+ SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_ION_HANDLE, PVRSRVMapIonHandleBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_UNMAP_ION_HANDLE, PVRSRVUnmapIonHandleBW); -+#endif -+ -+ /* SIM */ -+ SetDispatchTableEntry(PVRSRV_BRIDGE_PROCESS_SIMISR_EVENT, DummyBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_REGISTER_SIM_PROCESS, DummyBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_UNREGISTER_SIM_PROCESS, DummyBW); -+ -+ /* User Mapping */ -+ SetDispatchTableEntry(PVRSRV_BRIDGE_MAPPHYSTOUSERSPACE, DummyBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_UNMAPPHYSTOUSERSPACE, DummyBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_GETPHYSTOUSERSPACEMAP, DummyBW); -+ -+ SetDispatchTableEntry(PVRSRV_BRIDGE_GET_FB_STATS, DummyBW); -+ -+ /* API to retrieve misc. info. from services */ -+ SetDispatchTableEntry(PVRSRV_BRIDGE_GET_MISC_INFO, PVRSRVGetMiscInfoBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_RELEASE_MISC_INFO, DummyBW); -+ -+ /* Overlay ioctls */ -+#if defined (SUPPORT_OVERLAY_ROTATE_BLIT) -+ SetDispatchTableEntry(PVRSRV_BRIDGE_INIT_3D_OVL_BLT_RES, DummyBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_DEINIT_3D_OVL_BLT_RES, DummyBW); -+#endif -+ -+ -+ /* PDUMP */ -+#if defined(PDUMP) -+ SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_INIT, DummyBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_MEMPOL, PDumpMemPolBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DUMPMEM, PDumpMemBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_REG, PDumpRegWithFlagsBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_REGPOL, PDumpRegPolBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_COMMENT, PDumpCommentBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_SETFRAME, PDumpSetFrameBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_ISCAPTURING, PDumpIsCaptureFrameBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DUMPBITMAP, PDumpBitmapBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DUMPREADREG, PDumpReadRegBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_SYNCPOL, PDumpSyncPolBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DUMPSYNC, PDumpSyncDumpBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_MEMPAGES, PDumpMemPagesBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DRIVERINFO, PDumpDriverInfoBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DUMPPDDEVPADDR, PDumpPDDevPAddrBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_CYCLE_COUNT_REG_READ, PDumpCycleCountRegReadBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_STARTINITPHASE, PDumpStartInitPhaseBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_STOPINITPHASE, PDumpStopInitPhaseBW); -+#endif /* defined(PDUMP) */ -+ -+ /* DisplayClass APIs */ -+ SetDispatchTableEntry(PVRSRV_BRIDGE_GET_OEMJTABLE, DummyBW); -+ -+ /* device class enum */ -+ SetDispatchTableEntry(PVRSRV_BRIDGE_ENUM_CLASS, PVRSRVEnumerateDCBW); -+ -+ /* display class API */ -+ SetDispatchTableEntry(PVRSRV_BRIDGE_OPEN_DISPCLASS_DEVICE, PVRSRVOpenDCDeviceBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_CLOSE_DISPCLASS_DEVICE, PVRSRVCloseDCDeviceBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_ENUM_DISPCLASS_FORMATS, PVRSRVEnumDCFormatsBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_ENUM_DISPCLASS_DIMS, PVRSRVEnumDCDimsBW); -+#if defined(SUPPORT_PVRSRV_GET_DC_SYSTEM_BUFFER) -+ SetDispatchTableEntry(PVRSRV_BRIDGE_GET_DISPCLASS_SYSBUFFER, PVRSRVGetDCSystemBufferBW); -+#else -+ SetDispatchTableEntry(PVRSRV_BRIDGE_GET_DISPCLASS_SYSBUFFER, DummyBW); -+#endif -+ SetDispatchTableEntry(PVRSRV_BRIDGE_GET_DISPCLASS_INFO, PVRSRVGetDCInfoBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_CREATE_DISPCLASS_SWAPCHAIN, PVRSRVCreateDCSwapChainBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_DESTROY_DISPCLASS_SWAPCHAIN, PVRSRVDestroyDCSwapChainBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_SET_DISPCLASS_DSTRECT, PVRSRVSetDCDstRectBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_SET_DISPCLASS_SRCRECT, PVRSRVSetDCSrcRectBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_SET_DISPCLASS_DSTCOLOURKEY, PVRSRVSetDCDstColourKeyBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_SET_DISPCLASS_SRCCOLOURKEY, PVRSRVSetDCSrcColourKeyBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_GET_DISPCLASS_BUFFERS, PVRSRVGetDCBuffersBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_BUFFER, PVRSRVSwapToDCBufferBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_BUFFER2, PVRSRVSwapToDCBuffer2BW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_SYSTEM, PVRSRVSwapToDCSystemBW); -+ -+ /* buffer class API */ -+ SetDispatchTableEntry(PVRSRV_BRIDGE_OPEN_BUFFERCLASS_DEVICE, PVRSRVOpenBCDeviceBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_CLOSE_BUFFERCLASS_DEVICE, PVRSRVCloseBCDeviceBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_GET_BUFFERCLASS_INFO, PVRSRVGetBCInfoBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_GET_BUFFERCLASS_BUFFER, PVRSRVGetBCBufferBW); -+ -+ /* Wrap/Unwrap external memory */ -+ SetDispatchTableEntry(PVRSRV_BRIDGE_WRAP_EXT_MEMORY, PVRSRVWrapExtMemoryBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_UNWRAP_EXT_MEMORY, PVRSRVUnwrapExtMemoryBW); -+ -+ /* Shared memory */ -+ SetDispatchTableEntry(PVRSRV_BRIDGE_ALLOC_SHARED_SYS_MEM, PVRSRVAllocSharedSysMemoryBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_FREE_SHARED_SYS_MEM, PVRSRVFreeSharedSysMemoryBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_MEMINFO_MEM, PVRSRVMapMemInfoMemBW); -+ -+ /* Intialisation Service support */ -+ SetDispatchTableEntry(PVRSRV_BRIDGE_INITSRV_CONNECT, &PVRSRVInitSrvConnectBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_INITSRV_DISCONNECT, &PVRSRVInitSrvDisconnectBW); -+ -+ /* Event Object */ -+ SetDispatchTableEntry(PVRSRV_BRIDGE_EVENT_OBJECT_WAIT, &PVRSRVEventObjectWaitBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_EVENT_OBJECT_OPEN, &PVRSRVEventObjectOpenBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_EVENT_OBJECT_CLOSE, &PVRSRVEventObjectCloseBW); -+ -+ SetDispatchTableEntry(PVRSRV_BRIDGE_CREATE_SYNC_INFO_MOD_OBJ, PVRSRVCreateSyncInfoModObjBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_DESTROY_SYNC_INFO_MOD_OBJ, PVRSRVDestroySyncInfoModObjBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_MODIFY_PENDING_SYNC_OPS, PVRSRVModifyPendingSyncOpsBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_MODIFY_COMPLETE_SYNC_OPS, PVRSRVModifyCompleteSyncOpsBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC_OPS_TAKE_TOKEN, PVRSRVSyncOpsTakeTokenBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC_OPS_FLUSH_TO_TOKEN, PVRSRVSyncOpsFlushToTokenBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC_OPS_FLUSH_TO_MOD_OBJ, PVRSRVSyncOpsFlushToModObjBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC_OPS_FLUSH_TO_DELTA, PVRSRVSyncOpsFlushToDeltaBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_ALLOC_SYNC_INFO, PVRSRVAllocSyncInfoBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_FREE_SYNC_INFO, PVRSRVFreeSyncInfoBW); -+ -+#if defined (SUPPORT_SGX) -+ SetSGXDispatchTableEntry(); -+#endif -+#if defined (SUPPORT_VGX) -+ SetVGXDispatchTableEntry(); -+#endif -+#if defined (SUPPORT_MSVDX) -+ SetMSVDXDispatchTableEntry(); -+#endif -+ -+ /* A safety net to help ensure there won't be any un-initialised dispatch -+ * table entries... */ -+ /* Note: This is specifically done _after_ setting all the dispatch entries -+ * so that SetDispatchTableEntry can detect mistakes where entries -+ * overlap */ -+ for(i=0;i<BRIDGE_DISPATCH_TABLE_ENTRY_COUNT;i++) -+ { -+ if(!g_BridgeDispatchTable[i].pfFunction) -+ { -+ g_BridgeDispatchTable[i].pfFunction = &DummyBW; -+#if defined(DEBUG_BRIDGE_KM) -+ g_BridgeDispatchTable[i].pszIOCName = "_PVRSRV_BRIDGE_DUMMY"; -+ g_BridgeDispatchTable[i].pszFunctionName = "DummyBW"; -+ g_BridgeDispatchTable[i].ui32CallCount = 0; -+ g_BridgeDispatchTable[i].ui32CopyFromUserTotalBytes = 0; -+ g_BridgeDispatchTable[i].ui32CopyToUserTotalBytes = 0; -+#endif -+ } -+ } -+ -+ return PVRSRV_OK; -+} -+ -+IMG_INT BridgedDispatchKM(PVRSRV_PER_PROCESS_DATA * psPerProc, -+ PVRSRV_BRIDGE_PACKAGE * psBridgePackageKM) -+{ -+ IMG_VOID * psBridgeIn; -+ IMG_VOID * psBridgeOut; -+ BridgeWrapperFunction pfBridgeHandler; -+ IMG_UINT32 ui32BridgeID = psBridgePackageKM->ui32BridgeID; -+ IMG_INT err = -EFAULT; -+ -+#if defined(DEBUG_TRACE_BRIDGE_KM) -+ PVR_DPF((PVR_DBG_ERROR, "%s: %s", -+ __FUNCTION__, -+ g_BridgeDispatchTable[ui32BridgeID].pszIOCName)); -+#endif -+ -+#if defined(DEBUG_BRIDGE_KM) -+ g_BridgeDispatchTable[ui32BridgeID].ui32CallCount++; -+ g_BridgeGlobalStats.ui32IOCTLCount++; -+#endif -+ -+ if(!psPerProc->bInitProcess) -+ { -+ if(PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RAN)) -+ { -+ if(!PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: Initialisation failed. Driver unusable.", -+ __FUNCTION__)); -+ goto return_fault; -+ } -+ } -+ else -+ { -+ if(PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RUNNING)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: Initialisation is in progress", -+ __FUNCTION__)); -+ goto return_fault; -+ } -+ else -+ { -+ /* Only certain operations are allowed */ -+ switch(ui32BridgeID) -+ { -+ case PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_CONNECT_SERVICES): -+ case PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_DISCONNECT_SERVICES): -+ case PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_INITSRV_CONNECT): -+ case PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_INITSRV_DISCONNECT): -+ break; -+ default: -+ PVR_DPF((PVR_DBG_ERROR, "%s: Driver initialisation not completed yet.", -+ __FUNCTION__)); -+ goto return_fault; -+ } -+ } -+ } -+ } -+ -+#if defined(__linux__) -+ { -+ /* This should be moved into the linux specific code */ -+ SYS_DATA *psSysData; -+ -+ SysAcquireData(&psSysData); -+ -+ /* We have already set up some static buffers to store our ioctl data... */ -+ psBridgeIn = ((ENV_DATA *)psSysData->pvEnvSpecificData)->pvBridgeData; -+ psBridgeOut = (IMG_PVOID)((IMG_PBYTE)psBridgeIn + PVRSRV_MAX_BRIDGE_IN_SIZE); -+ -+ /* check we are not using a bigger bridge than allocated */ -+ if((psBridgePackageKM->ui32InBufferSize > PVRSRV_MAX_BRIDGE_IN_SIZE) || -+ (psBridgePackageKM->ui32OutBufferSize > PVRSRV_MAX_BRIDGE_OUT_SIZE)) -+ { -+ goto return_fault; -+ } -+ -+ -+ if(psBridgePackageKM->ui32InBufferSize > 0) -+ { -+ if(!OSAccessOK(PVR_VERIFY_READ, -+ psBridgePackageKM->pvParamIn, -+ psBridgePackageKM->ui32InBufferSize)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: Invalid pvParamIn pointer", __FUNCTION__)); -+ } -+ -+ if(CopyFromUserWrapper(psPerProc, -+ ui32BridgeID, -+ psBridgeIn, -+ psBridgePackageKM->pvParamIn, -+ psBridgePackageKM->ui32InBufferSize) -+ != PVRSRV_OK) -+ { -+ goto return_fault; -+ } -+ } -+ } -+#else -+ psBridgeIn = psBridgePackageKM->pvParamIn; -+ psBridgeOut = psBridgePackageKM->pvParamOut; -+#endif -+ -+ if(ui32BridgeID >= (BRIDGE_DISPATCH_TABLE_ENTRY_COUNT)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: ui32BridgeID = %d is out if range!", -+ __FUNCTION__, ui32BridgeID)); -+ goto return_fault; -+ } -+ pfBridgeHandler = -+ (BridgeWrapperFunction)g_BridgeDispatchTable[ui32BridgeID].pfFunction; -+ err = pfBridgeHandler(ui32BridgeID, -+ psBridgeIn, -+ psBridgeOut, -+ psPerProc); -+ if(err < 0) -+ { -+ goto return_fault; -+ } -+ -+#if defined(__linux__) -+ /* This should be moved into the linux specific code */ -+ if(CopyToUserWrapper(psPerProc, -+ ui32BridgeID, -+ psBridgePackageKM->pvParamOut, -+ psBridgeOut, -+ psBridgePackageKM->ui32OutBufferSize) -+ != PVRSRV_OK) -+ { -+ goto return_fault; -+ } -+#endif -+ -+ err = 0; -+return_fault: -+ -+ ReleaseHandleBatch(psPerProc); -+ return err; -+} -+ -+/****************************************************************************** -+ End of file (bridged_pvr_bridge.c) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/bridged/bridged_pvr_bridge.h b/drivers/staging/ti-es8-sgx/services4/srvkm/bridged/bridged_pvr_bridge.h -new file mode 100644 -index 0000000..63aed147 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/bridged/bridged_pvr_bridge.h -@@ -0,0 +1,257 @@ -+/*************************************************************************/ /*! -+@Title PVR Bridge Functionality -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Header for the PVR Bridge code -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#ifndef __BRIDGED_PVR_BRIDGE_H__ -+#define __BRIDGED_PVR_BRIDGE_H__ -+ -+#include "pvr_bridge.h" -+ -+#if defined(__cplusplus) -+extern "C" { -+#endif -+ -+#if defined(__linux__) -+#define PVRSRV_GET_BRIDGE_ID(X) _IOC_NR(X) -+#else -+#define PVRSRV_GET_BRIDGE_ID(X) ((X) - PVRSRV_IOWR(PVRSRV_BRIDGE_CORE_CMD_FIRST)) -+#endif -+ -+#ifndef ENOMEM -+#define ENOMEM 12 -+#endif -+#ifndef EFAULT -+#define EFAULT 14 -+#endif -+#ifndef ENOTTY -+#define ENOTTY 25 -+#endif -+ -+#if defined(DEBUG_BRIDGE_KM) -+PVRSRV_ERROR -+CopyFromUserWrapper(PVRSRV_PER_PROCESS_DATA *pProcData, -+ IMG_UINT32 ui32BridgeID, -+ IMG_VOID *pvDest, -+ IMG_VOID *pvSrc, -+ IMG_UINT32 ui32Size); -+PVRSRV_ERROR -+CopyToUserWrapper(PVRSRV_PER_PROCESS_DATA *pProcData, -+ IMG_UINT32 ui32BridgeID, -+ IMG_VOID *pvDest, -+ IMG_VOID *pvSrc, -+ IMG_UINT32 ui32Size); -+#else -+#define CopyFromUserWrapper(pProcData, ui32BridgeID, pvDest, pvSrc, ui32Size) \ -+ OSCopyFromUser(pProcData, pvDest, pvSrc, ui32Size) -+#define CopyToUserWrapper(pProcData, ui32BridgeID, pvDest, pvSrc, ui32Size) \ -+ OSCopyToUser(pProcData, pvDest, pvSrc, ui32Size) -+#endif -+ -+ -+#define ASSIGN_AND_RETURN_ON_ERROR(error, src, res) \ -+ do \ -+ { \ -+ (error) = (src); \ -+ if ((error) != PVRSRV_OK) \ -+ { \ -+ return (res); \ -+ } \ -+ } while ((error) != PVRSRV_OK); -+ -+#define ASSIGN_AND_EXIT_ON_ERROR(error, src) \ -+ ASSIGN_AND_RETURN_ON_ERROR(error, src, 0) -+ -+#if defined(PVR_SECURE_HANDLES) -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(NewHandleBatch) -+#endif -+static INLINE PVRSRV_ERROR -+NewHandleBatch(PVRSRV_PER_PROCESS_DATA *psPerProc, -+ IMG_UINT32 ui32BatchSize) -+{ -+ PVRSRV_ERROR eError; -+ -+ PVR_ASSERT(!psPerProc->bHandlesBatched); -+ -+ eError = PVRSRVNewHandleBatch(psPerProc->psHandleBase, ui32BatchSize); -+ -+ if (eError == PVRSRV_OK) -+ { -+ psPerProc->bHandlesBatched = IMG_TRUE; -+ } -+ -+ return eError; -+} -+ -+#define NEW_HANDLE_BATCH_OR_ERROR(error, psPerProc, ui32BatchSize) \ -+ ASSIGN_AND_EXIT_ON_ERROR(error, NewHandleBatch(psPerProc, ui32BatchSize)) -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(CommitHandleBatch) -+#endif -+static INLINE PVRSRV_ERROR -+CommitHandleBatch(PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ PVR_ASSERT(psPerProc->bHandlesBatched); -+ -+ psPerProc->bHandlesBatched = IMG_FALSE; -+ -+ return PVRSRVCommitHandleBatch(psPerProc->psHandleBase); -+} -+ -+ -+#define COMMIT_HANDLE_BATCH_OR_ERROR(error, psPerProc) \ -+ ASSIGN_AND_EXIT_ON_ERROR(error, CommitHandleBatch(psPerProc)) -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(ReleaseHandleBatch) -+#endif -+static INLINE IMG_VOID -+ReleaseHandleBatch(PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ if (psPerProc->bHandlesBatched) -+ { -+ psPerProc->bHandlesBatched = IMG_FALSE; -+ -+ PVRSRVReleaseHandleBatch(psPerProc->psHandleBase); -+ } -+} -+#else /* defined(PVR_SECURE_HANDLES) */ -+#define NEW_HANDLE_BATCH_OR_ERROR(error, psPerProc, ui32BatchSize) -+#define COMMIT_HANDLE_BATCH_OR_ERROR(error, psPerProc) -+#define ReleaseHandleBatch(psPerProc) -+#endif /* defined(PVR_SECURE_HANDLES) */ -+ -+IMG_INT -+DummyBW(IMG_UINT32 ui32BridgeID, -+ IMG_VOID *psBridgeIn, -+ IMG_VOID *psBridgeOut, -+ PVRSRV_PER_PROCESS_DATA *psPerProc); -+ -+typedef IMG_INT (*BridgeWrapperFunction)(IMG_UINT32 ui32BridgeID, -+ IMG_VOID *psBridgeIn, -+ IMG_VOID *psBridgeOut, -+ PVRSRV_PER_PROCESS_DATA *psPerProc); -+ -+typedef struct _PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY -+{ -+ BridgeWrapperFunction pfFunction; /*!< The wrapper function that validates the ioctl -+ arguments before calling into srvkm proper */ -+#if defined(DEBUG_BRIDGE_KM) -+ const IMG_CHAR *pszIOCName; /*!< Name of the ioctl: e.g. "PVRSRV_BRIDGE_CONNECT_SERVICES" */ -+ const IMG_CHAR *pszFunctionName; /*!< Name of the wrapper function: e.g. "PVRSRVConnectBW" */ -+ IMG_UINT32 ui32CallCount; /*!< The total number of times the ioctl has been called */ -+ IMG_UINT32 ui32CopyFromUserTotalBytes; /*!< The total number of bytes copied from -+ userspace within this ioctl */ -+ IMG_UINT32 ui32CopyToUserTotalBytes; /*!< The total number of bytes copied from -+ userspace within this ioctl */ -+#endif -+}PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY; -+ -+#if defined(SUPPORT_VGX) || defined(SUPPORT_MSVDX) -+ #if defined(SUPPORT_VGX) -+ #define BRIDGE_DISPATCH_TABLE_ENTRY_COUNT (PVRSRV_BRIDGE_LAST_VGX_CMD+1) -+ #define PVRSRV_BRIDGE_LAST_DEVICE_CMD PVRSRV_BRIDGE_LAST_VGX_CMD -+ #else -+ #define BRIDGE_DISPATCH_TABLE_ENTRY_COUNT (PVRSRV_BRIDGE_LAST_MSVDX_CMD+1) -+ #define PVRSRV_BRIDGE_LAST_DEVICE_CMD PVRSRV_BRIDGE_LAST_MSVDX_CMD -+ #endif -+#else -+ #if defined(SUPPORT_SGX) -+ #define BRIDGE_DISPATCH_TABLE_ENTRY_COUNT (PVRSRV_BRIDGE_LAST_SGX_CMD+1) -+ #define PVRSRV_BRIDGE_LAST_DEVICE_CMD PVRSRV_BRIDGE_LAST_SGX_CMD -+ #else -+ #define BRIDGE_DISPATCH_TABLE_ENTRY_COUNT (PVRSRV_BRIDGE_LAST_NON_DEVICE_CMD+1) -+ #define PVRSRV_BRIDGE_LAST_DEVICE_CMD PVRSRV_BRIDGE_LAST_NON_DEVICE_CMD -+ #endif -+#endif -+ -+extern PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY g_BridgeDispatchTable[BRIDGE_DISPATCH_TABLE_ENTRY_COUNT]; -+ -+IMG_VOID -+_SetDispatchTableEntry(IMG_UINT32 ui32Index, -+ const IMG_CHAR *pszIOCName, -+ BridgeWrapperFunction pfFunction, -+ const IMG_CHAR *pszFunctionName); -+ -+ -+/* PRQA S 0884,3410 2*/ /* macro relies on the lack of brackets */ -+#define SetDispatchTableEntry(ui32Index, pfFunction) \ -+ _SetDispatchTableEntry(PVRSRV_GET_BRIDGE_ID(ui32Index), #ui32Index, (BridgeWrapperFunction)pfFunction, #pfFunction) -+ -+#define DISPATCH_TABLE_GAP_THRESHOLD 5 -+ -+#if defined(DEBUG) -+#define PVRSRV_BRIDGE_ASSERT_CMD(X, Y) PVR_ASSERT(X == PVRSRV_GET_BRIDGE_ID(Y)) -+#else -+#define PVRSRV_BRIDGE_ASSERT_CMD(X, Y) PVR_UNREFERENCED_PARAMETER(X) -+#endif -+ -+ -+#if defined(DEBUG_BRIDGE_KM) -+typedef struct _PVRSRV_BRIDGE_GLOBAL_STATS -+{ -+ IMG_UINT32 ui32IOCTLCount; -+ IMG_UINT32 ui32TotalCopyFromUserBytes; -+ IMG_UINT32 ui32TotalCopyToUserBytes; -+}PVRSRV_BRIDGE_GLOBAL_STATS; -+ -+/* OS specific code way want to report the stats held here and within the -+ * BRIDGE_DISPATCH_TABLE_ENTRYs (E.g. on Linux we report these via a -+ * proc entry /proc/pvr/bridge_stats. Ref printLinuxBridgeStats()) */ -+extern PVRSRV_BRIDGE_GLOBAL_STATS g_BridgeGlobalStats; -+#endif -+ -+ -+PVRSRV_ERROR CommonBridgeInit(IMG_VOID); -+ -+IMG_INT BridgedDispatchKM(PVRSRV_PER_PROCESS_DATA * psPerProc, -+ PVRSRV_BRIDGE_PACKAGE * psBridgePackageKM); -+ -+#if defined (__cplusplus) -+} -+#endif -+ -+#endif /* __BRIDGED_PVR_BRIDGE_H__ */ -+ -+/****************************************************************************** -+ End of file (bridged_pvr_bridge.h) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/bridged/bridged_support.c b/drivers/staging/ti-es8-sgx/services4/srvkm/bridged/bridged_support.c -new file mode 100644 -index 0000000..202bc70 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/bridged/bridged_support.c -@@ -0,0 +1,113 @@ -+/*************************************************************************/ /*! -+@Title PVR Bridge Support Functions -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description User/kernel mode bridge support. The functions in here -+ may be used beyond the bridge code proper (e.g. Linux -+ mmap interface). -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#include "img_defs.h" -+#include "servicesint.h" -+#include "bridged_support.h" -+ -+ -+/* -+ * Derive the internal OS specific memory handle from a secure -+ * handle. -+ */ -+PVRSRV_ERROR -+PVRSRVLookupOSMemHandle(PVRSRV_HANDLE_BASE *psHandleBase, IMG_HANDLE *phOSMemHandle, IMG_HANDLE hMHandle) -+{ -+ IMG_HANDLE hMHandleInt; -+ PVRSRV_HANDLE_TYPE eHandleType; -+ PVRSRV_ERROR eError; -+ -+ /* -+ * We don't know the type of the handle at this point, so we use -+ * PVRSRVLookupHandleAnyType to look it up. -+ */ -+ eError = PVRSRVLookupHandleAnyType(psHandleBase, &hMHandleInt, -+ &eHandleType, -+ hMHandle); -+ if(eError != PVRSRV_OK) -+ { -+ return eError; -+ } -+ -+ switch(eHandleType) -+ { -+#if defined(PVR_SECURE_HANDLES) -+ case PVRSRV_HANDLE_TYPE_MEM_INFO: -+ case PVRSRV_HANDLE_TYPE_MEM_INFO_REF: -+ case PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO: -+ { -+ PVRSRV_KERNEL_MEM_INFO *psMemInfo = (PVRSRV_KERNEL_MEM_INFO *)hMHandleInt; -+ -+ *phOSMemHandle = psMemInfo->sMemBlk.hOSMemHandle; -+ -+ break; -+ } -+ case PVRSRV_HANDLE_TYPE_SYNC_INFO: -+ { -+ PVRSRV_KERNEL_SYNC_INFO *psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)hMHandleInt; -+ PVRSRV_KERNEL_MEM_INFO *psMemInfo = psSyncInfo->psSyncDataMemInfoKM; -+ -+ *phOSMemHandle = psMemInfo->sMemBlk.hOSMemHandle; -+ -+ break; -+ } -+ case PVRSRV_HANDLE_TYPE_SOC_TIMER: -+ { -+ *phOSMemHandle = (IMG_VOID *)hMHandleInt; -+ break; -+ } -+#else -+ case PVRSRV_HANDLE_TYPE_NONE: -+ *phOSMemHandle = (IMG_VOID *)hMHandleInt; -+ break; -+#endif -+ default: -+ return PVRSRV_ERROR_BAD_MAPPING; -+ } -+ -+ return PVRSRV_OK; -+} -+/****************************************************************************** -+ End of file (bridged_support.c) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/bridged/bridged_support.h b/drivers/staging/ti-es8-sgx/services4/srvkm/bridged/bridged_support.h -new file mode 100644 -index 0000000..e32fa88 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/bridged/bridged_support.h -@@ -0,0 +1,68 @@ -+/*************************************************************************/ /*! -+@Title PVR Bridge Support -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description User/kernel mode bridge support. The functions in here -+ may be used beyond the bridge code proper (e.g. Linux -+ mmap interface). -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#ifndef __BRIDGED_SUPPORT_H__ -+#define __BRIDGED_SUPPORT_H__ -+ -+#include "handle.h" -+ -+#if defined(__cplusplus) -+extern "C" { -+#endif -+ -+/* -+ * Derive the internal OS specific memory handle from a secure -+ * handle. -+ */ -+PVRSRV_ERROR PVRSRVLookupOSMemHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phOSMemHandle, IMG_HANDLE hMHandle); -+ -+#if defined (__cplusplus) -+} -+#endif -+ -+#endif /* __BRIDGED_SUPPORT_H__ */ -+ -+/****************************************************************************** -+ End of file (bridged_support.h) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/bridged/sgx/bridged_sgx_bridge.c b/drivers/staging/ti-es8-sgx/services4/srvkm/bridged/sgx/bridged_sgx_bridge.c -new file mode 100644 -index 0000000..a0a26bc ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/bridged/sgx/bridged_sgx_bridge.c -@@ -0,0 +1,3156 @@ -+/*************************************************************************/ /*! -+@Title SGX Common Bridge Module (kernel side) -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Receives calls from the user portion of services and -+ despatches them to functions in the kernel portion. -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+ -+ -+#include <stddef.h> -+ -+#include "img_defs.h" -+ -+#if defined(SUPPORT_SGX) -+ -+#include "services.h" -+#include "pvr_debug.h" -+#include "pvr_bridge.h" -+#include "sgx_bridge.h" -+#include "perproc.h" -+#include "power.h" -+#include "pvr_bridge_km.h" -+#include "sgx_bridge_km.h" -+#include "sgx_options.h" -+ -+#if defined(SUPPORT_MSVDX) -+ #include "msvdx_bridge.h" -+#endif -+ -+#include "bridged_pvr_bridge.h" -+#include "bridged_sgx_bridge.h" -+#include "sgxutils.h" -+#include "buffer_manager.h" -+#include "pdump_km.h" -+ -+static IMG_INT -+SGXGetClientInfoBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_GETCLIENTINFO *psGetClientInfoIN, -+ PVRSRV_BRIDGE_OUT_GETCLIENTINFO *psGetClientInfoOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_HANDLE hDevCookieInt; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_GETCLIENTINFO); -+ -+ psGetClientInfoOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDevCookieInt, -+ psGetClientInfoIN->hDevCookie, -+ PVRSRV_HANDLE_TYPE_DEV_NODE); -+ if(psGetClientInfoOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psGetClientInfoOUT->eError = -+ SGXGetClientInfoKM(hDevCookieInt, -+ &psGetClientInfoOUT->sClientInfo); -+ return 0; -+} -+ -+static IMG_INT -+SGXReleaseClientInfoBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_RELEASECLIENTINFO *psReleaseClientInfoIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ PVRSRV_SGXDEV_INFO *psDevInfo; -+ IMG_HANDLE hDevCookieInt; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_RELEASECLIENTINFO); -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDevCookieInt, -+ psReleaseClientInfoIN->hDevCookie, -+ PVRSRV_HANDLE_TYPE_DEV_NODE); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookieInt)->pvDevice; -+ -+ PVR_ASSERT(psDevInfo->ui32ClientRefCount > 0); -+ -+ /* -+ * psDevInfo->ui32ClientRefCount can be zero if an error occurred before SGXGetClientInfo is called -+ */ -+ if (psDevInfo->ui32ClientRefCount > 0) -+ { -+ psDevInfo->ui32ClientRefCount--; -+ } -+ -+ psRetOUT->eError = PVRSRV_OK; -+ -+ return 0; -+} -+ -+ -+static IMG_INT -+SGXGetInternalDevInfoBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_GETINTERNALDEVINFO *psSGXGetInternalDevInfoIN, -+ PVRSRV_BRIDGE_OUT_GETINTERNALDEVINFO *psSGXGetInternalDevInfoOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_HANDLE hDevCookieInt; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_GETINTERNALDEVINFO); -+ -+ psSGXGetInternalDevInfoOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDevCookieInt, -+ psSGXGetInternalDevInfoIN->hDevCookie, -+ PVRSRV_HANDLE_TYPE_DEV_NODE); -+ if(psSGXGetInternalDevInfoOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psSGXGetInternalDevInfoOUT->eError = -+ SGXGetInternalDevInfoKM(hDevCookieInt, -+ &psSGXGetInternalDevInfoOUT->sSGXInternalDevInfo); -+ -+ /* -+ * Handle is not allocated in batch mode, as there is no resource -+ * allocation to undo if the handle allocation fails. -+ */ -+ psSGXGetInternalDevInfoOUT->eError = -+ PVRSRVAllocHandle(psPerProc->psHandleBase, -+ &psSGXGetInternalDevInfoOUT->sSGXInternalDevInfo.hHostCtlKernelMemInfoHandle, -+ psSGXGetInternalDevInfoOUT->sSGXInternalDevInfo.hHostCtlKernelMemInfoHandle, -+ PVRSRV_HANDLE_TYPE_MEM_INFO, -+ PVRSRV_HANDLE_ALLOC_FLAG_SHARED); -+ -+ return 0; -+} -+ -+ -+static IMG_INT -+SGXDoKickBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_DOKICK *psDoKickIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_HANDLE hDevCookieInt; -+ IMG_UINT32 i; -+ IMG_INT ret = 0; -+ IMG_UINT32 ui32NumDstSyncs; -+ IMG_HANDLE *phKernelSyncInfoHandles = IMG_NULL; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_DOKICK); -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDevCookieInt, -+ psDoKickIN->hDevCookie, -+ PVRSRV_HANDLE_TYPE_DEV_NODE); -+ -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &psDoKickIN->sCCBKick.hCCBKernelMemInfo, -+ psDoKickIN->sCCBKick.hCCBKernelMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ if(psDoKickIN->sCCBKick.hTA3DSyncInfo != IMG_NULL) -+ { -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &psDoKickIN->sCCBKick.hTA3DSyncInfo, -+ psDoKickIN->sCCBKick.hTA3DSyncInfo, -+ PVRSRV_HANDLE_TYPE_SYNC_INFO); -+ -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ } -+ -+ if(psDoKickIN->sCCBKick.hTASyncInfo != IMG_NULL) -+ { -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &psDoKickIN->sCCBKick.hTASyncInfo, -+ psDoKickIN->sCCBKick.hTASyncInfo, -+ PVRSRV_HANDLE_TYPE_SYNC_INFO); -+ -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ } -+ -+#if defined(FIX_HW_BRN_31620) -+ /* We need to lookup the mem context and pass it through */ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &psDoKickIN->sCCBKick.hDevMemContext, -+ psDoKickIN->sCCBKick.hDevMemContext, -+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT); -+ -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+#endif -+ -+ if(psDoKickIN->sCCBKick.h3DSyncInfo != IMG_NULL) -+ { -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &psDoKickIN->sCCBKick.h3DSyncInfo, -+ psDoKickIN->sCCBKick.h3DSyncInfo, -+ PVRSRV_HANDLE_TYPE_SYNC_INFO); -+ -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ } -+ -+ -+#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS) -+ /* SRC and DST sync details */ -+ if (psDoKickIN->sCCBKick.ui32NumTASrcSyncs > SGX_MAX_TA_SRC_SYNCS) -+ { -+ psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; -+ return 0; -+ } -+ -+ for(i=0; i<psDoKickIN->sCCBKick.ui32NumTASrcSyncs; i++) -+ { -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &psDoKickIN->sCCBKick.ahTASrcKernelSyncInfo[i], -+ psDoKickIN->sCCBKick.ahTASrcKernelSyncInfo[i], -+ PVRSRV_HANDLE_TYPE_SYNC_INFO); -+ -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ } -+ -+ if (psDoKickIN->sCCBKick.ui32NumTADstSyncs > SGX_MAX_TA_DST_SYNCS) -+ { -+ psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; -+ return 0; -+ } -+ -+ for(i=0; i<psDoKickIN->sCCBKick.ui32NumTADstSyncs; i++) -+ { -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &psDoKickIN->sCCBKick.ahTADstKernelSyncInfo[i], -+ psDoKickIN->sCCBKick.ahTADstKernelSyncInfo[i], -+ PVRSRV_HANDLE_TYPE_SYNC_INFO); -+ -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ } -+ -+ if (psDoKickIN->sCCBKick.ui32Num3DSrcSyncs > SGX_MAX_3D_SRC_SYNCS) -+ { -+ psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; -+ return 0; -+ } -+ -+ for(i=0; i<psDoKickIN->sCCBKick.ui32Num3DSrcSyncs; i++) -+ { -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &psDoKickIN->sCCBKick.ah3DSrcKernelSyncInfo[i], -+ psDoKickIN->sCCBKick.ah3DSrcKernelSyncInfo[i], -+ PVRSRV_HANDLE_TYPE_SYNC_INFO); -+ -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ } -+#else/* #if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS) */ -+ /* texture dependency details */ -+ if (psDoKickIN->sCCBKick.ui32NumSrcSyncs > SGX_MAX_SRC_SYNCS_TA) -+ { -+ psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; -+ return 0; -+ } -+ -+#if !defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) -+ for(i=0; i<psDoKickIN->sCCBKick.ui32NumSrcSyncs; i++) -+ { -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &psDoKickIN->sCCBKick.ahSrcKernelSyncInfo[i], -+ psDoKickIN->sCCBKick.ahSrcKernelSyncInfo[i], -+ PVRSRV_HANDLE_TYPE_SYNC_INFO); -+ -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ } -+#endif /* !defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) */ -+#endif /* defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS) */ -+ -+ if (psDoKickIN->sCCBKick.ui32NumTAStatusVals > SGX_MAX_TA_STATUS_VALS) -+ { -+ psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; -+ return 0; -+ } -+ for (i = 0; i < psDoKickIN->sCCBKick.ui32NumTAStatusVals; i++) -+ { -+ psRetOUT->eError = -+#if defined(SUPPORT_SGX_NEW_STATUS_VALS) -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &psDoKickIN->sCCBKick.asTAStatusUpdate[i].hKernelMemInfo, -+ psDoKickIN->sCCBKick.asTAStatusUpdate[i].hKernelMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ -+ -+#else -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &psDoKickIN->sCCBKick.ahTAStatusSyncInfo[i], -+ psDoKickIN->sCCBKick.ahTAStatusSyncInfo[i], -+ PVRSRV_HANDLE_TYPE_SYNC_INFO); -+#endif -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ } -+ -+ if (psDoKickIN->sCCBKick.ui32Num3DStatusVals > SGX_MAX_3D_STATUS_VALS) -+ { -+ psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; -+ return 0; -+ } -+ for(i = 0; i < psDoKickIN->sCCBKick.ui32Num3DStatusVals; i++) -+ { -+ psRetOUT->eError = -+#if defined(SUPPORT_SGX_NEW_STATUS_VALS) -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &psDoKickIN->sCCBKick.as3DStatusUpdate[i].hKernelMemInfo, -+ psDoKickIN->sCCBKick.as3DStatusUpdate[i].hKernelMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ -+#else -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &psDoKickIN->sCCBKick.ah3DStatusSyncInfo[i], -+ psDoKickIN->sCCBKick.ah3DStatusSyncInfo[i], -+ PVRSRV_HANDLE_TYPE_SYNC_INFO); -+#endif -+ -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ } -+ -+ ui32NumDstSyncs = psDoKickIN->sCCBKick.ui32NumDstSyncObjects; -+ -+ if(ui32NumDstSyncs > 0) -+ { -+ if(!OSAccessOK(PVR_VERIFY_READ, -+ psDoKickIN->sCCBKick.pahDstSyncHandles, -+ ui32NumDstSyncs * sizeof(IMG_HANDLE))) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: SGXDoKickBW:" -+ " Invalid pasDstSyncHandles pointer", __FUNCTION__)); -+ return -EFAULT; -+ } -+ -+ psRetOUT->eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ ui32NumDstSyncs * sizeof(IMG_HANDLE), -+ (IMG_VOID **)&phKernelSyncInfoHandles, -+ 0, -+ "Array of Synchronization Info Handles"); -+ if (psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ if(CopyFromUserWrapper(psPerProc, -+ ui32BridgeID, -+ phKernelSyncInfoHandles, -+ psDoKickIN->sCCBKick.pahDstSyncHandles, -+ ui32NumDstSyncs * sizeof(IMG_HANDLE)) != PVRSRV_OK) -+ { -+ ret = -EFAULT; -+ goto PVRSRV_BRIDGE_SGX_DOKICK_RETURN_RESULT; -+ } -+ -+ /* Set sCCBKick.pahDstSyncHandles to point to the local memory */ -+ psDoKickIN->sCCBKick.pahDstSyncHandles = phKernelSyncInfoHandles; -+ -+ for( i = 0; i < ui32NumDstSyncs; i++) -+ { -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &psDoKickIN->sCCBKick.pahDstSyncHandles[i], -+ psDoKickIN->sCCBKick.pahDstSyncHandles[i], -+ PVRSRV_HANDLE_TYPE_SYNC_INFO); -+ -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ goto PVRSRV_BRIDGE_SGX_DOKICK_RETURN_RESULT; -+ } -+ -+ } -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &psDoKickIN->sCCBKick.hKernelHWSyncListMemInfo, -+ psDoKickIN->sCCBKick.hKernelHWSyncListMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ goto PVRSRV_BRIDGE_SGX_DOKICK_RETURN_RESULT; -+ } -+ } -+ -+ psRetOUT->eError = -+ SGXDoKickKM(hDevCookieInt, -+ &psDoKickIN->sCCBKick); -+ -+PVRSRV_BRIDGE_SGX_DOKICK_RETURN_RESULT: -+ -+ if(phKernelSyncInfoHandles) -+ { -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, -+ ui32NumDstSyncs * sizeof(IMG_HANDLE), -+ (IMG_VOID *)phKernelSyncInfoHandles, -+ 0); -+ /*not nulling pointer, out of scope*/ -+ } -+ return ret; -+} -+ -+ -+static IMG_INT -+SGXScheduleProcessQueuesBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_SGX_SCHEDULE_PROCESS_QUEUES *psScheduleProcQIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_HANDLE hDevCookieInt; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_SCHEDULE_PROCESS_QUEUES); -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDevCookieInt, -+ psScheduleProcQIN->hDevCookie, -+ PVRSRV_HANDLE_TYPE_DEV_NODE); -+ -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = SGXScheduleProcessQueuesKM(hDevCookieInt); -+ -+ return 0; -+} -+ -+ -+#if defined(TRANSFER_QUEUE) -+static IMG_INT -+SGXSubmitTransferBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_SUBMITTRANSFER *psSubmitTransferIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_HANDLE hDevCookieInt; -+ PVRSRV_TRANSFER_SGX_KICK *psKick; -+ IMG_UINT32 i; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_SUBMITTRANSFER); -+ PVR_UNREFERENCED_PARAMETER(ui32BridgeID); -+ -+ psKick = &psSubmitTransferIN->sKick; -+ -+#if defined(FIX_HW_BRN_31620) -+ /* We need to lookup the mem context and pass it through */ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &psKick->hDevMemContext, -+ psKick->hDevMemContext, -+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT); -+ -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+#endif -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDevCookieInt, -+ psSubmitTransferIN->hDevCookie, -+ PVRSRV_HANDLE_TYPE_DEV_NODE); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &psKick->hCCBMemInfo, -+ psKick->hCCBMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ if (psKick->hTASyncInfo != IMG_NULL) -+ { -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &psKick->hTASyncInfo, -+ psKick->hTASyncInfo, -+ PVRSRV_HANDLE_TYPE_SYNC_INFO); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ } -+ -+ if (psKick->h3DSyncInfo != IMG_NULL) -+ { -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &psKick->h3DSyncInfo, -+ psKick->h3DSyncInfo, -+ PVRSRV_HANDLE_TYPE_SYNC_INFO); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ } -+ -+ if (psKick->ui32NumSrcSync > SGX_MAX_TRANSFER_SYNC_OPS) -+ { -+ psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; -+ return 0; -+ } -+ for (i = 0; i < psKick->ui32NumSrcSync; i++) -+ { -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &psKick->ahSrcSyncInfo[i], -+ psKick->ahSrcSyncInfo[i], -+ PVRSRV_HANDLE_TYPE_SYNC_INFO); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ } -+ -+ if (psKick->ui32NumDstSync > SGX_MAX_TRANSFER_SYNC_OPS) -+ { -+ psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; -+ return 0; -+ } -+ for (i = 0; i < psKick->ui32NumDstSync; i++) -+ { -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &psKick->ahDstSyncInfo[i], -+ psKick->ahDstSyncInfo[i], -+ PVRSRV_HANDLE_TYPE_SYNC_INFO); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ } -+ -+ psRetOUT->eError = SGXSubmitTransferKM(hDevCookieInt, psKick); -+ -+ return 0; -+} -+ -+static IMG_INT -+SGXSetTransferContextPriorityBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_SGX_SET_TRANSFER_CONTEXT_PRIORITY *psSGXSetTransferContextPriorityIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_HANDLE hDevCookieInt; -+ IMG_HANDLE hTransferContextInt; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_SET_TRANSFER_CONTEXT_PRIORITY); -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDevCookieInt, -+ psSGXSetTransferContextPriorityIN->hDevCookie, -+ PVRSRV_HANDLE_TYPE_DEV_NODE); -+ -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hTransferContextInt, -+ psSGXSetTransferContextPriorityIN->hHWTransferContext, -+ PVRSRV_HANDLE_TYPE_SGX_HW_TRANSFER_CONTEXT); -+ -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = SGXSetTransferContextPriorityKM( -+ hDevCookieInt, -+ hTransferContextInt, -+ psSGXSetTransferContextPriorityIN->ui32Priority, -+ psSGXSetTransferContextPriorityIN->ui32OffsetOfPriorityField); -+ -+ return 0; -+} -+ -+static IMG_INT -+SGXSetRenderContextPriorityBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_SGX_SET_RENDER_CONTEXT_PRIORITY *psSGXSetRenderContextPriorityIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_HANDLE hDevCookieInt; -+ IMG_HANDLE hRenderContextInt; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_SET_RENDER_CONTEXT_PRIORITY); -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDevCookieInt, -+ psSGXSetRenderContextPriorityIN->hDevCookie, -+ PVRSRV_HANDLE_TYPE_DEV_NODE); -+ -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hRenderContextInt, -+ psSGXSetRenderContextPriorityIN->hHWRenderContext, -+ PVRSRV_HANDLE_TYPE_SGX_HW_RENDER_CONTEXT); -+ -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = SGXSetRenderContextPriorityKM( -+ hDevCookieInt, -+ hRenderContextInt, -+ psSGXSetRenderContextPriorityIN->ui32Priority, -+ psSGXSetRenderContextPriorityIN->ui32OffsetOfPriorityField); -+ -+ return 0; -+} -+ -+ -+#if defined(SGX_FEATURE_2D_HARDWARE) -+static IMG_INT -+SGXSubmit2DBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_SUBMIT2D *psSubmit2DIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_HANDLE hDevCookieInt; -+ PVRSRV_2D_SGX_KICK *psKick; -+ IMG_UINT32 i; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_SUBMIT2D); -+ PVR_UNREFERENCED_PARAMETER(ui32BridgeID); -+ -+ psKick = &psSubmit2DIN->sKick; -+ -+#if defined(FIX_HW_BRN_31620) -+ /* We need to lookup the mem context and pass it through */ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &psKick->hDevMemContext, -+ psKick->hDevMemContext, -+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT); -+ -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+#endif -+ -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDevCookieInt, -+ psSubmit2DIN->hDevCookie, -+ PVRSRV_HANDLE_TYPE_DEV_NODE); -+ -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &psKick->hCCBMemInfo, -+ psKick->hCCBMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ if (psKick->hTASyncInfo != IMG_NULL) -+ { -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &psKick->hTASyncInfo, -+ psKick->hTASyncInfo, -+ PVRSRV_HANDLE_TYPE_SYNC_INFO); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ } -+ -+ if (psKick->h3DSyncInfo != IMG_NULL) -+ { -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &psKick->h3DSyncInfo, -+ psKick->h3DSyncInfo, -+ PVRSRV_HANDLE_TYPE_SYNC_INFO); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ } -+ -+ if (psKick->ui32NumSrcSync > SGX_MAX_2D_SRC_SYNC_OPS) -+ { -+ psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; -+ return 0; -+ } -+ for (i = 0; i < psKick->ui32NumSrcSync; i++) -+ { -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &psKick->ahSrcSyncInfo[i], -+ psKick->ahSrcSyncInfo[i], -+ PVRSRV_HANDLE_TYPE_SYNC_INFO); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ } -+ -+ if (psKick->hDstSyncInfo != IMG_NULL) -+ { -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &psKick->hDstSyncInfo, -+ psKick->hDstSyncInfo, -+ PVRSRV_HANDLE_TYPE_SYNC_INFO); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ } -+ -+ psRetOUT->eError = -+ SGXSubmit2DKM(hDevCookieInt, psKick); -+ -+ return 0; -+} -+#endif /* #if defined(SGX_FEATURE_2D_HARDWARE) */ -+#endif /* #if defined(TRANSFER_QUEUE) */ -+ -+ -+static IMG_INT -+SGXGetMiscInfoBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_SGXGETMISCINFO *psSGXGetMiscInfoIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_HANDLE hDevCookieInt; -+ IMG_HANDLE hDevMemContextInt = 0; -+ PVRSRV_SGXDEV_INFO *psDevInfo; -+ SGX_MISC_INFO sMiscInfo; -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, -+ PVRSRV_BRIDGE_SGX_GETMISCINFO); -+ -+ psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDevCookieInt, -+ psSGXGetMiscInfoIN->hDevCookie, -+ PVRSRV_HANDLE_TYPE_DEV_NODE); -+ -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG) -+ /* Lookup handle for dev mem context */ -+ if (psSGXGetMiscInfoIN->psMiscInfo->eRequest == SGX_MISC_INFO_REQUEST_MEMREAD) -+ { -+ psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDevMemContextInt, -+ psSGXGetMiscInfoIN->psMiscInfo->hDevMemContext, -+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT); -+ -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ } -+#endif -+ /* device node is required for scheduling a CCB command */ -+ psDeviceNode = hDevCookieInt; -+ PVR_ASSERT(psDeviceNode != IMG_NULL); -+ if (psDeviceNode == IMG_NULL) -+ { -+ return -EFAULT; -+ } -+ -+ psDevInfo = psDeviceNode->pvDevice; -+ -+ /* Copy psMiscInfo to kernel space */ -+ psRetOUT->eError = CopyFromUserWrapper(psPerProc, -+ ui32BridgeID, -+ &sMiscInfo, -+ psSGXGetMiscInfoIN->psMiscInfo, -+ sizeof(SGX_MISC_INFO)); -+ if (psRetOUT->eError != PVRSRV_OK) -+ { -+ return -EFAULT; -+ } -+ -+ { -+ psRetOUT->eError = SGXGetMiscInfoKM(psDevInfo, &sMiscInfo, psDeviceNode, hDevMemContextInt); -+ -+ if (psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ } -+ -+ /* Copy back misc info to user address space */ -+ psRetOUT->eError = CopyToUserWrapper(psPerProc, -+ ui32BridgeID, -+ psSGXGetMiscInfoIN->psMiscInfo, -+ &sMiscInfo, -+ sizeof(SGX_MISC_INFO)); -+ if (psRetOUT->eError != PVRSRV_OK) -+ { -+ return -EFAULT; -+ } -+ return 0; -+} -+ -+ -+static IMG_INT -+SGXReadHWPerfCBBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_SGX_READ_HWPERF_CB *psSGXReadHWPerfCBIN, -+ PVRSRV_BRIDGE_OUT_SGX_READ_HWPERF_CB *psSGXReadHWPerfCBOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_HANDLE hDevCookieInt; -+ PVRSRV_SGX_HWPERF_CB_ENTRY *psAllocated; -+ IMG_HANDLE hAllocatedHandle; -+ IMG_UINT32 ui32AllocatedSize; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_READ_HWPERF_CB); -+ -+ psSGXReadHWPerfCBOUT->eError =PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDevCookieInt, -+ psSGXReadHWPerfCBIN->hDevCookie, -+ PVRSRV_HANDLE_TYPE_DEV_NODE); -+ -+ if(psSGXReadHWPerfCBOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ ui32AllocatedSize = psSGXReadHWPerfCBIN->ui32ArraySize * -+ sizeof(psSGXReadHWPerfCBIN->psHWPerfCBData[0]); -+ ASSIGN_AND_EXIT_ON_ERROR(psSGXReadHWPerfCBOUT->eError, -+ OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ ui32AllocatedSize, -+ (IMG_VOID **)&psAllocated, -+ &hAllocatedHandle, -+ "Array of Hardware Performance Circular Buffer Data")); -+ -+ psSGXReadHWPerfCBOUT->eError = SGXReadHWPerfCBKM(hDevCookieInt, -+ psSGXReadHWPerfCBIN->ui32ArraySize, -+ psAllocated, -+ &psSGXReadHWPerfCBOUT->ui32DataCount, -+ &psSGXReadHWPerfCBOUT->ui32ClockSpeed, -+ &psSGXReadHWPerfCBOUT->ui32HostTimeStamp); -+ if (psSGXReadHWPerfCBOUT->eError == PVRSRV_OK) -+ { -+ psSGXReadHWPerfCBOUT->eError = CopyToUserWrapper(psPerProc, -+ ui32BridgeID, -+ psSGXReadHWPerfCBIN->psHWPerfCBData, -+ psAllocated, -+ ui32AllocatedSize); -+ } -+ -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, -+ ui32AllocatedSize, -+ psAllocated, -+ hAllocatedHandle); -+ /*not nulling pointer, out of scope*/ -+ -+ return 0; -+} -+ -+ -+static IMG_INT -+SGXDevInitPart2BW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_SGXDEVINITPART2 *psSGXDevInitPart2IN, -+ PVRSRV_BRIDGE_OUT_SGXDEVINITPART2 *psSGXDevInitPart2OUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_HANDLE hDevCookieInt; -+ PVRSRV_ERROR eError; -+ IMG_BOOL bDissociateFailed = IMG_FALSE; -+ IMG_BOOL bLookupFailed = IMG_FALSE; -+ IMG_BOOL bReleaseFailed = IMG_FALSE; -+ IMG_HANDLE hDummy; -+ IMG_UINT32 i; -+ IMG_VOID *pCommands = IMG_NULL; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_DEVINITPART2); -+ -+ /* Report the kernel-side build options to UM */ -+ psSGXDevInitPart2OUT->ui32KMBuildOptions = SGX_BUILD_OPTIONS; -+ -+ if(!psPerProc->bInitProcess) -+ { -+ psSGXDevInitPart2OUT->eError = PVRSRV_ERROR_PROCESS_NOT_INITIALISED; -+ return 0; -+ } -+ -+ psSGXDevInitPart2OUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDevCookieInt, -+ psSGXDevInitPart2IN->hDevCookie, -+ PVRSRV_HANDLE_TYPE_DEV_NODE); -+ if(psSGXDevInitPart2OUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ /* Copy debug script commands from UM to KM */ -+ for(i = 0; i < SGX_FEATURE_MP_CORE_COUNT_3D; i++) -+ { -+ /* Allocate memory in KM */ -+ psSGXDevInitPart2OUT->eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ SGX_MAX_PRINT_COMMANDS * sizeof(SGX_INIT_COMMAND), -+ (IMG_VOID **) &pCommands, -+ 0, -+ "debug script commands kernel copy"); -+ -+ if(psSGXDevInitPart2OUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ /* Copy commands */ -+ if(CopyFromUserWrapper(psPerProc, -+ ui32BridgeID, -+ pCommands, -+ psSGXDevInitPart2IN->sInitInfo.sScripts.apsSGXREGDebugCommandsPart2[i], -+ SGX_MAX_PRINT_COMMANDS * sizeof(SGX_INIT_COMMAND)) != PVRSRV_OK) -+ { -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, -+ SGX_MAX_PRINT_COMMANDS * sizeof(SGX_INIT_COMMAND), -+ pCommands, -+ 0); -+ return -EFAULT; -+ -+ } -+ /* update pointer */ -+ psSGXDevInitPart2IN->sInitInfo.sScripts.apsSGXREGDebugCommandsPart2[i] = pCommands; -+ -+ } -+ -+ /* Check all the meminfo handles */ -+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDummy, -+ psSGXDevInitPart2IN->sInitInfo.hKernelCCBMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if (eError != PVRSRV_OK) -+ { -+ bLookupFailed = IMG_TRUE; -+ } -+ -+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDummy, -+ psSGXDevInitPart2IN->sInitInfo.hKernelCCBCtlMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if (eError != PVRSRV_OK) -+ { -+ bLookupFailed = IMG_TRUE; -+ } -+ -+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDummy, -+ psSGXDevInitPart2IN->sInitInfo.hKernelCCBEventKickerMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if (eError != PVRSRV_OK) -+ { -+ bLookupFailed = IMG_TRUE; -+ } -+ -+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDummy, -+ psSGXDevInitPart2IN->sInitInfo.hKernelSGXHostCtlMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if (eError != PVRSRV_OK) -+ { -+ bLookupFailed = IMG_TRUE; -+ } -+ -+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDummy, -+ psSGXDevInitPart2IN->sInitInfo.hKernelSGXTA3DCtlMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if (eError != PVRSRV_OK) -+ { -+ bLookupFailed = IMG_TRUE; -+ } -+ -+#if defined(FIX_HW_BRN_31272) || defined(FIX_HW_BRN_31780) || defined(FIX_HW_BRN_33920) -+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDummy, -+ psSGXDevInitPart2IN->sInitInfo.hKernelSGXPTLAWriteBackMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if (eError != PVRSRV_OK) -+ { -+ bLookupFailed = IMG_TRUE; -+ } -+#endif -+ -+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDummy, -+ psSGXDevInitPart2IN->sInitInfo.hKernelSGXMiscMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if (eError != PVRSRV_OK) -+ { -+ bLookupFailed = IMG_TRUE; -+ } -+ -+#if defined(SGX_SUPPORT_HWPROFILING) -+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDummy, -+ psSGXDevInitPart2IN->sInitInfo.hKernelHWProfilingMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if (eError != PVRSRV_OK) -+ { -+ bLookupFailed = IMG_TRUE; -+ } -+#endif -+ -+#if defined(SUPPORT_SGX_HWPERF) -+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDummy, -+ psSGXDevInitPart2IN->sInitInfo.hKernelHWPerfCBMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SGXDevInitPart2BW: Failed to look up HWPerf meminfo (possibly due to SUPPORT_SGX_HWPERF option mismatch)")); -+ bLookupFailed = IMG_TRUE; -+ } -+#endif -+ -+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDummy, -+ psSGXDevInitPart2IN->sInitInfo.hKernelTASigBufferMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if (eError != PVRSRV_OK) -+ { -+ bLookupFailed = IMG_TRUE; -+ } -+ -+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDummy, -+ psSGXDevInitPart2IN->sInitInfo.hKernel3DSigBufferMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if (eError != PVRSRV_OK) -+ { -+ bLookupFailed = IMG_TRUE; -+ } -+ -+ -+#if defined(FIX_HW_BRN_31542) || defined(FIX_HW_BRN_36513) -+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDummy, -+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAVDMStreamMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if (eError != PVRSRV_OK) -+ { -+ bLookupFailed = IMG_TRUE; -+ } -+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDummy, -+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAIndexStreamMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if (eError != PVRSRV_OK) -+ { -+ bLookupFailed = IMG_TRUE; -+ } -+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDummy, -+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPDSMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if (eError != PVRSRV_OK) -+ { -+ bLookupFailed = IMG_TRUE; -+ } -+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDummy, -+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAUSEMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if (eError != PVRSRV_OK) -+ { -+ bLookupFailed = IMG_TRUE; -+ } -+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDummy, -+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAParamMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if (eError != PVRSRV_OK) -+ { -+ bLookupFailed = IMG_TRUE; -+ } -+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDummy, -+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPMPTMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if (eError != PVRSRV_OK) -+ { -+ bLookupFailed = IMG_TRUE; -+ } -+ -+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDummy, -+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWATPCMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if (eError != PVRSRV_OK) -+ { -+ bLookupFailed = IMG_TRUE; -+ } -+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDummy, -+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPSGRgnHdrMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if (eError != PVRSRV_OK) -+ { -+ bLookupFailed = IMG_TRUE; -+ } -+#endif -+ -+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && \ -+ defined(FIX_HW_BRN_33657) && defined(SUPPORT_SECURE_33657_FIX) -+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDummy, -+ psSGXDevInitPart2IN->sInitInfo.hKernelVDMStateUpdateBufferMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if (eError != PVRSRV_OK) -+ { -+ bLookupFailed = IMG_TRUE; -+ } -+#endif -+ -+#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG) -+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDummy, -+ psSGXDevInitPart2IN->sInitInfo.hKernelEDMStatusBufferMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if (eError != PVRSRV_OK) -+ { -+ bLookupFailed = IMG_TRUE; -+ } -+#endif -+ -+ for (i = 0; i < SGX_MAX_INIT_MEM_HANDLES; i++) -+ { -+ IMG_HANDLE hHandle = psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i]; -+ -+ if (hHandle == IMG_NULL) -+ { -+ continue; -+ } -+ -+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDummy, -+ hHandle, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if (eError != PVRSRV_OK) -+ { -+ bLookupFailed = IMG_TRUE; -+ } -+ } -+ -+ if (bLookupFailed) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SGXDevInitPart2BW: A handle lookup failed")); -+ psSGXDevInitPart2OUT->eError = PVRSRV_ERROR_INIT2_PHASE_FAILED; -+ return 0; -+ } -+ -+ /* Lookup and release the device memory handles */ -+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, -+ &psSGXDevInitPart2IN->sInitInfo.hKernelCCBMemInfo, -+ psSGXDevInitPart2IN->sInitInfo.hKernelCCBMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if (eError != PVRSRV_OK) -+ { -+ bReleaseFailed = IMG_TRUE; -+ } -+ -+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, -+ &psSGXDevInitPart2IN->sInitInfo.hKernelCCBCtlMemInfo, -+ psSGXDevInitPart2IN->sInitInfo.hKernelCCBCtlMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if (eError != PVRSRV_OK) -+ { -+ bReleaseFailed = IMG_TRUE; -+ } -+ -+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, -+ &psSGXDevInitPart2IN->sInitInfo.hKernelCCBEventKickerMemInfo, -+ psSGXDevInitPart2IN->sInitInfo.hKernelCCBEventKickerMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if (eError != PVRSRV_OK) -+ { -+ bReleaseFailed = IMG_TRUE; -+ } -+ -+ -+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, -+ &psSGXDevInitPart2IN->sInitInfo.hKernelSGXHostCtlMemInfo, -+ psSGXDevInitPart2IN->sInitInfo.hKernelSGXHostCtlMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if (eError != PVRSRV_OK) -+ { -+ bReleaseFailed = IMG_TRUE; -+ } -+ -+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, -+ &psSGXDevInitPart2IN->sInitInfo.hKernelSGXTA3DCtlMemInfo, -+ psSGXDevInitPart2IN->sInitInfo.hKernelSGXTA3DCtlMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if (eError != PVRSRV_OK) -+ { -+ bReleaseFailed = IMG_TRUE; -+ } -+ -+#if defined(FIX_HW_BRN_31272) || defined(FIX_HW_BRN_31780) || defined(FIX_HW_BRN_33920) -+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, -+ &psSGXDevInitPart2IN->sInitInfo.hKernelSGXPTLAWriteBackMemInfo, -+ psSGXDevInitPart2IN->sInitInfo.hKernelSGXPTLAWriteBackMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if (eError != PVRSRV_OK) -+ { -+ bReleaseFailed = IMG_TRUE; -+ } -+#endif -+ -+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, -+ &psSGXDevInitPart2IN->sInitInfo.hKernelSGXMiscMemInfo, -+ psSGXDevInitPart2IN->sInitInfo.hKernelSGXMiscMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if (eError != PVRSRV_OK) -+ { -+ bReleaseFailed = IMG_TRUE; -+ } -+ -+ -+#if defined(SGX_SUPPORT_HWPROFILING) -+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, -+ &psSGXDevInitPart2IN->sInitInfo.hKernelHWProfilingMemInfo, -+ psSGXDevInitPart2IN->sInitInfo.hKernelHWProfilingMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if (eError != PVRSRV_OK) -+ { -+ bReleaseFailed = IMG_TRUE; -+ } -+#endif -+ -+#if defined(SUPPORT_SGX_HWPERF) -+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, -+ &psSGXDevInitPart2IN->sInitInfo.hKernelHWPerfCBMemInfo, -+ psSGXDevInitPart2IN->sInitInfo.hKernelHWPerfCBMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if (eError != PVRSRV_OK) -+ { -+ bReleaseFailed = IMG_TRUE; -+ } -+#endif -+ -+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, -+ &psSGXDevInitPart2IN->sInitInfo.hKernelTASigBufferMemInfo, -+ psSGXDevInitPart2IN->sInitInfo.hKernelTASigBufferMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if (eError != PVRSRV_OK) -+ { -+ bReleaseFailed = IMG_TRUE; -+ } -+ -+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, -+ &psSGXDevInitPart2IN->sInitInfo.hKernel3DSigBufferMemInfo, -+ psSGXDevInitPart2IN->sInitInfo.hKernel3DSigBufferMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if (eError != PVRSRV_OK) -+ { -+ bReleaseFailed = IMG_TRUE; -+ } -+ -+ -+#if defined(FIX_HW_BRN_31542) || defined(FIX_HW_BRN_36513) -+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, -+ &psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAVDMStreamMemInfo, -+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAVDMStreamMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if (eError != PVRSRV_OK) -+ { -+ bReleaseFailed = IMG_TRUE; -+ } -+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, -+ &psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAIndexStreamMemInfo, -+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAIndexStreamMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if (eError != PVRSRV_OK) -+ { -+ bReleaseFailed = IMG_TRUE; -+ } -+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, -+ &psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPDSMemInfo, -+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPDSMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if (eError != PVRSRV_OK) -+ { -+ bReleaseFailed = IMG_TRUE; -+ } -+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, -+ &psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAUSEMemInfo, -+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAUSEMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if (eError != PVRSRV_OK) -+ { -+ bReleaseFailed = IMG_TRUE; -+ } -+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, -+ &psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAParamMemInfo, -+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAParamMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if (eError != PVRSRV_OK) -+ { -+ bReleaseFailed = IMG_TRUE; -+ } -+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, -+ &psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPMPTMemInfo, -+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPMPTMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if (eError != PVRSRV_OK) -+ { -+ bReleaseFailed = IMG_TRUE; -+ } -+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, -+ &psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWATPCMemInfo, -+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWATPCMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if (eError != PVRSRV_OK) -+ { -+ bReleaseFailed = IMG_TRUE; -+ } -+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, -+ &psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPSGRgnHdrMemInfo, -+ psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPSGRgnHdrMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if (eError != PVRSRV_OK) -+ { -+ bReleaseFailed = IMG_TRUE; -+ } -+#endif -+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && \ -+ defined(FIX_HW_BRN_33657) && defined(SUPPORT_SECURE_33657_FIX) -+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, -+ &psSGXDevInitPart2IN->sInitInfo.hKernelVDMStateUpdateBufferMemInfo, -+ psSGXDevInitPart2IN->sInitInfo.hKernelVDMStateUpdateBufferMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if (eError != PVRSRV_OK) -+ { -+ bReleaseFailed = IMG_TRUE; -+ } -+#endif -+ -+#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG) -+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, -+ &psSGXDevInitPart2IN->sInitInfo.hKernelEDMStatusBufferMemInfo, -+ psSGXDevInitPart2IN->sInitInfo.hKernelEDMStatusBufferMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if (eError != PVRSRV_OK) -+ { -+ bReleaseFailed = IMG_TRUE; -+ } -+#endif -+ -+ for (i = 0; i < SGX_MAX_INIT_MEM_HANDLES; i++) -+ { -+ IMG_HANDLE *phHandle = &psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i]; -+ -+ if (*phHandle == IMG_NULL) -+ continue; -+ -+ eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase, -+ phHandle, -+ *phHandle, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if (eError != PVRSRV_OK) -+ { -+ bReleaseFailed = IMG_TRUE; -+ } -+ } -+ -+ if (bReleaseFailed) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SGXDevInitPart2BW: A handle release failed")); -+ psSGXDevInitPart2OUT->eError = PVRSRV_ERROR_INIT2_PHASE_FAILED; -+ /* -+ * Given that we checked the handles before release, a release -+ * failure is unexpected. -+ */ -+ PVR_DBG_BREAK; -+ return 0; -+ } -+ -+ /* Dissociate device memory from caller */ -+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelCCBMemInfo); -+ if (eError != PVRSRV_OK) -+ { -+ bDissociateFailed = IMG_TRUE; -+ } -+ -+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelCCBCtlMemInfo); -+ if (eError != PVRSRV_OK) -+ { -+ bDissociateFailed = IMG_TRUE; -+ } -+ -+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelCCBEventKickerMemInfo); -+ if (eError != PVRSRV_OK) -+ { -+ bDissociateFailed = IMG_TRUE; -+ } -+ -+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXHostCtlMemInfo); -+ if (eError != PVRSRV_OK) -+ { -+ bDissociateFailed = IMG_TRUE; -+ } -+ -+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXTA3DCtlMemInfo); -+ if (eError != PVRSRV_OK) -+ { -+ bDissociateFailed = IMG_TRUE; -+ } -+ -+#if defined(FIX_HW_BRN_31272) || defined(FIX_HW_BRN_31780) || defined(FIX_HW_BRN_33920) -+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXPTLAWriteBackMemInfo); -+ if (eError != PVRSRV_OK) -+ { -+ bDissociateFailed = IMG_TRUE; -+ } -+#endif -+ -+ /* Dissociate SGX MiscInfo buffer from user space */ -+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXMiscMemInfo); -+ if (eError != PVRSRV_OK) -+ { -+ bDissociateFailed = IMG_TRUE; -+ } -+ -+ -+#if defined(SGX_SUPPORT_HWPROFILING) -+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelHWProfilingMemInfo); -+ bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK); -+#endif -+ -+#if defined(SUPPORT_SGX_HWPERF) -+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelHWPerfCBMemInfo); -+ if (eError != PVRSRV_OK) -+ { -+ bDissociateFailed = IMG_TRUE; -+ } -+#endif -+ -+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelTASigBufferMemInfo); -+ if (eError != PVRSRV_OK) -+ { -+ bDissociateFailed = IMG_TRUE; -+ } -+ -+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernel3DSigBufferMemInfo); -+ if (eError != PVRSRV_OK) -+ { -+ bDissociateFailed = IMG_TRUE; -+ } -+ -+#if defined(FIX_HW_BRN_31542) || defined(FIX_HW_BRN_36513) -+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAVDMStreamMemInfo); -+ bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK); -+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAIndexStreamMemInfo); -+ bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK); -+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPDSMemInfo); -+ bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK); -+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAUSEMemInfo); -+ bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK); -+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAParamMemInfo); -+ bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK); -+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPMPTMemInfo); -+ bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK); -+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWATPCMemInfo); -+ bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK); -+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelClearClipWAPSGRgnHdrMemInfo); -+ bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK); -+#endif -+ -+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && \ -+ defined(FIX_HW_BRN_33657) && defined(SUPPORT_SECURE_33657_FIX) -+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelVDMStateUpdateBufferMemInfo); -+ bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK); -+#endif -+ -+#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG) -+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelEDMStatusBufferMemInfo); -+ bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK); -+#endif -+ -+ for (i = 0; i < SGX_MAX_INIT_MEM_HANDLES; i++) -+ { -+ IMG_HANDLE hHandle = psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i]; -+ -+ if (hHandle == IMG_NULL) -+ continue; -+ -+ eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, hHandle); -+ if (eError != PVRSRV_OK) -+ { -+ bDissociateFailed = IMG_TRUE; -+ } -+ } -+ -+ /* If any dissociations failed, free all the device memory passed in */ -+ if(bDissociateFailed) -+ { -+ PVRSRVFreeDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelCCBMemInfo); -+ PVRSRVFreeDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelCCBCtlMemInfo); -+ PVRSRVFreeDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXHostCtlMemInfo); -+ PVRSRVFreeDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXTA3DCtlMemInfo); -+#if defined(FIX_HW_BRN_31272) || defined(FIX_HW_BRN_31780) || defined(FIX_HW_BRN_33920) -+ PVRSRVFreeDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXPTLAWriteBackMemInfo); -+#endif -+ PVRSRVFreeDeviceMemKM(hDevCookieInt, psSGXDevInitPart2IN->sInitInfo.hKernelSGXMiscMemInfo); -+ -+ for (i = 0; i < SGX_MAX_INIT_MEM_HANDLES; i++) -+ { -+ IMG_HANDLE hHandle = psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i]; -+ -+ if (hHandle == IMG_NULL) -+ continue; -+ -+ PVRSRVFreeDeviceMemKM(hDevCookieInt, (PVRSRV_KERNEL_MEM_INFO *)hHandle); -+ -+ } -+ -+ PVR_DPF((PVR_DBG_ERROR, "SGXDevInitPart2BW: A dissociate failed")); -+ -+ psSGXDevInitPart2OUT->eError = PVRSRV_ERROR_INIT2_PHASE_FAILED; -+ -+ /* A dissociation failure is unexpected */ -+ PVR_DBG_BREAK; -+ return 0; -+ } -+ -+ psSGXDevInitPart2OUT->eError = -+ DevInitSGXPart2KM(psPerProc, -+ hDevCookieInt, -+ &psSGXDevInitPart2IN->sInitInfo); -+ -+ return 0; -+} -+ -+ -+static IMG_INT -+SGXRegisterHWRenderContextBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_RENDER_CONTEXT *psSGXRegHWRenderContextIN, -+ PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_RENDER_CONTEXT *psSGXRegHWRenderContextOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_HANDLE hDevCookieInt; -+// PVRSRV_SGXDEV_INFO *psDevInfo; -+ IMG_HANDLE hHWRenderContextInt; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_REGISTER_HW_RENDER_CONTEXT); -+ -+ NEW_HANDLE_BATCH_OR_ERROR(psSGXRegHWRenderContextOUT->eError, psPerProc, 1); -+ -+ psSGXRegHWRenderContextOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDevCookieInt, -+ psSGXRegHWRenderContextIN->hDevCookie, -+ PVRSRV_HANDLE_TYPE_DEV_NODE); -+ if(psSGXRegHWRenderContextOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ hHWRenderContextInt = -+ SGXRegisterHWRenderContextKM(hDevCookieInt, -+ psSGXRegHWRenderContextIN->pHWRenderContextCpuVAddr, -+ psSGXRegHWRenderContextIN->ui32HWRenderContextSize, -+ psSGXRegHWRenderContextIN->ui32OffsetToPDDevPAddr, -+ psSGXRegHWRenderContextIN->hDevMemContext, -+ &psSGXRegHWRenderContextOUT->sHWRenderContextDevVAddr, -+ psPerProc); -+ -+ if (hHWRenderContextInt == IMG_NULL) -+ { -+ psSGXRegHWRenderContextOUT->eError = PVRSRV_ERROR_UNABLE_TO_REGISTER_CONTEXT; -+ return 0; -+ } -+ -+ PVRSRVAllocHandleNR(psPerProc->psHandleBase, -+ &psSGXRegHWRenderContextOUT->hHWRenderContext, -+ hHWRenderContextInt, -+ PVRSRV_HANDLE_TYPE_SGX_HW_RENDER_CONTEXT, -+ PVRSRV_HANDLE_ALLOC_FLAG_NONE); -+ -+ COMMIT_HANDLE_BATCH_OR_ERROR(psSGXRegHWRenderContextOUT->eError, psPerProc); -+ -+ return 0; -+} -+ -+ -+static IMG_INT -+SGXUnregisterHWRenderContextBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_RENDER_CONTEXT *psSGXUnregHWRenderContextIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_HANDLE hHWRenderContextInt; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_UNREGISTER_HW_RENDER_CONTEXT); -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hHWRenderContextInt, -+ psSGXUnregHWRenderContextIN->hHWRenderContext, -+ PVRSRV_HANDLE_TYPE_SGX_HW_RENDER_CONTEXT); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = SGXUnregisterHWRenderContextKM(hHWRenderContextInt, -+ psSGXUnregHWRenderContextIN->bForceCleanup); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = -+ PVRSRVReleaseHandle(psPerProc->psHandleBase, -+ psSGXUnregHWRenderContextIN->hHWRenderContext, -+ PVRSRV_HANDLE_TYPE_SGX_HW_RENDER_CONTEXT); -+ -+ return 0; -+} -+ -+ -+static IMG_INT -+SGXRegisterHWTransferContextBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_TRANSFER_CONTEXT *psSGXRegHWTransferContextIN, -+ PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_TRANSFER_CONTEXT *psSGXRegHWTransferContextOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_HANDLE hDevCookieInt; -+ IMG_HANDLE hHWTransferContextInt; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_REGISTER_HW_TRANSFER_CONTEXT); -+ -+ NEW_HANDLE_BATCH_OR_ERROR(psSGXRegHWTransferContextOUT->eError, psPerProc, 1); -+ -+ psSGXRegHWTransferContextOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDevCookieInt, -+ psSGXRegHWTransferContextIN->hDevCookie, -+ PVRSRV_HANDLE_TYPE_DEV_NODE); -+ if(psSGXRegHWTransferContextOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ hHWTransferContextInt = -+ SGXRegisterHWTransferContextKM(hDevCookieInt, -+ psSGXRegHWTransferContextIN->pHWTransferContextCpuVAddr, -+ psSGXRegHWTransferContextIN->ui32HWTransferContextSize, -+ psSGXRegHWTransferContextIN->ui32OffsetToPDDevPAddr, -+ psSGXRegHWTransferContextIN->hDevMemContext, -+ &psSGXRegHWTransferContextOUT->sHWTransferContextDevVAddr, -+ psPerProc); -+ -+ if (hHWTransferContextInt == IMG_NULL) -+ { -+ psSGXRegHWTransferContextOUT->eError = PVRSRV_ERROR_UNABLE_TO_REGISTER_CONTEXT; -+ return 0; -+ } -+ -+ PVRSRVAllocHandleNR(psPerProc->psHandleBase, -+ &psSGXRegHWTransferContextOUT->hHWTransferContext, -+ hHWTransferContextInt, -+ PVRSRV_HANDLE_TYPE_SGX_HW_TRANSFER_CONTEXT, -+ PVRSRV_HANDLE_ALLOC_FLAG_NONE); -+ -+ COMMIT_HANDLE_BATCH_OR_ERROR(psSGXRegHWTransferContextOUT->eError, psPerProc); -+ -+ return 0; -+} -+ -+ -+static IMG_INT -+SGXUnregisterHWTransferContextBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_TRANSFER_CONTEXT *psSGXUnregHWTransferContextIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_HANDLE hHWTransferContextInt; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_UNREGISTER_HW_TRANSFER_CONTEXT); -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hHWTransferContextInt, -+ psSGXUnregHWTransferContextIN->hHWTransferContext, -+ PVRSRV_HANDLE_TYPE_SGX_HW_TRANSFER_CONTEXT); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = SGXUnregisterHWTransferContextKM(hHWTransferContextInt, -+ psSGXUnregHWTransferContextIN->bForceCleanup); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = -+ PVRSRVReleaseHandle(psPerProc->psHandleBase, -+ psSGXUnregHWTransferContextIN->hHWTransferContext, -+ PVRSRV_HANDLE_TYPE_SGX_HW_TRANSFER_CONTEXT); -+ -+ return 0; -+} -+ -+ -+#if defined(SGX_FEATURE_2D_HARDWARE) -+static IMG_INT -+SGXRegisterHW2DContextBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_2D_CONTEXT *psSGXRegHW2DContextIN, -+ PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_2D_CONTEXT *psSGXRegHW2DContextOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_HANDLE hDevCookieInt; -+ IMG_HANDLE hHW2DContextInt; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_REGISTER_HW_2D_CONTEXT); -+ -+ NEW_HANDLE_BATCH_OR_ERROR(psSGXRegHW2DContextOUT->eError, psPerProc, 1); -+ -+ psSGXRegHW2DContextOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDevCookieInt, -+ psSGXRegHW2DContextIN->hDevCookie, -+ PVRSRV_HANDLE_TYPE_DEV_NODE); -+ if(psSGXRegHW2DContextOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ hHW2DContextInt = -+ SGXRegisterHW2DContextKM(hDevCookieInt, -+ psSGXRegHW2DContextIN->pHW2DContextCpuVAddr, -+ psSGXRegHW2DContextIN->ui32HW2DContextSize, -+ psSGXRegHW2DContextIN->ui32OffsetToPDDevPAddr, -+ psSGXRegHW2DContextIN->hDevMemContext, -+ &psSGXRegHW2DContextOUT->sHW2DContextDevVAddr, -+ psPerProc); -+ -+ if (hHW2DContextInt == IMG_NULL) -+ { -+ psSGXRegHW2DContextOUT->eError = PVRSRV_ERROR_UNABLE_TO_REGISTER_CONTEXT; -+ return 0; -+ } -+ -+ PVRSRVAllocHandleNR(psPerProc->psHandleBase, -+ &psSGXRegHW2DContextOUT->hHW2DContext, -+ hHW2DContextInt, -+ PVRSRV_HANDLE_TYPE_SGX_HW_2D_CONTEXT, -+ PVRSRV_HANDLE_ALLOC_FLAG_NONE); -+ -+ COMMIT_HANDLE_BATCH_OR_ERROR(psSGXRegHW2DContextOUT->eError, psPerProc); -+ -+ return 0; -+} -+ -+ -+static IMG_INT -+SGXUnregisterHW2DContextBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_2D_CONTEXT *psSGXUnregHW2DContextIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_HANDLE hHW2DContextInt; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_UNREGISTER_HW_2D_CONTEXT); -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hHW2DContextInt, -+ psSGXUnregHW2DContextIN->hHW2DContext, -+ PVRSRV_HANDLE_TYPE_SGX_HW_2D_CONTEXT); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = SGXUnregisterHW2DContextKM(hHW2DContextInt, -+ psSGXUnregHW2DContextIN->bForceCleanup); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = -+ PVRSRVReleaseHandle(psPerProc->psHandleBase, -+ psSGXUnregHW2DContextIN->hHW2DContext, -+ PVRSRV_HANDLE_TYPE_SGX_HW_2D_CONTEXT); -+ -+ return 0; -+} -+#endif /* #if defined(SGX_FEATURE_2D_HARDWARE) */ -+ -+static IMG_INT -+SGXFlushHWRenderTargetBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_SGX_FLUSH_HW_RENDER_TARGET *psSGXFlushHWRenderTargetIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_HANDLE hDevCookieInt; -+// PVRSRV_SGXDEV_INFO *psDevInfo; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_FLUSH_HW_RENDER_TARGET); -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDevCookieInt, -+ psSGXFlushHWRenderTargetIN->hDevCookie, -+ PVRSRV_HANDLE_TYPE_DEV_NODE); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+// psDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookieInt)->pvDevice; -+ -+ psRetOUT->eError = SGXFlushHWRenderTargetKM(hDevCookieInt, psSGXFlushHWRenderTargetIN->sHWRTDataSetDevVAddr, IMG_FALSE); -+ -+ return 0; -+} -+ -+ -+static IMG_INT -+SGX2DQueryBlitsCompleteBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_2DQUERYBLTSCOMPLETE *ps2DQueryBltsCompleteIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_HANDLE hDevCookieInt; -+ IMG_VOID *pvSyncInfo; -+ PVRSRV_SGXDEV_INFO *psDevInfo; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_2DQUERYBLTSCOMPLETE); -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDevCookieInt, -+ ps2DQueryBltsCompleteIN->hDevCookie, -+ PVRSRV_HANDLE_TYPE_DEV_NODE); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &pvSyncInfo, -+ ps2DQueryBltsCompleteIN->hKernSyncInfo, -+ PVRSRV_HANDLE_TYPE_SYNC_INFO); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookieInt)->pvDevice; -+ -+ psRetOUT->eError = -+ SGX2DQueryBlitsCompleteKM(psDevInfo, -+ (PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo, -+ ps2DQueryBltsCompleteIN->bWaitForComplete); -+ -+ return 0; -+} -+ -+ -+static IMG_INT -+SGXFindSharedPBDescBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_SGXFINDSHAREDPBDESC *psSGXFindSharedPBDescIN, -+ PVRSRV_BRIDGE_OUT_SGXFINDSHAREDPBDESC *psSGXFindSharedPBDescOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_HANDLE hDevCookieInt; -+ PVRSRV_KERNEL_MEM_INFO *psSharedPBDescKernelMemInfo; -+ PVRSRV_KERNEL_MEM_INFO *psHWPBDescKernelMemInfo; -+ PVRSRV_KERNEL_MEM_INFO *psBlockKernelMemInfo; -+ PVRSRV_KERNEL_MEM_INFO *psHWBlockKernelMemInfo; -+ PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescSubKernelMemInfos = IMG_NULL; -+ IMG_UINT32 ui32SharedPBDescSubKernelMemInfosCount = 0; -+ IMG_UINT32 i; -+ IMG_HANDLE hSharedPBDesc = IMG_NULL; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC); -+ -+ NEW_HANDLE_BATCH_OR_ERROR(psSGXFindSharedPBDescOUT->eError, psPerProc, PVRSRV_BRIDGE_SGX_SHAREDPBDESC_MAX_SUBMEMINFOS + 4); -+ -+ psSGXFindSharedPBDescOUT->hSharedPBDesc = IMG_NULL; -+ -+ psSGXFindSharedPBDescOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDevCookieInt, -+ psSGXFindSharedPBDescIN->hDevCookie, -+ PVRSRV_HANDLE_TYPE_DEV_NODE); -+ if(psSGXFindSharedPBDescOUT->eError != PVRSRV_OK) -+ goto PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC_EXIT; -+ -+ psSGXFindSharedPBDescOUT->eError = -+ SGXFindSharedPBDescKM(psPerProc, hDevCookieInt, -+ psSGXFindSharedPBDescIN->bLockOnFailure, -+ psSGXFindSharedPBDescIN->ui32TotalPBSize, -+ &hSharedPBDesc, -+ &psSharedPBDescKernelMemInfo, -+ &psHWPBDescKernelMemInfo, -+ &psBlockKernelMemInfo, -+ &psHWBlockKernelMemInfo, -+ &ppsSharedPBDescSubKernelMemInfos, -+ &ui32SharedPBDescSubKernelMemInfosCount); -+ if(psSGXFindSharedPBDescOUT->eError != PVRSRV_OK) -+ goto PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC_EXIT; -+ -+ PVR_ASSERT(ui32SharedPBDescSubKernelMemInfosCount -+ <= PVRSRV_BRIDGE_SGX_SHAREDPBDESC_MAX_SUBMEMINFOS); -+ -+ psSGXFindSharedPBDescOUT->ui32SharedPBDescSubKernelMemInfoHandlesCount = -+ ui32SharedPBDescSubKernelMemInfosCount; -+ -+ if(hSharedPBDesc == IMG_NULL) -+ { -+ psSGXFindSharedPBDescOUT->hSharedPBDescKernelMemInfoHandle = 0; -+ /* It's not an error if we don't find a buffer, -+ * we just return NULL */ -+ goto PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC_EXIT; -+ } -+ -+ PVRSRVAllocHandleNR(psPerProc->psHandleBase, -+ &psSGXFindSharedPBDescOUT->hSharedPBDesc, -+ hSharedPBDesc, -+ PVRSRV_HANDLE_TYPE_SHARED_PB_DESC, -+ PVRSRV_HANDLE_ALLOC_FLAG_NONE); -+ -+ /* -+ * We allocate handles of type PVRSRV_HANDLE_TYPE_MEM_INFO_REF here, -+ * as the process doesn't own the underlying memory, and so should -+ * only be allowed a restricted set of operations on it, such as -+ * mapping it into its address space. -+ */ -+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, -+ &psSGXFindSharedPBDescOUT->hSharedPBDescKernelMemInfoHandle, -+ psSharedPBDescKernelMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO_REF, -+ PVRSRV_HANDLE_ALLOC_FLAG_MULTI, -+ psSGXFindSharedPBDescOUT->hSharedPBDesc); -+ -+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, -+ &psSGXFindSharedPBDescOUT->hHWPBDescKernelMemInfoHandle, -+ psHWPBDescKernelMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO_REF, -+ PVRSRV_HANDLE_ALLOC_FLAG_MULTI, -+ psSGXFindSharedPBDescOUT->hSharedPBDesc); -+ -+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, -+ &psSGXFindSharedPBDescOUT->hBlockKernelMemInfoHandle, -+ psBlockKernelMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO_REF, -+ PVRSRV_HANDLE_ALLOC_FLAG_MULTI, -+ psSGXFindSharedPBDescOUT->hSharedPBDesc); -+ -+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, -+ &psSGXFindSharedPBDescOUT->hHWBlockKernelMemInfoHandle, -+ psHWBlockKernelMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO_REF, -+ PVRSRV_HANDLE_ALLOC_FLAG_MULTI, -+ psSGXFindSharedPBDescOUT->hSharedPBDesc); -+ -+ -+ for(i=0; i<ui32SharedPBDescSubKernelMemInfosCount; i++) -+ { -+ PVRSRV_BRIDGE_OUT_SGXFINDSHAREDPBDESC *psSGXFindSharedPBDescOut = -+ psSGXFindSharedPBDescOUT; -+ -+ PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, -+ &psSGXFindSharedPBDescOut->ahSharedPBDescSubKernelMemInfoHandles[i], -+ ppsSharedPBDescSubKernelMemInfos[i], -+ PVRSRV_HANDLE_TYPE_MEM_INFO_REF, -+ PVRSRV_HANDLE_ALLOC_FLAG_MULTI, -+ psSGXFindSharedPBDescOUT->hSharedPBDescKernelMemInfoHandle); -+ } -+ -+PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC_EXIT: -+ if (ppsSharedPBDescSubKernelMemInfos != IMG_NULL) -+ { -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(PVRSRV_KERNEL_MEM_INFO *) * ui32SharedPBDescSubKernelMemInfosCount, -+ ppsSharedPBDescSubKernelMemInfos, -+ IMG_NULL); -+ } -+ -+ if(psSGXFindSharedPBDescOUT->eError != PVRSRV_OK) -+ { -+ if(hSharedPBDesc != IMG_NULL) -+ { -+ SGXUnrefSharedPBDescKM(hSharedPBDesc); -+ } -+ } -+ else -+ { -+ COMMIT_HANDLE_BATCH_OR_ERROR(psSGXFindSharedPBDescOUT->eError, psPerProc); -+ } -+ -+ return 0; -+} -+ -+ -+static IMG_INT -+SGXUnrefSharedPBDescBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_SGXUNREFSHAREDPBDESC *psSGXUnrefSharedPBDescIN, -+ PVRSRV_BRIDGE_OUT_SGXUNREFSHAREDPBDESC *psSGXUnrefSharedPBDescOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_HANDLE hSharedPBDesc; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_UNREFSHAREDPBDESC); -+ -+ psSGXUnrefSharedPBDescOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hSharedPBDesc, -+ psSGXUnrefSharedPBDescIN->hSharedPBDesc, -+ PVRSRV_HANDLE_TYPE_SHARED_PB_DESC); -+ if(psSGXUnrefSharedPBDescOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psSGXUnrefSharedPBDescOUT->eError = -+ SGXUnrefSharedPBDescKM(hSharedPBDesc); -+ -+ if(psSGXUnrefSharedPBDescOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psSGXUnrefSharedPBDescOUT->eError = -+ PVRSRVReleaseHandle(psPerProc->psHandleBase, -+ psSGXUnrefSharedPBDescIN->hSharedPBDesc, -+ PVRSRV_HANDLE_TYPE_SHARED_PB_DESC); -+ -+ return 0; -+} -+ -+ -+static IMG_INT -+SGXAddSharedPBDescBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_SGXADDSHAREDPBDESC *psSGXAddSharedPBDescIN, -+ PVRSRV_BRIDGE_OUT_SGXADDSHAREDPBDESC *psSGXAddSharedPBDescOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_HANDLE hDevCookieInt; -+ PVRSRV_KERNEL_MEM_INFO *psSharedPBDescKernelMemInfo; -+ PVRSRV_KERNEL_MEM_INFO *psHWPBDescKernelMemInfo; -+ PVRSRV_KERNEL_MEM_INFO *psBlockKernelMemInfo; -+ PVRSRV_KERNEL_MEM_INFO *psHWBlockKernelMemInfo; -+ IMG_UINT32 ui32KernelMemInfoHandlesCount = -+ psSGXAddSharedPBDescIN->ui32KernelMemInfoHandlesCount; -+ IMG_INT ret = 0; -+ IMG_HANDLE *phKernelMemInfoHandles = IMG_NULL; -+ PVRSRV_KERNEL_MEM_INFO **ppsKernelMemInfos = IMG_NULL; -+ IMG_UINT32 i; -+ PVRSRV_ERROR eError; -+ IMG_HANDLE hSharedPBDesc = IMG_NULL; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC); -+ -+ NEW_HANDLE_BATCH_OR_ERROR(psSGXAddSharedPBDescOUT->eError, psPerProc, 1); -+ -+ psSGXAddSharedPBDescOUT->hSharedPBDesc = IMG_NULL; -+ -+ PVR_ASSERT(ui32KernelMemInfoHandlesCount -+ <= PVRSRV_BRIDGE_SGX_SHAREDPBDESC_MAX_SUBMEMINFOS); -+ -+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDevCookieInt, -+ psSGXAddSharedPBDescIN->hDevCookie, -+ PVRSRV_HANDLE_TYPE_DEV_NODE); -+ if(eError != PVRSRV_OK) -+ { -+ goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT; -+ } -+ -+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ (IMG_VOID **)&psSharedPBDescKernelMemInfo, -+ psSGXAddSharedPBDescIN->hSharedPBDescKernelMemInfo, -+ PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO); -+ if(eError != PVRSRV_OK) -+ { -+ goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT; -+ } -+ -+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ (IMG_VOID **)&psHWPBDescKernelMemInfo, -+ psSGXAddSharedPBDescIN->hHWPBDescKernelMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if(eError != PVRSRV_OK) -+ { -+ goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT; -+ } -+ -+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ (IMG_VOID **)&psBlockKernelMemInfo, -+ psSGXAddSharedPBDescIN->hBlockKernelMemInfo, -+ PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO); -+ if(eError != PVRSRV_OK) -+ { -+ goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT; -+ } -+ -+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ (IMG_VOID **)&psHWBlockKernelMemInfo, -+ psSGXAddSharedPBDescIN->hHWBlockKernelMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if(eError != PVRSRV_OK) -+ { -+ goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT; -+ } -+ -+ -+ if(!OSAccessOK(PVR_VERIFY_READ, -+ psSGXAddSharedPBDescIN->phKernelMemInfoHandles, -+ ui32KernelMemInfoHandlesCount * sizeof(IMG_HANDLE))) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC:" -+ " Invalid phKernelMemInfos pointer", __FUNCTION__)); -+ ret = -EFAULT; -+ goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT; -+ } -+ -+ eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ ui32KernelMemInfoHandlesCount * sizeof(IMG_HANDLE), -+ (IMG_VOID **)&phKernelMemInfoHandles, -+ 0, -+ "Array of Handles"); -+ if (eError != PVRSRV_OK) -+ { -+ goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT; -+ } -+ -+ if(CopyFromUserWrapper(psPerProc, -+ ui32BridgeID, -+ phKernelMemInfoHandles, -+ psSGXAddSharedPBDescIN->phKernelMemInfoHandles, -+ ui32KernelMemInfoHandlesCount * sizeof(IMG_HANDLE)) -+ != PVRSRV_OK) -+ { -+ ret = -EFAULT; -+ goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT; -+ } -+ -+ eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ ui32KernelMemInfoHandlesCount * sizeof(PVRSRV_KERNEL_MEM_INFO *), -+ (IMG_VOID **)&ppsKernelMemInfos, -+ 0, -+ "Array of pointers to Kernel Memory Info"); -+ if (eError != PVRSRV_OK) -+ { -+ goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT; -+ } -+ -+ for(i=0; i<ui32KernelMemInfoHandlesCount; i++) -+ { -+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ (IMG_VOID **)&ppsKernelMemInfos[i], -+ phKernelMemInfoHandles[i], -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if(eError != PVRSRV_OK) -+ { -+ goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT; -+ } -+ } -+ -+ /* -+ * Release all the handles we've just looked up, as none -+ * of the associated resources will be valid for access via -+ * those handles once we return from SGXAddSharedPBDesc. -+ */ -+ /* PRQA S 3198 2 */ /* override redundant warning as PVR_ASSERT is ignored by QAC */ -+ eError = PVRSRVReleaseHandle(psPerProc->psHandleBase, -+ psSGXAddSharedPBDescIN->hSharedPBDescKernelMemInfo, -+ PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO); -+ PVR_ASSERT(eError == PVRSRV_OK); -+ -+ /* PRQA S 3198 2 */ /* override redundant warning as PVR_ASSERT is ignored by QAC */ -+ eError = PVRSRVReleaseHandle(psPerProc->psHandleBase, -+ psSGXAddSharedPBDescIN->hHWPBDescKernelMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ PVR_ASSERT(eError == PVRSRV_OK); -+ -+ /* PRQA S 3198 2 */ /* override redundant warning as PVR_ASSERT is ignored by QAC */ -+ eError = PVRSRVReleaseHandle(psPerProc->psHandleBase, -+ psSGXAddSharedPBDescIN->hBlockKernelMemInfo, -+ PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO); -+ PVR_ASSERT(eError == PVRSRV_OK); -+ -+ /* PRQA S 3198 2 */ /* override redundant warning as PVR_ASSERT is ignored by QAC */ -+ eError = PVRSRVReleaseHandle(psPerProc->psHandleBase, -+ psSGXAddSharedPBDescIN->hHWBlockKernelMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ PVR_ASSERT(eError == PVRSRV_OK); -+ -+ for(i=0; i<ui32KernelMemInfoHandlesCount; i++) -+ { -+ /* PRQA S 3198 2 */ /* override redundant warning as PVR_ASSERT is ignored by QAC */ -+ eError = PVRSRVReleaseHandle(psPerProc->psHandleBase, -+ phKernelMemInfoHandles[i], -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ PVR_ASSERT(eError == PVRSRV_OK); -+ } -+ -+ eError = SGXAddSharedPBDescKM(psPerProc, hDevCookieInt, -+ psSharedPBDescKernelMemInfo, -+ psHWPBDescKernelMemInfo, -+ psBlockKernelMemInfo, -+ psHWBlockKernelMemInfo, -+ psSGXAddSharedPBDescIN->ui32TotalPBSize, -+ &hSharedPBDesc, -+ ppsKernelMemInfos, -+ ui32KernelMemInfoHandlesCount, -+ psSGXAddSharedPBDescIN->sHWPBDescDevVAddr); -+ -+ -+ if (eError != PVRSRV_OK) -+ { -+ goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT; -+ } -+ -+ PVRSRVAllocHandleNR(psPerProc->psHandleBase, -+ &psSGXAddSharedPBDescOUT->hSharedPBDesc, -+ hSharedPBDesc, -+ PVRSRV_HANDLE_TYPE_SHARED_PB_DESC, -+ PVRSRV_HANDLE_ALLOC_FLAG_NONE); -+ -+PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT: -+ -+ if(phKernelMemInfoHandles) -+ { -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, -+ psSGXAddSharedPBDescIN->ui32KernelMemInfoHandlesCount * sizeof(IMG_HANDLE), -+ (IMG_VOID *)phKernelMemInfoHandles, -+ 0); -+ } -+ if(ppsKernelMemInfos) -+ { -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, -+ psSGXAddSharedPBDescIN->ui32KernelMemInfoHandlesCount * sizeof(PVRSRV_KERNEL_MEM_INFO *), -+ (IMG_VOID *)ppsKernelMemInfos, -+ 0); -+ } -+ -+ if(ret == 0 && eError == PVRSRV_OK) -+ { -+ COMMIT_HANDLE_BATCH_OR_ERROR(psSGXAddSharedPBDescOUT->eError, psPerProc); -+ } -+ -+ psSGXAddSharedPBDescOUT->eError = eError; -+ -+ return ret; -+} -+ -+static IMG_INT -+SGXGetInfoForSrvinitBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_SGXINFO_FOR_SRVINIT *psSGXInfoForSrvinitIN, -+ PVRSRV_BRIDGE_OUT_SGXINFO_FOR_SRVINIT *psSGXInfoForSrvinitOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_HANDLE hDevCookieInt; -+ IMG_UINT32 i; -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGXINFO_FOR_SRVINIT); -+ -+ NEW_HANDLE_BATCH_OR_ERROR(psSGXInfoForSrvinitOUT->eError, psPerProc, PVRSRV_MAX_CLIENT_HEAPS); -+ -+ if(!psPerProc->bInitProcess) -+ { -+ psSGXInfoForSrvinitOUT->eError = PVRSRV_ERROR_PROCESS_NOT_INITIALISED; -+ return 0; -+ } -+ -+ psSGXInfoForSrvinitOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt, -+ psSGXInfoForSrvinitIN->hDevCookie, -+ PVRSRV_HANDLE_TYPE_DEV_NODE); -+ -+ if(psSGXInfoForSrvinitOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psSGXInfoForSrvinitOUT->eError = -+ SGXGetInfoForSrvinitKM(hDevCookieInt, -+ &psSGXInfoForSrvinitOUT->sInitInfo); -+ -+ if(psSGXInfoForSrvinitOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ for(i = 0; i < PVRSRV_MAX_CLIENT_HEAPS; i++) -+ { -+ PVRSRV_HEAP_INFO *psHeapInfo; -+ -+ psHeapInfo = &psSGXInfoForSrvinitOUT->sInitInfo.asHeapInfo[i]; -+ -+ if (psHeapInfo->ui32HeapID != (IMG_UINT32)SGX_UNDEFINED_HEAP_ID) -+ { -+ IMG_HANDLE hDevMemHeapExt; -+ -+ if (psHeapInfo->hDevMemHeap != IMG_NULL) -+ { -+ /* Allocate heap handle */ -+ PVRSRVAllocHandleNR(psPerProc->psHandleBase, -+ &hDevMemHeapExt, -+ psHeapInfo->hDevMemHeap, -+ PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP, -+ PVRSRV_HANDLE_ALLOC_FLAG_SHARED); -+ psHeapInfo->hDevMemHeap = hDevMemHeapExt; -+ } -+ } -+ } -+ -+ COMMIT_HANDLE_BATCH_OR_ERROR(psSGXInfoForSrvinitOUT->eError, psPerProc); -+ -+ return 0; -+} -+ -+#if defined(PDUMP) -+// PRQA S 5120++ -+/***************************************************************************** -+ FUNCTION : DumpBufferArray -+ PURPOSE : PDUMP information in stored buffer array -+ PARAMETERS : -+ RETURNS : -+*****************************************************************************/ -+static IMG_VOID -+DumpBufferArray(PVRSRV_PER_PROCESS_DATA *psPerProc, -+ PSGX_KICKTA_DUMP_BUFFER psBufferArray, -+ IMG_UINT32 ui32BufferArrayLength, -+ IMG_BOOL bDumpPolls) -+{ -+ IMG_UINT32 i; -+ -+ for (i=0; i<ui32BufferArrayLength; i++) -+ { -+ PSGX_KICKTA_DUMP_BUFFER psBuffer; -+ PVRSRV_KERNEL_MEM_INFO *psCtrlMemInfoKM; -+ IMG_CHAR * pszName; -+ IMG_HANDLE hUniqueTag; -+ IMG_UINT32 ui32Offset; -+ -+ psBuffer = &psBufferArray[i]; -+ pszName = psBuffer->pszName; -+ if (!pszName) -+ { -+ pszName = "Nameless buffer"; -+ } -+ -+ hUniqueTag = MAKEUNIQUETAG((PVRSRV_KERNEL_MEM_INFO *)psBuffer->hKernelMemInfo); -+ -+ #if defined(SUPPORT_SGX_NEW_STATUS_VALS) -+ psCtrlMemInfoKM = ((PVRSRV_KERNEL_MEM_INFO *)psBuffer->hCtrlKernelMemInfo); -+ ui32Offset = psBuffer->sCtrlDevVAddr.uiAddr - psCtrlMemInfoKM->sDevVAddr.uiAddr; -+ #else -+ psCtrlMemInfoKM = ((PVRSRV_KERNEL_MEM_INFO *)psBuffer->hKernelMemInfo)->psKernelSyncInfo->psSyncDataMemInfoKM; -+ ui32Offset = offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete); -+ #endif -+ -+ if (psBuffer->ui32Start <= psBuffer->ui32End) -+ { -+ if (bDumpPolls) -+ { -+ PDUMPCOMMENTWITHFLAGS(0, "Wait for %s space\r\n", pszName); -+ PDUMPCBP(psCtrlMemInfoKM, -+ ui32Offset, -+ psBuffer->ui32Start, -+ psBuffer->ui32SpaceUsed, -+ psBuffer->ui32BufferSize, -+ 0, -+ MAKEUNIQUETAG(psCtrlMemInfoKM)); -+ } -+ -+ PDUMPCOMMENTWITHFLAGS(0, "%s\r\n", pszName); -+ PDUMPMEMUM(psPerProc, -+ IMG_NULL, -+ psBuffer->pvLinAddr, -+ (PVRSRV_KERNEL_MEM_INFO*)psBuffer->hKernelMemInfo, -+ psBuffer->ui32Start, -+ psBuffer->ui32End - psBuffer->ui32Start, -+ 0, -+ hUniqueTag); -+ } -+ else -+ { -+ /* -+ Range of data wraps the end of the buffer so it needs to be dumped in two sections -+ */ -+ -+ if (bDumpPolls) -+ { -+ PDUMPCOMMENTWITHFLAGS(0, "Wait for %s space\r\n", pszName); -+ PDUMPCBP(psCtrlMemInfoKM, -+ ui32Offset, -+ psBuffer->ui32Start, -+ psBuffer->ui32BackEndLength, -+ psBuffer->ui32BufferSize, -+ 0, -+ MAKEUNIQUETAG(psCtrlMemInfoKM)); -+ } -+ PDUMPCOMMENTWITHFLAGS(0, "%s (part 1)\r\n", pszName); -+ PDUMPMEMUM(psPerProc, -+ IMG_NULL, -+ psBuffer->pvLinAddr, -+ (PVRSRV_KERNEL_MEM_INFO*)psBuffer->hKernelMemInfo, -+ psBuffer->ui32Start, -+ psBuffer->ui32BackEndLength, -+ 0, -+ hUniqueTag); -+ -+ if (bDumpPolls) -+ { -+ PDUMPMEMPOL(psCtrlMemInfoKM, -+ ui32Offset, -+ 0, -+ 0xFFFFFFFF, -+ PDUMP_POLL_OPERATOR_NOTEQUAL, -+ 0, -+ MAKEUNIQUETAG(psCtrlMemInfoKM)); -+ -+ PDUMPCOMMENTWITHFLAGS(0, "Wait for %s space\r\n", pszName); -+ PDUMPCBP(psCtrlMemInfoKM, -+ ui32Offset, -+ 0, -+ psBuffer->ui32End, -+ psBuffer->ui32BufferSize, -+ 0, -+ MAKEUNIQUETAG(psCtrlMemInfoKM)); -+ } -+ PDUMPCOMMENTWITHFLAGS(0, "%s (part 2)\r\n", pszName); -+ PDUMPMEMUM(psPerProc, -+ IMG_NULL, -+ psBuffer->pvLinAddr, -+ (PVRSRV_KERNEL_MEM_INFO*)psBuffer->hKernelMemInfo, -+ 0, -+ psBuffer->ui32End, -+ 0, -+ hUniqueTag); -+ } -+ } -+} -+static IMG_INT -+SGXPDumpBufferArrayBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_PDUMP_BUFFER_ARRAY *psPDumpBufferArrayIN, -+ IMG_VOID *psBridgeOut, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_UINT32 i; -+#if defined(__QNXNTO__) -+ const IMG_UINT32 NAME_BUFFER_SIZE = 30; -+ IMG_PCHAR pszNameBuffer, pszName; -+ IMG_UINT32 ui32NameBufferArraySize, ui32NameLength; -+#endif -+ SGX_KICKTA_DUMP_BUFFER *psKickTADumpBuffer; -+ IMG_UINT32 ui32BufferArrayLength = -+ psPDumpBufferArrayIN->ui32BufferArrayLength; -+ IMG_UINT32 ui32BufferArraySize = -+ ui32BufferArrayLength * sizeof(SGX_KICKTA_DUMP_BUFFER); -+ PVRSRV_ERROR eError = PVRSRV_ERROR_TOO_FEW_BUFFERS; -+ -+ PVR_UNREFERENCED_PARAMETER(psBridgeOut); -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_PDUMP_BUFFER_ARRAY); -+ -+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ ui32BufferArraySize, -+ (IMG_PVOID *)&psKickTADumpBuffer, 0, -+ "Array of Kick Tile Accelerator Dump Buffer") != PVRSRV_OK) -+ { -+ return -ENOMEM; -+ } -+ -+ if(CopyFromUserWrapper(psPerProc, -+ ui32BridgeID, -+ psKickTADumpBuffer, -+ psPDumpBufferArrayIN->psBufferArray, -+ ui32BufferArraySize) != PVRSRV_OK) -+ { -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32BufferArraySize, psKickTADumpBuffer, 0); -+ /*not nulling pointer, out of scope*/ -+ return -EFAULT; -+ } -+ -+#if defined (__QNXNTO__) -+ ui32NameBufferArraySize = ui32BufferArrayLength * NAME_BUFFER_SIZE; -+ if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, ui32NameBufferArraySize, -+ (IMG_PVOID *)&pszNameBuffer, 0, -+ "Kick Tile Accelerator Dump Buffer names") != PVRSRV_OK) -+ { -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32BufferArraySize, psKickTADumpBuffer, 0); -+ return -ENOMEM; -+ } -+ -+ pszName = pszNameBuffer; -+ -+ for (i=0; i<ui32BufferArrayLength; i++) -+ { -+ if (psKickTADumpBuffer[i].pszName) -+ { -+ ui32NameLength = psKickTADumpBuffer[i].ui32NameLength; -+ if (ui32NameLength >= NAME_BUFFER_SIZE) -+ { -+ ui32NameLength = NAME_BUFFER_SIZE - 1; -+ } -+ -+ if (ui32NameLength && -+ (CopyFromUserWrapper(psPerProc, ui32BridgeID, pszName, -+ psKickTADumpBuffer[i].pszName, ui32NameLength + 1) == PVRSRV_OK)) -+ { -+ pszName[NAME_BUFFER_SIZE - 1] = 0; -+ psKickTADumpBuffer[i].pszName = pszName; -+ pszName += NAME_BUFFER_SIZE; -+ } -+ else -+ { -+ PVR_DPF((PVR_DBG_WARNING, "Failed to read PDUMP buffer name")); -+ psKickTADumpBuffer[i].pszName = 0; -+ } -+ } -+ } -+#endif -+ -+ for(i = 0; i < ui32BufferArrayLength; i++) -+ { -+ IMG_VOID *pvMemInfo; -+ -+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &pvMemInfo, -+ psKickTADumpBuffer[i].hKernelMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ -+ if(eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRV_BRIDGE_SGX_PDUMP_BUFFER_ARRAY: " -+ "PVRSRVLookupHandle failed (%d)", eError)); -+ break; -+ } -+ psKickTADumpBuffer[i].hKernelMemInfo = pvMemInfo; -+ -+#if defined(SUPPORT_SGX_NEW_STATUS_VALS) -+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &pvMemInfo, -+ psKickTADumpBuffer[i].hCtrlKernelMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ -+ if(eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRV_BRIDGE_SGX_PDUMP_BUFFER_ARRAY: " -+ "PVRSRVLookupHandle failed (%d)", eError)); -+ break; -+ } -+ psKickTADumpBuffer[i].hCtrlKernelMemInfo = pvMemInfo; -+#endif -+ -+ } -+ -+ if(eError == PVRSRV_OK) -+ { -+ DumpBufferArray(psPerProc, -+ psKickTADumpBuffer, -+ ui32BufferArrayLength, -+ psPDumpBufferArrayIN->bDumpPolls); -+ } -+ -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32BufferArraySize, psKickTADumpBuffer, 0); -+#if defined (__QNXNTO__) -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32NameBufferArraySize, pszNameBuffer, 0); -+#endif -+ /*not nulling pointer, out of scope*/ -+ -+ return 0; -+} -+ -+static IMG_INT -+SGXPDump3DSignatureRegistersBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_PDUMP_3D_SIGNATURE_REGISTERS *psPDump3DSignatureRegistersIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_UINT32 ui32RegisterArraySize = psPDump3DSignatureRegistersIN->ui32NumRegisters * sizeof(IMG_UINT32); -+ IMG_UINT32 *pui32Registers = IMG_NULL; -+ PVRSRV_SGXDEV_INFO *psDevInfo; -+#if defined(SGX_FEATURE_MP) && defined(FIX_HW_BRN_27270) -+ IMG_UINT32 ui32RegVal = 0; -+#endif -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+ IMG_HANDLE hDevMemContextInt = 0; -+ IMG_UINT32 ui32MMUContextID; -+ IMG_INT ret = -EFAULT; -+ -+ PVR_UNREFERENCED_PARAMETER(psRetOUT); -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_PDUMP_3D_SIGNATURE_REGISTERS); -+ -+ if (ui32RegisterArraySize == 0) -+ { -+ goto ExitNoError; -+ } -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ (IMG_VOID**)&psDeviceNode, -+ psPDump3DSignatureRegistersIN->hDevCookie, -+ PVRSRV_HANDLE_TYPE_DEV_NODE); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PDumpTASignatureRegistersBW: hDevCookie lookup failed")); -+ goto Exit; -+ } -+ -+ psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice; -+ -+#if defined(SGX_FEATURE_MP) && defined(FIX_HW_BRN_27270) -+ /* Enable all cores available */ -+ ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_CORE); -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_CORE, (SGX_FEATURE_MP_CORE_COUNT - 1) << EUR_CR_MASTER_CORE_ENABLE_SHIFT); -+#if defined(PDUMP) -+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_MASTER_CORE, (SGX_FEATURE_MP_CORE_COUNT - 1) << EUR_CR_MASTER_CORE_ENABLE_SHIFT, -+ psPDump3DSignatureRegistersIN->bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0); -+#endif -+#endif -+ -+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ ui32RegisterArraySize, -+ (IMG_PVOID *)&pui32Registers, 0, -+ "Array of Registers") != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PDump3DSignatureRegistersBW: OSAllocMem failed")); -+ goto Exit; -+ } -+ -+ if(CopyFromUserWrapper(psPerProc, -+ ui32BridgeID, -+ pui32Registers, -+ psPDump3DSignatureRegistersIN->pui32Registers, -+ ui32RegisterArraySize) != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PDump3DSignatureRegistersBW: CopyFromUserWrapper failed")); -+ goto Exit; -+ } -+ -+ PDump3DSignatureRegisters(&psDeviceNode->sDevId, -+ psPDump3DSignatureRegistersIN->ui32DumpFrameNum, -+ psPDump3DSignatureRegistersIN->bLastFrame, -+ pui32Registers, -+ psPDump3DSignatureRegistersIN->ui32NumRegisters); -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle( psPerProc->psHandleBase, -+ &hDevMemContextInt, -+ psPDump3DSignatureRegistersIN->hDevMemContext, -+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ /* look up the MMU context ID */ -+ PVR_ASSERT(psDeviceNode->pfnMMUGetContextID != IMG_NULL); -+ ui32MMUContextID = psDeviceNode->pfnMMUGetContextID((IMG_HANDLE)psDeviceNode->sDevMemoryInfo.pBMKernelContext); -+ -+ PDumpSignatureBuffer(&psDeviceNode->sDevId, -+ "out.tasig", "TA", 0, -+ psDevInfo->psKernelTASigBufferMemInfo->sDevVAddr, -+ (IMG_UINT32)psDevInfo->psKernelTASigBufferMemInfo->uAllocSize, -+ ui32MMUContextID, -+ 0 /*ui32PDumpFlags*/); -+ PDumpSignatureBuffer(&psDeviceNode->sDevId, -+ "out.3dsig", "3D", 0, -+ psDevInfo->psKernel3DSigBufferMemInfo->sDevVAddr, -+ (IMG_UINT32)psDevInfo->psKernel3DSigBufferMemInfo->uAllocSize, -+ ui32MMUContextID, -+ 0 /*ui32PDumpFlags*/); -+ -+ExitNoError: -+ psRetOUT->eError = PVRSRV_OK; -+ ret = 0; -+Exit: -+ if (pui32Registers != IMG_NULL) -+ { -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32RegisterArraySize, pui32Registers, 0); -+ } -+ -+#if defined(SGX_FEATURE_MP) && defined(FIX_HW_BRN_27270) -+ if (psDevInfo != IMG_NULL) -+ { -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_CORE, ui32RegVal); -+#if defined(PDUMP) -+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_MASTER_CORE, ui32RegVal, -+ psPDump3DSignatureRegistersIN->bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0); -+#endif -+ } -+#endif -+ -+ return ret; -+} -+ -+static IMG_INT -+SGXPDumpCounterRegistersBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_PDUMP_COUNTER_REGISTERS *psPDumpCounterRegistersIN, -+ IMG_VOID *psBridgeOut, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_UINT32 ui32RegisterArraySize = psPDumpCounterRegistersIN->ui32NumRegisters * sizeof(IMG_UINT32); -+ IMG_UINT32 *pui32Registers = IMG_NULL; -+ PVRSRV_DEVICE_NODE *psDeviceNode ; -+ IMG_INT ret = -EFAULT; -+ -+ PVR_UNREFERENCED_PARAMETER(psBridgeOut); -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_PDUMP_COUNTER_REGISTERS); -+ -+ if (ui32RegisterArraySize == 0) -+ { -+ goto ExitNoError; -+ } -+ -+ if(PVRSRVLookupHandle(psPerProc->psHandleBase, -+ (IMG_VOID**)&psDeviceNode, -+ psPDumpCounterRegistersIN->hDevCookie, -+ PVRSRV_HANDLE_TYPE_DEV_NODE) != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SGXPDumpCounterRegistersBW: hDevCookie lookup failed")); -+ ret = -ENOMEM; -+ goto Exit; -+ } -+ -+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ ui32RegisterArraySize, -+ (IMG_PVOID *)&pui32Registers, 0, -+ "Array of Registers") != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PDumpCounterRegistersBW: OSAllocMem failed")); -+ ret = -ENOMEM; -+ goto Exit; -+ } -+ -+ if(CopyFromUserWrapper(psPerProc, -+ ui32BridgeID, -+ pui32Registers, -+ psPDumpCounterRegistersIN->pui32Registers, -+ ui32RegisterArraySize) != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PDumpCounterRegistersBW: CopyFromUserWrapper failed")); -+ goto Exit; -+ } -+ -+ PDumpCounterRegisters(&psDeviceNode->sDevId, -+ psPDumpCounterRegistersIN->ui32DumpFrameNum, -+ psPDumpCounterRegistersIN->bLastFrame, -+ pui32Registers, -+ psPDumpCounterRegistersIN->ui32NumRegisters); -+ -+ExitNoError: -+ ret = 0; -+Exit: -+ if (pui32Registers != IMG_NULL) -+ { -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32RegisterArraySize, pui32Registers, 0); -+ } -+ -+ return ret; -+} -+ -+static IMG_INT -+SGXPDumpTASignatureRegistersBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_PDUMP_TA_SIGNATURE_REGISTERS *psPDumpTASignatureRegistersIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ IMG_UINT32 ui32RegisterArraySize = psPDumpTASignatureRegistersIN->ui32NumRegisters * sizeof(IMG_UINT32); -+ IMG_UINT32 *pui32Registers = IMG_NULL; -+#if defined(SGX_FEATURE_MP) && defined(FIX_HW_BRN_27270) -+ PVRSRV_SGXDEV_INFO *psDevInfo = IMG_NULL; -+ IMG_UINT32 ui32RegVal = 0; -+#endif -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+ IMG_INT ret = -EFAULT; -+ -+ PVR_UNREFERENCED_PARAMETER(psRetOUT); -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_PDUMP_TA_SIGNATURE_REGISTERS); -+ -+ if (ui32RegisterArraySize == 0) -+ { -+ goto ExitNoError; -+ } -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, (IMG_VOID**)&psDeviceNode, -+ psPDumpTASignatureRegistersIN->hDevCookie, -+ PVRSRV_HANDLE_TYPE_DEV_NODE); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PDumpTASignatureRegistersBW: hDevCookie lookup failed")); -+ goto Exit; -+ } -+ -+#if defined(SGX_FEATURE_MP) && defined(FIX_HW_BRN_27270) -+ -+ psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice; -+ -+ /* Enable all cores available */ -+ ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_CORE); -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_CORE, (SGX_FEATURE_MP_CORE_COUNT - 1) << EUR_CR_MASTER_CORE_ENABLE_SHIFT); -+#if defined(PDUMP) -+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_MASTER_CORE, (SGX_FEATURE_MP_CORE_COUNT - 1) << EUR_CR_MASTER_CORE_ENABLE_SHIFT, -+ psPDumpTASignatureRegistersIN->bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0); -+#endif -+#endif -+ -+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ ui32RegisterArraySize, -+ (IMG_PVOID *)&pui32Registers, 0, -+ "Array of Registers") != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PDumpTASignatureRegistersBW: OSAllocMem failed")); -+ ret = -ENOMEM; -+ goto Exit; -+ } -+ -+ if(CopyFromUserWrapper(psPerProc, -+ ui32BridgeID, -+ pui32Registers, -+ psPDumpTASignatureRegistersIN->pui32Registers, -+ ui32RegisterArraySize) != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PDumpTASignatureRegistersBW: CopyFromUserWrapper failed")); -+ goto Exit; -+ } -+ -+ PDumpTASignatureRegisters(&psDeviceNode->sDevId, -+ psPDumpTASignatureRegistersIN->ui32DumpFrameNum, -+ psPDumpTASignatureRegistersIN->ui32TAKickCount, -+ psPDumpTASignatureRegistersIN->bLastFrame, -+ pui32Registers, -+ psPDumpTASignatureRegistersIN->ui32NumRegisters); -+ -+ExitNoError: -+ psRetOUT->eError = PVRSRV_OK; -+ ret = 0; -+Exit: -+ if (pui32Registers != IMG_NULL) -+ { -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32RegisterArraySize, pui32Registers, 0); -+ } -+ -+#if defined(SGX_FEATURE_MP) && defined(FIX_HW_BRN_27270) -+ if (psDevInfo != IMG_NULL) -+ { -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_CORE, ui32RegVal); -+#if defined(PDUMP) -+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_MASTER_CORE, ui32RegVal, -+ psPDumpTASignatureRegistersIN->bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0); -+#endif -+ } -+#endif -+ -+ return ret; -+} -+//PRQA S 5120-- -+ -+ -+static IMG_INT -+SGXPDumpHWPerfCBBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_PDUMP_HWPERFCB *psPDumpHWPerfCBIN, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+#if defined(SUPPORT_SGX_HWPERF) -+#if defined(__linux__) || defined(__QNXNTO__) -+ PVRSRV_SGXDEV_INFO *psDevInfo; -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+ IMG_HANDLE hDevMemContextInt = 0; -+ IMG_UINT32 ui32MMUContextID = 0; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_PDUMP_HWPERFCB); -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, (IMG_VOID**)&psDeviceNode, -+ psPDumpHWPerfCBIN->hDevCookie, -+ PVRSRV_HANDLE_TYPE_DEV_NODE); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psDevInfo = psDeviceNode->pvDevice; -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle( psPerProc->psHandleBase, -+ &hDevMemContextInt, -+ psPDumpHWPerfCBIN->hDevMemContext, -+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ /* look up the MMU context ID */ -+ PVR_ASSERT(psDeviceNode->pfnMMUGetContextID != IMG_NULL); -+ ui32MMUContextID = psDeviceNode->pfnMMUGetContextID(hDevMemContextInt); -+ -+ PDumpHWPerfCBKM(&psDeviceNode->sDevId, -+ &psPDumpHWPerfCBIN->szFileName[0], -+ psPDumpHWPerfCBIN->ui32FileOffset, -+ psDevInfo->psKernelHWPerfCBMemInfo->sDevVAddr, -+ psDevInfo->psKernelHWPerfCBMemInfo->uAllocSize, -+ ui32MMUContextID, -+ psPDumpHWPerfCBIN->ui32PDumpFlags); -+ -+ return 0; -+#else -+ PVR_UNREFERENCED_PARAMETER(ui32BridgeID); -+ PVR_UNREFERENCED_PARAMETER(psPDumpHWPerfCBIN); -+ PVR_UNREFERENCED_PARAMETER(psRetOUT); -+ PVR_UNREFERENCED_PARAMETER(psPerProc); -+ return 0; -+#endif -+#else -+ PVR_UNREFERENCED_PARAMETER(ui32BridgeID); -+ PVR_UNREFERENCED_PARAMETER(psPDumpHWPerfCBIN); -+ PVR_UNREFERENCED_PARAMETER(psRetOUT); -+ PVR_UNREFERENCED_PARAMETER(psPerProc); -+ return -EFAULT; -+#endif /* defined(SUPPORT_SGX_HWPERF) */ -+} -+ -+ -+static IMG_INT -+SGXPDumpSaveMemBW(IMG_UINT32 ui32BridgeID, -+ PVRSRV_BRIDGE_IN_PDUMP_SAVEMEM *psPDumpSaveMem, -+ PVRSRV_BRIDGE_RETURN *psRetOUT, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+ IMG_HANDLE hDevMemContextInt = 0; -+ IMG_UINT32 ui32MMUContextID; -+ -+ PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_PDUMP_SAVEMEM); -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle(psPerProc->psHandleBase, -+ (IMG_VOID**)&psDeviceNode, -+ psPDumpSaveMem->hDevCookie, -+ PVRSRV_HANDLE_TYPE_DEV_NODE); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ psRetOUT->eError = -+ PVRSRVLookupHandle( psPerProc->psHandleBase, -+ &hDevMemContextInt, -+ psPDumpSaveMem->hDevMemContext, -+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT); -+ if(psRetOUT->eError != PVRSRV_OK) -+ { -+ return 0; -+ } -+ -+ /* look up the MMU context ID */ -+ PVR_ASSERT(psDeviceNode->pfnMMUGetContextID != IMG_NULL); -+ ui32MMUContextID = psDeviceNode->pfnMMUGetContextID(hDevMemContextInt); -+ -+ PDumpSaveMemKM(&psDeviceNode->sDevId, -+ &psPDumpSaveMem->szFileName[0], -+ psPDumpSaveMem->ui32FileOffset, -+ psPDumpSaveMem->sDevVAddr, -+ psPDumpSaveMem->ui32Size, -+ ui32MMUContextID, -+ psPDumpSaveMem->ui32PDumpFlags); -+ return 0; -+} -+ -+#endif /* PDUMP */ -+ -+ -+/* PRQA S 0313,3635 END_SET_SGX */ /* function macro required this format */ -+IMG_VOID SetSGXDispatchTableEntry(IMG_VOID) -+{ -+ -+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_GETCLIENTINFO, SGXGetClientInfoBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_RELEASECLIENTINFO, SGXReleaseClientInfoBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_GETINTERNALDEVINFO, SGXGetInternalDevInfoBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_DOKICK, SGXDoKickBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_GETPHYSPAGEADDR, DummyBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_READREGISTRYDWORD, DummyBW); -+ -+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_2DQUERYBLTSCOMPLETE, SGX2DQueryBlitsCompleteBW); -+ -+#if defined(TRANSFER_QUEUE) -+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_SUBMITTRANSFER, SGXSubmitTransferBW); -+#endif -+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_GETMISCINFO, SGXGetMiscInfoBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGXINFO_FOR_SRVINIT , SGXGetInfoForSrvinitBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_DEVINITPART2, SGXDevInitPart2BW); -+ -+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC, SGXFindSharedPBDescBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_UNREFSHAREDPBDESC, SGXUnrefSharedPBDescBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC, SGXAddSharedPBDescBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_REGISTER_HW_RENDER_CONTEXT, SGXRegisterHWRenderContextBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_FLUSH_HW_RENDER_TARGET, SGXFlushHWRenderTargetBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_UNREGISTER_HW_RENDER_CONTEXT, SGXUnregisterHWRenderContextBW); -+#if defined(SGX_FEATURE_2D_HARDWARE) -+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_SUBMIT2D, SGXSubmit2DBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_REGISTER_HW_2D_CONTEXT, SGXRegisterHW2DContextBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_UNREGISTER_HW_2D_CONTEXT, SGXUnregisterHW2DContextBW); -+#endif -+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_REGISTER_HW_TRANSFER_CONTEXT, SGXRegisterHWTransferContextBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_UNREGISTER_HW_TRANSFER_CONTEXT, SGXUnregisterHWTransferContextBW); -+ -+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_SCHEDULE_PROCESS_QUEUES, SGXScheduleProcessQueuesBW); -+ -+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_READ_HWPERF_CB, SGXReadHWPerfCBBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_SET_RENDER_CONTEXT_PRIORITY, SGXSetRenderContextPriorityBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_SET_TRANSFER_CONTEXT_PRIORITY, SGXSetTransferContextPriorityBW); -+ -+#if defined(PDUMP) -+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_PDUMP_BUFFER_ARRAY, SGXPDumpBufferArrayBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_PDUMP_3D_SIGNATURE_REGISTERS, SGXPDump3DSignatureRegistersBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_PDUMP_COUNTER_REGISTERS, SGXPDumpCounterRegistersBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_PDUMP_TA_SIGNATURE_REGISTERS, SGXPDumpTASignatureRegistersBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_PDUMP_HWPERFCB, SGXPDumpHWPerfCBBW); -+ SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_PDUMP_SAVEMEM, SGXPDumpSaveMemBW); -+#endif -+} -+/* PRQA L:END_SET_SGX */ /* end of setup overrides */ -+ -+#endif /* SUPPORT_SGX */ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/bridged/sgx/bridged_sgx_bridge.h b/drivers/staging/ti-es8-sgx/services4/srvkm/bridged/sgx/bridged_sgx_bridge.h -new file mode 100644 -index 0000000..3cb6282 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/bridged/sgx/bridged_sgx_bridge.h -@@ -0,0 +1,61 @@ -+/*************************************************************************/ /*! -+@Title SGX Bridge Functionality -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Header for the PVR Bridge code -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#ifndef __BRIDGED_SGX_BRIDGE_H__ -+#define __BRIDGED_SGX_BRIDGE_H__ -+ -+#if defined (__cplusplus) -+extern "C" { -+#endif -+ -+ -+IMG_VOID SetSGXDispatchTableEntry(IMG_VOID); -+ -+#if defined (__cplusplus) -+} -+#endif -+ -+#endif /* __BRIDGED_SGX_BRIDGE_H__ */ -+ -+/****************************************************************************** -+ End of file (bridged_sgx_bridge.h) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/common/buffer_manager.c b/drivers/staging/ti-es8-sgx/services4/srvkm/common/buffer_manager.c -new file mode 100644 -index 0000000..3a2efa3 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/common/buffer_manager.c -@@ -0,0 +1,3406 @@ -+/*************************************************************************/ /*! -+@Title Buffer management functions for Linux -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Manages buffers mapped into two memory spaces - cpu and device, -+ either of which can be virtual or physical. -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#include "services_headers.h" -+ -+#include "sysconfig.h" -+#include "hash.h" -+#include "ra.h" -+#include "pdump_km.h" -+#include "lists.h" -+ -+static IMG_BOOL -+ZeroBuf(BM_BUF *pBuf, BM_MAPPING *pMapping, IMG_SIZE_T uBytes, IMG_UINT32 ui32Flags); -+static IMG_VOID -+BM_FreeMemory (IMG_VOID *pH, IMG_UINTPTR_T base, BM_MAPPING *psMapping); -+static IMG_BOOL -+BM_ImportMemory(IMG_VOID *pH, IMG_SIZE_T uSize, -+ IMG_SIZE_T *pActualSize, BM_MAPPING **ppsMapping, -+ IMG_UINT32 ui32Flags, IMG_PVOID pvPrivData, -+ IMG_UINT32 ui32PrivDataLength, IMG_UINTPTR_T *pBase); -+ -+static IMG_BOOL -+DevMemoryAlloc (BM_CONTEXT *pBMContext, -+ BM_MAPPING *pMapping, -+ IMG_SIZE_T *pActualSize, -+ IMG_UINT32 ui32Flags, -+ IMG_UINT32 dev_vaddr_alignment, -+ IMG_DEV_VIRTADDR *pDevVAddr); -+static IMG_VOID -+DevMemoryFree (BM_MAPPING *pMapping); -+ -+/*! -+****************************************************************************** -+ -+ @Function AllocMemory -+ -+ @Description Allocate a buffer mapped into both cpu and device virtual -+ address spaces. This is now quite simple: -+ -+ 1. Choose whence to get the memory; -+ 2. Obtain memory from that source; -+ 3. Work out the actual buffer addresses in other spaces. -+ -+ In choosing whence to get the memory we work like this: -+ -+ 1. If an import arena exists, use unless BP_CONTIGUOUS is set; -+ 2. Use a contiguous pool. -+ -+ @Input pBMContext - BM context -+ @Input psBMHeap - BM heap -+ @Input psDevVAddr - device virtual address (optional) -+ @Input uSize - requested buffer size in bytes. -+ @Input ui32Flags - property flags for the buffer. -+ @Input uDevVAddrAlignment - required device virtual address -+ alignment, or 0. -+ @Input pvPrivData - opaque private data passed through to allocator -+ @Input ui32PrivDataLength - length of opaque private data -+ -+ @Output pBuf - receives a pointer to a descriptor of the allocated -+ buffer. -+ @Return IMG_TRUE - Success -+ IMG_FALSE - Failed. -+ -+ *****************************************************************************/ -+static IMG_BOOL -+AllocMemory (BM_CONTEXT *pBMContext, -+ BM_HEAP *psBMHeap, -+ IMG_DEV_VIRTADDR *psDevVAddr, -+ IMG_SIZE_T uSize, -+ IMG_UINT32 ui32Flags, -+ IMG_UINT32 uDevVAddrAlignment, -+ IMG_PVOID pvPrivData, -+ IMG_UINT32 ui32PrivDataLength, -+ IMG_UINT32 ui32ChunkSize, -+ IMG_UINT32 ui32NumVirtChunks, -+ IMG_UINT32 ui32NumPhysChunks, -+ IMG_BOOL *pabMapChunk, -+ BM_BUF *pBuf) -+{ -+ BM_MAPPING *pMapping; -+ IMG_UINTPTR_T uOffset; -+ RA_ARENA *pArena = IMG_NULL; -+ -+ PVR_DPF ((PVR_DBG_MESSAGE, -+ "AllocMemory (uSize=0x%" SIZE_T_FMT_LEN "x, ui32Flags=0x%x, align=0x%x)", -+ uSize, ui32Flags, uDevVAddrAlignment)); -+ -+ /* -+ what to do depends on combination of DevVaddr generation -+ and backing RAM requirement -+ */ -+ if(ui32Flags & PVRSRV_MEM_RAM_BACKED_ALLOCATION) -+ { -+ if(ui32Flags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR) -+ { -+ /* user supplied DevVAddr, RAM backing */ -+ PVR_DPF ((PVR_DBG_ERROR, "AllocMemory: combination of DevVAddr management and RAM backing mode unsupported")); -+ return IMG_FALSE; -+ } -+ -+ /* BM supplied DevVAddr, RAM Backing */ -+ -+ /* check heap attributes */ -+ if(psBMHeap->ui32Attribs -+ & (PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG -+ |PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG)) -+ { -+ /* specify arena (VM+RAM)*/ -+ pArena = psBMHeap->pImportArena; -+ PVR_ASSERT(psBMHeap->sDevArena.psDeviceMemoryHeapInfo->ui32Attribs & PVRSRV_MEM_RAM_BACKED_ALLOCATION); -+ } -+ else -+ { -+ PVR_DPF ((PVR_DBG_ERROR, "AllocMemory: backing store type doesn't match heap")); -+ return IMG_FALSE; -+ } -+ -+ /* Now allocate from the arena we chose above. */ -+ if (ui32Flags & PVRSRV_MEM_SPARSE) -+ { -+ IMG_BOOL bSuccess; -+ IMG_SIZE_T uActualSize; -+ -+ /* Allocate physcial memory */ -+ bSuccess = BM_ImportMemory(psBMHeap, -+ ui32ChunkSize * ui32NumPhysChunks, -+ &uActualSize, -+ &pMapping, -+ ui32Flags, -+ pvPrivData, -+ ui32PrivDataLength, -+ IMG_NULL); /* We allocate VM space */ -+ -+ if (!bSuccess) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "AllocMemory: BM_ImportMemory failed")); -+ return IMG_FALSE; -+ } -+ -+ if (uActualSize != ui32ChunkSize * ui32NumPhysChunks) -+ { -+ /* -+ Most likley the chunksize was not host page multiple so -+ return with an error -+ */ -+ PVR_DPF((PVR_DBG_ERROR, "AllocMemory: Failed to allocate memory for sparse allocation")); -+ BM_FreeMemory(pArena, IMG_NULL, pMapping); -+ return IMG_FALSE; -+ } -+ -+ pMapping->uSizeVM = ui32ChunkSize * ui32NumVirtChunks; -+ uSize = pMapping->uSizeVM; -+ pMapping->ui32ChunkSize = ui32ChunkSize; -+ pMapping->ui32NumVirtChunks = ui32NumVirtChunks; -+ pMapping->ui32NumPhysChunks = ui32NumPhysChunks; -+ pMapping->pabMapChunk = pabMapChunk; -+ -+ /* Allocate VA space and map in the physical memory */ -+ bSuccess = DevMemoryAlloc (pBMContext, -+ pMapping, -+ IMG_NULL, -+ ui32Flags, -+ uDevVAddrAlignment, -+ &pMapping->DevVAddr); -+ if (!bSuccess) -+ { -+ PVR_DPF((PVR_DBG_ERROR, -+ "AllocMemory: Failed to allocate device memory")); -+ BM_FreeMemory(pArena, IMG_NULL, pMapping); -+ return IMG_FALSE; -+ } -+ -+ /* uDevVAddrAlignment is currently set to zero so QAC generates warning which we override */ -+ /* PRQA S 3356,3358 1 */ -+ PVR_ASSERT (uDevVAddrAlignment>1?(pMapping->DevVAddr.uiAddr%uDevVAddrAlignment)==0:1); -+ pBuf->DevVAddr.uiAddr = pMapping->DevVAddr.uiAddr; -+ } -+ else -+ { -+ if (!RA_Alloc(pArena, -+ uSize, -+ IMG_NULL, -+ (IMG_VOID*) &pMapping, -+ ui32Flags, -+ uDevVAddrAlignment, -+ 0, -+ pvPrivData, -+ ui32PrivDataLength, -+ (IMG_UINTPTR_T *)&(pBuf->DevVAddr.uiAddr))) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "AllocMemory: RA_Alloc(0x%" SIZE_T_FMT_LEN "x) FAILED", uSize)); -+ return IMG_FALSE; -+ } -+ } -+ -+ uOffset = pBuf->DevVAddr.uiAddr - pMapping->DevVAddr.uiAddr; -+ if(pMapping->CpuVAddr) -+ { -+ pBuf->CpuVAddr = (IMG_VOID*) ((IMG_UINTPTR_T)pMapping->CpuVAddr + uOffset); -+ } -+ else -+ { -+ pBuf->CpuVAddr = IMG_NULL; -+ } -+ -+ if(uSize == pMapping->uSizeVM) -+ { -+ pBuf->hOSMemHandle = pMapping->hOSMemHandle; -+ } -+ else -+ { -+ if(OSGetSubMemHandle(pMapping->hOSMemHandle, -+ uOffset, -+ uSize, -+ psBMHeap->ui32Attribs, -+ &pBuf->hOSMemHandle)!=PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "AllocMemory: OSGetSubMemHandle FAILED")); -+ return IMG_FALSE; -+ } -+ } -+ -+ /* for hm_contiguous and hm_wrapped memory, the pMapping -+ * will have a physical address, else 0 */ -+ pBuf->CpuPAddr.uiAddr = pMapping->CpuPAddr.uiAddr + uOffset; -+ -+ if(ui32Flags & PVRSRV_MEM_ZERO) -+ { -+ if(!ZeroBuf(pBuf, pMapping, uSize, psBMHeap->ui32Attribs | ui32Flags)) -+ { -+ return IMG_FALSE; -+ } -+ } -+ } -+ else -+ { -+ if(ui32Flags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR) -+ { -+ /* user supplied DevVAddr, no RAM backing */ -+ PVR_ASSERT(psDevVAddr != IMG_NULL); -+ -+ if (psDevVAddr == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "AllocMemory: invalid parameter - psDevVAddr")); -+ return IMG_FALSE; -+ } -+ -+ /* just make space in the pagetables */ -+ pBMContext->psDeviceNode->pfnMMUAlloc (psBMHeap->pMMUHeap, -+ uSize, -+ IMG_NULL, -+ PVRSRV_MEM_USER_SUPPLIED_DEVVADDR, -+ uDevVAddrAlignment, -+ psDevVAddr); -+ -+ /* setup buf */ -+ pBuf->DevVAddr = *psDevVAddr; -+ } -+ else -+ { -+ IMG_BOOL bResult; -+ /* BM supplied DevVAddr, no RAM Backing */ -+ -+ /* just make space in the pagetables */ -+ bResult = pBMContext->psDeviceNode->pfnMMUAlloc (psBMHeap->pMMUHeap, -+ uSize, -+ IMG_NULL, -+ 0, -+ uDevVAddrAlignment, -+ &pBuf->DevVAddr); -+ -+ if(!bResult) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "AllocMemory: MMUAlloc failed")); -+ return IMG_FALSE; -+ } -+ } -+ -+ /* allocate a mocked-up mapping */ -+ if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof (struct _BM_MAPPING_), -+ (IMG_PVOID *)&pMapping, IMG_NULL, -+ "Buffer Manager Mapping") != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "AllocMemory: OSAllocMem(0x%" SIZE_T_FMT_LEN "x) FAILED", sizeof(*pMapping))); -+ return IMG_FALSE; -+ } -+ -+ /* setup buf */ -+ pBuf->CpuVAddr = IMG_NULL; -+ pBuf->hOSMemHandle = 0; -+ pBuf->CpuPAddr.uiAddr = 0; -+ -+ /* setup mapping */ -+ pMapping->CpuVAddr = IMG_NULL; -+ pMapping->CpuPAddr.uiAddr = 0; -+ pMapping->DevVAddr = pBuf->DevVAddr; -+ pMapping->psSysAddr = IMG_NULL; -+ pMapping->uSize = uSize; -+ pMapping->hOSMemHandle = 0; -+ } -+ -+ /* Record the arena pointer in the mapping. */ -+ pMapping->pArena = pArena; -+ -+ /* record the heap */ -+ pMapping->pBMHeap = psBMHeap; -+ pBuf->pMapping = pMapping; -+ -+ /* output some stats */ -+ PVR_DPF ((PVR_DBG_MESSAGE, -+ "AllocMemory: pMapping=%p: DevV=%08X CpuV=%p CpuP=" CPUPADDR_FMT " uSize=0x%" SIZE_T_FMT_LEN "x", -+ pMapping, -+ pMapping->DevVAddr.uiAddr, -+ pMapping->CpuVAddr, -+ pMapping->CpuPAddr.uiAddr, -+ pMapping->uSize)); -+ -+ PVR_DPF ((PVR_DBG_MESSAGE, -+ "AllocMemory: pBuf=%p: DevV=%08X CpuV=%p CpuP=" CPUPADDR_FMT " uSize=0x%" SIZE_T_FMT_LEN "x", -+ pBuf, -+ pBuf->DevVAddr.uiAddr, -+ pBuf->CpuVAddr, -+ pBuf->CpuPAddr.uiAddr, -+ uSize)); -+ -+ /* Verify virtual device address alignment */ -+ PVR_ASSERT(((pBuf->DevVAddr.uiAddr) & (uDevVAddrAlignment - 1)) == 0); -+ -+ return IMG_TRUE; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function WrapMemory -+ -+ @Description Allocate a buffer mapped into both cpu and device virtual -+ address spaces. -+ -+ @Input psBMHeap - BM heap -+ @Input uSize - requested buffer size in bytes. -+ @Input ui32BaseOffset - Offset from page of wrap. -+ @Input bPhysContig - Is the wrap physically contiguous. -+ @Input psAddr - List of pages to wrap. -+ @Input pvCPUVAddr - Optional CPU Kernel virtual address (page aligned) of memory to wrap -+ @Input ui32Flags - property flags for the buffer. -+ @Output Buf - receives a pointer to a descriptor of the allocated -+ buffer. -+ @Return IMG_TRUE - Success -+ IMG_FALSE - Failed. -+ -+ *****************************************************************************/ -+static IMG_BOOL -+WrapMemory (BM_HEAP *psBMHeap, -+ IMG_SIZE_T uSize, -+ IMG_SIZE_T uiBaseOffset, -+ IMG_BOOL bPhysContig, -+ IMG_SYS_PHYADDR *psAddr, -+ IMG_VOID *pvCPUVAddr, -+ IMG_UINT32 ui32Flags, -+ BM_BUF *pBuf) -+{ -+ IMG_DEV_VIRTADDR DevVAddr = {0}; -+ BM_MAPPING *pMapping; -+ IMG_BOOL bResult; -+ IMG_SIZE_T const uPageSize = HOST_PAGESIZE(); -+ /* We should not pass down R/W flags into the OS layers so create ui32Attribs */ -+ IMG_UINT32 ui32Attribs = ui32Flags & ~(PVRSRV_MEM_READ | PVRSRV_MEM_WRITE); -+ -+ PVR_DPF ((PVR_DBG_MESSAGE, -+ "WrapMemory(psBMHeap=%p, size=0x%" SIZE_T_FMT_LEN "x, offset=0x%" SIZE_T_FMT_LEN -+ "x, bPhysContig=0x%x, sysPAddr=0x" SYSPADDR_FMT ", pvCPUVAddr = 0x%p, flags=0x%x)", -+ psBMHeap, -+ uSize, -+ uiBaseOffset, -+ bPhysContig, -+ psAddr->uiAddr, -+ pvCPUVAddr, -+ ui32Flags)); -+ -+ PVR_ASSERT((psAddr->uiAddr & (uPageSize - 1)) == 0); -+ /* Only need lower 12 bits of the cpu addr - don't care what size a void* is */ -+ PVR_ASSERT(((IMG_UINTPTR_T)pvCPUVAddr & (uPageSize - 1)) == 0); -+ -+ uSize += uiBaseOffset; -+ uSize = HOST_PAGEALIGN (uSize); -+ -+ /* allocate a mocked-up mapping */ -+ if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(*pMapping), -+ (IMG_PVOID *)&pMapping, IMG_NULL, -+ "Mocked-up mapping") != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSAllocMem(0x%" SIZE_T_FMT_LEN "x) FAILED", sizeof(*pMapping))); -+ return IMG_FALSE; -+ } -+ -+ OSMemSet(pMapping, 0, sizeof (*pMapping)); -+ -+ pMapping->uSize = uSize; -+ pMapping->uSizeVM = uSize; -+ pMapping->pBMHeap = psBMHeap; -+ -+ if(pvCPUVAddr) -+ { -+ pMapping->CpuVAddr = pvCPUVAddr; -+ -+ if (bPhysContig) -+ { -+ pMapping->eCpuMemoryOrigin = hm_wrapped_virtaddr; -+ pMapping->CpuPAddr = SysSysPAddrToCpuPAddr(psAddr[0]); -+ -+ if(OSRegisterMem(pMapping->CpuPAddr, -+ pMapping->CpuVAddr, -+ pMapping->uSize, -+ ui32Attribs, -+ &pMapping->hOSMemHandle) != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSRegisterMem Phys=0x" CPUPADDR_FMT ", Size=%" SIZE_T_FMT_LEN "u) failed", -+ pMapping->CpuPAddr.uiAddr, pMapping->uSize)); -+ goto fail_cleanup; -+ } -+ } -+ else -+ { -+ pMapping->eCpuMemoryOrigin = hm_wrapped_scatter_virtaddr; -+ pMapping->psSysAddr = psAddr; -+ -+ if(OSRegisterDiscontigMem(pMapping->psSysAddr, -+ pMapping->CpuVAddr, -+ pMapping->uSize, -+ ui32Attribs, -+ &pMapping->hOSMemHandle) != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSRegisterDiscontigMem Size=0x%" SIZE_T_FMT_LEN "u) failed", -+ pMapping->uSize)); -+ goto fail_cleanup; -+ } -+ } -+ } -+ else -+ { -+ if (bPhysContig) -+ { -+ pMapping->eCpuMemoryOrigin = hm_wrapped; -+ pMapping->CpuPAddr = SysSysPAddrToCpuPAddr(psAddr[0]); -+ -+ if(OSReservePhys(pMapping->CpuPAddr, -+ pMapping->uSize, -+ ui32Attribs, -+ IMG_NULL, -+ &pMapping->CpuVAddr, -+ &pMapping->hOSMemHandle) != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSReservePhys Phys=0x" CPUPADDR_FMT ", Size=%" SIZE_T_FMT_LEN "u) failed", -+ pMapping->CpuPAddr.uiAddr, pMapping->uSize)); -+ goto fail_cleanup; -+ } -+ } -+ else -+ { -+ pMapping->eCpuMemoryOrigin = hm_wrapped_scatter; -+ pMapping->psSysAddr = psAddr; -+ -+ if(OSReserveDiscontigPhys(pMapping->psSysAddr, -+ pMapping->uSize, -+ ui32Attribs, -+ &pMapping->CpuVAddr, -+ &pMapping->hOSMemHandle) != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSReserveDiscontigPhys Size=%" SIZE_T_FMT_LEN "u) failed", -+ pMapping->uSize)); -+ goto fail_cleanup; -+ } -+ } -+ } -+ -+ /* -+ * Allocate device memory for this buffer. -+ */ -+ bResult = DevMemoryAlloc(psBMHeap->pBMContext, -+ pMapping, -+ IMG_NULL, -+ ui32Flags, -+ IMG_CAST_TO_DEVVADDR_UINT(uPageSize), -+ &DevVAddr); -+ if (!bResult) -+ { -+ PVR_DPF((PVR_DBG_ERROR, -+ "WrapMemory: DevMemoryAlloc(0x%" SIZE_T_FMT_LEN "x) failed", -+ pMapping->uSize)); -+ goto fail_cleanup; -+ } -+ -+ /* -+ * Determine the offset of this allocation within the underlying -+ * dual mapped chunk of memory, we can assume that all three -+ * addresses associated with this allocation are placed at the same -+ * offset within the underlying chunk. -+ */ -+ pBuf->CpuPAddr.uiAddr = pMapping->CpuPAddr.uiAddr + uiBaseOffset; -+ if(!uiBaseOffset) -+ { -+ pBuf->hOSMemHandle = pMapping->hOSMemHandle; -+ } -+ else -+ { -+ if(OSGetSubMemHandle(pMapping->hOSMemHandle, -+ uiBaseOffset, -+ (pMapping->uSize - uiBaseOffset), -+ ui32Attribs, -+ &pBuf->hOSMemHandle)!=PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSGetSubMemHandle failed")); -+ goto fail_cleanup; -+ } -+ } -+ if(pMapping->CpuVAddr) -+ { -+ pBuf->CpuVAddr = (IMG_VOID*) ((IMG_UINTPTR_T)pMapping->CpuVAddr + uiBaseOffset); -+ } -+ pBuf->DevVAddr.uiAddr = pMapping->DevVAddr.uiAddr + IMG_CAST_TO_DEVVADDR_UINT(uiBaseOffset); -+ -+ if(ui32Flags & PVRSRV_MEM_ZERO) -+ { -+ if(!ZeroBuf(pBuf, pMapping, uSize, ui32Flags)) -+ { -+ return IMG_FALSE; -+ } -+ } -+ -+ PVR_DPF ((PVR_DBG_MESSAGE, "DevVaddr.uiAddr=%08X", DevVAddr.uiAddr)); -+ PVR_DPF ((PVR_DBG_MESSAGE, -+ "WrapMemory: DevV=%08X CpuP=" CPUPADDR_FMT " uSize=0x%" SIZE_T_FMT_LEN "x", -+ pMapping->DevVAddr.uiAddr, pMapping->CpuPAddr.uiAddr, pMapping->uSize)); -+ PVR_DPF ((PVR_DBG_MESSAGE, -+ "WrapMemory: DevV=%08X CpuP=" CPUPADDR_FMT " uSize=0x%" SIZE_T_FMT_LEN "x", -+ pBuf->DevVAddr.uiAddr, pBuf->CpuPAddr.uiAddr, uSize)); -+ -+ pBuf->pMapping = pMapping; -+ return IMG_TRUE; -+ -+fail_cleanup: -+ if(uiBaseOffset && pBuf->hOSMemHandle) -+ { -+ OSReleaseSubMemHandle(pBuf->hOSMemHandle, ui32Attribs); -+ } -+ -+ if(pMapping && (pMapping->CpuVAddr || pMapping->hOSMemHandle)) -+ { -+ switch(pMapping->eCpuMemoryOrigin) -+ { -+ case hm_wrapped: -+ OSUnReservePhys(pMapping->CpuVAddr, pMapping->uSize, ui32Attribs, pMapping->hOSMemHandle); -+ break; -+ case hm_wrapped_virtaddr: -+ OSUnRegisterMem(pMapping->CpuVAddr, pMapping->uSize, ui32Attribs, pMapping->hOSMemHandle); -+ break; -+ case hm_wrapped_scatter: -+ OSUnReserveDiscontigPhys(pMapping->CpuVAddr, pMapping->uSize, ui32Attribs, pMapping->hOSMemHandle); -+ break; -+ case hm_wrapped_scatter_virtaddr: -+ OSUnRegisterDiscontigMem(pMapping->CpuVAddr, pMapping->uSize, ui32Attribs, pMapping->hOSMemHandle); -+ break; -+ default: -+ break; -+ } -+ -+ } -+ -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_MAPPING), pMapping, IMG_NULL); -+ /*not nulling pointer, out of scope*/ -+ -+ return IMG_FALSE; -+} -+ -+ -+static IMG_BOOL -+ZeroBuf(BM_BUF *pBuf, BM_MAPPING *pMapping, IMG_SIZE_T uBytes, IMG_UINT32 ui32Flags) -+{ -+ IMG_VOID *pvCpuVAddr; -+ -+ if(pBuf->CpuVAddr) -+ { -+ OSMemSet(pBuf->CpuVAddr, 0, uBytes); -+ } -+ else if(pMapping->eCpuMemoryOrigin == hm_contiguous -+ || pMapping->eCpuMemoryOrigin == hm_wrapped) -+ { -+ pvCpuVAddr = OSMapPhysToLin(pBuf->CpuPAddr, -+ uBytes, -+ PVRSRV_HAP_KERNEL_ONLY -+ | (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK), -+ IMG_NULL); -+ if(!pvCpuVAddr) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "ZeroBuf: OSMapPhysToLin for contiguous buffer failed")); -+ return IMG_FALSE; -+ } -+ OSMemSet(pvCpuVAddr, 0, uBytes); -+ OSUnMapPhysToLin(pvCpuVAddr, -+ uBytes, -+ PVRSRV_HAP_KERNEL_ONLY -+ | (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK), -+ IMG_NULL); -+ } -+ else -+ { -+ IMG_SIZE_T uBytesRemaining = uBytes; -+ IMG_SIZE_T uCurrentOffset = 0; -+ IMG_CPU_PHYADDR CpuPAddr; -+ -+ /* Walk through the pBuf one page at a time and use -+ * transient mappings to zero the memory */ -+ -+ PVR_ASSERT(pBuf->hOSMemHandle); -+ -+ while(uBytesRemaining > 0) -+ { -+ IMG_SIZE_T uBlockBytes = MIN(uBytesRemaining, HOST_PAGESIZE()); -+ CpuPAddr = OSMemHandleToCpuPAddr(pBuf->hOSMemHandle, uCurrentOffset); -+ /* If the CpuPAddr isn't page aligned then start by writing up to the next page -+ * boundary (or uBytesRemaining if less), so that subsequent iterations can -+ * copy full physical pages. */ -+ if(CpuPAddr.uiAddr & (HOST_PAGESIZE() -1)) -+ { -+ uBlockBytes = -+ MIN(uBytesRemaining, (IMG_UINT32)(HOST_PAGEALIGN(CpuPAddr.uiAddr) - CpuPAddr.uiAddr)); -+ } -+ -+ pvCpuVAddr = OSMapPhysToLin(CpuPAddr, -+ uBlockBytes, -+ PVRSRV_HAP_KERNEL_ONLY -+ | (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK), -+ IMG_NULL); -+ if(!pvCpuVAddr) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "ZeroBuf: OSMapPhysToLin while zeroing non-contiguous memory FAILED")); -+ return IMG_FALSE; -+ } -+ OSMemSet(pvCpuVAddr, 0, uBlockBytes); -+ OSUnMapPhysToLin(pvCpuVAddr, -+ uBlockBytes, -+ PVRSRV_HAP_KERNEL_ONLY -+ | (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK), -+ IMG_NULL); -+ -+ uBytesRemaining -= uBlockBytes; -+ uCurrentOffset += uBlockBytes; -+ } -+ } -+ -+ return IMG_TRUE; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function FreeBuf -+ -+ @Description Free a buffer previously allocated with BM_Alloc() or unwrap -+ one previous wrapped with BM_Wrap(). -+ The buffer is identified by the buffer descriptor pBuf -+ returned at allocation. Note the double indirection when -+ passing the buffer. -+ -+ -+ @Input pBuf - buffer descriptor to free. -+ @Input ui32Flags - flags -+ @Input bFromAllocator - Is this being called by the -+ allocator? -+ -+ @Return None. -+ -+ *****************************************************************************/ -+static IMG_VOID -+FreeBuf (BM_BUF *pBuf, IMG_UINT32 ui32Flags, IMG_BOOL bFromAllocator) -+{ -+ BM_MAPPING *pMapping; -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+ -+ PVR_DPF ((PVR_DBG_MESSAGE, -+ "FreeBuf: pBuf=0x%p: DevVAddr=%08X CpuVAddr=0x%p CpuPAddr=" CPUPADDR_FMT, -+ pBuf, pBuf->DevVAddr.uiAddr, -+ pBuf->CpuVAddr, pBuf->CpuPAddr.uiAddr)); -+ -+ /* record mapping */ -+ pMapping = pBuf->pMapping; -+ -+ psDeviceNode = pMapping->pBMHeap->pBMContext->psDeviceNode; -+ if (psDeviceNode->pfnCacheInvalidate) -+ { -+ psDeviceNode->pfnCacheInvalidate(psDeviceNode); -+ } -+ -+ if(ui32Flags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR) -+ { -+ /* Submemhandle is required by exported mappings */ -+ if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0)) -+ { -+ /* user supplied Device Virtual Address */ -+ if(ui32Flags & PVRSRV_MEM_RAM_BACKED_ALLOCATION) -+ { -+ /* RAM backed allocation */ -+ PVR_DPF ((PVR_DBG_ERROR, "FreeBuf: combination of DevVAddr management and RAM backing mode unsupported")); -+ } -+ else -+ { -+ /* free the mocked-up mapping */ -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_MAPPING), pMapping, IMG_NULL); -+ pBuf->pMapping = IMG_NULL; /*nulling pointer alias*/ -+ } -+ } -+ } -+ else -+ { -+ /* BM supplied Device Virtual Address */ -+ if(pBuf->hOSMemHandle != pMapping->hOSMemHandle) -+ { -+ /* Submemhandle is required by exported mappings */ -+ if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0)) -+ { -+ OSReleaseSubMemHandle(pBuf->hOSMemHandle, ui32Flags); -+ } -+ } -+ if(ui32Flags & PVRSRV_MEM_RAM_BACKED_ALLOCATION) -+ { -+ /* Submemhandle is required by exported mappings */ -+ if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0)) -+ { -+ /* -+ RAM backed allocation -+ Note: currently no need to distinguish between hm_env and hm_contiguous -+ */ -+ PVR_ASSERT(pBuf->ui32ExportCount == 0); -+ if (pBuf->pMapping->ui32Flags & PVRSRV_MEM_SPARSE) -+ { -+ IMG_UINT32 ui32FreeSize = sizeof(IMG_BOOL) * pBuf->pMapping->ui32NumVirtChunks; -+ IMG_PVOID pvFreePtr = pBuf->pMapping->pabMapChunk; -+ -+ /* With sparse allocations we don't go through the sub-alloc RA */ -+ BM_FreeMemory(pBuf->pMapping->pBMHeap, pBuf->DevVAddr.uiAddr, pBuf->pMapping); -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, -+ ui32FreeSize, -+ pvFreePtr, -+ IMG_NULL); -+ } -+ else -+ { -+ RA_Free (pBuf->pMapping->pArena, pBuf->DevVAddr.uiAddr, IMG_FALSE); -+ } -+ } -+ } -+ else -+ { -+ if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0)) -+ { -+ switch (pMapping->eCpuMemoryOrigin) -+ { -+ case hm_wrapped: -+ OSUnReservePhys(pMapping->CpuVAddr, pMapping->uSize, ui32Flags, pMapping->hOSMemHandle); -+ break; -+ case hm_wrapped_virtaddr: -+ OSUnRegisterMem(pMapping->CpuVAddr, pMapping->uSize, ui32Flags, pMapping->hOSMemHandle); -+ break; -+ case hm_wrapped_scatter: -+ OSUnReserveDiscontigPhys(pMapping->CpuVAddr, pMapping->uSize, ui32Flags, pMapping->hOSMemHandle); -+ break; -+ case hm_wrapped_scatter_virtaddr: -+ OSUnRegisterDiscontigMem(pMapping->CpuVAddr, pMapping->uSize, ui32Flags, pMapping->hOSMemHandle); -+ break; -+ default: -+ break; -+ } -+ } -+ if (bFromAllocator) -+ DevMemoryFree (pMapping); -+ -+ if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0)) -+ { -+ /* free the mocked-up mapping */ -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_MAPPING), pMapping, IMG_NULL); -+ pBuf->pMapping = IMG_NULL; /*nulling pointer alias*/ -+ } -+ } -+ } -+ -+ -+ if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0)) -+ { -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_BUF), pBuf, IMG_NULL); -+ /*not nulling pointer, copy on stack*/ -+ } -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function BM_DestroyContext_AnyCb -+ -+ @Description Destroy a buffer manager heap. -+ -+ @Input psBMHeap -+ -+ @Return PVRSRV_ERROR -+ -+ *****************************************************************************/ -+static PVRSRV_ERROR BM_DestroyContext_AnyCb(BM_HEAP *psBMHeap) -+{ -+ if(psBMHeap->ui32Attribs -+ & (PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG -+ |PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG)) -+ { -+ if (psBMHeap->pImportArena) -+ { -+ IMG_BOOL bTestDelete = RA_TestDelete(psBMHeap->pImportArena); -+ if (!bTestDelete) -+ { -+ PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyContext_AnyCb: RA_TestDelete failed")); -+ return PVRSRV_ERROR_UNABLE_TO_DESTROY_BM_HEAP; -+ } -+ } -+ } -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function BM_DestroyContext -+ -+ @Description Destroy a buffer manager context. All allocated buffers must be -+ free'd before calling this function. This function is called -+ also to perform cleanup during aborted initialisations so it's -+ fairly careful not to assume any given resource has really been -+ created/allocated. -+ -+ @Return PVRSRV_ERROR -+ -+ *****************************************************************************/ -+PVRSRV_ERROR -+BM_DestroyContext(IMG_HANDLE hBMContext, -+ IMG_BOOL *pbDestroyed) -+{ -+ PVRSRV_ERROR eError; -+ BM_CONTEXT *pBMContext = (BM_CONTEXT*)hBMContext; -+ -+ PVR_DPF ((PVR_DBG_MESSAGE, "BM_DestroyContext")); -+ -+ if (pbDestroyed != IMG_NULL) -+ { -+ *pbDestroyed = IMG_FALSE; -+ } -+ -+ /* -+ Exit straight away if it's an invalid context handle -+ */ -+ if (pBMContext == IMG_NULL) -+ { -+ PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyContext: Invalid handle")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ pBMContext->ui32RefCount--; -+ -+ if (pBMContext->ui32RefCount > 0) -+ { -+ /* Just return if there are more references to this context */ -+ return PVRSRV_OK; -+ } -+ -+ /* -+ Check whether there is a bug in the client which brought it here before -+ all the allocations have been freed. -+ */ -+ eError = List_BM_HEAP_PVRSRV_ERROR_Any(pBMContext->psBMHeap, &BM_DestroyContext_AnyCb); -+ if(eError != PVRSRV_OK) -+ { -+ PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyContext: List_BM_HEAP_PVRSRV_ERROR_Any failed")); -+ return eError; -+ } -+ else -+ { -+ /* free the device memory context */ -+ eError = ResManFreeResByPtr(pBMContext->hResItem, CLEANUP_WITH_POLL); -+ if(eError != PVRSRV_OK) -+ { -+ PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyContext: ResManFreeResByPtr failed %d",eError)); -+ return eError; -+ } -+ -+ /* mark context as destroyed */ -+ if (pbDestroyed != IMG_NULL) -+ { -+ *pbDestroyed = IMG_TRUE; -+ } -+ } -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function BM_DestroyContextCallBack_AnyVaCb -+ -+ @Description Destroy Device memory context -+ -+ @Input psBMHeap - heap to be freed. -+ @Input va - list of variable arguments with the following contents: -+ - psDeviceNode -+ @Return PVRSRV_ERROR -+ -+ *****************************************************************************/ -+static PVRSRV_ERROR BM_DestroyContextCallBack_AnyVaCb(BM_HEAP *psBMHeap, va_list va) -+{ -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+ psDeviceNode = va_arg(va, PVRSRV_DEVICE_NODE*); -+ -+ /* Free up the import arenas */ -+ if(psBMHeap->ui32Attribs -+ & (PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG -+ |PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG)) -+ { -+ if (psBMHeap->pImportArena) -+ { -+ RA_Delete (psBMHeap->pImportArena); -+ } -+ } -+ else -+ { -+ PVR_DPF((PVR_DBG_ERROR, "BM_DestroyContext: backing store type unsupported")); -+ return PVRSRV_ERROR_UNSUPPORTED_BACKING_STORE; -+ } -+ -+ /* Free up the MMU Heaps */ -+ psDeviceNode->pfnMMUDelete(psBMHeap->pMMUHeap); -+ -+ /* Free Heap memory */ -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_HEAP), psBMHeap, IMG_NULL); -+ /*not nulling pointer, copy on stack*/ -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function BM_DestroyContextCallBack -+ -+ @Description Destroy Device memory context -+ -+ @Input pvParam - opaque void ptr param -+ @Input ui32Param - opaque unsigned long param -+ -+ @Return PVRSRV_ERROR -+ -+ *****************************************************************************/ -+static PVRSRV_ERROR BM_DestroyContextCallBack(IMG_PVOID pvParam, -+ IMG_UINT32 ui32Param, -+ IMG_BOOL bDummy) -+{ -+ BM_CONTEXT *pBMContext = pvParam; -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+ PVRSRV_ERROR eError; -+/* BM_CONTEXT **ppBMContext; -+ BM_HEAP *psBMHeap, *psTmpBMHeap;*/ -+ -+ PVR_UNREFERENCED_PARAMETER(ui32Param); -+ PVR_UNREFERENCED_PARAMETER(bDummy); -+ -+ /* -+ Get DeviceNode from BMcontext -+ */ -+ psDeviceNode = pBMContext->psDeviceNode; -+ -+ /* -+ Free the import arenas and heaps -+ */ -+ eError = List_BM_HEAP_PVRSRV_ERROR_Any_va(pBMContext->psBMHeap, -+ &BM_DestroyContextCallBack_AnyVaCb, -+ psDeviceNode); -+ if (eError != PVRSRV_OK) -+ { -+ return eError; -+ } -+ /* -+ 'Finalise' the MMU -+ */ -+ if (pBMContext->psMMUContext) -+ { -+ psDeviceNode->pfnMMUFinalise(pBMContext->psMMUContext); -+ } -+ -+ /* -+ Free up generic, useful resources - if they were allocated. -+ */ -+ if (pBMContext->pBufferHash) -+ { -+ HASH_Delete(pBMContext->pBufferHash); -+ } -+ -+ if (pBMContext == psDeviceNode->sDevMemoryInfo.pBMKernelContext) -+ { -+ /* Freeing the kernel context */ -+ psDeviceNode->sDevMemoryInfo.pBMKernelContext = IMG_NULL; -+ } -+ else -+ { -+ if (pBMContext->ppsThis != IMG_NULL) -+ { -+ /* -+ * Remove context from the linked list -+ */ -+ List_BM_CONTEXT_Remove(pBMContext); -+ } -+ } -+ -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_CONTEXT), pBMContext, IMG_NULL); -+ /*not nulling pointer, copy on stack*/ -+ -+ return PVRSRV_OK; -+} -+ -+ -+static IMG_HANDLE BM_CreateContext_IncRefCount_AnyVaCb(BM_CONTEXT *pBMContext, va_list va) -+{ -+ PRESMAN_CONTEXT hResManContext; -+ hResManContext = va_arg(va, PRESMAN_CONTEXT); -+ if(ResManFindResourceByPtr(hResManContext, pBMContext->hResItem) == PVRSRV_OK) -+ { -+ /* just increment the refcount and return the memory context found for this process */ -+ pBMContext->ui32RefCount++; -+ return pBMContext; -+ } -+ return IMG_NULL; -+} -+ -+static IMG_VOID BM_CreateContext_InsertHeap_ForEachVaCb(BM_HEAP *psBMHeap, va_list va) -+{ -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+ BM_CONTEXT *pBMContext; -+ psDeviceNode = va_arg(va, PVRSRV_DEVICE_NODE*); -+ pBMContext = va_arg(va, BM_CONTEXT*); -+ switch(psBMHeap->sDevArena.DevMemHeapType) -+ { -+ case DEVICE_MEMORY_HEAP_SHARED: -+ case DEVICE_MEMORY_HEAP_SHARED_EXPORTED: -+ { -+ /* insert the heap into the device's MMU page directory/table */ -+ psDeviceNode->pfnMMUInsertHeap(pBMContext->psMMUContext, psBMHeap->pMMUHeap); -+ break; -+ } -+ } -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function BM_CreateContext -+ -+ @Description Creates and initialises a buffer manager context. This function must be called -+ before any other buffer manager functions. -+ -+ @Return valid BM context handle - Success -+ IMG_NULL - Failed -+ -+ *****************************************************************************/ -+IMG_HANDLE -+BM_CreateContext(PVRSRV_DEVICE_NODE *psDeviceNode, -+ IMG_DEV_PHYADDR *psPDDevPAddr, -+ PVRSRV_PER_PROCESS_DATA *psPerProc, -+ IMG_BOOL *pbCreated) -+{ -+ BM_CONTEXT *pBMContext; -+/* BM_HEAP *psBMHeap;*/ -+ DEVICE_MEMORY_INFO *psDevMemoryInfo; -+ IMG_BOOL bKernelContext; -+ PRESMAN_CONTEXT hResManContext; -+ -+ PVR_DPF((PVR_DBG_MESSAGE, "BM_CreateContext")); -+ -+ if (psPerProc == IMG_NULL) -+ { -+ bKernelContext = IMG_TRUE; -+ hResManContext = psDeviceNode->hResManContext; -+ } -+ else -+ { -+ bKernelContext = IMG_FALSE; -+ hResManContext = psPerProc->hResManContext; -+ } -+ -+ if (pbCreated != IMG_NULL) -+ { -+ *pbCreated = IMG_FALSE; -+ } -+ -+ /* setup the device memory info. */ -+ psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo; -+ -+ if (bKernelContext == IMG_FALSE) -+ { -+ IMG_HANDLE res = (IMG_HANDLE) List_BM_CONTEXT_Any_va(psDevMemoryInfo->pBMContext, -+ &BM_CreateContext_IncRefCount_AnyVaCb, -+ hResManContext); -+ if (res) -+ { -+ return res; -+ } -+ } -+ -+ /* allocate a BM context */ -+ if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof (struct _BM_CONTEXT_), -+ (IMG_PVOID *)&pBMContext, IMG_NULL, -+ "Buffer Manager Context") != PVRSRV_OK) -+ { -+ PVR_DPF ((PVR_DBG_ERROR, "BM_CreateContext: Alloc failed")); -+ return IMG_NULL; -+ } -+ OSMemSet(pBMContext, 0, sizeof (BM_CONTEXT)); -+ -+ /* store the associated devicenode */ -+ pBMContext->psDeviceNode = psDeviceNode; -+ -+ /* This hash table is used to store BM_Wraps in a global way */ -+ /* INTEGRATION_POINT: 32 is an abitrary limit on the number of hashed BM_wraps */ -+ pBMContext->pBufferHash = HASH_Create(32); -+ if (pBMContext->pBufferHash==IMG_NULL) -+ { -+ PVR_DPF ((PVR_DBG_ERROR, "BM_CreateContext: HASH_Create failed")); -+ goto cleanup; -+ } -+ -+ if((IMG_NULL == psDeviceNode->pfnMMUInitialise) || (psDeviceNode->pfnMMUInitialise(psDeviceNode, -+ &pBMContext->psMMUContext, -+ psPDDevPAddr) != PVRSRV_OK)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "BM_CreateContext: MMUInitialise failed")); -+ goto cleanup; -+ } -+ -+ if(bKernelContext) -+ { -+ /* just save the kernel context */ -+ PVR_ASSERT(psDevMemoryInfo->pBMKernelContext == IMG_NULL); -+ psDevMemoryInfo->pBMKernelContext = pBMContext; -+ } -+ else -+ { -+ /* -+ On the creation of each new context we must -+ insert the kernel context's 'shared' and 'shared_exported' -+ heaps into the new context -+ - check the kernel context and heaps exist -+ */ -+ PVR_ASSERT(psDevMemoryInfo->pBMKernelContext); -+ -+ if (psDevMemoryInfo->pBMKernelContext == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "BM_CreateContext: psDevMemoryInfo->pBMKernelContext invalid")); -+ goto cleanup; -+ } -+ -+ PVR_ASSERT(psDevMemoryInfo->pBMKernelContext->psBMHeap); -+ -+ /* -+ insert the kernel heaps structures into the new context's shared heap list -+ Note. this will include the kernel only heaps but these will not actually -+ be imported into the context nor returned to the client -+ */ -+ pBMContext->psBMSharedHeap = psDevMemoryInfo->pBMKernelContext->psBMHeap; -+ -+ /* -+ insert the shared heaps into the MMU page directory/table -+ for the new context -+ */ -+ List_BM_HEAP_ForEach_va(pBMContext->psBMSharedHeap, -+ &BM_CreateContext_InsertHeap_ForEachVaCb, -+ psDeviceNode, -+ pBMContext); -+ -+ /* Finally, insert the new context into the list of BM contexts */ -+ List_BM_CONTEXT_Insert(&psDevMemoryInfo->pBMContext, pBMContext); -+ } -+ -+ /* Increment the refcount, as creation is successful */ -+ pBMContext->ui32RefCount++; -+ -+ /* register with resman */ -+ pBMContext->hResItem = ResManRegisterRes(hResManContext, -+ RESMAN_TYPE_DEVICEMEM_CONTEXT, -+ pBMContext, -+ 0, -+ &BM_DestroyContextCallBack); -+ if (pBMContext->hResItem == IMG_NULL) -+ { -+ PVR_DPF ((PVR_DBG_ERROR, "BM_CreateContext: ResManRegisterRes failed")); -+ goto cleanup; -+ } -+ -+ if (pbCreated != IMG_NULL) -+ { -+ *pbCreated = IMG_TRUE; -+ } -+ return (IMG_HANDLE)pBMContext; -+ -+cleanup: -+ (IMG_VOID)BM_DestroyContextCallBack(pBMContext, 0, CLEANUP_WITH_POLL); -+ -+ return IMG_NULL; -+} -+ -+ -+static IMG_VOID *BM_CreateHeap_AnyVaCb(BM_HEAP *psBMHeap, va_list va) -+{ -+ DEVICE_MEMORY_HEAP_INFO *psDevMemHeapInfo; -+ psDevMemHeapInfo = va_arg(va, DEVICE_MEMORY_HEAP_INFO*); -+ if (psBMHeap->sDevArena.ui32HeapID == psDevMemHeapInfo->ui32HeapID) -+ { -+ /* Match - just return already created heap */ -+ return psBMHeap; -+ } -+ else -+ { -+ return IMG_NULL; -+ } -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function BM_CreateHeap -+ -+ @Description Creates and initialises a BM heap for a given BM context. -+ -+ @Return -+ valid heap handle - success -+ IMG_NULL - failure -+ -+ -+ *****************************************************************************/ -+IMG_HANDLE -+BM_CreateHeap (IMG_HANDLE hBMContext, -+ DEVICE_MEMORY_HEAP_INFO *psDevMemHeapInfo) -+{ -+ BM_CONTEXT *pBMContext = (BM_CONTEXT*)hBMContext; -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+ BM_HEAP *psBMHeap; -+ -+ PVR_DPF((PVR_DBG_MESSAGE, "BM_CreateHeap")); -+ -+ if(!pBMContext) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "BM_CreateHeap: BM_CONTEXT null")); -+ return IMG_NULL; -+ } -+ -+ psDeviceNode = pBMContext->psDeviceNode; -+ -+ /* -+ * Ensure that the heap size is a multiple of the data page size. -+ */ -+ PVR_ASSERT((psDevMemHeapInfo->ui32HeapSize & (psDevMemHeapInfo->ui32DataPageSize - 1)) == 0); -+ PVR_ASSERT(psDevMemHeapInfo->ui32HeapSize > 0); -+ -+ /* -+ We may be being asked to create a heap in a context which already has one. -+ Test for refcount > 0 because PVRSRVGetDeviceMemHeapInfoKM doesn't increment the refcount. -+ This does mean that the first call to PVRSRVCreateDeviceMemContextKM will first try to find -+ heaps that we already know don't exist -+ */ -+ if(pBMContext->ui32RefCount > 0) -+ { -+ psBMHeap = (BM_HEAP*)List_BM_HEAP_Any_va(pBMContext->psBMHeap, -+ &BM_CreateHeap_AnyVaCb, -+ psDevMemHeapInfo); -+ -+ if (psBMHeap) -+ { -+ return psBMHeap; -+ } -+ } -+ -+ -+ if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof (BM_HEAP), -+ (IMG_PVOID *)&psBMHeap, IMG_NULL, -+ "Buffer Manager Heap") != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "BM_CreateHeap: Alloc failed")); -+ return IMG_NULL; -+ } -+ -+ OSMemSet (psBMHeap, 0, sizeof (BM_HEAP)); -+ -+ psBMHeap->sDevArena.ui32HeapID = psDevMemHeapInfo->ui32HeapID; -+ psBMHeap->sDevArena.pszName = psDevMemHeapInfo->pszName; -+ psBMHeap->sDevArena.BaseDevVAddr = psDevMemHeapInfo->sDevVAddrBase; -+ psBMHeap->sDevArena.ui32Size = psDevMemHeapInfo->ui32HeapSize; -+ psBMHeap->sDevArena.DevMemHeapType = psDevMemHeapInfo->DevMemHeapType; -+ psBMHeap->sDevArena.ui32DataPageSize = psDevMemHeapInfo->ui32DataPageSize; -+ psBMHeap->sDevArena.psDeviceMemoryHeapInfo = psDevMemHeapInfo; -+ psBMHeap->ui32Attribs = psDevMemHeapInfo->ui32Attribs; -+#if defined(SUPPORT_MEMORY_TILING) -+ psBMHeap->ui32XTileStride = psDevMemHeapInfo->ui32XTileStride; -+#endif -+ -+ /* tie the heap to the context */ -+ psBMHeap->pBMContext = pBMContext; -+ -+ psBMHeap->pMMUHeap = psDeviceNode->pfnMMUCreate (pBMContext->psMMUContext, -+ &psBMHeap->sDevArena, -+ &psBMHeap->pVMArena, -+ &psBMHeap->psMMUAttrib); -+ if (!psBMHeap->pMMUHeap) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "BM_CreateHeap: MMUCreate failed")); -+ goto ErrorExit; -+ } -+ -+ /* memory is allocated from the OS as required */ -+ psBMHeap->pImportArena = RA_Create (psDevMemHeapInfo->pszBSName, -+ 0, 0, IMG_NULL, -+ MAX(HOST_PAGESIZE(), psBMHeap->sDevArena.ui32DataPageSize), -+ &BM_ImportMemory, -+ &BM_FreeMemory, -+ IMG_NULL, -+ psBMHeap); -+ if(psBMHeap->pImportArena == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "BM_CreateHeap: RA_Create failed")); -+ goto ErrorExit; -+ } -+ -+ if(psBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG) -+ { -+ /* -+ memory comes from a device memory contiguous allocator (ra) -+ Note: these arenas are shared across the system so don't delete -+ as part of heap destroy -+ */ -+ psBMHeap->pLocalDevMemArena = psDevMemHeapInfo->psLocalDevMemArena; -+ if(psBMHeap->pLocalDevMemArena == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "BM_CreateHeap: LocalDevMemArena null")); -+ goto ErrorExit; -+ } -+ } -+ -+ /* insert heap into head of the heap list */ -+ List_BM_HEAP_Insert(&pBMContext->psBMHeap, psBMHeap); -+ -+ return (IMG_HANDLE)psBMHeap; -+ -+ /* handle error case */ -+ErrorExit: -+ -+ /* Free up the MMU if we created one */ -+ if (psBMHeap->pMMUHeap != IMG_NULL) -+ { -+ psDeviceNode->pfnMMUDelete (psBMHeap->pMMUHeap); -+ /* don't finalise psMMUContext as we don't own it */ -+ } -+ -+ /* Free the Heap memory */ -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_HEAP), psBMHeap, IMG_NULL); -+ /*not nulling pointer, out of scope*/ -+ -+ return IMG_NULL; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function BM_DestroyHeap -+ -+ @Description Destroys a BM heap -+ -+ @Return -+ valid heap handle - success -+ IMG_NULL - failure -+ -+ -+ *****************************************************************************/ -+IMG_VOID -+BM_DestroyHeap (IMG_HANDLE hDevMemHeap) -+{ -+ BM_HEAP* psBMHeap = (BM_HEAP*)hDevMemHeap; -+ PVRSRV_DEVICE_NODE *psDeviceNode = psBMHeap->pBMContext->psDeviceNode; -+ -+ PVR_DPF((PVR_DBG_MESSAGE, "BM_DestroyHeap")); -+ -+ if(psBMHeap) -+ { -+ /* Free up the import arenas */ -+ if(psBMHeap->ui32Attribs -+ & (PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG -+ |PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG)) -+ { -+ if (psBMHeap->pImportArena) -+ { -+ RA_Delete (psBMHeap->pImportArena); -+ } -+ } -+ else -+ { -+ PVR_DPF((PVR_DBG_ERROR, "BM_DestroyHeap: backing store type unsupported")); -+ return; -+ } -+ -+ /* Free up the MMU Heap */ -+ psDeviceNode->pfnMMUDelete (psBMHeap->pMMUHeap); -+ -+ /* remove from the heap list */ -+ List_BM_HEAP_Remove(psBMHeap); -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_HEAP), psBMHeap, IMG_NULL); -+ } -+ else -+ { -+ PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyHeap: invalid heap handle")); -+ } -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function BM_Reinitialise -+ -+ @Description Reinitialise the buffer manager after a power down event. -+ -+ @Return IMG_TRUE - Success -+ IMG_FALSE - Failed -+ -+ *****************************************************************************/ -+IMG_BOOL -+BM_Reinitialise (PVRSRV_DEVICE_NODE *psDeviceNode) -+{ -+ -+ PVR_DPF((PVR_DBG_MESSAGE, "BM_Reinitialise")); -+ PVR_UNREFERENCED_PARAMETER(psDeviceNode); -+ -+ /* FIXME: Need to reenable all contexts -+ List_BM_CONTEXT_ForEach(psDeviceNode->sDevMemoryInfo.pBMContext, MMU_Enable); -+ */ -+ -+ return IMG_TRUE; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function BM_Alloc -+ -+ @Description Allocate a buffer mapped into both cpu and device virtual -+ memory maps. -+ -+ @Input hDevMemHeap -+ @Input psDevVAddr - device virtual address specified by caller (optional) -+ @Input uSize - require size in bytes of the buffer. -+ @Input pui32Flags - bit mask of buffer property flags. -+ @Input uDevVAddrAlignment - required alignment in bytes, or 0. -+ @Input pvPrivData - opaque private data passed through to allocator -+ @Input ui32PrivDataLength - length of opaque private data -+ -+ @Output phBuf - receives buffer handle -+ @Output pui32Flags - bit mask of heap property flags. -+ -+ @Return IMG_TRUE - Success -+ IMG_FALSE - Failure -+ -+ *****************************************************************************/ -+IMG_BOOL -+BM_Alloc ( IMG_HANDLE hDevMemHeap, -+ IMG_DEV_VIRTADDR *psDevVAddr, -+ IMG_SIZE_T uSize, -+ IMG_UINT32 *pui32Flags, -+ IMG_UINT32 uDevVAddrAlignment, -+ IMG_PVOID pvPrivData, -+ IMG_UINT32 ui32PrivDataLength, -+ IMG_UINT32 ui32ChunkSize, -+ IMG_UINT32 ui32NumVirtChunks, -+ IMG_UINT32 ui32NumPhysChunks, -+ IMG_BOOL *pabMapChunk, -+ BM_HANDLE *phBuf) -+{ -+ BM_BUF *pBuf; -+ BM_CONTEXT *pBMContext; -+ BM_HEAP *psBMHeap; -+ SYS_DATA *psSysData; -+ IMG_UINT32 ui32Flags; -+ -+ if (pui32Flags == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "BM_Alloc: invalid parameter")); -+ PVR_DBG_BREAK; -+ return IMG_FALSE; -+ } -+ -+ ui32Flags = *pui32Flags; -+ -+ PVR_DPF ((PVR_DBG_MESSAGE, -+ "BM_Alloc (uSize=0x%" SIZE_T_FMT_LEN "x, ui32Flags=0x%x, uDevVAddrAlignment=0x%x)", -+ uSize, ui32Flags, uDevVAddrAlignment)); -+ -+ SysAcquireData(&psSysData); -+ -+ psBMHeap = (BM_HEAP*)hDevMemHeap; -+ pBMContext = psBMHeap->pBMContext; -+ -+ if(uDevVAddrAlignment == 0) -+ { -+ uDevVAddrAlignment = 1; -+ } -+ -+ /* -+ * Allocate something in which to record the allocation's details. -+ */ -+ if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof (BM_BUF), -+ (IMG_PVOID *)&pBuf, IMG_NULL, -+ "Buffer Manager buffer") != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "BM_Alloc: BM_Buf alloc FAILED")); -+ return IMG_FALSE; -+ } -+ OSMemSet(pBuf, 0, sizeof (BM_BUF)); -+ -+ /* -+ * Allocate the memory itself now. -+ */ -+ if (AllocMemory(pBMContext, -+ psBMHeap, -+ psDevVAddr, -+ uSize, -+ ui32Flags, -+ uDevVAddrAlignment, -+ pvPrivData, -+ ui32PrivDataLength, -+ ui32ChunkSize, -+ ui32NumVirtChunks, -+ ui32NumPhysChunks, -+ pabMapChunk, -+ pBuf) != IMG_TRUE) -+ { -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof (BM_BUF), pBuf, IMG_NULL); -+ /* not nulling pointer, out of scope */ -+ PVR_DPF((PVR_DBG_ERROR, "BM_Alloc: AllocMemory FAILED")); -+ return IMG_FALSE; -+ } -+ -+ PVR_DPF ((PVR_DBG_MESSAGE, -+ "BM_Alloc (uSize=0x%" SIZE_T_FMT_LEN "x, ui32Flags=0x%x)", -+ uSize, ui32Flags)); -+ -+ /* -+ * Assign the handle and return. -+ */ -+ pBuf->ui32RefCount = 1; -+ *phBuf = (BM_HANDLE)pBuf; -+ *pui32Flags = ui32Flags | psBMHeap->ui32Attribs; -+ -+ /* -+ * If the user has specified heap CACHETYPE flags themselves, -+ * override any CACHETYPE flags inherited from the heap. -+ */ -+ if(ui32Flags & PVRSRV_HAP_CACHETYPE_MASK) -+ { -+ *pui32Flags &= ~PVRSRV_HAP_CACHETYPE_MASK; -+ *pui32Flags |= (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK); -+ } -+ -+ return IMG_TRUE; -+} -+ -+ -+ -+#if defined(PVR_LMA) -+/*! -+****************************************************************************** -+ -+ @Function ValidSysPAddrArrayForDev -+ -+ @Description Verify the array of system address is accessible -+ by the given device. -+ -+ @Input psDeviceNode -+ @Input psSysPAddr - system address array -+ @Input uPageSize - size of address array -+ -+ @Return IMG_BOOL -+ -+ *****************************************************************************/ -+static IMG_BOOL -+ValidSysPAddrArrayForDev(PVRSRV_DEVICE_NODE *psDeviceNode, IMG_SYS_PHYADDR *psSysPAddr, IMG_UINT32 ui32PageCount, IMG_SIZE_T uPageSize) -+{ -+ IMG_UINT32 i; -+ -+ for (i = 0; i < ui32PageCount; i++) -+ { -+ IMG_SYS_PHYADDR sStartSysPAddr = psSysPAddr[i]; -+ IMG_SYS_PHYADDR sEndSysPAddr; -+ -+ if (!SysVerifySysPAddrToDevPAddr(psDeviceNode->sDevId.eDeviceType, sStartSysPAddr)) -+ { -+ return IMG_FALSE; -+ } -+ -+ sEndSysPAddr.uiAddr = sStartSysPAddr.uiAddr + uPageSize; -+ -+ if (!SysVerifySysPAddrToDevPAddr(psDeviceNode->sDevId.eDeviceType, sEndSysPAddr)) -+ { -+ return IMG_FALSE; -+ } -+ } -+ -+ return IMG_TRUE; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function ValidSysPAddrRangeForDev -+ -+ @Description Verify a system address range is accessible -+ by the given device. -+ -+ @Input psDeviceNode -+ @Input sStartSysPAddr - starting system address -+ @Input ui32Range - length of address range -+ -+ @Return IMG_BOOL -+ -+ *****************************************************************************/ -+static IMG_BOOL -+ValidSysPAddrRangeForDev(PVRSRV_DEVICE_NODE *psDeviceNode, IMG_SYS_PHYADDR sStartSysPAddr, IMG_SIZE_T uRange) -+{ -+ IMG_SYS_PHYADDR sEndSysPAddr; -+ -+ if (!SysVerifySysPAddrToDevPAddr(psDeviceNode->sDevId.eDeviceType, sStartSysPAddr)) -+ { -+ return IMG_FALSE; -+ } -+ -+ sEndSysPAddr.uiAddr = sStartSysPAddr.uiAddr + uRange; -+ -+ if (!SysVerifySysPAddrToDevPAddr(psDeviceNode->sDevId.eDeviceType, sEndSysPAddr)) -+ { -+ return IMG_FALSE; -+ } -+ -+ return IMG_TRUE; -+} -+ -+#define WRAP_MAPPING_SIZE(uByteSize, uPageOffset) HOST_PAGEALIGN((uByteSize) + (uPageOffset)) -+ -+#define WRAP_PAGE_COUNT(uByteSize, uPageOffset, uHostPageSize) (WRAP_MAPPING_SIZE(uByteSize, uPageOffset) / (uHostPageSize)) -+ -+#endif -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function BM_Wrap -+ -+ @Description Create a buffer which wraps user provided system physical -+ memory. -+ The wrapped memory must be page aligned. BM_Wrap will -+ roundup the size to a multiple of cpu pages. -+ -+ @Input uSize - size of memory to wrap. -+ @Input ui32Offset - Offset into page of memory to wrap. -+ @Input bPhysContig - Is the wrap physically contiguous. -+ @Input psSysAddr - list of system physical page addresses of memory to wrap. -+ @Input pvCPUVAddr - optional CPU kernel virtual address (Page aligned) of memory to wrap. -+ @Input ui32Flags - bit mask of buffer property flags. -+ @output phBuf - receives the buffer handle. -+ -+ @Return IMG_TRUE - Success. -+ IMG_FALSE - Failed -+ -+ *****************************************************************************/ -+IMG_BOOL -+BM_Wrap ( IMG_HANDLE hDevMemHeap, -+ IMG_SIZE_T uSize, -+ IMG_SIZE_T uOffset, -+ IMG_BOOL bPhysContig, -+ IMG_SYS_PHYADDR *psSysAddr, -+ IMG_VOID *pvCPUVAddr, -+ IMG_UINT32 *pui32Flags, -+ BM_HANDLE *phBuf) -+{ -+ BM_BUF *pBuf; -+ BM_CONTEXT *psBMContext; -+ BM_HEAP *psBMHeap; -+ SYS_DATA *psSysData; -+ IMG_SYS_PHYADDR sHashAddress; -+ IMG_UINT32 ui32Flags; -+ -+ psBMHeap = (BM_HEAP*)hDevMemHeap; -+ psBMContext = psBMHeap->pBMContext; -+ -+ ui32Flags = psBMHeap->ui32Attribs & (PVRSRV_HAP_CACHETYPE_MASK | PVRSRV_HAP_MAPTYPE_MASK); -+ -+ if ((pui32Flags != IMG_NULL) && ((*pui32Flags & PVRSRV_HAP_CACHETYPE_MASK) != 0)) -+ { -+ ui32Flags &= ~PVRSRV_HAP_CACHETYPE_MASK; -+ ui32Flags |= *pui32Flags & PVRSRV_HAP_CACHETYPE_MASK; -+ } -+ -+ if ((pui32Flags != IMG_NULL) && ((*pui32Flags & (PVRSRV_MEM_READ | PVRSRV_MEM_WRITE)) != 0)) -+ { -+ ui32Flags &= ~(PVRSRV_MEM_READ | PVRSRV_MEM_WRITE); -+ ui32Flags |= *pui32Flags & (PVRSRV_MEM_READ | PVRSRV_MEM_WRITE); -+ } -+ -+ PVR_DPF ((PVR_DBG_MESSAGE, -+ "BM_Wrap (uSize=0x%" SIZE_T_FMT_LEN "x, uOffset=0x%" SIZE_T_FMT_LEN -+ "x, bPhysContig=0x%x, syspAddr=0x" SYSPADDR_FMT ", pvCPUVAddr=0x%p, ui32Flags=0x%x)", -+ uSize, -+ uOffset, -+ bPhysContig, -+ psSysAddr->uiAddr, -+ pvCPUVAddr, -+ ui32Flags)); -+ -+ SysAcquireData(&psSysData); -+ -+#if defined(PVR_LMA) -+ if (bPhysContig) -+ { -+ if (!ValidSysPAddrRangeForDev(psBMContext->psDeviceNode, *psSysAddr, WRAP_MAPPING_SIZE(uSize, uOffset))) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: System address range invalid for device")); -+ return IMG_FALSE; -+ } -+ } -+ else -+ { -+ IMG_SIZE_T uHostPageSize = HOST_PAGESIZE(); -+ -+ if (!ValidSysPAddrArrayForDev(psBMContext->psDeviceNode, psSysAddr, WRAP_PAGE_COUNT(uSize, uOffset, uHostPageSize), uHostPageSize)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: Array of system addresses invalid for device")); -+ return IMG_FALSE; -+ } -+ } -+#endif -+ /* -+ * Insert the System Physical Address of the first page into the hash so we can optimise multiple wraps of the -+ * same memory. -+ */ -+ sHashAddress = psSysAddr[0]; -+ -+ /* Add the in-page offset to ensure a unique hash */ -+ sHashAddress.uiAddr += uOffset; -+ -+ /* See if this address has already been wrapped, note that the cast is ok as this is only local mem */ -+ pBuf = (BM_BUF *)HASH_Retrieve(psBMContext->pBufferHash, (IMG_UINTPTR_T)sHashAddress.uiAddr); -+ -+ if(pBuf) -+ { -+ IMG_SIZE_T uMappingSize = HOST_PAGEALIGN (uSize + uOffset); -+ -+ /* Check base address, size and contiguity type match */ -+ if(pBuf->pMapping->uSize == uMappingSize && (pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped || -+ pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped_virtaddr)) -+ { -+ PVR_DPF((PVR_DBG_MESSAGE, -+ "BM_Wrap (Matched previous Wrap! uSize=0x%" SIZE_T_FMT_LEN "x, uOffset=0x%" SIZE_T_FMT_LEN "x, SysAddr=" SYSPADDR_FMT ")", -+ uSize, -+ uOffset, -+ sHashAddress.uiAddr)); -+ -+ PVRSRVBMBufIncRef(pBuf); -+ *phBuf = (BM_HANDLE)pBuf; -+ if(pui32Flags) -+ *pui32Flags = ui32Flags; -+ -+ return IMG_TRUE; -+ } -+ else -+ { -+ /* Otherwise removed that item from the hash table -+ (a workaround for buffer device class) */ -+ HASH_Remove(psBMContext->pBufferHash, (IMG_UINTPTR_T)sHashAddress.uiAddr); -+ } -+ } -+ -+ /* -+ * Allocate something in which to record the allocation's details. -+ */ -+ if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof (BM_BUF), -+ (IMG_PVOID *)&pBuf, IMG_NULL, -+ "Buffer Manager buffer") != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: BM_Buf alloc FAILED")); -+ return IMG_FALSE; -+ } -+ OSMemSet(pBuf, 0, sizeof (BM_BUF)); -+ -+ /* -+ * Actually perform the memory wrap. -+ */ -+ if (WrapMemory (psBMHeap, uSize, uOffset, bPhysContig, psSysAddr, pvCPUVAddr, ui32Flags, pBuf) != IMG_TRUE) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: WrapMemory FAILED")); -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof (BM_BUF), pBuf, IMG_NULL); -+ /*not nulling pointer, out of scope*/ -+ return IMG_FALSE; -+ } -+ -+ /* Only insert the buffer in the hash table if it is contiguous - allows for optimisation of multiple wraps -+ * of the same contiguous buffer. -+ */ -+ if(pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped || pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped_virtaddr) -+ { -+ /* Have we calculated the right Hash key ? */ -+ PVR_ASSERT(SysSysPAddrToCpuPAddr(sHashAddress).uiAddr == pBuf->CpuPAddr.uiAddr); -+ -+ if (!HASH_Insert (psBMContext->pBufferHash, (IMG_UINTPTR_T)sHashAddress.uiAddr, (IMG_UINTPTR_T)pBuf)) -+ { -+ FreeBuf (pBuf, ui32Flags, IMG_TRUE); -+ PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: HASH_Insert FAILED")); -+ return IMG_FALSE; -+ } -+ } -+ -+ PVR_DPF ((PVR_DBG_MESSAGE, -+ "BM_Wrap (uSize=0x%" SIZE_T_FMT_LEN "x, ui32Flags=0x%x, devVAddr=%08X)", -+ uSize, ui32Flags, pBuf->DevVAddr.uiAddr)); -+ -+ /* -+ * Assign the handle and return. -+ */ -+ pBuf->ui32RefCount = 1; -+ *phBuf = (BM_HANDLE)pBuf; -+ if(pui32Flags) -+ { -+ /* need to override the heap attributes SINGLE PROC to MULT_PROC. */ -+ *pui32Flags = (ui32Flags & ~PVRSRV_HAP_MAPTYPE_MASK) | PVRSRV_HAP_MULTI_PROCESS; -+ } -+ -+ return IMG_TRUE; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function BM_Export -+ -+ @Description Export a buffer previously allocated via BM_Alloc. -+ -+ @Input hBuf - buffer handle. -+ @Input ui32Flags - flags -+ -+ @Return None. -+ -+ *****************************************************************************/ -+ -+IMG_VOID -+BM_Export (BM_HANDLE hBuf) -+{ -+ BM_BUF *pBuf = (BM_BUF *)hBuf; -+ -+ PVRSRVBMBufIncExport(pBuf); -+} -+ -+/*! -+****************************************************************************** -+ @Function BM_Export -+ -+ @Description Export a buffer previously allocated via BM_Alloc. -+ -+ @Input hBuf - buffer handle. -+ -+ @Return None. -+**************************************************************************/ -+IMG_VOID -+BM_FreeExport(BM_HANDLE hBuf, -+ IMG_UINT32 ui32Flags) -+{ -+ BM_BUF *pBuf = (BM_BUF *)hBuf; -+ -+ PVRSRVBMBufDecExport(pBuf); -+ FreeBuf (pBuf, ui32Flags, IMG_FALSE); -+} -+ -+/*! -+****************************************************************************** -+ @Function BM_FreeExport -+ -+ @Description Free a buffer previously exported via BM_Export. -+ -+ @Input hBuf - buffer handle. -+ @Input ui32Flags - flags -+ -+ @Return None. -+**************************************************************************/ -+IMG_VOID -+BM_Free (BM_HANDLE hBuf, -+ IMG_UINT32 ui32Flags) -+{ -+ BM_BUF *pBuf = (BM_BUF *)hBuf; -+ SYS_DATA *psSysData; -+ IMG_SYS_PHYADDR sHashAddr; -+ -+ PVR_DPF ((PVR_DBG_MESSAGE, "BM_Free (h=0x%p)", hBuf)); -+ PVR_ASSERT (pBuf!=IMG_NULL); -+ -+ if (pBuf == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "BM_Free: invalid parameter")); -+ return; -+ } -+ -+ SysAcquireData(&psSysData); -+ -+ PVRSRVBMBufDecRef(pBuf); -+ if(pBuf->ui32RefCount == 0) -+ { -+ if(pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped || pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped_virtaddr) -+ { -+ sHashAddr = SysCpuPAddrToSysPAddr(pBuf->CpuPAddr); -+ -+ HASH_Remove (pBuf->pMapping->pBMHeap->pBMContext->pBufferHash, (IMG_UINTPTR_T)sHashAddr.uiAddr); -+ } -+ FreeBuf (pBuf, ui32Flags, IMG_TRUE); -+ } -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function BM_HandleToCpuVaddr -+ -+ @Description Retreive the cpu virtual address associated with a buffer. -+ -+ @Input buffer handle. -+ -+ @Return buffers cpu virtual address, or NULL if none exists -+ -+ *****************************************************************************/ -+IMG_CPU_VIRTADDR -+BM_HandleToCpuVaddr (BM_HANDLE hBuf) -+{ -+ BM_BUF *pBuf = (BM_BUF *)hBuf; -+ -+ PVR_ASSERT (pBuf != IMG_NULL); -+ if (pBuf == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "BM_HandleToCpuVaddr: invalid parameter")); -+ return IMG_NULL; -+ } -+ -+ PVR_DPF ((PVR_DBG_MESSAGE, -+ "BM_HandleToCpuVaddr(h=0x%p)=0x%p", -+ hBuf, pBuf->CpuVAddr)); -+ return pBuf->CpuVAddr; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function BM_HandleToDevVaddr -+ -+ @Description Retreive the device virtual address associated with a buffer. -+ -+ @Input hBuf - buffer handle. -+ -+ @Return buffers device virtual address. -+ -+ *****************************************************************************/ -+IMG_DEV_VIRTADDR -+BM_HandleToDevVaddr (BM_HANDLE hBuf) -+{ -+ BM_BUF *pBuf = (BM_BUF *)hBuf; -+ -+ PVR_ASSERT (pBuf != IMG_NULL); -+ if (pBuf == IMG_NULL) -+ { -+ IMG_DEV_VIRTADDR DevVAddr = {0}; -+ PVR_DPF((PVR_DBG_ERROR, "BM_HandleToDevVaddr: invalid parameter")); -+ return DevVAddr; -+ } -+ -+ PVR_DPF ((PVR_DBG_MESSAGE, "BM_HandleToDevVaddr(h=0x%p)=%08X", hBuf, pBuf->DevVAddr.uiAddr)); -+ return pBuf->DevVAddr; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function BM_HandleToSysPaddr -+ -+ @Description Retreive the system physical address associated with a buffer. -+ -+ @Input hBuf - buffer handle. -+ -+ @Return buffers device virtual address. -+ -+ *****************************************************************************/ -+IMG_SYS_PHYADDR -+BM_HandleToSysPaddr (BM_HANDLE hBuf) -+{ -+ BM_BUF *pBuf = (BM_BUF *)hBuf; -+ -+ PVR_ASSERT (pBuf != IMG_NULL); -+ -+ if (pBuf == IMG_NULL) -+ { -+ IMG_SYS_PHYADDR PhysAddr = {0}; -+ PVR_DPF((PVR_DBG_ERROR, "BM_HandleToSysPaddr: invalid parameter")); -+ return PhysAddr; -+ } -+ -+ PVR_DPF ((PVR_DBG_MESSAGE, "BM_HandleToSysPaddr(h=0lx%p)=" CPUPADDR_FMT, hBuf, pBuf->CpuPAddr.uiAddr)); -+ return SysCpuPAddrToSysPAddr (pBuf->CpuPAddr); -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function BM_HandleToMemOSHandle -+ -+ @Description Retreive the underlying memory handle associated with a buffer. -+ -+ @Input hBuf - buffer handle. -+ -+ @Return OS Specific memory handle. -+ -+ *****************************************************************************/ -+IMG_HANDLE -+BM_HandleToOSMemHandle(BM_HANDLE hBuf) -+{ -+ BM_BUF *pBuf = (BM_BUF *)hBuf; -+ -+ PVR_ASSERT (pBuf != IMG_NULL); -+ -+ if (pBuf == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "BM_HandleToOSMemHandle: invalid parameter")); -+ return IMG_NULL; -+ } -+ -+ PVR_DPF ((PVR_DBG_MESSAGE, -+ "BM_HandleToOSMemHandle(h=0x%p)=0x%p", -+ hBuf, pBuf->hOSMemHandle)); -+ return pBuf->hOSMemHandle; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function DevMemoryAlloc -+ -+ @Description Allocate device memory for a given physical/virtual memory -+ mapping. We handle the main cases where device MMU mappings -+ are required - these are the dynamic cases: all wrappings of -+ host OS memory and host OS imports for SYS_MMU_NORMAL mode. -+ -+ If no MMU support is required then we simply map device virtual -+ space as device physical space. -+ -+ @Input pBMContext - the pager to allocate from. -+ @Output pMapping - the mapping descriptor to be filled in for this -+ allocation. -+ @Output pActualSize - the actual size of the block allocated in -+ bytes. -+ @Input ui32Flags - allocation flags -+ @Input dev_vaddr_alignment - required device virtual address -+ alignment, or 0. -+ @Output pDevVAddr - receives the device virtual base address of the -+ allocated block. -+ @Return IMG_TRUE - Success -+ IMG_FALSE - Failed. -+ -+ *****************************************************************************/ -+static IMG_BOOL -+DevMemoryAlloc (BM_CONTEXT *pBMContext, -+ BM_MAPPING *pMapping, -+ IMG_SIZE_T *pActualSize, -+ IMG_UINT32 ui32Flags, -+ IMG_UINT32 dev_vaddr_alignment, -+ IMG_DEV_VIRTADDR *pDevVAddr) -+{ -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+#ifdef PDUMP -+ IMG_UINT32 ui32PDumpSize = (IMG_UINT32)pMapping->uSize; -+ IMG_UINT32 ui32PDumpFlags; -+#endif -+ -+ psDeviceNode = pBMContext->psDeviceNode; -+ -+#ifdef PDUMP -+#if defined(SUPPORT_PDUMP_MULTI_PROCESS) -+ ui32PDumpFlags = psDeviceNode->pfnMMUIsHeapShared(pMapping->pBMHeap->pMMUHeap) -+ ? PDUMP_FLAGS_PERSISTENT : PDUMP_FLAGS_CONTINUOUS; -+#else -+ ui32PDumpFlags = PDUMP_FLAGS_CONTINUOUS; -+#endif -+#endif -+ -+ if(ui32Flags & PVRSRV_MEM_INTERLEAVED) -+ { -+ /* double the size */ -+ pMapping->uSize *= 2; -+ } -+ -+#ifdef PDUMP -+ if(ui32Flags & PVRSRV_MEM_DUMMY) -+ { -+ /* only one page behind a dummy allocation */ -+ ui32PDumpSize = pMapping->pBMHeap->sDevArena.ui32DataPageSize; -+ } -+#endif -+ -+ /* Check we haven't fall through a gap */ -+ PVR_ASSERT(pMapping->uSizeVM != 0); -+ /* allocate device linear space */ -+ if (!psDeviceNode->pfnMMUAlloc (pMapping->pBMHeap->pMMUHeap, -+ pMapping->uSizeVM, -+ pActualSize, -+ 0, -+ dev_vaddr_alignment, -+ &(pMapping->DevVAddr))) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "DevMemoryAlloc ERROR MMU_Alloc")); -+ return IMG_FALSE; -+ } -+ -+#ifdef SUPPORT_SGX_MMU_BYPASS -+ EnableHostAccess(pBMContext->psMMUContext); -+#endif -+ -+#if defined(PDUMP) -+ /* pdump the memory allocate */ -+ PDUMPMALLOCPAGES(&psDeviceNode->sDevId, -+ pMapping->DevVAddr.uiAddr, -+ pMapping->CpuVAddr, -+ pMapping->hOSMemHandle, -+ ui32PDumpSize, -+ pMapping->pBMHeap->sDevArena.ui32DataPageSize, -+ (IMG_HANDLE)pMapping, -+ ui32PDumpFlags); -+#endif -+ -+ switch (pMapping->eCpuMemoryOrigin) -+ { -+ case hm_wrapped: -+ case hm_wrapped_virtaddr: -+ case hm_contiguous: -+ { -+ if (ui32Flags & PVRSRV_MEM_SPARSE) -+ { -+ /* Check if this device supports sparse mappings */ -+ PVR_ASSERT(psDeviceNode->pfnMMUMapPagesSparse != IMG_NULL); -+ psDeviceNode->pfnMMUMapPagesSparse(pMapping->pBMHeap->pMMUHeap, -+ pMapping->DevVAddr, -+ SysCpuPAddrToSysPAddr (pMapping->CpuPAddr), -+ pMapping->ui32ChunkSize, -+ pMapping->ui32NumVirtChunks, -+ pMapping->ui32NumPhysChunks, -+ pMapping->pabMapChunk, -+ ui32Flags, -+ (IMG_HANDLE)pMapping); -+ } -+ else -+ { -+ psDeviceNode->pfnMMUMapPages ( pMapping->pBMHeap->pMMUHeap, -+ pMapping->DevVAddr, -+ SysCpuPAddrToSysPAddr (pMapping->CpuPAddr), -+ pMapping->uSize, -+ ui32Flags, -+ (IMG_HANDLE)pMapping); -+ } -+ *pDevVAddr = pMapping->DevVAddr; -+ break; -+ } -+ case hm_env: -+ { -+ if (ui32Flags & PVRSRV_MEM_SPARSE) -+ { -+ /* Check if this device supports sparse mappings */ -+ PVR_ASSERT(psDeviceNode->pfnMMUMapShadowSparse != IMG_NULL); -+ psDeviceNode->pfnMMUMapShadowSparse(pMapping->pBMHeap->pMMUHeap, -+ pMapping->DevVAddr, -+ pMapping->ui32ChunkSize, -+ pMapping->ui32NumVirtChunks, -+ pMapping->ui32NumPhysChunks, -+ pMapping->pabMapChunk, -+ pMapping->CpuVAddr, -+ pMapping->hOSMemHandle, -+ pDevVAddr, -+ ui32Flags, -+ (IMG_HANDLE)pMapping); -+ } -+ else -+ { -+ psDeviceNode->pfnMMUMapShadow ( pMapping->pBMHeap->pMMUHeap, -+ pMapping->DevVAddr, -+ pMapping->uSize, -+ pMapping->CpuVAddr, -+ pMapping->hOSMemHandle, -+ pDevVAddr, -+ ui32Flags, -+ (IMG_HANDLE)pMapping); -+ } -+ break; -+ } -+ case hm_wrapped_scatter: -+ case hm_wrapped_scatter_virtaddr: -+ { -+ psDeviceNode->pfnMMUMapScatter (pMapping->pBMHeap->pMMUHeap, -+ pMapping->DevVAddr, -+ pMapping->psSysAddr, -+ pMapping->uSize, -+ ui32Flags, -+ (IMG_HANDLE)pMapping); -+ -+ *pDevVAddr = pMapping->DevVAddr; -+ break; -+ } -+ default: -+ PVR_DPF((PVR_DBG_ERROR, -+ "Illegal value %d for pMapping->eCpuMemoryOrigin", -+ pMapping->eCpuMemoryOrigin)); -+ return IMG_FALSE; -+ } -+ -+#ifdef SUPPORT_SGX_MMU_BYPASS -+ DisableHostAccess(pBMContext->psMMUContext); -+#endif -+ -+ return IMG_TRUE; -+} -+ -+static IMG_VOID -+DevMemoryFree (BM_MAPPING *pMapping) -+{ -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+ IMG_DEV_PHYADDR sDevPAddr; -+#ifdef PDUMP -+ IMG_UINT32 ui32PSize; -+ IMG_UINT32 ui32PDumpFlags; -+#endif -+ -+ psDeviceNode = pMapping->pBMHeap->pBMContext->psDeviceNode; -+ sDevPAddr = psDeviceNode->pfnMMUGetPhysPageAddr(pMapping->pBMHeap->pMMUHeap, pMapping->DevVAddr); -+ -+#ifdef PDUMP -+#if defined(SUPPORT_PDUMP_MULTI_PROCESS) -+ ui32PDumpFlags = psDeviceNode->pfnMMUIsHeapShared(pMapping->pBMHeap->pMMUHeap) -+ ? PDUMP_FLAGS_PERSISTENT : PDUMP_FLAGS_CONTINUOUS; -+#else -+ ui32PDumpFlags = PDUMP_FLAGS_CONTINUOUS; -+#endif -+#endif -+ -+ if (sDevPAddr.uiAddr != 0) -+ { -+#ifdef PDUMP -+ /* pdump the memory free */ -+ if(pMapping->ui32Flags & PVRSRV_MEM_DUMMY) -+ { -+ /* physical memory size differs in the case of Dummy allocations */ -+ ui32PSize = pMapping->pBMHeap->sDevArena.ui32DataPageSize; -+ } -+ else -+ { -+ ui32PSize = (IMG_UINT32)pMapping->uSize; -+ } -+ -+ PDUMPFREEPAGES(pMapping->pBMHeap, -+ pMapping->DevVAddr, -+ ui32PSize, -+ pMapping->pBMHeap->sDevArena.ui32DataPageSize, -+ (IMG_HANDLE)pMapping, -+ (pMapping->ui32Flags & PVRSRV_MEM_INTERLEAVED) ? IMG_TRUE : IMG_FALSE, -+ (pMapping->ui32Flags & PVRSRV_MEM_SPARSE) ? IMG_TRUE : IMG_FALSE, -+ ui32PDumpFlags); -+#endif -+ } -+ PVR_ASSERT(pMapping->uSizeVM != 0); -+ psDeviceNode->pfnMMUFree (pMapping->pBMHeap->pMMUHeap, pMapping->DevVAddr, IMG_CAST_TO_DEVVADDR_UINT(pMapping->uSizeVM)); -+} -+ -+/* If this array grows larger, it might be preferable to use a hashtable rather than an array. */ -+#ifndef XPROC_WORKAROUND_NUM_SHAREABLES -+#define XPROC_WORKAROUND_NUM_SHAREABLES 200 -+#endif -+ -+#define XPROC_WORKAROUND_BAD_SHAREINDEX 0773407734 -+ -+#define XPROC_WORKAROUND_UNKNOWN 0 -+#define XPROC_WORKAROUND_ALLOC 1 -+#define XPROC_WORKAROUND_MAP 2 -+ -+static IMG_UINT32 gXProcWorkaroundShareIndex = XPROC_WORKAROUND_BAD_SHAREINDEX; -+static IMG_UINT32 gXProcWorkaroundState = XPROC_WORKAROUND_UNKNOWN; -+ -+/* PRQA S 0686 10 */ /* force compiler to init structure */ -+XPROC_DATA gXProcWorkaroundShareData[XPROC_WORKAROUND_NUM_SHAREABLES] = {{0}}; -+ -+PVRSRV_ERROR BM_XProcWorkaroundSetShareIndex(IMG_UINT32 ui32Index) -+{ -+ /* if you fail this assertion - did you acquire the mutex? -+ did you call "set" exactly once? -+ did you call "unset" exactly once per set? -+ */ -+ if (gXProcWorkaroundShareIndex != XPROC_WORKAROUND_BAD_SHAREINDEX) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "No, it's already set!")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ gXProcWorkaroundShareIndex = ui32Index; -+ gXProcWorkaroundState = XPROC_WORKAROUND_MAP; -+ -+ return PVRSRV_OK; -+} -+ -+PVRSRV_ERROR BM_XProcWorkaroundUnsetShareIndex(IMG_UINT32 ui32Index) -+{ -+ /* if you fail this assertion - did you acquire the mutex? -+ did you call "set" exactly once? -+ did you call "unset" exactly once per set? -+ */ -+ if (gXProcWorkaroundShareIndex == XPROC_WORKAROUND_BAD_SHAREINDEX) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "huh? how can it be bad??")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ if (gXProcWorkaroundShareIndex != ui32Index) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "gXProcWorkaroundShareIndex == 0x%08x != 0x%08x == ui32Index", gXProcWorkaroundShareIndex, ui32Index)); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ gXProcWorkaroundShareIndex = XPROC_WORKAROUND_BAD_SHAREINDEX; -+ gXProcWorkaroundState = XPROC_WORKAROUND_UNKNOWN; -+ -+ return PVRSRV_OK; -+} -+ -+PVRSRV_ERROR BM_XProcWorkaroundFindNewBufferAndSetShareIndex(IMG_UINT32 *pui32Index) -+{ -+ /* if you fail this assertion - did you acquire the mutex? -+ did you call "set" exactly once? -+ did you call "unset" exactly once per set? -+ */ -+ if (gXProcWorkaroundShareIndex != XPROC_WORKAROUND_BAD_SHAREINDEX) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ for (*pui32Index = 0; *pui32Index < XPROC_WORKAROUND_NUM_SHAREABLES; (*pui32Index)++) -+ { -+ if (gXProcWorkaroundShareData[*pui32Index].ui32RefCount == 0) -+ { -+ gXProcWorkaroundShareIndex = *pui32Index; -+ gXProcWorkaroundState = XPROC_WORKAROUND_ALLOC; -+ return PVRSRV_OK; -+ } -+ } -+ -+ PVR_DPF((PVR_DBG_ERROR, "ran out of shared buffers")); -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+} -+ -+static PVRSRV_ERROR -+XProcWorkaroundAllocShareable(RA_ARENA *psArena, -+ IMG_UINT32 ui32AllocFlags, -+ IMG_UINT32 ui32Size, -+ IMG_UINT32 ui32PageSize, -+ IMG_PVOID pvPrivData, -+ IMG_UINT32 ui32PrivDataLength, -+ IMG_VOID **ppvCpuVAddr, -+ IMG_HANDLE *phOSMemHandle) -+{ -+ if ((ui32AllocFlags & PVRSRV_MEM_XPROC) == 0) -+ { -+ PVR_DPF((PVR_DBG_VERBOSE, "XProcWorkaroundAllocShareable: bad flags")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ if (gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32RefCount > 0) -+ { -+ PVR_DPF((PVR_DBG_VERBOSE, -+ "XProcWorkaroundAllocShareable: re-using previously allocated pages")); -+ -+ ui32AllocFlags &= ~PVRSRV_HAP_MAPTYPE_MASK; -+ ui32AllocFlags |= PVRSRV_HAP_SINGLE_PROCESS; -+ -+ if (ui32AllocFlags != gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32AllocFlags) -+ { -+ PVR_DPF((PVR_DBG_ERROR, -+ "Can't! Flags don't match! (I had 0x%08x, you gave 0x%08x)", -+ gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32AllocFlags, -+ ui32AllocFlags)); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ if (ui32Size != gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32Size) -+ { -+ PVR_DPF((PVR_DBG_ERROR, -+ "Can't! Size doesn't match!")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ if (ui32PageSize != gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32PageSize) -+ { -+ PVR_DPF((PVR_DBG_ERROR, -+ "Can't! Page Size doesn't match!")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ *ppvCpuVAddr = gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].pvCpuVAddr; -+ *phOSMemHandle = gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].hOSMemHandle; -+ -+ BM_XProcIndexAcquire(gXProcWorkaroundShareIndex); -+ -+ return PVRSRV_OK; -+ } -+ else -+ { -+ if (gXProcWorkaroundState != XPROC_WORKAROUND_ALLOC) -+ { -+ PVR_DPF((PVR_DBG_ERROR, -+ "XPROC workaround in bad state! About to allocate memory from non-alloc state! (%d)", -+ gXProcWorkaroundState)); -+ } -+ PVR_ASSERT(gXProcWorkaroundState == XPROC_WORKAROUND_ALLOC); -+ -+ if (psArena != IMG_NULL) -+ { -+ IMG_CPU_PHYADDR sCpuPAddr; -+ IMG_SYS_PHYADDR sSysPAddr; -+ -+ PVR_DPF((PVR_DBG_VERBOSE, -+ "XProcWorkaroundAllocShareable: making a NEW allocation from local mem")); -+ -+ if (!RA_Alloc (psArena, -+ ui32Size, -+ IMG_NULL, -+ IMG_NULL, -+ 0, -+ ui32PageSize, -+ 0, -+ pvPrivData, -+ ui32PrivDataLength, -+ (IMG_UINTPTR_T *)&sSysPAddr.uiAddr)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "XProcWorkaroundAllocShareable: RA_Alloc(0x%x) FAILED", ui32Size)); -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ -+ sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr); -+ if(OSReservePhys(sCpuPAddr, -+ ui32Size, -+ ui32AllocFlags, -+ IMG_NULL, -+ (IMG_VOID **)&gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].pvCpuVAddr, -+ &gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].hOSMemHandle) != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "XProcWorkaroundAllocShareable: OSReservePhys failed")); -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].sSysPAddr = sSysPAddr; -+ } -+ else -+ { -+ PVR_DPF((PVR_DBG_VERBOSE, -+ "XProcWorkaroundAllocShareable: making a NEW allocation from OS")); -+ -+ ui32AllocFlags &= ~PVRSRV_HAP_MAPTYPE_MASK; -+ ui32AllocFlags |= PVRSRV_HAP_SINGLE_PROCESS; -+ -+ /* allocate pages from the OS RAM */ -+ if (OSAllocPages(ui32AllocFlags, -+ ui32Size, -+ ui32PageSize, -+ pvPrivData, -+ ui32PrivDataLength, -+ IMG_NULL, /* FIXME: to support cross process sparse allocations */ -+ (IMG_VOID **)&gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].pvCpuVAddr, -+ &gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].hOSMemHandle) != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, -+ "XProcWorkaroundAllocShareable: OSAllocPages(0x%x) failed", -+ ui32PageSize)); -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ } -+ -+ gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].psArena = psArena; -+ gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32AllocFlags = ui32AllocFlags; -+ gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32Size = ui32Size; -+ gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].ui32PageSize = ui32PageSize; -+ -+ *ppvCpuVAddr = gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].pvCpuVAddr; -+ *phOSMemHandle = gXProcWorkaroundShareData[gXProcWorkaroundShareIndex].hOSMemHandle; -+ -+ BM_XProcIndexAcquire(gXProcWorkaroundShareIndex); -+ -+ return PVRSRV_OK; -+ } -+} -+ -+static PVRSRV_ERROR XProcWorkaroundHandleToSI(IMG_HANDLE hOSMemHandle, IMG_UINT32 *pui32SI) -+{ -+ IMG_UINT32 ui32SI; -+ IMG_BOOL bFound; -+ IMG_BOOL bErrorDups; -+ -+ bFound = IMG_FALSE; -+ bErrorDups = IMG_FALSE; -+ -+ for (ui32SI = 0; ui32SI < XPROC_WORKAROUND_NUM_SHAREABLES; ui32SI++) -+ { -+ if (gXProcWorkaroundShareData[ui32SI].ui32RefCount>0 && gXProcWorkaroundShareData[ui32SI].hOSMemHandle == hOSMemHandle) -+ { -+ if (bFound) -+ { -+ bErrorDups = IMG_TRUE; -+ } -+ else -+ { -+ *pui32SI = ui32SI; -+ bFound = IMG_TRUE; -+ } -+ } -+ } -+ -+ if (bErrorDups || !bFound) -+ { -+ return PVRSRV_ERROR_BM_BAD_SHAREMEM_HANDLE; -+ } -+ -+ return PVRSRV_OK; -+} -+ -+#if defined(PVRSRV_REFCOUNT_DEBUG) -+IMG_VOID _BM_XProcIndexAcquireDebug(const IMG_CHAR *pszFile, IMG_INT iLine, IMG_UINT32 ui32Index) -+#else -+IMG_VOID _BM_XProcIndexAcquire(IMG_UINT32 ui32Index) -+#endif -+{ -+#if defined(PVRSRV_REFCOUNT_DEBUG) -+ PVRSRVBMXProcIncRef2(pszFile, iLine, ui32Index); -+#else -+ PVRSRVBMXProcIncRef(ui32Index); -+#endif -+} -+ -+#if defined(PVRSRV_REFCOUNT_DEBUG) -+IMG_VOID _BM_XProcIndexReleaseDebug(const IMG_CHAR *pszFile, IMG_INT iLine, IMG_UINT32 ui32Index) -+#else -+IMG_VOID _BM_XProcIndexRelease(IMG_UINT32 ui32Index) -+#endif -+{ -+#if defined(PVRSRV_REFCOUNT_DEBUG) -+ PVRSRVBMXProcDecRef2(pszFile, iLine, ui32Index); -+#else -+ PVRSRVBMXProcDecRef(ui32Index); -+#endif -+ -+ PVR_DPF((PVR_DBG_VERBOSE, "Reduced refcount of SI[%d] from %d to %d", -+ ui32Index, gXProcWorkaroundShareData[ui32Index].ui32RefCount+1, gXProcWorkaroundShareData[ui32Index].ui32RefCount)); -+ -+ if (gXProcWorkaroundShareData[ui32Index].ui32RefCount == 0) -+ { -+ if (gXProcWorkaroundShareData[ui32Index].psArena != IMG_NULL) -+ { -+ IMG_SYS_PHYADDR sSysPAddr; -+ -+ if (gXProcWorkaroundShareData[ui32Index].pvCpuVAddr != IMG_NULL) -+ { -+ OSUnReservePhys(gXProcWorkaroundShareData[ui32Index].pvCpuVAddr, -+ gXProcWorkaroundShareData[ui32Index].ui32Size, -+ gXProcWorkaroundShareData[ui32Index].ui32AllocFlags, -+ gXProcWorkaroundShareData[ui32Index].hOSMemHandle); -+ } -+ sSysPAddr = gXProcWorkaroundShareData[ui32Index].sSysPAddr; -+ RA_Free (gXProcWorkaroundShareData[ui32Index].psArena, -+ (IMG_UINTPTR_T)sSysPAddr.uiAddr, -+ IMG_FALSE); -+ } -+ else -+ { -+ PVR_DPF((PVR_DBG_VERBOSE, "freeing OS memory")); -+ OSFreePages(gXProcWorkaroundShareData[ui32Index].ui32AllocFlags, -+ gXProcWorkaroundShareData[ui32Index].ui32PageSize, -+ gXProcWorkaroundShareData[ui32Index].pvCpuVAddr, -+ gXProcWorkaroundShareData[ui32Index].hOSMemHandle); -+ } -+ } -+} -+ -+static IMG_VOID XProcWorkaroundFreeShareable(IMG_HANDLE hOSMemHandle) -+{ -+ IMG_UINT32 ui32SI = (IMG_UINT32)((IMG_UINTPTR_T)hOSMemHandle & 0xffffU); -+ PVRSRV_ERROR eError; -+ -+ eError = XProcWorkaroundHandleToSI(hOSMemHandle, &ui32SI); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "bad handle")); -+ return; -+ } -+ -+ BM_XProcIndexRelease(ui32SI); -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function BM_ImportMemory -+ -+ @Description Provide a resource allocator with a source of pages of memory -+ from the Host OS's own allocation. Allocates a block of pages -+ larger than requested, allowing the resource allocator to -+ operate a small cache of pre allocated pages. -+ -+ @Input pH - buffer manager handle, not the void type is dictated -+ by the generic nature of the resource allocator interface. -+ @Input uRequestSize - requested size in bytes -+ @Output pActualSize - receives the actual size allocated in bytes -+ which may be >= requested size -+ @Output ppsMapping - receives the arbitrary user reference -+ associated with the underlying storage. -+ @Input ui32Flags - bit mask of allocation flags -+ @Input pvPrivData - opaque private data passed through to allocator -+ @Input ui32PrivDataLength - length of opaque private data -+ @Output pBase - receives a pointer to the allocated storage. -+ -+ @Return IMG_TRUE - success -+ IMG_FALSE - failed -+ -+ *****************************************************************************/ -+static IMG_BOOL -+BM_ImportMemory (IMG_VOID *pH, -+ IMG_SIZE_T uRequestSize, -+ IMG_SIZE_T *pActualSize, -+ BM_MAPPING **ppsMapping, -+ IMG_UINT32 ui32Flags, -+ IMG_PVOID pvPrivData, -+ IMG_UINT32 ui32PrivDataLength, -+ IMG_UINTPTR_T *pBase) -+{ -+ BM_MAPPING *pMapping; -+ BM_HEAP *pBMHeap = pH; -+ BM_CONTEXT *pBMContext = pBMHeap->pBMContext; -+ IMG_BOOL bResult; -+ IMG_SIZE_T uSize; -+ IMG_SIZE_T uPSize; -+ IMG_SIZE_T uDevVAddrAlignment = 0; /* ? */ -+ -+ PVR_DPF ((PVR_DBG_MESSAGE, -+ "BM_ImportMemory (pBMContext=0x%p, uRequestSize=0x%" SIZE_T_FMT_LEN -+ "x, ui32Flags=0x%x, uAlign=0x%" SIZE_T_FMT_LEN "x)", -+ pBMContext, uRequestSize, ui32Flags, uDevVAddrAlignment)); -+ -+ PVR_ASSERT (ppsMapping != IMG_NULL); -+ PVR_ASSERT (pBMContext != IMG_NULL); -+ -+ if (ppsMapping == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "BM_ImportMemory: invalid parameter")); -+ goto fail_exit; -+ } -+ -+ uSize = HOST_PAGEALIGN (uRequestSize); -+ PVR_ASSERT (uSize >= uRequestSize); -+ -+ if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof (BM_MAPPING), -+ (IMG_PVOID *)&pMapping, IMG_NULL, -+ "Buffer Manager Mapping") != PVRSRV_OK) -+ { -+ PVR_DPF ((PVR_DBG_ERROR, "BM_ImportMemory: failed BM_MAPPING alloc")); -+ goto fail_exit; -+ } -+ -+ pMapping->hOSMemHandle = 0; -+ pMapping->CpuVAddr = 0; -+ pMapping->DevVAddr.uiAddr = 0; -+ pMapping->CpuPAddr.uiAddr = 0; -+ pMapping->uSize = uSize; -+ if ((ui32Flags & PVRSRV_MEM_SPARSE) == 0) -+ { -+ pMapping->uSizeVM = uSize; -+ } -+ pMapping->pBMHeap = pBMHeap; -+ pMapping->ui32Flags = ui32Flags; -+ -+ /* -+ * If anyone want's to know, pass back the actual size of our allocation. -+ * There could be up to an extra page's worth of memory which will be marked -+ * as free in the RA. -+ */ -+ if (pActualSize) -+ { -+ *pActualSize = uSize; -+ } -+ -+ /* if it's a dummy allocation only use one physical page */ -+ if(pMapping->ui32Flags & PVRSRV_MEM_DUMMY) -+ { -+ uPSize = pBMHeap->sDevArena.ui32DataPageSize; -+ } -+ else -+ { -+ uPSize = pMapping->uSize; -+ } -+ -+ if (ui32Flags & PVRSRV_MEM_XPROC) -+ { -+ IMG_UINT32 ui32Attribs = pBMHeap->ui32Attribs | PVRSRV_MEM_XPROC; -+ IMG_BOOL bBadBackingStoreType; -+ -+ if(ui32Flags & PVRSRV_MEM_ION) -+ { -+ ui32Attribs |= PVRSRV_MEM_ION; -+ } -+ -+ bBadBackingStoreType = IMG_TRUE; -+ -+ if ((ui32Attribs & PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG) != 0) -+ { -+ uDevVAddrAlignment = MAX(pBMHeap->sDevArena.ui32DataPageSize, HOST_PAGESIZE()); -+ -+ -+ if (uPSize % uDevVAddrAlignment != 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "Cannot use use this memory sharing workaround with allocations that might be suballocated")); -+ goto fail_mapping_alloc; -+ } -+ uDevVAddrAlignment = 0; /* FIXME: find out why it doesn't work if alignment is specified */ -+ -+ /* If the user has specified heap CACHETYPE flags, use them to -+ * override the flags inherited from the heap. -+ */ -+ if (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK) -+ { -+ ui32Attribs &= ~PVRSRV_HAP_CACHETYPE_MASK; -+ ui32Attribs |= (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK); -+ } -+ -+ /* allocate "shared" pages. */ -+ if (XProcWorkaroundAllocShareable(IMG_NULL, -+ ui32Attribs, -+ (IMG_UINT32)uPSize, -+ pBMHeap->sDevArena.ui32DataPageSize, -+ pvPrivData, -+ ui32PrivDataLength, -+ (IMG_VOID **)&pMapping->CpuVAddr, -+ &pMapping->hOSMemHandle) != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, -+ "BM_ImportMemory: XProcWorkaroundAllocShareable(0x%" SIZE_T_FMT_LEN "x) failed", -+ uPSize)); -+ goto fail_mapping_alloc; -+ } -+ -+ /* specify how page addresses are derived */ -+ /* it works just like "env" now - no need to record -+ it as shareable, as we use the actual hOSMemHandle -+ and only divert to our wrapper layer based on Attribs */ -+ pMapping->eCpuMemoryOrigin = hm_env; -+ bBadBackingStoreType = IMG_FALSE; -+ } -+ -+ if ((ui32Attribs & PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG) != 0) -+ { -+ uDevVAddrAlignment = pBMHeap->sDevArena.ui32DataPageSize; -+ -+ if (uPSize % uDevVAddrAlignment != 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "Cannot use use this memory sharing workaround with allocations that might be suballocated")); -+ goto fail_mapping_alloc; -+ } -+ uDevVAddrAlignment = 0; /* FIXME: find out why it doesn't work if alignment is specified */ -+ -+ /* If the user has specified heap CACHETYPE flags, use them to -+ * override the flags inherited from the heap. -+ */ -+ if (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK) -+ { -+ ui32Attribs &= ~PVRSRV_HAP_CACHETYPE_MASK; -+ ui32Attribs |= (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK); -+ } -+ -+ /* allocate "shared" pages. */ -+ if (XProcWorkaroundAllocShareable(pBMHeap->pLocalDevMemArena, -+ ui32Attribs, -+ (IMG_UINT32)uPSize, -+ pBMHeap->sDevArena.ui32DataPageSize, -+ pvPrivData, -+ ui32PrivDataLength, -+ (IMG_VOID **)&pMapping->CpuVAddr, -+ &pMapping->hOSMemHandle) != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, -+ "BM_ImportMemory: XProcWorkaroundAllocShareable(0x%" SIZE_T_FMT_LEN "x) failed", -+ uPSize)); -+ goto fail_mapping_alloc; -+ } -+ -+ /* specify how page addresses are derived */ -+ /* it works just like "env" now - no need to record -+ it as shareable, as we use the actual hOSMemHandle -+ and only divert to our wrapper layer based on Attribs */ -+ pMapping->eCpuMemoryOrigin = hm_env; -+ bBadBackingStoreType = IMG_FALSE; -+ } -+ -+ if (bBadBackingStoreType) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "Cannot use this memory sharing workaround with this type of backing store")); -+ goto fail_mapping_alloc; -+ } -+ } -+ else -+ -+ /* -+ What type of backing store do we have? -+ */ -+ if(pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG) -+ { -+ IMG_UINT32 ui32Attribs = pBMHeap->ui32Attribs; -+ -+ /* The allocation code needs to know this is a sparse mapping */ -+ if (pMapping->ui32Flags & PVRSRV_MEM_SPARSE) -+ { -+ ui32Attribs |= PVRSRV_MEM_SPARSE; -+ } -+ -+ /* If the user has specified heap CACHETYPE flags, use them to -+ * override the flags inherited from the heap. -+ */ -+ if (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK) -+ { -+ ui32Attribs &= ~PVRSRV_HAP_CACHETYPE_MASK; -+ ui32Attribs |= (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK); -+ } -+ -+ if (pMapping->ui32Flags & PVRSRV_MEM_ALLOCATENONCACHEDMEM) -+ { -+ ui32Attribs &= ~PVRSRV_MEM_ALLOCATENONCACHEDMEM; -+ ui32Attribs |= (pMapping->ui32Flags & PVRSRV_MEM_ALLOCATENONCACHEDMEM); -+ } -+ -+ /* allocate pages from the OS RAM */ -+ if (OSAllocPages(ui32Attribs, -+ uPSize, -+ pBMHeap->sDevArena.ui32DataPageSize, -+ pvPrivData, -+ ui32PrivDataLength, -+ pMapping, -+ (IMG_VOID **)&pMapping->CpuVAddr, -+ &pMapping->hOSMemHandle) != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, -+ "BM_ImportMemory: OSAllocPages(0x%" SIZE_T_FMT_LEN "x) failed", -+ uPSize)); -+ goto fail_mapping_alloc; -+ } -+ -+ /* specify how page addresses are derived */ -+ pMapping->eCpuMemoryOrigin = hm_env; -+ } -+ else if(pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG) -+ { -+ IMG_SYS_PHYADDR sSysPAddr; -+ IMG_UINT32 ui32Attribs = pBMHeap->ui32Attribs; -+ -+ /* The allocation code needs to know this is a sparse mapping */ -+ if (pMapping->ui32Flags & PVRSRV_MEM_SPARSE) -+ { -+ ui32Attribs |= PVRSRV_MEM_SPARSE; -+ } -+ -+ /* allocate pages from the local device memory allocator */ -+ PVR_ASSERT(pBMHeap->pLocalDevMemArena != IMG_NULL); -+ -+ /* If the user has specified heap CACHETYPE flags, use them to -+ * override the flags inherited from the heap. -+ */ -+ if (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK) -+ { -+ ui32Attribs &= ~PVRSRV_HAP_CACHETYPE_MASK; -+ ui32Attribs |= (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK); -+ } -+ -+ if (!RA_Alloc (pBMHeap->pLocalDevMemArena, -+ uPSize, -+ IMG_NULL, -+ IMG_NULL, -+ 0, -+ pBMHeap->sDevArena.ui32DataPageSize, -+ 0, -+ pvPrivData, -+ ui32PrivDataLength, -+ (IMG_UINTPTR_T *)&sSysPAddr.uiAddr)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "BM_ImportMemory: RA_Alloc(0x%" SIZE_T_FMT_LEN "x) FAILED", uPSize)); -+ goto fail_mapping_alloc; -+ } -+ -+ /* derive the CPU virtual address */ -+ pMapping->CpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr); -+ if(OSReservePhys(pMapping->CpuPAddr, -+ uPSize, -+ ui32Attribs, -+ pMapping, -+ &pMapping->CpuVAddr, -+ &pMapping->hOSMemHandle) != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "BM_ImportMemory: OSReservePhys failed")); -+ goto fail_dev_mem_alloc; -+ } -+ -+ /* specify how page addresses are derived */ -+ pMapping->eCpuMemoryOrigin = hm_contiguous; -+ } -+ else -+ { -+ PVR_DPF((PVR_DBG_ERROR, "BM_ImportMemory: Invalid backing store type")); -+ goto fail_mapping_alloc; -+ } -+ -+ /* -+ * Allocate some device memory for what we just allocated. -+ */ -+ if ((ui32Flags & PVRSRV_MEM_SPARSE) == 0) -+ { -+ bResult = DevMemoryAlloc (pBMContext, -+ pMapping, -+ IMG_NULL, -+ ui32Flags, -+ (IMG_UINT32)uDevVAddrAlignment, -+ &pMapping->DevVAddr); -+ if (!bResult) -+ { -+ PVR_DPF((PVR_DBG_ERROR, -+ "BM_ImportMemory: DevMemoryAlloc(0x%" SIZE_T_FMT_LEN "x) failed", -+ pMapping->uSize)); -+ goto fail_dev_mem_alloc; -+ } -+ -+ /* uDevVAddrAlignment is currently set to zero so QAC generates warning which we override */ -+ /* PRQA S 3356,3358 1 */ -+ PVR_ASSERT (uDevVAddrAlignment>1?(pMapping->DevVAddr.uiAddr%uDevVAddrAlignment)==0:1); -+ PVR_ASSERT(pBase); -+ *pBase = pMapping->DevVAddr.uiAddr; -+ } -+ -+ *ppsMapping = pMapping; -+ -+ PVR_DPF ((PVR_DBG_MESSAGE, "BM_ImportMemory: IMG_TRUE")); -+ return IMG_TRUE; -+ -+fail_dev_mem_alloc: -+ if (pMapping && (pMapping->CpuVAddr || pMapping->hOSMemHandle)) -+ { -+ /* the size is double the actual size for interleaved allocations */ -+ if(pMapping->ui32Flags & PVRSRV_MEM_INTERLEAVED) -+ { -+ pMapping->uSize /= 2; -+ } -+ -+ if(pMapping->ui32Flags & PVRSRV_MEM_DUMMY) -+ { -+ uPSize = pBMHeap->sDevArena.ui32DataPageSize; -+ } -+ else -+ { -+ uPSize = pMapping->uSize; -+ } -+ -+ if (ui32Flags & PVRSRV_MEM_XPROC) -+ { -+ XProcWorkaroundFreeShareable(pMapping->hOSMemHandle); -+ } -+ else -+ if(pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG) -+ { -+ OSFreePages(pBMHeap->ui32Attribs, -+ uPSize, -+ (IMG_VOID *)pMapping->CpuVAddr, -+ pMapping->hOSMemHandle); -+ } -+ else -+ { -+ IMG_SYS_PHYADDR sSysPAddr; -+ -+ if(pMapping->CpuVAddr) -+ { -+ OSUnReservePhys(pMapping->CpuVAddr, -+ uPSize, -+ pBMHeap->ui32Attribs, -+ pMapping->hOSMemHandle); -+ } -+ sSysPAddr = SysCpuPAddrToSysPAddr(pMapping->CpuPAddr); -+ RA_Free (pBMHeap->pLocalDevMemArena, (IMG_UINTPTR_T)sSysPAddr.uiAddr, IMG_FALSE); -+ } -+ } -+fail_mapping_alloc: -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_MAPPING), pMapping, IMG_NULL); -+ /*not nulling pointer, out of scope*/ -+fail_exit: -+ return IMG_FALSE; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function BM_FreeMemory -+ -+ @Description Free a block of pages previously allocated via -+ BM_ImportMemory. -+ -+ @Input h - buffer manager handle, not the void type as dictated by -+ the generic nature of the resource allocator interface. -+ @Input _base - base address of blocks to free. -+ @Input psMapping - arbitrary user reference associated with the -+ underlying storage provided by BM_ImportMemory -+ @Return None -+ -+ *****************************************************************************/ -+static IMG_VOID -+BM_FreeMemory (IMG_VOID *h, IMG_UINTPTR_T _base, BM_MAPPING *psMapping) -+{ -+ BM_HEAP *pBMHeap = h; -+ IMG_SIZE_T uPSize; -+ -+ PVR_UNREFERENCED_PARAMETER (_base); -+ -+ PVR_DPF ((PVR_DBG_MESSAGE, -+ "BM_FreeMemory (h=0x%p, base=0x" UINTPTR_FMT ", psMapping=0x%p)", -+ h, _base, psMapping)); -+ -+ PVR_ASSERT (psMapping != IMG_NULL); -+ -+ if (psMapping == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "BM_FreeMemory: invalid parameter")); -+ return; -+ } -+ -+ /* -+ Only free the virtual memory if we got as far a allocating it. -+ This NULL check should be safe as we always have a guard page -+ at virtual address 0x00000000 -+ */ -+ if (psMapping->DevVAddr.uiAddr) -+ { -+ DevMemoryFree (psMapping); -+ } -+ -+ /* the size is double the actual for interleaved */ -+ if((psMapping->ui32Flags & PVRSRV_MEM_INTERLEAVED) != 0) -+ { -+ psMapping->uSize /= 2; -+ } -+ -+ if(psMapping->ui32Flags & PVRSRV_MEM_DUMMY) -+ { -+ uPSize = psMapping->pBMHeap->sDevArena.ui32DataPageSize; -+ } -+ else -+ { -+ uPSize = psMapping->uSize; -+ } -+ -+ if (psMapping->ui32Flags & PVRSRV_MEM_XPROC) -+ { -+ XProcWorkaroundFreeShareable(psMapping->hOSMemHandle); -+ } -+ else -+ if(pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG) -+ { -+ OSFreePages(pBMHeap->ui32Attribs, -+ uPSize, -+ (IMG_VOID *) psMapping->CpuVAddr, -+ psMapping->hOSMemHandle); -+ } -+ else if(pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG) -+ { -+ IMG_SYS_PHYADDR sSysPAddr; -+ -+ OSUnReservePhys(psMapping->CpuVAddr, uPSize, pBMHeap->ui32Attribs, psMapping->hOSMemHandle); -+ -+ sSysPAddr = SysCpuPAddrToSysPAddr(psMapping->CpuPAddr); -+ -+ RA_Free (pBMHeap->pLocalDevMemArena, (IMG_UINTPTR_T)sSysPAddr.uiAddr, IMG_FALSE); -+ } -+ else -+ { -+ PVR_DPF((PVR_DBG_ERROR, "BM_FreeMemory: Invalid backing store type")); -+ } -+ -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_MAPPING), psMapping, IMG_NULL); -+ /*not nulling pointer, copy on stack*/ -+ -+ PVR_DPF((PVR_DBG_MESSAGE, -+ "..BM_FreeMemory (h=0x%p, base=0x" UINTPTR_FMT ")", -+ h, _base)); -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function BM_GetPhysPageAddr -+ -+ @Description -+ -+ @Input psMemInfo -+ -+ @Input sDevVPageAddr -+ -+ @Output psDevPAddr -+ -+ @Return IMG_VOID -+ -+******************************************************************************/ -+ -+IMG_VOID BM_GetPhysPageAddr(PVRSRV_KERNEL_MEM_INFO *psMemInfo, -+ IMG_DEV_VIRTADDR sDevVPageAddr, -+ IMG_DEV_PHYADDR *psDevPAddr) -+{ -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+ -+ PVR_DPF((PVR_DBG_MESSAGE, "BM_GetPhysPageAddr")); -+ -+ PVR_ASSERT(psMemInfo && psDevPAddr); -+ -+ /* check it's a page address */ -+ PVR_ASSERT((sDevVPageAddr.uiAddr & 0xFFF) == 0); -+ -+ /* PRQA S 0505 4 */ /* PVR_ASSERT should catch NULL ptrs */ -+ psDeviceNode = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->pBMContext->psDeviceNode; -+ -+ *psDevPAddr = psDeviceNode->pfnMMUGetPhysPageAddr(((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->pMMUHeap, -+ sDevVPageAddr); -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function BM_GetMMUContext -+ -+ @Description utility function to return the MMU context -+ -+ @Input hDevMemHeap - the Dev mem heap handle -+ -+ @Return MMU context, else NULL -+**************************************************************************/ -+MMU_CONTEXT* BM_GetMMUContext(IMG_HANDLE hDevMemHeap) -+{ -+ BM_HEAP *pBMHeap = (BM_HEAP*)hDevMemHeap; -+ -+ PVR_DPF((PVR_DBG_VERBOSE, "BM_GetMMUContext")); -+ -+ return pBMHeap->pBMContext->psMMUContext; -+} -+ -+/*! -+****************************************************************************** -+ @Function BM_GetMMUContextFromMemContext -+ -+ @Description utility function to return the MMU context -+ -+ @Input hDevMemContext - the Dev mem context handle -+ -+ @Return MMU context, else NULL -+**************************************************************************/ -+MMU_CONTEXT* BM_GetMMUContextFromMemContext(IMG_HANDLE hDevMemContext) -+{ -+ BM_CONTEXT *pBMContext = (BM_CONTEXT*)hDevMemContext; -+ -+ PVR_DPF ((PVR_DBG_VERBOSE, "BM_GetMMUContextFromMemContext")); -+ -+ return pBMContext->psMMUContext; -+} -+ -+/*! -+****************************************************************************** -+ @Function BM_GetMMUHeap -+ -+ @Description utility function to return the MMU heap handle -+ -+ @Input hDevMemHeap - the Dev mem heap handle -+ -+ @Return MMU heap handle, else NULL -+**************************************************************************/ -+IMG_HANDLE BM_GetMMUHeap(IMG_HANDLE hDevMemHeap) -+{ -+ PVR_DPF((PVR_DBG_VERBOSE, "BM_GetMMUHeap")); -+ -+ return (IMG_HANDLE)((BM_HEAP*)hDevMemHeap)->pMMUHeap; -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function BM_GetDeviceNode -+ -+ @Description utility function to return the devicenode from the BM Context -+ -+ @Input hDevMemContext - the Dev Mem Context -+ -+ @Return MMU heap handle, else NULL -+**************************************************************************/ -+PVRSRV_DEVICE_NODE* BM_GetDeviceNode(IMG_HANDLE hDevMemContext) -+{ -+ PVR_DPF((PVR_DBG_VERBOSE, "BM_GetDeviceNode")); -+ -+ return ((BM_CONTEXT*)hDevMemContext)->psDeviceNode; -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function BM_GetMappingHandle -+ -+ @Description utility function to return the mapping handle from a meminfo -+ -+ @Input psMemInfo - kernel meminfo -+ -+ @Return mapping handle, else NULL -+**************************************************************************/ -+IMG_HANDLE BM_GetMappingHandle(PVRSRV_KERNEL_MEM_INFO *psMemInfo) -+{ -+ PVR_DPF((PVR_DBG_VERBOSE, "BM_GetMappingHandle")); -+ -+ return ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->hOSMemHandle; -+} -+ -+/*! -+****************************************************************************** -+ @Function BM_MappingHandleFromBuffer -+ -+ @Description utility function to get the BM mapping handle from a BM buffer -+ -+ @Input hBuffer - Handle to BM buffer -+ -+ @Return BM mapping handle -+**************************************************************************/ -+IMG_HANDLE BM_MappingHandleFromBuffer(IMG_HANDLE hBuffer) -+{ -+ BM_BUF *psBuffer; -+ -+ PVR_ASSERT(hBuffer != IMG_NULL); -+ psBuffer = hBuffer; -+ return psBuffer->pMapping; -+} -+ -+/*! -+****************************************************************************** -+ @Function BM_GetVirtualSize -+ -+ @Description utility function to get the VM size of a BM mapping -+ -+ @Input hBMHandle - Handle to BM mapping -+ -+ @Return VM size of mapping -+**************************************************************************/ -+IMG_UINT32 BM_GetVirtualSize(IMG_HANDLE hBMHandle) -+{ -+ BM_MAPPING *psMapping; -+ -+ PVR_ASSERT(hBMHandle != IMG_NULL); -+ psMapping = hBMHandle; -+ return psMapping->ui32ChunkSize * psMapping->ui32NumVirtChunks; -+} -+ -+/*! -+****************************************************************************** -+ @Function BM_MapPageAtOffset -+ -+ @Description utility function check if the specificed offset in a BM mapping -+ is a page that needs tp be mapped -+ -+ @Input hBMHandle - Handle to BM mapping -+ -+ @Input ui32Offset - Offset into allocation -+ -+ @Return IMG_TRUE if the page should be mapped -+**************************************************************************/ -+IMG_BOOL BM_MapPageAtOffset(IMG_HANDLE hBMHandle, IMG_UINT32 ui32Offset) -+{ -+ BM_MAPPING *psMapping; -+ IMG_UINT32 ui32ChunkIndex; -+ -+ PVR_ASSERT(hBMHandle != IMG_NULL); -+ psMapping = hBMHandle; -+ -+ ui32ChunkIndex = ui32Offset / psMapping->ui32ChunkSize; -+ /* Check for overrun */ -+ PVR_ASSERT(ui32ChunkIndex <= psMapping->ui32NumVirtChunks); -+ return psMapping->pabMapChunk[ui32ChunkIndex]; -+} -+ -+/*! -+****************************************************************************** -+ @Function BM_VirtOffsetToPhyscial -+ -+ @Description utility function find of physical offset of a sparse allocation -+ from it's virtual offset. -+ -+ @Input hBMHandle - Handle to BM mapping -+ -+ @Input ui32VirtOffset - Virtual offset into allocation -+ -+ @Output pui32PhysOffset - Physical offset -+ -+ @Return IMG_TRUE if the virtual offset is physically backed -+**************************************************************************/ -+IMG_BOOL BM_VirtOffsetToPhysical(IMG_HANDLE hBMHandle, -+ IMG_UINT32 ui32VirtOffset, -+ IMG_UINT32 *pui32PhysOffset) -+{ -+ BM_MAPPING *psMapping; -+ IMG_UINT32 ui32ChunkOffset; -+ IMG_UINT32 ui32PhysOffset = 0; -+ IMG_UINT32 i; -+ -+ PVR_ASSERT(hBMHandle != IMG_NULL); -+ psMapping = hBMHandle; -+ -+ ui32ChunkOffset = ui32VirtOffset / psMapping->ui32ChunkSize; -+ if (!psMapping->pabMapChunk[ui32ChunkOffset]) -+ { -+ return IMG_FALSE; -+ } -+ -+ for (i=0;i<ui32ChunkOffset;i++) -+ { -+ if (psMapping->pabMapChunk[i]) -+ { -+ ui32PhysOffset += psMapping->ui32ChunkSize; -+ } -+ } -+ *pui32PhysOffset = ui32PhysOffset; -+ -+ return IMG_TRUE; -+} -+/****************************************************************************** -+ End of file (buffer_manager.c) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/common/deviceclass.c b/drivers/staging/ti-es8-sgx/services4/srvkm/common/deviceclass.c -new file mode 100644 -index 0000000..9bf18ab ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/common/deviceclass.c -@@ -0,0 +1,2926 @@ -+/*************************************************************************/ /*! -+@File -+@Title Device class services functions -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Kernel services functions for device class devices -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#include "services_headers.h" -+#include "buffer_manager.h" -+#include "kernelbuffer.h" -+#include "kerneldisplay.h" -+#include "pvr_bridge_km.h" -+#include "pdump_km.h" -+#include "deviceid.h" -+ -+#include "lists.h" -+ -+#if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) -+#include "pvr_sync.h" -+#endif -+ -+PVRSRV_ERROR AllocateDeviceID(SYS_DATA *psSysData, IMG_UINT32 *pui32DevID); -+PVRSRV_ERROR FreeDeviceID(SYS_DATA *psSysData, IMG_UINT32 ui32DevID); -+ -+#if defined(SUPPORT_CUSTOM_SWAP_OPERATIONS) -+IMG_VOID PVRSRVFreeCommandCompletePacketKM(IMG_HANDLE hCmdCookie, -+ IMG_BOOL bScheduleMISR); -+#endif -+/*********************************************************************** -+ Local Display Class Structures -+************************************************************************/ -+typedef struct PVRSRV_DC_SRV2DISP_KMJTABLE_TAG *PPVRSRV_DC_SRV2DISP_KMJTABLE; -+ -+/* -+ Display Class Buffer Info -+*/ -+typedef struct PVRSRV_DC_BUFFER_TAG -+{ -+ /* BC/DC common details - THIS MUST BE THE FIRST MEMBER */ -+ PVRSRV_DEVICECLASS_BUFFER sDeviceClassBuffer; -+ -+ struct PVRSRV_DISPLAYCLASS_INFO_TAG *psDCInfo; -+ struct PVRSRV_DC_SWAPCHAIN_TAG *psSwapChain; -+} PVRSRV_DC_BUFFER; -+ -+/* -+ Display Device Class kernel swapchain information structure -+*/ -+typedef struct PVRSRV_DC_SWAPCHAIN_TAG -+{ -+ IMG_HANDLE hExtSwapChain; -+ IMG_UINT32 ui32SwapChainID; -+ IMG_UINT32 ui32RefCount; -+ IMG_UINT32 ui32Flags; -+ PVRSRV_QUEUE_INFO *psQueue; -+ PVRSRV_DC_BUFFER asBuffer[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS]; -+ IMG_UINT32 ui32BufferCount; -+ PVRSRV_DC_BUFFER *psLastFlipBuffer; -+ IMG_UINT32 ui32MinSwapInterval; -+ IMG_UINT32 ui32MaxSwapInterval; -+#if !defined(SUPPORT_DC_CMDCOMPLETE_WHEN_NO_LONGER_DISPLAYED) -+ PVRSRV_KERNEL_SYNC_INFO **ppsLastSyncInfos; -+ IMG_UINT32 ui32LastNumSyncInfos; -+#endif /* !defined(SUPPORT_DC_CMDCOMPLETE_WHEN_NO_LONGER_DISPLAYED) */ -+ struct PVRSRV_DISPLAYCLASS_INFO_TAG *psDCInfo; -+ struct PVRSRV_DC_SWAPCHAIN_TAG *psNext; -+} PVRSRV_DC_SWAPCHAIN; -+ -+ -+/* -+ Display Device Class kernel swapchain referecne structure -+*/ -+typedef struct PVRSRV_DC_SWAPCHAIN_REF_TAG -+{ -+ struct PVRSRV_DC_SWAPCHAIN_TAG *psSwapChain; -+ IMG_HANDLE hResItem; -+} PVRSRV_DC_SWAPCHAIN_REF; -+ -+ -+/* -+ Display Device Class kernel services information structure -+*/ -+typedef struct PVRSRV_DISPLAYCLASS_INFO_TAG -+{ -+ IMG_UINT32 ui32RefCount; -+ IMG_UINT32 ui32DeviceID; -+ IMG_HANDLE hExtDevice; -+ PPVRSRV_DC_SRV2DISP_KMJTABLE psFuncTable; -+ IMG_HANDLE hDevMemContext; -+ PVRSRV_DC_BUFFER sSystemBuffer; -+ struct PVRSRV_DC_SWAPCHAIN_TAG *psDCSwapChainShared; -+} PVRSRV_DISPLAYCLASS_INFO; -+ -+ -+/* -+ Per-context Display Device Class kernel services information structure -+*/ -+typedef struct PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO_TAG -+{ -+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo; -+ PRESMAN_ITEM hResItem; -+} PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO; -+ -+ -+/*********************************************************************** -+ Local Buffer Class Structures -+************************************************************************/ -+typedef struct PVRSRV_BC_SRV2BUFFER_KMJTABLE_TAG *PPVRSRV_BC_SRV2BUFFER_KMJTABLE; -+ -+/* -+ Buffer Class Buffer Info -+*/ -+typedef struct PVRSRV_BC_BUFFER_TAG -+{ -+ /* BC/DC common details - THIS MUST BE THE FIRST MEMBER */ -+ PVRSRV_DEVICECLASS_BUFFER sDeviceClassBuffer; -+ -+ struct PVRSRV_BUFFERCLASS_INFO_TAG *psBCInfo; -+} PVRSRV_BC_BUFFER; -+ -+ -+/* -+ Buffer Device Class kernel services information structure -+*/ -+typedef struct PVRSRV_BUFFERCLASS_INFO_TAG -+{ -+ IMG_UINT32 ui32RefCount; -+ IMG_UINT32 ui32DeviceID; -+ IMG_HANDLE hExtDevice; -+ PPVRSRV_BC_SRV2BUFFER_KMJTABLE psFuncTable; -+ IMG_HANDLE hDevMemContext; -+ /* buffer info returned from 3rd party driver */ -+ IMG_UINT32 ui32BufferCount; -+ PVRSRV_BC_BUFFER *psBuffer; -+ -+} PVRSRV_BUFFERCLASS_INFO; -+ -+ -+/* -+ Per-context Buffer Device Class kernel services information structure -+*/ -+typedef struct PVRSRV_BUFFERCLASS_PERCONTEXT_INFO_TAG -+{ -+ PVRSRV_BUFFERCLASS_INFO *psBCInfo; -+ IMG_HANDLE hResItem; -+} PVRSRV_BUFFERCLASS_PERCONTEXT_INFO; -+ -+ -+/*! -+****************************************************************************** -+ @Function DCDeviceHandleToDCInfo -+ -+ @Description -+ -+ Convert a client-visible 3rd party device class handle to an internal -+ PVRSRV_DISPLAYCLASS_INFO pointer. -+ -+ @Input hDeviceKM - handle to display class device, returned from OpenDCDevice -+ -+ @Return -+ success: pointer to PVRSRV_DISPLAYCLASS_INFO -+ failure: IMG_NULL -+******************************************************************************/ -+static PVRSRV_DISPLAYCLASS_INFO* DCDeviceHandleToDCInfo (IMG_HANDLE hDeviceKM) -+{ -+ PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo; -+ -+ psDCPerContextInfo = (PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *)hDeviceKM; -+ -+ return psDCPerContextInfo->psDCInfo; -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function BCDeviceHandleToBCInfo -+ -+ @Description -+ -+ Convert a client-visible 3rd party buffer class handle to an internal -+ PVRSRV_BUFFERCLASS_INFO pointer. -+ -+ @Input hDeviceKM - handle to buffer class device, returned from OpenBCDevice -+ -+ @Return -+ success: pointer to PVRSRV_BUFFERCLASS_INFO -+ failure: IMG_NULL -+******************************************************************************/ -+static PVRSRV_BUFFERCLASS_INFO* BCDeviceHandleToBCInfo (IMG_HANDLE hDeviceKM) -+{ -+ PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo; -+ -+ psBCPerContextInfo = (PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *)hDeviceKM; -+ -+ return psBCPerContextInfo->psBCInfo; -+} -+ -+/*! -+****************************************************************************** -+ @Function PVRSRVEnumerateDCKM_ForEachVaCb -+ -+ @Description -+ -+ Enumerates the device node (if is of the same class as given). -+ -+ @Input psDeviceNode - The device node to be enumerated -+ va - variable arguments list, with: -+ pui32DevCount - The device count pointer (to be increased) -+ ppui32DevID - The pointer to the device IDs pointer (to be updated and increased) -+ peDeviceClass - The pointer to the device class of the psDeviceNode's to be enumerated. -+******************************************************************************/ -+static IMG_VOID PVRSRVEnumerateDCKM_ForEachVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va) -+{ -+ IMG_UINT *pui32DevCount; -+ IMG_UINT32 **ppui32DevID; -+ PVRSRV_DEVICE_CLASS peDeviceClass; -+ -+ pui32DevCount = va_arg(va, IMG_UINT*); -+ ppui32DevID = va_arg(va, IMG_UINT32**); -+ peDeviceClass = va_arg(va, PVRSRV_DEVICE_CLASS); -+ -+ if ((psDeviceNode->sDevId.eDeviceClass == peDeviceClass) -+ && (psDeviceNode->sDevId.eDeviceType == PVRSRV_DEVICE_TYPE_EXT)) -+ { -+ (*pui32DevCount)++; -+ if(*ppui32DevID) -+ { -+ *(*ppui32DevID)++ = psDeviceNode->sDevId.ui32DeviceIndex; -+ } -+ } -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVEnumerateDCKM -+ -+ @Description -+ -+ Enumerates devices available in a given class. -+ On first call, pass valid ptr for pui32DevCount and IMG_NULL for pui32DevID, -+ On second call, pass same ptr for pui32DevCount and client allocated ptr -+ for pui32DevID device id list -+ -+ @Input hServices - handle for services connection -+ @Input ui32DevClass - device class identifier -+ @Output pui32DevCount - number of devices available in class -+ @Output pui32DevID - list of device ids in the device class -+ -+ @Return -+ success: handle to matching display class device -+ failure: IMG_NULL -+ -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR PVRSRVEnumerateDCKM (PVRSRV_DEVICE_CLASS DeviceClass, -+ IMG_UINT32 *pui32DevCount, -+ IMG_UINT32 *pui32DevID ) -+{ -+ /*PVRSRV_DEVICE_NODE *psDeviceNode;*/ -+ IMG_UINT ui32DevCount = 0; -+ SYS_DATA *psSysData; -+ -+ SysAcquireData(&psSysData); -+ -+ /* search devonode list for devices in specified class and return the device ids */ -+ List_PVRSRV_DEVICE_NODE_ForEach_va(psSysData->psDeviceNodeList, -+ &PVRSRVEnumerateDCKM_ForEachVaCb, -+ &ui32DevCount, -+ &pui32DevID, -+ DeviceClass); -+ -+ if(pui32DevCount) -+ { -+ *pui32DevCount = ui32DevCount; -+ } -+ else if(pui32DevID == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVEnumerateDCKM: Invalid parameters")); -+ return (PVRSRV_ERROR_INVALID_PARAMS); -+ } -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVRegisterDCDeviceKM -+ -+ @Description -+ -+ registers an external device with the system -+ -+ @Input psFuncTable : device function table -+ -+ @Output pui32DeviceID : unique device key (for case of multiple identical devices) -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+static -+PVRSRV_ERROR PVRSRVRegisterDCDeviceKM (PVRSRV_DC_SRV2DISP_KMJTABLE *psFuncTable, -+ IMG_UINT32 *pui32DeviceID) -+{ -+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo = IMG_NULL; -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+ SYS_DATA *psSysData; -+ -+ /* -+ IN: -+ - name of client side ext. device driver library for subsequent loading -+ - predefined list of callbacks into kernel ext. device driver (based on class type) -+ -+ FUNCTION TASKS: -+ - allocate display device class info structure -+ - hang ext.device kernel callbacks on this structure (pfnKSwapToSystem) -+ -+ OUT: -+ - DEVICE_ID -+ - pass back devinfo? no -+ -+ Q&A: -+ - DEVICE_ID passed in or allocated - assume allocate -+ */ -+ -+ SysAcquireData(&psSysData); -+ -+ /* -+ If we got this far we're doing dynamic enumeration -+ or first time static registration -+ */ -+ -+ /* Allocate device control block */ -+ if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(*psDCInfo), -+ (IMG_VOID **)&psDCInfo, IMG_NULL, -+ "Display Class Info") != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDCDeviceKM: Failed psDCInfo alloc")); -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ OSMemSet (psDCInfo, 0, sizeof(*psDCInfo)); -+ -+ /* setup the display device information structure */ -+ if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE), -+ (IMG_VOID **)&psDCInfo->psFuncTable, IMG_NULL, -+ "Function table for SRVKM->DISPLAY") != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDCDeviceKM: Failed psFuncTable alloc")); -+ goto ErrorExit; -+ } -+ OSMemSet (psDCInfo->psFuncTable, 0, sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE)); -+ -+ /* copy the jump table */ -+ *psDCInfo->psFuncTable = *psFuncTable; -+ -+ /* Allocate device node */ -+ if(OSAllocMem( PVRSRV_OS_NON_PAGEABLE_HEAP, -+ sizeof(PVRSRV_DEVICE_NODE), -+ (IMG_VOID **)&psDeviceNode, IMG_NULL, -+ "Device Node") != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDCDeviceKM: Failed psDeviceNode alloc")); -+ goto ErrorExit; -+ } -+ OSMemSet (psDeviceNode, 0, sizeof(PVRSRV_DEVICE_NODE)); -+ -+ psDeviceNode->pvDevice = (IMG_VOID*)psDCInfo; -+ psDeviceNode->ui32pvDeviceSize = sizeof(*psDCInfo); -+ psDeviceNode->ui32RefCount = 1; -+ psDeviceNode->sDevId.eDeviceType = PVRSRV_DEVICE_TYPE_EXT; -+ psDeviceNode->sDevId.eDeviceClass = PVRSRV_DEVICE_CLASS_DISPLAY; -+ psDeviceNode->psSysData = psSysData; -+ -+ /* allocate a unique device id */ -+ if (AllocateDeviceID(psSysData, &psDeviceNode->sDevId.ui32DeviceIndex) != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed to allocate Device ID")); -+ goto ErrorExit; -+ } -+ psDCInfo->ui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex; -+ if (pui32DeviceID) -+ { -+ *pui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex; -+ } -+ -+ /* Register the device with the system */ -+ SysRegisterExternalDevice(psDeviceNode); -+ -+ /* and finally insert the device into the dev-list */ -+ List_PVRSRV_DEVICE_NODE_Insert(&psSysData->psDeviceNodeList, psDeviceNode); -+ -+ return PVRSRV_OK; -+ -+ErrorExit: -+ -+ if(psDCInfo->psFuncTable) -+ { -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE), psDCInfo->psFuncTable, IMG_NULL); -+ psDCInfo->psFuncTable = IMG_NULL; -+ } -+ -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DISPLAYCLASS_INFO), psDCInfo, IMG_NULL); -+ /*not nulling pointer, out of scope*/ -+ -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVRemoveDCDeviceKM -+ -+ @Description -+ -+ Removes external device from services system record -+ -+ @Input ui32DeviceIndex : unique device key (for case of multiple identical devices) -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+static PVRSRV_ERROR PVRSRVRemoveDCDeviceKM(IMG_UINT32 ui32DevIndex) -+{ -+ SYS_DATA *psSysData; -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo; -+ -+ SysAcquireData(&psSysData); -+ -+ /*search the node matching the devindex and display class*/ -+ psDeviceNode = (PVRSRV_DEVICE_NODE*) -+ List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList, -+ &MatchDeviceKM_AnyVaCb, -+ ui32DevIndex, -+ IMG_FALSE, -+ PVRSRV_DEVICE_CLASS_DISPLAY); -+ if (!psDeviceNode) -+ { -+ /*device not found*/ -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveDCDeviceKM: requested device %d not present", ui32DevIndex)); -+ return PVRSRV_ERROR_NO_DEVICENODE_FOUND; -+ } -+ -+ /* setup DCInfo ptr */ -+ psDCInfo = (PVRSRV_DISPLAYCLASS_INFO*)psDeviceNode->pvDevice; -+ -+ /* -+ The device can only be removed if there are -+ no open connections in the Services interface -+ */ -+ if(psDCInfo->ui32RefCount == 0) -+ { -+ /* -+ Remove from the device list. -+ */ -+ List_PVRSRV_DEVICE_NODE_Remove(psDeviceNode); -+ -+ /* Unregister the device with the system */ -+ SysRemoveExternalDevice(psDeviceNode); -+ -+ /* -+ OK found a device with a matching devindex -+ remove registration information -+ */ -+ PVR_ASSERT(psDCInfo->ui32RefCount == 0); -+ (IMG_VOID)FreeDeviceID(psSysData, ui32DevIndex); -+ (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE), psDCInfo->psFuncTable, IMG_NULL); -+ psDCInfo->psFuncTable = IMG_NULL; -+ (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DISPLAYCLASS_INFO), psDCInfo, IMG_NULL); -+ /*not nulling original pointer, overwritten*/ -+ (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DEVICE_NODE), psDeviceNode, IMG_NULL); -+ /*not nulling pointer, out of scope*/ -+ } -+ else -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveDCDeviceKM: failed as %d Services DC API connections are still open", psDCInfo->ui32RefCount)); -+ return PVRSRV_ERROR_UNABLE_TO_REMOVE_DEVICE; -+ } -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVRegisterBCDeviceKM -+ -+ @Description -+ -+ registers an external device with the system -+ -+ @Input psFuncTable : device function table -+ @Input ui32DeviceIndex : unique device key (for case of multiple identical devices) -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+static -+PVRSRV_ERROR PVRSRVRegisterBCDeviceKM (PVRSRV_BC_SRV2BUFFER_KMJTABLE *psFuncTable, -+ IMG_UINT32 *pui32DeviceID) -+{ -+ PVRSRV_BUFFERCLASS_INFO *psBCInfo = IMG_NULL; -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+ SYS_DATA *psSysData; -+ /* -+ IN: -+ - name of client side ext. device driver library for subsequent loading -+ - predefined list of callbacks into kernel ext. device driver (based on class type) -+ -+ FUNCTION TASKS: -+ - allocate buffer device class info structure -+ -+ OUT: -+ - DEVICE_ID -+ - pass back devinfo? no -+ -+ Q&A: -+ - DEVICE_ID passed in or allocated - assume allcoate -+ */ -+ -+ SysAcquireData(&psSysData); -+ -+ /* -+ If we got this far we're doing dynamic enumeration -+ or first time static registration -+ */ -+ -+ /* Allocate device control block */ -+ if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(*psBCInfo), -+ (IMG_VOID **)&psBCInfo, IMG_NULL, -+ "Buffer Class Info") != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed psBCInfo alloc")); -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ OSMemSet (psBCInfo, 0, sizeof(*psBCInfo)); -+ -+ /* setup the buffer device information structure */ -+ if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(PVRSRV_BC_SRV2BUFFER_KMJTABLE), -+ (IMG_VOID **)&psBCInfo->psFuncTable, IMG_NULL, -+ "Function table for SRVKM->BUFFER") != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed psFuncTable alloc")); -+ goto ErrorExit; -+ } -+ OSMemSet (psBCInfo->psFuncTable, 0, sizeof(PVRSRV_BC_SRV2BUFFER_KMJTABLE)); -+ -+ /* copy the jump table */ -+ *psBCInfo->psFuncTable = *psFuncTable; -+ -+ /* Allocate device node */ -+ if(OSAllocMem( PVRSRV_OS_NON_PAGEABLE_HEAP, -+ sizeof(PVRSRV_DEVICE_NODE), -+ (IMG_VOID **)&psDeviceNode, IMG_NULL, -+ "Device Node") != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed psDeviceNode alloc")); -+ goto ErrorExit; -+ } -+ OSMemSet (psDeviceNode, 0, sizeof(PVRSRV_DEVICE_NODE)); -+ -+ psDeviceNode->pvDevice = (IMG_VOID*)psBCInfo; -+ psDeviceNode->ui32pvDeviceSize = sizeof(*psBCInfo); -+ psDeviceNode->ui32RefCount = 1; -+ psDeviceNode->sDevId.eDeviceType = PVRSRV_DEVICE_TYPE_EXT; -+ psDeviceNode->sDevId.eDeviceClass = PVRSRV_DEVICE_CLASS_BUFFER; -+ psDeviceNode->psSysData = psSysData; -+ -+ /* allocate a unique device id */ -+ if (AllocateDeviceID(psSysData, &psDeviceNode->sDevId.ui32DeviceIndex) != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterBCDeviceKM: Failed to allocate Device ID")); -+ goto ErrorExit; -+ } -+ psBCInfo->ui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex; -+ if (pui32DeviceID) -+ { -+ *pui32DeviceID = psDeviceNode->sDevId.ui32DeviceIndex; -+ } -+ -+ /* and finally insert the device into the dev-list */ -+ List_PVRSRV_DEVICE_NODE_Insert(&psSysData->psDeviceNodeList, psDeviceNode); -+ -+ return PVRSRV_OK; -+ -+ErrorExit: -+ -+ if(psBCInfo->psFuncTable) -+ { -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PPVRSRV_BC_SRV2BUFFER_KMJTABLE), psBCInfo->psFuncTable, IMG_NULL); -+ psBCInfo->psFuncTable = IMG_NULL; -+ } -+ -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BUFFERCLASS_INFO), psBCInfo, IMG_NULL); -+ /*not nulling shared pointer, wasn't allocated to this point*/ -+ -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVRemoveBCDeviceKM -+ -+ @Description -+ -+ Removes external device from services system record -+ -+ @Input ui32DeviceIndex : unique device key (for case of multiple identical devices) -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+static PVRSRV_ERROR PVRSRVRemoveBCDeviceKM(IMG_UINT32 ui32DevIndex) -+{ -+ SYS_DATA *psSysData; -+ PVRSRV_DEVICE_NODE *psDevNode; -+ PVRSRV_BUFFERCLASS_INFO *psBCInfo; -+ -+ SysAcquireData(&psSysData); -+ -+ /*search the device node with the devindex and buffer class*/ -+ psDevNode = (PVRSRV_DEVICE_NODE*) -+ List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList, -+ &MatchDeviceKM_AnyVaCb, -+ ui32DevIndex, -+ IMG_FALSE, -+ PVRSRV_DEVICE_CLASS_BUFFER); -+ -+ if (!psDevNode) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveBCDeviceKM: requested device %d not present", ui32DevIndex)); -+ return PVRSRV_ERROR_NO_DEVICENODE_FOUND; -+ } -+ -+ /* set-up devnode ptr */ -+/* psDevNode = *(ppsDevNode); */ -+ /* setup BCInfo ptr */ -+ psBCInfo = (PVRSRV_BUFFERCLASS_INFO*)psDevNode->pvDevice; -+ -+ /* -+ The device can only be removed if there are -+ no open connections in the Services interface -+ */ -+ if(psBCInfo->ui32RefCount == 0) -+ { -+ /* -+ Remove from the device list. -+ */ -+ List_PVRSRV_DEVICE_NODE_Remove(psDevNode); -+ -+ /* -+ OK found a device with a matching devindex -+ remove registration information -+ */ -+ (IMG_VOID)FreeDeviceID(psSysData, ui32DevIndex); -+ (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BC_SRV2BUFFER_KMJTABLE), psBCInfo->psFuncTable, IMG_NULL); -+ psBCInfo->psFuncTable = IMG_NULL; -+ (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BUFFERCLASS_INFO), psBCInfo, IMG_NULL); -+ /*not nulling pointer, copy on stack*/ -+ (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DEVICE_NODE), psDevNode, IMG_NULL); -+ /*not nulling pointer, out of scope*/ -+ } -+ else -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveBCDeviceKM: failed as %d Services BC API connections are still open", psBCInfo->ui32RefCount)); -+ return PVRSRV_ERROR_UNABLE_TO_REMOVE_DEVICE; -+ } -+ -+ return PVRSRV_OK; -+} -+ -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVCloseDCDeviceKM -+ -+ @Description -+ -+ Closes a connection to the Display Class device -+ -+ @Input hDeviceKM : device handle -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR PVRSRVCloseDCDeviceKM (IMG_HANDLE hDeviceKM) -+{ -+ PVRSRV_ERROR eError; -+ PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo; -+ -+ psDCPerContextInfo = (PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *)hDeviceKM; -+ -+ /* Remove the item from the resman list and trigger the callback. */ -+ eError = ResManFreeResByPtr(psDCPerContextInfo->hResItem, CLEANUP_WITH_POLL); -+ -+ return eError; -+} -+ -+ -+static PVRSRV_ERROR CloseDCDeviceCallBack(IMG_PVOID pvParam, -+ IMG_UINT32 ui32Param, -+ IMG_BOOL bDummy) -+{ -+ PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo; -+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo; -+ -+ PVR_UNREFERENCED_PARAMETER(ui32Param); -+ PVR_UNREFERENCED_PARAMETER(bDummy); -+ -+ psDCPerContextInfo = (PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *)pvParam; -+ psDCInfo = psDCPerContextInfo->psDCInfo; -+ -+ if(psDCInfo->sSystemBuffer.sDeviceClassBuffer.ui32MemMapRefCount != 0) -+ { -+ PVR_DPF((PVR_DBG_MESSAGE,"CloseDCDeviceCallBack: system buffer (0x%p) still mapped (refcount = %d)", -+ &psDCInfo->sSystemBuffer.sDeviceClassBuffer, -+ psDCInfo->sSystemBuffer.sDeviceClassBuffer.ui32MemMapRefCount)); -+ } -+ -+ psDCInfo->ui32RefCount--; -+ if(psDCInfo->ui32RefCount == 0) -+ { -+ /* close the external device */ -+ psDCInfo->psFuncTable->pfnCloseDCDevice(psDCInfo->hExtDevice); -+ -+ PVRSRVKernelSyncInfoDecRef(psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo, IMG_NULL); -+ -+ psDCInfo->hDevMemContext = IMG_NULL; -+ psDCInfo->hExtDevice = IMG_NULL; -+ } -+ -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO), psDCPerContextInfo, IMG_NULL); -+ /*not nulling pointer, copy on stack*/ -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVOpenDCDeviceKM -+ -+ @Description -+ -+ Opens a connection to the Display Class device, associating the connection -+ with a Device Memory Context for a services managed device -+ -+ @Input psPerProc : Per-process data -+ @Input ui32DeviceID : unique device index -+ @Input hDevCookie : devcookie used to derive the Device Memory -+ Context into BC surfaces will be mapped into -+ @Outut phDeviceKM : handle to the DC device -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR PVRSRVOpenDCDeviceKM (PVRSRV_PER_PROCESS_DATA *psPerProc, -+ IMG_UINT32 ui32DeviceID, -+ IMG_HANDLE hDevCookie, -+ IMG_HANDLE *phDeviceKM) -+{ -+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo; -+ PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo; -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+ SYS_DATA *psSysData; -+ PVRSRV_ERROR eError; -+ -+ if(!phDeviceKM || !hDevCookie) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Invalid params")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ SysAcquireData(&psSysData); -+ -+ /* find the matching devicenode */ -+ psDeviceNode = (PVRSRV_DEVICE_NODE*) -+ List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList, -+ &MatchDeviceKM_AnyVaCb, -+ ui32DeviceID, -+ IMG_FALSE, -+ PVRSRV_DEVICE_CLASS_DISPLAY); -+ if (!psDeviceNode) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: no devnode matching index %d", ui32DeviceID)); -+ return PVRSRV_ERROR_NO_DEVICENODE_FOUND; -+ } -+ psDCInfo = (PVRSRV_DISPLAYCLASS_INFO*)psDeviceNode->pvDevice; -+ -+ /* -+ Allocate the per-context DC Info before calling the external device, -+ to make error handling easier. -+ */ -+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(*psDCPerContextInfo), -+ (IMG_VOID **)&psDCPerContextInfo, IMG_NULL, -+ "Display Class per Context Info") != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Failed psDCPerContextInfo alloc")); -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ OSMemSet(psDCPerContextInfo, 0, sizeof(*psDCPerContextInfo)); -+ -+ if(psDCInfo->ui32RefCount++ == 0) -+ { -+ -+ psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie; -+ -+ /* store the device kernel context to map into */ -+ psDCInfo->hDevMemContext = (IMG_HANDLE)psDeviceNode->sDevMemoryInfo.pBMKernelContext; -+ -+ /* create a syncinfo for the device's system surface */ -+ eError = PVRSRVAllocSyncInfoKM(IMG_NULL, -+ (IMG_HANDLE)psDeviceNode->sDevMemoryInfo.pBMKernelContext, -+ &psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo); -+ if(eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Failed sync info alloc")); -+ psDCInfo->ui32RefCount--; -+ return eError; -+ } -+ -+ /* open the external device */ -+ eError = psDCInfo->psFuncTable->pfnOpenDCDevice(ui32DeviceID, -+ &psDCInfo->hExtDevice, -+ (PVRSRV_SYNC_DATA*)psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo->psSyncDataMemInfoKM->pvLinAddrKM); -+ if(eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Failed to open external DC device")); -+ psDCInfo->ui32RefCount--; -+ PVRSRVKernelSyncInfoDecRef(psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo, IMG_NULL); -+ return eError; -+ } -+ -+ psDCPerContextInfo->psDCInfo = psDCInfo; -+ eError = PVRSRVGetDCSystemBufferKM(psDCPerContextInfo, IMG_NULL); -+ if(eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Failed to get system buffer")); -+ psDCInfo->ui32RefCount--; -+ PVRSRVKernelSyncInfoDecRef(psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo, IMG_NULL); -+ return eError; -+ } -+ psDCInfo->sSystemBuffer.sDeviceClassBuffer.ui32MemMapRefCount = 0; -+ } -+ else -+ { -+ psDCPerContextInfo->psDCInfo = psDCInfo; -+ } -+ -+ psDCPerContextInfo->hResItem = ResManRegisterRes(psPerProc->hResManContext, -+ RESMAN_TYPE_DISPLAYCLASS_DEVICE, -+ psDCPerContextInfo, -+ 0, -+ &CloseDCDeviceCallBack); -+ -+ /* return a reference to the DCPerContextInfo */ -+ *phDeviceKM = (IMG_HANDLE)psDCPerContextInfo; -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVEnumDCFormatsKM -+ -+ @Description -+ -+ Enumerates the devices pixel formats -+ -+ @Input hDeviceKM : device handle -+ @Output pui32Count : number of pixel formats -+ @Output psFormat : format list -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR PVRSRVEnumDCFormatsKM (IMG_HANDLE hDeviceKM, -+ IMG_UINT32 *pui32Count, -+ DISPLAY_FORMAT *psFormat) -+{ -+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo; -+ -+ if(!hDeviceKM || !pui32Count || !psFormat) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVEnumDCFormatsKM: Invalid parameters")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); -+ -+ /* call into the display device driver to get info */ -+ return psDCInfo->psFuncTable->pfnEnumDCFormats(psDCInfo->hExtDevice, pui32Count, psFormat); -+} -+ -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVEnumDCDimsKM -+ -+ @Description -+ -+ Enumerates the devices mode dimensions for a given pixel format -+ -+ @Input hDeviceKM : device handle -+ @Input psFormat : pixel format -+ @Output pui32Count : number of dimensions -+ @Output psDim : dimensions list -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR PVRSRVEnumDCDimsKM (IMG_HANDLE hDeviceKM, -+ DISPLAY_FORMAT *psFormat, -+ IMG_UINT32 *pui32Count, -+ DISPLAY_DIMS *psDim) -+{ -+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo; -+ -+ if(!hDeviceKM || !pui32Count || !psFormat) // psDim==NULL to query number of dims -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVEnumDCDimsKM: Invalid parameters")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); -+ -+ /* call into the display device driver to get info */ -+ return psDCInfo->psFuncTable->pfnEnumDCDims(psDCInfo->hExtDevice, psFormat, pui32Count, psDim); -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVGetDCSystemBufferKM -+ -+ @Description -+ -+ Get the primary surface and optionally return its buffer handle -+ -+ @Input hDeviceKM : device handle -+ @Output phBuffer : Optional buffer handle -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR PVRSRVGetDCSystemBufferKM (IMG_HANDLE hDeviceKM, -+ IMG_HANDLE *phBuffer) -+{ -+ PVRSRV_ERROR eError; -+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo; -+ IMG_HANDLE hExtBuffer; -+ -+ if(!hDeviceKM) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetDCSystemBufferKM: Invalid parameters")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); -+ -+ /* call into the display device driver to get info */ -+ eError = psDCInfo->psFuncTable->pfnGetDCSystemBuffer(psDCInfo->hExtDevice, &hExtBuffer); -+ if(eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetDCSystemBufferKM: Failed to get valid buffer handle from external driver")); -+ return eError; -+ } -+ -+ /* save the new info */ -+ psDCInfo->sSystemBuffer.sDeviceClassBuffer.pfnGetBufferAddr = psDCInfo->psFuncTable->pfnGetBufferAddr; -+ psDCInfo->sSystemBuffer.sDeviceClassBuffer.hDevMemContext = psDCInfo->hDevMemContext; -+ psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtDevice = psDCInfo->hExtDevice; -+ psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtBuffer = hExtBuffer; -+ -+ psDCInfo->sSystemBuffer.psDCInfo = psDCInfo; -+ -+ /* return handle */ -+ if (phBuffer) -+ { -+ *phBuffer = (IMG_HANDLE)&(psDCInfo->sSystemBuffer); -+ } -+ -+ return PVRSRV_OK; -+} -+ -+ -+/****************************************************************************** -+ -+ @Function PVRSRVGetDCInfoKM -+ -+ @Description -+ -+ Gets Display Class device Info -+ -+ @Input hDeviceKM : device handle -+ @Output psDisplayInfo -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR PVRSRVGetDCInfoKM (IMG_HANDLE hDeviceKM, -+ DISPLAY_INFO *psDisplayInfo) -+{ -+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo; -+ PVRSRV_ERROR eError; -+ -+ if(!hDeviceKM || !psDisplayInfo) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetDCInfoKM: Invalid parameters")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); -+ -+ /* call into the display device driver to get info */ -+ eError = psDCInfo->psFuncTable->pfnGetDCInfo(psDCInfo->hExtDevice, psDisplayInfo); -+ if (eError != PVRSRV_OK) -+ { -+ return eError; -+ } -+ -+ if (psDisplayInfo->ui32MaxSwapChainBuffers > PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS) -+ { -+ psDisplayInfo->ui32MaxSwapChainBuffers = PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS; -+ } -+ -+ return PVRSRV_OK; -+} -+ -+ -+IMG_EXPORT -+PVRSRV_ERROR PVRSRVDestroyDCSwapChainKM(IMG_HANDLE hSwapChainRef) -+{ -+ PVRSRV_ERROR eError; -+ PVRSRV_DC_SWAPCHAIN_REF *psSwapChainRef; -+ -+ if(!hSwapChainRef) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVDestroyDCSwapChainKM: Invalid parameters")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psSwapChainRef = hSwapChainRef; -+ -+ eError = ResManFreeResByPtr(psSwapChainRef->hResItem, CLEANUP_WITH_POLL); -+ -+ return eError; -+} -+ -+ -+static PVRSRV_ERROR DestroyDCSwapChain(PVRSRV_DC_SWAPCHAIN *psSwapChain) -+{ -+ PVRSRV_ERROR eError; -+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo = psSwapChain->psDCInfo; -+ IMG_UINT32 i; -+ -+ /* Update shared swapchains list */ -+ if( psDCInfo->psDCSwapChainShared ) -+ { -+ if( psDCInfo->psDCSwapChainShared == psSwapChain ) -+ { -+ psDCInfo->psDCSwapChainShared = psSwapChain->psNext; -+ } -+ else -+ { -+ PVRSRV_DC_SWAPCHAIN *psCurrentSwapChain; -+ psCurrentSwapChain = psDCInfo->psDCSwapChainShared; -+ while( psCurrentSwapChain->psNext ) -+ { -+ if( psCurrentSwapChain->psNext != psSwapChain ) -+ { -+ psCurrentSwapChain = psCurrentSwapChain->psNext; -+ continue; -+ } -+ psCurrentSwapChain->psNext = psSwapChain->psNext; -+ break; -+ } -+ } -+ } -+ -+ /* Destroy command queue before swapchain - it may use the swapchain when commands are flushed. */ -+ PVRSRVDestroyCommandQueueKM(psSwapChain->psQueue); -+ -+ /* call into the display device driver to destroy a swapchain */ -+ eError = psDCInfo->psFuncTable->pfnDestroyDCSwapChain(psDCInfo->hExtDevice, -+ psSwapChain->hExtSwapChain); -+ -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"DestroyDCSwapChainCallBack: Failed to destroy DC swap chain")); -+ return eError; -+ } -+ -+ /* free the resources */ -+ for(i=0; i<psSwapChain->ui32BufferCount; i++) -+ { -+ if(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo) -+ { -+ PVRSRVKernelSyncInfoDecRef(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo, IMG_NULL); -+ } -+ } -+ -+#if !defined(SUPPORT_DC_CMDCOMPLETE_WHEN_NO_LONGER_DISPLAYED) -+ if (psSwapChain->ppsLastSyncInfos) -+ { -+ for (i = 0; i < psSwapChain->ui32LastNumSyncInfos; i++) -+ { -+ if (psSwapChain->ppsLastSyncInfos[i]) -+ { -+ PVRSRVKernelSyncInfoDecRef(psSwapChain->ppsLastSyncInfos[i], IMG_NULL); -+ psSwapChain->ppsLastSyncInfos[i] = IMG_NULL; -+ } -+ } -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_KERNEL_SYNC_INFO *) * psSwapChain->ui32LastNumSyncInfos, -+ psSwapChain->ppsLastSyncInfos, IMG_NULL); -+ } -+#endif /* !defined(SUPPORT_DC_CMDCOMPLETE_WHEN_NO_LONGER_DISPLAYED) */ -+ -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SWAPCHAIN), psSwapChain, IMG_NULL); -+ /*not nulling pointer, copy on stack*/ -+ -+ return eError; -+} -+ -+ -+static PVRSRV_ERROR DestroyDCSwapChainRefCallBack(IMG_PVOID pvParam, -+ IMG_UINT32 ui32Param, -+ IMG_BOOL bDummy) -+{ -+ PVRSRV_DC_SWAPCHAIN_REF *psSwapChainRef = (PVRSRV_DC_SWAPCHAIN_REF *) pvParam; -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ IMG_UINT32 i; -+ -+ PVR_UNREFERENCED_PARAMETER(ui32Param); -+ PVR_UNREFERENCED_PARAMETER(bDummy); -+ -+ for (i = 0; i < psSwapChainRef->psSwapChain->ui32BufferCount; i++) -+ { -+ if (psSwapChainRef->psSwapChain->asBuffer[i].sDeviceClassBuffer.ui32MemMapRefCount != 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "DestroyDCSwapChainRefCallBack: swapchain (0x%p) still mapped (ui32MemMapRefCount = %d)", -+ &psSwapChainRef->psSwapChain->asBuffer[i].sDeviceClassBuffer, -+ psSwapChainRef->psSwapChain->asBuffer[i].sDeviceClassBuffer.ui32MemMapRefCount)); -+ } -+ } -+ -+ if(--psSwapChainRef->psSwapChain->ui32RefCount == 0) -+ { -+ eError = DestroyDCSwapChain(psSwapChainRef->psSwapChain); -+ } -+ -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SWAPCHAIN_REF), psSwapChainRef, IMG_NULL); -+ return eError; -+} -+ -+static PVRSRV_DC_SWAPCHAIN* PVRSRVFindSharedDCSwapChainKM(PVRSRV_DISPLAYCLASS_INFO *psDCInfo, -+ IMG_UINT32 ui32SwapChainID) -+{ -+ PVRSRV_DC_SWAPCHAIN *psCurrentSwapChain; -+ -+ for(psCurrentSwapChain = psDCInfo->psDCSwapChainShared; -+ psCurrentSwapChain; -+ psCurrentSwapChain = psCurrentSwapChain->psNext) -+ { -+ if(psCurrentSwapChain->ui32SwapChainID == ui32SwapChainID) -+ return psCurrentSwapChain; -+ } -+ return IMG_NULL; -+} -+ -+static PVRSRV_ERROR PVRSRVCreateDCSwapChainRefKM(PVRSRV_PER_PROCESS_DATA *psPerProc, -+ PVRSRV_DC_SWAPCHAIN *psSwapChain, -+ PVRSRV_DC_SWAPCHAIN_REF **ppsSwapChainRef) -+{ -+ PVRSRV_DC_SWAPCHAIN_REF *psSwapChainRef = IMG_NULL; -+ -+ /* Allocate swapchain reference structre*/ -+ if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(PVRSRV_DC_SWAPCHAIN_REF), -+ (IMG_VOID **)&psSwapChainRef, IMG_NULL, -+ "Display Class Swapchain Reference") != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainRefKM: Failed psSwapChainRef alloc")); -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ OSMemSet (psSwapChainRef, 0, sizeof(PVRSRV_DC_SWAPCHAIN_REF)); -+ -+ /* Bump refcount */ -+ psSwapChain->ui32RefCount++; -+ -+ /* Create reference resource */ -+ psSwapChainRef->psSwapChain = psSwapChain; -+ psSwapChainRef->hResItem = ResManRegisterRes(psPerProc->hResManContext, -+ RESMAN_TYPE_DISPLAYCLASS_SWAPCHAIN_REF, -+ psSwapChainRef, -+ 0, -+ &DestroyDCSwapChainRefCallBack); -+ *ppsSwapChainRef = psSwapChainRef; -+ -+ return PVRSRV_OK; -+} -+ -+ -+IMG_EXPORT -+PVRSRV_ERROR PVRSRVCreateDCSwapChainKM (PVRSRV_PER_PROCESS_DATA *psPerProc, -+ IMG_HANDLE hDeviceKM, -+ IMG_UINT32 ui32Flags, -+ DISPLAY_SURF_ATTRIBUTES *psDstSurfAttrib, -+ DISPLAY_SURF_ATTRIBUTES *psSrcSurfAttrib, -+ IMG_UINT32 ui32BufferCount, -+ IMG_UINT32 ui32OEMFlags, -+ IMG_HANDLE *phSwapChainRef, -+ IMG_UINT32 *pui32SwapChainID) -+{ -+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo; -+ PVRSRV_DC_SWAPCHAIN *psSwapChain = IMG_NULL; -+ PVRSRV_DC_SWAPCHAIN_REF *psSwapChainRef = IMG_NULL; -+ PVRSRV_SYNC_DATA *apsSyncData[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS]; -+ PVRSRV_QUEUE_INFO *psQueue = IMG_NULL; -+ PVRSRV_ERROR eError; -+ IMG_UINT32 i; -+ DISPLAY_INFO sDisplayInfo; -+ -+ if(!hDeviceKM -+ || !psDstSurfAttrib -+ || !psSrcSurfAttrib -+ || !phSwapChainRef -+ || !pui32SwapChainID) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Invalid parameters")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ OSMemSet (apsSyncData, 0, sizeof(PVRSRV_SYNC_DATA *) * PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS); -+ -+ if (ui32BufferCount > PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Too many buffers")); -+ return PVRSRV_ERROR_TOOMANYBUFFERS; -+ } -+ -+ psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); -+ -+ if( ui32Flags & PVRSRV_CREATE_SWAPCHAIN_QUERY ) -+ { -+ /* Query - use pui32SwapChainID as input */ -+ psSwapChain = PVRSRVFindSharedDCSwapChainKM(psDCInfo, *pui32SwapChainID ); -+ if( psSwapChain ) -+ { -+ /* Create new reference */ -+ eError = PVRSRVCreateDCSwapChainRefKM(psPerProc, -+ psSwapChain, -+ &psSwapChainRef); -+ if( eError != PVRSRV_OK ) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Couldn't create swap chain reference")); -+ return eError; -+ } -+ -+ *phSwapChainRef = (IMG_HANDLE)psSwapChainRef; -+ return PVRSRV_OK; -+ } -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: No shared SwapChain found for query")); -+ return PVRSRV_ERROR_FLIP_CHAIN_EXISTS; -+ } -+ -+ /* Allocate swapchain control structure for srvkm */ -+ if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(PVRSRV_DC_SWAPCHAIN), -+ (IMG_VOID **)&psSwapChain, IMG_NULL, -+ "Display Class Swapchain") != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Failed psSwapChain alloc")); -+ eError = PVRSRV_ERROR_OUT_OF_MEMORY; -+ goto ErrorExit; -+ } -+ OSMemSet (psSwapChain, 0, sizeof(PVRSRV_DC_SWAPCHAIN)); -+ -+ /* Create a command queue for the swapchain */ -+ eError = PVRSRVCreateCommandQueueKM(1024, &psQueue); -+ if(eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Failed to create CmdQueue")); -+ goto ErrorExit; -+ } -+ -+ /* store the Queue */ -+ psSwapChain->psQueue = psQueue; -+ -+ /* Create a Sync Object for each surface in the swapchain */ -+ for(i=0; i<ui32BufferCount; i++) -+ { -+ eError = PVRSRVAllocSyncInfoKM(IMG_NULL, -+ psDCInfo->hDevMemContext, -+ &psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo); -+ if(eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Failed to alloc syninfo for psSwapChain")); -+ goto ErrorExit; -+ } -+ -+ /* setup common device class info */ -+ psSwapChain->asBuffer[i].sDeviceClassBuffer.pfnGetBufferAddr = psDCInfo->psFuncTable->pfnGetBufferAddr; -+ psSwapChain->asBuffer[i].sDeviceClassBuffer.hDevMemContext = psDCInfo->hDevMemContext; -+ psSwapChain->asBuffer[i].sDeviceClassBuffer.hExtDevice = psDCInfo->hExtDevice; -+ -+ /* save off useful ptrs */ -+ psSwapChain->asBuffer[i].psDCInfo = psDCInfo; -+ psSwapChain->asBuffer[i].psSwapChain = psSwapChain; -+ -+ /* syncinfos must be passed as array of syncdata ptrs to the 3rd party driver */ -+ apsSyncData[i] = (PVRSRV_SYNC_DATA*)psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->psSyncDataMemInfoKM->pvLinAddrKM; -+ } -+ -+ psSwapChain->ui32BufferCount = ui32BufferCount; -+ psSwapChain->psDCInfo = psDCInfo; -+ -+#if defined(PDUMP) -+ PDUMPCOMMENT("Allocate DC swap chain (SwapChainID == %u, BufferCount == %u)", -+ *pui32SwapChainID, -+ ui32BufferCount); -+ PDUMPCOMMENT(" Src surface dimensions == %u x %u", -+ psSrcSurfAttrib->sDims.ui32Width, -+ psSrcSurfAttrib->sDims.ui32Height); -+ PDUMPCOMMENT(" Dst surface dimensions == %u x %u", -+ psDstSurfAttrib->sDims.ui32Width, -+ psDstSurfAttrib->sDims.ui32Height); -+#endif -+ -+ eError = psDCInfo->psFuncTable->pfnGetDCInfo(psDCInfo->hExtDevice, &sDisplayInfo); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Failed to get DC info")); -+ return eError; -+ } -+ -+ psSwapChain->ui32MinSwapInterval = sDisplayInfo.ui32MinSwapInterval; -+ psSwapChain->ui32MaxSwapInterval = sDisplayInfo.ui32MaxSwapInterval; -+ -+ /* call into the display device driver to create a swapchain */ -+ eError = psDCInfo->psFuncTable->pfnCreateDCSwapChain(psDCInfo->hExtDevice, -+ ui32Flags, -+ psDstSurfAttrib, -+ psSrcSurfAttrib, -+ ui32BufferCount, -+ apsSyncData, -+ ui32OEMFlags, -+ &psSwapChain->hExtSwapChain, -+ &psSwapChain->ui32SwapChainID); -+ if(eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Failed to create 3rd party SwapChain")); -+ PDUMPCOMMENT("Swapchain allocation failed."); -+ goto ErrorExit; -+ } -+ -+ /* Create new reference */ -+ eError = PVRSRVCreateDCSwapChainRefKM(psPerProc, -+ psSwapChain, -+ &psSwapChainRef); -+ if( eError != PVRSRV_OK ) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDCSwapChainKM: Couldn't create swap chain reference")); -+ PDUMPCOMMENT("Swapchain allocation failed."); -+ goto ErrorExit; -+ } -+ -+ psSwapChain->ui32RefCount = 1; -+ psSwapChain->ui32Flags = ui32Flags; -+ -+ /* Save pointer in DC structure if it's shared struct */ -+ if( ui32Flags & PVRSRV_CREATE_SWAPCHAIN_SHARED ) -+ { -+ if(! psDCInfo->psDCSwapChainShared ) -+ { -+ psDCInfo->psDCSwapChainShared = psSwapChain; -+ } -+ else -+ { -+ PVRSRV_DC_SWAPCHAIN *psOldHead = psDCInfo->psDCSwapChainShared; -+ psDCInfo->psDCSwapChainShared = psSwapChain; -+ psSwapChain->psNext = psOldHead; -+ } -+ } -+ -+ /* We create swapchain - pui32SwapChainID is output */ -+ *pui32SwapChainID = psSwapChain->ui32SwapChainID; -+ -+ /* return the swapchain reference handle */ -+ *phSwapChainRef= (IMG_HANDLE)psSwapChainRef; -+ -+ return eError; -+ -+ErrorExit: -+ -+ for(i=0; i<ui32BufferCount; i++) -+ { -+ if(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo) -+ { -+ PVRSRVKernelSyncInfoDecRef(psSwapChain->asBuffer[i].sDeviceClassBuffer.psKernelSyncInfo, IMG_NULL); -+ } -+ } -+ -+ if(psQueue) -+ { -+ PVRSRVDestroyCommandQueueKM(psQueue); -+ } -+ -+ if(psSwapChain) -+ { -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SWAPCHAIN), psSwapChain, IMG_NULL); -+ /*not nulling pointer, out of scope*/ -+ } -+ -+ return eError; -+} -+ -+ -+ -+ -+IMG_EXPORT -+PVRSRV_ERROR PVRSRVSetDCDstRectKM(IMG_HANDLE hDeviceKM, -+ IMG_HANDLE hSwapChainRef, -+ IMG_RECT *psRect) -+{ -+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo; -+ PVRSRV_DC_SWAPCHAIN *psSwapChain; -+ -+ if(!hDeviceKM || !hSwapChainRef) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSetDCDstRectKM: Invalid parameters")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); -+ psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef)->psSwapChain; -+ -+ return psDCInfo->psFuncTable->pfnSetDCDstRect(psDCInfo->hExtDevice, -+ psSwapChain->hExtSwapChain, -+ psRect); -+} -+ -+ -+IMG_EXPORT -+PVRSRV_ERROR PVRSRVSetDCSrcRectKM(IMG_HANDLE hDeviceKM, -+ IMG_HANDLE hSwapChainRef, -+ IMG_RECT *psRect) -+{ -+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo; -+ PVRSRV_DC_SWAPCHAIN *psSwapChain; -+ -+ if(!hDeviceKM || !hSwapChainRef) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSetDCSrcRectKM: Invalid parameters")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); -+ psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef)->psSwapChain; -+ -+ return psDCInfo->psFuncTable->pfnSetDCSrcRect(psDCInfo->hExtDevice, -+ psSwapChain->hExtSwapChain, -+ psRect); -+} -+ -+ -+IMG_EXPORT -+PVRSRV_ERROR PVRSRVSetDCDstColourKeyKM(IMG_HANDLE hDeviceKM, -+ IMG_HANDLE hSwapChainRef, -+ IMG_UINT32 ui32CKColour) -+{ -+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo; -+ PVRSRV_DC_SWAPCHAIN *psSwapChain; -+ -+ if(!hDeviceKM || !hSwapChainRef) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSetDCDstColourKeyKM: Invalid parameters")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); -+ psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef)->psSwapChain; -+ -+ return psDCInfo->psFuncTable->pfnSetDCDstColourKey(psDCInfo->hExtDevice, -+ psSwapChain->hExtSwapChain, -+ ui32CKColour); -+} -+ -+ -+IMG_EXPORT -+PVRSRV_ERROR PVRSRVSetDCSrcColourKeyKM(IMG_HANDLE hDeviceKM, -+ IMG_HANDLE hSwapChainRef, -+ IMG_UINT32 ui32CKColour) -+{ -+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo; -+ PVRSRV_DC_SWAPCHAIN *psSwapChain; -+ -+ if(!hDeviceKM || !hSwapChainRef) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSetDCSrcColourKeyKM: Invalid parameters")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); -+ psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef)->psSwapChain; -+ -+ return psDCInfo->psFuncTable->pfnSetDCSrcColourKey(psDCInfo->hExtDevice, -+ psSwapChain->hExtSwapChain, -+ ui32CKColour); -+} -+ -+ -+IMG_EXPORT -+PVRSRV_ERROR PVRSRVGetDCBuffersKM(IMG_HANDLE hDeviceKM, -+ IMG_HANDLE hSwapChainRef, -+ IMG_UINT32 *pui32BufferCount, -+ IMG_HANDLE *phBuffer, -+ IMG_SYS_PHYADDR *psPhyAddr) -+{ -+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo; -+ PVRSRV_DC_SWAPCHAIN *psSwapChain; -+ IMG_HANDLE ahExtBuffer[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS]; -+ PVRSRV_ERROR eError; -+ IMG_UINT32 i; -+ -+ if(!hDeviceKM || !hSwapChainRef || !phBuffer || !psPhyAddr) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetDCBuffersKM: Invalid parameters")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); -+ psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef)->psSwapChain; -+ -+ /* call into the display device driver to get info */ -+ eError = psDCInfo->psFuncTable->pfnGetDCBuffers(psDCInfo->hExtDevice, -+ psSwapChain->hExtSwapChain, -+ pui32BufferCount, -+ ahExtBuffer); -+ -+ PVR_ASSERT(*pui32BufferCount <= PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS); -+ -+ /* -+ populate the srvkm's buffer structure with the 3rd party buffer handles -+ and return the services buffer handles -+ */ -+ for(i=0; i<*pui32BufferCount; i++) -+ { -+ psSwapChain->asBuffer[i].sDeviceClassBuffer.hExtBuffer = ahExtBuffer[i]; -+ phBuffer[i] = (IMG_HANDLE)&psSwapChain->asBuffer[i]; -+ } -+ -+ return eError; -+} -+ -+ -+IMG_EXPORT -+PVRSRV_ERROR PVRSRVSwapToDCBufferKM(IMG_HANDLE hDeviceKM, -+ IMG_HANDLE hBuffer, -+ IMG_UINT32 ui32SwapInterval, -+ IMG_HANDLE hPrivateTag, -+ IMG_UINT32 ui32ClipRectCount, -+ IMG_RECT *psClipRect) -+{ -+ PVRSRV_ERROR eError; -+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo; -+ PVRSRV_DC_BUFFER *psBuffer; -+ PVRSRV_QUEUE_INFO *psQueue; -+ DISPLAYCLASS_FLIP_COMMAND *psFlipCmd; -+ IMG_UINT32 i; -+ IMG_BOOL bAddReferenceToLast = IMG_TRUE; -+ IMG_UINT16 ui16SwapCommandID = DC_FLIP_COMMAND; -+ IMG_UINT32 ui32NumSrcSyncs = 1; -+ PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[2]; -+ PVRSRV_COMMAND *psCommand; -+ SYS_DATA *psSysData; -+ -+ if(!hDeviceKM || !hBuffer || !psClipRect) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Invalid parameters")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psBuffer = (PVRSRV_DC_BUFFER*)hBuffer; -+ psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); -+ -+ /* Validate swap interval against limits */ -+ if(ui32SwapInterval < psBuffer->psSwapChain->ui32MinSwapInterval || -+ ui32SwapInterval > psBuffer->psSwapChain->ui32MaxSwapInterval) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Invalid swap interval. Requested %u, Allowed range %u-%u", -+ ui32SwapInterval, psBuffer->psSwapChain->ui32MinSwapInterval, psBuffer->psSwapChain->ui32MaxSwapInterval)); -+ return PVRSRV_ERROR_INVALID_SWAPINTERVAL; -+ } -+ -+#if defined(SUPPORT_CUSTOM_SWAP_OPERATIONS) -+ -+ if(psDCInfo->psFuncTable->pfnQuerySwapCommandID != IMG_NULL) -+ { -+ psDCInfo->psFuncTable->pfnQuerySwapCommandID(psDCInfo->hExtDevice, -+ psBuffer->psSwapChain->hExtSwapChain, -+ psBuffer->sDeviceClassBuffer.hExtBuffer, -+ hPrivateTag, -+ &ui16SwapCommandID, -+ &bAddReferenceToLast); -+ -+ } -+ -+#endif -+ -+ /* get the queue from the buffer structure */ -+ psQueue = psBuffer->psSwapChain->psQueue; -+ -+ /* specify the syncs */ -+ apsSrcSync[0] = psBuffer->sDeviceClassBuffer.psKernelSyncInfo; -+ if(bAddReferenceToLast && psBuffer->psSwapChain->psLastFlipBuffer && -+ psBuffer != psBuffer->psSwapChain->psLastFlipBuffer) -+ { -+ apsSrcSync[1] = psBuffer->psSwapChain->psLastFlipBuffer->sDeviceClassBuffer.psKernelSyncInfo; -+ ui32NumSrcSyncs++; -+ } -+ -+ /* insert the command (header) */ -+ eError = PVRSRVInsertCommandKM (psQueue, -+ &psCommand, -+ psDCInfo->ui32DeviceID, -+ ui16SwapCommandID, -+ 0, -+ IMG_NULL, -+ ui32NumSrcSyncs, -+ apsSrcSync, -+ sizeof(DISPLAYCLASS_FLIP_COMMAND) + (sizeof(IMG_RECT) * ui32ClipRectCount), -+ IMG_NULL, -+ IMG_NULL, -+ IMG_NULL); -+ if(eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Failed to get space in queue")); -+ goto Exit; -+ } -+ -+ /* setup the flip command */ -+ psFlipCmd = (DISPLAYCLASS_FLIP_COMMAND*)psCommand->pvData; -+ -+ /* Ext Device Handle */ -+ psFlipCmd->hExtDevice = psDCInfo->hExtDevice; -+ -+ /* Ext SwapChain Handle */ -+ psFlipCmd->hExtSwapChain = psBuffer->psSwapChain->hExtSwapChain; -+ -+ /* Ext Buffer Handle (Buffer to Flip to) */ -+ psFlipCmd->hExtBuffer = psBuffer->sDeviceClassBuffer.hExtBuffer; -+ -+ /* private tag */ -+ psFlipCmd->hPrivateTag = hPrivateTag; -+ -+ /* setup the clip rects */ -+ psFlipCmd->ui32ClipRectCount = ui32ClipRectCount; -+ /* cliprect memory appends the command structure */ -+ psFlipCmd->psClipRect = (IMG_RECT*)((IMG_UINT8*)psFlipCmd + sizeof(DISPLAYCLASS_FLIP_COMMAND)); // PRQA S 3305 -+ /* copy the clip rects */ -+ for(i=0; i<ui32ClipRectCount; i++) -+ { -+ psFlipCmd->psClipRect[i] = psClipRect[i]; -+ } -+ -+ /* number of vsyncs between successive flips */ -+ psFlipCmd->ui32SwapInterval = ui32SwapInterval; -+ -+ SysAcquireData(&psSysData); -+ -+ /* Because we might be composing just software surfaces, without -+ * any SGX renders since the last frame, we won't necessarily -+ * have cleaned/flushed the CPU caches before the buffers need -+ * to be displayed. -+ * -+ * Doing so now is safe because InsertCommand bumped ROP2 on the -+ * affected buffers (preventing more SW renders starting) but the -+ * display won't start to process the buffers until SubmitCommand. -+ */ -+ { -+ if(psSysData->ePendingCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_FLUSH) -+ { -+ OSFlushCPUCacheKM(); -+ } -+ else if(psSysData->ePendingCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_CLEAN) -+ { -+ OSCleanCPUCacheKM(); -+ } -+ -+ psSysData->ePendingCacheOpType = PVRSRV_MISC_INFO_CPUCACHEOP_NONE; -+ } -+ -+ /* submit the command */ -+ eError = PVRSRVSubmitCommandKM (psQueue, psCommand); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Failed to submit command")); -+ goto Exit; -+ } -+ -+ /* -+ Schedule an MISR to process it -+ */ -+ eError = OSScheduleMISR(psSysData); -+ -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBufferKM: Failed to schedule MISR")); -+ goto Exit; -+ } -+ -+ /* update the last flip buffer */ -+ psBuffer->psSwapChain->psLastFlipBuffer = psBuffer; -+ -+Exit: -+ -+ if(eError == PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE) -+ { -+ eError = PVRSRV_ERROR_RETRY; -+ } -+ -+ return eError; -+} -+ -+typedef struct _CALLBACK_DATA_ -+{ -+ IMG_PVOID pvPrivData; -+ IMG_UINT32 ui32PrivDataLength; -+ IMG_PVOID ppvMemInfos; -+ IMG_UINT32 ui32NumMemInfos; -+} CALLBACK_DATA; -+ -+static IMG_VOID FreePrivateData(IMG_HANDLE hCallbackData) -+{ -+ CALLBACK_DATA *psCallbackData = hCallbackData; -+ -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, psCallbackData->ui32PrivDataLength, -+ psCallbackData->pvPrivData, IMG_NULL); -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(IMG_VOID *) * psCallbackData->ui32NumMemInfos, -+ psCallbackData->ppvMemInfos, IMG_NULL); -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(CALLBACK_DATA), hCallbackData, IMG_NULL); -+} -+ -+IMG_EXPORT -+PVRSRV_ERROR PVRSRVSwapToDCBuffer2KM(IMG_HANDLE hDeviceKM, -+ IMG_HANDLE hSwapChain, -+ IMG_UINT32 ui32SwapInterval, -+ PVRSRV_KERNEL_MEM_INFO **ppsMemInfos, -+ PVRSRV_KERNEL_SYNC_INFO **ppsSyncInfos, -+ IMG_UINT32 ui32NumMemSyncInfos, -+ IMG_PVOID pvPrivData, -+ IMG_UINT32 ui32PrivDataLength, -+ IMG_HANDLE *phFence) -+{ -+ IMG_UINT32 ui32NumSyncInfos = ui32NumMemSyncInfos; -+ PVRSRV_KERNEL_SYNC_INFO **ppsCompiledSyncInfos; -+ IMG_UINT32 i, ui32NumCompiledSyncInfos; -+ DISPLAYCLASS_FLIP_COMMAND2 *psFlipCmd; -+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo; -+ PVRSRV_DC_SWAPCHAIN *psSwapChain; -+ CALLBACK_DATA *psCallbackData; -+ PVRSRV_QUEUE_INFO *psQueue; -+ PVRSRV_COMMAND *psCommand; -+ IMG_PVOID *ppvMemInfos; -+ PVRSRV_ERROR eError; -+ SYS_DATA *psSysData; -+ -+#if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) -+ struct sync_fence *apsFence[SGX_MAX_SRC_SYNCS_TA]; -+#endif /* defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) */ -+ -+ if(!hDeviceKM || !hSwapChain || !ppsMemInfos || !ppsSyncInfos || ui32NumMemSyncInfos < 1) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBuffer2KM: Invalid parameters")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psSwapChain = ((PVRSRV_DC_SWAPCHAIN_REF*)hSwapChain)->psSwapChain; -+ psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); -+ -+ /* Validate swap interval against limits */ -+ if(ui32SwapInterval < psSwapChain->ui32MinSwapInterval || -+ ui32SwapInterval > psSwapChain->ui32MaxSwapInterval) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBuffer2KM: Invalid swap interval. Requested %u, Allowed range %u-%u", -+ ui32SwapInterval, psSwapChain->ui32MinSwapInterval, psSwapChain->ui32MaxSwapInterval)); -+ return PVRSRV_ERROR_INVALID_SWAPINTERVAL; -+ } -+ -+ eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(CALLBACK_DATA), -+ (IMG_VOID **)&psCallbackData, IMG_NULL, -+ "PVRSRVSwapToDCBuffer2KM callback data"); -+ if (eError != PVRSRV_OK) -+ { -+ return eError; -+ } -+ -+ psCallbackData->pvPrivData = pvPrivData; -+ psCallbackData->ui32PrivDataLength = ui32PrivDataLength; -+ -+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(IMG_VOID *) * ui32NumMemSyncInfos, -+ (IMG_VOID **)&ppvMemInfos, IMG_NULL, -+ "Swap Command Meminfos") != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBuffer2KM: Failed to allocate space for meminfo list")); -+ psCallbackData->ppvMemInfos = IMG_NULL; -+ goto Exit; -+ } -+ -+ for(i = 0; i < ui32NumMemSyncInfos; i++) -+ { -+ ppvMemInfos[i] = ppsMemInfos[i]; -+ } -+ -+ psCallbackData->ppvMemInfos = ppvMemInfos; -+ psCallbackData->ui32NumMemInfos = ui32NumMemSyncInfos; -+ -+#if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) -+ eError = PVRSyncFencesToSyncInfos(ppsSyncInfos, &ui32NumSyncInfos, apsFence); -+ if(eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBuffer2KM: PVRSyncFencesToSyncInfos failed")); -+ goto Exit; -+ } -+#endif /* defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) */ -+ -+ /* get the queue from the buffer structure */ -+ psQueue = psSwapChain->psQueue; -+ -+#if !defined(SUPPORT_DC_CMDCOMPLETE_WHEN_NO_LONGER_DISPLAYED) -+ if(psSwapChain->ppsLastSyncInfos) -+ { -+ IMG_UINT32 ui32NumUniqueSyncInfos = psSwapChain->ui32LastNumSyncInfos; -+ IMG_BOOL *abUnique; -+ IMG_UINT32 j; -+ -+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(IMG_BOOL) * psSwapChain->ui32LastNumSyncInfos, -+ (IMG_VOID **)&abUnique, IMG_NULL, -+ "Unique booleans") != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBuffer2KM: Failed to allocate space for unique booleans")); -+ goto Exit; -+ } -+ -+ for(j = 0; j < psSwapChain->ui32LastNumSyncInfos; j++) -+ { -+ abUnique[j] = IMG_TRUE; -+ for(i = 0; i < ui32NumSyncInfos; i++) -+ { -+ PVR_ASSERT(psSwapChain->ppsLastSyncInfos[j]); -+ PVR_ASSERT(ppsSyncInfos[i]); -+ if(psSwapChain->ppsLastSyncInfos[j] == ppsSyncInfos[i]) -+ { -+ abUnique[j] = IMG_FALSE; -+ ui32NumUniqueSyncInfos--; -+ break; -+ } -+ } -+ } -+ -+ ui32NumCompiledSyncInfos = ui32NumSyncInfos + ui32NumUniqueSyncInfos; -+ -+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(PVRSRV_KERNEL_SYNC_INFO *) * ui32NumCompiledSyncInfos, -+ (IMG_VOID **)&ppsCompiledSyncInfos, IMG_NULL, -+ "Compiled syncinfos") != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBuffer2KM: Failed to allocate space for meminfo list")); -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(IMG_BOOL) * psSwapChain->ui32LastNumSyncInfos, -+ (IMG_VOID *)abUnique, IMG_NULL); -+#if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) -+ for(i = 0; apsFence[i]; i++) -+ if(apsFence[i]) -+ sync_fence_put(apsFence[i]); -+#endif -+ goto Exit; -+ } -+ -+ OSMemCopy(ppsCompiledSyncInfos, ppsSyncInfos, sizeof(PVRSRV_KERNEL_SYNC_INFO *) * ui32NumSyncInfos); -+ for(j = 0, i = ui32NumSyncInfos; j < psSwapChain->ui32LastNumSyncInfos; j++) -+ { -+ if(abUnique[j]) -+ { -+ ppsCompiledSyncInfos[i] = psSwapChain->ppsLastSyncInfos[j]; -+ i++; -+ } -+ } -+ -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(IMG_BOOL) * psSwapChain->ui32LastNumSyncInfos, -+ (IMG_VOID *)abUnique, IMG_NULL); -+ } -+ else -+#endif /* !defined(SUPPORT_DC_CMDCOMPLETE_WHEN_NO_LONGER_DISPLAYED) */ -+ { -+ IMG_UINT32 j, ui32Missing = 0; -+ -+ /* Older synchronization schemes would just pass down the syncinfos -+ * hanging off of the meminfos. So we would expect identical lists. -+ * However, newer drivers may send down additional synchronization -+ * i.e. for TQ fence operations. In such a case we need to allocate -+ * more space for the compiled syncinfos to ensure everything is -+ * ROP2 synchronized. -+ */ -+ for(j = 0; j < ui32NumSyncInfos; j++) -+ { -+ IMG_BOOL bFound = IMG_FALSE; -+ -+ for(i = 0; i < ui32NumSyncInfos; i++) -+ { -+ if(ppsSyncInfos[j] == ppsMemInfos[i]->psKernelSyncInfo) -+ { -+ bFound = IMG_TRUE; -+ break; -+ } -+ } -+ -+ if(!bFound) -+ ui32Missing++; -+ } -+ -+ if(ui32Missing) -+ { -+ IMG_UINT32 k; -+ -+ ui32NumCompiledSyncInfos = ui32NumSyncInfos + ui32Missing; -+ -+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(PVRSRV_KERNEL_SYNC_INFO *) * ui32NumCompiledSyncInfos, -+ (IMG_VOID **)&ppsCompiledSyncInfos, IMG_NULL, -+ "Compiled syncinfos") != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBuffer2KM: Failed to allocate space for meminfo list")); -+#if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) -+ for(i = 0; apsFence[i]; i++) -+ if(apsFence[i]) -+ sync_fence_put(apsFence[i]); -+#endif -+ goto Exit; -+ } -+ -+ for(i = 0; i < ui32NumSyncInfos; i++) -+ { -+ ppsCompiledSyncInfos[i] = ppsSyncInfos[i]; -+ } -+ -+ k = i; -+ for(i = 0; i < ui32NumSyncInfos; i++) -+ { -+ for(j = 0; j < ui32NumSyncInfos; j++) -+ { -+ if(ppsSyncInfos[j] == ppsMemInfos[i]->psKernelSyncInfo) -+ break; -+ } -+ -+ if(j == ui32NumSyncInfos) -+ { -+ /* Insert the unique one */ -+ PVR_ASSERT(k < ui32NumCompiledSyncInfos); -+ ppsCompiledSyncInfos[k] = ppsMemInfos[i]->psKernelSyncInfo; -+ k++; -+ } -+ } -+ } -+ else -+ { -+ ppsCompiledSyncInfos = ppsSyncInfos; -+ ui32NumCompiledSyncInfos = ui32NumSyncInfos; -+ } -+ } -+ -+ /* insert the command (header) */ -+ eError = PVRSRVInsertCommandKM (psQueue, -+ &psCommand, -+ psDCInfo->ui32DeviceID, -+ DC_FLIP_COMMAND, -+ 0, -+ IMG_NULL, -+ ui32NumCompiledSyncInfos, -+ ppsCompiledSyncInfos, -+ sizeof(DISPLAYCLASS_FLIP_COMMAND2), -+ FreePrivateData, -+ psCallbackData, -+ phFence); -+ -+#if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) -+ /* InsertCommand bumped the refcount on the raw sync objects, so we -+ * can put the fences now. Even if the fences are deleted, the syncs -+ * will persist. -+ */ -+ for(i = 0; apsFence[i]; i++) -+ if(apsFence[i]) -+ sync_fence_put(apsFence[i]); -+#endif -+ -+ if (ppsCompiledSyncInfos != ppsSyncInfos) -+ { -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(PVRSRV_KERNEL_SYNC_INFO *) * ui32NumCompiledSyncInfos, -+ (IMG_VOID *)ppsCompiledSyncInfos, -+ IMG_NULL); -+ } -+ if(eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBuffer2KM: Failed to get space in queue")); -+ goto Exit; -+ } -+ -+ /* setup the flip command */ -+ psFlipCmd = (DISPLAYCLASS_FLIP_COMMAND2*)psCommand->pvData; -+ -+ /* Ext Device Handle */ -+ psFlipCmd->hExtDevice = psDCInfo->hExtDevice; -+ -+ /* Ext SwapChain Handle */ -+ psFlipCmd->hExtSwapChain = psSwapChain->hExtSwapChain; -+ -+ /* number of vsyncs between successive flips */ -+ psFlipCmd->ui32SwapInterval = ui32SwapInterval; -+ -+ /* Opaque private data, if supplied */ -+ psFlipCmd->pvPrivData = pvPrivData; -+ psFlipCmd->ui32PrivDataLength = ui32PrivDataLength; -+ -+ psFlipCmd->ppsMemInfos = (PDC_MEM_INFO *)ppvMemInfos; -+ psFlipCmd->ui32NumMemInfos = ui32NumMemSyncInfos; -+ -+ /* Even though this is "unused", we have to initialize it, -+ * as the display controller might NULL-test it. -+ */ -+ psFlipCmd->hUnused = IMG_NULL; -+ -+ SysAcquireData(&psSysData); -+ -+ /* Because we might be composing just software surfaces, without -+ * any SGX renders since the last frame, we won't necessarily -+ * have cleaned/flushed the CPU caches before the buffers need -+ * to be displayed. -+ * -+ * Doing so now is safe because InsertCommand bumped ROP2 on the -+ * affected buffers (preventing more SW renders starting) but the -+ * display won't start to process the buffers until SubmitCommand. -+ */ -+ { -+ if(psSysData->ePendingCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_FLUSH) -+ { -+ OSFlushCPUCacheKM(); -+ } -+ else if(psSysData->ePendingCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_CLEAN) -+ { -+ OSCleanCPUCacheKM(); -+ } -+ -+ psSysData->ePendingCacheOpType = PVRSRV_MISC_INFO_CPUCACHEOP_NONE; -+ } -+ -+ /* submit the command */ -+ eError = PVRSRVSubmitCommandKM (psQueue, psCommand); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBuffer2KM: Failed to submit command")); -+#if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) -+ sync_fence_put(psCommand->pvCleanupFence); -+ sync_fence_put(*phFence); -+ *phFence = IMG_NULL; -+#endif -+ goto Exit; -+ } -+ -+ /* The command has been submitted and so psCallbackData will be freed by the callback */ -+ psCallbackData = IMG_NULL; -+ -+ /* -+ Schedule an MISR to process it -+ */ -+ eError = OSScheduleMISR(psSysData); -+ -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBuffer2KM: Failed to schedule MISR")); -+#if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) -+ sync_fence_put(*phFence); -+ *phFence = IMG_NULL; -+#endif -+ goto Exit; -+ } -+ -+#if !defined(SUPPORT_DC_CMDCOMPLETE_WHEN_NO_LONGER_DISPLAYED) -+ /* Reallocate the syncinfo list if it was too small */ -+ if (psSwapChain->ui32LastNumSyncInfos < ui32NumSyncInfos) -+ { -+ if (psSwapChain->ppsLastSyncInfos) -+ { -+ for (i = 0; i < psSwapChain->ui32LastNumSyncInfos; i++) -+ { -+ if (psSwapChain->ppsLastSyncInfos[i]) -+ { -+ PVRSRVKernelSyncInfoDecRef(psSwapChain->ppsLastSyncInfos[i], IMG_NULL); -+ psSwapChain->ppsLastSyncInfos[i] = IMG_NULL; -+ } -+ } -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_KERNEL_SYNC_INFO *) * psSwapChain->ui32LastNumSyncInfos, -+ psSwapChain->ppsLastSyncInfos, IMG_NULL); -+ } -+ -+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(PVRSRV_KERNEL_SYNC_INFO *) * ui32NumSyncInfos, -+ (IMG_VOID **)&psSwapChain->ppsLastSyncInfos, IMG_NULL, -+ "Last syncinfos") != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBuffer2KM: Failed to allocate space for meminfo list")); -+#if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) -+ sync_fence_put(*phFence); -+ *phFence = IMG_NULL; -+#endif -+ goto Exit; -+ } -+ } -+ -+ for (i = 0; i < psSwapChain->ui32LastNumSyncInfos; i++) -+ { -+ if (psSwapChain->ppsLastSyncInfos[i]) -+ { -+ PVRSRVKernelSyncInfoDecRef(psSwapChain->ppsLastSyncInfos[i], IMG_NULL); -+ psSwapChain->ppsLastSyncInfos[i] = IMG_NULL; -+ } -+ } -+ -+ psSwapChain->ui32LastNumSyncInfos = ui32NumSyncInfos; -+ -+ for(i = 0; i < ui32NumSyncInfos; i++) -+ { -+ psSwapChain->ppsLastSyncInfos[i] = ppsSyncInfos[i]; -+ PVRSRVKernelSyncInfoIncRef(psSwapChain->ppsLastSyncInfos[i], IMG_NULL); -+ } -+#endif /* !defined(SUPPORT_DC_CMDCOMPLETE_WHEN_NO_LONGER_DISPLAYED) */ -+ -+Exit: -+ if (psCallbackData) -+ { -+ if(psCallbackData->ppvMemInfos) -+ { -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(IMG_VOID *) * psCallbackData->ui32NumMemInfos, -+ psCallbackData->ppvMemInfos, IMG_NULL); -+ } -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(CALLBACK_DATA), psCallbackData, IMG_NULL); -+ } -+ if(eError == PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE) -+ { -+ eError = PVRSRV_ERROR_RETRY; -+ } -+ -+ return eError; -+} -+ -+ -+IMG_EXPORT -+PVRSRV_ERROR PVRSRVSwapToDCSystemKM(IMG_HANDLE hDeviceKM, -+ IMG_HANDLE hSwapChainRef) -+{ -+ PVRSRV_ERROR eError; -+ PVRSRV_QUEUE_INFO *psQueue; -+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo; -+ PVRSRV_DC_SWAPCHAIN *psSwapChain; -+ PVRSRV_DC_SWAPCHAIN_REF *psSwapChainRef; -+ DISPLAYCLASS_FLIP_COMMAND *psFlipCmd; -+ IMG_UINT32 ui32NumSrcSyncs = 1; -+ PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[2]; -+ PVRSRV_COMMAND *psCommand; -+ IMG_BOOL bAddReferenceToLast = IMG_TRUE; -+ IMG_UINT16 ui16SwapCommandID = DC_FLIP_COMMAND; -+ SYS_DATA *psSysData; -+ -+ if(!hDeviceKM || !hSwapChainRef) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Invalid parameters")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); -+ psSwapChainRef = (PVRSRV_DC_SWAPCHAIN_REF*)hSwapChainRef; -+ psSwapChain = psSwapChainRef->psSwapChain; -+ -+ /* -+ If more than 1 reference to the swapchain exists then -+ ignore any request to swap to the system buffer -+ */ -+ if (psSwapChain->ui32RefCount > 1) -+ { -+ return PVRSRV_OK; -+ } -+ -+ /* get the queue from the buffer structure */ -+ psQueue = psSwapChain->psQueue; -+ -+#if defined(SUPPORT_CUSTOM_SWAP_OPERATIONS) -+ -+ if(psDCInfo->psFuncTable->pfnQuerySwapCommandID != IMG_NULL) -+ { -+ psDCInfo->psFuncTable->pfnQuerySwapCommandID(psDCInfo->hExtDevice, -+ psSwapChain->hExtSwapChain, -+ psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtBuffer, -+ 0, -+ &ui16SwapCommandID, -+ &bAddReferenceToLast); -+ -+ } -+ -+#endif -+ -+ /* specify the syncs */ -+ apsSrcSync[0] = psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo; -+ if(bAddReferenceToLast && psSwapChain->psLastFlipBuffer) -+ { -+ /* Make sure we don't make a double dependency on the same server */ -+ if (apsSrcSync[0] != psSwapChain->psLastFlipBuffer->sDeviceClassBuffer.psKernelSyncInfo) -+ { -+ apsSrcSync[1] = psSwapChain->psLastFlipBuffer->sDeviceClassBuffer.psKernelSyncInfo; -+ ui32NumSrcSyncs++; -+ } -+ } -+ -+ /* insert the command (header) */ -+ eError = PVRSRVInsertCommandKM (psQueue, -+ &psCommand, -+ psDCInfo->ui32DeviceID, -+ ui16SwapCommandID, -+ 0, -+ IMG_NULL, -+ ui32NumSrcSyncs, -+ apsSrcSync, -+ sizeof(DISPLAYCLASS_FLIP_COMMAND), -+ IMG_NULL, -+ IMG_NULL, -+ IMG_NULL); -+ if(eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Failed to get space in queue")); -+ goto Exit; -+ } -+ -+ /* setup the flip command */ -+ psFlipCmd = (DISPLAYCLASS_FLIP_COMMAND*)psCommand->pvData; -+ -+ /* Ext Device Handle */ -+ psFlipCmd->hExtDevice = psDCInfo->hExtDevice; -+ -+ /* Ext SwapChain Handle */ -+ psFlipCmd->hExtSwapChain = psSwapChain->hExtSwapChain; -+ -+ /* Ext Buffer Handle (Buffer to Flip to) */ -+ psFlipCmd->hExtBuffer = psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtBuffer; -+ -+ /* private tag */ -+ psFlipCmd->hPrivateTag = IMG_NULL; -+ -+ /* setup the clip rects */ -+ psFlipCmd->ui32ClipRectCount = 0; -+ -+ psFlipCmd->ui32SwapInterval = 1; -+ -+ /* submit the command */ -+ eError = PVRSRVSubmitCommandKM (psQueue, psCommand); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Failed to submit command")); -+ goto Exit; -+ } -+ -+ /* Schedule an MISR to process it */ -+ SysAcquireData(&psSysData); -+ eError = OSScheduleMISR(psSysData); -+ -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Failed to schedule MISR")); -+ goto Exit; -+ } -+ -+ /* update the last flip buffer */ -+ psSwapChain->psLastFlipBuffer = &psDCInfo->sSystemBuffer; -+ -+ eError = PVRSRV_OK; -+ -+Exit: -+ -+ if(eError == PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE) -+ { -+ eError = PVRSRV_ERROR_RETRY; -+ } -+ -+ return eError; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVRegisterSystemISRHandler -+ -+ @Description -+ -+ registers an external ISR to be called of the back of a system ISR -+ -+ @Input ppfnISRHandler : ISR pointer -+ -+ @Input hISRHandlerData : Callback data -+ -+ @Input ui32ISRSourceMask : ISR Mask -+ -+ @Input ui32DeviceID : unique device key -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+static -+PVRSRV_ERROR PVRSRVRegisterSystemISRHandler (PFN_ISR_HANDLER pfnISRHandler, -+ IMG_VOID *pvISRHandlerData, -+ IMG_UINT32 ui32ISRSourceMask, -+ IMG_UINT32 ui32DeviceID) -+{ -+ SYS_DATA *psSysData; -+ PVRSRV_DEVICE_NODE *psDevNode; -+ -+ PVR_UNREFERENCED_PARAMETER(ui32ISRSourceMask); -+ -+ SysAcquireData(&psSysData); -+ -+ /* Find Dev Node (just using the device id, ignore the class) */ -+ psDevNode = (PVRSRV_DEVICE_NODE*) -+ List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList, -+ &MatchDeviceKM_AnyVaCb, -+ ui32DeviceID, -+ IMG_TRUE); -+ -+ if (psDevNode == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterSystemISRHandler: Failed to get psDevNode")); -+ PVR_DBG_BREAK; -+ return PVRSRV_ERROR_NO_DEVICENODE_FOUND; -+ } -+ -+ /* set up data before enabling the ISR */ -+ psDevNode->pvISRData = (IMG_VOID*) pvISRHandlerData; -+ -+ /* enable the ISR */ -+ psDevNode->pfnDeviceISR = pfnISRHandler; -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVSetDCState_ForEachVaCb -+ -+ @Description -+ -+ If the device node is a display, calls its set state function. -+ -+ @Input psDeviceNode - the device node -+ va - variable argument list with: -+ ui32State - the state to be set. -+ -+******************************************************************************/ -+static -+IMG_VOID PVRSRVSetDCState_ForEachVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va) -+{ -+ PVRSRV_DISPLAYCLASS_INFO *psDCInfo; -+ IMG_UINT32 ui32State; -+ ui32State = va_arg(va, IMG_UINT32); -+ -+ if (psDeviceNode->sDevId.eDeviceClass == PVRSRV_DEVICE_CLASS_DISPLAY) -+ { -+ psDCInfo = (PVRSRV_DISPLAYCLASS_INFO *)psDeviceNode->pvDevice; -+ if (psDCInfo->psFuncTable->pfnSetDCState && psDCInfo->hExtDevice) -+ { -+ psDCInfo->psFuncTable->pfnSetDCState(psDCInfo->hExtDevice, ui32State); -+ } -+ } -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVSetDCState -+ -+ @Description -+ -+ Calls the display driver(s) to put them into the specified state. -+ -+ @Input ui32State: new DC state - one of DC_STATE_* -+ -+******************************************************************************/ -+IMG_VOID IMG_CALLCONV PVRSRVSetDCState(IMG_UINT32 ui32State) -+{ -+/* PVRSRV_DISPLAYCLASS_INFO *psDCInfo; -+ PVRSRV_DEVICE_NODE *psDeviceNode; */ -+ SYS_DATA *psSysData; -+ -+ SysAcquireData(&psSysData); -+ -+ List_PVRSRV_DEVICE_NODE_ForEach_va(psSysData->psDeviceNodeList, -+ &PVRSRVSetDCState_ForEachVaCb, -+ ui32State); -+} -+ -+static PVRSRV_ERROR -+PVRSRVDCMemInfoGetCpuVAddr(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo, -+ IMG_CPU_VIRTADDR *pVAddr) -+{ -+ *pVAddr = psKernelMemInfo->pvLinAddrKM; -+ return PVRSRV_OK; -+} -+ -+static PVRSRV_ERROR -+PVRSRVDCMemInfoGetCpuPAddr(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo, -+ IMG_SIZE_T uByteOffset, IMG_CPU_PHYADDR *pPAddr) -+{ -+ *pPAddr = OSMemHandleToCpuPAddr(psKernelMemInfo->sMemBlk.hOSMemHandle, uByteOffset); -+ return PVRSRV_OK; -+} -+ -+static PVRSRV_ERROR -+PVRSRVDCMemInfoGetByteSize(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo, -+ IMG_SIZE_T *uByteSize) -+{ -+ *uByteSize = psKernelMemInfo->uAllocSize; -+ return PVRSRV_OK; -+} -+ -+static IMG_BOOL -+PVRSRVDCMemInfoIsPhysContig(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo) -+{ -+ return OSMemHandleIsPhysContig(psKernelMemInfo->sMemBlk.hOSMemHandle); -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRGetDisplayClassJTable -+ -+ @Description -+ -+ Sets up function table for 3rd party Display Class Device to call through -+ -+ @Input psJTable : pointer to function pointer table memory -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+IMG_EXPORT -+IMG_BOOL PVRGetDisplayClassJTable(PVRSRV_DC_DISP2SRV_KMJTABLE *psJTable) -+{ -+ psJTable->ui32TableSize = sizeof(PVRSRV_DC_DISP2SRV_KMJTABLE); -+ psJTable->pfnPVRSRVRegisterDCDevice = &PVRSRVRegisterDCDeviceKM; -+ psJTable->pfnPVRSRVRemoveDCDevice = &PVRSRVRemoveDCDeviceKM; -+ psJTable->pfnPVRSRVOEMFunction = &SysOEMFunction; -+ psJTable->pfnPVRSRVRegisterCmdProcList = &PVRSRVRegisterCmdProcListKM; -+ psJTable->pfnPVRSRVRemoveCmdProcList = &PVRSRVRemoveCmdProcListKM; -+ psJTable->pfnPVRSRVCmdComplete = &PVRSRVCommandCompleteKM; -+ psJTable->pfnPVRSRVRegisterSystemISRHandler = &PVRSRVRegisterSystemISRHandler; -+ psJTable->pfnPVRSRVRegisterPowerDevice = &PVRSRVRegisterPowerDevice; -+#if defined(SUPPORT_CUSTOM_SWAP_OPERATIONS) -+ psJTable->pfnPVRSRVFreeCmdCompletePacket = &PVRSRVFreeCommandCompletePacketKM; -+#endif -+ psJTable->pfnPVRSRVDCMemInfoGetCpuVAddr = &PVRSRVDCMemInfoGetCpuVAddr; -+ psJTable->pfnPVRSRVDCMemInfoGetCpuPAddr = &PVRSRVDCMemInfoGetCpuPAddr; -+ psJTable->pfnPVRSRVDCMemInfoGetByteSize = &PVRSRVDCMemInfoGetByteSize; -+ psJTable->pfnPVRSRVDCMemInfoIsPhysContig = &PVRSRVDCMemInfoIsPhysContig; -+ return IMG_TRUE; -+} -+ -+ -+ -+/****************************************************************************** -+ -+ @Function PVRSRVCloseBCDeviceKM -+ -+ @Description -+ -+ Closes a connection to the Buffer Class device -+ -+ @Input hDeviceKM : device handle -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR PVRSRVCloseBCDeviceKM (IMG_HANDLE hDeviceKM) -+{ -+ PVRSRV_ERROR eError; -+ PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo; -+ -+ psBCPerContextInfo = (PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *)hDeviceKM; -+ -+ /* Remove the item from the resman list and trigger the callback. */ -+ eError = ResManFreeResByPtr(psBCPerContextInfo->hResItem, CLEANUP_WITH_POLL); -+ -+ return eError; -+} -+ -+ -+static PVRSRV_ERROR CloseBCDeviceCallBack(IMG_PVOID pvParam, -+ IMG_UINT32 ui32Param, -+ IMG_BOOL bDummy) -+{ -+ PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo; -+ PVRSRV_BUFFERCLASS_INFO *psBCInfo; -+ IMG_UINT32 i; -+ -+ PVR_UNREFERENCED_PARAMETER(ui32Param); -+ PVR_UNREFERENCED_PARAMETER(bDummy); -+ -+ psBCPerContextInfo = (PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *)pvParam; -+ -+ psBCInfo = psBCPerContextInfo->psBCInfo; -+ -+ for (i = 0; i < psBCInfo->ui32BufferCount; i++) -+ { -+ if (psBCInfo->psBuffer[i].sDeviceClassBuffer.ui32MemMapRefCount != 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "CloseBCDeviceCallBack: buffer %d (0x%p) still mapped (ui32MemMapRefCount = %d)", -+ i, -+ &psBCInfo->psBuffer[i].sDeviceClassBuffer, -+ psBCInfo->psBuffer[i].sDeviceClassBuffer.ui32MemMapRefCount)); -+ return PVRSRV_ERROR_STILL_MAPPED; -+ } -+ } -+ -+ psBCInfo->ui32RefCount--; -+ if(psBCInfo->ui32RefCount == 0) -+ { -+ /* close the external device */ -+ psBCInfo->psFuncTable->pfnCloseBCDevice(psBCInfo->ui32DeviceID, psBCInfo->hExtDevice); -+ -+ /* free syncinfos */ -+ for(i=0; i<psBCInfo->ui32BufferCount; i++) -+ { -+ if(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo) -+ { -+ PVRSRVKernelSyncInfoDecRef(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo, IMG_NULL); -+ } -+ } -+ -+ /* free buffers */ -+ if(psBCInfo->psBuffer) -+ { -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BC_BUFFER) * psBCInfo->ui32BufferCount, psBCInfo->psBuffer, IMG_NULL); -+ psBCInfo->psBuffer = IMG_NULL; -+ } -+ } -+ -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BUFFERCLASS_PERCONTEXT_INFO), psBCPerContextInfo, IMG_NULL); -+ /*not nulling pointer, copy on stack*/ -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVOpenBCDeviceKM -+ -+ @Description -+ -+ Opens a connection to the Buffer Class device, associating the connection -+ with a Device Memory Context for a services managed device -+ -+ @Input psPerProc : Per-process data -+ @Input ui32DeviceID : unique device index -+ @Input hDevCookie : devcookie used to derive the Device Memory -+ Context into BC surfaces will be mapped into -+ @Outut phDeviceKM : handle to the DC device -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR PVRSRVOpenBCDeviceKM (PVRSRV_PER_PROCESS_DATA *psPerProc, -+ IMG_UINT32 ui32DeviceID, -+ IMG_HANDLE hDevCookie, -+ IMG_HANDLE *phDeviceKM) -+{ -+ PVRSRV_BUFFERCLASS_INFO *psBCInfo; -+ PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo; -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+ SYS_DATA *psSysData; -+ IMG_UINT32 i; -+ PVRSRV_ERROR eError; -+ -+ if(!phDeviceKM || !hDevCookie) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Invalid params")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ SysAcquireData(&psSysData); -+ -+ /* find the matching devicenode */ -+ psDeviceNode = (PVRSRV_DEVICE_NODE*) -+ List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList, -+ &MatchDeviceKM_AnyVaCb, -+ ui32DeviceID, -+ IMG_FALSE, -+ PVRSRV_DEVICE_CLASS_BUFFER); -+ if (!psDeviceNode) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: No devnode matching index %d", ui32DeviceID)); -+ return PVRSRV_ERROR_NO_DEVICENODE_FOUND; -+ } -+ psBCInfo = (PVRSRV_BUFFERCLASS_INFO*)psDeviceNode->pvDevice; -+ -+/* -+FoundDevice: -+*/ -+ /* -+ Allocate the per-context BC Info before calling the external device, -+ to make error handling easier. -+ */ -+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(*psBCPerContextInfo), -+ (IMG_VOID **)&psBCPerContextInfo, IMG_NULL, -+ "Buffer Class per Context Info") != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed psBCPerContextInfo alloc")); -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ OSMemSet(psBCPerContextInfo, 0, sizeof(*psBCPerContextInfo)); -+ -+ if(psBCInfo->ui32RefCount++ == 0) -+ { -+ BUFFER_INFO sBufferInfo; -+ -+ psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie; -+ -+ /* store the device kernel context to map into */ -+ psBCInfo->hDevMemContext = (IMG_HANDLE)psDeviceNode->sDevMemoryInfo.pBMKernelContext; -+ -+ /* open the external device */ -+ eError = psBCInfo->psFuncTable->pfnOpenBCDevice(ui32DeviceID, &psBCInfo->hExtDevice); -+ if(eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed to open external BC device")); -+ return eError; -+ } -+ -+ /* get information about the buffers */ -+ eError = psBCInfo->psFuncTable->pfnGetBCInfo(psBCInfo->hExtDevice, &sBufferInfo); -+ if(eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM : Failed to get BC Info")); -+ return eError; -+ } -+ -+ /* interpret and store info */ -+ psBCInfo->ui32BufferCount = sBufferInfo.ui32BufferCount; -+ -+ /* allocate BC buffers */ -+ eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(PVRSRV_BC_BUFFER) * sBufferInfo.ui32BufferCount, -+ (IMG_VOID **)&psBCInfo->psBuffer, -+ IMG_NULL, -+ "Array of Buffer Class Buffer"); -+ if(eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed to allocate BC buffers")); -+ return eError; -+ } -+ OSMemSet (psBCInfo->psBuffer, -+ 0, -+ sizeof(PVRSRV_BC_BUFFER) * sBufferInfo.ui32BufferCount); -+ -+ for(i=0; i<psBCInfo->ui32BufferCount; i++) -+ { -+ /* create a syncinfo for the device's system surface */ -+ eError = PVRSRVAllocSyncInfoKM(IMG_NULL, -+ psBCInfo->hDevMemContext, -+ &psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo); -+ if(eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed sync info alloc")); -+ goto ErrorExit; -+ } -+ -+ /* -+ get the buffers from the buffer class -+ drivers by index, passing-in the syncdata objects -+ */ -+ eError = psBCInfo->psFuncTable->pfnGetBCBuffer(psBCInfo->hExtDevice, -+ i, -+ psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->psSyncData, -+ &psBCInfo->psBuffer[i].sDeviceClassBuffer.hExtBuffer); -+ if(eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed to get BC buffers")); -+ goto ErrorExit; -+ } -+ -+ /* setup common device class info */ -+ psBCInfo->psBuffer[i].sDeviceClassBuffer.pfnGetBufferAddr = psBCInfo->psFuncTable->pfnGetBufferAddr; -+ psBCInfo->psBuffer[i].sDeviceClassBuffer.hDevMemContext = psBCInfo->hDevMemContext; -+ psBCInfo->psBuffer[i].sDeviceClassBuffer.hExtDevice = psBCInfo->hExtDevice; -+ psBCInfo->psBuffer[i].sDeviceClassBuffer.ui32MemMapRefCount = 0; -+ } -+ } -+ -+ psBCPerContextInfo->psBCInfo = psBCInfo; -+ psBCPerContextInfo->hResItem = ResManRegisterRes(psPerProc->hResManContext, -+ RESMAN_TYPE_BUFFERCLASS_DEVICE, -+ psBCPerContextInfo, -+ 0, -+ &CloseBCDeviceCallBack); -+ -+ /* return a reference to the BCPerContextInfo */ -+ *phDeviceKM = (IMG_HANDLE)psBCPerContextInfo; -+ -+ return PVRSRV_OK; -+ -+ErrorExit: -+ -+ /* free syncinfos */ -+ for(i=0; i<psBCInfo->ui32BufferCount; i++) -+ { -+ if(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo) -+ { -+ PVRSRVKernelSyncInfoDecRef(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo, IMG_NULL); -+ } -+ } -+ -+ /* free buffers */ -+ if(psBCInfo->psBuffer) -+ { -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BC_BUFFER), psBCInfo->psBuffer, IMG_NULL); -+ psBCInfo->psBuffer = IMG_NULL; -+ } -+ -+ return eError; -+} -+ -+ -+ -+ -+/****************************************************************************** -+ -+ @Function PVRSRVGetBCInfoKM -+ -+ @Description -+ -+ Gets Buffer Class device Info -+ -+ @Input hDeviceKM : device handle -+ @Output psBufferInfo -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR PVRSRVGetBCInfoKM (IMG_HANDLE hDeviceKM, -+ BUFFER_INFO *psBufferInfo) -+{ -+ PVRSRV_BUFFERCLASS_INFO *psBCInfo; -+ PVRSRV_ERROR eError; -+ -+ if(!hDeviceKM || !psBufferInfo) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetBCInfoKM: Invalid parameters")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psBCInfo = BCDeviceHandleToBCInfo(hDeviceKM); -+ -+ eError = psBCInfo->psFuncTable->pfnGetBCInfo(psBCInfo->hExtDevice, psBufferInfo); -+ -+ if(eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetBCInfoKM : Failed to get BC Info")); -+ return eError; -+ } -+ -+ return PVRSRV_OK; -+} -+ -+ -+/****************************************************************************** -+ -+ @Function PVRSRVGetBCBufferKM -+ -+ @Description -+ -+ Gets Buffer Class Buffer Handle -+ -+ @Input hDeviceKM : device handle -+ @Output psBufferInfo -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR PVRSRVGetBCBufferKM (IMG_HANDLE hDeviceKM, -+ IMG_UINT32 ui32BufferIndex, -+ IMG_HANDLE *phBuffer) -+{ -+ PVRSRV_BUFFERCLASS_INFO *psBCInfo; -+ -+ if(!hDeviceKM || !phBuffer) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetBCBufferKM: Invalid parameters")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psBCInfo = BCDeviceHandleToBCInfo(hDeviceKM); -+ -+ if(ui32BufferIndex < psBCInfo->ui32BufferCount) -+ { -+ *phBuffer = (IMG_HANDLE)&psBCInfo->psBuffer[ui32BufferIndex]; -+ } -+ else -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetBCBufferKM: Buffer index %d out of range (%d)", ui32BufferIndex,psBCInfo->ui32BufferCount)); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRGetBufferClassJTable -+ -+ @Description -+ -+ Sets up function table for 3rd party Buffer Class Device to call through -+ -+ @Input psJTable : pointer to function pointer table memory -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+IMG_EXPORT -+IMG_BOOL PVRGetBufferClassJTable(PVRSRV_BC_BUFFER2SRV_KMJTABLE *psJTable) -+{ -+ psJTable->ui32TableSize = sizeof(PVRSRV_BC_BUFFER2SRV_KMJTABLE); -+ -+ psJTable->pfnPVRSRVRegisterBCDevice = &PVRSRVRegisterBCDeviceKM; -+ psJTable->pfnPVRSRVScheduleDevices = &PVRSRVScheduleDevicesKM; -+ psJTable->pfnPVRSRVRemoveBCDevice = &PVRSRVRemoveBCDeviceKM; -+ -+ return IMG_TRUE; -+} -+ -+/****************************************************************************** -+ End of file (deviceclass.c) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/common/deviceid.h b/drivers/staging/ti-es8-sgx/services4/srvkm/common/deviceid.h -new file mode 100644 -index 0000000..1cf9f0f ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/common/deviceid.h -@@ -0,0 +1,51 @@ -+/*************************************************************************/ /*! -+@Title Device ID helpers -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#ifndef __DEVICEID_H__ -+#define __DEVICEID_H__ -+ -+#include "services.h" -+#include "syscommon.h" -+ -+PVRSRV_ERROR AllocateDeviceID(SYS_DATA *psSysData, IMG_UINT32 *pui32DevID); -+PVRSRV_ERROR FreeDeviceID(SYS_DATA *psSysData, IMG_UINT32 ui32DevID); -+ -+#endif /* __DEVICEID_H__ */ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/common/devicemem.c b/drivers/staging/ti-es8-sgx/services4/srvkm/common/devicemem.c -new file mode 100644 -index 0000000..e36e8f6 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/common/devicemem.c -@@ -0,0 +1,2645 @@ -+/*************************************************************************/ /*! -+@Title Device addressable memory functions -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Device addressable memory APIs -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#include <stddef.h> -+ -+#include "services_headers.h" -+#include "buffer_manager.h" -+#include "pdump_km.h" -+#include "pvr_bridge_km.h" -+#include "osfunc.h" -+#include "devicemem.h" -+ -+#if defined(SUPPORT_ION) -+#include "ion.h" -+#include "env_perproc.h" -+#include "ion_sync.h" -+ -+/* Start size of the g_IonSyncHash hash table */ -+#define ION_SYNC_HASH_SIZE 20 -+HASH_TABLE *g_psIonSyncHash = IMG_NULL; -+#endif -+ -+/* local function prototypes */ -+static PVRSRV_ERROR AllocDeviceMem(IMG_HANDLE hDevCookie, -+ IMG_HANDLE hDevMemHeap, -+ IMG_UINT32 ui32Flags, -+ IMG_SIZE_T ui32Size, -+ IMG_SIZE_T ui32Alignment, -+ IMG_PVOID pvPrivData, -+ IMG_UINT32 ui32PrivDataLength, -+ IMG_UINT32 ui32ChunkSize, -+ IMG_UINT32 ui32NumVirtChunks, -+ IMG_UINT32 ui32NumPhysChunks, -+ IMG_BOOL *pabMapChunk, -+ PVRSRV_KERNEL_MEM_INFO **ppsMemInfo); -+ -+/* local structures */ -+ -+/* -+ structure stored in resman to store references -+ to the SRC and DST meminfo -+*/ -+typedef struct _RESMAN_MAP_DEVICE_MEM_DATA_ -+{ -+ /* the DST meminfo created by the map */ -+ PVRSRV_KERNEL_MEM_INFO *psMemInfo; -+ /* SRC meminfo */ -+ PVRSRV_KERNEL_MEM_INFO *psSrcMemInfo; -+} RESMAN_MAP_DEVICE_MEM_DATA; -+ -+/* -+ map device class resman memory storage structure -+*/ -+typedef struct _PVRSRV_DC_MAPINFO_ -+{ -+ PVRSRV_KERNEL_MEM_INFO *psMemInfo; -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+ IMG_UINT32 ui32RangeIndex; -+ IMG_UINT32 ui32TilingStride; -+ PVRSRV_DEVICECLASS_BUFFER *psDeviceClassBuffer; -+} PVRSRV_DC_MAPINFO; -+ -+static IMG_UINT32 g_ui32SyncUID = 0; -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVGetDeviceMemHeapsKM -+ -+ @Description -+ -+ Gets the device shared memory heaps -+ -+ @Input hDevCookie : -+ @Output phDevMemContext : ptr to handle to memory context -+ @Output psHeapInfo : ptr to array of heap info -+ -+ @Return PVRSRV_DEVICE_NODE, valid devnode or IMG_NULL -+ -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDeviceMemHeapsKM(IMG_HANDLE hDevCookie, -+ PVRSRV_HEAP_INFO *psHeapInfo) -+{ -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+ IMG_UINT32 ui32HeapCount; -+ DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; -+ IMG_UINT32 i; -+ -+ if (hDevCookie == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetDeviceMemHeapsKM: hDevCookie invalid")); -+ PVR_DBG_BREAK; -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie; -+ -+ /* Setup useful pointers */ -+ ui32HeapCount = psDeviceNode->sDevMemoryInfo.ui32HeapCount; -+ psDeviceMemoryHeap = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeap; -+ -+ /* check we don't exceed the max number of heaps */ -+ PVR_ASSERT(ui32HeapCount <= PVRSRV_MAX_CLIENT_HEAPS); -+ -+ /* retrieve heap information */ -+ for(i=0; i<ui32HeapCount; i++) -+ { -+ /* return information about the heap */ -+ psHeapInfo[i].ui32HeapID = psDeviceMemoryHeap[i].ui32HeapID; -+ psHeapInfo[i].hDevMemHeap = psDeviceMemoryHeap[i].hDevMemHeap; -+ psHeapInfo[i].sDevVAddrBase = psDeviceMemoryHeap[i].sDevVAddrBase; -+ psHeapInfo[i].ui32HeapByteSize = psDeviceMemoryHeap[i].ui32HeapSize; -+ psHeapInfo[i].ui32Attribs = psDeviceMemoryHeap[i].ui32Attribs; -+ /* (XTileStride > 0) denotes a tiled heap */ -+ psHeapInfo[i].ui32XTileStride = psDeviceMemoryHeap[i].ui32XTileStride; -+ } -+ -+ for(; i < PVRSRV_MAX_CLIENT_HEAPS; i++) -+ { -+ OSMemSet(psHeapInfo + i, 0, sizeof(*psHeapInfo)); -+ psHeapInfo[i].ui32HeapID = (IMG_UINT32)PVRSRV_UNDEFINED_HEAP_ID; -+ } -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVCreateDeviceMemContextKM -+ -+ @Description -+ -+ Creates a device memory context -+ -+ @Input hDevCookie : -+ @Input psPerProc : Per-process data -+ @Output phDevMemContext : ptr to handle to memory context -+ @Output pui32ClientHeapCount : ptr to heap count -+ @Output psHeapInfo : ptr to array of heap info -+ -+ @Return PVRSRV_DEVICE_NODE, valid devnode or IMG_NULL -+ -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateDeviceMemContextKM(IMG_HANDLE hDevCookie, -+ PVRSRV_PER_PROCESS_DATA *psPerProc, -+ IMG_HANDLE *phDevMemContext, -+ IMG_UINT32 *pui32ClientHeapCount, -+ PVRSRV_HEAP_INFO *psHeapInfo, -+ IMG_BOOL *pbCreated, -+ IMG_BOOL *pbShared) -+{ -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+ IMG_UINT32 ui32HeapCount, ui32ClientHeapCount=0; -+ DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; -+ IMG_HANDLE hDevMemContext; -+ IMG_HANDLE hDevMemHeap; -+ IMG_DEV_PHYADDR sPDDevPAddr; -+ IMG_UINT32 i; -+ -+#if !defined(PVR_SECURE_HANDLES) -+ PVR_UNREFERENCED_PARAMETER(pbShared); -+#endif -+ -+ if (hDevCookie == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVCreateDeviceMemContextKM: hDevCookie invalid")); -+ PVR_DBG_BREAK; -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie; -+ -+ /* -+ Setup useful pointers -+ */ -+ ui32HeapCount = psDeviceNode->sDevMemoryInfo.ui32HeapCount; -+ psDeviceMemoryHeap = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeap; -+ -+ /* -+ check we don't exceed the max number of heaps -+ */ -+ PVR_ASSERT(ui32HeapCount <= PVRSRV_MAX_CLIENT_HEAPS); -+ -+ /* -+ Create a memory context for the caller -+ */ -+ hDevMemContext = BM_CreateContext(psDeviceNode, -+ &sPDDevPAddr, -+ psPerProc, -+ pbCreated); -+ if (hDevMemContext == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDeviceMemContextKM: Failed BM_CreateContext")); -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ -+ /* create the per context heaps */ -+ for(i=0; i<ui32HeapCount; i++) -+ { -+ switch(psDeviceMemoryHeap[i].DevMemHeapType) -+ { -+ case DEVICE_MEMORY_HEAP_SHARED_EXPORTED: -+ { -+ /* return information about the heap */ -+ psHeapInfo[ui32ClientHeapCount].ui32HeapID = psDeviceMemoryHeap[i].ui32HeapID; -+ psHeapInfo[ui32ClientHeapCount].hDevMemHeap = psDeviceMemoryHeap[i].hDevMemHeap; -+ psHeapInfo[ui32ClientHeapCount].sDevVAddrBase = psDeviceMemoryHeap[i].sDevVAddrBase; -+ psHeapInfo[ui32ClientHeapCount].ui32HeapByteSize = psDeviceMemoryHeap[i].ui32HeapSize; -+ psHeapInfo[ui32ClientHeapCount].ui32Attribs = psDeviceMemoryHeap[i].ui32Attribs; -+ #if defined(SUPPORT_MEMORY_TILING) -+ psHeapInfo[ui32ClientHeapCount].ui32XTileStride = psDeviceMemoryHeap[i].ui32XTileStride; -+ #else -+ psHeapInfo[ui32ClientHeapCount].ui32XTileStride = 0; -+ #endif -+ -+#if defined(PVR_SECURE_HANDLES) -+ pbShared[ui32ClientHeapCount] = IMG_TRUE; -+#endif -+ ui32ClientHeapCount++; -+ break; -+ } -+ case DEVICE_MEMORY_HEAP_PERCONTEXT: -+ { -+ if (psDeviceMemoryHeap[i].ui32HeapSize > 0) -+ { -+ hDevMemHeap = BM_CreateHeap(hDevMemContext, -+ &psDeviceMemoryHeap[i]); -+ if (hDevMemHeap == IMG_NULL) -+ { -+ BM_DestroyContext(hDevMemContext, IMG_NULL); -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ } -+ else -+ { -+ hDevMemHeap = IMG_NULL; -+ } -+ -+ /* return information about the heap */ -+ psHeapInfo[ui32ClientHeapCount].ui32HeapID = psDeviceMemoryHeap[i].ui32HeapID; -+ psHeapInfo[ui32ClientHeapCount].hDevMemHeap = hDevMemHeap; -+ psHeapInfo[ui32ClientHeapCount].sDevVAddrBase = psDeviceMemoryHeap[i].sDevVAddrBase; -+ psHeapInfo[ui32ClientHeapCount].ui32HeapByteSize = psDeviceMemoryHeap[i].ui32HeapSize; -+ psHeapInfo[ui32ClientHeapCount].ui32Attribs = psDeviceMemoryHeap[i].ui32Attribs; -+ #if defined(SUPPORT_MEMORY_TILING) -+ psHeapInfo[ui32ClientHeapCount].ui32XTileStride = psDeviceMemoryHeap[i].ui32XTileStride; -+ #else -+ psHeapInfo[ui32ClientHeapCount].ui32XTileStride = 0; -+ #endif -+#if defined(PVR_SECURE_HANDLES) -+ pbShared[ui32ClientHeapCount] = IMG_FALSE; -+#endif -+ -+ ui32ClientHeapCount++; -+ break; -+ } -+ } -+ } -+ -+ /* return shared_exported and per context heap information to the caller */ -+ *pui32ClientHeapCount = ui32ClientHeapCount; -+ *phDevMemContext = hDevMemContext; -+ -+ return PVRSRV_OK; -+} -+ -+IMG_EXPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyDeviceMemContextKM(IMG_HANDLE hDevCookie, -+ IMG_HANDLE hDevMemContext, -+ IMG_BOOL *pbDestroyed) -+{ -+ PVR_UNREFERENCED_PARAMETER(hDevCookie); -+ -+ return BM_DestroyContext(hDevMemContext, pbDestroyed); -+} -+ -+ -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVGetDeviceMemHeapInfoKM -+ -+ @Description -+ -+ gets heap info -+ -+ @Input hDevCookie : -+ @Input hDevMemContext : ptr to handle to memory context -+ @Output pui32ClientHeapCount : ptr to heap count -+ @Output psHeapInfo : ptr to array of heap info -+ -+ @Return -+ -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDeviceMemHeapInfoKM(IMG_HANDLE hDevCookie, -+ IMG_HANDLE hDevMemContext, -+ IMG_UINT32 *pui32ClientHeapCount, -+ PVRSRV_HEAP_INFO *psHeapInfo, -+ IMG_BOOL *pbShared) -+{ -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+ IMG_UINT32 ui32HeapCount, ui32ClientHeapCount=0; -+ DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; -+ IMG_HANDLE hDevMemHeap; -+ IMG_UINT32 i; -+ -+#if !defined(PVR_SECURE_HANDLES) -+ PVR_UNREFERENCED_PARAMETER(pbShared); -+#endif -+ -+ if (hDevCookie == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetDeviceMemHeapInfoKM: hDevCookie invalid")); -+ PVR_DBG_BREAK; -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie; -+ -+ /* -+ Setup useful pointers -+ */ -+ ui32HeapCount = psDeviceNode->sDevMemoryInfo.ui32HeapCount; -+ psDeviceMemoryHeap = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeap; -+ -+ /* -+ check we don't exceed the max number of heaps -+ */ -+ PVR_ASSERT(ui32HeapCount <= PVRSRV_MAX_CLIENT_HEAPS); -+ -+ /* create the per context heaps */ -+ for(i=0; i<ui32HeapCount; i++) -+ { -+ switch(psDeviceMemoryHeap[i].DevMemHeapType) -+ { -+ case DEVICE_MEMORY_HEAP_SHARED_EXPORTED: -+ { -+ /* return information about the heap */ -+ psHeapInfo[ui32ClientHeapCount].ui32HeapID = psDeviceMemoryHeap[i].ui32HeapID; -+ psHeapInfo[ui32ClientHeapCount].hDevMemHeap = psDeviceMemoryHeap[i].hDevMemHeap; -+ psHeapInfo[ui32ClientHeapCount].sDevVAddrBase = psDeviceMemoryHeap[i].sDevVAddrBase; -+ psHeapInfo[ui32ClientHeapCount].ui32HeapByteSize = psDeviceMemoryHeap[i].ui32HeapSize; -+ psHeapInfo[ui32ClientHeapCount].ui32Attribs = psDeviceMemoryHeap[i].ui32Attribs; -+ psHeapInfo[ui32ClientHeapCount].ui32XTileStride = psDeviceMemoryHeap[i].ui32XTileStride; -+#if defined(PVR_SECURE_HANDLES) -+ pbShared[ui32ClientHeapCount] = IMG_TRUE; -+#endif -+ ui32ClientHeapCount++; -+ break; -+ } -+ case DEVICE_MEMORY_HEAP_PERCONTEXT: -+ { -+ if (psDeviceMemoryHeap[i].ui32HeapSize > 0) -+ { -+ hDevMemHeap = BM_CreateHeap(hDevMemContext, -+ &psDeviceMemoryHeap[i]); -+ -+ if (hDevMemHeap == IMG_NULL) -+ { -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ } -+ else -+ { -+ hDevMemHeap = IMG_NULL; -+ } -+ -+ /* return information about the heap */ -+ psHeapInfo[ui32ClientHeapCount].ui32HeapID = psDeviceMemoryHeap[i].ui32HeapID; -+ psHeapInfo[ui32ClientHeapCount].hDevMemHeap = hDevMemHeap; -+ psHeapInfo[ui32ClientHeapCount].sDevVAddrBase = psDeviceMemoryHeap[i].sDevVAddrBase; -+ psHeapInfo[ui32ClientHeapCount].ui32HeapByteSize = psDeviceMemoryHeap[i].ui32HeapSize; -+ psHeapInfo[ui32ClientHeapCount].ui32Attribs = psDeviceMemoryHeap[i].ui32Attribs; -+ psHeapInfo[ui32ClientHeapCount].ui32XTileStride = psDeviceMemoryHeap[i].ui32XTileStride; -+#if defined(PVR_SECURE_HANDLES) -+ pbShared[ui32ClientHeapCount] = IMG_FALSE; -+#endif -+ -+ ui32ClientHeapCount++; -+ break; -+ } -+ } -+ } -+ -+ /* return shared_exported and per context heap information to the caller */ -+ *pui32ClientHeapCount = ui32ClientHeapCount; -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function AllocDeviceMem -+ -+ @Description -+ -+ Allocates device memory -+ -+ @Input hDevCookie : -+ -+ @Input hDevMemHeap -+ -+ @Input ui32Flags : Some combination of PVRSRV_MEM_ flags -+ -+ @Input ui32Size : Number of bytes to allocate -+ -+ @Input ui32Alignment : Alignment of allocation -+ -+ @Input pvPrivData : Opaque private data passed through to allocator -+ -+ @Input ui32PrivDataLength : Length of opaque private data -+ -+ @Output **ppsMemInfo : On success, receives a pointer to the created MEM_INFO structure -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+static PVRSRV_ERROR AllocDeviceMem(IMG_HANDLE hDevCookie, -+ IMG_HANDLE hDevMemHeap, -+ IMG_UINT32 ui32Flags, -+ IMG_SIZE_T ui32Size, -+ IMG_SIZE_T ui32Alignment, -+ IMG_PVOID pvPrivData, -+ IMG_UINT32 ui32PrivDataLength, -+ IMG_UINT32 ui32ChunkSize, -+ IMG_UINT32 ui32NumVirtChunks, -+ IMG_UINT32 ui32NumPhysChunks, -+ IMG_BOOL *pabMapChunk, -+ PVRSRV_KERNEL_MEM_INFO **ppsMemInfo) -+{ -+ PVRSRV_KERNEL_MEM_INFO *psMemInfo; -+ BM_HANDLE hBuffer; -+ /* Pointer to implementation details within the mem_info */ -+ PVRSRV_MEMBLK *psMemBlock; -+ IMG_BOOL bBMError; -+ -+ PVR_UNREFERENCED_PARAMETER(hDevCookie); -+ -+ *ppsMemInfo = IMG_NULL; -+ -+ if(OSAllocMem(PVRSRV_PAGEABLE_SELECT, -+ sizeof(PVRSRV_KERNEL_MEM_INFO), -+ (IMG_VOID **)&psMemInfo, IMG_NULL, -+ "Kernel Memory Info") != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"AllocDeviceMem: Failed to alloc memory for block")); -+ return (PVRSRV_ERROR_OUT_OF_MEMORY); -+ } -+ -+ OSMemSet(psMemInfo, 0, sizeof(*psMemInfo)); -+ -+ psMemBlock = &(psMemInfo->sMemBlk); -+ -+ /* BM supplied Device Virtual Address with physical backing RAM */ -+ psMemInfo->ui32Flags = ui32Flags | PVRSRV_MEM_RAM_BACKED_ALLOCATION; -+ -+ bBMError = BM_Alloc (hDevMemHeap, -+ IMG_NULL, -+ ui32Size, -+ &psMemInfo->ui32Flags, -+ IMG_CAST_TO_DEVVADDR_UINT(ui32Alignment), -+ pvPrivData, -+ ui32PrivDataLength, -+ ui32ChunkSize, -+ ui32NumVirtChunks, -+ ui32NumPhysChunks, -+ pabMapChunk, -+ &hBuffer); -+ -+ if (!bBMError) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"AllocDeviceMem: BM_Alloc Failed")); -+ OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL); -+ /*not nulling pointer, out of scope*/ -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ -+ /* Fill in "Implementation dependant" section of mem info */ -+ psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer); -+ psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer); -+ -+ /* Convert from BM_HANDLE to external IMG_HANDLE */ -+ psMemBlock->hBuffer = (IMG_HANDLE)hBuffer; -+ -+ /* Fill in the public fields of the MEM_INFO structure */ -+ -+ psMemInfo->pvLinAddrKM = BM_HandleToCpuVaddr(hBuffer); -+ -+ psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr; -+ -+ if (ui32Flags & PVRSRV_MEM_SPARSE) -+ { -+ psMemInfo->uAllocSize = ui32ChunkSize * ui32NumVirtChunks; -+ } -+ else -+ { -+ psMemInfo->uAllocSize = ui32Size; -+ } -+ -+ /* Clear the Backup buffer pointer as we do not have one at this point. We only allocate this as we are going up/down */ -+ psMemInfo->pvSysBackupBuffer = IMG_NULL; -+ -+ /* -+ * Setup the output. -+ */ -+ *ppsMemInfo = psMemInfo; -+ -+ /* -+ * And I think we're done for now.... -+ */ -+ return (PVRSRV_OK); -+} -+ -+static PVRSRV_ERROR FreeDeviceMem2(PVRSRV_KERNEL_MEM_INFO *psMemInfo, PVRSRV_FREE_CALLBACK_ORIGIN eCallbackOrigin) -+{ -+ BM_HANDLE hBuffer; -+ -+ if (!psMemInfo) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ hBuffer = psMemInfo->sMemBlk.hBuffer; -+ -+ switch(eCallbackOrigin) -+ { -+ case PVRSRV_FREE_CALLBACK_ORIGIN_ALLOCATOR: -+ BM_Free(hBuffer, psMemInfo->ui32Flags); -+ break; -+ case PVRSRV_FREE_CALLBACK_ORIGIN_IMPORTER: -+ BM_FreeExport(hBuffer, psMemInfo->ui32Flags); -+ break; -+ default: -+ break; -+ } -+ -+ if (psMemInfo->pvSysBackupBuffer && -+ eCallbackOrigin == PVRSRV_FREE_CALLBACK_ORIGIN_ALLOCATOR) -+ { -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, psMemInfo->uAllocSize, psMemInfo->pvSysBackupBuffer, IMG_NULL); -+ psMemInfo->pvSysBackupBuffer = IMG_NULL; -+ } -+ -+ if (psMemInfo->ui32RefCount == 0) -+ OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL); -+ -+ return(PVRSRV_OK); -+} -+ -+static PVRSRV_ERROR FreeDeviceMem(PVRSRV_KERNEL_MEM_INFO *psMemInfo) -+{ -+ BM_HANDLE hBuffer; -+ -+ if (!psMemInfo) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ hBuffer = psMemInfo->sMemBlk.hBuffer; -+ -+ BM_Free(hBuffer, psMemInfo->ui32Flags); -+ -+ if(psMemInfo->pvSysBackupBuffer) -+ { -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, psMemInfo->uAllocSize, psMemInfo->pvSysBackupBuffer, IMG_NULL); -+ psMemInfo->pvSysBackupBuffer = IMG_NULL; -+ } -+ -+ OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL); -+ -+ return(PVRSRV_OK); -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVAllocSyncInfoKM -+ -+ @Description -+ -+ Allocates a sync info -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVAllocSyncInfoKM(IMG_HANDLE hDevCookie, -+ IMG_HANDLE hDevMemContext, -+ PVRSRV_KERNEL_SYNC_INFO **ppsKernelSyncInfo) -+{ -+ IMG_HANDLE hSyncDevMemHeap; -+ DEVICE_MEMORY_INFO *psDevMemoryInfo; -+ BM_CONTEXT *pBMContext; -+ PVRSRV_ERROR eError; -+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo; -+ PVRSRV_SYNC_DATA *psSyncData; -+ -+ eError = OSAllocMem(PVRSRV_PAGEABLE_SELECT, -+ sizeof(PVRSRV_KERNEL_SYNC_INFO), -+ (IMG_VOID **)&psKernelSyncInfo, IMG_NULL, -+ "Kernel Synchronization Info"); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVAllocSyncInfoKM: Failed to alloc memory")); -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ -+ eError = OSAtomicAlloc(&psKernelSyncInfo->pvRefCount); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVAllocSyncInfoKM: Failed to allocate atomic")); -+ OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_SYNC_INFO), psKernelSyncInfo, IMG_NULL); -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ -+ -+ /* Get the devnode from the devheap */ -+ pBMContext = (BM_CONTEXT*)hDevMemContext; -+ psDevMemoryInfo = &pBMContext->psDeviceNode->sDevMemoryInfo; -+ -+ /* and choose a heap for the syncinfo */ -+ hSyncDevMemHeap = psDevMemoryInfo->psDeviceMemoryHeap[psDevMemoryInfo->ui32SyncHeapID].hDevMemHeap; -+ -+ /* -+ Cache consistent flag would be unnecessary if the heap attributes were -+ changed to specify it. -+ */ -+ eError = AllocDeviceMem(hDevCookie, -+ hSyncDevMemHeap, -+ PVRSRV_MEM_CACHE_CONSISTENT, -+ sizeof(PVRSRV_SYNC_DATA), -+ sizeof(IMG_UINT32), -+ IMG_NULL, -+ 0, -+ 0, 0, 0, IMG_NULL, /* Sparse mapping args, not required */ -+ &psKernelSyncInfo->psSyncDataMemInfoKM); -+ -+ if (eError != PVRSRV_OK) -+ { -+ -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVAllocSyncInfoKM: Failed to alloc memory")); -+ OSAtomicFree(psKernelSyncInfo->pvRefCount); -+ OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_SYNC_INFO), psKernelSyncInfo, IMG_NULL); -+ /*not nulling pointer, out of scope*/ -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ -+ /* init sync data */ -+ psKernelSyncInfo->psSyncData = psKernelSyncInfo->psSyncDataMemInfoKM->pvLinAddrKM; -+ psSyncData = psKernelSyncInfo->psSyncData; -+ -+ psSyncData->ui32WriteOpsPending = 0; -+ psSyncData->ui32WriteOpsComplete = 0; -+ psSyncData->ui32ReadOpsPending = 0; -+ psSyncData->ui32ReadOpsComplete = 0; -+ psSyncData->ui32ReadOps2Pending = 0; -+ psSyncData->ui32ReadOps2Complete = 0; -+ psSyncData->ui32LastOpDumpVal = 0; -+ psSyncData->ui32LastReadOpDumpVal = 0; -+ psSyncData->ui64LastWrite = 0; -+ -+ /* -+ Note: -+ PDumping here means that we PDump syncs that we might not -+ need to know about for the multi-process but this -+ unavoidable as there is no point where we can PDump -+ that guarantees it will be initialised before we us it -+ (e.g. kick time is too late as the client might have -+ issued a POL on it before that point) -+ */ -+#if defined(PDUMP) -+ PDUMPCOMMENT("Allocating kernel sync object"); -+ PDUMPMEM(psKernelSyncInfo->psSyncDataMemInfoKM->pvLinAddrKM, -+ psKernelSyncInfo->psSyncDataMemInfoKM, -+ 0, -+ (IMG_UINT32)psKernelSyncInfo->psSyncDataMemInfoKM->uAllocSize, -+#if defined(SUPPORT_PDUMP_MULTI_PROCESS) -+ PDUMP_FLAGS_PERSISTENT, -+#else -+ PDUMP_FLAGS_CONTINUOUS, -+#endif -+ MAKEUNIQUETAG(psKernelSyncInfo->psSyncDataMemInfoKM)); -+#endif -+ -+ psKernelSyncInfo->sWriteOpsCompleteDevVAddr.uiAddr = psKernelSyncInfo->psSyncDataMemInfoKM->sDevVAddr.uiAddr + offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete); -+ psKernelSyncInfo->sReadOpsCompleteDevVAddr.uiAddr = psKernelSyncInfo->psSyncDataMemInfoKM->sDevVAddr.uiAddr + offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete); -+ psKernelSyncInfo->sReadOps2CompleteDevVAddr.uiAddr = psKernelSyncInfo->psSyncDataMemInfoKM->sDevVAddr.uiAddr + offsetof(PVRSRV_SYNC_DATA, ui32ReadOps2Complete); -+ psKernelSyncInfo->ui32UID = g_ui32SyncUID++; -+ -+ /* syncinfo meminfo has no syncinfo! */ -+ psKernelSyncInfo->psSyncDataMemInfoKM->psKernelSyncInfo = IMG_NULL; -+ -+ OSAtomicInc(psKernelSyncInfo->pvRefCount); -+ -+ /* return result */ -+ *ppsKernelSyncInfo = psKernelSyncInfo; -+ -+ return PVRSRV_OK; -+} -+ -+IMG_EXPORT -+IMG_VOID PVRSRVAcquireSyncInfoKM(PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo) -+{ -+ OSAtomicInc(psKernelSyncInfo->pvRefCount); -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVFreeSyncInfoKM -+ -+ @Description -+ -+ Frees a sync info -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+IMG_EXPORT -+IMG_VOID IMG_CALLCONV PVRSRVReleaseSyncInfoKM(PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo) -+{ -+ if (OSAtomicDecAndTest(psKernelSyncInfo->pvRefCount)) -+ { -+ FreeDeviceMem(psKernelSyncInfo->psSyncDataMemInfoKM); -+ -+ /* Catch anyone who is trying to access the freed structure */ -+ psKernelSyncInfo->psSyncDataMemInfoKM = IMG_NULL; -+ psKernelSyncInfo->psSyncData = IMG_NULL; -+ OSAtomicFree(psKernelSyncInfo->pvRefCount); -+ (IMG_VOID)OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_SYNC_INFO), psKernelSyncInfo, IMG_NULL); -+ /*not nulling pointer, copy on stack*/ -+ } -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function freeExternal -+ -+ @Description -+ -+ Code for freeing meminfo elements that are specific to external types memory -+ -+ @Input psMemInfo : Kernel meminfo -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+ -+static IMG_VOID freeExternal(PVRSRV_KERNEL_MEM_INFO *psMemInfo) -+{ -+ IMG_HANDLE hOSWrapMem = psMemInfo->sMemBlk.hOSWrapMem; -+ -+ /* free the page addr array if req'd */ -+ if(psMemInfo->sMemBlk.psIntSysPAddr) -+ { -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(IMG_SYS_PHYADDR), psMemInfo->sMemBlk.psIntSysPAddr, IMG_NULL); -+ psMemInfo->sMemBlk.psIntSysPAddr = IMG_NULL; -+ } -+ -+ /* Mem type dependent stuff */ -+ if (psMemInfo->memType == PVRSRV_MEMTYPE_WRAPPED) -+ { -+ if(hOSWrapMem) -+ { -+ OSReleasePhysPageAddr(hOSWrapMem); -+ } -+ } -+#if defined(SUPPORT_ION) -+ else if (psMemInfo->memType == PVRSRV_MEMTYPE_ION) -+ { -+ if (hOSWrapMem) -+ { -+ IonUnimportBufferAndReleasePhysAddr(hOSWrapMem); -+ } -+ } -+#endif -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function FreeMemCallBackCommon -+ -+ @Description -+ -+ Common code for freeing device mem (called for freeing, unwrapping and unmapping) -+ -+ @Input psMemInfo : Kernel meminfo -+ @Input ui32Param : packet size -+ @Input uibFromAllocatorParam : Are we being called by the original allocator? -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR FreeMemCallBackCommon(PVRSRV_KERNEL_MEM_INFO *psMemInfo, -+ IMG_UINT32 ui32Param, -+ PVRSRV_FREE_CALLBACK_ORIGIN eCallbackOrigin) -+{ -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ -+ PVR_UNREFERENCED_PARAMETER(ui32Param); -+ -+ /* decrement the refcount */ -+ PVRSRVKernelMemInfoDecRef(psMemInfo); -+ -+ /* check no other processes has this meminfo mapped */ -+ if (psMemInfo->ui32RefCount == 0) -+ { -+ if((psMemInfo->ui32Flags & PVRSRV_MEM_EXPORTED) != 0) -+ { -+ IMG_HANDLE hMemInfo = IMG_NULL; -+ -+ /* find the handle */ -+ eError = PVRSRVFindHandle(KERNEL_HANDLE_BASE, -+ &hMemInfo, -+ psMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if(eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "FreeMemCallBackCommon: can't find exported meminfo in the global handle list")); -+ return eError; -+ } -+ -+ /* release the handle */ -+ eError = PVRSRVReleaseHandle(KERNEL_HANDLE_BASE, -+ hMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if(eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "FreeMemCallBackCommon: PVRSRVReleaseHandle failed for exported meminfo")); -+ return eError; -+ } -+ } -+ -+ switch(psMemInfo->memType) -+ { -+ /* Fall through: Free only what we should for each memory type */ -+ case PVRSRV_MEMTYPE_WRAPPED: -+ case PVRSRV_MEMTYPE_ION: -+ freeExternal(psMemInfo); -+ case PVRSRV_MEMTYPE_DEVICE: -+ case PVRSRV_MEMTYPE_DEVICECLASS: -+#if defined(SUPPORT_ION) -+ if (psMemInfo->hIonSyncInfo) -+ { -+ /* -+ For syncs attached to Ion imported buffers we handle -+ things a little differently -+ */ -+ PVRSRVIonBufferSyncInfoDecRef(psMemInfo->hIonSyncInfo, psMemInfo); -+ } -+ else -+#endif -+ { -+ if (psMemInfo->psKernelSyncInfo) -+ { -+ PVRSRVKernelSyncInfoDecRef(psMemInfo->psKernelSyncInfo, psMemInfo); -+ } -+ } -+ break; -+ default: -+ PVR_DPF((PVR_DBG_ERROR, "FreeMemCallBackCommon: Unknown memType")); -+ eError = PVRSRV_ERROR_INVALID_MEMINFO; -+ } -+ } -+ -+ /* -+ * FreeDeviceMem2 will do the right thing, freeing -+ * the virtual memory info when the allocator calls -+ * but only releaseing the physical pages when everyone -+ * is done. -+ */ -+ -+ if (eError == PVRSRV_OK) -+ { -+ eError = FreeDeviceMem2(psMemInfo, eCallbackOrigin); -+ } -+ -+ return eError; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function FreeDeviceMemCallBack -+ -+ @Description -+ -+ ResMan call back to free device memory -+ -+ @Input pvParam : data packet -+ @Input ui32Param : packet size -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+static PVRSRV_ERROR FreeDeviceMemCallBack(IMG_PVOID pvParam, -+ IMG_UINT32 ui32Param, -+ IMG_BOOL bDummy) -+{ -+ PVRSRV_KERNEL_MEM_INFO *psMemInfo = (PVRSRV_KERNEL_MEM_INFO *)pvParam; -+ -+ PVR_UNREFERENCED_PARAMETER(bDummy); -+ -+ return FreeMemCallBackCommon(psMemInfo, ui32Param, -+ PVRSRV_FREE_CALLBACK_ORIGIN_ALLOCATOR); -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVFreeDeviceMemKM -+ -+ @Description -+ -+ Frees memory allocated with PVRAllocDeviceMem, including the mem_info structure -+ -+ @Input psMemInfo : -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeDeviceMemKM(IMG_HANDLE hDevCookie, -+ PVRSRV_KERNEL_MEM_INFO *psMemInfo) -+{ -+ PVRSRV_ERROR eError; -+ -+ PVR_UNREFERENCED_PARAMETER(hDevCookie); -+ -+ if (!psMemInfo) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ if (psMemInfo->sMemBlk.hResItem != IMG_NULL) -+ { -+ eError = ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem, CLEANUP_WITH_POLL); -+ } -+ else -+ { -+ /* PVRSRV_MEM_NO_RESMAN */ -+ eError = FreeDeviceMemCallBack(psMemInfo, 0, CLEANUP_WITH_POLL); -+ } -+ -+ return eError; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVAllocDeviceMemKM -+ -+ @Description -+ -+ Allocates device memory -+ -+ @Input hDevCookie : -+ @Input psPerProc : Per-process data -+ @Input hDevMemHeap -+ @Input ui32Flags : Some combination of PVRSRV_MEM_ flags -+ @Input ui32Size : Number of bytes to allocate -+ @Input ui32Alignment : -+ @Output **ppsMemInfo : On success, receives a pointer to the created MEM_INFO structure -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR IMG_CALLCONV _PVRSRVAllocDeviceMemKM(IMG_HANDLE hDevCookie, -+ PVRSRV_PER_PROCESS_DATA *psPerProc, -+ IMG_HANDLE hDevMemHeap, -+ IMG_UINT32 ui32Flags, -+ IMG_SIZE_T ui32Size, -+ IMG_SIZE_T ui32Alignment, -+ IMG_PVOID pvPrivData, -+ IMG_UINT32 ui32PrivDataLength, -+ IMG_UINT32 ui32ChunkSize, -+ IMG_UINT32 ui32NumVirtChunks, -+ IMG_UINT32 ui32NumPhysChunks, -+ IMG_BOOL *pabMapChunk, -+ PVRSRV_KERNEL_MEM_INFO **ppsMemInfo) -+{ -+ PVRSRV_KERNEL_MEM_INFO *psMemInfo; -+ PVRSRV_ERROR eError; -+ BM_HEAP *psBMHeap; -+ IMG_HANDLE hDevMemContext; -+ -+ if (!hDevMemHeap || -+ ((ui32Size == 0) && ((ui32Flags & PVRSRV_MEM_SPARSE) == 0)) || -+ (((ui32ChunkSize == 0) || (ui32NumVirtChunks == 0) || (ui32NumPhysChunks == 0) || -+ (pabMapChunk == IMG_NULL )) && (ui32Flags & PVRSRV_MEM_SPARSE))) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ /* Sprase alloc input validation */ -+ if (ui32Flags & PVRSRV_MEM_SPARSE) -+ { -+ IMG_UINT32 i; -+ IMG_UINT32 ui32Check = 0; -+ -+ if (ui32NumVirtChunks < ui32NumPhysChunks) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ for (i=0;i<ui32NumVirtChunks;i++) -+ { -+ if (pabMapChunk[i]) -+ { -+ ui32Check++; -+ } -+ } -+ if (ui32NumPhysChunks != ui32Check) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ } -+ -+ /* FIXME: At the moment we force CACHETYPE override allocations to -+ * be multiples of PAGE_SIZE and page aligned. If the RA/BM -+ * is fixed, this limitation can be removed. -+ * -+ * INTEGRATION_POINT: HOST_PAGESIZE() is not correct, should be device-specific. -+ */ -+ if (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK) -+ { -+ /* PRQA S 3415 1 */ /* order of evaluation is not important */ -+ if (((ui32Size % HOST_PAGESIZE()) != 0) || -+ ((ui32Alignment % HOST_PAGESIZE()) != 0)) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ } -+ -+ eError = AllocDeviceMem(hDevCookie, -+ hDevMemHeap, -+ ui32Flags, -+ ui32Size, -+ ui32Alignment, -+ pvPrivData, -+ ui32PrivDataLength, -+ ui32ChunkSize, -+ ui32NumVirtChunks, -+ ui32NumPhysChunks, -+ pabMapChunk, -+ &psMemInfo); -+ -+ if (eError != PVRSRV_OK) -+ { -+ return eError; -+ } -+ -+ if (ui32Flags & PVRSRV_MEM_NO_SYNCOBJ) -+ { -+ psMemInfo->psKernelSyncInfo = IMG_NULL; -+ } -+ else -+ { -+ /* -+ allocate a syncinfo but don't register with resman -+ because the holding devicemem will handle the syncinfo -+ */ -+ psBMHeap = (BM_HEAP*)hDevMemHeap; -+ hDevMemContext = (IMG_HANDLE)psBMHeap->pBMContext; -+ eError = PVRSRVAllocSyncInfoKM(hDevCookie, -+ hDevMemContext, -+ &psMemInfo->psKernelSyncInfo); -+ if(eError != PVRSRV_OK) -+ { -+ goto free_mainalloc; -+ } -+ } -+ -+ /* -+ * Setup the output. -+ */ -+ *ppsMemInfo = psMemInfo; -+ -+ if (ui32Flags & PVRSRV_MEM_NO_RESMAN) -+ { -+ psMemInfo->sMemBlk.hResItem = IMG_NULL; -+ } -+ else -+ { -+ /* register with the resman */ -+ psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext, -+ RESMAN_TYPE_DEVICEMEM_ALLOCATION, -+ psMemInfo, -+ 0, -+ &FreeDeviceMemCallBack); -+ if (psMemInfo->sMemBlk.hResItem == IMG_NULL) -+ { -+ eError = PVRSRV_ERROR_OUT_OF_MEMORY; -+ goto free_mainalloc; -+ } -+ } -+ -+ /* increment the refcount */ -+ PVRSRVKernelMemInfoIncRef(psMemInfo); -+ -+ psMemInfo->memType = PVRSRV_MEMTYPE_DEVICE; -+ -+ /* -+ * And I think we're done for now.... -+ */ -+ return (PVRSRV_OK); -+ -+free_mainalloc: -+ if (psMemInfo->psKernelSyncInfo) -+ { -+ PVRSRVKernelSyncInfoDecRef(psMemInfo->psKernelSyncInfo, psMemInfo); -+ } -+ FreeDeviceMem(psMemInfo); -+ -+ return eError; -+} -+ -+#if defined(SUPPORT_ION) -+static PVRSRV_ERROR IonUnmapCallback(IMG_PVOID pvParam, -+ IMG_UINT32 ui32Param, -+ IMG_BOOL bDummy) -+{ -+ PVRSRV_KERNEL_MEM_INFO *psMemInfo = (PVRSRV_KERNEL_MEM_INFO *)pvParam; -+ -+ PVR_UNREFERENCED_PARAMETER(bDummy); -+ -+ return FreeMemCallBackCommon(psMemInfo, ui32Param, PVRSRV_FREE_CALLBACK_ORIGIN_ALLOCATOR); -+} -+ -+PVRSRV_ERROR PVRSRVIonBufferSyncAcquire(IMG_HANDLE hUnique, -+ IMG_HANDLE hDevCookie, -+ IMG_HANDLE hDevMemContext, -+ PVRSRV_ION_SYNC_INFO **ppsIonSyncInfo) -+{ -+ PVRSRV_ION_SYNC_INFO *psIonSyncInfo; -+ PVRSRV_ERROR eError; -+ IMG_BOOL bRet; -+ -+ /* Check the hash to see if we already have a sync for this buffer */ -+ psIonSyncInfo = (PVRSRV_ION_SYNC_INFO *) HASH_Retrieve(g_psIonSyncHash, (IMG_UINTPTR_T) hUnique); -+ if (psIonSyncInfo == 0) -+ { -+ /* This buffer is new to us, create the syncinfo for it */ -+ eError = OSAllocMem(PVRSRV_PAGEABLE_SELECT, -+ sizeof(PVRSRV_ION_SYNC_INFO), -+ (IMG_VOID **)&psIonSyncInfo, IMG_NULL, -+ "Ion Synchronization Info"); -+ if (eError != PVRSRV_OK) -+ { -+ return eError; -+ } -+ -+ eError = PVRSRVAllocSyncInfoKM(hDevCookie, -+ hDevMemContext, -+ &psIonSyncInfo->psSyncInfo); -+ if (eError != PVRSRV_OK) -+ { -+ OSFreeMem(PVRSRV_PAGEABLE_SELECT, -+ sizeof(PVRSRV_ION_SYNC_INFO), -+ psIonSyncInfo, -+ IMG_NULL); -+ -+ return eError; -+ } -+#if defined(SUPPORT_MEMINFO_IDS) -+ psIonSyncInfo->ui64Stamp = ++g_ui64MemInfoID; -+#else -+ psIonSyncInfo->ui64Stamp = 0; -+#endif -+ bRet = HASH_Insert(g_psIonSyncHash, (IMG_UINTPTR_T) hUnique, (IMG_UINTPTR_T) psIonSyncInfo); -+ if (!bRet) -+ { -+ eError = PVRSRV_ERROR_OUT_OF_MEMORY; -+ -+ PVRSRVKernelSyncInfoDecRef(psIonSyncInfo->psSyncInfo, IMG_NULL); -+ OSFreeMem(PVRSRV_PAGEABLE_SELECT, -+ sizeof(PVRSRV_ION_SYNC_INFO), -+ psIonSyncInfo, -+ IMG_NULL); -+ -+ return eError; -+ } -+ -+ psIonSyncInfo->ui32RefCount = 0; -+ psIonSyncInfo->hUnique = hUnique; -+ } -+ -+ psIonSyncInfo->ui32RefCount++; -+ *ppsIonSyncInfo = psIonSyncInfo; -+ return PVRSRV_OK; -+} -+ -+IMG_VOID PVRSRVIonBufferSyncRelease(PVRSRV_ION_SYNC_INFO *psIonSyncInfo) -+{ -+ psIonSyncInfo->ui32RefCount--; -+ -+ if (psIonSyncInfo->ui32RefCount == 0) -+ { -+ PVRSRV_ION_SYNC_INFO *psLookup; -+ /* -+ If we're holding the last reference to the syncinfo -+ then free it -+ */ -+ psLookup = (PVRSRV_ION_SYNC_INFO *) HASH_Remove(g_psIonSyncHash, (IMG_UINTPTR_T) psIonSyncInfo->hUnique); -+ PVR_ASSERT(psLookup == psIonSyncInfo); -+ PVRSRVKernelSyncInfoDecRef(psIonSyncInfo->psSyncInfo, IMG_NULL); -+ OSFreeMem(PVRSRV_PAGEABLE_SELECT, -+ sizeof(PVRSRV_ION_SYNC_INFO), -+ psIonSyncInfo, -+ IMG_NULL); -+ } -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVMapIonHandleKM -+ -+ @Description -+ -+ Map an ION buffer into the specified device memory context -+ -+ @Input psPerProc : PerProcess data -+ @Input hDevCookie : Device node cookie -+ @Input hDevMemHeap : Heap ion handles are mapped into -+ @Input ui32NumBuffers : Number of ion handles to map. (If one handle is being -+ mapped, this should be 1, not 0.) -+ @Input phIon : Array of ui32NumBuffers ion handles (fds) -+ @Input ui32Flags : Mapping flags -+ @Input ui32ChunkCount : If ui32NumBuffers is 1, this is the number of -+ "chunks" specified to be mapped into device-virtual -+ address space. If ui32NumBuffers > 1, it is ignored. -+ @Input pauiOffset : Array of offsets in device-virtual address space to map -+ "chunks" of physical from the ion allocation. -+ @Input pauiSize : Array of sizes in bytes of device-virtual address space to -+ map "chunks" of physical from the ion allocation. -+ @Input puiIonBufferSize : Size in bytes of resulting device-virtual mapping. -+ @Output ppsKernelMemInfo: Output kernel meminfo if successful -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR PVRSRVMapIonHandleKM(PVRSRV_PER_PROCESS_DATA *psPerProc, -+ IMG_HANDLE hDevCookie, -+ IMG_HANDLE hDevMemHeap, -+ IMG_UINT32 ui32NumFDs, -+ IMG_INT32 *pi32BufferFDs, -+ IMG_UINT32 ui32Flags, -+ IMG_UINT32 ui32ChunkCount, -+ IMG_SIZE_T *pauiOffset, -+ IMG_SIZE_T *pauiSize, -+ IMG_SIZE_T *puiIonBufferSize, -+ PVRSRV_KERNEL_MEM_INFO **ppsKernelMemInfo, -+ IMG_UINT64 *pui64Stamp) -+{ -+ PVRSRV_ENV_PER_PROCESS_DATA *psPerProcEnv = PVRSRVProcessPrivateData(psPerProc); -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+ PVRSRV_KERNEL_MEM_INFO *psNewKernelMemInfo; -+ IMG_SYS_PHYADDR *pasSysPhysAddr; -+ IMG_SYS_PHYADDR *pasAdjustedSysPhysAddr; -+ PVRSRV_MEMBLK *psMemBlock; -+ PVRSRV_ERROR eError; -+ IMG_HANDLE hPriv; -+ IMG_HANDLE hUnique; -+ BM_HANDLE hBuffer; -+ IMG_SIZE_T uiMapSize = 0; -+ IMG_SIZE_T uiAdjustOffset = 0; -+ IMG_UINT32 ui32PageCount; -+ IMG_UINT32 i; -+ IMG_BOOL bAllocSync = (ui32Flags & PVRSRV_MEM_NO_SYNCOBJ)?IMG_FALSE:IMG_TRUE; -+ -+ if ((hDevCookie == IMG_NULL) || (ui32ChunkCount == 0) -+ || (hDevMemHeap == IMG_NULL) || (ppsKernelMemInfo == IMG_NULL)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: Invalid params", __FUNCTION__)); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ for (i=0;i<ui32ChunkCount;i++) -+ { -+ if ((pauiOffset[i] & HOST_PAGEMASK) != 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"%s: Chunk offset is not page aligned", __FUNCTION__)); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ if ((pauiSize[i] & HOST_PAGEMASK) != 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"%s: Chunk size is not page aligned", __FUNCTION__)); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ uiMapSize += pauiSize[i]; -+ } -+ -+ psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie; -+ -+ if(OSAllocMem(PVRSRV_PAGEABLE_SELECT, -+ sizeof(PVRSRV_KERNEL_MEM_INFO), -+ (IMG_VOID **)&psNewKernelMemInfo, IMG_NULL, -+ "Kernel Memory Info") != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"%s: Failed to alloc memory for block", __FUNCTION__)); -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ OSMemSet(psNewKernelMemInfo, 0, sizeof(PVRSRV_KERNEL_MEM_INFO)); -+ -+ /* Import the ION buffer into our ion_client and DMA map it */ -+ eError = IonImportBufferAndAcquirePhysAddr(psPerProcEnv->psIONClient, -+ ui32NumFDs, -+ pi32BufferFDs, -+ &ui32PageCount, -+ &pasSysPhysAddr, -+ &psNewKernelMemInfo->pvLinAddrKM, -+ &hPriv, -+ &hUnique); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: Failed to get ion buffer/buffer phys addr", __FUNCTION__)); -+ goto exitFailedImport; -+ } -+ -+ /* -+ Make sure the number of pages detected by the ion import are at least -+ the size of the total chunked region -+ */ -+ if(ui32PageCount * PAGE_SIZE < uiMapSize) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: ion allocator returned fewer page addresses " -+ "than specified chunk size(s)", __FUNCTION__)); -+ eError = PVRSRV_ERROR_INVALID_PARAMS; -+ goto exitFailedAdjustedAlloc; -+ } -+ -+ /* -+ An Ion buffer might have a number of "chunks" in it which need to be -+ mapped virtually continuous so we need to create a new array of -+ addresses based on this chunk data for the actual wrap -+ */ -+ if(OSAllocMem(PVRSRV_PAGEABLE_SELECT, -+ sizeof(IMG_SYS_PHYADDR) * (uiMapSize/HOST_PAGESIZE()), -+ (IMG_VOID **)&pasAdjustedSysPhysAddr, IMG_NULL, -+ "Ion adjusted system address array") != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"%s: Failed to alloc memory for adjusted array", __FUNCTION__)); -+ goto exitFailedAdjustedAlloc; -+ } -+ OSMemSet(pasAdjustedSysPhysAddr, 0, sizeof(IMG_SYS_PHYADDR) * (uiMapSize/HOST_PAGESIZE())); -+ -+ for (i=0;i<ui32ChunkCount;i++) -+ { -+ OSMemCopy(&pasAdjustedSysPhysAddr[uiAdjustOffset], -+ &pasSysPhysAddr[pauiOffset[i]/HOST_PAGESIZE()], -+ (pauiSize[i]/HOST_PAGESIZE()) * sizeof(IMG_SYS_PHYADDR)); -+ -+ uiAdjustOffset += pauiSize[i]/HOST_PAGESIZE(); -+ } -+ -+ /* Wrap the returned addresses into our memory context */ -+ if (!BM_Wrap(hDevMemHeap, -+ uiMapSize, -+ 0, -+ IMG_FALSE, -+ pasAdjustedSysPhysAddr, -+ IMG_NULL, -+ &ui32Flags, /* This function clobbers our bits in ui32Flags */ -+ &hBuffer)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: Failed to wrap ion buffer", __FUNCTION__)); -+ eError = PVRSRV_ERROR_OUT_OF_MEMORY; -+ goto exitFailedWrap; -+ } -+ -+ /* Fill in "Implementation dependant" section of mem info */ -+ psMemBlock = &psNewKernelMemInfo->sMemBlk; -+ psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer); -+ psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer); -+ psMemBlock->hBuffer = (IMG_HANDLE) hBuffer; -+ psMemBlock->hOSWrapMem = hPriv; /* Saves creating a new element as we know hOSWrapMem will not be used */ -+ psMemBlock->psIntSysPAddr = pasAdjustedSysPhysAddr; -+ -+ psNewKernelMemInfo->ui32Flags = ui32Flags; -+ psNewKernelMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr; -+ psNewKernelMemInfo->uAllocSize = uiMapSize; -+ psNewKernelMemInfo->memType = PVRSRV_MEMTYPE_ION; -+ PVRSRVKernelMemInfoIncRef(psNewKernelMemInfo); -+ -+ /* Clear the Backup buffer pointer as we do not have one at this point. We only allocate this as we are going up/down */ -+ psNewKernelMemInfo->pvSysBackupBuffer = IMG_NULL; -+ -+ if (!bAllocSync) -+ { -+ psNewKernelMemInfo->psKernelSyncInfo = IMG_NULL; -+ } -+ else -+ { -+ PVRSRV_ION_SYNC_INFO *psIonSyncInfo; -+ BM_HEAP *psBMHeap; -+ IMG_HANDLE hDevMemContext; -+ -+ psBMHeap = (BM_HEAP*)hDevMemHeap; -+ hDevMemContext = (IMG_HANDLE)psBMHeap->pBMContext; -+ -+ eError = PVRSRVIonBufferSyncInfoIncRef(hUnique, -+ hDevCookie, -+ hDevMemContext, -+ &psIonSyncInfo, -+ psNewKernelMemInfo); -+ if(eError != PVRSRV_OK) -+ { -+ goto exitFailedSync; -+ } -+ psNewKernelMemInfo->hIonSyncInfo = psIonSyncInfo; -+ psNewKernelMemInfo->psKernelSyncInfo = IonBufferSyncGetKernelSyncInfo(psIonSyncInfo); -+ *pui64Stamp = IonBufferSyncGetStamp(psIonSyncInfo); -+ } -+ -+ /* register with the resman */ -+ psNewKernelMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext, -+ RESMAN_TYPE_DEVICEMEM_ION, -+ psNewKernelMemInfo, -+ 0, -+ &IonUnmapCallback); -+ if (psNewKernelMemInfo->sMemBlk.hResItem == IMG_NULL) -+ { -+ eError = PVRSRV_ERROR_OUT_OF_MEMORY; -+ goto exitFailedResman; -+ } -+ -+ psNewKernelMemInfo->memType = PVRSRV_MEMTYPE_ION; -+ -+ /* -+ As the user doesn't tell us the size, just the "chunk" information -+ return actual size of the Ion buffer so we can mmap it. -+ */ -+ *puiIonBufferSize = ui32PageCount * HOST_PAGESIZE(); -+ *ppsKernelMemInfo = psNewKernelMemInfo; -+ return PVRSRV_OK; -+ -+exitFailedResman: -+ if (psNewKernelMemInfo->psKernelSyncInfo) -+ { -+ PVRSRVIonBufferSyncInfoDecRef(psNewKernelMemInfo->hIonSyncInfo, psNewKernelMemInfo); -+ } -+exitFailedSync: -+ BM_Free(hBuffer, ui32Flags); -+exitFailedWrap: -+ OSFreeMem(PVRSRV_PAGEABLE_SELECT, -+ sizeof(IMG_SYS_PHYADDR) * uiAdjustOffset, -+ pasAdjustedSysPhysAddr, -+ IMG_NULL); -+exitFailedAdjustedAlloc: -+ IonUnimportBufferAndReleasePhysAddr(hPriv); -+exitFailedImport: -+ OSFreeMem(PVRSRV_PAGEABLE_SELECT, -+ sizeof(PVRSRV_KERNEL_MEM_INFO), -+ psNewKernelMemInfo, -+ IMG_NULL); -+ -+ return eError; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVUnmapIonHandleKM -+ -+ @Description -+ -+ Frees an ion buffer mapped with PVRSRVMapIonHandleKM, including the mem_info structure -+ -+ @Input psMemInfo : -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapIonHandleKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo) -+{ -+ if (!psMemInfo) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ return ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem, CLEANUP_WITH_POLL); -+} -+#endif /* SUPPORT_ION */ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVDissociateDeviceMemKM -+ -+ @Description -+ -+ Dissociates memory from the process that allocates it. Intended for -+ transfering the ownership of device memory from a particular process -+ to the kernel. -+ -+ @Input psMemInfo : -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVDissociateDeviceMemKM(IMG_HANDLE hDevCookie, -+ PVRSRV_KERNEL_MEM_INFO *psMemInfo) -+{ -+ PVRSRV_ERROR eError; -+ PVRSRV_DEVICE_NODE *psDeviceNode = hDevCookie; -+ -+ PVR_UNREFERENCED_PARAMETER(hDevCookie); -+ -+ if (!psMemInfo) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ eError = ResManDissociateRes(psMemInfo->sMemBlk.hResItem, psDeviceNode->hResManContext); -+ -+ PVR_ASSERT(eError == PVRSRV_OK); -+ -+ return eError; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVGetFreeDeviceMemKM -+ -+ @Description -+ -+ Determines how much memory remains available in the system with the specified -+ capabilities. -+ -+ @Input ui32Flags : -+ -+ @Output pui32Total : -+ -+ @Output pui32Free : -+ -+ @Output pui32LargestBlock : -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetFreeDeviceMemKM(IMG_UINT32 ui32Flags, -+ IMG_SIZE_T *pui32Total, -+ IMG_SIZE_T *pui32Free, -+ IMG_SIZE_T *pui32LargestBlock) -+{ -+ /* TO BE IMPLEMENTED */ -+ -+ PVR_UNREFERENCED_PARAMETER(ui32Flags); -+ PVR_UNREFERENCED_PARAMETER(pui32Total); -+ PVR_UNREFERENCED_PARAMETER(pui32Free); -+ PVR_UNREFERENCED_PARAMETER(pui32LargestBlock); -+ -+ return PVRSRV_OK; -+} -+ -+ -+ -+ -+/*! -+****************************************************************************** -+ @Function PVRSRVUnwrapExtMemoryKM -+ -+ @Description On last unwrap of a given meminfo, unmaps physical pages from a -+ wrapped allocation, and frees the associated device address space. -+ Note: this can only unmap memory mapped by PVRSRVWrapExtMemory -+ -+ @Input psMemInfo - mem info describing the wrapped allocation -+ @Return None -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVUnwrapExtMemoryKM (PVRSRV_KERNEL_MEM_INFO *psMemInfo) -+{ -+ if (!psMemInfo) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ return ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem, CLEANUP_WITH_POLL); -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function UnwrapExtMemoryCallBack -+ -+ @Description Resman callback to unwrap memory -+ -+ @Input pvParam - opaque void ptr param -+ @Input ui32Param - opaque unsigned long param -+ @Return PVRSRV_ERROR -+******************************************************************************/ -+static PVRSRV_ERROR UnwrapExtMemoryCallBack(IMG_PVOID pvParam, -+ IMG_UINT32 ui32Param, -+ IMG_BOOL bDummy) -+{ -+ PVRSRV_KERNEL_MEM_INFO *psMemInfo = (PVRSRV_KERNEL_MEM_INFO *)pvParam; -+ -+ PVR_UNREFERENCED_PARAMETER(bDummy); -+ -+ return FreeMemCallBackCommon(psMemInfo, ui32Param, -+ PVRSRV_FREE_CALLBACK_ORIGIN_ALLOCATOR); -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function PVRSRVWrapExtMemoryKM -+ -+ @Description Allocates a Device Virtual Address in the shared mapping heap -+ and maps physical pages into that allocation. Note, if the pages are -+ already mapped into the heap, the existing allocation is returned. -+ -+ @Input hDevCookie - Device cookie -+ @Input psPerProc - Per-process data -+ @Input hDevMemContext - device memory context -+ @Input uByteSize - Size of allocation -+ @Input uPageOffset - Offset into the first page of the memory to be wrapped -+ @Input bPhysContig - whether the underlying memory is physically contiguous -+ @Input psExtSysPAddr - The list of Device Physical page addresses -+ @Input pvLinAddr - ptr to buffer to wrap -+ @Output ppsMemInfo - mem info describing the wrapped allocation -+ @Return None -+******************************************************************************/ -+ -+IMG_EXPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVWrapExtMemoryKM(IMG_HANDLE hDevCookie, -+ PVRSRV_PER_PROCESS_DATA *psPerProc, -+ IMG_HANDLE hDevMemContext, -+ IMG_SIZE_T uByteSize, -+ IMG_SIZE_T uPageOffset, -+ IMG_BOOL bPhysContig, -+ IMG_SYS_PHYADDR *psExtSysPAddr, -+ IMG_VOID *pvLinAddr, -+ IMG_UINT32 ui32Flags, -+ PVRSRV_KERNEL_MEM_INFO **ppsMemInfo) -+{ -+ PVRSRV_KERNEL_MEM_INFO *psMemInfo = IMG_NULL; -+ DEVICE_MEMORY_INFO *psDevMemoryInfo; -+ IMG_SIZE_T ui32HostPageSize = HOST_PAGESIZE(); -+ IMG_HANDLE hDevMemHeap = IMG_NULL; -+ PVRSRV_DEVICE_NODE* psDeviceNode; -+ BM_HANDLE hBuffer; -+ PVRSRV_MEMBLK *psMemBlock; -+ IMG_BOOL bBMError; -+ BM_HEAP *psBMHeap; -+ PVRSRV_ERROR eError; -+ IMG_VOID *pvPageAlignedCPUVAddr; -+ IMG_SYS_PHYADDR *psIntSysPAddr = IMG_NULL; -+ IMG_HANDLE hOSWrapMem = IMG_NULL; -+ DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; -+ IMG_UINT32 i; -+ IMG_SIZE_T uPageCount = 0; -+ -+ PVR_DPF ((PVR_DBG_MESSAGE, -+ "PVRSRVWrapExtMemoryKM (uSize=0x%" SIZE_T_FMT_LEN "x, uPageOffset=0x%" -+ SIZE_T_FMT_LEN "x, bPhysContig=%d, extSysPAddr=" SYSPADDR_FMT -+ ", pvLinAddr=%p, ui32Flags=%u)", -+ uByteSize, -+ uPageOffset, -+ bPhysContig, -+ psExtSysPAddr?psExtSysPAddr->uiAddr:0x0, -+ pvLinAddr, -+ ui32Flags)); -+ -+ psDeviceNode = (PVRSRV_DEVICE_NODE*)hDevCookie; -+ PVR_ASSERT(psDeviceNode != IMG_NULL); -+ -+ if (psDeviceNode == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVWrapExtMemoryKM: invalid parameter")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ if(pvLinAddr) -+ { -+ /* derive the page offset from the cpu ptr (in case it's not supplied) */ -+ uPageOffset = (IMG_UINTPTR_T)pvLinAddr & (ui32HostPageSize - 1); -+ -+ /* get the pagecount and the page aligned base ptr */ -+ uPageCount = HOST_PAGEALIGN(uByteSize + uPageOffset) / ui32HostPageSize; -+ pvPageAlignedCPUVAddr = (IMG_VOID *)((IMG_UINTPTR_T)pvLinAddr - uPageOffset); -+ -+ /* allocate array of SysPAddr to hold page addresses */ -+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ uPageCount * sizeof(IMG_SYS_PHYADDR), -+ (IMG_VOID **)&psIntSysPAddr, IMG_NULL, -+ "Array of Page Addresses") != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: Failed to alloc memory for block")); -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ -+ eError = OSAcquirePhysPageAddr(pvPageAlignedCPUVAddr, -+ uPageCount * ui32HostPageSize, -+ psIntSysPAddr, -+ &hOSWrapMem); -+ if(eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: Failed to alloc memory for block")); -+ eError = PVRSRV_ERROR_OUT_OF_MEMORY;//FIXME: need better error code -+ goto ErrorExitPhase1; -+ } -+ -+ /* replace the supplied page address list */ -+ psExtSysPAddr = psIntSysPAddr; -+ -+ /* assume memory is not physically contiguous; -+ we shouldn't trust what the user says here -+ */ -+ bPhysContig = IMG_FALSE; -+ } -+ else -+ { -+ if (psExtSysPAddr) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVWrapExtMemoryKM: invalid parameter, physical address passing is not supported")); -+ } -+ else -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVWrapExtMemoryKM: invalid parameter, no address specificed")); -+ } -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ /* Choose the heap to map to */ -+ psDevMemoryInfo = &((BM_CONTEXT*)hDevMemContext)->psDeviceNode->sDevMemoryInfo; -+ psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap; -+ for(i=0; i<PVRSRV_MAX_CLIENT_HEAPS; i++) -+ { -+ if(HEAP_IDX(psDeviceMemoryHeap[i].ui32HeapID) == psDevMemoryInfo->ui32MappingHeapID) -+ { -+ if(psDeviceMemoryHeap[i].DevMemHeapType == DEVICE_MEMORY_HEAP_PERCONTEXT) -+ { -+ if (psDeviceMemoryHeap[i].ui32HeapSize > 0) -+ { -+ hDevMemHeap = BM_CreateHeap(hDevMemContext, &psDeviceMemoryHeap[i]); -+ } -+ else -+ { -+ hDevMemHeap = IMG_NULL; -+ } -+ } -+ else -+ { -+ hDevMemHeap = psDevMemoryInfo->psDeviceMemoryHeap[i].hDevMemHeap; -+ } -+ break; -+ } -+ } -+ -+ if(hDevMemHeap == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: unable to find mapping heap")); -+ eError = PVRSRV_ERROR_UNABLE_TO_FIND_MAPPING_HEAP; -+ goto ErrorExitPhase2; -+ } -+ -+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(PVRSRV_KERNEL_MEM_INFO), -+ (IMG_VOID **)&psMemInfo, IMG_NULL, -+ "Kernel Memory Info") != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: Failed to alloc memory for block")); -+ eError = PVRSRV_ERROR_OUT_OF_MEMORY; -+ goto ErrorExitPhase2; -+ } -+ -+ OSMemSet(psMemInfo, 0, sizeof(*psMemInfo)); -+ /* -+ Force the memory to be read/write. This used to be done in the BM, but -+ ion imports don't want this behaviour -+ */ -+ psMemInfo->ui32Flags = ui32Flags | PVRSRV_MEM_READ | PVRSRV_MEM_WRITE; -+ -+ psMemBlock = &(psMemInfo->sMemBlk); -+ -+ bBMError = BM_Wrap(hDevMemHeap, -+ uByteSize, -+ uPageOffset, -+ bPhysContig, -+ psExtSysPAddr, -+ IMG_NULL, -+ &psMemInfo->ui32Flags, -+ &hBuffer); -+ if (!bBMError) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: BM_Wrap Failed")); -+ eError = PVRSRV_ERROR_BAD_MAPPING; -+ goto ErrorExitPhase3; -+ } -+ -+ /* Fill in "Implementation dependant" section of mem info */ -+ psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer); -+ psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer); -+ psMemBlock->hOSWrapMem = hOSWrapMem; -+ psMemBlock->psIntSysPAddr = psIntSysPAddr; -+ -+ /* Convert from BM_HANDLE to external IMG_HANDLE */ -+ psMemBlock->hBuffer = (IMG_HANDLE)hBuffer; -+ -+ /* Fill in the public fields of the MEM_INFO structure */ -+ psMemInfo->pvLinAddrKM = BM_HandleToCpuVaddr(hBuffer); -+ psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr; -+ psMemInfo->uAllocSize = uByteSize; -+ -+ /* Clear the Backup buffer pointer as we do not have one at this point. -+ We only allocate this as we are going up/down -+ */ -+ psMemInfo->pvSysBackupBuffer = IMG_NULL; -+ -+ /* -+ allocate a syncinfo but don't register with resman -+ because the holding devicemem will handle the syncinfo -+ */ -+ psBMHeap = (BM_HEAP*)hDevMemHeap; -+ hDevMemContext = (IMG_HANDLE)psBMHeap->pBMContext; -+ eError = PVRSRVAllocSyncInfoKM(hDevCookie, -+ hDevMemContext, -+ &psMemInfo->psKernelSyncInfo); -+ if(eError != PVRSRV_OK) -+ { -+ goto ErrorExitPhase4; -+ } -+ -+ /* increment the refcount */ -+ PVRSRVKernelMemInfoIncRef(psMemInfo); -+ -+ psMemInfo->memType = PVRSRV_MEMTYPE_WRAPPED; -+ -+ /* Register Resource */ -+ psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext, -+ RESMAN_TYPE_DEVICEMEM_WRAP, -+ psMemInfo, -+ 0, -+ &UnwrapExtMemoryCallBack); -+ -+ /* return the meminfo */ -+ *ppsMemInfo = psMemInfo; -+ -+ return PVRSRV_OK; -+ -+ /* error handling: */ -+ -+ErrorExitPhase4: -+ if(psMemInfo) -+ { -+ FreeDeviceMem(psMemInfo); -+ /* -+ FreeDeviceMem will free the meminfo so set -+ it to NULL to avoid double free below -+ */ -+ psMemInfo = IMG_NULL; -+ } -+ -+ErrorExitPhase3: -+ if(psMemInfo) -+ { -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL); -+ /*not nulling pointer, out of scope*/ -+ } -+ -+ErrorExitPhase2: -+ if(psIntSysPAddr) -+ { -+ OSReleasePhysPageAddr(hOSWrapMem); -+ } -+ -+ErrorExitPhase1: -+ if(psIntSysPAddr) -+ { -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, uPageCount * sizeof(IMG_SYS_PHYADDR), psIntSysPAddr, IMG_NULL); -+ /*not nulling shared pointer, uninitialized to this point*/ -+ } -+ -+ return eError; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVUnmapDeviceMemoryKM -+ -+ @Description -+ Unmaps an existing allocation previously mapped by PVRSRVMapDeviceMemory -+ -+ @Input psMemInfo -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapDeviceMemoryKM (PVRSRV_KERNEL_MEM_INFO *psMemInfo) -+{ -+ if (!psMemInfo) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ return ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem, CLEANUP_WITH_POLL); -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function UnmapDeviceMemoryCallBack -+ -+ @Description Resman callback to unmap memory memory previously mapped -+ from one allocation to another -+ -+ @Input pvParam - opaque void ptr param -+ @Input ui32Param - opaque unsigned long param -+ @Return PVRSRV_ERROR -+******************************************************************************/ -+static PVRSRV_ERROR UnmapDeviceMemoryCallBack(IMG_PVOID pvParam, -+ IMG_UINT32 ui32Param, -+ IMG_BOOL bDummy) -+{ -+ PVRSRV_ERROR eError; -+ RESMAN_MAP_DEVICE_MEM_DATA *psMapData = pvParam; -+ -+ PVR_UNREFERENCED_PARAMETER(ui32Param); -+ PVR_UNREFERENCED_PARAMETER(bDummy); -+ -+ if(psMapData->psMemInfo->sMemBlk.psIntSysPAddr) -+ { -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(IMG_SYS_PHYADDR), psMapData->psMemInfo->sMemBlk.psIntSysPAddr, IMG_NULL); -+ psMapData->psMemInfo->sMemBlk.psIntSysPAddr = IMG_NULL; -+ } -+ -+ if( psMapData->psMemInfo->psKernelSyncInfo ) -+ { -+ PVRSRVKernelSyncInfoDecRef(psMapData->psMemInfo->psKernelSyncInfo, psMapData->psMemInfo); -+ } -+ -+ eError = FreeDeviceMem(psMapData->psMemInfo); -+ if(eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"UnmapDeviceMemoryCallBack: Failed to free DST meminfo")); -+ return eError; -+ } -+ -+ /* This will only free the src psMemInfo if we hold the last reference */ -+ eError = FreeMemCallBackCommon(psMapData->psSrcMemInfo, 0, -+ PVRSRV_FREE_CALLBACK_ORIGIN_IMPORTER); -+ -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RESMAN_MAP_DEVICE_MEM_DATA), psMapData, IMG_NULL); -+ /*not nulling pointer, copy on stack*/ -+ -+ return eError; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVMapDeviceMemoryKM -+ -+ @Description -+ Maps an existing allocation to a specific device address space and heap -+ Note: it's valid to map from one physical device to another -+ -+ @Input psPerProc : Per-process data -+ @Input psSrcMemInfo -+ @Input hDstDevMemHeap -+ @Input ppsDstMemInfo -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceMemoryKM(PVRSRV_PER_PROCESS_DATA *psPerProc, -+ PVRSRV_KERNEL_MEM_INFO *psSrcMemInfo, -+ IMG_HANDLE hDstDevMemHeap, -+ PVRSRV_KERNEL_MEM_INFO **ppsDstMemInfo) -+{ -+ PVRSRV_ERROR eError; -+ IMG_UINT32 i; -+ IMG_SIZE_T uPageCount, uPageOffset; -+ IMG_SIZE_T ui32HostPageSize = HOST_PAGESIZE(); -+ IMG_SYS_PHYADDR *psSysPAddr = IMG_NULL; -+ IMG_DEV_PHYADDR sDevPAddr; -+ BM_BUF *psBuf; -+ IMG_DEV_VIRTADDR sDevVAddr; -+ PVRSRV_KERNEL_MEM_INFO *psMemInfo = IMG_NULL; -+ BM_HANDLE hBuffer; -+ PVRSRV_MEMBLK *psMemBlock; -+ IMG_BOOL bBMError; -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+ IMG_VOID *pvPageAlignedCPUVAddr; -+ RESMAN_MAP_DEVICE_MEM_DATA *psMapData = IMG_NULL; -+ -+ /* check params */ -+ if(!psSrcMemInfo || !hDstDevMemHeap || !ppsDstMemInfo) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: invalid parameters")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ /* initialise the Dst Meminfo to NULL*/ -+ *ppsDstMemInfo = IMG_NULL; -+ -+ uPageOffset = psSrcMemInfo->sDevVAddr.uiAddr & (ui32HostPageSize - 1); -+ uPageCount = HOST_PAGEALIGN(psSrcMemInfo->uAllocSize + uPageOffset) / ui32HostPageSize; -+ pvPageAlignedCPUVAddr = (IMG_VOID *)((IMG_UINTPTR_T)psSrcMemInfo->pvLinAddrKM - uPageOffset); -+ -+ /* -+ allocate array of SysPAddr to hold SRC allocation page addresses -+ */ -+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ uPageCount*sizeof(IMG_SYS_PHYADDR), -+ (IMG_VOID **)&psSysPAddr, IMG_NULL, -+ "Array of Page Addresses") != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: Failed to alloc memory for block")); -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ -+ psBuf = psSrcMemInfo->sMemBlk.hBuffer; -+ -+ /* get the device node */ -+ psDeviceNode = psBuf->pMapping->pBMHeap->pBMContext->psDeviceNode; -+ -+ /* build a list of physical page addresses */ -+ sDevVAddr.uiAddr = psSrcMemInfo->sDevVAddr.uiAddr - IMG_CAST_TO_DEVVADDR_UINT(uPageOffset); -+ for(i=0; i<uPageCount; i++) -+ { -+ BM_GetPhysPageAddr(psSrcMemInfo, sDevVAddr, &sDevPAddr); -+ -+ /* save the address */ -+ psSysPAddr[i] = SysDevPAddrToSysPAddr (psDeviceNode->sDevId.eDeviceType, sDevPAddr); -+ -+ /* advance the DevVaddr one page */ -+ sDevVAddr.uiAddr += IMG_CAST_TO_DEVVADDR_UINT(ui32HostPageSize); -+ } -+ -+ /* allocate the resman map data */ -+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(RESMAN_MAP_DEVICE_MEM_DATA), -+ (IMG_VOID **)&psMapData, IMG_NULL, -+ "Resource Manager Map Data") != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: Failed to alloc resman map data")); -+ eError = PVRSRV_ERROR_OUT_OF_MEMORY; -+ goto ErrorExit; -+ } -+ -+ if(OSAllocMem(PVRSRV_PAGEABLE_SELECT, -+ sizeof(PVRSRV_KERNEL_MEM_INFO), -+ (IMG_VOID **)&psMemInfo, IMG_NULL, -+ "Kernel Memory Info") != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: Failed to alloc memory for block")); -+ eError = PVRSRV_ERROR_OUT_OF_MEMORY; -+ goto ErrorExit; -+ } -+ -+ OSMemSet(psMemInfo, 0, sizeof(*psMemInfo)); -+ -+ /* -+ Force the memory to be read/write. This used to be done in the BM, but -+ ion imports don't want this behaviour -+ */ -+ psMemInfo->ui32Flags = psSrcMemInfo->ui32Flags | PVRSRV_MEM_READ | PVRSRV_MEM_WRITE; -+ -+ psMemBlock = &(psMemInfo->sMemBlk); -+ -+ bBMError = BM_Wrap(hDstDevMemHeap, -+ psSrcMemInfo->uAllocSize, -+ uPageOffset, -+ IMG_FALSE, -+ psSysPAddr, -+ pvPageAlignedCPUVAddr, -+ &psMemInfo->ui32Flags, -+ &hBuffer); -+ -+ if (!bBMError) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: BM_Wrap Failed")); -+ eError = PVRSRV_ERROR_BAD_MAPPING; -+ goto ErrorExit; -+ } -+ -+ /* Fill in "Implementation dependant" section of mem info */ -+ psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer); -+ psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer); -+ -+ /* Convert from BM_HANDLE to external IMG_HANDLE */ -+ psMemBlock->hBuffer = (IMG_HANDLE)hBuffer; -+ -+ /* Store page list */ -+ psMemBlock->psIntSysPAddr = psSysPAddr; -+ -+ /* patch up the CPU VAddr into the meminfo */ -+ psMemInfo->pvLinAddrKM = psSrcMemInfo->pvLinAddrKM; -+ -+ /* Fill in the public fields of the MEM_INFO structure */ -+ psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr; -+ psMemInfo->uAllocSize = psSrcMemInfo->uAllocSize; -+ psMemInfo->psKernelSyncInfo = psSrcMemInfo->psKernelSyncInfo; -+ -+ /* reference the same ksi that the original meminfo referenced */ -+ if(psMemInfo->psKernelSyncInfo) -+ { -+ PVRSRVKernelSyncInfoIncRef(psMemInfo->psKernelSyncInfo, psMemInfo); -+ } -+ -+ /* Clear the Backup buffer pointer as we do not have one at this point. -+ We only allocate this as we are going up/down -+ */ -+ psMemInfo->pvSysBackupBuffer = IMG_NULL; -+ -+ /* increment our refcount */ -+ PVRSRVKernelMemInfoIncRef(psMemInfo); -+ -+ /* increment the src refcount */ -+ PVRSRVKernelMemInfoIncRef(psSrcMemInfo); -+ -+ /* Tell the buffer manager about the export */ -+ BM_Export(psSrcMemInfo->sMemBlk.hBuffer); -+ -+ psMemInfo->memType = PVRSRV_MEMTYPE_MAPPED; -+ -+ /* setup the resman map data */ -+ psMapData->psMemInfo = psMemInfo; -+ psMapData->psSrcMemInfo = psSrcMemInfo; -+ -+ /* Register Resource */ -+ psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext, -+ RESMAN_TYPE_DEVICEMEM_MAPPING, -+ psMapData, -+ 0, -+ &UnmapDeviceMemoryCallBack); -+ -+ *ppsDstMemInfo = psMemInfo; -+ -+ return PVRSRV_OK; -+ -+ /* error handling: */ -+ -+ErrorExit: -+ -+ if(psSysPAddr) -+ { -+ /* Free the page address list */ -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(IMG_SYS_PHYADDR), psSysPAddr, IMG_NULL); -+ /*not nulling shared pointer, holding structure could be not initialized*/ -+ } -+ -+ if(psMemInfo) -+ { -+ /* Free the page address list */ -+ OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL); -+ /*not nulling shared pointer, holding structure could be not initialized*/ -+ } -+ -+ if(psMapData) -+ { -+ /* Free the resman map data */ -+ OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(RESMAN_MAP_DEVICE_MEM_DATA), psMapData, IMG_NULL); -+ /*not nulling pointer, out of scope*/ -+ } -+ -+ return eError; -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function PVRSRVUnmapDeviceClassMemoryKM -+ -+ @Description unmaps physical pages from devices address space at a specified -+ Device Virtual Address. -+ Note: this can only unmap memory mapped by -+ PVRSRVMapDeviceClassMemoryKM -+ -+ @Input psMemInfo - mem info describing the device virtual address -+ to unmap RAM from -+ @Return None -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapDeviceClassMemoryKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo) -+{ -+ if (!psMemInfo) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ return ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem, CLEANUP_WITH_POLL); -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function UnmapDeviceClassMemoryCallBack -+ -+ @Description Resman callback to unmap device class memory -+ -+ @Input pvParam - opaque void ptr param -+ @Input ui32Param - opaque unsigned long param -+ @Return PVRSRV_ERROR -+******************************************************************************/ -+static PVRSRV_ERROR UnmapDeviceClassMemoryCallBack(IMG_PVOID pvParam, -+ IMG_UINT32 ui32Param, -+ IMG_BOOL bDummy) -+{ -+ PVRSRV_DC_MAPINFO *psDCMapInfo = pvParam; -+ PVRSRV_KERNEL_MEM_INFO *psMemInfo; -+ -+ PVR_UNREFERENCED_PARAMETER(ui32Param); -+ PVR_UNREFERENCED_PARAMETER(bDummy); -+ -+ psMemInfo = psDCMapInfo->psMemInfo; -+ -+#if defined(SUPPORT_MEMORY_TILING) -+ if(psDCMapInfo->ui32TilingStride > 0) -+ { -+ PVRSRV_DEVICE_NODE *psDeviceNode = psDCMapInfo->psDeviceNode; -+ -+ if (psDeviceNode->pfnFreeMemTilingRange(psDeviceNode, -+ psDCMapInfo->ui32RangeIndex) != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"UnmapDeviceClassMemoryCallBack: FreeMemTilingRange failed")); -+ } -+ } -+#endif -+ -+ (psDCMapInfo->psDeviceClassBuffer->ui32MemMapRefCount)--; -+ -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_MAPINFO), psDCMapInfo, IMG_NULL); -+ -+ return FreeMemCallBackCommon(psMemInfo, ui32Param, -+ PVRSRV_FREE_CALLBACK_ORIGIN_ALLOCATOR); -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function PVRSRVMapDeviceClassMemoryKM -+ -+ @Description maps physical pages for DeviceClass buffers into a devices -+ address space at a specified and pre-allocated Device -+ Virtual Address -+ -+ @Input psPerProc - Per-process data -+ @Input hDevMemContext - Device memory context -+ @Input hDeviceClassBuffer - Device Class Buffer (Surface) handle -+ @Input hDevMemContext - device memory context to which mapping -+ is made -+ @Output ppsMemInfo - mem info describing the mapped memory -+ @Output phOSMapInfo - OS specific mapping information -+ @Return None -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceClassMemoryKM(PVRSRV_PER_PROCESS_DATA *psPerProc, -+ IMG_HANDLE hDevMemContext, -+ IMG_HANDLE hDeviceClassBuffer, -+ PVRSRV_KERNEL_MEM_INFO **ppsMemInfo, -+ IMG_HANDLE *phOSMapInfo) -+{ -+ PVRSRV_ERROR eError; -+ PVRSRV_DEVICE_NODE* psDeviceNode; -+ PVRSRV_KERNEL_MEM_INFO *psMemInfo = IMG_NULL; -+ PVRSRV_DEVICECLASS_BUFFER *psDeviceClassBuffer; -+ IMG_SYS_PHYADDR *psSysPAddr; -+ IMG_VOID *pvCPUVAddr, *pvPageAlignedCPUVAddr; -+ IMG_BOOL bPhysContig; -+ BM_CONTEXT *psBMContext; -+ DEVICE_MEMORY_INFO *psDevMemoryInfo; -+ DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; -+ IMG_HANDLE hDevMemHeap = IMG_NULL; -+ IMG_UINT32 ui32ByteSize; -+ IMG_SIZE_T uOffset; -+ IMG_SIZE_T uPageSize = HOST_PAGESIZE(); -+ BM_HANDLE hBuffer; -+ PVRSRV_MEMBLK *psMemBlock; -+ IMG_BOOL bBMError; -+ IMG_UINT32 i; -+ PVRSRV_DC_MAPINFO *psDCMapInfo = IMG_NULL; -+ -+ if(!hDeviceClassBuffer || !ppsMemInfo || !phOSMapInfo || !hDevMemContext) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: invalid parameters")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ /* allocate resman storage structure */ -+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(PVRSRV_DC_MAPINFO), -+ (IMG_VOID **)&psDCMapInfo, IMG_NULL, -+ "PVRSRV_DC_MAPINFO") != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: Failed to alloc memory for psDCMapInfo")); -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ OSMemSet(psDCMapInfo, 0, sizeof(PVRSRV_DC_MAPINFO)); -+ -+ psDeviceClassBuffer = (PVRSRV_DEVICECLASS_BUFFER*)hDeviceClassBuffer; -+ -+ /* -+ call into external driver to get info so we can map a meminfo -+ Notes: -+ It's expected that third party displays will only support -+ physically contiguous display surfaces. However, it's possible -+ a given display may have an MMU and therefore support non-contig' -+ display surfaces. -+ -+ If surfaces are contiguous, ext driver should return: -+ - a CPU virtual address, or IMG_NULL where the surface is not mapped to CPU -+ - (optional) an OS Mapping handle for KM->UM surface mapping -+ - the size in bytes -+ - a single system physical address -+ -+ If surfaces are non-contiguous, ext driver should return: -+ - a CPU virtual address -+ - (optional) an OS Mapping handle for KM->UM surface mapping -+ - the size in bytes (must be multiple of 4kB) -+ - a list of system physical addresses (at 4kB intervals) -+ */ -+ eError = psDeviceClassBuffer->pfnGetBufferAddr(psDeviceClassBuffer->hExtDevice, -+ psDeviceClassBuffer->hExtBuffer, -+ &psSysPAddr, -+ &ui32ByteSize, -+ &pvCPUVAddr, -+ phOSMapInfo, -+ &bPhysContig, -+ &psDCMapInfo->ui32TilingStride); -+ if(eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: unable to get buffer address")); -+ goto ErrorExitPhase1; -+ } -+ -+ /* Choose the heap to map to */ -+ psBMContext = (BM_CONTEXT*)psDeviceClassBuffer->hDevMemContext; -+ psDeviceNode = psBMContext->psDeviceNode; -+ psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo; -+ psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap; -+ for(i=0; i<PVRSRV_MAX_CLIENT_HEAPS; i++) -+ { -+ if(HEAP_IDX(psDeviceMemoryHeap[i].ui32HeapID) == psDevMemoryInfo->ui32MappingHeapID) -+ { -+ if(psDeviceMemoryHeap[i].DevMemHeapType == DEVICE_MEMORY_HEAP_PERCONTEXT) -+ { -+ if (psDeviceMemoryHeap[i].ui32HeapSize > 0) -+ { -+ hDevMemHeap = BM_CreateHeap(hDevMemContext, &psDeviceMemoryHeap[i]); -+ } -+ else -+ { -+ hDevMemHeap = IMG_NULL; -+ } -+ } -+ else -+ { -+ hDevMemHeap = psDevMemoryInfo->psDeviceMemoryHeap[i].hDevMemHeap; -+ } -+ break; -+ } -+ } -+ -+ if(hDevMemHeap == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: unable to find mapping heap")); -+ eError = PVRSRV_ERROR_UNABLE_TO_FIND_RESOURCE; -+ goto ErrorExitPhase1; -+ } -+ -+ /* Only need lower 12 bits of the cpu addr - don't care what size a void* is */ -+ uOffset = ((IMG_UINTPTR_T)pvCPUVAddr) & (uPageSize - 1); -+ pvPageAlignedCPUVAddr = (IMG_VOID *)((IMG_UINTPTR_T)pvCPUVAddr - uOffset); -+ -+ eError = OSAllocMem(PVRSRV_PAGEABLE_SELECT, -+ sizeof(PVRSRV_KERNEL_MEM_INFO), -+ (IMG_VOID **)&psMemInfo, IMG_NULL, -+ "Kernel Memory Info"); -+ if(eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: Failed to alloc memory for block")); -+ goto ErrorExitPhase1; -+ } -+ -+ OSMemSet(psMemInfo, 0, sizeof(*psMemInfo)); -+ -+ /* -+ Force the memory to be read/write. This used to be done in the BM, but -+ ion imports don't want this behaviour -+ */ -+ psMemInfo->ui32Flags |= PVRSRV_MEM_READ | PVRSRV_MEM_WRITE; -+ -+ psMemBlock = &(psMemInfo->sMemBlk); -+ -+ bBMError = BM_Wrap(hDevMemHeap, -+ ui32ByteSize, -+ uOffset, -+ bPhysContig, -+ psSysPAddr, -+ pvPageAlignedCPUVAddr, -+ &psMemInfo->ui32Flags, -+ &hBuffer); -+ -+ if (!bBMError) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: BM_Wrap Failed")); -+ /*not nulling pointer, out of scope*/ -+ eError = PVRSRV_ERROR_BAD_MAPPING; -+ goto ErrorExitPhase2; -+ } -+ -+ /* Fill in "Implementation dependant" section of mem info */ -+ psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer); -+ psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer); -+ -+ /* Convert from BM_HANDLE to external IMG_HANDLE */ -+ psMemBlock->hBuffer = (IMG_HANDLE)hBuffer; -+ -+ /* patch up the CPU VAddr into the meminfo - use the address from the BM, not the one from the deviceclass -+ api, to ensure user mode mapping is possible -+ */ -+ psMemInfo->pvLinAddrKM = BM_HandleToCpuVaddr(hBuffer); -+ -+ /* Fill in the public fields of the MEM_INFO structure */ -+ psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr; -+ psMemInfo->uAllocSize = ui32ByteSize; -+ psMemInfo->psKernelSyncInfo = psDeviceClassBuffer->psKernelSyncInfo; -+ -+ PVR_ASSERT(psMemInfo->psKernelSyncInfo != IMG_NULL); -+ if (psMemInfo->psKernelSyncInfo) -+ { -+ PVRSRVKernelSyncInfoIncRef(psMemInfo->psKernelSyncInfo, psMemInfo); -+ } -+ -+ /* Clear the Backup buffer pointer as we do not have one at this point. -+ We only allocate this as we are going up/down -+ */ -+ psMemInfo->pvSysBackupBuffer = IMG_NULL; -+ -+ /* setup DCMapInfo */ -+ psDCMapInfo->psMemInfo = psMemInfo; -+ psDCMapInfo->psDeviceClassBuffer = psDeviceClassBuffer; -+ -+#if defined(SUPPORT_MEMORY_TILING) -+ psDCMapInfo->psDeviceNode = psDeviceNode; -+ -+ if(psDCMapInfo->ui32TilingStride > 0) -+ { -+ /* try to acquire a tiling range on this device */ -+ eError = psDeviceNode->pfnAllocMemTilingRange(psDeviceNode, -+ psMemInfo, -+ psDCMapInfo->ui32TilingStride, -+ &psDCMapInfo->ui32RangeIndex); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: AllocMemTilingRange failed")); -+ goto ErrorExitPhase3; -+ } -+ } -+#endif -+ -+ /* Register Resource */ -+ psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext, -+ RESMAN_TYPE_DEVICECLASSMEM_MAPPING, -+ psDCMapInfo, -+ 0, -+ &UnmapDeviceClassMemoryCallBack); -+ -+ (psDeviceClassBuffer->ui32MemMapRefCount)++; -+ PVRSRVKernelMemInfoIncRef(psMemInfo); -+ -+ psMemInfo->memType = PVRSRV_MEMTYPE_DEVICECLASS; -+ -+ /* return the meminfo */ -+ *ppsMemInfo = psMemInfo; -+ -+#if defined(SUPPORT_PDUMP_MULTI_PROCESS) -+ /* If the 3PDD supplies a kernel virtual address, we can PDUMP it */ -+ if(psMemInfo->pvLinAddrKM) -+ { -+ /* FIXME: -+ * Initialise the display surface here when it is mapped into Services. -+ * Otherwise there is a risk that pdump toolchain will assign previously -+ * used physical pages, leading to visual artefacts on the unrendered surface -+ * (e.g. during LLS rendering). -+ * -+ * A better method is to pdump the allocation from the DC driver, so the -+ * BM_Wrap pdumps only the virtual memory which better represents the driver -+ * behaviour. -+ */ -+ PDUMPCOMMENT("Dump display surface"); -+ PDUMPMEM(IMG_NULL, psMemInfo, uOffset, psMemInfo->uAllocSize, PDUMP_FLAGS_CONTINUOUS, ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping); -+ } -+#endif -+ return PVRSRV_OK; -+ -+#if defined(SUPPORT_MEMORY_TILING) -+ErrorExitPhase3: -+ if(psMemInfo) -+ { -+ if (psMemInfo->psKernelSyncInfo) -+ { -+ PVRSRVKernelSyncInfoDecRef(psMemInfo->psKernelSyncInfo, psMemInfo); -+ } -+ -+ FreeDeviceMem(psMemInfo); -+ /* -+ FreeDeviceMem will free the meminfo so set -+ it to NULL to avoid double free below -+ */ -+ psMemInfo = IMG_NULL; -+ } -+#endif -+ -+ErrorExitPhase2: -+ if(psMemInfo) -+ { -+ OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL); -+ } -+ -+ErrorExitPhase1: -+ if(psDCMapInfo) -+ { -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_KERNEL_MEM_INFO), psDCMapInfo, IMG_NULL); -+ } -+ -+ return eError; -+} -+ -+ -+IMG_EXPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVChangeDeviceMemoryAttributesKM(IMG_HANDLE hKernelMemInfo, IMG_UINT32 ui32Attribs) -+{ -+ PVRSRV_KERNEL_MEM_INFO *psKMMemInfo; -+ -+ if (hKernelMemInfo == IMG_NULL) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psKMMemInfo = (PVRSRV_KERNEL_MEM_INFO *)hKernelMemInfo; -+ -+ if (ui32Attribs & PVRSRV_CHANGEDEVMEM_ATTRIBS_CACHECOHERENT) -+ { -+ psKMMemInfo->ui32Flags |= PVRSRV_MEM_CACHE_CONSISTENT; -+ } -+ else -+ { -+ psKMMemInfo->ui32Flags &= ~PVRSRV_MEM_CACHE_CONSISTENT; -+ } -+ -+ return PVRSRV_OK; -+} -+ -+PVRSRV_ERROR IMG_CALLCONV PVRSRVInitDeviceMem(IMG_VOID) -+{ -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ -+#if defined(SUPPORT_ION) -+ /* -+ For Ion buffers we need to store which ones we know about so -+ we don't give the same buffer a different sync -+ */ -+ g_psIonSyncHash = HASH_Create(ION_SYNC_HASH_SIZE); -+ if (g_psIonSyncHash == IMG_NULL) -+ { -+ eError = PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+#endif -+ -+ return eError; -+} -+ -+IMG_VOID IMG_CALLCONV PVRSRVDeInitDeviceMem(IMG_VOID) -+{ -+#if defined(SUPPORT_ION) -+ HASH_Delete(g_psIonSyncHash); -+#endif -+} -+ -+ -+ -+/****************************************************************************** -+ End of file (devicemem.c) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/common/handle.c b/drivers/staging/ti-es8-sgx/services4/srvkm/common/handle.c -new file mode 100644 -index 0000000..95aac61 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/common/handle.c -@@ -0,0 +1,2548 @@ -+/*************************************************************************/ /*! -+@Title Resource Handle Manager -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Provide resource handle management -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#if defined(PVR_SECURE_HANDLES) -+/* See handle.h for a description of the handle API. */ -+ -+/* -+ * There is no locking here. It is assumed the code is used in a single -+ * threaded environment. In particular, it is assumed that the code will -+ * never be called from an interrupt handler. -+ * -+ * The implmentation supports movable handle structures, allowing the address -+ * of a handle structure to change without having to fix up pointers in -+ * any of the handle structures. For example, the linked list mechanism -+ * used to link subhandles together uses handle array indices rather than -+ * pointers to the structures themselves. -+ */ -+ -+#include <stddef.h> -+ -+#include "services_headers.h" -+#include "handle.h" -+ -+#ifdef DEBUG -+#define HANDLE_BLOCK_SHIFT 2 -+#else -+#define HANDLE_BLOCK_SHIFT 8 -+#endif -+ -+#define DIVIDE_BY_BLOCK_SIZE(i) (((IMG_UINT32)(i)) >> HANDLE_BLOCK_SHIFT) -+#define MULTIPLY_BY_BLOCK_SIZE(i) (((IMG_UINT32)(i)) << HANDLE_BLOCK_SHIFT) -+ -+#define HANDLE_BLOCK_SIZE MULTIPLY_BY_BLOCK_SIZE(1) -+#define HANDLE_SUB_BLOCK_MASK (HANDLE_BLOCK_SIZE - 1) -+#define HANDLE_BLOCK_MASK (~(HANDLE_SUB_BLOCK_MASK)) -+ -+#define HANDLE_HASH_TAB_INIT_SIZE 32 -+ -+#define INDEX_IS_VALID(psBase, i) ((i) < (psBase)->ui32TotalHandCount) -+ -+/* Valid handles are never NULL, but handle array indices are based from 0 */ -+#define INDEX_TO_HANDLE(i) ((IMG_HANDLE)((IMG_UINTPTR_T)(i) + 1)) -+#define HANDLE_TO_INDEX(h) ((IMG_UINT32)(IMG_UINTPTR_T)(h) - 1) -+ -+ -+#define INDEX_TO_BLOCK_INDEX(i) DIVIDE_BY_BLOCK_SIZE(i) -+#define BLOCK_INDEX_TO_INDEX(i) MULTIPLY_BY_BLOCK_SIZE(i) -+#define INDEX_TO_SUB_BLOCK_INDEX(i) ((i) & HANDLE_SUB_BLOCK_MASK) -+ -+#define INDEX_TO_INDEX_STRUCT_PTR(psArray, i) (&((psArray)[INDEX_TO_BLOCK_INDEX(i)])) -+#define BASE_AND_INDEX_TO_INDEX_STRUCT_PTR(psBase, i) INDEX_TO_INDEX_STRUCT_PTR((psBase)->psHandleArray, i) -+ -+#define INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, i) (BASE_AND_INDEX_TO_INDEX_STRUCT_PTR(psBase, i)->ui32FreeHandBlockCount) -+ -+#define INDEX_TO_HANDLE_STRUCT_PTR(psBase, i) (BASE_AND_INDEX_TO_INDEX_STRUCT_PTR(psBase, i)->psHandle + INDEX_TO_SUB_BLOCK_INDEX(i)) -+ -+#define HANDLE_TO_HANDLE_STRUCT_PTR(psBase, h) (INDEX_TO_HANDLE_STRUCT_PTR(psBase, HANDLE_TO_INDEX(h))) -+ -+#define HANDLE_PTR_TO_INDEX(psHandle) ((psHandle)->ui32Index) -+#define HANDLE_PTR_TO_HANDLE(psHandle) INDEX_TO_HANDLE(HANDLE_PTR_TO_INDEX(psHandle)) -+ -+#define ROUND_DOWN_TO_MULTIPLE_OF_BLOCK_SIZE(a) (HANDLE_BLOCK_MASK & (a)) -+#define ROUND_UP_TO_MULTIPLE_OF_BLOCK_SIZE(a) ROUND_DOWN_TO_MULTIPLE_OF_BLOCK_SIZE((a) + HANDLE_BLOCK_SIZE - 1) -+ -+#define DEFAULT_MAX_HANDLE 0x7fffffffu -+#define DEFAULT_MAX_INDEX_PLUS_ONE ROUND_DOWN_TO_MULTIPLE_OF_BLOCK_SIZE(DEFAULT_MAX_HANDLE) -+ -+#define HANDLES_BATCHED(psBase) ((psBase)->ui32HandBatchSize != 0) -+ -+#define HANDLE_ARRAY_SIZE(handleCount) DIVIDE_BY_BLOCK_SIZE(ROUND_UP_TO_MULTIPLE_OF_BLOCK_SIZE(handleCount)) -+ -+#define SET_FLAG(v, f) ((IMG_VOID)((v) |= (f))) -+#define CLEAR_FLAG(v, f) ((IMG_VOID)((v) &= ~(f))) -+#define TEST_FLAG(v, f) ((IMG_BOOL)(((v) & (f)) != 0)) -+ -+#define TEST_ALLOC_FLAG(psHandle, f) TEST_FLAG((psHandle)->eFlag, f) -+ -+#define SET_INTERNAL_FLAG(psHandle, f) SET_FLAG((psHandle)->eInternalFlag, f) -+#define CLEAR_INTERNAL_FLAG(psHandle, f) CLEAR_FLAG((psHandle)->eInternalFlag, f) -+#define TEST_INTERNAL_FLAG(psHandle, f) TEST_FLAG((psHandle)->eInternalFlag, f) -+ -+#define BATCHED_HANDLE(psHandle) TEST_INTERNAL_FLAG(psHandle, INTERNAL_HANDLE_FLAG_BATCHED) -+ -+#define SET_BATCHED_HANDLE(psHandle) SET_INTERNAL_FLAG(psHandle, INTERNAL_HANDLE_FLAG_BATCHED) -+ -+#define SET_UNBATCHED_HANDLE(psHandle) CLEAR_INTERNAL_FLAG(psHandle, INTERNAL_HANDLE_FLAG_BATCHED) -+ -+#define BATCHED_HANDLE_PARTIALLY_FREE(psHandle) TEST_INTERNAL_FLAG(psHandle, INTERNAL_HANDLE_FLAG_BATCHED_PARTIALLY_FREE) -+ -+#define SET_BATCHED_HANDLE_PARTIALLY_FREE(psHandle) SET_INTERNAL_FLAG(psHandle, INTERNAL_HANDLE_FLAG_BATCHED_PARTIALLY_FREE) -+ -+#define HANDLE_STRUCT_IS_FREE(psHandle) ((psHandle)->eType == PVRSRV_HANDLE_TYPE_NONE && (psHandle)->eInternalFlag == INTERNAL_HANDLE_FLAG_NONE) -+ -+#ifdef MIN -+#undef MIN -+#endif -+ -+#define MIN(x, y) (((x) < (y)) ? (x) : (y)) -+ -+/* -+ * Linked list structure. Used for both the list head and list items. -+ * Array indices, rather than pointers, are used to point to the next and -+ * previous items on the list. -+ */ -+struct sHandleList -+{ -+ IMG_UINT32 ui32Prev; -+ IMG_UINT32 ui32Next; -+ IMG_HANDLE hParent; -+}; -+ -+enum ePVRSRVInternalHandleFlag -+{ -+ INTERNAL_HANDLE_FLAG_NONE = 0x00, -+ INTERNAL_HANDLE_FLAG_BATCHED = 0x01, -+ INTERNAL_HANDLE_FLAG_BATCHED_PARTIALLY_FREE = 0x02, -+}; -+ -+/* Handle structure */ -+struct sHandle -+{ -+ /* Handle type */ -+ PVRSRV_HANDLE_TYPE eType; -+ -+ /* Pointer to the data that the handle represents */ -+ IMG_VOID *pvData; -+ -+ /* -+ * When handles are on the free list, the value of the "next index -+ * plus one field" has the following meaning: -+ * zero - next handle is the one that follows this one, -+ * nonzero - the index of the next handle is the value minus one. -+ * This scheme means handle space can be initialised to all zeros. -+ * -+ * When this field is used to link together handles on a list -+ * other than the free list, zero indicates the end of the -+ * list, with nonzero the same as above. -+ */ -+ IMG_UINT32 ui32NextIndexPlusOne; -+ -+ /* Internal flags */ -+ enum ePVRSRVInternalHandleFlag eInternalFlag; -+ -+ /* Flags specified when the handle was allocated */ -+ PVRSRV_HANDLE_ALLOC_FLAG eFlag; -+ -+ /* Index of this handle in the handle array */ -+ IMG_UINT32 ui32Index; -+ -+ /* List head for subhandles of this handle */ -+ struct sHandleList sChildren; -+ -+ /* List entry for sibling subhandles */ -+ struct sHandleList sSiblings; -+}; -+ -+/* Handle array index structure. -+ * The handle array is an array of index structures, reallocated as the number of -+ * handles increases. -+ * NOTE: There is one index structure per block of handles. -+ */ -+struct sHandleIndex -+{ -+ /* Pointer to first handle structure in the block */ -+ struct sHandle *psHandle; -+ -+ /* Block allocation cookie returned from OSAllocMem for the block of handles */ -+ IMG_HANDLE hBlockAlloc; -+ -+ /* Number of free handles in block */ -+ IMG_UINT32 ui32FreeHandBlockCount; -+}; -+ -+struct _PVRSRV_HANDLE_BASE_ -+{ -+ /* Handle returned from OSAllocMem for handle base allocation */ -+ IMG_HANDLE hBaseBlockAlloc; -+ -+ /* Handle returned from OSAllocMem for handle array allocation */ -+ IMG_HANDLE hArrayBlockAlloc; -+ -+ /* Pointer to array of pointers to handle structures */ -+ struct sHandleIndex *psHandleArray; -+ -+ /* -+ * Pointer to handle hash table. -+ * The hash table is used to do reverse lookups, converting data -+ * pointers to handles. -+ */ -+ HASH_TABLE *psHashTab; -+ -+ /* Number of free handles */ -+ IMG_UINT32 ui32FreeHandCount; -+ -+ /* -+ * If purging is not enabled, this is the array index of first free -+ * handle. -+ * If purging is enabled, this is the index to start searching for -+ * a free handle from. In this case it is usually zero, unless -+ * the handle array size has been increased due to lack of -+ * handles. -+ */ -+ IMG_UINT32 ui32FirstFreeIndex; -+ -+ /* Maximum handle index, plus one */ -+ IMG_UINT32 ui32MaxIndexPlusOne; -+ -+ /* Total number of handles, free and allocated */ -+ IMG_UINT32 ui32TotalHandCount; -+ -+ /* -+ * Index of the last free index, plus one. Not used if purging -+ * is enabled. -+ */ -+ IMG_UINT32 ui32LastFreeIndexPlusOne; -+ -+ /* Size of current handle batch, or zero if batching not enabled */ -+ IMG_UINT32 ui32HandBatchSize; -+ -+ /* Number of handles prior to start of current batch */ -+ IMG_UINT32 ui32TotalHandCountPreBatch; -+ -+ /* Index of first handle in batch, plus one */ -+ IMG_UINT32 ui32FirstBatchIndexPlusOne; -+ -+ /* Number of handle allocation failures in batch */ -+ IMG_UINT32 ui32BatchHandAllocFailures; -+ -+ /* Purging enabled. -+ * If purging is enabled, the size of the table can be reduced -+ * by removing free space at the end of the table. To make -+ * purging more likely to succeed, handles are allocated as -+ * far to the front of the table as possible. The first free -+ * handle is found by a linear search from the start of the table, -+ * and so no free handle list management is done. -+ */ -+ IMG_BOOL bPurgingEnabled; -+}; -+ -+/* -+ * The key for the handle hash table is an array of three elements, the -+ * pointer to the resource, the resource type, and the process ID. The -+ * eHandKey enumeration gives the array indices of the elements making -+ * up the key. -+ */ -+enum eHandKey { -+ HAND_KEY_DATA = 0, -+ HAND_KEY_TYPE, -+ HAND_KEY_PARENT, -+ HAND_KEY_LEN /* Must be last item in list */ -+}; -+ -+/* -+ * Kernel handle base structure. For handles that are not allocated on -+ * behalf of a particular process -+ */ -+PVRSRV_HANDLE_BASE *gpsKernelHandleBase = IMG_NULL; -+ -+/* HAND_KEY is the type of the hash table key */ -+typedef IMG_UINTPTR_T HAND_KEY[HAND_KEY_LEN]; -+ -+/*! -+****************************************************************************** -+ -+ @Function HandleListInit -+ -+ @Description Initialise a linked list structure embedded in a handle -+ structure. -+ -+ @Input ui32Index - index of handle in the handle array -+ psList - pointer to linked list structure -+ hParent - parent handle, or IMG_NULL -+ -+******************************************************************************/ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(HandleListInit) -+#endif -+static INLINE -+IMG_VOID HandleListInit(IMG_UINT32 ui32Index, struct sHandleList *psList, IMG_HANDLE hParent) -+{ -+ psList->ui32Next = ui32Index; -+ psList->ui32Prev = ui32Index; -+ psList->hParent = hParent; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function InitParentList -+ -+ @Description Initialise the children list head in a handle structure. -+ The children are the subhandles of this handle. -+ -+ @Input psHandle - pointer to handle structure -+ -+******************************************************************************/ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(InitParentList) -+#endif -+static INLINE -+IMG_VOID InitParentList(struct sHandle *psHandle) -+{ -+ IMG_UINT32 ui32Parent = HANDLE_PTR_TO_INDEX(psHandle); -+ -+ HandleListInit(ui32Parent, &psHandle->sChildren, INDEX_TO_HANDLE(ui32Parent)); -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function InitChildEntry -+ -+ @Description Initialise the child list entry in a handle structure. -+ The list entry is used to link together subhandles of -+ a given handle. -+ -+ @Input psHandle - pointer to handle structure -+ -+******************************************************************************/ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(InitChildEntry) -+#endif -+static INLINE -+IMG_VOID InitChildEntry(struct sHandle *psHandle) -+{ -+ HandleListInit(HANDLE_PTR_TO_INDEX(psHandle), &psHandle->sSiblings, IMG_NULL); -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function HandleListIsEmpty -+ -+ @Description Determine whether a given linked list is empty. -+ -+ @Input ui32Index - index of the handle containing the list head -+ psList - pointer to the list head -+ -+ @Return IMG_TRUE if the list is empty, IMG_FALSE if it isn't. -+ -+******************************************************************************/ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(HandleListIsEmpty) -+#endif -+static INLINE -+IMG_BOOL HandleListIsEmpty(IMG_UINT32 ui32Index, struct sHandleList *psList) -+{ -+ IMG_BOOL bIsEmpty; -+ -+ bIsEmpty = (IMG_BOOL)(psList->ui32Next == ui32Index); -+ -+#ifdef DEBUG -+ { -+ IMG_BOOL bIsEmpty2; -+ -+ bIsEmpty2 = (IMG_BOOL)(psList->ui32Prev == ui32Index); -+ PVR_ASSERT(bIsEmpty == bIsEmpty2); -+ } -+#endif -+ -+ return bIsEmpty; -+} -+ -+#ifdef DEBUG -+/*! -+****************************************************************************** -+ -+ @Function NoChildren -+ -+ @Description Determine whether a handle has any subhandles -+ -+ @Input psHandle - pointer to handle structure -+ -+ @Return IMG_TRUE if the handle has no subhandles, IMG_FALSE if it does. -+ -+******************************************************************************/ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(NoChildren) -+#endif -+static INLINE -+IMG_BOOL NoChildren(struct sHandle *psHandle) -+{ -+ PVR_ASSERT(psHandle->sChildren.hParent == HANDLE_PTR_TO_HANDLE(psHandle)); -+ -+ return HandleListIsEmpty(HANDLE_PTR_TO_INDEX(psHandle), &psHandle->sChildren); -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function NoParent -+ -+ @Description Determine whether a handle is a subhandle -+ -+ @Input psHandle - pointer to handle structure -+ -+ @Return IMG_TRUE if the handle is not a subhandle, IMG_FALSE if it is. -+ -+******************************************************************************/ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(NoParent) -+#endif -+static INLINE -+IMG_BOOL NoParent(struct sHandle *psHandle) -+{ -+ if (HandleListIsEmpty(HANDLE_PTR_TO_INDEX(psHandle), &psHandle->sSiblings)) -+ { -+ PVR_ASSERT(psHandle->sSiblings.hParent == IMG_NULL); -+ -+ return IMG_TRUE; -+ } -+ else -+ { -+ PVR_ASSERT(psHandle->sSiblings.hParent != IMG_NULL); -+ } -+ return IMG_FALSE; -+} -+#endif /*DEBUG*/ -+/*! -+****************************************************************************** -+ -+ @Function ParentHandle -+ -+ @Description Determine the parent of a handle -+ -+ @Input psHandle - pointer to handle structure -+ -+ @Return Parent handle, or IMG_NULL if the handle is not a subhandle. -+ -+******************************************************************************/ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(ParentHandle) -+#endif -+static INLINE -+IMG_HANDLE ParentHandle(struct sHandle *psHandle) -+{ -+ return psHandle->sSiblings.hParent; -+} -+ -+/* -+ * The LIST_PTR_FROM_INDEX_AND_OFFSET macro is used to generate either a -+ * pointer to the subhandle list head, or a pointer to the linked list -+ * structure of an item on a subhandle list. -+ * The list head is itself on the list, but is at a different offset -+ * in the handle structure to the linked list structure for items on -+ * the list. The two linked list structures are differentiated by -+ * the third parameter, containing the parent index. The parent field -+ * in the list head structure references the handle structure that contains -+ * it. For items on the list, the parent field in the linked list structure -+ * references the parent handle, which will be different from the handle -+ * containing the linked list structure. -+ */ -+#define LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, i, p, po, eo) \ -+ ((struct sHandleList *)((IMG_CHAR *)(INDEX_TO_HANDLE_STRUCT_PTR(psBase, i)) + (((i) == (p)) ? (po) : (eo)))) -+ -+/*! -+****************************************************************************** -+ -+ @Function HandleListInsertBefore -+ -+ @Description Insert a handle before a handle currently on the list. -+ -+ @Input ui32InsIndex - index of handle to be inserted after -+ psIns - pointer to handle structure to be inserted after -+ uiParentOffset - offset to list head struct in handle structure -+ ui32EntryIndex - index of handle to be inserted -+ psEntry - pointer to handle structure of item to be inserted -+ uiEntryOffset - offset of list item struct in handle structure -+ -+******************************************************************************/ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(HandleListInsertBefore) -+#endif -+static INLINE -+IMG_VOID HandleListInsertBefore(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32InsIndex, struct sHandleList *psIns, IMG_SIZE_T uiParentOffset, IMG_UINT32 ui32EntryIndex, struct sHandleList *psEntry, IMG_SIZE_T uiEntryOffset, IMG_UINT32 ui32ParentIndex) -+{ -+ /* PRQA S 3305 7 */ /*override stricter alignment warning */ -+ struct sHandleList *psPrevIns = LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, psIns->ui32Prev, ui32ParentIndex, uiParentOffset, uiEntryOffset); -+ -+ PVR_ASSERT(psEntry->hParent == IMG_NULL); -+ PVR_ASSERT(ui32InsIndex == psPrevIns->ui32Next); -+ PVR_ASSERT(LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, ui32ParentIndex, ui32ParentIndex, uiParentOffset, uiParentOffset)->hParent == INDEX_TO_HANDLE(ui32ParentIndex)); -+ -+ psEntry->ui32Prev = psIns->ui32Prev; -+ psIns->ui32Prev = ui32EntryIndex; -+ psEntry->ui32Next = ui32InsIndex; -+ psPrevIns->ui32Next = ui32EntryIndex; -+ -+ psEntry->hParent = INDEX_TO_HANDLE(ui32ParentIndex); -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function AdoptChild -+ -+ @Description Assign a subhandle to a handle -+ -+ @Input psParent - pointer to handle structure of parent handle -+ psChild - pointer to handle structure of child subhandle -+ -+******************************************************************************/ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(AdoptChild) -+#endif -+static INLINE -+IMG_VOID AdoptChild(PVRSRV_HANDLE_BASE *psBase, struct sHandle *psParent, struct sHandle *psChild) -+{ -+ IMG_UINT32 ui32Parent = HANDLE_TO_INDEX(psParent->sChildren.hParent); -+ -+ PVR_ASSERT(ui32Parent == HANDLE_PTR_TO_INDEX(psParent)); -+ -+ HandleListInsertBefore(psBase, ui32Parent, &psParent->sChildren, offsetof(struct sHandle, sChildren), HANDLE_PTR_TO_INDEX(psChild), &psChild->sSiblings, offsetof(struct sHandle, sSiblings), ui32Parent); -+ -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function HandleListRemove -+ -+ @Description Remove a handle from a list -+ -+ @Input ui32EntryIndex - index of handle to be removed -+ psEntry - pointer to handle structure of item to be removed -+ uiEntryOffset - offset of list item struct in handle structure -+ uiParentOffset - offset to list head struct in handle structure -+ -+******************************************************************************/ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(HandleListRemove) -+#endif -+static INLINE -+IMG_VOID HandleListRemove(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32EntryIndex, struct sHandleList *psEntry, IMG_SIZE_T uiEntryOffset, IMG_SIZE_T uiParentOffset) -+{ -+ if (!HandleListIsEmpty(ui32EntryIndex, psEntry)) -+ { -+ /* PRQA S 3305 3 */ /*override stricter alignment warning */ -+ struct sHandleList *psPrev = LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, psEntry->ui32Prev, HANDLE_TO_INDEX(psEntry->hParent), uiParentOffset, uiEntryOffset); -+ struct sHandleList *psNext = LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, psEntry->ui32Next, HANDLE_TO_INDEX(psEntry->hParent), uiParentOffset, uiEntryOffset); -+ -+ /* -+ * The list head is on the list, and we don't want to -+ * remove it. -+ */ -+ PVR_ASSERT(psEntry->hParent != IMG_NULL); -+ -+ psPrev->ui32Next = psEntry->ui32Next; -+ psNext->ui32Prev = psEntry->ui32Prev; -+ -+ HandleListInit(ui32EntryIndex, psEntry, IMG_NULL); -+ } -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function UnlinkFromParent -+ -+ @Description Remove a subhandle from its parents list -+ -+ @Input psHandle - pointer to handle structure of child subhandle -+ -+******************************************************************************/ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(UnlinkFromParent) -+#endif -+static INLINE -+IMG_VOID UnlinkFromParent(PVRSRV_HANDLE_BASE *psBase, struct sHandle *psHandle) -+{ -+ HandleListRemove(psBase, HANDLE_PTR_TO_INDEX(psHandle), &psHandle->sSiblings, offsetof(struct sHandle, sSiblings), offsetof(struct sHandle, sChildren)); -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function HandleListIterate -+ -+ @Description Iterate over the items in a list -+ -+ @Input psHead - pointer to list head -+ uiParentOffset - offset to list head struct in handle structure -+ uiEntryOffset - offset of list item struct in handle structure -+ pfnIterFunc - function to be called for each handle in the list -+ -+******************************************************************************/ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(HandleListIterate) -+#endif -+static INLINE -+PVRSRV_ERROR HandleListIterate(PVRSRV_HANDLE_BASE *psBase, struct sHandleList *psHead, IMG_SIZE_T uiParentOffset, IMG_SIZE_T uiEntryOffset, PVRSRV_ERROR (*pfnIterFunc)(PVRSRV_HANDLE_BASE *, struct sHandle *)) -+{ -+ IMG_UINT32 ui32Index; -+ IMG_UINT32 ui32Parent = HANDLE_TO_INDEX(psHead->hParent); -+ -+ PVR_ASSERT(psHead->hParent != IMG_NULL); -+ -+ /* -+ * Follow the next chain from the list head until we reach -+ * the list head again, which signifies the end of the list. -+ */ -+ for(ui32Index = psHead->ui32Next; ui32Index != ui32Parent; ) -+ { -+ struct sHandle *psHandle = INDEX_TO_HANDLE_STRUCT_PTR(psBase, ui32Index); -+ /* PRQA S 3305 2 */ /*override stricter alignment warning */ -+ struct sHandleList *psEntry = LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, ui32Index, ui32Parent, uiParentOffset, uiEntryOffset); -+ PVRSRV_ERROR eError; -+ -+ PVR_ASSERT(psEntry->hParent == psHead->hParent); -+ /* -+ * Get the next index now, in case the list item is -+ * modified by the iteration function. -+ */ -+ ui32Index = psEntry->ui32Next; -+ -+ eError = (*pfnIterFunc)(psBase, psHandle); -+ if (eError != PVRSRV_OK) -+ { -+ return eError; -+ } -+ } -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function IterateOverChildren -+ -+ @Description Iterate over the subhandles of a parent handle -+ -+ @Input psParent - pointer to parent handle structure -+ pfnIterFunc - function to be called for each subhandle -+ -+******************************************************************************/ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(IterateOverChildren) -+#endif -+static INLINE -+PVRSRV_ERROR IterateOverChildren(PVRSRV_HANDLE_BASE *psBase, struct sHandle *psParent, PVRSRV_ERROR (*pfnIterFunc)(PVRSRV_HANDLE_BASE *, struct sHandle *)) -+{ -+ return HandleListIterate(psBase, &psParent->sChildren, offsetof(struct sHandle, sChildren), offsetof(struct sHandle, sSiblings), pfnIterFunc); -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function GetHandleStructure -+ -+ @Description Get the handle structure for a given handle -+ -+ @Input psBase - pointer to handle base structure -+ ppsHandle - location to return pointer to handle structure -+ hHandle - handle from client -+ eType - handle type or PVRSRV_HANDLE_TYPE_NONE if the -+ handle type is not to be checked. -+ -+ @Output ppsHandle - points to a pointer to the handle structure -+ -+ @Return Error code or PVRSRV_OK -+ -+******************************************************************************/ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(GetHandleStructure) -+#endif -+static INLINE -+PVRSRV_ERROR GetHandleStructure(PVRSRV_HANDLE_BASE *psBase, struct sHandle **ppsHandle, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType) -+{ -+ IMG_UINT32 ui32Index = HANDLE_TO_INDEX(hHandle); -+ struct sHandle *psHandle; -+ -+ /* Check handle index is in range */ -+ if (!INDEX_IS_VALID(psBase, ui32Index)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "GetHandleStructure: Handle index out of range (%u >= %u)", ui32Index, psBase->ui32TotalHandCount)); -+ return PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE; -+ } -+ -+ psHandle = INDEX_TO_HANDLE_STRUCT_PTR(psBase, ui32Index); -+ if (psHandle->eType == PVRSRV_HANDLE_TYPE_NONE) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "GetHandleStructure: Handle not allocated (index: %u)", ui32Index)); -+ return PVRSRV_ERROR_HANDLE_NOT_ALLOCATED; -+ } -+ -+ /* -+ * Unless PVRSRV_HANDLE_TYPE_NONE was passed in to this function, -+ * check handle is of the correct type. -+ */ -+ if (eType != PVRSRV_HANDLE_TYPE_NONE && eType != psHandle->eType) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "GetHandleStructure: Handle type mismatch (%d != %d)", eType, psHandle->eType)); -+ return PVRSRV_ERROR_HANDLE_TYPE_MISMATCH; -+ } -+ -+ /* Return the handle structure */ -+ *ppsHandle = psHandle; -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function ParentIfPrivate -+ -+ @Description Return the parent handle if the handle was allocated -+ with PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE, else return -+ IMG_NULL -+ -+ @Input psHandle - pointer to handle -+ -+ @Return Parent handle, or IMG_NULL -+ -+******************************************************************************/ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(ParentIfPrivate) -+#endif -+static INLINE -+IMG_HANDLE ParentIfPrivate(struct sHandle *psHandle) -+{ -+ return TEST_ALLOC_FLAG(psHandle, PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE) ? -+ ParentHandle(psHandle) : IMG_NULL; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function InitKey -+ -+ @Description Initialise a hash table key for the current process -+ -+ @Input psBase - pointer to handle base structure -+ aKey - pointer to key -+ pvData - pointer to the resource the handle represents -+ eType - type of resource -+ -+******************************************************************************/ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(InitKey) -+#endif -+static INLINE -+IMG_VOID InitKey(HAND_KEY aKey, PVRSRV_HANDLE_BASE *psBase, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, IMG_HANDLE hParent) -+{ -+ PVR_UNREFERENCED_PARAMETER(psBase); -+ -+ aKey[HAND_KEY_DATA] = (IMG_UINTPTR_T)pvData; -+ aKey[HAND_KEY_TYPE] = (IMG_UINTPTR_T)eType; -+ aKey[HAND_KEY_PARENT] = (IMG_UINTPTR_T)hParent; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function ReallocHandleArray -+ -+ @Description Reallocate the handle array -+ -+ @Input psBase - handle base. -+ phBlockAlloc - pointer to block allocation handle. -+ ui32NewCount - new handle count -+ ui32OldCount - old handle count -+ -+ @Return Error code or PVRSRV_OK -+ -+******************************************************************************/ -+static -+PVRSRV_ERROR ReallocHandleArray(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32NewCount) -+{ -+ struct sHandleIndex *psOldArray = psBase->psHandleArray; -+ IMG_HANDLE hOldArrayBlockAlloc = psBase->hArrayBlockAlloc; -+ IMG_UINT32 ui32OldCount = psBase->ui32TotalHandCount; -+ struct sHandleIndex *psNewArray = IMG_NULL; -+ IMG_HANDLE hNewArrayBlockAlloc = IMG_NULL; -+ PVRSRV_ERROR eError; -+ PVRSRV_ERROR eReturn = PVRSRV_OK; -+ IMG_UINT32 ui32Index; -+ -+ if (ui32NewCount == ui32OldCount) -+ { -+ return PVRSRV_OK; -+ } -+ -+ if (ui32NewCount != 0 && !psBase->bPurgingEnabled && -+ ui32NewCount < ui32OldCount) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ if (((ui32OldCount % HANDLE_BLOCK_SIZE) != 0) || -+ ((ui32NewCount % HANDLE_BLOCK_SIZE) != 0)) -+ { -+ PVR_ASSERT((ui32OldCount % HANDLE_BLOCK_SIZE) == 0); -+ PVR_ASSERT((ui32NewCount % HANDLE_BLOCK_SIZE) == 0); -+ -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ if (ui32NewCount != 0) -+ { -+ /* Allocate new handle array */ -+ eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, -+ HANDLE_ARRAY_SIZE(ui32NewCount) * sizeof(struct sHandleIndex), -+ (IMG_VOID **)&psNewArray, -+ &hNewArrayBlockAlloc, -+ "Memory Area"); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Couldn't allocate new handle array (%d)", eError)); -+ eReturn = eError; -+ goto error; -+ } -+ -+ if (ui32OldCount != 0) -+ { -+ OSMemCopy(psNewArray, psOldArray, HANDLE_ARRAY_SIZE(MIN(ui32NewCount, ui32OldCount)) * sizeof(struct sHandleIndex)); -+ } -+ } -+ -+ /* -+ * If the new handle array is smaller than the old one, free -+ * unused handle structures -+ */ -+ for(ui32Index = ui32NewCount; ui32Index < ui32OldCount; ui32Index += HANDLE_BLOCK_SIZE) -+ { -+ struct sHandleIndex *psIndex = INDEX_TO_INDEX_STRUCT_PTR(psOldArray, ui32Index); -+ -+ eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(struct sHandle) * HANDLE_BLOCK_SIZE, -+ psIndex->psHandle, -+ psIndex->hBlockAlloc); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Couldn't free handle structures (%d)", eError)); -+ } -+ } -+ -+ /* -+ * If the new handle array is bigger than the old one, allocate -+ * new handle structures -+ */ -+ for(ui32Index = ui32OldCount; ui32Index < ui32NewCount; ui32Index += HANDLE_BLOCK_SIZE) -+ { -+ /* PRQA S 0505 1 */ /* psNewArray is never NULL, see assert earlier */ -+ struct sHandleIndex *psIndex = INDEX_TO_INDEX_STRUCT_PTR(psNewArray, ui32Index); -+ -+ eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, -+ sizeof(struct sHandle) * HANDLE_BLOCK_SIZE, -+ (IMG_VOID **)&psIndex->psHandle, -+ &psIndex->hBlockAlloc, -+ "Memory Area"); -+ if (eError != PVRSRV_OK) -+ { -+ psIndex->psHandle = IMG_NULL; -+ PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Couldn't allocate handle structures (%d)", eError)); -+ eReturn = eError; -+ } -+ else -+ { -+ IMG_UINT32 ui32SubIndex; -+ -+ psIndex->ui32FreeHandBlockCount = HANDLE_BLOCK_SIZE; -+ -+ for(ui32SubIndex = 0; ui32SubIndex < HANDLE_BLOCK_SIZE; ui32SubIndex++) -+ { -+ struct sHandle *psHandle = psIndex->psHandle + ui32SubIndex; -+ -+ -+ psHandle->ui32Index = ui32SubIndex + ui32Index; -+ psHandle->eType = PVRSRV_HANDLE_TYPE_NONE; -+ psHandle->eInternalFlag = INTERNAL_HANDLE_FLAG_NONE; -+ psHandle->ui32NextIndexPlusOne = 0; -+ } -+ } -+ } -+ if (eReturn != PVRSRV_OK) -+ { -+ goto error; -+ } -+ -+#ifdef DEBUG_MAX_HANDLE_COUNT -+ /* Force handle failure to test error exit code */ -+ if (ui32NewCount > DEBUG_MAX_HANDLE_COUNT) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Max handle count (%u) reached", DEBUG_MAX_HANDLE_COUNT)); -+ eReturn = PVRSRV_ERROR_OUT_OF_MEMORY; -+ goto error; -+ } -+#endif -+ -+ if (psOldArray != IMG_NULL) -+ { -+ /* Free old handle array */ -+ eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, -+ HANDLE_ARRAY_SIZE(ui32OldCount) * sizeof(struct sHandleIndex), -+ psOldArray, -+ hOldArrayBlockAlloc); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Couldn't free old handle array (%d)", eError)); -+ } -+ } -+ -+ psBase->psHandleArray = psNewArray; -+ psBase->hArrayBlockAlloc = hNewArrayBlockAlloc; -+ psBase->ui32TotalHandCount = ui32NewCount; -+ -+ if (ui32NewCount > ui32OldCount) -+ { -+ /* Check for wraparound */ -+ PVR_ASSERT(psBase->ui32FreeHandCount + (ui32NewCount - ui32OldCount) > psBase->ui32FreeHandCount); -+ -+ /* PRQA S 3382 1 */ /* ui32NewCount always > ui32OldCount */ -+ psBase->ui32FreeHandCount += (ui32NewCount - ui32OldCount); -+ -+ /* -+ * If purging is enabled, there is no free handle list -+ * management, but as an optimization, when allocating -+ * new handles, we use ui32FirstFreeIndex to point to -+ * the first handle in a newly allocated block. -+ */ -+ if (psBase->ui32FirstFreeIndex == 0) -+ { -+ PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne == 0); -+ -+ psBase->ui32FirstFreeIndex = ui32OldCount; -+ } -+ else -+ { -+ if (!psBase->bPurgingEnabled) -+ { -+ PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne != 0); -+ PVR_ASSERT(INDEX_TO_HANDLE_STRUCT_PTR(psBase, psBase->ui32LastFreeIndexPlusOne - 1)->ui32NextIndexPlusOne == 0); -+ -+ INDEX_TO_HANDLE_STRUCT_PTR(psBase, psBase->ui32LastFreeIndexPlusOne - 1)->ui32NextIndexPlusOne = ui32OldCount + 1; -+ } -+ } -+ -+ if (!psBase->bPurgingEnabled) -+ { -+ psBase->ui32LastFreeIndexPlusOne = ui32NewCount; -+ } -+ } -+ else -+ { -+ PVR_ASSERT(ui32NewCount == 0 || psBase->bPurgingEnabled); -+ PVR_ASSERT(ui32NewCount == 0 || psBase->ui32FirstFreeIndex <= ui32NewCount); -+ PVR_ASSERT(psBase->ui32FreeHandCount - (ui32OldCount - ui32NewCount) < psBase->ui32FreeHandCount); -+ -+ /* PRQA S 3382 1 */ /* ui32OldCount always >= ui32NewCount */ -+ psBase->ui32FreeHandCount -= (ui32OldCount - ui32NewCount); -+ -+ if (ui32NewCount == 0) -+ { -+ psBase->ui32FirstFreeIndex = 0; -+ psBase->ui32LastFreeIndexPlusOne = 0; -+ } -+ } -+ -+ PVR_ASSERT(psBase->ui32FirstFreeIndex <= psBase->ui32TotalHandCount); -+ -+ return PVRSRV_OK; -+ -+error: -+ PVR_ASSERT(eReturn != PVRSRV_OK); -+ -+ if (psNewArray != IMG_NULL) -+ { -+ /* Free any new handle structures that were allocated */ -+ for(ui32Index = ui32OldCount; ui32Index < ui32NewCount; ui32Index += HANDLE_BLOCK_SIZE) -+ { -+ struct sHandleIndex *psIndex = INDEX_TO_INDEX_STRUCT_PTR(psNewArray, ui32Index); -+ if (psIndex->psHandle != IMG_NULL) -+ { -+ eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(struct sHandle) * HANDLE_BLOCK_SIZE, -+ psIndex->psHandle, -+ psIndex->hBlockAlloc); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Couldn't free handle structures (%d)", eError)); -+ } -+ } -+ } -+ -+ /* Free new handle array */ -+ eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, -+ HANDLE_ARRAY_SIZE(ui32NewCount) * sizeof(struct sHandleIndex), -+ psNewArray, -+ hNewArrayBlockAlloc); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "ReallocHandleArray: Couldn't free new handle array (%d)", eError)); -+ } -+ } -+ -+ return eReturn; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function FreeHandleArray -+ -+ @Description Frees the handle array. -+ The memory containing the array of handle structure -+ pointers is deallocated. -+ -+ @Input psBase - pointer to handle base structure -+ -+ @Return Error code or PVRSRV_OK -+ -+******************************************************************************/ -+static PVRSRV_ERROR FreeHandleArray(PVRSRV_HANDLE_BASE *psBase) -+{ -+ return ReallocHandleArray(psBase, 0); -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function FreeHandle -+ -+ @Description Free a handle structure. -+ -+ @Input psBase - pointer to handle base structure -+ psHandle - pointer to handle structure -+ -+ @Return PVRSRV_OK or PVRSRV_ERROR -+ -+******************************************************************************/ -+static PVRSRV_ERROR FreeHandle(PVRSRV_HANDLE_BASE *psBase, struct sHandle *psHandle) -+{ -+ HAND_KEY aKey; -+ IMG_UINT32 ui32Index = HANDLE_PTR_TO_INDEX(psHandle); -+ PVRSRV_ERROR eError; -+ -+ /* -+ * If a handle allocated in batch mode is freed whilst still -+ * in batch mode, the type is set to PVRSRV_HANDLE_TYPE_NONE further -+ * down, to indicate the handle will not be used, but not actually -+ * freed. The Free is completed when this function is called a -+ * second time as part of the batch commit or release. -+ */ -+ -+ InitKey(aKey, psBase, psHandle->pvData, psHandle->eType, ParentIfPrivate(psHandle)); -+ -+ if (!TEST_ALLOC_FLAG(psHandle, PVRSRV_HANDLE_ALLOC_FLAG_MULTI) && !BATCHED_HANDLE_PARTIALLY_FREE(psHandle)) -+ { -+ IMG_HANDLE hHandle; -+ hHandle = (IMG_HANDLE) HASH_Remove_Extended(psBase->psHashTab, aKey); -+ -+ -+ PVR_ASSERT(hHandle != IMG_NULL); -+ PVR_ASSERT(hHandle == INDEX_TO_HANDLE(ui32Index)); -+ PVR_UNREFERENCED_PARAMETER(hHandle); -+ } -+ -+ /* Unlink handle from parent */ -+ UnlinkFromParent(psBase, psHandle); -+ -+ /* Free children */ -+ eError = IterateOverChildren(psBase, psHandle, FreeHandle); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "FreeHandle: Error whilst freeing subhandles (%d)", eError)); -+ return eError; -+ } -+ -+ /* -+ * Clear the type here, so that a handle can no longer be looked -+ * up if it is only partially freed. -+ */ -+ psHandle->eType = PVRSRV_HANDLE_TYPE_NONE; -+ -+ if (BATCHED_HANDLE(psHandle) && !BATCHED_HANDLE_PARTIALLY_FREE(psHandle)) -+ { -+ /* PRQA S 1474,4130 1 */ /* ignore warnings about enum types being modified */ -+ SET_BATCHED_HANDLE_PARTIALLY_FREE(psHandle); -+ /* -+ * If the handle was allocated in batch mode, delay the free -+ * until the batch commit or release. -+ */ -+ return PVRSRV_OK; -+ } -+ -+ /* No free list management if purging is enabled */ -+ if (!psBase->bPurgingEnabled) -+ { -+ if (psBase->ui32FreeHandCount == 0) -+ { -+ PVR_ASSERT(psBase->ui32FirstFreeIndex == 0); -+ PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne == 0); -+ -+ psBase->ui32FirstFreeIndex = ui32Index; -+ } -+ else -+ { -+ /* -+ * Put the handle pointer on the end of the the free -+ * handle pointer linked list. -+ */ -+ PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne != 0); -+ PVR_ASSERT(INDEX_TO_HANDLE_STRUCT_PTR(psBase, psBase->ui32LastFreeIndexPlusOne - 1)->ui32NextIndexPlusOne == 0); -+ INDEX_TO_HANDLE_STRUCT_PTR(psBase, psBase->ui32LastFreeIndexPlusOne - 1)->ui32NextIndexPlusOne = ui32Index + 1; -+ } -+ -+ PVR_ASSERT(psHandle->ui32NextIndexPlusOne == 0); -+ -+ /* Update the end of the free handle linked list */ -+ psBase->ui32LastFreeIndexPlusOne = ui32Index + 1; -+ } -+ -+ psBase->ui32FreeHandCount++; -+ INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, ui32Index)++; -+ -+ PVR_ASSERT(INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, ui32Index)<= HANDLE_BLOCK_SIZE); -+ -+#ifdef DEBUG -+ { -+ IMG_UINT32 ui32BlockedIndex; -+ IMG_UINT32 ui32FreeHandCount = 0; -+ -+ for (ui32BlockedIndex = 0; ui32BlockedIndex < psBase->ui32TotalHandCount; ui32BlockedIndex += HANDLE_BLOCK_SIZE) -+ { -+ ui32FreeHandCount += INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, ui32BlockedIndex); -+ } -+ -+ PVR_ASSERT(ui32FreeHandCount == psBase->ui32FreeHandCount); -+ } -+#endif -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function FreeAllHandles -+ -+ @Description Free all handles for a given handle base -+ -+ @Input psBase - pointer to handle base structure -+ -+ @Return PVRSRV_OK or PVRSRV_ERROR -+ -+******************************************************************************/ -+static PVRSRV_ERROR FreeAllHandles(PVRSRV_HANDLE_BASE *psBase) -+{ -+ IMG_UINT32 i; -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ -+ if (psBase->ui32FreeHandCount == psBase->ui32TotalHandCount) -+ { -+ return eError; -+ } -+ -+ for (i = 0; i < psBase->ui32TotalHandCount; i++) -+ { -+ struct sHandle *psHandle; -+ -+ psHandle = INDEX_TO_HANDLE_STRUCT_PTR(psBase, i); -+ -+ if (psHandle->eType != PVRSRV_HANDLE_TYPE_NONE) -+ { -+ eError = FreeHandle(psBase, psHandle); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "FreeAllHandles: FreeHandle failed (%d)", eError)); -+ break; -+ } -+ -+ /* Break out of loop if all the handles free */ -+ if (psBase->ui32FreeHandCount == psBase->ui32TotalHandCount) -+ { -+ break; -+ } -+ } -+ } -+ -+ return eError; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function FreeHandleBase -+ -+ @Description Free a handle base. -+ -+ @Input psHandleBase - pointer to handle base -+ -+ @Return Error code or PVRSRV_OK -+ -+******************************************************************************/ -+static PVRSRV_ERROR FreeHandleBase(PVRSRV_HANDLE_BASE *psBase) -+{ -+ PVRSRV_ERROR eError; -+ -+ if (HANDLES_BATCHED(psBase)) -+ { -+ PVR_DPF((PVR_DBG_WARNING, "FreeHandleBase: Uncommitted/Unreleased handle batch")); -+ PVRSRVReleaseHandleBatch(psBase); -+ } -+ -+ /* Free the handle array */ -+ eError = FreeAllHandles(psBase); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "FreeHandleBase: Couldn't free handles (%d)", eError)); -+ return eError; -+ } -+ -+ /* Free the handle array */ -+ eError = FreeHandleArray(psBase); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "FreeHandleBase: Couldn't free handle array (%d)", eError)); -+ return eError; -+ } -+ -+ if (psBase->psHashTab != IMG_NULL) -+ { -+ /* Free the hash table */ -+ HASH_Delete(psBase->psHashTab); -+ } -+ -+ eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(*psBase), -+ psBase, -+ psBase->hBaseBlockAlloc); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "FreeHandleBase: Couldn't free handle base (%d)", eError)); -+ return eError; -+ } -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function FindHandle -+ -+ @Description Find handle corresponding to a resource pointer -+ -+ @Input psBase - pointer to handle base structure -+ pvData - pointer to resource to be associated with the handle -+ eType - the type of resource -+ -+ @Return the handle, or IMG_NULL if not found -+ -+******************************************************************************/ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(FindHandle) -+#endif -+static INLINE -+IMG_HANDLE FindHandle(PVRSRV_HANDLE_BASE *psBase, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, IMG_HANDLE hParent) -+{ -+ HAND_KEY aKey; -+ -+ PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE); -+ -+ InitKey(aKey, psBase, pvData, eType, hParent); -+ -+ return (IMG_HANDLE) HASH_Retrieve_Extended(psBase->psHashTab, aKey); -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function IncreaseHandleArraySize -+ -+ @Description Allocate some more free handles -+ -+ @Input psBase - pointer to handle base structure -+ ui32Delta - number of new handles required -+ -+ @Return Error code or PVRSRV_OK -+ -+******************************************************************************/ -+static PVRSRV_ERROR IncreaseHandleArraySize(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32Delta) -+{ -+ PVRSRV_ERROR eError; -+ IMG_UINT32 ui32DeltaAdjusted = ROUND_UP_TO_MULTIPLE_OF_BLOCK_SIZE(ui32Delta); -+ IMG_UINT32 ui32NewTotalHandCount = psBase->ui32TotalHandCount + ui32DeltaAdjusted; -+ -+ PVR_ASSERT(ui32Delta != 0); -+ -+ /* -+ * Check new count against max handle index, and check for wrap around. -+ */ -+ if (ui32NewTotalHandCount > psBase->ui32MaxIndexPlusOne || ui32NewTotalHandCount <= psBase->ui32TotalHandCount) -+ { -+ ui32NewTotalHandCount = psBase->ui32MaxIndexPlusOne; -+ -+ ui32DeltaAdjusted = ui32NewTotalHandCount - psBase->ui32TotalHandCount; -+ -+ if (ui32DeltaAdjusted < ui32Delta) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "IncreaseHandleArraySize: Maximum handle limit reached (%d)", psBase->ui32MaxIndexPlusOne)); -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ } -+ -+ PVR_ASSERT(ui32DeltaAdjusted >= ui32Delta); -+ -+ /* Realloc handle pointer array */ -+ eError = ReallocHandleArray(psBase, ui32NewTotalHandCount); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "IncreaseHandleArraySize: ReallocHandleArray failed (%d)", eError)); -+ return eError; -+ } -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function EnsureFreeHandles -+ -+ @Description Ensure there are enough free handles -+ -+ @Input psBase - pointer to handle base structure -+ ui32Free - number of free handles required -+ -+ @Return Error code or PVRSRV_OK -+ -+******************************************************************************/ -+static PVRSRV_ERROR EnsureFreeHandles(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32Free) -+{ -+ PVRSRV_ERROR eError; -+ -+ if (ui32Free > psBase->ui32FreeHandCount) -+ { -+ IMG_UINT32 ui32FreeHandDelta = ui32Free - psBase->ui32FreeHandCount; -+ eError = IncreaseHandleArraySize(psBase, ui32FreeHandDelta); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnsureFreeHandles: Couldn't allocate %u handles to ensure %u free handles (IncreaseHandleArraySize failed with error %d)", ui32FreeHandDelta, ui32Free, eError)); -+ -+ return eError; -+ } -+ } -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function AllocHandle -+ -+ @Description Allocate a new handle -+ -+ @Input phHandle - location for new handle -+ pvData - pointer to resource to be associated with the handle -+ eType - the type of resource -+ hParent - parent handle or IMG_NULL -+ -+ @Output phHandle - points to new handle -+ -+ @Return Error code or PVRSRV_OK -+ -+******************************************************************************/ -+static PVRSRV_ERROR AllocHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_HANDLE hParent) -+{ -+ IMG_UINT32 ui32NewIndex = DEFAULT_MAX_INDEX_PLUS_ONE; -+ struct sHandle *psNewHandle = IMG_NULL; -+ IMG_HANDLE hHandle; -+ HAND_KEY aKey; -+ PVRSRV_ERROR eError; -+ -+ /* PVRSRV_HANDLE_TYPE_NONE is reserved for internal use */ -+ PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE); -+ PVR_ASSERT(psBase != IMG_NULL); -+ PVR_ASSERT(psBase->psHashTab != IMG_NULL); -+ -+ if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI)) -+ { -+ /* Handle must not already exist */ -+ PVR_ASSERT(FindHandle(psBase, pvData, eType, hParent) == IMG_NULL); -+ } -+ -+ if (psBase->ui32FreeHandCount == 0 && HANDLES_BATCHED(psBase)) -+ { -+ PVR_DPF((PVR_DBG_WARNING, "AllocHandle: Handle batch size (%u) was too small, allocating additional space", psBase->ui32HandBatchSize)); -+ } -+ -+ /* Ensure there is a free handle */ -+ eError = EnsureFreeHandles(psBase, 1); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "AllocHandle: EnsureFreeHandles failed (%d)", eError)); -+ return eError; -+ } -+ PVR_ASSERT(psBase->ui32FreeHandCount != 0); -+ -+ if (!psBase->bPurgingEnabled) -+ { -+ /* Array index of first free handle */ -+ ui32NewIndex = psBase->ui32FirstFreeIndex; -+ -+ /* Get handle array entry */ -+ psNewHandle = INDEX_TO_HANDLE_STRUCT_PTR(psBase, ui32NewIndex); -+ } -+ else -+ { -+ IMG_UINT32 ui32BlockedIndex; -+ -+ /* -+ * If purging is enabled, we always try to allocate handles -+ * at the front of the array, to increase the chances that -+ * the size of the handle array can be reduced by a purge. -+ * No linked list of free handles is kept; we search for -+ * free handles as required. -+ */ -+ -+ /* -+ * ui32FirstFreeIndex should only be set when a new batch of -+ * handle structures is allocated, and should always be a -+ * multiple of the block size. -+ */ -+ PVR_ASSERT((psBase->ui32FirstFreeIndex % HANDLE_BLOCK_SIZE) == 0); -+ -+ for (ui32BlockedIndex = ROUND_DOWN_TO_MULTIPLE_OF_BLOCK_SIZE(psBase->ui32FirstFreeIndex); ui32BlockedIndex < psBase->ui32TotalHandCount; ui32BlockedIndex += HANDLE_BLOCK_SIZE) -+ { -+ struct sHandleIndex *psIndex = BASE_AND_INDEX_TO_INDEX_STRUCT_PTR(psBase, ui32BlockedIndex); -+ -+ if (psIndex->ui32FreeHandBlockCount == 0) -+ { -+ continue; -+ } -+ -+ for (ui32NewIndex = ui32BlockedIndex; ui32NewIndex < ui32BlockedIndex + HANDLE_BLOCK_SIZE; ui32NewIndex++) -+ { -+ psNewHandle = INDEX_TO_HANDLE_STRUCT_PTR(psBase, ui32NewIndex); -+ if (HANDLE_STRUCT_IS_FREE(psNewHandle)) -+ { -+ break; -+ } -+ } -+ } -+ psBase->ui32FirstFreeIndex = 0; -+ PVR_ASSERT(ui32NewIndex < psBase->ui32TotalHandCount); -+ } -+ PVR_ASSERT(psNewHandle != IMG_NULL); -+ -+ /* Handle to be returned to client */ -+ hHandle = INDEX_TO_HANDLE(ui32NewIndex); -+ -+ /* -+ * If a data pointer can be associated with multiple handles, we -+ * don't put the handle in the hash table, as the data pointer -+ * may not map to a unique handle -+ */ -+ if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI)) -+ { -+ /* Initialise hash key */ -+ InitKey(aKey, psBase, pvData, eType, hParent); -+ -+ /* Put the new handle in the hash table */ -+ if (!HASH_Insert_Extended(psBase->psHashTab, aKey, (IMG_UINTPTR_T)hHandle)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "AllocHandle: Couldn't add handle to hash table")); -+ -+ return PVRSRV_ERROR_UNABLE_TO_ADD_HANDLE; -+ } -+ } -+ -+ psBase->ui32FreeHandCount--; -+ -+ PVR_ASSERT(INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, ui32NewIndex) <= HANDLE_BLOCK_SIZE); -+ PVR_ASSERT(INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, ui32NewIndex) > 0); -+ -+ INDEX_TO_FREE_HAND_BLOCK_COUNT(psBase, ui32NewIndex)--; -+ -+ /* No free list management if purging is enabled */ -+ if (!psBase->bPurgingEnabled) -+ { -+ /* Check whether the last free handle has been allocated */ -+ if (psBase->ui32FreeHandCount == 0) -+ { -+ PVR_ASSERT(psBase->ui32FirstFreeIndex == ui32NewIndex); -+ PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne == (ui32NewIndex + 1)); -+ -+ psBase->ui32LastFreeIndexPlusOne = 0; -+ psBase->ui32FirstFreeIndex = 0; -+ } -+ else -+ { -+ /* -+ * Update the first free handle index. -+ * If the "next free index plus one" field in the new -+ * handle structure is zero, the next free index is -+ * the index of the new handle plus one. This -+ * convention has been adopted to simplify the -+ * initialisation of freshly allocated handle -+ * space. -+ */ -+ psBase->ui32FirstFreeIndex = (psNewHandle->ui32NextIndexPlusOne == 0) ? -+ ui32NewIndex + 1 : -+ psNewHandle->ui32NextIndexPlusOne - 1; -+ } -+ } -+ -+ /* Initialise the newly allocated handle */ -+ PVR_ASSERT(psNewHandle->ui32Index == ui32NewIndex); -+ -+ /* PRQA S 0505 1 */ /* psNewHandle is never NULL, see assert earlier */ -+ psNewHandle->eType = eType; -+ psNewHandle->pvData = pvData; -+ psNewHandle->eInternalFlag = INTERNAL_HANDLE_FLAG_NONE; -+ psNewHandle->eFlag = eFlag; -+ -+ InitParentList(psNewHandle); -+#if defined(DEBUG) -+ PVR_ASSERT(NoChildren(psNewHandle)); -+#endif -+ -+ InitChildEntry(psNewHandle); -+#if defined(DEBUG) -+ PVR_ASSERT(NoParent(psNewHandle)); -+#endif -+ -+ if (HANDLES_BATCHED(psBase)) -+ { -+ /* Add handle to batch list */ -+ psNewHandle->ui32NextIndexPlusOne = psBase->ui32FirstBatchIndexPlusOne; -+ -+ psBase->ui32FirstBatchIndexPlusOne = ui32NewIndex + 1; -+ -+ /* PRQA S 1474 1 */ /* ignore warnings about enum types being modified */ -+ SET_BATCHED_HANDLE(psNewHandle); -+ } -+ else -+ { -+ psNewHandle->ui32NextIndexPlusOne = 0; -+ } -+ -+ /* Return the new handle to the client */ -+ *phHandle = hHandle; -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVAllocHandle -+ -+ @Description Allocate a handle -+ -+ @Input phHandle - location for new handle -+ pvData - pointer to resource to be associated with the handle -+ eType - the type of resource -+ -+ @Output phHandle - points to new handle -+ -+ @Return Error code or PVRSRV_OK -+ -+******************************************************************************/ -+PVRSRV_ERROR PVRSRVAllocHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag) -+{ -+ IMG_HANDLE hHandle; -+ PVRSRV_ERROR eError; -+ -+ *phHandle = IMG_NULL; -+ -+ if (HANDLES_BATCHED(psBase)) -+ { -+ /* -+ * Increment the counter in case of failure. It will be -+ * decremented on success. -+ */ -+ psBase->ui32BatchHandAllocFailures++; -+ } -+ -+ /* PVRSRV_HANDLE_TYPE_NONE is reserved for internal use */ -+ PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE); -+ -+ if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI)) -+ { -+ /* See if there is already a handle for this data pointer */ -+ hHandle = FindHandle(psBase, pvData, eType, IMG_NULL); -+ if (hHandle != IMG_NULL) -+ { -+ struct sHandle *psHandle; -+ -+ eError = GetHandleStructure(psBase, &psHandle, hHandle, eType); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocHandle: Lookup of existing handle failed")); -+ return eError; -+ } -+ -+ /* -+ * If the client is willing to share a handle, and the -+ * existing handle is marked as shareable, return the -+ * existing handle. -+ */ -+ if (TEST_FLAG(psHandle->eFlag & eFlag, PVRSRV_HANDLE_ALLOC_FLAG_SHARED)) -+ { -+ *phHandle = hHandle; -+ eError = PVRSRV_OK; -+ goto exit_ok; -+ } -+ -+ return PVRSRV_ERROR_HANDLE_NOT_SHAREABLE; -+ } -+ } -+ -+ eError = AllocHandle(psBase, phHandle, pvData, eType, eFlag, IMG_NULL); -+ -+exit_ok: -+ if (HANDLES_BATCHED(psBase) && (eError == PVRSRV_OK)) -+ { -+ psBase->ui32BatchHandAllocFailures--; -+ } -+ -+ return eError; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVAllocSubHandle -+ -+ @Description Allocate a subhandle -+ -+ @Input phHandle - location for new subhandle -+ pvData - pointer to resource to be associated with the subhandle -+ eType - the type of resource -+ hParent - parent handle -+ -+ @Output phHandle - points to new subhandle -+ -+ @Return Error code or PVRSRV_OK -+ -+******************************************************************************/ -+PVRSRV_ERROR PVRSRVAllocSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_HANDLE hParent) -+{ -+ struct sHandle *psPHand; -+ struct sHandle *psCHand; -+ PVRSRV_ERROR eError; -+ IMG_HANDLE hParentKey; -+ IMG_HANDLE hHandle; -+ -+ *phHandle = IMG_NULL; -+ -+ if (HANDLES_BATCHED(psBase)) -+ { -+ /* -+ * Increment the counter in case of failure. It will be -+ * decremented on success. -+ */ -+ psBase->ui32BatchHandAllocFailures++; -+ } -+ -+ /* PVRSRV_HANDLE_TYPE_NONE is reserved for internal use */ -+ PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE); -+ -+ hParentKey = TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE) ? -+ hParent : IMG_NULL; -+ -+ /* Lookup the parent handle */ -+ eError = GetHandleStructure(psBase, &psPHand, hParent, PVRSRV_HANDLE_TYPE_NONE); -+ if (eError != PVRSRV_OK) -+ { -+ return eError; -+ } -+ -+ if (!TEST_FLAG(eFlag, PVRSRV_HANDLE_ALLOC_FLAG_MULTI)) -+ { -+ /* See if there is already a handle for this data pointer */ -+ hHandle = FindHandle(psBase, pvData, eType, hParentKey); -+ if (hHandle != IMG_NULL) -+ { -+ struct sHandle *psCHandle; -+ PVRSRV_ERROR eErr; -+ -+ eErr = GetHandleStructure(psBase, &psCHandle, hHandle, eType); -+ if (eErr != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocSubHandle: Lookup of existing handle failed")); -+ return eErr; -+ } -+ -+ PVR_ASSERT(hParentKey != IMG_NULL && ParentHandle(HANDLE_TO_HANDLE_STRUCT_PTR(psBase, hHandle)) == hParent); -+ -+ /* -+ * If the client is willing to share a handle, the -+ * existing handle is marked as shareable, and the -+ * existing handle has the same parent, return the -+ * existing handle. -+ */ -+ if (TEST_FLAG(psCHandle->eFlag & eFlag, PVRSRV_HANDLE_ALLOC_FLAG_SHARED) && ParentHandle(HANDLE_TO_HANDLE_STRUCT_PTR(psBase, hHandle)) == hParent) -+ { -+ *phHandle = hHandle; -+ goto exit_ok; -+ } -+ return PVRSRV_ERROR_HANDLE_NOT_SHAREABLE; -+ } -+ } -+ -+ eError = AllocHandle(psBase, &hHandle, pvData, eType, eFlag, hParentKey); -+ if (eError != PVRSRV_OK) -+ { -+ return eError; -+ } -+ -+ /* -+ * Get the parent handle structure again, in case the handle -+ * structure has moved (depending on the implementation -+ * of AllocHandle). -+ */ -+ psPHand = HANDLE_TO_HANDLE_STRUCT_PTR(psBase, hParent); -+ -+ psCHand = HANDLE_TO_HANDLE_STRUCT_PTR(psBase, hHandle); -+ -+ AdoptChild(psBase, psPHand, psCHand); -+ -+ *phHandle = hHandle; -+ -+exit_ok: -+ if (HANDLES_BATCHED(psBase)) -+ { -+ psBase->ui32BatchHandAllocFailures--; -+ } -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVFindHandle -+ -+ @Description Find handle corresponding to a resource pointer -+ -+ @Input phHandle - location for returned handle -+ pvData - pointer to resource to be associated with the handle -+ eType - the type of resource -+ -+ @Output phHandle - points to handle -+ -+ @Return Error code or PVRSRV_OK -+ -+******************************************************************************/ -+PVRSRV_ERROR PVRSRVFindHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType) -+{ -+ IMG_HANDLE hHandle; -+ -+ PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE); -+ -+ /* See if there is a handle for this data pointer */ -+ hHandle = (IMG_HANDLE) FindHandle(psBase, pvData, eType, IMG_NULL); -+ if (hHandle == IMG_NULL) -+ { -+ return PVRSRV_ERROR_HANDLE_NOT_FOUND; -+ } -+ -+ *phHandle = hHandle; -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVLookupHandleAnyType -+ -+ @Description Lookup the data pointer and type corresponding to a handle -+ -+ @Input ppvData - location to return data pointer -+ peType - location to return handle type -+ hHandle - handle from client -+ -+ @Output ppvData - points to the data pointer -+ peType - points to handle type -+ -+ @Return Error code or PVRSRV_OK -+ -+******************************************************************************/ -+PVRSRV_ERROR PVRSRVLookupHandleAnyType(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, PVRSRV_HANDLE_TYPE *peType, IMG_HANDLE hHandle) -+{ -+ struct sHandle *psHandle; -+ PVRSRV_ERROR eError; -+ -+ eError = GetHandleStructure(psBase, &psHandle, hHandle, PVRSRV_HANDLE_TYPE_NONE); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVLookupHandleAnyType: Error looking up handle (%d)", eError)); -+ OSDumpStack(); -+ return eError; -+ } -+ -+ *ppvData = psHandle->pvData; -+ *peType = psHandle->eType; -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVLookupHandle -+ -+ @Description Lookup the data pointer corresponding to a handle -+ -+ @Input ppvData - location to return data pointer -+ hHandle - handle from client -+ eType - handle type -+ -+ @Output ppvData - points to the data pointer -+ -+ @Return Error code or PVRSRV_OK -+ -+******************************************************************************/ -+PVRSRV_ERROR PVRSRVLookupHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType) -+{ -+ struct sHandle *psHandle; -+ PVRSRV_ERROR eError; -+ -+ PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE); -+ -+ eError = GetHandleStructure(psBase, &psHandle, hHandle, eType); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVLookupHandle: Error looking up handle (%d)", eError)); -+ OSDumpStack(); -+ return eError; -+ } -+ -+ *ppvData = psHandle->pvData; -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVLookupSubHandle -+ -+ @Description Lookup the data pointer corresponding to a subhandle -+ -+ @Input ppvData - location to return data pointer -+ hHandle - handle from client -+ eType - handle type -+ hAncestor - ancestor handle -+ -+ @Output ppvData - points to the data pointer -+ -+ @Return Error code or PVRSRV_OK -+ -+******************************************************************************/ -+PVRSRV_ERROR PVRSRVLookupSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType, IMG_HANDLE hAncestor) -+{ -+ struct sHandle *psPHand; -+ struct sHandle *psCHand; -+ PVRSRV_ERROR eError; -+ -+ PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE); -+ -+ eError = GetHandleStructure(psBase, &psCHand, hHandle, eType); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVLookupSubHandle: Error looking up subhandle (%d)", eError)); -+ OSDumpStack(); -+ return eError; -+ } -+ -+ /* Look for hAncestor among the handle's ancestors */ -+ for (psPHand = psCHand; ParentHandle(psPHand) != hAncestor; ) -+ { -+ eError = GetHandleStructure(psBase, &psPHand, ParentHandle(psPHand), PVRSRV_HANDLE_TYPE_NONE); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVLookupSubHandle: Subhandle doesn't belong to given ancestor")); -+ return PVRSRV_ERROR_INVALID_SUBHANDLE; -+ } -+ } -+ -+ *ppvData = psCHand->pvData; -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVGetParentHandle -+ -+ @Description Lookup the parent of a handle -+ -+ @Input phParent - location for returning parent handle -+ hHandle - handle for which the parent handle is required -+ eType - handle type -+ hParent - parent handle -+ -+ @Output *phParent - parent handle, or IMG_NULL if there is no parent -+ -+ @Return Error code or PVRSRV_OK. Note that not having a parent is -+ not regarded as an error. -+ -+******************************************************************************/ -+PVRSRV_ERROR PVRSRVGetParentHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *phParent, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType) -+{ -+ struct sHandle *psHandle; -+ PVRSRV_ERROR eError; -+ -+ PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE); -+ -+ eError = GetHandleStructure(psBase, &psHandle, hHandle, eType); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetParentHandle: Error looking up subhandle (%d)", eError)); -+ OSDumpStack(); -+ return eError; -+ } -+ -+ *phParent = ParentHandle(psHandle); -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVLookupAndReleaseHandle -+ -+ @Description Lookup the data pointer corresponding to a handle -+ -+ @Input ppvData - location to return data pointer -+ hHandle - handle from client -+ eType - handle type -+ eFlag - lookup flags -+ -+ @Output ppvData - points to the data pointer -+ -+ @Return Error code or PVRSRV_OK -+ -+******************************************************************************/ -+PVRSRV_ERROR PVRSRVLookupAndReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType) -+{ -+ struct sHandle *psHandle; -+ PVRSRV_ERROR eError; -+ -+ PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE); -+ -+ eError = GetHandleStructure(psBase, &psHandle, hHandle, eType); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVLookupAndReleaseHandle: Error looking up handle (%d)", eError)); -+ OSDumpStack(); -+ return eError; -+ } -+ -+ *ppvData = psHandle->pvData; -+ -+ eError = FreeHandle(psBase, psHandle); -+ -+ return eError; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVReleaseHandle -+ -+ @Description Release a handle that is no longer needed -+ -+ @Input hHandle - handle from client -+ eType - handle type -+ -+ @Return Error code or PVRSRV_OK -+ -+******************************************************************************/ -+PVRSRV_ERROR PVRSRVReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType) -+{ -+ struct sHandle *psHandle; -+ PVRSRV_ERROR eError; -+ -+ PVR_ASSERT(eType != PVRSRV_HANDLE_TYPE_NONE); -+ -+ eError = GetHandleStructure(psBase, &psHandle, hHandle, eType); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVReleaseHandle: Error looking up handle (%d)", eError)); -+ OSDumpStack(); -+ return eError; -+ } -+ -+ eError = FreeHandle(psBase, psHandle); -+ -+ return eError; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVNewHandleBatch -+ -+ @Description Start a new handle batch -+ -+ @Input psBase - handle base -+ @Input ui32BatchSize - handle batch size -+ -+ @Return Error code or PVRSRV_OK -+ -+******************************************************************************/ -+PVRSRV_ERROR PVRSRVNewHandleBatch(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32BatchSize) -+{ -+ PVRSRV_ERROR eError; -+ -+ if (HANDLES_BATCHED(psBase)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVNewHandleBatch: There is a handle batch already in use (size %u)", psBase->ui32HandBatchSize)); -+ return PVRSRV_ERROR_HANDLE_BATCH_IN_USE; -+ } -+ -+ if (ui32BatchSize == 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVNewHandleBatch: Invalid batch size (%u)", ui32BatchSize)); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ eError = EnsureFreeHandles(psBase, ui32BatchSize); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVNewHandleBatch: EnsureFreeHandles failed (error %d)", eError)); -+ return eError; -+ } -+ -+ psBase->ui32HandBatchSize = ui32BatchSize; -+ -+ /* Record current number of handles */ -+ psBase->ui32TotalHandCountPreBatch = psBase->ui32TotalHandCount; -+ -+ PVR_ASSERT(psBase->ui32BatchHandAllocFailures == 0); -+ -+ PVR_ASSERT(psBase->ui32FirstBatchIndexPlusOne == 0); -+ -+ PVR_ASSERT(HANDLES_BATCHED(psBase)); -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVHandleBatchCommitOrRelease -+ -+ @Description Release a handle batch -+ -+ @Input psBase - handle base -+ bCommit - commit handles -+ -+ @Return none -+ -+******************************************************************************/ -+static PVRSRV_ERROR PVRSRVHandleBatchCommitOrRelease(PVRSRV_HANDLE_BASE *psBase, IMG_BOOL bCommit) -+{ -+ -+ IMG_UINT32 ui32IndexPlusOne; -+ IMG_BOOL bCommitBatch = bCommit; -+ -+ if (!HANDLES_BATCHED(psBase)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleBatchCommitOrRelease: There is no handle batch")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ -+ } -+ -+ if (psBase->ui32BatchHandAllocFailures != 0) -+ { -+ if (bCommit) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleBatchCommitOrRelease: Attempting to commit batch with handle allocation failures.")); -+ } -+ bCommitBatch = IMG_FALSE; -+ } -+ /* -+ * The whole point of batched handles is to avoid handle allocation -+ * failures. -+ */ -+ PVR_ASSERT(psBase->ui32BatchHandAllocFailures == 0 || !bCommit); -+ -+ ui32IndexPlusOne = psBase->ui32FirstBatchIndexPlusOne; -+ while(ui32IndexPlusOne != 0) -+ { -+ struct sHandle *psHandle = INDEX_TO_HANDLE_STRUCT_PTR(psBase, ui32IndexPlusOne - 1); -+ IMG_UINT32 ui32NextIndexPlusOne = psHandle->ui32NextIndexPlusOne; -+ PVR_ASSERT(BATCHED_HANDLE(psHandle)); -+ -+ psHandle->ui32NextIndexPlusOne = 0; -+ -+ if (!bCommitBatch || BATCHED_HANDLE_PARTIALLY_FREE(psHandle)) -+ { -+ PVRSRV_ERROR eError; -+ -+ /* -+ * We need a complete free here. If the handle -+ * is not partially free, set the handle as -+ * unbatched to avoid a partial free. -+ */ -+ if (!BATCHED_HANDLE_PARTIALLY_FREE(psHandle)) -+ { -+ /* PRQA S 1474,4130 1 */ /* ignore warnings about enum types being modified */ -+ SET_UNBATCHED_HANDLE(psHandle); /* PRQA S 4130 */ /* mis-use of enums FIXME*/ -+ } -+ -+ eError = FreeHandle(psBase, psHandle); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleBatchCommitOrRelease: Error freeing handle (%d)", eError)); -+ } -+ PVR_ASSERT(eError == PVRSRV_OK); -+ } -+ else -+ { -+ /* PRQA S 1474,4130 1 */ /* ignore warnings about enum types being modified */ -+ SET_UNBATCHED_HANDLE(psHandle); -+ } -+ -+ ui32IndexPlusOne = ui32NextIndexPlusOne; -+ } -+ -+#ifdef DEBUG -+ if (psBase->ui32TotalHandCountPreBatch != psBase->ui32TotalHandCount) -+ { -+ IMG_UINT32 ui32Delta = psBase->ui32TotalHandCount - psBase->ui32TotalHandCountPreBatch; -+ -+ PVR_ASSERT(psBase->ui32TotalHandCount > psBase->ui32TotalHandCountPreBatch); -+ -+ PVR_DPF((PVR_DBG_WARNING, "PVRSRVHandleBatchCommitOrRelease: The batch size was too small. Batch size was %u, but needs to be %u", psBase->ui32HandBatchSize, psBase->ui32HandBatchSize + ui32Delta)); -+ -+ } -+#endif -+ -+ psBase->ui32HandBatchSize = 0; -+ psBase->ui32FirstBatchIndexPlusOne = 0; -+ psBase->ui32TotalHandCountPreBatch = 0; -+ psBase->ui32BatchHandAllocFailures = 0; -+ -+ if (psBase->ui32BatchHandAllocFailures != 0 && bCommit) -+ { -+ PVR_ASSERT(!bCommitBatch); -+ -+ return PVRSRV_ERROR_HANDLE_BATCH_COMMIT_FAILURE; -+ } -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVCommitHandleBatch -+ -+ @Description Commit a handle batch -+ -+ @Input psBase - handle base -+ -+ @Return Error code or PVRSRV_OK -+ -+******************************************************************************/ -+PVRSRV_ERROR PVRSRVCommitHandleBatch(PVRSRV_HANDLE_BASE *psBase) -+{ -+ return PVRSRVHandleBatchCommitOrRelease(psBase, IMG_TRUE); -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRReleaseHandleBatch -+ -+ @Description Release a handle batch -+ -+ @Input psBase - handle base -+ -+ @Return none -+ -+******************************************************************************/ -+IMG_VOID PVRSRVReleaseHandleBatch(PVRSRV_HANDLE_BASE *psBase) -+{ -+ (IMG_VOID) PVRSRVHandleBatchCommitOrRelease(psBase, IMG_FALSE); -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVSetMaxHandle -+ -+ @Description Set maximum handle number for given handle base -+ -+ @Input psBase - pointer to handle base structure -+ ui32MaxHandle - Maximum handle number -+ -+ @Return Error code or PVRSRV_OK -+ -+******************************************************************************/ -+PVRSRV_ERROR PVRSRVSetMaxHandle(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32MaxHandle) -+{ -+ IMG_UINT32 ui32MaxHandleRounded; -+ -+ if (HANDLES_BATCHED(psBase)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSetMaxHandle: Limit cannot be set whilst in batch mode")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ /* Validate the limit */ -+ if (ui32MaxHandle == 0 || ui32MaxHandle > DEFAULT_MAX_HANDLE) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSetMaxHandle: Limit must be between %u and %u, inclusive", 0, DEFAULT_MAX_HANDLE)); -+ -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ /* The limit can only be set if no handles have been allocated */ -+ if (psBase->ui32TotalHandCount != 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSetMaxHandle: Limit cannot be set because handles have already been allocated")); -+ -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ ui32MaxHandleRounded = ROUND_DOWN_TO_MULTIPLE_OF_BLOCK_SIZE(ui32MaxHandle); -+ -+ /* -+ * Allow the maximum number of handles to be reduced, but never to -+ * zero. -+ */ -+ if (ui32MaxHandleRounded != 0 && ui32MaxHandleRounded < psBase->ui32MaxIndexPlusOne) -+ { -+ psBase->ui32MaxIndexPlusOne = ui32MaxHandleRounded; -+ } -+ -+ PVR_ASSERT(psBase->ui32MaxIndexPlusOne != 0); -+ PVR_ASSERT(psBase->ui32MaxIndexPlusOne <= DEFAULT_MAX_INDEX_PLUS_ONE); -+ PVR_ASSERT((psBase->ui32MaxIndexPlusOne % HANDLE_BLOCK_SIZE) == 0); -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVGetMaxHandle -+ -+ @Description Get maximum handle number for given handle base -+ -+ @Input psBase - pointer to handle base structure -+ -+ @Output Maximum handle number, or 0 if handle limits not -+ supported. -+ -+ @Return Error code or PVRSRV_OK -+ -+******************************************************************************/ -+IMG_UINT32 PVRSRVGetMaxHandle(PVRSRV_HANDLE_BASE *psBase) -+{ -+ return psBase->ui32MaxIndexPlusOne; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVEnableHandlePurging -+ -+ @Description Enable purging for a given handle base -+ -+ @Input psBase - pointer to handle base structure -+ -+ @Return Error code or PVRSRV_OK -+ -+******************************************************************************/ -+PVRSRV_ERROR PVRSRVEnableHandlePurging(PVRSRV_HANDLE_BASE *psBase) -+{ -+ if (psBase->bPurgingEnabled) -+ { -+ PVR_DPF((PVR_DBG_WARNING, "PVRSRVEnableHandlePurging: Purging already enabled")); -+ return PVRSRV_OK; -+ } -+ -+ /* Purging can only be enabled if no handles have been allocated */ -+ if (psBase->ui32TotalHandCount != 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVEnableHandlePurging: Handles have already been allocated")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psBase->bPurgingEnabled = IMG_TRUE; -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVPurgeHandles -+ -+ @Description Purge handles for a given handle base -+ -+ @Input psBase - pointer to handle base structure -+ -+ @Return Error code or PVRSRV_OK -+ -+******************************************************************************/ -+PVRSRV_ERROR PVRSRVPurgeHandles(PVRSRV_HANDLE_BASE *psBase) -+{ -+ IMG_UINT32 ui32BlockIndex; -+ IMG_UINT32 ui32NewHandCount; -+ -+ if (!psBase->bPurgingEnabled) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVPurgeHandles: Purging not enabled for this handle base")); -+ return PVRSRV_ERROR_NOT_SUPPORTED; -+ } -+ -+ if (HANDLES_BATCHED(psBase)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVPurgeHandles: Purging not allowed whilst in batch mode")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ PVR_ASSERT((psBase->ui32TotalHandCount % HANDLE_BLOCK_SIZE) == 0); -+ -+ for (ui32BlockIndex = INDEX_TO_BLOCK_INDEX(psBase->ui32TotalHandCount); ui32BlockIndex != 0; ui32BlockIndex--) -+ { -+ if (psBase->psHandleArray[ui32BlockIndex - 1].ui32FreeHandBlockCount != HANDLE_BLOCK_SIZE) -+ { -+ break; -+ } -+ } -+ ui32NewHandCount = BLOCK_INDEX_TO_INDEX(ui32BlockIndex); -+ -+ /* -+ * Check for a suitable decrease in the handle count. -+ */ -+ if (ui32NewHandCount <= (psBase->ui32TotalHandCount/2)) -+ { -+ PVRSRV_ERROR eError; -+ -+ // PVR_TRACE((" PVRSRVPurgeHandles: reducing number of handles from %u to %u", psBase->ui32TotalHandCount, ui32NewHandCount)); -+ -+ eError = ReallocHandleArray(psBase, ui32NewHandCount); -+ if (eError != PVRSRV_OK) -+ { -+ return eError; -+ } -+ } -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVAllocHandleBase -+ -+ @Description Allocate a handle base structure for a process -+ -+ @Input ppsBase - pointer to handle base structure pointer -+ -+ @Output ppsBase - points to handle base structure pointer -+ -+ @Return Error code or PVRSRV_OK -+ -+******************************************************************************/ -+PVRSRV_ERROR PVRSRVAllocHandleBase(PVRSRV_HANDLE_BASE **ppsBase) -+{ -+ PVRSRV_HANDLE_BASE *psBase; -+ IMG_HANDLE hBlockAlloc; -+ PVRSRV_ERROR eError; -+ -+ eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, -+ sizeof(*psBase), -+ (IMG_PVOID *)&psBase, -+ &hBlockAlloc, -+ "Handle Base"); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocHandleBase: Couldn't allocate handle base (%d)", eError)); -+ return eError; -+ } -+ OSMemSet(psBase, 0, sizeof(*psBase)); -+ -+ /* Create hash table */ -+ psBase->psHashTab = HASH_Create_Extended(HANDLE_HASH_TAB_INIT_SIZE, sizeof(HAND_KEY), HASH_Func_Default, HASH_Key_Comp_Default); -+ if (psBase->psHashTab == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocHandleBase: Couldn't create data pointer hash table\n")); -+ (IMG_VOID)PVRSRVFreeHandleBase(psBase); -+ return PVRSRV_ERROR_UNABLE_TO_CREATE_HASH_TABLE; -+ } -+ -+ psBase->hBaseBlockAlloc = hBlockAlloc; -+ -+ psBase->ui32MaxIndexPlusOne = DEFAULT_MAX_INDEX_PLUS_ONE; -+ -+ *ppsBase = psBase; -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVFreeHandleBase -+ -+ @Description Free a handle base structure -+ -+ @Input psBase - pointer to handle base structure -+ -+ @Return Error code or PVRSRV_OK -+ -+******************************************************************************/ -+PVRSRV_ERROR PVRSRVFreeHandleBase(PVRSRV_HANDLE_BASE *psBase) -+{ -+ PVRSRV_ERROR eError; -+ -+ PVR_ASSERT(psBase != gpsKernelHandleBase); -+ -+ eError = FreeHandleBase(psBase); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVFreeHandleBase: FreeHandleBase failed (%d)", eError)); -+ } -+ -+ return eError; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVHandleInit -+ -+ @Description Initialise handle management -+ -+ @Return Error code or PVRSRV_OK -+ -+******************************************************************************/ -+PVRSRV_ERROR PVRSRVHandleInit(IMG_VOID) -+{ -+ PVRSRV_ERROR eError; -+ -+ PVR_ASSERT(gpsKernelHandleBase == IMG_NULL); -+ -+ eError = PVRSRVAllocHandleBase(&gpsKernelHandleBase); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleInit: PVRSRVAllocHandleBase failed (%d)", eError)); -+ goto error; -+ } -+ -+ eError = PVRSRVEnableHandlePurging(gpsKernelHandleBase); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleInit: PVRSRVEnableHandlePurging failed (%d)", eError)); -+ goto error; -+ } -+ -+ return PVRSRV_OK; -+error: -+ (IMG_VOID) PVRSRVHandleDeInit(); -+ return eError; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVHandleDeInit -+ -+ @Description De-initialise handle management -+ -+ @Return Error code or PVRSRV_OK -+ -+******************************************************************************/ -+PVRSRV_ERROR PVRSRVHandleDeInit(IMG_VOID) -+{ -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ -+ if (gpsKernelHandleBase != IMG_NULL) -+ { -+ eError = FreeHandleBase(gpsKernelHandleBase); -+ if (eError == PVRSRV_OK) -+ { -+ gpsKernelHandleBase = IMG_NULL; -+ } -+ else -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleDeInit: FreeHandleBase failed (%d)", eError)); -+ } -+ } -+ -+ return eError; -+} -+#else -+/* disable warning about empty module */ -+#endif /* #if defined(PVR_SECURE_HANDLES) */ -+/****************************************************************************** -+ End of file (handle.c) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/common/hash.c b/drivers/staging/ti-es8-sgx/services4/srvkm/common/hash.c -new file mode 100644 -index 0000000..f4fbac1 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/common/hash.c -@@ -0,0 +1,738 @@ -+/*************************************************************************/ /*! -+@Title Self scaling hash tables. -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description -+ Implements simple self scaling hash tables. Hash collisions are -+ handled by chaining entries together. Hash tables are increased in -+ size when they become more than (50%?) full and decreased in size -+ when less than (25%?) full. Hash tables are never decreased below -+ their initial size. -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#include "pvr_debug.h" -+#include "img_defs.h" -+#include "services.h" -+#include "servicesint.h" -+#include "hash.h" -+#include "osfunc.h" -+ -+#define PRIVATE_MAX(a,b) ((a)>(b)?(a):(b)) -+ -+#define KEY_TO_INDEX(pHash, key, uSize) \ -+ ((pHash)->pfnHashFunc((pHash)->uKeySize, (key), (uSize)) % (uSize)) -+ -+#define KEY_COMPARE(pHash, pKey1, pKey2) \ -+ ((pHash)->pfnKeyComp((pHash)->uKeySize, (pKey1), (pKey2))) -+ -+/* Each entry in a hash table is placed into a bucket */ -+struct _BUCKET_ -+{ -+ /* the next bucket on the same chain */ -+ struct _BUCKET_ *pNext; -+ -+ /* entry value */ -+ IMG_UINTPTR_T v; -+ -+ /* entry key */ -+ IMG_UINTPTR_T k[]; /* PRQA S 0642 */ /* override dynamic array declaration warning */ -+}; -+typedef struct _BUCKET_ BUCKET; -+ -+struct _HASH_TABLE_ -+{ -+ /* the hash table array */ -+ BUCKET **ppBucketTable; -+ -+ /* current size of the hash table */ -+ IMG_UINT32 uSize; -+ -+ /* number of entries currently in the hash table */ -+ IMG_UINT32 uCount; -+ -+ /* the minimum size that the hash table should be re-sized to */ -+ IMG_UINT32 uMinimumSize; -+ -+ /* size of key in bytes */ -+ IMG_UINT32 uKeySize; -+ -+ /* hash function */ -+ HASH_FUNC *pfnHashFunc; -+ -+ /* key comparison function */ -+ HASH_KEY_COMP *pfnKeyComp; -+}; -+ -+/*! -+****************************************************************************** -+ @Function HASH_Func_Default -+ -+ @Description Hash function intended for hashing keys composed of -+ IMG_UINTPTR_T arrays. -+ -+ @Input uKeySize - the size of the hash key, in bytes. -+ @Input pKey - a pointer to the key to hash. -+ @Input uHashTabLen - the length of the hash table. -+ -+ @Return the hash value. -+******************************************************************************/ -+IMG_UINT32 -+HASH_Func_Default (IMG_SIZE_T uKeySize, IMG_VOID *pKey, IMG_UINT32 uHashTabLen) -+{ -+ IMG_UINTPTR_T *p = (IMG_UINTPTR_T *)pKey; -+ IMG_UINT32 uKeyLen = (IMG_UINT32)(uKeySize / sizeof(IMG_UINTPTR_T)); -+ IMG_UINT32 ui; -+ IMG_UINT32 uHashKey = 0; -+ -+ PVR_UNREFERENCED_PARAMETER(uHashTabLen); -+ -+ PVR_ASSERT((uKeySize % sizeof(IMG_UINTPTR_T)) == 0); -+ -+ for (ui = 0; ui < uKeyLen; ui++) -+ { -+ IMG_UINT32 uHashPart = (IMG_UINT32)*p++; -+ -+ uHashPart += (uHashPart << 12); -+ uHashPart ^= (uHashPart >> 22); -+ uHashPart += (uHashPart << 4); -+ uHashPart ^= (uHashPart >> 9); -+ uHashPart += (uHashPart << 10); -+ uHashPart ^= (uHashPart >> 2); -+ uHashPart += (uHashPart << 7); -+ uHashPart ^= (uHashPart >> 12); -+ -+ uHashKey += uHashPart; -+ } -+ -+ return uHashKey; -+} -+ -+/*! -+****************************************************************************** -+ @Function HASH_Key_Comp_Default -+ -+ @Description Compares keys composed of IMG_UINTPTR_T arrays. -+ -+ @Input uKeySize - the size of the hash key, in bytes. -+ @Input pKey1 - pointer to first hash key to compare. -+ @Input pKey2 - pointer to second hash key to compare. -+ @Return IMG_TRUE - the keys match. -+ IMG_FALSE - the keys don't match. -+******************************************************************************/ -+IMG_BOOL -+HASH_Key_Comp_Default (IMG_SIZE_T uKeySize, IMG_VOID *pKey1, IMG_VOID *pKey2) -+{ -+ IMG_UINTPTR_T *p1 = (IMG_UINTPTR_T *)pKey1; -+ IMG_UINTPTR_T *p2 = (IMG_UINTPTR_T *)pKey2; -+ IMG_UINT32 uKeyLen = (IMG_UINT32)(uKeySize / sizeof(IMG_UINTPTR_T)); -+ IMG_UINT32 ui; -+ -+ PVR_ASSERT((uKeySize % sizeof(IMG_UINTPTR_T)) == 0); -+ -+ for (ui = 0; ui < uKeyLen; ui++) -+ { -+ if (*p1++ != *p2++) -+ return IMG_FALSE; -+ } -+ -+ return IMG_TRUE; -+} -+ -+/*! -+****************************************************************************** -+ @Function _ChainInsert -+ -+ @Description Insert a bucket into the appropriate hash table chain. -+ -+ @Input pBucket - the bucket -+ @Input ppBucketTable - the hash table -+ @Input uSize - the size of the hash table -+ -+ @Return PVRSRV_ERROR -+******************************************************************************/ -+static PVRSRV_ERROR -+_ChainInsert (HASH_TABLE *pHash, BUCKET *pBucket, BUCKET **ppBucketTable, IMG_UINT32 uSize) -+{ -+ IMG_UINT32 uIndex; -+ -+ PVR_ASSERT (pBucket != IMG_NULL); -+ PVR_ASSERT (ppBucketTable != IMG_NULL); -+ PVR_ASSERT (uSize != 0); -+ -+ if ((pBucket == IMG_NULL) || (ppBucketTable == IMG_NULL) || (uSize == 0)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "_ChainInsert: invalid parameter")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ uIndex = KEY_TO_INDEX(pHash, pBucket->k, uSize); /* PRQA S 0432,0541 */ /* ignore dynamic array warning */ -+ pBucket->pNext = ppBucketTable[uIndex]; -+ ppBucketTable[uIndex] = pBucket; -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ @Function _Rehash -+ -+ @Description Iterate over every entry in an old hash table and -+ rehash into the new table. -+ -+ @Input ppOldTable - the old hash table -+ @Input uOldSize - the size of the old hash table -+ @Input ppNewTable - the new hash table -+ @Input uNewSize - the size of the new hash table -+ -+ @Return None -+******************************************************************************/ -+static PVRSRV_ERROR -+_Rehash (HASH_TABLE *pHash, -+ BUCKET **ppOldTable, IMG_UINT32 uOldSize, -+ BUCKET **ppNewTable, IMG_UINT32 uNewSize) -+{ -+ IMG_UINT32 uIndex; -+ for (uIndex=0; uIndex< uOldSize; uIndex++) -+ { -+ BUCKET *pBucket; -+ pBucket = ppOldTable[uIndex]; -+ while (pBucket != IMG_NULL) -+ { -+ PVRSRV_ERROR eError; -+ BUCKET *pNextBucket = pBucket->pNext; -+ eError = _ChainInsert (pHash, pBucket, ppNewTable, uNewSize); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "_Rehash: call to _ChainInsert failed")); -+ return eError; -+ } -+ pBucket = pNextBucket; -+ } -+ } -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ @Function _Resize -+ -+ @Description Attempt to resize a hash table, failure to allocate a -+ new larger hash table is not considered a hard failure. -+ We simply continue and allow the table to fill up, the -+ effect is to allow hash chains to become longer. -+ -+ @Input pHash - Hash table to resize. -+ @Input uNewSize - Required table size. -+ @Return IMG_TRUE Success -+ IMG_FALSE Failed -+******************************************************************************/ -+static IMG_BOOL -+_Resize (HASH_TABLE *pHash, IMG_UINT32 uNewSize) -+{ -+ if (uNewSize != pHash->uSize) -+ { -+ BUCKET **ppNewTable; -+ IMG_UINT32 uIndex; -+ -+ PVR_DPF ((PVR_DBG_MESSAGE, -+ "HASH_Resize: oldsize=0x%x newsize=0x%x count=0x%x", -+ pHash->uSize, uNewSize, pHash->uCount)); -+ -+ OSAllocMem(PVRSRV_PAGEABLE_SELECT, -+ sizeof (BUCKET *) * uNewSize, -+ (IMG_PVOID*)&ppNewTable, IMG_NULL, -+ "Hash Table Buckets"); -+ if (ppNewTable == IMG_NULL) -+ return IMG_FALSE; -+ -+ for (uIndex=0; uIndex<uNewSize; uIndex++) -+ ppNewTable[uIndex] = IMG_NULL; -+ -+ if (_Rehash (pHash, pHash->ppBucketTable, pHash->uSize, ppNewTable, uNewSize) != PVRSRV_OK) -+ { -+ return IMG_FALSE; -+ } -+ -+ OSFreeMem (PVRSRV_PAGEABLE_SELECT, sizeof(BUCKET *)*pHash->uSize, pHash->ppBucketTable, IMG_NULL); -+ /*not nulling pointer, being reassigned just below*/ -+ pHash->ppBucketTable = ppNewTable; -+ pHash->uSize = uNewSize; -+ } -+ return IMG_TRUE; -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function HASH_Create_Extended -+ -+ @Description Create a self scaling hash table, using the supplied -+ key size, and the supplied hash and key comparsion -+ functions. -+ -+ @Input uInitialLen - initial and minimum length of the -+ hash table, where the length refers to the number -+ of entries in the hash table, not its size in -+ bytes. -+ @Input uKeySize - the size of the key, in bytes. -+ @Input pfnHashFunc - pointer to hash function. -+ @Input pfnKeyComp - pointer to key comparsion function. -+ @Return IMG_NULL or hash table handle. -+******************************************************************************/ -+HASH_TABLE * HASH_Create_Extended (IMG_UINT32 uInitialLen, IMG_SIZE_T uKeySize, HASH_FUNC *pfnHashFunc, HASH_KEY_COMP *pfnKeyComp) -+{ -+ HASH_TABLE *pHash; -+ IMG_UINT32 uIndex; -+ -+ PVR_DPF ((PVR_DBG_MESSAGE, "HASH_Create_Extended: InitialSize=0x%x", uInitialLen)); -+ -+ if(OSAllocMem(PVRSRV_PAGEABLE_SELECT, -+ sizeof(HASH_TABLE), -+ (IMG_VOID **)&pHash, IMG_NULL, -+ "Hash Table") != PVRSRV_OK) -+ { -+ return IMG_NULL; -+ } -+ -+ pHash->uCount = 0; -+ pHash->uSize = uInitialLen; -+ pHash->uMinimumSize = uInitialLen; -+ pHash->uKeySize = (IMG_UINT32)uKeySize; -+ pHash->pfnHashFunc = pfnHashFunc; -+ pHash->pfnKeyComp = pfnKeyComp; -+ -+ OSAllocMem(PVRSRV_PAGEABLE_SELECT, -+ sizeof (BUCKET *) * pHash->uSize, -+ (IMG_PVOID*)&pHash->ppBucketTable, IMG_NULL, -+ "Hash Table Buckets"); -+ -+ if (pHash->ppBucketTable == IMG_NULL) -+ { -+ OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(HASH_TABLE), pHash, IMG_NULL); -+ /*not nulling pointer, out of scope*/ -+ return IMG_NULL; -+ } -+ -+ for (uIndex=0; uIndex<pHash->uSize; uIndex++) -+ pHash->ppBucketTable[uIndex] = IMG_NULL; -+ return pHash; -+} -+ -+/*! -+****************************************************************************** -+ @Function HASH_Create -+ -+ @Description Create a self scaling hash table with a key -+ consisting of a single IMG_UINTPTR_T, and using -+ the default hash and key comparison functions. -+ -+ @Input uInitialLen - initial and minimum length of the -+ hash table, where the length refers to the -+ number of entries in the hash table, not its size -+ in bytes. -+ @Return IMG_NULL or hash table handle. -+******************************************************************************/ -+HASH_TABLE * HASH_Create (IMG_UINT32 uInitialLen) -+{ -+ return HASH_Create_Extended(uInitialLen, sizeof(IMG_UINTPTR_T), -+ &HASH_Func_Default, &HASH_Key_Comp_Default); -+} -+ -+/*! -+****************************************************************************** -+ @Function HASH_Delete -+ -+ @Description Delete a hash table created by HASH_Create_Extended or -+ HASH_Create. All entries in the table must have been -+ removed before calling this function. -+ -+ @Input pHash - hash table -+ -+ @Return None -+******************************************************************************/ -+IMG_VOID -+HASH_Delete (HASH_TABLE *pHash) -+{ -+ if (pHash != IMG_NULL) -+ { -+ PVR_DPF ((PVR_DBG_MESSAGE, "HASH_Delete")); -+ -+ PVR_ASSERT (pHash->uCount==0); -+ if(pHash->uCount != 0) -+ { -+ PVR_DPF ((PVR_DBG_ERROR, "HASH_Delete: leak detected in hash table!")); -+ PVR_DPF ((PVR_DBG_ERROR, "Likely Cause: client drivers not freeing alocations before destroying devmemcontext")); -+ } -+ OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(BUCKET *)*pHash->uSize, pHash->ppBucketTable, IMG_NULL); -+ pHash->ppBucketTable = IMG_NULL; -+ OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(HASH_TABLE), pHash, IMG_NULL); -+ /*not nulling pointer, copy on stack*/ -+ } -+} -+ -+/*! -+****************************************************************************** -+ @Function HASH_Insert_Extended -+ -+ @Description Insert a key value pair into a hash table created -+ with HASH_Create_Extended. -+ -+ @Input pHash - the hash table. -+ @Input pKey - pointer to the key. -+ @Input v - the value associated with the key. -+ -+ @Return IMG_TRUE - success -+ IMG_FALSE - failure -+******************************************************************************/ -+IMG_BOOL -+HASH_Insert_Extended (HASH_TABLE *pHash, IMG_VOID *pKey, IMG_UINTPTR_T v) -+{ -+ BUCKET *pBucket; -+ -+ PVR_DPF ((PVR_DBG_MESSAGE, -+ "HASH_Insert_Extended: Hash=0x%p, pKey=0x%p, v=0x" UINTPTR_FMT, -+ pHash, pKey, v)); -+ -+ PVR_ASSERT (pHash != IMG_NULL); -+ -+ if (pHash == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "HASH_Insert_Extended: invalid parameter")); -+ return IMG_FALSE; -+ } -+ -+ if(OSAllocMem(PVRSRV_PAGEABLE_SELECT, -+ sizeof(BUCKET) + pHash->uKeySize, -+ (IMG_VOID **)&pBucket, IMG_NULL, -+ "Hash Table entry") != PVRSRV_OK) -+ { -+ return IMG_FALSE; -+ } -+ -+ pBucket->v = v; -+ /* PRQA S 0432,0541 1 */ /* ignore warning about dynamic array k (linux)*/ -+ OSMemCopy(pBucket->k, pKey, pHash->uKeySize); -+ if (_ChainInsert (pHash, pBucket, pHash->ppBucketTable, pHash->uSize) != PVRSRV_OK) -+ { -+ OSFreeMem(PVRSRV_PAGEABLE_SELECT, -+ sizeof(BUCKET) + pHash->uKeySize, -+ pBucket, IMG_NULL); -+ return IMG_FALSE; -+ } -+ -+ pHash->uCount++; -+ -+ /* check if we need to think about re-balencing */ -+ if (pHash->uCount << 1 > pHash->uSize) -+ { -+ /* Ignore the return code from _Resize because the hash table is -+ still in a valid state and although not ideally sized, it is still -+ functional */ -+ _Resize (pHash, pHash->uSize << 1); -+ } -+ -+ -+ return IMG_TRUE; -+} -+ -+/*! -+****************************************************************************** -+ @Function HASH_Insert -+ -+ @Description Insert a key value pair into a hash table created with -+ HASH_Create. -+ -+ @Input pHash - the hash table. -+ @Input k - the key value. -+ @Input v - the value associated with the key. -+ -+ @Return IMG_TRUE - success. -+ IMG_FALSE - failure. -+******************************************************************************/ -+IMG_BOOL -+HASH_Insert (HASH_TABLE *pHash, IMG_UINTPTR_T k, IMG_UINTPTR_T v) -+{ -+ PVR_DPF ((PVR_DBG_MESSAGE, -+ "HASH_Insert: Hash=0x%p, k=0x" UINTPTR_FMT ", v=0x" UINTPTR_FMT, -+ pHash, k, v)); -+ -+ return HASH_Insert_Extended(pHash, &k, v); -+} -+ -+/*! -+****************************************************************************** -+ @Function HASH_Remove_Extended -+ -+ @Description Remove a key from a hash table created with -+ HASH_Create_Extended. -+ -+ @Input pHash - the hash table. -+ @Input pKey - pointer to key. -+ -+ @Return 0 if the key is missing, or the value associated -+ with the key. -+******************************************************************************/ -+IMG_UINTPTR_T -+HASH_Remove_Extended(HASH_TABLE *pHash, IMG_VOID *pKey) -+{ -+ BUCKET **ppBucket; -+ IMG_UINT32 uIndex; -+ -+ PVR_DPF ((PVR_DBG_MESSAGE, "HASH_Remove_Extended: Hash=0x%p, pKey=0x%p", -+ pHash, pKey)); -+ -+ PVR_ASSERT (pHash != IMG_NULL); -+ -+ if (pHash == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "HASH_Remove_Extended: Null hash table")); -+ return 0; -+ } -+ -+ uIndex = KEY_TO_INDEX(pHash, pKey, pHash->uSize); -+ -+ for (ppBucket = &(pHash->ppBucketTable[uIndex]); *ppBucket != IMG_NULL; ppBucket = &((*ppBucket)->pNext)) -+ { -+ /* PRQA S 0432,0541 1 */ /* ignore warning about dynamic array k */ -+ if (KEY_COMPARE(pHash, (*ppBucket)->k, pKey)) -+ { -+ BUCKET *pBucket = *ppBucket; -+ IMG_UINTPTR_T v = pBucket->v; -+ (*ppBucket) = pBucket->pNext; -+ -+ OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(BUCKET) + pHash->uKeySize, pBucket, IMG_NULL); -+ /*not nulling original pointer, already overwritten*/ -+ -+ pHash->uCount--; -+ -+ /* check if we need to think about re-balencing */ -+ if (pHash->uSize > (pHash->uCount << 2) && -+ pHash->uSize > pHash->uMinimumSize) -+ { -+ /* Ignore the return code from _Resize because the -+ hash table is still in a valid state and although -+ not ideally sized, it is still functional */ -+ _Resize (pHash, -+ PRIVATE_MAX (pHash->uSize >> 1, -+ pHash->uMinimumSize)); -+ } -+ -+ PVR_DPF ((PVR_DBG_MESSAGE, -+ "HASH_Remove_Extended: Hash=0x%p, pKey=0x%p = 0x" UINTPTR_FMT, -+ pHash, pKey, v)); -+ return v; -+ } -+ } -+ PVR_DPF ((PVR_DBG_MESSAGE, -+ "HASH_Remove_Extended: Hash=0x%p, pKey=0x%p = 0x0 !!!!", -+ pHash, pKey)); -+ return 0; -+} -+ -+/*! -+****************************************************************************** -+ @Function HASH_Remove -+ -+ @Description Remove a key value pair from a hash table created -+ with HASH_Create. -+ -+ @Input pHash - the hash table -+ @Input k - the key -+ -+ @Return 0 if the key is missing, or the value associated -+ with the key. -+******************************************************************************/ -+IMG_UINTPTR_T -+HASH_Remove (HASH_TABLE *pHash, IMG_UINTPTR_T k) -+{ -+ PVR_DPF ((PVR_DBG_MESSAGE, "HASH_Remove: Hash=0x%p, k=0x" UINTPTR_FMT, -+ pHash, k)); -+ -+ return HASH_Remove_Extended(pHash, &k); -+} -+ -+/*! -+****************************************************************************** -+ @Function HASH_Retrieve_Extended -+ -+ @Description Retrieve a value from a hash table created with -+ HASH_Create_Extended. -+ -+ @Input pHash - the hash table. -+ @Input pKey - pointer to the key. -+ -+ @Return 0 if the key is missing, or the value associated with -+ the key. -+******************************************************************************/ -+IMG_UINTPTR_T -+HASH_Retrieve_Extended (HASH_TABLE *pHash, IMG_VOID *pKey) -+{ -+ BUCKET **ppBucket; -+ IMG_UINT32 uIndex; -+ -+ PVR_DPF ((PVR_DBG_MESSAGE, "HASH_Retrieve_Extended: Hash=0x%p, pKey=0x%p", -+ pHash, pKey)); -+ -+ PVR_ASSERT (pHash != IMG_NULL); -+ -+ if (pHash == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "HASH_Retrieve_Extended: Null hash table")); -+ return 0; -+ } -+ -+ uIndex = KEY_TO_INDEX(pHash, pKey, pHash->uSize); -+ -+ for (ppBucket = &(pHash->ppBucketTable[uIndex]); *ppBucket != IMG_NULL; ppBucket = &((*ppBucket)->pNext)) -+ { -+ /* PRQA S 0432,0541 1 */ /* ignore warning about dynamic array k */ -+ if (KEY_COMPARE(pHash, (*ppBucket)->k, pKey)) -+ { -+ BUCKET *pBucket = *ppBucket; -+ IMG_UINTPTR_T v = pBucket->v; -+ -+ PVR_DPF ((PVR_DBG_MESSAGE, -+ "HASH_Retrieve: Hash=0x%p, pKey=0x%p = 0x" UINTPTR_FMT, -+ pHash, pKey, v)); -+ return v; -+ } -+ } -+ PVR_DPF ((PVR_DBG_MESSAGE, -+ "HASH_Retrieve: Hash=0x%p, pKey=0x%p = 0x0 !!!!", -+ pHash, pKey)); -+ return 0; -+} -+ -+/*! -+****************************************************************************** -+ @Function HASH_Retrieve -+ -+ @Description Retrieve a value from a hash table created with -+ HASH_Create. -+ -+ @Input pHash - the hash table -+ @Input k - the key -+ @Return 0 if the key is missing, or the value associated with -+ the key. -+******************************************************************************/ -+IMG_UINTPTR_T -+HASH_Retrieve (HASH_TABLE *pHash, IMG_UINTPTR_T k) -+{ -+ PVR_DPF ((PVR_DBG_MESSAGE, "HASH_Retrieve: Hash=0x%p, k=0x" UINTPTR_FMT, -+ pHash, k)); -+ return HASH_Retrieve_Extended(pHash, &k); -+} -+ -+/*! -+****************************************************************************** -+ @Function HASH_Iterate -+ -+ @Description Iterate over every entry in the hash table -+ -+ @Input pHash - the old hash table -+ @Input pfnCallback - the size of the old hash table -+ -+ @Return Callback error if any, otherwise PVRSRV_OK -+******************************************************************************/ -+PVRSRV_ERROR -+HASH_Iterate(HASH_TABLE *pHash, HASH_pfnCallback pfnCallback) -+{ -+ IMG_UINT32 uIndex; -+ for (uIndex=0; uIndex < pHash->uSize; uIndex++) -+ { -+ BUCKET *pBucket; -+ pBucket = pHash->ppBucketTable[uIndex]; -+ while (pBucket != IMG_NULL) -+ { -+ PVRSRV_ERROR eError; -+ BUCKET *pNextBucket = pBucket->pNext; -+ -+ eError = pfnCallback((IMG_UINTPTR_T) ((IMG_VOID *) *(pBucket->k)), (IMG_UINTPTR_T) pBucket->v); -+ -+ /* The callback might want us to break out early */ -+ if (eError != PVRSRV_OK) -+ return eError; -+ -+ pBucket = pNextBucket; -+ } -+ } -+ return PVRSRV_OK; -+} -+ -+#ifdef HASH_TRACE -+/*! -+****************************************************************************** -+ @Function HASH_Dump -+ -+ @Description To dump the contents of a hash table in human readable -+ form. -+ -+ @Input pHash - the hash table -+ -+ @Return None -+******************************************************************************/ -+IMG_VOID -+HASH_Dump (HASH_TABLE *pHash) -+{ -+ IMG_UINT32 uIndex; -+ IMG_UINT32 uMaxLength=0; -+ IMG_UINT32 uEmptyCount=0; -+ -+ PVR_ASSERT (pHash != IMG_NULL); -+ for (uIndex=0; uIndex<pHash->uSize; uIndex++) -+ { -+ BUCKET *pBucket; -+ IMG_UINT32 uLength = 0; -+ if (pHash->ppBucketTable[uIndex] == IMG_NULL) -+ { -+ uEmptyCount++; -+ } -+ for (pBucket=pHash->ppBucketTable[uIndex]; -+ pBucket != IMG_NULL; -+ pBucket = pBucket->pNext) -+ { -+ uLength++; -+ } -+ uMaxLength = PRIVATE_MAX (uMaxLength, uLength); -+ } -+ -+ PVR_TRACE(("hash table: uMinimumSize=%d size=%d count=%d", -+ pHash->uMinimumSize, pHash->uSize, pHash->uCount)); -+ PVR_TRACE((" empty=%d max=%d", uEmptyCount, uMaxLength)); -+} -+#endif -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/common/lists.c b/drivers/staging/ti-es8-sgx/services4/srvkm/common/lists.c -new file mode 100644 -index 0000000..66401b0 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/common/lists.c -@@ -0,0 +1,156 @@ -+/*************************************************************************/ /*! -+@Title Linked list shared functions implementation -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Implementation of the list iterators for types shared among -+ more than one file in the services code. -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+#include "lists.h" -+#include "services_headers.h" -+ -+/*=================================================================== -+ LIST ITERATOR FUNCTIONS USED IN MORE THAN ONE FILE (those used just -+ once are implemented locally). -+ ===================================================================*/ -+ -+IMPLEMENT_LIST_ANY_VA(BM_HEAP) -+IMPLEMENT_LIST_ANY_2(BM_HEAP, PVRSRV_ERROR, PVRSRV_OK) -+IMPLEMENT_LIST_ANY_VA_2(BM_HEAP, PVRSRV_ERROR, PVRSRV_OK) -+IMPLEMENT_LIST_FOR_EACH_VA(BM_HEAP) -+IMPLEMENT_LIST_REMOVE(BM_HEAP) -+IMPLEMENT_LIST_INSERT(BM_HEAP) -+ -+IMPLEMENT_LIST_ANY_VA(BM_CONTEXT) -+IMPLEMENT_LIST_ANY_VA_2(BM_CONTEXT, IMG_HANDLE, IMG_NULL) -+IMPLEMENT_LIST_ANY_VA_2(BM_CONTEXT, PVRSRV_ERROR, PVRSRV_OK) -+IMPLEMENT_LIST_FOR_EACH(BM_CONTEXT) -+IMPLEMENT_LIST_REMOVE(BM_CONTEXT) -+IMPLEMENT_LIST_INSERT(BM_CONTEXT) -+ -+IMPLEMENT_LIST_ANY_2(PVRSRV_DEVICE_NODE, PVRSRV_ERROR, PVRSRV_OK) -+IMPLEMENT_LIST_ANY_VA(PVRSRV_DEVICE_NODE) -+IMPLEMENT_LIST_ANY_VA_2(PVRSRV_DEVICE_NODE, PVRSRV_ERROR, PVRSRV_OK) -+IMPLEMENT_LIST_FOR_EACH(PVRSRV_DEVICE_NODE) -+IMPLEMENT_LIST_FOR_EACH_VA(PVRSRV_DEVICE_NODE) -+IMPLEMENT_LIST_INSERT(PVRSRV_DEVICE_NODE) -+IMPLEMENT_LIST_REMOVE(PVRSRV_DEVICE_NODE) -+ -+IMPLEMENT_LIST_ANY_VA(PVRSRV_POWER_DEV) -+IMPLEMENT_LIST_ANY_VA_2(PVRSRV_POWER_DEV, PVRSRV_ERROR, PVRSRV_OK) -+IMPLEMENT_LIST_INSERT(PVRSRV_POWER_DEV) -+IMPLEMENT_LIST_REMOVE(PVRSRV_POWER_DEV) -+ -+ -+/*=================================================================== -+ BELOW ARE IMPLEMENTED SOME COMMON CALLBACKS USED IN DIFFERENT FILES -+ ===================================================================*/ -+ -+ -+/*! -+****************************************************************************** -+ @Function MatchDeviceKM_AnyVaCb -+ @Description Matchs a device node with an id and optionally a class. -+ -+ @Input psDeviceNode - Pointer to the device node. -+ @Input va - Variable argument list, with te following values: -+ # ui32DevIndex - Index of de device to match. -+ # bIgnoreClass - Flag indicating if there's -+ no need to check the device class. -+ # eDevClass - Device class, ONLY present if -+ bIgnoreClass was IMG_FALSE. -+ -+ @Return The pointer to the device node if it matchs, IMG_NULL -+ otherwise. -+******************************************************************************/ -+IMG_VOID* MatchDeviceKM_AnyVaCb(PVRSRV_DEVICE_NODE* psDeviceNode, va_list va) -+{ -+ IMG_UINT32 ui32DevIndex; -+ IMG_BOOL bIgnoreClass; -+ PVRSRV_DEVICE_CLASS eDevClass; -+ -+ ui32DevIndex = va_arg(va, IMG_UINT32); -+ bIgnoreClass = va_arg(va, IMG_BOOL); -+ if (!bIgnoreClass) -+ { -+ eDevClass = va_arg(va, PVRSRV_DEVICE_CLASS); -+ } -+ else -+ { -+ /*this value will never be used, since the short circuit evaluation -+ of the first clause will stop because bIgnoreClass is true, but the -+ compiler complains if it's not initialized.*/ -+ eDevClass = PVRSRV_DEVICE_CLASS_FORCE_I32; -+ } -+ -+ if ((bIgnoreClass || psDeviceNode->sDevId.eDeviceClass == eDevClass) && -+ psDeviceNode->sDevId.ui32DeviceIndex == ui32DevIndex) -+ { -+ return psDeviceNode; -+ } -+ return IMG_NULL; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function MatchPowerDeviceIndex_AnyVaCb -+ -+ @Description -+ Matches a power device with its device index. -+ -+ @Input va : variable argument list with: -+ ui32DeviceIndex : device index -+ -+ @Return the pointer to the device it matched, IMG_NULL otherwise. -+ -+******************************************************************************/ -+IMG_VOID* MatchPowerDeviceIndex_AnyVaCb(PVRSRV_POWER_DEV *psPowerDev, va_list va) -+{ -+ IMG_UINT32 ui32DeviceIndex; -+ -+ ui32DeviceIndex = va_arg(va, IMG_UINT32); -+ -+ if (psPowerDev->ui32DeviceIndex == ui32DeviceIndex) -+ { -+ return psPowerDev; -+ } -+ else -+ { -+ return IMG_NULL; -+ } -+} -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/common/mem.c b/drivers/staging/ti-es8-sgx/services4/srvkm/common/mem.c -new file mode 100644 -index 0000000..efffa33 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/common/mem.c -@@ -0,0 +1,175 @@ -+/*************************************************************************/ /*! -+@Title System memory functions -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description System memory allocation APIs -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#include "services_headers.h" -+#include "pvr_bridge_km.h" -+ -+ -+static PVRSRV_ERROR -+FreeSharedSysMemCallBack(IMG_PVOID pvParam, -+ IMG_UINT32 ui32Param, -+ IMG_BOOL bDummy) -+{ -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = pvParam; -+ -+ PVR_UNREFERENCED_PARAMETER(ui32Param); -+ PVR_UNREFERENCED_PARAMETER(bDummy); -+ -+ OSFreePages(psKernelMemInfo->ui32Flags, -+ psKernelMemInfo->uAllocSize, -+ psKernelMemInfo->pvLinAddrKM, -+ psKernelMemInfo->sMemBlk.hOSMemHandle); -+ -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(PVRSRV_KERNEL_MEM_INFO), -+ psKernelMemInfo, -+ IMG_NULL); -+ /*not nulling pointer, copy on stack*/ -+ -+ return PVRSRV_OK; -+} -+ -+ -+IMG_EXPORT PVRSRV_ERROR -+PVRSRVAllocSharedSysMemoryKM(PVRSRV_PER_PROCESS_DATA *psPerProc, -+ IMG_UINT32 ui32Flags, -+ IMG_SIZE_T uSize, -+ PVRSRV_KERNEL_MEM_INFO **ppsKernelMemInfo) -+{ -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; -+ -+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(PVRSRV_KERNEL_MEM_INFO), -+ (IMG_VOID **)&psKernelMemInfo, IMG_NULL, -+ "Kernel Memory Info") != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVAllocSharedSysMemoryKM: Failed to alloc memory for meminfo")); -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ -+ OSMemSet(psKernelMemInfo, 0, sizeof(*psKernelMemInfo)); -+ -+ ui32Flags &= ~PVRSRV_HAP_MAPTYPE_MASK; -+ ui32Flags |= PVRSRV_HAP_MULTI_PROCESS; -+ psKernelMemInfo->ui32Flags = ui32Flags; -+ psKernelMemInfo->uAllocSize = uSize; -+ -+ if(OSAllocPages(psKernelMemInfo->ui32Flags, -+ psKernelMemInfo->uAllocSize, -+ (IMG_UINT32)HOST_PAGESIZE(), -+ IMG_NULL, -+ 0, -+ IMG_NULL, -+ &psKernelMemInfo->pvLinAddrKM, -+ &psKernelMemInfo->sMemBlk.hOSMemHandle) -+ != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocSharedSysMemoryKM: Failed to alloc memory for block")); -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(PVRSRV_KERNEL_MEM_INFO), -+ psKernelMemInfo, -+ 0); -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ -+ /* register with the resman */ -+ psKernelMemInfo->sMemBlk.hResItem = -+ ResManRegisterRes(psPerProc->hResManContext, -+ RESMAN_TYPE_SHARED_MEM_INFO, -+ psKernelMemInfo, -+ 0, -+ &FreeSharedSysMemCallBack); -+ -+ *ppsKernelMemInfo = psKernelMemInfo; -+ -+ return PVRSRV_OK; -+} -+ -+ -+IMG_EXPORT PVRSRV_ERROR -+PVRSRVFreeSharedSysMemoryKM(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo) -+{ -+ PVRSRV_ERROR eError; -+ -+ if(psKernelMemInfo->sMemBlk.hResItem) -+ { -+ eError = ResManFreeResByPtr(psKernelMemInfo->sMemBlk.hResItem, CLEANUP_WITH_POLL); -+ } -+ else -+ { -+ eError = FreeSharedSysMemCallBack(psKernelMemInfo, 0, CLEANUP_WITH_POLL); -+ } -+ -+ return eError; -+} -+ -+ -+IMG_EXPORT PVRSRV_ERROR -+PVRSRVDissociateMemFromResmanKM(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo) -+{ -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ -+ if(!psKernelMemInfo) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ if(psKernelMemInfo->sMemBlk.hResItem) -+ { -+ eError = ResManDissociateRes(psKernelMemInfo->sMemBlk.hResItem, IMG_NULL); -+ -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVDissociateMemFromResmanKM: ResManDissociateRes failed")); -+ PVR_DBG_BREAK; -+ return eError; -+ } -+ -+ psKernelMemInfo->sMemBlk.hResItem = IMG_NULL; -+ } -+ -+ return eError; -+} -+ -+/****************************************************************************** -+ End of file (mem.c) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/common/mem_debug.c b/drivers/staging/ti-es8-sgx/services4/srvkm/common/mem_debug.c -new file mode 100644 -index 0000000..34bf564 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/common/mem_debug.c -@@ -0,0 +1,276 @@ -+/*************************************************************************/ /*! -+@Title Memory debugging routines. -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Adds extra memory to the allocations to trace the memory bounds -+ and other runtime information. -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#ifndef MEM_DEBUG_C -+#define MEM_DEBUG_C -+ -+#if defined(PVRSRV_DEBUG_OS_MEMORY) -+ -+#include "img_types.h" -+#include "services_headers.h" -+ -+#if defined (__cplusplus) -+extern "C" -+{ -+#endif -+ -+#define STOP_ON_ERROR 0 -+ -+ /* -+ Allocated Memory Layout: -+ -+ --------- \ -+ Status [OSMEM_DEBUG_INFO] |- TEST_BUFFER_PADDING_STATUS -+ --------- < -+ [0xBB]* [raw bytes] |- ui32Size -+ --------- < -+ [0xB2]* [raw bytes] |- TEST_BUFFER_PADDING_AFTER -+ --------- / -+ */ -+ -+ IMG_BOOL MemCheck(const IMG_PVOID pvAddr, const IMG_UINT8 ui8Pattern, IMG_SIZE_T uSize) -+ { -+ IMG_UINT8 *pui8Addr; -+ for (pui8Addr = (IMG_UINT8*)pvAddr; uSize > 0; uSize--, pui8Addr++) -+ { -+ if (*pui8Addr != ui8Pattern) -+ { -+ return IMG_FALSE; -+ } -+ } -+ return IMG_TRUE; -+ } -+ -+ /* -+ This function expects the pointer to the user data, not the debug data. -+ */ -+ IMG_VOID OSCheckMemDebug(IMG_PVOID pvCpuVAddr, IMG_SIZE_T uSize, const IMG_CHAR *pszFileName, const IMG_UINT32 uLine) -+ { -+ OSMEM_DEBUG_INFO const *psInfo = (OSMEM_DEBUG_INFO *)((IMG_UINTPTR_T)pvCpuVAddr - TEST_BUFFER_PADDING_STATUS); -+ -+ /* invalid pointer */ -+ if (pvCpuVAddr == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "Pointer 0x%p : null pointer" -+ " - referenced %s:%d - allocated %s:%d", -+ pvCpuVAddr, -+ pszFileName, uLine, -+ psInfo->sFileName, psInfo->uLineNo)); -+ while (STOP_ON_ERROR); -+ } -+ -+ /* align */ -+ if (((IMG_UINT32)pvCpuVAddr&3) != 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "Pointer 0x%p : invalid alignment" -+ " - referenced %s:%d - allocated %s:%d", -+ pvCpuVAddr, -+ pszFileName, uLine, -+ psInfo->sFileName, psInfo->uLineNo)); -+ while (STOP_ON_ERROR); -+ } -+ -+ /*check guard region before*/ -+ if (!MemCheck((IMG_PVOID)psInfo->sGuardRegionBefore, 0xB1, sizeof(psInfo->sGuardRegionBefore))) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "Pointer 0x%p : guard region before overwritten" -+ " - referenced %s:%d - allocated %s:%d", -+ pvCpuVAddr, -+ pszFileName, uLine, -+ psInfo->sFileName, psInfo->uLineNo)); -+ while (STOP_ON_ERROR); -+ } -+ -+ /*check size*/ -+ if (uSize != psInfo->uSize) -+ { -+ PVR_DPF((PVR_DBG_WARNING, -+ "Pointer 0x%p : supplied size was different to stored size (0x%" -+ SIZE_T_FMT_LEN "X != 0x%" SIZE_T_FMT_LEN "X)" -+ " - referenced %s:%d - allocated %s:%d", -+ pvCpuVAddr, uSize, psInfo->uSize, -+ pszFileName, uLine, -+ psInfo->sFileName, psInfo->uLineNo)); -+ while (STOP_ON_ERROR); -+ } -+ -+ /*check size parity*/ -+ if ((0x01234567 ^ psInfo->uSizeParityCheck) != psInfo->uSize) -+ { -+ PVR_DPF((PVR_DBG_WARNING, -+ "Pointer 0x%p : stored size parity error (0x%" -+ SIZE_T_FMT_LEN "X != 0x%" SIZE_T_FMT_LEN "X)" -+ " - referenced %s:%d - allocated %s:%d", -+ pvCpuVAddr, psInfo->uSize, 0x01234567 ^ psInfo->uSizeParityCheck, -+ pszFileName, uLine, -+ psInfo->sFileName, psInfo->uLineNo)); -+ while (STOP_ON_ERROR); -+ } -+ else -+ { -+ /*the stored size is ok, so we use it instead the supplied uSize*/ -+ uSize = psInfo->uSize; -+ } -+ -+ /*check padding after*/ -+ if (uSize) -+ { -+ if (!MemCheck((IMG_VOID*)((IMG_UINTPTR_T)pvCpuVAddr + uSize), 0xB2, TEST_BUFFER_PADDING_AFTER)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "Pointer 0x%p : guard region after overwritten" -+ " - referenced from %s:%d - allocated from %s:%d", -+ pvCpuVAddr, -+ pszFileName, uLine, -+ psInfo->sFileName, psInfo->uLineNo)); -+ } -+ } -+ -+ /* allocated... */ -+ if (psInfo->eValid != isAllocated) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "Pointer 0x%p : not allocated (freed? %d)" -+ " - referenced %s:%d - freed %s:%d", -+ pvCpuVAddr, psInfo->eValid == isFree, -+ pszFileName, uLine, -+ psInfo->sFileName, psInfo->uLineNo)); -+ while (STOP_ON_ERROR); -+ } -+ } -+ -+ IMG_VOID debug_strcpy(IMG_CHAR *pDest, const IMG_CHAR *pSrc) -+ { -+ IMG_SIZE_T i = 0; -+ -+ for (; i < 128; i++) /*changed to 128 to match the filename array size*/ -+ { -+ *pDest = *pSrc; -+ if (*pSrc == '\0') break; -+ pDest++; -+ pSrc++; -+ } -+ } -+ -+ PVRSRV_ERROR OSAllocMem_Debug_Wrapper(IMG_UINT32 ui32Flags, -+ IMG_UINT32 ui32Size, -+ IMG_PVOID *ppvCpuVAddr, -+ IMG_HANDLE *phBlockAlloc, -+ IMG_CHAR *pszFilename, -+ IMG_UINT32 ui32Line) -+ { -+ OSMEM_DEBUG_INFO *psInfo; -+ -+ PVRSRV_ERROR eError; -+ -+ eError = OSAllocMem_Debug_Linux_Memory_Allocations(ui32Flags, -+ ui32Size + TEST_BUFFER_PADDING, -+ ppvCpuVAddr, -+ phBlockAlloc, -+ pszFilename, -+ ui32Line); -+ -+ if (eError != PVRSRV_OK) -+ { -+ return eError; -+ } -+ -+ OSMemSet((IMG_CHAR *)(*ppvCpuVAddr) + TEST_BUFFER_PADDING_STATUS, 0xBB, ui32Size); -+ OSMemSet((IMG_CHAR *)(*ppvCpuVAddr) + ui32Size + TEST_BUFFER_PADDING_STATUS, 0xB2, TEST_BUFFER_PADDING_AFTER); -+ -+ /*fill the dbg info struct*/ -+ psInfo = (OSMEM_DEBUG_INFO *)(*ppvCpuVAddr); -+ -+ OSMemSet(psInfo->sGuardRegionBefore, 0xB1, sizeof(psInfo->sGuardRegionBefore)); -+ debug_strcpy(psInfo->sFileName, pszFilename); -+ psInfo->uLineNo = ui32Line; -+ psInfo->eValid = isAllocated; -+ psInfo->uSize = ui32Size; -+ psInfo->uSizeParityCheck = 0x01234567 ^ ui32Size; -+ -+ /*point to the user data section*/ -+ *ppvCpuVAddr = (IMG_PVOID) ((IMG_UINTPTR_T)*ppvCpuVAddr)+TEST_BUFFER_PADDING_STATUS; -+ -+#ifdef PVRSRV_LOG_MEMORY_ALLOCS -+ /*this is here to simplify the surounding logging macro, that is a expression -+ maybe the macro should be an expression */ -+ PVR_TRACE(("Allocated pointer (after debug info): 0x%p from %s:%d", *ppvCpuVAddr, pszFilename, ui32Line)); -+#endif -+ -+ return PVRSRV_OK; -+ } -+ -+ PVRSRV_ERROR OSFreeMem_Debug_Wrapper(IMG_UINT32 ui32Flags, -+ IMG_UINT32 ui32Size, -+ IMG_PVOID pvCpuVAddr, -+ IMG_HANDLE hBlockAlloc, -+ IMG_CHAR *pszFilename, -+ IMG_UINT32 ui32Line) -+ { -+ OSMEM_DEBUG_INFO *psInfo; -+ -+ /*check dbginfo (arg pointing to user memory)*/ -+ OSCheckMemDebug(pvCpuVAddr, ui32Size, pszFilename, ui32Line); -+ -+ /*mark memory as freed*/ -+ OSMemSet(pvCpuVAddr, 0xBF, ui32Size + TEST_BUFFER_PADDING_AFTER); -+ -+ /*point to the starting address of the total allocated memory*/ -+ psInfo = (OSMEM_DEBUG_INFO *)((IMG_UINTPTR_T) pvCpuVAddr - TEST_BUFFER_PADDING_STATUS); -+ -+ /*update dbg info struct*/ -+ psInfo->uSize = 0; -+ psInfo->uSizeParityCheck = 0; -+ psInfo->eValid = isFree; -+ psInfo->uLineNo = ui32Line; -+ debug_strcpy(psInfo->sFileName, pszFilename); -+ -+ return OSFreeMem_Debug_Linux_Memory_Allocations(ui32Flags, ui32Size + TEST_BUFFER_PADDING, psInfo, hBlockAlloc, pszFilename, ui32Line); -+ } -+ -+#if defined (__cplusplus) -+ -+} -+#endif -+ -+#endif /* PVRSRV_DEBUG_OS_MEMORY */ -+ -+#endif /* MEM_DEBUG_C */ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/common/metrics.c b/drivers/staging/ti-es8-sgx/services4/srvkm/common/metrics.c -new file mode 100644 -index 0000000..7042918 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/common/metrics.c -@@ -0,0 +1,208 @@ -+/*************************************************************************/ /*! -+@Title Time measuring functions. -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#include "services_headers.h" -+#include "metrics.h" -+ -+/* VGX: */ -+#if defined(SUPPORT_VGX) -+#include "vgxapi_km.h" -+#endif -+ -+/* SGX: */ -+#if defined(SUPPORT_SGX) -+#include "sgxapi_km.h" -+#endif -+ -+#if defined(DEBUG) || defined(TIMING) -+ -+static volatile IMG_UINT32 *pui32TimerRegister = 0; -+ -+#define PVRSRV_TIMER_TOTAL_IN_TICKS(X) asTimers[X].ui32Total -+#define PVRSRV_TIMER_TOTAL_IN_MS(X) ((1000*asTimers[X].ui32Total)/ui32TicksPerMS) -+#define PVRSRV_TIMER_COUNT(X) asTimers[X].ui32Count -+ -+ -+Temporal_Data asTimers[PVRSRV_NUM_TIMERS]; -+ -+ -+/*********************************************************************************** -+ Function Name : PVRSRVTimeNow -+ Inputs : None -+ Outputs : None -+ Returns : Current timer register value -+ Description : Returns the current timer register value -+************************************************************************************/ -+IMG_UINT32 PVRSRVTimeNow(IMG_VOID) -+{ -+ if (!pui32TimerRegister) -+ { -+ static IMG_BOOL bFirstTime = IMG_TRUE; -+ -+ if (bFirstTime) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVTimeNow: No timer register set up")); -+ -+ bFirstTime = IMG_FALSE; -+ } -+ -+ return 0; -+ } -+ -+#if defined(__sh__) -+ -+ return (0xffffffff-*pui32TimerRegister); -+ -+#else /* defined(__sh__) */ -+ -+ return 0; -+ -+#endif /* defined(__sh__) */ -+} -+ -+ -+/*********************************************************************************** -+ Function Name : PVRSRVGetCPUFreq -+ Inputs : None -+ Outputs : None -+ Returns : CPU timer frequency -+ Description : Returns the CPU timer frequency -+************************************************************************************/ -+static IMG_UINT32 PVRSRVGetCPUFreq(IMG_VOID) -+{ -+ IMG_UINT32 ui32Time1, ui32Time2; -+ -+ ui32Time1 = PVRSRVTimeNow(); -+ -+ OSWaitus(1000000); -+ -+ ui32Time2 = PVRSRVTimeNow(); -+ -+ PVR_DPF((PVR_DBG_WARNING, "PVRSRVGetCPUFreq: timer frequency = %d Hz", ui32Time2 - ui32Time1)); -+ -+ return (ui32Time2 - ui32Time1); -+} -+ -+ -+/*********************************************************************************** -+ Function Name : PVRSRVSetupMetricTimers -+ Inputs : pvDevInfo -+ Outputs : None -+ Returns : None -+ Description : Resets metric timers and sets up the timer register -+************************************************************************************/ -+IMG_VOID PVRSRVSetupMetricTimers(IMG_VOID *pvDevInfo) -+{ -+ IMG_UINT32 ui32Loop; -+ -+ PVR_UNREFERENCED_PARAMETER(pvDevInfo); -+ -+ for(ui32Loop=0; ui32Loop < (PVRSRV_NUM_TIMERS); ui32Loop++) -+ { -+ asTimers[ui32Loop].ui32Total = 0; -+ asTimers[ui32Loop].ui32Count = 0; -+ } -+ -+ #if defined(__sh__) -+ -+ /* timer control register */ -+ // clock / 1024 when TIMER_DIVISOR = 4 -+ // underflow int disabled -+ // we get approx 38 uS per timer tick -+ *TCR_2 = TIMER_DIVISOR; -+ -+ /* reset the timer counter to 0 */ -+ *TCOR_2 = *TCNT_2 = (IMG_UINT)0xffffffff; -+ -+ /* start timer 2 */ -+ *TST_REG |= (IMG_UINT8)0x04; -+ -+ pui32TimerRegister = (IMG_UINT32 *)TCNT_2; -+ -+ #else /* defined(__sh__) */ -+ -+ pui32TimerRegister = 0; -+ -+ #endif /* defined(__sh__) */ -+} -+ -+ -+/*********************************************************************************** -+ Function Name : PVRSRVOutputMetricTotals -+ Inputs : None -+ Outputs : None -+ Returns : None -+ Description : Displays final metric data -+************************************************************************************/ -+IMG_VOID PVRSRVOutputMetricTotals(IMG_VOID) -+{ -+ IMG_UINT32 ui32TicksPerMS, ui32Loop; -+ -+ ui32TicksPerMS = PVRSRVGetCPUFreq(); -+ -+ if (!ui32TicksPerMS) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVOutputMetricTotals: Failed to get CPU Freq")); -+ return; -+ } -+ -+ for(ui32Loop=0; ui32Loop < (PVRSRV_NUM_TIMERS); ui32Loop++) -+ { -+ if (asTimers[ui32Loop].ui32Count & 0x80000000L) -+ { -+ PVR_DPF((PVR_DBG_WARNING,"PVRSRVOutputMetricTotals: Timer %u is still ON", ui32Loop)); -+ } -+ } -+#if 0 -+ /* -+ ** EXAMPLE TIMER OUTPUT -+ */ -+ PVR_DPF((PVR_DBG_ERROR," Timer(%u): Total = %u",PVRSRV_TIMER_EXAMPLE_1, PVRSRV_TIMER_TOTAL_IN_TICKS(PVRSRV_TIMER_EXAMPLE_1))); -+ PVR_DPF((PVR_DBG_ERROR," Timer(%u): Time = %ums",PVRSRV_TIMER_EXAMPLE_1, PVRSRV_TIMER_TOTAL_IN_MS(PVRSRV_TIMER_EXAMPLE_1))); -+ PVR_DPF((PVR_DBG_ERROR," Timer(%u): Count = %u",PVRSRV_TIMER_EXAMPLE_1, PVRSRV_TIMER_COUNT(PVRSRV_TIMER_EXAMPLE_1))); -+#endif -+} -+ -+#endif /* defined(DEBUG) || defined(TIMING) */ -+ -+/****************************************************************************** -+ End of file (metrics.c) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/common/osfunc_common.c b/drivers/staging/ti-es8-sgx/services4/srvkm/common/osfunc_common.c -new file mode 100644 -index 0000000..2b4ec8c ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/common/osfunc_common.c -@@ -0,0 +1,46 @@ -+/*************************************************************************/ /*! -+@Title Wrapper layer for osfunc routines that have common code. -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Adds extra memory to the allocations to trace the memory bounds -+ and other runtime information. -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#include "img_types.h" -+#include "services_headers.h" -+#include "osfunc.h" -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/common/pdump_common.c b/drivers/staging/ti-es8-sgx/services4/srvkm/common/pdump_common.c -new file mode 100644 -index 0000000..a1eee7f ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/common/pdump_common.c -@@ -0,0 +1,3056 @@ -+/*************************************************************************/ /*! -+@Title Common PDump functions -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#if defined(PDUMP) -+#include <stdarg.h> -+ -+#include "services_headers.h" -+#include "perproc.h" -+ -+/* pdump headers */ -+#include "pdump_km.h" -+#include "pdump_int.h" -+ -+/* Allow temporary buffer size override */ -+#if !defined(PDUMP_TEMP_BUFFER_SIZE) -+#define PDUMP_TEMP_BUFFER_SIZE (64 * 1024U) -+#endif -+ -+/* DEBUG */ -+#if 1 -+#define PDUMP_DBG(a) PDumpOSDebugPrintf (a) -+#else -+#define PDUMP_DBG(a) -+#endif -+ -+ -+#define PTR_PLUS(t, p, x) ((t)(((IMG_CHAR *)(p)) + (x))) -+#define VPTR_PLUS(p, x) PTR_PLUS(IMG_VOID *, p, x) -+#define VPTR_INC(p, x) ((p) = VPTR_PLUS(p, x)) -+#define MAX_PDUMP_MMU_CONTEXTS (32) -+static IMG_VOID *gpvTempBuffer = IMG_NULL; -+static IMG_HANDLE ghTempBufferBlockAlloc; -+static IMG_UINT16 gui16MMUContextUsage = 0; -+ -+#if defined(PDUMP_DEBUG_OUTFILES) -+/* counter increments each time debug write is called */ -+IMG_UINT32 g_ui32EveryLineCounter = 1U; -+#endif -+ -+#if defined(SUPPORT_PDUMP_MULTI_PROCESS) -+ -+ -+IMG_BOOL _PDumpIsProcessActive(IMG_VOID) -+{ -+ PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData(); -+ if(psPerProc == IMG_NULL) -+ { -+ /* FIXME: kernel process logs some comments when kernel module is -+ * loaded, want to keep those. -+ */ -+ return IMG_TRUE; -+ } -+ return psPerProc->bPDumpActive; -+} -+ -+#endif /* SUPPORT_PDUMP_MULTI_PROCESS */ -+ -+#if defined(PDUMP_DEBUG_OUTFILES) -+static INLINE -+IMG_UINT32 _PDumpGetPID(IMG_VOID) -+{ -+ PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData(); -+ if(psPerProc == IMG_NULL) -+ { -+ /* Kernel PID */ -+ return 0; -+ } -+ return psPerProc->ui32PID; -+} -+#endif /* PDUMP_DEBUG_OUTFILES */ -+ -+/************************************************************************** -+ * Function Name : GetTempBuffer -+ * Inputs : None -+ * Outputs : None -+ * Returns : Temporary buffer address, or IMG_NULL -+ * Description : Get temporary buffer address. -+**************************************************************************/ -+static IMG_VOID *GetTempBuffer(IMG_VOID) -+{ -+ /* -+ * Allocate the temporary buffer, it it hasn't been allocated already. -+ * Return the address of the temporary buffer, or IMG_NULL if it -+ * couldn't be allocated. -+ * It is expected that the buffer will be allocated once, at driver -+ * load time, and left in place until the driver unloads. -+ */ -+ -+ if (gpvTempBuffer == IMG_NULL) -+ { -+ PVRSRV_ERROR eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ PDUMP_TEMP_BUFFER_SIZE, -+ &gpvTempBuffer, -+ &ghTempBufferBlockAlloc, -+ "PDUMP Temporary Buffer"); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "GetTempBuffer: OSAllocMem failed: %d", eError)); -+ } -+ } -+ -+ return gpvTempBuffer; -+} -+ -+static IMG_VOID FreeTempBuffer(IMG_VOID) -+{ -+ -+ if (gpvTempBuffer != IMG_NULL) -+ { -+ PVRSRV_ERROR eError = OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, -+ PDUMP_TEMP_BUFFER_SIZE, -+ gpvTempBuffer, -+ ghTempBufferBlockAlloc); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "FreeTempBuffer: OSFreeMem failed: %d", eError)); -+ } -+ else -+ { -+ gpvTempBuffer = IMG_NULL; -+ } -+ } -+} -+ -+IMG_VOID PDumpInitCommon(IMG_VOID) -+{ -+ /* Allocate temporary buffer for copying from user space */ -+ (IMG_VOID) GetTempBuffer(); -+ -+ /* Call environment specific PDump initialisation */ -+ PDumpInit(); -+} -+ -+IMG_VOID PDumpDeInitCommon(IMG_VOID) -+{ -+ /* Free temporary buffer */ -+ FreeTempBuffer(); -+ -+ /* Call environment specific PDump Deinitialisation */ -+ PDumpDeInit(); -+} -+ -+IMG_BOOL PDumpIsSuspended(IMG_VOID) -+{ -+ return PDumpOSIsSuspended(); -+} -+ -+IMG_BOOL PDumpIsCaptureFrameKM(IMG_VOID) -+{ -+#if defined(SUPPORT_PDUMP_MULTI_PROCESS) -+ if( _PDumpIsProcessActive() ) -+ { -+ return PDumpOSIsCaptureFrameKM(); -+ } -+ return IMG_FALSE; -+#else -+ return PDumpOSIsCaptureFrameKM(); -+#endif -+} -+ -+PVRSRV_ERROR PDumpSetFrameKM(IMG_UINT32 ui32Frame) -+{ -+#if defined(SUPPORT_PDUMP_MULTI_PROCESS) -+ if( _PDumpIsProcessActive() ) -+ { -+ return PDumpOSSetFrameKM(ui32Frame); -+ } -+ return PVRSRV_OK; -+#else -+ return PDumpOSSetFrameKM(ui32Frame); -+#endif -+} -+ -+/************************************************************************** -+ * Function Name : PDumpRegWithFlagsKM -+ * Inputs : pszPDumpDevName, Register offset, and value to write -+ * Outputs : None -+ * Returns : PVRSRV_ERROR -+ * Description : Create a PDUMP string, which represents a register write -+**************************************************************************/ -+PVRSRV_ERROR PDumpRegWithFlagsKM(IMG_CHAR *pszPDumpRegName, -+ IMG_UINT32 ui32Reg, -+ IMG_UINT32 ui32Data, -+ IMG_UINT32 ui32Flags) -+{ -+ PVRSRV_ERROR eErr; -+ PDUMP_GET_SCRIPT_STRING() -+ -+ PDUMP_LOCK(); -+ PDUMP_DBG(("PDumpRegWithFlagsKM")); -+ -+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "WRW :%s:0x%08X 0x%08X\r\n", -+ pszPDumpRegName, ui32Reg, ui32Data); -+ if(eErr != PVRSRV_OK) -+ { -+ PDUMP_UNLOCK(); -+ return eErr; -+ } -+ PDumpOSWriteString2(hScript, ui32Flags); -+ -+ PDUMP_UNLOCK(); -+ return PVRSRV_OK; -+} -+ -+/************************************************************************** -+ * Function Name : PDumpRegKM -+ * Inputs : Register offset, and value to write -+ * Outputs : None -+ * Returns : PVRSRV_ERROR -+ * Description : Create a PDUMP string, which represents a register write -+**************************************************************************/ -+PVRSRV_ERROR PDumpRegKM(IMG_CHAR *pszPDumpRegName, -+ IMG_UINT32 ui32Reg, -+ IMG_UINT32 ui32Data) -+{ -+ return PDumpRegWithFlagsKM(pszPDumpRegName, ui32Reg, ui32Data, PDUMP_FLAGS_CONTINUOUS); -+} -+ -+/************************************************************************** -+ * Function Name : PDumpRegPolWithFlagsKM -+ * Inputs : Description of what this register read is trying to do -+ * pszPDumpDevName -+ * Register offset -+ * expected value -+ * mask for that value -+ * Outputs : None -+ * Returns : None -+ * Description : Create a PDUMP string which represents a register read -+ * with the expected value -+**************************************************************************/ -+PVRSRV_ERROR PDumpRegPolWithFlagsKM(IMG_CHAR *pszPDumpRegName, -+ IMG_UINT32 ui32RegAddr, -+ IMG_UINT32 ui32RegValue, -+ IMG_UINT32 ui32Mask, -+ IMG_UINT32 ui32Flags, -+ PDUMP_POLL_OPERATOR eOperator) -+{ -+ /* Timings correct for linux and XP */ -+ #define POLL_DELAY 1000U -+ #define POLL_COUNT_LONG (2000000000U / POLL_DELAY) -+ #define POLL_COUNT_SHORT (1000000U / POLL_DELAY) -+ -+ PVRSRV_ERROR eErr; -+ IMG_UINT32 ui32PollCount; -+ PDUMP_GET_SCRIPT_STRING(); -+ -+ PDUMP_LOCK(); -+ PDUMP_DBG(("PDumpRegPolWithFlagsKM")); -+ -+ ui32PollCount = POLL_COUNT_LONG; -+ -+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "POL :%s:0x%08X 0x%08X 0x%08X %d %u %d\r\n", -+ pszPDumpRegName, ui32RegAddr, ui32RegValue, -+ ui32Mask, eOperator, ui32PollCount, POLL_DELAY); -+ if(eErr != PVRSRV_OK) -+ { -+ PDUMP_UNLOCK(); -+ return eErr; -+ } -+ PDumpOSWriteString2(hScript, ui32Flags); -+ -+ PDUMP_UNLOCK(); -+ return PVRSRV_OK; -+} -+ -+ -+/************************************************************************** -+ * Function Name : PDumpRegPol -+ * Inputs : Description of what this register read is trying to do -+ * pszPDumpDevName -+ Register offset -+ * expected value -+ * mask for that value -+ * Outputs : None -+ * Returns : None -+ * Description : Create a PDUMP string which represents a register read -+ * with the expected value -+**************************************************************************/ -+PVRSRV_ERROR PDumpRegPolKM(IMG_CHAR *pszPDumpRegName, IMG_UINT32 ui32RegAddr, IMG_UINT32 ui32RegValue, IMG_UINT32 ui32Mask, PDUMP_POLL_OPERATOR eOperator) -+{ -+ return PDumpRegPolWithFlagsKM(pszPDumpRegName, ui32RegAddr, ui32RegValue, ui32Mask, PDUMP_FLAGS_CONTINUOUS, eOperator); -+} -+ -+/************************************************************************** -+ * Function Name : PDumpMallocPages -+ * Inputs : psDevID, ui32DevVAddr, pvLinAddr, ui32NumBytes, hOSMemHandle -+ * : hUniqueTag -+ * Outputs : None -+ * Returns : None -+ * Description : Malloc memory pages -+ -+FIXME: This function assumes pvLinAddr is the address of the start of the -+block for this hOSMemHandle. -+If this isn't true, the call to PDumpOSCPUVAddrToDevPAddr below will be -+incorrect. (Consider using OSMemHandleToCPUPAddr() instead?) -+The only caller at the moment is in buffer_manager.c, which does the right -+thing. -+**************************************************************************/ -+PVRSRV_ERROR PDumpMallocPages (PVRSRV_DEVICE_IDENTIFIER *psDevID, -+ IMG_UINT32 ui32DevVAddr, -+ IMG_CPU_VIRTADDR pvLinAddr, -+ IMG_HANDLE hOSMemHandle, -+ IMG_UINT32 ui32NumBytes, -+ IMG_UINT32 ui32PageSize, -+ IMG_HANDLE hUniqueTag, -+ IMG_UINT32 ui32Flags) -+{ -+ PVRSRV_ERROR eErr; -+ IMG_PUINT8 pui8LinAddr; -+ IMG_UINT32 ui32Offset; -+ IMG_UINT32 ui32NumPages; -+ IMG_DEV_PHYADDR sDevPAddr; -+ IMG_UINT32 ui32Page; -+ IMG_UINT32 ui32PageSizeShift = 0; -+ IMG_UINT32 ui32PageSizeTmp; -+ PDUMP_GET_SCRIPT_STRING(); -+ -+ PDUMP_LOCK(); -+ -+ /* However, lin addr is only required in non-linux OSes */ -+#if !defined(LINUX) -+ PVR_ASSERT(((IMG_UINTPTR_T)pvLinAddr & HOST_PAGEMASK) == 0); -+#endif -+ -+ PVR_ASSERT(((IMG_UINT32) ui32DevVAddr & HOST_PAGEMASK) == 0); -+ PVR_ASSERT(((IMG_UINT32) ui32NumBytes & HOST_PAGEMASK) == 0); -+ -+ /* -+ Compute the amount to right-shift in order to divide by the page-size. -+ Required for 32-bit PAE kernels (thus phys addresses are 64-bits) where -+ 64-bit division is unsupported. -+ */ -+ ui32PageSizeTmp = ui32PageSize; -+ while (ui32PageSizeTmp >>= 1) -+ ui32PageSizeShift++; -+ -+ /* -+ Write a comment to the PDump2 script streams indicating the memory allocation -+ */ -+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "-- MALLOC :%s:VA_%08X 0x%08X %u (%d pages)\r\n", -+ psDevID->pszPDumpDevName, ui32DevVAddr, ui32NumBytes, ui32PageSize, ui32NumBytes / ui32PageSize); -+ if(eErr != PVRSRV_OK) -+ { -+ PDUMP_UNLOCK(); -+ return eErr; -+ } -+ PDumpOSWriteString2(hScript, ui32Flags); -+ -+ /* -+ Write to the MMU script stream indicating the memory allocation -+ */ -+ pui8LinAddr = (IMG_PUINT8) pvLinAddr; -+ ui32Offset = 0; -+ ui32NumPages = ui32NumBytes >> ui32PageSizeShift; -+ while (ui32NumPages) -+ { -+ ui32NumPages--; -+ -+ /* See FIXME in function header. -+ * Currently: linux pdump uses OSMemHandle and Offset -+ * other OSes use the LinAddr. -+ */ -+ /* Calculate the device physical address for this page */ -+ PDumpOSCPUVAddrToDevPAddr(psDevID->eDeviceType, -+ hOSMemHandle, -+ ui32Offset, -+ pui8LinAddr, -+ ui32PageSize, -+ &sDevPAddr); -+ ui32Page = (IMG_UINT32)(sDevPAddr.uiAddr >> ui32PageSizeShift); -+ /* increment kernel virtual address */ -+ pui8LinAddr += ui32PageSize; -+ ui32Offset += ui32PageSize; -+ -+ sDevPAddr.uiAddr = ui32Page * ui32PageSize; -+ -+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "MALLOC :%s:PA_" UINTPTR_FMT DEVPADDR_FMT " %u %u 0x" DEVPADDR_FMT "\r\n", -+ psDevID->pszPDumpDevName, -+ (IMG_UINTPTR_T)hUniqueTag, -+ sDevPAddr.uiAddr, -+ ui32PageSize, -+ ui32PageSize, -+ sDevPAddr.uiAddr); -+ if(eErr != PVRSRV_OK) -+ { -+ PDUMP_UNLOCK(); -+ return eErr; -+ } -+ PDumpOSWriteString2(hScript, ui32Flags); -+ } -+ -+ PDUMP_UNLOCK(); -+ return PVRSRV_OK; -+} -+ -+ -+/************************************************************************** -+ * Function Name : PDumpMallocPageTable -+ * Inputs : psDevId, pvLinAddr, ui32NumBytes, hUniqueTag -+ * Outputs : None -+ * Returns : None -+ * Description : Malloc memory page table -+**************************************************************************/ -+PVRSRV_ERROR PDumpMallocPageTable (PVRSRV_DEVICE_IDENTIFIER *psDevId, -+ IMG_HANDLE hOSMemHandle, -+ IMG_UINT32 ui32Offset, -+ IMG_CPU_VIRTADDR pvLinAddr, -+ IMG_UINT32 ui32PTSize, -+ IMG_UINT32 ui32Flags, -+ IMG_HANDLE hUniqueTag) -+{ -+ PVRSRV_ERROR eErr; -+ IMG_DEV_PHYADDR sDevPAddr; -+ PDUMP_GET_SCRIPT_STRING(); -+ -+ PDUMP_LOCK(); -+ PVR_ASSERT(((IMG_UINTPTR_T)pvLinAddr & (ui32PTSize - 1)) == 0); -+ -+ ui32Flags |= PDUMP_FLAGS_CONTINUOUS; -+ -+ /* -+ Write a comment to the PDump2 script streams indicating the memory allocation -+ */ -+ eErr = PDumpOSBufprintf(hScript, -+ ui32MaxLen, -+ "-- MALLOC :%s:PAGE_TABLE 0x%08X %u\r\n", -+ psDevId->pszPDumpDevName, -+ ui32PTSize, -+ ui32PTSize); -+ if(eErr != PVRSRV_OK) -+ { -+ PDUMP_UNLOCK(); -+ return eErr; -+ } -+ PDumpOSWriteString2(hScript, ui32Flags); -+ -+ /* -+ Write to the MMU script stream indicating the memory allocation -+ */ -+ // FIXME: we'll never need more than a 4k page for a pagetable -+ // fixing to 1 page for now. -+ // note: when the mmu code supports packed pagetables the PTs -+ // will be as small as 16bytes -+ -+ PDumpOSCPUVAddrToDevPAddr(psDevId->eDeviceType, -+ hOSMemHandle, /* um - does this mean the pvLinAddr would be ignored? Is that safe? */ -+ ui32Offset, -+ (IMG_PUINT8) pvLinAddr, -+ ui32PTSize, -+ &sDevPAddr); -+ -+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "MALLOC :%s:PA_" UINTPTR_FMT DEVPADDR_FMT -+ " 0x%X %u 0x" DEVPADDR_FMT "\r\n", -+ psDevId->pszPDumpDevName, -+ (IMG_UINTPTR_T)hUniqueTag, -+ sDevPAddr.uiAddr, -+ ui32PTSize,//size -+ ui32PTSize,//alignment -+ sDevPAddr.uiAddr); -+ if(eErr != PVRSRV_OK) -+ { -+ PDUMP_UNLOCK(); -+ return eErr; -+ } -+ PDumpOSWriteString2(hScript, ui32Flags); -+ -+ PDUMP_UNLOCK(); -+ return PVRSRV_OK; -+} -+ -+/************************************************************************** -+ * Function Name : PDumpFreePages -+ * Inputs : psBMHeap, sDevVAddr, ui32NumBytes, hUniqueTag, -+ bInterLeaved -+ * Outputs : None -+ * Returns : None -+ * Description : Free memory pages -+**************************************************************************/ -+PVRSRV_ERROR PDumpFreePages (BM_HEAP *psBMHeap, -+ IMG_DEV_VIRTADDR sDevVAddr, -+ IMG_UINT32 ui32NumBytes, -+ IMG_UINT32 ui32PageSize, -+ IMG_HANDLE hUniqueTag, -+ IMG_BOOL bInterleaved, -+ IMG_BOOL bSparse, -+ IMG_UINT32 ui32Flags) -+{ -+ PVRSRV_ERROR eErr; -+ IMG_UINT32 ui32NumPages, ui32PageCounter; -+ IMG_DEV_PHYADDR sDevPAddr; -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+ PDUMP_GET_SCRIPT_STRING(); -+ -+ PDUMP_LOCK(); -+ PVR_ASSERT(((IMG_UINT32) sDevVAddr.uiAddr & (ui32PageSize - 1)) == 0); -+ PVR_ASSERT(((IMG_UINT32) ui32NumBytes & (ui32PageSize - 1)) == 0); -+ -+ psDeviceNode = psBMHeap->pBMContext->psDeviceNode; -+ -+ /* -+ Write a comment to the PDUMP2 script streams indicating the memory free -+ */ -+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "-- FREE :%s:VA_%08X\r\n", -+ psDeviceNode->sDevId.pszPDumpDevName, sDevVAddr.uiAddr); -+ if(eErr != PVRSRV_OK) -+ { -+ PDUMP_UNLOCK(); -+ return eErr; -+ } -+ -+ PDumpOSWriteString2(hScript, ui32Flags); -+ -+ /* -+ Write to the MMU script stream indicating the memory free -+ */ -+ ui32NumPages = ui32NumBytes / ui32PageSize; -+ for (ui32PageCounter = 0; ui32PageCounter < ui32NumPages; ui32PageCounter++) -+ { -+ if (!bInterleaved || (ui32PageCounter % 2) == 0) -+ { -+ sDevPAddr = psDeviceNode->pfnMMUGetPhysPageAddr(psBMHeap->pMMUHeap, sDevVAddr); -+ -+ /* With sparse mappings we expect spaces */ -+ if (bSparse && (sDevPAddr.uiAddr == 0)) -+ { -+ continue; -+ } -+ -+ PVR_ASSERT(sDevPAddr.uiAddr != 0); -+ -+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "FREE :%s:PA_" UINTPTR_FMT DEVPADDR_FMT "\r\n", -+ psDeviceNode->sDevId.pszPDumpDevName, -+ (IMG_UINTPTR_T)hUniqueTag, -+ sDevPAddr.uiAddr); -+ if(eErr != PVRSRV_OK) -+ { -+ PDUMP_UNLOCK(); -+ return eErr; -+ } -+ PDumpOSWriteString2(hScript, ui32Flags); -+ } -+ else -+ { -+ /* Gap pages in an interleaved allocation should be ignored. */ -+ } -+ -+ sDevVAddr.uiAddr += ui32PageSize; -+ } -+ -+ PDUMP_UNLOCK(); -+ return PVRSRV_OK; -+} -+ -+/************************************************************************** -+ * Function Name : PDumpFreePageTable -+ * Inputs : psDevID, pvLinAddr, ui32NumBytes, hUniqueTag -+ * Outputs : None -+ * Returns : None -+ * Description : Free memory page table -+**************************************************************************/ -+PVRSRV_ERROR PDumpFreePageTable (PVRSRV_DEVICE_IDENTIFIER *psDevID, -+ IMG_HANDLE hOSMemHandle, -+ IMG_CPU_VIRTADDR pvLinAddr, -+ IMG_UINT32 ui32PTSize, -+ IMG_UINT32 ui32Flags, -+ IMG_HANDLE hUniqueTag) -+{ -+ PVRSRV_ERROR eErr; -+ IMG_DEV_PHYADDR sDevPAddr; -+ PDUMP_GET_SCRIPT_STRING(); -+ PVR_UNREFERENCED_PARAMETER(ui32PTSize); -+ -+ PDUMP_LOCK(); -+ -+ /* override QAC warning about wrap around */ -+ PVR_ASSERT(((IMG_UINTPTR_T)pvLinAddr & (ui32PTSize-1UL)) == 0); /* PRQA S 3382 */ -+ -+ /* -+ Write a comment to the PDUMP2 script streams indicating the memory free -+ */ -+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "-- FREE :%s:PAGE_TABLE\r\n", psDevID->pszPDumpDevName); -+ if(eErr != PVRSRV_OK) -+ { -+ PDUMP_UNLOCK(); -+ return eErr; -+ } -+ PDumpOSWriteString2(hScript, ui32Flags); -+ -+ /* -+ Write to the MMU script stream indicating the memory free -+ */ -+ // FIXME: we'll never need more than a 4k page for a pagetable -+ // fixing to 1 page for now. -+ // note: when the mmu code supports packed pagetables the PTs -+ // will be as small as 16bytes -+ -+ PDumpOSCPUVAddrToDevPAddr(psDevID->eDeviceType, -+ hOSMemHandle, /* um - does this mean the pvLinAddr would be ignored? Is that safe? */ -+ 0, -+ (IMG_PUINT8) pvLinAddr, -+ ui32PTSize, -+ &sDevPAddr); -+ -+ { -+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "FREE :%s:PA_" UINTPTR_FMT DEVPADDR_FMT "\r\n", -+ psDevID->pszPDumpDevName, -+ (IMG_UINTPTR_T)hUniqueTag, -+ sDevPAddr.uiAddr); -+ if(eErr != PVRSRV_OK) -+ { -+ PDUMP_UNLOCK(); -+ return eErr; -+ } -+ PDumpOSWriteString2(hScript, ui32Flags); -+ } -+ -+ PDUMP_UNLOCK(); -+ return PVRSRV_OK; -+} -+ -+/************************************************************************** -+ * Function Name : PDumpPDRegWithFlags -+ * Inputs : psMMUAttrib -+ * : ui32Reg -+ * : ui32Data -+ * : hUniqueTag -+ * Outputs : None -+ * Returns : None -+ * Description : Kernel Services internal pdump memory API -+ * Used for registers specifying physical addresses -+ e.g. MMU page directory register -+**************************************************************************/ -+PVRSRV_ERROR PDumpPDRegWithFlags(PDUMP_MMU_ATTRIB *psMMUAttrib, -+ IMG_UINT32 ui32Reg, -+ IMG_UINT32 ui32Data, -+ IMG_UINT32 ui32Flags, -+ IMG_HANDLE hUniqueTag) -+{ -+ PVRSRV_ERROR eErr; -+ IMG_CHAR *pszRegString; -+ IMG_DEV_PHYADDR sDevPAddr; -+ -+ PDUMP_GET_SCRIPT_STRING() -+ -+ PDUMP_LOCK(); -+ if(psMMUAttrib->pszPDRegRegion != IMG_NULL) -+ { -+ pszRegString = psMMUAttrib->pszPDRegRegion; -+ } -+ else -+ { -+ pszRegString = psMMUAttrib->sDevId.pszPDumpRegName; -+ } -+ -+ /* -+ Write to the MMU script stream indicating the physical page directory -+ */ -+#if defined(SGX_FEATURE_36BIT_MMU) -+ sDevPAddr.uiAddr = ((ui32Data & psMMUAttrib->ui32PDEMask) << psMMUAttrib->ui32PDEAlignShift); -+ -+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, -+ "WRW :%s:$1 :%s:PA_" UINTPTR_FMT DEVPADDR_FMT ":0x%08X\r\n", -+ psMMUAttrib->sDevId.pszPDumpDevName, -+ psMMUAttrib->sDevId.pszPDumpDevName, -+ (IMG_UINTPTR_T)hUniqueTag, -+ sDevPAddr.uiAddr, -+ ui32Data & ~psMMUAttrib->ui32PDEMask); -+ if(eErr != PVRSRV_OK) -+ { -+ PDUMP_UNLOCK(); -+ return eErr; -+ } -+ PDumpOSWriteString2(hScript, ui32Flags); -+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "SHR :%s:$1 :%s:$1 0x4\r\n", -+ psMMUAttrib->sDevId.pszPDumpDevName, -+ psMMUAttrib->sDevId.pszPDumpDevName); -+ if(eErr != PVRSRV_OK) -+ { -+ PDUMP_UNLOCK(); -+ return eErr; -+ } -+ PDumpOSWriteString2(hScript, ui32Flags); -+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, -+ "WRW :%s:0x%08X: %s:$1\r\n", -+ pszRegString, -+ ui32Reg, -+ psMMUAttrib->sDevId.pszPDumpDevName); -+ if(eErr != PVRSRV_OK) -+ { -+ PDUMP_UNLOCK(); -+ return eErr; -+ } -+ PDumpOSWriteString2(hScript, ui32Flags); -+#else -+ sDevPAddr.uiAddr = ((ui32Data & psMMUAttrib->ui32PDEMask) << psMMUAttrib->ui32PDEAlignShift); -+ -+ eErr = PDumpOSBufprintf(hScript, -+ ui32MaxLen, -+ "WRW :%s:0x%08X :%s:PA_" UINTPTR_FMT DEVPADDR_FMT ":0x%08X\r\n", -+ pszRegString, -+ ui32Reg, -+ psMMUAttrib->sDevId.pszPDumpDevName, -+ (IMG_UINTPTR_T)hUniqueTag, -+ sDevPAddr.uiAddr, -+ ui32Data & ~psMMUAttrib->ui32PDEMask); -+ if(eErr != PVRSRV_OK) -+ { -+ PDUMP_UNLOCK(); -+ return eErr; -+ } -+ PDumpOSWriteString2(hScript, ui32Flags); -+#endif -+ -+ PDUMP_UNLOCK(); -+ return PVRSRV_OK; -+} -+ -+/************************************************************************** -+ * Function Name : PDumpPDReg -+ * Inputs : psMMUAttrib -+ : ui32Reg -+ * : ui32Data -+ * : hUniqueTag -+ * Outputs : None -+ * Returns : PVRSRV_ERROR -+ * Description : Kernel Services internal pdump memory API -+ * Used for registers specifying physical addresses -+ e.g. MMU page directory register -+**************************************************************************/ -+PVRSRV_ERROR PDumpPDReg (PDUMP_MMU_ATTRIB *psMMUAttrib, -+ IMG_UINT32 ui32Reg, -+ IMG_UINT32 ui32Data, -+ IMG_HANDLE hUniqueTag) -+{ -+ return PDumpPDRegWithFlags(psMMUAttrib, ui32Reg, ui32Data, PDUMP_FLAGS_CONTINUOUS, hUniqueTag); -+} -+ -+/************************************************************************** -+ * Function Name : PDumpMemPolKM -+ * Inputs : psMemInfo -+ * : ui32Offset -+ * : ui32Value -+ * : ui32Mask -+ * : eOperator -+ * : ui32Flags -+ * : hUniqueTag -+ * Outputs : None -+ * Returns : PVRSRV_ERROR -+ * Description : Implements Client pdump memory poll API -+**************************************************************************/ -+PVRSRV_ERROR PDumpMemPolKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo, -+ IMG_UINT32 ui32Offset, -+ IMG_UINT32 ui32Value, -+ IMG_UINT32 ui32Mask, -+ PDUMP_POLL_OPERATOR eOperator, -+ IMG_UINT32 ui32Flags, -+ IMG_HANDLE hUniqueTag) -+{ -+ #define MEMPOLL_DELAY (1000) -+ #define MEMPOLL_COUNT (2000000000 / MEMPOLL_DELAY) -+ -+ PVRSRV_ERROR eErr; -+ IMG_UINT32 ui32PageOffset; -+ IMG_UINT8 *pui8LinAddr; -+ IMG_DEV_PHYADDR sDevPAddr; -+ IMG_DEV_VIRTADDR sDevVPageAddr; -+ PDUMP_MMU_ATTRIB *psMMUAttrib; -+ -+ PDUMP_GET_SCRIPT_STRING(); -+ -+ PDUMP_LOCK(); -+ if (PDumpOSIsSuspended()) -+ { -+ PDUMP_UNLOCK(); -+ return PVRSRV_OK; -+ } -+ -+ /* Check the offset and size don't exceed the bounds of the allocation */ -+ PVR_ASSERT((ui32Offset + sizeof(IMG_UINT32)) <= psMemInfo->uAllocSize); -+ -+ psMMUAttrib = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->psMMUAttrib; -+ -+ /* -+ Write a comment to the PDump2 script streams indicating the virtual memory pol -+ */ -+ eErr = PDumpOSBufprintf(hScript, -+ ui32MaxLen, -+ "-- POL :%s:VA_%08X 0x%08X 0x%08X %d %d %d\r\n", -+ psMMUAttrib->sDevId.pszPDumpDevName, -+ psMemInfo->sDevVAddr.uiAddr + ui32Offset, -+ ui32Value, -+ ui32Mask, -+ eOperator, -+ MEMPOLL_COUNT, -+ MEMPOLL_DELAY); -+ if(eErr != PVRSRV_OK) -+ { -+ PDUMP_UNLOCK(); -+ return eErr; -+ } -+ PDumpOSWriteString2(hScript, ui32Flags); -+ -+ -+ pui8LinAddr = psMemInfo->pvLinAddrKM; -+ -+ /* Advance address by offset */ -+ pui8LinAddr += ui32Offset; -+ -+ /* -+ query the buffer manager for the physical pages that back the -+ virtual address -+ */ -+ PDumpOSCPUVAddrToPhysPages(psMemInfo->sMemBlk.hOSMemHandle, -+ ui32Offset, -+ pui8LinAddr, -+ psMMUAttrib->ui32DataPageMask, -+ &ui32PageOffset); -+ -+ /* calculate the DevV page address */ -+ sDevVPageAddr.uiAddr = psMemInfo->sDevVAddr.uiAddr + ui32Offset - ui32PageOffset; -+ -+ PVR_ASSERT((sDevVPageAddr.uiAddr & psMMUAttrib->ui32DataPageMask) == 0); -+ -+ /* get the physical page address based on the device virtual address */ -+ BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr); -+ -+ /* convert DevP page address to byte address */ -+ sDevPAddr.uiAddr += ui32PageOffset; -+ -+ eErr = PDumpOSBufprintf(hScript, -+ ui32MaxLen, -+ "POL :%s:PA_" UINTPTR_FMT DEVPADDR_FMT ":0x%08X 0x%08X 0x%08X %d %d %d\r\n", -+ psMMUAttrib->sDevId.pszPDumpDevName, -+ (IMG_UINTPTR_T)hUniqueTag, -+ sDevPAddr.uiAddr & ~(psMMUAttrib->ui32DataPageMask), -+ (unsigned int)(sDevPAddr.uiAddr & (psMMUAttrib->ui32DataPageMask)), -+ ui32Value, -+ ui32Mask, -+ eOperator, -+ MEMPOLL_COUNT, -+ MEMPOLL_DELAY); -+ if(eErr != PVRSRV_OK) -+ { -+ PDUMP_UNLOCK(); -+ return eErr; -+ } -+ PDumpOSWriteString2(hScript, ui32Flags); -+ -+ PDUMP_UNLOCK(); -+ return PVRSRV_OK; -+} -+ -+/************************************************************************** -+ * Function Name : _PDumpMemIntKM -+ * Inputs : psMemInfo -+ * : ui32Offset -+ * : ui32Bytes -+ * : ui32Flags -+ * : hUniqueTag -+ * Outputs : None -+ * Returns : PVRSRV_ERROR -+ * Description : Implements Client pdump mem API -+**************************************************************************/ -+static PVRSRV_ERROR _PDumpMemIntKM(IMG_PVOID pvAltLinAddr, -+ PVRSRV_KERNEL_MEM_INFO *psMemInfo, -+ IMG_UINT32 ui32Offset, -+ IMG_UINT32 ui32Bytes, -+ IMG_UINT32 ui32Flags, -+ IMG_HANDLE hUniqueTag) -+{ -+ PVRSRV_ERROR eErr; -+ IMG_UINT32 ui32NumPages; -+ IMG_UINT32 ui32PageByteOffset; -+ IMG_UINT32 ui32BlockBytes; -+ IMG_UINT8* pui8LinAddr; -+ IMG_UINT8* pui8DataLinAddr = IMG_NULL; -+ IMG_DEV_VIRTADDR sDevVPageAddr; -+ IMG_DEV_VIRTADDR sDevVAddr; -+ IMG_DEV_PHYADDR sDevPAddr; -+ IMG_UINT32 ui32ParamOutPos; -+ PDUMP_MMU_ATTRIB *psMMUAttrib; -+ IMG_UINT32 ui32DataPageSize; -+ PDUMP_GET_SCRIPT_AND_FILE_STRING(); -+ -+ PDUMP_LOCK(); -+ /* PRQA S 3415 1 */ /* side effects desired */ -+ if (ui32Bytes == 0 || PDumpOSIsSuspended()) -+ { -+ PDUMP_UNLOCK(); -+ return PVRSRV_OK; -+ } -+ -+ psMMUAttrib = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->psMMUAttrib; -+ -+ /* -+ check the offset and size don't exceed the bounds of the allocation -+ */ -+ PVR_ASSERT((ui32Offset + ui32Bytes) <= psMemInfo->uAllocSize); -+ -+ if (!PDumpOSJTInitialised()) -+ { -+ PDUMP_UNLOCK(); -+ return PVRSRV_ERROR_PDUMP_NOT_AVAILABLE; -+ } -+ -+ /* setup memory addresses */ -+ if(pvAltLinAddr) -+ { -+ pui8DataLinAddr = pvAltLinAddr; -+ } -+ else if(psMemInfo->pvLinAddrKM) -+ { -+ pui8DataLinAddr = (IMG_UINT8 *)psMemInfo->pvLinAddrKM + ui32Offset; -+ } -+ pui8LinAddr = (IMG_UINT8 *)psMemInfo->pvLinAddrKM; -+ sDevVAddr = psMemInfo->sDevVAddr; -+ -+ /* advance address by offset */ -+ sDevVAddr.uiAddr += ui32Offset; -+ pui8LinAddr += ui32Offset; -+ -+ PVR_ASSERT(pui8DataLinAddr); -+ -+ PDumpOSCheckForSplitting(PDumpOSGetStream(PDUMP_STREAM_PARAM2), ui32Bytes, ui32Flags); -+ -+ ui32ParamOutPos = PDumpOSGetStreamOffset(PDUMP_STREAM_PARAM2); -+ -+ /* -+ write the binary data up-front. -+ */ -+ if(!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_PARAM2), -+ pui8DataLinAddr, -+ ui32Bytes, -+ ui32Flags)) -+ { -+ PDUMP_UNLOCK(); -+ return PVRSRV_ERROR_PDUMP_BUFFER_FULL; -+ } -+ -+ if (PDumpOSGetParamFileNum() == 0) -+ { -+ eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%.prm"); -+ } -+ else -+ { -+ eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%_%u.prm", PDumpOSGetParamFileNum()); -+ } -+ if(eErr != PVRSRV_OK) -+ { -+ PDUMP_UNLOCK(); -+ return eErr; -+ } -+ -+ /* -+ Write a comment to the PDump2 script streams indicating the virtual memory load -+ */ -+ eErr = PDumpOSBufprintf(hScript, -+ ui32MaxLenScript, -+ "-- LDB :%s:VA_" UINTPTR_FMT "%08X:0x%08X 0x%08X 0x%08X %s\r\n", -+ psMMUAttrib->sDevId.pszPDumpDevName, -+ (IMG_UINTPTR_T)hUniqueTag, -+ psMemInfo->sDevVAddr.uiAddr, -+ ui32Offset, -+ ui32Bytes, -+ ui32ParamOutPos, -+ pszFileName); -+ if(eErr != PVRSRV_OK) -+ { -+ PDUMP_UNLOCK(); -+ return eErr; -+ } -+ PDumpOSWriteString2(hScript, ui32Flags); -+ -+ /* -+ query the buffer manager for the physical pages that back the -+ virtual address -+ */ -+ PDumpOSCPUVAddrToPhysPages(psMemInfo->sMemBlk.hOSMemHandle, -+ ui32Offset, -+ pui8LinAddr, -+ psMMUAttrib->ui32DataPageMask, -+ &ui32PageByteOffset); -+ ui32DataPageSize = psMMUAttrib->ui32DataPageMask + 1; -+ ui32NumPages = (ui32PageByteOffset + ui32Bytes + psMMUAttrib->ui32DataPageMask) / ui32DataPageSize; -+ -+ while(ui32NumPages) -+ { -+ ui32NumPages--; -+ -+ /* calculate the DevV page address */ -+ sDevVPageAddr.uiAddr = sDevVAddr.uiAddr - ui32PageByteOffset; -+ -+ if (ui32DataPageSize <= PDUMP_TEMP_BUFFER_SIZE) -+ { -+ /* if a page fits within temp buffer, we should dump in page-aligned chunks. */ -+ PVR_ASSERT((sDevVPageAddr.uiAddr & psMMUAttrib->ui32DataPageMask) == 0); -+ } -+ -+ /* get the physical page address based on the device virtual address */ -+ BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr); -+ -+ /* convert DevP page address to byte address */ -+ sDevPAddr.uiAddr += ui32PageByteOffset; -+ -+ /* how many bytes to dump from this page */ -+ if (ui32PageByteOffset + ui32Bytes > ui32DataPageSize) -+ { -+ /* dump up to the page boundary */ -+ ui32BlockBytes = ui32DataPageSize - ui32PageByteOffset; -+ } -+ else -+ { -+ /* dump what's left */ -+ ui32BlockBytes = ui32Bytes; -+ } -+ -+ eErr = PDumpOSBufprintf(hScript, -+ ui32MaxLenScript, -+ "LDB :%s:PA_" UINTPTR_FMT DEVPADDR_FMT ":0x%08X 0x%08X 0x%08X %s\r\n", -+ psMMUAttrib->sDevId.pszPDumpDevName, -+ (IMG_UINTPTR_T)hUniqueTag, -+ sDevPAddr.uiAddr & ~(psMMUAttrib->ui32DataPageMask), -+ (unsigned int)(sDevPAddr.uiAddr & (psMMUAttrib->ui32DataPageMask)), -+ ui32BlockBytes, -+ ui32ParamOutPos, -+ pszFileName); -+ if(eErr != PVRSRV_OK) -+ { -+ PDUMP_UNLOCK(); -+ return eErr; -+ } -+ PDumpOSWriteString2(hScript, ui32Flags); -+ -+ /* update details for next page */ -+ -+#if defined(SGX_FEATURE_VARIABLE_MMU_PAGE_SIZE) -+ /* page may be larger than pdump temporary buffer */ -+ ui32PageByteOffset = (ui32PageByteOffset + ui32BlockBytes) % ui32DataPageSize; -+#else -+ /* page offset 0 after first page dump */ -+ ui32PageByteOffset = 0; -+#endif -+ /* bytes left over */ -+ ui32Bytes -= ui32BlockBytes; /* PRQA S 3382 */ /* QAC missed MIN test */ -+ /* advance devVaddr */ -+ sDevVAddr.uiAddr += ui32BlockBytes; -+ /* advance the cpuVaddr */ -+ pui8LinAddr += ui32BlockBytes; -+ /* update the file write offset */ -+ ui32ParamOutPos += ui32BlockBytes; -+ } -+ -+ PDUMP_UNLOCK(); -+ return PVRSRV_OK; -+} -+ -+/************************************************************************** -+ * Function Name : PDumpMemKM -+ * Inputs : psMemInfo -+ * : ui32Offset -+ * : ui32Bytes -+ * : ui32Flags -+ * : hUniqueTag -+ * Outputs : None -+ * Returns : PVRSRV_ERROR -+ * Description : Implements Client pdump mem API -+**************************************************************************/ -+PVRSRV_ERROR PDumpMemKM(IMG_PVOID pvAltLinAddr, -+ PVRSRV_KERNEL_MEM_INFO *psMemInfo, -+ IMG_UINT32 ui32Offset, -+ IMG_UINT32 ui32Bytes, -+ IMG_UINT32 ui32Flags, -+ IMG_HANDLE hUniqueTag) -+{ -+ /* -+ For now we don't support dumping sparse allocations that -+ are from within the kernel, or are from UM but without a -+ alternative linear address -+ */ -+ PVR_ASSERT((psMemInfo->ui32Flags & PVRSRV_MEM_SPARSE) == 0); -+ -+ if (psMemInfo->ui32Flags & PVRSRV_MEM_SPARSE) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ else -+ { -+ return _PDumpMemIntKM(pvAltLinAddr, -+ psMemInfo, -+ ui32Offset, -+ ui32Bytes, -+ ui32Flags, -+ hUniqueTag); -+ } -+} -+ -+PVRSRV_ERROR PDumpMemPDEntriesKM(PDUMP_MMU_ATTRIB *psMMUAttrib, -+ IMG_HANDLE hOSMemHandle, -+ IMG_CPU_VIRTADDR pvLinAddr, -+ IMG_UINT32 ui32Bytes, -+ IMG_UINT32 ui32Flags, -+ IMG_BOOL bInitialisePages, -+ IMG_HANDLE hUniqueTag1, -+ IMG_HANDLE hUniqueTag2) -+{ -+ PDUMP_MMU_ATTRIB sMMUAttrib; -+ -+ /* Override the (variable) PT size since PDs are always 4K in size */ -+ sMMUAttrib = *psMMUAttrib; -+ sMMUAttrib.ui32PTSize = (IMG_UINT32)HOST_PAGESIZE(); -+ return PDumpMemPTEntriesKM( &sMMUAttrib, -+ hOSMemHandle, -+ pvLinAddr, -+ ui32Bytes, -+ ui32Flags, -+ bInitialisePages, -+ hUniqueTag1, -+ hUniqueTag2); -+} -+ -+/************************************************************************** -+ * Function Name : PDumpMemPTEntriesKM -+ * Inputs : psMMUAttrib - MMU attributes for pdump -+ * : pvLinAddr - CPU address of PT base -+ * : ui32Bytes - size -+ * : ui32Flags - pdump flags -+ * : bInitialisePages - whether to initialise pages from file -+ * : hUniqueTag1 - ID for PT physical page -+ * : hUniqueTag2 - ID for target physical page (if !bInitialisePages) -+ * Outputs : None -+ * Returns : PVRSRV_ERROR -+ * Description : Kernel Services internal pdump memory API -+ * Used for memory without DevVAddress mappings -+ e.g. MMU page tables -+ FIXME: This function doesn't support non-4k data pages, -+ e.g. dummy data page -+**************************************************************************/ -+PVRSRV_ERROR PDumpMemPTEntriesKM(PDUMP_MMU_ATTRIB *psMMUAttrib, -+ IMG_HANDLE hOSMemHandle, -+ IMG_CPU_VIRTADDR pvLinAddr, -+ IMG_UINT32 ui32Bytes, -+ IMG_UINT32 ui32Flags, -+ IMG_BOOL bInitialisePages, -+ IMG_HANDLE hUniqueTag1, -+ IMG_HANDLE hUniqueTag2) -+{ -+ PVRSRV_ERROR eErr; -+ IMG_UINT32 ui32NumPages; -+ IMG_UINT32 ui32PageOffset; -+ IMG_UINT32 ui32BlockBytes; -+ IMG_UINT8* pui8LinAddr; -+ IMG_DEV_PHYADDR sDevPAddr; -+ IMG_DEV_PHYADDR sDevPAddrTmp; -+ IMG_CPU_PHYADDR sCpuPAddr; -+ IMG_UINT32 ui32Offset; -+ IMG_UINT32 ui32ParamOutPos; -+ IMG_UINT32 ui32PageMask; /* mask for the physical page backing the PT */ -+ -+#if !defined(SGX_FEATURE_36BIT_MMU) -+ IMG_DEV_PHYADDR sDevPAddrTmp2; -+#endif -+ PDUMP_GET_SCRIPT_AND_FILE_STRING(); -+ -+ PDUMP_LOCK(); -+ -+ -+ if (PDumpOSIsSuspended()) -+ { -+ PDUMP_UNLOCK(); -+ return PVRSRV_OK; -+ } -+ -+ if (!PDumpOSJTInitialised()) -+ { -+ PDUMP_UNLOCK(); -+ return PVRSRV_ERROR_PDUMP_NOT_AVAILABLE; -+ } -+ -+ if (!pvLinAddr) -+ { -+ PDUMP_UNLOCK(); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ PDumpOSCheckForSplitting(PDumpOSGetStream(PDUMP_STREAM_PARAM2), ui32Bytes, ui32Flags); -+ -+ ui32ParamOutPos = PDumpOSGetStreamOffset(PDUMP_STREAM_PARAM2); -+ -+ if (bInitialisePages) -+ { -+ /* -+ write the binary data up-front -+ Use the 'continuous' memory stream -+ */ -+ if (!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_PARAM2), -+ pvLinAddr, -+ ui32Bytes, -+ ui32Flags | PDUMP_FLAGS_CONTINUOUS)) -+ { -+ PDUMP_UNLOCK(); -+ return PVRSRV_ERROR_PDUMP_BUFFER_FULL; -+ } -+ -+ if (PDumpOSGetParamFileNum() == 0) -+ { -+ eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%.prm"); -+ } -+ else -+ { -+ eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%_%u.prm", PDumpOSGetParamFileNum()); -+ } -+ if(eErr != PVRSRV_OK) -+ { -+ PDUMP_UNLOCK(); -+ return eErr; -+ } -+ } -+ -+ /* -+ Mask for the physical page address backing the PT -+ The PT size can be less than 4k with variable page size support -+ The PD size is always 4k -+ FIXME: This won't work for dumping the dummy data page -+ */ -+ ui32PageMask = psMMUAttrib->ui32PTSize - 1; -+ -+ /* -+ Write to the MMU script stream indicating the physical page table entries -+ */ -+ /* physical pages that back the virtual address */ -+ ui32PageOffset = (IMG_UINT32)((IMG_UINTPTR_T)pvLinAddr & (psMMUAttrib->ui32PTSize - 1)); -+ ui32NumPages = (ui32PageOffset + ui32Bytes + psMMUAttrib->ui32PTSize - 1) / psMMUAttrib->ui32PTSize; -+ pui8LinAddr = (IMG_UINT8*) pvLinAddr; -+ -+ while (ui32NumPages) -+ { -+ ui32NumPages--; -+ /* FIXME: if we used OSMemHandleToCPUPAddr() here, we might be -+ able to lose the lin addr arg. At least one thing that -+ would need to be done here is to pass in an offset, as the -+ calling function doesn't necessarily give us the lin addr -+ of the start of the mem area. Probably best to keep the -+ lin addr arg for now - but would be nice to remove the -+ redundancy */ -+ sCpuPAddr = OSMapLinToCPUPhys(hOSMemHandle, pui8LinAddr); -+ sDevPAddr = SysCpuPAddrToDevPAddr(psMMUAttrib->sDevId.eDeviceType, sCpuPAddr); -+ -+ /* how many bytes to dump from this page */ -+ if (ui32PageOffset + ui32Bytes > psMMUAttrib->ui32PTSize) -+ { -+ /* dump up to the page boundary */ -+ ui32BlockBytes = psMMUAttrib->ui32PTSize - ui32PageOffset; -+ } -+ else -+ { -+ /* dump what's left */ -+ ui32BlockBytes = ui32Bytes; -+ } -+ -+ /* -+ Write a comment to the MMU script stream indicating the page table load -+ */ -+ -+ if (bInitialisePages) -+ { -+ eErr = PDumpOSBufprintf(hScript, -+ ui32MaxLenScript, -+ "LDB :%s:PA_" UINTPTR_FMT DEVPADDR_FMT ":0x%08X 0x%08X 0x%08X %s\r\n", -+ psMMUAttrib->sDevId.pszPDumpDevName, -+ (IMG_UINTPTR_T)hUniqueTag1, -+ sDevPAddr.uiAddr & ~ui32PageMask, -+ (unsigned int)(sDevPAddr.uiAddr & ui32PageMask), -+ ui32BlockBytes, -+ ui32ParamOutPos, -+ pszFileName); -+ if(eErr != PVRSRV_OK) -+ { -+ PDUMP_UNLOCK(); -+ return eErr; -+ } -+ PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS); -+ } -+ else -+ { -+ for (ui32Offset = 0; ui32Offset < ui32BlockBytes; ui32Offset += sizeof(IMG_UINT32)) -+ { -+ IMG_UINT32 ui32PTE = *((IMG_UINT32 *)(IMG_UINTPTR_T)(pui8LinAddr + ui32Offset)); /* PRQA S 3305 */ /* strict pointer */ -+ -+ if ((ui32PTE & psMMUAttrib->ui32PDEMask) != 0) -+ { -+ /* PT entry points to non-null page */ -+#if defined(SGX_FEATURE_36BIT_MMU) -+ sDevPAddrTmp.uiAddr = ((ui32PTE & psMMUAttrib->ui32PDEMask) << psMMUAttrib->ui32PTEAlignShift); -+ -+ eErr = PDumpOSBufprintf(hScript, -+ ui32MaxLenScript, -+ "WRW :%s:$1 :%s:PA_" UINTPTR_FMT DEVPADDR_FMT ":0x0\r\n", -+ psMMUAttrib->sDevId.pszPDumpDevName, -+ psMMUAttrib->sDevId.pszPDumpDevName, -+ (IMG_UINTPTR_T)hUniqueTag2, -+ sDevPAddrTmp.uiAddr); -+ if(eErr != PVRSRV_OK) -+ { -+ PDUMP_UNLOCK(); -+ return eErr; -+ } -+ PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS); -+ eErr = PDumpOSBufprintf(hScript, ui32MaxLenScript, "SHR :%s:$1 :%s:$1 0x4\r\n", -+ psMMUAttrib->sDevId.pszPDumpDevName, -+ psMMUAttrib->sDevId.pszPDumpDevName); -+ if(eErr != PVRSRV_OK) -+ { -+ PDUMP_UNLOCK(); -+ return eErr; -+ } -+ PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS); -+ eErr = PDumpOSBufprintf(hScript, ui32MaxLenScript, "OR :%s:$1 :%s:$1 0x%08X\r\n", -+ psMMUAttrib->sDevId.pszPDumpDevName, -+ psMMUAttrib->sDevId.pszPDumpDevName, -+ ui32PTE & ~psMMUAttrib->ui32PDEMask); -+ if(eErr != PVRSRV_OK) -+ { -+ PDUMP_UNLOCK(); -+ return eErr; -+ } -+ PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS); -+ sDevPAddrTmp.uiAddr = (sDevPAddr.uiAddr + ui32Offset) & ~ui32PageMask; -+ -+ eErr = PDumpOSBufprintf(hScript, -+ ui32MaxLenScript, -+ "WRW :%s:PA_" UINTPTR_FMT DEVPADDR_FMT ":0x%08X :%s:$1\r\n", -+ psMMUAttrib->sDevId.pszPDumpDevName, -+ (IMG_UINTPTR_T)hUniqueTag1, -+ sDevPAddrTmp.uiAddr, -+ (unsigned int)((sDevPAddr.uiAddr + ui32Offset) & ui32PageMask), -+ psMMUAttrib->sDevId.pszPDumpDevName); -+ if(eErr != PVRSRV_OK) -+ { -+ PDUMP_UNLOCK(); -+ return eErr; -+ } -+ PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS); -+#else -+ sDevPAddrTmp.uiAddr = (sDevPAddr.uiAddr + ui32Offset) & ~ui32PageMask; -+ sDevPAddrTmp2.uiAddr = (ui32PTE & psMMUAttrib->ui32PDEMask) << psMMUAttrib->ui32PTEAlignShift; -+ -+ eErr = PDumpOSBufprintf(hScript, -+ ui32MaxLenScript, -+ "WRW :%s:PA_" UINTPTR_FMT DEVPADDR_FMT ":0x%08X :%s:PA_" UINTPTR_FMT DEVPADDR_FMT ":0x%08X\r\n", -+ psMMUAttrib->sDevId.pszPDumpDevName, -+ (IMG_UINTPTR_T)hUniqueTag1, -+ sDevPAddrTmp.uiAddr, -+ (unsigned int)((sDevPAddr.uiAddr + ui32Offset) & ui32PageMask), -+ psMMUAttrib->sDevId.pszPDumpDevName, -+ (IMG_UINTPTR_T)hUniqueTag2, -+ sDevPAddrTmp2.uiAddr, -+ (unsigned int)(ui32PTE & ~psMMUAttrib->ui32PDEMask)); -+ if(eErr != PVRSRV_OK) -+ { -+ PDUMP_UNLOCK(); -+ return eErr; -+ } -+ PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS); -+#endif -+ } -+ else -+ { -+#if !defined(FIX_HW_BRN_31620) -+ PVR_ASSERT((ui32PTE & psMMUAttrib->ui32PTEValid) == 0UL); -+#endif -+ sDevPAddrTmp.uiAddr = (sDevPAddr.uiAddr + ui32Offset) & ~ui32PageMask; -+ -+ eErr = PDumpOSBufprintf(hScript, -+ ui32MaxLenScript, -+ "WRW :%s:PA_" UINTPTR_FMT DEVPADDR_FMT ":0x%08X 0x%08X" UINTPTR_FMT "\r\n", -+ psMMUAttrib->sDevId.pszPDumpDevName, -+ (IMG_UINTPTR_T)hUniqueTag1, -+ sDevPAddrTmp.uiAddr, -+ (unsigned int)((sDevPAddr.uiAddr + ui32Offset) & ui32PageMask), -+ ui32PTE << psMMUAttrib->ui32PTEAlignShift, -+ (IMG_UINTPTR_T)hUniqueTag2); -+ if(eErr != PVRSRV_OK) -+ { -+ PDUMP_UNLOCK(); -+ return eErr; -+ } -+ PDumpOSWriteString2(hScript, ui32Flags | PDUMP_FLAGS_CONTINUOUS); -+ } -+ } -+ } -+ -+ /* update details for next page */ -+ -+ /* page offset 0 after first page dump */ -+ ui32PageOffset = 0; -+ /* bytes left over */ -+ ui32Bytes -= ui32BlockBytes; -+ /* advance the cpuVaddr */ -+ pui8LinAddr += ui32BlockBytes; -+ /* update the file write offset */ -+ ui32ParamOutPos += ui32BlockBytes; -+ } -+ -+ PDUMP_UNLOCK(); -+ return PVRSRV_OK; -+} -+ -+PVRSRV_ERROR PDumpPDDevPAddrKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo, -+ IMG_UINT32 ui32Offset, -+ IMG_DEV_PHYADDR sPDDevPAddr, -+ IMG_HANDLE hUniqueTag1, -+ IMG_HANDLE hUniqueTag2) -+{ -+ PVRSRV_ERROR eErr; -+ IMG_UINT32 ui32PageByteOffset; -+ IMG_DEV_VIRTADDR sDevVAddr; -+ IMG_DEV_VIRTADDR sDevVPageAddr; -+ IMG_DEV_PHYADDR sDevPAddr; -+ IMG_UINT32 ui32Flags = PDUMP_FLAGS_CONTINUOUS; -+ IMG_UINT32 ui32ParamOutPos; -+ PDUMP_MMU_ATTRIB *psMMUAttrib; -+ IMG_UINT32 ui32PageMask; /* mask for the physical page backing the PT */ -+ IMG_DEV_PHYADDR sDevPAddrTmp; -+ -+ PDUMP_GET_SCRIPT_AND_FILE_STRING(); -+ -+ PDUMP_LOCK(); -+ if (!PDumpOSJTInitialised()) -+ { -+ PDUMP_UNLOCK(); -+ return PVRSRV_ERROR_PDUMP_NOT_AVAILABLE; -+ } -+ -+ psMMUAttrib = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->psMMUAttrib; -+ ui32PageMask = psMMUAttrib->ui32PTSize - 1; -+ -+ ui32ParamOutPos = PDumpOSGetStreamOffset(PDUMP_STREAM_PARAM2); -+ -+ /* Write the PD phys addr to the param stream up front */ -+ if(!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_PARAM2), -+ (IMG_UINT8 *)&sPDDevPAddr, -+ sizeof(IMG_DEV_PHYADDR), -+ ui32Flags)) -+ { -+ PDUMP_UNLOCK(); -+ return PVRSRV_ERROR_PDUMP_BUFFER_FULL; -+ } -+ -+ if (PDumpOSGetParamFileNum() == 0) -+ { -+ eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%.prm"); -+ } -+ else -+ { -+ eErr = PDumpOSSprintf(pszFileName, ui32MaxLenFileName, "%%0%%_%u.prm", PDumpOSGetParamFileNum()); -+ } -+ if(eErr != PVRSRV_OK) -+ { -+ PDUMP_UNLOCK(); -+ return eErr; -+ } -+ -+ /* Write a comment indicating the PD phys addr write, so that the offsets -+ * into the param stream increase in correspondence with the number of bytes -+ * written. */ -+ sDevPAddrTmp.uiAddr = sPDDevPAddr.uiAddr & ~ui32PageMask; -+ -+ eErr = PDumpOSBufprintf(hScript, -+ ui32MaxLenScript, -+ "-- LDB :%s:PA_0x" UINTPTR_FMT DEVPADDR_FMT ":0x%08X 0x%08" SIZE_T_FMT_LEN "X 0x%08X %s\r\n", -+ psMMUAttrib->sDevId.pszPDumpDevName, -+ (IMG_UINTPTR_T)hUniqueTag1, -+ sDevPAddrTmp.uiAddr, -+ (unsigned int)(sPDDevPAddr.uiAddr & ui32PageMask), -+ sizeof(IMG_DEV_PHYADDR), -+ ui32ParamOutPos, -+ pszFileName); -+ if(eErr != PVRSRV_OK) -+ { -+ PDUMP_UNLOCK(); -+ return eErr; -+ } -+ PDumpOSWriteString2(hScript, ui32Flags); -+ -+ sDevVAddr = psMemInfo->sDevVAddr; -+ ui32PageByteOffset = sDevVAddr.uiAddr & ui32PageMask; -+ -+ sDevVPageAddr.uiAddr = sDevVAddr.uiAddr - ui32PageByteOffset; -+ PVR_ASSERT((sDevVPageAddr.uiAddr & 0xFFF) == 0); -+ -+ BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr); -+ sDevPAddr.uiAddr += ui32PageByteOffset + ui32Offset; -+ -+#if defined(SGX_FEATURE_36BIT_MMU) -+ sDevPAddrTmp.uiAddr = sPDDevPAddr.uiAddr & ~ui32PageMask; -+ -+ eErr = PDumpOSBufprintf(hScript, -+ ui32MaxLenScript, -+ "WRW :%s:$1 :%s:PA_" UINTPTR_FMT DEVPADDR_FMT ":0x%08X\r\n", -+ psMMUAttrib->sDevId.pszPDumpDevName, -+ psMMUAttrib->sDevId.pszPDumpDevName, -+ (IMG_UINTPTR_T)hUniqueTag2, -+ sDevPAddrTmp.uiAddr, -+ (unsigned int)(sPDDevPAddr.uiAddr & ui32PageMask)); -+ if(eErr != PVRSRV_OK) -+ { -+ PDUMP_UNLOCK(); -+ return eErr; -+ } -+ PDumpOSWriteString2(hScript, ui32Flags); -+ -+ eErr = PDumpOSBufprintf(hScript, ui32MaxLenScript, "SHR :%s:$1 :%s:$1 0x4\r\n", -+ psMMUAttrib->sDevId.pszPDumpDevName, -+ psMMUAttrib->sDevId.pszPDumpDevName); -+ if(eErr != PVRSRV_OK) -+ { -+ PDUMP_UNLOCK(); -+ return eErr; -+ } -+ -+ PDumpOSWriteString2(hScript, ui32Flags); -+ sDevPAddrTmp.uiAddr = sDevPAddr.uiAddr & ~(psMMUAttrib->ui32DataPageMask); -+ -+ eErr = PDumpOSBufprintf(hScript, -+ ui32MaxLenScript, -+ "WRW :%s:PA_" UINTPTR_FMT DEVPADDR_FMT ":0x%08X :%s:$1\r\n", -+ psMMUAttrib->sDevId.pszPDumpDevName, -+ (IMG_UINTPTR_T)hUniqueTag1, -+ sDevPAddrTmp.uiAddr, -+ (unsigned int)((sDevPAddr.uiAddr) & (psMMUAttrib->ui32DataPageMask)), -+ psMMUAttrib->sDevId.pszPDumpDevName); -+ if(eErr != PVRSRV_OK) -+ { -+ PDUMP_UNLOCK(); -+ return eErr; -+ } -+#else -+ eErr = PDumpOSBufprintf(hScript, -+ ui32MaxLenScript, -+ "WRW :%s:PA_" UINTPTR_FMT DEVPADDR_FMT ":0x%08X :%s:PA_" UINTPTR_FMT DEVPADDR_FMT ":0x%08X \r\n", -+ psMMUAttrib->sDevId.pszPDumpDevName, -+ (IMG_UINTPTR_T)hUniqueTag1, -+ sDevPAddr.uiAddr & ~ui32PageMask, -+ (unsigned int)(sDevPAddr.uiAddr & ui32PageMask), -+ psMMUAttrib->sDevId.pszPDumpDevName, -+ (IMG_UINTPTR_T)hUniqueTag2, -+ sPDDevPAddr.uiAddr & psMMUAttrib->ui32PDEMask, -+ (unsigned int)(sPDDevPAddr.uiAddr & ~psMMUAttrib->ui32PDEMask)); -+ if(eErr != PVRSRV_OK) -+ { -+ PDUMP_UNLOCK(); -+ return eErr; -+ } -+#endif -+ PDumpOSWriteString2(hScript, ui32Flags); -+ -+ PDUMP_UNLOCK(); -+ return PVRSRV_OK; -+} -+ -+/************************************************************************** -+ * Function Name : PDumpCommentKM -+ * Inputs : pszComment, ui32Flags -+ * Outputs : None -+ * Returns : None -+ * Description : Dumps a comment -+**************************************************************************/ -+PVRSRV_ERROR PDumpCommentKM(IMG_CHAR *pszComment, IMG_UINT32 ui32Flags) -+{ -+ PVRSRV_ERROR eErr; -+ IMG_CHAR pszCommentPrefix[] = "-- "; /* prefix for comments */ -+#if defined(PDUMP_DEBUG_OUTFILES) -+ IMG_CHAR pszTemp[256]; -+#endif -+ IMG_UINT32 ui32LenCommentPrefix; -+ PDUMP_GET_SCRIPT_STRING(); -+ -+ PDUMP_LOCK(); -+ PDUMP_DBG(("PDumpCommentKM")); -+ -+ /* Put \r \n sequence at the end if it isn't already there */ -+ PDumpOSVerifyLineEnding(pszComment, ui32MaxLen); -+ -+ /* Length of string excluding terminating NULL character */ -+ ui32LenCommentPrefix = PDumpOSBuflen(pszCommentPrefix, sizeof(pszCommentPrefix)); -+ -+ /* Ensure output file is available for writing */ -+ /* FIXME: is this necessary? */ -+ if (!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_SCRIPT2), -+ (IMG_UINT8*)pszCommentPrefix, -+ ui32LenCommentPrefix, -+ ui32Flags)) -+ { -+#if defined(PDUMP_DEBUG_OUTFILES) -+ if(ui32Flags & PDUMP_FLAGS_CONTINUOUS) -+ { -+ PVR_DPF((PVR_DBG_WARNING, "Incomplete comment, %d: %s (continuous set)", -+ g_ui32EveryLineCounter, pszComment)); -+ PDUMP_UNLOCK(); -+ return PVRSRV_ERROR_PDUMP_BUFFER_FULL; -+ } -+ else if(ui32Flags & PDUMP_FLAGS_PERSISTENT) -+ { -+ PVR_DPF((PVR_DBG_WARNING, "Incomplete comment, %d: %s (persistent set)", -+ g_ui32EveryLineCounter, pszComment)); -+ PDUMP_UNLOCK(); -+ return PVRSRV_ERROR_CMD_NOT_PROCESSED; -+ } -+ else -+ { -+ PVR_DPF((PVR_DBG_WARNING, "Incomplete comment, %d: %s", -+ g_ui32EveryLineCounter, pszComment)); -+ PDUMP_UNLOCK(); -+ return PVRSRV_ERROR_CMD_NOT_PROCESSED; -+ } -+#else -+ PVR_DPF((PVR_DBG_WARNING, "Incomplete comment, %s", -+ pszComment)); -+ PDUMP_UNLOCK(); -+ return PVRSRV_ERROR_CMD_NOT_PROCESSED; -+#endif -+ } -+ -+#if defined(PDUMP_DEBUG_OUTFILES) -+ /* Prefix comment with PID and line number */ -+ eErr = PDumpOSSprintf(pszTemp, 256, "%d-%d %s", -+ _PDumpGetPID(), -+ g_ui32EveryLineCounter, -+ pszComment); -+ -+ /* Append the comment to the script stream */ -+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "%s", -+ pszTemp); -+#else -+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "%s", -+ pszComment); -+#endif -+ if( (eErr != PVRSRV_OK) && -+ (eErr != PVRSRV_ERROR_PDUMP_BUF_OVERFLOW)) -+ { -+ PDUMP_UNLOCK(); -+ return eErr; -+ } -+ PDumpOSWriteString2(hScript, ui32Flags); -+ -+ PDUMP_UNLOCK(); -+ return PVRSRV_OK; -+} -+ -+/************************************************************************** -+ * Function Name : PDumpCommentWithFlags -+ * Inputs : psPDev - PDev for PDump device -+ * : pszFormat - format string for comment -+ * : ... - args for format string -+ * Outputs : None -+ * Returns : None -+ * Description : PDumps a comments -+**************************************************************************/ -+PVRSRV_ERROR PDumpCommentWithFlags(IMG_UINT32 ui32Flags, IMG_CHAR * pszFormat, ...) -+{ -+ PVRSRV_ERROR eErr; -+ PDUMP_va_list ap; -+ PDUMP_GET_MSG_STRING(); -+ -+ PDUMP_LOCK_MSG(); -+ /* Construct the string */ -+ PDUMP_va_start(ap, pszFormat); -+ eErr = PDumpOSVSprintf(pszMsg, ui32MaxLen, pszFormat, ap); -+ PDUMP_va_end(ap); -+ -+ if(eErr != PVRSRV_OK) -+ { -+ PDUMP_UNLOCK_MSG(); -+ return eErr; -+ } -+ eErr = PDumpCommentKM(pszMsg, ui32Flags); -+ PDUMP_UNLOCK_MSG(); -+ return eErr; -+} -+ -+/************************************************************************** -+ * Function Name : PDumpComment -+ * Inputs : psPDev - PDev for PDump device -+ * : pszFormat - format string for comment -+ * : ... - args for format string -+ * Outputs : None -+ * Returns : None -+ * Description : PDumps a comments -+**************************************************************************/ -+PVRSRV_ERROR PDumpComment(IMG_CHAR *pszFormat, ...) -+{ -+ PVRSRV_ERROR eErr; -+ PDUMP_va_list ap; -+ PDUMP_GET_MSG_STRING(); -+ -+ PDUMP_LOCK_MSG(); -+ /* Construct the string */ -+ PDUMP_va_start(ap, pszFormat); -+ eErr = PDumpOSVSprintf(pszMsg, ui32MaxLen, pszFormat, ap); -+ PDUMP_va_end(ap); -+ -+ if(eErr != PVRSRV_OK) -+ { -+ PDUMP_UNLOCK_MSG(); -+ return eErr; -+ } -+ eErr = PDumpCommentKM(pszMsg, PDUMP_FLAGS_CONTINUOUS); -+ PDUMP_UNLOCK_MSG(); -+ return eErr; -+} -+ -+/************************************************************************** -+ * Function Name : PDumpDriverInfoKM -+ * Inputs : pszString, ui32Flags -+ * Outputs : None -+ * Returns : None -+ * Description : Dumps a comment -+**************************************************************************/ -+PVRSRV_ERROR PDumpDriverInfoKM(IMG_CHAR *pszString, IMG_UINT32 ui32Flags) -+{ -+ PVRSRV_ERROR eErr; -+ IMG_UINT32 ui32MsgLen; -+ PDUMP_GET_MSG_STRING(); -+ -+ PDUMP_LOCK_MSG(); -+ /* Construct the string */ -+ eErr = PDumpOSSprintf(pszMsg, ui32MaxLen, "%s", pszString); -+ if(eErr != PVRSRV_OK) -+ { -+ PDUMP_UNLOCK_MSG(); -+ return eErr; -+ } -+ -+ /* Put \r \n sequence at the end if it isn't already there */ -+ PDumpOSVerifyLineEnding(pszMsg, ui32MaxLen); -+ ui32MsgLen = PDumpOSBuflen(pszMsg, ui32MaxLen); -+ -+ if (!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_DRIVERINFO), -+ (IMG_UINT8*)pszMsg, -+ ui32MsgLen, -+ ui32Flags)) -+ { -+ if (ui32Flags & PDUMP_FLAGS_CONTINUOUS) -+ { -+ PDUMP_UNLOCK_MSG(); -+ return PVRSRV_ERROR_PDUMP_BUFFER_FULL; -+ } -+ else -+ { -+ PDUMP_UNLOCK_MSG(); -+ return PVRSRV_ERROR_CMD_NOT_PROCESSED; -+ } -+ } -+ -+ PDUMP_UNLOCK_MSG(); -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PDumpBitmapKM -+ -+ @Description -+ -+ Dumps a bitmap from device memory to a file -+ -+ @Input psDevId -+ @Input pszFileName -+ @Input ui32FileOffset -+ @Input ui32Width -+ @Input ui32Height -+ @Input ui32StrideInBytes -+ @Input sDevBaseAddr -+ @Input ui32Size -+ @Input ePixelFormat -+ @Input eMemFormat -+ @Input ui32PDumpFlags -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+PVRSRV_ERROR PDumpBitmapKM( PVRSRV_DEVICE_NODE *psDeviceNode, -+ IMG_CHAR *pszFileName, -+ IMG_UINT32 ui32FileOffset, -+ IMG_UINT32 ui32Width, -+ IMG_UINT32 ui32Height, -+ IMG_UINT32 ui32StrideInBytes, -+ IMG_DEV_VIRTADDR sDevBaseAddr, -+ IMG_HANDLE hDevMemContext, -+ IMG_UINT32 ui32Size, -+ PDUMP_PIXEL_FORMAT ePixelFormat, -+ PDUMP_MEM_FORMAT eMemFormat, -+ IMG_UINT32 ui32PDumpFlags) -+{ -+ PVRSRV_DEVICE_IDENTIFIER *psDevId = &psDeviceNode->sDevId; -+ IMG_UINT32 ui32MMUContextID; -+ PVRSRV_ERROR eErr; -+ PDUMP_GET_SCRIPT_STRING(); -+ -+ PDumpCommentWithFlags(ui32PDumpFlags, "\r\n-- Dump bitmap of render\r\n"); -+ -+ PDUMP_LOCK(); -+ /* find MMU context ID */ -+ ui32MMUContextID = psDeviceNode->pfnMMUGetContextID( hDevMemContext ); -+ -+ eErr = PDumpOSBufprintf(hScript, -+ ui32MaxLen, -+ "SII %s %s.bin :%s:v%x:0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\r\n", -+ pszFileName, -+ pszFileName, -+ psDevId->pszPDumpDevName, -+ ui32MMUContextID, -+ sDevBaseAddr.uiAddr, -+ ui32Size, -+ ui32FileOffset, -+ ePixelFormat, -+ ui32Width, -+ ui32Height, -+ ui32StrideInBytes, -+ eMemFormat); -+ if(eErr != PVRSRV_OK) -+ { -+ PDUMP_UNLOCK(); -+ return eErr; -+ } -+ -+ PDumpOSWriteString2( hScript, ui32PDumpFlags); -+ -+ PDUMP_UNLOCK(); -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PDumpReadRegKM -+ -+ @Description -+ -+ Dumps a read from a device register to a file -+ -+ @Input psConnection : connection info -+ @Input pszFileName -+ @Input ui32FileOffset -+ @Input ui32Address -+ @Input ui32Size -+ @Input ui32PDumpFlags -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+PVRSRV_ERROR PDumpReadRegKM ( IMG_CHAR *pszPDumpRegName, -+ IMG_CHAR *pszFileName, -+ IMG_UINT32 ui32FileOffset, -+ IMG_UINT32 ui32Address, -+ IMG_UINT32 ui32Size, -+ IMG_UINT32 ui32PDumpFlags) -+{ -+ PVRSRV_ERROR eErr; -+ PDUMP_GET_SCRIPT_STRING(); -+ PVR_UNREFERENCED_PARAMETER(ui32Size); -+ -+ PDUMP_LOCK(); -+ eErr = PDumpOSBufprintf(hScript, -+ ui32MaxLen, -+ "SAB :%s:0x%08X 0x%08X %s\r\n", -+ pszPDumpRegName, -+ ui32Address, -+ ui32FileOffset, -+ pszFileName); -+ if(eErr != PVRSRV_OK) -+ { -+ PDUMP_UNLOCK(); -+ return eErr; -+ } -+ -+ PDumpOSWriteString2( hScript, ui32PDumpFlags); -+ -+ PDUMP_UNLOCK(); -+ return PVRSRV_OK; -+} -+ -+/***************************************************************************** -+ @name PDumpTestNextFrame -+ @brief Tests whether the next frame will be pdumped -+ @param ui32CurrentFrame -+ @return bFrameDumped -+*****************************************************************************/ -+IMG_BOOL PDumpTestNextFrame(IMG_UINT32 ui32CurrentFrame) -+{ -+ IMG_BOOL bFrameDumped; -+ -+ /* -+ Try dumping a string -+ */ -+ (IMG_VOID) PDumpSetFrameKM(ui32CurrentFrame + 1); -+ bFrameDumped = PDumpIsCaptureFrameKM(); -+ (IMG_VOID) PDumpSetFrameKM(ui32CurrentFrame); -+ -+ return bFrameDumped; -+} -+ -+/***************************************************************************** -+ @name PDumpSignatureRegister -+ @brief Dumps a single signature register -+ @param psDevId - device ID -+ @param ui32Address - The register address -+ @param ui32Size - The amount of data to be dumped in bytes -+ @param pui32FileOffset - Offset of dump in output file -+ @param ui32Flags - Flags -+ @return none -+*****************************************************************************/ -+static PVRSRV_ERROR PDumpSignatureRegister (PVRSRV_DEVICE_IDENTIFIER *psDevId, -+ IMG_CHAR *pszFileName, -+ IMG_UINT32 ui32Address, -+ IMG_UINT32 ui32Size, -+ IMG_UINT32 *pui32FileOffset, -+ IMG_UINT32 ui32Flags) -+{ -+ PVRSRV_ERROR eErr; -+ PDUMP_GET_SCRIPT_STRING(); -+ -+ eErr = PDumpOSBufprintf(hScript, -+ ui32MaxLen, -+ "SAB :%s:0x%08X 0x%08X %s\r\n", -+ psDevId->pszPDumpRegName, -+ ui32Address, -+ *pui32FileOffset, -+ pszFileName); -+ if(eErr != PVRSRV_OK) -+ { -+ return eErr; -+ } -+ -+ PDumpOSWriteString2(hScript, ui32Flags); -+ *pui32FileOffset += ui32Size; -+ -+ return PVRSRV_OK; -+} -+ -+/***************************************************************************** -+ @name PDumpRegisterRange -+ @brief Dumps a list of signature registers to a file -+ @param psDevId - device ID -+ @param pszFileName - target filename for dump -+ @param pui32Registers - register list -+ @param ui32NumRegisters - number of regs to dump -+ @param pui32FileOffset - file offset -+ @param ui32Size - size of write in bytes -+ @param ui32Flags - pdump flags -+ @return none -+ *****************************************************************************/ -+static IMG_VOID PDumpRegisterRange(PVRSRV_DEVICE_IDENTIFIER *psDevId, -+ IMG_CHAR *pszFileName, -+ IMG_UINT32 *pui32Registers, -+ IMG_UINT32 ui32NumRegisters, -+ IMG_UINT32 *pui32FileOffset, -+ IMG_UINT32 ui32Size, -+ IMG_UINT32 ui32Flags) -+{ -+ IMG_UINT32 i; -+ for (i = 0; i < ui32NumRegisters; i++) -+ { -+ PDumpSignatureRegister(psDevId, pszFileName, pui32Registers[i], ui32Size, pui32FileOffset, ui32Flags); -+ } -+} -+ -+/***************************************************************************** -+ @name PDump3DSignatureRegisters -+ @brief Dumps the signature registers for 3D modules... -+ @param psDevId - device ID info -+ @param pui32Registers - register list -+ @param ui32NumRegisters - number of regs to dump -+ @return Error -+*****************************************************************************/ -+PVRSRV_ERROR PDump3DSignatureRegisters(PVRSRV_DEVICE_IDENTIFIER *psDevId, -+ IMG_UINT32 ui32DumpFrameNum, -+ IMG_BOOL bLastFrame, -+ IMG_UINT32 *pui32Registers, -+ IMG_UINT32 ui32NumRegisters) -+{ -+ PVRSRV_ERROR eErr; -+ IMG_UINT32 ui32FileOffset, ui32Flags; -+ PDUMP_GET_FILE_STRING(); -+ -+ ui32Flags = bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0; -+ ui32FileOffset = 0; -+ -+ PDumpCommentWithFlags(ui32Flags, "\r\n-- Dump 3D signature registers\r\n"); -+ eErr = PDumpOSSprintf(pszFileName, ui32MaxLen, "out%u_3d.sig", ui32DumpFrameNum); -+ if(eErr != PVRSRV_OK) -+ { -+ return eErr; -+ } -+ -+ /* -+ Note: -+ PDumpCommentWithFlags will take the lock so we defer the lock -+ taking until here -+ */ -+ PDUMP_LOCK(); -+ PDumpRegisterRange(psDevId, -+ pszFileName, -+ pui32Registers, -+ ui32NumRegisters, -+ &ui32FileOffset, -+ sizeof(IMG_UINT32), -+ ui32Flags); -+ -+ PDUMP_UNLOCK(); -+ return PVRSRV_OK; -+} -+ -+/***************************************************************************** -+ @name PDumpTASignatureRegisters -+ @brief Dumps the TA signature registers -+ @param psDevId - device id info -+ @param ui32DumpFrameNum - frame number -+ @param ui32TAKickCount - TA kick counter -+ @param bLastFrame -+ @param pui32Registers - register list -+ @param ui32NumRegisters - number of regs to dump -+ @return Error -+*****************************************************************************/ -+PVRSRV_ERROR PDumpTASignatureRegisters (PVRSRV_DEVICE_IDENTIFIER *psDevId, -+ IMG_UINT32 ui32DumpFrameNum, -+ IMG_UINT32 ui32TAKickCount, -+ IMG_BOOL bLastFrame, -+ IMG_UINT32 *pui32Registers, -+ IMG_UINT32 ui32NumRegisters) -+{ -+ PVRSRV_ERROR eErr; -+ IMG_UINT32 ui32FileOffset, ui32Flags; -+ PDUMP_GET_FILE_STRING(); -+ -+ ui32Flags = bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0; -+ ui32FileOffset = ui32TAKickCount * ui32NumRegisters * sizeof(IMG_UINT32); -+ -+ PDumpCommentWithFlags(ui32Flags, "\r\n-- Dump TA signature registers\r\n"); -+ eErr = PDumpOSSprintf(pszFileName, ui32MaxLen, "out%u_ta.sig", ui32DumpFrameNum); -+ if(eErr != PVRSRV_OK) -+ { -+ return eErr; -+ } -+ -+ /* -+ Note: -+ PDumpCommentWithFlags will take the lock so we defer the lock -+ taking until here -+ */ -+ PDUMP_LOCK(); -+ PDumpRegisterRange(psDevId, -+ pszFileName, -+ pui32Registers, -+ ui32NumRegisters, -+ &ui32FileOffset, -+ sizeof(IMG_UINT32), -+ ui32Flags); -+ PDUMP_UNLOCK(); -+ return PVRSRV_OK; -+} -+ -+/***************************************************************************** -+ @name PDumpCounterRegisters -+ @brief Dumps the performance counters -+ @param psDevId - device id info -+ @param ui32DumpFrameNum - frame number -+ @param bLastFrame -+ @param pui32Registers - register list -+ @param ui32NumRegisters - number of regs to dump -+ @return Error -+*****************************************************************************/ -+PVRSRV_ERROR PDumpCounterRegisters (PVRSRV_DEVICE_IDENTIFIER *psDevId, -+ IMG_UINT32 ui32DumpFrameNum, -+ IMG_BOOL bLastFrame, -+ IMG_UINT32 *pui32Registers, -+ IMG_UINT32 ui32NumRegisters) -+{ -+ PVRSRV_ERROR eErr; -+ IMG_UINT32 ui32FileOffset, ui32Flags; -+ PDUMP_GET_FILE_STRING(); -+ -+ ui32Flags = bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0UL; -+ ui32FileOffset = 0UL; -+ -+ PDumpCommentWithFlags(ui32Flags, "\r\n-- Dump counter registers\r\n"); -+ eErr = PDumpOSSprintf(pszFileName, ui32MaxLen, "out%u.perf", ui32DumpFrameNum); -+ if(eErr != PVRSRV_OK) -+ { -+ return eErr; -+ } -+ /* -+ Note: -+ PDumpCommentWithFlags will take the lock so we defer the lock -+ taking until here -+ */ -+ PDUMP_LOCK(); -+ PDumpRegisterRange(psDevId, -+ pszFileName, -+ pui32Registers, -+ ui32NumRegisters, -+ &ui32FileOffset, -+ sizeof(IMG_UINT32), -+ ui32Flags); -+ -+ PDUMP_UNLOCK(); -+ return PVRSRV_OK; -+} -+ -+/***************************************************************************** -+ @name PDumpRegRead -+ @brief Dump signature register read to script -+ @param pszPDumpDevName - pdump device name -+ @param ui32RegOffset - register offset -+ @param ui32Flags - pdump flags -+ @return Error -+*****************************************************************************/ -+PVRSRV_ERROR PDumpRegRead(IMG_CHAR *pszPDumpRegName, -+ const IMG_UINT32 ui32RegOffset, -+ IMG_UINT32 ui32Flags) -+{ -+ PVRSRV_ERROR eErr; -+ PDUMP_GET_SCRIPT_STRING(); -+ -+ PDUMP_LOCK(); -+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "RDW :%s:0x%X\r\n", -+ pszPDumpRegName, -+ ui32RegOffset); -+ if(eErr != PVRSRV_OK) -+ { -+ PDUMP_UNLOCK(); -+ return eErr; -+ } -+ PDumpOSWriteString2(hScript, ui32Flags); -+ -+ PDUMP_UNLOCK(); -+ return PVRSRV_OK; -+} -+ -+/***************************************************************************** -+ @name PDumpSaveMemKM -+ @brief Save device memory to a file -+ @param psDevId -+ @param pszFileName -+ @param ui32FileOffset -+ @param sDevBaseAddr -+ @param ui32Size -+ @param ui32PDumpFlags -+ @return Error -+*****************************************************************************/ -+PVRSRV_ERROR PDumpSaveMemKM (PVRSRV_DEVICE_IDENTIFIER *psDevId, -+ IMG_CHAR *pszFileName, -+ IMG_UINT32 ui32FileOffset, -+ IMG_DEV_VIRTADDR sDevBaseAddr, -+ IMG_UINT32 ui32Size, -+ IMG_UINT32 ui32MMUContextID, -+ IMG_UINT32 ui32PDumpFlags) -+{ -+ PVRSRV_ERROR eErr; -+ PDUMP_GET_SCRIPT_STRING(); -+ -+ PDUMP_LOCK(); -+ eErr = PDumpOSBufprintf(hScript, -+ ui32MaxLen, -+ "SAB :%s:v%x:0x%08X 0x%08X 0x%08X %s.bin\r\n", -+ psDevId->pszPDumpDevName, -+ ui32MMUContextID, -+ sDevBaseAddr.uiAddr, -+ ui32Size, -+ ui32FileOffset, -+ pszFileName); -+ if(eErr != PVRSRV_OK) -+ { -+ PDUMP_UNLOCK(); -+ return eErr; -+ } -+ -+ PDumpOSWriteString2(hScript, ui32PDumpFlags); -+ -+ PDUMP_UNLOCK(); -+ return PVRSRV_OK; -+} -+ -+/***************************************************************************** -+ @name PDumpCycleCountRegRead -+ @brief Dump counter register read to script -+ @param ui32RegOffset - register offset -+ @param bLastFrame -+ @return Error -+*****************************************************************************/ -+PVRSRV_ERROR PDumpCycleCountRegRead(PVRSRV_DEVICE_IDENTIFIER *psDevId, -+ const IMG_UINT32 ui32RegOffset, -+ IMG_BOOL bLastFrame) -+{ -+ PVRSRV_ERROR eErr; -+ PDUMP_GET_SCRIPT_STRING(); -+ -+ PDUMP_LOCK(); -+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "RDW :%s:0x%X\r\n", -+ psDevId->pszPDumpRegName, -+ ui32RegOffset); -+ if(eErr != PVRSRV_OK) -+ { -+ PDUMP_UNLOCK(); -+ return eErr; -+ } -+ PDumpOSWriteString2(hScript, bLastFrame ? PDUMP_FLAGS_LASTFRAME : 0); -+ -+ PDUMP_UNLOCK(); -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PDumpSignatureBuffer -+ -+ @Description -+ -+ Dumps a signature registers buffer -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR PDumpSignatureBuffer (PVRSRV_DEVICE_IDENTIFIER *psDevId, -+ IMG_CHAR *pszFileName, -+ IMG_CHAR *pszBufferType, -+ IMG_UINT32 ui32FileOffset, -+ IMG_DEV_VIRTADDR sDevBaseAddr, -+ IMG_UINT32 ui32Size, -+ IMG_UINT32 ui32MMUContextID, -+ IMG_UINT32 ui32PDumpFlags) -+{ -+ PDumpCommentWithFlags(ui32PDumpFlags, "\r\n-- Dump microkernel %s signature Buffer\r\n", -+ pszBufferType); -+ PDumpCommentWithFlags(ui32PDumpFlags, "Buffer format (sizes in 32-bit words):\r\n"); -+ PDumpCommentWithFlags(ui32PDumpFlags, "\tNumber of signatures per sample (1)\r\n"); -+ PDumpCommentWithFlags(ui32PDumpFlags, "\tNumber of samples (1)\r\n"); -+ PDumpCommentWithFlags(ui32PDumpFlags, "\tSignature register offsets (1 * number of signatures)\r\n"); -+ PDumpCommentWithFlags(ui32PDumpFlags, "\tSignature sample values (number of samples * number of signatures)\r\n"); -+ PDumpCommentWithFlags(ui32PDumpFlags, "Note: If buffer is full, last sample is final state after test completed\r\n"); -+ return PDumpSaveMemKM(psDevId, pszFileName, ui32FileOffset, sDevBaseAddr, ui32Size, -+ ui32MMUContextID, ui32PDumpFlags); -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PDumpHWPerfCBKM -+ -+ @Description -+ -+ Dumps the HW Perf Circular Buffer -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR PDumpHWPerfCBKM (PVRSRV_DEVICE_IDENTIFIER *psDevId, -+ IMG_CHAR *pszFileName, -+ IMG_UINT32 ui32FileOffset, -+ IMG_DEV_VIRTADDR sDevBaseAddr, -+ IMG_UINT32 ui32Size, -+ IMG_UINT32 ui32MMUContextID, -+ IMG_UINT32 ui32PDumpFlags) -+{ -+ PDumpCommentWithFlags(ui32PDumpFlags, "\r\n-- Dump Hardware Performance Circular Buffer\r\n"); -+ return PDumpSaveMemKM(psDevId, pszFileName, ui32FileOffset, sDevBaseAddr, ui32Size, -+ ui32MMUContextID, ui32PDumpFlags); -+} -+ -+ -+/***************************************************************************** -+ FUNCTION : PDumpCBP -+ -+ PURPOSE : Dump CBP command to script -+ -+ PARAMETERS : -+ -+ RETURNS : None -+*****************************************************************************/ -+PVRSRV_ERROR PDumpCBP(PPVRSRV_KERNEL_MEM_INFO psROffMemInfo, -+ IMG_UINT32 ui32ROffOffset, -+ IMG_UINT32 ui32WPosVal, -+ IMG_UINT32 ui32PacketSize, -+ IMG_UINT32 ui32BufferSize, -+ IMG_UINT32 ui32Flags, -+ IMG_HANDLE hUniqueTag) -+{ -+ PVRSRV_ERROR eErr; -+ IMG_UINT32 ui32PageOffset; -+ IMG_UINT8 *pui8LinAddr; -+ IMG_DEV_VIRTADDR sDevVAddr; -+ IMG_DEV_PHYADDR sDevPAddr; -+ IMG_DEV_VIRTADDR sDevVPageAddr; -+ //IMG_CPU_PHYADDR CpuPAddr; -+ PDUMP_MMU_ATTRIB *psMMUAttrib; -+ PDUMP_GET_SCRIPT_STRING(); -+ -+ PDUMP_LOCK(); -+ psMMUAttrib = ((BM_BUF*)psROffMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->psMMUAttrib; -+ -+ /* Check the offset and size don't exceed the bounds of the allocation */ -+ PVR_ASSERT((ui32ROffOffset + sizeof(IMG_UINT32)) <= psROffMemInfo->uAllocSize); -+ -+ pui8LinAddr = psROffMemInfo->pvLinAddrKM; -+ sDevVAddr = psROffMemInfo->sDevVAddr; -+ -+ /* Advance addresses by offset */ -+ pui8LinAddr += ui32ROffOffset; -+ sDevVAddr.uiAddr += ui32ROffOffset; -+ -+ /* -+ query the buffer manager for the physical pages that back the -+ virtual address -+ */ -+ PDumpOSCPUVAddrToPhysPages(psROffMemInfo->sMemBlk.hOSMemHandle, -+ ui32ROffOffset, -+ pui8LinAddr, -+ psMMUAttrib->ui32DataPageMask, -+ &ui32PageOffset); -+ -+ /* calculate the DevV page address */ -+ sDevVPageAddr.uiAddr = sDevVAddr.uiAddr - ui32PageOffset; -+ -+ PVR_ASSERT((sDevVPageAddr.uiAddr & 0xFFF) == 0); -+ -+ /* get the physical page address based on the device virtual address */ -+ BM_GetPhysPageAddr(psROffMemInfo, sDevVPageAddr, &sDevPAddr); -+ -+ /* convert DevP page address to byte address */ -+ sDevPAddr.uiAddr += ui32PageOffset; -+ -+ eErr = PDumpOSBufprintf(hScript, -+ ui32MaxLen, -+ "CBP :%s:PA_" UINTPTR_FMT DEVPADDR_FMT ":0x%08X 0x%08X 0x%08X 0x%08X\r\n", -+ psMMUAttrib->sDevId.pszPDumpDevName, -+ (IMG_UINTPTR_T)hUniqueTag, -+ sDevPAddr.uiAddr & ~(psMMUAttrib->ui32DataPageMask), -+ (unsigned int)(sDevPAddr.uiAddr & (psMMUAttrib->ui32DataPageMask)), -+ ui32WPosVal, -+ ui32PacketSize, -+ ui32BufferSize); -+ if(eErr != PVRSRV_OK) -+ { -+ PDUMP_UNLOCK(); -+ return eErr; -+ } -+ PDumpOSWriteString2(hScript, ui32Flags); -+ -+ PDUMP_UNLOCK(); -+ return PVRSRV_OK; -+} -+ -+ -+/************************************************************************** -+ * Function Name : PDumpIDLWithFlags -+ * Inputs : Idle time in clocks -+ * Outputs : None -+ * Returns : Error -+ * Description : Dump IDL command to script -+**************************************************************************/ -+PVRSRV_ERROR PDumpIDLWithFlags(IMG_UINT32 ui32Clocks, IMG_UINT32 ui32Flags) -+{ -+ PVRSRV_ERROR eErr; -+ PDUMP_GET_SCRIPT_STRING(); -+ -+ PDUMP_LOCK(); -+ PDUMP_DBG(("PDumpIDLWithFlags")); -+ -+ eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "IDL %u\r\n", ui32Clocks); -+ if(eErr != PVRSRV_OK) -+ { -+ PDUMP_UNLOCK(); -+ return eErr; -+ } -+ PDumpOSWriteString2(hScript, ui32Flags); -+ -+ PDUMP_UNLOCK(); -+ return PVRSRV_OK; -+} -+ -+ -+/************************************************************************** -+ * Function Name : PDumpIDL -+ * Inputs : Idle time in clocks -+ * Outputs : None -+ * Returns : Error -+ * Description : Dump IDL command to script -+**************************************************************************/ -+PVRSRV_ERROR PDumpIDL(IMG_UINT32 ui32Clocks) -+{ -+ return PDumpIDLWithFlags(ui32Clocks, PDUMP_FLAGS_CONTINUOUS); -+} -+ -+/************************************************************************** -+ * Function Name : PDumpMemUM -+ * Inputs : pvAltLinAddrUM -+ * : pvLinAddrUM -+ * : psMemInfo -+ * : ui32Offset -+ * : ui32Bytes -+ * : ui32Flags -+ * : hUniqueTag -+ * Outputs : None -+ * Returns : PVRSRV_ERROR -+ * Description : Dump user mode memory -+**************************************************************************/ -+PVRSRV_ERROR PDumpMemUM(PVRSRV_PER_PROCESS_DATA *psPerProc, -+ IMG_PVOID pvAltLinAddrUM, -+ IMG_PVOID pvLinAddrUM, -+ PVRSRV_KERNEL_MEM_INFO *psMemInfo, -+ IMG_UINT32 ui32Offset, -+ IMG_UINT32 ui32Bytes, -+ IMG_UINT32 ui32Flags, -+ IMG_HANDLE hUniqueTag) -+{ -+ IMG_VOID *pvAddrUM; -+ IMG_VOID *pvAddrKM; -+ PVRSRV_ERROR eError; -+ -+ if (psMemInfo->pvLinAddrKM != IMG_NULL && pvAltLinAddrUM == IMG_NULL) -+ { -+ /* -+ * There is a kernel virtual address for the memory that is -+ * being dumped, and no alternate user mode linear address. -+ */ -+ return PDumpMemKM(IMG_NULL, -+ psMemInfo, -+ ui32Offset, -+ ui32Bytes, -+ ui32Flags, -+ hUniqueTag); -+ } -+ -+ pvAddrUM = (pvAltLinAddrUM != IMG_NULL) ? pvAltLinAddrUM : ((pvLinAddrUM != IMG_NULL) ? VPTR_PLUS(pvLinAddrUM, ui32Offset) : IMG_NULL); -+ -+ pvAddrKM = GetTempBuffer(); -+ -+ /* -+ * The memory to be dumped needs to be copied in from -+ * the client. Dump the memory, a buffer at a time. -+ */ -+ PVR_ASSERT(pvAddrUM != IMG_NULL && pvAddrKM != IMG_NULL); -+ if (pvAddrUM == IMG_NULL || pvAddrKM == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PDumpMemUM: Nothing to dump")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ if (ui32Bytes > PDUMP_TEMP_BUFFER_SIZE) -+ { -+ PDumpCommentWithFlags(ui32Flags, "Dumping 0x%08x bytes of memory, in blocks of 0x%08x bytes", ui32Bytes, (IMG_UINT32)PDUMP_TEMP_BUFFER_SIZE); -+ } -+ -+ if (psMemInfo->ui32Flags & PVRSRV_MEM_SPARSE) -+ { -+ /* -+ In case of sparse mappings we can't just copy the full range as not -+ all pages are valid, instead we walk a page at a time only dumping -+ if the a page exists at that address -+ */ -+ IMG_UINT32 ui32BytesRemain = ui32Bytes; -+ IMG_UINT32 ui32InPageStart = ui32Offset & (~HOST_PAGEMASK); -+ IMG_UINT32 ui32PageOffset = ui32Offset & (HOST_PAGEMASK); -+ IMG_UINT32 ui32BytesToCopy = MIN(HOST_PAGESIZE() - ui32InPageStart, ui32BytesRemain); -+ -+ do -+ { -+ if (BM_MapPageAtOffset(BM_MappingHandleFromBuffer(psMemInfo->sMemBlk.hBuffer), ui32PageOffset)) -+ { -+ eError = OSCopyFromUser(psPerProc, -+ pvAddrKM, -+ pvAddrUM, -+ ui32BytesToCopy); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PDumpMemUM: OSCopyFromUser failed (%d)", eError)); -+ return eError; -+ } -+ -+ /* -+ At this point we know we're dumping a valid page so call -+ the internal function -+ */ -+ eError = _PDumpMemIntKM(pvAddrKM, -+ psMemInfo, -+ ui32PageOffset + ui32InPageStart, -+ ui32BytesToCopy, -+ ui32Flags, -+ hUniqueTag); -+ -+ if (eError != PVRSRV_OK) -+ { -+ /* -+ * If writing fails part way through, then some -+ * investigation is needed. -+ */ -+ if (ui32BytesToCopy != 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PDumpMemUM: PDumpMemKM failed (%d)", eError)); -+ } -+ PVR_ASSERT(ui32BytesToCopy == 0); -+ return eError; -+ } -+ } -+ -+ VPTR_INC(pvAddrUM, ui32BytesToCopy); -+ ui32BytesRemain -= ui32BytesToCopy; -+ ui32InPageStart = 0; -+ ui32PageOffset += HOST_PAGESIZE(); -+ } while(ui32BytesRemain); -+ } -+ else -+ { -+ IMG_UINT32 ui32CurrentOffset = ui32Offset; -+ IMG_UINT32 ui32BytesDumped; -+ -+ for (ui32BytesDumped = 0; ui32BytesDumped < ui32Bytes;) -+ { -+ IMG_UINT32 ui32BytesToDump = MIN(PDUMP_TEMP_BUFFER_SIZE, ui32Bytes - ui32BytesDumped); -+ -+ eError = OSCopyFromUser(psPerProc, -+ pvAddrKM, -+ pvAddrUM, -+ ui32BytesToDump); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PDumpMemUM: OSCopyFromUser failed (%d)", eError)); -+ return eError; -+ } -+ -+ eError = PDumpMemKM(pvAddrKM, -+ psMemInfo, -+ ui32CurrentOffset, -+ ui32BytesToDump, -+ ui32Flags, -+ hUniqueTag); -+ -+ if (eError != PVRSRV_OK) -+ { -+ /* -+ * If writing fails part way through, then some -+ * investigation is needed. -+ */ -+ if (ui32BytesDumped != 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PDumpMemUM: PDumpMemKM failed (%d)", eError)); -+ } -+ PVR_ASSERT(ui32BytesDumped == 0); -+ return eError; -+ } -+ -+ VPTR_INC(pvAddrUM, ui32BytesToDump); -+ ui32CurrentOffset += ui32BytesToDump; -+ ui32BytesDumped += ui32BytesToDump; -+ } -+ } -+ -+ return PVRSRV_OK; -+} -+ -+ -+/************************************************************************** -+ * Function Name : _PdumpAllocMMUContext -+ * Inputs : pui32MMUContextID -+ * Outputs : None -+ * Returns : PVRSRV_ERROR -+ * Description : pdump util to allocate MMU contexts -+**************************************************************************/ -+static PVRSRV_ERROR _PdumpAllocMMUContext(IMG_UINT32 *pui32MMUContextID) -+{ -+ IMG_UINT32 i; -+ -+ /* there are MAX_PDUMP_MMU_CONTEXTS contexts available, find one */ -+ for(i=0; i<MAX_PDUMP_MMU_CONTEXTS; i++) -+ { -+ if((gui16MMUContextUsage & (1U << i)) == 0) -+ { -+ /* mark in use */ -+ gui16MMUContextUsage |= 1U << i; -+ *pui32MMUContextID = i; -+ return PVRSRV_OK; -+ } -+ } -+ -+ PVR_DPF((PVR_DBG_ERROR, "_PdumpAllocMMUContext: no free MMU context ids")); -+ -+ return PVRSRV_ERROR_MMU_CONTEXT_NOT_FOUND; -+} -+ -+ -+/************************************************************************** -+ * Function Name : _PdumpFreeMMUContext -+ * Inputs : ui32MMUContextID -+ * Outputs : None -+ * Returns : PVRSRV_ERROR -+ * Description : pdump util to free MMU contexts -+**************************************************************************/ -+static PVRSRV_ERROR _PdumpFreeMMUContext(IMG_UINT32 ui32MMUContextID) -+{ -+ if(ui32MMUContextID < MAX_PDUMP_MMU_CONTEXTS) -+ { -+ /* free the id */ -+ gui16MMUContextUsage &= ~(1U << ui32MMUContextID); -+ return PVRSRV_OK; -+ } -+ -+ PVR_DPF((PVR_DBG_ERROR, "_PdumpFreeMMUContext: MMU context ids invalid")); -+ -+ return PVRSRV_ERROR_MMU_CONTEXT_NOT_FOUND; -+} -+ -+ -+/************************************************************************** -+ * Function Name : PDumpSetMMUContext -+ * Inputs : -+ * Outputs : None -+ * Returns : PVRSRV_ERROR -+ * Description : Set MMU Context -+**************************************************************************/ -+PVRSRV_ERROR PDumpSetMMUContext(PVRSRV_DEVICE_TYPE eDeviceType, -+ IMG_CHAR *pszMemSpace, -+ IMG_UINT32 *pui32MMUContextID, -+ IMG_UINT32 ui32MMUType, -+ IMG_HANDLE hUniqueTag1, -+ IMG_HANDLE hOSMemHandle, -+ IMG_VOID *pvPDCPUAddr) -+{ -+ IMG_UINT8 *pui8LinAddr = (IMG_UINT8 *)pvPDCPUAddr; -+ IMG_CPU_PHYADDR sCpuPAddr; -+ IMG_DEV_PHYADDR sDevPAddr; -+ IMG_UINT32 ui32MMUContextID; -+ PVRSRV_ERROR eErr; -+ PDUMP_GET_SCRIPT_STRING(); -+ -+ PDUMP_LOCK(); -+ -+ eErr = _PdumpAllocMMUContext(&ui32MMUContextID); -+ if(eErr != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PDumpSetMMUContext: _PdumpAllocMMUContext failed: %d", eErr)); -+ PDUMP_UNLOCK(); -+ return eErr; -+ } -+ -+ /* derive the DevPAddr */ -+ /* FIXME: if we used OSMemHandleToCPUPAddr() here, we could lose the lin addr arg */ -+ sCpuPAddr = OSMapLinToCPUPhys(hOSMemHandle, pui8LinAddr); -+ sDevPAddr = SysCpuPAddrToDevPAddr(eDeviceType, sCpuPAddr); -+ /* and round to 4k page */ -+ sDevPAddr.uiAddr &= ~((PVRSRV_4K_PAGE_SIZE) -1); -+ -+ eErr = PDumpOSBufprintf(hScript, -+ ui32MaxLen, -+ "MMU :%s:v%d %d :%s:PA_" UINTPTR_FMT DEVPADDR_FMT "\r\n", -+ pszMemSpace, -+ ui32MMUContextID, -+ ui32MMUType, -+ pszMemSpace, -+ (IMG_UINTPTR_T)hUniqueTag1, -+ sDevPAddr.uiAddr); -+ if(eErr != PVRSRV_OK) -+ { -+ PDUMP_UNLOCK(); -+ return eErr; -+ } -+ PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS); -+ -+ /* return the MMU Context ID */ -+ *pui32MMUContextID = ui32MMUContextID; -+ -+ PDUMP_UNLOCK(); -+ return PVRSRV_OK; -+} -+ -+ -+/************************************************************************** -+ * Function Name : PDumpClearMMUContext -+ * Inputs : -+ * Outputs : None -+ * Returns : PVRSRV_ERROR -+ * Description : Clear MMU Context -+**************************************************************************/ -+PVRSRV_ERROR PDumpClearMMUContext(PVRSRV_DEVICE_TYPE eDeviceType, -+ IMG_CHAR *pszMemSpace, -+ IMG_UINT32 ui32MMUContextID, -+ IMG_UINT32 ui32MMUType) -+{ -+ PVRSRV_ERROR eErr; -+ PDUMP_GET_SCRIPT_STRING(); -+ PVR_UNREFERENCED_PARAMETER(eDeviceType); -+ PVR_UNREFERENCED_PARAMETER(ui32MMUType); -+ -+ /* FIXME: Propagate error from PDumpComment once it's supported on -+ * all OSes and platforms -+ */ -+ PDumpComment("Clear MMU Context for memory space %s\r\n", pszMemSpace); -+ -+ /* -+ Note: -+ PDumpComment takes the lock so we can't take it until here -+ */ -+ PDUMP_LOCK(); -+ eErr = PDumpOSBufprintf(hScript, -+ ui32MaxLen, -+ "MMU :%s:v%d\r\n", -+ pszMemSpace, -+ ui32MMUContextID); -+ if(eErr != PVRSRV_OK) -+ { -+ PDUMP_UNLOCK(); -+ return eErr; -+ } -+ -+ PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS); -+ -+ eErr = _PdumpFreeMMUContext(ui32MMUContextID); -+ if(eErr != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PDumpClearMMUContext: _PdumpFreeMMUContext failed: %d", eErr)); -+ PDUMP_UNLOCK(); -+ return eErr; -+ } -+ -+ PDUMP_UNLOCK(); -+ return PVRSRV_OK; -+} -+ -+/***************************************************************************** -+ FUNCTION : PDumpStoreMemToFile -+ -+ PURPOSE : Dumps a given addr:size to a file -+ -+ PARAMETERS : -+ -+ RETURNS : -+*****************************************************************************/ -+PVRSRV_ERROR PDumpStoreMemToFile(PDUMP_MMU_ATTRIB *psMMUAttrib, -+ IMG_CHAR *pszFileName, -+ IMG_UINT32 ui32FileOffset, -+ PVRSRV_KERNEL_MEM_INFO *psMemInfo, -+ IMG_UINT32 uiAddr, -+ IMG_UINT32 ui32Size, -+ IMG_UINT32 ui32PDumpFlags, -+ IMG_HANDLE hUniqueTag) -+{ -+ IMG_DEV_PHYADDR sDevPAddr; -+ IMG_DEV_VIRTADDR sDevVPageAddr; -+ IMG_UINT32 ui32PageOffset; -+ -+ PDUMP_GET_SCRIPT_STRING(); -+ -+ PDUMP_LOCK(); -+ /* -+ query the buffer manager for the physical pages that back the -+ virtual address -+ */ -+ ui32PageOffset = (IMG_UINT32)((IMG_UINTPTR_T)psMemInfo->pvLinAddrKM & psMMUAttrib->ui32DataPageMask); -+ -+ /* calculate the DevV page address */ -+ sDevVPageAddr.uiAddr = uiAddr - ui32PageOffset; -+ -+ /* get the physical page address based on the device virtual address */ -+ BM_GetPhysPageAddr(psMemInfo, sDevVPageAddr, &sDevPAddr); -+ -+ /* convert DevP page address to byte address */ -+ sDevPAddr.uiAddr += ui32PageOffset; -+ -+ PDumpOSBufprintf(hScript, -+ ui32MaxLen, -+ "SAB :%s:PA_" UINTPTR_FMT DEVPADDR_FMT ":0x%08X 0x%08X 0x%08X %s\r\n", -+ psMMUAttrib->sDevId.pszPDumpDevName, -+ (IMG_UINTPTR_T)hUniqueTag, -+ (sDevPAddr.uiAddr & ~psMMUAttrib->ui32DataPageMask), -+ (unsigned int)(sDevPAddr.uiAddr & psMMUAttrib->ui32DataPageMask), -+ ui32Size, -+ ui32FileOffset, -+ pszFileName); -+ -+ PDumpOSWriteString2(hScript, ui32PDumpFlags); -+ -+ PDUMP_UNLOCK(); -+ return PVRSRV_OK; -+} -+ -+/***************************************************************************** -+ FUNCTION : PDumpRegBasedCBP -+ -+ PURPOSE : Dump CBP command to script -+ -+ PARAMETERS : -+ -+ RETURNS : None -+*****************************************************************************/ -+PVRSRV_ERROR PDumpRegBasedCBP(IMG_CHAR *pszPDumpRegName, -+ IMG_UINT32 ui32RegOffset, -+ IMG_UINT32 ui32WPosVal, -+ IMG_UINT32 ui32PacketSize, -+ IMG_UINT32 ui32BufferSize, -+ IMG_UINT32 ui32Flags) -+{ -+ PDUMP_GET_SCRIPT_STRING(); -+ -+ PDUMP_LOCK(); -+ -+ PDumpOSBufprintf(hScript, -+ ui32MaxLen, -+ "CBP :%s:0x%08X 0x%08X 0x%08X 0x%08X\r\n", -+ pszPDumpRegName, -+ ui32RegOffset, -+ ui32WPosVal, -+ ui32PacketSize, -+ ui32BufferSize); -+ PDumpOSWriteString2(hScript, ui32Flags); -+ -+ PDUMP_UNLOCK(); -+ return PVRSRV_OK; -+} -+ -+ -+/**************************************************** -+ * Non-uitron code here. -+ * For example, code communicating with dbg driver. -+ ***************************************************/ -+/* PRQA S 5087 1 */ /* include file needed here */ -+#include "syscommon.h" -+ -+/************************************************************************** -+ * Function Name : PDumpConnectionNotify -+ * Description : Called by the debugdrv to tell Services that pdump has -+ * connected -+ * NOTE: No debugdrv on uitron. -+ **************************************************************************/ -+IMG_EXPORT IMG_VOID PDumpConnectionNotify(IMG_VOID) -+{ -+ SYS_DATA *psSysData; -+ PVRSRV_DEVICE_NODE *psThis; -+ PVR_DPF((PVR_DBG_WARNING, "PDump has connected.")); -+ -+ /* Loop over all known devices */ -+ SysAcquireData(&psSysData); -+ -+ psThis = psSysData->psDeviceNodeList; -+ while (psThis) -+ { -+ if (psThis->pfnPDumpInitDevice) -+ { -+ /* Reset pdump according to connected device */ -+ psThis->pfnPDumpInitDevice(psThis); -+ } -+ psThis = psThis->psNext; -+ } -+} -+ -+/***************************************************************************** -+ * Function Name : DbgWrite -+ * Inputs : psStream - debug stream to write to -+ pui8Data - buffer -+ ui32BCount - buffer length -+ ui32Flags - flags, e.g. continuous, LF -+ * Outputs : None -+ * Returns : Bytes written -+ * Description : Write a block of data to a debug stream -+ * NOTE: No debugdrv on uitron. -+ *****************************************************************************/ -+IMG_UINT32 DbgWrite(PDBG_STREAM psStream, IMG_UINT8 *pui8Data, IMG_UINT32 ui32BCount, IMG_UINT32 ui32Flags) -+{ -+ IMG_UINT32 ui32BytesWritten = 0; -+ IMG_UINT32 ui32Off = 0; -+ PDBG_STREAM_CONTROL psCtrl = psStream->psCtrl; -+ -+ /* Return immediately if marked as "never" */ -+ if ((ui32Flags & PDUMP_FLAGS_NEVER) != 0) -+ { -+ return ui32BCount; -+ } -+ -+#if defined(SUPPORT_PDUMP_MULTI_PROCESS) -+ /* Return if process is not marked for pdumping, unless it's persistent. -+ */ -+ if ( (_PDumpIsProcessActive() == IMG_FALSE ) && -+ ((ui32Flags & PDUMP_FLAGS_PERSISTENT) == 0) && psCtrl->bInitPhaseComplete) -+ { -+ return ui32BCount; -+ } -+#endif -+ -+ /* Send persistent data first ... -+ * If we're still initialising the params will be captured to the -+ * init stream in the call to pfnDBGDrivWrite2 below. -+ */ -+ if ( ((ui32Flags & PDUMP_FLAGS_PERSISTENT) != 0) && (psCtrl->bInitPhaseComplete) ) -+ { -+ while (ui32BCount > 0) -+ { -+ /* -+ Params marked as persistent should be appended to the init phase. -+ For example window system mem mapping of the primary surface. -+ */ -+ ui32BytesWritten = PDumpOSDebugDriverWrite( psStream, -+ PDUMP_WRITE_MODE_PERSISTENT, -+ &pui8Data[ui32Off], ui32BCount, 1, 0); -+ -+ if (ui32BytesWritten == 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "DbgWrite: Failed to send persistent data")); -+ PDumpOSReleaseExecution(); -+ } -+ -+ if (ui32BytesWritten != 0xFFFFFFFFU) -+ { -+ ui32Off += ui32BytesWritten; -+ ui32BCount -= ui32BytesWritten; -+ } -+ else -+ { -+ PVR_DPF((PVR_DBG_ERROR, "DbgWrite: Failed to send persistent data")); -+ if( (psCtrl->ui32Flags & DEBUG_FLAGS_READONLY) != 0) -+ { -+ /* suspend pdump to prevent flooding kernel log buffer */ -+ PDumpSuspendKM(); -+ } -+ return 0xFFFFFFFFU; -+ } -+ } -+ -+ /* reset buffer counters */ -+ ui32BCount = ui32Off; ui32Off = 0; ui32BytesWritten = 0; -+ } -+ -+ while (((IMG_UINT32) ui32BCount > 0) && (ui32BytesWritten != 0xFFFFFFFFU)) -+ { -+ /* If we're in the init phase we treat persisent as meaning continuous */ -+ if (((ui32Flags & PDUMP_FLAGS_CONTINUOUS) != 0) || ((ui32Flags & PDUMP_FLAGS_PERSISTENT) != 0)) -+ { -+ /* -+ If pdump client (or its equivalent) isn't running then throw continuous data away. -+ */ -+ if (((psCtrl->ui32CapMode & DEBUG_CAPMODE_FRAMED) != 0) && -+ (psCtrl->ui32Start == 0xFFFFFFFFU) && -+ (psCtrl->ui32End == 0xFFFFFFFFU) && -+ psCtrl->bInitPhaseComplete) -+ { -+ ui32BytesWritten = ui32BCount; -+ } -+ else -+ { -+ ui32BytesWritten = PDumpOSDebugDriverWrite( psStream, -+ PDUMP_WRITE_MODE_CONTINUOUS, -+ &pui8Data[ui32Off], ui32BCount, 1, 0); -+ } -+ } -+ else -+ { -+ if (ui32Flags & PDUMP_FLAGS_LASTFRAME) -+ { -+ IMG_UINT32 ui32DbgFlags; -+ -+ ui32DbgFlags = 0; -+ if (ui32Flags & PDUMP_FLAGS_RESETLFBUFFER) -+ { -+ ui32DbgFlags |= WRITELF_FLAGS_RESETBUF; -+ } -+ -+ ui32BytesWritten = PDumpOSDebugDriverWrite( psStream, -+ PDUMP_WRITE_MODE_LASTFRAME, -+ &pui8Data[ui32Off], ui32BCount, 1, ui32DbgFlags); -+ } -+ else -+ { -+ ui32BytesWritten = PDumpOSDebugDriverWrite( psStream, -+ PDUMP_WRITE_MODE_BINCM, -+ &pui8Data[ui32Off], ui32BCount, 1, 0); -+ } -+ } -+ -+ /* -+ If the debug driver's buffers are full so no data could be written then yield -+ execution so pdump can run and empty them. -+ */ -+ if (ui32BytesWritten == 0) -+ { -+ if (ui32Flags & PDUMP_FLAGS_CONTINUOUS) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "Buffer is full during writing of %s", &pui8Data[ui32Off])); -+ } -+ PDumpOSReleaseExecution(); -+ } -+ -+ if (ui32BytesWritten != 0xFFFFFFFFU) -+ { -+ ui32Off += ui32BytesWritten; -+ ui32BCount -= ui32BytesWritten; -+ } -+ else -+ { -+ if (ui32Flags & PDUMP_FLAGS_CONTINUOUS) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "Error during writing of %s", &pui8Data[ui32Off])); -+ } -+ } -+ /* loop exits when i) all data is written, or ii) an unrecoverable error occurs */ -+ } -+ -+ return ui32BytesWritten; -+} -+ -+ -+ -+#else /* defined(PDUMP) */ -+/* disable warning about empty module */ -+#endif /* defined(PDUMP) */ -+/***************************************************************************** -+ End of file (pdump_common.c) -+*****************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/common/perproc.c b/drivers/staging/ti-es8-sgx/services4/srvkm/common/perproc.c -new file mode 100644 -index 0000000..385ec39 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/common/perproc.c -@@ -0,0 +1,398 @@ -+/*************************************************************************/ /*! -+@Title Per-process storage -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Manage per-process storage -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#include "services_headers.h" -+#include "resman.h" -+#include "handle.h" -+#include "perproc.h" -+#include "osperproc.h" -+#if defined(TTRACE) -+#include "ttrace.h" -+#endif -+ -+#define HASH_TAB_INIT_SIZE 32 -+ -+static HASH_TABLE *psHashTab = IMG_NULL; -+ -+/*! -+****************************************************************************** -+ -+ @Function FreePerProcData -+ -+ @Description Free a per-process data area -+ -+ @Input psPerProc - pointer to per-process data area -+ -+ @Return Error code, or PVRSRV_OK -+ -+******************************************************************************/ -+static PVRSRV_ERROR FreePerProcessData(PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ PVRSRV_ERROR eError; -+ IMG_UINTPTR_T uiPerProc; -+ -+ PVR_ASSERT(psPerProc != IMG_NULL); -+ -+ if (psPerProc == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: invalid parameter")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ uiPerProc = HASH_Remove(psHashTab, (IMG_UINTPTR_T)psPerProc->ui32PID); -+ if (uiPerProc == 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: Couldn't find process in per-process data hash table")); -+ /* -+ * We must have failed early in the per-process data area -+ * creation, before the process ID was set. -+ */ -+ PVR_ASSERT(psPerProc->ui32PID == 0); -+ } -+ else -+ { -+ PVR_ASSERT((PVRSRV_PER_PROCESS_DATA *)uiPerProc == psPerProc); -+ PVR_ASSERT(((PVRSRV_PER_PROCESS_DATA *)uiPerProc)->ui32PID == psPerProc->ui32PID); -+ } -+ -+ /* Free handle base for this process */ -+ if (psPerProc->psHandleBase != IMG_NULL) -+ { -+ eError = PVRSRVFreeHandleBase(psPerProc->psHandleBase); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: Couldn't free handle base for process (%d)", eError)); -+ return eError; -+ } -+ } -+ -+ /* Release handle for per-process data area */ -+ if (psPerProc->hPerProcData != IMG_NULL) -+ { -+ eError = PVRSRVReleaseHandle(KERNEL_HANDLE_BASE, psPerProc->hPerProcData, PVRSRV_HANDLE_TYPE_PERPROC_DATA); -+ -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: Couldn't release per-process data handle (%d)", eError)); -+ return eError; -+ } -+ } -+ -+ /* Call environment specific per process deinit function */ -+ eError = OSPerProcessPrivateDataDeInit(psPerProc->hOsPrivateData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: OSPerProcessPrivateDataDeInit failed (%d)", eError)); -+ return eError; -+ } -+ -+ eError = OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, -+ sizeof(*psPerProc), -+ psPerProc, -+ psPerProc->hBlockAlloc); -+ /*not nulling pointer, copy on stack*/ -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: Couldn't free per-process data (%d)", eError)); -+ return eError; -+ } -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVPerProcessData -+ -+ @Description Return per-process data area -+ -+ @Input ui32PID - process ID -+ -+ @Return Pointer to per-process data area, or IMG_NULL on error. -+ -+******************************************************************************/ -+PVRSRV_PER_PROCESS_DATA *PVRSRVPerProcessData(IMG_UINT32 ui32PID) -+{ -+ PVRSRV_PER_PROCESS_DATA *psPerProc; -+ -+ PVR_ASSERT(psHashTab != IMG_NULL); -+ -+ /* Look for existing per-process data area */ -+ psPerProc = (PVRSRV_PER_PROCESS_DATA *)HASH_Retrieve(psHashTab, (IMG_UINTPTR_T)ui32PID); -+ return psPerProc; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVPerProcessDataConnect -+ -+ @Description Allocate per-process data area, or increment refcount if one -+ already exists for this PID. -+ -+ @Input ui32PID - process ID -+ ppsPerProc - Pointer to per-process data area -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR PVRSRVPerProcessDataConnect(IMG_UINT32 ui32PID, IMG_UINT32 ui32Flags) -+{ -+ PVRSRV_PER_PROCESS_DATA *psPerProc; -+ IMG_HANDLE hBlockAlloc; -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ -+ if (psHashTab == IMG_NULL) -+ { -+ return PVRSRV_ERROR_INIT_FAILURE; -+ } -+ -+ /* Look for existing per-process data area */ -+ psPerProc = (PVRSRV_PER_PROCESS_DATA *)HASH_Retrieve(psHashTab, (IMG_UINTPTR_T)ui32PID); -+ -+ if (psPerProc == IMG_NULL) -+ { -+ /* Allocate per-process data area */ -+ eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, -+ sizeof(*psPerProc), -+ (IMG_PVOID *)&psPerProc, -+ &hBlockAlloc, -+ "Per Process Data"); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate per-process data (%d)", eError)); -+ return eError; -+ } -+ OSMemSet(psPerProc, 0, sizeof(*psPerProc)); -+ psPerProc->hBlockAlloc = hBlockAlloc; -+ -+ if (!HASH_Insert(psHashTab, (IMG_UINTPTR_T)ui32PID, (IMG_UINTPTR_T)psPerProc)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't insert per-process data into hash table")); -+ eError = PVRSRV_ERROR_INSERT_HASH_TABLE_DATA_FAILED; -+ goto failure; -+ } -+ -+ psPerProc->ui32PID = ui32PID; -+ psPerProc->ui32RefCount = 0; -+ -+#if defined(SUPPORT_PDUMP_MULTI_PROCESS) -+ if (ui32Flags == SRV_FLAGS_PDUMP_ACTIVE) -+ { -+ psPerProc->bPDumpActive = IMG_TRUE; -+ } -+#else -+ PVR_UNREFERENCED_PARAMETER(ui32Flags); -+#endif -+ -+ /* Call environment specific per process init function */ -+ eError = OSPerProcessPrivateDataInit(&psPerProc->hOsPrivateData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: OSPerProcessPrivateDataInit failed (%d)", eError)); -+ goto failure; -+ } -+ -+ /* Allocate a handle for the per-process data area */ -+ eError = PVRSRVAllocHandle(KERNEL_HANDLE_BASE, -+ &psPerProc->hPerProcData, -+ psPerProc, -+ PVRSRV_HANDLE_TYPE_PERPROC_DATA, -+ PVRSRV_HANDLE_ALLOC_FLAG_NONE); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate handle for per-process data (%d)", eError)); -+ goto failure; -+ } -+ -+ /* Allocate handle base for this process */ -+ eError = PVRSRVAllocHandleBase(&psPerProc->psHandleBase); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate handle base for process (%d)", eError)); -+ goto failure; -+ } -+ -+ /* Set per-process handle options */ -+ eError = OSPerProcessSetHandleOptions(psPerProc->psHandleBase); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't set handle options (%d)", eError)); -+ goto failure; -+ } -+ -+ /* Create a resource manager context for the process */ -+ eError = PVRSRVResManConnect(psPerProc, &psPerProc->hResManContext); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't register with the resource manager")); -+ goto failure; -+ } -+#if defined (TTRACE) -+ PVRSRVTimeTraceBufferCreate(ui32PID); -+#endif -+ } -+ -+ psPerProc->ui32RefCount++; -+ PVR_DPF((PVR_DBG_MESSAGE, -+ "PVRSRVPerProcessDataConnect: Process 0x%x has ref-count %d", -+ ui32PID, psPerProc->ui32RefCount)); -+ -+ return eError; -+ -+failure: -+ (IMG_VOID)FreePerProcessData(psPerProc); -+ return eError; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVPerProcessDataDisconnect -+ -+ @Description Decrement refcount for per-process data area, -+ and free the resources if necessary. -+ -+ @Input ui32PID - process ID -+ -+ @Return IMG_VOID -+ -+******************************************************************************/ -+IMG_VOID PVRSRVPerProcessDataDisconnect(IMG_UINT32 ui32PID) -+{ -+ PVRSRV_ERROR eError; -+ PVRSRV_PER_PROCESS_DATA *psPerProc; -+ -+ PVR_ASSERT(psHashTab != IMG_NULL); -+ -+ psPerProc = (PVRSRV_PER_PROCESS_DATA *)HASH_Retrieve(psHashTab, (IMG_UINTPTR_T)ui32PID); -+ if (psPerProc == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataDealloc: Couldn't locate per-process data for PID %u", ui32PID)); -+ } -+ else -+ { -+ psPerProc->ui32RefCount--; -+ if (psPerProc->ui32RefCount == 0) -+ { -+ PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVPerProcessDataDisconnect: " -+ "Last close from process 0x%x received", ui32PID)); -+ -+ /* Close the Resource Manager connection */ -+ PVRSRVResManDisconnect(psPerProc->hResManContext, IMG_FALSE); -+ -+#if defined (TTRACE) -+ PVRSRVTimeTraceBufferDestroy(ui32PID); -+#endif -+ -+ /* Free the per-process data */ -+ eError = FreePerProcessData(psPerProc); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataDisconnect: Error freeing per-process data")); -+ } -+ } -+ } -+ -+ eError = PVRSRVPurgeHandles(KERNEL_HANDLE_BASE); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataDisconnect: Purge of global handle pool failed (%d)", eError)); -+ } -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVPerProcessDataInit -+ -+ @Description Initialise per-process data management -+ -+ @Return Error code, or PVRSRV_OK -+ -+******************************************************************************/ -+PVRSRV_ERROR PVRSRVPerProcessDataInit(IMG_VOID) -+{ -+ PVR_ASSERT(psHashTab == IMG_NULL); -+ -+ /* Create hash table */ -+ psHashTab = HASH_Create(HASH_TAB_INIT_SIZE); -+ if (psHashTab == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataInit: Couldn't create per-process data hash table")); -+ return PVRSRV_ERROR_UNABLE_TO_CREATE_HASH_TABLE; -+ } -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVPerProcessDataDeInit -+ -+ @Description De-initialise per-process data management -+ -+ @Return Error code, or PVRSRV_OK -+ -+******************************************************************************/ -+PVRSRV_ERROR PVRSRVPerProcessDataDeInit(IMG_VOID) -+{ -+ /* Destroy per-process data area hash table */ -+ if (psHashTab != IMG_NULL) -+ { -+ /* Free the hash table */ -+ HASH_Delete(psHashTab); -+ psHashTab = IMG_NULL; -+ } -+ -+ return PVRSRV_OK; -+} -+ -+/****************************************************************************** -+ End of file (perproc.c) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/common/power.c b/drivers/staging/ti-es8-sgx/services4/srvkm/common/power.c -new file mode 100644 -index 0000000..cca1f89 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/common/power.c -@@ -0,0 +1,996 @@ -+/*************************************************************************/ /*! -+@Title Power management functions -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Main APIs for power management functions -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#include "services_headers.h" -+#include "pdump_km.h" -+ -+#include "lists.h" -+ -+static IMG_BOOL gbInitServerRunning = IMG_FALSE; -+static IMG_BOOL gbInitServerRan = IMG_FALSE; -+static IMG_BOOL gbInitSuccessful = IMG_FALSE; -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVSetInitServerState -+ -+ @Description Sets given services init state. -+ -+ @Input eInitServerState : a services init state -+ @Input bState : a state to set -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_STATE eInitServerState, IMG_BOOL bState) -+{ -+ -+ switch(eInitServerState) -+ { -+ case PVRSRV_INIT_SERVER_RUNNING: -+ gbInitServerRunning = bState; -+ break; -+ case PVRSRV_INIT_SERVER_RAN: -+ gbInitServerRan = bState; -+ break; -+ case PVRSRV_INIT_SERVER_SUCCESSFUL: -+ gbInitSuccessful = bState; -+ break; -+ default: -+ PVR_DPF((PVR_DBG_ERROR, -+ "PVRSRVSetInitServerState : Unknown state %x", eInitServerState)); -+ return PVRSRV_ERROR_UNKNOWN_INIT_SERVER_STATE; -+ } -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVGetInitServerState -+ -+ @Description Tests whether a given services init state was run. -+ -+ @Input eInitServerState : a services init state -+ -+ @Return IMG_BOOL -+ -+******************************************************************************/ -+IMG_EXPORT -+IMG_BOOL PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_STATE eInitServerState) -+{ -+ IMG_BOOL bReturnVal; -+ -+ switch(eInitServerState) -+ { -+ case PVRSRV_INIT_SERVER_RUNNING: -+ bReturnVal = gbInitServerRunning; -+ break; -+ case PVRSRV_INIT_SERVER_RAN: -+ bReturnVal = gbInitServerRan; -+ break; -+ case PVRSRV_INIT_SERVER_SUCCESSFUL: -+ bReturnVal = gbInitSuccessful; -+ break; -+ default: -+ PVR_DPF((PVR_DBG_ERROR, -+ "PVRSRVGetInitServerState : Unknown state %x", eInitServerState)); -+ bReturnVal = IMG_FALSE; -+ } -+ -+ return bReturnVal; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function _IsSystemStatePowered -+ -+ @Description Tests whether a given system state represents powered-up. -+ -+ @Input eSystemPowerState : a system power state -+ -+ @Return IMG_BOOL -+ -+******************************************************************************/ -+static IMG_BOOL _IsSystemStatePowered(PVRSRV_SYS_POWER_STATE eSystemPowerState) -+{ -+ return (IMG_BOOL)(eSystemPowerState < PVRSRV_SYS_POWER_STATE_D2); -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVPowerLock -+ -+ @Description Obtain the mutex for power transitions -+ -+ @Input ui32CallerID : KERNEL_ID or ISR_ID -+ @Input bSystemPowerEvent : Only pass IMG_TRUE if the lock is for a -+ system power state change -+ -+ @Return PVRSRV_ERROR IMG_CALLCONV -+ -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR PVRSRVPowerLock(IMG_UINT32 ui32CallerID, -+ IMG_BOOL bSystemPowerEvent) -+{ -+ PVRSRV_ERROR eError; -+ SYS_DATA *psSysData; -+ IMG_UINT32 ui32Timeout = 1000000; -+ IMG_BOOL bTryLock = (ui32CallerID == ISR_ID); -+ -+ SysAcquireData(&psSysData); -+ -+ eError = OSPowerLockWrap(bTryLock); -+ if (eError != PVRSRV_OK) -+ { -+ return eError; -+ } -+ -+ do -+ { -+ eError = OSLockResource(&psSysData->sPowerStateChangeResource, -+ ui32CallerID); -+ if (eError == PVRSRV_OK) -+ { -+ break; -+ } -+ else if (bTryLock) -+ { -+ /* -+ ISR failed to acquire lock so it must be held by a kernel thread. -+ */ -+ eError = PVRSRV_ERROR_RETRY; -+ break; -+ } -+ -+ OSWaitus(1); -+ ui32Timeout--; -+ } while (ui32Timeout > 0); -+ -+ if (eError != PVRSRV_OK) -+ { -+ OSPowerLockUnwrap(); -+ } -+ -+ /* PRQA S 3415 3 */ /* side effects desired */ -+ if ((eError == PVRSRV_OK) && -+ !bSystemPowerEvent && -+ !_IsSystemStatePowered(psSysData->eCurrentPowerState)) -+ { -+ /* Reject device power state change due to system power state. */ -+ PVRSRVPowerUnlock(ui32CallerID); -+ eError = PVRSRV_ERROR_RETRY; -+ } -+ -+ return eError; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVPowerUnlock -+ -+ @Description Release the mutex for power transitions -+ -+ @Input ui32CallerID : KERNEL_ID or ISR_ID -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+IMG_EXPORT -+IMG_VOID PVRSRVPowerUnlock(IMG_UINT32 ui32CallerID) -+{ -+ OSUnlockResource(&gpsSysData->sPowerStateChangeResource, ui32CallerID); -+ OSPowerLockUnwrap(); -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVDevicePrePowerStateKM_AnyVaCb -+ -+ @Description -+ -+ Perform device-specific processing required before a power transition -+ -+ @Input psPowerDevice : the device -+ @Input va : variable argument list with: -+ bAllDevices : IMG_TRUE - All devices -+ IMG_FALSE - Use ui32DeviceIndex -+ ui32DeviceIndex : device index -+ eNewPowerState : New power state -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+static PVRSRV_ERROR PVRSRVDevicePrePowerStateKM_AnyVaCb(PVRSRV_POWER_DEV *psPowerDevice, va_list va) -+{ -+ PVRSRV_DEV_POWER_STATE eNewDevicePowerState; -+ PVRSRV_ERROR eError; -+ -+ /*Variable Argument variables*/ -+ IMG_BOOL bAllDevices; -+ IMG_UINT32 ui32DeviceIndex; -+ PVRSRV_DEV_POWER_STATE eNewPowerState; -+ -+ /* WARNING: if types were not aligned to 4 bytes, this could be dangerous. */ -+ bAllDevices = va_arg(va, IMG_BOOL); -+ ui32DeviceIndex = va_arg(va, IMG_UINT32); -+ eNewPowerState = va_arg(va, PVRSRV_DEV_POWER_STATE); -+ -+ if (bAllDevices || (ui32DeviceIndex == psPowerDevice->ui32DeviceIndex)) -+ { -+ eNewDevicePowerState = (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT) ? -+ psPowerDevice->eDefaultPowerState : eNewPowerState; -+ -+ if (psPowerDevice->eCurrentPowerState != eNewDevicePowerState) -+ { -+ if (psPowerDevice->pfnPrePower != IMG_NULL) -+ { -+ /* Call the device's power callback. */ -+ eError = psPowerDevice->pfnPrePower(psPowerDevice->hDevCookie, -+ eNewDevicePowerState, -+ psPowerDevice->eCurrentPowerState); -+ if (eError != PVRSRV_OK) -+ { -+ return eError; -+ } -+ } -+ -+ /* Do any required system-layer processing. */ -+ eError = SysDevicePrePowerState(psPowerDevice->ui32DeviceIndex, -+ eNewDevicePowerState, -+ psPowerDevice->eCurrentPowerState); -+ if (eError != PVRSRV_OK) -+ { -+ return eError; -+ } -+ } -+ } -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVDevicePrePowerStateKM -+ -+ @Description -+ -+ Perform device-specific processing required before a power transition -+ -+ @Input bAllDevices : IMG_TRUE - All devices -+ IMG_FALSE - Use ui32DeviceIndex -+ @Input ui32DeviceIndex : device index -+ @Input eNewPowerState : New power state -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+static -+PVRSRV_ERROR PVRSRVDevicePrePowerStateKM(IMG_BOOL bAllDevices, -+ IMG_UINT32 ui32DeviceIndex, -+ PVRSRV_DEV_POWER_STATE eNewPowerState) -+{ -+ PVRSRV_ERROR eError; -+ SYS_DATA *psSysData; -+ -+ SysAcquireData(&psSysData); -+ -+ /* Loop through the power devices. */ -+ eError = List_PVRSRV_POWER_DEV_PVRSRV_ERROR_Any_va(psSysData->psPowerDeviceList, -+ &PVRSRVDevicePrePowerStateKM_AnyVaCb, -+ bAllDevices, -+ ui32DeviceIndex, -+ eNewPowerState); -+ -+ return eError; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVDevicePostPowerStateKM_AnyVaCb -+ -+ @Description -+ -+ Perform device-specific processing required after a power transition -+ -+ @Input psPowerDevice : the device -+ @Input va : variable argument list with: -+ bAllDevices : IMG_TRUE - All devices -+ IMG_FALSE - Use ui32DeviceIndex -+ ui32DeviceIndex : device index -+ eNewPowerState : New power state -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+static PVRSRV_ERROR PVRSRVDevicePostPowerStateKM_AnyVaCb(PVRSRV_POWER_DEV *psPowerDevice, va_list va) -+{ -+ PVRSRV_DEV_POWER_STATE eNewDevicePowerState; -+ PVRSRV_ERROR eError; -+ -+ /*Variable Argument variables*/ -+ IMG_BOOL bAllDevices; -+ IMG_UINT32 ui32DeviceIndex; -+ PVRSRV_DEV_POWER_STATE eNewPowerState; -+ -+ /* WARNING: if types were not aligned to 4 bytes, this could be dangerous. */ -+ bAllDevices = va_arg(va, IMG_BOOL); -+ ui32DeviceIndex = va_arg(va, IMG_UINT32); -+ eNewPowerState = va_arg(va, PVRSRV_DEV_POWER_STATE); -+ -+ if (bAllDevices || (ui32DeviceIndex == psPowerDevice->ui32DeviceIndex)) -+ { -+ eNewDevicePowerState = (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT) ? -+ psPowerDevice->eDefaultPowerState : eNewPowerState; -+ -+ if (psPowerDevice->eCurrentPowerState != eNewDevicePowerState) -+ { -+ /* Do any required system-layer processing. */ -+ eError = SysDevicePostPowerState(psPowerDevice->ui32DeviceIndex, -+ eNewDevicePowerState, -+ psPowerDevice->eCurrentPowerState); -+ if (eError != PVRSRV_OK) -+ { -+ return eError; -+ } -+ -+ if (psPowerDevice->pfnPostPower != IMG_NULL) -+ { -+ /* Call the device's power callback. */ -+ eError = psPowerDevice->pfnPostPower(psPowerDevice->hDevCookie, -+ eNewDevicePowerState, -+ psPowerDevice->eCurrentPowerState); -+ if (eError != PVRSRV_OK) -+ { -+ return eError; -+ } -+ } -+ -+ psPowerDevice->eCurrentPowerState = eNewDevicePowerState; -+ } -+ } -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVDevicePostPowerStateKM -+ -+ @Description -+ -+ Perform device-specific processing required after a power transition -+ -+ @Input bAllDevices : IMG_TRUE - All devices -+ IMG_FALSE - Use ui32DeviceIndex -+ @Input ui32DeviceIndex : device index -+ @Input eNewPowerState : New power state -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+static -+PVRSRV_ERROR PVRSRVDevicePostPowerStateKM(IMG_BOOL bAllDevices, -+ IMG_UINT32 ui32DeviceIndex, -+ PVRSRV_DEV_POWER_STATE eNewPowerState) -+{ -+ PVRSRV_ERROR eError; -+ SYS_DATA *psSysData; -+ -+ SysAcquireData(&psSysData); -+ -+ /* Loop through the power devices. */ -+ eError = List_PVRSRV_POWER_DEV_PVRSRV_ERROR_Any_va(psSysData->psPowerDeviceList, -+ &PVRSRVDevicePostPowerStateKM_AnyVaCb, -+ bAllDevices, -+ ui32DeviceIndex, -+ eNewPowerState); -+ -+ return eError; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVSetDevicePowerStateKM -+ -+ @Description Set the Device into a new state -+ -+ @Input ui32DeviceIndex : device index -+ @Input eNewPowerState : New power state -+ @Input ui32CallerID : KERNEL_ID or ISR_ID -+ @Input bRetainMutex : If true, the power mutex is retained on exit -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR PVRSRVSetDevicePowerStateKM(IMG_UINT32 ui32DeviceIndex, -+ PVRSRV_DEV_POWER_STATE eNewPowerState) -+{ -+ PVRSRV_ERROR eError; -+ SYS_DATA *psSysData; -+ -+ SysAcquireData(&psSysData); -+ -+ #if defined(PDUMP) -+ if (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT) -+ { -+ /* -+ Pdump a power-up regardless of the default state. -+ Then disable pdump and transition to the default power state. -+ This ensures that a power-up is always present in the pdump when necessary. -+ */ -+ eError = PVRSRVDevicePrePowerStateKM(IMG_FALSE, ui32DeviceIndex, PVRSRV_DEV_POWER_STATE_ON); -+ if(eError != PVRSRV_OK) -+ { -+ goto Exit; -+ } -+ -+ eError = PVRSRVDevicePostPowerStateKM(IMG_FALSE, ui32DeviceIndex, PVRSRV_DEV_POWER_STATE_ON); -+ -+ if (eError != PVRSRV_OK) -+ { -+ goto Exit; -+ } -+ -+ PDUMPSUSPEND(); -+ } -+ #endif /* PDUMP */ -+ -+ eError = PVRSRVDevicePrePowerStateKM(IMG_FALSE, ui32DeviceIndex, eNewPowerState); -+ if(eError != PVRSRV_OK) -+ { -+ if (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT) -+ { -+ PDUMPRESUME(); -+ } -+ goto Exit; -+ } -+ -+ eError = PVRSRVDevicePostPowerStateKM(IMG_FALSE, ui32DeviceIndex, eNewPowerState); -+ -+ if (eNewPowerState == PVRSRV_DEV_POWER_STATE_DEFAULT) -+ { -+ PDUMPRESUME(); -+ } -+ -+Exit: -+ -+ if(eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, -+ "PVRSRVSetDevicePowerStateKM : Transition to %d FAILED 0x%x", eNewPowerState, eError)); -+ } -+ -+ return eError; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVSystemPrePowerStateKM -+ -+ @Description Perform processing required before a system power transition -+ -+ @Input eNewSysPowerState : -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR PVRSRVSystemPrePowerStateKM(PVRSRV_SYS_POWER_STATE eNewSysPowerState) -+{ -+ PVRSRV_ERROR eError; -+ SYS_DATA *psSysData; -+ PVRSRV_DEV_POWER_STATE eNewDevicePowerState; -+ -+ SysAcquireData(&psSysData); -+ -+ /* This mutex is unlocked in PVRSRVSystemPostPowerStateKM() */ -+ eError = PVRSRVPowerLock(KERNEL_ID, IMG_TRUE); -+ if(eError != PVRSRV_OK) -+ { -+ return eError; -+ } -+ -+ if (_IsSystemStatePowered(eNewSysPowerState) != -+ _IsSystemStatePowered(psSysData->eCurrentPowerState)) -+ { -+ if (_IsSystemStatePowered(eNewSysPowerState)) -+ { -+ /* Return device back to its default state. */ -+ eNewDevicePowerState = PVRSRV_DEV_POWER_STATE_DEFAULT; -+ } -+ else -+ { -+ eNewDevicePowerState = PVRSRV_DEV_POWER_STATE_OFF; -+ } -+ -+ /* Perform device-specific transitions. */ -+ eError = PVRSRVDevicePrePowerStateKM(IMG_TRUE, 0, eNewDevicePowerState); -+ if (eError != PVRSRV_OK) -+ { -+ goto ErrorExit; -+ } -+ } -+ -+ if (eNewSysPowerState != psSysData->eCurrentPowerState) -+ { -+ /* Perform system-specific power transitions. */ -+ eError = SysSystemPrePowerState(eNewSysPowerState); -+ if (eError != PVRSRV_OK) -+ { -+ goto ErrorExit; -+ } -+ } -+ -+ return eError; -+ -+ErrorExit: -+ -+ PVR_DPF((PVR_DBG_ERROR, -+ "PVRSRVSystemPrePowerStateKM: Transition from %d to %d FAILED 0x%x", -+ psSysData->eCurrentPowerState, eNewSysPowerState, eError)); -+ -+ /* save the power state for the re-attempt */ -+ psSysData->eFailedPowerState = eNewSysPowerState; -+ -+ PVRSRVPowerUnlock(KERNEL_ID); -+ -+ return eError; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVSystemPostPowerStateKM -+ -+ @Description Perform processing required after a system power transition -+ -+ @Input eNewSysPowerState : -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR PVRSRVSystemPostPowerStateKM(PVRSRV_SYS_POWER_STATE eNewSysPowerState) -+{ -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ SYS_DATA *psSysData; -+ PVRSRV_DEV_POWER_STATE eNewDevicePowerState; -+ -+ SysAcquireData(&psSysData); -+ -+ if (eNewSysPowerState != psSysData->eCurrentPowerState) -+ { -+ /* Perform system-specific power transitions. */ -+ eError = SysSystemPostPowerState(eNewSysPowerState); -+ if (eError != PVRSRV_OK) -+ { -+ goto Exit; -+ } -+ } -+ -+ if (_IsSystemStatePowered(eNewSysPowerState) != -+ _IsSystemStatePowered(psSysData->eCurrentPowerState)) -+ { -+ if (_IsSystemStatePowered(eNewSysPowerState)) -+ { -+ /* Return device back to its default state. */ -+ eNewDevicePowerState = PVRSRV_DEV_POWER_STATE_DEFAULT; -+ } -+ else -+ { -+ eNewDevicePowerState = PVRSRV_DEV_POWER_STATE_OFF; -+ } -+ -+ /* Perform device-specific power transitions. */ -+ eError = PVRSRVDevicePostPowerStateKM(IMG_TRUE, 0, eNewDevicePowerState); -+ if (eError != PVRSRV_OK) -+ { -+ goto Exit; -+ } -+ } -+ -+ PVR_DPF((PVR_DBG_MESSAGE, -+ "PVRSRVSystemPostPowerStateKM: System Power Transition from %d to %d OK", -+ psSysData->eCurrentPowerState, eNewSysPowerState)); -+ -+ psSysData->eCurrentPowerState = eNewSysPowerState; -+ -+Exit: -+ -+ PVRSRVPowerUnlock(KERNEL_ID); -+ -+ /* PRQA S 3415 2 */ /* side effects desired */ -+ if (_IsSystemStatePowered(eNewSysPowerState) && -+ PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL)) -+ { -+ /* -+ Reprocess the devices' queues in case commands were blocked during -+ the power transition. -+ */ -+ PVRSRVScheduleDeviceCallbacks(); -+ } -+ -+ return eError; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVSetPowerStateKM -+ -+ @Description Set the system into a new state -+ -+ @Input eNewPowerState : -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE eNewSysPowerState) -+{ -+ PVRSRV_ERROR eError; -+ SYS_DATA *psSysData; -+ -+ SysAcquireData(&psSysData); -+ -+ eError = PVRSRVSystemPrePowerStateKM(eNewSysPowerState); -+ if(eError != PVRSRV_OK) -+ { -+ goto ErrorExit; -+ } -+ -+ eError = PVRSRVSystemPostPowerStateKM(eNewSysPowerState); -+ if(eError != PVRSRV_OK) -+ { -+ goto ErrorExit; -+ } -+ -+ /* save new power state */ -+ psSysData->eFailedPowerState = PVRSRV_SYS_POWER_STATE_Unspecified; -+ -+ return PVRSRV_OK; -+ -+ErrorExit: -+ -+ PVR_DPF((PVR_DBG_ERROR, -+ "PVRSRVSetPowerStateKM: Transition from %d to %d FAILED 0x%x", -+ psSysData->eCurrentPowerState, eNewSysPowerState, eError)); -+ -+ /* save the power state for the re-attempt */ -+ psSysData->eFailedPowerState = eNewSysPowerState; -+ -+ return eError; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVRegisterPowerDevice -+ -+ @Description -+ -+ Registers a device with the power manager. Passes Pre/Post Power handlers -+ and private device handle to be passed to power handlers -+ -+ @Input ui32DeviceIndex : device index -+ @Input pfnPrePower : Pre power transition handler -+ @Input pfnPostPower : Post power transition handler -+ @Input pfnPreClockSpeedChange : Pre clock speed transition handler (if required) -+ @Input pfnPostClockSpeedChange : Post clock speed transition handler (if required) -+ @Input hDevCookie : Dev cookie for dev power handlers -+ @Input eCurrentPowerState : Current power state of the device -+ @Input eDefaultPowerState : Default power state of the device -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR PVRSRVRegisterPowerDevice(IMG_UINT32 ui32DeviceIndex, -+ PFN_PRE_POWER pfnPrePower, -+ PFN_POST_POWER pfnPostPower, -+ PFN_PRE_CLOCKSPEED_CHANGE pfnPreClockSpeedChange, -+ PFN_POST_CLOCKSPEED_CHANGE pfnPostClockSpeedChange, -+ IMG_HANDLE hDevCookie, -+ PVRSRV_DEV_POWER_STATE eCurrentPowerState, -+ PVRSRV_DEV_POWER_STATE eDefaultPowerState) -+{ -+ PVRSRV_ERROR eError; -+ SYS_DATA *psSysData; -+ PVRSRV_POWER_DEV *psPowerDevice; -+ -+ if (pfnPrePower == IMG_NULL && -+ pfnPostPower == IMG_NULL) -+ { -+ return PVRSRVRemovePowerDevice(ui32DeviceIndex); -+ } -+ -+ SysAcquireData(&psSysData); -+ -+ eError = OSAllocMem( PVRSRV_OS_NON_PAGEABLE_HEAP, -+ sizeof(PVRSRV_POWER_DEV), -+ (IMG_VOID **)&psPowerDevice, IMG_NULL, -+ "Power Device"); -+ if(eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterPowerDevice: Failed to alloc PVRSRV_POWER_DEV")); -+ return eError; -+ } -+ -+ /* setup device for power manager */ -+ psPowerDevice->pfnPrePower = pfnPrePower; -+ psPowerDevice->pfnPostPower = pfnPostPower; -+ psPowerDevice->pfnPreClockSpeedChange = pfnPreClockSpeedChange; -+ psPowerDevice->pfnPostClockSpeedChange = pfnPostClockSpeedChange; -+ psPowerDevice->hDevCookie = hDevCookie; -+ psPowerDevice->ui32DeviceIndex = ui32DeviceIndex; -+ psPowerDevice->eCurrentPowerState = eCurrentPowerState; -+ psPowerDevice->eDefaultPowerState = eDefaultPowerState; -+ -+ /* insert into power device list */ -+ List_PVRSRV_POWER_DEV_Insert(&(psSysData->psPowerDeviceList), psPowerDevice); -+ -+ return (PVRSRV_OK); -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVRemovePowerDevice -+ -+ @Description -+ -+ Removes device from power management register. Device is located by Device Index -+ -+ @Input ui32DeviceIndex : device index -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR PVRSRVRemovePowerDevice (IMG_UINT32 ui32DeviceIndex) -+{ -+ SYS_DATA *psSysData; -+ PVRSRV_POWER_DEV *psPowerDev; -+ -+ SysAcquireData(&psSysData); -+ -+ /* find device in list and remove it */ -+ psPowerDev = (PVRSRV_POWER_DEV*) -+ List_PVRSRV_POWER_DEV_Any_va(psSysData->psPowerDeviceList, -+ &MatchPowerDeviceIndex_AnyVaCb, -+ ui32DeviceIndex); -+ -+ if (psPowerDev) -+ { -+ List_PVRSRV_POWER_DEV_Remove(psPowerDev); -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_POWER_DEV), psPowerDev, IMG_NULL); -+ /*not nulling pointer, copy on stack*/ -+ } -+ -+ return (PVRSRV_OK); -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVIsDevicePowered -+ -+ @Description -+ -+ Whether the device is powered, for the purposes of lockup detection. -+ -+ @Input ui32DeviceIndex : device index -+ -+ @Return IMG_BOOL -+ -+******************************************************************************/ -+IMG_EXPORT -+IMG_BOOL PVRSRVIsDevicePowered(IMG_UINT32 ui32DeviceIndex) -+{ -+ SYS_DATA *psSysData; -+ PVRSRV_POWER_DEV *psPowerDevice; -+ -+ SysAcquireData(&psSysData); -+ -+ /* PRQA S 3415 2 */ /* order not important */ -+ if (OSIsResourceLocked(&psSysData->sPowerStateChangeResource, KERNEL_ID) || -+ OSIsResourceLocked(&psSysData->sPowerStateChangeResource, ISR_ID)) -+ { -+ return IMG_FALSE; -+ } -+ -+ psPowerDevice = (PVRSRV_POWER_DEV*) -+ List_PVRSRV_POWER_DEV_Any_va(psSysData->psPowerDeviceList, -+ &MatchPowerDeviceIndex_AnyVaCb, -+ ui32DeviceIndex); -+ return (psPowerDevice && (psPowerDevice->eCurrentPowerState == PVRSRV_DEV_POWER_STATE_ON)) -+ ? IMG_TRUE : IMG_FALSE; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVDevicePreClockSpeedChange -+ -+ @Description -+ -+ Notification from system layer that a device clock speed change is about to happen. -+ -+ @Input ui32DeviceIndex : device index -+ @Input bIdleDevice : whether the device should be idled -+ @Input pvInfo -+ -+ @Return IMG_VOID -+ -+******************************************************************************/ -+PVRSRV_ERROR PVRSRVDevicePreClockSpeedChange(IMG_UINT32 ui32DeviceIndex, -+ IMG_BOOL bIdleDevice, -+ IMG_VOID *pvInfo) -+{ -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ SYS_DATA *psSysData; -+ PVRSRV_POWER_DEV *psPowerDevice; -+ -+ PVR_UNREFERENCED_PARAMETER(pvInfo); -+ -+ SysAcquireData(&psSysData); -+ -+ if (bIdleDevice) -+ { -+ /* This mutex is released in PVRSRVDevicePostClockSpeedChange. */ -+ eError = PVRSRVPowerLock(KERNEL_ID, IMG_FALSE); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVDevicePreClockSpeedChange : failed to acquire lock, error:0x%x", eError)); -+ return eError; -+ } -+ } -+ -+ /*search the device and then do the pre clock speed change*/ -+ psPowerDevice = (PVRSRV_POWER_DEV*) -+ List_PVRSRV_POWER_DEV_Any_va(psSysData->psPowerDeviceList, -+ &MatchPowerDeviceIndex_AnyVaCb, -+ ui32DeviceIndex); -+ -+ if (psPowerDevice && psPowerDevice->pfnPostClockSpeedChange) -+ { -+ eError = psPowerDevice->pfnPreClockSpeedChange(psPowerDevice->hDevCookie, -+ bIdleDevice, -+ psPowerDevice->eCurrentPowerState); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, -+ "PVRSRVDevicePreClockSpeedChange : Device %u failed, error:0x%x", -+ ui32DeviceIndex, eError)); -+ } -+ } -+ -+ if (bIdleDevice && eError != PVRSRV_OK) -+ { -+ PVRSRVPowerUnlock(KERNEL_ID); -+ } -+ -+ return eError; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVDevicePostClockSpeedChange -+ -+ @Description -+ -+ Notification from system layer that a device clock speed change has just happened. -+ -+ @Input ui32DeviceIndex : device index -+ @Input bIdleDevice : whether the device had been idled -+ @Input pvInfo -+ -+ @Return IMG_VOID -+ -+******************************************************************************/ -+IMG_VOID PVRSRVDevicePostClockSpeedChange(IMG_UINT32 ui32DeviceIndex, -+ IMG_BOOL bIdleDevice, -+ IMG_VOID *pvInfo) -+{ -+ PVRSRV_ERROR eError; -+ SYS_DATA *psSysData; -+ PVRSRV_POWER_DEV *psPowerDevice; -+ -+ PVR_UNREFERENCED_PARAMETER(pvInfo); -+ -+ SysAcquireData(&psSysData); -+ -+ /*search the device and then do the post clock speed change*/ -+ psPowerDevice = (PVRSRV_POWER_DEV*) -+ List_PVRSRV_POWER_DEV_Any_va(psSysData->psPowerDeviceList, -+ &MatchPowerDeviceIndex_AnyVaCb, -+ ui32DeviceIndex); -+ -+ if (psPowerDevice && psPowerDevice->pfnPostClockSpeedChange) -+ { -+ eError = psPowerDevice->pfnPostClockSpeedChange(psPowerDevice->hDevCookie, -+ bIdleDevice, -+ psPowerDevice->eCurrentPowerState); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, -+ "PVRSRVDevicePostClockSpeedChange : Device %u failed, error:0x%x", -+ ui32DeviceIndex, eError)); -+ } -+ } -+ -+ -+ if (bIdleDevice) -+ { -+ /* This mutex was acquired in PVRSRVDevicePreClockSpeedChange. */ -+ PVRSRVPowerUnlock(KERNEL_ID); -+ } -+} -+ -+/****************************************************************************** -+ End of file (power.c) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/common/pvrsrv.c b/drivers/staging/ti-es8-sgx/services4/srvkm/common/pvrsrv.c -new file mode 100644 -index 0000000..94a81cb ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/common/pvrsrv.c -@@ -0,0 +1,1836 @@ -+/*************************************************************************/ /*! -+@Title core services functions -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Main APIs for core services functions -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#include "services_headers.h" -+#include "buffer_manager.h" -+#include "pvr_bridge_km.h" -+#include "handle.h" -+#include "perproc.h" -+#include "pdump_km.h" -+#include "deviceid.h" -+#include "ra.h" -+#if defined(TTRACE) -+#include "ttrace.h" -+#endif -+#include "perfkm.h" -+#include "devicemem.h" -+ -+#include "pvrversion.h" -+ -+#include "lists.h" -+ -+IMG_UINT32 g_ui32InitFlags; -+ -+/* mark which parts of Services were initialised */ -+#define INIT_DATA_ENABLE_PDUMPINIT 0x1U -+#define INIT_DATA_ENABLE_TTARCE 0x2U -+#define INIT_DATA_ENABLE_DEVMEM 0x4U -+ -+/*! -+****************************************************************************** -+ -+ @Function AllocateDeviceID -+ -+ @Description -+ -+ allocates a device id from the pool of valid ids -+ -+ @input psSysData : system data -+ -+ @input pui32DevID : device id to return -+ -+ @Return device id -+ -+******************************************************************************/ -+PVRSRV_ERROR AllocateDeviceID(SYS_DATA *psSysData, IMG_UINT32 *pui32DevID) -+{ -+ SYS_DEVICE_ID* psDeviceWalker; -+ SYS_DEVICE_ID* psDeviceEnd; -+ -+ psDeviceWalker = &psSysData->sDeviceID[0]; -+ psDeviceEnd = psDeviceWalker + psSysData->ui32NumDevices; -+ -+ /* find a free ID */ -+ while (psDeviceWalker < psDeviceEnd) -+ { -+ if (!psDeviceWalker->bInUse) -+ { -+ psDeviceWalker->bInUse = IMG_TRUE; -+ *pui32DevID = psDeviceWalker->uiID; -+ return PVRSRV_OK; -+ } -+ psDeviceWalker++; -+ } -+ -+ PVR_DPF((PVR_DBG_ERROR,"AllocateDeviceID: No free and valid device IDs available!")); -+ -+ /* Should never get here: sDeviceID[] may have been setup too small */ -+ PVR_ASSERT(psDeviceWalker < psDeviceEnd); -+ -+ return PVRSRV_ERROR_NO_FREE_DEVICEIDS_AVALIABLE; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function FreeDeviceID -+ -+ @Description -+ -+ frees a device id from the pool of valid ids -+ -+ @input psSysData : system data -+ -+ @input ui32DevID : device id to free -+ -+ @Return device id -+ -+******************************************************************************/ -+PVRSRV_ERROR FreeDeviceID(SYS_DATA *psSysData, IMG_UINT32 ui32DevID) -+{ -+ SYS_DEVICE_ID* psDeviceWalker; -+ SYS_DEVICE_ID* psDeviceEnd; -+ -+ psDeviceWalker = &psSysData->sDeviceID[0]; -+ psDeviceEnd = psDeviceWalker + psSysData->ui32NumDevices; -+ -+ /* find the ID to free */ -+ while (psDeviceWalker < psDeviceEnd) -+ { -+ /* if matching id and in use, free */ -+ if ( -+ (psDeviceWalker->uiID == ui32DevID) && -+ (psDeviceWalker->bInUse) -+ ) -+ { -+ psDeviceWalker->bInUse = IMG_FALSE; -+ return PVRSRV_OK; -+ } -+ psDeviceWalker++; -+ } -+ -+ PVR_DPF((PVR_DBG_ERROR,"FreeDeviceID: no matching dev ID that is in use!")); -+ -+ /* should never get here */ -+ PVR_ASSERT(psDeviceWalker < psDeviceEnd); -+ -+ return PVRSRV_ERROR_INVALID_DEVICEID; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function ReadHWReg -+ -+ @Description -+ -+ register access function -+ -+ @input pvLinRegBaseAddr : lin addr of register block base -+ -+ @input ui32Offset : byte offset from register base -+ -+ @Return register value -+ -+******************************************************************************/ -+#ifndef ReadHWReg -+IMG_EXPORT -+IMG_UINT32 ReadHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset) -+{ -+ return *(volatile IMG_UINT32*)((IMG_UINTPTR_T)pvLinRegBaseAddr+ui32Offset); -+} -+#endif -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function WriteHWReg -+ -+ @Description -+ -+ register access function -+ -+ @input pvLinRegBaseAddr : lin addr of register block base -+ -+ @input ui32Offset : byte offset from register base -+ -+ @input ui32Value : value to write to register -+ -+ @Return register value : original reg. value -+ -+******************************************************************************/ -+#ifndef WriteHWReg -+IMG_EXPORT -+IMG_VOID WriteHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value) -+{ -+ PVR_DPF((PVR_DBG_MESSAGE,"WriteHWReg Base:%p, Offset: %x, Value %x", -+ pvLinRegBaseAddr,ui32Offset,ui32Value)); -+ -+ *(IMG_UINT32*)((IMG_UINTPTR_T)pvLinRegBaseAddr+ui32Offset) = ui32Value; -+} -+#endif -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function WriteHWRegs -+ -+ @Description -+ -+ register access function -+ -+ @input pvLinRegBaseAddr : lin addr of register block base -+ -+ @input ui32Count : register count -+ -+ @input psHWRegs : address/value register list -+ -+ @Return none -+ -+******************************************************************************/ -+#ifndef WriteHWRegs -+IMG_EXPORT -+IMG_VOID WriteHWRegs(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Count, PVRSRV_HWREG *psHWRegs) -+{ -+ while (ui32Count) -+ { -+ WriteHWReg (pvLinRegBaseAddr, psHWRegs->ui32RegAddr, psHWRegs->ui32RegVal); -+ psHWRegs++; -+ ui32Count--; -+ } -+} -+#endif -+ -+/*! -+****************************************************************************** -+ @Function PVRSRVEnumerateDCKM_ForEachVaCb -+ -+ @Description -+ -+ Enumerates the device node (if is of the same class as given). -+ -+ @Input psDeviceNode - The device node to be enumerated -+ va - variable arguments list, with: -+ pui32DevCount - The device count pointer (to be increased) -+ ppui32DevID - The pointer to the device IDs pointer (to be updated and increased) -+******************************************************************************/ -+static IMG_VOID PVRSRVEnumerateDevicesKM_ForEachVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va) -+{ -+ IMG_UINT *pui32DevCount; -+ PVRSRV_DEVICE_IDENTIFIER **ppsDevIdList; -+ -+ pui32DevCount = va_arg(va, IMG_UINT*); -+ ppsDevIdList = va_arg(va, PVRSRV_DEVICE_IDENTIFIER**); -+ -+ if (psDeviceNode->sDevId.eDeviceType != PVRSRV_DEVICE_TYPE_EXT) -+ { -+ *(*ppsDevIdList) = psDeviceNode->sDevId; -+ (*ppsDevIdList)++; -+ (*pui32DevCount)++; -+ } -+} -+ -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVEnumerateDevicesKM -+ -+ @Description -+ This function will enumerate all the devices supported by the -+ PowerVR services within the target system. -+ The function returns a list of the device ID strcutres stored either in -+ the services or constructed in the user mode glue component in certain -+ environments. The number of devices in the list is also returned. -+ -+ In a binary layered component which does not support dynamic runtime selection, -+ the glue code should compile to return the supported devices statically, -+ e.g. multiple instances of the same device if multiple devices are supported, -+ or the target combination of MBX and display device. -+ -+ In the case of an environment (for instance) where one MBX1 may connect to two -+ display devices this code would enumerate all three devices and even -+ non-dynamic MBX1 selection code should retain the facility to parse the list -+ to find the index of the MBX device -+ -+ @output pui32NumDevices : On success, contains the number of devices present -+ in the system -+ -+ @output psDevIdList : Pointer to called supplied buffer to receive the -+ list of PVRSRV_DEVICE_IDENTIFIER -+ -+ @return PVRSRV_ERROR : PVRSRV_NO_ERROR -+ -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumerateDevicesKM(IMG_UINT32 *pui32NumDevices, -+ PVRSRV_DEVICE_IDENTIFIER *psDevIdList) -+{ -+ SYS_DATA *psSysData; -+/* PVRSRV_DEVICE_NODE *psDeviceNode; */ -+ IMG_UINT32 i; -+ -+ if (!pui32NumDevices || !psDevIdList) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVEnumerateDevicesKM: Invalid params")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ SysAcquireData(&psSysData); -+ -+ /* -+ setup input buffer to be `empty' -+ */ -+ for (i=0; i<PVRSRV_MAX_DEVICES; i++) -+ { -+ psDevIdList[i].eDeviceType = PVRSRV_DEVICE_TYPE_UNKNOWN; -+ } -+ -+ /* and zero device count */ -+ *pui32NumDevices = 0; -+ -+ /* -+ Search through the device list for services managed devices -+ return id info for each device and the number of devices -+ available -+ */ -+ List_PVRSRV_DEVICE_NODE_ForEach_va(psSysData->psDeviceNodeList, -+ &PVRSRVEnumerateDevicesKM_ForEachVaCb, -+ pui32NumDevices, -+ &psDevIdList); -+ -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVInit -+ -+ @Description Initialise services -+ -+ @Input psSysData : sysdata structure -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+PVRSRV_ERROR IMG_CALLCONV PVRSRVInit(PSYS_DATA psSysData) -+{ -+ PVRSRV_ERROR eError; -+ -+ /* Initialise Resource Manager */ -+ eError = ResManInit(); -+ if (eError != PVRSRV_OK) -+ { -+ goto Error; -+ } -+ -+ eError = PVRSRVPerProcessDataInit(); -+ if(eError != PVRSRV_OK) -+ { -+ goto Error; -+ } -+ -+ /* Initialise handles */ -+ eError = PVRSRVHandleInit(); -+ if(eError != PVRSRV_OK) -+ { -+ goto Error; -+ } -+ -+ /* Initialise Power Manager Lock */ -+ eError = OSCreateResource(&psSysData->sPowerStateChangeResource); -+ if (eError != PVRSRV_OK) -+ { -+ goto Error; -+ } -+ -+ /* Initialise system power state */ -+ psSysData->eCurrentPowerState = PVRSRV_SYS_POWER_STATE_D0; -+ psSysData->eFailedPowerState = PVRSRV_SYS_POWER_STATE_Unspecified; -+ -+ /* Create an event object */ -+ if(OSAllocMem( PVRSRV_PAGEABLE_SELECT, -+ sizeof(PVRSRV_EVENTOBJECT) , -+ (IMG_VOID **)&psSysData->psGlobalEventObject, 0, -+ "Event Object") != PVRSRV_OK) -+ { -+ -+ goto Error; -+ } -+ -+ if(OSEventObjectCreateKM("PVRSRV_GLOBAL_EVENTOBJECT", psSysData->psGlobalEventObject) != PVRSRV_OK) -+ { -+ goto Error; -+ } -+ -+ /* Store OS high res timer fallbacks, the system is free to overide these */ -+ psSysData->pfnHighResTimerCreate = OSFuncHighResTimerCreate; -+ psSysData->pfnHighResTimerGetus = OSFuncHighResTimerGetus; -+ psSysData->pfnHighResTimerDestroy = OSFuncHighResTimerDestroy; -+ -+#if defined(TTRACE) -+ eError = PVRSRVTimeTraceInit(); -+ if (eError != PVRSRV_OK) -+ goto Error; -+ g_ui32InitFlags |= INIT_DATA_ENABLE_TTARCE; -+#endif -+ -+ /* Initialise pdump */ -+ PDUMPINIT(); -+ g_ui32InitFlags |= INIT_DATA_ENABLE_PDUMPINIT; -+ -+#if defined(SUPPORT_ION) -+ eError = PVRSRVInitDeviceMem(); -+ if (eError != PVRSRV_OK) -+ goto Error; -+ g_ui32InitFlags |= INIT_DATA_ENABLE_DEVMEM; -+#endif -+ -+ PERFINIT(); -+ return eError; -+ -+Error: -+ PVRSRVDeInit(psSysData); -+ return eError; -+} -+ -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVDeInit -+ -+ @Description De-Initialise services -+ -+ @Input psSysData : sysdata structure -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+IMG_VOID IMG_CALLCONV PVRSRVDeInit(PSYS_DATA psSysData) -+{ -+ PVRSRV_ERROR eError; -+ -+ PVR_UNREFERENCED_PARAMETER(psSysData); -+ -+ if (psSysData == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeInit: PVRSRVHandleDeInit failed - invalid param")); -+ return; -+ } -+ -+ PERFDEINIT(); -+ -+#if defined(SUPPORT_ION) -+ if ((g_ui32InitFlags & INIT_DATA_ENABLE_DEVMEM) > 0) -+ { -+ PVRSRVDeInitDeviceMem(); -+ } -+#endif -+ -+#if defined(TTRACE) -+ /* deinitialise ttrace */ -+ if ((g_ui32InitFlags & INIT_DATA_ENABLE_TTARCE) > 0) -+ { -+ PVRSRVTimeTraceDeinit(); -+ } -+#endif -+ /* deinitialise pdump */ -+ if( (g_ui32InitFlags & INIT_DATA_ENABLE_PDUMPINIT) > 0) -+ { -+ PDUMPDEINIT(); -+ } -+ -+ /* destroy event object */ -+ if(psSysData->psGlobalEventObject) -+ { -+ OSEventObjectDestroyKM(psSysData->psGlobalEventObject); -+ OSFreeMem( PVRSRV_PAGEABLE_SELECT, -+ sizeof(PVRSRV_EVENTOBJECT), -+ psSysData->psGlobalEventObject, -+ 0); -+ psSysData->psGlobalEventObject = IMG_NULL; -+ } -+ -+ eError = PVRSRVHandleDeInit(); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeInit: PVRSRVHandleDeInit failed")); -+ } -+ -+ eError = PVRSRVPerProcessDataDeInit(); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeInit: PVRSRVPerProcessDataDeInit failed")); -+ } -+ -+ ResManDeInit(); -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVRegisterDevice -+ -+ @Description -+ -+ registers a device with the system -+ -+ @Input psSysData : sysdata structure -+ -+ @Input pfnRegisterDevice : device registration function -+ -+ @Input ui32SOCInterruptBit : SoC interrupt bit for this device -+ -+ @Output pui32DeviceIndex : unique device key (for case of multiple identical devices) -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+PVRSRV_ERROR IMG_CALLCONV PVRSRVRegisterDevice(PSYS_DATA psSysData, -+ PVRSRV_ERROR (*pfnRegisterDevice)(PVRSRV_DEVICE_NODE*), -+ IMG_UINT32 ui32SOCInterruptBit, -+ IMG_UINT32 *pui32DeviceIndex) -+{ -+ PVRSRV_ERROR eError; -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+ -+ /* Allocate device node */ -+ if(OSAllocMem( PVRSRV_OS_NON_PAGEABLE_HEAP, -+ sizeof(PVRSRV_DEVICE_NODE), -+ (IMG_VOID **)&psDeviceNode, IMG_NULL, -+ "Device Node") != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDevice : Failed to alloc memory for psDeviceNode")); -+ return (PVRSRV_ERROR_OUT_OF_MEMORY); -+ } -+ OSMemSet (psDeviceNode, 0, sizeof(PVRSRV_DEVICE_NODE)); -+ -+ eError = pfnRegisterDevice(psDeviceNode); -+ if (eError != PVRSRV_OK) -+ { -+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, -+ sizeof(PVRSRV_DEVICE_NODE), psDeviceNode, IMG_NULL); -+ /*not nulling pointer, out of scope*/ -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterDevice : Failed to register device")); -+ return (PVRSRV_ERROR_DEVICE_REGISTER_FAILED); -+ } -+ -+ /* -+ make the refcount 1 and test on this to initialise device -+ at acquiredevinfo. On release if refcount is 1, deinitialise -+ and when refcount is 0 (sysdata de-alloc) deallocate the device -+ structures -+ */ -+ psDeviceNode->ui32RefCount = 1; -+ psDeviceNode->psSysData = psSysData; -+ psDeviceNode->ui32SOCInterruptBit = ui32SOCInterruptBit; -+ -+ /* all devices need a unique identifier */ -+ AllocateDeviceID(psSysData, &psDeviceNode->sDevId.ui32DeviceIndex); -+ -+ /* and finally insert the device into the dev-list */ -+ List_PVRSRV_DEVICE_NODE_Insert(&psSysData->psDeviceNodeList, psDeviceNode); -+ -+ /* and copy back index */ -+ *pui32DeviceIndex = psDeviceNode->sDevId.ui32DeviceIndex; -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVInitialiseDevice -+ -+ @Description -+ -+ initialises device by index -+ -+ @Input ui32DevIndex : Index to the required device -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+PVRSRV_ERROR IMG_CALLCONV PVRSRVInitialiseDevice (IMG_UINT32 ui32DevIndex) -+{ -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+ SYS_DATA *psSysData; -+ PVRSRV_ERROR eError; -+ -+ PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVInitialiseDevice")); -+ -+ SysAcquireData(&psSysData); -+ -+ /* Find device in the list */ -+ psDeviceNode = (PVRSRV_DEVICE_NODE*) -+ List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList, -+ &MatchDeviceKM_AnyVaCb, -+ ui32DevIndex, -+ IMG_TRUE); -+ if(!psDeviceNode) -+ { -+ /* Devinfo not in the list */ -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVInitialiseDevice: requested device is not present")); -+ return PVRSRV_ERROR_INIT_FAILURE; -+ } -+/* -+FoundDevice: -+*/ -+ -+ PVR_ASSERT (psDeviceNode->ui32RefCount > 0); -+ -+ /* -+ Create the device's resource manager context. -+ */ -+ eError = PVRSRVResManConnect(IMG_NULL, &psDeviceNode->hResManContext); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVInitialiseDevice: Failed PVRSRVResManConnect call")); -+ return eError; -+ } -+ -+ /* Initialise the device */ -+ if(psDeviceNode->pfnInitDevice != IMG_NULL) -+ { -+ eError = psDeviceNode->pfnInitDevice(psDeviceNode); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVInitialiseDevice: Failed InitDevice call")); -+ return eError; -+ } -+ } -+ -+ return PVRSRV_OK; -+} -+ -+ -+static PVRSRV_ERROR PVRSRVFinaliseSystem_SetPowerState_AnyCb(PVRSRV_DEVICE_NODE *psDeviceNode) -+{ -+ PVRSRV_ERROR eError; -+ -+ eError = PVRSRVPowerLock(KERNEL_ID, IMG_FALSE); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: Failed PVRSRVPowerLock call (device index: %d)", psDeviceNode->sDevId.ui32DeviceIndex)); -+ return eError; -+ } -+ -+ eError = PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex, -+ PVRSRV_DEV_POWER_STATE_DEFAULT); -+ PVRSRVPowerUnlock(KERNEL_ID); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: Failed PVRSRVSetDevicePowerStateKM call (device index: %d)", psDeviceNode->sDevId.ui32DeviceIndex)); -+ } -+ return eError; -+} -+ -+/*wraps the PVRSRVDevInitCompatCheck call and prints a debugging message if failed*/ -+static PVRSRV_ERROR PVRSRVFinaliseSystem_CompatCheck_AnyCb(PVRSRV_DEVICE_NODE *psDeviceNode) -+{ -+ PVRSRV_ERROR eError; -+ eError = PVRSRVDevInitCompatCheck(psDeviceNode); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: Failed PVRSRVDevInitCompatCheck call (device index: %d)", psDeviceNode->sDevId.ui32DeviceIndex)); -+ } -+ return eError; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVFinaliseSystem -+ -+ @Description -+ -+ Final part of system initialisation. -+ -+ @Input ui32DevIndex : Index to the required device -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+PVRSRV_ERROR IMG_CALLCONV PVRSRVFinaliseSystem(IMG_BOOL bInitSuccessful) -+{ -+/* PVRSRV_DEVICE_NODE *psDeviceNode;*/ -+ SYS_DATA *psSysData; -+ PVRSRV_ERROR eError; -+ -+ PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVFinaliseSystem")); -+ -+ SysAcquireData(&psSysData); -+ -+ if (bInitSuccessful) -+ { -+ eError = SysFinalise(); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVFinaliseSystem: SysFinalise failed (%d)", eError)); -+ return eError; -+ } -+ -+ /* Place all devices into their default power state. */ -+ eError = List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any(psSysData->psDeviceNodeList, -+ &PVRSRVFinaliseSystem_SetPowerState_AnyCb); -+ if (eError != PVRSRV_OK) -+ { -+ return eError; -+ } -+ -+ /* Verify microkernel compatibility for devices */ -+ eError = List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any(psSysData->psDeviceNodeList, -+ &PVRSRVFinaliseSystem_CompatCheck_AnyCb); -+ if (eError != PVRSRV_OK) -+ { -+ return eError; -+ } -+ } -+ -+ /* Some platforms call this too early in the boot phase. */ -+ PDUMPENDINITPHASE(); -+ -+ return PVRSRV_OK; -+} -+ -+ -+PVRSRV_ERROR PVRSRVDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode) -+{ -+ /* Only check devices which specify a compatibility check callback */ -+ if (psDeviceNode->pfnInitDeviceCompatCheck) -+ return psDeviceNode->pfnInitDeviceCompatCheck(psDeviceNode); -+ else -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVAcquireDeviceDataKM -+ -+ @Description -+ -+ Matchs a device given a device type and a device index. -+ -+ @input psDeviceNode :The device node to be matched. -+ -+ @Input va : Variable argument list with: -+ eDeviceType : Required device type. If type is unknown use ui32DevIndex -+ to locate device data -+ -+ ui32DevIndex : Index to the required device obtained from the -+ PVRSRVEnumerateDevice function -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+static IMG_VOID * PVRSRVAcquireDeviceDataKM_Match_AnyVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va) -+{ -+ PVRSRV_DEVICE_TYPE eDeviceType; -+ IMG_UINT32 ui32DevIndex; -+ -+ eDeviceType = va_arg(va, PVRSRV_DEVICE_TYPE); -+ ui32DevIndex = va_arg(va, IMG_UINT32); -+ -+ if ((eDeviceType != PVRSRV_DEVICE_TYPE_UNKNOWN && -+ psDeviceNode->sDevId.eDeviceType == eDeviceType) || -+ (eDeviceType == PVRSRV_DEVICE_TYPE_UNKNOWN && -+ psDeviceNode->sDevId.ui32DeviceIndex == ui32DevIndex)) -+ { -+ return psDeviceNode; -+ } -+ else -+ { -+ return IMG_NULL; -+ } -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVAcquireDeviceDataKM -+ -+ @Description -+ -+ Returns device information -+ -+ @Input ui32DevIndex : Index to the required device obtained from the -+ PVRSRVEnumerateDevice function -+ -+ @Input eDeviceType : Required device type. If type is unknown use ui32DevIndex -+ to locate device data -+ -+ @Output *phDevCookie : Dev Cookie -+ -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVAcquireDeviceDataKM (IMG_UINT32 ui32DevIndex, -+ PVRSRV_DEVICE_TYPE eDeviceType, -+ IMG_HANDLE *phDevCookie) -+{ -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+ SYS_DATA *psSysData; -+ -+ PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVAcquireDeviceDataKM")); -+ -+ SysAcquireData(&psSysData); -+ -+ /* Find device in the list */ -+ psDeviceNode = List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList, -+ &PVRSRVAcquireDeviceDataKM_Match_AnyVaCb, -+ eDeviceType, -+ ui32DevIndex); -+ -+ -+ if (!psDeviceNode) -+ { -+ /* device can't be found in the list so it isn't in the system */ -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVAcquireDeviceDataKM: requested device is not present")); -+ return PVRSRV_ERROR_INIT_FAILURE; -+ } -+ -+/*FoundDevice:*/ -+ -+ PVR_ASSERT (psDeviceNode->ui32RefCount > 0); -+ -+ /* return the dev cookie? */ -+ if (phDevCookie) -+ { -+ *phDevCookie = (IMG_HANDLE)psDeviceNode; -+ } -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVDeinitialiseDevice -+ -+ @Description -+ -+ This De-inits device -+ -+ @Input ui32DevIndex : Index to the required device -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+PVRSRV_ERROR IMG_CALLCONV PVRSRVDeinitialiseDevice(IMG_UINT32 ui32DevIndex) -+{ -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+ SYS_DATA *psSysData; -+ PVRSRV_ERROR eError; -+ -+ SysAcquireData(&psSysData); -+ -+ psDeviceNode = (PVRSRV_DEVICE_NODE*) -+ List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList, -+ &MatchDeviceKM_AnyVaCb, -+ ui32DevIndex, -+ IMG_TRUE); -+ -+ if (!psDeviceNode) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: requested device %d is not present", ui32DevIndex)); -+ return PVRSRV_ERROR_DEVICEID_NOT_FOUND; -+ } -+ -+ eError = PVRSRVPowerLock(KERNEL_ID, IMG_FALSE); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed PVRSRVPowerLock call")); -+ return eError; -+ } -+ -+ /* -+ Power down the device if necessary. -+ */ -+ eError = PVRSRVSetDevicePowerStateKM(ui32DevIndex, -+ PVRSRV_DEV_POWER_STATE_OFF); -+ PVRSRVPowerUnlock(KERNEL_ID); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed PVRSRVSetDevicePowerStateKM call")); -+ return eError; -+ } -+ -+ /* -+ Free the dissociated device memory. -+ */ -+ eError = ResManFreeResByCriteria(psDeviceNode->hResManContext, -+ RESMAN_CRITERIA_RESTYPE, -+ RESMAN_TYPE_DEVICEMEM_ALLOCATION, -+ IMG_NULL, 0); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed ResManFreeResByCriteria call")); -+ return eError; -+ } -+ -+ /* -+ De-init the device. -+ */ -+ if(psDeviceNode->pfnDeInitDevice != IMG_NULL) -+ { -+ eError = psDeviceNode->pfnDeInitDevice(psDeviceNode); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed DeInitDevice call")); -+ return eError; -+ } -+ } -+ -+ /* -+ Close the device's resource manager context. -+ */ -+ PVRSRVResManDisconnect(psDeviceNode->hResManContext, IMG_TRUE); -+ psDeviceNode->hResManContext = IMG_NULL; -+ -+ /* remove node from list */ -+ List_PVRSRV_DEVICE_NODE_Remove(psDeviceNode); -+ -+ /* deallocate id and memory */ -+ (IMG_VOID)FreeDeviceID(psSysData, ui32DevIndex); -+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, -+ sizeof(PVRSRV_DEVICE_NODE), psDeviceNode, IMG_NULL); -+ /*not nulling pointer, out of scope*/ -+ -+ return (PVRSRV_OK); -+} -+ -+ -+IMG_EXPORT -+PVRSRV_ERROR IMG_CALLCONV PollForValueKM (volatile IMG_UINT32* pui32LinMemAddr, -+ IMG_UINT32 ui32Value, -+ IMG_UINT32 ui32Mask, -+ IMG_UINT32 ui32Timeoutus, -+ IMG_UINT32 ui32PollPeriodus, -+ IMG_BOOL bAllowPreemption) -+{ -+#if defined (EMULATOR) -+ { -+ PVR_UNREFERENCED_PARAMETER(bAllowPreemption); -+ #if !defined(__linux__) -+ PVR_UNREFERENCED_PARAMETER(ui32PollPeriodus); -+ #endif -+ -+ /* For the Emulator we want the system to stop when a lock-up is detected so the state can be analysed. -+ * Also the Emulator is much slower than real silicon so timeouts are not valid. -+ */ -+ do -+ { -+ if((*pui32LinMemAddr & ui32Mask) == ui32Value) -+ { -+ return PVRSRV_OK; -+ } -+ -+ #if defined(__linux__) -+ OSWaitus(ui32PollPeriodus); -+ #else -+ OSReleaseThreadQuanta(); -+ #endif -+ -+ } while (ui32Timeoutus); /* Endless loop only for the Emulator */ -+ } -+#else -+ { -+ IMG_UINT32 ui32ActualValue = 0xFFFFFFFFU; /* Initialiser only required to prevent incorrect warning */ -+ -+ if (bAllowPreemption) -+ { -+ PVR_ASSERT(ui32PollPeriodus >= 1000); -+ } -+ -+ /* PRQA S 3415,4109 1 */ /* macro format critical - leave alone */ -+ LOOP_UNTIL_TIMEOUT(ui32Timeoutus) -+ { -+ ui32ActualValue = (*pui32LinMemAddr & ui32Mask); -+ if(ui32ActualValue == ui32Value) -+ { -+ return PVRSRV_OK; -+ } -+ -+ if (bAllowPreemption) -+ { -+ OSSleepms(ui32PollPeriodus / 1000); -+ } -+ else -+ { -+ OSWaitus(ui32PollPeriodus); -+ } -+ } END_LOOP_UNTIL_TIMEOUT(); -+ -+ PVR_DPF((PVR_DBG_ERROR,"PollForValueKM: Timeout. Expected 0x%x but found 0x%x (mask 0x%x).", -+ ui32Value, ui32ActualValue, ui32Mask)); -+ } -+#endif /* #if defined (EMULATOR) */ -+ -+ return PVRSRV_ERROR_TIMEOUT; -+} -+ -+ -+/*Level 3 of the loop nesting*/ -+static IMG_VOID PVRSRVGetMiscInfoKM_RA_GetStats_ForEachVaCb(BM_HEAP *psBMHeap, va_list va) -+{ -+ IMG_CHAR **ppszStr; -+ IMG_UINT32 *pui32StrLen; -+ IMG_UINT32 ui32Mode; -+ PVRSRV_ERROR (*pfnGetStats)(RA_ARENA *, IMG_CHAR **, IMG_UINT32 *); -+ -+ ppszStr = va_arg(va, IMG_CHAR**); -+ pui32StrLen = va_arg(va, IMG_UINT32*); -+ ui32Mode = va_arg(va, IMG_UINT32); -+ -+ /* Would be better to pass fn pointer in the variable args list -+ * but MS C compiler complains with error C2066: In ANSI C, -+ * it is not legal to cast between a function pointer and a data pointer. -+ */ -+ switch(ui32Mode) -+ { -+ case PVRSRV_MISC_INFO_MEMSTATS_PRESENT: -+ pfnGetStats = &RA_GetStats; -+ break; -+ case PVRSRV_MISC_INFO_FREEMEM_PRESENT: -+ pfnGetStats = &RA_GetStatsFreeMem; -+ break; -+ default: -+ return; -+ } -+ -+ if(psBMHeap->pImportArena) -+ { -+ pfnGetStats(psBMHeap->pImportArena, -+ ppszStr, -+ pui32StrLen); -+ } -+ -+ if(psBMHeap->pVMArena) -+ { -+ pfnGetStats(psBMHeap->pVMArena, -+ ppszStr, -+ pui32StrLen); -+ } -+} -+ -+/*Level 2 of the loop nesting*/ -+static PVRSRV_ERROR PVRSRVGetMiscInfoKM_BMContext_AnyVaCb(BM_CONTEXT *psBMContext, va_list va) -+{ -+ -+ IMG_UINT32 *pui32StrLen; -+ IMG_INT32 *pi32Count; -+ IMG_CHAR **ppszStr; -+ IMG_UINT32 ui32Mode; -+ -+ pui32StrLen = va_arg(va, IMG_UINT32*); -+ pi32Count = va_arg(va, IMG_INT32*); -+ ppszStr = va_arg(va, IMG_CHAR**); -+ ui32Mode = va_arg(va, IMG_UINT32); -+ -+ CHECK_SPACE(*pui32StrLen); -+ *pi32Count = OSSNPrintf(*ppszStr, 100, "\nApplication Context (hDevMemContext) %p:\n", -+ (IMG_HANDLE)psBMContext); -+ UPDATE_SPACE(*ppszStr, *pi32Count, *pui32StrLen); -+ -+ List_BM_HEAP_ForEach_va(psBMContext->psBMHeap, -+ &PVRSRVGetMiscInfoKM_RA_GetStats_ForEachVaCb, -+ ppszStr, -+ pui32StrLen, -+ ui32Mode); -+ return PVRSRV_OK; -+} -+ -+ -+/*level 1 of the loop nesting*/ -+static PVRSRV_ERROR PVRSRVGetMiscInfoKM_Device_AnyVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va) -+{ -+ IMG_UINT32 *pui32StrLen; -+ IMG_INT32 *pi32Count; -+ IMG_CHAR **ppszStr; -+ IMG_UINT32 ui32Mode; -+ -+ pui32StrLen = va_arg(va, IMG_UINT32*); -+ pi32Count = va_arg(va, IMG_INT32*); -+ ppszStr = va_arg(va, IMG_CHAR**); -+ ui32Mode = va_arg(va, IMG_UINT32); -+ -+ CHECK_SPACE(*pui32StrLen); -+ *pi32Count = OSSNPrintf(*ppszStr, 100, "\n\nDevice Type %d:\n", psDeviceNode->sDevId.eDeviceType); -+ UPDATE_SPACE(*ppszStr, *pi32Count, *pui32StrLen); -+ -+ /* kernel context: */ -+ if(psDeviceNode->sDevMemoryInfo.pBMKernelContext) -+ { -+ CHECK_SPACE(*pui32StrLen); -+ *pi32Count = OSSNPrintf(*ppszStr, 100, "\nKernel Context:\n"); -+ UPDATE_SPACE(*ppszStr, *pi32Count, *pui32StrLen); -+ -+ List_BM_HEAP_ForEach_va(psDeviceNode->sDevMemoryInfo.pBMKernelContext->psBMHeap, -+ &PVRSRVGetMiscInfoKM_RA_GetStats_ForEachVaCb, -+ ppszStr, -+ pui32StrLen, -+ ui32Mode); -+ } -+ -+ /* double loop app contexts:heaps */ -+ return List_BM_CONTEXT_PVRSRV_ERROR_Any_va(psDeviceNode->sDevMemoryInfo.pBMContext, -+ &PVRSRVGetMiscInfoKM_BMContext_AnyVaCb, -+ pui32StrLen, -+ pi32Count, -+ ppszStr, -+ ui32Mode); -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVGetMiscInfoKM -+ -+ @Description -+ Retrieves misc. info. -+ -+ @Output PVRSRV_MISC_INFO -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetMiscInfoKM(PVRSRV_MISC_INFO *psMiscInfo) -+{ -+ SYS_DATA *psSysData; -+ -+ if(!psMiscInfo) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetMiscInfoKM: invalid parameters")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psMiscInfo->ui32StatePresent = 0; -+ -+ /* do a basic check for uninitialised request flag */ -+ if(psMiscInfo->ui32StateRequest & ~(PVRSRV_MISC_INFO_TIMER_PRESENT -+ |PVRSRV_MISC_INFO_CLOCKGATE_PRESENT -+ |PVRSRV_MISC_INFO_MEMSTATS_PRESENT -+ |PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT -+ |PVRSRV_MISC_INFO_DDKVERSION_PRESENT -+ |PVRSRV_MISC_INFO_CPUCACHEOP_PRESENT -+ |PVRSRV_MISC_INFO_RESET_PRESENT -+ |PVRSRV_MISC_INFO_FREEMEM_PRESENT -+ |PVRSRV_MISC_INFO_GET_REF_COUNT_PRESENT -+ |PVRSRV_MISC_INFO_GET_PAGE_SIZE_PRESENT -+ |PVRSRV_MISC_INFO_FORCE_SWAP_TO_SYSTEM_PRESENT)) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetMiscInfoKM: invalid state request flags")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ SysAcquireData(&psSysData); -+ -+ /* return SOC Timer registers */ -+ if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_TIMER_PRESENT) != 0UL) && -+ (psSysData->pvSOCTimerRegisterKM != IMG_NULL)) -+ { -+ psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_TIMER_PRESENT; -+ psMiscInfo->pvSOCTimerRegisterKM = psSysData->pvSOCTimerRegisterKM; -+ psMiscInfo->hSOCTimerRegisterOSMemHandle = psSysData->hSOCTimerRegisterOSMemHandle; -+ } -+ else -+ { -+ psMiscInfo->pvSOCTimerRegisterKM = IMG_NULL; -+ psMiscInfo->hSOCTimerRegisterOSMemHandle = IMG_NULL; -+ } -+ -+ /* return SOC Clock Gating registers */ -+ if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_CLOCKGATE_PRESENT) != 0UL) && -+ (psSysData->pvSOCClockGateRegsBase != IMG_NULL)) -+ { -+ psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_CLOCKGATE_PRESENT; -+ psMiscInfo->pvSOCClockGateRegs = psSysData->pvSOCClockGateRegsBase; -+ psMiscInfo->ui32SOCClockGateRegsSize = psSysData->ui32SOCClockGateRegsSize; -+ } -+ -+ /* memory stats */ -+ if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_MEMSTATS_PRESENT) != 0UL) && -+ (psMiscInfo->pszMemoryStr != IMG_NULL)) -+ { -+ RA_ARENA **ppArena; -+/* BM_HEAP *psBMHeap; -+ BM_CONTEXT *psBMContext; -+ PVRSRV_DEVICE_NODE *psDeviceNode;*/ -+ IMG_CHAR *pszStr; -+ IMG_UINT32 ui32StrLen; -+ IMG_INT32 i32Count; -+ -+ pszStr = psMiscInfo->pszMemoryStr; -+ ui32StrLen = psMiscInfo->ui32MemoryStrLen; -+ -+ psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_MEMSTATS_PRESENT; -+ -+ /* Local backing stores */ -+ ppArena = &psSysData->apsLocalDevMemArena[0]; -+ while(*ppArena) -+ { -+ CHECK_SPACE(ui32StrLen); -+ i32Count = OSSNPrintf(pszStr, 100, "\nLocal Backing Store:\n"); -+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen); -+ -+ RA_GetStats(*ppArena, -+ &pszStr, -+ &ui32StrLen); -+ /* advance through the array */ -+ ppArena++; -+ } -+ -+ /* per device */ -+/* psDeviceNode = psSysData->psDeviceNodeList;*/ -+ -+ /*triple loop; devices:contexts:heaps*/ -+ List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any_va(psSysData->psDeviceNodeList, -+ &PVRSRVGetMiscInfoKM_Device_AnyVaCb, -+ &ui32StrLen, -+ &i32Count, -+ &pszStr, -+ PVRSRV_MISC_INFO_MEMSTATS_PRESENT); -+ -+ /* attach a new line and string terminate */ -+ i32Count = OSSNPrintf(pszStr, 100, "\n"); -+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen); -+ } -+ -+ /* Lean version of mem stats: only show free mem on each RA */ -+ if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_FREEMEM_PRESENT) != 0) -+ && psMiscInfo->pszMemoryStr) -+ { -+ IMG_CHAR *pszStr; -+ IMG_UINT32 ui32StrLen; -+ IMG_INT32 i32Count; -+ -+ pszStr = psMiscInfo->pszMemoryStr; -+ ui32StrLen = psMiscInfo->ui32MemoryStrLen; -+ -+ psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_FREEMEM_PRESENT; -+ -+ /* triple loop over devices:contexts:heaps */ -+ List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any_va(psSysData->psDeviceNodeList, -+ &PVRSRVGetMiscInfoKM_Device_AnyVaCb, -+ &ui32StrLen, -+ &i32Count, -+ &pszStr, -+ PVRSRV_MISC_INFO_FREEMEM_PRESENT); -+ -+ i32Count = OSSNPrintf(pszStr, 100, "\n"); -+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen); -+ } -+ -+ if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT) != 0UL) && -+ (psSysData->psGlobalEventObject != IMG_NULL)) -+ { -+ psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT; -+ psMiscInfo->sGlobalEventObject = *psSysData->psGlobalEventObject; -+ } -+ -+ /* DDK version and memstats not supported in same call to GetMiscInfo */ -+ -+ if (((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_DDKVERSION_PRESENT) != 0UL) -+ && ((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_MEMSTATS_PRESENT) == 0UL) -+ && (psMiscInfo->pszMemoryStr != IMG_NULL)) -+ { -+ IMG_CHAR *pszStr; -+ IMG_UINT32 ui32StrLen; -+ IMG_UINT32 ui32LenStrPerNum = 12; /* string length per UI32: 10 digits + '.' + '\0' = 12 bytes */ -+ IMG_INT32 i32Count; -+ IMG_INT i; -+ psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_DDKVERSION_PRESENT; -+ -+ /* construct DDK string */ -+ psMiscInfo->aui32DDKVersion[0] = PVRVERSION_MAJ; -+ psMiscInfo->aui32DDKVersion[1] = PVRVERSION_MIN; -+ psMiscInfo->aui32DDKVersion[2] = PVRVERSION_BUILD_HI; -+ psMiscInfo->aui32DDKVersion[3] = PVRVERSION_BUILD_LO; -+ -+ pszStr = psMiscInfo->pszMemoryStr; -+ ui32StrLen = psMiscInfo->ui32MemoryStrLen; -+ -+ for (i=0; i<4; i++) -+ { -+ if (ui32StrLen < ui32LenStrPerNum) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ i32Count = OSSNPrintf(pszStr, ui32LenStrPerNum, "%u", psMiscInfo->aui32DDKVersion[i]); -+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen); -+ if (i != 3) -+ { -+ i32Count = OSSNPrintf(pszStr, 2, "."); -+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen); -+ } -+ } -+ } -+ -+ if((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_CPUCACHEOP_PRESENT) != 0UL) -+ { -+ psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_CPUCACHEOP_PRESENT; -+ -+ if(psMiscInfo->sCacheOpCtl.bDeferOp) -+ { -+ /* For now, assume deferred ops are "full" cache ops, -+ * and we don't need (or expect) a meminfo. -+ */ -+ psSysData->ePendingCacheOpType = psMiscInfo->sCacheOpCtl.eCacheOpType; -+ } -+ else -+ { -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; -+ PVRSRV_PER_PROCESS_DATA *psPerProc; -+ -+ if(!psMiscInfo->sCacheOpCtl.u.psKernelMemInfo) -+ { -+ PVR_DPF((PVR_DBG_WARNING, "PVRSRVGetMiscInfoKM: " -+ "Ignoring non-deferred cache op with no meminfo")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ if(psSysData->ePendingCacheOpType != PVRSRV_MISC_INFO_CPUCACHEOP_NONE) -+ { -+ PVR_DPF((PVR_DBG_WARNING, "PVRSRVGetMiscInfoKM: " -+ "Deferred cache op is pending. It is unlikely you want " -+ "to combine deferred cache ops with immediate ones")); -+ } -+ -+ psPerProc = PVRSRVFindPerProcessData(); -+ -+ if(PVRSRVLookupHandle(psPerProc->psHandleBase, -+ (IMG_PVOID *)&psKernelMemInfo, -+ psMiscInfo->sCacheOpCtl.u.psKernelMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO) != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetMiscInfoKM: " -+ "Can't find kernel meminfo")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ if(psMiscInfo->sCacheOpCtl.eCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_FLUSH) -+ { -+ if(!OSFlushCPUCacheRangeKM(psKernelMemInfo->sMemBlk.hOSMemHandle, -+ 0, -+ psMiscInfo->sCacheOpCtl.pvBaseVAddr, -+ psMiscInfo->sCacheOpCtl.ui32Length)) -+ { -+ return PVRSRV_ERROR_CACHEOP_FAILED; -+ } -+ } -+ else if(psMiscInfo->sCacheOpCtl.eCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_CLEAN) -+ { -+ if(psMiscInfo->sCacheOpCtl.ui32Length!=0) -+ { -+ if(!OSCleanCPUCacheRangeKM(psKernelMemInfo->sMemBlk.hOSMemHandle, -+ 0, -+ psMiscInfo->sCacheOpCtl.pvBaseVAddr, -+ psMiscInfo->sCacheOpCtl.ui32Length)) -+ { -+ return PVRSRV_ERROR_CACHEOP_FAILED; -+ } -+ } -+ } -+ } -+ } -+ -+ if((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_GET_REF_COUNT_PRESENT) != 0UL) -+ { -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; -+ PVRSRV_PER_PROCESS_DATA *psPerProc; -+ -+ psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_GET_REF_COUNT_PRESENT; -+ -+ psPerProc = PVRSRVFindPerProcessData(); -+ -+ if(PVRSRVLookupHandle(psPerProc->psHandleBase, -+ (IMG_PVOID *)&psKernelMemInfo, -+ psMiscInfo->sGetRefCountCtl.u.psKernelMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO) != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetMiscInfoKM: " -+ "Can't find kernel meminfo")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psMiscInfo->sGetRefCountCtl.ui32RefCount = psKernelMemInfo->ui32RefCount; -+ } -+ -+ if ((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_GET_PAGE_SIZE_PRESENT) != 0UL) -+ { -+ psMiscInfo->ui32PageSize = HOST_PAGESIZE(); -+ psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_GET_PAGE_SIZE_PRESENT; -+ } -+ -+#if defined(PVRSRV_RESET_ON_HWTIMEOUT) -+ if((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_RESET_PRESENT) != 0UL) -+ { -+ PVR_LOG(("User requested OS reset")); -+ OSPanic(); -+ } -+#endif /* #if defined(PVRSRV_RESET_ON_HWTIMEOUT) */ -+ -+ if ((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_FORCE_SWAP_TO_SYSTEM_PRESENT) != 0UL) -+ { -+ PVRSRVSetDCState(DC_STATE_FORCE_SWAP_TO_SYSTEM); -+ psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_FORCE_SWAP_TO_SYSTEM_PRESENT; -+ } -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVDeviceLISR -+ -+ @Description -+ OS-independent Device Low-level Interrupt Service Routine -+ -+ @Input psDeviceNode -+ -+ @Return IMG_BOOL : Whether any interrupts were serviced -+ -+******************************************************************************/ -+IMG_BOOL IMG_CALLCONV PVRSRVDeviceLISR(PVRSRV_DEVICE_NODE *psDeviceNode) -+{ -+ SYS_DATA *psSysData; -+ IMG_BOOL bStatus = IMG_FALSE; -+ IMG_UINT32 ui32InterruptSource; -+ -+ if(!psDeviceNode) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVDeviceLISR: Invalid params\n")); -+ goto out; -+ } -+ psSysData = psDeviceNode->psSysData; -+ -+ /* query the SOC/system to see whether this device was the source of the interrupt */ -+ ui32InterruptSource = SysGetInterruptSource(psSysData, psDeviceNode); -+ if(ui32InterruptSource & psDeviceNode->ui32SOCInterruptBit) -+ { -+ if(psDeviceNode->pfnDeviceISR != IMG_NULL) -+ { -+ bStatus = (*psDeviceNode->pfnDeviceISR)(psDeviceNode->pvISRData); -+ } -+ -+ SysClearInterrupts(psSysData, psDeviceNode->ui32SOCInterruptBit); -+ } -+ -+out: -+ return bStatus; -+} -+ -+static IMG_VOID PVRSRVSystemLISR_ForEachVaCb(PVRSRV_DEVICE_NODE *psDeviceNode, va_list va) -+{ -+ -+ IMG_BOOL *pbStatus; -+ IMG_UINT32 *pui32InterruptSource; -+ IMG_UINT32 *pui32ClearInterrupts; -+ -+ pbStatus = va_arg(va, IMG_BOOL*); -+ pui32InterruptSource = va_arg(va, IMG_UINT32*); -+ pui32ClearInterrupts = va_arg(va, IMG_UINT32*); -+ -+ -+ if(psDeviceNode->pfnDeviceISR != IMG_NULL) -+ { -+ if(*pui32InterruptSource & psDeviceNode->ui32SOCInterruptBit) -+ { -+ if((*psDeviceNode->pfnDeviceISR)(psDeviceNode->pvISRData)) -+ { -+ /* Record if serviced any interrupts. */ -+ *pbStatus = IMG_TRUE; -+ } -+ /* Combine the SOC clear bits. */ -+ *pui32ClearInterrupts |= psDeviceNode->ui32SOCInterruptBit; -+ } -+ } -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVSystemLISR -+ -+ @Description -+ OS-independent System Low-level Interrupt Service Routine -+ -+ @Input pvSysData -+ -+ @Return IMG_BOOL : Whether any interrupts were serviced -+ -+******************************************************************************/ -+IMG_BOOL IMG_CALLCONV PVRSRVSystemLISR(IMG_VOID *pvSysData) -+{ -+ SYS_DATA *psSysData = pvSysData; -+ IMG_BOOL bStatus = IMG_FALSE; -+ IMG_UINT32 ui32InterruptSource; -+ IMG_UINT32 ui32ClearInterrupts = 0; -+/* PVRSRV_DEVICE_NODE *psDeviceNode;*/ -+ -+ if(!psSysData) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSystemLISR: Invalid params\n")); -+/* goto out; */ -+ } -+ else -+ { -+ /* query SOC for source of interrupts */ -+ ui32InterruptSource = SysGetInterruptSource(psSysData, IMG_NULL); -+ -+ /* only proceed if PVR interrupts */ -+ if(ui32InterruptSource) -+ { -+ /* traverse the devices' ISR handlers */ -+ List_PVRSRV_DEVICE_NODE_ForEach_va(psSysData->psDeviceNodeList, -+ &PVRSRVSystemLISR_ForEachVaCb, -+ &bStatus, -+ &ui32InterruptSource, -+ &ui32ClearInterrupts); -+ -+ SysClearInterrupts(psSysData, ui32ClearInterrupts); -+ } -+/*out:*/ -+ } -+ return bStatus; -+} -+ -+ -+static IMG_VOID PVRSRVMISR_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode) -+{ -+ if(psDeviceNode->pfnDeviceMISR != IMG_NULL) -+ { -+ (*psDeviceNode->pfnDeviceMISR)(psDeviceNode->pvISRData); -+ } -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVMISR -+ -+ @Input pvSysData -+ -+ @Description -+ OS-independent Medium-level Interrupt Service Routine -+ -+******************************************************************************/ -+IMG_VOID IMG_CALLCONV PVRSRVMISR(IMG_VOID *pvSysData) -+{ -+ SYS_DATA *psSysData = pvSysData; -+/* PVRSRV_DEVICE_NODE *psDeviceNode; */ -+ -+ if(!psSysData) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVMISR: Invalid params\n")); -+ return; -+ } -+ -+ /* Traverse the devices' MISR handlers. */ -+ List_PVRSRV_DEVICE_NODE_ForEach(psSysData->psDeviceNodeList, -+ &PVRSRVMISR_ForEachCb); -+ -+ /* Process the queues. */ -+ if (PVRSRVProcessQueues(IMG_FALSE) == PVRSRV_ERROR_PROCESSING_BLOCKED) -+ { -+ PVRSRVProcessQueues(IMG_FALSE); -+ } -+ -+ /* signal global event object */ -+ if (psSysData->psGlobalEventObject) -+ { -+ IMG_HANDLE hOSEventKM = psSysData->psGlobalEventObject->hOSEventKM; -+ if(hOSEventKM) -+ { -+ OSEventObjectSignalKM(hOSEventKM); -+ } -+ } -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVProcessConnect -+ -+ @Description Inform services that a process has connected. -+ -+ @Input ui32PID - process ID -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVProcessConnect(IMG_UINT32 ui32PID, IMG_UINT32 ui32Flags) -+{ -+ return PVRSRVPerProcessDataConnect(ui32PID, ui32Flags); -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVProcessDisconnect -+ -+ @Description Inform services that a process has disconnected. -+ -+ @Input ui32PID - process ID -+ -+ @Return IMG_VOID -+ -+******************************************************************************/ -+IMG_EXPORT -+IMG_VOID IMG_CALLCONV PVRSRVProcessDisconnect(IMG_UINT32 ui32PID) -+{ -+ PVRSRVPerProcessDataDisconnect(ui32PID); -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVSaveRestoreLiveSegments -+ -+ @Input pArena - the arena the segment was originally allocated from. -+ pbyBuffer - the system memory buffer set to null to get the size needed. -+ puiBufSize - size of system memory buffer. -+ bSave - IMG_TRUE if a save is required -+ -+ @Description -+ Function to save or restore Resources Live segments -+ -+******************************************************************************/ -+PVRSRV_ERROR IMG_CALLCONV PVRSRVSaveRestoreLiveSegments(IMG_HANDLE hArena, IMG_PBYTE pbyBuffer, -+ IMG_SIZE_T *puiBufSize, IMG_BOOL bSave) -+{ -+ IMG_SIZE_T uiBytesSaved = 0; -+ IMG_PVOID pvLocalMemCPUVAddr; -+ RA_SEGMENT_DETAILS sSegDetails; -+ -+ if (hArena == IMG_NULL) -+ { -+ return (PVRSRV_ERROR_INVALID_PARAMS); -+ } -+ -+ sSegDetails.uiSize = 0; -+ sSegDetails.sCpuPhyAddr.uiAddr = 0; -+ sSegDetails.hSegment = 0; -+ -+ /* walk the arena segments and write live one to the buffer */ -+ while (RA_GetNextLiveSegment(hArena, &sSegDetails)) -+ { -+ if (pbyBuffer == IMG_NULL) -+ { -+ /* calc buffer required */ -+ uiBytesSaved += sizeof(sSegDetails.uiSize) + sSegDetails.uiSize; -+ } -+ else -+ { -+ if ((uiBytesSaved + sizeof(sSegDetails.uiSize) + sSegDetails.uiSize) > *puiBufSize) -+ { -+ return (PVRSRV_ERROR_OUT_OF_MEMORY); -+ } -+ -+ PVR_DPF(( -+ PVR_DBG_MESSAGE, -+ "PVRSRVSaveRestoreLiveSegments: Base " CPUPADDR_FMT " size %" SIZE_T_FMT_LEN "x", -+ sSegDetails.sCpuPhyAddr.uiAddr, -+ sSegDetails.uiSize)); -+ -+ /* Map the device's local memory area onto the host. */ -+ pvLocalMemCPUVAddr = OSMapPhysToLin(sSegDetails.sCpuPhyAddr, -+ sSegDetails.uiSize, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ IMG_NULL); -+ if (pvLocalMemCPUVAddr == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSaveRestoreLiveSegments: Failed to map local memory to host")); -+ return (PVRSRV_ERROR_OUT_OF_MEMORY); -+ } -+ -+ if (bSave) -+ { -+ /* write segment size then segment data */ -+ OSMemCopy(pbyBuffer, &sSegDetails.uiSize, sizeof(sSegDetails.uiSize)); -+ pbyBuffer += sizeof(sSegDetails.uiSize); -+ -+ OSMemCopy(pbyBuffer, pvLocalMemCPUVAddr, sSegDetails.uiSize); -+ pbyBuffer += sSegDetails.uiSize; -+ } -+ else -+ { -+ IMG_UINT32 uiSize; -+ /* reag segment size and validate */ -+ OSMemCopy(&uiSize, pbyBuffer, sizeof(sSegDetails.uiSize)); -+ -+ if (uiSize != sSegDetails.uiSize) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVSaveRestoreLiveSegments: Segment size error")); -+ } -+ else -+ { -+ pbyBuffer += sizeof(sSegDetails.uiSize); -+ -+ OSMemCopy(pvLocalMemCPUVAddr, pbyBuffer, sSegDetails.uiSize); -+ pbyBuffer += sSegDetails.uiSize; -+ } -+ } -+ -+ -+ uiBytesSaved += sizeof(sSegDetails.uiSize) + sSegDetails.uiSize; -+ -+ OSUnMapPhysToLin(pvLocalMemCPUVAddr, -+ sSegDetails.uiSize, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ IMG_NULL); -+ } -+ } -+ -+ if (pbyBuffer == IMG_NULL) -+ { -+ *puiBufSize = uiBytesSaved; -+ } -+ -+ return (PVRSRV_OK); -+} -+ -+ -+/*! -+ ****************************************************************************** -+ -+ @Function PVRSRVGetErrorStringKM -+ -+ @Description Returns a text string relating to the PVRSRV_ERROR enum. -+ -+ @Note case statement used rather than an indexed arrary to ensure text is -+ synchronised with the correct enum -+ -+ @Input eError : PVRSRV_ERROR enum -+ -+ @Return const IMG_CHAR * : Text string -+ -+ @Note Must be kept in sync with servicesext.h -+ -+******************************************************************************/ -+ -+IMG_EXPORT -+const IMG_CHAR *PVRSRVGetErrorStringKM(PVRSRV_ERROR eError) -+{ -+/* PRQA S 5087 1 */ /* include file required here */ -+#include "pvrsrv_errors.h" -+} -+ -+static IMG_VOID PVRSRVCommandCompleteCallbacks_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode) -+{ -+ if(psDeviceNode->pfnDeviceCommandComplete != IMG_NULL) -+ { -+ /* Call the device's callback function. */ -+ (*psDeviceNode->pfnDeviceCommandComplete)(psDeviceNode); -+ } -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVScheduleDeviceCallbacks -+ -+ @Description Schedule all device callbacks -+ -+ @Return IMG_VOID -+ -+******************************************************************************/ -+IMG_VOID PVRSRVScheduleDeviceCallbacks(IMG_VOID) -+{ -+ SYS_DATA *psSysData; -+/* PVRSRV_DEVICE_NODE *psDeviceNode;*/ -+ -+ SysAcquireData(&psSysData); -+ -+ /*for all the device, invoke the callback function*/ -+ List_PVRSRV_DEVICE_NODE_ForEach(psSysData->psDeviceNodeList, -+ &PVRSRVCommandCompleteCallbacks_ForEachCb); -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVScheduleDevices -+ -+ @Description Schedules all Services-Managed Devices to check their pending -+ command queues. The intention is that ScheduleDevices be called by the -+ 3rd party BC driver after it has finished writing new data to its output -+ texture. -+ -+ @Return IMG_VOID -+ -+******************************************************************************/ -+IMG_EXPORT -+IMG_VOID PVRSRVScheduleDevicesKM(IMG_VOID) -+{ -+ PVRSRVScheduleDeviceCallbacks(); -+} -+ -+/***************************************************************************** -+ End of file (pvrsrv.c) -+*****************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/common/queue.c b/drivers/staging/ti-es8-sgx/services4/srvkm/common/queue.c -new file mode 100644 -index 0000000..68aa540 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/common/queue.c -@@ -0,0 +1,1585 @@ -+/*************************************************************************/ /*! -+@Title Kernel side command queue functions -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#include "services_headers.h" -+#include "pvr_bridge_km.h" -+ -+#include "lists.h" -+#include "ttrace.h" -+ -+#if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) -+#include <linux/sw_sync.h> -+static struct sync_fence *AllocQueueFence(struct sw_sync_timeline *psTimeline, IMG_UINT32 ui32FenceValue, const char *szName) -+{ -+ struct sync_fence *psFence = IMG_NULL; -+ struct sync_pt *psPt; -+ -+ psPt = sw_sync_pt_create(psTimeline, ui32FenceValue); -+ if(psPt) -+ { -+ psFence = sync_fence_create(szName, psPt); -+ if(!psFence) -+ { -+ sync_pt_free(psPt); -+ } -+ } -+ -+ return psFence; -+} -+#endif /* defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) */ -+ -+/* -+ * The number of commands of each type which can be in flight at once. -+ */ -+#if defined(SUPPORT_DC_CMDCOMPLETE_WHEN_NO_LONGER_DISPLAYED) -+#define DC_NUM_COMMANDS_PER_TYPE 2 -+#else -+#define DC_NUM_COMMANDS_PER_TYPE 1 -+#endif -+ -+/* -+ * List of private command processing function pointer tables and command -+ * complete tables for a device in the system. -+ * Each table is allocated when the device registers its private command -+ * processing functions. -+ */ -+typedef struct _DEVICE_COMMAND_DATA_ -+{ -+ PFN_CMD_PROC pfnCmdProc; -+ PCOMMAND_COMPLETE_DATA apsCmdCompleteData[DC_NUM_COMMANDS_PER_TYPE]; -+ IMG_UINT32 ui32CCBOffset; -+ IMG_UINT32 ui32MaxDstSyncCount; /*!< Maximum number of dest syncs */ -+ IMG_UINT32 ui32MaxSrcSyncCount; /*!< Maximum number of source syncs */ -+} DEVICE_COMMAND_DATA; -+ -+ -+#if defined(__linux__) && defined(__KERNEL__) -+ -+#include "proc.h" -+ -+/***************************************************************************** -+ FUNCTION : ProcSeqShowQueue -+ -+ PURPOSE : Print the content of queue element to /proc file -+ (See env/linux/proc.c:CreateProcReadEntrySeq) -+ -+ PARAMETERS : sfile - /proc seq_file -+ el - Element to print -+*****************************************************************************/ -+void ProcSeqShowQueue(struct seq_file *sfile,void* el) -+{ -+ PVRSRV_QUEUE_INFO *psQueue = (PVRSRV_QUEUE_INFO*)el; -+ IMG_INT cmds = 0; -+ IMG_SIZE_T uReadOffset; -+ IMG_SIZE_T uWriteOffset; -+ PVRSRV_COMMAND *psCmd; -+ -+ if(el == PVR_PROC_SEQ_START_TOKEN) -+ { -+ seq_printf( sfile, -+ "Command Queues\n" -+ "Queue CmdPtr Pid Command Size DevInd DSC SSC #Data ...\n"); -+ return; -+ } -+ -+ uReadOffset = psQueue->uReadOffset; -+ uWriteOffset = psQueue->uWriteOffset; -+ -+ while (uReadOffset != uWriteOffset) -+ { -+ psCmd= (PVRSRV_COMMAND *)((IMG_UINTPTR_T)psQueue->pvLinQueueKM + uReadOffset); -+ -+ seq_printf(sfile, "%p %p %5u %6u %3" SIZE_T_FMT_LEN "u %5u %2u %2u %3" SIZE_T_FMT_LEN "u \n", -+ psQueue, -+ psCmd, -+ psCmd->ui32ProcessID, -+ psCmd->CommandType, -+ psCmd->uCmdSize, -+ psCmd->ui32DevIndex, -+ psCmd->ui32DstSyncCount, -+ psCmd->ui32SrcSyncCount, -+ psCmd->uDataSize); -+ { -+ IMG_UINT32 i; -+ for (i = 0; i < psCmd->ui32SrcSyncCount; i++) -+ { -+ PVRSRV_SYNC_DATA *psSyncData = psCmd->psSrcSync[i].psKernelSyncInfoKM->psSyncData; -+ seq_printf(sfile, " Sync %u: ROP/ROC: 0x%x/0x%x WOP/WOC: 0x%x/0x%x ROC-VA: 0x%x WOC-VA: 0x%x\n", -+ i, -+ psCmd->psSrcSync[i].ui32ReadOps2Pending, -+ psSyncData->ui32ReadOps2Complete, -+ psCmd->psSrcSync[i].ui32WriteOpsPending, -+ psSyncData->ui32WriteOpsComplete, -+ psCmd->psSrcSync[i].psKernelSyncInfoKM->sReadOps2CompleteDevVAddr.uiAddr, -+ psCmd->psSrcSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr); -+ } -+ } -+ -+ /* taken from UPDATE_QUEUE_ROFF in queue.h */ -+ uReadOffset += psCmd->uCmdSize; -+ uReadOffset &= psQueue->uQueueSize - 1; -+ cmds++; -+ } -+ -+ if (cmds == 0) -+ { -+ seq_printf(sfile, "%p <empty>\n", psQueue); -+ } -+} -+ -+/***************************************************************************** -+ FUNCTION : ProcSeqOff2ElementQueue -+ -+ PURPOSE : Transale offset to element (/proc stuff) -+ -+ PARAMETERS : sfile - /proc seq_file -+ off - the offset into the buffer -+ -+ RETURNS : element to print -+*****************************************************************************/ -+void* ProcSeqOff2ElementQueue(struct seq_file * sfile, loff_t off) -+{ -+ PVRSRV_QUEUE_INFO *psQueue = IMG_NULL; -+ SYS_DATA *psSysData; -+ -+ PVR_UNREFERENCED_PARAMETER(sfile); -+ -+ if(!off) -+ { -+ return PVR_PROC_SEQ_START_TOKEN; -+ } -+ -+ -+ psSysData = SysAcquireDataNoCheck(); -+ if (psSysData != IMG_NULL) -+ { -+ for (psQueue = psSysData->psQueueList; (((--off) > 0) && (psQueue != IMG_NULL)); psQueue = psQueue->psNextKM); -+ } -+ -+ return psQueue; -+} -+#endif /* __linux__ && __KERNEL__ */ -+ -+/*! -+ * Macro to return space in given command queue -+ */ -+#define GET_SPACE_IN_CMDQ(psQueue) \ -+ ((((psQueue)->uReadOffset - (psQueue)->uWriteOffset) \ -+ + ((psQueue)->uQueueSize - 1)) & ((psQueue)->uQueueSize - 1)) -+ -+/*! -+ * Macro to Write Offset in given command queue -+ */ -+#define UPDATE_QUEUE_WOFF(psQueue, uSize) \ -+ (psQueue)->uWriteOffset = ((psQueue)->uWriteOffset + (uSize)) \ -+ & ((psQueue)->uQueueSize - 1); -+ -+/*! -+ * Check if an ops complete value has gone past the pending value. -+ * This can happen when dummy processing multiple operations, e.g. hardware recovery. -+ */ -+#define SYNCOPS_STALE(ui32OpsComplete, ui32OpsPending) \ -+ ((ui32OpsComplete) >= (ui32OpsPending)) -+ -+/*! -+**************************************************************************** -+ @Function : PVRSRVGetWriteOpsPending -+ -+ @Description : Gets the next operation to wait for in a sync object -+ -+ @Input : psSyncInfo - pointer to sync information struct -+ @Input : bIsReadOp - Is this a read or write op -+ -+ @Return : Next op value -+*****************************************************************************/ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(PVRSRVGetWriteOpsPending) -+#endif -+static INLINE -+IMG_UINT32 PVRSRVGetWriteOpsPending(PVRSRV_KERNEL_SYNC_INFO *psSyncInfo, IMG_BOOL bIsReadOp) -+{ -+ IMG_UINT32 ui32WriteOpsPending; -+ -+ if(bIsReadOp) -+ { -+ ui32WriteOpsPending = psSyncInfo->psSyncData->ui32WriteOpsPending; -+ } -+ else -+ { -+ /* -+ Note: This needs to be atomic and is provided the -+ kernel driver is single threaded (non-rentrant) -+ */ -+ ui32WriteOpsPending = psSyncInfo->psSyncData->ui32WriteOpsPending++; -+ } -+ -+ return ui32WriteOpsPending; -+} -+ -+/*! -+***************************************************************************** -+ @Function : PVRSRVGetReadOpsPending -+ -+ @Description : Gets the number of pending read ops -+ -+ @Input : psSyncInfo - pointer to sync information struct -+ @Input : bIsReadOp - Is this a read or write op -+ -+ @Return : Next op value -+*****************************************************************************/ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(PVRSRVGetReadOpsPending) -+#endif -+static INLINE -+IMG_UINT32 PVRSRVGetReadOpsPending(PVRSRV_KERNEL_SYNC_INFO *psSyncInfo, IMG_BOOL bIsReadOp) -+{ -+ IMG_UINT32 ui32ReadOpsPending; -+ -+ if(bIsReadOp) -+ { -+ ui32ReadOpsPending = psSyncInfo->psSyncData->ui32ReadOps2Pending++; -+ } -+ else -+ { -+ ui32ReadOpsPending = psSyncInfo->psSyncData->ui32ReadOps2Pending; -+ } -+ -+ return ui32ReadOpsPending; -+} -+ -+static IMG_VOID QueueDumpCmdComplete(COMMAND_COMPLETE_DATA *psCmdCompleteData, -+ IMG_UINT32 i, -+ IMG_BOOL bIsSrc) -+{ -+ PVRSRV_SYNC_OBJECT *psSyncObject; -+ -+ psSyncObject = bIsSrc ? psCmdCompleteData->psSrcSync : psCmdCompleteData->psDstSync; -+ -+ if (psCmdCompleteData->bInUse) -+ { -+ PVR_LOG(("\t%s %u: ROC DevVAddr:0x%X ROP:0x%x ROC:0x%x, WOC DevVAddr:0x%X WOP:0x%x WOC:0x%x", -+ bIsSrc ? "SRC" : "DEST", i, -+ psSyncObject[i].psKernelSyncInfoKM->sReadOps2CompleteDevVAddr.uiAddr, -+ psSyncObject[i].psKernelSyncInfoKM->psSyncData->ui32ReadOps2Pending, -+ psSyncObject[i].psKernelSyncInfoKM->psSyncData->ui32ReadOps2Complete, -+ psSyncObject[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr, -+ psSyncObject[i].psKernelSyncInfoKM->psSyncData->ui32WriteOpsPending, -+ psSyncObject[i].psKernelSyncInfoKM->psSyncData->ui32WriteOpsComplete)) -+ } -+ else -+ { -+ PVR_LOG(("\t%s %u: (Not in use)", bIsSrc ? "SRC" : "DEST", i)) -+ } -+} -+ -+ -+static IMG_VOID QueueDumpDebugInfo_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode) -+{ -+ if (psDeviceNode->sDevId.eDeviceClass == PVRSRV_DEVICE_CLASS_DISPLAY) -+ { -+ IMG_UINT32 ui32CmdCounter, ui32SyncCounter; -+ SYS_DATA *psSysData; -+ DEVICE_COMMAND_DATA *psDeviceCommandData; -+ PCOMMAND_COMPLETE_DATA psCmdCompleteData; -+ -+ SysAcquireData(&psSysData); -+ -+ psDeviceCommandData = psSysData->apsDeviceCommandData[psDeviceNode->sDevId.ui32DeviceIndex]; -+ -+ if (psDeviceCommandData != IMG_NULL) -+ { -+ for (ui32CmdCounter = 0; ui32CmdCounter < DC_NUM_COMMANDS_PER_TYPE; ui32CmdCounter++) -+ { -+ psCmdCompleteData = psDeviceCommandData[DC_FLIP_COMMAND].apsCmdCompleteData[ui32CmdCounter]; -+ -+ PVR_LOG(("Flip Command Complete Data %u for display device %u:", -+ ui32CmdCounter, psDeviceNode->sDevId.ui32DeviceIndex)) -+ -+ for (ui32SyncCounter = 0; -+ ui32SyncCounter < psCmdCompleteData->ui32SrcSyncCount; -+ ui32SyncCounter++) -+ { -+ QueueDumpCmdComplete(psCmdCompleteData, ui32SyncCounter, IMG_TRUE); -+ } -+ -+ for (ui32SyncCounter = 0; -+ ui32SyncCounter < psCmdCompleteData->ui32DstSyncCount; -+ ui32SyncCounter++) -+ { -+ QueueDumpCmdComplete(psCmdCompleteData, ui32SyncCounter, IMG_FALSE); -+ } -+ } -+ } -+ else -+ { -+ PVR_LOG(("There is no Command Complete Data for display device %u", psDeviceNode->sDevId.ui32DeviceIndex)) -+ } -+ } -+} -+ -+ -+IMG_VOID QueueDumpDebugInfo(IMG_VOID) -+{ -+ SYS_DATA *psSysData; -+ SysAcquireData(&psSysData); -+ List_PVRSRV_DEVICE_NODE_ForEach(psSysData->psDeviceNodeList, &QueueDumpDebugInfo_ForEachCb); -+} -+ -+ -+/***************************************************************************** -+ Kernel-side functions of User->Kernel transitions -+******************************************************************************/ -+ -+static IMG_SIZE_T NearestPower2(IMG_SIZE_T uValue) -+{ -+ IMG_SIZE_T uTemp, uResult = 1; -+ -+ if(!uValue) -+ return 0; -+ -+ uTemp = uValue - 1; -+ while(uTemp) -+ { -+ uResult <<= 1; -+ uTemp >>= 1; -+ } -+ -+ return uResult; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVCreateCommandQueueKM -+ -+ @Description -+ Creates a new command queue into which render/blt commands etc can be -+ inserted. -+ -+ @Input uQueueSize : -+ -+ @Output ppsQueueInfo : -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateCommandQueueKM(IMG_SIZE_T uQueueSize, -+ PVRSRV_QUEUE_INFO **ppsQueueInfo) -+{ -+ PVRSRV_QUEUE_INFO *psQueueInfo; -+ IMG_SIZE_T uPower2QueueSize = NearestPower2(uQueueSize); -+ SYS_DATA *psSysData; -+ PVRSRV_ERROR eError; -+ IMG_HANDLE hMemBlock; -+ -+ SysAcquireData(&psSysData); -+ -+ /* allocate an internal queue info structure */ -+ eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, -+ sizeof(PVRSRV_QUEUE_INFO), -+ (IMG_VOID **)&psQueueInfo, &hMemBlock, -+ "Queue Info"); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateCommandQueueKM: Failed to alloc queue struct")); -+ goto ErrorExit; -+ } -+ OSMemSet(psQueueInfo, 0, sizeof(PVRSRV_QUEUE_INFO)); -+ -+ psQueueInfo->hMemBlock[0] = hMemBlock; -+ psQueueInfo->ui32ProcessID = OSGetCurrentProcessIDKM(); -+ -+ /* allocate the command queue buffer - allow for overrun */ -+ eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, -+ uPower2QueueSize + PVRSRV_MAX_CMD_SIZE, -+ &psQueueInfo->pvLinQueueKM, &hMemBlock, -+ "Command Queue"); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateCommandQueueKM: Failed to alloc queue buffer")); -+ goto ErrorExit; -+ } -+ -+ psQueueInfo->hMemBlock[1] = hMemBlock; -+ psQueueInfo->pvLinQueueUM = psQueueInfo->pvLinQueueKM; -+ -+ /* Sanity check: Should be zeroed by OSMemSet */ -+ PVR_ASSERT(psQueueInfo->uReadOffset == 0); -+ PVR_ASSERT(psQueueInfo->uWriteOffset == 0); -+ -+ psQueueInfo->uQueueSize = uPower2QueueSize; -+ -+#if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) -+ psQueueInfo->pvTimeline = sw_sync_timeline_create("pvr_queue_proc"); -+ if(psQueueInfo->pvTimeline == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateCommandQueueKM: sw_sync_timeline_create() failed")); -+ goto ErrorExit; -+ } -+#endif -+ -+ /* if this is the first q, create a lock resource for the q list */ -+ if (psSysData->psQueueList == IMG_NULL) -+ { -+ eError = OSCreateResource(&psSysData->sQProcessResource); -+ if (eError != PVRSRV_OK) -+ { -+ goto ErrorExit; -+ } -+ } -+ -+ /* Ensure we don't corrupt queue list, by blocking access */ -+ eError = OSLockResource(&psSysData->sQProcessResource, -+ KERNEL_ID); -+ if (eError != PVRSRV_OK) -+ { -+ goto ErrorExit; -+ } -+ -+ psQueueInfo->psNextKM = psSysData->psQueueList; -+ psSysData->psQueueList = psQueueInfo; -+ -+ eError = OSUnlockResource(&psSysData->sQProcessResource, KERNEL_ID); -+ if (eError != PVRSRV_OK) -+ { -+ goto ErrorExit; -+ } -+ -+ *ppsQueueInfo = psQueueInfo; -+ -+ return PVRSRV_OK; -+ -+ErrorExit: -+ -+ if(psQueueInfo) -+ { -+ if(psQueueInfo->pvLinQueueKM) -+ { -+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, -+ psQueueInfo->uQueueSize, -+ psQueueInfo->pvLinQueueKM, -+ psQueueInfo->hMemBlock[1]); -+ psQueueInfo->pvLinQueueKM = IMG_NULL; -+ } -+ -+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, -+ sizeof(PVRSRV_QUEUE_INFO), -+ psQueueInfo, -+ psQueueInfo->hMemBlock[0]); -+ /*not nulling pointer, out of scope*/ -+ } -+ -+ return eError; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVDestroyCommandQueueKM -+ -+ @Description Destroys a command queue -+ -+ @Input psQueueInfo : -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyCommandQueueKM(PVRSRV_QUEUE_INFO *psQueueInfo) -+{ -+ PVRSRV_QUEUE_INFO *psQueue; -+ SYS_DATA *psSysData; -+ PVRSRV_ERROR eError; -+ IMG_BOOL bTimeout = IMG_TRUE; -+ -+ SysAcquireData(&psSysData); -+ -+ psQueue = psSysData->psQueueList; -+ -+ /* PRQA S 3415,4109 1 */ /* macro format critical - leave alone */ -+ LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) -+ { -+ if(psQueueInfo->uReadOffset == psQueueInfo->uWriteOffset) -+ { -+ bTimeout = IMG_FALSE; -+ break; -+ } -+ OSSleepms(1); -+ } END_LOOP_UNTIL_TIMEOUT(); -+ -+ if (bTimeout) -+ { -+ /* The command queue could not be flushed within the timeout period. -+ Allow the queue to be destroyed before returning the error code. */ -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVDestroyCommandQueueKM : Failed to empty queue")); -+ eError = PVRSRV_ERROR_CANNOT_FLUSH_QUEUE; -+ goto ErrorExit; -+ } -+ -+ /* Ensure we don't corrupt queue list, by blocking access */ -+ eError = OSLockResource(&psSysData->sQProcessResource, -+ KERNEL_ID); -+ if (eError != PVRSRV_OK) -+ { -+ goto ErrorExit; -+ } -+ -+#if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) -+ sync_timeline_destroy(psQueueInfo->pvTimeline); -+#endif -+ -+ if(psQueue == psQueueInfo) -+ { -+ psSysData->psQueueList = psQueueInfo->psNextKM; -+ -+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, -+ NearestPower2(psQueueInfo->uQueueSize) + PVRSRV_MAX_CMD_SIZE, -+ psQueueInfo->pvLinQueueKM, -+ psQueueInfo->hMemBlock[1]); -+ psQueueInfo->pvLinQueueKM = IMG_NULL; -+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, -+ sizeof(PVRSRV_QUEUE_INFO), -+ psQueueInfo, -+ psQueueInfo->hMemBlock[0]); -+ /* PRQA S 3199 1 */ /* see note */ -+ psQueueInfo = IMG_NULL; /*it's a copy on stack, but null it because the function doesn't end right here*/ -+ } -+ else -+ { -+ while(psQueue) -+ { -+ if(psQueue->psNextKM == psQueueInfo) -+ { -+ psQueue->psNextKM = psQueueInfo->psNextKM; -+ -+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, -+ psQueueInfo->uQueueSize, -+ psQueueInfo->pvLinQueueKM, -+ psQueueInfo->hMemBlock[1]); -+ psQueueInfo->pvLinQueueKM = IMG_NULL; -+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, -+ sizeof(PVRSRV_QUEUE_INFO), -+ psQueueInfo, -+ psQueueInfo->hMemBlock[0]); -+ /* PRQA S 3199 1 */ /* see note */ -+ psQueueInfo = IMG_NULL; /*it's a copy on stack, but null it because the function doesn't end right here*/ -+ break; -+ } -+ psQueue = psQueue->psNextKM; -+ } -+ -+ if(!psQueue) -+ { -+ eError = OSUnlockResource(&psSysData->sQProcessResource, KERNEL_ID); -+ if (eError != PVRSRV_OK) -+ { -+ goto ErrorExit; -+ } -+ eError = PVRSRV_ERROR_INVALID_PARAMS; -+ goto ErrorExit; -+ } -+ } -+ -+ /* unlock the Q list lock resource */ -+ eError = OSUnlockResource(&psSysData->sQProcessResource, KERNEL_ID); -+ if (eError != PVRSRV_OK) -+ { -+ goto ErrorExit; -+ } -+ -+ /* if the Q list is now empty, destroy the Q list lock resource */ -+ if (psSysData->psQueueList == IMG_NULL) -+ { -+ eError = OSDestroyResource(&psSysData->sQProcessResource); -+ if (eError != PVRSRV_OK) -+ { -+ goto ErrorExit; -+ } -+ } -+ -+ErrorExit: -+ -+ return eError; -+} -+ -+ -+/*! -+***************************************************************************** -+ -+ @Function : PVRSRVGetQueueSpaceKM -+ -+ @Description : Waits for queue access rights and checks for available space in -+ queue for task param structure -+ -+ @Input : psQueue - pointer to queue information struct -+ @Input : ui32ParamSize - size of task data structure -+ @Output : ppvSpace -+ -+ @Return : PVRSRV_ERROR -+*****************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetQueueSpaceKM(PVRSRV_QUEUE_INFO *psQueue, -+ IMG_SIZE_T uParamSize, -+ IMG_VOID **ppvSpace) -+{ -+ IMG_BOOL bTimeout = IMG_TRUE; -+ -+ /* round to 4byte units */ -+ uParamSize = (uParamSize + 3) & 0xFFFFFFFC; -+ -+ if (uParamSize > PVRSRV_MAX_CMD_SIZE) -+ { -+ PVR_DPF((PVR_DBG_WARNING,"PVRSRVGetQueueSpace: max command size is %d bytes", PVRSRV_MAX_CMD_SIZE)); -+ return PVRSRV_ERROR_CMD_TOO_BIG; -+ } -+ -+ /* PRQA S 3415,4109 1 */ /* macro format critical - leave alone */ -+ LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) -+ { -+ if (GET_SPACE_IN_CMDQ(psQueue) > uParamSize) -+ { -+ bTimeout = IMG_FALSE; -+ break; -+ } -+ OSSleepms(1); -+ } END_LOOP_UNTIL_TIMEOUT(); -+ -+ if (bTimeout == IMG_TRUE) -+ { -+ *ppvSpace = IMG_NULL; -+ -+ return PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE; -+ } -+ else -+ { -+ *ppvSpace = (IMG_VOID *)((IMG_UINTPTR_T)psQueue->pvLinQueueUM + psQueue->uWriteOffset); -+ } -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+***************************************************************************** -+ @Function PVRSRVInsertCommandKM -+ -+ @Description : -+ command insertion utility -+ - waits for space in the queue for a new command -+ - fills in generic command information -+ - returns a pointer to the caller who's expected to then fill -+ in the private data. -+ The caller should follow PVRSRVInsertCommand with PVRSRVSubmitCommand -+ which will update the queue's write offset so the command can be -+ executed. -+ -+ @Input psQueue : pointer to queue information struct -+ -+ @Output ppvCmdData : holds pointer to space in queue for private cmd data -+ -+ @Return PVRSRV_ERROR -+*****************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVInsertCommandKM(PVRSRV_QUEUE_INFO *psQueue, -+ PVRSRV_COMMAND **ppsCommand, -+ IMG_UINT32 ui32DevIndex, -+ IMG_UINT16 CommandType, -+ IMG_UINT32 ui32DstSyncCount, -+ PVRSRV_KERNEL_SYNC_INFO *apsDstSync[], -+ IMG_UINT32 ui32SrcSyncCount, -+ PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[], -+ IMG_SIZE_T uDataByteSize, -+ PFN_QUEUE_COMMAND_COMPLETE pfnCommandComplete, -+ IMG_HANDLE hCallbackData, -+ IMG_HANDLE *phFence) -+{ -+ PVRSRV_ERROR eError; -+ PVRSRV_COMMAND *psCommand; -+ IMG_SIZE_T uCommandSize; -+ IMG_UINT32 i; -+ SYS_DATA *psSysData; -+ DEVICE_COMMAND_DATA *psDeviceCommandData; -+ -+#if !defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) -+ PVR_UNREFERENCED_PARAMETER(phFence); -+#endif -+ -+ /* Check that we've got enough space in our command complete data for this command */ -+ SysAcquireData(&psSysData); -+ psDeviceCommandData = psSysData->apsDeviceCommandData[ui32DevIndex]; -+ -+ if ((psDeviceCommandData[CommandType].ui32MaxDstSyncCount < ui32DstSyncCount) || -+ (psDeviceCommandData[CommandType].ui32MaxSrcSyncCount < ui32SrcSyncCount)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVInsertCommandKM: Too many syncs")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ /* Round up to nearest 32 bit size so pointer arithmetic works */ -+ uDataByteSize = (uDataByteSize + 3UL) & ~3UL; -+ -+ /* calc. command size */ -+ uCommandSize = sizeof(PVRSRV_COMMAND) -+ + ((ui32DstSyncCount + ui32SrcSyncCount) * sizeof(PVRSRV_SYNC_OBJECT)) -+ + uDataByteSize; -+ -+ /* wait for space in queue */ -+ eError = PVRSRVGetQueueSpaceKM (psQueue, uCommandSize, (IMG_VOID**)&psCommand); -+ if(eError != PVRSRV_OK) -+ { -+ return eError; -+ } -+ -+#if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) -+ if(phFence != IMG_NULL) -+ { -+ struct sync_fence *psRetireFence, *psCleanupFence; -+ -+ /* New command? New timeline target */ -+ psQueue->ui32FenceValue++; -+ -+ psRetireFence = AllocQueueFence(psQueue->pvTimeline, psQueue->ui32FenceValue, "pvr_queue_retire"); -+ if(!psRetireFence) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVInsertCommandKM: sync_fence_create() failed")); -+ psQueue->ui32FenceValue--; -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ /* This similar to the retire fence, except that it is destroyed -+ * when a display command completes, rather than at the whim of -+ * userspace. It is used to keep the timeline alive. -+ */ -+ psCleanupFence = AllocQueueFence(psQueue->pvTimeline, psQueue->ui32FenceValue, "pvr_queue_cleanup"); -+ if(!psCleanupFence) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVInsertCommandKM: sync_fence_create() #2 failed")); -+ sync_fence_put(psRetireFence); -+ psQueue->ui32FenceValue--; -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psCommand->pvCleanupFence = psCleanupFence; -+ psCommand->pvTimeline = psQueue->pvTimeline; -+ *phFence = psRetireFence; -+ } -+ else -+ { -+ psCommand->pvTimeline = IMG_NULL; -+ } -+#endif /* defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) */ -+ -+ psCommand->ui32ProcessID = OSGetCurrentProcessIDKM(); -+ -+ /* setup the command */ -+ psCommand->uCmdSize = uCommandSize; /* this may change if cmd shrinks */ -+ psCommand->ui32DevIndex = ui32DevIndex; -+ psCommand->CommandType = CommandType; -+ psCommand->ui32DstSyncCount = ui32DstSyncCount; -+ psCommand->ui32SrcSyncCount = ui32SrcSyncCount; -+ /* override QAC warning about stricter pointers */ -+ /* PRQA S 3305 END_PTR_ASSIGNMENTS */ -+ psCommand->psDstSync = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psCommand) + sizeof(PVRSRV_COMMAND)); -+ -+ -+ psCommand->psSrcSync = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psCommand->psDstSync) -+ + (ui32DstSyncCount * sizeof(PVRSRV_SYNC_OBJECT))); -+ -+ psCommand->pvData = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psCommand->psSrcSync) -+ + (ui32SrcSyncCount * sizeof(PVRSRV_SYNC_OBJECT))); -+/* PRQA L:END_PTR_ASSIGNMENTS */ -+ -+ psCommand->uDataSize = uDataByteSize;/* this may change if cmd shrinks */ -+ -+ psCommand->pfnCommandComplete = pfnCommandComplete; -+ psCommand->hCallbackData = hCallbackData; -+ -+ PVR_TTRACE(PVRSRV_TRACE_GROUP_QUEUE, PVRSRV_TRACE_CLASS_CMD_START, QUEUE_TOKEN_INSERTKM); -+ PVR_TTRACE_UI32(PVRSRV_TRACE_GROUP_QUEUE, PVRSRV_TRACE_CLASS_NONE, -+ QUEUE_TOKEN_COMMAND_TYPE, CommandType); -+ -+ /* setup dst sync objects and their sync dependencies */ -+ for (i=0; i<ui32DstSyncCount; i++) -+ { -+ PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_QUEUE, QUEUE_TOKEN_DST_SYNC, -+ apsDstSync[i], PVRSRV_SYNCOP_SAMPLE); -+ -+ psCommand->psDstSync[i].psKernelSyncInfoKM = apsDstSync[i]; -+ psCommand->psDstSync[i].ui32WriteOpsPending = PVRSRVGetWriteOpsPending(apsDstSync[i], IMG_FALSE); -+ psCommand->psDstSync[i].ui32ReadOps2Pending = PVRSRVGetReadOpsPending(apsDstSync[i], IMG_FALSE); -+ -+ PVRSRVKernelSyncInfoIncRef(apsDstSync[i], IMG_NULL); -+ -+ PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVInsertCommandKM: Dst %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x", -+ i, psCommand->psDstSync[i].psKernelSyncInfoKM->sReadOps2CompleteDevVAddr.uiAddr, -+ psCommand->psDstSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr, -+ psCommand->psDstSync[i].ui32ReadOps2Pending, -+ psCommand->psDstSync[i].ui32WriteOpsPending)); -+ } -+ -+ /* setup src sync objects and their sync dependencies */ -+ for (i=0; i<ui32SrcSyncCount; i++) -+ { -+ PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_QUEUE, QUEUE_TOKEN_DST_SYNC, -+ apsSrcSync[i], PVRSRV_SYNCOP_SAMPLE); -+ -+ psCommand->psSrcSync[i].psKernelSyncInfoKM = apsSrcSync[i]; -+ psCommand->psSrcSync[i].ui32WriteOpsPending = PVRSRVGetWriteOpsPending(apsSrcSync[i], IMG_TRUE); -+ psCommand->psSrcSync[i].ui32ReadOps2Pending = PVRSRVGetReadOpsPending(apsSrcSync[i], IMG_TRUE); -+ -+ PVRSRVKernelSyncInfoIncRef(apsSrcSync[i], IMG_NULL); -+ -+ PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVInsertCommandKM: Src %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x", -+ i, psCommand->psSrcSync[i].psKernelSyncInfoKM->sReadOps2CompleteDevVAddr.uiAddr, -+ psCommand->psSrcSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr, -+ psCommand->psSrcSync[i].ui32ReadOps2Pending, -+ psCommand->psSrcSync[i].ui32WriteOpsPending)); -+ } -+ PVR_TTRACE(PVRSRV_TRACE_GROUP_QUEUE, PVRSRV_TRACE_CLASS_CMD_END, QUEUE_TOKEN_INSERTKM); -+ -+ /* return pointer to caller to fill out private data */ -+ *ppsCommand = psCommand; -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+******************************************************************************* -+ @Function : PVRSRVSubmitCommandKM -+ -+ @Description : -+ updates the queue's write offset so the command can be executed. -+ -+ @Input : psQueue - queue command is in -+ @Input : psCommand -+ -+ @Return : PVRSRV_ERROR -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVSubmitCommandKM(PVRSRV_QUEUE_INFO *psQueue, -+ PVRSRV_COMMAND *psCommand) -+{ -+ /* override QAC warnings about stricter pointers */ -+ /* PRQA S 3305 END_PTR_ASSIGNMENTS2 */ -+ /* patch pointers in the command to be kernel pointers */ -+ if (psCommand->ui32DstSyncCount > 0) -+ { -+ psCommand->psDstSync = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psQueue->pvLinQueueKM) -+ + psQueue->uWriteOffset + sizeof(PVRSRV_COMMAND)); -+ } -+ -+ if (psCommand->ui32SrcSyncCount > 0) -+ { -+ psCommand->psSrcSync = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psQueue->pvLinQueueKM) -+ + psQueue->uWriteOffset + sizeof(PVRSRV_COMMAND) -+ + (psCommand->ui32DstSyncCount * sizeof(PVRSRV_SYNC_OBJECT))); -+ } -+ -+ psCommand->pvData = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psQueue->pvLinQueueKM) -+ + psQueue->uWriteOffset + sizeof(PVRSRV_COMMAND) -+ + (psCommand->ui32DstSyncCount * sizeof(PVRSRV_SYNC_OBJECT)) -+ + (psCommand->ui32SrcSyncCount * sizeof(PVRSRV_SYNC_OBJECT))); -+ -+/* PRQA L:END_PTR_ASSIGNMENTS2 */ -+ -+ /* update write offset before releasing access lock */ -+ UPDATE_QUEUE_WOFF(psQueue, psCommand->uCmdSize); -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function CheckIfSyncIsQueued -+ -+ @Description Check if the specificed sync object is already queued and -+ can safely be given to the display controller. -+ This check is required as a 3rd party displayclass device can -+ have several flips "in flight" and we need to ensure that we -+ keep their pipeline full and don't deadlock waiting for them -+ to complete an operation on a surface. -+ -+ @Input psSysData : system data -+ @Input psCmdData : COMMAND_COMPLETE_DATA structure -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+static -+PVRSRV_ERROR CheckIfSyncIsQueued(PVRSRV_SYNC_OBJECT *psSync, COMMAND_COMPLETE_DATA *psCmdData) -+{ -+ IMG_UINT32 k; -+ -+ if (psCmdData->bInUse) -+ { -+ for (k=0;k<psCmdData->ui32SrcSyncCount;k++) -+ { -+ if (psSync->psKernelSyncInfoKM == psCmdData->psSrcSync[k].psKernelSyncInfoKM) -+ { -+ PVRSRV_SYNC_DATA *psSyncData = psSync->psKernelSyncInfoKM->psSyncData; -+ IMG_UINT32 ui32WriteOpsComplete = psSyncData->ui32WriteOpsComplete; -+ -+ /* -+ We still need to ensure that we don't we don't give a command -+ to the display controller if writes are outstanding on it -+ */ -+ if (ui32WriteOpsComplete == psSync->ui32WriteOpsPending) -+ { -+ return PVRSRV_OK; -+ } -+ else -+ { -+ if (SYNCOPS_STALE(ui32WriteOpsComplete, psSync->ui32WriteOpsPending)) -+ { -+ PVR_DPF((PVR_DBG_WARNING, -+ "CheckIfSyncIsQueued: Stale syncops psSyncData:0x%p ui32WriteOpsComplete:0x%x ui32WriteOpsPending:0x%x", -+ psSyncData, ui32WriteOpsComplete, psSync->ui32WriteOpsPending)); -+ return PVRSRV_OK; -+ } -+ } -+ } -+ } -+ } -+ return PVRSRV_ERROR_FAILED_DEPENDENCIES; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVProcessCommand -+ -+ @Description Tries to process a command -+ -+ @Input psSysData : system data -+ @Input psCommand : PVRSRV_COMMAND structure -+ @Input bFlush : Check for stale dependencies (only used for HW recovery) -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+static -+PVRSRV_ERROR PVRSRVProcessCommand(SYS_DATA *psSysData, -+ PVRSRV_COMMAND *psCommand, -+ IMG_BOOL bFlush) -+{ -+ PVRSRV_SYNC_OBJECT *psWalkerObj; -+ PVRSRV_SYNC_OBJECT *psEndObj; -+ IMG_UINT32 i; -+ COMMAND_COMPLETE_DATA *psCmdCompleteData; -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ IMG_UINT32 ui32WriteOpsComplete; -+ IMG_UINT32 ui32ReadOpsComplete; -+ DEVICE_COMMAND_DATA *psDeviceCommandData; -+ IMG_UINT32 ui32CCBOffset; -+ -+ /* satisfy sync dependencies on the DST(s) */ -+ psWalkerObj = psCommand->psDstSync; -+ psEndObj = psWalkerObj + psCommand->ui32DstSyncCount; -+ while (psWalkerObj < psEndObj) -+ { -+ PVRSRV_SYNC_DATA *psSyncData = psWalkerObj->psKernelSyncInfoKM->psSyncData; -+ -+ ui32WriteOpsComplete = psSyncData->ui32WriteOpsComplete; -+ ui32ReadOpsComplete = psSyncData->ui32ReadOps2Complete; -+ /* fail if reads or writes are not up to date */ -+ if ((ui32WriteOpsComplete != psWalkerObj->ui32WriteOpsPending) -+ || (ui32ReadOpsComplete != psWalkerObj->ui32ReadOps2Pending)) -+ { -+ if (!bFlush || -+ !SYNCOPS_STALE(ui32WriteOpsComplete, psWalkerObj->ui32WriteOpsPending) || -+ !SYNCOPS_STALE(ui32ReadOpsComplete, psWalkerObj->ui32ReadOps2Pending)) -+ { -+ return PVRSRV_ERROR_FAILED_DEPENDENCIES; -+ } -+ } -+ -+ psWalkerObj++; -+ } -+ -+ /* satisfy sync dependencies on the SRC(s) */ -+ psWalkerObj = psCommand->psSrcSync; -+ psEndObj = psWalkerObj + psCommand->ui32SrcSyncCount; -+ while (psWalkerObj < psEndObj) -+ { -+ PVRSRV_SYNC_DATA *psSyncData = psWalkerObj->psKernelSyncInfoKM->psSyncData; -+ -+ ui32ReadOpsComplete = psSyncData->ui32ReadOps2Complete; -+ ui32WriteOpsComplete = psSyncData->ui32WriteOpsComplete; -+ /* fail if writes are not up to date */ -+ if ((ui32WriteOpsComplete != psWalkerObj->ui32WriteOpsPending) -+ || (ui32ReadOpsComplete != psWalkerObj->ui32ReadOps2Pending)) -+ { -+ if (!bFlush && -+ SYNCOPS_STALE(ui32WriteOpsComplete, psWalkerObj->ui32WriteOpsPending) && -+ SYNCOPS_STALE(ui32ReadOpsComplete, psWalkerObj->ui32ReadOps2Pending)) -+ { -+ PVR_DPF((PVR_DBG_WARNING, -+ "PVRSRVProcessCommand: Stale syncops psSyncData:0x%p ui32WriteOpsComplete:0x%x ui32WriteOpsPending:0x%x", -+ psSyncData, ui32WriteOpsComplete, psWalkerObj->ui32WriteOpsPending)); -+ } -+ -+ if (!bFlush || -+ !SYNCOPS_STALE(ui32WriteOpsComplete, psWalkerObj->ui32WriteOpsPending) || -+ !SYNCOPS_STALE(ui32ReadOpsComplete, psWalkerObj->ui32ReadOps2Pending)) -+ { -+ IMG_UINT32 j; -+ PVRSRV_ERROR eError; -+ IMG_BOOL bFound = IMG_FALSE; -+ -+ psDeviceCommandData = psSysData->apsDeviceCommandData[psCommand->ui32DevIndex]; -+ for (j=0;j<DC_NUM_COMMANDS_PER_TYPE;j++) -+ { -+ eError = CheckIfSyncIsQueued(psWalkerObj, psDeviceCommandData[psCommand->CommandType].apsCmdCompleteData[j]); -+ -+ if (eError == PVRSRV_OK) -+ { -+ bFound = IMG_TRUE; -+ } -+ } -+ if (!bFound) -+ return PVRSRV_ERROR_FAILED_DEPENDENCIES; -+ } -+ } -+ psWalkerObj++; -+ } -+ -+ /* validate device type */ -+ if (psCommand->ui32DevIndex >= SYS_DEVICE_COUNT) -+ { -+ PVR_DPF((PVR_DBG_ERROR, -+ "PVRSRVProcessCommand: invalid DeviceType 0x%x", -+ psCommand->ui32DevIndex)); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ /* fish out the appropriate storage structure for the duration of the command */ -+ psDeviceCommandData = psSysData->apsDeviceCommandData[psCommand->ui32DevIndex]; -+ ui32CCBOffset = psDeviceCommandData[psCommand->CommandType].ui32CCBOffset; -+ psCmdCompleteData = psDeviceCommandData[psCommand->CommandType].apsCmdCompleteData[ui32CCBOffset]; -+ if (psCmdCompleteData->bInUse) -+ { -+ /* can use this to protect against concurrent execution of same command */ -+ return PVRSRV_ERROR_FAILED_DEPENDENCIES; -+ } -+ -+ /* mark the structure as in use */ -+ psCmdCompleteData->bInUse = IMG_TRUE; -+ -+ /* copy src updates over */ -+ psCmdCompleteData->ui32DstSyncCount = psCommand->ui32DstSyncCount; -+ for (i=0; i<psCommand->ui32DstSyncCount; i++) -+ { -+ psCmdCompleteData->psDstSync[i] = psCommand->psDstSync[i]; -+ -+ PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVProcessCommand: Dst %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x (CCB:%u)", -+ i, psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->sReadOps2CompleteDevVAddr.uiAddr, -+ psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr, -+ psCmdCompleteData->psDstSync[i].ui32ReadOps2Pending, -+ psCmdCompleteData->psDstSync[i].ui32WriteOpsPending, -+ ui32CCBOffset)); -+ } -+ -+ psCmdCompleteData->pfnCommandComplete = psCommand->pfnCommandComplete; -+ psCmdCompleteData->hCallbackData = psCommand->hCallbackData; -+ -+#if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) -+ psCmdCompleteData->pvCleanupFence = psCommand->pvCleanupFence; -+ psCmdCompleteData->pvTimeline = psCommand->pvTimeline; -+#endif -+ -+ /* copy dst updates over */ -+ psCmdCompleteData->ui32SrcSyncCount = psCommand->ui32SrcSyncCount; -+ for (i=0; i<psCommand->ui32SrcSyncCount; i++) -+ { -+ psCmdCompleteData->psSrcSync[i] = psCommand->psSrcSync[i]; -+ -+ PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVProcessCommand: Src %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x (CCB:%u)", -+ i, psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->sReadOps2CompleteDevVAddr.uiAddr, -+ psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr, -+ psCmdCompleteData->psSrcSync[i].ui32ReadOps2Pending, -+ psCmdCompleteData->psSrcSync[i].ui32WriteOpsPending, -+ ui32CCBOffset)); -+ } -+ -+ /* -+ call the cmd specific handler: -+ it should: -+ - check the cmd specific dependencies -+ - setup private cmd complete structure -+ - execute cmd on HW -+ - store psCmdCompleteData `cookie' and later pass as -+ argument to Generic Command Complete Callback -+ -+ n.b. ui32DataSize (packet size) is useful for packet validation -+ */ -+ if (psDeviceCommandData[psCommand->CommandType].pfnCmdProc((IMG_HANDLE)psCmdCompleteData, -+ (IMG_UINT32)psCommand->uDataSize, -+ psCommand->pvData) == IMG_FALSE) -+ { -+ /* -+ clean-up: -+ free cmd complete structure -+ */ -+ psCmdCompleteData->bInUse = IMG_FALSE; -+ eError = PVRSRV_ERROR_CMD_NOT_PROCESSED; -+ PVR_LOG(("Failed to submit command from queue processor, this could cause sync wedge!")); -+ } -+ else -+ { -+ /* Increment the CCB offset */ -+ psDeviceCommandData[psCommand->CommandType].ui32CCBOffset = (ui32CCBOffset + 1) % DC_NUM_COMMANDS_PER_TYPE; -+ } -+ -+ return eError; -+} -+ -+ -+static IMG_VOID PVRSRVProcessQueues_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode) -+{ -+ if (psDeviceNode->bReProcessDeviceCommandComplete && -+ psDeviceNode->pfnDeviceCommandComplete != IMG_NULL) -+ { -+ (*psDeviceNode->pfnDeviceCommandComplete)(psDeviceNode); -+ } -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVProcessQueues -+ -+ @Description Tries to process a command from each Q -+ -+ @input ui32CallerID - used to distinguish between async ISR/DPC type calls -+ the synchronous services driver -+ @input bFlush - flush commands with stale dependencies (only used for HW recovery) -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+ -+IMG_EXPORT -+PVRSRV_ERROR PVRSRVProcessQueues(IMG_BOOL bFlush) -+{ -+ PVRSRV_QUEUE_INFO *psQueue; -+ SYS_DATA *psSysData; -+ PVRSRV_COMMAND *psCommand; -+/* PVRSRV_DEVICE_NODE *psDeviceNode;*/ -+ -+ SysAcquireData(&psSysData); -+ -+ /* Ensure we don't corrupt queue list, by blocking access. This is required for OSs where -+ multiple ISR threads may exist simultaneously (eg WinXP DPC routines) -+ */ -+ while (OSLockResource(&psSysData->sQProcessResource, ISR_ID) != PVRSRV_OK) -+ { -+ OSWaitus(1); -+ }; -+ -+ psQueue = psSysData->psQueueList; -+ -+ if(!psQueue) -+ { -+ PVR_DPF((PVR_DBG_MESSAGE,"No Queues installed - cannot process commands")); -+ } -+ -+ if (bFlush) -+ { -+ PVRSRVSetDCState(DC_STATE_FLUSH_COMMANDS); -+ } -+ -+ while (psQueue) -+ { -+ while (psQueue->uReadOffset != psQueue->uWriteOffset) -+ { -+ psCommand = (PVRSRV_COMMAND*)((IMG_UINTPTR_T)psQueue->pvLinQueueKM + psQueue->uReadOffset); -+ -+ if (PVRSRVProcessCommand(psSysData, psCommand, bFlush) == PVRSRV_OK) -+ { -+ /* processed cmd so update queue */ -+ UPDATE_QUEUE_ROFF(psQueue, psCommand->uCmdSize) -+ continue; -+ } -+ -+ break; -+ } -+ psQueue = psQueue->psNextKM; -+ } -+ -+ if (bFlush) -+ { -+ PVRSRVSetDCState(DC_STATE_NO_FLUSH_COMMANDS); -+ } -+ -+ /* Re-process command complete handlers if necessary. */ -+ List_PVRSRV_DEVICE_NODE_ForEach(psSysData->psDeviceNodeList, -+ &PVRSRVProcessQueues_ForEachCb); -+ -+ OSUnlockResource(&psSysData->sQProcessResource, ISR_ID); -+ -+ return PVRSRV_OK; -+} -+ -+#if defined(SUPPORT_CUSTOM_SWAP_OPERATIONS) -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVFreeCommandCompletePacketKM -+ -+ @Description Updates non-private command complete sync objects -+ -+ @Input hCmdCookie : command cookie -+ @Input bScheduleMISR : obsolete parameter -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+IMG_INTERNAL -+IMG_VOID PVRSRVFreeCommandCompletePacketKM(IMG_HANDLE hCmdCookie, -+ IMG_BOOL bScheduleMISR) -+{ -+ COMMAND_COMPLETE_DATA *psCmdCompleteData = (COMMAND_COMPLETE_DATA *)hCmdCookie; -+ SYS_DATA *psSysData; -+ -+ PVR_UNREFERENCED_PARAMETER(bScheduleMISR); -+ -+ SysAcquireData(&psSysData); -+ -+ /* free command complete storage */ -+ psCmdCompleteData->bInUse = IMG_FALSE; -+ -+ /* FIXME: This may cause unrelated devices to be woken up. */ -+ PVRSRVScheduleDeviceCallbacks(); -+ -+ /* the MISR is always scheduled, regardless of bScheduleMISR */ -+ OSScheduleMISR(psSysData); -+} -+ -+#endif /* (SUPPORT_CUSTOM_SWAP_OPERATIONS) */ -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVCommandCompleteKM -+ -+ @Description Updates non-private command complete sync objects -+ -+ @Input hCmdCookie : command cookie -+ @Input bScheduleMISR : boolean to schedule MISR -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+IMG_EXPORT -+IMG_VOID PVRSRVCommandCompleteKM(IMG_HANDLE hCmdCookie, -+ IMG_BOOL bScheduleMISR) -+{ -+ IMG_UINT32 i; -+ COMMAND_COMPLETE_DATA *psCmdCompleteData = (COMMAND_COMPLETE_DATA *)hCmdCookie; -+ SYS_DATA *psSysData; -+ -+ SysAcquireData(&psSysData); -+ -+ PVR_TTRACE(PVRSRV_TRACE_GROUP_QUEUE, PVRSRV_TRACE_CLASS_CMD_COMP_START, -+ QUEUE_TOKEN_COMMAND_COMPLETE); -+ -+ /* update DST(s) syncs */ -+ for (i=0; i<psCmdCompleteData->ui32DstSyncCount; i++) -+ { -+ psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->psSyncData->ui32WriteOpsComplete++; -+ -+ PVRSRVKernelSyncInfoDecRef(psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM, IMG_NULL); -+ -+ PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_QUEUE, QUEUE_TOKEN_UPDATE_DST, -+ psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM, -+ PVRSRV_SYNCOP_COMPLETE); -+ -+ PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVCommandCompleteKM: Dst %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x", -+ i, psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->sReadOps2CompleteDevVAddr.uiAddr, -+ psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr, -+ psCmdCompleteData->psDstSync[i].ui32ReadOps2Pending, -+ psCmdCompleteData->psDstSync[i].ui32WriteOpsPending)); -+ } -+ -+ /* update SRC(s) syncs */ -+ for (i=0; i<psCmdCompleteData->ui32SrcSyncCount; i++) -+ { -+ psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->psSyncData->ui32ReadOps2Complete++; -+ -+ PVRSRVKernelSyncInfoDecRef(psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM, IMG_NULL); -+ -+ PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_QUEUE, QUEUE_TOKEN_UPDATE_SRC, -+ psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM, -+ PVRSRV_SYNCOP_COMPLETE); -+ -+ PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVCommandCompleteKM: Src %u RO-VA:0x%x WO-VA:0x%x ROP:0x%x WOP:0x%x", -+ i, psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->sReadOps2CompleteDevVAddr.uiAddr, -+ psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr, -+ psCmdCompleteData->psSrcSync[i].ui32ReadOps2Pending, -+ psCmdCompleteData->psSrcSync[i].ui32WriteOpsPending)); -+ } -+ -+ PVR_TTRACE(PVRSRV_TRACE_GROUP_QUEUE, PVRSRV_TRACE_CLASS_CMD_COMP_END, -+ QUEUE_TOKEN_COMMAND_COMPLETE); -+ -+ if (psCmdCompleteData->pfnCommandComplete) -+ { -+ psCmdCompleteData->pfnCommandComplete(psCmdCompleteData->hCallbackData); -+ } -+ -+#if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) -+ if(psCmdCompleteData->pvTimeline) -+ { -+ sw_sync_timeline_inc(psCmdCompleteData->pvTimeline, 1); -+ sync_fence_put(psCmdCompleteData->pvCleanupFence); -+ } -+#endif /* defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) */ -+ -+ /* free command complete storage */ -+ psCmdCompleteData->bInUse = IMG_FALSE; -+ -+ /* FIXME: This may cause unrelated devices to be woken up. */ -+ PVRSRVScheduleDeviceCallbacks(); -+ -+ if(bScheduleMISR) -+ { -+ OSScheduleMISR(psSysData); -+ } -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVRegisterCmdProcListKM -+ -+ @Description -+ -+ registers a list of private command processing functions with the Command -+ Queue Manager -+ -+ @Input ui32DevIndex : device index -+ -+ @Input ppfnCmdProcList : function ptr table of private command processors -+ -+ @Input ui32MaxSyncsPerCmd : max number of syncobjects used by command -+ -+ @Input ui32CmdCount : number of entries in function ptr table -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR PVRSRVRegisterCmdProcListKM(IMG_UINT32 ui32DevIndex, -+ PFN_CMD_PROC *ppfnCmdProcList, -+ IMG_UINT32 ui32MaxSyncsPerCmd[][2], -+ IMG_UINT32 ui32CmdCount) -+{ -+ SYS_DATA *psSysData; -+ PVRSRV_ERROR eError; -+ IMG_UINT32 ui32CmdCounter, ui32CmdTypeCounter; -+ IMG_SIZE_T ui32AllocSize; -+ DEVICE_COMMAND_DATA *psDeviceCommandData; -+ COMMAND_COMPLETE_DATA *psCmdCompleteData; -+ -+ /* validate device type */ -+ if(ui32DevIndex >= SYS_DEVICE_COUNT) -+ { -+ PVR_DPF((PVR_DBG_ERROR, -+ "PVRSRVRegisterCmdProcListKM: invalid DeviceType 0x%x", -+ ui32DevIndex)); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ /* acquire system data structure */ -+ SysAcquireData(&psSysData); -+ -+ /* array of pointers for each command store */ -+ ui32AllocSize = ui32CmdCount * sizeof(*psDeviceCommandData); -+ eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, -+ ui32AllocSize, -+ (IMG_VOID **)&psDeviceCommandData, IMG_NULL, -+ "Array of Pointers for Command Store"); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterCmdProcListKM: Failed to alloc CC data")); -+ goto ErrorExit; -+ } -+ -+ psSysData->apsDeviceCommandData[ui32DevIndex] = psDeviceCommandData; -+ -+ for (ui32CmdTypeCounter = 0; ui32CmdTypeCounter < ui32CmdCount; ui32CmdTypeCounter++) -+ { -+ psDeviceCommandData[ui32CmdTypeCounter].pfnCmdProc = ppfnCmdProcList[ui32CmdTypeCounter]; -+ psDeviceCommandData[ui32CmdTypeCounter].ui32CCBOffset = 0; -+ psDeviceCommandData[ui32CmdTypeCounter].ui32MaxDstSyncCount = ui32MaxSyncsPerCmd[ui32CmdTypeCounter][0]; -+ psDeviceCommandData[ui32CmdTypeCounter].ui32MaxSrcSyncCount = ui32MaxSyncsPerCmd[ui32CmdTypeCounter][1]; -+ for (ui32CmdCounter = 0; ui32CmdCounter < DC_NUM_COMMANDS_PER_TYPE; ui32CmdCounter++) -+ { -+ /* -+ allocate storage for the sync update on command complete -+ */ -+ ui32AllocSize = sizeof(COMMAND_COMPLETE_DATA) /* space for one GENERIC_CMD_COMPLETE */ -+ + ((ui32MaxSyncsPerCmd[ui32CmdTypeCounter][0] -+ + ui32MaxSyncsPerCmd[ui32CmdTypeCounter][1]) -+ * sizeof(PVRSRV_SYNC_OBJECT)); /* space for max sync objects */ -+ -+ eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, -+ ui32AllocSize, -+ (IMG_VOID **)&psCmdCompleteData, -+ IMG_NULL, -+ "Command Complete Data"); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterCmdProcListKM: Failed to alloc cmd %d", ui32CmdTypeCounter)); -+ goto ErrorExit; -+ } -+ -+ psDeviceCommandData[ui32CmdTypeCounter].apsCmdCompleteData[ui32CmdCounter] = psCmdCompleteData; -+ -+ /* clear memory */ -+ OSMemSet(psCmdCompleteData, 0x00, ui32AllocSize); -+ -+ /* setup sync pointers */ -+ psCmdCompleteData->psDstSync = (PVRSRV_SYNC_OBJECT*) -+ (((IMG_UINTPTR_T)psCmdCompleteData) -+ + sizeof(COMMAND_COMPLETE_DATA)); -+ psCmdCompleteData->psSrcSync = (PVRSRV_SYNC_OBJECT*) -+ (((IMG_UINTPTR_T)psCmdCompleteData->psDstSync) -+ + (sizeof(PVRSRV_SYNC_OBJECT) * ui32MaxSyncsPerCmd[ui32CmdTypeCounter][0])); -+ -+ psCmdCompleteData->ui32AllocSize = (IMG_UINT32)ui32AllocSize; -+ } -+ } -+ -+ return PVRSRV_OK; -+ -+ErrorExit: -+ -+ /* clean-up if things went wrong */ -+ if (PVRSRVRemoveCmdProcListKM(ui32DevIndex, ui32CmdCount) != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, -+ "PVRSRVRegisterCmdProcListKM: Failed to clean up after error, device 0x%x", -+ ui32DevIndex)); -+ } -+ -+ return eError; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVRemoveCmdProcListKM -+ -+ @Description -+ -+ removes a list of private command processing functions and data from the -+ Queue Manager -+ -+ @Input ui32DevIndex : device index -+ -+ @Input ui32CmdCount : number of entries in function ptr table -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR PVRSRVRemoveCmdProcListKM(IMG_UINT32 ui32DevIndex, -+ IMG_UINT32 ui32CmdCount) -+{ -+ SYS_DATA *psSysData; -+ IMG_UINT32 ui32CmdTypeCounter, ui32CmdCounter; -+ DEVICE_COMMAND_DATA *psDeviceCommandData; -+ COMMAND_COMPLETE_DATA *psCmdCompleteData; -+ IMG_SIZE_T ui32AllocSize; -+ -+ /* validate device type */ -+ if(ui32DevIndex >= SYS_DEVICE_COUNT) -+ { -+ PVR_DPF((PVR_DBG_ERROR, -+ "PVRSRVRemoveCmdProcListKM: invalid DeviceType 0x%x", -+ ui32DevIndex)); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ /* acquire system data structure */ -+ SysAcquireData(&psSysData); -+ -+ psDeviceCommandData = psSysData->apsDeviceCommandData[ui32DevIndex]; -+ if(psDeviceCommandData != IMG_NULL) -+ { -+ for (ui32CmdTypeCounter = 0; ui32CmdTypeCounter < ui32CmdCount; ui32CmdTypeCounter++) -+ { -+ for (ui32CmdCounter = 0; ui32CmdCounter < DC_NUM_COMMANDS_PER_TYPE; ui32CmdCounter++) -+ { -+ psCmdCompleteData = psDeviceCommandData[ui32CmdTypeCounter].apsCmdCompleteData[ui32CmdCounter]; -+ -+ /* free the cmd complete structure array entries */ -+ if (psCmdCompleteData != IMG_NULL) -+ { -+ PVR_ASSERT(psCmdCompleteData->bInUse == IMG_FALSE); -+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, psCmdCompleteData->ui32AllocSize, -+ psCmdCompleteData, IMG_NULL); -+ psDeviceCommandData[ui32CmdTypeCounter].apsCmdCompleteData[ui32CmdCounter] = IMG_NULL; -+ } -+ } -+ } -+ -+ /* free the cmd complete structure array for the device */ -+ ui32AllocSize = ui32CmdCount * sizeof(*psDeviceCommandData); -+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, ui32AllocSize, psDeviceCommandData, IMG_NULL); -+ psSysData->apsDeviceCommandData[ui32DevIndex] = IMG_NULL; -+ } -+ -+ return PVRSRV_OK; -+} -+ -+/****************************************************************************** -+ End of file (queue.c) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/common/ra.c b/drivers/staging/ti-es8-sgx/services4/srvkm/common/ra.c -new file mode 100644 -index 0000000..afe560f ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/common/ra.c -@@ -0,0 +1,2208 @@ -+/*************************************************************************/ /*! -+@Title Resource Allocator -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description -+ Implements generic resource allocation. The resource -+ allocator was originally intended to manage address spaces in -+ practice the resource allocator is generic and can manages arbitrary -+ sets of integers. -+ -+ Resources are allocated from arenas. Arena's can be created with an -+ initial span of resources. Further resources spans can be added to -+ arenas. A call back mechanism allows an arena to request further -+ resource spans on demand. -+ -+ Each arena maintains an ordered list of resource segments each -+ described by a boundary tag. Each boundary tag describes a segment -+ of resources which are either 'free', available for allocation, or -+ 'busy' currently allocated. Adjacent 'free' segments are always -+ coallesced to avoid fragmentation. -+ -+ For allocation, all 'free' segments are kept on lists of 'free' -+ segments in a table index by pvr_log2(segment size). ie Each table index -+ n holds 'free' segments in the size range 2**(n-1) -> 2**n. -+ -+ Allocation policy is based on an *almost* best fit -+ stratedy. Choosing any segment from the appropriate table entry -+ guarantees that we choose a segment which is with a power of 2 of -+ the size we are allocating. -+ -+ Allocated segments are inserted into a self scaling hash table which -+ maps the base resource of the span to the relevant boundary -+ tag. This allows the code to get back to the bounary tag without -+ exporting explicit boundary tag references through the API. -+ -+ Each arena has an associated quantum size, all allocations from the -+ arena are made in multiples of the basic quantum. -+ -+ On resource exhaustion in an arena, a callback if provided will be -+ used to request further resources. Resouces spans allocated by the -+ callback mechanism are delimited by special boundary tag markers of -+ zero span, 'span' markers. Span markers are never coallesced. Span -+ markers are used to detect when an imported span is completely free -+ and can be deallocated by the callback mechanism. -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+/* Issues: -+ * - flags, flags are passed into the resource allocator but are not currently used. -+ * - determination, of import size, is currently braindead. -+ * - debug code should be moved out to own module and #ifdef'd -+ */ -+ -+#include "services_headers.h" -+#include "hash.h" -+#include "ra.h" -+#include "buffer_manager.h" -+#include "osfunc.h" -+ -+#if defined(__linux__) && defined(__KERNEL__) -+#include <linux/kernel.h> -+#include "proc.h" -+#endif -+ -+#ifdef USE_BM_FREESPACE_CHECK -+#include <stdio.h> -+#endif -+ -+/* The initial, and minimum size of the live address -> boundary tag -+ structure hash table. The value 64 is a fairly arbitrary -+ choice. The hash table resizes on demand so the value choosen is -+ not critical. */ -+#define MINIMUM_HASH_SIZE (64) -+ -+#if defined(VALIDATE_ARENA_TEST) -+ -+/* This test validates the doubly linked ordered list of boundary tags, by -+checking that adjacent members of the list have compatible eResourceSpan -+and eResourceType values. */ -+ -+typedef enum RESOURCE_DESCRIPTOR_TAG { -+ -+ RESOURCE_SPAN_LIVE = 10, -+ RESOURCE_SPAN_FREE, -+ IMPORTED_RESOURCE_SPAN_START, -+ IMPORTED_RESOURCE_SPAN_LIVE, -+ IMPORTED_RESOURCE_SPAN_FREE, -+ IMPORTED_RESOURCE_SPAN_END, -+ -+} RESOURCE_DESCRIPTOR; -+ -+typedef enum RESOURCE_TYPE_TAG { -+ -+ IMPORTED_RESOURCE_TYPE = 20, -+ NON_IMPORTED_RESOURCE_TYPE -+ -+} RESOURCE_TYPE; -+ -+ -+static IMG_UINT32 ui32BoundaryTagID = 0; -+ -+IMG_UINT32 ValidateArena(RA_ARENA *pArena); -+#endif -+ -+/* boundary tags, used to describe a resource segment */ -+struct _BT_ -+{ -+ enum bt_type -+ { -+ btt_span, /* span markers */ -+ btt_free, /* free resource segment */ -+ btt_live /* allocated resource segment */ -+ } type; -+ -+ /* The base resource and extent of this segment */ -+ IMG_UINTPTR_T base; -+ IMG_SIZE_T uSize; -+ -+ /* doubly linked ordered list of all segments within the arena */ -+ struct _BT_ *pNextSegment; -+ struct _BT_ *pPrevSegment; -+ /* doubly linked un-ordered list of free segments. */ -+ struct _BT_ *pNextFree; -+ struct _BT_ *pPrevFree; -+ /* a user reference associated with this span, user references are -+ * currently only provided in the callback mechanism */ -+ BM_MAPPING *psMapping; -+ -+#if defined(VALIDATE_ARENA_TEST) -+ RESOURCE_DESCRIPTOR eResourceSpan; -+ RESOURCE_TYPE eResourceType; -+ -+ /* This variable provides a reference (used in debug messages) to incompatible -+ boundary tags within the doubly linked ordered list. */ -+ IMG_UINT32 ui32BoundaryTagID; -+#endif -+ -+}; -+typedef struct _BT_ BT; -+ -+ -+/* resource allocation arena */ -+struct _RA_ARENA_ -+{ -+ /* arena name for diagnostics output */ -+ IMG_CHAR *name; -+ -+ /* allocations within this arena are quantum sized */ -+ IMG_SIZE_T uQuantum; -+ -+ /* import interface, if provided */ -+ IMG_BOOL (*pImportAlloc)(IMG_VOID *, -+ IMG_SIZE_T uSize, -+ IMG_SIZE_T *pActualSize, -+ BM_MAPPING **ppsMapping, -+ IMG_UINT32 uFlags, -+ IMG_PVOID pvPrivData, -+ IMG_UINT32 ui32PrivDataLength, -+ IMG_UINTPTR_T *pBase); -+ IMG_VOID (*pImportFree) (IMG_VOID *, -+ IMG_UINTPTR_T, -+ BM_MAPPING *psMapping); -+ IMG_VOID (*pBackingStoreFree) (IMG_VOID *, IMG_SIZE_T, IMG_SIZE_T, IMG_HANDLE); -+ -+ /* arbitrary handle provided by arena owner to be passed into the -+ * import alloc and free hooks */ -+ IMG_VOID *pImportHandle; -+ -+ /* head of list of free boundary tags for indexed by pvr_log2 of the -+ boundary tag size */ -+#define FREE_TABLE_LIMIT 32 -+ -+ /* power-of-two table of free lists */ -+ BT *aHeadFree [FREE_TABLE_LIMIT]; -+ -+ /* resource ordered segment list */ -+ BT *pHeadSegment; -+ BT *pTailSegment; -+ -+ /* segment address to boundary tag hash table */ -+ HASH_TABLE *pSegmentHash; -+ -+#ifdef RA_STATS -+ RA_STATISTICS sStatistics; -+#endif -+ -+#if defined(CONFIG_PROC_FS) && defined(DEBUG) -+#define PROC_NAME_SIZE 64 -+ -+ struct proc_dir_entry* pProcInfo; -+ struct proc_dir_entry* pProcSegs; -+ -+ IMG_BOOL bInitProcEntry; -+#endif -+}; -+/* #define ENABLE_RA_DUMP 1 */ -+#if defined(ENABLE_RA_DUMP) -+IMG_VOID RA_Dump (RA_ARENA *pArena); -+#endif -+ -+#if defined(CONFIG_PROC_FS) && defined(DEBUG) -+ -+static void RA_ProcSeqShowInfo(struct seq_file *sfile, void* el); -+static void* RA_ProcSeqOff2ElementInfo(struct seq_file * sfile, loff_t off); -+ -+static void RA_ProcSeqShowRegs(struct seq_file *sfile, void* el); -+static void* RA_ProcSeqOff2ElementRegs(struct seq_file * sfile, loff_t off); -+ -+#endif /* defined(CONFIG_PROC_FS) && defined(DEBUG) */ -+ -+#ifdef USE_BM_FREESPACE_CHECK -+IMG_VOID CheckBMFreespace(IMG_VOID); -+#endif -+ -+#if defined(CONFIG_PROC_FS) && defined(DEBUG) -+static IMG_CHAR *ReplaceSpaces(IMG_CHAR * const pS) -+{ -+ IMG_CHAR *pT; -+ -+ for(pT = pS; *pT != 0; pT++) -+ { -+ if (*pT == ' ' || *pT == '\t') -+ { -+ *pT = '_'; -+ } -+ } -+ -+ return pS; -+} -+#endif -+ -+/*! -+****************************************************************************** -+ @Function _RequestAllocFail -+ -+ @Description Default callback allocator used if no callback is -+ specified, always fails to allocate further resources to the -+ arena. -+ -+ @Input _h - callback handle -+ @Input _uSize - requested allocation size -+ @Output _pActualSize - actual allocation size -+ @Input _pRef - user reference -+ @Input _uflags - allocation flags -+ @Input _pvPrivData - private data -+ @Input _ui32PrivDataLength - private data length -+ @Input _pBase - receives allocated base -+ -+ @Return IMG_FALSE, this function always fails to allocate. -+******************************************************************************/ -+static IMG_BOOL -+_RequestAllocFail (IMG_VOID *_h, -+ IMG_SIZE_T _uSize, -+ IMG_SIZE_T *_pActualSize, -+ BM_MAPPING **_ppsMapping, -+ IMG_UINT32 _uFlags, -+ IMG_PVOID _pvPrivData, -+ IMG_UINT32 _ui32PrivDataLength, -+ IMG_UINTPTR_T *_pBase) -+{ -+ PVR_UNREFERENCED_PARAMETER (_h); -+ PVR_UNREFERENCED_PARAMETER (_uSize); -+ PVR_UNREFERENCED_PARAMETER (_pActualSize); -+ PVR_UNREFERENCED_PARAMETER (_ppsMapping); -+ PVR_UNREFERENCED_PARAMETER (_uFlags); -+ PVR_UNREFERENCED_PARAMETER (_pBase); -+ PVR_UNREFERENCED_PARAMETER (_pvPrivData); -+ PVR_UNREFERENCED_PARAMETER (_ui32PrivDataLength); -+ -+ return IMG_FALSE; -+} -+ -+/*! -+****************************************************************************** -+ @Function pvr_log2 -+ -+ @Description Computes the floor of the log base 2 of a unsigned integer -+ -+ @Input n - unsigned integer -+ -+ @Return Floor(Log2(n)) -+******************************************************************************/ -+static IMG_UINT32 -+pvr_log2 (IMG_SIZE_T n) -+{ -+ IMG_UINT32 l = 0; -+ n>>=1; -+ while (n>0) -+ { -+ n>>=1; -+ l++; -+ } -+ return l; -+} -+ -+/*! -+****************************************************************************** -+ @Function _SegmentListInsertAfter -+ -+ @Description Insert a boundary tag into an arena segment list after a -+ specified boundary tag. -+ -+ @Input pArena - the arena. -+ @Input pInsertionPoint - the insertion point. -+ @Input pBT - the boundary tag to insert. -+ -+ @Return PVRSRV_ERROR -+******************************************************************************/ -+static PVRSRV_ERROR -+_SegmentListInsertAfter (RA_ARENA *pArena, -+ BT *pInsertionPoint, -+ BT *pBT) -+{ -+ PVR_ASSERT (pArena != IMG_NULL); -+ PVR_ASSERT (pInsertionPoint != IMG_NULL); -+ -+ if ((pInsertionPoint == IMG_NULL) || (pArena == IMG_NULL)) -+ { -+ PVR_DPF ((PVR_DBG_ERROR,"_SegmentListInsertAfter: invalid parameters")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ pBT->pNextSegment = pInsertionPoint->pNextSegment; -+ pBT->pPrevSegment = pInsertionPoint; -+ if (pInsertionPoint->pNextSegment == IMG_NULL) -+ pArena->pTailSegment = pBT; -+ else -+ pInsertionPoint->pNextSegment->pPrevSegment = pBT; -+ pInsertionPoint->pNextSegment = pBT; -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ @Function _SegmentListInsert -+ -+ @Description Insert a boundary tag into an arena segment list at the -+ appropriate point. -+ -+ @Input pArena - the arena. -+ @Input pBT - the boundary tag to insert. -+ -+ @Return None -+******************************************************************************/ -+static PVRSRV_ERROR -+_SegmentListInsert (RA_ARENA *pArena, BT *pBT) -+{ -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ -+ /* insert into the segment chain */ -+ if (pArena->pHeadSegment == IMG_NULL) -+ { -+ pArena->pHeadSegment = pArena->pTailSegment = pBT; -+ pBT->pNextSegment = pBT->pPrevSegment = IMG_NULL; -+ } -+ else -+ { -+ BT *pBTScan; -+ -+ if (pBT->base < pArena->pHeadSegment->base) -+ { -+ /* The base address of pBT is less than the base address of the boundary tag -+ at the head of the list - so insert this boundary tag at the head. */ -+ pBT->pNextSegment = pArena->pHeadSegment; -+ pArena->pHeadSegment->pPrevSegment = pBT; -+ pArena->pHeadSegment = pBT; -+ pBT->pPrevSegment = IMG_NULL; -+ } -+ else -+ { -+ -+ /* The base address of pBT is greater than or equal to that of the boundary tag -+ at the head of the list. Search for the insertion point: pBT must be inserted -+ before the first boundary tag with a greater base value - or at the end of the list. -+ */ -+ pBTScan = pArena->pHeadSegment; -+ -+ while ((pBTScan->pNextSegment != IMG_NULL) && (pBT->base >= pBTScan->pNextSegment->base)) -+ { -+ pBTScan = pBTScan->pNextSegment; -+ } -+ -+ eError = _SegmentListInsertAfter (pArena, pBTScan, pBT); -+ if (eError != PVRSRV_OK) -+ { -+ return eError; -+ } -+ } -+ } -+ return eError; -+} -+ -+/*! -+****************************************************************************** -+ @Function _SegmentListRemove -+ -+ @Description Remove a boundary tag from an arena segment list. -+ -+ @Input pArena - the arena. -+ @Input pBT - the boundary tag to remove. -+ -+ @Return None -+******************************************************************************/ -+static IMG_VOID -+_SegmentListRemove (RA_ARENA *pArena, BT *pBT) -+{ -+ if (pBT->pPrevSegment == IMG_NULL) -+ pArena->pHeadSegment = pBT->pNextSegment; -+ else -+ pBT->pPrevSegment->pNextSegment = pBT->pNextSegment; -+ -+ if (pBT->pNextSegment == IMG_NULL) -+ pArena->pTailSegment = pBT->pPrevSegment; -+ else -+ pBT->pNextSegment->pPrevSegment = pBT->pPrevSegment; -+} -+ -+/*! -+****************************************************************************** -+ @Function _SegmentSplit -+ -+ @Description Split a segment into two, maintain the arena segment list. The -+ boundary tag should not be in the free table. Neither the -+ original or the new neighbour bounary tag will be in the free -+ table. -+ -+ @Input pArena - the arena. -+ @Input pBT - the boundary tag to split. -+ @Input uSize - the required segment size of boundary tag after -+ splitting. -+ -+ @Return New neighbour boundary tag. -+ -+******************************************************************************/ -+static BT * -+_SegmentSplit (RA_ARENA *pArena, BT *pBT, IMG_SIZE_T uSize) -+{ -+ BT *pNeighbour; -+ -+ PVR_ASSERT (pArena != IMG_NULL); -+ -+ if (pArena == IMG_NULL) -+ { -+ PVR_DPF ((PVR_DBG_ERROR,"_SegmentSplit: invalid parameter - pArena")); -+ return IMG_NULL; -+ } -+ -+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(BT), -+ (IMG_VOID **)&pNeighbour, IMG_NULL, -+ "Boundary Tag") != PVRSRV_OK) -+ { -+ return IMG_NULL; -+ } -+ -+ OSMemSet(pNeighbour, 0, sizeof(BT)); -+ -+#if defined(VALIDATE_ARENA_TEST) -+ pNeighbour->ui32BoundaryTagID = ++ui32BoundaryTagID; -+#endif -+ -+ pNeighbour->pPrevSegment = pBT; -+ pNeighbour->pNextSegment = pBT->pNextSegment; -+ if (pBT->pNextSegment == IMG_NULL) -+ pArena->pTailSegment = pNeighbour; -+ else -+ pBT->pNextSegment->pPrevSegment = pNeighbour; -+ pBT->pNextSegment = pNeighbour; -+ -+ pNeighbour->type = btt_free; -+ pNeighbour->uSize = pBT->uSize - uSize; -+ pNeighbour->base = pBT->base + uSize; -+ pNeighbour->psMapping = pBT->psMapping; -+ pBT->uSize = uSize; -+ -+#if defined(VALIDATE_ARENA_TEST) -+ if (pNeighbour->pPrevSegment->eResourceType == IMPORTED_RESOURCE_TYPE) -+ { -+ pNeighbour->eResourceType = IMPORTED_RESOURCE_TYPE; -+ pNeighbour->eResourceSpan = IMPORTED_RESOURCE_SPAN_FREE; -+ } -+ else if (pNeighbour->pPrevSegment->eResourceType == NON_IMPORTED_RESOURCE_TYPE) -+ { -+ pNeighbour->eResourceType = NON_IMPORTED_RESOURCE_TYPE; -+ pNeighbour->eResourceSpan = RESOURCE_SPAN_FREE; -+ } -+ else -+ { -+ PVR_DPF ((PVR_DBG_ERROR,"_SegmentSplit: pNeighbour->pPrevSegment->eResourceType unrecognized")); -+ PVR_DBG_BREAK; -+ } -+#endif -+ -+ return pNeighbour; -+} -+ -+/*! -+****************************************************************************** -+ @Function _FreeListInsert -+ -+ @Description Insert a boundary tag into an arena free table. -+ -+ @Input pArena - the arena. -+ @Input pBT - the boundary tag. -+ -+ @Return None -+ -+******************************************************************************/ -+static IMG_VOID -+_FreeListInsert (RA_ARENA *pArena, BT *pBT) -+{ -+ IMG_UINT32 uIndex; -+ uIndex = pvr_log2 (pBT->uSize); -+ pBT->type = btt_free; -+ pBT->pNextFree = pArena->aHeadFree [uIndex]; -+ pBT->pPrevFree = IMG_NULL; -+ if (pArena->aHeadFree[uIndex] != IMG_NULL) -+ pArena->aHeadFree[uIndex]->pPrevFree = pBT; -+ pArena->aHeadFree [uIndex] = pBT; -+} -+ -+/*! -+****************************************************************************** -+ @Function _FreeListRemove -+ -+ @Description Remove a boundary tag from an arena free table. -+ -+ @Input pArena - the arena. -+ @Input pBT - the boundary tag. -+ -+ @Return None -+ -+******************************************************************************/ -+static IMG_VOID -+_FreeListRemove (RA_ARENA *pArena, BT *pBT) -+{ -+ IMG_UINT32 uIndex; -+ uIndex = pvr_log2 (pBT->uSize); -+ if (pBT->pNextFree != IMG_NULL) -+ pBT->pNextFree->pPrevFree = pBT->pPrevFree; -+ if (pBT->pPrevFree == IMG_NULL) -+ pArena->aHeadFree[uIndex] = pBT->pNextFree; -+ else -+ pBT->pPrevFree->pNextFree = pBT->pNextFree; -+} -+ -+/*! -+****************************************************************************** -+ @Function _BuildSpanMarker -+ -+ @Description Construct a span marker boundary tag. -+ -+ @Input pArena - arena to contain span marker -+ @Input base - the base of the bounary tag. -+ -+ @Return span marker boundary tag -+ -+******************************************************************************/ -+static BT * -+_BuildSpanMarker (IMG_UINTPTR_T base, IMG_SIZE_T uSize) -+{ -+ BT *pBT; -+ -+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(BT), -+ (IMG_VOID **)&pBT, IMG_NULL, -+ "Boundary Tag") != PVRSRV_OK) -+ { -+ return IMG_NULL; -+ } -+ -+ OSMemSet(pBT, 0, sizeof(BT)); -+ -+#if defined(VALIDATE_ARENA_TEST) -+ pBT->ui32BoundaryTagID = ++ui32BoundaryTagID; -+#endif -+ -+ pBT->type = btt_span; -+ pBT->base = base; -+ pBT->uSize = uSize; -+ pBT->psMapping = IMG_NULL; -+ -+ return pBT; -+} -+ -+/*! -+****************************************************************************** -+ @Function _BuildBT -+ -+ @Description Construct a boundary tag for a free segment. -+ -+ @Input base - the base of the resource segment. -+ @Input uSize - the extent of the resouce segment. -+ -+ @Return boundary tag -+ -+******************************************************************************/ -+static BT * -+_BuildBT (IMG_UINTPTR_T base, IMG_SIZE_T uSize) -+{ -+ BT *pBT; -+ -+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(BT), -+ (IMG_VOID **)&pBT, IMG_NULL, -+ "Boundary Tag") != PVRSRV_OK) -+ { -+ return IMG_NULL; -+ } -+ -+ OSMemSet(pBT, 0, sizeof(BT)); -+ -+#if defined(VALIDATE_ARENA_TEST) -+ pBT->ui32BoundaryTagID = ++ui32BoundaryTagID; -+#endif -+ -+ pBT->type = btt_free; -+ pBT->base = base; -+ pBT->uSize = uSize; -+ -+ return pBT; -+} -+ -+/*! -+****************************************************************************** -+ @Function _InsertResource -+ -+ @Description Add a free resource segment to an arena. -+ -+ @Input pArena - the arena. -+ @Input base - the base of the resource segment. -+ @Input uSize - the extent of the resource segment. -+ -+ @Return New bucket pointer -+ IMG_NULL failure -+ -+******************************************************************************/ -+static BT * -+_InsertResource (RA_ARENA *pArena, IMG_UINTPTR_T base, IMG_SIZE_T uSize) -+{ -+ BT *pBT; -+ PVR_ASSERT (pArena!=IMG_NULL); -+ if (pArena == IMG_NULL) -+ { -+ PVR_DPF ((PVR_DBG_ERROR,"_InsertResource: invalid parameter - pArena")); -+ return IMG_NULL; -+ } -+ -+ pBT = _BuildBT (base, uSize); -+ if (pBT != IMG_NULL) -+ { -+ -+#if defined(VALIDATE_ARENA_TEST) -+ pBT->eResourceSpan = RESOURCE_SPAN_FREE; -+ pBT->eResourceType = NON_IMPORTED_RESOURCE_TYPE; -+#endif -+ -+ if (_SegmentListInsert (pArena, pBT) != PVRSRV_OK) -+ { -+ PVR_DPF ((PVR_DBG_ERROR,"_InsertResource: call to _SegmentListInsert failed")); -+ return IMG_NULL; -+ } -+ _FreeListInsert (pArena, pBT); -+#ifdef RA_STATS -+ pArena->sStatistics.uTotalResourceCount+=uSize; -+ pArena->sStatistics.uFreeResourceCount+=uSize; -+ pArena->sStatistics.uSpanCount++; -+#endif -+ } -+ return pBT; -+} -+ -+/*! -+****************************************************************************** -+ @Function _InsertResourceSpan -+ -+ @Description Add a free resource span to an arena, complete with span markers. -+ -+ @Input pArena - the arena. -+ @Input base - the base of the resource segment. -+ @Input uSize - the extent of the resource segment. -+ -+ @Return the boundary tag representing the free resource segment, -+ or IMG_NULL on failure. -+******************************************************************************/ -+static BT * -+_InsertResourceSpan (RA_ARENA *pArena, IMG_UINTPTR_T base, IMG_SIZE_T uSize) -+{ -+ PVRSRV_ERROR eError; -+ BT *pSpanStart; -+ BT *pSpanEnd; -+ BT *pBT; -+ -+ PVR_ASSERT (pArena != IMG_NULL); -+ if (pArena == IMG_NULL) -+ { -+ PVR_DPF ((PVR_DBG_ERROR,"_InsertResourceSpan: invalid parameter - pArena")); -+ return IMG_NULL; -+ } -+ -+ PVR_DPF ((PVR_DBG_MESSAGE, -+ "RA_InsertResourceSpan: arena='%s', base=0x" UINTPTR_FMT ", size=0x%" SIZE_T_FMT_LEN "x", -+ pArena->name, base, uSize)); -+ -+ pSpanStart = _BuildSpanMarker (base, uSize); -+ if (pSpanStart == IMG_NULL) -+ { -+ goto fail_start; -+ } -+ -+#if defined(VALIDATE_ARENA_TEST) -+ pSpanStart->eResourceSpan = IMPORTED_RESOURCE_SPAN_START; -+ pSpanStart->eResourceType = IMPORTED_RESOURCE_TYPE; -+#endif -+ -+ pSpanEnd = _BuildSpanMarker (base + uSize, 0); -+ if (pSpanEnd == IMG_NULL) -+ { -+ goto fail_end; -+ } -+ -+#if defined(VALIDATE_ARENA_TEST) -+ pSpanEnd->eResourceSpan = IMPORTED_RESOURCE_SPAN_END; -+ pSpanEnd->eResourceType = IMPORTED_RESOURCE_TYPE; -+#endif -+ -+ pBT = _BuildBT (base, uSize); -+ if (pBT == IMG_NULL) -+ { -+ goto fail_bt; -+ } -+ -+#if defined(VALIDATE_ARENA_TEST) -+ pBT->eResourceSpan = IMPORTED_RESOURCE_SPAN_FREE; -+ pBT->eResourceType = IMPORTED_RESOURCE_TYPE; -+#endif -+ -+ eError = _SegmentListInsert (pArena, pSpanStart); -+ if (eError != PVRSRV_OK) -+ { -+ goto fail_SegListInsert; -+ } -+ -+ eError = _SegmentListInsertAfter (pArena, pSpanStart, pBT); -+ if (eError != PVRSRV_OK) -+ { -+ goto fail_SegListInsert; -+ } -+ -+ _FreeListInsert (pArena, pBT); -+ -+ eError = _SegmentListInsertAfter (pArena, pBT, pSpanEnd); -+ if (eError != PVRSRV_OK) -+ { -+ goto fail_SegListInsert; -+ } -+ -+#ifdef RA_STATS -+ pArena->sStatistics.uTotalResourceCount+=uSize; -+/* pArena->sStatistics.uFreeResourceCount+=uSize; -+ This has got to be wrong as uFreeResourceCount ends -+ up larger than uTotalResourceCount by uTotalResourceCount -+ - allocated memory -+*/ -+#endif -+ return pBT; -+ -+ fail_SegListInsert: -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pBT, IMG_NULL); -+ /*not nulling pointer, out of scope*/ -+ fail_bt: -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pSpanEnd, IMG_NULL); -+ /*not nulling pointer, out of scope*/ -+ fail_end: -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pSpanStart, IMG_NULL); -+ /*not nulling pointer, out of scope*/ -+ fail_start: -+ return IMG_NULL; -+} -+ -+/*! -+****************************************************************************** -+ @Function _FreeBT -+ -+ @Description Free a boundary tag taking care of the segment list and the -+ boundary tag free table. -+ -+ @Input pArena - the arena. -+ @Input pBT - the boundary tag to free. -+ @Input bFreeBackingStore - Should backing for the memory be freed -+ as well. -+ @Return None -+******************************************************************************/ -+static IMG_VOID -+_FreeBT (RA_ARENA *pArena, BT *pBT, IMG_BOOL bFreeBackingStore) -+{ -+ BT *pNeighbour; -+ IMG_UINTPTR_T uOrigBase; -+ IMG_SIZE_T uOrigSize; -+ -+ PVR_ASSERT (pArena!=IMG_NULL); -+ PVR_ASSERT (pBT!=IMG_NULL); -+ -+ if ((pArena == IMG_NULL) || (pBT == IMG_NULL)) -+ { -+ PVR_DPF ((PVR_DBG_ERROR,"_FreeBT: invalid parameter")); -+ return; -+ } -+ -+#ifdef RA_STATS -+ pArena->sStatistics.uLiveSegmentCount--; -+ pArena->sStatistics.uFreeSegmentCount++; -+ pArena->sStatistics.uFreeResourceCount+=pBT->uSize; -+#endif -+ -+ uOrigBase = pBT->base; -+ uOrigSize = pBT->uSize; -+ -+ /* try and coalesce with left neighbour */ -+ pNeighbour = pBT->pPrevSegment; -+ if (pNeighbour!=IMG_NULL -+ && pNeighbour->type == btt_free -+ && pNeighbour->base + pNeighbour->uSize == pBT->base) -+ { -+ _FreeListRemove (pArena, pNeighbour); -+ _SegmentListRemove (pArena, pNeighbour); -+ pBT->base = pNeighbour->base; -+ pBT->uSize += pNeighbour->uSize; -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pNeighbour, IMG_NULL); -+ /*not nulling original pointer, already overwritten*/ -+#ifdef RA_STATS -+ pArena->sStatistics.uFreeSegmentCount--; -+#endif -+ } -+ -+ /* try to coalesce with right neighbour */ -+ pNeighbour = pBT->pNextSegment; -+ if (pNeighbour!=IMG_NULL -+ && pNeighbour->type == btt_free -+ && pBT->base + pBT->uSize == pNeighbour->base) -+ { -+ _FreeListRemove (pArena, pNeighbour); -+ _SegmentListRemove (pArena, pNeighbour); -+ pBT->uSize += pNeighbour->uSize; -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pNeighbour, IMG_NULL); -+ /*not nulling original pointer, already overwritten*/ -+#ifdef RA_STATS -+ pArena->sStatistics.uFreeSegmentCount--; -+#endif -+ } -+ -+ /* try to free backing store memory. */ -+ if (pArena->pBackingStoreFree != IMG_NULL && bFreeBackingStore) -+ { -+ IMG_UINTPTR_T uRoundedStart, uRoundedEnd; -+ -+ /* Work out the first address we might be able to free. */ -+ uRoundedStart = (uOrigBase / pArena->uQuantum) * pArena->uQuantum; -+ /* If a span is still using that address then leave it. */ -+ if (uRoundedStart < pBT->base) -+ { -+ uRoundedStart += pArena->uQuantum; -+ } -+ -+ /* Work out the last address we might be able to free. */ -+ uRoundedEnd = ((uOrigBase + uOrigSize + pArena->uQuantum - 1) / pArena->uQuantum) * pArena->uQuantum; -+ /* If a span is still using that addres then leave it. */ -+ if (uRoundedEnd > (pBT->base + pBT->uSize)) -+ { -+ uRoundedEnd -= pArena->uQuantum; -+ } -+ -+ if (uRoundedStart < uRoundedEnd) -+ { -+ pArena->pBackingStoreFree(pArena->pImportHandle, (IMG_SIZE_T)uRoundedStart, (IMG_SIZE_T)uRoundedEnd, (IMG_HANDLE)0); -+ } -+ } -+ -+ if (pBT->pNextSegment!=IMG_NULL && pBT->pNextSegment->type == btt_span -+ && pBT->pPrevSegment!=IMG_NULL && pBT->pPrevSegment->type == btt_span) -+ { -+ BT *next = pBT->pNextSegment; -+ BT *prev = pBT->pPrevSegment; -+ _SegmentListRemove (pArena, next); -+ _SegmentListRemove (pArena, prev); -+ _SegmentListRemove (pArena, pBT); -+ pArena->pImportFree (pArena->pImportHandle, pBT->base, pBT->psMapping); -+#ifdef RA_STATS -+ pArena->sStatistics.uSpanCount--; -+ pArena->sStatistics.uExportCount++; -+ pArena->sStatistics.uFreeSegmentCount--; -+ pArena->sStatistics.uFreeResourceCount-=pBT->uSize; -+ pArena->sStatistics.uTotalResourceCount-=pBT->uSize; -+#endif -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), next, IMG_NULL); -+ /*not nulling original pointer, already overwritten*/ -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), prev, IMG_NULL); -+ /*not nulling original pointer, already overwritten*/ -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pBT, IMG_NULL); -+ /*not nulling pointer, copy on stack*/ -+ } -+ else -+ _FreeListInsert (pArena, pBT); -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function _AttemptAllocAligned -+ -+ @Description Attempt an allocation from an arena. -+ -+ @Input pArena - the arena. -+ @Input uSize - the requested allocation size. -+ @Output ppsMapping - the user references associated with -+ the allocated segment. -+ @Input flags - allocation flags -+ @Input uAlignment - required uAlignment, or 0 -+ @Input uAlignmentOffset -+ @Output base - allocated resource base -+ -+ @Return IMG_FALSE failure -+ IMG_TRUE success -+******************************************************************************/ -+static IMG_BOOL -+_AttemptAllocAligned (RA_ARENA *pArena, -+ IMG_SIZE_T uSize, -+ BM_MAPPING **ppsMapping, -+ IMG_UINT32 uFlags, -+ IMG_UINT32 uAlignment, -+ IMG_UINT32 uAlignmentOffset, -+ IMG_UINTPTR_T *base) -+{ -+ IMG_UINT32 uIndex; -+ PVR_ASSERT (pArena!=IMG_NULL); -+ if (pArena == IMG_NULL) -+ { -+ PVR_DPF ((PVR_DBG_ERROR,"_AttemptAllocAligned: invalid parameter - pArena")); -+ return IMG_FALSE; -+ } -+ -+ if (uAlignment>1) -+ uAlignmentOffset %= uAlignment; -+ -+ /* search for a near fit free boundary tag, start looking at the -+ pvr_log2 free table for our required size and work on up the -+ table. */ -+ uIndex = pvr_log2 (uSize); -+ -+ while (uIndex < FREE_TABLE_LIMIT && pArena->aHeadFree[uIndex]==IMG_NULL) -+ uIndex++; -+ -+ while (uIndex < FREE_TABLE_LIMIT) -+ { -+ if (pArena->aHeadFree[uIndex]!=IMG_NULL) -+ { -+ /* we have a cached free boundary tag */ -+ BT *pBT; -+ -+ pBT = pArena->aHeadFree [uIndex]; -+ while (pBT!=IMG_NULL) -+ { -+ IMG_UINTPTR_T aligned_base; -+ -+ if (uAlignment>1) -+ aligned_base = (pBT->base + uAlignmentOffset + uAlignment - 1) / uAlignment * uAlignment - uAlignmentOffset; -+ else -+ aligned_base = pBT->base; -+ PVR_DPF ((PVR_DBG_MESSAGE, -+ "RA_AttemptAllocAligned: pBT-base=0x" UINTPTR_FMT " " -+ "pBT-size=0x%" SIZE_T_FMT_LEN "x alignedbase=0x" -+ UINTPTR_FMT " size=0x%" SIZE_T_FMT_LEN "x", -+ pBT->base, -+ pBT->uSize, -+ aligned_base, -+ uSize)); -+ -+ if (pBT->base + pBT->uSize >= aligned_base + uSize) -+ { -+ if(!pBT->psMapping || pBT->psMapping->ui32Flags == uFlags) -+ { -+ _FreeListRemove (pArena, pBT); -+ -+ PVR_ASSERT (pBT->type == btt_free); -+ -+#ifdef RA_STATS -+ pArena->sStatistics.uLiveSegmentCount++; -+ pArena->sStatistics.uFreeSegmentCount--; -+ pArena->sStatistics.uFreeResourceCount-=pBT->uSize; -+#endif -+ -+ /* with uAlignment we might need to discard the front of this segment */ -+ if (aligned_base > pBT->base) -+ { -+ BT *pNeighbour; -+ pNeighbour = _SegmentSplit (pArena, pBT, (IMG_SIZE_T)(aligned_base - pBT->base)); -+ /* partition the buffer, create a new boundary tag */ -+ if (pNeighbour==IMG_NULL) -+ { -+ PVR_DPF ((PVR_DBG_ERROR,"_AttemptAllocAligned: Front split failed")); -+ /* Put pBT back in the list */ -+ _FreeListInsert (pArena, pBT); -+ return IMG_FALSE; -+ } -+ -+ _FreeListInsert (pArena, pBT); -+ #ifdef RA_STATS -+ pArena->sStatistics.uFreeSegmentCount++; -+ pArena->sStatistics.uFreeResourceCount+=pBT->uSize; -+ #endif -+ pBT = pNeighbour; -+ } -+ -+ /* the segment might be too big, if so, discard the back of the segment */ -+ if (pBT->uSize > uSize) -+ { -+ BT *pNeighbour; -+ pNeighbour = _SegmentSplit (pArena, pBT, uSize); -+ /* partition the buffer, create a new boundary tag */ -+ if (pNeighbour==IMG_NULL) -+ { -+ PVR_DPF ((PVR_DBG_ERROR,"_AttemptAllocAligned: Back split failed")); -+ /* Put pBT back in the list */ -+ _FreeListInsert (pArena, pBT); -+ return IMG_FALSE; -+ } -+ -+ _FreeListInsert (pArena, pNeighbour); -+ #ifdef RA_STATS -+ pArena->sStatistics.uFreeSegmentCount++; -+ pArena->sStatistics.uFreeResourceCount+=pNeighbour->uSize; -+ #endif -+ } -+ -+ pBT->type = btt_live; -+ -+#if defined(VALIDATE_ARENA_TEST) -+ if (pBT->eResourceType == IMPORTED_RESOURCE_TYPE) -+ { -+ pBT->eResourceSpan = IMPORTED_RESOURCE_SPAN_LIVE; -+ } -+ else if (pBT->eResourceType == NON_IMPORTED_RESOURCE_TYPE) -+ { -+ pBT->eResourceSpan = RESOURCE_SPAN_LIVE; -+ } -+ else -+ { -+ PVR_DPF ((PVR_DBG_ERROR,"_AttemptAllocAligned ERROR: pBT->eResourceType unrecognized")); -+ PVR_DBG_BREAK; -+ } -+#endif -+ if (!HASH_Insert (pArena->pSegmentHash, pBT->base, (IMG_UINTPTR_T) pBT)) -+ { -+ _FreeBT (pArena, pBT, IMG_FALSE); -+ return IMG_FALSE; -+ } -+ -+ if (ppsMapping!=IMG_NULL) -+ *ppsMapping = pBT->psMapping; -+ -+ *base = pBT->base; -+ -+ return IMG_TRUE; -+ } -+ else -+ { -+ PVR_DPF ((PVR_DBG_MESSAGE, -+ "AttemptAllocAligned: mismatch in flags. Import has %x, request was %x", pBT->psMapping->ui32Flags, uFlags)); -+ -+ } -+ } -+ pBT = pBT->pNextFree; -+ } -+ -+ } -+ uIndex++; -+ } -+ -+ return IMG_FALSE; -+} -+ -+ -+ -+/*! -+****************************************************************************** -+ @Function RA_Create -+ -+ @Description To create a resource arena. -+ -+ @Input name - the name of the arena for diagnostic purposes. -+ @Input base - the base of an initial resource span or 0. -+ @Input uSize - the size of an initial resource span or 0. -+ @Input uQuantum - the arena allocation quantum. -+ @Input alloc - a resource allocation callback or 0. -+ @Input free - a resource de-allocation callback or 0. -+ @Input backingstore_free - a callback to free resources for spans or 0. -+ @Input pImportHandle - handle passed to alloc and free or 0. -+ -+ @Return arena handle, or IMG_NULL. -+******************************************************************************/ -+RA_ARENA * -+RA_Create (IMG_CHAR *name, -+ IMG_UINTPTR_T base, -+ IMG_SIZE_T uSize, -+ BM_MAPPING *psMapping, -+ IMG_SIZE_T uQuantum, -+ IMG_BOOL (*imp_alloc)(IMG_VOID *, IMG_SIZE_T uSize, IMG_SIZE_T *pActualSize, -+ BM_MAPPING **ppsMapping, IMG_UINT32 _flags, -+ IMG_PVOID pvPrivData, IMG_UINT32 ui32PrivDataLength, -+ IMG_UINTPTR_T *pBase), -+ IMG_VOID (*imp_free) (IMG_VOID *, IMG_UINTPTR_T, BM_MAPPING *), -+ IMG_VOID (*backingstore_free) (IMG_VOID*, IMG_SIZE_T, IMG_SIZE_T, IMG_HANDLE), -+ IMG_VOID *pImportHandle) -+{ -+ RA_ARENA *pArena; -+ BT *pBT; -+ IMG_INT i; -+ -+ PVR_DPF ((PVR_DBG_MESSAGE, -+ "RA_Create: name='%s', base=0x" UINTPTR_FMT ", uSize=0x%" SIZE_T_FMT_LEN "x, alloc=0x%p, free=0x%p", -+ name, base, uSize, imp_alloc, imp_free)); -+ -+ -+ if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof (*pArena), -+ (IMG_VOID **)&pArena, IMG_NULL, -+ "Resource Arena") != PVRSRV_OK) -+ { -+ goto arena_fail; -+ } -+ -+ pArena->name = name; -+ pArena->pImportAlloc = (imp_alloc!=IMG_NULL) ? imp_alloc : &_RequestAllocFail; -+ pArena->pImportFree = imp_free; -+ pArena->pBackingStoreFree = backingstore_free; -+ pArena->pImportHandle = pImportHandle; -+ for (i=0; i<FREE_TABLE_LIMIT; i++) -+ pArena->aHeadFree[i] = IMG_NULL; -+ pArena->pHeadSegment = IMG_NULL; -+ pArena->pTailSegment = IMG_NULL; -+ pArena->uQuantum = uQuantum; -+ -+#ifdef RA_STATS -+ pArena->sStatistics.uSpanCount = 0; -+ pArena->sStatistics.uLiveSegmentCount = 0; -+ pArena->sStatistics.uFreeSegmentCount = 0; -+ pArena->sStatistics.uFreeResourceCount = 0; -+ pArena->sStatistics.uTotalResourceCount = 0; -+ pArena->sStatistics.uCumulativeAllocs = 0; -+ pArena->sStatistics.uCumulativeFrees = 0; -+ pArena->sStatistics.uImportCount = 0; -+ pArena->sStatistics.uExportCount = 0; -+#endif -+ -+#if defined(CONFIG_PROC_FS) && defined(DEBUG) -+ if(strcmp(pArena->name,"") != 0) -+ { -+ IMG_INT ret; -+ IMG_CHAR szProcInfoName[PROC_NAME_SIZE]; -+ IMG_CHAR szProcSegsName[PROC_NAME_SIZE]; -+ struct proc_dir_entry* (*pfnCreateProcEntrySeq)(const IMG_CHAR *, -+ IMG_VOID*, -+ pvr_next_proc_seq_t, -+ pvr_show_proc_seq_t, -+ pvr_off2element_proc_seq_t, -+ pvr_startstop_proc_seq_t, -+ write_proc_t); -+ -+ pArena->bInitProcEntry = !PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL); -+ -+ /* Don't put shared heap info into a per process /proc subdirectory */ -+ pfnCreateProcEntrySeq = pArena->bInitProcEntry ? CreateProcEntrySeq : CreatePerProcessProcEntrySeq; -+ -+ ret = snprintf(szProcInfoName, sizeof(szProcInfoName), "ra_info_%s", pArena->name); -+ if (ret > 0 && ret < sizeof(szProcInfoName)) -+ { -+ pArena->pProcInfo = pfnCreateProcEntrySeq(ReplaceSpaces(szProcInfoName), pArena, NULL, -+ RA_ProcSeqShowInfo, RA_ProcSeqOff2ElementInfo, NULL, NULL); -+ } -+ else -+ { -+ pArena->pProcInfo = 0; -+ PVR_DPF((PVR_DBG_ERROR, "RA_Create: couldn't create ra_info proc entry for arena %s", pArena->name)); -+ } -+ -+ ret = snprintf(szProcSegsName, sizeof(szProcSegsName), "ra_segs_%s", pArena->name); -+ if (ret > 0 && ret < sizeof(szProcInfoName)) -+ { -+ pArena->pProcSegs = pfnCreateProcEntrySeq(ReplaceSpaces(szProcSegsName), pArena, NULL, -+ RA_ProcSeqShowRegs, RA_ProcSeqOff2ElementRegs, NULL, NULL); -+ } -+ else -+ { -+ pArena->pProcSegs = 0; -+ PVR_DPF((PVR_DBG_ERROR, "RA_Create: couldn't create ra_segs proc entry for arena %s", pArena->name)); -+ } -+ } -+#endif /* defined(CONFIG_PROC_FS) && defined(DEBUG) */ -+ -+ pArena->pSegmentHash = HASH_Create (MINIMUM_HASH_SIZE); -+ if (pArena->pSegmentHash==IMG_NULL) -+ { -+ goto hash_fail; -+ } -+ if (uSize>0) -+ { -+ uSize = (uSize + uQuantum - 1) / uQuantum * uQuantum; -+ pBT = _InsertResource (pArena, base, uSize); -+ if (pBT == IMG_NULL) -+ { -+ goto insert_fail; -+ } -+ pBT->psMapping = psMapping; -+ -+ } -+ return pArena; -+ -+insert_fail: -+ HASH_Delete (pArena->pSegmentHash); -+hash_fail: -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RA_ARENA), pArena, IMG_NULL); -+ /*not nulling pointer, out of scope*/ -+arena_fail: -+ return IMG_NULL; -+} -+ -+/*! -+****************************************************************************** -+ @Function RA_Delete -+ -+ @Description To delete a resource arena. All resources allocated from -+ the arena must be freed before deleting the arena. -+ -+ @Input pArena - the arena to delete. -+ -+ @Return None -+******************************************************************************/ -+IMG_VOID -+RA_Delete (RA_ARENA *pArena) -+{ -+ IMG_UINT32 uIndex; -+ -+ PVR_ASSERT(pArena != IMG_NULL); -+ -+ if (pArena == IMG_NULL) -+ { -+ PVR_DPF ((PVR_DBG_ERROR,"RA_Delete: invalid parameter - pArena")); -+ return; -+ } -+ -+ PVR_DPF ((PVR_DBG_MESSAGE, -+ "RA_Delete: name='%s'", pArena->name)); -+ -+ for (uIndex=0; uIndex<FREE_TABLE_LIMIT; uIndex++) -+ pArena->aHeadFree[uIndex] = IMG_NULL; -+ -+ while (pArena->pHeadSegment != IMG_NULL) -+ { -+ BT *pBT = pArena->pHeadSegment; -+ -+ if (pBT->type != btt_free) -+ { -+ PVR_DPF ((PVR_DBG_ERROR,"RA_Delete: allocations still exist in the arena that is being destroyed")); -+ PVR_DPF ((PVR_DBG_ERROR,"Likely Cause: client drivers not freeing alocations before destroying devmemcontext")); -+ PVR_DPF ((PVR_DBG_ERROR,"RA_Delete: base = 0x" UINTPTR_FMT " size=0x%" SIZE_T_FMT_LEN "x", pBT->base, pBT->uSize)); -+ } -+ -+ _SegmentListRemove (pArena, pBT); -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BT), pBT, IMG_NULL); -+ /*not nulling original pointer, it has changed*/ -+#ifdef RA_STATS -+ pArena->sStatistics.uSpanCount--; -+#endif -+ } -+#if defined(CONFIG_PROC_FS) && defined(DEBUG) -+ { -+ IMG_VOID (*pfnRemoveProcEntrySeq)(struct proc_dir_entry*); -+ -+ pfnRemoveProcEntrySeq = pArena->bInitProcEntry ? RemoveProcEntrySeq : RemovePerProcessProcEntrySeq; -+ -+ if (pArena->pProcInfo != 0) -+ { -+ pfnRemoveProcEntrySeq( pArena->pProcInfo ); -+ } -+ -+ if (pArena->pProcSegs != 0) -+ { -+ pfnRemoveProcEntrySeq( pArena->pProcSegs ); -+ } -+ } -+#endif -+ HASH_Delete (pArena->pSegmentHash); -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RA_ARENA), pArena, IMG_NULL); -+ /*not nulling pointer, copy on stack*/ -+} -+ -+/*! -+****************************************************************************** -+ @Function RA_TestDelete -+ -+ @Description To test whether it is safe to delete a resource arena. If any -+ allocations have not been freed, the RA must not be deleted. -+ -+ @Input pArena - the arena to test. -+ -+ @Return IMG_BOOL - IMG_TRUE if is safe to go on and call RA_Delete. -+******************************************************************************/ -+IMG_BOOL -+RA_TestDelete (RA_ARENA *pArena) -+{ -+ PVR_ASSERT(pArena != IMG_NULL); -+ -+ if (pArena != IMG_NULL) -+ { -+ while (pArena->pHeadSegment != IMG_NULL) -+ { -+ BT *pBT = pArena->pHeadSegment; -+ if (pBT->type != btt_free) -+ { -+ PVR_DPF ((PVR_DBG_ERROR,"RA_TestDelete: detected resource leak!")); -+ PVR_DPF ((PVR_DBG_ERROR,"RA_TestDelete: base = 0x" UINTPTR_FMT " size=0x%" SIZE_T_FMT_LEN "x", pBT->base, pBT->uSize)); -+ return IMG_FALSE; -+ } -+ } -+ } -+ -+ return IMG_TRUE; -+} -+ -+/*! -+****************************************************************************** -+ @Function RA_Add -+ -+ @Description To add a resource span to an arena. The span must not -+ overlapp with any span previously added to the arena. -+ -+ @Input pArena - the arena to add a span into. -+ @Input base - the base of the span. -+ @Input uSize - the extent of the span. -+ -+ @Return IMG_TRUE - Success -+ IMG_FALSE - failure -+******************************************************************************/ -+IMG_BOOL -+RA_Add (RA_ARENA *pArena, IMG_UINTPTR_T base, IMG_SIZE_T uSize) -+{ -+ PVR_ASSERT (pArena != IMG_NULL); -+ -+ if (pArena == IMG_NULL) -+ { -+ PVR_DPF ((PVR_DBG_ERROR,"RA_Add: invalid parameter - pArena")); -+ return IMG_FALSE; -+ } -+ -+ PVR_DPF ((PVR_DBG_MESSAGE, -+ "RA_Add: name='%s', base=0x" UINTPTR_FMT ", size=0x%" SIZE_T_FMT_LEN "x", pArena->name, base, uSize)); -+ -+ uSize = (uSize + pArena->uQuantum - 1) / pArena->uQuantum * pArena->uQuantum; -+ return ((IMG_BOOL)(_InsertResource (pArena, base, uSize) != IMG_NULL)); -+} -+ -+/*! -+****************************************************************************** -+ @Function RA_Alloc -+ -+ @Description To allocate resource from an arena. -+ -+ @Input pArena - the arena -+ @Input uRequestSize - the size of resource segment requested. -+ @Output pActualSize - the actual size of resource segment -+ allocated, typcially rounded up by quantum. -+ @Output ppsMapping - the user reference associated with allocated resource span. -+ @Input uFlags - flags influencing allocation policy. -+ @Input uAlignment - the uAlignment constraint required for the -+ allocated segment, use 0 if uAlignment not required. -+ @Input uAlignmentOffset -+ @Input pvPrivData - opaque private data passed through to allocator -+ @Input ui32PrivDataLength - length of opaque private data -+ -+ @Output base - allocated base resource -+ -+ @Return IMG_TRUE - success -+ IMG_FALSE - failure -+******************************************************************************/ -+IMG_BOOL -+RA_Alloc (RA_ARENA *pArena, -+ IMG_SIZE_T uRequestSize, -+ IMG_SIZE_T *pActualSize, -+ BM_MAPPING **ppsMapping, -+ IMG_UINT32 uFlags, -+ IMG_UINT32 uAlignment, -+ IMG_UINT32 uAlignmentOffset, -+ IMG_PVOID pvPrivData, -+ IMG_UINT32 ui32PrivDataLength, -+ IMG_UINTPTR_T *base) -+{ -+ IMG_BOOL bResult; -+ IMG_SIZE_T uSize = uRequestSize; -+ -+ PVR_ASSERT (pArena!=IMG_NULL); -+ -+ if (pArena == IMG_NULL) -+ { -+ PVR_DPF ((PVR_DBG_ERROR,"RA_Alloc: invalid parameter - pArena")); -+ return IMG_FALSE; -+ } -+ -+#if defined(VALIDATE_ARENA_TEST) -+ ValidateArena(pArena); -+#endif -+ -+#ifdef USE_BM_FREESPACE_CHECK -+ CheckBMFreespace(); -+#endif -+ -+ if (pActualSize != IMG_NULL) -+ { -+ *pActualSize = uSize; -+ } -+ -+ PVR_DPF ((PVR_DBG_MESSAGE, -+ "RA_Alloc: arena='%s', size=0x%" SIZE_T_FMT_LEN "x(0x%" SIZE_T_FMT_LEN "x), alignment=0x%x, offset=0x%x", -+ pArena->name, uSize, uRequestSize, uAlignment, uAlignmentOffset)); -+ -+ /* if allocation failed then we might have an import source which -+ can provide more resource, else we will have to fail the -+ allocation to the caller. */ -+ bResult = _AttemptAllocAligned (pArena, uSize, ppsMapping, uFlags, -+ uAlignment, uAlignmentOffset, base); -+ if (!bResult) -+ { -+ BM_MAPPING *psImportMapping; -+ IMG_UINTPTR_T import_base; -+ IMG_SIZE_T uImportSize = uSize; -+ -+ /* -+ Ensure that we allocate sufficient space to meet the uAlignment -+ constraint -+ */ -+ if (uAlignment > pArena->uQuantum) -+ { -+ uImportSize += (uAlignment - 1); -+ } -+ -+ /* ensure that we import according to the quanta of this arena */ -+ uImportSize = ((uImportSize + pArena->uQuantum - 1)/pArena->uQuantum)*pArena->uQuantum; -+ -+ bResult = -+ pArena->pImportAlloc (pArena->pImportHandle, uImportSize, &uImportSize, -+ &psImportMapping, uFlags, -+ pvPrivData, ui32PrivDataLength, &import_base); -+ if (bResult) -+ { -+ BT *pBT; -+ pBT = _InsertResourceSpan (pArena, import_base, uImportSize); -+ /* successfully import more resource, create a span to -+ represent it and retry the allocation attempt */ -+ if (pBT == IMG_NULL) -+ { -+ /* insufficient resources to insert the newly acquired span, -+ so free it back again */ -+ pArena->pImportFree(pArena->pImportHandle, import_base, -+ psImportMapping); -+ PVR_DPF ((PVR_DBG_MESSAGE, -+ "RA_Alloc: name='%s', size=0x%" SIZE_T_FMT_LEN "x failed!", -+ pArena->name, uSize)); -+ /* RA_Dump (arena); */ -+ return IMG_FALSE; -+ } -+ pBT->psMapping = psImportMapping; -+#ifdef RA_STATS -+ pArena->sStatistics.uFreeSegmentCount++; -+ pArena->sStatistics.uFreeResourceCount += uImportSize; -+ pArena->sStatistics.uImportCount++; -+ pArena->sStatistics.uSpanCount++; -+#endif -+ bResult = _AttemptAllocAligned(pArena, uSize, ppsMapping, uFlags, -+ uAlignment, uAlignmentOffset, -+ base); -+ if (!bResult) -+ { -+ PVR_DPF ((PVR_DBG_MESSAGE, -+ "RA_Alloc: name='%s' uAlignment failed!", -+ pArena->name)); -+ } -+ } -+ } -+#ifdef RA_STATS -+ if (bResult) -+ pArena->sStatistics.uCumulativeAllocs++; -+#endif -+ -+ PVR_DPF ((PVR_DBG_MESSAGE, -+ "RA_Alloc: name='%s', size=0x%" SIZE_T_FMT_LEN "x, *base=0x" UINTPTR_FMT " = %d", -+ pArena->name, uSize, *base, bResult)); -+ -+ /* RA_Dump (pArena); -+ ra_stats (pArena); -+ */ -+ -+#if defined(VALIDATE_ARENA_TEST) -+ ValidateArena(pArena); -+#endif -+ -+ return bResult; -+} -+ -+ -+#if defined(VALIDATE_ARENA_TEST) -+ -+/*! -+****************************************************************************** -+ @Function ValidateArena -+ -+ @Description Validate an arena by checking that adjacent members of the -+ double linked ordered list are compatible. PVR_DBG_BREAK and -+ PVR_DPF messages are used when an error is detected. -+ NOTE: A DEBUG build is required for PVR_DBG_BREAK and PVR_DPF -+ to operate. -+ -+ @Input pArena - the arena -+ -+ @Return 0 -+******************************************************************************/ -+IMG_UINT32 ValidateArena(RA_ARENA *pArena) -+{ -+ BT* pSegment; -+ RESOURCE_DESCRIPTOR eNextSpan; -+ -+ pSegment = pArena->pHeadSegment; -+ -+ if (pSegment == IMG_NULL) -+ { -+ return 0; -+ } -+ -+ if (pSegment->eResourceType == IMPORTED_RESOURCE_TYPE) -+ { -+ PVR_ASSERT(pSegment->eResourceSpan == IMPORTED_RESOURCE_SPAN_START); -+ -+ while (pSegment->pNextSegment) -+ { -+ eNextSpan = pSegment->pNextSegment->eResourceSpan; -+ -+ switch (pSegment->eResourceSpan) -+ { -+ case IMPORTED_RESOURCE_SPAN_LIVE: -+ -+ if (!((eNextSpan == IMPORTED_RESOURCE_SPAN_LIVE) || -+ (eNextSpan == IMPORTED_RESOURCE_SPAN_FREE) || -+ (eNextSpan == IMPORTED_RESOURCE_SPAN_END))) -+ { -+ /* error - next span must be live, free or end */ -+ PVR_DPF((PVR_DBG_ERROR, -+ "ValidateArena ERROR: adjacent boundary tags %d (base=0x" UINTPTR_FMT -+ ") and %d (base=0x" UINTPTR_FMT ") are incompatible (arena: %s)", -+ pSegment->ui32BoundaryTagID, -+ pSegment->base, -+ pSegment->pNextSegment->ui32BoundaryTagID, -+ pSegment->pNextSegment->base, -+ pArena->name)); -+ -+ PVR_DBG_BREAK; -+ } -+ break; -+ -+ case IMPORTED_RESOURCE_SPAN_FREE: -+ -+ if (!((eNextSpan == IMPORTED_RESOURCE_SPAN_LIVE) || -+ (eNextSpan == IMPORTED_RESOURCE_SPAN_END))) -+ { -+ /* error - next span must be live or end */ -+ PVR_DPF((PVR_DBG_ERROR, -+ "ValidateArena ERROR: adjacent boundary tags %d (base=0x" UINTPTR_FMT -+ ") and %d (base=0x" UINTPTR_FMT ") are incompatible (arena: %s)", -+ pSegment->ui32BoundaryTagID, -+ pSegment->base, -+ pSegment->pNextSegment->ui32BoundaryTagID, -+ pSegment->pNextSegment->base, -+ pArena->name)); -+ -+ PVR_DBG_BREAK; -+ } -+ break; -+ -+ case IMPORTED_RESOURCE_SPAN_END: -+ -+ if ((eNextSpan == IMPORTED_RESOURCE_SPAN_LIVE) || -+ (eNextSpan == IMPORTED_RESOURCE_SPAN_FREE) || -+ (eNextSpan == IMPORTED_RESOURCE_SPAN_END)) -+ { -+ /* error - next span cannot be live, free or end */ -+ PVR_DPF((PVR_DBG_ERROR, -+ "ValidateArena ERROR: adjacent boundary tags %d (base=0x" UINTPTR_FMT -+ ") and %d (base=0x" UINTPTR_FMT ") are incompatible (arena: %s)", -+ pSegment->ui32BoundaryTagID, -+ pSegment->base, -+ pSegment->pNextSegment->ui32BoundaryTagID, -+ pSegment->pNextSegment->base, -+ pArena->name)); -+ -+ PVR_DBG_BREAK; -+ } -+ break; -+ -+ -+ case IMPORTED_RESOURCE_SPAN_START: -+ -+ if (!((eNextSpan == IMPORTED_RESOURCE_SPAN_LIVE) || -+ (eNextSpan == IMPORTED_RESOURCE_SPAN_FREE))) -+ { -+ /* error - next span must be live or free */ -+ PVR_DPF((PVR_DBG_ERROR, -+ "ValidateArena ERROR: adjacent boundary tags %d (base=0x" UINTPTR_FMT -+ ") and %d (base=0x" UINTPTR_FMT ") are incompatible (arena: %s)", -+ pSegment->ui32BoundaryTagID, -+ pSegment->base, -+ pSegment->pNextSegment->ui32BoundaryTagID, -+ pSegment->pNextSegment->base, -+ pArena->name)); -+ -+ PVR_DBG_BREAK; -+ } -+ break; -+ -+ default: -+ PVR_DPF((PVR_DBG_ERROR, -+ "ValidateArena ERROR: adjacent boundary tags %d (base=0x" UINTPTR_FMT -+ ") and %d (base=0x" UINTPTR_FMT ") are incompatible (arena: %s)", -+ pSegment->ui32BoundaryTagID, -+ pSegment->base, -+ pSegment->pNextSegment->ui32BoundaryTagID, -+ pSegment->pNextSegment->base, -+ pArena->name)); -+ -+ PVR_DBG_BREAK; -+ break; -+ } -+ pSegment = pSegment->pNextSegment; -+ } -+ } -+ else if (pSegment->eResourceType == NON_IMPORTED_RESOURCE_TYPE) -+ { -+ PVR_ASSERT((pSegment->eResourceSpan == RESOURCE_SPAN_FREE) || (pSegment->eResourceSpan == RESOURCE_SPAN_LIVE)); -+ -+ while (pSegment->pNextSegment) -+ { -+ eNextSpan = pSegment->pNextSegment->eResourceSpan; -+ -+ switch (pSegment->eResourceSpan) -+ { -+ case RESOURCE_SPAN_LIVE: -+ -+ if (!((eNextSpan == RESOURCE_SPAN_FREE) || -+ (eNextSpan == RESOURCE_SPAN_LIVE))) -+ { -+ /* error - next span must be free or live */ -+ PVR_DPF((PVR_DBG_ERROR, -+ "ValidateArena ERROR: adjacent boundary tags %d (base=0x" UINTPTR_FMT -+ ") and %d (base=0x" UINTPTR_FMT ") are incompatible (arena: %s)", -+ pSegment->ui32BoundaryTagID, -+ pSegment->base, -+ pSegment->pNextSegment->ui32BoundaryTagID, -+ pSegment->pNextSegment->base, -+ pArena->name)); -+ -+ PVR_DBG_BREAK; -+ } -+ break; -+ -+ case RESOURCE_SPAN_FREE: -+ -+ if (!((eNextSpan == RESOURCE_SPAN_FREE) || -+ (eNextSpan == RESOURCE_SPAN_LIVE))) -+ { -+ /* error - next span must be free or live */ -+ PVR_DPF((PVR_DBG_ERROR, -+ "ValidateArena ERROR: adjacent boundary tags %d (base=0x" UINTPTR_FMT -+ ") and %d (base=0x" UINTPTR_FMT ") are incompatible (arena: %s)", -+ pSegment->ui32BoundaryTagID, -+ pSegment->base, -+ pSegment->pNextSegment->ui32BoundaryTagID, -+ pSegment->pNextSegment->base, -+ pArena->name)); -+ -+ PVR_DBG_BREAK; -+ } -+ break; -+ -+ default: -+ PVR_DPF((PVR_DBG_ERROR, -+ "ValidateArena ERROR: adjacent boundary tags %d (base=0x" UINTPTR_FMT -+ ") and %d (base=0x" UINTPTR_FMT ") are incompatible (arena: %s)", -+ pSegment->ui32BoundaryTagID, -+ pSegment->base, -+ pSegment->pNextSegment->ui32BoundaryTagID, -+ pSegment->pNextSegment->base, -+ pArena->name)); -+ -+ PVR_DBG_BREAK; -+ break; -+ } -+ pSegment = pSegment->pNextSegment; -+ } -+ -+ } -+ else -+ { -+ PVR_DPF ((PVR_DBG_ERROR,"ValidateArena ERROR: pSegment->eResourceType unrecognized")); -+ -+ PVR_DBG_BREAK; -+ } -+ -+ return 0; -+} -+ -+#endif -+ -+ -+/*! -+****************************************************************************** -+ @Function RA_Free -+ -+ @Description To free a resource segment. -+ -+ @Input pArena - the arena the segment was originally allocated from. -+ @Input base - the base of the resource span to free. -+ @Input bFreeBackingStore - Should backing store memory be freed. -+ -+ @Return None -+******************************************************************************/ -+IMG_VOID -+RA_Free (RA_ARENA *pArena, IMG_UINTPTR_T base, IMG_BOOL bFreeBackingStore) -+{ -+ BT *pBT; -+ -+ PVR_ASSERT (pArena != IMG_NULL); -+ -+ if (pArena == IMG_NULL) -+ { -+ PVR_DPF ((PVR_DBG_ERROR,"RA_Free: invalid parameter - pArena")); -+ return; -+ } -+ -+#ifdef USE_BM_FREESPACE_CHECK -+ CheckBMFreespace(); -+#endif -+ -+ PVR_DPF ((PVR_DBG_MESSAGE, -+ "RA_Free: name='%s', base=0x" UINTPTR_FMT, pArena->name, base)); -+ -+ pBT = (BT *) HASH_Remove (pArena->pSegmentHash, base); -+ PVR_ASSERT (pBT != IMG_NULL); -+ -+ if (pBT) -+ { -+ PVR_ASSERT (pBT->base == base); -+ -+#ifdef RA_STATS -+ pArena->sStatistics.uCumulativeFrees++; -+#endif -+ -+#ifdef USE_BM_FREESPACE_CHECK -+{ -+ IMG_BYTE* p; -+ IMG_BYTE* endp; -+ -+ p = (IMG_BYTE*)pBT->base + SysGetDevicePhysOffset(); -+ endp = (IMG_BYTE*)((IMG_UINT32)(p + pBT->uSize)); -+ while ((IMG_UINT32)p & 3) -+ { -+ *p++ = 0xAA; -+ } -+ while (p < (IMG_BYTE*)((IMG_UINT32)endp & 0xfffffffc)) -+ { -+ *(IMG_UINT32*)p = 0xAAAAAAAA; -+ p += sizeof(IMG_UINT32); -+ } -+ while (p < endp) -+ { -+ *p++ = 0xAA; -+ } -+ PVR_DPF((PVR_DBG_MESSAGE, -+ "BM_FREESPACE_CHECK: RA_Free Cleared %p to %p (size=0x%" SIZE_T_FMT_LEN "x)", -+ (IMG_BYTE*)pBT->base + SysGetDevicePhysOffset(), -+ endp - 1, -+ pBT->uSize)); -+} -+#endif -+ _FreeBT (pArena, pBT, bFreeBackingStore); -+ } -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function RA_GetNextLiveSegment -+ -+ @Description Returns details of the next live resource segments -+ -+ @Input pArena - the arena the segment was originally allocated from. -+ @InOut psSegDetails - rtn details of segments -+ -+ @Return IMG_TRUE if operation succeeded -+******************************************************************************/ -+IMG_BOOL RA_GetNextLiveSegment(IMG_HANDLE hArena, RA_SEGMENT_DETAILS *psSegDetails) -+{ -+ BT *pBT; -+ -+ if (psSegDetails->hSegment) -+ { -+ pBT = (BT *)psSegDetails->hSegment; -+ } -+ else -+ { -+ RA_ARENA *pArena = (RA_ARENA *)hArena; -+ -+ pBT = pArena->pHeadSegment; -+ } -+ /* walk the arena segments and write live one to the buffer */ -+ while (pBT != IMG_NULL) -+ { -+ if (pBT->type == btt_live) -+ { -+ psSegDetails->uiSize = pBT->uSize; -+ psSegDetails->sCpuPhyAddr.uiAddr = pBT->base; -+ psSegDetails->hSegment = (IMG_HANDLE)pBT->pNextSegment; -+ -+ return IMG_TRUE; -+ } -+ -+ pBT = pBT->pNextSegment; -+ } -+ -+ psSegDetails->uiSize = 0; -+ psSegDetails->sCpuPhyAddr.uiAddr = 0; -+ psSegDetails->hSegment = (IMG_HANDLE)IMG_UNDEF; -+ -+ return IMG_FALSE; -+} -+ -+ -+#ifdef USE_BM_FREESPACE_CHECK -+RA_ARENA* pJFSavedArena = IMG_NULL; -+ -+IMG_VOID CheckBMFreespace(IMG_VOID) -+{ -+ BT *pBT; -+ IMG_BYTE* p; -+ IMG_BYTE* endp; -+ -+ if (pJFSavedArena != IMG_NULL) -+ { -+ for (pBT=pJFSavedArena->pHeadSegment; pBT!=IMG_NULL; pBT=pBT->pNextSegment) -+ { -+ if (pBT->type == btt_free) -+ { -+ p = (IMG_BYTE*)pBT->base + SysGetDevicePhysOffset(); -+ endp = (IMG_BYTE*)((IMG_UINT32)(p + pBT->uSize) & 0xfffffffc); -+ -+ while ((IMG_UINT32)p & 3) -+ { -+ if (*p++ != 0xAA) -+ { -+ fprintf(stderr,"BM_FREESPACE_CHECK: Blank space at %08X has changed to 0x%x\n",p,*(IMG_UINT32*)p); -+ for (;;); -+ break; -+ } -+ } -+ while (p < endp) -+ { -+ if (*(IMG_UINT32*)p != 0xAAAAAAAA) -+ { -+ fprintf(stderr,"BM_FREESPACE_CHECK: Blank space at %08X has changed to 0x%x\n",p,*(IMG_UINT32*)p); -+ for (;;); -+ break; -+ } -+ p += 4; -+ } -+ } -+ } -+ } -+} -+#endif -+ -+ -+#if (defined(CONFIG_PROC_FS) && defined(DEBUG)) || defined (RA_STATS) -+static IMG_CHAR * -+_BTType (IMG_INT eType) -+{ -+ switch (eType) -+ { -+ case btt_span: return "span"; -+ case btt_free: return "free"; -+ case btt_live: return "live"; -+ } -+ return "junk"; -+} -+#endif /*defined(CONFIG_PROC_FS) && defined(DEBUG)*/ -+ -+#if defined(ENABLE_RA_DUMP) -+/*! -+****************************************************************************** -+ @Function RA_Dump -+ -+ @Description To dump a readable description of an arena. Diagnostic only. -+ -+ @Input pArena - the arena to dump. -+ -+ @Return None -+******************************************************************************/ -+IMG_VOID -+RA_Dump (RA_ARENA *pArena) -+{ -+ BT *pBT; -+ PVR_ASSERT (pArena != IMG_NULL); -+ PVR_DPF ((PVR_DBG_MESSAGE,"Arena '%s':", pArena->name)); -+ PVR_DPF ((PVR_DBG_MESSAGE," alloc=%p free=%p handle=%p quantum=%d", -+ pArena->pImportAlloc, pArena->pImportFree, pArena->pImportHandle, -+ pArena->uQuantum)); -+ PVR_DPF ((PVR_DBG_MESSAGE," segment Chain:")); -+ if (pArena->pHeadSegment != IMG_NULL && -+ pArena->pHeadSegment->pPrevSegment != IMG_NULL) -+ PVR_DPF ((PVR_DBG_MESSAGE," error: head boundary tag has invalid pPrevSegment")); -+ if (pArena->pTailSegment != IMG_NULL && -+ pArena->pTailSegment->pNextSegment != IMG_NULL) -+ PVR_DPF ((PVR_DBG_MESSAGE," error: tail boundary tag has invalid pNextSegment")); -+ -+ for (pBT=pArena->pHeadSegment; pBT!=IMG_NULL; pBT=pBT->pNextSegment) -+ { -+ PVR_DPF ((PVR_DBG_MESSAGE,"\tbase=0x" UINTPTR_FMT " size=0x%" SIZE_T_FMT_LEN "x type=%s", -+ pBT->base, pBT->uSize, _BTType (pBT->type))); -+ } -+ -+#ifdef HASH_TRACE -+ HASH_Dump (pArena->pSegmentHash); -+#endif -+} -+#endif /* #if defined(ENABLE_RA_DUMP) */ -+ -+ -+#if defined(CONFIG_PROC_FS) && defined(DEBUG) -+ -+ -+static void RA_ProcSeqShowInfo(struct seq_file *sfile, void* el) -+{ -+ PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)sfile->private; -+ RA_ARENA *pArena = (RA_ARENA *)handlers->data; -+ IMG_UINTPTR_T off = (IMG_UINTPTR_T)el; -+ -+ switch (off) -+ { -+ case 1: -+ seq_printf(sfile, "quantum\t\t\t%" SIZE_T_FMT_LEN "u\n", pArena->uQuantum); -+ break; -+ case 2: -+ seq_printf(sfile, "import_handle\t\t%p\n", pArena->pImportHandle); -+ break; -+#ifdef RA_STATS -+ case 3: -+ seq_printf(sfile,"span count\t\t%" SIZE_T_FMT_LEN "u\n", pArena->sStatistics.uSpanCount); -+ break; -+ case 4: -+ seq_printf(sfile, "live segment count\t%" SIZE_T_FMT_LEN "u\n", pArena->sStatistics.uLiveSegmentCount); -+ break; -+ case 5: -+ seq_printf(sfile, "free segment count\t%" SIZE_T_FMT_LEN "u\n", pArena->sStatistics.uFreeSegmentCount); -+ break; -+ case 6: -+ seq_printf(sfile, "free resource count\t%" SIZE_T_FMT_LEN "u (0x%" SIZE_T_FMT_LEN "x)\n", -+ pArena->sStatistics.uFreeResourceCount, -+ pArena->sStatistics.uFreeResourceCount); -+ break; -+ case 7: -+ seq_printf(sfile, "total allocs\t\t%" SIZE_T_FMT_LEN "u\n", pArena->sStatistics.uCumulativeAllocs); -+ break; -+ case 8: -+ seq_printf(sfile, "total frees\t\t%" SIZE_T_FMT_LEN "u\n", pArena->sStatistics.uCumulativeFrees); -+ break; -+ case 9: -+ seq_printf(sfile, "import count\t\t%" SIZE_T_FMT_LEN "u\n", pArena->sStatistics.uImportCount); -+ break; -+ case 10: -+ seq_printf(sfile, "export count\t\t%" SIZE_T_FMT_LEN "u\n", pArena->sStatistics.uExportCount); -+ break; -+#endif -+ } -+ -+} -+ -+static void* RA_ProcSeqOff2ElementInfo(struct seq_file * sfile, loff_t off) -+{ -+#ifdef RA_STATS -+ if(off <= 9) -+#else -+ if(off <= 1) -+#endif -+ return (void*)(IMG_UINTPTR_T)(off+1); -+ return 0; -+} -+ -+static void RA_ProcSeqShowRegs(struct seq_file *sfile, void* el) -+{ -+ PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)sfile->private; -+ RA_ARENA *pArena = (RA_ARENA *)handlers->data; -+ BT *pBT = (BT*)el; -+ -+ if (el == PVR_PROC_SEQ_START_TOKEN) -+ { -+ seq_printf(sfile, "Arena \"%s\"\nBase Size Type Ref\n", pArena->name); -+ return; -+ } -+ -+ if (pBT) -+ { -+ seq_printf(sfile, "%p %" SIZE_T_FMT_LEN "x %4s %p\n", -+ (IMG_PVOID)pBT->base, pBT->uSize, _BTType (pBT->type), -+ pBT->psMapping); -+ } -+} -+ -+static void* RA_ProcSeqOff2ElementRegs(struct seq_file * sfile, loff_t off) -+{ -+ PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)sfile->private; -+ RA_ARENA *pArena = (RA_ARENA *)handlers->data; -+ BT *pBT = 0; -+ -+ if(off == 0) -+ return PVR_PROC_SEQ_START_TOKEN; -+ -+ for (pBT=pArena->pHeadSegment; --off && pBT; pBT=pBT->pNextSegment); -+ -+ return (void*)pBT; -+} -+ -+#endif /* defined(CONFIG_PROC_FS) && defined(DEBUG) */ -+ -+ -+#ifdef RA_STATS -+/*! -+****************************************************************************** -+ @Function RA_GetStats -+ -+ @Description Gets the arena stats and places in client buffer -+ -+ @Input pArena - the arena to print statistics for. -+ @Input ppszStr - caller string to fill -+ @Input pui32StrLen - length of caller string -+ -+ @Return PVRSRV_ERROR -+******************************************************************************/ -+PVRSRV_ERROR RA_GetStats(RA_ARENA *pArena, -+ IMG_CHAR **ppszStr, -+ IMG_UINT32 *pui32StrLen) -+{ -+ IMG_CHAR *pszStr = *ppszStr; -+ IMG_UINT32 ui32StrLen = *pui32StrLen; -+ IMG_INT32 i32Count; -+ BT *pBT; -+ -+ CHECK_SPACE(ui32StrLen); -+ i32Count = OSSNPrintf(pszStr, 100, "\nArena '%s':\n", pArena->name); -+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen); -+ -+ -+ CHECK_SPACE(ui32StrLen); -+ i32Count = OSSNPrintf(pszStr, 100, " allocCB=%p freeCB=%p handle=%p quantum=%" SIZE_T_FMT_LEN "u\n", -+ pArena->pImportAlloc, -+ pArena->pImportFree, -+ pArena->pImportHandle, -+ pArena->uQuantum); -+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen); -+ -+ CHECK_SPACE(ui32StrLen); -+ i32Count = OSSNPrintf(pszStr, 100, "span count\t\t%" SIZE_T_FMT_LEN "u\n", -+ pArena->sStatistics.uSpanCount); -+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen); -+ -+ CHECK_SPACE(ui32StrLen); -+ i32Count = OSSNPrintf(pszStr, 100, "live segment count\t%" SIZE_T_FMT_LEN "u\n", -+ pArena->sStatistics.uLiveSegmentCount); -+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen); -+ -+ CHECK_SPACE(ui32StrLen); -+ i32Count = OSSNPrintf(pszStr, 100, "free segment count\t%" SIZE_T_FMT_LEN "u\n", -+ pArena->sStatistics.uFreeSegmentCount); -+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen); -+ -+ CHECK_SPACE(ui32StrLen); -+ i32Count = OSSNPrintf(pszStr, 100, "free resource count\t%" SIZE_T_FMT_LEN "u (0x%" SIZE_T_FMT_LEN "x)\n", -+ pArena->sStatistics.uFreeResourceCount, -+ pArena->sStatistics.uFreeResourceCount); -+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen); -+ -+ CHECK_SPACE(ui32StrLen); -+ i32Count = OSSNPrintf(pszStr, 100, "total allocs\t\t%" SIZE_T_FMT_LEN "u\n", -+ pArena->sStatistics.uCumulativeAllocs); -+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen); -+ -+ CHECK_SPACE(ui32StrLen); -+ i32Count = OSSNPrintf(pszStr, 100, "total frees\t\t%" SIZE_T_FMT_LEN "u\n", -+ pArena->sStatistics.uCumulativeFrees); -+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen); -+ -+ CHECK_SPACE(ui32StrLen); -+ i32Count = OSSNPrintf(pszStr, 100, "import count\t\t%" SIZE_T_FMT_LEN "u\n", -+ pArena->sStatistics.uImportCount); -+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen); -+ -+ CHECK_SPACE(ui32StrLen); -+ i32Count = OSSNPrintf(pszStr, 100, "export count\t\t%" SIZE_T_FMT_LEN "u\n", -+ pArena->sStatistics.uExportCount); -+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen); -+ -+ CHECK_SPACE(ui32StrLen); -+ i32Count = OSSNPrintf(pszStr, 100, " segment Chain:\n"); -+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen); -+ -+ if (pArena->pHeadSegment != IMG_NULL && -+ pArena->pHeadSegment->pPrevSegment != IMG_NULL) -+ { -+ CHECK_SPACE(ui32StrLen); -+ i32Count = OSSNPrintf(pszStr, 100, " error: head boundary tag has invalid pPrevSegment\n"); -+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen); -+ } -+ -+ if (pArena->pTailSegment != IMG_NULL && -+ pArena->pTailSegment->pNextSegment != IMG_NULL) -+ { -+ CHECK_SPACE(ui32StrLen); -+ i32Count = OSSNPrintf(pszStr, 100, " error: tail boundary tag has invalid pNextSegment\n"); -+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen); -+ } -+ -+ for (pBT=pArena->pHeadSegment; pBT!=IMG_NULL; pBT=pBT->pNextSegment) -+ { -+ CHECK_SPACE(ui32StrLen); -+ i32Count = OSSNPrintf(pszStr, 100, "\tbase=0x%p size=0x%" SIZE_T_FMT_LEN "x type=%s ref=%p\n", -+ (void *)pBT->base, -+ pBT->uSize, -+ _BTType(pBT->type), -+ pBT->psMapping); -+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen); -+ } -+ -+ *ppszStr = pszStr; -+ *pui32StrLen = ui32StrLen; -+ -+ return PVRSRV_OK; -+} -+ -+PVRSRV_ERROR RA_GetStatsFreeMem(RA_ARENA *pArena, -+ IMG_CHAR **ppszStr, -+ IMG_UINT32 *pui32StrLen) -+{ -+ IMG_CHAR *pszStr = *ppszStr; -+ IMG_UINT32 ui32StrLen = *pui32StrLen; -+ IMG_INT32 i32Count; -+ CHECK_SPACE(ui32StrLen); -+ i32Count = OSSNPrintf(pszStr, 100, "Bytes free: Arena %-30s: %" SIZE_T_FMT_LEN "u (0x%" SIZE_T_FMT_LEN "x)\n", pArena->name, -+ pArena->sStatistics.uFreeResourceCount, -+ pArena->sStatistics.uFreeResourceCount); -+ UPDATE_SPACE(pszStr, i32Count, ui32StrLen); -+ *ppszStr = pszStr; -+ *pui32StrLen = ui32StrLen; -+ -+ return PVRSRV_OK; -+} -+#endif -+ -+/****************************************************************************** -+ End of file (ra.c) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/common/refcount.c b/drivers/staging/ti-es8-sgx/services4/srvkm/common/refcount.c -new file mode 100644 -index 0000000..a6dcb19 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/common/refcount.c -@@ -0,0 +1,675 @@ -+/*************************************************************************/ /*! -+@Title Services reference count debugging -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#if defined(PVRSRV_REFCOUNT_DEBUG) -+ -+#include "services_headers.h" -+ -+#ifndef __linux__ -+#warning Reference count debugging is not thread-safe on this platform -+#define PVRSRV_LOCK_CCB() -+#define PVRSRV_UNLOCK_CCB() -+#else /* __linux__ */ -+#include <linux/spinlock.h> -+static DEFINE_SPINLOCK(gsCCBLock); -+#define PVRSRV_LOCK_CCB() \ -+ { \ -+ unsigned long flags; \ -+ spin_lock_irqsave(&gsCCBLock, flags); -+#define PVRSRV_UNLOCK_CCB() \ -+ spin_unlock_irqrestore(&gsCCBLock, flags); \ -+ } -+#endif /* __linux__ */ -+ -+#define PVRSRV_REFCOUNT_CCB_MAX 512 -+#define PVRSRV_REFCOUNT_CCB_MESG_MAX 80 -+ -+#define PVRSRV_REFCOUNT_CCB_DEBUG_SYNCINFO (1U << 0) -+#define PVRSRV_REFCOUNT_CCB_DEBUG_MEMINFO (1U << 1) -+#define PVRSRV_REFCOUNT_CCB_DEBUG_BM_BUF (1U << 2) -+#define PVRSRV_REFCOUNT_CCB_DEBUG_BM_BUF2 (1U << 3) -+#define PVRSRV_REFCOUNT_CCB_DEBUG_BM_XPROC (1U << 4) -+ -+#if defined(__linux__) -+#define PVRSRV_REFCOUNT_CCB_DEBUG_MMAP (1U << 16) -+#define PVRSRV_REFCOUNT_CCB_DEBUG_MMAP2 (1U << 17) -+#define PVRSRV_REFCOUNT_CCB_DEBUG_ION_SYNC (1U << 18) -+#else -+#define PVRSRV_REFCOUNT_CCB_DEBUG_MMAP 0 -+#define PVRSRV_REFCOUNT_CCB_DEBUG_MMAP2 0 -+#define PVRSRV_REFCOUNT_CCB_DEBUG_ION_SYNC 0 -+#endif -+ -+#define PVRSRV_REFCOUNT_CCB_DEBUG_ALL ~0U -+ -+/*static const IMG_UINT guiDebugMask = PVRSRV_REFCOUNT_CCB_DEBUG_ALL;*/ -+static const IMG_UINT guiDebugMask = -+ PVRSRV_REFCOUNT_CCB_DEBUG_SYNCINFO | -+#if defined(SUPPORT_ION) -+ PVRSRV_REFCOUNT_CCB_DEBUG_ION_SYNC | -+#endif -+ PVRSRV_REFCOUNT_CCB_DEBUG_MMAP2; -+ -+typedef struct -+{ -+ const IMG_CHAR *pszFile; -+ IMG_INT iLine; -+ IMG_UINT32 ui32PID; -+ IMG_CHAR pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX]; -+} -+PVRSRV_REFCOUNT_CCB; -+ -+static PVRSRV_REFCOUNT_CCB gsRefCountCCB[PVRSRV_REFCOUNT_CCB_MAX]; -+static IMG_UINT giOffset; -+ -+static const IMG_CHAR gszHeader[] = -+ /* 10 20 30 40 50 60 70 -+ * 345678901234567890123456789012345678901234567890123456789012345678901 -+ */ -+ "TYPE SYNCINFO MEMINFO MEMHANDLE OTHER REF REF' SIZE PID"; -+ /* NCINFO deadbeef deadbeef deadbeef deadbeef 1234 1234 deadbeef */ -+ -+#define PVRSRV_REFCOUNT_CCB_FMT_STRING "%8.8s %8p %8p %8p %8p %.4d %.4d %.8x" -+ -+IMG_INTERNAL -+void PVRSRVDumpRefCountCCB(void) -+{ -+ int i; -+ -+ PVRSRV_LOCK_CCB(); -+ -+ PVR_LOG(("%s", gszHeader)); -+ -+ for(i = 0; i < PVRSRV_REFCOUNT_CCB_MAX; i++) -+ { -+ PVRSRV_REFCOUNT_CCB *psRefCountCCBEntry = -+ &gsRefCountCCB[(giOffset + i) % PVRSRV_REFCOUNT_CCB_MAX]; -+ -+ /* Early on, we won't have MAX_REFCOUNT_CCB_SIZE messages */ -+ if(!psRefCountCCBEntry->pszFile) -+ continue; -+ -+ PVR_LOG(("%s %d %s:%d", psRefCountCCBEntry->pcMesg, -+ psRefCountCCBEntry->ui32PID, -+ psRefCountCCBEntry->pszFile, -+ psRefCountCCBEntry->iLine)); -+ } -+ -+ PVRSRV_UNLOCK_CCB(); -+} -+ -+IMG_INTERNAL -+void PVRSRVKernelSyncInfoIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine, -+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo, -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo) -+{ -+ IMG_UINT32 ui32RefValue = OSAtomicRead(psKernelSyncInfo->pvRefCount); -+ -+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_SYNCINFO)) -+ goto skip; -+ -+ PVRSRV_LOCK_CCB(); -+ -+ gsRefCountCCB[giOffset].pszFile = pszFile; -+ gsRefCountCCB[giOffset].iLine = iLine; -+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM(); -+ snprintf(gsRefCountCCB[giOffset].pcMesg, -+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1, -+ PVRSRV_REFCOUNT_CCB_FMT_STRING, -+ "SYNCINFO", -+ psKernelSyncInfo, -+ psKernelMemInfo, -+ NULL, -+ (psKernelMemInfo) ? psKernelMemInfo->sMemBlk.hOSMemHandle : NULL, -+ ui32RefValue, -+ ui32RefValue + 1, -+ (psKernelMemInfo) ? psKernelMemInfo->uAllocSize : 0); -+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0; -+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX; -+ -+ PVRSRV_UNLOCK_CCB(); -+ -+skip: -+ PVRSRVAcquireSyncInfoKM(psKernelSyncInfo); -+} -+ -+IMG_INTERNAL -+void PVRSRVKernelSyncInfoDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine, -+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo, -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo) -+{ -+ IMG_UINT32 ui32RefValue = OSAtomicRead(psKernelSyncInfo->pvRefCount); -+ -+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_SYNCINFO)) -+ goto skip; -+ -+ PVRSRV_LOCK_CCB(); -+ -+ gsRefCountCCB[giOffset].pszFile = pszFile; -+ gsRefCountCCB[giOffset].iLine = iLine; -+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM(); -+ snprintf(gsRefCountCCB[giOffset].pcMesg, -+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1, -+ PVRSRV_REFCOUNT_CCB_FMT_STRING, -+ "SYNCINFO", -+ psKernelSyncInfo, -+ psKernelMemInfo, -+ (psKernelMemInfo) ? psKernelMemInfo->sMemBlk.hOSMemHandle : NULL, -+ NULL, -+ ui32RefValue, -+ ui32RefValue - 1, -+ (psKernelMemInfo) ? psKernelMemInfo->uAllocSize : 0); -+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0; -+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX; -+ -+ PVRSRV_UNLOCK_CCB(); -+ -+skip: -+ PVRSRVReleaseSyncInfoKM(psKernelSyncInfo); -+} -+ -+IMG_INTERNAL -+void PVRSRVKernelMemInfoIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine, -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo) -+{ -+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_MEMINFO)) -+ goto skip; -+ -+ PVRSRV_LOCK_CCB(); -+ -+ gsRefCountCCB[giOffset].pszFile = pszFile; -+ gsRefCountCCB[giOffset].iLine = iLine; -+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM(); -+ snprintf(gsRefCountCCB[giOffset].pcMesg, -+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1, -+ PVRSRV_REFCOUNT_CCB_FMT_STRING, -+ "MEMINFO", -+ psKernelMemInfo->psKernelSyncInfo, -+ psKernelMemInfo, -+ psKernelMemInfo->sMemBlk.hOSMemHandle, -+ NULL, -+ psKernelMemInfo->ui32RefCount, -+ psKernelMemInfo->ui32RefCount + 1, -+ psKernelMemInfo->uAllocSize); -+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0; -+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX; -+ -+ PVRSRV_UNLOCK_CCB(); -+ -+skip: -+ psKernelMemInfo->ui32RefCount++; -+} -+ -+IMG_INTERNAL -+void PVRSRVKernelMemInfoDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine, -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo) -+{ -+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_MEMINFO)) -+ goto skip; -+ -+ PVRSRV_LOCK_CCB(); -+ -+ gsRefCountCCB[giOffset].pszFile = pszFile; -+ gsRefCountCCB[giOffset].iLine = iLine; -+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM(); -+ snprintf(gsRefCountCCB[giOffset].pcMesg, -+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1, -+ PVRSRV_REFCOUNT_CCB_FMT_STRING, -+ "MEMINFO", -+ psKernelMemInfo->psKernelSyncInfo, -+ psKernelMemInfo, -+ psKernelMemInfo->sMemBlk.hOSMemHandle, -+ NULL, -+ psKernelMemInfo->ui32RefCount, -+ psKernelMemInfo->ui32RefCount - 1, -+ psKernelMemInfo->uAllocSize); -+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0; -+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX; -+ -+ PVRSRV_UNLOCK_CCB(); -+ -+skip: -+ psKernelMemInfo->ui32RefCount--; -+} -+ -+IMG_INTERNAL -+void PVRSRVBMBufIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine, BM_BUF *pBuf) -+{ -+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_BM_BUF)) -+ goto skip; -+ -+ PVRSRV_LOCK_CCB(); -+ -+ gsRefCountCCB[giOffset].pszFile = pszFile; -+ gsRefCountCCB[giOffset].iLine = iLine; -+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM(); -+ snprintf(gsRefCountCCB[giOffset].pcMesg, -+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1, -+ PVRSRV_REFCOUNT_CCB_FMT_STRING, -+ "BM_BUF", -+ NULL, -+ NULL, -+ BM_HandleToOSMemHandle(pBuf), -+ pBuf, -+ pBuf->ui32RefCount, -+ pBuf->ui32RefCount + 1, -+ (pBuf->pMapping) ? pBuf->pMapping->uSize : 0); -+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0; -+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX; -+ -+ PVRSRV_UNLOCK_CCB(); -+ -+skip: -+ pBuf->ui32RefCount++; -+} -+ -+IMG_INTERNAL -+void PVRSRVBMBufDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine, BM_BUF *pBuf) -+{ -+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_BM_BUF)) -+ goto skip; -+ -+ PVRSRV_LOCK_CCB(); -+ -+ gsRefCountCCB[giOffset].pszFile = pszFile; -+ gsRefCountCCB[giOffset].iLine = iLine; -+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM(); -+ snprintf(gsRefCountCCB[giOffset].pcMesg, -+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1, -+ PVRSRV_REFCOUNT_CCB_FMT_STRING, -+ "BM_BUF", -+ NULL, -+ NULL, -+ BM_HandleToOSMemHandle(pBuf), -+ pBuf, -+ pBuf->ui32RefCount, -+ pBuf->ui32RefCount - 1, -+ (pBuf->pMapping) ? pBuf->pMapping->uSize : 0); -+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0; -+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX; -+ -+ PVRSRV_UNLOCK_CCB(); -+ -+skip: -+ pBuf->ui32RefCount--; -+} -+ -+IMG_INTERNAL -+void PVRSRVBMBufIncExport2(const IMG_CHAR *pszFile, IMG_INT iLine, BM_BUF *pBuf) -+{ -+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_BM_BUF2)) -+ goto skip; -+ -+ PVRSRV_LOCK_CCB(); -+ -+ gsRefCountCCB[giOffset].pszFile = pszFile; -+ gsRefCountCCB[giOffset].iLine = iLine; -+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM(); -+ snprintf(gsRefCountCCB[giOffset].pcMesg, -+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1, -+ PVRSRV_REFCOUNT_CCB_FMT_STRING, -+ "BM_BUF2", -+ NULL, -+ NULL, -+ BM_HandleToOSMemHandle(pBuf), -+ pBuf, -+ pBuf->ui32ExportCount, -+ pBuf->ui32ExportCount + 1, -+ (pBuf->pMapping) ? pBuf->pMapping->uSize : 0); -+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0; -+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX; -+ -+ PVRSRV_UNLOCK_CCB(); -+ -+skip: -+ pBuf->ui32ExportCount++; -+} -+ -+IMG_INTERNAL -+void PVRSRVBMBufDecExport2(const IMG_CHAR *pszFile, IMG_INT iLine, BM_BUF *pBuf) -+{ -+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_BM_BUF2)) -+ goto skip; -+ -+ PVRSRV_LOCK_CCB(); -+ -+ gsRefCountCCB[giOffset].pszFile = pszFile; -+ gsRefCountCCB[giOffset].iLine = iLine; -+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM(); -+ snprintf(gsRefCountCCB[giOffset].pcMesg, -+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1, -+ PVRSRV_REFCOUNT_CCB_FMT_STRING, -+ "BM_BUF2", -+ NULL, -+ NULL, -+ BM_HandleToOSMemHandle(pBuf), -+ pBuf, -+ pBuf->ui32ExportCount, -+ pBuf->ui32ExportCount - 1, -+ (pBuf->pMapping) ? pBuf->pMapping->uSize : 0); -+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0; -+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX; -+ -+ PVRSRV_UNLOCK_CCB(); -+ -+skip: -+ pBuf->ui32ExportCount--; -+} -+ -+IMG_INTERNAL -+void PVRSRVBMXProcIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine, IMG_UINT32 ui32Index) -+{ -+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_BM_XPROC)) -+ goto skip; -+ -+ PVRSRV_LOCK_CCB(); -+ -+ gsRefCountCCB[giOffset].pszFile = pszFile; -+ gsRefCountCCB[giOffset].iLine = iLine; -+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM(); -+ snprintf(gsRefCountCCB[giOffset].pcMesg, -+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1, -+ PVRSRV_REFCOUNT_CCB_FMT_STRING, -+ "BM_XPROC", -+ NULL, -+ NULL, -+ gXProcWorkaroundShareData[ui32Index].hOSMemHandle, -+ (IMG_VOID *) ui32Index, -+ gXProcWorkaroundShareData[ui32Index].ui32RefCount, -+ gXProcWorkaroundShareData[ui32Index].ui32RefCount + 1, -+ gXProcWorkaroundShareData[ui32Index].ui32Size); -+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0; -+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX; -+ -+ PVRSRV_UNLOCK_CCB(); -+ -+skip: -+ gXProcWorkaroundShareData[ui32Index].ui32RefCount++; -+} -+ -+IMG_INTERNAL -+void PVRSRVBMXProcDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine, IMG_UINT32 ui32Index) -+{ -+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_BM_XPROC)) -+ goto skip; -+ -+ PVRSRV_LOCK_CCB(); -+ -+ gsRefCountCCB[giOffset].pszFile = pszFile; -+ gsRefCountCCB[giOffset].iLine = iLine; -+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM(); -+ snprintf(gsRefCountCCB[giOffset].pcMesg, -+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1, -+ PVRSRV_REFCOUNT_CCB_FMT_STRING, -+ "BM_XPROC", -+ NULL, -+ NULL, -+ gXProcWorkaroundShareData[ui32Index].hOSMemHandle, -+ (IMG_VOID *) ui32Index, -+ gXProcWorkaroundShareData[ui32Index].ui32RefCount, -+ gXProcWorkaroundShareData[ui32Index].ui32RefCount - 1, -+ gXProcWorkaroundShareData[ui32Index].ui32Size); -+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0; -+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX; -+ -+ PVRSRV_UNLOCK_CCB(); -+ -+skip: -+ gXProcWorkaroundShareData[ui32Index].ui32RefCount--; -+} -+ -+#if defined(__linux__) -+ -+/* mmap refcounting is Linux specific */ -+ -+IMG_INTERNAL -+void PVRSRVOffsetStructIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine, -+ PKV_OFFSET_STRUCT psOffsetStruct) -+{ -+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_MMAP)) -+ goto skip; -+ -+ PVRSRV_LOCK_CCB(); -+ -+ gsRefCountCCB[giOffset].pszFile = pszFile; -+ gsRefCountCCB[giOffset].iLine = iLine; -+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM(); -+ snprintf(gsRefCountCCB[giOffset].pcMesg, -+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1, -+ PVRSRV_REFCOUNT_CCB_FMT_STRING, -+ "MMAP", -+ NULL, -+ NULL, -+ psOffsetStruct->psLinuxMemArea, -+ psOffsetStruct, -+ psOffsetStruct->ui32RefCount, -+ psOffsetStruct->ui32RefCount + 1, -+ psOffsetStruct->uiRealByteSize); -+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0; -+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX; -+ -+ PVRSRV_UNLOCK_CCB(); -+ -+skip: -+ psOffsetStruct->ui32RefCount++; -+} -+ -+IMG_INTERNAL -+void PVRSRVOffsetStructDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine, -+ PKV_OFFSET_STRUCT psOffsetStruct) -+{ -+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_MMAP)) -+ goto skip; -+ -+ PVRSRV_LOCK_CCB(); -+ -+ gsRefCountCCB[giOffset].pszFile = pszFile; -+ gsRefCountCCB[giOffset].iLine = iLine; -+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM(); -+ snprintf(gsRefCountCCB[giOffset].pcMesg, -+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1, -+ PVRSRV_REFCOUNT_CCB_FMT_STRING, -+ "MMAP", -+ NULL, -+ NULL, -+ psOffsetStruct->psLinuxMemArea, -+ psOffsetStruct, -+ psOffsetStruct->ui32RefCount, -+ psOffsetStruct->ui32RefCount - 1, -+ psOffsetStruct->uiRealByteSize); -+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0; -+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX; -+ -+ PVRSRV_UNLOCK_CCB(); -+ -+skip: -+ psOffsetStruct->ui32RefCount--; -+} -+ -+IMG_INTERNAL -+void PVRSRVOffsetStructIncMapped2(const IMG_CHAR *pszFile, IMG_INT iLine, -+ PKV_OFFSET_STRUCT psOffsetStruct) -+{ -+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_MMAP2)) -+ goto skip; -+ -+ PVRSRV_LOCK_CCB(); -+ -+ gsRefCountCCB[giOffset].pszFile = pszFile; -+ gsRefCountCCB[giOffset].iLine = iLine; -+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM(); -+ snprintf(gsRefCountCCB[giOffset].pcMesg, -+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1, -+ PVRSRV_REFCOUNT_CCB_FMT_STRING, -+ "MMAP2", -+ NULL, -+ NULL, -+ psOffsetStruct->psLinuxMemArea, -+ psOffsetStruct, -+ psOffsetStruct->ui32Mapped, -+ psOffsetStruct->ui32Mapped + 1, -+ psOffsetStruct->uiRealByteSize); -+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0; -+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX; -+ -+ PVRSRV_UNLOCK_CCB(); -+ -+skip: -+ psOffsetStruct->ui32Mapped++; -+} -+ -+IMG_INTERNAL -+void PVRSRVOffsetStructDecMapped2(const IMG_CHAR *pszFile, IMG_INT iLine, -+ PKV_OFFSET_STRUCT psOffsetStruct) -+{ -+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_MMAP2)) -+ goto skip; -+ -+ PVRSRV_LOCK_CCB(); -+ -+ gsRefCountCCB[giOffset].pszFile = pszFile; -+ gsRefCountCCB[giOffset].iLine = iLine; -+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM(); -+ snprintf(gsRefCountCCB[giOffset].pcMesg, -+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1, -+ PVRSRV_REFCOUNT_CCB_FMT_STRING, -+ "MMAP2", -+ NULL, -+ NULL, -+ psOffsetStruct->psLinuxMemArea, -+ psOffsetStruct, -+ psOffsetStruct->ui32Mapped, -+ psOffsetStruct->ui32Mapped - 1, -+ psOffsetStruct->uiRealByteSize); -+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0; -+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX; -+ -+ PVRSRV_UNLOCK_CCB(); -+ -+skip: -+ psOffsetStruct->ui32Mapped--; -+} -+ -+#if defined(SUPPORT_ION) -+PVRSRV_ERROR PVRSRVIonBufferSyncInfoIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine, -+ IMG_HANDLE hUnique, -+ IMG_HANDLE hDevCookie, -+ IMG_HANDLE hDevMemContext, -+ PVRSRV_ION_SYNC_INFO **ppsIonSyncInfo, -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo) -+{ -+ PVRSRV_ERROR eError; -+ -+ /* -+ We have to do the call 1st as we need to Ion syninfo which it returns -+ */ -+ eError = PVRSRVIonBufferSyncAcquire(hUnique, -+ hDevCookie, -+ hDevMemContext, -+ ppsIonSyncInfo); -+ -+ if (eError == PVRSRV_OK) -+ { -+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_ION_SYNC)) -+ goto skip; -+ -+ PVRSRV_LOCK_CCB(); -+ -+ gsRefCountCCB[giOffset].pszFile = pszFile; -+ gsRefCountCCB[giOffset].iLine = iLine; -+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM(); -+ snprintf(gsRefCountCCB[giOffset].pcMesg, -+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1, -+ PVRSRV_REFCOUNT_CCB_FMT_STRING, -+ "ION_SYNC", -+ (*ppsIonSyncInfo)->psSyncInfo, -+ psKernelMemInfo, -+ NULL, -+ *ppsIonSyncInfo, -+ (*ppsIonSyncInfo)->ui32RefCount - 1, -+ (*ppsIonSyncInfo)->ui32RefCount, -+ 0); -+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0; -+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX; -+ -+ PVRSRV_UNLOCK_CCB(); -+ } -+ -+skip: -+ return eError; -+} -+ -+void PVRSRVIonBufferSyncInfoDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine, -+ PVRSRV_ION_SYNC_INFO *psIonSyncInfo, -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo) -+{ -+ if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_ION_SYNC)) -+ goto skip; -+ -+ PVRSRV_LOCK_CCB(); -+ -+ gsRefCountCCB[giOffset].pszFile = pszFile; -+ gsRefCountCCB[giOffset].iLine = iLine; -+ gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM(); -+ snprintf(gsRefCountCCB[giOffset].pcMesg, -+ PVRSRV_REFCOUNT_CCB_MESG_MAX - 1, -+ PVRSRV_REFCOUNT_CCB_FMT_STRING, -+ "ION_SYNC", -+ psIonSyncInfo->psSyncInfo, -+ psKernelMemInfo, -+ NULL, -+ psIonSyncInfo, -+ psIonSyncInfo->ui32RefCount, -+ psIonSyncInfo->ui32RefCount - 1, -+ 0); -+ gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0; -+ giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX; -+ -+ PVRSRV_UNLOCK_CCB(); -+skip: -+ PVRSRVIonBufferSyncRelease(psIonSyncInfo); -+} -+ -+#endif /* defined (SUPPORT_ION) */ -+ -+#endif /* defined(__linux__) */ -+ -+#endif /* defined(PVRSRV_REFCOUNT_DEBUG) */ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/common/resman.c b/drivers/staging/ti-es8-sgx/services4/srvkm/common/resman.c -new file mode 100644 -index 0000000..95fc2e4 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/common/resman.c -@@ -0,0 +1,987 @@ -+/*************************************************************************/ /*! -+@Title Resource Manager -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Provide resource management -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+#include "services_headers.h" -+#include "resman.h" -+ -+#ifdef __linux__ -+#include <linux/version.h> -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)) -+#ifndef AUTOCONF_INCLUDED -+#include <linux/config.h> -+#endif -+#endif -+ -+#include <linux/sched.h> -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,9) -+#include <linux/hardirq.h> -+#else -+#include <asm/hardirq.h> -+#endif -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) -+#include <linux/mutex.h> -+#else -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) -+#include <linux/semaphore.h> -+#else -+#include <asm/semaphore.h> -+#endif -+#endif -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) -+static DEFINE_MUTEX(lock); -+#define DOWN(m) mutex_lock(m) -+#define UP(m) mutex_unlock(m) -+#else -+static DECLARE_MUTEX(lock); -+#define DOWN(m) down(m) -+#define UP(m) up(m) -+#endif -+ -+#define ACQUIRE_SYNC_OBJ do { \ -+ if (in_interrupt()) { \ -+ printk("ISR cannot take RESMAN mutex\n"); \ -+ BUG(); \ -+ } \ -+ else DOWN(&lock); \ -+} while (0) -+#define RELEASE_SYNC_OBJ UP(&lock) -+ -+#else -+ -+#define ACQUIRE_SYNC_OBJ -+#define RELEASE_SYNC_OBJ -+ -+#endif -+ -+#define RESMAN_SIGNATURE 0x12345678 -+ -+/****************************************************************************** -+ * resman structures -+ *****************************************************************************/ -+ -+/* resman item structure */ -+typedef struct _RESMAN_ITEM_ -+{ -+#ifdef DEBUG -+ IMG_UINT32 ui32Signature; -+#endif -+ struct _RESMAN_ITEM_ **ppsThis; /*!< list navigation */ -+ struct _RESMAN_ITEM_ *psNext; /*!< list navigation */ -+ -+ IMG_UINT32 ui32Flags; /*!< flags */ -+ IMG_UINT32 ui32ResType;/*!< res type */ -+ -+ IMG_PVOID pvParam; /*!< param1 for callback */ -+ IMG_UINT32 ui32Param; /*!< param2 for callback */ -+ -+ RESMAN_FREE_FN pfnFreeResource;/*!< resman item free callback */ -+} RESMAN_ITEM; -+ -+ -+/* resman context structure */ -+typedef struct _RESMAN_CONTEXT_ -+{ -+#ifdef DEBUG -+ IMG_UINT32 ui32Signature; -+#endif -+ struct _RESMAN_CONTEXT_ **ppsThis;/*!< list navigation */ -+ struct _RESMAN_CONTEXT_ *psNext;/*!< list navigation */ -+ -+ PVRSRV_PER_PROCESS_DATA *psPerProc; /* owner of resources */ -+ -+ RESMAN_ITEM *psResItemList;/*!< res item list for context */ -+ -+} RESMAN_CONTEXT; -+ -+ -+/* resman list structure */ -+typedef struct -+{ -+ RESMAN_CONTEXT *psContextList; /*!< resman context list */ -+ -+} RESMAN_LIST, *PRESMAN_LIST; /* PRQA S 3205 */ -+ -+ -+PRESMAN_LIST gpsResList = IMG_NULL; -+ -+#include "lists.h" /* PRQA S 5087 */ /* include lists.h required here */ -+ -+static IMPLEMENT_LIST_ANY_VA(RESMAN_ITEM) -+static IMPLEMENT_LIST_ANY_VA_2(RESMAN_ITEM, IMG_BOOL, IMG_FALSE) -+static IMPLEMENT_LIST_INSERT(RESMAN_ITEM) -+static IMPLEMENT_LIST_REMOVE(RESMAN_ITEM) -+static IMPLEMENT_LIST_REVERSE(RESMAN_ITEM) -+ -+static IMPLEMENT_LIST_REMOVE(RESMAN_CONTEXT) -+static IMPLEMENT_LIST_INSERT(RESMAN_CONTEXT) -+ -+ -+#define PRINT_RESLIST(x, y, z) -+ -+/******************************************************** Forword references */ -+ -+static PVRSRV_ERROR FreeResourceByPtr(RESMAN_ITEM *psItem, IMG_BOOL bExecuteCallback, IMG_BOOL bForceCleanup); -+ -+static PVRSRV_ERROR FreeResourceByCriteria(PRESMAN_CONTEXT psContext, -+ IMG_UINT32 ui32SearchCriteria, -+ IMG_UINT32 ui32ResType, -+ IMG_PVOID pvParam, -+ IMG_UINT32 ui32Param, -+ IMG_BOOL bExecuteCallback); -+ -+ -+#ifdef DEBUG -+ static IMG_VOID ValidateResList(PRESMAN_LIST psResList); -+ #define VALIDATERESLIST() ValidateResList(gpsResList) -+#else -+ #define VALIDATERESLIST() -+#endif -+ -+ -+ -+ -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function ResManInit -+ -+ @Description initialises the resman -+ -+ @Return none -+ -+******************************************************************************/ -+PVRSRV_ERROR ResManInit(IMG_VOID) -+{ -+ if (gpsResList == IMG_NULL) -+ { -+ /* If not already initialised */ -+ if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(*gpsResList), -+ (IMG_VOID **)&gpsResList, IMG_NULL, -+ "Resource Manager List") != PVRSRV_OK) -+ { -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ -+ /* Init list, the linked list has dummy entries at both ends */ -+ gpsResList->psContextList = IMG_NULL; -+ -+ /* Check resource list */ -+ VALIDATERESLIST(); -+ } -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function ResManDeInit -+ -+ @Description de-initialises the resman -+ -+ @Return none -+ -+******************************************************************************/ -+IMG_VOID ResManDeInit(IMG_VOID) -+{ -+ if (gpsResList != IMG_NULL) -+ { -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*gpsResList), gpsResList, IMG_NULL); -+ gpsResList = IMG_NULL; -+ } -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVResManConnect -+ -+ @Description Opens a connection to the Resource Manager -+ -+ @input hPerProc - Per-process data (if applicable) -+ @output phResManContext - Resman context -+ -+ @Return error code or PVRSRV_OK -+ -+******************************************************************************/ -+PVRSRV_ERROR PVRSRVResManConnect(IMG_HANDLE hPerProc, -+ PRESMAN_CONTEXT *phResManContext) -+{ -+ PVRSRV_ERROR eError; -+ PRESMAN_CONTEXT psResManContext; -+ -+ /*Acquire resource list sync object*/ -+ ACQUIRE_SYNC_OBJ; -+ -+ /*Check resource list*/ -+ VALIDATERESLIST(); -+ -+ /* Allocate memory for the new context. */ -+ eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*psResManContext), -+ (IMG_VOID **)&psResManContext, IMG_NULL, -+ "Resource Manager Context"); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVResManConnect: ERROR allocating new RESMAN context struct")); -+ -+ /* Check resource list */ -+ VALIDATERESLIST(); -+ -+ /* Release resource list sync object */ -+ RELEASE_SYNC_OBJ; -+ -+ return eError; -+ } -+ -+#ifdef DEBUG -+ psResManContext->ui32Signature = RESMAN_SIGNATURE; -+#endif /* DEBUG */ -+ psResManContext->psResItemList = IMG_NULL; -+ psResManContext->psPerProc = hPerProc; -+ -+ /* Insert new context struct after the dummy first entry */ -+ List_RESMAN_CONTEXT_Insert(&gpsResList->psContextList, psResManContext); -+ -+ /* Check resource list */ -+ VALIDATERESLIST(); -+ -+ /* Release resource list sync object */ -+ RELEASE_SYNC_OBJ; -+ -+ *phResManContext = psResManContext; -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVResManDisconnect -+ -+ @Description Closes a Resource Manager connection and frees all resources -+ -+ @input hResManContext - Resman context -+ @input bKernelContext - IMG_TRUE for kernel contexts -+ -+ @Return IMG_VOID -+ -+******************************************************************************/ -+IMG_VOID PVRSRVResManDisconnect(PRESMAN_CONTEXT psResManContext, -+ IMG_BOOL bKernelContext) -+{ -+ /* Acquire resource list sync object */ -+ ACQUIRE_SYNC_OBJ; -+ -+ /* Check resource list */ -+ VALIDATERESLIST(); -+ -+ /* Print and validate resource list */ -+ PRINT_RESLIST(gpsResList, psResManContext, IMG_TRUE); -+ -+ /* Free all auto-freed resources in order */ -+ -+ if (!bKernelContext) -+ { -+ /* OS specific User-mode Mappings: */ -+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_OS_USERMODE_MAPPING, 0, 0, IMG_TRUE); -+ -+ /* VGX types: */ -+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DMA_CLIENT_FIFO_DATA, 0, 0, IMG_TRUE); -+ -+ /* Event Object */ -+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_EVENT_OBJECT, 0, 0, IMG_TRUE); -+ -+ /* syncobject state (Read/Write Complete values) */ -+ /* Must be FIFO, so we reverse the list, twice */ -+ List_RESMAN_ITEM_Reverse(&psResManContext->psResItemList); -+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_MODIFY_SYNC_OPS, 0, 0, IMG_TRUE); -+ List_RESMAN_ITEM_Reverse(&psResManContext->psResItemList); // (could survive without this - all following items would be cleared up "fifo" too) -+ -+ /* SGX types: */ -+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_HW_RENDER_CONTEXT, 0, 0, IMG_TRUE); -+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_HW_TRANSFER_CONTEXT, 0, 0, IMG_TRUE); -+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_HW_2D_CONTEXT, 0, 0, IMG_TRUE); -+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_TRANSFER_CONTEXT, 0, 0, IMG_TRUE); -+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_SHARED_PB_DESC_CREATE_LOCK, 0, 0, IMG_TRUE); -+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_SHARED_PB_DESC, 0, 0, IMG_TRUE); -+ -+ /* COMMON types: */ -+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_SYNC_INFO, 0, 0, IMG_TRUE); -+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICECLASSMEM_MAPPING, 0, 0, IMG_TRUE); -+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICEMEM_WRAP, 0, 0, IMG_TRUE); -+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICEMEM_MAPPING, 0, 0, IMG_TRUE); -+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_KERNEL_DEVICEMEM_ALLOCATION, 0, 0, IMG_TRUE); -+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICEMEM_ALLOCATION, 0, 0, IMG_TRUE); -+#if defined(SUPPORT_ION) -+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICEMEM_ION, 0, 0, IMG_TRUE); -+#endif -+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICEMEM_CONTEXT, 0, 0, IMG_TRUE); -+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_SHARED_MEM_INFO, 0, 0, IMG_TRUE); -+ -+ /* DISPLAY CLASS types: */ -+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DISPLAYCLASS_SWAPCHAIN_REF, 0, 0, IMG_TRUE); -+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DISPLAYCLASS_DEVICE, 0, 0, IMG_TRUE); -+ -+ /* BUFFER CLASS types: */ -+ FreeResourceByCriteria(psResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_BUFFERCLASS_DEVICE, 0, 0, IMG_TRUE); -+ } -+ -+ /* Ensure that there are no resources left */ -+ PVR_ASSERT(psResManContext->psResItemList == IMG_NULL); -+ -+ /* Remove the context struct from the list */ -+ List_RESMAN_CONTEXT_Remove(psResManContext); -+ -+ /* Free the context struct */ -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RESMAN_CONTEXT), psResManContext, IMG_NULL); -+ /*not nulling pointer, copy on stack*/ -+ -+ -+ /* Check resource list */ -+ VALIDATERESLIST(); -+ -+ /* Print and validate resource list */ -+ PRINT_RESLIST(gpsResList, psResManContext, IMG_FALSE); -+ -+ /* Release resource list sync object */ -+ RELEASE_SYNC_OBJ; -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function ResManRegisterRes -+ -+ @Description : Inform the resource manager that the given resource has -+ been alloacted and freeing of it will be the responsibility -+ of the resource manager -+ -+ @input psResManContext - resman context -+ @input ui32ResType - identify what kind of resource it is -+ @input pvParam - address of resource -+ @input ui32Param - size of resource -+ @input pfnFreeResource - pointer to function that frees this resource -+ -+ @Return On success a pointer to an opaque data structure that represents -+ the allocated resource, else NULL -+ -+**************************************************************************/ -+PRESMAN_ITEM ResManRegisterRes(PRESMAN_CONTEXT psResManContext, -+ IMG_UINT32 ui32ResType, -+ IMG_PVOID pvParam, -+ IMG_UINT32 ui32Param, -+ RESMAN_FREE_FN pfnFreeResource) -+{ -+ PRESMAN_ITEM psNewResItem; -+ -+ PVR_ASSERT(psResManContext != IMG_NULL); -+ PVR_ASSERT(ui32ResType != 0); -+ -+ if (psResManContext == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "ResManRegisterRes: invalid parameter - psResManContext")); -+ return (PRESMAN_ITEM) IMG_NULL; -+ } -+ -+ /* Acquire resource list sync object */ -+ ACQUIRE_SYNC_OBJ; -+ -+ /* Check resource list */ -+ VALIDATERESLIST(); -+ -+ PVR_DPF((PVR_DBG_MESSAGE, "ResManRegisterRes: register resource " -+ "Context 0x%p, ResType 0x%x, pvParam 0x%p, ui32Param 0x%x, " -+ "FreeFunc %p", -+ psResManContext, -+ ui32ResType, -+ pvParam, -+ ui32Param, -+ pfnFreeResource)); -+ -+ /* Allocate memory for the new resource structure */ -+ if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(RESMAN_ITEM), (IMG_VOID **)&psNewResItem, -+ IMG_NULL, -+ "Resource Manager Item") != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "ResManRegisterRes: " -+ "ERROR allocating new resource item")); -+ -+ /* Release resource list sync object */ -+ RELEASE_SYNC_OBJ; -+ -+ return((PRESMAN_ITEM)IMG_NULL); -+ } -+ -+ /* Fill in details about this resource */ -+#ifdef DEBUG -+ psNewResItem->ui32Signature = RESMAN_SIGNATURE; -+#endif /* DEBUG */ -+ psNewResItem->ui32ResType = ui32ResType; -+ psNewResItem->pvParam = pvParam; -+ psNewResItem->ui32Param = ui32Param; -+ psNewResItem->pfnFreeResource = pfnFreeResource; -+ psNewResItem->ui32Flags = 0; -+ -+ /* Insert new structure after dummy first entry */ -+ List_RESMAN_ITEM_Insert(&psResManContext->psResItemList, psNewResItem); -+ -+ /* Check resource list */ -+ VALIDATERESLIST(); -+ -+ /* Release resource list sync object */ -+ RELEASE_SYNC_OBJ; -+ -+ return(psNewResItem); -+} -+ -+/*! -+****************************************************************************** -+ @Function ResManFreeResByPtr -+ -+ @Description frees a resource by matching on pointer type -+ -+ @inputs psResItem - pointer to resource item to free -+ bForceCleanup - ignored uKernel re-sync -+ -+ @Return PVRSRV_ERROR -+**************************************************************************/ -+PVRSRV_ERROR ResManFreeResByPtr(RESMAN_ITEM *psResItem, IMG_BOOL bForceCleanup) -+{ -+ PVRSRV_ERROR eError; -+ -+ PVR_ASSERT(psResItem != IMG_NULL); -+ -+ if (psResItem == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_MESSAGE, "ResManFreeResByPtr: NULL ptr - nothing to do")); -+ return PVRSRV_OK; -+ } -+ -+ PVR_DPF((PVR_DBG_MESSAGE, "ResManFreeResByPtr: freeing resource at %p", -+ psResItem)); -+ -+ /*Acquire resource list sync object*/ -+ ACQUIRE_SYNC_OBJ; -+ -+ /*Check resource list*/ -+ VALIDATERESLIST(); -+ -+ /*Free resource*/ -+ eError = FreeResourceByPtr(psResItem, IMG_TRUE, bForceCleanup); -+ -+ /*Check resource list*/ -+ VALIDATERESLIST(); -+ -+ /*Release resource list sync object*/ -+ RELEASE_SYNC_OBJ; -+ -+ return(eError); -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function ResManFreeResByCriteria -+ -+ @Description frees a resource by matching on criteria -+ -+ @inputs hResManContext - handle for resman context -+ @inputs ui32SearchCriteria - indicates which parameters should be -+ used in search for resources to free -+ @inputs ui32ResType - identify what kind of resource to free -+ @inputs pvParam - address of resource to be free -+ @inputs ui32Param - size of resource to be free -+ -+ @Return PVRSRV_ERROR -+**************************************************************************/ -+PVRSRV_ERROR ResManFreeResByCriteria(PRESMAN_CONTEXT psResManContext, -+ IMG_UINT32 ui32SearchCriteria, -+ IMG_UINT32 ui32ResType, -+ IMG_PVOID pvParam, -+ IMG_UINT32 ui32Param) -+{ -+ PVRSRV_ERROR eError; -+ -+ PVR_ASSERT(psResManContext != IMG_NULL); -+ -+ /* Acquire resource list sync object */ -+ ACQUIRE_SYNC_OBJ; -+ -+ /* Check resource list */ -+ VALIDATERESLIST(); -+ -+ PVR_DPF((PVR_DBG_MESSAGE, "ResManFreeResByCriteria: " -+ "Context 0x%p, Criteria 0x%x, Type 0x%x, Addr 0x%p, Param 0x%x", -+ psResManContext, ui32SearchCriteria, ui32ResType, -+ pvParam, ui32Param)); -+ -+ /* Free resources by criteria for this context */ -+ eError = FreeResourceByCriteria(psResManContext, ui32SearchCriteria, -+ ui32ResType, pvParam, ui32Param, -+ IMG_TRUE); -+ -+ /* Check resource list */ -+ VALIDATERESLIST(); -+ -+ /* Release resource list sync object */ -+ RELEASE_SYNC_OBJ; -+ -+ return eError; -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function ResManDissociateRes -+ -+ @Description Moves a resource from one context to another. -+ -+ @inputs psResItem - pointer to resource item to dissociate -+ @inputs psNewResManContext - new resman context for the resource -+ -+ @Return IMG_VOID -+**************************************************************************/ -+PVRSRV_ERROR ResManDissociateRes(RESMAN_ITEM *psResItem, -+ PRESMAN_CONTEXT psNewResManContext) -+{ -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ -+ PVR_ASSERT(psResItem != IMG_NULL); -+ -+ if (psResItem == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "ResManDissociateRes: invalid parameter - psResItem")); -+ PVR_DBG_BREAK; -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+#ifdef DEBUG /* QAC fix */ -+ PVR_ASSERT(psResItem->ui32Signature == RESMAN_SIGNATURE); -+#endif -+ -+ if (psNewResManContext != IMG_NULL) -+ { -+ /* Remove this item from its old resource list */ -+ List_RESMAN_ITEM_Remove(psResItem); -+ -+ /* Re-insert into new list */ -+ List_RESMAN_ITEM_Insert(&psNewResManContext->psResItemList, psResItem); -+ -+ } -+ else -+ { -+ eError = FreeResourceByPtr(psResItem, IMG_FALSE, CLEANUP_WITH_POLL); -+ if(eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "ResManDissociateRes: failed to free resource by pointer")); -+ return eError; -+ } -+ } -+ -+ return eError; -+} -+ -+/*! -+****************************************************************************** -+ @Function ResManFindResourceByPtr_AnyVaCb -+ -+ @Description -+ Compares the resman item with a given pointer. -+ -+ @inputs psCurItem - theThe item to check -+ @inputs va - Variable argument list with: -+ psItem - pointer to resource item to find -+ -+ @Return IMG_BOOL -+**************************************************************************/ -+static IMG_BOOL ResManFindResourceByPtr_AnyVaCb(RESMAN_ITEM *psCurItem, va_list va) -+{ -+ RESMAN_ITEM *psItem; -+ -+ psItem = va_arg(va, RESMAN_ITEM*); -+ -+ return (IMG_BOOL)(psCurItem == psItem); -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function ResManFindResourceByPtr -+ -+ @Description -+ Attempts to find a resource in the list for this context -+ -+ @inputs hResManContext - handle for resman context -+ @inputs psItem - pointer to resource item to find -+ -+ @Return PVRSRV_ERROR -+**************************************************************************/ -+IMG_INTERNAL PVRSRV_ERROR ResManFindResourceByPtr(PRESMAN_CONTEXT psResManContext, -+ RESMAN_ITEM *psItem) -+{ -+/* RESMAN_ITEM *psCurItem;*/ -+ -+ PVRSRV_ERROR eResult; -+ -+ PVR_ASSERT(psResManContext != IMG_NULL); -+ PVR_ASSERT(psItem != IMG_NULL); -+ -+ if ((psItem == IMG_NULL) || (psResManContext == IMG_NULL)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "ResManFindResourceByPtr: invalid parameter")); -+ PVR_DBG_BREAK; -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+#ifdef DEBUG /* QAC fix */ -+ PVR_ASSERT(psItem->ui32Signature == RESMAN_SIGNATURE); -+#endif -+ -+ /* Acquire resource list sync object */ -+ ACQUIRE_SYNC_OBJ; -+ -+ PVR_DPF((PVR_DBG_MESSAGE, -+ "FindResourceByPtr: psItem=%p, psItem->psNext=%p", -+ psItem, psItem->psNext)); -+ -+ PVR_DPF((PVR_DBG_MESSAGE, -+ "FindResourceByPtr: Resource Ctx 0x%p, Type 0x%x, Addr 0x%p, " -+ "Param 0x%x, FnCall %p, Flags 0x%x", -+ psResManContext, -+ psItem->ui32ResType, -+ psItem->pvParam, -+ psItem->ui32Param, -+ psItem->pfnFreeResource, -+ psItem->ui32Flags)); -+ -+ /* Search resource items starting at after the first dummy item */ -+ if(List_RESMAN_ITEM_IMG_BOOL_Any_va(psResManContext->psResItemList, -+ &ResManFindResourceByPtr_AnyVaCb, -+ psItem)) -+ { -+ eResult = PVRSRV_OK; -+ } -+ else -+ { -+ eResult = PVRSRV_ERROR_NOT_OWNER; -+ } -+ -+ /* Release resource list sync object */ -+ RELEASE_SYNC_OBJ; -+ -+/* return PVRSRV_ERROR_NOT_OWNER;*/ -+ return eResult; -+} -+ -+/*! -+****************************************************************************** -+ @Function FreeResourceByPtr -+ -+ @Description -+ Frees a resource and move it from the list -+ NOTE : this function must be called with the resource -+ list sync object held -+ -+ @inputs psItem - pointer to resource item to free -+ bExecuteCallback - execute callback? -+ bForceCleanup - skips uKernel re-sync -+ -+ @Return PVRSRV_ERROR -+**************************************************************************/ -+static PVRSRV_ERROR FreeResourceByPtr(RESMAN_ITEM *psItem, -+ IMG_BOOL bExecuteCallback, -+ IMG_BOOL bForceCleanup) -+{ -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ -+ PVR_ASSERT(psItem != IMG_NULL); -+ -+ if (psItem == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "FreeResourceByPtr: invalid parameter")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+#ifdef DEBUG /* QAC fix */ -+ PVR_ASSERT(psItem->ui32Signature == RESMAN_SIGNATURE); -+#endif -+ -+ PVR_DPF((PVR_DBG_MESSAGE, -+ "FreeResourceByPtr: psItem=%p, psItem->psNext=%p", -+ psItem, psItem->psNext)); -+ -+ PVR_DPF((PVR_DBG_MESSAGE, -+ "FreeResourceByPtr: Type 0x%x, Addr 0x%p, " -+ "Param 0x%x, FnCall %p, Flags 0x%x", -+ psItem->ui32ResType, -+ psItem->pvParam, -+ psItem->ui32Param, -+ psItem->pfnFreeResource, psItem->ui32Flags)); -+ -+ /* Release resource list sync object just in case the free routine calls the resource manager */ -+ RELEASE_SYNC_OBJ; -+ -+ /* Call the freeing routine */ -+ if (bExecuteCallback) -+ { -+ eError = psItem->pfnFreeResource(psItem->pvParam, psItem->ui32Param, bForceCleanup); -+ if ((eError != PVRSRV_OK) && (eError != PVRSRV_ERROR_RETRY)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "FreeResourceByPtr: ERROR calling FreeResource function")); -+ } -+ } -+ -+ /* Acquire resource list sync object */ -+ ACQUIRE_SYNC_OBJ; -+ -+ if (eError != PVRSRV_ERROR_RETRY) -+ { -+ /* Remove this item from the resource list */ -+ List_RESMAN_ITEM_Remove(psItem); -+ -+ /* Free memory for the resource item */ -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RESMAN_ITEM), psItem, IMG_NULL); -+ } -+ -+ return(eError); -+} -+ -+/*! -+****************************************************************************** -+ @Function FreeResourceByCriteria_AnyVaCb -+ -+ @Description -+ Matches a resource manager item with a given criteria. -+ -+ @inputs psCuItem - the item to be matched -+ @inputs va - a variable argument list with:. -+ ui32SearchCriteria - indicates which parameters should be used -+ search for resources to free -+ ui32ResType - identify what kind of resource to free -+ pvParam - address of resource to be free -+ ui32Param - size of resource to be free -+ -+ -+ @Return psCurItem if matched, IMG_NULL otherwise. -+**************************************************************************/ -+static IMG_VOID* FreeResourceByCriteria_AnyVaCb(RESMAN_ITEM *psCurItem, va_list va) -+{ -+ IMG_UINT32 ui32SearchCriteria; -+ IMG_UINT32 ui32ResType; -+ IMG_PVOID pvParam; -+ IMG_UINT32 ui32Param; -+ -+ ui32SearchCriteria = va_arg(va, IMG_UINT32); -+ ui32ResType = va_arg(va, IMG_UINT32); -+ pvParam = va_arg(va, IMG_PVOID); -+ ui32Param = va_arg(va, IMG_UINT32); -+ -+ /*check that for all conditions are either disabled or eval to true*/ -+ if( -+ /* Check resource type */ -+ (((ui32SearchCriteria & RESMAN_CRITERIA_RESTYPE) == 0UL) || -+ (psCurItem->ui32ResType == ui32ResType)) -+ && -+ /* Check address */ -+ (((ui32SearchCriteria & RESMAN_CRITERIA_PVOID_PARAM) == 0UL) || -+ (psCurItem->pvParam == pvParam)) -+ && -+ /* Check size */ -+ (((ui32SearchCriteria & RESMAN_CRITERIA_UI32_PARAM) == 0UL) || -+ (psCurItem->ui32Param == ui32Param)) -+ ) -+ { -+ return psCurItem; -+ } -+ else -+ { -+ return IMG_NULL; -+ } -+} -+ -+/*! -+****************************************************************************** -+ @Function FreeResourceByCriteria -+ -+ @Description -+ Frees all resources that match the given criteria for the -+ context. -+ NOTE : this function must be called with the resource -+ list sync object held -+ -+ @inputs psResManContext - pointer to resman context -+ @inputs ui32SearchCriteria - indicates which parameters should be used -+ @inputs search for resources to free -+ @inputs ui32ResType - identify what kind of resource to free -+ @inputs pvParam - address of resource to be free -+ @inputs ui32Param - size of resource to be free -+ @inputs ui32AutoFreeLev - auto free level to free -+ @inputs bExecuteCallback - execute callback? -+ -+ @Return PVRSRV_ERROR -+**************************************************************************/ -+static PVRSRV_ERROR FreeResourceByCriteria(PRESMAN_CONTEXT psResManContext, -+ IMG_UINT32 ui32SearchCriteria, -+ IMG_UINT32 ui32ResType, -+ IMG_PVOID pvParam, -+ IMG_UINT32 ui32Param, -+ IMG_BOOL bExecuteCallback) -+{ -+ PRESMAN_ITEM psCurItem; -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ -+ /* Search resource items starting at after the first dummy item */ -+ /*while we get a match and not an error*/ -+ while((psCurItem = (PRESMAN_ITEM) -+ List_RESMAN_ITEM_Any_va(psResManContext->psResItemList, -+ &FreeResourceByCriteria_AnyVaCb, -+ ui32SearchCriteria, -+ ui32ResType, -+ pvParam, -+ ui32Param)) != IMG_NULL -+ && eError == PVRSRV_OK) -+ { -+ do -+ { -+ eError = FreeResourceByPtr(psCurItem, bExecuteCallback, CLEANUP_WITH_POLL); -+ if (eError == PVRSRV_ERROR_RETRY) -+ { -+ RELEASE_SYNC_OBJ; -+ OSReleaseBridgeLock(); -+ /* Give a chance for other threads to come in and SGX to do more work */ -+ OSSleepms(MAX_CLEANUP_TIME_WAIT_US/1000); -+ OSReacquireBridgeLock(); -+ ACQUIRE_SYNC_OBJ; -+ } -+ } while (eError == PVRSRV_ERROR_RETRY); -+ } -+ -+ return eError; -+} -+ -+ -+#ifdef DEBUG -+/*! -+****************************************************************************** -+ @Function ValidateResList -+ -+ @Description -+ Walks the resource list check the pointers -+ NOTE : this function must be called with the resource -+ list sync object held -+ -+ @Return none -+**************************************************************************/ -+static IMG_VOID ValidateResList(PRESMAN_LIST psResList) -+{ -+ PRESMAN_ITEM psCurItem, *ppsThisItem; -+ PRESMAN_CONTEXT psCurContext, *ppsThisContext; -+ -+ /* check we're initialised */ -+ if (psResList == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_MESSAGE, "ValidateResList: resman not initialised yet")); -+ return; -+ } -+ -+ psCurContext = psResList->psContextList; -+ ppsThisContext = &psResList->psContextList; -+ -+ /* Walk the context list */ -+ while(psCurContext != IMG_NULL) -+ { -+ /* Check current item */ -+ PVR_ASSERT(psCurContext->ui32Signature == RESMAN_SIGNATURE); -+ if (psCurContext->ppsThis != ppsThisContext) -+ { -+ PVR_DPF((PVR_DBG_WARNING, -+ "psCC=%p psCC->ppsThis=%p psCC->psNext=%p ppsTC=%p", -+ psCurContext, -+ psCurContext->ppsThis, -+ psCurContext->psNext, -+ ppsThisContext)); -+ PVR_ASSERT(psCurContext->ppsThis == ppsThisContext); -+ } -+ -+ /* Walk the list for this context */ -+ psCurItem = psCurContext->psResItemList; -+ ppsThisItem = &psCurContext->psResItemList; -+ while(psCurItem != IMG_NULL) -+ { -+ /* Check current item */ -+ PVR_ASSERT(psCurItem->ui32Signature == RESMAN_SIGNATURE); -+ if (psCurItem->ppsThis != ppsThisItem) -+ { -+ PVR_DPF((PVR_DBG_WARNING, -+ "psCurItem=%p psCurItem->ppsThis=%p psCurItem->psNext=%p ppsThisItem=%p", -+ psCurItem, -+ psCurItem->ppsThis, -+ psCurItem->psNext, -+ ppsThisItem)); -+ PVR_ASSERT(psCurItem->ppsThis == ppsThisItem); -+ } -+ -+ /* Move to next item */ -+ ppsThisItem = &psCurItem->psNext; -+ psCurItem = psCurItem->psNext; -+ } -+ -+ /* Move to next context */ -+ ppsThisContext = &psCurContext->psNext; -+ psCurContext = psCurContext->psNext; -+ } -+} -+#endif /* DEBUG */ -+ -+ -+/****************************************************************************** -+ End of file (resman.c) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/common/ttrace.c b/drivers/staging/ti-es8-sgx/services4/srvkm/common/ttrace.c -new file mode 100644 -index 0000000..6320273 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/common/ttrace.c -@@ -0,0 +1,597 @@ -+/*************************************************************************/ /*! -+@Title Timed Trace functions -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+#if defined (TTRACE) -+ -+#include "services_headers.h" -+#include "ttrace.h" -+ -+#if defined(PVRSRV_NEED_PVR_DPF) -+#define CHECKSIZE(n,m) \ -+ if ((n & m) != n) \ -+ PVR_DPF((PVR_DBG_ERROR,"Size check failed for " #m)) -+#else -+#define CHECKSIZE(n,m) -+#endif -+ -+#define TIME_TRACE_HASH_TABLE_SIZE 32 -+ -+HASH_TABLE *g_psBufferTable; -+IMG_UINT32 g_ui32HostUID; -+IMG_HANDLE g_psTimer; -+ -+/* Trace buffer struct */ -+typedef struct -+{ -+ IMG_UINT32 ui32Woff; /* Offset to where next item will be written */ -+ IMG_UINT32 ui32Roff; /* Offset to where to start reading from */ -+ IMG_UINT32 ui32ByteCount; /* Number of bytes in buffer */ -+ IMG_UINT8 ui8Data[0]; -+} sTimeTraceBuffer; -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVTimeTraceItemSize -+ -+ @Description -+ -+ Calculate the size of a trace item -+ -+ @Input psTraceItem : Trace item -+ -+ @Return size of trace item -+ -+******************************************************************************/ -+static IMG_UINT32 -+PVRSRVTimeTraceItemSize(IMG_UINT32 *psTraceItem) -+{ -+ IMG_UINT32 ui32Size = PVRSRV_TRACE_ITEM_SIZE; -+ -+ ui32Size += READ_HEADER(SIZE, psTraceItem[PVRSRV_TRACE_DATA_HEADER]); -+ -+ return ui32Size; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVTimeTraceAllocItem -+ -+ @Description -+ -+ Allocate a trace item from the buffer of the current process -+ -+ @Output ppsTraceItem : Pointer to allocated trace item -+ -+ @Input ui32Size : Size of data packet to be allocated -+ -+ @Return none -+ -+******************************************************************************/ -+static IMG_VOID -+PVRSRVTimeTraceAllocItem(IMG_UINT32 **pui32Item, IMG_UINT32 ui32Size) -+{ -+ IMG_UINT32 ui32PID = OSGetCurrentProcessIDKM(); -+ IMG_UINT32 ui32AllocOffset; -+ sTimeTraceBuffer *psBuffer = (sTimeTraceBuffer *) HASH_Retrieve(g_psBufferTable, (IMG_UINTPTR_T) ui32PID); -+ -+ /* The caller only asks for extra data space */ -+ ui32Size += PVRSRV_TRACE_ITEM_SIZE; -+ -+ /* Always round to 32-bit */ -+ ui32Size = ((ui32Size - 1) & (~0x3)) + 0x04; -+ -+ if (!psBuffer) -+ { -+ PVRSRV_ERROR eError; -+ -+ PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVTimeTraceAllocItem: Creating buffer for PID %u", ui32PID)); -+ eError = PVRSRVTimeTraceBufferCreate(ui32PID); -+ if (eError != PVRSRV_OK) -+ { -+ *pui32Item = IMG_NULL; -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVTimeTraceAllocItem: Failed to create buffer")); -+ return; -+ } -+ -+ psBuffer = (sTimeTraceBuffer *) HASH_Retrieve(g_psBufferTable, (IMG_UINTPTR_T) ui32PID); -+ if (psBuffer == IMG_NULL) -+ { -+ *pui32Item = NULL; -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVTimeTraceAllocItem: Failed to retrieve buffer")); -+ return; -+ } -+ } -+ -+ /* Can't allocate more then buffer size */ -+ if (ui32Size >= TIME_TRACE_BUFFER_SIZE) -+ { -+ *pui32Item = NULL; -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVTimeTraceAllocItem: Error trace item too large (%d)", ui32Size)); -+ return; -+ } -+ -+ /* FIXME: Enter critical section? */ -+ -+ /* Always ensure we have enough space to write a padding message */ -+ if ((psBuffer->ui32Woff + ui32Size + PVRSRV_TRACE_ITEM_SIZE) > TIME_TRACE_BUFFER_SIZE) -+ { -+ IMG_UINT32 *ui32WriteEOB = (IMG_UINT32 *) &psBuffer->ui8Data[psBuffer->ui32Woff]; -+ IMG_UINT32 ui32Remain = TIME_TRACE_BUFFER_SIZE - psBuffer->ui32Woff; -+ -+ /* Not enough space at the end of the buffer, back to the start */ -+ *ui32WriteEOB++ = WRITE_HEADER(GROUP, PVRSRV_TRACE_GROUP_PADDING); -+ *ui32WriteEOB++ = 0; /* Don't need timestamp */ -+ *ui32WriteEOB++ = 0; /* Don't need UID */ -+ *ui32WriteEOB = WRITE_HEADER(SIZE, (ui32Remain - PVRSRV_TRACE_ITEM_SIZE)); -+ psBuffer->ui32ByteCount += ui32Remain; -+ psBuffer->ui32Woff = ui32AllocOffset = 0; -+ } -+ else -+ ui32AllocOffset = psBuffer->ui32Woff; -+ -+ psBuffer->ui32Woff = psBuffer->ui32Woff + ui32Size; -+ psBuffer->ui32ByteCount += ui32Size; -+ -+ /* This allocation will start overwriting past our read pointer, move the read pointer along */ -+ while (psBuffer->ui32ByteCount > TIME_TRACE_BUFFER_SIZE) -+ { -+ IMG_UINT32 *psReadItem = (IMG_UINT32 *) &psBuffer->ui8Data[psBuffer->ui32Roff]; -+ IMG_UINT32 ui32ReadSize; -+ -+ ui32ReadSize = PVRSRVTimeTraceItemSize(psReadItem); -+ psBuffer->ui32Roff = (psBuffer->ui32Roff + ui32ReadSize) & (TIME_TRACE_BUFFER_SIZE - 1); -+ psBuffer->ui32ByteCount -= ui32ReadSize; -+ } -+ -+ *pui32Item = (IMG_UINT32 *) &psBuffer->ui8Data[ui32AllocOffset]; -+ /* FIXME: Exit critical section? */ -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVTimeTraceBufferCreate -+ -+ @Description -+ -+ Create a trace buffer. -+ -+ Note: We assume that this will only be called once per process. -+ -+ @Input ui32PID : PID of the process that is creating the buffer -+ -+ @Return none -+ -+******************************************************************************/ -+PVRSRV_ERROR PVRSRVTimeTraceBufferCreate(IMG_UINT32 ui32PID) -+{ -+ sTimeTraceBuffer *psBuffer; -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ -+ eError = OSAllocMem(PVRSRV_PAGEABLE_SELECT, -+ sizeof(sTimeTraceBuffer) + TIME_TRACE_BUFFER_SIZE, -+ (IMG_VOID **)&psBuffer, IMG_NULL, -+ "Time Trace Buffer"); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVTimeTraceBufferCreate: Error allocating trace buffer")); -+ return eError; -+ } -+ -+ OSMemSet(psBuffer, 0, TIME_TRACE_BUFFER_SIZE); -+ -+ if (!HASH_Insert(g_psBufferTable, (IMG_UINTPTR_T) ui32PID, (IMG_UINTPTR_T) psBuffer)) -+ { -+ OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(sTimeTraceBuffer) + TIME_TRACE_BUFFER_SIZE, -+ psBuffer, NULL); -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVTimeTraceBufferCreate: Error adding trace buffer to hash table")); -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ -+ return eError; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVTimeTraceBufferDestroy -+ -+ @Description -+ -+ Destroy a trace buffer. -+ -+ Note: We assume that this will only be called once per process. -+ -+ @Input ui32PID : PID of the process that is creating the buffer -+ -+ @Return none -+ -+******************************************************************************/ -+PVRSRV_ERROR PVRSRVTimeTraceBufferDestroy(IMG_UINT32 ui32PID) -+{ -+ sTimeTraceBuffer *psBuffer; -+ -+#if defined(DUMP_TTRACE_BUFFERS_ON_EXIT) -+ PVRSRVDumpTimeTraceBuffers(); -+#endif -+ psBuffer = (sTimeTraceBuffer *) HASH_Retrieve(g_psBufferTable, (IMG_UINTPTR_T) ui32PID); -+ if (psBuffer) -+ { -+ OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(sTimeTraceBuffer) + TIME_TRACE_BUFFER_SIZE, -+ psBuffer, NULL); -+ HASH_Remove(g_psBufferTable, (IMG_UINTPTR_T) ui32PID); -+ return PVRSRV_OK; -+ } -+ -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVTimeTraceBufferDestroy: Can't find trace buffer in hash table")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVTimeTraceInit -+ -+ @Description -+ -+ Initialise the timed trace subsystem. -+ -+ @Return Error -+ -+******************************************************************************/ -+PVRSRV_ERROR PVRSRVTimeTraceInit(IMG_VOID) -+{ -+ g_psBufferTable = HASH_Create(TIME_TRACE_HASH_TABLE_SIZE); -+ -+ /* Create hash table to store the per process buffers in */ -+ if (!g_psBufferTable) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVTimeTraceInit: Error creating hash table")); -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ -+ /* Create the kernel buffer */ -+ PVRSRVTimeTraceBufferCreate(KERNEL_ID); -+ -+ g_psTimer = OSFuncHighResTimerCreate(); -+ -+ if (!g_psTimer) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVTimeTraceInit: Error creating timer")); -+ return PVRSRV_ERROR_INIT_FAILURE; -+ } -+ return PVRSRV_OK; -+} -+ -+static PVRSRV_ERROR _PVRSRVTimeTraceBufferDestroy(IMG_UINTPTR_T hKey, IMG_UINTPTR_T hData) -+{ -+ PVR_UNREFERENCED_PARAMETER(hData); -+ PVR_DPF((PVR_DBG_MESSAGE, "_PVRSRVTimeTraceBufferDestroy: Destroying buffer for PID %u", (IMG_UINT32) hKey)); -+ -+ PVRSRVTimeTraceBufferDestroy(hKey); -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVTimeTraceDeinit -+ -+ @Description -+ -+ De-initialise the timed trace subsystem. -+ -+ @Return Error -+ -+******************************************************************************/ -+IMG_VOID PVRSRVTimeTraceDeinit(IMG_VOID) -+{ -+ PVRSRVTimeTraceBufferDestroy(KERNEL_ID); -+ /* Free any buffers the where created at alloc item time */ -+ HASH_Iterate(g_psBufferTable, _PVRSRVTimeTraceBufferDestroy); -+ HASH_Delete(g_psBufferTable); -+ OSFuncHighResTimerDestroy(g_psTimer); -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVTimeTraceWriteHeader -+ -+ @Description -+ -+ Write the header for a trace item. -+ -+ @Input pui32TraceItem : Pointer to trace item -+ -+ @Input ui32Group : Trace item's group ID -+ -+ @Input ui32Class : Trace item's class ID -+ -+ @Input ui32Token : Trace item's ui32Token ID -+ -+ @Input ui32Size : Trace item's data payload size -+ -+ @Input ui32Type : Trace item's data type -+ -+ @Input ui32Count : Trace item's data count -+ -+ @Return Pointer to data payload space, or NULL if no data payload -+ -+******************************************************************************/ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(PVRSRVTimeTraceWriteHeader) -+#endif -+static INLINE IMG_VOID *PVRSRVTimeTraceWriteHeader(IMG_UINT32 *pui32TraceItem, IMG_UINT32 ui32Group, -+ IMG_UINT32 ui32Class, IMG_UINT32 ui32Token, -+ IMG_UINT32 ui32Size, IMG_UINT32 ui32Type, -+ IMG_UINT32 ui32Count) -+{ -+ /* Sanity check arg's */ -+ CHECKSIZE(ui32Group, PVRSRV_TRACE_GROUP_MASK); -+ CHECKSIZE(ui32Class, PVRSRV_TRACE_CLASS_MASK); -+ CHECKSIZE(ui32Token, PVRSRV_TRACE_TOKEN_MASK); -+ -+ CHECKSIZE(ui32Size, PVRSRV_TRACE_SIZE_MASK); -+ CHECKSIZE(ui32Type, PVRSRV_TRACE_TYPE_MASK); -+ CHECKSIZE(ui32Count, PVRSRV_TRACE_COUNT_MASK); -+ -+ /* Trace header */ -+ pui32TraceItem[PVRSRV_TRACE_HEADER] = WRITE_HEADER(GROUP, ui32Group); -+ pui32TraceItem[PVRSRV_TRACE_HEADER] |= WRITE_HEADER(CLASS, ui32Class); -+ pui32TraceItem[PVRSRV_TRACE_HEADER] |= WRITE_HEADER(TOKEN, ui32Token); -+ -+ /* Data header */ -+ pui32TraceItem[PVRSRV_TRACE_DATA_HEADER] = WRITE_HEADER(SIZE, ui32Size); -+ pui32TraceItem[PVRSRV_TRACE_DATA_HEADER] |= WRITE_HEADER(TYPE, ui32Type); -+ pui32TraceItem[PVRSRV_TRACE_DATA_HEADER] |= WRITE_HEADER(COUNT, ui32Count); -+ -+ pui32TraceItem[PVRSRV_TRACE_TIMESTAMP] = OSFuncHighResTimerGetus(g_psTimer); -+ pui32TraceItem[PVRSRV_TRACE_HOSTUID] = g_ui32HostUID++; -+ -+ return ui32Size?((IMG_VOID *) &pui32TraceItem[PVRSRV_TRACE_DATA_PAYLOAD]):NULL; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVTimeTraceArray -+ -+ @Description -+ -+ Write trace item with an array of data -+ -+ @Input ui32Group : Trace item's group ID -+ -+ @Input ui32Class : Trace item's class ID -+ -+ @Input ui32Token : Trace item's ui32Token ID -+ -+ @Input ui32Size : Trace item's data payload size -+ -+ @Input ui32Type : Trace item's data type -+ -+ @Input ui32Count : Trace item's data count -+ -+ @Input pui8Data : Pointer to data array -+ -+ @Return Pointer to data payload space, or NULL if no data payload -+ -+******************************************************************************/ -+IMG_VOID PVRSRVTimeTraceArray(IMG_UINT32 ui32Group, IMG_UINT32 ui32Class, IMG_UINT32 ui32Token, -+ IMG_UINT32 ui32Type, IMG_UINT32 ui32Count, IMG_UINT8 *pui8Data) -+{ -+ IMG_UINT32 *pui32TraceItem; -+ IMG_UINT32 ui32Size, ui32TypeSize; -+ IMG_UINT8 *ui8Ptr; -+ -+ /* Only the 1st 4 sizes are for ui types, others are "special" */ -+ switch (ui32Type) -+ { -+ case PVRSRV_TRACE_TYPE_UI8: ui32TypeSize = 1; -+ break; -+ case PVRSRV_TRACE_TYPE_UI16: ui32TypeSize = 2; -+ break; -+ case PVRSRV_TRACE_TYPE_UI32: ui32TypeSize = 4; -+ break; -+ case PVRSRV_TRACE_TYPE_UI64: ui32TypeSize = 8; -+ break; -+ default: -+ PVR_DPF((PVR_DBG_ERROR, "Unsupported size\n")); -+ return; -+ } -+ -+ ui32Size = ui32TypeSize * ui32Count; -+ -+ /* Allocate space from the buffer */ -+ PVRSRVTimeTraceAllocItem(&pui32TraceItem, ui32Size); -+ -+ if (!pui32TraceItem) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "Can't find buffer\n")); -+ return; -+ } -+ -+ ui8Ptr = PVRSRVTimeTraceWriteHeader(pui32TraceItem, ui32Group, ui32Class, ui32Token, -+ ui32Size, ui32Type, ui32Count); -+ -+ if (ui8Ptr) -+ { -+ OSMemCopy(ui8Ptr, pui8Data, ui32Size); -+ } -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVTimeTraceSyncObject -+ -+ @Description -+ -+ Write trace item with a sync object -+ -+ @Input ui32Group : Trace item's group ID -+ -+ @Input ui32Token : Trace item's ui32Token ID -+ -+ @Input psSync : Sync object -+ -+ @Input ui8SyncOpp : Sync object operation -+ -+ @Return None -+ -+******************************************************************************/ -+IMG_VOID PVRSRVTimeTraceSyncObject(IMG_UINT32 ui32Group, IMG_UINT32 ui32Token, -+ PVRSRV_KERNEL_SYNC_INFO *psSync, IMG_UINT8 ui8SyncOp) -+{ -+ IMG_UINT32 *pui32TraceItem; -+ IMG_UINT32 *ui32Ptr; -+ IMG_UINT32 ui32Size = PVRSRV_TRACE_TYPE_SYNC_SIZE; -+ -+ -+ PVRSRVTimeTraceAllocItem(&pui32TraceItem, ui32Size); -+ -+ if (!pui32TraceItem) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "Can't find buffer\n")); -+ return; -+ } -+ -+ ui32Ptr = PVRSRVTimeTraceWriteHeader(pui32TraceItem, ui32Group, PVRSRV_TRACE_CLASS_SYNC, -+ ui32Token, ui32Size, PVRSRV_TRACE_TYPE_SYNC, 1); -+ -+ ui32Ptr[PVRSRV_TRACE_SYNC_UID] = psSync->ui32UID; -+ ui32Ptr[PVRSRV_TRACE_SYNC_WOP] = psSync->psSyncData->ui32WriteOpsPending; -+ ui32Ptr[PVRSRV_TRACE_SYNC_WOC] = psSync->psSyncData->ui32WriteOpsComplete; -+ ui32Ptr[PVRSRV_TRACE_SYNC_ROP] = psSync->psSyncData->ui32ReadOpsPending; -+ ui32Ptr[PVRSRV_TRACE_SYNC_ROC] = psSync->psSyncData->ui32ReadOpsComplete; -+ ui32Ptr[PVRSRV_TRACE_SYNC_RO2P] = psSync->psSyncData->ui32ReadOps2Pending; -+ ui32Ptr[PVRSRV_TRACE_SYNC_RO2C] = psSync->psSyncData->ui32ReadOps2Complete; -+ ui32Ptr[PVRSRV_TRACE_SYNC_WO_DEV_VADDR] = psSync->sWriteOpsCompleteDevVAddr.uiAddr; -+ ui32Ptr[PVRSRV_TRACE_SYNC_RO_DEV_VADDR] = psSync->sReadOpsCompleteDevVAddr.uiAddr; -+ ui32Ptr[PVRSRV_TRACE_SYNC_RO2_DEV_VADDR] = psSync->sReadOps2CompleteDevVAddr.uiAddr; -+ ui32Ptr[PVRSRV_TRACE_SYNC_OP] = ui8SyncOp; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVDumpTimeTraceBuffer -+ -+ @Description -+ -+ Dump the contents of the trace buffer. -+ -+ @Input hKey : Trace item's group ID -+ -+ @Input hData : Trace item's ui32Token ID -+ -+ @Return Error -+ -+******************************************************************************/ -+static PVRSRV_ERROR PVRSRVDumpTimeTraceBuffer(IMG_UINTPTR_T hKey, IMG_UINTPTR_T hData) -+{ -+ sTimeTraceBuffer *psBuffer = (sTimeTraceBuffer *) hData; -+ IMG_UINT32 ui32ByteCount = psBuffer->ui32ByteCount; -+ IMG_UINT32 ui32Walker = psBuffer->ui32Roff; -+ IMG_UINT32 ui32Read, ui32LineLen, ui32EOL, ui32MinLine; -+ -+ PVR_DPF((PVR_DBG_ERROR, "TTB for PID %u:\n", (IMG_UINT32) hKey)); -+ -+ while (ui32ByteCount) -+ { -+ IMG_UINT32 *pui32Buffer = (IMG_UINT32 *) &psBuffer->ui8Data[ui32Walker]; -+ -+ ui32LineLen = (ui32ByteCount/sizeof(IMG_UINT32)); -+ ui32EOL = (TIME_TRACE_BUFFER_SIZE - ui32Walker)/sizeof(IMG_UINT32); -+ ui32MinLine = (ui32LineLen < ui32EOL)?ui32LineLen:ui32EOL; -+ -+ if (ui32MinLine >= 4) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "\t(TTB-%X) %08X %08X %08X %08X", ui32ByteCount, -+ pui32Buffer[0], pui32Buffer[1], pui32Buffer[2], pui32Buffer[3])); -+ ui32Read = 4 * sizeof(IMG_UINT32); -+ } -+ else if (ui32MinLine >= 3) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "\t(TTB-%X) %08X %08X %08X", ui32ByteCount, -+ pui32Buffer[0], pui32Buffer[1], pui32Buffer[2])); -+ ui32Read = 3 * sizeof(IMG_UINT32); -+ } -+ else if (ui32MinLine >= 2) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "\t(TTB-%X) %08X %08X", ui32ByteCount, -+ pui32Buffer[0], pui32Buffer[1])); -+ ui32Read = 2 * sizeof(IMG_UINT32); -+ } -+ else -+ { -+ PVR_DPF((PVR_DBG_ERROR, "\t(TTB-%X) %08X", ui32ByteCount, -+ pui32Buffer[0])); -+ ui32Read = sizeof(IMG_UINT32); -+ } -+ -+ ui32Walker = (ui32Walker + ui32Read) & (TIME_TRACE_BUFFER_SIZE - 1); -+ ui32ByteCount -= ui32Read; -+ } -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVDumpTimeTraceBuffers -+ -+ @Description -+ -+ Dump the contents of all the trace buffers. -+ -+ @Return None -+ -+******************************************************************************/ -+IMG_VOID PVRSRVDumpTimeTraceBuffers(IMG_VOID) -+{ -+ HASH_Iterate(g_psBufferTable, PVRSRVDumpTimeTraceBuffer); -+} -+ -+#endif /* TTRACE */ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/mmu.c b/drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/mmu.c -new file mode 100644 -index 0000000..21a894a ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/mmu.c -@@ -0,0 +1,4661 @@ -+/*************************************************************************/ /*! -+@Title MMU Management -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Implements basic low level control of MMU. -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#include "sgxdefs.h" -+#include "sgxmmu.h" -+#include "services_headers.h" -+#include "buffer_manager.h" -+#include "hash.h" -+#include "ra.h" -+#include "pdump_km.h" -+#include "sgxapi_km.h" -+#include "sgxinfo.h" -+#include "sgxinfokm.h" -+#include "mmu.h" -+#include "sgxconfig.h" -+#include "sgx_bridge_km.h" -+#include "pdump_osfunc.h" -+ -+#define UINT32_MAX_VALUE 0xFFFFFFFFUL -+ -+/* -+ MMU performs device virtual to physical translation. -+ terminology: -+ page directory (PD) -+ pagetable (PT) -+ data page (DP) -+ -+ Incoming 32bit Device Virtual Addresses are deconstructed into 3 fields: -+ --------------------------------------------------------- -+ | PD Index/tag: | PT Index: | DP offset: | -+ | bits 31:22 | bits 21:n | bits (n-1):0 | -+ --------------------------------------------------------- -+ where typically n=12 for a standard 4k DP -+ but n=16 for a 64k DP -+ -+ MMU page directory (PD), pagetable (PT) and data page (DP) config: -+ PD: -+ - always one page per address space -+ - up to 4k in size to span 4Gb (32bit) -+ - contains up to 1024 32bit entries -+ - entries are indexed by the top 12 bits of an incoming 32bit device virtual address -+ - the PD entry selected contains the physical address of the PT to -+ perform the next stage of the V to P translation -+ -+ PT: -+ - size depends on the DP size, e.g. 4k DPs have 4k PTs but 16k DPs have 1k PTs -+ - each PT always spans 4Mb of device virtual address space irrespective of DP size -+ - number of entries in a PT depend on DP size and ranges from 1024 to 4 entries -+ - entries are indexed by the PT Index field of the device virtual address (21:n) -+ - the PT entry selected contains the physical address of the DP to access -+ -+ DP: -+ - size varies from 4k to 4M in multiple of 4 steppings -+ - DP offset field of the device virtual address ((n-1):0) is used as a byte offset -+ to address into the DP itself -+*/ -+ -+#define SGX_MAX_PD_ENTRIES (1<<(SGX_FEATURE_ADDRESS_SPACE_SIZE - SGX_MMU_PT_SHIFT - SGX_MMU_PAGE_SHIFT)) -+ -+#if defined(FIX_HW_BRN_31620) -+/* Sim doesn't use the address mask */ -+#define SGX_MMU_PDE_DUMMY_PAGE (0)//(0x00000020U) -+#define SGX_MMU_PTE_DUMMY_PAGE (0)//(0x00000020U) -+ -+/* 4MB adress range per page table */ -+#define BRN31620_PT_ADDRESS_RANGE_SHIFT 22 -+#define BRN31620_PT_ADDRESS_RANGE_SIZE (1 << BRN31620_PT_ADDRESS_RANGE_SHIFT) -+ -+/* 64MB address range per PDE cache line */ -+#define BRN31620_PDE_CACHE_FILL_SHIFT 26 -+#define BRN31620_PDE_CACHE_FILL_SIZE (1 << BRN31620_PDE_CACHE_FILL_SHIFT) -+#define BRN31620_PDE_CACHE_FILL_MASK (BRN31620_PDE_CACHE_FILL_SIZE - 1) -+ -+/* Page Directory Enteries per cache line */ -+#define BRN31620_PDES_PER_CACHE_LINE_SHIFT (BRN31620_PDE_CACHE_FILL_SHIFT - BRN31620_PT_ADDRESS_RANGE_SHIFT) -+#define BRN31620_PDES_PER_CACHE_LINE_SIZE (1 << BRN31620_PDES_PER_CACHE_LINE_SHIFT) -+#define BRN31620_PDES_PER_CACHE_LINE_MASK (BRN31620_PDES_PER_CACHE_LINE_SIZE - 1) -+ -+/* Macros for working out offset for dummy pages */ -+#define BRN31620_DUMMY_PAGE_OFFSET (1 * SGX_MMU_PAGE_SIZE) -+#define BRN31620_DUMMY_PDE_INDEX (BRN31620_DUMMY_PAGE_OFFSET / BRN31620_PT_ADDRESS_RANGE_SIZE) -+#define BRN31620_DUMMY_PTE_INDEX ((BRN31620_DUMMY_PAGE_OFFSET - (BRN31620_DUMMY_PDE_INDEX * BRN31620_PT_ADDRESS_RANGE_SIZE))/SGX_MMU_PAGE_SIZE) -+ -+/* Cache number of cache lines */ -+#define BRN31620_CACHE_FLUSH_SHIFT (32 - BRN31620_PDE_CACHE_FILL_SHIFT) -+#define BRN31620_CACHE_FLUSH_SIZE (1 << BRN31620_CACHE_FLUSH_SHIFT) -+ -+/* Cache line bits in a UINT32 */ -+#define BRN31620_CACHE_FLUSH_BITS_SHIFT 5 -+#define BRN31620_CACHE_FLUSH_BITS_SIZE (1 << BRN31620_CACHE_FLUSH_BITS_SHIFT) -+#define BRN31620_CACHE_FLUSH_BITS_MASK (BRN31620_CACHE_FLUSH_BITS_SIZE - 1) -+ -+/* Cache line index in array */ -+#define BRN31620_CACHE_FLUSH_INDEX_BITS (BRN31620_CACHE_FLUSH_SHIFT - BRN31620_CACHE_FLUSH_BITS_SHIFT) -+#define BRN31620_CACHE_FLUSH_INDEX_SIZE (1 << BRN31620_CACHE_FLUSH_INDEX_BITS) -+ -+#define BRN31620_DUMMY_PAGE_SIGNATURE 0xFEEBEE01 -+#endif -+ -+typedef struct _MMU_PT_INFO_ -+{ -+ /* note: may need a union here to accommodate a PT page address for local memory */ -+ IMG_VOID *hPTPageOSMemHandle; -+ IMG_CPU_VIRTADDR PTPageCpuVAddr; -+ /* Map of reserved PTEs. -+ * Reserved PTEs are like "valid" PTEs in that they (and the DevVAddrs they represent) -+ * cannot be assigned to another allocation but their "reserved" status persists through -+ * any amount of mapping and unmapping, until the allocation is finally destroyed. -+ * -+ * Reserved and Valid are independent. -+ * When a PTE is first reserved, it will have Reserved=1 and Valid=0. -+ * When the PTE is actually mapped, it will have Reserved=1 and Valid=1. -+ * When the PTE is unmapped, it will have Reserved=1 and Valid=0. -+ * At this point, the PT will can not be destroyed because although there is -+ * not an active mapping on the PT, it is known a PTE is reserved for use. -+ * -+ * The above sequence of mapping and unmapping may repeat any number of times -+ * until the allocation is unmapped and destroyed which causes the PTE to have -+ * Valid=0 and Reserved=0. -+ */ -+ /* Number of PTEs set up. -+ * i.e. have a valid SGX Phys Addr and the "VALID" PTE bit == 1 -+ */ -+ IMG_UINT32 ui32ValidPTECount; -+} MMU_PT_INFO; -+ -+#define MMU_CONTEXT_NAME_SIZE 50 -+struct _MMU_CONTEXT_ -+{ -+ /* the device node */ -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+ -+ /* Page Directory CPUVirt and DevPhys Addresses */ -+ IMG_CPU_VIRTADDR pvPDCpuVAddr; -+ IMG_DEV_PHYADDR sPDDevPAddr; -+ -+ IMG_VOID *hPDOSMemHandle; -+ -+ /* information about dynamically allocated pagetables */ -+ MMU_PT_INFO *apsPTInfoList[SGX_MAX_PD_ENTRIES]; -+ -+ PVRSRV_SGXDEV_INFO *psDevInfo; -+ -+#if defined(PDUMP) -+ IMG_UINT32 ui32PDumpMMUContextID; -+#if defined(SUPPORT_PDUMP_MULTI_PROCESS) -+ IMG_BOOL bPDumpActive; -+#endif -+#endif -+ -+ IMG_UINT32 ui32PID; -+ IMG_CHAR szName[MMU_CONTEXT_NAME_SIZE]; -+ -+#if defined (FIX_HW_BRN_31620) -+ IMG_UINT32 ui32PDChangeMask[BRN31620_CACHE_FLUSH_INDEX_SIZE]; -+ IMG_UINT32 ui32PDCacheRangeRefCount[BRN31620_CACHE_FLUSH_SIZE]; -+ MMU_PT_INFO *apsPTInfoListSave[SGX_MAX_PD_ENTRIES]; -+#endif -+ struct _MMU_CONTEXT_ *psNext; -+}; -+ -+struct _MMU_HEAP_ -+{ -+ /* MMU context */ -+ MMU_CONTEXT *psMMUContext; -+ -+ /* -+ heap specific details: -+ */ -+ /* the Base PD index for the heap */ -+ IMG_UINT32 ui32PDBaseIndex; -+ /* number of pagetables in this heap */ -+ IMG_UINT32 ui32PageTableCount; -+ /* total number of pagetable entries in this heap which may be mapped to data pages */ -+ IMG_UINT32 ui32PTETotalUsable; -+ /* PD entry DP size control field */ -+ IMG_UINT32 ui32PDEPageSizeCtrl; -+ -+ /* -+ Data Page (DP) Details: -+ */ -+ /* size in bytes of a data page */ -+ IMG_UINT32 ui32DataPageSize; -+ /* bit width of the data page offset addressing field */ -+ IMG_UINT32 ui32DataPageBitWidth; -+ /* bit mask of the data page offset addressing field */ -+ IMG_UINT32 ui32DataPageMask; -+ -+ /* -+ PageTable (PT) Details: -+ */ -+ /* bit shift to base of PT addressing field */ -+ IMG_UINT32 ui32PTShift; -+ /* bit width of the PT addressing field */ -+ IMG_UINT32 ui32PTBitWidth; -+ /* bit mask of the PT addressing field */ -+ IMG_UINT32 ui32PTMask; -+ /* size in bytes of a pagetable */ -+ IMG_UINT32 ui32PTSize; -+ /* Allocated PT Entries per PT */ -+ IMG_UINT32 ui32PTNumEntriesAllocated; -+ /* Usable PT Entries per PT (may be different to num allocated for 4MB data page) */ -+ IMG_UINT32 ui32PTNumEntriesUsable; -+ -+ /* -+ PageDirectory Details: -+ */ -+ /* bit shift to base of PD addressing field */ -+ IMG_UINT32 ui32PDShift; -+ /* bit width of the PD addressing field */ -+ IMG_UINT32 ui32PDBitWidth; -+ /* bit mask of the PT addressing field */ -+ IMG_UINT32 ui32PDMask; -+ -+ /* -+ Arena Info: -+ */ -+ RA_ARENA *psVMArena; -+ DEV_ARENA_DESCRIPTOR *psDevArena; -+ -+ /* If we have sparse mappings then we can't do PT level sanity checks */ -+ IMG_BOOL bHasSparseMappings; -+#if defined(PDUMP) -+ PDUMP_MMU_ATTRIB sMMUAttrib; -+#endif -+}; -+ -+ -+ -+#if defined (SUPPORT_SGX_MMU_DUMMY_PAGE) -+#define DUMMY_DATA_PAGE_SIGNATURE 0xDEADBEEF -+#endif -+ -+/* local prototypes: */ -+static IMG_VOID -+_DeferredFreePageTable (MMU_HEAP *pMMUHeap, IMG_UINT32 ui32PTIndex, IMG_BOOL bOSFreePT); -+ -+#if defined(PDUMP) -+static IMG_VOID -+MMU_PDumpPageTables (MMU_HEAP *pMMUHeap, -+ IMG_DEV_VIRTADDR DevVAddr, -+ IMG_SIZE_T uSize, -+ IMG_BOOL bForUnmap, -+ IMG_HANDLE hUniqueTag); -+#endif /* #if defined(PDUMP) */ -+ -+/* This option tests page table memory, for use during device bring-up. */ -+#define PAGE_TEST 0 -+#if PAGE_TEST -+static IMG_VOID PageTest(IMG_VOID* pMem, IMG_DEV_PHYADDR sDevPAddr); -+#endif -+ -+/* This option dumps out the PT if an assert fails */ -+#define PT_DUMP 1 -+ -+/* This option sanity checks page table PTE valid count matches active PTEs */ -+#define PT_DEBUG 0 -+#if (PT_DEBUG || PT_DUMP) && defined(PVRSRV_NEED_PVR_DPF) -+static IMG_VOID DumpPT(MMU_PT_INFO *psPTInfoList) -+{ -+ IMG_UINT32 *p = (IMG_UINT32*)psPTInfoList->PTPageCpuVAddr; -+ IMG_UINT32 i; -+ -+ /* 1024 entries in a 4K page table */ -+ for(i = 0; i < 1024; i += 8) -+ { -+ PVR_DPF((PVR_DBG_ERROR, -+ "%08X %08X %08X %08X %08X %08X %08X %08X\n", -+ p[i + 0], p[i + 1], p[i + 2], p[i + 3], -+ p[i + 4], p[i + 5], p[i + 6], p[i + 7])); -+ } -+} -+#else /* (PT_DEBUG || PT_DUMP) && defined(PVRSRV_NEED_PVR_DPF) */ -+static INLINE IMG_VOID DumpPT(MMU_PT_INFO *psPTInfoList) -+{ -+ PVR_UNREFERENCED_PARAMETER(psPTInfoList); -+} -+#endif /* (PT_DEBUG || PT_DUMP) && defined(PVRSRV_NEED_PVR_DPF) */ -+ -+#if PT_DEBUG -+static IMG_VOID CheckPT(MMU_PT_INFO *psPTInfoList) -+{ -+ IMG_UINT32 *p = (IMG_UINT32*) psPTInfoList->PTPageCpuVAddr; -+ IMG_UINT32 i, ui32Count = 0; -+ -+ /* 1024 entries in a 4K page table */ -+ for(i = 0; i < 1024; i++) -+ if(p[i] & SGX_MMU_PTE_VALID) -+ ui32Count++; -+ -+ if(psPTInfoList->ui32ValidPTECount != ui32Count) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "ui32ValidPTECount: %u ui32Count: %u\n", -+ psPTInfoList->ui32ValidPTECount, ui32Count)); -+ DumpPT(psPTInfoList); -+ BUG(); -+ } -+} -+#else /* PT_DEBUG */ -+static INLINE IMG_VOID CheckPT(MMU_PT_INFO *psPTInfoList) -+{ -+ PVR_UNREFERENCED_PARAMETER(psPTInfoList); -+} -+#endif /* PT_DEBUG */ -+ -+/* -+ Debug functionality that allows us to make the CPU -+ mapping of pagetable memory readonly and only make -+ it read/write when we alter it. This allows us -+ to check that our memory isn't being overwritten -+*/ -+#if defined(PVRSRV_MMU_MAKE_READWRITE_ON_DEMAND) -+ -+#include <linux/version.h> -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)) -+#ifndef AUTOCONF_INCLUDED -+#include <linux/config.h> -+#endif -+#else -+#include <generated/autoconf.h> -+#endif -+ -+#include <linux/mm.h> -+#include <linux/sched.h> -+#include <linux/highmem.h> -+#include <asm/pgtable.h> -+#include <asm/tlbflush.h> -+ -+static IMG_VOID MakeKernelPageReadWrite(IMG_PVOID ulCPUVAddr) -+{ -+ pgd_t *psPGD; -+ pud_t *psPUD; -+ pmd_t *psPMD; -+ pte_t *psPTE; -+ pte_t ptent; -+ IMG_UINT32 ui32CPUVAddr = (IMG_UINT32) ulCPUVAddr; -+ -+ psPGD = pgd_offset_k(ui32CPUVAddr); -+ if (pgd_none(*psPGD) || pgd_bad(*psPGD)) -+ { -+ PVR_ASSERT(0); -+ } -+ -+ psPUD = pud_offset(psPGD, ui32CPUVAddr); -+ if (pud_none(*psPUD) || pud_bad(*psPUD)) -+ { -+ PVR_ASSERT(0); -+ } -+ -+ psPMD = pmd_offset(psPUD, ui32CPUVAddr); -+ if (pmd_none(*psPMD) || pmd_bad(*psPMD)) -+ { -+ PVR_ASSERT(0); -+ } -+ psPTE = (pte_t *)pte_offset_kernel(psPMD, ui32CPUVAddr); -+ -+ ptent = ptep_modify_prot_start(&init_mm, ui32CPUVAddr, psPTE); -+ ptent = pte_mkwrite(ptent); -+ ptep_modify_prot_commit(&init_mm, ui32CPUVAddr, psPTE, ptent); -+ -+ flush_tlb_all(); -+} -+ -+static IMG_VOID MakeKernelPageReadOnly(IMG_PVOID ulCPUVAddr) -+{ -+ pgd_t *psPGD; -+ pud_t *psPUD; -+ pmd_t *psPMD; -+ pte_t *psPTE; -+ pte_t ptent; -+ IMG_UINT32 ui32CPUVAddr = (IMG_UINT32) ulCPUVAddr; -+ -+ OSWriteMemoryBarrier(); -+ -+ psPGD = pgd_offset_k(ui32CPUVAddr); -+ if (pgd_none(*psPGD) || pgd_bad(*psPGD)) -+ { -+ PVR_ASSERT(0); -+ } -+ -+ psPUD = pud_offset(psPGD, ui32CPUVAddr); -+ if (pud_none(*psPUD) || pud_bad(*psPUD)) -+ { -+ PVR_ASSERT(0); -+ } -+ -+ psPMD = pmd_offset(psPUD, ui32CPUVAddr); -+ if (pmd_none(*psPMD) || pmd_bad(*psPMD)) -+ { -+ PVR_ASSERT(0); -+ } -+ -+ psPTE = (pte_t *)pte_offset_kernel(psPMD, ui32CPUVAddr); -+ -+ ptent = ptep_modify_prot_start(&init_mm, ui32CPUVAddr, psPTE); -+ ptent = pte_wrprotect(ptent); -+ ptep_modify_prot_commit(&init_mm, ui32CPUVAddr, psPTE, ptent); -+ -+ flush_tlb_all(); -+ -+} -+ -+#else /* defined(PVRSRV_MMU_MAKE_READWRITE_ON_DEMAND) */ -+ -+static INLINE IMG_VOID MakeKernelPageReadWrite(IMG_PVOID ulCPUVAddr) -+{ -+ PVR_UNREFERENCED_PARAMETER(ulCPUVAddr); -+} -+ -+static INLINE IMG_VOID MakeKernelPageReadOnly(IMG_PVOID ulCPUVAddr) -+{ -+ PVR_UNREFERENCED_PARAMETER(ulCPUVAddr); -+} -+ -+#endif /* defined(PVRSRV_MMU_MAKE_READWRITE_ON_DEMAND) */ -+ -+/*___________________________________________________________________________ -+ -+ Information for SUPPORT_PDUMP_MULTI_PROCESS feature. -+ -+ The client marked for pdumping will set the bPDumpActive flag in -+ the MMU Context (see MMU_Initialise). -+ -+ Shared heap allocations should be persistent so all apps which -+ are pdumped will see the allocation. Persistent flag over-rides -+ the bPDumpActive flag (see pdump_common.c/DbgWrite function). -+ -+ The idea is to dump PT,DP for shared heap allocations, but only -+ dump the PDE if the allocation is mapped into the kernel or active -+ client context. This ensures if a background app allocates on a -+ shared heap then all clients can access it in the pdump toolchain. -+ -+ -+ -+ PD PT DP -+ +-+ -+ | |---> +-+ -+ +-+ | |---> +-+ -+ +-+ + + -+ +-+ -+ -+ PD allocation/free: pdump flags are 0 (only need PD for active apps) -+ PT allocation/free: pdump flags are 0 -+ unless PT is for a shared heap, in which case persistent is set -+ PD entries (MMU init/insert shared heap): -+ only pdump if PDE is on the active MMU context, flags are 0 -+ PD entries (PT alloc): -+ pdump flags are 0 if kernel heap -+ pdump flags are 0 if shared heap and PDE is on active MMU context -+ otherwise ignore. -+ PT entries pdump flags are 0 -+ unless PTE is for a shared heap, in which case persistent is set -+ -+ NOTE: PDump common code:- -+ PDumpMallocPages and PDumpMemKM also set the persistent flag for -+ shared heap allocations. -+ -+ ___________________________________________________________________________ -+*/ -+ -+ -+/*! -+****************************************************************************** -+ FUNCTION: MMU_IsHeapShared -+ -+ PURPOSE: Is this heap shared? -+ PARAMETERS: In: pMMU_Heap -+ RETURNS: true if heap is shared -+******************************************************************************/ -+IMG_BOOL MMU_IsHeapShared(MMU_HEAP* pMMUHeap) -+{ -+ switch(pMMUHeap->psDevArena->DevMemHeapType) -+ { -+ case DEVICE_MEMORY_HEAP_SHARED : -+ case DEVICE_MEMORY_HEAP_SHARED_EXPORTED : -+ return IMG_TRUE; -+ case DEVICE_MEMORY_HEAP_PERCONTEXT : -+ case DEVICE_MEMORY_HEAP_KERNEL : -+ return IMG_FALSE; -+ default: -+ { -+ PVR_DPF((PVR_DBG_ERROR, "MMU_IsHeapShared: ERROR invalid heap type")); -+ return IMG_FALSE; -+ } -+ } -+} -+ -+#ifdef SUPPORT_SGX_MMU_BYPASS -+/*! -+****************************************************************************** -+ FUNCTION: EnableHostAccess -+ -+ PURPOSE: Enables Host accesses to device memory, by passing the device -+ MMU address translation -+ -+ PARAMETERS: In: psMMUContext -+ RETURNS: None -+******************************************************************************/ -+IMG_VOID -+EnableHostAccess (MMU_CONTEXT *psMMUContext) -+{ -+ IMG_UINT32 ui32RegVal; -+ IMG_VOID *pvRegsBaseKM = psMMUContext->psDevInfo->pvRegsBaseKM; -+ -+ /* -+ bypass the MMU for the host port requestor, -+ conserving bypass state of other requestors -+ */ -+ ui32RegVal = OSReadHWReg(pvRegsBaseKM, EUR_CR_BIF_CTRL); -+ -+ OSWriteHWReg(pvRegsBaseKM, -+ EUR_CR_BIF_CTRL, -+ ui32RegVal | EUR_CR_BIF_CTRL_MMU_BYPASS_HOST_MASK); -+ /* assume we're not wiping-out any other bits */ -+ PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, EUR_CR_BIF_CTRL_MMU_BYPASS_HOST_MASK); -+} -+ -+/*! -+****************************************************************************** -+ FUNCTION: DisableHostAccess -+ -+ PURPOSE: Disables Host accesses to device memory, by passing the device -+ MMU address translation -+ -+ PARAMETERS: In: psMMUContext -+ RETURNS: None -+******************************************************************************/ -+IMG_VOID -+DisableHostAccess (MMU_CONTEXT *psMMUContext) -+{ -+ IMG_UINT32 ui32RegVal; -+ IMG_VOID *pvRegsBaseKM = psMMUContext->psDevInfo->pvRegsBaseKM; -+ -+ /* -+ disable MMU-bypass for the host port requestor, -+ conserving bypass state of other requestors -+ and flushing all caches/tlbs -+ */ -+ OSWriteHWReg(pvRegsBaseKM, -+ EUR_CR_BIF_CTRL, -+ ui32RegVal & ~EUR_CR_BIF_CTRL_MMU_BYPASS_HOST_MASK); -+ /* assume we're not wiping-out any other bits */ -+ PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, 0); -+} -+#endif -+ -+ -+#if defined(SGX_FEATURE_SYSTEM_CACHE) -+/*! -+****************************************************************************** -+ FUNCTION: MMU_InvalidateSystemLevelCache -+ -+ PURPOSE: Invalidates the System Level Cache to purge stale PDEs and PTEs -+ -+ PARAMETERS: In: psDevInfo -+ RETURNS: None -+ -+******************************************************************************/ -+static IMG_VOID MMU_InvalidateSystemLevelCache(PVRSRV_SGXDEV_INFO *psDevInfo) -+{ -+ #if defined(SGX_FEATURE_MP) -+ psDevInfo->ui32CacheControl |= SGXMKIF_CC_INVAL_BIF_SL; -+ #else -+ /* The MMU always bypasses the SLC */ -+ PVR_UNREFERENCED_PARAMETER(psDevInfo); -+ #endif /* SGX_FEATURE_MP */ -+} -+#endif /* SGX_FEATURE_SYSTEM_CACHE */ -+ -+/*! -+****************************************************************************** -+ FUNCTION: MMU_InvalidateDirectoryCache -+ -+ PURPOSE: Invalidates the page directory cache + page table cache + requestor TLBs -+ -+ PARAMETERS: In: psDevInfo -+ RETURNS: None -+ -+******************************************************************************/ -+IMG_VOID MMU_InvalidateDirectoryCache(PVRSRV_SGXDEV_INFO *psDevInfo) -+{ -+ psDevInfo->ui32CacheControl |= SGXMKIF_CC_INVAL_BIF_PD; -+ #if defined(SGX_FEATURE_SYSTEM_CACHE) -+ MMU_InvalidateSystemLevelCache(psDevInfo); -+ #endif /* SGX_FEATURE_SYSTEM_CACHE */ -+} -+ -+ -+/*! -+****************************************************************************** -+ FUNCTION: MMU_InvalidatePageTableCache -+ -+ PURPOSE: Invalidates the page table cache + requestor TLBs -+ -+ PARAMETERS: In: psDevInfo -+ RETURNS: None -+ -+******************************************************************************/ -+static IMG_VOID MMU_InvalidatePageTableCache(PVRSRV_SGXDEV_INFO *psDevInfo) -+{ -+ psDevInfo->ui32CacheControl |= SGXMKIF_CC_INVAL_BIF_PT; -+ #if defined(SGX_FEATURE_SYSTEM_CACHE) -+ MMU_InvalidateSystemLevelCache(psDevInfo); -+ #endif /* SGX_FEATURE_SYSTEM_CACHE */ -+} -+ -+#if defined(FIX_HW_BRN_31620) -+/*! -+****************************************************************************** -+ FUNCTION: BRN31620InvalidatePageTableEntry -+ -+ PURPOSE: Frees page tables in PDE cache line chunks re-wiring the -+ dummy page when required -+ -+ PARAMETERS: In: psMMUContext, ui32PDIndex, ui32PTIndex -+ RETURNS: None -+ -+******************************************************************************/ -+static IMG_VOID BRN31620InvalidatePageTableEntry(MMU_CONTEXT *psMMUContext, IMG_UINT32 ui32PDIndex, IMG_UINT32 ui32PTIndex, IMG_UINT32 *pui32PTE) -+{ -+ PVRSRV_SGXDEV_INFO *psDevInfo = psMMUContext->psDevInfo; -+ -+ /* -+ * Note: We can't tell at this stage if this PT will be freed before -+ * the end of the function so we always wire up the dummy page to -+ * to the PT. -+ */ -+ if (((ui32PDIndex % (BRN31620_PDE_CACHE_FILL_SIZE/BRN31620_PT_ADDRESS_RANGE_SIZE)) == BRN31620_DUMMY_PDE_INDEX) -+ && (ui32PTIndex == BRN31620_DUMMY_PTE_INDEX)) -+ { -+ *pui32PTE = (psDevInfo->sBRN31620DummyPageDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT) -+ | SGX_MMU_PTE_DUMMY_PAGE -+ | SGX_MMU_PTE_READONLY -+ | SGX_MMU_PTE_VALID; -+ } -+ else -+ { -+ *pui32PTE = 0; -+ } -+} -+ -+/*! -+****************************************************************************** -+ FUNCTION: BRN31620FreePageTable -+ -+ PURPOSE: Frees page tables in PDE cache line chunks re-wiring the -+ dummy page when required -+ -+ PARAMETERS: In: psMMUContext, ui32PDIndex -+ RETURNS: IMG_TRUE if we freed any PT's -+ -+******************************************************************************/ -+static IMG_BOOL BRN31620FreePageTable(MMU_HEAP *psMMUHeap, IMG_UINT32 ui32PDIndex) -+{ -+ MMU_CONTEXT *psMMUContext = psMMUHeap->psMMUContext; -+ PVRSRV_SGXDEV_INFO *psDevInfo = psMMUContext->psDevInfo; -+ IMG_UINT32 ui32PDCacheLine = ui32PDIndex >> BRN31620_PDES_PER_CACHE_LINE_SHIFT; -+ IMG_UINT32 bFreePTs = IMG_FALSE; -+ IMG_UINT32 *pui32Tmp; -+ -+ PVR_ASSERT(psMMUHeap != IMG_NULL); -+ -+ /* -+ * Clear the PT info for this PD index so even if we don't -+ * free the memory here apsPTInfoList[PDIndex] will trigger -+ * an "allocation" in _DeferredAllocPagetables which -+ * bumps up the refcount. -+ */ -+ PVR_ASSERT(psMMUContext->apsPTInfoListSave[ui32PDIndex] == IMG_NULL); -+ -+ psMMUContext->apsPTInfoListSave[ui32PDIndex] = psMMUContext->apsPTInfoList[ui32PDIndex]; -+ psMMUContext->apsPTInfoList[ui32PDIndex] = IMG_NULL; -+ -+ /* Check if this was the last PT in the cache line */ -+ if (--psMMUContext->ui32PDCacheRangeRefCount[ui32PDCacheLine] == 0) -+ { -+ IMG_UINT32 i; -+ IMG_UINT32 ui32PDIndexStart = ui32PDCacheLine * BRN31620_PDES_PER_CACHE_LINE_SIZE; -+ IMG_UINT32 ui32PDIndexEnd = ui32PDIndexStart + BRN31620_PDES_PER_CACHE_LINE_SIZE; -+ IMG_UINT32 ui32PDBitMaskIndex, ui32PDBitMaskShift; -+ -+ /* Free all PT's in cache line */ -+ for (i=ui32PDIndexStart;i<ui32PDIndexEnd;i++) -+ { -+ /* This PT is _really_ being freed now */ -+ psMMUContext->apsPTInfoList[i] = psMMUContext->apsPTInfoListSave[i]; -+ psMMUContext->apsPTInfoListSave[i] = IMG_NULL; -+ _DeferredFreePageTable(psMMUHeap, i - psMMUHeap->ui32PDBaseIndex, IMG_TRUE); -+ } -+ -+ ui32PDBitMaskIndex = ui32PDCacheLine >> BRN31620_CACHE_FLUSH_BITS_SHIFT; -+ ui32PDBitMaskShift = ui32PDCacheLine & BRN31620_CACHE_FLUSH_BITS_MASK; -+ -+ /* Check if this is a shared heap */ -+ if (MMU_IsHeapShared(psMMUHeap)) -+ { -+ /* Mark the remove of the Page Table from all memory contexts */ -+ MMU_CONTEXT *psMMUContextWalker = (MMU_CONTEXT*) psMMUHeap->psMMUContext->psDevInfo->pvMMUContextList; -+ -+ while(psMMUContextWalker) -+ { -+ psMMUContextWalker->ui32PDChangeMask[ui32PDBitMaskIndex] |= 1 << ui32PDBitMaskShift; -+ -+ /* -+ * We've just cleared a cache line's worth of PDE's so we need -+ * to wire up the dummy PT -+ */ -+ MakeKernelPageReadWrite(psMMUContextWalker->pvPDCpuVAddr); -+ pui32Tmp = (IMG_UINT32 *) psMMUContextWalker->pvPDCpuVAddr; -+ pui32Tmp[ui32PDIndexStart + BRN31620_DUMMY_PDE_INDEX] = (psDevInfo->sBRN31620DummyPTDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT) -+ | SGX_MMU_PDE_PAGE_SIZE_4K -+ | SGX_MMU_PDE_DUMMY_PAGE -+ | SGX_MMU_PDE_VALID; -+ MakeKernelPageReadOnly(psMMUContextWalker->pvPDCpuVAddr); -+ -+ PDUMPCOMMENT("BRN31620 Re-wire dummy PT due to releasing PT allocation block"); -+ PDUMPPDENTRIES(&psMMUHeap->sMMUAttrib, psMMUContextWalker->hPDOSMemHandle, (IMG_VOID*)&pui32Tmp[ui32PDIndexStart + BRN31620_DUMMY_PDE_INDEX], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG); -+ psMMUContextWalker = psMMUContextWalker->psNext; -+ } -+ } -+ else -+ { -+ psMMUContext->ui32PDChangeMask[ui32PDBitMaskIndex] |= 1 << ui32PDBitMaskShift; -+ -+ /* -+ * We've just cleared a cache line's worth of PDE's so we need -+ * to wire up the dummy PT -+ */ -+ MakeKernelPageReadWrite(psMMUContext->pvPDCpuVAddr); -+ pui32Tmp = (IMG_UINT32 *) psMMUContext->pvPDCpuVAddr; -+ pui32Tmp[ui32PDIndexStart + BRN31620_DUMMY_PDE_INDEX] = (psDevInfo->sBRN31620DummyPTDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT) -+ | SGX_MMU_PDE_PAGE_SIZE_4K -+ | SGX_MMU_PDE_DUMMY_PAGE -+ | SGX_MMU_PDE_VALID; -+ MakeKernelPageReadOnly(psMMUContext->pvPDCpuVAddr); -+ -+ PDUMPCOMMENT("BRN31620 Re-wire dummy PT due to releasing PT allocation block"); -+ PDUMPPDENTRIES(&psMMUHeap->sMMUAttrib, psMMUContext->hPDOSMemHandle, (IMG_VOID*)&pui32Tmp[ui32PDIndexStart + BRN31620_DUMMY_PDE_INDEX], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG); -+ } -+ /* We've freed a cachline's worth of PDE's so trigger a PD cache flush */ -+ bFreePTs = IMG_TRUE; -+ } -+ -+ return bFreePTs; -+} -+#endif -+ -+/*! -+****************************************************************************** -+ FUNCTION: _AllocPageTableMemory -+ -+ PURPOSE: Allocate physical memory for a page table -+ -+ PARAMETERS: In: pMMUHeap - the mmu -+ In: psPTInfoList - PT info -+ Out: psDevPAddr - device physical address for new PT -+ RETURNS: IMG_TRUE - Success -+ IMG_FALSE - Failed -+******************************************************************************/ -+static IMG_BOOL -+_AllocPageTableMemory (MMU_HEAP *pMMUHeap, -+ MMU_PT_INFO *psPTInfoList, -+ IMG_DEV_PHYADDR *psDevPAddr) -+{ -+ IMG_DEV_PHYADDR sDevPAddr; -+ IMG_CPU_PHYADDR sCpuPAddr; -+ -+ /* -+ depending on the specific system, pagetables are allocated from system memory -+ or device local memory. For now, just look for at least a valid local heap/arena -+ */ -+ if(pMMUHeap->psDevArena->psDeviceMemoryHeapInfo->psLocalDevMemArena == IMG_NULL) -+ { -+ //FIXME: replace with an RA, this allocator only handles 4k allocs -+ if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, -+ pMMUHeap->ui32PTSize, -+ SGX_MMU_PAGE_SIZE,//FIXME: assume 4K page size for now (wastes memory for smaller pagetables -+ IMG_NULL, -+ 0, -+ IMG_NULL, -+ (IMG_VOID **)&psPTInfoList->PTPageCpuVAddr, -+ &psPTInfoList->hPTPageOSMemHandle) != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "_AllocPageTableMemory: ERROR call to OSAllocPages failed")); -+ return IMG_FALSE; -+ } -+ -+ /* -+ Force the page to read only, we will make it read/write as -+ and when we need to -+ */ -+ MakeKernelPageReadOnly(psPTInfoList->PTPageCpuVAddr); -+ -+ /* translate address to device physical */ -+ if(psPTInfoList->PTPageCpuVAddr) -+ { -+ sCpuPAddr = OSMapLinToCPUPhys(psPTInfoList->hPTPageOSMemHandle, -+ psPTInfoList->PTPageCpuVAddr); -+ } -+ else -+ { -+ /* This isn't used in all cases since not all ports currently support -+ * OSMemHandleToCpuPAddr() */ -+ sCpuPAddr = OSMemHandleToCpuPAddr(psPTInfoList->hPTPageOSMemHandle, 0); -+ } -+ -+ sDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr); -+ } -+ else -+ { -+ /* -+ We cannot use IMG_SYS_PHYADDR here, as that is 64-bit for 32-bit PAE builds. -+ The physical address in this call to RA_Alloc is specifically the SysPAddr -+ of local (card) space, and it is highly unlikely we would ever need to -+ support > 4GB of local (card) memory (this does assume that such local -+ memory will be mapped into System physical memory space at a low address so -+ that any and all local memory exists within the 4GB SYSPAddr range). -+ */ -+ IMG_UINTPTR_T uiLocalPAddr; -+ IMG_SYS_PHYADDR sSysPAddr; -+ -+ /* -+ just allocate from the first local memory arena -+ (unlikely to be more than one local mem area(?)) -+ */ -+ //FIXME: just allocate a 4K page for each PT for now -+ if(RA_Alloc(pMMUHeap->psDevArena->psDeviceMemoryHeapInfo->psLocalDevMemArena, -+ SGX_MMU_PAGE_SIZE,//pMMUHeap->ui32PTSize, -+ IMG_NULL, -+ IMG_NULL, -+ 0, -+ SGX_MMU_PAGE_SIZE,//pMMUHeap->ui32PTSize, -+ 0, -+ IMG_NULL, -+ 0, -+ &uiLocalPAddr)!= IMG_TRUE) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "_AllocPageTableMemory: ERROR call to RA_Alloc failed")); -+ return IMG_FALSE; -+ } -+ -+ /* Munge the local PAddr back into the SysPAddr */ -+ sSysPAddr.uiAddr = uiLocalPAddr; -+ -+ /* derive the CPU virtual address */ -+ sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr); -+ /* note: actual ammount is pMMUHeap->ui32PTSize but must be a multiple of 4k pages */ -+ psPTInfoList->PTPageCpuVAddr = OSMapPhysToLin(sCpuPAddr, -+ SGX_MMU_PAGE_SIZE, -+ PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY, -+ &psPTInfoList->hPTPageOSMemHandle); -+ if(!psPTInfoList->PTPageCpuVAddr) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "_AllocPageTableMemory: ERROR failed to map page tables")); -+ return IMG_FALSE; -+ } -+ -+ /* translate address to device physical */ -+ sDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr); -+ -+ #if PAGE_TEST -+ PageTest(psPTInfoList->PTPageCpuVAddr, sDevPAddr); -+ #endif -+ } -+ -+ MakeKernelPageReadWrite(psPTInfoList->PTPageCpuVAddr); -+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) -+ { -+ IMG_UINT32 *pui32Tmp; -+ IMG_UINT32 i; -+ -+ pui32Tmp = (IMG_UINT32*)psPTInfoList->PTPageCpuVAddr; -+ /* point the new PT entries to the dummy data page */ -+ for(i=0; i<pMMUHeap->ui32PTNumEntriesUsable; i++) -+ { -+ pui32Tmp[i] = (pMMUHeap->psMMUContext->psDevInfo->sDummyDataDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT) -+ | SGX_MMU_PTE_VALID; -+ } -+ /* zero the remaining allocated entries, if any */ -+ for(; i<pMMUHeap->ui32PTNumEntriesAllocated; i++) -+ { -+ pui32Tmp[i] = 0; -+ } -+ } -+#else -+ /* Zero the page table. */ -+ OSMemSet(psPTInfoList->PTPageCpuVAddr, 0, pMMUHeap->ui32PTSize); -+#endif -+ MakeKernelPageReadOnly(psPTInfoList->PTPageCpuVAddr); -+ -+#if defined(PDUMP) -+ { -+ IMG_UINT32 ui32Flags = 0; -+#if defined(SUPPORT_PDUMP_MULTI_PROCESS) -+ /* make sure shared heap PT allocs are always pdumped */ -+ ui32Flags |= ( MMU_IsHeapShared(pMMUHeap) ) ? PDUMP_FLAGS_PERSISTENT : 0; -+#endif -+ /* pdump the PT malloc */ -+ PDUMPMALLOCPAGETABLE(&pMMUHeap->psMMUContext->psDeviceNode->sDevId, psPTInfoList->hPTPageOSMemHandle, 0, psPTInfoList->PTPageCpuVAddr, pMMUHeap->ui32PTSize, ui32Flags, PDUMP_PT_UNIQUETAG); -+ /* pdump the PT Pages */ -+ PDUMPMEMPTENTRIES(&pMMUHeap->sMMUAttrib, psPTInfoList->hPTPageOSMemHandle, psPTInfoList->PTPageCpuVAddr, pMMUHeap->ui32PTSize, ui32Flags, IMG_TRUE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG); -+ } -+#endif -+ -+ /* return the DevPAddr */ -+ *psDevPAddr = sDevPAddr; -+ -+ return IMG_TRUE; -+} -+ -+ -+/*! -+****************************************************************************** -+ FUNCTION: _FreePageTableMemory -+ -+ PURPOSE: Free physical memory for a page table -+ -+ PARAMETERS: In: pMMUHeap - the mmu -+ In: psPTInfoList - PT info to free -+ RETURNS: NONE -+******************************************************************************/ -+static IMG_VOID -+_FreePageTableMemory (MMU_HEAP *pMMUHeap, MMU_PT_INFO *psPTInfoList) -+{ -+ /* -+ free the PT page: -+ depending on the specific system, pagetables are allocated from system memory -+ or device local memory. For now, just look for at least a valid local heap/arena -+ */ -+ if(pMMUHeap->psDevArena->psDeviceMemoryHeapInfo->psLocalDevMemArena == IMG_NULL) -+ { -+ /* Force the page to read write before we free it*/ -+ MakeKernelPageReadWrite(psPTInfoList->PTPageCpuVAddr); -+ -+ //FIXME: replace with an RA, this allocator only handles 4k allocs -+ OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, -+ pMMUHeap->ui32PTSize, -+ psPTInfoList->PTPageCpuVAddr, -+ psPTInfoList->hPTPageOSMemHandle); -+ } -+ else -+ { -+ IMG_SYS_PHYADDR sSysPAddr; -+ IMG_CPU_PHYADDR sCpuPAddr; -+ -+ /* derive the system physical address */ -+ sCpuPAddr = OSMapLinToCPUPhys(psPTInfoList->hPTPageOSMemHandle, -+ psPTInfoList->PTPageCpuVAddr); -+ sSysPAddr = SysCpuPAddrToSysPAddr (sCpuPAddr); -+ -+ /* unmap the CPU mapping */ -+ /* note: actual ammount is pMMUHeap->ui32PTSize but must be a multiple of 4k pages */ -+ OSUnMapPhysToLin(psPTInfoList->PTPageCpuVAddr, -+ SGX_MMU_PAGE_SIZE, -+ PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY, -+ psPTInfoList->hPTPageOSMemHandle); -+ -+ /* -+ just free from the first local memory arena -+ (unlikely to be more than one local mem area(?)) -+ Note that the cast to IMG_UINTPTR_T is ok as we're local mem. -+ */ -+ RA_Free (pMMUHeap->psDevArena->psDeviceMemoryHeapInfo->psLocalDevMemArena, (IMG_UINTPTR_T)sSysPAddr.uiAddr, IMG_FALSE); -+ } -+} -+ -+ -+ -+/*! -+****************************************************************************** -+ FUNCTION: _DeferredFreePageTable -+ -+ PURPOSE: Free one page table associated with an MMU. -+ -+ PARAMETERS: In: pMMUHeap - the mmu heap -+ In: ui32PTIndex - index of the page table to free relative -+ to the base of heap. -+ RETURNS: None -+******************************************************************************/ -+static IMG_VOID -+_DeferredFreePageTable (MMU_HEAP *pMMUHeap, IMG_UINT32 ui32PTIndex, IMG_BOOL bOSFreePT) -+{ -+ IMG_UINT32 *pui32PDEntry; -+ IMG_UINT32 i; -+ IMG_UINT32 ui32PDIndex; -+ SYS_DATA *psSysData; -+ MMU_PT_INFO **ppsPTInfoList; -+ -+ SysAcquireData(&psSysData); -+ -+ /* find the index/offset in PD entries */ -+ ui32PDIndex = pMMUHeap->psDevArena->BaseDevVAddr.uiAddr >> pMMUHeap->ui32PDShift; -+ -+ /* set the base PT info */ -+ ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex]; -+ -+ { -+#if PT_DEBUG -+ if(ppsPTInfoList[ui32PTIndex] && ppsPTInfoList[ui32PTIndex]->ui32ValidPTECount > 0) -+ { -+ DumpPT(ppsPTInfoList[ui32PTIndex]); -+ /* Fall-through, will fail assert */ -+ } -+#endif -+ -+ /* Assert that all mappings have gone */ -+ PVR_ASSERT(ppsPTInfoList[ui32PTIndex] == IMG_NULL || ppsPTInfoList[ui32PTIndex]->ui32ValidPTECount == 0); -+ } -+ -+#if defined(PDUMP) -+ { -+ IMG_UINT32 ui32Flags = 0; -+#if defined(SUPPORT_PDUMP_MULTI_PROCESS) -+ ui32Flags |= ( MMU_IsHeapShared(pMMUHeap) ) ? PDUMP_FLAGS_PERSISTENT : 0; -+#endif -+ /* pdump the PT free */ -+ PDUMPCOMMENT("Free page table (page count == %08X)", pMMUHeap->ui32PageTableCount); -+ if(ppsPTInfoList[ui32PTIndex] && ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr) -+ { -+ PDUMPFREEPAGETABLE(&pMMUHeap->psMMUContext->psDeviceNode->sDevId, ppsPTInfoList[ui32PTIndex]->hPTPageOSMemHandle, ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr, pMMUHeap->ui32PTSize, ui32Flags, PDUMP_PT_UNIQUETAG); -+ } -+ } -+#endif -+ -+ switch(pMMUHeap->psDevArena->DevMemHeapType) -+ { -+ case DEVICE_MEMORY_HEAP_SHARED : -+ case DEVICE_MEMORY_HEAP_SHARED_EXPORTED : -+ { -+ /* Remove Page Table from all memory contexts */ -+ MMU_CONTEXT *psMMUContext = (MMU_CONTEXT*)pMMUHeap->psMMUContext->psDevInfo->pvMMUContextList; -+ -+ while(psMMUContext) -+ { -+ /* get the PD CPUVAddr base and advance to the first entry */ -+ MakeKernelPageReadWrite(psMMUContext->pvPDCpuVAddr); -+ pui32PDEntry = (IMG_UINT32*)psMMUContext->pvPDCpuVAddr; -+ pui32PDEntry += ui32PDIndex; -+ -+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) -+ /* point the PD entry to the dummy PT */ -+ pui32PDEntry[ui32PTIndex] = (psMMUContext->psDevInfo->sDummyPTDevPAddr.uiAddr -+ >>SGX_MMU_PDE_ADDR_ALIGNSHIFT) -+ | SGX_MMU_PDE_PAGE_SIZE_4K -+ | SGX_MMU_PDE_VALID; -+#else -+ /* free the entry */ -+ if(bOSFreePT) -+ { -+ pui32PDEntry[ui32PTIndex] = 0; -+ } -+#endif -+ MakeKernelPageReadOnly(psMMUContext->pvPDCpuVAddr); -+ #if defined(PDUMP) -+ /* pdump the PD Page modifications */ -+ #if defined(SUPPORT_PDUMP_MULTI_PROCESS) -+ if(psMMUContext->bPDumpActive) -+ #endif -+ { -+ PDUMPPDENTRIES(&pMMUHeap->sMMUAttrib, psMMUContext->hPDOSMemHandle, (IMG_VOID*)&pui32PDEntry[ui32PTIndex], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG); -+ } -+ #endif -+ /* advance to next context */ -+ psMMUContext = psMMUContext->psNext; -+ } -+ break; -+ } -+ case DEVICE_MEMORY_HEAP_PERCONTEXT : -+ case DEVICE_MEMORY_HEAP_KERNEL : -+ { -+ MakeKernelPageReadWrite(pMMUHeap->psMMUContext->pvPDCpuVAddr); -+ /* Remove Page Table from this memory context only */ -+ pui32PDEntry = (IMG_UINT32*)pMMUHeap->psMMUContext->pvPDCpuVAddr; -+ pui32PDEntry += ui32PDIndex; -+ -+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) -+ /* point the PD entry to the dummy PT */ -+ pui32PDEntry[ui32PTIndex] = (pMMUHeap->psMMUContext->psDevInfo->sDummyPTDevPAddr.uiAddr -+ >>SGX_MMU_PDE_ADDR_ALIGNSHIFT) -+ | SGX_MMU_PDE_PAGE_SIZE_4K -+ | SGX_MMU_PDE_VALID; -+#else -+ /* free the entry */ -+ if(bOSFreePT) -+ { -+ pui32PDEntry[ui32PTIndex] = 0; -+ } -+#endif -+ MakeKernelPageReadOnly(pMMUHeap->psMMUContext->pvPDCpuVAddr); -+ -+ /* pdump the PD Page modifications */ -+ PDUMPPDENTRIES(&pMMUHeap->sMMUAttrib, pMMUHeap->psMMUContext->hPDOSMemHandle, (IMG_VOID*)&pui32PDEntry[ui32PTIndex], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG); -+ break; -+ } -+ default: -+ { -+ PVR_DPF((PVR_DBG_ERROR, "_DeferredFreePagetable: ERROR invalid heap type")); -+ return; -+ } -+ } -+ -+ /* clear the PT entries in each PT page */ -+ if(ppsPTInfoList[ui32PTIndex] != IMG_NULL) -+ { -+ if(ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr != IMG_NULL) -+ { -+ IMG_PUINT32 pui32Tmp; -+ -+ MakeKernelPageReadWrite(ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr); -+ pui32Tmp = (IMG_UINT32*)ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr; -+ -+ /* clear the entries */ -+ for(i=0; -+ (i<pMMUHeap->ui32PTETotalUsable) && (i<pMMUHeap->ui32PTNumEntriesUsable); -+ i++) -+ { -+ /* over-allocated PT entries for 4MB data page case should never be non-zero */ -+ pui32Tmp[i] = 0; -+ } -+ MakeKernelPageReadOnly(ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr); -+ -+ /* -+ free the pagetable memory -+ */ -+ if(bOSFreePT) -+ { -+ _FreePageTableMemory(pMMUHeap, ppsPTInfoList[ui32PTIndex]); -+ } -+ -+ /* -+ decrement the PT Entry Count by the number -+ of entries we've cleared in this pass -+ */ -+ pMMUHeap->ui32PTETotalUsable -= i; -+ } -+ else -+ { -+ /* decrement the PT Entry Count by a page's worth of entries */ -+ pMMUHeap->ui32PTETotalUsable -= pMMUHeap->ui32PTNumEntriesUsable; -+ } -+ -+ if(bOSFreePT) -+ { -+ /* free the pt info */ -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(MMU_PT_INFO), -+ ppsPTInfoList[ui32PTIndex], -+ IMG_NULL); -+ ppsPTInfoList[ui32PTIndex] = IMG_NULL; -+ } -+ } -+ else -+ { -+ /* decrement the PT Entry Count by a page's worth of usable entries */ -+ pMMUHeap->ui32PTETotalUsable -= pMMUHeap->ui32PTNumEntriesUsable; -+ } -+ -+ PDUMPCOMMENT("Finished free page table (page count == %08X)", pMMUHeap->ui32PageTableCount); -+} -+ -+/*! -+****************************************************************************** -+ FUNCTION: _DeferredFreePageTables -+ -+ PURPOSE: Free the page tables associated with an MMU. -+ -+ PARAMETERS: In: pMMUHeap - the mmu -+ RETURNS: None -+******************************************************************************/ -+static IMG_VOID -+_DeferredFreePageTables (MMU_HEAP *pMMUHeap) -+{ -+ IMG_UINT32 i; -+#if defined(FIX_HW_BRN_31620) -+ MMU_CONTEXT *psMMUContext = pMMUHeap->psMMUContext; -+ IMG_BOOL bInvalidateDirectoryCache = IMG_FALSE; -+ IMG_UINT32 ui32PDIndex; -+ IMG_UINT32 *pui32Tmp; -+ IMG_UINT32 j; -+#endif -+#if defined(PDUMP) -+ PDUMPCOMMENT("Free PTs (MMU Context ID == %u, PDBaseIndex == %u, PT count == 0x%x)", -+ pMMUHeap->psMMUContext->ui32PDumpMMUContextID, -+ pMMUHeap->ui32PDBaseIndex, -+ pMMUHeap->ui32PageTableCount); -+#endif -+#if defined(FIX_HW_BRN_31620) -+ for(i=0; i<pMMUHeap->ui32PageTableCount; i++) -+ { -+ ui32PDIndex = (pMMUHeap->ui32PDBaseIndex + i); -+ -+ if (psMMUContext->apsPTInfoList[ui32PDIndex]) -+ { -+ if (psMMUContext->apsPTInfoList[ui32PDIndex]->PTPageCpuVAddr) -+ { -+ /* -+ * We have to do this to setup the dummy page as -+ * not all heaps are PD cache size or aligned -+ */ -+ for (j=0;j<SGX_MMU_PT_SIZE;j++) -+ { -+ pui32Tmp = (IMG_UINT32 *) psMMUContext->apsPTInfoList[ui32PDIndex]->PTPageCpuVAddr; -+ BRN31620InvalidatePageTableEntry(psMMUContext, ui32PDIndex, j, &pui32Tmp[j]); -+ } -+ } -+ /* Free the PT and NULL's out the PTInfo */ -+ if (BRN31620FreePageTable(pMMUHeap, ui32PDIndex) == IMG_TRUE) -+ { -+ bInvalidateDirectoryCache = IMG_TRUE; -+ } -+ } -+ } -+ -+ /* -+ * Due to freeing PT's in chunks we might need to flush the PT cache -+ * rather then the directory cache -+ */ -+ if (bInvalidateDirectoryCache) -+ { -+ MMU_InvalidateDirectoryCache(pMMUHeap->psMMUContext->psDevInfo); -+ } -+ else -+ { -+ MMU_InvalidatePageTableCache(pMMUHeap->psMMUContext->psDevInfo); -+ } -+#else -+ for(i=0; i<pMMUHeap->ui32PageTableCount; i++) -+ { -+ _DeferredFreePageTable(pMMUHeap, i, IMG_TRUE); -+ } -+ MMU_InvalidateDirectoryCache(pMMUHeap->psMMUContext->psDevInfo); -+#endif -+} -+ -+ -+/*! -+****************************************************************************** -+ FUNCTION: _DeferredAllocPagetables -+ -+ PURPOSE: allocates page tables at time of allocation -+ -+ PARAMETERS: In: pMMUHeap - the mmu heap -+ DevVAddr - devVAddr of allocation -+ ui32Size - size of allocation -+ RETURNS: IMG_TRUE - Success -+ IMG_FALSE - Failed -+******************************************************************************/ -+static IMG_BOOL -+_DeferredAllocPagetables(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR DevVAddr, IMG_UINT32 ui32Size) -+{ -+ IMG_UINT32 ui32PageTableCount; -+ IMG_UINT32 ui32PDIndex; -+ IMG_UINT32 i; -+ IMG_UINT32 *pui32PDEntry; -+ MMU_PT_INFO **ppsPTInfoList; -+ SYS_DATA *psSysData; -+ IMG_DEV_VIRTADDR sHighDevVAddr; -+#if defined(FIX_HW_BRN_31620) -+ IMG_BOOL bFlushSystemCache = IMG_FALSE; -+ IMG_BOOL bSharedPT = IMG_FALSE; -+ IMG_DEV_VIRTADDR sDevVAddrRequestStart; -+ IMG_DEV_VIRTADDR sDevVAddrRequestEnd; -+ IMG_UINT32 ui32PDRequestStart; -+ IMG_UINT32 ui32PDRequestEnd; -+ IMG_UINT32 ui32ModifiedCachelines[BRN31620_CACHE_FLUSH_INDEX_SIZE]; -+#endif -+ -+ /* Check device linear address */ -+#if SGX_FEATURE_ADDRESS_SPACE_SIZE < 32 -+ PVR_ASSERT(DevVAddr.uiAddr < (1<<SGX_FEATURE_ADDRESS_SPACE_SIZE)); -+#endif -+ -+ /* get the sysdata */ -+ SysAcquireData(&psSysData); -+ -+ /* find the index/offset in PD entries */ -+ ui32PDIndex = DevVAddr.uiAddr >> pMMUHeap->ui32PDShift; -+ -+ /* how many PDs does the allocation occupy? */ -+ /* first check for overflows */ -+ if((UINT32_MAX_VALUE - DevVAddr.uiAddr) -+ < (ui32Size + pMMUHeap->ui32DataPageMask + pMMUHeap->ui32PTMask)) -+ { -+ /* detected overflow, clamp to highest address, reserve all PDs */ -+ sHighDevVAddr.uiAddr = UINT32_MAX_VALUE; -+ ui32PageTableCount = 1024; -+ } -+ else -+ { -+ sHighDevVAddr.uiAddr = DevVAddr.uiAddr -+ + ui32Size -+ + pMMUHeap->ui32DataPageMask -+ + pMMUHeap->ui32PTMask; -+ -+ ui32PageTableCount = sHighDevVAddr.uiAddr >> pMMUHeap->ui32PDShift; -+ } -+ -+ -+ /* Fix allocation of last 4MB */ -+ if (ui32PageTableCount == 0) -+ ui32PageTableCount = 1024; -+ -+#if defined(FIX_HW_BRN_31620) -+ for (i=0;i<BRN31620_CACHE_FLUSH_INDEX_SIZE;i++) -+ { -+ ui32ModifiedCachelines[i] = 0; -+ } -+ -+ /*****************************************************************/ -+ /* Save off requested data and round allocation to PD cache line */ -+ /*****************************************************************/ -+ sDevVAddrRequestStart = DevVAddr; -+ ui32PDRequestStart = ui32PDIndex; -+ sDevVAddrRequestEnd = sHighDevVAddr; -+ ui32PDRequestEnd = ui32PageTableCount - 1; -+ -+ /* Round allocations down to the PD cacheline */ -+ DevVAddr.uiAddr = DevVAddr.uiAddr & (~BRN31620_PDE_CACHE_FILL_MASK); -+ -+ /* Round the end address of the PD allocation to cacheline */ -+ if (UINT32_MAX_VALUE - sHighDevVAddr.uiAddr < (BRN31620_PDE_CACHE_FILL_SIZE - 1)) -+ { -+ sHighDevVAddr.uiAddr = UINT32_MAX_VALUE; -+ ui32PageTableCount = 1024; -+ } -+ else -+ { -+ sHighDevVAddr.uiAddr = ((sHighDevVAddr.uiAddr + (BRN31620_PDE_CACHE_FILL_SIZE - 1)) & (~BRN31620_PDE_CACHE_FILL_MASK)); -+ ui32PageTableCount = sHighDevVAddr.uiAddr >> pMMUHeap->ui32PDShift; -+ } -+ -+ ui32PDIndex = DevVAddr.uiAddr >> pMMUHeap->ui32PDShift; -+ -+ /* Fix allocation of last 4MB */ -+ if (ui32PageTableCount == 0) -+ ui32PageTableCount = 1024; -+#endif -+ -+ ui32PageTableCount -= ui32PDIndex; -+ -+ /* get the PD CPUVAddr base and advance to the first entry */ -+ pui32PDEntry = (IMG_UINT32*)pMMUHeap->psMMUContext->pvPDCpuVAddr; -+ pui32PDEntry += ui32PDIndex; -+ -+ /* and advance to the first PT info list */ -+ ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex]; -+ -+#if defined(PDUMP) -+ { -+ IMG_UINT32 ui32Flags = 0; -+ -+ /* pdump the PD Page modifications */ -+ if( MMU_IsHeapShared(pMMUHeap) ) -+ { -+ ui32Flags |= PDUMP_FLAGS_CONTINUOUS; -+ } -+ PDUMPCOMMENTWITHFLAGS(ui32Flags, "Alloc PTs (MMU Context ID == %u, PDBaseIndex == %u, Size == 0x%x, Shared = %s)", -+ pMMUHeap->psMMUContext->ui32PDumpMMUContextID, -+ pMMUHeap->ui32PDBaseIndex, -+ ui32Size, -+ MMU_IsHeapShared(pMMUHeap)?"True":"False"); -+ PDUMPCOMMENTWITHFLAGS(ui32Flags, "Alloc page table (page count == %08X)", ui32PageTableCount); -+ PDUMPCOMMENTWITHFLAGS(ui32Flags, "Page directory mods (page count == %08X)", ui32PageTableCount); -+ } -+#endif -+ /* walk the psPTInfoList to see what needs allocating: */ -+ for(i=0; i<ui32PageTableCount; i++) -+ { -+ if(ppsPTInfoList[i] == IMG_NULL) -+ { -+#if defined(FIX_HW_BRN_31620) -+ /* Check if we have a saved PT (i.e. this PDE cache line is still live) */ -+ if (pMMUHeap->psMMUContext->apsPTInfoListSave[ui32PDIndex + i]) -+ { -+ /* Only make this PTInfo "live" if it's requested */ -+ if (((ui32PDIndex + i) >= ui32PDRequestStart) && ((ui32PDIndex + i) <= ui32PDRequestEnd)) -+ { -+ IMG_UINT32 ui32PDCacheLine = (ui32PDIndex + i) >> BRN31620_PDES_PER_CACHE_LINE_SHIFT; -+ -+ ppsPTInfoList[i] = pMMUHeap->psMMUContext->apsPTInfoListSave[ui32PDIndex + i]; -+ pMMUHeap->psMMUContext->apsPTInfoListSave[ui32PDIndex + i] = IMG_NULL; -+ -+ pMMUHeap->psMMUContext->ui32PDCacheRangeRefCount[ui32PDCacheLine]++; -+ } -+ } -+ else -+ { -+#endif -+ OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof (MMU_PT_INFO), -+ (IMG_VOID **)&ppsPTInfoList[i], IMG_NULL, -+ "MMU Page Table Info"); -+ if (ppsPTInfoList[i] == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "_DeferredAllocPagetables: ERROR call to OSAllocMem failed")); -+ return IMG_FALSE; -+ } -+ OSMemSet (ppsPTInfoList[i], 0, sizeof(MMU_PT_INFO)); -+#if defined(FIX_HW_BRN_31620) -+ } -+#endif -+ } -+#if defined(FIX_HW_BRN_31620) -+ /* Only try to allocate if ppsPTInfoList[i] is valid */ -+ if (ppsPTInfoList[i]) -+ { -+#endif -+ if(ppsPTInfoList[i]->hPTPageOSMemHandle == IMG_NULL -+ && ppsPTInfoList[i]->PTPageCpuVAddr == IMG_NULL) -+ { -+ IMG_DEV_PHYADDR sDevPAddr = { 0 }; -+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) -+ IMG_UINT32 *pui32Tmp; -+ IMG_UINT32 j; -+#else -+#if !defined(FIX_HW_BRN_31620) -+ /* no page table has been allocated so allocate one */ -+ PVR_ASSERT(pui32PDEntry[i] == 0); -+#endif -+#endif -+ if(_AllocPageTableMemory (pMMUHeap, ppsPTInfoList[i], &sDevPAddr) != IMG_TRUE) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "_DeferredAllocPagetables: ERROR call to _AllocPageTableMemory failed")); -+ return IMG_FALSE; -+ } -+#if defined(FIX_HW_BRN_31620) -+ bFlushSystemCache = IMG_TRUE; -+ /* Bump up the page table count if required */ -+ { -+ IMG_UINT32 ui32PD; -+ IMG_UINT32 ui32PDCacheLine; -+ IMG_UINT32 ui32PDBitMaskIndex; -+ IMG_UINT32 ui32PDBitMaskShift; -+ -+ ui32PD = ui32PDIndex + i; -+ ui32PDCacheLine = ui32PD >> BRN31620_PDES_PER_CACHE_LINE_SHIFT; -+ ui32PDBitMaskIndex = ui32PDCacheLine >> BRN31620_CACHE_FLUSH_BITS_SHIFT; -+ ui32PDBitMaskShift = ui32PDCacheLine & BRN31620_CACHE_FLUSH_BITS_MASK; -+ ui32ModifiedCachelines[ui32PDBitMaskIndex] |= 1 << ui32PDBitMaskShift; -+ -+ /* Add 1 to ui32PD as we want the count, not a range */ -+ if ((pMMUHeap->ui32PDBaseIndex + pMMUHeap->ui32PageTableCount) < (ui32PD + 1)) -+ { -+ pMMUHeap->ui32PageTableCount = (ui32PD + 1) - pMMUHeap->ui32PDBaseIndex; -+ } -+ -+ if (((ui32PDIndex + i) >= ui32PDRequestStart) && ((ui32PDIndex + i) <= ui32PDRequestEnd)) -+ { -+ pMMUHeap->psMMUContext->ui32PDCacheRangeRefCount[ui32PDCacheLine]++; -+ } -+ } -+#endif -+ switch(pMMUHeap->psDevArena->DevMemHeapType) -+ { -+ case DEVICE_MEMORY_HEAP_SHARED : -+ case DEVICE_MEMORY_HEAP_SHARED_EXPORTED : -+ { -+ /* insert Page Table into all memory contexts */ -+ MMU_CONTEXT *psMMUContext = (MMU_CONTEXT*)pMMUHeap->psMMUContext->psDevInfo->pvMMUContextList; -+#if defined(SUPPORT_PDUMP_MULTI_PROCESS) -+ PVRSRV_SGXDEV_INFO *psDevInfo = psMMUContext->psDevInfo; -+#endif -+ while(psMMUContext) -+ { -+ MakeKernelPageReadWrite(psMMUContext->pvPDCpuVAddr); -+ /* get the PD CPUVAddr base and advance to the first entry */ -+ pui32PDEntry = (IMG_UINT32*)psMMUContext->pvPDCpuVAddr; -+ pui32PDEntry += ui32PDIndex; -+ -+ /* insert the page, specify the data page size and make the pde valid */ -+ pui32PDEntry[i] = (IMG_UINT32)(sDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT) -+ | pMMUHeap->ui32PDEPageSizeCtrl -+ | SGX_MMU_PDE_VALID; -+ MakeKernelPageReadOnly(psMMUContext->pvPDCpuVAddr); -+ #if defined(PDUMP) -+ /* pdump the PD Page modifications */ -+ #if defined(SUPPORT_PDUMP_MULTI_PROCESS) -+ if(psMMUContext->bPDumpActive) -+ #endif -+ { -+#if defined(SUPPORT_PDUMP_MULTI_PROCESS) -+ /* -+ Any modification of the uKernel memory context -+ needs to be PDumped when we're multi-process -+ */ -+ IMG_UINT32 ui32HeapFlags = ( psMMUContext->sPDDevPAddr.uiAddr == psDevInfo->sKernelPDDevPAddr.uiAddr ) ? PDUMP_FLAGS_PERSISTENT : 0; -+#else -+ IMG_UINT32 ui32HeapFlags = 0; -+#endif -+ PDUMPPDENTRIES(&pMMUHeap->sMMUAttrib, psMMUContext->hPDOSMemHandle, (IMG_VOID*)&pui32PDEntry[i], sizeof(IMG_UINT32), ui32HeapFlags, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG); -+ } -+ #endif /* PDUMP */ -+ /* advance to next context */ -+ psMMUContext = psMMUContext->psNext; -+ } -+#if defined(FIX_HW_BRN_31620) -+ bSharedPT = IMG_TRUE; -+#endif -+ break; -+ } -+ case DEVICE_MEMORY_HEAP_PERCONTEXT : -+ case DEVICE_MEMORY_HEAP_KERNEL : -+ { -+ MakeKernelPageReadWrite(pMMUHeap->psMMUContext->pvPDCpuVAddr); -+ /* insert Page Table into only this memory context */ -+ pui32PDEntry[i] = (IMG_UINT32)(sDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT) -+ | pMMUHeap->ui32PDEPageSizeCtrl -+ | SGX_MMU_PDE_VALID; -+ MakeKernelPageReadOnly(pMMUHeap->psMMUContext->pvPDCpuVAddr); -+ /* pdump the PD Page modifications */ -+ PDUMPPDENTRIES(&pMMUHeap->sMMUAttrib, pMMUHeap->psMMUContext->hPDOSMemHandle, (IMG_VOID*)&pui32PDEntry[i], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG); -+ break; -+ } -+ default: -+ { -+ PVR_DPF((PVR_DBG_ERROR, "_DeferredAllocPagetables: ERROR invalid heap type")); -+ return IMG_FALSE; -+ } -+ } -+ -+#if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) -+ /* This is actually not to do with multiple mem contexts, but to do with the directory cache. -+ In the 1 context implementation of the MMU, the directory "cache" is actually a copy of the -+ page directory memory, and requires updating whenever the page directory changes, even if there -+ was no previous value in a particular entry -+ */ -+ MMU_InvalidateDirectoryCache(pMMUHeap->psMMUContext->psDevInfo); -+#endif -+#if defined(FIX_HW_BRN_31620) -+ /* If this PT is not in the requested range then save it and null out the main PTInfo */ -+ if (((ui32PDIndex + i) < ui32PDRequestStart) || ((ui32PDIndex + i) > ui32PDRequestEnd)) -+ { -+ pMMUHeap->psMMUContext->apsPTInfoListSave[ui32PDIndex + i] = ppsPTInfoList[i]; -+ ppsPTInfoList[i] = IMG_NULL; -+ } -+#endif -+ } -+ else -+ { -+#if !defined(FIX_HW_BRN_31620) -+ /* already have an allocated PT */ -+ PVR_ASSERT(pui32PDEntry[i] != 0); -+#endif -+ } -+#if defined(FIX_HW_BRN_31620) -+ } -+#endif -+ } -+ -+ #if defined(SGX_FEATURE_SYSTEM_CACHE) -+ #if defined(FIX_HW_BRN_31620) -+ /* This function might not allocate any new PT's so check before flushing */ -+ if (bFlushSystemCache) -+ { -+ #endif -+ -+ MMU_InvalidateSystemLevelCache(pMMUHeap->psMMUContext->psDevInfo); -+ #endif /* SGX_FEATURE_SYSTEM_CACHE */ -+ #if defined(FIX_HW_BRN_31620) -+ } -+ -+ /* Handle the last 4MB roll over */ -+ sHighDevVAddr.uiAddr = sHighDevVAddr.uiAddr - 1; -+ -+ /* Update our PD flush mask if required */ -+ if (bFlushSystemCache) -+ { -+ MMU_CONTEXT *psMMUContext; -+ -+ if (bSharedPT) -+ { -+ MMU_CONTEXT *psMMUContext = (MMU_CONTEXT*)pMMUHeap->psMMUContext->psDevInfo->pvMMUContextList; -+ -+ while(psMMUContext) -+ { -+ for (i=0;i<BRN31620_CACHE_FLUSH_INDEX_SIZE;i++) -+ { -+ psMMUContext->ui32PDChangeMask[i] |= ui32ModifiedCachelines[i]; -+ } -+ -+ /* advance to next context */ -+ psMMUContext = psMMUContext->psNext; -+ } -+ } -+ else -+ { -+ for (i=0;i<BRN31620_CACHE_FLUSH_INDEX_SIZE;i++) -+ { -+ pMMUHeap->psMMUContext->ui32PDChangeMask[i] |= ui32ModifiedCachelines[i]; -+ } -+ } -+ -+ /* -+ * Always hook up the dummy page when we allocate a new range of PTs. -+ * It might be this is overwritten before the SGX access the dummy page -+ * but we don't care, it's a lot simpler to add this logic here. -+ */ -+ psMMUContext = pMMUHeap->psMMUContext; -+ for (i=0;i<BRN31620_CACHE_FLUSH_INDEX_SIZE;i++) -+ { -+ IMG_UINT32 j; -+ -+ for(j=0;j<BRN31620_CACHE_FLUSH_BITS_SIZE;j++) -+ { -+ if (ui32ModifiedCachelines[i] & (1 << j)) -+ { -+ PVRSRV_SGXDEV_INFO *psDevInfo = psMMUContext->psDevInfo; -+ MMU_PT_INFO *psTempPTInfo = IMG_NULL; -+ IMG_UINT32 *pui32Tmp; -+ -+ ui32PDIndex = (((i * BRN31620_CACHE_FLUSH_BITS_SIZE) + j) * BRN31620_PDES_PER_CACHE_LINE_SIZE) + BRN31620_DUMMY_PDE_INDEX; -+ -+ /* The PT for the dummy page might not be "live". If not get it from the saved pointer */ -+ if (psMMUContext->apsPTInfoList[ui32PDIndex]) -+ { -+ psTempPTInfo = psMMUContext->apsPTInfoList[ui32PDIndex]; -+ } -+ else -+ { -+ psTempPTInfo = psMMUContext->apsPTInfoListSave[ui32PDIndex]; -+ } -+ -+ PVR_ASSERT(psTempPTInfo != IMG_NULL); -+ -+ MakeKernelPageReadWrite(psTempPTInfo->PTPageCpuVAddr); -+ pui32Tmp = (IMG_UINT32 *) psTempPTInfo->PTPageCpuVAddr; -+ PVR_ASSERT(pui32Tmp != IMG_NULL); -+ pui32Tmp[BRN31620_DUMMY_PTE_INDEX] = (psDevInfo->sBRN31620DummyPageDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT) -+ | SGX_MMU_PTE_DUMMY_PAGE -+ | SGX_MMU_PTE_READONLY -+ | SGX_MMU_PTE_VALID; -+ MakeKernelPageReadOnly(psTempPTInfo->PTPageCpuVAddr); -+ PDUMPCOMMENT("BRN31620 Dump PTE for dummy page after wireing up new PT"); -+ PDUMPMEMPTENTRIES(&pMMUHeap->sMMUAttrib, psTempPTInfo->hPTPageOSMemHandle, (IMG_VOID *) &pui32Tmp[BRN31620_DUMMY_PTE_INDEX], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG); -+ } -+ } -+ } -+ } -+ #endif -+ -+ return IMG_TRUE; -+} -+ -+ -+#if defined(PDUMP) -+/*! -+ * FUNCTION: MMU_GetPDumpContextID -+ * -+ * RETURNS: pdump MMU context ID -+ */ -+IMG_UINT32 MMU_GetPDumpContextID(IMG_HANDLE hDevMemContext) -+{ -+ BM_CONTEXT *pBMContext = hDevMemContext; -+ PVR_ASSERT(pBMContext); -+ /* PRQA S 0505 1 */ /* PVR_ASSERT should catch NULL ptr */ -+ return pBMContext->psMMUContext->ui32PDumpMMUContextID; -+} -+ -+/*! -+ * FUNCTION: MMU_SetPDumpAttribs -+ * -+ * PURPOSE: Called from MMU_Initialise and MMU_Create. -+ * Sets up device-specific attributes for pdumping. -+ * FIXME: breaks variable size PTs. Really need separate per context -+ * and per heap attribs. -+ * -+ * INPUT: psDeviceNode - used to access deviceID -+ * INPUT: ui32DataPageMask - data page mask -+ * INPUT: ui32PTSize - PT size -+ * -+ * OUTPUT: psMMUAttrib - pdump MMU attributes -+ * -+ * RETURNS: none -+ */ -+#if defined(SGX_FEATURE_VARIABLE_MMU_PAGE_SIZE) -+# error "FIXME: breaks variable size pagetables" -+#endif -+static IMG_VOID MMU_SetPDumpAttribs(PDUMP_MMU_ATTRIB *psMMUAttrib, -+ PVRSRV_DEVICE_NODE *psDeviceNode, -+ IMG_UINT32 ui32DataPageMask, -+ IMG_UINT32 ui32PTSize) -+{ -+ /* Sets up device ID, contains pdump memspace name */ -+ psMMUAttrib->sDevId = psDeviceNode->sDevId; -+ -+ psMMUAttrib->pszPDRegRegion = IMG_NULL; -+ psMMUAttrib->ui32DataPageMask = ui32DataPageMask; -+ -+ psMMUAttrib->ui32PTEValid = SGX_MMU_PTE_VALID; -+ psMMUAttrib->ui32PTSize = ui32PTSize; -+ psMMUAttrib->ui32PTEAlignShift = SGX_MMU_PTE_ADDR_ALIGNSHIFT; -+ -+ psMMUAttrib->ui32PDEMask = SGX_MMU_PDE_ADDR_MASK; -+ psMMUAttrib->ui32PDEAlignShift = SGX_MMU_PDE_ADDR_ALIGNSHIFT; -+} -+#endif /* PDUMP */ -+ -+/*! -+****************************************************************************** -+ FUNCTION: MMU_Initialise -+ -+ PURPOSE: Called from BM_CreateContext. -+ Allocates the top level Page Directory 4k Page for the new context. -+ -+ PARAMETERS: None -+ RETURNS: PVRSRV_ERROR -+******************************************************************************/ -+PVRSRV_ERROR -+MMU_Initialise (PVRSRV_DEVICE_NODE *psDeviceNode, MMU_CONTEXT **ppsMMUContext, IMG_DEV_PHYADDR *psPDDevPAddr) -+{ -+ IMG_UINT32 *pui32Tmp; -+ IMG_UINT32 i; -+ IMG_CPU_VIRTADDR pvPDCpuVAddr; -+ IMG_DEV_PHYADDR sPDDevPAddr; -+ IMG_CPU_PHYADDR sCpuPAddr; -+ MMU_CONTEXT *psMMUContext; -+ IMG_HANDLE hPDOSMemHandle = IMG_NULL; -+ SYS_DATA *psSysData; -+ PVRSRV_SGXDEV_INFO *psDevInfo; -+#if defined(PDUMP) -+ PDUMP_MMU_ATTRIB sMMUAttrib; -+#endif -+ PVR_DPF ((PVR_DBG_MESSAGE, "MMU_Initialise")); -+ -+ SysAcquireData(&psSysData); -+#if defined(PDUMP) -+ /* Note: these attribs are on the stack, used only to pdump the MMU context -+ * creation. */ -+ MMU_SetPDumpAttribs(&sMMUAttrib, psDeviceNode, -+ SGX_MMU_PAGE_MASK, -+ SGX_MMU_PT_SIZE * sizeof(IMG_UINT32)); -+#endif -+ -+ OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof (MMU_CONTEXT), -+ (IMG_VOID **)&psMMUContext, IMG_NULL, -+ "MMU Context"); -+ if (psMMUContext == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to OSAllocMem failed")); -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ OSMemSet (psMMUContext, 0, sizeof(MMU_CONTEXT)); -+ -+ /* stick the devinfo in the context for subsequent use */ -+ psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice; -+ psMMUContext->psDevInfo = psDevInfo; -+ -+ /* record device node for subsequent use */ -+ psMMUContext->psDeviceNode = psDeviceNode; -+ -+ /* allocate 4k page directory page for the new context */ -+ if(psDeviceNode->psLocalDevMemArena == IMG_NULL) -+ { -+ if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, -+ SGX_MMU_PAGE_SIZE, -+ SGX_MMU_PAGE_SIZE, -+ IMG_NULL, -+ 0, -+ IMG_NULL, -+ &pvPDCpuVAddr, -+ &hPDOSMemHandle) != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to OSAllocPages failed")); -+ return PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES; -+ } -+ -+ if(pvPDCpuVAddr) -+ { -+ sCpuPAddr = OSMapLinToCPUPhys(hPDOSMemHandle, -+ pvPDCpuVAddr); -+ } -+ else -+ { -+ /* This is not used in all cases, since not all ports currently -+ * support OSMemHandleToCpuPAddr */ -+ sCpuPAddr = OSMemHandleToCpuPAddr(hPDOSMemHandle, 0); -+ } -+ sPDDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr); -+ -+ #if PAGE_TEST -+ PageTest(pvPDCpuVAddr, sPDDevPAddr); -+ #endif -+ -+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) -+ /* Allocate dummy PT and Data pages for the first context to be created */ -+ if(!psDevInfo->pvMMUContextList) -+ { -+ /* Dummy PT page */ -+ if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, -+ SGX_MMU_PAGE_SIZE, -+ SGX_MMU_PAGE_SIZE, -+ IMG_NULL, -+ 0, -+ IMG_NULL, -+ &psDevInfo->pvDummyPTPageCpuVAddr, -+ &psDevInfo->hDummyPTPageOSMemHandle) != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to OSAllocPages failed")); -+ return PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES; -+ } -+ -+ if(psDevInfo->pvDummyPTPageCpuVAddr) -+ { -+ sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->hDummyPTPageOSMemHandle, -+ psDevInfo->pvDummyPTPageCpuVAddr); -+ } -+ else -+ { -+ /* This is not used in all cases, since not all ports currently -+ * support OSMemHandleToCpuPAddr */ -+ sCpuPAddr = OSMemHandleToCpuPAddr(psDevInfo->hDummyPTPageOSMemHandle, 0); -+ } -+ psDevInfo->sDummyPTDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr); -+ -+ /* Dummy Data page */ -+ if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, -+ SGX_MMU_PAGE_SIZE, -+ SGX_MMU_PAGE_SIZE, -+ IMG_NULL, -+ 0, -+ IMG_NULL, -+ &psDevInfo->pvDummyDataPageCpuVAddr, -+ &psDevInfo->hDummyDataPageOSMemHandle) != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to OSAllocPages failed")); -+ return PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES; -+ } -+ -+ if(psDevInfo->pvDummyDataPageCpuVAddr) -+ { -+ sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->hDummyPTPageOSMemHandle, -+ psDevInfo->pvDummyDataPageCpuVAddr); -+ } -+ else -+ { -+ sCpuPAddr = OSMemHandleToCpuPAddr(psDevInfo->hDummyDataPageOSMemHandle, 0); -+ } -+ psDevInfo->sDummyDataDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr); -+ } -+#endif /* #if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) */ -+#if defined(FIX_HW_BRN_31620) -+ /* Allocate dummy Data pages for the first context to be created */ -+ if(!psDevInfo->pvMMUContextList) -+ { -+ IMG_UINT32 j; -+ /* Allocate dummy page */ -+ if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, -+ SGX_MMU_PAGE_SIZE, -+ SGX_MMU_PAGE_SIZE, -+ IMG_NULL, -+ 0, -+ IMG_NULL, -+ &psDevInfo->pvBRN31620DummyPageCpuVAddr, -+ &psDevInfo->hBRN31620DummyPageOSMemHandle) != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to OSAllocPages failed")); -+ return PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES; -+ } -+ -+ /* Get a physical address */ -+ if(psDevInfo->pvBRN31620DummyPageCpuVAddr) -+ { -+ sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->hBRN31620DummyPageOSMemHandle, -+ psDevInfo->pvBRN31620DummyPageCpuVAddr); -+ } -+ else -+ { -+ sCpuPAddr = OSMemHandleToCpuPAddr(psDevInfo->hBRN31620DummyPageOSMemHandle, 0); -+ } -+ -+ pui32Tmp = (IMG_UINT32 *)psDevInfo->pvBRN31620DummyPageCpuVAddr; -+ for(j=0; j<(SGX_MMU_PAGE_SIZE/4); j++) -+ { -+ pui32Tmp[j] = BRN31620_DUMMY_PAGE_SIGNATURE; -+ } -+ -+ psDevInfo->sBRN31620DummyPageDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr); -+ PDUMPMALLOCPAGETABLE(&psDeviceNode->sDevId, psDevInfo->hBRN31620DummyPageOSMemHandle, 0, psDevInfo->pvBRN31620DummyPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG); -+ -+ /* Allocate dummy PT */ -+ if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, -+ SGX_MMU_PAGE_SIZE, -+ SGX_MMU_PAGE_SIZE, -+ IMG_NULL, -+ 0, -+ IMG_NULL, -+ &psDevInfo->pvBRN31620DummyPTCpuVAddr, -+ &psDevInfo->hBRN31620DummyPTOSMemHandle) != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to OSAllocPages failed")); -+ return PVRSRV_ERROR_FAILED_TO_ALLOC_PAGES; -+ } -+ -+ /* Get a physical address */ -+ if(psDevInfo->pvBRN31620DummyPTCpuVAddr) -+ { -+ sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->hBRN31620DummyPTOSMemHandle, -+ psDevInfo->pvBRN31620DummyPTCpuVAddr); -+ } -+ else -+ { -+ sCpuPAddr = OSMemHandleToCpuPAddr(psDevInfo->hBRN31620DummyPTOSMemHandle, 0); -+ } -+ -+ OSMemSet(psDevInfo->pvBRN31620DummyPTCpuVAddr,0,SGX_MMU_PAGE_SIZE); -+ psDevInfo->sBRN31620DummyPTDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr); -+ PDUMPMALLOCPAGETABLE(&psDeviceNode->sDevId, psDevInfo->hBRN31620DummyPTOSMemHandle, 0, psDevInfo->pvBRN31620DummyPTCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG); -+ } -+#endif -+ } -+ else -+ { -+ /* -+ We cannot use IMG_SYS_PHYADDR here, as that is 64-bit for 32-bit PAE builds. -+ The physical address in this call to RA_Alloc is specifically the SysPAddr -+ of local (card) space, and it is highly unlikely we would ever need to -+ support > 4GB of local (card) memory (this does assume that such local -+ memory will be mapped into System physical memory space at a low address so -+ that any and all local memory exists within the 4GB SYSPAddr range). -+ */ -+ IMG_UINTPTR_T uiLocalPAddr; -+ IMG_SYS_PHYADDR sSysPAddr; -+ -+ /* allocate from the device's local memory arena */ -+ if(RA_Alloc(psDeviceNode->psLocalDevMemArena, -+ SGX_MMU_PAGE_SIZE, -+ IMG_NULL, -+ IMG_NULL, -+ 0, -+ SGX_MMU_PAGE_SIZE, -+ 0, -+ IMG_NULL, -+ 0, -+ &uiLocalPAddr)!= IMG_TRUE) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to RA_Alloc failed")); -+ return PVRSRV_ERROR_FAILED_TO_ALLOC_VIRT_MEMORY; -+ } -+ -+ /* Munge the local PAddr back into the SysPAddr */ -+ sSysPAddr.uiAddr = uiLocalPAddr; -+ -+ /* derive the CPU virtual address */ -+ sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr); -+ sPDDevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sSysPAddr); -+ pvPDCpuVAddr = OSMapPhysToLin(sCpuPAddr, -+ SGX_MMU_PAGE_SIZE, -+ PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY, -+ &hPDOSMemHandle); -+ if(!pvPDCpuVAddr) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR failed to map page tables")); -+ return PVRSRV_ERROR_FAILED_TO_MAP_PAGE_TABLE; -+ } -+ -+ #if PAGE_TEST -+ PageTest(pvPDCpuVAddr, sPDDevPAddr); -+ #endif -+ -+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) -+ /* Allocate dummy PT and Data pages for the first context to be created */ -+ if(!psDevInfo->pvMMUContextList) -+ { -+ /* Dummy PT page */ -+ if(RA_Alloc(psDeviceNode->psLocalDevMemArena, -+ SGX_MMU_PAGE_SIZE, -+ IMG_NULL, -+ IMG_NULL, -+ 0, -+ SGX_MMU_PAGE_SIZE, -+ 0, -+ IMG_NULL, -+ 0, -+ &uiLocalPAddr)!= IMG_TRUE) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to RA_Alloc failed")); -+ return PVRSRV_ERROR_FAILED_TO_ALLOC_VIRT_MEMORY; -+ } -+ -+ /* Munge the local PAddr back into the SysPAddr */ -+ sSysPAddr.uiAddr = uiLocalPAddr; -+ -+ /* derive the CPU virtual address */ -+ sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr); -+ psDevInfo->sDummyPTDevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sSysPAddr); -+ psDevInfo->pvDummyPTPageCpuVAddr = OSMapPhysToLin(sCpuPAddr, -+ SGX_MMU_PAGE_SIZE, -+ PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY, -+ &psDevInfo->hDummyPTPageOSMemHandle); -+ if(!psDevInfo->pvDummyPTPageCpuVAddr) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR failed to map page tables")); -+ return PVRSRV_ERROR_FAILED_TO_MAP_PAGE_TABLE; -+ } -+ -+ /* Dummy Data page */ -+ if(RA_Alloc(psDeviceNode->psLocalDevMemArena, -+ SGX_MMU_PAGE_SIZE, -+ IMG_NULL, -+ IMG_NULL, -+ 0, -+ SGX_MMU_PAGE_SIZE, -+ 0, -+ IMG_NULL, -+ 0, -+ &uiLocalPAddr)!= IMG_TRUE) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to RA_Alloc failed")); -+ return PVRSRV_ERROR_FAILED_TO_ALLOC_VIRT_MEMORY; -+ } -+ -+ /* Munge the local PAddr back into the SysPAddr */ -+ sSysPAddr.uiAddr = uiLocalPAddr; -+ -+ /* derive the CPU virtual address */ -+ sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr); -+ psDevInfo->sDummyDataDevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sSysPAddr); -+ psDevInfo->pvDummyDataPageCpuVAddr = OSMapPhysToLin(sCpuPAddr, -+ SGX_MMU_PAGE_SIZE, -+ PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY, -+ &psDevInfo->hDummyDataPageOSMemHandle); -+ if(!psDevInfo->pvDummyDataPageCpuVAddr) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR failed to map page tables")); -+ return PVRSRV_ERROR_FAILED_TO_MAP_PAGE_TABLE; -+ } -+ } -+#endif /* #if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) */ -+#if defined(FIX_HW_BRN_31620) -+ /* Allocate dummy PT and Data pages for the first context to be created */ -+ if(!psDevInfo->pvMMUContextList) -+ { -+ IMG_UINT32 j; -+ /* Allocate dummy page */ -+ if(RA_Alloc(psDeviceNode->psLocalDevMemArena, -+ SGX_MMU_PAGE_SIZE, -+ IMG_NULL, -+ IMG_NULL, -+ 0, -+ SGX_MMU_PAGE_SIZE, -+ 0, -+ IMG_NULL, -+ 0, -+ &uiLocalPAddr)!= IMG_TRUE) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to RA_Alloc failed")); -+ return PVRSRV_ERROR_FAILED_TO_ALLOC_VIRT_MEMORY; -+ } -+ -+ /* Munge the local PAddr back into the SysPAddr */ -+ sSysPAddr.uiAddr = uiLocalPAddr; -+ -+ /* derive the CPU virtual address */ -+ sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr); -+ psDevInfo->sBRN31620DummyPageDevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sSysPAddr); -+ psDevInfo->pvBRN31620DummyPageCpuVAddr = OSMapPhysToLin(sCpuPAddr, -+ SGX_MMU_PAGE_SIZE, -+ PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY, -+ &psDevInfo->hBRN31620DummyPageOSMemHandle); -+ if(!psDevInfo->pvBRN31620DummyPageCpuVAddr) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR failed to map page tables")); -+ return PVRSRV_ERROR_FAILED_TO_MAP_PAGE_TABLE; -+ } -+ -+ MakeKernelPageReadWrite(psDevInfo->pvBRN31620DummyPageCpuVAddr); -+ pui32Tmp = (IMG_UINT32 *)psDevInfo->pvBRN31620DummyPageCpuVAddr; -+ for(j=0; j<(SGX_MMU_PAGE_SIZE/4); j++) -+ { -+ pui32Tmp[j] = BRN31620_DUMMY_PAGE_SIGNATURE; -+ } -+ MakeKernelPageReadOnly(psDevInfo->pvBRN31620DummyPageCpuVAddr); -+ PDUMPMALLOCPAGETABLE(&psDeviceNode->sDevId, psDevInfo->hBRN31620DummyPageOSMemHandle, 0, psDevInfo->pvBRN31620DummyPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG); -+ -+ /* Allocate dummy PT */ -+ if(RA_Alloc(psDeviceNode->psLocalDevMemArena, -+ SGX_MMU_PAGE_SIZE, -+ IMG_NULL, -+ IMG_NULL, -+ 0, -+ SGX_MMU_PAGE_SIZE, -+ 0, -+ IMG_NULL, -+ 0, -+ &uiLocalPAddr)!= IMG_TRUE) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to RA_Alloc failed")); -+ return PVRSRV_ERROR_FAILED_TO_ALLOC_VIRT_MEMORY; -+ } -+ -+ /* Munge the local PAddr back into the SysPAddr */ -+ sSysPAddr.uiAddr = uiLocalPAddr; -+ -+ /* derive the CPU virtual address */ -+ sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr); -+ psDevInfo->sBRN31620DummyPTDevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sSysPAddr); -+ psDevInfo->pvBRN31620DummyPTCpuVAddr = OSMapPhysToLin(sCpuPAddr, -+ SGX_MMU_PAGE_SIZE, -+ PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY, -+ &psDevInfo->hBRN31620DummyPTOSMemHandle); -+ -+ if(!psDevInfo->pvBRN31620DummyPTCpuVAddr) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR failed to map page tables")); -+ return PVRSRV_ERROR_FAILED_TO_MAP_PAGE_TABLE; -+ } -+ -+ OSMemSet(psDevInfo->pvBRN31620DummyPTCpuVAddr,0,SGX_MMU_PAGE_SIZE); -+ PDUMPMALLOCPAGETABLE(&psDeviceNode->sDevId, psDevInfo->hBRN31620DummyPTOSMemHandle, 0, psDevInfo->pvBRN31620DummyPTCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG); -+ } -+#endif /* #if defined(FIX_HW_BRN_31620) */ -+ } -+ -+#if defined(FIX_HW_BRN_31620) -+ if (!psDevInfo->pvMMUContextList) -+ { -+ /* Save the kernel MMU context which is always the 1st to be created */ -+ psDevInfo->hKernelMMUContext = psMMUContext; -+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: saving kernel mmu context: %p", psMMUContext)); -+ } -+#endif -+ -+#if defined(PDUMP) -+#if defined(SUPPORT_PDUMP_MULTI_PROCESS) -+ /* Find out if this context is for the active pdump client. -+ * If it is, need to ensure PD entries are pdumped whenever another -+ * process allocates from a shared heap. */ -+ { -+ PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData(); -+ if(psPerProc == IMG_NULL) -+ { -+ /* changes to the kernel context PD/PTs should be pdumped */ -+ psMMUContext->bPDumpActive = IMG_TRUE; -+ } -+ else -+ { -+ psMMUContext->bPDumpActive = psPerProc->bPDumpActive; -+ } -+ } -+#endif /* SUPPORT_PDUMP_MULTI_PROCESS */ -+ /* pdump the PD malloc */ -+ PDUMPCOMMENT("Alloc page directory for new MMU context (PDDevPAddr == 0x" DEVPADDR_FMT ")", sPDDevPAddr.uiAddr); -+ PDUMPMALLOCPAGETABLE(&psDeviceNode->sDevId, hPDOSMemHandle, 0, pvPDCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PD_UNIQUETAG); -+#endif /* PDUMP */ -+ -+#ifdef SUPPORT_SGX_MMU_BYPASS -+ EnableHostAccess(psMMUContext); -+#endif -+ -+ if (pvPDCpuVAddr) -+ { -+ pui32Tmp = (IMG_UINT32 *)pvPDCpuVAddr; -+ } -+ else -+ { -+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: pvPDCpuVAddr invalid")); -+ return PVRSRV_ERROR_INVALID_CPU_ADDR; -+ } -+ -+ -+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) -+ MakeKernelPageReadWrite(pvPDCpuVAddr); -+ /* wire-up the new PD to the dummy PT */ -+ for(i=0; i<SGX_MMU_PD_SIZE; i++) -+ { -+ pui32Tmp[i] = (psDevInfo->sDummyPTDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT) -+ | SGX_MMU_PDE_PAGE_SIZE_4K -+ | SGX_MMU_PDE_VALID; -+ } -+ MakeKernelPageReadOnly(pvPDCpuVAddr); -+ -+ if(!psDevInfo->pvMMUContextList) -+ { -+ /* -+ if we've just allocated the dummy pages -+ wire up the dummy PT to the dummy data page -+ */ -+ MakeKernelPageReadWrite(psDevInfo->pvDummyPTPageCpuVAddr); -+ pui32Tmp = (IMG_UINT32 *)psDevInfo->pvDummyPTPageCpuVAddr; -+ for(i=0; i<SGX_MMU_PT_SIZE; i++) -+ { -+ pui32Tmp[i] = (psDevInfo->sDummyDataDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT) -+ | SGX_MMU_PTE_VALID; -+ } -+ MakeKernelPageReadOnly(psDevInfo->pvDummyPTPageCpuVAddr); -+ /* pdump the Dummy PT Page */ -+ PDUMPCOMMENT("Dummy Page table contents"); -+ PDUMPMEMPTENTRIES(&sMMUAttrib, psDevInfo->hDummyPTOSMemHandle, psDevInfo->pvDummyPTPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG); -+ -+ /* -+ write a signature to the dummy data page -+ */ -+ MakeKernelPageReadWrite(psDevInfo->pvDummyDataPageCpuVAddr); -+ pui32Tmp = (IMG_UINT32 *)psDevInfo->pvDummyDataPageCpuVAddr; -+ for(i=0; i<(SGX_MMU_PAGE_SIZE/4); i++) -+ { -+ pui32Tmp[i] = DUMMY_DATA_PAGE_SIGNATURE; -+ } -+ MakeKernelPageReadOnly(psDevInfo->pvDummyDataPageCpuVAddr); -+ /* pdump the Dummy Data Page */ -+ PDUMPCOMMENT("Dummy Data Page contents"); -+ PDUMPMEMPTENTRIES(PVRSRV_DEVICE_TYPE_SGX, psDevInfo->hDummyDataPageOSMemHandle, psDevInfo->pvDummyDataPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG); -+ } -+#else /* #if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) */ -+ /* initialise the PD to invalid address state */ -+ MakeKernelPageReadWrite(pvPDCpuVAddr); -+ for(i=0; i<SGX_MMU_PD_SIZE; i++) -+ { -+ /* invalid, no read, no write, no cache consistency */ -+ pui32Tmp[i] = 0; -+ } -+ MakeKernelPageReadOnly(pvPDCpuVAddr); -+#endif /* #if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) */ -+ -+#if defined(PDUMP) -+#if defined(SUPPORT_PDUMP_MULTI_PROCESS) -+ if(psMMUContext->bPDumpActive) -+#endif /* SUPPORT_PDUMP_MULTI_PROCESS */ -+ { -+ /* pdump the PD Page */ -+ PDUMPCOMMENT("Page directory contents"); -+ PDUMPPDENTRIES(&sMMUAttrib, hPDOSMemHandle, pvPDCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG); -+ } -+#endif -+#if defined(FIX_HW_BRN_31620) -+ { -+ IMG_UINT32 i; -+ IMG_UINT32 ui32PDCount = 0; -+ IMG_UINT32 *pui32PT; -+ pui32Tmp = (IMG_UINT32 *)pvPDCpuVAddr; -+ -+ PDUMPCOMMENT("BRN31620 Set up dummy PT"); -+ -+ MakeKernelPageReadWrite(psDevInfo->pvBRN31620DummyPTCpuVAddr); -+ pui32PT = (IMG_UINT32 *) psDevInfo->pvBRN31620DummyPTCpuVAddr; -+ pui32PT[BRN31620_DUMMY_PTE_INDEX] = (psDevInfo->sBRN31620DummyPageDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT) -+ | SGX_MMU_PTE_DUMMY_PAGE -+ | SGX_MMU_PTE_READONLY -+ | SGX_MMU_PTE_VALID; -+ MakeKernelPageReadOnly(psDevInfo->pvBRN31620DummyPTCpuVAddr); -+ -+#if defined(PDUMP) -+ /* Dump initial contents */ -+ PDUMPCOMMENT("BRN31620 Dump dummy PT contents"); -+ PDUMPMEMPTENTRIES(&sMMUAttrib, psDevInfo->hBRN31620DummyPTOSMemHandle, psDevInfo->pvBRN31620DummyPTCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG); -+ PDUMPCOMMENT("BRN31620 Dump dummy page contents"); -+ PDUMPMEMPTENTRIES(&sMMUAttrib, psDevInfo->hBRN31620DummyPageOSMemHandle, psDevInfo->pvBRN31620DummyPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG); -+ -+ /* Dump the wiring */ -+ for(i=0;i<SGX_MMU_PT_SIZE;i++) -+ { -+ PDUMPMEMPTENTRIES(&sMMUAttrib, psDevInfo->hBRN31620DummyPTOSMemHandle, &pui32PT[i], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG); -+ } -+#endif -+ PDUMPCOMMENT("BRN31620 Dump PDE wire up"); -+ /* Walk the PD wireing up the PT's */ -+ for(i=0;i<SGX_MMU_PD_SIZE;i++) -+ { -+ pui32Tmp[i] = 0; -+ -+ if (ui32PDCount == BRN31620_DUMMY_PDE_INDEX) -+ { -+ MakeKernelPageReadWrite(pvPDCpuVAddr); -+ pui32Tmp[i] = (psDevInfo->sBRN31620DummyPTDevPAddr.uiAddr>>SGX_MMU_PDE_ADDR_ALIGNSHIFT) -+ | SGX_MMU_PDE_PAGE_SIZE_4K -+ | SGX_MMU_PDE_DUMMY_PAGE -+ | SGX_MMU_PDE_VALID; -+ MakeKernelPageReadOnly(pvPDCpuVAddr); -+ } -+ PDUMPMEMPTENTRIES(&sMMUAttrib, hPDOSMemHandle, (IMG_VOID *) &pui32Tmp[i], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG); -+ ui32PDCount++; -+ if (ui32PDCount == BRN31620_PDES_PER_CACHE_LINE_SIZE) -+ { -+ /* Reset PT count */ -+ ui32PDCount = 0; -+ } -+ } -+ -+ -+ /* pdump the Dummy PT Page */ -+ PDUMPCOMMENT("BRN31620 dummy Page table contents"); -+ PDUMPMEMPTENTRIES(&sMMUAttrib, psDevInfo->hBRN31620DummyPageOSMemHandle, psDevInfo->pvBRN31620DummyPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG); -+ } -+#endif -+#if defined(PDUMP) -+ /* pdump set MMU context */ -+ { -+ PVRSRV_ERROR eError; -+ /* default MMU type is 1, 4k page */ -+ IMG_UINT32 ui32MMUType = 1; -+ -+ #if defined(SGX_FEATURE_36BIT_MMU) -+ ui32MMUType = 3; -+ #else -+ #if defined(SGX_FEATURE_VARIABLE_MMU_PAGE_SIZE) -+ ui32MMUType = 2; -+ #endif -+ #endif -+ -+ eError = PDumpSetMMUContext(PVRSRV_DEVICE_TYPE_SGX, -+ psDeviceNode->sDevId.pszPDumpDevName, -+ &psMMUContext->ui32PDumpMMUContextID, -+ ui32MMUType, -+ PDUMP_PT_UNIQUETAG, -+ hPDOSMemHandle, -+ pvPDCpuVAddr); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "MMU_Initialise: ERROR call to PDumpSetMMUContext failed")); -+ return eError; -+ } -+ } -+ -+ /* PDump the context ID */ -+ PDUMPCOMMENT("Set MMU context complete (MMU Context ID == %u)", psMMUContext->ui32PDumpMMUContextID); -+#endif -+ -+#if defined(FIX_HW_BRN_31620) -+ for(i=0;i<BRN31620_CACHE_FLUSH_INDEX_SIZE;i++) -+ { -+ psMMUContext->ui32PDChangeMask[i] = 0; -+ } -+ -+ for(i=0;i<BRN31620_CACHE_FLUSH_SIZE;i++) -+ { -+ psMMUContext->ui32PDCacheRangeRefCount[i] = 0; -+ } -+ -+ for(i=0;i<SGX_MAX_PD_ENTRIES;i++) -+ { -+ psMMUContext->apsPTInfoListSave[i] = IMG_NULL; -+ } -+#endif -+ /* store PD info in the MMU context */ -+ psMMUContext->pvPDCpuVAddr = pvPDCpuVAddr; -+ psMMUContext->sPDDevPAddr = sPDDevPAddr; -+ psMMUContext->hPDOSMemHandle = hPDOSMemHandle; -+ -+ /* Get some process information to aid debug */ -+ psMMUContext->ui32PID = OSGetCurrentProcessIDKM(); -+ psMMUContext->szName[0] = '\0'; -+ OSGetCurrentProcessNameKM(psMMUContext->szName, MMU_CONTEXT_NAME_SIZE); -+ -+ /* return context */ -+ *ppsMMUContext = psMMUContext; -+ -+ /* return the PD DevVAddr */ -+ *psPDDevPAddr = sPDDevPAddr; -+ -+ -+ /* add the new MMU context onto the list of MMU contexts */ -+ psMMUContext->psNext = (MMU_CONTEXT*)psDevInfo->pvMMUContextList; -+ psDevInfo->pvMMUContextList = (IMG_VOID*)psMMUContext; -+ -+#ifdef SUPPORT_SGX_MMU_BYPASS -+ DisableHostAccess(psMMUContext); -+#endif -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ FUNCTION: MMU_Finalise -+ -+ PURPOSE: Finalise the mmu module, deallocate all resources. -+ -+ PARAMETERS: In: psMMUContext - MMU context to deallocate -+ RETURNS: None. -+******************************************************************************/ -+IMG_VOID -+MMU_Finalise (MMU_CONTEXT *psMMUContext) -+{ -+ IMG_UINT32 *pui32Tmp, i; -+ SYS_DATA *psSysData; -+ MMU_CONTEXT **ppsMMUContext; -+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) || defined(FIX_HW_BRN_31620) -+ PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psMMUContext->psDevInfo; -+ MMU_CONTEXT *psMMUContextList = (MMU_CONTEXT*)psDevInfo->pvMMUContextList; -+#endif -+ -+ SysAcquireData(&psSysData); -+ -+#if defined(PDUMP) -+ /* pdump the MMU context clear */ -+ PDUMPCOMMENT("Clear MMU context (MMU Context ID == %u)", psMMUContext->ui32PDumpMMUContextID); -+ PDUMPCLEARMMUCONTEXT(PVRSRV_DEVICE_TYPE_SGX, psMMUContext->psDeviceNode->sDevId.pszPDumpDevName, psMMUContext->ui32PDumpMMUContextID, 2); -+ -+ /* pdump the PD free */ -+ PDUMPCOMMENT("Free page directory (PDDevPAddr == 0x" DEVPADDR_FMT ")", -+ psMMUContext->sPDDevPAddr.uiAddr); -+#endif /* PDUMP */ -+ -+ PDUMPFREEPAGETABLE(&psMMUContext->psDeviceNode->sDevId, psMMUContext->hPDOSMemHandle, psMMUContext->pvPDCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG); -+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) -+ PDUMPFREEPAGETABLE(&psMMUContext->psDeviceNode->sDevId, psDevInfo->hDummyPTPageOSMemHandle, psDevInfo->pvDummyPTPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG); -+ PDUMPFREEPAGETABLE(&psMMUContext->psDeviceNode->sDevId, psDevInfo->hDummyDataPageOSMemHandle, psDevInfo->pvDummyDataPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG); -+#endif -+ -+ pui32Tmp = (IMG_UINT32 *)psMMUContext->pvPDCpuVAddr; -+ -+ MakeKernelPageReadWrite(psMMUContext->pvPDCpuVAddr); -+ /* initialise the PD to invalid address state */ -+ for(i=0; i<SGX_MMU_PD_SIZE; i++) -+ { -+ /* invalid, no read, no write, no cache consistency */ -+ pui32Tmp[i] = 0; -+ } -+ MakeKernelPageReadOnly(psMMUContext->pvPDCpuVAddr); -+ -+ /* -+ free the PD: -+ depending on the specific system, the PD is allocated from system memory -+ or device local memory. For now, just look for at least a valid local heap/arena -+ */ -+ if(psMMUContext->psDeviceNode->psLocalDevMemArena == IMG_NULL) -+ { -+#if defined(FIX_HW_BRN_31620) -+ PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psMMUContext->psDevInfo; -+#endif -+ MakeKernelPageReadWrite(psMMUContext->pvPDCpuVAddr); -+ OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, -+ SGX_MMU_PAGE_SIZE, -+ psMMUContext->pvPDCpuVAddr, -+ psMMUContext->hPDOSMemHandle); -+ -+#if defined(FIX_HW_BRN_31620) -+ /* If this is the _last_ MMU context it must be the uKernel */ -+ if (!psMMUContextList->psNext) -+ { -+ PDUMPFREEPAGETABLE(&psMMUContext->psDeviceNode->sDevId, psDevInfo->hBRN31620DummyPageOSMemHandle, psDevInfo->pvBRN31620DummyPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG); -+ OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, -+ SGX_MMU_PAGE_SIZE, -+ psDevInfo->pvBRN31620DummyPageCpuVAddr, -+ psDevInfo->hBRN31620DummyPageOSMemHandle); -+ -+ PDUMPFREEPAGETABLE(&psMMUContext->psDeviceNode->sDevId, psDevInfo->hBRN31620DummyPTOSMemHandle, psDevInfo->pvBRN31620DummyPTCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG); -+ OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, -+ SGX_MMU_PAGE_SIZE, -+ psDevInfo->pvBRN31620DummyPTCpuVAddr, -+ psDevInfo->hBRN31620DummyPTOSMemHandle); -+ -+ } -+#endif -+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) -+ /* if this is the last context free the dummy pages too */ -+ if(!psMMUContextList->psNext) -+ { -+ OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, -+ SGX_MMU_PAGE_SIZE, -+ psDevInfo->pvDummyPTPageCpuVAddr, -+ psDevInfo->hDummyPTPageOSMemHandle); -+ OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, -+ SGX_MMU_PAGE_SIZE, -+ psDevInfo->pvDummyDataPageCpuVAddr, -+ psDevInfo->hDummyDataPageOSMemHandle); -+ } -+#endif -+ } -+ else -+ { -+ IMG_SYS_PHYADDR sSysPAddr; -+ IMG_CPU_PHYADDR sCpuPAddr; -+ -+ /* derive the system physical address */ -+ sCpuPAddr = OSMapLinToCPUPhys(psMMUContext->hPDOSMemHandle, -+ psMMUContext->pvPDCpuVAddr); -+ sSysPAddr = SysCpuPAddrToSysPAddr(sCpuPAddr); -+ -+ /* unmap the CPU mapping */ -+ OSUnMapPhysToLin(psMMUContext->pvPDCpuVAddr, -+ SGX_MMU_PAGE_SIZE, -+ PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY, -+ psMMUContext->hPDOSMemHandle); -+ /* and free the memory, Note that the cast to IMG_UINTPTR_T is ok as we're local mem. */ -+ RA_Free (psMMUContext->psDeviceNode->psLocalDevMemArena, (IMG_UINTPTR_T)sSysPAddr.uiAddr, IMG_FALSE); -+ -+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) -+ /* if this is the last context free the dummy pages too */ -+ if(!psMMUContextList->psNext) -+ { -+ /* free the Dummy PT Page */ -+ sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->hDummyPTPageOSMemHandle, -+ psDevInfo->pvDummyPTPageCpuVAddr); -+ sSysPAddr = SysCpuPAddrToSysPAddr(sCpuPAddr); -+ -+ /* unmap the CPU mapping */ -+ OSUnMapPhysToLin(psDevInfo->pvDummyPTPageCpuVAddr, -+ SGX_MMU_PAGE_SIZE, -+ PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY, -+ psDevInfo->hDummyPTPageOSMemHandle); -+ /* and free the memory */ -+ RA_Free (psMMUContext->psDeviceNode->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE); -+ -+ /* free the Dummy Data Page */ -+ sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->hDummyDataPageOSMemHandle, -+ psDevInfo->pvDummyDataPageCpuVAddr); -+ sSysPAddr = SysCpuPAddrToSysPAddr(sCpuPAddr); -+ -+ /* unmap the CPU mapping */ -+ OSUnMapPhysToLin(psDevInfo->pvDummyDataPageCpuVAddr, -+ SGX_MMU_PAGE_SIZE, -+ PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY, -+ psDevInfo->hDummyDataPageOSMemHandle); -+ /* and free the memory */ -+ RA_Free (psMMUContext->psDeviceNode->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE); -+ } -+#endif -+#if defined(FIX_HW_BRN_31620) -+ /* if this is the last context free the dummy pages too */ -+ if(!psMMUContextList->psNext) -+ { -+ /* free the Page */ -+ PDUMPFREEPAGETABLE(&psMMUContext->psDeviceNode->sDevId, psDevInfo->hBRN31620DummyPageOSMemHandle, psDevInfo->pvBRN31620DummyPageCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG); -+ -+ sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->hBRN31620DummyPageOSMemHandle, -+ psDevInfo->pvBRN31620DummyPageCpuVAddr); -+ sSysPAddr = SysCpuPAddrToSysPAddr(sCpuPAddr); -+ -+ /* unmap the CPU mapping */ -+ OSUnMapPhysToLin(psDevInfo->pvBRN31620DummyPageCpuVAddr, -+ SGX_MMU_PAGE_SIZE, -+ PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY, -+ psDevInfo->hBRN31620DummyPageOSMemHandle); -+ /* and free the memory */ -+ RA_Free (psMMUContext->psDeviceNode->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE); -+ -+ /* free the Dummy PT */ -+ PDUMPFREEPAGETABLE(&psMMUContext->psDeviceNode->sDevId, psDevInfo->hBRN31620DummyPTOSMemHandle, psDevInfo->pvBRN31620DummyPTCpuVAddr, SGX_MMU_PAGE_SIZE, 0, PDUMP_PT_UNIQUETAG); -+ -+ sCpuPAddr = OSMapLinToCPUPhys(psDevInfo->hBRN31620DummyPTOSMemHandle, -+ psDevInfo->pvBRN31620DummyPTCpuVAddr); -+ sSysPAddr = SysCpuPAddrToSysPAddr(sCpuPAddr); -+ -+ /* unmap the CPU mapping */ -+ OSUnMapPhysToLin(psDevInfo->pvBRN31620DummyPTCpuVAddr, -+ SGX_MMU_PAGE_SIZE, -+ PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY, -+ psDevInfo->hBRN31620DummyPTOSMemHandle); -+ /* and free the memory */ -+ RA_Free (psMMUContext->psDeviceNode->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE); -+ } -+#endif -+ } -+ -+ PVR_DPF ((PVR_DBG_MESSAGE, "MMU_Finalise")); -+ -+ /* remove the MMU context from the list of MMU contexts */ -+ ppsMMUContext = (MMU_CONTEXT**)&psMMUContext->psDevInfo->pvMMUContextList; -+ while(*ppsMMUContext) -+ { -+ if(*ppsMMUContext == psMMUContext) -+ { -+ /* remove item from the list */ -+ *ppsMMUContext = psMMUContext->psNext; -+ break; -+ } -+ -+ /* advance to next next */ -+ ppsMMUContext = &((*ppsMMUContext)->psNext); -+ } -+ -+ /* free the context itself. */ -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(MMU_CONTEXT), psMMUContext, IMG_NULL); -+ /*not nulling pointer, copy on stack*/ -+} -+ -+ -+/*! -+****************************************************************************** -+ FUNCTION: MMU_InsertHeap -+ -+ PURPOSE: Copies PDEs from shared/exported heap into current MMU context. -+ -+ PARAMETERS: In: psMMUContext - the mmu -+ In: psMMUHeap - a shared/exported heap -+ -+ RETURNS: None -+******************************************************************************/ -+IMG_VOID -+MMU_InsertHeap(MMU_CONTEXT *psMMUContext, MMU_HEAP *psMMUHeap) -+{ -+ IMG_UINT32 *pui32PDCpuVAddr = (IMG_UINT32 *) psMMUContext->pvPDCpuVAddr; -+ IMG_UINT32 *pui32KernelPDCpuVAddr = (IMG_UINT32 *) psMMUHeap->psMMUContext->pvPDCpuVAddr; -+ IMG_UINT32 ui32PDEntry; -+#if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) -+ IMG_BOOL bInvalidateDirectoryCache = IMG_FALSE; -+#endif -+ -+ /* advance to the first entry */ -+ pui32PDCpuVAddr += psMMUHeap->psDevArena->BaseDevVAddr.uiAddr >> psMMUHeap->ui32PDShift; -+ pui32KernelPDCpuVAddr += psMMUHeap->psDevArena->BaseDevVAddr.uiAddr >> psMMUHeap->ui32PDShift; -+ -+ /* -+ update the PD range relating to the heap's -+ device virtual address range -+ */ -+#if defined(PDUMP) -+ PDUMPCOMMENT("Page directory shared heap range copy"); -+ PDUMPCOMMENT(" (Source heap MMU Context ID == %u, PT count == 0x%x)", -+ psMMUHeap->psMMUContext->ui32PDumpMMUContextID, -+ psMMUHeap->ui32PageTableCount); -+ PDUMPCOMMENT(" (Destination MMU Context ID == %u)", psMMUContext->ui32PDumpMMUContextID); -+#endif /* PDUMP */ -+#ifdef SUPPORT_SGX_MMU_BYPASS -+ EnableHostAccess(psMMUContext); -+#endif -+ -+ for (ui32PDEntry = 0; ui32PDEntry < psMMUHeap->ui32PageTableCount; ui32PDEntry++) -+ { -+#if (!defined(SUPPORT_SGX_MMU_DUMMY_PAGE)) && (!defined(FIX_HW_BRN_31620)) -+ /* check we have invalidated target PDEs */ -+ PVR_ASSERT(pui32PDCpuVAddr[ui32PDEntry] == 0); -+#endif -+ MakeKernelPageReadWrite(psMMUContext->pvPDCpuVAddr); -+ /* copy over the PDEs */ -+ pui32PDCpuVAddr[ui32PDEntry] = pui32KernelPDCpuVAddr[ui32PDEntry]; -+ MakeKernelPageReadOnly(psMMUContext->pvPDCpuVAddr); -+ if (pui32PDCpuVAddr[ui32PDEntry]) -+ { -+ /* Ensure the shared heap allocation is mapped into the context/PD -+ * for the active pdump process/app. The PTs and backing physical -+ * should also be pdumped (elsewhere). -+ * MALLOC (PT) -+ * LDB (init PT) -+ * MALLOC (data page) -+ * WRW (PTE->data page) -+ * LDB (init data page) -- could be useful to ensure page is initialised -+ */ -+ #if defined(PDUMP) -+ //PDUMPCOMMENT("MMU_InsertHeap: Mapping shared heap to new context %d (%s)", psMMUContext->ui32PDumpMMUContextID, (psMMUContext->bPDumpActive) ? "active" : ""); -+ #if defined(SUPPORT_PDUMP_MULTI_PROCESS) -+ if(psMMUContext->bPDumpActive) -+ #endif /* SUPPORT_PDUMP_MULTI_PROCESS */ -+ { -+ PDUMPPDENTRIES(&psMMUHeap->sMMUAttrib, psMMUContext->hPDOSMemHandle, (IMG_VOID *) &pui32PDCpuVAddr[ui32PDEntry], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG); -+ } -+ #endif -+#if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) -+ bInvalidateDirectoryCache = IMG_TRUE; -+#endif -+ } -+ } -+ -+#ifdef SUPPORT_SGX_MMU_BYPASS -+ DisableHostAccess(psMMUContext); -+#endif -+ -+#if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) -+ if (bInvalidateDirectoryCache) -+ { -+ /* This is actually not to do with multiple mem contexts, but to do with the directory cache. -+ In the 1 context implementation of the MMU, the directory "cache" is actually a copy of the -+ page directory memory, and requires updating whenever the page directory changes, even if there -+ was no previous value in a particular entry -+ */ -+ MMU_InvalidateDirectoryCache(psMMUContext->psDevInfo); -+ } -+#endif -+} -+ -+ -+/*! -+****************************************************************************** -+ FUNCTION: MMU_UnmapPagesAndFreePTs -+ -+ PURPOSE: unmap pages, invalidate virtual address and try to free the PTs -+ -+ PARAMETERS: In: psMMUHeap - the mmu. -+ In: sDevVAddr - the device virtual address. -+ In: ui32PageCount - page count -+ In: hUniqueTag - A unique ID for use as a tag identifier -+ -+ RETURNS: None -+******************************************************************************/ -+static IMG_VOID -+MMU_UnmapPagesAndFreePTs (MMU_HEAP *psMMUHeap, -+ IMG_DEV_VIRTADDR sDevVAddr, -+ IMG_UINT32 ui32PageCount, -+ IMG_HANDLE hUniqueTag) -+{ -+ IMG_DEV_VIRTADDR sTmpDevVAddr; -+ IMG_UINT32 i; -+ IMG_UINT32 ui32PDIndex; -+ IMG_UINT32 ui32PTIndex; -+ IMG_UINT32 *pui32Tmp; -+ IMG_BOOL bInvalidateDirectoryCache = IMG_FALSE; -+ -+#if !defined (PDUMP) -+ PVR_UNREFERENCED_PARAMETER(hUniqueTag); -+#endif -+ /* setup tmp devvaddr to base of allocation */ -+ sTmpDevVAddr = sDevVAddr; -+ -+ for(i=0; i<ui32PageCount; i++) -+ { -+ MMU_PT_INFO **ppsPTInfoList; -+ -+ /* find the index/offset in PD entries */ -+ ui32PDIndex = sTmpDevVAddr.uiAddr >> psMMUHeap->ui32PDShift; -+ -+ /* and advance to the first PT info list */ -+ ppsPTInfoList = &psMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex]; -+ -+ { -+ /* find the index/offset of the first PT in the first PT page */ -+ ui32PTIndex = (sTmpDevVAddr.uiAddr & psMMUHeap->ui32PTMask) >> psMMUHeap->ui32PTShift; -+ -+ /* Is the PT page valid? */ -+ if (!ppsPTInfoList[0]) -+ { -+ /* -+ With sparse mappings we expect that the PT could be freed -+ before we reach the end of it as the unmapped pages don't -+ bump ui32ValidPTECount so it can reach zero before we reach -+ the end of the PT. -+ */ -+ if (!psMMUHeap->bHasSparseMappings) -+ { -+ PVR_DPF((PVR_DBG_MESSAGE, "MMU_UnmapPagesAndFreePTs: Invalid PT for alloc at VAddr:0x%08X (VaddrIni:0x%08X AllocPage:%u) PDIdx:%u PTIdx:%u",sTmpDevVAddr.uiAddr, sDevVAddr.uiAddr,i, ui32PDIndex, ui32PTIndex )); -+ } -+ -+ /* advance the sTmpDevVAddr by one page */ -+ sTmpDevVAddr.uiAddr += psMMUHeap->ui32DataPageSize; -+ -+ /* Try to unmap the remaining allocation pages */ -+ continue; -+ } -+ -+ /* setup pointer to the first entry in the PT page */ -+ pui32Tmp = (IMG_UINT32*)ppsPTInfoList[0]->PTPageCpuVAddr; -+ -+ /* Is PTPageCpuVAddr valid ? */ -+ if (!pui32Tmp) -+ { -+ continue; -+ } -+ -+ CheckPT(ppsPTInfoList[0]); -+ -+ /* Decrement the valid page count only if the current page is valid*/ -+ if (pui32Tmp[ui32PTIndex] & SGX_MMU_PTE_VALID) -+ { -+ ppsPTInfoList[0]->ui32ValidPTECount--; -+ } -+ else -+ { -+ if (!psMMUHeap->bHasSparseMappings) -+ { -+ PVR_DPF((PVR_DBG_MESSAGE, "MMU_UnmapPagesAndFreePTs: Page is already invalid for alloc at VAddr:0x%08X (VAddrIni:0x%08X AllocPage:%u) PDIdx:%u PTIdx:%u",sTmpDevVAddr.uiAddr, sDevVAddr.uiAddr,i, ui32PDIndex, ui32PTIndex )); -+ } -+ } -+ -+ /* The page table count should not go below zero */ -+ PVR_ASSERT((IMG_INT32)ppsPTInfoList[0]->ui32ValidPTECount >= 0); -+ MakeKernelPageReadWrite(ppsPTInfoList[0]->PTPageCpuVAddr); -+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) -+ /* point the PT entry to the dummy data page */ -+ pui32Tmp[ui32PTIndex] = (psMMUHeap->psMMUContext->psDevInfo->sDummyDataDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT) -+ | SGX_MMU_PTE_VALID; -+#else -+ /* invalidate entry */ -+#if defined(FIX_HW_BRN_31620) -+ BRN31620InvalidatePageTableEntry(psMMUHeap->psMMUContext, ui32PDIndex, ui32PTIndex, &pui32Tmp[ui32PTIndex]); -+#else -+ pui32Tmp[ui32PTIndex] = 0; -+#endif -+#endif -+ MakeKernelPageReadOnly(ppsPTInfoList[0]->PTPageCpuVAddr); -+ CheckPT(ppsPTInfoList[0]); -+ } -+ -+ /* -+ Free a page table if we can. -+ */ -+ if (ppsPTInfoList[0] && (ppsPTInfoList[0]->ui32ValidPTECount == 0) -+ ) -+ { -+#if defined(FIX_HW_BRN_31620) -+ if (BRN31620FreePageTable(psMMUHeap, ui32PDIndex) == IMG_TRUE) -+ { -+ bInvalidateDirectoryCache = IMG_TRUE; -+ } -+#else -+ _DeferredFreePageTable(psMMUHeap, ui32PDIndex - psMMUHeap->ui32PDBaseIndex, IMG_TRUE); -+ bInvalidateDirectoryCache = IMG_TRUE; -+#endif -+ } -+ -+ /* advance the sTmpDevVAddr by one page */ -+ sTmpDevVAddr.uiAddr += psMMUHeap->ui32DataPageSize; -+ } -+ -+ if(bInvalidateDirectoryCache) -+ { -+ MMU_InvalidateDirectoryCache(psMMUHeap->psMMUContext->psDevInfo); -+ } -+ else -+ { -+ MMU_InvalidatePageTableCache(psMMUHeap->psMMUContext->psDevInfo); -+ } -+ -+#if defined(PDUMP) -+ MMU_PDumpPageTables(psMMUHeap, -+ sDevVAddr, -+ psMMUHeap->ui32DataPageSize * ui32PageCount, -+ IMG_TRUE, -+ hUniqueTag); -+#endif /* #if defined(PDUMP) */ -+} -+ -+ -+/*! -+****************************************************************************** -+ FUNCTION: MMU_FreePageTables -+ -+ PURPOSE: Call back from RA_Free to zero page table entries used by freed -+ spans. -+ -+ PARAMETERS: In: pvMMUHeap -+ In: ui32Start -+ In: ui32End -+ In: hUniqueTag - A unique ID for use as a tag identifier -+ RETURNS: -+******************************************************************************/ -+static IMG_VOID MMU_FreePageTables(IMG_PVOID pvMMUHeap, -+ IMG_SIZE_T uStart, -+ IMG_SIZE_T uEnd, -+ IMG_HANDLE hUniqueTag) -+{ -+ MMU_HEAP *pMMUHeap = (MMU_HEAP*)pvMMUHeap; -+ IMG_DEV_VIRTADDR Start; -+ -+ Start.uiAddr = (IMG_UINT32)uStart; -+ -+ MMU_UnmapPagesAndFreePTs(pMMUHeap, Start, (IMG_UINT32)((uEnd - uStart) >> pMMUHeap->ui32PTShift), hUniqueTag); -+} -+ -+/*! -+****************************************************************************** -+ FUNCTION: MMU_Create -+ -+ PURPOSE: Create an mmu device virtual heap. -+ -+ PARAMETERS: In: psMMUContext - MMU context -+ In: psDevArena - device memory resource arena -+ Out: ppsVMArena - virtual mapping arena -+ RETURNS: MMU_HEAP -+ RETURNS: -+******************************************************************************/ -+MMU_HEAP * -+MMU_Create (MMU_CONTEXT *psMMUContext, -+ DEV_ARENA_DESCRIPTOR *psDevArena, -+ RA_ARENA **ppsVMArena, -+ PDUMP_MMU_ATTRIB **ppsMMUAttrib) -+{ -+ MMU_HEAP *pMMUHeap; -+ IMG_UINT32 ui32ScaleSize; -+ -+ PVR_UNREFERENCED_PARAMETER(ppsMMUAttrib); -+ -+ PVR_ASSERT (psDevArena != IMG_NULL); -+ -+ if (psDevArena == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "MMU_Create: invalid parameter")); -+ return IMG_NULL; -+ } -+ -+ OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof (MMU_HEAP), -+ (IMG_VOID **)&pMMUHeap, IMG_NULL, -+ "MMU Heap"); -+ if (pMMUHeap == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "MMU_Create: ERROR call to OSAllocMem failed")); -+ return IMG_NULL; -+ } -+ -+ pMMUHeap->psMMUContext = psMMUContext; -+ pMMUHeap->psDevArena = psDevArena; -+ -+ /* -+ generate page table and data page mask and shift values -+ based on the data page size -+ */ -+ switch(pMMUHeap->psDevArena->ui32DataPageSize) -+ { -+ case 0x1000: -+ ui32ScaleSize = 0; -+ pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_4K; -+ break; -+#if defined(SGX_FEATURE_VARIABLE_MMU_PAGE_SIZE) -+ case 0x4000: -+ ui32ScaleSize = 2; -+ pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_16K; -+ break; -+ case 0x10000: -+ ui32ScaleSize = 4; -+ pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_64K; -+ break; -+ case 0x40000: -+ ui32ScaleSize = 6; -+ pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_256K; -+ break; -+ case 0x100000: -+ ui32ScaleSize = 8; -+ pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_1M; -+ break; -+ case 0x400000: -+ ui32ScaleSize = 10; -+ pMMUHeap->ui32PDEPageSizeCtrl = SGX_MMU_PDE_PAGE_SIZE_4M; -+ break; -+#endif /* #if defined(SGX_FEATURE_VARIABLE_MMU_PAGE_SIZE) */ -+ default: -+ PVR_DPF((PVR_DBG_ERROR, "MMU_Create: invalid data page size")); -+ goto ErrorFreeHeap; -+ } -+ -+ /* number of bits of address offset into the data page */ -+ pMMUHeap->ui32DataPageSize = psDevArena->ui32DataPageSize; -+ pMMUHeap->ui32DataPageBitWidth = SGX_MMU_PAGE_SHIFT + ui32ScaleSize; -+ pMMUHeap->ui32DataPageMask = pMMUHeap->ui32DataPageSize - 1; -+ /* number of bits of address indexing into a pagetable */ -+ pMMUHeap->ui32PTShift = pMMUHeap->ui32DataPageBitWidth; -+ pMMUHeap->ui32PTBitWidth = SGX_MMU_PT_SHIFT - ui32ScaleSize; -+ pMMUHeap->ui32PTMask = SGX_MMU_PT_MASK & (SGX_MMU_PT_MASK<<ui32ScaleSize); -+ pMMUHeap->ui32PTSize = (IMG_UINT32)(1UL<<pMMUHeap->ui32PTBitWidth) * sizeof(IMG_UINT32); -+ -+ /* note: PT size must be at least 4 entries, even for 4Mb data page size */ -+ if(pMMUHeap->ui32PTSize < 4 * sizeof(IMG_UINT32)) -+ { -+ pMMUHeap->ui32PTSize = 4 * sizeof(IMG_UINT32); -+ } -+ pMMUHeap->ui32PTNumEntriesAllocated = pMMUHeap->ui32PTSize >> 2; -+ -+ /* find the number of actual PT entries per PD entry range. For 4MB data -+ * pages we only use the first entry although the PT has 16 byte allocation/alignment -+ * (due to 4 LSbits of the PDE are reserved for control) */ -+ pMMUHeap->ui32PTNumEntriesUsable = (IMG_UINT32)(1UL << pMMUHeap->ui32PTBitWidth); -+ -+ /* number of bits of address indexing into a page directory */ -+ pMMUHeap->ui32PDShift = pMMUHeap->ui32PTBitWidth + pMMUHeap->ui32PTShift; -+ pMMUHeap->ui32PDBitWidth = SGX_FEATURE_ADDRESS_SPACE_SIZE - pMMUHeap->ui32PTBitWidth - pMMUHeap->ui32DataPageBitWidth; -+ pMMUHeap->ui32PDMask = SGX_MMU_PD_MASK & (SGX_MMU_PD_MASK>>(32-SGX_FEATURE_ADDRESS_SPACE_SIZE)); -+ -+ /* External system cache violates this rule */ -+#if !defined (SUPPORT_EXTERNAL_SYSTEM_CACHE) -+ /* -+ The heap must start on a PT boundary to avoid PT sharing across heaps -+ The only exception is the first heap which can start at any address -+ from 0 to the end of the first PT boundary -+ */ -+ if(psDevArena->BaseDevVAddr.uiAddr > (pMMUHeap->ui32DataPageMask | pMMUHeap->ui32PTMask)) -+ { -+ /* -+ if for some reason the first heap starts after the end of the first PT boundary -+ but is not aligned to a PT boundary then the assert will trigger unncessarily -+ */ -+ PVR_ASSERT ((psDevArena->BaseDevVAddr.uiAddr -+ & (pMMUHeap->ui32DataPageMask -+ | pMMUHeap->ui32PTMask)) == 0); -+ } -+#endif -+ /* how many PT entries do we need? */ -+ pMMUHeap->ui32PTETotalUsable = pMMUHeap->psDevArena->ui32Size >> pMMUHeap->ui32PTShift; -+ -+ /* calculate the PD Base index for the Heap (required for page mapping) */ -+ pMMUHeap->ui32PDBaseIndex = (pMMUHeap->psDevArena->BaseDevVAddr.uiAddr & pMMUHeap->ui32PDMask) >> pMMUHeap->ui32PDShift; -+ -+ /* -+ how many page tables? -+ round up to nearest entries to the nearest page table sized block -+ */ -+ pMMUHeap->ui32PageTableCount = (pMMUHeap->ui32PTETotalUsable + pMMUHeap->ui32PTNumEntriesUsable - 1) -+ >> pMMUHeap->ui32PTBitWidth; -+ PVR_ASSERT(pMMUHeap->ui32PageTableCount > 0); -+ -+ /* Create the arena */ -+ pMMUHeap->psVMArena = RA_Create(psDevArena->pszName, -+ psDevArena->BaseDevVAddr.uiAddr, -+ psDevArena->ui32Size, -+ IMG_NULL, -+ MAX(HOST_PAGESIZE(), pMMUHeap->ui32DataPageSize), -+ IMG_NULL, -+ IMG_NULL, -+ &MMU_FreePageTables, -+ pMMUHeap); -+ -+ if (pMMUHeap->psVMArena == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "MMU_Create: ERROR call to RA_Create failed")); -+ goto ErrorFreePagetables; -+ } -+ -+#if defined(PDUMP) -+ /* setup per-heap PDUMP MMU attributes */ -+ MMU_SetPDumpAttribs(&pMMUHeap->sMMUAttrib, -+ psMMUContext->psDeviceNode, -+ pMMUHeap->ui32DataPageMask, -+ pMMUHeap->ui32PTSize); -+ *ppsMMUAttrib = &pMMUHeap->sMMUAttrib; -+ -+ PDUMPCOMMENT("Create MMU device from arena %s (Size == 0x%x, DataPageSize == 0x%x, BaseDevVAddr == 0x%x)", -+ psDevArena->pszName, -+ psDevArena->ui32Size, -+ pMMUHeap->ui32DataPageSize, -+ psDevArena->BaseDevVAddr.uiAddr); -+#endif /* PDUMP */ -+ -+ /* -+ And return the RA for VM arena management -+ */ -+ *ppsVMArena = pMMUHeap->psVMArena; -+ -+ return pMMUHeap; -+ -+ /* drop into here if errors */ -+ErrorFreePagetables: -+ _DeferredFreePageTables (pMMUHeap); -+ -+ErrorFreeHeap: -+ OSFreeMem (PVRSRV_OS_PAGEABLE_HEAP, sizeof(MMU_HEAP), pMMUHeap, IMG_NULL); -+ /*not nulling pointer, out of scope*/ -+ -+ return IMG_NULL; -+} -+ -+/*! -+****************************************************************************** -+ FUNCTION: MMU_Delete -+ -+ PURPOSE: Delete an MMU device virtual heap. -+ -+ PARAMETERS: In: pMMUHeap - The MMU heap to delete. -+ RETURNS: -+******************************************************************************/ -+IMG_VOID -+MMU_Delete (MMU_HEAP *pMMUHeap) -+{ -+ if (pMMUHeap != IMG_NULL) -+ { -+ PVR_DPF ((PVR_DBG_MESSAGE, "MMU_Delete")); -+ -+ if(pMMUHeap->psVMArena) -+ { -+ RA_Delete (pMMUHeap->psVMArena); -+ } -+ -+#if defined(PDUMP) -+ PDUMPCOMMENT("Delete MMU device from arena %s (BaseDevVAddr == 0x%x, PT count for deferred free == 0x%x)", -+ pMMUHeap->psDevArena->pszName, -+ pMMUHeap->psDevArena->BaseDevVAddr.uiAddr, -+ pMMUHeap->ui32PageTableCount); -+#endif /* PDUMP */ -+ -+#ifdef SUPPORT_SGX_MMU_BYPASS -+ EnableHostAccess(pMMUHeap->psMMUContext); -+#endif -+ _DeferredFreePageTables (pMMUHeap); -+#ifdef SUPPORT_SGX_MMU_BYPASS -+ DisableHostAccess(pMMUHeap->psMMUContext); -+#endif -+ -+ OSFreeMem (PVRSRV_OS_PAGEABLE_HEAP, sizeof(MMU_HEAP), pMMUHeap, IMG_NULL); -+ /*not nulling pointer, copy on stack*/ -+ } -+} -+ -+/*! -+****************************************************************************** -+ FUNCTION: MMU_Alloc -+ PURPOSE: Allocate space in an mmu's virtual address space. -+ PARAMETERS: In: pMMUHeap - MMU to allocate on. -+ In: uSize - Size in bytes to allocate. -+ Out: pActualSize - If non null receives actual size allocated. -+ In: uFlags - Allocation flags. -+ In: uDevVAddrAlignment - Required alignment. -+ Out: DevVAddr - Receives base address of allocation. -+ RETURNS: IMG_TRUE - Success -+ IMG_FALSE - Failure -+******************************************************************************/ -+IMG_BOOL -+MMU_Alloc (MMU_HEAP *pMMUHeap, -+ IMG_SIZE_T uSize, -+ IMG_SIZE_T *pActualSize, -+ IMG_UINT32 uFlags, -+ IMG_UINT32 uDevVAddrAlignment, -+ IMG_DEV_VIRTADDR *psDevVAddr) -+{ -+ IMG_BOOL bStatus; -+ -+ PVR_DPF ((PVR_DBG_MESSAGE, -+ "MMU_Alloc: uSize=0x%" SIZE_T_FMT_LEN "x, flags=0x%x, align=0x%x", -+ uSize, uFlags, uDevVAddrAlignment)); -+ -+ /* -+ Only allocate a VM address if the caller did not supply one -+ */ -+ if((uFlags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR) == 0) -+ { -+ IMG_UINTPTR_T uiAddr; -+ -+ bStatus = RA_Alloc (pMMUHeap->psVMArena, -+ uSize, -+ pActualSize, -+ IMG_NULL, -+ 0, -+ uDevVAddrAlignment, -+ 0, -+ IMG_NULL, -+ 0, -+ &uiAddr); -+ if(!bStatus) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"MMU_Alloc: RA_Alloc of VMArena failed")); -+ PVR_DPF((PVR_DBG_ERROR,"MMU_Alloc: Alloc of DevVAddr failed from heap %s ID%d", -+ pMMUHeap->psDevArena->pszName, -+ pMMUHeap->psDevArena->ui32HeapID)); -+ return bStatus; -+ } -+ -+ psDevVAddr->uiAddr = IMG_CAST_TO_DEVVADDR_UINT(uiAddr); -+ } -+ -+ #ifdef SUPPORT_SGX_MMU_BYPASS -+ EnableHostAccess(pMMUHeap->psMMUContext); -+ #endif -+ -+ /* allocate page tables to cover allocation as required */ -+ bStatus = _DeferredAllocPagetables(pMMUHeap, *psDevVAddr, (IMG_UINT32)uSize); -+ -+ #ifdef SUPPORT_SGX_MMU_BYPASS -+ DisableHostAccess(pMMUHeap->psMMUContext); -+ #endif -+ -+ if (!bStatus) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"MMU_Alloc: _DeferredAllocPagetables failed")); -+ PVR_DPF((PVR_DBG_ERROR,"MMU_Alloc: Failed to alloc pagetable(s) for DevVAddr 0x%8.8x from heap %s ID%d", -+ psDevVAddr->uiAddr, -+ pMMUHeap->psDevArena->pszName, -+ pMMUHeap->psDevArena->ui32HeapID)); -+ if((uFlags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR) == 0) -+ { -+ /* free the VM address */ -+ RA_Free (pMMUHeap->psVMArena, psDevVAddr->uiAddr, IMG_FALSE); -+ } -+ } -+ -+ return bStatus; -+} -+ -+/*! -+****************************************************************************** -+ FUNCTION: MMU_Free -+ PURPOSE: Free space in an mmu's virtual address space. -+ PARAMETERS: In: pMMUHeap - MMU to deallocate on. -+ In: DevVAddr - Base address to deallocate. -+ RETURNS: None -+******************************************************************************/ -+IMG_VOID -+MMU_Free (MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR DevVAddr, IMG_UINT32 ui32Size) -+{ -+ PVR_ASSERT (pMMUHeap != IMG_NULL); -+ -+ if (pMMUHeap == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "MMU_Free: invalid parameter")); -+ return; -+ } -+ -+ PVR_DPF((PVR_DBG_MESSAGE, "MMU_Free: Freeing DevVAddr 0x%08X from heap %s ID%d", -+ DevVAddr.uiAddr, -+ pMMUHeap->psDevArena->pszName, -+ pMMUHeap->psDevArena->ui32HeapID)); -+ -+ if((DevVAddr.uiAddr >= pMMUHeap->psDevArena->BaseDevVAddr.uiAddr) && -+ (DevVAddr.uiAddr + ui32Size <= pMMUHeap->psDevArena->BaseDevVAddr.uiAddr + pMMUHeap->psDevArena->ui32Size)) -+ { -+ RA_Free (pMMUHeap->psVMArena, DevVAddr.uiAddr, IMG_TRUE); -+ return; -+ } -+ -+ PVR_DPF((PVR_DBG_ERROR,"MMU_Free: Couldn't free DevVAddr %08X from heap %s ID%d (not in range of heap))", -+ DevVAddr.uiAddr, -+ pMMUHeap->psDevArena->pszName, -+ pMMUHeap->psDevArena->ui32HeapID)); -+} -+ -+/*! -+****************************************************************************** -+ FUNCTION: MMU_Enable -+ -+ PURPOSE: Enable an mmu. Establishes pages tables and takes the mmu out -+ of bypass and waits for the mmu to acknowledge enabled. -+ -+ PARAMETERS: In: pMMUHeap - the mmu -+ RETURNS: None -+******************************************************************************/ -+IMG_VOID -+MMU_Enable (MMU_HEAP *pMMUHeap) -+{ -+ PVR_UNREFERENCED_PARAMETER(pMMUHeap); -+ /* SGX mmu is always enabled (stub function) */ -+} -+ -+/*! -+****************************************************************************** -+ FUNCTION: MMU_Disable -+ -+ PURPOSE: Disable an mmu, takes the mmu into bypass. -+ -+ PARAMETERS: In: pMMUHeap - the mmu -+ RETURNS: None -+******************************************************************************/ -+IMG_VOID -+MMU_Disable (MMU_HEAP *pMMUHeap) -+{ -+ PVR_UNREFERENCED_PARAMETER(pMMUHeap); -+ /* SGX mmu is always enabled (stub function) */ -+} -+ -+#if defined(FIX_HW_BRN_31620) -+/*! -+****************************************************************************** -+ FUNCTION: MMU_GetCacheFlushRange -+ -+ PURPOSE: Gets device physical address of the mmu context. -+ -+ PARAMETERS: In: pMMUContext - the mmu context -+ Out: pui32RangeMask - Bit mask showing which PD cache -+ lines have changed -+ RETURNS: None -+******************************************************************************/ -+ -+IMG_VOID MMU_GetCacheFlushRange(MMU_CONTEXT *pMMUContext, IMG_UINT32 *pui32RangeMask) -+{ -+ IMG_UINT32 i; -+ -+ for (i=0;i<BRN31620_CACHE_FLUSH_INDEX_SIZE;i++) -+ { -+ pui32RangeMask[i] = pMMUContext->ui32PDChangeMask[i]; -+ -+ /* Clear bit mask for the next set of allocations */ -+ pMMUContext->ui32PDChangeMask[i] = 0; -+ } -+} -+ -+/*! -+****************************************************************************** -+ FUNCTION: MMU_GetPDPhysAddr -+ -+ PURPOSE: Gets device physical address of the mmu contexts PD. -+ -+ PARAMETERS: In: pMMUContext - the mmu context -+ Out: psDevPAddr - Address of PD -+ RETURNS: None -+******************************************************************************/ -+ -+IMG_VOID MMU_GetPDPhysAddr(MMU_CONTEXT *pMMUContext, IMG_DEV_PHYADDR *psDevPAddr) -+{ -+ *psDevPAddr = pMMUContext->sPDDevPAddr; -+} -+ -+#endif -+#if defined(PDUMP) -+/*! -+****************************************************************************** -+ FUNCTION: MMU_PDumpPageTables -+ -+ PURPOSE: PDump the linear mapping for a range of pages at a specified -+ virtual address. -+ -+ PARAMETERS: In: pMMUHeap - the mmu. -+ In: DevVAddr - the device virtual address. -+ In: uSize - size of memory range in bytes -+ In: hUniqueTag - A unique ID for use as a tag identifier -+ RETURNS: None -+******************************************************************************/ -+static IMG_VOID -+MMU_PDumpPageTables (MMU_HEAP *pMMUHeap, -+ IMG_DEV_VIRTADDR DevVAddr, -+ IMG_SIZE_T uSize, -+ IMG_BOOL bForUnmap, -+ IMG_HANDLE hUniqueTag) -+{ -+ IMG_UINT32 ui32NumPTEntries; -+ IMG_UINT32 ui32PTIndex; -+ IMG_UINT32 *pui32PTEntry; -+ -+ MMU_PT_INFO **ppsPTInfoList; -+ IMG_UINT32 ui32PDIndex; -+ IMG_UINT32 ui32PTDumpCount; -+ -+#if defined(FIX_HW_BRN_31620) -+ PVRSRV_SGXDEV_INFO *psDevInfo = pMMUHeap->psMMUContext->psDevInfo; -+#endif -+ /* find number of PT entries to dump */ -+ ui32NumPTEntries = (IMG_UINT32)((uSize + pMMUHeap->ui32DataPageMask) >> pMMUHeap->ui32PTShift); -+ -+ /* find the index/offset in PD entries */ -+ ui32PDIndex = DevVAddr.uiAddr >> pMMUHeap->ui32PDShift; -+ -+ /* set the base PT info */ -+ ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex]; -+ -+ /* find the index/offset of the first PT entry in the first PT page */ -+ ui32PTIndex = (DevVAddr.uiAddr & pMMUHeap->ui32PTMask) >> pMMUHeap->ui32PTShift; -+ -+ /* pdump the PT Page modification */ -+ PDUMPCOMMENT("Page table mods (num entries == %08X) %s", ui32NumPTEntries, bForUnmap ? "(for unmap)" : ""); -+ -+ /* walk the PT pages, dumping as we go */ -+ while(ui32NumPTEntries > 0) -+ { -+ MMU_PT_INFO* psPTInfo = *ppsPTInfoList++; -+ -+ if(ui32NumPTEntries <= pMMUHeap->ui32PTNumEntriesUsable - ui32PTIndex) -+ { -+ ui32PTDumpCount = ui32NumPTEntries; -+ } -+ else -+ { -+ ui32PTDumpCount = pMMUHeap->ui32PTNumEntriesUsable - ui32PTIndex; -+ } -+ -+ if (psPTInfo) -+ { -+#if defined(FIX_HW_BRN_31620) -+ IMG_UINT32 i; -+#endif -+ IMG_UINT32 ui32Flags = 0; -+#if defined(SUPPORT_PDUMP_MULTI_PROCESS) -+ ui32Flags |= ( MMU_IsHeapShared(pMMUHeap) ) ? PDUMP_FLAGS_PERSISTENT : 0; -+#endif -+ pui32PTEntry = (IMG_UINT32*)psPTInfo->PTPageCpuVAddr; -+#if defined(FIX_HW_BRN_31620) -+ if ((ui32PDIndex % (BRN31620_PDE_CACHE_FILL_SIZE/BRN31620_PT_ADDRESS_RANGE_SIZE)) == BRN31620_DUMMY_PDE_INDEX) -+ { -+ for (i=ui32PTIndex;i<(ui32PTIndex + ui32PTDumpCount);i++) -+ { -+ if (pui32PTEntry[i] == ((psDevInfo->sBRN31620DummyPageDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT) -+ | SGX_MMU_PTE_DUMMY_PAGE -+ | SGX_MMU_PTE_READONLY -+ | SGX_MMU_PTE_VALID)) -+ { -+ PDUMPMEMPTENTRIES(&pMMUHeap->sMMUAttrib, psPTInfo->hPTPageOSMemHandle, (IMG_VOID *) &pui32PTEntry[i], sizeof(IMG_UINT32), ui32Flags, IMG_FALSE, PDUMP_PT_UNIQUETAG, PDUMP_PD_UNIQUETAG); -+ } -+ else -+ { -+ PDUMPMEMPTENTRIES(&pMMUHeap->sMMUAttrib, psPTInfo->hPTPageOSMemHandle, (IMG_VOID *) &pui32PTEntry[i], sizeof(IMG_UINT32), ui32Flags, IMG_FALSE, PDUMP_PT_UNIQUETAG, hUniqueTag); -+ } -+ } -+ } -+ else -+#endif -+ { -+ PDUMPMEMPTENTRIES(&pMMUHeap->sMMUAttrib, psPTInfo->hPTPageOSMemHandle, (IMG_VOID *) &pui32PTEntry[ui32PTIndex], ui32PTDumpCount * sizeof(IMG_UINT32), ui32Flags, IMG_FALSE, PDUMP_PT_UNIQUETAG, hUniqueTag); -+ } -+ } -+ -+ /* decrement PT entries left */ -+ ui32NumPTEntries -= ui32PTDumpCount; -+ -+ /* reset offset in page */ -+ ui32PTIndex = 0; -+ -+#if defined(FIX_HW_BRN_31620) -+ /* For 31620 we need to know which PD index we're working on */ -+ ui32PDIndex++; -+#endif -+ } -+ -+ PDUMPCOMMENT("Finished page table mods %s", bForUnmap ? "(for unmap)" : ""); -+} -+#endif /* #if defined(PDUMP) */ -+ -+ -+/*! -+****************************************************************************** -+ FUNCTION: MMU_MapPage -+ -+ PURPOSE: Create a mapping for one page at a specified virtual address. -+ -+ PARAMETERS: In: pMMUHeap - the mmu. -+ In: DevVAddr - the device virtual address. -+ In: DevPAddr - the device physical address of the page to map. -+ In: ui32MemFlags - BM r/w/cache flags -+ RETURNS: None -+******************************************************************************/ -+static IMG_VOID -+MMU_MapPage (MMU_HEAP *pMMUHeap, -+ IMG_DEV_VIRTADDR DevVAddr, -+ IMG_DEV_PHYADDR DevPAddr, -+ IMG_UINT32 ui32MemFlags) -+{ -+ IMG_UINT32 ui32Index; -+ IMG_UINT32 *pui32Tmp; -+ IMG_UINT32 ui32MMUFlags = 0; -+ MMU_PT_INFO **ppsPTInfoList; -+ -+ /* check the physical alignment of the memory to map */ -+ PVR_ASSERT((DevPAddr.uiAddr & pMMUHeap->ui32DataPageMask) == 0); -+ -+ /* -+ unravel the read/write/cache flags -+ */ -+ if(((PVRSRV_MEM_READ|PVRSRV_MEM_WRITE) & ui32MemFlags) == (PVRSRV_MEM_READ|PVRSRV_MEM_WRITE)) -+ { -+ /* read/write */ -+ ui32MMUFlags = 0; -+ } -+ else if(PVRSRV_MEM_READ & ui32MemFlags) -+ { -+ /* read only */ -+ ui32MMUFlags |= SGX_MMU_PTE_READONLY; -+ } -+ else if(PVRSRV_MEM_WRITE & ui32MemFlags) -+ { -+ /* write only */ -+ ui32MMUFlags |= SGX_MMU_PTE_WRITEONLY; -+ } -+ -+ /* cache coherency */ -+ if(PVRSRV_MEM_CACHE_CONSISTENT & ui32MemFlags) -+ { -+ ui32MMUFlags |= SGX_MMU_PTE_CACHECONSISTENT; -+ } -+ -+#if !defined(FIX_HW_BRN_25503) -+ /* EDM protection */ -+ if(PVRSRV_MEM_EDM_PROTECT & ui32MemFlags) -+ { -+ ui32MMUFlags |= SGX_MMU_PTE_EDMPROTECT; -+ } -+#endif -+ -+ /* -+ we receive a device physical address for the page that is to be mapped -+ and a device virtual address representing where it should be mapped to -+ */ -+ -+ /* find the index/offset in PD entries */ -+ ui32Index = DevVAddr.uiAddr >> pMMUHeap->ui32PDShift; -+ -+ /* and advance to the first PT info list */ -+ ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32Index]; -+ -+ CheckPT(ppsPTInfoList[0]); -+ -+ /* find the index/offset of the first PT in the first PT page */ -+ ui32Index = (DevVAddr.uiAddr & pMMUHeap->ui32PTMask) >> pMMUHeap->ui32PTShift; -+ -+ /* setup pointer to the first entry in the PT page */ -+ pui32Tmp = (IMG_UINT32*)ppsPTInfoList[0]->PTPageCpuVAddr; -+ -+#if !defined(SUPPORT_SGX_MMU_DUMMY_PAGE) -+ { -+ IMG_UINT32 uTmp = pui32Tmp[ui32Index]; -+ -+ /* Is the current page already valid? (should not be unless it was allocated and not deallocated) */ -+#if defined(FIX_HW_BRN_31620) -+ if ((uTmp & SGX_MMU_PTE_VALID) && ((DevVAddr.uiAddr & BRN31620_PDE_CACHE_FILL_MASK) != BRN31620_DUMMY_PAGE_OFFSET)) -+#else -+ if ((uTmp & SGX_MMU_PTE_VALID) != 0) -+#endif -+ -+ { -+ PVR_DPF((PVR_DBG_ERROR, "MMU_MapPage: Page is already valid for alloc at VAddr:0x%08X PDIdx:%u PTIdx:%u", -+ DevVAddr.uiAddr, -+ DevVAddr.uiAddr >> pMMUHeap->ui32PDShift, -+ ui32Index )); -+ PVR_DPF((PVR_DBG_ERROR, "MMU_MapPage: Page table entry value: 0x%08X", uTmp)); -+ -+ PVR_DPF((PVR_DBG_ERROR, "MMU_MapPage: Physical page to map: 0x" DEVPADDR_FMT, -+ DevPAddr.uiAddr)); -+ -+#if PT_DUMP -+ DumpPT(ppsPTInfoList[0]); -+#endif -+ } -+#if !defined(FIX_HW_BRN_31620) -+ PVR_ASSERT((uTmp & SGX_MMU_PTE_VALID) == 0); -+#endif -+ } -+#endif -+ -+ /* One more valid entry in the page table. */ -+ ppsPTInfoList[0]->ui32ValidPTECount++; -+ -+ MakeKernelPageReadWrite(ppsPTInfoList[0]->PTPageCpuVAddr); -+ /* map in the physical page */ -+ pui32Tmp[ui32Index] = ((IMG_UINT32)(DevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT) -+ & ((~pMMUHeap->ui32DataPageMask)>>SGX_MMU_PTE_ADDR_ALIGNSHIFT)) -+ | SGX_MMU_PTE_VALID -+ | ui32MMUFlags; -+ MakeKernelPageReadOnly(ppsPTInfoList[0]->PTPageCpuVAddr); -+ CheckPT(ppsPTInfoList[0]); -+} -+ -+ -+/*! -+****************************************************************************** -+ FUNCTION: MMU_MapScatter -+ -+ PURPOSE: Create a linear mapping for a range of pages at a specified -+ virtual address. -+ -+ PARAMETERS: In: pMMUHeap - the mmu. -+ In: DevVAddr - the device virtual address. -+ In: psSysAddr - the device physical address of the page to -+ map. -+ In: uSize - size of memory range in bytes -+ In: ui32MemFlags - page table flags. -+ In: hUniqueTag - A unique ID for use as a tag identifier -+ RETURNS: None -+******************************************************************************/ -+IMG_VOID -+MMU_MapScatter (MMU_HEAP *pMMUHeap, -+ IMG_DEV_VIRTADDR DevVAddr, -+ IMG_SYS_PHYADDR *psSysAddr, -+ IMG_SIZE_T uSize, -+ IMG_UINT32 ui32MemFlags, -+ IMG_HANDLE hUniqueTag) -+{ -+#if defined(PDUMP) -+ IMG_DEV_VIRTADDR MapBaseDevVAddr; -+#endif /*PDUMP*/ -+ IMG_UINT32 uCount, i; -+ IMG_DEV_PHYADDR DevPAddr; -+ -+ PVR_ASSERT (pMMUHeap != IMG_NULL); -+ -+#if defined(PDUMP) -+ MapBaseDevVAddr = DevVAddr; -+#else -+ PVR_UNREFERENCED_PARAMETER(hUniqueTag); -+#endif /*PDUMP*/ -+ -+ for (i=0, uCount=0; uCount<uSize; i++, uCount+=pMMUHeap->ui32DataPageSize) -+ { -+ IMG_SYS_PHYADDR sSysAddr; -+ -+ sSysAddr = psSysAddr[i]; -+ -+ -+ /* check the physical alignment of the memory to map */ -+ PVR_ASSERT((sSysAddr.uiAddr & pMMUHeap->ui32DataPageMask) == 0); -+ -+ DevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sSysAddr); -+ -+ MMU_MapPage (pMMUHeap, DevVAddr, DevPAddr, ui32MemFlags); -+ DevVAddr.uiAddr += pMMUHeap->ui32DataPageSize; -+ -+ PVR_DPF ((PVR_DBG_MESSAGE, -+ "MMU_MapScatter: devVAddr=%x, SysAddr=" SYSPADDR_FMT ", size=0x%x/0x%" SIZE_T_FMT_LEN "x", -+ DevVAddr.uiAddr, sSysAddr.uiAddr, uCount, uSize)); -+ } -+ -+#if defined(PDUMP) -+ MMU_PDumpPageTables (pMMUHeap, MapBaseDevVAddr, uSize, IMG_FALSE, hUniqueTag); -+#endif /* #if defined(PDUMP) */ -+} -+ -+/*! -+****************************************************************************** -+ FUNCTION: MMU_MapPages -+ -+ PURPOSE: Create a linear mapping for a ranege of pages at a specified -+ virtual address. -+ -+ PARAMETERS: In: pMMUHeap - the mmu. -+ In: DevVAddr - the device virtual address. -+ In: SysPAddr - the system physical address of the page to -+ map. -+ In: uSize - size of memory range in bytes -+ In: ui32MemFlags - page table flags. -+ In: hUniqueTag - A unique ID for use as a tag identifier -+ RETURNS: None -+******************************************************************************/ -+IMG_VOID -+MMU_MapPages (MMU_HEAP *pMMUHeap, -+ IMG_DEV_VIRTADDR DevVAddr, -+ IMG_SYS_PHYADDR SysPAddr, -+ IMG_SIZE_T uSize, -+ IMG_UINT32 ui32MemFlags, -+ IMG_HANDLE hUniqueTag) -+{ -+ IMG_DEV_PHYADDR DevPAddr; -+#if defined(PDUMP) -+ IMG_DEV_VIRTADDR MapBaseDevVAddr; -+#endif /*PDUMP*/ -+ IMG_UINT32 uCount; -+ IMG_UINT32 ui32VAdvance; -+ IMG_UINT32 ui32PAdvance; -+ -+ PVR_ASSERT (pMMUHeap != IMG_NULL); -+ -+ PVR_DPF ((PVR_DBG_MESSAGE, "MMU_MapPages: heap:%s, heap_id:%d devVAddr=%08X, SysPAddr=" SYSPADDR_FMT ", size=0x%" SIZE_T_FMT_LEN "x", -+ pMMUHeap->psDevArena->pszName, -+ pMMUHeap->psDevArena->ui32HeapID, -+ DevVAddr.uiAddr, -+ SysPAddr.uiAddr, -+ uSize)); -+ -+ /* set the virtual and physical advance */ -+ ui32VAdvance = pMMUHeap->ui32DataPageSize; -+ ui32PAdvance = pMMUHeap->ui32DataPageSize; -+ -+#if defined(PDUMP) -+ MapBaseDevVAddr = DevVAddr; -+#else -+ PVR_UNREFERENCED_PARAMETER(hUniqueTag); -+#endif /*PDUMP*/ -+ -+ DevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, SysPAddr); -+ -+ /* check the physical alignment of the memory to map */ -+ PVR_ASSERT((DevPAddr.uiAddr & pMMUHeap->ui32DataPageMask) == 0); -+ -+ /* -+ for dummy allocations there is only one physical -+ page backing the virtual range -+ */ -+ if(ui32MemFlags & PVRSRV_MEM_DUMMY) -+ { -+ ui32PAdvance = 0; -+ } -+ -+ for (uCount=0; uCount<uSize; uCount+=ui32VAdvance) -+ { -+ MMU_MapPage (pMMUHeap, DevVAddr, DevPAddr, ui32MemFlags); -+ DevVAddr.uiAddr += ui32VAdvance; -+ DevPAddr.uiAddr += ui32PAdvance; -+ } -+ -+#if defined(PDUMP) -+ MMU_PDumpPageTables (pMMUHeap, MapBaseDevVAddr, uSize, IMG_FALSE, hUniqueTag); -+#endif /* #if defined(PDUMP) */ -+} -+ -+ -+/*! -+****************************************************************************** -+ FUNCTION: MMU_MapPagesSparse -+ -+ PURPOSE: Create a linear mapping for a ranege of pages at a specified -+ virtual address. -+ -+ PARAMETERS: In: pMMUHeap - the mmu. -+ In: DevVAddr - the device virtual address. -+ In: SysPAddr - the system physical address of the page to -+ map. -+ In: ui32ChunkSize - Size of the chunk (must be page multiple) -+ In: ui32NumVirtChunks - Number of virtual chunks -+ In: ui32NumPhysChunks - Number of physical chunks -+ In: pabMapChunk - Mapping array -+ In: ui32MemFlags - page table flags. -+ In: hUniqueTag - A unique ID for use as a tag identifier -+ RETURNS: None -+******************************************************************************/ -+IMG_VOID -+MMU_MapPagesSparse (MMU_HEAP *pMMUHeap, -+ IMG_DEV_VIRTADDR DevVAddr, -+ IMG_SYS_PHYADDR SysPAddr, -+ IMG_UINT32 ui32ChunkSize, -+ IMG_UINT32 ui32NumVirtChunks, -+ IMG_UINT32 ui32NumPhysChunks, -+ IMG_BOOL *pabMapChunk, -+ IMG_UINT32 ui32MemFlags, -+ IMG_HANDLE hUniqueTag) -+{ -+ IMG_DEV_PHYADDR DevPAddr; -+#if defined(PDUMP) -+ IMG_DEV_VIRTADDR MapBaseDevVAddr; -+#endif /*PDUMP*/ -+ IMG_UINT32 uCount; -+ IMG_UINT32 ui32VAdvance; -+ IMG_UINT32 ui32PAdvance; -+ IMG_SIZE_T uSizeVM = ui32ChunkSize * ui32NumVirtChunks; -+#if !defined(PVRSRV_NEED_PVR_DPF) -+ PVR_UNREFERENCED_PARAMETER(ui32NumPhysChunks); -+#endif -+ -+ PVR_ASSERT (pMMUHeap != IMG_NULL); -+ -+ PVR_DPF ((PVR_DBG_MESSAGE, "MMU_MapPagesSparse: heap:%s, heap_id:%d devVAddr=%08X, SysPAddr=" SYSPADDR_FMT ", VM space=0x%" SIZE_T_FMT_LEN "x, PHYS space=0x%x", -+ pMMUHeap->psDevArena->pszName, -+ pMMUHeap->psDevArena->ui32HeapID, -+ DevVAddr.uiAddr, -+ SysPAddr.uiAddr, -+ uSizeVM, -+ ui32ChunkSize * ui32NumPhysChunks)); -+ -+ /* set the virtual and physical advance */ -+ ui32VAdvance = pMMUHeap->ui32DataPageSize; -+ ui32PAdvance = pMMUHeap->ui32DataPageSize; -+ -+#if defined(PDUMP) -+ MapBaseDevVAddr = DevVAddr; -+#else -+ PVR_UNREFERENCED_PARAMETER(hUniqueTag); -+#endif /*PDUMP*/ -+ -+ DevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, SysPAddr); -+ -+ /* check the physical alignment of the memory to map */ -+ PVR_ASSERT((DevPAddr.uiAddr & pMMUHeap->ui32DataPageMask) == 0); -+ -+ /* -+ for dummy allocations there is only one physical -+ page backing the virtual range -+ */ -+ if(ui32MemFlags & PVRSRV_MEM_DUMMY) -+ { -+ ui32PAdvance = 0; -+ } -+ -+ for (uCount=0; uCount<uSizeVM; uCount+=ui32VAdvance) -+ { -+ if (pabMapChunk[uCount/ui32ChunkSize]) -+ { -+ MMU_MapPage (pMMUHeap, DevVAddr, DevPAddr, ui32MemFlags); -+ DevPAddr.uiAddr += ui32PAdvance; -+ } -+ DevVAddr.uiAddr += ui32VAdvance; -+ } -+ pMMUHeap->bHasSparseMappings = IMG_TRUE; -+ -+#if defined(PDUMP) -+ MMU_PDumpPageTables (pMMUHeap, MapBaseDevVAddr, uSizeVM, IMG_FALSE, hUniqueTag); -+#endif /* #if defined(PDUMP) */ -+} -+ -+/*! -+****************************************************************************** -+ FUNCTION: MMU_MapShadow -+ -+ PURPOSE: Create a mapping for a range of pages from either a CPU -+ virtual adddress, (or if NULL a hOSMemHandle) to a specified -+ device virtual address. -+ -+ PARAMETERS: In: pMMUHeap - the mmu. -+ In: MapBaseDevVAddr - A page aligned device virtual address -+ to start mapping from. -+ In: uByteSize - A page aligned mapping length in bytes. -+ In: CpuVAddr - A page aligned CPU virtual address. -+ In: hOSMemHandle - An alternative OS specific memory handle -+ for mapping RAM without a CPU virtual -+ address -+ Out: pDevVAddr - deprecated - It used to return a byte aligned -+ device virtual address corresponding to the -+ cpu virtual address (When CpuVAddr wasn't -+ constrained to be page aligned.) Now it just -+ returns MapBaseDevVAddr. Unaligned semantics -+ can easily be handled above this API if required. -+ In: hUniqueTag - A unique ID for use as a tag identifier -+ In: ui32MemFlags - page table flags. -+ RETURNS: None -+******************************************************************************/ -+IMG_VOID -+MMU_MapShadow (MMU_HEAP *pMMUHeap, -+ IMG_DEV_VIRTADDR MapBaseDevVAddr, -+ IMG_SIZE_T uByteSize, -+ IMG_CPU_VIRTADDR CpuVAddr, -+ IMG_HANDLE hOSMemHandle, -+ IMG_DEV_VIRTADDR *pDevVAddr, -+ IMG_UINT32 ui32MemFlags, -+ IMG_HANDLE hUniqueTag) -+{ -+ IMG_UINT32 i; -+ IMG_UINT32 uOffset = 0; -+ IMG_DEV_VIRTADDR MapDevVAddr; -+ IMG_UINT32 ui32VAdvance; -+ IMG_UINT32 ui32PAdvance; -+ -+#if !defined (PDUMP) -+ PVR_UNREFERENCED_PARAMETER(hUniqueTag); -+#endif -+ -+ PVR_DPF ((PVR_DBG_MESSAGE, -+ "MMU_MapShadow: DevVAddr:%08X, Bytes:0x%" SIZE_T_FMT_LEN "x, CPUVAddr:%p", -+ MapBaseDevVAddr.uiAddr, -+ uByteSize, -+ CpuVAddr)); -+ -+ /* set the virtual and physical advance */ -+ ui32VAdvance = pMMUHeap->ui32DataPageSize; -+ ui32PAdvance = pMMUHeap->ui32DataPageSize; -+ -+ /* note: can't do useful check on the CPU Addr other than it being at least 4k alignment */ -+ PVR_ASSERT(((IMG_UINTPTR_T)CpuVAddr & (SGX_MMU_PAGE_SIZE - 1)) == 0); -+ PVR_ASSERT(((IMG_UINT32)uByteSize & pMMUHeap->ui32DataPageMask) == 0); -+ pDevVAddr->uiAddr = MapBaseDevVAddr.uiAddr; -+ -+ /* -+ for dummy allocations there is only one physical -+ page backing the virtual range -+ */ -+ if(ui32MemFlags & PVRSRV_MEM_DUMMY) -+ { -+ ui32PAdvance = 0; -+ } -+ -+ /* Loop through cpu memory and map page by page */ -+ MapDevVAddr = MapBaseDevVAddr; -+ for (i=0; i<uByteSize; i+=ui32VAdvance) -+ { -+ IMG_CPU_PHYADDR CpuPAddr; -+ IMG_DEV_PHYADDR DevPAddr; -+ -+ if(CpuVAddr) -+ { -+ CpuPAddr = OSMapLinToCPUPhys (hOSMemHandle, -+ (IMG_VOID *)((IMG_UINTPTR_T)CpuVAddr + uOffset)); -+ } -+ else -+ { -+ CpuPAddr = OSMemHandleToCpuPAddr(hOSMemHandle, uOffset); -+ } -+ DevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, CpuPAddr); -+ -+ /* check the physical alignment of the memory to map */ -+ PVR_ASSERT((DevPAddr.uiAddr & pMMUHeap->ui32DataPageMask) == 0); -+ -+ PVR_DPF ((PVR_DBG_MESSAGE, -+ "Offset=0x%x: CpuVAddr=%p, CpuPAddr=" CPUPADDR_FMT ", DevVAddr=%08X, DevPAddr=" DEVPADDR_FMT, -+ uOffset, -+ (IMG_PVOID)((IMG_UINTPTR_T)CpuVAddr + uOffset), -+ CpuPAddr.uiAddr, -+ MapDevVAddr.uiAddr, -+ DevPAddr.uiAddr)); -+ -+ MMU_MapPage (pMMUHeap, MapDevVAddr, DevPAddr, ui32MemFlags); -+ -+ /* loop update */ -+ MapDevVAddr.uiAddr += ui32VAdvance; -+ uOffset += ui32PAdvance; -+ } -+ -+#if defined(PDUMP) -+ MMU_PDumpPageTables (pMMUHeap, MapBaseDevVAddr, uByteSize, IMG_FALSE, hUniqueTag); -+#endif /* #if defined(PDUMP) */ -+} -+ -+/*! -+****************************************************************************** -+ FUNCTION: MMU_MapShadowSparse -+ -+ PURPOSE: Create a mapping for a range of pages from either a CPU -+ virtual adddress, (or if NULL a hOSMemHandle) to a specified -+ device virtual address. -+ -+ PARAMETERS: In: pMMUHeap - the mmu. -+ In: MapBaseDevVAddr - A page aligned device virtual address -+ to start mapping from. -+ In: ui32ChunkSize - Size of the chunk (must be page multiple) -+ In: ui32NumVirtChunks - Number of virtual chunks -+ In: ui32NumPhysChunks - Number of physical chunks -+ In: pabMapChunk - Mapping array -+ In: CpuVAddr - A page aligned CPU virtual address. -+ In: hOSMemHandle - An alternative OS specific memory handle -+ for mapping RAM without a CPU virtual -+ address -+ Out: pDevVAddr - deprecated - It used to return a byte aligned -+ device virtual address corresponding to the -+ cpu virtual address (When CpuVAddr wasn't -+ constrained to be page aligned.) Now it just -+ returns MapBaseDevVAddr. Unaligned semantics -+ can easily be handled above this API if required. -+ In: hUniqueTag - A unique ID for use as a tag identifier -+ In: ui32MemFlags - page table flags. -+ RETURNS: None -+******************************************************************************/ -+IMG_VOID -+MMU_MapShadowSparse (MMU_HEAP *pMMUHeap, -+ IMG_DEV_VIRTADDR MapBaseDevVAddr, -+ IMG_UINT32 ui32ChunkSize, -+ IMG_UINT32 ui32NumVirtChunks, -+ IMG_UINT32 ui32NumPhysChunks, -+ IMG_BOOL *pabMapChunk, -+ IMG_CPU_VIRTADDR CpuVAddr, -+ IMG_HANDLE hOSMemHandle, -+ IMG_DEV_VIRTADDR *pDevVAddr, -+ IMG_UINT32 ui32MemFlags, -+ IMG_HANDLE hUniqueTag) -+{ -+ IMG_UINT32 i; -+ IMG_UINT32 uOffset = 0; -+ IMG_DEV_VIRTADDR MapDevVAddr; -+ IMG_UINT32 ui32VAdvance; -+ IMG_UINT32 ui32PAdvance; -+ IMG_SIZE_T uiSizeVM = ui32ChunkSize * ui32NumVirtChunks; -+ IMG_UINT32 ui32ChunkIndex = 0; -+ IMG_UINT32 ui32ChunkOffset = 0; -+#if !defined(PVRSRV_NEED_PVR_DPF) -+ PVR_UNREFERENCED_PARAMETER(ui32NumPhysChunks); -+#endif -+#if !defined (PDUMP) -+ PVR_UNREFERENCED_PARAMETER(hUniqueTag); -+#endif -+ -+ PVR_DPF ((PVR_DBG_MESSAGE, -+ "MMU_MapShadowSparse: DevVAddr:%08X, VM space:0x%" SIZE_T_FMT_LEN "x, CPUVAddr:%p PHYS space:0x%x", -+ MapBaseDevVAddr.uiAddr, -+ uiSizeVM, -+ CpuVAddr, -+ ui32ChunkSize * ui32NumPhysChunks)); -+ -+ /* set the virtual and physical advance */ -+ ui32VAdvance = pMMUHeap->ui32DataPageSize; -+ ui32PAdvance = pMMUHeap->ui32DataPageSize; -+ -+ /* note: can't do useful check on the CPU Addr other than it being at least 4k alignment */ -+ PVR_ASSERT(((IMG_UINTPTR_T)CpuVAddr & (SGX_MMU_PAGE_SIZE - 1)) == 0); -+ PVR_ASSERT(((IMG_UINT32)uiSizeVM & pMMUHeap->ui32DataPageMask) == 0); -+ pDevVAddr->uiAddr = MapBaseDevVAddr.uiAddr; -+ -+ /* Shouldn't come through the sparse interface */ -+ PVR_ASSERT((ui32MemFlags & PVRSRV_MEM_DUMMY) == 0); -+ -+ /* Loop through cpu memory and map page by page */ -+ MapDevVAddr = MapBaseDevVAddr; -+ for (i=0; i<uiSizeVM; i+=ui32VAdvance) -+ { -+ IMG_CPU_PHYADDR CpuPAddr; -+ IMG_DEV_PHYADDR DevPAddr; -+ -+ if (pabMapChunk[i/ui32ChunkSize]) -+ /*if (pabMapChunk[ui32ChunkIndex])*/ -+ { -+ if(CpuVAddr) -+ { -+ CpuPAddr = OSMapLinToCPUPhys (hOSMemHandle, -+ (IMG_VOID *)((IMG_UINTPTR_T)CpuVAddr + uOffset)); -+ } -+ else -+ { -+ CpuPAddr = OSMemHandleToCpuPAddr(hOSMemHandle, uOffset); -+ } -+ DevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, CpuPAddr); -+ -+ /* check the physical alignment of the memory to map */ -+ PVR_ASSERT((DevPAddr.uiAddr & pMMUHeap->ui32DataPageMask) == 0); -+ -+ PVR_DPF ((PVR_DBG_MESSAGE, -+ "Offset=0x%x: CpuVAddr=%p, CpuPAddr=" CPUPADDR_FMT ", DevVAddr=%08X, DevPAddr=" DEVPADDR_FMT, -+ uOffset, -+ (void *)((IMG_UINTPTR_T)CpuVAddr + uOffset), -+ CpuPAddr.uiAddr, -+ MapDevVAddr.uiAddr, -+ DevPAddr.uiAddr)); -+ -+ MMU_MapPage (pMMUHeap, MapDevVAddr, DevPAddr, ui32MemFlags); -+ uOffset += ui32PAdvance; -+ } -+ -+ /* loop update */ -+ MapDevVAddr.uiAddr += ui32VAdvance; -+ -+ if (ui32ChunkOffset == ui32ChunkSize) -+ { -+ ui32ChunkIndex++; -+ ui32ChunkOffset = 0; -+ } -+ } -+ -+ pMMUHeap->bHasSparseMappings = IMG_TRUE; -+#if defined(PDUMP) -+ MMU_PDumpPageTables (pMMUHeap, MapBaseDevVAddr, uiSizeVM, IMG_FALSE, hUniqueTag); -+#endif /* #if defined(PDUMP) */ -+} -+ -+/*! -+****************************************************************************** -+ FUNCTION: MMU_UnmapPages -+ -+ PURPOSE: unmap pages and invalidate virtual address -+ -+ PARAMETERS: In: psMMUHeap - the mmu. -+ In: sDevVAddr - the device virtual address. -+ In: ui32PageCount - page count -+ In: hUniqueTag - A unique ID for use as a tag identifier -+ -+ RETURNS: None -+******************************************************************************/ -+IMG_VOID -+MMU_UnmapPages (MMU_HEAP *psMMUHeap, -+ IMG_DEV_VIRTADDR sDevVAddr, -+ IMG_UINT32 ui32PageCount, -+ IMG_HANDLE hUniqueTag) -+{ -+ IMG_UINT32 uPageSize = psMMUHeap->ui32DataPageSize; -+ IMG_DEV_VIRTADDR sTmpDevVAddr; -+ IMG_UINT32 i; -+ IMG_UINT32 ui32PDIndex; -+ IMG_UINT32 ui32PTIndex; -+ IMG_UINT32 *pui32Tmp; -+ -+#if !defined (PDUMP) -+ PVR_UNREFERENCED_PARAMETER(hUniqueTag); -+#endif -+ -+ /* setup tmp devvaddr to base of allocation */ -+ sTmpDevVAddr = sDevVAddr; -+ -+ for(i=0; i<ui32PageCount; i++) -+ { -+ MMU_PT_INFO **ppsPTInfoList; -+ -+ /* find the index/offset in PD entries */ -+ ui32PDIndex = sTmpDevVAddr.uiAddr >> psMMUHeap->ui32PDShift; -+ -+ /* and advance to the first PT info list */ -+ ppsPTInfoList = &psMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex]; -+ -+ /* find the index/offset of the first PT in the first PT page */ -+ ui32PTIndex = (sTmpDevVAddr.uiAddr & psMMUHeap->ui32PTMask) >> psMMUHeap->ui32PTShift; -+ -+ /* Is the PT page valid? */ -+ if ((!ppsPTInfoList[0]) && (!psMMUHeap->bHasSparseMappings)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "MMU_UnmapPages: ERROR Invalid PT for alloc at VAddr:0x%08X (VaddrIni:0x%08X AllocPage:%u) PDIdx:%u PTIdx:%u", -+ sTmpDevVAddr.uiAddr, -+ sDevVAddr.uiAddr, -+ i, -+ ui32PDIndex, -+ ui32PTIndex)); -+ -+ /* advance the sTmpDevVAddr by one page */ -+ sTmpDevVAddr.uiAddr += uPageSize; -+ -+ /* Try to unmap the remaining allocation pages */ -+ continue; -+ } -+ -+ CheckPT(ppsPTInfoList[0]); -+ -+ /* setup pointer to the first entry in the PT page */ -+ pui32Tmp = (IMG_UINT32*)ppsPTInfoList[0]->PTPageCpuVAddr; -+ -+ /* Decrement the valid page count only if the current page is valid*/ -+ if (pui32Tmp[ui32PTIndex] & SGX_MMU_PTE_VALID) -+ { -+ ppsPTInfoList[0]->ui32ValidPTECount--; -+ } -+ else -+ { -+ PVR_DPF((PVR_DBG_ERROR, "MMU_UnmapPages: Page is already invalid for alloc at VAddr:0x%08X (VAddrIni:0x%08X AllocPage:%u) PDIdx:%u PTIdx:%u", -+ sTmpDevVAddr.uiAddr, -+ sDevVAddr.uiAddr, -+ i, -+ ui32PDIndex, -+ ui32PTIndex)); -+ PVR_DPF((PVR_DBG_ERROR, "MMU_UnmapPages: Page table entry value: 0x%08X", pui32Tmp[ui32PTIndex])); -+ } -+ -+ /* The page table count should not go below zero */ -+ PVR_ASSERT((IMG_INT32)ppsPTInfoList[0]->ui32ValidPTECount >= 0); -+ -+ MakeKernelPageReadWrite(ppsPTInfoList[0]->PTPageCpuVAddr); -+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) -+ /* point the PT entry to the dummy data page */ -+ pui32Tmp[ui32PTIndex] = (psMMUHeap->psMMUContext->psDevInfo->sDummyDataDevPAddr.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT) -+ | SGX_MMU_PTE_VALID; -+#else -+ /* invalidate entry */ -+#if defined(FIX_HW_BRN_31620) -+ BRN31620InvalidatePageTableEntry(psMMUHeap->psMMUContext, ui32PDIndex, ui32PTIndex, &pui32Tmp[ui32PTIndex]); -+#else -+ pui32Tmp[ui32PTIndex] = 0; -+#endif -+#endif -+ MakeKernelPageReadOnly(ppsPTInfoList[0]->PTPageCpuVAddr); -+ -+ CheckPT(ppsPTInfoList[0]); -+ -+ /* advance the sTmpDevVAddr by one page */ -+ sTmpDevVAddr.uiAddr += uPageSize; -+ } -+ -+ MMU_InvalidatePageTableCache(psMMUHeap->psMMUContext->psDevInfo); -+ -+#if defined(PDUMP) -+ MMU_PDumpPageTables (psMMUHeap, sDevVAddr, uPageSize*ui32PageCount, IMG_TRUE, hUniqueTag); -+#endif /* #if defined(PDUMP) */ -+} -+ -+ -+/*! -+****************************************************************************** -+ FUNCTION: MMU_GetPhysPageAddr -+ -+ PURPOSE: extracts physical address from MMU page tables -+ -+ PARAMETERS: In: pMMUHeap - the mmu -+ PARAMETERS: In: sDevVPageAddr - the virtual address to extract physical -+ page mapping from -+ RETURNS: None -+******************************************************************************/ -+IMG_DEV_PHYADDR -+MMU_GetPhysPageAddr(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR sDevVPageAddr) -+{ -+ IMG_UINT32 *pui32PageTable; -+ IMG_UINT32 ui32Index; -+ IMG_DEV_PHYADDR sDevPAddr; -+ MMU_PT_INFO **ppsPTInfoList; -+ -+ /* find the index/offset in PD entries */ -+ ui32Index = sDevVPageAddr.uiAddr >> pMMUHeap->ui32PDShift; -+ -+ /* and advance to the first PT info list */ -+ ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32Index]; -+ if (!ppsPTInfoList[0]) -+ { -+ /* Heaps with sparse mappings are allowed invalid pages */ -+ if (!pMMUHeap->bHasSparseMappings) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"MMU_GetPhysPageAddr: Not mapped in at 0x%08x", sDevVPageAddr.uiAddr)); -+ } -+ sDevPAddr.uiAddr = 0; -+ return sDevPAddr; -+ } -+ -+ /* find the index/offset of the first PT in the first PT page */ -+ ui32Index = (sDevVPageAddr.uiAddr & pMMUHeap->ui32PTMask) >> pMMUHeap->ui32PTShift; -+ -+ /* setup pointer to the first entry in the PT page */ -+ pui32PageTable = (IMG_UINT32*)ppsPTInfoList[0]->PTPageCpuVAddr; -+ -+ /* read back physical page */ -+ sDevPAddr.uiAddr = pui32PageTable[ui32Index]; -+ -+ /* Mask off non-address bits */ -+ sDevPAddr.uiAddr &= ~(pMMUHeap->ui32DataPageMask>>SGX_MMU_PTE_ADDR_ALIGNSHIFT); -+ -+ /* and align the address */ -+ sDevPAddr.uiAddr <<= SGX_MMU_PTE_ADDR_ALIGNSHIFT; -+ -+ return sDevPAddr; -+} -+ -+ -+IMG_DEV_PHYADDR MMU_GetPDDevPAddr(MMU_CONTEXT *pMMUContext) -+{ -+ return (pMMUContext->sPDDevPAddr); -+} -+ -+ -+/*! -+****************************************************************************** -+ FUNCTION: SGXGetPhysPageAddr -+ -+ PURPOSE: Gets DEV and CPU physical address of sDevVAddr -+ -+ PARAMETERS: In: hDevMemHeap - device mem heap handle -+ PARAMETERS: In: sDevVAddr - the base virtual address to unmap from -+ PARAMETERS: Out: pDevPAddr - DEV physical address -+ PARAMETERS: Out: pCpuPAddr - CPU physical address -+ RETURNS: None -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR SGXGetPhysPageAddrKM (IMG_HANDLE hDevMemHeap, -+ IMG_DEV_VIRTADDR sDevVAddr, -+ IMG_DEV_PHYADDR *pDevPAddr, -+ IMG_CPU_PHYADDR *pCpuPAddr) -+{ -+ MMU_HEAP *pMMUHeap; -+ IMG_DEV_PHYADDR DevPAddr; -+ -+ /* -+ Get MMU Heap From hDevMemHeap -+ */ -+ pMMUHeap = (MMU_HEAP*)BM_GetMMUHeap(hDevMemHeap); -+ -+ DevPAddr = MMU_GetPhysPageAddr(pMMUHeap, sDevVAddr); -+ pCpuPAddr->uiAddr = DevPAddr.uiAddr; /* SysDevPAddrToCPUPAddr(DevPAddr) */ -+ pDevPAddr->uiAddr = DevPAddr.uiAddr; -+ -+ return (pDevPAddr->uiAddr != 0) ? PVRSRV_OK : PVRSRV_ERROR_INVALID_PARAMS; -+} -+ -+ -+/*! -+****************************************************************************** -+ FUNCTION: SGXGetMMUPDAddrKM -+ -+ PURPOSE: Gets PD device physical address of hDevMemContext -+ -+ PARAMETERS: In: hDevCookie - device cookie -+ PARAMETERS: In: hDevMemContext - memory context -+ PARAMETERS: Out: psPDDevPAddr - MMU PD address -+ RETURNS: None -+******************************************************************************/ -+PVRSRV_ERROR SGXGetMMUPDAddrKM(IMG_HANDLE hDevCookie, -+ IMG_HANDLE hDevMemContext, -+ IMG_DEV_PHYADDR *psPDDevPAddr) -+{ -+ if (!hDevCookie || !hDevMemContext || !psPDDevPAddr) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ /* return the address */ -+ *psPDDevPAddr = ((BM_CONTEXT*)hDevMemContext)->psMMUContext->sPDDevPAddr; -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ FUNCTION: MMU_BIFResetPDAlloc -+ -+ PURPOSE: Allocate a dummy Page Directory, Page Table and Page which can -+ be used for dynamic dummy page mapping during SGX reset. -+ Note: since this is only used for hardware recovery, no -+ pdumping is performed. -+ -+ PARAMETERS: In: psDevInfo - device info -+ RETURNS: PVRSRV_OK or error -+******************************************************************************/ -+PVRSRV_ERROR MMU_BIFResetPDAlloc(PVRSRV_SGXDEV_INFO *psDevInfo) -+{ -+ PVRSRV_ERROR eError; -+ SYS_DATA *psSysData; -+ RA_ARENA *psLocalDevMemArena; -+ IMG_HANDLE hOSMemHandle = IMG_NULL; -+ IMG_BYTE *pui8MemBlock = IMG_NULL; -+ IMG_SYS_PHYADDR sMemBlockSysPAddr; -+ IMG_CPU_PHYADDR sMemBlockCpuPAddr; -+ -+ SysAcquireData(&psSysData); -+ -+ psLocalDevMemArena = psSysData->apsLocalDevMemArena[0]; -+ -+ /* allocate 3 pages - for the PD, PT and dummy page */ -+ if(psLocalDevMemArena == IMG_NULL) -+ { -+ /* UMA system */ -+ eError = OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, -+ 3 * SGX_MMU_PAGE_SIZE, -+ SGX_MMU_PAGE_SIZE, -+ IMG_NULL, -+ 0, -+ IMG_NULL, -+ (IMG_VOID **)&pui8MemBlock, -+ &hOSMemHandle); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "MMU_BIFResetPDAlloc: ERROR call to OSAllocPages failed")); -+ return eError; -+ } -+ -+ /* translate address to device physical */ -+ if(pui8MemBlock) -+ { -+ sMemBlockCpuPAddr = OSMapLinToCPUPhys(hOSMemHandle, -+ pui8MemBlock); -+ } -+ else -+ { -+ /* This isn't used in all cases since not all ports currently support -+ * OSMemHandleToCpuPAddr() */ -+ sMemBlockCpuPAddr = OSMemHandleToCpuPAddr(hOSMemHandle, 0); -+ } -+ } -+ else -+ { -+ /* non-UMA system */ -+ -+ /* -+ We cannot use IMG_SYS_PHYADDR here, as that is 64-bit for 32-bit PAE builds. -+ The physical address in this call to RA_Alloc is specifically the SysPAddr -+ of local (card) space, and it is highly unlikely we would ever need to -+ support > 4GB of local (card) memory (this does assume that such local -+ memory will be mapped into System physical memory space at a low address so -+ that any and all local memory exists within the 4GB SYSPAddr range). -+ */ -+ IMG_UINTPTR_T uiLocalPAddr; -+ -+ if(RA_Alloc(psLocalDevMemArena, -+ 3 * SGX_MMU_PAGE_SIZE, -+ IMG_NULL, -+ IMG_NULL, -+ 0, -+ SGX_MMU_PAGE_SIZE, -+ 0, -+ IMG_NULL, -+ 0, -+ &uiLocalPAddr) != IMG_TRUE) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "MMU_BIFResetPDAlloc: ERROR call to RA_Alloc failed")); -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ -+ /* Munge the local PAddr back into the SysPAddr */ -+ sMemBlockSysPAddr.uiAddr = uiLocalPAddr; -+ -+ /* derive the CPU virtual address */ -+ sMemBlockCpuPAddr = SysSysPAddrToCpuPAddr(sMemBlockSysPAddr); -+ pui8MemBlock = OSMapPhysToLin(sMemBlockCpuPAddr, -+ SGX_MMU_PAGE_SIZE * 3, -+ PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY, -+ &hOSMemHandle); -+ if(!pui8MemBlock) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "MMU_BIFResetPDAlloc: ERROR failed to map page tables")); -+ return PVRSRV_ERROR_BAD_MAPPING; -+ } -+ } -+ -+ psDevInfo->hBIFResetPDOSMemHandle = hOSMemHandle; -+ psDevInfo->sBIFResetPDDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sMemBlockCpuPAddr); -+ psDevInfo->sBIFResetPTDevPAddr.uiAddr = psDevInfo->sBIFResetPDDevPAddr.uiAddr + SGX_MMU_PAGE_SIZE; -+ psDevInfo->sBIFResetPageDevPAddr.uiAddr = psDevInfo->sBIFResetPTDevPAddr.uiAddr + SGX_MMU_PAGE_SIZE; -+ /* override pointer cast warnings */ -+ /* PRQA S 3305,509 2 */ -+ psDevInfo->pui32BIFResetPD = (IMG_UINT32 *)pui8MemBlock; -+ psDevInfo->pui32BIFResetPT = (IMG_UINT32 *)(pui8MemBlock + SGX_MMU_PAGE_SIZE); -+ -+ /* Invalidate entire PD and PT. */ -+ OSMemSet(psDevInfo->pui32BIFResetPD, 0, SGX_MMU_PAGE_SIZE); -+ OSMemSet(psDevInfo->pui32BIFResetPT, 0, SGX_MMU_PAGE_SIZE); -+ /* Fill dummy page with markers. */ -+ OSMemSet(pui8MemBlock + (2 * SGX_MMU_PAGE_SIZE), 0xDB, SGX_MMU_PAGE_SIZE); -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ FUNCTION: MMU_BIFResetPDFree -+ -+ PURPOSE: Free resources allocated in MMU_BIFResetPDAlloc. -+ -+ PARAMETERS: In: psDevInfo - device info -+ RETURNS: -+******************************************************************************/ -+IMG_VOID MMU_BIFResetPDFree(PVRSRV_SGXDEV_INFO *psDevInfo) -+{ -+ SYS_DATA *psSysData; -+ RA_ARENA *psLocalDevMemArena; -+ IMG_SYS_PHYADDR sPDSysPAddr; -+ -+ SysAcquireData(&psSysData); -+ -+ psLocalDevMemArena = psSysData->apsLocalDevMemArena[0]; -+ -+ /* free the page directory */ -+ if(psLocalDevMemArena == IMG_NULL) -+ { -+ OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, -+ 3 * SGX_MMU_PAGE_SIZE, -+ psDevInfo->pui32BIFResetPD, -+ psDevInfo->hBIFResetPDOSMemHandle); -+ } -+ else -+ { -+ OSUnMapPhysToLin(psDevInfo->pui32BIFResetPD, -+ 3 * SGX_MMU_PAGE_SIZE, -+ PVRSRV_HAP_WRITECOMBINE|PVRSRV_HAP_KERNEL_ONLY, -+ psDevInfo->hBIFResetPDOSMemHandle); -+ -+ sPDSysPAddr = SysDevPAddrToSysPAddr(PVRSRV_DEVICE_TYPE_SGX, psDevInfo->sBIFResetPDDevPAddr); -+ /* Note that the cast to IMG_UINTPTR_T is ok as we're local mem. */ -+ RA_Free(psLocalDevMemArena, (IMG_UINTPTR_T)sPDSysPAddr.uiAddr, IMG_FALSE); -+ } -+} -+ -+IMG_VOID MMU_CheckFaultAddr(PVRSRV_SGXDEV_INFO *psDevInfo, IMG_UINT32 ui32PDDevPAddr, IMG_UINT32 ui32FaultAddr) -+{ -+ MMU_CONTEXT *psMMUContext = psDevInfo->pvMMUContextList; -+ -+ while (psMMUContext && (psMMUContext->sPDDevPAddr.uiAddr != ui32PDDevPAddr)) -+ { -+ psMMUContext = psMMUContext->psNext; -+ } -+ -+ if (psMMUContext) -+ { -+ IMG_UINT32 ui32PTIndex; -+ IMG_UINT32 ui32PDIndex; -+ -+ PVR_LOG(("Found MMU context for page fault 0x%08x", ui32FaultAddr)); -+ PVR_LOG(("GPU memory context is for PID=%d (%s)", psMMUContext->ui32PID, psMMUContext->szName)); -+ -+ ui32PTIndex = (ui32FaultAddr & SGX_MMU_PT_MASK) >> SGX_MMU_PAGE_SHIFT; -+ ui32PDIndex = (ui32FaultAddr & SGX_MMU_PD_MASK) >> (SGX_MMU_PT_SHIFT + SGX_MMU_PAGE_SHIFT); -+ -+ if (psMMUContext->apsPTInfoList[ui32PDIndex]) -+ { -+ if (psMMUContext->apsPTInfoList[ui32PDIndex]->PTPageCpuVAddr) -+ { -+ IMG_UINT32 *pui32Ptr = psMMUContext->apsPTInfoList[ui32PDIndex]->PTPageCpuVAddr; -+ IMG_UINT32 ui32PTE = pui32Ptr[ui32PTIndex]; -+ -+ PVR_LOG(("PDE valid: PTE = 0x%08x (PhysAddr = 0x%08x, %s)", -+ ui32PTE, -+ ui32PTE & SGX_MMU_PTE_ADDR_MASK, -+ ui32PTE & SGX_MMU_PTE_VALID?"valid":"Invalid")); -+ } -+ else -+ { -+ PVR_LOG(("Found PT info but no CPU address")); -+ } -+ } -+ else -+ { -+ PVR_LOG(("No PDE found")); -+ } -+ } -+} -+ -+#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE) -+/*! -+****************************************************************************** -+ FUNCTION: MMU_MapExtSystemCacheRegs -+ -+ PURPOSE: maps external system cache control registers into SGX MMU -+ -+ PARAMETERS: In: psDeviceNode - device node -+ RETURNS: -+******************************************************************************/ -+PVRSRV_ERROR MMU_MapExtSystemCacheRegs(PVRSRV_DEVICE_NODE *psDeviceNode) -+{ -+ IMG_UINT32 *pui32PT; -+ PVRSRV_SGXDEV_INFO *psDevInfo; -+ IMG_UINT32 ui32PDIndex; -+ IMG_UINT32 ui32PTIndex; -+ PDUMP_MMU_ATTRIB sMMUAttrib; -+ -+ psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice; -+ -+ sMMUAttrib = psDevInfo->sMMUAttrib; -+#if defined(PDUMP) -+ MMU_SetPDumpAttribs(&sMMUAttrib, psDeviceNode, -+ SGX_MMU_PAGE_MASK, -+ SGX_MMU_PT_SIZE * sizeof(IMG_UINT32)); -+#endif -+ -+#if defined(PDUMP) -+ { -+ IMG_CHAR szScript[128]; -+ -+ sprintf(szScript, "MALLOC :EXTSYSCACHE:PA_%08X%08X %u %u 0x%p\r\n", 0, psDevInfo->sExtSysCacheRegsDevPBase.uiAddr, SGX_MMU_PAGE_SIZE, SGX_MMU_PAGE_SIZE, psDevInfo->sExtSysCacheRegsDevPBase.uiAddr); -+ PDumpOSWriteString2(szScript, PDUMP_FLAGS_CONTINUOUS); -+ } -+#endif -+ -+ ui32PDIndex = (SGX_EXT_SYSTEM_CACHE_REGS_DEVVADDR_BASE & SGX_MMU_PD_MASK) >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT); -+ ui32PTIndex = (SGX_EXT_SYSTEM_CACHE_REGS_DEVVADDR_BASE & SGX_MMU_PT_MASK) >> SGX_MMU_PAGE_SHIFT; -+ -+ pui32PT = (IMG_UINT32 *) psDeviceNode->sDevMemoryInfo.pBMKernelContext->psMMUContext->apsPTInfoList[ui32PDIndex]->PTPageCpuVAddr; -+ -+ MakeKernelPageReadWrite(pui32PT); -+ /* map the PT to the registers */ -+ pui32PT[ui32PTIndex] = (psDevInfo->sExtSysCacheRegsDevPBase.uiAddr>>SGX_MMU_PTE_ADDR_ALIGNSHIFT) -+ | SGX_MMU_PTE_VALID; -+ MakeKernelPageReadOnly(pui32PT); -+#if defined(PDUMP) -+ /* Add the entery to the PT */ -+ { -+ IMG_DEV_PHYADDR sDevPAddr; -+ IMG_CPU_PHYADDR sCpuPAddr; -+ IMG_UINT32 ui32PageMask; -+ IMG_UINT32 ui32PTE; -+ PVRSRV_ERROR eErr; -+ -+ PDUMP_GET_SCRIPT_AND_FILE_STRING(); -+ -+ ui32PageMask = sMMUAttrib.ui32PTSize - 1; -+ sCpuPAddr = OSMapLinToCPUPhys(psDeviceNode->sDevMemoryInfo.pBMKernelContext->psMMUContext->apsPTInfoList[ui32PDIndex]->hPTPageOSMemHandle, &pui32PT[ui32PTIndex]); -+ sDevPAddr = SysCpuPAddrToDevPAddr(sMMUAttrib.sDevId.eDeviceType, sCpuPAddr); -+ ui32PTE = *((IMG_UINT32 *) (&pui32PT[ui32PTIndex])); -+ -+ eErr = PDumpOSBufprintf(hScript, -+ ui32MaxLenScript, -+ "WRW :%s:PA_%p%p:0x%08X :%s:PA_%p%08X:0x%08X\r\n", -+ sMMUAttrib.sDevId.pszPDumpDevName, -+ PDUMP_PT_UNIQUETAG, -+ (IMG_PVOID)((sDevPAddr.uiAddr) & ~ui32PageMask), -+ (sDevPAddr.uiAddr) & ui32PageMask, -+ "EXTSYSCACHE", -+ PDUMP_PD_UNIQUETAG, -+ (ui32PTE & sMMUAttrib.ui32PDEMask) << sMMUAttrib.ui32PTEAlignShift, -+ ui32PTE & ~sMMUAttrib.ui32PDEMask); -+ if(eErr != PVRSRV_OK) -+ { -+ return eErr; -+ } -+ PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS); -+ } -+#endif -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ FUNCTION: MMU_UnmapExtSystemCacheRegs -+ -+ PURPOSE: unmaps external system cache control registers -+ -+ PARAMETERS: In: psDeviceNode - device node -+ RETURNS: -+******************************************************************************/ -+PVRSRV_ERROR MMU_UnmapExtSystemCacheRegs(PVRSRV_DEVICE_NODE *psDeviceNode) -+{ -+ SYS_DATA *psSysData; -+ RA_ARENA *psLocalDevMemArena; -+ PVRSRV_SGXDEV_INFO *psDevInfo; -+ IMG_UINT32 ui32PDIndex; -+ IMG_UINT32 ui32PTIndex; -+ IMG_UINT32 *pui32PT; -+ PDUMP_MMU_ATTRIB sMMUAttrib; -+ -+ psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice; -+ -+ sMMUAttrib = psDevInfo->sMMUAttrib; -+ -+#if defined(PDUMP) -+ MMU_SetPDumpAttribs(&sMMUAttrib, psDeviceNode, -+ SGX_MMU_PAGE_MASK, -+ SGX_MMU_PT_SIZE * sizeof(IMG_UINT32)); -+#endif -+ SysAcquireData(&psSysData); -+ -+ psLocalDevMemArena = psSysData->apsLocalDevMemArena[0]; -+ -+ /* unmap the MMU page table from the PD */ -+ ui32PDIndex = (SGX_EXT_SYSTEM_CACHE_REGS_DEVVADDR_BASE & SGX_MMU_PD_MASK) >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT); -+ ui32PTIndex = (SGX_EXT_SYSTEM_CACHE_REGS_DEVVADDR_BASE & SGX_MMU_PT_MASK) >> SGX_MMU_PAGE_SHIFT; -+ -+ /* Only unmap it if the PT hasn't already been freed */ -+ if (psDeviceNode->sDevMemoryInfo.pBMKernelContext->psMMUContext->apsPTInfoList[ui32PDIndex]) -+ { -+ if (psDeviceNode->sDevMemoryInfo.pBMKernelContext->psMMUContext->apsPTInfoList[ui32PDIndex]->PTPageCpuVAddr) -+ { -+ pui32PT = (IMG_UINT32 *) psDeviceNode->sDevMemoryInfo.pBMKernelContext->psMMUContext->apsPTInfoList[ui32PDIndex]->PTPageCpuVAddr; -+ } -+ } -+ -+ MakeKernelPageReadWrite(pui32PT); -+ pui32PT[ui32PTIndex] = 0; -+ MakeKernelPageReadOnly(pui32PT); -+ -+ PDUMPMEMPTENTRIES(&sMMUAttrib, psDeviceNode->sDevMemoryInfo.pBMKernelContext->psMMUContext->hPDOSMemHandle, &pui32PT[ui32PTIndex], sizeof(IMG_UINT32), 0, IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG); -+ -+ return PVRSRV_OK; -+} -+#endif -+ -+ -+#if PAGE_TEST -+/*! -+****************************************************************************** -+ FUNCTION: PageTest -+ -+ PURPOSE: Tests page table memory, for use during device bring-up. -+ -+ PARAMETERS: In: void* pMem - page address (CPU mapped) -+ PARAMETERS: In: IMG_DEV_PHYADDR sDevPAddr - page device phys address -+ RETURNS: None, provides debug output and breaks if an error is detected. -+******************************************************************************/ -+static IMG_VOID PageTest(IMG_VOID* pMem, IMG_DEV_PHYADDR sDevPAddr) -+{ -+ volatile IMG_UINT32 ui32WriteData; -+ volatile IMG_UINT32 ui32ReadData; -+ volatile IMG_UINT32 *pMem32 = (volatile IMG_UINT32 *)pMem; -+ IMG_INT n; -+ IMG_BOOL bOK=IMG_TRUE; -+ -+ ui32WriteData = 0xffffffff; -+ -+ for (n=0; n<1024; n++) -+ { -+ pMem32[n] = ui32WriteData; -+ ui32ReadData = pMem32[n]; -+ -+ if (ui32WriteData != ui32ReadData) -+ { -+ // Mem fault -+ PVR_DPF ((PVR_DBG_ERROR, "Error - memory page test failed at device phys address 0x" DEVPADDR_FMT, sDevPAddr.uiAddr + (n<<2) )); -+ PVR_DBG_BREAK; -+ bOK = IMG_FALSE; -+ } -+ } -+ -+ ui32WriteData = 0; -+ -+ for (n=0; n<1024; n++) -+ { -+ pMem32[n] = ui32WriteData; -+ ui32ReadData = pMem32[n]; -+ -+ if (ui32WriteData != ui32ReadData) -+ { -+ // Mem fault -+ PVR_DPF ((PVR_DBG_ERROR, "Error - memory page test failed at device phys address 0x" DEVPADDR_FMT, sDevPAddr.uiAddr + (n<<2))); -+ PVR_DBG_BREAK; -+ bOK = IMG_FALSE; -+ } -+ } -+ -+ if (bOK) -+ { -+ PVR_DPF ((PVR_DBG_VERBOSE, "MMU Page 0x" DEVPADDR_FMT " is OK", sDevPAddr.uiAddr)); -+ } -+ else -+ { -+ PVR_DPF ((PVR_DBG_VERBOSE, "MMU Page 0x" DEVPADDR_FMT " *** FAILED ***", sDevPAddr.uiAddr)); -+ } -+} -+#endif -+ -+/****************************************************************************** -+ End of file (mmu.c) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/mmu.h b/drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/mmu.h -new file mode 100644 -index 0000000..bb28ec2 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/mmu.h -@@ -0,0 +1,501 @@ -+/*************************************************************************/ /*! -+@Title MMU Management -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Implements basic low level control of MMU. -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#ifndef _MMU_H_ -+#define _MMU_H_ -+ -+#include "sgxinfokm.h" -+ -+/* -+****************************************************************************** -+ FUNCTION: MMU_Initialise -+ -+ PURPOSE: Initialise the mmu module. -+ -+ PARAMETERS: None -+ RETURNS: PVRSRV_ERROR -+******************************************************************************/ -+PVRSRV_ERROR -+MMU_Initialise (PVRSRV_DEVICE_NODE *psDeviceNode, MMU_CONTEXT **ppsMMUContext, IMG_DEV_PHYADDR *psPDDevPAddr); -+ -+/* -+****************************************************************************** -+ FUNCTION: MMU_Finalise -+ -+ PURPOSE: Finalise the mmu module, deallocate all resources. -+ -+ PARAMETERS: None. -+ RETURNS: None. -+******************************************************************************/ -+IMG_VOID -+MMU_Finalise (MMU_CONTEXT *psMMUContext); -+ -+ -+/* -+****************************************************************************** -+ FUNCTION: MMU_InsertHeap -+ -+ PURPOSE: Inserts shared heap into the specified context -+ from the kernel context -+ -+ PARAMETERS: None. -+ RETURNS: None. -+******************************************************************************/ -+IMG_VOID -+MMU_InsertHeap(MMU_CONTEXT *psMMUContext, MMU_HEAP *psMMUHeap); -+ -+/* -+****************************************************************************** -+ FUNCTION: MMU_Create -+ -+ PURPOSE: Create an mmu device. -+ -+ PARAMETERS: In: psMMUContext - -+ In: psDevArena - -+ Out: ppsVMArena -+ RETURNS: MMU_HEAP -+******************************************************************************/ -+MMU_HEAP * -+MMU_Create (MMU_CONTEXT *psMMUContext, -+ DEV_ARENA_DESCRIPTOR *psDevArena, -+ RA_ARENA **ppsVMArena, -+ PDUMP_MMU_ATTRIB **ppsMMUAttrib); -+ -+/* -+****************************************************************************** -+ FUNCTION: MMU_Delete -+ -+ PURPOSE: Delete an mmu device. -+ -+ PARAMETERS: In: pMMUHeap - The mmu to delete. -+ RETURNS: -+******************************************************************************/ -+IMG_VOID -+MMU_Delete (MMU_HEAP *pMMUHeap); -+ -+/* -+****************************************************************************** -+ FUNCTION: MMU_Alloc -+ PURPOSE: Allocate space in an mmu's virtual address space. -+ PARAMETERS: In: pMMUHeap - MMU to allocate on. -+ In: uSize - Size in bytes to allocate. -+ Out: pActualSize - If non null receives actual size allocated. -+ In: uFlags - Allocation flags. -+ In: uDevVAddrAlignment - Required alignment. -+ Out: pDevVAddr - Receives base address of allocation. -+ RETURNS: IMG_TRUE - Success -+ IMG_FALSE - Failure -+******************************************************************************/ -+IMG_BOOL -+MMU_Alloc (MMU_HEAP *pMMUHeap, -+ IMG_SIZE_T uSize, -+ IMG_SIZE_T *pActualSize, -+ IMG_UINT32 uFlags, -+ IMG_UINT32 uDevVAddrAlignment, -+ IMG_DEV_VIRTADDR *pDevVAddr); -+ -+/* -+****************************************************************************** -+ FUNCTION: MMU_Free -+ PURPOSE: Frees space in an mmu's virtual address space. -+ PARAMETERS: In: pMMUHeap - MMU to free on. -+ In: DevVAddr - Base address of allocation. -+ RETURNS: IMG_TRUE - Success -+ IMG_FALSE - Failure -+******************************************************************************/ -+IMG_VOID -+MMU_Free (MMU_HEAP *pMMUHeap, -+ IMG_DEV_VIRTADDR DevVAddr, -+ IMG_UINT32 ui32Size); -+ -+/* -+****************************************************************************** -+ FUNCTION: MMU_Enable -+ -+ PURPOSE: Enable an mmu. Establishes pages tables and takes the mmu out -+ of bypass and waits for the mmu to acknowledge enabled. -+ -+ PARAMETERS: In: pMMUHeap - the mmu -+ RETURNS: None -+******************************************************************************/ -+IMG_VOID -+MMU_Enable (MMU_HEAP *pMMUHeap); -+ -+/* -+****************************************************************************** -+ FUNCTION: MMU_Disable -+ -+ PURPOSE: Disable an mmu, takes the mmu into bypass. -+ -+ PARAMETERS: In: pMMUHeap - the mmu -+ RETURNS: None -+******************************************************************************/ -+IMG_VOID -+MMU_Disable (MMU_HEAP *pMMUHeap); -+ -+/* -+****************************************************************************** -+ FUNCTION: MMU_MapPages -+ -+ PURPOSE: Create a mapping for a range of pages from a device physical -+ adddress to a specified device virtual address. -+ -+ PARAMETERS: In: pMMUHeap - the mmu. -+ In: DevVAddr - the device virtual address. -+ In: SysPAddr - the system physical address of the page to map. -+ In: uSize - size of memory range in bytes -+ In: ui32MemFlags - page table flags. -+ In: hUniqueTag - A unique ID for use as a tag identifier -+ RETURNS: None -+******************************************************************************/ -+IMG_VOID -+MMU_MapPages (MMU_HEAP *pMMUHeap, -+ IMG_DEV_VIRTADDR DevVAddr, -+ IMG_SYS_PHYADDR SysPAddr, -+ IMG_SIZE_T uSize, -+ IMG_UINT32 ui32MemFlags, -+ IMG_HANDLE hUniqueTag); -+ -+/* -+****************************************************************************** -+ FUNCTION: MMU_MapPagesSparse -+ -+ PURPOSE: Create a mapping for a range of pages from a device physical -+ adddress to a specified device virtual address. -+ -+ PARAMETERS: In: pMMUHeap - the mmu. -+ In: DevVAddr - the device virtual address. -+ In: SysPAddr - the system physical address of the page to map. -+ In: ui32ChunkSize - Size of the chunk (must be page multiple) -+ In: ui32NumVirtChunks - Number of virtual chunks -+ In: ui32NumPhysChunks - Number of physical chunks -+ In: pabMapChunk - Mapping array -+ In: ui32MemFlags - page table flags. -+ In: hUniqueTag - A unique ID for use as a tag identifier -+ RETURNS: None -+******************************************************************************/ -+IMG_VOID -+MMU_MapPagesSparse (MMU_HEAP *pMMUHeap, -+ IMG_DEV_VIRTADDR DevVAddr, -+ IMG_SYS_PHYADDR SysPAddr, -+ IMG_UINT32 ui32ChunkSize, -+ IMG_UINT32 ui32NumVirtChunks, -+ IMG_UINT32 ui32NumPhysChunks, -+ IMG_BOOL *pabMapChunk, -+ IMG_UINT32 ui32MemFlags, -+ IMG_HANDLE hUniqueTag); -+ -+/* -+****************************************************************************** -+ FUNCTION: MMU_MapShadow -+ -+ PURPOSE: Create a mapping for a range of pages from a CPU virtual -+ adddress to a specified device virtual address. -+ -+ PARAMETERS: In: pMMUHeap - the mmu. -+ In: MapBaseDevVAddr - A page aligned device virtual address -+ to start mapping from. -+ In: uByteSize - A page aligned mapping length in bytes. -+ In: CpuVAddr - A page aligned CPU virtual address. -+ In: hOSMemHandle - An alternative OS specific memory handle -+ for mapping RAM without a CPU virtual -+ address -+ Out: pDevVAddr - deprecated -+ In: hUniqueTag - A unique ID for use as a tag identifier -+ In: ui32MemFlags - page table flags. -+ RETURNS: None -+******************************************************************************/ -+IMG_VOID -+MMU_MapShadow (MMU_HEAP * pMMUHeap, -+ IMG_DEV_VIRTADDR MapBaseDevVAddr, -+ IMG_SIZE_T uByteSize, -+ IMG_CPU_VIRTADDR CpuVAddr, -+ IMG_HANDLE hOSMemHandle, -+ IMG_DEV_VIRTADDR * pDevVAddr, -+ IMG_UINT32 ui32MemFlags, -+ IMG_HANDLE hUniqueTag); -+ -+/* -+****************************************************************************** -+ FUNCTION: MMU_MapShadowSparse -+ -+ PURPOSE: Create a mapping for a range of pages from a CPU virtual -+ adddress to a specified device virtual address. -+ -+ PARAMETERS: In: pMMUHeap - the mmu. -+ In: MapBaseDevVAddr - A page aligned device virtual address -+ to start mapping from. -+ In: ui32ChunkSize - Size of the chunk (must be page multiple) -+ In: ui32NumVirtChunks - Number of virtual chunks -+ In: ui32NumPhysChunks - Number of physical chunks -+ In: pabMapChunk - Mapping array -+ In: CpuVAddr - A page aligned CPU virtual address. -+ In: hOSMemHandle - An alternative OS specific memory handle -+ for mapping RAM without a CPU virtual -+ address -+ Out: pDevVAddr - deprecated -+ In: hUniqueTag - A unique ID for use as a tag identifier -+ In: ui32MemFlags - page table flags. -+ RETURNS: None -+******************************************************************************/ -+IMG_VOID -+MMU_MapShadowSparse (MMU_HEAP * pMMUHeap, -+ IMG_DEV_VIRTADDR MapBaseDevVAddr, -+ IMG_UINT32 ui32ChunkSize, -+ IMG_UINT32 ui32NumVirtChunks, -+ IMG_UINT32 ui32NumPhysChunks, -+ IMG_BOOL * pabMapChunk, -+ IMG_CPU_VIRTADDR CpuVAddr, -+ IMG_HANDLE hOSMemHandle, -+ IMG_DEV_VIRTADDR * pDevVAddr, -+ IMG_UINT32 ui32MemFlags, -+ IMG_HANDLE hUniqueTag); -+ -+/* -+****************************************************************************** -+ FUNCTION: MMU_UnmapPages -+ -+ PURPOSE: unmaps pages and invalidates virtual address. -+ -+ PARAMETERS: In: psMMUHeap - the mmu. -+ In: sDevVAddr - the device virtual address. -+ In: ui32PageCount - page count. -+ RETURNS: None -+******************************************************************************/ -+IMG_VOID -+MMU_UnmapPages (MMU_HEAP *psMMUHeap, -+ IMG_DEV_VIRTADDR sDevVAddr, -+ IMG_UINT32 ui32PageCount, -+ IMG_HANDLE hUniqueTag); -+ -+/* -+****************************************************************************** -+ FUNCTION: MMU_MapScatter -+ -+ PURPOSE: Create a mapping for a list of pages to a specified device -+ virtual address. -+ -+ PARAMETERS: In: pMMUHeap - the mmu. -+ In: DevVAddr - the device virtual address. -+ In: psSysAddr - the list of physical addresses of the pages to -+ map. -+ RETURNS: None -+******************************************************************************/ -+IMG_VOID -+MMU_MapScatter (MMU_HEAP *pMMUHeap, -+ IMG_DEV_VIRTADDR DevVAddr, -+ IMG_SYS_PHYADDR *psSysAddr, -+ IMG_SIZE_T uSize, -+ IMG_UINT32 ui32MemFlags, -+ IMG_HANDLE hUniqueTag); -+ -+ -+/* -+****************************************************************************** -+ FUNCTION: MMU_GetPhysPageAddr -+ -+ PURPOSE: extracts physical address from MMU page tables -+ -+ PARAMETERS: In: pMMUHeap - the mmu -+ PARAMETERS: In: sDevVPageAddr - the virtual address to extract physical -+ page mapping from -+ RETURNS: IMG_DEV_PHYADDR -+******************************************************************************/ -+IMG_DEV_PHYADDR -+MMU_GetPhysPageAddr(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR sDevVPageAddr); -+ -+ -+/* -+****************************************************************************** -+ FUNCTION: MMU_GetPDDevPAddr -+ -+ PURPOSE: returns PD given the MMU context (SGX to MMU API) -+ -+ PARAMETERS: In: pMMUContext - the mmu -+ RETURNS: IMG_DEV_PHYADDR -+******************************************************************************/ -+IMG_DEV_PHYADDR -+MMU_GetPDDevPAddr(MMU_CONTEXT *pMMUContext); -+ -+ -+#ifdef SUPPORT_SGX_MMU_BYPASS -+/* -+****************************************************************************** -+ FUNCTION: EnableHostAccess -+ -+ PURPOSE: Enables Host accesses to device memory, by passing the device -+ MMU address translation -+ -+ PARAMETERS: In: psMMUContext -+ RETURNS: None -+******************************************************************************/ -+IMG_VOID -+EnableHostAccess (MMU_CONTEXT *psMMUContext); -+ -+ -+/* -+****************************************************************************** -+ FUNCTION: DisableHostAccess -+ -+ PURPOSE: Disables Host accesses to device memory, by passing the device -+ MMU address translation -+ -+ PARAMETERS: In: psMMUContext -+ RETURNS: None -+******************************************************************************/ -+IMG_VOID -+DisableHostAccess (MMU_CONTEXT *psMMUContext); -+#endif -+ -+/* -+****************************************************************************** -+ FUNCTION: MMU_InvalidateDirectoryCache -+ -+ PURPOSE: Invalidates the page directory cache -+ -+ PARAMETERS: In: psDevInfo -+ RETURNS: None -+******************************************************************************/ -+IMG_VOID MMU_InvalidateDirectoryCache(PVRSRV_SGXDEV_INFO *psDevInfo); -+ -+/* -+****************************************************************************** -+ FUNCTION: MMU_BIFResetPDAlloc -+ -+ PURPOSE: Allocate a dummy Page Directory which causes all virtual -+ addresses to page fault. -+ -+ PARAMETERS: In: psDevInfo - device info -+ RETURNS: PVRSRV_OK or error -+******************************************************************************/ -+PVRSRV_ERROR MMU_BIFResetPDAlloc(PVRSRV_SGXDEV_INFO *psDevInfo); -+ -+/* -+****************************************************************************** -+ FUNCTION: MMU_BIFResetPDFree -+ -+ PURPOSE: Free resources allocated in MMU_BIFResetPDAlloc. -+ -+ PARAMETERS: In: psDevInfo - device info -+ RETURNS: -+******************************************************************************/ -+IMG_VOID MMU_BIFResetPDFree(PVRSRV_SGXDEV_INFO *psDevInfo); -+ -+#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE) -+/* -+****************************************************************************** -+ FUNCTION: MMU_MapExtSystemCacheRegs -+ -+ PURPOSE: maps external system cache control registers into SGX MMU -+ -+ PARAMETERS: In: psDeviceNode - device node -+ RETURNS: -+******************************************************************************/ -+PVRSRV_ERROR MMU_MapExtSystemCacheRegs(PVRSRV_DEVICE_NODE *psDeviceNode); -+ -+/* -+****************************************************************************** -+ FUNCTION: MMU_UnmapExtSystemCacheRegs -+ -+ PURPOSE: unmaps external system cache control registers -+ -+ PARAMETERS: In: psDeviceNode - device node -+ RETURNS: -+******************************************************************************/ -+PVRSRV_ERROR MMU_UnmapExtSystemCacheRegs(PVRSRV_DEVICE_NODE *psDeviceNode); -+#endif /* #if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE) */ -+ -+/* -+****************************************************************************** -+ FUNCTION: MMU_IsHeapShared -+ -+ PURPOSE: Is this heap shared? -+ PARAMETERS: In: pMMU_Heap -+ RETURNS: true if heap is shared -+******************************************************************************/ -+IMG_BOOL MMU_IsHeapShared(MMU_HEAP* pMMU_Heap); -+ -+#if defined(FIX_HW_BRN_31620) -+/* -+****************************************************************************** -+ FUNCTION: MMU_GetCacheFlushRange -+ -+ PURPOSE: Gets device physical address of the mmu context. -+ -+ PARAMETERS: In: pMMUContext - the mmu context -+ Out: pui32RangeMask - Bit mask showing which PD cache -+ lines have changed -+ RETURNS: None -+******************************************************************************/ -+IMG_VOID MMU_GetCacheFlushRange(MMU_CONTEXT *pMMUContext, IMG_UINT32 *pui32RangeMask); -+ -+/* -+****************************************************************************** -+ FUNCTION: MMU_GetPDPhysAddr -+ -+ PURPOSE: Gets device physical address of the mmu contexts PD. -+ -+ PARAMETERS: In: pMMUContext - the mmu context -+ Out: psDevPAddr - Address of PD -+ RETURNS: None -+******************************************************************************/ -+IMG_VOID MMU_GetPDPhysAddr(MMU_CONTEXT *pMMUContext, IMG_DEV_PHYADDR *psDevPAddr); -+ -+#endif -+ -+ -+IMG_VOID MMU_CheckFaultAddr(PVRSRV_SGXDEV_INFO *psDevInfo, IMG_UINT32 ui32PDDevPAddr, IMG_UINT32 ui32RegVal); -+ -+#if defined(PDUMP) -+/* -+****************************************************************************** -+ FUNCTION: MMU_GetPDumpContextID -+ -+ PURPOSE: translates device mem context to unique pdump identifier -+ -+ PARAMETERS: In: hDevMemContext - device memory per-process context -+ RETURNS: context identifier used internally in pdump -+******************************************************************************/ -+IMG_UINT32 MMU_GetPDumpContextID(IMG_HANDLE hDevMemContext); -+#endif /* #ifdef PDUMP */ -+ -+#endif /* #ifndef _MMU_H_ */ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/pb.c b/drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/pb.c -new file mode 100644 -index 0000000..4ed18bb ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/pb.c -@@ -0,0 +1,493 @@ -+/*************************************************************************/ /*! -+@Title Parameter Buffer management functions -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#include <stddef.h> -+ -+#include "services_headers.h" -+#include "sgx_bridge_km.h" -+#include "sgxapi_km.h" -+#include "sgxinfo.h" -+#include "sgxinfokm.h" -+#include "pvr_bridge_km.h" -+#include "pdump_km.h" -+#include "sgxutils.h" -+ -+#if !defined(__linux__) && !defined(__QNXNTO__) -+#pragma message("FIXME: Review use of OS_PAGEABLE vs OS_NON_PAGEABLE") -+#endif -+ -+#include "lists.h" -+ -+static IMPLEMENT_LIST_INSERT(PVRSRV_STUB_PBDESC) -+static IMPLEMENT_LIST_REMOVE(PVRSRV_STUB_PBDESC) -+ -+static PRESMAN_ITEM psResItemCreateSharedPB = IMG_NULL; -+static PVRSRV_PER_PROCESS_DATA *psPerProcCreateSharedPB = IMG_NULL; -+ -+static PVRSRV_ERROR SGXCleanupSharedPBDescCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param, IMG_BOOL bDummy); -+static PVRSRV_ERROR SGXCleanupSharedPBDescCreateLockCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param, IMG_BOOL bDummy); -+ -+/* override level pointer indirection */ -+/* PRQA S 5102 12 */ -+IMG_EXPORT PVRSRV_ERROR -+SGXFindSharedPBDescKM(PVRSRV_PER_PROCESS_DATA *psPerProc, -+ IMG_HANDLE hDevCookie, -+ IMG_BOOL bLockOnFailure, -+ IMG_UINT32 ui32TotalPBSize, -+ IMG_HANDLE *phSharedPBDesc, -+ PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescKernelMemInfo, -+ PVRSRV_KERNEL_MEM_INFO **ppsHWPBDescKernelMemInfo, -+ PVRSRV_KERNEL_MEM_INFO **ppsBlockKernelMemInfo, -+ PVRSRV_KERNEL_MEM_INFO **ppsHWBlockKernelMemInfo, -+ PVRSRV_KERNEL_MEM_INFO ***pppsSharedPBDescSubKernelMemInfos, -+ IMG_UINT32 *ui32SharedPBDescSubKernelMemInfosCount) -+{ -+ PVRSRV_STUB_PBDESC *psStubPBDesc; -+ PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescSubKernelMemInfos=IMG_NULL; -+ PVRSRV_SGXDEV_INFO *psSGXDevInfo; -+ PVRSRV_ERROR eError; -+ -+ psSGXDevInfo = ((PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice; -+ -+ psStubPBDesc = psSGXDevInfo->psStubPBDescListKM; -+ if (psStubPBDesc != IMG_NULL) -+ { -+ IMG_UINT32 i; -+ PRESMAN_ITEM psResItem; -+ -+ if(psStubPBDesc->ui32TotalPBSize != ui32TotalPBSize) -+ { -+ PVR_DPF((PVR_DBG_WARNING, -+ "SGXFindSharedPBDescKM: Shared PB requested with different size (0x%x) from existing shared PB (0x%x) - requested size ignored", -+ ui32TotalPBSize, psStubPBDesc->ui32TotalPBSize)); -+ } -+ -+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(PVRSRV_KERNEL_MEM_INFO *) -+ * psStubPBDesc->ui32SubKernelMemInfosCount, -+ (IMG_VOID **)&ppsSharedPBDescSubKernelMemInfos, -+ IMG_NULL, -+ "Array of Kernel Memory Info") != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SGXFindSharedPBDescKM: OSAllocMem failed")); -+ -+ eError = PVRSRV_ERROR_OUT_OF_MEMORY; -+ goto ExitNotFound; -+ } -+ -+ psResItem = ResManRegisterRes(psPerProc->hResManContext, -+ RESMAN_TYPE_SHARED_PB_DESC, -+ psStubPBDesc, -+ 0, -+ &SGXCleanupSharedPBDescCallback); -+ -+ if (psResItem == IMG_NULL) -+ { -+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, -+ sizeof(PVRSRV_KERNEL_MEM_INFO *) * psStubPBDesc->ui32SubKernelMemInfosCount, -+ ppsSharedPBDescSubKernelMemInfos, -+ 0); -+ /*not nulling pointer, out of scope*/ -+ -+ PVR_DPF((PVR_DBG_ERROR, "SGXFindSharedPBDescKM: ResManRegisterRes failed")); -+ -+ eError = PVRSRV_ERROR_UNABLE_TO_REGISTER_RESOURCE; -+ goto ExitNotFound; -+ } -+ -+ *ppsSharedPBDescKernelMemInfo = psStubPBDesc->psSharedPBDescKernelMemInfo; -+ *ppsHWPBDescKernelMemInfo = psStubPBDesc->psHWPBDescKernelMemInfo; -+ *ppsBlockKernelMemInfo = psStubPBDesc->psBlockKernelMemInfo; -+ *ppsHWBlockKernelMemInfo = psStubPBDesc->psHWBlockKernelMemInfo; -+ -+ *ui32SharedPBDescSubKernelMemInfosCount = -+ psStubPBDesc->ui32SubKernelMemInfosCount; -+ -+ *pppsSharedPBDescSubKernelMemInfos = ppsSharedPBDescSubKernelMemInfos; -+ -+ for(i=0; i<psStubPBDesc->ui32SubKernelMemInfosCount; i++) -+ { -+ ppsSharedPBDescSubKernelMemInfos[i] = -+ psStubPBDesc->ppsSubKernelMemInfos[i]; -+ } -+ -+ psStubPBDesc->ui32RefCount++; -+ *phSharedPBDesc = (IMG_HANDLE)psResItem; -+ return PVRSRV_OK; -+ } -+ -+ eError = PVRSRV_OK; -+ if (bLockOnFailure) -+ { -+ if (psResItemCreateSharedPB == IMG_NULL) -+ { -+ psResItemCreateSharedPB = ResManRegisterRes(psPerProc->hResManContext, -+ RESMAN_TYPE_SHARED_PB_DESC_CREATE_LOCK, -+ psPerProc, -+ 0, -+ &SGXCleanupSharedPBDescCreateLockCallback); -+ -+ if (psResItemCreateSharedPB == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SGXFindSharedPBDescKM: ResManRegisterRes failed")); -+ -+ eError = PVRSRV_ERROR_UNABLE_TO_REGISTER_RESOURCE; -+ goto ExitNotFound; -+ } -+ PVR_ASSERT(psPerProcCreateSharedPB == IMG_NULL); -+ psPerProcCreateSharedPB = psPerProc; -+ } -+ else -+ { -+ eError = PVRSRV_ERROR_PROCESSING_BLOCKED; -+ } -+ } -+ExitNotFound: -+ *phSharedPBDesc = IMG_NULL; -+ -+ return eError; -+} -+ -+ -+static PVRSRV_ERROR -+SGXCleanupSharedPBDescKM(PVRSRV_STUB_PBDESC *psStubPBDescIn) -+{ -+ /*PVRSRV_STUB_PBDESC **ppsStubPBDesc;*/ -+ IMG_UINT32 i; -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+ -+ psDeviceNode = (PVRSRV_DEVICE_NODE*)psStubPBDescIn->hDevCookie; -+ -+ psStubPBDescIn->ui32RefCount--; -+ if (psStubPBDescIn->ui32RefCount == 0) -+ { -+ IMG_DEV_VIRTADDR sHWPBDescDevVAddr = psStubPBDescIn->sHWPBDescDevVAddr; -+ List_PVRSRV_STUB_PBDESC_Remove(psStubPBDescIn); -+ for(i=0 ; i<psStubPBDescIn->ui32SubKernelMemInfosCount; i++) -+ { -+ PVRSRVFreeDeviceMemKM(psStubPBDescIn->hDevCookie, -+ psStubPBDescIn->ppsSubKernelMemInfos[i]); -+ } -+ -+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, -+ sizeof(PVRSRV_KERNEL_MEM_INFO *) * psStubPBDescIn->ui32SubKernelMemInfosCount, -+ psStubPBDescIn->ppsSubKernelMemInfos, -+ 0); -+ psStubPBDescIn->ppsSubKernelMemInfos = IMG_NULL; -+ -+ PVRSRVFreeSharedSysMemoryKM(psStubPBDescIn->psBlockKernelMemInfo); -+ -+ PVRSRVFreeDeviceMemKM(psStubPBDescIn->hDevCookie, psStubPBDescIn->psHWBlockKernelMemInfo); -+ -+ PVRSRVFreeDeviceMemKM(psStubPBDescIn->hDevCookie, psStubPBDescIn->psHWPBDescKernelMemInfo); -+ -+ PVRSRVFreeSharedSysMemoryKM(psStubPBDescIn->psSharedPBDescKernelMemInfo); -+ -+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, -+ sizeof(PVRSRV_STUB_PBDESC), -+ psStubPBDescIn, -+ 0); -+ /*not nulling pointer, copy on stack*/ -+ -+ /* signal the microkernel to clear its sTAHWPBDesc and s3DHWPBDesc values in sTA3DCtl */ -+ SGXCleanupRequest(psDeviceNode, -+ &sHWPBDescDevVAddr, -+ PVRSRV_CLEANUPCMD_PB, -+ CLEANUP_WITH_POLL); -+ } -+ return PVRSRV_OK; -+ /*return PVRSRV_ERROR_INVALID_PARAMS;*/ -+} -+ -+static PVRSRV_ERROR SGXCleanupSharedPBDescCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param, IMG_BOOL bDummy) -+{ -+ PVRSRV_STUB_PBDESC *psStubPBDesc = (PVRSRV_STUB_PBDESC *)pvParam; -+ -+ PVR_UNREFERENCED_PARAMETER(ui32Param); -+ PVR_UNREFERENCED_PARAMETER(bDummy); -+ -+ return SGXCleanupSharedPBDescKM(psStubPBDesc); -+} -+ -+static PVRSRV_ERROR SGXCleanupSharedPBDescCreateLockCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param, IMG_BOOL bDummy) -+{ -+#ifdef DEBUG -+ PVRSRV_PER_PROCESS_DATA *psPerProc = (PVRSRV_PER_PROCESS_DATA *)pvParam; -+ PVR_ASSERT(psPerProc == psPerProcCreateSharedPB); -+#else -+ PVR_UNREFERENCED_PARAMETER(pvParam); -+#endif -+ -+ PVR_UNREFERENCED_PARAMETER(ui32Param); -+ PVR_UNREFERENCED_PARAMETER(bDummy); -+ -+ psPerProcCreateSharedPB = IMG_NULL; -+ psResItemCreateSharedPB = IMG_NULL; -+ -+ return PVRSRV_OK; -+} -+ -+ -+IMG_EXPORT PVRSRV_ERROR -+SGXUnrefSharedPBDescKM(IMG_HANDLE hSharedPBDesc) -+{ -+ PVR_ASSERT(hSharedPBDesc != IMG_NULL); -+ -+ return ResManFreeResByPtr(hSharedPBDesc, CLEANUP_WITH_POLL); -+} -+ -+ -+IMG_EXPORT PVRSRV_ERROR -+SGXAddSharedPBDescKM(PVRSRV_PER_PROCESS_DATA *psPerProc, -+ IMG_HANDLE hDevCookie, -+ PVRSRV_KERNEL_MEM_INFO *psSharedPBDescKernelMemInfo, -+ PVRSRV_KERNEL_MEM_INFO *psHWPBDescKernelMemInfo, -+ PVRSRV_KERNEL_MEM_INFO *psBlockKernelMemInfo, -+ PVRSRV_KERNEL_MEM_INFO *psHWBlockKernelMemInfo, -+ IMG_UINT32 ui32TotalPBSize, -+ IMG_HANDLE *phSharedPBDesc, -+ PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescSubKernelMemInfos, -+ IMG_UINT32 ui32SharedPBDescSubKernelMemInfosCount, -+ IMG_DEV_VIRTADDR sHWPBDescDevVAddr) -+{ -+ PVRSRV_STUB_PBDESC *psStubPBDesc=IMG_NULL; -+ PVRSRV_ERROR eRet = PVRSRV_ERROR_INVALID_PERPROC; -+ IMG_UINT32 i; -+ PVRSRV_SGXDEV_INFO *psSGXDevInfo; -+ PRESMAN_ITEM psResItem; -+ -+ /* -+ * The caller must have previously called SGXFindSharedPBDesc with -+ * bLockOnFailure set, and not managed to find a suitable shared PB. -+ */ -+ if (psPerProcCreateSharedPB != psPerProc) -+ { -+ goto NoAdd; -+ } -+ else -+ { -+ PVR_ASSERT(psResItemCreateSharedPB != IMG_NULL); -+ -+ ResManFreeResByPtr(psResItemCreateSharedPB, CLEANUP_WITH_POLL); -+ -+ PVR_ASSERT(psResItemCreateSharedPB == IMG_NULL); -+ PVR_ASSERT(psPerProcCreateSharedPB == IMG_NULL); -+ } -+ -+ psSGXDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice; -+ -+ psStubPBDesc = psSGXDevInfo->psStubPBDescListKM; -+ if (psStubPBDesc != IMG_NULL) -+ { -+ if(psStubPBDesc->ui32TotalPBSize != ui32TotalPBSize) -+ { -+ PVR_DPF((PVR_DBG_WARNING, -+ "SGXAddSharedPBDescKM: Shared PB requested with different size (0x%x) from existing shared PB (0x%x) - requested size ignored", -+ ui32TotalPBSize, psStubPBDesc->ui32TotalPBSize)); -+ -+ } -+ -+ /* -+ * We make the caller think the add was successful, -+ * but return the existing shared PB desc rather than -+ * a new one. -+ */ -+ psResItem = ResManRegisterRes(psPerProc->hResManContext, -+ RESMAN_TYPE_SHARED_PB_DESC, -+ psStubPBDesc, -+ 0, -+ &SGXCleanupSharedPBDescCallback); -+ if (psResItem == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, -+ "SGXAddSharedPBDescKM: " -+ "Failed to register existing shared " -+ "PBDesc with the resource manager")); -+ goto NoAddKeepPB; -+ } -+ -+ /* -+ * The caller will unreference the PB desc after -+ * a successful add, so up the reference count. -+ */ -+ psStubPBDesc->ui32RefCount++; -+ -+ *phSharedPBDesc = (IMG_HANDLE)psResItem; -+ eRet = PVRSRV_OK; -+ goto NoAddKeepPB; -+ } -+ -+ if(OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, -+ sizeof(PVRSRV_STUB_PBDESC), -+ (IMG_VOID **)&psStubPBDesc, -+ 0, -+ "Stub Parameter Buffer Description") != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SGXAddSharedPBDescKM: Failed to alloc " -+ "StubPBDesc")); -+ eRet = PVRSRV_ERROR_OUT_OF_MEMORY; -+ goto NoAdd; -+ } -+ -+ -+ psStubPBDesc->ppsSubKernelMemInfos = IMG_NULL; -+ -+ if(OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, -+ sizeof(PVRSRV_KERNEL_MEM_INFO *) -+ * ui32SharedPBDescSubKernelMemInfosCount, -+ (IMG_VOID **)&psStubPBDesc->ppsSubKernelMemInfos, -+ 0, -+ "Array of Kernel Memory Info") != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SGXAddSharedPBDescKM: " -+ "Failed to alloc " -+ "StubPBDesc->ppsSubKernelMemInfos")); -+ eRet = PVRSRV_ERROR_OUT_OF_MEMORY; -+ goto NoAdd; -+ } -+ -+ if(PVRSRVDissociateMemFromResmanKM(psSharedPBDescKernelMemInfo) -+ != PVRSRV_OK) -+ { -+ goto NoAdd; -+ } -+ -+ if(PVRSRVDissociateMemFromResmanKM(psHWPBDescKernelMemInfo) -+ != PVRSRV_OK) -+ { -+ goto NoAdd; -+ } -+ -+ if(PVRSRVDissociateMemFromResmanKM(psBlockKernelMemInfo) -+ != PVRSRV_OK) -+ { -+ goto NoAdd; -+ } -+ -+ if(PVRSRVDissociateMemFromResmanKM(psHWBlockKernelMemInfo) -+ != PVRSRV_OK) -+ { -+ goto NoAdd; -+ } -+ -+ psStubPBDesc->ui32RefCount = 1; -+ psStubPBDesc->ui32TotalPBSize = ui32TotalPBSize; -+ psStubPBDesc->psSharedPBDescKernelMemInfo = psSharedPBDescKernelMemInfo; -+ psStubPBDesc->psHWPBDescKernelMemInfo = psHWPBDescKernelMemInfo; -+ psStubPBDesc->psBlockKernelMemInfo = psBlockKernelMemInfo; -+ psStubPBDesc->psHWBlockKernelMemInfo = psHWBlockKernelMemInfo; -+ -+ psStubPBDesc->ui32SubKernelMemInfosCount = -+ ui32SharedPBDescSubKernelMemInfosCount; -+ for(i=0; i<ui32SharedPBDescSubKernelMemInfosCount; i++) -+ { -+ psStubPBDesc->ppsSubKernelMemInfos[i] = ppsSharedPBDescSubKernelMemInfos[i]; -+ if(PVRSRVDissociateMemFromResmanKM(ppsSharedPBDescSubKernelMemInfos[i]) -+ != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SGXAddSharedPBDescKM: " -+ "Failed to dissociate shared PBDesc " -+ "from process")); -+ goto NoAdd; -+ } -+ } -+ -+ psStubPBDesc->sHWPBDescDevVAddr = sHWPBDescDevVAddr; -+ -+ psResItem = ResManRegisterRes(psPerProc->hResManContext, -+ RESMAN_TYPE_SHARED_PB_DESC, -+ psStubPBDesc, -+ 0, -+ &SGXCleanupSharedPBDescCallback); -+ if (psResItem == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SGXAddSharedPBDescKM: " -+ "Failed to register shared PBDesc " -+ " with the resource manager")); -+ goto NoAdd; -+ } -+ psStubPBDesc->hDevCookie = hDevCookie; -+ -+ /* Finally everything was prepared successfully so link the new -+ * PB in to place. */ -+ List_PVRSRV_STUB_PBDESC_Insert(&(psSGXDevInfo->psStubPBDescListKM), -+ psStubPBDesc); -+ -+ *phSharedPBDesc = (IMG_HANDLE)psResItem; -+ -+ return PVRSRV_OK; -+ -+NoAdd: -+ if(psStubPBDesc) -+ { -+ if(psStubPBDesc->ppsSubKernelMemInfos) -+ { -+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, -+ sizeof(PVRSRV_KERNEL_MEM_INFO *) * ui32SharedPBDescSubKernelMemInfosCount, -+ psStubPBDesc->ppsSubKernelMemInfos, -+ 0); -+ psStubPBDesc->ppsSubKernelMemInfos = IMG_NULL; -+ } -+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, -+ sizeof(PVRSRV_STUB_PBDESC), -+ psStubPBDesc, -+ 0); -+ /*not nulling pointer, out of scope*/ -+ } -+ -+NoAddKeepPB: -+ for (i = 0; i < ui32SharedPBDescSubKernelMemInfosCount; i++) -+ { -+ PVRSRVFreeDeviceMemKM(hDevCookie, ppsSharedPBDescSubKernelMemInfos[i]); -+ } -+ -+ PVRSRVFreeSharedSysMemoryKM(psSharedPBDescKernelMemInfo); -+ PVRSRVFreeDeviceMemKM(hDevCookie, psHWPBDescKernelMemInfo); -+ -+ PVRSRVFreeSharedSysMemoryKM(psBlockKernelMemInfo); -+ PVRSRVFreeDeviceMemKM(hDevCookie, psHWBlockKernelMemInfo); -+ -+ return eRet; -+} -+ -+/****************************************************************************** -+ End of file (pb.c) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/sgx_bridge_km.h b/drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/sgx_bridge_km.h -new file mode 100644 -index 0000000..260a265 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/sgx_bridge_km.h -@@ -0,0 +1,254 @@ -+/*************************************************************************/ /*! -+@Title SGX Bridge Functionality -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Header for the SGX Bridge code -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#if !defined(__SGX_BRIDGE_KM_H__) -+#define __SGX_BRIDGE_KM_H__ -+ -+#include "sgxapi_km.h" -+#include "sgxinfo.h" -+#include "sgxinfokm.h" -+#include "sgx_bridge.h" -+#include "pvr_bridge.h" -+#include "perproc.h" -+ -+#if defined (__cplusplus) -+extern "C" { -+#endif -+ -+IMG_IMPORT -+PVRSRV_ERROR SGXSubmitTransferKM(IMG_HANDLE hDevHandle, PVRSRV_TRANSFER_SGX_KICK *psKick); -+ -+#if defined(SGX_FEATURE_2D_HARDWARE) -+IMG_IMPORT -+PVRSRV_ERROR SGXSubmit2DKM(IMG_HANDLE hDevHandle, PVRSRV_2D_SGX_KICK *psKick); -+#endif -+ -+IMG_IMPORT -+PVRSRV_ERROR SGXDoKickKM(IMG_HANDLE hDevHandle, -+ SGX_CCB_KICK *psCCBKick); -+ -+IMG_IMPORT -+PVRSRV_ERROR SGXGetPhysPageAddrKM(IMG_HANDLE hDevMemHeap, -+ IMG_DEV_VIRTADDR sDevVAddr, -+ IMG_DEV_PHYADDR *pDevPAddr, -+ IMG_CPU_PHYADDR *pCpuPAddr); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV SGXGetMMUPDAddrKM(IMG_HANDLE hDevCookie, -+ IMG_HANDLE hDevMemContext, -+ IMG_DEV_PHYADDR *psPDDevPAddr); -+ -+IMG_IMPORT -+PVRSRV_ERROR SGXGetClientInfoKM(IMG_HANDLE hDevCookie, -+ SGX_CLIENT_INFO* psClientInfo); -+ -+IMG_IMPORT -+PVRSRV_ERROR SGXGetMiscInfoKM(PVRSRV_SGXDEV_INFO *psDevInfo, -+ SGX_MISC_INFO *psMiscInfo, -+ PVRSRV_DEVICE_NODE *psDeviceNode, -+ IMG_HANDLE hDevMemContext); -+ -+IMG_IMPORT -+PVRSRV_ERROR SGXReadHWPerfCBKM(IMG_HANDLE hDevHandle, -+ IMG_UINT32 ui32ArraySize, -+ PVRSRV_SGX_HWPERF_CB_ENTRY *psHWPerfCBData, -+ IMG_UINT32 *pui32DataCount, -+ IMG_UINT32 *pui32ClockSpeed, -+ IMG_UINT32 *pui32HostTimeStamp); -+ -+IMG_IMPORT -+PVRSRV_ERROR SGX2DQueryBlitsCompleteKM(PVRSRV_SGXDEV_INFO *psDevInfo, -+ PVRSRV_KERNEL_SYNC_INFO *psSyncInfo, -+ IMG_BOOL bWaitForComplete); -+ -+IMG_IMPORT -+PVRSRV_ERROR SGXGetInfoForSrvinitKM(IMG_HANDLE hDevHandle, -+ SGX_BRIDGE_INFO_FOR_SRVINIT *psInitInfo); -+ -+IMG_IMPORT -+PVRSRV_ERROR DevInitSGXPart2KM(PVRSRV_PER_PROCESS_DATA *psPerProc, -+ IMG_HANDLE hDevHandle, -+ SGX_BRIDGE_INIT_INFO *psInitInfo); -+ -+/*! -+ * ***************************************************************************** -+ * @brief Looks for a parameter buffer description that corresponds to -+ * a buffer of size ui32TotalPBSize, optionally taking the lock -+ * needed for SharedPBCreation on failure. -+ * -+ * Note if a PB Desc is found then its internal reference counter -+ * is automatically incremented. It is your responsability to call -+ * SGXUnrefSharedPBDesc to decrement this reference and free associated -+ * resources when you are done. -+ * -+ * If bLockOnFailure is set, and a suitable shared PB isn't found, -+ * an internal flag is set, allowing this process to create a -+ * shared PB. Any other process calling this function with -+ * bLockOnFailure set, will receive the return code -+ * PVRSRV_ERROR_PROCESSING_BLOCKED, indicating that it needs -+ * to retry the function call. The internal flag is cleared -+ * when this process creates a shared PB. -+ * -+ * Note: You are responsible for freeing the list returned in -+ * pppsSharedPBDescSubKernelMemInfos -+ * via OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, -+ * sizeof(PVRSRV_KERNEL_MEM_INFO *) -+ * * ui32SharedPBDescSubKernelMemInfosCount, -+ * ppsSharedPBDescSubKernelMemInfos, -+ * NULL); -+ * -+ * @param[in] psPerProc -+ * @param[in] hDevCookie -+ * @param[in] bLockOnError -+ * @param[in] ui32TotalPBSize -+ * @param[in] phSharedPBDesc -+ * @param[out] ppsSharedPBDescKernelMemInfo -+ * @param[out] ppsHWPBDescKernelMemInfo -+ * @param[out] pppsSharedPBDescSubKernelMemInfos A list of integral sub meminfos. -+ * @param[out] ui32SharedPBDescSubKernelMemInfosCount -+ * -+ * @return PVRSRV_ERROR -+ ********************************************************************************/ -+/* disable QAC pointer level check for over 2 */ -+/* PRQA S 5102++ */ -+IMG_IMPORT PVRSRV_ERROR -+SGXFindSharedPBDescKM(PVRSRV_PER_PROCESS_DATA *psPerProc, -+ IMG_HANDLE hDevCookie, -+ IMG_BOOL bLockOnFailure, -+ IMG_UINT32 ui32TotalPBSize, -+ IMG_HANDLE *phSharedPBDesc, -+ PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescKernelMemInfo, -+ PVRSRV_KERNEL_MEM_INFO **ppsHWPBDescKernelMemInfo, -+ PVRSRV_KERNEL_MEM_INFO **ppsBlockKernelMemInfo, -+ PVRSRV_KERNEL_MEM_INFO **ppsHWBlockKernelMemInfo, -+ PVRSRV_KERNEL_MEM_INFO ***pppsSharedPBDescSubKernelMemInfos, -+ IMG_UINT32 *ui32SharedPBDescSubKernelMemInfosCount); -+ -+/*! -+ * ***************************************************************************** -+ * @brief Decrements the reference counter and frees all userspace resources -+ * associated with a SharedPBDesc. -+ * -+ * @param hSharedPBDesc -+ * -+ * @return PVRSRV_ERROR -+ ********************************************************************************/ -+IMG_IMPORT PVRSRV_ERROR -+SGXUnrefSharedPBDescKM(IMG_HANDLE hSharedPBDesc); -+ -+/*! -+ * ***************************************************************************** -+ * @brief Links a new SharedPBDesc into a kernel managed list that can -+ * then be queried by other clients. -+ * -+ * As a side affect this function also dissociates the SharedPBDesc -+ * from the calling process so that the memory won't be freed if the -+ * process dies/exits. (The kernel assumes responsability over the -+ * memory at the same time) -+ * -+ * As well as the psSharedPBDescKernelMemInfo you must also pass -+ * a complete list of other meminfos that are integral to the -+ * shared PB description. (Although the kernel doesn't have direct -+ * access to the shared PB desc it still needs to be able to -+ * clean up all the associated resources when it is no longer -+ * in use.) -+ * -+ * If the dissociation fails then all the memory associated with -+ * the psSharedPBDescKernelMemInfo and all entries in psKernelMemInfos -+ * will be freed by kernel services! Because of this, you are -+ * responsible for freeing the corresponding client meminfos _before_ -+ * calling SGXAddSharedPBDescKM. -+ * -+ * This function will return an error unless a succesful call to -+ * SGXFindSharedPBDesc, with bLockOnFailure set, has been made. -+ * -+ * @param psPerProc -+ * @param hDevCookie -+ * @param psSharedPBDescKernelMemInfo -+ * @param psHWPBDescKernelMemInfo -+ * @param psBlockKernelMemInfo -+ * @param ui32TotalPBSize The size of the associated parameter buffer -+ * @param ppsSharedPBDescSubKernelMemInfos A list of other meminfos integral to -+ * the shared PB description. -+ * @param ui32SharedPBDescSubKernelMemInfosCount The number of entires in -+ * psKernelMemInfos -+ * @param sHWPBDescDevVAddr The device virtual address of the HWPBDesc -+ * -+ * @return PVRSRV_ERROR -+ ********************************************************************************/ -+IMG_IMPORT PVRSRV_ERROR -+SGXAddSharedPBDescKM(PVRSRV_PER_PROCESS_DATA *psPerProc, -+ IMG_HANDLE hDevCookie, -+ PVRSRV_KERNEL_MEM_INFO *psSharedPBDescKernelMemInfo, -+ PVRSRV_KERNEL_MEM_INFO *psHWPBDescKernelMemInfo, -+ PVRSRV_KERNEL_MEM_INFO *psBlockKernelMemInfo, -+ PVRSRV_KERNEL_MEM_INFO *psHWBlockKernelMemInfo, -+ IMG_UINT32 ui32TotalPBSize, -+ IMG_HANDLE *phSharedPBDesc, -+ PVRSRV_KERNEL_MEM_INFO **psSharedPBDescSubKernelMemInfos, -+ IMG_UINT32 ui32SharedPBDescSubKernelMemInfosCount, -+ IMG_DEV_VIRTADDR sHWPBDescDevVAddr); -+ -+ -+/*! -+ * ***************************************************************************** -+ * @brief Gets device information that is not intended to be passed -+ on beyond the srvclient libs. -+ * -+ * @param[in] hDevCookie -+ * @param[out] psSGXInternalDevInfo -+ * -+ * @return -+ ********************************************************************************/ -+IMG_IMPORT PVRSRV_ERROR -+SGXGetInternalDevInfoKM(IMG_HANDLE hDevCookie, -+ SGX_INTERNAL_DEVINFO *psSGXInternalDevInfo); -+ -+#if defined (__cplusplus) -+} -+#endif -+ -+#endif /* __SGX_BRIDGE_KM_H__ */ -+ -+/****************************************************************************** -+ End of file (sgx_bridge_km.h) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/sgxconfig.h b/drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/sgxconfig.h -new file mode 100644 -index 0000000..99b84a8 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/sgxconfig.h -@@ -0,0 +1,457 @@ -+/*************************************************************************/ /*! -+@Title device configuration -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#ifndef __SGXCONFIG_H__ -+#define __SGXCONFIG_H__ -+ -+#include "sgxdefs.h" -+ -+#define DEV_DEVICE_TYPE PVRSRV_DEVICE_TYPE_SGX -+#define DEV_DEVICE_CLASS PVRSRV_DEVICE_CLASS_3D -+ -+#define DEV_MAJOR_VERSION 1 -+#define DEV_MINOR_VERSION 0 -+ -+#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE) -+#define SGX_KERNEL_DATA_HEAP_OFFSET 0x00001000 -+#else -+#define SGX_KERNEL_DATA_HEAP_OFFSET 0x00000000 -+#endif -+ -+ -+#if SGX_FEATURE_ADDRESS_SPACE_SIZE == 32 -+#if defined(FIX_HW_BRN_31620) -+ #if defined(SGX_FEATURE_2D_HARDWARE) -+ #define SGX_2D_HEAP_BASE 0x04000000 -+ #define SGX_2D_HEAP_SIZE (0x08000000-0x04000000-0x00001000) -+ #endif -+ -+ #define SGX_GENERAL_HEAP_BASE 0x08000000 -+ #define SGX_GENERAL_HEAP_SIZE (0xB8000000-0x00001000) -+ -+ /* -+ * For hybrid PB we have to split virtual PB range between the shared -+ * PB and percontext PB due to the fact we only have one heap config -+ * per device. -+ * If hybrid PB is enabled we split the space according to HYBRID_SHARED_PB_SIZE. -+ * i.e. HYBRID_SHARED_PB_SIZE defines the size of the shared PB and the -+ * remainder is the size of the percontext PB. -+ * If hybrid PB is not enabled then we still create both heaps (helps keep -+ * the code clean) and define the size of the unused one to 0 -+ */ -+ -+ #define SGX_3DPARAMETERS_HEAP_SIZE 0x10000000 -+ -+ /* By default we split the PB 50/50 */ -+#if !defined(HYBRID_SHARED_PB_SIZE) -+ #define HYBRID_SHARED_PB_SIZE (SGX_3DPARAMETERS_HEAP_SIZE >> 1) -+#endif -+#if defined(SUPPORT_HYBRID_PB) -+ #define SGX_SHARED_3DPARAMETERS_SIZE (HYBRID_SHARED_PB_SIZE) -+ #define SGX_SHARED_3DPARAMETERS_HEAP_SIZE (HYBRID_SHARED_PB_SIZE-0x00001000) -+ #define SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE (SGX_3DPARAMETERS_HEAP_SIZE - SGX_SHARED_3DPARAMETERS_SIZE - 0x00001000) -+#else -+#if defined(SUPPORT_PERCONTEXT_PB) -+ #define SGX_SHARED_3DPARAMETERS_SIZE 0 -+ #define SGX_SHARED_3DPARAMETERS_HEAP_SIZE 0 -+ #define SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE (SGX_3DPARAMETERS_HEAP_SIZE - 0x00001000) -+#endif -+#if defined(SUPPORT_SHARED_PB) -+ #define SGX_SHARED_3DPARAMETERS_SIZE SGX_3DPARAMETERS_HEAP_SIZE -+ #define SGX_SHARED_3DPARAMETERS_HEAP_SIZE (SGX_3DPARAMETERS_HEAP_SIZE - 0x00001000) -+ #define SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE 0 -+#endif -+#endif -+ -+ #define SGX_SHARED_3DPARAMETERS_HEAP_BASE 0xC0000000 -+ /* Size is defined above */ -+ -+ #define SGX_PERCONTEXT_3DPARAMETERS_HEAP_BASE (SGX_SHARED_3DPARAMETERS_HEAP_BASE + SGX_SHARED_3DPARAMETERS_SIZE) -+ /* Size is defined above */ -+ -+ #define SGX_TADATA_HEAP_BASE 0xD0000000 -+ #define SGX_TADATA_HEAP_SIZE (0x0D000000-0x00001000) -+ -+ #define SGX_SYNCINFO_HEAP_BASE 0xE0000000 -+ #define SGX_SYNCINFO_HEAP_SIZE (0x01000000-0x00001000) -+ -+ #define SGX_PDSPIXEL_CODEDATA_HEAP_BASE 0xE4000000 -+ #define SGX_PDSPIXEL_CODEDATA_HEAP_SIZE (0x02000000-0x00001000) -+ -+ #define SGX_KERNEL_CODE_HEAP_BASE 0xE8000000 -+ #define SGX_KERNEL_CODE_HEAP_SIZE (0x00080000-0x00001000) -+ -+ #define SGX_PDSVERTEX_CODEDATA_HEAP_BASE 0xEC000000 -+ #define SGX_PDSVERTEX_CODEDATA_HEAP_SIZE (0x01C00000-0x00001000) -+ -+ #define SGX_KERNEL_DATA_HEAP_BASE (0xF0000000+SGX_KERNEL_DATA_HEAP_OFFSET) -+ #define SGX_KERNEL_DATA_HEAP_SIZE (0x03000000-(0x00001000+SGX_KERNEL_DATA_HEAP_OFFSET)) -+ -+ /* Actual Pixel and Vertex shared heaps sizes may be reduced by -+ * override - see SGX_USE_CODE_SEGMENT_RANGE_BITS.*/ -+ #define SGX_PIXELSHADER_HEAP_BASE 0xF4000000 -+ #define SGX_PIXELSHADER_HEAP_SIZE (0x05000000-0x00001000) -+ -+ #define SGX_VERTEXSHADER_HEAP_BASE 0xFC000000 -+ #define SGX_VERTEXSHADER_HEAP_SIZE (0x02000000-0x00001000) -+#else /* FIX_HW_BRN_31620 */ -+ #if defined(SGX_FEATURE_2D_HARDWARE) -+ #define SGX_2D_HEAP_BASE 0x00100000 -+ #define SGX_2D_HEAP_SIZE (0x08000000-0x00100000-0x00001000) -+ #endif -+ -+ #if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP) -+ #define SGX_GENERAL_MAPPING_HEAP_BASE 0x08000000 -+ #define SGX_GENERAL_MAPPING_HEAP_SIZE (0x08000000-0x00001000) -+ #endif -+ -+ #if !defined(SUPPORT_MEMORY_TILING) -+ #define SGX_GENERAL_HEAP_BASE 0x10000000 -+ #define SGX_GENERAL_HEAP_SIZE (0xC2000000-0x00001000) -+ #else -+ #include <sgx_msvdx_defs.h> -+ /* Create heaps with memory tiling enabled. -+ * SGX HW limit is 10 heaps. -+ */ -+ /* Tiled heap space is taken from general heap */ -+ #define SGX_GENERAL_HEAP_BASE 0x10000000 -+ #define SGX_GENERAL_HEAP_SIZE (0xB5000000-0x00001000) -+ -+ #define SGX_VPB_TILED_HEAP_STRIDE TILING_TILE_STRIDE_2K -+ #define SGX_VPB_TILED_HEAP_BASE 0xC5000000 -+ #define SGX_VPB_TILED_HEAP_SIZE (0x0D000000-0x00001000) -+ -+ /* Check tiled heap base alignment */ -+ #if((SGX_VPB_TILED_HEAP_BASE & SGX_BIF_TILING_ADDR_INV_MASK) != 0) -+ #error "sgxconfig.h: SGX_VPB_TILED_HEAP has insufficient alignment" -+ #endif -+ -+ #endif /* SUPPORT_MEMORY_TILING */ -+ -+ /* -+ * For hybrid PB we have to split virtual PB range between the shared -+ * PB and percontext PB due to the fact we only have one heap config -+ * per device. -+ * If hybrid PB is enabled we split the space according to HYBRID_SHARED_PB_SIZE. -+ * i.e. HYBRID_SHARED_PB_SIZE defines the size of the shared PB and the -+ * remainder is the size of the percontext PB. -+ * If hybrid PB is not enabled then we still create both heaps (helps keep -+ * the code clean) and define the size of the unused one to 0 -+ */ -+ -+ #define SGX_3DPARAMETERS_HEAP_SIZE 0x10000000 -+ -+ /* By default we split the PB 50/50 */ -+#if !defined(HYBRID_SHARED_PB_SIZE) -+ #define HYBRID_SHARED_PB_SIZE (SGX_3DPARAMETERS_HEAP_SIZE >> 1) -+#endif -+#if defined(SUPPORT_HYBRID_PB) -+ #define SGX_SHARED_3DPARAMETERS_SIZE (HYBRID_SHARED_PB_SIZE) -+ #define SGX_SHARED_3DPARAMETERS_HEAP_SIZE (HYBRID_SHARED_PB_SIZE-0x00001000) -+ #define SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE (SGX_3DPARAMETERS_HEAP_SIZE - SGX_SHARED_3DPARAMETERS_SIZE - 0x00001000) -+#else -+#if defined(SUPPORT_PERCONTEXT_PB) -+ #define SGX_SHARED_3DPARAMETERS_SIZE 0 -+ #define SGX_SHARED_3DPARAMETERS_HEAP_SIZE 0 -+ #define SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE (SGX_3DPARAMETERS_HEAP_SIZE - 0x00001000) -+#endif -+#if defined(SUPPORT_SHARED_PB) -+ #define SGX_SHARED_3DPARAMETERS_SIZE SGX_3DPARAMETERS_HEAP_SIZE -+ #define SGX_SHARED_3DPARAMETERS_HEAP_SIZE (SGX_3DPARAMETERS_HEAP_SIZE - 0x00001000) -+ #define SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE 0 -+#endif -+#endif -+ -+ #define SGX_SHARED_3DPARAMETERS_HEAP_BASE 0xD2000000 -+ /* Size is defined above */ -+ -+ #define SGX_PERCONTEXT_3DPARAMETERS_HEAP_BASE (SGX_SHARED_3DPARAMETERS_HEAP_BASE + SGX_SHARED_3DPARAMETERS_SIZE) -+ /* Size is defined above */ -+ -+ #define SGX_TADATA_HEAP_BASE 0xE2000000 -+ #define SGX_TADATA_HEAP_SIZE (0x0D000000-0x00001000) -+ -+ #define SGX_SYNCINFO_HEAP_BASE 0xEF000000 -+ #define SGX_SYNCINFO_HEAP_SIZE (0x01000000-0x00001000) -+ -+ #define SGX_PDSPIXEL_CODEDATA_HEAP_BASE 0xF0000000 -+ #define SGX_PDSPIXEL_CODEDATA_HEAP_SIZE (0x02000000-0x00001000) -+ -+ #define SGX_KERNEL_CODE_HEAP_BASE 0xF2000000 -+ #define SGX_KERNEL_CODE_HEAP_SIZE (0x00080000-0x00001000) -+ -+ #define SGX_PDSVERTEX_CODEDATA_HEAP_BASE 0xF2400000 -+ #define SGX_PDSVERTEX_CODEDATA_HEAP_SIZE (0x01C00000-0x00001000) -+ -+ #define SGX_KERNEL_DATA_HEAP_BASE (0xF4000000+SGX_KERNEL_DATA_HEAP_OFFSET) -+ #define SGX_KERNEL_DATA_HEAP_SIZE (0x05000000-(0x00001000+SGX_KERNEL_DATA_HEAP_OFFSET)) -+ -+ /* Actual Pixel and Vertex shared heaps sizes may be reduced by -+ * override - see SGX_USE_CODE_SEGMENT_RANGE_BITS.*/ -+ #define SGX_PIXELSHADER_HEAP_BASE 0xF9000000 -+ #define SGX_PIXELSHADER_HEAP_SIZE (0x05000000-0x00001000) -+ -+ #define SGX_VERTEXSHADER_HEAP_BASE 0xFE000000 -+ #define SGX_VERTEXSHADER_HEAP_SIZE (0x02000000-0x00001000) -+#endif /* FIX_HW_BRN_31620 */ -+ /* signal we've identified the core by the build */ -+ #define SGX_CORE_IDENTIFIED -+#endif /* SGX_FEATURE_ADDRESS_SPACE_SIZE == 32 */ -+ -+#if SGX_FEATURE_ADDRESS_SPACE_SIZE == 28 -+ -+#if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP) -+ #define SGX_GENERAL_MAPPING_HEAP_BASE 0x00001000 -+ #define SGX_GENERAL_MAPPING_HEAP_SIZE (0x01800000-0x00001000-0x00001000) -+ -+ #define SGX_GENERAL_HEAP_BASE 0x01800000 -+ #define SGX_GENERAL_HEAP_SIZE (0x07000000-0x00001000) -+ -+#else -+ #define SGX_GENERAL_HEAP_BASE 0x00001000 -+#if defined(SUPPORT_LARGE_GENERAL_HEAP) -+ #define SGX_GENERAL_HEAP_SIZE (0x0B800000-0x00001000-0x00001000) -+#else -+ #define SGX_GENERAL_HEAP_SIZE (0x08800000-0x00001000-0x00001000) -+#endif -+#endif -+ -+ /* -+ * For hybrid PB we have to split virtual PB range between the shared -+ * PB and percontext PB due to the fact we only have one heap config -+ * per device. -+ * If hybrid PB is enabled we split the space according to HYBRID_SHARED_PB_SIZE. -+ * i.e. HYBRID_SHARED_PB_SIZE defines the size of the shared PB and the -+ * remainder is the size of the percontext PB. -+ * If hybrid PB is not enabled then we still create both heaps (helps keep -+ * the code clean) and define the size of the unused one to 0 -+ */ -+#if defined(SUPPORT_LARGE_GENERAL_HEAP) -+ #define SGX_3DPARAMETERS_HEAP_SIZE 0x01000000 -+#else -+ #define SGX_3DPARAMETERS_HEAP_SIZE 0x04000000 -+#endif -+ -+ /* By default we split the PB 50/50 */ -+#if !defined(HYBRID_SHARED_PB_SIZE) -+ #define HYBRID_SHARED_PB_SIZE (SGX_3DPARAMETERS_HEAP_SIZE >> 1) -+#endif -+#if defined(SUPPORT_HYBRID_PB) -+ #define SGX_SHARED_3DPARAMETERS_SIZE (HYBRID_SHARED_PB_SIZE) -+ #define SGX_SHARED_3DPARAMETERS_HEAP_SIZE (HYBRID_SHARED_PB_SIZE-0x00001000) -+ #define SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE (SGX_3DPARAMETERS_HEAP_SIZE - SGX_SHARED_3DPARAMETERS_SIZE - 0x00001000) -+#else -+#if defined(SUPPORT_PERCONTEXT_PB) -+ #define SGX_SHARED_3DPARAMETERS_SIZE 0 -+ #define SGX_SHARED_3DPARAMETERS_HEAP_SIZE 0 -+ #define SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE (SGX_3DPARAMETERS_HEAP_SIZE - 0x00001000) -+#endif -+#if defined(SUPPORT_SHARED_PB) -+ #define SGX_SHARED_3DPARAMETERS_SIZE SGX_3DPARAMETERS_HEAP_SIZE -+ #define SGX_SHARED_3DPARAMETERS_HEAP_SIZE (SGX_3DPARAMETERS_HEAP_SIZE - 0x00001000) -+ #define SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE 0 -+#endif -+#endif -+ -+#if defined(SUPPORT_LARGE_GENERAL_HEAP) -+ #define SGX_SHARED_3DPARAMETERS_HEAP_BASE 0x0B800000 -+#else -+ #define SGX_SHARED_3DPARAMETERS_HEAP_BASE 0x08800000 -+#endif -+ -+ /* Size is defined above */ -+ -+ #define SGX_PERCONTEXT_3DPARAMETERS_HEAP_BASE (SGX_SHARED_3DPARAMETERS_HEAP_BASE + SGX_SHARED_3DPARAMETERS_SIZE) -+ /* Size is defined above */ -+ -+ #define SGX_TADATA_HEAP_BASE 0x0C800000 -+ #define SGX_TADATA_HEAP_SIZE (0x01000000-0x00001000) -+ -+ #define SGX_SYNCINFO_HEAP_BASE 0x0D800000 -+ #define SGX_SYNCINFO_HEAP_SIZE (0x00400000-0x00001000) -+ -+ #define SGX_PDSPIXEL_CODEDATA_HEAP_BASE 0x0DC00000 -+ #define SGX_PDSPIXEL_CODEDATA_HEAP_SIZE (0x00800000-0x00001000) -+ -+ #define SGX_KERNEL_CODE_HEAP_BASE 0x0E400000 -+ #define SGX_KERNEL_CODE_HEAP_SIZE (0x00080000-0x00001000) -+ -+ #define SGX_PDSVERTEX_CODEDATA_HEAP_BASE 0x0E800000 -+ #define SGX_PDSVERTEX_CODEDATA_HEAP_SIZE (0x00800000-0x00001000) -+ -+ #define SGX_KERNEL_DATA_HEAP_BASE (0x0F000000+SGX_KERNEL_DATA_HEAP_OFFSET) -+ #define SGX_KERNEL_DATA_HEAP_SIZE (0x00400000-(0x00001000+SGX_KERNEL_DATA_HEAP_OFFSET)) -+ -+ #define SGX_PIXELSHADER_HEAP_BASE 0x0F400000 -+ #define SGX_PIXELSHADER_HEAP_SIZE (0x00500000-0x00001000) -+ -+ #define SGX_VERTEXSHADER_HEAP_BASE 0x0FC00000 -+ #define SGX_VERTEXSHADER_HEAP_SIZE (0x00200000-0x00001000) -+ -+ /* signal we've identified the core by the build */ -+ #define SGX_CORE_IDENTIFIED -+ -+#endif /* SGX_FEATURE_ADDRESS_SPACE_SIZE == 28 */ -+ -+#if !defined(SGX_CORE_IDENTIFIED) -+ #error "sgxconfig.h: ERROR: unspecified SGX Core version" -+#endif -+ -+/********************************************************************************* -+ * -+ * SGX_PDSPIXEL_CODEDATA_HEAP_BASE + 64MB range must include PDSVERTEX_CODEDATA and KERNEL_CODE heaps -+ * -+ ********************************************************************************/ -+#if !defined (SGX_FEATURE_EDM_VERTEX_PDSADDR_FULL_RANGE) -+ #if ((SGX_KERNEL_CODE_HEAP_BASE + SGX_KERNEL_CODE_HEAP_SIZE - SGX_PDSPIXEL_CODEDATA_HEAP_BASE) > 0x4000000) -+ #error "sgxconfig.h: ERROR: SGX_KERNEL_CODE_HEAP_BASE out of range of SGX_PDSPIXEL_CODEDATA_HEAP_BASE" -+ #endif -+ -+ #if ((SGX_PDSVERTEX_CODEDATA_HEAP_BASE + SGX_PDSVERTEX_CODEDATA_HEAP_SIZE - SGX_PDSPIXEL_CODEDATA_HEAP_BASE) > 0x4000000) -+ #error "sgxconfig.h: ERROR: SGX_PDSVERTEX_CODEDATA_HEAP_BASE out of range of SGX_PDSPIXEL_CODEDATA_HEAP_BASE" -+ #endif -+#endif -+ -+/********************************************************************************* -+ * -+ * The General Mapping heap must be within the 2D requestor range of the 2D heap base -+ * -+ ********************************************************************************/ -+#if defined(SGX_FEATURE_2D_HARDWARE) && defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP) -+ #if ((SGX_GENERAL_MAPPING_HEAP_BASE + SGX_GENERAL_MAPPING_HEAP_SIZE - SGX_2D_HEAP_BASE) >= EUR_CR_BIF_TWOD_REQ_BASE_ADDR_MASK) -+ #error "sgxconfig.h: ERROR: SGX_GENERAL_MAPPING_HEAP inaccessable by 2D requestor" -+ #endif -+#endif -+ -+/********************************************************************************* -+ * -+ * The kernel code heap base must be aligned to a USSE code page -+ * -+ ********************************************************************************/ -+#if defined (EURASIA_USE_CODE_PAGE_SIZE) -+ #if ((SGX_KERNEL_CODE_HEAP_BASE & (EURASIA_USE_CODE_PAGE_SIZE - 1)) != 0) -+ #error "sgxconfig.h: ERROR: Kernel code heap base misalignment" -+ #endif -+#endif -+ -+/********************************************************************************* -+ * -+ * Heap overlap check -+ * -+ ********************************************************************************/ -+#if defined(SGX_FEATURE_2D_HARDWARE) -+ #if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP) -+ #if ((SGX_2D_HEAP_BASE + SGX_2D_HEAP_SIZE) >= SGX_GENERAL_MAPPING_HEAP_BASE) -+ #error "sgxconfig.h: ERROR: SGX_2D_HEAP overlaps SGX_GENERAL_MAPPING_HEAP" -+ #endif -+ #else -+ #if ((SGX_2D_HEAP_BASE + SGX_2D_HEAP_SIZE) >= SGX_GENERAL_HEAP_BASE) -+ #error "sgxconfig.h: ERROR: SGX_2D_HEAP overlaps SGX_GENERAL_HEAP_BASE" -+ #endif -+ #endif -+#endif -+ -+#if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP) -+ #if ((SGX_GENERAL_MAPPING_HEAP_BASE + SGX_GENERAL_MAPPING_HEAP_SIZE) >= SGX_GENERAL_HEAP_BASE) -+ #error "sgxconfig.h: ERROR: SGX_GENERAL_MAPPING_HEAP overlaps SGX_GENERAL_HEAP" -+ #endif -+#endif -+ -+#if defined(SUPPORT_HYBRID_PB) -+ #if ((HYBRID_SHARED_PB_SIZE + 0x000001000) > SGX_3DPARAMETERS_HEAP_SIZE) -+ #error "sgxconfig.h: ERROR: HYBRID_SHARED_PB_SIZE too large" -+ #endif -+#endif -+ -+#if defined(SUPPORT_MEMORY_TILING) -+ #if ((SGX_GENERAL_HEAP_BASE + SGX_GENERAL_HEAP_SIZE) >= SGX_VPB_TILED_HEAP_BASE) -+ #error "sgxconfig.h: ERROR: SGX_GENERAL_HEAP overlaps SGX_VPB_TILED_HEAP" -+ #endif -+ #if ((SGX_VPB_TILED_HEAP_BASE + SGX_VPB_TILED_HEAP_SIZE) >= SGX_SHARED_3DPARAMETERS_HEAP_BASE) -+ #error "sgxconfig.h: ERROR: SGX_VPB_TILED_HEAP overlaps SGX_3DPARAMETERS_HEAP" -+ #endif -+#else -+ #if ((SGX_GENERAL_HEAP_BASE + SGX_GENERAL_HEAP_SIZE) >= SGX_SHARED_3DPARAMETERS_HEAP_BASE) -+ #error "sgxconfig.h: ERROR: SGX_GENERAL_HEAP overlaps SGX_3DPARAMETERS_HEAP" -+ #endif -+#endif -+ -+#if (((SGX_PERCONTEXT_3DPARAMETERS_HEAP_BASE + SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE) >= SGX_TADATA_HEAP_BASE) && (SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE > 0)) -+ #error "sgxconfig.h: ERROR: SGX_PERCONTEXT_3DPARAMETERS_HEAP_BASE overlaps SGX_TADATA_HEAP" -+#endif -+ -+#if ((SGX_TADATA_HEAP_BASE + SGX_TADATA_HEAP_SIZE) >= SGX_SYNCINFO_HEAP_BASE) -+ #error "sgxconfig.h: ERROR: SGX_TADATA_HEAP overlaps SGX_SYNCINFO_HEAP" -+#endif -+ -+#if ((SGX_SYNCINFO_HEAP_BASE + SGX_SYNCINFO_HEAP_SIZE) >= SGX_PDSPIXEL_CODEDATA_HEAP_BASE) -+ #error "sgxconfig.h: ERROR: SGX_SYNCINFO_HEAP overlaps SGX_PDSPIXEL_CODEDATA_HEAP" -+#endif -+ -+#if ((SGX_PDSPIXEL_CODEDATA_HEAP_BASE + SGX_PDSPIXEL_CODEDATA_HEAP_SIZE) >= SGX_KERNEL_CODE_HEAP_BASE) -+ #error "sgxconfig.h: ERROR: SGX_PDSPIXEL_CODEDATA_HEAP overlaps SGX_KERNEL_CODE_HEAP" -+#endif -+ -+#if ((SGX_KERNEL_CODE_HEAP_BASE + SGX_KERNEL_CODE_HEAP_SIZE) >= SGX_PDSVERTEX_CODEDATA_HEAP_BASE) -+ #error "sgxconfig.h: ERROR: SGX_KERNEL_CODE_HEAP overlaps SGX_PDSVERTEX_CODEDATA_HEAP" -+#endif -+ -+#if ((SGX_PDSVERTEX_CODEDATA_HEAP_BASE + SGX_PDSVERTEX_CODEDATA_HEAP_SIZE) >= SGX_KERNEL_DATA_HEAP_BASE) -+ #error "sgxconfig.h: ERROR: SGX_PDSVERTEX_CODEDATA_HEAP overlaps SGX_KERNEL_DATA_HEAP" -+#endif -+ -+#if ((SGX_KERNEL_DATA_HEAP_BASE + SGX_KERNEL_DATA_HEAP_SIZE) >= SGX_PIXELSHADER_HEAP_BASE) -+ #error "sgxconfig.h: ERROR: SGX_KERNEL_DATA_HEAP overlaps SGX_PIXELSHADER_HEAP" -+#endif -+ -+#if ((SGX_PIXELSHADER_HEAP_BASE + SGX_PIXELSHADER_HEAP_SIZE) >= SGX_VERTEXSHADER_HEAP_BASE) -+ #error "sgxconfig.h: ERROR: SGX_PIXELSHADER_HEAP overlaps SGX_VERTEXSHADER_HEAP" -+#endif -+ -+#if ((SGX_VERTEXSHADER_HEAP_BASE + SGX_VERTEXSHADER_HEAP_SIZE) < SGX_VERTEXSHADER_HEAP_BASE) -+ #error "sgxconfig.h: ERROR: SGX_VERTEXSHADER_HEAP_BASE size cause wraparound" -+#endif -+ -+#endif /* __SGXCONFIG_H__ */ -+ -+/***************************************************************************** -+ End of file (sgxconfig.h) -+*****************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/sgxinfokm.h b/drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/sgxinfokm.h -new file mode 100644 -index 0000000..bf98fe4 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/sgxinfokm.h -@@ -0,0 +1,594 @@ -+/*************************************************************************/ /*! -+@Title SGX kernel services structues/functions -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Structures and inline functions for KM services component -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+#ifndef __SGXINFOKM_H__ -+#define __SGXINFOKM_H__ -+ -+#include "sgxdefs.h" -+#include "device.h" -+#include "power.h" -+#include "sysconfig.h" -+#include "sgxscript.h" -+#include "sgxinfo.h" -+ -+#if defined (__cplusplus) -+extern "C" { -+#endif -+ -+/****************************************************************************/ -+/* kernel only defines: */ -+/****************************************************************************/ -+/* SGXDeviceMap Flag defines */ -+#define SGX_HOSTPORT_PRESENT 0x00000001UL -+ -+ -+/* -+ SGX PDUMP register bank name (prefix) -+*/ -+#define SGX_PDUMPREG_NAME "SGXREG" -+ -+/****************************************************************************/ -+/* kernel only structures: */ -+/****************************************************************************/ -+ -+/*Forward declaration*/ -+typedef struct _PVRSRV_STUB_PBDESC_ PVRSRV_STUB_PBDESC; -+ -+ -+typedef struct _PVRSRV_SGX_CCB_INFO_ *PPVRSRV_SGX_CCB_INFO; -+ -+typedef struct _PVRSRV_SGXDEV_INFO_ -+{ -+ PVRSRV_DEVICE_TYPE eDeviceType; -+ PVRSRV_DEVICE_CLASS eDeviceClass; -+ -+ IMG_UINT8 ui8VersionMajor; -+ IMG_UINT8 ui8VersionMinor; -+ IMG_UINT32 ui32CoreConfig; -+ IMG_UINT32 ui32CoreFlags; -+ -+ /* Kernel mode linear address of device registers */ -+ IMG_PVOID pvRegsBaseKM; -+ -+#if defined(SGX_FEATURE_HOST_PORT) -+ /* Kernel mode linear address of host port */ -+ IMG_PVOID pvHostPortBaseKM; -+ /* HP size */ -+ IMG_UINT32 ui32HPSize; -+ /* HP syspaddr */ -+ IMG_SYS_PHYADDR sHPSysPAddr; -+#endif -+ -+ /* FIXME: The alloc for this should go through OSAllocMem in future */ -+ IMG_HANDLE hRegMapping; -+ -+ /* System physical address of device registers*/ -+ IMG_SYS_PHYADDR sRegsPhysBase; -+ /* Register region size in bytes */ -+ IMG_UINT32 ui32RegSize; -+ -+#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE) -+ /* external system cache register region size in bytes */ -+ IMG_UINT32 ui32ExtSysCacheRegsSize; -+ /* external system cache register device relative physical address */ -+ IMG_DEV_PHYADDR sExtSysCacheRegsDevPBase; -+ /* ptr to page table */ -+ IMG_UINT32 *pui32ExtSystemCacheRegsPT; -+ /* handle to page table alloc/mapping */ -+ IMG_HANDLE hExtSystemCacheRegsPTPageOSMemHandle; -+ /* sys phys addr of PT */ -+ IMG_SYS_PHYADDR sExtSystemCacheRegsPTSysPAddr; -+#endif -+ -+ /* SGX clock speed */ -+ IMG_UINT32 ui32CoreClockSpeed; -+ IMG_UINT32 ui32uKernelTimerClock; -+ IMG_BOOL bSGXIdle; -+ -+ PVRSRV_STUB_PBDESC *psStubPBDescListKM; -+ -+ -+ /* kernel memory context info */ -+ IMG_DEV_PHYADDR sKernelPDDevPAddr; -+ -+ IMG_UINT32 ui32HeapCount; /*!< heap count */ -+ IMG_VOID *pvDeviceMemoryHeap; -+ PPVRSRV_KERNEL_MEM_INFO psKernelCCBMemInfo; /*!< meminfo for CCB in device accessible memory */ -+ PVRSRV_SGX_KERNEL_CCB *psKernelCCB; /*!< kernel mode linear address of CCB in device accessible memory */ -+ PPVRSRV_SGX_CCB_INFO psKernelCCBInfo; /*!< CCB information structure */ -+ PPVRSRV_KERNEL_MEM_INFO psKernelCCBCtlMemInfo; /*!< meminfo for CCB control in device accessible memory */ -+ PVRSRV_SGX_CCB_CTL *psKernelCCBCtl; /*!< kernel mode linear address of CCB control in device accessible memory */ -+ PPVRSRV_KERNEL_MEM_INFO psKernelCCBEventKickerMemInfo; /*!< meminfo for kernel CCB event kicker */ -+ IMG_UINT32 *pui32KernelCCBEventKicker; /*!< kernel mode linear address of kernel CCB event kicker */ -+#if defined(PDUMP) -+ IMG_UINT32 ui32KernelCCBEventKickerDumpVal; /*!< pdump copy of the kernel CCB event kicker */ -+#endif /* PDUMP */ -+ PVRSRV_KERNEL_MEM_INFO *psKernelSGXMiscMemInfo; /*!< kernel mode linear address of SGX misc info buffer */ -+ IMG_UINT32 aui32HostKickAddr[SGXMKIF_CMD_MAX]; /*!< ukernel host kick offests */ -+#if defined(SGX_SUPPORT_HWPROFILING) -+ PPVRSRV_KERNEL_MEM_INFO psKernelHWProfilingMemInfo; -+#endif -+ PPVRSRV_KERNEL_MEM_INFO psKernelHWPerfCBMemInfo; /*!< Meminfo for hardware performace circular buffer */ -+ PPVRSRV_KERNEL_MEM_INFO psKernelTASigBufferMemInfo; /*!< Meminfo for TA signature buffer */ -+ PPVRSRV_KERNEL_MEM_INFO psKernel3DSigBufferMemInfo; /*!< Meminfo for 3D signature buffer */ -+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && \ -+ defined(FIX_HW_BRN_33657) && defined(SUPPORT_SECURE_33657_FIX) -+ PPVRSRV_KERNEL_MEM_INFO psKernelVDMStateUpdateBufferMemInfo; /*!< Meminfo for state update buffer */ -+#endif -+#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG) -+ PPVRSRV_KERNEL_MEM_INFO psKernelEDMStatusBufferMemInfo; /*!< Meminfo for EDM status buffer */ -+#endif -+ /* Client reference count */ -+ IMG_UINT32 ui32ClientRefCount; -+ -+ /* cache control word for micro kernel cache flush/invalidates */ -+ IMG_UINT32 ui32CacheControl; -+ -+ /* client-side build options */ -+ IMG_UINT32 ui32ClientBuildOptions; -+ -+ /* client-side microkernel structure sizes */ -+ SGX_MISCINFO_STRUCT_SIZES sSGXStructSizes; -+ -+ /* -+ if we don't preallocate the pagetables we must -+ insert newly allocated page tables dynamically -+ */ -+ IMG_VOID *pvMMUContextList; -+ -+ /* Copy of registry ForcePTOff entry */ -+ IMG_BOOL bForcePTOff; -+ -+ IMG_UINT32 ui32EDMTaskReg0; -+ IMG_UINT32 ui32EDMTaskReg1; -+ -+ IMG_UINT32 ui32ClkGateCtl; -+ IMG_UINT32 ui32ClkGateCtl2; -+ IMG_UINT32 ui32ClkGateStatusReg; -+ IMG_UINT32 ui32ClkGateStatusMask; -+#if defined(SGX_FEATURE_MP) -+ IMG_UINT32 ui32MasterClkGateStatusReg; -+ IMG_UINT32 ui32MasterClkGateStatusMask; -+ IMG_UINT32 ui32MasterClkGateStatus2Reg; -+ IMG_UINT32 ui32MasterClkGateStatus2Mask; -+#endif /* SGX_FEATURE_MP */ -+ SGX_INIT_SCRIPTS sScripts; -+ -+ /* Members associated with dummy PD needed for BIF reset */ -+ IMG_HANDLE hBIFResetPDOSMemHandle; -+ IMG_DEV_PHYADDR sBIFResetPDDevPAddr; -+ IMG_DEV_PHYADDR sBIFResetPTDevPAddr; -+ IMG_DEV_PHYADDR sBIFResetPageDevPAddr; -+ IMG_UINT32 *pui32BIFResetPD; -+ IMG_UINT32 *pui32BIFResetPT; -+ -+ -+#if defined(SUPPORT_HW_RECOVERY) -+ /* Timeout callback handle */ -+ IMG_HANDLE hTimer; -+ /* HW recovery Time stamp */ -+ IMG_UINT32 ui32TimeStamp; -+#endif -+ -+ /* Number of SGX resets */ -+ IMG_UINT32 ui32NumResets; -+ -+ /* host control */ -+ PVRSRV_KERNEL_MEM_INFO *psKernelSGXHostCtlMemInfo; -+ SGXMKIF_HOST_CTL *psSGXHostCtl; -+ -+ /* TA/3D control */ -+ PVRSRV_KERNEL_MEM_INFO *psKernelSGXTA3DCtlMemInfo; -+ -+#if defined(FIX_HW_BRN_31272) || defined(FIX_HW_BRN_31780) || defined(FIX_HW_BRN_33920) -+ PVRSRV_KERNEL_MEM_INFO *psKernelSGXPTLAWriteBackMemInfo; -+#endif -+ -+ IMG_UINT32 ui32Flags; -+ -+ /* memory tiling range usage */ -+ IMG_UINT32 ui32MemTilingUsage; -+ -+ #if defined(PDUMP) -+ PVRSRV_SGX_PDUMP_CONTEXT sPDContext; -+ #endif -+ -+#if defined(SUPPORT_SGX_MMU_DUMMY_PAGE) -+ /* SGX MMU dummy page details */ -+ IMG_VOID *pvDummyPTPageCpuVAddr; -+ IMG_DEV_PHYADDR sDummyPTDevPAddr; -+ IMG_HANDLE hDummyPTPageOSMemHandle; -+ IMG_VOID *pvDummyDataPageCpuVAddr; -+ IMG_DEV_PHYADDR sDummyDataDevPAddr; -+ IMG_HANDLE hDummyDataPageOSMemHandle; -+#endif -+#if defined(PDUMP) -+ PDUMP_MMU_ATTRIB sMMUAttrib; -+#endif -+ IMG_UINT32 asSGXDevData[SGX_MAX_DEV_DATA]; -+ -+#if defined(FIX_HW_BRN_31620) -+ /* Dummy page refs */ -+ IMG_VOID *pvBRN31620DummyPageCpuVAddr; -+ IMG_HANDLE hBRN31620DummyPageOSMemHandle; -+ IMG_DEV_PHYADDR sBRN31620DummyPageDevPAddr; -+ -+ /* Dummy PT refs */ -+ IMG_VOID *pvBRN31620DummyPTCpuVAddr; -+ IMG_HANDLE hBRN31620DummyPTOSMemHandle; -+ IMG_DEV_PHYADDR sBRN31620DummyPTDevPAddr; -+ -+ IMG_HANDLE hKernelMMUContext; -+#endif -+ -+} PVRSRV_SGXDEV_INFO; -+ -+ -+typedef struct _SGX_TIMING_INFORMATION_ -+{ -+ IMG_UINT32 ui32CoreClockSpeed; -+ IMG_UINT32 ui32HWRecoveryFreq; -+ IMG_BOOL bEnableActivePM; -+ IMG_UINT32 ui32ActivePowManLatencyms; -+ IMG_UINT32 ui32uKernelFreq; -+} SGX_TIMING_INFORMATION; -+ -+/* FIXME Rename this structure to sg more generalised as it's been extended*/ -+/* SGX device map */ -+typedef struct _SGX_DEVICE_MAP_ -+{ -+ IMG_UINT32 ui32Flags; -+ -+ /* Registers */ -+ IMG_SYS_PHYADDR sRegsSysPBase; -+ IMG_CPU_PHYADDR sRegsCpuPBase; -+ IMG_CPU_VIRTADDR pvRegsCpuVBase; -+ IMG_UINT32 ui32RegsSize; -+ -+#if defined(SGX_FEATURE_HOST_PORT) -+ IMG_SYS_PHYADDR sHPSysPBase; -+ IMG_CPU_PHYADDR sHPCpuPBase; -+ IMG_UINT32 ui32HPSize; -+#endif -+ -+ /* Local Device Memory Region: (if present) */ -+ IMG_SYS_PHYADDR sLocalMemSysPBase; -+ IMG_DEV_PHYADDR sLocalMemDevPBase; -+ IMG_CPU_PHYADDR sLocalMemCpuPBase; -+ IMG_UINT32 ui32LocalMemSize; -+ -+#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE) -+ IMG_UINT32 ui32ExtSysCacheRegsSize; -+ IMG_DEV_PHYADDR sExtSysCacheRegsDevPBase; -+#endif -+ -+ /* device interrupt IRQ */ -+ IMG_UINT32 ui32IRQ; -+ -+#if !defined(SGX_DYNAMIC_TIMING_INFO) -+ /* timing information*/ -+ SGX_TIMING_INFORMATION sTimingInfo; -+#endif -+#if defined(PDUMP) -+ /* pdump memory region name */ -+ IMG_CHAR *pszPDumpDevName; -+#endif -+} SGX_DEVICE_MAP; -+ -+ -+struct _PVRSRV_STUB_PBDESC_ -+{ -+ IMG_UINT32 ui32RefCount; -+ IMG_UINT32 ui32TotalPBSize; -+ PVRSRV_KERNEL_MEM_INFO *psSharedPBDescKernelMemInfo; -+ PVRSRV_KERNEL_MEM_INFO *psHWPBDescKernelMemInfo; -+ PVRSRV_KERNEL_MEM_INFO **ppsSubKernelMemInfos; -+ IMG_UINT32 ui32SubKernelMemInfosCount; -+ IMG_HANDLE hDevCookie; -+ PVRSRV_KERNEL_MEM_INFO *psBlockKernelMemInfo; -+ PVRSRV_KERNEL_MEM_INFO *psHWBlockKernelMemInfo; -+ IMG_DEV_VIRTADDR sHWPBDescDevVAddr; -+ PVRSRV_STUB_PBDESC *psNext; -+ PVRSRV_STUB_PBDESC **ppsThis; -+}; -+ -+/*! -+ ****************************************************************************** -+ * CCB control structure for SGX -+ *****************************************************************************/ -+typedef struct _PVRSRV_SGX_CCB_INFO_ -+{ -+ PVRSRV_KERNEL_MEM_INFO *psCCBMemInfo; /*!< meminfo for CCB in device accessible memory */ -+ PVRSRV_KERNEL_MEM_INFO *psCCBCtlMemInfo; /*!< meminfo for CCB control in device accessible memory */ -+ SGXMKIF_COMMAND *psCommands; /*!< linear address of the array of commands */ -+ IMG_UINT32 *pui32WriteOffset; /*!< linear address of the write offset into array of commands */ -+ volatile IMG_UINT32 *pui32ReadOffset; /*!< linear address of the read offset into array of commands */ -+#if defined(PDUMP) -+ IMG_UINT32 ui32CCBDumpWOff; /*!< for pdumping */ -+#endif -+} PVRSRV_SGX_CCB_INFO; -+ -+ -+typedef struct _SGX_BRIDGE_INIT_INFO_KM_ -+{ -+ IMG_HANDLE hKernelCCBMemInfo; -+ IMG_HANDLE hKernelCCBCtlMemInfo; -+ IMG_HANDLE hKernelCCBEventKickerMemInfo; -+ IMG_HANDLE hKernelSGXHostCtlMemInfo; -+ IMG_HANDLE hKernelSGXTA3DCtlMemInfo; -+#if defined(FIX_HW_BRN_31272) || defined(FIX_HW_BRN_31780) || defined(FIX_HW_BRN_33920) -+ IMG_HANDLE hKernelSGXPTLAWriteBackMemInfo; -+#endif -+ IMG_HANDLE hKernelSGXMiscMemInfo; -+ -+ IMG_UINT32 aui32HostKickAddr[SGXMKIF_CMD_MAX]; -+ -+ SGX_INIT_SCRIPTS sScripts; -+ -+ IMG_UINT32 ui32ClientBuildOptions; -+ SGX_MISCINFO_STRUCT_SIZES sSGXStructSizes; -+ -+#if defined(SGX_SUPPORT_HWPROFILING) -+ IMG_HANDLE hKernelHWProfilingMemInfo; -+#endif -+#if defined(SUPPORT_SGX_HWPERF) -+ IMG_HANDLE hKernelHWPerfCBMemInfo; -+#endif -+ IMG_HANDLE hKernelTASigBufferMemInfo; -+ IMG_HANDLE hKernel3DSigBufferMemInfo; -+ -+#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG) -+ IMG_HANDLE hKernelEDMStatusBufferMemInfo; -+#endif -+ -+ IMG_UINT32 ui32EDMTaskReg0; -+ IMG_UINT32 ui32EDMTaskReg1; -+ -+ IMG_UINT32 ui32ClkGateStatusReg; -+ IMG_UINT32 ui32ClkGateStatusMask; -+#if defined(SGX_FEATURE_MP) -+// IMG_UINT32 ui32MasterClkGateStatusReg; -+// IMG_UINT32 ui32MasterClkGateStatusMask; -+// IMG_UINT32 ui32MasterClkGateStatus2Reg; -+// IMG_UINT32 ui32MasterClkGateStatus2Mask; -+#endif /* SGX_FEATURE_MP */ -+ -+ IMG_UINT32 ui32CacheControl; -+ -+ IMG_UINT32 asInitDevData[SGX_MAX_DEV_DATA]; -+ IMG_HANDLE asInitMemHandles[SGX_MAX_INIT_MEM_HANDLES]; -+ -+} SGX_BRIDGE_INIT_INFO_KM; -+ -+ -+typedef struct _SGX_INTERNEL_STATUS_UPDATE_KM_ -+{ -+ CTL_STATUS sCtlStatus; -+ IMG_HANDLE hKernelMemInfo; -+} SGX_INTERNEL_STATUS_UPDATE_KM; -+ -+ -+typedef struct _SGX_CCB_KICK_KM_ -+{ -+ SGXMKIF_COMMAND sCommand; -+ IMG_HANDLE hCCBKernelMemInfo; -+ -+ IMG_UINT32 ui32NumDstSyncObjects; -+ IMG_HANDLE hKernelHWSyncListMemInfo; -+ -+ /* DST syncs */ -+ IMG_HANDLE *pahDstSyncHandles; -+ -+ IMG_UINT32 ui32NumTAStatusVals; -+ IMG_UINT32 ui32Num3DStatusVals; -+ -+#if defined(SUPPORT_SGX_NEW_STATUS_VALS) -+ SGX_INTERNEL_STATUS_UPDATE_KM asTAStatusUpdate[SGX_MAX_TA_STATUS_VALS]; -+ SGX_INTERNEL_STATUS_UPDATE_KM as3DStatusUpdate[SGX_MAX_3D_STATUS_VALS]; -+#else -+ IMG_HANDLE ahTAStatusSyncInfo[SGX_MAX_TA_STATUS_VALS]; -+ IMG_HANDLE ah3DStatusSyncInfo[SGX_MAX_3D_STATUS_VALS]; -+#endif -+ -+ IMG_BOOL bFirstKickOrResume; -+#if defined(NO_HARDWARE) || defined(PDUMP) -+ IMG_BOOL bTerminateOrAbort; -+#endif -+ -+ /* CCB offset of data structure associated with this kick */ -+ IMG_UINT32 ui32CCBOffset; -+ -+#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS) -+ /* SRC and DST syncs */ -+ IMG_UINT32 ui32NumTASrcSyncs; -+ IMG_HANDLE ahTASrcKernelSyncInfo[SGX_MAX_TA_SRC_SYNCS]; -+ IMG_UINT32 ui32NumTADstSyncs; -+ IMG_HANDLE ahTADstKernelSyncInfo[SGX_MAX_TA_DST_SYNCS]; -+ IMG_UINT32 ui32Num3DSrcSyncs; -+ IMG_HANDLE ah3DSrcKernelSyncInfo[SGX_MAX_3D_SRC_SYNCS]; -+#else -+ /* SRC syncs */ -+ IMG_UINT32 ui32NumSrcSyncs; -+ IMG_HANDLE ahSrcKernelSyncInfo[SGX_MAX_SRC_SYNCS_TA]; -+#endif -+ -+ /* TA/3D dependency data */ -+ IMG_BOOL bTADependency; -+ IMG_HANDLE hTA3DSyncInfo; -+ -+ IMG_HANDLE hTASyncInfo; -+ IMG_HANDLE h3DSyncInfo; -+#if defined(PDUMP) -+ IMG_UINT32 ui32CCBDumpWOff; -+#endif -+#if defined(NO_HARDWARE) -+ IMG_UINT32 ui32WriteOpsPendingVal; -+#endif -+} SGX_CCB_KICK_KM; -+ -+ -+#if defined(TRANSFER_QUEUE) -+typedef struct _PVRSRV_TRANSFER_SGX_KICK_KM_ -+{ -+ IMG_HANDLE hCCBMemInfo; -+ IMG_UINT32 ui32SharedCmdCCBOffset; -+ -+ IMG_DEV_VIRTADDR sHWTransferContextDevVAddr; -+ -+ IMG_HANDLE hTASyncInfo; -+ IMG_HANDLE h3DSyncInfo; -+ -+ IMG_UINT32 ui32NumSrcSync; -+ IMG_HANDLE ahSrcSyncInfo[SGX_MAX_TRANSFER_SYNC_OPS]; -+ -+ IMG_UINT32 ui32NumDstSync; -+ IMG_HANDLE ahDstSyncInfo[SGX_MAX_TRANSFER_SYNC_OPS]; -+ -+ IMG_UINT32 ui32Flags; -+ -+ IMG_UINT32 ui32PDumpFlags; -+#if defined(PDUMP) -+ IMG_UINT32 ui32CCBDumpWOff; -+#endif -+} PVRSRV_TRANSFER_SGX_KICK_KM, *PPVRSRV_TRANSFER_SGX_KICK_KM; -+ -+#if defined(SGX_FEATURE_2D_HARDWARE) -+typedef struct _PVRSRV_2D_SGX_KICK_KM_ -+{ -+ IMG_HANDLE hCCBMemInfo; -+ IMG_UINT32 ui32SharedCmdCCBOffset; -+ -+ IMG_DEV_VIRTADDR sHW2DContextDevVAddr; -+ -+ IMG_UINT32 ui32NumSrcSync; -+ IMG_HANDLE ahSrcSyncInfo[SGX_MAX_2D_SRC_SYNC_OPS]; -+ -+ /* need to be able to check reads and writes on dest, and update writes */ -+ IMG_HANDLE hDstSyncInfo; -+ -+ /* need to be able to check reads and writes on TA ops, and update writes */ -+ IMG_HANDLE hTASyncInfo; -+ -+ /* need to be able to check reads and writes on 2D ops, and update writes */ -+ IMG_HANDLE h3DSyncInfo; -+ -+ IMG_UINT32 ui32PDumpFlags; -+#if defined(PDUMP) -+ IMG_UINT32 ui32CCBDumpWOff; -+#endif -+} PVRSRV_2D_SGX_KICK_KM, *PPVRSRV_2D_SGX_KICK_KM; -+#endif /* defined(SGX_FEATURE_2D_HARDWARE) */ -+#endif /* #if defined(TRANSFER_QUEUE) */ -+ -+/****************************************************************************/ -+/* kernel only functions prototypes */ -+/****************************************************************************/ -+PVRSRV_ERROR SGXRegisterDevice (PVRSRV_DEVICE_NODE *psDeviceNode); -+ -+IMG_VOID SGXOSTimer(IMG_VOID *pvData); -+ -+IMG_VOID SGXReset(PVRSRV_SGXDEV_INFO *psDevInfo, -+ IMG_BOOL bHardwareRecovery, -+ IMG_UINT32 ui32PDUMPFlags); -+ -+IMG_VOID SGXInitClocks(PVRSRV_SGXDEV_INFO *psDevInfo, -+ IMG_UINT32 ui32PDUMPFlags); -+ -+PVRSRV_ERROR SGXInitialise(PVRSRV_SGXDEV_INFO *psDevInfo, -+ IMG_BOOL bHardwareRecovery); -+PVRSRV_ERROR SGXDeinitialise(IMG_HANDLE hDevCookie); -+ -+PVRSRV_ERROR SGXPrePowerState(IMG_HANDLE hDevHandle, -+ PVRSRV_DEV_POWER_STATE eNewPowerState, -+ PVRSRV_DEV_POWER_STATE eCurrentPowerState); -+ -+PVRSRV_ERROR SGXPostPowerState(IMG_HANDLE hDevHandle, -+ PVRSRV_DEV_POWER_STATE eNewPowerState, -+ PVRSRV_DEV_POWER_STATE eCurrentPowerState); -+ -+PVRSRV_ERROR SGXPreClockSpeedChange(IMG_HANDLE hDevHandle, -+ IMG_BOOL bIdleDevice, -+ PVRSRV_DEV_POWER_STATE eCurrentPowerState); -+ -+PVRSRV_ERROR SGXPostClockSpeedChange(IMG_HANDLE hDevHandle, -+ IMG_BOOL bIdleDevice, -+ PVRSRV_DEV_POWER_STATE eCurrentPowerState); -+ -+IMG_VOID SGXPanic(PVRSRV_SGXDEV_INFO *psDevInfo); -+ -+IMG_VOID SGXDumpDebugInfo (PVRSRV_SGXDEV_INFO *psDevInfo, -+ IMG_BOOL bDumpSGXRegs); -+ -+PVRSRV_ERROR SGXDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode); -+ -+#if defined(SGX_DYNAMIC_TIMING_INFO) -+IMG_VOID SysGetSGXTimingInformation(SGX_TIMING_INFORMATION *psSGXTimingInfo); -+#endif -+ -+/****************************************************************************/ -+/* kernel only functions: */ -+/****************************************************************************/ -+#if defined(NO_HARDWARE) -+static INLINE IMG_VOID NoHardwareGenerateEvent(PVRSRV_SGXDEV_INFO *psDevInfo, -+ IMG_UINT32 ui32StatusRegister, -+ IMG_UINT32 ui32StatusValue, -+ IMG_UINT32 ui32StatusMask) -+{ -+ IMG_UINT32 ui32RegVal; -+ -+ ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, ui32StatusRegister); -+ -+ ui32RegVal &= ~ui32StatusMask; -+ ui32RegVal |= (ui32StatusValue & ui32StatusMask); -+ -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32StatusRegister, ui32RegVal); -+} -+#endif -+ -+#if defined(__cplusplus) -+} -+#endif -+ -+#endif /* __SGXINFOKM_H__ */ -+ -+/***************************************************************************** -+ End of file (sgxinfokm.h) -+*****************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/sgxinit.c b/drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/sgxinit.c -new file mode 100644 -index 0000000..96ec48b ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/sgxinit.c -@@ -0,0 +1,3388 @@ -+/*************************************************************************/ /*! -+@Title Device specific initialisation routines -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#include <stddef.h> -+ -+#include "sgxdefs.h" -+#include "sgxmmu.h" -+#include "services_headers.h" -+#include "buffer_manager.h" -+#include "sgxapi_km.h" -+#include "sgxinfo.h" -+#include "sgx_mkif_km.h" -+#include "sgxconfig.h" -+#include "sysconfig.h" -+#include "pvr_bridge_km.h" -+ -+#include "sgx_bridge_km.h" -+ -+#include "pdump_km.h" -+#include "ra.h" -+#include "mmu.h" -+#include "handle.h" -+#include "perproc.h" -+ -+#include "sgxutils.h" -+#include "pvrversion.h" -+#include "sgx_options.h" -+ -+#include "lists.h" -+#include "srvkm.h" -+#include "ttrace.h" -+ -+IMG_UINT32 g_ui32HostIRQCountSample = 0; -+ -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,7,0)) -+#include <soc.h> -+#endif -+ -+#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG) -+ -+static const IMG_CHAR *SGXUKernelStatusString(IMG_UINT32 code) -+{ -+ switch(code) -+ { -+#define MKTC_ST(x) \ -+ case x: \ -+ return #x; -+#include "sgx_ukernel_status_codes.h" -+ default: -+ return "(Unknown)"; -+ } -+} -+ -+#endif /* defined(PVRSRV_USSE_EDM_STATUS_DEBUG) */ -+ -+#define VAR(x) #x -+/* PRQA S 0881 11 */ /* ignore 'order of evaluation' warning */ -+#define CHECK_SIZE(NAME) \ -+{ \ -+ if (psSGXStructSizes->ui32Sizeof_##NAME != psDevInfo->sSGXStructSizes.ui32Sizeof_##NAME) \ -+ { \ -+ PVR_DPF((PVR_DBG_ERROR, "SGXDevInitCompatCheck: Size check failed for SGXMKIF_%s (client) = %d bytes, (ukernel) = %d bytes\n", \ -+ VAR(NAME), \ -+ psDevInfo->sSGXStructSizes.ui32Sizeof_##NAME, \ -+ psSGXStructSizes->ui32Sizeof_##NAME )); \ -+ bStructSizesFailed = IMG_TRUE; \ -+ } \ -+} -+ -+#if defined (SYS_USING_INTERRUPTS) -+IMG_BOOL SGX_ISRHandler(IMG_VOID *pvData); -+#endif -+ -+ -+static -+PVRSRV_ERROR SGXGetMiscInfoUkernel(PVRSRV_SGXDEV_INFO *psDevInfo, -+ PVRSRV_DEVICE_NODE *psDeviceNode, -+ IMG_HANDLE hDevMemContext); -+#if defined(PDUMP) -+static -+PVRSRV_ERROR SGXResetPDump(PVRSRV_DEVICE_NODE *psDeviceNode); -+#endif -+ -+/*! -+******************************************************************************* -+ -+ @Function SGXCommandComplete -+ -+ @Description -+ -+ SGX command complete handler -+ -+ @Input psDeviceNode - SGX device node -+ -+ @Return none -+ -+******************************************************************************/ -+static IMG_VOID SGXCommandComplete(PVRSRV_DEVICE_NODE *psDeviceNode) -+{ -+#if defined(OS_SUPPORTS_IN_LISR) -+ if (OSInLISR(psDeviceNode->psSysData)) -+ { -+ /* -+ * We shouldn't call SGXScheduleProcessQueuesKM in an -+ * LISR, as it may attempt to power up SGX. -+ * We assume that the LISR will schedule the MISR, which -+ * will test the following flag, and call -+ * SGXScheduleProcessQueuesKM if the flag is set. -+ */ -+ psDeviceNode->bReProcessDeviceCommandComplete = IMG_TRUE; -+ } -+ else -+ { -+ SGXScheduleProcessQueuesKM(psDeviceNode); -+ } -+#else -+ SGXScheduleProcessQueuesKM(psDeviceNode); -+#endif -+} -+ -+/*! -+******************************************************************************* -+ -+ @Function DeinitDevInfo -+ -+ @Description -+ -+ Deinits DevInfo -+ -+ @Input none -+ -+ @Return none -+ -+******************************************************************************/ -+static IMG_UINT32 DeinitDevInfo(PVRSRV_SGXDEV_INFO *psDevInfo) -+{ -+ if (psDevInfo->psKernelCCBInfo != IMG_NULL) -+ { -+ /* -+ Free CCB info. -+ */ -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_SGX_CCB_INFO), psDevInfo->psKernelCCBInfo, IMG_NULL); -+ } -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+******************************************************************************* -+ -+ @Function InitDevInfo -+ -+ @Description -+ -+ Loads DevInfo -+ -+ @Input psDeviceNode -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+static PVRSRV_ERROR InitDevInfo(PVRSRV_PER_PROCESS_DATA *psPerProc, -+ PVRSRV_DEVICE_NODE *psDeviceNode, -+ SGX_BRIDGE_INIT_INFO *psInitInfo) -+{ -+ PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice; -+ PVRSRV_ERROR eError; -+ -+ PVRSRV_SGX_CCB_INFO *psKernelCCBInfo = IMG_NULL; -+ -+ PVR_UNREFERENCED_PARAMETER(psPerProc); -+ psDevInfo->sScripts = psInitInfo->sScripts; -+ -+ psDevInfo->psKernelCCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelCCBMemInfo; -+ psDevInfo->psKernelCCB = (PVRSRV_SGX_KERNEL_CCB *) psDevInfo->psKernelCCBMemInfo->pvLinAddrKM; -+ -+ psDevInfo->psKernelCCBCtlMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelCCBCtlMemInfo; -+ psDevInfo->psKernelCCBCtl = (PVRSRV_SGX_CCB_CTL *) psDevInfo->psKernelCCBCtlMemInfo->pvLinAddrKM; -+ -+ psDevInfo->psKernelCCBEventKickerMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelCCBEventKickerMemInfo; -+ psDevInfo->pui32KernelCCBEventKicker = (IMG_UINT32 *)psDevInfo->psKernelCCBEventKickerMemInfo->pvLinAddrKM; -+ -+ psDevInfo->psKernelSGXHostCtlMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelSGXHostCtlMemInfo; -+ psDevInfo->psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psKernelSGXHostCtlMemInfo->pvLinAddrKM; -+ -+ psDevInfo->psKernelSGXTA3DCtlMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelSGXTA3DCtlMemInfo; -+ -+#if defined(FIX_HW_BRN_31272) || defined(FIX_HW_BRN_31780) || defined(FIX_HW_BRN_33920) -+ psDevInfo->psKernelSGXPTLAWriteBackMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelSGXPTLAWriteBackMemInfo; -+#endif -+ -+ psDevInfo->psKernelSGXMiscMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelSGXMiscMemInfo; -+ -+#if defined(SGX_SUPPORT_HWPROFILING) -+ psDevInfo->psKernelHWProfilingMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelHWProfilingMemInfo; -+#endif -+#if defined(SUPPORT_SGX_HWPERF) -+ psDevInfo->psKernelHWPerfCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelHWPerfCBMemInfo; -+#endif -+ psDevInfo->psKernelTASigBufferMemInfo = psInitInfo->hKernelTASigBufferMemInfo; -+ psDevInfo->psKernel3DSigBufferMemInfo = psInitInfo->hKernel3DSigBufferMemInfo; -+#if defined(SGX_FEATURE_VDM_CONTEXT_SWITCH) && \ -+ defined(FIX_HW_BRN_33657) && defined(SUPPORT_SECURE_33657_FIX) -+ psDevInfo->psKernelVDMStateUpdateBufferMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelVDMStateUpdateBufferMemInfo; -+#endif -+#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG) -+ psDevInfo->psKernelEDMStatusBufferMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psInitInfo->hKernelEDMStatusBufferMemInfo; -+#endif -+ /* -+ * Assign client-side build options for later verification -+ */ -+ psDevInfo->ui32ClientBuildOptions = psInitInfo->ui32ClientBuildOptions; -+ -+ /* -+ * Assign microkernel IF structure sizes for later verification -+ */ -+ psDevInfo->sSGXStructSizes = psInitInfo->sSGXStructSizes; -+ -+ /* -+ Setup the kernel version of the CCB control -+ */ -+ eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, -+ sizeof(PVRSRV_SGX_CCB_INFO), -+ (IMG_VOID **)&psKernelCCBInfo, 0, -+ "SGX Circular Command Buffer Info"); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"InitDevInfo: Failed to alloc memory")); -+ goto failed_allockernelccb; -+ } -+ -+ -+ OSMemSet(psKernelCCBInfo, 0, sizeof(PVRSRV_SGX_CCB_INFO)); -+ psKernelCCBInfo->psCCBMemInfo = psDevInfo->psKernelCCBMemInfo; -+ psKernelCCBInfo->psCCBCtlMemInfo = psDevInfo->psKernelCCBCtlMemInfo; -+ psKernelCCBInfo->psCommands = psDevInfo->psKernelCCB->asCommands; -+ psKernelCCBInfo->pui32WriteOffset = &psDevInfo->psKernelCCBCtl->ui32WriteOffset; -+ psKernelCCBInfo->pui32ReadOffset = &psDevInfo->psKernelCCBCtl->ui32ReadOffset; -+ psDevInfo->psKernelCCBInfo = psKernelCCBInfo; -+ -+ /* -+ Copy the USE code addresses for the host kick. -+ */ -+ OSMemCopy(psDevInfo->aui32HostKickAddr, psInitInfo->aui32HostKickAddr, -+ SGXMKIF_CMD_MAX * sizeof(psDevInfo->aui32HostKickAddr[0])); -+ -+ psDevInfo->bForcePTOff = IMG_FALSE; -+ -+ psDevInfo->ui32CacheControl = psInitInfo->ui32CacheControl; -+ -+ psDevInfo->ui32EDMTaskReg0 = psInitInfo->ui32EDMTaskReg0; -+ psDevInfo->ui32EDMTaskReg1 = psInitInfo->ui32EDMTaskReg1; -+ psDevInfo->ui32ClkGateCtl = psInitInfo->ui32ClkGateCtl; -+ psDevInfo->ui32ClkGateCtl2 = psInitInfo->ui32ClkGateCtl2; -+ psDevInfo->ui32ClkGateStatusReg = psInitInfo->ui32ClkGateStatusReg; -+ psDevInfo->ui32ClkGateStatusMask = psInitInfo->ui32ClkGateStatusMask; -+#if defined(SGX_FEATURE_MP) -+ psDevInfo->ui32MasterClkGateStatusReg = psInitInfo->ui32MasterClkGateStatusReg; -+ psDevInfo->ui32MasterClkGateStatusMask = psInitInfo->ui32MasterClkGateStatusMask; -+ psDevInfo->ui32MasterClkGateStatus2Reg = psInitInfo->ui32MasterClkGateStatus2Reg; -+ psDevInfo->ui32MasterClkGateStatus2Mask = psInitInfo->ui32MasterClkGateStatus2Mask; -+#endif /* SGX_FEATURE_MP */ -+ -+ -+ /* Initialise Dev Data */ -+ OSMemCopy(&psDevInfo->asSGXDevData, &psInitInfo->asInitDevData, sizeof(psDevInfo->asSGXDevData)); -+ -+ return PVRSRV_OK; -+ -+failed_allockernelccb: -+ DeinitDevInfo(psDevInfo); -+ -+ return eError; -+} -+ -+ -+ -+ -+static PVRSRV_ERROR SGXRunScript(PVRSRV_SGXDEV_INFO *psDevInfo, SGX_INIT_COMMAND *psScript, IMG_UINT32 ui32NumInitCommands) -+{ -+ IMG_UINT32 ui32PC, ui32RegVal; -+ SGX_INIT_COMMAND *psComm; -+ -+ for (ui32PC = 0, psComm = psScript; -+ ui32PC < ui32NumInitCommands; -+ ui32PC++, psComm++) -+ { -+ switch (psComm->eOp) -+ { -+ case SGX_INIT_OP_WRITE_HW_REG: -+ { -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, psComm->sWriteHWReg.ui32Offset, psComm->sWriteHWReg.ui32Value); -+ PDUMPCOMMENT("SGXRunScript: Write HW reg operation"); -+ PDUMPREG(SGX_PDUMPREG_NAME, psComm->sWriteHWReg.ui32Offset, psComm->sWriteHWReg.ui32Value); -+ break; -+ } -+ case SGX_INIT_OP_READ_HW_REG: -+ { -+ OSReadHWReg(psDevInfo->pvRegsBaseKM, psComm->sReadHWReg.ui32Offset); -+#if defined(PDUMP) -+ PDUMPCOMMENT("SGXRunScript: Read HW reg operation"); -+ PDumpRegRead(SGX_PDUMPREG_NAME, psComm->sReadHWReg.ui32Offset, PDUMP_FLAGS_CONTINUOUS); -+#endif -+ break; -+ } -+ case SGX_INIT_OP_PRINT_HW_REG: -+ { -+ ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, psComm->sReadHWReg.ui32Offset); -+ PVR_LOG((" (SGXREG) 0x%08X : 0x%08X", psComm->sReadHWReg.ui32Offset, ui32RegVal)); -+ -+ break; -+ } -+ -+#if defined(PDUMP) -+ case SGX_INIT_OP_PDUMP_HW_REG: -+ { -+ PDUMPCOMMENT("SGXRunScript: Dump HW reg operation"); -+ PDUMPREG(SGX_PDUMPREG_NAME, psComm->sPDumpHWReg.ui32Offset, psComm->sPDumpHWReg.ui32Value); -+ break; -+ } -+#endif -+ case SGX_INIT_OP_HALT: -+ { -+ return PVRSRV_OK; -+ } -+ case SGX_INIT_OP_ILLEGAL: -+ /* FALLTHROUGH */ -+ default: -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SGXRunScript: PC %d: Illegal command: %d", ui32PC, psComm->eOp)); -+ return PVRSRV_ERROR_UNKNOWN_SCRIPT_OPERATION; -+ } -+ } -+ -+ } -+ -+ return PVRSRV_ERROR_UNKNOWN_SCRIPT_OPERATION; -+} -+ -+#if defined(SUPPORT_MEMORY_TILING) -+static PVRSRV_ERROR SGX_AllocMemTilingRangeInt(PVRSRV_SGXDEV_INFO *psDevInfo, -+ IMG_UINT32 ui32Start, -+ IMG_UINT32 ui32End, -+ IMG_UINT32 ui32TilingStride, -+ IMG_UINT32 *pui32RangeIndex) -+{ -+ IMG_UINT32 i; -+ IMG_UINT32 ui32Offset; -+ IMG_UINT32 ui32Val; -+ -+ /* HW supports 10 ranges */ -+ for(i=0; i < SGX_BIF_NUM_TILING_RANGES; i++) -+ { -+ if((psDevInfo->ui32MemTilingUsage & (1U << i)) == 0) -+ { -+ /* mark in use */ -+ psDevInfo->ui32MemTilingUsage |= 1U << i; -+ /* output range index if the caller wants it */ -+ if(pui32RangeIndex != IMG_NULL) -+ { -+ *pui32RangeIndex = i; -+ } -+ goto RangeAllocated; -+ } -+ } -+ -+ PVR_DPF((PVR_DBG_ERROR,"SGX_AllocMemTilingRange: all tiling ranges in use")); -+ return PVRSRV_ERROR_EXCEEDED_HW_LIMITS; -+ -+RangeAllocated: -+ -+ /* An improperly aligned range could cause BIF not to tile some memory which is intended to be tiled, -+ * or cause BIF to tile some memory which is not intended to be. -+ */ -+ if(ui32Start & ~SGX_BIF_TILING_ADDR_MASK) -+ { -+ PVR_DPF((PVR_DBG_WARNING,"SGX_AllocMemTilingRangeInt: Tiling range start (0x%08X) fails" -+ "alignment test", ui32Start)); -+ } -+ if((ui32End + 0x00001000) & ~SGX_BIF_TILING_ADDR_MASK) -+ { -+ PVR_DPF((PVR_DBG_WARNING,"SGX_AllocMemTilingRangeInt: Tiling range end (0x%08X) fails" -+ "alignment test", ui32End)); -+ } -+ -+ ui32Offset = EUR_CR_BIF_TILE0 + (i<<2); -+ -+ ui32Val = ((ui32TilingStride << EUR_CR_BIF_TILE0_CFG_SHIFT) & EUR_CR_BIF_TILE0_CFG_MASK) -+ | (((ui32End>>SGX_BIF_TILING_ADDR_LSB) << EUR_CR_BIF_TILE0_MAX_ADDRESS_SHIFT) & EUR_CR_BIF_TILE0_MAX_ADDRESS_MASK) -+ | (((ui32Start>>SGX_BIF_TILING_ADDR_LSB) << EUR_CR_BIF_TILE0_MIN_ADDRESS_SHIFT) & EUR_CR_BIF_TILE0_MIN_ADDRESS_MASK) -+ | (EUR_CR_BIF_TILE0_ENABLE << EUR_CR_BIF_TILE0_CFG_SHIFT); -+ -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32Offset, ui32Val); -+ PDUMPREG(SGX_PDUMPREG_NAME, ui32Offset, ui32Val); -+ -+#if defined(SGX_FEATURE_BIF_WIDE_TILING_AND_4K_ADDRESS) -+ ui32Offset = EUR_CR_BIF_TILE0_ADDR_EXT + (i<<2); -+ -+ ui32Val = (((ui32End>>SGX_BIF_TILING_EXT_ADDR_LSB) << EUR_CR_BIF_TILE0_ADDR_EXT_MAX_SHIFT) & EUR_CR_BIF_TILE0_ADDR_EXT_MAX_MASK) -+ | (((ui32Start>>SGX_BIF_TILING_EXT_ADDR_LSB) << EUR_CR_BIF_TILE0_ADDR_EXT_MIN_SHIFT) & EUR_CR_BIF_TILE0_ADDR_EXT_MIN_MASK); -+ -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32Offset, ui32Val); -+ PDUMPREG(SGX_PDUMPREG_NAME, ui32Offset, ui32Val); -+#endif /* SGX_FEATURE_BIF_WIDE_TILING_AND_4K_ADDRESS */ -+ -+ return PVRSRV_OK; -+} -+ -+#endif /* SUPPORT_MEMORY_TILING */ -+ -+/*! -+******************************************************************************* -+ -+ @Function SGXInitialise -+ -+ @Description -+ -+ (client invoked) chip-reset and initialisation -+ -+ @Input pvDeviceNode - device info. structure -+ @Input bHardwareRecovery - true if recovering powered hardware, -+ false if powering up -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR SGXInitialise(PVRSRV_SGXDEV_INFO *psDevInfo, -+ IMG_BOOL bHardwareRecovery) -+{ -+ PVRSRV_ERROR eError; -+ PVRSRV_KERNEL_MEM_INFO *psSGXHostCtlMemInfo = psDevInfo->psKernelSGXHostCtlMemInfo; -+ SGXMKIF_HOST_CTL *psSGXHostCtl = psSGXHostCtlMemInfo->pvLinAddrKM; -+ static IMG_BOOL bFirstTime = IMG_TRUE; -+#if defined(PDUMP) -+ IMG_BOOL bPDumpIsSuspended = PDumpIsSuspended(); -+#endif /* PDUMP */ -+ -+#if defined(SGX_FEATURE_MP) -+ /* Slave core clocks must be enabled during reset */ -+#else -+ SGXInitClocks(psDevInfo, PDUMP_FLAGS_CONTINUOUS); -+#endif /* SGX_FEATURE_MP */ -+ -+ /* -+ Part 1 of the initialisation script runs before resetting SGX. -+ */ -+ PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "SGX initialisation script part 1\n"); -+ eError = SGXRunScript(psDevInfo, psDevInfo->sScripts.asInitCommandsPart1, SGX_MAX_INIT_COMMANDS); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SGXInitialise: SGXRunScript (part 1) failed (%d)", eError)); -+ return eError; -+ } -+ PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "End of SGX initialisation script part 1\n"); -+ -+ /* Reset the chip */ -+ psDevInfo->ui32NumResets++; -+ -+#if !defined(SGX_FEATURE_MP) -+ bHardwareRecovery |= bFirstTime; -+#endif /* SGX_FEATURE_MP */ -+ -+ SGXReset(psDevInfo, bHardwareRecovery, PDUMP_FLAGS_CONTINUOUS); -+ -+#if defined(EUR_CR_POWER) -+#if defined(SGX531) -+ /* -+ Disable half the pipes. -+ 531 has 2 pipes within a 4 pipe framework, so -+ the 2 redundant pipes must be disabled even -+ though they do not exist. -+ */ -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_POWER, 1); -+ PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_POWER, 1); -+#else -+ /* set the default pipe count (all fully enabled) */ -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_POWER, 0); -+ PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_POWER, 0); -+#endif -+#endif -+ -+ /* Initialise the kernel CCB event kicker value */ -+ *psDevInfo->pui32KernelCCBEventKicker = 0; -+#if defined(PDUMP) -+ if (!bPDumpIsSuspended) -+ { -+ psDevInfo->ui32KernelCCBEventKickerDumpVal = 0; -+ PDUMPMEM(&psDevInfo->ui32KernelCCBEventKickerDumpVal, -+ psDevInfo->psKernelCCBEventKickerMemInfo, 0, -+ sizeof(*psDevInfo->pui32KernelCCBEventKicker), PDUMP_FLAGS_CONTINUOUS, -+ MAKEUNIQUETAG(psDevInfo->psKernelCCBEventKickerMemInfo)); -+ } -+#endif /* PDUMP */ -+ -+#if defined(SUPPORT_MEMORY_TILING) -+ { -+ /* Initialise EUR_CR_BIF_TILE registers for any tiling heaps */ -+ DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap = psDevInfo->pvDeviceMemoryHeap; -+ IMG_UINT32 i; -+ -+ psDevInfo->ui32MemTilingUsage = 0; -+ -+ for(i=0; i<psDevInfo->ui32HeapCount; i++) -+ { -+ if(psDeviceMemoryHeap[i].ui32XTileStride > 0) -+ { -+ /* Set up the HW control registers */ -+ eError = SGX_AllocMemTilingRangeInt( -+ psDevInfo, -+ psDeviceMemoryHeap[i].sDevVAddrBase.uiAddr, -+ psDeviceMemoryHeap[i].sDevVAddrBase.uiAddr -+ + psDeviceMemoryHeap[i].ui32HeapSize, -+ psDeviceMemoryHeap[i].ui32XTileStride, -+ NULL); -+ if(eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "Unable to allocate SGX BIF tiling range for heap: %s", -+ psDeviceMemoryHeap[i].pszName)); -+ break; -+ } -+ } -+ } -+ } -+#endif -+ -+ /* -+ Part 2 of the initialisation script runs after resetting SGX. -+ */ -+ PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "SGX initialisation script part 2\n"); -+ eError = SGXRunScript(psDevInfo, psDevInfo->sScripts.asInitCommandsPart2, SGX_MAX_INIT_COMMANDS); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SGXInitialise: SGXRunScript (part 2) failed (%d)", eError)); -+ return eError; -+ } -+ PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "End of SGX initialisation script part 2\n"); -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) -+ if(!(cpu_is_omap3530() || cpu_is_omap3517())) -+#else -+ if(!(cpu_is_omap3430() || soc_is_am35xx())) -+#endif -+ { -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, 0xFF08, 0x80000000);//OCP Bypass mode -+ } -+ -+ -+ /* Record the system timestamp for the microkernel */ -+ psSGXHostCtl->ui32HostClock = OSClockus(); -+ -+ psSGXHostCtl->ui32InitStatus = 0; -+#if defined(PDUMP) -+ PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, -+ "Reset the SGX microkernel initialisation status\n"); -+ PDUMPMEM(IMG_NULL, psSGXHostCtlMemInfo, -+ offsetof(SGXMKIF_HOST_CTL, ui32InitStatus), -+ sizeof(IMG_UINT32), PDUMP_FLAGS_CONTINUOUS, -+ MAKEUNIQUETAG(psSGXHostCtlMemInfo)); -+ PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, -+ "Initialise the microkernel\n"); -+#endif /* PDUMP */ -+ -+#if defined(SGX_FEATURE_MULTI_EVENT_KICK) -+ OSWriteMemoryBarrier(); -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, -+ SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK2, 0), -+ EUR_CR_EVENT_KICK2_NOW_MASK); -+#else -+ *psDevInfo->pui32KernelCCBEventKicker = (*psDevInfo->pui32KernelCCBEventKicker + 1) & 0xFF; -+ OSWriteMemoryBarrier(); -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, -+ SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK, 0), -+ EUR_CR_EVENT_KICK_NOW_MASK); -+#endif /* SGX_FEATURE_MULTI_EVENT_KICK */ -+ -+ OSMemoryBarrier(); -+ -+#if defined(PDUMP) -+ /* -+ Dump the host kick. -+ */ -+ if (!bPDumpIsSuspended) -+ { -+#if defined(SGX_FEATURE_MULTI_EVENT_KICK) -+ PDUMPREG(SGX_PDUMPREG_NAME, SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK2, 0), EUR_CR_EVENT_KICK2_NOW_MASK); -+#else -+ psDevInfo->ui32KernelCCBEventKickerDumpVal = 1; -+ PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, -+ "First increment of the SGX event kicker value\n"); -+ PDUMPMEM(&psDevInfo->ui32KernelCCBEventKickerDumpVal, -+ psDevInfo->psKernelCCBEventKickerMemInfo, -+ 0, -+ sizeof(IMG_UINT32), -+ PDUMP_FLAGS_CONTINUOUS, -+ MAKEUNIQUETAG(psDevInfo->psKernelCCBEventKickerMemInfo)); -+ PDUMPREG(SGX_PDUMPREG_NAME, SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK, 0), EUR_CR_EVENT_KICK_NOW_MASK); -+#endif /* SGX_FEATURE_MULTI_EVENT_KICK */ -+ } -+#endif /* PDUMP */ -+ -+#if !defined(NO_HARDWARE) -+ /* -+ Wait for the microkernel to finish initialising. -+ */ -+ if (PollForValueKM(&psSGXHostCtl->ui32InitStatus, -+ PVRSRV_USSE_EDM_INIT_COMPLETE, -+ PVRSRV_USSE_EDM_INIT_COMPLETE, -+ MAX_HW_TIME_US, -+ MAX_HW_TIME_US/WAIT_TRY_COUNT, -+ IMG_FALSE) != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SGXInitialise: Wait for uKernel initialisation failed")); -+ -+ SGXDumpDebugInfo(psDevInfo, IMG_FALSE); -+ PVR_DBG_BREAK; -+ -+ return PVRSRV_ERROR_RETRY; -+ } -+#endif /* NO_HARDWARE */ -+ -+#if defined(PDUMP) -+ PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, -+ "Wait for the SGX microkernel initialisation to complete"); -+ PDUMPMEMPOL(psSGXHostCtlMemInfo, -+ offsetof(SGXMKIF_HOST_CTL, ui32InitStatus), -+ PVRSRV_USSE_EDM_INIT_COMPLETE, -+ PVRSRV_USSE_EDM_INIT_COMPLETE, -+ PDUMP_POLL_OPERATOR_EQUAL, -+ PDUMP_FLAGS_CONTINUOUS, -+ MAKEUNIQUETAG(psSGXHostCtlMemInfo)); -+#endif /* PDUMP */ -+ -+ PVR_ASSERT(psDevInfo->psKernelCCBCtl->ui32ReadOffset == psDevInfo->psKernelCCBCtl->ui32WriteOffset); -+ -+ bFirstTime = IMG_FALSE; -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+******************************************************************************* -+ -+ @Function SGXDeinitialise -+ -+ @Description -+ -+ (client invoked) chip-reset and deinitialisation -+ -+ @Input hDevCookie - device info. handle -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR SGXDeinitialise(IMG_HANDLE hDevCookie) -+ -+{ -+ PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *) hDevCookie; -+ PVRSRV_ERROR eError; -+ -+ /* Did SGXInitialise map the SGX registers in? */ -+ if (psDevInfo->pvRegsBaseKM == IMG_NULL) -+ { -+ return PVRSRV_OK; -+ } -+ -+ eError = SGXRunScript(psDevInfo, psDevInfo->sScripts.asDeinitCommands, SGX_MAX_DEINIT_COMMANDS); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SGXDeinitialise: SGXRunScript failed (%d)", eError)); -+ return eError; -+ } -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+******************************************************************************* -+ -+ @Function DevInitSGXPart1 -+ -+ @Description -+ -+ Reset and initialise Chip -+ -+ @Input pvDeviceNode - device info. structure -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+static PVRSRV_ERROR DevInitSGXPart1 (IMG_VOID *pvDeviceNode) -+{ -+ IMG_HANDLE hDevMemHeap = IMG_NULL; -+ PVRSRV_SGXDEV_INFO *psDevInfo; -+ IMG_HANDLE hKernelDevMemContext; -+ IMG_DEV_PHYADDR sPDDevPAddr; -+ IMG_UINT32 i; -+ PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvDeviceNode; -+ DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeap; -+ PVRSRV_ERROR eError; -+ -+ /* pdump info about the core */ -+ PDUMPCOMMENT("SGX Core Version Information: %s", SGX_CORE_FRIENDLY_NAME); -+ -+ #if defined(SGX_FEATURE_MP) -+ #if !defined(SGX_FEATURE_MP_PLUS) -+ PDUMPCOMMENT("SGX Multi-processor: %d cores", SGX_FEATURE_MP_CORE_COUNT); -+ #else -+ PDUMPCOMMENT("SGX Multi-processor: %d TA cores, %d 3D cores", SGX_FEATURE_MP_CORE_COUNT_TA, SGX_FEATURE_MP_CORE_COUNT_3D); -+ #endif -+ #endif /* SGX_FEATURE_MP */ -+ -+#if (SGX_CORE_REV == 0) -+ PDUMPCOMMENT("SGX Core Revision Information: head RTL"); -+#else -+ PDUMPCOMMENT("SGX Core Revision Information: %d", SGX_CORE_REV); -+#endif -+ -+ #if defined(SGX_FEATURE_SYSTEM_CACHE) -+ PDUMPCOMMENT("SGX System Level Cache is present\r\n"); -+ #if defined(SGX_BYPASS_SYSTEM_CACHE) -+ PDUMPCOMMENT("SGX System Level Cache is bypassed\r\n"); -+ #endif /* SGX_BYPASS_SYSTEM_CACHE */ -+ #endif /* SGX_FEATURE_SYSTEM_CACHE */ -+ -+ PDUMPCOMMENT("SGX Initialisation Part 1"); -+ -+ /* Allocate device control block */ -+ if(OSAllocMem( PVRSRV_OS_NON_PAGEABLE_HEAP, -+ sizeof(PVRSRV_SGXDEV_INFO), -+ (IMG_VOID **)&psDevInfo, IMG_NULL, -+ "SGX Device Info") != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart1 : Failed to alloc memory for DevInfo")); -+ return (PVRSRV_ERROR_OUT_OF_MEMORY); -+ } -+ OSMemSet (psDevInfo, 0, sizeof(PVRSRV_SGXDEV_INFO)); -+ -+ /* setup info from jdisplayconfig.h (variations controlled by build) */ -+ psDevInfo->eDeviceType = DEV_DEVICE_TYPE; -+ psDevInfo->eDeviceClass = DEV_DEVICE_CLASS; -+ -+ /* Store the devinfo as its needed by dynamically enumerated systems called from BM */ -+ psDeviceNode->pvDevice = (IMG_PVOID)psDevInfo; -+ -+ /* get heap info from the devnode */ -+ psDevInfo->ui32HeapCount = psDeviceNode->sDevMemoryInfo.ui32HeapCount; -+ psDevInfo->pvDeviceMemoryHeap = (IMG_VOID*)psDeviceMemoryHeap; -+ -+ /* create the kernel memory context */ -+ hKernelDevMemContext = BM_CreateContext(psDeviceNode, -+ &sPDDevPAddr, -+ IMG_NULL, -+ IMG_NULL); -+ if (hKernelDevMemContext == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart1: Failed BM_CreateContext")); -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ -+ psDevInfo->sKernelPDDevPAddr = sPDDevPAddr; -+ -+ /* create the kernel, shared and shared_exported heaps */ -+ for(i=0; i<psDeviceNode->sDevMemoryInfo.ui32HeapCount; i++) -+ { -+ switch(psDeviceMemoryHeap[i].DevMemHeapType) -+ { -+ case DEVICE_MEMORY_HEAP_KERNEL: -+ case DEVICE_MEMORY_HEAP_SHARED: -+ case DEVICE_MEMORY_HEAP_SHARED_EXPORTED: -+ { -+ /* Shared PB heap could be zero size */ -+ if (psDeviceMemoryHeap[i].ui32HeapSize > 0) -+ { -+ hDevMemHeap = BM_CreateHeap (hKernelDevMemContext, -+ &psDeviceMemoryHeap[i]); -+ /* -+ in the case of kernel context heaps just store -+ the heap handle in the heap info structure -+ */ -+ psDeviceMemoryHeap[i].hDevMemHeap = hDevMemHeap; -+ } -+ break; -+ } -+ } -+ } -+#if defined(PDUMP) -+ if(hDevMemHeap) -+ { -+ /* set up the MMU pdump info */ -+ psDevInfo->sMMUAttrib = *((BM_HEAP*)hDevMemHeap)->psMMUAttrib; -+ } -+#endif -+ eError = MMU_BIFResetPDAlloc(psDevInfo); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"DevInitSGX : Failed to alloc memory for BIF reset")); -+ return eError; -+ } -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+******************************************************************************* -+ -+ @Function SGXGetInfoForSrvinitKM -+ -+ @Description -+ -+ Get SGX related information necessary for initilisation server -+ -+ @Input hDevHandle - device handle -+ psInitInfo - pointer to structure for returned information -+ -+ @Output psInitInfo - pointer to structure containing returned information -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR SGXGetInfoForSrvinitKM(IMG_HANDLE hDevHandle, SGX_BRIDGE_INFO_FOR_SRVINIT *psInitInfo) -+{ -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+ PVRSRV_SGXDEV_INFO *psDevInfo; -+ PVRSRV_ERROR eError; -+ -+ PDUMPCOMMENT("SGXGetInfoForSrvinit"); -+ -+ psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevHandle; -+ psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice; -+ -+ psInitInfo->sPDDevPAddr = psDevInfo->sKernelPDDevPAddr; -+ -+ eError = PVRSRVGetDeviceMemHeapsKM(hDevHandle, &psInitInfo->asHeapInfo[0]); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SGXGetInfoForSrvinit: PVRSRVGetDeviceMemHeapsKM failed (%d)", eError)); -+ return eError; -+ } -+ -+ return eError; -+} -+ -+/*! -+******************************************************************************* -+ -+ @Function DevInitSGXPart2KM -+ -+ @Description -+ -+ Reset and initialise Chip -+ -+ @Input pvDeviceNode - device info. structure -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR DevInitSGXPart2KM (PVRSRV_PER_PROCESS_DATA *psPerProc, -+ IMG_HANDLE hDevHandle, -+ SGX_BRIDGE_INIT_INFO *psInitInfo) -+{ -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+ PVRSRV_SGXDEV_INFO *psDevInfo; -+ PVRSRV_ERROR eError; -+ SGX_DEVICE_MAP *psSGXDeviceMap; -+ PVRSRV_DEV_POWER_STATE eDefaultPowerState; -+ -+ PDUMPCOMMENT("SGX Initialisation Part 2"); -+ -+ psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevHandle; -+ psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice; -+ -+ /* -+ Init devinfo -+ */ -+ eError = InitDevInfo(psPerProc, psDeviceNode, psInitInfo); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to load EDM program")); -+ goto failed_init_dev_info; -+ } -+ -+ -+ eError = SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE_SGX, -+ (IMG_VOID**)&psSGXDeviceMap); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to get device memory map!")); -+ return PVRSRV_ERROR_INIT_FAILURE; -+ } -+ -+ /* Registers already mapped? */ -+ if (psSGXDeviceMap->pvRegsCpuVBase) -+ { -+ psDevInfo->pvRegsBaseKM = psSGXDeviceMap->pvRegsCpuVBase; -+ } -+ else -+ { -+ /* Map Regs */ -+ psDevInfo->pvRegsBaseKM = OSMapPhysToLin(psSGXDeviceMap->sRegsCpuPBase, -+ psSGXDeviceMap->ui32RegsSize, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ IMG_NULL); -+ if (!psDevInfo->pvRegsBaseKM) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to map in regs\n")); -+ return PVRSRV_ERROR_BAD_MAPPING; -+ } -+ } -+ psDevInfo->ui32RegSize = psSGXDeviceMap->ui32RegsSize; -+ psDevInfo->sRegsPhysBase = psSGXDeviceMap->sRegsSysPBase; -+ -+ -+#if defined(SGX_FEATURE_HOST_PORT) -+ if (psSGXDeviceMap->ui32Flags & SGX_HOSTPORT_PRESENT) -+ { -+ /* Map Host Port */ -+ psDevInfo->pvHostPortBaseKM = OSMapPhysToLin(psSGXDeviceMap->sHPCpuPBase, -+ psSGXDeviceMap->ui32HPSize, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ IMG_NULL); -+ if (!psDevInfo->pvHostPortBaseKM) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: Failed to map in host port\n")); -+ return PVRSRV_ERROR_BAD_MAPPING; -+ } -+ psDevInfo->ui32HPSize = psSGXDeviceMap->ui32HPSize; -+ psDevInfo->sHPSysPAddr = psSGXDeviceMap->sHPSysPBase; -+ } -+#endif/* #ifdef SGX_FEATURE_HOST_PORT */ -+ -+#if defined (SYS_USING_INTERRUPTS) -+ -+ /* Set up ISR callback information. */ -+ psDeviceNode->pvISRData = psDeviceNode; -+ /* ISR handler address was set up earlier */ -+ PVR_ASSERT(psDeviceNode->pfnDeviceISR == SGX_ISRHandler); -+ -+#endif /* SYS_USING_INTERRUPTS */ -+ -+ /* Prevent the microkernel being woken up before there is something to do. */ -+ psDevInfo->psSGXHostCtl->ui32PowerStatus |= PVRSRV_USSE_EDM_POWMAN_NO_WORK; -+ eDefaultPowerState = PVRSRV_DEV_POWER_STATE_OFF; -+ /* Register the device with the power manager. */ -+ eError = PVRSRVRegisterPowerDevice (psDeviceNode->sDevId.ui32DeviceIndex, -+ &SGXPrePowerState, &SGXPostPowerState, -+ &SGXPreClockSpeedChange, &SGXPostClockSpeedChange, -+ (IMG_HANDLE)psDeviceNode, -+ PVRSRV_DEV_POWER_STATE_OFF, -+ eDefaultPowerState); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"DevInitSGXPart2KM: failed to register device with power manager")); -+ return eError; -+ } -+ -+#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE) -+ /* map the external system cache control registers into the SGX MMU */ -+ psDevInfo->ui32ExtSysCacheRegsSize = psSGXDeviceMap->ui32ExtSysCacheRegsSize; -+ psDevInfo->sExtSysCacheRegsDevPBase = psSGXDeviceMap->sExtSysCacheRegsDevPBase; -+ eError = MMU_MapExtSystemCacheRegs(psDeviceNode); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SGXInitialise : Failed to map external system cache registers")); -+ return eError; -+ } -+#endif /* SUPPORT_EXTERNAL_SYSTEM_CACHE */ -+ -+ /* -+ Initialise the Kernel CCB -+ */ -+ OSMemSet(psDevInfo->psKernelCCB, 0, sizeof(PVRSRV_SGX_KERNEL_CCB)); -+ OSMemSet(psDevInfo->psKernelCCBCtl, 0, sizeof(PVRSRV_SGX_CCB_CTL)); -+ OSMemSet(psDevInfo->pui32KernelCCBEventKicker, 0, sizeof(*psDevInfo->pui32KernelCCBEventKicker)); -+ PDUMPCOMMENT("Initialise Kernel CCB"); -+ PDUMPMEM(IMG_NULL, psDevInfo->psKernelCCBMemInfo, 0, sizeof(PVRSRV_SGX_KERNEL_CCB), PDUMP_FLAGS_CONTINUOUS, MAKEUNIQUETAG(psDevInfo->psKernelCCBMemInfo)); -+ PDUMPCOMMENT("Initialise Kernel CCB Control"); -+ PDUMPMEM(IMG_NULL, psDevInfo->psKernelCCBCtlMemInfo, 0, sizeof(PVRSRV_SGX_CCB_CTL), PDUMP_FLAGS_CONTINUOUS, MAKEUNIQUETAG(psDevInfo->psKernelCCBCtlMemInfo)); -+ PDUMPCOMMENT("Initialise Kernel CCB Event Kicker"); -+ PDUMPMEM(IMG_NULL, psDevInfo->psKernelCCBEventKickerMemInfo, 0, sizeof(*psDevInfo->pui32KernelCCBEventKicker), PDUMP_FLAGS_CONTINUOUS, MAKEUNIQUETAG(psDevInfo->psKernelCCBEventKickerMemInfo)); -+ -+ return PVRSRV_OK; -+ -+failed_init_dev_info: -+ return eError; -+} -+ -+/*! -+******************************************************************************* -+ -+ @Function DevDeInitSGX -+ -+ @Description -+ -+ Reset and deinitialise Chip -+ -+ @Input pvDeviceNode - device info. structure -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+static PVRSRV_ERROR DevDeInitSGX (IMG_VOID *pvDeviceNode) -+{ -+ PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvDeviceNode; -+ PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice; -+ PVRSRV_ERROR eError; -+ IMG_UINT32 ui32Heap; -+ IMG_UINT32 ui32Count; -+ DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; -+ SGX_DEVICE_MAP *psSGXDeviceMap; -+ -+ if (!psDevInfo) -+ { -+ /* Can happen if DevInitSGX failed */ -+ PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Null DevInfo")); -+ return PVRSRV_OK; -+ } -+ -+#if defined(SUPPORT_HW_RECOVERY) -+ if (psDevInfo->hTimer) -+ { -+ eError = OSRemoveTimer(psDevInfo->hTimer); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Failed to remove timer")); -+ return eError; -+ } -+ psDevInfo->hTimer = IMG_NULL; -+ } -+#endif /* SUPPORT_HW_RECOVERY */ -+ -+#if defined(SUPPORT_EXTERNAL_SYSTEM_CACHE) -+ /* unmap the external system cache control registers */ -+ eError = MMU_UnmapExtSystemCacheRegs(psDeviceNode); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Failed to unmap ext system cache registers")); -+ return eError; -+ } -+#endif /* SUPPORT_EXTERNAL_SYSTEM_CACHE */ -+ -+ MMU_BIFResetPDFree(psDevInfo); -+ -+ /* -+ DeinitDevInfo the DevInfo -+ */ -+ DeinitDevInfo(psDevInfo); -+ -+ /* Destroy heaps. */ -+ psDeviceMemoryHeap = (DEVICE_MEMORY_HEAP_INFO *)psDevInfo->pvDeviceMemoryHeap; -+ for(ui32Heap=0; ui32Heap<psDeviceNode->sDevMemoryInfo.ui32HeapCount; ui32Heap++) -+ { -+ switch(psDeviceMemoryHeap[ui32Heap].DevMemHeapType) -+ { -+ case DEVICE_MEMORY_HEAP_KERNEL: -+ case DEVICE_MEMORY_HEAP_SHARED: -+ case DEVICE_MEMORY_HEAP_SHARED_EXPORTED: -+ { -+ if (psDeviceMemoryHeap[ui32Heap].hDevMemHeap != IMG_NULL) -+ { -+ BM_DestroyHeap(psDeviceMemoryHeap[ui32Heap].hDevMemHeap); -+ } -+ break; -+ } -+ } -+ } -+ -+ /* Destroy the kernel context. */ -+ eError = BM_DestroyContext(psDeviceNode->sDevMemoryInfo.pBMKernelContext, IMG_NULL); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX : Failed to destroy kernel context")); -+ return eError; -+ } -+ -+ /* remove the device from the power manager */ -+ eError = PVRSRVRemovePowerDevice (((PVRSRV_DEVICE_NODE*)pvDeviceNode)->sDevId.ui32DeviceIndex); -+ if (eError != PVRSRV_OK) -+ { -+ return eError; -+ } -+ -+ eError = SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE_SGX, -+ (IMG_VOID**)&psSGXDeviceMap); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"DevDeInitSGX: Failed to get device memory map!")); -+ return eError; -+ } -+ -+ /* Only unmap the registers if they were mapped here */ -+ if (!psSGXDeviceMap->pvRegsCpuVBase) -+ { -+ /* UnMap Regs */ -+ if (psDevInfo->pvRegsBaseKM != IMG_NULL) -+ { -+ OSUnMapPhysToLin(psDevInfo->pvRegsBaseKM, -+ psDevInfo->ui32RegSize, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ IMG_NULL); -+ } -+ } -+ -+#if defined(SGX_FEATURE_HOST_PORT) -+ if (psSGXDeviceMap->ui32Flags & SGX_HOSTPORT_PRESENT) -+ { -+ /* unMap Host Port */ -+ if (psDevInfo->pvHostPortBaseKM != IMG_NULL) -+ { -+ OSUnMapPhysToLin(psDevInfo->pvHostPortBaseKM, -+ psDevInfo->ui32HPSize, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ IMG_NULL); -+ } -+ } -+#endif /* #ifdef SGX_FEATURE_HOST_PORT */ -+ -+ /* Deallocate KM mem allocated for debug script commands */ -+ for (ui32Count = 0; ui32Count < SGX_FEATURE_MP_CORE_COUNT_3D; ui32Count++) -+ { -+ if(psDevInfo->sScripts.apsSGXREGDebugCommandsPart2[ui32Count]) -+ { -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, -+ SGX_MAX_PRINT_COMMANDS * sizeof(SGX_INIT_COMMAND), -+ psDevInfo->sScripts.apsSGXREGDebugCommandsPart2[ui32Count], -+ 0); -+ } -+ } -+ -+ /* DeAllocate devinfo */ -+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, -+ sizeof(PVRSRV_SGXDEV_INFO), -+ psDevInfo, -+ 0); -+ -+ psDeviceNode->pvDevice = IMG_NULL; -+ -+ if (psDeviceMemoryHeap != IMG_NULL) -+ { -+ /* Free the device memory heap info. */ -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(DEVICE_MEMORY_HEAP_INFO) * SGX_MAX_HEAP_ID, -+ psDeviceMemoryHeap, -+ 0); -+ } -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+******************************************************************************* -+ -+ @Function SGXDumpDebugReg -+ -+ @Description -+ -+ Dump a single SGX debug register value -+ -+ @Input psDevInfo - SGX device info -+ @Input ui32CoreNum - processor number -+ @Input pszName - string used for logging -+ @Input ui32RegAddr - SGX register offset -+ -+ @Return IMG_VOID -+ -+******************************************************************************/ -+static IMG_VOID SGXDumpDebugReg (PVRSRV_SGXDEV_INFO *psDevInfo, -+ IMG_UINT32 ui32CoreNum, -+ IMG_CHAR *pszName, -+ IMG_UINT32 ui32RegAddr) -+{ -+ IMG_UINT32 ui32RegVal; -+ ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_SELECT(ui32RegAddr, ui32CoreNum)); -+ PVR_LOG(("(P%u) %s%08X", ui32CoreNum, pszName, ui32RegVal)); -+} -+ -+#if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) || defined(FIX_HW_BRN_31620) -+static INLINE IMG_UINT32 GetDirListBaseReg(IMG_UINT32 ui32Index) -+{ -+ if (ui32Index == 0) -+ { -+ return EUR_CR_BIF_DIR_LIST_BASE0; -+ } -+ else -+ { -+ return (EUR_CR_BIF_DIR_LIST_BASE1 + ((ui32Index - 1) * 0x4)); -+ } -+} -+#endif -+ -+/*! -+******************************************************************************* -+ -+ @Function SGXDumpDebugInfo -+ -+ @Description -+ -+ Dump useful debugging info -+ -+ @Input psDevInfo - SGX device info -+ @Input bDumpSGXRegs - Whether to dump SGX debug registers. Must not be done -+ when SGX is not powered. -+ -+ @Return IMG_VOID -+ -+******************************************************************************/ -+IMG_VOID SGXDumpDebugInfo (PVRSRV_SGXDEV_INFO *psDevInfo, -+ IMG_BOOL bDumpSGXRegs) -+{ -+ IMG_UINT32 ui32CoreNum; -+ -+ PVR_LOG(("SGX debug (%s)", PVRVERSION_STRING)); -+ -+ if (bDumpSGXRegs) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SGX Register Base Address (Linear): 0x%p", psDevInfo->pvRegsBaseKM)); -+ PVR_DPF((PVR_DBG_ERROR,"SGX Register Base Address (Physical): 0x" SYSPADDR_FMT, psDevInfo->sRegsPhysBase.uiAddr)); -+ -+ SGXDumpDebugReg(psDevInfo, 0, "EUR_CR_CORE_ID: ", EUR_CR_CORE_ID); -+ SGXDumpDebugReg(psDevInfo, 0, "EUR_CR_CORE_REVISION: ", EUR_CR_CORE_REVISION); -+ for (ui32CoreNum = 0; ui32CoreNum < SGX_FEATURE_MP_CORE_COUNT_3D; ui32CoreNum++) -+ { -+ /* Dump HW event status */ -+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_EVENT_STATUS: ", EUR_CR_EVENT_STATUS); -+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_EVENT_STATUS2: ", EUR_CR_EVENT_STATUS2); -+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_BIF_CTRL: ", EUR_CR_BIF_CTRL); -+ #if defined(EUR_CR_BIF_BANK0) -+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_BIF_BANK0: ", EUR_CR_BIF_BANK0); -+ #endif -+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_BIF_INT_STAT: ", EUR_CR_BIF_INT_STAT); -+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_BIF_FAULT: ", EUR_CR_BIF_FAULT); -+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_BIF_MEM_REQ_STAT: ", EUR_CR_BIF_MEM_REQ_STAT); -+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_CLKGATECTL: ", EUR_CR_CLKGATECTL); -+ #if defined(EUR_CR_PDS_PC_BASE) -+ SGXDumpDebugReg(psDevInfo, ui32CoreNum, "EUR_CR_PDS_PC_BASE: ", EUR_CR_PDS_PC_BASE); -+ #endif -+ } -+ -+ #if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) && !defined(FIX_HW_BRN_31620) -+ { -+ IMG_UINT32 ui32RegVal; -+ IMG_UINT32 ui32PDDevPAddr; -+ -+ /* -+ If there was a SGX pagefault check the page table too see if the -+ host thinks the fault is correct -+ */ -+ ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_INT_STAT); -+ if (ui32RegVal & EUR_CR_BIF_INT_STAT_PF_N_RW_MASK) -+ { -+ ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_FAULT); -+ ui32RegVal &= EUR_CR_BIF_FAULT_ADDR_MASK; -+ ui32PDDevPAddr = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_DIR_LIST_BASE0); -+ ui32PDDevPAddr &= EUR_CR_BIF_DIR_LIST_BASE0_ADDR_MASK; -+ MMU_CheckFaultAddr(psDevInfo, ui32PDDevPAddr, ui32RegVal); -+ } -+ } -+ #else -+ { -+ IMG_UINT32 ui32FaultAddress; -+ IMG_UINT32 ui32Bank0; -+ IMG_UINT32 ui32DirListIndex; -+ IMG_UINT32 ui32PDDevPAddr; -+ -+ ui32FaultAddress = OSReadHWReg(psDevInfo->pvRegsBaseKM, -+ EUR_CR_BIF_FAULT); -+ ui32FaultAddress = ui32FaultAddress & EUR_CR_BIF_FAULT_ADDR_MASK; -+ -+ ui32Bank0 = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_BANK0); -+ -+ /* Check the EDM's's memory context */ -+ ui32DirListIndex = (ui32Bank0 & EUR_CR_BIF_BANK0_INDEX_EDM_MASK) >> EUR_CR_BIF_BANK0_INDEX_EDM_SHIFT; -+ ui32PDDevPAddr = OSReadHWReg(psDevInfo->pvRegsBaseKM, -+ GetDirListBaseReg(ui32DirListIndex)); -+ PVR_LOG(("Checking EDM memory context (index = %d, PD = 0x%08x)", ui32DirListIndex, ui32PDDevPAddr)); -+ MMU_CheckFaultAddr(psDevInfo, ui32PDDevPAddr, ui32FaultAddress); -+ -+ /* Check the TA's memory context */ -+ ui32DirListIndex = (ui32Bank0 & EUR_CR_BIF_BANK0_INDEX_TA_MASK) >> EUR_CR_BIF_BANK0_INDEX_TA_SHIFT; -+ ui32PDDevPAddr = OSReadHWReg(psDevInfo->pvRegsBaseKM, -+ GetDirListBaseReg(ui32DirListIndex)); -+ PVR_LOG(("Checking TA memory context (index = %d, PD = 0x%08x)", ui32DirListIndex, ui32PDDevPAddr)); -+ MMU_CheckFaultAddr(psDevInfo, ui32PDDevPAddr, ui32FaultAddress); -+ -+ /* Check the 3D's memory context */ -+ ui32DirListIndex = (ui32Bank0 & EUR_CR_BIF_BANK0_INDEX_3D_MASK) >> EUR_CR_BIF_BANK0_INDEX_3D_SHIFT; -+ ui32PDDevPAddr = OSReadHWReg(psDevInfo->pvRegsBaseKM, -+ GetDirListBaseReg(ui32DirListIndex)); -+ PVR_LOG(("Checking 3D memory context (index = %d, PD = 0x%08x)", ui32DirListIndex, ui32PDDevPAddr)); -+ MMU_CheckFaultAddr(psDevInfo, ui32PDDevPAddr, ui32FaultAddress); -+ -+ #if defined(EUR_CR_BIF_BANK0_INDEX_2D_MASK) -+ /* Check the 2D's memory context */ -+ ui32DirListIndex = (ui32Bank0 & EUR_CR_BIF_BANK0_INDEX_2D_MASK) >> EUR_CR_BIF_BANK0_INDEX_2D_SHIFT; -+ ui32PDDevPAddr = OSReadHWReg(psDevInfo->pvRegsBaseKM, -+ GetDirListBaseReg(ui32DirListIndex)); -+ PVR_LOG(("Checking 2D memory context (index = %d, PD = 0x%08x)", ui32DirListIndex, ui32PDDevPAddr)); -+ MMU_CheckFaultAddr(psDevInfo, ui32PDDevPAddr, ui32FaultAddress); -+ #endif -+ -+ #if defined(EUR_CR_BIF_BANK0_INDEX_PTLA_MASK) -+ /* Check the 2D's memory context */ -+ ui32DirListIndex = (ui32Bank0 & EUR_CR_BIF_BANK0_INDEX_PTLA_MASK) >> EUR_CR_BIF_BANK0_INDEX_PTLA_SHIFT; -+ ui32PDDevPAddr = OSReadHWReg(psDevInfo->pvRegsBaseKM, -+ GetDirListBaseReg(ui32DirListIndex)); -+ PVR_LOG(("Checking PTLA memory context (index = %d, PD = 0x%08x)", ui32DirListIndex, ui32PDDevPAddr)); -+ MMU_CheckFaultAddr(psDevInfo, ui32PDDevPAddr, ui32FaultAddress); -+ #endif -+ -+ #if defined(EUR_CR_BIF_BANK0_INDEX_HOST_MASK) -+ /* Check the Host's memory context */ -+ ui32DirListIndex = (ui32Bank0 & EUR_CR_BIF_BANK0_INDEX_HOST_MASK) >> EUR_CR_BIF_BANK0_INDEX_HOST_SHIFT; -+ ui32PDDevPAddr = OSReadHWReg(psDevInfo->pvRegsBaseKM, -+ GetDirListBaseReg(ui32DirListIndex)); -+ PVR_LOG(("Checking Host memory context (index = %d, PD = 0x%08x)", ui32DirListIndex, ui32PDDevPAddr)); -+ MMU_CheckFaultAddr(psDevInfo, ui32PDDevPAddr, ui32FaultAddress); -+ #endif -+ } -+ #endif -+ } -+ /* -+ Dump out the outstanding queue items. -+ */ -+ QueueDumpDebugInfo(); -+ -+ { -+ /* -+ Dump out the Host control. -+ */ -+ SGXMKIF_HOST_CTL *psSGXHostCtl = psDevInfo->psSGXHostCtl; -+ IMG_UINT32 *pui32HostCtlBuffer = (IMG_UINT32 *)psSGXHostCtl; -+ IMG_UINT32 ui32LoopCounter; -+ -+ /* Report which defines are enabled that affect the HostCTL structure being dumped-out here */ -+ { -+ IMG_UINT32 ui32CtlFlags = 0; -+ #if defined(PVRSRV_USSE_EDM_BREAKPOINTS) -+ ui32CtlFlags = ui32CtlFlags | 0x0001; -+ #endif -+ #if defined(FIX_HW_BRN_28889) -+ ui32CtlFlags = ui32CtlFlags | 0x0002; -+ #endif -+ #if defined(SUPPORT_HW_RECOVERY) -+ ui32CtlFlags = ui32CtlFlags | 0x0004; -+ #endif -+ #if defined(SGX_FEATURE_EXTENDED_PERF_COUNTERS) -+ ui32CtlFlags = ui32CtlFlags | 0x0008; -+ #endif -+ PVR_LOG((" Host Ctl flags= %08x", ui32CtlFlags)); -+ } -+ -+ if (psSGXHostCtl->ui32AssertFail != 0) -+ { -+ PVR_LOG(("SGX Microkernel assert fail: 0x%08X", psSGXHostCtl->ui32AssertFail)); -+ psSGXHostCtl->ui32AssertFail = 0; -+ } -+ -+ PVR_LOG(("SGX Host control:")); -+ -+ for (ui32LoopCounter = 0; -+ ui32LoopCounter < sizeof(*psDevInfo->psSGXHostCtl) / sizeof(*pui32HostCtlBuffer); -+ ui32LoopCounter += 4) -+ { -+ PVR_LOG(("\t(HC-%" SIZE_T_FMT_LEN "X) 0x%08X 0x%08X 0x%08X 0x%08X", -+ ui32LoopCounter * sizeof(*pui32HostCtlBuffer), -+ pui32HostCtlBuffer[ui32LoopCounter + 0], pui32HostCtlBuffer[ui32LoopCounter + 1], -+ pui32HostCtlBuffer[ui32LoopCounter + 2], pui32HostCtlBuffer[ui32LoopCounter + 3])); -+ } -+ } -+ -+ { -+ /* -+ Dump out the TA/3D control. -+ */ -+ IMG_UINT32 *pui32TA3DCtlBuffer = psDevInfo->psKernelSGXTA3DCtlMemInfo->pvLinAddrKM; -+ IMG_UINT32 ui32LoopCounter; -+ -+ PVR_LOG(("SGX TA/3D control:")); -+ -+ for (ui32LoopCounter = 0; -+ ui32LoopCounter < psDevInfo->psKernelSGXTA3DCtlMemInfo->uAllocSize / sizeof(*pui32TA3DCtlBuffer); -+ ui32LoopCounter += 4) -+ { -+ PVR_LOG(("\t(T3C-%" SIZE_T_FMT_LEN "X) 0x%08X 0x%08X 0x%08X 0x%08X", -+ ui32LoopCounter * sizeof(*pui32TA3DCtlBuffer), -+ pui32TA3DCtlBuffer[ui32LoopCounter + 0], pui32TA3DCtlBuffer[ui32LoopCounter + 1], -+ pui32TA3DCtlBuffer[ui32LoopCounter + 2], pui32TA3DCtlBuffer[ui32LoopCounter + 3])); -+ } -+ } -+ -+ #if defined(PVRSRV_USSE_EDM_STATUS_DEBUG) -+ { -+ IMG_UINT32 *pui32MKTraceBuffer = psDevInfo->psKernelEDMStatusBufferMemInfo->pvLinAddrKM; -+ IMG_UINT32 ui32LastStatusCode, ui32WriteOffset; -+ -+ ui32LastStatusCode = *pui32MKTraceBuffer; -+ pui32MKTraceBuffer++; -+ ui32WriteOffset = *pui32MKTraceBuffer; -+ pui32MKTraceBuffer++; -+ -+ PVR_LOG(("Last SGX microkernel status code: %08X %s", -+ ui32LastStatusCode, SGXUKernelStatusString(ui32LastStatusCode))); -+ -+ #if defined(PVRSRV_DUMP_MK_TRACE) -+ /* -+ Dump the raw microkernel trace buffer to the log. -+ */ -+ { -+ IMG_UINT32 ui32LoopCounter; -+ -+ for (ui32LoopCounter = 0; -+ ui32LoopCounter < SGXMK_TRACE_BUFFER_SIZE; -+ ui32LoopCounter++) -+ { -+ IMG_UINT32 *pui32BufPtr; -+ pui32BufPtr = pui32MKTraceBuffer + -+ (((ui32WriteOffset + ui32LoopCounter) % SGXMK_TRACE_BUFFER_SIZE) * 4); -+ PVR_LOG(("\t(MKT-%X) %08X %08X %08X %08X %s", ui32LoopCounter, -+ pui32BufPtr[2], pui32BufPtr[3], pui32BufPtr[1], pui32BufPtr[0], -+ SGXUKernelStatusString(pui32BufPtr[0]))); -+ } -+ } -+ #endif /* PVRSRV_DUMP_MK_TRACE */ -+ } -+ #endif /* PVRSRV_USSE_EDM_STATUS_DEBUG */ -+ -+ { -+ /* -+ Dump out the kernel CCB. -+ */ -+ PVR_LOG(("SGX Kernel CCB WO:0x%X RO:0x%X", -+ psDevInfo->psKernelCCBCtl->ui32WriteOffset, -+ psDevInfo->psKernelCCBCtl->ui32ReadOffset)); -+ -+ #if defined(PVRSRV_DUMP_KERNEL_CCB) -+ { -+ IMG_UINT32 ui32LoopCounter; -+ -+ for (ui32LoopCounter = 0; -+ ui32LoopCounter < sizeof(psDevInfo->psKernelCCB->asCommands) / -+ sizeof(psDevInfo->psKernelCCB->asCommands[0]); -+ ui32LoopCounter++) -+ { -+ SGXMKIF_COMMAND *psCommand = &psDevInfo->psKernelCCB->asCommands[ui32LoopCounter]; -+ -+ PVR_LOG(("\t(KCCB-%X) %08X %08X - %08X %08X %08X %08X", ui32LoopCounter, -+ psCommand->ui32ServiceAddress, psCommand->ui32CacheControl, -+ psCommand->ui32Data[0], psCommand->ui32Data[1], -+ psCommand->ui32Data[2], psCommand->ui32Data[3])); -+ } -+ } -+ #endif /* PVRSRV_DUMP_KERNEL_CCB */ -+ } -+ #if defined (TTRACE) -+ PVRSRVDumpTimeTraceBuffers(); -+ #endif -+ -+} -+ -+ -+#if defined(SYS_USING_INTERRUPTS) || defined(SUPPORT_HW_RECOVERY) -+/*! -+******************************************************************************* -+ -+ @Function HWRecoveryResetSGX -+ -+ @Description -+ -+ Resets SGX -+ -+ Note: may be called from an ISR so should not call pdump. -+ -+ @Input psDevInfo - dev info -+ -+ @Input ui32Component - core component to reset -+ -+ @Return IMG_VOID -+ -+******************************************************************************/ -+static -+IMG_VOID HWRecoveryResetSGX (PVRSRV_DEVICE_NODE *psDeviceNode, -+ IMG_UINT32 ui32Component, -+ IMG_UINT32 ui32CallerID) -+{ -+ PVRSRV_ERROR eError; -+ IMG_UINT32 ui32Count; -+ PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice; -+ SGXMKIF_HOST_CTL *psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psSGXHostCtl; -+ -+#if defined(SUPPORT_HWRECOVERY_TRACE_LIMIT) -+ static IMG_UINT32 ui32Clockinus = 0; -+ static IMG_UINT32 ui32HWRecoveryCount=0; -+ IMG_UINT32 ui32TempClockinus=0; -+#endif -+ -+ PVR_UNREFERENCED_PARAMETER(ui32Component); -+ -+ /* -+ Ensure that hardware recovery is serialised with any power transitions. -+ */ -+ eError = PVRSRVPowerLock(ui32CallerID, IMG_FALSE); -+ if(eError != PVRSRV_OK) -+ { -+ /* -+ Unable to obtain lock because there is already a power transition -+ in progress. -+ */ -+ PVR_DPF((PVR_DBG_WARNING,"HWRecoveryResetSGX: Power transition in progress")); -+ return; -+ } -+ -+ psSGXHostCtl->ui32InterruptClearFlags |= PVRSRV_USSE_EDM_INTERRUPT_HWR; -+ -+ PVR_LOG(("HWRecoveryResetSGX: SGX Hardware Recovery triggered")); -+ -+ /* Run SGXREGDebug scripts */ -+#if defined(SGX_FEATURE_MP) -+ PVR_LOG(("(HYD)")); -+ eError = SGXRunScript(psDevInfo, psDevInfo->sScripts.asSGXREGDebugCommandsPart1, SGX_MAX_PRINT_COMMANDS); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"HWRecoveryResetSGX: SGXREGDebugCommandsPart1 SGXRunScript failed (%d)", eError)); -+ } -+#endif -+ -+ for (ui32Count = 0; ui32Count < SGX_FEATURE_MP_CORE_COUNT_3D; ui32Count++) -+ { -+ PVR_LOG(("(P%u)",ui32Count)); -+ eError = SGXRunScript(psDevInfo, psDevInfo->sScripts.apsSGXREGDebugCommandsPart2[ui32Count], SGX_MAX_PRINT_COMMANDS); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"HWRecoveryResetSGX: SGXREGDebugCommandsPart2 SGXRunScript failed (%d)", eError)); -+ } -+ } -+ /* Scripts end */ -+ -+#if defined(SUPPORT_HWRECOVERY_TRACE_LIMIT) -+/* -+ * The following defines are system specific and should be defined in -+ * the corresponding sysconfig.h file. The values indicated are examples only. -+ SYS_SGX_HWRECOVERY_TRACE_RESET_TIME_PERIOD 5000000 //(5 Seconds) -+ SYS_SGX_MAX_HWRECOVERY_OCCURANCE_COUNT 5 -+ */ -+ ui32TempClockinus = OSClockus(); -+ if((ui32TempClockinus-ui32Clockinus) < SYS_SGX_HWRECOVERY_TRACE_RESET_TIME_PERIOD){ -+ ui32HWRecoveryCount++; -+ if(SYS_SGX_MAX_HWRECOVERY_OCCURANCE_COUNT <= ui32HWRecoveryCount){ -+ OSPanic(); -+ } -+ }else{ -+ ui32Clockinus = ui32TempClockinus; -+ SGXDumpDebugInfo(psDeviceNode->pvDevice, IMG_TRUE); -+ ui32HWRecoveryCount = 0; -+ } -+#else -+ SGXDumpDebugInfo(psDeviceNode->pvDevice, IMG_TRUE); -+#endif -+ -+ /* Suspend pdumping. */ -+ PDUMPSUSPEND(); -+ -+ /* Reset and re-initialise SGX. */ -+ eError = SGXInitialise(psDevInfo, IMG_TRUE); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"HWRecoveryResetSGX: SGXInitialise failed (%d)", eError)); -+ } -+ -+ /* Resume pdumping. */ -+ PDUMPRESUME(); -+ -+ PVRSRVPowerUnlock(ui32CallerID); -+ -+ /* Send a dummy kick so that we start processing again */ -+ SGXScheduleProcessQueuesKM(psDeviceNode); -+ -+ /* Flush any old commands from the queues. */ -+ PVRSRVProcessQueues(IMG_TRUE); -+} -+#endif /* #if defined(SYS_USING_INTERRUPTS) || defined(SUPPORT_HW_RECOVERY) */ -+ -+ -+#if defined(SUPPORT_HW_RECOVERY) -+/*! -+****************************************************************************** -+ -+ @Function SGXOSTimer -+ -+ @Description -+ -+ Timer function for SGX -+ -+ @Input pvData - private data -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+IMG_VOID SGXOSTimer(IMG_VOID *pvData) -+{ -+ PVRSRV_DEVICE_NODE *psDeviceNode = pvData; -+ PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; -+ static IMG_UINT32 ui32EDMTasks = 0; -+ static IMG_UINT32 ui32LockupCounter = 0; /* To prevent false positives */ -+ static IMG_UINT32 ui32OpenCLDelayCounter = 0; -+ static IMG_UINT32 ui32NumResets = 0; -+#if defined(FIX_HW_BRN_31093) -+ static IMG_BOOL bBRN31093Inval = IMG_FALSE; -+#endif -+ IMG_UINT32 ui32CurrentEDMTasks; -+ IMG_UINT32 ui32CurrentOpenCLDelayCounter=0; -+ IMG_BOOL bLockup = IMG_FALSE; -+ IMG_BOOL bPoweredDown; -+ -+ /* increment a timestamp */ -+ psDevInfo->ui32TimeStamp++; -+ -+#if defined(NO_HARDWARE) -+ bPoweredDown = IMG_TRUE; -+#else -+ bPoweredDown = (SGXIsDevicePowered(psDeviceNode)) ? IMG_FALSE : IMG_TRUE; -+#endif /* NO_HARDWARE */ -+ -+ /* -+ * Check whether EDM timer tasks are getting scheduled. If not, assume -+ * that SGX has locked up and reset the chip. -+ */ -+ -+ /* Check whether the timer should be running */ -+ if (bPoweredDown) -+ { -+ ui32LockupCounter = 0; -+ #if defined(FIX_HW_BRN_31093) -+ bBRN31093Inval = IMG_FALSE; -+ #endif -+ } -+ else -+ { -+ /* The PDS timer should be running. */ -+ ui32CurrentEDMTasks = OSReadHWReg(psDevInfo->pvRegsBaseKM, psDevInfo->ui32EDMTaskReg0); -+ if (psDevInfo->ui32EDMTaskReg1 != 0) -+ { -+ ui32CurrentEDMTasks ^= OSReadHWReg(psDevInfo->pvRegsBaseKM, psDevInfo->ui32EDMTaskReg1); -+ } -+ if ((ui32CurrentEDMTasks == ui32EDMTasks) && -+ (psDevInfo->ui32NumResets == ui32NumResets)) -+ { -+ ui32LockupCounter++; -+ if (ui32LockupCounter == 3) -+ { -+ ui32LockupCounter = 0; -+ ui32CurrentOpenCLDelayCounter = (psDevInfo->psSGXHostCtl)->ui32OpenCLDelayCount; -+ if(0 != ui32CurrentOpenCLDelayCounter) -+ { -+ if(ui32OpenCLDelayCounter != ui32CurrentOpenCLDelayCounter){ -+ ui32OpenCLDelayCounter = ui32CurrentOpenCLDelayCounter; -+ }else{ -+ ui32OpenCLDelayCounter -= 1; -+ (psDevInfo->psSGXHostCtl)->ui32OpenCLDelayCount = ui32OpenCLDelayCounter; -+ } -+ goto SGX_NoUKernel_LockUp; -+ } -+ -+ -+ #if defined(FIX_HW_BRN_31093) -+ if (bBRN31093Inval == IMG_FALSE) -+ { -+ /* It could be a BIF hang so do a INVAL_PTE */ -+ #if defined(FIX_HW_BRN_29997) -+ IMG_UINT32 ui32BIFCtrl; -+ /* Pause the BIF before issuing the invalidate */ -+ ui32BIFCtrl = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL); -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32BIFCtrl | EUR_CR_BIF_CTRL_PAUSE_MASK); -+ /* delay for 200 clocks */ -+ SGXWaitClocks(psDevInfo, 200); -+ #endif -+ /* Flag that we have attempt to un-block the BIF */ -+ bBRN31093Inval = IMG_TRUE; -+ -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL_INVAL, EUR_CR_BIF_CTRL_INVAL_PTE_MASK); -+ /* delay for 200 clocks */ -+ SGXWaitClocks(psDevInfo, 200); -+ -+ #if defined(FIX_HW_BRN_29997) -+ /* un-pause the BIF by restoring the BIF_CTRL */ -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32BIFCtrl); -+ #endif -+ } -+ else -+ #endif -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SGXOSTimer() detected SGX lockup (0x%x tasks)", ui32EDMTasks)); -+ -+ bLockup = IMG_TRUE; -+ (psDevInfo->psSGXHostCtl)->ui32OpenCLDelayCount = 0; -+ } -+ } -+ } -+ else -+ { -+ #if defined(FIX_HW_BRN_31093) -+ bBRN31093Inval = IMG_FALSE; -+ #endif -+ ui32LockupCounter = 0; -+ ui32EDMTasks = ui32CurrentEDMTasks; -+ ui32NumResets = psDevInfo->ui32NumResets; -+ } -+ } -+SGX_NoUKernel_LockUp: -+ -+ if (bLockup) -+ { -+ SGXMKIF_HOST_CTL *psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psSGXHostCtl; -+ -+ /* increment the counter so we know the host detected the lockup */ -+ psSGXHostCtl->ui32HostDetectedLockups ++; -+ -+ /* Reset the chip and process the queues. */ -+ HWRecoveryResetSGX(psDeviceNode, 0, ISR_ID); -+ } -+} -+#endif /* defined(SUPPORT_HW_RECOVERY) */ -+ -+ -+ -+#if defined(SYS_USING_INTERRUPTS) -+ -+/* -+ SGX ISR Handler -+*/ -+IMG_BOOL SGX_ISRHandler (IMG_VOID *pvData) -+{ -+ IMG_BOOL bInterruptProcessed = IMG_FALSE; -+ -+ -+ /* Real Hardware */ -+ { -+ IMG_UINT32 ui32EventStatus, ui32EventEnable; -+ IMG_UINT32 ui32EventClear = 0; -+#if defined(SGX_FEATURE_DATA_BREAKPOINTS) -+ IMG_UINT32 ui32EventStatus2, ui32EventEnable2; -+#endif -+ IMG_UINT32 ui32EventClear2 = 0; -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+ PVRSRV_SGXDEV_INFO *psDevInfo; -+ -+ /* check for null pointers */ -+ if(pvData == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SGX_ISRHandler: Invalid params\n")); -+ return bInterruptProcessed; -+ } -+ -+ psDeviceNode = (PVRSRV_DEVICE_NODE *)pvData; -+ psDevInfo = (PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice; -+ -+ ui32EventStatus = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_STATUS); -+ ui32EventEnable = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_ENABLE); -+ -+ /* test only the unmasked bits */ -+ ui32EventStatus &= ui32EventEnable; -+ -+#if defined(SGX_FEATURE_DATA_BREAKPOINTS) -+ ui32EventStatus2 = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_STATUS2); -+ ui32EventEnable2 = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_ENABLE2); -+ -+ /* test only the unmasked bits */ -+ ui32EventStatus2 &= ui32EventEnable2; -+#endif /* defined(SGX_FEATURE_DATA_BREAKPOINTS) */ -+ -+ /* Thought: is it better to insist that the bit assignment in -+ the "clear" register(s) matches that of the "status" register(s)? -+ It would greatly simplify this LISR */ -+ -+ if (ui32EventStatus & EUR_CR_EVENT_STATUS_SW_EVENT_MASK) -+ { -+ ui32EventClear |= EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_MASK; -+ } -+ -+#if defined(SGX_FEATURE_DATA_BREAKPOINTS) -+ if (ui32EventStatus2 & EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_UNTRAPPED_MASK) -+ { -+ ui32EventClear2 |= EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_UNTRAPPED_MASK; -+ } -+ -+ if (ui32EventStatus2 & EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_TRAPPED_MASK) -+ { -+ ui32EventClear2 |= EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_TRAPPED_MASK; -+ } -+#endif /* defined(SGX_FEATURE_DATA_BREAKPOINTS) */ -+ -+ if (ui32EventClear || ui32EventClear2) -+ { -+ bInterruptProcessed = IMG_TRUE; -+ -+ /* Clear master interrupt bit */ -+ ui32EventClear |= EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_MASK; -+ -+ /* clear the events */ -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR, ui32EventClear); -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR2, ui32EventClear2); -+ -+ /* -+ Sample the current count from the uKernel _after_ we've cleared the -+ interrupt. -+ */ -+ g_ui32HostIRQCountSample = psDevInfo->psSGXHostCtl->ui32InterruptCount; -+ } -+ } -+ -+ return bInterruptProcessed; -+} -+ -+ -+/* -+ SGX MISR Handler -+*/ -+static IMG_VOID SGX_MISRHandler (IMG_VOID *pvData) -+{ -+ PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)pvData; -+ PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO*)psDeviceNode->pvDevice; -+ SGXMKIF_HOST_CTL *psSGXHostCtl = (SGXMKIF_HOST_CTL *)psDevInfo->psSGXHostCtl; -+ -+ if (((psSGXHostCtl->ui32InterruptFlags & PVRSRV_USSE_EDM_INTERRUPT_HWR) != 0UL) && -+ ((psSGXHostCtl->ui32InterruptClearFlags & PVRSRV_USSE_EDM_INTERRUPT_HWR) == 0UL)) -+ { -+ HWRecoveryResetSGX(psDeviceNode, 0, ISR_ID); -+ } -+ -+#if defined(OS_SUPPORTS_IN_LISR) -+ if (psDeviceNode->bReProcessDeviceCommandComplete) -+ { -+ SGXScheduleProcessQueuesKM(psDeviceNode); -+ } -+#endif -+ -+ SGXTestActivePowerEvent(psDeviceNode, ISR_ID); -+} -+#endif /* #if defined (SYS_USING_INTERRUPTS) */ -+ -+#if defined(SUPPORT_MEMORY_TILING) -+ -+IMG_INTERNAL -+PVRSRV_ERROR SGX_AllocMemTilingRange(PVRSRV_DEVICE_NODE *psDeviceNode, -+ PVRSRV_KERNEL_MEM_INFO *psMemInfo, -+ IMG_UINT32 ui32XTileStride, -+ IMG_UINT32 *pui32RangeIndex) -+{ -+ return SGX_AllocMemTilingRangeInt(psDeviceNode->pvDevice, -+ psMemInfo->sDevVAddr.uiAddr, -+ psMemInfo->sDevVAddr.uiAddr + ((IMG_UINT32) psMemInfo->uAllocSize) + SGX_MMU_PAGE_SIZE - 1, -+ ui32XTileStride, -+ pui32RangeIndex); -+} -+ -+IMG_INTERNAL -+PVRSRV_ERROR SGX_FreeMemTilingRange(PVRSRV_DEVICE_NODE *psDeviceNode, -+ IMG_UINT32 ui32RangeIndex) -+{ -+ PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; -+ IMG_UINT32 ui32Offset; -+ IMG_UINT32 ui32Val; -+ -+ if(ui32RangeIndex >= 10) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SGX_FreeMemTilingRange: invalid Range index ")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ /* clear the usage bit */ -+ psDevInfo->ui32MemTilingUsage &= ~(1<<ui32RangeIndex); -+ -+ /* disable the range */ -+ ui32Offset = EUR_CR_BIF_TILE0 + (ui32RangeIndex<<2); -+ ui32Val = 0; -+ -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32Offset, ui32Val); -+ PDUMPREG(SGX_PDUMPREG_NAME, ui32Offset, ui32Val); -+ -+ return PVRSRV_OK; -+} -+ -+#endif /* defined(SUPPORT_MEMORY_TILING) */ -+ -+ -+static IMG_VOID SGXCacheInvalidate(PVRSRV_DEVICE_NODE *psDeviceNode) -+{ -+ PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; -+ -+ #if defined(SGX_FEATURE_MP) -+ psDevInfo->ui32CacheControl |= SGXMKIF_CC_INVAL_BIF_SL; -+ #else -+ PVR_UNREFERENCED_PARAMETER(psDevInfo); -+ #endif /* SGX_FEATURE_MP */ -+} -+ -+/*! -+******************************************************************************* -+ -+ @Function SGXRegisterDevice -+ -+ @Description -+ -+ Registers the device with the system -+ -+ @Input: psDeviceNode - device node -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+PVRSRV_ERROR SGXRegisterDevice (PVRSRV_DEVICE_NODE *psDeviceNode) -+{ -+ DEVICE_MEMORY_INFO *psDevMemoryInfo; -+ DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; -+ -+ /* setup details that never change */ -+ psDeviceNode->sDevId.eDeviceType = DEV_DEVICE_TYPE; -+ psDeviceNode->sDevId.eDeviceClass = DEV_DEVICE_CLASS; -+#if defined(PDUMP) -+ { -+ /* memory space names are set up in system code */ -+ SGX_DEVICE_MAP *psSGXDeviceMemMap; -+ SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE_SGX, -+ (IMG_VOID**)&psSGXDeviceMemMap); -+ -+ psDeviceNode->sDevId.pszPDumpDevName = psSGXDeviceMemMap->pszPDumpDevName; -+ PVR_ASSERT(psDeviceNode->sDevId.pszPDumpDevName != IMG_NULL); -+ } -+ -+ psDeviceNode->sDevId.pszPDumpRegName = SGX_PDUMPREG_NAME; -+#endif /* PDUMP */ -+ -+ psDeviceNode->pfnInitDevice = &DevInitSGXPart1; -+ psDeviceNode->pfnDeInitDevice = &DevDeInitSGX; -+ -+ psDeviceNode->pfnInitDeviceCompatCheck = &SGXDevInitCompatCheck; -+#if defined(PDUMP) -+ psDeviceNode->pfnPDumpInitDevice = &SGXResetPDump; -+ psDeviceNode->pfnMMUGetContextID = &MMU_GetPDumpContextID; -+#endif -+ /* -+ MMU callbacks -+ */ -+ psDeviceNode->pfnMMUInitialise = &MMU_Initialise; -+ psDeviceNode->pfnMMUFinalise = &MMU_Finalise; -+ psDeviceNode->pfnMMUInsertHeap = &MMU_InsertHeap; -+ psDeviceNode->pfnMMUCreate = &MMU_Create; -+ psDeviceNode->pfnMMUDelete = &MMU_Delete; -+ psDeviceNode->pfnMMUAlloc = &MMU_Alloc; -+ psDeviceNode->pfnMMUFree = &MMU_Free; -+ psDeviceNode->pfnMMUMapPages = &MMU_MapPages; -+ psDeviceNode->pfnMMUMapShadow = &MMU_MapShadow; -+ psDeviceNode->pfnMMUUnmapPages = &MMU_UnmapPages; -+ psDeviceNode->pfnMMUMapScatter = &MMU_MapScatter; -+ psDeviceNode->pfnMMUGetPhysPageAddr = &MMU_GetPhysPageAddr; -+ psDeviceNode->pfnMMUGetPDDevPAddr = &MMU_GetPDDevPAddr; -+#if defined(SUPPORT_PDUMP_MULTI_PROCESS) -+ psDeviceNode->pfnMMUIsHeapShared = &MMU_IsHeapShared; -+#endif -+#if defined(FIX_HW_BRN_31620) -+ psDeviceNode->pfnMMUGetCacheFlushRange = &MMU_GetCacheFlushRange; -+ psDeviceNode->pfnMMUGetPDPhysAddr = &MMU_GetPDPhysAddr; -+#else -+ psDeviceNode->pfnMMUGetCacheFlushRange = IMG_NULL; -+ psDeviceNode->pfnMMUGetPDPhysAddr = IMG_NULL; -+#endif -+ psDeviceNode->pfnMMUMapPagesSparse = &MMU_MapPagesSparse; -+ psDeviceNode->pfnMMUMapShadowSparse = &MMU_MapShadowSparse; -+ -+#if defined (SYS_USING_INTERRUPTS) -+ /* -+ SGX ISR handler -+ */ -+ psDeviceNode->pfnDeviceISR = SGX_ISRHandler; -+ psDeviceNode->pfnDeviceMISR = SGX_MISRHandler; -+#endif -+ -+#if defined(SUPPORT_MEMORY_TILING) -+ psDeviceNode->pfnAllocMemTilingRange = SGX_AllocMemTilingRange; -+ psDeviceNode->pfnFreeMemTilingRange = SGX_FreeMemTilingRange; -+#endif -+ -+ /* -+ SGX command complete handler -+ */ -+ psDeviceNode->pfnDeviceCommandComplete = &SGXCommandComplete; -+ -+ psDeviceNode->pfnCacheInvalidate = SGXCacheInvalidate; -+ -+ /* -+ and setup the device's memory map: -+ */ -+ psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo; -+ /* size of address space */ -+ psDevMemoryInfo->ui32AddressSpaceSizeLog2 = SGX_FEATURE_ADDRESS_SPACE_SIZE; -+ -+ /* flags, backing store details to be specified by system */ -+ psDevMemoryInfo->ui32Flags = 0; -+ -+ /* device memory heap info about each heap in a device address space */ -+ if(OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(DEVICE_MEMORY_HEAP_INFO) * SGX_MAX_HEAP_ID, -+ (IMG_VOID **)&psDevMemoryInfo->psDeviceMemoryHeap, 0, -+ "Array of Device Memory Heap Info") != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SGXRegisterDevice : Failed to alloc memory for DEVICE_MEMORY_HEAP_INFO")); -+ return (PVRSRV_ERROR_OUT_OF_MEMORY); -+ } -+ OSMemSet(psDevMemoryInfo->psDeviceMemoryHeap, 0, sizeof(DEVICE_MEMORY_HEAP_INFO) * SGX_MAX_HEAP_ID); -+ -+ psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap; -+ -+ /* -+ setup heaps -+ Note: backing store to be setup by system (defaults to UMA) -+ */ -+ -+ /************* general ***************/ -+ psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_GENERAL_HEAP_ID); -+ psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_GENERAL_HEAP_BASE; -+ psDeviceMemoryHeap->ui32HeapSize = SGX_GENERAL_HEAP_SIZE; -+ psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE -+ | PVRSRV_MEM_RAM_BACKED_ALLOCATION -+ | PVRSRV_HAP_SINGLE_PROCESS; -+ psDeviceMemoryHeap->pszName = "General"; -+ psDeviceMemoryHeap->pszBSName = "General BS"; -+ psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT; -+ /* set the default (4k). System can override these as required */ -+ psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE; -+#if !defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP) -+ /* specify the mapping heap ID for this device */ -+ psDevMemoryInfo->ui32MappingHeapID = (IMG_UINT32)(psDeviceMemoryHeap - psDevMemoryInfo->psDeviceMemoryHeap); -+#endif -+ psDeviceMemoryHeap++;/* advance to the next heap */ -+ -+#if defined(SUPPORT_MEMORY_TILING) -+ /************* VPB tiling ***************/ -+ psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_VPB_TILED_HEAP_ID); -+ psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_VPB_TILED_HEAP_BASE; -+ psDeviceMemoryHeap->ui32HeapSize = SGX_VPB_TILED_HEAP_SIZE; -+ psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE -+ | PVRSRV_MEM_RAM_BACKED_ALLOCATION -+ | PVRSRV_HAP_SINGLE_PROCESS; -+ psDeviceMemoryHeap->pszName = "VPB Tiled"; -+ psDeviceMemoryHeap->pszBSName = "VPB Tiled BS"; -+ psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT; -+ /* set the default (4k). System can override these as required */ -+ psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE; -+ psDeviceMemoryHeap->ui32XTileStride = SGX_VPB_TILED_HEAP_STRIDE; -+ PVR_DPF((PVR_DBG_WARNING, "VPB tiling heap tiling stride = 0x%x", psDeviceMemoryHeap->ui32XTileStride)); -+ psDeviceMemoryHeap++;/* advance to the next heap */ -+#endif -+ -+ /************* TA data ***************/ -+ psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_TADATA_HEAP_ID); -+ psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_TADATA_HEAP_BASE; -+ psDeviceMemoryHeap->ui32HeapSize = SGX_TADATA_HEAP_SIZE; -+ psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE -+ | PVRSRV_MEM_RAM_BACKED_ALLOCATION -+ | PVRSRV_HAP_MULTI_PROCESS; -+ psDeviceMemoryHeap->pszName = "TA Data"; -+ psDeviceMemoryHeap->pszBSName = "TA Data BS"; -+ psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT; -+ /* set the default (4k). System can override these as required */ -+ psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE; -+ psDeviceMemoryHeap++;/* advance to the next heap */ -+ -+ -+ /************* kernel code ***************/ -+ psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_KERNEL_CODE_HEAP_ID); -+ psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_KERNEL_CODE_HEAP_BASE; -+ psDeviceMemoryHeap->ui32HeapSize = SGX_KERNEL_CODE_HEAP_SIZE; -+ psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE -+ | PVRSRV_MEM_RAM_BACKED_ALLOCATION -+ | PVRSRV_HAP_MULTI_PROCESS; -+ psDeviceMemoryHeap->pszName = "Kernel Code"; -+ psDeviceMemoryHeap->pszBSName = "Kernel Code BS"; -+ psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED; -+ /* set the default (4k). System can override these as required */ -+ psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE; -+ psDeviceMemoryHeap++;/* advance to the next heap */ -+ -+ -+ /************* Kernel Video Data ***************/ -+ psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_KERNEL_DATA_HEAP_ID); -+ psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_KERNEL_DATA_HEAP_BASE; -+ psDeviceMemoryHeap->ui32HeapSize = SGX_KERNEL_DATA_HEAP_SIZE; -+ psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE -+ | PVRSRV_MEM_RAM_BACKED_ALLOCATION -+ | PVRSRV_HAP_MULTI_PROCESS; -+ psDeviceMemoryHeap->pszName = "KernelData"; -+ psDeviceMemoryHeap->pszBSName = "KernelData BS"; -+ psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED; -+ /* set the default (4k). System can override these as required */ -+ psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE; -+ psDeviceMemoryHeap++;/* advance to the next heap */ -+ -+ -+ /************* PixelShaderUSSE ***************/ -+ psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_PIXELSHADER_HEAP_ID); -+ psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_PIXELSHADER_HEAP_BASE; -+ /* -+ The actual size of the pixel and vertex shader heap must be such that all -+ addresses are within range of the one of the USSE code base registers, but -+ the addressable range is hardware-dependent. -+ SGX_PIXELSHADER_HEAP_SIZE is defined to be the maximum possible size -+ to ensure that the heap layout is consistent across all SGXs. -+ */ -+ psDeviceMemoryHeap->ui32HeapSize = ((10 << SGX_USE_CODE_SEGMENT_RANGE_BITS) - 0x00001000); -+ PVR_ASSERT(psDeviceMemoryHeap->ui32HeapSize <= SGX_PIXELSHADER_HEAP_SIZE); -+ psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE -+ | PVRSRV_MEM_RAM_BACKED_ALLOCATION -+ | PVRSRV_HAP_SINGLE_PROCESS; -+ psDeviceMemoryHeap->pszName = "PixelShaderUSSE"; -+ psDeviceMemoryHeap->pszBSName = "PixelShaderUSSE BS"; -+ psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT; -+ /* set the default (4k). System can override these as required */ -+ psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE; -+ psDeviceMemoryHeap++;/* advance to the next heap */ -+ -+ -+ /************* VertexShaderUSSE ***************/ -+ psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_VERTEXSHADER_HEAP_ID); -+ psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_VERTEXSHADER_HEAP_BASE; -+ /* See comment above with PixelShaderUSSE ui32HeapSize */ -+ psDeviceMemoryHeap->ui32HeapSize = ((4 << SGX_USE_CODE_SEGMENT_RANGE_BITS) - 0x00001000); -+ PVR_ASSERT(psDeviceMemoryHeap->ui32HeapSize <= SGX_VERTEXSHADER_HEAP_SIZE); -+ psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE -+ | PVRSRV_MEM_RAM_BACKED_ALLOCATION -+ | PVRSRV_HAP_SINGLE_PROCESS; -+ psDeviceMemoryHeap->pszName = "VertexShaderUSSE"; -+ psDeviceMemoryHeap->pszBSName = "VertexShaderUSSE BS"; -+ psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT; -+ /* set the default (4k). System can override these as required */ -+ psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE; -+ psDeviceMemoryHeap++;/* advance to the next heap */ -+ -+ -+ /************* PDS Pixel Code/Data ***************/ -+ psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_PDSPIXEL_CODEDATA_HEAP_ID); -+ psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_PDSPIXEL_CODEDATA_HEAP_BASE; -+ psDeviceMemoryHeap->ui32HeapSize = SGX_PDSPIXEL_CODEDATA_HEAP_SIZE; -+ psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE -+ | PVRSRV_MEM_RAM_BACKED_ALLOCATION -+ | PVRSRV_HAP_SINGLE_PROCESS; -+ psDeviceMemoryHeap->pszName = "PDSPixelCodeData"; -+ psDeviceMemoryHeap->pszBSName = "PDSPixelCodeData BS"; -+ psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT; -+ /* set the default (4k). System can override these as required */ -+ psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE; -+ psDeviceMemoryHeap++;/* advance to the next heap */ -+ -+ -+ /************* PDS Vertex Code/Data ***************/ -+ psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_PDSVERTEX_CODEDATA_HEAP_ID); -+ psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_PDSVERTEX_CODEDATA_HEAP_BASE; -+ psDeviceMemoryHeap->ui32HeapSize = SGX_PDSVERTEX_CODEDATA_HEAP_SIZE; -+ psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE -+ | PVRSRV_MEM_RAM_BACKED_ALLOCATION -+ | PVRSRV_HAP_SINGLE_PROCESS; -+ psDeviceMemoryHeap->pszName = "PDSVertexCodeData"; -+ psDeviceMemoryHeap->pszBSName = "PDSVertexCodeData BS"; -+ psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT; -+ /* set the default (4k). System can override these as required */ -+ psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE; -+ psDeviceMemoryHeap++;/* advance to the next heap */ -+ -+ -+ /************* CacheCoherent ***************/ -+ psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_SYNCINFO_HEAP_ID); -+ psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_SYNCINFO_HEAP_BASE; -+ psDeviceMemoryHeap->ui32HeapSize = SGX_SYNCINFO_HEAP_SIZE; -+ psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE -+ | PVRSRV_MEM_RAM_BACKED_ALLOCATION -+ | PVRSRV_HAP_MULTI_PROCESS; -+ psDeviceMemoryHeap->pszName = "CacheCoherent"; -+ psDeviceMemoryHeap->pszBSName = "CacheCoherent BS"; -+ psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED; -+ /* set the default (4k). System can override these as required */ -+ psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE; -+ /* set the sync heap id */ -+ psDevMemoryInfo->ui32SyncHeapID = (IMG_UINT32)(psDeviceMemoryHeap - psDevMemoryInfo->psDeviceMemoryHeap); -+ psDeviceMemoryHeap++;/* advance to the next heap */ -+ -+ -+ /************* Shared 3D Parameters ***************/ -+ psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_SHARED_3DPARAMETERS_HEAP_ID); -+ psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_SHARED_3DPARAMETERS_HEAP_BASE; -+ psDeviceMemoryHeap->ui32HeapSize = SGX_SHARED_3DPARAMETERS_HEAP_SIZE; -+ psDeviceMemoryHeap->pszName = "Shared 3DParameters"; -+ psDeviceMemoryHeap->pszBSName = "Shared 3DParameters BS"; -+ psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE -+ | PVRSRV_MEM_RAM_BACKED_ALLOCATION -+ | PVRSRV_HAP_MULTI_PROCESS; -+ psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED; -+ -+ /* set the default (4k). System can override these as required */ -+ psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE; -+ psDeviceMemoryHeap++;/* advance to the next heap */ -+ -+ /************* Percontext 3D Parameters ***************/ -+ psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_PERCONTEXT_3DPARAMETERS_HEAP_ID); -+ psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_PERCONTEXT_3DPARAMETERS_HEAP_BASE; -+ psDeviceMemoryHeap->ui32HeapSize = SGX_PERCONTEXT_3DPARAMETERS_HEAP_SIZE; -+ psDeviceMemoryHeap->pszName = "Percontext 3DParameters"; -+ psDeviceMemoryHeap->pszBSName = "Percontext 3DParameters BS"; -+ psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE -+ | PVRSRV_MEM_RAM_BACKED_ALLOCATION -+ | PVRSRV_HAP_SINGLE_PROCESS; -+ psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT; -+ /* set the default (4k). System can override these as required */ -+ psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE; -+ psDeviceMemoryHeap++;/* advance to the next heap */ -+ -+ -+#if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP) -+ /************* General Mapping ***************/ -+ psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_GENERAL_MAPPING_HEAP_ID); -+ psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_GENERAL_MAPPING_HEAP_BASE; -+ psDeviceMemoryHeap->ui32HeapSize = SGX_GENERAL_MAPPING_HEAP_SIZE; -+ psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE -+ | PVRSRV_MEM_RAM_BACKED_ALLOCATION -+ | PVRSRV_HAP_MULTI_PROCESS; -+ psDeviceMemoryHeap->pszName = "GeneralMapping"; -+ psDeviceMemoryHeap->pszBSName = "GeneralMapping BS"; -+ #if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) && defined(FIX_HW_BRN_23410) -+ /* -+ if((2D hardware is enabled) -+ && (multi-mem contexts enabled) -+ && (BRN23410 is present)) -+ - then don't make the heap per-context otherwise -+ the TA and 2D requestors must always be aligned to -+ the same address space which could affect performance -+ */ -+ psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED; -+ #else /* defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) && defined(FIX_HW_BRN_23410) */ -+ psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_PERCONTEXT; -+ #endif /* defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) && defined(FIX_HW_BRN_23410) */ -+ -+ /* set the default (4k). System can override these as required */ -+ psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE; -+ /* specify the mapping heap ID for this device */ -+ psDevMemoryInfo->ui32MappingHeapID = (IMG_UINT32)(psDeviceMemoryHeap - psDevMemoryInfo->psDeviceMemoryHeap); -+ psDeviceMemoryHeap++;/* advance to the next heap */ -+#endif /* #if defined(SUPPORT_SGX_GENERAL_MAPPING_HEAP) */ -+ -+ -+#if defined(SGX_FEATURE_2D_HARDWARE) -+ /************* 2D HW Heap ***************/ -+ psDeviceMemoryHeap->ui32HeapID = HEAP_ID( PVRSRV_DEVICE_TYPE_SGX, SGX_2D_HEAP_ID); -+ psDeviceMemoryHeap->sDevVAddrBase.uiAddr = SGX_2D_HEAP_BASE; -+ psDeviceMemoryHeap->ui32HeapSize = SGX_2D_HEAP_SIZE; -+ psDeviceMemoryHeap->ui32Attribs = PVRSRV_HAP_WRITECOMBINE -+ | PVRSRV_MEM_RAM_BACKED_ALLOCATION -+ | PVRSRV_HAP_SINGLE_PROCESS; -+ psDeviceMemoryHeap->pszName = "2D"; -+ psDeviceMemoryHeap->pszBSName = "2D BS"; -+ psDeviceMemoryHeap->DevMemHeapType = DEVICE_MEMORY_HEAP_SHARED_EXPORTED; -+ /* set the default (4k). System can override these as required */ -+ psDeviceMemoryHeap->ui32DataPageSize = SGX_MMU_PAGE_SIZE; -+ psDeviceMemoryHeap++;/* advance to the next heap */ -+#endif /* #if defined(SGX_FEATURE_2D_HARDWARE) */ -+ -+ -+ /* set the heap count */ -+ psDevMemoryInfo->ui32HeapCount = (IMG_UINT32)(psDeviceMemoryHeap - psDevMemoryInfo->psDeviceMemoryHeap); -+ -+ return PVRSRV_OK; -+} -+ -+#if defined(PDUMP) -+static -+PVRSRV_ERROR SGXResetPDump(PVRSRV_DEVICE_NODE *psDeviceNode) -+{ -+ PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)(psDeviceNode->pvDevice); -+ psDevInfo->psKernelCCBInfo->ui32CCBDumpWOff = 0; -+ PVR_DPF((PVR_DBG_MESSAGE, "Reset pdump CCB write offset.")); -+ -+ return PVRSRV_OK; -+} -+#endif /* PDUMP */ -+ -+ -+/*! -+******************************************************************************* -+ -+ @Function SGXGetClientInfoKM -+ -+ @Description Gets the client information -+ -+ @Input hDevCookie -+ -+ @Output psClientInfo -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR SGXGetClientInfoKM(IMG_HANDLE hDevCookie, -+ SGX_CLIENT_INFO* psClientInfo) -+{ -+ PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice; -+ -+ /* -+ If this is the first client to connect to SGX perform initialisation -+ */ -+ psDevInfo->ui32ClientRefCount++; -+ -+ /* -+ Copy information to the client info. -+ */ -+ psClientInfo->ui32ProcessID = OSGetCurrentProcessIDKM(); -+ -+ /* -+ Copy requested information. -+ */ -+ OSMemCopy(&psClientInfo->asDevData, &psDevInfo->asSGXDevData, sizeof(psClientInfo->asDevData)); -+ -+ /* just return OK */ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+******************************************************************************* -+ -+ @Function SGXPanic -+ -+ @Description -+ -+ Called when an unrecoverable situation is detected. Dumps SGX debug -+ information and tells the OS to panic. -+ -+ @Input psDevInfo - SGX device info -+ -+ @Return IMG_VOID -+ -+******************************************************************************/ -+IMG_VOID SGXPanic(PVRSRV_SGXDEV_INFO *psDevInfo) -+{ -+ PVR_LOG(("SGX panic")); -+ SGXDumpDebugInfo(psDevInfo, IMG_FALSE); -+ OSPanic(); -+} -+ -+ -+/*! -+******************************************************************************* -+ -+ @Function SGXDevInitCompatCheck -+ -+ @Description -+ -+ Check compatibility of host driver and microkernel (DDK and build options) -+ for SGX devices at services/device initialisation -+ -+ @Input psDeviceNode - device node -+ -+ @Return PVRSRV_ERROR - depending on mismatch found -+ -+******************************************************************************/ -+PVRSRV_ERROR SGXDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode) -+{ -+ PVRSRV_ERROR eError; -+ PVRSRV_SGXDEV_INFO *psDevInfo; -+ IMG_UINT32 ui32BuildOptions, ui32BuildOptionsMismatch; -+#if !defined(NO_HARDWARE) -+ PPVRSRV_KERNEL_MEM_INFO psMemInfo; -+ PVRSRV_SGX_MISCINFO_INFO *psSGXMiscInfoInt; /*!< internal misc info for ukernel */ -+ PVRSRV_SGX_MISCINFO_FEATURES *psSGXFeatures; -+ SGX_MISCINFO_STRUCT_SIZES *psSGXStructSizes; /*!< microkernel structure sizes */ -+ IMG_BOOL bStructSizesFailed; -+ -+ /* Exceptions list for core rev check, format is pairs of (hw rev, sw rev) */ -+ IMG_BOOL bCheckCoreRev; -+ const IMG_UINT32 aui32CoreRevExceptions[] = -+ { -+ 0x10100, 0x10101 -+ }; -+ const IMG_UINT32 ui32NumCoreExceptions = sizeof(aui32CoreRevExceptions) / (2*sizeof(IMG_UINT32)); -+ IMG_UINT i; -+#endif -+ -+ /* Ensure it's a SGX device */ -+ if(psDeviceNode->sDevId.eDeviceType != PVRSRV_DEVICE_TYPE_SGX) -+ { -+ PVR_LOG(("(FAIL) SGXInit: Device not of type SGX")); -+ eError = PVRSRV_ERROR_INVALID_PARAMS; -+ goto chk_exit; -+ } -+ -+ psDevInfo = psDeviceNode->pvDevice; -+ -+ /* -+ * 1. Check kernel-side and client-side build options -+ * 2. Ensure ukernel DDK version and driver DDK version are compatible -+ * 3. Check ukernel build options against kernel-side build options -+ */ -+ -+ /* -+ * Check KM build options against client-side host driver -+ */ -+ -+ ui32BuildOptions = (SGX_BUILD_OPTIONS); -+ if (ui32BuildOptions != psDevInfo->ui32ClientBuildOptions) -+ { -+ ui32BuildOptionsMismatch = ui32BuildOptions ^ psDevInfo->ui32ClientBuildOptions; -+ if ( (psDevInfo->ui32ClientBuildOptions & ui32BuildOptionsMismatch) != 0) -+ { -+ PVR_LOG(("(FAIL) SGXInit: Mismatch in client-side and KM driver build options; " -+ "extra options present in client-side driver: (0x%x). Please check sgx_options.h", -+ psDevInfo->ui32ClientBuildOptions & ui32BuildOptionsMismatch )); -+ } -+ -+ if ( (ui32BuildOptions & ui32BuildOptionsMismatch) != 0) -+ { -+ PVR_LOG(("(FAIL) SGXInit: Mismatch in client-side and KM driver build options; " -+ "extra options present in KM: (0x%x). Please check sgx_options.h", -+ ui32BuildOptions & ui32BuildOptionsMismatch )); -+ } -+ eError = PVRSRV_ERROR_BUILD_MISMATCH; -+ goto chk_exit; -+ } -+ else -+ { -+ PVR_DPF((PVR_DBG_MESSAGE, "SGXInit: Client-side and KM driver build options match. [ OK ]")); -+ } -+ -+#if !defined (NO_HARDWARE) -+ psMemInfo = psDevInfo->psKernelSGXMiscMemInfo; -+ -+ /* Clear state (not strictly necessary since this is the first call) */ -+ psSGXMiscInfoInt = psMemInfo->pvLinAddrKM; -+ psSGXMiscInfoInt->ui32MiscInfoFlags = 0; -+ psSGXMiscInfoInt->ui32MiscInfoFlags |= PVRSRV_USSE_MISCINFO_GET_STRUCT_SIZES; -+ eError = SGXGetMiscInfoUkernel(psDevInfo, psDeviceNode, IMG_NULL); -+ -+ /* -+ * Validate DDK version -+ */ -+ if(eError != PVRSRV_OK) -+ { -+ PVR_LOG(("(FAIL) SGXInit: Unable to validate device DDK version")); -+ goto chk_exit; -+ } -+ psSGXFeatures = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXFeatures; -+ if( (psSGXFeatures->ui32DDKVersion != -+ ((PVRVERSION_MAJ << 16) | -+ (PVRVERSION_MIN << 8))) || -+ (psSGXFeatures->ui32DDKBuild != PVRVERSION_BUILD) ) -+ { -+ PVR_LOG(("(FAIL) SGXInit: Incompatible driver DDK revision (%d)/device DDK revision (%d).", -+ PVRVERSION_BUILD, psSGXFeatures->ui32DDKBuild)); -+ eError = PVRSRV_ERROR_DDK_VERSION_MISMATCH; -+ goto chk_exit; -+ } -+ else -+ { -+ PVR_DPF((PVR_DBG_MESSAGE, "SGXInit: driver DDK (%d) and device DDK (%d) match. [ OK ]", -+ PVRVERSION_BUILD, psSGXFeatures->ui32DDKBuild)); -+ } -+ -+ /* -+ * Check hardware core revision is compatible with the one in software -+ */ -+ if (psSGXFeatures->ui32CoreRevSW == 0) -+ { -+ /* -+ Head core revision cannot be checked. -+ */ -+ PVR_LOG(("SGXInit: HW core rev (%x) check skipped.", -+ psSGXFeatures->ui32CoreRev)); -+ } -+ else -+ { -+ /* For some cores the hw/sw core revisions are expected not to match. For these -+ * exceptional cases the core rev compatibility check should be skipped. -+ */ -+ bCheckCoreRev = IMG_TRUE; -+ for(i=0; i<ui32NumCoreExceptions; i+=2) -+ { -+ if( (psSGXFeatures->ui32CoreRev==aui32CoreRevExceptions[i]) && -+ (psSGXFeatures->ui32CoreRevSW==aui32CoreRevExceptions[i+1]) ) -+ { -+ PVR_LOG(("SGXInit: HW core rev (%x), SW core rev (%x) check skipped.", -+ psSGXFeatures->ui32CoreRev, -+ psSGXFeatures->ui32CoreRevSW)); -+ bCheckCoreRev = IMG_FALSE; -+ } -+ } -+ -+ if (bCheckCoreRev) -+ { -+ if (psSGXFeatures->ui32CoreRev != psSGXFeatures->ui32CoreRevSW) -+ { -+ PVR_LOG(("(FAIL) SGXInit: Incompatible HW core rev (%x) and SW core rev (%x).", -+ psSGXFeatures->ui32CoreRev, psSGXFeatures->ui32CoreRevSW)); -+ eError = PVRSRV_ERROR_BUILD_MISMATCH; -+ goto chk_exit; -+ } -+ else -+ { -+ PVR_DPF((PVR_DBG_MESSAGE, "SGXInit: HW core rev (%x) and SW core rev (%x) match. [ OK ]", -+ psSGXFeatures->ui32CoreRev, psSGXFeatures->ui32CoreRevSW)); -+ } -+ } -+ } -+ -+ /* -+ * Check ukernel structure sizes are the same as those in the driver -+ */ -+ psSGXStructSizes = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXStructSizes; -+ -+ bStructSizesFailed = IMG_FALSE; -+ -+ CHECK_SIZE(HOST_CTL); -+ CHECK_SIZE(COMMAND); -+#if defined(SGX_FEATURE_2D_HARDWARE) -+ CHECK_SIZE(2DCMD); -+ CHECK_SIZE(2DCMD_SHARED); -+#endif -+ CHECK_SIZE(CMDTA); -+ CHECK_SIZE(CMDTA_SHARED); -+ CHECK_SIZE(TRANSFERCMD); -+ CHECK_SIZE(TRANSFERCMD_SHARED); -+ -+ CHECK_SIZE(3DREGISTERS); -+ CHECK_SIZE(HWPBDESC); -+ CHECK_SIZE(HWRENDERCONTEXT); -+ CHECK_SIZE(HWRENDERDETAILS); -+ CHECK_SIZE(HWRTDATA); -+ CHECK_SIZE(HWRTDATASET); -+ CHECK_SIZE(HWTRANSFERCONTEXT); -+ -+ if (bStructSizesFailed == IMG_TRUE) -+ { -+ PVR_LOG(("(FAIL) SGXInit: Mismatch in SGXMKIF structure sizes.")); -+ eError = PVRSRV_ERROR_BUILD_MISMATCH; -+ goto chk_exit; -+ } -+ else -+ { -+ PVR_DPF((PVR_DBG_MESSAGE, "SGXInit: SGXMKIF structure sizes match. [ OK ]")); -+ } -+ -+ /* -+ * Check ukernel build options against KM host driver -+ */ -+ -+ ui32BuildOptions = psSGXFeatures->ui32BuildOptions; -+ if (ui32BuildOptions != (SGX_BUILD_OPTIONS)) -+ { -+ ui32BuildOptionsMismatch = ui32BuildOptions ^ (SGX_BUILD_OPTIONS); -+ if ( ((SGX_BUILD_OPTIONS) & ui32BuildOptionsMismatch) != 0) -+ { -+ PVR_LOG(("(FAIL) SGXInit: Mismatch in driver and microkernel build options; " -+ "extra options present in driver: (0x%x). Please check sgx_options.h", -+ (SGX_BUILD_OPTIONS) & ui32BuildOptionsMismatch )); -+ } -+ -+ if ( (ui32BuildOptions & ui32BuildOptionsMismatch) != 0) -+ { -+ PVR_LOG(("(FAIL) SGXInit: Mismatch in driver and microkernel build options; " -+ "extra options present in microkernel: (0x%x). Please check sgx_options.h", -+ ui32BuildOptions & ui32BuildOptionsMismatch )); -+ } -+ eError = PVRSRV_ERROR_BUILD_MISMATCH; -+ goto chk_exit; -+ } -+ else -+ { -+ PVR_DPF((PVR_DBG_MESSAGE, "SGXInit: Driver and microkernel build options match. [ OK ]")); -+ } -+#endif // NO_HARDWARE -+ -+ eError = PVRSRV_OK; -+chk_exit: -+#if defined(IGNORE_SGX_INIT_COMPATIBILITY_CHECK) -+ return PVRSRV_OK; -+#else -+ return eError; -+#endif -+} -+ -+/* -+ * @Function SGXGetMiscInfoUkernel -+ * -+ * @Description Returns misc info (e.g. SGX build info/flags) from microkernel -+ * -+ * @Input psDevInfo : device info from init phase -+ * @Input psDeviceNode : device node, used for scheduling ukernel to query SGX features -+ * -+ * @Return PVRSRV_ERROR : -+ * -+ */ -+static -+PVRSRV_ERROR SGXGetMiscInfoUkernel(PVRSRV_SGXDEV_INFO *psDevInfo, -+ PVRSRV_DEVICE_NODE *psDeviceNode, -+ IMG_HANDLE hDevMemContext) -+{ -+ PVRSRV_ERROR eError; -+ SGXMKIF_COMMAND sCommandData; /* CCB command data */ -+ PVRSRV_SGX_MISCINFO_INFO *psSGXMiscInfoInt; /*!< internal misc info for ukernel */ -+ PVRSRV_SGX_MISCINFO_FEATURES *psSGXFeatures; /*!< sgx features for client */ -+ SGX_MISCINFO_STRUCT_SIZES *psSGXStructSizes; /*!< internal info: microkernel structure sizes */ -+ -+ PPVRSRV_KERNEL_MEM_INFO psMemInfo = psDevInfo->psKernelSGXMiscMemInfo; -+ -+ if (! psMemInfo->pvLinAddrKM) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SGXGetMiscInfoUkernel: Invalid address.")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ psSGXMiscInfoInt = psMemInfo->pvLinAddrKM; -+ psSGXFeatures = &psSGXMiscInfoInt->sSGXFeatures; -+ psSGXStructSizes = &psSGXMiscInfoInt->sSGXStructSizes; -+ -+ psSGXMiscInfoInt->ui32MiscInfoFlags &= ~PVRSRV_USSE_MISCINFO_READY; -+ -+ /* Reset SGX features */ -+ OSMemSet(psSGXFeatures, 0, sizeof(*psSGXFeatures)); -+ OSMemSet(psSGXStructSizes, 0, sizeof(*psSGXStructSizes)); -+ -+ /* set up buffer address for SGX features in CCB */ -+ sCommandData.ui32Data[1] = psMemInfo->sDevVAddr.uiAddr; /* device V addr of output buffer */ -+ -+ PDUMPCOMMENT("Microkernel kick for SGXGetMiscInfo"); -+ eError = SGXScheduleCCBCommandKM(psDeviceNode, -+ SGXMKIF_CMD_GETMISCINFO, -+ &sCommandData, -+ KERNEL_ID, -+ 0, -+ hDevMemContext, -+ IMG_FALSE); -+ -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SGXGetMiscInfoUkernel: SGXScheduleCCBCommandKM failed.")); -+ return eError; -+ } -+ -+ /* FIXME: DWORD value to determine code path in ukernel? -+ * E.g. could use getMiscInfo to obtain register values for diagnostics? */ -+ -+#if !defined(NO_HARDWARE) -+ { -+ IMG_BOOL bExit; -+ -+ bExit = IMG_FALSE; -+ LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) -+ { -+ if ((psSGXMiscInfoInt->ui32MiscInfoFlags & PVRSRV_USSE_MISCINFO_READY) != 0) -+ { -+ bExit = IMG_TRUE; -+ break; -+ } -+ } END_LOOP_UNTIL_TIMEOUT(); -+ -+ /*if the loop exited because a timeout*/ -+ if (!bExit) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SGXGetMiscInfoUkernel: Timeout occurred waiting for misc info.")); -+ return PVRSRV_ERROR_TIMEOUT; -+ } -+ } -+#endif /* NO_HARDWARE */ -+ -+ return PVRSRV_OK; -+} -+ -+ -+ -+/* -+ * @Function SGXGetMiscInfoKM -+ * -+ * @Description Returns miscellaneous SGX info -+ * -+ * @Input psDevInfo : device info from init phase -+ * @Input psDeviceNode : device node, used for scheduling ukernel to query SGX features -+ * -+ * @Output psMiscInfo : query request plus user-mode mem for holding returned data -+ * -+ * @Return PVRSRV_ERROR : -+ * -+ */ -+IMG_EXPORT -+PVRSRV_ERROR SGXGetMiscInfoKM(PVRSRV_SGXDEV_INFO *psDevInfo, -+ SGX_MISC_INFO *psMiscInfo, -+ PVRSRV_DEVICE_NODE *psDeviceNode, -+ IMG_HANDLE hDevMemContext) -+{ -+ PVRSRV_ERROR eError; -+ PPVRSRV_KERNEL_MEM_INFO psMemInfo = psDevInfo->psKernelSGXMiscMemInfo; -+ IMG_UINT32 *pui32MiscInfoFlags = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->ui32MiscInfoFlags; -+ -+ /* Reset the misc info state flags */ -+ *pui32MiscInfoFlags = 0; -+ -+#if !defined(SUPPORT_SGX_EDM_MEMORY_DEBUG) -+ PVR_UNREFERENCED_PARAMETER(hDevMemContext); -+#endif -+ -+ switch(psMiscInfo->eRequest) -+ { -+#if defined(SGX_FEATURE_DATA_BREAKPOINTS) -+ case SGX_MISC_INFO_REQUEST_SET_BREAKPOINT: -+ { -+ IMG_UINT32 ui32MaskDM; -+ IMG_UINT32 ui32CtrlWEnable; -+ IMG_UINT32 ui32CtrlREnable; -+ IMG_UINT32 ui32CtrlTrapEnable; -+ IMG_UINT32 ui32RegVal; -+ IMG_UINT32 ui32StartRegVal; -+ IMG_UINT32 ui32EndRegVal; -+ SGXMKIF_COMMAND sCommandData; -+ -+ /* Set or Clear BP? */ -+ if(psMiscInfo->uData.sSGXBreakpointInfo.bBPEnable) -+ { -+ /* set the break point */ -+ IMG_DEV_VIRTADDR sBPDevVAddr = psMiscInfo->uData.sSGXBreakpointInfo.sBPDevVAddr; -+ IMG_DEV_VIRTADDR sBPDevVAddrEnd = psMiscInfo->uData.sSGXBreakpointInfo.sBPDevVAddrEnd; -+ -+ /* BP address */ -+ ui32StartRegVal = sBPDevVAddr.uiAddr & EUR_CR_BREAKPOINT0_START_ADDRESS_MASK; -+ ui32EndRegVal = sBPDevVAddrEnd.uiAddr & EUR_CR_BREAKPOINT0_END_ADDRESS_MASK; -+ -+ ui32MaskDM = psMiscInfo->uData.sSGXBreakpointInfo.ui32DataMasterMask; -+ ui32CtrlWEnable = psMiscInfo->uData.sSGXBreakpointInfo.bWrite; -+ ui32CtrlREnable = psMiscInfo->uData.sSGXBreakpointInfo.bRead; -+ ui32CtrlTrapEnable = psMiscInfo->uData.sSGXBreakpointInfo.bTrapped; -+ -+ /* normal data BP */ -+ ui32RegVal = ((ui32MaskDM<<EUR_CR_BREAKPOINT0_MASK_DM_SHIFT) & EUR_CR_BREAKPOINT0_MASK_DM_MASK) | -+ ((ui32CtrlWEnable<<EUR_CR_BREAKPOINT0_CTRL_WENABLE_SHIFT) & EUR_CR_BREAKPOINT0_CTRL_WENABLE_MASK) | -+ ((ui32CtrlREnable<<EUR_CR_BREAKPOINT0_CTRL_RENABLE_SHIFT) & EUR_CR_BREAKPOINT0_CTRL_RENABLE_MASK) | -+ ((ui32CtrlTrapEnable<<EUR_CR_BREAKPOINT0_CTRL_TRAPENABLE_SHIFT) & EUR_CR_BREAKPOINT0_CTRL_TRAPENABLE_MASK); -+ } -+ else -+ { -+ /* clear the break point */ -+ ui32RegVal = ui32StartRegVal = ui32EndRegVal = 0; -+ } -+ -+ /* setup the command */ -+ sCommandData.ui32Data[0] = psMiscInfo->uData.sSGXBreakpointInfo.ui32BPIndex; -+ sCommandData.ui32Data[1] = ui32StartRegVal; -+ sCommandData.ui32Data[2] = ui32EndRegVal; -+ sCommandData.ui32Data[3] = ui32RegVal; -+ -+ /* clear signal flags */ -+ psDevInfo->psSGXHostCtl->ui32BPSetClearSignal = 0; -+ -+ PDUMPCOMMENT("Microkernel kick for setting a data breakpoint"); -+ eError = SGXScheduleCCBCommandKM(psDeviceNode, -+ SGXMKIF_CMD_DATABREAKPOINT, -+ &sCommandData, -+ KERNEL_ID, -+ 0, -+ hDevMemContext, -+ IMG_FALSE); -+ -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SGXGetMiscInfoKM: SGXScheduleCCBCommandKM failed.")); -+ return eError; -+ } -+ -+#if defined(NO_HARDWARE) -+ /* clear signal flags */ -+ psDevInfo->psSGXHostCtl->ui32BPSetClearSignal = 0; -+#else -+ { -+ IMG_BOOL bExit; -+ -+ bExit = IMG_FALSE; -+ LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) -+ { -+ if (psDevInfo->psSGXHostCtl->ui32BPSetClearSignal != 0) -+ { -+ bExit = IMG_TRUE; -+ /* clear signal flags */ -+ psDevInfo->psSGXHostCtl->ui32BPSetClearSignal = 0; -+ break; -+ } -+ } END_LOOP_UNTIL_TIMEOUT(); -+ -+ /*if the loop exited because a timeout*/ -+ if (!bExit) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SGXGetMiscInfoKM: Timeout occurred waiting BP set/clear")); -+ return PVRSRV_ERROR_TIMEOUT; -+ } -+ } -+#endif /* NO_HARDWARE */ -+ -+ return PVRSRV_OK; -+ } -+ -+ case SGX_MISC_INFO_REQUEST_POLL_BREAKPOINT: -+ { -+ /* This request checks to see whether a breakpoint has -+ been trapped. If so, it returns the number of the -+ breakpoint number that was trapped in ui32BPIndex, -+ sTrappedBPDevVAddr to the address which was trapped, -+ and sets bTrappedBP. Otherwise, bTrappedBP will be -+ false, and other fields should be ignored. */ -+ /* The uKernel is not used, since if we are stopped on a -+ breakpoint, it is not possible to guarantee that the -+ uKernel would be able to run */ -+#if !defined(NO_HARDWARE) -+#if defined(SGX_FEATURE_MP) -+ IMG_BOOL bTrappedBPMaster; -+ IMG_UINT32 ui32CoreNum, ui32TrappedBPCoreNum; -+#if defined(SGX_FEATURE_PERPIPE_BKPT_REGS) -+ IMG_UINT32 ui32PipeNum, ui32TrappedBPPipeNum; -+/* ui32PipeNum is the pipe number plus 1, or 0 to represent "partition" */ -+#define NUM_PIPES_PLUS_ONE (SGX_FEATURE_PERPIPE_BKPT_REGS_NUMPIPES+1) -+#endif -+ IMG_BOOL bTrappedBPAny; -+#endif /* defined(SGX_FEATURE_MP) */ -+ IMG_BOOL bFoundOne; -+ -+#if defined(SGX_FEATURE_MP) -+ ui32TrappedBPCoreNum = 0; -+ bTrappedBPMaster = !!(EUR_CR_MASTER_BREAKPOINT_TRAPPED_MASK & OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_BREAKPOINT)); -+ bTrappedBPAny = bTrappedBPMaster; -+#if defined(SGX_FEATURE_PERPIPE_BKPT_REGS) -+ ui32TrappedBPPipeNum = 0; /* just to keep the (incorrect) compiler happy */ -+#endif -+ for (ui32CoreNum = 0; ui32CoreNum < SGX_FEATURE_MP_CORE_COUNT_3D; ui32CoreNum++) -+ { -+#if defined(SGX_FEATURE_PERPIPE_BKPT_REGS) -+ /* FIXME: this macro makes the assumption that the PARTITION regs are the same -+ distance before the PIPE0 regs as the PIPE1 regs are after it, _and_ -+ assumes that the fields in the partition regs are in the same place -+ in the pipe regs. Need to validate these assumptions, or assert them */ -+#define SGX_MP_CORE_PIPE_SELECT(r,c,p) \ -+ ((SGX_MP_CORE_SELECT(EUR_CR_PARTITION_##r,c) + p*(EUR_CR_PIPE0_##r-EUR_CR_PARTITION_##r))) -+ for (ui32PipeNum = 0; ui32PipeNum < NUM_PIPES_PLUS_ONE; ui32PipeNum++) -+ { -+ bFoundOne = -+ 0 != (EUR_CR_PARTITION_BREAKPOINT_TRAPPED_MASK & -+ OSReadHWReg(psDevInfo->pvRegsBaseKM, -+ SGX_MP_CORE_PIPE_SELECT(BREAKPOINT, -+ ui32CoreNum, -+ ui32PipeNum))); -+ if (bFoundOne) -+ { -+ bTrappedBPAny = IMG_TRUE; -+ ui32TrappedBPCoreNum = ui32CoreNum; -+ ui32TrappedBPPipeNum = ui32PipeNum; -+ } -+ } -+#else /* defined(SGX_FEATURE_PERPIPE_BKPT_REGS) */ -+ bFoundOne = !!(EUR_CR_BREAKPOINT_TRAPPED_MASK & OSReadHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_SELECT(EUR_CR_BREAKPOINT, ui32CoreNum))); -+ if (bFoundOne) -+ { -+ bTrappedBPAny = IMG_TRUE; -+ ui32TrappedBPCoreNum = ui32CoreNum; -+ } -+#endif /* defined(SGX_FEATURE_PERPIPE_BKPT_REGS) */ -+ } -+ -+ psMiscInfo->uData.sSGXBreakpointInfo.bTrappedBP = bTrappedBPAny; -+#else /* defined(SGX_FEATURE_MP) */ -+#if defined(SGX_FEATURE_PERPIPE_BKPT_REGS) -+ #error Not yet considered the case for per-pipe regs in non-mp case -+#endif -+ psMiscInfo->uData.sSGXBreakpointInfo.bTrappedBP = 0 != (EUR_CR_BREAKPOINT_TRAPPED_MASK & OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BREAKPOINT)); -+#endif /* defined(SGX_FEATURE_MP) */ -+ -+ if (psMiscInfo->uData.sSGXBreakpointInfo.bTrappedBP) -+ { -+ IMG_UINT32 ui32Info0, ui32Info1; -+ -+#if defined(SGX_FEATURE_MP) -+#if defined(SGX_FEATURE_PERPIPE_BKPT_REGS) -+ ui32Info0 = OSReadHWReg(psDevInfo->pvRegsBaseKM, bTrappedBPMaster?EUR_CR_MASTER_BREAKPOINT_TRAP_INFO0:SGX_MP_CORE_PIPE_SELECT(BREAKPOINT_TRAP_INFO0, ui32TrappedBPCoreNum, ui32TrappedBPPipeNum)); -+ ui32Info1 = OSReadHWReg(psDevInfo->pvRegsBaseKM, bTrappedBPMaster?EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1:SGX_MP_CORE_PIPE_SELECT(BREAKPOINT_TRAP_INFO1, ui32TrappedBPCoreNum, ui32TrappedBPPipeNum)); -+#else /* defined(SGX_FEATURE_PERPIPE_BKPT_REGS) */ -+ ui32Info0 = OSReadHWReg(psDevInfo->pvRegsBaseKM, bTrappedBPMaster?EUR_CR_MASTER_BREAKPOINT_TRAP_INFO0:SGX_MP_CORE_SELECT(EUR_CR_BREAKPOINT_TRAP_INFO0, ui32TrappedBPCoreNum)); -+ ui32Info1 = OSReadHWReg(psDevInfo->pvRegsBaseKM, bTrappedBPMaster?EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1:SGX_MP_CORE_SELECT(EUR_CR_BREAKPOINT_TRAP_INFO1, ui32TrappedBPCoreNum)); -+#endif /* defined(SGX_FEATURE_PERPIPE_BKPT_REGS) */ -+#else /* defined(SGX_FEATURE_MP) */ -+ ui32Info0 = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BREAKPOINT_TRAP_INFO0); -+ ui32Info1 = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BREAKPOINT_TRAP_INFO1); -+#endif /* defined(SGX_FEATURE_MP) */ -+ -+#ifdef SGX_FEATURE_PERPIPE_BKPT_REGS -+ psMiscInfo->uData.sSGXBreakpointInfo.ui32BPIndex = (ui32Info1 & EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_NUMBER_MASK) >> EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_NUMBER_SHIFT; -+ psMiscInfo->uData.sSGXBreakpointInfo.sTrappedBPDevVAddr.uiAddr = ui32Info0 & EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO0_ADDRESS_MASK; -+ psMiscInfo->uData.sSGXBreakpointInfo.ui32TrappedBPBurstLength = (ui32Info1 & EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_SIZE_MASK) >> EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_SIZE_SHIFT; -+ psMiscInfo->uData.sSGXBreakpointInfo.bTrappedBPRead = !!(ui32Info1 & EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_RNW_MASK); -+ psMiscInfo->uData.sSGXBreakpointInfo.ui32TrappedBPDataMaster = (ui32Info1 & EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_DATA_MASTER_MASK) >> EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_DATA_MASTER_SHIFT; -+ psMiscInfo->uData.sSGXBreakpointInfo.ui32TrappedBPTag = (ui32Info1 & EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_TAG_MASK) >> EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_TAG_SHIFT; -+#else /* defined(SGX_FEATURE_PERPIPE_BKPT_REGS) */ -+ psMiscInfo->uData.sSGXBreakpointInfo.ui32BPIndex = (ui32Info1 & EUR_CR_BREAKPOINT_TRAP_INFO1_NUMBER_MASK) >> EUR_CR_BREAKPOINT_TRAP_INFO1_NUMBER_SHIFT; -+ psMiscInfo->uData.sSGXBreakpointInfo.sTrappedBPDevVAddr.uiAddr = ui32Info0 & EUR_CR_BREAKPOINT_TRAP_INFO0_ADDRESS_MASK; -+ psMiscInfo->uData.sSGXBreakpointInfo.ui32TrappedBPBurstLength = (ui32Info1 & EUR_CR_BREAKPOINT_TRAP_INFO1_SIZE_MASK) >> EUR_CR_BREAKPOINT_TRAP_INFO1_SIZE_SHIFT; -+ psMiscInfo->uData.sSGXBreakpointInfo.bTrappedBPRead = !!(ui32Info1 & EUR_CR_BREAKPOINT_TRAP_INFO1_RNW_MASK); -+ psMiscInfo->uData.sSGXBreakpointInfo.ui32TrappedBPDataMaster = (ui32Info1 & EUR_CR_BREAKPOINT_TRAP_INFO1_DATA_MASTER_MASK) >> EUR_CR_BREAKPOINT_TRAP_INFO1_DATA_MASTER_SHIFT; -+ psMiscInfo->uData.sSGXBreakpointInfo.ui32TrappedBPTag = (ui32Info1 & EUR_CR_BREAKPOINT_TRAP_INFO1_TAG_MASK) >> EUR_CR_BREAKPOINT_TRAP_INFO1_TAG_SHIFT; -+#endif /* defined(SGX_FEATURE_PERPIPE_BKPT_REGS) */ -+#if defined(SGX_FEATURE_MP) -+#if defined(SGX_FEATURE_PERPIPE_BKPT_REGS) -+ /* mp, per-pipe regbanks */ -+ psMiscInfo->uData.sSGXBreakpointInfo.ui32CoreNum = bTrappedBPMaster?65535:(ui32TrappedBPCoreNum + (ui32TrappedBPPipeNum<<10)); -+#else /* defined(SGX_FEATURE_PERPIPE_BKPT_REGS) */ -+ /* mp, regbanks unsplit */ -+ psMiscInfo->uData.sSGXBreakpointInfo.ui32CoreNum = bTrappedBPMaster?65535:ui32TrappedBPCoreNum; -+#endif /* defined(SGX_FEATURE_PERPIPE_BKPT_REGS) */ -+#else /* defined(SGX_FEATURE_MP) */ -+#if defined(SGX_FEATURE_PERPIPE_BKPT_REGS) -+ /* non-mp, per-pipe regbanks */ -+#error non-mp perpipe regs not yet supported -+#else /* defined(SGX_FEATURE_PERPIPE_BKPT_REGS) */ -+ /* non-mp */ -+ psMiscInfo->uData.sSGXBreakpointInfo.ui32CoreNum = 65534; -+#endif /* defined(SGX_FEATURE_PERPIPE_BKPT_REGS) */ -+#endif /* defined(SGX_FEATURE_MP) */ -+ } -+#endif /* !defined(NO_HARDWARE) */ -+ return PVRSRV_OK; -+ } -+ -+ case SGX_MISC_INFO_REQUEST_RESUME_BREAKPOINT: -+ { -+ /* This request resumes from the currently trapped breakpoint. */ -+ /* Core number must be supplied */ -+ /* Polls for notify to be acknowledged by h/w */ -+#if !defined(NO_HARDWARE) -+#if defined(SGX_FEATURE_MP) -+ IMG_UINT32 ui32CoreNum; -+ IMG_BOOL bMaster; -+#if defined(SGX_FEATURE_PERPIPE_BKPT_REGS) -+ IMG_UINT32 ui32PipeNum; -+#endif -+#endif /* defined(SGX_FEATURE_MP) */ -+ IMG_UINT32 ui32OldSeqNum, ui32NewSeqNum; -+ -+#if defined(SGX_FEATURE_MP) -+#if defined(SGX_FEATURE_PERPIPE_BKPT_REGS) -+ ui32PipeNum = psMiscInfo->uData.sSGXBreakpointInfo.ui32CoreNum >> 10; -+ ui32CoreNum = psMiscInfo->uData.sSGXBreakpointInfo.ui32CoreNum & 1023; -+ bMaster = psMiscInfo->uData.sSGXBreakpointInfo.ui32CoreNum > 32767; -+#else /* defined(SGX_FEATURE_PERPIPE_BKPT_REGS) */ -+ ui32CoreNum = psMiscInfo->uData.sSGXBreakpointInfo.ui32CoreNum; -+ bMaster = ui32CoreNum > SGX_FEATURE_MP_CORE_COUNT_3D; -+#endif /* defined(SGX_FEATURE_PERPIPE_BKPT_REGS) */ -+ if (bMaster) -+ { -+ /* master */ -+ /* EUR_CR_MASTER_BREAKPOINT_TRAPPED_MASK | EUR_CR_MASTER_BREAKPOINT_SEQNUM_MASK */ -+ ui32OldSeqNum = 0x1c & OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_BREAKPOINT); -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_BREAKPOINT_TRAP, EUR_CR_MASTER_BREAKPOINT_TRAP_WRNOTIFY_MASK | EUR_CR_MASTER_BREAKPOINT_TRAP_CONTINUE_MASK); -+ do -+ { -+ ui32NewSeqNum = 0x1c & OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_BREAKPOINT); -+ } -+ while (ui32OldSeqNum == ui32NewSeqNum); -+ } -+ else -+#endif /* defined(SGX_FEATURE_MP) */ -+ { -+ /* core */ -+#if defined(SGX_FEATURE_PERPIPE_BKPT_REGS) -+ ui32OldSeqNum = 0x1c & OSReadHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_PIPE_SELECT(BREAKPOINT, ui32CoreNum, ui32PipeNum)); -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_PIPE_SELECT(BREAKPOINT_TRAP, ui32CoreNum, ui32PipeNum), EUR_CR_PARTITION_BREAKPOINT_TRAP_WRNOTIFY_MASK | EUR_CR_PARTITION_BREAKPOINT_TRAP_CONTINUE_MASK); -+ do -+ { -+ ui32NewSeqNum = 0x1c & OSReadHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_PIPE_SELECT(BREAKPOINT, ui32CoreNum, ui32PipeNum)); -+ } -+ while (ui32OldSeqNum == ui32NewSeqNum); -+#else /* defined(SGX_FEATURE_PERPIPE_BKPT_REGS) */ -+ ui32OldSeqNum = 0x1c & OSReadHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_SELECT(EUR_CR_BREAKPOINT, ui32CoreNum)); -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_SELECT(EUR_CR_BREAKPOINT_TRAP, ui32CoreNum), EUR_CR_BREAKPOINT_TRAP_WRNOTIFY_MASK | EUR_CR_BREAKPOINT_TRAP_CONTINUE_MASK); -+ do -+ { -+ ui32NewSeqNum = 0x1c & OSReadHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_SELECT(EUR_CR_BREAKPOINT, ui32CoreNum)); -+ } -+ while (ui32OldSeqNum == ui32NewSeqNum); -+#endif /* defined(SGX_FEATURE_PERPIPE_BKPT_REGS) */ -+ } -+#endif /* !defined(NO_HARDWARE) */ -+ return PVRSRV_OK; -+ } -+#endif /* SGX_FEATURE_DATA_BREAKPOINTS) */ -+ -+ case SGX_MISC_INFO_REQUEST_CLOCKSPEED: -+ { -+ psMiscInfo->uData.ui32SGXClockSpeed = psDevInfo->ui32CoreClockSpeed; -+ return PVRSRV_OK; -+ } -+ -+ case SGX_MISC_INFO_REQUEST_CLOCKSPEED_SLCSIZE: -+ { -+ psMiscInfo->uData.sQueryClockSpeedSLCSize.ui32SGXClockSpeed = SYS_SGX_CLOCK_SPEED; -+#if defined(SGX_FEATURE_SYSTEM_CACHE) && defined(SYS_SGX_SLC_SIZE) -+ psMiscInfo->uData.sQueryClockSpeedSLCSize.ui32SGXSLCSize = SYS_SGX_SLC_SIZE; -+#else -+ psMiscInfo->uData.sQueryClockSpeedSLCSize.ui32SGXSLCSize = 0; -+#endif /* defined(SGX_FEATURE_SYSTEM_CACHE) && defined(SYS_SGX_SLC_SIZE) */ -+ return PVRSRV_OK; -+ } -+ -+ case SGX_MISC_INFO_REQUEST_ACTIVEPOWER: -+ { -+ psMiscInfo->uData.sActivePower.ui32NumActivePowerEvents = psDevInfo->psSGXHostCtl->ui32NumActivePowerEvents; -+ return PVRSRV_OK; -+ } -+ -+ case SGX_MISC_INFO_REQUEST_LOCKUPS: -+ { -+#if defined(SUPPORT_HW_RECOVERY) -+ psMiscInfo->uData.sLockups.ui32uKernelDetectedLockups = psDevInfo->psSGXHostCtl->ui32uKernelDetectedLockups; -+ psMiscInfo->uData.sLockups.ui32HostDetectedLockups = psDevInfo->psSGXHostCtl->ui32HostDetectedLockups; -+#else -+ psMiscInfo->uData.sLockups.ui32uKernelDetectedLockups = 0; -+ psMiscInfo->uData.sLockups.ui32HostDetectedLockups = 0; -+#endif -+ return PVRSRV_OK; -+ } -+ -+ case SGX_MISC_INFO_REQUEST_SPM: -+ { -+ /* this is dealt with in UM */ -+ return PVRSRV_OK; -+ } -+ -+ case SGX_MISC_INFO_REQUEST_SGXREV: -+ { -+ PVRSRV_SGX_MISCINFO_FEATURES *psSGXFeatures; -+// PPVRSRV_KERNEL_MEM_INFO psMemInfo = psDevInfo->psKernelSGXMiscMemInfo; -+ -+ eError = SGXGetMiscInfoUkernel(psDevInfo, psDeviceNode, hDevMemContext); -+ if(eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "An error occurred in SGXGetMiscInfoUkernel: %d\n", -+ eError)); -+ return eError; -+ } -+ psSGXFeatures = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXFeatures; -+ -+ /* Copy SGX features into misc info struct, to return to client */ -+ psMiscInfo->uData.sSGXFeatures = *psSGXFeatures; -+ -+ /* Debug output */ -+ PVR_DPF((PVR_DBG_MESSAGE, "SGXGetMiscInfoKM: Core 0x%x, sw ID 0x%x, sw Rev 0x%x\n", -+ psSGXFeatures->ui32CoreRev, -+ psSGXFeatures->ui32CoreIdSW, -+ psSGXFeatures->ui32CoreRevSW)); -+ PVR_DPF((PVR_DBG_MESSAGE, "SGXGetMiscInfoKM: DDK version 0x%x, DDK build 0x%x\n", -+ psSGXFeatures->ui32DDKVersion, -+ psSGXFeatures->ui32DDKBuild)); -+ -+ /* done! */ -+ return PVRSRV_OK; -+ } -+ -+ case SGX_MISC_INFO_REQUEST_DRIVER_SGXREV: -+ { -+ PVRSRV_SGX_MISCINFO_FEATURES *psSGXFeatures; -+ -+ psSGXFeatures = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXFeatures; -+ -+ /* Reset the misc information to prevent -+ * confusion with values returned from the ukernel -+ */ -+ OSMemSet(psMemInfo->pvLinAddrKM, 0, -+ sizeof(PVRSRV_SGX_MISCINFO_INFO)); -+ -+ psSGXFeatures->ui32DDKVersion = -+ (PVRVERSION_MAJ << 16) | -+ (PVRVERSION_MIN << 8); -+ psSGXFeatures->ui32DDKBuild = PVRVERSION_BUILD; -+ -+ /* Also report the kernel module build options -- used in SGXConnectionCheck() */ -+ psSGXFeatures->ui32BuildOptions = (SGX_BUILD_OPTIONS); -+ -+ /* Copy SGX features into misc info struct, to return to client */ -+ psMiscInfo->uData.sSGXFeatures = *psSGXFeatures; -+ return PVRSRV_OK; -+ } -+ -+#if defined(PVRSRV_USSE_EDM_STATUS_DEBUG) -+ case SGX_MISC_INFO_REQUEST_EDM_STATUS_BUFFER_INFO: -+ { -+ /* Report the EDM status buffer location in memory */ -+ psMiscInfo->uData.sEDMStatusBufferInfo.sDevVAEDMStatusBuffer = psDevInfo->psKernelEDMStatusBufferMemInfo->sDevVAddr; -+ psMiscInfo->uData.sEDMStatusBufferInfo.pvEDMStatusBuffer = psDevInfo->psKernelEDMStatusBufferMemInfo->pvLinAddrKM; -+ return PVRSRV_OK; -+ } -+#endif -+ -+#if defined(SUPPORT_SGX_EDM_MEMORY_DEBUG) -+ case SGX_MISC_INFO_REQUEST_MEMREAD: -+ case SGX_MISC_INFO_REQUEST_MEMCOPY: -+ { -+ PVRSRV_ERROR eError; -+ PVRSRV_SGX_MISCINFO_FEATURES *psSGXFeatures; -+ PVRSRV_SGX_MISCINFO_MEMACCESS *psSGXMemSrc; /* user-defined mem read */ -+ PVRSRV_SGX_MISCINFO_MEMACCESS *psSGXMemDest; /* user-defined mem write */ -+ -+ { -+ /* Set the mem read flag; src is user-defined */ -+ *pui32MiscInfoFlags |= PVRSRV_USSE_MISCINFO_MEMREAD; -+ psSGXMemSrc = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXMemAccessSrc; -+ -+ if(psMiscInfo->sDevVAddrSrc.uiAddr != 0) -+ { -+ psSGXMemSrc->sDevVAddr = psMiscInfo->sDevVAddrSrc; /* src address */ -+ } -+ else -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ } -+ -+ if( psMiscInfo->eRequest == SGX_MISC_INFO_REQUEST_MEMCOPY) -+ { -+ /* Set the mem write flag; dest is user-defined */ -+ *pui32MiscInfoFlags |= PVRSRV_USSE_MISCINFO_MEMWRITE; -+ psSGXMemDest = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXMemAccessDest; -+ -+ if(psMiscInfo->sDevVAddrDest.uiAddr != 0) -+ { -+ psSGXMemDest->sDevVAddr = psMiscInfo->sDevVAddrDest; /* dest address */ -+ } -+ else -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ } -+ -+ /* Get physical address of PD for memory read (may need to switch context in microkernel) */ -+ if(psMiscInfo->hDevMemContext != IMG_NULL) -+ { -+ SGXGetMMUPDAddrKM( (IMG_HANDLE)psDeviceNode, hDevMemContext, &psSGXMemSrc->sPDDevPAddr); -+ -+ /* Single app will always use the same src and dest mem context */ -+ psSGXMemDest->sPDDevPAddr = psSGXMemSrc->sPDDevPAddr; -+ } -+ else -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ /* Submit the task to the ukernel */ -+ eError = SGXGetMiscInfoUkernel(psDevInfo, psDeviceNode); -+ if(eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "An error occurred in SGXGetMiscInfoUkernel: %d\n", -+ eError)); -+ return eError; -+ } -+ psSGXFeatures = &((PVRSRV_SGX_MISCINFO_INFO*)(psMemInfo->pvLinAddrKM))->sSGXFeatures; -+ -+#if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) -+ if(*pui32MiscInfoFlags & PVRSRV_USSE_MISCINFO_MEMREAD_FAIL) -+ { -+ return PVRSRV_ERROR_INVALID_MISCINFO; -+ } -+#endif -+ /* Copy SGX features into misc info struct, to return to client */ -+ psMiscInfo->uData.sSGXFeatures = *psSGXFeatures; -+ return PVRSRV_OK; -+ } -+#endif /* SUPPORT_SGX_EDM_MEMORY_DEBUG */ -+ -+#if defined(SUPPORT_SGX_HWPERF) -+ case SGX_MISC_INFO_REQUEST_SET_HWPERF_STATUS: -+ { -+ PVRSRV_SGX_MISCINFO_SET_HWPERF_STATUS *psSetHWPerfStatus = &psMiscInfo->uData.sSetHWPerfStatus; -+ const IMG_UINT32 ui32ValidFlags = PVRSRV_SGX_HWPERF_STATUS_RESET_COUNTERS | -+ PVRSRV_SGX_HWPERF_STATUS_GRAPHICS_ON | -+ PVRSRV_SGX_HWPERF_STATUS_PERIODIC_ON | -+ PVRSRV_SGX_HWPERF_STATUS_MK_EXECUTION_ON; -+ SGXMKIF_COMMAND sCommandData = {0}; -+ -+ /* Check for valid flags */ -+ if ((psSetHWPerfStatus->ui32NewHWPerfStatus & ~ui32ValidFlags) != 0) -+ { -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ #if defined(PDUMP) -+ PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, -+ "SGX ukernel HWPerf status %u\n", -+ psSetHWPerfStatus->ui32NewHWPerfStatus); -+ #endif /* PDUMP */ -+ -+ /* Copy the new group selector(s) to the host ctl for the ukernel */ -+ #if defined(SGX_FEATURE_EXTENDED_PERF_COUNTERS) -+ OSMemCopy(&psDevInfo->psSGXHostCtl->aui32PerfGroup[0], -+ &psSetHWPerfStatus->aui32PerfGroup[0], -+ sizeof(psDevInfo->psSGXHostCtl->aui32PerfGroup)); -+ OSMemCopy(&psDevInfo->psSGXHostCtl->aui32PerfBit[0], -+ &psSetHWPerfStatus->aui32PerfBit[0], -+ sizeof(psDevInfo->psSGXHostCtl->aui32PerfBit)); -+ psDevInfo->psSGXHostCtl->ui32PerfCounterBitSelect = psSetHWPerfStatus->ui32PerfCounterBitSelect; -+ psDevInfo->psSGXHostCtl->ui32PerfSumMux = psSetHWPerfStatus->ui32PerfSumMux; -+ #if defined(PDUMP) -+ PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo, -+ offsetof(SGXMKIF_HOST_CTL, aui32PerfGroup), -+ sizeof(psDevInfo->psSGXHostCtl->aui32PerfGroup), -+ PDUMP_FLAGS_CONTINUOUS, -+ MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo)); -+ PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo, -+ offsetof(SGXMKIF_HOST_CTL, aui32PerfBit), -+ sizeof(psDevInfo->psSGXHostCtl->aui32PerfBit), -+ PDUMP_FLAGS_CONTINUOUS, -+ MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo)); -+ PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo, -+ offsetof(SGXMKIF_HOST_CTL, ui32PerfCounterBitSelect), -+ sizeof(psDevInfo->psSGXHostCtl->ui32PerfCounterBitSelect), -+ PDUMP_FLAGS_CONTINUOUS, -+ MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo)); -+ PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo, -+ offsetof(SGXMKIF_HOST_CTL, ui32PerfSumMux), -+ sizeof(psDevInfo->psSGXHostCtl->ui32PerfSumMux), -+ PDUMP_FLAGS_CONTINUOUS, -+ MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo)); -+ #endif /* PDUMP */ -+ #else -+ psDevInfo->psSGXHostCtl->ui32PerfGroup = psSetHWPerfStatus->ui32PerfGroup; -+ #if defined(PDUMP) -+ PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo, -+ offsetof(SGXMKIF_HOST_CTL, ui32PerfGroup), -+ sizeof(psDevInfo->psSGXHostCtl->ui32PerfGroup), -+ PDUMP_FLAGS_CONTINUOUS, -+ MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo)); -+ #endif /* PDUMP */ -+ #endif /* SGX_FEATURE_EXTENDED_PERF_COUNTERS */ -+ -+ /* Kick the ukernel to update the hardware state */ -+ sCommandData.ui32Data[0] = psSetHWPerfStatus->ui32NewHWPerfStatus; -+ eError = SGXScheduleCCBCommandKM(psDeviceNode, -+ SGXMKIF_CMD_SETHWPERFSTATUS, -+ &sCommandData, -+ KERNEL_ID, -+ 0, -+ hDevMemContext, -+ IMG_FALSE); -+ return eError; -+ } -+#endif /* SUPPORT_SGX_HWPERF */ -+ -+ case SGX_MISC_INFO_DUMP_DEBUG_INFO: -+ { -+ PVR_LOG(("User requested SGX debug info")); -+ -+ /* Dump SGX debug data to the kernel log. */ -+ SGXDumpDebugInfo(psDeviceNode->pvDevice, IMG_FALSE); -+ -+ return PVRSRV_OK; -+ } -+ -+ case SGX_MISC_INFO_DUMP_DEBUG_INFO_FORCE_REGS: -+ { -+ if(!OSProcHasPrivSrvInit()) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "Insufficient privileges to dump SGX " -+ "debug info with registers")); -+ -+ return PVRSRV_ERROR_INVALID_MISCINFO; -+ } -+ -+ PVR_LOG(("User requested SGX debug info")); -+ -+ /* Dump SGX debug data to the kernel log. */ -+ SGXDumpDebugInfo(psDeviceNode->pvDevice, IMG_TRUE); -+ -+ return PVRSRV_OK; -+ } -+ -+#if defined(DEBUG) -+ /* Don't allow user-mode to reboot the device in production drivers */ -+ case SGX_MISC_INFO_PANIC: -+ { -+ PVR_LOG(("User requested SGX panic")); -+ -+ SGXPanic(psDeviceNode->pvDevice); -+ -+ return PVRSRV_OK; -+ } -+#endif -+ -+ default: -+ { -+ /* switch statement fell though, so: */ -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ } -+} -+ -+ -+IMG_EXPORT -+PVRSRV_ERROR SGXReadHWPerfCBKM(IMG_HANDLE hDevHandle, -+ IMG_UINT32 ui32ArraySize, -+ PVRSRV_SGX_HWPERF_CB_ENTRY *psClientHWPerfEntry, -+ IMG_UINT32 *pui32DataCount, -+ IMG_UINT32 *pui32ClockSpeed, -+ IMG_UINT32 *pui32HostTimeStamp) -+{ -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle; -+ PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; -+ SGXMKIF_HWPERF_CB *psHWPerfCB = psDevInfo->psKernelHWPerfCBMemInfo->pvLinAddrKM; -+ IMG_UINT i; -+ -+ for (i = 0; -+ psHWPerfCB->ui32Woff != psHWPerfCB->ui32Roff && i < ui32ArraySize; -+ i++) -+ { -+ SGXMKIF_HWPERF_CB_ENTRY *psMKPerfEntry = &psHWPerfCB->psHWPerfCBData[psHWPerfCB->ui32Roff]; -+ -+ psClientHWPerfEntry[i].ui32FrameNo = psMKPerfEntry->ui32FrameNo; -+ psClientHWPerfEntry[i].ui32PID = psMKPerfEntry->ui32PID; -+ psClientHWPerfEntry[i].ui32RTData = psMKPerfEntry->ui32RTData; -+ psClientHWPerfEntry[i].ui32Type = psMKPerfEntry->ui32Type; -+ psClientHWPerfEntry[i].ui32Ordinal = psMKPerfEntry->ui32Ordinal; -+ psClientHWPerfEntry[i].ui32Info = psMKPerfEntry->ui32Info; -+ psClientHWPerfEntry[i].ui32Clocksx16 = SGXConvertTimeStamp(psDevInfo, -+ psMKPerfEntry->ui32TimeWraps, -+ psMKPerfEntry->ui32Time); -+ OSMemCopy(&psClientHWPerfEntry[i].ui32Counters[0][0], -+ &psMKPerfEntry->ui32Counters[0][0], -+ sizeof(psMKPerfEntry->ui32Counters)); -+ -+ OSMemCopy(&psClientHWPerfEntry[i].ui32MiscCounters[0][0], -+ &psMKPerfEntry->ui32MiscCounters[0][0], -+ sizeof(psMKPerfEntry->ui32MiscCounters)); -+ -+ psHWPerfCB->ui32Roff = (psHWPerfCB->ui32Roff + 1) & (SGXMKIF_HWPERF_CB_SIZE - 1); -+ } -+ -+ *pui32DataCount = i; -+ *pui32ClockSpeed = psDevInfo->ui32CoreClockSpeed; -+ *pui32HostTimeStamp = OSClockus(); -+ -+ return eError; -+} -+ -+ -+/****************************************************************************** -+ End of file (sgxinit.c) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/sgxkick.c b/drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/sgxkick.c -new file mode 100644 -index 0000000..33d7d73 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/sgxkick.c -@@ -0,0 +1,839 @@ -+/*************************************************************************/ /*! -+@Title Device specific kickTA routines -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#include <stddef.h> /* For the macro offsetof() */ -+#include "services_headers.h" -+#include "sgxinfo.h" -+#include "sgxinfokm.h" -+#if defined (PDUMP) -+#include "sgxapi_km.h" -+#include "pdump_km.h" -+#endif -+#include "sgx_bridge_km.h" -+#include "osfunc.h" -+#include "pvr_debug.h" -+#include "sgxutils.h" -+#include "ttrace.h" -+ -+#if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) -+#include "pvr_sync.h" -+#endif -+ -+/*! -+****************************************************************************** -+ -+ @Function SGXDoKickKM -+ -+ @Description -+ -+ Really kicks the TA -+ -+ @Input hDevHandle - Device handle -+ -+ @Return ui32Error - success or failure -+ -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR SGXDoKickKM(IMG_HANDLE hDevHandle, SGX_CCB_KICK *psCCBKick) -+{ -+ PVRSRV_ERROR eError; -+ PVRSRV_KERNEL_SYNC_INFO *psSyncInfo; -+ PVRSRV_KERNEL_MEM_INFO *psCCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *) psCCBKick->hCCBKernelMemInfo; -+ SGXMKIF_CMDTA_SHARED *psTACmd; -+ IMG_UINT32 i; -+ IMG_HANDLE hDevMemContext = IMG_NULL; -+#if defined(FIX_HW_BRN_31620) -+ hDevMemContext = psCCBKick->hDevMemContext; -+#endif -+ PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_FUNCTION_ENTER, KICK_TOKEN_DOKICK); -+ -+ if (!CCB_OFFSET_IS_VALID(SGXMKIF_CMDTA_SHARED, psCCBMemInfo, psCCBKick, ui32CCBOffset)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SGXDoKickKM: Invalid CCB offset")); -+ PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_FUNCTION_EXIT, KICK_TOKEN_DOKICK); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ /* override QAC warning about stricter alignment */ -+ /* PRQA S 3305 1 */ -+ psTACmd = CCB_DATA_FROM_OFFSET(SGXMKIF_CMDTA_SHARED, psCCBMemInfo, psCCBKick, ui32CCBOffset); -+ -+ PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_CMD_START, KICK_TOKEN_DOKICK); -+ -+#if defined(TTRACE) -+ if (psCCBKick->bFirstKickOrResume) -+ { -+ PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK, -+ PVRSRV_TRACE_CLASS_FLAGS, -+ KICK_TOKEN_FIRST_KICK); -+ } -+ -+ if (psCCBKick->bLastInScene) -+ { -+ PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK, -+ PVRSRV_TRACE_CLASS_FLAGS, -+ KICK_TOKEN_LAST_KICK); -+ } -+#endif -+ PVR_TTRACE_UI32(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_CCB, -+ KICK_TOKEN_CCB_OFFSET, psCCBKick->ui32CCBOffset); -+ -+ /* TA/3D dependency */ -+ if (psCCBKick->hTA3DSyncInfo) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTA3DSyncInfo; -+ -+ PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_KICK, KICK_TOKEN_TA3D_SYNC, -+ psSyncInfo, PVRSRV_SYNCOP_SAMPLE); -+ -+ psTACmd->sTA3DDependency.sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; -+ -+ psTACmd->sTA3DDependency.ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; -+ -+ if (psCCBKick->bTADependency) -+ { -+ psSyncInfo->psSyncData->ui32WriteOpsPending++; -+ } -+ } -+ -+ if (psCCBKick->hTASyncInfo != IMG_NULL) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTASyncInfo; -+ -+ PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_KICK, KICK_TOKEN_TA_SYNC, -+ psSyncInfo, PVRSRV_SYNCOP_SAMPLE); -+ -+ psTACmd->sTATQSyncReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; -+ psTACmd->sTATQSyncWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; -+ -+ psTACmd->ui32TATQSyncReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++; -+ psTACmd->ui32TATQSyncWriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; -+ } -+ -+ if (psCCBKick->h3DSyncInfo != IMG_NULL) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->h3DSyncInfo; -+ -+ PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_KICK, KICK_TOKEN_3D_SYNC, -+ psSyncInfo, PVRSRV_SYNCOP_SAMPLE); -+ -+ psTACmd->s3DTQSyncReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; -+ psTACmd->s3DTQSyncWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; -+ -+ psTACmd->ui323DTQSyncReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++; -+ psTACmd->ui323DTQSyncWriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; -+ } -+ -+ psTACmd->ui32NumTAStatusVals = psCCBKick->ui32NumTAStatusVals; -+ if (psCCBKick->ui32NumTAStatusVals != 0) -+ { -+ /* Copy status vals over */ -+ for (i = 0; i < psCCBKick->ui32NumTAStatusVals; i++) -+ { -+#if defined(SUPPORT_SGX_NEW_STATUS_VALS) -+ psTACmd->sCtlTAStatusInfo[i] = psCCBKick->asTAStatusUpdate[i].sCtlStatus; -+#else -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ahTAStatusSyncInfo[i]; -+ psTACmd->sCtlTAStatusInfo[i].sStatusDevAddr = psSyncInfo->sReadOpsCompleteDevVAddr; -+ psTACmd->sCtlTAStatusInfo[i].ui32StatusValue = psSyncInfo->psSyncData->ui32ReadOpsPending; -+#endif -+ } -+ } -+ -+ psTACmd->ui32Num3DStatusVals = psCCBKick->ui32Num3DStatusVals; -+ if (psCCBKick->ui32Num3DStatusVals != 0) -+ { -+ /* Copy status vals over */ -+ for (i = 0; i < psCCBKick->ui32Num3DStatusVals; i++) -+ { -+#if defined(SUPPORT_SGX_NEW_STATUS_VALS) -+ psTACmd->sCtl3DStatusInfo[i] = psCCBKick->as3DStatusUpdate[i].sCtlStatus; -+#else -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ah3DStatusSyncInfo[i]; -+ psTACmd->sCtl3DStatusInfo[i].sStatusDevAddr = psSyncInfo->sReadOpsCompleteDevVAddr; -+ psTACmd->sCtl3DStatusInfo[i].ui32StatusValue = psSyncInfo->psSyncData->ui32ReadOpsPending; -+#endif -+ } -+ } -+ -+ -+#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS) -+ /* SRC and DST sync dependencies */ -+ psTACmd->ui32NumTASrcSyncs = psCCBKick->ui32NumTASrcSyncs; -+ for (i=0; i<psCCBKick->ui32NumTASrcSyncs; i++) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTASrcKernelSyncInfo[i]; -+ -+ psTACmd->asTASrcSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; -+ psTACmd->asTASrcSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; -+ -+ /* Get ui32ReadOpsPending snapshot and copy into the CCB - before incrementing. */ -+ psTACmd->asTASrcSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++; -+ /* Copy ui32WriteOpsPending snapshot into the CCB. */ -+ psTACmd->asTASrcSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; -+ } -+ -+ psTACmd->ui32NumTADstSyncs = psCCBKick->ui32NumTADstSyncs; -+ for (i=0; i<psCCBKick->ui32NumTADstSyncs; i++) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTADstKernelSyncInfo[i]; -+ -+ psTACmd->asTADstSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; -+ psTACmd->asTADstSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; -+ -+ /* Get ui32ReadOpsPending snapshot and copy into the CCB */ -+ psTACmd->asTADstSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; -+ /* Copy ui32WriteOpsPending snapshot into the CCB - before incrementing */ -+ psTACmd->asTADstSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++; -+ } -+ -+ psTACmd->ui32Num3DSrcSyncs = psCCBKick->ui32Num3DSrcSyncs; -+ for (i=0; i<psCCBKick->ui32Num3DSrcSyncs; i++) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ah3DSrcKernelSyncInfo[i]; -+ -+ psTACmd->as3DSrcSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; -+ psTACmd->as3DSrcSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; -+ -+ /* Get ui32ReadOpsPending snapshot and copy into the CCB - before incrementing. */ -+ psTACmd->as3DSrcSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++; -+ /* Copy ui32WriteOpsPending snapshot into the CCB. */ -+ psTACmd->as3DSrcSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; -+ } -+#else /* SUPPORT_SGX_GENERALISED_SYNCOBJECTS */ -+ /* texture dependencies */ -+#if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) -+ eError = PVRSyncPatchCCBKickSyncInfos(psCCBKick->ahSrcKernelSyncInfo, -+ psTACmd->asSrcSyncs, -+ &psCCBKick->ui32NumSrcSyncs); -+ if(eError != PVRSRV_OK) -+ { -+ /* We didn't kick yet, or perform PDUMP processing, so we should -+ * be able to trivially roll back any changes made to the sync -+ * data. If we don't do this, we'll wedge services cleanup. -+ */ -+ -+ if (psCCBKick->h3DSyncInfo != IMG_NULL) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->h3DSyncInfo; -+ psSyncInfo->psSyncData->ui32ReadOpsPending--; -+ } -+ -+ if (psCCBKick->hTASyncInfo != IMG_NULL) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTASyncInfo; -+ psSyncInfo->psSyncData->ui32ReadOpsPending--; -+ } -+ -+ if (psCCBKick->hTA3DSyncInfo && psCCBKick->bTADependency) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTA3DSyncInfo; -+ psSyncInfo->psSyncData->ui32WriteOpsPending--; -+ } -+ -+ PVR_DPF((PVR_DBG_ERROR, "SGXDoKickKM: PVRSyncPatchCCBKickSyncInfos failed.")); -+ PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_FUNCTION_EXIT, -+ KICK_TOKEN_DOKICK); -+ return eError; -+ } -+#else /* defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) */ -+ for (i=0; i<psCCBKick->ui32NumSrcSyncs; i++) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahSrcKernelSyncInfo[i]; -+ -+ PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_KICK, KICK_TOKEN_SRC_SYNC, -+ psSyncInfo, PVRSRV_SYNCOP_SAMPLE); -+ -+ psTACmd->asSrcSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; -+ psTACmd->asSrcSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; -+ -+ /* Get ui32ReadOpsPending snapshot and copy into the CCB - before incrementing. */ -+ psTACmd->asSrcSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++; -+ /* Copy ui32WriteOpsPending snapshot into the CCB. */ -+ psTACmd->asSrcSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; -+ } -+#endif /* defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) */ -+ psTACmd->ui32NumSrcSyncs = psCCBKick->ui32NumSrcSyncs; -+#endif /* defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS) */ -+ -+ if (psCCBKick->bFirstKickOrResume && psCCBKick->ui32NumDstSyncObjects > 0) -+ { -+ PVRSRV_KERNEL_MEM_INFO *psHWDstSyncListMemInfo = -+ (PVRSRV_KERNEL_MEM_INFO *)psCCBKick->hKernelHWSyncListMemInfo; -+ SGXMKIF_HWDEVICE_SYNC_LIST *psHWDeviceSyncList = psHWDstSyncListMemInfo->pvLinAddrKM; -+ IMG_UINT32 ui32NumDstSyncs = psCCBKick->ui32NumDstSyncObjects; -+ -+ PVR_ASSERT(((PVRSRV_KERNEL_MEM_INFO *)psCCBKick->hKernelHWSyncListMemInfo)->uAllocSize >= (sizeof(SGXMKIF_HWDEVICE_SYNC_LIST) + -+ (sizeof(PVRSRV_DEVICE_SYNC_OBJECT) * ui32NumDstSyncs))); -+ -+ psHWDeviceSyncList->ui32NumSyncObjects = ui32NumDstSyncs; -+#if defined(PDUMP) -+ if (PDumpIsCaptureFrameKM()) -+ { -+ PDUMPCOMMENT("HWDeviceSyncList for TACmd\r\n"); -+ PDUMPMEM(IMG_NULL, -+ psHWDstSyncListMemInfo, -+ 0, -+ sizeof(SGXMKIF_HWDEVICE_SYNC_LIST), -+ 0, -+ MAKEUNIQUETAG(psHWDstSyncListMemInfo)); -+ } -+#endif -+ -+ for (i=0; i<ui32NumDstSyncs; i++) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->pahDstSyncHandles[i]; -+ -+ if (psSyncInfo) -+ { -+ psSyncInfo->psSyncData->ui64LastWrite = ui64KickCount; -+ -+ PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_KICK, KICK_TOKEN_DST_SYNC, -+ psSyncInfo, PVRSRV_SYNCOP_SAMPLE); -+ -+ psHWDeviceSyncList->asSyncData[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; -+ psHWDeviceSyncList->asSyncData[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; -+ psHWDeviceSyncList->asSyncData[i].sReadOps2CompleteDevVAddr = psSyncInfo->sReadOps2CompleteDevVAddr; -+ -+ psHWDeviceSyncList->asSyncData[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; -+ psHWDeviceSyncList->asSyncData[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++; -+ psHWDeviceSyncList->asSyncData[i].ui32ReadOps2PendingVal = psSyncInfo->psSyncData->ui32ReadOps2Pending; -+ -+ #if defined(PDUMP) -+ if (PDumpIsCaptureFrameKM()) -+ { -+ IMG_UINT32 ui32ModifiedValue; -+ IMG_UINT32 ui32SyncOffset = offsetof(SGXMKIF_HWDEVICE_SYNC_LIST, asSyncData) -+ + (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)); -+ IMG_UINT32 ui32WOpsOffset = ui32SyncOffset -+ + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal); -+ IMG_UINT32 ui32ROpsOffset = ui32SyncOffset -+ + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal); -+ IMG_UINT32 ui32ROps2Offset = ui32SyncOffset -+ + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOps2PendingVal); -+ -+ PDUMPCOMMENT("HWDeviceSyncObject for RT: %i\r\n", i); -+ -+ PDUMPMEM(IMG_NULL, -+ psHWDstSyncListMemInfo, -+ ui32SyncOffset, -+ sizeof(PVRSRV_DEVICE_SYNC_OBJECT), -+ 0, -+ MAKEUNIQUETAG(psHWDstSyncListMemInfo)); -+ -+ psSyncInfo->psSyncData->ui32LastOpDumpVal++; -+ -+ ui32ModifiedValue = psSyncInfo->psSyncData->ui32LastOpDumpVal - 1; -+ -+ PDUMPCOMMENT("Modify RT %d WOpPendingVal in HWDevSyncList\r\n", i); -+ -+ PDUMPMEM(&ui32ModifiedValue, -+ psHWDstSyncListMemInfo, -+ ui32WOpsOffset, -+ sizeof(IMG_UINT32), -+ 0, -+ MAKEUNIQUETAG(psHWDstSyncListMemInfo)); -+ -+ ui32ModifiedValue = 0; -+ PDUMPCOMMENT("Modify RT %d ROpsPendingVal in HWDevSyncList\r\n", i); -+ -+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, -+ psHWDstSyncListMemInfo, -+ ui32ROpsOffset, -+ sizeof(IMG_UINT32), -+ 0, -+ MAKEUNIQUETAG(psHWDstSyncListMemInfo)); -+ -+ /* -+ * Force the ROps2Complete value to 0. -+ */ -+ PDUMPCOMMENT("Modify RT %d ROps2PendingVal in HWDevSyncList\r\n", i); -+ PDUMPMEM(&ui32ModifiedValue, -+ psHWDstSyncListMemInfo, -+ ui32ROps2Offset, -+ sizeof(IMG_UINT32), -+ 0, -+ MAKEUNIQUETAG(psHWDstSyncListMemInfo)); -+ } -+ #endif /* defined(PDUMP) */ -+ } -+ else -+ { -+ psHWDeviceSyncList->asSyncData[i].sWriteOpsCompleteDevVAddr.uiAddr = 0; -+ psHWDeviceSyncList->asSyncData[i].sReadOpsCompleteDevVAddr.uiAddr = 0; -+ psHWDeviceSyncList->asSyncData[i].sReadOps2CompleteDevVAddr.uiAddr = 0; -+ -+ psHWDeviceSyncList->asSyncData[i].ui32ReadOpsPendingVal = 0; -+ psHWDeviceSyncList->asSyncData[i].ui32ReadOps2PendingVal = 0; -+ psHWDeviceSyncList->asSyncData[i].ui32WriteOpsPendingVal = 0; -+ } -+ } -+ } -+ -+ /* -+ NOTE: THIS MUST BE THE LAST THING WRITTEN TO THE TA COMMAND! -+ Set the ready for so the uKernel will process the command. -+ */ -+ psTACmd->ui32CtrlFlags |= SGXMKIF_CMDTA_CTRLFLAGS_READY; -+ -+#if defined(PDUMP) -+ if (PDumpIsCaptureFrameKM()) -+ { -+ PDUMPCOMMENT("Shared part of TA command\r\n"); -+ -+ PDUMPMEM(psTACmd, -+ psCCBMemInfo, -+ psCCBKick->ui32CCBDumpWOff, -+ sizeof(SGXMKIF_CMDTA_SHARED), -+ 0, -+ MAKEUNIQUETAG(psCCBMemInfo)); -+ -+#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS) -+ for (i=0; i<psCCBKick->ui32NumTASrcSyncs; i++) -+ { -+ IMG_UINT32 ui32ModifiedValue; -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTASrcKernelSyncInfo[i]; -+ -+ psSyncInfo->psSyncData->ui32LastReadOpDumpVal++; -+ -+ ui32ModifiedValue = psSyncInfo->psSyncData->ui32LastReadOpDumpVal - 1; -+ -+ PDUMPCOMMENT("Modify TA SrcSync %d ROpsPendingVal\r\n", i); -+ -+ PDUMPMEM(&ui32ModifiedValue, -+ psCCBMemInfo, -+ psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asTASrcSyncs) + -+ (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal), -+ sizeof(IMG_UINT32), -+ 0, -+ MAKEUNIQUETAG(psCCBMemInfo)); -+ -+ PDUMPCOMMENT("Modify TA SrcSync %d WOpPendingVal\r\n", i); -+ -+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, -+ psCCBMemInfo, -+ psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asTASrcSyncs) + -+ (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal), -+ sizeof(IMG_UINT32), -+ 0, -+ MAKEUNIQUETAG(psCCBMemInfo)); -+ } -+ -+ for (i=0; i<psCCBKick->ui32NumTADstSyncs; i++) -+ { -+ IMG_UINT32 ui32ModifiedValue; -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTADstKernelSyncInfo[i]; -+ -+ psSyncInfo->psSyncData->ui32LastOpDumpVal++; -+ -+ ui32ModifiedValue = psSyncInfo->psSyncData->ui32LastOpDumpVal - 1; -+ -+ PDUMPCOMMENT("Modify TA DstSync %d WOpPendingVal\r\n", i); -+ -+ PDUMPMEM(&ui32ModifiedValue, -+ psCCBMemInfo, -+ psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asTADstSyncs) + -+ (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal), -+ sizeof(IMG_UINT32), -+ 0, -+ MAKEUNIQUETAG(psCCBMemInfo)); -+ -+ PDUMPCOMMENT("Modify TA DstSync %d ROpsPendingVal\r\n", i); -+ -+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, -+ psCCBMemInfo, -+ psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asTADstSyncs) + -+ (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal), -+ sizeof(IMG_UINT32), -+ 0, -+ MAKEUNIQUETAG(psCCBMemInfo)); -+ } -+ -+ for (i=0; i<psCCBKick->ui32Num3DSrcSyncs; i++) -+ { -+ IMG_UINT32 ui32ModifiedValue; -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ah3DSrcKernelSyncInfo[i]; -+ -+ psSyncInfo->psSyncData->ui32LastReadOpDumpVal++; -+ -+ ui32ModifiedValue = psSyncInfo->psSyncData->ui32LastReadOpDumpVal - 1; -+ -+ PDUMPCOMMENT("Modify 3D SrcSync %d ROpsPendingVal\r\n", i); -+ -+ PDUMPMEM(&ui32ModifiedValue, -+ psCCBMemInfo, -+ psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, as3DSrcSyncs) + -+ (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal), -+ sizeof(IMG_UINT32), -+ 0, -+ MAKEUNIQUETAG(psCCBMemInfo)); -+ -+ PDUMPCOMMENT("Modify 3D SrcSync %d WOpPendingVal\r\n", i); -+ -+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, -+ psCCBMemInfo, -+ psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, as3DSrcSyncs) + -+ (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal), -+ sizeof(IMG_UINT32), -+ 0, -+ MAKEUNIQUETAG(psCCBMemInfo)); -+ } -+#else/* SUPPORT_SGX_GENERALISED_SYNCOBJECTS */ -+ for (i=0; i<psCCBKick->ui32NumSrcSyncs; i++) -+ { -+ IMG_UINT32 ui32ModifiedValue; -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahSrcKernelSyncInfo[i]; -+ -+ psSyncInfo->psSyncData->ui32LastReadOpDumpVal++; -+ -+ ui32ModifiedValue = psSyncInfo->psSyncData->ui32LastReadOpDumpVal - 1; -+ -+ PDUMPCOMMENT("Modify SrcSync %d ROpsPendingVal\r\n", i); -+ -+ PDUMPMEM(&ui32ModifiedValue, -+ psCCBMemInfo, -+ psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asSrcSyncs) + -+ (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal), -+ sizeof(IMG_UINT32), -+ 0, -+ MAKEUNIQUETAG(psCCBMemInfo)); -+ -+ PDUMPCOMMENT("Modify SrcSync %d WOpPendingVal\r\n", i); -+ -+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, -+ psCCBMemInfo, -+ psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asSrcSyncs) + -+ (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal), -+ sizeof(IMG_UINT32), -+ 0, -+ MAKEUNIQUETAG(psCCBMemInfo)); -+ } -+ -+ if (psCCBKick->hTA3DSyncInfo != IMG_NULL) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTA3DSyncInfo; -+ -+ PDUMPCOMMENT("Modify TA/3D dependency WOpPendingVal\r\n"); -+ -+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, -+ psCCBMemInfo, -+ psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, sTA3DDependency.ui32WriteOpsPendingVal), -+ sizeof(IMG_UINT32), -+ 0, -+ MAKEUNIQUETAG(psCCBMemInfo)); -+ -+ if (psCCBKick->bTADependency) -+ { -+ psSyncInfo->psSyncData->ui32LastOpDumpVal++; -+ } -+ } -+ -+ if (psCCBKick->hTASyncInfo != IMG_NULL) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTASyncInfo; -+ -+ PDUMPCOMMENT("Modify TA/TQ ROpPendingVal\r\n"); -+ -+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, -+ psCCBMemInfo, -+ psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, ui32TATQSyncReadOpsPendingVal), -+ sizeof(IMG_UINT32), -+ 0, -+ MAKEUNIQUETAG(psCCBMemInfo)); -+ -+ PDUMPCOMMENT("Modify TA/TQ WOpPendingVal\r\n"); -+ -+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, -+ psCCBMemInfo, -+ psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, ui32TATQSyncWriteOpsPendingVal), -+ sizeof(IMG_UINT32), -+ 0, -+ MAKEUNIQUETAG(psCCBMemInfo)); -+ -+ psSyncInfo->psSyncData->ui32LastReadOpDumpVal++; -+ } -+ -+ if (psCCBKick->h3DSyncInfo != IMG_NULL) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->h3DSyncInfo; -+ -+ PDUMPCOMMENT("Modify 3D/TQ ROpPendingVal\r\n"); -+ -+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, -+ psCCBMemInfo, -+ psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, ui323DTQSyncReadOpsPendingVal), -+ sizeof(IMG_UINT32), -+ 0, -+ MAKEUNIQUETAG(psCCBMemInfo)); -+ -+ PDUMPCOMMENT("Modify 3D/TQ WOpPendingVal\r\n"); -+ -+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, -+ psCCBMemInfo, -+ psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, ui323DTQSyncWriteOpsPendingVal), -+ sizeof(IMG_UINT32), -+ 0, -+ MAKEUNIQUETAG(psCCBMemInfo)); -+ -+ psSyncInfo->psSyncData->ui32LastReadOpDumpVal++; -+ } -+ -+#endif/* SUPPORT_SGX_GENERALISED_SYNCOBJECTS */ -+ -+ for (i = 0; i < psCCBKick->ui32NumTAStatusVals; i++) -+ { -+#if !defined(SUPPORT_SGX_NEW_STATUS_VALS) -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ahTAStatusSyncInfo[i]; -+ PDUMPCOMMENT("Modify TA status value in TA cmd\r\n"); -+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, -+ psCCBMemInfo, -+ psCCBKick->ui32CCBDumpWOff + (IMG_UINT32)offsetof(SGXMKIF_CMDTA_SHARED, sCtlTAStatusInfo[i].ui32StatusValue), -+ sizeof(IMG_UINT32), -+ 0, -+ MAKEUNIQUETAG(psCCBMemInfo)); -+#endif -+ } -+ -+ for (i = 0; i < psCCBKick->ui32Num3DStatusVals; i++) -+ { -+#if !defined(SUPPORT_SGX_NEW_STATUS_VALS) -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ah3DStatusSyncInfo[i]; -+ PDUMPCOMMENT("Modify 3D status value in TA cmd\r\n"); -+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, -+ psCCBMemInfo, -+ psCCBKick->ui32CCBDumpWOff + (IMG_UINT32)offsetof(SGXMKIF_CMDTA_SHARED, sCtl3DStatusInfo[i].ui32StatusValue), -+ sizeof(IMG_UINT32), -+ 0, -+ MAKEUNIQUETAG(psCCBMemInfo)); -+#endif -+ } -+ } -+#endif /* defined(PDUMP) */ -+ -+ PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_CMD_END, -+ KICK_TOKEN_DOKICK); -+ -+ eError = SGXScheduleCCBCommandKM(hDevHandle, SGXMKIF_CMD_TA, &psCCBKick->sCommand, KERNEL_ID, 0, hDevMemContext, psCCBKick->bLastInScene); -+ if (eError == PVRSRV_ERROR_RETRY) -+ { -+ if (psCCBKick->bFirstKickOrResume && psCCBKick->ui32NumDstSyncObjects > 0) -+ { -+ for (i=0; i < psCCBKick->ui32NumDstSyncObjects; i++) -+ { -+ /* Client will retry, so undo the write ops pending increment done above. */ -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->pahDstSyncHandles[i]; -+ -+ if (psSyncInfo) -+ { -+ psSyncInfo->psSyncData->ui32WriteOpsPending--; -+#if defined(PDUMP) -+ if (PDumpIsCaptureFrameKM()) -+ { -+ psSyncInfo->psSyncData->ui32LastOpDumpVal--; -+ } -+#endif -+ } -+ } -+ } -+ -+#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS) -+ for (i=0; i<psCCBKick->ui32NumTASrcSyncs; i++) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTASrcKernelSyncInfo[i]; -+ psSyncInfo->psSyncData->ui32ReadOpsPending--; -+ } -+ for (i=0; i<psCCBKick->ui32NumTADstSyncs; i++) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTADstKernelSyncInfo[i]; -+ psSyncInfo->psSyncData->ui32WriteOpsPending--; -+ } -+ for (i=0; i<psCCBKick->ui32Num3DSrcSyncs; i++) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ah3DSrcKernelSyncInfo[i]; -+ psSyncInfo->psSyncData->ui32ReadOpsPending--; -+ } -+#else/* SUPPORT_SGX_GENERALISED_SYNCOBJECTS */ -+ for (i=0; i<psCCBKick->ui32NumSrcSyncs; i++) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahSrcKernelSyncInfo[i]; -+ psSyncInfo->psSyncData->ui32ReadOpsPending--; -+ } -+#endif/* SUPPORT_SGX_GENERALISED_SYNCOBJECTS */ -+ -+ if (psCCBKick->hTA3DSyncInfo) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTA3DSyncInfo; -+ psSyncInfo->psSyncData->ui32ReadOpsPending--; -+ } -+ -+ if (psCCBKick->hTASyncInfo) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTASyncInfo; -+ psSyncInfo->psSyncData->ui32ReadOpsPending--; -+ } -+ -+ if (psCCBKick->h3DSyncInfo) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->h3DSyncInfo; -+ psSyncInfo->psSyncData->ui32ReadOpsPending--; -+ } -+ -+ PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_FUNCTION_EXIT, -+ KICK_TOKEN_DOKICK); -+ return eError; -+ } -+ else if (PVRSRV_OK != eError) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SGXDoKickKM: SGXScheduleCCBCommandKM failed.")); -+ PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_FUNCTION_EXIT, -+ KICK_TOKEN_DOKICK); -+ return eError; -+ } -+ -+ -+#if defined(NO_HARDWARE) -+ -+ -+ /* TA/3D dependency */ -+ if (psCCBKick->hTA3DSyncInfo) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTA3DSyncInfo; -+ -+ if (psCCBKick->bTADependency) -+ { -+ psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; -+ } -+ } -+ -+ if (psCCBKick->hTASyncInfo != IMG_NULL) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTASyncInfo; -+ -+ psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending; -+ } -+ -+ if (psCCBKick->h3DSyncInfo != IMG_NULL) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->h3DSyncInfo; -+ -+ psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending; -+ } -+ -+ /* Copy status vals over */ -+ for (i = 0; i < psCCBKick->ui32NumTAStatusVals; i++) -+ { -+#if defined(SUPPORT_SGX_NEW_STATUS_VALS) -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = (PVRSRV_KERNEL_MEM_INFO*)psCCBKick->asTAStatusUpdate[i].hKernelMemInfo; -+ /* derive offset into meminfo and write the status value */ -+ *(IMG_UINT32*)((IMG_UINTPTR_T)psKernelMemInfo->pvLinAddrKM -+ + (psTACmd->sCtlTAStatusInfo[i].sStatusDevAddr.uiAddr -+ - psKernelMemInfo->sDevVAddr.uiAddr)) = psTACmd->sCtlTAStatusInfo[i].ui32StatusValue; -+#else -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ahTAStatusSyncInfo[i]; -+ psSyncInfo->psSyncData->ui32ReadOpsComplete = psTACmd->sCtlTAStatusInfo[i].ui32StatusValue; -+#endif -+ } -+ -+#if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS) -+ /* SRC and DST dependencies */ -+ for (i=0; i<psCCBKick->ui32NumTASrcSyncs; i++) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTASrcKernelSyncInfo[i]; -+ psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending; -+ } -+ for (i=0; i<psCCBKick->ui32NumTADstSyncs; i++) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTADstKernelSyncInfo[i]; -+ psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; -+ } -+ for (i=0; i<psCCBKick->ui32Num3DSrcSyncs; i++) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ah3DSrcKernelSyncInfo[i]; -+ psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending; -+ } -+#else/* SUPPORT_SGX_GENERALISED_SYNCOBJECTS */ -+ /* texture dependencies */ -+ for (i=0; i<psCCBKick->ui32NumSrcSyncs; i++) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahSrcKernelSyncInfo[i]; -+ psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending; -+ } -+#endif/* SUPPORT_SGX_GENERALISED_SYNCOBJECTS */ -+ -+ if (psCCBKick->bTerminateOrAbort) -+ { -+ if (psCCBKick->ui32NumDstSyncObjects > 0) -+ { -+ PVRSRV_KERNEL_MEM_INFO *psHWDstSyncListMemInfo = -+ (PVRSRV_KERNEL_MEM_INFO *)psCCBKick->hKernelHWSyncListMemInfo; -+ SGXMKIF_HWDEVICE_SYNC_LIST *psHWDeviceSyncList = psHWDstSyncListMemInfo->pvLinAddrKM; -+ -+ for (i=0; i<psCCBKick->ui32NumDstSyncObjects; i++) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->pahDstSyncHandles[i]; -+ if (psSyncInfo) -+ psSyncInfo->psSyncData->ui32WriteOpsComplete = psHWDeviceSyncList->asSyncData[i].ui32WriteOpsPendingVal+1; -+ } -+ } -+ -+ /* Copy status vals over */ -+ for (i = 0; i < psCCBKick->ui32Num3DStatusVals; i++) -+ { -+#if defined(SUPPORT_SGX_NEW_STATUS_VALS) -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = (PVRSRV_KERNEL_MEM_INFO*)psCCBKick->as3DStatusUpdate[i].hKernelMemInfo; -+ /* derive offset into meminfo and write the status value */ -+ *(IMG_UINT32*)((IMG_UINTPTR_T)psKernelMemInfo->pvLinAddrKM -+ + (psTACmd->sCtl3DStatusInfo[i].sStatusDevAddr.uiAddr -+ - psKernelMemInfo->sDevVAddr.uiAddr)) = psTACmd->sCtl3DStatusInfo[i].ui32StatusValue; -+#else -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ah3DStatusSyncInfo[i]; -+ psSyncInfo->psSyncData->ui32ReadOpsComplete = psTACmd->sCtl3DStatusInfo[i].ui32StatusValue; -+#endif -+ } -+ } -+#endif -+ PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_FUNCTION_EXIT, -+ KICK_TOKEN_DOKICK); -+ return eError; -+} -+ -+/****************************************************************************** -+ End of file (sgxkick.c) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/sgxpower.c b/drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/sgxpower.c -new file mode 100644 -index 0000000..196e6ea ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/sgxpower.c -@@ -0,0 +1,650 @@ -+/*************************************************************************/ /*! -+@Title Device specific power routines -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#include <stddef.h> -+ -+#include "sgxdefs.h" -+#include "services_headers.h" -+#include "sgxapi_km.h" -+#include "sgx_mkif_km.h" -+#include "sgxutils.h" -+#include "pdump_km.h" -+ -+extern IMG_UINT32 g_ui32HostIRQCountSample; -+ -+#if defined(SUPPORT_HW_RECOVERY) -+static PVRSRV_ERROR SGXAddTimer(PVRSRV_DEVICE_NODE *psDeviceNode, -+ SGX_TIMING_INFORMATION *psSGXTimingInfo, -+ IMG_HANDLE *phTimer) -+{ -+ /* -+ Install timer callback for HW recovery at 50 times lower -+ frequency than the microkernel timer. -+ */ -+ *phTimer = OSAddTimer(SGXOSTimer, psDeviceNode, -+ 1000 * 50 / psSGXTimingInfo->ui32uKernelFreq); -+ if(*phTimer == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SGXAddTimer : Failed to register timer callback function")); -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ -+ return PVRSRV_OK; -+} -+#endif /* SUPPORT_HW_RECOVERY*/ -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SGXUpdateTimingInfo -+ -+ @Description -+ -+ Derives the microkernel timing info from the system-supplied values -+ -+ @Input psDeviceNode : SGX Device node -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+static PVRSRV_ERROR SGXUpdateTimingInfo(PVRSRV_DEVICE_NODE *psDeviceNode) -+{ -+ PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; -+#if defined(SGX_DYNAMIC_TIMING_INFO) -+ SGX_TIMING_INFORMATION sSGXTimingInfo = {0}; -+#else -+ SGX_DEVICE_MAP *psSGXDeviceMap; -+#endif -+ IMG_UINT32 ui32ActivePowManSampleRate; -+ SGX_TIMING_INFORMATION *psSGXTimingInfo; -+ -+ -+#if defined(SGX_DYNAMIC_TIMING_INFO) -+ psSGXTimingInfo = &sSGXTimingInfo; -+ SysGetSGXTimingInformation(psSGXTimingInfo); -+#else -+ SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE_SGX, -+ (IMG_VOID**)&psSGXDeviceMap); -+ psSGXTimingInfo = &psSGXDeviceMap->sTimingInfo; -+#endif -+ -+#if defined(SUPPORT_HW_RECOVERY) -+ { -+ PVRSRV_ERROR eError; -+ IMG_UINT32 ui32OlduKernelFreq; -+ -+ if (psDevInfo->hTimer != IMG_NULL) -+ { -+ ui32OlduKernelFreq = psDevInfo->ui32CoreClockSpeed / psDevInfo->ui32uKernelTimerClock; -+ if (ui32OlduKernelFreq != psSGXTimingInfo->ui32uKernelFreq) -+ { -+ /* -+ The ukernel timer frequency has changed. -+ */ -+ IMG_HANDLE hNewTimer; -+ -+ eError = SGXAddTimer(psDeviceNode, psSGXTimingInfo, &hNewTimer); -+ if (eError == PVRSRV_OK) -+ { -+ eError = OSRemoveTimer(psDevInfo->hTimer); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SGXUpdateTimingInfo: Failed to remove timer")); -+ } -+ psDevInfo->hTimer = hNewTimer; -+ } -+ else -+ { -+ /* Failed to allocate the new timer, leave the old one. */ -+ } -+ } -+ } -+ else -+ { -+ eError = SGXAddTimer(psDeviceNode, psSGXTimingInfo, &psDevInfo->hTimer); -+ if (eError != PVRSRV_OK) -+ { -+ return eError; -+ } -+ } -+ -+ psDevInfo->psSGXHostCtl->ui32HWRecoverySampleRate = -+ psSGXTimingInfo->ui32uKernelFreq / psSGXTimingInfo->ui32HWRecoveryFreq; -+ } -+#endif /* SUPPORT_HW_RECOVERY*/ -+ -+ /* Copy the SGX clock speed for use in the kernel */ -+ psDevInfo->ui32CoreClockSpeed = psSGXTimingInfo->ui32CoreClockSpeed; -+ psDevInfo->ui32uKernelTimerClock = psSGXTimingInfo->ui32CoreClockSpeed / psSGXTimingInfo->ui32uKernelFreq; -+ -+ /* FIXME: no need to duplicate - remove it from psDevInfo */ -+ psDevInfo->psSGXHostCtl->ui32uKernelTimerClock = psDevInfo->ui32uKernelTimerClock; -+#if defined(PDUMP) -+ PDUMPCOMMENT("Host Control - Microkernel clock"); -+ PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo, -+ offsetof(SGXMKIF_HOST_CTL, ui32uKernelTimerClock), -+ sizeof(IMG_UINT32), PDUMP_FLAGS_CONTINUOUS, -+ MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo)); -+#endif /* PDUMP */ -+ -+ if (psSGXTimingInfo->bEnableActivePM) -+ { -+ ui32ActivePowManSampleRate = -+ psSGXTimingInfo->ui32uKernelFreq * psSGXTimingInfo->ui32ActivePowManLatencyms / 1000; -+ /* -+ ui32ActivePowerCounter has the value 0 when SGX is not idle. -+ When SGX becomes idle, the value of ui32ActivePowerCounter is changed from 0 to ui32ActivePowManSampleRate. -+ The ukernel timer routine decrements the value of ui32ActivePowerCounter if it is not 0. -+ When the ukernel timer decrements ui32ActivePowerCounter from 1 to 0, the ukernel timer will -+ request power down. -+ Therefore the minimum value of ui32ActivePowManSampleRate is 1. -+ */ -+ ui32ActivePowManSampleRate += 1; -+ } -+ else -+ { -+ ui32ActivePowManSampleRate = 0; -+ } -+ -+ psDevInfo->psSGXHostCtl->ui32ActivePowManSampleRate = ui32ActivePowManSampleRate; -+#if defined(PDUMP) -+ PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo, -+ offsetof(SGXMKIF_HOST_CTL, ui32ActivePowManSampleRate), -+ sizeof(IMG_UINT32), PDUMP_FLAGS_CONTINUOUS, -+ MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo)); -+#endif /* PDUMP */ -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SGXStartTimer -+ -+ @Description -+ -+ Start the microkernel timer -+ -+ @Input psDevInfo : SGX Device Info -+ -+ @Return IMG_VOID : -+ -+******************************************************************************/ -+static IMG_VOID SGXStartTimer(PVRSRV_SGXDEV_INFO *psDevInfo) -+{ -+ #if defined(SUPPORT_HW_RECOVERY) -+ PVRSRV_ERROR eError; -+ -+ eError = OSEnableTimer(psDevInfo->hTimer); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SGXStartTimer : Failed to enable host timer")); -+ } -+ #else -+ PVR_UNREFERENCED_PARAMETER(psDevInfo); -+ #endif /* SUPPORT_HW_RECOVERY */ -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SGXPollForClockGating -+ -+ @Description -+ -+ Wait until the SGX core clocks have gated. -+ -+ @Input psDevInfo : SGX Device Info -+ @Input ui32Register : Offset of register to poll -+ @Input ui32Register : Value of register to poll for -+ @Input pszComment : Description of poll -+ -+ @Return IMG_VOID : -+ -+******************************************************************************/ -+static IMG_VOID SGXPollForClockGating (PVRSRV_SGXDEV_INFO *psDevInfo, -+ IMG_UINT32 ui32Register, -+ IMG_UINT32 ui32RegisterValue, -+ IMG_CHAR *pszComment) -+{ -+ PVR_UNREFERENCED_PARAMETER(psDevInfo); -+ PVR_UNREFERENCED_PARAMETER(ui32Register); -+ PVR_UNREFERENCED_PARAMETER(ui32RegisterValue); -+ PVR_UNREFERENCED_PARAMETER(pszComment); -+ -+ #if !defined(NO_HARDWARE) -+ PVR_ASSERT(psDevInfo != IMG_NULL); -+ -+ /* PRQA S 0505 1 */ /* QAC does not like assert() */ -+ if (PollForValueKM((IMG_UINT32 *)psDevInfo->pvRegsBaseKM + (ui32Register >> 2), -+ 0, -+ ui32RegisterValue, -+ MAX_HW_TIME_US, -+ MAX_HW_TIME_US/WAIT_TRY_COUNT, -+ IMG_FALSE) != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SGXPollForClockGating: %s failed.", pszComment)); -+ SGXDumpDebugInfo(psDevInfo, IMG_FALSE); -+ PVR_DBG_BREAK; -+ } -+ #endif /* NO_HARDWARE */ -+ -+ PDUMPCOMMENT("%s", pszComment); -+ PDUMPREGPOL(SGX_PDUMPREG_NAME, ui32Register, 0, ui32RegisterValue, PDUMP_POLL_OPERATOR_EQUAL); -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SGXPrePowerState -+ -+ @Description -+ -+ does necessary preparation before power state transition -+ -+ @Input hDevHandle : SGX Device Node -+ @Input eNewPowerState : New power state -+ @Input eCurrentPowerState : Current power state -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+PVRSRV_ERROR SGXPrePowerState (IMG_HANDLE hDevHandle, -+ PVRSRV_DEV_POWER_STATE eNewPowerState, -+ PVRSRV_DEV_POWER_STATE eCurrentPowerState) -+{ -+ if ((eNewPowerState != eCurrentPowerState) && -+ (eNewPowerState != PVRSRV_DEV_POWER_STATE_ON)) -+ { -+ PVRSRV_ERROR eError; -+ PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle; -+ PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; -+ IMG_UINT32 ui32PowerCmd, ui32CompleteStatus; -+ SGXMKIF_COMMAND sCommand = {0}; -+ IMG_UINT32 ui32Core; -+ IMG_UINT32 ui32CoresEnabled; -+ -+ #if defined(SUPPORT_HW_RECOVERY) -+ /* Disable timer callback for HW recovery */ -+ eError = OSDisableTimer(psDevInfo->hTimer); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SGXPrePowerState: Failed to disable timer")); -+ return eError; -+ } -+ #endif /* SUPPORT_HW_RECOVERY */ -+ -+ if (eNewPowerState == PVRSRV_DEV_POWER_STATE_OFF) -+ { -+ /* Request the ukernel to idle SGX and save its state. */ -+ ui32PowerCmd = PVRSRV_POWERCMD_POWEROFF; -+ ui32CompleteStatus = PVRSRV_USSE_EDM_POWMAN_POWEROFF_COMPLETE; -+ PDUMPCOMMENT("SGX power off request"); -+ } -+ else -+ { -+ /* Request the ukernel to idle SGX. */ -+ ui32PowerCmd = PVRSRV_POWERCMD_IDLE; -+ ui32CompleteStatus = PVRSRV_USSE_EDM_POWMAN_IDLE_COMPLETE; -+ PDUMPCOMMENT("SGX idle request"); -+ } -+ -+ sCommand.ui32Data[1] = ui32PowerCmd; -+ -+ eError = SGXScheduleCCBCommand(psDeviceNode, SGXMKIF_CMD_POWER, &sCommand, KERNEL_ID, 0, IMG_NULL, IMG_FALSE); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SGXPrePowerState: Failed to submit power down command")); -+ return eError; -+ } -+ -+ /* Wait for the ukernel to complete processing. */ -+ #if !defined(NO_HARDWARE) -+ if (PollForValueKM(&psDevInfo->psSGXHostCtl->ui32PowerStatus, -+ ui32CompleteStatus, -+ ui32CompleteStatus, -+ MAX_HW_TIME_US, -+ MAX_HW_TIME_US/WAIT_TRY_COUNT, -+ IMG_FALSE) != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SGXPrePowerState: Wait for SGX ukernel power transition failed.")); -+ SGXDumpDebugInfo(psDevInfo, IMG_FALSE); -+ PVR_DBG_BREAK; -+ } -+ #endif /* NO_HARDWARE */ -+ -+ #if defined(PDUMP) -+ PDUMPCOMMENT("TA/3D CCB Control - Wait for power event on uKernel."); -+ PDUMPMEMPOL(psDevInfo->psKernelSGXHostCtlMemInfo, -+ offsetof(SGXMKIF_HOST_CTL, ui32PowerStatus), -+ ui32CompleteStatus, -+ ui32CompleteStatus, -+ PDUMP_POLL_OPERATOR_EQUAL, -+ 0, -+ MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo)); -+ #endif /* PDUMP */ -+ -+ /* Wait for the pending ukernel to host interrupts to come back. */ -+ #if !defined(NO_HARDWARE) -+ if (PollForValueKM(&g_ui32HostIRQCountSample, -+ psDevInfo->psSGXHostCtl->ui32InterruptCount, -+ 0xffffffff, -+ MAX_HW_TIME_US, -+ MAX_HW_TIME_US/WAIT_TRY_COUNT, -+ IMG_FALSE) != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SGXPrePowerState: Wait for pending interrupts failed.")); -+ SGXDumpDebugInfo(psDevInfo, IMG_FALSE); -+ PVR_DBG_BREAK; -+ } -+ #endif /* NO_HARDWARE */ -+#if defined(SGX_FEATURE_MP) -+ ui32CoresEnabled = ((OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_CORE) & EUR_CR_MASTER_CORE_ENABLE_MASK) >> EUR_CR_MASTER_CORE_ENABLE_SHIFT) + 1; -+#else -+ ui32CoresEnabled = 1; -+#endif -+ -+ for (ui32Core = 0; ui32Core < ui32CoresEnabled; ui32Core++) -+ { -+ /* Wait for SGX clock gating. */ -+ SGXPollForClockGating(psDevInfo, -+ SGX_MP_CORE_SELECT(psDevInfo->ui32ClkGateStatusReg, ui32Core), -+ psDevInfo->ui32ClkGateStatusMask, -+ "Wait for SGX clock gating"); -+ } -+ -+ #if defined(SGX_FEATURE_MP) -+ /* Wait for SGX master clock gating. */ -+ SGXPollForClockGating(psDevInfo, -+ psDevInfo->ui32MasterClkGateStatusReg, -+ psDevInfo->ui32MasterClkGateStatusMask, -+ "Wait for SGX master clock gating"); -+ -+ SGXPollForClockGating(psDevInfo, -+ psDevInfo->ui32MasterClkGateStatus2Reg, -+ psDevInfo->ui32MasterClkGateStatus2Mask, -+ "Wait for SGX master clock gating (2)"); -+ #endif /* SGX_FEATURE_MP */ -+ -+ if (eNewPowerState == PVRSRV_DEV_POWER_STATE_OFF) -+ { -+ /* Finally, de-initialise some registers. */ -+ eError = SGXDeinitialise(psDevInfo); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SGXPrePowerState: SGXDeinitialise failed: %u", eError)); -+ return eError; -+ } -+ } -+ } -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SGXPostPowerState -+ -+ @Description -+ -+ does necessary preparation after power state transition -+ -+ @Input hDevHandle : SGX Device Node -+ @Input eNewPowerState : New power state -+ @Input eCurrentPowerState : Current power state -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+PVRSRV_ERROR SGXPostPowerState (IMG_HANDLE hDevHandle, -+ PVRSRV_DEV_POWER_STATE eNewPowerState, -+ PVRSRV_DEV_POWER_STATE eCurrentPowerState) -+{ -+ if ((eNewPowerState != eCurrentPowerState) && -+ (eCurrentPowerState != PVRSRV_DEV_POWER_STATE_ON)) -+ { -+ PVRSRV_ERROR eError; -+ PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle; -+ PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; -+ SGXMKIF_HOST_CTL *psSGXHostCtl = psDevInfo->psSGXHostCtl; -+ -+ /* Reset the power manager flags. */ -+ psSGXHostCtl->ui32PowerStatus = 0; -+ #if defined(PDUMP) -+ PDUMPCOMMENT("Host Control - Reset power status"); -+ PDUMPMEM(IMG_NULL, psDevInfo->psKernelSGXHostCtlMemInfo, -+ offsetof(SGXMKIF_HOST_CTL, ui32PowerStatus), -+ sizeof(IMG_UINT32), PDUMP_FLAGS_CONTINUOUS, -+ MAKEUNIQUETAG(psDevInfo->psKernelSGXHostCtlMemInfo)); -+ #endif /* PDUMP */ -+ -+ if (eCurrentPowerState == PVRSRV_DEV_POWER_STATE_OFF) -+ { -+ /* -+ Coming up from off, re-initialise SGX. -+ */ -+ -+ /* -+ Re-generate the timing data required by SGX. -+ */ -+ eError = SGXUpdateTimingInfo(psDeviceNode); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SGXPostPowerState: SGXUpdateTimingInfo failed")); -+ return eError; -+ } -+ -+ /* -+ Run the SGX init script. -+ */ -+ eError = SGXInitialise(psDevInfo, IMG_FALSE); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SGXPostPowerState: SGXInitialise failed")); -+ return eError; -+ } -+ } -+ else -+ { -+ /* -+ Coming up from idle, restart the ukernel. -+ */ -+ SGXMKIF_COMMAND sCommand = {0}; -+ -+ sCommand.ui32Data[1] = PVRSRV_POWERCMD_RESUME; -+ eError = SGXScheduleCCBCommand(psDeviceNode, SGXMKIF_CMD_POWER, &sCommand, ISR_ID, 0, IMG_NULL, IMG_FALSE); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SGXPostPowerState failed to schedule CCB command: %u", eError)); -+ return eError; -+ } -+ } -+ -+ SGXStartTimer(psDevInfo); -+ } -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SGXPreClockSpeedChange -+ -+ @Description -+ -+ Does processing required before an SGX clock speed change. -+ -+ @Input hDevHandle : SGX Device Node -+ @Input bIdleDevice : Whether the microkernel needs to be idled -+ @Input eCurrentPowerState : Power state of the device -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+PVRSRV_ERROR SGXPreClockSpeedChange (IMG_HANDLE hDevHandle, -+ IMG_BOOL bIdleDevice, -+ PVRSRV_DEV_POWER_STATE eCurrentPowerState) -+{ -+ PVRSRV_ERROR eError; -+ PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle; -+ PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; -+ -+ PVR_UNREFERENCED_PARAMETER(psDevInfo); -+ -+ if (eCurrentPowerState == PVRSRV_DEV_POWER_STATE_ON) -+ { -+ if (bIdleDevice) -+ { -+ /* -+ * Idle SGX. -+ */ -+ PDUMPSUSPEND(); -+ -+ eError = SGXPrePowerState(hDevHandle, PVRSRV_DEV_POWER_STATE_IDLE, -+ PVRSRV_DEV_POWER_STATE_ON); -+ -+ if (eError != PVRSRV_OK) -+ { -+ PDUMPRESUME(); -+ return eError; -+ } -+ } -+ else -+ { -+ #if defined(SUPPORT_HW_RECOVERY) -+ PVRSRV_ERROR eError; -+ -+ eError = OSDisableTimer(psDevInfo->hTimer); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SGXStartTimer : Failed to enable host timer")); -+ } -+ #endif /* SUPPORT_HW_RECOVERY */ -+ } -+ } -+ -+ PVR_DPF((PVR_DBG_MESSAGE,"SGXPreClockSpeedChange: SGX clock speed was %uHz", -+ psDevInfo->ui32CoreClockSpeed)); -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SGXPostClockSpeedChange -+ -+ @Description -+ -+ Does processing required after an SGX clock speed change. -+ -+ @Input hDevHandle : SGX Device Node -+ @Input bIdleDevice : Whether the microkernel had been idled previously -+ @Input eCurrentPowerState : Power state of the device -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+PVRSRV_ERROR SGXPostClockSpeedChange (IMG_HANDLE hDevHandle, -+ IMG_BOOL bIdleDevice, -+ PVRSRV_DEV_POWER_STATE eCurrentPowerState) -+{ -+ PVRSRV_DEVICE_NODE *psDeviceNode = hDevHandle; -+ PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; -+ IMG_UINT32 ui32OldClockSpeed = psDevInfo->ui32CoreClockSpeed; -+ -+ PVR_UNREFERENCED_PARAMETER(ui32OldClockSpeed); -+ -+ if (eCurrentPowerState == PVRSRV_DEV_POWER_STATE_ON) -+ { -+ PVRSRV_ERROR eError; -+ -+ /* -+ Re-generate the timing data required by SGX. -+ */ -+ eError = SGXUpdateTimingInfo(psDeviceNode); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SGXPostPowerState: SGXUpdateTimingInfo failed")); -+ return eError; -+ } -+ -+ if (bIdleDevice) -+ { -+ /* -+ * Resume SGX. -+ */ -+ eError = SGXPostPowerState(hDevHandle, PVRSRV_DEV_POWER_STATE_ON, -+ PVRSRV_DEV_POWER_STATE_IDLE); -+ -+ PDUMPRESUME(); -+ -+ if (eError != PVRSRV_OK) -+ { -+ return eError; -+ } -+ } -+ else -+ { -+ SGXStartTimer(psDevInfo); -+ } -+ } -+ -+ PVR_DPF((PVR_DBG_MESSAGE,"SGXPostClockSpeedChange: SGX clock speed changed from %uHz to %uHz", -+ ui32OldClockSpeed, psDevInfo->ui32CoreClockSpeed)); -+ -+ return PVRSRV_OK; -+} -+ -+ -+/****************************************************************************** -+ End of file (sgxpower.c) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/sgxreset.c b/drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/sgxreset.c -new file mode 100644 -index 0000000..fa975e5 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/sgxreset.c -@@ -0,0 +1,818 @@ -+/*************************************************************************/ /*! -+@Title Device specific reset routines -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#include "sgxdefs.h" -+#include "sgxmmu.h" -+#include "services_headers.h" -+#include "sgxinfokm.h" -+#include "sgxconfig.h" -+#include "sgxutils.h" -+ -+#include "pdump_km.h" -+ -+ -+/*! -+******************************************************************************* -+ -+ @Function SGXInitClocks -+ -+ @Description -+ Initialise the SGX clocks -+ -+ @Input psDevInfo - device info. structure -+ @Input ui32PDUMPFlags - flags to control PDUMP output -+ -+ @Return IMG_VOID -+ -+******************************************************************************/ -+IMG_VOID SGXInitClocks(PVRSRV_SGXDEV_INFO *psDevInfo, -+ IMG_UINT32 ui32PDUMPFlags) -+{ -+ IMG_UINT32 ui32RegVal; -+ -+#if !defined(PDUMP) -+ PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags); -+#endif /* PDUMP */ -+ -+ ui32RegVal = psDevInfo->ui32ClkGateCtl; -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_CLKGATECTL, ui32RegVal); -+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_CLKGATECTL, ui32RegVal, ui32PDUMPFlags); -+ -+#if defined(EUR_CR_CLKGATECTL2) -+ ui32RegVal = psDevInfo->ui32ClkGateCtl2; -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_CLKGATECTL2, ui32RegVal); -+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_CLKGATECTL2, ui32RegVal, ui32PDUMPFlags); -+#endif -+} -+ -+ -+/*! -+******************************************************************************* -+ -+ @Function SGXResetInitBIFContexts -+ -+ @Description -+ Initialise the BIF memory contexts -+ -+ @Input psDevInfo - SGX Device Info -+ -+ @Return IMG_VOID -+ -+******************************************************************************/ -+static IMG_VOID SGXResetInitBIFContexts(PVRSRV_SGXDEV_INFO *psDevInfo, -+ IMG_UINT32 ui32PDUMPFlags) -+{ -+ IMG_UINT32 ui32RegVal; -+ -+#if !defined(PDUMP) -+ PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags); -+#endif /* PDUMP */ -+ -+ ui32RegVal = 0; -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal); -+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags); -+ -+#if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) -+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Initialise the BIF bank settings\r\n"); -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_BANK_SET, ui32RegVal); -+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_BANK_SET, ui32RegVal, ui32PDUMPFlags); -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_BANK0, ui32RegVal); -+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_BANK0, ui32RegVal, ui32PDUMPFlags); -+#endif /* SGX_FEATURE_MULTIPLE_MEM_CONTEXTS */ -+ -+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Initialise the BIF directory list\r\n"); -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_DIR_LIST_BASE0, ui32RegVal); -+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_DIR_LIST_BASE0, ui32RegVal, ui32PDUMPFlags); -+ -+#if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) -+ { -+ IMG_UINT32 ui32DirList, ui32DirListReg; -+ -+ for (ui32DirList = 1; -+ ui32DirList < SGX_FEATURE_BIF_NUM_DIRLISTS; -+ ui32DirList++) -+ { -+ ui32DirListReg = EUR_CR_BIF_DIR_LIST_BASE1 + 4 * (ui32DirList - 1); -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32DirListReg, ui32RegVal); -+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, ui32DirListReg, ui32RegVal, ui32PDUMPFlags); -+ } -+ } -+#endif /* SGX_FEATURE_MULTIPLE_MEM_CONTEXTS */ -+} -+ -+ -+/*! -+******************************************************************************* -+ -+ @Function SGXResetSetupBIFContexts -+ -+ @Description -+ Configure the BIF for the EDM context -+ -+ @Input psDevInfo - SGX Device Info -+ -+ @Return IMG_VOID -+ -+******************************************************************************/ -+static IMG_VOID SGXResetSetupBIFContexts(PVRSRV_SGXDEV_INFO *psDevInfo, -+ IMG_UINT32 ui32PDUMPFlags) -+{ -+ IMG_UINT32 ui32RegVal; -+ -+#if !defined(PDUMP) -+ PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags); -+#endif /* PDUMP */ -+ -+ #if defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) -+ /* Set up EDM for bank 0 to point at kernel context */ -+ ui32RegVal = (SGX_BIF_DIR_LIST_INDEX_EDM << EUR_CR_BIF_BANK0_INDEX_EDM_SHIFT); -+ -+ #if defined(SGX_FEATURE_2D_HARDWARE) && !defined(SGX_FEATURE_PTLA) -+ /* Set up 2D core for bank 0 to point at kernel context */ -+ ui32RegVal |= (SGX_BIF_DIR_LIST_INDEX_EDM << EUR_CR_BIF_BANK0_INDEX_2D_SHIFT); -+ #endif /* SGX_FEATURE_2D_HARDWARE */ -+ -+ #if defined(FIX_HW_BRN_23410) -+ /* Set up TA core for bank 0 to point at kernel context to guarantee it is a valid context */ -+ ui32RegVal |= (SGX_BIF_DIR_LIST_INDEX_EDM << EUR_CR_BIF_BANK0_INDEX_TA_SHIFT); -+ #endif /* FIX_HW_BRN_23410 */ -+ -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_BANK0, ui32RegVal); -+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Set up EDM requestor page table in BIF\r\n"); -+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_BANK0, ui32RegVal, ui32PDUMPFlags); -+ #endif /* defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) */ -+ -+ { -+ IMG_UINT32 ui32EDMDirListReg; -+ -+ /* Set up EDM context with kernel page directory */ -+ #if (SGX_BIF_DIR_LIST_INDEX_EDM == 0) -+ ui32EDMDirListReg = EUR_CR_BIF_DIR_LIST_BASE0; -+ #else -+ /* Bases 0 and 1 are not necessarily contiguous */ -+ ui32EDMDirListReg = EUR_CR_BIF_DIR_LIST_BASE1 + 4 * (SGX_BIF_DIR_LIST_INDEX_EDM - 1); -+ #endif /* SGX_BIF_DIR_LIST_INDEX_EDM */ -+ -+ ui32RegVal = (IMG_UINT32)(psDevInfo->sKernelPDDevPAddr.uiAddr >> SGX_MMU_PDE_ADDR_ALIGNSHIFT); -+ -+#if defined(FIX_HW_BRN_28011) -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_DIR_LIST_BASE0, ui32RegVal); -+ PDUMPPDREGWITHFLAGS(&psDevInfo->sMMUAttrib, EUR_CR_BIF_DIR_LIST_BASE0, ui32RegVal, ui32PDUMPFlags, PDUMP_PD_UNIQUETAG); -+#endif -+ -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, ui32EDMDirListReg, ui32RegVal); -+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Initialise the EDM's directory list base\r\n"); -+ PDUMPPDREGWITHFLAGS(&psDevInfo->sMMUAttrib, ui32EDMDirListReg, ui32RegVal, ui32PDUMPFlags, PDUMP_PD_UNIQUETAG); -+ } -+} -+ -+ -+/*! -+******************************************************************************* -+ -+ @Function SGXResetSleep -+ -+ @Description -+ -+ Sleep for a short time to allow reset register writes to complete. -+ Required because no status registers are available to poll on. -+ -+ @Input psDevInfo - SGX Device Info -+ @Input ui32PDUMPFlags - flags to control PDUMP output -+ @Input bPDump - Pdump the sleep -+ -+ @Return Nothing -+ -+******************************************************************************/ -+static IMG_VOID SGXResetSleep(PVRSRV_SGXDEV_INFO *psDevInfo, -+ IMG_UINT32 ui32PDUMPFlags, -+ IMG_BOOL bPDump) -+{ -+#if defined(PDUMP) || defined(EMULATOR) -+ IMG_UINT32 ui32ReadRegister; -+ -+ #if defined(SGX_FEATURE_MP) -+ ui32ReadRegister = EUR_CR_MASTER_SOFT_RESET; -+ #else -+ ui32ReadRegister = EUR_CR_SOFT_RESET; -+ #endif /* SGX_FEATURE_MP */ -+#endif -+ -+#if !defined(PDUMP) -+ PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags); -+#endif /* PDUMP */ -+ -+ /* Sleep for 100 SGX clocks */ -+ SGXWaitClocks(psDevInfo, 100); -+ if (bPDump) -+ { -+ PDUMPIDLWITHFLAGS(30, ui32PDUMPFlags); -+#if defined(PDUMP) -+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Read back to flush the register writes\r\n"); -+ PDumpRegRead(SGX_PDUMPREG_NAME, ui32ReadRegister, ui32PDUMPFlags); -+#endif -+ } -+ -+#if defined(EMULATOR) -+ /* -+ Read a register to make sure we wait long enough on the emulator... -+ */ -+ OSReadHWReg(psDevInfo->pvRegsBaseKM, ui32ReadRegister); -+#endif -+} -+ -+ -+#if !defined(SGX_FEATURE_MP) -+/*! -+******************************************************************************* -+ -+ @Function SGXResetSoftReset -+ -+ @Description -+ -+ Write to the SGX soft reset register. -+ -+ @Input psDevInfo - SGX Device Info -+ @Input bResetBIF - Include the BIF in the soft reset -+ @Input ui32PDUMPFlags - flags to control PDUMP output -+ @Input bPDump - Pdump the sleep -+ -+ @Return Nothing -+ -+******************************************************************************/ -+static IMG_VOID SGXResetSoftReset(PVRSRV_SGXDEV_INFO *psDevInfo, -+ IMG_BOOL bResetBIF, -+ IMG_UINT32 ui32PDUMPFlags, -+ IMG_BOOL bPDump) -+{ -+ IMG_UINT32 ui32SoftResetRegVal; -+ -+ ui32SoftResetRegVal = -+ /* add common reset bits: */ -+ EUR_CR_SOFT_RESET_DPM_RESET_MASK | -+ EUR_CR_SOFT_RESET_TA_RESET_MASK | -+ EUR_CR_SOFT_RESET_USE_RESET_MASK | -+ EUR_CR_SOFT_RESET_ISP_RESET_MASK | -+ EUR_CR_SOFT_RESET_TSP_RESET_MASK; -+ -+/* add conditional reset bits: */ -+#ifdef EUR_CR_SOFT_RESET_TWOD_RESET_MASK -+ ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_TWOD_RESET_MASK; -+#endif -+#if defined(EUR_CR_SOFT_RESET_TE_RESET_MASK) -+ ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_TE_RESET_MASK; -+#endif -+#if defined(EUR_CR_SOFT_RESET_MTE_RESET_MASK) -+ ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_MTE_RESET_MASK; -+#endif -+#if defined(EUR_CR_SOFT_RESET_ISP2_RESET_MASK) -+ ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_ISP2_RESET_MASK; -+#endif -+#if defined(EUR_CR_SOFT_RESET_PDS_RESET_MASK) -+ ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_PDS_RESET_MASK; -+#endif -+#if defined(EUR_CR_SOFT_RESET_PBE_RESET_MASK) -+ ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_PBE_RESET_MASK; -+#endif -+#if defined(EUR_CR_SOFT_RESET_CACHEL2_RESET_MASK) -+ ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_CACHEL2_RESET_MASK; -+#endif -+#if defined(EUR_CR_SOFT_RESET_TCU_L2_RESET_MASK) -+ ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_TCU_L2_RESET_MASK; -+#endif -+#if defined(EUR_CR_SOFT_RESET_UCACHEL2_RESET_MASK) -+ ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_UCACHEL2_RESET_MASK; -+#endif -+#if defined(EUR_CR_SOFT_RESET_MADD_RESET_MASK) -+ ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_MADD_RESET_MASK; -+#endif -+#if defined(EUR_CR_SOFT_RESET_ITR_RESET_MASK) -+ ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_ITR_RESET_MASK; -+#endif -+#if defined(EUR_CR_SOFT_RESET_TEX_RESET_MASK) -+ ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_TEX_RESET_MASK; -+#endif -+#if defined(EUR_CR_SOFT_RESET_IDXFIFO_RESET_MASK) -+ ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_IDXFIFO_RESET_MASK; -+#endif -+#if defined(EUR_CR_SOFT_RESET_VDM_RESET_MASK) -+ ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_VDM_RESET_MASK; -+#endif -+#if defined(EUR_CR_SOFT_RESET_DCU_L2_RESET_MASK) -+ ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_DCU_L2_RESET_MASK; -+#endif -+#if defined(EUR_CR_SOFT_RESET_DCU_L0L1_RESET_MASK) -+ ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_DCU_L0L1_RESET_MASK; -+#endif -+ -+#if !defined(PDUMP) -+ PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags); -+#endif /* PDUMP */ -+ -+ if (bResetBIF) -+ { -+ ui32SoftResetRegVal |= EUR_CR_SOFT_RESET_BIF_RESET_MASK; -+ } -+ -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_SOFT_RESET, ui32SoftResetRegVal); -+ if (bPDump) -+ { -+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_SOFT_RESET, ui32SoftResetRegVal, ui32PDUMPFlags); -+ } -+} -+ -+ -+/*! -+******************************************************************************* -+ -+ @Function SGXResetInvalDC -+ -+ @Description -+ -+ Invalidate the BIF Directory Cache and wait for the operation to complete. -+ -+ @Input psDevInfo - SGX Device Info -+ @Input ui32PDUMPFlags - flags to control PDUMP output -+ -+ @Return Nothing -+ -+******************************************************************************/ -+static IMG_VOID SGXResetInvalDC(PVRSRV_SGXDEV_INFO *psDevInfo, -+ IMG_UINT32 ui32PDUMPFlags, -+ IMG_BOOL bPDump) -+{ -+ IMG_UINT32 ui32RegVal; -+ -+ /* Invalidate BIF Directory cache. */ -+#if defined(EUR_CR_BIF_CTRL_INVAL) -+ ui32RegVal = EUR_CR_BIF_CTRL_INVAL_ALL_MASK; -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL_INVAL, ui32RegVal); -+ if (bPDump) -+ { -+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL_INVAL, ui32RegVal, ui32PDUMPFlags); -+ } -+#else -+ ui32RegVal = EUR_CR_BIF_CTRL_INVALDC_MASK; -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal); -+ if (bPDump) -+ { -+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags); -+ } -+ -+ ui32RegVal = 0; -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal); -+ if (bPDump) -+ { -+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags); -+ } -+#endif -+ SGXResetSleep(psDevInfo, ui32PDUMPFlags, bPDump); -+ -+#if !defined(SGX_FEATURE_MULTIPLE_MEM_CONTEXTS) -+ { -+ /* -+ Wait for the DC invalidate to complete - indicated by -+ outstanding reads reaching zero. -+ */ -+ if (PollForValueKM((IMG_UINT32 *)((IMG_UINT8*)psDevInfo->pvRegsBaseKM + EUR_CR_BIF_MEM_REQ_STAT), -+ 0, -+ EUR_CR_BIF_MEM_REQ_STAT_READS_MASK, -+ MAX_HW_TIME_US, -+ MAX_HW_TIME_US/WAIT_TRY_COUNT, -+ IMG_FALSE) != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"Wait for DC invalidate failed.")); -+ PVR_DBG_BREAK; -+ } -+ -+ if (bPDump) -+ { -+ PDUMPREGPOLWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_MEM_REQ_STAT, 0, EUR_CR_BIF_MEM_REQ_STAT_READS_MASK, ui32PDUMPFlags, PDUMP_POLL_OPERATOR_EQUAL); -+ } -+ } -+#endif /* SGX_FEATURE_MULTIPLE_MEM_CONTEXTS */ -+} -+#endif /* SGX_FEATURE_MP */ -+ -+ -+/*! -+******************************************************************************* -+ -+ @Function SGXReset -+ -+ @Description -+ -+ Reset chip -+ -+ @Input psDevInfo - device info. structure -+ @Input bHardwareRecovery - true if recovering powered hardware, -+ false if powering up -+ @Input ui32PDUMPFlags - flags to control PDUMP output -+ -+ @Return IMG_VOID -+ -+******************************************************************************/ -+IMG_VOID SGXReset(PVRSRV_SGXDEV_INFO *psDevInfo, -+ IMG_BOOL bHardwareRecovery, -+ IMG_UINT32 ui32PDUMPFlags) -+#if !defined(SGX_FEATURE_MP) -+{ -+ IMG_UINT32 ui32RegVal; -+#if defined(EUR_CR_BIF_INT_STAT_FAULT_REQ_MASK) -+ const IMG_UINT32 ui32BifFaultMask = EUR_CR_BIF_INT_STAT_FAULT_REQ_MASK; -+#else -+ const IMG_UINT32 ui32BifFaultMask = EUR_CR_BIF_INT_STAT_FAULT_MASK; -+#endif -+ -+#if !defined(PDUMP) -+ PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags); -+#endif /* PDUMP */ -+ -+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Start of SGX reset sequence\r\n"); -+ -+#if defined(FIX_HW_BRN_23944) -+ /* Pause the BIF. */ -+ ui32RegVal = EUR_CR_BIF_CTRL_PAUSE_MASK; -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal); -+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags); -+ -+ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE); -+ -+ ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_INT_STAT); -+ if (ui32RegVal & ui32BifFaultMask) -+ { -+ /* Page fault needs to be cleared before resetting the BIF. */ -+ ui32RegVal = EUR_CR_BIF_CTRL_PAUSE_MASK | EUR_CR_BIF_CTRL_CLEAR_FAULT_MASK; -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal); -+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags); -+ -+ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE); -+ -+ ui32RegVal = EUR_CR_BIF_CTRL_PAUSE_MASK; -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_CTRL, ui32RegVal); -+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_CTRL, ui32RegVal, ui32PDUMPFlags); -+ -+ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE); -+ } -+#endif /* defined(FIX_HW_BRN_23944) */ -+ -+ /* Reset all including BIF */ -+ SGXResetSoftReset(psDevInfo, IMG_TRUE, ui32PDUMPFlags, IMG_TRUE); -+ -+ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE); -+ -+ /* -+ Initialise the BIF state. -+ */ -+#if defined(SGX_FEATURE_36BIT_MMU) -+ /* enable 36bit addressing mode if the MMU supports it*/ -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_36BIT_ADDRESSING, EUR_CR_BIF_36BIT_ADDRESSING_ENABLE_MASK); -+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_36BIT_ADDRESSING, EUR_CR_BIF_36BIT_ADDRESSING_ENABLE_MASK, ui32PDUMPFlags); -+#else -+ #if defined(EUR_CR_BIF_36BIT_ADDRESSING) -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, -+ EUR_CR_BIF_36BIT_ADDRESSING, -+ 0); -+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, -+ EUR_CR_BIF_36BIT_ADDRESSING, -+ 0, -+ ui32PDUMPFlags); -+ #endif -+#endif -+ -+ SGXResetInitBIFContexts(psDevInfo, ui32PDUMPFlags); -+ -+#if defined(EUR_CR_BIF_MEM_ARB_CONFIG) -+ /* -+ Initialise the memory arbiter to its default state -+ */ -+ ui32RegVal = (12UL << EUR_CR_BIF_MEM_ARB_CONFIG_PAGE_SIZE_SHIFT) | -+ (7UL << EUR_CR_BIF_MEM_ARB_CONFIG_BEST_CNT_SHIFT) | -+ (12UL << EUR_CR_BIF_MEM_ARB_CONFIG_TTE_THRESH_SHIFT); -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_MEM_ARB_CONFIG, ui32RegVal); -+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_MEM_ARB_CONFIG, ui32RegVal, ui32PDUMPFlags); -+#endif /* EUR_CR_BIF_MEM_ARB_CONFIG */ -+ -+#if defined(SGX_FEATURE_SYSTEM_CACHE) -+ #if defined(SGX_BYPASS_SYSTEM_CACHE) -+ /* set the SLC to bypass all accesses */ -+ ui32RegVal = MNE_CR_CTRL_BYPASS_ALL_MASK; -+ #else -+ #if defined(FIX_HW_BRN_26620) -+ ui32RegVal = 0; -+ #else -+ /* set the SLC to bypass cache-coherent accesses */ -+ ui32RegVal = MNE_CR_CTRL_BYP_CC_MASK; -+ #endif -+ #if defined(FIX_HW_BRN_34028) -+ /* Bypass the MNE for the USEC requester */ -+ ui32RegVal |= (8 << MNE_CR_CTRL_BYPASS_SHIFT); -+ #endif -+ #endif /* SGX_BYPASS_SYSTEM_CACHE */ -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, MNE_CR_CTRL, ui32RegVal); -+ PDUMPREG(SGX_PDUMPREG_NAME, MNE_CR_CTRL, ui32RegVal); -+#endif /* SGX_FEATURE_SYSTEM_CACHE */ -+ -+ if (bHardwareRecovery) -+ { -+ /* -+ Set all requestors to the dummy PD which forces all memory -+ accesses to page fault. -+ This enables us to flush out BIF requests from parts of SGX -+ which do not have their own soft reset. -+ Note: sBIFResetPDDevPAddr.uiAddr is a relative address (2GB max) -+ MSB is the bus master flag; 1 == enabled -+ */ -+ ui32RegVal = (IMG_UINT32)psDevInfo->sBIFResetPDDevPAddr.uiAddr; -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_DIR_LIST_BASE0, ui32RegVal); -+ -+ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_FALSE); -+ -+ /* Bring BIF out of reset. */ -+ SGXResetSoftReset(psDevInfo, IMG_FALSE, ui32PDUMPFlags, IMG_TRUE); -+ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_FALSE); -+ -+ SGXResetInvalDC(psDevInfo, ui32PDUMPFlags, IMG_FALSE); -+ -+ /* -+ Check for a page fault from parts of SGX which do not have a reset. -+ */ -+ for (;;) -+ { -+ IMG_UINT32 ui32BifIntStat = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_INT_STAT); -+ IMG_DEV_VIRTADDR sBifFault; -+ IMG_UINT32 ui32PDIndex, ui32PTIndex; -+ -+ if ((ui32BifIntStat & ui32BifFaultMask) == 0) -+ { -+ break; -+ } -+ -+ /* -+ There is a page fault, so reset the BIF again, map in the dummy page, -+ bring the BIF up and invalidate the Directory Cache. -+ */ -+ sBifFault.uiAddr = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_FAULT); -+ PVR_DPF((PVR_DBG_WARNING, "SGXReset: Page fault 0x%x/0x%x", ui32BifIntStat, sBifFault.uiAddr)); -+ ui32PDIndex = sBifFault.uiAddr >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT); -+ ui32PTIndex = (sBifFault.uiAddr & SGX_MMU_PT_MASK) >> SGX_MMU_PAGE_SHIFT; -+ -+ /* Put the BIF into reset. */ -+ SGXResetSoftReset(psDevInfo, IMG_TRUE, ui32PDUMPFlags, IMG_FALSE); -+ -+ /* Map in the dummy page. */ -+ psDevInfo->pui32BIFResetPD[ui32PDIndex] = (IMG_UINT32)(psDevInfo->sBIFResetPTDevPAddr.uiAddr -+ >>SGX_MMU_PDE_ADDR_ALIGNSHIFT) -+ | SGX_MMU_PDE_PAGE_SIZE_4K -+ | SGX_MMU_PDE_VALID; -+ psDevInfo->pui32BIFResetPT[ui32PTIndex] = (IMG_UINT32)(psDevInfo->sBIFResetPageDevPAddr.uiAddr -+ >>SGX_MMU_PTE_ADDR_ALIGNSHIFT) -+ | SGX_MMU_PTE_VALID; -+ -+ /* Clear outstanding events. */ -+ ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_STATUS); -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR, ui32RegVal); -+ ui32RegVal = OSReadHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_STATUS2); -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR2, ui32RegVal); -+ -+ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_FALSE); -+ -+ /* Bring the BIF out of reset. */ -+ SGXResetSoftReset(psDevInfo, IMG_FALSE, ui32PDUMPFlags, IMG_FALSE); -+ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_FALSE); -+ -+ /* Invalidate Directory Cache. */ -+ SGXResetInvalDC(psDevInfo, ui32PDUMPFlags, IMG_FALSE); -+ -+ /* Unmap the dummy page and try again. */ -+ psDevInfo->pui32BIFResetPD[ui32PDIndex] = 0; -+ psDevInfo->pui32BIFResetPT[ui32PTIndex] = 0; -+ } -+ } -+ else -+ { -+ /* Bring BIF out of reset. */ -+ SGXResetSoftReset(psDevInfo, IMG_FALSE, ui32PDUMPFlags, IMG_TRUE); -+ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_FALSE); -+ } -+ -+ /* -+ Initialise the BIF memory contexts before bringing the rest of SGX out of reset. -+ */ -+ SGXResetSetupBIFContexts(psDevInfo, ui32PDUMPFlags); -+ -+#if defined(SGX_FEATURE_2D_HARDWARE) && !defined(SGX_FEATURE_PTLA) -+ /* check that the heap base has the right alignment (1Mb) */ -+ #if ((SGX_2D_HEAP_BASE & ~EUR_CR_BIF_TWOD_REQ_BASE_ADDR_MASK) != 0) -+ #error "SGXReset: SGX_2D_HEAP_BASE doesn't match EUR_CR_BIF_TWOD_REQ_BASE_ADDR_MASK alignment" -+ #endif -+ /* Set up 2D requestor base */ -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_BIF_TWOD_REQ_BASE, SGX_2D_HEAP_BASE); -+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_BIF_TWOD_REQ_BASE, SGX_2D_HEAP_BASE, ui32PDUMPFlags); -+#endif -+ -+ /* Invalidate BIF Directory cache. */ -+ SGXResetInvalDC(psDevInfo, ui32PDUMPFlags, IMG_TRUE); -+ -+ PVR_DPF((PVR_DBG_MESSAGE,"Soft Reset of SGX")); -+ -+ /* Take chip out of reset */ -+ ui32RegVal = 0; -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_SOFT_RESET, ui32RegVal); -+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_SOFT_RESET, ui32RegVal, ui32PDUMPFlags); -+ -+ /* wait a bit */ -+ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE); -+ -+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "End of SGX reset sequence\r\n"); -+} -+ -+#else -+ -+{ -+ IMG_UINT32 ui32RegVal; -+ -+ PVR_UNREFERENCED_PARAMETER(bHardwareRecovery); -+ -+#if !defined(PDUMP) -+ PVR_UNREFERENCED_PARAMETER(ui32PDUMPFlags); -+#endif /* PDUMP */ -+ -+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Start of SGX MP reset sequence\r\n"); -+ -+ /* Put hydra into soft reset */ -+ ui32RegVal = EUR_CR_MASTER_SOFT_RESET_BIF_RESET_MASK | -+ EUR_CR_MASTER_SOFT_RESET_IPF_RESET_MASK | -+ EUR_CR_MASTER_SOFT_RESET_DPM_RESET_MASK | -+ EUR_CR_MASTER_SOFT_RESET_VDM_RESET_MASK; -+ -+ if (bHardwareRecovery) -+ { -+ ui32RegVal |= EUR_CR_MASTER_SOFT_RESET_MCI_RESET_MASK; -+ } -+ -+#if defined(SGX_FEATURE_PTLA) -+ ui32RegVal |= EUR_CR_MASTER_SOFT_RESET_PTLA_RESET_MASK; -+#endif -+#if defined(SGX_FEATURE_SYSTEM_CACHE) -+ ui32RegVal |= EUR_CR_MASTER_SOFT_RESET_SLC_RESET_MASK; -+#endif -+ -+ /* Hard reset the slave cores */ -+ ui32RegVal |= EUR_CR_MASTER_SOFT_RESET_CORE_RESET_MASK(0) | -+ EUR_CR_MASTER_SOFT_RESET_CORE_RESET_MASK(1) | -+ EUR_CR_MASTER_SOFT_RESET_CORE_RESET_MASK(2) | -+ EUR_CR_MASTER_SOFT_RESET_CORE_RESET_MASK(3); -+ -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_SOFT_RESET, ui32RegVal); -+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Soft reset hydra partition, hard reset the cores\r\n"); -+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_MASTER_SOFT_RESET, ui32RegVal, ui32PDUMPFlags); -+ -+ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE); -+ -+ ui32RegVal = 0; -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_BIF_CTRL, ui32RegVal); -+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Initialise the hydra BIF control\r\n"); -+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_MASTER_BIF_CTRL, ui32RegVal, ui32PDUMPFlags); -+ -+#if defined(SGX_FEATURE_SYSTEM_CACHE) -+ #if defined(SGX_BYPASS_SYSTEM_CACHE) -+ ui32RegVal = EUR_CR_MASTER_SLC_CTRL_BYPASS_ALL_MASK; -+ #else -+ ui32RegVal = EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_REQ0_MASK | -+ #if defined(FIX_HW_BRN_30954) -+ EUR_CR_MASTER_SLC_CTRL_DISABLE_REORDERING_MASK | -+ #endif -+ #if defined(PVR_SLC_8KB_ADDRESS_MODE) -+ (4 << EUR_CR_MASTER_SLC_CTRL_ADDR_DECODE_MODE_SHIFT) | -+ #endif -+ #if defined(FIX_HW_BRN_33809) -+ (2 << EUR_CR_MASTER_SLC_CTRL_ADDR_DECODE_MODE_SHIFT) | -+ #endif -+ (0xC << EUR_CR_MASTER_SLC_CTRL_ARB_PAGE_SIZE_SHIFT); -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_SLC_CTRL, ui32RegVal); -+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Initialise the hydra SLC control\r\n"); -+ PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_MASTER_SLC_CTRL, ui32RegVal); -+ -+ ui32RegVal = EUR_CR_MASTER_SLC_CTRL_BYPASS_BYP_CC_MASK; -+ #if defined(FIX_HW_BRN_31620) -+ ui32RegVal |= EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_MMU_MASK; -+ #endif -+ #if defined(FIX_HW_BRN_31195) -+ ui32RegVal |= EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE0_MASK | -+ EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE1_MASK | -+ EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE2_MASK | -+ EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE3_MASK | -+ EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_TA_MASK; -+ #endif -+ #endif /* SGX_BYPASS_SYSTEM_CACHE */ -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_SLC_CTRL_BYPASS, ui32RegVal); -+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Initialise the hydra SLC bypass control\r\n"); -+ PDUMPREG(SGX_PDUMPREG_NAME, EUR_CR_MASTER_SLC_CTRL_BYPASS, ui32RegVal); -+#endif /* SGX_FEATURE_SYSTEM_CACHE */ -+ -+ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE); -+ -+ /* Remove the resets */ -+ ui32RegVal = 0; -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_SOFT_RESET, ui32RegVal); -+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Remove the resets from all of SGX\r\n"); -+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_MASTER_SOFT_RESET, ui32RegVal, ui32PDUMPFlags); -+ -+ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE); -+ -+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Turn on the slave cores' clock gating\r\n"); -+ SGXInitClocks(psDevInfo, ui32PDUMPFlags); -+ -+ SGXResetSleep(psDevInfo, ui32PDUMPFlags, IMG_TRUE); -+ -+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "Initialise the slave BIFs\r\n"); -+ -+#if defined(FIX_HW_BRN_31278) || defined(FIX_HW_BRN_31620) || defined(FIX_HW_BRN_31671) || defined(FIX_HW_BRN_32085) -+ #if defined(FIX_HW_BRN_31278) || defined(FIX_HW_BRN_32085) -+ /* disable prefetch */ -+ ui32RegVal = (1<<EUR_CR_MASTER_BIF_MMU_CTRL_ADDR_HASH_MODE_SHIFT); -+ #else -+ ui32RegVal = (1<<EUR_CR_MASTER_BIF_MMU_CTRL_ADDR_HASH_MODE_SHIFT) | EUR_CR_MASTER_BIF_MMU_CTRL_PREFETCHING_ON_MASK; -+ #endif -+ #if !defined(FIX_HW_BRN_31620) && !defined(FIX_HW_BRN_31671) -+ /* enable the DC TLB */ -+ ui32RegVal |= EUR_CR_MASTER_BIF_MMU_CTRL_ENABLE_DC_TLB_MASK; -+ #endif -+ -+ /* Master bank */ -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, EUR_CR_MASTER_BIF_MMU_CTRL, ui32RegVal); -+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, EUR_CR_MASTER_BIF_MMU_CTRL, ui32RegVal, ui32PDUMPFlags); -+ -+ #if defined(FIX_HW_BRN_31278) || defined(FIX_HW_BRN_32085) -+ /* disable prefetch */ -+ ui32RegVal = (1<<EUR_CR_BIF_MMU_CTRL_ADDR_HASH_MODE_SHIFT); -+ #else -+ ui32RegVal = (1<<EUR_CR_BIF_MMU_CTRL_ADDR_HASH_MODE_SHIFT) | EUR_CR_BIF_MMU_CTRL_PREFETCHING_ON_MASK; -+ #endif -+ #if !defined(FIX_HW_BRN_31620) && !defined(FIX_HW_BRN_31671) -+ /* enable the DC TLB */ -+ ui32RegVal |= EUR_CR_BIF_MMU_CTRL_ENABLE_DC_TLB_MASK; -+ #endif -+ -+ /* Per-core */ -+ { -+ IMG_UINT32 ui32Core; -+ -+ for (ui32Core=0;ui32Core<SGX_FEATURE_MP_CORE_COUNT;ui32Core++) -+ { -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, SGX_MP_CORE_SELECT(EUR_CR_BIF_MMU_CTRL, ui32Core), ui32RegVal); -+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, SGX_MP_CORE_SELECT(EUR_CR_BIF_MMU_CTRL, ui32Core), ui32RegVal, ui32PDUMPFlags); -+ } -+ } -+#endif -+ -+ SGXResetInitBIFContexts(psDevInfo, ui32PDUMPFlags); -+ SGXResetSetupBIFContexts(psDevInfo, ui32PDUMPFlags); -+ -+ PDUMPCOMMENTWITHFLAGS(ui32PDUMPFlags, "End of SGX MP reset sequence\r\n"); -+} -+#endif /* SGX_FEATURE_MP */ -+ -+ -+/****************************************************************************** -+ End of file (sgxreset.c) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/sgxtransfer.c b/drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/sgxtransfer.c -new file mode 100644 -index 0000000..bc4c762 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/sgxtransfer.c -@@ -0,0 +1,897 @@ -+/*************************************************************************/ /*! -+@Title Device specific transfer queue routines -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#if defined(TRANSFER_QUEUE) -+ -+#include <stddef.h> -+ -+#include "sgxdefs.h" -+#include "services_headers.h" -+#include "buffer_manager.h" -+#include "sgxinfo.h" -+#include "sysconfig.h" -+#include "pdump_km.h" -+#include "mmu.h" -+#include "pvr_bridge.h" -+#include "sgx_bridge_km.h" -+#include "sgxinfokm.h" -+#include "osfunc.h" -+#include "pvr_debug.h" -+#include "sgxutils.h" -+#include "ttrace.h" -+ -+#if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) -+#include "pvr_sync.h" -+#endif -+ -+IMG_EXPORT PVRSRV_ERROR SGXSubmitTransferKM(IMG_HANDLE hDevHandle, PVRSRV_TRANSFER_SGX_KICK *psKick) -+{ -+ PVRSRV_KERNEL_MEM_INFO *psCCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psKick->hCCBMemInfo; -+ SGXMKIF_COMMAND sCommand = {0}; -+ SGXMKIF_TRANSFERCMD_SHARED *psSharedTransferCmd; -+ PVRSRV_KERNEL_SYNC_INFO *psSyncInfo; -+ PVRSRV_ERROR eError; -+ IMG_UINT32 loop; -+ IMG_HANDLE hDevMemContext = IMG_NULL; -+ IMG_BOOL abSrcSyncEnable[SGX_MAX_TRANSFER_SYNC_OPS]; -+ IMG_UINT32 ui32RealSrcSyncNum = 0; -+ IMG_BOOL abDstSyncEnable[SGX_MAX_TRANSFER_SYNC_OPS]; -+ IMG_UINT32 ui32RealDstSyncNum = 0; -+ -+ -+#if defined(PDUMP) -+ IMG_BOOL bPersistentProcess = IMG_FALSE; -+ /* -+ * For persistent processes, the HW kicks should not go into the -+ * extended init phase; only keep memory transactions from the -+ * window system which are necessary to run the client app. -+ */ -+ { -+ PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData(); -+ if(psPerProc != IMG_NULL) -+ { -+ bPersistentProcess = psPerProc->bPDumpPersistent; -+ } -+ } -+#endif /* PDUMP */ -+#if defined(FIX_HW_BRN_31620) -+ hDevMemContext = psKick->hDevMemContext; -+#endif -+ PVR_TTRACE(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_FUNCTION_ENTER, TRANSFER_TOKEN_SUBMIT); -+ -+ for (loop = 0; loop < SGX_MAX_TRANSFER_SYNC_OPS; loop++) -+ { -+ abSrcSyncEnable[loop] = IMG_TRUE; -+ abDstSyncEnable[loop] = IMG_TRUE; -+ } -+ -+ if (!CCB_OFFSET_IS_VALID(SGXMKIF_TRANSFERCMD_SHARED, psCCBMemInfo, psKick, ui32SharedCmdCCBOffset)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SGXSubmitTransferKM: Invalid CCB offset")); -+ PVR_TTRACE(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_FUNCTION_EXIT, -+ TRANSFER_TOKEN_SUBMIT); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ /* override QAC warning about stricter alignment */ -+ /* PRQA S 3305 1 */ -+ psSharedTransferCmd = CCB_DATA_FROM_OFFSET(SGXMKIF_TRANSFERCMD_SHARED, psCCBMemInfo, psKick, ui32SharedCmdCCBOffset); -+ -+ PVR_TTRACE(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_CMD_START, TRANSFER_TOKEN_SUBMIT); -+ PVR_TTRACE_UI32(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_CCB, -+ TRANSFER_TOKEN_CCB_OFFSET, psKick->ui32SharedCmdCCBOffset); -+ -+ if (psKick->hTASyncInfo != IMG_NULL) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo; -+ -+ PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_TRANSFER, TRANSFER_TOKEN_TA_SYNC, -+ psSyncInfo, PVRSRV_SYNCOP_SAMPLE); -+ -+ psSharedTransferCmd->ui32TASyncWriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++; -+ psSharedTransferCmd->ui32TASyncReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; -+ -+ psSharedTransferCmd->sTASyncWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; -+ psSharedTransferCmd->sTASyncReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; -+ } -+ else -+ { -+ psSharedTransferCmd->sTASyncWriteOpsCompleteDevVAddr.uiAddr = 0; -+ psSharedTransferCmd->sTASyncReadOpsCompleteDevVAddr.uiAddr = 0; -+ } -+ -+ if (psKick->h3DSyncInfo != IMG_NULL) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo; -+ -+ PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_TRANSFER, TRANSFER_TOKEN_3D_SYNC, -+ psSyncInfo, PVRSRV_SYNCOP_SAMPLE); -+ -+ psSharedTransferCmd->ui323DSyncWriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++; -+ psSharedTransferCmd->ui323DSyncReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; -+ -+ psSharedTransferCmd->s3DSyncWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; -+ psSharedTransferCmd->s3DSyncReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; -+ } -+ else -+ { -+ psSharedTransferCmd->s3DSyncWriteOpsCompleteDevVAddr.uiAddr = 0; -+ psSharedTransferCmd->s3DSyncReadOpsCompleteDevVAddr.uiAddr = 0; -+ } -+ -+ /* filter out multiple occurrences of the same sync object from srcs or dests -+ * note : the same sync can still be used to synchronize both src and dst. -+ */ -+ for (loop = 0; loop < MIN(SGX_MAX_TRANSFER_SYNC_OPS, psKick->ui32NumSrcSync); loop++) -+ { -+ IMG_UINT32 i; -+ -+ PVRSRV_KERNEL_SYNC_INFO * psMySyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[loop]; -+ -+ for (i = 0; i < loop; i++) -+ { -+ if (abSrcSyncEnable[i]) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[i]; -+ -+ if (psSyncInfo->sWriteOpsCompleteDevVAddr.uiAddr == psMySyncInfo->sWriteOpsCompleteDevVAddr.uiAddr) -+ { -+ PVR_DPF((PVR_DBG_WARNING, "SGXSubmitTransferKM : Same src synchronized multiple times!")); -+ abSrcSyncEnable[loop] = IMG_FALSE; -+ break; -+ } -+ } -+ } -+ if (abSrcSyncEnable[loop]) -+ { -+ ui32RealSrcSyncNum++; -+ } -+ } -+ for (loop = 0; loop < MIN(SGX_MAX_TRANSFER_SYNC_OPS, psKick->ui32NumDstSync); loop++) -+ { -+ IMG_UINT32 i; -+ -+ PVRSRV_KERNEL_SYNC_INFO * psMySyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[loop]; -+ -+ for (i = 0; i < loop; i++) -+ { -+ if (abDstSyncEnable[i]) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[i]; -+ -+ if (psSyncInfo->sWriteOpsCompleteDevVAddr.uiAddr == psMySyncInfo->sWriteOpsCompleteDevVAddr.uiAddr) -+ { -+ PVR_DPF((PVR_DBG_WARNING, "SGXSubmitTransferKM : Same dst synchronized multiple times!")); -+ abDstSyncEnable[loop] = IMG_FALSE; -+ break; -+ } -+ } -+ } -+ if (abDstSyncEnable[loop]) -+ { -+ ui32RealDstSyncNum++; -+ } -+ } -+ -+ if ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) == 0UL) -+ { -+ IMG_UINT32 i = 0; -+ -+ for (loop = 0; loop < psKick->ui32NumSrcSync; loop++) -+ { -+ if (abSrcSyncEnable[loop]) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[loop]; -+ -+ PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_TRANSFER, TRANSFER_TOKEN_SRC_SYNC, -+ psSyncInfo, PVRSRV_SYNCOP_SAMPLE); -+ -+ psSharedTransferCmd->asSrcSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; -+ psSharedTransferCmd->asSrcSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; -+ -+ psSharedTransferCmd->asSrcSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; -+ psSharedTransferCmd->asSrcSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; -+ i++; -+ } -+ } -+ PVR_ASSERT(i == ui32RealSrcSyncNum); -+ -+ i = 0; -+ for (loop = 0; loop < psKick->ui32NumDstSync; loop++) -+ { -+ if (abDstSyncEnable[loop]) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[loop]; -+ -+ psSyncInfo->psSyncData->ui64LastWrite = ui64KickCount; -+ -+ PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_TRANSFER, TRANSFER_TOKEN_DST_SYNC, -+ psSyncInfo, PVRSRV_SYNCOP_SAMPLE); -+ -+ psSharedTransferCmd->asDstSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; -+ psSharedTransferCmd->asDstSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; -+ psSharedTransferCmd->asDstSyncs[i].ui32ReadOps2PendingVal = psSyncInfo->psSyncData->ui32ReadOps2Pending; -+ -+ psSharedTransferCmd->asDstSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; -+ psSharedTransferCmd->asDstSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; -+ psSharedTransferCmd->asDstSyncs[i].sReadOps2CompleteDevVAddr = psSyncInfo->sReadOps2CompleteDevVAddr; -+ i++; -+ } -+ } -+ PVR_ASSERT(i == ui32RealDstSyncNum); -+ -+ /* -+ * We allow source and destination sync objects to be the -+ * same, which is why the read/write pending updates are delayed -+ * until the transfer command has been updated with the current -+ * values from the objects. -+ */ -+ for (loop = 0; loop < psKick->ui32NumSrcSync; loop++) -+ { -+ if (abSrcSyncEnable[loop]) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[loop]; -+ psSyncInfo->psSyncData->ui32ReadOpsPending++; -+ } -+ } -+ for (loop = 0; loop < psKick->ui32NumDstSync; loop++) -+ { -+ if (abDstSyncEnable[loop]) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[loop]; -+ psSyncInfo->psSyncData->ui32WriteOpsPending++; -+ } -+ } -+ -+#if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) -+ if (ui32RealDstSyncNum < SGX_MAX_TRANSFER_SYNC_OPS - 2 && psKick->iFenceFd > 0) -+ { -+ IMG_HANDLE ahSyncInfo[SGX_MAX_SRC_SYNCS_TA]; -+ PVRSRV_DEVICE_SYNC_OBJECT *apsDevSyncs = &psSharedTransferCmd->asDstSyncs[ui32RealDstSyncNum]; -+ IMG_UINT32 ui32NumSrcSyncs = 1; -+ IMG_UINT32 i; -+ ahSyncInfo[0] = (IMG_HANDLE)(psKick->iFenceFd - 1); -+ -+ eError = PVRSyncPatchTransferSyncInfos(ahSyncInfo, apsDevSyncs, &ui32NumSrcSyncs); -+ if (eError != PVRSRV_OK) -+ { -+ /* We didn't kick yet, or perform PDUMP processing, so we should -+ * be able to trivially roll back any changes made to the sync -+ * data. If we don't do this, we'll wedge services cleanup. -+ */ -+ -+ for (loop = 0; loop < psKick->ui32NumDstSync; loop++) -+ { -+ if (abDstSyncEnable[loop]) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[loop]; -+ psSyncInfo->psSyncData->ui32WriteOpsPending--; -+ } -+ } -+ -+ for (loop = 0; loop < psKick->ui32NumSrcSync; loop++) -+ { -+ if (abSrcSyncEnable[loop]) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[loop]; -+ psSyncInfo->psSyncData->ui32ReadOpsPending--; -+ } -+ } -+ -+ if (psKick->h3DSyncInfo != IMG_NULL) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo; -+ psSyncInfo->psSyncData->ui32WriteOpsPending++; -+ } -+ -+ if (psKick->hTASyncInfo != IMG_NULL) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo; -+ psSyncInfo->psSyncData->ui32WriteOpsPending--; -+ } -+ -+ PVR_DPF((PVR_DBG_ERROR, "SGXSubmitTransferKM: PVRSyncPatchCCBKickSyncInfos failed.")); -+ PVR_TTRACE(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_FUNCTION_EXIT, -+ TRANSFER_TOKEN_SUBMIT); -+ return eError; -+ } -+ -+ /* Find a free dst sync to slot in our extra sync */ -+ for (loop = 0; loop < psKick->ui32NumDstSync; loop++) -+ { -+ if (abDstSyncEnable[loop]) -+ break; -+ } -+ -+ /* We shouldn't be in this code path if ui32RealDstSyncNum -+ * didn't allow for at least two free synchronization slots. -+ */ -+ PVR_ASSERT(loop + ui32NumSrcSyncs <= SGX_MAX_TRANSFER_SYNC_OPS); -+ -+ /* Slot in the extra dst syncs */ -+ for (i = 0; i < ui32NumSrcSyncs; i++) -+ { -+ psKick->ahDstSyncInfo[loop + i] = ahSyncInfo[i]; -+ abDstSyncEnable[loop + i] = IMG_TRUE; -+ psKick->ui32NumDstSync++; -+ ui32RealDstSyncNum++; -+ } -+ } -+#endif /* defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) */ -+ } -+ -+ psSharedTransferCmd->ui32NumSrcSyncs = ui32RealSrcSyncNum; -+ psSharedTransferCmd->ui32NumDstSyncs = ui32RealDstSyncNum; -+ -+#if defined(PDUMP) -+ if (PDumpIsCaptureFrameKM() -+ || ((psKick->ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0)) -+ { -+ PDUMPCOMMENT("Shared part of transfer command\r\n"); -+ PDUMPMEM(psSharedTransferCmd, -+ psCCBMemInfo, -+ psKick->ui32CCBDumpWOff, -+ sizeof(SGXMKIF_TRANSFERCMD_SHARED), -+ psKick->ui32PDumpFlags, -+ MAKEUNIQUETAG(psCCBMemInfo)); -+ -+ if ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) == 0UL) -+ { -+ IMG_UINT32 i = 0; -+ -+ for (loop = 0; loop < psKick->ui32NumSrcSync; loop++) -+ { -+ if (abSrcSyncEnable[loop]) -+ { -+ psSyncInfo = psKick->ahSrcSyncInfo[loop]; -+ -+ PDUMPCOMMENT("Tweak src surface write op in transfer cmd\r\n"); -+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, -+ psCCBMemInfo, -+ psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, asSrcSyncs) + i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal)), -+ sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal), -+ psKick->ui32PDumpFlags, -+ MAKEUNIQUETAG(psCCBMemInfo)); -+ -+ PDUMPCOMMENT("Tweak src surface read op in transfer cmd\r\n"); -+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, -+ psCCBMemInfo, -+ psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, asSrcSyncs) + i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal)), -+ sizeof(psSyncInfo->psSyncData->ui32LastReadOpDumpVal), -+ psKick->ui32PDumpFlags, -+ MAKEUNIQUETAG(psCCBMemInfo)); -+ i++; -+ } -+ } -+ -+ i = 0; -+ for (loop = 0; loop < psKick->ui32NumDstSync; loop++) -+ { -+ if (abDstSyncEnable[i]) -+ { -+ IMG_UINT32 ui32PDumpReadOp2 = 0; -+ psSyncInfo = psKick->ahDstSyncInfo[loop]; -+ -+ PDUMPCOMMENT("Tweak dest surface write op in transfer cmd\r\n"); -+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, -+ psCCBMemInfo, -+ psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, asDstSyncs) + i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal)), -+ sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal), -+ psKick->ui32PDumpFlags, -+ MAKEUNIQUETAG(psCCBMemInfo)); -+ -+ PDUMPCOMMENT("Tweak dest surface read op in transfer cmd\r\n"); -+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, -+ psCCBMemInfo, -+ psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, asDstSyncs) + i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal)), -+ sizeof(psSyncInfo->psSyncData->ui32LastReadOpDumpVal), -+ psKick->ui32PDumpFlags, -+ MAKEUNIQUETAG(psCCBMemInfo)); -+ -+ PDUMPCOMMENT("Tweak dest surface read op2 in transfer cmd\r\n"); -+ PDUMPMEM(&ui32PDumpReadOp2, -+ psCCBMemInfo, -+ psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, asDstSyncs) + i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOps2PendingVal)), -+ sizeof(ui32PDumpReadOp2), -+ psKick->ui32PDumpFlags, -+ MAKEUNIQUETAG(psCCBMemInfo)); -+ i++; -+ } -+ } -+ -+ /* -+ * We allow the first source and destination sync objects to be the -+ * same, which is why the read/write pending updates are delayed -+ * until the transfer command has been updated with the current -+ * values from the objects. -+ */ -+ for (loop = 0; loop < (psKick->ui32NumSrcSync); loop++) -+ { -+ if (abSrcSyncEnable[loop]) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[loop]; -+ psSyncInfo->psSyncData->ui32LastReadOpDumpVal++; -+ } -+ } -+ -+ for (loop = 0; loop < (psKick->ui32NumDstSync); loop++) -+ { -+ if (abDstSyncEnable[loop]) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[0]; -+ psSyncInfo->psSyncData->ui32LastOpDumpVal++; -+ } -+ } -+ } -+ -+ if (psKick->hTASyncInfo != IMG_NULL) -+ { -+ psSyncInfo = psKick->hTASyncInfo; -+ -+ PDUMPCOMMENT("Tweak TA/TQ surface write op in transfer cmd\r\n"); -+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, -+ psCCBMemInfo, -+ psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, ui32TASyncWriteOpsPendingVal)), -+ sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal), -+ psKick->ui32PDumpFlags, -+ MAKEUNIQUETAG(psCCBMemInfo)); -+ -+ PDUMPCOMMENT("Tweak TA/TQ surface read op in transfer cmd\r\n"); -+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, -+ psCCBMemInfo, -+ psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, ui32TASyncReadOpsPendingVal)), -+ sizeof(psSyncInfo->psSyncData->ui32LastReadOpDumpVal), -+ psKick->ui32PDumpFlags, -+ MAKEUNIQUETAG(psCCBMemInfo)); -+ -+ psSyncInfo->psSyncData->ui32LastOpDumpVal++; -+ } -+ -+ if (psKick->h3DSyncInfo != IMG_NULL) -+ { -+ psSyncInfo = psKick->h3DSyncInfo; -+ -+ PDUMPCOMMENT("Tweak 3D/TQ surface write op in transfer cmd\r\n"); -+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, -+ psCCBMemInfo, -+ psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, ui323DSyncWriteOpsPendingVal)), -+ sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal), -+ psKick->ui32PDumpFlags, -+ MAKEUNIQUETAG(psCCBMemInfo)); -+ -+ PDUMPCOMMENT("Tweak 3D/TQ surface read op in transfer cmd\r\n"); -+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, -+ psCCBMemInfo, -+ psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, ui323DSyncReadOpsPendingVal)), -+ sizeof(psSyncInfo->psSyncData->ui32LastReadOpDumpVal), -+ psKick->ui32PDumpFlags, -+ MAKEUNIQUETAG(psCCBMemInfo)); -+ -+ psSyncInfo->psSyncData->ui32LastOpDumpVal++; -+ } -+ } -+#endif -+ -+ sCommand.ui32Data[1] = psKick->sHWTransferContextDevVAddr.uiAddr; -+ -+ PVR_TTRACE(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_CMD_END, -+ TRANSFER_TOKEN_SUBMIT); -+ -+ eError = SGXScheduleCCBCommandKM(hDevHandle, SGXMKIF_CMD_TRANSFER, &sCommand, KERNEL_ID, psKick->ui32PDumpFlags, hDevMemContext, IMG_FALSE); -+ -+ if (eError == PVRSRV_ERROR_RETRY) -+ { -+ /* Client will retry, so undo the sync ops pending increment(s) done above. */ -+ if ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) == 0UL) -+ { -+ for (loop = 0; loop < psKick->ui32NumSrcSync; loop++) -+ { -+ if (abSrcSyncEnable[loop]) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[loop]; -+ psSyncInfo->psSyncData->ui32ReadOpsPending--; -+#if defined(PDUMP) -+ if (PDumpIsCaptureFrameKM() -+ || ((psKick->ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0)) -+ { -+ psSyncInfo->psSyncData->ui32LastReadOpDumpVal--; -+ } -+#endif -+ } -+ } -+ for (loop = 0; loop < psKick->ui32NumDstSync; loop++) -+ { -+ if (abDstSyncEnable[loop]) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[loop]; -+ psSyncInfo->psSyncData->ui32WriteOpsPending--; -+#if defined(PDUMP) -+ if (PDumpIsCaptureFrameKM() -+ || ((psKick->ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0)) -+ { -+ psSyncInfo->psSyncData->ui32LastOpDumpVal--; -+ } -+#endif -+ } -+ } -+ } -+ -+ /* Command needed to be synchronised with the TA? */ -+ if (psKick->hTASyncInfo != IMG_NULL) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo; -+ psSyncInfo->psSyncData->ui32WriteOpsPending--; -+ } -+ -+ /* Command needed to be synchronised with the 3D? */ -+ if (psKick->h3DSyncInfo != IMG_NULL) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo; -+ psSyncInfo->psSyncData->ui32WriteOpsPending--; -+ } -+ } -+ -+ else if (PVRSRV_OK != eError) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SGXSubmitTransferKM: SGXScheduleCCBCommandKM failed.")); -+ PVR_TTRACE(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_FUNCTION_EXIT, -+ TRANSFER_TOKEN_SUBMIT); -+ return eError; -+ } -+ -+ -+#if defined(NO_HARDWARE) -+ if ((psKick->ui32Flags & SGXMKIF_TQFLAGS_NOSYNCUPDATE) == 0) -+ { -+ /* Update sync objects pretending that we have done the job*/ -+ for (loop = 0; loop < psKick->ui32NumSrcSync; loop++) -+ { -+ if (abSrcSyncEnable[loop]) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[loop]; -+ psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending; -+ } -+ } -+ -+ for (loop = 0; loop < psKick->ui32NumDstSync; loop++) -+ { -+ if (abDstSyncEnable[loop]) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[loop]; -+ psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; -+ } -+ } -+ -+ if (psKick->hTASyncInfo != IMG_NULL) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo; -+ -+ psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; -+ } -+ -+ if (psKick->h3DSyncInfo != IMG_NULL) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo; -+ -+ psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; -+ } -+ } -+#endif -+ PVR_TTRACE(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_FUNCTION_EXIT, -+ TRANSFER_TOKEN_SUBMIT); -+ return eError; -+} -+ -+#if defined(SGX_FEATURE_2D_HARDWARE) -+IMG_EXPORT PVRSRV_ERROR SGXSubmit2DKM(IMG_HANDLE hDevHandle, PVRSRV_2D_SGX_KICK *psKick) -+ -+{ -+ PVRSRV_KERNEL_MEM_INFO *psCCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psKick->hCCBMemInfo; -+ SGXMKIF_COMMAND sCommand = {0}; -+ SGXMKIF_2DCMD_SHARED *ps2DCmd; -+ PVRSRV_KERNEL_SYNC_INFO *psSyncInfo; -+ PVRSRV_ERROR eError; -+ IMG_UINT32 i; -+ IMG_HANDLE hDevMemContext = IMG_NULL; -+#if defined(FIX_HW_BRN_31620) -+ hDevMemContext = psKick->hDevMemContext; -+#endif -+ -+ if (!CCB_OFFSET_IS_VALID(SGXMKIF_2DCMD_SHARED, psCCBMemInfo, psKick, ui32SharedCmdCCBOffset)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SGXSubmit2DKM: Invalid CCB offset")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ /* override QAC warning about stricter alignment */ -+ /* PRQA S 3305 1 */ -+ ps2DCmd = CCB_DATA_FROM_OFFSET(SGXMKIF_2DCMD_SHARED, psCCBMemInfo, psKick, ui32SharedCmdCCBOffset); -+ -+ /* Command needs to be synchronised with the TA? */ -+ if (psKick->hTASyncInfo != IMG_NULL) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo; -+ -+ ps2DCmd->sTASyncData.ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++; -+ ps2DCmd->sTASyncData.ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; -+ -+ ps2DCmd->sTASyncData.sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; -+ ps2DCmd->sTASyncData.sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; -+ } -+ else -+ { -+ ps2DCmd->sTASyncData.sWriteOpsCompleteDevVAddr.uiAddr = 0; -+ ps2DCmd->sTASyncData.sReadOpsCompleteDevVAddr.uiAddr = 0; -+ } -+ -+ /* Command needs to be synchronised with the 3D? */ -+ if (psKick->h3DSyncInfo != IMG_NULL) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo; -+ -+ ps2DCmd->s3DSyncData.ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++; -+ ps2DCmd->s3DSyncData.ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; -+ -+ ps2DCmd->s3DSyncData.sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; -+ ps2DCmd->s3DSyncData.sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; -+ } -+ else -+ { -+ ps2DCmd->s3DSyncData.sWriteOpsCompleteDevVAddr.uiAddr = 0; -+ ps2DCmd->s3DSyncData.sReadOpsCompleteDevVAddr.uiAddr = 0; -+ } -+ -+ /* -+ * We allow the first source and destination sync objects to be the -+ * same, which is why the read/write pending updates are delayed -+ * until the transfer command has been updated with the current -+ * values from the objects. -+ */ -+ ps2DCmd->ui32NumSrcSync = psKick->ui32NumSrcSync; -+ -+ for (i = 0; i < psKick->ui32NumSrcSync; i++) -+ { -+ psSyncInfo = psKick->ahSrcSyncInfo[i]; -+ -+ ps2DCmd->sSrcSyncData[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; -+ ps2DCmd->sSrcSyncData[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; -+ -+ ps2DCmd->sSrcSyncData[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; -+ ps2DCmd->sSrcSyncData[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; -+ } -+ -+ if (psKick->hDstSyncInfo != IMG_NULL) -+ { -+ psSyncInfo = psKick->hDstSyncInfo; -+ -+ ps2DCmd->sDstSyncData.ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; -+ ps2DCmd->sDstSyncData.ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; -+ ps2DCmd->sDstSyncData.ui32ReadOps2PendingVal = psSyncInfo->psSyncData->ui32ReadOps2Pending; -+ -+ ps2DCmd->sDstSyncData.sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; -+ ps2DCmd->sDstSyncData.sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; -+ ps2DCmd->sDstSyncData.sReadOps2CompleteDevVAddr = psSyncInfo->sReadOps2CompleteDevVAddr; -+ -+ /* We can do this immediately as we only have one */ -+ psSyncInfo->psSyncData->ui32WriteOpsPending++; -+ } -+ else -+ { -+ ps2DCmd->sDstSyncData.sWriteOpsCompleteDevVAddr.uiAddr = 0; -+ ps2DCmd->sDstSyncData.sReadOpsCompleteDevVAddr.uiAddr = 0; -+ ps2DCmd->sDstSyncData.sReadOps2CompleteDevVAddr.uiAddr = 0; -+ } -+ -+ /* Read/Write ops pending updates, delayed from above */ -+ for (i = 0; i < psKick->ui32NumSrcSync; i++) -+ { -+ psSyncInfo = psKick->ahSrcSyncInfo[i]; -+ psSyncInfo->psSyncData->ui32ReadOpsPending++; -+ } -+ -+#if defined(PDUMP) -+ if ((PDumpIsCaptureFrameKM() -+ || ((psKick->ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0))) -+ { -+ /* Pdump the command from the per context CCB */ -+ PDUMPCOMMENT("Shared part of 2D command\r\n"); -+ PDUMPMEM(ps2DCmd, -+ psCCBMemInfo, -+ psKick->ui32CCBDumpWOff, -+ sizeof(SGXMKIF_2DCMD_SHARED), -+ psKick->ui32PDumpFlags, -+ MAKEUNIQUETAG(psCCBMemInfo)); -+ -+ for (i = 0; i < psKick->ui32NumSrcSync; i++) -+ { -+ psSyncInfo = psKick->ahSrcSyncInfo[i]; -+ -+ PDUMPCOMMENT("Tweak src surface write op in 2D cmd\r\n"); -+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, -+ psCCBMemInfo, -+ psKick->ui32CCBDumpWOff + (IMG_UINT32)offsetof(SGXMKIF_2DCMD_SHARED, sSrcSyncData[i].ui32WriteOpsPendingVal), -+ sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal), -+ psKick->ui32PDumpFlags, -+ MAKEUNIQUETAG(psCCBMemInfo)); -+ -+ PDUMPCOMMENT("Tweak src surface read op in 2D cmd\r\n"); -+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, -+ psCCBMemInfo, -+ psKick->ui32CCBDumpWOff + (IMG_UINT32)offsetof(SGXMKIF_2DCMD_SHARED, sSrcSyncData[i].ui32ReadOpsPendingVal), -+ sizeof(psSyncInfo->psSyncData->ui32LastReadOpDumpVal), -+ psKick->ui32PDumpFlags, -+ MAKEUNIQUETAG(psCCBMemInfo)); -+ } -+ -+ if (psKick->hDstSyncInfo != IMG_NULL) -+ { -+ IMG_UINT32 ui32PDumpReadOp2 = 0; -+ psSyncInfo = psKick->hDstSyncInfo; -+ -+ PDUMPCOMMENT("Tweak dest surface write op in 2D cmd\r\n"); -+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, -+ psCCBMemInfo, -+ psKick->ui32CCBDumpWOff + (IMG_UINT32)offsetof(SGXMKIF_2DCMD_SHARED, sDstSyncData.ui32WriteOpsPendingVal), -+ sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal), -+ psKick->ui32PDumpFlags, -+ MAKEUNIQUETAG(psCCBMemInfo)); -+ -+ PDUMPCOMMENT("Tweak dest surface read op in 2D cmd\r\n"); -+ PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, -+ psCCBMemInfo, -+ psKick->ui32CCBDumpWOff + (IMG_UINT32)offsetof(SGXMKIF_2DCMD_SHARED, sDstSyncData.ui32ReadOpsPendingVal), -+ sizeof(psSyncInfo->psSyncData->ui32LastReadOpDumpVal), -+ psKick->ui32PDumpFlags, -+ MAKEUNIQUETAG(psCCBMemInfo)); -+ PDUMPCOMMENT("Tweak dest surface read op2 in 2D cmd\r\n"); -+ PDUMPMEM(&ui32PDumpReadOp2, -+ psCCBMemInfo, -+ psKick->ui32CCBDumpWOff + (IMG_UINT32)offsetof(SGXMKIF_2DCMD_SHARED, sDstSyncData.ui32ReadOps2PendingVal), -+ sizeof(ui32PDumpReadOp2), -+ psKick->ui32PDumpFlags, -+ MAKEUNIQUETAG(psCCBMemInfo)); -+ } -+ -+ /* Read/Write ops pending updates, delayed from above */ -+ for (i = 0; i < psKick->ui32NumSrcSync; i++) -+ { -+ psSyncInfo = psKick->ahSrcSyncInfo[i]; -+ psSyncInfo->psSyncData->ui32LastReadOpDumpVal++; -+ } -+ -+ if (psKick->hDstSyncInfo != IMG_NULL) -+ { -+ psSyncInfo = psKick->hDstSyncInfo; -+ psSyncInfo->psSyncData->ui32LastOpDumpVal++; -+ } -+ } -+#endif -+ -+ sCommand.ui32Data[1] = psKick->sHW2DContextDevVAddr.uiAddr; -+ -+ eError = SGXScheduleCCBCommandKM(hDevHandle, SGXMKIF_CMD_2D, &sCommand, KERNEL_ID, psKick->ui32PDumpFlags, hDevMemContext, IMG_FALSE); -+ -+ if (eError == PVRSRV_ERROR_RETRY) -+ { -+ /* Client will retry, so undo the write ops pending increment -+ done above. -+ */ -+#if defined(PDUMP) -+ if (PDumpIsCaptureFrameKM()) -+ { -+ for (i = 0; i < psKick->ui32NumSrcSync; i++) -+ { -+ psSyncInfo = psKick->ahSrcSyncInfo[i]; -+ psSyncInfo->psSyncData->ui32LastReadOpDumpVal--; -+ } -+ -+ if (psKick->hDstSyncInfo != IMG_NULL) -+ { -+ psSyncInfo = psKick->hDstSyncInfo; -+ psSyncInfo->psSyncData->ui32LastOpDumpVal--; -+ } -+ } -+#endif -+ -+ for (i = 0; i < psKick->ui32NumSrcSync; i++) -+ { -+ psSyncInfo = psKick->ahSrcSyncInfo[i]; -+ psSyncInfo->psSyncData->ui32ReadOpsPending--; -+ } -+ -+ if (psKick->hDstSyncInfo != IMG_NULL) -+ { -+ psSyncInfo = psKick->hDstSyncInfo; -+ psSyncInfo->psSyncData->ui32WriteOpsPending--; -+ } -+ -+ /* Command needed to be synchronised with the TA? */ -+ if (psKick->hTASyncInfo != IMG_NULL) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo; -+ -+ psSyncInfo->psSyncData->ui32WriteOpsPending--; -+ } -+ -+ /* Command needed to be synchronised with the 3D? */ -+ if (psKick->h3DSyncInfo != IMG_NULL) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo; -+ -+ psSyncInfo->psSyncData->ui32WriteOpsPending--; -+ } -+ } -+ -+ -+ -+ -+#if defined(NO_HARDWARE) -+ /* Update sync objects pretending that we have done the job*/ -+ for(i = 0; i < psKick->ui32NumSrcSync; i++) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[i]; -+ psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending; -+ } -+ -+ if (psKick->hDstSyncInfo != IMG_NULL) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hDstSyncInfo; -+ -+ psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; -+ } -+ -+ if (psKick->hTASyncInfo != IMG_NULL) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo; -+ -+ psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; -+ } -+ -+ if (psKick->h3DSyncInfo != IMG_NULL) -+ { -+ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo; -+ -+ psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; -+ } -+#endif -+ -+ return eError; -+} -+#endif /* SGX_FEATURE_2D_HARDWARE */ -+#endif /* TRANSFER_QUEUE */ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/sgxutils.c b/drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/sgxutils.c -new file mode 100644 -index 0000000..bb10775 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/sgxutils.c -@@ -0,0 +1,1919 @@ -+/*************************************************************************/ /*! -+@Title Device specific utility routines -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Device specific functions -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#include <stddef.h> -+ -+#include "sgxdefs.h" -+#include "services_headers.h" -+#include "buffer_manager.h" -+#include "sgx_bridge_km.h" -+#include "sgxapi_km.h" -+#include "sgxinfo.h" -+#include "sgx_mkif_km.h" -+#include "sysconfig.h" -+#include "pdump_km.h" -+#include "mmu.h" -+#include "pvr_bridge_km.h" -+#include "osfunc.h" -+#include "pvr_debug.h" -+#include "sgxutils.h" -+#include "ttrace.h" -+#include "sgxmmu.h" -+ -+#ifdef __linux__ -+#include <linux/kernel.h> // sprintf -+#include <linux/string.h> // strncpy, strlen -+#else -+#include <stdio.h> -+#endif -+ -+IMG_UINT64 ui64KickCount; -+ -+ -+#if defined(SYS_CUSTOM_POWERDOWN) -+PVRSRV_ERROR SysPowerDownMISR(PVRSRV_DEVICE_NODE * psDeviceNode, IMG_UINT32 ui32CallerID); -+#endif -+ -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SGXPostActivePowerEvent -+ -+ @Description -+ -+ post power event functionality (e.g. restart) -+ -+ @Input psDeviceNode : SGX Device Node -+ @Input ui32CallerID - KERNEL_ID or ISR_ID -+ -+ @Return IMG_VOID : -+ -+******************************************************************************/ -+static IMG_VOID SGXPostActivePowerEvent(PVRSRV_DEVICE_NODE * psDeviceNode, -+ IMG_UINT32 ui32CallerID) -+{ -+ PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; -+ SGXMKIF_HOST_CTL *psSGXHostCtl = psDevInfo->psSGXHostCtl; -+ -+ /* Update the counter for stats. */ -+ psSGXHostCtl->ui32NumActivePowerEvents++; -+ -+ if ((psSGXHostCtl->ui32PowerStatus & PVRSRV_USSE_EDM_POWMAN_POWEROFF_RESTART_IMMEDIATE) != 0) -+ { -+ PVR_DPF((PVR_DBG_MESSAGE, "SGXPostActivePowerEvent: SGX requests immediate restart")); -+ -+ /* -+ Events were queued during the active power -+ request, so SGX will need to be restarted. -+ */ -+ if (ui32CallerID == ISR_ID) -+ { -+ psDeviceNode->bReProcessDeviceCommandComplete = IMG_TRUE; -+ } -+ else -+ { -+ SGXScheduleProcessQueuesKM(psDeviceNode); -+ } -+ } -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SGXTestActivePowerEvent -+ -+ @Description -+ -+ Checks whether the microkernel has generated an active power event. If so, -+ perform the power transition. -+ -+ @Input psDeviceNode : SGX Device Node -+ @Input ui32CallerID - KERNEL_ID or ISR_ID -+ -+ @Return IMG_VOID : -+ -+******************************************************************************/ -+IMG_VOID SGXTestActivePowerEvent (PVRSRV_DEVICE_NODE *psDeviceNode, -+ IMG_UINT32 ui32CallerID) -+{ -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; -+ SGXMKIF_HOST_CTL *psSGXHostCtl = psDevInfo->psSGXHostCtl; -+ -+#if defined(SYS_SUPPORTS_SGX_IDLE_CALLBACK) -+ if (!psDevInfo->bSGXIdle && -+ ((psSGXHostCtl->ui32InterruptFlags & PVRSRV_USSE_EDM_INTERRUPT_IDLE) != 0)) -+ { -+ psDevInfo->bSGXIdle = IMG_TRUE; -+ SysSGXIdleTransition(psDevInfo->bSGXIdle); -+ } -+ else if (psDevInfo->bSGXIdle && -+ ((psSGXHostCtl->ui32InterruptFlags & PVRSRV_USSE_EDM_INTERRUPT_IDLE) == 0)) -+ { -+ psDevInfo->bSGXIdle = IMG_FALSE; -+ SysSGXIdleTransition(psDevInfo->bSGXIdle); -+ } -+#endif /* SYS_SUPPORTS_SGX_IDLE_CALLBACK */ -+ -+ /* -+ * Quickly check (without lock) if there is an APM event we should handle. -+ * This check fails most of the time so we don't want to incur lock overhead. -+ * Check the flags in the reverse order that microkernel clears them to prevent -+ * us from seeing an inconsistent state. -+ */ -+ if (((psSGXHostCtl->ui32InterruptClearFlags & PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER) == 0) && -+ ((psSGXHostCtl->ui32InterruptFlags & PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER) != 0)) -+ { -+ eError = PVRSRVPowerLock(ui32CallerID, IMG_FALSE); -+ if (eError == PVRSRV_ERROR_RETRY) -+ { -+ return; -+ } -+ else if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SGXTestActivePowerEvent failed to acquire lock - " -+ "ui32CallerID:%d eError:%u", ui32CallerID, eError)); -+ return; -+ } -+ -+ /* -+ * Check again (with lock) if APM event has been cleared or handled. A race -+ * condition may allow multiple threads to pass the quick check. -+ */ -+ if (((psSGXHostCtl->ui32InterruptClearFlags & PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER) != 0) || -+ ((psSGXHostCtl->ui32InterruptFlags & PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER) == 0)) -+ { -+ PVRSRVPowerUnlock(ui32CallerID); -+ return; -+ } -+ -+ /* Microkernel is idle and is requesting to be powered down. */ -+ psSGXHostCtl->ui32InterruptClearFlags |= PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER; -+ -+ /* Suspend pdumping. */ -+ PDUMPSUSPEND(); -+ -+#if defined(SYS_CUSTOM_POWERDOWN) -+ /* -+ Some power down code cannot be executed inside an MISR on -+ some platforms that use mutexes inside the power code. -+ */ -+ eError = SysPowerDownMISR(psDeviceNode, ui32CallerID); -+#else -+ eError = PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex, -+ PVRSRV_DEV_POWER_STATE_OFF); -+ if (eError == PVRSRV_OK) -+ { -+ SGXPostActivePowerEvent(psDeviceNode, ui32CallerID); -+ } -+#endif -+ PVRSRVPowerUnlock(ui32CallerID); -+ -+ /* Resume pdumping */ -+ PDUMPRESUME(); -+ } -+ -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SGXTestActivePowerEvent error:%u", eError)); -+ } -+} -+ -+ -+/****************************************************************************** -+ FUNCTION : SGXAcquireKernelCCBSlot -+ -+ PURPOSE : Attempts to obtain a slot in the Kernel CCB -+ -+ PARAMETERS : psCCB - the CCB -+ -+ RETURNS : Address of space if available, IMG_NULL otherwise -+******************************************************************************/ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(SGXAcquireKernelCCBSlot) -+#endif -+static INLINE SGXMKIF_COMMAND * SGXAcquireKernelCCBSlot(PVRSRV_SGX_CCB_INFO *psCCB) -+{ -+ LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) -+ { -+ if(((*psCCB->pui32WriteOffset + 1) & 255) != *psCCB->pui32ReadOffset) -+ { -+ return &psCCB->psCommands[*psCCB->pui32WriteOffset]; -+ } -+ -+ OSSleepms(1); -+ } END_LOOP_UNTIL_TIMEOUT(); -+ -+ /* Time out on waiting for CCB space */ -+ return IMG_NULL; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function SGXScheduleCCBCommand -+ -+ @Description - Submits a CCB command and kicks the ukernel (without -+ power management) -+ -+ @Input psDevInfo - pointer to device info -+ @Input eCmdType - see SGXMKIF_CMD_* -+ @Input psCommandData - kernel CCB command -+ @Input ui32CallerID - KERNEL_ID or ISR_ID -+ @Input ui32PDumpFlags -+ -+ @Return ui32Error - success or failure -+ -+******************************************************************************/ -+PVRSRV_ERROR SGXScheduleCCBCommand(PVRSRV_DEVICE_NODE *psDeviceNode, -+ SGXMKIF_CMD_TYPE eCmdType, -+ SGXMKIF_COMMAND *psCommandData, -+ IMG_UINT32 ui32CallerID, -+ IMG_UINT32 ui32PDumpFlags, -+ IMG_HANDLE hDevMemContext, -+ IMG_BOOL bLastInScene) -+{ -+ PVRSRV_SGX_CCB_INFO *psKernelCCB; -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ SGXMKIF_COMMAND *psSGXCommand; -+ PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; -+ SGXMKIF_HOST_CTL *psSGXHostCtl = psDevInfo->psSGXHostCtl; -+#if defined(FIX_HW_BRN_31620) -+ IMG_UINT32 ui32CacheMasks[4]; -+ IMG_UINT32 i; -+ MMU_CONTEXT *psMMUContext; -+#endif -+#if defined(PDUMP) -+ IMG_VOID *pvDumpCommand; -+ IMG_BOOL bPDumpIsSuspended = PDumpIsSuspended(); -+#if defined(SUPPORT_PDUMP_MULTI_PROCESS) -+ IMG_BOOL bPDumpActive = _PDumpIsProcessActive(); -+#else -+ IMG_BOOL bPDumpActive = IMG_TRUE; -+#endif -+#else -+ PVR_UNREFERENCED_PARAMETER(ui32CallerID); -+ PVR_UNREFERENCED_PARAMETER(ui32PDumpFlags); -+#endif -+ -+#if defined(FIX_HW_BRN_31620) -+ for(i=0;i<4;i++) -+ { -+ ui32CacheMasks[i] = 0; -+ } -+ -+ psMMUContext = psDevInfo->hKernelMMUContext; -+ psDeviceNode->pfnMMUGetCacheFlushRange(psMMUContext, &ui32CacheMasks[0]); -+ -+ /* Put the apps memory context in the bottom half */ -+ if (hDevMemContext) -+ { -+ BM_CONTEXT *psBMContext = (BM_CONTEXT *) hDevMemContext; -+ -+ psMMUContext = psBMContext->psMMUContext; -+ psDeviceNode->pfnMMUGetCacheFlushRange(psMMUContext, &ui32CacheMasks[2]); -+ } -+ -+ /* If we have an outstanding flush request then set the cachecontrol bit */ -+ if (ui32CacheMasks[0] || ui32CacheMasks[1] || ui32CacheMasks[2] || ui32CacheMasks[3]) -+ { -+ psDevInfo->ui32CacheControl |= SGXMKIF_CC_INVAL_BIF_PD; -+ } -+#endif -+ -+#if defined(FIX_HW_BRN_28889) -+ /* -+ If the data cache and bif cache need invalidating there has been a cleanup -+ request. Therefore, we need to send the invalidate seperately and wait -+ for it to complete. -+ */ -+ if ( (eCmdType != SGXMKIF_CMD_PROCESS_QUEUES) && -+ ((psDevInfo->ui32CacheControl & SGXMKIF_CC_INVAL_DATA) != 0) && -+ ((psDevInfo->ui32CacheControl & (SGXMKIF_CC_INVAL_BIF_PT | SGXMKIF_CC_INVAL_BIF_PD)) != 0)) -+ { -+ #if defined(PDUMP) -+ PVRSRV_KERNEL_MEM_INFO *psSGXHostCtlMemInfo = psDevInfo->psKernelSGXHostCtlMemInfo; -+ #endif -+ SGXMKIF_HOST_CTL *psSGXHostCtl = psDevInfo->psSGXHostCtl; -+ SGXMKIF_COMMAND sCacheCommand = {0}; -+ -+ eError = SGXScheduleCCBCommand(psDeviceNode, -+ SGXMKIF_CMD_PROCESS_QUEUES, -+ &sCacheCommand, -+ ui32CallerID, -+ ui32PDumpFlags, -+ hDevMemContext, -+ bLastInScene); -+ if (eError != PVRSRV_OK) -+ { -+ goto Exit; -+ } -+ -+ /* Wait for the invalidate to happen */ -+ #if !defined(NO_HARDWARE) -+ if(PollForValueKM(&psSGXHostCtl->ui32InvalStatus, -+ PVRSRV_USSE_EDM_BIF_INVAL_COMPLETE, -+ PVRSRV_USSE_EDM_BIF_INVAL_COMPLETE, -+ 2 * MAX_HW_TIME_US, -+ MAX_HW_TIME_US/WAIT_TRY_COUNT, -+ IMG_FALSE) != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SGXScheduleCCBCommand: Wait for uKernel to Invalidate BIF cache failed")); -+ PVR_DBG_BREAK; -+ } -+ #endif -+ -+ #if defined(PDUMP) -+ /* Pdump the poll as well. */ -+ PDUMPCOMMENTWITHFLAGS(0, "Host Control - Poll for BIF cache invalidate request to complete"); -+ PDUMPMEMPOL(psSGXHostCtlMemInfo, -+ offsetof(SGXMKIF_HOST_CTL, ui32InvalStatus), -+ PVRSRV_USSE_EDM_BIF_INVAL_COMPLETE, -+ PVRSRV_USSE_EDM_BIF_INVAL_COMPLETE, -+ PDUMP_POLL_OPERATOR_EQUAL, -+ 0, -+ MAKEUNIQUETAG(psSGXHostCtlMemInfo)); -+ #endif /* PDUMP */ -+ -+ psSGXHostCtl->ui32InvalStatus &= ~(PVRSRV_USSE_EDM_BIF_INVAL_COMPLETE); -+ PDUMPMEM(IMG_NULL, psSGXHostCtlMemInfo, offsetof(SGXMKIF_HOST_CTL, ui32CleanupStatus), sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psSGXHostCtlMemInfo)); -+ } -+#else -+ PVR_UNREFERENCED_PARAMETER(hDevMemContext); -+#endif -+ -+#if defined(FIX_HW_BRN_31620) -+ if ((eCmdType != SGXMKIF_CMD_FLUSHPDCACHE) && (psDevInfo->ui32CacheControl & SGXMKIF_CC_INVAL_BIF_PD)) -+ { -+ SGXMKIF_COMMAND sPDECacheCommand = {0}; -+ IMG_DEV_PHYADDR sDevPAddr; -+ -+ /* Put the kernel info in the top 1/2 of the data */ -+ psMMUContext = psDevInfo->hKernelMMUContext; -+ -+ psDeviceNode->pfnMMUGetPDPhysAddr(psMMUContext, &sDevPAddr); -+ sPDECacheCommand.ui32Data[0] = sDevPAddr.uiAddr | 1; -+ sPDECacheCommand.ui32Data[1] = ui32CacheMasks[0]; -+ sPDECacheCommand.ui32Data[2] = ui32CacheMasks[1]; -+ -+ /* Put the apps memory context in the bottom half */ -+ if (hDevMemContext) -+ { -+ BM_CONTEXT *psBMContext = (BM_CONTEXT *) hDevMemContext; -+ -+ psMMUContext = psBMContext->psMMUContext; -+ -+ psDeviceNode->pfnMMUGetPDPhysAddr(psMMUContext, &sDevPAddr); -+ /* Or in 1 to the lsb to show we have a valid context */ -+ sPDECacheCommand.ui32Data[3] = sDevPAddr.uiAddr | 1; -+ sPDECacheCommand.ui32Data[4] = ui32CacheMasks[2]; -+ sPDECacheCommand.ui32Data[5] = ui32CacheMasks[3]; -+ } -+ -+ /* Only do a kick if there is any update */ -+ if (sPDECacheCommand.ui32Data[1] | sPDECacheCommand.ui32Data[2] | sPDECacheCommand.ui32Data[4] | -+ sPDECacheCommand.ui32Data[5]) -+ { -+ eError = SGXScheduleCCBCommand(psDeviceNode, -+ SGXMKIF_CMD_FLUSHPDCACHE, -+ &sPDECacheCommand, -+ ui32CallerID, -+ ui32PDumpFlags, -+ hDevMemContext, -+ bLastInScene); -+ if (eError != PVRSRV_OK) -+ { -+ goto Exit; -+ } -+ } -+ } -+#endif -+ psKernelCCB = psDevInfo->psKernelCCBInfo; -+ -+ psSGXCommand = SGXAcquireKernelCCBSlot(psKernelCCB); -+ -+ /* Wait for CCB space timed out */ -+ if(!psSGXCommand) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SGXScheduleCCBCommand: Wait for CCB space timed out")) ; -+ eError = PVRSRV_ERROR_TIMEOUT; -+ goto Exit; -+ } -+ -+ /* embed cache control word */ -+ psCommandData->ui32CacheControl = psDevInfo->ui32CacheControl; -+ -+#if defined(PDUMP) -+ /* Accumulate any cache invalidates that may have happened */ -+ psDevInfo->sPDContext.ui32CacheControl |= psDevInfo->ui32CacheControl; -+#endif -+ -+ /* and clear it */ -+ psDevInfo->ui32CacheControl = 0; -+ -+ /* Copy command data over */ -+ *psSGXCommand = *psCommandData; -+ -+ if (eCmdType >= SGXMKIF_CMD_MAX) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SGXScheduleCCBCommand: Unknown command type: %d", eCmdType)) ; -+ eError = PVRSRV_ERROR_INVALID_CCB_COMMAND; -+ goto Exit; -+ } -+ -+ if (eCmdType == SGXMKIF_CMD_2D || -+ eCmdType == SGXMKIF_CMD_TRANSFER || -+ ((eCmdType == SGXMKIF_CMD_TA) && bLastInScene)) -+ { -+ SYS_DATA *psSysData; -+ -+ /* CPU cache clean control */ -+ SysAcquireData(&psSysData); -+ -+ if(psSysData->ePendingCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_FLUSH) -+ { -+ OSFlushCPUCacheKM(); -+ } -+ else if(psSysData->ePendingCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_CLEAN) -+ { -+ OSCleanCPUCacheKM(); -+ } -+ -+ /* Clear the pending op */ -+ psSysData->ePendingCacheOpType = PVRSRV_MISC_INFO_CPUCACHEOP_NONE; -+ } -+ -+ PVR_ASSERT(eCmdType < SGXMKIF_CMD_MAX); -+ psSGXCommand->ui32ServiceAddress = psDevInfo->aui32HostKickAddr[eCmdType]; /* PRQA S 3689 */ /* misuse of enums for bounds checking */ -+ -+#if defined(PDUMP) -+ if ((ui32CallerID != ISR_ID) && (bPDumpIsSuspended == IMG_FALSE) && -+ (bPDumpActive == IMG_TRUE) ) -+ { -+ /* Poll for space in the CCB. */ -+ PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Poll for space in the Kernel CCB\r\n"); -+ PDUMPMEMPOL(psKernelCCB->psCCBCtlMemInfo, -+ offsetof(PVRSRV_SGX_CCB_CTL, ui32ReadOffset), -+ (psKernelCCB->ui32CCBDumpWOff + 1) & 0xff, -+ 0xff, -+ PDUMP_POLL_OPERATOR_NOTEQUAL, -+ ui32PDumpFlags, -+ MAKEUNIQUETAG(psKernelCCB->psCCBCtlMemInfo)); -+ -+ PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Kernel CCB command (type == %d)\r\n", eCmdType); -+ pvDumpCommand = (IMG_VOID *)((IMG_UINT8 *)psKernelCCB->psCCBMemInfo->pvLinAddrKM + (*psKernelCCB->pui32WriteOffset * sizeof(SGXMKIF_COMMAND))); -+ -+ PDUMPMEM(pvDumpCommand, -+ psKernelCCB->psCCBMemInfo, -+ psKernelCCB->ui32CCBDumpWOff * sizeof(SGXMKIF_COMMAND), -+ sizeof(SGXMKIF_COMMAND), -+ ui32PDumpFlags, -+ MAKEUNIQUETAG(psKernelCCB->psCCBMemInfo)); -+ -+ /* Overwrite cache control with pdump shadow */ -+ PDUMPMEM(&psDevInfo->sPDContext.ui32CacheControl, -+ psKernelCCB->psCCBMemInfo, -+ psKernelCCB->ui32CCBDumpWOff * sizeof(SGXMKIF_COMMAND) + -+ offsetof(SGXMKIF_COMMAND, ui32CacheControl), -+ sizeof(IMG_UINT32), -+ ui32PDumpFlags, -+ MAKEUNIQUETAG(psKernelCCB->psCCBMemInfo)); -+ -+ if (PDumpIsCaptureFrameKM() -+ || ((ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0)) -+ { -+ /* Clear cache invalidate shadow */ -+ psDevInfo->sPDContext.ui32CacheControl = 0; -+ } -+ } -+#endif -+ -+#if defined(FIX_HW_BRN_26620) && defined(SGX_FEATURE_SYSTEM_CACHE) && !defined(SGX_BYPASS_SYSTEM_CACHE) -+ /* Make sure the previous command has been read before send the next one */ -+ eError = PollForValueKM (psKernelCCB->pui32ReadOffset, -+ *psKernelCCB->pui32WriteOffset, -+ 0xFF, -+ MAX_HW_TIME_US, -+ MAX_HW_TIME_US/WAIT_TRY_COUNT, -+ IMG_FALSE); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SGXScheduleCCBCommand: Timeout waiting for previous command to be read")) ; -+ eError = PVRSRV_ERROR_TIMEOUT; -+ goto Exit; -+ } -+#endif -+ -+ /* -+ Increment the write offset -+ */ -+ *psKernelCCB->pui32WriteOffset = (*psKernelCCB->pui32WriteOffset + 1) & 255; -+ -+#if defined(PDUMP) -+ if ((ui32CallerID != ISR_ID) && (bPDumpIsSuspended == IMG_FALSE) && -+ (bPDumpActive == IMG_TRUE) ) -+ { -+ #if defined(FIX_HW_BRN_26620) && defined(SGX_FEATURE_SYSTEM_CACHE) && !defined(SGX_BYPASS_SYSTEM_CACHE) -+ PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Poll for previous Kernel CCB CMD to be read\r\n"); -+ PDUMPMEMPOL(psKernelCCB->psCCBCtlMemInfo, -+ offsetof(PVRSRV_SGX_CCB_CTL, ui32ReadOffset), -+ (psKernelCCB->ui32CCBDumpWOff), -+ 0xFF, -+ PDUMP_POLL_OPERATOR_EQUAL, -+ ui32PDumpFlags, -+ MAKEUNIQUETAG(psKernelCCB->psCCBCtlMemInfo)); -+ #endif -+ -+ if (PDumpIsCaptureFrameKM() -+ || ((ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0)) -+ { -+ psKernelCCB->ui32CCBDumpWOff = (psKernelCCB->ui32CCBDumpWOff + 1) & 0xFF; -+ psDevInfo->ui32KernelCCBEventKickerDumpVal = (psDevInfo->ui32KernelCCBEventKickerDumpVal + 1) & 0xFF; -+ } -+ -+ PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Kernel CCB write offset\r\n"); -+ PDUMPMEM(&psKernelCCB->ui32CCBDumpWOff, -+ psKernelCCB->psCCBCtlMemInfo, -+ offsetof(PVRSRV_SGX_CCB_CTL, ui32WriteOffset), -+ sizeof(IMG_UINT32), -+ ui32PDumpFlags, -+ MAKEUNIQUETAG(psKernelCCB->psCCBCtlMemInfo)); -+ PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Kernel CCB event kicker\r\n"); -+ PDUMPMEM(&psDevInfo->ui32KernelCCBEventKickerDumpVal, -+ psDevInfo->psKernelCCBEventKickerMemInfo, -+ 0, -+ sizeof(IMG_UINT32), -+ ui32PDumpFlags, -+ MAKEUNIQUETAG(psDevInfo->psKernelCCBEventKickerMemInfo)); -+ PDUMPCOMMENTWITHFLAGS(ui32PDumpFlags, "Kick the SGX microkernel\r\n"); -+ #if defined(FIX_HW_BRN_26620) && defined(SGX_FEATURE_SYSTEM_CACHE) && !defined(SGX_BYPASS_SYSTEM_CACHE) -+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK2, 0), EUR_CR_EVENT_KICK2_NOW_MASK, ui32PDumpFlags); -+ #else -+ PDUMPREGWITHFLAGS(SGX_PDUMPREG_NAME, SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK, 0), EUR_CR_EVENT_KICK_NOW_MASK, ui32PDumpFlags); -+ #endif -+ } -+#endif -+ -+ *psDevInfo->pui32KernelCCBEventKicker = (*psDevInfo->pui32KernelCCBEventKicker + 1) & 0xFF; -+ -+ /* -+ * New command submission is considered a proper handling of any pending APM -+ * event, so mark it as handled to prevent other host threads from taking -+ * action. -+ */ -+ psSGXHostCtl->ui32InterruptClearFlags |= PVRSRV_USSE_EDM_INTERRUPT_ACTIVE_POWER; -+ -+ OSWriteMemoryBarrier(); -+ -+ /* Order is importent for post processor! */ -+ PVR_TTRACE_UI32(PVRSRV_TRACE_GROUP_MKSYNC, PVRSRV_TRACE_CLASS_NONE, -+ MKSYNC_TOKEN_KERNEL_CCB_OFFSET, *psKernelCCB->pui32WriteOffset); -+ PVR_TTRACE_UI32(PVRSRV_TRACE_GROUP_MKSYNC, PVRSRV_TRACE_CLASS_NONE, -+ MKSYNC_TOKEN_CORE_CLK, psDevInfo->ui32CoreClockSpeed); -+ PVR_TTRACE_UI32(PVRSRV_TRACE_GROUP_MKSYNC, PVRSRV_TRACE_CLASS_NONE, -+ MKSYNC_TOKEN_UKERNEL_CLK, psDevInfo->ui32uKernelTimerClock); -+ -+ -+#if defined(FIX_HW_BRN_26620) && defined(SGX_FEATURE_SYSTEM_CACHE) && !defined(SGX_BYPASS_SYSTEM_CACHE) -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, -+ SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK2, 0), -+ EUR_CR_EVENT_KICK2_NOW_MASK); -+#else -+ OSWriteHWReg(psDevInfo->pvRegsBaseKM, -+ SGX_MP_CORE_SELECT(EUR_CR_EVENT_KICK, 0), -+ EUR_CR_EVENT_KICK_NOW_MASK); -+#endif -+ -+ OSMemoryBarrier(); -+ -+#if defined(NO_HARDWARE) -+ /* Increment read offset */ -+ *psKernelCCB->pui32ReadOffset = (*psKernelCCB->pui32ReadOffset + 1) & 255; -+#endif -+ -+ ui64KickCount++; -+Exit: -+ return eError; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SGXScheduleCCBCommandKM -+ -+ @Description - Submits a CCB command and kicks the ukernel -+ -+ @Input psDeviceNode - pointer to SGX device node -+ @Input eCmdType - see SGXMKIF_CMD_* -+ @Input psCommandData - kernel CCB command -+ @Input ui32CallerID - KERNEL_ID or ISR_ID -+ @Input ui32PDumpFlags -+ -+ @Return ui32Error - success or failure -+ -+******************************************************************************/ -+PVRSRV_ERROR SGXScheduleCCBCommandKM(PVRSRV_DEVICE_NODE *psDeviceNode, -+ SGXMKIF_CMD_TYPE eCmdType, -+ SGXMKIF_COMMAND *psCommandData, -+ IMG_UINT32 ui32CallerID, -+ IMG_UINT32 ui32PDumpFlags, -+ IMG_HANDLE hDevMemContext, -+ IMG_BOOL bLastInScene) -+{ -+ PVRSRV_ERROR eError; -+ -+ eError = PVRSRVPowerLock(ui32CallerID, IMG_FALSE); -+ if (eError == PVRSRV_ERROR_RETRY) -+ { -+ if (ui32CallerID == ISR_ID) -+ { -+ SYS_DATA *psSysData; -+ -+ /* -+ ISR failed to acquire lock so it must be held by a kernel thread. -+ Bring up and kick SGX if necessary when the lock is available. -+ */ -+ psDeviceNode->bReProcessDeviceCommandComplete = IMG_TRUE; -+ eError = PVRSRV_OK; -+ -+ SysAcquireData(&psSysData); -+ OSScheduleMISR(psSysData); -+ } -+ else -+ { -+ /* -+ Return to srvclient for retry. -+ */ -+ } -+ -+ return eError; -+ } -+ else if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SGXScheduleCCBCommandKM failed to acquire lock - " -+ "ui32CallerID:%d eError:%u", ui32CallerID, eError)); -+ return eError; -+ } -+ -+ /* Note that a power-up has been dumped in the init phase. */ -+ PDUMPSUSPEND(); -+ -+ /* Ensure that SGX is powered up before kicking the ukernel. */ -+ eError = PVRSRVSetDevicePowerStateKM(psDeviceNode->sDevId.ui32DeviceIndex, -+ PVRSRV_DEV_POWER_STATE_ON); -+ -+ PDUMPRESUME(); -+ -+ if (eError == PVRSRV_OK) -+ { -+ psDeviceNode->bReProcessDeviceCommandComplete = IMG_FALSE; -+ } -+ else -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SGXScheduleCCBCommandKM failed to acquire lock - " -+ "ui32CallerID:%d eError:%u", ui32CallerID, eError)); -+ return eError; -+ } -+ -+ eError = SGXScheduleCCBCommand(psDeviceNode, eCmdType, psCommandData, ui32CallerID, ui32PDumpFlags, hDevMemContext, bLastInScene); -+ -+ PVRSRVPowerUnlock(ui32CallerID); -+ return eError; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SGXScheduleProcessQueuesKM -+ -+ @Description - Software command complete handler -+ -+ @Input psDeviceNode - SGX device node -+ -+******************************************************************************/ -+PVRSRV_ERROR SGXScheduleProcessQueuesKM(PVRSRV_DEVICE_NODE *psDeviceNode) -+{ -+ PVRSRV_ERROR eError; -+ PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; -+ SGXMKIF_HOST_CTL *psHostCtl = psDevInfo->psKernelSGXHostCtlMemInfo->pvLinAddrKM; -+ IMG_UINT32 ui32PowerStatus; -+ SGXMKIF_COMMAND sCommand = {0}; -+ -+ ui32PowerStatus = psHostCtl->ui32PowerStatus; -+ if ((ui32PowerStatus & PVRSRV_USSE_EDM_POWMAN_NO_WORK) != 0) -+ { -+ /* The ukernel has no work to do so don't waste power. */ -+ return PVRSRV_OK; -+ } -+ -+ eError = SGXScheduleCCBCommandKM(psDeviceNode, SGXMKIF_CMD_PROCESS_QUEUES, &sCommand, ISR_ID, 0, IMG_NULL, IMG_FALSE); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SGXScheduleProcessQueuesKM failed to schedule CCB command: %u", eError)); -+ return eError; -+ } -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SGXIsDevicePowered -+ -+ @Description -+ -+ Whether the device is powered, for the purposes of lockup detection. -+ -+ @Input psDeviceNode - pointer to device node -+ -+ @Return IMG_BOOL : Whether device is powered -+ -+******************************************************************************/ -+IMG_BOOL SGXIsDevicePowered(PVRSRV_DEVICE_NODE *psDeviceNode) -+{ -+ return PVRSRVIsDevicePowered(psDeviceNode->sDevId.ui32DeviceIndex); -+} -+ -+/*! -+******************************************************************************* -+ -+ @Function SGXGetInternalDevInfoKM -+ -+ @Description -+ Gets device information that is not intended to be passed -+ on beyond the srvclient libs. -+ -+ @Input hDevCookie -+ -+ @Output psSGXInternalDevInfo -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR SGXGetInternalDevInfoKM(IMG_HANDLE hDevCookie, -+ SGX_INTERNAL_DEVINFO *psSGXInternalDevInfo) -+{ -+ PVRSRV_SGXDEV_INFO *psDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice; -+ -+ psSGXInternalDevInfo->ui32Flags = psDevInfo->ui32Flags; -+ psSGXInternalDevInfo->bForcePTOff = (IMG_BOOL)psDevInfo->bForcePTOff; -+ -+ /* This should be patched up by OS bridge code */ -+ psSGXInternalDevInfo->hHostCtlKernelMemInfoHandle = -+ (IMG_HANDLE)psDevInfo->psKernelSGXHostCtlMemInfo; -+ -+ return PVRSRV_OK; -+} -+ -+ -+/***************************************************************************** -+ FUNCTION : SGXCleanupRequest -+ -+ PURPOSE : Wait for the microkernel to clean up its references to either a -+ render context or render target. -+ -+ PARAMETERS : psDeviceNode - SGX device node -+ psHWDataDevVAddr - Device Address of the resource -+ ui32CleanupType - PVRSRV_CLEANUPCMD_* -+ bForceCleanup - Skips sync polling -+ -+ RETURNS : error status -+*****************************************************************************/ -+PVRSRV_ERROR SGXCleanupRequest(PVRSRV_DEVICE_NODE *psDeviceNode, -+ IMG_DEV_VIRTADDR *psHWDataDevVAddr, -+ IMG_UINT32 ui32CleanupType, -+ IMG_BOOL bForceCleanup) -+{ -+ PVRSRV_ERROR eError; -+ PVRSRV_SGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; -+ PVRSRV_KERNEL_MEM_INFO *psHostCtlMemInfo = psDevInfo->psKernelSGXHostCtlMemInfo; -+ SGXMKIF_HOST_CTL *psHostCtl = psHostCtlMemInfo->pvLinAddrKM; -+ -+ SGXMKIF_COMMAND sCommand = {0}; -+ -+ -+ if (bForceCleanup != FORCE_CLEANUP) -+ { -+ sCommand.ui32Data[0] = ui32CleanupType; -+ sCommand.ui32Data[1] = (psHWDataDevVAddr == IMG_NULL) ? 0 : psHWDataDevVAddr->uiAddr; -+ PDUMPCOMMENTWITHFLAGS(0, "Request ukernel resource clean-up, Type %u, Data 0x%X", sCommand.ui32Data[0], sCommand.ui32Data[1]); -+ -+ eError = SGXScheduleCCBCommandKM(psDeviceNode, SGXMKIF_CMD_CLEANUP, &sCommand, KERNEL_ID, 0, IMG_NULL, IMG_FALSE); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SGXCleanupRequest: Failed to submit clean-up command")); -+ SGXDumpDebugInfo(psDevInfo, IMG_FALSE); -+ PVR_DBG_BREAK; -+ return eError; -+ } -+ -+ /* Wait for the uKernel process the cleanup request */ -+ #if !defined(NO_HARDWARE) -+ if(PollForValueKM(&psHostCtl->ui32CleanupStatus, -+ PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE, -+ PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE, -+ 10 * MAX_HW_TIME_US, -+ 1000, -+ IMG_TRUE) != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SGXCleanupRequest: Wait for uKernel to clean up (%u) failed", ui32CleanupType)); -+ eError = PVRSRV_ERROR_TIMEOUT; -+ SGXDumpDebugInfo(psDevInfo, IMG_FALSE); -+ PVR_DBG_BREAK; -+ } -+ #endif -+ -+ #if defined(PDUMP) -+ /* -+ Pdump the poll as well. -+ Note: -+ We don't expect the cleanup to report busy as the client should have -+ ensured the the resource has been finished with before requesting -+ it's cleanup. This isn't true of the abnormal termination case but -+ we don't expect to PDump that. Unless/until PDump has flow control -+ there isn't anything else we can do. -+ */ -+ PDUMPCOMMENTWITHFLAGS(0, "Host Control - Poll for clean-up request to complete"); -+ PDUMPMEMPOL(psHostCtlMemInfo, -+ offsetof(SGXMKIF_HOST_CTL, ui32CleanupStatus), -+ PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE | PVRSRV_USSE_EDM_CLEANUPCMD_DONE, -+ PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE | PVRSRV_USSE_EDM_CLEANUPCMD_DONE, -+ PDUMP_POLL_OPERATOR_EQUAL, -+ 0, -+ MAKEUNIQUETAG(psHostCtlMemInfo)); -+ #endif /* PDUMP */ -+ -+ if (eError != PVRSRV_OK) -+ { -+ return eError; -+ } -+ } -+ -+ if (psHostCtl->ui32CleanupStatus & PVRSRV_USSE_EDM_CLEANUPCMD_BUSY) -+ { -+ /* Only one flag should be set */ -+ PVR_ASSERT((psHostCtl->ui32CleanupStatus & PVRSRV_USSE_EDM_CLEANUPCMD_DONE) == 0); -+ eError = PVRSRV_ERROR_RETRY; -+ psHostCtl->ui32CleanupStatus &= ~(PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE | PVRSRV_USSE_EDM_CLEANUPCMD_BUSY); -+ } -+ else -+ { -+ eError = PVRSRV_OK; -+ psHostCtl->ui32CleanupStatus &= ~(PVRSRV_USSE_EDM_CLEANUPCMD_COMPLETE | PVRSRV_USSE_EDM_CLEANUPCMD_DONE); -+ } -+ -+ PDUMPMEM(IMG_NULL, psHostCtlMemInfo, offsetof(SGXMKIF_HOST_CTL, ui32CleanupStatus), sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psHostCtlMemInfo)); -+ -+ /* Request the cache invalidate */ -+#if defined(SGX_FEATURE_SYSTEM_CACHE) -+ psDevInfo->ui32CacheControl |= (SGXMKIF_CC_INVAL_BIF_SL | SGXMKIF_CC_INVAL_DATA); -+#else -+ psDevInfo->ui32CacheControl |= SGXMKIF_CC_INVAL_DATA; -+#endif -+ return eError; -+} -+ -+ -+typedef struct _SGX_HW_RENDER_CONTEXT_CLEANUP_ -+{ -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+ PVRSRV_KERNEL_MEM_INFO *psHWRenderContextMemInfo; -+ IMG_HANDLE hBlockAlloc; -+ PRESMAN_ITEM psResItem; -+ IMG_BOOL bCleanupTimerRunning; -+ IMG_PVOID pvTimeData; -+} SGX_HW_RENDER_CONTEXT_CLEANUP; -+ -+ -+static PVRSRV_ERROR SGXCleanupHWRenderContextCallback(IMG_PVOID pvParam, -+ IMG_UINT32 ui32Param, -+ IMG_BOOL bForceCleanup) -+{ -+ PVRSRV_ERROR eError; -+ SGX_HW_RENDER_CONTEXT_CLEANUP *psCleanup = pvParam; -+ -+ PVR_UNREFERENCED_PARAMETER(ui32Param); -+ -+ eError = SGXCleanupRequest(psCleanup->psDeviceNode, -+ &psCleanup->psHWRenderContextMemInfo->sDevVAddr, -+ PVRSRV_CLEANUPCMD_RC, -+ bForceCleanup); -+ -+ if (eError == PVRSRV_ERROR_RETRY) -+ { -+ if (!psCleanup->bCleanupTimerRunning) -+ { -+ OSTimeCreateWithUSOffset(&psCleanup->pvTimeData, MAX_CLEANUP_TIME_US); -+ psCleanup->bCleanupTimerRunning = IMG_TRUE; -+ } -+ else -+ { -+ if (OSTimeHasTimePassed(psCleanup->pvTimeData)) -+ { -+ eError = PVRSRV_ERROR_TIMEOUT_POLLING_FOR_VALUE; -+ psCleanup->bCleanupTimerRunning = IMG_FALSE; -+ OSTimeDestroy(psCleanup->pvTimeData); -+ } -+ } -+ } -+ else -+ { -+ if (psCleanup->bCleanupTimerRunning) -+ { -+ OSTimeDestroy(psCleanup->pvTimeData); -+ } -+ } -+ -+ if (eError != PVRSRV_ERROR_RETRY) -+ { -+ /* Free the Device Mem allocated */ -+ PVRSRVFreeDeviceMemKM(psCleanup->psDeviceNode, -+ psCleanup->psHWRenderContextMemInfo); -+ -+ /* Finally, free the cleanup structure itself */ -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(SGX_HW_RENDER_CONTEXT_CLEANUP), -+ psCleanup, -+ psCleanup->hBlockAlloc); -+ /*not nulling pointer, copy on stack*/ -+ } -+ -+ return eError; -+} -+ -+typedef struct _SGX_HW_TRANSFER_CONTEXT_CLEANUP_ -+{ -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+ PVRSRV_KERNEL_MEM_INFO *psHWTransferContextMemInfo; -+ IMG_HANDLE hBlockAlloc; -+ PRESMAN_ITEM psResItem; -+ IMG_BOOL bCleanupTimerRunning; -+ IMG_PVOID pvTimeData; -+} SGX_HW_TRANSFER_CONTEXT_CLEANUP; -+ -+ -+static PVRSRV_ERROR SGXCleanupHWTransferContextCallback(IMG_PVOID pvParam, -+ IMG_UINT32 ui32Param, -+ IMG_BOOL bForceCleanup) -+{ -+ PVRSRV_ERROR eError; -+ SGX_HW_TRANSFER_CONTEXT_CLEANUP *psCleanup = (SGX_HW_TRANSFER_CONTEXT_CLEANUP *)pvParam; -+ -+ PVR_UNREFERENCED_PARAMETER(ui32Param); -+ -+ eError = SGXCleanupRequest(psCleanup->psDeviceNode, -+ &psCleanup->psHWTransferContextMemInfo->sDevVAddr, -+ PVRSRV_CLEANUPCMD_TC, -+ bForceCleanup); -+ -+ if (eError == PVRSRV_ERROR_RETRY) -+ { -+ if (!psCleanup->bCleanupTimerRunning) -+ { -+ OSTimeCreateWithUSOffset(&psCleanup->pvTimeData, MAX_CLEANUP_TIME_US); -+ psCleanup->bCleanupTimerRunning = IMG_TRUE; -+ } -+ else -+ { -+ if (OSTimeHasTimePassed(psCleanup->pvTimeData)) -+ { -+ eError = PVRSRV_ERROR_TIMEOUT_POLLING_FOR_VALUE; -+ psCleanup->bCleanupTimerRunning = IMG_FALSE; -+ OSTimeDestroy(psCleanup->pvTimeData); -+ } -+ } -+ } -+ else -+ { -+ if (psCleanup->bCleanupTimerRunning) -+ { -+ OSTimeDestroy(psCleanup->pvTimeData); -+ } -+ } -+ -+ if (eError != PVRSRV_ERROR_RETRY) -+ { -+ /* Free the Device Mem allocated */ -+ PVRSRVFreeDeviceMemKM(psCleanup->psDeviceNode, -+ psCleanup->psHWTransferContextMemInfo); -+ -+ /* Finally, free the cleanup structure itself */ -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(SGX_HW_TRANSFER_CONTEXT_CLEANUP), -+ psCleanup, -+ psCleanup->hBlockAlloc); -+ /*not nulling pointer, copy on stack*/ -+ } -+ -+ return eError; -+} -+ -+IMG_EXPORT -+IMG_HANDLE SGXRegisterHWRenderContextKM(IMG_HANDLE hDeviceNode, -+ IMG_CPU_VIRTADDR *psHWRenderContextCpuVAddr, -+ IMG_UINT32 ui32HWRenderContextSize, -+ IMG_UINT32 ui32OffsetToPDDevPAddr, -+ IMG_HANDLE hDevMemContext, -+ IMG_DEV_VIRTADDR *psHWRenderContextDevVAddr, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ PVRSRV_ERROR eError; -+ IMG_HANDLE hBlockAlloc; -+ SGX_HW_RENDER_CONTEXT_CLEANUP *psCleanup; -+ PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)hDeviceNode; -+ DEVICE_MEMORY_INFO *psDevMemoryInfo; -+ DEVICE_MEMORY_HEAP_INFO *psHeapInfo; -+ IMG_HANDLE hDevMemContextInt; -+ MMU_CONTEXT *psMMUContext; -+ IMG_DEV_PHYADDR sPDDevPAddr; -+ int iPtrByte; -+ IMG_UINT8 *pSrc; -+ IMG_UINT8 *pDst; -+ PRESMAN_ITEM psResItem; -+ IMG_UINT32 ui32PDDevPAddrInDirListFormat; -+ -+ eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(SGX_HW_RENDER_CONTEXT_CLEANUP), -+ (IMG_VOID **)&psCleanup, -+ &hBlockAlloc, -+ "SGX Hardware Render Context Cleanup"); -+ -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWRenderContextKM: Couldn't allocate memory for SGX_HW_RENDER_CONTEXT_CLEANUP structure")); -+ goto exit0; -+ } -+ -+ psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo; -+ psHeapInfo = &psDevMemoryInfo->psDeviceMemoryHeap[SGX_KERNEL_DATA_HEAP_ID]; -+ -+ eError = PVRSRVAllocDeviceMemKM(hDeviceNode, -+ psPerProc, -+ psHeapInfo->hDevMemHeap, -+ PVRSRV_MEM_READ | PVRSRV_MEM_WRITE -+ | PVRSRV_MEM_NO_SYNCOBJ | PVRSRV_MEM_EDM_PROTECT -+ | PVRSRV_MEM_CACHE_CONSISTENT, -+ ui32HWRenderContextSize, -+ 32, -+ IMG_NULL, -+ 0, -+ 0,0,0,IMG_NULL, /* No sparse mapping data */ -+ &psCleanup->psHWRenderContextMemInfo, -+ "HW Render Context"); -+ -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWRenderContextKM: Couldn't allocate device memory for HW Render Context")); -+ goto exit1; -+ } -+ -+ eError = OSCopyFromUser(psPerProc, -+ psCleanup->psHWRenderContextMemInfo->pvLinAddrKM, -+ psHWRenderContextCpuVAddr, -+ ui32HWRenderContextSize); -+ -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWRenderContextKM: Couldn't copy user-mode copy of HWContext into device memory")); -+ goto exit2; -+ } -+ -+ /* Pass the DevVAddr of the new context back up through the bridge */ -+ psHWRenderContextDevVAddr->uiAddr = psCleanup->psHWRenderContextMemInfo->sDevVAddr.uiAddr; -+ -+ /* Retrieve the PDDevPAddr */ -+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDevMemContextInt, -+ hDevMemContext, -+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT); -+ -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWRenderContextKM: Can't lookup DevMem Context")); -+ goto exit2; -+ } -+ -+ psMMUContext = BM_GetMMUContextFromMemContext(hDevMemContextInt); -+ sPDDevPAddr = psDeviceNode->pfnMMUGetPDDevPAddr(psMMUContext); -+ -+ /* -+ The PDDevPAddr needs to be shifted-down, as the uKernel expects it in the -+ format it will be inserted into the DirList registers in. -+ */ -+ ui32PDDevPAddrInDirListFormat = (IMG_UINT32)(sPDDevPAddr.uiAddr >> SGX_MMU_PTE_ADDR_ALIGNSHIFT); -+ -+ /* -+ patch-in the Page-Directory Device-Physical address. Note that this is -+ copied-in one byte at a time, as we have no guarantee that the usermode- -+ provided ui32OffsetToPDDevPAddr is a validly-aligned address for the -+ current CPU architecture. -+ */ -+ pSrc = (IMG_UINT8 *)&ui32PDDevPAddrInDirListFormat; -+ pDst = (IMG_UINT8 *)psCleanup->psHWRenderContextMemInfo->pvLinAddrKM; -+ pDst += ui32OffsetToPDDevPAddr; -+ -+ for (iPtrByte = 0; iPtrByte < sizeof(ui32PDDevPAddrInDirListFormat); iPtrByte++) -+ { -+ pDst[iPtrByte] = pSrc[iPtrByte]; -+ } -+ -+#if defined(PDUMP) -+ /* PDUMP the HW context */ -+ PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "HW Render context struct"); -+ -+ PDUMPMEM( -+ IMG_NULL, -+ psCleanup->psHWRenderContextMemInfo, -+ 0, -+ ui32HWRenderContextSize, -+ PDUMP_FLAGS_CONTINUOUS, -+ MAKEUNIQUETAG(psCleanup->psHWRenderContextMemInfo)); -+ -+ /* PDUMP the PDDevPAddr */ -+ PDUMPCOMMENT("Page directory address in HW render context"); -+ PDUMPPDDEVPADDR( -+ psCleanup->psHWRenderContextMemInfo, -+ ui32OffsetToPDDevPAddr, -+ sPDDevPAddr, -+ MAKEUNIQUETAG(psCleanup->psHWRenderContextMemInfo), -+ PDUMP_PD_UNIQUETAG); -+#endif -+ -+ psCleanup->hBlockAlloc = hBlockAlloc; -+ psCleanup->psDeviceNode = psDeviceNode; -+ psCleanup->bCleanupTimerRunning = IMG_FALSE; -+ -+ psResItem = ResManRegisterRes(psPerProc->hResManContext, -+ RESMAN_TYPE_HW_RENDER_CONTEXT, -+ (IMG_VOID *)psCleanup, -+ 0, -+ &SGXCleanupHWRenderContextCallback); -+ -+ if (psResItem == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWRenderContextKM: ResManRegisterRes failed")); -+ goto exit2; -+ } -+ -+ psCleanup->psResItem = psResItem; -+ -+ return (IMG_HANDLE)psCleanup; -+ -+/* Error exit paths */ -+exit2: -+ PVRSRVFreeDeviceMemKM(hDeviceNode, -+ psCleanup->psHWRenderContextMemInfo); -+exit1: -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(SGX_HW_RENDER_CONTEXT_CLEANUP), -+ psCleanup, -+ psCleanup->hBlockAlloc); -+ /*not nulling pointer, out of scope*/ -+exit0: -+ return IMG_NULL; -+} -+ -+IMG_EXPORT -+PVRSRV_ERROR SGXUnregisterHWRenderContextKM(IMG_HANDLE hHWRenderContext, IMG_BOOL bForceCleanup) -+{ -+ PVRSRV_ERROR eError; -+ SGX_HW_RENDER_CONTEXT_CLEANUP *psCleanup; -+ -+ PVR_ASSERT(hHWRenderContext != IMG_NULL); -+ -+ psCleanup = (SGX_HW_RENDER_CONTEXT_CLEANUP *)hHWRenderContext; -+ -+ if (psCleanup == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SGXUnregisterHWRenderContextKM: invalid parameter")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ eError = ResManFreeResByPtr(psCleanup->psResItem, bForceCleanup); -+ -+ return eError; -+} -+ -+ -+IMG_EXPORT -+IMG_HANDLE SGXRegisterHWTransferContextKM(IMG_HANDLE hDeviceNode, -+ IMG_CPU_VIRTADDR *psHWTransferContextCpuVAddr, -+ IMG_UINT32 ui32HWTransferContextSize, -+ IMG_UINT32 ui32OffsetToPDDevPAddr, -+ IMG_HANDLE hDevMemContext, -+ IMG_DEV_VIRTADDR *psHWTransferContextDevVAddr, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ PVRSRV_ERROR eError; -+ IMG_HANDLE hBlockAlloc; -+ SGX_HW_TRANSFER_CONTEXT_CLEANUP *psCleanup; -+ PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)hDeviceNode; -+ DEVICE_MEMORY_INFO *psDevMemoryInfo; -+ DEVICE_MEMORY_HEAP_INFO *psHeapInfo; -+ IMG_HANDLE hDevMemContextInt; -+ MMU_CONTEXT *psMMUContext; -+ IMG_DEV_PHYADDR sPDDevPAddr; -+ int iPtrByte; -+ IMG_UINT8 *pSrc; -+ IMG_UINT8 *pDst; -+ PRESMAN_ITEM psResItem; -+ IMG_UINT32 ui32PDDevPAddrInDirListFormat; -+ -+ eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(SGX_HW_TRANSFER_CONTEXT_CLEANUP), -+ (IMG_VOID **)&psCleanup, -+ &hBlockAlloc, -+ "SGX Hardware Transfer Context Cleanup"); -+ -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWTransferContextKM: Couldn't allocate memory for SGX_HW_TRANSFER_CONTEXT_CLEANUP structure")); -+ goto exit0; -+ } -+ -+ psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo; -+ psHeapInfo = &psDevMemoryInfo->psDeviceMemoryHeap[SGX_KERNEL_DATA_HEAP_ID]; -+ -+ PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "Allocate HW Transfer context"); -+ eError = PVRSRVAllocDeviceMemKM(hDeviceNode, -+ psPerProc, -+ psHeapInfo->hDevMemHeap, -+ PVRSRV_MEM_READ | PVRSRV_MEM_WRITE -+ | PVRSRV_MEM_NO_SYNCOBJ | PVRSRV_MEM_EDM_PROTECT -+ | PVRSRV_MEM_CACHE_CONSISTENT, -+ ui32HWTransferContextSize, -+ 32, -+ IMG_NULL, -+ 0, -+ 0,0,0,IMG_NULL, /* No sparse mapping data */ -+ &psCleanup->psHWTransferContextMemInfo, -+ "HW Render Context"); -+ -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWTransferContextKM: Couldn't allocate device memory for HW Render Context")); -+ goto exit1; -+ } -+ -+ eError = OSCopyFromUser(psPerProc, -+ psCleanup->psHWTransferContextMemInfo->pvLinAddrKM, -+ psHWTransferContextCpuVAddr, -+ ui32HWTransferContextSize); -+ -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWTransferContextKM: Couldn't copy user-mode copy of HWContext into device memory")); -+ goto exit2; -+ } -+ -+ /* Pass the DevVAddr of the new context back up through the bridge */ -+ psHWTransferContextDevVAddr->uiAddr = psCleanup->psHWTransferContextMemInfo->sDevVAddr.uiAddr; -+ -+ /* Retrieve the PDDevPAddr */ -+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDevMemContextInt, -+ hDevMemContext, -+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT); -+ -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWTransferContextKM: Can't lookup DevMem Context")); -+ goto exit2; -+ } -+ -+ psMMUContext = BM_GetMMUContextFromMemContext(hDevMemContextInt); -+ sPDDevPAddr = psDeviceNode->pfnMMUGetPDDevPAddr(psMMUContext); -+ -+ /* -+ The PDDevPAddr needs to be shifted-down, as the uKernel expects it in the -+ format it will be inserted into the DirList registers in. -+ */ -+ ui32PDDevPAddrInDirListFormat = (IMG_UINT32)(sPDDevPAddr.uiAddr >> SGX_MMU_PTE_ADDR_ALIGNSHIFT); -+ -+ /* -+ patch-in the Page-Directory Device-Physical address. Note that this is -+ copied-in one byte at a time, as we have no guarantee that the usermode- -+ provided ui32OffsetToPDDevPAddr is a validly-aligned address for the -+ current CPU architecture. -+ */ -+ pSrc = (IMG_UINT8 *)&ui32PDDevPAddrInDirListFormat; -+ pDst = (IMG_UINT8 *)psCleanup->psHWTransferContextMemInfo->pvLinAddrKM; -+ pDst += ui32OffsetToPDDevPAddr; -+ -+ for (iPtrByte = 0; iPtrByte < sizeof(ui32PDDevPAddrInDirListFormat); iPtrByte++) -+ { -+ pDst[iPtrByte] = pSrc[iPtrByte]; -+ } -+ -+#if defined(PDUMP) -+ /* PDUMP the HW Transfer Context */ -+ PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "HW Transfer context struct"); -+ -+ PDUMPMEM( -+ IMG_NULL, -+ psCleanup->psHWTransferContextMemInfo, -+ 0, -+ ui32HWTransferContextSize, -+ PDUMP_FLAGS_CONTINUOUS, -+ MAKEUNIQUETAG(psCleanup->psHWTransferContextMemInfo)); -+ -+ /* PDUMP the PDDevPAddr */ -+ PDUMPCOMMENT("Page directory address in HW transfer context"); -+ -+ PDUMPPDDEVPADDR( -+ psCleanup->psHWTransferContextMemInfo, -+ ui32OffsetToPDDevPAddr, -+ sPDDevPAddr, -+ MAKEUNIQUETAG(psCleanup->psHWTransferContextMemInfo), -+ PDUMP_PD_UNIQUETAG); -+#endif -+ -+ psCleanup->hBlockAlloc = hBlockAlloc; -+ psCleanup->psDeviceNode = psDeviceNode; -+ psCleanup->bCleanupTimerRunning = IMG_FALSE; -+ -+ psResItem = ResManRegisterRes(psPerProc->hResManContext, -+ RESMAN_TYPE_HW_TRANSFER_CONTEXT, -+ psCleanup, -+ 0, -+ &SGXCleanupHWTransferContextCallback); -+ -+ if (psResItem == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHWTransferContextKM: ResManRegisterRes failed")); -+ goto exit2; -+ } -+ -+ psCleanup->psResItem = psResItem; -+ -+ return (IMG_HANDLE)psCleanup; -+ -+/* Error exit paths */ -+exit2: -+ PVRSRVFreeDeviceMemKM(hDeviceNode, -+ psCleanup->psHWTransferContextMemInfo); -+exit1: -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(SGX_HW_TRANSFER_CONTEXT_CLEANUP), -+ psCleanup, -+ psCleanup->hBlockAlloc); -+ /*not nulling pointer, out of scope*/ -+ -+exit0: -+ return IMG_NULL; -+} -+ -+IMG_EXPORT -+PVRSRV_ERROR SGXUnregisterHWTransferContextKM(IMG_HANDLE hHWTransferContext, IMG_BOOL bForceCleanup) -+{ -+ PVRSRV_ERROR eError; -+ SGX_HW_TRANSFER_CONTEXT_CLEANUP *psCleanup; -+ -+ PVR_ASSERT(hHWTransferContext != IMG_NULL); -+ -+ psCleanup = (SGX_HW_TRANSFER_CONTEXT_CLEANUP *)hHWTransferContext; -+ -+ if (psCleanup == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SGXUnregisterHWTransferContextKM: invalid parameter")); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ eError = ResManFreeResByPtr(psCleanup->psResItem, bForceCleanup); -+ -+ return eError; -+} -+ -+IMG_EXPORT -+PVRSRV_ERROR SGXSetTransferContextPriorityKM( -+ IMG_HANDLE hDeviceNode, -+ IMG_HANDLE hHWTransferContext, -+ IMG_UINT32 ui32Priority, -+ IMG_UINT32 ui32OffsetOfPriorityField) -+{ -+ SGX_HW_TRANSFER_CONTEXT_CLEANUP *psCleanup; -+ IMG_UINT8 *pSrc; -+ IMG_UINT8 *pDst; -+ int iPtrByte; -+ PVR_UNREFERENCED_PARAMETER(hDeviceNode); -+ -+ if (hHWTransferContext != IMG_NULL) -+ { -+ psCleanup = (SGX_HW_TRANSFER_CONTEXT_CLEANUP *)hHWTransferContext; -+ -+ if ((ui32OffsetOfPriorityField + sizeof(ui32Priority)) -+ >= psCleanup->psHWTransferContextMemInfo->uAllocSize) -+ { -+ PVR_DPF(( -+ PVR_DBG_ERROR, -+ "SGXSetTransferContextPriorityKM: invalid context prioirty offset")); -+ -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ /* -+ cannot be sure that offset (passed from user-land) is safe to deref -+ as a word-ptr on current CPU arch: copy one byte at a time. -+ */ -+ pDst = (IMG_UINT8 *)psCleanup->psHWTransferContextMemInfo->pvLinAddrKM; -+ pDst += ui32OffsetOfPriorityField; -+ pSrc = (IMG_UINT8 *)&ui32Priority; -+ -+ for (iPtrByte = 0; iPtrByte < sizeof(ui32Priority); iPtrByte++) -+ { -+ pDst[iPtrByte] = pSrc[iPtrByte]; -+ } -+ } -+ return PVRSRV_OK; -+} -+ -+IMG_EXPORT -+PVRSRV_ERROR SGXSetRenderContextPriorityKM( -+ IMG_HANDLE hDeviceNode, -+ IMG_HANDLE hHWRenderContext, -+ IMG_UINT32 ui32Priority, -+ IMG_UINT32 ui32OffsetOfPriorityField) -+{ -+ SGX_HW_RENDER_CONTEXT_CLEANUP *psCleanup; -+ IMG_UINT8 *pSrc; -+ IMG_UINT8 *pDst; -+ int iPtrByte; -+ PVR_UNREFERENCED_PARAMETER(hDeviceNode); -+ -+ if (hHWRenderContext != IMG_NULL) -+ { -+ psCleanup = (SGX_HW_RENDER_CONTEXT_CLEANUP *)hHWRenderContext; -+ if ((ui32OffsetOfPriorityField + sizeof(ui32Priority)) -+ >= psCleanup->psHWRenderContextMemInfo->uAllocSize) -+ { -+ PVR_DPF(( -+ PVR_DBG_ERROR, -+ "SGXSetContextPriorityKM: invalid HWRenderContext prioirty offset")); -+ -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ /* -+ cannot be sure that offset (passed from user-land) is safe to deref -+ as a word-ptr on current CPU arch: copy one byte at a time. -+ */ -+ pDst = (IMG_UINT8 *)psCleanup->psHWRenderContextMemInfo->pvLinAddrKM; -+ pDst += ui32OffsetOfPriorityField; -+ -+ pSrc = (IMG_UINT8 *)&ui32Priority; -+ -+ for (iPtrByte = 0; iPtrByte < sizeof(ui32Priority); iPtrByte++) -+ { -+ pDst[iPtrByte] = pSrc[iPtrByte]; -+ } -+ } -+ return PVRSRV_OK; -+} -+ -+#if defined(SGX_FEATURE_2D_HARDWARE) -+typedef struct _SGX_HW_2D_CONTEXT_CLEANUP_ -+{ -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+ PVRSRV_KERNEL_MEM_INFO *psHW2DContextMemInfo; -+ IMG_HANDLE hBlockAlloc; -+ PRESMAN_ITEM psResItem; -+ IMG_BOOL bCleanupTimerRunning; -+ IMG_PVOID pvTimeData; -+} SGX_HW_2D_CONTEXT_CLEANUP; -+ -+static PVRSRV_ERROR SGXCleanupHW2DContextCallback(IMG_PVOID pvParam, -+ IMG_UINT32 ui32Param, -+ IMG_BOOL bForceCleanup) -+{ -+ PVRSRV_ERROR eError; -+ SGX_HW_2D_CONTEXT_CLEANUP *psCleanup = (SGX_HW_2D_CONTEXT_CLEANUP *)pvParam; -+ -+ PVR_UNREFERENCED_PARAMETER(ui32Param); -+ -+ /* First, ensure the context is no longer being utilised */ -+ eError = SGXCleanupRequest(psCleanup->psDeviceNode, -+ &psCleanup->psHW2DContextMemInfo->sDevVAddr, -+ PVRSRV_CLEANUPCMD_2DC, -+ bForceCleanup); -+ -+ if (eError == PVRSRV_ERROR_RETRY) -+ { -+ if (!psCleanup->bCleanupTimerRunning) -+ { -+ OSTimeCreateWithUSOffset(&psCleanup->pvTimeData, MAX_CLEANUP_TIME_US); -+ psCleanup->bCleanupTimerRunning = IMG_TRUE; -+ } -+ else -+ { -+ if (OSTimeHasTimePassed(psCleanup->pvTimeData)) -+ { -+ eError = PVRSRV_ERROR_TIMEOUT_POLLING_FOR_VALUE; -+ psCleanup->bCleanupTimerRunning = IMG_FALSE; -+ OSTimeDestroy(psCleanup->pvTimeData); -+ } -+ } -+ } -+ else -+ { -+ if (psCleanup->bCleanupTimerRunning) -+ { -+ OSTimeDestroy(psCleanup->pvTimeData); -+ } -+ } -+ -+ if (eError != PVRSRV_ERROR_RETRY) -+ { -+ /* Free the Device Mem allocated */ -+ PVRSRVFreeDeviceMemKM(psCleanup->psDeviceNode, -+ psCleanup->psHW2DContextMemInfo); -+ -+ /* Finally, free the cleanup structure itself */ -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(SGX_HW_2D_CONTEXT_CLEANUP), -+ psCleanup, -+ psCleanup->hBlockAlloc); -+ /*not nulling pointer, copy on stack*/ -+ } -+ return eError; -+} -+ -+IMG_HANDLE SGXRegisterHW2DContextKM(IMG_HANDLE hDeviceNode, -+ IMG_CPU_VIRTADDR *psHW2DContextCpuVAddr, -+ IMG_UINT32 ui32HW2DContextSize, -+ IMG_UINT32 ui32OffsetToPDDevPAddr, -+ IMG_HANDLE hDevMemContext, -+ IMG_DEV_VIRTADDR *psHW2DContextDevVAddr, -+ PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ PVRSRV_ERROR eError; -+ IMG_HANDLE hBlockAlloc; -+ SGX_HW_2D_CONTEXT_CLEANUP *psCleanup; -+ PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)hDeviceNode; -+ DEVICE_MEMORY_INFO *psDevMemoryInfo; -+ DEVICE_MEMORY_HEAP_INFO *psHeapInfo; -+ IMG_HANDLE hDevMemContextInt; -+ MMU_CONTEXT *psMMUContext; -+ IMG_DEV_PHYADDR sPDDevPAddr; -+ int iPtrByte; -+ IMG_UINT8 *pSrc; -+ IMG_UINT8 *pDst; -+ PRESMAN_ITEM psResItem; -+ IMG_UINT32 ui32PDDevPAddrInDirListFormat; -+ -+ eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(SGX_HW_2D_CONTEXT_CLEANUP), -+ (IMG_VOID **)&psCleanup, -+ &hBlockAlloc, -+ "SGX Hardware 2D Context Cleanup"); -+ -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHW2DContextKM: Couldn't allocate memory for SGX_HW_2D_CONTEXT_CLEANUP structure")); -+ goto exit0; -+ } -+ -+ psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo; -+ psHeapInfo = &psDevMemoryInfo->psDeviceMemoryHeap[SGX_KERNEL_DATA_HEAP_ID]; -+ -+ eError = PVRSRVAllocDeviceMemKM(hDeviceNode, -+ psPerProc, -+ psHeapInfo->hDevMemHeap, -+ PVRSRV_MEM_READ | PVRSRV_MEM_WRITE -+ | PVRSRV_MEM_NO_SYNCOBJ | PVRSRV_MEM_EDM_PROTECT -+ | PVRSRV_MEM_CACHE_CONSISTENT, -+ ui32HW2DContextSize, -+ 32, -+ IMG_NULL, -+ 0, -+ 0,0,0,IMG_NULL, /* No sparse mapping data */ -+ &psCleanup->psHW2DContextMemInfo, -+ "HW 2D Context"); -+ -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHW2DContextKM: Couldn't allocate device memory for HW Render Context")); -+ goto exit1; -+ } -+ -+ eError = OSCopyFromUser(psPerProc, -+ psCleanup->psHW2DContextMemInfo->pvLinAddrKM, -+ psHW2DContextCpuVAddr, -+ ui32HW2DContextSize); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHW2DContextKM: Couldn't copy user-mode copy of HWContext into device memory")); -+ goto exit2; -+ } -+ -+ /* Pass the DevVAddr of the new context back up through the bridge */ -+ psHW2DContextDevVAddr->uiAddr = psCleanup->psHW2DContextMemInfo->sDevVAddr.uiAddr; -+ -+ /* Retrieve the PDDevPAddr */ -+ eError = PVRSRVLookupHandle(psPerProc->psHandleBase, -+ &hDevMemContextInt, -+ hDevMemContext, -+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT); -+ -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHW2DContextKM: Can't lookup DevMem Context")); -+ goto exit2; -+ } -+ -+ psMMUContext = BM_GetMMUContextFromMemContext(hDevMemContextInt); -+ sPDDevPAddr = psDeviceNode->pfnMMUGetPDDevPAddr(psMMUContext); -+ -+ /* -+ The PDDevPAddr needs to be shifted-down, as the uKernel expects it in the -+ format it will be inserted into the DirList registers in. -+ */ -+ ui32PDDevPAddrInDirListFormat = sPDDevPAddr.uiAddr >> SGX_MMU_PTE_ADDR_ALIGNSHIFT; -+ -+ /* -+ patch-in the Page-Directory Device-Physical address. Note that this is -+ copied-in one byte at a time, as we have no guarantee that the usermode- -+ provided ui32OffsetToPDDevPAddr is a validly-aligned address for the -+ current CPU architecture. -+ */ -+ pSrc = (IMG_UINT8 *)&ui32PDDevPAddrInDirListFormat; -+ pDst = (IMG_UINT8 *)psCleanup->psHW2DContextMemInfo->pvLinAddrKM; -+ pDst += ui32OffsetToPDDevPAddr; -+ -+ for (iPtrByte = 0; iPtrByte < sizeof(ui32PDDevPAddrInDirListFormat); iPtrByte++) -+ { -+ pDst[iPtrByte] = pSrc[iPtrByte]; -+ } -+ -+#if defined(PDUMP) -+ /* PDUMP the HW 2D Context */ -+ PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "HW 2D context struct"); -+ -+ PDUMPMEM( -+ IMG_NULL, -+ psCleanup->psHW2DContextMemInfo, -+ 0, -+ ui32HW2DContextSize, -+ PDUMP_FLAGS_CONTINUOUS, -+ MAKEUNIQUETAG(psCleanup->psHW2DContextMemInfo)); -+ -+ /* PDUMP the PDDevPAddr */ -+ PDUMPCOMMENT("Page directory address in HW 2D transfer context"); -+ PDUMPPDDEVPADDR( -+ psCleanup->psHW2DContextMemInfo, -+ ui32OffsetToPDDevPAddr, -+ sPDDevPAddr, -+ MAKEUNIQUETAG(psCleanup->psHW2DContextMemInfo), -+ PDUMP_PD_UNIQUETAG); -+#endif -+ -+ psCleanup->hBlockAlloc = hBlockAlloc; -+ psCleanup->psDeviceNode = psDeviceNode; -+ psCleanup->bCleanupTimerRunning = IMG_FALSE; -+ -+ psResItem = ResManRegisterRes(psPerProc->hResManContext, -+ RESMAN_TYPE_HW_2D_CONTEXT, -+ psCleanup, -+ 0, -+ &SGXCleanupHW2DContextCallback); -+ -+ if (psResItem == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SGXRegisterHW2DContextKM: ResManRegisterRes failed")); -+ goto exit2; -+ } -+ -+ psCleanup->psResItem = psResItem; -+ -+ return (IMG_HANDLE)psCleanup; -+ -+/* Error exit paths */ -+exit2: -+ PVRSRVFreeDeviceMemKM(hDeviceNode, -+ psCleanup->psHW2DContextMemInfo); -+exit1: -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, -+ sizeof(SGX_HW_2D_CONTEXT_CLEANUP), -+ psCleanup, -+ psCleanup->hBlockAlloc); -+ /*not nulling pointer, out of scope*/ -+exit0: -+ return IMG_NULL; -+} -+ -+IMG_EXPORT -+PVRSRV_ERROR SGXUnregisterHW2DContextKM(IMG_HANDLE hHW2DContext, IMG_BOOL bForceCleanup) -+{ -+ PVRSRV_ERROR eError; -+ SGX_HW_2D_CONTEXT_CLEANUP *psCleanup; -+ -+ PVR_ASSERT(hHW2DContext != IMG_NULL); -+ -+ if (hHW2DContext == IMG_NULL) -+ { -+ return (PVRSRV_ERROR_INVALID_PARAMS); -+ } -+ -+ psCleanup = (SGX_HW_2D_CONTEXT_CLEANUP *)hHW2DContext; -+ -+ eError = ResManFreeResByPtr(psCleanup->psResItem, bForceCleanup); -+ -+ return eError; -+} -+#endif /* #if defined(SGX_FEATURE_2D_HARDWARE)*/ -+ -+/*!**************************************************************************** -+ @Function SGX2DQuerySyncOpsCompleteKM -+ -+ @Input psSyncInfo : Sync object to be queried -+ -+ @Return IMG_TRUE - ops complete, IMG_FALSE - ops pending -+ -+******************************************************************************/ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(SGX2DQuerySyncOpsComplete) -+#endif -+static INLINE -+IMG_BOOL SGX2DQuerySyncOpsComplete(PVRSRV_KERNEL_SYNC_INFO *psSyncInfo, -+ IMG_UINT32 ui32ReadOpsPending, -+ IMG_UINT32 ui32WriteOpsPending) -+{ -+ PVRSRV_SYNC_DATA *psSyncData = psSyncInfo->psSyncData; -+ -+ return (IMG_BOOL)( -+ (psSyncData->ui32ReadOpsComplete >= ui32ReadOpsPending) && -+ (psSyncData->ui32WriteOpsComplete >= ui32WriteOpsPending) -+ ); -+} -+ -+/*!**************************************************************************** -+ @Function SGX2DQueryBlitsCompleteKM -+ -+ @Input psDevInfo : SGX device info structure -+ -+ @Input psSyncInfo : Sync object to be queried -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+IMG_EXPORT -+PVRSRV_ERROR SGX2DQueryBlitsCompleteKM(PVRSRV_SGXDEV_INFO *psDevInfo, -+ PVRSRV_KERNEL_SYNC_INFO *psSyncInfo, -+ IMG_BOOL bWaitForComplete) -+{ -+ IMG_UINT32 ui32ReadOpsPending, ui32WriteOpsPending; -+ -+ PVR_UNREFERENCED_PARAMETER(psDevInfo); -+ -+ PVR_DPF((PVR_DBG_CALLTRACE, "SGX2DQueryBlitsCompleteKM: Start")); -+ -+ ui32ReadOpsPending = psSyncInfo->psSyncData->ui32ReadOpsPending; -+ ui32WriteOpsPending = psSyncInfo->psSyncData->ui32WriteOpsPending; -+ -+ if(SGX2DQuerySyncOpsComplete(psSyncInfo, ui32ReadOpsPending, ui32WriteOpsPending)) -+ { -+ /* Instant success */ -+ PVR_DPF((PVR_DBG_CALLTRACE, "SGX2DQueryBlitsCompleteKM: No wait. Blits complete.")); -+ return PVRSRV_OK; -+ } -+ -+ /* Not complete yet */ -+ if (!bWaitForComplete) -+ { -+ /* Just report not complete */ -+ PVR_DPF((PVR_DBG_CALLTRACE, "SGX2DQueryBlitsCompleteKM: No wait. Ops pending.")); -+ return PVRSRV_ERROR_CMD_NOT_PROCESSED; -+ } -+ -+ /* Start polling */ -+ PVR_DPF((PVR_DBG_MESSAGE, "SGX2DQueryBlitsCompleteKM: Ops pending. Start polling.")); -+ -+ LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) -+ { -+ OSSleepms(1); -+ -+ if(SGX2DQuerySyncOpsComplete(psSyncInfo, ui32ReadOpsPending, ui32WriteOpsPending)) -+ { -+ /* Success */ -+ PVR_DPF((PVR_DBG_CALLTRACE, "SGX2DQueryBlitsCompleteKM: Wait over. Blits complete.")); -+ return PVRSRV_OK; -+ } -+ -+ OSSleepms(1); -+ } END_LOOP_UNTIL_TIMEOUT(); -+ -+ /* Timed out */ -+ PVR_DPF((PVR_DBG_ERROR,"SGX2DQueryBlitsCompleteKM: Timed out. Ops pending.")); -+ -+#if defined(DEBUG) -+ { -+ PVRSRV_SYNC_DATA *psSyncData = psSyncInfo->psSyncData; -+ -+ PVR_TRACE(("SGX2DQueryBlitsCompleteKM: Syncinfo: 0x%p, Syncdata: 0x%p", -+ psSyncInfo, psSyncData)); -+ -+ PVR_TRACE(("SGX2DQueryBlitsCompleteKM: Read ops complete: %d, Read ops pending: %d", psSyncData->ui32ReadOpsComplete, psSyncData->ui32ReadOpsPending)); -+ PVR_TRACE(("SGX2DQueryBlitsCompleteKM: Write ops complete: %d, Write ops pending: %d", psSyncData->ui32WriteOpsComplete, psSyncData->ui32WriteOpsPending)); -+ -+ } -+#endif -+ -+ return PVRSRV_ERROR_TIMEOUT; -+} -+ -+ -+IMG_EXPORT -+PVRSRV_ERROR SGXFlushHWRenderTargetKM(IMG_HANDLE psDeviceNode, -+ IMG_DEV_VIRTADDR sHWRTDataSetDevVAddr, -+ IMG_BOOL bForceCleanup) -+{ -+ PVR_ASSERT(sHWRTDataSetDevVAddr.uiAddr != IMG_NULL); -+ -+ return SGXCleanupRequest(psDeviceNode, -+ &sHWRTDataSetDevVAddr, -+ PVRSRV_CLEANUPCMD_RT, -+ bForceCleanup); -+} -+ -+ -+IMG_UINT32 SGXConvertTimeStamp(PVRSRV_SGXDEV_INFO *psDevInfo, -+ IMG_UINT32 ui32TimeWraps, -+ IMG_UINT32 ui32Time) -+{ -+#if defined(EUR_CR_TIMER) -+ PVR_UNREFERENCED_PARAMETER(psDevInfo); -+ PVR_UNREFERENCED_PARAMETER(ui32TimeWraps); -+ return ui32Time; -+#else -+ IMG_UINT64 ui64Clocks; -+ IMG_UINT32 ui32Clocksx16; -+ -+ ui64Clocks = ((IMG_UINT64)ui32TimeWraps * psDevInfo->ui32uKernelTimerClock) + -+ (psDevInfo->ui32uKernelTimerClock - (ui32Time & EUR_CR_EVENT_TIMER_VALUE_MASK)); -+ ui32Clocksx16 = (IMG_UINT32)(ui64Clocks / 16); -+ -+ return ui32Clocksx16; -+#endif /* EUR_CR_TIMER */ -+} -+ -+ -+IMG_VOID SGXWaitClocks(PVRSRV_SGXDEV_INFO *psDevInfo, -+ IMG_UINT32 ui32SGXClocks) -+{ -+ /* -+ Round up to the next microsecond. -+ */ -+ OSWaitus(1 + (ui32SGXClocks * 1000000 / psDevInfo->ui32CoreClockSpeed)); -+} -+ -+ -+ -+/****************************************************************************** -+ End of file (sgxutils.c) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/sgxutils.h b/drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/sgxutils.h -new file mode 100644 -index 0000000..fc2ef6f ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx/sgxutils.h -@@ -0,0 +1,195 @@ -+/*************************************************************************/ /*! -+@Title Device specific utility routines declarations -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Inline functions/structures specific to SGX -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#include "perproc.h" -+#include "sgxinfokm.h" -+ -+/* PRQA S 3410 7 */ /* macros require the absence of some brackets */ -+#define CCB_OFFSET_IS_VALID(type, psCCBMemInfo, psCCBKick, offset) \ -+ ((sizeof(type) <= (psCCBMemInfo)->uAllocSize) && \ -+ ((psCCBKick)->offset <= (psCCBMemInfo)->uAllocSize - sizeof(type))) -+ -+#define CCB_DATA_FROM_OFFSET(type, psCCBMemInfo, psCCBKick, offset) \ -+ ((type *)(((IMG_CHAR *)(psCCBMemInfo)->pvLinAddrKM) + \ -+ (psCCBKick)->offset)) -+ -+extern IMG_UINT64 ui64KickCount; -+ -+ -+IMG_IMPORT -+IMG_VOID SGXTestActivePowerEvent(PVRSRV_DEVICE_NODE *psDeviceNode, -+ IMG_UINT32 ui32CallerID); -+ -+IMG_IMPORT -+PVRSRV_ERROR SGXScheduleCCBCommand(PVRSRV_DEVICE_NODE *psDeviceNode, -+ SGXMKIF_CMD_TYPE eCommandType, -+ SGXMKIF_COMMAND *psCommandData, -+ IMG_UINT32 ui32CallerID, -+ IMG_UINT32 ui32PDumpFlags, -+ IMG_HANDLE hDevMemContext, -+ IMG_BOOL bLastInScene); -+IMG_IMPORT -+PVRSRV_ERROR SGXScheduleCCBCommandKM(PVRSRV_DEVICE_NODE *psDeviceNode, -+ SGXMKIF_CMD_TYPE eCommandType, -+ SGXMKIF_COMMAND *psCommandData, -+ IMG_UINT32 ui32CallerID, -+ IMG_UINT32 ui32PDumpFlags, -+ IMG_HANDLE hDevMemContext, -+ IMG_BOOL bLastInScene); -+ -+IMG_IMPORT -+PVRSRV_ERROR SGXScheduleProcessQueuesKM(PVRSRV_DEVICE_NODE *psDeviceNode); -+ -+IMG_IMPORT -+IMG_BOOL SGXIsDevicePowered(PVRSRV_DEVICE_NODE *psDeviceNode); -+ -+IMG_IMPORT -+IMG_HANDLE SGXRegisterHWRenderContextKM(IMG_HANDLE psDeviceNode, -+ IMG_CPU_VIRTADDR *psHWRenderContextCpuVAddr, -+ IMG_UINT32 ui32HWRenderContextSize, -+ IMG_UINT32 ui32OffsetToPDDevPAddr, -+ IMG_HANDLE hDevMemContext, -+ IMG_DEV_VIRTADDR *psHWRenderContextDevVAddr, -+ PVRSRV_PER_PROCESS_DATA *psPerProc); -+ -+IMG_IMPORT -+IMG_HANDLE SGXRegisterHWTransferContextKM(IMG_HANDLE psDeviceNode, -+ IMG_CPU_VIRTADDR *psHWTransferContextCpuVAddr, -+ IMG_UINT32 ui32HWTransferContextSize, -+ IMG_UINT32 ui32OffsetToPDDevPAddr, -+ IMG_HANDLE hDevMemContext, -+ IMG_DEV_VIRTADDR *psHWTransferContextDevVAddr, -+ PVRSRV_PER_PROCESS_DATA *psPerProc); -+ -+IMG_IMPORT -+PVRSRV_ERROR SGXFlushHWRenderTargetKM(IMG_HANDLE psSGXDevInfo, -+ IMG_DEV_VIRTADDR psHWRTDataSetDevVAddr, -+ IMG_BOOL bForceCleanup); -+ -+IMG_IMPORT -+PVRSRV_ERROR SGXUnregisterHWRenderContextKM(IMG_HANDLE hHWRenderContext, IMG_BOOL bForceCleanup); -+ -+IMG_IMPORT -+PVRSRV_ERROR SGXUnregisterHWTransferContextKM(IMG_HANDLE hHWTransferContext, IMG_BOOL bForceCleanup); -+ -+IMG_IMPORT -+PVRSRV_ERROR SGXSetRenderContextPriorityKM(IMG_HANDLE hDeviceNode, -+ IMG_HANDLE hHWRenderContext, -+ IMG_UINT32 ui32Priority, -+ IMG_UINT32 ui32OffsetOfPriorityField); -+ -+IMG_IMPORT -+PVRSRV_ERROR SGXSetTransferContextPriorityKM(IMG_HANDLE hDeviceNode, -+ IMG_HANDLE hHWTransferContext, -+ IMG_UINT32 ui32Priority, -+ IMG_UINT32 ui32OffsetOfPriorityField); -+ -+#if defined(SGX_FEATURE_2D_HARDWARE) -+IMG_IMPORT -+IMG_HANDLE SGXRegisterHW2DContextKM(IMG_HANDLE psDeviceNode, -+ IMG_CPU_VIRTADDR *psHW2DContextCpuVAddr, -+ IMG_UINT32 ui32HW2DContextSize, -+ IMG_UINT32 ui32OffsetToPDDevPAddr, -+ IMG_HANDLE hDevMemContext, -+ IMG_DEV_VIRTADDR *psHW2DContextDevVAddr, -+ PVRSRV_PER_PROCESS_DATA *psPerProc); -+ -+IMG_IMPORT -+PVRSRV_ERROR SGXUnregisterHW2DContextKM(IMG_HANDLE hHW2DContext, IMG_BOOL bForceCleanup); -+#endif -+ -+IMG_UINT32 SGXConvertTimeStamp(PVRSRV_SGXDEV_INFO *psDevInfo, -+ IMG_UINT32 ui32TimeWraps, -+ IMG_UINT32 ui32Time); -+ -+/*! -+******************************************************************************* -+ -+ @Function SGXWaitClocks -+ -+ @Description -+ -+ Wait for a specified number of SGX clock cycles to elapse. -+ -+ @Input psDevInfo - SGX Device Info -+ @Input ui32SGXClocks - number of clock cycles to wait -+ -+ @Return IMG_VOID -+ -+******************************************************************************/ -+IMG_VOID SGXWaitClocks(PVRSRV_SGXDEV_INFO *psDevInfo, -+ IMG_UINT32 ui32SGXClocks); -+ -+PVRSRV_ERROR SGXCleanupRequest(PVRSRV_DEVICE_NODE *psDeviceNode, -+ IMG_DEV_VIRTADDR *psHWDataDevVAddr, -+ IMG_UINT32 ui32CleanupType, -+ IMG_BOOL bForceCleanup); -+ -+IMG_IMPORT -+PVRSRV_ERROR PVRSRVGetSGXRevDataKM(PVRSRV_DEVICE_NODE* psDeviceNode, IMG_UINT32 *pui32SGXCoreRev, -+ IMG_UINT32 *pui32SGXCoreID); -+ -+/*! -+****************************************************************************** -+ -+ @Function SGXContextSuspend -+ -+ @Description - Interface to the SGX microkernel to instruct it to suspend or -+ resume processing on a given context. This will interrupt current -+ processing of this context if a task is already running and is -+ interruptable. -+ -+ @Input psDeviceNode SGX device node -+ @Input psHWContextDevVAddr SGX virtual address of the context to be suspended -+ or resumed. Can be of type SGXMKIF_HWRENDERCONTEXT, -+ SGXMKIF_HWTRANSFERCONTEXT or SGXMKIF_HW2DCONTEXT -+ @Input bResume IMG_TRUE to put a context into suspend state, -+ IMG_FALSE to resume a previously suspended context -+ -+******************************************************************************/ -+PVRSRV_ERROR SGXContextSuspend(PVRSRV_DEVICE_NODE *psDeviceNode, -+ IMG_DEV_VIRTADDR *psHWContextDevVAddr, -+ IMG_BOOL bResume); -+ -+/****************************************************************************** -+ End of file (sgxutils.h) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/Kbuild.mk b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/Kbuild.mk -new file mode 100644 -index 0000000..5a36a40 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/Kbuild.mk -@@ -0,0 +1,168 @@ -+########################################################################### ### -+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+#@License Dual MIT/GPLv2 -+# -+# The contents of this file are subject to the MIT license as set out below. -+# -+# Permission is hereby granted, free of charge, to any person obtaining a copy -+# of this software and associated documentation files (the "Software"), to deal -+# in the Software without restriction, including without limitation the rights -+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+# copies of the Software, and to permit persons to whom the Software is -+# furnished to do so, subject to the following conditions: -+# -+# The above copyright notice and this permission notice shall be included in -+# all copies or substantial portions of the Software. -+# -+# Alternatively, the contents of this file may be used under the terms of -+# the GNU General Public License Version 2 ("GPL") in which case the provisions -+# of GPL are applicable instead of those above. -+# -+# If you wish to allow use of your version of this file only under the terms of -+# GPL, and not to allow others to use your version of this file under the terms -+# of the MIT license, indicate your decision by deleting the provisions above -+# and replace them with the notice and other provisions required by GPL as set -+# out in the file called "GPL-COPYING" included in this distribution. If you do -+# not delete the provisions above, a recipient may use your version of this file -+# under the terms of either the MIT license or GPL. -+# -+# This License is also included in this distribution in the file called -+# "MIT-COPYING". -+# -+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+### ########################################################################### -+ -+pvrsrvkm-y += \ -+ services4/srvkm/env/linux/osfunc.o \ -+ services4/srvkm/env/linux/mutils.o \ -+ services4/srvkm/env/linux/mmap.o \ -+ services4/srvkm/env/linux/module.o \ -+ services4/srvkm/env/linux/pdump.o \ -+ services4/srvkm/env/linux/proc.o \ -+ services4/srvkm/env/linux/pvr_bridge_k.o \ -+ services4/srvkm/env/linux/pvr_debug.o \ -+ services4/srvkm/env/linux/mm.o \ -+ services4/srvkm/env/linux/mutex.o \ -+ services4/srvkm/env/linux/event.o \ -+ services4/srvkm/env/linux/osperproc.o \ -+ services4/srvkm/common/buffer_manager.o \ -+ services4/srvkm/common/devicemem.o \ -+ services4/srvkm/common/deviceclass.o \ -+ services4/srvkm/common/handle.o \ -+ services4/srvkm/common/hash.o \ -+ services4/srvkm/common/lists.o \ -+ services4/srvkm/common/mem.o \ -+ services4/srvkm/common/mem_debug.o \ -+ services4/srvkm/common/metrics.o \ -+ services4/srvkm/common/osfunc_common.o \ -+ services4/srvkm/common/pdump_common.o \ -+ services4/srvkm/common/perproc.o \ -+ services4/srvkm/common/power.o \ -+ services4/srvkm/common/pvrsrv.o \ -+ services4/srvkm/common/queue.o \ -+ services4/srvkm/common/ra.o \ -+ services4/srvkm/common/refcount.o \ -+ services4/srvkm/common/resman.o \ -+ services4/srvkm/bridged/bridged_support.o \ -+ services4/srvkm/bridged/bridged_pvr_bridge.o \ -+ services4/system/$(PVR_SYSTEM)/sysconfig.o \ -+ services4/system/$(PVR_SYSTEM)/sysutils.o -+ -+pvrsrvkm-$(CONFIG_ION_OMAP) += \ -+ services4/srvkm/env/linux/ion.o -+ -+ifeq ($(SUPPORT_ION),1) -+pvrsrvkm-y += \ -+ services4/srvkm/env/linux/ion.o -+endif -+ -+ifeq ($(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC),1) -+pvrsrvkm-y += \ -+ services4/srvkm/env/linux/pvr_sync.o -+endif -+ -+ifeq ($(TTRACE),1) -+pvrsrvkm-y += \ -+ services4/srvkm/common/ttrace.o -+endif -+ -+ifneq ($(W),1) -+CFLAGS_osfunc.o := -Werror -+CFLAGS_mutils.o := -Werror -+CFLAGS_mmap.o := -Werror -+CFLAGS_module.o := -Werror -+CFLAGS_pdump.o := -Werror -+CFLAGS_proc.o := -Werror -+CFLAGS_pvr_bridge_k.o := -Werror -+CFLAGS_pvr_debug.o := -Werror -+CFLAGS_mm.o := -Werror -+CFLAGS_mutex.o := -Werror -+CFLAGS_event.o := -Werror -+CFLAGS_osperproc.o := -Werror -+CFLAGS_buffer_manager.o := -Werror -+CFLAGS_devicemem.o := -Werror -+CFLAGS_deviceclass.o := -Werror -+CFLAGS_handle.o := -Werror -+CFLAGS_hash.o := -Werror -+CFLAGS_metrics.o := -Werror -+CFLAGS_pvrsrv.o := -Werror -+CFLAGS_queue.o := -Werror -+CFLAGS_ra.o := -Werror -+CFLAGS_resman.o := -Werror -+CFLAGS_power.o := -Werror -+CFLAGS_mem.o := -Werror -+CFLAGS_pdump_common.o := -Werror -+CFLAGS_bridged_support.o := -Werror -+CFLAGS_bridged_pvr_bridge.o := -Werror -+CFLAGS_perproc.o := -Werror -+CFLAGS_lists.o := -Werror -+CFLAGS_mem_debug.o := -Werror -+CFLAGS_osfunc_common.o := -Werror -+CFLAGS_refcount.o := -Werror -+endif -+ -+# SUPPORT_SGX==1 only -+ -+pvrsrvkm-y += \ -+ services4/srvkm/bridged/sgx/bridged_sgx_bridge.o \ -+ services4/srvkm/devices/sgx/sgxinit.o \ -+ services4/srvkm/devices/sgx/sgxpower.o \ -+ services4/srvkm/devices/sgx/sgxreset.o \ -+ services4/srvkm/devices/sgx/sgxutils.o \ -+ services4/srvkm/devices/sgx/sgxkick.o \ -+ services4/srvkm/devices/sgx/sgxtransfer.o \ -+ services4/srvkm/devices/sgx/mmu.o \ -+ services4/srvkm/devices/sgx/pb.o -+ -+ifneq ($(W),1) -+CFLAGS_bridged_sgx_bridge.o := -Werror -+CFLAGS_sgxinit.o := -Werror -+CFLAGS_sgxpower.o := -Werror -+CFLAGS_sgxreset.o := -Werror -+CFLAGS_sgxutils.o := -Werror -+CFLAGS_sgxkick.o := -Werror -+CFLAGS_sgxtransfer.o := -Werror -+CFLAGS_mmu.o := -Werror -+CFLAGS_pb.o := -Werror -+endif -+ -+ifeq ($(SUPPORT_DRI_DRM),1) -+ -+pvrsrvkm-y += \ -+ services4/srvkm/env/linux/pvr_drm.o -+ -+ccflags-y += \ -+ -Iinclude/drm \ -+ -I$(TOP)/services4/include/env/linux \ -+ -+ifeq ($(PVR_DRI_DRM_NOT_PCI),1) -+ccflags-y += -I$(TOP)/services4/3rdparty/linux_drm -+endif -+ -+endif # SUPPORT_DRI_DRM -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/Linux.mk b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/Linux.mk -new file mode 100644 -index 0000000..0e0ccb5 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/Linux.mk -@@ -0,0 +1,45 @@ -+########################################################################### ### -+#@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+#@License Dual MIT/GPLv2 -+# -+# The contents of this file are subject to the MIT license as set out below. -+# -+# Permission is hereby granted, free of charge, to any person obtaining a copy -+# of this software and associated documentation files (the "Software"), to deal -+# in the Software without restriction, including without limitation the rights -+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+# copies of the Software, and to permit persons to whom the Software is -+# furnished to do so, subject to the following conditions: -+# -+# The above copyright notice and this permission notice shall be included in -+# all copies or substantial portions of the Software. -+# -+# Alternatively, the contents of this file may be used under the terms of -+# the GNU General Public License Version 2 ("GPL") in which case the provisions -+# of GPL are applicable instead of those above. -+# -+# If you wish to allow use of your version of this file only under the terms of -+# GPL, and not to allow others to use your version of this file under the terms -+# of the MIT license, indicate your decision by deleting the provisions above -+# and replace them with the notice and other provisions required by GPL as set -+# out in the file called "GPL-COPYING" included in this distribution. If you do -+# not delete the provisions above, a recipient may use your version of this file -+# under the terms of either the MIT license or GPL. -+# -+# This License is also included in this distribution in the file called -+# "MIT-COPYING". -+# -+# EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+# PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+# PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+### ########################################################################### -+ -+modules := srvkm -+ -+srvkm_type := kernel_module -+srvkm_target := pvrsrvkm.ko -+srvkm_makefile := $(THIS_DIR)/Kbuild.mk -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/env_data.h b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/env_data.h -new file mode 100644 -index 0000000..0eacee56 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/env_data.h -@@ -0,0 +1,93 @@ -+/*************************************************************************/ /*! -+@Title Environmental Data header file -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Linux-specific part of system data. -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+#ifndef _ENV_DATA_ -+#define _ENV_DATA_ -+ -+#include <linux/interrupt.h> -+#include <linux/pci.h> -+ -+#if defined(PVR_LINUX_MISR_USING_WORKQUEUE) || defined(PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE) -+#include <linux/workqueue.h> -+#endif -+ -+/* -+ * Env data specific to linux - convenient place to put this -+ */ -+ -+/* Fairly arbitrary sizes - hopefully enough for all bridge calls */ -+#define PVRSRV_MAX_BRIDGE_IN_SIZE 0x1000 -+#define PVRSRV_MAX_BRIDGE_OUT_SIZE 0x1000 -+ -+typedef struct _PVR_PCI_DEV_TAG -+{ -+ struct pci_dev *psPCIDev; -+ HOST_PCI_INIT_FLAGS ePCIFlags; -+ IMG_BOOL abPCIResourceInUse[DEVICE_COUNT_RESOURCE]; -+} PVR_PCI_DEV; -+ -+typedef struct _ENV_DATA_TAG -+{ -+ IMG_VOID *pvBridgeData; -+ struct pm_dev *psPowerDevice; -+ IMG_BOOL bLISRInstalled; -+ IMG_BOOL bMISRInstalled; -+ IMG_UINT32 ui32IRQ; -+ IMG_VOID *pvISRCookie; -+#if defined(PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE) -+ struct workqueue_struct *psWorkQueue; -+#endif -+#if defined(PVR_LINUX_MISR_USING_WORKQUEUE) || defined(PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE) -+ struct work_struct sMISRWork; -+ IMG_VOID *pvMISRData; -+#else -+ struct tasklet_struct sMISRTasklet; -+#endif -+#if defined (SUPPORT_ION) -+ IMG_HANDLE hIonHeaps; -+ IMG_HANDLE hIonDev; -+#endif -+} ENV_DATA; -+ -+#endif /* _ENV_DATA_ */ -+/***************************************************************************** -+ End of file (env_data.h) -+*****************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/env_perproc.h b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/env_perproc.h -new file mode 100644 -index 0000000..b475c79 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/env_perproc.h -@@ -0,0 +1,79 @@ -+/*************************************************************************/ /*! -+@Title OS specific per process data interface -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Linux per process data -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+#ifndef __ENV_PERPROC_H__ -+#define __ENV_PERPROC_H__ -+ -+#include <linux/list.h> -+#include <linux/proc_fs.h> -+ -+#include "services.h" -+#include "handle.h" -+ -+#define ION_CLIENT_NAME_SIZE 50 -+typedef struct _PVRSRV_ENV_PER_PROCESS_DATA_ -+{ -+ IMG_HANDLE hBlockAlloc; -+ struct proc_dir_entry *psProcDir; -+#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT) -+ struct list_head sDRMAuthListHead; -+#endif -+#if defined(SUPPORT_ION) -+ struct ion_client *psIONClient; -+ IMG_CHAR azIonClientName[ION_CLIENT_NAME_SIZE]; -+#endif -+} PVRSRV_ENV_PER_PROCESS_DATA; -+ -+IMG_VOID RemovePerProcessProcDir(PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc); -+ -+PVRSRV_ERROR LinuxMMapPerProcessConnect(PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc); -+ -+IMG_VOID LinuxMMapPerProcessDisconnect(PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc); -+ -+PVRSRV_ERROR LinuxMMapPerProcessHandleOptions(PVRSRV_HANDLE_BASE *psHandleBase); -+ -+IMG_HANDLE LinuxTerminatingProcessPrivateData(IMG_VOID); -+ -+#endif /* __ENV_PERPROC_H__ */ -+ -+/****************************************************************************** -+ End of file (env_perproc.h) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/event.c b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/event.c -new file mode 100644 -index 0000000..4064b67 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/event.c -@@ -0,0 +1,413 @@ -+/*************************************************************************/ /*! -+@Title Event Object -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#include <linux/version.h> -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)) -+#ifndef AUTOCONF_INCLUDED -+#include <linux/config.h> -+#endif -+#endif -+ -+#include <asm/io.h> -+#include <asm/page.h> -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0)) -+#include <asm/system.h> -+#endif -+#include <linux/mm.h> -+#include <linux/slab.h> -+#include <linux/vmalloc.h> -+#include <linux/delay.h> -+#include <linux/pci.h> -+ -+#include <linux/string.h> -+#include <linux/sched.h> -+#include <linux/interrupt.h> -+#include <asm/hardirq.h> -+#include <linux/spinlock.h> -+#include <linux/timer.h> -+#include <linux/capability.h> -+#include <linux/sched.h> -+#include <asm/uaccess.h> -+ -+#include "img_types.h" -+#include "services_headers.h" -+#include "mm.h" -+#include "pvrmmap.h" -+#include "mmap.h" -+#include "env_data.h" -+#include "proc.h" -+#include "mutex.h" -+#include "lock.h" -+#include "event.h" -+ -+typedef struct PVRSRV_LINUX_EVENT_OBJECT_LIST_TAG -+{ -+ rwlock_t sLock; -+ struct list_head sList; -+ -+} PVRSRV_LINUX_EVENT_OBJECT_LIST; -+ -+ -+typedef struct PVRSRV_LINUX_EVENT_OBJECT_TAG -+{ -+ atomic_t sTimeStamp; -+ IMG_UINT32 ui32TimeStampPrevious; -+#if defined(DEBUG) -+ IMG_UINT ui32Stats; -+#endif -+ wait_queue_head_t sWait; -+ struct list_head sList; -+ IMG_HANDLE hResItem; -+ PVRSRV_LINUX_EVENT_OBJECT_LIST *psLinuxEventObjectList; -+} PVRSRV_LINUX_EVENT_OBJECT; -+ -+/*! -+****************************************************************************** -+ -+ @Function LinuxEventObjectListCreate -+ -+ @Description -+ -+ Linux wait object list creation -+ -+ @Output hOSEventKM : Pointer to the event object list handle -+ -+ @Return PVRSRV_ERROR : Error code -+ -+******************************************************************************/ -+PVRSRV_ERROR LinuxEventObjectListCreate(IMG_HANDLE *phEventObjectList) -+{ -+ PVRSRV_LINUX_EVENT_OBJECT_LIST *psEventObjectList; -+ -+ if(OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(PVRSRV_LINUX_EVENT_OBJECT_LIST), -+ (IMG_VOID **)&psEventObjectList, IMG_NULL, -+ "Linux Event Object List") != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectCreate: failed to allocate memory for event list")); -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ -+ INIT_LIST_HEAD(&psEventObjectList->sList); -+ -+ rwlock_init(&psEventObjectList->sLock); -+ -+ *phEventObjectList = (IMG_HANDLE *) psEventObjectList; -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function LinuxEventObjectListDestroy -+ -+ @Description -+ -+ Linux wait object list destruction -+ -+ @Input hOSEventKM : Event object list handle -+ -+ @Return PVRSRV_ERROR : Error code -+ -+******************************************************************************/ -+PVRSRV_ERROR LinuxEventObjectListDestroy(IMG_HANDLE hEventObjectList) -+{ -+ -+ PVRSRV_LINUX_EVENT_OBJECT_LIST *psEventObjectList = (PVRSRV_LINUX_EVENT_OBJECT_LIST *) hEventObjectList ; -+ -+ if(psEventObjectList) -+ { -+ IMG_BOOL bListEmpty; -+ -+ read_lock(&psEventObjectList->sLock); -+ bListEmpty = list_empty(&psEventObjectList->sList); -+ read_unlock(&psEventObjectList->sLock); -+ -+ if (!bListEmpty) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectListDestroy: Event List is not empty")); -+ return PVRSRV_ERROR_UNABLE_TO_DESTROY_EVENT; -+ } -+ -+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(PVRSRV_LINUX_EVENT_OBJECT_LIST), psEventObjectList, IMG_NULL); -+ /*not nulling pointer, copy on stack*/ -+ } -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function LinuxEventObjectDelete -+ -+ @Description -+ -+ Linux wait object removal -+ -+ @Input hOSEventObjectList : Event object list handle -+ @Input hOSEventObject : Event object handle -+ @Input bResManCallback : Called from the resman -+ -+ @Return PVRSRV_ERROR : Error code -+ -+******************************************************************************/ -+PVRSRV_ERROR LinuxEventObjectDelete(IMG_HANDLE hOSEventObjectList, IMG_HANDLE hOSEventObject) -+{ -+ if(hOSEventObjectList) -+ { -+ if(hOSEventObject) -+ { -+ PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject = (PVRSRV_LINUX_EVENT_OBJECT *)hOSEventObject; -+#if defined(DEBUG) -+ PVR_DPF((PVR_DBG_MESSAGE, "LinuxEventObjectListDelete: Event object waits: %u", psLinuxEventObject->ui32Stats)); -+#endif -+ if(ResManFreeResByPtr(psLinuxEventObject->hResItem, CLEANUP_WITH_POLL) != PVRSRV_OK) -+ { -+ return PVRSRV_ERROR_UNABLE_TO_DESTROY_EVENT; -+ } -+ -+ return PVRSRV_OK; -+ } -+ } -+ return PVRSRV_ERROR_UNABLE_TO_DESTROY_EVENT; -+ -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function LinuxEventObjectDeleteCallback -+ -+ @Description -+ -+ Linux wait object removal -+ -+ @Input hOSEventObject : Event object handle -+ -+ @Return PVRSRV_ERROR : Error code -+ -+******************************************************************************/ -+static PVRSRV_ERROR LinuxEventObjectDeleteCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param, IMG_BOOL bForceCleanup) -+{ -+ PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject = pvParam; -+ PVRSRV_LINUX_EVENT_OBJECT_LIST *psLinuxEventObjectList = psLinuxEventObject->psLinuxEventObjectList; -+ unsigned long ulLockFlags; -+ -+ PVR_UNREFERENCED_PARAMETER(ui32Param); -+ PVR_UNREFERENCED_PARAMETER(bForceCleanup); -+ -+ write_lock_irqsave(&psLinuxEventObjectList->sLock, ulLockFlags); -+ list_del(&psLinuxEventObject->sList); -+ write_unlock_irqrestore(&psLinuxEventObjectList->sLock, ulLockFlags); -+ -+#if defined(DEBUG) -+ PVR_DPF((PVR_DBG_MESSAGE, "LinuxEventObjectDeleteCallback: Event object waits: %u", psLinuxEventObject->ui32Stats)); -+#endif -+ -+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(PVRSRV_LINUX_EVENT_OBJECT), psLinuxEventObject, IMG_NULL); -+ /*not nulling pointer, copy on stack*/ -+ -+ return PVRSRV_OK; -+} -+/*! -+****************************************************************************** -+ -+ @Function LinuxEventObjectAdd -+ -+ @Description -+ -+ Linux wait object addition -+ -+ @Input hOSEventObjectList : Event object list handle -+ @Output phOSEventObject : Pointer to the event object handle -+ -+ @Return PVRSRV_ERROR : Error code -+ -+******************************************************************************/ -+PVRSRV_ERROR LinuxEventObjectAdd(IMG_HANDLE hOSEventObjectList, IMG_HANDLE *phOSEventObject) -+ { -+ PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject; -+ PVRSRV_LINUX_EVENT_OBJECT_LIST *psLinuxEventObjectList = (PVRSRV_LINUX_EVENT_OBJECT_LIST*)hOSEventObjectList; -+ IMG_UINT32 ui32PID = OSGetCurrentProcessIDKM(); -+ PVRSRV_PER_PROCESS_DATA *psPerProc; -+ unsigned long ulLockFlags; -+ -+ psPerProc = PVRSRVPerProcessData(ui32PID); -+ if (psPerProc == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectAdd: Couldn't find per-process data")); -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ -+ /* allocate completion variable */ -+ if(OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(PVRSRV_LINUX_EVENT_OBJECT), -+ (IMG_VOID **)&psLinuxEventObject, IMG_NULL, -+ "Linux Event Object") != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectAdd: failed to allocate memory ")); -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ -+ INIT_LIST_HEAD(&psLinuxEventObject->sList); -+ -+ atomic_set(&psLinuxEventObject->sTimeStamp, 0); -+ psLinuxEventObject->ui32TimeStampPrevious = 0; -+ -+#if defined(DEBUG) -+ psLinuxEventObject->ui32Stats = 0; -+#endif -+ init_waitqueue_head(&psLinuxEventObject->sWait); -+ -+ psLinuxEventObject->psLinuxEventObjectList = psLinuxEventObjectList; -+ -+ psLinuxEventObject->hResItem = ResManRegisterRes(psPerProc->hResManContext, -+ RESMAN_TYPE_EVENT_OBJECT, -+ psLinuxEventObject, -+ 0, -+ &LinuxEventObjectDeleteCallback); -+ -+ write_lock_irqsave(&psLinuxEventObjectList->sLock, ulLockFlags); -+ list_add(&psLinuxEventObject->sList, &psLinuxEventObjectList->sList); -+ write_unlock_irqrestore(&psLinuxEventObjectList->sLock, ulLockFlags); -+ -+ *phOSEventObject = psLinuxEventObject; -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function LinuxEventObjectSignal -+ -+ @Description -+ -+ Linux wait object signaling function -+ -+ @Input hOSEventObjectList : Event object list handle -+ -+ @Return PVRSRV_ERROR : Error code -+ -+******************************************************************************/ -+PVRSRV_ERROR LinuxEventObjectSignal(IMG_HANDLE hOSEventObjectList) -+{ -+ PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject; -+ PVRSRV_LINUX_EVENT_OBJECT_LIST *psLinuxEventObjectList = (PVRSRV_LINUX_EVENT_OBJECT_LIST*)hOSEventObjectList; -+ struct list_head *psListEntry, *psList; -+ -+ psList = &psLinuxEventObjectList->sList; -+ -+ /* -+ * We don't take the write lock in interrupt context, so we don't -+ * need to use read_lock_irqsave. -+ */ -+ read_lock(&psLinuxEventObjectList->sLock); -+ list_for_each(psListEntry, psList) -+ { -+ -+ psLinuxEventObject = (PVRSRV_LINUX_EVENT_OBJECT *)list_entry(psListEntry, PVRSRV_LINUX_EVENT_OBJECT, sList); -+ -+ atomic_inc(&psLinuxEventObject->sTimeStamp); -+ wake_up_interruptible(&psLinuxEventObject->sWait); -+ } -+ read_unlock(&psLinuxEventObjectList->sLock); -+ -+ return PVRSRV_OK; -+ -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function LinuxEventObjectWait -+ -+ @Description -+ -+ Linux wait object routine -+ -+ @Input hOSEventObject : Event object handle -+ -+ @Input ui32MSTimeout : Time out value in msec -+ -+ @Return PVRSRV_ERROR : Error code -+ -+******************************************************************************/ -+PVRSRV_ERROR LinuxEventObjectWait(IMG_HANDLE hOSEventObject, IMG_UINT32 ui32MSTimeout) -+{ -+ IMG_UINT32 ui32TimeStamp; -+ DEFINE_WAIT(sWait); -+ -+ PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject = (PVRSRV_LINUX_EVENT_OBJECT *) hOSEventObject; -+ -+ IMG_UINT32 ui32TimeOutJiffies = msecs_to_jiffies(ui32MSTimeout); -+ -+ do -+ { -+ prepare_to_wait(&psLinuxEventObject->sWait, &sWait, TASK_INTERRUPTIBLE); -+ ui32TimeStamp = (IMG_UINT32)atomic_read(&psLinuxEventObject->sTimeStamp); -+ -+ if(psLinuxEventObject->ui32TimeStampPrevious != ui32TimeStamp) -+ { -+ break; -+ } -+ -+ LinuxUnLockMutex(&gPVRSRVLock); -+ -+ ui32TimeOutJiffies = (IMG_UINT32)schedule_timeout((IMG_INT32)ui32TimeOutJiffies); -+ -+ LinuxLockMutexNested(&gPVRSRVLock, PVRSRV_LOCK_CLASS_BRIDGE); -+#if defined(DEBUG) -+ psLinuxEventObject->ui32Stats++; -+#endif -+ -+ -+ } while (ui32TimeOutJiffies); -+ -+ finish_wait(&psLinuxEventObject->sWait, &sWait); -+ -+ psLinuxEventObject->ui32TimeStampPrevious = ui32TimeStamp; -+ -+ return ui32TimeOutJiffies ? PVRSRV_OK : PVRSRV_ERROR_TIMEOUT; -+ -+} -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/event.h b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/event.h -new file mode 100644 -index 0000000..f4a4ec6 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/event.h -@@ -0,0 +1,48 @@ -+/*************************************************************************/ /*! -+@Title Event Object -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+ -+PVRSRV_ERROR LinuxEventObjectListCreate(IMG_HANDLE *phEventObjectList); -+PVRSRV_ERROR LinuxEventObjectListDestroy(IMG_HANDLE hEventObjectList); -+PVRSRV_ERROR LinuxEventObjectAdd(IMG_HANDLE hOSEventObjectList, IMG_HANDLE *phOSEventObject); -+PVRSRV_ERROR LinuxEventObjectDelete(IMG_HANDLE hOSEventObjectList, IMG_HANDLE hOSEventObject); -+PVRSRV_ERROR LinuxEventObjectSignal(IMG_HANDLE hOSEventObjectList); -+PVRSRV_ERROR LinuxEventObjectWait(IMG_HANDLE hOSEventObject, IMG_UINT32 ui32MSTimeout); -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/ion.c b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/ion.c -new file mode 100644 -index 0000000..2b7e955 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/ion.c -@@ -0,0 +1,423 @@ -+/*************************************************************************/ /*! -+@Title Ion driver inter-operability code. -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#include "ion.h" -+ -+/* Three possible configurations: -+ * -+ * - !SUPPORT_ION && CONFIG_ION_OMAP -+ * This is ion inter-op, not real ion support. -+ * -+ * - SUPPORT_ION && CONFIG_ION_OMAP -+ * Real ion support, but sharing with an SOC ion device. We need -+ * to co-share the heaps too. -+ * -+ * - SUPPORT_ION && !CONFIG_ION_OMAP -+ * "Reference" ion implementation. Creates its own ion device -+ * and heaps for the driver to use. -+ */ -+ -+#if !defined(SUPPORT_ION) && defined(CONFIG_ION_OMAP) -+ -+/* Legacy ion inter-op mode */ -+ -+#include "services.h" -+#include "servicesint.h" -+#include "mutex.h" -+#include "lock.h" -+#include "mm.h" -+#include "handle.h" -+#include "perproc.h" -+#include "env_perproc.h" -+#include "private_data.h" -+#include "pvr_debug.h" -+ -+#include <linux/module.h> -+#include <linux/file.h> -+#include <linux/fs.h> -+ -+extern struct ion_client *gpsIONClient; -+ -+void PVRSRVExportFDToIONHandles(int fd, struct ion_client **client, -+ struct ion_handle *handles[2]) -+{ -+ PVRSRV_FILE_PRIVATE_DATA *psPrivateData; -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; -+ LinuxMemArea *psLinuxMemArea; -+ PVRSRV_ERROR eError; -+ struct file *psFile; -+ -+ /* Take the bridge mutex so the handle won't be freed underneath us */ -+ LinuxLockMutexNested(&gPVRSRVLock, PVRSRV_LOCK_CLASS_BRIDGE); -+ -+ psFile = fget(fd); -+ if(!psFile) -+ goto err_unlock; -+ -+ psPrivateData = psFile->private_data; -+ if(!psPrivateData) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: struct file* has no private_data; " -+ "invalid export handle", __func__)); -+ goto err_fput; -+ } -+ -+ eError = PVRSRVLookupHandle(KERNEL_HANDLE_BASE, -+ (IMG_PVOID *)&psKernelMemInfo, -+ psPrivateData->hKernelMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO); -+ if(eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: Failed to look up MEM_INFO handle", -+ __func__)); -+ goto err_fput; -+ } -+ -+ psLinuxMemArea = (LinuxMemArea *)psKernelMemInfo->sMemBlk.hOSMemHandle; -+ BUG_ON(psLinuxMemArea == IMG_NULL); -+ -+ if(psLinuxMemArea->eAreaType != LINUX_MEM_AREA_ION) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: Valid handle, but not an ION buffer", -+ __func__)); -+ goto err_fput; -+ } -+ -+ handles[0] = psLinuxMemArea->uData.sIONTilerAlloc.psIONHandle[0]; -+ handles[1] = psLinuxMemArea->uData.sIONTilerAlloc.psIONHandle[1]; -+ if(client) -+ *client = gpsIONClient; -+ -+err_fput: -+ fput(psFile); -+err_unlock: -+ /* Allow PVRSRV clients to communicate with srvkm again */ -+ LinuxUnLockMutex(&gPVRSRVLock); -+} -+ -+struct ion_handle * -+PVRSRVExportFDToIONHandle(int fd, struct ion_client **client) -+{ -+ struct ion_handle *psHandles[2] = { IMG_NULL, IMG_NULL }; -+ PVRSRVExportFDToIONHandles(fd, client, psHandles); -+ return psHandles[0]; -+} -+ -+EXPORT_SYMBOL(PVRSRVExportFDToIONHandles); -+EXPORT_SYMBOL(PVRSRVExportFDToIONHandle); -+ -+#endif /* !defined(SUPPORT_ION) && defined(CONFIG_ION_OMAP) */ -+ -+#if defined(SUPPORT_ION) -+ -+#include <linux/scatterlist.h> -+#include <linux/kernel.h> -+#include <linux/slab.h> -+#include <linux/err.h> -+ -+#if defined(CONFIG_ION_OMAP) -+ -+/* Real ion with sharing */ -+ -+extern struct ion_device *omap_ion_device; -+struct ion_device *gpsIonDev; -+ -+PVRSRV_ERROR IonInit(IMG_VOID) -+{ -+ gpsIonDev = omap_ion_device; -+ return PVRSRV_OK; -+} -+ -+IMG_VOID IonDeinit(IMG_VOID) -+{ -+ gpsIonDev = IMG_NULL; -+} -+ -+#else /* defined(CONFIG_ION_OMAP) */ -+ -+/* "Reference" ion implementation */ -+ -+#include "../drivers/gpu/ion/ion_priv.h" -+ -+static struct ion_heap **gapsIonHeaps; -+struct ion_device *gpsIonDev; -+ -+static struct ion_platform_data gsGenericConfig = -+{ -+ .nr = 2, -+ .heaps = -+ { -+ { -+ .type = ION_HEAP_TYPE_SYSTEM_CONTIG, -+ .name = "System contig", -+ .id = ION_HEAP_TYPE_SYSTEM_CONTIG, -+ }, -+ { -+ .type = ION_HEAP_TYPE_SYSTEM, -+ .name = "System", -+ .id = ION_HEAP_TYPE_SYSTEM, -+ } -+ } -+}; -+ -+PVRSRV_ERROR IonInit(IMG_VOID) -+{ -+ int uiHeapCount = gsGenericConfig.nr; -+ int uiError; -+ int i; -+ -+ gapsIonHeaps = kzalloc(sizeof(struct ion_heap *) * uiHeapCount, GFP_KERNEL); -+ /* Create the ion devicenode */ -+ gpsIonDev = ion_device_create(NULL); -+ if (IS_ERR_OR_NULL(gpsIonDev)) { -+ kfree(gapsIonHeaps); -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ -+ /* Register all the heaps */ -+ for (i = 0; i < gsGenericConfig.nr; i++) -+ { -+ struct ion_platform_heap *psPlatHeapData = &gsGenericConfig.heaps[i]; -+ -+ gapsIonHeaps[i] = ion_heap_create(psPlatHeapData); -+ if (IS_ERR_OR_NULL(gapsIonHeaps[i])) -+ { -+ uiError = PTR_ERR(gapsIonHeaps[i]); -+ goto failHeapCreate; -+ } -+ ion_device_add_heap(gpsIonDev, gapsIonHeaps[i]); -+ } -+ -+ return PVRSRV_OK; -+failHeapCreate: -+ for (i = 0; i < uiHeapCount; i++) -+ { -+ if (gapsIonHeaps[i]) -+ { -+ ion_heap_destroy(gapsIonHeaps[i]); -+ } -+ } -+ kfree(gapsIonHeaps); -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+} -+ -+IMG_VOID IonDeinit(IMG_VOID) -+{ -+ int uiHeapCount = gsGenericConfig.nr; -+ int i; -+ -+ for (i = 0; i < uiHeapCount; i++) -+ { -+ if (gapsIonHeaps[i]) -+ { -+ ion_heap_destroy(gapsIonHeaps[i]); -+ } -+ } -+ kfree(gapsIonHeaps); -+ ion_device_destroy(gpsIonDev); -+} -+ -+#endif /* defined(CONFIG_ION_OMAP) */ -+ -+#define MAX_IMPORT_ION_FDS 3 -+ -+typedef struct _ION_IMPORT_DATA_ -+{ -+ /* ion client handles are imported into */ -+ struct ion_client *psIonClient; -+ -+ /* Number of ion handles represented by this import */ -+ IMG_UINT32 ui32NumIonHandles; -+ -+ /* Array of ion handles in use by services */ -+ struct ion_handle *apsIonHandle[MAX_IMPORT_ION_FDS]; -+ -+ /* Array of physical addresses represented by these buffers */ -+ IMG_SYS_PHYADDR *psSysPhysAddr; -+ -+ /* If ui32NumBuffers is 1 and ion_map_kernel() is implemented by the -+ * allocator, this may be non-NULL. Otherwise it will be NULL. -+ */ -+ IMG_PVOID pvKernAddr0; -+} -+ION_IMPORT_DATA; -+ -+PVRSRV_ERROR IonImportBufferAndAcquirePhysAddr(IMG_HANDLE hIonDev, -+ IMG_UINT32 ui32NumFDs, -+ IMG_INT32 *pai32BufferFDs, -+ IMG_UINT32 *pui32PageCount, -+ IMG_SYS_PHYADDR **ppsSysPhysAddr, -+ IMG_PVOID *ppvKernAddr0, -+ IMG_HANDLE *phPriv, -+ IMG_HANDLE *phUnique) -+{ -+ struct scatterlist *psTemp, *psScatterList[MAX_IMPORT_ION_FDS] = {}; -+ PVRSRV_ERROR eError = PVRSRV_ERROR_OUT_OF_MEMORY; -+ struct ion_client *psIonClient = hIonDev; -+ IMG_UINT32 i, k, ui32PageCount = 0; -+ ION_IMPORT_DATA *psImportData; -+ -+ if(ui32NumFDs > MAX_IMPORT_ION_FDS) -+ { -+ printk(KERN_ERR "%s: More ion export fds passed in than supported " -+ "(%d provided, %d max)", __func__, ui32NumFDs, -+ MAX_IMPORT_ION_FDS); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ psImportData = kzalloc(sizeof(ION_IMPORT_DATA), GFP_KERNEL); -+ if (psImportData == NULL) -+ { -+ goto exitFailKMallocImportData; -+ } -+ -+ /* Set up import data for free call */ -+ psImportData->psIonClient = psIonClient; -+ psImportData->ui32NumIonHandles = ui32NumFDs; -+ -+ for(i = 0; i < ui32NumFDs; i++) -+ { -+ int fd = (int)pai32BufferFDs[i]; -+ -+ psImportData->apsIonHandle[i] = ion_import_fd(psIonClient, fd); -+ if (psImportData->apsIonHandle[i] == IMG_NULL) -+ { -+ eError = PVRSRV_ERROR_BAD_MAPPING; -+ goto exitFailImport; -+ } -+ -+ psScatterList[i] = ion_map_dma(psIonClient, psImportData->apsIonHandle[i]); -+ if (psScatterList[i] == NULL) -+ { -+ eError = PVRSRV_ERROR_INVALID_PARAMS; -+ goto exitFailImport; -+ } -+ -+ for(psTemp = psScatterList[i]; psTemp; psTemp = sg_next(psTemp)) -+ { -+ IMG_UINT32 j; -+ for (j = 0; j < psTemp->length; j += PAGE_SIZE) -+ { -+ ui32PageCount++; -+ } -+ } -+ } -+ -+ BUG_ON(ui32PageCount == 0); -+ -+ psImportData->psSysPhysAddr = kmalloc(sizeof(IMG_SYS_PHYADDR) * ui32PageCount, GFP_KERNEL); -+ if (psImportData->psSysPhysAddr == NULL) -+ { -+ goto exitFailImport; -+ } -+ -+ for(i = 0, k = 0; i < ui32NumFDs; i++) -+ { -+ for(psTemp = psScatterList[i]; psTemp; psTemp = sg_next(psTemp)) -+ { -+ IMG_UINT32 j; -+ for (j = 0; j < psTemp->length; j += PAGE_SIZE) -+ { -+ psImportData->psSysPhysAddr[k].uiAddr = sg_phys(psTemp) + j; -+ k++; -+ } -+ } -+ } -+ -+ *pui32PageCount = ui32PageCount; -+ *ppsSysPhysAddr = psImportData->psSysPhysAddr; -+ -+ if(ui32NumFDs == 1) -+ { -+ IMG_PVOID pvKernAddr0; -+ -+ pvKernAddr0 = ion_map_kernel(psIonClient, psImportData->apsIonHandle[0]); -+ if (IS_ERR(pvKernAddr0)) -+ { -+ pvKernAddr0 = IMG_NULL; -+ } -+ -+ psImportData->pvKernAddr0 = pvKernAddr0; -+ *ppvKernAddr0 = pvKernAddr0; -+ } -+ else -+ { -+ *ppvKernAddr0 = NULL; -+ } -+ -+ *phPriv = psImportData; -+ *phUnique = (IMG_HANDLE)psImportData->psSysPhysAddr[0].uiAddr; -+ -+ return PVRSRV_OK; -+ -+exitFailImport: -+ for(i = 0; psImportData->apsIonHandle[i] != NULL; i++) -+ { -+ if(psScatterList[i]) -+ ion_unmap_dma(psIonClient, psImportData->apsIonHandle[i]); -+ ion_free(psIonClient, psImportData->apsIonHandle[i]); -+ } -+ kfree(psImportData); -+exitFailKMallocImportData: -+ return eError; -+} -+ -+IMG_VOID IonUnimportBufferAndReleasePhysAddr(IMG_HANDLE hPriv) -+{ -+ ION_IMPORT_DATA *psImportData = hPriv; -+ IMG_UINT32 i; -+ -+ if (psImportData->pvKernAddr0) -+ { -+ ion_unmap_kernel(psImportData->psIonClient, psImportData->apsIonHandle[0]); -+ } -+ -+ for(i = 0; i < psImportData->ui32NumIonHandles; i++) -+ { -+ ion_unmap_dma(psImportData->psIonClient, psImportData->apsIonHandle[i]); -+ ion_free(psImportData->psIonClient, psImportData->apsIonHandle[i]); -+ } -+ -+ kfree(psImportData->psSysPhysAddr); -+ kfree(psImportData); -+} -+ -+#endif /* defined(SUPPORT_ION) */ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/ion.h b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/ion.h -new file mode 100644 -index 0000000..ba55a93 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/ion.h -@@ -0,0 +1,83 @@ -+/*************************************************************************/ /*! -+@Title Ion driver inter-operability code. -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#ifndef __IMG_LINUX_ION_H__ -+#define __IMG_LINUX_ION_H__ -+ -+#include <linux/ion.h> -+#if defined (CONFIG_ION_OMAP) -+#include <linux/omap_ion.h> -+#endif -+#if defined (SUPPORT_ION) -+#include "img_types.h" -+#include "servicesext.h" -+#endif -+ -+#if !defined(SUPPORT_ION) && defined(CONFIG_ION_OMAP) -+ -+void PVRSRVExportFDToIONHandles(int fd, struct ion_client **client, -+ struct ion_handle *handles[2]); -+ -+struct ion_handle *PVRSRVExportFDToIONHandle(int fd, -+ struct ion_client **client); -+ -+#endif /* !defined(SUPPORT_ION) && defined(CONFIG_ION_OMAP) */ -+ -+#if defined(SUPPORT_ION) -+ -+PVRSRV_ERROR IonInit(IMG_VOID); -+ -+IMG_VOID IonDeinit(IMG_VOID); -+ -+PVRSRV_ERROR IonImportBufferAndAcquirePhysAddr(IMG_HANDLE hIonDev, -+ IMG_UINT32 ui32NumFDs, -+ IMG_INT32 *pi32BufferFDs, -+ IMG_UINT32 *pui32PageCount, -+ IMG_SYS_PHYADDR **ppsSysPhysAddr, -+ IMG_PVOID *ppvKernAddr0, -+ IMG_HANDLE *phPriv, -+ IMG_HANDLE *phUnique); -+ -+IMG_VOID IonUnimportBufferAndReleasePhysAddr(IMG_HANDLE hPriv); -+ -+#endif /* defined(SUPPORT_ION) */ -+ -+#endif /* __IMG_LINUX_ION_H__ */ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/linkage.h b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/linkage.h -new file mode 100644 -index 0000000..55cd4f0 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/linkage.h -@@ -0,0 +1,72 @@ -+/*************************************************************************/ /*! -+@Title Linux specific Services code internal interfaces -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Interfaces between various parts of the Linux specific -+ Services code, that don't have any other obvious -+ header file to go into. -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+#ifndef __LINKAGE_H__ -+#define __LINKAGE_H__ -+ -+#if !defined(SUPPORT_DRI_DRM) -+long PVRSRV_BridgeDispatchKM(struct file *file, unsigned int cmd, unsigned long arg); -+#endif -+ -+IMG_VOID PVRDPFInit(IMG_VOID); -+PVRSRV_ERROR PVROSFuncInit(IMG_VOID); -+IMG_VOID PVROSFuncDeInit(IMG_VOID); -+ -+#ifdef DEBUG -+ -+IMG_INT PVRDebugProcSetLevel(struct file *file, const IMG_CHAR *buffer, IMG_UINT32 count, IMG_VOID *data); -+void ProcSeqShowDebugLevel(struct seq_file *sfile,void* el); -+ -+#ifdef PVR_MANUAL_POWER_CONTROL -+IMG_INT PVRProcSetPowerLevel(struct file *file, const IMG_CHAR *buffer, IMG_UINT32 count, IMG_VOID *data); -+ -+void ProcSeqShowPowerLevel(struct seq_file *sfile,void* el); -+ -+#endif /* PVR_MANUAL_POWER_CONTROL */ -+ -+#endif /* DEBUG */ -+ -+#endif /* __LINKAGE_H__ */ -+/***************************************************************************** -+ End of file (linkage.h) -+*****************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/lock.h b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/lock.h -new file mode 100644 -index 0000000..11adcaa ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/lock.h -@@ -0,0 +1,56 @@ -+/*************************************************************************/ /*! -+@Title Main driver lock -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description The main driver lock, held in most places in -+ the driver. -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+#ifndef __LOCK_H__ -+#define __LOCK_H__ -+ -+/* -+ * Main driver lock, used to ensure driver code is single threaded. -+ * There are some places where this lock must not be taken, such as -+ * in the mmap related deriver entry points. -+ */ -+extern PVRSRV_LINUX_MUTEX gPVRSRVLock; -+ -+#endif /* __LOCK_H__ */ -+/***************************************************************************** -+ End of file (lock.h) -+*****************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/mm.c b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/mm.c -new file mode 100644 -index 0000000..cf00137 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/mm.c -@@ -0,0 +1,2868 @@ -+/*************************************************************************/ /*! -+@Title Misc memory management utility functions for Linux -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#include <linux/version.h> -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)) -+#ifndef AUTOCONF_INCLUDED -+#include <linux/config.h> -+#endif -+#endif -+ -+#if !defined(PVR_LINUX_MEM_AREA_POOL_MAX_PAGES) -+#define PVR_LINUX_MEM_AREA_POOL_MAX_PAGES 0 -+#endif -+ -+#include <linux/kernel.h> -+#include <asm/atomic.h> -+#include <linux/list.h> -+#include <linux/mutex.h> -+#include <linux/mm.h> -+#include <linux/vmalloc.h> -+#include <asm/io.h> -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) -+#include <linux/wrapper.h> -+#endif -+#include <linux/slab.h> -+#include <linux/highmem.h> -+#include <linux/sched.h> -+ -+#if defined(PVR_LINUX_MEM_AREA_POOL_ALLOW_SHRINK) -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0)) -+#include <linux/shrinker.h> -+#endif -+#endif -+ -+#include "img_defs.h" -+#include "services.h" -+#include "servicesint.h" -+#include "syscommon.h" -+#include "mutils.h" -+#include "mm.h" -+#include "pvrmmap.h" -+#include "mmap.h" -+#include "osfunc.h" -+#include "pvr_debug.h" -+#include "proc.h" -+#include "mutex.h" -+#include "lock.h" -+ -+#if defined(DEBUG_LINUX_MEM_AREAS) || defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -+ #include "lists.h" -+#endif -+ -+/* Decide whether or not DevMem allocs need __GFP_DMA32 */ -+#ifndef SGX_FEATURE_36BIT_MMU -+# ifdef CONFIG_ZONE_DMA32 -+# if defined CONFIG_X86_PAE || defined CONFIG_ARM_LPAE || defined CONFIG_64BIT -+# define PVR_USE_DMA32_FOR_DEVMEM_ALLOCS -+# endif -+# endif -+#endif -+ -+/* -+ * The page pool entry count is an atomic int so that the shrinker function -+ * can return it even when we can't take the lock that protects the page pool -+ * list. -+ */ -+static atomic_t g_sPagePoolEntryCount = ATOMIC_INIT(0); -+ -+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -+typedef enum { -+ DEBUG_MEM_ALLOC_TYPE_KMALLOC, -+ DEBUG_MEM_ALLOC_TYPE_VMALLOC, -+ DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES, -+ DEBUG_MEM_ALLOC_TYPE_IOREMAP, -+ DEBUG_MEM_ALLOC_TYPE_IO, -+ DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE, -+ DEBUG_MEM_ALLOC_TYPE_ION, -+#if defined(PVR_LINUX_MEM_AREA_USE_VMAP) -+ DEBUG_MEM_ALLOC_TYPE_VMAP, -+#endif -+ DEBUG_MEM_ALLOC_TYPE_COUNT -+} DEBUG_MEM_ALLOC_TYPE; -+ -+typedef struct _DEBUG_MEM_ALLOC_REC -+{ -+ DEBUG_MEM_ALLOC_TYPE eAllocType; -+ IMG_UINTPTR_T uiKey; /* Some unique value (private to the eAllocType) */ -+ IMG_VOID *pvCpuVAddr; -+ IMG_CPU_PHYADDR sCpuPAddr; -+ IMG_VOID *pvPrivateData; -+ IMG_SIZE_T uiBytes; -+ pid_t pid; -+ IMG_CHAR *pszFileName; -+ IMG_UINT32 ui32Line; -+ -+ struct _DEBUG_MEM_ALLOC_REC *psNext; -+ struct _DEBUG_MEM_ALLOC_REC **ppsThis; -+} DEBUG_MEM_ALLOC_REC; -+ -+static IMPLEMENT_LIST_ANY_VA_2(DEBUG_MEM_ALLOC_REC, IMG_BOOL, IMG_FALSE) -+static IMPLEMENT_LIST_ANY_VA(DEBUG_MEM_ALLOC_REC) -+static IMPLEMENT_LIST_FOR_EACH(DEBUG_MEM_ALLOC_REC) -+static IMPLEMENT_LIST_INSERT(DEBUG_MEM_ALLOC_REC) -+static IMPLEMENT_LIST_REMOVE(DEBUG_MEM_ALLOC_REC) -+ -+ -+static DEBUG_MEM_ALLOC_REC *g_MemoryRecords; -+ -+static IMG_UINT32 g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_COUNT]; -+static IMG_UINT32 g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_COUNT]; -+ -+/* vmalloc + kmalloc + alloc_pages + kmem_cache */ -+static IMG_UINT32 g_SysRAMWaterMark; /* Doesn't include page pool */ -+static IMG_UINT32 g_SysRAMHighWaterMark; /* *DOES* include page pool */ -+ -+static inline IMG_UINT32 -+SysRAMTrueWaterMark(void) -+{ -+ return g_SysRAMWaterMark + PAGES_TO_BYTES(atomic_read(&g_sPagePoolEntryCount)); -+} -+ -+/* ioremap + io */ -+static IMG_UINT32 g_IOMemWaterMark; -+static IMG_UINT32 g_IOMemHighWaterMark; -+ -+static IMG_VOID DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE eAllocType, -+ IMG_UINTPTR_T uiKey, -+ IMG_VOID *pvCpuVAddr, -+ IMG_CPU_PHYADDR sCpuPAddr, -+ IMG_VOID *pvPrivateData, -+ IMG_SIZE_T uiBytes, -+ IMG_CHAR *pszFileName, -+ IMG_UINT32 ui32Line); -+ -+static IMG_VOID DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE eAllocType, IMG_UINTPTR_T uiKey, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line); -+ -+static IMG_CHAR *DebugMemAllocRecordTypeToString(DEBUG_MEM_ALLOC_TYPE eAllocType); -+ -+ -+static struct proc_dir_entry *g_SeqFileMemoryRecords; -+static void* ProcSeqNextMemoryRecords(struct seq_file *sfile,void* el,loff_t off); -+static void ProcSeqShowMemoryRecords(struct seq_file *sfile,void* el); -+static void* ProcSeqOff2ElementMemoryRecords(struct seq_file * sfile, loff_t off); -+ -+#endif -+ -+ -+#if defined(DEBUG_LINUX_MEM_AREAS) -+typedef struct _DEBUG_LINUX_MEM_AREA_REC -+{ -+ LinuxMemArea *psLinuxMemArea; -+ IMG_UINT32 ui32Flags; -+ pid_t pid; -+ -+ struct _DEBUG_LINUX_MEM_AREA_REC *psNext; -+ struct _DEBUG_LINUX_MEM_AREA_REC **ppsThis; -+}DEBUG_LINUX_MEM_AREA_REC; -+ -+ -+static IMPLEMENT_LIST_ANY_VA(DEBUG_LINUX_MEM_AREA_REC) -+static IMPLEMENT_LIST_FOR_EACH(DEBUG_LINUX_MEM_AREA_REC) -+static IMPLEMENT_LIST_INSERT(DEBUG_LINUX_MEM_AREA_REC) -+static IMPLEMENT_LIST_REMOVE(DEBUG_LINUX_MEM_AREA_REC) -+ -+ -+ -+ -+static DEBUG_LINUX_MEM_AREA_REC *g_LinuxMemAreaRecords; -+static IMG_UINT32 g_LinuxMemAreaCount; -+static IMG_UINT32 g_LinuxMemAreaWaterMark; -+static IMG_UINT32 g_LinuxMemAreaHighWaterMark; -+ -+ -+static struct proc_dir_entry *g_SeqFileMemArea; -+ -+static void* ProcSeqNextMemArea(struct seq_file *sfile,void* el,loff_t off); -+static void ProcSeqShowMemArea(struct seq_file *sfile,void* el); -+static void* ProcSeqOff2ElementMemArea(struct seq_file *sfile, loff_t off); -+ -+#endif -+ -+#if defined(DEBUG_LINUX_MEM_AREAS) || defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -+static PVRSRV_LINUX_MUTEX g_sDebugMutex; -+#endif -+ -+#if (defined(DEBUG_LINUX_MEM_AREAS) || defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)) -+static void ProcSeqStartstopDebugMutex(struct seq_file *sfile,IMG_BOOL start); -+#endif -+ -+typedef struct -+{ -+ /* Linkage for page pool LRU list */ -+ struct list_head sPagePoolItem; -+ -+ struct page *psPage; -+} LinuxPagePoolEntry; -+ -+static LinuxKMemCache *g_PsLinuxMemAreaCache; -+static LinuxKMemCache *g_PsLinuxPagePoolCache; -+ -+static LIST_HEAD(g_sPagePoolList); -+static int g_iPagePoolMaxEntries; -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)) -+static IMG_VOID ReservePages(IMG_VOID *pvAddress, IMG_SIZE_T uiLength); -+static IMG_VOID UnreservePages(IMG_VOID *pvAddress, IMG_SIZE_T uiLength); -+#endif -+ -+static LinuxMemArea *LinuxMemAreaStructAlloc(IMG_VOID); -+static IMG_VOID LinuxMemAreaStructFree(LinuxMemArea *psLinuxMemArea); -+#if defined(DEBUG_LINUX_MEM_AREAS) -+static IMG_VOID DebugLinuxMemAreaRecordAdd(LinuxMemArea *psLinuxMemArea, IMG_UINT32 ui32Flags); -+static DEBUG_LINUX_MEM_AREA_REC *DebugLinuxMemAreaRecordFind(LinuxMemArea *psLinuxMemArea); -+static IMG_VOID DebugLinuxMemAreaRecordRemove(LinuxMemArea *psLinuxMemArea); -+#endif -+ -+ -+static inline IMG_BOOL -+AreaIsUncached(IMG_UINT32 ui32AreaFlags) -+{ -+ return (ui32AreaFlags & (PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_UNCACHED)) != 0; -+} -+ -+static inline IMG_BOOL -+CanFreeToPool(LinuxMemArea *psLinuxMemArea) -+{ -+ return AreaIsUncached(psLinuxMemArea->ui32AreaFlags) && !psLinuxMemArea->bNeedsCacheInvalidate; -+} -+ -+IMG_VOID * -+_KMallocWrapper(IMG_SIZE_T uiByteSize, gfp_t uFlags, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line) -+{ -+ IMG_VOID *pvRet; -+ pvRet = kmalloc(uiByteSize, uFlags); -+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -+ if (pvRet) -+ { -+ IMG_CPU_PHYADDR sCpuPAddr; -+ sCpuPAddr.uiAddr = 0; -+ -+ DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_KMALLOC, -+ (IMG_UINTPTR_T)pvRet, -+ pvRet, -+ sCpuPAddr, -+ NULL, -+ uiByteSize, -+ pszFileName, -+ ui32Line -+ ); -+ } -+#else -+ PVR_UNREFERENCED_PARAMETER(pszFileName); -+ PVR_UNREFERENCED_PARAMETER(ui32Line); -+#endif -+ return pvRet; -+} -+ -+ -+IMG_VOID -+_KFreeWrapper(IMG_VOID *pvCpuVAddr, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line) -+{ -+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -+ DebugMemAllocRecordRemove( -+ DEBUG_MEM_ALLOC_TYPE_KMALLOC, -+ (IMG_UINTPTR_T)pvCpuVAddr, -+ pszFileName, -+ ui32Line); -+#else -+ PVR_UNREFERENCED_PARAMETER(pszFileName); -+ PVR_UNREFERENCED_PARAMETER(ui32Line); -+#endif -+ kfree(pvCpuVAddr); -+} -+ -+ -+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -+static IMG_VOID -+DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE eAllocType, -+ IMG_UINTPTR_T uiKey, -+ IMG_VOID *pvCpuVAddr, -+ IMG_CPU_PHYADDR sCpuPAddr, -+ IMG_VOID *pvPrivateData, -+ IMG_SIZE_T uiBytes, -+ IMG_CHAR *pszFileName, -+ IMG_UINT32 ui32Line) -+{ -+ DEBUG_MEM_ALLOC_REC *psRecord; -+ -+ LinuxLockMutexNested(&g_sDebugMutex, PVRSRV_LOCK_CLASS_MM_DEBUG); -+ -+ psRecord = kmalloc(sizeof(DEBUG_MEM_ALLOC_REC), GFP_KERNEL); -+ -+ psRecord->eAllocType = eAllocType; -+ psRecord->uiKey = uiKey; -+ psRecord->pvCpuVAddr = pvCpuVAddr; -+ psRecord->sCpuPAddr.uiAddr = sCpuPAddr.uiAddr; -+ psRecord->pvPrivateData = pvPrivateData; -+ psRecord->pid = OSGetCurrentProcessIDKM(); -+ psRecord->uiBytes = uiBytes; -+ psRecord->pszFileName = pszFileName; -+ psRecord->ui32Line = ui32Line; -+ -+ List_DEBUG_MEM_ALLOC_REC_Insert(&g_MemoryRecords, psRecord); -+ -+ g_WaterMarkData[eAllocType] += uiBytes; -+ if (g_WaterMarkData[eAllocType] > g_HighWaterMarkData[eAllocType]) -+ { -+ g_HighWaterMarkData[eAllocType] = g_WaterMarkData[eAllocType]; -+ } -+ -+ if (eAllocType == DEBUG_MEM_ALLOC_TYPE_KMALLOC -+ || eAllocType == DEBUG_MEM_ALLOC_TYPE_VMALLOC -+ || eAllocType == DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES -+ || eAllocType == DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE) -+ { -+ IMG_SIZE_T uSysRAMTrueWaterMark; -+ -+ g_SysRAMWaterMark += uiBytes; -+ uSysRAMTrueWaterMark = SysRAMTrueWaterMark(); -+ -+ if (uSysRAMTrueWaterMark > g_SysRAMHighWaterMark) -+ { -+ g_SysRAMHighWaterMark = uSysRAMTrueWaterMark; -+ } -+ } -+ else if (eAllocType == DEBUG_MEM_ALLOC_TYPE_IOREMAP -+ || eAllocType == DEBUG_MEM_ALLOC_TYPE_IO) -+ { -+ g_IOMemWaterMark += uiBytes; -+ if (g_IOMemWaterMark > g_IOMemHighWaterMark) -+ { -+ g_IOMemHighWaterMark = g_IOMemWaterMark; -+ } -+ } -+ -+ LinuxUnLockMutex(&g_sDebugMutex); -+} -+ -+ -+static IMG_BOOL DebugMemAllocRecordRemove_AnyVaCb(DEBUG_MEM_ALLOC_REC *psCurrentRecord, va_list va) -+{ -+ DEBUG_MEM_ALLOC_TYPE eAllocType; -+ IMG_UINTPTR_T uiKey; -+ -+ eAllocType = va_arg(va, DEBUG_MEM_ALLOC_TYPE); -+ uiKey = va_arg(va, IMG_UINTPTR_T); -+ -+ if (psCurrentRecord->eAllocType == eAllocType -+ && psCurrentRecord->uiKey == uiKey) -+ { -+ eAllocType = psCurrentRecord->eAllocType; -+ g_WaterMarkData[eAllocType] -= psCurrentRecord->uiBytes; -+ -+ if (eAllocType == DEBUG_MEM_ALLOC_TYPE_KMALLOC -+ || eAllocType == DEBUG_MEM_ALLOC_TYPE_VMALLOC -+ || eAllocType == DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES -+ || eAllocType == DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE) -+ { -+ g_SysRAMWaterMark -= psCurrentRecord->uiBytes; -+ } -+ else if (eAllocType == DEBUG_MEM_ALLOC_TYPE_IOREMAP -+ || eAllocType == DEBUG_MEM_ALLOC_TYPE_IO) -+ { -+ g_IOMemWaterMark -= psCurrentRecord->uiBytes; -+ } -+ -+ List_DEBUG_MEM_ALLOC_REC_Remove(psCurrentRecord); -+ kfree(psCurrentRecord); -+ -+ return IMG_TRUE; -+ } -+ else -+ { -+ return IMG_FALSE; -+ } -+} -+ -+ -+static IMG_VOID -+DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE eAllocType, IMG_UINTPTR_T uiKey, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line) -+{ -+/* DEBUG_MEM_ALLOC_REC **ppsCurrentRecord;*/ -+ -+ LinuxLockMutexNested(&g_sDebugMutex, PVRSRV_LOCK_CLASS_MM_DEBUG); -+ -+ /* Locate the corresponding allocation entry */ -+ if (!List_DEBUG_MEM_ALLOC_REC_IMG_BOOL_Any_va(g_MemoryRecords, -+ DebugMemAllocRecordRemove_AnyVaCb, -+ eAllocType, -+ uiKey)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: couldn't find an entry for type=%s with uiKey=" UINTPTR_FMT " (called from %s, line %d\n", -+ __FUNCTION__, DebugMemAllocRecordTypeToString(eAllocType), uiKey, -+ pszFileName, ui32Line)); -+ } -+ -+ LinuxUnLockMutex(&g_sDebugMutex); -+} -+ -+ -+static IMG_CHAR * -+DebugMemAllocRecordTypeToString(DEBUG_MEM_ALLOC_TYPE eAllocType) -+{ -+ IMG_CHAR *apszDebugMemoryRecordTypes[] = { -+ "KMALLOC", -+ "VMALLOC", -+ "ALLOC_PAGES", -+ "IOREMAP", -+ "IO", -+ "KMEM_CACHE_ALLOC", -+#if defined(PVR_LINUX_MEM_AREA_USE_VMAP) -+ "VMAP" -+#endif -+ }; -+ return apszDebugMemoryRecordTypes[eAllocType]; -+} -+#endif -+ -+ -+static IMG_BOOL -+AllocFlagsToPGProt(pgprot_t *pPGProtFlags, IMG_UINT32 ui32AllocFlags) -+{ -+ pgprot_t PGProtFlags; -+ -+ switch (ui32AllocFlags & PVRSRV_HAP_CACHETYPE_MASK) -+ { -+ case PVRSRV_HAP_CACHED: -+ PGProtFlags = PAGE_KERNEL; -+ break; -+ case PVRSRV_HAP_WRITECOMBINE: -+ PGProtFlags = PGPROT_WC(PAGE_KERNEL); -+ break; -+ case PVRSRV_HAP_UNCACHED: -+ PGProtFlags = PGPROT_UC(PAGE_KERNEL); -+ break; -+ default: -+ PVR_DPF((PVR_DBG_ERROR, -+ "%s: Unknown mapping flags=0x%08x", -+ __FUNCTION__, ui32AllocFlags)); -+ dump_stack(); -+ return IMG_FALSE; -+ } -+ -+ *pPGProtFlags = PGProtFlags; -+ -+ return IMG_TRUE; -+} -+ -+IMG_VOID * -+_VMallocWrapper(IMG_SIZE_T uiBytes, -+ IMG_UINT32 ui32AllocFlags, -+ IMG_CHAR *pszFileName, -+ IMG_UINT32 ui32Line) -+{ -+ pgprot_t PGProtFlags; -+ IMG_VOID *pvRet; -+ gfp_t gfp_mask; -+ -+ if (!AllocFlagsToPGProt(&PGProtFlags, ui32AllocFlags)) -+ { -+ return NULL; -+ } -+ -+ gfp_mask = GFP_KERNEL; -+ -+#if defined(PVR_USE_DMA32_FOR_DEVMEM_ALLOCS) -+ gfp_mask |= __GFP_DMA32; -+#else -+ gfp_mask |= __GFP_HIGHMEM; -+#endif -+ -+ /* Allocate virtually contiguous pages */ -+ pvRet = __vmalloc(uiBytes, gfp_mask, PGProtFlags); -+ -+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -+ if (pvRet) -+ { -+ IMG_CPU_PHYADDR sCpuPAddr; -+ sCpuPAddr.uiAddr = 0; -+ -+ DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_VMALLOC, -+ (IMG_UINTPTR_T)pvRet, -+ pvRet, -+ sCpuPAddr, -+ NULL, -+ PAGE_ALIGN(uiBytes), -+ pszFileName, -+ ui32Line -+ ); -+ } -+#else -+ PVR_UNREFERENCED_PARAMETER(pszFileName); -+ PVR_UNREFERENCED_PARAMETER(ui32Line); -+#endif -+ -+ return pvRet; -+} -+ -+ -+IMG_VOID -+_VFreeWrapper(IMG_VOID *pvCpuVAddr, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line) -+{ -+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -+ DebugMemAllocRecordRemove( -+ DEBUG_MEM_ALLOC_TYPE_VMALLOC, -+ (IMG_UINTPTR_T)pvCpuVAddr, -+ pszFileName, -+ ui32Line); -+#else -+ PVR_UNREFERENCED_PARAMETER(pszFileName); -+ PVR_UNREFERENCED_PARAMETER(ui32Line); -+#endif -+ vfree(pvCpuVAddr); -+} -+ -+ -+#if defined(PVR_LINUX_MEM_AREA_USE_VMAP) -+static IMG_VOID * -+_VMapWrapper(struct page **ppsPageList, IMG_UINT32 ui32NumPages, IMG_UINT32 ui32AllocFlags, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line) -+{ -+ pgprot_t PGProtFlags; -+ IMG_VOID *pvRet; -+ -+ if (!AllocFlagsToPGProt(&PGProtFlags, ui32AllocFlags)) -+ { -+ return NULL; -+ } -+ -+ pvRet = vmap(ppsPageList, ui32NumPages, GFP_KERNEL | __GFP_HIGHMEM, PGProtFlags); -+ -+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -+ if (pvRet) -+ { -+ IMG_CPU_PHYADDR sCpuPAddr; -+ sCpuPAddr.uiAddr = 0; -+ -+ DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_VMAP, -+ (IMG_UINTPTR_T)pvRet, -+ pvRet, -+ sCpuPAddr, -+ NULL, -+ PAGES_TO_BYTES(ui32NumPages), -+ pszFileName, -+ ui32Line -+ ); -+ } -+#else -+ PVR_UNREFERENCED_PARAMETER(pszFileName); -+ PVR_UNREFERENCED_PARAMETER(ui32Line); -+#endif -+ -+ return pvRet; -+} -+ -+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -+#define VMapWrapper(ppsPageList, uBytes, ui32AllocFlags) _VMapWrapper(ppsPageList, uBytes, ui32AllocFlags, __FILE__, __LINE__) -+#else -+#define VMapWrapper(ppsPageList, uBytes, ui32AllocFlags) _VMapWrapper(ppsPageList, uBytes, ui32AllocFlags, NULL, 0) -+#endif -+ -+ -+static IMG_VOID -+_VUnmapWrapper(IMG_VOID *pvCpuVAddr, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line) -+{ -+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -+ DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_VMAP, -+ (IMG_UINTPTR_T)pvCpuVAddr, pszFileName, ui32Line); -+#else -+ PVR_UNREFERENCED_PARAMETER(pszFileName); -+ PVR_UNREFERENCED_PARAMETER(ui32Line); -+#endif -+ vunmap(pvCpuVAddr); -+} -+ -+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -+#define VUnmapWrapper(pvCpuVAddr) _VUnmapWrapper(pvCpuVAddr, __FILE__, __LINE__) -+#else -+#define VUnmapWrapper(pvCpuVAddr) _VUnmapWrapper(pvCpuVAddr, NULL, 0) -+#endif -+ -+#endif /* defined(PVR_LINUX_MEM_AREA_USE_VMAP) */ -+ -+ -+IMG_VOID -+_KMemCacheFreeWrapper(LinuxKMemCache *psCache, IMG_VOID *pvObject, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line) -+{ -+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -+ DebugMemAllocRecordRemove( -+ DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE, -+ (IMG_UINTPTR_T)pvObject, -+ pszFileName, -+ ui32Line); -+#else -+ PVR_UNREFERENCED_PARAMETER(pszFileName); -+ PVR_UNREFERENCED_PARAMETER(ui32Line); -+#endif -+ -+ kmem_cache_free(psCache, pvObject); -+} -+ -+ -+const IMG_CHAR * -+KMemCacheNameWrapper(LinuxKMemCache *psCache) -+{ -+ PVR_UNREFERENCED_PARAMETER(psCache); -+ -+ /* In this case kmem_cache_t is an incomplete typedef, -+ * so we can't even de-reference to get the name member. It is also a GPL export symbol */ -+ return ""; -+} -+ -+ -+static LinuxPagePoolEntry * -+LinuxPagePoolEntryAlloc(IMG_VOID) -+{ -+ return KMemCacheAllocWrapper(g_PsLinuxPagePoolCache, GFP_KERNEL); -+} -+ -+static IMG_VOID -+LinuxPagePoolEntryFree(LinuxPagePoolEntry *psPagePoolEntry) -+{ -+ KMemCacheFreeWrapper(g_PsLinuxPagePoolCache, psPagePoolEntry); -+} -+ -+ -+static struct page * -+AllocPageFromLinux(void) -+{ -+ struct page *psPage; -+ gfp_t gfp_mask; -+ -+ gfp_mask = GFP_KERNEL; -+ -+#if defined(PVR_USE_DMA32_FOR_DEVMEM_ALLOCS) -+ gfp_mask |= __GFP_DMA32; -+#else -+ gfp_mask |= __GFP_HIGHMEM; -+#endif -+ -+ psPage = alloc_pages(gfp_mask, 0); -+ if (!psPage) -+ { -+ return NULL; -+ -+ } -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)) -+ /* Reserve those pages to allow them to be re-mapped to user space */ -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)) -+ SetPageReserved(psPage); -+#else -+ mem_map_reserve(psPage); -+#endif -+#endif -+ return psPage; -+} -+ -+ -+static IMG_VOID -+FreePageToLinux(struct page *psPage) -+{ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)) -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)) -+ ClearPageReserved(psPage); -+#else -+ mem_map_reserve(psPage); -+#endif -+#endif -+ __free_pages(psPage, 0); -+} -+ -+ -+#if (PVR_LINUX_MEM_AREA_POOL_MAX_PAGES != 0) -+static DEFINE_MUTEX(g_sPagePoolMutex); -+ -+static inline void -+PagePoolLock(void) -+{ -+ mutex_lock(&g_sPagePoolMutex); -+} -+ -+static inline void -+PagePoolUnlock(void) -+{ -+ mutex_unlock(&g_sPagePoolMutex); -+} -+ -+static inline int -+PagePoolTrylock(void) -+{ -+ return mutex_trylock(&g_sPagePoolMutex); -+} -+ -+#else /* (PVR_LINUX_MEM_AREA_POOL_MAX_PAGES != 0) */ -+static inline void -+PagePoolLock(void) -+{ -+} -+ -+static inline void -+PagePoolUnlock(void) -+{ -+} -+ -+static inline int -+PagePoolTrylock(void) -+{ -+ return 1; -+} -+#endif /* (PVR_LINUX_MEM_AREA_POOL_MAX_PAGES != 0) */ -+ -+ -+static inline void -+AddEntryToPool(LinuxPagePoolEntry *psPagePoolEntry) -+{ -+ list_add_tail(&psPagePoolEntry->sPagePoolItem, &g_sPagePoolList); -+ atomic_inc(&g_sPagePoolEntryCount); -+} -+ -+static inline void -+RemoveEntryFromPool(LinuxPagePoolEntry *psPagePoolEntry) -+{ -+ list_del(&psPagePoolEntry->sPagePoolItem); -+ atomic_dec(&g_sPagePoolEntryCount); -+} -+ -+static inline LinuxPagePoolEntry * -+RemoveFirstEntryFromPool(void) -+{ -+ LinuxPagePoolEntry *psPagePoolEntry; -+ -+ if (list_empty(&g_sPagePoolList)) -+ { -+ PVR_ASSERT(atomic_read(&g_sPagePoolEntryCount) == 0); -+ -+ return NULL; -+ } -+ -+ PVR_ASSERT(atomic_read(&g_sPagePoolEntryCount) > 0); -+ -+ psPagePoolEntry = list_first_entry(&g_sPagePoolList, LinuxPagePoolEntry, sPagePoolItem); -+ -+ RemoveEntryFromPool(psPagePoolEntry); -+ -+ return psPagePoolEntry; -+} -+ -+static struct page * -+AllocPage(IMG_UINT32 ui32AreaFlags, IMG_BOOL *pbFromPagePool) -+{ -+ struct page *psPage = NULL; -+ -+ /* -+ * Only uncached allocations can come from the page pool. -+ * The page pool is currently used to reduce the cost of -+ * invalidating the CPU cache when uncached memory is allocated. -+ */ -+ if (AreaIsUncached(ui32AreaFlags) && atomic_read(&g_sPagePoolEntryCount) != 0) -+ { -+ LinuxPagePoolEntry *psPagePoolEntry; -+ -+ PagePoolLock(); -+ psPagePoolEntry = RemoveFirstEntryFromPool(); -+ PagePoolUnlock(); -+ -+ /* List may have changed since we checked the counter */ -+ if (psPagePoolEntry) -+ { -+ psPage = psPagePoolEntry->psPage; -+ LinuxPagePoolEntryFree(psPagePoolEntry); -+ *pbFromPagePool = IMG_TRUE; -+ } -+ } -+ -+ if (!psPage) -+ { -+ psPage = AllocPageFromLinux(); -+ if (psPage) -+ { -+ *pbFromPagePool = IMG_FALSE; -+ } -+ } -+ -+ return psPage; -+ -+} -+ -+static IMG_VOID -+FreePage(IMG_BOOL bToPagePool, struct page *psPage) -+{ -+ /* Only uncached allocations can be freed to the page pool */ -+ if (bToPagePool && atomic_read(&g_sPagePoolEntryCount) < g_iPagePoolMaxEntries) -+ { -+ LinuxPagePoolEntry *psPagePoolEntry = LinuxPagePoolEntryAlloc(); -+ if (psPagePoolEntry) -+ { -+ psPagePoolEntry->psPage = psPage; -+ -+ PagePoolLock(); -+ AddEntryToPool(psPagePoolEntry); -+ PagePoolUnlock(); -+ -+ return; -+ } -+ } -+ -+ FreePageToLinux(psPage); -+} -+ -+static IMG_VOID -+FreePagePool(IMG_VOID) -+{ -+ LinuxPagePoolEntry *psPagePoolEntry, *psTempPoolEntry; -+ -+ PagePoolLock(); -+ -+#if (PVR_LINUX_MEM_AREA_POOL_MAX_PAGES != 0) -+ PVR_TRACE(("%s: Freeing %d pages from pool", __FUNCTION__, atomic_read(&g_sPagePoolEntryCount))); -+#else -+ PVR_ASSERT(atomic_read(&g_sPagePoolEntryCount) == 0); -+ PVR_ASSERT(list_empty(&g_sPagePoolList)); -+#endif -+ -+ list_for_each_entry_safe(psPagePoolEntry, psTempPoolEntry, &g_sPagePoolList, sPagePoolItem) -+ { -+ RemoveEntryFromPool(psPagePoolEntry); -+ -+ FreePageToLinux(psPagePoolEntry->psPage); -+ LinuxPagePoolEntryFree(psPagePoolEntry); -+ } -+ -+ PVR_ASSERT(atomic_read(&g_sPagePoolEntryCount) == 0); -+ -+ PagePoolUnlock(); -+} -+ -+#if defined(PVR_LINUX_MEM_AREA_POOL_ALLOW_SHRINK) -+#if defined(PVRSRV_NEED_PVR_ASSERT) -+static struct shrinker g_sShrinker; -+#endif -+ -+static int -+ShrinkPagePool(struct shrinker *psShrinker, struct shrink_control *psShrinkControl) -+{ -+ unsigned long uNumToScan = psShrinkControl->nr_to_scan; -+ -+ PVR_ASSERT(psShrinker == &g_sShrinker); -+ (void)psShrinker; -+ -+ if (uNumToScan != 0) -+ { -+ LinuxPagePoolEntry *psPagePoolEntry, *psTempPoolEntry; -+ -+ PVR_TRACE(("%s: Number to scan: %ld", __FUNCTION__, uNumToScan)); -+ PVR_TRACE(("%s: Pages in pool before scan: %d", __FUNCTION__, atomic_read(&g_sPagePoolEntryCount))); -+ -+ if (!PagePoolTrylock()) -+ { -+ PVR_TRACE(("%s: Couldn't get page pool lock", __FUNCTION__)); -+ return -1; -+ } -+ -+ list_for_each_entry_safe(psPagePoolEntry, psTempPoolEntry, &g_sPagePoolList, sPagePoolItem) -+ { -+ RemoveEntryFromPool(psPagePoolEntry); -+ -+ FreePageToLinux(psPagePoolEntry->psPage); -+ LinuxPagePoolEntryFree(psPagePoolEntry); -+ -+ if (--uNumToScan == 0) -+ { -+ break; -+ } -+ } -+ -+ if (list_empty(&g_sPagePoolList)) -+ { -+ PVR_ASSERT(atomic_read(&g_sPagePoolEntryCount) == 0); -+ } -+ -+ PagePoolUnlock(); -+ -+ PVR_TRACE(("%s: Pages in pool after scan: %d", __FUNCTION__, atomic_read(&g_sPagePoolEntryCount))); -+ } -+ -+ return atomic_read(&g_sPagePoolEntryCount); -+} -+#endif -+ -+static IMG_BOOL -+AllocPages(IMG_UINT32 ui32AreaFlags, struct page ***pppsPageList, IMG_HANDLE *phBlockPageList, IMG_UINT32 ui32NumPages, IMG_BOOL *pbFromPagePool) -+{ -+ struct page **ppsPageList; -+ IMG_HANDLE hBlockPageList; -+ IMG_INT32 i; /* Must be signed; see "for" loop conditions */ -+ PVRSRV_ERROR eError; -+ IMG_BOOL bFromPagePool = IMG_FALSE; -+ -+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -+ IMG_CPU_PHYADDR sCpuPAddr; -+#endif -+ -+ eError = OSAllocMem(0, sizeof(*ppsPageList) * ui32NumPages, (IMG_VOID **)&ppsPageList, &hBlockPageList, -+ "Array of pages"); -+ if (eError != PVRSRV_OK) -+ { -+ goto failed_page_list_alloc; -+ } -+ -+ *pbFromPagePool = IMG_TRUE; -+ for(i = 0; i < (IMG_INT32)ui32NumPages; i++) -+ { -+ ppsPageList[i] = AllocPage(ui32AreaFlags, &bFromPagePool); -+ if (!ppsPageList[i]) -+ { -+ goto failed_alloc_pages; -+ } -+ *pbFromPagePool &= bFromPagePool; -+ } -+ -+ *pppsPageList = ppsPageList; -+ *phBlockPageList = hBlockPageList; -+ -+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -+ sCpuPAddr.uiAddr = 0; -+ -+ DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES, -+ (IMG_UINTPTR_T)ppsPageList, -+ 0, -+ sCpuPAddr, -+ NULL, -+ PAGES_TO_BYTES(ui32NumPages), -+ "unknown", -+ 0 -+ ); -+#endif -+ -+ return IMG_TRUE; -+ -+failed_alloc_pages: -+ for(i--; i >= 0; i--) -+ { -+ FreePage(*pbFromPagePool, ppsPageList[i]); -+ } -+ (IMG_VOID) OSFreeMem(0, sizeof(*ppsPageList) * ui32NumPages, ppsPageList, hBlockPageList); -+ -+failed_page_list_alloc: -+ return IMG_FALSE; -+} -+ -+ -+static IMG_VOID -+FreePages(IMG_BOOL bToPagePool, struct page **ppsPageList, IMG_HANDLE hBlockPageList, IMG_UINT32 ui32NumPages) -+{ -+ IMG_INT32 i; -+ -+ for(i = 0; i < (IMG_INT32)ui32NumPages; i++) -+ { -+ FreePage(bToPagePool, ppsPageList[i]); -+ } -+ -+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -+ DebugMemAllocRecordRemove( -+ DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES, -+ (IMG_UINTPTR_T)ppsPageList, -+ __FILE__, -+ __LINE__); -+#endif -+ -+ (IMG_VOID) OSFreeMem(0, sizeof(*ppsPageList) * ui32NumPages, ppsPageList, hBlockPageList); -+} -+ -+ -+LinuxMemArea * -+NewVMallocLinuxMemArea(IMG_SIZE_T uBytes, IMG_UINT32 ui32AreaFlags) -+{ -+ LinuxMemArea *psLinuxMemArea = NULL; -+ IMG_VOID *pvCpuVAddr; -+#if defined(PVR_LINUX_MEM_AREA_USE_VMAP) -+ IMG_UINT32 ui32NumPages = 0; -+ struct page **ppsPageList = NULL; -+ IMG_HANDLE hBlockPageList; -+#endif -+ IMG_BOOL bFromPagePool = IMG_FALSE; -+ -+ psLinuxMemArea = LinuxMemAreaStructAlloc(); -+ if (!psLinuxMemArea) -+ { -+ goto failed; -+ } -+ -+#if defined(PVR_LINUX_MEM_AREA_USE_VMAP) -+ ui32NumPages = RANGE_TO_PAGES(uBytes); -+ -+ if (!AllocPages(ui32AreaFlags, &ppsPageList, &hBlockPageList, ui32NumPages, &bFromPagePool)) -+ { -+ goto failed; -+ } -+ -+ pvCpuVAddr = VMapWrapper(ppsPageList, ui32NumPages, ui32AreaFlags); -+#else /* defined(PVR_LINUX_MEM_AREA_USE_VMAP) */ -+ pvCpuVAddr = VMallocWrapper(uBytes, ui32AreaFlags); -+ if (!pvCpuVAddr) -+ { -+ goto failed; -+ } -+/* PG_reserved was deprecated in linux-2.6.15 */ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)) -+ /* Reserve those pages to allow them to be re-mapped to user space */ -+ ReservePages(pvCpuVAddr, uBytes); -+#endif -+#endif /* defined(PVR_LINUX_MEM_AREA_USE_VMAP) */ -+ -+ psLinuxMemArea->eAreaType = LINUX_MEM_AREA_VMALLOC; -+ psLinuxMemArea->uData.sVmalloc.pvVmallocAddress = pvCpuVAddr; -+#if defined(PVR_LINUX_MEM_AREA_USE_VMAP) -+ psLinuxMemArea->uData.sVmalloc.ppsPageList = ppsPageList; -+ psLinuxMemArea->uData.sVmalloc.hBlockPageList = hBlockPageList; -+#endif -+ psLinuxMemArea->uiByteSize = uBytes; -+ psLinuxMemArea->ui32AreaFlags = ui32AreaFlags; -+ INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList); -+ -+#if defined(DEBUG_LINUX_MEM_AREAS) -+ DebugLinuxMemAreaRecordAdd(psLinuxMemArea, ui32AreaFlags); -+#endif -+ -+ /* This works around a problem where Linux will not invalidate -+ * the cache for physical memory it frees that is direct mapped. -+ * -+ * As a result, cache entries remain that may be subsequently flushed -+ * to these physical pages after they have been allocated for another -+ * purpose. For a subsequent cached use of this memory, that is not a -+ * problem, but if we are allocating uncached or write-combined memory, -+ * and bypassing the cache, it can cause subsequent uncached writes to -+ * the memory to be replaced with junk from the cache. -+ * -+ * If the pages are from our page cache, no cache invalidate is needed. -+ * -+ * This just handles the __vmalloc() case (when we have a kernel virtual -+ * address range). The alloc_pages() path is handled in mmap.c. -+ */ -+ if (AreaIsUncached(ui32AreaFlags) && !bFromPagePool) -+ { -+ OSInvalidateCPUCacheRangeKM(psLinuxMemArea, 0, pvCpuVAddr, uBytes); -+ } -+ -+ return psLinuxMemArea; -+ -+failed: -+ PVR_DPF((PVR_DBG_ERROR, "%s: failed!", __FUNCTION__)); -+#if defined(PVR_LINUX_MEM_AREA_USE_VMAP) -+ if (ppsPageList) -+ { -+ FreePages(bFromPagePool, ppsPageList, hBlockPageList, ui32NumPages); -+ } -+#endif -+ if (psLinuxMemArea) -+ { -+ LinuxMemAreaStructFree(psLinuxMemArea); -+ } -+ -+ return NULL; -+} -+ -+ -+IMG_VOID -+FreeVMallocLinuxMemArea(LinuxMemArea *psLinuxMemArea) -+{ -+#if defined(PVR_LINUX_MEM_AREA_USE_VMAP) -+ IMG_UINT32 ui32NumPages; -+ struct page **ppsPageList; -+ IMG_HANDLE hBlockPageList; -+#endif -+ -+ PVR_ASSERT(psLinuxMemArea); -+ PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_VMALLOC); -+ PVR_ASSERT(psLinuxMemArea->uData.sVmalloc.pvVmallocAddress); -+ -+#if defined(DEBUG_LINUX_MEM_AREAS) -+ DebugLinuxMemAreaRecordRemove(psLinuxMemArea); -+#endif -+ -+ PVR_DPF((PVR_DBG_MESSAGE,"%s: pvCpuVAddr: %p", -+ __FUNCTION__, psLinuxMemArea->uData.sVmalloc.pvVmallocAddress)); -+ -+#if defined(PVR_LINUX_MEM_AREA_USE_VMAP) -+ VUnmapWrapper(psLinuxMemArea->uData.sVmalloc.pvVmallocAddress); -+ -+ ui32NumPages = RANGE_TO_PAGES(psLinuxMemArea->uiByteSize); -+ ppsPageList = psLinuxMemArea->uData.sVmalloc.ppsPageList; -+ hBlockPageList = psLinuxMemArea->uData.sVmalloc.hBlockPageList; -+ -+ FreePages(CanFreeToPool(psLinuxMemArea), ppsPageList, hBlockPageList, ui32NumPages); -+#else -+/* PG_reserved was deprecated in linux-2.6.15 */ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)) -+ UnreservePages(psLinuxMemArea->uData.sVmalloc.pvVmallocAddress, -+ psLinuxMemArea->uiByteSize); -+#endif -+ -+ VFreeWrapper(psLinuxMemArea->uData.sVmalloc.pvVmallocAddress); -+#endif /* defined(PVR_LINUX_MEM_AREA_USE_VMAP) */ -+ -+ LinuxMemAreaStructFree(psLinuxMemArea); -+} -+ -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)) -+/* Reserve pages of memory in order that they're not automatically -+ deallocated after the last user reference dies. */ -+static IMG_VOID -+ReservePages(IMG_VOID *pvAddress, IMG_SIZE_T uLength) -+{ -+ IMG_VOID *pvPage; -+ IMG_VOID *pvEnd = pvAddress + uLength; -+ -+ for(pvPage = pvAddress; pvPage < pvEnd; pvPage += PAGE_SIZE) -+ { -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)) -+ SetPageReserved(vmalloc_to_page(pvPage)); -+#else -+ mem_map_reserve(vmalloc_to_page(pvPage)); -+#endif -+ } -+} -+ -+ -+/* Un-reserve pages of memory in order that they can be freed. */ -+static IMG_VOID -+UnreservePages(IMG_VOID *pvAddress, IMG_SIZE_T uLength) -+{ -+ IMG_VOID *pvPage; -+ IMG_VOID *pvEnd = pvAddress + uLength; -+ -+ for(pvPage = pvAddress; pvPage < pvEnd; pvPage += PAGE_SIZE) -+ { -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)) -+ ClearPageReserved(vmalloc_to_page(pvPage)); -+#else -+ mem_map_unreserve(vmalloc_to_page(pvPage)); -+#endif -+ } -+} -+#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)) */ -+ -+ -+IMG_VOID * -+_IORemapWrapper(IMG_CPU_PHYADDR BasePAddr, -+ IMG_SIZE_T uBytes, -+ IMG_UINT32 ui32MappingFlags, -+ IMG_CHAR *pszFileName, -+ IMG_UINT32 ui32Line) -+{ -+ IMG_VOID *pvIORemapCookie; -+ -+ switch (ui32MappingFlags & PVRSRV_HAP_CACHETYPE_MASK) -+ { -+ case PVRSRV_HAP_CACHED: -+ pvIORemapCookie = (IMG_VOID *)IOREMAP(BasePAddr.uiAddr, uBytes); -+ break; -+ case PVRSRV_HAP_WRITECOMBINE: -+ pvIORemapCookie = (IMG_VOID *)IOREMAP_WC(BasePAddr.uiAddr, uBytes); -+ break; -+ case PVRSRV_HAP_UNCACHED: -+ pvIORemapCookie = (IMG_VOID *)IOREMAP_UC(BasePAddr.uiAddr, uBytes); -+ break; -+ default: -+ PVR_DPF((PVR_DBG_ERROR, "IORemapWrapper: unknown mapping flags")); -+ return NULL; -+ } -+ -+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -+ if (pvIORemapCookie) -+ { -+ DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_IOREMAP, -+ (IMG_UINTPTR_T)pvIORemapCookie, -+ pvIORemapCookie, -+ BasePAddr, -+ NULL, -+ uBytes, -+ pszFileName, -+ ui32Line -+ ); -+ } -+#else -+ PVR_UNREFERENCED_PARAMETER(pszFileName); -+ PVR_UNREFERENCED_PARAMETER(ui32Line); -+#endif -+ -+ return pvIORemapCookie; -+} -+ -+ -+IMG_VOID -+_IOUnmapWrapper(IMG_VOID *pvIORemapCookie, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line) -+{ -+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -+ DebugMemAllocRecordRemove( -+ DEBUG_MEM_ALLOC_TYPE_IOREMAP, -+ (IMG_UINTPTR_T)pvIORemapCookie, -+ pszFileName, -+ ui32Line); -+#else -+ PVR_UNREFERENCED_PARAMETER(pszFileName); -+ PVR_UNREFERENCED_PARAMETER(ui32Line); -+#endif -+ iounmap(pvIORemapCookie); -+} -+ -+ -+LinuxMemArea * -+NewIORemapLinuxMemArea(IMG_CPU_PHYADDR BasePAddr, -+ IMG_SIZE_T uBytes, -+ IMG_UINT32 ui32AreaFlags) -+{ -+ LinuxMemArea *psLinuxMemArea; -+ IMG_VOID *pvIORemapCookie; -+ -+ psLinuxMemArea = LinuxMemAreaStructAlloc(); -+ if (!psLinuxMemArea) -+ { -+ return NULL; -+ } -+ -+ pvIORemapCookie = IORemapWrapper(BasePAddr, uBytes, ui32AreaFlags); -+ if (!pvIORemapCookie) -+ { -+ LinuxMemAreaStructFree(psLinuxMemArea); -+ return NULL; -+ } -+ -+ psLinuxMemArea->eAreaType = LINUX_MEM_AREA_IOREMAP; -+ psLinuxMemArea->uData.sIORemap.pvIORemapCookie = pvIORemapCookie; -+ psLinuxMemArea->uData.sIORemap.CPUPhysAddr = BasePAddr; -+ psLinuxMemArea->uiByteSize = uBytes; -+ psLinuxMemArea->ui32AreaFlags = ui32AreaFlags; -+ INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList); -+ -+#if defined(DEBUG_LINUX_MEM_AREAS) -+ DebugLinuxMemAreaRecordAdd(psLinuxMemArea, ui32AreaFlags); -+#endif -+ -+ return psLinuxMemArea; -+} -+ -+ -+IMG_VOID -+FreeIORemapLinuxMemArea(LinuxMemArea *psLinuxMemArea) -+{ -+ PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_IOREMAP); -+ -+#if defined(DEBUG_LINUX_MEM_AREAS) -+ DebugLinuxMemAreaRecordRemove(psLinuxMemArea); -+#endif -+ -+ IOUnmapWrapper(psLinuxMemArea->uData.sIORemap.pvIORemapCookie); -+ -+ LinuxMemAreaStructFree(psLinuxMemArea); -+} -+ -+ -+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL) -+/* -+ * Avoid using remap_pfn_range on RAM, if possible. On x86 systems, with -+ * PAT enabled, remap_pfn_range checks the page attributes requested by -+ * remap_pfn_range against those of the direct kernel mapping for those -+ * pages (if any). This is rather annoying if the pages have been obtained -+ * with alloc_pages, where we just ask for raw pages; we don't care about -+ * the direct mapping. This latter issue arises when device memory is -+ * exported from one process to another. Services implements this -+ * using memory wrapping, which ends up creating an external KV memory area. -+ */ -+static IMG_BOOL -+TreatExternalPagesAsContiguous(IMG_SYS_PHYADDR *psSysPhysAddr, IMG_SIZE_T uBytes, IMG_BOOL bPhysContig) -+{ -+ IMG_UINT32 ui32; -+ IMG_UINT32 ui32AddrChk; -+ IMG_UINT32 ui32NumPages = RANGE_TO_PAGES(uBytes); -+ -+ /* -+ * If bPhysContig is IMG_TRUE, we must assume psSysPhysAddr points -+ * to the address of the first page, not an array of page addresses. -+ */ -+ for (ui32 = 0, ui32AddrChk = psSysPhysAddr[0].uiAddr; -+ ui32 < ui32NumPages; -+ ui32++, ui32AddrChk = (bPhysContig) ? (ui32AddrChk + PAGE_SIZE) : psSysPhysAddr[ui32].uiAddr) -+ { -+ if (!pfn_valid(PHYS_TO_PFN(ui32AddrChk))) -+ { -+ break; -+ } -+ } -+ if (ui32 == ui32NumPages) -+ { -+ return IMG_FALSE; -+ } -+ -+ if (!bPhysContig) -+ { -+ for (ui32 = 0, ui32AddrChk = psSysPhysAddr[0].uiAddr; -+ ui32 < ui32NumPages; -+ ui32++, ui32AddrChk += PAGE_SIZE) -+ { -+ if (psSysPhysAddr[ui32].uiAddr != ui32AddrChk) -+ { -+ return IMG_FALSE; -+ } -+ } -+ } -+ -+ return IMG_TRUE; -+} -+#endif -+ -+LinuxMemArea *NewExternalKVLinuxMemArea(IMG_SYS_PHYADDR *pBasePAddr, IMG_VOID *pvCPUVAddr, IMG_SIZE_T uBytes, IMG_BOOL bPhysContig, IMG_UINT32 ui32AreaFlags) -+{ -+ LinuxMemArea *psLinuxMemArea; -+ -+ psLinuxMemArea = LinuxMemAreaStructAlloc(); -+ if (!psLinuxMemArea) -+ { -+ return NULL; -+ } -+ -+ psLinuxMemArea->eAreaType = LINUX_MEM_AREA_EXTERNAL_KV; -+ psLinuxMemArea->uData.sExternalKV.pvExternalKV = pvCPUVAddr; -+ psLinuxMemArea->uData.sExternalKV.bPhysContig = -+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL) -+ (bPhysContig || TreatExternalPagesAsContiguous(pBasePAddr, uiBytes, bPhysContig)) -+ ? IMG_TRUE : IMG_FALSE; -+#else -+ bPhysContig; -+#endif -+ if (psLinuxMemArea->uData.sExternalKV.bPhysContig) -+ { -+ psLinuxMemArea->uData.sExternalKV.uPhysAddr.SysPhysAddr = *pBasePAddr; -+ } -+ else -+ { -+ psLinuxMemArea->uData.sExternalKV.uPhysAddr.pSysPhysAddr = pBasePAddr; -+ } -+ psLinuxMemArea->uiByteSize = uBytes; -+ psLinuxMemArea->ui32AreaFlags = ui32AreaFlags; -+ INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList); -+ -+#if defined(DEBUG_LINUX_MEM_AREAS) -+ DebugLinuxMemAreaRecordAdd(psLinuxMemArea, ui32AreaFlags); -+#endif -+ -+ return psLinuxMemArea; -+} -+ -+ -+IMG_VOID -+FreeExternalKVLinuxMemArea(LinuxMemArea *psLinuxMemArea) -+{ -+ PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_EXTERNAL_KV); -+ -+#if defined(DEBUG_LINUX_MEM_AREAS) -+ DebugLinuxMemAreaRecordRemove(psLinuxMemArea); -+#endif -+ -+ LinuxMemAreaStructFree(psLinuxMemArea); -+} -+ -+ -+LinuxMemArea * -+NewIOLinuxMemArea(IMG_CPU_PHYADDR BasePAddr, -+ IMG_SIZE_T uBytes, -+ IMG_UINT32 ui32AreaFlags) -+{ -+ LinuxMemArea *psLinuxMemArea = LinuxMemAreaStructAlloc(); -+ if (!psLinuxMemArea) -+ { -+ return NULL; -+ } -+ -+ /* Nothing to activly do. We just keep a record of the physical range. */ -+ psLinuxMemArea->eAreaType = LINUX_MEM_AREA_IO; -+ psLinuxMemArea->uData.sIO.CPUPhysAddr.uiAddr = BasePAddr.uiAddr; -+ psLinuxMemArea->uiByteSize = uBytes; -+ psLinuxMemArea->ui32AreaFlags = ui32AreaFlags; -+ INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList); -+ -+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -+ DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_IO, -+ BasePAddr.uiAddr, -+ 0, -+ BasePAddr, -+ NULL, -+ uBytes, -+ "unknown", -+ 0 -+ ); -+#endif -+ -+#if defined(DEBUG_LINUX_MEM_AREAS) -+ DebugLinuxMemAreaRecordAdd(psLinuxMemArea, ui32AreaFlags); -+#endif -+ -+ return psLinuxMemArea; -+} -+ -+ -+IMG_VOID -+FreeIOLinuxMemArea(LinuxMemArea *psLinuxMemArea) -+{ -+ PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_IO); -+ -+#if defined(DEBUG_LINUX_MEM_AREAS) -+ DebugLinuxMemAreaRecordRemove(psLinuxMemArea); -+#endif -+ -+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -+ DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_IO, -+ psLinuxMemArea->uData.sIO.CPUPhysAddr.uiAddr, -+ __FILE__, -+ __LINE__); -+#endif -+ -+ /* Nothing more to do than free the LinuxMemArea struct */ -+ -+ LinuxMemAreaStructFree(psLinuxMemArea); -+} -+ -+ -+LinuxMemArea * -+NewAllocPagesLinuxMemArea(IMG_SIZE_T uBytes, IMG_UINT32 ui32AreaFlags) -+{ -+ LinuxMemArea *psLinuxMemArea; -+ IMG_UINT32 ui32NumPages; -+ struct page **ppsPageList; -+ IMG_HANDLE hBlockPageList; -+ IMG_BOOL bFromPagePool; -+ -+ psLinuxMemArea = LinuxMemAreaStructAlloc(); -+ if (!psLinuxMemArea) -+ { -+ goto failed_area_alloc; -+ } -+ -+ ui32NumPages = RANGE_TO_PAGES(uBytes); -+ -+ if (!AllocPages(ui32AreaFlags, &ppsPageList, &hBlockPageList, ui32NumPages, &bFromPagePool)) -+ { -+ goto failed_alloc_pages; -+ } -+ -+ psLinuxMemArea->eAreaType = LINUX_MEM_AREA_ALLOC_PAGES; -+ psLinuxMemArea->uData.sPageList.ppsPageList = ppsPageList; -+ psLinuxMemArea->uData.sPageList.hBlockPageList = hBlockPageList; -+ psLinuxMemArea->uiByteSize = uBytes; -+ psLinuxMemArea->ui32AreaFlags = ui32AreaFlags; -+ INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList); -+ -+ /* We defer the cache flush to the first user mapping of this memory */ -+ psLinuxMemArea->bNeedsCacheInvalidate = AreaIsUncached(ui32AreaFlags) && !bFromPagePool; -+ -+#if defined(DEBUG_LINUX_MEM_AREAS) -+ DebugLinuxMemAreaRecordAdd(psLinuxMemArea, ui32AreaFlags); -+#endif -+ -+ return psLinuxMemArea; -+ -+failed_alloc_pages: -+ LinuxMemAreaStructFree(psLinuxMemArea); -+failed_area_alloc: -+ PVR_DPF((PVR_DBG_ERROR, "%s: failed", __FUNCTION__)); -+ -+ return NULL; -+} -+ -+ -+IMG_VOID -+FreeAllocPagesLinuxMemArea(LinuxMemArea *psLinuxMemArea) -+{ -+ IMG_UINT32 ui32NumPages; -+ struct page **ppsPageList; -+ IMG_HANDLE hBlockPageList; -+ -+ PVR_ASSERT(psLinuxMemArea); -+ PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_ALLOC_PAGES); -+ -+#if defined(DEBUG_LINUX_MEM_AREAS) -+ DebugLinuxMemAreaRecordRemove(psLinuxMemArea); -+#endif -+ -+ ui32NumPages = RANGE_TO_PAGES(psLinuxMemArea->uiByteSize); -+ ppsPageList = psLinuxMemArea->uData.sPageList.ppsPageList; -+ hBlockPageList = psLinuxMemArea->uData.sPageList.hBlockPageList; -+ -+ FreePages(CanFreeToPool(psLinuxMemArea), ppsPageList, hBlockPageList, ui32NumPages); -+ -+ LinuxMemAreaStructFree(psLinuxMemArea); -+} -+ -+#if defined(CONFIG_ION_OMAP) -+ -+#include "env_perproc.h" -+ -+#include <linux/ion.h> -+#include <linux/omap_ion.h> -+ -+extern struct ion_client *gpsIONClient; -+ -+LinuxMemArea * -+NewIONLinuxMemArea(IMG_SIZE_T uBytes, IMG_UINT32 ui32AreaFlags, -+ IMG_PVOID pvPrivData, IMG_SIZE_T uiPrivDataLength) -+{ -+ const IMG_SIZE_T uiAllocDataLen = -+ offsetof(struct omap_ion_tiler_alloc_data, handle); -+ struct omap_ion_tiler_alloc_data asAllocData[2] = {}; -+ u32 *pu32PageAddrs[2] = { NULL, NULL }; -+ IMG_UINT32 i, ui32NumHandlesPerFd; -+ IMG_BYTE *pbPrivData = pvPrivData; -+ IMG_CPU_PHYADDR *pCPUPhysAddrs; -+ int iNumPages[2] = { 0, 0 }; -+ LinuxMemArea *psLinuxMemArea; -+ -+ psLinuxMemArea = LinuxMemAreaStructAlloc(); -+ if (!psLinuxMemArea) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: Failed to allocate LinuxMemArea struct", __func__)); -+ goto err_out; -+ } -+ -+ /* Depending on the UM config, userspace might give us info for -+ * one or two ION allocations. Divide the total size of data we -+ * were given by this ui32AllocDataLen, and check it's 1 or 2. -+ * Otherwise abort. -+ */ -+ BUG_ON(uiPrivDataLength != uiAllocDataLen && -+ uiPrivDataLength != uiAllocDataLen * 2); -+ ui32NumHandlesPerFd = uiPrivDataLength / uiAllocDataLen; -+ -+ /* Shuffle the alloc data into separate Y & UV bits and -+ * make two separate allocations via the tiler. -+ */ -+ for(i = 0; i < ui32NumHandlesPerFd; i++) -+ { -+ memcpy(&asAllocData[i], &pbPrivData[i * uiAllocDataLen], uiAllocDataLen); -+ -+ if (omap_ion_tiler_alloc(gpsIONClient, &asAllocData[i]) < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: Failed to allocate via ion_tiler", __func__)); -+ goto err_free; -+ } -+ -+ if (omap_tiler_pages(gpsIONClient, asAllocData[i].handle, &iNumPages[i], -+ &pu32PageAddrs[i]) < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: Failed to compute tiler pages", __func__)); -+ goto err_free; -+ } -+ } -+ -+ /* Assume the user-allocator has already done the tiler math and that the -+ * number of tiler pages allocated matches any other allocation type. -+ */ -+ BUG_ON(uBytes != (iNumPages[0] + iNumPages[1]) * PAGE_SIZE); -+ BUG_ON(sizeof(IMG_CPU_PHYADDR) != sizeof(int)); -+ -+ /* Glue the page lists together */ -+ pCPUPhysAddrs = vmalloc(sizeof(IMG_CPU_PHYADDR) * (iNumPages[0] + iNumPages[1])); -+ if (!pCPUPhysAddrs) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: Failed to allocate page list", __func__)); -+ goto err_free; -+ } -+ for(i = 0; i < iNumPages[0]; i++) -+ pCPUPhysAddrs[i].uiAddr = pu32PageAddrs[0][i]; -+ for(i = 0; i < iNumPages[1]; i++) -+ pCPUPhysAddrs[iNumPages[0] + i].uiAddr = pu32PageAddrs[1][i]; -+ -+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -+ DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_ION, -+ (IMG_UINTPTR_T)asAllocData[0].handle, -+ 0, -+ (IMG_CPU_PHYADDR){0}, -+ NULL, -+ PAGE_ALIGN(uBytes), -+ "unknown", -+ 0 -+ ); -+#endif -+ -+ for(i = 0; i < 2; i++) -+ psLinuxMemArea->uData.sIONTilerAlloc.psIONHandle[i] = asAllocData[i].handle; -+ -+ psLinuxMemArea->eAreaType = LINUX_MEM_AREA_ION; -+ psLinuxMemArea->uData.sIONTilerAlloc.pCPUPhysAddrs = pCPUPhysAddrs; -+ psLinuxMemArea->uiByteSize = uBytes; -+ psLinuxMemArea->ui32AreaFlags = ui32AreaFlags; -+ INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList); -+ -+ /* We defer the cache flush to the first user mapping of this memory */ -+ psLinuxMemArea->bNeedsCacheInvalidate = AreaIsUncached(ui32AreaFlags); -+ -+#if defined(DEBUG_LINUX_MEM_AREAS) -+ DebugLinuxMemAreaRecordAdd(psLinuxMemArea, ui32AreaFlags); -+#endif -+ -+err_out: -+ return psLinuxMemArea; -+ -+err_free: -+ LinuxMemAreaStructFree(psLinuxMemArea); -+ psLinuxMemArea = IMG_NULL; -+ goto err_out; -+} -+ -+ -+IMG_VOID -+FreeIONLinuxMemArea(LinuxMemArea *psLinuxMemArea) -+{ -+ IMG_UINT32 i; -+ -+#if defined(DEBUG_LINUX_MEM_AREAS) -+ DebugLinuxMemAreaRecordRemove(psLinuxMemArea); -+#endif -+ -+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -+ DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_ION, -+ (IMG_UINTPTR_T)psLinuxMemArea->uData.sIONTilerAlloc.psIONHandle[0], -+ __FILE__, __LINE__); -+#endif -+ -+ for(i = 0; i < 2; i++) -+ { -+ if (!psLinuxMemArea->uData.sIONTilerAlloc.psIONHandle[i]) -+ break; -+ ion_free(gpsIONClient, psLinuxMemArea->uData.sIONTilerAlloc.psIONHandle[i]); -+ psLinuxMemArea->uData.sIONTilerAlloc.psIONHandle[i] = IMG_NULL; -+ } -+ -+ /* free copy of page list, originals are freed by ion_free */ -+ vfree(psLinuxMemArea->uData.sIONTilerAlloc.pCPUPhysAddrs); -+ psLinuxMemArea->uData.sIONTilerAlloc.pCPUPhysAddrs = IMG_NULL; -+ -+ LinuxMemAreaStructFree(psLinuxMemArea); -+} -+ -+#endif /* defined(CONFIG_ION_OMAP) */ -+ -+struct page* -+LinuxMemAreaOffsetToPage(LinuxMemArea *psLinuxMemArea, -+ IMG_UINTPTR_T uByteOffset) -+{ -+ IMG_UINTPTR_T uPageIndex; -+ IMG_CHAR *pui8Addr; -+ -+ switch (psLinuxMemArea->eAreaType) -+ { -+ case LINUX_MEM_AREA_ALLOC_PAGES: -+ uPageIndex = PHYS_TO_PFN(uByteOffset); -+ return psLinuxMemArea->uData.sPageList.ppsPageList[uPageIndex]; -+ -+ case LINUX_MEM_AREA_VMALLOC: -+ pui8Addr = psLinuxMemArea->uData.sVmalloc.pvVmallocAddress; -+ pui8Addr += uByteOffset; -+ return vmalloc_to_page(pui8Addr); -+ -+ case LINUX_MEM_AREA_SUB_ALLOC: -+ /* PRQA S 3670 3 */ /* ignore recursive warning */ -+ return LinuxMemAreaOffsetToPage(psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea, -+ psLinuxMemArea->uData.sSubAlloc.uiByteOffset -+ + uByteOffset); -+ default: -+ PVR_DPF((PVR_DBG_ERROR, -+ "%s: Unsupported request for struct page from LinuxMemArea with type=%s", -+ __FUNCTION__, LinuxMemAreaTypeToString(psLinuxMemArea->eAreaType))); -+ return NULL; -+ } -+} -+ -+ -+LinuxKMemCache * -+KMemCacheCreateWrapper(IMG_CHAR *pszName, -+ size_t Size, -+ size_t Align, -+ IMG_UINT32 ui32Flags) -+{ -+#if defined(DEBUG_LINUX_SLAB_ALLOCATIONS) -+ ui32Flags |= SLAB_POISON|SLAB_RED_ZONE; -+#endif -+ return kmem_cache_create(pszName, Size, Align, ui32Flags, NULL -+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22)) -+ , NULL -+#endif /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22) */ -+ ); -+} -+ -+ -+IMG_VOID -+KMemCacheDestroyWrapper(LinuxKMemCache *psCache) -+{ -+ kmem_cache_destroy(psCache); -+} -+ -+ -+IMG_VOID * -+_KMemCacheAllocWrapper(LinuxKMemCache *psCache, -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)) -+ gfp_t Flags, -+#else -+ IMG_INT Flags, -+#endif -+ IMG_CHAR *pszFileName, -+ IMG_UINT32 ui32Line) -+{ -+ IMG_VOID *pvRet; -+ -+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -+ IMG_CPU_PHYADDR sCpuPAddr; -+#endif -+ -+ pvRet = kmem_cache_zalloc(psCache, Flags); -+ -+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -+ sCpuPAddr.uiAddr = 0; -+ DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE, -+ (IMG_UINTPTR_T)pvRet, -+ pvRet, -+ sCpuPAddr, -+ psCache, -+ kmem_cache_size(psCache), -+ pszFileName, -+ ui32Line -+ ); -+#else -+ PVR_UNREFERENCED_PARAMETER(pszFileName); -+ PVR_UNREFERENCED_PARAMETER(ui32Line); -+#endif -+ -+ return pvRet; -+} -+ -+ -+LinuxMemArea * -+NewSubLinuxMemArea(LinuxMemArea *psParentLinuxMemArea, -+ IMG_UINTPTR_T uiByteOffset, -+ IMG_SIZE_T uBytes) -+{ -+ LinuxMemArea *psLinuxMemArea; -+ -+ PVR_ASSERT((uiByteOffset + uBytes) <= psParentLinuxMemArea->uiByteSize); -+ -+ psLinuxMemArea = LinuxMemAreaStructAlloc(); -+ if (!psLinuxMemArea) -+ { -+ return NULL; -+ } -+ -+ psLinuxMemArea->eAreaType = LINUX_MEM_AREA_SUB_ALLOC; -+ psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea = psParentLinuxMemArea; -+ psLinuxMemArea->uData.sSubAlloc.uiByteOffset = uiByteOffset; -+ psLinuxMemArea->uiByteSize = uBytes; -+ psLinuxMemArea->ui32AreaFlags = psParentLinuxMemArea->ui32AreaFlags; -+ psLinuxMemArea->bNeedsCacheInvalidate = psParentLinuxMemArea->bNeedsCacheInvalidate; -+ INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList); -+ -+#if defined(DEBUG_LINUX_MEM_AREAS) -+ { -+ DEBUG_LINUX_MEM_AREA_REC *psParentRecord; -+ psParentRecord = DebugLinuxMemAreaRecordFind(psParentLinuxMemArea); -+ DebugLinuxMemAreaRecordAdd(psLinuxMemArea, psParentRecord->ui32Flags); -+ } -+#endif -+ -+ return psLinuxMemArea; -+} -+ -+ -+static IMG_VOID -+FreeSubLinuxMemArea(LinuxMemArea *psLinuxMemArea) -+{ -+ PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_SUB_ALLOC); -+ -+#if defined(DEBUG_LINUX_MEM_AREAS) -+ DebugLinuxMemAreaRecordRemove(psLinuxMemArea); -+#endif -+ -+ /* Nothing more to do than free the LinuxMemArea structure */ -+ -+ LinuxMemAreaStructFree(psLinuxMemArea); -+} -+ -+ -+static LinuxMemArea * -+LinuxMemAreaStructAlloc(IMG_VOID) -+{ -+/* debug */ -+#if 0 -+ LinuxMemArea *psLinuxMemArea; -+ psLinuxMemArea = kmem_cache_alloc(g_PsLinuxMemAreaCache, GFP_KERNEL); -+ printk(KERN_ERR "%s: psLinuxMemArea=%p\n", __FUNCTION__, psLinuxMemArea); -+ dump_stack(); -+ return psLinuxMemArea; -+#else -+ return KMemCacheAllocWrapper(g_PsLinuxMemAreaCache, GFP_KERNEL); -+#endif -+} -+ -+ -+static IMG_VOID -+LinuxMemAreaStructFree(LinuxMemArea *psLinuxMemArea) -+{ -+ KMemCacheFreeWrapper(g_PsLinuxMemAreaCache, psLinuxMemArea); -+ /* debug */ -+ //printk(KERN_ERR "%s(%p)\n", __FUNCTION__, psLinuxMemArea); -+} -+ -+ -+IMG_VOID -+LinuxMemAreaDeepFree(LinuxMemArea *psLinuxMemArea) -+{ -+ switch (psLinuxMemArea->eAreaType) -+ { -+ case LINUX_MEM_AREA_VMALLOC: -+ FreeVMallocLinuxMemArea(psLinuxMemArea); -+ break; -+ case LINUX_MEM_AREA_ALLOC_PAGES: -+ FreeAllocPagesLinuxMemArea(psLinuxMemArea); -+ break; -+ case LINUX_MEM_AREA_IOREMAP: -+ FreeIORemapLinuxMemArea(psLinuxMemArea); -+ break; -+ case LINUX_MEM_AREA_EXTERNAL_KV: -+ FreeExternalKVLinuxMemArea(psLinuxMemArea); -+ break; -+ case LINUX_MEM_AREA_IO: -+ FreeIOLinuxMemArea(psLinuxMemArea); -+ break; -+ case LINUX_MEM_AREA_SUB_ALLOC: -+ FreeSubLinuxMemArea(psLinuxMemArea); -+ break; -+ case LINUX_MEM_AREA_ION: -+ FreeIONLinuxMemArea(psLinuxMemArea); -+ break; -+ default: -+ PVR_DPF((PVR_DBG_ERROR, "%s: Unknown are type (%d)\n", -+ __FUNCTION__, psLinuxMemArea->eAreaType)); -+ break; -+ } -+} -+ -+ -+#if defined(DEBUG_LINUX_MEM_AREAS) -+static IMG_VOID -+DebugLinuxMemAreaRecordAdd(LinuxMemArea *psLinuxMemArea, IMG_UINT32 ui32Flags) -+{ -+ DEBUG_LINUX_MEM_AREA_REC *psNewRecord; -+ const IMG_CHAR *pi8FlagsString; -+ -+ LinuxLockMutexNested(&g_sDebugMutex, PVRSRV_LOCK_CLASS_MM_DEBUG); -+ -+ if (psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC) -+ { -+ g_LinuxMemAreaWaterMark += psLinuxMemArea->uiByteSize; -+ if (g_LinuxMemAreaWaterMark > g_LinuxMemAreaHighWaterMark) -+ { -+ g_LinuxMemAreaHighWaterMark = g_LinuxMemAreaWaterMark; -+ } -+ } -+ g_LinuxMemAreaCount++; -+ -+ /* Create a new memory allocation record */ -+ psNewRecord = kmalloc(sizeof(DEBUG_LINUX_MEM_AREA_REC), GFP_KERNEL); -+ if (psNewRecord) -+ { -+ /* Record the allocation */ -+ psNewRecord->psLinuxMemArea = psLinuxMemArea; -+ psNewRecord->ui32Flags = ui32Flags; -+ psNewRecord->pid = OSGetCurrentProcessIDKM(); -+ -+ List_DEBUG_LINUX_MEM_AREA_REC_Insert(&g_LinuxMemAreaRecords, psNewRecord); -+ } -+ else -+ { -+ PVR_DPF((PVR_DBG_ERROR, -+ "%s: failed to allocate linux memory area record.", -+ __FUNCTION__)); -+ } -+ -+ /* Sanity check the flags */ -+ pi8FlagsString = HAPFlagsToString(ui32Flags); -+ if (strstr(pi8FlagsString, "UNKNOWN")) -+ { -+ PVR_DPF((PVR_DBG_ERROR, -+ "%s: Unexpected flags (0x%08x) associated with psLinuxMemArea @ %p", -+ __FUNCTION__, -+ ui32Flags, -+ psLinuxMemArea)); -+ //dump_stack(); -+ } -+ -+ LinuxUnLockMutex(&g_sDebugMutex); -+} -+ -+ -+ -+static IMG_VOID* MatchLinuxMemArea_AnyVaCb(DEBUG_LINUX_MEM_AREA_REC *psCurrentRecord, -+ va_list va) -+{ -+ LinuxMemArea *psLinuxMemArea; -+ -+ psLinuxMemArea = va_arg(va, LinuxMemArea*); -+ if (psCurrentRecord->psLinuxMemArea == psLinuxMemArea) -+ { -+ return psCurrentRecord; -+ } -+ else -+ { -+ return IMG_NULL; -+ } -+} -+ -+ -+static DEBUG_LINUX_MEM_AREA_REC * -+DebugLinuxMemAreaRecordFind(LinuxMemArea *psLinuxMemArea) -+{ -+ DEBUG_LINUX_MEM_AREA_REC *psCurrentRecord; -+ -+ LinuxLockMutexNested(&g_sDebugMutex, PVRSRV_LOCK_CLASS_MM_DEBUG); -+ psCurrentRecord = List_DEBUG_LINUX_MEM_AREA_REC_Any_va(g_LinuxMemAreaRecords, -+ MatchLinuxMemArea_AnyVaCb, -+ psLinuxMemArea); -+ -+/*exit_unlock:*/ -+ LinuxUnLockMutex(&g_sDebugMutex); -+ -+ return psCurrentRecord; -+} -+ -+ -+static IMG_VOID -+DebugLinuxMemAreaRecordRemove(LinuxMemArea *psLinuxMemArea) -+{ -+ DEBUG_LINUX_MEM_AREA_REC *psCurrentRecord; -+ -+ LinuxLockMutexNested(&g_sDebugMutex, PVRSRV_LOCK_CLASS_MM_DEBUG); -+ -+ if (psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC) -+ { -+ g_LinuxMemAreaWaterMark -= psLinuxMemArea->uiByteSize; -+ } -+ g_LinuxMemAreaCount--; -+ -+ /* Locate the corresponding allocation entry */ -+ psCurrentRecord = List_DEBUG_LINUX_MEM_AREA_REC_Any_va(g_LinuxMemAreaRecords, -+ MatchLinuxMemArea_AnyVaCb, -+ psLinuxMemArea); -+ if (psCurrentRecord) -+ { -+ /* Unlink the allocation record */ -+ List_DEBUG_LINUX_MEM_AREA_REC_Remove(psCurrentRecord); -+ kfree(psCurrentRecord); -+ } -+ else -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: couldn't find an entry for psLinuxMemArea=%p\n", -+ __FUNCTION__, psLinuxMemArea)); -+ } -+ -+ LinuxUnLockMutex(&g_sDebugMutex); -+} -+#endif -+ -+ -+IMG_VOID * -+LinuxMemAreaToCpuVAddr(LinuxMemArea *psLinuxMemArea) -+{ -+ switch (psLinuxMemArea->eAreaType) -+ { -+ case LINUX_MEM_AREA_VMALLOC: -+ return psLinuxMemArea->uData.sVmalloc.pvVmallocAddress; -+ case LINUX_MEM_AREA_IOREMAP: -+ return psLinuxMemArea->uData.sIORemap.pvIORemapCookie; -+ case LINUX_MEM_AREA_EXTERNAL_KV: -+ return psLinuxMemArea->uData.sExternalKV.pvExternalKV; -+ case LINUX_MEM_AREA_SUB_ALLOC: -+ { -+ IMG_CHAR *pAddr = -+ LinuxMemAreaToCpuVAddr(psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea); /* PRQA S 3670 */ /* ignore recursive warning */ -+ if (!pAddr) -+ { -+ return NULL; -+ } -+ return pAddr + psLinuxMemArea->uData.sSubAlloc.uiByteOffset; -+ } -+ default: -+ return NULL; -+ } -+} -+ -+ -+IMG_CPU_PHYADDR -+LinuxMemAreaToCpuPAddr(LinuxMemArea *psLinuxMemArea, IMG_UINTPTR_T uiByteOffset) -+{ -+ IMG_CPU_PHYADDR CpuPAddr; -+ -+ CpuPAddr.uiAddr = 0; -+ -+ switch (psLinuxMemArea->eAreaType) -+ { -+ case LINUX_MEM_AREA_IOREMAP: -+ { -+ CpuPAddr = psLinuxMemArea->uData.sIORemap.CPUPhysAddr; -+ CpuPAddr.uiAddr += uiByteOffset; -+ break; -+ } -+ case LINUX_MEM_AREA_EXTERNAL_KV: -+ { -+ if (psLinuxMemArea->uData.sExternalKV.bPhysContig) -+ { -+ CpuPAddr = SysSysPAddrToCpuPAddr(psLinuxMemArea->uData.sExternalKV.uPhysAddr.SysPhysAddr); -+ CpuPAddr.uiAddr += uiByteOffset; -+ } -+ else -+ { -+ IMG_UINTPTR_T uiPageIndex = PHYS_TO_PFN(uiByteOffset); -+ IMG_SYS_PHYADDR SysPAddr = psLinuxMemArea->uData.sExternalKV.uPhysAddr.pSysPhysAddr[uiPageIndex]; -+ -+ CpuPAddr = SysSysPAddrToCpuPAddr(SysPAddr); -+ CpuPAddr.uiAddr += ADDR_TO_PAGE_OFFSET(uiByteOffset); -+ } -+ break; -+ } -+ case LINUX_MEM_AREA_IO: -+ { -+ CpuPAddr = psLinuxMemArea->uData.sIO.CPUPhysAddr; -+ CpuPAddr.uiAddr += uiByteOffset; -+ break; -+ } -+ case LINUX_MEM_AREA_VMALLOC: -+ { -+ IMG_CHAR *pCpuVAddr; -+ pCpuVAddr = -+ (IMG_CHAR *)psLinuxMemArea->uData.sVmalloc.pvVmallocAddress; -+ pCpuVAddr += uiByteOffset; -+ CpuPAddr.uiAddr = VMallocToPhys(pCpuVAddr); -+ break; -+ } -+ case LINUX_MEM_AREA_ION: -+ { -+ IMG_UINTPTR_T uiPageIndex = PHYS_TO_PFN(uiByteOffset); -+ CpuPAddr = psLinuxMemArea->uData.sIONTilerAlloc.pCPUPhysAddrs[uiPageIndex]; -+ CpuPAddr.uiAddr += ADDR_TO_PAGE_OFFSET(uiByteOffset); -+ break; -+ } -+ case LINUX_MEM_AREA_ALLOC_PAGES: -+ { -+ struct page *page; -+ IMG_UINTPTR_T uiPageIndex = PHYS_TO_PFN(uiByteOffset); -+ page = psLinuxMemArea->uData.sPageList.ppsPageList[uiPageIndex]; -+ CpuPAddr.uiAddr = page_to_phys(page); -+ CpuPAddr.uiAddr += ADDR_TO_PAGE_OFFSET(uiByteOffset); -+ break; -+ } -+ case LINUX_MEM_AREA_SUB_ALLOC: -+ { -+ CpuPAddr = -+ OSMemHandleToCpuPAddr(psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea, -+ psLinuxMemArea->uData.sSubAlloc.uiByteOffset -+ + uiByteOffset); -+ break; -+ } -+ default: -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: Unknown LinuxMemArea type (%d)\n", -+ __FUNCTION__, psLinuxMemArea->eAreaType)); -+ PVR_ASSERT(CpuPAddr.uiAddr); -+ break; -+ } -+ } -+ -+ return CpuPAddr; -+} -+ -+ -+IMG_BOOL -+LinuxMemAreaPhysIsContig(LinuxMemArea *psLinuxMemArea) -+{ -+ switch (psLinuxMemArea->eAreaType) -+ { -+ case LINUX_MEM_AREA_IOREMAP: -+ case LINUX_MEM_AREA_IO: -+ return IMG_TRUE; -+ -+ case LINUX_MEM_AREA_EXTERNAL_KV: -+ return psLinuxMemArea->uData.sExternalKV.bPhysContig; -+ -+ case LINUX_MEM_AREA_ION: -+ case LINUX_MEM_AREA_VMALLOC: -+ case LINUX_MEM_AREA_ALLOC_PAGES: -+ return IMG_FALSE; -+ -+ case LINUX_MEM_AREA_SUB_ALLOC: -+ /* PRQA S 3670 1 */ /* ignore recursive warning */ -+ return LinuxMemAreaPhysIsContig(psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea); -+ -+ default: -+ PVR_DPF((PVR_DBG_ERROR, "%s: Unknown LinuxMemArea type (%d)\n", -+ __FUNCTION__, psLinuxMemArea->eAreaType)); -+ break; -+ } -+ return IMG_FALSE; -+} -+ -+ -+const IMG_CHAR * -+LinuxMemAreaTypeToString(LINUX_MEM_AREA_TYPE eMemAreaType) -+{ -+ /* Note we explicitly check the types instead of e.g. -+ * using the type to index an array of strings so -+ * we remain orthogonal to enum changes */ -+ switch (eMemAreaType) -+ { -+ case LINUX_MEM_AREA_IOREMAP: -+ return "LINUX_MEM_AREA_IOREMAP"; -+ case LINUX_MEM_AREA_EXTERNAL_KV: -+ return "LINUX_MEM_AREA_EXTERNAL_KV"; -+ case LINUX_MEM_AREA_IO: -+ return "LINUX_MEM_AREA_IO"; -+ case LINUX_MEM_AREA_VMALLOC: -+ return "LINUX_MEM_AREA_VMALLOC"; -+ case LINUX_MEM_AREA_SUB_ALLOC: -+ return "LINUX_MEM_AREA_SUB_ALLOC"; -+ case LINUX_MEM_AREA_ALLOC_PAGES: -+ return "LINUX_MEM_AREA_ALLOC_PAGES"; -+ case LINUX_MEM_AREA_ION: -+ return "LINUX_MEM_AREA_ION"; -+ default: -+ PVR_ASSERT(0); -+ } -+ -+ return ""; -+} -+ -+ -+#if defined(DEBUG_LINUX_MEM_AREAS) || defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -+static void ProcSeqStartstopDebugMutex(struct seq_file *sfile, IMG_BOOL start) -+{ -+ if (start) -+ { -+ LinuxLockMutexNested(&g_sDebugMutex, PVRSRV_LOCK_CLASS_MM_DEBUG); -+ } -+ else -+ { -+ LinuxUnLockMutex(&g_sDebugMutex); -+ } -+} -+#endif /* defined(DEBUG_LINUX_MEM_AREAS) || defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) */ -+ -+#if defined(DEBUG_LINUX_MEM_AREAS) -+ -+static IMG_VOID* DecOffMemAreaRec_AnyVaCb(DEBUG_LINUX_MEM_AREA_REC *psNode, va_list va) -+{ -+ off_t *pOff = va_arg(va, off_t*); -+ if (--(*pOff)) -+ { -+ return IMG_NULL; -+ } -+ else -+ { -+ return psNode; -+ } -+} -+ -+/* seq_file version of generating output, for reference check proc.c:CreateProcReadEntrySeq */ -+static void* ProcSeqNextMemArea(struct seq_file *sfile,void* el,loff_t off) -+{ -+ DEBUG_LINUX_MEM_AREA_REC *psRecord; -+ psRecord = (DEBUG_LINUX_MEM_AREA_REC*) -+ List_DEBUG_LINUX_MEM_AREA_REC_Any_va(g_LinuxMemAreaRecords, -+ DecOffMemAreaRec_AnyVaCb, -+ &off); -+ return (void*)psRecord; -+} -+ -+static void* ProcSeqOff2ElementMemArea(struct seq_file * sfile, loff_t off) -+{ -+ DEBUG_LINUX_MEM_AREA_REC *psRecord; -+ if (!off) -+ { -+ return PVR_PROC_SEQ_START_TOKEN; -+ } -+ -+ psRecord = (DEBUG_LINUX_MEM_AREA_REC*) -+ List_DEBUG_LINUX_MEM_AREA_REC_Any_va(g_LinuxMemAreaRecords, -+ DecOffMemAreaRec_AnyVaCb, -+ &off); -+ return (void*)psRecord; -+} -+ -+ -+static void ProcSeqShowMemArea(struct seq_file *sfile,void* el) -+{ -+ DEBUG_LINUX_MEM_AREA_REC *psRecord = (DEBUG_LINUX_MEM_AREA_REC*)el; -+ if (el == PVR_PROC_SEQ_START_TOKEN) -+ { -+ -+#if !defined(DEBUG_LINUX_XML_PROC_FILES) -+ seq_printf(sfile, -+ "Number of Linux Memory Areas: %u\n" -+ "At the current water mark these areas correspond to %u bytes (excluding SUB areas)\n" -+ "At the highest water mark these areas corresponded to %u bytes (excluding SUB areas)\n" -+ "\nDetails for all Linux Memory Areas:\n" -+ "%s %-24s %s %s %-8s %-5s %s\n", -+ g_LinuxMemAreaCount, -+ g_LinuxMemAreaWaterMark, -+ g_LinuxMemAreaHighWaterMark, -+ "psLinuxMemArea", -+ "LinuxMemType", -+ "CpuVAddr", -+ "CpuPAddr", -+ "Bytes", -+ "Pid", -+ "Flags" -+ ); -+#else -+ seq_printf(sfile, -+ "<mem_areas_header>\n" -+ "\t<count>%u</count>\n" -+ "\t<watermark key=\"mar0\" description=\"current\" bytes=\"%u\"/>\n" /* (excluding SUB areas) */ -+ "\t<watermark key=\"mar1\" description=\"high\" bytes=\"%u\"/>\n" /* (excluding SUB areas) */ -+ "</mem_areas_header>\n", -+ g_LinuxMemAreaCount, -+ g_LinuxMemAreaWaterMark, -+ g_LinuxMemAreaHighWaterMark -+ ); -+#endif -+ return; -+ } -+ -+ seq_printf(sfile, -+#if !defined(DEBUG_LINUX_XML_PROC_FILES) -+ "%p %-24s %p " CPUPADDR_FMT " %" SIZE_T_FMT_LEN "u %-5u %08x=(%s)\n", -+#else -+ "<linux_mem_area>\n" -+ "\t<pointer>%p</pointer>\n" -+ "\t<type>%s</type>\n" -+ "\t<cpu_virtual>%p</cpu_virtual>\n" -+ "\t<cpu_physical>" CPUPADDR_FMT "</cpu_physical>\n" -+ "\t<bytes>%" SIZE_T_FMT_LEN "d</bytes>\n" -+ "\t<pid>%u</pid>\n" -+ "\t<flags>%08x</flags>\n" -+ "\t<flags_string>%s</flags_string>\n" -+ "</linux_mem_area>\n", -+#endif -+ psRecord->psLinuxMemArea, -+ LinuxMemAreaTypeToString(psRecord->psLinuxMemArea->eAreaType), -+ LinuxMemAreaToCpuVAddr(psRecord->psLinuxMemArea), -+ LinuxMemAreaToCpuPAddr(psRecord->psLinuxMemArea,0).uiAddr, -+ psRecord->psLinuxMemArea->uiByteSize, -+ psRecord->pid, -+ psRecord->ui32Flags, -+ HAPFlagsToString(psRecord->ui32Flags) -+ ); -+ -+} -+ -+#endif /* DEBUG_LINUX_MEM_AREAS */ -+ -+ -+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -+ -+static IMG_VOID* DecOffMemAllocRec_AnyVaCb(DEBUG_MEM_ALLOC_REC *psNode, va_list va) -+{ -+ off_t *pOff = va_arg(va, off_t*); -+ if (--(*pOff)) -+ { -+ return IMG_NULL; -+ } -+ else -+ { -+ return psNode; -+ } -+} -+ -+ -+/* seq_file version of generating output, for reference check proc.c:CreateProcReadEntrySeq */ -+static void* ProcSeqNextMemoryRecords(struct seq_file *sfile,void* el,loff_t off) -+{ -+ DEBUG_MEM_ALLOC_REC *psRecord; -+ psRecord = (DEBUG_MEM_ALLOC_REC*) -+ List_DEBUG_MEM_ALLOC_REC_Any_va(g_MemoryRecords, -+ DecOffMemAllocRec_AnyVaCb, -+ &off); -+#if defined(DEBUG_LINUX_XML_PROC_FILES) -+ if (!psRecord) -+ { -+ seq_printf(sfile, "</meminfo>\n"); -+ } -+#endif -+ -+ return (void*)psRecord; -+} -+ -+static void* ProcSeqOff2ElementMemoryRecords(struct seq_file *sfile, loff_t off) -+{ -+ DEBUG_MEM_ALLOC_REC *psRecord; -+ if (!off) -+ { -+ return PVR_PROC_SEQ_START_TOKEN; -+ } -+ -+ psRecord = (DEBUG_MEM_ALLOC_REC*) -+ List_DEBUG_MEM_ALLOC_REC_Any_va(g_MemoryRecords, -+ DecOffMemAllocRec_AnyVaCb, -+ &off); -+ -+#if defined(DEBUG_LINUX_XML_PROC_FILES) -+ if (!psRecord) -+ { -+ seq_printf(sfile, "</meminfo>\n"); -+ } -+#endif -+ -+ return (void*)psRecord; -+} -+ -+static void ProcSeqShowMemoryRecords(struct seq_file *sfile,void* el) -+{ -+ DEBUG_MEM_ALLOC_REC *psRecord = (DEBUG_MEM_ALLOC_REC*)el; -+ if (el == PVR_PROC_SEQ_START_TOKEN) -+ { -+#if !defined(DEBUG_LINUX_XML_PROC_FILES) -+ /* NOTE: If you update this code, please also update the XML varient below -+ * too! */ -+ -+ seq_printf(sfile, "%-60s: %d bytes\n", -+ "Current Water Mark of bytes allocated via kmalloc", -+ g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMALLOC]); -+ seq_printf(sfile, "%-60s: %d bytes\n", -+ "Highest Water Mark of bytes allocated via kmalloc", -+ g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMALLOC]); -+ seq_printf(sfile, "%-60s: %d bytes\n", -+ "Current Water Mark of bytes allocated via vmalloc", -+ g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMALLOC]); -+ seq_printf(sfile, "%-60s: %d bytes\n", -+ "Highest Water Mark of bytes allocated via vmalloc", -+ g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMALLOC]); -+ seq_printf(sfile, "%-60s: %d bytes\n", -+ "Current Water Mark of bytes allocated via alloc_pages", -+ g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES]); -+ seq_printf(sfile, "%-60s: %d bytes\n", -+ "Highest Water Mark of bytes allocated via alloc_pages", -+ g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES]); -+ seq_printf(sfile, "%-60s: %d bytes\n", -+ "Current Water Mark of bytes allocated via ioremap", -+ g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_IOREMAP]); -+ seq_printf(sfile, "%-60s: %d bytes\n", -+ "Highest Water Mark of bytes allocated via ioremap", -+ g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_IOREMAP]); -+ seq_printf(sfile, "%-60s: %d bytes\n", -+ "Current Water Mark of bytes reserved for \"IO\" memory areas", -+ g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_IO]); -+ seq_printf(sfile, "%-60s: %d bytes\n", -+ "Highest Water Mark of bytes allocated for \"IO\" memory areas", -+ g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_IO]); -+ seq_printf(sfile, "%-60s: %d bytes\n", -+ "Current Water Mark of bytes allocated via kmem_cache_alloc", -+ g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE]); -+ seq_printf(sfile, "%-60s: %d bytes\n", -+ "Highest Water Mark of bytes allocated via kmem_cache_alloc", -+ g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE]); -+#if defined(PVR_LINUX_MEM_AREA_USE_VMAP) -+ seq_printf(sfile, "%-60s: %d bytes\n", -+ "Current Water Mark of bytes mapped via vmap", -+ g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMAP]); -+ seq_printf(sfile, "%-60s: %d bytes\n", -+ "Highest Water Mark of bytes mapped via vmap", -+ g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMAP]); -+#endif -+#if (PVR_LINUX_MEM_AREA_POOL_MAX_PAGES != 0) -+ seq_printf(sfile, "%-60s: %d pages\n", -+ "Number of pages in page pool", -+ atomic_read(&g_sPagePoolEntryCount)); -+#endif -+ seq_printf( sfile, "\n"); -+ seq_printf(sfile, "%-60s: %d bytes\n", -+ "The Current Water Mark for memory allocated from system RAM", -+ SysRAMTrueWaterMark()); -+ seq_printf(sfile, "%-60s: %d bytes\n", -+ "The Highest Water Mark for memory allocated from system RAM", -+ g_SysRAMHighWaterMark); -+ seq_printf(sfile, "%-60s: %d bytes\n", -+ "The Current Water Mark for memory allocated from IO memory", -+ g_IOMemWaterMark); -+ seq_printf(sfile, "%-60s: %d bytes\n", -+ "The Highest Water Mark for memory allocated from IO memory", -+ g_IOMemHighWaterMark); -+ -+ seq_printf( sfile, "\n"); -+ -+ seq_printf(sfile, "Details for all known allocations:\n" -+ "%-16s %-8s %-8s %-10s %-5s %-10s %s\n", -+ "Type", -+ "CpuVAddr", -+ "CpuPAddr", -+ "Bytes", -+ "PID", -+ "PrivateData", -+ "Filename:Line"); -+ -+#else /* DEBUG_LINUX_XML_PROC_FILES */ -+ -+ /* Note: If you want to update the description property of a watermark -+ * ensure that the key property remains unchanged so that watermark data -+ * logged over time from different driver revisions may remain comparable -+ */ -+ seq_printf(sfile, "<meminfo>\n<meminfo_header>\n"); -+ seq_printf(sfile, -+ "<watermark key=\"mr0\" description=\"kmalloc_current\" bytes=\"%d\"/>\n", -+ g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMALLOC]); -+ seq_printf(sfile, -+ "<watermark key=\"mr1\" description=\"kmalloc_high\" bytes=\"%d\"/>\n", -+ g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMALLOC]); -+ seq_printf(sfile, -+ "<watermark key=\"mr2\" description=\"vmalloc_current\" bytes=\"%d\"/>\n", -+ g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMALLOC]); -+ seq_printf(sfile, -+ "<watermark key=\"mr3\" description=\"vmalloc_high\" bytes=\"%d\"/>\n", -+ g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMALLOC]); -+ seq_printf(sfile, -+ "<watermark key=\"mr4\" description=\"alloc_pages_current\" bytes=\"%d\"/>\n", -+ g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES]); -+ seq_printf(sfile, -+ "<watermark key=\"mr5\" description=\"alloc_pages_high\" bytes=\"%d\"/>\n", -+ g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES]); -+ seq_printf(sfile, -+ "<watermark key=\"mr6\" description=\"ioremap_current\" bytes=\"%d\"/>\n", -+ g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_IOREMAP]); -+ seq_printf(sfile, -+ "<watermark key=\"mr7\" description=\"ioremap_high\" bytes=\"%d\"/>\n", -+ g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_IOREMAP]); -+ seq_printf(sfile, -+ "<watermark key=\"mr8\" description=\"io_current\" bytes=\"%d\"/>\n", -+ g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_IO]); -+ seq_printf(sfile, -+ "<watermark key=\"mr9\" description=\"io_high\" bytes=\"%d\"/>\n", -+ g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_IO]); -+ seq_printf(sfile, -+ "<watermark key=\"mr10\" description=\"kmem_cache_current\" bytes=\"%d\"/>\n", -+ g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE]); -+ seq_printf(sfile, -+ "<watermark key=\"mr11\" description=\"kmem_cache_high\" bytes=\"%d\"/>\n", -+ g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE]); -+#if defined(PVR_LINUX_MEM_AREA_USE_VMAP) -+ seq_printf(sfile, -+ "<watermark key=\"mr12\" description=\"vmap_current\" bytes=\"%d\"/>\n", -+ g_WaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMAP]); -+ seq_printf(sfile, -+ "<watermark key=\"mr13\" description=\"vmap_high\" bytes=\"%d\"/>\n", -+ g_HighWaterMarkData[DEBUG_MEM_ALLOC_TYPE_VMAP]); -+#endif -+ seq_printf(sfile, -+ "<watermark key=\"mr14\" description=\"system_ram_current\" bytes=\"%d\"/>\n", -+ SysRAMTrueWaterMark()); -+ seq_printf(sfile, -+ "<watermark key=\"mr15\" description=\"system_ram_high\" bytes=\"%d\"/>\n", -+ g_SysRAMHighWaterMark); -+ seq_printf(sfile, -+ "<watermark key=\"mr16\" description=\"system_io_current\" bytes=\"%d\"/>\n", -+ g_IOMemWaterMark); -+ seq_printf(sfile, -+ "<watermark key=\"mr17\" description=\"system_io_high\" bytes=\"%d\"/>\n", -+ g_IOMemHighWaterMark); -+ -+#if (PVR_LINUX_MEM_AREA_POOL_MAX_PAGES != 0) -+ seq_printf(sfile, -+ "<watermark key=\"mr18\" description=\"page_pool_current\" bytes=\"%d\"/>\n", -+ PAGES_TO_BYTES(atomic_read(&g_sPagePoolEntryCount))); -+#endif -+ seq_printf(sfile, "</meminfo_header>\n"); -+ -+#endif /* DEBUG_LINUX_XML_PROC_FILES */ -+ return; -+ } -+ -+ if (psRecord->eAllocType != DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE) -+ { -+ seq_printf(sfile, -+#if !defined(DEBUG_LINUX_XML_PROC_FILES) -+ "%-16s %p " CPUPADDR_FMT " %" SIZE_T_FMT_LEN "u %-5d %-10s %s:%d\n", -+#else -+ "<allocation>\n" -+ "\t<type>%s</type>\n" -+ "\t<cpu_virtual>%p</cpu_virtual>\n" -+ "\t<cpu_physical>" CPUPADDR_FMT "</cpu_physical>\n" -+ "\t<bytes>%" SIZE_T_FMT_LEN "u</bytes>\n" -+ "\t<pid>%d</pid>\n" -+ "\t<private>%s</private>\n" -+ "\t<filename>%s</filename>\n" -+ "\t<line>%d</line>\n" -+ "</allocation>\n", -+#endif -+ DebugMemAllocRecordTypeToString(psRecord->eAllocType), -+ psRecord->pvCpuVAddr, -+ psRecord->sCpuPAddr.uiAddr, -+ psRecord->uiBytes, -+ psRecord->pid, -+ "NULL", -+ psRecord->pszFileName, -+ psRecord->ui32Line); -+ } -+ else -+ { -+ seq_printf(sfile, -+#if !defined(DEBUG_LINUX_XML_PROC_FILES) -+ "%-16s %p " CPUPADDR_FMT " %" SIZE_T_FMT_LEN "u %-5d %-10s %s:%d\n", -+#else -+ "<allocation>\n" -+ "\t<type>%s</type>\n" -+ "\t<cpu_virtual>%p</cpu_virtual>\n" -+ "\t<cpu_physical>" CPUPADDR_FMT "</cpu_physical>\n" -+ "\t<bytes>%" SIZE_T_FMT_LEN "u</bytes>\n" -+ "\t<pid>%d</pid>\n" -+ "\t<private>%s</private>\n" -+ "\t<filename>%s</filename>\n" -+ "\t<line>%d</line>\n" -+ "</allocation>\n", -+#endif -+ DebugMemAllocRecordTypeToString(psRecord->eAllocType), -+ psRecord->pvCpuVAddr, -+ psRecord->sCpuPAddr.uiAddr, -+ psRecord->uiBytes, -+ psRecord->pid, -+ KMemCacheNameWrapper(psRecord->pvPrivateData), -+ psRecord->pszFileName, -+ psRecord->ui32Line); -+ } -+} -+ -+#endif /* defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) */ -+ -+ -+#if defined(DEBUG_LINUX_MEM_AREAS) || defined(DEBUG_LINUX_MMAP_AREAS) -+/* This could be moved somewhere more general */ -+const IMG_CHAR * -+HAPFlagsToString(IMG_UINT32 ui32Flags) -+{ -+ static IMG_CHAR szFlags[50]; -+ IMG_INT32 i32Pos = 0; -+ IMG_UINT32 ui32CacheTypeIndex, ui32MapTypeIndex; -+ IMG_CHAR *apszCacheTypes[] = { -+ "UNCACHED", -+ "CACHED", -+ "WRITECOMBINE", -+ "UNKNOWN" -+ }; -+ IMG_CHAR *apszMapType[] = { -+ "KERNEL_ONLY", -+ "SINGLE_PROCESS", -+ "MULTI_PROCESS", -+ "FROM_EXISTING_PROCESS", -+ "NO_CPU_VIRTUAL", -+ "UNKNOWN" -+ }; -+ -+ /* FIXME create an enum for the cache type that we can -+ * cast and select so we get compiler warnings when -+ * when this code isn't complete due to new flags */ -+ if (ui32Flags & PVRSRV_HAP_UNCACHED) { -+ ui32CacheTypeIndex = 0; -+ } else if (ui32Flags & PVRSRV_HAP_CACHED) { -+ ui32CacheTypeIndex = 1; -+ } else if (ui32Flags & PVRSRV_HAP_WRITECOMBINE) { -+ ui32CacheTypeIndex = 2; -+ } else { -+ ui32CacheTypeIndex = 3; -+ PVR_DPF((PVR_DBG_ERROR, "%s: unknown cache type (%u)", -+ __FUNCTION__, (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK))); -+ } -+ -+ /* FIXME create an enum for the map type that we can -+ * cast and select so we get compiler warnings when -+ * when this code isn't complete due to new flags */ -+ if (ui32Flags & PVRSRV_HAP_KERNEL_ONLY) { -+ ui32MapTypeIndex = 0; -+ } else if (ui32Flags & PVRSRV_HAP_SINGLE_PROCESS) { -+ ui32MapTypeIndex = 1; -+ } else if (ui32Flags & PVRSRV_HAP_MULTI_PROCESS) { -+ ui32MapTypeIndex = 2; -+ } else if (ui32Flags & PVRSRV_HAP_FROM_EXISTING_PROCESS) { -+ ui32MapTypeIndex = 3; -+ } else if (ui32Flags & PVRSRV_HAP_NO_CPU_VIRTUAL) { -+ ui32MapTypeIndex = 4; -+ } else { -+ ui32MapTypeIndex = 5; -+ PVR_DPF((PVR_DBG_ERROR, "%s: unknown map type (%u)", -+ __FUNCTION__, (ui32Flags & PVRSRV_HAP_MAPTYPE_MASK))); -+ } -+ -+ i32Pos = sprintf(szFlags, "%s|", apszCacheTypes[ui32CacheTypeIndex]); -+ if (i32Pos <= 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: sprintf for cache type %u failed (%d)", -+ __FUNCTION__, ui32CacheTypeIndex, i32Pos)); -+ szFlags[0] = 0; -+ } -+ else -+ { -+ sprintf(szFlags + i32Pos, "%s", apszMapType[ui32MapTypeIndex]); -+ } -+ -+ return szFlags; -+} -+#endif -+ -+#if defined(DEBUG_LINUX_MEM_AREAS) -+static IMG_VOID LinuxMMCleanup_MemAreas_ForEachCb(DEBUG_LINUX_MEM_AREA_REC *psCurrentRecord) -+{ -+ LinuxMemArea *psLinuxMemArea; -+ -+ psLinuxMemArea = psCurrentRecord->psLinuxMemArea; -+ PVR_DPF((PVR_DBG_ERROR, "%s: BUG!: Cleaning up Linux memory area (%p), type=%s, size=%"SIZE_T_FMT_LEN"d bytes", -+ __FUNCTION__, -+ psCurrentRecord->psLinuxMemArea, -+ LinuxMemAreaTypeToString(psCurrentRecord->psLinuxMemArea->eAreaType), -+ psCurrentRecord->psLinuxMemArea->uiByteSize)); -+ /* Note this will also remove psCurrentRecord from g_LinuxMemAreaRecords -+ * but that's ok since we have already got a pointer to the next area. */ -+ LinuxMemAreaDeepFree(psLinuxMemArea); -+} -+#endif -+ -+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -+static IMG_VOID LinuxMMCleanup_MemRecords_ForEachVa(DEBUG_MEM_ALLOC_REC *psCurrentRecord) -+ -+{ -+ -+/* It's a bug if anything remains allocated at this point. We -+ * report an error, and simply brute force free anything we find. */ -+ PVR_DPF((PVR_DBG_ERROR, "%s: BUG!: Cleaning up memory: " -+ "type=%s " -+ "CpuVAddr=%p " -+ "CpuPAddr=0x" CPUPADDR_FMT ", " -+ "allocated @ file=%s,line=%d", -+ __FUNCTION__, -+ DebugMemAllocRecordTypeToString(psCurrentRecord->eAllocType), -+ psCurrentRecord->pvCpuVAddr, -+ psCurrentRecord->sCpuPAddr.uiAddr, -+ psCurrentRecord->pszFileName, -+ psCurrentRecord->ui32Line)); -+ switch (psCurrentRecord->eAllocType) -+ { -+ case DEBUG_MEM_ALLOC_TYPE_KMALLOC: -+ KFreeWrapper(psCurrentRecord->pvCpuVAddr); -+ break; -+ case DEBUG_MEM_ALLOC_TYPE_IOREMAP: -+ IOUnmapWrapper(psCurrentRecord->pvCpuVAddr); -+ break; -+ case DEBUG_MEM_ALLOC_TYPE_IO: -+ /* Nothing needed except to free the record */ -+ DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_IO, psCurrentRecord->uiKey, __FILE__, __LINE__); -+ break; -+ case DEBUG_MEM_ALLOC_TYPE_VMALLOC: -+ VFreeWrapper(psCurrentRecord->pvCpuVAddr); -+ break; -+ case DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES: -+ DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES, psCurrentRecord->uiKey, __FILE__, __LINE__); -+ break; -+ case DEBUG_MEM_ALLOC_TYPE_KMEM_CACHE: -+ KMemCacheFreeWrapper(psCurrentRecord->pvPrivateData, psCurrentRecord->pvCpuVAddr); -+ break; -+#if defined(PVR_LINUX_MEM_AREA_USE_VMAP) -+ case DEBUG_MEM_ALLOC_TYPE_VMAP: -+ VUnmapWrapper(psCurrentRecord->pvCpuVAddr); -+ break; -+#endif -+ default: -+ PVR_ASSERT(0); -+ } -+} -+#endif -+ -+ -+#if defined(PVR_LINUX_MEM_AREA_POOL_ALLOW_SHRINK) -+static struct shrinker g_sShrinker = -+{ -+ .shrink = ShrinkPagePool, -+ .seeks = DEFAULT_SEEKS -+}; -+ -+static IMG_BOOL g_bShrinkerRegistered; -+#endif -+ -+IMG_VOID -+LinuxMMCleanup(IMG_VOID) -+{ -+#if defined(DEBUG_LINUX_MEM_AREAS) -+ { -+ if (g_LinuxMemAreaCount) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: BUG!: There are %d LinuxMemArea allocation unfreed (%d bytes)", -+ __FUNCTION__, g_LinuxMemAreaCount, g_LinuxMemAreaWaterMark)); -+ } -+ -+ List_DEBUG_LINUX_MEM_AREA_REC_ForEach(g_LinuxMemAreaRecords, LinuxMMCleanup_MemAreas_ForEachCb); -+ -+ if (g_SeqFileMemArea) -+ { -+ RemoveProcEntrySeq(g_SeqFileMemArea); -+ } -+ } -+#endif -+ -+#if defined(PVR_LINUX_MEM_AREA_POOL_ALLOW_SHRINK) -+ if (g_bShrinkerRegistered) -+ { -+ unregister_shrinker(&g_sShrinker); -+ } -+#endif -+ -+ /* -+ * The page pool must be freed after any remaining mem areas, but before -+ * the remaining memory resources. -+ */ -+ FreePagePool(); -+ -+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -+ { -+ -+ /* -+ * It's a bug if anything remains allocated at this point. We -+ * report an error, and simply brute force free anything we find. -+ */ -+ List_DEBUG_MEM_ALLOC_REC_ForEach(g_MemoryRecords, LinuxMMCleanup_MemRecords_ForEachVa); -+ -+ if (g_SeqFileMemoryRecords) -+ { -+ RemoveProcEntrySeq(g_SeqFileMemoryRecords); -+ } -+ } -+#endif -+ -+ if (g_PsLinuxMemAreaCache) -+ { -+ KMemCacheDestroyWrapper(g_PsLinuxMemAreaCache); -+ } -+ -+ if (g_PsLinuxPagePoolCache) -+ { -+ KMemCacheDestroyWrapper(g_PsLinuxPagePoolCache); -+ } -+} -+ -+PVRSRV_ERROR -+LinuxMMInit(IMG_VOID) -+{ -+#if defined(DEBUG_LINUX_MEM_AREAS) || defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -+ LinuxInitMutex(&g_sDebugMutex); -+#endif -+ -+#if defined(DEBUG_LINUX_MEM_AREAS) -+ { -+ g_SeqFileMemArea = CreateProcReadEntrySeq( -+ "mem_areas", -+ NULL, -+ ProcSeqNextMemArea, -+ ProcSeqShowMemArea, -+ ProcSeqOff2ElementMemArea, -+ ProcSeqStartstopDebugMutex -+ ); -+ if (!g_SeqFileMemArea) -+ { -+ goto failed; -+ } -+ } -+#endif -+ -+ -+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -+ { -+ g_SeqFileMemoryRecords = CreateProcReadEntrySeq( -+ "meminfo", -+ NULL, -+ ProcSeqNextMemoryRecords, -+ ProcSeqShowMemoryRecords, -+ ProcSeqOff2ElementMemoryRecords, -+ ProcSeqStartstopDebugMutex -+ ); -+ if (!g_SeqFileMemoryRecords) -+ { -+ goto failed; -+ } -+ } -+#endif -+ -+ g_PsLinuxMemAreaCache = KMemCacheCreateWrapper("img-mm", sizeof(LinuxMemArea), 0, 0); -+ if (!g_PsLinuxMemAreaCache) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"%s: failed to allocate mem area kmem_cache", __FUNCTION__)); -+ goto failed; -+ } -+ -+#if (PVR_LINUX_MEM_AREA_POOL_MAX_PAGES != 0) -+ g_iPagePoolMaxEntries = PVR_LINUX_MEM_AREA_POOL_MAX_PAGES; -+ if (g_iPagePoolMaxEntries <= 0 || g_iPagePoolMaxEntries > INT_MAX/2) -+ { -+ g_iPagePoolMaxEntries = INT_MAX/2; -+ PVR_TRACE(("%s: No limit set for page pool size", __FUNCTION__)); -+ } -+ else -+ { -+ PVR_TRACE(("%s: Maximum page pool size: %d", __FUNCTION__, g_iPagePoolMaxEntries)); -+ } -+ -+ g_PsLinuxPagePoolCache = KMemCacheCreateWrapper("img-mm-pool", sizeof(LinuxPagePoolEntry), 0, 0); -+ if (!g_PsLinuxPagePoolCache) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"%s: failed to allocate page pool kmem_cache", __FUNCTION__)); -+ goto failed; -+ } -+#endif -+ -+#if defined(PVR_LINUX_MEM_AREA_POOL_ALLOW_SHRINK) -+ register_shrinker(&g_sShrinker); -+ g_bShrinkerRegistered = IMG_TRUE; -+#endif -+ -+ return PVRSRV_OK; -+ -+failed: -+ LinuxMMCleanup(); -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+} -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/mm.h b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/mm.h -new file mode 100644 -index 0000000..d4d1866 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/mm.h -@@ -0,0 +1,733 @@ -+/*************************************************************************/ /*! -+@Title Linux Memory Management. -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Declares various memory management utility functions -+ for Linux. -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+#ifndef __IMG_LINUX_MM_H__ -+#define __IMG_LINUX_MM_H__ -+ -+#include <linux/version.h> -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)) -+#ifndef AUTOCONF_INCLUDED -+#include <linux/config.h> -+#endif -+#endif -+ -+#include <linux/slab.h> -+#include <linux/mm.h> -+#include <linux/list.h> -+ -+#include <asm/io.h> -+ -+#define PHYS_TO_PFN(phys) ((phys) >> PAGE_SHIFT) -+#define PFN_TO_PHYS(pfn) ((pfn) << PAGE_SHIFT) -+ -+#define RANGE_TO_PAGES(range) (((range) + (PAGE_SIZE - 1)) >> PAGE_SHIFT) -+ -+#define ADDR_TO_PAGE_OFFSET(addr) (((unsigned long)(addr)) & (PAGE_SIZE - 1)) -+ -+#define PAGES_TO_BYTES(pages) ((pages) << PAGE_SHIFT) -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)) -+#define REMAP_PFN_RANGE(vma, addr, pfn, size, prot) remap_pfn_range(vma, addr, pfn, size, prot) -+#else -+#define REMAP_PFN_RANGE(vma, addr, pfn, size, prot) remap_page_range(vma, addr, PFN_TO_PHYS(pfn), size, prot) -+#endif -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12)) -+#define IO_REMAP_PFN_RANGE(vma, addr, pfn, size, prot) io_remap_pfn_range(vma, addr, pfn, size, prot) -+#else -+#define IO_REMAP_PFN_RANGE(vma, addr, pfn, size, prot) io_remap_page_range(vma, addr, PFN_TO_PHYS(pfn), size, prot) -+#endif -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)) -+#define VM_INSERT_PAGE(vma, addr, page) vm_insert_page(vma, addr, page) -+#else -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)) -+#define VM_INSERT_PAGE(vma, addr, page) remap_pfn_range(vma, addr, page_to_pfn(page), PAGE_SIZE, vma->vm_page_prot); -+#else -+#define VM_INSERT_PAGE(vma, addr, page) remap_page_range(vma, addr, page_to_phys(page), PAGE_SIZE, vma->vm_page_prot); -+#endif -+#endif -+ -+static inline IMG_UINTPTR_T VMallocToPhys(IMG_VOID *pCpuVAddr) -+{ -+ return (page_to_phys(vmalloc_to_page(pCpuVAddr)) + ADDR_TO_PAGE_OFFSET(pCpuVAddr)); -+ -+} -+ -+typedef enum { -+ LINUX_MEM_AREA_IOREMAP, -+ LINUX_MEM_AREA_EXTERNAL_KV, -+ LINUX_MEM_AREA_IO, -+ LINUX_MEM_AREA_VMALLOC, -+ LINUX_MEM_AREA_ALLOC_PAGES, -+ LINUX_MEM_AREA_SUB_ALLOC, -+ LINUX_MEM_AREA_ION, -+#if defined(PVR_LINUX_MEM_AREA_USE_VMAP) -+ LINUX_MEM_AREA_VMAP, -+#endif -+ LINUX_MEM_AREA_TYPE_COUNT -+}LINUX_MEM_AREA_TYPE; -+ -+typedef struct _LinuxMemArea LinuxMemArea; -+ -+ -+/* FIXME - describe this structure. */ -+struct _LinuxMemArea { -+ LINUX_MEM_AREA_TYPE eAreaType; -+ union _uData -+ { -+ struct _sIORemap -+ { -+ /* Note: The memory this represents is _not_ implicitly -+ * page aligned, neither is its size */ -+ IMG_CPU_PHYADDR CPUPhysAddr; -+ IMG_VOID *pvIORemapCookie; -+ }sIORemap; -+ struct _sExternalKV -+ { -+ /* Note: The memory this represents is _not_ implicitly -+ * page aligned, neither is its size */ -+ IMG_BOOL bPhysContig; -+ union { -+ /* -+ * SYSPhysAddr is valid if bPhysContig is true, else -+ * pSysPhysAddr is valid -+ */ -+ IMG_SYS_PHYADDR SysPhysAddr; -+ IMG_SYS_PHYADDR *pSysPhysAddr; -+ } uPhysAddr; -+ IMG_VOID *pvExternalKV; -+ }sExternalKV; -+ struct _sIO -+ { -+ /* Note: The memory this represents is _not_ implicitly -+ * page aligned, neither is its size */ -+ IMG_CPU_PHYADDR CPUPhysAddr; -+ }sIO; -+ struct _sVmalloc -+ { -+ /* Note the memory this represents _is_ implicitly -+ * page aligned _and_ so is its size */ -+ IMG_VOID *pvVmallocAddress; -+#if defined(PVR_LINUX_MEM_AREA_USE_VMAP) -+ struct page **ppsPageList; -+ IMG_HANDLE hBlockPageList; -+#endif -+ }sVmalloc; -+ struct _sPageList -+ { -+ /* Note the memory this represents _is_ implicitly -+ * page aligned _and_ so is its size */ -+ struct page **ppsPageList; -+ IMG_HANDLE hBlockPageList; -+ }sPageList; -+ struct _sIONTilerAlloc -+ { -+ /* Note the memory this represents _is_ implicitly -+ * page aligned _and_ so is its size */ -+ IMG_CPU_PHYADDR *pCPUPhysAddrs; -+ struct ion_handle *psIONHandle[2]; -+ }sIONTilerAlloc; -+ struct _sSubAlloc -+ { -+ /* Note: The memory this represents is _not_ implicitly -+ * page aligned, neither is its size */ -+ LinuxMemArea *psParentLinuxMemArea; -+ IMG_UINTPTR_T uiByteOffset; -+ }sSubAlloc; -+ }uData; -+ -+ IMG_SIZE_T uiByteSize; /* Size of memory area */ -+ -+ IMG_UINT32 ui32AreaFlags; /* Flags passed at creation time */ -+ -+ IMG_BOOL bMMapRegistered; /* Registered with mmap code */ -+ -+ IMG_BOOL bNeedsCacheInvalidate; /* Cache should be invalidated on first map? */ -+ -+ IMG_HANDLE hBMHandle; /* Handle back to BM for this allocation */ -+ -+ /* List entry for global list of areas registered for mmap */ -+ struct list_head sMMapItem; -+ -+ /* -+ * Head of list of all mmap offset structures associated with this -+ * memory area. -+ */ -+ struct list_head sMMapOffsetStructList; -+}; -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)) -+typedef kmem_cache_t LinuxKMemCache; -+#else -+typedef struct kmem_cache LinuxKMemCache; -+#endif -+ -+ -+/*! -+ ******************************************************************************* -+ * @Function LinuxMMInit -+ * -+ * @Description -+ * -+ * Initialise linux memory management code. -+ * This should be called during services initialisation. -+ * -+ * @Return none -+******************************************************************************/ -+PVRSRV_ERROR LinuxMMInit(IMG_VOID); -+ -+ -+/*! -+ ******************************************************************************* -+ * -+ * @Function LinuxMMCleanup -+ * -+ * @Description -+ * -+ * Cleanup state for the linux memory management code. -+ * This should be called at services cleanup. -+ * -+ * @Return none -+******************************************************************************/ -+IMG_VOID LinuxMMCleanup(IMG_VOID); -+ -+ -+/*! -+ ******************************************************************************* -+ * @brief Wrappers for kmalloc/kfree with optional /proc/pvr/km tracking -+ * They can also be used as more concise replacements for OSAllocMem -+ * in Linux specific code. -+ * -+ * @param uByteSize -+ * -+ * @return -+ ******************************************************************************/ -+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -+#define KMallocWrapper(uByteSize, uFlags) _KMallocWrapper(uByteSize, uFlags, __FILE__, __LINE__) -+#else -+#define KMallocWrapper(uByteSize, uFlags) _KMallocWrapper(uByteSize, uFlags, NULL, 0) -+#endif -+IMG_VOID *_KMallocWrapper(IMG_SIZE_T uByteSize, gfp_t uFlags, IMG_CHAR *szFileName, IMG_UINT32 ui32Line); -+ -+ -+/*! -+ ******************************************************************************* -+ * @brief -+ * -+ * @param pvCpuVAddr -+ * -+ * @return -+ ******************************************************************************/ -+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -+#define KFreeWrapper(pvCpuVAddr) _KFreeWrapper(pvCpuVAddr, __FILE__, __LINE__) -+#else -+#define KFreeWrapper(pvCpuVAddr) _KFreeWrapper(pvCpuVAddr, NULL, 0) -+#endif -+IMG_VOID _KFreeWrapper(IMG_VOID *pvCpuVAddr, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line); -+ -+ -+/*! -+ ******************************************************************************* -+ * @brief -+ * -+ * @param uBytes -+ * @param ui32AllocFlags -+ * -+ * @return -+ ******************************************************************************/ -+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -+#define VMallocWrapper(uiBytes, ui32AllocFlags) _VMallocWrapper(uiBytes, ui32AllocFlags, __FILE__, __LINE__) -+#else -+#define VMallocWrapper(uiBytes, ui32AllocFlags) _VMallocWrapper(uiBytes, ui32AllocFlags, NULL, 0) -+#endif -+IMG_VOID *_VMallocWrapper(IMG_SIZE_T uiBytes, IMG_UINT32 ui32AllocFlags, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line); -+ -+ -+/*! -+ ******************************************************************************* -+ * @brief -+ * -+ * @param pvCpuVAddr -+ * -+ * @return -+ ******************************************************************************/ -+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -+#define VFreeWrapper(pvCpuVAddr) _VFreeWrapper(pvCpuVAddr, __FILE__, __LINE__) -+#else -+#define VFreeWrapper(pvCpuVAddr) _VFreeWrapper(pvCpuVAddr, NULL, 0) -+#endif -+IMG_VOID _VFreeWrapper(IMG_VOID *pvCpuVAddr, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line); -+ -+ -+/*! -+ ******************************************************************************* -+ * @brief Allocates virtually contiguous pages -+ * -+ * @param uBytes number of bytes to reserve -+ * @param ui32AreaFlags Heap caching and mapping Flags -+ * -+ * @return Page-aligned address of virtual allocation or NULL on error -+ ******************************************************************************/ -+LinuxMemArea *NewVMallocLinuxMemArea(IMG_SIZE_T uBytes, IMG_UINT32 ui32AreaFlags); -+ -+ -+/*! -+ ******************************************************************************* -+ * @brief Deallocates virtually contiguous pages -+ * -+ * @param LinuxMemArea from NewVMallocLinuxMemArea -+ * -+ ******************************************************************************/ -+IMG_VOID FreeVMallocLinuxMemArea(LinuxMemArea *psLinuxMemArea); -+ -+ -+/*! -+ ******************************************************************************* -+ * @brief Reserve physical IO memory and create a CPU virtual mapping for it -+ * -+ * @param BasePAddr -+ * @param uiBytes -+ * @param ui32MappingFlags -+ * -+ * @return -+ ******************************************************************************/ -+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -+#define IORemapWrapper(BasePAddr, uiBytes, ui32MappingFlags) \ -+ _IORemapWrapper(BasePAddr, uiBytes, ui32MappingFlags, __FILE__, __LINE__) -+#else -+#define IORemapWrapper(BasePAddr, uiBytes, ui32MappingFlags) \ -+ _IORemapWrapper(BasePAddr, uiBytes, ui32MappingFlags, NULL, 0) -+#endif -+IMG_VOID *_IORemapWrapper(IMG_CPU_PHYADDR BasePAddr, -+ IMG_SIZE_T uiBytes, -+ IMG_UINT32 ui32MappingFlags, -+ IMG_CHAR *pszFileName, -+ IMG_UINT32 ui32Line); -+ -+ -+/*! -+ ******************************************************************************* -+ * @brief Reserve physical IO memory and create a CPU virtual mapping for it -+ * -+ * @param BasePAddr -+ * @param uiBytes -+ * @param ui32AreaFlags Heap caching and mapping Flags -+ * -+ * @return -+ ******************************************************************************/ -+LinuxMemArea *NewIORemapLinuxMemArea(IMG_CPU_PHYADDR BasePAddr, IMG_SIZE_T uiBytes, IMG_UINT32 ui32AreaFlags); -+ -+ -+/*! -+ ******************************************************************************* -+ * @brief -+ * -+ * @param psLinuxMemArea -+ * -+ * @return -+ ********************************************************************************/ -+IMG_VOID FreeIORemapLinuxMemArea(LinuxMemArea *psLinuxMemArea); -+ -+/*! -+ ******************************************************************************* -+ * @brief Register physical memory which already has a CPU virtual mapping -+ * -+ * @param pBasePAddr -+ * @param pvCPUVAddr -+ * @param bPhysContig -+ * @param uBytes -+ * @param ui32AreaFlags Heap caching and mapping Flags -+ * -+ * @return -+ ******************************************************************************/ -+LinuxMemArea *NewExternalKVLinuxMemArea(IMG_SYS_PHYADDR *pBasePAddr, IMG_VOID *pvCPUVAddr, IMG_SIZE_T uBytes, IMG_BOOL bPhysContig, IMG_UINT32 ui32AreaFlags); -+ -+ -+/*! -+ ******************************************************************************* -+ * @brief -+ * -+ * @param psLinuxMemArea -+ * -+ * @return -+ ******************************************************************************/ -+IMG_VOID FreeExternalKVLinuxMemArea(LinuxMemArea *psLinuxMemArea); -+ -+ -+/*! -+ ****************************************************************************** -+ * @brief Unmaps an IO memory mapping created using IORemap -+ * -+ * @param pvIORemapCookie -+ * -+ * @return -+ ******************************************************************************/ -+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -+#define IOUnmapWrapper(pvIORemapCookie) \ -+ _IOUnmapWrapper(pvIORemapCookie, __FILE__, __LINE__) -+#else -+#define IOUnmapWrapper(pvIORemapCookie) \ -+ _IOUnmapWrapper(pvIORemapCookie, NULL, 0) -+#endif -+IMG_VOID _IOUnmapWrapper(IMG_VOID *pvIORemapCookie, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line); -+ -+ -+/*! -+ ******************************************************************************* -+ * @brief -+ * -+ * @param psLinuxMemArea -+ * @param uByteOffset -+ * -+ * @return -+ ******************************************************************************/ -+struct page *LinuxMemAreaOffsetToPage(LinuxMemArea *psLinuxMemArea, IMG_UINTPTR_T uByteOffset); -+ -+ -+/*! -+ ******************************************************************************* -+ * @brief -+ * -+ * @param pszName -+ * @param Size -+ * @param Align -+ * @param ui32Flags -+ * -+ * @return -+ ******************************************************************************/ -+LinuxKMemCache *KMemCacheCreateWrapper(IMG_CHAR *pszName, size_t Size, size_t Align, IMG_UINT32 ui32Flags); -+ -+ -+/*! -+ ******************************************************************************* -+ * @brief -+ * -+ * @param psCache -+ * -+ * @return -+ ******************************************************************************/ -+IMG_VOID KMemCacheDestroyWrapper(LinuxKMemCache *psCache); -+ -+ -+/*! -+ ******************************************************************************* -+ * @brief -+ * -+ * @param psCache -+ * @param Flags -+ * -+ * @return -+ ******************************************************************************/ -+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -+#define KMemCacheAllocWrapper(psCache, Flags) _KMemCacheAllocWrapper(psCache, Flags, __FILE__, __LINE__) -+#else -+#define KMemCacheAllocWrapper(psCache, Flags) _KMemCacheAllocWrapper(psCache, Flags, NULL, 0) -+#endif -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)) -+IMG_VOID *_KMemCacheAllocWrapper(LinuxKMemCache *psCache, gfp_t Flags, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line); -+#else -+IMG_VOID *_KMemCacheAllocWrapper(LinuxKMemCache *psCache, int Flags, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line); -+#endif -+ -+/*! -+ ******************************************************************************* -+ * @brief -+ * -+ * @param psCache -+ * @param pvObject -+ * -+ * @return -+ ******************************************************************************/ -+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -+#define KMemCacheFreeWrapper(psCache, pvObject) _KMemCacheFreeWrapper(psCache, pvObject, __FILE__, __LINE__) -+#else -+#define KMemCacheFreeWrapper(psCache, pvObject) _KMemCacheFreeWrapper(psCache, pvObject, NULL, 0) -+#endif -+IMG_VOID _KMemCacheFreeWrapper(LinuxKMemCache *psCache, IMG_VOID *pvObject, IMG_CHAR *pszFileName, IMG_UINT32 ui32Line); -+ -+ -+/*! -+ ******************************************************************************* -+ * @brief -+ * -+ * @param psCache -+ * -+ * @return -+ ******************************************************************************/ -+const IMG_CHAR *KMemCacheNameWrapper(LinuxKMemCache *psCache); -+ -+ -+/*! -+ ******************************************************************************* -+ * @brief -+ * -+ * @param BasePAddr -+ * @param uiBytes -+ * @param ui32AreaFlags Heap caching and mapping Flags -+ * -+ * @return -+ ******************************************************************************/ -+LinuxMemArea *NewIOLinuxMemArea(IMG_CPU_PHYADDR BasePAddr, IMG_SIZE_T uiBytes, IMG_UINT32 ui32AreaFlags); -+ -+ -+/*! -+ ******************************************************************************* -+ * @brief -+ * -+ * @param psLinuxMemArea -+ * -+ * @return -+ ******************************************************************************/ -+IMG_VOID FreeIOLinuxMemArea(LinuxMemArea *psLinuxMemArea); -+ -+ -+/*! -+ ******************************************************************************* -+ * @brief -+ * -+ * @param uiBytes -+ * @param ui32AreaFlags E.g Heap caching and mapping Flags -+ * -+ * @return -+ ******************************************************************************/ -+LinuxMemArea *NewAllocPagesLinuxMemArea(IMG_SIZE_T uiBytes, IMG_UINT32 ui32AreaFlags); -+ -+ -+/*! -+ ******************************************************************************* -+ * @brief -+ * -+ * @param psLinuxMemArea -+ * -+ * @return -+ ******************************************************************************/ -+IMG_VOID FreeAllocPagesLinuxMemArea(LinuxMemArea *psLinuxMemArea); -+ -+ -+#if defined(CONFIG_ION_OMAP) -+ -+/*! -+ ******************************************************************************* -+ * @brief -+ * -+ * @param uiBytes -+ * @param ui32AreaFlags E.g Heap caching and mapping Flags -+ * -+ * @return -+ ******************************************************************************/ -+LinuxMemArea * -+NewIONLinuxMemArea(IMG_SIZE_T uiBytes, IMG_UINT32 ui32AreaFlags, -+ IMG_PVOID pvPrivData, IMG_SIZE_T uiPrivDataLength); -+ -+ -+/*! -+ ******************************************************************************* -+ * @brief -+ * -+ * @param psLinuxMemArea -+ * -+ * @return -+ ******************************************************************************/ -+IMG_VOID FreeIONLinuxMemArea(LinuxMemArea *psLinuxMemArea); -+ -+#else /* defined(CONFIG_ION_OMAP) */ -+ -+static inline LinuxMemArea * -+NewIONLinuxMemArea(IMG_SIZE_T uBytes, IMG_UINT32 ui32AreaFlags, -+ IMG_PVOID pvPrivData, IMG_SIZE_T uPrivDataLength) -+{ -+ PVR_UNREFERENCED_PARAMETER(uBytes); -+ PVR_UNREFERENCED_PARAMETER(ui32AreaFlags); -+ PVR_UNREFERENCED_PARAMETER(pvPrivData); -+ PVR_UNREFERENCED_PARAMETER(uPrivDataLength); -+ BUG(); -+ return IMG_NULL; -+} -+ -+static inline IMG_VOID FreeIONLinuxMemArea(LinuxMemArea *psLinuxMemArea) -+{ -+ PVR_UNREFERENCED_PARAMETER(psLinuxMemArea); -+ BUG(); -+} -+ -+#endif /* defined(CONFIG_ION_OMAP) */ -+ -+ -+/*! -+ ******************************************************************************* -+ * @brief -+ * -+ * @param psParentLinuxMemArea -+ * @param uByteOffset -+ * @param uBytes -+ * -+ * @return -+ ******************************************************************************/ -+LinuxMemArea *NewSubLinuxMemArea(LinuxMemArea *psParentLinuxMemArea, -+ IMG_UINTPTR_T uByteOffset, -+ IMG_SIZE_T uBytes); -+ -+ -+/*! -+ ******************************************************************************* -+ * @brief -+ * -+ * @param psLinuxMemArea -+ * -+ * @return -+ ******************************************************************************/ -+IMG_VOID LinuxMemAreaDeepFree(LinuxMemArea *psLinuxMemArea); -+ -+ -+/*! -+ ******************************************************************************* -+ * @brief For debug builds, LinuxMemAreas are tracked in /proc -+ * -+ * @param psLinuxMemArea -+ * -+ ******************************************************************************/ -+#if defined(LINUX_MEM_AREAS_DEBUG) -+IMG_VOID LinuxMemAreaRegister(LinuxMemArea *psLinuxMemArea); -+#else -+#define LinuxMemAreaRegister(X) -+#endif -+ -+ -+/*! -+ ******************************************************************************* -+ * @brief -+ * -+ * @param psLinuxMemArea -+ * -+ * @return -+ ******************************************************************************/ -+IMG_VOID *LinuxMemAreaToCpuVAddr(LinuxMemArea *psLinuxMemArea); -+ -+ -+/*! -+ ******************************************************************************* -+ * @brief -+ * -+ * @param psLinuxMemArea -+ * @param uByteOffset -+ * -+ * @return -+ ******************************************************************************/ -+IMG_CPU_PHYADDR LinuxMemAreaToCpuPAddr(LinuxMemArea *psLinuxMemArea, IMG_UINTPTR_T uByteOffset); -+ -+ -+#define LinuxMemAreaToCpuPFN(psLinuxMemArea, uByteOffset) PHYS_TO_PFN(LinuxMemAreaToCpuPAddr(psLinuxMemArea, uByteOffset).uiAddr) -+ -+/*! -+ ******************************************************************************* -+ * @brief Indicate whether a LinuxMemArea is physically contiguous -+ * -+ * @param psLinuxMemArea -+ * -+ * @return IMG_TRUE if the physical address range is contiguous, else IMG_FALSE -+ ******************************************************************************/ -+IMG_BOOL LinuxMemAreaPhysIsContig(LinuxMemArea *psLinuxMemArea); -+ -+/*! -+ ******************************************************************************* -+ * @brief Return the real underlying LinuxMemArea -+ * -+ * @param psLinuxMemArea -+ * -+ * @return The real underlying LinuxMemArea -+ ******************************************************************************/ -+static inline LinuxMemArea * -+LinuxMemAreaRoot(LinuxMemArea *psLinuxMemArea) -+{ -+ if(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_SUB_ALLOC) -+ { -+ return psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea; -+ } -+ else -+ { -+ return psLinuxMemArea; -+ } -+} -+ -+ -+/*! -+ ******************************************************************************* -+ * @brief Return type of real underlying LinuxMemArea -+ * -+ * @param psLinuxMemArea -+ * -+ * @return The areas eAreaType or for SUB areas; return the parents eAreaType. -+ ******************************************************************************/ -+static inline LINUX_MEM_AREA_TYPE -+LinuxMemAreaRootType(LinuxMemArea *psLinuxMemArea) -+{ -+ return LinuxMemAreaRoot(psLinuxMemArea)->eAreaType; -+} -+ -+ -+/*! -+ ******************************************************************************* -+ * @brief Converts the enum type of a LinuxMemArea to a const string -+ * -+ * @param eMemAreaType -+ * -+ * @return const string representation of type -+ ******************************************************************************/ -+const IMG_CHAR *LinuxMemAreaTypeToString(LINUX_MEM_AREA_TYPE eMemAreaType); -+ -+ -+/*! -+ ******************************************************************************* -+ * @brief -+ * -+ * @param ui32Flags -+ * -+ * @return -+ ******************************************************************************/ -+#if defined(DEBUG) || defined(DEBUG_LINUX_MEM_AREAS) -+const IMG_CHAR *HAPFlagsToString(IMG_UINT32 ui32Flags); -+#endif -+ -+#endif /* __IMG_LINUX_MM_H__ */ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/mmap.c b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/mmap.c -new file mode 100644 -index 0000000..932bf16 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/mmap.c -@@ -0,0 +1,1653 @@ -+/*************************************************************************/ /*! -+@Title Linux mmap interface -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#include <linux/version.h> -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)) -+#ifndef AUTOCONF_INCLUDED -+#include <linux/config.h> -+#endif -+#endif -+ -+#include <linux/mm.h> -+#include <linux/module.h> -+#include <linux/vmalloc.h> -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) -+#include <linux/wrapper.h> -+#endif -+#include <linux/slab.h> -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)) -+#include <linux/highmem.h> -+#endif -+#include <asm/io.h> -+#include <asm/page.h> -+#include <asm/shmparam.h> -+#include <asm/pgtable.h> -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)) -+#include <linux/sched.h> -+#include <asm/current.h> -+#endif -+#if defined(SUPPORT_DRI_DRM) -+#include <drm/drmP.h> -+#endif -+ -+#ifdef CONFIG_ARCH_OMAP5 -+#ifdef CONFIG_DSSCOMP -+#include <../drivers/staging/omapdrm/omap_dmm_tiler.h> -+#endif -+#endif -+ -+#include "services_headers.h" -+ -+#include "pvrmmap.h" -+#include "mutils.h" -+#include "mmap.h" -+#include "mm.h" -+#include "proc.h" -+#include "mutex.h" -+#include "handle.h" -+#include "perproc.h" -+#include "env_perproc.h" -+#include "bridged_support.h" -+#if defined(SUPPORT_DRI_DRM) -+#include "pvr_drm.h" -+#endif -+ -+#if !defined(PVR_SECURE_HANDLES) -+#error "The mmap code requires PVR_SECURE_HANDLES" -+#endif -+ -+/* WARNING: -+ * The mmap code has its own mutex, to prevent a possible deadlock, -+ * when using gPVRSRVLock. -+ * The Linux kernel takes the mm->mmap_sem before calling the mmap -+ * entry points (PVRMMap, MMapVOpen, MMapVClose), but the ioctl -+ * entry point may take mm->mmap_sem during fault handling, or -+ * before calling get_user_pages. If gPVRSRVLock was used in the -+ * mmap entry points, a deadlock could result, due to the ioctl -+ * and mmap code taking the two locks in different orders. -+ * As a corollary to this, the mmap entry points must not call -+ * any driver code that relies on gPVRSRVLock is held. -+ */ -+PVRSRV_LINUX_MUTEX g_sMMapMutex; -+ -+static LinuxKMemCache *g_psMemmapCache = NULL; -+static LIST_HEAD(g_sMMapAreaList); -+static LIST_HEAD(g_sMMapOffsetStructList); -+#if defined(DEBUG_LINUX_MMAP_AREAS) -+static IMG_UINT32 g_ui32RegisteredAreas = 0; -+static IMG_SIZE_T g_uiTotalByteSize = 0; -+#endif -+ -+ -+#if defined(DEBUG_LINUX_MMAP_AREAS) -+static struct proc_dir_entry *g_ProcMMap; -+#endif /* defined(DEBUG_LINUX_MMAP_AREAS) */ -+ -+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL) -+/* -+ * Now that we are using mmap2 in srvclient, almost (*) the full 32 -+ * bit offset is available. The range of values is divided into two. -+ * The first part of the range, from FIRST_PHYSICAL_PFN to -+ * LAST_PHYSICAL_PFN, is for raw page mappings (VM_PFNMAP). The -+ * resulting 43 bit (*) physical address range should be enough for -+ * the current range of processors we support. -+ * -+ * NB: (*) -- the above figures assume 4KB page size. The offset -+ * argument to mmap2() is in units of 4,096 bytes regardless of page -+ * size. Thus, we lose (PAGE_SHIFT-12) bits of resolution on other -+ * architectures. -+ * -+ * The second part of the range, from FIRST_SPECIAL_PFN to LAST_SPECIAL_PFN, -+ * is used for all other mappings. These other mappings will always -+ * consist of pages with associated page structures, and need not -+ * represent a contiguous range of physical addresses. -+ * -+ */ -+#define MMAP2_PGOFF_RESOLUTION (32-PAGE_SHIFT+12) -+#define RESERVED_PGOFF_BITS 1 -+#define MAX_MMAP_HANDLE ((1UL<<(MMAP2_PGOFF_RESOLUTION-RESERVED_PGOFF_BITS))-1) -+ -+#define FIRST_PHYSICAL_PFN 0 -+#define LAST_PHYSICAL_PFN (FIRST_PHYSICAL_PFN + MAX_MMAP_HANDLE) -+#define FIRST_SPECIAL_PFN (LAST_PHYSICAL_PFN + 1) -+#define LAST_SPECIAL_PFN (FIRST_SPECIAL_PFN + MAX_MMAP_HANDLE) -+ -+#else /* !defined(PVR_MAKE_ALL_PFNS_SPECIAL) */ -+ -+#if PAGE_SHIFT != 12 -+#error This build variant has not yet been made non-4KB page-size aware -+#endif -+ -+/* -+ * Since we no longer have to worry about clashes with the mmap -+ * offsets used for pure PFN mappings (VM_PFNMAP), there is greater -+ * freedom in choosing the mmap handles. This is useful if the -+ * mmap offset space has to be shared with another driver component. -+ */ -+ -+#if defined(PVR_MMAP_OFFSET_BASE) -+#define FIRST_SPECIAL_PFN PVR_MMAP_OFFSET_BASE -+#else -+#define FIRST_SPECIAL_PFN 0x80000000UL -+#endif -+ -+#if defined(PVR_NUM_MMAP_HANDLES) -+#define MAX_MMAP_HANDLE PVR_NUM_MMAP_HANDLES -+#else -+#define MAX_MMAP_HANDLE 0x7fffffffUL -+#endif -+ -+#endif /* !defined(PVR_MAKE_ALL_PFNS_SPECIAL) */ -+ -+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL) -+static inline IMG_BOOL -+PFNIsPhysical(IMG_UINT32 pfn) -+{ -+ /* Unsigned, no need to compare >=0 */ -+ return (/*(pfn >= FIRST_PHYSICAL_PFN) &&*/ (pfn <= LAST_PHYSICAL_PFN)) ? IMG_TRUE : IMG_FALSE; -+} -+ -+static inline IMG_BOOL -+PFNIsSpecial(IMG_UINT32 pfn) -+{ -+ /* Unsigned, no need to compare <=MAX_UINT */ -+ return ((pfn >= FIRST_SPECIAL_PFN) /*&& (pfn <= LAST_SPECIAL_PFN)*/) ? IMG_TRUE : IMG_FALSE; -+} -+#endif -+ -+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL) -+static inline IMG_HANDLE -+MMapOffsetToHandle(IMG_UINT32 pfn) -+{ -+ if (PFNIsPhysical(pfn)) -+ { -+ PVR_ASSERT(PFNIsPhysical(pfn)); -+ return IMG_NULL; -+ } -+ return (IMG_HANDLE)(pfn - FIRST_SPECIAL_PFN); -+} -+#endif -+ -+static inline IMG_UINTPTR_T -+HandleToMMapOffset(IMG_HANDLE hHandle) -+{ -+ IMG_UINTPTR_T ulHandle = (IMG_UINTPTR_T)hHandle; -+ -+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL) -+ if (PFNIsSpecial(ulHandle)) -+ { -+ PVR_ASSERT(PFNIsSpecial(ulHandle)); -+ return 0; -+ } -+#endif -+ return ulHandle + FIRST_SPECIAL_PFN; -+} -+ -+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL) -+/* -+ * Determine whether physical or special mappings will be used for -+ * a given memory area. At present, this decision is made on -+ * whether the mapping represents a contiguous range of physical -+ * addresses, which is a requirement for raw page mappings (VM_PFNMAP). -+ * In the VMA structure for such a mapping, vm_pgoff is the PFN -+ * (page frame number, the physical address divided by the page size) -+ * of the first page in the VMA. The second page is assumed to have -+ * PFN (vm_pgoff + 1), the third (vm_pgoff + 2) and so on. -+ */ -+static inline IMG_BOOL -+LinuxMemAreaUsesPhysicalMap(LinuxMemArea *psLinuxMemArea) -+{ -+ return LinuxMemAreaPhysIsContig(psLinuxMemArea); -+} -+#endif -+ -+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL) -+static inline IMG_UINT32 -+GetCurrentThreadID(IMG_VOID) -+{ -+ /* -+ * The PID is the thread ID, as each thread is a -+ * seperate process. -+ */ -+ return (IMG_UINT32)current->pid; -+} -+#endif -+ -+/* -+ * Create an offset structure, which is used to hold per-process -+ * mmap data. -+ */ -+static PKV_OFFSET_STRUCT -+CreateOffsetStruct(LinuxMemArea *psLinuxMemArea, IMG_UINTPTR_T uiOffset, IMG_SIZE_T uiRealByteSize) -+{ -+ PKV_OFFSET_STRUCT psOffsetStruct; -+#if defined(DEBUG) || defined(DEBUG_LINUX_MMAP_AREAS) -+ const IMG_CHAR *pszName = LinuxMemAreaTypeToString(LinuxMemAreaRootType(psLinuxMemArea)); -+#endif -+ -+#if defined(DEBUG) || defined(DEBUG_LINUX_MMAP_AREAS) -+ PVR_DPF((PVR_DBG_MESSAGE, -+ "%s(%s, psLinuxMemArea: 0x%p, ui32AllocFlags: 0x%8x)", -+ __FUNCTION__, pszName, psLinuxMemArea, psLinuxMemArea->ui32AreaFlags)); -+#endif -+ -+ PVR_ASSERT(psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC || LinuxMemAreaRoot(psLinuxMemArea)->eAreaType != LINUX_MEM_AREA_SUB_ALLOC); -+ -+ PVR_ASSERT(psLinuxMemArea->bMMapRegistered); -+ -+ psOffsetStruct = KMemCacheAllocWrapper(g_psMemmapCache, GFP_KERNEL); -+ if(psOffsetStruct == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"PVRMMapRegisterArea: Couldn't alloc another mapping record from cache")); -+ return IMG_NULL; -+ } -+ -+ psOffsetStruct->uiMMapOffset = uiOffset; -+ -+ psOffsetStruct->psLinuxMemArea = psLinuxMemArea; -+ -+ psOffsetStruct->uiRealByteSize = uiRealByteSize; -+ -+ /* -+ * We store the TID in case two threads within a process -+ * generate the same offset structure, and both end up on the -+ * list of structures waiting to be mapped, at the same time. -+ * This could happen if two sub areas within the same page are -+ * being mapped at the same time. -+ * The TID allows the mmap entry point to distinguish which -+ * mapping is being done by which thread. -+ */ -+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL) -+ psOffsetStruct->ui32TID = GetCurrentThreadID(); -+#endif -+ psOffsetStruct->ui32PID = OSGetCurrentProcessIDKM(); -+ -+#if defined(DEBUG_LINUX_MMAP_AREAS) -+ /* Extra entries to support proc filesystem debug info */ -+ psOffsetStruct->pszName = pszName; -+#endif -+ -+ list_add_tail(&psOffsetStruct->sAreaItem, &psLinuxMemArea->sMMapOffsetStructList); -+ -+ return psOffsetStruct; -+} -+ -+ -+static IMG_VOID -+DestroyOffsetStruct(PKV_OFFSET_STRUCT psOffsetStruct) -+{ -+#ifdef DEBUG -+ IMG_CPU_PHYADDR CpuPAddr; -+ CpuPAddr = LinuxMemAreaToCpuPAddr(psOffsetStruct->psLinuxMemArea, 0); -+#endif -+ -+ list_del(&psOffsetStruct->sAreaItem); -+ -+ if (psOffsetStruct->bOnMMapList) -+ { -+ list_del(&psOffsetStruct->sMMapItem); -+ } -+ -+#ifdef DEBUG -+ PVR_DPF((PVR_DBG_MESSAGE, "%s: Table entry: " -+ "psLinuxMemArea=%p, CpuPAddr=0x" CPUPADDR_FMT, -+ __FUNCTION__, -+ psOffsetStruct->psLinuxMemArea, -+ CpuPAddr.uiAddr)); -+#endif -+ -+ KMemCacheFreeWrapper(g_psMemmapCache, psOffsetStruct); -+} -+ -+ -+/* -+ * There are no alignment constraints for mapping requests made by user -+ * mode Services. For this, and potentially other reasons, the -+ * mapping created for a users request may look different to the -+ * original request in terms of size and alignment. -+ * -+ * This function determines an offset that the user can add to the mapping -+ * that is _actually_ created which will point to the memory they are -+ * _really_ interested in. -+ * -+ */ -+static inline IMG_VOID -+DetermineUsersSizeAndByteOffset(LinuxMemArea *psLinuxMemArea, -+ IMG_SIZE_T *puiRealByteSize, -+ IMG_UINTPTR_T *puiByteOffset) -+{ -+ IMG_UINTPTR_T uiPageAlignmentOffset; -+ IMG_CPU_PHYADDR CpuPAddr; -+ -+ CpuPAddr = LinuxMemAreaToCpuPAddr(psLinuxMemArea, 0); -+ uiPageAlignmentOffset = ADDR_TO_PAGE_OFFSET(CpuPAddr.uiAddr); -+ -+ *puiByteOffset = uiPageAlignmentOffset; -+ -+ *puiRealByteSize = PAGE_ALIGN(psLinuxMemArea->uiByteSize + uiPageAlignmentOffset); -+} -+ -+ -+/*! -+ ******************************************************************************* -+ -+ @Function PVRMMapOSMemHandleToMMapData -+ -+ @Description -+ -+ Determine various parameters needed to mmap a memory area, and to -+ locate the memory within the mapped area. -+ -+ @input psPerProc : Per-process data. -+ @input hMHandle : Memory handle. -+ @input puiMMapOffset : pointer to location for returned mmap offset. -+ @input puiByteOffset : pointer to location for returned byte offset. -+ @input puiRealByteSize : pointer to location for returned real byte size. -+ @input puiUserVaddr : pointer to location for returned user mode address. -+ -+ @output puiMMapOffset : points to mmap offset to be used in mmap2 sys call. -+ @output puiByteOffset : points to byte offset of start of memory -+ within mapped area returned by mmap2. -+ @output puiRealByteSize : points to size of area to be mapped. -+ @output puiUserVAddr : points to user mode address of start of -+ mapping, or 0 if it hasn't been mapped yet. -+ -+ @Return PVRSRV_ERROR : PVRSRV_OK, or error code. -+ -+ ******************************************************************************/ -+PVRSRV_ERROR -+PVRMMapOSMemHandleToMMapData(PVRSRV_PER_PROCESS_DATA *psPerProc, -+ IMG_HANDLE hMHandle, -+ IMG_UINTPTR_T *puiMMapOffset, -+ IMG_UINTPTR_T *puiByteOffset, -+ IMG_SIZE_T *puiRealByteSize, -+ IMG_UINTPTR_T *puiUserVAddr) -+{ -+ LinuxMemArea *psLinuxMemArea; -+ PKV_OFFSET_STRUCT psOffsetStruct; -+ IMG_HANDLE hOSMemHandle; -+ PVRSRV_ERROR eError; -+ -+ LinuxLockMutexNested(&g_sMMapMutex, PVRSRV_LOCK_CLASS_MMAP); -+ -+ PVR_ASSERT(PVRSRVGetMaxHandle(psPerProc->psHandleBase) <= MAX_MMAP_HANDLE); -+ -+ eError = PVRSRVLookupOSMemHandle(psPerProc->psHandleBase, &hOSMemHandle, hMHandle); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: Lookup of handle %p failed", __FUNCTION__, hMHandle)); -+ -+ goto exit_unlock; -+ } -+ -+ psLinuxMemArea = (LinuxMemArea *)hOSMemHandle; -+ -+ /* Sparse mappings have to ask the BM for the virtual size */ -+ if (psLinuxMemArea->hBMHandle) -+ { -+ *puiRealByteSize = BM_GetVirtualSize(psLinuxMemArea->hBMHandle); -+ *puiByteOffset = 0; -+ } -+ else -+ { -+ DetermineUsersSizeAndByteOffset(psLinuxMemArea, -+ puiRealByteSize, -+ puiByteOffset); -+ } -+ -+ /* Check whether this memory area has already been mapped */ -+ list_for_each_entry(psOffsetStruct, &psLinuxMemArea->sMMapOffsetStructList, sAreaItem) -+ { -+ if (psPerProc->ui32PID == psOffsetStruct->ui32PID) -+ { -+ if (!psLinuxMemArea->hBMHandle) -+ { -+ PVR_ASSERT(*puiRealByteSize == psOffsetStruct->uiRealByteSize); -+ } -+ /* -+ * User mode locking is required to stop two threads racing to -+ * map the same memory area. The lock should prevent a -+ * second thread retrieving mmap data for a given handle, -+ * before the first thread has done the mmap. -+ * Without locking, both threads may attempt the mmap, -+ * and one of them will fail. -+ */ -+ *puiMMapOffset = psOffsetStruct->uiMMapOffset; -+ *puiUserVAddr = psOffsetStruct->uiUserVAddr; -+ PVRSRVOffsetStructIncRef(psOffsetStruct); -+ -+ eError = PVRSRV_OK; -+ goto exit_unlock; -+ } -+ } -+ -+ /* Memory area won't have been mapped yet */ -+ *puiUserVAddr = 0; -+ -+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL) -+ if (LinuxMemAreaUsesPhysicalMap(psLinuxMemArea)) -+ { -+ *puiMMapOffset = LinuxMemAreaToCpuPFN(psLinuxMemArea, 0); -+ PVR_ASSERT(PFNIsPhysical(*puiMMapOffset)); -+ } -+ else -+#endif -+ { -+ *puiMMapOffset = HandleToMMapOffset(hMHandle); -+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL) -+ PVR_ASSERT(PFNIsSpecial(*puiMMapOffset)); -+#endif -+ } -+ -+ psOffsetStruct = CreateOffsetStruct(psLinuxMemArea, *puiMMapOffset, *puiRealByteSize); -+ if (psOffsetStruct == IMG_NULL) -+ { -+ eError = PVRSRV_ERROR_OUT_OF_MEMORY; -+ goto exit_unlock; -+ } -+ -+ /* -+ * Offset structures representing physical mappings are added to -+ * a list, so that they can be located when the memory area is mapped. -+ */ -+ list_add_tail(&psOffsetStruct->sMMapItem, &g_sMMapOffsetStructList); -+ -+ psOffsetStruct->bOnMMapList = IMG_TRUE; -+ -+ PVRSRVOffsetStructIncRef(psOffsetStruct); -+ -+ eError = PVRSRV_OK; -+ -+ /* Need to scale up the offset to counter the shifting that -+ is done in the mmap2() syscall, as it expects the pgoff -+ argument to be in units of 4,096 bytes irrespective of -+ page size */ -+ *puiMMapOffset = *puiMMapOffset << (PAGE_SHIFT - 12); -+ -+exit_unlock: -+ LinuxUnLockMutex(&g_sMMapMutex); -+ -+ return eError; -+} -+ -+ -+/*! -+ ******************************************************************************* -+ -+ @Function PVRMMapReleaseMMapData -+ -+ @Description -+ -+ Release mmap data. -+ -+ @input psPerProc : Per-process data. -+ @input hMHandle : Memory handle. -+ @input pbMUnmap : pointer to location for munmap flag. -+ @input puiUserVAddr : pointer to location for user mode address of mapping. -+ @input puiByteSize : pointer to location for size of mapping. -+ -+ @Output pbMUnmap : points to flag that indicates whether an munmap is -+ required. -+ @output puiUserVAddr : points to user mode address to munmap. -+ -+ @Return PVRSRV_ERROR : PVRSRV_OK, or error code. -+ -+ ******************************************************************************/ -+PVRSRV_ERROR -+PVRMMapReleaseMMapData(PVRSRV_PER_PROCESS_DATA *psPerProc, -+ IMG_HANDLE hMHandle, -+ IMG_BOOL *pbMUnmap, -+ IMG_SIZE_T *puiRealByteSize, -+ IMG_UINTPTR_T *puiUserVAddr) -+{ -+ LinuxMemArea *psLinuxMemArea; -+ PKV_OFFSET_STRUCT psOffsetStruct; -+ IMG_HANDLE hOSMemHandle; -+ PVRSRV_ERROR eError; -+ IMG_UINT32 ui32PID = OSGetCurrentProcessIDKM(); -+ -+ LinuxLockMutexNested(&g_sMMapMutex, PVRSRV_LOCK_CLASS_MMAP); -+ -+ PVR_ASSERT(PVRSRVGetMaxHandle(psPerProc->psHandleBase) <= MAX_MMAP_HANDLE); -+ -+ eError = PVRSRVLookupOSMemHandle(psPerProc->psHandleBase, &hOSMemHandle, hMHandle); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: Lookup of handle %p failed", __FUNCTION__, hMHandle)); -+ -+ goto exit_unlock; -+ } -+ -+ psLinuxMemArea = (LinuxMemArea *)hOSMemHandle; -+ -+ /* Find the offset structure */ -+ list_for_each_entry(psOffsetStruct, &psLinuxMemArea->sMMapOffsetStructList, sAreaItem) -+ { -+ if (psOffsetStruct->ui32PID == ui32PID) -+ { -+ if (psOffsetStruct->ui32RefCount == 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: Attempt to release mmap data with zero reference count for offset struct 0x%p, memory area %p", __FUNCTION__, psOffsetStruct, psLinuxMemArea)); -+ eError = PVRSRV_ERROR_STILL_MAPPED; -+ goto exit_unlock; -+ } -+ -+ PVRSRVOffsetStructDecRef(psOffsetStruct); -+ -+ *pbMUnmap = (IMG_BOOL)((psOffsetStruct->ui32RefCount == 0) && (psOffsetStruct->uiUserVAddr != 0)); -+ -+ *puiUserVAddr = (*pbMUnmap) ? psOffsetStruct->uiUserVAddr : 0; -+ *puiRealByteSize = (*pbMUnmap) ? psOffsetStruct->uiRealByteSize : 0; -+ -+ eError = PVRSRV_OK; -+ goto exit_unlock; -+ } -+ } -+ -+ /* MMap data not found */ -+ PVR_DPF((PVR_DBG_ERROR, "%s: Mapping data not found for handle %p (memory area %p)", __FUNCTION__, hMHandle, psLinuxMemArea)); -+ -+ eError = PVRSRV_ERROR_MAPPING_NOT_FOUND; -+ -+exit_unlock: -+ LinuxUnLockMutex(&g_sMMapMutex); -+ -+ return eError; -+} -+ -+static inline PKV_OFFSET_STRUCT -+FindOffsetStructByOffset(IMG_UINTPTR_T uiOffset, IMG_SIZE_T uiRealByteSize) -+{ -+ PKV_OFFSET_STRUCT psOffsetStruct; -+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL) -+ IMG_UINT32 ui32TID = GetCurrentThreadID(); -+#endif -+ IMG_UINT32 ui32PID = OSGetCurrentProcessIDKM(); -+ -+ list_for_each_entry(psOffsetStruct, &g_sMMapOffsetStructList, sMMapItem) -+ { -+ if (uiOffset == psOffsetStruct->uiMMapOffset && uiRealByteSize == psOffsetStruct->uiRealByteSize && psOffsetStruct->ui32PID == ui32PID) -+ { -+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL) -+ /* -+ * If the offset is physical, make sure the thread IDs match, -+ * as different threads may be mapping different memory areas -+ * with the same offset. -+ */ -+ if (!PFNIsPhysical(uiOffset) || psOffsetStruct->ui32TID == ui32TID) -+#endif -+ { -+ return psOffsetStruct; -+ } -+ } -+ } -+ -+ return IMG_NULL; -+} -+ -+ -+/* -+ * Map a memory area into user space. -+ * Note, the ui32ByteOffset is _not_ implicitly page aligned since -+ * LINUX_MEM_AREA_SUB_ALLOC LinuxMemAreas have no alignment constraints. -+ */ -+static IMG_BOOL -+DoMapToUser(LinuxMemArea *psLinuxMemArea, -+ struct vm_area_struct* ps_vma, -+ IMG_UINTPTR_T uiByteOffset) -+{ -+ IMG_SIZE_T uiByteSize; -+ -+ if ((psLinuxMemArea->hBMHandle) && (uiByteOffset != 0)) -+ { -+ /* Partial mapping of sparse allocations should never happen */ -+ return IMG_FALSE; -+ } -+ -+ if (psLinuxMemArea->eAreaType == LINUX_MEM_AREA_SUB_ALLOC) -+ { -+ return DoMapToUser(LinuxMemAreaRoot(psLinuxMemArea), /* PRQA S 3670 */ /* allow recursion */ -+ ps_vma, -+ psLinuxMemArea->uData.sSubAlloc.uiByteOffset + uiByteOffset); -+ } -+ -+ /* -+ * Note that ui32ByteSize may be larger than the size of the memory -+ * area being mapped, as the former is a multiple of the page size. -+ */ -+ uiByteSize = ps_vma->vm_end - ps_vma->vm_start; -+ PVR_ASSERT(ADDR_TO_PAGE_OFFSET(uiByteSize) == 0); -+ -+#if defined (__sparc__) -+ /* -+ * For LINUX_MEM_AREA_EXTERNAL_KV, we don't know where the address range -+ * we are being asked to map has come from, that is, whether it is memory -+ * or I/O. For all architectures other than SPARC, there is no distinction. -+ * Since we don't currently support SPARC, we won't worry about it. -+ */ -+#error "SPARC not supported" -+#endif -+ -+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL) -+ if (PFNIsPhysical(ps_vma->vm_pgoff)) -+ { -+ IMG_INT result; -+ -+ PVR_ASSERT(LinuxMemAreaPhysIsContig(psLinuxMemArea)); -+ PVR_ASSERT(LinuxMemAreaToCpuPFN(psLinuxMemArea, ui32ByteOffset) == ps_vma->vm_pgoff); -+ /* -+ * Since the memory is contiguous, we can map the whole range in one -+ * go . -+ */ -+ -+ PVR_ASSERT(psLinuxMemArea->hBMHandle == IMG_NULL); -+ -+ result = IO_REMAP_PFN_RANGE(ps_vma, ps_vma->vm_start, ps_vma->vm_pgoff, uiByteSize, ps_vma->vm_page_prot); -+ -+ if(result == 0) -+ { -+ return IMG_TRUE; -+ } -+ -+ PVR_DPF((PVR_DBG_MESSAGE, "%s: Failed to map contiguous physical address range (%d), trying non-contiguous path", __FUNCTION__, result)); -+ } -+#endif -+ -+ { -+ /* -+ * Memory may be non-contiguous, so we map the range page, -+ * by page. Since VM_PFNMAP mappings are assumed to be physically -+ * contiguous, we can't legally use REMAP_PFN_RANGE (that is, we -+ * could, but the resulting VMA may confuse other bits of the kernel -+ * that attempt to interpret it). -+ * The only alternative is to use VM_INSERT_PAGE, which requires -+ * finding the page structure corresponding to each page, or -+ * if mixed maps are supported (VM_MIXEDMAP), vm_insert_mixed. -+ */ -+ IMG_UINTPTR_T ulVMAPos; -+ IMG_UINTPTR_T uiByteEnd = uiByteOffset + uiByteSize; -+ IMG_UINTPTR_T uiPA; -+ IMG_UINTPTR_T uiAdjustedPA = uiByteOffset; -+#if defined(PVR_MAKE_ALL_PFNS_SPECIAL) -+ IMG_BOOL bMixedMap = IMG_FALSE; -+#endif -+ /* First pass, validate the page frame numbers */ -+ for(uiPA = uiByteOffset; uiPA < uiByteEnd; uiPA += PAGE_SIZE) -+ { -+ IMG_UINTPTR_T pfn; -+ IMG_BOOL bMapPage = IMG_TRUE; -+ -+ if (psLinuxMemArea->hBMHandle) -+ { -+ if (!BM_MapPageAtOffset(psLinuxMemArea->hBMHandle, uiPA)) -+ { -+ bMapPage = IMG_FALSE; -+ } -+ } -+ -+ if (bMapPage) -+ { -+ pfn = LinuxMemAreaToCpuPFN(psLinuxMemArea, uiAdjustedPA); -+ if (!pfn_valid(pfn)) -+ { -+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL) -+ PVR_DPF((PVR_DBG_ERROR,"%s: Error - PFN invalid: 0x" UINTPTR_FMT, __FUNCTION__, pfn)); -+ return IMG_FALSE; -+#else -+ bMixedMap = IMG_TRUE; -+#endif -+ } -+ else if (0 == page_count(pfn_to_page(pfn))) -+ { -+ bMixedMap = IMG_TRUE; -+ } -+ uiAdjustedPA += PAGE_SIZE; -+ } -+ } -+ -+#if defined(PVR_MAKE_ALL_PFNS_SPECIAL) -+ if (bMixedMap) -+ { -+ ps_vma->vm_flags |= VM_MIXEDMAP; -+ } -+#endif -+ /* Second pass, get the page structures and insert the pages */ -+ ulVMAPos = ps_vma->vm_start; -+ uiAdjustedPA = uiByteOffset; -+ for(uiPA = uiByteOffset; uiPA < uiByteEnd; uiPA += PAGE_SIZE) -+ { -+ IMG_UINTPTR_T pfn; -+ IMG_INT result; -+ IMG_BOOL bMapPage = IMG_TRUE; -+ -+ if (psLinuxMemArea->hBMHandle) -+ { -+ /* We have a sparse allocation, check if this page should be mapped */ -+ if (!BM_MapPageAtOffset(psLinuxMemArea->hBMHandle, uiPA)) -+ { -+ bMapPage = IMG_FALSE; -+ } -+ } -+ -+ if (bMapPage) -+ { -+ pfn = LinuxMemAreaToCpuPFN(psLinuxMemArea, uiAdjustedPA); -+ -+#if defined(PVR_MAKE_ALL_PFNS_SPECIAL) -+ if (bMixedMap) -+ { -+ result = vm_insert_mixed(ps_vma, ulVMAPos, pfn); -+ if(result != 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"%s: Error - vm_insert_mixed failed (%d)", __FUNCTION__, result)); -+ return IMG_FALSE; -+ } -+ } -+ else -+#endif -+ { -+ struct page *psPage; -+ -+ PVR_ASSERT(pfn_valid(pfn)); -+ -+ psPage = pfn_to_page(pfn); -+ -+ result = VM_INSERT_PAGE(ps_vma, ulVMAPos, psPage); -+ if(result != 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"%s: Error - VM_INSERT_PAGE failed (%d)", __FUNCTION__, result)); -+ return IMG_FALSE; -+ } -+ } -+ uiAdjustedPA += PAGE_SIZE; -+ } -+ ulVMAPos += PAGE_SIZE; -+ } -+ } -+ -+ return IMG_TRUE; -+} -+ -+ -+static IMG_VOID -+MMapVOpenNoLock(struct vm_area_struct* ps_vma) -+{ -+ PKV_OFFSET_STRUCT psOffsetStruct = (PKV_OFFSET_STRUCT)ps_vma->vm_private_data; -+ -+ PVR_ASSERT(psOffsetStruct != IMG_NULL); -+ PVR_ASSERT(!psOffsetStruct->bOnMMapList); -+ -+ PVRSRVOffsetStructIncMapped(psOffsetStruct); -+ -+ if (psOffsetStruct->ui32Mapped > 1) -+ { -+ PVR_DPF((PVR_DBG_WARNING, "%s: Offset structure 0x%p is being shared across processes (psOffsetStruct->ui32Mapped: %u)", __FUNCTION__, psOffsetStruct, psOffsetStruct->ui32Mapped)); -+ PVR_ASSERT((ps_vma->vm_flags & VM_DONTCOPY) == 0); -+ } -+ -+#if defined(DEBUG_LINUX_MMAP_AREAS) -+ -+ PVR_DPF((PVR_DBG_MESSAGE, -+ "%s: psLinuxMemArea 0x%p, KVAddress 0x%p MMapOffset " UINTPTR_FMT ", ui32Mapped %d", -+ __FUNCTION__, -+ psOffsetStruct->psLinuxMemArea, -+ LinuxMemAreaToCpuVAddr(psOffsetStruct->psLinuxMemArea), -+ psOffsetStruct->uiMMapOffset, -+ psOffsetStruct->ui32Mapped)); -+#endif -+} -+ -+ -+/* -+ * Linux mmap open entry point. -+ */ -+static void -+MMapVOpen(struct vm_area_struct* ps_vma) -+{ -+ LinuxLockMutexNested(&g_sMMapMutex, PVRSRV_LOCK_CLASS_MMAP); -+ -+ MMapVOpenNoLock(ps_vma); -+ -+ LinuxUnLockMutex(&g_sMMapMutex); -+} -+ -+ -+static IMG_VOID -+MMapVCloseNoLock(struct vm_area_struct* ps_vma) -+{ -+ PKV_OFFSET_STRUCT psOffsetStruct = (PKV_OFFSET_STRUCT)ps_vma->vm_private_data; -+ PVR_ASSERT(psOffsetStruct != IMG_NULL); -+ -+#if defined(DEBUG_LINUX_MMAP_AREAS) -+ PVR_DPF((PVR_DBG_MESSAGE, -+ "%s: psLinuxMemArea %p, CpuVAddr %p uiMMapOffset " UINTPTR_FMT ", ui32Mapped %d", -+ __FUNCTION__, -+ psOffsetStruct->psLinuxMemArea, -+ LinuxMemAreaToCpuVAddr(psOffsetStruct->psLinuxMemArea), -+ psOffsetStruct->uiMMapOffset, -+ psOffsetStruct->ui32Mapped)); -+#endif -+ -+ PVR_ASSERT(!psOffsetStruct->bOnMMapList); -+ PVRSRVOffsetStructDecMapped(psOffsetStruct); -+ if (psOffsetStruct->ui32Mapped == 0) -+ { -+ if (psOffsetStruct->ui32RefCount != 0) -+ { -+ PVR_DPF(( -+ PVR_DBG_MESSAGE, -+ "%s: psOffsetStruct %p has non-zero reference count (ui32RefCount = %u). User mode address of start of mapping: 0x" UINTPTR_FMT, -+ __FUNCTION__, -+ psOffsetStruct, -+ psOffsetStruct->ui32RefCount, -+ psOffsetStruct->uiUserVAddr)); -+ } -+ -+ DestroyOffsetStruct(psOffsetStruct); -+ } -+ -+ ps_vma->vm_private_data = NULL; -+} -+ -+/* -+ * Linux mmap close entry point. -+ */ -+static void -+MMapVClose(struct vm_area_struct* ps_vma) -+{ -+ LinuxLockMutexNested(&g_sMMapMutex, PVRSRV_LOCK_CLASS_MMAP); -+ -+ MMapVCloseNoLock(ps_vma); -+ -+ LinuxUnLockMutex(&g_sMMapMutex); -+} -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)) -+/* -+ * This vma operation is used to read data from mmap regions. It is called -+ * by access_process_vm, which is called to handle PTRACE_PEEKDATA ptrace -+ * requests and reads from /proc/<pid>/mem. -+ */ -+static int MMapVAccess(struct vm_area_struct *ps_vma, unsigned long addr, -+ void *buf, int len, int write) -+{ -+ PKV_OFFSET_STRUCT psOffsetStruct; -+ LinuxMemArea *psLinuxMemArea; -+ unsigned long ulOffset; -+ int iRetVal = -EINVAL; -+ IMG_VOID *pvKernelAddr; -+ -+ LinuxLockMutexNested(&g_sMMapMutex, PVRSRV_LOCK_CLASS_MMAP); -+ -+ psOffsetStruct = (PKV_OFFSET_STRUCT)ps_vma->vm_private_data; -+ psLinuxMemArea = psOffsetStruct->psLinuxMemArea; -+ ulOffset = addr - ps_vma->vm_start; -+ -+ if (ulOffset+len > psLinuxMemArea->uiByteSize) -+ /* Out of range. We shouldn't get here, because the kernel will do -+ the necessary checks before calling access_process_vm. */ -+ goto exit_unlock; -+ -+ pvKernelAddr = LinuxMemAreaToCpuVAddr(psLinuxMemArea); -+ -+ if (pvKernelAddr) -+ { -+ memcpy(buf, pvKernelAddr+ulOffset, len); -+ iRetVal = len; -+ } -+ else -+ { -+ IMG_UINTPTR_T pfn, uiOffsetInPage; -+ struct page *page; -+ -+ pfn = LinuxMemAreaToCpuPFN(psLinuxMemArea, ulOffset); -+ -+ if (!pfn_valid(pfn)) -+ goto exit_unlock; -+ -+ page = pfn_to_page(pfn); -+ uiOffsetInPage = ADDR_TO_PAGE_OFFSET(ulOffset); -+ -+ if (uiOffsetInPage + len > PAGE_SIZE) -+ /* The region crosses a page boundary */ -+ goto exit_unlock; -+ -+ pvKernelAddr = kmap(page); -+ memcpy(buf, pvKernelAddr + uiOffsetInPage, len); -+ kunmap(page); -+ -+ iRetVal = len; -+ } -+ -+exit_unlock: -+ LinuxUnLockMutex(&g_sMMapMutex); -+ return iRetVal; -+} -+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) */ -+ -+static struct vm_operations_struct MMapIOOps = -+{ -+ .open=MMapVOpen, -+ .close=MMapVClose, -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)) -+ .access=MMapVAccess, -+#endif -+}; -+ -+ -+/*! -+ ******************************************************************************* -+ -+ @Function PVRMMap -+ -+ @Description -+ -+ Driver mmap entry point. -+ -+ @input pFile : unused. -+ @input ps_vma : pointer to linux memory area descriptor. -+ -+ @Return 0, or Linux error code. -+ -+ ******************************************************************************/ -+int -+PVRMMap(struct file* pFile, struct vm_area_struct* ps_vma) -+{ -+ LinuxMemArea *psFlushMemArea = IMG_NULL; -+ PKV_OFFSET_STRUCT psOffsetStruct; -+ IMG_SIZE_T uiByteSize; -+ IMG_VOID *pvBase = IMG_NULL; -+ int iRetVal = 0; -+ IMG_UINTPTR_T uiByteOffset = 0; /* Keep compiler happy */ -+ IMG_SIZE_T uiFlushSize = 0; -+ -+ PVR_UNREFERENCED_PARAMETER(pFile); -+ -+ LinuxLockMutexNested(&g_sMMapMutex, PVRSRV_LOCK_CLASS_MMAP); -+ -+ uiByteSize = ps_vma->vm_end - ps_vma->vm_start; -+ -+ PVR_DPF((PVR_DBG_MESSAGE, "%s: Received mmap(2) request with ui32MMapOffset 0x" UINTPTR_FMT "," -+ " and uiByteSize %" SIZE_T_FMT_LEN "u(0x%" SIZE_T_FMT_LEN "x)", -+ __FUNCTION__, -+ ps_vma->vm_pgoff, -+ uiByteSize, -+ uiByteSize)); -+ -+ psOffsetStruct = FindOffsetStructByOffset(ps_vma->vm_pgoff, uiByteSize); -+ -+ if (psOffsetStruct == IMG_NULL) -+ { -+#if defined(SUPPORT_DRI_DRM) -+ LinuxUnLockMutex(&g_sMMapMutex); -+ -+#if !defined(SUPPORT_DRI_DRM_EXT) -+ /* Pass unknown requests onto the DRM module */ -+ return drm_mmap(pFile, ps_vma); -+#else -+ /* -+ * Indicate to caller that the request is not for us. -+ * Do not return this error elsewhere in this function, as the -+ * caller may use it as a clue as to whether the mmap request -+ * should be passed on to another component (e.g. drm_mmap). -+ */ -+ return -ENOENT; -+#endif -+#else -+ PVR_UNREFERENCED_PARAMETER(pFile); -+ -+ PVR_DPF((PVR_DBG_ERROR, -+ "%s: Attempted to mmap unregistered area at vm_pgoff 0x%lx", -+ __FUNCTION__, ps_vma->vm_pgoff)); -+ iRetVal = -EINVAL; -+#endif -+ goto unlock_and_return; -+ } -+ -+ list_del(&psOffsetStruct->sMMapItem); -+ psOffsetStruct->bOnMMapList = IMG_FALSE; -+ -+ /* Only support shared writeable mappings */ -+ if (((ps_vma->vm_flags & VM_WRITE) != 0) && -+ ((ps_vma->vm_flags & VM_SHARED) == 0)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: Cannot mmap non-shareable writable areas", __FUNCTION__)); -+ iRetVal = -EINVAL; -+ goto unlock_and_return; -+ } -+ -+ PVR_DPF((PVR_DBG_MESSAGE, "%s: Mapped psLinuxMemArea 0x%p\n", -+ __FUNCTION__, psOffsetStruct->psLinuxMemArea)); -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0)) -+ ps_vma->vm_flags |= VM_RESERVED; -+#else -+ ps_vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP; /* Don't swap */ -+#endif -+ -+ ps_vma->vm_flags |= VM_IO; -+ -+ /* -+ * Disable mremap because our nopage handler assumes all -+ * page requests have already been validated. -+ */ -+ ps_vma->vm_flags |= VM_DONTEXPAND; -+ -+ /* Don't allow mapping to be inherited across a process fork */ -+ ps_vma->vm_flags |= VM_DONTCOPY; -+ -+ ps_vma->vm_private_data = (void *)psOffsetStruct; -+ -+ switch(psOffsetStruct->psLinuxMemArea->ui32AreaFlags & PVRSRV_HAP_CACHETYPE_MASK) -+ { -+ case PVRSRV_HAP_CACHED: -+ /* This is the default, do nothing. */ -+ break; -+ case PVRSRV_HAP_WRITECOMBINE: -+ ps_vma->vm_page_prot = PGPROT_WC(ps_vma->vm_page_prot); -+ break; -+ case PVRSRV_HAP_UNCACHED: -+ ps_vma->vm_page_prot = PGPROT_UC(ps_vma->vm_page_prot); -+ break; -+ default: -+ PVR_DPF((PVR_DBG_ERROR, "%s: unknown cache type", __FUNCTION__)); -+ iRetVal = -EINVAL; -+ goto unlock_and_return; -+ } -+ -+#ifdef CONFIG_ARCH_OMAP5 -+ { -+ IMG_BOOL bModPageProt = IMG_FALSE; -+ -+ /* In OMAP5, the Cortex A15 no longer masks an issue with the L2 -+ * interconnect. Write-combined access to the TILER aperture will -+ * generate SIGBUS / "non-line fetch abort" errors due to L2 -+ * interconnect bus accesses. The workaround is to use a shared -+ * device access. -+ */ -+ -+ bModPageProt |= (psOffsetStruct->psLinuxMemArea->eAreaType == LINUX_MEM_AREA_ION); -+ -+#ifdef CONFIG_DSSCOMP -+ bModPageProt |= is_tiler_addr(LinuxMemAreaToCpuPAddr(psOffsetStruct->psLinuxMemArea, 0).uiAddr); -+#endif /* CONFIG_DSSCOMP */ -+ -+ if (bModPageProt) -+ { -+ ps_vma->vm_page_prot = __pgprot_modify(ps_vma->vm_page_prot, -+ L_PTE_MT_MASK, -+ L_PTE_MT_DEV_SHARED); -+ } -+ } -+#endif /* CONFIG_ARCH_OMAP5 */ -+ -+ /* Install open and close handlers for ref-counting */ -+ ps_vma->vm_ops = &MMapIOOps; -+ -+ if(!DoMapToUser(psOffsetStruct->psLinuxMemArea, ps_vma, 0)) -+ { -+ iRetVal = -EAGAIN; -+ goto unlock_and_return; -+ } -+ -+ PVR_ASSERT(psOffsetStruct->uiUserVAddr == 0); -+ -+ psOffsetStruct->uiUserVAddr = ps_vma->vm_start; -+ -+ /* Compute the flush region (if necessary) inside the mmap mutex */ -+ if(psOffsetStruct->psLinuxMemArea->bNeedsCacheInvalidate) -+ { -+ psFlushMemArea = psOffsetStruct->psLinuxMemArea; -+ -+ /* Sparse mappings have to ask the BM for the virtual size */ -+ if (psFlushMemArea->hBMHandle) -+ { -+ pvBase = (IMG_VOID *)ps_vma->vm_start; -+ uiByteOffset = 0; -+ uiFlushSize = BM_GetVirtualSize(psFlushMemArea->hBMHandle); -+ } -+ else -+ { -+ IMG_SIZE_T uiDummyByteSize; -+ -+ DetermineUsersSizeAndByteOffset(psFlushMemArea, -+ &uiDummyByteSize, -+ &uiByteOffset); -+ -+ pvBase = (IMG_VOID *)ps_vma->vm_start + uiByteOffset; -+ uiFlushSize = psFlushMemArea->uiByteSize; -+ } -+ -+ psFlushMemArea->bNeedsCacheInvalidate = IMG_FALSE; -+ } -+ -+ /* Call the open routine to increment the usage count */ -+ MMapVOpenNoLock(ps_vma); -+ -+ PVR_DPF((PVR_DBG_MESSAGE, "%s: Mapped area at offset 0x" UINTPTR_FMT "\n", -+ __FUNCTION__, (IMG_UINTPTR_T)ps_vma->vm_pgoff)); -+ -+unlock_and_return: -+ if (iRetVal != 0 && psOffsetStruct != IMG_NULL) -+ { -+ DestroyOffsetStruct(psOffsetStruct); -+ } -+ -+ LinuxUnLockMutex(&g_sMMapMutex); -+ -+ if(psFlushMemArea) -+ { -+ OSInvalidateCPUCacheRangeKM(psFlushMemArea, uiByteOffset, pvBase, -+ uiFlushSize); -+ } -+ -+ return iRetVal; -+} -+ -+ -+#if defined(DEBUG_LINUX_MMAP_AREAS) -+ -+/* -+ * Lock MMap regions list (called on page start/stop while reading /proc/mmap) -+ -+ * sfile : seq_file that handles /proc file -+ * start : TRUE if it's start, FALSE if it's stop -+ * -+*/ -+static void ProcSeqStartstopMMapRegistations(struct seq_file *sfile,IMG_BOOL start) -+{ -+ if(start) -+ { -+ LinuxLockMutexNested(&g_sMMapMutex, PVRSRV_LOCK_CLASS_MMAP); -+ } -+ else -+ { -+ LinuxUnLockMutex(&g_sMMapMutex); -+ } -+} -+ -+ -+/* -+ * Convert offset (index from KVOffsetTable) to element -+ * (called when reading /proc/mmap file) -+ -+ * sfile : seq_file that handles /proc file -+ * off : index into the KVOffsetTable from which to print -+ * -+ * returns void* : Pointer to element that will be dumped -+ * -+*/ -+static void* ProcSeqOff2ElementMMapRegistrations(struct seq_file *sfile, loff_t off) -+{ -+ LinuxMemArea *psLinuxMemArea; -+ if(!off) -+ { -+ return PVR_PROC_SEQ_START_TOKEN; -+ } -+ -+ list_for_each_entry(psLinuxMemArea, &g_sMMapAreaList, sMMapItem) -+ { -+ PKV_OFFSET_STRUCT psOffsetStruct; -+ -+ list_for_each_entry(psOffsetStruct, &psLinuxMemArea->sMMapOffsetStructList, sAreaItem) -+ { -+ off--; -+ if (off == 0) -+ { -+ PVR_ASSERT(psOffsetStruct->psLinuxMemArea == psLinuxMemArea); -+ return (void*)psOffsetStruct; -+ } -+ } -+ } -+ return (void*)0; -+} -+ -+/* -+ * Gets next MMap element to show. (called when reading /proc/mmap file) -+ -+ * sfile : seq_file that handles /proc file -+ * el : actual element -+ * off : index into the KVOffsetTable from which to print -+ * -+ * returns void* : Pointer to element to show (0 ends iteration) -+*/ -+static void* ProcSeqNextMMapRegistrations(struct seq_file *sfile,void* el,loff_t off) -+{ -+ return ProcSeqOff2ElementMMapRegistrations(sfile,off); -+} -+ -+ -+/* -+ * Show MMap element (called when reading /proc/mmap file) -+ -+ * sfile : seq_file that handles /proc file -+ * el : actual element -+ * -+*/ -+static void ProcSeqShowMMapRegistrations(struct seq_file *sfile, void *el) -+{ -+ KV_OFFSET_STRUCT *psOffsetStruct = (KV_OFFSET_STRUCT*)el; -+ LinuxMemArea *psLinuxMemArea; -+ IMG_SIZE_T uiRealByteSize; -+ IMG_UINTPTR_T uiByteOffset; -+ -+ if(el == PVR_PROC_SEQ_START_TOKEN) -+ { -+ seq_printf( sfile, -+#if !defined(DEBUG_LINUX_XML_PROC_FILES) -+ "Allocations registered for mmap: %u\n" -+ "In total these areas correspond to %" SIZE_T_FMT_LEN "u bytes\n" -+ "psLinuxMemArea " -+ "UserVAddr " -+ "KernelVAddr " -+ "CpuPAddr " -+ "MMapOffset " -+ "ByteLength " -+ "LinuxMemType " -+ "Pid Name Flags\n", -+#else -+ "<mmap_header>\n" -+ "\t<count>%u</count>\n" -+ "\t<bytes>%" SIZE_T_FMT_LEN "u</bytes>\n" -+ "</mmap_header>\n", -+#endif -+ g_ui32RegisteredAreas, -+ g_uiTotalByteSize -+ ); -+ return; -+ } -+ -+ psLinuxMemArea = psOffsetStruct->psLinuxMemArea; -+ -+ DetermineUsersSizeAndByteOffset(psLinuxMemArea, -+ &uiRealByteSize, -+ &uiByteOffset); -+ -+ seq_printf( sfile, -+#if !defined(DEBUG_LINUX_XML_PROC_FILES) -+ "%p %p %p " CPUPADDR_FMT " " UINTPTR_FMT " %" SIZE_T_FMT_LEN "u %-24s %-5u %-8s %08x(%s)\n", -+#else -+ "<mmap_record>\n" -+ "\t<pointer>%p</pointer>\n" -+ "\t<user_virtual>%p</user_virtual>\n" -+ "\t<kernel_virtual>%p</kernel_virtual>\n" -+ "\t<cpu_physical>" CPUPADDR_FMT "</cpu_physical>\n" -+ "\t<mmap_offset>" UINTPTR_FMT "</mmap_offset>\n" -+ "\t<bytes>%" SIZE_T_FMT_LEN "u</bytes>\n" -+ "\t<linux_mem_area_type>%-24s</linux_mem_area_type>\n" -+ "\t<pid>%-5u</pid>\n" -+ "\t<name>%-8s</name>\n" -+ "\t<flags>%08x</flags>\n" -+ "\t<flags_string>%s</flags_string>\n" -+ "</mmap_record>\n", -+#endif -+ psLinuxMemArea, -+ (IMG_PVOID)(psOffsetStruct->uiUserVAddr + uiByteOffset), -+ LinuxMemAreaToCpuVAddr(psLinuxMemArea), -+ LinuxMemAreaToCpuPAddr(psLinuxMemArea,0).uiAddr, -+ (IMG_UINTPTR_T)psOffsetStruct->uiMMapOffset, -+ psLinuxMemArea->uiByteSize, -+ LinuxMemAreaTypeToString(psLinuxMemArea->eAreaType), -+ psOffsetStruct->ui32PID, -+ psOffsetStruct->pszName, -+ psLinuxMemArea->ui32AreaFlags, -+ HAPFlagsToString(psLinuxMemArea->ui32AreaFlags)); -+} -+ -+#endif -+ -+ -+/*! -+ ******************************************************************************* -+ -+ @Function PVRMMapRegisterArea -+ -+ @Description -+ -+ Register a memory area with the mmap code. -+ -+ @input psLinuxMemArea : pointer to memory area. -+ -+ @Return PVRSRV_OK, or PVRSRV_ERROR. -+ -+ ******************************************************************************/ -+PVRSRV_ERROR -+PVRMMapRegisterArea(LinuxMemArea *psLinuxMemArea) -+{ -+ PVRSRV_ERROR eError; -+#if defined(DEBUG) || defined(DEBUG_LINUX_MMAP_AREAS) -+ const IMG_CHAR *pszName = LinuxMemAreaTypeToString(LinuxMemAreaRootType(psLinuxMemArea)); -+#endif -+ -+ LinuxLockMutexNested(&g_sMMapMutex, PVRSRV_LOCK_CLASS_MMAP); -+ -+#if defined(DEBUG) || defined(DEBUG_LINUX_MMAP_AREAS) -+ PVR_DPF((PVR_DBG_MESSAGE, -+ "%s(%s, psLinuxMemArea 0x%p, ui32AllocFlags 0x%8x)", -+ __FUNCTION__, pszName, psLinuxMemArea, psLinuxMemArea->ui32AreaFlags)); -+#endif -+ -+ PVR_ASSERT(psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC || LinuxMemAreaRoot(psLinuxMemArea)->eAreaType != LINUX_MEM_AREA_SUB_ALLOC); -+ -+ /* Check this mem area hasn't already been registered */ -+ if(psLinuxMemArea->bMMapRegistered) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: psLinuxMemArea 0x%p is already registered", -+ __FUNCTION__, psLinuxMemArea)); -+ eError = PVRSRV_ERROR_INVALID_PARAMS; -+ goto exit_unlock; -+ } -+ -+ list_add_tail(&psLinuxMemArea->sMMapItem, &g_sMMapAreaList); -+ -+ psLinuxMemArea->bMMapRegistered = IMG_TRUE; -+ -+#if defined(DEBUG_LINUX_MMAP_AREAS) -+ g_ui32RegisteredAreas++; -+ /* -+ * Sub memory areas are excluded from g_ui32TotalByteSize so that we -+ * don't count memory twice, once for the parent and again for sub -+ * allocationis. -+ */ -+ if (psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC) -+ { -+ g_uiTotalByteSize += psLinuxMemArea->uiByteSize; -+ } -+#endif -+ -+ eError = PVRSRV_OK; -+ -+exit_unlock: -+ LinuxUnLockMutex(&g_sMMapMutex); -+ -+ return eError; -+} -+ -+ -+/*! -+ ******************************************************************************* -+ -+ @Function PVRMMapRemoveRegisterArea -+ -+ @Description -+ -+ Unregister a memory area with the mmap code. -+ -+ @input psLinuxMemArea : pointer to memory area. -+ -+ @Return PVRSRV_OK, or PVRSRV_ERROR. -+ -+ ******************************************************************************/ -+PVRSRV_ERROR -+PVRMMapRemoveRegisteredArea(LinuxMemArea *psLinuxMemArea) -+{ -+ PVRSRV_ERROR eError; -+ PKV_OFFSET_STRUCT psOffsetStruct, psTmpOffsetStruct; -+ -+ LinuxLockMutexNested(&g_sMMapMutex, PVRSRV_LOCK_CLASS_MMAP); -+ -+ PVR_ASSERT(psLinuxMemArea->bMMapRegistered); -+ -+ list_for_each_entry_safe(psOffsetStruct, psTmpOffsetStruct, &psLinuxMemArea->sMMapOffsetStructList, sAreaItem) -+ { -+ if (psOffsetStruct->ui32Mapped != 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: psOffsetStruct 0x%p for memory area 0x0x%p is still mapped; psOffsetStruct->ui32Mapped %u", __FUNCTION__, psOffsetStruct, psLinuxMemArea, psOffsetStruct->ui32Mapped)); -+ dump_stack(); -+ PVRSRVDumpRefCountCCB(); -+ eError = PVRSRV_ERROR_STILL_MAPPED; -+ goto exit_unlock; -+ } -+ else -+ { -+ /* -+ * An offset structure is created when a call is made to get -+ * the mmap data for a physical mapping. If the data is never -+ * used for mmap, we will be left with an umapped offset -+ * structure. -+ */ -+ PVR_DPF((PVR_DBG_WARNING, "%s: psOffsetStruct 0x%p was never mapped", __FUNCTION__, psOffsetStruct)); -+ } -+ -+ PVR_ASSERT((psOffsetStruct->ui32Mapped == 0) && psOffsetStruct->bOnMMapList); -+ -+ DestroyOffsetStruct(psOffsetStruct); -+ } -+ -+ list_del(&psLinuxMemArea->sMMapItem); -+ -+ psLinuxMemArea->bMMapRegistered = IMG_FALSE; -+ -+#if defined(DEBUG_LINUX_MMAP_AREAS) -+ g_ui32RegisteredAreas--; -+ if (psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC) -+ { -+ g_uiTotalByteSize -= psLinuxMemArea->uiByteSize; -+ } -+#endif -+ -+ eError = PVRSRV_OK; -+ -+exit_unlock: -+ LinuxUnLockMutex(&g_sMMapMutex); -+ return eError; -+} -+ -+ -+/*! -+ ******************************************************************************* -+ -+ @Function LinuxMMapPerProcessConnect -+ -+ @Description -+ -+ Per-process mmap initialisation code. -+ -+ @input psEnvPerProc : pointer to OS specific per-process data. -+ -+ @Return PVRSRV_OK, or PVRSRV_ERROR. -+ -+ ******************************************************************************/ -+PVRSRV_ERROR -+LinuxMMapPerProcessConnect(PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc) -+{ -+ PVR_UNREFERENCED_PARAMETER(psEnvPerProc); -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+ ******************************************************************************* -+ -+ @Function LinuxMMapPerProcessDisconnect -+ -+ @Description -+ -+ Per-process mmap deinitialisation code. -+ -+ @input psEnvPerProc : pointer to OS specific per-process data. -+ -+ ******************************************************************************/ -+IMG_VOID -+LinuxMMapPerProcessDisconnect(PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc) -+{ -+ PKV_OFFSET_STRUCT psOffsetStruct, psTmpOffsetStruct; -+ IMG_BOOL bWarn = IMG_FALSE; -+ IMG_UINT32 ui32PID = OSGetCurrentProcessIDKM(); -+ -+ PVR_UNREFERENCED_PARAMETER(psEnvPerProc); -+ -+ LinuxLockMutexNested(&g_sMMapMutex, PVRSRV_LOCK_CLASS_MMAP); -+ -+ list_for_each_entry_safe(psOffsetStruct, psTmpOffsetStruct, &g_sMMapOffsetStructList, sMMapItem) -+ { -+ if (psOffsetStruct->ui32PID == ui32PID) -+ { -+ if (!bWarn) -+ { -+ PVR_DPF((PVR_DBG_WARNING, "%s: process has unmapped offset structures. Removing them", __FUNCTION__)); -+ bWarn = IMG_TRUE; -+ } -+ PVR_ASSERT(psOffsetStruct->ui32Mapped == 0); -+ PVR_ASSERT(psOffsetStruct->bOnMMapList); -+ -+ DestroyOffsetStruct(psOffsetStruct); -+ } -+ } -+ -+ LinuxUnLockMutex(&g_sMMapMutex); -+} -+ -+ -+/*! -+ ******************************************************************************* -+ -+ @Function LinuxMMapPerProcessHandleOptions -+ -+ @Description -+ -+ Set secure handle options required by mmap code. -+ -+ @input psHandleBase : pointer to handle base. -+ -+ @Return PVRSRV_OK, or PVRSRV_ERROR. -+ -+ ******************************************************************************/ -+PVRSRV_ERROR LinuxMMapPerProcessHandleOptions(PVRSRV_HANDLE_BASE *psHandleBase) -+{ -+ PVRSRV_ERROR eError; -+ -+ eError = PVRSRVSetMaxHandle(psHandleBase, MAX_MMAP_HANDLE); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"%s: failed to set handle limit (%d)", __FUNCTION__, eError)); -+ return eError; -+ } -+ -+ return eError; -+} -+ -+ -+/*! -+ ******************************************************************************* -+ -+ @Function PVRMMapInit -+ -+ @Description -+ -+ MMap initialisation code -+ -+ ******************************************************************************/ -+IMG_VOID -+PVRMMapInit(IMG_VOID) -+{ -+ LinuxInitMutex(&g_sMMapMutex); -+ -+ g_psMemmapCache = KMemCacheCreateWrapper("img-mmap", sizeof(KV_OFFSET_STRUCT), 0, 0); -+ if (!g_psMemmapCache) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"%s: failed to allocate kmem_cache", __FUNCTION__)); -+ goto error; -+ } -+ -+#if defined(DEBUG_LINUX_MMAP_AREAS) -+ g_ProcMMap = CreateProcReadEntrySeq("mmap", NULL, -+ ProcSeqNextMMapRegistrations, -+ ProcSeqShowMMapRegistrations, -+ ProcSeqOff2ElementMMapRegistrations, -+ ProcSeqStartstopMMapRegistations -+ ); -+#endif /* defined(DEBUG_LINUX_MMAP_AREAS) */ -+ return; -+ -+error: -+ PVRMMapCleanup(); -+ return; -+} -+ -+ -+/*! -+ ******************************************************************************* -+ -+ @Function PVRMMapCleanup -+ -+ @Description -+ -+ Mmap deinitialisation code -+ -+ ******************************************************************************/ -+IMG_VOID -+PVRMMapCleanup(IMG_VOID) -+{ -+ PVRSRV_ERROR eError; -+ -+ if (!list_empty(&g_sMMapAreaList)) -+ { -+ LinuxMemArea *psLinuxMemArea, *psTmpMemArea; -+ -+ PVR_DPF((PVR_DBG_ERROR, "%s: Memory areas are still registered with MMap", __FUNCTION__)); -+ -+ PVR_TRACE(("%s: Unregistering memory areas", __FUNCTION__)); -+ list_for_each_entry_safe(psLinuxMemArea, psTmpMemArea, &g_sMMapAreaList, sMMapItem) -+ { -+ eError = PVRMMapRemoveRegisteredArea(psLinuxMemArea); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: PVRMMapRemoveRegisteredArea failed (%d)", __FUNCTION__, eError)); -+ } -+ PVR_ASSERT(eError == PVRSRV_OK); -+ -+ LinuxMemAreaDeepFree(psLinuxMemArea); -+ } -+ } -+ PVR_ASSERT(list_empty((&g_sMMapAreaList))); -+ -+#if defined(DEBUG_LINUX_MMAP_AREAS) -+ RemoveProcEntrySeq(g_ProcMMap); -+#endif /* defined(DEBUG_LINUX_MMAP_AREAS) */ -+ -+ if(g_psMemmapCache) -+ { -+ KMemCacheDestroyWrapper(g_psMemmapCache); -+ g_psMemmapCache = NULL; -+ } -+} -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/mmap.h b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/mmap.h -new file mode 100644 -index 0000000..5094a40 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/mmap.h -@@ -0,0 +1,231 @@ -+/*************************************************************************/ /*! -+@Title Linux mmap interface declaration -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#if !defined(__MMAP_H__) -+#define __MMAP_H__ -+ -+#include <linux/mm.h> -+#include <linux/list.h> -+ -+#if defined(VM_MIXEDMAP) -+/* -+ * Mixed maps allow us to avoid using raw PFN mappings (VM_PFNMAP) for -+ * pages without pages structures ("struct page"), giving us more -+ * freedom in choosing the mmap offset for mappings. Mixed maps also -+ * allow both the mmap and the wrap code to be simplified somewhat. -+ */ -+#define PVR_MAKE_ALL_PFNS_SPECIAL -+#endif -+ -+#include "perproc.h" -+#include "mm.h" -+ -+/* -+ * This structure represents the relationship between an mmap2 file -+ * offset and a LinuxMemArea for a given process. -+ */ -+typedef struct KV_OFFSET_STRUCT_TAG -+{ -+ /* -+ * Mapping count. Incremented when the mapping is created, and -+ * if the mapping is inherited across a process fork. -+ */ -+ IMG_UINT32 ui32Mapped; -+ -+ /* -+ * Offset to be passed to mmap2 to map the associated memory area -+ * into user space. The offset may represent the page frame number -+ * of the first page in the area (if the area is physically -+ * contiguous), or it may represent the secure handle associated -+ * with the area. -+ */ -+ IMG_UINTPTR_T uiMMapOffset; -+ -+ IMG_SIZE_T uiRealByteSize; -+ -+ /* Memory area associated with this offset structure */ -+ LinuxMemArea *psLinuxMemArea; -+ -+#if !defined(PVR_MAKE_ALL_PFNS_SPECIAL) -+ /* ID of the thread that owns this structure */ -+ IMG_UINT32 ui32TID; -+#endif -+ -+ /* ID of the process that owns this structure */ -+ IMG_UINT32 ui32PID; -+ -+ /* -+ * For offsets that represent actual page frame numbers, this structure -+ * is temporarily put on a list so that it can be found from the -+ * driver mmap entry point. This flag indicates the structure is -+ * on the list. -+ */ -+ IMG_BOOL bOnMMapList; -+ -+ /* Reference count for this structure */ -+ IMG_UINT32 ui32RefCount; -+ -+ /* -+ * User mode address of start of mapping. This is not necessarily the -+ * first user mode address of the memory area. -+ */ -+ IMG_UINTPTR_T uiUserVAddr; -+ -+ /* Extra entries to support proc filesystem debug info */ -+#if defined(DEBUG_LINUX_MMAP_AREAS) -+ const IMG_CHAR *pszName; -+#endif -+ -+ /* List entry field for MMap list */ -+ struct list_head sMMapItem; -+ -+ /* List entry field for per-memory area list */ -+ struct list_head sAreaItem; -+}KV_OFFSET_STRUCT, *PKV_OFFSET_STRUCT; -+ -+ -+ -+/*! -+ ******************************************************************************* -+ * @Function Mmap initialisation code -+ ******************************************************************************/ -+IMG_VOID PVRMMapInit(IMG_VOID); -+ -+ -+/*! -+ ******************************************************************************* -+ * @Function Mmap de-initialisation code -+ ******************************************************************************/ -+IMG_VOID PVRMMapCleanup(IMG_VOID); -+ -+ -+/*! -+ ******************************************************************************* -+ * @Function Registers a memory area with the mmap code -+ * -+ * @Input psLinuxMemArea -+ * -+ * @Return PVRSRV_ERROR status -+ ******************************************************************************/ -+PVRSRV_ERROR PVRMMapRegisterArea(LinuxMemArea *psLinuxMemArea); -+ -+ -+/*! -+ ******************************************************************************* -+ * @Function Unregisters a memory area from the mmap code -+ * -+ * @Input psLinuxMemArea -+ * -+ * @Return PVRSRV_ERROR status -+ ******************************************************************************/ -+PVRSRV_ERROR PVRMMapRemoveRegisteredArea(LinuxMemArea *psLinuxMemArea); -+ -+ -+/*! -+ ****************************************************************************** -+ * @Function When a userspace services client, requests to map a memory -+ * area to userspace, this function validates the request and -+ * returns the details that the client must use when calling mmap(2). -+ * -+ * @Input psPerProc Per process data. -+ * @Input hMHandle Handle associated with the memory to map. -+ * This is a (secure) handle to the OS specific -+ * memory handle structure (hOSMemHandle), or -+ * a handle to a structure that contains the -+ * memory handle. -+ * @Output pui32MMapOffset The page aligned offset that the client must -+ * pass to the mmap2 system call. -+ * @Output pui32ByteOffset The real mapping that will be created for the -+ * services client may have a different -+ * size/alignment from it request. This offset -+ * is returned to the client and should be added -+ * to virtual address returned from mmap2 to get -+ * the first address corresponding to its request. -+ * @Output pui32RealByteOffset The size that the mapping will really be, -+ * that the client must also pass to mmap/munmap. -+ * -+ * @Output pui32UserVAddr Pointer to returned user mode address of -+ * mapping. -+ * @Return PVRSRV_ERROR -+ ******************************************************************************/ -+PVRSRV_ERROR PVRMMapOSMemHandleToMMapData(PVRSRV_PER_PROCESS_DATA *psPerProc, -+ IMG_HANDLE hMHandle, -+ IMG_UINTPTR_T *puiMMapOffset, -+ IMG_UINTPTR_T *puiByteOffset, -+ IMG_SIZE_T *puiRealByteSize, -+ IMG_UINTPTR_T *puiUserVAddr); -+ -+/*! -+ ******************************************************************************* -+ -+ @Function Release mmap data. -+ -+ @Input psPerProc Per-process data. -+ @Input hMHandle Memory handle. -+ -+ @Output pbMUnmap Flag that indicates whether an munmap is -+ required. -+ @Output pui32RealByteSize Location for size of mapping. -+ @Output pui32UserVAddr User mode address to munmap. -+ -+ @Return PVRSRV_ERROR -+ ******************************************************************************/ -+PVRSRV_ERROR -+PVRMMapReleaseMMapData(PVRSRV_PER_PROCESS_DATA *psPerProc, -+ IMG_HANDLE hMHandle, -+ IMG_BOOL *pbMUnmap, -+ IMG_SIZE_T *puiRealByteSize, -+ IMG_UINTPTR_T *puiUserVAddr); -+ -+/*! -+ ******************************************************************************* -+ * @Function driver mmap entry point -+ * -+ * @Input pFile : user file structure -+ * -+ * @Input ps_vma : vm area structure -+ * -+ * @Return 0 for success, -errno for failure. -+ ******************************************************************************/ -+int PVRMMap(struct file* pFile, struct vm_area_struct* ps_vma); -+ -+ -+#endif /* __MMAP_H__ */ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/module.c b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/module.c -new file mode 100644 -index 0000000..157bef3 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/module.c -@@ -0,0 +1,1311 @@ -+/*************************************************************************/ /*! -+@Title Linux module setup -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#include <linux/version.h> -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)) -+#ifndef AUTOCONF_INCLUDED -+#include <linux/config.h> -+#endif -+#endif -+ -+#if defined(SUPPORT_DRI_DRM) && !defined(SUPPORT_DRI_DRM_PLUGIN) -+#define PVR_MOD_STATIC -+#else -+ /* -+ * For LDM drivers, define PVR_LDM_MODULE to indicate generic LDM -+ * support is required, besides indicating the exact support -+ * required (e.g. platform, or PCI device). -+ */ -+ #if defined(LDM_PLATFORM) -+ #define PVR_LDM_PLATFORM_MODULE -+ #define PVR_LDM_DEVICE_CLASS -+ #define PVR_LDM_MODULE -+ #else -+ #if defined(LDM_PCI) -+ #define PVR_LDM_DEVICE_CLASS -+ #define PVR_LDM_PCI_MODULE -+ #define PVR_LDM_MODULE -+ #else -+ #if defined(SYS_SHARES_WITH_3PKM) -+ #define PVR_LDM_DEVICE_CLASS -+ #endif -+ #endif -+ #endif -+#define PVR_MOD_STATIC static -+#endif -+ -+#if defined(PVR_LDM_PLATFORM_PRE_REGISTERED) -+#if !defined(NO_HARDWARE) -+#define PVR_USE_PRE_REGISTERED_PLATFORM_DEV -+#endif -+#endif -+ -+#include <linux/init.h> -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/fs.h> -+#include <linux/proc_fs.h> -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)) -+#include <linux/of.h> -+#endif -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)) -+#include <linux/reset.h> -+#include <linux/io.h> -+#endif -+ -+#if defined(SUPPORT_DRI_DRM) -+#include <drm/drmP.h> -+#if defined(PVR_SECURE_DRM_AUTH_EXPORT) -+#include "env_perproc.h" -+#endif -+#endif -+ -+#if defined(PVR_LDM_PLATFORM_MODULE) -+#include <linux/platform_device.h> -+#endif /* PVR_LDM_PLATFORM_MODULE */ -+ -+#if defined(PVR_LDM_PCI_MODULE) -+#include <linux/pci.h> -+#endif /* PVR_LDM_PCI_MODULE */ -+ -+#if defined(PVR_LDM_DEVICE_CLASS) -+#include <linux/device.h> -+#endif /* PVR_LDM_DEVICE_CLASS */ -+ -+#if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL) -+#include <asm/uaccess.h> -+#endif -+ -+#include "img_defs.h" -+#include "services.h" -+#include "kerneldisplay.h" -+#include "kernelbuffer.h" -+#include "syscommon.h" -+#include "pvrmmap.h" -+#include "mutils.h" -+#include "mm.h" -+#include "mmap.h" -+#include "mutex.h" -+#include "pvr_debug.h" -+#include "srvkm.h" -+#include "perproc.h" -+#include "handle.h" -+#include "pvr_bridge_km.h" -+#include "proc.h" -+#include "pvrmodule.h" -+#include "private_data.h" -+#include "lock.h" -+#include "linkage.h" -+#include "buffer_manager.h" -+#if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) -+#include "pvr_sync.h" -+#endif -+ -+#if defined(SUPPORT_DRI_DRM) -+#include "pvr_drm.h" -+#endif -+/* -+ * DRVNAME is the name we use to register our driver. -+ * DEVNAME is the name we use to register actual device nodes. -+ */ -+#if defined(PVR_LDM_MODULE) -+//#define DRVNAME PVR_LDM_DRIVER_REGISTRATION_NAME -+#define DRVNAME PVRSRV_MODNAME -+#endif -+#define DEVNAME PVRSRV_MODNAME -+ -+#if defined(SUPPORT_DRI_DRM) -+#define PRIVATE_DATA(pFile) ((pFile)->driver_priv) -+#else -+#define PRIVATE_DATA(pFile) ((pFile)->private_data) -+#endif -+ -+/* -+ * This is all module configuration stuff required by the linux kernel. -+ */ -+MODULE_SUPPORTED_DEVICE(DEVNAME); -+ -+#if defined(PVRSRV_NEED_PVR_DPF) -+#include <linux/moduleparam.h> -+extern IMG_UINT32 gPVRDebugLevel; -+module_param(gPVRDebugLevel, uint, 0644); -+MODULE_PARM_DESC(gPVRDebugLevel, "Sets the level of debug output (default 0x7)"); -+#endif /* defined(PVRSRV_NEED_PVR_DPF) */ -+ -+#if defined(CONFIG_ION_OMAP) -+#include <linux/ion.h> -+#include <linux/omap_ion.h> -+extern struct ion_device *omap_ion_device; -+struct ion_client *gpsIONClient; -+#endif /* defined(CONFIG_ION_OMAP) */ -+ -+/* PRQA S 3207 2 */ /* ignore 'not used' warning */ -+EXPORT_SYMBOL(PVRGetDisplayClassJTable); -+EXPORT_SYMBOL(PVRGetBufferClassJTable); -+ -+#if defined(PVR_LDM_DEVICE_CLASS) && !defined(SUPPORT_DRI_DRM) -+/* -+ * Device class used for /sys entries (and udev device node creation) -+ */ -+static struct class *psPvrClass; -+#endif -+ -+#if !defined(SUPPORT_DRI_DRM) -+/* -+ * This is the major number we use for all nodes in /dev. -+ */ -+static int AssignedMajorNumber; -+ -+/* -+ * These are the operations that will be associated with the device node -+ * we create. -+ * -+ * With gcc -W, specifying only the non-null members produces "missing -+ * initializer" warnings. -+*/ -+static int PVRSRVOpen(struct inode* pInode, struct file* pFile); -+static int PVRSRVRelease(struct inode* pInode, struct file* pFile); -+ -+static struct file_operations pvrsrv_fops = -+{ -+ .owner=THIS_MODULE, -+ .unlocked_ioctl = PVRSRV_BridgeDispatchKM, -+ .open=PVRSRVOpen, -+ .release=PVRSRVRelease, -+ .mmap=PVRMMap, -+}; -+#endif -+ -+PVRSRV_LINUX_MUTEX gPVRSRVLock; -+ -+/* PID of process being released */ -+IMG_UINT32 gui32ReleasePID; -+ -+#if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL) -+static IMG_UINT32 gPVRPowerLevel; -+#endif -+ -+static int PVRSRVIONClientCreate(void) -+{ -+#if defined(CONFIG_ION_OMAP) -+ gpsIONClient = ion_client_create(omap_ion_device, -+ 1 << OMAP_ION_HEAP_TYPE_TILER, -+ "pvr"); -+ if (IS_ERR_OR_NULL(gpsIONClient)) -+ { -+ int err; -+ -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRVDriverProbe: Couldn't create ion client")); -+ -+ err = PTR_ERR(gpsIONClient); -+ gpsIONClient = IMG_NULL; -+ -+ return err; -+ } -+#endif /* defined(CONFIG_ION_OMAP) */ -+ -+ return 0; -+} -+ -+static void PVRSRVIONClientDestroy(void) -+{ -+#if defined(CONFIG_ION_OMAP) -+ if (gpsIONClient != NULL) -+ { -+ ion_client_destroy(gpsIONClient); -+ gpsIONClient = IMG_NULL; -+ } -+#endif -+} -+ -+#if defined(PVR_LDM_MODULE) -+ -+#if defined(PVR_LDM_PLATFORM_MODULE) -+#define LDM_DEV struct platform_device -+#define LDM_DRV struct platform_driver -+#endif /*PVR_LDM_PLATFORM_MODULE */ -+ -+#if defined(PVR_LDM_PCI_MODULE) -+#define LDM_DEV struct pci_dev -+#define LDM_DRV struct pci_driver -+#endif /* PVR_LDM_PCI_MODULE */ -+/* -+ * This is the driver interface we support. -+ */ -+#if defined(PVR_LDM_PLATFORM_MODULE) -+static int PVRSRVDriverRemove(LDM_DEV *device); -+static int PVRSRVDriverProbe(LDM_DEV *device); -+#endif -+#if defined(PVR_LDM_PCI_MODULE) -+static void PVRSRVDriverRemove(LDM_DEV *device); -+static int PVRSRVDriverProbe(LDM_DEV *device, const struct pci_device_id *id); -+#endif -+static int PVRSRVDriverSuspend(LDM_DEV *device, pm_message_t state); -+static void PVRSRVDriverShutdown(LDM_DEV *device); -+static int PVRSRVDriverResume(LDM_DEV *device); -+ -+#if defined(PVR_LDM_PCI_MODULE) -+/* This structure is used by the Linux module code */ -+struct pci_device_id powervr_id_table[] __devinitdata = { -+ {PCI_DEVICE(SYS_SGX_DEV_VENDOR_ID, SYS_SGX_DEV_DEVICE_ID)}, -+#if defined (SYS_SGX_DEV1_DEVICE_ID) -+ {PCI_DEVICE(SYS_SGX_DEV_VENDOR_ID, SYS_SGX_DEV1_DEVICE_ID)}, -+#endif -+ {0} -+}; -+ -+MODULE_DEVICE_TABLE(pci, powervr_id_table); -+#endif -+ -+#if defined(PVR_USE_PRE_REGISTERED_PLATFORM_DEV) -+static struct platform_device_id powervr_id_table[] __devinitdata = { -+ {SYS_SGX_DEV_NAME, 0}, -+ {} -+}; -+#endif -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)) -+static const struct of_device_id omap_sgx_of_match[] = { -+ { -+ .compatible = "ti,sgx", -+ }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, omap_sgx_of_match); -+#endif -+ -+ -+static LDM_DRV powervr_driver = { -+#if defined(PVR_LDM_PLATFORM_MODULE) -+ .driver = { -+ .name = DRVNAME, -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)) -+ .of_match_table = of_match_ptr(omap_sgx_of_match), -+#endif -+ }, -+#endif -+#if defined(PVR_LDM_PCI_MODULE) -+ .name = DRVNAME, -+#endif -+#if defined(PVR_LDM_PCI_MODULE) || defined(PVR_USE_PRE_REGISTERED_PLATFORM_DEV) -+ .id_table = powervr_id_table, -+#endif -+ .probe = PVRSRVDriverProbe, -+#if defined(PVR_LDM_PLATFORM_MODULE) -+ .remove = PVRSRVDriverRemove, -+#endif -+#if defined(PVR_LDM_PCI_MODULE) -+ .remove = __devexit_p(PVRSRVDriverRemove), -+#endif -+ .suspend = PVRSRVDriverSuspend, -+ .resume = PVRSRVDriverResume, -+ .shutdown = PVRSRVDriverShutdown, -+}; -+ -+LDM_DEV *gpsPVRLDMDev; -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)) -+struct reset_control *rstc; -+bool already_deasserted = false; -+#endif -+ -+#if defined(MODULE) && defined(PVR_LDM_PLATFORM_MODULE) && \ -+ !defined(PVR_USE_PRE_REGISTERED_PLATFORM_DEV) -+#if !defined(PM_RUNTIME_SUPPORT) -+static void PVRSRVDeviceRelease(struct device unref__ *pDevice) -+{ -+} -+static struct platform_device powervr_device = { -+ .name = DEVNAME, -+ .id = -1, -+ .dev = { -+ .release = PVRSRVDeviceRelease -+ } -+}; -+#endif -+#endif -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVDriverProbe -+ -+ @Description -+ -+ See whether a given device is really one we can drive. The platform bus -+ handler has already established that we should be able to service this device -+ because of the name match. We probably don't need to do anything else. -+ -+ @input pDevice - the device for which a probe is requested -+ -+ @Return 0 for success or <0 for an error. -+ -+*****************************************************************************/ -+#if defined(PVR_LDM_PLATFORM_MODULE) -+static int PVRSRVDriverProbe(LDM_DEV *pDevice) -+#endif -+#if defined(PVR_LDM_PCI_MODULE) -+static int __devinit PVRSRVDriverProbe(LDM_DEV *pDevice, const struct pci_device_id *id) -+#endif -+{ -+ SYS_DATA *psSysData; -+ int ret; -+ PVR_TRACE(("PVRSRVDriverProbe(pDevice=%p)", pDevice)); -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)) -+ rstc = reset_control_get(&pDevice->dev, NULL); -+ -+ if (IS_ERR(rstc)) -+ { -+ dev_err(&pDevice->dev, "%s: error: reset_control_get\n", __func__); -+ return PTR_ERR(rstc); -+ } -+ -+ ret = reset_control_clear_reset(rstc); -+ -+ if (ret < 0) -+ { -+ dev_err(&pDevice->dev, "%s: error: reset_control_clear_reset\n", __func__); -+ return ret; -+ } -+ -+ ret = reset_control_deassert(rstc); -+ -+ if (ret == -EEXIST) -+ { -+ already_deasserted = true; -+ } -+ else if (ret < 0) -+ { -+ dev_err(&pDevice->dev, "%s: error: reset_control_deassert\n", __func__); -+ return ret; -+ } -+#endif -+ -+#if 0 /* INTEGRATION_POINT */ -+ /* Some systems require device-specific system initialisation. -+ * E.g. this lets the OS track a device's dependencies on various -+ * system hardware. -+ * -+ * Note: some systems use this to enable HW that SysAcquireData -+ * will depend on, therefore it must be called first. -+ */ -+ if (PerDeviceSysInitialise((IMG_PVOID)pDevice) != PVRSRV_OK) -+ { -+ return -EINVAL; -+ } -+#endif -+ /* SysInitialise only designed to be called once. -+ */ -+ psSysData = SysAcquireDataNoCheck(); -+ if (psSysData == IMG_NULL) -+ { -+ gpsPVRLDMDev = pDevice; -+ if (SysInitialise() != PVRSRV_OK) -+ { -+ return -ENODEV; -+ } -+ } -+ -+ return PVRSRVIONClientCreate(); -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVDriverRemove -+ -+ @Description -+ -+ This call is the opposite of the probe call: it is called when the device is -+ being removed from the driver's control. See the file $KERNELDIR/drivers/ -+ base/bus.c:device_release_driver() for the call to this function. -+ -+ This is the correct place to clean up anything our driver did while it was -+ asoociated with the device. -+ -+ @input pDevice - the device for which driver detachment is happening -+ -+ @Return 0 for success or <0 for an error. -+ -+*****************************************************************************/ -+#if defined (PVR_LDM_PLATFORM_MODULE) -+static int PVRSRVDriverRemove(LDM_DEV *pDevice) -+#endif -+#if defined(PVR_LDM_PCI_MODULE) -+static void __devexit PVRSRVDriverRemove(LDM_DEV *pDevice) -+#endif -+{ -+ SYS_DATA *psSysData; -+ -+ PVR_TRACE(("PVRSRVDriverRemove(pDevice=%p)", pDevice)); -+ -+ PVRSRVIONClientDestroy(); -+ -+ SysAcquireData(&psSysData); -+ -+#if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL) -+ if (gPVRPowerLevel != 0) -+ { -+ if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D0) == PVRSRV_OK) -+ { -+ gPVRPowerLevel = 0; -+ } -+ } -+#endif -+ (void) SysDeinitialise(psSysData); -+ -+ gpsPVRLDMDev = IMG_NULL; -+ -+#if 0 /* INTEGRATION_POINT */ -+ /* See previous integration point for details. */ -+ if (PerDeviceSysDeInitialise((IMG_PVOID)pDevice) != PVRSRV_OK) -+ { -+ return -EINVAL; -+ } -+#endif -+ -+#if defined (PVR_LDM_PLATFORM_MODULE) -+ return 0; -+#endif -+#if defined (PVR_LDM_PCI_MODULE) -+ return; -+#endif -+} -+#endif /* defined(PVR_LDM_MODULE) */ -+ -+ -+#if defined(PVR_LDM_MODULE) || defined(SUPPORT_DRI_DRM) -+static PVRSRV_LINUX_MUTEX gsPMMutex; -+static IMG_BOOL bDriverIsSuspended; -+static IMG_BOOL bDriverIsShutdown; -+#endif -+ -+#if defined(PVR_LDM_MODULE) || defined(PVR_DRI_DRM_PLATFORM_DEV) -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVDriverShutdown -+ -+ @Description -+ -+ Suspend device operation for system shutdown. This is called as part of the -+ system halt/reboot process. The driver is put into a quiescent state by -+ setting the power state to D3. -+ -+ @input pDevice - the device for which shutdown is requested -+ -+ @Return nothing -+ -+*****************************************************************************/ -+#if defined(SUPPORT_DRI_DRM) && !defined(PVR_DRI_DRM_PLATFORM_DEV) && \ -+ !defined(SUPPORT_DRI_DRM_PLUGIN) -+void PVRSRVDriverShutdown(struct drm_device *pDevice) -+#else -+PVR_MOD_STATIC void PVRSRVDriverShutdown(LDM_DEV *pDevice) -+#endif -+{ -+ PVR_TRACE(("PVRSRVDriverShutdown(pDevice=%p)", pDevice)); -+ -+ LinuxLockMutexNested(&gsPMMutex, PVRSRV_LOCK_CLASS_POWER); -+ -+ if (!bDriverIsShutdown && !bDriverIsSuspended) -+ { -+ /* -+ * Take the bridge mutex, and never release it, to stop -+ * processes trying to use the driver after it has been -+ * shutdown. -+ */ -+ LinuxLockMutexNested(&gPVRSRVLock, PVRSRV_LOCK_CLASS_BRIDGE); -+ -+ (void) PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D3); -+ } -+ -+ bDriverIsShutdown = IMG_TRUE; -+ -+ /* The bridge mutex is held on exit */ -+ LinuxUnLockMutex(&gsPMMutex); -+} -+ -+#endif /* defined(PVR_LDM_MODULE) || defined(PVR_DRI_DRM_PLATFORM_DEV) */ -+ -+ -+#if defined(PVR_LDM_MODULE) || defined(SUPPORT_DRI_DRM) -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVDriverSuspend -+ -+ @Description -+ -+ For 2.6 kernels: -+ Suspend device operation. We always get three calls to this regardless of -+ the state (D1-D3) chosen. The order is SUSPEND_DISABLE, SUSPEND_SAVE_STATE -+ then SUSPEND_POWER_DOWN. We take action as soon as we get the disable call, -+ the other states not being handled by us yet. -+ -+ For MontaVista 2.4 kernels: -+ This call gets made once only when someone does something like -+ -+ # echo -e -n "suspend powerdown 0" >/sys.devices/legacy/pvrsrv0/power -+ -+ The 3rd, numeric parameter (0) in the above has no relevence and is not -+ passed into us. The state parameter is always zero and the level parameter -+ is always SUSPEND_POWER_DOWN. Vive la difference! -+ -+ @input pDevice - the device for which resume is requested -+ -+ @Return 0 for success or <0 for an error. -+ -+*****************************************************************************/ -+#if defined(SUPPORT_DRI_DRM) && !defined(PVR_DRI_DRM_PLATFORM_DEV) && \ -+ !defined(SUPPORT_DRI_DRM_PLUGIN) -+#if defined(SUPPORT_DRM_MODESET) -+int PVRSRVDriverSuspend(struct pci_dev *pDevice, pm_message_t state) -+#else -+int PVRSRVDriverSuspend(struct drm_device *pDevice, pm_message_t state) -+#endif -+#else -+PVR_MOD_STATIC int PVRSRVDriverSuspend(LDM_DEV *pDevice, pm_message_t state) -+#endif -+{ -+ int res = 0; -+#if !(defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL) && !defined(SUPPORT_DRI_DRM)) -+ PVR_TRACE(( "PVRSRVDriverSuspend(pDevice=%p)", pDevice)); -+ -+ LinuxLockMutexNested(&gsPMMutex, PVRSRV_LOCK_CLASS_POWER); -+ -+ if (!bDriverIsSuspended && !bDriverIsShutdown) -+ { -+ LinuxLockMutexNested(&gPVRSRVLock, PVRSRV_LOCK_CLASS_BRIDGE); -+ -+ if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D3) == PVRSRV_OK) -+ { -+ /* The bridge mutex will be held until we resume */ -+ bDriverIsSuspended = IMG_TRUE; -+ } -+ else -+ { -+ LinuxUnLockMutex(&gPVRSRVLock); -+ res = -EINVAL; -+ } -+ } -+ -+ LinuxUnLockMutex(&gsPMMutex); -+#endif -+ return res; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVDriverResume -+ -+ @Description -+ -+ Resume device operation following a lull due to earlier suspension. It is -+ implicit we're returning to D0 (fully operational) state. We always get three -+ calls to this using level thus: RESUME_POWER_ON, RESUME_RESTORE_STATE then -+ RESUME_ENABLE. On 2.6 kernels We don't do anything until we get the enable -+ call; on the MontaVista set-up we only ever get the RESUME_POWER_ON call. -+ -+ @input pDevice - the device for which resume is requested -+ -+ @Return 0 for success or <0 for an error. -+ -+*****************************************************************************/ -+#if defined(SUPPORT_DRI_DRM) && !defined(PVR_DRI_DRM_PLATFORM_DEV) && \ -+ !defined(SUPPORT_DRI_DRM_PLUGIN) -+#if defined(SUPPORT_DRM_MODESET) -+int PVRSRVDriverResume(struct pci_dev *pDevice) -+#else -+int PVRSRVDriverResume(struct drm_device *pDevice) -+#endif -+#else -+PVR_MOD_STATIC int PVRSRVDriverResume(LDM_DEV *pDevice) -+#endif -+{ -+ int res = 0; -+#if !(defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL) && !defined(SUPPORT_DRI_DRM)) -+ PVR_TRACE(("PVRSRVDriverResume(pDevice=%p)", pDevice)); -+ -+ LinuxLockMutexNested(&gsPMMutex, PVRSRV_LOCK_CLASS_POWER); -+ -+ if (bDriverIsSuspended && !bDriverIsShutdown) -+ { -+ if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D0) == PVRSRV_OK) -+ { -+ bDriverIsSuspended = IMG_FALSE; -+ LinuxUnLockMutex(&gPVRSRVLock); -+ } -+ else -+ { -+ /* The bridge mutex is not released on failure */ -+ res = -EINVAL; -+ } -+ } -+ -+ LinuxUnLockMutex(&gsPMMutex); -+#endif -+ return res; -+} -+#endif /* defined(PVR_LDM_MODULE) || defined(SUPPORT_DRI_DRM) */ -+ -+ -+#if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL) && !defined(SUPPORT_DRI_DRM) -+/* -+ * If PVR_LDM_PCI_MODULE is defined (and PVR_MANUAL_POWER_CONTROL is *NOT* defined), -+ * the device can be suspended and resumed without suspending/resuming the -+ * system, by writing values into the power/state sysfs file for the device. -+ * To suspend: -+ * echo -n 2 > power/state -+ * To Resume: -+ * echo -n 0 > power/state -+ * -+ * The problem with this approach is that the device is usually left -+ * powered up; it is the responsibility of the bus driver to remove -+ * the power. -+ * -+ * Defining PVR_MANUAL_POWER_CONTROL is intended to make it easier to -+ * debug power management issues, especially when power is really removed -+ * from the device. It is easier to debug the driver if it is not being -+ * suspended/resumed with the rest of the system. -+ * -+ * When PVR_MANUAL_POWER_CONTROL is defined, the following proc entry is -+ * created: -+ * /proc/pvr/power_control -+ * The driver suspend/resume entry points defined below no longer suspend or -+ * resume the device. To suspend the device, type the following: -+ * echo 2 > /proc/pvr/power_control -+ * To resume the device, type: -+ * echo 0 > /proc/pvr/power_control -+ * -+ * The following example shows how to suspend/resume the device independently -+ * of the rest of the system. -+ * Suspend the device: -+ * echo 2 > /proc/pvr/power_control -+ * Suspend the system. Then you should be able to suspend and resume -+ * as normal. To resume the device type the following: -+ * echo 0 > /proc/pvr/power_control -+ */ -+ -+IMG_INT PVRProcSetPowerLevel(struct file *file, const IMG_CHAR *buffer, IMG_UINT32 count, IMG_VOID *data) -+{ -+ IMG_CHAR data_buffer[2]; -+ IMG_UINT32 PVRPowerLevel; -+ -+ if (count != sizeof(data_buffer)) -+ { -+ return -EINVAL; -+ } -+ else -+ { -+ if (copy_from_user(data_buffer, buffer, count)) -+ return -EINVAL; -+ if (data_buffer[count - 1] != '\n') -+ return -EINVAL; -+ PVRPowerLevel = data_buffer[0] - '0'; -+ if (PVRPowerLevel != gPVRPowerLevel) -+ { -+ if (PVRPowerLevel != 0) -+ { -+ if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D3) != PVRSRV_OK) -+ { -+ return -EINVAL; -+ } -+ } -+ else -+ { -+ if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D0) != PVRSRV_OK) -+ { -+ return -EINVAL; -+ } -+ } -+ -+ gPVRPowerLevel = PVRPowerLevel; -+ } -+ } -+ return (count); -+} -+ -+void ProcSeqShowPowerLevel(struct seq_file *sfile,void* el) -+{ -+ seq_printf(sfile, "%lu\n", gPVRPowerLevel); -+} -+ -+#endif -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVOpen -+ -+ @Description -+ -+ Release access the PVR services node - called when a file is closed, whether -+ at exit or using close(2) system call. -+ -+ @input pInode - the inode for the file being openeded -+ -+ @input pFile - the file handle data for the actual file being opened -+ -+ @Return 0 for success or <0 for an error. -+ -+*****************************************************************************/ -+#if defined(SUPPORT_DRI_DRM) -+int PVRSRVOpen(struct drm_device unref__ *dev, struct drm_file *pFile) -+#else -+static int PVRSRVOpen(struct inode unref__ * pInode, struct file *pFile) -+#endif -+{ -+ PVRSRV_FILE_PRIVATE_DATA *psPrivateData; -+ IMG_HANDLE hBlockAlloc; -+ int iRet = -ENOMEM; -+ PVRSRV_ERROR eError; -+ IMG_UINT32 ui32PID; -+#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT) -+ PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc; -+#endif -+ -+ LinuxLockMutexNested(&gPVRSRVLock, PVRSRV_LOCK_CLASS_BRIDGE); -+ -+ ui32PID = OSGetCurrentProcessIDKM(); -+ -+ if (PVRSRVProcessConnect(ui32PID, 0) != PVRSRV_OK) -+ goto err_unlock; -+ -+#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT) -+ psEnvPerProc = PVRSRVPerProcessPrivateData(ui32PID); -+ if (psEnvPerProc == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: No per-process private data", __FUNCTION__)); -+ goto err_unlock; -+ } -+#endif -+ -+ eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, -+ sizeof(PVRSRV_FILE_PRIVATE_DATA), -+ (IMG_PVOID *)&psPrivateData, -+ &hBlockAlloc, -+ "File Private Data"); -+ -+ if(eError != PVRSRV_OK) -+ goto err_unlock; -+ -+ psPrivateData->hKernelMemInfo = NULL; -+#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT) -+ psPrivateData->psDRMFile = pFile; -+ -+ list_add_tail(&psPrivateData->sDRMAuthListItem, &psEnvPerProc->sDRMAuthListHead); -+#endif -+ psPrivateData->ui32OpenPID = ui32PID; -+ psPrivateData->hBlockAlloc = hBlockAlloc; -+ PRIVATE_DATA(pFile) = psPrivateData; -+ iRet = 0; -+err_unlock: -+ LinuxUnLockMutex(&gPVRSRVLock); -+ return iRet; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRSRVRelease -+ -+ @Description -+ -+ Release access the PVR services node - called when a file is closed, whether -+ at exit or using close(2) system call. -+ -+ @input pInode - the inode for the file being released -+ -+ @input pFile - the file handle data for the actual file being released -+ -+ @Return 0 for success or <0 for an error. -+ -+*****************************************************************************/ -+#if defined(SUPPORT_DRI_DRM) -+void PVRSRVRelease(void *pvPrivData) -+#else -+static int PVRSRVRelease(struct inode unref__ * pInode, struct file *pFile) -+#endif -+{ -+ PVRSRV_FILE_PRIVATE_DATA *psPrivateData; -+ int err = 0; -+ -+ LinuxLockMutexNested(&gPVRSRVLock, PVRSRV_LOCK_CLASS_BRIDGE); -+ -+#if defined(SUPPORT_DRI_DRM) -+ psPrivateData = (PVRSRV_FILE_PRIVATE_DATA *)pvPrivData; -+#else -+ psPrivateData = PRIVATE_DATA(pFile); -+#endif -+ if (psPrivateData != IMG_NULL) -+ { -+#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT) -+ list_del(&psPrivateData->sDRMAuthListItem); -+#endif -+ -+ if(psPrivateData->hKernelMemInfo) -+ { -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; -+ -+ /* Look up the meminfo we just exported */ -+ if(PVRSRVLookupHandle(KERNEL_HANDLE_BASE, -+ (IMG_PVOID *)&psKernelMemInfo, -+ psPrivateData->hKernelMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO) != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: Failed to look up export handle", __FUNCTION__)); -+ err = -EFAULT; -+ goto err_unlock; -+ } -+ -+ /* Tell the XProc about the export if required */ -+ if (psKernelMemInfo->sShareMemWorkaround.bInUse) -+ { -+ BM_XProcIndexRelease(psKernelMemInfo->sShareMemWorkaround.ui32ShareIndex); -+ } -+ -+ /* This drops the psMemInfo refcount bumped on export */ -+ if(FreeMemCallBackCommon(psKernelMemInfo, 0, -+ PVRSRV_FREE_CALLBACK_ORIGIN_EXTERNAL) != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: FreeMemCallBackCommon failed", __FUNCTION__)); -+ err = -EFAULT; -+ goto err_unlock; -+ } -+ } -+ -+ /* Usually this is the same as OSGetCurrentProcessIDKM(), -+ * but not necessarily (e.g. fork(), child closes last..) -+ */ -+ gui32ReleasePID = psPrivateData->ui32OpenPID; -+ PVRSRVProcessDisconnect(psPrivateData->ui32OpenPID); -+ gui32ReleasePID = 0; -+ -+ OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, -+ sizeof(PVRSRV_FILE_PRIVATE_DATA), -+ psPrivateData, psPrivateData->hBlockAlloc); -+ -+#if !defined(SUPPORT_DRI_DRM) -+ PRIVATE_DATA(pFile) = IMG_NULL; /*nulling shared pointer*/ -+#endif -+ } -+ -+err_unlock: -+ LinuxUnLockMutex(&gPVRSRVLock); -+#if defined(SUPPORT_DRI_DRM) -+ return; -+#else -+ return err; -+#endif -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function PVRCore_Init -+ -+ @Description -+ -+ Insert the driver into the kernel. -+ -+ The device major number is allocated by the kernel dynamically. This means -+ that the device node (nominally /dev/pvrsrv) will need to be re-made at boot -+ time if the number changes between subsequent loads of the module. While the -+ number often stays constant between loads this is not guaranteed. The node -+ is made as root on the shell with: -+ -+ mknod /dev/pvrsrv c nnn 0 -+ -+ where nnn is the major number found in /proc/devices for DEVNAME and also -+ reported by the PVR_DPF() - look at the boot log using dmesg' to see this). -+ -+ Currently the auto-generated script /etc/init.d/rc.pvr handles creation of -+ the device. In other environments the device may be created either through -+ devfs or sysfs. -+ -+ Readable proc-filesystem entries under /proc/pvr are created with -+ CreateProcEntries(). These can be read at runtime to get information about -+ the device (eg. 'cat /proc/pvr/vm') -+ -+ __init places the function in a special memory section that the kernel frees -+ once the function has been run. Refer also to module_init() macro call below. -+ -+ @input none -+ -+ @Return none -+ -+*****************************************************************************/ -+#if defined(SUPPORT_DRI_DRM) -+int PVRCore_Init(void) -+#else -+static int __init PVRCore_Init(void) -+#endif -+{ -+ int error; -+#if !defined(PVR_LDM_MODULE) -+ PVRSRV_ERROR eError; -+#endif -+#if !defined(SUPPORT_DRI_DRM) && defined(PVR_LDM_DEVICE_CLASS) -+ struct device *psDev; -+#endif -+ -+ -+ -+#if !defined(SUPPORT_DRI_DRM) -+ /* -+ * Must come before attempting to print anything via Services. -+ * For DRM, the initialisation will already have been done. -+ */ -+ PVRDPFInit(); -+#endif -+ PVR_TRACE(("PVRCore_Init")); -+ -+#if defined(PVR_LDM_MODULE) || defined(SUPPORT_DRI_DRM) -+ LinuxInitMutex(&gsPMMutex); -+#endif -+ LinuxInitMutex(&gPVRSRVLock); -+ -+ if (CreateProcEntries ()) -+ { -+ error = -ENOMEM; -+ return error; -+ } -+ -+ if (PVROSFuncInit() != PVRSRV_OK) -+ { -+ error = -ENOMEM; -+ goto init_failed; -+ } -+ -+ PVRLinuxMUtilsInit(); -+ -+ if(LinuxMMInit() != PVRSRV_OK) -+ { -+ error = -ENOMEM; -+ goto init_failed; -+ } -+ -+ LinuxBridgeInit(); -+ -+ -+ PVRMMapInit(); -+ -+#if defined(PVR_LDM_MODULE) -+ -+#if defined(PVR_LDM_PLATFORM_MODULE) || defined(SUPPORT_DRI_DRM_PLUGIN) -+ if ((error = platform_driver_register(&powervr_driver)) != 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to register platform driver (%d)", error)); -+ -+ goto init_failed; -+ } -+ -+#if defined(MODULE) && !defined(PVR_USE_PRE_REGISTERED_PLATFORM_DEV) -+#if !defined(PM_RUNTIME_SUPPORT) -+ if ((error = platform_device_register(&powervr_device)) != 0) -+ { -+ platform_driver_unregister(&powervr_driver); -+ -+ PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to register platform device (%d)", error)); -+ -+ goto init_failed; -+ } -+#endif -+#endif -+#endif /* PVR_LDM_PLATFORM_MODULE */ -+ -+#if defined(PVR_LDM_PCI_MODULE) -+ if ((error = pci_register_driver(&powervr_driver)) != 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to register PCI driver (%d)", error)); -+ -+ goto init_failed; -+ } -+#endif /* PVR_LDM_PCI_MODULE */ -+#endif /* defined(PVR_LDM_MODULE) */ -+ -+#if !defined(PVR_LDM_MODULE) -+ /* -+ * Drivers using LDM, will call SysInitialise in the probe/attach code -+ */ -+ if ((eError = SysInitialise()) != PVRSRV_OK) -+ { -+ error = -ENODEV; -+#if defined(TCF_REV) && (TCF_REV == 110) -+ if(eError == PVRSRV_ERROR_NOT_SUPPORTED) -+ { -+ printk("\nAtlas wrapper (FPGA image) version mismatch"); -+ error = -ENODEV; -+ } -+#endif -+ goto init_failed; -+ } -+ -+ error = PVRSRVIONClientCreate(); -+ if (error != 0) -+ { -+ goto sys_deinit; -+ } -+#endif /* !defined(PVR_LDM_MODULE) */ -+ -+#if !defined(SUPPORT_DRI_DRM) -+ AssignedMajorNumber = register_chrdev(0, DEVNAME, &pvrsrv_fops); -+ -+ if (AssignedMajorNumber <= 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to get major number")); -+ -+ error = -EBUSY; -+ goto sys_deinit; -+ } -+ -+ PVR_TRACE(("PVRCore_Init: major device %d", AssignedMajorNumber)); -+ -+#if defined(PVR_LDM_DEVICE_CLASS) -+ /* -+ * This code (using GPL symbols) facilitates automatic device -+ * node creation on platforms with udev (or similar). -+ */ -+ psPvrClass = class_create(THIS_MODULE, "pvr"); -+ -+ if (IS_ERR(psPvrClass)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to create class (%ld)", PTR_ERR(psPvrClass))); -+ error = -EBUSY; -+ goto unregister_device; -+ } -+ -+ psDev = device_create(psPvrClass, NULL, MKDEV(AssignedMajorNumber, 0), -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)) -+ NULL, -+#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)) */ -+ DEVNAME); -+ if (IS_ERR(psDev)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to create device (%ld)", PTR_ERR(psDev))); -+ error = -EBUSY; -+ goto destroy_class; -+ } -+#endif /* defined(PVR_LDM_DEVICE_CLASS) */ -+#endif /* !defined(SUPPORT_DRI_DRM) */ -+ -+#if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) -+ PVRSyncDeviceInit(); -+#endif -+ return 0; -+ -+#if !defined(SUPPORT_DRI_DRM) -+#if defined(PVR_LDM_DEVICE_CLASS) -+destroy_class: -+ class_destroy(psPvrClass); -+unregister_device: -+ unregister_chrdev((IMG_UINT)AssignedMajorNumber, DEVNAME); -+#endif -+#endif -+#if !defined(PVR_LDM_MODULE) || !defined(SUPPORT_DRI_DRM) -+sys_deinit: -+#endif -+#if defined(PVR_LDM_MODULE) -+#if defined(PVR_LDM_PCI_MODULE) -+ pci_unregister_driver(&powervr_driver); -+#endif -+ -+#if defined (PVR_LDM_PLATFORM_MODULE) -+#if defined(MODULE) && !defined(PVR_USE_PRE_REGISTERED_PLATFORM_DEV) -+#if !defined(PM_RUNTIME_SUPPORT) -+ platform_device_unregister(&powervr_device); -+#endif -+#endif -+ platform_driver_unregister(&powervr_driver); -+#endif -+ -+#else /* defined(PVR_LDM_MODULE) */ -+ PVRSRVIONClientDestroy(); -+ -+ /* LDM drivers call SysDeinitialise during PVRSRVDriverRemove */ -+ { -+ SYS_DATA *psSysData; -+ -+ psSysData = SysAcquireDataNoCheck(); -+ if (psSysData != IMG_NULL) -+ { -+ (void) SysDeinitialise(psSysData); -+ } -+ } -+#endif /* defined(PVR_LDM_MODULE) */ -+init_failed: -+ PVRMMapCleanup(); -+ LinuxMMCleanup(); -+ LinuxBridgeDeInit(); -+ PVROSFuncDeInit(); -+ RemoveProcEntries(); -+ -+ return error; -+ -+} /*PVRCore_Init*/ -+ -+ -+/*! -+***************************************************************************** -+ -+ @Function PVRCore_Cleanup -+ -+ @Description -+ -+ Remove the driver from the kernel. -+ -+ There's no way we can get out of being unloaded other than panicking; we -+ just do everything and plough on regardless of error. -+ -+ __exit places the function in a special memory section that the kernel frees -+ once the function has been run. Refer also to module_exit() macro call below. -+ -+ Note that the for LDM on MontaVista kernels, the positioning of the driver -+ de-registration is the opposite way around than would be suggested by the -+ registration case or the 2,6 kernel case. This is the correct way to do it -+ and the kernel panics if you change it. You have been warned. -+ -+ @input none -+ -+ @Return none -+ -+*****************************************************************************/ -+#if defined(SUPPORT_DRI_DRM) -+void PVRCore_Cleanup(void) -+#else -+static void __exit PVRCore_Cleanup(void) -+#endif -+{ -+#if !defined(PVR_LDM_MODULE) -+ SYS_DATA *psSysData; -+#endif -+ PVR_TRACE(("PVRCore_Cleanup")); -+ -+#if !defined(PVR_LDM_MODULE) -+ SysAcquireData(&psSysData); -+#endif -+ -+#if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) -+ PVRSyncDeviceDeInit(); -+#endif -+ -+#if !defined(SUPPORT_DRI_DRM) -+ -+#if defined(PVR_LDM_DEVICE_CLASS) -+ device_destroy(psPvrClass, MKDEV(AssignedMajorNumber, 0)); -+ class_destroy(psPvrClass); -+#endif -+ -+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22)) -+ if ( -+#endif /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22)) */ -+ unregister_chrdev((IMG_UINT)AssignedMajorNumber, DEVNAME) -+#if !(LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22)) -+ ; -+#else /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22)) */ -+ ) -+ { -+ PVR_DPF((PVR_DBG_ERROR," can't unregister device major %d", AssignedMajorNumber)); -+ } -+#endif /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22)) */ -+#endif /* !defined(SUPPORT_DRI_DRM) */ -+ -+#if defined(PVR_LDM_MODULE) -+ -+#if defined(PVR_LDM_PCI_MODULE) -+ pci_unregister_driver(&powervr_driver); -+#endif -+ -+#if defined (PVR_LDM_PLATFORM_MODULE) -+#if defined(MODULE) && !defined(PVR_USE_PRE_REGISTERED_PLATFORM_DEV) -+#if !defined(PM_RUNTIME_SUPPORT) -+ platform_device_unregister(&powervr_device); -+#endif -+#endif -+ platform_driver_unregister(&powervr_driver); -+#endif -+ -+#else /* defined(PVR_LDM_MODULE) */ -+#if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL) -+ if (gPVRPowerLevel != 0) -+ { -+ if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D0) == PVRSRV_OK) -+ { -+ gPVRPowerLevel = 0; -+ } -+ } -+#endif -+ PVRSRVIONClientDestroy(); -+ -+ /* LDM drivers call SysDeinitialise during PVRSRVDriverRemove */ -+ (void) SysDeinitialise(psSysData); -+#endif /* defined(PVR_LDM_MODULE) */ -+ -+ PVRMMapCleanup(); -+ -+ LinuxMMCleanup(); -+ -+ LinuxBridgeDeInit(); -+ -+ PVROSFuncDeInit(); -+ -+ RemoveProcEntries(); -+ -+ PVR_TRACE(("PVRCore_Cleanup: unloading")); -+} -+ -+/* -+ * These macro calls define the initialisation and removal functions of the -+ * driver. Although they are prefixed `module_', they apply when compiling -+ * statically as well; in both cases they define the function the kernel will -+ * run to start/stop the driver. -+*/ -+#if !defined(SUPPORT_DRI_DRM) -+module_init(PVRCore_Init); -+module_exit(PVRCore_Cleanup); -+#endif -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/mutex.c b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/mutex.c -new file mode 100644 -index 0000000..aaa81b9 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/mutex.c -@@ -0,0 +1,162 @@ -+/*************************************************************************/ /*! -+@Title Linux mutex interface -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#include <linux/version.h> -+#include <linux/errno.h> -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)) -+#include <linux/mutex.h> -+#else -+#include <asm/semaphore.h> -+#endif -+#include <linux/module.h> -+ -+#include <img_defs.h> -+#include <services.h> -+ -+#include "mutex.h" -+ -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)) -+ -+IMG_VOID LinuxInitMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex) -+{ -+ mutex_init(psPVRSRVMutex); -+} -+ -+IMG_VOID LinuxLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex) -+{ -+ mutex_lock(psPVRSRVMutex); -+} -+ -+IMG_VOID LinuxLockMutexNested(PVRSRV_LINUX_MUTEX *psPVRSRVMutex, unsigned int uiLockClass) -+{ -+ mutex_lock_nested(psPVRSRVMutex, uiLockClass); -+} -+ -+PVRSRV_ERROR LinuxLockMutexInterruptible(PVRSRV_LINUX_MUTEX *psPVRSRVMutex) -+{ -+ if(mutex_lock_interruptible(psPVRSRVMutex) == -EINTR) -+ { -+ return PVRSRV_ERROR_MUTEX_INTERRUPTIBLE_ERROR; -+ } -+ else -+ { -+ return PVRSRV_OK; -+ } -+} -+ -+IMG_INT32 LinuxTryLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex) -+{ -+ return mutex_trylock(psPVRSRVMutex); -+} -+ -+IMG_VOID LinuxUnLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex) -+{ -+ mutex_unlock(psPVRSRVMutex); -+} -+ -+IMG_BOOL LinuxIsLockedMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex) -+{ -+ return (mutex_is_locked(psPVRSRVMutex)) ? IMG_TRUE : IMG_FALSE; -+} -+ -+ -+#else /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)) */ -+ -+ -+IMG_VOID LinuxInitMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex) -+{ -+ init_MUTEX(&psPVRSRVMutex->sSemaphore); -+ atomic_set(&psPVRSRVMutex->Count, 0); -+} -+ -+IMG_VOID LinuxLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex) -+{ -+ down(&psPVRSRVMutex->sSemaphore); -+ atomic_dec(&psPVRSRVMutex->Count); -+} -+ -+IMG_VOID LinuxLockMutexNested(PVRSRV_LINUX_MUTEX *psPVRSRVMutex, unsigned int uiLockClass) -+{ -+ LinuxLockMutex(psPVRSRVMutex); -+} -+ -+PVRSRV_ERROR LinuxLockMutexInterruptible(PVRSRV_LINUX_MUTEX *psPVRSRVMutex) -+{ -+ if(down_interruptible(&psPVRSRVMutex->sSemaphore) == -EINTR) -+ { -+ /* The process was sent a signal while waiting for the semaphore -+ * (e.g. a kill signal from userspace) -+ */ -+ return PVRSRV_ERROR_MUTEX_INTERRUPTIBLE_ERROR; -+ }else{ -+ atomic_dec(&psPVRSRVMutex->Count); -+ return PVRSRV_OK; -+ } -+} -+ -+IMG_INT32 LinuxTryLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex) -+{ -+ IMG_INT32 Status = down_trylock(&psPVRSRVMutex->sSemaphore); -+ if(Status == 0) -+ { -+ atomic_dec(&psPVRSRVMutex->Count); -+ } -+ -+ return Status == 0; -+} -+ -+IMG_VOID LinuxUnLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex) -+{ -+ atomic_inc(&psPVRSRVMutex->Count); -+ up(&psPVRSRVMutex->sSemaphore); -+} -+ -+IMG_BOOL LinuxIsLockedMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex) -+{ -+ IMG_INT32 iCount; -+ -+ iCount = atomic_read(&psPVRSRVMutex->Count); -+ -+ return (IMG_BOOL)iCount; -+} -+ -+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)) */ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/mutex.h b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/mutex.h -new file mode 100644 -index 0000000..f0f462d ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/mutex.h -@@ -0,0 +1,99 @@ -+/*************************************************************************/ /*! -+@Title Linux mutex interface -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+ -+#ifndef __INCLUDED_LINUX_MUTEX_H_ -+#define __INCLUDED_LINUX_MUTEX_H_ -+ -+#include <linux/version.h> -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)) -+#include <linux/mutex.h> -+#else -+#include <asm/semaphore.h> -+#endif -+ -+ -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)) -+ -+typedef struct mutex PVRSRV_LINUX_MUTEX; -+ -+#else /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)) */ -+ -+ -+typedef struct { -+ struct semaphore sSemaphore; -+ /* since Linux's struct semaphore is intended to be -+ * opaque we don't poke inside for the count and -+ * instead we track it outselves. (So we can implement -+ * LinuxIsLockedMutex) -+ */ -+ atomic_t Count; -+}PVRSRV_LINUX_MUTEX; -+ -+#endif -+ -+enum PVRSRV_MUTEX_LOCK_CLASS -+{ -+ PVRSRV_LOCK_CLASS_POWER, -+ PVRSRV_LOCK_CLASS_BRIDGE, -+ PVRSRV_LOCK_CLASS_MMAP, -+ PVRSRV_LOCK_CLASS_MM_DEBUG, -+ PVRSRV_LOCK_CLASS_PVR_DEBUG, -+}; -+ -+extern IMG_VOID LinuxInitMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex); -+ -+extern IMG_VOID LinuxLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex); -+ -+extern IMG_VOID LinuxLockMutexNested(PVRSRV_LINUX_MUTEX *psPVRSRVMutex, unsigned int uiLockClass); -+ -+extern PVRSRV_ERROR LinuxLockMutexInterruptible(PVRSRV_LINUX_MUTEX *psPVRSRVMutex); -+ -+extern IMG_INT32 LinuxTryLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex); -+ -+extern IMG_VOID LinuxUnLockMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex); -+ -+extern IMG_BOOL LinuxIsLockedMutex(PVRSRV_LINUX_MUTEX *psPVRSRVMutex); -+ -+ -+#endif /* __INCLUDED_LINUX_MUTEX_H_ */ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/mutils.c b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/mutils.c -new file mode 100644 -index 0000000..4fe7dfa ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/mutils.c -@@ -0,0 +1,165 @@ -+/*************************************************************************/ /*! -+@Title Linux memory interface support functions -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#include <linux/version.h> -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)) -+#ifndef AUTOCONF_INCLUDED -+#include <linux/config.h> -+#endif -+#endif -+ -+#include <linux/spinlock.h> -+#include <linux/mm.h> -+#include <asm/page.h> -+#include <asm/pgtable.h> -+ -+#include "img_defs.h" -+#include "pvr_debug.h" -+#include "mutils.h" -+ -+#if defined(SUPPORT_LINUX_X86_PAT) -+#define PAT_LINUX_X86_WC 1 -+ -+#define PAT_X86_ENTRY_BITS 8 -+ -+#define PAT_X86_BIT_PWT 1U -+#define PAT_X86_BIT_PCD 2U -+#define PAT_X86_BIT_PAT 4U -+#define PAT_X86_BIT_MASK (PAT_X86_BIT_PAT | PAT_X86_BIT_PCD | PAT_X86_BIT_PWT) -+ -+static IMG_BOOL g_write_combining_available = IMG_FALSE; -+ -+#define PROT_TO_PAT_INDEX(v, B) ((v & _PAGE_ ## B) ? PAT_X86_BIT_ ## B : 0) -+ -+static inline IMG_UINT -+pvr_pat_index(pgprotval_t prot_val) -+{ -+ IMG_UINT ret = 0; -+ pgprotval_t val = prot_val & _PAGE_CACHE_MASK; -+ -+ ret |= PROT_TO_PAT_INDEX(val, PAT); -+ ret |= PROT_TO_PAT_INDEX(val, PCD); -+ ret |= PROT_TO_PAT_INDEX(val, PWT); -+ -+ return ret; -+} -+ -+static inline IMG_UINT -+pvr_pat_entry(u64 pat, IMG_UINT index) -+{ -+ return (IMG_UINT)(pat >> (index * PAT_X86_ENTRY_BITS)) & PAT_X86_BIT_MASK; -+} -+ -+static IMG_VOID -+PVRLinuxX86PATProbe(IMG_VOID) -+{ -+ /* -+ * cpu_has_pat indicates whether PAT support is available on the CPU, -+ * but doesn't indicate if it has been enabled. -+ */ -+ if (cpu_has_pat) /* PRQA S 3335 */ /* ignore 'no function declared' */ -+ { -+ u64 pat; -+ IMG_UINT pat_index; -+ IMG_UINT pat_entry; -+ -+ PVR_TRACE(("%s: PAT available", __FUNCTION__)); -+ /* -+ * There is no Linux API for finding out if write combining -+ * is avaialable through the PAT, so we take the direct -+ * approach, and see if the PAT MSR contains a write combining -+ * entry. -+ */ -+ rdmsrl(MSR_IA32_CR_PAT, pat); -+ PVR_TRACE(("%s: Top 32 bits of PAT: 0x%.8x", __FUNCTION__, (IMG_UINT)(pat >> 32))); -+ PVR_TRACE(("%s: Bottom 32 bits of PAT: 0x%.8x", __FUNCTION__, (IMG_UINT)(pat))); -+ -+ pat_index = pvr_pat_index(_PAGE_CACHE_WC); -+ PVR_TRACE(("%s: PAT index for write combining: %u", __FUNCTION__, pat_index)); -+ -+ pat_entry = pvr_pat_entry(pat, pat_index); -+ PVR_TRACE(("%s: PAT entry for write combining: 0x%.2x (should be 0x%.2x)", __FUNCTION__, pat_entry, PAT_LINUX_X86_WC)); -+ -+#if defined(SUPPORT_LINUX_X86_WRITECOMBINE) -+ g_write_combining_available = (IMG_BOOL)(pat_entry == PAT_LINUX_X86_WC); -+#endif -+ } -+#if defined(DEBUG) -+#if defined(SUPPORT_LINUX_X86_WRITECOMBINE) -+ if (g_write_combining_available) -+ { -+ PVR_TRACE(("%s: Write combining available via PAT", __FUNCTION__)); -+ } -+ else -+ { -+ PVR_TRACE(("%s: Write combining not available", __FUNCTION__)); -+ } -+#else /* defined(SUPPORT_LINUX_X86_WRITECOMBINE) */ -+ PVR_TRACE(("%s: Write combining disabled in driver build", __FUNCTION__)); -+#endif /* defined(SUPPORT_LINUX_X86_WRITECOMBINE) */ -+#endif /* DEBUG */ -+} -+ -+pgprot_t -+pvr_pgprot_writecombine(pgprot_t prot) -+{ -+ /* -+ * It would be worth checking from time to time to see if a -+ * pgprot_writecombine function (or similar) is introduced on Linux for -+ * x86 processors. If so, this function, and PVRLinuxX86PATProbe can be -+ * removed, and a macro used to select between pgprot_writecombine and -+ * pgprot_noncached, dpending on the value for of -+ * SUPPORT_LINUX_X86_WRITECOMBINE. -+ */ -+ /* PRQA S 0481,0482 2 */ /* scalar expressions */ -+ return (g_write_combining_available) ? -+ __pgprot((pgprot_val(prot) & ~_PAGE_CACHE_MASK) | _PAGE_CACHE_WC) : pgprot_noncached(prot); -+} -+#endif /* defined(SUPPORT_LINUX_X86_PAT) */ -+ -+IMG_VOID -+PVRLinuxMUtilsInit(IMG_VOID) -+{ -+#if defined(SUPPORT_LINUX_X86_PAT) -+ PVRLinuxX86PATProbe(); -+#endif -+} -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/mutils.h b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/mutils.h -new file mode 100644 -index 0000000..b8848d7 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/mutils.h -@@ -0,0 +1,118 @@ -+/*************************************************************************/ /*! -+@Title Memory management support utils -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Declares various memory management support functions -+ for Linux. -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+#ifndef __IMG_LINUX_MUTILS_H__ -+#define __IMG_LINUX_MUTILS_H__ -+ -+#include <linux/version.h> -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)) -+#ifndef AUTOCONF_INCLUDED -+#include <linux/config.h> -+#endif -+#endif -+ -+#if !(defined(__i386__) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26))) -+#if defined(SUPPORT_LINUX_X86_PAT) -+#undef SUPPORT_LINUX_X86_PAT -+#endif -+#endif -+ -+#if defined(SUPPORT_LINUX_X86_PAT) -+ pgprot_t pvr_pgprot_writecombine(pgprot_t prot); -+ #define PGPROT_WC(pv) pvr_pgprot_writecombine(pv) -+#else -+ #if defined(__arm__) || defined(__sh__) -+ #define PGPROT_WC(pv) pgprot_writecombine(pv) -+ #else -+ #if defined(__i386__) || defined(__x86_64) || defined(__mips__) -+ #define PGPROT_WC(pv) pgprot_noncached(pv) -+ #else -+ #define PGPROT_WC(pv) pgprot_noncached(pv) -+ #error Unsupported architecture! -+ #endif -+ #endif -+#endif -+ -+#define PGPROT_UC(pv) pgprot_noncached(pv) -+ -+#if defined(__i386__) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)) -+ #define IOREMAP(pa, bytes) ioremap_cache(pa, bytes) -+#else -+ #if defined(__arm__) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) -+ #define IOREMAP(pa, bytes) ioremap_cached(pa, bytes) -+ #else -+ #define IOREMAP(pa, bytes) ioremap(pa, bytes) -+ #endif -+#endif -+ -+#if defined(SUPPORT_LINUX_X86_PAT) -+ #if defined(SUPPORT_LINUX_X86_WRITECOMBINE) -+ #define IOREMAP_WC(pa, bytes) ioremap_wc(pa, bytes) -+ #else -+ #define IOREMAP_WC(pa, bytes) ioremap_nocache(pa, bytes) -+ #endif -+#else -+ #if defined(__arm__) -+ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)) -+ #define IOREMAP_WC(pa, bytes) ioremap_wc(pa, bytes) -+ #else -+ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)) -+ #define IOREMAP_WC(pa, bytes) ioremap_nocache(pa, bytes) -+ #else -+ #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) || (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17)) -+ #define IOREMAP_WC(pa, bytes) __ioremap(pa, bytes, L_PTE_BUFFERABLE) -+ #else -+ #define IOREMAP_WC(pa, bytes) __ioremap(pa, bytes, , L_PTE_BUFFERABLE, 1) -+ #endif -+ #endif -+ #endif -+ #else -+ #define IOREMAP_WC(pa, bytes) ioremap_nocache(pa, bytes) -+ #endif -+#endif -+ -+#define IOREMAP_UC(pa, bytes) ioremap_nocache(pa, bytes) -+ -+IMG_VOID PVRLinuxMUtilsInit(IMG_VOID); -+ -+#endif /* __IMG_LINUX_MUTILS_H__ */ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/osfunc.c b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/osfunc.c -new file mode 100644 -index 0000000..40ce379 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/osfunc.c -@@ -0,0 +1,4630 @@ -+/*************************************************************************/ /*! -+@Title Environment related functions -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#include <linux/version.h> -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)) -+#ifndef AUTOCONF_INCLUDED -+#include <linux/config.h> -+#endif -+#endif -+ -+#include <asm/io.h> -+#include <asm/page.h> -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0)) -+#include <asm/system.h> -+#endif -+#include <asm/cacheflush.h> -+#include <linux/mm.h> -+#include <linux/pagemap.h> -+#include <linux/hugetlb.h> -+#include <linux/slab.h> -+#include <linux/vmalloc.h> -+#include <linux/delay.h> -+#include <linux/pci.h> -+ -+#include <linux/string.h> -+#include <linux/sched.h> -+#include <linux/interrupt.h> -+#include <asm/hardirq.h> -+#include <linux/timer.h> -+#include <linux/capability.h> -+#include <asm/uaccess.h> -+#include <linux/spinlock.h> -+#if defined(PVR_LINUX_MISR_USING_WORKQUEUE) || \ -+ defined(PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE) || \ -+ defined(PVR_LINUX_TIMERS_USING_WORKQUEUES) || \ -+ defined(PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE) || \ -+ defined(PVR_LINUX_USING_WORKQUEUES) -+#include <linux/workqueue.h> -+#endif -+ -+#include "img_types.h" -+#include "services_headers.h" -+#include "mm.h" -+#include "pvrmmap.h" -+#include "mmap.h" -+#include "env_data.h" -+#include "proc.h" -+#include "mutex.h" -+#include "event.h" -+#include "linkage.h" -+#include "pvr_uaccess.h" -+#include "lock.h" -+#if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) -+#include "pvr_sync.h" -+#endif -+ -+#if defined (SUPPORT_ION) -+#include "ion.h" -+#endif -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)) -+#define ON_EACH_CPU(func, info, wait) on_each_cpu(func, info, wait) -+#else -+#define ON_EACH_CPU(func, info, wait) on_each_cpu(func, info, 0, wait) -+#endif -+ -+//#if defined(PVR_LINUX_USING_WORKQUEUES) && !defined(CONFIG_PREEMPT) -+/* -+ * Services spins at certain points waiting for events (e.g. swap -+ * chain destrucion). If those events rely on workqueues running, -+ * it needs to be possible to preempt the waiting thread. -+ * Removing the need for CONFIG_PREEMPT will require adding preemption -+ * points at various points in Services. -+ */ -+//#error "A preemptible Linux kernel is required when using workqueues" -+//#endif -+ -+#if defined(EMULATOR) -+#define EVENT_OBJECT_TIMEOUT_MS (2000) -+#else -+#define EVENT_OBJECT_TIMEOUT_MS (100) -+#endif /* EMULATOR */ -+ -+#if !defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -+PVRSRV_ERROR OSAllocMem_Impl(IMG_UINT32 ui32Flags, IMG_SIZE_T uiSize, IMG_PVOID *ppvCpuVAddr, IMG_HANDLE *phBlockAlloc) -+#else -+PVRSRV_ERROR OSAllocMem_Impl(IMG_UINT32 ui32Flags, IMG_SIZE_T uiSize, IMG_PVOID *ppvCpuVAddr, IMG_HANDLE *phBlockAlloc, IMG_CHAR *pszFilename, IMG_UINT32 ui32Line) -+#endif -+{ -+ PVR_UNREFERENCED_PARAMETER(ui32Flags); -+ PVR_UNREFERENCED_PARAMETER(phBlockAlloc); -+ -+ if (uiSize > PAGE_SIZE) -+ { -+ /* Try to allocate the memory using vmalloc */ -+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -+ *ppvCpuVAddr = _VMallocWrapper(uiSize, PVRSRV_HAP_CACHED, pszFilename, ui32Line); -+#else -+ *ppvCpuVAddr = VMallocWrapper(uiSize, PVRSRV_HAP_CACHED); -+#endif -+ if (*ppvCpuVAddr) -+ { -+ return PVRSRV_OK; -+ } -+ } -+ -+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -+ *ppvCpuVAddr = _KMallocWrapper(uiSize, GFP_KERNEL | __GFP_NOWARN, pszFilename, ui32Line); -+#else -+ *ppvCpuVAddr = KMallocWrapper(uiSize, GFP_KERNEL | __GFP_NOWARN); -+#endif -+ if (!*ppvCpuVAddr) -+ { -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ -+ return PVRSRV_OK; -+} -+ -+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,24)) -+ -+static inline int is_vmalloc_addr(const void *pvCpuVAddr) -+{ -+ unsigned long lAddr = (unsigned long)pvCpuVAddr; -+ return lAddr >= VMALLOC_START && lAddr < VMALLOC_END; -+} -+ -+#endif /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,24)) */ -+ -+#if !defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -+PVRSRV_ERROR OSFreeMem_Impl(IMG_UINT32 ui32Flags, IMG_SIZE_T uiSize, IMG_PVOID pvCpuVAddr, IMG_HANDLE hBlockAlloc) -+#else -+PVRSRV_ERROR OSFreeMem_Impl(IMG_UINT32 ui32Flags, IMG_SIZE_T uiSize, IMG_PVOID pvCpuVAddr, IMG_HANDLE hBlockAlloc, IMG_CHAR *pszFilename, IMG_UINT32 ui32Line) -+#endif -+{ -+ PVR_UNREFERENCED_PARAMETER(ui32Flags); -+ PVR_UNREFERENCED_PARAMETER(uiSize); -+ PVR_UNREFERENCED_PARAMETER(hBlockAlloc); -+ -+ if (is_vmalloc_addr(pvCpuVAddr)) -+ { -+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -+ _VFreeWrapper(pvCpuVAddr, pszFilename, ui32Line); -+#else -+ VFreeWrapper(pvCpuVAddr); -+#endif -+ } -+ else -+ { -+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -+ _KFreeWrapper(pvCpuVAddr, pszFilename, ui32Line); -+#else -+ KFreeWrapper(pvCpuVAddr); -+#endif -+ } -+ -+ return PVRSRV_OK; -+} -+ -+ -+PVRSRV_ERROR -+OSAllocPages_Impl(IMG_UINT32 ui32AllocFlags, -+ IMG_SIZE_T uiSize, -+ IMG_UINT32 ui32PageSize, -+ IMG_PVOID pvPrivData, -+ IMG_UINT32 ui32PrivDataLength, -+ IMG_HANDLE hBMHandle, -+ IMG_VOID **ppvCpuVAddr, -+ IMG_HANDLE *phOSMemHandle) -+{ -+ LinuxMemArea *psLinuxMemArea; -+ -+ PVR_UNREFERENCED_PARAMETER(ui32PageSize); -+ -+#if 0 -+ /* For debug: force all OSAllocPages allocations to have a kernel -+ * virtual address */ -+ if(ui32AllocFlags & PVRSRV_HAP_SINGLE_PROCESS) -+ { -+ ui32AllocFlags &= ~PVRSRV_HAP_SINGLE_PROCESS; -+ ui32AllocFlags |= PVRSRV_HAP_MULTI_PROCESS; -+ } -+#endif -+ -+ if(ui32AllocFlags & PVRSRV_MEM_ION) -+ { -+ /* We'll only see HAP_SINGLE_PROCESS with MEM_ION */ -+ BUG_ON((ui32AllocFlags & PVRSRV_HAP_MAPTYPE_MASK) != PVRSRV_HAP_SINGLE_PROCESS); -+ -+ psLinuxMemArea = NewIONLinuxMemArea(uiSize, ui32AllocFlags, -+ pvPrivData, ui32PrivDataLength); -+ if(!psLinuxMemArea) -+ { -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ -+ PVRMMapRegisterArea(psLinuxMemArea); -+ goto ExitSkipSwitch; -+ } -+ -+ switch(ui32AllocFlags & PVRSRV_HAP_MAPTYPE_MASK) -+ { -+ case PVRSRV_HAP_KERNEL_ONLY: -+ { -+ psLinuxMemArea = NewVMallocLinuxMemArea(uiSize, ui32AllocFlags); -+ if(!psLinuxMemArea) -+ { -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ break; -+ } -+ case PVRSRV_HAP_SINGLE_PROCESS: -+ { -+ /* Currently PVRSRV_HAP_SINGLE_PROCESS implies that we dont need a -+ * kernel virtual mapping, but will need a user space virtual mapping */ -+ -+ psLinuxMemArea = NewAllocPagesLinuxMemArea(uiSize, ui32AllocFlags); -+ if(!psLinuxMemArea) -+ { -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ PVRMMapRegisterArea(psLinuxMemArea); -+ break; -+ } -+ -+ case PVRSRV_HAP_MULTI_PROCESS: -+ { -+ /* Currently PVRSRV_HAP_MULTI_PROCESS implies that we need a kernel -+ * virtual mapping and potentially multiple user space virtual -+ * mappings: Note: these eat into our limited kernel virtual -+ * address space. */ -+ -+#if defined(VIVT_CACHE) || defined(__sh__) -+ /* ARM9 caches are tagged with virtual pages, not physical. As we are going to -+ * share this memory in different address spaces, we don't want it to be cached. -+ * ARM11 has physical tagging, so we can cache this memory without fear of virtual -+ * address aliasing in the TLB, as long as the kernel supports cache colouring for -+ * VIPT architectures. */ -+ ui32AllocFlags &= ~PVRSRV_HAP_CACHED; -+#endif -+ psLinuxMemArea = NewVMallocLinuxMemArea(uiSize, ui32AllocFlags); -+ if(!psLinuxMemArea) -+ { -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ PVRMMapRegisterArea(psLinuxMemArea); -+ break; -+ } -+ default: -+ PVR_DPF((PVR_DBG_ERROR, "OSAllocPages: invalid flags 0x%x\n", ui32AllocFlags)); -+ *ppvCpuVAddr = NULL; -+ *phOSMemHandle = (IMG_HANDLE)0; -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ /* -+ In case of sparse mapping we need to handle back to the BM as it -+ knows the mapping info -+ */ -+ if (ui32AllocFlags & PVRSRV_MEM_SPARSE) -+ { -+ psLinuxMemArea->hBMHandle = hBMHandle; -+ } -+ -+ExitSkipSwitch: -+ *ppvCpuVAddr = LinuxMemAreaToCpuVAddr(psLinuxMemArea); -+ *phOSMemHandle = psLinuxMemArea; -+ -+ LinuxMemAreaRegister(psLinuxMemArea); -+ -+ return PVRSRV_OK; -+} -+ -+ -+PVRSRV_ERROR -+OSFreePages(IMG_UINT32 ui32AllocFlags, IMG_SIZE_T uiBytes, IMG_VOID *pvCpuVAddr, IMG_HANDLE hOSMemHandle) -+{ -+ LinuxMemArea *psLinuxMemArea; -+ PVRSRV_ERROR eError; -+ -+ PVR_UNREFERENCED_PARAMETER(uiBytes); -+ PVR_UNREFERENCED_PARAMETER(pvCpuVAddr); -+ -+ psLinuxMemArea = (LinuxMemArea *)hOSMemHandle; -+ -+ switch(ui32AllocFlags & PVRSRV_HAP_MAPTYPE_MASK) -+ { -+ case PVRSRV_HAP_KERNEL_ONLY: -+ break; -+ case PVRSRV_HAP_SINGLE_PROCESS: -+ case PVRSRV_HAP_MULTI_PROCESS: -+ eError = PVRMMapRemoveRegisteredArea(psLinuxMemArea); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, -+ "OSFreePages(ui32AllocFlags=0x%08X, ui32Bytes=%" SIZE_T_FMT_LEN "u, " -+ "pvCpuVAddr=%p, hOSMemHandle=%p) FAILED!", -+ ui32AllocFlags, uiBytes, pvCpuVAddr, hOSMemHandle)); -+ return eError; -+ } -+ break; -+ default: -+ PVR_DPF((PVR_DBG_ERROR,"%s: invalid flags 0x%x\n", -+ __FUNCTION__, ui32AllocFlags)); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ LinuxMemAreaDeepFree(psLinuxMemArea); -+ -+ return PVRSRV_OK; -+} -+ -+ -+PVRSRV_ERROR -+OSGetSubMemHandle(IMG_HANDLE hOSMemHandle, -+ IMG_UINTPTR_T uiByteOffset, -+ IMG_SIZE_T uiBytes, -+ IMG_UINT32 ui32Flags, -+ IMG_HANDLE *phOSMemHandleRet) -+{ -+ LinuxMemArea *psParentLinuxMemArea, *psLinuxMemArea; -+ PVRSRV_ERROR eError; -+ -+ psParentLinuxMemArea = (LinuxMemArea *)hOSMemHandle; -+ -+ psLinuxMemArea = NewSubLinuxMemArea(psParentLinuxMemArea, uiByteOffset, uiBytes); -+ if(!psLinuxMemArea) -+ { -+ *phOSMemHandleRet = NULL; -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ *phOSMemHandleRet = psLinuxMemArea; -+ -+ /* KERNEL_ONLY areas are never mmapable. */ -+ if(ui32Flags & PVRSRV_HAP_KERNEL_ONLY) -+ { -+ return PVRSRV_OK; -+ } -+ -+ eError = PVRMMapRegisterArea(psLinuxMemArea); -+ if(eError != PVRSRV_OK) -+ { -+ goto failed_register_area; -+ } -+ -+ return PVRSRV_OK; -+ -+failed_register_area: -+ *phOSMemHandleRet = NULL; -+ LinuxMemAreaDeepFree(psLinuxMemArea); -+ return eError; -+} -+ -+PVRSRV_ERROR -+OSReleaseSubMemHandle(IMG_VOID *hOSMemHandle, IMG_UINT32 ui32Flags) -+{ -+ LinuxMemArea *psLinuxMemArea; -+ PVRSRV_ERROR eError; -+ -+ psLinuxMemArea = (LinuxMemArea *)hOSMemHandle; -+ PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_SUB_ALLOC); -+ -+ if((ui32Flags & PVRSRV_HAP_KERNEL_ONLY) == 0) -+ { -+ eError = PVRMMapRemoveRegisteredArea(psLinuxMemArea); -+ if(eError != PVRSRV_OK) -+ { -+ return eError; -+ } -+ } -+ LinuxMemAreaDeepFree(psLinuxMemArea); -+ -+ return PVRSRV_OK; -+} -+ -+ -+IMG_CPU_PHYADDR -+OSMemHandleToCpuPAddr(IMG_VOID *hOSMemHandle, IMG_UINTPTR_T uiByteOffset) -+{ -+ PVR_ASSERT(hOSMemHandle); -+ -+ return LinuxMemAreaToCpuPAddr(hOSMemHandle, uiByteOffset); -+} -+ -+ -+IMG_BOOL OSMemHandleIsPhysContig(IMG_VOID *hOSMemHandle) -+{ -+ LinuxMemArea *psLinuxMemArea = (LinuxMemArea *)hOSMemHandle; -+ -+ PVR_ASSERT(psLinuxMemArea); -+ -+ if(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_EXTERNAL_KV) -+ return psLinuxMemArea->uData.sExternalKV.bPhysContig; -+ -+ return IMG_FALSE; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function OSMemCopy -+ -+ @Description Copies memory around -+ -+ @Input pvDst - pointer to dst -+ @Output pvSrc - pointer to src -+ @Input ui32Size - bytes to copy -+ -+ @Return none -+ -+******************************************************************************/ -+IMG_VOID OSMemCopy(IMG_VOID *pvDst, IMG_VOID *pvSrc, IMG_SIZE_T uiSize) -+{ -+#if defined(USE_UNOPTIMISED_MEMCPY) -+ IMG_UINT8 *Src,*Dst; -+ IMG_INT i; -+ -+ Src=(IMG_UINT8 *)pvSrc; -+ Dst=(IMG_UINT8 *)pvDst; -+ for(i=0;i<uiSize;i++) -+ { -+ Dst[i]=Src[i]; -+ } -+#else -+ memcpy(pvDst, pvSrc, uiSize); -+#endif -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function OSMemSet -+ -+ @Description Function that does the same as the C memset() functions -+ -+ @Modified *pvDest : pointer to start of buffer to be set -+ -+ @Input ui8Value: value to set each byte to -+ -+ @Input ui32Size : number of bytes to set -+ -+ @Return IMG_VOID -+ -+******************************************************************************/ -+IMG_VOID OSMemSet(IMG_VOID *pvDest, IMG_UINT8 ui8Value, IMG_SIZE_T uiSize) -+{ -+#if defined(USE_UNOPTIMISED_MEMSET) -+ IMG_UINT8 *Buff; -+ IMG_INT i; -+ -+ Buff=(IMG_UINT8 *)pvDest; -+ for(i=0;i<uiSize;i++) -+ { -+ Buff[i]=ui8Value; -+ } -+#else -+ memset(pvDest, (IMG_INT) ui8Value, (size_t) uiSize); -+#endif -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function OSStringCopy -+ @Description strcpy -+******************************************************************************/ -+IMG_CHAR *OSStringCopy(IMG_CHAR *pszDest, const IMG_CHAR *pszSrc) -+{ -+ return (strcpy(pszDest, pszSrc)); -+} -+ -+/*! -+****************************************************************************** -+ @Function OSSNPrintf -+ @Description snprintf -+******************************************************************************/ -+IMG_INT32 OSSNPrintf(IMG_CHAR *pStr, IMG_SIZE_T uiSize, const IMG_CHAR *pszFormat, ...) -+{ -+ va_list argList; -+ IMG_INT32 iCount; -+ -+ va_start(argList, pszFormat); -+ iCount = vsnprintf(pStr, (size_t)uiSize, pszFormat, argList); -+ va_end(argList); -+ -+ return iCount; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function OSBreakResourceLock -+ -+ @Description unlocks an OS dependant resource -+ -+ @Input phResource - pointer to OS dependent resource structure -+ @Input ui32ID - Lock value to look for -+ -+ @Return -+ -+******************************************************************************/ -+IMG_VOID OSBreakResourceLock (PVRSRV_RESOURCE *psResource, IMG_UINT32 ui32ID) -+{ -+ volatile IMG_UINT32 *pui32Access = (volatile IMG_UINT32 *)&psResource->ui32Lock; -+ -+ if(*pui32Access) -+ { -+ if(psResource->ui32ID == ui32ID) -+ { -+ psResource->ui32ID = 0; -+ *pui32Access = 0; -+ } -+ else -+ { -+ PVR_DPF((PVR_DBG_MESSAGE,"OSBreakResourceLock: Resource is not locked for this process.")); -+ } -+ } -+ else -+ { -+ PVR_DPF((PVR_DBG_MESSAGE,"OSBreakResourceLock: Resource is not locked")); -+ } -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function OSCreateResource -+ -+ @Description creates a OS dependant resource object -+ -+ @Input phResource - pointer to OS dependent resource -+ -+ @Return error status -+ -+******************************************************************************/ -+PVRSRV_ERROR OSCreateResource(PVRSRV_RESOURCE *psResource) -+{ -+ psResource->ui32ID = 0; -+ psResource->ui32Lock = 0; -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function OSDestroyResource -+ -+ @Description destroys an OS dependant resource object -+ -+ @Input phResource - pointer to OS dependent resource -+ -+ @Return error status -+ -+******************************************************************************/ -+PVRSRV_ERROR OSDestroyResource (PVRSRV_RESOURCE *psResource) -+{ -+ OSBreakResourceLock (psResource, psResource->ui32ID); -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function OSInitEnvData -+ -+ @Description Allocates space for env specific data -+ -+ @Input ppvEnvSpecificData - pointer to pointer in which to return -+ allocated data. -+ @Input ui32MMUMode - MMU mode. -+ -+ @Return nothing -+ -+******************************************************************************/ -+PVRSRV_ERROR OSInitEnvData(IMG_PVOID *ppvEnvSpecificData) -+{ -+ ENV_DATA *psEnvData; -+ PVRSRV_ERROR eError; -+ -+ /* allocate env specific data */ -+ eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(ENV_DATA), (IMG_VOID **)&psEnvData, IMG_NULL, -+ "Environment Data"); -+ if (eError != PVRSRV_OK) -+ { -+ return eError; -+ } -+ -+ eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, PVRSRV_MAX_BRIDGE_IN_SIZE + PVRSRV_MAX_BRIDGE_OUT_SIZE, -+ &psEnvData->pvBridgeData, IMG_NULL, -+ "Bridge Data"); -+ if (eError != PVRSRV_OK) -+ { -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(ENV_DATA), psEnvData, IMG_NULL); -+ /*not nulling pointer, out of scope*/ -+ return eError; -+ } -+ -+ -+ /* ISR installation flags */ -+ psEnvData->bMISRInstalled = IMG_FALSE; -+ psEnvData->bLISRInstalled = IMG_FALSE; -+ -+ /* copy structure back */ -+ *ppvEnvSpecificData = psEnvData; -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function OSDeInitEnvData -+ -+ @Description frees env specific data memory -+ -+ @Input pvEnvSpecificData - pointer to private structure -+ -+ @Return PVRSRV_OK on success else PVRSRV_ERROR_OUT_OF_MEMORY -+ -+******************************************************************************/ -+PVRSRV_ERROR OSDeInitEnvData(IMG_PVOID pvEnvSpecificData) -+{ -+ ENV_DATA *psEnvData = (ENV_DATA*)pvEnvSpecificData; -+ -+ PVR_ASSERT(!psEnvData->bMISRInstalled); -+ PVR_ASSERT(!psEnvData->bLISRInstalled); -+ -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, PVRSRV_MAX_BRIDGE_IN_SIZE + PVRSRV_MAX_BRIDGE_OUT_SIZE, psEnvData->pvBridgeData, IMG_NULL); -+ psEnvData->pvBridgeData = IMG_NULL; -+ -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(ENV_DATA), pvEnvSpecificData, IMG_NULL); -+ /*not nulling pointer, copy on stack*/ -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function OSReleaseThreadQuanta -+ -+ @Description -+ Releases thread quanta -+ -+ @Return nothing -+ -+******************************************************************************/ -+IMG_VOID OSReleaseThreadQuanta(IMG_VOID) -+{ -+ schedule(); -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function OSClockus -+ -+ @Description -+ This function returns the clock in microseconds -+ -+ @Input void -+ -+ @Return - clock (us) -+ -+******************************************************************************/ -+IMG_UINT32 OSClockus(IMG_VOID) -+{ -+ IMG_UINT32 time, j = jiffies; -+ -+ time = j * (1000000 / HZ); -+ -+ return time; -+} -+ -+ -+IMG_VOID OSWaitus(IMG_UINT32 ui32Timeus) -+{ -+ udelay(ui32Timeus); -+} -+ -+ -+IMG_VOID OSSleepms(IMG_UINT32 ui32Timems) -+{ -+ msleep(ui32Timems); -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function OSFuncHighResTimerCreate -+ -+ @Description -+ This function creates a high res timer who's handle is returned -+ -+ @Input nothing -+ -+ @Return handle -+ -+******************************************************************************/ -+IMG_HANDLE OSFuncHighResTimerCreate(IMG_VOID) -+{ -+ /* We don't need a handle, but we must return non-NULL */ -+ return (IMG_HANDLE) 1; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function OSFuncHighResTimerGetus -+ -+ @Description -+ This function returns the current timestamp in us -+ -+ @Input nothing -+ -+ @Return handle -+ -+******************************************************************************/ -+IMG_UINT32 OSFuncHighResTimerGetus(IMG_HANDLE hTimer) -+{ -+ return (IMG_UINT32) jiffies_to_usecs(jiffies); -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function OSFuncHighResTimerDestroy -+ -+ @Description -+ This function will destroy the high res timer -+ -+ @Input nothing -+ -+ @Return handle -+ -+******************************************************************************/ -+IMG_VOID OSFuncHighResTimerDestroy(IMG_HANDLE hTimer) -+{ -+ PVR_UNREFERENCED_PARAMETER(hTimer); -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function OSGetCurrentProcessIDKM -+ -+ @Description Returns handle for current process -+ -+ @Return ID of current process -+ -+*****************************************************************************/ -+IMG_UINT32 OSGetCurrentProcessIDKM(IMG_VOID) -+{ -+ if (in_interrupt()) -+ { -+ return KERNEL_ID; -+ } -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) -+ return (IMG_UINT32)current->pgrp; -+#else -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)) -+ return (IMG_UINT32)task_tgid_nr(current); -+#else -+ return (IMG_UINT32)current->tgid; -+#endif -+#endif -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function OSGetPageSize -+ -+ @Description gets page size -+ -+ @Return page size -+ -+******************************************************************************/ -+IMG_UINT32 OSGetPageSize(IMG_VOID) -+{ -+#if defined(__sh__) -+ IMG_UINT32 ui32ReturnValue = PAGE_SIZE; -+ -+ return (ui32ReturnValue); -+#else -+ return PAGE_SIZE; -+#endif -+} -+ -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)) -+/*! -+****************************************************************************** -+ -+ @Function DeviceISRWrapper -+ -+ @Description wrapper for Device ISR function to conform to ISR OS interface -+ -+ @Return -+ -+******************************************************************************/ -+static irqreturn_t DeviceISRWrapper(int irq, void *dev_id -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)) -+ , struct pt_regs *regs -+#endif -+ ) -+{ -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+ IMG_BOOL bStatus = IMG_FALSE; -+ -+ PVR_UNREFERENCED_PARAMETER(irq); -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)) -+ PVR_UNREFERENCED_PARAMETER(regs); -+#endif -+ psDeviceNode = (PVRSRV_DEVICE_NODE*)dev_id; -+ if(!psDeviceNode) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "DeviceISRWrapper: invalid params\n")); -+ goto out; -+ } -+ -+ bStatus = PVRSRVDeviceLISR(psDeviceNode); -+ -+ if (bStatus) -+ { -+ OSScheduleMISR((IMG_VOID *)psDeviceNode->psSysData); -+ } -+ -+out: -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) -+ return bStatus ? IRQ_HANDLED : IRQ_NONE; -+#endif -+} -+ -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SystemISRWrapper -+ -+ @Description wrapper for System ISR function to conform to ISR OS interface -+ -+ @Input Interrupt - NT interrupt object. -+ @Input Context - Context parameter -+ -+ @Return -+ -+******************************************************************************/ -+static irqreturn_t SystemISRWrapper(int irq, void *dev_id -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)) -+ , struct pt_regs *regs -+#endif -+ ) -+{ -+ SYS_DATA *psSysData; -+ IMG_BOOL bStatus = IMG_FALSE; -+ -+ PVR_UNREFERENCED_PARAMETER(irq); -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)) -+ PVR_UNREFERENCED_PARAMETER(regs); -+#endif -+ psSysData = (SYS_DATA *)dev_id; -+ if(!psSysData) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SystemISRWrapper: invalid params\n")); -+ goto out; -+ } -+ -+ bStatus = PVRSRVSystemLISR(psSysData); -+ -+ if (bStatus) -+ { -+ OSScheduleMISR((IMG_VOID *)psSysData); -+ } -+ -+out: -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) -+ return bStatus ? IRQ_HANDLED : IRQ_NONE; -+#endif -+} -+/*! -+****************************************************************************** -+ -+ @Function OSInstallDeviceLISR -+ -+ @Description Installs a Device ISR -+ -+ @Input pvSysData -+ @Input ui32Irq - IRQ number -+ @Input pszISRName - ISR name -+ @Input pvDeviceNode - device node contains ISR function and data argument -+ -+ @Return error status -+ -+******************************************************************************/ -+PVRSRV_ERROR OSInstallDeviceLISR(IMG_VOID *pvSysData, -+ IMG_UINT32 ui32Irq, -+ IMG_CHAR *pszISRName, -+ IMG_VOID *pvDeviceNode) -+{ -+ SYS_DATA *psSysData = (SYS_DATA*)pvSysData; -+ ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData; -+ -+ if (psEnvData->bLISRInstalled) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "OSInstallDeviceLISR: An ISR has already been installed: IRQ %d cookie %p", psEnvData->ui32IRQ, psEnvData->pvISRCookie)); -+ return PVRSRV_ERROR_ISR_ALREADY_INSTALLED; -+ } -+ -+ PVR_TRACE(("Installing device LISR %s on IRQ %d with cookie %p", pszISRName, ui32Irq, pvDeviceNode)); -+ -+ if(request_irq(ui32Irq, DeviceISRWrapper, -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)) -+ SA_SHIRQ -+#else -+ IRQF_SHARED -+#endif -+ , pszISRName, pvDeviceNode)) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"OSInstallDeviceLISR: Couldn't install device LISR on IRQ %d", ui32Irq)); -+ -+ return PVRSRV_ERROR_UNABLE_TO_INSTALL_ISR; -+ } -+ -+ psEnvData->ui32IRQ = ui32Irq; -+ psEnvData->pvISRCookie = pvDeviceNode; -+ psEnvData->bLISRInstalled = IMG_TRUE; -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function OSUninstallDeviceLISR -+ -+ @Description Uninstalls a Device ISR -+ -+ @Input pvSysData - sysdata -+ -+ @Return error status -+ -+******************************************************************************/ -+PVRSRV_ERROR OSUninstallDeviceLISR(IMG_VOID *pvSysData) -+{ -+ SYS_DATA *psSysData = (SYS_DATA*)pvSysData; -+ ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData; -+ -+ if (!psEnvData->bLISRInstalled) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "OSUninstallDeviceLISR: No LISR has been installed")); -+ return PVRSRV_ERROR_ISR_NOT_INSTALLED; -+ } -+ -+ PVR_TRACE(("Uninstalling device LISR on IRQ %d with cookie %p", psEnvData->ui32IRQ, psEnvData->pvISRCookie)); -+ -+ free_irq(psEnvData->ui32IRQ, psEnvData->pvISRCookie); -+ -+ psEnvData->bLISRInstalled = IMG_FALSE; -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function OSInstallSystemLISR -+ -+ @Description Installs a System ISR -+ -+ @Input psSysData -+ @Input ui32Irq - IRQ number -+ -+ @Return error status -+ -+******************************************************************************/ -+PVRSRV_ERROR OSInstallSystemLISR(IMG_VOID *pvSysData, IMG_UINT32 ui32Irq) -+{ -+ SYS_DATA *psSysData = (SYS_DATA*)pvSysData; -+ ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData; -+ -+ if (psEnvData->bLISRInstalled) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "OSInstallSystemLISR: An LISR has already been installed: IRQ %d cookie %p", psEnvData->ui32IRQ, psEnvData->pvISRCookie)); -+ return PVRSRV_ERROR_ISR_ALREADY_INSTALLED; -+ } -+ -+ PVR_TRACE(("Installing system LISR on IRQ %d with cookie %p", ui32Irq, pvSysData)); -+ -+ if(request_irq(ui32Irq, SystemISRWrapper, -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)) -+ SA_SHIRQ -+#else -+ IRQF_SHARED -+#endif -+ , PVRSRV_MODNAME, pvSysData)) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"OSInstallSystemLISR: Couldn't install system LISR on IRQ %d", ui32Irq)); -+ -+ return PVRSRV_ERROR_UNABLE_TO_INSTALL_ISR; -+ } -+ -+ psEnvData->ui32IRQ = ui32Irq; -+ psEnvData->pvISRCookie = pvSysData; -+ psEnvData->bLISRInstalled = IMG_TRUE; -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function OSUninstallSystemLISR -+ -+ @Description Uninstalls a System ISR -+ -+ @Input psSysData -+ -+ @Return error status -+ -+******************************************************************************/ -+PVRSRV_ERROR OSUninstallSystemLISR(IMG_VOID *pvSysData) -+{ -+ SYS_DATA *psSysData = (SYS_DATA*)pvSysData; -+ ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData; -+ -+ if (!psEnvData->bLISRInstalled) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "OSUninstallSystemLISR: No LISR has been installed")); -+ return PVRSRV_ERROR_ISR_NOT_INSTALLED; -+ } -+ -+ PVR_TRACE(("Uninstalling system LISR on IRQ %d with cookie %p", psEnvData->ui32IRQ, psEnvData->pvISRCookie)); -+ -+ free_irq(psEnvData->ui32IRQ, psEnvData->pvISRCookie); -+ -+ psEnvData->bLISRInstalled = IMG_FALSE; -+ -+ return PVRSRV_OK; -+} -+ -+#if defined(PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE) -+/*! -+****************************************************************************** -+ -+ @Function MISRWrapper -+ -+ @Description OS dependent MISR wrapper -+ -+ @Input psSysData -+ -+ @Return error status -+ -+******************************************************************************/ -+static void MISRWrapper( -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)) -+ void *data -+#else -+ struct work_struct *data -+#endif -+) -+{ -+ ENV_DATA *psEnvData = container_of(data, ENV_DATA, sMISRWork); -+ SYS_DATA *psSysData = (SYS_DATA *)psEnvData->pvMISRData; -+ -+ PVRSRVMISR(psSysData); -+ -+#if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) -+ PVRSyncUpdateAllSyncs(); -+#endif -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function OSInstallMISR -+ -+ @Description Installs an OS dependent MISR -+ -+ @Input psSysData -+ -+ @Return error status -+ -+******************************************************************************/ -+PVRSRV_ERROR OSInstallMISR(IMG_VOID *pvSysData) -+{ -+ SYS_DATA *psSysData = (SYS_DATA*)pvSysData; -+ ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData; -+ -+ if (psEnvData->bMISRInstalled) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "OSInstallMISR: An MISR has already been installed")); -+ return PVRSRV_ERROR_ISR_ALREADY_INSTALLED; -+ } -+ -+ PVR_TRACE(("Installing MISR with cookie %p", pvSysData)); -+ -+ psEnvData->psWorkQueue = create_singlethread_workqueue("pvr_workqueue"); -+ -+ if (psEnvData->psWorkQueue == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "OSInstallMISR: create_singlethreaded_workqueue failed")); -+ return PVRSRV_ERROR_UNABLE_TO_CREATE_THREAD; -+ } -+ -+ INIT_WORK(&psEnvData->sMISRWork, MISRWrapper -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)) -+ , (void *)&psEnvData->sMISRWork -+#endif -+ ); -+ -+ psEnvData->pvMISRData = pvSysData; -+ psEnvData->bMISRInstalled = IMG_TRUE; -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function OSUninstallMISR -+ -+ @Description Uninstalls an OS dependent MISR -+ -+ @Input psSysData -+ -+ @Return error status -+ -+******************************************************************************/ -+PVRSRV_ERROR OSUninstallMISR(IMG_VOID *pvSysData) -+{ -+ SYS_DATA *psSysData = (SYS_DATA*)pvSysData; -+ ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData; -+ -+ if (!psEnvData->bMISRInstalled) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "OSUninstallMISR: No MISR has been installed")); -+ return PVRSRV_ERROR_ISR_NOT_INSTALLED; -+ } -+ -+ PVR_TRACE(("Uninstalling MISR")); -+ -+ destroy_workqueue(psEnvData->psWorkQueue); -+ -+ psEnvData->bMISRInstalled = IMG_FALSE; -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function OSScheduleMISR -+ -+ @Description Schedules an OS dependent MISR -+ -+ @Input pvSysData -+ -+ @Return error status -+ -+******************************************************************************/ -+PVRSRV_ERROR OSScheduleMISR(IMG_VOID *pvSysData) -+{ -+ SYS_DATA *psSysData = (SYS_DATA*)pvSysData; -+ ENV_DATA *psEnvData = (ENV_DATA*)psSysData->pvEnvSpecificData; -+ -+ if (psEnvData->bMISRInstalled) -+ { -+ queue_work(psEnvData->psWorkQueue, &psEnvData->sMISRWork); -+ } -+ -+ return PVRSRV_OK; -+} -+#else /* defined(PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE) */ -+#if defined(PVR_LINUX_MISR_USING_WORKQUEUE) -+/*! -+****************************************************************************** -+ -+ @Function MISRWrapper -+ -+ @Description OS dependent MISR wrapper -+ -+ @Input psSysData -+ -+ @Return error status -+ -+******************************************************************************/ -+static void MISRWrapper( -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)) -+ void *data -+#else -+ struct work_struct *data -+#endif -+) -+{ -+ ENV_DATA *psEnvData = container_of(data, ENV_DATA, sMISRWork); -+ SYS_DATA *psSysData = (SYS_DATA *)psEnvData->pvMISRData; -+ -+ PVRSRVMISR(psSysData); -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function OSInstallMISR -+ -+ @Description Installs an OS dependent MISR -+ -+ @Input psSysData -+ -+ @Return error status -+ -+******************************************************************************/ -+PVRSRV_ERROR OSInstallMISR(IMG_VOID *pvSysData) -+{ -+ SYS_DATA *psSysData = (SYS_DATA*)pvSysData; -+ ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData; -+ -+ if (psEnvData->bMISRInstalled) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "OSInstallMISR: An MISR has already been installed")); -+ return PVRSRV_ERROR_ISR_ALREADY_INSTALLED; -+ } -+ -+ PVR_TRACE(("Installing MISR with cookie %p", pvSysData)); -+ -+ INIT_WORK(&psEnvData->sMISRWork, MISRWrapper -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)) -+ , (void *)&psEnvData->sMISRWork -+#endif -+ ); -+ -+ psEnvData->pvMISRData = pvSysData; -+ psEnvData->bMISRInstalled = IMG_TRUE; -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function OSUninstallMISR -+ -+ @Description Uninstalls an OS dependent MISR -+ -+ @Input psSysData -+ -+ @Return error status -+ -+******************************************************************************/ -+PVRSRV_ERROR OSUninstallMISR(IMG_VOID *pvSysData) -+{ -+ SYS_DATA *psSysData = (SYS_DATA*)pvSysData; -+ ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData; -+ -+ if (!psEnvData->bMISRInstalled) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "OSUninstallMISR: No MISR has been installed")); -+ return PVRSRV_ERROR_ISR_NOT_INSTALLED; -+ } -+ -+ PVR_TRACE(("Uninstalling MISR")); -+ -+ flush_scheduled_work(); -+ -+ psEnvData->bMISRInstalled = IMG_FALSE; -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function OSScheduleMISR -+ -+ @Description Schedules an OS dependent MISR -+ -+ @Input pvSysData -+ -+ @Return error status -+ -+******************************************************************************/ -+PVRSRV_ERROR OSScheduleMISR(IMG_VOID *pvSysData) -+{ -+ SYS_DATA *psSysData = (SYS_DATA*)pvSysData; -+ ENV_DATA *psEnvData = (ENV_DATA*)psSysData->pvEnvSpecificData; -+ -+ if (psEnvData->bMISRInstalled) -+ { -+ schedule_work(&psEnvData->sMISRWork); -+ } -+ -+ return PVRSRV_OK; -+} -+ -+#else /* #if defined(PVR_LINUX_MISR_USING_WORKQUEUE) */ -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function MISRWrapper -+ -+ @Description OS dependent MISR wrapper -+ -+ @Input psSysData -+ -+ @Return error status -+ -+******************************************************************************/ -+static void MISRWrapper(unsigned long data) -+{ -+ SYS_DATA *psSysData; -+ -+ psSysData = (SYS_DATA *)data; -+ -+ PVRSRVMISR(psSysData); -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function OSInstallMISR -+ -+ @Description Installs an OS dependent MISR -+ -+ @Input psSysData -+ -+ @Return error status -+ -+******************************************************************************/ -+PVRSRV_ERROR OSInstallMISR(IMG_VOID *pvSysData) -+{ -+ SYS_DATA *psSysData = (SYS_DATA*)pvSysData; -+ ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData; -+ -+ if (psEnvData->bMISRInstalled) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "OSInstallMISR: An MISR has already been installed")); -+ return PVRSRV_ERROR_ISR_ALREADY_INSTALLED; -+ } -+ -+ PVR_TRACE(("Installing MISR with cookie %p", pvSysData)); -+ -+ tasklet_init(&psEnvData->sMISRTasklet, MISRWrapper, (unsigned long)pvSysData); -+ -+ psEnvData->bMISRInstalled = IMG_TRUE; -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function OSUninstallMISR -+ -+ @Description Uninstalls an OS dependent MISR -+ -+ @Input psSysData -+ -+ @Return error status -+ -+******************************************************************************/ -+PVRSRV_ERROR OSUninstallMISR(IMG_VOID *pvSysData) -+{ -+ SYS_DATA *psSysData = (SYS_DATA*)pvSysData; -+ ENV_DATA *psEnvData = (ENV_DATA *)psSysData->pvEnvSpecificData; -+ -+ if (!psEnvData->bMISRInstalled) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "OSUninstallMISR: No MISR has been installed")); -+ return PVRSRV_ERROR_ISR_NOT_INSTALLED; -+ } -+ -+ PVR_TRACE(("Uninstalling MISR")); -+ -+ tasklet_kill(&psEnvData->sMISRTasklet); -+ -+ psEnvData->bMISRInstalled = IMG_FALSE; -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function OSScheduleMISR -+ -+ @Description Schedules an OS dependent MISR -+ -+ @Input pvSysData -+ -+ @Return error status -+ -+******************************************************************************/ -+PVRSRV_ERROR OSScheduleMISR(IMG_VOID *pvSysData) -+{ -+ SYS_DATA *psSysData = (SYS_DATA*)pvSysData; -+ ENV_DATA *psEnvData = (ENV_DATA*)psSysData->pvEnvSpecificData; -+ -+ if (psEnvData->bMISRInstalled) -+ { -+ tasklet_schedule(&psEnvData->sMISRTasklet); -+ } -+ -+ return PVRSRV_OK; -+} -+ -+#endif /* #if defined(PVR_LINUX_MISR_USING_WORKQUEUE) */ -+#endif /* #if defined(PVR_LINUX_MISR_USING_PRIVATE_WORKQUEUE) */ -+ -+#endif /* #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)) */ -+ -+IMG_VOID OSPanic(IMG_VOID) -+{ -+ BUG(); -+} -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)) -+#define OS_TAS(p) xchg((p), 1) -+#else -+#define OS_TAS(p) tas(p) -+#endif -+/*! -+****************************************************************************** -+ -+ @Function OSLockResource -+ -+ @Description locks an OS dependant Resource -+ -+ @Input phResource - pointer to OS dependent Resource -+ @Input bBlock - do we want to block? -+ -+ @Return error status -+ -+******************************************************************************/ -+PVRSRV_ERROR OSLockResource ( PVRSRV_RESOURCE *psResource, -+ IMG_UINT32 ui32ID) -+ -+{ -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ -+ if(!OS_TAS(&psResource->ui32Lock)) -+ psResource->ui32ID = ui32ID; -+ else -+ eError = PVRSRV_ERROR_UNABLE_TO_LOCK_RESOURCE; -+ -+ return eError; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function OSUnlockResource -+ -+ @Description unlocks an OS dependant resource -+ -+ @Input phResource - pointer to OS dependent resource structure -+ -+ @Return -+ -+******************************************************************************/ -+PVRSRV_ERROR OSUnlockResource (PVRSRV_RESOURCE *psResource, IMG_UINT32 ui32ID) -+{ -+ volatile IMG_UINT32 *pui32Access = (volatile IMG_UINT32 *)&psResource->ui32Lock; -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ -+ if(*pui32Access) -+ { -+ if(psResource->ui32ID == ui32ID) -+ { -+ psResource->ui32ID = 0; -+ smp_mb(); -+ *pui32Access = 0; -+ } -+ else -+ { -+ PVR_DPF((PVR_DBG_ERROR,"OSUnlockResource: Resource %p is not locked with expected value.", psResource)); -+ PVR_DPF((PVR_DBG_MESSAGE,"Should be %x is actually %x", ui32ID, psResource->ui32ID)); -+ eError = PVRSRV_ERROR_INVALID_LOCK_ID; -+ } -+ } -+ else -+ { -+ PVR_DPF((PVR_DBG_ERROR,"OSUnlockResource: Resource %p is not locked", psResource)); -+ eError = PVRSRV_ERROR_RESOURCE_NOT_LOCKED; -+ } -+ -+ return eError; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function OSIsResourceLocked -+ -+ @Description tests if resource is locked -+ -+ @Input phResource - pointer to OS dependent resource structure -+ -+ @Return error status -+ -+******************************************************************************/ -+IMG_BOOL OSIsResourceLocked (PVRSRV_RESOURCE *psResource, IMG_UINT32 ui32ID) -+{ -+ volatile IMG_UINT32 *pui32Access = (volatile IMG_UINT32 *)&psResource->ui32Lock; -+ -+ return (*(volatile IMG_UINT32 *)pui32Access == 1) && (psResource->ui32ID == ui32ID) -+ ? IMG_TRUE -+ : IMG_FALSE; -+} -+ -+ -+#if !defined(SYS_CUSTOM_POWERLOCK_WRAP) -+PVRSRV_ERROR OSPowerLockWrap(IMG_BOOL bTryLock) -+{ -+ PVR_UNREFERENCED_PARAMETER(bTryLock); -+ -+ return PVRSRV_OK; -+} -+ -+IMG_VOID OSPowerLockUnwrap (IMG_VOID) -+{ -+} -+#endif /* SYS_CUSTOM_POWERLOCK_WRAP */ -+ -+ -+IMG_CPU_PHYADDR OSMapLinToCPUPhys(IMG_HANDLE hOSMemHandle, -+ IMG_VOID *pvLinAddr) -+{ -+ IMG_CPU_PHYADDR CpuPAddr; -+ LinuxMemArea *psLinuxMemArea; -+ IMG_UINTPTR_T uiByteOffset; -+ IMG_UINT32 ui32ByteOffset; -+ -+ PVR_ASSERT(hOSMemHandle != IMG_NULL); -+ -+ psLinuxMemArea = (LinuxMemArea *)hOSMemHandle; -+ -+ uiByteOffset = (IMG_UINTPTR_T)pvLinAddr - (IMG_UINTPTR_T)LinuxMemAreaToCpuVAddr(psLinuxMemArea); -+ ui32ByteOffset = (IMG_UINT32)uiByteOffset; -+ -+ CpuPAddr = LinuxMemAreaToCpuPAddr(hOSMemHandle, ui32ByteOffset); -+ -+ return CpuPAddr; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function OSMapPhysToLin -+ -+ @Description Maps the physical memory into linear addr range -+ -+ @Input BasePAddr : physical cpu address -+ -+ @Input ui32Bytes - bytes to map -+ -+ @Input ui32CacheType - cache type -+ -+ @Return : Linear addr of mapping on success, else NULL -+ -+ ******************************************************************************/ -+IMG_VOID * -+OSMapPhysToLin(IMG_CPU_PHYADDR BasePAddr, -+ IMG_SIZE_T uiBytes, -+ IMG_UINT32 ui32MappingFlags, -+ IMG_HANDLE *phOSMemHandle) -+{ -+ if(ui32MappingFlags & PVRSRV_HAP_KERNEL_ONLY) -+ { -+ /* -+ * Provide some backwards compatibility, until all callers -+ * have been updated to pass a non-null OSMemHandle pointer. -+ * Such callers must not call OSMapLinToCPUPhys. -+ */ -+ if(phOSMemHandle == IMG_NULL) -+ { -+ IMG_VOID *pvIORemapCookie; -+ pvIORemapCookie = IORemapWrapper(BasePAddr, uiBytes, ui32MappingFlags); -+ if(pvIORemapCookie == IMG_NULL) -+ { -+ return IMG_NULL; -+ } -+ return pvIORemapCookie; -+ } -+ else -+ { -+ LinuxMemArea *psLinuxMemArea = NewIORemapLinuxMemArea(BasePAddr, uiBytes, ui32MappingFlags); -+ -+ if(psLinuxMemArea == IMG_NULL) -+ { -+ return IMG_NULL; -+ } -+ -+ *phOSMemHandle = (IMG_HANDLE)psLinuxMemArea; -+ return LinuxMemAreaToCpuVAddr(psLinuxMemArea); -+ } -+ } -+ -+ PVR_DPF((PVR_DBG_ERROR, -+ "OSMapPhysToLin should only be used with PVRSRV_HAP_KERNEL_ONLY " -+ " (Use OSReservePhys otherwise)")); -+ -+ return IMG_NULL; -+} -+ -+/*! -+****************************************************************************** -+ @Function OSUnMapPhysToLin -+ @Description Unmaps memory that was mapped with OSMapPhysToLin -+ @Return TRUE on success, else FALSE -+******************************************************************************/ -+IMG_BOOL -+OSUnMapPhysToLin(IMG_VOID *pvLinAddr, IMG_SIZE_T uiBytes, IMG_UINT32 ui32MappingFlags, IMG_HANDLE hOSMemHandle) -+{ -+ PVR_UNREFERENCED_PARAMETER(uiBytes); -+ -+ if(ui32MappingFlags & PVRSRV_HAP_KERNEL_ONLY) -+ { -+ if (hOSMemHandle == IMG_NULL) -+ { -+ IOUnmapWrapper(pvLinAddr); -+ } -+ else -+ { -+ LinuxMemArea *psLinuxMemArea = (LinuxMemArea *)hOSMemHandle; -+ -+ PVR_ASSERT(LinuxMemAreaToCpuVAddr(psLinuxMemArea) == pvLinAddr); -+ -+ FreeIORemapLinuxMemArea(psLinuxMemArea); -+ } -+ -+ return IMG_TRUE; -+ } -+ -+ PVR_DPF((PVR_DBG_ERROR, -+ "OSUnMapPhysToLin should only be used with PVRSRV_HAP_KERNEL_ONLY " -+ " (Use OSUnReservePhys otherwise)")); -+ return IMG_FALSE; -+} -+ -+/*! -+****************************************************************************** -+ @Function RegisterExternalMem -+ @Description Registers external memory for user mode mapping -+ @Return TRUE on success, else FALSE, MemHandle out -+******************************************************************************/ -+static PVRSRV_ERROR -+RegisterExternalMem(IMG_SYS_PHYADDR *pBasePAddr, -+ IMG_VOID *pvCPUVAddr, -+ IMG_UINT32 ui32Bytes, -+ IMG_BOOL bPhysContig, -+ IMG_UINT32 ui32MappingFlags, -+ IMG_HANDLE *phOSMemHandle) -+{ -+ LinuxMemArea *psLinuxMemArea; -+ -+ switch(ui32MappingFlags & PVRSRV_HAP_MAPTYPE_MASK) -+ { -+ case PVRSRV_HAP_KERNEL_ONLY: -+ { -+ psLinuxMemArea = NewExternalKVLinuxMemArea(pBasePAddr, pvCPUVAddr, ui32Bytes, bPhysContig, ui32MappingFlags); -+ -+ if(!psLinuxMemArea) -+ { -+ return PVRSRV_ERROR_BAD_MAPPING; -+ } -+ break; -+ } -+ case PVRSRV_HAP_SINGLE_PROCESS: -+ { -+ psLinuxMemArea = NewExternalKVLinuxMemArea(pBasePAddr, pvCPUVAddr, ui32Bytes, bPhysContig, ui32MappingFlags); -+ -+ if(!psLinuxMemArea) -+ { -+ return PVRSRV_ERROR_BAD_MAPPING; -+ } -+ PVRMMapRegisterArea(psLinuxMemArea); -+ break; -+ } -+ case PVRSRV_HAP_MULTI_PROCESS: -+ { -+ /* Currently PVRSRV_HAP_MULTI_PROCESS implies that we need a kernel -+ * virtual mapping and potentially multiple user space virtual mappings. -+ * Beware that the kernel virtual address space is a limited resource. -+ */ -+#if defined(VIVT_CACHE) || defined(__sh__) -+ /* -+ * ARM9 caches are tagged with virtual pages, not physical. As we are going to -+ * share this memory in different address spaces, we don't want it to be cached. -+ * ARM11 has physical tagging, so we can cache this memory without fear of virtual -+ * address aliasing in the TLB, as long as the kernel supports cache colouring for -+ * VIPT architectures. -+ */ -+ ui32MappingFlags &= ~PVRSRV_HAP_CACHED; -+#endif -+ psLinuxMemArea = NewExternalKVLinuxMemArea(pBasePAddr, pvCPUVAddr, ui32Bytes, bPhysContig, ui32MappingFlags); -+ -+ if(!psLinuxMemArea) -+ { -+ return PVRSRV_ERROR_BAD_MAPPING; -+ } -+ PVRMMapRegisterArea(psLinuxMemArea); -+ break; -+ } -+ default: -+ PVR_DPF((PVR_DBG_ERROR,"OSRegisterMem : invalid flags 0x%x\n", ui32MappingFlags)); -+ *phOSMemHandle = (IMG_HANDLE)0; -+ return PVRSRV_ERROR_INVALID_FLAGS; -+ } -+ -+ *phOSMemHandle = (IMG_HANDLE)psLinuxMemArea; -+ -+ LinuxMemAreaRegister(psLinuxMemArea); -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function OSRegisterMem -+ @Description Registers external memory for user mode mapping -+ @Output phOSMemHandle - handle to registered memory -+ @Return TRUE on success, else FALSE -+******************************************************************************/ -+PVRSRV_ERROR -+OSRegisterMem(IMG_CPU_PHYADDR BasePAddr, -+ IMG_VOID *pvCPUVAddr, -+ IMG_SIZE_T uiBytes, -+ IMG_UINT32 ui32MappingFlags, -+ IMG_HANDLE *phOSMemHandle) -+{ -+ IMG_SYS_PHYADDR SysPAddr = SysCpuPAddrToSysPAddr(BasePAddr); -+ -+ return RegisterExternalMem(&SysPAddr, pvCPUVAddr, uiBytes, IMG_TRUE, ui32MappingFlags, phOSMemHandle); -+} -+ -+ -+PVRSRV_ERROR OSRegisterDiscontigMem(IMG_SYS_PHYADDR *pBasePAddr, IMG_VOID *pvCPUVAddr, IMG_SIZE_T uiBytes, IMG_UINT32 ui32MappingFlags, IMG_HANDLE *phOSMemHandle) -+{ -+ return RegisterExternalMem(pBasePAddr, pvCPUVAddr, uiBytes, IMG_FALSE, ui32MappingFlags, phOSMemHandle); -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function OSUnRegisterMem -+ @Description UnRegisters external memory for user mode mapping -+ @Return TRUE on success, else FALSE -+******************************************************************************/ -+PVRSRV_ERROR -+OSUnRegisterMem (IMG_VOID *pvCpuVAddr, -+ IMG_SIZE_T uiBytes, -+ IMG_UINT32 ui32MappingFlags, -+ IMG_HANDLE hOSMemHandle) -+{ -+ LinuxMemArea *psLinuxMemArea = (LinuxMemArea *)hOSMemHandle; -+ PVRSRV_ERROR eError; -+ -+ PVR_UNREFERENCED_PARAMETER(pvCpuVAddr); -+ PVR_UNREFERENCED_PARAMETER(uiBytes); -+ -+ switch(ui32MappingFlags & PVRSRV_HAP_MAPTYPE_MASK) -+ { -+ case PVRSRV_HAP_KERNEL_ONLY: -+ break; -+ case PVRSRV_HAP_SINGLE_PROCESS: -+ case PVRSRV_HAP_MULTI_PROCESS: -+ { -+ eError = PVRMMapRemoveRegisteredArea(psLinuxMemArea); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s(%p, %" SIZE_T_FMT_LEN "u, 0x%08X, %p) FAILED!", -+ __FUNCTION__, pvCpuVAddr, uiBytes, -+ ui32MappingFlags, hOSMemHandle)); -+ return eError; -+ } -+ break; -+ } -+ default: -+ { -+ PVR_DPF((PVR_DBG_ERROR, "OSUnRegisterMem : invalid flags 0x%x", ui32MappingFlags)); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ } -+ -+ LinuxMemAreaDeepFree(psLinuxMemArea); -+ -+ return PVRSRV_OK; -+} -+ -+PVRSRV_ERROR OSUnRegisterDiscontigMem(IMG_VOID *pvCpuVAddr, IMG_SIZE_T uiBytes, IMG_UINT32 ui32Flags, IMG_HANDLE hOSMemHandle) -+{ -+ return OSUnRegisterMem(pvCpuVAddr, uiBytes, ui32Flags, hOSMemHandle); -+} -+ -+/*! -+****************************************************************************** -+ @Function OSReservePhys -+ @Description Registers physical memory for user mode mapping -+ @Output ppvCpuVAddr -+ @Output phOsMemHandle handle to registered memory -+ @Return TRUE on success, else FALSE -+******************************************************************************/ -+PVRSRV_ERROR -+OSReservePhys(IMG_CPU_PHYADDR BasePAddr, -+ IMG_SIZE_T uiBytes, -+ IMG_UINT32 ui32MappingFlags, -+ IMG_HANDLE hBMHandle, -+ IMG_VOID **ppvCpuVAddr, -+ IMG_HANDLE *phOSMemHandle) -+{ -+ LinuxMemArea *psLinuxMemArea; -+ -+#if 0 -+ /* For debug: force all OSReservePhys reservations to have a kernel -+ * virtual address */ -+ if(ui32MappingFlags & PVRSRV_HAP_SINGLE_PROCESS) -+ { -+ ui32MappingFlags &= ~PVRSRV_HAP_SINGLE_PROCESS; -+ ui32MappingFlags |= PVRSRV_HAP_MULTI_PROCESS; -+ } -+#endif -+ -+ switch(ui32MappingFlags & PVRSRV_HAP_MAPTYPE_MASK) -+ { -+ case PVRSRV_HAP_KERNEL_ONLY: -+ { -+ /* Currently PVRSRV_HAP_KERNEL_ONLY implies that a kernel virtual -+ * mapping is required for the allocation and no user virtual -+ * mappings are allowed: Note these eat into our limited kernel -+ * virtual address space */ -+ psLinuxMemArea = NewIORemapLinuxMemArea(BasePAddr, uiBytes, ui32MappingFlags); -+ if(!psLinuxMemArea) -+ { -+ return PVRSRV_ERROR_BAD_MAPPING; -+ } -+ break; -+ } -+ case PVRSRV_HAP_SINGLE_PROCESS: -+ { -+ /* Currently this implies that we dont need a kernel virtual -+ * mapping, but will need a user space virtual mapping */ -+ psLinuxMemArea = NewIOLinuxMemArea(BasePAddr, uiBytes, ui32MappingFlags); -+ if(!psLinuxMemArea) -+ { -+ return PVRSRV_ERROR_BAD_MAPPING; -+ } -+ PVRMMapRegisterArea(psLinuxMemArea); -+ break; -+ } -+ case PVRSRV_HAP_MULTI_PROCESS: -+ { -+ /* Currently PVRSRV_HAP_MULTI_PROCESS implies that we need a kernel -+ * virtual mapping and potentially multiple user space virtual mappings. -+ * Beware that the kernel virtual address space is a limited resource. -+ */ -+#if defined(VIVT_CACHE) || defined(__sh__) -+ /* -+ * ARM9 caches are tagged with virtual pages, not physical. As we are going to -+ * share this memory in different address spaces, we don't want it to be cached. -+ * ARM11 has physical tagging, so we can cache this memory without fear of virtual -+ * address aliasing in the TLB, as long as the kernel supports cache colouring for -+ * VIPT architectures. -+ */ -+ ui32MappingFlags &= ~PVRSRV_HAP_CACHED; -+#endif -+ psLinuxMemArea = NewIORemapLinuxMemArea(BasePAddr, uiBytes, ui32MappingFlags); -+ if(!psLinuxMemArea) -+ { -+ return PVRSRV_ERROR_BAD_MAPPING; -+ } -+ PVRMMapRegisterArea(psLinuxMemArea); -+ break; -+ } -+ default: -+ PVR_DPF((PVR_DBG_ERROR,"OSMapPhysToLin : invalid flags 0x%x\n", ui32MappingFlags)); -+ *ppvCpuVAddr = NULL; -+ *phOSMemHandle = (IMG_HANDLE)0; -+ return PVRSRV_ERROR_INVALID_FLAGS; -+ } -+ -+ /* -+ In case of sparse mapping we need to handle back to the BM as it -+ knows the mapping info -+ */ -+ if (ui32MappingFlags & PVRSRV_MEM_SPARSE) -+ { -+ PVR_ASSERT(hBMHandle != IMG_NULL); -+ psLinuxMemArea->hBMHandle = hBMHandle; -+ } -+ -+ *phOSMemHandle = (IMG_HANDLE)psLinuxMemArea; -+ *ppvCpuVAddr = LinuxMemAreaToCpuVAddr(psLinuxMemArea); -+ -+ LinuxMemAreaRegister(psLinuxMemArea); -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ @Function OSUnReservePhys -+ @Description UnRegisters physical memory for user mode mapping -+ @Return TRUE on success, else FALSE -+******************************************************************************/ -+PVRSRV_ERROR -+OSUnReservePhys(IMG_VOID *pvCpuVAddr, -+ IMG_SIZE_T uiBytes, -+ IMG_UINT32 ui32MappingFlags, -+ IMG_HANDLE hOSMemHandle) -+{ -+ LinuxMemArea *psLinuxMemArea; -+ PVRSRV_ERROR eError; -+ -+ PVR_UNREFERENCED_PARAMETER(pvCpuVAddr); -+ PVR_UNREFERENCED_PARAMETER(uiBytes); -+ -+ psLinuxMemArea = (LinuxMemArea *)hOSMemHandle; -+ -+ switch(ui32MappingFlags & PVRSRV_HAP_MAPTYPE_MASK) -+ { -+ case PVRSRV_HAP_KERNEL_ONLY: -+ break; -+ case PVRSRV_HAP_SINGLE_PROCESS: -+ case PVRSRV_HAP_MULTI_PROCESS: -+ { -+ eError = PVRMMapRemoveRegisteredArea(psLinuxMemArea); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s(%p, %" SIZE_T_FMT_LEN "u, 0x%08X, %p) FAILED!", -+ __FUNCTION__, pvCpuVAddr, uiBytes, -+ ui32MappingFlags, hOSMemHandle)); -+ return eError; -+ } -+ break; -+ } -+ default: -+ { -+ PVR_DPF((PVR_DBG_ERROR, "OSUnMapPhysToLin : invalid flags 0x%x", ui32MappingFlags)); -+ return PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ } -+ -+ LinuxMemAreaDeepFree(psLinuxMemArea); -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function OSBaseAllocContigMemory -+ @Description Allocate a block of contiguous virtual non-paged memory. -+ @Input ui32Size - number of bytes to allocate -+ @Output ppvLinAddr - pointer to variable that will receive the linear address of buffer -+ @Return PVRSRV_OK if allocation successed else returns PVRSRV_ERROR_OUT_OF_MEMORY -+ **************************************************************************/ -+PVRSRV_ERROR OSBaseAllocContigMemory(IMG_SIZE_T uiSize, IMG_CPU_VIRTADDR *pvLinAddr, IMG_CPU_PHYADDR *psPhysAddr) -+{ -+#if !defined(NO_HARDWARE) -+ PVR_UNREFERENCED_PARAMETER(uiSize); -+ PVR_UNREFERENCED_PARAMETER(pvLinAddr); -+ PVR_UNREFERENCED_PARAMETER(psPhysAddr); -+ PVR_DPF((PVR_DBG_ERROR, "%s: Not available", __FUNCTION__)); -+ -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+#else -+/* -+ * On Linux, the returned virtual address should be used for CPU access, -+ * and not be remapped into the CPU virtual address using ioremap. The fact -+ * that the RAM is being managed by the kernel, and already has a virtual -+ * address, seems to lead to problems when the attributes of the memory are -+ * changed in the ioremap call (such as from cached to non-cached). -+ */ -+ IMG_VOID *pvKernLinAddr; -+ -+#if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -+ pvKernLinAddr = _KMallocWrapper(uiSize, GFP_KERNEL, __FILE__, __LINE__); -+#else -+ pvKernLinAddr = KMallocWrapper(uiSize, GFP_KERNEL); -+#endif -+ if (!pvKernLinAddr) -+ { -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ -+ *pvLinAddr = pvKernLinAddr; -+ -+ psPhysAddr->uiAddr = virt_to_phys(pvKernLinAddr); -+ -+ return PVRSRV_OK; -+#endif /* !defined(NO_HARDWARE) */ -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function OSBaseFreeContigMemory -+ @Description Frees memory allocated with OSBaseAllocContigMemory -+ @Input LinAddr - pointer to buffer allocated with OSBaseAllocContigMemory -+ **************************************************************************/ -+PVRSRV_ERROR OSBaseFreeContigMemory(IMG_SIZE_T uiSize, IMG_CPU_VIRTADDR pvLinAddr, IMG_CPU_PHYADDR psPhysAddr) -+{ -+#if !defined(NO_HARDWARE) -+ PVR_UNREFERENCED_PARAMETER(uiSize); -+ PVR_UNREFERENCED_PARAMETER(pvLinAddr); -+ PVR_UNREFERENCED_PARAMETER(psPhysAddr.uiAddr); -+ -+ PVR_DPF((PVR_DBG_WARNING, "%s: Not available", __FUNCTION__)); -+#else -+ PVR_UNREFERENCED_PARAMETER(uiSize); -+ PVR_UNREFERENCED_PARAMETER(psPhysAddr.uiAddr); -+ -+ KFreeWrapper(pvLinAddr); -+#endif -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function OSWriteHWReg -+ -+ @Description -+ -+ register access function -+ -+ @input pvLinRegBaseAddr : lin addr of register block base -+ -+ @input ui32Offset : -+ -+ @input ui32Value : -+ -+ @Return none -+ -+******************************************************************************/ -+ -+IMG_UINT32 OSReadHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset) -+{ -+#if !defined(NO_HARDWARE) -+ return (IMG_UINT32) readl((IMG_PBYTE)pvLinRegBaseAddr+ui32Offset); -+#else -+ return *(IMG_UINT32 *)((IMG_PBYTE)pvLinRegBaseAddr+ui32Offset); -+#endif -+} -+ -+IMG_VOID OSWriteHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value) -+{ -+#if !defined(NO_HARDWARE) -+ writel(ui32Value, (IMG_PBYTE)pvLinRegBaseAddr+ui32Offset); -+#else -+ *(IMG_UINT32 *)((IMG_PBYTE)pvLinRegBaseAddr+ui32Offset) = ui32Value; -+#endif -+} -+ -+#if defined(CONFIG_PCI) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)) -+ -+/*! -+****************************************************************************** -+ -+ @Function OSPCISetDev -+ -+ @Description -+ -+ Set a PCI device for subsequent use. -+ -+ @input pvPCICookie : Pointer to OS specific PCI structure/cookie -+ -+ @input eFlags : Flags -+ -+ @Return Pointer to PCI device handle -+ -+******************************************************************************/ -+PVRSRV_PCI_DEV_HANDLE OSPCISetDev(IMG_VOID *pvPCICookie, HOST_PCI_INIT_FLAGS eFlags) -+{ -+ int err; -+ IMG_UINT32 i; -+ PVR_PCI_DEV *psPVRPCI; -+ -+ PVR_TRACE(("OSPCISetDev")); -+ -+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*psPVRPCI), (IMG_VOID **)&psPVRPCI, IMG_NULL, -+ "PCI Device") != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "OSPCISetDev: Couldn't allocate PVR PCI structure")); -+ return IMG_NULL; -+ } -+ -+ psPVRPCI->psPCIDev = (struct pci_dev *)pvPCICookie; -+ psPVRPCI->ePCIFlags = eFlags; -+ -+ err = pci_enable_device(psPVRPCI->psPCIDev); -+ if (err != 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "OSPCISetDev: Couldn't enable device (%d)", err)); -+ return IMG_NULL; -+ } -+ -+ if (psPVRPCI->ePCIFlags & HOST_PCI_INIT_FLAG_BUS_MASTER) /* PRQA S 3358 */ /* misuse of enums */ -+ { -+ pci_set_master(psPVRPCI->psPCIDev); -+ } -+ -+ if (psPVRPCI->ePCIFlags & HOST_PCI_INIT_FLAG_MSI) /* PRQA S 3358 */ /* misuse of enums */ -+ { -+#if defined(CONFIG_PCI_MSI) -+ err = pci_enable_msi(psPVRPCI->psPCIDev); -+ if (err != 0) -+ { -+ PVR_DPF((PVR_DBG_WARNING, "OSPCISetDev: Couldn't enable MSI (%d)", err)); -+ psPVRPCI->ePCIFlags &= ~HOST_PCI_INIT_FLAG_MSI; /* PRQA S 1474,3358,4130 */ /* misuse of enums */ -+ } -+#else -+ PVR_DPF((PVR_DBG_WARNING, "OSPCISetDev: MSI support not enabled in the kernel")); -+#endif -+ } -+ -+ /* Initialise the PCI resource tracking array */ -+ for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) -+ { -+ psPVRPCI->abPCIResourceInUse[i] = IMG_FALSE; -+ } -+ -+ return (PVRSRV_PCI_DEV_HANDLE)psPVRPCI; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function OSPCIAcquireDev -+ -+ @Description -+ -+ Acquire a PCI device for subsequent use. -+ -+ @input ui16VendorID : Vendor PCI ID -+ -+ @input ui16VendorID : Device PCI ID -+ -+ @input eFlags : Flags -+ -+ @Return PVESRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_PCI_DEV_HANDLE OSPCIAcquireDev(IMG_UINT16 ui16VendorID, IMG_UINT16 ui16DeviceID, HOST_PCI_INIT_FLAGS eFlags) -+{ -+ struct pci_dev *psPCIDev; -+ -+ psPCIDev = pci_get_device(ui16VendorID, ui16DeviceID, NULL); -+ if (psPCIDev == NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "OSPCIAcquireDev: Couldn't acquire device")); -+ return IMG_NULL; -+ } -+ -+ return OSPCISetDev((IMG_VOID *)psPCIDev, eFlags); -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function OSPCIIRQ -+ -+ @Description -+ -+ Get the interrupt number for the device. -+ -+ @input hPVRPCI : PCI device handle -+ -+ @input pui32IRQ : Pointer to where the interrupt number should be returned -+ -+ @Return PVESRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR OSPCIIRQ(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 *pui32IRQ) -+{ -+ PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI; -+ -+ *pui32IRQ = psPVRPCI->psPCIDev->irq; -+ -+ return PVRSRV_OK; -+} -+ -+/* Functions supported by OSPCIAddrRangeFunc */ -+enum HOST_PCI_ADDR_RANGE_FUNC -+{ -+ HOST_PCI_ADDR_RANGE_FUNC_LEN, -+ HOST_PCI_ADDR_RANGE_FUNC_START, -+ HOST_PCI_ADDR_RANGE_FUNC_END, -+ HOST_PCI_ADDR_RANGE_FUNC_REQUEST, -+ HOST_PCI_ADDR_RANGE_FUNC_RELEASE -+}; -+ -+/*! -+****************************************************************************** -+ -+ @Function OSPCIAddrRangeFunc -+ -+ @Description -+ -+ Internal support function for various address range related functions -+ -+ @input eFunc : Function to perform -+ -+ @input hPVRPCI : PCI device handle -+ -+ @input ui32Index : Address range index -+ -+ @Return function dependent -+ -+******************************************************************************/ -+static IMG_UINT32 OSPCIAddrRangeFunc(enum HOST_PCI_ADDR_RANGE_FUNC eFunc, -+ PVRSRV_PCI_DEV_HANDLE hPVRPCI, -+ IMG_UINT32 ui32Index) -+{ -+ PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI; -+ -+ if (ui32Index >= DEVICE_COUNT_RESOURCE) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "OSPCIAddrRangeFunc: Index out of range")); -+ return 0; -+ -+ } -+ -+ switch (eFunc) -+ { -+ case HOST_PCI_ADDR_RANGE_FUNC_LEN: -+ return pci_resource_len(psPVRPCI->psPCIDev, ui32Index); -+ case HOST_PCI_ADDR_RANGE_FUNC_START: -+ return pci_resource_start(psPVRPCI->psPCIDev, ui32Index); -+ case HOST_PCI_ADDR_RANGE_FUNC_END: -+ return pci_resource_end(psPVRPCI->psPCIDev, ui32Index); -+ case HOST_PCI_ADDR_RANGE_FUNC_REQUEST: -+ { -+ int err; -+ -+ err = pci_request_region(psPVRPCI->psPCIDev, (IMG_INT)ui32Index, PVRSRV_MODNAME); -+ if (err != 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "OSPCIAddrRangeFunc: pci_request_region_failed (%d)", err)); -+ return 0; -+ } -+ psPVRPCI->abPCIResourceInUse[ui32Index] = IMG_TRUE; -+ return 1; -+ } -+ case HOST_PCI_ADDR_RANGE_FUNC_RELEASE: -+ if (psPVRPCI->abPCIResourceInUse[ui32Index]) -+ { -+ pci_release_region(psPVRPCI->psPCIDev, (IMG_INT)ui32Index); -+ psPVRPCI->abPCIResourceInUse[ui32Index] = IMG_FALSE; -+ } -+ return 1; -+ default: -+ PVR_DPF((PVR_DBG_ERROR, "OSPCIAddrRangeFunc: Unknown function")); -+ break; -+ } -+ -+ return 0; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function OSPCIAddrRangeLen -+ -+ @Description -+ -+ Returns length of a given address range length -+ -+ @input hPVRPCI : PCI device handle -+ -+ @input ui32Index : Address range index -+ -+ @Return Length of address range, or 0 if no such range -+ -+******************************************************************************/ -+IMG_UINT32 OSPCIAddrRangeLen(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index) -+{ -+ return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_LEN, hPVRPCI, ui32Index); -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function OSPCIAddrRangeStart -+ -+ @Description -+ -+ Returns the start of a given address range -+ -+ @input hPVRPCI : PCI device handle -+ -+ @input ui32Index : Address range index -+ -+ @Return Start of address range, or 0 if no such range -+ -+******************************************************************************/ -+IMG_UINT32 OSPCIAddrRangeStart(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index) -+{ -+ return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_START, hPVRPCI, ui32Index); -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function OSPCIAddrRangeEnd -+ -+ @Description -+ -+ Returns the end of a given address range -+ -+ @input hPVRPCI : PCI device handle"ayy -+ -+ @input ui32Index : Address range index -+ -+ @Return End of address range, or 0 if no such range -+ -+******************************************************************************/ -+IMG_UINT32 OSPCIAddrRangeEnd(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index) -+{ -+ return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_END, hPVRPCI, ui32Index); -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function OSPCIRequestAddrRange -+ -+ @Description -+ -+ Request a given address range index for subsequent use -+ -+ @input hPVRPCI : PCI device handle -+ -+ @input ui32Index : Address range index -+ -+ @Return PVESRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR OSPCIRequestAddrRange(PVRSRV_PCI_DEV_HANDLE hPVRPCI, -+ IMG_UINT32 ui32Index) -+{ -+ return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_REQUEST, hPVRPCI, ui32Index) == 0 ? PVRSRV_ERROR_PCI_CALL_FAILED : PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function OSPCIReleaseAddrRange -+ -+ @Description -+ -+ Release a given address range that is no longer being used -+ -+ @input hPVRPCI : PCI device handle -+ -+ @input ui32Index : Address range index -+ -+ @Return PVESRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR OSPCIReleaseAddrRange(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index) -+{ -+ return OSPCIAddrRangeFunc(HOST_PCI_ADDR_RANGE_FUNC_RELEASE, hPVRPCI, ui32Index) == 0 ? PVRSRV_ERROR_PCI_CALL_FAILED : PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function OSPCIReleaseDev -+ -+ @Description -+ -+ Release a PCI device that is no longer being used -+ -+ @input hPVRPCI : PCI device handle -+ -+ @Return PVESRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR OSPCIReleaseDev(PVRSRV_PCI_DEV_HANDLE hPVRPCI) -+{ -+ PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI; -+ int i; -+ -+ PVR_TRACE(("OSPCIReleaseDev")); -+ -+ /* Release all PCI regions that are currently in use */ -+ for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) -+ { -+ if (psPVRPCI->abPCIResourceInUse[i]) -+ { -+ PVR_TRACE(("OSPCIReleaseDev: Releasing Address range %d", i)); -+ pci_release_region(psPVRPCI->psPCIDev, i); -+ psPVRPCI->abPCIResourceInUse[i] = IMG_FALSE; -+ } -+ } -+ -+#if defined(CONFIG_PCI_MSI) -+ if (psPVRPCI->ePCIFlags & HOST_PCI_INIT_FLAG_MSI) /* PRQA S 3358 */ /* misuse of enums */ -+ { -+ pci_disable_msi(psPVRPCI->psPCIDev); -+ } -+#endif -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)) -+ if (psPVRPCI->ePCIFlags & HOST_PCI_INIT_FLAG_BUS_MASTER) /* PRQA S 3358 */ /* misuse of enums */ -+ { -+ pci_clear_master(psPVRPCI->psPCIDev); -+ } -+#endif -+ pci_disable_device(psPVRPCI->psPCIDev); -+ -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*psPVRPCI), (IMG_VOID *)psPVRPCI, IMG_NULL); -+ /*not nulling pointer, copy on stack*/ -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function OSPCISuspendDev -+ -+ @Description -+ -+ Prepare PCI device to be turned off by power management -+ -+ @input hPVRPCI : PCI device handle -+ -+ @Return PVESRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR OSPCISuspendDev(PVRSRV_PCI_DEV_HANDLE hPVRPCI) -+{ -+ PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI; -+ int i; -+ int err; -+ -+ PVR_TRACE(("OSPCISuspendDev")); -+ -+ /* Release all PCI regions that are currently in use */ -+ for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) -+ { -+ if (psPVRPCI->abPCIResourceInUse[i]) -+ { -+ pci_release_region(psPVRPCI->psPCIDev, i); -+ } -+ } -+ -+ err = pci_save_state(psPVRPCI->psPCIDev); -+ if (err != 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "OSPCISuspendDev: pci_save_state_failed (%d)", err)); -+ return PVRSRV_ERROR_PCI_CALL_FAILED; -+ } -+ -+ pci_disable_device(psPVRPCI->psPCIDev); -+ -+ err = pci_set_power_state(psPVRPCI->psPCIDev, pci_choose_state(psPVRPCI->psPCIDev, PMSG_SUSPEND)); -+ switch(err) -+ { -+ case 0: -+ break; -+ case -EIO: -+ PVR_DPF((PVR_DBG_WARNING, "OSPCISuspendDev: device doesn't support PCI PM")); -+ break; -+ case -EINVAL: -+ PVR_DPF((PVR_DBG_ERROR, "OSPCISuspendDev: can't enter requested power state")); -+ break; -+ default: -+ PVR_DPF((PVR_DBG_ERROR, "OSPCISuspendDev: pci_set_power_state failed (%d)", err)); -+ break; -+ } -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function OSPCIResumeDev -+ -+ @Description -+ -+ Prepare a PCI device to be resumed by power management -+ -+ @input hPVRPCI : PCI device handle -+ -+ @input pvPCICookie : Pointer to OS specific PCI structure/cookie -+ -+ @input eFlags : Flags -+ -+ @Return PVESRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR OSPCIResumeDev(PVRSRV_PCI_DEV_HANDLE hPVRPCI) -+{ -+ PVR_PCI_DEV *psPVRPCI = (PVR_PCI_DEV *)hPVRPCI; -+ int err; -+ int i; -+ -+ PVR_TRACE(("OSPCIResumeDev")); -+ -+ err = pci_set_power_state(psPVRPCI->psPCIDev, pci_choose_state(psPVRPCI->psPCIDev, PMSG_ON)); -+ switch(err) -+ { -+ case 0: -+ break; -+ case -EIO: -+ PVR_DPF((PVR_DBG_WARNING, "OSPCIResumeDev: device doesn't support PCI PM")); -+ break; -+ case -EINVAL: -+ PVR_DPF((PVR_DBG_ERROR, "OSPCIResumeDev: can't enter requested power state")); -+ return PVRSRV_ERROR_UNKNOWN_POWER_STATE; -+ default: -+ PVR_DPF((PVR_DBG_ERROR, "OSPCIResumeDev: pci_set_power_state failed (%d)", err)); -+ return PVRSRV_ERROR_UNKNOWN_POWER_STATE; -+ } -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) -+ pci_restore_state(psPVRPCI->psPCIDev); -+#else -+ err = pci_restore_state(psPVRPCI->psPCIDev); -+ if (err != 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "OSPCIResumeDev: pci_restore_state failed (%d)", err)); -+ return PVRSRV_ERROR_PCI_CALL_FAILED; -+ } -+#endif -+ -+ err = pci_enable_device(psPVRPCI->psPCIDev); -+ if (err != 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "OSPCIResumeDev: Couldn't enable device (%d)", err)); -+ return PVRSRV_ERROR_PCI_CALL_FAILED; -+ } -+ -+ if (psPVRPCI->ePCIFlags & HOST_PCI_INIT_FLAG_BUS_MASTER) /* PRQA S 3358 */ /* misuse of enums */ -+ pci_set_master(psPVRPCI->psPCIDev); -+ -+ /* Restore the PCI resource tracking array */ -+ for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) -+ { -+ if (psPVRPCI->abPCIResourceInUse[i]) -+ { -+ err = pci_request_region(psPVRPCI->psPCIDev, i, PVRSRV_MODNAME); -+ if (err != 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "OSPCIResumeDev: pci_request_region_failed (region %d, error %d)", i, err)); -+ } -+ } -+ -+ } -+ -+ return PVRSRV_OK; -+} -+ -+#endif /* #if defined(CONFIG_PCI) && (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)) */ -+ -+#define OS_MAX_TIMERS 8 -+ -+/* Timer callback strucure used by OSAddTimer */ -+typedef struct TIMER_CALLBACK_DATA_TAG -+{ -+ IMG_BOOL bInUse; -+ PFN_TIMER_FUNC pfnTimerFunc; -+ IMG_VOID *pvData; -+ struct timer_list sTimer; -+ IMG_UINT32 ui32Delay; -+ IMG_BOOL bActive; -+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES) || defined(PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE) -+ struct work_struct sWork; -+#endif -+}TIMER_CALLBACK_DATA; -+ -+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES) -+static struct workqueue_struct *psTimerWorkQueue; -+#endif -+ -+static TIMER_CALLBACK_DATA sTimers[OS_MAX_TIMERS]; -+ -+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES) || defined(PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE) -+DEFINE_MUTEX(sTimerStructLock); -+#else -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39)) -+/* The lock is used to control access to sTimers */ -+/* PRQA S 0671,0685 1 */ /* C99 macro not understood by QAC */ -+static spinlock_t sTimerStructLock = SPIN_LOCK_UNLOCKED; -+#else -+static DEFINE_SPINLOCK(sTimerStructLock); -+#endif -+#endif -+ -+static void OSTimerCallbackBody(TIMER_CALLBACK_DATA *psTimerCBData) -+{ -+ if (!psTimerCBData->bActive) -+ return; -+ -+ /* call timer callback */ -+ psTimerCBData->pfnTimerFunc(psTimerCBData->pvData); -+ -+ /* reset timer */ -+ mod_timer(&psTimerCBData->sTimer, psTimerCBData->ui32Delay + jiffies); -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function OSTimerCallbackWrapper -+ -+ @Description -+ -+ OS specific timer callback wrapper function -+ -+ @Input ui32Data : timer callback data -+ -+ @Return NONE -+ -+******************************************************************************/ -+static IMG_VOID OSTimerCallbackWrapper(IMG_UINTPTR_T uiData) -+{ -+ TIMER_CALLBACK_DATA *psTimerCBData = (TIMER_CALLBACK_DATA*)uiData; -+ -+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES) || defined(PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE) -+ int res; -+ -+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES) -+ res = queue_work(psTimerWorkQueue, &psTimerCBData->sWork); -+#else -+ res = schedule_work(&psTimerCBData->sWork); -+#endif -+ if (res == 0) -+ { -+ PVR_DPF((PVR_DBG_WARNING, "OSTimerCallbackWrapper: work already queued")); -+ } -+#else -+ OSTimerCallbackBody(psTimerCBData); -+#endif -+} -+ -+ -+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES) || defined(PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE) -+static void OSTimerWorkQueueCallBack(struct work_struct *psWork) -+{ -+ TIMER_CALLBACK_DATA *psTimerCBData = container_of(psWork, TIMER_CALLBACK_DATA, sWork); -+ -+ OSTimerCallbackBody(psTimerCBData); -+} -+#endif -+ -+/*! -+****************************************************************************** -+ -+ @Function OSAddTimer -+ -+ @Description -+ -+ OS specific function to install a timer callback -+ -+ @Input pfnTimerFunc : timer callback -+ -+ @Input *pvData :callback data -+ -+ @Input ui32MsTimeout: callback period -+ -+ @Return IMG_HANDLE : valid handle success, NULL failure -+ -+******************************************************************************/ -+IMG_HANDLE OSAddTimer(PFN_TIMER_FUNC pfnTimerFunc, IMG_VOID *pvData, IMG_UINT32 ui32MsTimeout) -+{ -+ TIMER_CALLBACK_DATA *psTimerCBData; -+ IMG_UINTPTR_T ui; -+#if !(defined(PVR_LINUX_TIMERS_USING_WORKQUEUES) || defined(PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE)) -+ unsigned long ulLockFlags; -+#endif -+ -+ /* check callback */ -+ if(!pfnTimerFunc) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "OSAddTimer: passed invalid callback")); -+ return IMG_NULL; -+ } -+ -+ /* Allocate timer callback data structure */ -+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES) || defined(PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE) -+ mutex_lock(&sTimerStructLock); -+#else -+ spin_lock_irqsave(&sTimerStructLock, ulLockFlags); -+#endif -+ for (ui = 0; ui < OS_MAX_TIMERS; ui++) -+ { -+ psTimerCBData = &sTimers[ui]; -+ if (!psTimerCBData->bInUse) -+ { -+ psTimerCBData->bInUse = IMG_TRUE; -+ break; -+ } -+ } -+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES) || defined(PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE) -+ mutex_unlock(&sTimerStructLock); -+#else -+ spin_unlock_irqrestore(&sTimerStructLock, ulLockFlags); -+#endif -+ if (ui >= OS_MAX_TIMERS) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "OSAddTimer: all timers are in use")); -+ return IMG_NULL; -+ } -+ -+ psTimerCBData->pfnTimerFunc = pfnTimerFunc; -+ psTimerCBData->pvData = pvData; -+ psTimerCBData->bActive = IMG_FALSE; -+ -+ /* -+ HZ = ticks per second -+ ui32MsTimeout = required ms delay -+ ticks = (Hz * ui32MsTimeout) / 1000 -+ */ -+ psTimerCBData->ui32Delay = ((HZ * ui32MsTimeout) < 1000) -+ ? 1 -+ : ((HZ * ui32MsTimeout) / 1000); -+ /* initialise object */ -+ init_timer(&psTimerCBData->sTimer); -+ -+ /* setup timer object */ -+ /* PRQA S 0307,0563 1 */ /* ignore warning about inconpartible ptr casting */ -+ psTimerCBData->sTimer.function = (IMG_VOID *)OSTimerCallbackWrapper; -+ psTimerCBData->sTimer.data = (IMG_UINTPTR_T)psTimerCBData; -+ -+ return (IMG_HANDLE)(ui + 1); -+} -+ -+ -+static inline TIMER_CALLBACK_DATA *GetTimerStructure(IMG_HANDLE hTimer) -+{ -+ IMG_UINTPTR_T ui = ((IMG_UINTPTR_T)hTimer) - 1; -+ -+ PVR_ASSERT(ui < OS_MAX_TIMERS); -+ -+ return &sTimers[ui]; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function OSRemoveTimer -+ -+ @Description -+ -+ OS specific function to remove a timer callback -+ -+ @Input hTimer : timer handle -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+PVRSRV_ERROR OSRemoveTimer (IMG_HANDLE hTimer) -+{ -+ TIMER_CALLBACK_DATA *psTimerCBData = GetTimerStructure(hTimer); -+ -+ PVR_ASSERT(psTimerCBData->bInUse); -+ PVR_ASSERT(!psTimerCBData->bActive); -+ -+ /* free timer callback data struct */ -+ psTimerCBData->bInUse = IMG_FALSE; -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function OSEnableTimer -+ -+ @Description -+ -+ OS specific function to enable a timer callback -+ -+ @Input hTimer : timer handle -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+PVRSRV_ERROR OSEnableTimer (IMG_HANDLE hTimer) -+{ -+ TIMER_CALLBACK_DATA *psTimerCBData = GetTimerStructure(hTimer); -+ -+ PVR_ASSERT(psTimerCBData->bInUse); -+ PVR_ASSERT(!psTimerCBData->bActive); -+ -+ /* Start timer arming */ -+ psTimerCBData->bActive = IMG_TRUE; -+ -+ /* set the expire time */ -+ psTimerCBData->sTimer.expires = psTimerCBData->ui32Delay + jiffies; -+ -+ /* Add the timer to the list */ -+ add_timer(&psTimerCBData->sTimer); -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function OSDisableTimer -+ -+ @Description -+ -+ OS specific function to disable a timer callback -+ -+ @Input hTimer : timer handle -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+PVRSRV_ERROR OSDisableTimer (IMG_HANDLE hTimer) -+{ -+ TIMER_CALLBACK_DATA *psTimerCBData = GetTimerStructure(hTimer); -+ -+ PVR_ASSERT(psTimerCBData->bInUse); -+ PVR_ASSERT(psTimerCBData->bActive); -+ -+ /* Stop timer from arming */ -+ psTimerCBData->bActive = IMG_FALSE; -+ smp_mb(); -+ -+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES) -+ flush_workqueue(psTimerWorkQueue); -+#endif -+#if defined(PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE) -+ flush_scheduled_work(); -+#endif -+ -+ /* remove timer */ -+ del_timer_sync(&psTimerCBData->sTimer); -+ -+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES) -+ /* -+ * This second flush is to catch the case where the timer ran -+ * before we managed to delete it, in which case, it will have -+ * queued more work for the workqueue. Since the bActive flag -+ * has been cleared, this second flush won't result in the -+ * timer being rearmed. -+ */ -+ flush_workqueue(psTimerWorkQueue); -+#endif -+#if defined(PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE) -+ flush_scheduled_work(); -+#endif -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function OSEventObjectCreateKM -+ -+ @Description -+ -+ OS specific function to create an event object -+ -+ @Input pszName : Globally unique event object name (if null name must be autogenerated) -+ -+ @Output psEventObject : OS event object info structure -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+PVRSRV_ERROR OSEventObjectCreateKM(const IMG_CHAR *pszName, PVRSRV_EVENTOBJECT *psEventObject) -+{ -+ -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ -+ if(psEventObject) -+ { -+ if(pszName) -+ { -+ /* copy over the event object name */ -+ strncpy(psEventObject->szName, pszName, EVENTOBJNAME_MAXLENGTH); -+ } -+ else -+ { -+ /* autogenerate a name */ -+ static IMG_UINT16 ui16NameIndex = 0; -+ snprintf(psEventObject->szName, EVENTOBJNAME_MAXLENGTH, "PVRSRV_EVENTOBJECT_%d", ui16NameIndex++); -+ } -+ -+ if(LinuxEventObjectListCreate(&psEventObject->hOSEventKM) != PVRSRV_OK) -+ { -+ eError = PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ -+ } -+ else -+ { -+ PVR_DPF((PVR_DBG_ERROR, "OSEventObjectCreateKM: psEventObject is not a valid pointer")); -+ eError = PVRSRV_ERROR_UNABLE_TO_CREATE_EVENT; -+ } -+ -+ return eError; -+ -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function OSEventObjectDestroyKM -+ -+ @Description -+ -+ OS specific function to destroy an event object -+ -+ @Input psEventObject : OS event object info structure -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+PVRSRV_ERROR OSEventObjectDestroyKM(PVRSRV_EVENTOBJECT *psEventObject) -+{ -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ -+ if(psEventObject) -+ { -+ if(psEventObject->hOSEventKM) -+ { -+ LinuxEventObjectListDestroy(psEventObject->hOSEventKM); -+ } -+ else -+ { -+ PVR_DPF((PVR_DBG_ERROR, "OSEventObjectDestroyKM: hOSEventKM is not a valid pointer")); -+ eError = PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ } -+ else -+ { -+ PVR_DPF((PVR_DBG_ERROR, "OSEventObjectDestroyKM: psEventObject is not a valid pointer")); -+ eError = PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ return eError; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function OSEventObjectWaitKM -+ -+ @Description -+ -+ OS specific function to wait for an event object. Called from client -+ -+ @Input hOSEventKM : OS and kernel specific handle to event object -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+PVRSRV_ERROR OSEventObjectWaitKM(IMG_HANDLE hOSEventKM) -+{ -+ PVRSRV_ERROR eError; -+ -+ if(hOSEventKM) -+ { -+ eError = LinuxEventObjectWait(hOSEventKM, EVENT_OBJECT_TIMEOUT_MS); -+ } -+ else -+ { -+ PVR_DPF((PVR_DBG_ERROR, "OSEventObjectWaitKM: hOSEventKM is not a valid handle")); -+ eError = PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ return eError; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function OSEventObjectOpenKM -+ -+ @Description -+ -+ OS specific function to open an event object. Called from client -+ -+ @Input psEventObject : Pointer to an event object -+ @Output phOSEvent : OS and kernel specific handle to event object -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+PVRSRV_ERROR OSEventObjectOpenKM(PVRSRV_EVENTOBJECT *psEventObject, -+ IMG_HANDLE *phOSEvent) -+{ -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ -+ if(psEventObject) -+ { -+ if(LinuxEventObjectAdd(psEventObject->hOSEventKM, phOSEvent) != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectAdd: failed")); -+ eError = PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ } -+ else -+ { -+ PVR_DPF((PVR_DBG_ERROR, "OSEventObjectCreateKM: psEventObject is not a valid pointer")); -+ eError = PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ return eError; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function OSEventObjectCloseKM -+ -+ @Description -+ -+ OS specific function to close an event object. Called from client -+ -+ @Input psEventObject : Pointer to an event object -+ @OInput hOSEventKM : OS and kernel specific handle to event object -+ -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+PVRSRV_ERROR OSEventObjectCloseKM(PVRSRV_EVENTOBJECT *psEventObject, -+ IMG_HANDLE hOSEventKM) -+{ -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ -+ if(psEventObject) -+ { -+ if(LinuxEventObjectDelete(psEventObject->hOSEventKM, hOSEventKM) != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectDelete: failed")); -+ eError = PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ } -+ else -+ { -+ PVR_DPF((PVR_DBG_ERROR, "OSEventObjectDestroyKM: psEventObject is not a valid pointer")); -+ eError = PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ return eError; -+ -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function OSEventObjectSignalKM -+ -+ @Description -+ -+ OS specific function to 'signal' an event object. Called from L/MISR -+ -+ @Input hOSEventKM : OS and kernel specific handle to event object -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+PVRSRV_ERROR OSEventObjectSignalKM(IMG_HANDLE hOSEventKM) -+{ -+ PVRSRV_ERROR eError; -+ -+ if(hOSEventKM) -+ { -+ eError = LinuxEventObjectSignal(hOSEventKM); -+ } -+ else -+ { -+ PVR_DPF((PVR_DBG_ERROR, "OSEventObjectSignalKM: hOSEventKM is not a valid handle")); -+ eError = PVRSRV_ERROR_INVALID_PARAMS; -+ } -+ -+ return eError; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function OSProcHasPrivSrvInit -+ -+ @Description -+ -+ Does the process have sufficient privileges to initialise services? -+ -+ @Input none -+ -+ @Return IMG_BOOL : -+ -+******************************************************************************/ -+IMG_BOOL OSProcHasPrivSrvInit(IMG_VOID) -+{ -+ return (capable(CAP_SYS_MODULE) != 0) ? IMG_TRUE : IMG_FALSE; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function OSCopyToUser -+ -+ @Description -+ -+ Copy a block of data into user space -+ -+ @Input pvSrc -+ -+ @Output pvDest -+ -+ @Input ui32Bytes -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+PVRSRV_ERROR OSCopyToUser(IMG_PVOID pvProcess, -+ IMG_VOID *pvDest, -+ IMG_VOID *pvSrc, -+ IMG_SIZE_T uiBytes) -+{ -+ PVR_UNREFERENCED_PARAMETER(pvProcess); -+ -+ if(pvr_copy_to_user(pvDest, pvSrc, uiBytes)==0) -+ return PVRSRV_OK; -+ else -+ return PVRSRV_ERROR_FAILED_TO_COPY_VIRT_MEMORY; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function OSCopyFromUser -+ -+ @Description -+ -+ Copy a block of data from the user space -+ -+ @Output pvDest -+ -+ @Input pvSrc -+ -+ @Input ui32Bytes -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+PVRSRV_ERROR OSCopyFromUser( IMG_PVOID pvProcess, -+ IMG_VOID *pvDest, -+ IMG_VOID *pvSrc, -+ IMG_SIZE_T uiBytes) -+{ -+ PVR_UNREFERENCED_PARAMETER(pvProcess); -+ -+ if(pvr_copy_from_user(pvDest, pvSrc, uiBytes)==0) -+ return PVRSRV_OK; -+ else -+ return PVRSRV_ERROR_FAILED_TO_COPY_VIRT_MEMORY; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function OSAccessOK -+ -+ @Description -+ -+ Checks if a user space pointer is valide -+ -+ @Input eVerification -+ -+ @Input pvUserPtr -+ -+ @Input ui32Bytes -+ -+ @Return IMG_BOOL : -+ -+******************************************************************************/ -+IMG_BOOL OSAccessOK(IMG_VERIFY_TEST eVerification, IMG_VOID *pvUserPtr, IMG_SIZE_T uiBytes) -+{ -+ IMG_INT linuxType; -+ -+ if (eVerification == PVR_VERIFY_READ) -+ { -+ linuxType = VERIFY_READ; -+ } -+ else -+ { -+ PVR_ASSERT(eVerification == PVR_VERIFY_WRITE); -+ linuxType = VERIFY_WRITE; -+ } -+ -+ return access_ok(linuxType, pvUserPtr, uiBytes); -+} -+ -+typedef enum _eWrapMemType_ -+{ -+ WRAP_TYPE_NULL = 0, -+ WRAP_TYPE_GET_USER_PAGES, -+ WRAP_TYPE_FIND_VMA -+} eWrapMemType; -+ -+typedef struct _sWrapMemInfo_ -+{ -+ eWrapMemType eType; -+ IMG_INT iNumPages; -+ IMG_INT iNumPagesMapped; -+ struct page **ppsPages; -+ IMG_SYS_PHYADDR *psPhysAddr; -+ IMG_INT iPageOffset; -+#if defined(DEBUG) -+ IMG_UINTPTR_T uStartAddr; -+ IMG_UINTPTR_T uBeyondEndAddr; -+ struct vm_area_struct *psVMArea; -+#endif -+} sWrapMemInfo; -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function *CPUVAddrToPFN -+ -+ @Description -+ -+ Find the PFN associated with a given CPU virtual address, and return -+ the associated page structure, if it exists. -+ The page in question must be present (i.e. no fault handling required), -+ and must be writable. A get_page is done on the returned page structure. -+ -+ @Input psVMArea - pointer to VM area structure -+ uCPUVAddr - CPU virtual address -+ pui32PFN - Pointer to returned PFN. -+ ppsPAge - Pointer to returned page structure pointer. -+ -+ @Output *pui32PFN - Set to PFN -+ *ppsPage - Pointer to the page structure if present, else NULL. -+ @Return IMG_TRUE if PFN lookup was succesful. -+ -+******************************************************************************/ -+static IMG_BOOL CPUVAddrToPFN(struct vm_area_struct *psVMArea, IMG_UINTPTR_T uCPUVAddr, IMG_UINT32 *pui32PFN, struct page **ppsPage) -+{ -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,10)) -+ pgd_t *psPGD; -+ pud_t *psPUD; -+ pmd_t *psPMD; -+ pte_t *psPTE; -+ struct mm_struct *psMM = psVMArea->vm_mm; -+ spinlock_t *psPTLock; -+ IMG_BOOL bRet = IMG_FALSE; -+ -+ *pui32PFN = 0; -+ *ppsPage = NULL; -+ -+ psPGD = pgd_offset(psMM, uCPUVAddr); -+ if (pgd_none(*psPGD) || pgd_bad(*psPGD)) -+ return bRet; -+ -+ psPUD = pud_offset(psPGD, uCPUVAddr); -+ if (pud_none(*psPUD) || pud_bad(*psPUD)) -+ return bRet; -+ -+ psPMD = pmd_offset(psPUD, uCPUVAddr); -+ if (pmd_none(*psPMD) || pmd_bad(*psPMD)) -+ return bRet; -+ -+ psPTE = (pte_t *)pte_offset_map_lock(psMM, psPMD, uCPUVAddr, &psPTLock); -+ -+ if ((pte_none(*psPTE) == 0) && (pte_present(*psPTE) != 0) && (pte_write(*psPTE) != 0)) -+ { -+ *pui32PFN = pte_pfn(*psPTE); -+ bRet = IMG_TRUE; -+ -+ if (pfn_valid(*pui32PFN)) -+ { -+ *ppsPage = pfn_to_page(*pui32PFN); -+ -+ get_page(*ppsPage); -+ } -+ } -+ -+ pte_unmap_unlock(psPTE, psPTLock); -+ -+ return bRet; -+#else -+ return IMG_FALSE; -+#endif -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function OSReleasePhysPageAddr -+ -+ @Description -+ -+ Release wrapped memory. -+ -+ @Input hOSWrapMem : Driver cookie -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR OSReleasePhysPageAddr(IMG_HANDLE hOSWrapMem) -+{ -+ sWrapMemInfo *psInfo = (sWrapMemInfo *)hOSWrapMem; -+ IMG_INT i; -+ -+ if (psInfo == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_WARNING, -+ "OSReleasePhysPageAddr: called with null wrap handle")); -+ return PVRSRV_OK; -+ } -+ -+ switch (psInfo->eType) -+ { -+ case WRAP_TYPE_NULL: -+ { -+ PVR_DPF((PVR_DBG_WARNING, -+ "OSReleasePhysPageAddr: called with wrap type WRAP_TYPE_NULL")); -+ break; -+ } -+ case WRAP_TYPE_GET_USER_PAGES: -+ { -+ for (i = 0; i < psInfo->iNumPagesMapped; i++) -+ { -+ struct page *psPage = psInfo->ppsPages[i]; -+ -+ PVR_ASSERT(psPage != NULL); -+ -+ /* -+ * If the number of pages mapped is not the same as -+ * the number of pages in the address range, then -+ * get_user_pages must have failed, so we are cleaning -+ * up after failure, and the pages can't be dirty. -+ */ -+ if (psInfo->iNumPagesMapped == psInfo->iNumPages) -+ { -+ if (!PageReserved(psPage)) -+ { -+ SetPageDirty(psPage); -+ } -+ } -+ page_cache_release(psPage); -+ } -+ break; -+ } -+ case WRAP_TYPE_FIND_VMA: -+ { -+ for (i = 0; i < psInfo->iNumPages; i++) -+ { -+ if (psInfo->ppsPages[i] != IMG_NULL) -+ { -+ put_page(psInfo->ppsPages[i]); -+ } -+ } -+ break; -+ } -+ default: -+ { -+ PVR_DPF((PVR_DBG_ERROR, -+ "OSReleasePhysPageAddr: Unknown wrap type (%d)", psInfo->eType)); -+ return PVRSRV_ERROR_INVALID_WRAP_TYPE; -+ } -+ } -+ -+ if (psInfo->ppsPages != IMG_NULL) -+ { -+ kfree(psInfo->ppsPages); -+ } -+ -+ if (psInfo->psPhysAddr != IMG_NULL) -+ { -+ kfree(psInfo->psPhysAddr); -+ } -+ -+ kfree(psInfo); -+ -+ return PVRSRV_OK; -+} -+ -+#if defined(CONFIG_TI_TILER) || defined(CONFIG_DRM_OMAP_DMM_TILER) -+ -+static IMG_UINT32 CPUAddrToTilerPhy(IMG_UINT32 uiAddr) -+{ -+ IMG_UINT32 ui32PhysAddr = 0; -+ pte_t *ptep, pte; -+ pgd_t *pgd; -+ pmd_t *pmd; -+ pud_t *pud; -+ -+ pgd = pgd_offset(current->mm, uiAddr); -+ if (pgd_none(*pgd) || pgd_bad(*pgd)) -+ goto err_out; -+ -+ pud = pud_offset(pgd, uiAddr); -+ if (pud_none(*pud) || pud_bad(*pud)) -+ goto err_out; -+ -+ pmd = pmd_offset(pud, uiAddr); -+ if (pmd_none(*pmd) || pmd_bad(*pmd)) -+ goto err_out; -+ -+ ptep = pte_offset_map(pmd, uiAddr); -+ if (!ptep) -+ goto err_out; -+ -+ pte = *ptep; -+ if (!pte_present(pte)) -+ goto err_out; -+ -+ ui32PhysAddr = (pte & PAGE_MASK) | (~PAGE_MASK & uiAddr); -+ -+ /* If the physAddr is not in the TILER physical range -+ * then we don't proceed. -+ */ -+ if (ui32PhysAddr < 0x60000000 && ui32PhysAddr > 0x7fffffff) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "CPUAddrToTilerPhy: Not in tiler range")); -+ ui32PhysAddr = 0; -+ goto err_out; -+ } -+ -+err_out: -+ return ui32PhysAddr; -+} -+ -+#endif /* defined(CONFIG_TI_TILER) && defined(CONFIG_DRM_OMAP_DMM_TILER) */ -+ -+/*! -+****************************************************************************** -+ -+ @Function OSAcquirePhysPageAddr -+ -+ @Description -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR OSAcquirePhysPageAddr(IMG_VOID *pvCPUVAddr, -+ IMG_SIZE_T uiBytes, -+ IMG_SYS_PHYADDR *psSysPAddr, -+ IMG_HANDLE *phOSWrapMem) -+{ -+ IMG_UINTPTR_T uStartAddrOrig = (IMG_UINTPTR_T) pvCPUVAddr; -+ IMG_SIZE_T uAddrRangeOrig = uiBytes; -+ IMG_UINTPTR_T uBeyondEndAddrOrig = uStartAddrOrig + uAddrRangeOrig; -+ IMG_UINTPTR_T uStartAddr; -+ IMG_SIZE_T uAddrRange; -+ IMG_UINTPTR_T uBeyondEndAddr; -+ IMG_UINTPTR_T uAddr; -+ IMG_INT i; -+ struct vm_area_struct *psVMArea; -+ sWrapMemInfo *psInfo = NULL; -+ IMG_BOOL bHavePageStructs = IMG_FALSE; -+ IMG_BOOL bHaveNoPageStructs = IMG_FALSE; -+ IMG_BOOL bMMapSemHeld = IMG_FALSE; -+ PVRSRV_ERROR eError = PVRSRV_ERROR_OUT_OF_MEMORY; -+ -+ /* Align start and end addresses to page boundaries */ -+ uStartAddr = uStartAddrOrig & PAGE_MASK; -+ uBeyondEndAddr = PAGE_ALIGN(uBeyondEndAddrOrig); -+ uAddrRange = uBeyondEndAddr - uStartAddr; -+ -+ /* -+ * Check for address range calculation overflow, and attempts to wrap -+ * zero bytes. -+ */ -+ if (uBeyondEndAddr <= uStartAddr) -+ { -+ PVR_DPF((PVR_DBG_ERROR, -+ "OSAcquirePhysPageAddr: Invalid address range (start " UINTPTR_FMT ", length %" SIZE_T_FMT_LEN "x)", -+ uStartAddrOrig, uAddrRangeOrig)); -+ goto error; -+ } -+ -+ /* Allocate information structure */ -+ psInfo = kmalloc(sizeof(*psInfo), GFP_KERNEL); -+ if (psInfo == NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, -+ "OSAcquirePhysPageAddr: Couldn't allocate information structure")); -+ goto error; -+ } -+ memset(psInfo, 0, sizeof(*psInfo)); -+ -+#if defined(DEBUG) -+ psInfo->uStartAddr = uStartAddrOrig; -+ psInfo->uBeyondEndAddr = uBeyondEndAddrOrig; -+#endif -+ -+ psInfo->iNumPages = (IMG_INT)(uAddrRange >> PAGE_SHIFT); -+ psInfo->iPageOffset = (IMG_INT)(uStartAddrOrig & ~PAGE_MASK); -+ -+ /* Allocate physical address array */ -+ psInfo->psPhysAddr = kmalloc((size_t)psInfo->iNumPages * sizeof(*psInfo->psPhysAddr), GFP_KERNEL); -+ if (psInfo->psPhysAddr == NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, -+ "OSAcquirePhysPageAddr: Couldn't allocate page array")); -+ goto error; -+ } -+ memset(psInfo->psPhysAddr, 0, (size_t)psInfo->iNumPages * sizeof(*psInfo->psPhysAddr)); -+ -+ /* Allocate page array */ -+ psInfo->ppsPages = kmalloc((size_t)psInfo->iNumPages * sizeof(*psInfo->ppsPages), GFP_KERNEL); -+ if (psInfo->ppsPages == NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, -+ "OSAcquirePhysPageAddr: Couldn't allocate page array")); -+ goto error; -+ } -+ memset(psInfo->ppsPages, 0, (size_t)psInfo->iNumPages * sizeof(*psInfo->ppsPages)); -+ -+ /* Default error code from now on */ -+ eError = PVRSRV_ERROR_BAD_MAPPING; -+ -+ /* Set the mapping type to aid clean up */ -+ psInfo->eType = WRAP_TYPE_GET_USER_PAGES; -+ -+ /* Lock down user memory */ -+ down_read(¤t->mm->mmap_sem); -+ bMMapSemHeld = IMG_TRUE; -+ -+ /* Get page list */ -+ psInfo->iNumPagesMapped = get_user_pages(current, current->mm, uStartAddr, psInfo->iNumPages, 1, 0, psInfo->ppsPages, NULL); -+ -+ if (psInfo->iNumPagesMapped >= 0) -+ { -+ /* See if we got all the pages we wanted */ -+ if (psInfo->iNumPagesMapped != psInfo->iNumPages) -+ { -+ PVR_TRACE(("OSAcquirePhysPageAddr: Couldn't map all the pages needed (wanted: %d, got %d)", psInfo->iNumPages, psInfo->iNumPagesMapped)); -+ -+ goto error; -+ } -+ -+ /* Build list of physical page addresses */ -+ for (i = 0; i < psInfo->iNumPages; i++) -+ { -+ IMG_CPU_PHYADDR CPUPhysAddr; -+ IMG_UINT32 ui32PFN; -+ -+ ui32PFN = page_to_pfn(psInfo->ppsPages[i]); -+ CPUPhysAddr.uiAddr = ui32PFN << PAGE_SHIFT; -+ if ((CPUPhysAddr.uiAddr >> PAGE_SHIFT) != ui32PFN) -+ { -+ PVR_DPF((PVR_DBG_ERROR, -+ "OSAcquirePhysPageAddr: Page frame number out of range (%x)", ui32PFN)); -+ -+ goto error; -+ } -+ psInfo->psPhysAddr[i] = SysCpuPAddrToSysPAddr(CPUPhysAddr); -+ psSysPAddr[i] = psInfo->psPhysAddr[i]; -+ -+ } -+ -+ goto exit; -+ } -+ -+ PVR_DPF((PVR_DBG_MESSAGE, "OSAcquirePhysPageAddr: get_user_pages failed (%d), using CPU page table", psInfo->iNumPagesMapped)); -+ -+ /* Reset some fields */ -+ psInfo->eType = WRAP_TYPE_NULL; -+ psInfo->iNumPagesMapped = 0; -+ memset(psInfo->ppsPages, 0, (size_t)psInfo->iNumPages * sizeof(*psInfo->ppsPages)); -+ -+ /* -+ * get_user_pages didn't work. If this is due to the address range -+ * representing memory mapped I/O, then we'll look for the pages -+ * in the appropriate memory region of the process. -+ */ -+ -+ /* Set the mapping type to aid clean up */ -+ psInfo->eType = WRAP_TYPE_FIND_VMA; -+ -+ psVMArea = find_vma(current->mm, uStartAddrOrig); -+ if (psVMArea == NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, -+ "OSAcquirePhysPageAddr: Couldn't find memory region containing start address " UINTPTR_FMT, -+ uStartAddrOrig)); -+ -+ goto error; -+ } -+#if defined(DEBUG) -+ psInfo->psVMArea = psVMArea; -+#endif -+ -+ /* -+ * find_vma locates a region with an end point past a given -+ * virtual address. So check the address is actually in the region. -+ */ -+ if (uStartAddrOrig < psVMArea->vm_start) -+ { -+ PVR_DPF((PVR_DBG_ERROR, -+ "OSAcquirePhysPageAddr: Start address " UINTPTR_FMT " is outside of the region returned by find_vma", -+ uStartAddrOrig)); -+ goto error; -+ } -+ -+ /* Now check the end address is in range */ -+ if (uBeyondEndAddrOrig > psVMArea->vm_end) -+ { -+ PVR_DPF((PVR_DBG_ERROR, -+ "OSAcquirePhysPageAddr: End address " UINTPTR_FMT " is outside of the region returned by find_vma", uBeyondEndAddrOrig)); -+ goto error; -+ } -+ -+ /* Does the region represent memory mapped I/O? */ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0)) -+ if ((psVMArea->vm_flags & (VM_IO | VM_RESERVED)) != (VM_IO | VM_RESERVED)) -+#else -+ if ((psVMArea->vm_flags & (VM_IO | VM_DONTEXPAND | VM_DONTDUMP)) != (VM_IO | VM_DONTEXPAND | VM_DONTDUMP)) -+#endif -+ -+ { -+ PVR_DPF((PVR_DBG_ERROR, -+ "OSAcquirePhysPageAddr: Memory region does not represent memory mapped I/O (VMA flags: 0x%lx)", psVMArea->vm_flags)); -+ goto error; -+ } -+ -+ /* We require read and write access */ -+ if ((psVMArea->vm_flags & (VM_READ | VM_WRITE)) != (VM_READ | VM_WRITE)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, -+ "OSAcquirePhysPageAddr: No read/write access to memory region (VMA flags: 0x%lx)", psVMArea->vm_flags)); -+ goto error; -+ } -+ -+ for (uAddr = uStartAddrOrig, i = 0; uAddr < uBeyondEndAddrOrig; uAddr += PAGE_SIZE, i++) -+ { -+ IMG_CPU_PHYADDR CPUPhysAddr; -+ IMG_UINT32 ui32PFN = 0; -+ -+ PVR_ASSERT(i < psInfo->iNumPages); -+ -+ if (!CPUVAddrToPFN(psVMArea, uAddr, &ui32PFN, &psInfo->ppsPages[i])) -+ { -+ PVR_DPF((PVR_DBG_ERROR, -+ "OSAcquirePhysPageAddr: Invalid CPU virtual address")); -+ -+ goto error; -+ } -+ if (psInfo->ppsPages[i] == NULL) -+ { -+#if defined(CONFIG_TI_TILER) || defined(CONFIG_DRM_OMAP_DMM_TILER) -+ /* This could be tiler memory.*/ -+ IMG_UINT32 ui32TilerAddr = CPUAddrToTilerPhy(uAddr); -+ if (ui32TilerAddr) -+ { -+ bHavePageStructs = IMG_TRUE; -+ psInfo->iNumPagesMapped++; -+ psInfo->psPhysAddr[i].uiAddr = ui32TilerAddr; -+ psSysPAddr[i].uiAddr = ui32TilerAddr; -+ continue; -+ } -+#endif /* defined(CONFIG_TI_TILER) || defined(CONFIG_DRM_OMAP_DMM_TILER) */ -+ -+ bHaveNoPageStructs = IMG_TRUE; -+ } -+ else -+ { -+ bHavePageStructs = IMG_TRUE; -+ -+ psInfo->iNumPagesMapped++; -+ -+ PVR_ASSERT(ui32PFN == page_to_pfn(psInfo->ppsPages[i])); -+ } -+ -+ CPUPhysAddr.uiAddr = ui32PFN << PAGE_SHIFT; -+ if ((CPUPhysAddr.uiAddr >> PAGE_SHIFT) != ui32PFN) -+ { -+ PVR_DPF((PVR_DBG_ERROR, -+ "OSAcquirePhysPageAddr: Page frame number out of range (%x)", ui32PFN)); -+ -+ goto error; -+ } -+ -+ psInfo->psPhysAddr[i] = SysCpuPAddrToSysPAddr(CPUPhysAddr); -+ psSysPAddr[i] = psInfo->psPhysAddr[i]; -+ } -+ PVR_ASSERT(i == psInfo->iNumPages); -+ -+#if defined(VM_MIXEDMAP) -+ if ((psVMArea->vm_flags & VM_MIXEDMAP) != 0) -+ { -+ goto exit; -+ } -+#endif -+ -+ if (bHavePageStructs && bHaveNoPageStructs) -+ { -+ PVR_DPF((PVR_DBG_ERROR, -+ "OSAcquirePhysPageAddr: Region is VM_MIXEDMAP, but isn't marked as such")); -+ goto error; -+ } -+ -+ if (!bHaveNoPageStructs) -+ { -+ /* The ideal case; every page has a page structure */ -+ goto exit; -+ } -+ -+#if defined(VM_PFNMAP) -+ if ((psVMArea->vm_flags & VM_PFNMAP) == 0) -+#endif -+ { -+ PVR_DPF((PVR_DBG_ERROR, -+ "OSAcquirePhysPageAddr: Region is VM_PFNMAP, but isn't marked as such")); -+ goto error; -+ } -+ -+exit: -+ PVR_ASSERT(bMMapSemHeld); -+ up_read(¤t->mm->mmap_sem); -+ -+ /* Return the cookie */ -+ *phOSWrapMem = (IMG_HANDLE)psInfo; -+ -+ if (bHaveNoPageStructs) -+ { -+ PVR_DPF((PVR_DBG_MESSAGE, -+ "OSAcquirePhysPageAddr: Region contains pages which can't be locked down (no page structures)")); -+ } -+ -+ PVR_ASSERT(psInfo->eType != 0); -+ -+ return PVRSRV_OK; -+ -+error: -+ if (bMMapSemHeld) -+ { -+ up_read(¤t->mm->mmap_sem); -+ } -+ OSReleasePhysPageAddr((IMG_HANDLE)psInfo); -+ -+ PVR_ASSERT(eError != PVRSRV_OK); -+ -+ return eError; -+} -+ -+typedef void (*InnerCacheOp_t)(const void *pvStart, const void *pvEnd); -+ -+#if defined(__arm__) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)) -+typedef void (*OuterCacheOp_t)(phys_addr_t uStart, phys_addr_t uEnd); -+#else -+typedef void (*OuterCacheOp_t)(unsigned long ulStart, unsigned long ulEnd); -+#endif -+ -+#if defined(CONFIG_OUTER_CACHE) -+ -+/* -+ Note: use IMG_CPU_PHYADDR to return CPU Phys Addresses, and not just 'unsigned long', -+ as this is not big enough to hold physical addresses on 32-bit PAE devices. -+*/ -+typedef IMG_BOOL (*MemAreaToPhys_t)(LinuxMemArea *psLinuxMemArea, -+ IMG_VOID *pvRangeAddrStart, -+ IMG_UINT32 ui32PageNumOffset, -+ IMG_UINT32 ui32PageNum, -+ IMG_CPU_PHYADDR *psStart); -+ -+static IMG_BOOL VMallocAreaToPhys(LinuxMemArea *psLinuxMemArea, -+ IMG_VOID *pvRangeAddrStart, -+ IMG_UINT32 ui32PageNumOffset, -+ IMG_UINT32 ui32PageNum, -+ IMG_CPU_PHYADDR *psStart) -+{ -+ psStart->uiAddr = vmalloc_to_pfn(pvRangeAddrStart + ui32PageNum * PAGE_SIZE) << PAGE_SHIFT; -+ return IMG_TRUE; -+} -+ -+static IMG_BOOL ExternalKVAreaToPhys(LinuxMemArea *psLinuxMemArea, -+ IMG_VOID *pvRangeAddrStart, -+ IMG_UINT32 ui32PageNumOffset, -+ IMG_UINT32 ui32PageNum, -+ IMG_CPU_PHYADDR *psStart) -+{ -+ IMG_SYS_PHYADDR SysPAddr; -+ SysPAddr = psLinuxMemArea->uData.sExternalKV.uPhysAddr.pSysPhysAddr[ui32PageNumOffset + ui32PageNum]; -+ *psStart = SysSysPAddrToCpuPAddr(SysPAddr); -+ return IMG_TRUE; -+} -+ -+static IMG_BOOL AllocPagesAreaToPhys(LinuxMemArea *psLinuxMemArea, -+ IMG_VOID *pvRangeAddrStart, -+ IMG_UINT32 ui32PageNumOffset, -+ IMG_UINT32 ui32PageNum, -+ IMG_CPU_PHYADDR *psStart) -+{ -+ struct page *pPage; -+ -+ pPage = psLinuxMemArea->uData.sPageList.ppsPageList[ui32PageNumOffset + ui32PageNum]; -+ psStart->uiAddr = page_to_pfn(pPage) << PAGE_SHIFT; -+ return IMG_TRUE; -+} -+ -+static IMG_BOOL AllocPagesSparseAreaToPhys(LinuxMemArea *psLinuxMemArea, -+ IMG_VOID *pvRangeAddrStart, -+ IMG_UINT32 ui32PageNumOffset, -+ IMG_UINT32 ui32PageNum, -+ IMG_CPU_PHYADDR *psStart) -+{ -+ IMG_UINT32 ui32VirtOffset = (ui32PageNumOffset + ui32PageNum) << PAGE_SHIFT; -+ IMG_UINT32 ui32PhysOffset; -+ struct page *pPage; -+ -+ if (BM_VirtOffsetToPhysical(psLinuxMemArea->hBMHandle, ui32VirtOffset, &ui32PhysOffset)) -+ { -+ PVR_ASSERT(ui32PhysOffset <= ui32VirtOffset); -+ pPage = psLinuxMemArea->uData.sPageList.ppsPageList[ui32PhysOffset >> PAGE_SHIFT]; -+ psStart->uiAddr = page_to_pfn(pPage) << PAGE_SHIFT; -+ return IMG_TRUE; -+ } -+ -+ return IMG_FALSE; -+} -+ -+ -+static IMG_BOOL IONAreaToPhys(LinuxMemArea *psLinuxMemArea, -+ IMG_VOID *pvRangeAddrStart, -+ IMG_UINT32 ui32PageNumOffset, -+ IMG_UINT32 ui32PageNum, -+ IMG_CPU_PHYADDR *psStart) -+{ -+ *psStart = psLinuxMemArea->uData.sIONTilerAlloc.pCPUPhysAddrs[ui32PageNumOffset + ui32PageNum];; -+ return IMG_TRUE; -+} -+ -+#endif /* defined(CONFIG_OUTER_CACHE) */ -+ -+/* g_sMMapMutex must be held while this function is called */ -+ -+static -+IMG_VOID *FindMMapBaseVAddr(struct list_head *psMMapOffsetStructList, -+ IMG_VOID *pvRangeAddrStart, IMG_UINT32 ui32Length) -+{ -+ PKV_OFFSET_STRUCT psOffsetStruct; -+ IMG_VOID *pvMinVAddr; -+ -+ /* There's no kernel-virtual for this type of allocation, so if -+ * we're flushing it, it must be user-virtual, and therefore -+ * have a mapping. -+ */ -+ list_for_each_entry(psOffsetStruct, psMMapOffsetStructList, sAreaItem) -+ { -+ if(OSGetCurrentProcessIDKM() != psOffsetStruct->ui32PID) -+ continue; -+ -+ pvMinVAddr = (IMG_VOID *)psOffsetStruct->uiUserVAddr; -+ -+ /* Within permissible range */ -+ if(pvRangeAddrStart >= pvMinVAddr && -+ ui32Length <= psOffsetStruct->uiRealByteSize) -+ return pvMinVAddr; -+ } -+ -+ return IMG_NULL; -+} -+ -+extern PVRSRV_LINUX_MUTEX g_sMMapMutex; -+ -+static inline void DoInnerCacheOp(IMG_HANDLE hOSMemHandle, -+ IMG_UINT32 ui32ByteOffset, -+ IMG_VOID *pvRangeAddrStart, -+ IMG_UINT32 ui32Length, -+ InnerCacheOp_t pfnInnerCacheOp) -+{ -+ LinuxMemArea *psLinuxMemArea = hOSMemHandle; -+ -+ if (!psLinuxMemArea->hBMHandle) -+ { -+ pfnInnerCacheOp(pvRangeAddrStart, pvRangeAddrStart + ui32Length); -+ } -+ else -+ { -+ IMG_UINT32 ui32ByteRemain = ui32Length; -+ IMG_UINT32 ui32BytesToDo = PAGE_SIZE - (((IMG_UINTPTR_T) pvRangeAddrStart) & (~PAGE_MASK)); -+ IMG_UINT8 *pbDo = (IMG_UINT8 *) pvRangeAddrStart; -+ -+ while(ui32ByteRemain) -+ { -+ if (BM_MapPageAtOffset(psLinuxMemArea->hBMHandle, ui32ByteOffset + (ui32Length - ui32ByteRemain))) -+ { -+ pfnInnerCacheOp(pbDo, pbDo + ui32BytesToDo); -+ } -+ pbDo += ui32BytesToDo; -+ ui32ByteRemain -= ui32BytesToDo; -+ ui32BytesToDo = MIN(ui32ByteRemain, PAGE_SIZE); -+ } -+ } -+} -+ -+static -+IMG_BOOL CheckExecuteCacheOp(IMG_HANDLE hOSMemHandle, -+ IMG_UINT32 ui32ByteOffset, -+ IMG_VOID *pvRangeAddrStart, -+ IMG_SIZE_T uiLength, -+ InnerCacheOp_t pfnInnerCacheOp, -+ OuterCacheOp_t pfnOuterCacheOp) -+{ -+ LinuxMemArea *psLinuxMemArea = (LinuxMemArea *)hOSMemHandle; -+ IMG_SIZE_T uiAreaLength = 0; -+ IMG_UINTPTR_T uiAreaOffset = 0; -+ struct list_head *psMMapOffsetStructList; -+ IMG_VOID *pvMinVAddr; -+ -+#if defined(CONFIG_OUTER_CACHE) -+ MemAreaToPhys_t pfnMemAreaToPhys = IMG_NULL; -+ IMG_UINTPTR_T uPageNumOffset = 0; -+#endif -+ -+ PVR_ASSERT(psLinuxMemArea != IMG_NULL); -+ -+ LinuxLockMutexNested(&g_sMMapMutex, PVRSRV_LOCK_CLASS_MMAP); -+ -+ psMMapOffsetStructList = &psLinuxMemArea->sMMapOffsetStructList; -+ uiAreaLength = psLinuxMemArea->uiByteSize; -+ -+ /* -+ Don't check the length in the case of sparse mappings as -+ we only know the physical length not the virtual -+ */ -+ if (!psLinuxMemArea->hBMHandle) -+ { -+ PVR_ASSERT(uiLength <= uiAreaLength); -+ } -+ -+ if(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_SUB_ALLOC) -+ { -+ uiAreaOffset = psLinuxMemArea->uData.sSubAlloc.uiByteOffset; -+ psLinuxMemArea = psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea; -+ } -+ -+ /* Recursion surely isn't possible? */ -+ PVR_ASSERT(psLinuxMemArea->eAreaType != LINUX_MEM_AREA_SUB_ALLOC); -+ -+ switch(psLinuxMemArea->eAreaType) -+ { -+ case LINUX_MEM_AREA_VMALLOC: -+ { -+ if(is_vmalloc_addr(pvRangeAddrStart)) -+ { -+ pvMinVAddr = psLinuxMemArea->uData.sVmalloc.pvVmallocAddress + uiAreaOffset; -+ -+ /* Outside permissible range */ -+ if(pvRangeAddrStart < pvMinVAddr) -+ goto err_blocked; -+ -+ DoInnerCacheOp(hOSMemHandle, -+ ui32ByteOffset, -+ pvRangeAddrStart, -+ uiLength, -+ pfnInnerCacheOp); -+ } -+ else -+ { -+ /* If this isn't a vmalloc address, assume we're flushing by -+ * user-virtual. Compute the mmap base vaddr and use this to -+ * compute the offset in vmalloc space. -+ */ -+ -+ pvMinVAddr = FindMMapBaseVAddr(psMMapOffsetStructList, -+ pvRangeAddrStart, uiLength); -+ if(!pvMinVAddr) -+ goto err_blocked; -+ -+ DoInnerCacheOp(hOSMemHandle, -+ ui32ByteOffset, -+ pvRangeAddrStart, -+ uiLength, -+ pfnInnerCacheOp); -+ -+#if defined(CONFIG_OUTER_CACHE) -+ /* -+ * We don't need to worry about cache aliasing here because -+ * we have already flushed the virtually-indexed caches (L1 -+ * etc.) by the supplied user-virtual addresses. -+ * -+ * The vmalloc address will only be used to determine -+ * affected physical pages for outer cache flushing. -+ */ -+ pvRangeAddrStart = psLinuxMemArea->uData.sVmalloc.pvVmallocAddress + -+ (uiAreaOffset & PAGE_MASK) + (pvRangeAddrStart - pvMinVAddr); -+ } -+ -+ pfnMemAreaToPhys = VMallocAreaToPhys; -+#else /* defined(CONFIG_OUTER_CACHE) */ -+ } -+#endif /* defined(CONFIG_OUTER_CACHE) */ -+ break; -+ } -+ -+ case LINUX_MEM_AREA_EXTERNAL_KV: -+ { -+ /* We'll only see bPhysContig for frame buffers, and we shouldn't -+ * be flushing those (they're write combined or uncached). -+ */ -+ if (psLinuxMemArea->uData.sExternalKV.bPhysContig == IMG_TRUE) -+ { -+ PVR_DPF((PVR_DBG_WARNING, "%s: Attempt to flush contiguous external memory", __func__)); -+ goto err_blocked; -+ } -+ -+ /* If it has a kernel virtual address, something odd has happened. -+ * We expect EXTERNAL_KV _only_ from the wrapping of ALLOC_PAGES. -+ */ -+ if (psLinuxMemArea->uData.sExternalKV.pvExternalKV != IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_WARNING, "%s: Attempt to flush external memory with a kernel virtual address", __func__)); -+ goto err_blocked; -+ } -+ -+ pvMinVAddr = FindMMapBaseVAddr(psMMapOffsetStructList, -+ pvRangeAddrStart, uiLength); -+ if(!pvMinVAddr) -+ goto err_blocked; -+ -+ DoInnerCacheOp(hOSMemHandle, -+ ui32ByteOffset, -+ pvRangeAddrStart, -+ uiLength, -+ pfnInnerCacheOp); -+ -+#if defined(CONFIG_OUTER_CACHE) -+ uPageNumOffset = ((uiAreaOffset & PAGE_MASK) + (pvRangeAddrStart - pvMinVAddr)) >> PAGE_SHIFT; -+ pfnMemAreaToPhys = ExternalKVAreaToPhys; -+#endif -+ break; -+ } -+ -+ case LINUX_MEM_AREA_ION: -+ { -+ pvMinVAddr = FindMMapBaseVAddr(psMMapOffsetStructList, -+ pvRangeAddrStart, uiLength); -+ if(!pvMinVAddr) -+ goto err_blocked; -+ -+ DoInnerCacheOp(hOSMemHandle, -+ ui32ByteOffset, -+ pvRangeAddrStart, -+ uiLength, -+ pfnInnerCacheOp); -+ -+#if defined(CONFIG_OUTER_CACHE) -+ uPageNumOffset = ((uiAreaOffset & PAGE_MASK) + (pvRangeAddrStart - pvMinVAddr)) >> PAGE_SHIFT; -+ pfnMemAreaToPhys = IONAreaToPhys; -+#endif -+ break; -+ } -+ -+ case LINUX_MEM_AREA_ALLOC_PAGES: -+ { -+ pvMinVAddr = FindMMapBaseVAddr(psMMapOffsetStructList, -+ pvRangeAddrStart, uiLength); -+ if(!pvMinVAddr) -+ goto err_blocked; -+ -+ DoInnerCacheOp(hOSMemHandle, -+ ui32ByteOffset, -+ pvRangeAddrStart, -+ uiLength, -+ pfnInnerCacheOp); -+ -+#if defined(CONFIG_OUTER_CACHE) -+ uPageNumOffset = ((uiAreaOffset & PAGE_MASK) + (pvRangeAddrStart - pvMinVAddr)) >> PAGE_SHIFT; -+ if (psLinuxMemArea->hBMHandle) -+ { -+ pfnMemAreaToPhys = AllocPagesSparseAreaToPhys; -+ } -+ else -+ { -+ pfnMemAreaToPhys = AllocPagesAreaToPhys; -+ } -+#endif -+ break; -+ } -+ -+ default: -+ PVR_DBG_BREAK; -+ } -+ -+ LinuxUnLockMutex(&g_sMMapMutex); -+ -+#if defined(CONFIG_OUTER_CACHE) -+ PVR_ASSERT(pfnMemAreaToPhys != IMG_NULL); -+ -+ /* Outer caches need some more work, to get a list of physical addresses */ -+ { -+ IMG_CPU_PHYADDR sStart, sEnd; -+ unsigned long ulLength, ulStartOffset, ulEndOffset; -+ IMG_UINT32 i, ui32NumPages; -+ IMG_BOOL bValidPage; -+ -+ /* Length and offsets of flush region WRT page alignment */ -+ ulLength = (unsigned long)uiLength; -+ ulStartOffset = ((unsigned long)pvRangeAddrStart) & (PAGE_SIZE - 1); -+ ulEndOffset = ((unsigned long)pvRangeAddrStart + ulLength) & (PAGE_SIZE - 1); -+ -+ /* The affected pages, rounded up */ -+ ui32NumPages = (ulStartOffset + ulLength + PAGE_SIZE - 1) >> PAGE_SHIFT; -+ -+ for(i = 0; i < ui32NumPages; i++) -+ { -+ bValidPage = pfnMemAreaToPhys(psLinuxMemArea, pvRangeAddrStart, -+ uPageNumOffset, i, &sStart); -+ if (bValidPage) -+ { -+ sEnd.uiAddr = sStart.uiAddr + PAGE_SIZE; -+ -+ if(i == ui32NumPages - 1 && ulEndOffset != 0) -+ sEnd.uiAddr = sStart.uiAddr + ulEndOffset; -+ -+ if(i == 0) -+ sStart.uiAddr += ulStartOffset; -+ -+ pfnOuterCacheOp(sStart.uiAddr, sEnd.uiAddr); -+ } -+ } -+ } -+#endif -+ -+ return IMG_TRUE; -+ -+err_blocked: -+ PVR_DPF((PVR_DBG_WARNING, "%s: Blocked cache op on virtual range " -+ "%p-%p (type %d)", __func__, -+ pvRangeAddrStart, pvRangeAddrStart + uiLength, -+ psLinuxMemArea->eAreaType)); -+ LinuxUnLockMutex(&g_sMMapMutex); -+ return IMG_FALSE; -+} -+ -+#if defined(__i386__) || defined (__x86_64__) -+ -+#define ROUND_UP(x,a) (((x) + (a) - 1) & ~((a) - 1)) -+ -+static void per_cpu_cache_flush(void *arg) -+{ -+ PVR_UNREFERENCED_PARAMETER(arg); -+ wbinvd(); -+} -+ -+static void x86_flush_cache_range(const void *pvStart, const void *pvEnd) -+{ -+ IMG_BYTE *pbStart = (IMG_BYTE *)pvStart; -+ IMG_BYTE *pbEnd = (IMG_BYTE *)pvEnd; -+ IMG_BYTE *pbBase; -+ -+ pbEnd = (IMG_BYTE *)ROUND_UP((IMG_UINTPTR_T)pbEnd, -+ boot_cpu_data.x86_clflush_size); -+ -+ mb(); -+ for(pbBase = pbStart; pbBase < pbEnd; pbBase += boot_cpu_data.x86_clflush_size) -+ { -+ clflush(pbBase); -+ } -+ mb(); -+} -+ -+IMG_VOID OSCleanCPUCacheKM(IMG_VOID) -+{ -+ /* No clean feature on x86 */ -+ ON_EACH_CPU(per_cpu_cache_flush, NULL, 1); -+} -+ -+IMG_VOID OSFlushCPUCacheKM(IMG_VOID) -+{ -+ ON_EACH_CPU(per_cpu_cache_flush, NULL, 1); -+} -+ -+IMG_BOOL OSFlushCPUCacheRangeKM(IMG_HANDLE hOSMemHandle, -+ IMG_UINT32 ui32ByteOffset, -+ IMG_VOID *pvRangeAddrStart, -+ IMG_UINT32 ui32Length) -+{ -+ /* Write-back and invalidate */ -+ return CheckExecuteCacheOp(hOSMemHandle, ui32ByteOffset, pvRangeAddrStart, ui32Length, -+ x86_flush_cache_range, IMG_NULL); -+} -+ -+IMG_BOOL OSCleanCPUCacheRangeKM(IMG_HANDLE hOSMemHandle, -+ IMG_UINT32 ui32ByteOffset, -+ IMG_VOID *pvRangeAddrStart, -+ IMG_UINT32 ui32Length) -+{ -+ /* No clean feature on x86 */ -+ return CheckExecuteCacheOp(hOSMemHandle, ui32ByteOffset, pvRangeAddrStart, ui32Length, -+ x86_flush_cache_range, IMG_NULL); -+} -+ -+IMG_BOOL OSInvalidateCPUCacheRangeKM(IMG_HANDLE hOSMemHandle, -+ IMG_UINT32 ui32ByteOffset, -+ IMG_VOID *pvRangeAddrStart, -+ IMG_UINT32 ui32Length) -+{ -+ /* No invalidate-only support */ -+ return CheckExecuteCacheOp(hOSMemHandle, ui32ByteOffset, pvRangeAddrStart, ui32Length, -+ x86_flush_cache_range, IMG_NULL); -+} -+ -+#else /* defined(__i386__) || defined(__x86_64__) */ -+ -+#if defined(__arm__) -+ -+static void per_cpu_cache_flush(void *arg) -+{ -+ PVR_UNREFERENCED_PARAMETER(arg); -+ flush_cache_all(); -+} -+ -+IMG_VOID OSCleanCPUCacheKM(IMG_VOID) -+{ -+ /* No full (inner) cache clean op */ -+ ON_EACH_CPU(per_cpu_cache_flush, NULL, 1); -+#if defined(CONFIG_OUTER_CACHE) -+ outer_clean_range(0, ULONG_MAX); -+#endif -+} -+ -+IMG_VOID OSFlushCPUCacheKM(IMG_VOID) -+{ -+ ON_EACH_CPU(per_cpu_cache_flush, NULL, 1); -+#if defined(CONFIG_OUTER_CACHE) && \ -+ (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) -+ /* To use the "deferred flush" (not clean) DDK feature you need a kernel -+ * implementation of outer_flush_all() for ARM CPUs with an outer cache -+ * controller (e.g. PL310, common with Cortex A9 and later). -+ * -+ * Reference DDKs don't require this functionality, as they will only -+ * clean the cache, never flush (clean+invalidate) it. -+ */ -+ outer_flush_all(); -+#endif -+} -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34)) -+static inline size_t pvr_dmac_range_len(const void *pvStart, const void *pvEnd) -+{ -+ return (size_t)((char *)pvEnd - (char *)pvStart); -+} -+#endif -+ -+static void pvr_dmac_inv_range(const void *pvStart, const void *pvEnd) -+{ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34)) -+ dmac_inv_range(pvStart, pvEnd); -+#else -+ dmac_map_area(pvStart, pvr_dmac_range_len(pvStart, pvEnd), DMA_FROM_DEVICE); -+#endif -+} -+ -+static void pvr_dmac_clean_range(const void *pvStart, const void *pvEnd) -+{ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34)) -+ dmac_clean_range(pvStart, pvEnd); -+#else -+ dmac_map_area(pvStart, pvr_dmac_range_len(pvStart, pvEnd), DMA_TO_DEVICE); -+#endif -+} -+ -+IMG_BOOL OSFlushCPUCacheRangeKM(IMG_HANDLE hOSMemHandle, -+ IMG_UINT32 ui32ByteOffset, -+ IMG_VOID *pvRangeAddrStart, -+ IMG_UINT32 ui32Length) -+{ -+ return CheckExecuteCacheOp(hOSMemHandle, ui32ByteOffset, -+ pvRangeAddrStart, ui32Length, -+ dmac_flush_range, outer_flush_range); -+} -+ -+IMG_BOOL OSCleanCPUCacheRangeKM(IMG_HANDLE hOSMemHandle, -+ IMG_UINT32 ui32ByteOffset, -+ IMG_VOID *pvRangeAddrStart, -+ IMG_UINT32 ui32Length) -+{ -+ return CheckExecuteCacheOp(hOSMemHandle, ui32ByteOffset, -+ pvRangeAddrStart, ui32Length, -+ pvr_dmac_clean_range, outer_clean_range); -+} -+ -+IMG_BOOL OSInvalidateCPUCacheRangeKM(IMG_HANDLE hOSMemHandle, -+ IMG_UINT32 ui32ByteOffset, -+ IMG_VOID *pvRangeAddrStart, -+ IMG_UINT32 ui32Length) -+{ -+ return CheckExecuteCacheOp(hOSMemHandle, ui32ByteOffset, -+ pvRangeAddrStart, ui32Length, -+ pvr_dmac_inv_range, outer_inv_range); -+} -+ -+#else /* defined(__arm__) */ -+ -+#if defined(__mips__) -+/* -+ * dmac cache functions are supposed to be used for dma -+ * memory which comes from dma-able memory. However examining -+ * the implementation of dmac cache functions and experimenting, -+ * can assert that dmac functions are safe to use for high-mem -+ * memory as well for our OS{Clean/Flush/Invalidate}Cache functions -+ * -+ */ -+ -+IMG_VOID OSCleanCPUCacheKM(IMG_VOID) -+{ -+ /* dmac functions flush full cache if size is larger than -+ * p-cache size. This is a workaround for the fact that -+ * __flush_cache_all is not an exported symbol. Please -+ * replace with custom function if available in latest -+ * version of linux being used. -+ * Arbitrary large number (1MB) which should be larger than -+ * mips p-cache sizes for some time in future. -+ * */ -+ dma_cache_wback(0, 0x100000); -+} -+ -+IMG_VOID OSFlushCPUCacheKM(IMG_VOID) -+{ -+ /* dmac functions flush full cache if size is larger than -+ * p-cache size. This is a workaround for the fact that -+ * __flush_cache_all is not an exported symbol. Please -+ * replace with custom function if available in latest -+ * version of linux being used. -+ * Arbitrary large number (1MB) which should be larger than -+ * mips p-cache sizes for some time in future. -+ * */ -+ dma_cache_wback_inv(0, 0x100000); -+} -+ -+static inline IMG_UINT32 pvr_dma_range_len(const void *pvStart, const void *pvEnd) -+{ -+ return (IMG_UINT32)((char *)pvEnd - (char *)pvStart); -+} -+ -+static void pvr_dma_cache_wback_inv(const void *pvStart, const void *pvEnd) -+{ -+ dma_cache_wback_inv((IMG_UINTPTR_T)pvStart, pvr_dma_range_len(pvStart, pvEnd)); -+} -+ -+static void pvr_dma_cache_wback(const void *pvStart, const void *pvEnd) -+{ -+ dma_cache_wback((IMG_UINTPTR_T)pvStart, pvr_dma_range_len(pvStart, pvEnd)); -+} -+ -+static void pvr_dma_cache_inv(const void *pvStart, const void *pvEnd) -+{ -+ dma_cache_inv((IMG_UINTPTR_T)pvStart, pvr_dma_range_len(pvStart, pvEnd)); -+} -+ -+IMG_BOOL OSFlushCPUCacheRangeKM(IMG_HANDLE hOSMemHandle, -+ IMG_UINT32 ui32ByteOffset, -+ IMG_VOID *pvRangeAddrStart, -+ IMG_UINT32 ui32Length) -+{ -+ return CheckExecuteCacheOp(hOSMemHandle, ui32ByteOffset, -+ pvRangeAddrStart, ui32Length, -+ pvr_dma_cache_wback_inv, IMG_NULL); -+} -+ -+IMG_BOOL OSCleanCPUCacheRangeKM(IMG_HANDLE hOSMemHandle, -+ IMG_UINT32 ui32ByteOffset, -+ IMG_VOID *pvRangeAddrStart, -+ IMG_UINT32 ui32Length) -+{ -+ return CheckExecuteCacheOp(hOSMemHandle, ui32ByteOffset, -+ pvRangeAddrStart, ui32Length, -+ pvr_dma_cache_wback, IMG_NULL); -+} -+ -+IMG_BOOL OSInvalidateCPUCacheRangeKM(IMG_HANDLE hOSMemHandle, -+ IMG_UINT32 ui32ByteOffset, -+ IMG_VOID *pvRangeAddrStart, -+ IMG_UINT32 ui32Length) -+{ -+ return CheckExecuteCacheOp(hOSMemHandle, ui32ByteOffset, -+ pvRangeAddrStart, ui32Length, -+ pvr_dma_cache_inv, IMG_NULL); -+} -+ -+#else /* defined(__mips__) */ -+ -+#error "Implement CPU cache flush/clean/invalidate primitives for this CPU!" -+ -+#endif /* defined(__mips__) */ -+ -+#endif /* defined(__arm__) */ -+ -+#endif /* defined(__i386__) */ -+ -+typedef struct _AtomicStruct -+{ -+ atomic_t RefCount; -+} AtomicStruct; -+ -+PVRSRV_ERROR OSAtomicAlloc(IMG_PVOID *ppvRefCount) -+{ -+ AtomicStruct *psRefCount; -+ -+ psRefCount = kmalloc(sizeof(AtomicStruct), GFP_KERNEL); -+ if (psRefCount == NULL) -+ { -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ atomic_set(&psRefCount->RefCount, 0); -+ -+ *ppvRefCount = psRefCount; -+ return PVRSRV_OK; -+} -+ -+IMG_VOID OSAtomicFree(IMG_PVOID pvRefCount) -+{ -+ AtomicStruct *psRefCount = pvRefCount; -+ -+ PVR_ASSERT(atomic_read(&psRefCount->RefCount) == 0); -+ kfree(psRefCount); -+} -+ -+IMG_VOID OSAtomicInc(IMG_PVOID pvRefCount) -+{ -+ AtomicStruct *psRefCount = pvRefCount; -+ -+ atomic_inc(&psRefCount->RefCount); -+} -+ -+IMG_BOOL OSAtomicDecAndTest(IMG_PVOID pvRefCount) -+{ -+ AtomicStruct *psRefCount = pvRefCount; -+ -+ return atomic_dec_and_test(&psRefCount->RefCount) ? IMG_TRUE:IMG_FALSE; -+} -+ -+IMG_UINT32 OSAtomicRead(IMG_PVOID pvRefCount) -+{ -+ AtomicStruct *psRefCount = pvRefCount; -+ -+ return (IMG_UINT32) atomic_read(&psRefCount->RefCount); -+} -+ -+IMG_VOID OSReleaseBridgeLock(IMG_VOID) -+{ -+ LinuxUnLockMutex(&gPVRSRVLock); -+} -+ -+IMG_VOID OSReacquireBridgeLock(IMG_VOID) -+{ -+ LinuxLockMutexNested(&gPVRSRVLock, PVRSRV_LOCK_CLASS_BRIDGE); -+} -+ -+typedef struct _OSTime -+{ -+ unsigned long ulTime; -+} OSTime; -+ -+PVRSRV_ERROR OSTimeCreateWithUSOffset(IMG_PVOID *pvRet, IMG_UINT32 ui32USOffset) -+{ -+ OSTime *psOSTime; -+ -+ psOSTime = kmalloc(sizeof(OSTime), GFP_KERNEL); -+ if (psOSTime == IMG_NULL) -+ { -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ -+ psOSTime->ulTime = jiffies + usecs_to_jiffies(ui32USOffset); -+ *pvRet = psOSTime; -+ return PVRSRV_OK; -+} -+ -+ -+IMG_BOOL OSTimeHasTimePassed(IMG_PVOID pvData) -+{ -+ OSTime *psOSTime = pvData; -+ -+ if (time_is_before_jiffies(psOSTime->ulTime)) -+ { -+ return IMG_TRUE; -+ } -+ return IMG_FALSE; -+} -+ -+IMG_VOID OSTimeDestroy(IMG_PVOID pvData) -+{ -+ kfree(pvData); -+} -+ -+IMG_VOID OSGetCurrentProcessNameKM(IMG_CHAR *pszName, IMG_UINT32 ui32Size) -+{ -+ strncpy(pszName, current->comm, MIN(ui32Size,TASK_COMM_LEN)); -+} -+ -+/* One time osfunc initialisation */ -+PVRSRV_ERROR PVROSFuncInit(IMG_VOID) -+{ -+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES) -+ { -+ psTimerWorkQueue = create_workqueue("pvr_timer"); -+ if (psTimerWorkQueue == NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: couldn't create timer workqueue", __FUNCTION__)); -+ return PVRSRV_ERROR_UNABLE_TO_CREATE_THREAD; -+ -+ } -+ } -+#endif -+ -+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES) || defined(PVR_LINUX_TIMERS_USING_SHARED_WORKQUEUE) -+ { -+ IMG_UINT32 ui32i; -+ -+ for (ui32i = 0; ui32i < OS_MAX_TIMERS; ui32i++) -+ { -+ TIMER_CALLBACK_DATA *psTimerCBData = &sTimers[ui32i]; -+ -+ INIT_WORK(&psTimerCBData->sWork, OSTimerWorkQueueCallBack); -+ } -+ } -+#endif -+ -+#if defined (SUPPORT_ION) -+ { -+ PVRSRV_ERROR eError; -+ -+ eError = IonInit(); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: IonInit failed", __FUNCTION__)); -+ } -+ } -+#endif -+ return PVRSRV_OK; -+} -+ -+/* -+ * Osfunc deinitialisation. -+ * Note that PVROSFuncInit may not have been called -+ */ -+IMG_VOID PVROSFuncDeInit(IMG_VOID) -+{ -+#if defined (SUPPORT_ION) -+ IonDeinit(); -+#endif -+#if defined(PVR_LINUX_TIMERS_USING_WORKQUEUES) -+ if (psTimerWorkQueue != NULL) -+ { -+ destroy_workqueue(psTimerWorkQueue); -+ } -+#endif -+} -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/osperproc.c b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/osperproc.c -new file mode 100644 -index 0000000..8101719 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/osperproc.c -@@ -0,0 +1,154 @@ -+/*************************************************************************/ /*! -+@Title Linux specific per process data functions -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#include "services_headers.h" -+#include "osperproc.h" -+ -+#include "env_perproc.h" -+#include "proc.h" -+ -+#if defined (SUPPORT_ION) -+#include "ion.h" -+extern struct ion_device *gpsIonDev; -+#endif -+ -+extern IMG_UINT32 gui32ReleasePID; -+ -+PVRSRV_ERROR OSPerProcessPrivateDataInit(IMG_HANDLE *phOsPrivateData) -+{ -+ PVRSRV_ERROR eError; -+ IMG_HANDLE hBlockAlloc; -+ PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc; -+ -+ eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, -+ sizeof(PVRSRV_ENV_PER_PROCESS_DATA), -+ phOsPrivateData, -+ &hBlockAlloc, -+ "Environment per Process Data"); -+ -+ if (eError != PVRSRV_OK) -+ { -+ *phOsPrivateData = IMG_NULL; -+ -+ PVR_DPF((PVR_DBG_ERROR, "%s: OSAllocMem failed (%d)", __FUNCTION__, eError)); -+ return eError; -+ } -+ -+ psEnvPerProc = (PVRSRV_ENV_PER_PROCESS_DATA *)*phOsPrivateData; -+ OSMemSet(psEnvPerProc, 0, sizeof(*psEnvPerProc)); -+ -+ psEnvPerProc->hBlockAlloc = hBlockAlloc; -+ -+ /* Linux specific mmap processing */ -+ LinuxMMapPerProcessConnect(psEnvPerProc); -+ -+#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT) -+ /* Linked list of PVRSRV_FILE_PRIVATE_DATA structures */ -+ INIT_LIST_HEAD(&psEnvPerProc->sDRMAuthListHead); -+#endif -+ -+#if defined(SUPPORT_ION) -+ OSSNPrintf(psEnvPerProc->azIonClientName, ION_CLIENT_NAME_SIZE, "pvr_ion_client-%d", OSGetCurrentProcessIDKM()); -+ psEnvPerProc->psIONClient = -+ ion_client_create(gpsIonDev, -+#if defined(CONFIG_ION_OMAP) -+ /*1 << ION_HEAP_TYPE_SYSTEM_CONTIG |*/ -+ 1 << ION_HEAP_TYPE_SYSTEM -+ | 1 << OMAP_ION_HEAP_TYPE_TILER -+#else /* defined(CONFIG_ION_OMAP) */ -+ -1 -+#endif /* defined(CONFIG_ION_OMAP) */ -+ , psEnvPerProc->azIonClientName); -+ -+ if (IS_ERR_OR_NULL(psEnvPerProc->psIONClient)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "OSPerProcessPrivateDataInit: Couldn't create " -+ "ion client for per process data")); -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+#endif /* defined(SUPPORT_ION) */ -+ -+ return PVRSRV_OK; -+} -+ -+PVRSRV_ERROR OSPerProcessPrivateDataDeInit(IMG_HANDLE hOsPrivateData) -+{ -+ PVRSRV_ERROR eError; -+ PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc; -+ -+ if (hOsPrivateData == IMG_NULL) -+ { -+ return PVRSRV_OK; -+ } -+ -+ psEnvPerProc = (PVRSRV_ENV_PER_PROCESS_DATA *)hOsPrivateData; -+ -+ /* Linux specific mmap processing */ -+ LinuxMMapPerProcessDisconnect(psEnvPerProc); -+ -+ /* Remove per process /proc entries */ -+ RemovePerProcessProcDir(psEnvPerProc); -+ -+ eError = OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, -+ sizeof(PVRSRV_ENV_PER_PROCESS_DATA), -+ hOsPrivateData, -+ psEnvPerProc->hBlockAlloc); -+ /*not nulling pointer, copy on stack*/ -+ -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: OSFreeMem failed (%d)", __FUNCTION__, eError)); -+ } -+ -+ return PVRSRV_OK; -+} -+ -+PVRSRV_ERROR OSPerProcessSetHandleOptions(PVRSRV_HANDLE_BASE *psHandleBase) -+{ -+ return LinuxMMapPerProcessHandleOptions(psHandleBase); -+} -+ -+IMG_HANDLE LinuxTerminatingProcessPrivateData(IMG_VOID) -+{ -+ if(!gui32ReleasePID) -+ return NULL; -+ return PVRSRVPerProcessPrivateData(gui32ReleasePID); -+} -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/pdump.c b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/pdump.c -new file mode 100644 -index 0000000..4bab1b0 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/pdump.c -@@ -0,0 +1,855 @@ -+/*************************************************************************/ /*! -+@Title Parameter dump macro target routines -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#if defined (SUPPORT_SGX) || defined (SUPPORT_VGX) -+#if defined (PDUMP) -+ -+#include <asm/atomic.h> -+#include <stdarg.h> -+#if defined (SUPPORT_SGX) -+#include "sgxdefs.h" /* Is this still needed? */ -+#endif -+#include "services_headers.h" -+ -+#include "pvrversion.h" -+#include "pvr_debug.h" -+ -+#include "dbgdrvif.h" -+#if defined (SUPPORT_SGX) -+#include "sgxmmu.h"/* Is this still needed? */ -+#endif -+#include "mm.h" -+#include "pdump_km.h" -+#include "pdump_int.h" -+ -+#include <linux/kernel.h> // sprintf -+#include <linux/string.h> // strncpy, strlen -+#include <linux/mutex.h> -+ -+static IMG_BOOL PDumpWriteString2 (IMG_CHAR * pszString, IMG_UINT32 ui32Flags); -+static IMG_BOOL PDumpWriteILock (PDBG_STREAM psStream, IMG_UINT8 *pui8Data, IMG_UINT32 ui32Count, IMG_UINT32 ui32Flags); -+static IMG_VOID DbgSetFrame (PDBG_STREAM psStream, IMG_UINT32 ui32Frame); -+static IMG_VOID DbgSetMarker (PDBG_STREAM psStream, IMG_UINT32 ui32Marker); -+ -+#define PDUMP_DATAMASTER_PIXEL (1) -+#define PDUMP_DATAMASTER_EDM (3) -+ -+/* -+ Maximum file size to split output files -+*/ -+#define MAX_FILE_SIZE 0x40000000 -+ -+static atomic_t gsPDumpSuspended = ATOMIC_INIT(0); -+ -+static PDBGKM_SERVICE_TABLE gpfnDbgDrv = IMG_NULL; -+ -+DEFINE_MUTEX(sPDumpLock); -+DEFINE_MUTEX(sPDumpMsgLock); -+ -+IMG_CHAR *pszStreamName[PDUMP_NUM_STREAMS] = { "ParamStream2", -+ "ScriptStream2", -+ "DriverInfoStream"}; -+typedef struct PDBG_PDUMP_STATE_TAG -+{ -+ PDBG_STREAM psStream[PDUMP_NUM_STREAMS]; -+ IMG_UINT32 ui32ParamFileNum; -+ -+ IMG_CHAR *pszMsg; -+ IMG_CHAR *pszScript; -+ IMG_CHAR *pszFile; -+ -+} PDBG_PDUMP_STATE; -+ -+static PDBG_PDUMP_STATE gsDBGPdumpState = {{IMG_NULL}, 0, IMG_NULL, IMG_NULL, IMG_NULL}; -+ -+#define SZ_MSG_SIZE_MAX PVRSRV_PDUMP_MAX_COMMENT_SIZE-1 -+#define SZ_SCRIPT_SIZE_MAX PVRSRV_PDUMP_MAX_COMMENT_SIZE-1 -+#define SZ_FILENAME_SIZE_MAX PVRSRV_PDUMP_MAX_COMMENT_SIZE-1 -+ -+ -+ -+ -+static inline IMG_BOOL PDumpSuspended(IMG_VOID) -+{ -+ return (atomic_read(&gsPDumpSuspended) != 0) ? IMG_TRUE : IMG_FALSE; -+} -+ -+/*! -+ * \name PDumpOSGetScriptString -+ */ -+PVRSRV_ERROR PDumpOSGetScriptString(IMG_HANDLE *phScript, -+ IMG_UINT32 *pui32MaxLen) -+{ -+ *phScript = (IMG_HANDLE)gsDBGPdumpState.pszScript; -+ *pui32MaxLen = SZ_SCRIPT_SIZE_MAX; -+ if ((!*phScript) || PDumpSuspended()) -+ { -+ return PVRSRV_ERROR_PDUMP_NOT_ACTIVE; -+ } -+ return PVRSRV_OK; -+} -+ -+/*! -+ * \name PDumpOSGetMessageString -+ */ -+PVRSRV_ERROR PDumpOSGetMessageString(IMG_CHAR **ppszMsg, -+ IMG_UINT32 *pui32MaxLen) -+{ -+ *ppszMsg = gsDBGPdumpState.pszMsg; -+ *pui32MaxLen = SZ_MSG_SIZE_MAX; -+ if ((!*ppszMsg) || PDumpSuspended()) -+ { -+ return PVRSRV_ERROR_PDUMP_NOT_ACTIVE; -+ } -+ return PVRSRV_OK; -+} -+ -+/*! -+ * \name PDumpOSGetFilenameString -+ */ -+PVRSRV_ERROR PDumpOSGetFilenameString(IMG_CHAR **ppszFile, -+ IMG_UINT32 *pui32MaxLen) -+{ -+ *ppszFile = gsDBGPdumpState.pszFile; -+ *pui32MaxLen = SZ_FILENAME_SIZE_MAX; -+ if ((!*ppszFile) || PDumpSuspended()) -+ { -+ return PVRSRV_ERROR_PDUMP_NOT_ACTIVE; -+ } -+ return PVRSRV_OK; -+} -+ -+/*! -+ * \name PDumpOSWriteString2 -+ */ -+IMG_BOOL PDumpOSWriteString2(IMG_HANDLE hScript, IMG_UINT32 ui32Flags) -+{ -+ return PDumpWriteString2(hScript, ui32Flags); -+} -+ -+/*! -+ * \name PDumpOSBufprintf -+ */ -+PVRSRV_ERROR PDumpOSBufprintf(IMG_HANDLE hBuf, IMG_UINT32 ui32ScriptSizeMax, IMG_CHAR* pszFormat, ...) -+{ -+ IMG_CHAR* pszBuf = hBuf; -+ IMG_INT32 n; -+ va_list vaArgs; -+ -+ va_start(vaArgs, pszFormat); -+ -+ n = vsnprintf(pszBuf, ui32ScriptSizeMax, pszFormat, vaArgs); -+ -+ va_end(vaArgs); -+ -+ if (n>=(IMG_INT32)ui32ScriptSizeMax || n==-1) /* glibc >= 2.1 or glibc 2.0 */ -+ { -+ PVR_DPF((PVR_DBG_ERROR, "Buffer overflow detected, pdump output may be incomplete.")); -+ -+ return PVRSRV_ERROR_PDUMP_BUF_OVERFLOW; -+ } -+ -+#if defined(PDUMP_DEBUG_OUTFILES) -+ g_ui32EveryLineCounter++; -+#endif -+ return PVRSRV_OK; -+} -+ -+/*! -+ * \name PDumpOSVSprintf -+ */ -+PVRSRV_ERROR PDumpOSVSprintf(IMG_CHAR *pszComment, IMG_UINT32 ui32ScriptSizeMax, IMG_CHAR* pszFormat, PDUMP_va_list vaArgs) -+{ -+ IMG_INT32 n; -+ -+ n = vsnprintf(pszComment, ui32ScriptSizeMax, pszFormat, vaArgs); -+ -+ if (n>=(IMG_INT32)ui32ScriptSizeMax || n==-1) /* glibc >= 2.1 or glibc 2.0 */ -+ { -+ PVR_DPF((PVR_DBG_ERROR, "Buffer overflow detected, pdump output may be incomplete.")); -+ -+ return PVRSRV_ERROR_PDUMP_BUF_OVERFLOW; -+ } -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+ * \name PDumpOSDebugPrintf -+ */ -+IMG_VOID PDumpOSDebugPrintf(IMG_CHAR* pszFormat, ...) -+{ -+ PVR_UNREFERENCED_PARAMETER(pszFormat); -+ -+ /* FIXME: Implement using services PVR_DBG or otherwise with kprintf */ -+} -+ -+/*! -+ * \name PDumpOSSprintf -+ */ -+PVRSRV_ERROR PDumpOSSprintf(IMG_CHAR *pszComment, IMG_UINT32 ui32ScriptSizeMax, IMG_CHAR *pszFormat, ...) -+{ -+ IMG_INT32 n; -+ va_list vaArgs; -+ -+ va_start(vaArgs, pszFormat); -+ -+ n = vsnprintf(pszComment, ui32ScriptSizeMax, pszFormat, vaArgs); -+ -+ va_end(vaArgs); -+ -+ if (n>=(IMG_INT32)ui32ScriptSizeMax || n==-1) /* glibc >= 2.1 or glibc 2.0 */ -+ { -+ PVR_DPF((PVR_DBG_ERROR, "Buffer overflow detected, pdump output may be incomplete.")); -+ -+ return PVRSRV_ERROR_PDUMP_BUF_OVERFLOW; -+ } -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+ * \name PDumpOSBuflen -+ */ -+IMG_UINT32 PDumpOSBuflen(IMG_HANDLE hBuffer, IMG_UINT32 ui32BufferSizeMax) -+{ -+ IMG_CHAR* pszBuf = hBuffer; -+ IMG_UINT32 ui32Count = 0; -+ -+ while ((pszBuf[ui32Count]!=0) && (ui32Count<ui32BufferSizeMax) ) -+ { -+ ui32Count++; -+ } -+ return(ui32Count); -+} -+ -+/*! -+ * \name PDumpOSVerifyLineEnding -+ */ -+IMG_VOID PDumpOSVerifyLineEnding(IMG_HANDLE hBuffer, IMG_UINT32 ui32BufferSizeMax) -+{ -+ IMG_UINT32 ui32Count; -+ IMG_CHAR* pszBuf = hBuffer; -+ -+ /* strlen */ -+ ui32Count = PDumpOSBuflen(hBuffer, ui32BufferSizeMax); -+ -+ /* Put \r \n sequence at the end if it isn't already there */ -+ if ((ui32Count >= 1) && (pszBuf[ui32Count-1] != '\n') && (ui32Count<ui32BufferSizeMax)) -+ { -+ pszBuf[ui32Count] = '\n'; -+ ui32Count++; -+ pszBuf[ui32Count] = '\0'; -+ } -+ if ((ui32Count >= 2) && (pszBuf[ui32Count-2] != '\r') && (ui32Count<ui32BufferSizeMax)) -+ { -+ pszBuf[ui32Count-1] = '\r'; -+ pszBuf[ui32Count] = '\n'; -+ ui32Count++; -+ pszBuf[ui32Count] = '\0'; -+ } -+} -+ -+/*! -+ * \name PDumpOSGetStream -+ */ -+IMG_HANDLE PDumpOSGetStream(IMG_UINT32 ePDumpStream) -+{ -+ return (IMG_HANDLE)gsDBGPdumpState.psStream[ePDumpStream]; -+} -+ -+/*! -+ * \name PDumpOSGetStreamOffset -+ */ -+IMG_UINT32 PDumpOSGetStreamOffset(IMG_UINT32 ePDumpStream) -+{ -+ PDBG_STREAM psStream = gsDBGPdumpState.psStream[ePDumpStream]; -+ return gpfnDbgDrv->pfnGetStreamOffset(psStream); -+} -+ -+/*! -+ * \name PDumpOSGetParamFileNum -+ */ -+IMG_UINT32 PDumpOSGetParamFileNum(IMG_VOID) -+{ -+ return gsDBGPdumpState.ui32ParamFileNum; -+} -+ -+/*! -+ * \name PDumpOSWriteString -+ */ -+IMG_BOOL PDumpOSWriteString(IMG_HANDLE hStream, -+ IMG_UINT8 *psui8Data, -+ IMG_UINT32 ui32Size, -+ IMG_UINT32 ui32Flags) -+{ -+ PDBG_STREAM psStream = (PDBG_STREAM)hStream; -+ return PDumpWriteILock(psStream, -+ psui8Data, -+ ui32Size, -+ ui32Flags); -+} -+ -+/*! -+ * \name PDumpOSCheckForSplitting -+ */ -+IMG_VOID PDumpOSCheckForSplitting(IMG_HANDLE hStream, IMG_UINT32 ui32Size, IMG_UINT32 ui32Flags) -+{ -+ /* File size limit not implemented for this OS. -+ */ -+ PVR_UNREFERENCED_PARAMETER(hStream); -+ PVR_UNREFERENCED_PARAMETER(ui32Size); -+ PVR_UNREFERENCED_PARAMETER(ui32Flags); -+} -+ -+/*! -+ * \name PDumpOSJTInitialised -+ */ -+IMG_BOOL PDumpOSJTInitialised(IMG_VOID) -+{ -+ if(gpfnDbgDrv) -+ { -+ return IMG_TRUE; -+ } -+ return IMG_FALSE; -+} -+ -+/*! -+ * \name PDumpOSIsSuspended -+ */ -+inline IMG_BOOL PDumpOSIsSuspended(IMG_VOID) -+{ -+ return (atomic_read(&gsPDumpSuspended) != 0) ? IMG_TRUE : IMG_FALSE; -+} -+ -+/*! -+ * \name PDumpOSCPUVAddrToDevPAddr -+ */ -+IMG_VOID PDumpOSCPUVAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType, -+ IMG_HANDLE hOSMemHandle, -+ IMG_UINT32 ui32Offset, -+ IMG_UINT8 *pui8LinAddr, -+ IMG_UINT32 ui32PageSize, -+ IMG_DEV_PHYADDR *psDevPAddr) -+{ -+ IMG_CPU_PHYADDR sCpuPAddr; -+ -+ PVR_UNREFERENCED_PARAMETER(pui8LinAddr); -+ PVR_UNREFERENCED_PARAMETER(ui32PageSize); /* for when no assert */ -+ -+ /* Caller must now alway supply hOSMemHandle, even though we only (presently) -+ use it here in the linux implementation */ -+ -+ PVR_ASSERT (hOSMemHandle != IMG_NULL); -+ -+ sCpuPAddr = OSMemHandleToCpuPAddr(hOSMemHandle, ui32Offset); -+ PVR_ASSERT((sCpuPAddr.uiAddr & (ui32PageSize - 1)) == 0); -+ -+ /* convert CPU physical addr to device physical */ -+ *psDevPAddr = SysCpuPAddrToDevPAddr(eDeviceType, sCpuPAddr); -+} -+ -+/*! -+ * \name PDumpOSCPUVAddrToPhysPages -+ */ -+IMG_VOID PDumpOSCPUVAddrToPhysPages(IMG_HANDLE hOSMemHandle, -+ IMG_UINT32 ui32Offset, -+ IMG_PUINT8 pui8LinAddr, -+ IMG_UINTPTR_T ui32DataPageMask, -+ IMG_UINT32 *pui32PageOffset) -+{ -+ if(hOSMemHandle) -+ { -+ /* -+ * If a Services memory handle is provided then use it. -+ */ -+ IMG_CPU_PHYADDR sCpuPAddr; -+ -+ PVR_UNREFERENCED_PARAMETER(pui8LinAddr); -+ -+ sCpuPAddr = OSMemHandleToCpuPAddr(hOSMemHandle, ui32Offset); -+ *pui32PageOffset = sCpuPAddr.uiAddr & ui32DataPageMask; -+ } -+ else -+ { -+ PVR_UNREFERENCED_PARAMETER(hOSMemHandle); -+ PVR_UNREFERENCED_PARAMETER(ui32Offset); -+ -+ *pui32PageOffset = ((IMG_UINTPTR_T)pui8LinAddr & ui32DataPageMask); -+ } -+} -+ -+/*! -+ * \name PDumpOSDebugDriverWrite -+ */ -+IMG_UINT32 PDumpOSDebugDriverWrite( PDBG_STREAM psStream, -+ PDUMP_DDWMODE eDbgDrvWriteMode, -+ IMG_UINT8 *pui8Data, -+ IMG_UINT32 ui32BCount, -+ IMG_UINT32 ui32Level, -+ IMG_UINT32 ui32DbgDrvFlags) -+{ -+ switch(eDbgDrvWriteMode) -+ { -+ case PDUMP_WRITE_MODE_CONTINUOUS: -+ PVR_UNREFERENCED_PARAMETER(ui32DbgDrvFlags); -+ return gpfnDbgDrv->pfnDBGDrivWrite2(psStream, pui8Data, ui32BCount, ui32Level); -+ case PDUMP_WRITE_MODE_LASTFRAME: -+ return gpfnDbgDrv->pfnWriteLF(psStream, pui8Data, ui32BCount, ui32Level, ui32DbgDrvFlags); -+ case PDUMP_WRITE_MODE_BINCM: -+ PVR_UNREFERENCED_PARAMETER(ui32DbgDrvFlags); -+ return gpfnDbgDrv->pfnWriteBINCM(psStream, pui8Data, ui32BCount, ui32Level); -+ case PDUMP_WRITE_MODE_PERSISTENT: -+ PVR_UNREFERENCED_PARAMETER(ui32DbgDrvFlags); -+ return gpfnDbgDrv->pfnWritePersist(psStream, pui8Data, ui32BCount, ui32Level); -+ default: -+ PVR_UNREFERENCED_PARAMETER(ui32DbgDrvFlags); -+ break; -+ } -+ return 0xFFFFFFFFU; -+} -+ -+/*! -+ * \name PDumpOSReleaseExecution -+ */ -+IMG_VOID PDumpOSReleaseExecution(IMG_VOID) -+{ -+ OSReleaseThreadQuanta(); -+} -+ -+/************************************************************************** -+ * Function Name : PDumpInit -+ * Outputs : None -+ * Returns : -+ * Description : Reset connection to vldbgdrv -+ * Then try to connect to PDUMP streams -+**************************************************************************/ -+IMG_VOID PDumpInit(IMG_VOID) -+{ -+ IMG_UINT32 i; -+ DBGKM_CONNECT_NOTIFIER sConnectNotifier; -+ -+ /* If we tried this earlier, then we might have connected to the driver -+ * But if pdump.exe was running then the stream connected would fail -+ */ -+ if (!gpfnDbgDrv) -+ { -+ DBGDrvGetServiceTable(&gpfnDbgDrv); -+ -+ -+ // If something failed then no point in trying to connect streams -+ if (gpfnDbgDrv == IMG_NULL) -+ { -+ return; -+ } -+ -+ /* -+ * Pass the connection notify callback -+ */ -+ sConnectNotifier.pfnConnectNotifier = &PDumpConnectionNotify; -+ gpfnDbgDrv->pfnSetConnectNotifier(sConnectNotifier); -+ -+ if(!gsDBGPdumpState.pszFile) -+ { -+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_FILENAME_SIZE_MAX, (IMG_PVOID *)&gsDBGPdumpState.pszFile, 0, -+ "Filename string") != PVRSRV_OK) -+ { -+ goto init_failed; -+ } -+ } -+ -+ if(!gsDBGPdumpState.pszMsg) -+ { -+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_MSG_SIZE_MAX, (IMG_PVOID *)&gsDBGPdumpState.pszMsg, 0, -+ "Message string") != PVRSRV_OK) -+ { -+ goto init_failed; -+ } -+ } -+ -+ if(!gsDBGPdumpState.pszScript) -+ { -+ if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_SCRIPT_SIZE_MAX, (IMG_PVOID *)&gsDBGPdumpState.pszScript, 0, -+ "Script string") != PVRSRV_OK) -+ { -+ goto init_failed; -+ } -+ } -+ -+ for(i=0; i < PDUMP_NUM_STREAMS; i++) -+ { -+ gsDBGPdumpState.psStream[i] = gpfnDbgDrv->pfnCreateStream(pszStreamName[i], -+ DEBUG_CAPMODE_FRAMED, -+ DEBUG_OUTMODE_STREAMENABLE, -+ 0, -+ 10); -+ -+ gpfnDbgDrv->pfnSetCaptureMode(gsDBGPdumpState.psStream[i],DEBUG_CAPMODE_FRAMED,0xFFFFFFFF, 0xFFFFFFFF, 1); -+ gpfnDbgDrv->pfnSetFrame(gsDBGPdumpState.psStream[i],0); -+ } -+ -+ PDUMPCOMMENT("Driver Product Name: %s", VS_PRODUCT_NAME); -+ PDUMPCOMMENT("Driver Product Version: %s (%s)", PVRVERSION_STRING, PVRVERSION_FAMILY); -+ PDUMPCOMMENT("Start of Init Phase"); -+ } -+ -+ return; -+ -+init_failed: -+ -+ if(gsDBGPdumpState.pszFile) -+ { -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_FILENAME_SIZE_MAX, (IMG_PVOID) gsDBGPdumpState.pszFile, 0); -+ gsDBGPdumpState.pszFile = IMG_NULL; -+ } -+ -+ if(gsDBGPdumpState.pszScript) -+ { -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_SCRIPT_SIZE_MAX, (IMG_PVOID) gsDBGPdumpState.pszScript, 0); -+ gsDBGPdumpState.pszScript = IMG_NULL; -+ } -+ -+ if(gsDBGPdumpState.pszMsg) -+ { -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_MSG_SIZE_MAX, (IMG_PVOID) gsDBGPdumpState.pszMsg, 0); -+ gsDBGPdumpState.pszMsg = IMG_NULL; -+ } -+ -+ /* -+ * Remove the connection notify callback -+ */ -+ sConnectNotifier.pfnConnectNotifier = 0; -+ gpfnDbgDrv->pfnSetConnectNotifier(sConnectNotifier); -+ -+ gpfnDbgDrv = IMG_NULL; -+} -+ -+ -+IMG_VOID PDumpDeInit(IMG_VOID) -+{ -+ IMG_UINT32 i; -+ DBGKM_CONNECT_NOTIFIER sConnectNotifier; -+ -+ for(i=0; i < PDUMP_NUM_STREAMS; i++) -+ { -+ gpfnDbgDrv->pfnDestroyStream(gsDBGPdumpState.psStream[i]); -+ } -+ -+ if(gsDBGPdumpState.pszFile) -+ { -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_FILENAME_SIZE_MAX, (IMG_PVOID) gsDBGPdumpState.pszFile, 0); -+ gsDBGPdumpState.pszFile = IMG_NULL; -+ } -+ -+ if(gsDBGPdumpState.pszScript) -+ { -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_SCRIPT_SIZE_MAX, (IMG_PVOID) gsDBGPdumpState.pszScript, 0); -+ gsDBGPdumpState.pszScript = IMG_NULL; -+ } -+ -+ if(gsDBGPdumpState.pszMsg) -+ { -+ OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_MSG_SIZE_MAX, (IMG_PVOID) gsDBGPdumpState.pszMsg, 0); -+ gsDBGPdumpState.pszMsg = IMG_NULL; -+ } -+ -+ /* -+ * Remove the connection notify callback -+ */ -+ sConnectNotifier.pfnConnectNotifier = 0; -+ gpfnDbgDrv->pfnSetConnectNotifier(sConnectNotifier); -+ -+ gpfnDbgDrv = IMG_NULL; -+} -+ -+/************************************************************************** -+ * Function Name : PDumpStartInitPhaseKM -+ * Inputs : None -+ * Outputs : None -+ * Returns : None -+ * Description : Resume init phase state -+**************************************************************************/ -+PVRSRV_ERROR PDumpStartInitPhaseKM(IMG_VOID) -+{ -+ IMG_UINT32 i; -+ -+ if (gpfnDbgDrv) -+ { -+ PDUMPCOMMENT("Start Init Phase"); -+ for(i=0; i < PDUMP_NUM_STREAMS; i++) -+ { -+ gpfnDbgDrv->pfnStartInitPhase(gsDBGPdumpState.psStream[i]); -+ } -+ } -+ return PVRSRV_OK; -+} -+ -+/************************************************************************** -+ * Function Name : PDumpStopInitPhaseKM -+ * Inputs : None -+ * Outputs : None -+ * Returns : None -+ * Description : End init phase state -+**************************************************************************/ -+PVRSRV_ERROR PDumpStopInitPhaseKM(IMG_VOID) -+{ -+ IMG_UINT32 i; -+ -+ if (gpfnDbgDrv) -+ { -+ PDUMPCOMMENT("Stop Init Phase"); -+ -+ for(i=0; i < PDUMP_NUM_STREAMS; i++) -+ { -+ gpfnDbgDrv->pfnStopInitPhase(gsDBGPdumpState.psStream[i]); -+ } -+ } -+ return PVRSRV_OK; -+} -+ -+/************************************************************************** -+ * Function Name : PDumpIsLastCaptureFrameKM -+ * Inputs : None -+ * Outputs : None -+ * Returns : True or false -+ * Description : Tests whether the current frame is being pdumped -+**************************************************************************/ -+IMG_BOOL PDumpIsLastCaptureFrameKM(IMG_VOID) -+{ -+ return gpfnDbgDrv->pfnIsLastCaptureFrame(gsDBGPdumpState.psStream[PDUMP_STREAM_SCRIPT2]); -+} -+ -+ -+/************************************************************************** -+ * Function Name : PDumpIsCaptureFrameKM -+ * Inputs : None -+ * Outputs : None -+ * Returns : True or false -+ * Description : Tests whether the current frame is being pdumped -+**************************************************************************/ -+IMG_BOOL PDumpOSIsCaptureFrameKM(IMG_VOID) -+{ -+ if (PDumpSuspended()) -+ { -+ return IMG_FALSE; -+ } -+ return gpfnDbgDrv->pfnIsCaptureFrame(gsDBGPdumpState.psStream[PDUMP_STREAM_SCRIPT2], IMG_FALSE); -+} -+ -+/************************************************************************** -+ * Function Name : PDumpSetFrameKM -+ * Inputs : None -+ * Outputs : None -+ * Returns : None -+ * Description : Sets a frame -+**************************************************************************/ -+PVRSRV_ERROR PDumpOSSetFrameKM(IMG_UINT32 ui32Frame) -+{ -+ IMG_UINT32 ui32Stream; -+ -+ for (ui32Stream = 0; ui32Stream < PDUMP_NUM_STREAMS; ui32Stream++) -+ { -+ if (gsDBGPdumpState.psStream[ui32Stream]) -+ { -+ DbgSetFrame(gsDBGPdumpState.psStream[ui32Stream], ui32Frame); -+ } -+ } -+ -+ return PVRSRV_OK; -+} -+ -+ -+/***************************************************************************** -+ FUNCTION : PDumpWriteString2 -+ -+ PURPOSE : -+ -+ PARAMETERS : -+ -+ RETURNS : -+*****************************************************************************/ -+static IMG_BOOL PDumpWriteString2(IMG_CHAR * pszString, IMG_UINT32 ui32Flags) -+{ -+ return PDumpWriteILock(gsDBGPdumpState.psStream[PDUMP_STREAM_SCRIPT2], (IMG_UINT8 *) pszString, strlen(pszString), ui32Flags); -+} -+ -+ -+/***************************************************************************** -+ FUNCTION : PDumpWriteILock -+ -+ PURPOSE : Writes, making sure it all goes... -+ -+ PARAMETERS : -+ -+ RETURNS : -+*****************************************************************************/ -+static IMG_BOOL PDumpWriteILock(PDBG_STREAM psStream, IMG_UINT8 *pui8Data, IMG_UINT32 ui32Count, IMG_UINT32 ui32Flags) -+{ -+ IMG_UINT32 ui32Written = 0; -+ if ((psStream == IMG_NULL) || PDumpSuspended() || ((ui32Flags & PDUMP_FLAGS_NEVER) != 0)) -+ { -+ PVR_DPF((PVR_DBG_MESSAGE, "PDumpWriteILock: Failed to write 0x%x bytes to stream 0x%p", ui32Count, psStream)); -+ return IMG_TRUE; -+ } -+ -+ -+ /* -+ Set the stream marker to split output files -+ */ -+ -+ if (psStream == gsDBGPdumpState.psStream[PDUMP_STREAM_PARAM2]) -+ { -+ IMG_UINT32 ui32ParamOutPos = gpfnDbgDrv->pfnGetStreamOffset(gsDBGPdumpState.psStream[PDUMP_STREAM_PARAM2]); -+ -+ if (ui32ParamOutPos + ui32Count > MAX_FILE_SIZE) -+ { -+ if ((gsDBGPdumpState.psStream[PDUMP_STREAM_SCRIPT2] && PDumpWriteString2("\r\n-- Splitting pdump output file\r\n\r\n", ui32Flags))) -+ { -+ DbgSetMarker(gsDBGPdumpState.psStream[PDUMP_STREAM_PARAM2], ui32ParamOutPos); -+ gsDBGPdumpState.ui32ParamFileNum++; -+ } -+ } -+ } -+ -+ ui32Written = DbgWrite(psStream, pui8Data, ui32Count, ui32Flags); -+ -+ if (ui32Written == 0xFFFFFFFF) -+ { -+ return IMG_FALSE; -+ } -+ -+ return IMG_TRUE; -+} -+ -+/***************************************************************************** -+ FUNCTION : DbgSetFrame -+ -+ PURPOSE : Sets the frame in the stream -+ -+ PARAMETERS : psStream - Stream pointer -+ ui32Frame - Frame number to set -+ -+ RETURNS : None -+*****************************************************************************/ -+static IMG_VOID DbgSetFrame(PDBG_STREAM psStream, IMG_UINT32 ui32Frame) -+{ -+ gpfnDbgDrv->pfnSetFrame(psStream, ui32Frame); -+} -+ -+/***************************************************************************** -+ FUNCTION : DbgSetMarker -+ -+ PURPOSE : Sets the marker of the stream to split output files -+ -+ PARAMETERS : psStream - Stream pointer -+ ui32Marker - Marker number to set -+ -+ RETURNS : None -+*****************************************************************************/ -+static IMG_VOID DbgSetMarker(PDBG_STREAM psStream, IMG_UINT32 ui32Marker) -+{ -+ gpfnDbgDrv->pfnSetMarker(psStream, ui32Marker); -+} -+ -+IMG_VOID PDumpSuspendKM(IMG_VOID) -+{ -+ atomic_inc(&gsPDumpSuspended); -+} -+ -+IMG_VOID PDumpResumeKM(IMG_VOID) -+{ -+ atomic_dec(&gsPDumpSuspended); -+} -+ -+/* Set to 1 if you want to debug PDump locking issues */ -+#define DEBUG_PDUMP_LOCKS 0 -+ -+#if DEBUG_PDUMP_LOCKS -+static IMG_UINT32 ui32Count=0; -+static IMG_UINT32 aui32LockLine[2] = {0}; -+static IMG_UINT32 aui32UnlockLine[2] = {0}; -+static IMG_UINT32 ui32LockLineCount = 0; -+static IMG_UINT32 ui32UnlockLineCount = 0; -+#endif -+ -+IMG_VOID PDumpOSLock(IMG_UINT32 ui32Line) -+{ -+#if DEBUG_PDUMP_LOCKS -+ aui32LockLine[ui32LockLineCount++ % 2] = ui32Line; -+ ui32Count++; -+ if (ui32Count == 2) -+ { -+ IMG_UINT32 i; -+ printk(KERN_ERR "Double lock\n"); -+ dump_stack(); -+ for (i=0;i<2;i++) -+ { -+ printk(KERN_ERR "Lock[%d] = %d, Unlock[%d] = %d\n", i, aui32LockLine[i],i, aui32UnlockLine[i]); -+ } -+ } -+#endif -+ mutex_lock(&sPDumpLock); -+} -+ -+IMG_VOID PDumpOSUnlock(IMG_UINT32 ui32Line) -+{ -+ mutex_unlock(&sPDumpLock); -+#if DEBUG_PDUMP_LOCKS -+ aui32UnlockLine[ui32UnlockLineCount++ % 2] = ui32Line; -+ ui32Count--; -+#endif -+} -+ -+IMG_VOID PDumpOSLockMessageBuffer(IMG_VOID) -+{ -+ mutex_lock(&sPDumpMsgLock); -+} -+ -+IMG_VOID PDumpOSUnlockMessageBuffer(IMG_VOID) -+{ -+ mutex_unlock(&sPDumpMsgLock); -+} -+ -+#endif /* #if defined (PDUMP) */ -+#endif /* #if defined (SUPPORT_SGX) */ -+/***************************************************************************** -+ End of file (PDUMP.C) -+*****************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/private_data.h b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/private_data.h -new file mode 100644 -index 0000000..83cee45 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/private_data.h -@@ -0,0 +1,90 @@ -+/*************************************************************************/ /*! -+@Title Linux private data structure -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#ifndef __INCLUDED_PRIVATE_DATA_H_ -+#define __INCLUDED_PRIVATE_DATA_H_ -+ -+#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT) -+#include <linux/list.h> -+#include <drm/drmP.h> -+#endif -+ -+/* This structure is required in the rare case that a process creates -+ * a connection to services, but before closing the file descriptor, -+ * does a fork(). This fork() will duplicate the file descriptor in the -+ * child process. If the parent process dies before the child, this can -+ * cause the PVRSRVRelease() method to be called in a different process -+ * context than the original PVRSRVOpen(). This is bad because we need -+ * to update the per-process data reference count and/or free the -+ * per-process data. So we must keep a record of which PID's per-process -+ * data to inspect during ->release(). -+ */ -+ -+typedef struct -+{ -+ /* PID that created this services connection */ -+ IMG_UINT32 ui32OpenPID; -+ -+ /* Global kernel MemInfo handle */ -+ IMG_HANDLE hKernelMemInfo; -+ -+#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT) -+ /* The private data is on a list in the per-process data structure */ -+ struct list_head sDRMAuthListItem; -+ -+ struct drm_file *psDRMFile; -+#endif -+ -+#if defined(SUPPORT_MEMINFO_IDS) -+ /* Globally unique "stamp" for kernel MemInfo */ -+ IMG_UINT64 ui64Stamp; -+#endif /* defined(SUPPORT_MEMINFO_IDS) */ -+ -+ /* Accounting for OSAllocMem */ -+ IMG_HANDLE hBlockAlloc; -+ -+#if defined(SUPPORT_DRI_DRM_EXT) -+ IMG_PVOID pPriv; /*private data for extending this struct*/ -+#endif -+} -+PVRSRV_FILE_PRIVATE_DATA; -+ -+#endif /* __INCLUDED_PRIVATE_DATA_H_ */ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/proc.c b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/proc.c -new file mode 100644 -index 0000000..01dd813 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/proc.c -@@ -0,0 +1,1493 @@ -+/*************************************************************************/ /*! -+@Title Proc files implementation. -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Functions for creating and reading proc filesystem entries. -+ Proc filesystem support must be built into the kernel for -+ these functions to be any use. -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#include <linux/version.h> -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)) -+#ifndef AUTOCONF_INCLUDED -+#include <linux/config.h> -+#endif -+#endif -+ -+#include <linux/init.h> -+#include <linux/module.h> -+#include <linux/fs.h> -+#include <linux/proc_fs.h> -+#include <linux/seq_file.h> -+ -+#include "services_headers.h" -+ -+#include "queue.h" -+#include "resman.h" -+#include "pvrmmap.h" -+#include "pvr_debug.h" -+#include "pvrversion.h" -+#include "proc.h" -+#include "perproc.h" -+#include "env_perproc.h" -+#include "linkage.h" -+ -+#include "lists.h" -+ -+// The proc entry for our /proc/pvr directory -+static struct proc_dir_entry * dir; -+ -+static const IMG_CHAR PVRProcDirRoot[] = "pvr"; -+ -+static IMG_INT pvr_proc_open(struct inode *inode,struct file *file); -+static void *pvr_proc_seq_start (struct seq_file *m, loff_t *pos); -+static void pvr_proc_seq_stop (struct seq_file *m, void *v); -+static void *pvr_proc_seq_next (struct seq_file *m, void *v, loff_t *pos); -+static int pvr_proc_seq_show (struct seq_file *m, void *v); -+static ssize_t pvr_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos); -+ -+static struct file_operations pvr_proc_operations = -+{ -+ .open = pvr_proc_open, -+ .read = seq_read, -+ .write = pvr_proc_write, -+ .llseek = seq_lseek, -+ .release = seq_release, -+}; -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)) -+static ssize_t pvr_proc_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos); -+static struct file_operations pvr_read_proc_operations = -+{ -+.open = pvr_proc_open, -+.read = pvr_proc_read, -+.write = pvr_proc_write, -+.llseek = seq_lseek, -+.release = seq_release, -+}; -+#endif -+ -+static struct seq_operations pvr_proc_seq_operations = -+{ -+ .start = pvr_proc_seq_start, -+ .next = pvr_proc_seq_next, -+ .stop = pvr_proc_seq_stop, -+ .show = pvr_proc_seq_show, -+}; -+ -+static struct proc_dir_entry* g_pProcQueue; -+static struct proc_dir_entry* g_pProcVersion; -+static struct proc_dir_entry* g_pProcSysNodes; -+ -+#ifdef DEBUG -+static struct proc_dir_entry* g_pProcDebugLevel; -+#endif -+ -+#ifdef PVR_MANUAL_POWER_CONTROL -+static struct proc_dir_entry* g_pProcPowerLevel; -+#endif -+ -+ -+static void ProcSeqShowVersion(struct seq_file *sfile,void* el); -+ -+static void ProcSeqShowSysNodes(struct seq_file *sfile,void* el); -+static void* ProcSeqOff2ElementSysNodes(struct seq_file * sfile, loff_t off); -+ -+/*! -+****************************************************************************** -+ -+ @Function : printAppend -+ -+ @Description -+ -+ Print into the supplied buffer at the specified offset remaining within -+ the specified total buffer size. -+ -+ @Input size : the total size of the buffer -+ -+ @Input off : the offset into the buffer to start printing -+ -+ @Input format : the printf format string -+ -+ @Input ... : format args -+ -+ @Return : The number of chars now in the buffer (original value of 'off' -+ plus number of chars added); 'size' if full. -+ -+*****************************************************************************/ -+off_t printAppend(IMG_CHAR * buffer, size_t size, off_t off, const IMG_CHAR * format, ...) -+{ -+ IMG_INT n; -+ size_t space = size - (size_t)off; -+ va_list ap; -+ -+ va_start (ap, format); -+ -+ n = vsnprintf (buffer+off, space, format, ap); -+ -+ va_end (ap); -+ /* According to POSIX, n is greater than or equal to the size available if -+ * the print would have overflowed the buffer. Other platforms may -+ * return -1 if printing was truncated. -+ */ -+ if (n >= (IMG_INT)space || n < 0) -+ { -+ /* Ensure final string is terminated */ -+ buffer[size - 1] = 0; -+ return (off_t)(size - 1); -+ } -+ else -+ { -+ return (off + (off_t)n); -+ } -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function : ProcSeq1ElementOff2Element -+ -+ @Description -+ -+ Heleper Offset -> Element function for /proc files with only one entry -+ without header. -+ -+ @Input sfile : seq_file object related to /proc/ file -+ -+ @Input off : the offset into the buffer (id of object) -+ -+ @Return : Pointer to element to be shown. -+ -+*****************************************************************************/ -+void* ProcSeq1ElementOff2Element(struct seq_file *sfile, loff_t off) -+{ -+ PVR_UNREFERENCED_PARAMETER(sfile); -+ // Return anything that is not PVR_RPOC_SEQ_START_TOKEN and NULL -+ if(!off) -+ return (void*)2; -+ return NULL; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function : ProcSeq1ElementHeaderOff2Element -+ -+ @Description -+ -+ Heleper Offset -> Element function for /proc files with only one entry -+ with header. -+ -+ @Input sfile : seq_file object related to /proc/ file -+ -+ @Input off : the offset into the buffer (id of object) -+ -+ @Return : Pointer to element to be shown. -+ -+*****************************************************************************/ -+void* ProcSeq1ElementHeaderOff2Element(struct seq_file *sfile, loff_t off) -+{ -+ PVR_UNREFERENCED_PARAMETER(sfile); -+ -+ if(!off) -+ { -+ return PVR_PROC_SEQ_START_TOKEN; -+ } -+ -+ // Return anything that is not PVR_RPOC_SEQ_START_TOKEN and NULL -+ if(off == 1) -+ return (void*)2; -+ -+ return NULL; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function : pvr_proc_open -+ -+ @Description -+ File opening function passed to proc_dir_entry->proc_fops for /proc entries -+ created by CreateProcReadEntrySeq. -+ -+ @Input inode : inode entry of opened /proc file -+ -+ @Input file : file entry of opened /proc file -+ -+ @Return : 0 if no errors -+ -+*****************************************************************************/ -+static IMG_INT pvr_proc_open(struct inode *inode,struct file *file) -+{ -+ IMG_INT ret = seq_open(file, &pvr_proc_seq_operations); -+ -+ struct seq_file *seq = (struct seq_file*)file->private_data; -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)) -+ struct proc_dir_entry* pvr_proc_entry = PDE(inode); -+ -+ /* Add pointer to handlers to seq_file structure */ -+ seq->private = pvr_proc_entry->data; -+#else -+ PVR_PROC_SEQ_HANDLERS *data = (PVR_PROC_SEQ_HANDLERS *) PDE_DATA(inode); -+ seq->private = data; -+#endif -+ return ret; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function : pvr_proc_write -+ -+ @Description -+ File writing function passed to proc_dir_entry->proc_fops for /proc files. -+ It's exacly the same function that is used as default one (->fs/proc/generic.c), -+ it calls proc_dir_entry->write_proc for writing procedure. -+ -+*****************************************************************************/ -+static ssize_t pvr_proc_write(struct file *file, const char __user *buffer, -+ size_t count, loff_t *ppos) -+{ -+ struct inode *inode = file->f_path.dentry->d_inode; -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)) -+ struct proc_dir_entry * dp; -+ -+ PVR_UNREFERENCED_PARAMETER(ppos); -+ dp = PDE(inode); -+ -+ if (!dp->write_proc) -+ return -EIO; -+ -+ return dp->write_proc(file, buffer, count, dp->data); -+#else -+ PVR_PROC_SEQ_HANDLERS *data = (PVR_PROC_SEQ_HANDLERS *) PDE_DATA(inode); -+ PVR_UNREFERENCED_PARAMETER(ppos); -+ if (!data->write_proc) -+ return -EIO; -+ return data->write_proc(file, buffer, count, data); -+#endif -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function : pvr_proc_seq_start -+ -+ @Description -+ Seq_file start function. Detailed description of seq_file workflow can -+ be found here: http://tldp.org/LDP/lkmpg/2.6/html/x861.html. -+ This function ises off2element handler. -+ -+ @Input proc_seq_file : sequence file entry -+ -+ @Input pos : offset within file (id of entry) -+ -+ @Return : Pointer to element from we start enumeration (0 ends it) -+ -+*****************************************************************************/ -+static void *pvr_proc_seq_start (struct seq_file *proc_seq_file, loff_t *pos) -+{ -+ PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)proc_seq_file->private; -+ if(handlers->startstop != NULL) -+ handlers->startstop(proc_seq_file, IMG_TRUE); -+ return handlers->off2element(proc_seq_file, *pos); -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function : pvr_proc_seq_stop -+ -+ @Description -+ Seq_file stop function. Detailed description of seq_file workflow can -+ be found here: http://tldp.org/LDP/lkmpg/2.6/html/x861.html. -+ -+ @Input proc_seq_file : sequence file entry -+ -+ @Input v : current element pointer -+ -+*****************************************************************************/ -+static void pvr_proc_seq_stop (struct seq_file *proc_seq_file, void *v) -+{ -+ PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)proc_seq_file->private; -+ PVR_UNREFERENCED_PARAMETER(v); -+ -+ if(handlers->startstop != NULL) -+ handlers->startstop(proc_seq_file, IMG_FALSE); -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function : pvr_proc_seq_next -+ -+ @Description -+ Seq_file next element function. Detailed description of seq_file workflow can -+ be found here: http://tldp.org/LDP/lkmpg/2.6/html/x861.html. -+ It uses supplied 'next' handler for fetching next element (or 0 if there is no one) -+ -+ @Input proc_seq_file : sequence file entry -+ -+ @Input pos : offset within file (id of entry) -+ -+ @Input v : current element pointer -+ -+ @Return : next element pointer (or 0 if end) -+ -+*****************************************************************************/ -+static void *pvr_proc_seq_next (struct seq_file *proc_seq_file, void *v, loff_t *pos) -+{ -+ PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)proc_seq_file->private; -+ (*pos)++; -+ if( handlers->next != NULL) -+ return handlers->next( proc_seq_file, v, *pos ); -+ return handlers->off2element(proc_seq_file, *pos); -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function : pvr_proc_seq_show -+ -+ @Description -+ Seq_file show element function. Detailed description of seq_file workflow can -+ be found here: http://tldp.org/LDP/lkmpg/2.6/html/x861.html. -+ It call proper 'show' handler to show (dump) current element using seq_* functions -+ -+ @Input proc_seq_file : sequence file entry -+ -+ @Input v : current element pointer -+ -+ @Return : 0 if everything is OK -+ -+*****************************************************************************/ -+static int pvr_proc_seq_show (struct seq_file *proc_seq_file, void *v) -+{ -+ PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)proc_seq_file->private; -+ handlers->show( proc_seq_file,v ); -+ return 0; -+} -+ -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function : CreateProcEntryInDirSeq -+ -+ @Description -+ -+ Create a file under the given directory. These dynamic files can be used at -+ runtime to get or set information about the device. Whis version uses seq_file -+ interface -+ -+ @Input pdir : parent directory -+ -+ @Input name : the name of the file to create -+ -+ @Input data : aditional data that will be passed to handlers -+ -+ @Input next_handler : the function to call to provide the next element. OPTIONAL, if not -+ supplied, then off2element function is used instead -+ -+ @Input show_handler : the function to call to show element -+ -+ @Input off2element_handler : the function to call when it is needed to translate offest to element -+ -+ @Input startstop_handler : the function to call when output memory page starts or stops. OPTIONAL. -+ -+ @Input whandler : the function to interpret writes from the user -+ -+ @Return Ptr to proc entry , 0 for failure -+ -+ -+*****************************************************************************/ -+static struct proc_dir_entry* CreateProcEntryInDirSeq( -+ struct proc_dir_entry *pdir, -+ const IMG_CHAR * name, -+ IMG_VOID* data, -+ pvr_next_proc_seq_t next_handler, -+ pvr_show_proc_seq_t show_handler, -+ pvr_off2element_proc_seq_t off2element_handler, -+ pvr_startstop_proc_seq_t startstop_handler, -+ write_proc_t whandler -+ ) -+{ -+ -+ struct proc_dir_entry * file; -+ mode_t mode; -+ PVR_PROC_SEQ_HANDLERS *seq_handlers; -+ -+ if (!dir) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "CreateProcEntryInDirSeq: cannot make proc entry /proc/%s/%s: no parent", PVRProcDirRoot, name)); -+ return NULL; -+ } -+ -+ mode = S_IFREG; -+ -+ if (show_handler) -+ { -+ mode |= S_IRUGO; -+ } -+ -+ if (whandler) -+ { -+ mode |= S_IWUSR; -+ } -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)) -+ file=create_proc_entry(name, mode, pdir); -+ -+ if (file) -+ { -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)) -+ file->owner = THIS_MODULE; -+#endif -+ -+ file->proc_fops = &pvr_proc_operations; -+ file->write_proc = whandler; -+ -+ /* Pass the handlers */ -+ file->data = kmalloc(sizeof(PVR_PROC_SEQ_HANDLERS), GFP_KERNEL); -+ if(file->data) -+ { -+ seq_handlers = (PVR_PROC_SEQ_HANDLERS*)file->data; -+ seq_handlers->next = next_handler; -+ seq_handlers->show = show_handler; -+ seq_handlers->off2element = off2element_handler; -+ seq_handlers->startstop = startstop_handler; -+ seq_handlers->data = data; -+ -+ return file; -+ } -+ } -+#else -+/* Pass the handlers */ -+ seq_handlers = (PVR_PROC_SEQ_HANDLERS*) kmalloc(sizeof(PVR_PROC_SEQ_HANDLERS), GFP_KERNEL); -+ if(seq_handlers) -+ { -+ seq_handlers->next = next_handler; -+ seq_handlers->show = show_handler; -+ seq_handlers->off2element = off2element_handler; -+ seq_handlers->startstop = startstop_handler; -+ seq_handlers->data = data; -+ seq_handlers->write_proc = whandler; -+ file=proc_create_data(name, mode, pdir, &pvr_proc_operations,seq_handlers); -+ if (file) -+ return file; -+ kfree (seq_handlers); -+ } -+#endif -+ -+ PVR_DPF((PVR_DBG_ERROR, "CreateProcEntryInDirSeq: cannot make proc entry /proc/%s/%s: no memory", PVRProcDirRoot, name)); -+ return NULL; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function : CreateProcReadEntrySeq -+ -+ @Description -+ -+ Create a file under /proc/pvr. These dynamic files can be used at runtime -+ to get information about the device. Creation WILL fail if proc support is -+ not compiled into the kernel. That said, the Linux kernel is not even happy -+ to build without /proc support these days. This version uses seq_file structure -+ for handling content generation. -+ -+ @Input name : the name of the file to create -+ -+ @Input data : aditional data that will be passed to handlers -+ -+ @Input next_handler : the function to call to provide the next element. OPTIONAL, if not -+ supplied, then off2element function is used instead -+ -+ @Input show_handler : the function to call to show element -+ -+ @Input off2element_handler : the function to call when it is needed to translate offest to element -+ -+ @Input startstop_handler : the function to call when output memory page starts or stops. OPTIONAL. -+ -+ @Return Ptr to proc entry , 0 for failure -+ -+*****************************************************************************/ -+struct proc_dir_entry* CreateProcReadEntrySeq ( -+ const IMG_CHAR * name, -+ IMG_VOID* data, -+ pvr_next_proc_seq_t next_handler, -+ pvr_show_proc_seq_t show_handler, -+ pvr_off2element_proc_seq_t off2element_handler, -+ pvr_startstop_proc_seq_t startstop_handler -+ ) -+{ -+ return CreateProcEntrySeq(name, -+ data, -+ next_handler, -+ show_handler, -+ off2element_handler, -+ startstop_handler, -+ NULL); -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function : CreateProcEntrySeq -+ -+ @Description -+ -+ @Description -+ -+ Create a file under /proc/pvr. These dynamic files can be used at runtime -+ to get information about the device. Creation WILL fail if proc support is -+ not compiled into the kernel. That said, the Linux kernel is not even happy -+ to build without /proc support these days. This version uses seq_file structure -+ for handling content generation and is fuller than CreateProcReadEntrySeq (it -+ supports write access); -+ -+ @Input name : the name of the file to create -+ -+ @Input data : aditional data that will be passed to handlers -+ -+ @Input next_handler : the function to call to provide the next element. OPTIONAL, if not -+ supplied, then off2element function is used instead -+ -+ @Input show_handler : the function to call to show element -+ -+ @Input off2element_handler : the function to call when it is needed to translate offest to element -+ -+ @Input startstop_handler : the function to call when output memory page starts or stops. OPTIONAL. -+ -+ @Input whandler : the function to interpret writes from the user -+ -+ @Return Ptr to proc entry , 0 for failure -+ -+*****************************************************************************/ -+struct proc_dir_entry* CreateProcEntrySeq ( -+ const IMG_CHAR * name, -+ IMG_VOID* data, -+ pvr_next_proc_seq_t next_handler, -+ pvr_show_proc_seq_t show_handler, -+ pvr_off2element_proc_seq_t off2element_handler, -+ pvr_startstop_proc_seq_t startstop_handler, -+ write_proc_t whandler -+ ) -+{ -+ return CreateProcEntryInDirSeq( -+ dir, -+ name, -+ data, -+ next_handler, -+ show_handler, -+ off2element_handler, -+ startstop_handler, -+ whandler -+ ); -+} -+ -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function : CreatePerProcessProcEntrySeq -+ -+ @Description -+ -+ Create a file under /proc/pvr/<current process ID>. Apart from the -+ directory where the file is created, this works the same way as -+ CreateProcEntry. It's seq_file version. -+ -+ -+ -+ @Input name : the name of the file to create -+ -+ @Input data : aditional data that will be passed to handlers -+ -+ @Input next_handler : the function to call to provide the next element. OPTIONAL, if not -+ supplied, then off2element function is used instead -+ -+ @Input show_handler : the function to call to show element -+ -+ @Input off2element_handler : the function to call when it is needed to translate offest to element -+ -+ @Input startstop_handler : the function to call when output memory page starts or stops. OPTIONAL. -+ -+ @Input whandler : the function to interpret writes from the user -+ -+ @Return Ptr to proc entry , 0 for failure -+ -+*****************************************************************************/ -+struct proc_dir_entry* CreatePerProcessProcEntrySeq ( -+ const IMG_CHAR * name, -+ IMG_VOID* data, -+ pvr_next_proc_seq_t next_handler, -+ pvr_show_proc_seq_t show_handler, -+ pvr_off2element_proc_seq_t off2element_handler, -+ pvr_startstop_proc_seq_t startstop_handler, -+ write_proc_t whandler -+ ) -+{ -+ PVRSRV_ENV_PER_PROCESS_DATA *psPerProc; -+ IMG_UINT32 ui32PID; -+ -+ if (!dir) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntrySeq: /proc/%s doesn't exist", PVRProcDirRoot)); -+ return NULL; -+ } -+ -+ ui32PID = OSGetCurrentProcessIDKM(); -+ -+ psPerProc = PVRSRVPerProcessPrivateData(ui32PID); -+ if (!psPerProc) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntrySeq: no per process data")); -+ -+ return NULL; -+ } -+ -+ if (!psPerProc->psProcDir) -+ { -+ IMG_CHAR dirname[16]; -+ IMG_INT ret; -+ -+ ret = snprintf(dirname, sizeof(dirname), "%u", ui32PID); -+ -+ if (ret <=0 || ret >= (IMG_INT)sizeof(dirname)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: couldn't generate per process proc directory name \"%u\"", ui32PID)); -+ return NULL; -+ } -+ else -+ { -+ psPerProc->psProcDir = proc_mkdir(dirname, dir); -+ if (!psPerProc->psProcDir) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: couldn't create per process proc directory /proc/%s/%u", -+ PVRProcDirRoot, ui32PID)); -+ return NULL; -+ } -+ } -+ } -+ -+ return CreateProcEntryInDirSeq(psPerProc->psProcDir, name, data, next_handler, -+ show_handler,off2element_handler,startstop_handler,whandler); -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function : RemoveProcEntrySeq -+ -+ @Description -+ -+ Remove a single node (created using *Seq function) under /proc/pvr. -+ -+ @Input proc_entry : structure returned by Create function. -+ -+ @Return nothing -+ -+*****************************************************************************/ -+IMG_VOID RemoveProcEntrySeq( struct proc_dir_entry* proc_entry ) -+{ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)) -+ if (dir) -+ { -+ void* data = proc_entry->data ; -+ PVR_DPF((PVR_DBG_MESSAGE, "Removing /proc/%s/%s", PVRProcDirRoot, proc_entry->name)); -+ remove_proc_entry(proc_entry->name, dir); -+ if( data) -+ kfree( data ); -+ } -+#endif -+ -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function : RemovePerProcessProcEntry Seq -+ -+ @Description -+ -+ Remove a single node under the per process proc directory (created by *Seq function). -+ -+ Remove a single node (created using *Seq function) under /proc/pvr. -+ -+ @Input proc_entry : structure returned by Create function. -+ -+ @Return nothing -+ -+*****************************************************************************/ -+IMG_VOID RemovePerProcessProcEntrySeq(struct proc_dir_entry* proc_entry) -+{ -+ PVRSRV_ENV_PER_PROCESS_DATA *psPerProc; -+ -+ psPerProc = LinuxTerminatingProcessPrivateData(); -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)) -+ if (!psPerProc) -+ { -+ psPerProc = PVRSRVFindPerProcessPrivateData(); -+ if (!psPerProc) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: can't " -+ "remove %s, no per process data", proc_entry->name)); -+ return; -+ } -+ } -+ -+ if (psPerProc->psProcDir) -+ { -+ void* data = proc_entry->data ; -+ PVR_DPF((PVR_DBG_MESSAGE, "Removing proc entry %s from %s", proc_entry->name, psPerProc->psProcDir->name)); -+ -+ remove_proc_entry(proc_entry->name, psPerProc->psProcDir); -+ if(data) -+ kfree( data ); -+ } -+#endif -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function : pvr_read_proc_vm -+ -+ @Description -+ -+ When the user accesses the proc filesystem entry for the device, we are -+ called here to create the content for the 'file'. We can print anything we -+ want here. If the info we want to return is too big for one page ('count' -+ chars), we return successive chunks on each call. For a number of ways of -+ achieving this, refer to proc_file_read() in linux/fs/proc/generic.c. -+ -+ Here, as we are accessing lists of information, we output '1' in '*start' to -+ instruct proc to advance 'off' by 1 on each call. The number of chars placed -+ in the buffer is returned. Multiple calls are made here by the proc -+ filesystem until we set *eof. We can return zero without setting eof to -+ instruct proc to flush 'page' (causing it to be printed) if there is not -+ enough space left (eg for a complete line). -+ -+ @Input page : where to write the output -+ -+ @Input start : memory location into which should be written next offset -+ to read from. -+ -+ @Input off : the offset into the /proc file being read -+ -+ @Input count : the size of the buffer 'page' -+ -+ @Input eof : memory location into which 1 should be written when at EOF -+ -+ @Input data : data specific to this /proc file entry -+ -+ @Return : length of string written to page -+ -+*****************************************************************************/ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)) -+ -+static IMG_INT pvr_read_proc(IMG_CHAR *page, IMG_CHAR **start, off_t off, -+ IMG_INT count, IMG_INT *eof, IMG_VOID *data) -+{ -+ /* PRQA S 0307 1 */ /* ignore warning about casting to different pointer type */ -+ pvr_read_proc_t *pprn = (pvr_read_proc_t *)data; -+ -+ off_t len = pprn (page, (size_t)count, off); -+ -+ if (len == END_OF_FILE) -+ { -+ len = 0; -+ *eof = 1; -+ } -+ else if (!len) /* not enough space in the buffer */ -+ { -+ *start = (IMG_CHAR *) 0; /* don't advance the offset */ -+ } -+ else -+ { -+ *start = (IMG_CHAR *) 1; -+ } -+ -+ return len; -+} -+ -+ -+#else -+static ssize_t pvr_proc_read(struct file *file, char __user *buffer,size_t count, loff_t *ppos) -+{ -+ struct inode *inode = file->f_path.dentry->d_inode; -+ PVR_PROC_SEQ_HANDLERS *data = (PVR_PROC_SEQ_HANDLERS *) PDE_DATA(inode); -+ PVR_UNREFERENCED_PARAMETER(ppos); -+ if (!data->read_proc) -+ return -EIO; -+ return -EIO; -+ -+} -+#endif -+/****************************************************************************** -+ -+ @Function : CreateProcEntryInDir -+ -+ @Description -+ -+ Create a file under the given directory. These dynamic files can be used at -+ runtime to get or set information about the device. -+ -+ @Input pdir : parent directory -+ -+ @Input name : the name of the file to create -+ -+ @Input rhandler : the function to supply the content -+ -+ @Input whandler : the function to interpret writes from the user -+ -+ @Return success code : 0 or -errno. -+ -+*****************************************************************************/ -+static IMG_INT CreateProcEntryInDir(struct proc_dir_entry *pdir, const IMG_CHAR * name, read_proc_t rhandler, write_proc_t whandler, IMG_VOID *data) -+{ -+ struct proc_dir_entry * file; -+ mode_t mode; -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)) -+ PVR_PROC_SEQ_HANDLERS *handlers; -+#endif -+ if (!pdir) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "CreateProcEntryInDir: parent directory doesn't exist")); -+ -+ return -ENOMEM; -+ } -+ -+ mode = S_IFREG; -+ -+ if (rhandler) -+ { -+ mode |= S_IRUGO; -+ } -+ -+ if (whandler) -+ { -+ mode |= S_IWUSR; -+ } -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)) -+ file = create_proc_entry(name, mode, pdir); -+ -+ if (file) -+ { -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)) -+ file->owner = THIS_MODULE; -+#endif -+ file->read_proc = rhandler; -+ file->write_proc = whandler; -+ file->data = data; -+ -+ PVR_DPF((PVR_DBG_MESSAGE, "Created proc entry %s in %s", name, pdir->name)); -+ -+ return 0; -+ } -+#else -+ handlers = (PVR_PROC_SEQ_HANDLERS*) kmalloc(sizeof(PVR_PROC_SEQ_HANDLERS), GFP_KERNEL); -+ if (handlers) -+ { -+ handlers->data = data; -+ handlers->read_proc = rhandler; -+ handlers->write_proc = whandler; -+ file = proc_create_data(name, mode, pdir, &pvr_read_proc_operations, handlers); -+ if (file) -+ { -+ PVR_DPF((PVR_DBG_MESSAGE, "Created proc entry %s in %s", name, "?" /*pdir->name*/)); -+ return 0; -+ } -+ kfree (handlers); -+ } -+ PVR_DPF((PVR_DBG_ERROR, "CreateProcEntry: cannot create proc entry %s in %s", name, "?" /*pdir->name*/)); -+#endif -+ -+ -+ return -ENOMEM; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function : CreateProcEntry -+ -+ @Description -+ -+ Create a file under /proc/pvr. These dynamic files can be used at runtime -+ to get or set information about the device. -+ -+ This interface is fuller than CreateProcReadEntry, and supports write access; -+ it is really just a wrapper for the native linux functions. -+ -+ @Input name : the name of the file to create under /proc/pvr -+ -+ @Input rhandler : the function to supply the content -+ -+ @Input whandler : the function to interpret writes from the user -+ -+ @Return success code : 0 or -errno. -+ -+*****************************************************************************/ -+IMG_INT CreateProcEntry(const IMG_CHAR * name, read_proc_t rhandler, write_proc_t whandler, IMG_VOID *data) -+{ -+ return CreateProcEntryInDir(dir, name, rhandler, whandler, data); -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function : CreatePerProcessProcEntry -+ -+ @Description -+ -+ Create a file under /proc/pvr/<current process ID>. Apart from the -+ directory where the file is created, this works the same way as -+ CreateProcEntry. -+ -+ @Input name : the name of the file to create under the per process /proc directory -+ -+ @Input rhandler : the function to supply the content -+ -+ @Input whandler : the function to interpret writes from the user -+ -+ @Return success code : 0 or -errno. -+ -+*****************************************************************************/ -+IMG_INT CreatePerProcessProcEntry(const IMG_CHAR * name, read_proc_t rhandler, write_proc_t whandler, IMG_VOID *data) -+{ -+ PVRSRV_ENV_PER_PROCESS_DATA *psPerProc; -+ IMG_UINT32 ui32PID; -+ -+ if (!dir) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: /proc/%s doesn't exist", PVRProcDirRoot)); -+ -+ return -ENOMEM; -+ } -+ -+ ui32PID = OSGetCurrentProcessIDKM(); -+ -+ psPerProc = PVRSRVPerProcessPrivateData(ui32PID); -+ if (!psPerProc) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: no per process data")); -+ -+ return -ENOMEM; -+ } -+ -+ if (!psPerProc->psProcDir) -+ { -+ IMG_CHAR dirname[16]; -+ IMG_INT ret; -+ -+ ret = snprintf(dirname, sizeof(dirname), "%u", ui32PID); -+ -+ if (ret <=0 || ret >= (IMG_INT)sizeof(dirname)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: couldn't generate per process proc directory name \"%u\"", ui32PID)); -+ -+ return -ENOMEM; -+ } -+ else -+ { -+ psPerProc->psProcDir = proc_mkdir(dirname, dir); -+ if (!psPerProc->psProcDir) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: couldn't create per process proc directory /proc/%s/%u", PVRProcDirRoot, ui32PID)); -+ -+ return -ENOMEM; -+ } -+ } -+ } -+ -+ return CreateProcEntryInDir(psPerProc->psProcDir, name, rhandler, whandler, data); -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function : CreateProcReadEntry -+ -+ @Description -+ -+ Create a file under /proc/pvr. These dynamic files can be used at runtime -+ to get information about the device. Creation WILL fail if proc support is -+ not compiled into the kernel. That said, the Linux kernel is not even happy -+ to build without /proc support these days. -+ -+ @Input name : the name of the file to create -+ -+ @Input handler : the function to call to provide the content -+ -+ @Return 0 for success, -errno for failure -+ -+*****************************************************************************/ -+IMG_INT CreateProcReadEntry(const IMG_CHAR * name, pvr_read_proc_t handler) -+{ -+ struct proc_dir_entry * file; -+ -+ if (!dir) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "CreateProcReadEntry: cannot make proc entry /proc/%s/%s: no parent", PVRProcDirRoot, name)); -+ -+ return -ENOMEM; -+ } -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)) -+ /* PRQA S 0307 1 */ /* ignore warning about casting to different pointer type */ -+ file = create_proc_read_entry (name, S_IFREG | S_IRUGO, dir, pvr_read_proc, (IMG_VOID *)handler); -+ -+ if (file) -+ { -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)) -+ file->owner = THIS_MODULE; -+#endif -+ return 0; -+ } -+#else -+// use file_ops pointing to pvr_read_proc -+ file = proc_create_data (name, S_IFREG | S_IRUGO, dir, &pvr_read_proc_operations, handler); -+ if(file) -+ return 0; -+#endif -+ PVR_DPF((PVR_DBG_ERROR, "CreateProcReadEntry: cannot make proc entry /proc/%s/%s: no memory", PVRProcDirRoot, name)); -+ -+ return -ENOMEM; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function : CreateProcEntries -+ -+ @Description -+ -+ Create a directory /proc/pvr and the necessary entries within it. These -+ dynamic files can be used at runtime to get information about the device. -+ Creation might fail if proc support is not compiled into the kernel or if -+ there is no memory -+ -+ @Input none -+ -+ @Return nothing -+ -+*****************************************************************************/ -+IMG_INT CreateProcEntries(IMG_VOID) -+{ -+ dir = proc_mkdir (PVRProcDirRoot, NULL); -+ -+ if (!dir) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "CreateProcEntries: cannot make /proc/%s directory", PVRProcDirRoot)); -+ -+ return -ENOMEM; -+ } -+ -+ g_pProcQueue = CreateProcReadEntrySeq("queue", NULL, NULL, ProcSeqShowQueue, ProcSeqOff2ElementQueue, NULL); -+ g_pProcVersion = CreateProcReadEntrySeq("version", NULL, NULL, ProcSeqShowVersion, ProcSeq1ElementHeaderOff2Element, NULL); -+ g_pProcSysNodes = CreateProcReadEntrySeq("nodes", NULL, NULL, ProcSeqShowSysNodes, ProcSeqOff2ElementSysNodes, NULL); -+ -+ if(!g_pProcQueue || !g_pProcVersion || !g_pProcSysNodes) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "CreateProcEntries: couldn't make /proc/%s files", PVRProcDirRoot)); -+ -+ return -ENOMEM; -+ } -+ -+ -+#ifdef DEBUG -+ -+ g_pProcDebugLevel = CreateProcEntrySeq("debug_level", NULL, NULL, -+ ProcSeqShowDebugLevel, -+ ProcSeq1ElementOff2Element, NULL, -+ (IMG_VOID*)PVRDebugProcSetLevel); -+ if(!g_pProcDebugLevel) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "CreateProcEntries: couldn't make /proc/%s/debug_level", PVRProcDirRoot)); -+ -+ return -ENOMEM; -+ } -+ -+#ifdef PVR_MANUAL_POWER_CONTROL -+ g_pProcPowerLevel = CreateProcEntrySeq("power_control", NULL, NULL, -+ ProcSeqShowPowerLevel, -+ ProcSeq1ElementOff2Element, NULL, -+ PVRProcSetPowerLevel); -+ if(!g_pProcPowerLevel) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "CreateProcEntries: couldn't make /proc/%s/power_control", PVRProcDirRoot)); -+ -+ return -ENOMEM; -+ } -+#endif -+#endif -+ -+ return 0; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function : RemoveProcEntry -+ -+ @Description -+ -+ Remove a single node under /proc/pvr. -+ -+ @Input name : the name of the node to remove -+ -+ @Return nothing -+ -+*****************************************************************************/ -+IMG_VOID RemoveProcEntry(const IMG_CHAR * name) -+{ -+ if (dir) -+ { -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)) -+ remove_proc_entry(name, dir); -+#endif -+ PVR_DPF((PVR_DBG_MESSAGE, "Removing /proc/%s/%s", PVRProcDirRoot, name)); -+ } -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function : RemovePerProcessProcEntry -+ -+ @Description -+ -+ Remove a single node under the per process proc directory. -+ -+ @Input name : the name of the node to remove -+ -+ @Return nothing -+ -+*****************************************************************************/ -+IMG_VOID RemovePerProcessProcEntry(const IMG_CHAR *name) -+{ -+ PVRSRV_ENV_PER_PROCESS_DATA *psPerProc; -+ -+ psPerProc = LinuxTerminatingProcessPrivateData(); -+ if (!psPerProc) -+ { -+ psPerProc = PVRSRVFindPerProcessPrivateData(); -+ if (!psPerProc) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: can't " -+ "remove %s, no per process data", name)); -+ return; -+ } -+ } -+ -+ if (psPerProc->psProcDir) -+ { -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)) -+ remove_proc_entry(name, psPerProc->psProcDir); -+ PVR_DPF((PVR_DBG_MESSAGE, "Removing proc entry %s from %s", name, psPerProc->psProcDir->name)); -+#endif -+ } -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function : RemovePerProcessProcDir -+ -+ @Description -+ -+ Remove the per process directorty under /proc/pvr. -+ -+ @Input psPerProc : environment specific per process data -+ -+ @Return nothing -+ -+*****************************************************************************/ -+IMG_VOID RemovePerProcessProcDir(PVRSRV_ENV_PER_PROCESS_DATA *psPerProc) -+{ -+ if (psPerProc->psProcDir) -+ { -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)) -+ while (psPerProc->psProcDir->subdir) -+ { -+ PVR_DPF((PVR_DBG_WARNING, "Belatedly removing /proc/%s/%s/%s", PVRProcDirRoot, psPerProc->psProcDir->name, psPerProc->psProcDir->subdir->name)); -+ -+ RemoveProcEntry(psPerProc->psProcDir->subdir->name); -+ } -+ RemoveProcEntry(psPerProc->psProcDir->name); -+#endif -+ } -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function : RemoveProcEntries -+ -+ Description -+ -+ Proc filesystem entry deletion - Remove all proc filesystem entries for -+ the driver. -+ -+ @Input none -+ -+ @Return nothing -+ -+*****************************************************************************/ -+IMG_VOID RemoveProcEntries(IMG_VOID) -+{ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)) -+#ifdef DEBUG -+ RemoveProcEntrySeq( g_pProcDebugLevel ); -+#ifdef PVR_MANUAL_POWER_CONTROL -+ RemoveProcEntrySeq( g_pProcPowerLevel ); -+#endif /* PVR_MANUAL_POWER_CONTROL */ -+#endif -+ -+ RemoveProcEntrySeq(g_pProcQueue); -+ RemoveProcEntrySeq(g_pProcVersion); -+ RemoveProcEntrySeq(g_pProcSysNodes); -+ while (dir->subdir) -+ { -+ PVR_DPF((PVR_DBG_WARNING, "Belatedly removing /proc/%s/%s", PVRProcDirRoot, dir->subdir->name)); -+ -+ RemoveProcEntry(dir->subdir->name); -+ } -+ -+ remove_proc_entry(PVRProcDirRoot, NULL); -+#else -+ proc_remove(dir); -+#endif -+} -+ -+/***************************************************************************** -+ FUNCTION : ProcSeqShowVersion -+ -+ PURPOSE : Print the content of version to /proc file -+ -+ PARAMETERS : sfile - /proc seq_file -+ el - Element to print -+*****************************************************************************/ -+static void ProcSeqShowVersion(struct seq_file *sfile,void* el) -+{ -+ SYS_DATA *psSysData; -+ IMG_CHAR *pszSystemVersionString = "None"; -+ -+ if(el == PVR_PROC_SEQ_START_TOKEN) -+ { -+ seq_printf(sfile, -+ "Version %s (%s) %s\n", -+ PVRVERSION_STRING, -+ PVR_BUILD_TYPE, PVR_BUILD_DIR); -+ return; -+ } -+ -+ psSysData = SysAcquireDataNoCheck(); -+ if(psSysData != IMG_NULL && psSysData->pszVersionString != IMG_NULL) -+ { -+ pszSystemVersionString = psSysData->pszVersionString; -+ } -+ -+ seq_printf( sfile, "System Version String: %s\n", pszSystemVersionString); -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function procDumpSysNodes (plus deviceTypeToString and deviceClassToString) -+ -+ @Description -+ -+ Format the contents of /proc/pvr/nodes -+ -+ @Input buf : where to place format contents data. -+ -+ @Input size : the size of the buffer into which to place data -+ -+ @Input off : how far into the file we are. -+ -+ @Return amount of data placed in buffer, 0, or END_OF_FILE : -+ -+******************************************************************************/ -+static const IMG_CHAR *deviceTypeToString(PVRSRV_DEVICE_TYPE deviceType) -+{ -+ switch (deviceType) -+ { -+ default: -+ { -+ static IMG_CHAR text[10]; -+ -+ sprintf(text, "?%x", (IMG_UINT)deviceType); -+ -+ return text; -+ } -+ } -+} -+ -+ -+static const IMG_CHAR *deviceClassToString(PVRSRV_DEVICE_CLASS deviceClass) -+{ -+ switch (deviceClass) -+ { -+ case PVRSRV_DEVICE_CLASS_3D: -+ { -+ return "3D"; -+ } -+ case PVRSRV_DEVICE_CLASS_DISPLAY: -+ { -+ return "display"; -+ } -+ case PVRSRV_DEVICE_CLASS_BUFFER: -+ { -+ return "buffer"; -+ } -+ default: -+ { -+ static IMG_CHAR text[10]; -+ -+ sprintf(text, "?%x", (IMG_UINT)deviceClass); -+ return text; -+ } -+ } -+} -+ -+static IMG_VOID* DecOffPsDev_AnyVaCb(PVRSRV_DEVICE_NODE *psNode, va_list va) -+{ -+ off_t *pOff = va_arg(va, off_t*); -+ if (--(*pOff)) -+ { -+ return IMG_NULL; -+ } -+ else -+ { -+ return psNode; -+ } -+} -+ -+/***************************************************************************** -+ FUNCTION : ProcSeqShowSysNodes -+ -+ PURPOSE : Print the content of version to /proc file -+ -+ PARAMETERS : sfile - /proc seq_file -+ el - Element to print -+*****************************************************************************/ -+static void ProcSeqShowSysNodes(struct seq_file *sfile,void* el) -+{ -+ PVRSRV_DEVICE_NODE *psDevNode; -+ -+ if(el == PVR_PROC_SEQ_START_TOKEN) -+ { -+ seq_printf( sfile, -+ "Registered nodes\n" -+ "Addr Type Class Index Ref pvDev Size Res\n"); -+ return; -+ } -+ -+ psDevNode = (PVRSRV_DEVICE_NODE*)el; -+ -+ seq_printf( sfile, -+ "%p %-8s %-8s %4d %2u %p %3u %p\n", -+ psDevNode, -+ deviceTypeToString(psDevNode->sDevId.eDeviceType), -+ deviceClassToString(psDevNode->sDevId.eDeviceClass), -+ psDevNode->sDevId.eDeviceClass, -+ psDevNode->ui32RefCount, -+ psDevNode->pvDevice, -+ psDevNode->ui32pvDeviceSize, -+ psDevNode->hResManContext); -+} -+ -+/***************************************************************************** -+ FUNCTION : ProcSeqOff2ElementSysNodes -+ -+ PURPOSE : Transale offset to element (/proc stuff) -+ -+ PARAMETERS : sfile - /proc seq_file -+ off - the offset into the buffer -+ -+ RETURNS : element to print -+*****************************************************************************/ -+static void* ProcSeqOff2ElementSysNodes(struct seq_file * sfile, loff_t off) -+{ -+ SYS_DATA *psSysData; -+ PVRSRV_DEVICE_NODE*psDevNode = IMG_NULL; -+ -+ PVR_UNREFERENCED_PARAMETER(sfile); -+ -+ if(!off) -+ { -+ return PVR_PROC_SEQ_START_TOKEN; -+ } -+ -+ psSysData = SysAcquireDataNoCheck(); -+ if (psSysData != IMG_NULL) -+ { -+ /* Find Dev Node */ -+ psDevNode = (PVRSRV_DEVICE_NODE*) -+ List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList, -+ DecOffPsDev_AnyVaCb, -+ &off); -+ } -+ -+ /* Return anything that is not PVR_RPOC_SEQ_START_TOKEN and NULL */ -+ return (void*)psDevNode; -+} -+ -+/***************************************************************************** -+ End of file (proc.c) -+*****************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/proc.h b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/proc.h -new file mode 100644 -index 0000000..c098c73 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/proc.h -@@ -0,0 +1,139 @@ -+/*************************************************************************/ /*! -+@Title Proc interface definition. -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Functions for creating and reading proc filesystem entries. -+ Refer to proc.c -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#ifndef __SERVICES_PROC_H__ -+#define __SERVICES_PROC_H__ -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0)) -+#include <asm/system.h> // va_list etc -+#endif -+#include <linux/proc_fs.h> // read_proc_t etc -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)) -+typedef int (read_proc_t)(char *page, char **start, off_t off,int count, int *eof, void *data); -+typedef int (write_proc_t)(struct file *file, const char __user *buffer,unsigned long count, void *data); -+#endif -+ -+#include <linux/seq_file.h> // seq_file -+ -+#define END_OF_FILE (off_t) -1 -+ -+typedef off_t (pvr_read_proc_t)(IMG_CHAR *, size_t, off_t); -+ -+ -+#define PVR_PROC_SEQ_START_TOKEN (void*)1 -+typedef void* (pvr_next_proc_seq_t)(struct seq_file *,void*,loff_t); -+typedef void* (pvr_off2element_proc_seq_t)(struct seq_file *, loff_t); -+typedef void (pvr_show_proc_seq_t)(struct seq_file *,void*); -+typedef void (pvr_startstop_proc_seq_t)(struct seq_file *, IMG_BOOL start); -+ -+typedef struct _PVR_PROC_SEQ_HANDLERS_ { -+ pvr_next_proc_seq_t *next; -+ pvr_show_proc_seq_t *show; -+ pvr_off2element_proc_seq_t *off2element; -+ pvr_startstop_proc_seq_t *startstop; -+ IMG_VOID *data; -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)) -+read_proc_t *read_proc; -+write_proc_t *write_proc; -+#endif -+} PVR_PROC_SEQ_HANDLERS; -+ -+ -+/** off2element function for elements with only ONE element (no header) */ -+void* ProcSeq1ElementOff2Element(struct seq_file *sfile, loff_t off); -+ -+/** off2element function for elements with only ONE element (+ header) */ -+void* ProcSeq1ElementHeaderOff2Element(struct seq_file *sfile, loff_t off); -+ -+off_t printAppend(IMG_CHAR * buffer, size_t size, off_t off, const IMG_CHAR * format, ...) -+ __attribute__((format(printf, 4, 5))); -+ -+IMG_INT CreateProcEntries(IMG_VOID); -+ -+IMG_INT CreateProcReadEntry (const IMG_CHAR * name, pvr_read_proc_t handler); -+ -+IMG_INT CreateProcEntry(const IMG_CHAR * name, read_proc_t rhandler, write_proc_t whandler, IMG_VOID *data); -+ -+IMG_INT CreatePerProcessProcEntry(const IMG_CHAR * name, read_proc_t rhandler, write_proc_t whandler, IMG_VOID *data); -+ -+IMG_VOID RemoveProcEntry(const IMG_CHAR * name); -+ -+IMG_VOID RemovePerProcessProcEntry(const IMG_CHAR * name); -+ -+IMG_VOID RemoveProcEntries(IMG_VOID); -+ -+struct proc_dir_entry* CreateProcReadEntrySeq ( -+ const IMG_CHAR* name, -+ IMG_VOID* data, -+ pvr_next_proc_seq_t next_handler, -+ pvr_show_proc_seq_t show_handler, -+ pvr_off2element_proc_seq_t off2element_handler, -+ pvr_startstop_proc_seq_t startstop_handler -+ ); -+ -+struct proc_dir_entry* CreateProcEntrySeq ( -+ const IMG_CHAR* name, -+ IMG_VOID* data, -+ pvr_next_proc_seq_t next_handler, -+ pvr_show_proc_seq_t show_handler, -+ pvr_off2element_proc_seq_t off2element_handler, -+ pvr_startstop_proc_seq_t startstop_handler, -+ write_proc_t whandler -+ ); -+ -+struct proc_dir_entry* CreatePerProcessProcEntrySeq ( -+ const IMG_CHAR* name, -+ IMG_VOID* data, -+ pvr_next_proc_seq_t next_handler, -+ pvr_show_proc_seq_t show_handler, -+ pvr_off2element_proc_seq_t off2element_handler, -+ pvr_startstop_proc_seq_t startstop_handler, -+ write_proc_t whandler -+ ); -+ -+ -+IMG_VOID RemoveProcEntrySeq(struct proc_dir_entry* proc_entry); -+IMG_VOID RemovePerProcessProcEntrySeq(struct proc_dir_entry* proc_entry); -+ -+#endif -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/pvr_bridge_k.c b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/pvr_bridge_k.c -new file mode 100644 -index 0000000..143400c ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/pvr_bridge_k.c -@@ -0,0 +1,524 @@ -+/*************************************************************************/ /*! -+@Title PVR Bridge Module (kernel side) -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Receives calls from the user portion of services and -+ despatches them to functions in the kernel portion. -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#include "img_defs.h" -+#include "services.h" -+#include "pvr_bridge.h" -+#include "perproc.h" -+#include "mutex.h" -+#include "syscommon.h" -+#include "pvr_debug.h" -+#include "proc.h" -+#include "private_data.h" -+#include "linkage.h" -+#include "pvr_bridge_km.h" -+#include "pvr_uaccess.h" -+#include "refcount.h" -+#include "buffer_manager.h" -+ -+#if defined(SUPPORT_DRI_DRM) -+#include <drm/drmP.h> -+#include "pvr_drm.h" -+#if defined(PVR_SECURE_DRM_AUTH_EXPORT) -+#include "env_perproc.h" -+#endif -+#endif -+ -+/* VGX: */ -+#if defined(SUPPORT_VGX) -+#include "vgx_bridge.h" -+#endif -+ -+/* SGX: */ -+#if defined(SUPPORT_SGX) -+#include "sgx_bridge.h" -+#endif -+ -+#include "bridged_pvr_bridge.h" -+ -+#if defined(SUPPORT_DRI_DRM) -+#define PRIVATE_DATA(pFile) ((pFile)->driver_priv) -+#else -+#define PRIVATE_DATA(pFile) ((pFile)->private_data) -+#endif -+ -+#if defined(DEBUG_BRIDGE_KM) -+ -+static struct proc_dir_entry *g_ProcBridgeStats =0; -+static void* ProcSeqNextBridgeStats(struct seq_file *sfile,void* el,loff_t off); -+static void ProcSeqShowBridgeStats(struct seq_file *sfile,void* el); -+static void* ProcSeqOff2ElementBridgeStats(struct seq_file * sfile, loff_t off); -+static void ProcSeqStartstopBridgeStats(struct seq_file *sfile,IMG_BOOL start); -+ -+#endif -+ -+extern PVRSRV_LINUX_MUTEX gPVRSRVLock; -+ -+#if defined(SUPPORT_MEMINFO_IDS) -+IMG_UINT64 g_ui64MemInfoID; -+#endif /* defined(SUPPORT_MEMINFO_IDS) */ -+ -+PVRSRV_ERROR -+LinuxBridgeInit(IMG_VOID) -+{ -+#if defined(DEBUG_BRIDGE_KM) -+ { -+ g_ProcBridgeStats = CreateProcReadEntrySeq( -+ "bridge_stats", -+ NULL, -+ ProcSeqNextBridgeStats, -+ ProcSeqShowBridgeStats, -+ ProcSeqOff2ElementBridgeStats, -+ ProcSeqStartstopBridgeStats -+ ); -+ if(!g_ProcBridgeStats) -+ { -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ } -+#endif -+ return CommonBridgeInit(); -+} -+ -+IMG_VOID -+LinuxBridgeDeInit(IMG_VOID) -+{ -+#if defined(DEBUG_BRIDGE_KM) -+ RemoveProcEntrySeq(g_ProcBridgeStats); -+#endif -+} -+ -+#if defined(DEBUG_BRIDGE_KM) -+ -+/* -+ * Lock MMap regions list (called on page start/stop while reading /proc/mmap) -+ * -+ * sfile : seq_file that handles /proc file -+ * start : TRUE if it's start, FALSE if it's stop -+ * -+ */ -+static void ProcSeqStartstopBridgeStats(struct seq_file *sfile,IMG_BOOL start) -+{ -+ if(start) -+ { -+ LinuxLockMutexNested(&gPVRSRVLock, PVRSRV_LOCK_CLASS_BRIDGE); -+ } -+ else -+ { -+ LinuxUnLockMutex(&gPVRSRVLock); -+ } -+} -+ -+ -+/* -+ * Convert offset (index from KVOffsetTable) to element -+ * (called when reading /proc/mmap file) -+ -+ * sfile : seq_file that handles /proc file -+ * off : index into the KVOffsetTable from which to print -+ * -+ * returns void* : Pointer to element that will be dumped -+ * -+*/ -+static void* ProcSeqOff2ElementBridgeStats(struct seq_file *sfile, loff_t off) -+{ -+ if(!off) -+ { -+ return PVR_PROC_SEQ_START_TOKEN; -+ } -+ -+ if(off > BRIDGE_DISPATCH_TABLE_ENTRY_COUNT) -+ { -+ return (void*)0; -+ } -+ -+ -+ return (void*)&g_BridgeDispatchTable[off-1]; -+} -+ -+/* -+ * Gets next MMap element to show. (called when reading /proc/mmap file) -+ -+ * sfile : seq_file that handles /proc file -+ * el : actual element -+ * off : index into the KVOffsetTable from which to print -+ * -+ * returns void* : Pointer to element to show (0 ends iteration) -+*/ -+static void* ProcSeqNextBridgeStats(struct seq_file *sfile,void* el,loff_t off) -+{ -+ return ProcSeqOff2ElementBridgeStats(sfile,off); -+} -+ -+ -+/* -+ * Show MMap element (called when reading /proc/mmap file) -+ -+ * sfile : seq_file that handles /proc file -+ * el : actual element -+ * -+*/ -+static void ProcSeqShowBridgeStats(struct seq_file *sfile,void* el) -+{ -+ PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY *psEntry = ( PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY*)el; -+ -+ if(el == PVR_PROC_SEQ_START_TOKEN) -+ { -+ seq_printf(sfile, -+ "Total ioctl call count = %u\n" -+ "Total number of bytes copied via copy_from_user = %u\n" -+ "Total number of bytes copied via copy_to_user = %u\n" -+ "Total number of bytes copied via copy_*_user = %u\n\n" -+ "%-45s | %-40s | %10s | %20s | %10s\n", -+ g_BridgeGlobalStats.ui32IOCTLCount, -+ g_BridgeGlobalStats.ui32TotalCopyFromUserBytes, -+ g_BridgeGlobalStats.ui32TotalCopyToUserBytes, -+ g_BridgeGlobalStats.ui32TotalCopyFromUserBytes+g_BridgeGlobalStats.ui32TotalCopyToUserBytes, -+ "Bridge Name", -+ "Wrapper Function", -+ "Call Count", -+ "copy_from_user Bytes", -+ "copy_to_user Bytes" -+ ); -+ return; -+ } -+ -+ seq_printf(sfile, -+ "%-45s %-40s %-10u %-20u %-10u\n", -+ psEntry->pszIOCName, -+ psEntry->pszFunctionName, -+ psEntry->ui32CallCount, -+ psEntry->ui32CopyFromUserTotalBytes, -+ psEntry->ui32CopyToUserTotalBytes); -+} -+ -+#endif /* DEBUG_BRIDGE_KM */ -+ -+ -+#if defined(SUPPORT_DRI_DRM) -+int -+PVRSRV_BridgeDispatchKM(struct drm_device unref__ *dev, void *arg, struct drm_file *pFile) -+#else -+long -+PVRSRV_BridgeDispatchKM(struct file *pFile, unsigned int unref__ ioctlCmd, unsigned long arg) -+#endif -+{ -+ IMG_UINT32 cmd; -+#if !defined(SUPPORT_DRI_DRM) -+ PVRSRV_BRIDGE_PACKAGE *psBridgePackageUM = (PVRSRV_BRIDGE_PACKAGE *)arg; -+ PVRSRV_BRIDGE_PACKAGE sBridgePackageKM; -+#endif -+ PVRSRV_BRIDGE_PACKAGE *psBridgePackageKM; -+ IMG_UINT32 ui32PID = OSGetCurrentProcessIDKM(); -+ PVRSRV_PER_PROCESS_DATA *psPerProc; -+ IMG_INT err = -EFAULT; -+ -+ LinuxLockMutexNested(&gPVRSRVLock, PVRSRV_LOCK_CLASS_BRIDGE); -+ -+#if defined(SUPPORT_DRI_DRM) -+ psBridgePackageKM = (PVRSRV_BRIDGE_PACKAGE *)arg; -+ PVR_ASSERT(psBridgePackageKM != IMG_NULL); -+#else -+ psBridgePackageKM = &sBridgePackageKM; -+ -+ if(!OSAccessOK(PVR_VERIFY_WRITE, -+ psBridgePackageUM, -+ sizeof(PVRSRV_BRIDGE_PACKAGE))) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: Received invalid pointer to function arguments", -+ __FUNCTION__)); -+ -+ goto unlock_and_return; -+ } -+ -+ /* FIXME - Currently the CopyFromUserWrapper which collects stats about -+ * how much data is shifted to/from userspace isn't available to us -+ * here. */ -+ if(OSCopyFromUser(IMG_NULL, -+ psBridgePackageKM, -+ psBridgePackageUM, -+ sizeof(PVRSRV_BRIDGE_PACKAGE)) -+ != PVRSRV_OK) -+ { -+ goto unlock_and_return; -+ } -+#endif -+ -+ cmd = psBridgePackageKM->ui32BridgeID; -+ -+ if(cmd != PVRSRV_BRIDGE_CONNECT_SERVICES) -+ { -+ PVRSRV_ERROR eError; -+ -+ eError = PVRSRVLookupHandle(KERNEL_HANDLE_BASE, -+ (IMG_PVOID *)&psPerProc, -+ psBridgePackageKM->hKernelServices, -+ PVRSRV_HANDLE_TYPE_PERPROC_DATA); -+ if(eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: Invalid kernel services handle (%d)", -+ __FUNCTION__, eError)); -+ goto unlock_and_return; -+ } -+ -+ if(psPerProc->ui32PID != ui32PID) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: Process %d tried to access data " -+ "belonging to process %d", __FUNCTION__, ui32PID, -+ psPerProc->ui32PID)); -+ goto unlock_and_return; -+ } -+ } -+ else -+ { -+ /* lookup per-process data for this process */ -+ psPerProc = PVRSRVPerProcessData(ui32PID); -+ if(psPerProc == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "PVRSRV_BridgeDispatchKM: " -+ "Couldn't create per-process data area")); -+ goto unlock_and_return; -+ } -+ } -+ -+ psBridgePackageKM->ui32BridgeID = PVRSRV_GET_BRIDGE_ID(psBridgePackageKM->ui32BridgeID); -+ -+ switch(cmd) -+ { -+ case PVRSRV_BRIDGE_EXPORT_DEVICEMEM_2: -+ { -+ PVRSRV_FILE_PRIVATE_DATA *psPrivateData = PRIVATE_DATA(pFile); -+ -+ if(psPrivateData->hKernelMemInfo) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: Can only export one MemInfo " -+ "per file descriptor", __FUNCTION__)); -+ err = -EINVAL; -+ goto unlock_and_return; -+ } -+ break; -+ } -+ -+ case PVRSRV_BRIDGE_MAP_DEV_MEMORY_2: -+ { -+ PVRSRV_BRIDGE_IN_MAP_DEV_MEMORY *psMapDevMemIN = -+ (PVRSRV_BRIDGE_IN_MAP_DEV_MEMORY *)psBridgePackageKM->pvParamIn; -+ PVRSRV_FILE_PRIVATE_DATA *psPrivateData = PRIVATE_DATA(pFile); -+ -+ if(!psPrivateData->hKernelMemInfo) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: File descriptor has no " -+ "associated MemInfo handle", __FUNCTION__)); -+ err = -EINVAL; -+ goto unlock_and_return; -+ } -+ -+ if (pvr_put_user(psPrivateData->hKernelMemInfo, &psMapDevMemIN->hKernelMemInfo) != 0) -+ { -+ err = -EFAULT; -+ goto unlock_and_return; -+ } -+ break; -+ } -+ -+ default: -+ { -+ PVRSRV_FILE_PRIVATE_DATA *psPrivateData = PRIVATE_DATA(pFile); -+ -+ if(psPrivateData->hKernelMemInfo) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: Import/Export handle tried " -+ "to use privileged service", __FUNCTION__)); -+ goto unlock_and_return; -+ } -+ break; -+ } -+ } -+ -+#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT) -+ switch(cmd) -+ { -+ case PVRSRV_BRIDGE_MAP_DEV_MEMORY: -+ case PVRSRV_BRIDGE_MAP_DEVICECLASS_MEMORY: -+ { -+ PVRSRV_FILE_PRIVATE_DATA *psPrivateData; -+ int authenticated = pFile->authenticated; -+ PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc; -+ -+ if (authenticated) -+ { -+ break; -+ } -+ -+ /* -+ * The DRM file structure we are using for Services -+ * is not one that DRI authentication was done on. -+ * Look for an authenticated file structure for -+ * this process, making sure the DRM master is the -+ * same as ours. -+ */ -+ psEnvPerProc = (PVRSRV_ENV_PER_PROCESS_DATA *)PVRSRVProcessPrivateData(psPerProc); -+ if (psEnvPerProc == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: Process private data not allocated", __FUNCTION__)); -+ err = -EFAULT; -+ goto unlock_and_return; -+ } -+ -+ list_for_each_entry(psPrivateData, &psEnvPerProc->sDRMAuthListHead, sDRMAuthListItem) -+ { -+ struct drm_file *psDRMFile = psPrivateData->psDRMFile; -+ -+ if (pFile->master == psDRMFile->master) -+ { -+ authenticated |= psDRMFile->authenticated; -+ if (authenticated) -+ { -+ break; -+ } -+ } -+ } -+ -+ if (!authenticated) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: Not authenticated for mapping device or device class memory", __FUNCTION__)); -+ err = -EPERM; -+ goto unlock_and_return; -+ } -+ break; -+ } -+ default: -+ break; -+ } -+#endif /* defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT) */ -+ -+ err = BridgedDispatchKM(psPerProc, psBridgePackageKM); -+ if(err != PVRSRV_OK) -+ goto unlock_and_return; -+ -+ switch(cmd) -+ { -+ case PVRSRV_BRIDGE_EXPORT_DEVICEMEM_2: -+ { -+ PVRSRV_BRIDGE_OUT_EXPORTDEVICEMEM *psExportDeviceMemOUT = -+ (PVRSRV_BRIDGE_OUT_EXPORTDEVICEMEM *)psBridgePackageKM->pvParamOut; -+ PVRSRV_FILE_PRIVATE_DATA *psPrivateData = PRIVATE_DATA(pFile); -+ IMG_HANDLE hMemInfo; -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; -+ -+ if (pvr_get_user(hMemInfo, &psExportDeviceMemOUT->hMemInfo) != 0) -+ { -+ err = -EFAULT; -+ goto unlock_and_return; -+ } -+ -+ /* Look up the meminfo we just exported */ -+ if(PVRSRVLookupHandle(KERNEL_HANDLE_BASE, -+ (IMG_PVOID *)&psKernelMemInfo, -+ hMemInfo, -+ PVRSRV_HANDLE_TYPE_MEM_INFO) != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: Failed to look up export handle", __FUNCTION__)); -+ err = -EFAULT; -+ goto unlock_and_return; -+ } -+ -+ /* Bump the refcount; decremented on release of the fd */ -+ PVRSRVKernelMemInfoIncRef(psKernelMemInfo); -+ -+ /* Tell the XProc about the export if required */ -+ if (psKernelMemInfo->sShareMemWorkaround.bInUse) -+ { -+ BM_XProcIndexAcquire(psKernelMemInfo->sShareMemWorkaround.ui32ShareIndex); -+ } -+ -+ psPrivateData->hKernelMemInfo = hMemInfo; -+#if defined(SUPPORT_MEMINFO_IDS) -+ psPrivateData->ui64Stamp = ++g_ui64MemInfoID; -+ -+ psKernelMemInfo->ui64Stamp = psPrivateData->ui64Stamp; -+ if (pvr_put_user(psPrivateData->ui64Stamp, &psExportDeviceMemOUT->ui64Stamp) != 0) -+ { -+ err = -EFAULT; -+ goto unlock_and_return; -+ } -+#endif -+ break; -+ } -+ -+#if defined(SUPPORT_MEMINFO_IDS) -+ case PVRSRV_BRIDGE_MAP_DEV_MEMORY: -+ case PVRSRV_BRIDGE_MAP_DEV_MEMORY_2: -+ { -+ PVRSRV_BRIDGE_OUT_MAP_DEV_MEMORY *psMapDeviceMemoryOUT = -+ (PVRSRV_BRIDGE_OUT_MAP_DEV_MEMORY *)psBridgePackageKM->pvParamOut; -+ PVRSRV_FILE_PRIVATE_DATA *psPrivateData = PRIVATE_DATA(pFile); -+ if (pvr_put_user(psPrivateData->ui64Stamp, &psMapDeviceMemoryOUT->sDstClientMemInfo.ui64Stamp) != 0) -+ { -+ err = -EFAULT; -+ goto unlock_and_return; -+ } -+ break; -+ } -+ -+ case PVRSRV_BRIDGE_MAP_DEVICECLASS_MEMORY: -+ { -+ PVRSRV_BRIDGE_OUT_MAP_DEVICECLASS_MEMORY *psDeviceClassMemoryOUT = -+ (PVRSRV_BRIDGE_OUT_MAP_DEVICECLASS_MEMORY *)psBridgePackageKM->pvParamOut; -+ if (pvr_put_user(++g_ui64MemInfoID, &psDeviceClassMemoryOUT->sClientMemInfo.ui64Stamp) != 0) -+ { -+ err = -EFAULT; -+ goto unlock_and_return; -+ } -+ break; -+ } -+#endif /* defined(SUPPORT_MEMINFO_IDS) */ -+ -+ default: -+ break; -+ } -+ -+unlock_and_return: -+ LinuxUnLockMutex(&gPVRSRVLock); -+ return err; -+} -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/pvr_debug.c b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/pvr_debug.c -new file mode 100644 -index 0000000..33b05dd ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/pvr_debug.c -@@ -0,0 +1,506 @@ -+/*************************************************************************/ /*! -+@Title Debug Functionality -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Provides kernel side Debug Functionality -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#include <linux/version.h> -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)) -+#ifndef AUTOCONF_INCLUDED -+#include <linux/config.h> -+#endif -+#endif -+ -+#include <asm/io.h> -+#include <asm/uaccess.h> -+#include <linux/kernel.h> -+#include <linux/hardirq.h> -+#include <linux/module.h> -+#include <linux/spinlock.h> -+#include <linux/string.h> // strncpy, strlen -+#include <stdarg.h> -+#include "img_types.h" -+#include "servicesext.h" -+#include "pvr_debug.h" -+#include "srvkm.h" -+#include "proc.h" -+#include "mutex.h" -+#include "linkage.h" -+#include "pvr_uaccess.h" -+ -+#if !defined(CONFIG_PREEMPT) -+#define PVR_DEBUG_ALWAYS_USE_SPINLOCK -+#endif -+ -+static IMG_BOOL VBAppend(IMG_CHAR *pszBuf, IMG_UINT32 ui32BufSiz, -+ const IMG_CHAR* pszFormat, va_list VArgs) -+ IMG_FORMAT_PRINTF(3, 0); -+ -+ -+#if defined(PVRSRV_NEED_PVR_DPF) -+ -+#define PVR_MAX_FILEPATH_LEN 256 -+ -+static IMG_BOOL BAppend(IMG_CHAR *pszBuf, IMG_UINT32 ui32BufSiz, -+ const IMG_CHAR *pszFormat, ...) -+ IMG_FORMAT_PRINTF(3, 4); -+ -+/* NOTE: Must NOT be static! Used in module.c.. */ -+IMG_UINT32 gPVRDebugLevel = -+ (DBGPRIV_FATAL | DBGPRIV_ERROR | DBGPRIV_WARNING); -+ -+#endif /* defined(PVRSRV_NEED_PVR_DPF) || defined(PVRSRV_NEED_PVR_TRACE) */ -+ -+#define PVR_MAX_MSG_LEN PVR_MAX_DEBUG_MESSAGE_LEN -+ -+#if !defined(PVR_DEBUG_ALWAYS_USE_SPINLOCK) -+/* Message buffer for non-IRQ messages */ -+static IMG_CHAR gszBufferNonIRQ[PVR_MAX_MSG_LEN + 1]; -+#endif -+ -+/* Message buffer for IRQ messages */ -+static IMG_CHAR gszBufferIRQ[PVR_MAX_MSG_LEN + 1]; -+ -+#if !defined(PVR_DEBUG_ALWAYS_USE_SPINLOCK) -+/* The lock is used to control access to gszBufferNonIRQ */ -+static PVRSRV_LINUX_MUTEX gsDebugMutexNonIRQ; -+#endif -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39)) -+/* The lock is used to control access to gszBufferIRQ */ -+/* PRQA S 0671,0685 1 */ /* ignore warnings about C99 style initialisation */ -+static spinlock_t gsDebugLockIRQ = SPIN_LOCK_UNLOCKED; -+#else -+static DEFINE_SPINLOCK(gsDebugLockIRQ); -+#endif -+ -+#if !defined(PVR_DEBUG_ALWAYS_USE_SPINLOCK) -+#if !defined (USE_SPIN_LOCK) /* to keep QAC happy */ -+#define USE_SPIN_LOCK (in_interrupt() || !preemptible()) -+#endif -+#endif -+ -+static inline void GetBufferLock(unsigned long *pulLockFlags) -+{ -+#if !defined(PVR_DEBUG_ALWAYS_USE_SPINLOCK) -+ if (USE_SPIN_LOCK) -+#endif -+ { -+ spin_lock_irqsave(&gsDebugLockIRQ, *pulLockFlags); -+ } -+#if !defined(PVR_DEBUG_ALWAYS_USE_SPINLOCK) -+ else -+ { -+ LinuxLockMutexNested(&gsDebugMutexNonIRQ, PVRSRV_LOCK_CLASS_PVR_DEBUG); -+ } -+#endif -+} -+ -+static inline void ReleaseBufferLock(unsigned long ulLockFlags) -+{ -+#if !defined(PVR_DEBUG_ALWAYS_USE_SPINLOCK) -+ if (USE_SPIN_LOCK) -+#endif -+ { -+ spin_unlock_irqrestore(&gsDebugLockIRQ, ulLockFlags); -+ } -+#if !defined(PVR_DEBUG_ALWAYS_USE_SPINLOCK) -+ else -+ { -+ LinuxUnLockMutex(&gsDebugMutexNonIRQ); -+ } -+#endif -+} -+ -+static inline void SelectBuffer(IMG_CHAR **ppszBuf, IMG_UINT32 *pui32BufSiz) -+{ -+#if !defined(PVR_DEBUG_ALWAYS_USE_SPINLOCK) -+ if (USE_SPIN_LOCK) -+#endif -+ { -+ *ppszBuf = gszBufferIRQ; -+ *pui32BufSiz = sizeof(gszBufferIRQ); -+ } -+#if !defined(PVR_DEBUG_ALWAYS_USE_SPINLOCK) -+ else -+ { -+ *ppszBuf = gszBufferNonIRQ; -+ *pui32BufSiz = sizeof(gszBufferNonIRQ); -+ } -+#endif -+} -+ -+/* -+ * Append a string to a buffer using formatted conversion. -+ * The function takes a variable number of arguments, pointed -+ * to by the var args list. -+ */ -+static IMG_BOOL VBAppend(IMG_CHAR *pszBuf, IMG_UINT32 ui32BufSiz, const IMG_CHAR* pszFormat, va_list VArgs) -+{ -+ IMG_UINT32 ui32Used; -+ IMG_UINT32 ui32Space; -+ IMG_INT32 i32Len; -+ -+ ui32Used = strlen(pszBuf); -+ BUG_ON(ui32Used >= ui32BufSiz); -+ ui32Space = ui32BufSiz - ui32Used; -+ -+ i32Len = vsnprintf(&pszBuf[ui32Used], ui32Space, pszFormat, VArgs); -+ pszBuf[ui32BufSiz - 1] = 0; -+ -+ /* Return true if string was truncated */ -+ return (i32Len < 0 || i32Len >= (IMG_INT32)ui32Space) ? IMG_TRUE : IMG_FALSE; -+} -+ -+/* Actually required for ReleasePrintf too */ -+ -+IMG_VOID PVRDPFInit(IMG_VOID) -+{ -+#if !defined(PVR_DEBUG_ALWAYS_USE_SPINLOCK) -+ LinuxInitMutex(&gsDebugMutexNonIRQ); -+#endif -+} -+ -+/*! -+****************************************************************************** -+ @Function PVRSRVReleasePrintf -+ @Description To output an important message to the user in release builds -+ @Input pszFormat - The message format string -+ @Input ... - Zero or more arguments for use by the format string -+ @Return None -+ ******************************************************************************/ -+IMG_VOID PVRSRVReleasePrintf(const IMG_CHAR *pszFormat, ...) -+{ -+ va_list vaArgs; -+ unsigned long ulLockFlags = 0; -+ IMG_CHAR *pszBuf; -+ IMG_UINT32 ui32BufSiz; -+ -+ SelectBuffer(&pszBuf, &ui32BufSiz); -+ -+ va_start(vaArgs, pszFormat); -+ -+ GetBufferLock(&ulLockFlags); -+ strncpy (pszBuf, "PVR_K: ", (ui32BufSiz -1)); -+ -+ if (VBAppend(pszBuf, ui32BufSiz, pszFormat, vaArgs)) -+ { -+ printk(KERN_INFO "PVR_K:(Message Truncated): %s\n", pszBuf); -+ } -+ else -+ { -+ printk(KERN_INFO "%s\n", pszBuf); -+ } -+ -+ ReleaseBufferLock(ulLockFlags); -+ va_end(vaArgs); -+ -+} -+ -+#if defined(PVRSRV_NEED_PVR_TRACE) -+ -+/*! -+****************************************************************************** -+ @Function PVRTrace -+ @Description To output a debug message to the user -+ @Input pszFormat - The message format string -+ @Input ... - Zero or more arguments for use by the format string -+ @Return None -+ ******************************************************************************/ -+IMG_VOID PVRSRVTrace(const IMG_CHAR* pszFormat, ...) -+{ -+ va_list VArgs; -+ unsigned long ulLockFlags = 0; -+ IMG_CHAR *pszBuf; -+ IMG_UINT32 ui32BufSiz; -+ -+ SelectBuffer(&pszBuf, &ui32BufSiz); -+ -+ va_start(VArgs, pszFormat); -+ -+ GetBufferLock(&ulLockFlags); -+ -+ strncpy(pszBuf, "PVR: ", (ui32BufSiz -1)); -+ -+ if (VBAppend(pszBuf, ui32BufSiz, pszFormat, VArgs)) -+ { -+ printk(KERN_INFO "PVR_K:(Message Truncated): %s\n", pszBuf); -+ } -+ else -+ { -+ printk(KERN_INFO "%s\n", pszBuf); -+ } -+ -+ ReleaseBufferLock(ulLockFlags); -+ -+ va_end(VArgs); -+} -+ -+#endif /* defined(PVRSRV_NEED_PVR_TRACE) */ -+ -+#if defined(PVRSRV_NEED_PVR_DPF) -+ -+/* -+ * Append a string to a buffer using formatted conversion. -+ * The function takes a variable number of arguments, calling -+ * VBAppend to do the actual work. -+ */ -+static IMG_BOOL BAppend(IMG_CHAR *pszBuf, IMG_UINT32 ui32BufSiz, const IMG_CHAR *pszFormat, ...) -+{ -+ va_list VArgs; -+ IMG_BOOL bTrunc; -+ -+ va_start (VArgs, pszFormat); -+ -+ bTrunc = VBAppend(pszBuf, ui32BufSiz, pszFormat, VArgs); -+ -+ va_end (VArgs); -+ -+ return bTrunc; -+} -+ -+/*! -+****************************************************************************** -+ @Function PVRSRVDebugPrintf -+ @Description To output a debug message to the user -+ @Input uDebugLevel - The current debug level -+ @Input pszFile - The source file generating the message -+ @Input uLine - The line of the source file -+ @Input pszFormat - The message format string -+ @Input ... - Zero or more arguments for use by the format string -+ @Return None -+ ******************************************************************************/ -+IMG_VOID PVRSRVDebugPrintf ( -+ IMG_UINT32 ui32DebugLevel, -+ const IMG_CHAR* pszFullFileName, -+ IMG_UINT32 ui32Line, -+ const IMG_CHAR* pszFormat, -+ ... -+ ) -+{ -+ IMG_BOOL bTrace; -+ const IMG_CHAR *pszFileName = pszFullFileName; -+ IMG_CHAR *pszLeafName; -+ -+ -+ bTrace = (IMG_BOOL)(ui32DebugLevel & DBGPRIV_CALLTRACE) ? IMG_TRUE : IMG_FALSE; -+ -+ if (gPVRDebugLevel & ui32DebugLevel) -+ { -+ va_list vaArgs; -+ unsigned long ulLockFlags = 0; -+ IMG_CHAR *pszBuf; -+ IMG_UINT32 ui32BufSiz; -+ -+ SelectBuffer(&pszBuf, &ui32BufSiz); -+ -+ va_start(vaArgs, pszFormat); -+ -+ GetBufferLock(&ulLockFlags); -+ -+ /* Add in the level of warning */ -+ if (bTrace == IMG_FALSE) -+ { -+ switch(ui32DebugLevel) -+ { -+ case DBGPRIV_FATAL: -+ { -+ strncpy (pszBuf, "PVR_K:(Fatal): ", (ui32BufSiz -1)); -+ break; -+ } -+ case DBGPRIV_ERROR: -+ { -+ strncpy (pszBuf, "PVR_K:(Error): ", (ui32BufSiz -1)); -+ break; -+ } -+ case DBGPRIV_WARNING: -+ { -+ strncpy (pszBuf, "PVR_K:(Warning): ", (ui32BufSiz -1)); -+ break; -+ } -+ case DBGPRIV_MESSAGE: -+ { -+ strncpy (pszBuf, "PVR_K:(Message): ", (ui32BufSiz -1)); -+ break; -+ } -+ case DBGPRIV_VERBOSE: -+ { -+ strncpy (pszBuf, "PVR_K:(Verbose): ", (ui32BufSiz -1)); -+ break; -+ } -+ default: -+ { -+ strncpy (pszBuf, "PVR_K:(Unknown message level)", (ui32BufSiz -1)); -+ break; -+ } -+ } -+ } -+ else -+ { -+ strncpy (pszBuf, "PVR_K: ", (ui32BufSiz -1)); -+ } -+ -+ if (VBAppend(pszBuf, ui32BufSiz, pszFormat, vaArgs)) -+ { -+ printk(KERN_INFO "PVR_K:(Message Truncated): %s\n", pszBuf); -+ } -+ else -+ { -+ /* Traces don't need a location */ -+ if (bTrace == IMG_FALSE) -+ { -+#ifdef DEBUG_LOG_PATH_TRUNCATE -+ /* Buffer for rewriting filepath in log messages */ -+ static IMG_CHAR szFileNameRewrite[PVR_MAX_FILEPATH_LEN]; -+ -+ IMG_CHAR* pszTruncIter; -+ IMG_CHAR* pszTruncBackInter; -+ -+ /* Truncate path (DEBUG_LOG_PATH_TRUNCATE shoud be set to EURASIA env var)*/ -+ if (strlen(pszFullFileName) > strlen(DEBUG_LOG_PATH_TRUNCATE)+1) -+ pszFileName = pszFullFileName + strlen(DEBUG_LOG_PATH_TRUNCATE)+1; -+ -+ /* Try to find '/../' entries and remove it together with -+ previous entry. Repeat unit all removed */ -+ strncpy(szFileNameRewrite, pszFileName,PVR_MAX_FILEPATH_LEN); -+ -+ if(strlen(szFileNameRewrite) == PVR_MAX_FILEPATH_LEN-1) { -+ IMG_CHAR szTruncateMassage[] = "FILENAME TRUNCATED"; -+ strcpy(szFileNameRewrite + (PVR_MAX_FILEPATH_LEN - 1 - strlen(szTruncateMassage)), szTruncateMassage); -+ } -+ -+ pszTruncIter = szFileNameRewrite; -+ while(*pszTruncIter++ != 0) -+ { -+ IMG_CHAR* pszNextStartPoint; -+ /* Find '/../' pattern */ -+ if( -+ !( ( *pszTruncIter == '/' && (pszTruncIter-4 >= szFileNameRewrite) ) && -+ ( *(pszTruncIter-1) == '.') && -+ ( *(pszTruncIter-2) == '.') && -+ ( *(pszTruncIter-3) == '/') ) -+ ) continue; -+ -+ /* Find previous '/' */ -+ pszTruncBackInter = pszTruncIter - 3; -+ while(*(--pszTruncBackInter) != '/') -+ { -+ if(pszTruncBackInter <= szFileNameRewrite) break; -+ } -+ pszNextStartPoint = pszTruncBackInter; -+ -+ /* Remove found region */ -+ while(*pszTruncIter != 0) -+ { -+ *pszTruncBackInter++ = *pszTruncIter++; -+ } -+ *pszTruncBackInter = 0; -+ -+ /* Start again */ -+ pszTruncIter = pszNextStartPoint; -+ } -+ -+ pszFileName = szFileNameRewrite; -+ /* Remove first '/' if exist (it's always relative path */ -+ if(*pszFileName == '/') pszFileName++; -+#endif -+ -+#if !defined(__sh__) -+ pszLeafName = (IMG_CHAR *)strrchr (pszFileName, '\\'); -+ -+ if (pszLeafName) -+ { -+ pszFileName = pszLeafName; -+ } -+#endif /* __sh__ */ -+ -+ if (BAppend(pszBuf, ui32BufSiz, " [%u, %s]", ui32Line, pszFileName)) -+ { -+ printk(KERN_INFO "PVR_K:(Message Truncated): %s\n", pszBuf); -+ } -+ else -+ { -+ printk(KERN_INFO "%s\n", pszBuf); -+ } -+ } -+ else -+ { -+ printk(KERN_INFO "%s\n", pszBuf); -+ } -+ } -+ -+ ReleaseBufferLock(ulLockFlags); -+ -+ va_end (vaArgs); -+ } -+} -+ -+#endif /* PVRSRV_NEED_PVR_DPF */ -+ -+#if defined(DEBUG) -+ -+IMG_INT PVRDebugProcSetLevel(struct file *file, const IMG_CHAR *buffer, IMG_UINT32 count, IMG_VOID *data) -+{ -+#define _PROC_SET_BUFFER_SZ 6 -+ IMG_CHAR data_buffer[_PROC_SET_BUFFER_SZ]; -+ -+ if (count > _PROC_SET_BUFFER_SZ) -+ { -+ return -EINVAL; -+ } -+ else -+ { -+ if (pvr_copy_from_user(data_buffer, buffer, count)) -+ return -EINVAL; -+ if (data_buffer[count - 1] != '\n') -+ return -EINVAL; -+ if (sscanf(data_buffer, "%i", &gPVRDebugLevel) == 0) -+ return -EINVAL; -+ gPVRDebugLevel &= (1 << DBGPRIV_DBGLEVEL_COUNT) - 1; -+ } -+ return (count); -+} -+ -+void ProcSeqShowDebugLevel(struct seq_file *sfile,void* el) -+{ -+ seq_printf(sfile, "%u\n", gPVRDebugLevel); -+} -+ -+#endif /* defined(DEBUG) */ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/pvr_drm.c b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/pvr_drm.c -new file mode 100644 -index 0000000..f59e544 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/pvr_drm.c -@@ -0,0 +1,742 @@ -+/*************************************************************************/ /*! -+@Title PowerVR drm driver -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description linux module setup -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+#if defined(SUPPORT_DRI_DRM) -+ -+#include <linux/version.h> -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)) -+#ifndef AUTOCONF_INCLUDED -+#include <linux/config.h> -+#endif -+#endif -+ -+#include <linux/init.h> -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/fs.h> -+#include <linux/proc_fs.h> -+#include <linux/sched.h> -+#include <asm/ioctl.h> -+#include <drm/drmP.h> -+#include <drm/drm.h> -+ -+#include "img_defs.h" -+#include "services.h" -+#include "kerneldisplay.h" -+#include "kernelbuffer.h" -+#include "syscommon.h" -+#include "pvrmmap.h" -+#include "mm.h" -+#include "mmap.h" -+#include "mutex.h" -+#include "pvr_debug.h" -+#include "srvkm.h" -+#include "perproc.h" -+#include "handle.h" -+#include "pvr_bridge_km.h" -+#include "pvr_bridge.h" -+#include "proc.h" -+#include "pvrmodule.h" -+#include "pvrversion.h" -+#include "lock.h" -+#include "linkage.h" -+#include "pvr_drm.h" -+ -+#if defined(PVR_DRI_DRM_NOT_PCI) -+#include "pvr_drm_mod.h" -+#endif -+ -+#if defined(NO_HARDWARE) -+#define PVR_DRM_NAME SYS_SGX_DEV_NAME -+#else -+#define PVR_DRM_NAME PVRSRV_MODNAME -+#endif -+ -+#define PVR_DRM_DESC "Imagination Technologies PVR DRM" -+ -+#define PVR_DRM_DATE "20110701" -+ -+#if defined(PVR_DRI_DRM_PLATFORM_DEV) && !defined(SUPPORT_DRI_DRM_PLUGIN) -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)) -+#define PVR_NEW_STYLE_DRM_PLATFORM_DEV -+#else -+#define PVR_OLD_STYLE_DRM_PLATFORM_DEV -+#endif -+#endif -+ -+/* -+ * Prior to Linux 2.6.36, we couldn't do the release processing in post close -+ * when workqueues were being used, because drm_release held the big kernel -+ * lock (BKL) when it called post close. -+ * If the resman needs to wait for processing being done by a workqueue, -+ * that processing won't complete whilst the lock is held by another thread, -+ * as the workqueue won't get scheduled. -+ */ -+#undef PVR_DRI_DRM_USE_POST_CLOSE -+#if (defined(SUPPORT_DRI_DRM_EXT) && !defined(PVR_LINUX_USING_WORKQUEUES)) || \ -+ (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)) -+#define PVR_DRI_DRM_USE_POST_CLOSE -+#endif -+ -+DECLARE_WAIT_QUEUE_HEAD(sWaitForInit); -+ -+#if defined(SUPPORT_DRM_MODESET) -+static struct drm_driver sPVRDrmDriver; -+#endif -+ -+/* Once bInitComplete and bInitFailed are set, they stay set */ -+IMG_BOOL bInitComplete; -+IMG_BOOL bInitFailed; -+ -+#if !defined(PVR_DRI_DRM_NOT_PCI) && !defined(SUPPORT_DRI_DRM_PLUGIN) -+#if defined(PVR_DRI_DRM_PLATFORM_DEV) -+struct platform_device *gpsPVRLDMDev; -+#else -+struct pci_dev *gpsPVRLDMDev; -+#endif -+#endif -+ -+struct drm_device *gpsPVRDRMDev; -+ -+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,24)) -+#error "Linux kernel version 2.6.25 or later required for PVR DRM support" -+#endif -+ -+#define PVR_DRM_FILE struct drm_file * -+ -+#if !defined(SUPPORT_DRI_DRM_EXT) && !defined(SUPPORT_DRI_DRM_PLUGIN) -+#if defined(PVR_DRI_DRM_PLATFORM_DEV) -+#if defined(PVR_LDM_PLATFORM_PRE_REGISTERED) || defined(NO_HARDWARE) -+static struct platform_device_id asPlatIdList[] = { -+ {SYS_SGX_DEV_NAME, 0}, -+ {} -+}; -+#endif -+#else /* defined(PVR_DRI_DRM_PLATFORM_DEV) */ -+static struct pci_device_id asPciIdList[] = { -+#if defined(PVR_DRI_DRM_NOT_PCI) -+ {1, 1, 1, 1, 0, 0, 0}, -+#else /* defined(PVR_DRI_DRM_NOT_PCI) */ -+ {SYS_SGX_DEV_VENDOR_ID, SYS_SGX_DEV_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, -+#if defined(SYS_SGX_DEV1_DEVICE_ID) -+ {SYS_SGX_DEV_VENDOR_ID, SYS_SGX_DEV1_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, -+#endif /* defined(SYS_SGX_DEV1_DEVICE_ID) */ -+#endif /* defined(PVR_DRI_DRM_NOT_PCI) */ -+ {0} -+}; -+#endif /* defined(PVR_DRI_DRM_PLATFORM_DEV) */ -+#endif /* !defined(SUPPORT_DRI_DRM_EXT) */ -+ -+DRI_DRM_STATIC int -+PVRSRVDrmLoad(struct drm_device *dev, unsigned long flags) -+{ -+ int iRes = 0; -+ -+ PVR_TRACE(("PVRSRVDrmLoad")); -+ -+ gpsPVRDRMDev = dev; -+#if !defined(PVR_DRI_DRM_NOT_PCI) && !defined(SUPPORT_DRI_DRM_PLUGIN) -+#if defined(PVR_DRI_DRM_PLATFORM_DEV) -+ gpsPVRLDMDev = dev->platformdev; -+#else -+ gpsPVRLDMDev = dev->pdev; -+#endif -+#endif -+ -+#if defined(PDUMP) -+ iRes = dbgdrv_init(); -+ if (iRes != 0) -+ { -+ goto exit; -+ } -+#endif -+ /* Module initialisation */ -+ iRes = PVRCore_Init(); -+ if (iRes != 0) -+ { -+ goto exit_dbgdrv_cleanup; -+ } -+ -+#if defined(DISPLAY_CONTROLLER) -+ iRes = PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Init)(dev); -+ if (iRes != 0) -+ { -+ goto exit_pvrcore_cleanup; -+ } -+#endif -+ goto exit; -+ -+#if defined(DISPLAY_CONTROLLER) -+exit_pvrcore_cleanup: -+ PVRCore_Cleanup(); -+#endif -+exit_dbgdrv_cleanup: -+#if defined(PDUMP) -+ dbgdrv_cleanup(); -+#endif -+exit: -+ if (iRes != 0) -+ { -+ bInitFailed = IMG_TRUE; -+ } -+ bInitComplete = IMG_TRUE; -+ -+ wake_up_interruptible(&sWaitForInit); -+ -+ return iRes; -+} -+ -+DRI_DRM_STATIC int -+PVRSRVDrmUnload(struct drm_device *dev) -+{ -+ PVR_TRACE(("PVRSRVDrmUnload")); -+ -+#if defined(DISPLAY_CONTROLLER) -+ PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Cleanup)(dev); -+#endif -+ -+ PVRCore_Cleanup(); -+ -+#if defined(PDUMP) -+ dbgdrv_cleanup(); -+#endif -+ -+ return 0; -+} -+ -+DRI_DRM_STATIC int -+PVRSRVDrmOpen(struct drm_device *dev, struct drm_file *file) -+{ -+ while (!bInitComplete) -+ { -+ DEFINE_WAIT(sWait); -+ -+ prepare_to_wait(&sWaitForInit, &sWait, TASK_INTERRUPTIBLE); -+ -+ if (!bInitComplete) -+ { -+ PVR_TRACE(("%s: Waiting for module initialisation to complete", __FUNCTION__)); -+ -+ schedule(); -+ } -+ -+ finish_wait(&sWaitForInit, &sWait); -+ -+ if (signal_pending(current)) -+ { -+ return -ERESTARTSYS; -+ } -+ } -+ -+ if (bInitFailed) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: Module initialisation failed", __FUNCTION__)); -+ return -EINVAL; -+ } -+ -+ return PVRSRVOpen(dev, file); -+} -+ -+#if defined(PVR_DRI_DRM_USE_POST_CLOSE) || defined(SUPPORT_DRI_DRM_PLUGIN) -+#if defined(SUPPORT_DRI_DRM_PLUGIN) -+DRI_DRM_STATIC int -+PVRSRVDrmRelease(struct drm_device *dev, struct drm_file *file) -+#else -+DRI_DRM_STATIC void -+PVRSRVDrmPostClose(struct drm_device *dev, struct drm_file *file) -+#endif -+{ -+ PVRSRVRelease(file->driver_priv); -+ -+ file->driver_priv = NULL; -+ -+#if defined(SUPPORT_DRI_DRM_PLUGIN) -+ return 0; -+#endif -+} -+#else -+DRI_DRM_STATIC int -+PVRSRVDrmRelease(struct inode *inode, struct file *filp) -+{ -+ struct drm_file *file_priv = filp->private_data; -+ void *psDriverPriv = file_priv->driver_priv; -+ int ret; -+ -+ ret = drm_release(inode, filp); -+ -+ if (ret != 0) -+ { -+ /* -+ * An error means drm_release didn't call drm_lastclose, -+ * but it will have freed file_priv. -+ */ -+ PVR_DPF((PVR_DBG_ERROR, "%s : drm_release failed: %d", -+ __FUNCTION__, ret)); -+ } -+ -+ PVRSRVRelease(psDriverPriv); -+ -+ return 0; -+} -+#endif -+ -+DRI_DRM_STATIC int -+PVRDRMIsMaster(struct drm_device *dev, void *arg, struct drm_file *pFile) -+{ -+ return 0; -+} -+ -+#if defined(SUPPORT_DRI_DRM_EXT) -+int -+PVRDRM_Dummy_ioctl(struct drm_device *dev, void *arg, struct drm_file *pFile) -+{ -+ return 0; -+} -+#endif -+ -+DRI_DRM_STATIC int -+PVRDRMUnprivCmd(struct drm_device *dev, void *arg, struct drm_file *pFile) -+{ -+ int ret = 0; -+ -+ LinuxLockMutexNested(&gPVRSRVLock, PVRSRV_LOCK_CLASS_BRIDGE); -+ -+ if (arg == NULL) -+ { -+ ret = -EFAULT; -+ } -+ else -+ { -+ IMG_UINT32 *pui32Args = (IMG_UINT32 *)arg; -+ IMG_UINT32 ui32Cmd = pui32Args[0]; -+ IMG_UINT32 *pui32OutArg = (IMG_UINT32 *)arg; -+ -+ switch (ui32Cmd) -+ { -+ case PVR_DRM_UNPRIV_INIT_SUCCESFUL: -+ *pui32OutArg = PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL) ? 1 : 0; -+ break; -+ -+ default: -+ ret = -EFAULT; -+ } -+ -+ } -+ -+ LinuxUnLockMutex(&gPVRSRVLock); -+ -+ return ret; -+} -+ -+#if defined(DISPLAY_CONTROLLER) && defined(PVR_DISPLAY_CONTROLLER_DRM_IOCTL) -+static int -+PVRDRM_Display_ioctl(struct drm_device *dev, void *arg, struct drm_file *pFile) -+{ -+ int res; -+ -+ LinuxLockMutexNested(&gPVRSRVLock, PVRSRV_LOCK_CLASS_BRIDGE); -+ -+ res = PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Ioctl)(dev, arg, pFile); -+ -+ LinuxUnLockMutex(&gPVRSRVLock); -+ -+ return res; -+} -+#endif -+ -+#if defined(SUPPORT_DRM_MODESET) -+static int -+PVRSRVPciProbe(struct pci_dev *dev, const struct pci_device_id *id) -+{ -+ PVR_TRACE(("PVRSRVPciProbe")); -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)) -+ return drm_get_pci_dev(dev, id, &sPVRDrmDriver); -+#else -+ return drm_get_dev(dev, id, &sPVRDrmDriver); -+#endif -+} -+ -+static void -+PVRSRVPciRemove(struct pci_dev *dev) -+{ -+ struct drm_device *psDrmDev; -+ -+ PVR_TRACE(("PVRSRVPciRemove")); -+ -+ psDrmDev = pci_get_drvdata(dev); -+ drm_put_dev(psDrmDev); -+} -+#endif -+ -+/* -+ * For Linux 2.6.33 and above, the DRM ioctl entry point is of the unlocked -+ * variety. The big kernel lock is still taken for ioctls, unless -+ * the DRM_UNLOCKED flag is set. If you revise one of the driver specific -+ * ioctls, or add a new one, consider whether the gPVRSRVLock mutex needs -+ * to be taken. -+ */ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33)) -+#define PVR_DRM_FOPS_IOCTL .unlocked_ioctl -+#define PVR_DRM_UNLOCKED DRM_UNLOCKED -+#else -+#define PVR_DRM_FOPS_IOCTL .ioctl -+#define PVR_DRM_UNLOCKED 0 -+#endif -+ -+#if !defined(SUPPORT_DRI_DRM_EXT) -+ -+#if defined(DRM_IOCTL_DEF) -+#define PVR_DRM_IOCTL_DEF(ioctl, _func, _flags) DRM_IOCTL_DEF(DRM_##ioctl, _func, _flags) -+#else -+#define PVR_DRM_IOCTL_DEF(ioctl, _func, _flags) DRM_IOCTL_DEF_DRV(ioctl, _func, _flags) -+#endif -+ -+struct drm_ioctl_desc sPVRDrmIoctls[] = { -+ PVR_DRM_IOCTL_DEF(PVR_SRVKM, PVRSRV_BridgeDispatchKM, PVR_DRM_UNLOCKED), -+ PVR_DRM_IOCTL_DEF(PVR_IS_MASTER, PVRDRMIsMaster, DRM_MASTER | PVR_DRM_UNLOCKED), -+ PVR_DRM_IOCTL_DEF(PVR_UNPRIV, PVRDRMUnprivCmd, PVR_DRM_UNLOCKED), -+#if defined(PDUMP) -+ PVR_DRM_IOCTL_DEF(PVR_DBGDRV, dbgdrv_ioctl, PVR_DRM_UNLOCKED), -+#endif -+#if defined(DISPLAY_CONTROLLER) && defined(PVR_DISPLAY_CONTROLLER_DRM_IOCTL) -+ PVR_DRM_IOCTL_DEF(PVR_DISP, PVRDRM_Display_ioctl, DRM_MASTER | PVR_DRM_UNLOCKED) -+#endif -+}; -+ -+#if !defined(SUPPORT_DRI_DRM_PLUGIN) -+static int pvr_max_ioctl = DRM_ARRAY_SIZE(sPVRDrmIoctls); -+#endif -+ -+#if defined(PVR_DRI_DRM_PLATFORM_DEV) && !defined(SUPPORT_DRI_DRM_EXT) && \ -+ !defined(SUPPORT_DRI_DRM_PLUGIN) -+static int PVRSRVDrmProbe(struct platform_device *pDevice); -+static int PVRSRVDrmRemove(struct platform_device *pDevice); -+#endif /* defined(PVR_DRI_DRM_PLATFORM_DEV) && !defined(SUPPORT_DRI_DRM_EXT) */ -+ -+#if defined(SUPPORT_DRI_DRM_PLUGIN) -+static PVRSRV_DRM_PLUGIN sPVRDrmPlugin = -+{ -+ .name = PVR_DRM_NAME, -+ -+ .open = PVRSRVDrmOpen, -+ .load = PVRSRVDrmLoad, -+ .unload = PVRSRVDrmUnload, -+ -+ .release = PVRSRVDrmRelease, -+ -+ .mmap = PVRMMap, -+ -+ .ioctls = sPVRDrmIoctls, -+ .num_ioctls = DRM_ARRAY_SIZE(sPVRDrmIoctls), -+ .ioctl_start = 0 -+}; -+#else /* defined(SUPPORT_DRI_DRM_PLUGIN) */ -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) -+static const struct file_operations sPVRFileOps = -+{ -+ .owner = THIS_MODULE, -+ .open = drm_open, -+#if defined(PVR_DRI_DRM_USE_POST_CLOSE) -+ .release = drm_release, -+#else -+ .release = PVRSRVDrmRelease, -+#endif -+ PVR_DRM_FOPS_IOCTL = drm_ioctl, -+ .mmap = PVRMMap, -+ .poll = drm_poll, -+ .fasync = drm_fasync, -+}; -+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) */ -+ -+static struct drm_driver sPVRDrmDriver = -+{ -+#if defined(PVR_OLD_STYLE_DRM_PLATFORM_DEV) -+ .driver_features = DRIVER_USE_PLATFORM_DEVICE, -+#else -+ .driver_features = 0, -+#endif -+ .dev_priv_size = 0, -+ .load = PVRSRVDrmLoad, -+ .unload = PVRSRVDrmUnload, -+ .open = PVRSRVDrmOpen, -+#if defined(PVR_DRI_DRM_USE_POST_CLOSE) -+ .postclose = PVRSRVDrmPostClose, -+#endif -+#if !defined(PVR_DRI_DRM_PLATFORM_DEV) && !defined(SUPPORT_DRM_MODESET) -+ .suspend = PVRSRVDriverSuspend, -+ .resume = PVRSRVDriverResume, -+#endif -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)) -+ .get_map_ofs = drm_core_get_map_ofs, -+ .get_reg_ofs = drm_core_get_reg_ofs, -+#endif -+ .ioctls = sPVRDrmIoctls, -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) -+ .fops = &sPVRFileOps, -+#else -+ .fops = -+ { -+ .owner = THIS_MODULE, -+ .open = drm_open, -+#if defined(PVR_DRI_DRM_USE_POST_CLOSE) -+ .release = drm_release, -+#else -+ .release = PVRSRVDrmRelease, -+#endif -+ PVR_DRM_FOPS_IOCTL = drm_ioctl, -+ .mmap = PVRMMap, -+ .poll = drm_poll, -+ .fasync = drm_fasync, -+ }, -+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) */ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39)) -+#if defined(PVR_OLD_STYLE_DRM_PLATFORM_DEV) -+ .platform_driver = -+ { -+ .id_table = asPlatIdList, -+ .driver = -+ { -+ .name = PVR_DRM_NAME, -+ }, -+ .probe = PVRSRVDrmProbe, -+ .remove = PVRSRVDrmRemove, -+ .suspend = PVRSRVDriverSuspend, -+ .resume = PVRSRVDriverResume, -+ .shutdown = PVRSRVDriverShutdown, -+ }, -+#else -+ .pci_driver = -+ { -+ .name = PVR_DRM_NAME, -+ .id_table = asPciIdList, -+#if defined(SUPPORT_DRM_MODESET) -+ .probe = PVRSRVPciProbe, -+ .remove = PVRSRVPciRemove, -+ .suspend = PVRSRVDriverSuspend, -+ .resume = PVRSRVDriverResume, -+#endif -+ }, -+#endif -+#endif -+ .name = PVR_DRM_NAME, -+ .desc = PVR_DRM_DESC, -+ .date = PVR_DRM_DATE, -+ .major = PVRVERSION_MAJ, -+ .minor = PVRVERSION_MIN, -+ .patchlevel = PVRVERSION_BUILD, -+}; -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)) && !defined(PVR_DRI_DRM_PLATFORM_DEV) -+static struct pci_driver sPVRPCIDriver = -+{ -+ .name = PVR_DRM_NAME, -+ .id_table = asPciIdList, -+#if defined(SUPPORT_DRM_MODESET) -+ .probe = PVRSRVPciProbe, -+ .remove = PVRSRVPciRemove, -+ .suspend = PVRSRVDriverSuspend, -+ .resume = PVRSRVDriverResume, -+#endif -+}; -+#endif -+ -+#if defined(PVR_NEW_STYLE_DRM_PLATFORM_DEV) -+#if defined(NO_HARDWARE) -+static void PVRSRVDeviceRelease(struct device unref__ *pDevice) -+{ -+} -+ -+static struct platform_device sPVRPlatDevice = { -+ .name = PVR_DRM_NAME, -+ .id = -1, -+ .dev = { -+ .release = PVRSRVDeviceRelease -+ } -+}; -+#endif -+ -+static struct platform_driver sPVRPlatDriver = -+{ -+ .id_table = asPlatIdList, -+ .driver = -+ { -+ .name = PVR_DRM_NAME, -+ }, -+ .probe = PVRSRVDrmProbe, -+ .remove = PVRSRVDrmRemove, -+ .suspend = PVRSRVDriverSuspend, -+ .resume = PVRSRVDriverResume, -+ .shutdown = PVRSRVDriverShutdown, -+}; -+#endif -+ -+#endif /* defined(SUPPORT_DRI_DRM_PLUGIN) */ -+ -+#if defined(PVR_DRI_DRM_PLATFORM_DEV) && !defined(SUPPORT_DRI_DRM_EXT) && \ -+ !defined(SUPPORT_DRI_DRM_PLUGIN) -+static int -+PVRSRVDrmProbe(struct platform_device *pDevice) -+{ -+ PVR_TRACE(("PVRSRVDrmProbe")); -+ -+#if defined(PVR_NEW_STYLE_DRM_PLATFORM_DEV) -+ gpsPVRLDMDev = pDevice; -+ -+ return drm_platform_init(&sPVRDrmDriver, gpsPVRLDMDev); -+#else -+ return drm_get_platform_dev(pDevice, &sPVRDrmDriver); -+#endif -+} -+ -+static int -+PVRSRVDrmRemove(struct platform_device *pDevice) -+{ -+ PVR_TRACE(("PVRSRVDrmRemove")); -+ -+#if defined(PVR_NEW_STYLE_DRM_PLATFORM_DEV) -+ drm_platform_exit(&sPVRDrmDriver, gpsPVRLDMDev); -+#else -+ drm_put_dev(gpsPVRDRMDev); -+#endif -+ return 0; -+} -+#endif -+ -+static int __init PVRSRVDrmInit(void) -+{ -+ int iRes; -+#if !defined(SUPPORT_DRI_DRM_PLUGIN) -+ sPVRDrmDriver.num_ioctls = pvr_max_ioctl; -+#endif -+ -+#if defined(SUPPORT_DRM_MODESET) -+ sPVRDrmDriver.driver_features |= DRIVER_MODESET; -+#endif -+ -+ /* Must come before attempting to print anything via Services */ -+ PVRDPFInit(); -+ -+#if defined(PVR_NEW_STYLE_DRM_PLATFORM_DEV) -+ iRes = platform_driver_register(&sPVRPlatDriver); -+#if defined(NO_HARDWARE) -+ if (iRes == 0) -+ { -+ iRes = platform_device_register(&sPVRPlatDevice); -+ if (iRes != 0) -+ { -+ platform_driver_unregister(&sPVRPlatDriver); -+ } -+ } -+#endif -+#else /* defined(PVR_NEW_STYLE_DRM_PLATFORM_DEV) */ -+#if defined(SUPPORT_DRI_DRM_PLUGIN) -+ iRes = SysDRMRegisterPlugin(&sPVRDrmPlugin); -+#else /* defined(SUPPORT_DRI_DRM_PLUGIN) */ -+#if defined(PVR_DRI_DRM_NOT_PCI) -+ iRes = drm_pvr_dev_add(); -+ if (iRes != 0) -+ { -+ return iRes; -+ } -+#endif -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)) -+#if defined(PVR_DRI_DRM_PLATFORM_DEV) -+ iRes = drm_platform_init(&sPVRDrmDriver, gpsPVRLDMDev); -+#else -+ iRes = drm_pci_init(&sPVRDrmDriver, &sPVRPCIDriver); -+#endif -+#else /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)) */ -+ iRes = drm_init(&sPVRDrmDriver); -+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)) */ -+ -+#if defined(PVR_DRI_DRM_NOT_PCI) -+ if (iRes != 0) -+ { -+ drm_pvr_dev_remove(); -+ } -+#endif -+#endif /* defined(SUPPORT_DRI_DRM_PLUGIN) */ -+#endif /* defined(PVR_NEW_STYLE_DRM_PLATFORM_DEV) */ -+ return iRes; -+} -+ -+static void __exit PVRSRVDrmExit(void) -+{ -+#if defined(PVR_NEW_STYLE_DRM_PLATFORM_DEV) -+#if defined(NO_HARDWARE) -+ platform_device_unregister(&sPVRPlatDevice); -+#endif -+ platform_driver_unregister(&sPVRPlatDriver); -+#else /* defined(PVR_NEW_STYLE_DRM_PLATFORM_DEV) */ -+#if defined(SUPPORT_DRI_DRM_PLUGIN) -+ SysDRMUnregisterPlugin(&sPVRDrmPlugin); -+#else /* defined(SUPPORT_DRI_DRM_PLUGIN) */ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)) -+#if defined(PVR_DRI_DRM_PLATFORM_DEV) -+ drm_platform_exit(&sPVRDrmDriver, gpsPVRLDMDev); -+#else -+ drm_pci_exit(&sPVRDrmDriver, &sPVRPCIDriver); -+#endif -+#else /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)) */ -+ drm_exit(&sPVRDrmDriver); -+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)) */ -+ -+#if defined(PVR_DRI_DRM_NOT_PCI) -+ drm_pvr_dev_remove(); -+#endif -+#endif /* defined(SUPPORT_DRI_DRM_PLUGIN) */ -+#endif /* defined(PVR_NEW_STYLE_DRM_PLATFORM_DEV) */ -+} -+ -+/* -+ * These macro calls define the initialisation and removal functions of the -+ * driver. Although they are prefixed `module_', they apply when compiling -+ * statically as well; in both cases they define the function the kernel will -+ * run to start/stop the driver. -+*/ -+module_init(PVRSRVDrmInit); -+module_exit(PVRSRVDrmExit); -+#endif /* !defined(SUPPORT_DRI_DRM_EXT) */ -+#endif /* defined(SUPPORT_DRI_DRM) */ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/pvr_drm.h b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/pvr_drm.h -new file mode 100644 -index 0000000..c2ee856 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/pvr_drm.h -@@ -0,0 +1,158 @@ -+/*************************************************************************/ /*! -+@Title PowerVR drm driver -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description drm module -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+#if !defined(__PVR_DRM_H__) -+#define __PVR_DRM_H__ -+ -+#include "pvr_drm_shared.h" -+ -+#if defined(SUPPORT_DRI_DRM) -+#define PVR_DRM_MAKENAME_HELPER(x, y) x ## y -+#define PVR_DRM_MAKENAME(x, y) PVR_DRM_MAKENAME_HELPER(x, y) -+ -+#if defined(PVR_DRI_DRM_PLATFORM_DEV) -+#define LDM_DEV struct platform_device -+#endif -+ -+int PVRCore_Init(void); -+void PVRCore_Cleanup(void); -+int PVRSRVOpen(struct drm_device *dev, struct drm_file *pFile); -+void PVRSRVRelease(void *pvPrivData); -+ -+#if !defined(SUPPORT_DRI_DRM_PLUGIN) -+#if defined(PVR_DRI_DRM_PLATFORM_DEV) -+void PVRSRVDriverShutdown(LDM_DEV *pDevice); -+int PVRSRVDriverSuspend(LDM_DEV *pDevice, pm_message_t state); -+int PVRSRVDriverResume(LDM_DEV *pDevice); -+#else -+#if defined(SUPPORT_DRM_MODESET) -+int PVRSRVDriverSuspend(struct pci_dev *pDevice, pm_message_t state); -+int PVRSRVDriverResume(struct pci_dev *pDevice); -+#else -+int PVRSRVDriverSuspend(struct drm_device *pDevice, pm_message_t state); -+int PVRSRVDriverResume(struct drm_device *pDevice); -+#endif /* defined(SUPPORT_DRM_MODESET) */ -+#endif /* defined(PVR_DRI_DRM_PLATFORM_DEV) */ -+#endif /* !defined(SUPPORT_DRI_DRM_PLUGIN) */ -+ -+int PVRSRV_BridgeDispatchKM(struct drm_device *dev, void *arg, struct drm_file *pFile); -+ -+#if defined(SUPPORT_DRI_DRM_EXT) -+#define DRI_DRM_STATIC -+/*Exported functions to common drm layer*/ -+int PVRSRVDrmLoad(struct drm_device *dev, unsigned long flags); -+int PVRSRVDrmUnload(struct drm_device *dev); -+int PVRSRVDrmOpen(struct drm_device *dev, struct drm_file *file); -+#if defined(PVR_LINUX_USING_WORKQUEUES) -+DRI_DRM_STATIC int PVRSRVDrmRelease(struct inode *inode, struct file *filp); -+#else -+void PVRSRVDrmPostClose(struct drm_device *dev, struct drm_file *file); -+#endif -+int PVRDRMIsMaster(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile); -+int PVRDRMUnprivCmd(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile); -+int PVRDRM_Dummy_ioctl(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile); -+#else -+#define DRI_DRM_STATIC static -+#endif /* defined(SUPPORT_DRI_DRM_EXT) */ -+ -+#if defined(DISPLAY_CONTROLLER) -+extern int PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Init)(struct drm_device *); -+extern void PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Cleanup)(struct drm_device *); -+extern int PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Suspend)(struct drm_device *); -+extern int PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Resume)(struct drm_device *); -+#if defined(PVR_DISPLAY_CONTROLLER_DRM_IOCTL) -+extern int PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Ioctl)(struct drm_device *dev, void *arg, struct drm_file *pFile); -+#endif -+#endif -+ -+#if defined(PDUMP) -+int dbgdrv_init(void); -+void dbgdrv_cleanup(void); -+IMG_INT dbgdrv_ioctl(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile); -+#endif -+ -+#if !defined(SUPPORT_DRI_DRM_EXT) -+/* -+ * We need the command number names to begin with "DRM_" for newer versions -+ * of the macro used to fill out the DRM ioctl table. Similarly, the -+ * ioctl number names must begin with "DRM_IOCTL_". The suffixes for the -+ * two sets of strings must match (e.g. end with "PVR_SRVKM" in both -+ * cases). -+ */ -+ -+#define DRM_PVR_SRVKM PVR_DRM_SRVKM_CMD -+#define DRM_PVR_IS_MASTER PVR_DRM_IS_MASTER_CMD -+#define DRM_PVR_UNPRIV PVR_DRM_UNPRIV_CMD -+#define DRM_PVR_DBGDRV PVR_DRM_DBGDRV_CMD -+#define DRM_PVR_DISP PVR_DRM_DISP_CMD -+ -+/* IOCTL numbers, relative to DRM_COMMAND_BASE */ -+#define DRM_IOCTL_PVR_SRVKM _IO(0, DRM_PVR_SRVKM) -+#define DRM_IOCTL_PVR_IS_MASTER _IO(0, DRM_PVR_IS_MASTER) -+#define DRM_IOCTL_PVR_UNPRIV _IO(0, DRM_PVR_UNPRIV) -+#define DRM_IOCTL_PVR_DBGDRV _IO(0, DRM_PVR_DBGDRV) -+#define DRM_IOCTL_PVR_DISP _IO(0, DRM_PVR_DISP) -+#endif /* !defined(SUPPORT_DRI_DRM_EXT) */ -+ -+#if defined(SUPPORT_DRI_DRM_PLUGIN) -+typedef struct { -+ char *name; -+ -+ int (*load)(struct drm_device *dev, unsigned long flags); -+ int (*unload)(struct drm_device *dev); -+ -+ int (*open)(struct drm_device *dev, struct drm_file *file); -+ int (*release)(struct drm_device *dev, struct drm_file *file); -+ -+ int (*mmap)(struct file* pFile, struct vm_area_struct* ps_vma); -+ -+ struct drm_ioctl_desc *ioctls; -+ int num_ioctls; -+ int ioctl_start; -+} PVRSRV_DRM_PLUGIN; -+ -+int SysDRMRegisterPlugin(PVRSRV_DRM_PLUGIN *psDRMPlugin); -+void SysDRMUnregisterPlugin(PVRSRV_DRM_PLUGIN *psDRMPlugin); -+#endif /* defined(SUPPORT_DRI_DRM_PLUGIN) */ -+ -+#endif /* defined(SUPPORT_DRI_DRM) */ -+ -+#endif /* defined(__PVR_DRM_H__) */ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/pvr_uaccess.h b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/pvr_uaccess.h -new file mode 100644 -index 0000000..e78aba7 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/pvr_uaccess.h -@@ -0,0 +1,87 @@ -+/*************************************************************************/ /*! -+@Title Utility functions for user space access -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+#ifndef __PVR_UACCESS_H__ -+#define __PVR_UACCESS_H__ -+ -+#include <linux/version.h> -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)) -+#ifndef AUTOCONF_INCLUDED -+#include <linux/config.h> -+#endif -+#endif -+ -+#include <asm/uaccess.h> -+ -+static inline unsigned long pvr_copy_to_user(void __user *pvTo, const void *pvFrom, unsigned long ulBytes) -+{ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33)) -+ if (access_ok(VERIFY_WRITE, pvTo, ulBytes)) -+ { -+ return __copy_to_user(pvTo, pvFrom, ulBytes); -+ } -+ return ulBytes; -+#else -+ return copy_to_user(pvTo, pvFrom, ulBytes); -+#endif -+} -+ -+static inline unsigned long pvr_copy_from_user(void *pvTo, const void __user *pvFrom, unsigned long ulBytes) -+{ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33)) -+ /* -+ * The compile time correctness checking introduced for copy_from_user in -+ * Linux 2.6.33 isn't fully comaptible with our usage of the function. -+ */ -+ if (access_ok(VERIFY_READ, pvFrom, ulBytes)) -+ { -+ return __copy_from_user(pvTo, pvFrom, ulBytes); -+ } -+ return ulBytes; -+#else -+ return copy_from_user(pvTo, pvFrom, ulBytes); -+#endif -+} -+ -+#define pvr_put_user put_user -+#define pvr_get_user get_user -+ -+#endif /* __PVR_UACCESS_H__ */ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/hwdefs/ocpdefs.h b/drivers/staging/ti-es8-sgx/services4/srvkm/hwdefs/ocpdefs.h -new file mode 100644 -index 0000000..07a6412 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/hwdefs/ocpdefs.h -@@ -0,0 +1,308 @@ -+/*************************************************************************/ /*! -+@Title OCP HW definitions. -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#ifndef _OCPDEFS_H_ -+#define _OCPDEFS_H_ -+ -+/* Register EUR_CR_OCP_REVISION */ -+#define EUR_CR_OCP_REVISION 0xFE00 -+#define EUR_CR_OCP_REVISION_REV_MASK 0xFFFFFFFFUL -+#define EUR_CR_OCP_REVISION_REV_SHIFT 0 -+#define EUR_CR_OCP_REVISION_REV_SIGNED 0 -+ -+/* Register EUR_CR_OCP_HWINFO */ -+#define EUR_CR_OCP_HWINFO 0xFE04 -+#define EUR_CR_OCP_HWINFO_SYS_BUS_WIDTH_MASK 0x00000003UL -+#define EUR_CR_OCP_HWINFO_SYS_BUS_WIDTH_SHIFT 0 -+#define EUR_CR_OCP_HWINFO_SYS_BUS_WIDTH_SIGNED 0 -+ -+#define EUR_CR_OCP_HWINFO_MEM_BUS_WIDTH_MASK 0x00000004UL -+#define EUR_CR_OCP_HWINFO_MEM_BUS_WIDTH_SHIFT 2 -+#define EUR_CR_OCP_HWINFO_MEM_BUS_WIDTH_SIGNED 0 -+ -+/* Register EUR_CR_OCP_SYSCONFIG */ -+#define EUR_CR_OCP_SYSCONFIG 0xFE10 -+#define EUR_CR_OCP_SYSCONFIG_IDLE_MODE_MASK 0x0000000CUL -+#define EUR_CR_OCP_SYSCONFIG_IDLE_MODE_SHIFT 2 -+#define EUR_CR_OCP_SYSCONFIG_IDLE_MODE_SIGNED 0 -+ -+#define EUR_CR_OCP_SYSCONFIG_STANDBY_MODE_MASK 0x00000030UL -+#define EUR_CR_OCP_SYSCONFIG_STANDBY_MODE_SHIFT 4 -+#define EUR_CR_OCP_SYSCONFIG_STANDBY_MODE_SIGNED 0 -+ -+/* Register EUR_CR_OCP_IRQSTATUS_RAW_0 */ -+#define EUR_CR_OCP_IRQSTATUS_RAW_0 0xFE24 -+#define EUR_CR_OCP_IRQSTATUS_RAW_0_INIT_MASK 0x00000001UL -+#define EUR_CR_OCP_IRQSTATUS_RAW_0_INIT_SHIFT 0 -+#define EUR_CR_OCP_IRQSTATUS_RAW_0_INIT_SIGNED 0 -+ -+/* Register EUR_CR_OCP_IRQSTATUS_RAW_1 */ -+#define EUR_CR_OCP_IRQSTATUS_RAW_1 0xFE28 -+#define EUR_CR_OCP_IRQSTATUS_RAW_1_TARGET_MASK 0x00000001UL -+#define EUR_CR_OCP_IRQSTATUS_RAW_1_TARGET_SHIFT 0 -+#define EUR_CR_OCP_IRQSTATUS_RAW_1_TARGET_SIGNED 0 -+ -+/* Register EUR_CR_OCP_IRQSTATUS_RAW_2 */ -+#define EUR_CR_OCP_IRQSTATUS_RAW_2 0xFE2C -+#define EUR_CR_OCP_IRQSTATUS_RAW_2_SGXCORE_MASK 0x00000001UL -+#define EUR_CR_OCP_IRQSTATUS_RAW_2_SGXCORE_SHIFT 0 -+#define EUR_CR_OCP_IRQSTATUS_RAW_2_SGXCORE_SIGNED 0 -+ -+/* Register EUR_CR_OCP_IRQSTATUS_0 */ -+#define EUR_CR_OCP_IRQSTATUS_0 0xFE30 -+#define EUR_CR_OCP_IRQSTATUS_0_INIT_MASK 0x00000001UL -+#define EUR_CR_OCP_IRQSTATUS_0_INIT_SHIFT 0 -+#define EUR_CR_OCP_IRQSTATUS_0_INIT_SIGNED 0 -+ -+/* Register EUR_CR_OCP_IRQSTATUS_1 */ -+#define EUR_CR_OCP_IRQSTATUS_1 0xFE34 -+#define EUR_CR_OCP_IRQSTATUS_1_TARGET_MASK 0x00000001UL -+#define EUR_CR_OCP_IRQSTATUS_1_TARGET_SHIFT 0 -+#define EUR_CR_OCP_IRQSTATUS_1_TARGET_SIGNED 0 -+ -+/* Register EUR_CR_OCP_IRQSTATUS_2 */ -+#define EUR_CR_OCP_IRQSTATUS_2 0xFE38 -+#define EUR_CR_OCP_IRQSTATUS_2_SGXCORE_MASK 0x00000001UL -+#define EUR_CR_OCP_IRQSTATUS_2_SGXCORE_SHIFT 0 -+#define EUR_CR_OCP_IRQSTATUS_2_SGXCORE_SIGNED 0 -+ -+/* Register EUR_CR_OCP_IRQENABLE_SET_0 */ -+#define EUR_CR_OCP_IRQENABLE_SET_0 0xFE3C -+#define EUR_CR_OCP_IRQENABLE_SET_0_INIT_MASK 0x00000001UL -+#define EUR_CR_OCP_IRQENABLE_SET_0_INIT_SHIFT 0 -+#define EUR_CR_OCP_IRQENABLE_SET_0_INIT_SIGNED 0 -+ -+/* Register EUR_CR_OCP_IRQENABLE_SET_1 */ -+#define EUR_CR_OCP_IRQENABLE_SET_1 0xFE40 -+#define EUR_CR_OCP_IRQENABLE_SET_1_TARGET_MASK 0x00000001UL -+#define EUR_CR_OCP_IRQENABLE_SET_1_TARGET_SHIFT 0 -+#define EUR_CR_OCP_IRQENABLE_SET_1_TARGET_SIGNED 0 -+ -+/* Register EUR_CR_OCP_IRQENABLE_SET_2 */ -+#define EUR_CR_OCP_IRQENABLE_SET_2 0xFE44 -+#define EUR_CR_OCP_IRQENABLE_SET_2_SGXCORE_MASK 0x00000001UL -+#define EUR_CR_OCP_IRQENABLE_SET_2_SGXCORE_SHIFT 0 -+#define EUR_CR_OCP_IRQENABLE_SET_2_SGXCORE_SIGNED 0 -+ -+/* Register EUR_CR_OCP_IRQENABLE_CLR_0 */ -+#define EUR_CR_OCP_IRQENABLE_CLR_0 0xFE48 -+#define EUR_CR_OCP_IRQENABLE_CLR_0_INIT_MASK 0x00000001UL -+#define EUR_CR_OCP_IRQENABLE_CLR_0_INIT_SHIFT 0 -+#define EUR_CR_OCP_IRQENABLE_CLR_0_INIT_SIGNED 0 -+ -+/* Register EUR_CR_OCP_IRQENABLE_CLR_1 */ -+#define EUR_CR_OCP_IRQENABLE_CLR_1 0xFE4C -+#define EUR_CR_OCP_IRQENABLE_CLR_1_TARGET_MASK 0x00000001UL -+#define EUR_CR_OCP_IRQENABLE_CLR_1_TARGET_SHIFT 0 -+#define EUR_CR_OCP_IRQENABLE_CLR_1_TARGET_SIGNED 0 -+ -+/* Register EUR_CR_OCP_IRQENABLE_CLR_2 */ -+#define EUR_CR_OCP_IRQENABLE_CLR_2 0xFE50 -+#define EUR_CR_OCP_IRQENABLE_CLR_2_SGXCORE_MASK 0x00000001UL -+#define EUR_CR_OCP_IRQENABLE_CLR_2_SGXCORE_SHIFT 0 -+#define EUR_CR_OCP_IRQENABLE_CLR_2_SGXCORE_SIGNED 0 -+ -+/* Register EUR_CR_OCP_PAGE_CONFIG */ -+#define EUR_CR_OCP_PAGE_CONFIG 0xFF00 -+#define EUR_CR_OCP_PAGE_CONFIG_MEM_PAGE_SIZE_MASK 0x00000001UL -+#define EUR_CR_OCP_PAGE_CONFIG_MEM_PAGE_SIZE_SHIFT 0 -+#define EUR_CR_OCP_PAGE_CONFIG_MEM_PAGE_SIZE_SIGNED 0 -+ -+#define EUR_CR_OCP_PAGE_CONFIG_MEM_PAGE_CHECK_ENABLE_MASK 0x00000004UL -+#define EUR_CR_OCP_PAGE_CONFIG_MEM_PAGE_CHECK_ENABLE_SHIFT 2 -+#define EUR_CR_OCP_PAGE_CONFIG_MEM_PAGE_CHECK_ENABLE_SIGNED 0 -+ -+#define EUR_CR_OCP_PAGE_CONFIG_SIZE_MASK 0x00000018UL -+#define EUR_CR_OCP_PAGE_CONFIG_SIZE_SHIFT 3 -+#define EUR_CR_OCP_PAGE_CONFIG_SIZE_SIGNED 0 -+ -+/* Register EUR_CR_OCP_INTERRUPT_EVENT */ -+#define EUR_CR_OCP_INTERRUPT_EVENT 0xFF04 -+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_RESP_UNEXPECTED_MASK 0x00000001UL -+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_RESP_UNEXPECTED_SHIFT 0 -+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_RESP_UNEXPECTED_SIGNED 0 -+ -+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_RESP_UNUSED_TAG_MASK 0x00000002UL -+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_RESP_UNUSED_TAG_SHIFT 1 -+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_RESP_UNUSED_TAG_SIGNED 0 -+ -+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_RESP_ERROR_MASK 0x00000004UL -+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_RESP_ERROR_SHIFT 2 -+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_RESP_ERROR_SIGNED 0 -+ -+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_PAGE_CROSS_ERROR_MASK 0x00000008UL -+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_PAGE_CROSS_ERROR_SHIFT 3 -+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_PAGE_CROSS_ERROR_SIGNED 0 -+ -+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_READ_TAG_FIFO_OVR_MASK 0x00000010UL -+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_READ_TAG_FIFO_OVR_SHIFT 4 -+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_READ_TAG_FIFO_OVR_SIGNED 0 -+ -+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_MEM_REQ_FIFO_OVR_MASK 0x00000020UL -+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_MEM_REQ_FIFO_OVR_SHIFT 5 -+#define EUR_CR_OCP_INTERRUPT_EVENT_INIT_MEM_REQ_FIFO_OVR_SIGNED 0 -+ -+#define EUR_CR_OCP_INTERRUPT_EVENT_TARGET_RESP_FIFO_FULL_MASK 0x00000100UL -+#define EUR_CR_OCP_INTERRUPT_EVENT_TARGET_RESP_FIFO_FULL_SHIFT 8 -+#define EUR_CR_OCP_INTERRUPT_EVENT_TARGET_RESP_FIFO_FULL_SIGNED 0 -+ -+#define EUR_CR_OCP_INTERRUPT_EVENT_TARGET_CMD_FIFO_FULL_MASK 0x00000200UL -+#define EUR_CR_OCP_INTERRUPT_EVENT_TARGET_CMD_FIFO_FULL_SHIFT 9 -+#define EUR_CR_OCP_INTERRUPT_EVENT_TARGET_CMD_FIFO_FULL_SIGNED 0 -+ -+#define EUR_CR_OCP_INTERRUPT_EVENT_TARGET_INVALID_OCP_CMD_MASK 0x00000400UL -+#define EUR_CR_OCP_INTERRUPT_EVENT_TARGET_INVALID_OCP_CMD_SHIFT 10 -+#define EUR_CR_OCP_INTERRUPT_EVENT_TARGET_INVALID_OCP_CMD_SIGNED 0 -+ -+/* Register EUR_CR_OCP_DEBUG_CONFIG */ -+#define EUR_CR_OCP_DEBUG_CONFIG 0xFF08 -+#define EUR_CR_OCP_DEBUG_CONFIG_FORCE_TARGET_IDLE_MASK 0x00000003UL -+#define EUR_CR_OCP_DEBUG_CONFIG_FORCE_TARGET_IDLE_SHIFT 0 -+#define EUR_CR_OCP_DEBUG_CONFIG_FORCE_TARGET_IDLE_SIGNED 0 -+ -+#define EUR_CR_OCP_DEBUG_CONFIG_FORCE_INIT_IDLE_MASK 0x0000000CUL -+#define EUR_CR_OCP_DEBUG_CONFIG_FORCE_INIT_IDLE_SHIFT 2 -+#define EUR_CR_OCP_DEBUG_CONFIG_FORCE_INIT_IDLE_SIGNED 0 -+ -+#define EUR_CR_OCP_DEBUG_CONFIG_FORCE_PASS_DATA_MASK 0x00000010UL -+#define EUR_CR_OCP_DEBUG_CONFIG_FORCE_PASS_DATA_SHIFT 4 -+#define EUR_CR_OCP_DEBUG_CONFIG_FORCE_PASS_DATA_SIGNED 0 -+ -+#define EUR_CR_OCP_DEBUG_CONFIG_SELECT_INIT_IDLE_MASK 0x00000020UL -+#define EUR_CR_OCP_DEBUG_CONFIG_SELECT_INIT_IDLE_SHIFT 5 -+#define EUR_CR_OCP_DEBUG_CONFIG_SELECT_INIT_IDLE_SIGNED 0 -+ -+#define EUR_CR_OCP_DEBUG_CONFIG_THALIA_INT_BYPASS_MASK 0x80000000UL -+#define EUR_CR_OCP_DEBUG_CONFIG_THALIA_INT_BYPASS_SHIFT 31 -+#define EUR_CR_OCP_DEBUG_CONFIG_THALIA_INT_BYPASS_SIGNED 0 -+ -+/* Register EUR_CR_OCP_DEBUG_STATUS */ -+#define EUR_CR_OCP_DEBUG_STATUS 0xFF0C -+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_MCONNECT_MASK 0x00000003UL -+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_MCONNECT_SHIFT 0 -+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_MCONNECT_SIGNED 0 -+ -+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SCONNECT_MASK 0x00000004UL -+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SCONNECT_SHIFT 2 -+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SCONNECT_SIGNED 0 -+ -+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SIDLEREQ_MASK 0x00000008UL -+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SIDLEREQ_SHIFT 3 -+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SIDLEREQ_SIGNED 0 -+ -+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SDISCACK_MASK 0x00000030UL -+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SDISCACK_SHIFT 4 -+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SDISCACK_SIGNED 0 -+ -+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SIDLEACK_MASK 0x000000C0UL -+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SIDLEACK_SHIFT 6 -+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_SIDLEACK_SIGNED 0 -+ -+#define EUR_CR_OCP_DEBUG_STATUS_INIT_MCONNECT0_MASK 0x00000300UL -+#define EUR_CR_OCP_DEBUG_STATUS_INIT_MCONNECT0_SHIFT 8 -+#define EUR_CR_OCP_DEBUG_STATUS_INIT_MCONNECT0_SIGNED 0 -+ -+#define EUR_CR_OCP_DEBUG_STATUS_INIT_SCONNECT0_MASK 0x00000400UL -+#define EUR_CR_OCP_DEBUG_STATUS_INIT_SCONNECT0_SHIFT 10 -+#define EUR_CR_OCP_DEBUG_STATUS_INIT_SCONNECT0_SIGNED 0 -+ -+#define EUR_CR_OCP_DEBUG_STATUS_INIT_SCONNECT1_MASK 0x00000800UL -+#define EUR_CR_OCP_DEBUG_STATUS_INIT_SCONNECT1_SHIFT 11 -+#define EUR_CR_OCP_DEBUG_STATUS_INIT_SCONNECT1_SIGNED 0 -+ -+#define EUR_CR_OCP_DEBUG_STATUS_INIT_SCONNECT2_MASK 0x00001000UL -+#define EUR_CR_OCP_DEBUG_STATUS_INIT_SCONNECT2_SHIFT 12 -+#define EUR_CR_OCP_DEBUG_STATUS_INIT_SCONNECT2_SIGNED 0 -+ -+#define EUR_CR_OCP_DEBUG_STATUS_INIT_MDISCACK_MASK 0x00006000UL -+#define EUR_CR_OCP_DEBUG_STATUS_INIT_MDISCACK_SHIFT 13 -+#define EUR_CR_OCP_DEBUG_STATUS_INIT_MDISCACK_SIGNED 0 -+ -+#define EUR_CR_OCP_DEBUG_STATUS_INIT_MDISCREQ_MASK 0x00008000UL -+#define EUR_CR_OCP_DEBUG_STATUS_INIT_MDISCREQ_SHIFT 15 -+#define EUR_CR_OCP_DEBUG_STATUS_INIT_MDISCREQ_SIGNED 0 -+ -+#define EUR_CR_OCP_DEBUG_STATUS_INIT_MWAIT_MASK 0x00010000UL -+#define EUR_CR_OCP_DEBUG_STATUS_INIT_MWAIT_SHIFT 16 -+#define EUR_CR_OCP_DEBUG_STATUS_INIT_MWAIT_SIGNED 0 -+ -+#define EUR_CR_OCP_DEBUG_STATUS_INIT_MSTANDBY_MASK 0x00020000UL -+#define EUR_CR_OCP_DEBUG_STATUS_INIT_MSTANDBY_SHIFT 17 -+#define EUR_CR_OCP_DEBUG_STATUS_INIT_MSTANDBY_SIGNED 0 -+ -+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_CMD_OUT_MASK 0x001C0000UL -+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_CMD_OUT_SHIFT 18 -+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_CMD_OUT_SIGNED 0 -+ -+#define EUR_CR_OCP_DEBUG_STATUS_WHICH_TARGET_REGISTER_MASK 0x03E00000UL -+#define EUR_CR_OCP_DEBUG_STATUS_WHICH_TARGET_REGISTER_SHIFT 21 -+#define EUR_CR_OCP_DEBUG_STATUS_WHICH_TARGET_REGISTER_SIGNED 0 -+ -+#define EUR_CR_OCP_DEBUG_STATUS_RESP_ERROR_MASK 0x04000000UL -+#define EUR_CR_OCP_DEBUG_STATUS_RESP_ERROR_SHIFT 26 -+#define EUR_CR_OCP_DEBUG_STATUS_RESP_ERROR_SIGNED 0 -+ -+#define EUR_CR_OCP_DEBUG_STATUS_CMD_FIFO_FULL_MASK 0x08000000UL -+#define EUR_CR_OCP_DEBUG_STATUS_CMD_FIFO_FULL_SHIFT 27 -+#define EUR_CR_OCP_DEBUG_STATUS_CMD_FIFO_FULL_SIGNED 0 -+ -+#define EUR_CR_OCP_DEBUG_STATUS_RESP_FIFO_FULL_MASK 0x10000000UL -+#define EUR_CR_OCP_DEBUG_STATUS_RESP_FIFO_FULL_SHIFT 28 -+#define EUR_CR_OCP_DEBUG_STATUS_RESP_FIFO_FULL_SIGNED 0 -+ -+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_IDLE_MASK 0x20000000UL -+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_IDLE_SHIFT 29 -+#define EUR_CR_OCP_DEBUG_STATUS_TARGET_IDLE_SIGNED 0 -+ -+#define EUR_CR_OCP_DEBUG_STATUS_CMD_RESP_DEBUG_STATE_MASK 0x40000000UL -+#define EUR_CR_OCP_DEBUG_STATUS_CMD_RESP_DEBUG_STATE_SHIFT 30 -+#define EUR_CR_OCP_DEBUG_STATUS_CMD_RESP_DEBUG_STATE_SIGNED 0 -+ -+#define EUR_CR_OCP_DEBUG_STATUS_CMD_DEBUG_STATE_MASK 0x80000000UL -+#define EUR_CR_OCP_DEBUG_STATUS_CMD_DEBUG_STATE_SHIFT 31 -+#define EUR_CR_OCP_DEBUG_STATUS_CMD_DEBUG_STATE_SIGNED 0 -+ -+ -+#endif /* _OCPDEFS_H_ */ -+ -+/***************************************************************************** -+ End of file (ocpdefs.h) -+*****************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/hwdefs/sgx530defs.h b/drivers/staging/ti-es8-sgx/services4/srvkm/hwdefs/sgx530defs.h -new file mode 100644 -index 0000000..0962123 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/hwdefs/sgx530defs.h -@@ -0,0 +1,541 @@ -+/*************************************************************************/ /*! -+@Title Hardware defs for SGX530. -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#ifndef _SGX530DEFS_KM_H_ -+#define _SGX530DEFS_KM_H_ -+ -+/* Register EUR_CR_CLKGATECTL */ -+#define EUR_CR_CLKGATECTL 0x0000 -+#define EUR_CR_CLKGATECTL_2D_CLKG_MASK 0x00000003U -+#define EUR_CR_CLKGATECTL_2D_CLKG_SHIFT 0 -+#define EUR_CR_CLKGATECTL_ISP_CLKG_MASK 0x00000030U -+#define EUR_CR_CLKGATECTL_ISP_CLKG_SHIFT 4 -+#define EUR_CR_CLKGATECTL_TSP_CLKG_MASK 0x00000300U -+#define EUR_CR_CLKGATECTL_TSP_CLKG_SHIFT 8 -+#define EUR_CR_CLKGATECTL_TA_CLKG_MASK 0x00003000U -+#define EUR_CR_CLKGATECTL_TA_CLKG_SHIFT 12 -+#define EUR_CR_CLKGATECTL_DPM_CLKG_MASK 0x00030000U -+#define EUR_CR_CLKGATECTL_DPM_CLKG_SHIFT 16 -+#define EUR_CR_CLKGATECTL_USE_CLKG_MASK 0x00300000U -+#define EUR_CR_CLKGATECTL_USE_CLKG_SHIFT 20 -+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_MASK 0x01000000U -+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_SHIFT 24 -+/* Register EUR_CR_CLKGATESTATUS */ -+#define EUR_CR_CLKGATESTATUS 0x0004 -+#define EUR_CR_CLKGATESTATUS_2D_CLKS_MASK 0x00000001U -+#define EUR_CR_CLKGATESTATUS_2D_CLKS_SHIFT 0 -+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_MASK 0x00000010U -+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_SHIFT 4 -+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_MASK 0x00000100U -+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_SHIFT 8 -+#define EUR_CR_CLKGATESTATUS_TA_CLKS_MASK 0x00001000U -+#define EUR_CR_CLKGATESTATUS_TA_CLKS_SHIFT 12 -+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_MASK 0x00010000U -+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_SHIFT 16 -+#define EUR_CR_CLKGATESTATUS_USE_CLKS_MASK 0x00100000U -+#define EUR_CR_CLKGATESTATUS_USE_CLKS_SHIFT 20 -+/* Register EUR_CR_CLKGATECTLOVR */ -+#define EUR_CR_CLKGATECTLOVR 0x0008 -+#define EUR_CR_CLKGATECTLOVR_2D_CLKO_MASK 0x00000003U -+#define EUR_CR_CLKGATECTLOVR_2D_CLKO_SHIFT 0 -+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_MASK 0x00000030U -+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_SHIFT 4 -+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_MASK 0x00000300U -+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_SHIFT 8 -+#define EUR_CR_CLKGATECTLOVR_TA_CLKO_MASK 0x00003000U -+#define EUR_CR_CLKGATECTLOVR_TA_CLKO_SHIFT 12 -+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_MASK 0x00030000U -+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_SHIFT 16 -+#define EUR_CR_CLKGATECTLOVR_USE_CLKO_MASK 0x00300000U -+#define EUR_CR_CLKGATECTLOVR_USE_CLKO_SHIFT 20 -+/* Register EUR_CR_CORE_ID */ -+#define EUR_CR_CORE_ID 0x0010 -+#define EUR_CR_CORE_ID_CONFIG_MASK 0x0000FFFFU -+#define EUR_CR_CORE_ID_CONFIG_SHIFT 0 -+#define EUR_CR_CORE_ID_ID_MASK 0xFFFF0000U -+#define EUR_CR_CORE_ID_ID_SHIFT 16 -+/* Register EUR_CR_CORE_REVISION */ -+#define EUR_CR_CORE_REVISION 0x0014 -+#define EUR_CR_CORE_REVISION_MAINTENANCE_MASK 0x000000FFU -+#define EUR_CR_CORE_REVISION_MAINTENANCE_SHIFT 0 -+#define EUR_CR_CORE_REVISION_MINOR_MASK 0x0000FF00U -+#define EUR_CR_CORE_REVISION_MINOR_SHIFT 8 -+#define EUR_CR_CORE_REVISION_MAJOR_MASK 0x00FF0000U -+#define EUR_CR_CORE_REVISION_MAJOR_SHIFT 16 -+#define EUR_CR_CORE_REVISION_DESIGNER_MASK 0xFF000000U -+#define EUR_CR_CORE_REVISION_DESIGNER_SHIFT 24 -+/* Register EUR_CR_DESIGNER_REV_FIELD1 */ -+#define EUR_CR_DESIGNER_REV_FIELD1 0x0018 -+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_MASK 0xFFFFFFFFU -+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_SHIFT 0 -+/* Register EUR_CR_DESIGNER_REV_FIELD2 */ -+#define EUR_CR_DESIGNER_REV_FIELD2 0x001C -+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_MASK 0xFFFFFFFFU -+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_SHIFT 0 -+/* Register EUR_CR_SOFT_RESET */ -+#define EUR_CR_SOFT_RESET 0x0080 -+#define EUR_CR_SOFT_RESET_BIF_RESET_MASK 0x00000001U -+#define EUR_CR_SOFT_RESET_BIF_RESET_SHIFT 0 -+#define EUR_CR_SOFT_RESET_TWOD_RESET_MASK 0x00000002U -+#define EUR_CR_SOFT_RESET_TWOD_RESET_SHIFT 1 -+#define EUR_CR_SOFT_RESET_DPM_RESET_MASK 0x00000004U -+#define EUR_CR_SOFT_RESET_DPM_RESET_SHIFT 2 -+#define EUR_CR_SOFT_RESET_TA_RESET_MASK 0x00000008U -+#define EUR_CR_SOFT_RESET_TA_RESET_SHIFT 3 -+#define EUR_CR_SOFT_RESET_USE_RESET_MASK 0x00000010U -+#define EUR_CR_SOFT_RESET_USE_RESET_SHIFT 4 -+#define EUR_CR_SOFT_RESET_ISP_RESET_MASK 0x00000020U -+#define EUR_CR_SOFT_RESET_ISP_RESET_SHIFT 5 -+#define EUR_CR_SOFT_RESET_TSP_RESET_MASK 0x00000040U -+#define EUR_CR_SOFT_RESET_TSP_RESET_SHIFT 6 -+/* Register EUR_CR_EVENT_HOST_ENABLE2 */ -+#define EUR_CR_EVENT_HOST_ENABLE2 0x0110 -+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_MASK 0x00000010U -+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_SHIFT 4 -+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_MASK 0x00000008U -+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_SHIFT 3 -+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_MASK 0x00000004U -+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_SHIFT 2 -+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_MASK 0x00000002U -+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_SHIFT 1 -+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_MASK 0x00000001U -+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_SHIFT 0 -+/* Register EUR_CR_EVENT_HOST_CLEAR2 */ -+#define EUR_CR_EVENT_HOST_CLEAR2 0x0114 -+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_MASK 0x00000010U -+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_SHIFT 4 -+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_MASK 0x00000008U -+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_SHIFT 3 -+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_MASK 0x00000004U -+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_SHIFT 2 -+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_MASK 0x00000002U -+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_SHIFT 1 -+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_MASK 0x00000001U -+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_SHIFT 0 -+/* Register EUR_CR_EVENT_STATUS2 */ -+#define EUR_CR_EVENT_STATUS2 0x0118 -+#define EUR_CR_EVENT_STATUS2_TRIG_TA_MASK 0x00000010U -+#define EUR_CR_EVENT_STATUS2_TRIG_TA_SHIFT 4 -+#define EUR_CR_EVENT_STATUS2_TRIG_3D_MASK 0x00000008U -+#define EUR_CR_EVENT_STATUS2_TRIG_3D_SHIFT 3 -+#define EUR_CR_EVENT_STATUS2_TRIG_DL_MASK 0x00000004U -+#define EUR_CR_EVENT_STATUS2_TRIG_DL_SHIFT 2 -+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_MASK 0x00000002U -+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_SHIFT 1 -+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_MASK 0x00000001U -+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_SHIFT 0 -+/* Register EUR_CR_EVENT_STATUS */ -+#define EUR_CR_EVENT_STATUS 0x012CU -+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_MASK 0x80000000U -+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_SHIFT 31 -+#define EUR_CR_EVENT_STATUS_TIMER_MASK 0x20000000U -+#define EUR_CR_EVENT_STATUS_TIMER_SHIFT 29 -+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_MASK 0x10000000U -+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_SHIFT 28 -+#define EUR_CR_EVENT_STATUS_TWOD_COMPLETE_MASK 0x08000000U -+#define EUR_CR_EVENT_STATUS_TWOD_COMPLETE_SHIFT 27 -+#define EUR_CR_EVENT_STATUS_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U -+#define EUR_CR_EVENT_STATUS_MADD_CACHE_INVALCOMPLETE_SHIFT 26 -+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U -+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25 -+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_MASK 0x01000000U -+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_SHIFT 24 -+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_MASK 0x00800000U -+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_SHIFT 23 -+#define EUR_CR_EVENT_STATUS_DPM_INITEND_MASK 0x00400000U -+#define EUR_CR_EVENT_STATUS_DPM_INITEND_SHIFT 22 -+#define EUR_CR_EVENT_STATUS_OTPM_LOADED_MASK 0x00200000U -+#define EUR_CR_EVENT_STATUS_OTPM_LOADED_SHIFT 21 -+#define EUR_CR_EVENT_STATUS_OTPM_INV_MASK 0x00100000U -+#define EUR_CR_EVENT_STATUS_OTPM_INV_SHIFT 20 -+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_MASK 0x00080000U -+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_SHIFT 19 -+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_MASK 0x00040000U -+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_SHIFT 18 -+#define EUR_CR_EVENT_STATUS_ISP_HALT_MASK 0x00020000U -+#define EUR_CR_EVENT_STATUS_ISP_HALT_SHIFT 17 -+#define EUR_CR_EVENT_STATUS_ISP_VISIBILITY_FAIL_MASK 0x00010000U -+#define EUR_CR_EVENT_STATUS_ISP_VISIBILITY_FAIL_SHIFT 16 -+#define EUR_CR_EVENT_STATUS_BREAKPOINT_MASK 0x00008000U -+#define EUR_CR_EVENT_STATUS_BREAKPOINT_SHIFT 15 -+#define EUR_CR_EVENT_STATUS_SW_EVENT_MASK 0x00004000U -+#define EUR_CR_EVENT_STATUS_SW_EVENT_SHIFT 14 -+#define EUR_CR_EVENT_STATUS_TA_FINISHED_MASK 0x00002000U -+#define EUR_CR_EVENT_STATUS_TA_FINISHED_SHIFT 13 -+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_MASK 0x00001000U -+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_SHIFT 12 -+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_MASK 0x00000800U -+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_SHIFT 11 -+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_MASK 0x00000400U -+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_SHIFT 10 -+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_MASK 0x00000200U -+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_SHIFT 9 -+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_MASK 0x00000100U -+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_SHIFT 8 -+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_MASK 0x00000080U -+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_SHIFT 7 -+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_MASK 0x00000040U -+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_SHIFT 6 -+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_MASK 0x00000020U -+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_SHIFT 5 -+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_MASK 0x00000010U -+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_SHIFT 4 -+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_MASK 0x00000008U -+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_SHIFT 3 -+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U -+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_SHIFT 2 -+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U -+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_SHIFT 1 -+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_MASK 0x00000001U -+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_SHIFT 0 -+/* Register EUR_CR_EVENT_HOST_ENABLE */ -+#define EUR_CR_EVENT_HOST_ENABLE 0x0130 -+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_MASK 0x80000000U -+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_SHIFT 31 -+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_MASK 0x20000000U -+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_SHIFT 29 -+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_MASK 0x10000000U -+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_SHIFT 28 -+#define EUR_CR_EVENT_HOST_ENABLE_TWOD_COMPLETE_MASK 0x08000000U -+#define EUR_CR_EVENT_HOST_ENABLE_TWOD_COMPLETE_SHIFT 27 -+#define EUR_CR_EVENT_HOST_ENABLE_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U -+#define EUR_CR_EVENT_HOST_ENABLE_MADD_CACHE_INVALCOMPLETE_SHIFT 26 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_MASK 0x01000000U -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_SHIFT 24 -+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_MASK 0x00800000U -+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_SHIFT 23 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_MASK 0x00400000U -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_SHIFT 22 -+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_MASK 0x00200000U -+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_SHIFT 21 -+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_MASK 0x00100000U -+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_SHIFT 20 -+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_MASK 0x00080000U -+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_SHIFT 19 -+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_MASK 0x00040000U -+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_SHIFT 18 -+#define EUR_CR_EVENT_HOST_ENABLE_ISP_HALT_MASK 0x00020000U -+#define EUR_CR_EVENT_HOST_ENABLE_ISP_HALT_SHIFT 17 -+#define EUR_CR_EVENT_HOST_ENABLE_ISP_VISIBILITY_FAIL_MASK 0x00010000U -+#define EUR_CR_EVENT_HOST_ENABLE_ISP_VISIBILITY_FAIL_SHIFT 16 -+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_MASK 0x00008000U -+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_SHIFT 15 -+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_MASK 0x00004000U -+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_SHIFT 14 -+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_MASK 0x00002000U -+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_SHIFT 13 -+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_MASK 0x00001000U -+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_SHIFT 12 -+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_MASK 0x00000800U -+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_SHIFT 11 -+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_MASK 0x00000400U -+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_SHIFT 10 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_MASK 0x00000200U -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_SHIFT 9 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_MASK 0x00000100U -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_SHIFT 8 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_MASK 0x00000080U -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_SHIFT 7 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_MASK 0x00000040U -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_SHIFT 6 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_MASK 0x00000020U -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_SHIFT 5 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_MASK 0x00000010U -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_SHIFT 4 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_MASK 0x00000008U -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_SHIFT 3 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_SHIFT 2 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_SHIFT 1 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_MASK 0x00000001U -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_SHIFT 0 -+/* Register EUR_CR_EVENT_HOST_CLEAR */ -+#define EUR_CR_EVENT_HOST_CLEAR 0x0134 -+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_MASK 0x80000000U -+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_SHIFT 31 -+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_MASK 0x20000000U -+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_SHIFT 29 -+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_MASK 0x10000000U -+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_SHIFT 28 -+#define EUR_CR_EVENT_HOST_CLEAR_TWOD_COMPLETE_MASK 0x08000000U -+#define EUR_CR_EVENT_HOST_CLEAR_TWOD_COMPLETE_SHIFT 27 -+#define EUR_CR_EVENT_HOST_CLEAR_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U -+#define EUR_CR_EVENT_HOST_CLEAR_MADD_CACHE_INVALCOMPLETE_SHIFT 26 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_MASK 0x01000000U -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_SHIFT 24 -+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_MASK 0x00800000U -+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_SHIFT 23 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_MASK 0x00400000U -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_SHIFT 22 -+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_MASK 0x00200000U -+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_SHIFT 21 -+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_MASK 0x00100000U -+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_SHIFT 20 -+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_MASK 0x00080000U -+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_SHIFT 19 -+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_MASK 0x00040000U -+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_SHIFT 18 -+#define EUR_CR_EVENT_HOST_CLEAR_ISP_HALT_MASK 0x00020000U -+#define EUR_CR_EVENT_HOST_CLEAR_ISP_HALT_SHIFT 17 -+#define EUR_CR_EVENT_HOST_CLEAR_ISP_VISIBILITY_FAIL_MASK 0x00010000U -+#define EUR_CR_EVENT_HOST_CLEAR_ISP_VISIBILITY_FAIL_SHIFT 16 -+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_MASK 0x00008000U -+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_SHIFT 15 -+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_MASK 0x00004000U -+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_SHIFT 14 -+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_MASK 0x00002000U -+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_SHIFT 13 -+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_MASK 0x00001000U -+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_SHIFT 12 -+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_MASK 0x00000800U -+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_SHIFT 11 -+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_MASK 0x00000400U -+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_SHIFT 10 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_MASK 0x00000200U -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_SHIFT 9 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_MASK 0x00000100U -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_SHIFT 8 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_MASK 0x00000080U -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_SHIFT 7 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_MASK 0x00000040U -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_SHIFT 6 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_MASK 0x00000020U -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_SHIFT 5 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_MASK 0x00000010U -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_SHIFT 4 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_MASK 0x00000008U -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_SHIFT 3 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_SHIFT 2 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_SHIFT 1 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_MASK 0x00000001U -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_SHIFT 0 -+/* Register EUR_CR_PDS_EXEC_BASE */ -+#define EUR_CR_PDS_EXEC_BASE 0x0AB8 -+#define EUR_CR_PDS_EXEC_BASE_ADDR_MASK 0x0FF00000U -+#define EUR_CR_PDS_EXEC_BASE_ADDR_SHIFT 20 -+/* Register EUR_CR_EVENT_KICKER */ -+#define EUR_CR_EVENT_KICKER 0x0AC4 -+#define EUR_CR_EVENT_KICKER_ADDRESS_MASK 0x0FFFFFF0U -+#define EUR_CR_EVENT_KICKER_ADDRESS_SHIFT 4 -+/* Register EUR_CR_EVENT_KICK */ -+#define EUR_CR_EVENT_KICK 0x0AC8 -+#define EUR_CR_EVENT_KICK_NOW_MASK 0x00000001U -+#define EUR_CR_EVENT_KICK_NOW_SHIFT 0 -+/* Register EUR_CR_EVENT_TIMER */ -+#define EUR_CR_EVENT_TIMER 0x0ACC -+#define EUR_CR_EVENT_TIMER_ENABLE_MASK 0x01000000U -+#define EUR_CR_EVENT_TIMER_ENABLE_SHIFT 24 -+#define EUR_CR_EVENT_TIMER_VALUE_MASK 0x00FFFFFFU -+#define EUR_CR_EVENT_TIMER_VALUE_SHIFT 0 -+/* Register EUR_CR_PDS_INV0 */ -+#define EUR_CR_PDS_INV0 0x0AD0 -+#define EUR_CR_PDS_INV0_DSC_MASK 0x00000001U -+#define EUR_CR_PDS_INV0_DSC_SHIFT 0 -+/* Register EUR_CR_PDS_INV1 */ -+#define EUR_CR_PDS_INV1 0x0AD4 -+#define EUR_CR_PDS_INV1_DSC_MASK 0x00000001U -+#define EUR_CR_PDS_INV1_DSC_SHIFT 0 -+/* Register EUR_CR_PDS_INV2 */ -+#define EUR_CR_PDS_INV2 0x0AD8 -+#define EUR_CR_PDS_INV2_DSC_MASK 0x00000001U -+#define EUR_CR_PDS_INV2_DSC_SHIFT 0 -+/* Register EUR_CR_PDS_INV3 */ -+#define EUR_CR_PDS_INV3 0x0ADC -+#define EUR_CR_PDS_INV3_DSC_MASK 0x00000001U -+#define EUR_CR_PDS_INV3_DSC_SHIFT 0 -+/* Register EUR_CR_PDS_INV_CSC */ -+#define EUR_CR_PDS_INV_CSC 0x0AE0 -+#define EUR_CR_PDS_INV_CSC_KICK_MASK 0x00000001U -+#define EUR_CR_PDS_INV_CSC_KICK_SHIFT 0 -+/* Register EUR_CR_PDS_PC_BASE */ -+#define EUR_CR_PDS_PC_BASE 0x0B2C -+#define EUR_CR_PDS_PC_BASE_ADDRESS_MASK 0x3FFFFFFFU -+#define EUR_CR_PDS_PC_BASE_ADDRESS_SHIFT 0 -+/* Register EUR_CR_BIF_CTRL */ -+#define EUR_CR_BIF_CTRL 0x0C00 -+#define EUR_CR_BIF_CTRL_NOREORDER_MASK 0x00000001U -+#define EUR_CR_BIF_CTRL_NOREORDER_SHIFT 0 -+#define EUR_CR_BIF_CTRL_PAUSE_MASK 0x00000002U -+#define EUR_CR_BIF_CTRL_PAUSE_SHIFT 1 -+#define EUR_CR_BIF_CTRL_FLUSH_MASK 0x00000004U -+#define EUR_CR_BIF_CTRL_FLUSH_SHIFT 2 -+#define EUR_CR_BIF_CTRL_INVALDC_MASK 0x00000008U -+#define EUR_CR_BIF_CTRL_INVALDC_SHIFT 3 -+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_MASK 0x00000010U -+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_SHIFT 4 -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_CACHE_MASK 0x00000100U -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_CACHE_SHIFT 8 -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_MASK 0x00000200U -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_SHIFT 9 -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TE_MASK 0x00000400U -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TE_SHIFT 10 -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TWOD_MASK 0x00000800U -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TWOD_SHIFT 11 -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_MASK 0x00001000U -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_SHIFT 12 -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_MASK 0x00002000U -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_SHIFT 13 -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_MASK 0x00004000U -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_SHIFT 14 -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_MASK 0x00008000U -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_SHIFT 15 -+/* Register EUR_CR_BIF_INT_STAT */ -+#define EUR_CR_BIF_INT_STAT 0x0C04 -+#define EUR_CR_BIF_INT_STAT_FAULT_MASK 0x00003FFFU -+#define EUR_CR_BIF_INT_STAT_FAULT_SHIFT 0 -+#define EUR_CR_BIF_INT_STAT_PF_N_RW_MASK 0x00004000U -+#define EUR_CR_BIF_INT_STAT_PF_N_RW_SHIFT 14 -+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_MASK 0x00008000U -+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_SHIFT 15 -+/* Register EUR_CR_BIF_FAULT */ -+#define EUR_CR_BIF_FAULT 0x0C08 -+#define EUR_CR_BIF_FAULT_ADDR_MASK 0x0FFFF000U -+#define EUR_CR_BIF_FAULT_ADDR_SHIFT 12 -+/* Register EUR_CR_BIF_DIR_LIST_BASE0 */ -+#define EUR_CR_BIF_DIR_LIST_BASE0 0x0C84 -+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_MASK 0xFFFFF000U -+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_SHIFT 12 -+/* Register EUR_CR_BIF_TWOD_REQ_BASE */ -+#define EUR_CR_BIF_TWOD_REQ_BASE 0x0C88 -+#define EUR_CR_BIF_TWOD_REQ_BASE_ADDR_MASK 0x0FF00000U -+#define EUR_CR_BIF_TWOD_REQ_BASE_ADDR_SHIFT 20 -+/* Register EUR_CR_BIF_TA_REQ_BASE */ -+#define EUR_CR_BIF_TA_REQ_BASE 0x0C90 -+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_MASK 0x0FF00000U -+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_SHIFT 20 -+/* Register EUR_CR_BIF_MEM_REQ_STAT */ -+#define EUR_CR_BIF_MEM_REQ_STAT 0x0CA8 -+#define EUR_CR_BIF_MEM_REQ_STAT_READS_MASK 0x000000FFU -+#define EUR_CR_BIF_MEM_REQ_STAT_READS_SHIFT 0 -+/* Register EUR_CR_BIF_3D_REQ_BASE */ -+#define EUR_CR_BIF_3D_REQ_BASE 0x0CAC -+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_MASK 0x0FF00000U -+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_SHIFT 20 -+/* Register EUR_CR_BIF_ZLS_REQ_BASE */ -+#define EUR_CR_BIF_ZLS_REQ_BASE 0x0CB0 -+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_MASK 0x0FF00000U -+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_SHIFT 20 -+/* Register EUR_CR_2D_BLIT_STATUS */ -+#define EUR_CR_2D_BLIT_STATUS 0x0E04 -+#define EUR_CR_2D_BLIT_STATUS_COMPLETE_MASK 0x00FFFFFFU -+#define EUR_CR_2D_BLIT_STATUS_COMPLETE_SHIFT 0 -+#define EUR_CR_2D_BLIT_STATUS_BUSY_MASK 0x01000000U -+#define EUR_CR_2D_BLIT_STATUS_BUSY_SHIFT 24 -+/* Register EUR_CR_2D_VIRTUAL_FIFO_0 */ -+#define EUR_CR_2D_VIRTUAL_FIFO_0 0x0E10 -+#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_MASK 0x00000001U -+#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_SHIFT 0 -+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MASK 0x0000000EU -+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_SHIFT 1 -+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_MASK 0x00000FF0U -+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_SHIFT 4 -+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_MASK 0x0000F000U -+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_SHIFT 12 -+/* Register EUR_CR_2D_VIRTUAL_FIFO_1 */ -+#define EUR_CR_2D_VIRTUAL_FIFO_1 0x0E14 -+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_MASK 0x00000FFFU -+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_SHIFT 0 -+#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_MASK 0x00FFF000U -+#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_SHIFT 12 -+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_MASK 0xFF000000U -+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_SHIFT 24 -+/* Table EUR_CR_USE_CODE_BASE */ -+/* Register EUR_CR_USE_CODE_BASE */ -+#define EUR_CR_USE_CODE_BASE(X) (0x0A0C + (4 * (X))) -+#define EUR_CR_USE_CODE_BASE_ADDR_MASK 0x00FFFFFFU -+#define EUR_CR_USE_CODE_BASE_ADDR_SHIFT 0 -+#define EUR_CR_USE_CODE_BASE_DM_MASK 0x03000000U -+#define EUR_CR_USE_CODE_BASE_DM_SHIFT 24 -+/* Number of entries in table EUR_CR_USE_CODE_BASE */ -+#define EUR_CR_USE_CODE_BASE_SIZE_UINT32 16 -+#define EUR_CR_USE_CODE_BASE_NUM_ENTRIES 16 -+#define EUR_CR_MNE_CR_CTRL 0x0D00 -+#define EUR_CR_MNE_CR_CTRL_BYP_CC_N_MASK 0x00010000U -+#define EUR_CR_MNE_CR_CTRL_BYP_CC_N_SHIFT 16 -+#define EUR_CR_MNE_CR_CTRL_BYP_CC_MASK 0x00008000U -+#define EUR_CR_MNE_CR_CTRL_BYP_CC_SHIFT 15 -+#define EUR_CR_MNE_CR_CTRL_USE_INVAL_ADDR_MASK 0x00007800U -+#define EUR_CR_MNE_CR_CTRL_USE_INVAL_ADDR_SHIFT 11 -+#define EUR_CR_MNE_CR_CTRL_BYPASS_ALL_MASK 0x00000400U -+#define EUR_CR_MNE_CR_CTRL_BYPASS_ALL_SHIFT 10 -+#define EUR_CR_MNE_CR_CTRL_BYPASS_MASK 0x000003E0U -+#define EUR_CR_MNE_CR_CTRL_BYPASS_SHIFT 5 -+#define EUR_CR_MNE_CR_CTRL_PAUSE_MASK 0x00000010U -+#define EUR_CR_MNE_CR_CTRL_PAUSE_SHIFT 4 -+#define EUR_CR_MNE_CR_CTRL_INVAL_PREQ_MASK 0x0000000EU -+#define EUR_CR_MNE_CR_CTRL_INVAL_PREQ_SHIFT 1 -+#define EUR_CR_MNE_CR_CTRL_INVAL_PREQ_PDS_MASK (1UL<<EUR_CR_MNE_CR_CTRL_INVAL_PREQ_SHIFT+2) -+#define EUR_CR_MNE_CR_CTRL_INVAL_PREQ_USEC_MASK (1UL<<EUR_CR_MNE_CR_CTRL_INVAL_PREQ_SHIFT+1) -+#define EUR_CR_MNE_CR_CTRL_INVAL_PREQ_CACHE_MASK (1UL<<EUR_CR_MNE_CR_CTRL_INVAL_PREQ_SHIFT) -+#define EUR_CR_MNE_CR_CTRL_INVAL_ALL_MASK 0x00000001U -+#define EUR_CR_MNE_CR_CTRL_INVAL_ALL_SHIFT 0 -+#define EUR_CR_MNE_CR_USE_INVAL 0x0D04 -+#define EUR_CR_MNE_CR_USE_INVAL_ADDR_MASK 0xFFFFFFFFU -+#define EUR_CR_MNE_CR_USE_INVAL_ADDR_SHIFT 0 -+#define EUR_CR_MNE_CR_STAT 0x0D08 -+#define EUR_CR_MNE_CR_STAT_PAUSED_MASK 0x00000400U -+#define EUR_CR_MNE_CR_STAT_PAUSED_SHIFT 10 -+#define EUR_CR_MNE_CR_STAT_READS_MASK 0x000003FFU -+#define EUR_CR_MNE_CR_STAT_READS_SHIFT 0 -+#define EUR_CR_MNE_CR_STAT_STATS 0x0D0C -+#define EUR_CR_MNE_CR_STAT_STATS_RST_MASK 0x000FFFF0U -+#define EUR_CR_MNE_CR_STAT_STATS_RST_SHIFT 4 -+#define EUR_CR_MNE_CR_STAT_STATS_SEL_MASK 0x0000000FU -+#define EUR_CR_MNE_CR_STAT_STATS_SEL_SHIFT 0 -+#define EUR_CR_MNE_CR_STAT_STATS_OUT 0x0D10 -+#define EUR_CR_MNE_CR_STAT_STATS_OUT_VALUE_MASK 0xFFFFFFFFU -+#define EUR_CR_MNE_CR_STAT_STATS_OUT_VALUE_SHIFT 0 -+#define EUR_CR_MNE_CR_EVENT_STATUS 0x0D14 -+#define EUR_CR_MNE_CR_EVENT_STATUS_INVAL_MASK 0x00000001U -+#define EUR_CR_MNE_CR_EVENT_STATUS_INVAL_SHIFT 0 -+#define EUR_CR_MNE_CR_EVENT_CLEAR 0x0D18 -+#define EUR_CR_MNE_CR_EVENT_CLEAR_INVAL_MASK 0x00000001U -+#define EUR_CR_MNE_CR_EVENT_CLEAR_INVAL_SHIFT 0 -+#define EUR_CR_MNE_CR_CTRL_INVAL 0x0D20 -+ -+#endif /* _SGX530DEFS_KM_H_ */ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/hwdefs/sgx540defs.h b/drivers/staging/ti-es8-sgx/services4/srvkm/hwdefs/sgx540defs.h -new file mode 100644 -index 0000000..65ef17e ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/hwdefs/sgx540defs.h -@@ -0,0 +1,604 @@ -+/*************************************************************************/ /*! -+@Title Hardware defs for SGX540. -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#ifndef _SGX540DEFS_KM_H_ -+#define _SGX540DEFS_KM_H_ -+ -+/* Register EUR_CR_CLKGATECTL */ -+#define EUR_CR_CLKGATECTL 0x0000 -+#define EUR_CR_CLKGATECTL_ISP_CLKG_MASK 0x00000003U -+#define EUR_CR_CLKGATECTL_ISP_CLKG_SHIFT 0 -+#define EUR_CR_CLKGATECTL_ISP2_CLKG_MASK 0x0000000CU -+#define EUR_CR_CLKGATECTL_ISP2_CLKG_SHIFT 2 -+#define EUR_CR_CLKGATECTL_TSP_CLKG_MASK 0x00000030U -+#define EUR_CR_CLKGATECTL_TSP_CLKG_SHIFT 4 -+#define EUR_CR_CLKGATECTL_TE_CLKG_MASK 0x000000C0U -+#define EUR_CR_CLKGATECTL_TE_CLKG_SHIFT 6 -+#define EUR_CR_CLKGATECTL_MTE_CLKG_MASK 0x00000300U -+#define EUR_CR_CLKGATECTL_MTE_CLKG_SHIFT 8 -+#define EUR_CR_CLKGATECTL_DPM_CLKG_MASK 0x00000C00U -+#define EUR_CR_CLKGATECTL_DPM_CLKG_SHIFT 10 -+#define EUR_CR_CLKGATECTL_VDM_CLKG_MASK 0x00003000U -+#define EUR_CR_CLKGATECTL_VDM_CLKG_SHIFT 12 -+#define EUR_CR_CLKGATECTL_PDS_CLKG_MASK 0x0000C000U -+#define EUR_CR_CLKGATECTL_PDS_CLKG_SHIFT 14 -+#define EUR_CR_CLKGATECTL_IDXFIFO_CLKG_MASK 0x00030000U -+#define EUR_CR_CLKGATECTL_IDXFIFO_CLKG_SHIFT 16 -+#define EUR_CR_CLKGATECTL_TA_CLKG_MASK 0x000C0000U -+#define EUR_CR_CLKGATECTL_TA_CLKG_SHIFT 18 -+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_MASK 0x01000000U -+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_SHIFT 24 -+#define EUR_CR_CLKGATECTL_SYSTEM_CLKG_MASK 0x10000000U -+#define EUR_CR_CLKGATECTL_SYSTEM_CLKG_SHIFT 28 -+/* Register EUR_CR_CLKGATECTL2 */ -+#define EUR_CR_CLKGATECTL2 0x0004 -+#define EUR_CR_CLKGATECTL2_PBE_CLKG_MASK 0x00000003U -+#define EUR_CR_CLKGATECTL2_PBE_CLKG_SHIFT 0 -+#define EUR_CR_CLKGATECTL2_CACHEL2_CLKG_MASK 0x0000000CU -+#define EUR_CR_CLKGATECTL2_CACHEL2_CLKG_SHIFT 2 -+#define EUR_CR_CLKGATECTL2_UCACHEL2_CLKG_MASK 0x00000030U -+#define EUR_CR_CLKGATECTL2_UCACHEL2_CLKG_SHIFT 4 -+#define EUR_CR_CLKGATECTL2_USE0_CLKG_MASK 0x000000C0U -+#define EUR_CR_CLKGATECTL2_USE0_CLKG_SHIFT 6 -+#define EUR_CR_CLKGATECTL2_ITR0_CLKG_MASK 0x00000300U -+#define EUR_CR_CLKGATECTL2_ITR0_CLKG_SHIFT 8 -+#define EUR_CR_CLKGATECTL2_TEX0_CLKG_MASK 0x00000C00U -+#define EUR_CR_CLKGATECTL2_TEX0_CLKG_SHIFT 10 -+#define EUR_CR_CLKGATECTL2_MADD0_CLKG_MASK 0x00003000U -+#define EUR_CR_CLKGATECTL2_MADD0_CLKG_SHIFT 12 -+#define EUR_CR_CLKGATECTL2_USE1_CLKG_MASK 0x0000C000U -+#define EUR_CR_CLKGATECTL2_USE1_CLKG_SHIFT 14 -+#define EUR_CR_CLKGATECTL2_ITR1_CLKG_MASK 0x00030000U -+#define EUR_CR_CLKGATECTL2_ITR1_CLKG_SHIFT 16 -+#define EUR_CR_CLKGATECTL2_TEX1_CLKG_MASK 0x000C0000U -+#define EUR_CR_CLKGATECTL2_TEX1_CLKG_SHIFT 18 -+#define EUR_CR_CLKGATECTL2_MADD1_CLKG_MASK 0x00300000U -+#define EUR_CR_CLKGATECTL2_MADD1_CLKG_SHIFT 20 -+/* Register EUR_CR_CLKGATESTATUS */ -+#define EUR_CR_CLKGATESTATUS 0x0008 -+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_MASK 0x00000001U -+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_SHIFT 0 -+#define EUR_CR_CLKGATESTATUS_ISP2_CLKS_MASK 0x00000002U -+#define EUR_CR_CLKGATESTATUS_ISP2_CLKS_SHIFT 1 -+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_MASK 0x00000004U -+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_SHIFT 2 -+#define EUR_CR_CLKGATESTATUS_TE_CLKS_MASK 0x00000008U -+#define EUR_CR_CLKGATESTATUS_TE_CLKS_SHIFT 3 -+#define EUR_CR_CLKGATESTATUS_MTE_CLKS_MASK 0x00000010U -+#define EUR_CR_CLKGATESTATUS_MTE_CLKS_SHIFT 4 -+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_MASK 0x00000020U -+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_SHIFT 5 -+#define EUR_CR_CLKGATESTATUS_VDM_CLKS_MASK 0x00000040U -+#define EUR_CR_CLKGATESTATUS_VDM_CLKS_SHIFT 6 -+#define EUR_CR_CLKGATESTATUS_PDS_CLKS_MASK 0x00000080U -+#define EUR_CR_CLKGATESTATUS_PDS_CLKS_SHIFT 7 -+#define EUR_CR_CLKGATESTATUS_PBE_CLKS_MASK 0x00000100U -+#define EUR_CR_CLKGATESTATUS_PBE_CLKS_SHIFT 8 -+#define EUR_CR_CLKGATESTATUS_CACHEL2_CLKS_MASK 0x00000200U -+#define EUR_CR_CLKGATESTATUS_CACHEL2_CLKS_SHIFT 9 -+#define EUR_CR_CLKGATESTATUS_UCACHEL2_CLKS_MASK 0x00000400U -+#define EUR_CR_CLKGATESTATUS_UCACHEL2_CLKS_SHIFT 10 -+#define EUR_CR_CLKGATESTATUS_USE0_CLKS_MASK 0x00000800U -+#define EUR_CR_CLKGATESTATUS_USE0_CLKS_SHIFT 11 -+#define EUR_CR_CLKGATESTATUS_ITR0_CLKS_MASK 0x00001000U -+#define EUR_CR_CLKGATESTATUS_ITR0_CLKS_SHIFT 12 -+#define EUR_CR_CLKGATESTATUS_TEX0_CLKS_MASK 0x00002000U -+#define EUR_CR_CLKGATESTATUS_TEX0_CLKS_SHIFT 13 -+#define EUR_CR_CLKGATESTATUS_MADD0_CLKS_MASK 0x00004000U -+#define EUR_CR_CLKGATESTATUS_MADD0_CLKS_SHIFT 14 -+#define EUR_CR_CLKGATESTATUS_USE1_CLKS_MASK 0x00008000U -+#define EUR_CR_CLKGATESTATUS_USE1_CLKS_SHIFT 15 -+#define EUR_CR_CLKGATESTATUS_ITR1_CLKS_MASK 0x00010000U -+#define EUR_CR_CLKGATESTATUS_ITR1_CLKS_SHIFT 16 -+#define EUR_CR_CLKGATESTATUS_TEX1_CLKS_MASK 0x00020000U -+#define EUR_CR_CLKGATESTATUS_TEX1_CLKS_SHIFT 17 -+#define EUR_CR_CLKGATESTATUS_MADD1_CLKS_MASK 0x00040000U -+#define EUR_CR_CLKGATESTATUS_MADD1_CLKS_SHIFT 18 -+#define EUR_CR_CLKGATESTATUS_IDXFIFO_CLKS_MASK 0x00080000U -+#define EUR_CR_CLKGATESTATUS_IDXFIFO_CLKS_SHIFT 19 -+#define EUR_CR_CLKGATESTATUS_TA_CLKS_MASK 0x00100000U -+#define EUR_CR_CLKGATESTATUS_TA_CLKS_SHIFT 20 -+/* Register EUR_CR_CLKGATECTLOVR */ -+#define EUR_CR_CLKGATECTLOVR 0x000C -+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_MASK 0x00000003U -+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_SHIFT 0 -+#define EUR_CR_CLKGATECTLOVR_ISP2_CLKO_MASK 0x0000000CU -+#define EUR_CR_CLKGATECTLOVR_ISP2_CLKO_SHIFT 2 -+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_MASK 0x00000030U -+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_SHIFT 4 -+#define EUR_CR_CLKGATECTLOVR_TE_CLKO_MASK 0x000000C0U -+#define EUR_CR_CLKGATECTLOVR_TE_CLKO_SHIFT 6 -+#define EUR_CR_CLKGATECTLOVR_MTE_CLKO_MASK 0x00000300U -+#define EUR_CR_CLKGATECTLOVR_MTE_CLKO_SHIFT 8 -+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_MASK 0x00000C00U -+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_SHIFT 10 -+#define EUR_CR_CLKGATECTLOVR_VDM_CLKO_MASK 0x00003000U -+#define EUR_CR_CLKGATECTLOVR_VDM_CLKO_SHIFT 12 -+#define EUR_CR_CLKGATECTLOVR_PDS_CLKO_MASK 0x0000C000U -+#define EUR_CR_CLKGATECTLOVR_PDS_CLKO_SHIFT 14 -+#define EUR_CR_CLKGATECTLOVR_IDXFIFO_CLKO_MASK 0x00030000U -+#define EUR_CR_CLKGATECTLOVR_IDXFIFO_CLKO_SHIFT 16 -+#define EUR_CR_CLKGATECTLOVR_TA_CLKO_MASK 0x000C0000U -+#define EUR_CR_CLKGATECTLOVR_TA_CLKO_SHIFT 18 -+/* Register EUR_CR_POWER */ -+#define EUR_CR_POWER 0x001C -+#define EUR_CR_POWER_PIPE_DISABLE_MASK 0x00000001U -+#define EUR_CR_POWER_PIPE_DISABLE_SHIFT 0 -+/* Register EUR_CR_CORE_ID */ -+#define EUR_CR_CORE_ID 0x0020 -+#define EUR_CR_CORE_ID_CONFIG_MASK 0x0000FFFFU -+#define EUR_CR_CORE_ID_CONFIG_SHIFT 0 -+#define EUR_CR_CORE_ID_ID_MASK 0xFFFF0000U -+#define EUR_CR_CORE_ID_ID_SHIFT 16 -+/* Register EUR_CR_CORE_REVISION */ -+#define EUR_CR_CORE_REVISION 0x0024 -+#define EUR_CR_CORE_REVISION_MAINTENANCE_MASK 0x000000FFU -+#define EUR_CR_CORE_REVISION_MAINTENANCE_SHIFT 0 -+#define EUR_CR_CORE_REVISION_MINOR_MASK 0x0000FF00U -+#define EUR_CR_CORE_REVISION_MINOR_SHIFT 8 -+#define EUR_CR_CORE_REVISION_MAJOR_MASK 0x00FF0000U -+#define EUR_CR_CORE_REVISION_MAJOR_SHIFT 16 -+#define EUR_CR_CORE_REVISION_DESIGNER_MASK 0xFF000000U -+#define EUR_CR_CORE_REVISION_DESIGNER_SHIFT 24 -+/* Register EUR_CR_DESIGNER_REV_FIELD1 */ -+#define EUR_CR_DESIGNER_REV_FIELD1 0x0028 -+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_MASK 0xFFFFFFFFU -+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_SHIFT 0 -+/* Register EUR_CR_DESIGNER_REV_FIELD2 */ -+#define EUR_CR_DESIGNER_REV_FIELD2 0x002C -+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_MASK 0xFFFFFFFFU -+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_SHIFT 0 -+/* Register EUR_CR_SOFT_RESET */ -+#define EUR_CR_SOFT_RESET 0x0080 -+#define EUR_CR_SOFT_RESET_BIF_RESET_MASK 0x00000001U -+#define EUR_CR_SOFT_RESET_BIF_RESET_SHIFT 0 -+#define EUR_CR_SOFT_RESET_VDM_RESET_MASK 0x00000002U -+#define EUR_CR_SOFT_RESET_VDM_RESET_SHIFT 1 -+#define EUR_CR_SOFT_RESET_DPM_RESET_MASK 0x00000004U -+#define EUR_CR_SOFT_RESET_DPM_RESET_SHIFT 2 -+#define EUR_CR_SOFT_RESET_TE_RESET_MASK 0x00000008U -+#define EUR_CR_SOFT_RESET_TE_RESET_SHIFT 3 -+#define EUR_CR_SOFT_RESET_MTE_RESET_MASK 0x00000010U -+#define EUR_CR_SOFT_RESET_MTE_RESET_SHIFT 4 -+#define EUR_CR_SOFT_RESET_ISP_RESET_MASK 0x00000020U -+#define EUR_CR_SOFT_RESET_ISP_RESET_SHIFT 5 -+#define EUR_CR_SOFT_RESET_ISP2_RESET_MASK 0x00000040U -+#define EUR_CR_SOFT_RESET_ISP2_RESET_SHIFT 6 -+#define EUR_CR_SOFT_RESET_TSP_RESET_MASK 0x00000080U -+#define EUR_CR_SOFT_RESET_TSP_RESET_SHIFT 7 -+#define EUR_CR_SOFT_RESET_PDS_RESET_MASK 0x00000100U -+#define EUR_CR_SOFT_RESET_PDS_RESET_SHIFT 8 -+#define EUR_CR_SOFT_RESET_PBE_RESET_MASK 0x00000200U -+#define EUR_CR_SOFT_RESET_PBE_RESET_SHIFT 9 -+#define EUR_CR_SOFT_RESET_CACHEL2_RESET_MASK 0x00000400U -+#define EUR_CR_SOFT_RESET_CACHEL2_RESET_SHIFT 10 -+#define EUR_CR_SOFT_RESET_UCACHEL2_RESET_MASK 0x00000800U -+#define EUR_CR_SOFT_RESET_UCACHEL2_RESET_SHIFT 11 -+#define EUR_CR_SOFT_RESET_MADD_RESET_MASK 0x00001000U -+#define EUR_CR_SOFT_RESET_MADD_RESET_SHIFT 12 -+#define EUR_CR_SOFT_RESET_ITR_RESET_MASK 0x00002000U -+#define EUR_CR_SOFT_RESET_ITR_RESET_SHIFT 13 -+#define EUR_CR_SOFT_RESET_TEX_RESET_MASK 0x00004000U -+#define EUR_CR_SOFT_RESET_TEX_RESET_SHIFT 14 -+#define EUR_CR_SOFT_RESET_USE_RESET_MASK 0x00008000U -+#define EUR_CR_SOFT_RESET_USE_RESET_SHIFT 15 -+#define EUR_CR_SOFT_RESET_IDXFIFO_RESET_MASK 0x00010000U -+#define EUR_CR_SOFT_RESET_IDXFIFO_RESET_SHIFT 16 -+#define EUR_CR_SOFT_RESET_TA_RESET_MASK 0x00020000U -+#define EUR_CR_SOFT_RESET_TA_RESET_SHIFT 17 -+/* Register EUR_CR_EVENT_HOST_ENABLE2 */ -+#define EUR_CR_EVENT_HOST_ENABLE2 0x0110 -+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_MASK 0x00000010U -+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_SHIFT 4 -+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_MASK 0x00000008U -+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_SHIFT 3 -+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_MASK 0x00000004U -+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_SHIFT 2 -+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_MASK 0x00000002U -+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_SHIFT 1 -+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_MASK 0x00000001U -+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_SHIFT 0 -+/* Register EUR_CR_EVENT_HOST_CLEAR2 */ -+#define EUR_CR_EVENT_HOST_CLEAR2 0x0114 -+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_MASK 0x00000010U -+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_SHIFT 4 -+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_MASK 0x00000008U -+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_SHIFT 3 -+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_MASK 0x00000004U -+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_SHIFT 2 -+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_MASK 0x00000002U -+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_SHIFT 1 -+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_MASK 0x00000001U -+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_SHIFT 0 -+/* Register EUR_CR_EVENT_STATUS2 */ -+#define EUR_CR_EVENT_STATUS2 0x0118 -+#define EUR_CR_EVENT_STATUS2_TRIG_TA_MASK 0x00000010U -+#define EUR_CR_EVENT_STATUS2_TRIG_TA_SHIFT 4 -+#define EUR_CR_EVENT_STATUS2_TRIG_3D_MASK 0x00000008U -+#define EUR_CR_EVENT_STATUS2_TRIG_3D_SHIFT 3 -+#define EUR_CR_EVENT_STATUS2_TRIG_DL_MASK 0x00000004U -+#define EUR_CR_EVENT_STATUS2_TRIG_DL_SHIFT 2 -+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_MASK 0x00000002U -+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_SHIFT 1 -+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_MASK 0x00000001U -+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_SHIFT 0 -+/* Register EUR_CR_EVENT_STATUS */ -+#define EUR_CR_EVENT_STATUS 0x012CU -+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_MASK 0x80000000U -+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_SHIFT 31 -+#define EUR_CR_EVENT_STATUS_TIMER_MASK 0x20000000U -+#define EUR_CR_EVENT_STATUS_TIMER_SHIFT 29 -+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_MASK 0x10000000U -+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_SHIFT 28 -+#define EUR_CR_EVENT_STATUS_TWOD_COMPLETE_MASK 0x08000000U -+#define EUR_CR_EVENT_STATUS_TWOD_COMPLETE_SHIFT 27 -+#define EUR_CR_EVENT_STATUS_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U -+#define EUR_CR_EVENT_STATUS_MADD_CACHE_INVALCOMPLETE_SHIFT 26 -+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U -+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25 -+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_MASK 0x01000000U -+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_SHIFT 24 -+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_MASK 0x00800000U -+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_SHIFT 23 -+#define EUR_CR_EVENT_STATUS_DPM_INITEND_MASK 0x00400000U -+#define EUR_CR_EVENT_STATUS_DPM_INITEND_SHIFT 22 -+#define EUR_CR_EVENT_STATUS_OTPM_LOADED_MASK 0x00200000U -+#define EUR_CR_EVENT_STATUS_OTPM_LOADED_SHIFT 21 -+#define EUR_CR_EVENT_STATUS_OTPM_INV_MASK 0x00100000U -+#define EUR_CR_EVENT_STATUS_OTPM_INV_SHIFT 20 -+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_MASK 0x00080000U -+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_SHIFT 19 -+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_MASK 0x00040000U -+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_SHIFT 18 -+#define EUR_CR_EVENT_STATUS_ISP_HALT_MASK 0x00020000U -+#define EUR_CR_EVENT_STATUS_ISP_HALT_SHIFT 17 -+#define EUR_CR_EVENT_STATUS_ISP_VISIBILITY_FAIL_MASK 0x00010000U -+#define EUR_CR_EVENT_STATUS_ISP_VISIBILITY_FAIL_SHIFT 16 -+#define EUR_CR_EVENT_STATUS_BREAKPOINT_MASK 0x00008000U -+#define EUR_CR_EVENT_STATUS_BREAKPOINT_SHIFT 15 -+#define EUR_CR_EVENT_STATUS_SW_EVENT_MASK 0x00004000U -+#define EUR_CR_EVENT_STATUS_SW_EVENT_SHIFT 14 -+#define EUR_CR_EVENT_STATUS_TA_FINISHED_MASK 0x00002000U -+#define EUR_CR_EVENT_STATUS_TA_FINISHED_SHIFT 13 -+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_MASK 0x00001000U -+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_SHIFT 12 -+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_MASK 0x00000800U -+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_SHIFT 11 -+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_MASK 0x00000400U -+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_SHIFT 10 -+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_MASK 0x00000200U -+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_SHIFT 9 -+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_MASK 0x00000100U -+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_SHIFT 8 -+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_MASK 0x00000080U -+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_SHIFT 7 -+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_MASK 0x00000040U -+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_SHIFT 6 -+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_MASK 0x00000020U -+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_SHIFT 5 -+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_MASK 0x00000010U -+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_SHIFT 4 -+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_MASK 0x00000008U -+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_SHIFT 3 -+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U -+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_SHIFT 2 -+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U -+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_SHIFT 1 -+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_MASK 0x00000001U -+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_SHIFT 0 -+/* Register EUR_CR_EVENT_HOST_ENABLE */ -+#define EUR_CR_EVENT_HOST_ENABLE 0x0130 -+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_MASK 0x80000000U -+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_SHIFT 31 -+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_MASK 0x20000000U -+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_SHIFT 29 -+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_MASK 0x10000000U -+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_SHIFT 28 -+#define EUR_CR_EVENT_HOST_ENABLE_TWOD_COMPLETE_MASK 0x08000000U -+#define EUR_CR_EVENT_HOST_ENABLE_TWOD_COMPLETE_SHIFT 27 -+#define EUR_CR_EVENT_HOST_ENABLE_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U -+#define EUR_CR_EVENT_HOST_ENABLE_MADD_CACHE_INVALCOMPLETE_SHIFT 26 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_MASK 0x01000000U -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_SHIFT 24 -+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_MASK 0x00800000U -+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_SHIFT 23 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_MASK 0x00400000U -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_SHIFT 22 -+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_MASK 0x00200000U -+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_SHIFT 21 -+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_MASK 0x00100000U -+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_SHIFT 20 -+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_MASK 0x00080000U -+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_SHIFT 19 -+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_MASK 0x00040000U -+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_SHIFT 18 -+#define EUR_CR_EVENT_HOST_ENABLE_ISP_HALT_MASK 0x00020000U -+#define EUR_CR_EVENT_HOST_ENABLE_ISP_HALT_SHIFT 17 -+#define EUR_CR_EVENT_HOST_ENABLE_ISP_VISIBILITY_FAIL_MASK 0x00010000U -+#define EUR_CR_EVENT_HOST_ENABLE_ISP_VISIBILITY_FAIL_SHIFT 16 -+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_MASK 0x00008000U -+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_SHIFT 15 -+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_MASK 0x00004000U -+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_SHIFT 14 -+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_MASK 0x00002000U -+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_SHIFT 13 -+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_MASK 0x00001000U -+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_SHIFT 12 -+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_MASK 0x00000800U -+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_SHIFT 11 -+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_MASK 0x00000400U -+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_SHIFT 10 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_MASK 0x00000200U -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_SHIFT 9 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_MASK 0x00000100U -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_SHIFT 8 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_MASK 0x00000080U -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_SHIFT 7 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_MASK 0x00000040U -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_SHIFT 6 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_MASK 0x00000020U -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_SHIFT 5 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_MASK 0x00000010U -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_SHIFT 4 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_MASK 0x00000008U -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_SHIFT 3 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_SHIFT 2 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_SHIFT 1 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_MASK 0x00000001U -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_SHIFT 0 -+/* Register EUR_CR_EVENT_HOST_CLEAR */ -+#define EUR_CR_EVENT_HOST_CLEAR 0x0134 -+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_MASK 0x80000000U -+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_SHIFT 31 -+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_MASK 0x20000000U -+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_SHIFT 29 -+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_MASK 0x10000000U -+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_SHIFT 28 -+#define EUR_CR_EVENT_HOST_CLEAR_TWOD_COMPLETE_MASK 0x08000000U -+#define EUR_CR_EVENT_HOST_CLEAR_TWOD_COMPLETE_SHIFT 27 -+#define EUR_CR_EVENT_HOST_CLEAR_MADD_CACHE_INVALCOMPLETE_MASK 0x04000000U -+#define EUR_CR_EVENT_HOST_CLEAR_MADD_CACHE_INVALCOMPLETE_SHIFT 26 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_MASK 0x01000000U -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_SHIFT 24 -+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_MASK 0x00800000U -+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_SHIFT 23 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_MASK 0x00400000U -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_SHIFT 22 -+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_MASK 0x00200000U -+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_SHIFT 21 -+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_MASK 0x00100000U -+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_SHIFT 20 -+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_MASK 0x00080000U -+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_SHIFT 19 -+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_MASK 0x00040000U -+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_SHIFT 18 -+#define EUR_CR_EVENT_HOST_CLEAR_ISP_HALT_MASK 0x00020000U -+#define EUR_CR_EVENT_HOST_CLEAR_ISP_HALT_SHIFT 17 -+#define EUR_CR_EVENT_HOST_CLEAR_ISP_VISIBILITY_FAIL_MASK 0x00010000U -+#define EUR_CR_EVENT_HOST_CLEAR_ISP_VISIBILITY_FAIL_SHIFT 16 -+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_MASK 0x00008000U -+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_SHIFT 15 -+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_MASK 0x00004000U -+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_SHIFT 14 -+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_MASK 0x00002000U -+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_SHIFT 13 -+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_MASK 0x00001000U -+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_SHIFT 12 -+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_MASK 0x00000800U -+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_SHIFT 11 -+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_MASK 0x00000400U -+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_SHIFT 10 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_MASK 0x00000200U -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_SHIFT 9 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_MASK 0x00000100U -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_SHIFT 8 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_MASK 0x00000080U -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_SHIFT 7 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_MASK 0x00000040U -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_SHIFT 6 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_MASK 0x00000020U -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_SHIFT 5 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_MASK 0x00000010U -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_SHIFT 4 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_MASK 0x00000008U -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_SHIFT 3 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_SHIFT 2 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_SHIFT 1 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_MASK 0x00000001U -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_SHIFT 0 -+/* Register EUR_CR_TIMER */ -+#define EUR_CR_TIMER 0x0144 -+#define EUR_CR_TIMER_VALUE_MASK 0xFFFFFFFFU -+#define EUR_CR_TIMER_VALUE_SHIFT 0 -+/* Register EUR_CR_EVENT_KICK1 */ -+#define EUR_CR_EVENT_KICK1 0x0AB0 -+#define EUR_CR_EVENT_KICK1_NOW_MASK 0x000000FFU -+#define EUR_CR_EVENT_KICK1_NOW_SHIFT 0 -+/* Register EUR_CR_PDS_EXEC_BASE */ -+#define EUR_CR_PDS_EXEC_BASE 0x0AB8 -+#define EUR_CR_PDS_EXEC_BASE_ADDR_MASK 0x0FF00000U -+#define EUR_CR_PDS_EXEC_BASE_ADDR_SHIFT 20 -+/* Register EUR_CR_EVENT_KICK2 */ -+#define EUR_CR_EVENT_KICK2 0x0AC0 -+#define EUR_CR_EVENT_KICK2_NOW_MASK 0x00000001U -+#define EUR_CR_EVENT_KICK2_NOW_SHIFT 0 -+/* Register EUR_CR_EVENT_KICKER */ -+#define EUR_CR_EVENT_KICKER 0x0AC4 -+#define EUR_CR_EVENT_KICKER_ADDRESS_MASK 0x0FFFFFF0U -+#define EUR_CR_EVENT_KICKER_ADDRESS_SHIFT 4 -+/* Register EUR_CR_EVENT_KICK */ -+#define EUR_CR_EVENT_KICK 0x0AC8 -+#define EUR_CR_EVENT_KICK_NOW_MASK 0x00000001U -+#define EUR_CR_EVENT_KICK_NOW_SHIFT 0 -+/* Register EUR_CR_EVENT_TIMER */ -+#define EUR_CR_EVENT_TIMER 0x0ACC -+#define EUR_CR_EVENT_TIMER_ENABLE_MASK 0x01000000U -+#define EUR_CR_EVENT_TIMER_ENABLE_SHIFT 24 -+#define EUR_CR_EVENT_TIMER_VALUE_MASK 0x00FFFFFFU -+#define EUR_CR_EVENT_TIMER_VALUE_SHIFT 0 -+/* Register EUR_CR_PDS_INV0 */ -+#define EUR_CR_PDS_INV0 0x0AD0 -+#define EUR_CR_PDS_INV0_DSC_MASK 0x00000001U -+#define EUR_CR_PDS_INV0_DSC_SHIFT 0 -+/* Register EUR_CR_PDS_INV1 */ -+#define EUR_CR_PDS_INV1 0x0AD4 -+#define EUR_CR_PDS_INV1_DSC_MASK 0x00000001U -+#define EUR_CR_PDS_INV1_DSC_SHIFT 0 -+/* Register EUR_CR_EVENT_KICK3 */ -+#define EUR_CR_EVENT_KICK3 0x0AD8 -+#define EUR_CR_EVENT_KICK3_NOW_MASK 0x00000001U -+#define EUR_CR_EVENT_KICK3_NOW_SHIFT 0 -+/* Register EUR_CR_PDS_INV3 */ -+#define EUR_CR_PDS_INV3 0x0ADC -+#define EUR_CR_PDS_INV3_DSC_MASK 0x00000001U -+#define EUR_CR_PDS_INV3_DSC_SHIFT 0 -+/* Register EUR_CR_PDS_INV_CSC */ -+#define EUR_CR_PDS_INV_CSC 0x0AE0 -+#define EUR_CR_PDS_INV_CSC_KICK_MASK 0x00000001U -+#define EUR_CR_PDS_INV_CSC_KICK_SHIFT 0 -+/* Register EUR_CR_PDS_PC_BASE */ -+#define EUR_CR_PDS_PC_BASE 0x0B2C -+#define EUR_CR_PDS_PC_BASE_ADDRESS_MASK 0x00FFFFFFU -+#define EUR_CR_PDS_PC_BASE_ADDRESS_SHIFT 0 -+/* Register EUR_CR_BIF_CTRL */ -+#define EUR_CR_BIF_CTRL 0x0C00 -+#define EUR_CR_BIF_CTRL_NOREORDER_MASK 0x00000001U -+#define EUR_CR_BIF_CTRL_NOREORDER_SHIFT 0 -+#define EUR_CR_BIF_CTRL_PAUSE_MASK 0x00000002U -+#define EUR_CR_BIF_CTRL_PAUSE_SHIFT 1 -+#define EUR_CR_BIF_CTRL_FLUSH_MASK 0x00000004U -+#define EUR_CR_BIF_CTRL_FLUSH_SHIFT 2 -+#define EUR_CR_BIF_CTRL_INVALDC_MASK 0x00000008U -+#define EUR_CR_BIF_CTRL_INVALDC_SHIFT 3 -+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_MASK 0x00000010U -+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_SHIFT 4 -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_CACHE_MASK 0x00000100U -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_CACHE_SHIFT 8 -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_MASK 0x00000200U -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_SHIFT 9 -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TE_MASK 0x00000400U -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TE_SHIFT 10 -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_MASK 0x00001000U -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_SHIFT 12 -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_MASK 0x00002000U -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_SHIFT 13 -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_MASK 0x00004000U -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_SHIFT 14 -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_MASK 0x00008000U -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_SHIFT 15 -+/* Register EUR_CR_BIF_INT_STAT */ -+#define EUR_CR_BIF_INT_STAT 0x0C04 -+#define EUR_CR_BIF_INT_STAT_FAULT_MASK 0x00003FFFU -+#define EUR_CR_BIF_INT_STAT_FAULT_SHIFT 0 -+#define EUR_CR_BIF_INT_STAT_PF_N_RW_MASK 0x00004000U -+#define EUR_CR_BIF_INT_STAT_PF_N_RW_SHIFT 14 -+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_MASK 0x00008000U -+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_SHIFT 15 -+/* Register EUR_CR_BIF_FAULT */ -+#define EUR_CR_BIF_FAULT 0x0C08 -+#define EUR_CR_BIF_FAULT_SB_MASK 0x000001F0U -+#define EUR_CR_BIF_FAULT_SB_SHIFT 4 -+#define EUR_CR_BIF_FAULT_ADDR_MASK 0x0FFFF000U -+#define EUR_CR_BIF_FAULT_ADDR_SHIFT 12 -+/* Register EUR_CR_BIF_DIR_LIST_BASE0 */ -+#define EUR_CR_BIF_DIR_LIST_BASE0 0x0C84 -+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_MASK 0xFFFFF000U -+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_SHIFT 12 -+/* Register EUR_CR_BIF_TA_REQ_BASE */ -+#define EUR_CR_BIF_TA_REQ_BASE 0x0C90 -+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_MASK 0x0FF00000U -+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_SHIFT 20 -+/* Register EUR_CR_BIF_MEM_REQ_STAT */ -+#define EUR_CR_BIF_MEM_REQ_STAT 0x0CA8 -+#define EUR_CR_BIF_MEM_REQ_STAT_READS_MASK 0x000000FFU -+#define EUR_CR_BIF_MEM_REQ_STAT_READS_SHIFT 0 -+/* Register EUR_CR_BIF_3D_REQ_BASE */ -+#define EUR_CR_BIF_3D_REQ_BASE 0x0CAC -+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_MASK 0x0FF00000U -+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_SHIFT 20 -+/* Register EUR_CR_BIF_ZLS_REQ_BASE */ -+#define EUR_CR_BIF_ZLS_REQ_BASE 0x0CB0 -+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_MASK 0x0FF00000U -+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_SHIFT 20 -+/* Register EUR_CR_2D_BLIT_STATUS */ -+#define EUR_CR_2D_BLIT_STATUS 0x0E04 -+#define EUR_CR_2D_BLIT_STATUS_COMPLETE_MASK 0x00FFFFFFU -+#define EUR_CR_2D_BLIT_STATUS_COMPLETE_SHIFT 0 -+#define EUR_CR_2D_BLIT_STATUS_BUSY_MASK 0x01000000U -+#define EUR_CR_2D_BLIT_STATUS_BUSY_SHIFT 24 -+/* Register EUR_CR_2D_VIRTUAL_FIFO_0 */ -+#define EUR_CR_2D_VIRTUAL_FIFO_0 0x0E10 -+#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_MASK 0x00000001U -+#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_SHIFT 0 -+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MASK 0x0000000EU -+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_SHIFT 1 -+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_MASK 0x00000FF0U -+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_SHIFT 4 -+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_MASK 0x0000F000U -+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_SHIFT 12 -+/* Register EUR_CR_2D_VIRTUAL_FIFO_1 */ -+#define EUR_CR_2D_VIRTUAL_FIFO_1 0x0E14 -+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_MASK 0x00000FFFU -+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_SHIFT 0 -+#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_MASK 0x00FFF000U -+#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_SHIFT 12 -+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_MASK 0xFF000000U -+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_SHIFT 24 -+/* Table EUR_CR_USE_CODE_BASE */ -+/* Register EUR_CR_USE_CODE_BASE */ -+#define EUR_CR_USE_CODE_BASE(X) (0x0A0C + (4 * (X))) -+#define EUR_CR_USE_CODE_BASE_ADDR_MASK 0x00FFFFFFU -+#define EUR_CR_USE_CODE_BASE_ADDR_SHIFT 0 -+#define EUR_CR_USE_CODE_BASE_DM_MASK 0x03000000U -+#define EUR_CR_USE_CODE_BASE_DM_SHIFT 24 -+/* Number of entries in table EUR_CR_USE_CODE_BASE */ -+#define EUR_CR_USE_CODE_BASE_SIZE_UINT32 16 -+#define EUR_CR_USE_CODE_BASE_NUM_ENTRIES 16 -+ -+#endif /* _SGX540DEFS_KM_H_ */ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/hwdefs/sgx544defs.h b/drivers/staging/ti-es8-sgx/services4/srvkm/hwdefs/sgx544defs.h -new file mode 100644 -index 0000000..6892def ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/hwdefs/sgx544defs.h -@@ -0,0 +1,1486 @@ -+/*************************************************************************/ /*! -+@Title Hardware defs for SGX544. -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#ifndef _SGX544DEFS_KM_H_ -+#define _SGX544DEFS_KM_H_ -+ -+/* Register EUR_CR_CLKGATECTL */ -+#define EUR_CR_CLKGATECTL 0x0000 -+#define EUR_CR_CLKGATECTL_ISP_CLKG_MASK 0x00000003U -+#define EUR_CR_CLKGATECTL_ISP_CLKG_SHIFT 0 -+#define EUR_CR_CLKGATECTL_ISP_CLKG_SIGNED 0 -+#define EUR_CR_CLKGATECTL_ISP2_CLKG_MASK 0x0000000CU -+#define EUR_CR_CLKGATECTL_ISP2_CLKG_SHIFT 2 -+#define EUR_CR_CLKGATECTL_ISP2_CLKG_SIGNED 0 -+#define EUR_CR_CLKGATECTL_TSP_CLKG_MASK 0x00000030U -+#define EUR_CR_CLKGATECTL_TSP_CLKG_SHIFT 4 -+#define EUR_CR_CLKGATECTL_TSP_CLKG_SIGNED 0 -+#define EUR_CR_CLKGATECTL_TE_CLKG_MASK 0x000000C0U -+#define EUR_CR_CLKGATECTL_TE_CLKG_SHIFT 6 -+#define EUR_CR_CLKGATECTL_TE_CLKG_SIGNED 0 -+#define EUR_CR_CLKGATECTL_MTE_CLKG_MASK 0x00000300U -+#define EUR_CR_CLKGATECTL_MTE_CLKG_SHIFT 8 -+#define EUR_CR_CLKGATECTL_MTE_CLKG_SIGNED 0 -+#define EUR_CR_CLKGATECTL_DPM_CLKG_MASK 0x00000C00U -+#define EUR_CR_CLKGATECTL_DPM_CLKG_SHIFT 10 -+#define EUR_CR_CLKGATECTL_DPM_CLKG_SIGNED 0 -+#define EUR_CR_CLKGATECTL_VDM_CLKG_MASK 0x00003000U -+#define EUR_CR_CLKGATECTL_VDM_CLKG_SHIFT 12 -+#define EUR_CR_CLKGATECTL_VDM_CLKG_SIGNED 0 -+#define EUR_CR_CLKGATECTL_PDS_CLKG_MASK 0x0000C000U -+#define EUR_CR_CLKGATECTL_PDS_CLKG_SHIFT 14 -+#define EUR_CR_CLKGATECTL_PDS_CLKG_SIGNED 0 -+#define EUR_CR_CLKGATECTL_IDXFIFO_CLKG_MASK 0x00030000U -+#define EUR_CR_CLKGATECTL_IDXFIFO_CLKG_SHIFT 16 -+#define EUR_CR_CLKGATECTL_IDXFIFO_CLKG_SIGNED 0 -+#define EUR_CR_CLKGATECTL_TA_CLKG_MASK 0x000C0000U -+#define EUR_CR_CLKGATECTL_TA_CLKG_SHIFT 18 -+#define EUR_CR_CLKGATECTL_TA_CLKG_SIGNED 0 -+#define EUR_CR_CLKGATECTL_BIF_CORE_CLKG_MASK 0x00300000U -+#define EUR_CR_CLKGATECTL_BIF_CORE_CLKG_SHIFT 20 -+#define EUR_CR_CLKGATECTL_BIF_CORE_CLKG_SIGNED 0 -+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_MASK 0x01000000U -+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_SHIFT 24 -+#define EUR_CR_CLKGATECTL_AUTO_MAN_REG_SIGNED 0 -+#define EUR_CR_CLKGATECTL_SYSTEM_CLKG_MASK 0x10000000U -+#define EUR_CR_CLKGATECTL_SYSTEM_CLKG_SHIFT 28 -+#define EUR_CR_CLKGATECTL_SYSTEM_CLKG_SIGNED 0 -+/* Register EUR_CR_CLKGATECTL2 */ -+#define EUR_CR_CLKGATECTL2 0x0004 -+#define EUR_CR_CLKGATECTL2_PBE_CLKG_MASK 0x00000003U -+#define EUR_CR_CLKGATECTL2_PBE_CLKG_SHIFT 0 -+#define EUR_CR_CLKGATECTL2_PBE_CLKG_SIGNED 0 -+#define EUR_CR_CLKGATECTL2_TCU_L2_CLKG_MASK 0x0000000CU -+#define EUR_CR_CLKGATECTL2_TCU_L2_CLKG_SHIFT 2 -+#define EUR_CR_CLKGATECTL2_TCU_L2_CLKG_SIGNED 0 -+#define EUR_CR_CLKGATECTL2_UCACHEL2_CLKG_MASK 0x00000030U -+#define EUR_CR_CLKGATECTL2_UCACHEL2_CLKG_SHIFT 4 -+#define EUR_CR_CLKGATECTL2_UCACHEL2_CLKG_SIGNED 0 -+#define EUR_CR_CLKGATECTL2_USE0_CLKG_MASK 0x000000C0U -+#define EUR_CR_CLKGATECTL2_USE0_CLKG_SHIFT 6 -+#define EUR_CR_CLKGATECTL2_USE0_CLKG_SIGNED 0 -+#define EUR_CR_CLKGATECTL2_ITR0_CLKG_MASK 0x00000300U -+#define EUR_CR_CLKGATECTL2_ITR0_CLKG_SHIFT 8 -+#define EUR_CR_CLKGATECTL2_ITR0_CLKG_SIGNED 0 -+#define EUR_CR_CLKGATECTL2_TEX0_CLKG_MASK 0x00000C00U -+#define EUR_CR_CLKGATECTL2_TEX0_CLKG_SHIFT 10 -+#define EUR_CR_CLKGATECTL2_TEX0_CLKG_SIGNED 0 -+#define EUR_CR_CLKGATECTL2_USE1_CLKG_MASK 0x0000C000U -+#define EUR_CR_CLKGATECTL2_USE1_CLKG_SHIFT 14 -+#define EUR_CR_CLKGATECTL2_USE1_CLKG_SIGNED 0 -+#define EUR_CR_CLKGATECTL2_ITR1_CLKG_MASK 0x00030000U -+#define EUR_CR_CLKGATECTL2_ITR1_CLKG_SHIFT 16 -+#define EUR_CR_CLKGATECTL2_ITR1_CLKG_SIGNED 0 -+#define EUR_CR_CLKGATECTL2_TEX1_CLKG_MASK 0x000C0000U -+#define EUR_CR_CLKGATECTL2_TEX1_CLKG_SHIFT 18 -+#define EUR_CR_CLKGATECTL2_TEX1_CLKG_SIGNED 0 -+#define EUR_CR_CLKGATECTL2_DCU_L2_CLKG_MASK 0x00C00000U -+#define EUR_CR_CLKGATECTL2_DCU_L2_CLKG_SHIFT 22 -+#define EUR_CR_CLKGATECTL2_DCU_L2_CLKG_SIGNED 0 -+#define EUR_CR_CLKGATECTL2_DCU1_L0L1_CLKG_MASK 0x03000000U -+#define EUR_CR_CLKGATECTL2_DCU1_L0L1_CLKG_SHIFT 24 -+#define EUR_CR_CLKGATECTL2_DCU1_L0L1_CLKG_SIGNED 0 -+#define EUR_CR_CLKGATECTL2_DCU0_L0L1_CLKG_MASK 0x0C000000U -+#define EUR_CR_CLKGATECTL2_DCU0_L0L1_CLKG_SHIFT 26 -+#define EUR_CR_CLKGATECTL2_DCU0_L0L1_CLKG_SIGNED 0 -+/* Register EUR_CR_CLKGATESTATUS */ -+#define EUR_CR_CLKGATESTATUS 0x0008 -+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_MASK 0x00000001U -+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_SHIFT 0 -+#define EUR_CR_CLKGATESTATUS_ISP_CLKS_SIGNED 0 -+#define EUR_CR_CLKGATESTATUS_ISP2_CLKS_MASK 0x00000002U -+#define EUR_CR_CLKGATESTATUS_ISP2_CLKS_SHIFT 1 -+#define EUR_CR_CLKGATESTATUS_ISP2_CLKS_SIGNED 0 -+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_MASK 0x00000004U -+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_SHIFT 2 -+#define EUR_CR_CLKGATESTATUS_TSP_CLKS_SIGNED 0 -+#define EUR_CR_CLKGATESTATUS_TE_CLKS_MASK 0x00000008U -+#define EUR_CR_CLKGATESTATUS_TE_CLKS_SHIFT 3 -+#define EUR_CR_CLKGATESTATUS_TE_CLKS_SIGNED 0 -+#define EUR_CR_CLKGATESTATUS_MTE_CLKS_MASK 0x00000010U -+#define EUR_CR_CLKGATESTATUS_MTE_CLKS_SHIFT 4 -+#define EUR_CR_CLKGATESTATUS_MTE_CLKS_SIGNED 0 -+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_MASK 0x00000020U -+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_SHIFT 5 -+#define EUR_CR_CLKGATESTATUS_DPM_CLKS_SIGNED 0 -+#define EUR_CR_CLKGATESTATUS_VDM_CLKS_MASK 0x00000040U -+#define EUR_CR_CLKGATESTATUS_VDM_CLKS_SHIFT 6 -+#define EUR_CR_CLKGATESTATUS_VDM_CLKS_SIGNED 0 -+#define EUR_CR_CLKGATESTATUS_PDS_CLKS_MASK 0x00000080U -+#define EUR_CR_CLKGATESTATUS_PDS_CLKS_SHIFT 7 -+#define EUR_CR_CLKGATESTATUS_PDS_CLKS_SIGNED 0 -+#define EUR_CR_CLKGATESTATUS_PBE_CLKS_MASK 0x00000100U -+#define EUR_CR_CLKGATESTATUS_PBE_CLKS_SHIFT 8 -+#define EUR_CR_CLKGATESTATUS_PBE_CLKS_SIGNED 0 -+#define EUR_CR_CLKGATESTATUS_TCU_L2_CLKS_MASK 0x00000200U -+#define EUR_CR_CLKGATESTATUS_TCU_L2_CLKS_SHIFT 9 -+#define EUR_CR_CLKGATESTATUS_TCU_L2_CLKS_SIGNED 0 -+#define EUR_CR_CLKGATESTATUS_UCACHEL2_CLKS_MASK 0x00000400U -+#define EUR_CR_CLKGATESTATUS_UCACHEL2_CLKS_SHIFT 10 -+#define EUR_CR_CLKGATESTATUS_UCACHEL2_CLKS_SIGNED 0 -+#define EUR_CR_CLKGATESTATUS_USE0_CLKS_MASK 0x00000800U -+#define EUR_CR_CLKGATESTATUS_USE0_CLKS_SHIFT 11 -+#define EUR_CR_CLKGATESTATUS_USE0_CLKS_SIGNED 0 -+#define EUR_CR_CLKGATESTATUS_ITR0_CLKS_MASK 0x00001000U -+#define EUR_CR_CLKGATESTATUS_ITR0_CLKS_SHIFT 12 -+#define EUR_CR_CLKGATESTATUS_ITR0_CLKS_SIGNED 0 -+#define EUR_CR_CLKGATESTATUS_TEX0_CLKS_MASK 0x00002000U -+#define EUR_CR_CLKGATESTATUS_TEX0_CLKS_SHIFT 13 -+#define EUR_CR_CLKGATESTATUS_TEX0_CLKS_SIGNED 0 -+#define EUR_CR_CLKGATESTATUS_USE1_CLKS_MASK 0x00008000U -+#define EUR_CR_CLKGATESTATUS_USE1_CLKS_SHIFT 15 -+#define EUR_CR_CLKGATESTATUS_USE1_CLKS_SIGNED 0 -+#define EUR_CR_CLKGATESTATUS_ITR1_CLKS_MASK 0x00010000U -+#define EUR_CR_CLKGATESTATUS_ITR1_CLKS_SHIFT 16 -+#define EUR_CR_CLKGATESTATUS_ITR1_CLKS_SIGNED 0 -+#define EUR_CR_CLKGATESTATUS_TEX1_CLKS_MASK 0x00020000U -+#define EUR_CR_CLKGATESTATUS_TEX1_CLKS_SHIFT 17 -+#define EUR_CR_CLKGATESTATUS_TEX1_CLKS_SIGNED 0 -+#define EUR_CR_CLKGATESTATUS_IDXFIFO_CLKS_MASK 0x00080000U -+#define EUR_CR_CLKGATESTATUS_IDXFIFO_CLKS_SHIFT 19 -+#define EUR_CR_CLKGATESTATUS_IDXFIFO_CLKS_SIGNED 0 -+#define EUR_CR_CLKGATESTATUS_TA_CLKS_MASK 0x00100000U -+#define EUR_CR_CLKGATESTATUS_TA_CLKS_SHIFT 20 -+#define EUR_CR_CLKGATESTATUS_TA_CLKS_SIGNED 0 -+#define EUR_CR_CLKGATESTATUS_DCU_L2_CLKS_MASK 0x00200000U -+#define EUR_CR_CLKGATESTATUS_DCU_L2_CLKS_SHIFT 21 -+#define EUR_CR_CLKGATESTATUS_DCU_L2_CLKS_SIGNED 0 -+#define EUR_CR_CLKGATESTATUS_DCU0_L0L1_CLKS_MASK 0x00400000U -+#define EUR_CR_CLKGATESTATUS_DCU0_L0L1_CLKS_SHIFT 22 -+#define EUR_CR_CLKGATESTATUS_DCU0_L0L1_CLKS_SIGNED 0 -+#define EUR_CR_CLKGATESTATUS_DCU1_L0L1_CLKS_MASK 0x00800000U -+#define EUR_CR_CLKGATESTATUS_DCU1_L0L1_CLKS_SHIFT 23 -+#define EUR_CR_CLKGATESTATUS_DCU1_L0L1_CLKS_SIGNED 0 -+#define EUR_CR_CLKGATESTATUS_BIF_CORE_CLKS_MASK 0x01000000U -+#define EUR_CR_CLKGATESTATUS_BIF_CORE_CLKS_SHIFT 24 -+#define EUR_CR_CLKGATESTATUS_BIF_CORE_CLKS_SIGNED 0 -+/* Register EUR_CR_CLKGATECTLOVR */ -+#define EUR_CR_CLKGATECTLOVR 0x000C -+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_MASK 0x00000003U -+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_SHIFT 0 -+#define EUR_CR_CLKGATECTLOVR_ISP_CLKO_SIGNED 0 -+#define EUR_CR_CLKGATECTLOVR_ISP2_CLKO_MASK 0x0000000CU -+#define EUR_CR_CLKGATECTLOVR_ISP2_CLKO_SHIFT 2 -+#define EUR_CR_CLKGATECTLOVR_ISP2_CLKO_SIGNED 0 -+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_MASK 0x00000030U -+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_SHIFT 4 -+#define EUR_CR_CLKGATECTLOVR_TSP_CLKO_SIGNED 0 -+#define EUR_CR_CLKGATECTLOVR_TE_CLKO_MASK 0x000000C0U -+#define EUR_CR_CLKGATECTLOVR_TE_CLKO_SHIFT 6 -+#define EUR_CR_CLKGATECTLOVR_TE_CLKO_SIGNED 0 -+#define EUR_CR_CLKGATECTLOVR_MTE_CLKO_MASK 0x00000300U -+#define EUR_CR_CLKGATECTLOVR_MTE_CLKO_SHIFT 8 -+#define EUR_CR_CLKGATECTLOVR_MTE_CLKO_SIGNED 0 -+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_MASK 0x00000C00U -+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_SHIFT 10 -+#define EUR_CR_CLKGATECTLOVR_DPM_CLKO_SIGNED 0 -+#define EUR_CR_CLKGATECTLOVR_VDM_CLKO_MASK 0x00003000U -+#define EUR_CR_CLKGATECTLOVR_VDM_CLKO_SHIFT 12 -+#define EUR_CR_CLKGATECTLOVR_VDM_CLKO_SIGNED 0 -+#define EUR_CR_CLKGATECTLOVR_PDS_CLKO_MASK 0x0000C000U -+#define EUR_CR_CLKGATECTLOVR_PDS_CLKO_SHIFT 14 -+#define EUR_CR_CLKGATECTLOVR_PDS_CLKO_SIGNED 0 -+#define EUR_CR_CLKGATECTLOVR_IDXFIFO_CLKO_MASK 0x00030000U -+#define EUR_CR_CLKGATECTLOVR_IDXFIFO_CLKO_SHIFT 16 -+#define EUR_CR_CLKGATECTLOVR_IDXFIFO_CLKO_SIGNED 0 -+#define EUR_CR_CLKGATECTLOVR_TA_CLKO_MASK 0x000C0000U -+#define EUR_CR_CLKGATECTLOVR_TA_CLKO_SHIFT 18 -+#define EUR_CR_CLKGATECTLOVR_TA_CLKO_SIGNED 0 -+#define EUR_CR_CLKGATECTLOVR_BIF_CORE_CLKO_MASK 0x00300000U -+#define EUR_CR_CLKGATECTLOVR_BIF_CORE_CLKO_SHIFT 20 -+#define EUR_CR_CLKGATECTLOVR_BIF_CORE_CLKO_SIGNED 0 -+/* Register EUR_CR_POWER */ -+#define EUR_CR_POWER 0x001C -+#define EUR_CR_POWER_PIPE_DISABLE_MASK 0x00000001U -+#define EUR_CR_POWER_PIPE_DISABLE_SHIFT 0 -+#define EUR_CR_POWER_PIPE_DISABLE_SIGNED 0 -+/* Register EUR_CR_CORE_ID */ -+#define EUR_CR_CORE_ID 0x0020 -+#define EUR_CR_CORE_ID_CONFIG_MULTI_MASK 0x00000001U -+#define EUR_CR_CORE_ID_CONFIG_MULTI_SHIFT 0 -+#define EUR_CR_CORE_ID_CONFIG_MULTI_SIGNED 0 -+#define EUR_CR_CORE_ID_CONFIG_BASE_MASK 0x00000002U -+#define EUR_CR_CORE_ID_CONFIG_BASE_SHIFT 1 -+#define EUR_CR_CORE_ID_CONFIG_BASE_SIGNED 0 -+#define EUR_CR_CORE_ID_CONFIG_MASK 0x000000FCU -+#define EUR_CR_CORE_ID_CONFIG_SHIFT 2 -+#define EUR_CR_CORE_ID_CONFIG_SIGNED 0 -+#define EUR_CR_CORE_ID_CONFIG_CORES_MASK 0x00000F00U -+#define EUR_CR_CORE_ID_CONFIG_CORES_SHIFT 8 -+#define EUR_CR_CORE_ID_CONFIG_CORES_SIGNED 0 -+#define EUR_CR_CORE_ID_CONFIG_SLC_MASK 0x0000F000U -+#define EUR_CR_CORE_ID_CONFIG_SLC_SHIFT 12 -+#define EUR_CR_CORE_ID_CONFIG_SLC_SIGNED 0 -+#define EUR_CR_CORE_ID_ID_MASK 0xFFFF0000U -+#define EUR_CR_CORE_ID_ID_SHIFT 16 -+#define EUR_CR_CORE_ID_ID_SIGNED 0 -+/* Register EUR_CR_CORE_REVISION */ -+#define EUR_CR_CORE_REVISION 0x0024 -+#define EUR_CR_CORE_REVISION_MAINTENANCE_MASK 0x000000FFU -+#define EUR_CR_CORE_REVISION_MAINTENANCE_SHIFT 0 -+#define EUR_CR_CORE_REVISION_MAINTENANCE_SIGNED 0 -+#define EUR_CR_CORE_REVISION_MINOR_MASK 0x0000FF00U -+#define EUR_CR_CORE_REVISION_MINOR_SHIFT 8 -+#define EUR_CR_CORE_REVISION_MINOR_SIGNED 0 -+#define EUR_CR_CORE_REVISION_MAJOR_MASK 0x00FF0000U -+#define EUR_CR_CORE_REVISION_MAJOR_SHIFT 16 -+#define EUR_CR_CORE_REVISION_MAJOR_SIGNED 0 -+#define EUR_CR_CORE_REVISION_DESIGNER_MASK 0xFF000000U -+#define EUR_CR_CORE_REVISION_DESIGNER_SHIFT 24 -+#define EUR_CR_CORE_REVISION_DESIGNER_SIGNED 0 -+/* Register EUR_CR_DESIGNER_REV_FIELD1 */ -+#define EUR_CR_DESIGNER_REV_FIELD1 0x0028 -+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_MASK 0xFFFFFFFFU -+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_SHIFT 0 -+#define EUR_CR_DESIGNER_REV_FIELD1_DESIGNER_REV_FIELD1_SIGNED 0 -+/* Register EUR_CR_DESIGNER_REV_FIELD2 */ -+#define EUR_CR_DESIGNER_REV_FIELD2 0x002C -+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_MASK 0xFFFFFFFFU -+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_SHIFT 0 -+#define EUR_CR_DESIGNER_REV_FIELD2_DESIGNER_REV_FIELD2_SIGNED 0 -+/* Register EUR_CR_SOFT_RESET */ -+#define EUR_CR_SOFT_RESET 0x0080 -+#define EUR_CR_SOFT_RESET_BIF_RESET_MASK 0x00000001U -+#define EUR_CR_SOFT_RESET_BIF_RESET_SHIFT 0 -+#define EUR_CR_SOFT_RESET_BIF_RESET_SIGNED 0 -+#define EUR_CR_SOFT_RESET_VDM_RESET_MASK 0x00000002U -+#define EUR_CR_SOFT_RESET_VDM_RESET_SHIFT 1 -+#define EUR_CR_SOFT_RESET_VDM_RESET_SIGNED 0 -+#define EUR_CR_SOFT_RESET_DPM_RESET_MASK 0x00000004U -+#define EUR_CR_SOFT_RESET_DPM_RESET_SHIFT 2 -+#define EUR_CR_SOFT_RESET_DPM_RESET_SIGNED 0 -+#define EUR_CR_SOFT_RESET_TE_RESET_MASK 0x00000008U -+#define EUR_CR_SOFT_RESET_TE_RESET_SHIFT 3 -+#define EUR_CR_SOFT_RESET_TE_RESET_SIGNED 0 -+#define EUR_CR_SOFT_RESET_MTE_RESET_MASK 0x00000010U -+#define EUR_CR_SOFT_RESET_MTE_RESET_SHIFT 4 -+#define EUR_CR_SOFT_RESET_MTE_RESET_SIGNED 0 -+#define EUR_CR_SOFT_RESET_ISP_RESET_MASK 0x00000020U -+#define EUR_CR_SOFT_RESET_ISP_RESET_SHIFT 5 -+#define EUR_CR_SOFT_RESET_ISP_RESET_SIGNED 0 -+#define EUR_CR_SOFT_RESET_ISP2_RESET_MASK 0x00000040U -+#define EUR_CR_SOFT_RESET_ISP2_RESET_SHIFT 6 -+#define EUR_CR_SOFT_RESET_ISP2_RESET_SIGNED 0 -+#define EUR_CR_SOFT_RESET_TSP_RESET_MASK 0x00000080U -+#define EUR_CR_SOFT_RESET_TSP_RESET_SHIFT 7 -+#define EUR_CR_SOFT_RESET_TSP_RESET_SIGNED 0 -+#define EUR_CR_SOFT_RESET_PDS_RESET_MASK 0x00000100U -+#define EUR_CR_SOFT_RESET_PDS_RESET_SHIFT 8 -+#define EUR_CR_SOFT_RESET_PDS_RESET_SIGNED 0 -+#define EUR_CR_SOFT_RESET_PBE_RESET_MASK 0x00000200U -+#define EUR_CR_SOFT_RESET_PBE_RESET_SHIFT 9 -+#define EUR_CR_SOFT_RESET_PBE_RESET_SIGNED 0 -+#define EUR_CR_SOFT_RESET_TCU_L2_RESET_MASK 0x00000400U -+#define EUR_CR_SOFT_RESET_TCU_L2_RESET_SHIFT 10 -+#define EUR_CR_SOFT_RESET_TCU_L2_RESET_SIGNED 0 -+#define EUR_CR_SOFT_RESET_UCACHEL2_RESET_MASK 0x00000800U -+#define EUR_CR_SOFT_RESET_UCACHEL2_RESET_SHIFT 11 -+#define EUR_CR_SOFT_RESET_UCACHEL2_RESET_SIGNED 0 -+#define EUR_CR_SOFT_RESET_ITR_RESET_MASK 0x00002000U -+#define EUR_CR_SOFT_RESET_ITR_RESET_SHIFT 13 -+#define EUR_CR_SOFT_RESET_ITR_RESET_SIGNED 0 -+#define EUR_CR_SOFT_RESET_TEX_RESET_MASK 0x00004000U -+#define EUR_CR_SOFT_RESET_TEX_RESET_SHIFT 14 -+#define EUR_CR_SOFT_RESET_TEX_RESET_SIGNED 0 -+#define EUR_CR_SOFT_RESET_USE_RESET_MASK 0x00008000U -+#define EUR_CR_SOFT_RESET_USE_RESET_SHIFT 15 -+#define EUR_CR_SOFT_RESET_USE_RESET_SIGNED 0 -+#define EUR_CR_SOFT_RESET_IDXFIFO_RESET_MASK 0x00010000U -+#define EUR_CR_SOFT_RESET_IDXFIFO_RESET_SHIFT 16 -+#define EUR_CR_SOFT_RESET_IDXFIFO_RESET_SIGNED 0 -+#define EUR_CR_SOFT_RESET_TA_RESET_MASK 0x00020000U -+#define EUR_CR_SOFT_RESET_TA_RESET_SHIFT 17 -+#define EUR_CR_SOFT_RESET_TA_RESET_SIGNED 0 -+#define EUR_CR_SOFT_RESET_DCU_L2_RESET_MASK 0x00040000U -+#define EUR_CR_SOFT_RESET_DCU_L2_RESET_SHIFT 18 -+#define EUR_CR_SOFT_RESET_DCU_L2_RESET_SIGNED 0 -+#define EUR_CR_SOFT_RESET_DCU_L0L1_RESET_MASK 0x00080000U -+#define EUR_CR_SOFT_RESET_DCU_L0L1_RESET_SHIFT 19 -+#define EUR_CR_SOFT_RESET_DCU_L0L1_RESET_SIGNED 0 -+/* Register EUR_CR_EVENT_HOST_ENABLE2 */ -+#define EUR_CR_EVENT_HOST_ENABLE2 0x0110 -+#define EUR_CR_EVENT_HOST_ENABLE2_DATA_BREAKPOINT_UNTRAPPED_MASK 0x00000800U -+#define EUR_CR_EVENT_HOST_ENABLE2_DATA_BREAKPOINT_UNTRAPPED_SHIFT 11 -+#define EUR_CR_EVENT_HOST_ENABLE2_DATA_BREAKPOINT_UNTRAPPED_SIGNED 0 -+#define EUR_CR_EVENT_HOST_ENABLE2_DATA_BREAKPOINT_TRAPPED_MASK 0x00000400U -+#define EUR_CR_EVENT_HOST_ENABLE2_DATA_BREAKPOINT_TRAPPED_SHIFT 10 -+#define EUR_CR_EVENT_HOST_ENABLE2_DATA_BREAKPOINT_TRAPPED_SIGNED 0 -+#define EUR_CR_EVENT_HOST_ENABLE2_MTE_CONTEXT_DRAINED_MASK 0x00000200U -+#define EUR_CR_EVENT_HOST_ENABLE2_MTE_CONTEXT_DRAINED_SHIFT 9 -+#define EUR_CR_EVENT_HOST_ENABLE2_MTE_CONTEXT_DRAINED_SIGNED 0 -+#define EUR_CR_EVENT_HOST_ENABLE2_ISP2_ZLS_CSW_FINISHED_MASK 0x00000100U -+#define EUR_CR_EVENT_HOST_ENABLE2_ISP2_ZLS_CSW_FINISHED_SHIFT 8 -+#define EUR_CR_EVENT_HOST_ENABLE2_ISP2_ZLS_CSW_FINISHED_SIGNED 0 -+#define EUR_CR_EVENT_HOST_ENABLE2_DCU_INVALCOMPLETE_MASK 0x00000080U -+#define EUR_CR_EVENT_HOST_ENABLE2_DCU_INVALCOMPLETE_SHIFT 7 -+#define EUR_CR_EVENT_HOST_ENABLE2_DCU_INVALCOMPLETE_SIGNED 0 -+#define EUR_CR_EVENT_HOST_ENABLE2_MTE_STATE_FLUSHED_MASK 0x00000040U -+#define EUR_CR_EVENT_HOST_ENABLE2_MTE_STATE_FLUSHED_SHIFT 6 -+#define EUR_CR_EVENT_HOST_ENABLE2_MTE_STATE_FLUSHED_SIGNED 0 -+#define EUR_CR_EVENT_HOST_ENABLE2_TE_RGNHDR_INIT_COMPLETE_MASK 0x00000020U -+#define EUR_CR_EVENT_HOST_ENABLE2_TE_RGNHDR_INIT_COMPLETE_SHIFT 5 -+#define EUR_CR_EVENT_HOST_ENABLE2_TE_RGNHDR_INIT_COMPLETE_SIGNED 0 -+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_MASK 0x00000010U -+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_SHIFT 4 -+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_TA_SIGNED 0 -+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_MASK 0x00000008U -+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_SHIFT 3 -+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_3D_SIGNED 0 -+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_MASK 0x00000004U -+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_SHIFT 2 -+#define EUR_CR_EVENT_HOST_ENABLE2_TRIG_DL_SIGNED 0 -+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_MASK 0x00000002U -+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_SHIFT 1 -+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_3D_FREE_LOAD_SIGNED 0 -+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_MASK 0x00000001U -+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_SHIFT 0 -+#define EUR_CR_EVENT_HOST_ENABLE2_DPM_TA_FREE_LOAD_SIGNED 0 -+/* Register EUR_CR_EVENT_HOST_CLEAR2 */ -+#define EUR_CR_EVENT_HOST_CLEAR2 0x0114 -+#define EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_UNTRAPPED_MASK 0x00000800U -+#define EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_UNTRAPPED_SHIFT 11 -+#define EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_UNTRAPPED_SIGNED 0 -+#define EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_TRAPPED_MASK 0x00000400U -+#define EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_TRAPPED_SHIFT 10 -+#define EUR_CR_EVENT_HOST_CLEAR2_DATA_BREAKPOINT_TRAPPED_SIGNED 0 -+#define EUR_CR_EVENT_HOST_CLEAR2_MTE_CONTEXT_DRAINED_MASK 0x00000200U -+#define EUR_CR_EVENT_HOST_CLEAR2_MTE_CONTEXT_DRAINED_SHIFT 9 -+#define EUR_CR_EVENT_HOST_CLEAR2_MTE_CONTEXT_DRAINED_SIGNED 0 -+#define EUR_CR_EVENT_HOST_CLEAR2_ISP2_ZLS_CSW_FINISHED_MASK 0x00000100U -+#define EUR_CR_EVENT_HOST_CLEAR2_ISP2_ZLS_CSW_FINISHED_SHIFT 8 -+#define EUR_CR_EVENT_HOST_CLEAR2_ISP2_ZLS_CSW_FINISHED_SIGNED 0 -+#define EUR_CR_EVENT_HOST_CLEAR2_DCU_INVALCOMPLETE_MASK 0x00000080U -+#define EUR_CR_EVENT_HOST_CLEAR2_DCU_INVALCOMPLETE_SHIFT 7 -+#define EUR_CR_EVENT_HOST_CLEAR2_DCU_INVALCOMPLETE_SIGNED 0 -+#define EUR_CR_EVENT_HOST_CLEAR2_MTE_STATE_FLUSHED_MASK 0x00000040U -+#define EUR_CR_EVENT_HOST_CLEAR2_MTE_STATE_FLUSHED_SHIFT 6 -+#define EUR_CR_EVENT_HOST_CLEAR2_MTE_STATE_FLUSHED_SIGNED 0 -+#define EUR_CR_EVENT_HOST_CLEAR2_TE_RGNHDR_INIT_COMPLETE_MASK 0x00000020U -+#define EUR_CR_EVENT_HOST_CLEAR2_TE_RGNHDR_INIT_COMPLETE_SHIFT 5 -+#define EUR_CR_EVENT_HOST_CLEAR2_TE_RGNHDR_INIT_COMPLETE_SIGNED 0 -+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_MASK 0x00000010U -+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_SHIFT 4 -+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_TA_SIGNED 0 -+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_MASK 0x00000008U -+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_SHIFT 3 -+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_3D_SIGNED 0 -+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_MASK 0x00000004U -+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_SHIFT 2 -+#define EUR_CR_EVENT_HOST_CLEAR2_TRIG_DL_SIGNED 0 -+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_MASK 0x00000002U -+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_SHIFT 1 -+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_3D_FREE_LOAD_SIGNED 0 -+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_MASK 0x00000001U -+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_SHIFT 0 -+#define EUR_CR_EVENT_HOST_CLEAR2_DPM_TA_FREE_LOAD_SIGNED 0 -+/* Register EUR_CR_EVENT_STATUS2 */ -+#define EUR_CR_EVENT_STATUS2 0x0118 -+#define EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_UNTRAPPED_MASK 0x00000800U -+#define EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_UNTRAPPED_SHIFT 11 -+#define EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_UNTRAPPED_SIGNED 0 -+#define EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_TRAPPED_MASK 0x00000400U -+#define EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_TRAPPED_SHIFT 10 -+#define EUR_CR_EVENT_STATUS2_DATA_BREAKPOINT_TRAPPED_SIGNED 0 -+#define EUR_CR_EVENT_STATUS2_MTE_CONTEXT_DRAINED_MASK 0x00000200U -+#define EUR_CR_EVENT_STATUS2_MTE_CONTEXT_DRAINED_SHIFT 9 -+#define EUR_CR_EVENT_STATUS2_MTE_CONTEXT_DRAINED_SIGNED 0 -+#define EUR_CR_EVENT_STATUS2_ISP2_ZLS_CSW_FINISHED_MASK 0x00000100U -+#define EUR_CR_EVENT_STATUS2_ISP2_ZLS_CSW_FINISHED_SHIFT 8 -+#define EUR_CR_EVENT_STATUS2_ISP2_ZLS_CSW_FINISHED_SIGNED 0 -+#define EUR_CR_EVENT_STATUS2_DCU_INVALCOMPLETE_MASK 0x00000080U -+#define EUR_CR_EVENT_STATUS2_DCU_INVALCOMPLETE_SHIFT 7 -+#define EUR_CR_EVENT_STATUS2_DCU_INVALCOMPLETE_SIGNED 0 -+#define EUR_CR_EVENT_STATUS2_MTE_STATE_FLUSHED_MASK 0x00000040U -+#define EUR_CR_EVENT_STATUS2_MTE_STATE_FLUSHED_SHIFT 6 -+#define EUR_CR_EVENT_STATUS2_MTE_STATE_FLUSHED_SIGNED 0 -+#define EUR_CR_EVENT_STATUS2_TE_RGNHDR_INIT_COMPLETE_MASK 0x00000020U -+#define EUR_CR_EVENT_STATUS2_TE_RGNHDR_INIT_COMPLETE_SHIFT 5 -+#define EUR_CR_EVENT_STATUS2_TE_RGNHDR_INIT_COMPLETE_SIGNED 0 -+#define EUR_CR_EVENT_STATUS2_TRIG_TA_MASK 0x00000010U -+#define EUR_CR_EVENT_STATUS2_TRIG_TA_SHIFT 4 -+#define EUR_CR_EVENT_STATUS2_TRIG_TA_SIGNED 0 -+#define EUR_CR_EVENT_STATUS2_TRIG_3D_MASK 0x00000008U -+#define EUR_CR_EVENT_STATUS2_TRIG_3D_SHIFT 3 -+#define EUR_CR_EVENT_STATUS2_TRIG_3D_SIGNED 0 -+#define EUR_CR_EVENT_STATUS2_TRIG_DL_MASK 0x00000004U -+#define EUR_CR_EVENT_STATUS2_TRIG_DL_SHIFT 2 -+#define EUR_CR_EVENT_STATUS2_TRIG_DL_SIGNED 0 -+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_MASK 0x00000002U -+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_SHIFT 1 -+#define EUR_CR_EVENT_STATUS2_DPM_3D_FREE_LOAD_SIGNED 0 -+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_MASK 0x00000001U -+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_SHIFT 0 -+#define EUR_CR_EVENT_STATUS2_DPM_TA_FREE_LOAD_SIGNED 0 -+/* Register EUR_CR_EVENT_STATUS */ -+#define EUR_CR_EVENT_STATUS 0x012C -+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_MASK 0x80000000U -+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_SHIFT 31 -+#define EUR_CR_EVENT_STATUS_MASTER_INTERRUPT_SIGNED 0 -+#define EUR_CR_EVENT_STATUS_TIMER_MASK 0x20000000U -+#define EUR_CR_EVENT_STATUS_TIMER_SHIFT 29 -+#define EUR_CR_EVENT_STATUS_TIMER_SIGNED 0 -+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_MASK 0x10000000U -+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_SHIFT 28 -+#define EUR_CR_EVENT_STATUS_TA_DPM_FAULT_SIGNED 0 -+#define EUR_CR_EVENT_STATUS_TCU_INVALCOMPLETE_MASK 0x04000000U -+#define EUR_CR_EVENT_STATUS_TCU_INVALCOMPLETE_SHIFT 26 -+#define EUR_CR_EVENT_STATUS_TCU_INVALCOMPLETE_SIGNED 0 -+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U -+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25 -+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_ZLS_SIGNED 0 -+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_MASK 0x01000000U -+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_SHIFT 24 -+#define EUR_CR_EVENT_STATUS_DPM_TA_MEM_FREE_SIGNED 0 -+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_MASK 0x00800000U -+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_SHIFT 23 -+#define EUR_CR_EVENT_STATUS_ISP_END_TILE_SIGNED 0 -+#define EUR_CR_EVENT_STATUS_DPM_INITEND_MASK 0x00400000U -+#define EUR_CR_EVENT_STATUS_DPM_INITEND_SHIFT 22 -+#define EUR_CR_EVENT_STATUS_DPM_INITEND_SIGNED 0 -+#define EUR_CR_EVENT_STATUS_OTPM_LOADED_MASK 0x00200000U -+#define EUR_CR_EVENT_STATUS_OTPM_LOADED_SHIFT 21 -+#define EUR_CR_EVENT_STATUS_OTPM_LOADED_SIGNED 0 -+#define EUR_CR_EVENT_STATUS_OTPM_INV_MASK 0x00100000U -+#define EUR_CR_EVENT_STATUS_OTPM_INV_SHIFT 20 -+#define EUR_CR_EVENT_STATUS_OTPM_INV_SIGNED 0 -+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_MASK 0x00080000U -+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_SHIFT 19 -+#define EUR_CR_EVENT_STATUS_OTPM_FLUSHED_SIGNED 0 -+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_MASK 0x00040000U -+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_SHIFT 18 -+#define EUR_CR_EVENT_STATUS_PIXELBE_END_RENDER_SIGNED 0 -+#define EUR_CR_EVENT_STATUS_BREAKPOINT_MASK 0x00008000U -+#define EUR_CR_EVENT_STATUS_BREAKPOINT_SHIFT 15 -+#define EUR_CR_EVENT_STATUS_BREAKPOINT_SIGNED 0 -+#define EUR_CR_EVENT_STATUS_SW_EVENT_MASK 0x00004000U -+#define EUR_CR_EVENT_STATUS_SW_EVENT_SHIFT 14 -+#define EUR_CR_EVENT_STATUS_SW_EVENT_SIGNED 0 -+#define EUR_CR_EVENT_STATUS_TA_FINISHED_MASK 0x00002000U -+#define EUR_CR_EVENT_STATUS_TA_FINISHED_SHIFT 13 -+#define EUR_CR_EVENT_STATUS_TA_FINISHED_SIGNED 0 -+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_MASK 0x00001000U -+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_SHIFT 12 -+#define EUR_CR_EVENT_STATUS_TA_TERMINATE_SIGNED 0 -+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_MASK 0x00000800U -+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_SHIFT 11 -+#define EUR_CR_EVENT_STATUS_TPC_CLEAR_SIGNED 0 -+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_MASK 0x00000400U -+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_SHIFT 10 -+#define EUR_CR_EVENT_STATUS_TPC_FLUSH_SIGNED 0 -+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_MASK 0x00000200U -+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_SHIFT 9 -+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_CLEAR_SIGNED 0 -+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_MASK 0x00000100U -+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_SHIFT 8 -+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_LOAD_SIGNED 0 -+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_MASK 0x00000080U -+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_SHIFT 7 -+#define EUR_CR_EVENT_STATUS_DPM_CONTROL_STORE_SIGNED 0 -+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_MASK 0x00000040U -+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_SHIFT 6 -+#define EUR_CR_EVENT_STATUS_DPM_STATE_CLEAR_SIGNED 0 -+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_MASK 0x00000020U -+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_SHIFT 5 -+#define EUR_CR_EVENT_STATUS_DPM_STATE_LOAD_SIGNED 0 -+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_MASK 0x00000010U -+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_SHIFT 4 -+#define EUR_CR_EVENT_STATUS_DPM_STATE_STORE_SIGNED 0 -+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_MASK 0x00000008U -+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_SHIFT 3 -+#define EUR_CR_EVENT_STATUS_DPM_REACHED_MEM_THRESH_SIGNED 0 -+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U -+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_SHIFT 2 -+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_GBL_SIGNED 0 -+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U -+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_SHIFT 1 -+#define EUR_CR_EVENT_STATUS_DPM_OUT_OF_MEMORY_MT_SIGNED 0 -+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_MASK 0x00000001U -+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_SHIFT 0 -+#define EUR_CR_EVENT_STATUS_DPM_3D_MEM_FREE_SIGNED 0 -+/* Register EUR_CR_EVENT_HOST_ENABLE */ -+#define EUR_CR_EVENT_HOST_ENABLE 0x0130 -+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_MASK 0x80000000U -+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_SHIFT 31 -+#define EUR_CR_EVENT_HOST_ENABLE_MASTER_INTERRUPT_SIGNED 0 -+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_MASK 0x20000000U -+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_SHIFT 29 -+#define EUR_CR_EVENT_HOST_ENABLE_TIMER_SIGNED 0 -+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_MASK 0x10000000U -+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_SHIFT 28 -+#define EUR_CR_EVENT_HOST_ENABLE_TA_DPM_FAULT_SIGNED 0 -+#define EUR_CR_EVENT_HOST_ENABLE_TCU_INVALCOMPLETE_MASK 0x04000000U -+#define EUR_CR_EVENT_HOST_ENABLE_TCU_INVALCOMPLETE_SHIFT 26 -+#define EUR_CR_EVENT_HOST_ENABLE_TCU_INVALCOMPLETE_SIGNED 0 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_ZLS_SIGNED 0 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_MASK 0x01000000U -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_SHIFT 24 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_TA_MEM_FREE_SIGNED 0 -+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_MASK 0x00800000U -+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_SHIFT 23 -+#define EUR_CR_EVENT_HOST_ENABLE_ISP_END_TILE_SIGNED 0 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_MASK 0x00400000U -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_SHIFT 22 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_INITEND_SIGNED 0 -+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_MASK 0x00200000U -+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_SHIFT 21 -+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_LOADED_SIGNED 0 -+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_MASK 0x00100000U -+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_SHIFT 20 -+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_INV_SIGNED 0 -+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_MASK 0x00080000U -+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_SHIFT 19 -+#define EUR_CR_EVENT_HOST_ENABLE_OTPM_FLUSHED_SIGNED 0 -+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_MASK 0x00040000U -+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_SHIFT 18 -+#define EUR_CR_EVENT_HOST_ENABLE_PIXELBE_END_RENDER_SIGNED 0 -+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_MASK 0x00008000U -+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_SHIFT 15 -+#define EUR_CR_EVENT_HOST_ENABLE_BREAKPOINT_SIGNED 0 -+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_MASK 0x00004000U -+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_SHIFT 14 -+#define EUR_CR_EVENT_HOST_ENABLE_SW_EVENT_SIGNED 0 -+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_MASK 0x00002000U -+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_SHIFT 13 -+#define EUR_CR_EVENT_HOST_ENABLE_TA_FINISHED_SIGNED 0 -+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_MASK 0x00001000U -+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_SHIFT 12 -+#define EUR_CR_EVENT_HOST_ENABLE_TA_TERMINATE_SIGNED 0 -+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_MASK 0x00000800U -+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_SHIFT 11 -+#define EUR_CR_EVENT_HOST_ENABLE_TPC_CLEAR_SIGNED 0 -+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_MASK 0x00000400U -+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_SHIFT 10 -+#define EUR_CR_EVENT_HOST_ENABLE_TPC_FLUSH_SIGNED 0 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_MASK 0x00000200U -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_SHIFT 9 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_CLEAR_SIGNED 0 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_MASK 0x00000100U -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_SHIFT 8 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_LOAD_SIGNED 0 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_MASK 0x00000080U -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_SHIFT 7 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_CONTROL_STORE_SIGNED 0 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_MASK 0x00000040U -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_SHIFT 6 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_CLEAR_SIGNED 0 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_MASK 0x00000020U -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_SHIFT 5 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_LOAD_SIGNED 0 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_MASK 0x00000010U -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_SHIFT 4 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_STATE_STORE_SIGNED 0 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_MASK 0x00000008U -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_SHIFT 3 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_REACHED_MEM_THRESH_SIGNED 0 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_SHIFT 2 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_GBL_SIGNED 0 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_SHIFT 1 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_OUT_OF_MEMORY_MT_SIGNED 0 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_MASK 0x00000001U -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_SHIFT 0 -+#define EUR_CR_EVENT_HOST_ENABLE_DPM_3D_MEM_FREE_SIGNED 0 -+/* Register EUR_CR_EVENT_HOST_CLEAR */ -+#define EUR_CR_EVENT_HOST_CLEAR 0x0134 -+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_MASK 0x80000000U -+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_SHIFT 31 -+#define EUR_CR_EVENT_HOST_CLEAR_MASTER_INTERRUPT_SIGNED 0 -+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_MASK 0x20000000U -+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_SHIFT 29 -+#define EUR_CR_EVENT_HOST_CLEAR_TIMER_SIGNED 0 -+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_MASK 0x10000000U -+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_SHIFT 28 -+#define EUR_CR_EVENT_HOST_CLEAR_TA_DPM_FAULT_SIGNED 0 -+#define EUR_CR_EVENT_HOST_CLEAR_TCU_INVALCOMPLETE_MASK 0x04000000U -+#define EUR_CR_EVENT_HOST_CLEAR_TCU_INVALCOMPLETE_SHIFT 26 -+#define EUR_CR_EVENT_HOST_CLEAR_TCU_INVALCOMPLETE_SIGNED 0 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_MASK 0x02000000U -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_SHIFT 25 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_ZLS_SIGNED 0 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_MASK 0x01000000U -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_SHIFT 24 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_TA_MEM_FREE_SIGNED 0 -+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_MASK 0x00800000U -+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_SHIFT 23 -+#define EUR_CR_EVENT_HOST_CLEAR_ISP_END_TILE_SIGNED 0 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_MASK 0x00400000U -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_SHIFT 22 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_INITEND_SIGNED 0 -+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_MASK 0x00200000U -+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_SHIFT 21 -+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_LOADED_SIGNED 0 -+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_MASK 0x00100000U -+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_SHIFT 20 -+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_INV_SIGNED 0 -+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_MASK 0x00080000U -+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_SHIFT 19 -+#define EUR_CR_EVENT_HOST_CLEAR_OTPM_FLUSHED_SIGNED 0 -+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_MASK 0x00040000U -+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_SHIFT 18 -+#define EUR_CR_EVENT_HOST_CLEAR_PIXELBE_END_RENDER_SIGNED 0 -+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_MASK 0x00008000U -+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_SHIFT 15 -+#define EUR_CR_EVENT_HOST_CLEAR_BREAKPOINT_SIGNED 0 -+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_MASK 0x00004000U -+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_SHIFT 14 -+#define EUR_CR_EVENT_HOST_CLEAR_SW_EVENT_SIGNED 0 -+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_MASK 0x00002000U -+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_SHIFT 13 -+#define EUR_CR_EVENT_HOST_CLEAR_TA_FINISHED_SIGNED 0 -+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_MASK 0x00001000U -+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_SHIFT 12 -+#define EUR_CR_EVENT_HOST_CLEAR_TA_TERMINATE_SIGNED 0 -+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_MASK 0x00000800U -+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_SHIFT 11 -+#define EUR_CR_EVENT_HOST_CLEAR_TPC_CLEAR_SIGNED 0 -+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_MASK 0x00000400U -+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_SHIFT 10 -+#define EUR_CR_EVENT_HOST_CLEAR_TPC_FLUSH_SIGNED 0 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_MASK 0x00000200U -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_SHIFT 9 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_CLEAR_SIGNED 0 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_MASK 0x00000100U -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_SHIFT 8 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_LOAD_SIGNED 0 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_MASK 0x00000080U -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_SHIFT 7 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_CONTROL_STORE_SIGNED 0 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_MASK 0x00000040U -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_SHIFT 6 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_CLEAR_SIGNED 0 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_MASK 0x00000020U -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_SHIFT 5 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_LOAD_SIGNED 0 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_MASK 0x00000010U -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_SHIFT 4 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_STATE_STORE_SIGNED 0 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_MASK 0x00000008U -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_SHIFT 3 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_REACHED_MEM_THRESH_SIGNED 0 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_MASK 0x00000004U -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_SHIFT 2 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_GBL_SIGNED 0 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_MASK 0x00000002U -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_SHIFT 1 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_OUT_OF_MEMORY_MT_SIGNED 0 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_MASK 0x00000001U -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_SHIFT 0 -+#define EUR_CR_EVENT_HOST_CLEAR_DPM_3D_MEM_FREE_SIGNED 0 -+/* Register EUR_CR_TIMER */ -+#define EUR_CR_TIMER 0x0144 -+#define EUR_CR_TIMER_VALUE_MASK 0xFFFFFFFFU -+#define EUR_CR_TIMER_VALUE_SHIFT 0 -+#define EUR_CR_TIMER_VALUE_SIGNED 0 -+/* Register EUR_CR_EVENT_KICK1 */ -+#define EUR_CR_EVENT_KICK1 0x0AB0 -+#define EUR_CR_EVENT_KICK1_NOW_MASK 0x000000FFU -+#define EUR_CR_EVENT_KICK1_NOW_SHIFT 0 -+#define EUR_CR_EVENT_KICK1_NOW_SIGNED 0 -+/* Register EUR_CR_EVENT_KICK2 */ -+#define EUR_CR_EVENT_KICK2 0x0AC0 -+#define EUR_CR_EVENT_KICK2_NOW_MASK 0x00000001U -+#define EUR_CR_EVENT_KICK2_NOW_SHIFT 0 -+#define EUR_CR_EVENT_KICK2_NOW_SIGNED 0 -+/* Register EUR_CR_EVENT_KICKER */ -+#define EUR_CR_EVENT_KICKER 0x0AC4 -+#define EUR_CR_EVENT_KICKER_ADDRESS_MASK 0xFFFFFFF0U -+#define EUR_CR_EVENT_KICKER_ADDRESS_SHIFT 4 -+#define EUR_CR_EVENT_KICKER_ADDRESS_SIGNED 0 -+/* Register EUR_CR_EVENT_KICK */ -+#define EUR_CR_EVENT_KICK 0x0AC8 -+#define EUR_CR_EVENT_KICK_NOW_MASK 0x00000001U -+#define EUR_CR_EVENT_KICK_NOW_SHIFT 0 -+#define EUR_CR_EVENT_KICK_NOW_SIGNED 0 -+/* Register EUR_CR_EVENT_TIMER */ -+#define EUR_CR_EVENT_TIMER 0x0ACC -+#define EUR_CR_EVENT_TIMER_ENABLE_MASK 0x01000000U -+#define EUR_CR_EVENT_TIMER_ENABLE_SHIFT 24 -+#define EUR_CR_EVENT_TIMER_ENABLE_SIGNED 0 -+#define EUR_CR_EVENT_TIMER_VALUE_MASK 0x00FFFFFFU -+#define EUR_CR_EVENT_TIMER_VALUE_SHIFT 0 -+#define EUR_CR_EVENT_TIMER_VALUE_SIGNED 0 -+/* Register EUR_CR_PDS_INV0 */ -+#define EUR_CR_PDS_INV0 0x0AD0 -+#define EUR_CR_PDS_INV0_DSC_MASK 0x00000001U -+#define EUR_CR_PDS_INV0_DSC_SHIFT 0 -+#define EUR_CR_PDS_INV0_DSC_SIGNED 0 -+/* Register EUR_CR_PDS_INV1 */ -+#define EUR_CR_PDS_INV1 0x0AD4 -+#define EUR_CR_PDS_INV1_DSC_MASK 0x00000001U -+#define EUR_CR_PDS_INV1_DSC_SHIFT 0 -+#define EUR_CR_PDS_INV1_DSC_SIGNED 0 -+/* Register EUR_CR_EVENT_KICK3 */ -+#define EUR_CR_EVENT_KICK3 0x0AD8 -+#define EUR_CR_EVENT_KICK3_NOW_MASK 0x00000001U -+#define EUR_CR_EVENT_KICK3_NOW_SHIFT 0 -+#define EUR_CR_EVENT_KICK3_NOW_SIGNED 0 -+/* Register EUR_CR_PDS_INV3 */ -+#define EUR_CR_PDS_INV3 0x0ADC -+#define EUR_CR_PDS_INV3_DSC_MASK 0x00000001U -+#define EUR_CR_PDS_INV3_DSC_SHIFT 0 -+#define EUR_CR_PDS_INV3_DSC_SIGNED 0 -+/* Register EUR_CR_PDS_INV_CSC */ -+#define EUR_CR_PDS_INV_CSC 0x0AE0 -+#define EUR_CR_PDS_INV_CSC_KICK_MASK 0x00000001U -+#define EUR_CR_PDS_INV_CSC_KICK_SHIFT 0 -+#define EUR_CR_PDS_INV_CSC_KICK_SIGNED 0 -+/* Register EUR_CR_BIF_CTRL */ -+#define EUR_CR_BIF_CTRL 0x0C00 -+#define EUR_CR_BIF_CTRL_NOREORDER_MASK 0x00000001U -+#define EUR_CR_BIF_CTRL_NOREORDER_SHIFT 0 -+#define EUR_CR_BIF_CTRL_NOREORDER_SIGNED 0 -+#define EUR_CR_BIF_CTRL_PAUSE_MASK 0x00000002U -+#define EUR_CR_BIF_CTRL_PAUSE_SHIFT 1 -+#define EUR_CR_BIF_CTRL_PAUSE_SIGNED 0 -+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_MASK 0x00000010U -+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_SHIFT 4 -+#define EUR_CR_BIF_CTRL_CLEAR_FAULT_SIGNED 0 -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_MASK 0x00000200U -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_SHIFT 9 -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_VDM_SIGNED 0 -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TA_MASK 0x00000400U -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TA_SHIFT 10 -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TA_SIGNED 0 -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_MASK 0x00001000U -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_SHIFT 12 -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PBE_SIGNED 0 -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_MASK 0x00002000U -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_SHIFT 13 -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_TSPP_SIGNED 0 -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_MASK 0x00004000U -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_SHIFT 14 -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_ISP_SIGNED 0 -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_MASK 0x00008000U -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_SHIFT 15 -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_USE_SIGNED 0 -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PTLA_MASK 0x00010000U -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PTLA_SHIFT 16 -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_PTLA_SIGNED 0 -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_VDM_MASK 0x00020000U -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_VDM_SHIFT 17 -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_VDM_SIGNED 0 -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_IPF_MASK 0x00040000U -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_IPF_SHIFT 18 -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_IPF_SIGNED 0 -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_DPM_MASK 0x00080000U -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_DPM_SHIFT 19 -+#define EUR_CR_BIF_CTRL_MMU_BYPASS_MASTER_DPM_SIGNED 0 -+/* Register EUR_CR_BIF_INT_STAT */ -+#define EUR_CR_BIF_INT_STAT 0x0C04 -+#define EUR_CR_BIF_INT_STAT_FAULT_REQ_MASK 0x00003FFFU -+#define EUR_CR_BIF_INT_STAT_FAULT_REQ_SHIFT 0 -+#define EUR_CR_BIF_INT_STAT_FAULT_REQ_SIGNED 0 -+#define EUR_CR_BIF_INT_STAT_FAULT_TYPE_MASK 0x00070000U -+#define EUR_CR_BIF_INT_STAT_FAULT_TYPE_SHIFT 16 -+#define EUR_CR_BIF_INT_STAT_FAULT_TYPE_SIGNED 0 -+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_MASK 0x00080000U -+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_SHIFT 19 -+#define EUR_CR_BIF_INT_STAT_FLUSH_COMPLETE_SIGNED 0 -+/* Register EUR_CR_BIF_FAULT */ -+#define EUR_CR_BIF_FAULT 0x0C08 -+#define EUR_CR_BIF_FAULT_CID_MASK 0x0000000FU -+#define EUR_CR_BIF_FAULT_CID_SHIFT 0 -+#define EUR_CR_BIF_FAULT_CID_SIGNED 0 -+#define EUR_CR_BIF_FAULT_SB_MASK 0x000001F0U -+#define EUR_CR_BIF_FAULT_SB_SHIFT 4 -+#define EUR_CR_BIF_FAULT_SB_SIGNED 0 -+#define EUR_CR_BIF_FAULT_ADDR_MASK 0xFFFFF000U -+#define EUR_CR_BIF_FAULT_ADDR_SHIFT 12 -+#define EUR_CR_BIF_FAULT_ADDR_SIGNED 0 -+/* Register EUR_CR_BIF_TILE0 */ -+#define EUR_CR_BIF_TILE0 0x0C0C -+#define EUR_CR_BIF_TILE0_MIN_ADDRESS_MASK 0x00000FFFU -+#define EUR_CR_BIF_TILE0_MIN_ADDRESS_SHIFT 0 -+#define EUR_CR_BIF_TILE0_MIN_ADDRESS_SIGNED 0 -+#define EUR_CR_BIF_TILE0_MAX_ADDRESS_MASK 0x00FFF000U -+#define EUR_CR_BIF_TILE0_MAX_ADDRESS_SHIFT 12 -+#define EUR_CR_BIF_TILE0_MAX_ADDRESS_SIGNED 0 -+#define EUR_CR_BIF_TILE0_CFG_MASK 0x0F000000U -+#define EUR_CR_BIF_TILE0_CFG_SHIFT 24 -+#define EUR_CR_BIF_TILE0_CFG_SIGNED 0 -+/* Register EUR_CR_BIF_TILE1 */ -+#define EUR_CR_BIF_TILE1 0x0C10 -+#define EUR_CR_BIF_TILE1_MIN_ADDRESS_MASK 0x00000FFFU -+#define EUR_CR_BIF_TILE1_MIN_ADDRESS_SHIFT 0 -+#define EUR_CR_BIF_TILE1_MIN_ADDRESS_SIGNED 0 -+#define EUR_CR_BIF_TILE1_MAX_ADDRESS_MASK 0x00FFF000U -+#define EUR_CR_BIF_TILE1_MAX_ADDRESS_SHIFT 12 -+#define EUR_CR_BIF_TILE1_MAX_ADDRESS_SIGNED 0 -+#define EUR_CR_BIF_TILE1_CFG_MASK 0x0F000000U -+#define EUR_CR_BIF_TILE1_CFG_SHIFT 24 -+#define EUR_CR_BIF_TILE1_CFG_SIGNED 0 -+/* Register EUR_CR_BIF_TILE2 */ -+#define EUR_CR_BIF_TILE2 0x0C14 -+#define EUR_CR_BIF_TILE2_MIN_ADDRESS_MASK 0x00000FFFU -+#define EUR_CR_BIF_TILE2_MIN_ADDRESS_SHIFT 0 -+#define EUR_CR_BIF_TILE2_MIN_ADDRESS_SIGNED 0 -+#define EUR_CR_BIF_TILE2_MAX_ADDRESS_MASK 0x00FFF000U -+#define EUR_CR_BIF_TILE2_MAX_ADDRESS_SHIFT 12 -+#define EUR_CR_BIF_TILE2_MAX_ADDRESS_SIGNED 0 -+#define EUR_CR_BIF_TILE2_CFG_MASK 0x0F000000U -+#define EUR_CR_BIF_TILE2_CFG_SHIFT 24 -+#define EUR_CR_BIF_TILE2_CFG_SIGNED 0 -+/* Register EUR_CR_BIF_TILE3 */ -+#define EUR_CR_BIF_TILE3 0x0C18 -+#define EUR_CR_BIF_TILE3_MIN_ADDRESS_MASK 0x00000FFFU -+#define EUR_CR_BIF_TILE3_MIN_ADDRESS_SHIFT 0 -+#define EUR_CR_BIF_TILE3_MIN_ADDRESS_SIGNED 0 -+#define EUR_CR_BIF_TILE3_MAX_ADDRESS_MASK 0x00FFF000U -+#define EUR_CR_BIF_TILE3_MAX_ADDRESS_SHIFT 12 -+#define EUR_CR_BIF_TILE3_MAX_ADDRESS_SIGNED 0 -+#define EUR_CR_BIF_TILE3_CFG_MASK 0x0F000000U -+#define EUR_CR_BIF_TILE3_CFG_SHIFT 24 -+#define EUR_CR_BIF_TILE3_CFG_SIGNED 0 -+/* Register EUR_CR_BIF_TILE4 */ -+#define EUR_CR_BIF_TILE4 0x0C1C -+#define EUR_CR_BIF_TILE4_MIN_ADDRESS_MASK 0x00000FFFU -+#define EUR_CR_BIF_TILE4_MIN_ADDRESS_SHIFT 0 -+#define EUR_CR_BIF_TILE4_MIN_ADDRESS_SIGNED 0 -+#define EUR_CR_BIF_TILE4_MAX_ADDRESS_MASK 0x00FFF000U -+#define EUR_CR_BIF_TILE4_MAX_ADDRESS_SHIFT 12 -+#define EUR_CR_BIF_TILE4_MAX_ADDRESS_SIGNED 0 -+#define EUR_CR_BIF_TILE4_CFG_MASK 0x0F000000U -+#define EUR_CR_BIF_TILE4_CFG_SHIFT 24 -+#define EUR_CR_BIF_TILE4_CFG_SIGNED 0 -+/* Register EUR_CR_BIF_TILE5 */ -+#define EUR_CR_BIF_TILE5 0x0C20 -+#define EUR_CR_BIF_TILE5_MIN_ADDRESS_MASK 0x00000FFFU -+#define EUR_CR_BIF_TILE5_MIN_ADDRESS_SHIFT 0 -+#define EUR_CR_BIF_TILE5_MIN_ADDRESS_SIGNED 0 -+#define EUR_CR_BIF_TILE5_MAX_ADDRESS_MASK 0x00FFF000U -+#define EUR_CR_BIF_TILE5_MAX_ADDRESS_SHIFT 12 -+#define EUR_CR_BIF_TILE5_MAX_ADDRESS_SIGNED 0 -+#define EUR_CR_BIF_TILE5_CFG_MASK 0x0F000000U -+#define EUR_CR_BIF_TILE5_CFG_SHIFT 24 -+#define EUR_CR_BIF_TILE5_CFG_SIGNED 0 -+/* Register EUR_CR_BIF_TILE6 */ -+#define EUR_CR_BIF_TILE6 0x0C24 -+#define EUR_CR_BIF_TILE6_MIN_ADDRESS_MASK 0x00000FFFU -+#define EUR_CR_BIF_TILE6_MIN_ADDRESS_SHIFT 0 -+#define EUR_CR_BIF_TILE6_MIN_ADDRESS_SIGNED 0 -+#define EUR_CR_BIF_TILE6_MAX_ADDRESS_MASK 0x00FFF000U -+#define EUR_CR_BIF_TILE6_MAX_ADDRESS_SHIFT 12 -+#define EUR_CR_BIF_TILE6_MAX_ADDRESS_SIGNED 0 -+#define EUR_CR_BIF_TILE6_CFG_MASK 0x0F000000U -+#define EUR_CR_BIF_TILE6_CFG_SHIFT 24 -+#define EUR_CR_BIF_TILE6_CFG_SIGNED 0 -+/* Register EUR_CR_BIF_TILE7 */ -+#define EUR_CR_BIF_TILE7 0x0C28 -+#define EUR_CR_BIF_TILE7_MIN_ADDRESS_MASK 0x00000FFFU -+#define EUR_CR_BIF_TILE7_MIN_ADDRESS_SHIFT 0 -+#define EUR_CR_BIF_TILE7_MIN_ADDRESS_SIGNED 0 -+#define EUR_CR_BIF_TILE7_MAX_ADDRESS_MASK 0x00FFF000U -+#define EUR_CR_BIF_TILE7_MAX_ADDRESS_SHIFT 12 -+#define EUR_CR_BIF_TILE7_MAX_ADDRESS_SIGNED 0 -+#define EUR_CR_BIF_TILE7_CFG_MASK 0x0F000000U -+#define EUR_CR_BIF_TILE7_CFG_SHIFT 24 -+#define EUR_CR_BIF_TILE7_CFG_SIGNED 0 -+/* Register EUR_CR_BIF_TILE8 */ -+#define EUR_CR_BIF_TILE8 0x0C2C -+#define EUR_CR_BIF_TILE8_MIN_ADDRESS_MASK 0x00000FFFU -+#define EUR_CR_BIF_TILE8_MIN_ADDRESS_SHIFT 0 -+#define EUR_CR_BIF_TILE8_MIN_ADDRESS_SIGNED 0 -+#define EUR_CR_BIF_TILE8_MAX_ADDRESS_MASK 0x00FFF000U -+#define EUR_CR_BIF_TILE8_MAX_ADDRESS_SHIFT 12 -+#define EUR_CR_BIF_TILE8_MAX_ADDRESS_SIGNED 0 -+#define EUR_CR_BIF_TILE8_CFG_MASK 0x0F000000U -+#define EUR_CR_BIF_TILE8_CFG_SHIFT 24 -+#define EUR_CR_BIF_TILE8_CFG_SIGNED 0 -+/* Register EUR_CR_BIF_TILE9 */ -+#define EUR_CR_BIF_TILE9 0x0C30 -+#define EUR_CR_BIF_TILE9_MIN_ADDRESS_MASK 0x00000FFFU -+#define EUR_CR_BIF_TILE9_MIN_ADDRESS_SHIFT 0 -+#define EUR_CR_BIF_TILE9_MIN_ADDRESS_SIGNED 0 -+#define EUR_CR_BIF_TILE9_MAX_ADDRESS_MASK 0x00FFF000U -+#define EUR_CR_BIF_TILE9_MAX_ADDRESS_SHIFT 12 -+#define EUR_CR_BIF_TILE9_MAX_ADDRESS_SIGNED 0 -+#define EUR_CR_BIF_TILE9_CFG_MASK 0x0F000000U -+#define EUR_CR_BIF_TILE9_CFG_SHIFT 24 -+#define EUR_CR_BIF_TILE9_CFG_SIGNED 0 -+/* Register EUR_CR_BIF_CTRL_INVAL */ -+#define EUR_CR_BIF_CTRL_INVAL 0x0C34 -+#define EUR_CR_BIF_CTRL_INVAL_PTE_MASK 0x00000004U -+#define EUR_CR_BIF_CTRL_INVAL_PTE_SHIFT 2 -+#define EUR_CR_BIF_CTRL_INVAL_PTE_SIGNED 0 -+#define EUR_CR_BIF_CTRL_INVAL_ALL_MASK 0x00000008U -+#define EUR_CR_BIF_CTRL_INVAL_ALL_SHIFT 3 -+#define EUR_CR_BIF_CTRL_INVAL_ALL_SIGNED 0 -+/* Register EUR_CR_BIF_DIR_LIST_BASE1 */ -+#define EUR_CR_BIF_DIR_LIST_BASE1 0x0C38 -+#define EUR_CR_BIF_DIR_LIST_BASE1_ADDR_MASK 0xFFFFF000U -+#define EUR_CR_BIF_DIR_LIST_BASE1_ADDR_SHIFT 12 -+#define EUR_CR_BIF_DIR_LIST_BASE1_ADDR_SIGNED 0 -+/* Register EUR_CR_BIF_DIR_LIST_BASE2 */ -+#define EUR_CR_BIF_DIR_LIST_BASE2 0x0C3C -+#define EUR_CR_BIF_DIR_LIST_BASE2_ADDR_MASK 0xFFFFF000U -+#define EUR_CR_BIF_DIR_LIST_BASE2_ADDR_SHIFT 12 -+#define EUR_CR_BIF_DIR_LIST_BASE2_ADDR_SIGNED 0 -+/* Register EUR_CR_BIF_DIR_LIST_BASE3 */ -+#define EUR_CR_BIF_DIR_LIST_BASE3 0x0C40 -+#define EUR_CR_BIF_DIR_LIST_BASE3_ADDR_MASK 0xFFFFF000U -+#define EUR_CR_BIF_DIR_LIST_BASE3_ADDR_SHIFT 12 -+#define EUR_CR_BIF_DIR_LIST_BASE3_ADDR_SIGNED 0 -+/* Register EUR_CR_BIF_DIR_LIST_BASE4 */ -+#define EUR_CR_BIF_DIR_LIST_BASE4 0x0C44 -+#define EUR_CR_BIF_DIR_LIST_BASE4_ADDR_MASK 0xFFFFF000U -+#define EUR_CR_BIF_DIR_LIST_BASE4_ADDR_SHIFT 12 -+#define EUR_CR_BIF_DIR_LIST_BASE4_ADDR_SIGNED 0 -+/* Register EUR_CR_BIF_DIR_LIST_BASE5 */ -+#define EUR_CR_BIF_DIR_LIST_BASE5 0x0C48 -+#define EUR_CR_BIF_DIR_LIST_BASE5_ADDR_MASK 0xFFFFF000U -+#define EUR_CR_BIF_DIR_LIST_BASE5_ADDR_SHIFT 12 -+#define EUR_CR_BIF_DIR_LIST_BASE5_ADDR_SIGNED 0 -+/* Register EUR_CR_BIF_DIR_LIST_BASE6 */ -+#define EUR_CR_BIF_DIR_LIST_BASE6 0x0C4C -+#define EUR_CR_BIF_DIR_LIST_BASE6_ADDR_MASK 0xFFFFF000U -+#define EUR_CR_BIF_DIR_LIST_BASE6_ADDR_SHIFT 12 -+#define EUR_CR_BIF_DIR_LIST_BASE6_ADDR_SIGNED 0 -+/* Register EUR_CR_BIF_DIR_LIST_BASE7 */ -+#define EUR_CR_BIF_DIR_LIST_BASE7 0x0C50 -+#define EUR_CR_BIF_DIR_LIST_BASE7_ADDR_MASK 0xFFFFF000U -+#define EUR_CR_BIF_DIR_LIST_BASE7_ADDR_SHIFT 12 -+#define EUR_CR_BIF_DIR_LIST_BASE7_ADDR_SIGNED 0 -+/* Register EUR_CR_BIF_BANK_SET */ -+#define EUR_CR_BIF_BANK_SET 0x0C74 -+#define EUR_CR_BIF_BANK_SET_SELECT_2D_MASK 0x00000001U -+#define EUR_CR_BIF_BANK_SET_SELECT_2D_SHIFT 0 -+#define EUR_CR_BIF_BANK_SET_SELECT_2D_SIGNED 0 -+#define EUR_CR_BIF_BANK_SET_SELECT_3D_MASK 0x0000000CU -+#define EUR_CR_BIF_BANK_SET_SELECT_3D_SHIFT 2 -+#define EUR_CR_BIF_BANK_SET_SELECT_3D_SIGNED 0 -+#define EUR_CR_BIF_BANK_SET_SELECT_HOST_MASK 0x00000010U -+#define EUR_CR_BIF_BANK_SET_SELECT_HOST_SHIFT 4 -+#define EUR_CR_BIF_BANK_SET_SELECT_HOST_SIGNED 0 -+#define EUR_CR_BIF_BANK_SET_SELECT_TA_MASK 0x000000C0U -+#define EUR_CR_BIF_BANK_SET_SELECT_TA_SHIFT 6 -+#define EUR_CR_BIF_BANK_SET_SELECT_TA_SIGNED 0 -+#define EUR_CR_BIF_BANK_SET_SELECT_EDM_MASK 0x00000100U -+#define EUR_CR_BIF_BANK_SET_SELECT_EDM_SHIFT 8 -+#define EUR_CR_BIF_BANK_SET_SELECT_EDM_SIGNED 0 -+#define EUR_CR_BIF_BANK_SET_SELECT_DPM_LSS_MASK 0x00000200U -+#define EUR_CR_BIF_BANK_SET_SELECT_DPM_LSS_SHIFT 9 -+#define EUR_CR_BIF_BANK_SET_SELECT_DPM_LSS_SIGNED 0 -+/* Register EUR_CR_BIF_BANK0 */ -+#define EUR_CR_BIF_BANK0 0x0C78 -+#define EUR_CR_BIF_BANK0_INDEX_EDM_MASK 0x0000000FU -+#define EUR_CR_BIF_BANK0_INDEX_EDM_SHIFT 0 -+#define EUR_CR_BIF_BANK0_INDEX_EDM_SIGNED 0 -+#define EUR_CR_BIF_BANK0_INDEX_TA_MASK 0x000000F0U -+#define EUR_CR_BIF_BANK0_INDEX_TA_SHIFT 4 -+#define EUR_CR_BIF_BANK0_INDEX_TA_SIGNED 0 -+#define EUR_CR_BIF_BANK0_INDEX_3D_MASK 0x0000F000U -+#define EUR_CR_BIF_BANK0_INDEX_3D_SHIFT 12 -+#define EUR_CR_BIF_BANK0_INDEX_3D_SIGNED 0 -+#define EUR_CR_BIF_BANK0_INDEX_PTLA_MASK 0x000F0000U -+#define EUR_CR_BIF_BANK0_INDEX_PTLA_SHIFT 16 -+#define EUR_CR_BIF_BANK0_INDEX_PTLA_SIGNED 0 -+/* Register EUR_CR_BIF_BANK1 */ -+#define EUR_CR_BIF_BANK1 0x0C7C -+#define EUR_CR_BIF_BANK1_INDEX_EDM_MASK 0x0000000FU -+#define EUR_CR_BIF_BANK1_INDEX_EDM_SHIFT 0 -+#define EUR_CR_BIF_BANK1_INDEX_EDM_SIGNED 0 -+#define EUR_CR_BIF_BANK1_INDEX_TA_MASK 0x000000F0U -+#define EUR_CR_BIF_BANK1_INDEX_TA_SHIFT 4 -+#define EUR_CR_BIF_BANK1_INDEX_TA_SIGNED 0 -+#define EUR_CR_BIF_BANK1_INDEX_3D_MASK 0x0000F000U -+#define EUR_CR_BIF_BANK1_INDEX_3D_SHIFT 12 -+#define EUR_CR_BIF_BANK1_INDEX_3D_SIGNED 0 -+/* Register EUR_CR_BIF_DIR_LIST_BASE0 */ -+#define EUR_CR_BIF_DIR_LIST_BASE0 0x0C84 -+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_MASK 0xFFFFF000U -+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_SHIFT 12 -+#define EUR_CR_BIF_DIR_LIST_BASE0_ADDR_SIGNED 0 -+/* Register EUR_CR_BIF_TA_REQ_BASE */ -+#define EUR_CR_BIF_TA_REQ_BASE 0x0C90 -+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_MASK 0xFFF00000U -+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_SHIFT 20 -+#define EUR_CR_BIF_TA_REQ_BASE_ADDR_SIGNED 0 -+/* Register EUR_CR_BIF_MEM_REQ_STAT */ -+#define EUR_CR_BIF_MEM_REQ_STAT 0x0CA8 -+#define EUR_CR_BIF_MEM_REQ_STAT_READS_MASK 0x000000FFU -+#define EUR_CR_BIF_MEM_REQ_STAT_READS_SHIFT 0 -+#define EUR_CR_BIF_MEM_REQ_STAT_READS_SIGNED 0 -+/* Register EUR_CR_BIF_3D_REQ_BASE */ -+#define EUR_CR_BIF_3D_REQ_BASE 0x0CAC -+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_MASK 0xFFF00000U -+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_SHIFT 20 -+#define EUR_CR_BIF_3D_REQ_BASE_ADDR_SIGNED 0 -+/* Register EUR_CR_BIF_ZLS_REQ_BASE */ -+#define EUR_CR_BIF_ZLS_REQ_BASE 0x0CB0 -+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_MASK 0xFFF00000U -+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_SHIFT 20 -+#define EUR_CR_BIF_ZLS_REQ_BASE_ADDR_SIGNED 0 -+/* Register EUR_CR_BIF_BANK_STATUS */ -+#define EUR_CR_BIF_BANK_STATUS 0x0CB4 -+#define EUR_CR_BIF_BANK_STATUS_3D_CURRENT_BANK_MASK 0x00000001U -+#define EUR_CR_BIF_BANK_STATUS_3D_CURRENT_BANK_SHIFT 0 -+#define EUR_CR_BIF_BANK_STATUS_3D_CURRENT_BANK_SIGNED 0 -+#define EUR_CR_BIF_BANK_STATUS_TA_CURRENT_BANK_MASK 0x00000002U -+#define EUR_CR_BIF_BANK_STATUS_TA_CURRENT_BANK_SHIFT 1 -+#define EUR_CR_BIF_BANK_STATUS_TA_CURRENT_BANK_SIGNED 0 -+/* Register EUR_CR_BIF_MMU_CTRL */ -+#define EUR_CR_BIF_MMU_CTRL 0x0CD0 -+#define EUR_CR_BIF_MMU_CTRL_PREFETCHING_ON_MASK 0x00000001U -+#define EUR_CR_BIF_MMU_CTRL_PREFETCHING_ON_SHIFT 0 -+#define EUR_CR_BIF_MMU_CTRL_PREFETCHING_ON_SIGNED 0 -+#define EUR_CR_BIF_MMU_CTRL_ADDR_HASH_MODE_MASK 0x00000006U -+#define EUR_CR_BIF_MMU_CTRL_ADDR_HASH_MODE_SHIFT 1 -+#define EUR_CR_BIF_MMU_CTRL_ADDR_HASH_MODE_SIGNED 0 -+#define EUR_CR_BIF_MMU_CTRL_ENABLE_WRITE_BURST_COLLATE_MASK 0x00000008U -+#define EUR_CR_BIF_MMU_CTRL_ENABLE_WRITE_BURST_COLLATE_SHIFT 3 -+#define EUR_CR_BIF_MMU_CTRL_ENABLE_WRITE_BURST_COLLATE_SIGNED 0 -+#define EUR_CR_BIF_MMU_CTRL_ENABLE_DC_TLB_MASK 0x00000010U -+#define EUR_CR_BIF_MMU_CTRL_ENABLE_DC_TLB_SHIFT 4 -+#define EUR_CR_BIF_MMU_CTRL_ENABLE_DC_TLB_SIGNED 0 -+#define EUR_CR_BIF_MMU_CTRL_DISABLE_BURST_EXP_MASK 0x00000020U -+#define EUR_CR_BIF_MMU_CTRL_DISABLE_BURST_EXP_SHIFT 5 -+#define EUR_CR_BIF_MMU_CTRL_DISABLE_BURST_EXP_SIGNED 0 -+/* Register EUR_CR_2D_BLIT_STATUS */ -+#define EUR_CR_2D_BLIT_STATUS 0x0E04 -+#define EUR_CR_2D_BLIT_STATUS_COMPLETE_MASK 0x00FFFFFFU -+#define EUR_CR_2D_BLIT_STATUS_COMPLETE_SHIFT 0 -+#define EUR_CR_2D_BLIT_STATUS_COMPLETE_SIGNED 0 -+#define EUR_CR_2D_BLIT_STATUS_BUSY_MASK 0x01000000U -+#define EUR_CR_2D_BLIT_STATUS_BUSY_SHIFT 24 -+#define EUR_CR_2D_BLIT_STATUS_BUSY_SIGNED 0 -+/* Register EUR_CR_2D_VIRTUAL_FIFO_0 */ -+#define EUR_CR_2D_VIRTUAL_FIFO_0 0x0E10 -+#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_MASK 0x00000001U -+#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_SHIFT 0 -+#define EUR_CR_2D_VIRTUAL_FIFO_0_ENABLE_SIGNED 0 -+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MASK 0x0000000EU -+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_SHIFT 1 -+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_SIGNED 0 -+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_MASK 0x00000FF0U -+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_SHIFT 4 -+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_DIV_SIGNED 0 -+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_MASK 0x0000F000U -+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_SHIFT 12 -+#define EUR_CR_2D_VIRTUAL_FIFO_0_FLOWRATE_MUL_SIGNED 0 -+/* Register EUR_CR_2D_VIRTUAL_FIFO_1 */ -+#define EUR_CR_2D_VIRTUAL_FIFO_1 0x0E14 -+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_MASK 0x00000FFFU -+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_SHIFT 0 -+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_ACC_SIGNED 0 -+#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_MASK 0x00FFF000U -+#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_SHIFT 12 -+#define EUR_CR_2D_VIRTUAL_FIFO_1_MAX_ACC_SIGNED 0 -+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_MASK 0xFF000000U -+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_SHIFT 24 -+#define EUR_CR_2D_VIRTUAL_FIFO_1_MIN_METRIC_SIGNED 0 -+/* Register EUR_CR_BREAKPOINT0_START */ -+#define EUR_CR_BREAKPOINT0_START 0x0F44 -+#define EUR_CR_BREAKPOINT0_START_ADDRESS_MASK 0xFFFFFFF0U -+#define EUR_CR_BREAKPOINT0_START_ADDRESS_SHIFT 4 -+#define EUR_CR_BREAKPOINT0_START_ADDRESS_SIGNED 0 -+/* Register EUR_CR_BREAKPOINT0_END */ -+#define EUR_CR_BREAKPOINT0_END 0x0F48 -+#define EUR_CR_BREAKPOINT0_END_ADDRESS_MASK 0xFFFFFFF0U -+#define EUR_CR_BREAKPOINT0_END_ADDRESS_SHIFT 4 -+#define EUR_CR_BREAKPOINT0_END_ADDRESS_SIGNED 0 -+/* Register EUR_CR_BREAKPOINT0 */ -+#define EUR_CR_BREAKPOINT0 0x0F4C -+#define EUR_CR_BREAKPOINT0_MASK_DM_MASK 0x00000038U -+#define EUR_CR_BREAKPOINT0_MASK_DM_SHIFT 3 -+#define EUR_CR_BREAKPOINT0_MASK_DM_SIGNED 0 -+#define EUR_CR_BREAKPOINT0_CTRL_TRAPENABLE_MASK 0x00000004U -+#define EUR_CR_BREAKPOINT0_CTRL_TRAPENABLE_SHIFT 2 -+#define EUR_CR_BREAKPOINT0_CTRL_TRAPENABLE_SIGNED 0 -+#define EUR_CR_BREAKPOINT0_CTRL_WENABLE_MASK 0x00000002U -+#define EUR_CR_BREAKPOINT0_CTRL_WENABLE_SHIFT 1 -+#define EUR_CR_BREAKPOINT0_CTRL_WENABLE_SIGNED 0 -+#define EUR_CR_BREAKPOINT0_CTRL_RENABLE_MASK 0x00000001U -+#define EUR_CR_BREAKPOINT0_CTRL_RENABLE_SHIFT 0 -+#define EUR_CR_BREAKPOINT0_CTRL_RENABLE_SIGNED 0 -+/* Register EUR_CR_BREAKPOINT1_START */ -+#define EUR_CR_BREAKPOINT1_START 0x0F50 -+#define EUR_CR_BREAKPOINT1_START_ADDRESS_MASK 0xFFFFFFF0U -+#define EUR_CR_BREAKPOINT1_START_ADDRESS_SHIFT 4 -+#define EUR_CR_BREAKPOINT1_START_ADDRESS_SIGNED 0 -+/* Register EUR_CR_BREAKPOINT1_END */ -+#define EUR_CR_BREAKPOINT1_END 0x0F54 -+#define EUR_CR_BREAKPOINT1_END_ADDRESS_MASK 0xFFFFFFF0U -+#define EUR_CR_BREAKPOINT1_END_ADDRESS_SHIFT 4 -+#define EUR_CR_BREAKPOINT1_END_ADDRESS_SIGNED 0 -+/* Register EUR_CR_BREAKPOINT1 */ -+#define EUR_CR_BREAKPOINT1 0x0F58 -+#define EUR_CR_BREAKPOINT1_MASK_DM_MASK 0x00000038U -+#define EUR_CR_BREAKPOINT1_MASK_DM_SHIFT 3 -+#define EUR_CR_BREAKPOINT1_MASK_DM_SIGNED 0 -+#define EUR_CR_BREAKPOINT1_CTRL_TRAPENABLE_MASK 0x00000004U -+#define EUR_CR_BREAKPOINT1_CTRL_TRAPENABLE_SHIFT 2 -+#define EUR_CR_BREAKPOINT1_CTRL_TRAPENABLE_SIGNED 0 -+#define EUR_CR_BREAKPOINT1_CTRL_WENABLE_MASK 0x00000002U -+#define EUR_CR_BREAKPOINT1_CTRL_WENABLE_SHIFT 1 -+#define EUR_CR_BREAKPOINT1_CTRL_WENABLE_SIGNED 0 -+#define EUR_CR_BREAKPOINT1_CTRL_RENABLE_MASK 0x00000001U -+#define EUR_CR_BREAKPOINT1_CTRL_RENABLE_SHIFT 0 -+#define EUR_CR_BREAKPOINT1_CTRL_RENABLE_SIGNED 0 -+/* Register EUR_CR_BREAKPOINT2_START */ -+#define EUR_CR_BREAKPOINT2_START 0x0F5C -+#define EUR_CR_BREAKPOINT2_START_ADDRESS_MASK 0xFFFFFFF0U -+#define EUR_CR_BREAKPOINT2_START_ADDRESS_SHIFT 4 -+#define EUR_CR_BREAKPOINT2_START_ADDRESS_SIGNED 0 -+/* Register EUR_CR_BREAKPOINT2_END */ -+#define EUR_CR_BREAKPOINT2_END 0x0F60 -+#define EUR_CR_BREAKPOINT2_END_ADDRESS_MASK 0xFFFFFFF0U -+#define EUR_CR_BREAKPOINT2_END_ADDRESS_SHIFT 4 -+#define EUR_CR_BREAKPOINT2_END_ADDRESS_SIGNED 0 -+/* Register EUR_CR_BREAKPOINT2 */ -+#define EUR_CR_BREAKPOINT2 0x0F64 -+#define EUR_CR_BREAKPOINT2_MASK_DM_MASK 0x00000038U -+#define EUR_CR_BREAKPOINT2_MASK_DM_SHIFT 3 -+#define EUR_CR_BREAKPOINT2_MASK_DM_SIGNED 0 -+#define EUR_CR_BREAKPOINT2_CTRL_TRAPENABLE_MASK 0x00000004U -+#define EUR_CR_BREAKPOINT2_CTRL_TRAPENABLE_SHIFT 2 -+#define EUR_CR_BREAKPOINT2_CTRL_TRAPENABLE_SIGNED 0 -+#define EUR_CR_BREAKPOINT2_CTRL_WENABLE_MASK 0x00000002U -+#define EUR_CR_BREAKPOINT2_CTRL_WENABLE_SHIFT 1 -+#define EUR_CR_BREAKPOINT2_CTRL_WENABLE_SIGNED 0 -+#define EUR_CR_BREAKPOINT2_CTRL_RENABLE_MASK 0x00000001U -+#define EUR_CR_BREAKPOINT2_CTRL_RENABLE_SHIFT 0 -+#define EUR_CR_BREAKPOINT2_CTRL_RENABLE_SIGNED 0 -+/* Register EUR_CR_BREAKPOINT3_START */ -+#define EUR_CR_BREAKPOINT3_START 0x0F68 -+#define EUR_CR_BREAKPOINT3_START_ADDRESS_MASK 0xFFFFFFF0U -+#define EUR_CR_BREAKPOINT3_START_ADDRESS_SHIFT 4 -+#define EUR_CR_BREAKPOINT3_START_ADDRESS_SIGNED 0 -+/* Register EUR_CR_BREAKPOINT3_END */ -+#define EUR_CR_BREAKPOINT3_END 0x0F6C -+#define EUR_CR_BREAKPOINT3_END_ADDRESS_MASK 0xFFFFFFF0U -+#define EUR_CR_BREAKPOINT3_END_ADDRESS_SHIFT 4 -+#define EUR_CR_BREAKPOINT3_END_ADDRESS_SIGNED 0 -+/* Register EUR_CR_BREAKPOINT3 */ -+#define EUR_CR_BREAKPOINT3 0x0F70 -+#define EUR_CR_BREAKPOINT3_MASK_DM_MASK 0x00000038U -+#define EUR_CR_BREAKPOINT3_MASK_DM_SHIFT 3 -+#define EUR_CR_BREAKPOINT3_MASK_DM_SIGNED 0 -+#define EUR_CR_BREAKPOINT3_CTRL_TRAPENABLE_MASK 0x00000004U -+#define EUR_CR_BREAKPOINT3_CTRL_TRAPENABLE_SHIFT 2 -+#define EUR_CR_BREAKPOINT3_CTRL_TRAPENABLE_SIGNED 0 -+#define EUR_CR_BREAKPOINT3_CTRL_WENABLE_MASK 0x00000002U -+#define EUR_CR_BREAKPOINT3_CTRL_WENABLE_SHIFT 1 -+#define EUR_CR_BREAKPOINT3_CTRL_WENABLE_SIGNED 0 -+#define EUR_CR_BREAKPOINT3_CTRL_RENABLE_MASK 0x00000001U -+#define EUR_CR_BREAKPOINT3_CTRL_RENABLE_SHIFT 0 -+#define EUR_CR_BREAKPOINT3_CTRL_RENABLE_SIGNED 0 -+/* Register EUR_CR_BREAKPOINT_READ */ -+#define EUR_CR_BREAKPOINT_READ 0x0F74 -+#define EUR_CR_BREAKPOINT_READ_ADDRESS_MASK 0xFFFFFFF0U -+#define EUR_CR_BREAKPOINT_READ_ADDRESS_SHIFT 4 -+#define EUR_CR_BREAKPOINT_READ_ADDRESS_SIGNED 0 -+/* Register EUR_CR_PARTITION_BREAKPOINT_TRAP */ -+#define EUR_CR_PARTITION_BREAKPOINT_TRAP 0x0F78 -+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_CONTINUE_MASK 0x00000002U -+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_CONTINUE_SHIFT 1 -+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_CONTINUE_SIGNED 0 -+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_WRNOTIFY_MASK 0x00000001U -+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_WRNOTIFY_SHIFT 0 -+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_WRNOTIFY_SIGNED 0 -+/* Register EUR_CR_PARTITION_BREAKPOINT */ -+#define EUR_CR_PARTITION_BREAKPOINT 0x0F7C -+#define EUR_CR_PARTITION_BREAKPOINT_MODULE_ID_MASK 0x000003C0U -+#define EUR_CR_PARTITION_BREAKPOINT_MODULE_ID_SHIFT 6 -+#define EUR_CR_PARTITION_BREAKPOINT_MODULE_ID_SIGNED 0 -+#define EUR_CR_PARTITION_BREAKPOINT_ID_MASK 0x00000030U -+#define EUR_CR_PARTITION_BREAKPOINT_ID_SHIFT 4 -+#define EUR_CR_PARTITION_BREAKPOINT_ID_SIGNED 0 -+#define EUR_CR_PARTITION_BREAKPOINT_UNTRAPPED_MASK 0x00000008U -+#define EUR_CR_PARTITION_BREAKPOINT_UNTRAPPED_SHIFT 3 -+#define EUR_CR_PARTITION_BREAKPOINT_UNTRAPPED_SIGNED 0 -+#define EUR_CR_PARTITION_BREAKPOINT_TRAPPED_MASK 0x00000004U -+#define EUR_CR_PARTITION_BREAKPOINT_TRAPPED_SHIFT 2 -+#define EUR_CR_PARTITION_BREAKPOINT_TRAPPED_SIGNED 0 -+/* Register EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO0 */ -+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO0 0x0F80 -+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO0_ADDRESS_MASK 0xFFFFFFF0U -+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO0_ADDRESS_SHIFT 4 -+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO0_ADDRESS_SIGNED 0 -+/* Register EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1 */ -+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1 0x0F84 -+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_SIZE_MASK 0x00007C00U -+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_SIZE_SHIFT 10 -+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_SIZE_SIGNED 0 -+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_NUMBER_MASK 0x00000300U -+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_NUMBER_SHIFT 8 -+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_NUMBER_SIGNED 0 -+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_TAG_MASK 0x000000F8U -+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_TAG_SHIFT 3 -+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_TAG_SIGNED 0 -+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_DATA_MASTER_MASK 0x00000006U -+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_DATA_MASTER_SHIFT 1 -+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_DATA_MASTER_SIGNED 0 -+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_RNW_MASK 0x00000001U -+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_RNW_SHIFT 0 -+#define EUR_CR_PARTITION_BREAKPOINT_TRAP_INFO1_RNW_SIGNED 0 -+/* Register EUR_CR_USE_CODE_BASE_0 */ -+#define EUR_CR_USE_CODE_BASE_0 0x0A0C -+#define EUR_CR_USE_CODE_BASE_ADDR_00_MASK 0x03FFFFFFU -+#define EUR_CR_USE_CODE_BASE_ADDR_00_SHIFT 0 -+#define EUR_CR_USE_CODE_BASE_ADDR_00_SIGNED 0 -+#define EUR_CR_USE_CODE_BASE_DM_00_MASK 0x0C000000U -+#define EUR_CR_USE_CODE_BASE_DM_00_SHIFT 26 -+#define EUR_CR_USE_CODE_BASE_DM_00_SIGNED 0 -+/* Register EUR_CR_USE_CODE_BASE_1 */ -+#define EUR_CR_USE_CODE_BASE_1 0x0A10 -+#define EUR_CR_USE_CODE_BASE_ADDR_01_MASK 0x03FFFFFFU -+#define EUR_CR_USE_CODE_BASE_ADDR_01_SHIFT 0 -+#define EUR_CR_USE_CODE_BASE_ADDR_01_SIGNED 0 -+#define EUR_CR_USE_CODE_BASE_DM_01_MASK 0x0C000000U -+#define EUR_CR_USE_CODE_BASE_DM_01_SHIFT 26 -+#define EUR_CR_USE_CODE_BASE_DM_01_SIGNED 0 -+/* Register EUR_CR_USE_CODE_BASE_2 */ -+#define EUR_CR_USE_CODE_BASE_2 0x0A14 -+#define EUR_CR_USE_CODE_BASE_ADDR_02_MASK 0x03FFFFFFU -+#define EUR_CR_USE_CODE_BASE_ADDR_02_SHIFT 0 -+#define EUR_CR_USE_CODE_BASE_ADDR_02_SIGNED 0 -+#define EUR_CR_USE_CODE_BASE_DM_02_MASK 0x0C000000U -+#define EUR_CR_USE_CODE_BASE_DM_02_SHIFT 26 -+#define EUR_CR_USE_CODE_BASE_DM_02_SIGNED 0 -+/* Register EUR_CR_USE_CODE_BASE_3 */ -+#define EUR_CR_USE_CODE_BASE_3 0x0A18 -+#define EUR_CR_USE_CODE_BASE_ADDR_03_MASK 0x03FFFFFFU -+#define EUR_CR_USE_CODE_BASE_ADDR_03_SHIFT 0 -+#define EUR_CR_USE_CODE_BASE_ADDR_03_SIGNED 0 -+#define EUR_CR_USE_CODE_BASE_DM_03_MASK 0x0C000000U -+#define EUR_CR_USE_CODE_BASE_DM_03_SHIFT 26 -+#define EUR_CR_USE_CODE_BASE_DM_03_SIGNED 0 -+/* Register EUR_CR_USE_CODE_BASE_4 */ -+#define EUR_CR_USE_CODE_BASE_4 0x0A1C -+#define EUR_CR_USE_CODE_BASE_ADDR_04_MASK 0x03FFFFFFU -+#define EUR_CR_USE_CODE_BASE_ADDR_04_SHIFT 0 -+#define EUR_CR_USE_CODE_BASE_ADDR_04_SIGNED 0 -+#define EUR_CR_USE_CODE_BASE_DM_04_MASK 0x0C000000U -+#define EUR_CR_USE_CODE_BASE_DM_04_SHIFT 26 -+#define EUR_CR_USE_CODE_BASE_DM_04_SIGNED 0 -+/* Register EUR_CR_USE_CODE_BASE_5 */ -+#define EUR_CR_USE_CODE_BASE_5 0x0A20 -+#define EUR_CR_USE_CODE_BASE_ADDR_05_MASK 0x03FFFFFFU -+#define EUR_CR_USE_CODE_BASE_ADDR_05_SHIFT 0 -+#define EUR_CR_USE_CODE_BASE_ADDR_05_SIGNED 0 -+#define EUR_CR_USE_CODE_BASE_DM_05_MASK 0x0C000000U -+#define EUR_CR_USE_CODE_BASE_DM_05_SHIFT 26 -+#define EUR_CR_USE_CODE_BASE_DM_05_SIGNED 0 -+/* Register EUR_CR_USE_CODE_BASE_6 */ -+#define EUR_CR_USE_CODE_BASE_6 0x0A24 -+#define EUR_CR_USE_CODE_BASE_ADDR_06_MASK 0x03FFFFFFU -+#define EUR_CR_USE_CODE_BASE_ADDR_06_SHIFT 0 -+#define EUR_CR_USE_CODE_BASE_ADDR_06_SIGNED 0 -+#define EUR_CR_USE_CODE_BASE_DM_06_MASK 0x0C000000U -+#define EUR_CR_USE_CODE_BASE_DM_06_SHIFT 26 -+#define EUR_CR_USE_CODE_BASE_DM_06_SIGNED 0 -+/* Register EUR_CR_USE_CODE_BASE_7 */ -+#define EUR_CR_USE_CODE_BASE_7 0x0A28 -+#define EUR_CR_USE_CODE_BASE_ADDR_07_MASK 0x03FFFFFFU -+#define EUR_CR_USE_CODE_BASE_ADDR_07_SHIFT 0 -+#define EUR_CR_USE_CODE_BASE_ADDR_07_SIGNED 0 -+#define EUR_CR_USE_CODE_BASE_DM_07_MASK 0x0C000000U -+#define EUR_CR_USE_CODE_BASE_DM_07_SHIFT 26 -+#define EUR_CR_USE_CODE_BASE_DM_07_SIGNED 0 -+/* Register EUR_CR_USE_CODE_BASE_8 */ -+#define EUR_CR_USE_CODE_BASE_8 0x0A2C -+#define EUR_CR_USE_CODE_BASE_ADDR_08_MASK 0x03FFFFFFU -+#define EUR_CR_USE_CODE_BASE_ADDR_08_SHIFT 0 -+#define EUR_CR_USE_CODE_BASE_ADDR_08_SIGNED 0 -+#define EUR_CR_USE_CODE_BASE_DM_08_MASK 0x0C000000U -+#define EUR_CR_USE_CODE_BASE_DM_08_SHIFT 26 -+#define EUR_CR_USE_CODE_BASE_DM_08_SIGNED 0 -+/* Register EUR_CR_USE_CODE_BASE_9 */ -+#define EUR_CR_USE_CODE_BASE_9 0x0A30 -+#define EUR_CR_USE_CODE_BASE_ADDR_09_MASK 0x03FFFFFFU -+#define EUR_CR_USE_CODE_BASE_ADDR_09_SHIFT 0 -+#define EUR_CR_USE_CODE_BASE_ADDR_09_SIGNED 0 -+#define EUR_CR_USE_CODE_BASE_DM_09_MASK 0x0C000000U -+#define EUR_CR_USE_CODE_BASE_DM_09_SHIFT 26 -+#define EUR_CR_USE_CODE_BASE_DM_09_SIGNED 0 -+/* Register EUR_CR_USE_CODE_BASE_10 */ -+#define EUR_CR_USE_CODE_BASE_10 0x0A34 -+#define EUR_CR_USE_CODE_BASE_ADDR_10_MASK 0x03FFFFFFU -+#define EUR_CR_USE_CODE_BASE_ADDR_10_SHIFT 0 -+#define EUR_CR_USE_CODE_BASE_ADDR_10_SIGNED 0 -+#define EUR_CR_USE_CODE_BASE_DM_10_MASK 0x0C000000U -+#define EUR_CR_USE_CODE_BASE_DM_10_SHIFT 26 -+#define EUR_CR_USE_CODE_BASE_DM_10_SIGNED 0 -+/* Register EUR_CR_USE_CODE_BASE_11 */ -+#define EUR_CR_USE_CODE_BASE_11 0x0A38 -+#define EUR_CR_USE_CODE_BASE_ADDR_11_MASK 0x03FFFFFFU -+#define EUR_CR_USE_CODE_BASE_ADDR_11_SHIFT 0 -+#define EUR_CR_USE_CODE_BASE_ADDR_11_SIGNED 0 -+#define EUR_CR_USE_CODE_BASE_DM_11_MASK 0x0C000000U -+#define EUR_CR_USE_CODE_BASE_DM_11_SHIFT 26 -+#define EUR_CR_USE_CODE_BASE_DM_11_SIGNED 0 -+/* Register EUR_CR_USE_CODE_BASE_12 */ -+#define EUR_CR_USE_CODE_BASE_12 0x0A3C -+#define EUR_CR_USE_CODE_BASE_ADDR_12_MASK 0x03FFFFFFU -+#define EUR_CR_USE_CODE_BASE_ADDR_12_SHIFT 0 -+#define EUR_CR_USE_CODE_BASE_ADDR_12_SIGNED 0 -+#define EUR_CR_USE_CODE_BASE_DM_12_MASK 0x0C000000U -+#define EUR_CR_USE_CODE_BASE_DM_12_SHIFT 26 -+#define EUR_CR_USE_CODE_BASE_DM_12_SIGNED 0 -+/* Register EUR_CR_USE_CODE_BASE_13 */ -+#define EUR_CR_USE_CODE_BASE_13 0x0A40 -+#define EUR_CR_USE_CODE_BASE_ADDR_13_MASK 0x03FFFFFFU -+#define EUR_CR_USE_CODE_BASE_ADDR_13_SHIFT 0 -+#define EUR_CR_USE_CODE_BASE_ADDR_13_SIGNED 0 -+#define EUR_CR_USE_CODE_BASE_DM_13_MASK 0x0C000000U -+#define EUR_CR_USE_CODE_BASE_DM_13_SHIFT 26 -+#define EUR_CR_USE_CODE_BASE_DM_13_SIGNED 0 -+/* Register EUR_CR_USE_CODE_BASE_14 */ -+#define EUR_CR_USE_CODE_BASE_14 0x0A44 -+#define EUR_CR_USE_CODE_BASE_ADDR_14_MASK 0x03FFFFFFU -+#define EUR_CR_USE_CODE_BASE_ADDR_14_SHIFT 0 -+#define EUR_CR_USE_CODE_BASE_ADDR_14_SIGNED 0 -+#define EUR_CR_USE_CODE_BASE_DM_14_MASK 0x0C000000U -+#define EUR_CR_USE_CODE_BASE_DM_14_SHIFT 26 -+#define EUR_CR_USE_CODE_BASE_DM_14_SIGNED 0 -+/* Register EUR_CR_USE_CODE_BASE_15 */ -+#define EUR_CR_USE_CODE_BASE_15 0x0A48 -+#define EUR_CR_USE_CODE_BASE_ADDR_15_MASK 0x03FFFFFFU -+#define EUR_CR_USE_CODE_BASE_ADDR_15_SHIFT 0 -+#define EUR_CR_USE_CODE_BASE_ADDR_15_SIGNED 0 -+#define EUR_CR_USE_CODE_BASE_DM_15_MASK 0x0C000000U -+#define EUR_CR_USE_CODE_BASE_DM_15_SHIFT 26 -+#define EUR_CR_USE_CODE_BASE_DM_15_SIGNED 0 -+/* Register EUR_CR_PIPE0_BREAKPOINT_TRAP */ -+#define EUR_CR_PIPE0_BREAKPOINT_TRAP 0x0F88 -+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_CONTINUE_MASK 0x00000002U -+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_CONTINUE_SHIFT 1 -+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_CONTINUE_SIGNED 0 -+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_WRNOTIFY_MASK 0x00000001U -+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_WRNOTIFY_SHIFT 0 -+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_WRNOTIFY_SIGNED 0 -+/* Register EUR_CR_PIPE0_BREAKPOINT */ -+#define EUR_CR_PIPE0_BREAKPOINT 0x0F8C -+#define EUR_CR_PIPE0_BREAKPOINT_MODULE_ID_MASK 0x000003C0U -+#define EUR_CR_PIPE0_BREAKPOINT_MODULE_ID_SHIFT 6 -+#define EUR_CR_PIPE0_BREAKPOINT_MODULE_ID_SIGNED 0 -+#define EUR_CR_PIPE0_BREAKPOINT_ID_MASK 0x00000030U -+#define EUR_CR_PIPE0_BREAKPOINT_ID_SHIFT 4 -+#define EUR_CR_PIPE0_BREAKPOINT_ID_SIGNED 0 -+#define EUR_CR_PIPE0_BREAKPOINT_UNTRAPPED_MASK 0x00000008U -+#define EUR_CR_PIPE0_BREAKPOINT_UNTRAPPED_SHIFT 3 -+#define EUR_CR_PIPE0_BREAKPOINT_UNTRAPPED_SIGNED 0 -+#define EUR_CR_PIPE0_BREAKPOINT_TRAPPED_MASK 0x00000004U -+#define EUR_CR_PIPE0_BREAKPOINT_TRAPPED_SHIFT 2 -+#define EUR_CR_PIPE0_BREAKPOINT_TRAPPED_SIGNED 0 -+/* Register EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO0 */ -+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO0 0x0F90 -+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO0_ADDRESS_MASK 0xFFFFFFF0U -+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO0_ADDRESS_SHIFT 4 -+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO0_ADDRESS_SIGNED 0 -+/* Register EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1 */ -+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1 0x0F94 -+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_SIZE_MASK 0x00007C00U -+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_SIZE_SHIFT 10 -+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_SIZE_SIGNED 0 -+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_NUMBER_MASK 0x00000300U -+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_NUMBER_SHIFT 8 -+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_NUMBER_SIGNED 0 -+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_TAG_MASK 0x000000F8U -+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_TAG_SHIFT 3 -+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_TAG_SIGNED 0 -+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_DATA_MASTER_MASK 0x00000006U -+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_DATA_MASTER_SHIFT 1 -+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_DATA_MASTER_SIGNED 0 -+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_RNW_MASK 0x00000001U -+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_RNW_SHIFT 0 -+#define EUR_CR_PIPE0_BREAKPOINT_TRAP_INFO1_RNW_SIGNED 0 -+/* Register EUR_CR_PIPE1_BREAKPOINT_TRAP */ -+#define EUR_CR_PIPE1_BREAKPOINT_TRAP 0x0F98 -+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_CONTINUE_MASK 0x00000002U -+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_CONTINUE_SHIFT 1 -+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_CONTINUE_SIGNED 0 -+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_WRNOTIFY_MASK 0x00000001U -+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_WRNOTIFY_SHIFT 0 -+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_WRNOTIFY_SIGNED 0 -+/* Register EUR_CR_PIPE1_BREAKPOINT */ -+#define EUR_CR_PIPE1_BREAKPOINT 0x0F9C -+#define EUR_CR_PIPE1_BREAKPOINT_MODULE_ID_MASK 0x000003C0U -+#define EUR_CR_PIPE1_BREAKPOINT_MODULE_ID_SHIFT 6 -+#define EUR_CR_PIPE1_BREAKPOINT_MODULE_ID_SIGNED 0 -+#define EUR_CR_PIPE1_BREAKPOINT_ID_MASK 0x00000030U -+#define EUR_CR_PIPE1_BREAKPOINT_ID_SHIFT 4 -+#define EUR_CR_PIPE1_BREAKPOINT_ID_SIGNED 0 -+#define EUR_CR_PIPE1_BREAKPOINT_UNTRAPPED_MASK 0x00000008U -+#define EUR_CR_PIPE1_BREAKPOINT_UNTRAPPED_SHIFT 3 -+#define EUR_CR_PIPE1_BREAKPOINT_UNTRAPPED_SIGNED 0 -+#define EUR_CR_PIPE1_BREAKPOINT_TRAPPED_MASK 0x00000004U -+#define EUR_CR_PIPE1_BREAKPOINT_TRAPPED_SHIFT 2 -+#define EUR_CR_PIPE1_BREAKPOINT_TRAPPED_SIGNED 0 -+/* Register EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO0 */ -+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO0 0x0FA0 -+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO0_ADDRESS_MASK 0xFFFFFFF0U -+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO0_ADDRESS_SHIFT 4 -+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO0_ADDRESS_SIGNED 0 -+/* Register EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1 */ -+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1 0x0FA4 -+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_SIZE_MASK 0x00007C00U -+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_SIZE_SHIFT 10 -+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_SIZE_SIGNED 0 -+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_NUMBER_MASK 0x00000300U -+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_NUMBER_SHIFT 8 -+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_NUMBER_SIGNED 0 -+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_TAG_MASK 0x000000F8U -+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_TAG_SHIFT 3 -+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_TAG_SIGNED 0 -+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_DATA_MASTER_MASK 0x00000006U -+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_DATA_MASTER_SHIFT 1 -+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_DATA_MASTER_SIGNED 0 -+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_RNW_MASK 0x00000001U -+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_RNW_SHIFT 0 -+#define EUR_CR_PIPE1_BREAKPOINT_TRAP_INFO1_RNW_SIGNED 0 -+/* Table EUR_CR_USE_CODE_BASE */ -+/* Register EUR_CR_USE_CODE_BASE */ -+#define EUR_CR_USE_CODE_BASE(X) (0x0A0C + (4 * (X))) -+#define EUR_CR_USE_CODE_BASE_ADDR_MASK 0x03FFFFFFU -+#define EUR_CR_USE_CODE_BASE_ADDR_SHIFT 0 -+#define EUR_CR_USE_CODE_BASE_ADDR_SIGNED 0 -+#define EUR_CR_USE_CODE_BASE_DM_MASK 0x0C000000U -+#define EUR_CR_USE_CODE_BASE_DM_SHIFT 26 -+#define EUR_CR_USE_CODE_BASE_DM_SIGNED 0 -+/* Number of entries in table EUR_CR_USE_CODE_BASE */ -+#define EUR_CR_USE_CODE_BASE_SIZE_UINT32 16 -+#define EUR_CR_USE_CODE_BASE_NUM_ENTRIES 16 -+ -+#endif /* _SGX544DEFS_KM_H_ */ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/hwdefs/sgxdefs.h b/drivers/staging/ti-es8-sgx/services4/srvkm/hwdefs/sgxdefs.h -new file mode 100644 -index 0000000..ed24647 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/hwdefs/sgxdefs.h -@@ -0,0 +1,112 @@ -+/*************************************************************************/ /*! -+@Title SGX hw definitions -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#ifndef _SGXDEFS_H_ -+#define _SGXDEFS_H_ -+ -+#include "sgxerrata.h" -+#include "sgxfeaturedefs.h" -+ -+#if defined(SGX520) -+#include "sgx520defs.h" -+#else -+#if defined(SGX530) -+#include "sgx530defs.h" -+#else -+#if defined(SGX535) -+#include "sgx535defs.h" -+#else -+#if defined(SGX535_V1_1) -+#include "sgx535defs.h" -+#else -+#if defined(SGX540) -+#include "sgx540defs.h" -+#else -+#if defined(SGX543) -+#if defined(FIX_HW_BRN_29954) -+#include "sgx543_v1.164defs.h" -+#else -+#include "sgx543defs.h" -+#endif -+#else -+#if defined(SGX544) -+#include "sgx544defs.h" -+#else -+#if defined(SGX545) -+#include "sgx545defs.h" -+#else -+#if defined(SGX531) -+#include "sgx531defs.h" -+#else -+#if defined(SGX554) -+#include "sgx554defs.h" -+#endif -+#endif -+#endif -+#endif -+#endif -+#endif -+#endif -+#endif -+#endif -+#endif -+ -+#if defined(SGX_FEATURE_MP) -+#if defined(SGX554) -+#include "sgxmpplusdefs.h" -+#else -+#include "sgxmpdefs.h" -+#endif /* SGX554 */ -+#else /* SGX_FEATURE_MP */ -+#if defined(SGX_FEATURE_SYSTEM_CACHE) -+#include "mnemedefs.h" -+#endif -+#endif /* SGX_FEATURE_MP */ -+ -+/***************************************************************************** -+ Core specific defines. -+*****************************************************************************/ -+ -+#endif /* _SGXDEFS_H_ */ -+ -+/***************************************************************************** -+ End of file (sgxdefs.h) -+*****************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/hwdefs/sgxerrata.h b/drivers/staging/ti-es8-sgx/services4/srvkm/hwdefs/sgxerrata.h -new file mode 100644 -index 0000000..d9e8880 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/hwdefs/sgxerrata.h -@@ -0,0 +1,480 @@ -+/*************************************************************************/ /*! -+@Title SGX HW errata definitions -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Specifies associations between SGX core revisions -+ and SW workarounds required to fix HW errata that exist -+ in specific core revisions -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+#ifndef _SGXERRATA_KM_H_ -+#define _SGXERRATA_KM_H_ -+ -+/* ignore warnings about unrecognised preprocessing directives in conditional inclusion directives */ -+/* PRQA S 3115 ++ */ -+ -+#if defined(SGX520) && !defined(SGX_CORE_DEFINED) -+ /* define the _current_ SGX520 RTL head revision */ -+ #define SGX_CORE_REV_HEAD 0 -+ #if defined(USE_SGX_CORE_REV_HEAD) -+ /* build config selects Core Revision to be the Head */ -+ #define SGX_CORE_REV SGX_CORE_REV_HEAD -+ #endif -+ -+ #if SGX_CORE_REV == 111 -+ #else -+ #if SGX_CORE_REV == SGX_CORE_REV_HEAD -+ /* RTL head - no BRNs to apply */ -+ #else -+ #error "sgxerrata.h: SGX520 Core Revision unspecified" -+ #endif -+ #endif -+ /* signal that the Core Version has a valid definition */ -+ #define SGX_CORE_DEFINED -+#endif -+ -+#if defined(SGX530) && !defined(SGX_CORE_DEFINED) -+ /* define the _current_ SGX530 RTL head revision */ -+ #define SGX_CORE_REV_HEAD 0 -+ #if defined(USE_SGX_CORE_REV_HEAD) -+ /* build config selects Core Revision to be the Head */ -+ #define SGX_CORE_REV SGX_CORE_REV_HEAD -+ #endif -+ -+ #if SGX_CORE_REV == 120 -+ #define FIX_HW_BRN_22934/* Workaround in sgx featuredefs */ -+ #define FIX_HW_BRN_28889/* Workaround in services (srvkm) */ -+ #else -+ #if SGX_CORE_REV == 121 -+ #define FIX_HW_BRN_22934/* Workaround in sgx featuredefs */ -+ #define FIX_HW_BRN_28889/* Workaround in services (srvkm) */ -+ #else -+ #if SGX_CORE_REV == 125 -+ #define FIX_HW_BRN_22934/* Workaround in sgx featuredefs */ -+ #define FIX_HW_BRN_28889/* Workaround in services (srvkm) */ -+ #else -+ #if SGX_CORE_REV == 130 -+ #define FIX_HW_BRN_22934/* Workaround in sgx featuredefs */ -+ #define FIX_HW_BRN_28889/* Workaround in services (srvkm) */ -+ #else -+ #if SGX_CORE_REV == SGX_CORE_REV_HEAD -+ /* RTL head - no BRNs to apply */ -+ #else -+ #error "sgxerrata.h: SGX530 Core Revision unspecified" -+ #endif -+ #endif -+ #endif -+#endif -+ #endif -+ /* signal that the Core Version has a valid definition */ -+ #define SGX_CORE_DEFINED -+#endif -+ -+#if defined(SGX531) && !defined(SGX_CORE_DEFINED) -+ /* define the _current_ SGX531 RTL head revision */ -+ #define SGX_CORE_REV_HEAD 0 -+ #if defined(USE_SGX_CORE_REV_HEAD) -+ /* build config selects Core Revision to be the Head */ -+ #define SGX_CORE_REV SGX_CORE_REV_HEAD -+ #endif -+ -+ #if SGX_CORE_REV == 101 -+ #define FIX_HW_BRN_26620/* Workaround in services (srvkm) */ -+ #define FIX_HW_BRN_28011/* Workaround in services (srvkm) */ -+ #define FIX_HW_BRN_34028/* Workaround in services (srvkm) */ -+ #else -+ #if SGX_CORE_REV == 110 -+ #define FIX_HW_BRN_34028/* Workaround in services (srvkm) */ -+ #else -+ #if SGX_CORE_REV == SGX_CORE_REV_HEAD -+ /* RTL head - no BRNs to apply */ -+ #else -+ #error "sgxerrata.h: SGX531 Core Revision unspecified" -+ #endif -+ #endif -+ #endif -+ /* signal that the Core Version has a valid definition */ -+ #define SGX_CORE_DEFINED -+#endif -+ -+#if (defined(SGX535) || defined(SGX535_V1_1)) && !defined(SGX_CORE_DEFINED) -+ /* define the _current_ SGX535 RTL head revision */ -+ #define SGX_CORE_REV_HEAD 0 -+ #if defined(USE_SGX_CORE_REV_HEAD) -+ /* build config selects Core Revision to be the Head */ -+ #define SGX_CORE_REV SGX_CORE_REV_HEAD -+ #endif -+ -+ #if SGX_CORE_REV == 121 -+ #define FIX_HW_BRN_22934/* Workaround in sgx featuredefs */ -+ #define FIX_HW_BRN_23944/* Workaround in code (services) */ -+ #define FIX_HW_BRN_23410/* Workaround in code (services) and ucode */ -+ #else -+ #if SGX_CORE_REV == 126 -+ #define FIX_HW_BRN_22934/* Workaround in sgx featuredefs */ -+ #else -+ #if SGX_CORE_REV == SGX_CORE_REV_HEAD -+ /* RTL head - no BRNs to apply */ -+ #else -+ #error "sgxerrata.h: SGX535 Core Revision unspecified" -+ -+ #endif -+ #endif -+ #endif -+ /* signal that the Core Version has a valid definition */ -+ #define SGX_CORE_DEFINED -+#endif -+ -+#if defined(SGX540) && !defined(SGX_CORE_DEFINED) -+ /* define the _current_ SGX540 RTL head revision */ -+ #define SGX_CORE_REV_HEAD 0 -+ #if defined(USE_SGX_CORE_REV_HEAD) -+ /* build config selects Core Revision to be the Head */ -+ #define SGX_CORE_REV SGX_CORE_REV_HEAD -+ #endif -+ -+ #if SGX_CORE_REV == 110 -+ #define FIX_HW_BRN_25503/* Workaround in code (services) */ -+ #define FIX_HW_BRN_26620/* Workaround in services (srvkm) */ -+ #define FIX_HW_BRN_28011/* Workaround in services (srvkm) */ -+ #define FIX_HW_BRN_34028/* Workaround in services (srvkm) */ -+ #else -+ #if SGX_CORE_REV == 120 -+ #define FIX_HW_BRN_26620/* Workaround in services (srvkm) */ -+ #define FIX_HW_BRN_28011/* Workaround in services (srvkm) */ -+ #define FIX_HW_BRN_34028/* Workaround in services (srvkm) */ -+ #else -+ #if SGX_CORE_REV == 121 -+ #define FIX_HW_BRN_28011/* Workaround in services (srvkm) */ -+ #define FIX_HW_BRN_34028/* Workaround in services (srvkm) */ -+ #else -+ #if SGX_CORE_REV == 130 -+ #define FIX_HW_BRN_34028/* Workaround in services (srvkm) */ -+ #else -+ #if SGX_CORE_REV == SGX_CORE_REV_HEAD -+ /* RTL head - no BRNs to apply */ -+ #else -+ #error "sgxerrata.h: SGX540 Core Revision unspecified" -+ #endif -+ #endif -+ #endif -+ #endif -+ #endif -+ /* signal that the Core Version has a valid definition */ -+ #define SGX_CORE_DEFINED -+#endif -+ -+ -+#if defined(SGX543) && !defined(SGX_CORE_DEFINED) -+ /* define the _current_ SGX543 RTL head revision */ -+ #define SGX_CORE_REV_HEAD 0 -+ #if defined(USE_SGX_CORE_REV_HEAD) -+ /* build config selects Core Revision to be the Head */ -+ #define SGX_CORE_REV SGX_CORE_REV_HEAD -+ #endif -+ -+ #if SGX_CORE_REV == 122 -+ #define FIX_HW_BRN_29954/* turns off regbank split feature */ -+ #define FIX_HW_BRN_29997/* workaround in services */ -+ #define FIX_HW_BRN_30954/* workaround in services */ -+ #define FIX_HW_BRN_31093/* workaround in services */ -+ #define FIX_HW_BRN_31195/* workaround in services */ -+ #define FIX_HW_BRN_31272/* workaround in services (srvclient) and uKernel */ -+ #define FIX_HW_BRN_31278/* disabled prefetching in MMU */ -+ #define FIX_HW_BRN_31542/* workaround in uKernel and Services */ -+ #define FIX_HW_BRN_31620/* workaround in services */ -+ #define FIX_HW_BRN_31780/* workaround in uKernel */ -+ #define FIX_HW_BRN_32044 /* workaround in uKernel, services and client drivers */ -+ #define FIX_HW_BRN_32085 /* workaround in services: prefetch fix applied, investigating PT based fix */ -+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP) -+ #define FIX_HW_BRN_33657/* workaround in ukernel*/ -+ #endif -+ #define FIX_HW_BRN_33920/* workaround in ukernel */ -+ #define FIX_HW_BRN_36513 /* workaround in uKernel and Services */ -+ /* add BRNs here */ -+ #else -+ #if SGX_CORE_REV == 1221 -+ #define FIX_HW_BRN_29954/* turns off regbank split feature */ -+ #define FIX_HW_BRN_31195/* workaround in services */ -+ #define FIX_HW_BRN_31272/* workaround in services (srvclient) and uKernel */ -+ #define FIX_HW_BRN_31278/* disabled prefetching in MMU */ -+ #define FIX_HW_BRN_31542/* workaround in uKernel and Services */ -+ #define FIX_HW_BRN_31671/* workaround in uKernel */ -+ #define FIX_HW_BRN_31780/* workaround in uKernel */ -+ #define FIX_HW_BRN_32044/* workaround in uKernel, services and client drivers */ -+ #define FIX_HW_BRN_32085 /* workaround in services: prefetch fix applied, investigating PT based fix */ -+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP) -+ #define FIX_HW_BRN_33657/* workaround in ukernel*/ -+ #endif -+ #define FIX_HW_BRN_33920/* workaround in ukernel */ -+ #define FIX_HW_BRN_36513 /* workaround in uKernel and Services */ -+ /* add BRNs here */ -+ #else -+ #if SGX_CORE_REV == 141 -+ #define FIX_HW_BRN_29954/* turns off regbank split feature */ -+ #define FIX_HW_BRN_31671 /* workaround in uKernel */ -+ #define FIX_HW_BRN_31780/* workaround in uKernel */ -+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP) -+ #define FIX_HW_BRN_33657/* workaround in ukernel*/ -+ #endif -+ #define FIX_HW_BRN_36513 /* workaround in uKernel and Services */ -+ /* add BRNs here */ -+ #else -+ #if SGX_CORE_REV == 142 -+ #define FIX_HW_BRN_29954/* turns off regbank split feature */ -+ #define FIX_HW_BRN_31671 /* workaround in uKernel */ -+ #define FIX_HW_BRN_31780/* workaround in uKernel */ -+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP) -+ #define FIX_HW_BRN_33657/* workaround in ukernel*/ -+ #endif -+ #define FIX_HW_BRN_36513 /* workaround in uKernel and Services */ -+ /* add BRNs here */ -+ #else -+ #if SGX_CORE_REV == 2111 -+ #define FIX_HW_BRN_30982 /* workaround in uKernel and services */ -+ #define FIX_HW_BRN_31093/* workaround in services */ -+ #define FIX_HW_BRN_31195/* workaround in services */ -+ #define FIX_HW_BRN_31272/* workaround in services (srvclient) and uKernel */ -+ #define FIX_HW_BRN_31278/* disabled prefetching in MMU */ -+ #define FIX_HW_BRN_31542/* workaround in uKernel and Services */ -+ #define FIX_HW_BRN_31620/* workaround in services */ -+ #define FIX_HW_BRN_31780/* workaround in uKernel */ -+ #define FIX_HW_BRN_32044 /* workaround in uKernel, services and client drivers */ -+ #define FIX_HW_BRN_32085 /* workaround in services: prefetch fix applied, investigating PT based fix */ -+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP) -+ #define FIX_HW_BRN_33657/* workaround in ukernel*/ -+ #endif -+ #define FIX_HW_BRN_33920/* workaround in ukernel */ -+ #define FIX_HW_BRN_36513 /* workaround in uKernel and Services */ -+ /* add BRNs here */ -+ #else -+ #if SGX_CORE_REV == 213 -+ #define FIX_HW_BRN_31272/* workaround in services (srvclient) and uKernel */ -+ #define FIX_HW_BRN_31671 /* workaround in uKernel */ -+ #define FIX_HW_BRN_31780/* workaround in uKernel */ -+ #define FIX_HW_BRN_32085 /* workaround in services: prefetch fix applied, investigating PT based fix */ -+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP) -+ #define FIX_HW_BRN_33657/* workaround in ukernel*/ -+ #endif -+ #define FIX_HW_BRN_33920/* workaround in ukernel */ -+ #define FIX_HW_BRN_36513 /* workaround in uKernel and Services */ -+ /* add BRNs here */ -+ #else -+ #if SGX_CORE_REV == 216 -+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP) -+ #define FIX_HW_BRN_33657/* workaround in ukernel*/ -+ #endif -+ #define FIX_HW_BRN_36513 /* workaround in uKernel and Services */ -+ #else -+ #if SGX_CORE_REV == 302 -+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP) -+ #define FIX_HW_BRN_33657/* workaround in ukernel*/ -+ #endif -+ #define FIX_HW_BRN_36513 /* workaround in uKernel and Services */ -+ #else -+ #if SGX_CORE_REV == 303 -+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP) -+ #define FIX_HW_BRN_33657/* workaround in ukernel*/ -+ #endif -+ #define FIX_HW_BRN_36513 /* workaround in uKernel and Services */ -+ #else -+ #if SGX_CORE_REV == SGX_CORE_REV_HEAD -+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP) -+ #define FIX_HW_BRN_33657/* workaround in ukernel*/ -+ #endif -+ #else -+ #error "sgxerrata.h: SGX543 Core Revision unspecified" -+ #endif -+ #endif -+ #endif -+ #endif -+ #endif -+ #endif -+ #endif -+ #endif -+ #endif -+ #endif -+ /* signal that the Core Version has a valid definition */ -+ #define SGX_CORE_DEFINED -+#endif -+ -+#if defined(SGX544) && !defined(SGX_CORE_DEFINED) -+ /* define the _current_ SGX544 RTL head revision */ -+ #define SGX_CORE_REV_HEAD 0 -+ #if defined(USE_SGX_CORE_REV_HEAD) -+ /* build config selects Core Revision to be the Head */ -+ #define SGX_CORE_REV SGX_CORE_REV_HEAD -+ #endif -+ -+ #if SGX_CORE_REV == 104 -+ #define FIX_HW_BRN_29954/* turns off regbank split feature */ -+ #define FIX_HW_BRN_31093/* workaround in services */ -+ #define FIX_HW_BRN_31195/* workaround in services */ -+ #define FIX_HW_BRN_31272/* workaround in services (srvclient) and uKernel */ -+ #define FIX_HW_BRN_31278/* disabled prefetching in MMU */ -+ #define FIX_HW_BRN_31542 /* workaround in uKernel and Services */ -+ #define FIX_HW_BRN_31620/* workaround in services */ -+ #define FIX_HW_BRN_31671 /* workaround in uKernel */ -+ #define FIX_HW_BRN_31780/* workaround in uKernel */ -+ #define FIX_HW_BRN_32044 /* workaround in uKernel, services and client drivers */ -+ #define FIX_HW_BRN_32085 /* workaround in services: prefetch fix applied, investigating PT based fix */ -+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP) -+ #define FIX_HW_BRN_33657/* workaround in ukernel*/ -+ #endif -+ #define FIX_HW_BRN_33920/* workaround in ukernel */ -+ #define FIX_HW_BRN_36513 /* workaround in uKernel and Services */ -+ #else -+ #if SGX_CORE_REV == 105 -+ #define FIX_HW_BRN_31780/* workaround in uKernel */ -+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP) -+ #define FIX_HW_BRN_33657/* workaround in ukernel*/ -+ #endif -+ #define FIX_HW_BRN_33920/* workaround in ukernel */ -+ #define FIX_HW_BRN_36513 /* workaround in uKernel and Services */ -+ #else -+ #if SGX_CORE_REV == 112 -+ #define FIX_HW_BRN_31272/* workaround in services (srvclient) and uKernel */ -+ #define FIX_HW_BRN_33920/* workaround in ukernel */ -+ #define FIX_HW_BRN_36513 /* workaround in uKernel and Services */ -+ #else -+ #if SGX_CORE_REV == 114 -+ #define FIX_HW_BRN_31780/* workaround in uKernel */ -+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP) -+ #define FIX_HW_BRN_33657/* workaround in ukernel*/ -+ #endif -+ #define FIX_HW_BRN_36513 /* workaround in uKernel and Services */ -+ #else -+ #if SGX_CORE_REV == 115 -+ #define FIX_HW_BRN_31780/* workaround in uKernel */ -+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP) -+ #define FIX_HW_BRN_33657/* workaround in ukernel*/ -+ #endif -+ #define FIX_HW_BRN_36513 /* workaround in uKernel and Services */ -+ #else -+ #if SGX_CORE_REV == 116 -+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP) -+ #define FIX_HW_BRN_33657/* workaround in ukernel */ -+ #endif -+ #define FIX_HW_BRN_33809/* workaround in kernel (enable burst combiner) */ -+ #define FIX_HW_BRN_36513 /* workaround in uKernel and Services */ -+ #else -+ #if SGX_CORE_REV == SGX_CORE_REV_HEAD -+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP) -+ #define FIX_HW_BRN_33657/* workaround in ukernel*/ -+ #endif -+ #else -+ #error "sgxerrata.h: SGX544 Core Revision unspecified" -+ #endif -+ #endif -+ #endif -+ #endif -+ #endif -+ #endif -+ #endif -+ /* signal that the Core Version has a valid definition */ -+ #define SGX_CORE_DEFINED -+#endif -+ -+#if defined(SGX545) && !defined(SGX_CORE_DEFINED) -+ /* define the _current_ SGX545 RTL head revision */ -+ #define SGX_CORE_REV_HEAD 0 -+ #if defined(USE_SGX_CORE_REV_HEAD) -+ /* build config selects Core Revision to be the Head */ -+ #define SGX_CORE_REV SGX_CORE_REV_HEAD -+ #endif -+ -+ #if SGX_CORE_REV == 10131 -+ #else -+ #if SGX_CORE_REV == 1014 -+ #else -+ #if SGX_CORE_REV == 10141 -+ #else -+ #if SGX_CORE_REV == SGX_CORE_REV_HEAD -+ /* RTL head - no BRNs to apply */ -+ #else -+ #error "sgxerrata.h: SGX545 Core Revision unspecified" -+ #endif -+ #endif -+ #endif -+ #endif -+ /* signal that the Core Version has a valid definition */ -+ #define SGX_CORE_DEFINED -+#endif -+ -+#if defined(SGX554) && !defined(SGX_CORE_DEFINED) -+ /* define the _current_ SGX554 RTL head revision */ -+ #define SGX_CORE_REV_HEAD 0 -+ #if defined(USE_SGX_CORE_REV_HEAD) -+ /* build config selects Core Revision to be the Head */ -+ #define SGX_CORE_REV SGX_CORE_REV_HEAD -+ #endif -+ -+ #if SGX_CORE_REV == 1251 -+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP) -+ #define FIX_HW_BRN_33657/* workaround in ukernel*/ -+ #endif -+ #define FIX_HW_BRN_36513 /* workaround in uKernel and Services */ -+ /* add BRNs here */ -+ #else -+ #if SGX_CORE_REV == SGX_CORE_REV_HEAD -+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && defined(SGX_FEATURE_MP) -+ #define FIX_HW_BRN_33657/* workaround in ukernel*/ -+ #endif -+ #else -+ #error "sgxerrata.h: SGX554 Core Revision unspecified" -+ #endif -+ #endif -+ /* signal that the Core Version has a valid definition */ -+ #define SGX_CORE_DEFINED -+#endif -+ -+#if !defined(SGX_CORE_DEFINED) -+#if defined (__GNUC__) -+ #warning "sgxerrata.h: SGX Core Version unspecified" -+#else -+ #pragma message("sgxerrata.h: SGX Core Version unspecified") -+#endif -+#endif -+ -+/* restore warning */ -+/* PRQA S 3115 -- */ -+ -+#endif /* _SGXERRATA_KM_H_ */ -+ -+/****************************************************************************** -+ End of file (sgxerrata.h) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/hwdefs/sgxfeaturedefs.h b/drivers/staging/ti-es8-sgx/services4/srvkm/hwdefs/sgxfeaturedefs.h -new file mode 100644 -index 0000000..dfbc28b ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/hwdefs/sgxfeaturedefs.h -@@ -0,0 +1,270 @@ -+/*************************************************************************/ /*! -+@Title SGX fexture definitions -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+#if defined(SGX520) -+ #define SGX_CORE_FRIENDLY_NAME "SGX520" -+ #define SGX_CORE_ID SGX_CORE_ID_520 -+ #define SGX_FEATURE_ADDRESS_SPACE_SIZE (28) -+ #define SGX_FEATURE_NUM_USE_PIPES (1) -+ #define SGX_FEATURE_AUTOCLOCKGATING -+#else -+#if defined(SGX530) -+ #define SGX_CORE_FRIENDLY_NAME "SGX530" -+ #define SGX_CORE_ID SGX_CORE_ID_530 -+ #define SGX_FEATURE_ADDRESS_SPACE_SIZE (28) -+ #define SGX_FEATURE_NUM_USE_PIPES (2) -+ #define SGX_FEATURE_AUTOCLOCKGATING -+#else -+#if defined(SGX531) -+ #define SGX_CORE_FRIENDLY_NAME "SGX531" -+ #define SGX_CORE_ID SGX_CORE_ID_531 -+ #define SGX_FEATURE_ADDRESS_SPACE_SIZE (28) -+ #define SGX_FEATURE_NUM_USE_PIPES (2) -+ #define SGX_FEATURE_AUTOCLOCKGATING -+ #define SGX_FEATURE_MULTI_EVENT_KICK -+#else -+#if defined(SGX535) -+ #define SGX_CORE_FRIENDLY_NAME "SGX535" -+ #define SGX_CORE_ID SGX_CORE_ID_535 -+ #define SGX_FEATURE_ADDRESS_SPACE_SIZE (32) -+ #define SGX_FEATURE_MULTIPLE_MEM_CONTEXTS -+ #define SGX_FEATURE_BIF_NUM_DIRLISTS (16) -+ #define SGX_FEATURE_2D_HARDWARE -+ #define SGX_FEATURE_NUM_USE_PIPES (2) -+ #define SGX_FEATURE_AUTOCLOCKGATING -+ #define SUPPORT_SGX_GENERAL_MAPPING_HEAP -+ #define SGX_FEATURE_EDM_VERTEX_PDSADDR_FULL_RANGE -+#else -+#if defined(SGX540) -+ #define SGX_CORE_FRIENDLY_NAME "SGX540" -+ #define SGX_CORE_ID SGX_CORE_ID_540 -+ #define SGX_FEATURE_ADDRESS_SPACE_SIZE (28) -+ #define SGX_FEATURE_NUM_USE_PIPES (4) -+ #define SGX_FEATURE_AUTOCLOCKGATING -+ #define SGX_FEATURE_MULTI_EVENT_KICK -+#else -+#if defined(SGX543) -+ #define SGX_CORE_FRIENDLY_NAME "SGX543" -+ #define SGX_CORE_ID SGX_CORE_ID_543 -+ #define SGX_FEATURE_USE_NO_INSTRUCTION_PAIRING -+ #define SGX_FEATURE_USE_UNLIMITED_PHASES -+ #define SGX_FEATURE_ADDRESS_SPACE_SIZE (32) -+ #define SGX_FEATURE_MULTIPLE_MEM_CONTEXTS -+ #define SGX_FEATURE_BIF_NUM_DIRLISTS (8) -+ #define SGX_FEATURE_NUM_USE_PIPES (4) -+ #define SGX_FEATURE_AUTOCLOCKGATING -+ #define SGX_FEATURE_MONOLITHIC_UKERNEL -+ #define SGX_FEATURE_MULTI_EVENT_KICK -+ #define SGX_FEATURE_DATA_BREAKPOINTS -+ #define SGX_FEATURE_PERPIPE_BKPT_REGS -+ #define SGX_FEATURE_PERPIPE_BKPT_REGS_NUMPIPES (2) -+ #define SGX_FEATURE_2D_HARDWARE -+ #define SGX_FEATURE_PTLA -+ #define SGX_FEATURE_EXTENDED_PERF_COUNTERS -+ #define SGX_FEATURE_EDM_VERTEX_PDSADDR_FULL_RANGE -+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) -+ #if defined(SGX_FEATURE_MP) -+ #define SGX_FEATURE_MASTER_VDM_CONTEXT_SWITCH -+ #endif -+ #define SGX_FEATURE_SLAVE_VDM_CONTEXT_SWITCH -+ #endif -+#else -+#if defined(SGX544) -+ #define SGX_CORE_FRIENDLY_NAME "SGX544" -+ #define SGX_CORE_ID SGX_CORE_ID_544 -+ #define SGX_FEATURE_USE_NO_INSTRUCTION_PAIRING -+ #define SGX_FEATURE_USE_UNLIMITED_PHASES -+ #define SGX_FEATURE_ADDRESS_SPACE_SIZE (32) -+ #define SGX_FEATURE_MULTIPLE_MEM_CONTEXTS -+ #define SGX_FEATURE_BIF_NUM_DIRLISTS (8) -+ #define SGX_FEATURE_NUM_USE_PIPES (4) -+ #define SGX_FEATURE_AUTOCLOCKGATING -+ #define SGX_FEATURE_MONOLITHIC_UKERNEL -+ #define SGX_FEATURE_MULTI_EVENT_KICK -+// #define SGX_FEATURE_DATA_BREAKPOINTS -+// #define SGX_FEATURE_PERPIPE_BKPT_REGS -+// #define SGX_FEATURE_PERPIPE_BKPT_REGS_NUMPIPES (2) -+ #if defined(SGX_FEATURE_MP) -+ #define SGX_FEATURE_2D_HARDWARE -+ #define SGX_FEATURE_PTLA -+ #endif -+ #define SGX_FEATURE_EXTENDED_PERF_COUNTERS -+ #define SGX_FEATURE_EDM_VERTEX_PDSADDR_FULL_RANGE -+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) -+ #if defined(SGX_FEATURE_MP) -+ #define SGX_FEATURE_MASTER_VDM_CONTEXT_SWITCH -+ #define SGX_FEATURE_SLAVE_VDM_CONTEXT_SWITCH -+ #endif -+ #endif -+#else -+#if defined(SGX545) -+ #define SGX_CORE_FRIENDLY_NAME "SGX545" -+ #define SGX_CORE_ID SGX_CORE_ID_545 -+ #define SGX_FEATURE_ADDRESS_SPACE_SIZE (32) -+ #define SGX_FEATURE_AUTOCLOCKGATING -+ #define SGX_FEATURE_USE_NO_INSTRUCTION_PAIRING -+ #define SGX_FEATURE_USE_UNLIMITED_PHASES -+ #define SGX_FEATURE_VOLUME_TEXTURES -+ #define SGX_FEATURE_HOST_ALLOC_FROM_DPM -+ #define SGX_FEATURE_MULTIPLE_MEM_CONTEXTS -+ #define SGX_FEATURE_BIF_NUM_DIRLISTS (16) -+ #define SGX_FEATURE_NUM_USE_PIPES (4) -+ #define SGX_FEATURE_TEXTURESTRIDE_EXTENSION -+ #define SGX_FEATURE_PDS_DATA_INTERLEAVE_2DWORDS -+ #define SGX_FEATURE_MONOLITHIC_UKERNEL -+ #define SGX_FEATURE_ZLS_EXTERNALZ -+ #define SGX_FEATURE_NUM_PDS_PIPES (2) -+ #define SGX_FEATURE_NATIVE_BACKWARD_BLIT -+ #define SGX_FEATURE_MAX_TA_RENDER_TARGETS (512) -+ #define SGX_FEATURE_SECONDARY_REQUIRES_USE_KICK -+ #define SGX_FEATURE_WRITEBACK_DCU -+ //FIXME: this is defined in the build config for now -+ //#define SGX_FEATURE_36BIT_MMU -+ #define SGX_FEATURE_BIF_WIDE_TILING_AND_4K_ADDRESS -+ #define SGX_FEATURE_MULTI_EVENT_KICK -+ #define SGX_FEATURE_EDM_VERTEX_PDSADDR_FULL_RANGE -+#else -+#if defined(SGX554) -+ #define SGX_CORE_FRIENDLY_NAME "SGX554" -+ #define SGX_CORE_ID SGX_CORE_ID_554 -+ #define SGX_FEATURE_USE_NO_INSTRUCTION_PAIRING -+ #define SGX_FEATURE_USE_UNLIMITED_PHASES -+ #define SGX_FEATURE_ADDRESS_SPACE_SIZE (32) -+ #define SGX_FEATURE_MULTIPLE_MEM_CONTEXTS -+ #define SGX_FEATURE_BIF_NUM_DIRLISTS (8) -+ #define SGX_FEATURE_NUM_USE_PIPES (8) -+ #define SGX_FEATURE_AUTOCLOCKGATING -+ #define SGX_FEATURE_MONOLITHIC_UKERNEL -+ #define SGX_FEATURE_MULTI_EVENT_KICK -+// #define SGX_FEATURE_DATA_BREAKPOINTS -+// #define SGX_FEATURE_PERPIPE_BKPT_REGS -+// #define SGX_FEATURE_PERPIPE_BKPT_REGS_NUMPIPES (2) -+ #define SGX_FEATURE_2D_HARDWARE -+ #define SGX_FEATURE_PTLA -+ #define SGX_FEATURE_EXTENDED_PERF_COUNTERS -+ #define SGX_FEATURE_EDM_VERTEX_PDSADDR_FULL_RANGE -+ #if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) -+ #if defined(SGX_FEATURE_MP) -+ #define SGX_FEATURE_MASTER_VDM_CONTEXT_SWITCH -+ #endif -+ #define SGX_FEATURE_SLAVE_VDM_CONTEXT_SWITCH -+ #endif -+#endif -+#endif -+#endif -+#endif -+#endif -+#endif -+#endif -+#endif -+#endif -+ -+#if defined(SGX_FEATURE_SLAVE_VDM_CONTEXT_SWITCH) \ -+ || defined(SGX_FEATURE_MASTER_VDM_CONTEXT_SWITCH) -+/* Enable the define so common code for HW VDMCS code is compiled */ -+#define SGX_FEATURE_VDM_CONTEXT_SWITCH -+#endif -+ -+/* -+ 'switch-off' features if defined BRNs affect the feature -+*/ -+ -+#if defined(FIX_HW_BRN_27266) -+#undef SGX_FEATURE_36BIT_MMU -+#endif -+ -+#if defined(FIX_HW_BRN_22934) \ -+ || defined(FIX_HW_BRN_25499) -+#undef SGX_FEATURE_MULTI_EVENT_KICK -+#endif -+ -+#if defined(SGX_FEATURE_SYSTEM_CACHE) -+ #if defined(SGX_FEATURE_36BIT_MMU) -+ #error SGX_FEATURE_SYSTEM_CACHE is incompatible with SGX_FEATURE_36BIT_MMU -+ #endif -+ #if defined(FIX_HW_BRN_26620) && !defined(SGX_FEATURE_MULTI_EVENT_KICK) -+ #define SGX_BYPASS_SYSTEM_CACHE -+ #endif -+#endif -+ -+#if defined(FIX_HW_BRN_29954) -+#undef SGX_FEATURE_PERPIPE_BKPT_REGS -+#endif -+ -+#if defined(FIX_HW_BRN_31620) -+#undef SGX_FEATURE_MULTIPLE_MEM_CONTEXTS -+#undef SGX_FEATURE_BIF_NUM_DIRLISTS -+#endif -+ -+/* -+ Derive other definitions: -+*/ -+ -+/* define default MP core count */ -+#if defined(SGX_FEATURE_MP) -+#if defined(SGX_FEATURE_MP_CORE_COUNT_TA) && defined(SGX_FEATURE_MP_CORE_COUNT_3D) -+#if (SGX_FEATURE_MP_CORE_COUNT_TA > SGX_FEATURE_MP_CORE_COUNT_3D) -+#error Number of TA cores larger than number of 3D cores not supported in current driver -+#endif /* (SGX_FEATURE_MP_CORE_COUNT_TA > SGX_FEATURE_MP_CORE_COUNT_3D) */ -+#else -+#if defined(SGX_FEATURE_MP_CORE_COUNT) -+#define SGX_FEATURE_MP_CORE_COUNT_TA (SGX_FEATURE_MP_CORE_COUNT) -+#define SGX_FEATURE_MP_CORE_COUNT_3D (SGX_FEATURE_MP_CORE_COUNT) -+#else -+#error Either SGX_FEATURE_MP_CORE_COUNT or \ -+both SGX_FEATURE_MP_CORE_COUNT_TA and SGX_FEATURE_MP_CORE_COUNT_3D \ -+must be defined when SGX_FEATURE_MP is defined -+#endif /* SGX_FEATURE_MP_CORE_COUNT */ -+#endif /* defined(SGX_FEATURE_MP_CORE_COUNT_TA) && defined(SGX_FEATURE_MP_CORE_COUNT_3D) */ -+#else -+#define SGX_FEATURE_MP_CORE_COUNT (1) -+#define SGX_FEATURE_MP_CORE_COUNT_TA (1) -+#define SGX_FEATURE_MP_CORE_COUNT_3D (1) -+#endif /* SGX_FEATURE_MP */ -+ -+#if defined(SUPPORT_SGX_LOW_LATENCY_SCHEDULING) && !defined(SUPPORT_SGX_PRIORITY_SCHEDULING) -+#define SUPPORT_SGX_PRIORITY_SCHEDULING -+#endif -+ -+#include "img_types.h" -+ -+/****************************************************************************** -+ End of file (sgxfeaturedefs.h) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/hwdefs/sgxmmu.h b/drivers/staging/ti-es8-sgx/services4/srvkm/hwdefs/sgxmmu.h -new file mode 100644 -index 0000000..a6a907a ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/hwdefs/sgxmmu.h -@@ -0,0 +1,99 @@ -+/*************************************************************************/ /*! -+@Title SGX MMU defines -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Provides SGX MMU declarations and macros -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#if !defined(__SGXMMU_KM_H__) -+#define __SGXMMU_KM_H__ -+ -+/* to be implemented */ -+ -+/* SGX MMU maps 4Kb pages */ -+#define SGX_MMU_PAGE_SHIFT (12) -+#define SGX_MMU_PAGE_SIZE (1U<<SGX_MMU_PAGE_SHIFT) -+#define SGX_MMU_PAGE_MASK (SGX_MMU_PAGE_SIZE - 1U) -+ -+/* PD details */ -+#define SGX_MMU_PD_SHIFT (10) -+#define SGX_MMU_PD_SIZE (1U<<SGX_MMU_PD_SHIFT) -+#define SGX_MMU_PD_MASK (0xFFC00000U) -+ -+/* PD Entry details */ -+#if defined(SGX_FEATURE_36BIT_MMU) -+ #define SGX_MMU_PDE_ADDR_MASK (0xFFFFFF00U) -+ #define SGX_MMU_PDE_ADDR_ALIGNSHIFT (4) -+#else -+ #define SGX_MMU_PDE_ADDR_MASK (0xFFFFF000U) -+ #define SGX_MMU_PDE_ADDR_ALIGNSHIFT (0) -+#endif -+#define SGX_MMU_PDE_VALID (0x00000001U) -+/* variable page size control field */ -+#define SGX_MMU_PDE_PAGE_SIZE_4K (0x00000000U) -+#define SGX_MMU_PDE_PAGE_SIZE_16K (0x00000002U) -+#define SGX_MMU_PDE_PAGE_SIZE_64K (0x00000004U) -+#define SGX_MMU_PDE_PAGE_SIZE_256K (0x00000006U) -+#define SGX_MMU_PDE_PAGE_SIZE_1M (0x00000008U) -+#define SGX_MMU_PDE_PAGE_SIZE_4M (0x0000000AU) -+#define SGX_MMU_PDE_PAGE_SIZE_MASK (0x0000000EU) -+ -+/* PT details */ -+#define SGX_MMU_PT_SHIFT (10) -+#define SGX_MMU_PT_SIZE (1U<<SGX_MMU_PT_SHIFT) -+#define SGX_MMU_PT_MASK (0x003FF000U) -+ -+/* PT Entry details */ -+#if defined(SGX_FEATURE_36BIT_MMU) -+ #define SGX_MMU_PTE_ADDR_MASK (0xFFFFFF00U) -+ #define SGX_MMU_PTE_ADDR_ALIGNSHIFT (4) -+#else -+ #define SGX_MMU_PTE_ADDR_MASK (0xFFFFF000U) -+ #define SGX_MMU_PTE_ADDR_ALIGNSHIFT (0) -+#endif -+#define SGX_MMU_PTE_VALID (0x00000001U) -+#define SGX_MMU_PTE_WRITEONLY (0x00000002U) -+#define SGX_MMU_PTE_READONLY (0x00000004U) -+#define SGX_MMU_PTE_CACHECONSISTENT (0x00000008U) -+#define SGX_MMU_PTE_EDMPROTECT (0x00000010U) -+ -+#endif /* __SGXMMU_KM_H__ */ -+ -+/***************************************************************************** -+ End of file (sgxmmu.h) -+*****************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/hwdefs/sgxmpdefs.h b/drivers/staging/ti-es8-sgx/services4/srvkm/hwdefs/sgxmpdefs.h -new file mode 100644 -index 0000000..cd80e37 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/hwdefs/sgxmpdefs.h -@@ -0,0 +1,364 @@ -+/*************************************************************************/ /*! -+@Title Hardware defs for SGXMP. -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#ifndef _SGXMPDEFS_KM_H_ -+#define _SGXMPDEFS_KM_H_ -+ -+/* Register EUR_CR_MASTER_BIF_CTRL */ -+#define EUR_CR_MASTER_BIF_CTRL 0x4C00 -+#define EUR_CR_MASTER_BIF_CTRL_NOREORDER_MASK 0x00000001U -+#define EUR_CR_MASTER_BIF_CTRL_NOREORDER_SHIFT 0 -+#define EUR_CR_MASTER_BIF_CTRL_NOREORDER_SIGNED 0 -+#define EUR_CR_MASTER_BIF_CTRL_PAUSE_MASK 0x00000002U -+#define EUR_CR_MASTER_BIF_CTRL_PAUSE_SHIFT 1 -+#define EUR_CR_MASTER_BIF_CTRL_PAUSE_SIGNED 0 -+#define EUR_CR_MASTER_BIF_CTRL_CLEAR_FAULT_MASK 0x00000010U -+#define EUR_CR_MASTER_BIF_CTRL_CLEAR_FAULT_SHIFT 4 -+#define EUR_CR_MASTER_BIF_CTRL_CLEAR_FAULT_SIGNED 0 -+#define EUR_CR_MASTER_BIF_CTRL_MMU_BYPASS_PTLA_MASK 0x00010000U -+#define EUR_CR_MASTER_BIF_CTRL_MMU_BYPASS_PTLA_SHIFT 16 -+#define EUR_CR_MASTER_BIF_CTRL_MMU_BYPASS_PTLA_SIGNED 0 -+#define EUR_CR_MASTER_BIF_CTRL_MMU_BYPASS_MASTER_VDM_MASK 0x00020000U -+#define EUR_CR_MASTER_BIF_CTRL_MMU_BYPASS_MASTER_VDM_SHIFT 17 -+#define EUR_CR_MASTER_BIF_CTRL_MMU_BYPASS_MASTER_VDM_SIGNED 0 -+#define EUR_CR_MASTER_BIF_CTRL_MMU_BYPASS_MASTER_IPF_MASK 0x00040000U -+#define EUR_CR_MASTER_BIF_CTRL_MMU_BYPASS_MASTER_IPF_SHIFT 18 -+#define EUR_CR_MASTER_BIF_CTRL_MMU_BYPASS_MASTER_IPF_SIGNED 0 -+#define EUR_CR_MASTER_BIF_CTRL_MMU_BYPASS_MASTER_DPM_MASK 0x00080000U -+#define EUR_CR_MASTER_BIF_CTRL_MMU_BYPASS_MASTER_DPM_SHIFT 19 -+#define EUR_CR_MASTER_BIF_CTRL_MMU_BYPASS_MASTER_DPM_SIGNED 0 -+/* Register EUR_CR_MASTER_BIF_CTRL_INVAL */ -+#define EUR_CR_MASTER_BIF_CTRL_INVAL 0x4C34 -+#define EUR_CR_MASTER_BIF_CTRL_INVAL_PTE_MASK 0x00000004U -+#define EUR_CR_MASTER_BIF_CTRL_INVAL_PTE_SHIFT 2 -+#define EUR_CR_MASTER_BIF_CTRL_INVAL_PTE_SIGNED 0 -+#define EUR_CR_MASTER_BIF_CTRL_INVAL_ALL_MASK 0x00000008U -+#define EUR_CR_MASTER_BIF_CTRL_INVAL_ALL_SHIFT 3 -+#define EUR_CR_MASTER_BIF_CTRL_INVAL_ALL_SIGNED 0 -+/* Register EUR_CR_MASTER_BIF_MMU_CTRL */ -+#define EUR_CR_MASTER_BIF_MMU_CTRL 0x4CD0 -+#define EUR_CR_MASTER_BIF_MMU_CTRL_PREFETCHING_ON_MASK 0x00000001U -+#define EUR_CR_MASTER_BIF_MMU_CTRL_PREFETCHING_ON_SHIFT 0 -+#define EUR_CR_MASTER_BIF_MMU_CTRL_PREFETCHING_ON_SIGNED 0 -+#define EUR_CR_MASTER_BIF_MMU_CTRL_ADDR_HASH_MODE_MASK 0x00000006U -+#define EUR_CR_MASTER_BIF_MMU_CTRL_ADDR_HASH_MODE_SHIFT 1 -+#define EUR_CR_MASTER_BIF_MMU_CTRL_ADDR_HASH_MODE_SIGNED 0 -+#define EUR_CR_MASTER_BIF_MMU_CTRL_ENABLE_DC_TLB_MASK 0x00000010U -+#define EUR_CR_MASTER_BIF_MMU_CTRL_ENABLE_DC_TLB_SHIFT 4 -+#define EUR_CR_MASTER_BIF_MMU_CTRL_ENABLE_DC_TLB_SIGNED 0 -+/* Register EUR_CR_MASTER_SLC_CTRL */ -+#define EUR_CR_MASTER_SLC_CTRL 0x4D00 -+#define EUR_CR_MASTER_SLC_CTRL_DISABLE_REORDERING_MASK 0x00800000U -+#define EUR_CR_MASTER_SLC_CTRL_DISABLE_REORDERING_SHIFT 23 -+#define EUR_CR_MASTER_SLC_CTRL_DISABLE_REORDERING_SIGNED 0 -+#define EUR_CR_MASTER_SLC_CTRL_DISABLE_BURST_EXP_MASK 0x00400000U -+#define EUR_CR_MASTER_SLC_CTRL_DISABLE_BURST_EXP_SHIFT 22 -+#define EUR_CR_MASTER_SLC_CTRL_DISABLE_BURST_EXP_SIGNED 0 -+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_REQ3_MASK 0x00200000U -+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_REQ3_SHIFT 21 -+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_REQ3_SIGNED 0 -+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_REQ2_MASK 0x00100000U -+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_REQ2_SHIFT 20 -+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_REQ2_SIGNED 0 -+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_REQ1_MASK 0x00080000U -+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_REQ1_SHIFT 19 -+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_REQ1_SIGNED 0 -+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_REQ0_MASK 0x00040000U -+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_REQ0_SHIFT 18 -+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_REQ0_SIGNED 0 -+#define EUR_CR_MASTER_SLC_CTRL_DM_REF_SET_ALL_MASK 0x00010000U -+#define EUR_CR_MASTER_SLC_CTRL_DM_REF_SET_ALL_SHIFT 16 -+#define EUR_CR_MASTER_SLC_CTRL_DM_REF_SET_ALL_SIGNED 0 -+#define EUR_CR_MASTER_SLC_CTRL_ARB_PAGE_SIZE_MASK 0x0000F000U -+#define EUR_CR_MASTER_SLC_CTRL_ARB_PAGE_SIZE_SHIFT 12 -+#define EUR_CR_MASTER_SLC_CTRL_ARB_PAGE_SIZE_SIGNED 0 -+#define EUR_CR_MASTER_SLC_CTRL_ADDR_DECODE_MODE_MASK 0x00000E00U -+#define EUR_CR_MASTER_SLC_CTRL_ADDR_DECODE_MODE_SHIFT 9 -+#define EUR_CR_MASTER_SLC_CTRL_ADDR_DECODE_MODE_SIGNED 0 -+#define EUR_CR_MASTER_SLC_CTRL_PAUSE_MASK 0x00000100U -+#define EUR_CR_MASTER_SLC_CTRL_PAUSE_SHIFT 8 -+#define EUR_CR_MASTER_SLC_CTRL_PAUSE_SIGNED 0 -+/* Register EUR_CR_MASTER_SLC_CTRL_BYPASS */ -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS 0x4D04 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_BYP_CC_N_MASK 0x08000000U -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_BYP_CC_N_SHIFT 27 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_BYP_CC_N_SIGNED 0 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_BYP_CC_MASK 0x04000000U -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_BYP_CC_SHIFT 26 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_BYP_CC_SIGNED 0 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_CORE4_MASK 0x02000000U -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_CORE4_SHIFT 25 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_CORE4_SIGNED 0 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_CORE3_MASK 0x01000000U -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_CORE3_SHIFT 24 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_CORE3_SIGNED 0 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_CORE2_MASK 0x00800000U -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_CORE2_SHIFT 23 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_CORE2_SIGNED 0 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_CORE1_MASK 0x00400000U -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_CORE1_SHIFT 22 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_CORE1_SIGNED 0 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_CORE0_MASK 0x00200000U -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_CORE0_SHIFT 21 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_CORE0_SIGNED 0 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_PTLA_MASK 0x00100000U -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_PTLA_SHIFT 20 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_PTLA_SIGNED 0 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_ISP2_RCIF_MASK 0x00080000U -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_ISP2_RCIF_SHIFT 19 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_ISP2_RCIF_SIGNED 0 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_ZLS_MASK 0x00040000U -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_ZLS_SHIFT 18 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_ZLS_SIGNED 0 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_PBE_MASK 0x00020000U -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_PBE_SHIFT 17 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_PBE_SIGNED 0 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_VDM_MASK 0x00010000U -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_VDM_SHIFT 16 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_VDM_SIGNED 0 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_IPF_MASK 0x00008000U -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_IPF_SHIFT 15 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_IPF_SIGNED 0 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_PDS_MASK 0x00004000U -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_PDS_SHIFT 14 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_PDS_SIGNED 0 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USEC_MASK 0x00002000U -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USEC_SHIFT 13 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USEC_SIGNED 0 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE3_MASK 0x00001000U -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE3_SHIFT 12 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE3_SIGNED 0 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE2_MASK 0x00000800U -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE2_SHIFT 11 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE2_SIGNED 0 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE1_MASK 0x00000400U -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE1_SHIFT 10 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE1_SIGNED 0 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE0_MASK 0x00000200U -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE0_SHIFT 9 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_USE0_SIGNED 0 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_IPF_OBJ_MASK 0x00000100U -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_IPF_OBJ_SHIFT 8 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_IPF_OBJ_SIGNED 0 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_TPF_MASK 0x00000080U -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_TPF_SHIFT 7 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_TPF_SIGNED 0 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_TA_MASK 0x00000040U -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_TA_SHIFT 6 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_TA_SIGNED 0 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_CACHE_MASK 0x00000020U -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_CACHE_SHIFT 5 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_CACHE_SIGNED 0 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_MMU_MASK 0x00000010U -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_MMU_SHIFT 4 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_REQ_MMU_SIGNED 0 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_DM_EVENT_MASK 0x00000008U -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_DM_EVENT_SHIFT 3 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_DM_EVENT_SIGNED 0 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_DM_PIXEL_MASK 0x00000004U -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_DM_PIXEL_SHIFT 2 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_DM_PIXEL_SIGNED 0 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_DM_VERTEX_MASK 0x00000002U -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_DM_VERTEX_SHIFT 1 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_DM_VERTEX_SIGNED 0 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_ALL_MASK 0x00000001U -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_ALL_SHIFT 0 -+#define EUR_CR_MASTER_SLC_CTRL_BYPASS_ALL_SIGNED 0 -+/* Register EUR_CR_MASTER_SLC_CTRL_USSE_INVAL */ -+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL 0x4D08 -+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_ADDR_MASK 0xFFFFFFFFU -+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_ADDR_SHIFT 0 -+#define EUR_CR_MASTER_SLC_CTRL_USSE_INVAL_ADDR_SIGNED 0 -+/* Register EUR_CR_MASTER_SLC_CTRL_INVAL */ -+#define EUR_CR_MASTER_SLC_CTRL_INVAL 0x4D28 -+#define EUR_CR_MASTER_SLC_CTRL_INVAL_DM_EVENT_MASK 0x00000008U -+#define EUR_CR_MASTER_SLC_CTRL_INVAL_DM_EVENT_SHIFT 3 -+#define EUR_CR_MASTER_SLC_CTRL_INVAL_DM_EVENT_SIGNED 0 -+#define EUR_CR_MASTER_SLC_CTRL_INVAL_DM_PIXEL_MASK 0x00000004U -+#define EUR_CR_MASTER_SLC_CTRL_INVAL_DM_PIXEL_SHIFT 2 -+#define EUR_CR_MASTER_SLC_CTRL_INVAL_DM_PIXEL_SIGNED 0 -+#define EUR_CR_MASTER_SLC_CTRL_INVAL_DM_VERTEX_MASK 0x00000002U -+#define EUR_CR_MASTER_SLC_CTRL_INVAL_DM_VERTEX_SHIFT 1 -+#define EUR_CR_MASTER_SLC_CTRL_INVAL_DM_VERTEX_SIGNED 0 -+#define EUR_CR_MASTER_SLC_CTRL_INVAL_ALL_MASK 0x00000001U -+#define EUR_CR_MASTER_SLC_CTRL_INVAL_ALL_SHIFT 0 -+#define EUR_CR_MASTER_SLC_CTRL_INVAL_ALL_SIGNED 0 -+/* Register EUR_CR_MASTER_SLC_CTRL_FLUSH */ -+#define EUR_CR_MASTER_SLC_CTRL_FLUSH 0x4D2C -+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_DM_EVENT_MASK 0x00000080U -+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_DM_EVENT_SHIFT 7 -+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_DM_EVENT_SIGNED 0 -+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_DM_PIXEL_MASK 0x00000040U -+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_DM_PIXEL_SHIFT 6 -+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_DM_PIXEL_SIGNED 0 -+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_DM_VERTEX_MASK 0x00000020U -+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_DM_VERTEX_SHIFT 5 -+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_DM_VERTEX_SIGNED 0 -+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_ALL_MASK 0x00000010U -+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_ALL_SHIFT 4 -+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_ALL_SIGNED 0 -+/* Register EUR_CR_MASTER_SLC_CTRL_FLUSH_INV */ -+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_INV 0x4D34 -+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_INV_DM_EVENT_MASK 0x00000080U -+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_INV_DM_EVENT_SHIFT 7 -+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_INV_DM_EVENT_SIGNED 0 -+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_INV_DM_PIXEL_MASK 0x00000040U -+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_INV_DM_PIXEL_SHIFT 6 -+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_INV_DM_PIXEL_SIGNED 0 -+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_INV_DM_VERTEX_MASK 0x00000020U -+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_INV_DM_VERTEX_SHIFT 5 -+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_INV_DM_VERTEX_SIGNED 0 -+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_INV_ALL_MASK 0x00000010U -+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_INV_ALL_SHIFT 4 -+#define EUR_CR_MASTER_SLC_CTRL_FLUSH_INV_ALL_SIGNED 0 -+/* Register EUR_CR_MASTER_BREAKPOINT_READ */ -+#define EUR_CR_MASTER_BREAKPOINT_READ 0x4F18 -+#define EUR_CR_MASTER_BREAKPOINT_READ_ADDRESS_MASK 0xFFFFFFF0U -+#define EUR_CR_MASTER_BREAKPOINT_READ_ADDRESS_SHIFT 4 -+#define EUR_CR_MASTER_BREAKPOINT_READ_ADDRESS_SIGNED 0 -+/* Register EUR_CR_MASTER_BREAKPOINT_TRAP */ -+#define EUR_CR_MASTER_BREAKPOINT_TRAP 0x4F1C -+#define EUR_CR_MASTER_BREAKPOINT_TRAP_CONTINUE_MASK 0x00000002U -+#define EUR_CR_MASTER_BREAKPOINT_TRAP_CONTINUE_SHIFT 1 -+#define EUR_CR_MASTER_BREAKPOINT_TRAP_CONTINUE_SIGNED 0 -+#define EUR_CR_MASTER_BREAKPOINT_TRAP_WRNOTIFY_MASK 0x00000001U -+#define EUR_CR_MASTER_BREAKPOINT_TRAP_WRNOTIFY_SHIFT 0 -+#define EUR_CR_MASTER_BREAKPOINT_TRAP_WRNOTIFY_SIGNED 0 -+/* Register EUR_CR_MASTER_BREAKPOINT */ -+#define EUR_CR_MASTER_BREAKPOINT 0x4F20 -+#define EUR_CR_MASTER_BREAKPOINT_ID_MASK 0x00000030U -+#define EUR_CR_MASTER_BREAKPOINT_ID_SHIFT 4 -+#define EUR_CR_MASTER_BREAKPOINT_ID_SIGNED 0 -+#define EUR_CR_MASTER_BREAKPOINT_UNTRAPPED_MASK 0x00000008U -+#define EUR_CR_MASTER_BREAKPOINT_UNTRAPPED_SHIFT 3 -+#define EUR_CR_MASTER_BREAKPOINT_UNTRAPPED_SIGNED 0 -+#define EUR_CR_MASTER_BREAKPOINT_TRAPPED_MASK 0x00000004U -+#define EUR_CR_MASTER_BREAKPOINT_TRAPPED_SHIFT 2 -+#define EUR_CR_MASTER_BREAKPOINT_TRAPPED_SIGNED 0 -+/* Register EUR_CR_MASTER_BREAKPOINT_TRAP_INFO0 */ -+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO0 0x4F24 -+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO0_ADDRESS_MASK 0xFFFFFFF0U -+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO0_ADDRESS_SHIFT 4 -+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO0_ADDRESS_SIGNED 0 -+/* Register EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1 */ -+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1 0x4F28 -+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1_SIZE_MASK 0x00007C00U -+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1_SIZE_SHIFT 10 -+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1_SIZE_SIGNED 0 -+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1_NUMBER_MASK 0x00000300U -+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1_NUMBER_SHIFT 8 -+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1_NUMBER_SIGNED 0 -+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1_TAG_MASK 0x000000F8U -+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1_TAG_SHIFT 3 -+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1_TAG_SIGNED 0 -+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1_DATA_MASTER_MASK 0x00000006U -+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1_DATA_MASTER_SHIFT 1 -+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1_DATA_MASTER_SIGNED 0 -+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1_RNW_MASK 0x00000001U -+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1_RNW_SHIFT 0 -+#define EUR_CR_MASTER_BREAKPOINT_TRAP_INFO1_RNW_SIGNED 0 -+/* Register EUR_CR_MASTER_CORE */ -+#define EUR_CR_MASTER_CORE 0x4000 -+#define EUR_CR_MASTER_CORE_ENABLE_MASK 0x00000003U -+#define EUR_CR_MASTER_CORE_ENABLE_SHIFT 0 -+#define EUR_CR_MASTER_CORE_ENABLE_SIGNED 0 -+/* Register EUR_CR_MASTER_CORE_ID */ -+#define EUR_CR_MASTER_CORE_ID 0x4010 -+#define EUR_CR_MASTER_CORE_ID_CONFIG_MULTI_MASK 0x00000001U -+#define EUR_CR_MASTER_CORE_ID_CONFIG_MULTI_SHIFT 0 -+#define EUR_CR_MASTER_CORE_ID_CONFIG_MULTI_SIGNED 0 -+#define EUR_CR_MASTER_CORE_ID_CONFIG_BASE_MASK 0x00000002U -+#define EUR_CR_MASTER_CORE_ID_CONFIG_BASE_SHIFT 1 -+#define EUR_CR_MASTER_CORE_ID_CONFIG_BASE_SIGNED 0 -+#define EUR_CR_MASTER_CORE_ID_CONFIG_MASK 0x000000FCU -+#define EUR_CR_MASTER_CORE_ID_CONFIG_SHIFT 2 -+#define EUR_CR_MASTER_CORE_ID_CONFIG_SIGNED 0 -+#define EUR_CR_MASTER_CORE_ID_CONFIG_CORES_MASK 0x00000F00U -+#define EUR_CR_MASTER_CORE_ID_CONFIG_CORES_SHIFT 8 -+#define EUR_CR_MASTER_CORE_ID_CONFIG_CORES_SIGNED 0 -+#define EUR_CR_MASTER_CORE_ID_CONFIG_SLC_MASK 0x0000F000U -+#define EUR_CR_MASTER_CORE_ID_CONFIG_SLC_SHIFT 12 -+#define EUR_CR_MASTER_CORE_ID_CONFIG_SLC_SIGNED 0 -+#define EUR_CR_MASTER_CORE_ID_ID_MASK 0xFFFF0000U -+#define EUR_CR_MASTER_CORE_ID_ID_SHIFT 16 -+#define EUR_CR_MASTER_CORE_ID_ID_SIGNED 0 -+/* Register EUR_CR_MASTER_CORE_REVISION */ -+#define EUR_CR_MASTER_CORE_REVISION 0x4014 -+#define EUR_CR_MASTER_CORE_REVISION_MAINTENANCE_MASK 0x000000FFU -+#define EUR_CR_MASTER_CORE_REVISION_MAINTENANCE_SHIFT 0 -+#define EUR_CR_MASTER_CORE_REVISION_MAINTENANCE_SIGNED 0 -+#define EUR_CR_MASTER_CORE_REVISION_MINOR_MASK 0x0000FF00U -+#define EUR_CR_MASTER_CORE_REVISION_MINOR_SHIFT 8 -+#define EUR_CR_MASTER_CORE_REVISION_MINOR_SIGNED 0 -+#define EUR_CR_MASTER_CORE_REVISION_MAJOR_MASK 0x00FF0000U -+#define EUR_CR_MASTER_CORE_REVISION_MAJOR_SHIFT 16 -+#define EUR_CR_MASTER_CORE_REVISION_MAJOR_SIGNED 0 -+#define EUR_CR_MASTER_CORE_REVISION_DESIGNER_MASK 0xFF000000U -+#define EUR_CR_MASTER_CORE_REVISION_DESIGNER_SHIFT 24 -+#define EUR_CR_MASTER_CORE_REVISION_DESIGNER_SIGNED 0 -+/* Register EUR_CR_MASTER_SOFT_RESET */ -+#define EUR_CR_MASTER_SOFT_RESET 0x4080 -+#define EUR_CR_MASTER_SOFT_RESET_CORE_RESET_MASK(i) (0x00000001U << (0 + ((i) * 1))) -+#define EUR_CR_MASTER_SOFT_RESET_CORE_RESET_SHIFT(i) (0 + ((i) * 1)) -+#define EUR_CR_MASTER_SOFT_RESET_CORE_RESET_REGNUM(i) 0x4080 -+#define EUR_CR_MASTER_SOFT_RESET_IPF_RESET_MASK 0x00000010U -+#define EUR_CR_MASTER_SOFT_RESET_IPF_RESET_SHIFT 4 -+#define EUR_CR_MASTER_SOFT_RESET_IPF_RESET_SIGNED 0 -+#define EUR_CR_MASTER_SOFT_RESET_DPM_RESET_MASK 0x00000020U -+#define EUR_CR_MASTER_SOFT_RESET_DPM_RESET_SHIFT 5 -+#define EUR_CR_MASTER_SOFT_RESET_DPM_RESET_SIGNED 0 -+#define EUR_CR_MASTER_SOFT_RESET_VDM_RESET_MASK 0x00000040U -+#define EUR_CR_MASTER_SOFT_RESET_VDM_RESET_SHIFT 6 -+#define EUR_CR_MASTER_SOFT_RESET_VDM_RESET_SIGNED 0 -+#define EUR_CR_MASTER_SOFT_RESET_SLC_RESET_MASK 0x00000080U -+#define EUR_CR_MASTER_SOFT_RESET_SLC_RESET_SHIFT 7 -+#define EUR_CR_MASTER_SOFT_RESET_SLC_RESET_SIGNED 0 -+#define EUR_CR_MASTER_SOFT_RESET_BIF_RESET_MASK 0x00000100U -+#define EUR_CR_MASTER_SOFT_RESET_BIF_RESET_SHIFT 8 -+#define EUR_CR_MASTER_SOFT_RESET_BIF_RESET_SIGNED 0 -+#define EUR_CR_MASTER_SOFT_RESET_MCI_RESET_MASK 0x00000200U -+#define EUR_CR_MASTER_SOFT_RESET_MCI_RESET_SHIFT 9 -+#define EUR_CR_MASTER_SOFT_RESET_MCI_RESET_SIGNED 0 -+#define EUR_CR_MASTER_SOFT_RESET_PTLA_RESET_MASK 0x00000400U -+#define EUR_CR_MASTER_SOFT_RESET_PTLA_RESET_SHIFT 10 -+#define EUR_CR_MASTER_SOFT_RESET_PTLA_RESET_SIGNED 0 -+ -+#endif /* _SGXMPDEFS_KM_H_ */ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/include/buffer_manager.h b/drivers/staging/ti-es8-sgx/services4/srvkm/include/buffer_manager.h -new file mode 100644 -index 0000000..5e53b69 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/include/buffer_manager.h -@@ -0,0 +1,623 @@ -+/*************************************************************************/ /*! -+@Title Buffer Management. -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Manages buffers mapped into two virtual memory spaces, host and -+ device and referenced by handles. -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#ifndef _BUFFER_MANAGER_H_ -+#define _BUFFER_MANAGER_H_ -+ -+#include "img_types.h" -+#include "ra.h" -+#include "perproc.h" -+ -+#if defined(__cplusplus) -+extern "C"{ -+#endif -+ -+/* forward reference */ -+typedef struct _BM_HEAP_ BM_HEAP; -+ -+/* -+ * The mapping structure is used to record relations between CPU virtual, -+ * CPU physical and device virtual addresses for large chunks of memory -+ * from which we have resource-allocator draw our buffers. -+ * -+ * There is one per contiguous pool and one per import from the host OS. -+ */ -+struct _BM_MAPPING_ -+{ -+ enum -+ { -+ hm_wrapped = 1, /*!< wrapped user supplied contiguous*/ -+ hm_wrapped_scatter, /*!< wrapped user supplied scattered */ -+ hm_wrapped_virtaddr, /*!< wrapped user supplied contiguous with virtual address*/ -+ hm_wrapped_scatter_virtaddr, /*!< wrapped user supplied scattered with virtual address*/ -+ hm_env, /*!< obtained from environment */ -+ hm_contiguous /*!< contigous arena */ -+ } eCpuMemoryOrigin; -+ -+ BM_HEAP *pBMHeap; /* which BM heap */ -+ RA_ARENA *pArena; /* whence the memory comes */ -+ -+ IMG_CPU_VIRTADDR CpuVAddr; -+ IMG_CPU_PHYADDR CpuPAddr; -+ IMG_DEV_VIRTADDR DevVAddr; -+ IMG_SYS_PHYADDR *psSysAddr; -+ IMG_SIZE_T uSize; -+ IMG_SIZE_T uSizeVM; -+ IMG_HANDLE hOSMemHandle; -+ IMG_UINT32 ui32Flags; -+ -+ /* Sparse mapping data */ -+ IMG_UINT32 ui32ChunkSize; -+ IMG_UINT32 ui32NumVirtChunks; -+ IMG_UINT32 ui32NumPhysChunks; -+ IMG_BOOL *pabMapChunk; -+}; -+ -+/* -+ * The buffer structure handles individual allocations from the user; thus -+ * there is one allocated per call to BM_Alloc and one per call to BM_Wrap. -+ * We record a mapping reference so we know where to return allocated -+ * resources at BM_Free time. -+ */ -+typedef struct _BM_BUF_ -+{ -+ IMG_CPU_VIRTADDR *CpuVAddr; -+ IMG_VOID *hOSMemHandle; -+ IMG_CPU_PHYADDR CpuPAddr; -+ IMG_DEV_VIRTADDR DevVAddr; -+ -+ BM_MAPPING *pMapping; -+ IMG_UINT32 ui32RefCount; -+ IMG_UINT32 ui32ExportCount; -+} BM_BUF; -+ -+struct _BM_HEAP_ -+{ -+ IMG_UINT32 ui32Attribs; -+ BM_CONTEXT *pBMContext; -+ RA_ARENA *pImportArena; -+ RA_ARENA *pLocalDevMemArena; -+ RA_ARENA *pVMArena; -+ DEV_ARENA_DESCRIPTOR sDevArena; -+ MMU_HEAP *pMMUHeap; -+ PDUMP_MMU_ATTRIB *psMMUAttrib; -+ -+ struct _BM_HEAP_ *psNext; -+ struct _BM_HEAP_ **ppsThis; -+ /* BIF tile stride for this heap */ -+ IMG_UINT32 ui32XTileStride; -+}; -+ -+/* -+ * The bm-context structure -+ */ -+struct _BM_CONTEXT_ -+{ -+ MMU_CONTEXT *psMMUContext; -+ -+ /* -+ * Resource allocation arena of dual mapped pages. For devices -+ * where the hardware imposes different constraints on the valid -+ * device virtual address range depending on the use of the buffer -+ * we maintain two allocation arenas, one low address range, the -+ * other high. For devices without such a constrain we do not -+ * create the high arena, instead all allocations come from the -+ * low arena. -+ */ -+ BM_HEAP *psBMHeap; -+ -+ /* -+ * The Shared Heaps -+ */ -+ BM_HEAP *psBMSharedHeap; -+ -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+ -+ /* -+ * Hash table management. -+ */ -+ HASH_TABLE *pBufferHash; -+ -+ /* -+ * Resman item handle -+ */ -+ IMG_HANDLE hResItem; -+ -+ IMG_UINT32 ui32RefCount; -+ -+ /* -+ linked list next pointer -+ */ -+ struct _BM_CONTEXT_ *psNext; -+ struct _BM_CONTEXT_ **ppsThis; -+}; -+ -+/* refcount.c needs to know the internals of this structure */ -+typedef struct _XPROC_DATA_{ -+ IMG_UINT32 ui32RefCount; -+ IMG_UINT32 ui32AllocFlags; -+ IMG_UINT32 ui32Size; -+ IMG_UINT32 ui32PageSize; -+ RA_ARENA *psArena; -+ IMG_SYS_PHYADDR sSysPAddr; -+ IMG_VOID *pvCpuVAddr; -+ IMG_HANDLE hOSMemHandle; -+} XPROC_DATA; -+ -+extern XPROC_DATA gXProcWorkaroundShareData[]; -+/* -+ Buffer handle. -+*/ -+typedef IMG_VOID *BM_HANDLE; -+ -+/** Buffer manager allocation flags. -+ * -+ * Flags passed to BM_Alloc to specify buffer capabilities. -+ * -+ * @defgroup BP Buffer Manager Allocation Flags -+ * @{ -+ */ -+ -+/** Pool number mask. */ -+#define BP_POOL_MASK 0x7 -+ -+/* Request physically contiguous pages of memory */ -+#define BP_CONTIGUOUS (1 << 3) -+#define BP_PARAMBUFFER (1 << 4) -+ -+#define BM_MAX_DEVMEM_ARENAS 2 -+ -+/** @} */ -+ -+/** -+ * @Function BM_CreateContext -+ * -+ * @Description -+ * -+ * @Input -+ -+ * @Return -+ */ -+ -+IMG_HANDLE -+BM_CreateContext(PVRSRV_DEVICE_NODE *psDeviceNode, -+ IMG_DEV_PHYADDR *psPDDevPAddr, -+ PVRSRV_PER_PROCESS_DATA *psPerProc, -+ IMG_BOOL *pbCreated); -+ -+ -+/** -+ * @Function BM_DestroyContext -+ * -+ * @Description -+ * -+ * @Input -+ * -+ * @Return PVRSRV_ERROR -+ */ -+PVRSRV_ERROR -+BM_DestroyContext (IMG_HANDLE hBMContext, -+ IMG_BOOL *pbCreated); -+ -+ -+/** -+ * @Function BM_CreateHeap -+ * -+ * @Description -+ * -+ * @Input -+ * -+ * @Return -+ */ -+IMG_HANDLE -+BM_CreateHeap (IMG_HANDLE hBMContext, -+ DEVICE_MEMORY_HEAP_INFO *psDevMemHeapInfo); -+ -+/** -+ * @Function BM_DestroyHeap -+ * -+ * @Description -+ * -+ * @Input -+ * -+ * @Return -+ */ -+IMG_VOID -+BM_DestroyHeap (IMG_HANDLE hDevMemHeap); -+ -+ -+/** -+ * @Function BM_Reinitialise -+ * -+ * @Description -+ * -+ * Reinitialises the buffer manager after a power event. Calling this -+ * function will reprogram MMU registers and renable the MMU. -+ * -+ * @Input None -+ * @Return None -+ */ -+ -+IMG_BOOL -+BM_Reinitialise (PVRSRV_DEVICE_NODE *psDeviceNode); -+ -+/** -+ * @Function BM_Alloc -+ * -+ * @Description -+ * -+ * Allocate a buffer mapped into both host and device virtual memory -+ * maps. -+ * -+ * @Input uSize - require size in bytes of the buffer. -+ * @Input/Output pui32Flags - bit mask of buffer property flags + recieves heap flags. -+ * @Input uDevVAddrAlignment - required alignment in bytes, or 0. -+ * @Input pvPrivData - private data passed to OS allocator -+ * @Input ui32PrivDataLength - length of private data -+ * @Input ui32ChunkSize - Chunk size -+ * @Input ui32NumVirtChunks - Number of virtual chunks -+ * @Input ui32NumPhysChunks - Number of physical chunks -+ * @Input pabMapChunk - Chunk mapping array -+ * @Output phBuf - receives the buffer handle. -+ * @Return IMG_TRUE - Success, IMG_FALSE - Failed. -+ */ -+IMG_BOOL -+BM_Alloc (IMG_HANDLE hDevMemHeap, -+ IMG_DEV_VIRTADDR *psDevVAddr, -+ IMG_SIZE_T uSize, -+ IMG_UINT32 *pui32Flags, -+ IMG_UINT32 uDevVAddrAlignment, -+ IMG_PVOID pvPrivData, -+ IMG_UINT32 ui32PrivDataLength, -+ IMG_UINT32 ui32ChunkSize, -+ IMG_UINT32 ui32NumVirtChunks, -+ IMG_UINT32 ui32NumPhysChunks, -+ IMG_BOOL *pabMapChunk, -+ BM_HANDLE *phBuf); -+ -+/** -+ * @Function BM_Wrap -+ * -+ * @Description -+ * -+ * Create a buffer which wraps user provided host physical memory. -+ * The wrapped memory must be page aligned. BM_Wrap will roundup the -+ * size to a multiple of host pages. -+ * -+ * @Input ui32Size - size of memory to wrap. -+ * @Input ui32Offset - Offset into page of memory to wrap. -+ * @Input bPhysContig - Is the wrap physically contiguous. -+ * @Input psSysAddr - list of system physical page addresses of memory to wrap. -+ * @Input pvCPUVAddr - optional CPU kernel virtual address (Page aligned) of memory to wrap. -+ * @Input uFlags - bit mask of buffer property flags. -+ * @Input phBuf - receives the buffer handle. -+ * @Return IMG_TRUE - Success, IMG_FALSE - Failed -+ */ -+IMG_BOOL -+BM_Wrap ( IMG_HANDLE hDevMemHeap, -+ IMG_SIZE_T uSize, -+ IMG_SIZE_T uOffset, -+ IMG_BOOL bPhysContig, -+ IMG_SYS_PHYADDR *psSysAddr, -+ IMG_VOID *pvCPUVAddr, -+ IMG_UINT32 *pui32Flags, -+ BM_HANDLE *phBuf); -+ -+/** -+ * @Function BM_Free -+ * -+ * @Description -+ * -+ * Free a buffer previously allocated via BM_Alloc. -+ * -+ * @Input hBuf - buffer handle. -+ * @Return None. -+ */ -+IMG_VOID -+BM_Free (BM_HANDLE hBuf, -+ IMG_UINT32 ui32Flags); -+ -+ -+/** -+ * @Function BM_HandleToCpuVaddr -+ * -+ * @Description -+ * -+ * Retrieve the host virtual address associated with a buffer. -+ * -+ * @Input hBuf - buffer handle. -+ * -+ * @Return buffers host virtual address. -+ */ -+IMG_CPU_VIRTADDR -+BM_HandleToCpuVaddr (BM_HANDLE hBuf); -+ -+/** -+ * @Function BM_HandleToDevVaddr -+ * -+ * @Description -+ * -+ * Retrieve the device virtual address associated with a buffer. -+ * -+ * @Input hBuf - buffer handle. -+ * @Return buffers device virtual address. -+ */ -+IMG_DEV_VIRTADDR -+BM_HandleToDevVaddr (BM_HANDLE hBuf); -+ -+/** -+ * @Function BM_HandleToSysPaddr -+ * -+ * @Description -+ * -+ * Retrieve the system physical address associated with a buffer. -+ * -+ * @Input hBuf - buffer handle. -+ * @Return buffers device virtual address. -+ */ -+IMG_SYS_PHYADDR -+BM_HandleToSysPaddr (BM_HANDLE hBuf); -+ -+/** -+ * @Function BM_HandleToMemOSHandle -+ * -+ * @Description -+ * -+ * Retrieve the underlying memory handle associated with a buffer. -+ * -+ * @Input hBuf - buffer handle. -+ * @Return An OS Specific memory handle -+ */ -+IMG_HANDLE -+BM_HandleToOSMemHandle (BM_HANDLE hBuf); -+ -+/** -+ * @Function BM_GetPhysPageAddr -+ * -+ * @Description -+ * -+ * Retreive physical address backing dev V address -+ * -+ * @Input psMemInfo -+ * @Input sDevVPageAddr -+ * @Output psDevPAddr -+ * @Return PVRSRV_ERROR -+ */ -+IMG_VOID BM_GetPhysPageAddr(PVRSRV_KERNEL_MEM_INFO *psMemInfo, -+ IMG_DEV_VIRTADDR sDevVPageAddr, -+ IMG_DEV_PHYADDR *psDevPAddr); -+ -+/*! -+****************************************************************************** -+ @Function BM_GetMMUContext -+ -+ @Description -+ utility function to return the MMU context -+ -+ @inputs hDevMemHeap - the Dev mem heap handle -+ -+ @Return MMU context, else NULL -+**************************************************************************/ -+MMU_CONTEXT* BM_GetMMUContext(IMG_HANDLE hDevMemHeap); -+ -+/*! -+****************************************************************************** -+ @Function BM_GetMMUContextFromMemContext -+ -+ @Description -+ utility function to return the MMU context -+ -+ @inputs hDevMemHeap - the Dev mem heap handle -+ -+ @Return MMU context, else NULL -+**************************************************************************/ -+MMU_CONTEXT* BM_GetMMUContextFromMemContext(IMG_HANDLE hDevMemContext); -+ -+/*! -+****************************************************************************** -+ @Function BM_GetMMUHeap -+ -+ @Description -+ utility function to return the MMU heap handle -+ -+ @inputs hDevMemHeap - the Dev mem heap handle -+ -+ @Return MMU heap handle, else NULL -+**************************************************************************/ -+IMG_HANDLE BM_GetMMUHeap(IMG_HANDLE hDevMemHeap); -+ -+/*! -+****************************************************************************** -+ @Function BM_GetDeviceNode -+ -+ @Description utility function to return the devicenode from the BM Context -+ -+ @inputs hDevMemContext - the Dev Mem Context -+ -+ @Return MMU heap handle, else NULL -+**************************************************************************/ -+PVRSRV_DEVICE_NODE* BM_GetDeviceNode(IMG_HANDLE hDevMemContext); -+ -+ -+/*! -+****************************************************************************** -+ @Function BM_GetMappingHandle -+ -+ @Description utility function to return the mapping handle from a meminfo -+ -+ @inputs psMemInfo - kernel meminfo -+ -+ @Return mapping handle, else NULL -+**************************************************************************/ -+IMG_HANDLE BM_GetMappingHandle(PVRSRV_KERNEL_MEM_INFO *psMemInfo); -+ -+/*! -+****************************************************************************** -+ @Function BM_Export -+ -+ @Description Export a buffer previously allocated via BM_Alloc. -+ -+ @inputs hBuf - buffer handle. -+ -+ @Return None. -+**************************************************************************/ -+IMG_VOID BM_Export(BM_HANDLE hBuf); -+ -+/*! -+****************************************************************************** -+ @Function BM_FreeExport -+ -+ @Description Free a buffer previously exported via BM_Export. -+ -+ @inputs hBuf - buffer handle. -+ ui32Flags - flags -+ -+ @Return None. -+**************************************************************************/ -+IMG_VOID BM_FreeExport(BM_HANDLE hBuf, IMG_UINT32 ui32Flags); -+ -+/*! -+****************************************************************************** -+ @Function BM_MappingHandleFromBuffer -+ -+ @Description utility function to get the BM mapping handle from a BM buffer -+ -+ @Input hBuffer - Handle to BM buffer -+ -+ @Return BM mapping handle -+**************************************************************************/ -+IMG_HANDLE BM_MappingHandleFromBuffer(IMG_HANDLE hBuffer); -+ -+/*! -+****************************************************************************** -+ @Function BM_GetVirtualSize -+ -+ @Description utility function to get the VM size of a BM mapping -+ -+ @Input hBMHandle - Handle to BM mapping -+ -+ @Return VM size of mapping -+**************************************************************************/ -+IMG_UINT32 BM_GetVirtualSize(IMG_HANDLE hBMHandle); -+ -+/*! -+****************************************************************************** -+ @Function BM_MapPageAtOffset -+ -+ @Description utility function check if the specificed offset in a BM mapping -+ is a page that needs tp be mapped -+ -+ @Input hBMHandle - Handle to BM mapping -+ -+ @Input ui32Offset - Offset into import -+ -+ @Return IMG_TRUE if the page should be mapped -+**************************************************************************/ -+IMG_BOOL BM_MapPageAtOffset(IMG_HANDLE hBMHandle, IMG_UINT32 ui32Offset); -+ -+/*! -+****************************************************************************** -+ @Function BM_VirtOffsetToPhyscial -+ -+ @Description utility function find of physical offset of a sparse allocation -+ from it's virtual offset. -+ -+ @Input hBMHandle - Handle to BM mapping -+ -+ @Input ui32VirtOffset - Virtual offset into allocation -+ -+ @Output pui32PhysOffset - Physical offset -+ -+ @Return IMG_TRUE if the virtual offset is physically backed -+**************************************************************************/ -+IMG_BOOL BM_VirtOffsetToPhysical(IMG_HANDLE hBMHandle, -+ IMG_UINT32 ui32VirtOffset, -+ IMG_UINT32 *pui32PhysOffset); -+ -+/* The following are present for the "share mem" workaround for -+ cross-process mapping. This is only valid for a specific -+ use-case, and only tested on Linux (Android) and only -+ superficially at that. Do not rely on this API! */ -+/* The two "Set" functions set a piece of "global" state in the buffer -+ manager, and "Unset" removes this global state. Therefore, there -+ is no thread-safety here and it's the caller's responsibility to -+ ensure that a mutex is acquired before using these functions or any -+ device memory allocation functions, including, especially, -+ callbacks from RA. */ -+/* Once a "Share Index" is set by this means, any requests from the RA -+ to import a block of physical memory shall cause the physical -+ memory allocation to be refcounted, and shared iff the IDs chosen -+ match */ -+/* This API is difficult to use, but saves a lot of plumbing in other -+ APIs. The next generation of this library should have this functionality -+ plumbed in properly */ -+PVRSRV_ERROR BM_XProcWorkaroundSetShareIndex(IMG_UINT32 ui32Index); -+PVRSRV_ERROR BM_XProcWorkaroundUnsetShareIndex(IMG_UINT32 ui32Index); -+PVRSRV_ERROR BM_XProcWorkaroundFindNewBufferAndSetShareIndex(IMG_UINT32 *pui32Index); -+ -+#if defined(PVRSRV_REFCOUNT_DEBUG) -+IMG_VOID _BM_XProcIndexAcquireDebug(const IMG_CHAR *pszFile, IMG_INT iLine, IMG_UINT32 ui32Index); -+IMG_VOID _BM_XProcIndexReleaseDebug(const IMG_CHAR *pszFile, IMG_INT iLine, IMG_UINT32 ui32Index); -+ -+#define BM_XProcIndexAcquire(x...) \ -+ _BM_XProcIndexAcquireDebug(__FILE__, __LINE__, x) -+#define BM_XProcIndexRelease(x...) \ -+ _BM_XProcIndexReleaseDebug(__FILE__, __LINE__, x) -+ -+#else -+IMG_VOID _BM_XProcIndexAcquire(IMG_UINT32 ui32Index); -+IMG_VOID _BM_XProcIndexRelease(IMG_UINT32 ui32Index); -+ -+ -+#define BM_XProcIndexAcquire(x) \ -+ _BM_XProcIndexAcquire( x) -+#define BM_XProcIndexRelease(x) \ -+ _BM_XProcIndexRelease( x) -+#endif -+ -+ -+#if defined(__cplusplus) -+} -+#endif -+ -+#endif -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/include/device.h b/drivers/staging/ti-es8-sgx/services4/srvkm/include/device.h -new file mode 100644 -index 0000000..014e4da ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/include/device.h -@@ -0,0 +1,409 @@ -+/*************************************************************************/ /*! -+@Title Common Device header -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Device related function templates and defines -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#ifndef __DEVICE_H__ -+#define __DEVICE_H__ -+ -+#if defined(__cplusplus) -+extern "C" { -+#endif -+ -+#include "ra.h" /* RA_ARENA */ -+#include "resman.h" /* PRESMAN_ITEM */ -+ -+/* BM context forward reference */ -+typedef struct _BM_CONTEXT_ BM_CONTEXT; -+ -+/* pre-defined MMU structure forward references */ -+typedef struct _MMU_HEAP_ MMU_HEAP; -+typedef struct _MMU_CONTEXT_ MMU_CONTEXT; -+ -+/* physical resource types: */ -+/* contiguous system memory */ -+#define PVRSRV_BACKINGSTORE_SYSMEM_CONTIG (1<<(PVRSRV_MEM_BACKINGSTORE_FIELD_SHIFT+0)) -+/* non-contiguous system memory */ -+#define PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG (1<<(PVRSRV_MEM_BACKINGSTORE_FIELD_SHIFT+1)) -+/* contiguous local device memory */ -+#define PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG (1<<(PVRSRV_MEM_BACKINGSTORE_FIELD_SHIFT+2)) -+/* non-contiguous local device memory */ -+#define PVRSRV_BACKINGSTORE_LOCALMEM_NONCONTIG (1<<(PVRSRV_MEM_BACKINGSTORE_FIELD_SHIFT+3)) -+ -+/* heap types: */ -+typedef IMG_UINT32 DEVICE_MEMORY_HEAP_TYPE; -+#define DEVICE_MEMORY_HEAP_PERCONTEXT 0 -+#define DEVICE_MEMORY_HEAP_KERNEL 1 -+#define DEVICE_MEMORY_HEAP_SHARED 2 -+#define DEVICE_MEMORY_HEAP_SHARED_EXPORTED 3 -+ -+#define PVRSRV_DEVICE_NODE_FLAGS_PORT80DISPLAY 1 -+#define PVRSRV_DEVICE_NODE_FLAGS_MMU_OPT_INV 2 /* FIXME : Optimal Invalidation is not default */ -+ -+typedef struct _DEVICE_MEMORY_HEAP_INFO_ -+{ -+ /* heap identifier */ -+ IMG_UINT32 ui32HeapID; -+ -+ /* heap identifier string */ -+ IMG_CHAR *pszName; -+ -+ /* backing store identifier string */ -+ IMG_CHAR *pszBSName; -+ -+ /* Device virtual address of base of heap */ -+ IMG_DEV_VIRTADDR sDevVAddrBase; -+ -+ /* heapsize in bytes */ -+ IMG_UINT32 ui32HeapSize; -+ -+ /* Flags, includes physical resource (backing store type). Must be available to SOC */ -+ IMG_UINT32 ui32Attribs; -+ -+ /* Heap type: per device, kernel only, shared, shared_exported */ -+ DEVICE_MEMORY_HEAP_TYPE DevMemHeapType; -+ -+ /* kernel heap handle */ -+ IMG_HANDLE hDevMemHeap; -+ -+ /* ptr to local memory allocator for this heap */ -+ RA_ARENA *psLocalDevMemArena; -+ -+ /* MMU data page size (4kb, 16kb, 256kb, 1Mb, 4Mb) */ -+ IMG_UINT32 ui32DataPageSize; -+ -+ IMG_UINT32 ui32XTileStride; -+ -+} DEVICE_MEMORY_HEAP_INFO; -+ -+typedef struct _DEVICE_MEMORY_INFO_ -+{ -+ /* size of address space, as log2 */ -+ IMG_UINT32 ui32AddressSpaceSizeLog2; -+ -+ /* -+ flags, includes physical memory resource types available to the system. -+ Allows for validation at heap creation, define PVRSRV_BACKINGSTORE_XXX -+ */ -+ IMG_UINT32 ui32Flags; -+ -+ /* heap count. Doesn't include additional heaps from PVRSRVCreateDeviceMemHeap */ -+ IMG_UINT32 ui32HeapCount; -+ -+ /* the sync heap id - common code needs to know */ -+ IMG_UINT32 ui32SyncHeapID; -+ -+ /* heap for buffer mappings */ -+ IMG_UINT32 ui32MappingHeapID; -+ -+ /* heap for ion buffers */ -+ IMG_UINT32 ui32IonHeapID; -+ -+ /* device memory heap info about each heap in a device address space */ -+ DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; -+ -+ /* BM kernel context for the device */ -+ BM_CONTEXT *pBMKernelContext; -+ -+ /* BM context list for the device*/ -+ BM_CONTEXT *pBMContext; -+ -+} DEVICE_MEMORY_INFO; -+ -+ -+/*! -+ **************************************************************************** -+ Device memory descriptor for a given system -+ ****************************************************************************/ -+typedef struct DEV_ARENA_DESCRIPTOR_TAG -+{ -+ IMG_UINT32 ui32HeapID; /*!< memory pool has a unique id for diagnostic purposes */ -+ -+ IMG_CHAR *pszName; /*!< memory pool has a unique string for diagnostic purposes */ -+ -+ IMG_DEV_VIRTADDR BaseDevVAddr; /*!< Device virtual base address of the managed memory pool. */ -+ -+ IMG_UINT32 ui32Size; /*!< Size in bytes of the managed memory pool. */ -+ -+ DEVICE_MEMORY_HEAP_TYPE DevMemHeapType;/*!< heap type */ -+ -+ /* MMU data page size (4kb, 16kb, 256kb, 1Mb, 4Mb) */ -+ IMG_UINT32 ui32DataPageSize; -+ -+ DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeapInfo; -+ -+} DEV_ARENA_DESCRIPTOR; -+ -+ -+/* -+ PDUMP MMU atttributes -+*/ -+typedef struct _PDUMP_MMU_ATTRIB_ -+{ -+ PVRSRV_DEVICE_IDENTIFIER sDevId; -+ -+ IMG_CHAR *pszPDRegRegion; -+ -+ /* data page info */ -+ IMG_UINT32 ui32DataPageMask; -+ -+ /* page table info */ -+ IMG_UINT32 ui32PTEValid; -+ IMG_UINT32 ui32PTSize; -+ IMG_UINT32 ui32PTEAlignShift; -+ -+ /* page directory info */ -+ IMG_UINT32 ui32PDEMask; -+ IMG_UINT32 ui32PDEAlignShift; -+ -+} PDUMP_MMU_ATTRIB; -+ -+/* forward reference to _SYS_DATA_ */ -+typedef struct _SYS_DATA_TAG_ *PSYS_DATA; -+ -+typedef struct _PVRSRV_DEVICE_NODE_ -+{ -+ PVRSRV_DEVICE_IDENTIFIER sDevId; -+ IMG_UINT32 ui32RefCount; -+ -+ /* -+ callbacks the device must support: -+ */ -+ /* device initialiser */ -+ PVRSRV_ERROR (*pfnInitDevice) (IMG_VOID*); -+ /* device deinitialiser */ -+ PVRSRV_ERROR (*pfnDeInitDevice) (IMG_VOID*); -+ -+ /* device post-finalise compatibility check */ -+ PVRSRV_ERROR (*pfnInitDeviceCompatCheck) (struct _PVRSRV_DEVICE_NODE_*); -+ -+ /* device MMU interface */ -+ PVRSRV_ERROR (*pfnMMUInitialise)(struct _PVRSRV_DEVICE_NODE_*, MMU_CONTEXT**, IMG_DEV_PHYADDR*); -+ IMG_VOID (*pfnMMUFinalise)(MMU_CONTEXT*); -+ IMG_VOID (*pfnMMUInsertHeap)(MMU_CONTEXT*, MMU_HEAP*); -+ MMU_HEAP* (*pfnMMUCreate)(MMU_CONTEXT*,DEV_ARENA_DESCRIPTOR*,RA_ARENA**,PDUMP_MMU_ATTRIB **ppsMMUAttrib); -+ IMG_VOID (*pfnMMUDelete)(MMU_HEAP*); -+ IMG_BOOL (*pfnMMUAlloc)(MMU_HEAP*pMMU, -+ IMG_SIZE_T uSize, -+ IMG_SIZE_T *pActualSize, -+ IMG_UINT32 uFlags, -+ IMG_UINT32 uDevVAddrAlignment, -+ IMG_DEV_VIRTADDR *pDevVAddr); -+ IMG_VOID (*pfnMMUFree)(MMU_HEAP*,IMG_DEV_VIRTADDR,IMG_UINT32); -+ IMG_VOID (*pfnMMUEnable)(MMU_HEAP*); -+ IMG_VOID (*pfnMMUDisable)(MMU_HEAP*); -+ IMG_VOID (*pfnMMUMapPages)(MMU_HEAP *pMMU, -+ IMG_DEV_VIRTADDR devVAddr, -+ IMG_SYS_PHYADDR SysPAddr, -+ IMG_SIZE_T uSize, -+ IMG_UINT32 ui32MemFlags, -+ IMG_HANDLE hUniqueTag); -+ IMG_VOID (*pfnMMUMapPagesSparse)(MMU_HEAP *pMMU, -+ IMG_DEV_VIRTADDR devVAddr, -+ IMG_SYS_PHYADDR SysPAddr, -+ IMG_UINT32 ui32ChunkSize, -+ IMG_UINT32 ui32NumVirtChunks, -+ IMG_UINT32 ui32NumPhysChunks, -+ IMG_BOOL *pabMapChunk, -+ IMG_UINT32 ui32MemFlags, -+ IMG_HANDLE hUniqueTag); -+ -+ IMG_VOID (*pfnMMUMapShadow)(MMU_HEAP *pMMU, -+ IMG_DEV_VIRTADDR MapBaseDevVAddr, -+ IMG_SIZE_T uSize, -+ IMG_CPU_VIRTADDR CpuVAddr, -+ IMG_HANDLE hOSMemHandle, -+ IMG_DEV_VIRTADDR *pDevVAddr, -+ IMG_UINT32 ui32MemFlags, -+ IMG_HANDLE hUniqueTag); -+ IMG_VOID (*pfnMMUMapShadowSparse)(MMU_HEAP *pMMU, -+ IMG_DEV_VIRTADDR MapBaseDevVAddr, -+ IMG_UINT32 ui32ChunkSize, -+ IMG_UINT32 ui32NumVirtChunks, -+ IMG_UINT32 ui32NumPhysChunks, -+ IMG_BOOL *pabMapChunk, -+ IMG_CPU_VIRTADDR CpuVAddr, -+ IMG_HANDLE hOSMemHandle, -+ IMG_DEV_VIRTADDR *pDevVAddr, -+ IMG_UINT32 ui32MemFlags, -+ IMG_HANDLE hUniqueTag); -+ -+ IMG_VOID (*pfnMMUUnmapPages)(MMU_HEAP *pMMU, -+ IMG_DEV_VIRTADDR dev_vaddr, -+ IMG_UINT32 ui32PageCount, -+ IMG_HANDLE hUniqueTag); -+ -+ IMG_VOID (*pfnMMUMapScatter)(MMU_HEAP *pMMU, -+ IMG_DEV_VIRTADDR DevVAddr, -+ IMG_SYS_PHYADDR *psSysAddr, -+ IMG_SIZE_T uSize, -+ IMG_UINT32 ui32MemFlags, -+ IMG_HANDLE hUniqueTag); -+#if defined(SUPPORT_PDUMP_MULTI_PROCESS) -+ IMG_BOOL (*pfnMMUIsHeapShared)(MMU_HEAP *); -+#endif -+ IMG_DEV_PHYADDR (*pfnMMUGetPhysPageAddr)(MMU_HEAP *pMMUHeap, IMG_DEV_VIRTADDR sDevVPageAddr); -+ IMG_DEV_PHYADDR (*pfnMMUGetPDDevPAddr)(MMU_CONTEXT *pMMUContext); -+ IMG_VOID (*pfnMMUGetCacheFlushRange)(MMU_CONTEXT *pMMUContext, IMG_UINT32 *pui32RangeMask); -+ IMG_VOID (*pfnMMUGetPDPhysAddr)(MMU_CONTEXT *pMMUContext, IMG_DEV_PHYADDR *psDevPAddr); -+ -+ /* tiling range control functions */ -+ PVRSRV_ERROR (*pfnAllocMemTilingRange)(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode, -+ PVRSRV_KERNEL_MEM_INFO *psMemInfo, -+ IMG_UINT32 ui32TilingStride, -+ IMG_UINT32 *pui32RangeIndex); -+ PVRSRV_ERROR (*pfnFreeMemTilingRange)(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode, -+ IMG_UINT32 ui32RangeIndex); -+ -+ /* LISR handler for device */ -+ IMG_BOOL (*pfnDeviceISR)(IMG_VOID*); -+ /* ISR data */ -+ IMG_VOID *pvISRData; -+ /* System/SOC specific interrupt bit relating to this device */ -+ IMG_UINT32 ui32SOCInterruptBit; -+ /* MISR handler for device */ -+ IMG_VOID (*pfnDeviceMISR)(IMG_VOID*); -+ -+ /* Software command complete callback for device */ -+ IMG_VOID (*pfnDeviceCommandComplete)(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode); -+ /* Flag indicating that command complete callback needs to be reprocessed */ -+ IMG_BOOL bReProcessDeviceCommandComplete; -+ -+ IMG_VOID (*pfnCacheInvalidate)(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode); -+ -+ /* information about the device's address space and heaps */ -+ DEVICE_MEMORY_INFO sDevMemoryInfo; -+ -+ /* private device information */ -+ IMG_VOID *pvDevice; -+ IMG_UINT32 ui32pvDeviceSize; /* required by GetClassDeviceInfo API */ -+ -+ /* Resource Manager Context */ -+ PRESMAN_CONTEXT hResManContext; -+ -+ /* pointer back to parent sysdata */ -+ PSYS_DATA psSysData; -+ -+ /* default MMU PT/PD backing store to use for the device */ -+ RA_ARENA *psLocalDevMemArena; -+ -+ IMG_UINT32 ui32Flags; -+ -+ struct _PVRSRV_DEVICE_NODE_ *psNext; -+ struct _PVRSRV_DEVICE_NODE_ **ppsThis; -+ -+#if defined(PDUMP) -+ /* device-level callback which is called when pdump.exe starts. -+ * Should be implemented in device-specific init code, e.g. sgxinit.c -+ */ -+ PVRSRV_ERROR (*pfnPDumpInitDevice)(struct _PVRSRV_DEVICE_NODE_ *psDeviceNode); -+ /* device-level callback to return pdump ID associated to a memory context */ -+ IMG_UINT32 (*pfnMMUGetContextID)(IMG_HANDLE hDevMemContext); -+#endif -+} PVRSRV_DEVICE_NODE; -+ -+PVRSRV_ERROR IMG_CALLCONV PVRSRVRegisterDevice(PSYS_DATA psSysData, -+ PVRSRV_ERROR (*pfnRegisterDevice)(PVRSRV_DEVICE_NODE*), -+ IMG_UINT32 ui32SOCInterruptBit, -+ IMG_UINT32 *pui32DeviceIndex ); -+ -+PVRSRV_ERROR IMG_CALLCONV PVRSRVInitialiseDevice(IMG_UINT32 ui32DevIndex); -+PVRSRV_ERROR IMG_CALLCONV PVRSRVFinaliseSystem(IMG_BOOL bInitSuccesful); -+ -+PVRSRV_ERROR IMG_CALLCONV PVRSRVDevInitCompatCheck(PVRSRV_DEVICE_NODE *psDeviceNode); -+ -+PVRSRV_ERROR IMG_CALLCONV PVRSRVDeinitialiseDevice(IMG_UINT32 ui32DevIndex); -+ -+#if !defined(USE_CODE) -+ -+/*! -+****************************************************************************** -+ -+ @Function PollForValueKM -+ -+ @Description -+ Polls for a value to match a masked read of sysmem -+ -+ @Input pui32LinMemAddr : CPU linear address of the mem to poll -+ @Input ui32Value : req'd value -+ @Input ui32Mask : Mask -+ @Input ui32Timeoutus : maximum total time to wait (us) -+ @Input ui32PollPeriodus : minimum delay between consecutive polls (us) -+ @Input bAllowPreemption : allow the polling loop to be preempted -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV PollForValueKM(volatile IMG_UINT32* pui32LinMemAddr, -+ IMG_UINT32 ui32Value, -+ IMG_UINT32 ui32Mask, -+ IMG_UINT32 ui32Timeoutus, -+ IMG_UINT32 ui32PollPeriodus, -+ IMG_BOOL bAllowPreemption); -+ -+#endif /* !defined(USE_CODE) */ -+ -+ -+#if defined (USING_ISR_INTERRUPTS) -+PVRSRV_ERROR IMG_CALLCONV PollForInterruptKM(IMG_UINT32 ui32Value, -+ IMG_UINT32 ui32Mask, -+ IMG_UINT32 ui32Waitus, -+ IMG_UINT32 ui32Tries); -+ -+#endif /* #if defined (USING_ISR_INTERRUPTS) */ -+ -+/* The following functions don't really belong here (srvkm.h might be a better -+ * place), but as they use the device data structures, this is the most convenient -+ * place for them. */ -+PVRSRV_ERROR IMG_CALLCONV PVRSRVInit(PSYS_DATA psSysData); -+IMG_VOID IMG_CALLCONV PVRSRVDeInit(PSYS_DATA psSysData); -+IMG_BOOL IMG_CALLCONV PVRSRVDeviceLISR(PVRSRV_DEVICE_NODE *psDeviceNode); -+IMG_BOOL IMG_CALLCONV PVRSRVSystemLISR(IMG_VOID *pvSysData); -+IMG_VOID IMG_CALLCONV PVRSRVMISR(IMG_VOID *pvSysData); -+ -+#if defined(__cplusplus) -+} -+#endif -+ -+#endif /* __DEVICE_H__ */ -+ -+/****************************************************************************** -+ End of file (device.h) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/include/devicemem.h b/drivers/staging/ti-es8-sgx/services4/srvkm/include/devicemem.h -new file mode 100644 -index 0000000..00f8fe1 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/include/devicemem.h -@@ -0,0 +1,52 @@ -+/*************************************************************************/ /*! -+@Title KM internal device memory functions -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#include "img_defs.h" -+#include "img_types.h" -+#include "servicesext.h" -+ -+#ifndef __DEVICEMEM_H__ -+#define __DEVICEMEM_H__ -+ -+PVRSRV_ERROR IMG_CALLCONV PVRSRVInitDeviceMem(IMG_VOID); -+IMG_VOID IMG_CALLCONV PVRSRVDeInitDeviceMem(IMG_VOID); -+ -+#endif /* __DEVICEMEM_H__ */ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/include/handle.h b/drivers/staging/ti-es8-sgx/services4/srvkm/include/handle.h -new file mode 100644 -index 0000000..f636073 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/include/handle.h -@@ -0,0 +1,547 @@ -+/*************************************************************************/ /*! -+@Title Handle Manager API -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Provide handle management -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+#ifndef __HANDLE_H__ -+#define __HANDLE_H__ -+ -+/* -+ * Handle API -+ * ---------- -+ * The handle API is intended to provide handles for kernel resources, -+ * which can then be passed back to user space processes. -+ * -+ * The following functions comprise the API. Each function takes a -+ * pointer to a PVRSRV_HANDLE_BASE strcture, one of which is allocated -+ * for each process, and stored in the per-process data area. Use -+ * KERNEL_HANDLE_BASE for handles not allocated for a particular process, -+ * or for handles that need to be allocated before the PVRSRV_HANDLE_BASE -+ * structure for the process is available. -+ * -+ * PVRSRV_ERROR PVRSRVAllocHandle(PVRSRV_HANDLE_BASE *psBase, -+ * IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, -+ * PVRSRV_HANDLE_ALLOC_FLAG eFlag); -+ * -+ * Allocate a handle phHandle, for the resource of type eType pointed to by -+ * pvData. -+ * -+ * For handles that have a definite lifetime, where the corresponding -+ * resource is explicitly created and destroyed, eFlag should be zero. -+ * -+ * If the resource is not explicitly created and destroyed, eFlag should be -+ * set to PVRSRV_HANDLE_ALLOC_FLAG_SHARED. For a given process, the same -+ * handle will be returned each time a handle for the resource is allocated -+ * with the PVRSRV_HANDLE_ALLOC_FLAG_SHARED flag. -+ * -+ * If a particular resource may be referenced multiple times by a -+ * given process, setting eFlag to PVRSRV_HANDLE_ALLOC_FLAG_MULTI -+ * will allow multiple handles to be allocated for the resource. -+ * Such handles cannot be found with PVRSRVFindHandle. -+ * -+ * PVRSRV_ERROR PVRSRVAllocSubHandle(PVRSRV_HANDLE_BASE *psBase, -+ * IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, -+ * PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_HANDLE hParent); -+ * -+ * This function is similar to PVRSRVAllocHandle, except that the allocated -+ * handles are associated with a parent handle, hParent, that has been -+ * allocated previously. Subhandles are automatically deallocated when their -+ * parent handle is dealloacted. -+ * Subhandles can be treated as ordinary handles. For example, they may -+ * have subhandles of their own, and may be explicity deallocated using -+ * PVRSRVReleaseHandle (see below). -+ * -+ * PVRSRV_ERROR PVRSRVFindHandle(PVRSRV_HANDLE_BASE *psBase, -+ * IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType); -+ * -+ * Find the handle previously allocated for the resource pointed to by -+ * pvData, of type eType. Handles allocated with the flag -+ * PVRSRV_HANDLE_ALLOC_FLAG_MULTI cannot be found using this -+ * function. -+ * -+ * PVRSRV_ERROR PVRSRVLookupHandle(PVRSRV_HANDLE_BASE *psBase, -+ * IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType); -+ * -+ * Given a handle for a resource of type eType, return the pointer to the -+ * resource. -+ * -+ * PVRSRV_ERROR PVRSRVLookuSubHandle(PVRSRV_HANDLE_BASE *psBase, -+ * IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType, -+ * IMH_HANDLE hAncestor); -+ * -+ * Similar to PVRSRVLookupHandle, but checks the handle is a descendent -+ * of hAncestor. -+ * -+ * PVRSRV_ERROR PVRSRVLookupHandleAnyType(PVRSRV_HANDLE_BASE *psBase, -+ * IMG_PVOID *ppvData, PVRSRV_HANDLE_TYPE *peType, IMG_HANDLE hHandle); -+ * -+ * This function returns the resource pointer corresponding to the -+ * given handle, and the resource type in peType. This function is -+ * intended for situations where a handle may be one of several types, -+ * but the type isn't known beforehand. -+ * -+ * PVRSRV_ERROR PVRSRVReleaseHandle(PVRSRV_HANDLE_BASE *psBase, -+ * IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType); -+ * -+ * Deallocate a handle of given type. -+ * -+ * PVRSRV_ERROR PVRSRVLookupAndReleaseHandle(PVRSRV_HANDLE_BASE *psBase, -+ * IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType); -+ * -+ * This function combines the functionality of PVRSRVLookupHandle and -+ * PVRSRVReleaseHandle, deallocating the handle after looking it up. -+ * -+ * PVRSRV_ERROR PVRSRVGetParentHandle(PVRSRV_HANDLE_BASE *psBase, -+ * IMG_PVOID *phParent, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType); -+ * -+ * Return the parent of a handle in *phParent, or IMG_NULL if the handle has -+ * no parent. -+ * -+ * PVRSRV_ERROR PVRSRVNewHandleBatch(PVRSRV_HANDLE_BASE *psBase, -+ * IMG_UINT32 ui32BatchSize) -+ * -+ * Allocate a new handle batch. This preallocates ui32BatchSize handles. -+ * Batch mode simplifies the handling of handle allocation failures. -+ * The handle API is unchanged in batch mode, except that handles freed -+ * in batch mode will not be available for reallocation until the batch -+ * is committed or released (see below). -+ * -+ * PVRSRV_ERROR PVRSRVCommitHandleBatch(PVRSRV_HANDLE_BASE *psBase) -+ * void PVRSRVReleaseHandleBatch(PVRSRV_HANDLE_BASE *psBase) -+ * -+ * When handle allocation from a handle batch is complete, the -+ * batch must be committed by calling PVRSRVCommitHandleBatch. If -+ * an error occurred, and none of the handles in the batch are no -+ * longer needed, PVRSRVReleaseHandleBatch must be called. -+ * The macros PVRSRVAllocHandleNR, and PVRSRVAllocSubHandleNR -+ * are defined for use in batch mode. These work the same way -+ * as PVRSRVAllocHandle and PVRSRVAllocSubHandle, except that -+ * they don't return a value, relying on the fact that -+ * PVRSRVCommitHandleBatch will not commit any of the handles -+ * in a batch if there was an error allocating one of the -+ * handles in the batch. -+ * -+ * PVRSRV_ERROR PVRSRVSetMaxHandle(PVRSRV_HANDLE_BASE *psBase, -+ * IMG_UINT32 ui32MaxHandle) -+ * Set the maximum handle number. This is intended to restrict the -+ * handle range so that it will fit within a given field width. For -+ * example, setting the maximum handle number to 0x7fffffff, would -+ * ensure the handles would fit within a 31 bit width field. This -+ * facility should be used with caution, as it restricts the number of -+ * handles that can be allocated. -+ * -+ * IMG_UINT32 PVRSRVGetMaxHandle(PVRSRV_HANDLE_BASE *psBase) -+ * Return the maximum handle number, or 0 if the setting of a limit -+ * is not supported. -+ * -+ * PVRSRV_ERROR PVRSRVEnableHandlePurging(PVRSRV_HANDLE_BASE *psBase) -+ * Allows unused handle space to be reclaimed, by calling -+ * PVRSRVPurgeHandles. Note that allocating handles may have a -+ * higher overhead if purging is enabled. -+ * -+ * PVRSRV_ERROR PVRSRVPurgeHandles((PVRSRV_HANDLE_BASE *psBase) -+ * Purge handles for a handle base that has purging enabled. -+ */ -+ -+#if defined (__cplusplus) -+extern "C" { -+#endif -+ -+#include "img_types.h" -+#include "hash.h" -+#include "resman.h" -+ -+typedef enum -+{ -+ PVRSRV_HANDLE_TYPE_NONE = 0, -+ PVRSRV_HANDLE_TYPE_PERPROC_DATA, -+ PVRSRV_HANDLE_TYPE_DEV_NODE, -+ PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT, -+ PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP, -+ PVRSRV_HANDLE_TYPE_MEM_INFO, -+ PVRSRV_HANDLE_TYPE_SYNC_INFO, -+ PVRSRV_HANDLE_TYPE_DISP_INFO, -+ PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN, -+ PVRSRV_HANDLE_TYPE_BUF_INFO, -+ PVRSRV_HANDLE_TYPE_DISP_BUFFER, -+ PVRSRV_HANDLE_TYPE_BUF_BUFFER, -+ PVRSRV_HANDLE_TYPE_SGX_HW_RENDER_CONTEXT, -+ PVRSRV_HANDLE_TYPE_SGX_HW_TRANSFER_CONTEXT, -+ PVRSRV_HANDLE_TYPE_SGX_HW_2D_CONTEXT, -+ PVRSRV_HANDLE_TYPE_SHARED_PB_DESC, -+ PVRSRV_HANDLE_TYPE_MEM_INFO_REF, -+ PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO, -+ PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT, -+ PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT, -+ PVRSRV_HANDLE_TYPE_MMAP_INFO, -+ PVRSRV_HANDLE_TYPE_SOC_TIMER, -+ PVRSRV_HANDLE_TYPE_SYNC_INFO_MOD_OBJ, -+ PVRSRV_HANDLE_TYPE_RESITEM_INFO -+} PVRSRV_HANDLE_TYPE; -+ -+typedef enum -+{ -+ /* No flags */ -+ PVRSRV_HANDLE_ALLOC_FLAG_NONE = 0, -+ /* Share a handle that already exists for a given data pointer */ -+ PVRSRV_HANDLE_ALLOC_FLAG_SHARED = 0x01, -+ /* Muliple handles can point at the given data pointer */ -+ PVRSRV_HANDLE_ALLOC_FLAG_MULTI = 0x02, -+ /* Subhandles are allocated in a private handle space */ -+ PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE = 0x04 -+} PVRSRV_HANDLE_ALLOC_FLAG; -+ -+struct _PVRSRV_HANDLE_BASE_; -+typedef struct _PVRSRV_HANDLE_BASE_ PVRSRV_HANDLE_BASE; -+ -+#if defined(PVR_SECURE_HANDLES) -+extern PVRSRV_HANDLE_BASE *gpsKernelHandleBase; -+ -+#define KERNEL_HANDLE_BASE (gpsKernelHandleBase) -+ -+PVRSRV_ERROR PVRSRVAllocHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag); -+ -+PVRSRV_ERROR PVRSRVAllocSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_HANDLE hParent); -+ -+PVRSRV_ERROR PVRSRVFindHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType); -+ -+PVRSRV_ERROR PVRSRVLookupHandleAnyType(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, PVRSRV_HANDLE_TYPE *peType, IMG_HANDLE hHandle); -+ -+PVRSRV_ERROR PVRSRVLookupHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType); -+ -+PVRSRV_ERROR PVRSRVLookupSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType, IMG_HANDLE hAncestor); -+ -+PVRSRV_ERROR PVRSRVGetParentHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *phParent, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType); -+ -+PVRSRV_ERROR PVRSRVLookupAndReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType); -+ -+PVRSRV_ERROR PVRSRVReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType); -+ -+PVRSRV_ERROR PVRSRVNewHandleBatch(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32BatchSize); -+ -+PVRSRV_ERROR PVRSRVCommitHandleBatch(PVRSRV_HANDLE_BASE *psBase); -+ -+IMG_VOID PVRSRVReleaseHandleBatch(PVRSRV_HANDLE_BASE *psBase); -+ -+PVRSRV_ERROR PVRSRVSetMaxHandle(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32MaxHandle); -+ -+IMG_UINT32 PVRSRVGetMaxHandle(PVRSRV_HANDLE_BASE *psBase); -+ -+PVRSRV_ERROR PVRSRVEnableHandlePurging(PVRSRV_HANDLE_BASE *psBase); -+ -+PVRSRV_ERROR PVRSRVPurgeHandles(PVRSRV_HANDLE_BASE *psBase); -+ -+PVRSRV_ERROR PVRSRVAllocHandleBase(PVRSRV_HANDLE_BASE **ppsBase); -+ -+PVRSRV_ERROR PVRSRVFreeHandleBase(PVRSRV_HANDLE_BASE *psBase); -+ -+PVRSRV_ERROR PVRSRVHandleInit(IMG_VOID); -+ -+PVRSRV_ERROR PVRSRVHandleDeInit(IMG_VOID); -+ -+#else /* #if defined (PVR_SECURE_HANDLES) */ -+ -+#define KERNEL_HANDLE_BASE IMG_NULL -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(PVRSRVAllocHandle) -+#endif -+static INLINE -+PVRSRV_ERROR PVRSRVAllocHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag) -+{ -+ PVR_UNREFERENCED_PARAMETER(eType); -+ PVR_UNREFERENCED_PARAMETER(eFlag); -+ PVR_UNREFERENCED_PARAMETER(psBase); -+ -+ *phHandle = pvData; -+ return PVRSRV_OK; -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(PVRSRVAllocSubHandle) -+#endif -+static INLINE -+PVRSRV_ERROR PVRSRVAllocSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType, PVRSRV_HANDLE_ALLOC_FLAG eFlag, IMG_HANDLE hParent) -+{ -+ PVR_UNREFERENCED_PARAMETER(eType); -+ PVR_UNREFERENCED_PARAMETER(eFlag); -+ PVR_UNREFERENCED_PARAMETER(hParent); -+ PVR_UNREFERENCED_PARAMETER(psBase); -+ -+ *phHandle = pvData; -+ return PVRSRV_OK; -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(PVRSRVFindHandle) -+#endif -+static INLINE -+PVRSRV_ERROR PVRSRVFindHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData, PVRSRV_HANDLE_TYPE eType) -+{ -+ PVR_UNREFERENCED_PARAMETER(eType); -+ PVR_UNREFERENCED_PARAMETER(psBase); -+ -+ *phHandle = pvData; -+ return PVRSRV_OK; -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(PVRSRVLookupHandleAnyType) -+#endif -+static INLINE -+PVRSRV_ERROR PVRSRVLookupHandleAnyType(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, PVRSRV_HANDLE_TYPE *peType, IMG_HANDLE hHandle) -+{ -+ PVR_UNREFERENCED_PARAMETER(psBase); -+ /* -+ * Unlike the other functions here, the returned results will need -+ * to be handled differently for the secure and non-secure cases. -+ */ -+ *peType = PVRSRV_HANDLE_TYPE_NONE; -+ -+ *ppvData = hHandle; -+ return PVRSRV_OK; -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(PVRSRVLookupHandle) -+#endif -+static INLINE -+PVRSRV_ERROR PVRSRVLookupHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType) -+{ -+ PVR_UNREFERENCED_PARAMETER(psBase); -+ PVR_UNREFERENCED_PARAMETER(eType); -+ -+ *ppvData = hHandle; -+ return PVRSRV_OK; -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(PVRSRVLookupSubHandle) -+#endif -+static INLINE -+PVRSRV_ERROR PVRSRVLookupSubHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType, IMG_HANDLE hAncestor) -+{ -+ PVR_UNREFERENCED_PARAMETER(psBase); -+ PVR_UNREFERENCED_PARAMETER(eType); -+ PVR_UNREFERENCED_PARAMETER(hAncestor); -+ -+ *ppvData = hHandle; -+ return PVRSRV_OK; -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(PVRSRVGetParentHandle) -+#endif -+static INLINE -+PVRSRV_ERROR PVRSRVGetParentHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *phParent, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType) -+{ -+ PVR_UNREFERENCED_PARAMETER(psBase); -+ PVR_UNREFERENCED_PARAMETER(eType); -+ PVR_UNREFERENCED_PARAMETER(hHandle); -+ -+ *phParent = IMG_NULL; -+ -+ return PVRSRV_OK; -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(PVRSRVLookupAndReleaseHandle) -+#endif -+static INLINE -+PVRSRV_ERROR PVRSRVLookupAndReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_PVOID *ppvData, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType) -+{ -+ PVR_UNREFERENCED_PARAMETER(eType); -+ PVR_UNREFERENCED_PARAMETER(psBase); -+ -+ *ppvData = hHandle; -+ return PVRSRV_OK; -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(PVRSRVReleaseHandle) -+#endif -+static INLINE -+PVRSRV_ERROR PVRSRVReleaseHandle(PVRSRV_HANDLE_BASE *psBase, IMG_HANDLE hHandle, PVRSRV_HANDLE_TYPE eType) -+{ -+ PVR_UNREFERENCED_PARAMETER(hHandle); -+ PVR_UNREFERENCED_PARAMETER(eType); -+ PVR_UNREFERENCED_PARAMETER(psBase); -+ -+ return PVRSRV_OK; -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(PVRSRVNewHandleBatch) -+#endif -+static INLINE -+PVRSRV_ERROR PVRSRVNewHandleBatch(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32BatchSize) -+{ -+ PVR_UNREFERENCED_PARAMETER(psBase); -+ PVR_UNREFERENCED_PARAMETER(ui32BatchSize); -+ -+ return PVRSRV_OK; -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(PVRSRVCommitHandleBatch) -+#endif -+static INLINE -+PVRSRV_ERROR PVRSRVCommitHandleBatch(PVRSRV_HANDLE_BASE *psBase) -+{ -+ PVR_UNREFERENCED_PARAMETER(psBase); -+ -+ return PVRSRV_OK; -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(PVRSRVReleaseHandleBatch) -+#endif -+static INLINE -+IMG_VOID PVRSRVReleaseHandleBatch(PVRSRV_HANDLE_BASE *psBase) -+{ -+ PVR_UNREFERENCED_PARAMETER(psBase); -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(PVRSRVSetMaxHandle) -+#endif -+static INLINE -+PVRSRV_ERROR PVRSRVSetMaxHandle(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32MaxHandle) -+{ -+ PVR_UNREFERENCED_PARAMETER(psBase); -+ PVR_UNREFERENCED_PARAMETER(ui32MaxHandle); -+ -+ return PVRSRV_ERROR_NOT_SUPPORTED; -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(PVRSRVGetMaxHandle) -+#endif -+static INLINE -+IMG_UINT32 PVRSRVGetMaxHandle(PVRSRV_HANDLE_BASE *psBase) -+{ -+ PVR_UNREFERENCED_PARAMETER(psBase); -+ -+ return 0; -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(PVRSRVEnableHandlePurging) -+#endif -+static INLINE -+PVRSRV_ERROR PVRSRVEnableHandlePurging(PVRSRV_HANDLE_BASE *psBase) -+{ -+ PVR_UNREFERENCED_PARAMETER(psBase); -+ -+ return PVRSRV_OK; -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(PVRSRVPurgeHandles) -+#endif -+static INLINE -+PVRSRV_ERROR PVRSRVPurgeHandles(PVRSRV_HANDLE_BASE *psBase) -+{ -+ PVR_UNREFERENCED_PARAMETER(psBase); -+ -+ return PVRSRV_OK; -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(PVRSRVAllocHandleBase) -+#endif -+static INLINE -+PVRSRV_ERROR PVRSRVAllocHandleBase(PVRSRV_HANDLE_BASE **ppsBase) -+{ -+ *ppsBase = IMG_NULL; -+ -+ return PVRSRV_OK; -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(PVRSRVFreeHandleBase) -+#endif -+static INLINE -+PVRSRV_ERROR PVRSRVFreeHandleBase(PVRSRV_HANDLE_BASE *psBase) -+{ -+ PVR_UNREFERENCED_PARAMETER(psBase); -+ -+ return PVRSRV_OK; -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(PVRSRVHandleInit) -+#endif -+static INLINE -+PVRSRV_ERROR PVRSRVHandleInit(IMG_VOID) -+{ -+ return PVRSRV_OK; -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(PVRSRVHandleDeInit) -+#endif -+static INLINE -+PVRSRV_ERROR PVRSRVHandleDeInit(IMG_VOID) -+{ -+ return PVRSRV_OK; -+} -+ -+#endif /* #if defined (PVR_SECURE_HANDLES) */ -+ -+/* -+ * Versions of PVRSRVAllocHandle and PVRSRVAllocSubHandle with no return -+ * values. Intended for use with batched handle allocation, relying on -+ * CommitHandleBatch to detect handle allocation errors. -+ */ -+#define PVRSRVAllocHandleNR(psBase, phHandle, pvData, eType, eFlag) \ -+ (IMG_VOID)PVRSRVAllocHandle(psBase, phHandle, pvData, eType, eFlag) -+ -+#define PVRSRVAllocSubHandleNR(psBase, phHandle, pvData, eType, eFlag, hParent) \ -+ (IMG_VOID)PVRSRVAllocSubHandle(psBase, phHandle, pvData, eType, eFlag, hParent) -+ -+#if defined (__cplusplus) -+} -+#endif -+ -+#endif /* __HANDLE_H__ */ -+ -+/****************************************************************************** -+ End of file (handle.h) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/include/hash.h b/drivers/staging/ti-es8-sgx/services4/srvkm/include/hash.h -new file mode 100644 -index 0000000..56c4513 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/include/hash.h -@@ -0,0 +1,275 @@ -+/*************************************************************************/ /*! -+@Title Self scaling hash tables -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Implements simple self scaling hash tables. -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#ifndef _HASH_H_ -+#define _HASH_H_ -+ -+#include "img_types.h" -+#include "osfunc.h" -+ -+#if defined (__cplusplus) -+extern "C" { -+#endif -+ -+/* -+ * Keys passed to the comparsion function are only guaranteed to -+ * be aligned on an IMG_UINTPTR_T boundary. -+ */ -+typedef IMG_UINT32 HASH_FUNC(IMG_SIZE_T uKeySize, IMG_VOID *pKey, IMG_UINT32 uHashTabLen); -+typedef IMG_BOOL HASH_KEY_COMP(IMG_SIZE_T uKeySize, IMG_VOID *pKey1, IMG_VOID *pKey2); -+ -+typedef struct _HASH_TABLE_ HASH_TABLE; -+ -+typedef PVRSRV_ERROR (*HASH_pfnCallback) ( -+ IMG_UINTPTR_T k, -+ IMG_UINTPTR_T v -+); -+ -+/*! -+****************************************************************************** -+ @Function HASH_Func_Default -+ -+ @Description Hash function intended for hashing keys composed of -+ IMG_UINTPTR_T arrays. -+ -+ @Input uKeySize - the size of the hash key, in bytes. -+ @Input pKey - a pointer to the key to hash. -+ @Input uHashTabLen - the length of the hash table. -+ -+ @Return The hash value. -+******************************************************************************/ -+IMG_UINT32 HASH_Func_Default (IMG_SIZE_T uKeySize, IMG_VOID *pKey, IMG_UINT32 uHashTabLen); -+ -+/*! -+****************************************************************************** -+ @Function HASH_Key_Comp_Default -+ -+ @Description Compares keys composed of IMG_UINTPTR_T arrays. -+ -+ @Input uKeySize - the size of the hash key, in bytes. -+ @Input pKey1 - pointer to first hash key to compare. -+ @Input pKey2 - pointer to second hash key to compare. -+ -+ @Return IMG_TRUE - the keys match. -+ IMG_FALSE - the keys don't match. -+******************************************************************************/ -+IMG_BOOL HASH_Key_Comp_Default (IMG_SIZE_T uKeySize, IMG_VOID *pKey1, IMG_VOID *pKey2); -+ -+/*! -+****************************************************************************** -+ @Function HASH_Create_Extended -+ -+ @Description Create a self scaling hash table, using the supplied -+ key size, and the supllied hash and key comparsion -+ functions. -+ -+ @Input uInitialLen - initial and minimum length of the -+ hash table, where the length refers to the number -+ of entries in the hash table, not its size in -+ bytes. -+ @Input uKeySize - the size of the key, in bytes. -+ @Input pfnHashFunc - pointer to hash function. -+ @Input pfnKeyComp - pointer to key comparsion function. -+ -+ @Return IMG_NULL or hash table handle. -+******************************************************************************/ -+HASH_TABLE * HASH_Create_Extended (IMG_UINT32 uInitialLen, IMG_SIZE_T uKeySize, HASH_FUNC *pfnHashFunc, HASH_KEY_COMP *pfnKeyComp); -+ -+/*! -+****************************************************************************** -+ @Function HASH_Create -+ -+ @Description Create a self scaling hash table with a key -+ consisting of a single IMG_UINTPTR_T, and using -+ the default hash and key comparison functions. -+ -+ @Input uInitialLen - initial and minimum length of the -+ hash table, where the length refers to the -+ number of entries in the hash table, not its size -+ in bytes. -+ -+ @Return IMG_NULL or hash table handle. -+******************************************************************************/ -+HASH_TABLE * HASH_Create (IMG_UINT32 uInitialLen); -+ -+/*! -+****************************************************************************** -+ @Function HASH_Delete -+ -+ @Description Delete a hash table created by HASH_Create_Extended or -+ HASH_Create. All entries in the table must have been -+ removed before calling this function. -+ -+ @Input pHash - hash table -+ -+ @Return None -+******************************************************************************/ -+IMG_VOID HASH_Delete (HASH_TABLE *pHash); -+ -+/*! -+****************************************************************************** -+ @Function HASH_Insert_Extended -+ -+ @Description Insert a key value pair into a hash table created -+ with HASH_Create_Extended. -+ -+ @Input pHash - the hash table. -+ @Input pKey - pointer to the key. -+ @Input v - the value associated with the key. -+ -+ @Return IMG_TRUE - success. -+ IMG_FALSE - failure. -+******************************************************************************/ -+IMG_BOOL HASH_Insert_Extended (HASH_TABLE *pHash, IMG_VOID *pKey, IMG_UINTPTR_T v); -+ -+/*! -+****************************************************************************** -+ @Function HASH_Insert -+ -+ @Description Insert a key value pair into a hash table created with -+ HASH_Create. -+ -+ @Input pHash - the hash table. -+ @Input k - the key value. -+ @Input v - the value associated with the key. -+ -+ @Return IMG_TRUE - success. -+ IMG_FALSE - failure. -+******************************************************************************/ -+IMG_BOOL HASH_Insert (HASH_TABLE *pHash, IMG_UINTPTR_T k, IMG_UINTPTR_T v); -+ -+/*! -+****************************************************************************** -+ @Function HASH_Remove_Extended -+ -+ @Description Remove a key from a hash table created with -+ HASH_Create_Extended. -+ -+ @Input pHash - the hash table. -+ @Input pKey - pointer to key. -+ -+ @Return 0 if the key is missing, or the value associated -+ with the key. -+******************************************************************************/ -+IMG_UINTPTR_T HASH_Remove_Extended(HASH_TABLE *pHash, IMG_VOID *pKey); -+ -+/*! -+****************************************************************************** -+ @Function HASH_Remove -+ -+ @Description Remove a key value pair from a hash table created -+ with HASH_Create. -+ -+ @Input pHash - the hash table -+ @Input k - the key -+ -+ @Return 0 if the key is missing, or the value associated -+ with the key. -+******************************************************************************/ -+IMG_UINTPTR_T HASH_Remove (HASH_TABLE *pHash, IMG_UINTPTR_T k); -+ -+/*! -+****************************************************************************** -+ @Function HASH_Retrieve_Extended -+ -+ @Description Retrieve a value from a hash table created with -+ HASH_Create_Extended. -+ -+ @Input pHash - the hash table. -+ @Input pKey - pointer to the key. -+ -+ @Return 0 if the key is missing, or the value associated with -+ the key. -+******************************************************************************/ -+IMG_UINTPTR_T HASH_Retrieve_Extended (HASH_TABLE *pHash, IMG_VOID *pKey); -+ -+/*! -+****************************************************************************** -+ @Function HASH_Retrieve -+ -+ @Description Retrieve a value from a hash table created with -+ HASH_Create. -+ -+ @Input pHash - the hash table -+ @Input k - the key -+ -+ @Return 0 if the key is missing, or the value associated with -+ the key. -+******************************************************************************/ -+IMG_UINTPTR_T HASH_Retrieve (HASH_TABLE *pHash, IMG_UINTPTR_T k); -+ -+/*! -+****************************************************************************** -+ @Function HASH_Interate -+ -+ @Description Iterate over every entry in the hash table -+ -+ @Input pHash - the old hash table -+ @Input HASH_pfnCallback - the size of the old hash table -+ -+ @Return Callback error if any, otherwise PVRSRV_OK -+******************************************************************************/ -+PVRSRV_ERROR HASH_Iterate(HASH_TABLE *pHash, HASH_pfnCallback pfnCallback); -+ -+#ifdef HASH_TRACE -+/*! -+****************************************************************************** -+ @Function HASH_Dump -+ -+ @Description Dump out some information about a hash table. -+ -+ @Input pHash - the hash table -+ -+ @Return None -+******************************************************************************/ -+IMG_VOID HASH_Dump (HASH_TABLE *pHash); -+#endif -+ -+#if defined (__cplusplus) -+} -+#endif -+ -+#endif /* _HASH_H_ */ -+ -+/****************************************************************************** -+ End of file (hash.h) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/include/lists.h b/drivers/staging/ti-es8-sgx/services4/srvkm/include/lists.h -new file mode 100644 -index 0000000..445c130 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/include/lists.h -@@ -0,0 +1,349 @@ -+/*************************************************************************/ /*! -+@Title Linked list shared functions templates. -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Definition of the linked list function templates. -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#ifndef __LISTS_UTILS__ -+#define __LISTS_UTILS__ -+ -+/* instruct QAC to ignore warnings about the following custom formatted macros */ -+/* PRQA S 0881,3410 ++ */ -+#include <stdarg.h> -+#include "img_types.h" -+ -+/* -+ - USAGE - -+ -+ The list functions work with any structure that provides the fields psNext and -+ ppsThis. In order to make a function available for a given type, it is required -+ to use the funcion template macro that creates the actual code. -+ -+ There are 4 main types of functions: -+ - INSERT : given a pointer to the head pointer of the list and a pointer to -+ the node, inserts it as the new head. -+ - REMOVE : given a pointer to a node, removes it from its list. -+ - FOR EACH : apply a function over all the elements of a list. -+ - ANY : apply a function over the elements of a list, until one of them -+ return a non null value, and then returns it. -+ -+ The two last functions can have a variable argument form, with allows to pass -+ additional parameters to the callback function. In order to do this, the -+ callback function must take two arguments, the first is the current node and -+ the second is a list of variable arguments (va_list). -+ -+ The ANY functions have also another for wich specifies the return type of the -+ callback function and the default value returned by the callback function. -+ -+*/ -+ -+/*! -+****************************************************************************** -+ @Function List_##TYPE##_ForEach -+ -+ @Description Apply a callback function to all the elements of a list. -+ -+ @Input psHead - the head of the list to be processed. -+ @Input pfnCallBack - the function to be applied to each element -+ of the list. -+ -+ @Return None -+******************************************************************************/ -+#define DECLARE_LIST_FOR_EACH(TYPE) \ -+IMG_VOID List_##TYPE##_ForEach(TYPE *psHead, IMG_VOID(*pfnCallBack)(TYPE* psNode)) -+ -+#define IMPLEMENT_LIST_FOR_EACH(TYPE) \ -+IMG_VOID List_##TYPE##_ForEach(TYPE *psHead, IMG_VOID(*pfnCallBack)(TYPE* psNode))\ -+{\ -+ while(psHead)\ -+ {\ -+ pfnCallBack(psHead);\ -+ psHead = psHead->psNext;\ -+ }\ -+} -+ -+ -+#define DECLARE_LIST_FOR_EACH_VA(TYPE) \ -+IMG_VOID List_##TYPE##_ForEach_va(TYPE *psHead, IMG_VOID(*pfnCallBack)(TYPE* psNode, va_list va), ...) -+ -+#define IMPLEMENT_LIST_FOR_EACH_VA(TYPE) \ -+IMG_VOID List_##TYPE##_ForEach_va(TYPE *psHead, IMG_VOID(*pfnCallBack)(TYPE* psNode, va_list va), ...) \ -+{\ -+ va_list ap;\ -+ while(psHead)\ -+ {\ -+ va_start(ap, pfnCallBack);\ -+ pfnCallBack(psHead, ap);\ -+ psHead = psHead->psNext;\ -+ va_end(ap);\ -+ }\ -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function List_##TYPE##_Any -+ -+ @Description Applies a callback function to the elements of a list until -+ the function returns a non null value, then returns it. -+ -+ @Input psHead - the head of the list to be processed. -+ @Input pfnCallBack - the function to be applied to each element -+ of the list. -+ -+ @Return None -+******************************************************************************/ -+#define DECLARE_LIST_ANY(TYPE) \ -+IMG_VOID* List_##TYPE##_Any(TYPE *psHead, IMG_VOID* (*pfnCallBack)(TYPE* psNode)) -+ -+#define IMPLEMENT_LIST_ANY(TYPE) \ -+IMG_VOID* List_##TYPE##_Any(TYPE *psHead, IMG_VOID* (*pfnCallBack)(TYPE* psNode))\ -+{ \ -+ IMG_VOID *pResult;\ -+ TYPE *psNextNode;\ -+ pResult = IMG_NULL;\ -+ psNextNode = psHead;\ -+ while(psHead && !pResult)\ -+ {\ -+ psNextNode = psNextNode->psNext;\ -+ pResult = pfnCallBack(psHead);\ -+ psHead = psNextNode;\ -+ }\ -+ return pResult;\ -+} -+ -+ -+/*with variable arguments, that will be passed as a va_list to the callback function*/ -+ -+#define DECLARE_LIST_ANY_VA(TYPE) \ -+IMG_VOID* List_##TYPE##_Any_va(TYPE *psHead, IMG_VOID*(*pfnCallBack)(TYPE* psNode, va_list va), ...) -+ -+#define IMPLEMENT_LIST_ANY_VA(TYPE) \ -+IMG_VOID* List_##TYPE##_Any_va(TYPE *psHead, IMG_VOID*(*pfnCallBack)(TYPE* psNode, va_list va), ...)\ -+{\ -+ va_list ap;\ -+ TYPE *psNextNode;\ -+ IMG_VOID* pResult = IMG_NULL;\ -+ while(psHead && !pResult)\ -+ {\ -+ psNextNode = psHead->psNext;\ -+ va_start(ap, pfnCallBack);\ -+ pResult = pfnCallBack(psHead, ap);\ -+ va_end(ap);\ -+ psHead = psNextNode;\ -+ }\ -+ return pResult;\ -+} -+ -+/*those ones are for extra type safety, so there's no need to use castings for the results*/ -+ -+#define DECLARE_LIST_ANY_2(TYPE, RTYPE, CONTINUE) \ -+RTYPE List_##TYPE##_##RTYPE##_Any(TYPE *psHead, RTYPE (*pfnCallBack)(TYPE* psNode)) -+ -+#define IMPLEMENT_LIST_ANY_2(TYPE, RTYPE, CONTINUE) \ -+RTYPE List_##TYPE##_##RTYPE##_Any(TYPE *psHead, RTYPE (*pfnCallBack)(TYPE* psNode))\ -+{ \ -+ RTYPE result;\ -+ TYPE *psNextNode;\ -+ result = CONTINUE;\ -+ psNextNode = psHead;\ -+ while(psHead && result == CONTINUE)\ -+ {\ -+ psNextNode = psNextNode->psNext;\ -+ result = pfnCallBack(psHead);\ -+ psHead = psNextNode;\ -+ }\ -+ return result;\ -+} -+ -+ -+#define DECLARE_LIST_ANY_VA_2(TYPE, RTYPE, CONTINUE) \ -+RTYPE List_##TYPE##_##RTYPE##_Any_va(TYPE *psHead, RTYPE(*pfnCallBack)(TYPE* psNode, va_list va), ...) -+ -+#define IMPLEMENT_LIST_ANY_VA_2(TYPE, RTYPE, CONTINUE) \ -+RTYPE List_##TYPE##_##RTYPE##_Any_va(TYPE *psHead, RTYPE(*pfnCallBack)(TYPE* psNode, va_list va), ...)\ -+{\ -+ va_list ap;\ -+ TYPE *psNextNode;\ -+ RTYPE result = CONTINUE;\ -+ while(psHead && result == CONTINUE)\ -+ {\ -+ psNextNode = psHead->psNext;\ -+ va_start(ap, pfnCallBack);\ -+ result = pfnCallBack(psHead, ap);\ -+ va_end(ap);\ -+ psHead = psNextNode;\ -+ }\ -+ return result;\ -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function List_##TYPE##_Remove -+ -+ @Description Removes a given node from the list. -+ -+ @Input psNode - the pointer to the node to be removed. -+ -+ @Return None -+******************************************************************************/ -+#define DECLARE_LIST_REMOVE(TYPE) \ -+IMG_VOID List_##TYPE##_Remove(TYPE *psNode) -+ -+#define IMPLEMENT_LIST_REMOVE(TYPE) \ -+IMG_VOID List_##TYPE##_Remove(TYPE *psNode)\ -+{\ -+ (*psNode->ppsThis)=psNode->psNext;\ -+ if(psNode->psNext)\ -+ {\ -+ psNode->psNext->ppsThis = psNode->ppsThis;\ -+ }\ -+} -+ -+/*! -+****************************************************************************** -+ @Function List_##TYPE##_Insert -+ -+ @Description Inserts a given node at the beginnning of the list. -+ -+ @Input psHead - The pointer to the pointer to the head node. -+ @Input psNode - The pointer to the node to be inserted. -+ -+ @Return None -+******************************************************************************/ -+#define DECLARE_LIST_INSERT(TYPE) \ -+IMG_VOID List_##TYPE##_Insert(TYPE **ppsHead, TYPE *psNewNode) -+ -+#define IMPLEMENT_LIST_INSERT(TYPE) \ -+IMG_VOID List_##TYPE##_Insert(TYPE **ppsHead, TYPE *psNewNode)\ -+{\ -+ psNewNode->ppsThis = ppsHead;\ -+ psNewNode->psNext = *ppsHead;\ -+ *ppsHead = psNewNode;\ -+ if(psNewNode->psNext)\ -+ {\ -+ psNewNode->psNext->ppsThis = &(psNewNode->psNext);\ -+ }\ -+} -+ -+/*! -+****************************************************************************** -+ @Function List_##TYPE##_Reverse -+ -+ @Description Reverse a list in place -+ -+ @Input ppsHead - The pointer to the pointer to the head node. -+ -+ @Return None -+******************************************************************************/ -+#define DECLARE_LIST_REVERSE(TYPE) \ -+IMG_VOID List_##TYPE##_Reverse(TYPE **ppsHead) -+ -+#define IMPLEMENT_LIST_REVERSE(TYPE) \ -+IMG_VOID List_##TYPE##_Reverse(TYPE **ppsHead)\ -+{\ -+ TYPE *psTmpNode1; \ -+ TYPE *psTmpNode2; \ -+ TYPE *psCurNode; \ -+ psTmpNode1 = IMG_NULL; \ -+ psCurNode = *ppsHead; \ -+ while(psCurNode) { \ -+ psTmpNode2 = psCurNode->psNext; \ -+ psCurNode->psNext = psTmpNode1; \ -+ psTmpNode1 = psCurNode; \ -+ psCurNode = psTmpNode2; \ -+ if(psCurNode) \ -+ { \ -+ psTmpNode1->ppsThis = &(psCurNode->psNext); \ -+ } \ -+ else \ -+ { \ -+ psTmpNode1->ppsThis = ppsHead; \ -+ } \ -+ } \ -+ *ppsHead = psTmpNode1; \ -+} -+ -+#define IS_LAST_ELEMENT(x) ((x)->psNext == IMG_NULL) -+ -+#include "services_headers.h" -+ -+DECLARE_LIST_ANY_VA(BM_HEAP); -+DECLARE_LIST_ANY_2(BM_HEAP, PVRSRV_ERROR, PVRSRV_OK); -+DECLARE_LIST_ANY_VA_2(BM_HEAP, PVRSRV_ERROR, PVRSRV_OK); -+DECLARE_LIST_FOR_EACH_VA(BM_HEAP); -+DECLARE_LIST_REMOVE(BM_HEAP); -+DECLARE_LIST_INSERT(BM_HEAP); -+ -+DECLARE_LIST_ANY_VA(BM_CONTEXT); -+DECLARE_LIST_ANY_VA_2(BM_CONTEXT, IMG_HANDLE, IMG_NULL); -+DECLARE_LIST_ANY_VA_2(BM_CONTEXT, PVRSRV_ERROR, PVRSRV_OK); -+DECLARE_LIST_FOR_EACH(BM_CONTEXT); -+DECLARE_LIST_REMOVE(BM_CONTEXT); -+DECLARE_LIST_INSERT(BM_CONTEXT); -+ -+DECLARE_LIST_ANY_2(PVRSRV_DEVICE_NODE, PVRSRV_ERROR, PVRSRV_OK); -+DECLARE_LIST_ANY_VA(PVRSRV_DEVICE_NODE); -+DECLARE_LIST_ANY_VA_2(PVRSRV_DEVICE_NODE, PVRSRV_ERROR, PVRSRV_OK); -+DECLARE_LIST_FOR_EACH(PVRSRV_DEVICE_NODE); -+DECLARE_LIST_FOR_EACH_VA(PVRSRV_DEVICE_NODE); -+DECLARE_LIST_INSERT(PVRSRV_DEVICE_NODE); -+DECLARE_LIST_REMOVE(PVRSRV_DEVICE_NODE); -+ -+DECLARE_LIST_ANY_VA(PVRSRV_POWER_DEV); -+DECLARE_LIST_ANY_VA_2(PVRSRV_POWER_DEV, PVRSRV_ERROR, PVRSRV_OK); -+DECLARE_LIST_INSERT(PVRSRV_POWER_DEV); -+DECLARE_LIST_REMOVE(PVRSRV_POWER_DEV); -+ -+#undef DECLARE_LIST_ANY_2 -+#undef DECLARE_LIST_ANY_VA -+#undef DECLARE_LIST_ANY_VA_2 -+#undef DECLARE_LIST_FOR_EACH -+#undef DECLARE_LIST_FOR_EACH_VA -+#undef DECLARE_LIST_INSERT -+#undef DECLARE_LIST_REMOVE -+ -+IMG_VOID* MatchDeviceKM_AnyVaCb(PVRSRV_DEVICE_NODE* psDeviceNode, va_list va); -+IMG_VOID* MatchPowerDeviceIndex_AnyVaCb(PVRSRV_POWER_DEV *psPowerDev, va_list va); -+ -+#endif -+ -+/* re-enable warnings */ -+/* PRQA S 0881,3410 -- */ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/include/metrics.h b/drivers/staging/ti-es8-sgx/services4/srvkm/include/metrics.h -new file mode 100644 -index 0000000..a9eb685 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/include/metrics.h -@@ -0,0 +1,146 @@ -+/*************************************************************************/ /*! -+@Title Time measurement interface. -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#ifndef _METRICS_ -+#define _METRICS_ -+ -+ -+#if defined (__cplusplus) -+extern "C" { -+#endif -+ -+ -+#if defined(DEBUG) || defined(TIMING) -+ -+ -+typedef struct -+{ -+ IMG_UINT32 ui32Start; -+ IMG_UINT32 ui32Stop; -+ IMG_UINT32 ui32Total; -+ IMG_UINT32 ui32Count; -+} Temporal_Data; -+ -+extern Temporal_Data asTimers[]; -+ -+extern IMG_UINT32 PVRSRVTimeNow(IMG_VOID); -+extern IMG_VOID PVRSRVSetupMetricTimers(IMG_VOID *pvDevInfo); -+extern IMG_VOID PVRSRVOutputMetricTotals(IMG_VOID); -+ -+ -+#define PVRSRV_TIMER_DUMMY 0 -+ -+#define PVRSRV_TIMER_EXAMPLE_1 1 -+#define PVRSRV_TIMER_EXAMPLE_2 2 -+ -+ -+#define PVRSRV_NUM_TIMERS (PVRSRV_TIMER_EXAMPLE_2 + 1) -+ -+#define PVRSRV_TIME_START(X) { \ -+ asTimers[X].ui32Count += 1; \ -+ asTimers[X].ui32Count |= 0x80000000L; \ -+ asTimers[X].ui32Start = PVRSRVTimeNow(); \ -+ asTimers[X].ui32Stop = 0; \ -+ } -+ -+#define PVRSRV_TIME_SUSPEND(X) { \ -+ asTimers[X].ui32Stop += PVRSRVTimeNow() - asTimers[X].ui32Start; \ -+ } -+ -+#define PVRSRV_TIME_RESUME(X) { \ -+ asTimers[X].ui32Start = PVRSRVTimeNow(); \ -+ } -+ -+#define PVRSRV_TIME_STOP(X) { \ -+ asTimers[X].ui32Stop += PVRSRVTimeNow() - asTimers[X].ui32Start; \ -+ asTimers[X].ui32Total += asTimers[X].ui32Stop; \ -+ asTimers[X].ui32Count &= 0x7FFFFFFFL; \ -+ } -+ -+#define PVRSRV_TIME_RESET(X) { \ -+ asTimers[X].ui32Start = 0; \ -+ asTimers[X].ui32Stop = 0; \ -+ asTimers[X].ui32Total = 0; \ -+ asTimers[X].ui32Count = 0; \ -+ } -+ -+ -+#if defined(__sh__) -+ -+#define TST_REG ((volatile IMG_UINT8 *) (psDevInfo->pvSOCRegsBaseKM)) // timer start register -+ -+#define TCOR_2 ((volatile IMG_UINT *) (psDevInfo->pvSOCRegsBaseKM+28)) // timer constant register_2 -+#define TCNT_2 ((volatile IMG_UINT *) (psDevInfo->pvSOCRegsBaseKM+32)) // timer counter register_2 -+#define TCR_2 ((volatile IMG_UINT16 *)(psDevInfo->pvSOCRegsBaseKM+36)) // timer control register_2 -+ -+#define TIMER_DIVISOR 4 -+ -+#endif /* defined(__sh__) */ -+ -+ -+ -+#else /* defined(DEBUG) || defined(TIMING) */ -+ -+ -+ -+#define PVRSRV_TIME_START(X) -+#define PVRSRV_TIME_SUSPEND(X) -+#define PVRSRV_TIME_RESUME(X) -+#define PVRSRV_TIME_STOP(X) -+#define PVRSRV_TIME_RESET(X) -+ -+#define PVRSRVSetupMetricTimers(X) -+#define PVRSRVOutputMetricTotals() -+ -+ -+ -+#endif /* defined(DEBUG) || defined(TIMING) */ -+ -+#if defined(__cplusplus) -+} -+#endif -+ -+ -+#endif /* _METRICS_ */ -+ -+/************************************************************************** -+ End of file (metrics.h) -+**************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/include/osfunc.h b/drivers/staging/ti-es8-sgx/services4/srvkm/include/osfunc.h -new file mode 100644 -index 0000000..92fd4b6 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/include/osfunc.h -@@ -0,0 +1,785 @@ -+/*************************************************************************/ /*! -+@Title OS functions header -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description OS specific API definitions -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+#ifdef DEBUG_RELEASE_BUILD -+#pragma optimize( "", off ) -+#define DEBUG 1 -+#endif -+ -+#ifndef __OSFUNC_H__ -+#define __OSFUNC_H__ -+ -+#if defined (__cplusplus) -+extern "C" { -+#endif -+ -+#if defined(__linux__) && defined(__KERNEL__) -+#include <linux/hardirq.h> -+#include <linux/string.h> -+#if defined(__arm__) -+#include <asm/memory.h> -+#endif -+#endif -+ -+ -+/* setup conditional pageable / non-pageable select */ -+ /* Other OSs only need pageable */ -+ #define PVRSRV_PAGEABLE_SELECT PVRSRV_OS_PAGEABLE_HEAP -+ -+/****************************************************************************** -+ * Static defines -+ *****************************************************************************/ -+#define KERNEL_ID 0xffffffffL -+#define POWER_MANAGER_ID 0xfffffffeL -+#define ISR_ID 0xfffffffdL -+#define TIMER_ID 0xfffffffcL -+ -+ -+#define HOST_PAGESIZE OSGetPageSize -+#define HOST_PAGEMASK (HOST_PAGESIZE()-1) -+#define HOST_PAGEALIGN(addr) (((addr) + HOST_PAGEMASK) & ~HOST_PAGEMASK) -+ -+/****************************************************************************** -+ * Host memory heaps -+ *****************************************************************************/ -+#define PVRSRV_OS_HEAP_MASK 0xf /* host heap flags mask */ -+#define PVRSRV_OS_PAGEABLE_HEAP 0x1 /* allocation pageable */ -+#define PVRSRV_OS_NON_PAGEABLE_HEAP 0x2 /* allocation non pageable */ -+ -+ -+IMG_UINT32 OSClockus(IMG_VOID); -+IMG_UINT32 OSGetPageSize(IMG_VOID); -+PVRSRV_ERROR OSInstallDeviceLISR(IMG_VOID *pvSysData, -+ IMG_UINT32 ui32Irq, -+ IMG_CHAR *pszISRName, -+ IMG_VOID *pvDeviceNode); -+PVRSRV_ERROR OSUninstallDeviceLISR(IMG_VOID *pvSysData); -+PVRSRV_ERROR OSInstallSystemLISR(IMG_VOID *pvSysData, IMG_UINT32 ui32Irq); -+PVRSRV_ERROR OSUninstallSystemLISR(IMG_VOID *pvSysData); -+PVRSRV_ERROR OSInstallMISR(IMG_VOID *pvSysData); -+PVRSRV_ERROR OSUninstallMISR(IMG_VOID *pvSysData); -+IMG_CPU_PHYADDR OSMapLinToCPUPhys(IMG_HANDLE, IMG_VOID* pvLinAddr); -+IMG_VOID OSMemCopy(IMG_VOID *pvDst, IMG_VOID *pvSrc, IMG_SIZE_T uiSize); -+IMG_VOID *OSMapPhysToLin(IMG_CPU_PHYADDR BasePAddr, IMG_SIZE_T uBytes, IMG_UINT32 ui32Flags, IMG_HANDLE *phOSMemHandle); -+IMG_BOOL OSUnMapPhysToLin(IMG_VOID *pvLinAddr, IMG_SIZE_T uBytes, IMG_UINT32 ui32Flags, IMG_HANDLE hOSMemHandle); -+ -+PVRSRV_ERROR OSReservePhys(IMG_CPU_PHYADDR BasePAddr, IMG_SIZE_T uBytes, IMG_UINT32 ui32Flags, IMG_HANDLE hBMHandle, IMG_VOID **ppvCpuVAddr, IMG_HANDLE *phOSMemHandle); -+PVRSRV_ERROR OSUnReservePhys(IMG_VOID *pvCpuVAddr, IMG_SIZE_T uBytes, IMG_UINT32 ui32Flags, IMG_HANDLE hOSMemHandle); -+ -+/* Some terminology: -+ * -+ * FLUSH Flush w/ invalidate -+ * CLEAN Flush w/o invalidate -+ * INVALIDATE Invalidate w/o flush -+ */ -+ -+#if defined(__linux__) && defined(__KERNEL__) -+ -+IMG_VOID OSFlushCPUCacheKM(IMG_VOID); -+ -+IMG_VOID OSCleanCPUCacheKM(IMG_VOID); -+ -+IMG_BOOL OSFlushCPUCacheRangeKM(IMG_HANDLE hOSMemHandle, -+ IMG_UINT32 ui32ByteOffset, -+ IMG_VOID *pvRangeAddrStart, -+ IMG_UINT32 ui32Length); -+IMG_BOOL OSCleanCPUCacheRangeKM(IMG_HANDLE hOSMemHandle, -+ IMG_UINT32 ui32ByteOffset, -+ IMG_VOID *pvRangeAddrStart, -+ IMG_UINT32 ui32Length); -+IMG_BOOL OSInvalidateCPUCacheRangeKM(IMG_HANDLE hOSMemHandle, -+ IMG_UINT32 ui32ByteOffset, -+ IMG_VOID *pvRangeAddrStart, -+ IMG_UINT32 ui32Length); -+ -+#else /* defined(__linux__) && defined(__KERNEL__) */ -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(OSFlushCPUCacheKM) -+#endif -+static INLINE IMG_VOID OSFlushCPUCacheKM(IMG_VOID) {} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(OSCleanCPUCacheKM) -+#endif -+static INLINE IMG_VOID OSCleanCPUCacheKM(IMG_VOID) {} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(OSFlushCPUCacheRangeKM) -+#endif -+static INLINE IMG_BOOL OSFlushCPUCacheRangeKM(IMG_HANDLE hOSMemHandle, -+ IMG_UINT32 ui32ByteOffset, -+ IMG_VOID *pvRangeAddrStart, -+ IMG_UINT32 ui32Length) -+{ -+ PVR_UNREFERENCED_PARAMETER(hOSMemHandle); -+ PVR_UNREFERENCED_PARAMETER(ui32ByteOffset); -+ PVR_UNREFERENCED_PARAMETER(pvRangeAddrStart); -+ PVR_UNREFERENCED_PARAMETER(ui32Length); -+ return IMG_FALSE; -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(OSCleanCPUCacheRangeKM) -+#endif -+static INLINE IMG_BOOL OSCleanCPUCacheRangeKM(IMG_HANDLE hOSMemHandle, -+ IMG_UINT32 ui32ByteOffset, -+ IMG_VOID *pvRangeAddrStart, -+ IMG_UINT32 ui32Length) -+{ -+ PVR_UNREFERENCED_PARAMETER(hOSMemHandle); -+ PVR_UNREFERENCED_PARAMETER(ui32ByteOffset); -+ PVR_UNREFERENCED_PARAMETER(pvRangeAddrStart); -+ PVR_UNREFERENCED_PARAMETER(ui32Length); -+ return IMG_FALSE; -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(OSInvalidateCPUCacheRangeKM) -+#endif -+static INLINE IMG_BOOL OSInvalidateCPUCacheRangeKM(IMG_HANDLE hOSMemHandle, -+ IMG_UINT32 ui32ByteOffset, -+ IMG_VOID *pvRangeAddrStart, -+ IMG_UINT32 ui32Length) -+{ -+ PVR_UNREFERENCED_PARAMETER(hOSMemHandle); -+ PVR_UNREFERENCED_PARAMETER(ui32ByteOffset); -+ PVR_UNREFERENCED_PARAMETER(pvRangeAddrStart); -+ PVR_UNREFERENCED_PARAMETER(ui32Length); -+ return IMG_FALSE; -+} -+ -+#endif /* defined(__linux__) && defined(__KERNEL__) */ -+ -+#if defined(__linux__) || defined(__QNXNTO__) -+PVRSRV_ERROR OSRegisterDiscontigMem(IMG_SYS_PHYADDR *pBasePAddr, -+ IMG_VOID *pvCpuVAddr, -+ IMG_SIZE_T uBytes, -+ IMG_UINT32 ui32Flags, -+ IMG_HANDLE *phOSMemHandle); -+PVRSRV_ERROR OSUnRegisterDiscontigMem(IMG_VOID *pvCpuVAddr, -+ IMG_SIZE_T uBytes, -+ IMG_UINT32 ui32Flags, -+ IMG_HANDLE hOSMemHandle); -+#else /* defined(__linux__) */ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(OSRegisterDiscontigMem) -+#endif -+static INLINE PVRSRV_ERROR OSRegisterDiscontigMem(IMG_SYS_PHYADDR *pBasePAddr, -+ IMG_VOID *pvCpuVAddr, -+ IMG_SIZE_T uBytes, -+ IMG_UINT32 ui32Flags, -+ IMG_HANDLE *phOSMemHandle) -+{ -+ PVR_UNREFERENCED_PARAMETER(pBasePAddr); -+ PVR_UNREFERENCED_PARAMETER(pvCpuVAddr); -+ PVR_UNREFERENCED_PARAMETER(ui32Bytes); -+ PVR_UNREFERENCED_PARAMETER(ui32Flags); -+ PVR_UNREFERENCED_PARAMETER(phOSMemHandle); -+ -+ return PVRSRV_ERROR_NOT_SUPPORTED; -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(OSUnRegisterDiscontigMem) -+#endif -+static INLINE PVRSRV_ERROR OSUnRegisterDiscontigMem(IMG_VOID *pvCpuVAddr, -+ IMG_SIZE_T uBytes, -+ IMG_UINT32 ui32Flags, -+ IMG_HANDLE hOSMemHandle) -+{ -+ PVR_UNREFERENCED_PARAMETER(pvCpuVAddr); -+ PVR_UNREFERENCED_PARAMETER(ui32Bytes); -+ PVR_UNREFERENCED_PARAMETER(ui32Flags); -+ PVR_UNREFERENCED_PARAMETER(hOSMemHandle); -+ -+ return PVRSRV_ERROR_NOT_SUPPORTED; -+} -+#endif /* defined(__linux__) */ -+ -+ -+#if defined(__linux__) || defined(__QNXNTO__) -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(OSReserveDiscontigPhys) -+#endif -+static INLINE PVRSRV_ERROR OSReserveDiscontigPhys(IMG_SYS_PHYADDR *pBasePAddr, IMG_SIZE_T uBytes, IMG_UINT32 ui32Flags, IMG_VOID **ppvCpuVAddr, IMG_HANDLE *phOSMemHandle) -+{ -+#if defined(__linux__) || defined(__QNXNTO__) -+ *ppvCpuVAddr = IMG_NULL; -+ return OSRegisterDiscontigMem(pBasePAddr, *ppvCpuVAddr, uBytes, ui32Flags, phOSMemHandle); -+#else -+ extern IMG_CPU_PHYADDR SysSysPAddrToCpuPAddr(IMG_SYS_PHYADDR SysPAddr); -+ -+ /* -+ * On uITRON we know: -+ * 1. We will only be called with a non-contig physical if we -+ * already have a contiguous CPU linear -+ * 2. There is a one->one mapping of CpuPAddr -> CpuVAddr -+ * 3. Looking up the first CpuPAddr will find the first CpuVAddr -+ * 4. We don't need to unmap -+ */ -+ -+ return OSReservePhys(SysSysPAddrToCpuPAddr(pBasePAddr[0]), uBytes, ui32Flags, IMG_NULL, ppvCpuVAddr, phOSMemHandle); -+#endif -+} -+ -+static INLINE PVRSRV_ERROR OSUnReserveDiscontigPhys(IMG_VOID *pvCpuVAddr, IMG_SIZE_T uBytes, IMG_UINT32 ui32Flags, IMG_HANDLE hOSMemHandle) -+{ -+#if defined(__linux__) || defined(__QNXNTO__) -+ OSUnRegisterDiscontigMem(pvCpuVAddr, uBytes, ui32Flags, hOSMemHandle); -+#endif -+ /* We don't need to unmap */ -+ return PVRSRV_OK; -+} -+#else /* defined(__linux__) */ -+ -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(OSReserveDiscontigPhys) -+#endif -+static INLINE PVRSRV_ERROR OSReserveDiscontigPhys(IMG_SYS_PHYADDR *pBasePAddr, IMG_SIZE_T uBytes, IMG_UINT32 ui32Flags, IMG_VOID **ppvCpuVAddr, IMG_HANDLE *phOSMemHandle) -+{ -+ PVR_UNREFERENCED_PARAMETER(pBasePAddr); -+ PVR_UNREFERENCED_PARAMETER(uBytes); -+ PVR_UNREFERENCED_PARAMETER(ui32Flags); -+ PVR_UNREFERENCED_PARAMETER(ppvCpuVAddr); -+ PVR_UNREFERENCED_PARAMETER(phOSMemHandle); -+ -+ return PVRSRV_ERROR_NOT_SUPPORTED; -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(OSUnReserveDiscontigPhys) -+#endif -+static INLINE PVRSRV_ERROR OSUnReserveDiscontigPhys(IMG_VOID *pvCpuVAddr, IMG_SIZE_T uBytes, IMG_UINT32 ui32Flags, IMG_HANDLE hOSMemHandle) -+{ -+ PVR_UNREFERENCED_PARAMETER(pvCpuVAddr); -+ PVR_UNREFERENCED_PARAMETER(uBytes); -+ PVR_UNREFERENCED_PARAMETER(ui32Flags); -+ PVR_UNREFERENCED_PARAMETER(hOSMemHandle); -+ -+ return PVRSRV_ERROR_NOT_SUPPORTED; -+} -+#endif /* defined(__linux__) */ -+ -+PVRSRV_ERROR OSRegisterMem(IMG_CPU_PHYADDR BasePAddr, -+ IMG_VOID *pvCpuVAddr, -+ IMG_SIZE_T uBytes, -+ IMG_UINT32 ui32Flags, -+ IMG_HANDLE *phOSMemHandle); -+PVRSRV_ERROR OSUnRegisterMem(IMG_VOID *pvCpuVAddr, -+ IMG_SIZE_T uBytes, -+ IMG_UINT32 ui32Flags, -+ IMG_HANDLE hOSMemHandle); -+ -+ -+ -+#if defined(__linux__) || defined(__QNXNTO__) -+PVRSRV_ERROR OSGetSubMemHandle(IMG_HANDLE hOSMemHandle, -+ IMG_UINTPTR_T uByteOffset, -+ IMG_SIZE_T uBytes, -+ IMG_UINT32 ui32Flags, -+ IMG_HANDLE *phOSMemHandleRet); -+PVRSRV_ERROR OSReleaseSubMemHandle(IMG_HANDLE hOSMemHandle, IMG_UINT32 ui32Flags); -+#else -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(OSGetSubMemHandle) -+#endif -+static INLINE PVRSRV_ERROR OSGetSubMemHandle(IMG_HANDLE hOSMemHandle, -+ IMG_UINTPTR_T uByteOffset, -+ IMG_SIZE_T uBytes, -+ IMG_UINT32 ui32Flags, -+ IMG_HANDLE *phOSMemHandleRet) -+{ -+ PVR_UNREFERENCED_PARAMETER(uByteOffset); -+ PVR_UNREFERENCED_PARAMETER(uBytes); -+ PVR_UNREFERENCED_PARAMETER(ui32Flags); -+ -+ *phOSMemHandleRet = hOSMemHandle; -+ return PVRSRV_OK; -+} -+ -+static INLINE PVRSRV_ERROR OSReleaseSubMemHandle(IMG_HANDLE hOSMemHandle, IMG_UINT32 ui32Flags) -+{ -+ PVR_UNREFERENCED_PARAMETER(hOSMemHandle); -+ PVR_UNREFERENCED_PARAMETER(ui32Flags); -+ return PVRSRV_OK; -+} -+#endif -+ -+IMG_UINT32 OSGetCurrentProcessIDKM(IMG_VOID); -+IMG_UINTPTR_T OSGetCurrentThreadID( IMG_VOID ); -+IMG_VOID OSMemSet(IMG_VOID *pvDest, IMG_UINT8 ui8Value, IMG_SIZE_T uSize); -+ -+PVRSRV_ERROR OSAllocPages_Impl(IMG_UINT32 ui32Flags, IMG_SIZE_T uSize, IMG_UINT32 ui32PageSize, -+ IMG_PVOID pvPrivData, IMG_UINT32 ui32PrivDataLength, IMG_HANDLE hBMHandle, IMG_PVOID *ppvLinAddr, IMG_HANDLE *phPageAlloc); -+PVRSRV_ERROR OSFreePages(IMG_UINT32 ui32Flags, IMG_SIZE_T uSize, IMG_PVOID pvLinAddr, IMG_HANDLE hPageAlloc); -+ -+ -+/*--------------------- -+The set of macros below follows this pattern: -+ -+f(x) = if F -> f2(g(x)) -+ else -> g(x) -+ -+g(x) = if G -> g2(h(x)) -+ else -> h(x) -+ -+h(x) = ... -+ -+-----------------------*/ -+ -+/*If level 3 wrapper is enabled, we add a PVR_TRACE and call the next level, else just call the next level*/ -+#ifdef PVRSRV_LOG_MEMORY_ALLOCS -+ #define OSAllocMem(flags, size, linAddr, blockAlloc, logStr) \ -+ (PVR_TRACE(("OSAllocMem(" #flags ", " #size ", " #linAddr ", " #blockAlloc "): " logStr " (size = 0x%lx)", size)), \ -+ OSAllocMem_Debug_Wrapper(flags, size, linAddr, blockAlloc, __FILE__, __LINE__)) -+ -+ #define OSAllocPages(flags, size, pageSize, privdata, privdatalength, bmhandle, linAddr, pageAlloc) \ -+ (PVR_TRACE(("OSAllocPages(" #flags ", " #size ", " #pageSize ", " #linAddr ", " #pageAlloc "): (size = 0x%lx)", size)), \ -+ OSAllocPages_Impl(flags, size, pageSize, linAddr, privdata, privdatalength, bmhandle, pageAlloc)) -+ -+ #define OSFreeMem(flags, size, linAddr, blockAlloc) \ -+ (PVR_TRACE(("OSFreeMem(" #flags ", " #size ", " #linAddr ", " #blockAlloc "): (pointer = 0x%X)", linAddr)), \ -+ OSFreeMem_Debug_Wrapper(flags, size, linAddr, blockAlloc, __FILE__, __LINE__)) -+#else -+ #define OSAllocMem(flags, size, linAddr, blockAlloc, logString) \ -+ OSAllocMem_Debug_Wrapper(flags, size, linAddr, blockAlloc, __FILE__, __LINE__) -+ -+ #define OSAllocPages OSAllocPages_Impl -+ -+ #define OSFreeMem(flags, size, linAddr, blockAlloc) \ -+ OSFreeMem_Debug_Wrapper(flags, size, linAddr, blockAlloc, __FILE__, __LINE__) -+#endif -+ -+/*If level 2 wrapper is enabled declare the function, -+else alias to level 1 wrapper, else the wrapper function will be used*/ -+#ifdef PVRSRV_DEBUG_OS_MEMORY -+ -+ PVRSRV_ERROR OSAllocMem_Debug_Wrapper(IMG_UINT32 ui32Flags, -+ IMG_UINT32 ui32Size, -+ IMG_PVOID *ppvCpuVAddr, -+ IMG_HANDLE *phBlockAlloc, -+ IMG_CHAR *pszFilename, -+ IMG_UINT32 ui32Line); -+ -+ PVRSRV_ERROR OSFreeMem_Debug_Wrapper(IMG_UINT32 ui32Flags, -+ IMG_UINT32 ui32Size, -+ IMG_PVOID pvCpuVAddr, -+ IMG_HANDLE hBlockAlloc, -+ IMG_CHAR *pszFilename, -+ IMG_UINT32 ui32Line); -+ -+ -+ typedef struct -+ { -+ IMG_UINT8 sGuardRegionBefore[8]; -+ IMG_CHAR sFileName[128]; -+ IMG_UINT32 uLineNo; -+ IMG_SIZE_T uSize; -+ IMG_SIZE_T uSizeParityCheck; -+ enum valid_tag -+ { isFree = 0x277260FF, -+ isAllocated = 0x260511AA -+ } eValid; -+ } OSMEM_DEBUG_INFO; -+ -+ #define TEST_BUFFER_PADDING_STATUS (sizeof(OSMEM_DEBUG_INFO)) -+ #define TEST_BUFFER_PADDING_AFTER (8) -+ #define TEST_BUFFER_PADDING (TEST_BUFFER_PADDING_STATUS + TEST_BUFFER_PADDING_AFTER) -+#else -+ #define OSAllocMem_Debug_Wrapper OSAllocMem_Debug_Linux_Memory_Allocations -+ #define OSFreeMem_Debug_Wrapper OSFreeMem_Debug_Linux_Memory_Allocations -+#endif -+ -+/*If level 1 wrapper is enabled declare the functions with extra parameters -+else alias to level 0 and declare the functions without the extra debugging parameters*/ -+#if (defined(__linux__) || defined(__QNXNTO__)) && defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) -+ PVRSRV_ERROR OSAllocMem_Impl(IMG_UINT32 ui32Flags, IMG_SIZE_T uSize, IMG_PVOID *ppvLinAddr, IMG_HANDLE *phBlockAlloc, IMG_CHAR *pszFilename, IMG_UINT32 ui32Line); -+ PVRSRV_ERROR OSFreeMem_Impl(IMG_UINT32 ui32Flags, IMG_SIZE_T uSize, IMG_PVOID pvLinAddr, IMG_HANDLE hBlockAlloc, IMG_CHAR *pszFilename, IMG_UINT32 ui32Line); -+ -+ #define OSAllocMem_Debug_Linux_Memory_Allocations OSAllocMem_Impl -+ #define OSFreeMem_Debug_Linux_Memory_Allocations OSFreeMem_Impl -+#else -+ PVRSRV_ERROR OSAllocMem_Impl(IMG_UINT32 ui32Flags, IMG_SIZE_T uSize, IMG_PVOID *ppvLinAddr, IMG_HANDLE *phBlockAlloc); -+ PVRSRV_ERROR OSFreeMem_Impl(IMG_UINT32 ui32Flags, IMG_SIZE_T uSize, IMG_PVOID pvLinAddr, IMG_HANDLE hBlockAlloc); -+ -+ #define OSAllocMem_Debug_Linux_Memory_Allocations(flags, size, addr, blockAlloc, file, line) \ -+ OSAllocMem_Impl(flags, size, addr, blockAlloc) -+ #define OSFreeMem_Debug_Linux_Memory_Allocations(flags, size, addr, blockAlloc, file, line) \ -+ OSFreeMem_Impl(flags, size, addr, blockAlloc) -+#endif -+ -+ -+#if defined(__linux__) || defined(__QNXNTO__) -+IMG_CPU_PHYADDR OSMemHandleToCpuPAddr(IMG_VOID *hOSMemHandle, IMG_UINTPTR_T uiByteOffset); -+#else -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(OSMemHandleToCpuPAddr) -+#endif -+static INLINE IMG_CPU_PHYADDR OSMemHandleToCpuPAddr(IMG_HANDLE hOSMemHandle, IMG_UINTPTR_T uiByteOffset) -+{ -+ IMG_CPU_PHYADDR sCpuPAddr; -+ PVR_UNREFERENCED_PARAMETER(hOSMemHandle); -+ PVR_UNREFERENCED_PARAMETER(uiByteOffset); -+ sCpuPAddr.uiAddr = 0; -+ return sCpuPAddr; -+} -+#endif -+ -+#if defined(__linux__) -+IMG_BOOL OSMemHandleIsPhysContig(IMG_VOID *hOSMemHandle); -+#else -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(OSMemHandleIsPhysContig) -+#endif -+static INLINE IMG_BOOL OSMemHandleIsPhysContig(IMG_HANDLE hOSMemHandle) -+{ -+ PVR_UNREFERENCED_PARAMETER(hOSMemHandle); -+ return IMG_FALSE; -+} -+#endif -+ -+PVRSRV_ERROR OSInitEnvData(IMG_PVOID *ppvEnvSpecificData); -+PVRSRV_ERROR OSDeInitEnvData(IMG_PVOID pvEnvSpecificData); -+IMG_CHAR* OSStringCopy(IMG_CHAR *pszDest, const IMG_CHAR *pszSrc); -+IMG_INT32 OSSNPrintf(IMG_CHAR *pStr, IMG_SIZE_T uSize, const IMG_CHAR *pszFormat, ...) IMG_FORMAT_PRINTF(3, 4); -+#define OSStringLength(pszString) strlen(pszString) -+ -+PVRSRV_ERROR OSEventObjectCreateKM(const IMG_CHAR *pszName, -+ PVRSRV_EVENTOBJECT *psEventObject); -+PVRSRV_ERROR OSEventObjectDestroyKM(PVRSRV_EVENTOBJECT *psEventObject); -+PVRSRV_ERROR OSEventObjectSignalKM(IMG_HANDLE hOSEventKM); -+PVRSRV_ERROR OSEventObjectWaitKM(IMG_HANDLE hOSEventKM); -+PVRSRV_ERROR OSEventObjectOpenKM(PVRSRV_EVENTOBJECT *psEventObject, -+ IMG_HANDLE *phOSEvent); -+PVRSRV_ERROR OSEventObjectCloseKM(PVRSRV_EVENTOBJECT *psEventObject, -+ IMG_HANDLE hOSEventKM); -+ -+ -+PVRSRV_ERROR OSBaseAllocContigMemory(IMG_SIZE_T uSize, IMG_CPU_VIRTADDR *pLinAddr, IMG_CPU_PHYADDR *pPhysAddr); -+PVRSRV_ERROR OSBaseFreeContigMemory(IMG_SIZE_T uSize, IMG_CPU_VIRTADDR LinAddr, IMG_CPU_PHYADDR PhysAddr); -+ -+IMG_PVOID MapUserFromKernel(IMG_PVOID pvLinAddrKM,IMG_SIZE_T uSize,IMG_HANDLE *phMemBlock); -+IMG_PVOID OSMapHWRegsIntoUserSpace(IMG_HANDLE hDevCookie, IMG_SYS_PHYADDR sRegAddr, IMG_UINT32 ulSize, IMG_PVOID *ppvProcess); -+IMG_VOID OSUnmapHWRegsFromUserSpace(IMG_HANDLE hDevCookie, IMG_PVOID pvUserAddr, IMG_PVOID pvProcess); -+ -+IMG_VOID UnmapUserFromKernel(IMG_PVOID pvLinAddrUM, IMG_SIZE_T uSize, IMG_HANDLE hMemBlock); -+ -+PVRSRV_ERROR OSMapPhysToUserSpace(IMG_HANDLE hDevCookie, -+ IMG_SYS_PHYADDR sCPUPhysAddr, -+ IMG_SIZE_T uiSizeInBytes, -+ IMG_UINT32 ui32CacheFlags, -+ IMG_PVOID *ppvUserAddr, -+ IMG_SIZE_T *puiActualSize, -+ IMG_HANDLE hMappingHandle); -+ -+PVRSRV_ERROR OSUnmapPhysToUserSpace(IMG_HANDLE hDevCookie, -+ IMG_PVOID pvUserAddr, -+ IMG_PVOID pvProcess); -+ -+PVRSRV_ERROR OSLockResource(PVRSRV_RESOURCE *psResource, IMG_UINT32 ui32ID); -+PVRSRV_ERROR OSUnlockResource(PVRSRV_RESOURCE *psResource, IMG_UINT32 ui32ID); -+IMG_BOOL OSIsResourceLocked(PVRSRV_RESOURCE *psResource, IMG_UINT32 ui32ID); -+PVRSRV_ERROR OSCreateResource(PVRSRV_RESOURCE *psResource); -+PVRSRV_ERROR OSDestroyResource(PVRSRV_RESOURCE *psResource); -+IMG_VOID OSBreakResourceLock(PVRSRV_RESOURCE *psResource, IMG_UINT32 ui32ID); -+ -+#if defined(SYS_CUSTOM_POWERLOCK_WRAP) -+#define OSPowerLockWrap SysPowerLockWrap -+#define OSPowerLockUnwrap SysPowerLockUnwrap -+#else -+/****************************************************************************** -+ @Function OSPowerLockWrap -+ -+ @Description OS-specific wrapper around the power lock -+ -+ @Input bTryLock - don't block on lock contention -+ -+ @Return PVRSRV_ERROR -+******************************************************************************/ -+PVRSRV_ERROR OSPowerLockWrap(IMG_BOOL bTryLock); -+ -+/****************************************************************************** -+ @Function OSPowerLockUnwrap -+ -+ @Description OS-specific wrapper around the power unlock -+ -+ @Return IMG_VOID -+******************************************************************************/ -+IMG_VOID OSPowerLockUnwrap(IMG_VOID); -+#endif /* SYS_CUSTOM_POWERLOCK_WRAP */ -+ -+/*! -+****************************************************************************** -+ -+ @Function OSWaitus -+ -+ @Description -+ This function implements a busy wait of the specified microseconds -+ This function does NOT release thread quanta -+ -+ @Input ui32Timeus - (us) -+ -+ @Return IMG_VOID -+ -+******************************************************************************/ -+IMG_VOID OSWaitus(IMG_UINT32 ui32Timeus); -+ -+/*! -+****************************************************************************** -+ -+ @Function OSSleepms -+ -+ @Description -+ This function implements a sleep of the specified milliseconds -+ This function may allow pre-emption if implemented -+ -+ @Input ui32Timems - (ms) -+ -+ @Return IMG_VOID -+ -+******************************************************************************/ -+IMG_VOID OSSleepms(IMG_UINT32 ui32Timems); -+ -+IMG_HANDLE OSFuncHighResTimerCreate(IMG_VOID); -+IMG_UINT32 OSFuncHighResTimerGetus(IMG_HANDLE hTimer); -+IMG_VOID OSFuncHighResTimerDestroy(IMG_HANDLE hTimer); -+IMG_VOID OSReleaseThreadQuanta(IMG_VOID); -+IMG_UINT32 OSPCIReadDword(IMG_UINT32 ui32Bus, IMG_UINT32 ui32Dev, IMG_UINT32 ui32Func, IMG_UINT32 ui32Reg); -+IMG_VOID OSPCIWriteDword(IMG_UINT32 ui32Bus, IMG_UINT32 ui32Dev, IMG_UINT32 ui32Func, IMG_UINT32 ui32Reg, IMG_UINT32 ui32Value); -+ -+IMG_IMPORT -+IMG_UINT32 ReadHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset); -+ -+IMG_IMPORT -+IMG_VOID WriteHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value); -+ -+IMG_IMPORT IMG_VOID WriteHWRegs(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Count, PVRSRV_HWREG *psHWRegs); -+ -+#ifndef OSReadHWReg -+IMG_UINT32 OSReadHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset); -+#endif -+#ifndef OSWriteHWReg -+IMG_VOID OSWriteHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value); -+#endif -+ -+typedef IMG_VOID (*PFN_TIMER_FUNC)(IMG_VOID*); -+IMG_HANDLE OSAddTimer(PFN_TIMER_FUNC pfnTimerFunc, IMG_VOID *pvData, IMG_UINT32 ui32MsTimeout); -+PVRSRV_ERROR OSRemoveTimer (IMG_HANDLE hTimer); -+PVRSRV_ERROR OSEnableTimer (IMG_HANDLE hTimer); -+PVRSRV_ERROR OSDisableTimer (IMG_HANDLE hTimer); -+ -+PVRSRV_ERROR OSGetSysMemSize(IMG_SIZE_T *puBytes); -+ -+typedef enum _HOST_PCI_INIT_FLAGS_ -+{ -+ HOST_PCI_INIT_FLAG_BUS_MASTER = 0x00000001, -+ HOST_PCI_INIT_FLAG_MSI = 0x00000002, -+ HOST_PCI_INIT_FLAG_FORCE_I32 = 0x7fffffff -+} HOST_PCI_INIT_FLAGS; -+ -+struct _PVRSRV_PCI_DEV_OPAQUE_STRUCT_; -+typedef struct _PVRSRV_PCI_DEV_OPAQUE_STRUCT_ *PVRSRV_PCI_DEV_HANDLE; -+ -+PVRSRV_PCI_DEV_HANDLE OSPCIAcquireDev(IMG_UINT16 ui16VendorID, IMG_UINT16 ui16DeviceID, HOST_PCI_INIT_FLAGS eFlags); -+PVRSRV_PCI_DEV_HANDLE OSPCISetDev(IMG_VOID *pvPCICookie, HOST_PCI_INIT_FLAGS eFlags); -+PVRSRV_ERROR OSPCIReleaseDev(PVRSRV_PCI_DEV_HANDLE hPVRPCI); -+PVRSRV_ERROR OSPCIIRQ(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 *pui32IRQ); -+IMG_UINT32 OSPCIAddrRangeLen(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index); -+IMG_UINT32 OSPCIAddrRangeStart(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index); -+IMG_UINT32 OSPCIAddrRangeEnd(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index); -+PVRSRV_ERROR OSPCIRequestAddrRange(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index); -+PVRSRV_ERROR OSPCIReleaseAddrRange(PVRSRV_PCI_DEV_HANDLE hPVRPCI, IMG_UINT32 ui32Index); -+PVRSRV_ERROR OSPCISuspendDev(PVRSRV_PCI_DEV_HANDLE hPVRPCI); -+PVRSRV_ERROR OSPCIResumeDev(PVRSRV_PCI_DEV_HANDLE hPVRPCI); -+ -+PVRSRV_ERROR OSScheduleMISR(IMG_VOID *pvSysData); -+ -+/****************************************************************************** -+ -+ @Function OSPanic -+ -+ @Description Take action in response to an unrecoverable driver error -+ -+ @Input IMG_VOID -+ -+ @Return IMG_VOID -+ -+******************************************************************************/ -+IMG_VOID OSPanic(IMG_VOID); -+ -+IMG_BOOL OSProcHasPrivSrvInit(IMG_VOID); -+ -+typedef enum _img_verify_test -+{ -+ PVR_VERIFY_WRITE = 0, -+ PVR_VERIFY_READ -+} IMG_VERIFY_TEST; -+ -+IMG_BOOL OSAccessOK(IMG_VERIFY_TEST eVerification, IMG_VOID *pvUserPtr, IMG_SIZE_T uBytes); -+ -+PVRSRV_ERROR OSCopyToUser(IMG_PVOID pvProcess, IMG_VOID *pvDest, IMG_VOID *pvSrc, IMG_SIZE_T uBytes); -+PVRSRV_ERROR OSCopyFromUser(IMG_PVOID pvProcess, IMG_VOID *pvDest, IMG_VOID *pvSrc, IMG_SIZE_T uBytes); -+ -+#if defined(__linux__) || defined(__QNXNTO__) -+PVRSRV_ERROR OSAcquirePhysPageAddr(IMG_VOID* pvCPUVAddr, -+ IMG_SIZE_T uBytes, -+ IMG_SYS_PHYADDR *psSysPAddr, -+ IMG_HANDLE *phOSWrapMem); -+PVRSRV_ERROR OSReleasePhysPageAddr(IMG_HANDLE hOSWrapMem); -+#else -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(OSAcquirePhysPageAddr) -+#endif -+static INLINE PVRSRV_ERROR OSAcquirePhysPageAddr(IMG_VOID* pvCPUVAddr, -+ IMG_SIZE_T uBytes, -+ IMG_SYS_PHYADDR *psSysPAddr, -+ IMG_HANDLE *phOSWrapMem) -+{ -+ PVR_UNREFERENCED_PARAMETER(pvCPUVAddr); -+ PVR_UNREFERENCED_PARAMETER(uBytes); -+ PVR_UNREFERENCED_PARAMETER(psSysPAddr); -+ PVR_UNREFERENCED_PARAMETER(phOSWrapMem); -+ return PVRSRV_OK; -+} -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(OSReleasePhysPageAddr) -+#endif -+static INLINE PVRSRV_ERROR OSReleasePhysPageAddr(IMG_HANDLE hOSWrapMem) -+{ -+ PVR_UNREFERENCED_PARAMETER(hOSWrapMem); -+ return PVRSRV_OK; -+} -+#endif -+ -+#if defined(__linux__) && defined(__KERNEL__) -+ -+#define OS_SUPPORTS_IN_LISR -+ -+static inline IMG_BOOL OSInLISR(IMG_VOID unref__ *pvSysData) -+{ -+ PVR_UNREFERENCED_PARAMETER(pvSysData); -+ return (in_irq()) ? IMG_TRUE : IMG_FALSE; -+} -+ -+static inline IMG_VOID OSWriteMemoryBarrier(IMG_VOID) -+{ -+ wmb(); -+} -+ -+static inline IMG_VOID OSMemoryBarrier(IMG_VOID) -+{ -+ mb(); -+} -+ -+#else /* defined(__linux__) && defined(__KERNEL__) */ -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(OSWriteMemoryBarrier) -+#endif -+static INLINE IMG_VOID OSWriteMemoryBarrier(IMG_VOID) { } -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(OSMemoryBarrier) -+#endif -+static INLINE IMG_VOID OSMemoryBarrier(IMG_VOID) { } -+ -+#endif /* defined(__linux__) && defined(__KERNEL__) */ -+ -+/* Atomic functions */ -+PVRSRV_ERROR OSAtomicAlloc(IMG_PVOID *ppvRefCount); -+IMG_VOID OSAtomicFree(IMG_PVOID pvRefCount); -+IMG_VOID OSAtomicInc(IMG_PVOID pvRefCount); -+IMG_BOOL OSAtomicDecAndTest(IMG_PVOID pvRefCount); -+IMG_UINT32 OSAtomicRead(IMG_PVOID pvRefCount); -+ -+PVRSRV_ERROR OSTimeCreateWithUSOffset(IMG_PVOID *pvRet, IMG_UINT32 ui32MSOffset); -+IMG_BOOL OSTimeHasTimePassed(IMG_PVOID pvData); -+IMG_VOID OSTimeDestroy(IMG_PVOID pvData); -+ -+#if defined(__linux__) -+IMG_VOID OSReleaseBridgeLock(IMG_VOID); -+IMG_VOID OSReacquireBridgeLock(IMG_VOID); -+#else -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(OSReleaseBridgeLock) -+#endif -+static INLINE IMG_VOID OSReleaseBridgeLock(IMG_VOID) { } -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(OSReacquireBridgeLock) -+#endif -+static INLINE IMG_VOID OSReacquireBridgeLock(IMG_VOID) { } -+ -+#endif -+ -+#if defined(__linux__) -+IMG_VOID OSGetCurrentProcessNameKM(IMG_CHAR *pszName, IMG_UINT32 ui32Size); -+#else -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(OSGetCurrentProcessNameKM) -+#endif -+static INLINE IMG_VOID OSGetCurrentProcessNameKM(IMG_CHAR *pszName, IMG_UINT32 ui32Size) -+{ -+ PVR_UNREFERENCED_PARAMETER(pszName); -+ PVR_UNREFERENCED_PARAMETER(ui32Size); -+} -+ -+#endif -+ -+#if defined(__linux__) && defined(DEBUG) -+#define OSDumpStack dump_stack -+#else -+#define OSDumpStack() -+#endif -+ -+#if defined (__cplusplus) -+} -+#endif -+ -+#endif /* __OSFUNC_H__ */ -+ -+/****************************************************************************** -+ End of file (osfunc.h) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/include/osperproc.h b/drivers/staging/ti-es8-sgx/services4/srvkm/include/osperproc.h -new file mode 100644 -index 0000000..0b962b4 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/include/osperproc.h -@@ -0,0 +1,94 @@ -+/*************************************************************************/ /*! -+@Title OS specific per process data interface -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description OS specific per process data interface -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+#ifndef __OSPERPROC_H__ -+#define __OSPERPROC_H__ -+ -+#if defined (__cplusplus) -+extern "C" { -+#endif -+ -+#if defined(__linux__) || defined(__QNXNTO__) -+PVRSRV_ERROR OSPerProcessPrivateDataInit(IMG_HANDLE *phOsPrivateData); -+PVRSRV_ERROR OSPerProcessPrivateDataDeInit(IMG_HANDLE hOsPrivateData); -+ -+PVRSRV_ERROR OSPerProcessSetHandleOptions(PVRSRV_HANDLE_BASE *psHandleBase); -+#else /* defined(__linux__) */ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(OSPerProcessPrivateDataInit) -+#endif -+static INLINE PVRSRV_ERROR OSPerProcessPrivateDataInit(IMG_HANDLE *phOsPrivateData) -+{ -+ PVR_UNREFERENCED_PARAMETER(phOsPrivateData); -+ -+ return PVRSRV_OK; -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(OSPerProcessPrivateDataDeInit) -+#endif -+static INLINE PVRSRV_ERROR OSPerProcessPrivateDataDeInit(IMG_HANDLE hOsPrivateData) -+{ -+ PVR_UNREFERENCED_PARAMETER(hOsPrivateData); -+ -+ return PVRSRV_OK; -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(OSPerProcessSetHandleOptions) -+#endif -+static INLINE PVRSRV_ERROR OSPerProcessSetHandleOptions(PVRSRV_HANDLE_BASE *psHandleBase) -+{ -+ PVR_UNREFERENCED_PARAMETER(psHandleBase); -+ -+ return PVRSRV_OK; -+} -+#endif /* defined(__linux__) */ -+ -+#if defined (__cplusplus) -+} -+#endif -+ -+#endif /* __OSPERPROC_H__ */ -+ -+/****************************************************************************** -+ End of file (osperproc.h) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/include/pdump_int.h b/drivers/staging/ti-es8-sgx/services4/srvkm/include/pdump_int.h -new file mode 100644 -index 0000000..fda9ee6 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/include/pdump_int.h -@@ -0,0 +1,99 @@ -+/*************************************************************************/ /*! -+@Title Parameter dump internal common functions -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+ -+#ifndef __PDUMP_INT_H__ -+#define __PDUMP_INT_H__ -+ -+#if defined (__cplusplus) -+extern "C" { -+#endif -+ -+/* -+ * This file contains internal pdump utility functions which may be accessed -+ * from OS-specific code. The header should not be included outside of srvkm -+ * pdump files. -+ */ -+ -+#if !defined(_UITRON) -+/* -+ * No dbgdriver on uitron, so ignore any common functions for communicating -+ * with dbgdriver. -+ */ -+#include "dbgdrvif.h" -+ -+/* Callbacks which are registered with the debug driver. */ -+IMG_EXPORT IMG_VOID PDumpConnectionNotify(IMG_VOID); -+ -+#endif /* !defined(_UITRON) */ -+ -+typedef enum -+{ -+ /* Continuous writes are always captured in the dbgdrv; the buffer will -+ * expand if no client/sink process is running. -+ */ -+ PDUMP_WRITE_MODE_CONTINUOUS = 0, -+ /* Last frame capture */ -+ PDUMP_WRITE_MODE_LASTFRAME, -+ /* Capture frame, binary data */ -+ PDUMP_WRITE_MODE_BINCM, -+ /* Persistent capture, append data to init phase */ -+ PDUMP_WRITE_MODE_PERSISTENT -+} PDUMP_DDWMODE; -+ -+ -+IMG_UINT32 DbgWrite(PDBG_STREAM psStream, IMG_UINT8 *pui8Data, IMG_UINT32 ui32BCount, IMG_UINT32 ui32Flags); -+ -+IMG_UINT32 PDumpOSDebugDriverWrite( PDBG_STREAM psStream, -+ PDUMP_DDWMODE eDbgDrvWriteMode, -+ IMG_UINT8 *pui8Data, -+ IMG_UINT32 ui32BCount, -+ IMG_UINT32 ui32Level, -+ IMG_UINT32 ui32DbgDrvFlags); -+ -+#if defined (__cplusplus) -+} -+#endif -+#endif /* __PDUMP_INT_H__ */ -+ -+/****************************************************************************** -+ End of file (pdump_int.h) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/include/pdump_km.h b/drivers/staging/ti-es8-sgx/services4/srvkm/include/pdump_km.h -new file mode 100644 -index 0000000..ec2a76c ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/include/pdump_km.h -@@ -0,0 +1,444 @@ -+/*************************************************************************/ /*! -+@Title pdump functions -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Main APIs for pdump functions -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+#ifndef _PDUMP_KM_H_ -+#define _PDUMP_KM_H_ -+ -+ -+/* -+ * Include the OS abstraction APIs -+ */ -+#include "pdump_osfunc.h" -+ -+#if defined(__cplusplus) -+extern "C" { -+#endif -+ -+/* -+ * Pull in pdump flags from services include -+ */ -+#include "pdump.h" -+ -+#define PDUMP_PD_UNIQUETAG (IMG_HANDLE)0 -+#define PDUMP_PT_UNIQUETAG (IMG_HANDLE)0 -+ -+/* -+ * PDump streams (common to all OSes) -+ */ -+#define PDUMP_STREAM_PARAM2 0 -+#define PDUMP_STREAM_SCRIPT2 1 -+#define PDUMP_STREAM_DRIVERINFO 2 -+#define PDUMP_NUM_STREAMS 3 -+ -+#if defined(PDUMP_DEBUG_OUTFILES) -+/* counter increments each time debug write is called */ -+extern IMG_UINT32 g_ui32EveryLineCounter; -+#endif -+ -+#ifndef PDUMP -+#define MAKEUNIQUETAG(hMemInfo) (0) -+#endif -+ -+IMG_BOOL _PDumpIsProcessActive(IMG_VOID); -+ -+#ifdef PDUMP -+ -+#define MAKEUNIQUETAG(hMemInfo) (((BM_BUF *)(((PVRSRV_KERNEL_MEM_INFO *)(hMemInfo))->sMemBlk.hBuffer))->pMapping) -+ -+ IMG_IMPORT PVRSRV_ERROR PDumpMemPolKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo, -+ IMG_UINT32 ui32Offset, -+ IMG_UINT32 ui32Value, -+ IMG_UINT32 ui32Mask, -+ PDUMP_POLL_OPERATOR eOperator, -+ IMG_UINT32 ui32Flags, -+ IMG_HANDLE hUniqueTag); -+ -+ IMG_IMPORT PVRSRV_ERROR PDumpMemUM(PVRSRV_PER_PROCESS_DATA *psProcData, -+ IMG_PVOID pvAltLinAddr, -+ IMG_PVOID pvLinAddr, -+ PVRSRV_KERNEL_MEM_INFO *psMemInfo, -+ IMG_UINT32 ui32Offset, -+ IMG_UINT32 ui32Bytes, -+ IMG_UINT32 ui32Flags, -+ IMG_HANDLE hUniqueTag); -+ -+ IMG_IMPORT PVRSRV_ERROR PDumpMemKM(IMG_PVOID pvAltLinAddr, -+ PVRSRV_KERNEL_MEM_INFO *psMemInfo, -+ IMG_UINT32 ui32Offset, -+ IMG_UINT32 ui32Bytes, -+ IMG_UINT32 ui32Flags, -+ IMG_HANDLE hUniqueTag); -+ PVRSRV_ERROR PDumpMemPagesKM(PVRSRV_DEVICE_IDENTIFIER *psDevID, -+ IMG_DEV_PHYADDR *pPages, -+ IMG_UINT32 ui32NumPages, -+ IMG_DEV_VIRTADDR sDevAddr, -+ IMG_UINT32 ui32Start, -+ IMG_UINT32 ui32Length, -+ IMG_UINT32 ui32Flags, -+ IMG_HANDLE hUniqueTag); -+ -+ PVRSRV_ERROR PDumpMemPDEntriesKM(PDUMP_MMU_ATTRIB *psMMUAttrib, -+ IMG_HANDLE hOSMemHandle, -+ IMG_CPU_VIRTADDR pvLinAddr, -+ IMG_UINT32 ui32Bytes, -+ IMG_UINT32 ui32Flags, -+ IMG_BOOL bInitialisePages, -+ IMG_HANDLE hUniqueTag1, -+ IMG_HANDLE hUniqueTag2); -+ -+ PVRSRV_ERROR PDumpMemPTEntriesKM(PDUMP_MMU_ATTRIB *psMMUAttrib, -+ IMG_HANDLE hOSMemHandle, -+ IMG_CPU_VIRTADDR pvLinAddr, -+ IMG_UINT32 ui32Bytes, -+ IMG_UINT32 ui32Flags, -+ IMG_BOOL bInitialisePages, -+ IMG_HANDLE hUniqueTag1, -+ IMG_HANDLE hUniqueTag2); -+ IMG_VOID PDumpInitCommon(IMG_VOID); -+ IMG_VOID PDumpDeInitCommon(IMG_VOID); -+ IMG_VOID PDumpInit(IMG_VOID); -+ IMG_VOID PDumpDeInit(IMG_VOID); -+ IMG_BOOL PDumpIsSuspended(IMG_VOID); -+ PVRSRV_ERROR PDumpStartInitPhaseKM(IMG_VOID); -+ PVRSRV_ERROR PDumpStopInitPhaseKM(IMG_VOID); -+ IMG_IMPORT PVRSRV_ERROR PDumpSetFrameKM(IMG_UINT32 ui32Frame); -+ IMG_IMPORT PVRSRV_ERROR PDumpCommentKM(IMG_CHAR *pszComment, IMG_UINT32 ui32Flags); -+ IMG_IMPORT PVRSRV_ERROR PDumpDriverInfoKM(IMG_CHAR *pszString, IMG_UINT32 ui32Flags); -+ -+ PVRSRV_ERROR PDumpRegWithFlagsKM(IMG_CHAR *pszPDumpRegName, -+ IMG_UINT32 ui32RegAddr, -+ IMG_UINT32 ui32RegValue, -+ IMG_UINT32 ui32Flags); -+ PVRSRV_ERROR PDumpRegPolWithFlagsKM(IMG_CHAR *pszPDumpRegName, -+ IMG_UINT32 ui32RegAddr, -+ IMG_UINT32 ui32RegValue, -+ IMG_UINT32 ui32Mask, -+ IMG_UINT32 ui32Flags, -+ PDUMP_POLL_OPERATOR eOperator); -+ PVRSRV_ERROR PDumpRegPolKM(IMG_CHAR *pszPDumpRegName, -+ IMG_UINT32 ui32RegAddr, -+ IMG_UINT32 ui32RegValue, -+ IMG_UINT32 ui32Mask, -+ PDUMP_POLL_OPERATOR eOperator); -+ -+ IMG_IMPORT PVRSRV_ERROR PDumpBitmapKM(PVRSRV_DEVICE_NODE *psDeviceNode, -+ IMG_CHAR *pszFileName, -+ IMG_UINT32 ui32FileOffset, -+ IMG_UINT32 ui32Width, -+ IMG_UINT32 ui32Height, -+ IMG_UINT32 ui32StrideInBytes, -+ IMG_DEV_VIRTADDR sDevBaseAddr, -+ IMG_HANDLE hDevMemContext, -+ IMG_UINT32 ui32Size, -+ PDUMP_PIXEL_FORMAT ePixelFormat, -+ PDUMP_MEM_FORMAT eMemFormat, -+ IMG_UINT32 ui32PDumpFlags); -+ IMG_IMPORT PVRSRV_ERROR PDumpReadRegKM(IMG_CHAR *pszPDumpRegName, -+ IMG_CHAR *pszFileName, -+ IMG_UINT32 ui32FileOffset, -+ IMG_UINT32 ui32Address, -+ IMG_UINT32 ui32Size, -+ IMG_UINT32 ui32PDumpFlags); -+ -+ PVRSRV_ERROR PDumpRegKM(IMG_CHAR* pszPDumpRegName, -+ IMG_UINT32 dwReg, -+ IMG_UINT32 dwData); -+ -+ PVRSRV_ERROR PDumpComment(IMG_CHAR* pszFormat, ...) IMG_FORMAT_PRINTF(1, 2); -+ PVRSRV_ERROR PDumpCommentWithFlags(IMG_UINT32 ui32Flags, -+ IMG_CHAR* pszFormat, -+ ...) IMG_FORMAT_PRINTF(2, 3); -+ -+ PVRSRV_ERROR PDumpPDReg(PDUMP_MMU_ATTRIB *psMMUAttrib, -+ IMG_UINT32 ui32Reg, -+ IMG_UINT32 ui32dwData, -+ IMG_HANDLE hUniqueTag); -+ PVRSRV_ERROR PDumpPDRegWithFlags(PDUMP_MMU_ATTRIB *psMMUAttrib, -+ IMG_UINT32 ui32Reg, -+ IMG_UINT32 ui32Data, -+ IMG_UINT32 ui32Flags, -+ IMG_HANDLE hUniqueTag); -+ -+ IMG_BOOL PDumpIsLastCaptureFrameKM(IMG_VOID); -+ IMG_IMPORT IMG_BOOL PDumpIsCaptureFrameKM(IMG_VOID); -+ -+ IMG_VOID PDumpMallocPagesPhys(PVRSRV_DEVICE_IDENTIFIER *psDevID, -+ IMG_UINT32 ui32DevVAddr, -+ IMG_PUINT32 pui32PhysPages, -+ IMG_UINT32 ui32NumPages, -+ IMG_HANDLE hUniqueTag); -+ PVRSRV_ERROR PDumpSetMMUContext(PVRSRV_DEVICE_TYPE eDeviceType, -+ IMG_CHAR *pszMemSpace, -+ IMG_UINT32 *pui32MMUContextID, -+ IMG_UINT32 ui32MMUType, -+ IMG_HANDLE hUniqueTag1, -+ IMG_HANDLE hOSMemHandle, -+ IMG_VOID *pvPDCPUAddr); -+ PVRSRV_ERROR PDumpClearMMUContext(PVRSRV_DEVICE_TYPE eDeviceType, -+ IMG_CHAR *pszMemSpace, -+ IMG_UINT32 ui32MMUContextID, -+ IMG_UINT32 ui32MMUType); -+ -+ PVRSRV_ERROR PDumpPDDevPAddrKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo, -+ IMG_UINT32 ui32Offset, -+ IMG_DEV_PHYADDR sPDDevPAddr, -+ IMG_HANDLE hUniqueTag1, -+ IMG_HANDLE hUniqueTag2); -+ -+ IMG_BOOL PDumpTestNextFrame(IMG_UINT32 ui32CurrentFrame); -+ -+ PVRSRV_ERROR PDumpSaveMemKM (PVRSRV_DEVICE_IDENTIFIER *psDevId, -+ IMG_CHAR *pszFileName, -+ IMG_UINT32 ui32FileOffset, -+ IMG_DEV_VIRTADDR sDevBaseAddr, -+ IMG_UINT32 ui32Size, -+ IMG_UINT32 ui32DataMaster, -+ IMG_UINT32 ui32PDumpFlags); -+ -+ PVRSRV_ERROR PDumpTASignatureRegisters(PVRSRV_DEVICE_IDENTIFIER *psDevId, -+ IMG_UINT32 ui32DumpFrameNum, -+ IMG_UINT32 ui32TAKickCount, -+ IMG_BOOL bLastFrame, -+ IMG_UINT32 *pui32Registers, -+ IMG_UINT32 ui32NumRegisters); -+ -+ PVRSRV_ERROR PDump3DSignatureRegisters(PVRSRV_DEVICE_IDENTIFIER *psDevId, -+ IMG_UINT32 ui32DumpFrameNum, -+ IMG_BOOL bLastFrame, -+ IMG_UINT32 *pui32Registers, -+ IMG_UINT32 ui32NumRegisters); -+ -+ PVRSRV_ERROR PDumpCounterRegisters(PVRSRV_DEVICE_IDENTIFIER *psDevId, -+ IMG_UINT32 ui32DumpFrameNum, -+ IMG_BOOL bLastFrame, -+ IMG_UINT32 *pui32Registers, -+ IMG_UINT32 ui32NumRegisters); -+ -+ PVRSRV_ERROR PDumpRegRead(IMG_CHAR *pszPDumpRegName, -+ const IMG_UINT32 dwRegOffset, -+ IMG_UINT32 ui32Flags); -+ -+ PVRSRV_ERROR PDumpCycleCountRegRead(PVRSRV_DEVICE_IDENTIFIER *psDevId, -+ const IMG_UINT32 dwRegOffset, -+ IMG_BOOL bLastFrame); -+ -+ PVRSRV_ERROR PDumpIDLWithFlags(IMG_UINT32 ui32Clocks, IMG_UINT32 ui32Flags); -+ PVRSRV_ERROR PDumpIDL(IMG_UINT32 ui32Clocks); -+ -+ PVRSRV_ERROR PDumpMallocPages(PVRSRV_DEVICE_IDENTIFIER *psDevID, -+ IMG_UINT32 ui32DevVAddr, -+ IMG_CPU_VIRTADDR pvLinAddr, -+ IMG_HANDLE hOSMemHandle, -+ IMG_UINT32 ui32NumBytes, -+ IMG_UINT32 ui32PageSize, -+ IMG_HANDLE hUniqueTag, -+ IMG_UINT32 ui32Flags); -+ PVRSRV_ERROR PDumpMallocPageTable(PVRSRV_DEVICE_IDENTIFIER *psDevId, -+ IMG_HANDLE hOSMemHandle, -+ IMG_UINT32 ui32Offset, -+ IMG_CPU_VIRTADDR pvLinAddr, -+ IMG_UINT32 ui32NumBytes, -+ IMG_UINT32 ui32Flags, -+ IMG_HANDLE hUniqueTag); -+ PVRSRV_ERROR PDumpFreePages(struct _BM_HEAP_ *psBMHeap, -+ IMG_DEV_VIRTADDR sDevVAddr, -+ IMG_UINT32 ui32NumBytes, -+ IMG_UINT32 ui32PageSize, -+ IMG_HANDLE hUniqueTag, -+ IMG_BOOL bInterleaved, -+ IMG_BOOL bSparse, -+ IMG_UINT32 ui32Flags); -+ PVRSRV_ERROR PDumpFreePageTable(PVRSRV_DEVICE_IDENTIFIER *psDevID, -+ IMG_HANDLE hOSMemHandle, -+ IMG_CPU_VIRTADDR pvLinAddr, -+ IMG_UINT32 ui32NumBytes, -+ IMG_UINT32 ui32Flags, -+ IMG_HANDLE hUniqueTag); -+ -+ IMG_IMPORT PVRSRV_ERROR PDumpHWPerfCBKM(PVRSRV_DEVICE_IDENTIFIER *psDevId, -+ IMG_CHAR *pszFileName, -+ IMG_UINT32 ui32FileOffset, -+ IMG_DEV_VIRTADDR sDevBaseAddr, -+ IMG_UINT32 ui32Size, -+ IMG_UINT32 ui32MMUContextID, -+ IMG_UINT32 ui32PDumpFlags); -+ -+ PVRSRV_ERROR PDumpSignatureBuffer(PVRSRV_DEVICE_IDENTIFIER *psDevId, -+ IMG_CHAR *pszFileName, -+ IMG_CHAR *pszBufferType, -+ IMG_UINT32 ui32FileOffset, -+ IMG_DEV_VIRTADDR sDevBaseAddr, -+ IMG_UINT32 ui32Size, -+ IMG_UINT32 ui32MMUContextID, -+ IMG_UINT32 ui32PDumpFlags); -+ -+ PVRSRV_ERROR PDumpCBP(PPVRSRV_KERNEL_MEM_INFO psROffMemInfo, -+ IMG_UINT32 ui32ROffOffset, -+ IMG_UINT32 ui32WPosVal, -+ IMG_UINT32 ui32PacketSize, -+ IMG_UINT32 ui32BufferSize, -+ IMG_UINT32 ui32Flags, -+ IMG_HANDLE hUniqueTag); -+ -+ PVRSRV_ERROR PDumpRegBasedCBP(IMG_CHAR *pszPDumpRegName, -+ IMG_UINT32 ui32RegOffset, -+ IMG_UINT32 ui32WPosVal, -+ IMG_UINT32 ui32PacketSize, -+ IMG_UINT32 ui32BufferSize, -+ IMG_UINT32 ui32Flags); -+ -+ IMG_VOID PDumpVGXMemToFile(IMG_CHAR *pszFileName, -+ IMG_UINT32 ui32FileOffset, -+ PVRSRV_KERNEL_MEM_INFO *psMemInfo, -+ IMG_UINT32 uiAddr, -+ IMG_UINT32 ui32Size, -+ IMG_UINT32 ui32PDumpFlags, -+ IMG_HANDLE hUniqueTag); -+ -+ IMG_VOID PDumpSuspendKM(IMG_VOID); -+ IMG_VOID PDumpResumeKM(IMG_VOID); -+ -+ /* New pdump common functions */ -+ PVRSRV_ERROR PDumpStoreMemToFile(PDUMP_MMU_ATTRIB *psMMUAttrib, -+ IMG_CHAR *pszFileName, -+ IMG_UINT32 ui32FileOffset, -+ PVRSRV_KERNEL_MEM_INFO *psMemInfo, -+ IMG_UINT32 uiAddr, -+ IMG_UINT32 ui32Size, -+ IMG_UINT32 ui32PDumpFlags, -+ IMG_HANDLE hUniqueTag); -+ -+ #define PDUMPMEMPOL PDumpMemPolKM -+ #define PDUMPMEM PDumpMemKM -+ #define PDUMPMEMPTENTRIES PDumpMemPTEntriesKM -+ #define PDUMPPDENTRIES PDumpMemPDEntriesKM -+ #define PDUMPMEMUM PDumpMemUM -+ #define PDUMPINIT PDumpInitCommon -+ #define PDUMPDEINIT PDumpDeInitCommon -+ #define PDUMPISLASTFRAME PDumpIsLastCaptureFrameKM -+ #define PDUMPTESTFRAME PDumpIsCaptureFrameKM -+ #define PDUMPTESTNEXTFRAME PDumpTestNextFrame -+ #define PDUMPREGWITHFLAGS PDumpRegWithFlagsKM -+ #define PDUMPREG PDumpRegKM -+ #define PDUMPCOMMENT PDumpComment -+ #define PDUMPCOMMENTWITHFLAGS PDumpCommentWithFlags -+ #define PDUMPREGPOL PDumpRegPolKM -+ #define PDUMPREGPOLWITHFLAGS PDumpRegPolWithFlagsKM -+ #define PDUMPMALLOCPAGES PDumpMallocPages -+ #define PDUMPMALLOCPAGETABLE PDumpMallocPageTable -+ #define PDUMPSETMMUCONTEXT PDumpSetMMUContext -+ #define PDUMPCLEARMMUCONTEXT PDumpClearMMUContext -+ #define PDUMPPDDEVPADDR PDumpPDDevPAddrKM -+ #define PDUMPFREEPAGES PDumpFreePages -+ #define PDUMPFREEPAGETABLE PDumpFreePageTable -+ #define PDUMPPDREG PDumpPDReg -+ #define PDUMPPDREGWITHFLAGS PDumpPDRegWithFlags -+ #define PDUMPCBP PDumpCBP -+ #define PDUMPREGBASEDCBP PDumpRegBasedCBP -+ #define PDUMPMALLOCPAGESPHYS PDumpMallocPagesPhys -+ #define PDUMPENDINITPHASE PDumpStopInitPhaseKM -+ #define PDUMPBITMAPKM PDumpBitmapKM -+ #define PDUMPDRIVERINFO PDumpDriverInfoKM -+ #define PDUMPIDLWITHFLAGS PDumpIDLWithFlags -+ #define PDUMPIDL PDumpIDL -+ #define PDUMPSUSPEND PDumpSuspendKM -+ #define PDUMPRESUME PDumpResumeKM -+ -+#else -+#if defined LINUX || defined (__QNXNTO__) || defined GCC_IA32 || defined GCC_ARM -+ #define PDUMPMEMPOL(args...) -+ #define PDUMPMEM(args...) -+ #define PDUMPMEMPTENTRIES(args...) -+ #define PDUMPPDENTRIES(args...) -+ #define PDUMPMEMUM(args...) -+ #define PDUMPINIT(args...) -+ #define PDUMPDEINIT(args...) -+ #define PDUMPISLASTFRAME(args...) -+ #define PDUMPTESTFRAME(args...) -+ #define PDUMPTESTNEXTFRAME(args...) -+ #define PDUMPREGWITHFLAGS(args...) -+ #define PDUMPREG(args...) -+ #define PDUMPCOMMENT(args...) -+ #define PDUMPREGPOL(args...) -+ #define PDUMPREGPOLWITHFLAGS(args...) -+ #define PDUMPMALLOCPAGES(args...) -+ #define PDUMPMALLOCPAGETABLE(args...) -+ #define PDUMPSETMMUCONTEXT(args...) -+ #define PDUMPCLEARMMUCONTEXT(args...) -+ #define PDUMPPDDEVPADDR(args...) -+ #define PDUMPFREEPAGES(args...) -+ #define PDUMPFREEPAGETABLE(args...) -+ #define PDUMPPDREG(args...) -+ #define PDUMPPDREGWITHFLAGS(args...) -+ #define PDUMPSYNC(args...) -+ #define PDUMPCOPYTOMEM(args...) -+ #define PDUMPWRITE(args...) -+ #define PDUMPCBP(args...) -+ #define PDUMPREGBASEDCBP(args...) -+ #define PDUMPCOMMENTWITHFLAGS(args...) -+ #define PDUMPMALLOCPAGESPHYS(args...) -+ #define PDUMPENDINITPHASE(args...) -+ #define PDUMPMSVDXREG(args...) -+ #define PDUMPMSVDXREGWRITE(args...) -+ #define PDUMPMSVDXREGREAD(args...) -+ #define PDUMPMSVDXPOLEQ(args...) -+ #define PDUMPMSVDXPOL(args...) -+ #define PDUMPBITMAPKM(args...) -+ #define PDUMPDRIVERINFO(args...) -+ #define PDUMPIDLWITHFLAGS(args...) -+ #define PDUMPIDL(args...) -+ #define PDUMPSUSPEND(args...) -+ #define PDUMPRESUME(args...) -+ #define PDUMPMSVDXWRITEREF(args...) -+ #else -+ #error Compiler not specified -+ #endif -+#endif -+ -+#if defined (__cplusplus) -+} -+#endif -+ -+#endif /* _PDUMP_KM_H_ */ -+ -+/****************************************************************************** -+ End of file (pdump_km.h) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/include/pdump_osfunc.h b/drivers/staging/ti-es8-sgx/services4/srvkm/include/pdump_osfunc.h -new file mode 100644 -index 0000000..9d80fc8 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/include/pdump_osfunc.h -@@ -0,0 +1,385 @@ -+/*************************************************************************/ /*! -+@Title OS-independent interface to helper functions for pdump -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#include <stdarg.h> -+ -+#if defined(__cplusplus) -+extern "C" { -+#endif -+ -+ -+/* -+ * Some OSes (WinXP,CE) allocate the string on the stack, but some -+ * (Linux,Symbian) use a global variable/lock instead. -+ * Would be good to use the same across all OSes. -+ * -+ * A handle is returned which represents IMG_CHAR* type on all OSes except -+ * Symbian when it represents PDumpState* type. -+ * -+ * The allocated buffer length is also returned on OSes where it's -+ * supported (e.g. Linux). -+ */ -+#define MAX_PDUMP_STRING_LENGTH (256) -+ -+ -+#if defined(__QNXNTO__) -+ -+#define PDUMP_GET_SCRIPT_STRING() \ -+ IMG_CHAR pszScript[MAX_PDUMP_STRING_LENGTH]; \ -+ IMG_UINT32 ui32MaxLen = MAX_PDUMP_STRING_LENGTH-1; \ -+ IMG_HANDLE hScript = (IMG_HANDLE)pszScript; -+ -+#define PDUMP_GET_MSG_STRING() \ -+ IMG_CHAR pszMsg[MAX_PDUMP_STRING_LENGTH]; \ -+ IMG_UINT32 ui32MaxLen = MAX_PDUMP_STRING_LENGTH-1; -+ -+#define PDUMP_GET_FILE_STRING() \ -+ IMG_CHAR pszFileName[MAX_PDUMP_STRING_LENGTH]; \ -+ IMG_UINT32 ui32MaxLen = MAX_PDUMP_STRING_LENGTH-1; -+ -+#define PDUMP_GET_SCRIPT_AND_FILE_STRING() \ -+ IMG_CHAR pszScript[MAX_PDUMP_STRING_LENGTH]; \ -+ IMG_CHAR pszFileName[MAX_PDUMP_STRING_LENGTH]; \ -+ IMG_UINT32 ui32MaxLenScript = MAX_PDUMP_STRING_LENGTH-1; \ -+ IMG_UINT32 ui32MaxLenFileName = MAX_PDUMP_STRING_LENGTH-1; \ -+ IMG_HANDLE hScript = (IMG_HANDLE)pszScript; -+ -+#define PDUMP_LOCK(args...) -+#define PDUMP_UNLOCK(args...) -+#define PDUMP_LOCK_MSG(args...) -+#define PDUMP_UNLOCK_MSG(args...) -+ -+#else /* __QNXNTO__ */ -+ -+ -+ /* -+ * Linux -+ */ -+#define PDUMP_GET_SCRIPT_STRING() \ -+ IMG_HANDLE hScript; \ -+ IMG_UINT32 ui32MaxLen; \ -+ PVRSRV_ERROR eError; \ -+ eError = PDumpOSGetScriptString(&hScript, &ui32MaxLen);\ -+ if(eError != PVRSRV_OK) return eError; -+ -+#define PDUMP_GET_MSG_STRING() \ -+ IMG_CHAR *pszMsg; \ -+ IMG_UINT32 ui32MaxLen; \ -+ PVRSRV_ERROR eError; \ -+ eError = PDumpOSGetMessageString(&pszMsg, &ui32MaxLen);\ -+ if(eError != PVRSRV_OK) return eError; -+ -+#define PDUMP_GET_FILE_STRING() \ -+ IMG_CHAR *pszFileName; \ -+ IMG_UINT32 ui32MaxLen; \ -+ PVRSRV_ERROR eError; \ -+ eError = PDumpOSGetFilenameString(&pszFileName, &ui32MaxLen);\ -+ if(eError != PVRSRV_OK) return eError; -+ -+#define PDUMP_GET_SCRIPT_AND_FILE_STRING() \ -+ IMG_HANDLE hScript; \ -+ IMG_CHAR *pszFileName; \ -+ IMG_UINT32 ui32MaxLenScript; \ -+ IMG_UINT32 ui32MaxLenFileName; \ -+ PVRSRV_ERROR eError; \ -+ eError = PDumpOSGetScriptString(&hScript, &ui32MaxLenScript);\ -+ if(eError != PVRSRV_OK) return eError; \ -+ eError = PDumpOSGetFilenameString(&pszFileName, &ui32MaxLenFileName);\ -+ if(eError != PVRSRV_OK) return eError; -+ -+#define PDUMP_LOCK() \ -+ PDumpOSLock(__LINE__); -+ -+#define PDUMP_UNLOCK() \ -+ PDumpOSUnlock(__LINE__); -+ -+#define PDUMP_LOCK_MSG() \ -+ PDumpOSLockMessageBuffer(); -+ -+#define PDUMP_UNLOCK_MSG() \ -+ PDumpOSUnlockMessageBuffer(); -+ -+ /*! -+ * @name PDumpOSLock -+ * @brief Lock the PDump streams -+ * @return error none -+ */ -+ IMG_VOID PDumpOSLock(IMG_UINT32 ui32Line); -+ -+ /*! -+ * @name PDumpOSUnlock -+ * @brief Lock the PDump streams -+ * @return error none -+ */ -+ IMG_VOID PDumpOSUnlock(IMG_UINT32 ui32Line); -+ -+ /*! -+ * @name PDumpOSLockMessageBuffer -+ * @brief Lock the PDump message buffer -+ * @return error none -+ */ -+ IMG_VOID PDumpOSLockMessageBuffer(IMG_VOID); -+ -+ /*! -+ * @name PDumpOSUnlockMessageBuffer -+ * @brief Lock the PDump message buffer -+ * @return error none -+ */ -+ IMG_VOID PDumpOSUnlockMessageBuffer(IMG_VOID); -+ -+#endif /* __QNXNTO__ */ -+ -+ /*! -+ * @name PDumpOSGetScriptString -+ * @brief Get the "script" buffer -+ * @param phScript - buffer handle for pdump script -+ * @param pui32MaxLen - max length of the script buffer -+ * FIXME: the max length should be internal to the OS-specific code -+ * @return error (always PVRSRV_OK on some OSes) -+ */ -+ PVRSRV_ERROR PDumpOSGetScriptString(IMG_HANDLE *phScript, IMG_UINT32 *pui32MaxLen); -+ -+ /*! -+ * @name PDumpOSGetMessageString -+ * @brief Get the "message" buffer -+ * @param pszMsg - buffer pointer for pdump messages -+ * @param pui32MaxLen - max length of the message buffer -+ * FIXME: the max length should be internal to the OS-specific code -+ * @return error (always PVRSRV_OK on some OSes) -+ */ -+ PVRSRV_ERROR PDumpOSGetMessageString(IMG_CHAR **ppszMsg, IMG_UINT32 *pui32MaxLen); -+ -+ /*! -+ * @name PDumpOSGetFilenameString -+ * @brief Get the "filename" buffer -+ * @param ppszFile - buffer pointer for filename -+ * @param pui32MaxLen - max length of the filename buffer -+ * FIXME: the max length should be internal to the OS-specific code -+ * @return error (always PVRSRV_OK on some OSes) -+ */ -+ PVRSRV_ERROR PDumpOSGetFilenameString(IMG_CHAR **ppszFile, IMG_UINT32 *pui32MaxLen); -+ -+ -+/* -+ * Define macro for processing variable args list in OS-independent -+ * manner. See e.g. PDumpComment(). -+ */ -+ -+#define PDUMP_va_list va_list -+#define PDUMP_va_start va_start -+#define PDUMP_va_end va_end -+ -+ -+ -+/*! -+ * @name PDumpOSGetStream -+ * @brief Get a handle to the labelled stream (cast the handle to PDBG_STREAM to use it) -+ * @param ePDumpStream - stream label -+ */ -+IMG_HANDLE PDumpOSGetStream(IMG_UINT32 ePDumpStream); -+ -+/*! -+ * @name PDumpOSGetStreamOffset -+ * @brief Return current offset within the labelled stream -+ * @param ePDumpStream - stream label -+ */ -+IMG_UINT32 PDumpOSGetStreamOffset(IMG_UINT32 ePDumpStream); -+ -+/*! -+ * @name PDumpOSGetParamFileNum -+ * @brief Return file number of the 'script' stream, in the case that the file was split -+ * @param ePDumpStream - stream label -+ */ -+IMG_UINT32 PDumpOSGetParamFileNum(IMG_VOID); -+ -+/*! -+ * @name PDumpOSCheckForSplitting -+ * @brief Check if the requested pdump params are too large for a single file -+ * @param hStream - pdump stream -+ * @param ui32Size - size of params to dump (bytes) -+ * @param ui32Flags - pdump flags -+ */ -+IMG_VOID PDumpOSCheckForSplitting(IMG_HANDLE hStream, IMG_UINT32 ui32Size, IMG_UINT32 ui32Flags); -+ -+/*! -+ * @name PDumpOSIsSuspended -+ * @brief Is the pdump stream busy? -+ * @return IMG_BOOL -+ */ -+IMG_BOOL PDumpOSIsSuspended(IMG_VOID); -+ -+/*! -+ * @name PDumpOSIsSuspended -+ * @brief Is the pdump jump table initialised? -+ * @return IMG_BOOL -+ */ -+IMG_BOOL PDumpOSJTInitialised(IMG_VOID); -+ -+/*! -+ * @name PDumpOSWriteString -+ * @brief General function for writing to pdump stream. -+ * Usually more convenient to use PDumpOSWriteString2 below. -+ * @param hDbgStream - pdump stream handle -+ * @param psui8Data - data to write -+ * @param ui32Size - size of write -+ * @param ui32Flags - pdump flags -+ * @return error -+ */ -+IMG_BOOL PDumpOSWriteString(IMG_HANDLE hDbgStream, -+ IMG_UINT8 *psui8Data, -+ IMG_UINT32 ui32Size, -+ IMG_UINT32 ui32Flags); -+ -+/*! -+ * @name PDumpOSWriteString2 -+ * @brief Write a string to the "script" output stream -+ * @param pszScript - buffer to write (ptr to state structure on Symbian) -+ * @param ui32Flags - pdump flags -+ * @return error -+ */ -+IMG_BOOL PDumpOSWriteString2(IMG_HANDLE hScript, IMG_UINT32 ui32Flags); -+ -+/*! -+ * @name PDumpOSBufprintf -+ * @brief Printf to OS-specific pdump state buffer -+ * @param hBuf - buffer handle to write into (ptr to state structure on Symbian) -+ * @param ui32ScriptSizeMax - maximum size of data to write (not supported on all OSes) -+ * @param pszFormat - format string -+ */ -+PVRSRV_ERROR PDumpOSBufprintf(IMG_HANDLE hBuf, IMG_UINT32 ui32ScriptSizeMax, IMG_CHAR* pszFormat, ...) IMG_FORMAT_PRINTF(3, 4); -+ -+/*! -+ * @name PDumpOSDebugPrintf -+ * @brief Debug message during pdumping -+ * @param pszFormat - format string -+ */ -+IMG_VOID PDumpOSDebugPrintf(IMG_CHAR* pszFormat, ...) IMG_FORMAT_PRINTF(1, 2); -+ -+/* -+ * Write into a IMG_CHAR* on all OSes. Can be allocated on the stack or heap. -+ */ -+/*! -+ * @name PDumpOSSprintf -+ * @brief Printf to IMG char array -+ * @param pszComment - char array to print into -+ * @param pszFormat - format string -+ */ -+PVRSRV_ERROR PDumpOSSprintf(IMG_CHAR *pszComment, IMG_UINT32 ui32ScriptSizeMax, IMG_CHAR *pszFormat, ...) IMG_FORMAT_PRINTF(3, 4); -+ -+/*! -+ * @name PDumpOSVSprintf -+ * @brief Printf to IMG string using variable args (see stdarg.h). This is necessary -+ * because the ... notation does not support nested function calls. -+ * @param pszMsg - char array to print into -+ * @param ui32ScriptSizeMax - maximum size of data to write (not supported on all OSes) -+ * @param pszFormat - format string -+ * @param vaArgs - variable args structure (from stdarg.h) -+ */ -+PVRSRV_ERROR PDumpOSVSprintf(IMG_CHAR *pszMsg, IMG_UINT32 ui32ScriptSizeMax, IMG_CHAR* pszFormat, PDUMP_va_list vaArgs) IMG_FORMAT_PRINTF(3, 0); -+ -+/*! -+ * @name PDumpOSBuflen -+ * @param hBuffer - handle to buffer (ptr to state structure on Symbian) -+ * @param ui32BuffeRSizeMax - max size of buffer (chars) -+ * @return length of buffer, will always be <= ui32BufferSizeMax -+ */ -+IMG_UINT32 PDumpOSBuflen(IMG_HANDLE hBuffer, IMG_UINT32 ui32BufferSizeMax); -+ -+/*! -+ * @name PDumpOSVerifyLineEnding -+ * @brief Put \r\n sequence at the end if it isn't already there -+ * @param hBuffer - handle to buffer -+ * @param ui32BufferSizeMax - max size of buffer (chars) -+ */ -+IMG_VOID PDumpOSVerifyLineEnding(IMG_HANDLE hBuffer, IMG_UINT32 ui32BufferSizeMax); -+ -+/*! -+ * @name PDumpOSCPUVAddrToDevPAddr -+ * @brief OS function to convert CPU virtual to device physical for dumping pages -+ * @param hOSMemHandle mem allocation handle (used if kernel virtual mem space is limited, e.g. linux) -+ * @param ui32Offset dword offset into allocation (for use with mem handle, e.g. linux) -+ * @param pui8LinAddr CPU linear addr (usually a kernel virtual address) -+ * @param ui32PageSize page size, used for assertion check -+ * @return psDevPAddr device physical addr -+ */ -+IMG_VOID PDumpOSCPUVAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType, -+ IMG_HANDLE hOSMemHandle, -+ IMG_UINT32 ui32Offset, -+ IMG_UINT8 *pui8LinAddr, -+ IMG_UINT32 ui32PageSize, -+ IMG_DEV_PHYADDR *psDevPAddr); -+ -+/*! -+ * @name PDumpOSCPUVAddrToPhysPages -+ * @brief OS function to convert CPU virtual to backing physical pages -+ * @param hOSMemHandle mem allocation handle (used if kernel virtual mem space is limited, e.g. linux) -+ * @param ui32Offset offset within mem allocation block -+ * @param pui8LinAddr CPU linear addr -+ * @param uiDataPageMask mask for data page (= data page size -1) -+ * @return pui32PageOffset CPU page offset (same as device page offset if page sizes equal) -+ */ -+IMG_VOID PDumpOSCPUVAddrToPhysPages(IMG_HANDLE hOSMemHandle, -+ IMG_UINT32 ui32Offset, -+ IMG_PUINT8 pui8LinAddr, -+ IMG_UINTPTR_T uiDataPageMask, -+ IMG_UINT32 *pui32PageOffset); -+ -+/*! -+ * @name PDumpOSReleaseExecution -+ * @brief OS function to switch to another process, to clear pdump buffers -+ */ -+IMG_VOID PDumpOSReleaseExecution(IMG_VOID); -+ -+/*! -+ * @name PDumpOSIsCaptureFrameKM -+ * @brief Is the current frame a capture frame? -+ */ -+IMG_BOOL PDumpOSIsCaptureFrameKM(IMG_VOID); -+ -+/*! -+ * @name PDumpOSSetFrameKM -+ * @brief Set frame counter -+ */ -+PVRSRV_ERROR PDumpOSSetFrameKM(IMG_UINT32 ui32Frame); -+ -+#if defined (__cplusplus) -+} -+#endif -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/include/perfkm.h b/drivers/staging/ti-es8-sgx/services4/srvkm/include/perfkm.h -new file mode 100644 -index 0000000..458a29b ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/include/perfkm.h -@@ -0,0 +1,53 @@ -+/*************************************************************************/ /*! -+@Title Perf initialisation -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+#ifndef _PERFKM_H_ -+#define _PERFKM_H_ -+ -+#include "img_types.h" -+ -+#define PERFINIT() -+#define PERFDEINIT() -+ -+#endif /* _PERFKM_H_ */ -+ -+/****************************************************************************** -+ End of file (perfkm.h) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/include/perproc.h b/drivers/staging/ti-es8-sgx/services4/srvkm/include/perproc.h -new file mode 100644 -index 0000000..124f2f2 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/include/perproc.h -@@ -0,0 +1,141 @@ -+/*************************************************************************/ /*! -+@Title Handle Manager API -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Perprocess data -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+#ifndef __PERPROC_H__ -+#define __PERPROC_H__ -+ -+#if defined (__cplusplus) -+extern "C" { -+#endif -+ -+#include "img_types.h" -+#include "resman.h" -+ -+#include "handle.h" -+ -+typedef struct _PVRSRV_PER_PROCESS_DATA_ -+{ -+ IMG_UINT32 ui32PID; -+ IMG_HANDLE hBlockAlloc; -+ PRESMAN_CONTEXT hResManContext; -+ IMG_HANDLE hPerProcData; -+ PVRSRV_HANDLE_BASE *psHandleBase; -+#if defined (PVR_SECURE_HANDLES) -+ /* Handles are being allocated in batches */ -+ IMG_BOOL bHandlesBatched; -+#endif /* PVR_SECURE_HANDLES */ -+ IMG_UINT32 ui32RefCount; -+ -+ /* True if the process is the initialisation server. */ -+ IMG_BOOL bInitProcess; -+#if defined(PDUMP) -+ /* True if pdump data from the process is 'persistent' */ -+ IMG_BOOL bPDumpPersistent; -+#if defined(SUPPORT_PDUMP_MULTI_PROCESS) -+ /* True if this process is marked for pdumping. This flag is -+ * significant in a multi-app environment. -+ */ -+ IMG_BOOL bPDumpActive; -+#endif /* SUPPORT_PDUMP_MULTI_PROCESS */ -+#endif -+ /* -+ * OS specific data can be stored via this handle. -+ * See osperproc.h for a generic mechanism for initialising -+ * this field. -+ */ -+ IMG_HANDLE hOsPrivateData; -+} PVRSRV_PER_PROCESS_DATA; -+ -+PVRSRV_PER_PROCESS_DATA *PVRSRVPerProcessData(IMG_UINT32 ui32PID); -+ -+PVRSRV_ERROR PVRSRVPerProcessDataConnect(IMG_UINT32 ui32PID, IMG_UINT32 ui32Flags); -+IMG_VOID PVRSRVPerProcessDataDisconnect(IMG_UINT32 ui32PID); -+ -+PVRSRV_ERROR PVRSRVPerProcessDataInit(IMG_VOID); -+PVRSRV_ERROR PVRSRVPerProcessDataDeInit(IMG_VOID); -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(PVRSRVFindPerProcessData) -+#endif -+static INLINE -+PVRSRV_PER_PROCESS_DATA *PVRSRVFindPerProcessData(IMG_VOID) -+{ -+ return PVRSRVPerProcessData(OSGetCurrentProcessIDKM()); -+} -+ -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(PVRSRVProcessPrivateData) -+#endif -+static INLINE -+IMG_HANDLE PVRSRVProcessPrivateData(PVRSRV_PER_PROCESS_DATA *psPerProc) -+{ -+ return (psPerProc != IMG_NULL) ? psPerProc->hOsPrivateData : IMG_NULL; -+} -+ -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(PVRSRVPerProcessPrivateData) -+#endif -+static INLINE -+IMG_HANDLE PVRSRVPerProcessPrivateData(IMG_UINT32 ui32PID) -+{ -+ return PVRSRVProcessPrivateData(PVRSRVPerProcessData(ui32PID)); -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(PVRSRVFindPerProcessPrivateData) -+#endif -+static INLINE -+IMG_HANDLE PVRSRVFindPerProcessPrivateData(IMG_VOID) -+{ -+ return PVRSRVProcessPrivateData(PVRSRVFindPerProcessData()); -+} -+ -+#if defined (__cplusplus) -+} -+#endif -+ -+#endif /* __PERPROC_H__ */ -+ -+/****************************************************************************** -+ End of file (perproc.h) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/include/power.h b/drivers/staging/ti-es8-sgx/services4/srvkm/include/power.h -new file mode 100644 -index 0000000..5f54de3 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/include/power.h -@@ -0,0 +1,140 @@ -+/*************************************************************************/ /*! -+@Title Power Management Functions -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Main APIs for power management functions -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+#ifndef POWER_H -+#define POWER_H -+ -+#if defined(__cplusplus) -+extern "C" { -+#endif -+ -+ -+/*! -+ ***************************************************************************** -+ * Power management -+ *****************************************************************************/ -+ -+typedef struct _PVRSRV_POWER_DEV_TAG_ -+{ -+ PFN_PRE_POWER pfnPrePower; -+ PFN_POST_POWER pfnPostPower; -+ PFN_PRE_CLOCKSPEED_CHANGE pfnPreClockSpeedChange; -+ PFN_POST_CLOCKSPEED_CHANGE pfnPostClockSpeedChange; -+ IMG_HANDLE hDevCookie; -+ IMG_UINT32 ui32DeviceIndex; -+ PVRSRV_DEV_POWER_STATE eDefaultPowerState; -+ PVRSRV_DEV_POWER_STATE eCurrentPowerState; -+ struct _PVRSRV_POWER_DEV_TAG_ *psNext; -+ struct _PVRSRV_POWER_DEV_TAG_ **ppsThis; -+ -+} PVRSRV_POWER_DEV; -+ -+typedef enum _PVRSRV_INIT_SERVER_STATE_ -+{ -+ PVRSRV_INIT_SERVER_Unspecified = -1, -+ PVRSRV_INIT_SERVER_RUNNING = 0, -+ PVRSRV_INIT_SERVER_RAN = 1, -+ PVRSRV_INIT_SERVER_SUCCESSFUL = 2, -+ PVRSRV_INIT_SERVER_NUM = 3, -+ PVRSRV_INIT_SERVER_FORCE_I32 = 0x7fffffff -+ -+} PVRSRV_INIT_SERVER_STATE, *PPVRSRV_INIT_SERVER_STATE; -+ -+IMG_IMPORT -+IMG_BOOL PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_STATE eInitServerState); -+ -+IMG_IMPORT -+PVRSRV_ERROR PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_STATE eInitServerState, IMG_BOOL bState); -+ -+ -+ -+IMG_IMPORT -+PVRSRV_ERROR PVRSRVPowerLock(IMG_UINT32 ui32CallerID, -+ IMG_BOOL bSystemPowerEvent); -+IMG_IMPORT -+IMG_VOID PVRSRVPowerUnlock(IMG_UINT32 ui32CallerID); -+ -+IMG_IMPORT -+PVRSRV_ERROR PVRSRVSetDevicePowerStateKM(IMG_UINT32 ui32DeviceIndex, -+ PVRSRV_DEV_POWER_STATE eNewPowerState); -+ -+IMG_IMPORT -+PVRSRV_ERROR PVRSRVSystemPrePowerStateKM(PVRSRV_SYS_POWER_STATE eNewPowerState); -+IMG_IMPORT -+PVRSRV_ERROR PVRSRVSystemPostPowerStateKM(PVRSRV_SYS_POWER_STATE eNewPowerState); -+ -+IMG_IMPORT -+PVRSRV_ERROR PVRSRVSetPowerStateKM (PVRSRV_SYS_POWER_STATE ePVRState); -+ -+IMG_IMPORT -+PVRSRV_ERROR PVRSRVRegisterPowerDevice(IMG_UINT32 ui32DeviceIndex, -+ PFN_PRE_POWER pfnPrePower, -+ PFN_POST_POWER pfnPostPower, -+ PFN_PRE_CLOCKSPEED_CHANGE pfnPreClockSpeedChange, -+ PFN_POST_CLOCKSPEED_CHANGE pfnPostClockSpeedChange, -+ IMG_HANDLE hDevCookie, -+ PVRSRV_DEV_POWER_STATE eCurrentPowerState, -+ PVRSRV_DEV_POWER_STATE eDefaultPowerState); -+ -+IMG_IMPORT -+PVRSRV_ERROR PVRSRVRemovePowerDevice (IMG_UINT32 ui32DeviceIndex); -+ -+IMG_IMPORT -+IMG_BOOL PVRSRVIsDevicePowered(IMG_UINT32 ui32DeviceIndex); -+ -+IMG_IMPORT -+PVRSRV_ERROR PVRSRVDevicePreClockSpeedChange(IMG_UINT32 ui32DeviceIndex, -+ IMG_BOOL bIdleDevice, -+ IMG_VOID *pvInfo); -+ -+IMG_IMPORT -+IMG_VOID PVRSRVDevicePostClockSpeedChange(IMG_UINT32 ui32DeviceIndex, -+ IMG_BOOL bIdleDevice, -+ IMG_VOID *pvInfo); -+ -+#if defined (__cplusplus) -+} -+#endif -+#endif /* POWER_H */ -+ -+/****************************************************************************** -+ End of file (power.h) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/include/queue.h b/drivers/staging/ti-es8-sgx/services4/srvkm/include/queue.h -new file mode 100644 -index 0000000..6784567 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/include/queue.h -@@ -0,0 +1,151 @@ -+/*************************************************************************/ /*! -+@Title Command Queue API -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Internal structures and definitions for command queues -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#ifndef QUEUE_H -+#define QUEUE_H -+ -+ -+#if defined(__cplusplus) -+extern "C" { -+#endif -+ -+/*! -+ * Macro to Read Offset in given command queue -+ */ -+#define UPDATE_QUEUE_ROFF(psQueue, uSize) \ -+ (psQueue)->uReadOffset = ((psQueue)->uReadOffset + (uSize)) \ -+ & ((psQueue)->uQueueSize - 1); -+ -+/*! -+ generic cmd complete structure. -+ This structure represents the storage required between starting and finishing -+ a given cmd and is required to hold the generic sync object update data. -+ note: for any given system we know what command types we support and -+ therefore how much storage is required for any number of commands in progress -+ */ -+ typedef struct _COMMAND_COMPLETE_DATA_ -+ { -+ IMG_BOOL bInUse; -+ /* <arg(s) to PVRSRVProcessQueues>; */ /*!< TBD */ -+ IMG_UINT32 ui32DstSyncCount; /*!< number of dst sync objects */ -+ IMG_UINT32 ui32SrcSyncCount; /*!< number of src sync objects */ -+ PVRSRV_SYNC_OBJECT *psDstSync; /*!< dst sync ptr list, -+ allocated on back of this structure */ -+ PVRSRV_SYNC_OBJECT *psSrcSync; /*!< src sync ptr list, -+ allocated on back of this structure */ -+ IMG_UINT32 ui32AllocSize; /*!< allocated size*/ -+ PFN_QUEUE_COMMAND_COMPLETE pfnCommandComplete; /*!< Command complete callback */ -+ IMG_HANDLE hCallbackData; /*!< Command complete callback data */ -+ -+#if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) -+ IMG_VOID *pvCleanupFence; /*!< Sync fence to 'put' after timeline inc() */ -+ IMG_VOID *pvTimeline; /*!< Android sync timeline to inc() */ -+#endif -+ }COMMAND_COMPLETE_DATA, *PCOMMAND_COMPLETE_DATA; -+ -+#if !defined(USE_CODE) -+IMG_VOID QueueDumpDebugInfo(IMG_VOID); -+ -+IMG_IMPORT -+PVRSRV_ERROR PVRSRVProcessQueues (IMG_BOOL bFlush); -+ -+#if defined(__linux__) && defined(__KERNEL__) -+#include <linux/types.h> -+#include <linux/seq_file.h> -+void* ProcSeqOff2ElementQueue(struct seq_file * sfile, loff_t off); -+void ProcSeqShowQueue(struct seq_file *sfile,void* el); -+#endif -+ -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateCommandQueueKM(IMG_SIZE_T uQueueSize, -+ PVRSRV_QUEUE_INFO **ppsQueueInfo); -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyCommandQueueKM(PVRSRV_QUEUE_INFO *psQueueInfo); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVInsertCommandKM(PVRSRV_QUEUE_INFO *psQueue, -+ PVRSRV_COMMAND **ppsCommand, -+ IMG_UINT32 ui32DevIndex, -+ IMG_UINT16 CommandType, -+ IMG_UINT32 ui32DstSyncCount, -+ PVRSRV_KERNEL_SYNC_INFO *apsDstSync[], -+ IMG_UINT32 ui32SrcSyncCount, -+ PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[], -+ IMG_SIZE_T ui32DataByteSize, -+ PFN_QUEUE_COMMAND_COMPLETE pfnCommandComplete, -+ IMG_HANDLE hCallbackData, -+ IMG_HANDLE *phFence); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVGetQueueSpaceKM(PVRSRV_QUEUE_INFO *psQueue, -+ IMG_SIZE_T uParamSize, -+ IMG_VOID **ppvSpace); -+ -+IMG_IMPORT -+PVRSRV_ERROR IMG_CALLCONV PVRSRVSubmitCommandKM(PVRSRV_QUEUE_INFO *psQueue, -+ PVRSRV_COMMAND *psCommand); -+ -+IMG_IMPORT -+IMG_VOID PVRSRVCommandCompleteKM(IMG_HANDLE hCmdCookie, IMG_BOOL bScheduleMISR); -+ -+IMG_IMPORT -+PVRSRV_ERROR PVRSRVRegisterCmdProcListKM(IMG_UINT32 ui32DevIndex, -+ PFN_CMD_PROC *ppfnCmdProcList, -+ IMG_UINT32 ui32MaxSyncsPerCmd[][2], -+ IMG_UINT32 ui32CmdCount); -+IMG_IMPORT -+PVRSRV_ERROR PVRSRVRemoveCmdProcListKM(IMG_UINT32 ui32DevIndex, -+ IMG_UINT32 ui32CmdCount); -+ -+#endif /* !defined(USE_CODE) */ -+ -+ -+#if defined (__cplusplus) -+} -+#endif -+ -+#endif /* QUEUE_H */ -+ -+/****************************************************************************** -+ End of file (queue.h) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/include/ra.h b/drivers/staging/ti-es8-sgx/services4/srvkm/include/ra.h -new file mode 100644 -index 0000000..2f872d8 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/include/ra.h -@@ -0,0 +1,289 @@ -+/*************************************************************************/ /*! -+@Title Resource Allocator API -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#ifndef _RA_H_ -+#define _RA_H_ -+ -+#include "img_types.h" -+#include "hash.h" -+#include "osfunc.h" -+ -+/** Resource arena. -+ * struct _RA_ARENA_ deliberately opaque -+ */ -+typedef struct _RA_ARENA_ RA_ARENA; //PRQA S 3313 -+typedef struct _BM_MAPPING_ BM_MAPPING; -+ -+ -+ -+/** Enable support for arena statistics. */ -+#define RA_STATS -+ -+ -+/** Resource arena statistics. */ -+struct _RA_STATISTICS_ -+{ -+ /** total number of segments add to the arena */ -+ IMG_SIZE_T uSpanCount; -+ -+ /** number of current live segments within the arena */ -+ IMG_SIZE_T uLiveSegmentCount; -+ -+ /** number of current free segments within the arena */ -+ IMG_SIZE_T uFreeSegmentCount; -+ -+ /** total number of resource within the arena */ -+ IMG_SIZE_T uTotalResourceCount; -+ -+ /** number of free resource within the arena */ -+ IMG_SIZE_T uFreeResourceCount; -+ -+ /** total number of resources allocated from the arena */ -+ IMG_SIZE_T uCumulativeAllocs; -+ -+ /** total number of resources returned to the arena */ -+ IMG_SIZE_T uCumulativeFrees; -+ -+ /** total number of spans allocated by the callback mechanism */ -+ IMG_SIZE_T uImportCount; -+ -+ /** total number of spans deallocated by the callback mechanism */ -+ IMG_SIZE_T uExportCount; -+}; -+typedef struct _RA_STATISTICS_ RA_STATISTICS; -+ -+struct _RA_SEGMENT_DETAILS_ -+{ -+ IMG_SIZE_T uiSize; -+ IMG_CPU_PHYADDR sCpuPhyAddr; -+ IMG_HANDLE hSegment; -+}; -+typedef struct _RA_SEGMENT_DETAILS_ RA_SEGMENT_DETAILS; -+ -+/** -+ * @Function RA_Create -+ * -+ * @Description -+ * -+ * To create a resource arena. -+ * -+ * @Input name - the name of the arena for diagnostic purposes. -+ * @Input base - the base of an initial resource span or 0. -+ * @Input uSize - the size of an initial resource span or 0. -+ * @Input pRef - the reference to return for the initial resource or 0. -+ * @Input uQuantum - the arena allocation quantum. -+ * @Input alloc - a resource allocation callback or 0. -+ * @Input free - a resource de-allocation callback or 0. -+ * @Input import_handle - handle passed to alloc and free or 0. -+ * @Return arena handle, or IMG_NULL. -+ */ -+RA_ARENA * -+RA_Create (IMG_CHAR *name, -+ IMG_UINTPTR_T base, -+ IMG_SIZE_T uSize, -+ BM_MAPPING *psMapping, -+ IMG_SIZE_T uQuantum, -+ IMG_BOOL (*imp_alloc)(IMG_VOID *_h, -+ IMG_SIZE_T uSize, -+ IMG_SIZE_T *pActualSize, -+ BM_MAPPING **ppsMapping, -+ IMG_UINT32 uFlags, -+ IMG_PVOID pvPrivData, -+ IMG_UINT32 ui32PrivDataLength, -+ IMG_UINTPTR_T *pBase), -+ IMG_VOID (*imp_free) (IMG_VOID *, -+ IMG_UINTPTR_T, -+ BM_MAPPING *), -+ IMG_VOID (*backingstore_free) (IMG_VOID *, -+ IMG_SIZE_T, -+ IMG_SIZE_T, -+ IMG_HANDLE), -+ IMG_VOID *import_handle); -+ -+/** -+ * @Function RA_Delete -+ * -+ * @Description -+ * -+ * To delete a resource arena. All resources allocated from the arena -+ * must be freed before deleting the arena. -+ * -+ * @Input pArena - the arena to delete. -+ * @Return None -+ */ -+IMG_VOID -+RA_Delete (RA_ARENA *pArena); -+ -+/** -+ * @Function RA_TestDelete -+ * -+ * @Description -+ * -+ * To test whether it is safe to delete a resource arena. If any allocations -+ * have not been freed, the RA must not be deleted. -+ * -+ * @Input pArena - the arena to test. -+ * @Return IMG_BOOL - IMG_TRUE if is safe to go on and call RA_Delete. -+ */ -+IMG_BOOL -+RA_TestDelete (RA_ARENA *pArena); -+ -+/** -+ * @Function RA_Add -+ * -+ * @Description -+ * -+ * To add a resource span to an arena. The span must not overlap with -+ * any span previously added to the arena. -+ * -+ * @Input pArena - the arena to add a span into. -+ * @Input base - the base of the span. -+ * @Input uSize - the extent of the span. -+ * @Return IMG_TRUE - success, IMG_FALSE - failure -+ */ -+IMG_BOOL -+RA_Add (RA_ARENA *pArena, IMG_UINTPTR_T base, IMG_SIZE_T uSize); -+ -+/** -+ * @Function RA_Alloc -+ * -+ * @Description -+ * -+ * To allocate resource from an arena. -+ * -+ * @Input pArena - the arena -+ * @Input uRequestSize - the size of resource segment requested. -+ * @Output pActualSize - the actual_size of resource segment allocated, -+ * typcially rounded up by quantum. -+ * @Output ppsMapping - the user reference associated with allocated -+ * resource span. -+ * @Input uFlags - flags influencing allocation policy. -+ * @Input uAlignment - the alignment constraint required for the -+ * allocated segment, use 0 if alignment not required. -+ * @Input uAlignmentOffset - the required alignment offset -+ * @Input pvPrivData - private data passed to OS allocator -+ * @Input ui32PrivData - length of private data -+ * -+ * @Output pBase - allocated base resource -+ * @Return IMG_TRUE - success, IMG_FALSE - failure -+ */ -+IMG_BOOL -+RA_Alloc (RA_ARENA *pArena, -+ IMG_SIZE_T uSize, -+ IMG_SIZE_T *pActualSize, -+ BM_MAPPING **ppsMapping, -+ IMG_UINT32 uFlags, -+ IMG_UINT32 uAlignment, -+ IMG_UINT32 uAlignmentOffset, -+ IMG_PVOID pvPrivData, -+ IMG_UINT32 ui32PrivDataLength, -+ IMG_UINTPTR_T *pBase); -+ -+/** -+ * @Function RA_Free -+ * -+ * @Description To free a resource segment. -+ * -+ * @Input pArena - the arena the segment was originally allocated from. -+ * @Input base - the base of the resource span to free. -+ * @Input bFreeBackingStore - Should backing store memory be freed? -+ * -+ * @Return None -+ */ -+IMG_VOID -+RA_Free (RA_ARENA *pArena, IMG_UINTPTR_T base, IMG_BOOL bFreeBackingStore); -+ -+ -+#ifdef RA_STATS -+ -+#define CHECK_SPACE(total) \ -+{ \ -+ if((total)<100) \ -+ return PVRSRV_ERROR_INVALID_PARAMS; \ -+} -+ -+#define UPDATE_SPACE(str, count, total) \ -+{ \ -+ if((count) == -1) \ -+ return PVRSRV_ERROR_INVALID_PARAMS; \ -+ else \ -+ { \ -+ (str) += (count); \ -+ (total) -= (count); \ -+ } \ -+} -+ -+ -+/** -+ * @Function RA_GetNextLiveSegment -+ * -+ * @Description Returns details of the next live resource segments -+ * -+ * @Input pArena - the arena the segment was originally allocated from. -+ * @Output psSegDetails - rtn details of segments -+ * -+ * @Return IMG_TRUE if operation succeeded -+ */ -+IMG_BOOL RA_GetNextLiveSegment(IMG_HANDLE hArena, RA_SEGMENT_DETAILS *psSegDetails); -+ -+ -+/** -+ * @Function RA_GetStats -+ * -+ * @Description gets stats on a given arena -+ * -+ * @Input pArena - the arena the segment was originally allocated from. -+ * @Input ppszStr - string to write stats to -+ * @Input pui32StrLen - length of string -+ * -+ * @Return PVRSRV_ERROR -+ */ -+PVRSRV_ERROR RA_GetStats(RA_ARENA *pArena, -+ IMG_CHAR **ppszStr, -+ IMG_UINT32 *pui32StrLen); -+ -+PVRSRV_ERROR RA_GetStatsFreeMem(RA_ARENA *pArena, -+ IMG_CHAR **ppszStr, -+ IMG_UINT32 *pui32StrLen); -+ -+#endif /* #ifdef RA_STATS */ -+ -+#endif -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/include/refcount.h b/drivers/staging/ti-es8-sgx/services4/srvkm/include/refcount.h -new file mode 100644 -index 0000000..a2efd6c ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/include/refcount.h -@@ -0,0 +1,246 @@ -+/*************************************************************************/ /*! -+@Title Services reference count debugging -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#ifndef __REFCOUNT_H__ -+#define __REFCOUNT_H__ -+ -+#include "pvr_bridge_km.h" -+#if defined(SUPPORT_ION) -+#include "ion_sync.h" -+#endif /* defined(SUPPORT_ION) */ -+ -+#if defined(PVRSRV_REFCOUNT_DEBUG) -+ -+void PVRSRVDumpRefCountCCB(void); -+ -+#define PVRSRVKernelSyncInfoIncRef(x...) \ -+ PVRSRVKernelSyncInfoIncRef2(__FILE__, __LINE__, x) -+#define PVRSRVKernelSyncInfoDecRef(x...) \ -+ PVRSRVKernelSyncInfoDecRef2(__FILE__, __LINE__, x) -+#define PVRSRVKernelMemInfoIncRef(x...) \ -+ PVRSRVKernelMemInfoIncRef2(__FILE__, __LINE__, x) -+#define PVRSRVKernelMemInfoDecRef(x...) \ -+ PVRSRVKernelMemInfoDecRef2(__FILE__, __LINE__, x) -+#define PVRSRVBMBufIncRef(x...) \ -+ PVRSRVBMBufIncRef2(__FILE__, __LINE__, x) -+#define PVRSRVBMBufDecRef(x...) \ -+ PVRSRVBMBufDecRef2(__FILE__, __LINE__, x) -+#define PVRSRVBMBufIncExport(x...) \ -+ PVRSRVBMBufIncExport2(__FILE__, __LINE__, x) -+#define PVRSRVBMBufDecExport(x...) \ -+ PVRSRVBMBufDecExport2(__FILE__, __LINE__, x) -+ -+void PVRSRVKernelSyncInfoIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine, -+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo, -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo); -+void PVRSRVKernelSyncInfoDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine, -+ PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo, -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo); -+void PVRSRVKernelMemInfoIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine, -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo); -+void PVRSRVKernelMemInfoDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine, -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo); -+void PVRSRVBMBufIncRef2(const IMG_CHAR *pszFile, -+ IMG_INT iLine, BM_BUF *pBuf); -+void PVRSRVBMBufDecRef2(const IMG_CHAR *pszFile, -+ IMG_INT iLine, BM_BUF *pBuf); -+void PVRSRVBMBufIncExport2(const IMG_CHAR *pszFile, -+ IMG_INT iLine, BM_BUF *pBuf); -+void PVRSRVBMBufDecExport2(const IMG_CHAR *pszFile, -+ IMG_INT iLine, BM_BUF *pBuf); -+void PVRSRVBMXProcIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine, -+ IMG_UINT32 ui32Index); -+void PVRSRVBMXProcDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine, -+ IMG_UINT32 ui32Index); -+ -+#if defined(__linux__) -+ -+/* mmap refcounting is Linux specific */ -+#include "mmap.h" -+ -+#define PVRSRVOffsetStructIncRef(x...) \ -+ PVRSRVOffsetStructIncRef2(__FILE__, __LINE__, x) -+#define PVRSRVOffsetStructDecRef(x...) \ -+ PVRSRVOffsetStructDecRef2(__FILE__, __LINE__, x) -+#define PVRSRVOffsetStructIncMapped(x...) \ -+ PVRSRVOffsetStructIncMapped2(__FILE__, __LINE__, x) -+#define PVRSRVOffsetStructDecMapped(x...) \ -+ PVRSRVOffsetStructDecMapped2(__FILE__, __LINE__, x) -+ -+void PVRSRVOffsetStructIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine, -+ PKV_OFFSET_STRUCT psOffsetStruct); -+void PVRSRVOffsetStructDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine, -+ PKV_OFFSET_STRUCT psOffsetStruct); -+void PVRSRVOffsetStructIncMapped2(const IMG_CHAR *pszFile, IMG_INT iLine, -+ PKV_OFFSET_STRUCT psOffsetStruct); -+void PVRSRVOffsetStructDecMapped2(const IMG_CHAR *pszFile, IMG_INT iLine, -+ PKV_OFFSET_STRUCT psOffsetStruct); -+ -+#if defined(SUPPORT_ION) -+#define PVRSRVIonBufferSyncInfoIncRef(x...) \ -+ PVRSRVIonBufferSyncInfoIncRef2(__FILE__, __LINE__, x) -+#define PVRSRVIonBufferSyncInfoDecRef(x...) \ -+ PVRSRVIonBufferSyncInfoDecRef2(__FILE__, __LINE__, x) -+ -+PVRSRV_ERROR PVRSRVIonBufferSyncInfoIncRef2(const IMG_CHAR *pszFile, IMG_INT iLine, -+ IMG_HANDLE hUnique, -+ IMG_HANDLE hDevCookie, -+ IMG_HANDLE hDevMemContext, -+ PVRSRV_ION_SYNC_INFO **ppsIonSyncInfo, -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo); -+void PVRSRVIonBufferSyncInfoDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine, -+ PVRSRV_ION_SYNC_INFO *psIonSyncInfo, -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo); -+#endif /* defined (SUPPORT_ION) */ -+ -+#endif /* defined(__linux__) */ -+ -+#else /* defined(PVRSRV_REFCOUNT_DEBUG) */ -+ -+static INLINE void PVRSRVDumpRefCountCCB(void) { } -+ -+static INLINE void PVRSRVKernelSyncInfoIncRef(PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo, -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo) -+{ -+ PVR_UNREFERENCED_PARAMETER(psKernelMemInfo); -+ PVRSRVAcquireSyncInfoKM(psKernelSyncInfo); -+} -+ -+static INLINE void PVRSRVKernelSyncInfoDecRef(PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo, -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo) -+{ -+ PVR_UNREFERENCED_PARAMETER(psKernelMemInfo); -+ PVRSRVReleaseSyncInfoKM(psKernelSyncInfo); -+} -+ -+static INLINE void PVRSRVKernelMemInfoIncRef(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo) -+{ -+ psKernelMemInfo->ui32RefCount++; -+} -+ -+static INLINE void PVRSRVKernelMemInfoDecRef(PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo) -+{ -+ psKernelMemInfo->ui32RefCount--; -+} -+ -+static INLINE void PVRSRVBMBufIncRef(BM_BUF *pBuf) -+{ -+ pBuf->ui32RefCount++; -+} -+ -+static INLINE void PVRSRVBMBufDecRef(BM_BUF *pBuf) -+{ -+ pBuf->ui32RefCount--; -+} -+ -+static INLINE void PVRSRVBMBufIncExport(BM_BUF *pBuf) -+{ -+ pBuf->ui32ExportCount++; -+} -+ -+static INLINE void PVRSRVBMBufDecExport(BM_BUF *pBuf) -+{ -+ pBuf->ui32ExportCount--; -+} -+ -+static INLINE void PVRSRVBMXProcIncRef(IMG_UINT32 ui32Index) -+{ -+ gXProcWorkaroundShareData[ui32Index].ui32RefCount++; -+} -+ -+static INLINE void PVRSRVBMXProcDecRef(IMG_UINT32 ui32Index) -+{ -+ gXProcWorkaroundShareData[ui32Index].ui32RefCount--; -+} -+ -+#if defined(__linux__) -+ -+/* mmap refcounting is Linux specific */ -+#include "mmap.h" -+ -+static INLINE void PVRSRVOffsetStructIncRef(PKV_OFFSET_STRUCT psOffsetStruct) -+{ -+ psOffsetStruct->ui32RefCount++; -+} -+ -+static INLINE void PVRSRVOffsetStructDecRef(PKV_OFFSET_STRUCT psOffsetStruct) -+{ -+ psOffsetStruct->ui32RefCount--; -+} -+ -+static INLINE void PVRSRVOffsetStructIncMapped(PKV_OFFSET_STRUCT psOffsetStruct) -+{ -+ psOffsetStruct->ui32Mapped++; -+} -+ -+static INLINE void PVRSRVOffsetStructDecMapped(PKV_OFFSET_STRUCT psOffsetStruct) -+{ -+ psOffsetStruct->ui32Mapped--; -+} -+ -+#if defined(SUPPORT_ION) -+static INLINE PVRSRV_ERROR PVRSRVIonBufferSyncInfoIncRef(IMG_HANDLE hUnique, -+ IMG_HANDLE hDevCookie, -+ IMG_HANDLE hDevMemContext, -+ PVRSRV_ION_SYNC_INFO **ppsIonSyncInfo, -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo) -+{ -+ PVR_UNREFERENCED_PARAMETER(psKernelMemInfo); -+ -+ return PVRSRVIonBufferSyncAcquire(hUnique, -+ hDevCookie, -+ hDevMemContext, -+ ppsIonSyncInfo); -+} -+ -+static INLINE void PVRSRVIonBufferSyncInfoDecRef(PVRSRV_ION_SYNC_INFO *psIonSyncInfo, -+ PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo) -+{ -+ PVR_UNREFERENCED_PARAMETER(psKernelMemInfo); -+ PVRSRVIonBufferSyncRelease(psIonSyncInfo); -+} -+#endif /* defined (SUPPORT_ION) */ -+ -+#endif /* defined(__linux__) */ -+ -+#endif /* defined(PVRSRV_REFCOUNT_DEBUG) */ -+ -+#endif /* __REFCOUNT_H__ */ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/include/resman.h b/drivers/staging/ti-es8-sgx/services4/srvkm/include/resman.h -new file mode 100644 -index 0000000..a39f382 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/include/resman.h -@@ -0,0 +1,151 @@ -+/*************************************************************************/ /*! -+@Title Resource Manager API -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Provide resource management -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#ifndef __RESMAN_H__ -+#define __RESMAN_H__ -+ -+#if defined (__cplusplus) -+extern "C" { -+#endif -+ -+/****************************************************************************** -+ * resman definitions -+ *****************************************************************************/ -+ -+enum { -+ /* SGX: */ -+ RESMAN_TYPE_SHARED_PB_DESC = 1, /*!< Parameter buffer kernel stubs */ -+ RESMAN_TYPE_SHARED_PB_DESC_CREATE_LOCK, /*!< Shared parameter buffer creation lock */ -+ RESMAN_TYPE_HW_RENDER_CONTEXT, /*!< Hardware Render Context Resource */ -+ RESMAN_TYPE_HW_TRANSFER_CONTEXT, /*!< Hardware transfer Context Resource */ -+ RESMAN_TYPE_HW_2D_CONTEXT, /*!< Hardware 2D Context Resource */ -+ RESMAN_TYPE_TRANSFER_CONTEXT, /*!< Transfer Queue context */ -+ -+ /* VGX: */ -+ RESMAN_TYPE_DMA_CLIENT_FIFO_DATA, /*!< VGX DMA Client FIFO data */ -+ -+ /* DISPLAY CLASS: */ -+ RESMAN_TYPE_DISPLAYCLASS_SWAPCHAIN_REF, /*!< Display Class Swapchain Reference Resource */ -+ RESMAN_TYPE_DISPLAYCLASS_DEVICE, /*!< Display Class Device Resource */ -+ -+ /* BUFFER CLASS: */ -+ RESMAN_TYPE_BUFFERCLASS_DEVICE, /*!< Buffer Class Device Resource */ -+ -+ /* OS specific User mode Mappings: */ -+ RESMAN_TYPE_OS_USERMODE_MAPPING, /*!< OS specific User mode mappings */ -+ -+ /* COMMON: */ -+ RESMAN_TYPE_DEVICEMEM_CONTEXT, /*!< Device Memory Context Resource */ -+ RESMAN_TYPE_DEVICECLASSMEM_MAPPING, /*!< Device Memory Mapping Resource */ -+ RESMAN_TYPE_DEVICEMEM_MAPPING, /*!< Device Memory Mapping Resource */ -+ RESMAN_TYPE_DEVICEMEM_WRAP, /*!< Device Memory Wrap Resource */ -+ RESMAN_TYPE_DEVICEMEM_ALLOCATION, /*!< Device Memory Allocation Resource */ -+ RESMAN_TYPE_DEVICEMEM_ION, /*!< Device Memory Ion Resource */ -+ RESMAN_TYPE_EVENT_OBJECT, /*!< Event Object */ -+ RESMAN_TYPE_SHARED_MEM_INFO, /*!< Shared system memory meminfo */ -+ RESMAN_TYPE_MODIFY_SYNC_OPS, /*!< Syncobject synchronisation Resource*/ -+ RESMAN_TYPE_SYNC_INFO, /*!< Syncobject Resource*/ -+ -+ /* KERNEL: */ -+ RESMAN_TYPE_KERNEL_DEVICEMEM_ALLOCATION /*!< Device Memory Allocation Resource */ -+}; -+ -+#define RESMAN_CRITERIA_ALL 0x00000000 /*!< match by criteria all */ -+#define RESMAN_CRITERIA_RESTYPE 0x00000001 /*!< match by criteria type */ -+#define RESMAN_CRITERIA_PVOID_PARAM 0x00000002 /*!< match by criteria param1 */ -+#define RESMAN_CRITERIA_UI32_PARAM 0x00000004 /*!< match by criteria param2 */ -+ -+typedef PVRSRV_ERROR (*RESMAN_FREE_FN)(IMG_PVOID pvParam, IMG_UINT32 ui32Param, IMG_BOOL bForceCleanup); -+ -+typedef struct _RESMAN_ITEM_ *PRESMAN_ITEM; -+typedef struct _RESMAN_CONTEXT_ *PRESMAN_CONTEXT; -+ -+/****************************************************************************** -+ * resman functions -+ *****************************************************************************/ -+ -+/* -+ Note: -+ Resource cleanup can fail with retry in which case we don't remove -+ it from resman's list and either UM or KM will try to release the -+ resource at a later date (and will keep trying until a non-retry -+ error is returned) -+*/ -+ -+PVRSRV_ERROR ResManInit(IMG_VOID); -+IMG_VOID ResManDeInit(IMG_VOID); -+ -+PRESMAN_ITEM ResManRegisterRes(PRESMAN_CONTEXT hResManContext, -+ IMG_UINT32 ui32ResType, -+ IMG_PVOID pvParam, -+ IMG_UINT32 ui32Param, -+ RESMAN_FREE_FN pfnFreeResource); -+ -+PVRSRV_ERROR ResManFreeResByPtr(PRESMAN_ITEM psResItem, -+ IMG_BOOL bForceCleanup); -+ -+PVRSRV_ERROR ResManFreeResByCriteria(PRESMAN_CONTEXT hResManContext, -+ IMG_UINT32 ui32SearchCriteria, -+ IMG_UINT32 ui32ResType, -+ IMG_PVOID pvParam, -+ IMG_UINT32 ui32Param); -+ -+PVRSRV_ERROR ResManDissociateRes(PRESMAN_ITEM psResItem, -+ PRESMAN_CONTEXT psNewResManContext); -+ -+PVRSRV_ERROR ResManFindResourceByPtr(PRESMAN_CONTEXT hResManContext, -+ PRESMAN_ITEM psItem); -+ -+PVRSRV_ERROR PVRSRVResManConnect(IMG_HANDLE hPerProc, -+ PRESMAN_CONTEXT *phResManContext); -+IMG_VOID PVRSRVResManDisconnect(PRESMAN_CONTEXT hResManContext, -+ IMG_BOOL bKernelContext); -+ -+#if defined (__cplusplus) -+} -+#endif -+ -+#endif /* __RESMAN_H__ */ -+ -+/****************************************************************************** -+ End of file (resman.h) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/include/services_headers.h b/drivers/staging/ti-es8-sgx/services4/srvkm/include/services_headers.h -new file mode 100644 -index 0000000..d369f02 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/include/services_headers.h -@@ -0,0 +1,67 @@ -+/*************************************************************************/ /*! -+@Title Command queues and synchronisation -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Internal structures and definitions for command queues and -+ synchronisation -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+ -+#ifndef SERVICES_HEADERS_H -+#define SERVICES_HEADERS_H -+ -+#ifdef DEBUG_RELEASE_BUILD -+#pragma optimize( "", off ) -+#define DEBUG 1 -+#endif -+ -+#include "img_defs.h" -+#include "services.h" -+#include "servicesint.h" -+#include "power.h" -+#include "resman.h" -+#include "queue.h" -+#include "srvkm.h" -+#include "kerneldisplay.h" -+#include "syscommon.h" -+#include "pvr_debug.h" -+#include "metrics.h" -+#include "osfunc.h" -+#include "refcount.h" -+ -+#endif /* SERVICES_HEADERS_H */ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/include/srvkm.h b/drivers/staging/ti-es8-sgx/services4/srvkm/include/srvkm.h -new file mode 100644 -index 0000000..b59a628 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/include/srvkm.h -@@ -0,0 +1,129 @@ -+/*************************************************************************/ /*! -+@Title Services kernel module internal header file -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#ifndef SRVKM_H -+#define SRVKM_H -+ -+ -+#if defined(__cplusplus) -+extern "C" { -+#endif -+ -+ /** Use PVR_DPF() unless message is necessary in release build -+ */ -+ #ifdef PVR_DISABLE_LOGGING -+ #define PVR_LOG(X) -+ #else -+ /* PRQA S 3410 1 */ /* this macro requires no brackets in order to work */ -+ #define PVR_LOG(X) PVRSRVReleasePrintf X; -+ #endif -+ -+ IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVReleasePrintf(const IMG_CHAR *pszFormat, ...) IMG_FORMAT_PRINTF(1, 2); -+ -+ IMG_IMPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVProcessConnect(IMG_UINT32 ui32PID, IMG_UINT32 ui32Flags); -+ IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVProcessDisconnect(IMG_UINT32 ui32PID); -+ -+ IMG_IMPORT IMG_VOID PVRSRVScheduleDevicesKM(IMG_VOID); -+ -+ IMG_VOID IMG_CALLCONV PVRSRVSetDCState(IMG_UINT32 ui32State); -+ -+ PVRSRV_ERROR IMG_CALLCONV PVRSRVSaveRestoreLiveSegments(IMG_HANDLE hArena, IMG_PBYTE pbyBuffer, IMG_SIZE_T *puiBufSize, IMG_BOOL bSave); -+ -+ IMG_VOID PVRSRVScheduleDeviceCallbacks(IMG_VOID); -+ -+ -+#if defined (__cplusplus) -+} -+#endif -+ -+/****************** -+HIGHER LEVEL MACROS -+*******************/ -+ -+/*---------------------------------------------------------------------------- -+Repeats the body of the loop for a certain minimum time, or until the body -+exits by its own means (break, return, goto, etc.) -+ -+Example of usage: -+ -+LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) -+{ -+ if(psQueueInfo->ui32ReadOffset == psQueueInfo->ui32WriteOffset) -+ { -+ bTimeout = IMG_FALSE; -+ break; -+ } -+ -+ OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT); -+} END_LOOP_UNTIL_TIMEOUT(); -+ -+-----------------------------------------------------------------------------*/ -+ -+/* uiNotLastLoop will remain at 1 until the timeout has expired, at which time -+ * it will be decremented and the loop executed one final time. This is necessary -+ * when preemption is enabled. -+ */ -+/* PRQA S 3411,3431 12 */ /* critical format, leave alone */ -+#define LOOP_UNTIL_TIMEOUT(TIMEOUT) \ -+{\ -+ IMG_UINT32 uiOffset, uiStart, uiCurrent; \ -+ IMG_INT32 iNotLastLoop; \ -+ for(uiOffset = 0, uiStart = OSClockus(), uiCurrent = uiStart + 1, iNotLastLoop = 1;\ -+ ((uiCurrent - uiStart + uiOffset) < (TIMEOUT)) || iNotLastLoop--; \ -+ uiCurrent = OSClockus(), \ -+ uiOffset = uiCurrent < uiStart ? IMG_UINT32_MAX - uiStart : uiOffset, \ -+ uiStart = uiCurrent < uiStart ? 0 : uiStart) -+ -+#define END_LOOP_UNTIL_TIMEOUT() \ -+} -+ -+/*! -+ ****************************************************************************** -+ -+ @Function PVRSRVGetErrorStringKM -+ -+ @Description Returns a text string relating to the PVRSRV_ERROR enum. -+ -+ ******************************************************************************/ -+IMG_IMPORT -+const IMG_CHAR *PVRSRVGetErrorStringKM(PVRSRV_ERROR eError); -+ -+#endif /* SRVKM_H */ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/include/ttrace.h b/drivers/staging/ti-es8-sgx/services4/srvkm/include/ttrace.h -new file mode 100644 -index 0000000..cb70ff8 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/include/ttrace.h -@@ -0,0 +1,200 @@ -+/*************************************************************************/ /*! -+@Title Timed Trace header -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Timed Trace header. Contines structures and functions used -+ in the timed trace subsystem. -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+#include "services_headers.h" -+#include "ttrace_common.h" -+#include "ttrace_tokens.h" -+ -+#ifndef __TTRACE_H__ -+#define __TTRACE_H__ -+ -+#if defined(TTRACE) -+ -+ #define PVR_TTRACE(group, class, token) \ -+ PVRSRVTimeTrace(group, class, token) -+ #define PVR_TTRACE_UI8(group, class, token, val) \ -+ PVRSRVTimeTraceUI8(group, class, token, val) -+ #define PVR_TTRACE_UI16(group, class, token, val) \ -+ PVRSRVTimeTraceUI16(group, class, token, val) -+ #define PVR_TTRACE_UI32(group, class, token, val) \ -+ PVRSRVTimeTraceUI32(group, class, token, val) -+ #define PVR_TTRACE_UI64(group, class, token, val) \ -+ PVRSRVTimeTraceUI64(group, class, token, val) -+ #define PVR_TTRACE_DEV_VIRTADDR(group, class, token, val) \ -+ PVRSRVTimeTraceDevVirtAddr(group, class, token, val) -+ #define PVR_TTRACE_CPU_PHYADDR(group, class, token, val) \ -+ PVRSRVTimeTraceCpuPhyAddr(group, class, token, val) -+ #define PVR_TTRACE_DEV_PHYADDR(group, class, token, val) \ -+ PVRSRVTimeTraceDevPhysAddr(group, class, token, val) -+ #define PVR_TTRACE_SYS_PHYADDR(group, class, token, val) \ -+ PVRSRVTimeTraceSysPhysAddr(group, class, token, val) -+ #define PVR_TTRACE_SYNC_OBJECT(group, token, syncobj, op) \ -+ PVRSRVTimeTraceSyncObject(group, token, syncobj, op) -+ -+IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVTimeTraceArray(IMG_UINT32 ui32Group, IMG_UINT32 ui32Class, -+ IMG_UINT32 ui32Token, IMG_UINT32 ui32TypeSize, -+ IMG_UINT32 ui32Count, IMG_UINT8 *ui8Data); -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(PVRSRVTimeTrace) -+#endif -+static INLINE IMG_VOID PVRSRVTimeTrace(IMG_UINT32 ui32Group, IMG_UINT32 ui32Class, -+ IMG_UINT32 ui32Token) -+{ -+ PVRSRVTimeTraceArray(ui32Group, ui32Class, ui32Token, 0, 0, NULL); -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(PVRSRVTimeTraceUI8) -+#endif -+static INLINE IMG_VOID PVRSRVTimeTraceUI8(IMG_UINT32 ui32Group, IMG_UINT32 ui32Class, -+ IMG_UINT32 ui32Token, IMG_UINT8 ui8Value) -+{ -+ PVRSRVTimeTraceArray(ui32Group, ui32Class, ui32Token, PVRSRV_TRACE_TYPE_UI8, -+ 1, &ui8Value); -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(PVRSRVTimeTraceUI16) -+#endif -+static INLINE IMG_VOID PVRSRVTimeTraceUI16(IMG_UINT32 ui32Group, IMG_UINT32 ui32Class, -+ IMG_UINT32 ui32Token, IMG_UINT16 ui16Value) -+{ -+ PVRSRVTimeTraceArray(ui32Group, ui32Class, ui32Token, PVRSRV_TRACE_TYPE_UI16, -+ 1, (IMG_UINT8 *) &ui16Value); -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(PVRSRVTimeTraceUI32) -+#endif -+static INLINE IMG_VOID PVRSRVTimeTraceUI32(IMG_UINT32 ui32Group, IMG_UINT32 ui32Class, -+ IMG_UINT32 ui32Token, IMG_UINT32 ui32Value) -+{ -+ PVRSRVTimeTraceArray(ui32Group, ui32Class, ui32Token, PVRSRV_TRACE_TYPE_UI32, -+ 1, (IMG_UINT8 *) &ui32Value); -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(PVRSRVTimeTraceUI64) -+#endif -+static INLINE IMG_VOID PVRSRVTimeTraceUI64(IMG_UINT32 ui32Group, IMG_UINT32 ui32Class, -+ IMG_UINT32 ui32Token, IMG_UINT64 ui64Value) -+{ -+ PVRSRVTimeTraceArray(ui32Group, ui32Class, ui32Token, PVRSRV_TRACE_TYPE_UI64, -+ 1, (IMG_UINT8 *) &ui64Value); -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(PVRSRVTimeTraceDevVirtAddr) -+#endif -+static INLINE IMG_VOID PVRSRVTimeTraceDevVirtAddr(IMG_UINT32 ui32Group, IMG_UINT32 ui32Class, -+ IMG_UINT32 ui32Token, IMG_DEV_VIRTADDR psVAddr) -+{ -+ PVRSRVTimeTraceArray(ui32Group, ui32Class, ui32Token, PVRSRV_TRACE_TYPE_UI32, -+ 1, (IMG_UINT8 *) &psVAddr.uiAddr); -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(PVRSRVTimeTraceCpuPhyAddr) -+#endif -+static INLINE IMG_VOID PVRSRVTimeTraceCpuPhyAddr(IMG_UINT32 ui32Group, IMG_UINT32 ui32Class, -+ IMG_UINT32 ui32Token, IMG_CPU_PHYADDR psPAddr) -+{ -+ PVRSRVTimeTraceArray(ui32Group, ui32Class, ui32Token, PVRSRV_TRACE_TYPE_UI32, -+ 1, (IMG_UINT8 *) &psPAddr.uiAddr); -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(PVRSRVTimeTraceDevPhysAddr) -+#endif -+static INLINE IMG_VOID PVRSRVTimeTraceDevPhysAddr(IMG_UINT32 ui32Group, IMG_UINT32 ui32Class, -+ IMG_UINT32 ui32Token, IMG_DEV_PHYADDR psPAddr) -+{ -+ PVRSRVTimeTraceArray(ui32Group, ui32Class, ui32Token, PVRSRV_TRACE_TYPE_UI32, -+ 1, (IMG_UINT8 *) &psPAddr.uiAddr); -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(PVRSRVTimeTraceSysPhysAddr) -+#endif -+static INLINE IMG_VOID PVRSRVTimeTraceSysPhysAddr(IMG_UINT32 ui32Group, IMG_UINT32 ui32Class, -+ IMG_UINT32 ui32Token, IMG_SYS_PHYADDR psPAddr) -+{ -+ PVRSRVTimeTraceArray(ui32Group, ui32Class, ui32Token, sizeof(psPAddr.uiAddr), -+ 1, (IMG_UINT8 *) &psPAddr.uiAddr); -+} -+ -+#else /* defined(PVRSRV_NEED_PVR_TIME_TRACE) */ -+ -+ #define PVR_TTRACE(group, class, token) \ -+ ((void) 0) -+ #define PVR_TTRACE_UI8(group, class, token, val) \ -+ ((void) 0) -+ #define PVR_TTRACE_UI16(group, class, token, val) \ -+ ((void) 0) -+ #define PVR_TTRACE_UI32(group, class, token, val) \ -+ ((void) 0) -+ #define PVR_TTRACE_UI64(group, class, token, val) \ -+ ((void) 0) -+ #define PVR_TTRACE_DEV_VIRTADDR(group, class, token, val) \ -+ ((void) 0) -+ #define PVR_TTRACE_CPU_PHYADDR(group, class, token, val) \ -+ ((void) 0) -+ #define PVR_TTRACE_DEV_PHYADDR(group, class, token, val) \ -+ ((void) 0) -+ #define PVR_TTRACE_SYS_PHYADDR(group, class, token, val) \ -+ ((void) 0) -+ #define PVR_TTRACE_SYNC_OBJECT(group, token, syncobj, op) \ -+ ((void) 0) -+ -+#endif /* defined(PVRSRV_NEED_PVR_TIME_TRACE) */ -+ -+IMG_IMPORT PVRSRV_ERROR PVRSRVTimeTraceInit(IMG_VOID); -+IMG_IMPORT IMG_VOID PVRSRVTimeTraceDeinit(IMG_VOID); -+ -+IMG_IMPORT IMG_VOID PVRSRVTimeTraceSyncObject(IMG_UINT32 ui32Group, IMG_UINT32 ui32Token, -+ PVRSRV_KERNEL_SYNC_INFO *psSync, IMG_UINT8 ui8SyncOp); -+IMG_IMPORT PVRSRV_ERROR PVRSRVTimeTraceBufferCreate(IMG_UINT32 ui32PID); -+IMG_IMPORT PVRSRV_ERROR PVRSRVTimeTraceBufferDestroy(IMG_UINT32 ui32PID); -+ -+IMG_IMPORT IMG_VOID PVRSRVDumpTimeTraceBuffers(IMG_VOID); -+#endif /* __TTRACE_H__ */ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/include/ttrace_common.h b/drivers/staging/ti-es8-sgx/services4/srvkm/include/ttrace_common.h -new file mode 100644 -index 0000000..1fde07d ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/include/ttrace_common.h -@@ -0,0 +1,146 @@ -+/*************************************************************************/ /*! -+@Title Timed Trace header -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Timed Trace common header. Contains shared defines and -+ structures which are shared with the post processing tool. -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+#include "img_types.h" -+ -+#ifndef __TTRACE_COMMON_H__ -+#define __TTRACE_COMMON_H__ -+ -+/* -+ * Trace item -+ * ========== -+ * -+ * A trace item contains a trace header, a timestamp, a UID and a -+ * data header all of which are 32-bit and mandatory. If there -+ * is no data then the data header size is set to 0. -+ * -+ * Trace header -+ * ------------ -+ * 31 27 23 19 15 11 7 3 -+ * GGGG GGGG CCCC CCCC TTTT TTTT TTTT TTTT -+ * -+ * G = group -+ * Note: -+ * Group 0xff means the message is padding -+ * -+ * C = class -+ * T = Token -+ * -+ * Data header -+ *----------- -+ * 31 27 23 19 15 11 7 3 -+ * SSSS SSSS SSSS SSSS TTTT CCCC CCCC CCCC -+ * -+ * S = data packet size -+ * T = Type -+ * 0000 - 8 bit -+ * 0001 - 16 bit -+ * 0010 - 32 bit -+ * 0011 - 64 bit -+ * -+ * C = data item count -+ * -+ * Note: It might look strange having both the packet -+ * size and the data item count, but the idea -+ * is the you might have a "special" data type -+ * who's size might not be known by the post -+ * processing program and rather then fail -+ * processing the buffer after that point if we -+ * know the size we can just skip it and move to -+ * the next item. -+ */ -+ -+ -+#define PVRSRV_TRACE_HEADER 0 -+#define PVRSRV_TRACE_TIMESTAMP 1 -+#define PVRSRV_TRACE_HOSTUID 2 -+#define PVRSRV_TRACE_DATA_HEADER 3 -+#define PVRSRV_TRACE_DATA_PAYLOAD 4 -+ -+#define PVRSRV_TRACE_ITEM_SIZE 16 -+ -+#define PVRSRV_TRACE_GROUP_MASK 0xff -+#define PVRSRV_TRACE_CLASS_MASK 0xff -+#define PVRSRV_TRACE_TOKEN_MASK 0xffff -+ -+#define PVRSRV_TRACE_GROUP_SHIFT 24 -+#define PVRSRV_TRACE_CLASS_SHIFT 16 -+#define PVRSRV_TRACE_TOKEN_SHIFT 0 -+ -+#define PVRSRV_TRACE_SIZE_MASK 0xffff -+#define PVRSRV_TRACE_TYPE_MASK 0xf -+#define PVRSRV_TRACE_COUNT_MASK 0xfff -+ -+#define PVRSRV_TRACE_SIZE_SHIFT 16 -+#define PVRSRV_TRACE_TYPE_SHIFT 12 -+#define PVRSRV_TRACE_COUNT_SHIFT 0 -+ -+ -+#define WRITE_HEADER(n,m) \ -+ ((m & PVRSRV_TRACE_##n##_MASK) << PVRSRV_TRACE_##n##_SHIFT) -+ -+#define READ_HEADER(n,m) \ -+ ((m & (PVRSRV_TRACE_##n##_MASK << PVRSRV_TRACE_##n##_SHIFT)) >> PVRSRV_TRACE_##n##_SHIFT) -+ -+#define TIME_TRACE_BUFFER_SIZE 4096 -+ -+/* Type defines for trace items */ -+#define PVRSRV_TRACE_TYPE_UI8 0 -+#define PVRSRV_TRACE_TYPE_UI16 1 -+#define PVRSRV_TRACE_TYPE_UI32 2 -+#define PVRSRV_TRACE_TYPE_UI64 3 -+ -+#define PVRSRV_TRACE_TYPE_SYNC 15 -+ #define PVRSRV_TRACE_SYNC_UID 0 -+ #define PVRSRV_TRACE_SYNC_WOP 1 -+ #define PVRSRV_TRACE_SYNC_WOC 2 -+ #define PVRSRV_TRACE_SYNC_ROP 3 -+ #define PVRSRV_TRACE_SYNC_ROC 4 -+ #define PVRSRV_TRACE_SYNC_WO_DEV_VADDR 5 -+ #define PVRSRV_TRACE_SYNC_RO_DEV_VADDR 6 -+ #define PVRSRV_TRACE_SYNC_OP 7 -+ #define PVRSRV_TRACE_SYNC_RO2P 8 -+ #define PVRSRV_TRACE_SYNC_RO2C 9 -+ #define PVRSRV_TRACE_SYNC_RO2_DEV_VADDR 10 -+#define PVRSRV_TRACE_TYPE_SYNC_SIZE ((PVRSRV_TRACE_SYNC_RO2_DEV_VADDR + 1) * sizeof(IMG_UINT32)) -+ -+#endif /* __TTRACE_COMMON_H__*/ -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/include/ttrace_tokens.h b/drivers/staging/ti-es8-sgx/services4/srvkm/include/ttrace_tokens.h -new file mode 100644 -index 0000000..393ba08 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/include/ttrace_tokens.h -@@ -0,0 +1,119 @@ -+/*************************************************************************/ /*! -+@Title Timed Trace header -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Timed Trace token header. Contains defines for all the tokens -+ used. -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#ifndef __TTRACE_TOKENS_H__ -+#define __TTRACE_TOKENS_H__ -+ -+/* All defines should use decimal so to not confuse the post processing tool */ -+ -+/* Trace groups */ -+#define PVRSRV_TRACE_GROUP_KICK 0 -+#define PVRSRV_TRACE_GROUP_TRANSFER 1 -+#define PVRSRV_TRACE_GROUP_QUEUE 2 -+#define PVRSRV_TRACE_GROUP_POWER 3 -+#define PVRSRV_TRACE_GROUP_MKSYNC 4 -+ -+#define PVRSRV_TRACE_GROUP_PADDING 255 -+ -+/* Trace classes */ -+#define PVRSRV_TRACE_CLASS_FUNCTION_ENTER 0 -+#define PVRSRV_TRACE_CLASS_FUNCTION_EXIT 1 -+#define PVRSRV_TRACE_CLASS_SYNC 2 -+#define PVRSRV_TRACE_CLASS_CCB 3 -+#define PVRSRV_TRACE_CLASS_CMD_START 4 -+#define PVRSRV_TRACE_CLASS_CMD_END 5 -+#define PVRSRV_TRACE_CLASS_CMD_COMP_START 6 -+#define PVRSRV_TRACE_CLASS_CMD_COMP_END 7 -+#define PVRSRV_TRACE_CLASS_FLAGS 8 -+ -+#define PVRSRV_TRACE_CLASS_NONE 255 -+ -+/* Operation about to happen on the sync object */ -+#define PVRSRV_SYNCOP_SAMPLE 0 -+#define PVRSRV_SYNCOP_COMPLETE 1 -+#define PVRSRV_SYNCOP_DUMP 2 -+ -+/* -+ * Trace tokens -+ * ------------ -+ * These only need to unique within a group. -+ */ -+ -+/* Kick group tokens */ -+#define KICK_TOKEN_DOKICK 0 -+#define KICK_TOKEN_CCB_OFFSET 1 -+#define KICK_TOKEN_TA3D_SYNC 2 -+#define KICK_TOKEN_TA_SYNC 3 -+#define KICK_TOKEN_3D_SYNC 4 -+#define KICK_TOKEN_SRC_SYNC 5 -+#define KICK_TOKEN_DST_SYNC 6 -+#define KICK_TOKEN_FIRST_KICK 7 -+#define KICK_TOKEN_LAST_KICK 8 -+ -+/* Transfer Queue group tokens */ -+#define TRANSFER_TOKEN_SUBMIT 0 -+#define TRANSFER_TOKEN_TA_SYNC 1 -+#define TRANSFER_TOKEN_3D_SYNC 2 -+#define TRANSFER_TOKEN_SRC_SYNC 3 -+#define TRANSFER_TOKEN_DST_SYNC 4 -+#define TRANSFER_TOKEN_CCB_OFFSET 5 -+ -+/* Queue group tokens */ -+#define QUEUE_TOKEN_GET_SPACE 0 -+#define QUEUE_TOKEN_INSERTKM 1 -+#define QUEUE_TOKEN_SUBMITKM 2 -+#define QUEUE_TOKEN_PROCESS_COMMAND 3 -+#define QUEUE_TOKEN_PROCESS_QUEUES 4 -+#define QUEUE_TOKEN_COMMAND_COMPLETE 5 -+#define QUEUE_TOKEN_UPDATE_DST 6 -+#define QUEUE_TOKEN_UPDATE_SRC 7 -+#define QUEUE_TOKEN_SRC_SYNC 8 -+#define QUEUE_TOKEN_DST_SYNC 9 -+#define QUEUE_TOKEN_COMMAND_TYPE 10 -+ -+/* uKernel Sync tokens */ -+#define MKSYNC_TOKEN_KERNEL_CCB_OFFSET 0 -+#define MKSYNC_TOKEN_CORE_CLK 1 -+#define MKSYNC_TOKEN_UKERNEL_CLK 2 -+ -+#endif /* __TTRACE_TOKENS_H__ */ -diff --git a/drivers/staging/ti-es8-sgx/services4/system/include/syscommon.h b/drivers/staging/ti-es8-sgx/services4/system/include/syscommon.h -new file mode 100644 -index 0000000..94bc7a0 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/include/syscommon.h -@@ -0,0 +1,391 @@ -+/*************************************************************************/ /*! -+@Title Common System APIs and structures -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description This header provides common system-specific declarations and macros -+ that are supported by all system's -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#ifndef _SYSCOMMON_H -+#define _SYSCOMMON_H -+ -+#include "sysconfig.h" /* System specific system defines */ -+#include "sysinfo.h" /* globally accessible system info */ -+#include "servicesint.h" -+#include "queue.h" -+#include "power.h" -+#include "resman.h" -+#include "ra.h" -+#include "device.h" -+#include "buffer_manager.h" -+#include "pvr_debug.h" -+#include "services.h" -+ -+#if defined(NO_HARDWARE) && defined(__linux__) && defined(__KERNEL__) -+#include <asm/io.h> -+#endif -+ -+#if defined (__cplusplus) -+extern "C" { -+#endif -+ -+/*! -+ **************************************************************************** -+ device id management structure -+ ****************************************************************************/ -+typedef struct _SYS_DEVICE_ID_TAG -+{ -+ IMG_UINT32 uiID; -+ IMG_BOOL bInUse; -+ -+} SYS_DEVICE_ID; -+ -+ -+/* -+ the max number of independent local backing stores services supports -+ (grow this number if ever required) -+*/ -+#define SYS_MAX_LOCAL_DEVMEM_ARENAS 4 -+ -+typedef IMG_HANDLE (*PFN_HTIMER_CREATE) (IMG_VOID); -+typedef IMG_UINT32 (*PFN_HTIMER_GETUS) (IMG_HANDLE); -+typedef IMG_VOID (*PFN_HTIMER_DESTROY) (IMG_HANDLE); -+/*! -+ **************************************************************************** -+ Top level system data structure -+ ****************************************************************************/ -+typedef struct _SYS_DATA_TAG_ -+{ -+ IMG_UINT32 ui32NumDevices; /*!< number of devices in system */ -+ SYS_DEVICE_ID sDeviceID[SYS_DEVICE_COUNT]; -+ PVRSRV_DEVICE_NODE *psDeviceNodeList; /*!< list of private device info structures */ -+ PVRSRV_POWER_DEV *psPowerDeviceList; /*!< list of devices registered with the power manager */ -+ PVRSRV_RESOURCE sPowerStateChangeResource; /*!< lock for power state transitions */ -+ PVRSRV_SYS_POWER_STATE eCurrentPowerState; /*!< current Kernel services power state */ -+ PVRSRV_SYS_POWER_STATE eFailedPowerState; /*!< Kernel services power state (Failed to transition to) */ -+ IMG_UINT32 ui32CurrentOSPowerState; /*!< current OS specific power state */ -+ PVRSRV_QUEUE_INFO *psQueueList; /*!< list of all command queues in the system */ -+ PVRSRV_KERNEL_SYNC_INFO *psSharedSyncInfoList; /*!< list of cross process syncinfos */ -+ IMG_PVOID pvEnvSpecificData; /*!< Environment specific data */ -+ IMG_PVOID pvSysSpecificData; /*!< Unique to system, accessible at system layer only */ -+ PVRSRV_RESOURCE sQProcessResource; /*!< Command Q processing access lock */ -+ IMG_VOID *pvSOCRegsBase; /*!< SOC registers base linear address */ -+ IMG_HANDLE hSOCTimerRegisterOSMemHandle; /*!< SOC Timer register (if present) */ -+ IMG_UINT32 *pvSOCTimerRegisterKM; /*!< SOC Timer register (if present) */ -+ IMG_VOID *pvSOCClockGateRegsBase; /*!< SOC Clock gating registers (if present) */ -+ IMG_UINT32 ui32SOCClockGateRegsSize; -+ -+ struct _DEVICE_COMMAND_DATA_ *apsDeviceCommandData[SYS_DEVICE_COUNT]; -+ /*!< command complete data and callback function store for every command for every device */ -+ -+ RA_ARENA *apsLocalDevMemArena[SYS_MAX_LOCAL_DEVMEM_ARENAS]; /*!< RA Arenas for local device memory heap management */ -+ -+ IMG_CHAR *pszVersionString; /*!< Human readable string showing relevent system version info */ -+ PVRSRV_EVENTOBJECT *psGlobalEventObject; /*!< OS Global Event Object */ -+ -+ PVRSRV_MISC_INFO_CPUCACHEOP_TYPE ePendingCacheOpType; /*!< Deferred CPU cache op control */ -+ -+ PFN_HTIMER_CREATE pfnHighResTimerCreate; -+ PFN_HTIMER_GETUS pfnHighResTimerGetus; -+ PFN_HTIMER_DESTROY pfnHighResTimerDestroy; -+} SYS_DATA; -+ -+ -+/**************************************************************************** -+ * common function prototypes -+ ****************************************************************************/ -+ -+#if defined (CUSTOM_DISPLAY_SEGMENT) -+PVRSRV_ERROR SysGetDisplaySegmentAddress (IMG_VOID *pvDevInfo, IMG_VOID *pvPhysicalAddress, IMG_UINT32 *pui32Length); -+#endif -+ -+PVRSRV_ERROR SysInitialise(IMG_VOID); -+PVRSRV_ERROR SysFinalise(IMG_VOID); -+ -+PVRSRV_ERROR SysDeinitialise(SYS_DATA *psSysData); -+PVRSRV_ERROR SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE eDeviceType, -+ IMG_VOID **ppvDeviceMap); -+ -+IMG_VOID SysRegisterExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode); -+IMG_VOID SysRemoveExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode); -+ -+IMG_UINT32 SysGetInterruptSource(SYS_DATA *psSysData, -+ PVRSRV_DEVICE_NODE *psDeviceNode); -+ -+IMG_VOID SysClearInterrupts(SYS_DATA* psSysData, IMG_UINT32 ui32ClearBits); -+ -+PVRSRV_ERROR SysResetDevice(IMG_UINT32 ui32DeviceIndex); -+ -+PVRSRV_ERROR SysSystemPrePowerState(PVRSRV_SYS_POWER_STATE eNewPowerState); -+PVRSRV_ERROR SysSystemPostPowerState(PVRSRV_SYS_POWER_STATE eNewPowerState); -+PVRSRV_ERROR SysDevicePrePowerState(IMG_UINT32 ui32DeviceIndex, -+ PVRSRV_DEV_POWER_STATE eNewPowerState, -+ PVRSRV_DEV_POWER_STATE eCurrentPowerState); -+PVRSRV_ERROR SysDevicePostPowerState(IMG_UINT32 ui32DeviceIndex, -+ PVRSRV_DEV_POWER_STATE eNewPowerState, -+ PVRSRV_DEV_POWER_STATE eCurrentPowerState); -+ -+#if defined(SYS_SUPPORTS_SGX_IDLE_CALLBACK) -+IMG_VOID SysSGXIdleTransition(IMG_BOOL bSGXIdle); -+#endif /* SYS_SUPPORTS_SGX_IDLE_CALLBACK */ -+ -+#if defined(SYS_CUSTOM_POWERLOCK_WRAP) -+PVRSRV_ERROR SysPowerLockWrap(IMG_BOOL bTryLock); -+IMG_VOID SysPowerLockUnwrap(IMG_VOID); -+#endif -+ -+PVRSRV_ERROR SysOEMFunction ( IMG_UINT32 ui32ID, -+ IMG_VOID *pvIn, -+ IMG_UINT32 ulInSize, -+ IMG_VOID *pvOut, -+ IMG_UINT32 ulOutSize); -+ -+ -+IMG_DEV_PHYADDR SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE eDeviceType, IMG_CPU_PHYADDR cpu_paddr); -+IMG_DEV_PHYADDR SysSysPAddrToDevPAddr (PVRSRV_DEVICE_TYPE eDeviceType, IMG_SYS_PHYADDR SysPAddr); -+IMG_SYS_PHYADDR SysDevPAddrToSysPAddr (PVRSRV_DEVICE_TYPE eDeviceType, IMG_DEV_PHYADDR SysPAddr); -+IMG_CPU_PHYADDR SysSysPAddrToCpuPAddr (IMG_SYS_PHYADDR SysPAddr); -+IMG_SYS_PHYADDR SysCpuPAddrToSysPAddr (IMG_CPU_PHYADDR cpu_paddr); -+#if defined(PVR_LMA) -+IMG_BOOL SysVerifyCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE eDeviceType, IMG_CPU_PHYADDR CpuPAddr); -+IMG_BOOL SysVerifySysPAddrToDevPAddr (PVRSRV_DEVICE_TYPE eDeviceType, IMG_SYS_PHYADDR SysPAddr); -+#endif -+ -+extern SYS_DATA* gpsSysData; -+ -+ -+#if !defined(USE_CODE) -+ -+/*! -+****************************************************************************** -+ -+ @Function SysAcquireData -+ -+ @Description returns reference to to sysdata -+ creating one on first call -+ -+ @Input ppsSysData - pointer to copy reference into -+ -+ @Return ppsSysData updated -+ -+******************************************************************************/ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(SysAcquireData) -+#endif -+static INLINE IMG_VOID SysAcquireData(SYS_DATA **ppsSysData) -+{ -+ /* Copy pointer back system information pointer */ -+ *ppsSysData = gpsSysData; -+ -+ /* -+ Verify we've not been called before being initialised. Instinctively -+ we should do this check first, but in the failing case we'll just write -+ null back and the compiler won't warn about an uninitialised varible. -+ */ -+ PVR_ASSERT (gpsSysData != IMG_NULL); -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysAcquireDataNoCheck -+ -+ @Description returns reference to to sysdata -+ creating one on first call -+ -+ @Input none -+ -+ @Return psSysData - pointer to copy reference into -+ -+******************************************************************************/ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(SysAcquireDataNoCheck) -+#endif -+static INLINE SYS_DATA * SysAcquireDataNoCheck(IMG_VOID) -+{ -+ /* return pointer back system information pointer */ -+ return gpsSysData; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysInitialiseCommon -+ -+ @Description Performs system initialisation common to all systems -+ -+ @Input psSysData - pointer to system data -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(SysInitialiseCommon) -+#endif -+static INLINE PVRSRV_ERROR SysInitialiseCommon(SYS_DATA *psSysData) -+{ -+ PVRSRV_ERROR eError; -+ -+ /* Initialise Services */ -+ eError = PVRSRVInit(psSysData); -+ -+ return eError; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function SysDeinitialiseCommon -+ -+ @Description Performs system deinitialisation common to all systems -+ -+ @Input psSysData - pointer to system data -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(SysDeinitialiseCommon) -+#endif -+static INLINE IMG_VOID SysDeinitialiseCommon(SYS_DATA *psSysData) -+{ -+ /* De-initialise Services */ -+ PVRSRVDeInit(psSysData); -+ -+ OSDestroyResource(&psSysData->sPowerStateChangeResource); -+} -+#endif /* !defined(USE_CODE) */ -+ -+ -+/* -+ * SysReadHWReg and SysWriteHWReg differ from OSReadHWReg and OSWriteHWReg -+ * in that they are always intended for use with real hardware, even on -+ * NO_HARDWARE systems. -+ */ -+#if !(defined(NO_HARDWARE) && defined(__linux__) && defined(__KERNEL__)) -+#define SysReadHWReg(p, o) OSReadHWReg(p, o) -+#define SysWriteHWReg(p, o, v) OSWriteHWReg(p, o, v) -+#else /* !(defined(NO_HARDWARE) && defined(__linux__)) */ -+/*! -+****************************************************************************** -+ -+ @Function SysReadHWReg -+ -+ @Description -+ -+ register read function -+ -+ @input pvLinRegBaseAddr : lin addr of register block base -+ -+ @input ui32Offset : -+ -+ @Return register value -+ -+******************************************************************************/ -+static inline IMG_UINT32 SysReadHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset) -+{ -+ return (IMG_UINT32) readl(pvLinRegBaseAddr + ui32Offset); -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function SysWriteHWReg -+ -+ @Description -+ -+ register write function -+ -+ @input pvLinRegBaseAddr : lin addr of register block base -+ -+ @input ui32Offset : -+ -+ @input ui32Value : -+ -+ @Return none -+ -+******************************************************************************/ -+static inline IMG_VOID SysWriteHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value) -+{ -+ writel(ui32Value, pvLinRegBaseAddr + ui32Offset); -+} -+#endif /* !(defined(NO_HARDWARE) && defined(__linux__)) */ -+ -+#if defined(__cplusplus) -+} -+#endif -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(SysHighResTimerCreate) -+#endif -+static INLINE IMG_HANDLE SysHighResTimerCreate(IMG_VOID) -+{ -+ SYS_DATA *psSysData; -+ -+ SysAcquireData(&psSysData); -+ return psSysData->pfnHighResTimerCreate(); -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(SysHighResTimerGetus) -+#endif -+static INLINE IMG_UINT32 SysHighResTimerGetus(IMG_HANDLE hTimer) -+{ -+ SYS_DATA *psSysData; -+ -+ SysAcquireData(&psSysData); -+ return psSysData->pfnHighResTimerGetus(hTimer); -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(SysHighResTimerDestroy) -+#endif -+static INLINE IMG_VOID SysHighResTimerDestroy(IMG_HANDLE hTimer) -+{ -+ SYS_DATA *psSysData; -+ -+ SysAcquireData(&psSysData); -+ psSysData->pfnHighResTimerDestroy(hTimer); -+} -+#endif -+ -+/***************************************************************************** -+ End of file (syscommon.h) -+*****************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/system/omap/oemfuncs.h b/drivers/staging/ti-es8-sgx/services4/system/omap/oemfuncs.h -new file mode 100644 -index 0000000..77c70d6 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/omap/oemfuncs.h -@@ -0,0 +1,78 @@ -+/*************************************************************************/ /*! -+@Title SGX kernel/client driver interface structures and prototypes -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#if !defined(__OEMFUNCS_H__) -+#define __OEMFUNCS_H__ -+ -+#if defined (__cplusplus) -+extern "C" { -+#endif -+ -+/* function in/out data structures: */ -+typedef IMG_UINT32 (*PFN_SRV_BRIDGEDISPATCH)( IMG_UINT32 Ioctl, -+ IMG_BYTE *pInBuf, -+ IMG_UINT32 InBufLen, -+ IMG_BYTE *pOutBuf, -+ IMG_UINT32 OutBufLen, -+ IMG_UINT32 *pdwBytesTransferred); -+/* -+ Function table for kernel 3rd party driver to kernel services -+*/ -+typedef struct PVRSRV_DC_OEM_JTABLE_TAG -+{ -+ PFN_SRV_BRIDGEDISPATCH pfnOEMBridgeDispatch; -+ IMG_PVOID pvDummy1; -+ IMG_PVOID pvDummy2; -+ IMG_PVOID pvDummy3; -+ -+} PVRSRV_DC_OEM_JTABLE; -+ -+#define OEM_GET_EXT_FUNCS (1<<1) -+ -+#if defined(__cplusplus) -+} -+#endif -+ -+#endif /* __OEMFUNCS_H__ */ -+ -+/***************************************************************************** -+ End of file (oemfuncs.h) -+*****************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/system/omap/sysconfig.c b/drivers/staging/ti-es8-sgx/services4/system/omap/sysconfig.c -new file mode 100644 -index 0000000..c7ae511 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/omap/sysconfig.c -@@ -0,0 +1,1274 @@ -+/*************************************************************************/ /*! -+@Title System Configuration -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description System Configuration functions -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#include "sysconfig.h" -+#include "services_headers.h" -+#include "kerneldisplay.h" -+#include "oemfuncs.h" -+#include "sgxinfo.h" -+#include "sgxinfokm.h" -+#include "syslocal.h" -+ -+#include "ocpdefs.h" -+ -+/* top level system data anchor point*/ -+SYS_DATA* gpsSysData = (SYS_DATA*)IMG_NULL; -+SYS_DATA gsSysData; -+ -+static SYS_SPECIFIC_DATA gsSysSpecificData; -+SYS_SPECIFIC_DATA *gpsSysSpecificData; -+ -+/* SGX structures */ -+static IMG_UINT32 gui32SGXDeviceID; -+static SGX_DEVICE_MAP gsSGXDeviceMap; -+static PVRSRV_DEVICE_NODE *gpsSGXDevNode; -+ -+ -+#if defined(NO_HARDWARE) || defined(SGX_OCP_REGS_ENABLED) -+static IMG_CPU_VIRTADDR gsSGXRegsCPUVAddr; -+#endif -+ -+#if defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO) -+extern struct platform_device *gpsPVRLDMDev; -+#endif -+ -+IMG_UINT32 PVRSRV_BridgeDispatchKM(IMG_UINT32 Ioctl, -+ IMG_BYTE *pInBuf, -+ IMG_UINT32 InBufLen, -+ IMG_BYTE *pOutBuf, -+ IMG_UINT32 OutBufLen, -+ IMG_UINT32 *pdwBytesTransferred); -+ -+#if defined(SGX_OCP_REGS_ENABLED) -+ -+static IMG_CPU_VIRTADDR gpvOCPRegsLinAddr; -+ -+static PVRSRV_ERROR EnableSGXClocksWrap(SYS_DATA *psSysData) -+{ -+ PVRSRV_ERROR eError = EnableSGXClocks(psSysData); -+ -+#if !defined(SGX_OCP_NO_INT_BYPASS) -+ if(eError == PVRSRV_OK) -+ { -+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_SYSCONFIG, 0x14); -+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_DEBUG_CONFIG, EUR_CR_OCP_DEBUG_CONFIG_THALIA_INT_BYPASS_MASK); -+ } -+#endif -+ return eError; -+} -+ -+#else /* defined(SGX_OCP_REGS_ENABLED) */ -+ -+static INLINE PVRSRV_ERROR EnableSGXClocksWrap(SYS_DATA *psSysData) -+{ -+ return EnableSGXClocks(psSysData); -+} -+ -+#endif /* defined(SGX_OCP_REGS_ENABLED) */ -+ -+static INLINE PVRSRV_ERROR EnableSystemClocksWrap(SYS_DATA *psSysData) -+{ -+ PVRSRV_ERROR eError = EnableSystemClocks(psSysData); -+ -+#if !defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ if(eError == PVRSRV_OK) -+ { -+ /* -+ * The SGX Clocks are enabled separately if active power -+ * management is enabled. -+ */ -+ eError = EnableSGXClocksWrap(psSysData); -+ if (eError != PVRSRV_OK) -+ { -+ DisableSystemClocks(psSysData); -+ } -+ } -+#endif -+ -+ return eError; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function SysLocateDevices -+ -+ @Description Specifies devices in the systems memory map -+ -+ @Input psSysData - sys data -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+static PVRSRV_ERROR SysLocateDevices(SYS_DATA *psSysData) -+{ -+#if defined(NO_HARDWARE) -+ PVRSRV_ERROR eError; -+ IMG_CPU_PHYADDR sCpuPAddr; -+#else -+#if defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO) -+ struct resource *dev_res; -+ int dev_irq; -+#endif -+#endif -+ -+ PVR_UNREFERENCED_PARAMETER(psSysData); -+ -+ /* SGX Device: */ -+ gsSGXDeviceMap.ui32Flags = 0x0; -+ -+#if defined(NO_HARDWARE) -+ /* -+ * For no hardware, allocate some contiguous memory for the -+ * register block. -+ */ -+ -+ /* Registers */ -+ gsSGXDeviceMap.ui32RegsSize = SYS_OMAP_SGX_REGS_SIZE; -+ -+ eError = OSBaseAllocContigMemory(gsSGXDeviceMap.ui32RegsSize, -+ &gsSGXRegsCPUVAddr, -+ &sCpuPAddr); -+ if(eError != PVRSRV_OK) -+ { -+ return eError; -+ } -+ gsSGXDeviceMap.sRegsCpuPBase = sCpuPAddr; -+ gsSGXDeviceMap.sRegsSysPBase = SysCpuPAddrToSysPAddr(gsSGXDeviceMap.sRegsCpuPBase); -+#if defined(__linux__) -+ /* Indicate the registers are already mapped */ -+ gsSGXDeviceMap.pvRegsCpuVBase = gsSGXRegsCPUVAddr; -+#else -+ /* -+ * FIXME: Could we just use the virtual address returned by -+ * OSBaseAllocContigMemory? -+ */ -+ gsSGXDeviceMap.pvRegsCpuVBase = IMG_NULL; -+#endif -+ -+ OSMemSet(gsSGXRegsCPUVAddr, 0, gsSGXDeviceMap.ui32RegsSize); -+ -+ /* -+ device interrupt IRQ -+ Note: no interrupts available on no hardware system -+ */ -+ gsSGXDeviceMap.ui32IRQ = 0; -+ -+#else /* defined(NO_HARDWARE) */ -+#if defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO) -+ /* get the resource and IRQ through platform resource API */ -+ dev_res = platform_get_resource(gpsPVRLDMDev, IORESOURCE_MEM, 0); -+ if (dev_res == NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: platform_get_resource failed", __FUNCTION__)); -+ return PVRSRV_ERROR_INVALID_DEVICE; -+ } -+ -+ dev_irq = platform_get_irq(gpsPVRLDMDev, 0); -+ if (dev_irq < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: platform_get_irq failed (%d)", __FUNCTION__, -dev_irq)); -+ return PVRSRV_ERROR_INVALID_DEVICE; -+ } -+ -+ gsSGXDeviceMap.sRegsSysPBase.uiAddr = dev_res->start; -+ gsSGXDeviceMap.sRegsCpuPBase = -+ SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sRegsSysPBase); -+ PVR_TRACE(("SGX register base: 0x%lx", (unsigned long)gsSGXDeviceMap.sRegsCpuPBase.uiAddr)); -+ -+#if defined(SGX544) && defined(SGX_FEATURE_MP) -+ /* FIXME: Workaround due to HWMOD change. Otherwise this region is too small. */ -+ gsSGXDeviceMap.ui32RegsSize = SYS_OMAP_SGX_REGS_SIZE; -+#else -+ gsSGXDeviceMap.ui32RegsSize = (unsigned int)(dev_res->end - dev_res->start); -+#endif -+ PVR_TRACE(("SGX register size: %d",gsSGXDeviceMap.ui32RegsSize)); -+ -+ gsSGXDeviceMap.ui32IRQ = dev_irq; -+ PVR_TRACE(("SGX IRQ: %d", gsSGXDeviceMap.ui32IRQ)); -+#else /* defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO) */ -+ gsSGXDeviceMap.sRegsSysPBase.uiAddr = SYS_OMAP_SGX_REGS_SYS_PHYS_BASE; -+ gsSGXDeviceMap.sRegsCpuPBase = SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sRegsSysPBase); -+ gsSGXDeviceMap.ui32RegsSize = SYS_OMAP_SGX_REGS_SIZE; -+ -+ gsSGXDeviceMap.ui32IRQ = SYS_OMAP_SGX_IRQ; -+ -+#endif /* defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO) */ -+#if defined(SGX_OCP_REGS_ENABLED) -+ gsSGXRegsCPUVAddr = OSMapPhysToLin(gsSGXDeviceMap.sRegsCpuPBase, -+ gsSGXDeviceMap.ui32RegsSize, -+ PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY, -+ IMG_NULL); -+ -+ if (gsSGXRegsCPUVAddr == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysLocateDevices: Failed to map SGX registers")); -+ return PVRSRV_ERROR_BAD_MAPPING; -+ } -+ -+ /* Indicate the registers are already mapped */ -+ gsSGXDeviceMap.pvRegsCpuVBase = gsSGXRegsCPUVAddr; -+ gpvOCPRegsLinAddr = gsSGXRegsCPUVAddr; -+#endif -+#endif /* defined(NO_HARDWARE) */ -+ -+#if defined(PDUMP) -+ { -+ /* initialise memory region name for pdumping */ -+ static IMG_CHAR pszPDumpDevName[] = "SGXMEM"; -+ gsSGXDeviceMap.pszPDumpDevName = pszPDumpDevName; -+ } -+#endif -+ -+ /* add other devices here: */ -+ -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysCreateVersionString -+ -+ @Description Read the version string -+ -+ @Return IMG_CHAR * : Version string -+ -+******************************************************************************/ -+static IMG_CHAR *SysCreateVersionString(void) -+{ -+ static IMG_CHAR aszVersionString[100]; -+ IMG_UINT32 ui32MaxStrLen; -+ SYS_DATA *psSysData; -+ IMG_UINT32 ui32SGXRevision; -+ IMG_INT32 i32Count; -+ -+ SysAcquireData(&psSysData); -+ -+ ui32SGXRevision = SGX_CORE_REV; -+ ui32MaxStrLen = 99; -+ -+ i32Count = OSSNPrintf(aszVersionString, ui32MaxStrLen + 1, -+ "SGX revision = %u", -+ (IMG_UINT)(ui32SGXRevision)); -+ if(i32Count == -1) -+ { -+ return IMG_NULL; -+ } -+ -+ return aszVersionString; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysInitialise -+ -+ @Description Initialises kernel services at 'driver load' time -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+PVRSRV_ERROR SysInitialise(IMG_VOID) -+{ -+ IMG_UINT32 i; -+ PVRSRV_ERROR eError; -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+#if !defined(PVR_NO_OMAP_TIMER) -+ IMG_CPU_PHYADDR TimerRegPhysBase; -+#endif -+#if !defined(SGX_DYNAMIC_TIMING_INFO) -+ SGX_TIMING_INFORMATION* psTimingInfo; -+#endif -+ gpsSysData = &gsSysData; -+ OSMemSet(gpsSysData, 0, sizeof(SYS_DATA)); -+ -+ gpsSysSpecificData = &gsSysSpecificData; -+ OSMemSet(gpsSysSpecificData, 0, sizeof(SYS_SPECIFIC_DATA)); -+ -+ gpsSysData->pvSysSpecificData = gpsSysSpecificData; -+ -+ eError = OSInitEnvData(&gpsSysData->pvEnvSpecificData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to setup env structure")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_ENVDATA); -+ -+ gpsSysData->ui32NumDevices = SYS_DEVICE_COUNT; -+ -+ /* init device ID's */ -+ for(i=0; i<SYS_DEVICE_COUNT; i++) -+ { -+ gpsSysData->sDeviceID[i].uiID = i; -+ gpsSysData->sDeviceID[i].bInUse = IMG_FALSE; -+ } -+ -+ gpsSysData->psDeviceNodeList = IMG_NULL; -+ gpsSysData->psQueueList = IMG_NULL; -+ -+ eError = SysInitialiseCommon(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed in SysInitialiseCommon")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ -+#if !defined(SGX_DYNAMIC_TIMING_INFO) -+ /* Set up timing information*/ -+ psTimingInfo = &gsSGXDeviceMap.sTimingInfo; -+ psTimingInfo->ui32CoreClockSpeed = SYS_SGX_CLOCK_SPEED; -+ psTimingInfo->ui32HWRecoveryFreq = SYS_SGX_HWRECOVERY_TIMEOUT_FREQ; -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ psTimingInfo->bEnableActivePM = IMG_TRUE; -+#else -+ psTimingInfo->bEnableActivePM = IMG_FALSE; -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ psTimingInfo->ui32ActivePowManLatencyms = SYS_SGX_ACTIVE_POWER_LATENCY_MS; -+ psTimingInfo->ui32uKernelFreq = SYS_SGX_PDS_TIMER_FREQ; -+#endif -+ -+ /* -+ Setup the Source Clock Divider value -+ */ -+ gpsSysSpecificData->ui32SrcClockDiv = 3; -+ -+ /* -+ Locate the devices within the system, specifying -+ the physical addresses of each devices components -+ (regs, mem, ports etc.) -+ */ -+ eError = SysLocateDevices(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to locate devices")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV); -+ -+ eError = SysPMRuntimeRegister(); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to register with OSPM!")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_PM_RUNTIME); -+ -+ eError = SysDvfsInitialize(gpsSysSpecificData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to initialize DVFS")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_DVFS_INIT); -+ -+ /* -+ Register devices with the system -+ This also sets up their memory maps/heaps -+ */ -+ eError = PVRSRVRegisterDevice(gpsSysData, SGXRegisterDevice, -+ DEVICE_SGX_INTERRUPT, &gui32SGXDeviceID); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to register device!")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_REGDEV); -+ -+ /* -+ Once all devices are registered, specify the backing store -+ and, if required, customise the memory heap config -+ */ -+ psDeviceNode = gpsSysData->psDeviceNodeList; -+ while(psDeviceNode) -+ { -+ /* perform any OEM SOC address space customisations here */ -+ switch(psDeviceNode->sDevId.eDeviceType) -+ { -+ case PVRSRV_DEVICE_TYPE_SGX: -+ { -+ DEVICE_MEMORY_INFO *psDevMemoryInfo; -+ DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; -+ -+ /* -+ specify the backing store to use for the devices MMU PT/PDs -+ - the PT/PDs are always UMA in this system -+ */ -+ psDeviceNode->psLocalDevMemArena = IMG_NULL; -+ -+ /* useful pointers */ -+ psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo; -+ psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap; -+ -+ /* specify the backing store for all SGX heaps */ -+ for(i=0; i<psDevMemoryInfo->ui32HeapCount; i++) -+ { -+ psDeviceMemoryHeap[i].ui32Attribs |= PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG; -+ } -+ -+ gpsSGXDevNode = psDeviceNode; -+ gsSysSpecificData.psSGXDevNode = psDeviceNode; -+ -+ break; -+ } -+ default: -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to find SGX device node!")); -+ return PVRSRV_ERROR_INIT_FAILURE; -+ } -+ -+ /* advance to next device */ -+ psDeviceNode = psDeviceNode->psNext; -+ } -+ -+ eError = EnableSystemClocksWrap(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable system clocks (%d)", eError)); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS); -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ eError = EnableSGXClocksWrap(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable SGX clocks (%d)", eError)); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ -+ eError = PVRSRVInitialiseDevice(gui32SGXDeviceID); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to initialise device!")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_INITDEV); -+ -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ /* SGX defaults to D3 power state */ -+ DisableSGXClocks(gpsSysData); -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ -+#if !defined(PVR_NO_OMAP_TIMER) -+#if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA) -+ TimerRegPhysBase = gsSysSpecificData.sTimerRegPhysBase; -+#else -+ TimerRegPhysBase.uiAddr = SYS_OMAP_GP11TIMER_REGS_SYS_PHYS_BASE; -+#endif -+ gpsSysData->pvSOCTimerRegisterKM = IMG_NULL; -+ gpsSysData->hSOCTimerRegisterOSMemHandle = 0; -+ if (TimerRegPhysBase.uiAddr != 0) -+ { -+ OSReservePhys(TimerRegPhysBase, -+ 4, -+ PVRSRV_HAP_MULTI_PROCESS|PVRSRV_HAP_UNCACHED, -+ IMG_NULL, -+ (IMG_VOID **)&gpsSysData->pvSOCTimerRegisterKM, -+ &gpsSysData->hSOCTimerRegisterOSMemHandle); -+ } -+#endif /* !defined(PVR_NO_OMAP_TIMER) */ -+ -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysFinalise -+ -+ @Description Final part of initialisation at 'driver load' time -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+PVRSRV_ERROR SysFinalise(IMG_VOID) -+{ -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ eError = EnableSGXClocksWrap(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to Enable SGX clocks (%d)", eError)); -+ return eError; -+ } -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ -+ eError = OSInstallMISR(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to install MISR")); -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_MISR); -+ -+#if defined(SYS_USING_INTERRUPTS) -+ /* install a Device ISR */ -+ eError = OSInstallDeviceLISR(gpsSysData, gsSGXDeviceMap.ui32IRQ, "SGX ISR", gpsSGXDevNode); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to install ISR")); -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR); -+#if !defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ SysEnableSGXInterrupts(gpsSysData); -+#endif -+#endif /* defined(SYS_USING_INTERRUPTS) */ -+#if defined(__linux__) -+ /* Create a human readable version string for this system */ -+ gpsSysData->pszVersionString = SysCreateVersionString(); -+ if (!gpsSysData->pszVersionString) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to create a system version string")); -+ } -+ else -+ { -+ PVR_TRACE(("SysFinalise: Version string: %s", gpsSysData->pszVersionString)); -+ } -+#endif -+ -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ /* SGX defaults to D3 power state */ -+ DisableSGXClocks(gpsSysData); -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ -+ gpsSysSpecificData->bSGXInitComplete = IMG_TRUE; -+ -+ return eError; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysDeinitialise -+ -+ @Description De-initialises kernel services at 'driver unload' time -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR SysDeinitialise (SYS_DATA *psSysData) -+{ -+ PVRSRV_ERROR eError; -+ -+ PVR_UNREFERENCED_PARAMETER(psSysData); -+ -+ if(gpsSysData->pvSOCTimerRegisterKM) -+ { -+ OSUnReservePhys(gpsSysData->pvSOCTimerRegisterKM, -+ 4, -+ PVRSRV_HAP_MULTI_PROCESS|PVRSRV_HAP_UNCACHED, -+ gpsSysData->hSOCTimerRegisterOSMemHandle); -+ } -+ -+ -+#if defined(SYS_USING_INTERRUPTS) -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR)) -+ { -+ eError = OSUninstallDeviceLISR(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: OSUninstallDeviceLISR failed")); -+ return eError; -+ } -+ } -+#endif -+ -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_MISR)) -+ { -+ eError = OSUninstallMISR(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: OSUninstallMISR failed")); -+ return eError; -+ } -+ } -+ -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_INITDEV)) -+ { -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ PVR_ASSERT(SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS)); -+ /* Reenable SGX clocks whilst SGX is being deinitialised. */ -+ eError = EnableSGXClocksWrap(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: EnableSGXClocks failed")); -+ return eError; -+ } -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ -+ /* Deinitialise SGX */ -+ eError = PVRSRVDeinitialiseDevice(gui32SGXDeviceID); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: failed to de-init the device")); -+ return eError; -+ } -+ } -+ -+ /* Disable system clocks. Must happen after last access to hardware */ -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS)) -+ { -+ DisableSystemClocks(gpsSysData); -+ } -+ -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_DVFS_INIT)) -+ { -+ eError = SysDvfsDeinitialize(gpsSysSpecificData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: Failed to de-init DVFS")); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ } -+ -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_PM_RUNTIME)) -+ { -+ eError = SysPMRuntimeUnregister(); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: Failed to unregister with OSPM!")); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ } -+ -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_ENVDATA)) -+ { -+ eError = OSDeInitEnvData(gpsSysData->pvEnvSpecificData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: failed to de-init env structure")); -+ return eError; -+ } -+ } -+ -+ SysDeinitialiseCommon(gpsSysData); -+ -+#if defined(NO_HARDWARE) || defined(SGX_OCP_REGS_ENABLED) -+ if(gsSGXRegsCPUVAddr != IMG_NULL) -+ { -+#if defined(NO_HARDWARE) -+ /* Free hardware resources. */ -+ OSBaseFreeContigMemory(SYS_OMAP_SGX_REGS_SIZE, gsSGXRegsCPUVAddr, gsSGXDeviceMap.sRegsCpuPBase); -+#else -+#if defined(SGX_OCP_REGS_ENABLED) -+ OSUnMapPhysToLin(gsSGXRegsCPUVAddr, -+ gsSGXDeviceMap.ui32RegsSize, -+ PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY, -+ IMG_NULL); -+ -+ gpvOCPRegsLinAddr = IMG_NULL; -+#endif -+#endif /* defined(NO_HARDWARE) */ -+ gsSGXRegsCPUVAddr = IMG_NULL; -+ gsSGXDeviceMap.pvRegsCpuVBase = gsSGXRegsCPUVAddr; -+ } -+#endif /* defined(NO_HARDWARE) || defined(SGX_OCP_REGS_ENABLED) */ -+ -+ -+ gpsSysSpecificData->ui32SysSpecificData = 0; -+ gpsSysSpecificData->bSGXInitComplete = IMG_FALSE; -+ -+ gpsSysData = IMG_NULL; -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysGetDeviceMemoryMap -+ -+ @Description returns a device address map for the specified device -+ -+ @Input eDeviceType - device type -+ @Input ppvDeviceMap - void ptr to receive device specific info. -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE eDeviceType, -+ IMG_VOID **ppvDeviceMap) -+{ -+ -+ switch(eDeviceType) -+ { -+ case PVRSRV_DEVICE_TYPE_SGX: -+ { -+ /* just return a pointer to the structure */ -+ *ppvDeviceMap = (IMG_VOID*)&gsSGXDeviceMap; -+ -+ break; -+ } -+ default: -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysGetDeviceMemoryMap: unsupported device type")); -+ } -+ } -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function SysCpuPAddrToDevPAddr -+ -+ @Description Compute a device physical address from a cpu physical -+ address. Relevant when -+ -+ @Input cpu_paddr - cpu physical address. -+ @Input eDeviceType - device type required if DevPAddr -+ address spaces vary across devices -+ in the same system -+ @Return device physical address. -+ -+******************************************************************************/ -+IMG_DEV_PHYADDR SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType, -+ IMG_CPU_PHYADDR CpuPAddr) -+{ -+ IMG_DEV_PHYADDR DevPAddr; -+ -+ PVR_UNREFERENCED_PARAMETER(eDeviceType); -+ -+ /* Note: for UMA system we assume DevP == CpuP */ -+ DevPAddr.uiAddr = CpuPAddr.uiAddr; -+ -+ return DevPAddr; -+} -+ -+/*! -+****************************************************************************** -+ @Function SysSysPAddrToCpuPAddr -+ -+ @Description Compute a cpu physical address from a system physical -+ address. -+ -+ @Input sys_paddr - system physical address. -+ @Return cpu physical address. -+ -+******************************************************************************/ -+IMG_CPU_PHYADDR SysSysPAddrToCpuPAddr (IMG_SYS_PHYADDR sys_paddr) -+{ -+ IMG_CPU_PHYADDR cpu_paddr; -+ -+ /* This would only be an inequality if the CPU's MMU did not point to -+ sys address 0, ie. multi CPU system */ -+ cpu_paddr.uiAddr = sys_paddr.uiAddr; -+ return cpu_paddr; -+} -+ -+/*! -+****************************************************************************** -+ @Function SysCpuPAddrToSysPAddr -+ -+ @Description Compute a system physical address from a cpu physical -+ address. -+ -+ @Input cpu_paddr - cpu physical address. -+ @Return device physical address. -+ -+******************************************************************************/ -+IMG_SYS_PHYADDR SysCpuPAddrToSysPAddr (IMG_CPU_PHYADDR cpu_paddr) -+{ -+ IMG_SYS_PHYADDR sys_paddr; -+ -+ /* This would only be an inequality if the CPU's MMU did not point to -+ sys address 0, ie. multi CPU system */ -+ sys_paddr.uiAddr = cpu_paddr.uiAddr; -+ return sys_paddr; -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function SysSysPAddrToDevPAddr -+ -+ @Description Compute a device physical address from a system physical -+ address. -+ -+ @Input SysPAddr - system physical address. -+ @Input eDeviceType - device type required if DevPAddr -+ address spaces vary across devices -+ in the same system -+ -+ @Return Device physical address. -+ -+******************************************************************************/ -+IMG_DEV_PHYADDR SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType, IMG_SYS_PHYADDR SysPAddr) -+{ -+ IMG_DEV_PHYADDR DevPAddr; -+ -+ PVR_UNREFERENCED_PARAMETER(eDeviceType); -+ -+ /* Note: for UMA system we assume DevP == CpuP */ -+ DevPAddr.uiAddr = SysPAddr.uiAddr; -+ -+ return DevPAddr; -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function SysDevPAddrToSysPAddr -+ -+ @Description Compute a device physical address from a system physical -+ address. -+ -+ @Input DevPAddr - device physical address. -+ @Input eDeviceType - device type required if DevPAddr -+ address spaces vary across devices -+ in the same system -+ -+ @Return System physical address. -+ -+******************************************************************************/ -+IMG_SYS_PHYADDR SysDevPAddrToSysPAddr(PVRSRV_DEVICE_TYPE eDeviceType, IMG_DEV_PHYADDR DevPAddr) -+{ -+ IMG_SYS_PHYADDR SysPAddr; -+ -+ PVR_UNREFERENCED_PARAMETER(eDeviceType); -+ -+ /* Note: for UMA system we assume DevP == SysP */ -+ SysPAddr.uiAddr = DevPAddr.uiAddr; -+ -+ return SysPAddr; -+} -+ -+ -+/***************************************************************************** -+ @Function SysRegisterExternalDevice -+ -+ @Description Called when a 3rd party device registers with services -+ -+ @Input psDeviceNode - the new device node. -+ -+ @Return IMG_VOID -+*****************************************************************************/ -+IMG_VOID SysRegisterExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode) -+{ -+ PVR_UNREFERENCED_PARAMETER(psDeviceNode); -+} -+ -+ -+/***************************************************************************** -+ @Function SysRemoveExternalDevice -+ -+ @Description Called when a 3rd party device unregisters from services -+ -+ @Input psDeviceNode - the device node being removed. -+ -+ @Return IMG_VOID -+*****************************************************************************/ -+IMG_VOID SysRemoveExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode) -+{ -+ PVR_UNREFERENCED_PARAMETER(psDeviceNode); -+} -+ -+/*! -+****************************************************************************** -+ @Function SysGetInterruptSource -+ -+ @Description Returns System specific information about the device(s) that -+ generated the interrupt in the system -+ -+ @Input psSysData -+ @Input psDeviceNode -+ -+ @Return System specific information indicating which device(s) -+ generated the interrupt -+ -+******************************************************************************/ -+IMG_UINT32 SysGetInterruptSource(SYS_DATA *psSysData, -+ PVRSRV_DEVICE_NODE *psDeviceNode) -+{ -+ PVR_UNREFERENCED_PARAMETER(psSysData); -+#if defined(NO_HARDWARE) -+ /* no interrupts in no_hw system just return all bits */ -+ return 0xFFFFFFFF; -+#else -+ /* Not a shared irq, so we know this is an interrupt for this device */ -+ return psDeviceNode->ui32SOCInterruptBit; -+#endif -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function SysClearInterrupts -+ -+ @Description Clears specified system interrupts -+ -+ @Input psSysData -+ @Input ui32ClearBits -+ -+ @Return IMG_VOID -+ -+******************************************************************************/ -+IMG_VOID SysClearInterrupts(SYS_DATA* psSysData, IMG_UINT32 ui32ClearBits) -+{ -+ PVR_UNREFERENCED_PARAMETER(ui32ClearBits); -+ PVR_UNREFERENCED_PARAMETER(psSysData); -+#if !defined(NO_HARDWARE) -+#if defined(SGX_OCP_NO_INT_BYPASS) -+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_IRQSTATUS_2, 0x1); -+#endif -+ /* Flush posted writes */ -+ OSReadHWReg(((PVRSRV_SGXDEV_INFO *)gpsSGXDevNode->pvDevice)->pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR); -+#endif /* defined(NO_HARDWARE) */ -+} -+ -+#if defined(SGX_OCP_NO_INT_BYPASS) -+/*! -+****************************************************************************** -+ @Function SysEnableSGXInterrupts -+ -+ @Description Enables SGX interrupts -+ -+ @Input psSysData -+ -+ @Return IMG_VOID -+ -+******************************************************************************/ -+IMG_VOID SysEnableSGXInterrupts(SYS_DATA *psSysData) -+{ -+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *)psSysData->pvSysSpecificData; -+ if (SYS_SPECIFIC_DATA_TEST(psSysSpecData, SYS_SPECIFIC_DATA_ENABLE_LISR) && !SYS_SPECIFIC_DATA_TEST(psSysSpecData, SYS_SPECIFIC_DATA_IRQ_ENABLED)) -+ { -+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_IRQSTATUS_2, 0x1); -+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_IRQENABLE_SET_2, 0x1); -+ SYS_SPECIFIC_DATA_SET(psSysSpecData, SYS_SPECIFIC_DATA_IRQ_ENABLED); -+ } -+} -+ -+/*! -+****************************************************************************** -+ @Function SysDisableSGXInterrupts -+ -+ @Description Disables SGX interrupts -+ -+ @Input psSysData -+ -+ @Return IMG_VOID -+ -+******************************************************************************/ -+IMG_VOID SysDisableSGXInterrupts(SYS_DATA *psSysData) -+{ -+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *)psSysData->pvSysSpecificData; -+ -+ if (SYS_SPECIFIC_DATA_TEST(psSysSpecData, SYS_SPECIFIC_DATA_IRQ_ENABLED)) -+ { -+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_IRQENABLE_CLR_2, 0x1); -+ SYS_SPECIFIC_DATA_CLEAR(psSysSpecData, SYS_SPECIFIC_DATA_IRQ_ENABLED); -+ } -+} -+#endif /* defined(SGX_OCP_NO_INT_BYPASS) */ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysSystemPrePowerState -+ -+ @Description Perform system-level processing required before a power transition -+ -+ @Input eNewPowerState : -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR SysSystemPrePowerState(PVRSRV_SYS_POWER_STATE eNewPowerState) -+{ -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ -+ if (eNewPowerState == PVRSRV_SYS_POWER_STATE_D3) -+ { -+ PVR_TRACE(("SysSystemPrePowerState: Entering state D3")); -+ -+#if defined(SYS_USING_INTERRUPTS) -+ if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR)) -+ { -+#if defined(SYS_CUSTOM_POWERLOCK_WRAP) -+ IMG_BOOL bWrapped = WrapSystemPowerChange(&gsSysSpecificData); -+#endif -+ eError = OSUninstallDeviceLISR(gpsSysData); -+#if defined(SYS_CUSTOM_POWERLOCK_WRAP) -+ if (bWrapped) -+ { -+ UnwrapSystemPowerChange(&gsSysSpecificData); -+ } -+#endif -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysSystemPrePowerState: OSUninstallDeviceLISR failed (%d)", eError)); -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR); -+ SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR); -+ } -+#endif -+ -+ if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS)) -+ { -+ DisableSystemClocks(gpsSysData); -+ -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS); -+ SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS); -+ } -+ } -+ -+ return eError; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysSystemPostPowerState -+ -+ @Description Perform system-level processing required after a power transition -+ -+ @Input eNewPowerState : -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR SysSystemPostPowerState(PVRSRV_SYS_POWER_STATE eNewPowerState) -+{ -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ -+ if (eNewPowerState == PVRSRV_SYS_POWER_STATE_D0) -+ { -+ PVR_TRACE(("SysSystemPostPowerState: Entering state D0")); -+ -+ if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS)) -+ { -+ eError = EnableSystemClocksWrap(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysSystemPostPowerState: EnableSystemClocksWrap failed (%d)", eError)); -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS); -+ SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS); -+ } -+ -+#if defined(SYS_USING_INTERRUPTS) -+ if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR)) -+ { -+#if defined(SYS_CUSTOM_POWERLOCK_WRAP) -+ IMG_BOOL bWrapped = WrapSystemPowerChange(&gsSysSpecificData); -+#endif -+ -+ eError = OSInstallDeviceLISR(gpsSysData, gsSGXDeviceMap.ui32IRQ, "SGX ISR", gpsSGXDevNode); -+#if defined(SYS_CUSTOM_POWERLOCK_WRAP) -+ if (bWrapped) -+ { -+ UnwrapSystemPowerChange(&gsSysSpecificData); -+ } -+#endif -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysSystemPostPowerState: OSInstallDeviceLISR failed to install ISR (%d)", eError)); -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR); -+ SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR); -+ } -+#endif -+ } -+ return eError; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysDevicePrePowerState -+ -+ @Description Perform system level processing required before a device power -+ transition -+ -+ @Input ui32DeviceIndex : -+ @Input eNewPowerState : -+ @Input eCurrentPowerState : -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR SysDevicePrePowerState(IMG_UINT32 ui32DeviceIndex, -+ PVRSRV_DEV_POWER_STATE eNewPowerState, -+ PVRSRV_DEV_POWER_STATE eCurrentPowerState) -+{ -+ PVR_UNREFERENCED_PARAMETER(eCurrentPowerState); -+ -+ if (ui32DeviceIndex != gui32SGXDeviceID) -+ { -+ return PVRSRV_OK; -+ } -+ -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ if (eNewPowerState == PVRSRV_DEV_POWER_STATE_OFF) -+ { -+ PVR_DPF((PVR_DBG_MESSAGE, "SysDevicePrePowerState: SGX Entering state D3")); -+ DisableSGXClocks(gpsSysData); -+ } -+#else /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ PVR_UNREFERENCED_PARAMETER(eNewPowerState ); -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysDevicePostPowerState -+ -+ @Description Perform system level processing required after a device power -+ transition -+ -+ @Input ui32DeviceIndex : -+ @Input eNewPowerState : -+ @Input eCurrentPowerState : -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR SysDevicePostPowerState(IMG_UINT32 ui32DeviceIndex, -+ PVRSRV_DEV_POWER_STATE eNewPowerState, -+ PVRSRV_DEV_POWER_STATE eCurrentPowerState) -+{ -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ -+ PVR_UNREFERENCED_PARAMETER(eNewPowerState); -+ -+ if (ui32DeviceIndex != gui32SGXDeviceID) -+ { -+ return eError; -+ } -+ -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ if (eCurrentPowerState == PVRSRV_DEV_POWER_STATE_OFF) -+ { -+ PVR_DPF((PVR_DBG_MESSAGE, "SysDevicePostPowerState: SGX Leaving state D3")); -+ eError = EnableSGXClocksWrap(gpsSysData); -+ } -+#else /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ PVR_UNREFERENCED_PARAMETER(eCurrentPowerState); -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ -+ return eError; -+} -+ -+#if defined(SYS_SUPPORTS_SGX_IDLE_CALLBACK) -+ -+IMG_VOID SysSGXIdleTransition(IMG_BOOL bSGXIdle) -+{ -+ PVR_DPF((PVR_DBG_MESSAGE, "SysSGXIdleTransition switch to %u", bSGXIdle)); -+} -+ -+#endif /* defined(SYS_SUPPORTS_SGX_IDLE_CALLBACK) */ -+ -+/***************************************************************************** -+ @Function SysOEMFunction -+ -+ @Description marshalling function for custom OEM functions -+ -+ @Input ui32ID - function ID -+ @Input pvIn - in data -+ @Output pvOut - out data -+ -+ @Return PVRSRV_ERROR -+*****************************************************************************/ -+PVRSRV_ERROR SysOEMFunction ( IMG_UINT32 ui32ID, -+ IMG_VOID *pvIn, -+ IMG_UINT32 ulInSize, -+ IMG_VOID *pvOut, -+ IMG_UINT32 ulOutSize) -+{ -+ PVR_UNREFERENCED_PARAMETER(ui32ID); -+ PVR_UNREFERENCED_PARAMETER(pvIn); -+ PVR_UNREFERENCED_PARAMETER(ulInSize); -+ PVR_UNREFERENCED_PARAMETER(pvOut); -+ PVR_UNREFERENCED_PARAMETER(ulOutSize); -+ -+ if ((ui32ID == OEM_GET_EXT_FUNCS) && -+ (ulOutSize == sizeof(PVRSRV_DC_OEM_JTABLE))) -+ { -+ PVRSRV_DC_OEM_JTABLE *psOEMJTable = (PVRSRV_DC_OEM_JTABLE*) pvOut; -+ psOEMJTable->pfnOEMBridgeDispatch = &PVRSRV_BridgeDispatchKM; -+ return PVRSRV_OK; -+ } -+ -+ return PVRSRV_ERROR_INVALID_PARAMS; -+} -+/****************************************************************************** -+ End of file (sysconfig.c) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/system/omap/sysconfig.h b/drivers/staging/ti-es8-sgx/services4/system/omap/sysconfig.h -new file mode 100644 -index 0000000..db15ae4 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/omap/sysconfig.h -@@ -0,0 +1,105 @@ -+/*************************************************************************/ /*! -+@Title System Description Header -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description This header provides system-specific declarations and macros -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#if !defined(__SOCCONFIG_H__) -+#define __SOCCONFIG_H__ -+ -+#define VS_PRODUCT_NAME "OMAP4" -+ -+ -+#define SYS_SGX_HWRECOVERY_TIMEOUT_FREQ (100) // 10ms (100hz) -+#define SYS_SGX_PDS_TIMER_FREQ (1000) // 1ms (1000hz) -+ -+/* Allow the AP latency to be overridden in the build config */ -+#if !defined(SYS_SGX_ACTIVE_POWER_LATENCY_MS) -+#define SYS_SGX_ACTIVE_POWER_LATENCY_MS (2) -+#endif -+ -+ -+#define SYS_OMAP_SGX_REGS_SYS_PHYS_BASE 0x56000000 -+#define SYS_OMAP_SGX_REGS_SIZE 0xFFFF -+ -+#define SYS_OMAP_SGX_IRQ 53 /* OMAP4 IRQ's are offset by 32 */ -+ -+#define SYS_OMAP_DSS_REGS_SYS_PHYS_BASE 0x58000000 -+#define SYS_OMAP_DSS_REGS_SIZE 0x7000 -+ -+#define SYS_OMAP_DSS_HDMI_INTERRUPT_STATUS_REG 0x6028 -+#define SYS_OMAP_DSS_HDMI_INTERRUPT_ENABLE_REG 0x602c -+ -+#define SYS_OMAP_DSS_HDMI_INTERRUPT_VSYNC_ENABLE_MASK 0x10000 -+#define SYS_OMAP_DSS_HDMI_INTERRUPT_VSYNC_STATUS_MASK 0x10000 -+ -+#define SYS_OMAP_DSS_LCD_INTERRUPT_STATUS_REG 0x1018 -+#define SYS_OMAP_DSS_LCD_INTERRUPT_ENABLE_REG 0x101c -+ -+#define SYS_OMAP_DSS_LCD_INTERRUPT_VSYNC_ENABLE_MASK 0x40002 -+#define SYS_OMAP_DSS_LCD_INTERRUPT_VSYNC_STATUS_MASK 0x40002 -+ -+ -+#define SYS_OMAP_GP11TIMER_ENABLE_SYS_PHYS_BASE 0x48088038 -+#define SYS_OMAP_GP11TIMER_REGS_SYS_PHYS_BASE 0x4808803C -+#define SYS_OMAP_GP11TIMER_TSICR_SYS_PHYS_BASE 0x48088054 -+ -+/* Interrupt bits */ -+#define DEVICE_SGX_INTERRUPT (1<<0) -+#define DEVICE_MSVDX_INTERRUPT (1<<1) -+#define DEVICE_DISP_INTERRUPT (1<<2) -+ -+#if defined(__linux__) -+/* -+ * Recent OMAP4 kernels register SGX as platform device "omap_gpu". -+ * This device must be used with the Linux power management calls -+ * in sysutils_linux.c, in order for SGX to be powered on. -+ */ -+#if defined(PVR_LDM_PLATFORM_PRE_REGISTERED_DEV) -+#define SYS_SGX_DEV_NAME PVR_LDM_PLATFORM_PRE_REGISTERED_DEV -+#else -+#define SYS_SGX_DEV_NAME "omap_gpu" -+#endif /* defined(PVR_LDM_PLATFORM_PRE_REGISTERED_DEV) */ -+#endif /* defined(__linux__) */ -+ -+/***************************************************************************** -+ * system specific data structures -+ *****************************************************************************/ -+ -+#endif /* __SYSCONFIG_H__ */ -diff --git a/drivers/staging/ti-es8-sgx/services4/system/omap/sysinfo.h b/drivers/staging/ti-es8-sgx/services4/system/omap/sysinfo.h -new file mode 100644 -index 0000000..84febab ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/omap/sysinfo.h -@@ -0,0 +1,70 @@ -+/*************************************************************************/ /*! -+@Title System Description Header -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description This header provides system-specific declarations and macros -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#if !defined(__SYSINFO_H__) -+#define __SYSINFO_H__ -+ -+#if defined(SGX540) && (SGX_CORE_REV == 120) -+#define SYS_SGX_CLOCK_SPEED 307200000 -+#else -+#define SYS_SGX_CLOCK_SPEED 304742400 -+#endif -+ -+/*!< System specific poll/timeout details */ -+#if defined(PVR_LINUX_USING_WORKQUEUES) -+/* -+ * The workqueue based 3rd party display driver may be blocked for up -+ * to 500ms waiting for a vsync when the screen goes blank, so we -+ * need to wait longer for the hardware if a flush of the swap chain is -+ * required. -+ */ -+#define MAX_HW_TIME_US (1000000) -+#define WAIT_TRY_COUNT (20000) -+#else -+#define MAX_HW_TIME_US (500000) -+#define WAIT_TRY_COUNT (10000) -+#endif -+ -+ -+#define SYS_DEVICE_COUNT 15 /* SGX, DISPLAYCLASS (external), BUFFERCLASS (external) */ -+ -+#endif /* __SYSINFO_H__ */ -diff --git a/drivers/staging/ti-es8-sgx/services4/system/omap/syslocal.h b/drivers/staging/ti-es8-sgx/services4/system/omap/syslocal.h -new file mode 100644 -index 0000000..b2315eb ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/omap/syslocal.h -@@ -0,0 +1,259 @@ -+/*************************************************************************/ /*! -+@Title Local system definitions -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description This header provides local system declarations and macros -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#if !defined(__SYSLOCAL_H__) -+#define __SYSLOCAL_H__ -+ -+#if defined(__linux__) -+ -+#include <linux/version.h> -+#include <linux/clk.h> -+#if defined(PVR_LINUX_USING_WORKQUEUES) -+#include <linux/mutex.h> -+#else -+#include <linux/spinlock.h> -+#endif -+#include <asm/atomic.h> -+ -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)) -+#include <linux/semaphore.h> -+#include <linux/resource.h> -+#else /* (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)) */ -+#include <asm/semaphore.h> -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22)) -+#include <asm/arch/resource.h> -+#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22)) */ -+#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)) */ -+ -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) -+#if !defined(LDM_PLATFORM) -+#error "LDM_PLATFORM must be set" -+#endif -+#define PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO -+#include <linux/platform_device.h> -+#endif -+ -+#if ((defined(DEBUG) || defined(TIMING)) && \ -+ (LINUX_VERSION_CODE == KERNEL_VERSION(2,6,34))) && \ -+ !defined(PVR_NO_OMAP_TIMER) -+/* -+ * We need to explicitly enable the GPTIMER11 clocks, or we'll get an -+ * abort when we try to access the timer registers. -+ */ -+#define PVR_OMAP4_TIMING_PRCM -+#endif -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) -+#include <plat/gpu.h> -+#if !defined(PVR_NO_OMAP_TIMER) -+#define PVR_OMAP_USE_DM_TIMER_API -+#include <plat/dmtimer.h> -+#endif -+#endif -+ -+#if !defined(PVR_NO_OMAP_TIMER) -+#define PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA -+#endif -+#endif /* defined(__linux__) */ -+ -+#if !defined(NO_HARDWARE) && \ -+ defined(SYS_USING_INTERRUPTS) -+#define SGX_OCP_REGS_ENABLED -+#endif -+ -+#if defined(__linux__) -+#if defined(SGX_OCP_REGS_ENABLED) -+/* FIXME: Temporary workaround for OMAP4470 and active power off in 4430 */ -+#if !defined(SGX544) && defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+#define SGX_OCP_NO_INT_BYPASS -+#endif -+#endif -+#endif -+ -+#if defined (__cplusplus) -+extern "C" { -+#endif -+ -+/***************************************************************************** -+ * system specific data structures -+ *****************************************************************************/ -+ -+/***************************************************************************** -+ * system specific function prototypes -+ *****************************************************************************/ -+ -+IMG_VOID DisableSystemClocks(SYS_DATA *psSysData); -+PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData); -+ -+IMG_VOID DisableSGXClocks(SYS_DATA *psSysData); -+PVRSRV_ERROR EnableSGXClocks(SYS_DATA *psSysData); -+ -+/* -+ * Various flags to indicate what has been initialised, and what -+ * has been temporarily deinitialised for power management purposes. -+ */ -+#define SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS 0x00000001 -+#define SYS_SPECIFIC_DATA_ENABLE_LISR 0x00000002 -+#define SYS_SPECIFIC_DATA_ENABLE_MISR 0x00000004 -+#define SYS_SPECIFIC_DATA_ENABLE_ENVDATA 0x00000008 -+#define SYS_SPECIFIC_DATA_ENABLE_LOCDEV 0x00000010 -+#define SYS_SPECIFIC_DATA_ENABLE_REGDEV 0x00000020 -+#define SYS_SPECIFIC_DATA_ENABLE_PDUMPINIT 0x00000040 -+#define SYS_SPECIFIC_DATA_ENABLE_INITDEV 0x00000080 -+#define SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV 0x00000100 -+ -+#define SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR 0x00000200 -+#define SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS 0x00000400 -+#define SYS_SPECIFIC_DATA_ENABLE_OCPREGS 0x00000800 -+#define SYS_SPECIFIC_DATA_ENABLE_PM_RUNTIME 0x00001000 -+#define SYS_SPECIFIC_DATA_IRQ_ENABLED 0x00002000 -+#define SYS_SPECIFIC_DATA_DVFS_INIT 0x00004000 -+ -+#define SYS_SPECIFIC_DATA_SET(psSysSpecData, flag) ((IMG_VOID)((psSysSpecData)->ui32SysSpecificData |= (flag))) -+ -+#define SYS_SPECIFIC_DATA_CLEAR(psSysSpecData, flag) ((IMG_VOID)((psSysSpecData)->ui32SysSpecificData &= ~(flag))) -+ -+#define SYS_SPECIFIC_DATA_TEST(psSysSpecData, flag) (((psSysSpecData)->ui32SysSpecificData & (flag)) != 0) -+ -+typedef struct _SYS_SPECIFIC_DATA_TAG_ -+{ -+ IMG_UINT32 ui32SysSpecificData; -+ PVRSRV_DEVICE_NODE *psSGXDevNode; -+ IMG_BOOL bSGXInitComplete; -+#if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA) -+ IMG_CPU_PHYADDR sTimerRegPhysBase; -+#endif -+#if !defined(__linux__) -+ IMG_BOOL bSGXClocksEnabled; -+#endif -+ IMG_UINT32 ui32SrcClockDiv; -+#if defined(__linux__) -+ IMG_BOOL bSysClocksOneTimeInit; -+ atomic_t sSGXClocksEnabled; -+#if defined(PVR_LINUX_USING_WORKQUEUES) -+ struct mutex sPowerLock; -+#else -+ IMG_BOOL bConstraintNotificationsEnabled; -+ spinlock_t sPowerLock; -+ atomic_t sPowerLockCPU; -+ spinlock_t sNotifyLock; -+ atomic_t sNotifyLockCPU; -+ IMG_BOOL bCallVDD2PostFunc; -+#endif -+#if defined(DEBUG) || defined(TIMING) -+ struct clk *psGPT11_FCK; -+ struct clk *psGPT11_ICK; -+#endif -+#if defined(PVR_OMAP_USE_DM_TIMER_API) -+ struct omap_dm_timer *psGPTimer; -+#endif -+ IMG_UINT32 ui32SGXFreqListSize; -+ IMG_UINT32 *pui32SGXFreqList; -+ IMG_UINT32 ui32SGXFreqListIndex; -+#endif /* defined(__linux__) */ -+} SYS_SPECIFIC_DATA; -+ -+extern SYS_SPECIFIC_DATA *gpsSysSpecificData; -+ -+#if defined(SGX_OCP_REGS_ENABLED) && defined(SGX_OCP_NO_INT_BYPASS) -+IMG_VOID SysEnableSGXInterrupts(SYS_DATA* psSysData); -+IMG_VOID SysDisableSGXInterrupts(SYS_DATA* psSysData); -+#else -+#define SysEnableSGXInterrupts(psSysData) -+#define SysDisableSGXInterrupts(psSysData) -+#endif -+ -+#if defined(SYS_CUSTOM_POWERLOCK_WRAP) -+IMG_BOOL WrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData); -+IMG_VOID UnwrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData); -+#endif -+ -+#if defined(__linux__) -+ -+PVRSRV_ERROR SysPMRuntimeRegister(void); -+PVRSRV_ERROR SysPMRuntimeUnregister(void); -+ -+PVRSRV_ERROR SysDvfsInitialize(SYS_SPECIFIC_DATA *psSysSpecificData); -+PVRSRV_ERROR SysDvfsDeinitialize(SYS_SPECIFIC_DATA *psSysSpecificData); -+ -+#else /* defined(__linux__) */ -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(SysPMRuntimeRegister) -+#endif -+static INLINE PVRSRV_ERROR SysPMRuntimeRegister(void) -+{ -+ return PVRSRV_OK; -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(SysPMRuntimeUnregister) -+#endif -+static INLINE PVRSRV_ERROR SysPMRuntimeUnregister(void) -+{ -+ return PVRSRV_OK; -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(SysDvfsInitialize) -+#endif -+static INLINE PVRSRV_ERROR SysDvfsInitialize(void) -+{ -+ return PVRSRV_OK; -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(SysDvfsDeinitialize) -+#endif -+static INLINE PVRSRV_ERROR SysDvfsDeinitialize(void) -+{ -+ return PVRSRV_OK; -+} -+ -+#endif /* defined(__linux__) */ -+ -+#if defined(__cplusplus) -+} -+#endif -+ -+#endif /* __SYSLOCAL_H__ */ -diff --git a/drivers/staging/ti-es8-sgx/services4/system/omap/sysutils.c b/drivers/staging/ti-es8-sgx/services4/system/omap/sysutils.c -new file mode 100644 -index 0000000..6725421 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/omap/sysutils.c -@@ -0,0 +1,47 @@ -+/*************************************************************************/ /*! -+@Title Shared (User/kernel) and System dependent utilities -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Provides system-specific functions -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+/* Pull in the correct system dependent sysutils source */ -+ -+#if defined(__linux__) -+#include "sysutils_linux.c" -+#endif -diff --git a/drivers/staging/ti-es8-sgx/services4/system/omap/sysutils_linux.c b/drivers/staging/ti-es8-sgx/services4/system/omap/sysutils_linux.c -new file mode 100644 -index 0000000..e23cc4c ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/omap/sysutils_linux.c -@@ -0,0 +1,865 @@ -+/*************************************************************************/ /*! -+@Title System dependent utilities -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Provides system-specific functions -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+#include <linux/version.h> -+#include <linux/clk.h> -+#include <linux/err.h> -+#include <linux/hardirq.h> -+#include <linux/mutex.h> -+#include <linux/slab.h> -+ -+#include "sgxdefs.h" -+#include "services_headers.h" -+#include "sysinfo.h" -+#include "sgxapi_km.h" -+#include "sysconfig.h" -+#include "sgxinfokm.h" -+#include "syslocal.h" -+ -+#include <linux/platform_device.h> -+#include <linux/pm_runtime.h> -+ -+#if defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) -+#include <linux/opp.h> -+#endif -+ -+#if defined(SUPPORT_DRI_DRM_PLUGIN) -+#include <drm/drmP.h> -+#include <drm/drm.h> -+ -+#include <linux/omap_gpu.h> -+ -+#include "pvr_drm.h" -+#endif -+ -+#define ONE_MHZ 1000000 -+#define HZ_TO_MHZ(m) ((m) / ONE_MHZ) -+ -+#if defined(SUPPORT_OMAP3430_SGXFCLK_96M) -+#define SGX_PARENT_CLOCK "cm_96m_fck" -+#else -+#define SGX_PARENT_CLOCK "core_ck" -+#endif -+ -+#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) -+extern struct platform_device *gpsPVRLDMDev; -+#endif -+ -+static PVRSRV_ERROR PowerLockWrap(SYS_SPECIFIC_DATA *psSysSpecData, IMG_BOOL bTryLock) -+{ -+ if (!in_interrupt()) -+ { -+ if (bTryLock) -+ { -+ int locked = mutex_trylock(&psSysSpecData->sPowerLock); -+ if (locked == 0) -+ { -+ return PVRSRV_ERROR_RETRY; -+ } -+ } -+ else -+ { -+ mutex_lock(&psSysSpecData->sPowerLock); -+ } -+ } -+ -+ return PVRSRV_OK; -+} -+ -+static IMG_VOID PowerLockUnwrap(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ if (!in_interrupt()) -+ { -+ mutex_unlock(&psSysSpecData->sPowerLock); -+ } -+} -+ -+PVRSRV_ERROR SysPowerLockWrap(IMG_BOOL bTryLock) -+{ -+ SYS_DATA *psSysData; -+ -+ SysAcquireData(&psSysData); -+ -+ return PowerLockWrap(psSysData->pvSysSpecificData, bTryLock); -+} -+ -+IMG_VOID SysPowerLockUnwrap(IMG_VOID) -+{ -+ SYS_DATA *psSysData; -+ -+ SysAcquireData(&psSysData); -+ -+ PowerLockUnwrap(psSysData->pvSysSpecificData); -+} -+ -+/* -+ * This function should be called to unwrap the Services power lock, prior -+ * to calling any function that might sleep. -+ * This function shouldn't be called prior to calling EnableSystemClocks -+ * or DisableSystemClocks, as those functions perform their own power lock -+ * unwrapping. -+ * If the function returns IMG_TRUE, UnwrapSystemPowerChange must be -+ * called to rewrap the power lock, prior to returning to Services. -+ */ -+IMG_BOOL WrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ return IMG_TRUE; -+} -+ -+IMG_VOID UnwrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+} -+ -+/* -+ * Return SGX timining information to caller. -+ */ -+IMG_VOID SysGetSGXTimingInformation(SGX_TIMING_INFORMATION *psTimingInfo) -+{ -+#if !defined(NO_HARDWARE) -+ PVR_ASSERT(atomic_read(&gpsSysSpecificData->sSGXClocksEnabled) != 0); -+#endif -+#if defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) -+ psTimingInfo->ui32CoreClockSpeed = -+ gpsSysSpecificData->pui32SGXFreqList[gpsSysSpecificData->ui32SGXFreqListIndex]; -+#else /* defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) */ -+ psTimingInfo->ui32CoreClockSpeed = SYS_SGX_CLOCK_SPEED; -+#endif -+ psTimingInfo->ui32HWRecoveryFreq = SYS_SGX_HWRECOVERY_TIMEOUT_FREQ; -+ psTimingInfo->ui32uKernelFreq = SYS_SGX_PDS_TIMER_FREQ; -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ psTimingInfo->bEnableActivePM = IMG_TRUE; -+#else -+ psTimingInfo->bEnableActivePM = IMG_FALSE; -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ psTimingInfo->ui32ActivePowManLatencyms = SYS_SGX_ACTIVE_POWER_LATENCY_MS; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function EnableSGXClocks -+ -+ @Description Enable SGX clocks -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR EnableSGXClocks(SYS_DATA *psSysData) -+{ -+#if !defined(NO_HARDWARE) -+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; -+ -+ /* SGX clocks already enabled? */ -+ if (atomic_read(&psSysSpecData->sSGXClocksEnabled) != 0) -+ { -+ return PVRSRV_OK; -+ } -+ -+ PVR_DPF((PVR_DBG_MESSAGE, "EnableSGXClocks: Enabling SGX Clocks")); -+ -+#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) -+#if defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) -+ { -+ struct gpu_platform_data *pdata; -+ IMG_UINT32 max_freq_index; -+ int res; -+ -+ pdata = (struct gpu_platform_data *)gpsPVRLDMDev->dev.platform_data; -+ max_freq_index = psSysSpecData->ui32SGXFreqListSize - 2; -+ -+ /* -+ * Request maximum frequency from DVFS layer if not already set. DVFS may -+ * report busy if early in initialization, but all other errors are -+ * considered serious. Upon any error we proceed assuming our safe frequency -+ * value to be in use as indicated by the "unknown" index. -+ */ -+ if (psSysSpecData->ui32SGXFreqListIndex != max_freq_index) -+ { -+ PVR_ASSERT(pdata->device_scale != IMG_NULL); -+ res = pdata->device_scale(&gpsPVRLDMDev->dev, -+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3,4,0)) -+ &gpsPVRLDMDev->dev, -+#endif -+ psSysSpecData->pui32SGXFreqList[max_freq_index]); -+ if (res == 0) -+ { -+ psSysSpecData->ui32SGXFreqListIndex = max_freq_index; -+ } -+ else if (res == -EBUSY) -+ { -+ PVR_DPF((PVR_DBG_WARNING, "EnableSGXClocks: Unable to scale SGX frequency (EBUSY)")); -+ psSysSpecData->ui32SGXFreqListIndex = psSysSpecData->ui32SGXFreqListSize - 1; -+ } -+ else if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Unable to scale SGX frequency (%d)", res)); -+ psSysSpecData->ui32SGXFreqListIndex = psSysSpecData->ui32SGXFreqListSize - 1; -+ } -+ } -+ } -+#endif /* defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) */ -+ { -+ /* -+ * pm_runtime_get_sync returns 1 after the module has -+ * been reloaded. -+ */ -+ int res = pm_runtime_get_sync(&gpsPVRLDMDev->dev); -+ if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: pm_runtime_get_sync failed (%d)", -res)); -+ return PVRSRV_ERROR_UNABLE_TO_ENABLE_CLOCK; -+ } -+ } -+#endif /* defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) */ -+ -+ SysEnableSGXInterrupts(psSysData); -+ -+ /* Indicate that the SGX clocks are enabled */ -+ atomic_set(&psSysSpecData->sSGXClocksEnabled, 1); -+ -+#else /* !defined(NO_HARDWARE) */ -+ PVR_UNREFERENCED_PARAMETER(psSysData); -+#endif /* !defined(NO_HARDWARE) */ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function DisableSGXClocks -+ -+ @Description Disable SGX clocks. -+ -+ @Return none -+ -+******************************************************************************/ -+IMG_VOID DisableSGXClocks(SYS_DATA *psSysData) -+{ -+#if !defined(NO_HARDWARE) -+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; -+ -+ /* SGX clocks already disabled? */ -+ if (atomic_read(&psSysSpecData->sSGXClocksEnabled) == 0) -+ { -+ return; -+ } -+ -+ PVR_DPF((PVR_DBG_MESSAGE, "DisableSGXClocks: Disabling SGX Clocks")); -+ -+ SysDisableSGXInterrupts(psSysData); -+ -+#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) -+ { -+ int res = pm_runtime_put_sync(&gpsPVRLDMDev->dev); -+ if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "DisableSGXClocks: pm_runtime_put_sync failed (%d)", -res)); -+ } -+ } -+#if defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) -+ { -+ struct gpu_platform_data *pdata; -+ int res; -+ -+ pdata = (struct gpu_platform_data *)gpsPVRLDMDev->dev.platform_data; -+ -+ /* -+ * Request minimum frequency (list index 0) from DVFS layer if not already -+ * set. DVFS may report busy if early in initialization, but all other errors -+ * are considered serious. Upon any error we proceed assuming our safe frequency -+ * value to be in use as indicated by the "unknown" index. -+ */ -+ if (psSysSpecData->ui32SGXFreqListIndex != 0) -+ { -+ PVR_ASSERT(pdata->device_scale != IMG_NULL); -+ res = pdata->device_scale(&gpsPVRLDMDev->dev, -+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3,4,0)) -+ &gpsPVRLDMDev->dev, -+#endif -+ psSysSpecData->pui32SGXFreqList[0]); -+ if (res == 0) -+ { -+ psSysSpecData->ui32SGXFreqListIndex = 0; -+ } -+ else if (res == -EBUSY) -+ { -+ PVR_DPF((PVR_DBG_WARNING, "DisableSGXClocks: Unable to scale SGX frequency (EBUSY)")); -+ psSysSpecData->ui32SGXFreqListIndex = psSysSpecData->ui32SGXFreqListSize - 1; -+ } -+ else if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "DisableSGXClocks: Unable to scale SGX frequency (%d)", res)); -+ psSysSpecData->ui32SGXFreqListIndex = psSysSpecData->ui32SGXFreqListSize - 1; -+ } -+ } -+ } -+#endif /* defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) */ -+#endif /* defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) */ -+ -+ /* Indicate that the SGX clocks are disabled */ -+ atomic_set(&psSysSpecData->sSGXClocksEnabled, 0); -+ -+#else /* !defined(NO_HARDWARE) */ -+ PVR_UNREFERENCED_PARAMETER(psSysData); -+#endif /* !defined(NO_HARDWARE) */ -+} -+ -+#if (defined(DEBUG) || defined(TIMING)) && !defined(PVR_NO_OMAP_TIMER) -+#if defined(PVR_OMAP_USE_DM_TIMER_API) -+#define GPTIMER_TO_USE 11 -+/*! -+****************************************************************************** -+ -+ @Function AcquireGPTimer -+ -+ @Description Acquire a GP timer -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+static PVRSRV_ERROR AcquireGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ PVR_ASSERT(psSysSpecData->psGPTimer == NULL); -+ -+ /* -+ * This code has problems on module reload for OMAP5 running Linux -+ * 3.4.10, due to omap2_dm_timer_set_src (called by -+ * omap_dm_timer_request_specific), being unable to set the parent -+ * clock to OMAP_TIMER_SRC_32_KHZ. -+ * Not calling omap_dm_timer_set_source doesn't help. -+ */ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) || !defined(MODULE) -+ /* -+ * This code could try requesting registers 9, 10, and 11, -+ * stopping at the first succesful request. We'll stick with -+ * 11 for now, as it avoids having to hard code yet more -+ * physical addresses into the code. -+ */ -+ psSysSpecData->psGPTimer = omap_dm_timer_request_specific(GPTIMER_TO_USE); -+ if (psSysSpecData->psGPTimer == NULL) -+ { -+ -+ PVR_DPF((PVR_DBG_WARNING, "%s: omap_dm_timer_request_specific failed", __FUNCTION__)); -+ return PVRSRV_ERROR_CLOCK_REQUEST_FAILED; -+ } -+ -+ omap_dm_timer_set_source(psSysSpecData->psGPTimer, OMAP_TIMER_SRC_SYS_CLK); -+ omap_dm_timer_enable(psSysSpecData->psGPTimer); -+ -+ /* Set autoreload, and start value of 0 */ -+ omap_dm_timer_set_load_start(psSysSpecData->psGPTimer, 1, 0); -+ -+ omap_dm_timer_start(psSysSpecData->psGPTimer); -+ -+ /* -+ * The DM timer API doesn't have a mechanism for obtaining the -+ * physical address of the counter register. -+ */ -+ psSysSpecData->sTimerRegPhysBase.uiAddr = SYS_OMAP_GP11TIMER_REGS_SYS_PHYS_BASE; -+#else /* (LINUX_VERSION_CODE <= KERNEL_VERSION(3,4,0)) || !defined(MODULE) */ -+ (void)psSysSpecData; -+#endif /* (LINUX_VERSION_CODE <= KERNEL_VERSION(3,4,0)) || !defined(MODULE) */ -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function ReleaseGPTimer -+ -+ @Description Release a GP timer -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+static void ReleaseGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ if (psSysSpecData->psGPTimer != NULL) -+ { -+ /* Always returns 0 */ -+ (void) omap_dm_timer_stop(psSysSpecData->psGPTimer); -+ -+ omap_dm_timer_disable(psSysSpecData->psGPTimer); -+ -+ omap_dm_timer_free(psSysSpecData->psGPTimer); -+ -+ psSysSpecData->sTimerRegPhysBase.uiAddr = 0; -+ -+ psSysSpecData->psGPTimer = NULL; -+ } -+ -+} -+#else /* PVR_OMAP_USE_DM_TIMER_API */ -+/*! -+****************************************************************************** -+ -+ @Function AcquireGPTimer -+ -+ @Description Acquire a GP timer -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+static PVRSRV_ERROR AcquireGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+#if defined(PVR_OMAP4_TIMING_PRCM) -+ struct clk *psCLK; -+ IMG_INT res; -+ struct clk *sys_ck; -+ IMG_INT rate; -+#endif -+ PVRSRV_ERROR eError; -+ -+ IMG_CPU_PHYADDR sTimerRegPhysBase; -+ IMG_HANDLE hTimerEnable; -+ IMG_UINT32 *pui32TimerEnable; -+ -+ PVR_ASSERT(psSysSpecData->sTimerRegPhysBase.uiAddr == 0); -+ -+#if defined(PVR_OMAP4_TIMING_PRCM) -+ /* assert our dependence on the GPTIMER11 module */ -+ psCLK = clk_get(NULL, "gpt11_fck"); -+ if (IS_ERR(psCLK)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get GPTIMER11 functional clock")); -+ goto ExitError; -+ } -+ psSysSpecData->psGPT11_FCK = psCLK; -+ -+ psCLK = clk_get(NULL, "gpt11_ick"); -+ if (IS_ERR(psCLK)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get GPTIMER11 interface clock")); -+ goto ExitError; -+ } -+ psSysSpecData->psGPT11_ICK = psCLK; -+ -+ sys_ck = clk_get(NULL, "sys_clkin_ck"); -+ if (IS_ERR(sys_ck)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get System clock")); -+ goto ExitError; -+ } -+ -+ if(clk_get_parent(psSysSpecData->psGPT11_FCK) != sys_ck) -+ { -+ PVR_TRACE(("Setting GPTIMER11 parent to System Clock")); -+ res = clk_set_parent(psSysSpecData->psGPT11_FCK, sys_ck); -+ if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't set GPTIMER11 parent clock (%d)", res)); -+ goto ExitError; -+ } -+ } -+ -+ rate = clk_get_rate(psSysSpecData->psGPT11_FCK); -+ PVR_TRACE(("GPTIMER11 clock is %dMHz", HZ_TO_MHZ(rate))); -+ -+ res = clk_enable(psSysSpecData->psGPT11_FCK); -+ if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't enable GPTIMER11 functional clock (%d)", res)); -+ goto ExitError; -+ } -+ -+ res = clk_enable(psSysSpecData->psGPT11_ICK); -+ if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't enable GPTIMER11 interface clock (%d)", res)); -+ goto ExitDisableGPT11FCK; -+ } -+#endif /* defined(PVR_OMAP4_TIMING_PRCM) */ -+ -+ /* Set the timer to non-posted mode */ -+ sTimerRegPhysBase.uiAddr = SYS_OMAP_GP11TIMER_TSICR_SYS_PHYS_BASE; -+ pui32TimerEnable = OSMapPhysToLin(sTimerRegPhysBase, -+ 4, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ &hTimerEnable); -+ -+ if (pui32TimerEnable == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: OSMapPhysToLin failed")); -+ goto ExitDisableGPT11ICK; -+ } -+ -+ if(!(*pui32TimerEnable & 4)) -+ { -+ PVR_TRACE(("Setting GPTIMER11 mode to posted (currently is non-posted)")); -+ -+ /* Set posted mode */ -+ *pui32TimerEnable |= 4; -+ } -+ -+ OSUnMapPhysToLin(pui32TimerEnable, -+ 4, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ hTimerEnable); -+ -+ /* Enable the timer */ -+ sTimerRegPhysBase.uiAddr = SYS_OMAP_GP11TIMER_ENABLE_SYS_PHYS_BASE; -+ pui32TimerEnable = OSMapPhysToLin(sTimerRegPhysBase, -+ 4, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ &hTimerEnable); -+ -+ if (pui32TimerEnable == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: OSMapPhysToLin failed")); -+ goto ExitDisableGPT11ICK; -+ } -+ -+ /* Enable and set autoreload on overflow */ -+ *pui32TimerEnable = 3; -+ -+ OSUnMapPhysToLin(pui32TimerEnable, -+ 4, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ hTimerEnable); -+ -+ psSysSpecData->sTimerRegPhysBase = sTimerRegPhysBase; -+ -+ eError = PVRSRV_OK; -+ -+ goto Exit; -+ -+ExitDisableGPT11ICK: -+#if defined(PVR_OMAP4_TIMING_PRCM) -+ clk_disable(psSysSpecData->psGPT11_ICK); -+ExitDisableGPT11FCK: -+ clk_disable(psSysSpecData->psGPT11_FCK); -+ExitError: -+#endif /* defined(PVR_OMAP4_TIMING_PRCM) */ -+ eError = PVRSRV_ERROR_CLOCK_REQUEST_FAILED; -+Exit: -+ return eError; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function ReleaseGPTimer -+ -+ @Description Release a GP timer -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+static void ReleaseGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ IMG_HANDLE hTimerDisable; -+ IMG_UINT32 *pui32TimerDisable; -+ -+ if (psSysSpecData->sTimerRegPhysBase.uiAddr == 0) -+ { -+ return; -+ } -+ -+ /* Disable the timer */ -+ pui32TimerDisable = OSMapPhysToLin(psSysSpecData->sTimerRegPhysBase, -+ 4, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ &hTimerDisable); -+ -+ if (pui32TimerDisable == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "DisableSystemClocks: OSMapPhysToLin failed")); -+ } -+ else -+ { -+ *pui32TimerDisable = 0; -+ -+ OSUnMapPhysToLin(pui32TimerDisable, -+ 4, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ hTimerDisable); -+ } -+ -+ psSysSpecData->sTimerRegPhysBase.uiAddr = 0; -+ -+#if defined(PVR_OMAP4_TIMING_PRCM) -+ clk_disable(psSysSpecData->psGPT11_ICK); -+ -+ clk_disable(psSysSpecData->psGPT11_FCK); -+#endif /* defined(PVR_OMAP4_TIMING_PRCM) */ -+} -+#endif /* PVR_OMAP_USE_DM_TIMER_API */ -+#else /* (DEBUG || TIMING) && !PVR_NO_OMAP_TIMER */ -+static PVRSRV_ERROR AcquireGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ PVR_UNREFERENCED_PARAMETER(psSysSpecData); -+ -+ return PVRSRV_OK; -+} -+static void ReleaseGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ PVR_UNREFERENCED_PARAMETER(psSysSpecData); -+} -+#endif /* (DEBUG || TIMING) && !PVR_NO_OMAP_TIMER */ -+ -+/*! -+****************************************************************************** -+ -+ @Function EnableSystemClocks -+ -+ @Description Setup up the clocks for the graphics device to work. -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData) -+{ -+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; -+ -+ PVR_TRACE(("EnableSystemClocks: Enabling System Clocks")); -+ -+ if (!psSysSpecData->bSysClocksOneTimeInit) -+ { -+ mutex_init(&psSysSpecData->sPowerLock); -+ -+ atomic_set(&psSysSpecData->sSGXClocksEnabled, 0); -+ -+ psSysSpecData->bSysClocksOneTimeInit = IMG_TRUE; -+ } -+ -+ return AcquireGPTimer(psSysSpecData); -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function DisableSystemClocks -+ -+ @Description Disable the graphics clocks. -+ -+ @Return none -+ -+******************************************************************************/ -+IMG_VOID DisableSystemClocks(SYS_DATA *psSysData) -+{ -+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; -+ -+ PVR_TRACE(("DisableSystemClocks: Disabling System Clocks")); -+ -+ /* -+ * Always disable the SGX clocks when the system clocks are disabled. -+ * This saves having to make an explicit call to DisableSGXClocks if -+ * active power management is enabled. -+ */ -+ DisableSGXClocks(psSysData); -+ -+ ReleaseGPTimer(psSysSpecData); -+} -+ -+PVRSRV_ERROR SysPMRuntimeRegister(void) -+{ -+#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) -+ pm_runtime_enable(&gpsPVRLDMDev->dev); -+#endif -+ return PVRSRV_OK; -+} -+ -+PVRSRV_ERROR SysPMRuntimeUnregister(void) -+{ -+#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) -+ pm_runtime_disable(&gpsPVRLDMDev->dev); -+#endif -+ return PVRSRV_OK; -+} -+ -+PVRSRV_ERROR SysDvfsInitialize(SYS_SPECIFIC_DATA *psSysSpecificData) -+{ -+#if !defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) -+ PVR_UNREFERENCED_PARAMETER(psSysSpecificData); -+#else /* !defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) */ -+ IMG_UINT32 i, *freq_list; -+ IMG_INT32 opp_count; -+ unsigned long freq; -+ struct opp *opp; -+ -+ /* -+ * We query and store the list of SGX frequencies just this once under the -+ * assumption that they are unchanging, e.g. no disabling of high frequency -+ * option for thermal management. This is currently valid for 4430 and 4460. -+ */ -+ rcu_read_lock(); -+ opp_count = opp_get_opp_count(&gpsPVRLDMDev->dev); -+ if (opp_count < 1) -+ { -+ rcu_read_unlock(); -+ PVR_DPF((PVR_DBG_ERROR, "SysDvfsInitialize: Could not retrieve opp count")); -+ return PVRSRV_ERROR_NOT_SUPPORTED; -+ } -+ -+ /* -+ * Allocate the frequency list with a slot for each available frequency plus -+ * one additional slot to hold a designated frequency value to assume when in -+ * an unknown frequency state. -+ */ -+ freq_list = kmalloc((opp_count + 1) * sizeof(IMG_UINT32), GFP_ATOMIC); -+ if (!freq_list) -+ { -+ rcu_read_unlock(); -+ PVR_DPF((PVR_DBG_ERROR, "SysDvfsInitialize: Could not allocate frequency list")); -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ -+ /* -+ * Fill in frequency list from lowest to highest then finally the "unknown" -+ * frequency value. We use the highest available frequency as our assumed value -+ * when in an unknown state, because it is safer for APM and hardware recovery -+ * timers to be longer than intended rather than shorter. -+ */ -+ freq = 0; -+ for (i = 0; i < opp_count; i++) -+ { -+ opp = opp_find_freq_ceil(&gpsPVRLDMDev->dev, &freq); -+ if (IS_ERR_OR_NULL(opp)) -+ { -+ rcu_read_unlock(); -+ PVR_DPF((PVR_DBG_ERROR, "SysDvfsInitialize: Could not retrieve opp level %d", i)); -+ kfree(freq_list); -+ return PVRSRV_ERROR_NOT_SUPPORTED; -+ } -+ freq_list[i] = (IMG_UINT32)freq; -+ freq++; -+ } -+ rcu_read_unlock(); -+ freq_list[opp_count] = freq_list[opp_count - 1]; -+ -+ psSysSpecificData->ui32SGXFreqListSize = opp_count + 1; -+ psSysSpecificData->pui32SGXFreqList = freq_list; -+ -+ /* Start in unknown state - no frequency request to DVFS yet made */ -+ psSysSpecificData->ui32SGXFreqListIndex = opp_count; -+#endif /* !defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) */ -+ -+ return PVRSRV_OK; -+} -+ -+PVRSRV_ERROR SysDvfsDeinitialize(SYS_SPECIFIC_DATA *psSysSpecificData) -+{ -+#if !defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) -+ PVR_UNREFERENCED_PARAMETER(psSysSpecificData); -+#else /* !defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) */ -+ /* -+ * We assume this function is only called if SysDvfsInitialize() was -+ * completed successfully before. -+ * -+ * The DVFS interface does not allow us to actually unregister as a -+ * user of SGX, so we do the next best thing which is to lower our -+ * required frequency to the minimum if not already set. DVFS may -+ * report busy if early in initialization, but all other errors are -+ * considered serious. -+ */ -+ if (psSysSpecificData->ui32SGXFreqListIndex != 0) -+ { -+ struct gpu_platform_data *pdata; -+ IMG_INT32 res; -+ -+ pdata = (struct gpu_platform_data *)gpsPVRLDMDev->dev.platform_data; -+ -+ PVR_ASSERT(pdata->device_scale != IMG_NULL); -+ res = pdata->device_scale(&gpsPVRLDMDev->dev, -+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3,4,0)) -+ &gpsPVRLDMDev->dev, -+#endif -+ psSysSpecificData->pui32SGXFreqList[0]); -+ if (res == -EBUSY) -+ { -+ PVR_DPF((PVR_DBG_WARNING, "SysDvfsDeinitialize: Unable to scale SGX frequency (EBUSY)")); -+ } -+ else if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SysDvfsDeinitialize: Unable to scale SGX frequency (%d)", res)); -+ } -+ -+ psSysSpecificData->ui32SGXFreqListIndex = 0; -+ } -+ -+ kfree(psSysSpecificData->pui32SGXFreqList); -+ psSysSpecificData->pui32SGXFreqList = 0; -+ psSysSpecificData->ui32SGXFreqListSize = 0; -+#endif /* !defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) */ -+ -+ return PVRSRV_OK; -+} -+ -+#if defined(SUPPORT_DRI_DRM_PLUGIN) -+static struct omap_gpu_plugin sOMAPGPUPlugin; -+ -+#define SYS_DRM_SET_PLUGIN_FIELD(d, s, f) (d)->f = (s)->f -+int -+SysDRMRegisterPlugin(PVRSRV_DRM_PLUGIN *psDRMPlugin) -+{ -+ int iRes; -+ -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, name); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, open); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, load); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, unload); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, release); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, mmap); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, ioctls); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, num_ioctls); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, ioctl_start); -+ -+ iRes = omap_gpu_register_plugin(&sOMAPGPUPlugin); -+ if (iRes != 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: omap_gpu_register_plugin failed (%d)", __FUNCTION__, iRes)); -+ } -+ -+ return iRes; -+} -+ -+void -+SysDRMUnregisterPlugin(PVRSRV_DRM_PLUGIN *psDRMPlugin) -+{ -+ int iRes = omap_gpu_unregister_plugin(&sOMAPGPUPlugin); -+ if (iRes != 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: omap_gpu_unregister_plugin failed (%d)", __FUNCTION__, iRes)); -+ } -+} -+#endif -diff --git a/drivers/staging/ti-es8-sgx/services4/system/omap3/oemfuncs.h b/drivers/staging/ti-es8-sgx/services4/system/omap3/oemfuncs.h -new file mode 100644 -index 0000000..77c70d6 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/omap3/oemfuncs.h -@@ -0,0 +1,78 @@ -+/*************************************************************************/ /*! -+@Title SGX kernel/client driver interface structures and prototypes -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#if !defined(__OEMFUNCS_H__) -+#define __OEMFUNCS_H__ -+ -+#if defined (__cplusplus) -+extern "C" { -+#endif -+ -+/* function in/out data structures: */ -+typedef IMG_UINT32 (*PFN_SRV_BRIDGEDISPATCH)( IMG_UINT32 Ioctl, -+ IMG_BYTE *pInBuf, -+ IMG_UINT32 InBufLen, -+ IMG_BYTE *pOutBuf, -+ IMG_UINT32 OutBufLen, -+ IMG_UINT32 *pdwBytesTransferred); -+/* -+ Function table for kernel 3rd party driver to kernel services -+*/ -+typedef struct PVRSRV_DC_OEM_JTABLE_TAG -+{ -+ PFN_SRV_BRIDGEDISPATCH pfnOEMBridgeDispatch; -+ IMG_PVOID pvDummy1; -+ IMG_PVOID pvDummy2; -+ IMG_PVOID pvDummy3; -+ -+} PVRSRV_DC_OEM_JTABLE; -+ -+#define OEM_GET_EXT_FUNCS (1<<1) -+ -+#if defined(__cplusplus) -+} -+#endif -+ -+#endif /* __OEMFUNCS_H__ */ -+ -+/***************************************************************************** -+ End of file (oemfuncs.h) -+*****************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/system/omap3/sysconfig.c b/drivers/staging/ti-es8-sgx/services4/system/omap3/sysconfig.c -new file mode 100644 -index 0000000..5f0e9c8 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/omap3/sysconfig.c -@@ -0,0 +1,1274 @@ -+/*************************************************************************/ /*! -+@Title System Configuration -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description System Configuration functions -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#include "sysconfig.h" -+#include "services_headers.h" -+#include "kerneldisplay.h" -+#include "oemfuncs.h" -+#include "sgxinfo.h" -+#include "sgxinfokm.h" -+#include "syslocal.h" -+ -+#include "ocpdefs.h" -+ -+/* top level system data anchor point*/ -+SYS_DATA* gpsSysData = (SYS_DATA*)IMG_NULL; -+SYS_DATA gsSysData; -+ -+static SYS_SPECIFIC_DATA gsSysSpecificData; -+SYS_SPECIFIC_DATA *gpsSysSpecificData; -+ -+/* SGX structures */ -+static IMG_UINT32 gui32SGXDeviceID; -+static SGX_DEVICE_MAP gsSGXDeviceMap; -+static PVRSRV_DEVICE_NODE *gpsSGXDevNode; -+ -+ -+#if defined(NO_HARDWARE) || defined(SGX_OCP_REGS_ENABLED) -+static IMG_CPU_VIRTADDR gsSGXRegsCPUVAddr; -+#endif -+ -+#if defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO) -+extern struct platform_device *gpsPVRLDMDev; -+#endif -+ -+IMG_UINT32 PVRSRV_BridgeDispatchKM(IMG_UINT32 Ioctl, -+ IMG_BYTE *pInBuf, -+ IMG_UINT32 InBufLen, -+ IMG_BYTE *pOutBuf, -+ IMG_UINT32 OutBufLen, -+ IMG_UINT32 *pdwBytesTransferred); -+ -+#if defined(SGX_OCP_REGS_ENABLED) -+ -+static IMG_CPU_VIRTADDR gpvOCPRegsLinAddr; -+ -+static PVRSRV_ERROR EnableSGXClocksWrap(SYS_DATA *psSysData) -+{ -+ PVRSRV_ERROR eError = EnableSGXClocks(psSysData); -+ -+#if !defined(SGX_OCP_NO_INT_BYPASS) -+ if(eError == PVRSRV_OK) -+ { -+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_SYSCONFIG, 0x14); -+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_DEBUG_CONFIG, EUR_CR_OCP_DEBUG_CONFIG_THALIA_INT_BYPASS_MASK); -+ } -+#endif -+ return eError; -+} -+ -+#else /* defined(SGX_OCP_REGS_ENABLED) */ -+ -+static INLINE PVRSRV_ERROR EnableSGXClocksWrap(SYS_DATA *psSysData) -+{ -+ return EnableSGXClocks(psSysData); -+} -+ -+#endif /* defined(SGX_OCP_REGS_ENABLED) */ -+ -+static INLINE PVRSRV_ERROR EnableSystemClocksWrap(SYS_DATA *psSysData) -+{ -+ PVRSRV_ERROR eError = EnableSystemClocks(psSysData); -+ -+#if !defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ if(eError == PVRSRV_OK) -+ { -+ /* -+ * The SGX Clocks are enabled separately if active power -+ * management is enabled. -+ */ -+ eError = EnableSGXClocksWrap(psSysData); -+ if (eError != PVRSRV_OK) -+ { -+ DisableSystemClocks(psSysData); -+ } -+ } -+#endif -+ -+ return eError; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function SysLocateDevices -+ -+ @Description Specifies devices in the systems memory map -+ -+ @Input psSysData - sys data -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+static PVRSRV_ERROR SysLocateDevices(SYS_DATA *psSysData) -+{ -+#if defined(NO_HARDWARE) -+ PVRSRV_ERROR eError; -+ IMG_CPU_PHYADDR sCpuPAddr; -+#else -+#if defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO) -+ struct resource *dev_res; -+ int dev_irq; -+#endif -+#endif -+ -+ PVR_UNREFERENCED_PARAMETER(psSysData); -+ -+ /* SGX Device: */ -+ gsSGXDeviceMap.ui32Flags = 0x0; -+ -+#if defined(NO_HARDWARE) -+ /* -+ * For no hardware, allocate some contiguous memory for the -+ * register block. -+ */ -+ -+ /* Registers */ -+ gsSGXDeviceMap.ui32RegsSize = SYS_OMAP3430_SGX_REGS_SIZE; -+ -+ eError = OSBaseAllocContigMemory(gsSGXDeviceMap.ui32RegsSize, -+ &gsSGXRegsCPUVAddr, -+ &sCpuPAddr); -+ if(eError != PVRSRV_OK) -+ { -+ return eError; -+ } -+ gsSGXDeviceMap.sRegsCpuPBase = sCpuPAddr; -+ gsSGXDeviceMap.sRegsSysPBase = SysCpuPAddrToSysPAddr(gsSGXDeviceMap.sRegsCpuPBase); -+#if defined(__linux__) -+ /* Indicate the registers are already mapped */ -+ gsSGXDeviceMap.pvRegsCpuVBase = gsSGXRegsCPUVAddr; -+#else -+ /* -+ * FIXME: Could we just use the virtual address returned by -+ * OSBaseAllocContigMemory? -+ */ -+ gsSGXDeviceMap.pvRegsCpuVBase = IMG_NULL; -+#endif -+ -+ OSMemSet(gsSGXRegsCPUVAddr, 0, gsSGXDeviceMap.ui32RegsSize); -+ -+ /* -+ device interrupt IRQ -+ Note: no interrupts available on no hardware system -+ */ -+ gsSGXDeviceMap.ui32IRQ = 0; -+ -+#else /* defined(NO_HARDWARE) */ -+#if defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO) -+ /* get the resource and IRQ through platform resource API */ -+ dev_res = platform_get_resource(gpsPVRLDMDev, IORESOURCE_MEM, 0); -+ if (dev_res == NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: platform_get_resource failed", __FUNCTION__)); -+ return PVRSRV_ERROR_INVALID_DEVICE; -+ } -+ -+ dev_irq = platform_get_irq(gpsPVRLDMDev, 0); -+ if (dev_irq < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: platform_get_irq failed (%d)", __FUNCTION__, -dev_irq)); -+ return PVRSRV_ERROR_INVALID_DEVICE; -+ } -+ -+ gsSGXDeviceMap.sRegsSysPBase.uiAddr = dev_res->start; -+ gsSGXDeviceMap.sRegsCpuPBase = -+ SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sRegsSysPBase); -+ PVR_TRACE(("SGX register base: 0x%lx", (unsigned long)gsSGXDeviceMap.sRegsCpuPBase.uiAddr)); -+ -+#if defined(SGX544) && defined(SGX_FEATURE_MP) -+ /* FIXME: Workaround due to HWMOD change. Otherwise this region is too small. */ -+ gsSGXDeviceMap.ui32RegsSize = SYS_OMAP3430_SGX_REGS_SIZE; -+#else -+ gsSGXDeviceMap.ui32RegsSize = (unsigned int)(dev_res->end - dev_res->start); -+#endif -+ PVR_TRACE(("SGX register size: %d",gsSGXDeviceMap.ui32RegsSize)); -+ -+ gsSGXDeviceMap.ui32IRQ = dev_irq; -+ PVR_TRACE(("SGX IRQ: %d", gsSGXDeviceMap.ui32IRQ)); -+#else /* defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO) */ -+ gsSGXDeviceMap.sRegsSysPBase.uiAddr = SYS_OMAP3430_SGX_REGS_SYS_PHYS_BASE; -+ gsSGXDeviceMap.sRegsCpuPBase = SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sRegsSysPBase); -+ gsSGXDeviceMap.ui32RegsSize = SYS_OMAP3430_SGX_REGS_SIZE; -+ -+ gsSGXDeviceMap.ui32IRQ = SYS_OMAP3430_SGX_IRQ; -+ -+#endif /* defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO) */ -+#if defined(SGX_OCP_REGS_ENABLED) -+ gsSGXRegsCPUVAddr = OSMapPhysToLin(gsSGXDeviceMap.sRegsCpuPBase, -+ gsSGXDeviceMap.ui32RegsSize, -+ PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY, -+ IMG_NULL); -+ -+ if (gsSGXRegsCPUVAddr == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysLocateDevices: Failed to map SGX registers")); -+ return PVRSRV_ERROR_BAD_MAPPING; -+ } -+ -+ /* Indicate the registers are already mapped */ -+ gsSGXDeviceMap.pvRegsCpuVBase = gsSGXRegsCPUVAddr; -+ gpvOCPRegsLinAddr = gsSGXRegsCPUVAddr; -+#endif -+#endif /* defined(NO_HARDWARE) */ -+ -+#if defined(PDUMP) -+ { -+ /* initialise memory region name for pdumping */ -+ static IMG_CHAR pszPDumpDevName[] = "SGXMEM"; -+ gsSGXDeviceMap.pszPDumpDevName = pszPDumpDevName; -+ } -+#endif -+ -+ /* add other devices here: */ -+ -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysCreateVersionString -+ -+ @Description Read the version string -+ -+ @Return IMG_CHAR * : Version string -+ -+******************************************************************************/ -+static IMG_CHAR *SysCreateVersionString(void) -+{ -+ static IMG_CHAR aszVersionString[100]; -+ IMG_UINT32 ui32MaxStrLen; -+ SYS_DATA *psSysData; -+ IMG_UINT32 ui32SGXRevision; -+ IMG_INT32 i32Count; -+ -+ SysAcquireData(&psSysData); -+ -+ ui32SGXRevision = SGX_CORE_REV; -+ ui32MaxStrLen = 99; -+ -+ i32Count = OSSNPrintf(aszVersionString, ui32MaxStrLen + 1, -+ "SGX revision = %u", -+ (IMG_UINT)(ui32SGXRevision)); -+ if(i32Count == -1) -+ { -+ return IMG_NULL; -+ } -+ -+ return aszVersionString; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysInitialise -+ -+ @Description Initialises kernel services at 'driver load' time -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+PVRSRV_ERROR SysInitialise(IMG_VOID) -+{ -+ IMG_UINT32 i; -+ PVRSRV_ERROR eError; -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+#if !defined(PVR_NO_OMAP_TIMER) -+ IMG_CPU_PHYADDR TimerRegPhysBase; -+#endif -+#if !defined(SGX_DYNAMIC_TIMING_INFO) -+ SGX_TIMING_INFORMATION* psTimingInfo; -+#endif -+ gpsSysData = &gsSysData; -+ OSMemSet(gpsSysData, 0, sizeof(SYS_DATA)); -+ -+ gpsSysSpecificData = &gsSysSpecificData; -+ OSMemSet(gpsSysSpecificData, 0, sizeof(SYS_SPECIFIC_DATA)); -+ -+ gpsSysData->pvSysSpecificData = gpsSysSpecificData; -+ -+ eError = OSInitEnvData(&gpsSysData->pvEnvSpecificData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to setup env structure")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_ENVDATA); -+ -+ gpsSysData->ui32NumDevices = SYS_DEVICE_COUNT; -+ -+ /* init device ID's */ -+ for(i=0; i<SYS_DEVICE_COUNT; i++) -+ { -+ gpsSysData->sDeviceID[i].uiID = i; -+ gpsSysData->sDeviceID[i].bInUse = IMG_FALSE; -+ } -+ -+ gpsSysData->psDeviceNodeList = IMG_NULL; -+ gpsSysData->psQueueList = IMG_NULL; -+ -+ eError = SysInitialiseCommon(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed in SysInitialiseCommon")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ -+#if !defined(SGX_DYNAMIC_TIMING_INFO) -+ /* Set up timing information*/ -+ psTimingInfo = &gsSGXDeviceMap.sTimingInfo; -+ psTimingInfo->ui32CoreClockSpeed = SYS_SGX_CLOCK_SPEED; -+ psTimingInfo->ui32HWRecoveryFreq = SYS_SGX_HWRECOVERY_TIMEOUT_FREQ; -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ psTimingInfo->bEnableActivePM = IMG_TRUE; -+#else -+ psTimingInfo->bEnableActivePM = IMG_FALSE; -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ psTimingInfo->ui32ActivePowManLatencyms = SYS_SGX_ACTIVE_POWER_LATENCY_MS; -+ psTimingInfo->ui32uKernelFreq = SYS_SGX_PDS_TIMER_FREQ; -+#endif -+ -+ /* -+ Setup the Source Clock Divider value -+ */ -+ gpsSysSpecificData->ui32SrcClockDiv = 3; -+ -+ /* -+ Locate the devices within the system, specifying -+ the physical addresses of each devices components -+ (regs, mem, ports etc.) -+ */ -+ eError = SysLocateDevices(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to locate devices")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV); -+ -+ eError = SysPMRuntimeRegister(); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to register with OSPM!")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_PM_RUNTIME); -+ -+ eError = SysDvfsInitialize(gpsSysSpecificData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to initialize DVFS")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_DVFS_INIT); -+ -+ /* -+ Register devices with the system -+ This also sets up their memory maps/heaps -+ */ -+ eError = PVRSRVRegisterDevice(gpsSysData, SGXRegisterDevice, -+ DEVICE_SGX_INTERRUPT, &gui32SGXDeviceID); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to register device!")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_REGDEV); -+ -+ /* -+ Once all devices are registered, specify the backing store -+ and, if required, customise the memory heap config -+ */ -+ psDeviceNode = gpsSysData->psDeviceNodeList; -+ while(psDeviceNode) -+ { -+ /* perform any OEM SOC address space customisations here */ -+ switch(psDeviceNode->sDevId.eDeviceType) -+ { -+ case PVRSRV_DEVICE_TYPE_SGX: -+ { -+ DEVICE_MEMORY_INFO *psDevMemoryInfo; -+ DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; -+ -+ /* -+ specify the backing store to use for the devices MMU PT/PDs -+ - the PT/PDs are always UMA in this system -+ */ -+ psDeviceNode->psLocalDevMemArena = IMG_NULL; -+ -+ /* useful pointers */ -+ psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo; -+ psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap; -+ -+ /* specify the backing store for all SGX heaps */ -+ for(i=0; i<psDevMemoryInfo->ui32HeapCount; i++) -+ { -+ psDeviceMemoryHeap[i].ui32Attribs |= PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG; -+ } -+ -+ gpsSGXDevNode = psDeviceNode; -+ gsSysSpecificData.psSGXDevNode = psDeviceNode; -+ -+ break; -+ } -+ default: -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to find SGX device node!")); -+ return PVRSRV_ERROR_INIT_FAILURE; -+ } -+ -+ /* advance to next device */ -+ psDeviceNode = psDeviceNode->psNext; -+ } -+ -+ eError = EnableSystemClocksWrap(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable system clocks (%d)", eError)); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS); -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ eError = EnableSGXClocksWrap(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable SGX clocks (%d)", eError)); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ -+ eError = PVRSRVInitialiseDevice(gui32SGXDeviceID); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to initialise device!")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_INITDEV); -+ -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ /* SGX defaults to D3 power state */ -+ DisableSGXClocks(gpsSysData); -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ -+#if !defined(PVR_NO_OMAP_TIMER) -+#if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA) -+ TimerRegPhysBase = gsSysSpecificData.sTimerRegPhysBase; -+#else -+ TimerRegPhysBase.uiAddr = SYS_OMAP3430_GP11TIMER_REGS_SYS_PHYS_BASE; -+#endif -+ gpsSysData->pvSOCTimerRegisterKM = IMG_NULL; -+ gpsSysData->hSOCTimerRegisterOSMemHandle = 0; -+ if (TimerRegPhysBase.uiAddr != 0) -+ { -+ OSReservePhys(TimerRegPhysBase, -+ 4, -+ PVRSRV_HAP_MULTI_PROCESS|PVRSRV_HAP_UNCACHED, -+ IMG_NULL, -+ (IMG_VOID **)&gpsSysData->pvSOCTimerRegisterKM, -+ &gpsSysData->hSOCTimerRegisterOSMemHandle); -+ } -+#endif /* !defined(PVR_NO_OMAP_TIMER) */ -+ -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysFinalise -+ -+ @Description Final part of initialisation at 'driver load' time -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+PVRSRV_ERROR SysFinalise(IMG_VOID) -+{ -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ eError = EnableSGXClocksWrap(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to Enable SGX clocks (%d)", eError)); -+ return eError; -+ } -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ -+ eError = OSInstallMISR(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to install MISR")); -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_MISR); -+ -+#if defined(SYS_USING_INTERRUPTS) -+ /* install a Device ISR */ -+ eError = OSInstallDeviceLISR(gpsSysData, gsSGXDeviceMap.ui32IRQ, "SGX ISR", gpsSGXDevNode); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to install ISR")); -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR); -+#if !defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ SysEnableSGXInterrupts(gpsSysData); -+#endif -+#endif /* defined(SYS_USING_INTERRUPTS) */ -+#if defined(__linux__) -+ /* Create a human readable version string for this system */ -+ gpsSysData->pszVersionString = SysCreateVersionString(); -+ if (!gpsSysData->pszVersionString) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to create a system version string")); -+ } -+ else -+ { -+ PVR_TRACE(("SysFinalise: Version string: %s", gpsSysData->pszVersionString)); -+ } -+#endif -+ -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ /* SGX defaults to D3 power state */ -+ DisableSGXClocks(gpsSysData); -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ -+ gpsSysSpecificData->bSGXInitComplete = IMG_TRUE; -+ -+ return eError; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysDeinitialise -+ -+ @Description De-initialises kernel services at 'driver unload' time -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR SysDeinitialise (SYS_DATA *psSysData) -+{ -+ PVRSRV_ERROR eError; -+ -+ PVR_UNREFERENCED_PARAMETER(psSysData); -+ -+ if(gpsSysData->pvSOCTimerRegisterKM) -+ { -+ OSUnReservePhys(gpsSysData->pvSOCTimerRegisterKM, -+ 4, -+ PVRSRV_HAP_MULTI_PROCESS|PVRSRV_HAP_UNCACHED, -+ gpsSysData->hSOCTimerRegisterOSMemHandle); -+ } -+ -+ -+#if defined(SYS_USING_INTERRUPTS) -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR)) -+ { -+ eError = OSUninstallDeviceLISR(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: OSUninstallDeviceLISR failed")); -+ return eError; -+ } -+ } -+#endif -+ -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_MISR)) -+ { -+ eError = OSUninstallMISR(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: OSUninstallMISR failed")); -+ return eError; -+ } -+ } -+ -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_INITDEV)) -+ { -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ PVR_ASSERT(SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS)); -+ /* Reenable SGX clocks whilst SGX is being deinitialised. */ -+ eError = EnableSGXClocksWrap(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: EnableSGXClocks failed")); -+ return eError; -+ } -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ -+ /* Deinitialise SGX */ -+ eError = PVRSRVDeinitialiseDevice(gui32SGXDeviceID); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: failed to de-init the device")); -+ return eError; -+ } -+ } -+ -+ /* Disable system clocks. Must happen after last access to hardware */ -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS)) -+ { -+ DisableSystemClocks(gpsSysData); -+ } -+ -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_DVFS_INIT)) -+ { -+ eError = SysDvfsDeinitialize(gpsSysSpecificData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: Failed to de-init DVFS")); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ } -+ -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_PM_RUNTIME)) -+ { -+ eError = SysPMRuntimeUnregister(); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: Failed to unregister with OSPM!")); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ } -+ -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_ENVDATA)) -+ { -+ eError = OSDeInitEnvData(gpsSysData->pvEnvSpecificData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: failed to de-init env structure")); -+ return eError; -+ } -+ } -+ -+ SysDeinitialiseCommon(gpsSysData); -+ -+#if defined(NO_HARDWARE) || defined(SGX_OCP_REGS_ENABLED) -+ if(gsSGXRegsCPUVAddr != IMG_NULL) -+ { -+#if defined(NO_HARDWARE) -+ /* Free hardware resources. */ -+ OSBaseFreeContigMemory(SYS_OMAP3430_SGX_REGS_SIZE, gsSGXRegsCPUVAddr, gsSGXDeviceMap.sRegsCpuPBase); -+#else -+#if defined(SGX_OCP_REGS_ENABLED) -+ OSUnMapPhysToLin(gsSGXRegsCPUVAddr, -+ gsSGXDeviceMap.ui32RegsSize, -+ PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY, -+ IMG_NULL); -+ -+ gpvOCPRegsLinAddr = IMG_NULL; -+#endif -+#endif /* defined(NO_HARDWARE) */ -+ gsSGXRegsCPUVAddr = IMG_NULL; -+ gsSGXDeviceMap.pvRegsCpuVBase = gsSGXRegsCPUVAddr; -+ } -+#endif /* defined(NO_HARDWARE) || defined(SGX_OCP_REGS_ENABLED) */ -+ -+ -+ gpsSysSpecificData->ui32SysSpecificData = 0; -+ gpsSysSpecificData->bSGXInitComplete = IMG_FALSE; -+ -+ gpsSysData = IMG_NULL; -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysGetDeviceMemoryMap -+ -+ @Description returns a device address map for the specified device -+ -+ @Input eDeviceType - device type -+ @Input ppvDeviceMap - void ptr to receive device specific info. -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE eDeviceType, -+ IMG_VOID **ppvDeviceMap) -+{ -+ -+ switch(eDeviceType) -+ { -+ case PVRSRV_DEVICE_TYPE_SGX: -+ { -+ /* just return a pointer to the structure */ -+ *ppvDeviceMap = (IMG_VOID*)&gsSGXDeviceMap; -+ -+ break; -+ } -+ default: -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysGetDeviceMemoryMap: unsupported device type")); -+ } -+ } -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function SysCpuPAddrToDevPAddr -+ -+ @Description Compute a device physical address from a cpu physical -+ address. Relevant when -+ -+ @Input cpu_paddr - cpu physical address. -+ @Input eDeviceType - device type required if DevPAddr -+ address spaces vary across devices -+ in the same system -+ @Return device physical address. -+ -+******************************************************************************/ -+IMG_DEV_PHYADDR SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType, -+ IMG_CPU_PHYADDR CpuPAddr) -+{ -+ IMG_DEV_PHYADDR DevPAddr; -+ -+ PVR_UNREFERENCED_PARAMETER(eDeviceType); -+ -+ /* Note: for UMA system we assume DevP == CpuP */ -+ DevPAddr.uiAddr = CpuPAddr.uiAddr; -+ -+ return DevPAddr; -+} -+ -+/*! -+****************************************************************************** -+ @Function SysSysPAddrToCpuPAddr -+ -+ @Description Compute a cpu physical address from a system physical -+ address. -+ -+ @Input sys_paddr - system physical address. -+ @Return cpu physical address. -+ -+******************************************************************************/ -+IMG_CPU_PHYADDR SysSysPAddrToCpuPAddr (IMG_SYS_PHYADDR sys_paddr) -+{ -+ IMG_CPU_PHYADDR cpu_paddr; -+ -+ /* This would only be an inequality if the CPU's MMU did not point to -+ sys address 0, ie. multi CPU system */ -+ cpu_paddr.uiAddr = sys_paddr.uiAddr; -+ return cpu_paddr; -+} -+ -+/*! -+****************************************************************************** -+ @Function SysCpuPAddrToSysPAddr -+ -+ @Description Compute a system physical address from a cpu physical -+ address. -+ -+ @Input cpu_paddr - cpu physical address. -+ @Return device physical address. -+ -+******************************************************************************/ -+IMG_SYS_PHYADDR SysCpuPAddrToSysPAddr (IMG_CPU_PHYADDR cpu_paddr) -+{ -+ IMG_SYS_PHYADDR sys_paddr; -+ -+ /* This would only be an inequality if the CPU's MMU did not point to -+ sys address 0, ie. multi CPU system */ -+ sys_paddr.uiAddr = cpu_paddr.uiAddr; -+ return sys_paddr; -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function SysSysPAddrToDevPAddr -+ -+ @Description Compute a device physical address from a system physical -+ address. -+ -+ @Input SysPAddr - system physical address. -+ @Input eDeviceType - device type required if DevPAddr -+ address spaces vary across devices -+ in the same system -+ -+ @Return Device physical address. -+ -+******************************************************************************/ -+IMG_DEV_PHYADDR SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType, IMG_SYS_PHYADDR SysPAddr) -+{ -+ IMG_DEV_PHYADDR DevPAddr; -+ -+ PVR_UNREFERENCED_PARAMETER(eDeviceType); -+ -+ /* Note: for UMA system we assume DevP == CpuP */ -+ DevPAddr.uiAddr = SysPAddr.uiAddr; -+ -+ return DevPAddr; -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function SysDevPAddrToSysPAddr -+ -+ @Description Compute a device physical address from a system physical -+ address. -+ -+ @Input DevPAddr - device physical address. -+ @Input eDeviceType - device type required if DevPAddr -+ address spaces vary across devices -+ in the same system -+ -+ @Return System physical address. -+ -+******************************************************************************/ -+IMG_SYS_PHYADDR SysDevPAddrToSysPAddr(PVRSRV_DEVICE_TYPE eDeviceType, IMG_DEV_PHYADDR DevPAddr) -+{ -+ IMG_SYS_PHYADDR SysPAddr; -+ -+ PVR_UNREFERENCED_PARAMETER(eDeviceType); -+ -+ /* Note: for UMA system we assume DevP == SysP */ -+ SysPAddr.uiAddr = DevPAddr.uiAddr; -+ -+ return SysPAddr; -+} -+ -+ -+/***************************************************************************** -+ @Function SysRegisterExternalDevice -+ -+ @Description Called when a 3rd party device registers with services -+ -+ @Input psDeviceNode - the new device node. -+ -+ @Return IMG_VOID -+*****************************************************************************/ -+IMG_VOID SysRegisterExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode) -+{ -+ PVR_UNREFERENCED_PARAMETER(psDeviceNode); -+} -+ -+ -+/***************************************************************************** -+ @Function SysRemoveExternalDevice -+ -+ @Description Called when a 3rd party device unregisters from services -+ -+ @Input psDeviceNode - the device node being removed. -+ -+ @Return IMG_VOID -+*****************************************************************************/ -+IMG_VOID SysRemoveExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode) -+{ -+ PVR_UNREFERENCED_PARAMETER(psDeviceNode); -+} -+ -+/*! -+****************************************************************************** -+ @Function SysGetInterruptSource -+ -+ @Description Returns System specific information about the device(s) that -+ generated the interrupt in the system -+ -+ @Input psSysData -+ @Input psDeviceNode -+ -+ @Return System specific information indicating which device(s) -+ generated the interrupt -+ -+******************************************************************************/ -+IMG_UINT32 SysGetInterruptSource(SYS_DATA *psSysData, -+ PVRSRV_DEVICE_NODE *psDeviceNode) -+{ -+ PVR_UNREFERENCED_PARAMETER(psSysData); -+#if defined(NO_HARDWARE) -+ /* no interrupts in no_hw system just return all bits */ -+ return 0xFFFFFFFF; -+#else -+ /* Not a shared irq, so we know this is an interrupt for this device */ -+ return psDeviceNode->ui32SOCInterruptBit; -+#endif -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function SysClearInterrupts -+ -+ @Description Clears specified system interrupts -+ -+ @Input psSysData -+ @Input ui32ClearBits -+ -+ @Return IMG_VOID -+ -+******************************************************************************/ -+IMG_VOID SysClearInterrupts(SYS_DATA* psSysData, IMG_UINT32 ui32ClearBits) -+{ -+ PVR_UNREFERENCED_PARAMETER(ui32ClearBits); -+ PVR_UNREFERENCED_PARAMETER(psSysData); -+#if !defined(NO_HARDWARE) -+#if defined(SGX_OCP_NO_INT_BYPASS) -+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_IRQSTATUS_2, 0x1); -+#endif -+ /* Flush posted writes */ -+ OSReadHWReg(((PVRSRV_SGXDEV_INFO *)gpsSGXDevNode->pvDevice)->pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR); -+#endif /* defined(NO_HARDWARE) */ -+} -+ -+#if defined(SGX_OCP_NO_INT_BYPASS) -+/*! -+****************************************************************************** -+ @Function SysEnableSGXInterrupts -+ -+ @Description Enables SGX interrupts -+ -+ @Input psSysData -+ -+ @Return IMG_VOID -+ -+******************************************************************************/ -+IMG_VOID SysEnableSGXInterrupts(SYS_DATA *psSysData) -+{ -+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *)psSysData->pvSysSpecificData; -+ if (SYS_SPECIFIC_DATA_TEST(psSysSpecData, SYS_SPECIFIC_DATA_ENABLE_LISR) && !SYS_SPECIFIC_DATA_TEST(psSysSpecData, SYS_SPECIFIC_DATA_IRQ_ENABLED)) -+ { -+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_IRQSTATUS_2, 0x1); -+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_IRQENABLE_SET_2, 0x1); -+ SYS_SPECIFIC_DATA_SET(psSysSpecData, SYS_SPECIFIC_DATA_IRQ_ENABLED); -+ } -+} -+ -+/*! -+****************************************************************************** -+ @Function SysDisableSGXInterrupts -+ -+ @Description Disables SGX interrupts -+ -+ @Input psSysData -+ -+ @Return IMG_VOID -+ -+******************************************************************************/ -+IMG_VOID SysDisableSGXInterrupts(SYS_DATA *psSysData) -+{ -+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *)psSysData->pvSysSpecificData; -+ -+ if (SYS_SPECIFIC_DATA_TEST(psSysSpecData, SYS_SPECIFIC_DATA_IRQ_ENABLED)) -+ { -+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_IRQENABLE_CLR_2, 0x1); -+ SYS_SPECIFIC_DATA_CLEAR(psSysSpecData, SYS_SPECIFIC_DATA_IRQ_ENABLED); -+ } -+} -+#endif /* defined(SGX_OCP_NO_INT_BYPASS) */ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysSystemPrePowerState -+ -+ @Description Perform system-level processing required before a power transition -+ -+ @Input eNewPowerState : -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR SysSystemPrePowerState(PVRSRV_SYS_POWER_STATE eNewPowerState) -+{ -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ -+ if (eNewPowerState == PVRSRV_SYS_POWER_STATE_D3) -+ { -+ PVR_TRACE(("SysSystemPrePowerState: Entering state D3")); -+ -+#if defined(SYS_USING_INTERRUPTS) -+ if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR)) -+ { -+#if defined(SYS_CUSTOM_POWERLOCK_WRAP) -+ IMG_BOOL bWrapped = WrapSystemPowerChange(&gsSysSpecificData); -+#endif -+ eError = OSUninstallDeviceLISR(gpsSysData); -+#if defined(SYS_CUSTOM_POWERLOCK_WRAP) -+ if (bWrapped) -+ { -+ UnwrapSystemPowerChange(&gsSysSpecificData); -+ } -+#endif -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysSystemPrePowerState: OSUninstallDeviceLISR failed (%d)", eError)); -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR); -+ SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR); -+ } -+#endif -+ -+ if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS)) -+ { -+ DisableSystemClocks(gpsSysData); -+ -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS); -+ SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS); -+ } -+ } -+ -+ return eError; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysSystemPostPowerState -+ -+ @Description Perform system-level processing required after a power transition -+ -+ @Input eNewPowerState : -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR SysSystemPostPowerState(PVRSRV_SYS_POWER_STATE eNewPowerState) -+{ -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ -+ if (eNewPowerState == PVRSRV_SYS_POWER_STATE_D0) -+ { -+ PVR_TRACE(("SysSystemPostPowerState: Entering state D0")); -+ -+ if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS)) -+ { -+ eError = EnableSystemClocksWrap(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysSystemPostPowerState: EnableSystemClocksWrap failed (%d)", eError)); -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS); -+ SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS); -+ } -+ -+#if defined(SYS_USING_INTERRUPTS) -+ if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR)) -+ { -+#if defined(SYS_CUSTOM_POWERLOCK_WRAP) -+ IMG_BOOL bWrapped = WrapSystemPowerChange(&gsSysSpecificData); -+#endif -+ -+ eError = OSInstallDeviceLISR(gpsSysData, gsSGXDeviceMap.ui32IRQ, "SGX ISR", gpsSGXDevNode); -+#if defined(SYS_CUSTOM_POWERLOCK_WRAP) -+ if (bWrapped) -+ { -+ UnwrapSystemPowerChange(&gsSysSpecificData); -+ } -+#endif -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysSystemPostPowerState: OSInstallDeviceLISR failed to install ISR (%d)", eError)); -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR); -+ SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR); -+ } -+#endif -+ } -+ return eError; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysDevicePrePowerState -+ -+ @Description Perform system level processing required before a device power -+ transition -+ -+ @Input ui32DeviceIndex : -+ @Input eNewPowerState : -+ @Input eCurrentPowerState : -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR SysDevicePrePowerState(IMG_UINT32 ui32DeviceIndex, -+ PVRSRV_DEV_POWER_STATE eNewPowerState, -+ PVRSRV_DEV_POWER_STATE eCurrentPowerState) -+{ -+ PVR_UNREFERENCED_PARAMETER(eCurrentPowerState); -+ -+ if (ui32DeviceIndex != gui32SGXDeviceID) -+ { -+ return PVRSRV_OK; -+ } -+ -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ if (eNewPowerState == PVRSRV_DEV_POWER_STATE_OFF) -+ { -+ PVR_DPF((PVR_DBG_MESSAGE, "SysDevicePrePowerState: SGX Entering state D3")); -+ DisableSGXClocks(gpsSysData); -+ } -+#else /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ PVR_UNREFERENCED_PARAMETER(eNewPowerState ); -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysDevicePostPowerState -+ -+ @Description Perform system level processing required after a device power -+ transition -+ -+ @Input ui32DeviceIndex : -+ @Input eNewPowerState : -+ @Input eCurrentPowerState : -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR SysDevicePostPowerState(IMG_UINT32 ui32DeviceIndex, -+ PVRSRV_DEV_POWER_STATE eNewPowerState, -+ PVRSRV_DEV_POWER_STATE eCurrentPowerState) -+{ -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ -+ PVR_UNREFERENCED_PARAMETER(eNewPowerState); -+ -+ if (ui32DeviceIndex != gui32SGXDeviceID) -+ { -+ return eError; -+ } -+ -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ if (eCurrentPowerState == PVRSRV_DEV_POWER_STATE_OFF) -+ { -+ PVR_DPF((PVR_DBG_MESSAGE, "SysDevicePostPowerState: SGX Leaving state D3")); -+ eError = EnableSGXClocksWrap(gpsSysData); -+ } -+#else /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ PVR_UNREFERENCED_PARAMETER(eCurrentPowerState); -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ -+ return eError; -+} -+ -+#if defined(SYS_SUPPORTS_SGX_IDLE_CALLBACK) -+ -+IMG_VOID SysSGXIdleTransition(IMG_BOOL bSGXIdle) -+{ -+ PVR_DPF((PVR_DBG_MESSAGE, "SysSGXIdleTransition switch to %u", bSGXIdle)); -+} -+ -+#endif /* defined(SYS_SUPPORTS_SGX_IDLE_CALLBACK) */ -+ -+/***************************************************************************** -+ @Function SysOEMFunction -+ -+ @Description marshalling function for custom OEM functions -+ -+ @Input ui32ID - function ID -+ @Input pvIn - in data -+ @Output pvOut - out data -+ -+ @Return PVRSRV_ERROR -+*****************************************************************************/ -+PVRSRV_ERROR SysOEMFunction ( IMG_UINT32 ui32ID, -+ IMG_VOID *pvIn, -+ IMG_UINT32 ulInSize, -+ IMG_VOID *pvOut, -+ IMG_UINT32 ulOutSize) -+{ -+ PVR_UNREFERENCED_PARAMETER(ui32ID); -+ PVR_UNREFERENCED_PARAMETER(pvIn); -+ PVR_UNREFERENCED_PARAMETER(ulInSize); -+ PVR_UNREFERENCED_PARAMETER(pvOut); -+ PVR_UNREFERENCED_PARAMETER(ulOutSize); -+ -+ if ((ui32ID == OEM_GET_EXT_FUNCS) && -+ (ulOutSize == sizeof(PVRSRV_DC_OEM_JTABLE))) -+ { -+ PVRSRV_DC_OEM_JTABLE *psOEMJTable = (PVRSRV_DC_OEM_JTABLE*) pvOut; -+ psOEMJTable->pfnOEMBridgeDispatch = &PVRSRV_BridgeDispatchKM; -+ return PVRSRV_OK; -+ } -+ -+ return PVRSRV_ERROR_INVALID_PARAMS; -+} -+/****************************************************************************** -+ End of file (sysconfig.c) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/system/omap3/sysconfig.h b/drivers/staging/ti-es8-sgx/services4/system/omap3/sysconfig.h -new file mode 100644 -index 0000000..36703bc ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/omap3/sysconfig.h -@@ -0,0 +1,109 @@ -+/*************************************************************************/ /*! -+@Title System Description Header -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description This header provides system-specific declarations and macros -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#if !defined(__SOCCONFIG_H__) -+#define __SOCCONFIG_H__ -+ -+#define VS_PRODUCT_NAME "OMAP3430" -+ -+ -+#define SYS_SGX_HWRECOVERY_TIMEOUT_FREQ (100) // 10ms (100hz) -+#define SYS_SGX_PDS_TIMER_FREQ (1000) // 1ms (1000hz) -+ -+/* Allow the AP latency to be overridden in the build config */ -+#if !defined(SYS_SGX_ACTIVE_POWER_LATENCY_MS) -+#define SYS_SGX_ACTIVE_POWER_LATENCY_MS (2) -+#endif -+ -+ -+#define SYS_OMAP3430_SGX_REGS_SYS_PHYS_BASE 0x50000000 -+#define SYS_OMAP3430_SGX_REGS_SIZE 0x4000 -+ -+#define SYS_OMAP3430_SGX_IRQ 21 /* OMAP4 IRQ's are offset by 32 */ -+ -+#define SYS_OMAP_DSS_REGS_SYS_PHYS_BASE 0x58000000 -+#define SYS_OMAP_DSS_REGS_SIZE 0x7000 -+ -+#define SYS_OMAP_DSS_HDMI_INTERRUPT_STATUS_REG 0x6028 -+#define SYS_OMAP_DSS_HDMI_INTERRUPT_ENABLE_REG 0x602c -+ -+#define SYS_OMAP_DSS_HDMI_INTERRUPT_VSYNC_ENABLE_MASK 0x10000 -+#define SYS_OMAP_DSS_HDMI_INTERRUPT_VSYNC_STATUS_MASK 0x10000 -+ -+#define SYS_OMAP_DSS_LCD_INTERRUPT_STATUS_REG 0x1018 -+#define SYS_OMAP_DSS_LCD_INTERRUPT_ENABLE_REG 0x101c -+ -+#define SYS_OMAP_DSS_LCD_INTERRUPT_VSYNC_ENABLE_MASK 0x40002 -+#define SYS_OMAP_DSS_LCD_INTERRUPT_VSYNC_STATUS_MASK 0x40002 -+ -+ -+#define SYS_OMAP3430_GP11TIMER_ENABLE_SYS_PHYS_BASE 0x48088024 -+#define SYS_OMAP3430_GP11TIMER_REGS_SYS_PHYS_BASE 0x48088028 -+#define SYS_OMAP3430_GP11TIMER_TSICR_SYS_PHYS_BASE 0x48088040 -+ -+ -+ -+/* Interrupt bits */ -+#define DEVICE_SGX_INTERRUPT (1<<0) -+#define DEVICE_MSVDX_INTERRUPT (1<<1) -+#define DEVICE_DISP_INTERRUPT (1<<2) -+ -+#if 0 -+#if defined(__linux__) -+/* -+ * Recent OMAP4 kernels register SGX as platform device "omap_gpu". -+ * This device must be used with the Linux power management calls -+ * in sysutils_linux.c, in order for SGX to be powered on. -+ */ -+#if defined(PVR_LDM_PLATFORM_PRE_REGISTERED_DEV) -+#define SYS_SGX_DEV_NAME PVR_LDM_PLATFORM_PRE_REGISTERED_DEV -+#else -+#define SYS_SGX_DEV_NAME "omap_gpu" -+#endif /* defined(PVR_LDM_PLATFORM_PRE_REGISTERED_DEV) */ -+#endif /* defined(__linux__) */ -+#endif -+ -+/***************************************************************************** -+ * system specific data structures -+ *****************************************************************************/ -+ -+#endif /* __SYSCONFIG_H__ */ -diff --git a/drivers/staging/ti-es8-sgx/services4/system/omap3/sysinfo.h b/drivers/staging/ti-es8-sgx/services4/system/omap3/sysinfo.h -new file mode 100644 -index 0000000..7383b9c ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/omap3/sysinfo.h -@@ -0,0 +1,70 @@ -+/*************************************************************************/ /*! -+@Title System Description Header -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description This header provides system-specific declarations and macros -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#if !defined(__SYSINFO_H__) -+#define __SYSINFO_H__ -+ -+#if defined(SGX540) && (SGX_CORE_REV == 120) -+#define SYS_SGX_CLOCK_SPEED 307200000 -+#else -+#define SYS_SGX_CLOCK_SPEED 200000000 -+#endif -+ -+/*!< System specific poll/timeout details */ -+#if defined(PVR_LINUX_USING_WORKQUEUES) -+/* -+ * The workqueue based 3rd party display driver may be blocked for up -+ * to 500ms waiting for a vsync when the screen goes blank, so we -+ * need to wait longer for the hardware if a flush of the swap chain is -+ * required. -+ */ -+#define MAX_HW_TIME_US (1000000) -+#define WAIT_TRY_COUNT (20000) -+#else -+#define MAX_HW_TIME_US (500000) -+#define WAIT_TRY_COUNT (10000) -+#endif -+ -+ -+#define SYS_DEVICE_COUNT 15 /* SGX, DISPLAYCLASS (external), BUFFERCLASS (external) */ -+ -+#endif /* __SYSINFO_H__ */ -diff --git a/drivers/staging/ti-es8-sgx/services4/system/omap3/syslocal.h b/drivers/staging/ti-es8-sgx/services4/system/omap3/syslocal.h -new file mode 100644 -index 0000000..c849332 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/omap3/syslocal.h -@@ -0,0 +1,264 @@ -+/*************************************************************************/ /*! -+@Title Local system definitions -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description This header provides local system declarations and macros -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#if !defined(__SYSLOCAL_H__) -+#define __SYSLOCAL_H__ -+ -+#if defined(__linux__) -+ -+#include <linux/version.h> -+#include <linux/clk.h> -+#if defined(PVR_LINUX_USING_WORKQUEUES) -+#include <linux/mutex.h> -+#else -+#include <linux/spinlock.h> -+#endif -+#include <asm/atomic.h> -+ -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)) -+#include <linux/semaphore.h> -+#include <linux/resource.h> -+#else /* (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)) */ -+#include <asm/semaphore.h> -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22)) -+#include <asm/arch/resource.h> -+#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22)) */ -+#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)) */ -+ -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) -+#if !defined(LDM_PLATFORM) -+#error "LDM_PLATFORM must be set" -+#endif -+//#define PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO -+//#include <linux/platform_device.h> -+#endif -+ -+#if ((defined(DEBUG) || defined(TIMING)) && \ -+ (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32))) && \ -+ !defined(PVR_NO_OMAP_TIMER) -+/* -+ * We need to explicitly enable the GPTIMER11 clocks, or we'll get an -+ * abort when we try to access the timer registers. -+ */ -+#define PVR_OMAP4_TIMING_PRCM -+#endif -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) -+//#include <plat/gpu.h> -+#if !defined(PVR_NO_OMAP_TIMER) -+//#define PVR_OMAP_USE_DM_TIMER_API -+//#include <plat/dmtimer.h> -+#endif -+#endif -+ -+#if !defined(PVR_NO_OMAP_TIMER) -+//#define PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA -+#endif -+#endif /* defined(__linux__) */ -+ -+#if !defined(NO_HARDWARE) && \ -+ defined(SYS_USING_INTERRUPTS) && \ -+ defined(SGX540) -+#define SGX_OCP_REGS_ENABLED -+#endif -+ -+#if defined(__linux__) -+#if defined(SGX_OCP_REGS_ENABLED) -+/* FIXME: Temporary workaround for OMAP4470 and active power off in 4430 */ -+#if !defined(SGX544) && defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+//#define SGX_OCP_NO_INT_BYPASS -+#endif -+#endif -+#endif -+ -+#if defined (__cplusplus) -+extern "C" { -+#endif -+ -+/***************************************************************************** -+ * system specific data structures -+ *****************************************************************************/ -+ -+/***************************************************************************** -+ * system specific function prototypes -+ *****************************************************************************/ -+ -+IMG_VOID DisableSystemClocks(SYS_DATA *psSysData); -+PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData); -+ -+IMG_VOID DisableSGXClocks(SYS_DATA *psSysData); -+PVRSRV_ERROR EnableSGXClocks(SYS_DATA *psSysData); -+ -+/* -+ * Various flags to indicate what has been initialised, and what -+ * has been temporarily deinitialised for power management purposes. -+ */ -+#define SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS 0x00000001 -+#define SYS_SPECIFIC_DATA_ENABLE_LISR 0x00000002 -+#define SYS_SPECIFIC_DATA_ENABLE_MISR 0x00000004 -+#define SYS_SPECIFIC_DATA_ENABLE_ENVDATA 0x00000008 -+#define SYS_SPECIFIC_DATA_ENABLE_LOCDEV 0x00000010 -+#define SYS_SPECIFIC_DATA_ENABLE_REGDEV 0x00000020 -+#define SYS_SPECIFIC_DATA_ENABLE_PDUMPINIT 0x00000040 -+#define SYS_SPECIFIC_DATA_ENABLE_INITDEV 0x00000080 -+#define SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV 0x00000100 -+ -+#define SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR 0x00000200 -+#define SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS 0x00000400 -+#define SYS_SPECIFIC_DATA_ENABLE_OCPREGS 0x00000800 -+#define SYS_SPECIFIC_DATA_ENABLE_PM_RUNTIME 0x00001000 -+#define SYS_SPECIFIC_DATA_IRQ_ENABLED 0x00002000 -+#define SYS_SPECIFIC_DATA_DVFS_INIT 0x00004000 -+ -+#define SYS_SPECIFIC_DATA_SET(psSysSpecData, flag) ((IMG_VOID)((psSysSpecData)->ui32SysSpecificData |= (flag))) -+ -+#define SYS_SPECIFIC_DATA_CLEAR(psSysSpecData, flag) ((IMG_VOID)((psSysSpecData)->ui32SysSpecificData &= ~(flag))) -+ -+#define SYS_SPECIFIC_DATA_TEST(psSysSpecData, flag) (((psSysSpecData)->ui32SysSpecificData & (flag)) != 0) -+ -+typedef struct _SYS_SPECIFIC_DATA_TAG_ -+{ -+ IMG_UINT32 ui32SysSpecificData; -+ PVRSRV_DEVICE_NODE *psSGXDevNode; -+ IMG_BOOL bSGXInitComplete; -+#if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA) -+ IMG_CPU_PHYADDR sTimerRegPhysBase; -+#endif -+#if !defined(__linux__) -+ IMG_BOOL bSGXClocksEnabled; -+#endif -+ IMG_UINT32 ui32SrcClockDiv; -+#if defined(__linux__) -+ IMG_BOOL bSysClocksOneTimeInit; -+ atomic_t sSGXClocksEnabled; -+#if defined(PVR_LINUX_USING_WORKQUEUES) -+ struct mutex sPowerLock; -+#else -+ IMG_BOOL bConstraintNotificationsEnabled; -+ spinlock_t sPowerLock; -+ atomic_t sPowerLockCPU; -+ spinlock_t sNotifyLock; -+ atomic_t sNotifyLockCPU; -+ IMG_BOOL bCallVDD2PostFunc; -+#endif -+ struct clk *psCORE_CK; -+ struct clk *psSGX_FCK; -+ struct clk *psSGX_ICK; -+ -+#if defined(DEBUG) || defined(TIMING) -+ struct clk *psGPT11_FCK; -+ struct clk *psGPT11_ICK; -+#endif -+#if defined(PVR_OMAP_USE_DM_TIMER_API) -+ struct omap_dm_timer *psGPTimer; -+#endif -+ IMG_UINT32 ui32SGXFreqListSize; -+ IMG_UINT32 *pui32SGXFreqList; -+ IMG_UINT32 ui32SGXFreqListIndex; -+#endif /* defined(__linux__) */ -+} SYS_SPECIFIC_DATA; -+ -+extern SYS_SPECIFIC_DATA *gpsSysSpecificData; -+ -+#if defined(SGX_OCP_REGS_ENABLED) && defined(SGX_OCP_NO_INT_BYPASS) -+IMG_VOID SysEnableSGXInterrupts(SYS_DATA* psSysData); -+IMG_VOID SysDisableSGXInterrupts(SYS_DATA* psSysData); -+#else -+#define SysEnableSGXInterrupts(psSysData) -+#define SysDisableSGXInterrupts(psSysData) -+#endif -+ -+#if defined(SYS_CUSTOM_POWERLOCK_WRAP) -+IMG_BOOL WrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData); -+IMG_VOID UnwrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData); -+#endif -+ -+#if defined(__linux__) -+ -+PVRSRV_ERROR SysPMRuntimeRegister(void); -+PVRSRV_ERROR SysPMRuntimeUnregister(void); -+ -+PVRSRV_ERROR SysDvfsInitialize(SYS_SPECIFIC_DATA *psSysSpecificData); -+PVRSRV_ERROR SysDvfsDeinitialize(SYS_SPECIFIC_DATA *psSysSpecificData); -+ -+#else /* defined(__linux__) */ -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(SysPMRuntimeRegister) -+#endif -+static INLINE PVRSRV_ERROR SysPMRuntimeRegister(void) -+{ -+ return PVRSRV_OK; -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(SysPMRuntimeUnregister) -+#endif -+static INLINE PVRSRV_ERROR SysPMRuntimeUnregister(void) -+{ -+ return PVRSRV_OK; -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(SysDvfsInitialize) -+#endif -+static INLINE PVRSRV_ERROR SysDvfsInitialize(void) -+{ -+ return PVRSRV_OK; -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(SysDvfsDeinitialize) -+#endif -+static INLINE PVRSRV_ERROR SysDvfsDeinitialize(void) -+{ -+ return PVRSRV_OK; -+} -+ -+#endif /* defined(__linux__) */ -+ -+#if defined(__cplusplus) -+} -+#endif -+ -+#endif /* __SYSLOCAL_H__ */ -diff --git a/drivers/staging/ti-es8-sgx/services4/system/omap3/sysutils.c b/drivers/staging/ti-es8-sgx/services4/system/omap3/sysutils.c -new file mode 100644 -index 0000000..6725421 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/omap3/sysutils.c -@@ -0,0 +1,47 @@ -+/*************************************************************************/ /*! -+@Title Shared (User/kernel) and System dependent utilities -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Provides system-specific functions -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+/* Pull in the correct system dependent sysutils source */ -+ -+#if defined(__linux__) -+#include "sysutils_linux.c" -+#endif -diff --git a/drivers/staging/ti-es8-sgx/services4/system/omap3/sysutils_linux.c b/drivers/staging/ti-es8-sgx/services4/system/omap3/sysutils_linux.c -new file mode 100644 -index 0000000..2eb7f5e ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/omap3/sysutils_linux.c -@@ -0,0 +1,958 @@ -+/*************************************************************************/ /*! -+@Title System dependent utilities -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Provides system-specific functions -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+#include <linux/version.h> -+#include <linux/clk.h> -+#include <linux/err.h> -+#include <linux/hardirq.h> -+#include <linux/mutex.h> -+#include <linux/slab.h> -+ -+#include "sgxdefs.h" -+#include "services_headers.h" -+#include "sysinfo.h" -+#include "sgxapi_km.h" -+#include "sysconfig.h" -+#include "sgxinfokm.h" -+#include "syslocal.h" -+ -+#include <linux/platform_device.h> -+#include <linux/pm_runtime.h> -+ -+#if defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) -+#include <linux/opp.h> -+#endif -+ -+#if defined(SUPPORT_DRI_DRM_PLUGIN) -+#include <drm/drmP.h> -+#include <drm/drm.h> -+ -+#include <linux/omap_gpu.h> -+ -+#include "pvr_drm.h" -+#endif -+ -+#define ONE_MHZ 1000000 -+#define HZ_TO_MHZ(m) ((m) / ONE_MHZ) -+ -+#if defined(SUPPORT_OMAP3430_SGXFCLK_96M) -+#define SGX_PARENT_CLOCK "cm_96m_fck" -+#else -+#define SGX_PARENT_CLOCK "core_ck" -+#endif -+ -+#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) -+extern struct platform_device *gpsPVRLDMDev; -+#endif -+ -+static PVRSRV_ERROR PowerLockWrap(SYS_SPECIFIC_DATA *psSysSpecData, IMG_BOOL bTryLock) -+{ -+ if (!in_interrupt()) -+ { -+ if (bTryLock) -+ { -+ int locked = mutex_trylock(&psSysSpecData->sPowerLock); -+ if (locked == 0) -+ { -+ return PVRSRV_ERROR_RETRY; -+ } -+ } -+ else -+ { -+ mutex_lock(&psSysSpecData->sPowerLock); -+ } -+ } -+ -+ return PVRSRV_OK; -+} -+ -+static IMG_VOID PowerLockUnwrap(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ if (!in_interrupt()) -+ { -+ mutex_unlock(&psSysSpecData->sPowerLock); -+ } -+} -+ -+PVRSRV_ERROR SysPowerLockWrap(IMG_BOOL bTryLock) -+{ -+ SYS_DATA *psSysData; -+ -+ SysAcquireData(&psSysData); -+ -+ return PowerLockWrap(psSysData->pvSysSpecificData, bTryLock); -+} -+ -+IMG_VOID SysPowerLockUnwrap(IMG_VOID) -+{ -+ SYS_DATA *psSysData; -+ -+ SysAcquireData(&psSysData); -+ -+ PowerLockUnwrap(psSysData->pvSysSpecificData); -+} -+ -+/* -+ * This function should be called to unwrap the Services power lock, prior -+ * to calling any function that might sleep. -+ * This function shouldn't be called prior to calling EnableSystemClocks -+ * or DisableSystemClocks, as those functions perform their own power lock -+ * unwrapping. -+ * If the function returns IMG_TRUE, UnwrapSystemPowerChange must be -+ * called to rewrap the power lock, prior to returning to Services. -+ */ -+IMG_BOOL WrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ return IMG_TRUE; -+} -+ -+IMG_VOID UnwrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+} -+ -+/* -+ * Return SGX timining information to caller. -+ */ -+IMG_VOID SysGetSGXTimingInformation(SGX_TIMING_INFORMATION *psTimingInfo) -+{ -+#if !defined(NO_HARDWARE) -+ PVR_ASSERT(atomic_read(&gpsSysSpecificData->sSGXClocksEnabled) != 0); -+#endif -+#if defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) -+ psTimingInfo->ui32CoreClockSpeed = -+ gpsSysSpecificData->pui32SGXFreqList[gpsSysSpecificData->ui32SGXFreqListIndex]; -+#else /* defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) */ -+ psTimingInfo->ui32CoreClockSpeed = SYS_SGX_CLOCK_SPEED; -+#endif -+ psTimingInfo->ui32HWRecoveryFreq = SYS_SGX_HWRECOVERY_TIMEOUT_FREQ; -+ psTimingInfo->ui32uKernelFreq = SYS_SGX_PDS_TIMER_FREQ; -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ psTimingInfo->bEnableActivePM = IMG_TRUE; -+#else -+ psTimingInfo->bEnableActivePM = IMG_FALSE; -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ psTimingInfo->ui32ActivePowManLatencyms = SYS_SGX_ACTIVE_POWER_LATENCY_MS; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function EnableSGXClocks -+ -+ @Description Enable SGX clocks -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR EnableSGXClocks(SYS_DATA *psSysData) -+{ -+#if !defined(NO_HARDWARE) -+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; -+#if !defined(PM_RUNTIME_SUPPORT) -+ IMG_INT res; -+ long lRate,lNewRate; -+#endif -+ /* SGX clocks already enabled? */ -+ if (atomic_read(&psSysSpecData->sSGXClocksEnabled) != 0) -+ { -+ return PVRSRV_OK; -+ } -+ -+#if !defined(PM_RUNTIME_SUPPORT) -+ PVR_DPF((PVR_DBG_MESSAGE, "EnableSGXClocks: Enabling SGX Clocks")); -+ res=clk_enable(psSysSpecData->psSGX_FCK); -+ if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Couldn't enable SGX functional clock (%d)", res)); -+ return PVRSRV_ERROR_UNABLE_TO_ENABLE_CLOCK; -+ } -+ -+ lNewRate = clk_round_rate(psSysSpecData->psSGX_FCK, SYS_SGX_CLOCK_SPEED + ONE_MHZ); -+ if (lNewRate <= 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Couldn't round SGX functional clock rate")); -+ return PVRSRV_ERROR_UNABLE_TO_ROUND_CLOCK_RATE; -+ } -+ -+ -+ lRate = clk_get_rate(psSysSpecData->psSGX_FCK); -+ if (lRate != lNewRate) -+ { -+ res = clk_set_rate(psSysSpecData->psSGX_FCK, lNewRate); -+ if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_WARNING, "EnableSGXClocks: Couldn't set SGX functional clock rate (%d)", res)); -+ return PVRSRV_ERROR_UNABLE_TO_SET_CLOCK_RATE; -+ } -+ } -+ -+#if defined(DEBUG) -+ { -+ IMG_UINT32 rate = clk_get_rate(psSysSpecData->psSGX_FCK); -+ PVR_DPF((PVR_DBG_MESSAGE, "EnableSGXClocks: SGX Functional Clock is %dMhz", HZ_TO_MHZ(rate))); -+ } -+#endif -+#endif -+#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) -+#if defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) -+ { -+ struct gpu_platform_data *pdata; -+ IMG_UINT32 max_freq_index; -+ int res; -+ -+ pdata = (struct gpu_platform_data *)gpsPVRLDMDev->dev.platform_data; -+ max_freq_index = psSysSpecData->ui32SGXFreqListSize - 2; -+ -+ /* -+ * Request maximum frequency from DVFS layer if not already set. DVFS may -+ * report busy if early in initialization, but all other errors are -+ * considered serious. Upon any error we proceed assuming our safe frequency -+ * value to be in use as indicated by the "unknown" index. -+ */ -+ if (psSysSpecData->ui32SGXFreqListIndex != max_freq_index) -+ { -+ PVR_ASSERT(pdata->device_scale != IMG_NULL); -+ res = pdata->device_scale(&gpsPVRLDMDev->dev, -+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3,4,0)) -+ &gpsPVRLDMDev->dev, -+#endif -+ psSysSpecData->pui32SGXFreqList[max_freq_index]); -+ if (res == 0) -+ { -+ psSysSpecData->ui32SGXFreqListIndex = max_freq_index; -+ } -+ else if (res == -EBUSY) -+ { -+ PVR_DPF((PVR_DBG_WARNING, "EnableSGXClocks: Unable to scale SGX frequency (EBUSY)")); -+ psSysSpecData->ui32SGXFreqListIndex = psSysSpecData->ui32SGXFreqListSize - 1; -+ } -+ else if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Unable to scale SGX frequency (%d)", res)); -+ psSysSpecData->ui32SGXFreqListIndex = psSysSpecData->ui32SGXFreqListSize - 1; -+ } -+ } -+ } -+#endif /* defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) */ -+ { -+ /* -+ * pm_runtime_get_sync returns 1 after the module has -+ * been reloaded. -+ */ -+#if defined(PM_RUNTIME_SUPPORT) -+ -+ int res = pm_runtime_get_sync(&gpsPVRLDMDev->dev); -+ if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: pm_runtime_get_sync failed (%d)", -res)); -+ return PVRSRV_ERROR_UNABLE_TO_ENABLE_CLOCK; -+ } -+#endif -+ } -+#endif /* defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) */ -+ -+ SysEnableSGXInterrupts(psSysData); -+ -+ /* Indicate that the SGX clocks are enabled */ -+ atomic_set(&psSysSpecData->sSGXClocksEnabled, 1); -+ -+#else /* !defined(NO_HARDWARE) */ -+ PVR_UNREFERENCED_PARAMETER(psSysData); -+#endif /* !defined(NO_HARDWARE) */ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function DisableSGXClocks -+ -+ @Description Disable SGX clocks. -+ -+ @Return none -+ -+******************************************************************************/ -+IMG_VOID DisableSGXClocks(SYS_DATA *psSysData) -+{ -+#if !defined(NO_HARDWARE) -+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; -+ -+ /* SGX clocks already disabled? */ -+ if (atomic_read(&psSysSpecData->sSGXClocksEnabled) == 0) -+ { -+ return; -+ } -+ -+ PVR_DPF((PVR_DBG_MESSAGE, "DisableSGXClocks: Disabling SGX Clocks")); -+#if !defined(PM_RUNTIME_SUPPORT) -+ clk_disable(psSysSpecData->psSGX_FCK); -+#endif -+ SysDisableSGXInterrupts(psSysData); -+ -+#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) -+ { -+#if defined(PM_RUNTIME_SUPPORT) -+ -+ int res = pm_runtime_put_sync(&gpsPVRLDMDev->dev); -+ if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "DisableSGXClocks: pm_runtime_put_sync failed (%d)", -res)); -+ } -+#endif -+ } -+#if defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) -+ { -+ struct gpu_platform_data *pdata; -+ int res; -+ -+ pdata = (struct gpu_platform_data *)gpsPVRLDMDev->dev.platform_data; -+ -+ /* -+ * Request minimum frequency (list index 0) from DVFS layer if not already -+ * set. DVFS may report busy if early in initialization, but all other errors -+ * are considered serious. Upon any error we proceed assuming our safe frequency -+ * value to be in use as indicated by the "unknown" index. -+ */ -+ if (psSysSpecData->ui32SGXFreqListIndex != 0) -+ { -+ PVR_ASSERT(pdata->device_scale != IMG_NULL); -+ res = pdata->device_scale(&gpsPVRLDMDev->dev, -+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3,4,0)) -+ &gpsPVRLDMDev->dev, -+#endif -+ psSysSpecData->pui32SGXFreqList[0]); -+ if (res == 0) -+ { -+ psSysSpecData->ui32SGXFreqListIndex = 0; -+ } -+ else if (res == -EBUSY) -+ { -+ PVR_DPF((PVR_DBG_WARNING, "DisableSGXClocks: Unable to scale SGX frequency (EBUSY)")); -+ psSysSpecData->ui32SGXFreqListIndex = psSysSpecData->ui32SGXFreqListSize - 1; -+ } -+ else if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "DisableSGXClocks: Unable to scale SGX frequency (%d)", res)); -+ psSysSpecData->ui32SGXFreqListIndex = psSysSpecData->ui32SGXFreqListSize - 1; -+ } -+ } -+ } -+#endif /* defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) */ -+#endif /* defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) */ -+ -+ /* Indicate that the SGX clocks are disabled */ -+ atomic_set(&psSysSpecData->sSGXClocksEnabled, 0); -+ -+#else /* !defined(NO_HARDWARE) */ -+ PVR_UNREFERENCED_PARAMETER(psSysData); -+#endif /* !defined(NO_HARDWARE) */ -+} -+ -+#if (defined(DEBUG) || defined(TIMING)) && !defined(PVR_NO_OMAP_TIMER) -+#if defined(PVR_OMAP_USE_DM_TIMER_API) -+#define GPTIMER_TO_USE 11 -+/*! -+****************************************************************************** -+ -+ @Function AcquireGPTimer -+ -+ @Description Acquire a GP timer -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+static PVRSRV_ERROR AcquireGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ PVR_ASSERT(psSysSpecData->psGPTimer == NULL); -+ -+ /* -+ * This code has problems on module reload for OMAP5 running Linux -+ * 3.4.10, due to omap2_dm_timer_set_src (called by -+ * omap_dm_timer_request_specific), being unable to set the parent -+ * clock to OMAP_TIMER_SRC_32_KHZ. -+ * Not calling omap_dm_timer_set_source doesn't help. -+ */ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) || !defined(MODULE) -+ /* -+ * This code could try requesting registers 9, 10, and 11, -+ * stopping at the first succesful request. We'll stick with -+ * 11 for now, as it avoids having to hard code yet more -+ * physical addresses into the code. -+ */ -+ psSysSpecData->psGPTimer = omap_dm_timer_request_specific(GPTIMER_TO_USE); -+ if (psSysSpecData->psGPTimer == NULL) -+ { -+ -+ PVR_DPF((PVR_DBG_WARNING, "%s: omap_dm_timer_request_specific failed", __FUNCTION__)); -+ return PVRSRV_ERROR_CLOCK_REQUEST_FAILED; -+ } -+ -+ omap_dm_timer_set_source(psSysSpecData->psGPTimer, OMAP_TIMER_SRC_SYS_CLK); -+ omap_dm_timer_enable(psSysSpecData->psGPTimer); -+ -+ /* Set autoreload, and start value of 0 */ -+ omap_dm_timer_set_load_start(psSysSpecData->psGPTimer, 1, 0); -+ -+ omap_dm_timer_start(psSysSpecData->psGPTimer); -+ -+ /* -+ * The DM timer API doesn't have a mechanism for obtaining the -+ * physical address of the counter register. -+ */ -+ psSysSpecData->sTimerRegPhysBase.uiAddr = SYS_OMAP3430_GP11TIMER_REGS_SYS_PHYS_BASE; -+#else /* (LINUX_VERSION_CODE <= KERNEL_VERSION(3,4,0)) || !defined(MODULE) */ -+ (void)psSysSpecData; -+#endif /* (LINUX_VERSION_CODE <= KERNEL_VERSION(3,4,0)) || !defined(MODULE) */ -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function ReleaseGPTimer -+ -+ @Description Release a GP timer -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+static void ReleaseGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ if (psSysSpecData->psGPTimer != NULL) -+ { -+ /* Always returns 0 */ -+ (void) omap_dm_timer_stop(psSysSpecData->psGPTimer); -+ -+ omap_dm_timer_disable(psSysSpecData->psGPTimer); -+ -+ omap_dm_timer_free(psSysSpecData->psGPTimer); -+ -+ psSysSpecData->sTimerRegPhysBase.uiAddr = 0; -+ -+ psSysSpecData->psGPTimer = NULL; -+ } -+ -+} -+#else /* PVR_OMAP_USE_DM_TIMER_API */ -+/*! -+****************************************************************************** -+ -+ @Function AcquireGPTimer -+ -+ @Description Acquire a GP timer -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+static PVRSRV_ERROR AcquireGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+#if defined(PVR_OMAP4_TIMING_PRCM) -+ struct clk *psCLK; -+ IMG_INT res; -+ struct clk *sys_ck; -+ IMG_INT rate; -+#endif -+ PVRSRV_ERROR eError; -+ -+ IMG_CPU_PHYADDR sTimerRegPhysBase; -+ IMG_HANDLE hTimerEnable; -+ IMG_UINT32 *pui32TimerEnable; -+#if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA) -+ PVR_ASSERT(psSysSpecData->sTimerRegPhysBase.uiAddr == 0); -+#endif -+ -+#if defined(PVR_OMAP4_TIMING_PRCM) -+ /* assert our dependence on the GPTIMER11 module */ -+ psCLK = clk_get(NULL, "gpt11_fck"); -+ if (IS_ERR(psCLK)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get GPTIMER11 functional clock")); -+ goto ExitError; -+ } -+ psSysSpecData->psGPT11_FCK = psCLK; -+ -+ psCLK = clk_get(NULL, "gpt11_ick"); -+ if (IS_ERR(psCLK)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get GPTIMER11 interface clock")); -+ goto ExitError; -+ } -+ psSysSpecData->psGPT11_ICK = psCLK; -+ -+ sys_ck = clk_get(NULL, "sys_ck"); -+ if (IS_ERR(sys_ck)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get System clock")); -+ goto ExitError; -+ } -+ -+ if(clk_get_parent(psSysSpecData->psGPT11_FCK) != sys_ck) -+ { -+ PVR_TRACE(("Setting GPTIMER11 parent to System Clock")); -+ res = clk_set_parent(psSysSpecData->psGPT11_FCK, sys_ck); -+ if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't set GPTIMER11 parent clock (%d)", res)); -+ goto ExitError; -+ } -+ } -+ -+ rate = clk_get_rate(psSysSpecData->psGPT11_FCK); -+ PVR_TRACE(("GPTIMER11 clock is %dMHz", HZ_TO_MHZ(rate))); -+ -+ res = clk_enable(psSysSpecData->psGPT11_FCK); -+ if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't enable GPTIMER11 functional clock (%d)", res)); -+ goto ExitError; -+ } -+ -+ res = clk_enable(psSysSpecData->psGPT11_ICK); -+ if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't enable GPTIMER11 interface clock (%d)", res)); -+ goto ExitDisableGPT11FCK; -+ } -+#endif /* defined(PVR_OMAP4_TIMING_PRCM) */ -+ -+ /* Set the timer to non-posted mode */ -+ sTimerRegPhysBase.uiAddr = SYS_OMAP3430_GP11TIMER_TSICR_SYS_PHYS_BASE; -+ pui32TimerEnable = OSMapPhysToLin(sTimerRegPhysBase, -+ 4, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ &hTimerEnable); -+ -+ if (pui32TimerEnable == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: OSMapPhysToLin failed")); -+ goto ExitDisableGPT11ICK; -+ } -+ -+ if(!(*pui32TimerEnable & 4)) -+ { -+ PVR_TRACE(("Setting GPTIMER11 mode to posted (currently is non-posted)")); -+ -+ /* Set posted mode */ -+ *pui32TimerEnable |= 4; -+ } -+ -+ OSUnMapPhysToLin(pui32TimerEnable, -+ 4, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ hTimerEnable); -+ -+ /* Enable the timer */ -+ sTimerRegPhysBase.uiAddr = SYS_OMAP3430_GP11TIMER_ENABLE_SYS_PHYS_BASE; -+ pui32TimerEnable = OSMapPhysToLin(sTimerRegPhysBase, -+ 4, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ &hTimerEnable); -+ -+ if (pui32TimerEnable == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: OSMapPhysToLin failed")); -+ goto ExitDisableGPT11ICK; -+ } -+ -+ /* Enable and set autoreload on overflow */ -+ *pui32TimerEnable = 3; -+ -+ OSUnMapPhysToLin(pui32TimerEnable, -+ 4, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ hTimerEnable); -+#if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA) -+ psSysSpecData->sTimerRegPhysBase = sTimerRegPhysBase; -+#endif -+ eError = PVRSRV_OK; -+ -+ goto Exit; -+ -+ExitDisableGPT11ICK: -+#if defined(PVR_OMAP4_TIMING_PRCM) -+ clk_disable(psSysSpecData->psGPT11_ICK); -+ExitDisableGPT11FCK: -+ clk_disable(psSysSpecData->psGPT11_FCK); -+ExitError: -+#endif /* defined(PVR_OMAP4_TIMING_PRCM) */ -+ eError = PVRSRV_ERROR_CLOCK_REQUEST_FAILED; -+Exit: -+ return eError; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function ReleaseGPTimer -+ -+ @Description Release a GP timer -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+static void ReleaseGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ IMG_HANDLE hTimerDisable; -+ IMG_UINT32 *pui32TimerDisable; -+ IMG_CPU_PHYADDR TimerRegPhysBase; -+#if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA) -+ if (psSysSpecData->sTimerRegPhysBase.uiAddr == 0) -+ { -+ return; -+ } -+#endif -+ /* Disable the timer */ -+ pui32TimerDisable = OSMapPhysToLin(TimerRegPhysBase, -+ 4, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ &hTimerDisable); -+ -+ if (pui32TimerDisable == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "DisableSystemClocks: OSMapPhysToLin failed")); -+ } -+ else -+ { -+ *pui32TimerDisable = 0; -+ -+ OSUnMapPhysToLin(pui32TimerDisable, -+ 4, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ hTimerDisable); -+ } -+#if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA) -+ psSysSpecData->sTimerRegPhysBase.uiAddr = 0; -+#endif -+#if defined(PVR_OMAP4_TIMING_PRCM) -+ clk_disable(psSysSpecData->psGPT11_ICK); -+ -+ clk_disable(psSysSpecData->psGPT11_FCK); -+#endif /* defined(PVR_OMAP4_TIMING_PRCM) */ -+} -+#endif /* PVR_OMAP_USE_DM_TIMER_API */ -+#else /* (DEBUG || TIMING) && !PVR_NO_OMAP_TIMER */ -+static PVRSRV_ERROR AcquireGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ PVR_UNREFERENCED_PARAMETER(psSysSpecData); -+ -+ return PVRSRV_OK; -+} -+static void ReleaseGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ PVR_UNREFERENCED_PARAMETER(psSysSpecData); -+} -+#endif /* (DEBUG || TIMING) && !PVR_NO_OMAP_TIMER */ -+ -+/*! -+****************************************************************************** -+ -+ @Function EnableSystemClocks -+ -+ @Description Setup up the clocks for the graphics device to work. -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData) -+{ -+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; -+#if !defined(PM_RUNTIME_SUPPORT) -+ struct clk *psCLK; -+ IMG_INT res; -+#endif -+ -+ PVR_TRACE(("EnableSystemClocks: Enabling System Clocks")); -+ -+ if (!psSysSpecData->bSysClocksOneTimeInit) -+ { -+ mutex_init(&psSysSpecData->sPowerLock); -+ -+ atomic_set(&psSysSpecData->sSGXClocksEnabled, 0); -+ -+ psCLK = clk_get(NULL, SGX_PARENT_CLOCK); -+ if (IS_ERR(psCLK)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSsystemClocks: Couldn't get Core Clock")); -+ return PVRSRV_ERROR_UNABLE_TO_GET_PARENT_CLOCK; -+ } -+ psSysSpecData->psCORE_CK = psCLK; -+ -+ -+// psSysSpecData->bSysClocksOneTimeInit = IMG_TRUE; -+#if !defined(PM_RUNTIME_SUPPORT) -+ psCLK = clk_get(NULL, "sgx_fck"); -+ if (IS_ERR(psCLK)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSsystemClocks: Couldn't get SGX Functional Clock")); -+ return PVRSRV_ERROR_UNABLE_TO_GET_CLOCK; -+ } -+ psSysSpecData->psSGX_FCK = psCLK; -+ -+ psCLK = clk_get(NULL, "sgx_ick"); -+ if (IS_ERR(psCLK)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get SGX Interface Clock")); -+ return PVRSRV_ERROR_UNABLE_TO_GET_CLOCK; -+ } -+ psSysSpecData->psSGX_ICK = psCLK; -+ -+ res = clk_set_parent(psSysSpecData->psSGX_FCK, psSysSpecData->psCORE_CK); -+ if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't set SGX parent clock (%d)", res)); -+ return PVRSRV_ERROR_UNABLE_TO_GET_PARENT_CLOCK; -+ } -+ -+ -+ psSysSpecData->bSysClocksOneTimeInit = IMG_TRUE; -+ -+ -+#endif -+ -+ } -+ -+ return AcquireGPTimer(psSysSpecData); -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function DisableSystemClocks -+ -+ @Description Disable the graphics clocks. -+ -+ @Return none -+ -+******************************************************************************/ -+IMG_VOID DisableSystemClocks(SYS_DATA *psSysData) -+{ -+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; -+ -+ PVR_TRACE(("DisableSystemClocks: Disabling System Clocks")); -+ -+ /* -+ * Always disable the SGX clocks when the system clocks are disabled. -+ * This saves having to make an explicit call to DisableSGXClocks if -+ * active power management is enabled. -+ */ -+ DisableSGXClocks(psSysData); -+ -+ ReleaseGPTimer(psSysSpecData); -+} -+ -+PVRSRV_ERROR SysPMRuntimeRegister(void) -+{ -+#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) -+#if defined(PM_RUNTIME_SUPPORT) -+ pm_runtime_enable(&gpsPVRLDMDev->dev); -+#endif -+#endif -+ return PVRSRV_OK; -+} -+ -+PVRSRV_ERROR SysPMRuntimeUnregister(void) -+{ -+#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) -+#if defined(PM_RUNTIME_SUPPORT) -+ pm_runtime_disable(&gpsPVRLDMDev->dev); -+#endif -+#endif -+ return PVRSRV_OK; -+} -+ -+PVRSRV_ERROR SysDvfsInitialize(SYS_SPECIFIC_DATA *psSysSpecificData) -+{ -+#if !defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) -+ PVR_UNREFERENCED_PARAMETER(psSysSpecificData); -+#else /* !defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) */ -+ IMG_UINT32 i, *freq_list; -+ IMG_INT32 opp_count; -+ unsigned long freq; -+ struct opp *opp; -+ -+ /* -+ * We query and store the list of SGX frequencies just this once under the -+ * assumption that they are unchanging, e.g. no disabling of high frequency -+ * option for thermal management. This is currently valid for 4430 and 4460. -+ */ -+ rcu_read_lock(); -+ opp_count = opp_get_opp_count(&gpsPVRLDMDev->dev); -+ if (opp_count < 1) -+ { -+ rcu_read_unlock(); -+ PVR_DPF((PVR_DBG_ERROR, "SysDvfsInitialize: Could not retrieve opp count")); -+ return PVRSRV_ERROR_NOT_SUPPORTED; -+ } -+ -+ /* -+ * Allocate the frequency list with a slot for each available frequency plus -+ * one additional slot to hold a designated frequency value to assume when in -+ * an unknown frequency state. -+ */ -+ freq_list = kmalloc((opp_count + 1) * sizeof(IMG_UINT32), GFP_ATOMIC); -+ if (!freq_list) -+ { -+ rcu_read_unlock(); -+ PVR_DPF((PVR_DBG_ERROR, "SysDvfsInitialize: Could not allocate frequency list")); -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ -+ /* -+ * Fill in frequency list from lowest to highest then finally the "unknown" -+ * frequency value. We use the highest available frequency as our assumed value -+ * when in an unknown state, because it is safer for APM and hardware recovery -+ * timers to be longer than intended rather than shorter. -+ */ -+ freq = 0; -+ for (i = 0; i < opp_count; i++) -+ { -+ opp = opp_find_freq_ceil(&gpsPVRLDMDev->dev, &freq); -+ if (IS_ERR_OR_NULL(opp)) -+ { -+ rcu_read_unlock(); -+ PVR_DPF((PVR_DBG_ERROR, "SysDvfsInitialize: Could not retrieve opp level %d", i)); -+ kfree(freq_list); -+ return PVRSRV_ERROR_NOT_SUPPORTED; -+ } -+ freq_list[i] = (IMG_UINT32)freq; -+ freq++; -+ } -+ rcu_read_unlock(); -+ freq_list[opp_count] = freq_list[opp_count - 1]; -+ -+ psSysSpecificData->ui32SGXFreqListSize = opp_count + 1; -+ psSysSpecificData->pui32SGXFreqList = freq_list; -+ -+ /* Start in unknown state - no frequency request to DVFS yet made */ -+ psSysSpecificData->ui32SGXFreqListIndex = opp_count; -+#endif /* !defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) */ -+ -+ return PVRSRV_OK; -+} -+ -+PVRSRV_ERROR SysDvfsDeinitialize(SYS_SPECIFIC_DATA *psSysSpecificData) -+{ -+#if !defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) -+ PVR_UNREFERENCED_PARAMETER(psSysSpecificData); -+#else /* !defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) */ -+ /* -+ * We assume this function is only called if SysDvfsInitialize() was -+ * completed successfully before. -+ * -+ * The DVFS interface does not allow us to actually unregister as a -+ * user of SGX, so we do the next best thing which is to lower our -+ * required frequency to the minimum if not already set. DVFS may -+ * report busy if early in initialization, but all other errors are -+ * considered serious. -+ */ -+ if (psSysSpecificData->ui32SGXFreqListIndex != 0) -+ { -+ struct gpu_platform_data *pdata; -+ IMG_INT32 res; -+ -+ pdata = (struct gpu_platform_data *)gpsPVRLDMDev->dev.platform_data; -+ -+ PVR_ASSERT(pdata->device_scale != IMG_NULL); -+ res = pdata->device_scale(&gpsPVRLDMDev->dev, -+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3,4,0)) -+ &gpsPVRLDMDev->dev, -+#endif -+ psSysSpecificData->pui32SGXFreqList[0]); -+ if (res == -EBUSY) -+ { -+ PVR_DPF((PVR_DBG_WARNING, "SysDvfsDeinitialize: Unable to scale SGX frequency (EBUSY)")); -+ } -+ else if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SysDvfsDeinitialize: Unable to scale SGX frequency (%d)", res)); -+ } -+ -+ psSysSpecificData->ui32SGXFreqListIndex = 0; -+ } -+ -+ kfree(psSysSpecificData->pui32SGXFreqList); -+ psSysSpecificData->pui32SGXFreqList = 0; -+ psSysSpecificData->ui32SGXFreqListSize = 0; -+#endif /* !defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) */ -+ -+ return PVRSRV_OK; -+} -+ -+#if defined(SUPPORT_DRI_DRM_PLUGIN) -+static struct omap_gpu_plugin sOMAPGPUPlugin; -+ -+#define SYS_DRM_SET_PLUGIN_FIELD(d, s, f) (d)->f = (s)->f -+int -+SysDRMRegisterPlugin(PVRSRV_DRM_PLUGIN *psDRMPlugin) -+{ -+ int iRes; -+ -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, name); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, open); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, load); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, unload); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, release); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, mmap); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, ioctls); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, num_ioctls); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, ioctl_start); -+ -+ iRes = omap_gpu_register_plugin(&sOMAPGPUPlugin); -+ if (iRes != 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: omap_gpu_register_plugin failed (%d)", __FUNCTION__, iRes)); -+ } -+ -+ return iRes; -+} -+ -+void -+SysDRMUnregisterPlugin(PVRSRV_DRM_PLUGIN *psDRMPlugin) -+{ -+ int iRes = omap_gpu_unregister_plugin(&sOMAPGPUPlugin); -+ if (iRes != 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: omap_gpu_unregister_plugin failed (%d)", __FUNCTION__, iRes)); -+ } -+} -+#endif -diff --git a/drivers/staging/ti-es8-sgx/services4/system/omap3630/oemfuncs.h b/drivers/staging/ti-es8-sgx/services4/system/omap3630/oemfuncs.h -new file mode 100644 -index 0000000..77c70d6 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/omap3630/oemfuncs.h -@@ -0,0 +1,78 @@ -+/*************************************************************************/ /*! -+@Title SGX kernel/client driver interface structures and prototypes -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#if !defined(__OEMFUNCS_H__) -+#define __OEMFUNCS_H__ -+ -+#if defined (__cplusplus) -+extern "C" { -+#endif -+ -+/* function in/out data structures: */ -+typedef IMG_UINT32 (*PFN_SRV_BRIDGEDISPATCH)( IMG_UINT32 Ioctl, -+ IMG_BYTE *pInBuf, -+ IMG_UINT32 InBufLen, -+ IMG_BYTE *pOutBuf, -+ IMG_UINT32 OutBufLen, -+ IMG_UINT32 *pdwBytesTransferred); -+/* -+ Function table for kernel 3rd party driver to kernel services -+*/ -+typedef struct PVRSRV_DC_OEM_JTABLE_TAG -+{ -+ PFN_SRV_BRIDGEDISPATCH pfnOEMBridgeDispatch; -+ IMG_PVOID pvDummy1; -+ IMG_PVOID pvDummy2; -+ IMG_PVOID pvDummy3; -+ -+} PVRSRV_DC_OEM_JTABLE; -+ -+#define OEM_GET_EXT_FUNCS (1<<1) -+ -+#if defined(__cplusplus) -+} -+#endif -+ -+#endif /* __OEMFUNCS_H__ */ -+ -+/***************************************************************************** -+ End of file (oemfuncs.h) -+*****************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/system/omap3630/sysconfig.c b/drivers/staging/ti-es8-sgx/services4/system/omap3630/sysconfig.c -new file mode 100644 -index 0000000..f38292e ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/omap3630/sysconfig.c -@@ -0,0 +1,1274 @@ -+/*************************************************************************/ /*! -+@Title System Configuration -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description System Configuration functions -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#include "sysconfig.h" -+#include "services_headers.h" -+#include "kerneldisplay.h" -+#include "oemfuncs.h" -+#include "sgxinfo.h" -+#include "sgxinfokm.h" -+#include "syslocal.h" -+ -+#include "ocpdefs.h" -+ -+/* top level system data anchor point*/ -+SYS_DATA* gpsSysData = (SYS_DATA*)IMG_NULL; -+SYS_DATA gsSysData; -+ -+static SYS_SPECIFIC_DATA gsSysSpecificData; -+SYS_SPECIFIC_DATA *gpsSysSpecificData; -+ -+/* SGX structures */ -+static IMG_UINT32 gui32SGXDeviceID; -+static SGX_DEVICE_MAP gsSGXDeviceMap; -+static PVRSRV_DEVICE_NODE *gpsSGXDevNode; -+ -+ -+#if defined(NO_HARDWARE) || defined(SGX_OCP_REGS_ENABLED) -+static IMG_CPU_VIRTADDR gsSGXRegsCPUVAddr; -+#endif -+ -+#if defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO) -+extern struct platform_device *gpsPVRLDMDev; -+#endif -+ -+IMG_UINT32 PVRSRV_BridgeDispatchKM(IMG_UINT32 Ioctl, -+ IMG_BYTE *pInBuf, -+ IMG_UINT32 InBufLen, -+ IMG_BYTE *pOutBuf, -+ IMG_UINT32 OutBufLen, -+ IMG_UINT32 *pdwBytesTransferred); -+ -+#if defined(SGX_OCP_REGS_ENABLED) -+ -+static IMG_CPU_VIRTADDR gpvOCPRegsLinAddr; -+ -+static PVRSRV_ERROR EnableSGXClocksWrap(SYS_DATA *psSysData) -+{ -+ PVRSRV_ERROR eError = EnableSGXClocks(psSysData); -+ -+#if !defined(SGX_OCP_NO_INT_BYPASS) -+ if(eError == PVRSRV_OK) -+ { -+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_SYSCONFIG, 0x14); -+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_DEBUG_CONFIG, EUR_CR_OCP_DEBUG_CONFIG_THALIA_INT_BYPASS_MASK); -+ } -+#endif -+ return eError; -+} -+ -+#else /* defined(SGX_OCP_REGS_ENABLED) */ -+ -+static INLINE PVRSRV_ERROR EnableSGXClocksWrap(SYS_DATA *psSysData) -+{ -+ return EnableSGXClocks(psSysData); -+} -+ -+#endif /* defined(SGX_OCP_REGS_ENABLED) */ -+ -+static INLINE PVRSRV_ERROR EnableSystemClocksWrap(SYS_DATA *psSysData) -+{ -+ PVRSRV_ERROR eError = EnableSystemClocks(psSysData); -+ -+#if !defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ if(eError == PVRSRV_OK) -+ { -+ /* -+ * The SGX Clocks are enabled separately if active power -+ * management is enabled. -+ */ -+ eError = EnableSGXClocksWrap(psSysData); -+ if (eError != PVRSRV_OK) -+ { -+ DisableSystemClocks(psSysData); -+ } -+ } -+#endif -+ -+ return eError; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function SysLocateDevices -+ -+ @Description Specifies devices in the systems memory map -+ -+ @Input psSysData - sys data -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+static PVRSRV_ERROR SysLocateDevices(SYS_DATA *psSysData) -+{ -+#if defined(NO_HARDWARE) -+ PVRSRV_ERROR eError; -+ IMG_CPU_PHYADDR sCpuPAddr; -+#else -+#if defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO) -+ struct resource *dev_res; -+ int dev_irq; -+#endif -+#endif -+ -+ PVR_UNREFERENCED_PARAMETER(psSysData); -+ -+ /* SGX Device: */ -+ gsSGXDeviceMap.ui32Flags = 0x0; -+ -+#if defined(NO_HARDWARE) -+ /* -+ * For no hardware, allocate some contiguous memory for the -+ * register block. -+ */ -+ -+ /* Registers */ -+ gsSGXDeviceMap.ui32RegsSize = SYS_OMAP3630_SGX_REGS_SIZE; -+ -+ eError = OSBaseAllocContigMemory(gsSGXDeviceMap.ui32RegsSize, -+ &gsSGXRegsCPUVAddr, -+ &sCpuPAddr); -+ if(eError != PVRSRV_OK) -+ { -+ return eError; -+ } -+ gsSGXDeviceMap.sRegsCpuPBase = sCpuPAddr; -+ gsSGXDeviceMap.sRegsSysPBase = SysCpuPAddrToSysPAddr(gsSGXDeviceMap.sRegsCpuPBase); -+#if defined(__linux__) -+ /* Indicate the registers are already mapped */ -+ gsSGXDeviceMap.pvRegsCpuVBase = gsSGXRegsCPUVAddr; -+#else -+ /* -+ * FIXME: Could we just use the virtual address returned by -+ * OSBaseAllocContigMemory? -+ */ -+ gsSGXDeviceMap.pvRegsCpuVBase = IMG_NULL; -+#endif -+ -+ OSMemSet(gsSGXRegsCPUVAddr, 0, gsSGXDeviceMap.ui32RegsSize); -+ -+ /* -+ device interrupt IRQ -+ Note: no interrupts available on no hardware system -+ */ -+ gsSGXDeviceMap.ui32IRQ = 0; -+ -+#else /* defined(NO_HARDWARE) */ -+#if defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO) -+ /* get the resource and IRQ through platform resource API */ -+ dev_res = platform_get_resource(gpsPVRLDMDev, IORESOURCE_MEM, 0); -+ if (dev_res == NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: platform_get_resource failed", __FUNCTION__)); -+ return PVRSRV_ERROR_INVALID_DEVICE; -+ } -+ -+ dev_irq = platform_get_irq(gpsPVRLDMDev, 0); -+ if (dev_irq < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: platform_get_irq failed (%d)", __FUNCTION__, -dev_irq)); -+ return PVRSRV_ERROR_INVALID_DEVICE; -+ } -+ -+ gsSGXDeviceMap.sRegsSysPBase.uiAddr = dev_res->start; -+ gsSGXDeviceMap.sRegsCpuPBase = -+ SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sRegsSysPBase); -+ PVR_TRACE(("SGX register base: 0x%lx", (unsigned long)gsSGXDeviceMap.sRegsCpuPBase.uiAddr)); -+ -+#if defined(SGX544) && defined(SGX_FEATURE_MP) -+ /* FIXME: Workaround due to HWMOD change. Otherwise this region is too small. */ -+ gsSGXDeviceMap.ui32RegsSize = SYS_OMAP3630_SGX_REGS_SIZE; -+#else -+ gsSGXDeviceMap.ui32RegsSize = (unsigned int)(dev_res->end - dev_res->start); -+#endif -+ PVR_TRACE(("SGX register size: %d",gsSGXDeviceMap.ui32RegsSize)); -+ -+ gsSGXDeviceMap.ui32IRQ = dev_irq; -+ PVR_TRACE(("SGX IRQ: %d", gsSGXDeviceMap.ui32IRQ)); -+#else /* defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO) */ -+ gsSGXDeviceMap.sRegsSysPBase.uiAddr = SYS_OMAP3630_SGX_REGS_SYS_PHYS_BASE; -+ gsSGXDeviceMap.sRegsCpuPBase = SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sRegsSysPBase); -+ gsSGXDeviceMap.ui32RegsSize = SYS_OMAP3630_SGX_REGS_SIZE; -+ -+ gsSGXDeviceMap.ui32IRQ = SYS_OMAP3630_SGX_IRQ; -+ -+#endif /* defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO) */ -+#if defined(SGX_OCP_REGS_ENABLED) -+ gsSGXRegsCPUVAddr = OSMapPhysToLin(gsSGXDeviceMap.sRegsCpuPBase, -+ gsSGXDeviceMap.ui32RegsSize, -+ PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY, -+ IMG_NULL); -+ -+ if (gsSGXRegsCPUVAddr == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysLocateDevices: Failed to map SGX registers")); -+ return PVRSRV_ERROR_BAD_MAPPING; -+ } -+ -+ /* Indicate the registers are already mapped */ -+ gsSGXDeviceMap.pvRegsCpuVBase = gsSGXRegsCPUVAddr; -+ gpvOCPRegsLinAddr = gsSGXRegsCPUVAddr; -+#endif -+#endif /* defined(NO_HARDWARE) */ -+ -+#if defined(PDUMP) -+ { -+ /* initialise memory region name for pdumping */ -+ static IMG_CHAR pszPDumpDevName[] = "SGXMEM"; -+ gsSGXDeviceMap.pszPDumpDevName = pszPDumpDevName; -+ } -+#endif -+ -+ /* add other devices here: */ -+ -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysCreateVersionString -+ -+ @Description Read the version string -+ -+ @Return IMG_CHAR * : Version string -+ -+******************************************************************************/ -+static IMG_CHAR *SysCreateVersionString(void) -+{ -+ static IMG_CHAR aszVersionString[100]; -+ IMG_UINT32 ui32MaxStrLen; -+ SYS_DATA *psSysData; -+ IMG_UINT32 ui32SGXRevision; -+ IMG_INT32 i32Count; -+ -+ SysAcquireData(&psSysData); -+ -+ ui32SGXRevision = SGX_CORE_REV; -+ ui32MaxStrLen = 99; -+ -+ i32Count = OSSNPrintf(aszVersionString, ui32MaxStrLen + 1, -+ "SGX revision = %u", -+ (IMG_UINT)(ui32SGXRevision)); -+ if(i32Count == -1) -+ { -+ return IMG_NULL; -+ } -+ -+ return aszVersionString; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysInitialise -+ -+ @Description Initialises kernel services at 'driver load' time -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+PVRSRV_ERROR SysInitialise(IMG_VOID) -+{ -+ IMG_UINT32 i; -+ PVRSRV_ERROR eError; -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+#if !defined(PVR_NO_OMAP_TIMER) -+ IMG_CPU_PHYADDR TimerRegPhysBase; -+#endif -+#if !defined(SGX_DYNAMIC_TIMING_INFO) -+ SGX_TIMING_INFORMATION* psTimingInfo; -+#endif -+ gpsSysData = &gsSysData; -+ OSMemSet(gpsSysData, 0, sizeof(SYS_DATA)); -+ -+ gpsSysSpecificData = &gsSysSpecificData; -+ OSMemSet(gpsSysSpecificData, 0, sizeof(SYS_SPECIFIC_DATA)); -+ -+ gpsSysData->pvSysSpecificData = gpsSysSpecificData; -+ -+ eError = OSInitEnvData(&gpsSysData->pvEnvSpecificData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to setup env structure")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_ENVDATA); -+ -+ gpsSysData->ui32NumDevices = SYS_DEVICE_COUNT; -+ -+ /* init device ID's */ -+ for(i=0; i<SYS_DEVICE_COUNT; i++) -+ { -+ gpsSysData->sDeviceID[i].uiID = i; -+ gpsSysData->sDeviceID[i].bInUse = IMG_FALSE; -+ } -+ -+ gpsSysData->psDeviceNodeList = IMG_NULL; -+ gpsSysData->psQueueList = IMG_NULL; -+ -+ eError = SysInitialiseCommon(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed in SysInitialiseCommon")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ -+#if !defined(SGX_DYNAMIC_TIMING_INFO) -+ /* Set up timing information*/ -+ psTimingInfo = &gsSGXDeviceMap.sTimingInfo; -+ psTimingInfo->ui32CoreClockSpeed = SYS_SGX_CLOCK_SPEED; -+ psTimingInfo->ui32HWRecoveryFreq = SYS_SGX_HWRECOVERY_TIMEOUT_FREQ; -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ psTimingInfo->bEnableActivePM = IMG_TRUE; -+#else -+ psTimingInfo->bEnableActivePM = IMG_FALSE; -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ psTimingInfo->ui32ActivePowManLatencyms = SYS_SGX_ACTIVE_POWER_LATENCY_MS; -+ psTimingInfo->ui32uKernelFreq = SYS_SGX_PDS_TIMER_FREQ; -+#endif -+ -+ /* -+ Setup the Source Clock Divider value -+ */ -+ gpsSysSpecificData->ui32SrcClockDiv = 3; -+ -+ /* -+ Locate the devices within the system, specifying -+ the physical addresses of each devices components -+ (regs, mem, ports etc.) -+ */ -+ eError = SysLocateDevices(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to locate devices")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV); -+ -+ eError = SysPMRuntimeRegister(); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to register with OSPM!")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_PM_RUNTIME); -+ -+ eError = SysDvfsInitialize(gpsSysSpecificData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to initialize DVFS")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_DVFS_INIT); -+ -+ /* -+ Register devices with the system -+ This also sets up their memory maps/heaps -+ */ -+ eError = PVRSRVRegisterDevice(gpsSysData, SGXRegisterDevice, -+ DEVICE_SGX_INTERRUPT, &gui32SGXDeviceID); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to register device!")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_REGDEV); -+ -+ /* -+ Once all devices are registered, specify the backing store -+ and, if required, customise the memory heap config -+ */ -+ psDeviceNode = gpsSysData->psDeviceNodeList; -+ while(psDeviceNode) -+ { -+ /* perform any OEM SOC address space customisations here */ -+ switch(psDeviceNode->sDevId.eDeviceType) -+ { -+ case PVRSRV_DEVICE_TYPE_SGX: -+ { -+ DEVICE_MEMORY_INFO *psDevMemoryInfo; -+ DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; -+ -+ /* -+ specify the backing store to use for the devices MMU PT/PDs -+ - the PT/PDs are always UMA in this system -+ */ -+ psDeviceNode->psLocalDevMemArena = IMG_NULL; -+ -+ /* useful pointers */ -+ psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo; -+ psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap; -+ -+ /* specify the backing store for all SGX heaps */ -+ for(i=0; i<psDevMemoryInfo->ui32HeapCount; i++) -+ { -+ psDeviceMemoryHeap[i].ui32Attribs |= PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG; -+ } -+ -+ gpsSGXDevNode = psDeviceNode; -+ gsSysSpecificData.psSGXDevNode = psDeviceNode; -+ -+ break; -+ } -+ default: -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to find SGX device node!")); -+ return PVRSRV_ERROR_INIT_FAILURE; -+ } -+ -+ /* advance to next device */ -+ psDeviceNode = psDeviceNode->psNext; -+ } -+ -+ eError = EnableSystemClocksWrap(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable system clocks (%d)", eError)); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS); -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ eError = EnableSGXClocksWrap(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable SGX clocks (%d)", eError)); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ -+ eError = PVRSRVInitialiseDevice(gui32SGXDeviceID); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to initialise device!")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_INITDEV); -+ -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ /* SGX defaults to D3 power state */ -+ DisableSGXClocks(gpsSysData); -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ -+#if !defined(PVR_NO_OMAP_TIMER) -+#if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA) -+ TimerRegPhysBase = gsSysSpecificData.sTimerRegPhysBase; -+#else -+ TimerRegPhysBase.uiAddr = SYS_OMAP3630_GP11TIMER_REGS_SYS_PHYS_BASE; -+#endif -+ gpsSysData->pvSOCTimerRegisterKM = IMG_NULL; -+ gpsSysData->hSOCTimerRegisterOSMemHandle = 0; -+ if (TimerRegPhysBase.uiAddr != 0) -+ { -+ OSReservePhys(TimerRegPhysBase, -+ 4, -+ PVRSRV_HAP_MULTI_PROCESS|PVRSRV_HAP_UNCACHED, -+ IMG_NULL, -+ (IMG_VOID **)&gpsSysData->pvSOCTimerRegisterKM, -+ &gpsSysData->hSOCTimerRegisterOSMemHandle); -+ } -+#endif /* !defined(PVR_NO_OMAP_TIMER) */ -+ -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysFinalise -+ -+ @Description Final part of initialisation at 'driver load' time -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+PVRSRV_ERROR SysFinalise(IMG_VOID) -+{ -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ eError = EnableSGXClocksWrap(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to Enable SGX clocks (%d)", eError)); -+ return eError; -+ } -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ -+ eError = OSInstallMISR(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to install MISR")); -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_MISR); -+ -+#if defined(SYS_USING_INTERRUPTS) -+ /* install a Device ISR */ -+ eError = OSInstallDeviceLISR(gpsSysData, gsSGXDeviceMap.ui32IRQ, "SGX ISR", gpsSGXDevNode); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to install ISR")); -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR); -+#if !defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ SysEnableSGXInterrupts(gpsSysData); -+#endif -+#endif /* defined(SYS_USING_INTERRUPTS) */ -+#if defined(__linux__) -+ /* Create a human readable version string for this system */ -+ gpsSysData->pszVersionString = SysCreateVersionString(); -+ if (!gpsSysData->pszVersionString) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to create a system version string")); -+ } -+ else -+ { -+ PVR_TRACE(("SysFinalise: Version string: %s", gpsSysData->pszVersionString)); -+ } -+#endif -+ -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ /* SGX defaults to D3 power state */ -+ DisableSGXClocks(gpsSysData); -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ -+ gpsSysSpecificData->bSGXInitComplete = IMG_TRUE; -+ -+ return eError; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysDeinitialise -+ -+ @Description De-initialises kernel services at 'driver unload' time -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR SysDeinitialise (SYS_DATA *psSysData) -+{ -+ PVRSRV_ERROR eError; -+ -+ PVR_UNREFERENCED_PARAMETER(psSysData); -+ -+ if(gpsSysData->pvSOCTimerRegisterKM) -+ { -+ OSUnReservePhys(gpsSysData->pvSOCTimerRegisterKM, -+ 4, -+ PVRSRV_HAP_MULTI_PROCESS|PVRSRV_HAP_UNCACHED, -+ gpsSysData->hSOCTimerRegisterOSMemHandle); -+ } -+ -+ -+#if defined(SYS_USING_INTERRUPTS) -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR)) -+ { -+ eError = OSUninstallDeviceLISR(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: OSUninstallDeviceLISR failed")); -+ return eError; -+ } -+ } -+#endif -+ -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_MISR)) -+ { -+ eError = OSUninstallMISR(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: OSUninstallMISR failed")); -+ return eError; -+ } -+ } -+ -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_INITDEV)) -+ { -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ PVR_ASSERT(SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS)); -+ /* Reenable SGX clocks whilst SGX is being deinitialised. */ -+ eError = EnableSGXClocksWrap(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: EnableSGXClocks failed")); -+ return eError; -+ } -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ -+ /* Deinitialise SGX */ -+ eError = PVRSRVDeinitialiseDevice(gui32SGXDeviceID); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: failed to de-init the device")); -+ return eError; -+ } -+ } -+ -+ /* Disable system clocks. Must happen after last access to hardware */ -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS)) -+ { -+ DisableSystemClocks(gpsSysData); -+ } -+ -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_DVFS_INIT)) -+ { -+ eError = SysDvfsDeinitialize(gpsSysSpecificData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: Failed to de-init DVFS")); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ } -+ -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_PM_RUNTIME)) -+ { -+ eError = SysPMRuntimeUnregister(); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: Failed to unregister with OSPM!")); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ } -+ -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_ENVDATA)) -+ { -+ eError = OSDeInitEnvData(gpsSysData->pvEnvSpecificData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: failed to de-init env structure")); -+ return eError; -+ } -+ } -+ -+ SysDeinitialiseCommon(gpsSysData); -+ -+#if defined(NO_HARDWARE) || defined(SGX_OCP_REGS_ENABLED) -+ if(gsSGXRegsCPUVAddr != IMG_NULL) -+ { -+#if defined(NO_HARDWARE) -+ /* Free hardware resources. */ -+ OSBaseFreeContigMemory(SYS_OMAP3630_SGX_REGS_SIZE, gsSGXRegsCPUVAddr, gsSGXDeviceMap.sRegsCpuPBase); -+#else -+#if defined(SGX_OCP_REGS_ENABLED) -+ OSUnMapPhysToLin(gsSGXRegsCPUVAddr, -+ gsSGXDeviceMap.ui32RegsSize, -+ PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY, -+ IMG_NULL); -+ -+ gpvOCPRegsLinAddr = IMG_NULL; -+#endif -+#endif /* defined(NO_HARDWARE) */ -+ gsSGXRegsCPUVAddr = IMG_NULL; -+ gsSGXDeviceMap.pvRegsCpuVBase = gsSGXRegsCPUVAddr; -+ } -+#endif /* defined(NO_HARDWARE) || defined(SGX_OCP_REGS_ENABLED) */ -+ -+ -+ gpsSysSpecificData->ui32SysSpecificData = 0; -+ gpsSysSpecificData->bSGXInitComplete = IMG_FALSE; -+ -+ gpsSysData = IMG_NULL; -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysGetDeviceMemoryMap -+ -+ @Description returns a device address map for the specified device -+ -+ @Input eDeviceType - device type -+ @Input ppvDeviceMap - void ptr to receive device specific info. -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE eDeviceType, -+ IMG_VOID **ppvDeviceMap) -+{ -+ -+ switch(eDeviceType) -+ { -+ case PVRSRV_DEVICE_TYPE_SGX: -+ { -+ /* just return a pointer to the structure */ -+ *ppvDeviceMap = (IMG_VOID*)&gsSGXDeviceMap; -+ -+ break; -+ } -+ default: -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysGetDeviceMemoryMap: unsupported device type")); -+ } -+ } -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function SysCpuPAddrToDevPAddr -+ -+ @Description Compute a device physical address from a cpu physical -+ address. Relevant when -+ -+ @Input cpu_paddr - cpu physical address. -+ @Input eDeviceType - device type required if DevPAddr -+ address spaces vary across devices -+ in the same system -+ @Return device physical address. -+ -+******************************************************************************/ -+IMG_DEV_PHYADDR SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType, -+ IMG_CPU_PHYADDR CpuPAddr) -+{ -+ IMG_DEV_PHYADDR DevPAddr; -+ -+ PVR_UNREFERENCED_PARAMETER(eDeviceType); -+ -+ /* Note: for UMA system we assume DevP == CpuP */ -+ DevPAddr.uiAddr = CpuPAddr.uiAddr; -+ -+ return DevPAddr; -+} -+ -+/*! -+****************************************************************************** -+ @Function SysSysPAddrToCpuPAddr -+ -+ @Description Compute a cpu physical address from a system physical -+ address. -+ -+ @Input sys_paddr - system physical address. -+ @Return cpu physical address. -+ -+******************************************************************************/ -+IMG_CPU_PHYADDR SysSysPAddrToCpuPAddr (IMG_SYS_PHYADDR sys_paddr) -+{ -+ IMG_CPU_PHYADDR cpu_paddr; -+ -+ /* This would only be an inequality if the CPU's MMU did not point to -+ sys address 0, ie. multi CPU system */ -+ cpu_paddr.uiAddr = sys_paddr.uiAddr; -+ return cpu_paddr; -+} -+ -+/*! -+****************************************************************************** -+ @Function SysCpuPAddrToSysPAddr -+ -+ @Description Compute a system physical address from a cpu physical -+ address. -+ -+ @Input cpu_paddr - cpu physical address. -+ @Return device physical address. -+ -+******************************************************************************/ -+IMG_SYS_PHYADDR SysCpuPAddrToSysPAddr (IMG_CPU_PHYADDR cpu_paddr) -+{ -+ IMG_SYS_PHYADDR sys_paddr; -+ -+ /* This would only be an inequality if the CPU's MMU did not point to -+ sys address 0, ie. multi CPU system */ -+ sys_paddr.uiAddr = cpu_paddr.uiAddr; -+ return sys_paddr; -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function SysSysPAddrToDevPAddr -+ -+ @Description Compute a device physical address from a system physical -+ address. -+ -+ @Input SysPAddr - system physical address. -+ @Input eDeviceType - device type required if DevPAddr -+ address spaces vary across devices -+ in the same system -+ -+ @Return Device physical address. -+ -+******************************************************************************/ -+IMG_DEV_PHYADDR SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType, IMG_SYS_PHYADDR SysPAddr) -+{ -+ IMG_DEV_PHYADDR DevPAddr; -+ -+ PVR_UNREFERENCED_PARAMETER(eDeviceType); -+ -+ /* Note: for UMA system we assume DevP == CpuP */ -+ DevPAddr.uiAddr = SysPAddr.uiAddr; -+ -+ return DevPAddr; -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function SysDevPAddrToSysPAddr -+ -+ @Description Compute a device physical address from a system physical -+ address. -+ -+ @Input DevPAddr - device physical address. -+ @Input eDeviceType - device type required if DevPAddr -+ address spaces vary across devices -+ in the same system -+ -+ @Return System physical address. -+ -+******************************************************************************/ -+IMG_SYS_PHYADDR SysDevPAddrToSysPAddr(PVRSRV_DEVICE_TYPE eDeviceType, IMG_DEV_PHYADDR DevPAddr) -+{ -+ IMG_SYS_PHYADDR SysPAddr; -+ -+ PVR_UNREFERENCED_PARAMETER(eDeviceType); -+ -+ /* Note: for UMA system we assume DevP == SysP */ -+ SysPAddr.uiAddr = DevPAddr.uiAddr; -+ -+ return SysPAddr; -+} -+ -+ -+/***************************************************************************** -+ @Function SysRegisterExternalDevice -+ -+ @Description Called when a 3rd party device registers with services -+ -+ @Input psDeviceNode - the new device node. -+ -+ @Return IMG_VOID -+*****************************************************************************/ -+IMG_VOID SysRegisterExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode) -+{ -+ PVR_UNREFERENCED_PARAMETER(psDeviceNode); -+} -+ -+ -+/***************************************************************************** -+ @Function SysRemoveExternalDevice -+ -+ @Description Called when a 3rd party device unregisters from services -+ -+ @Input psDeviceNode - the device node being removed. -+ -+ @Return IMG_VOID -+*****************************************************************************/ -+IMG_VOID SysRemoveExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode) -+{ -+ PVR_UNREFERENCED_PARAMETER(psDeviceNode); -+} -+ -+/*! -+****************************************************************************** -+ @Function SysGetInterruptSource -+ -+ @Description Returns System specific information about the device(s) that -+ generated the interrupt in the system -+ -+ @Input psSysData -+ @Input psDeviceNode -+ -+ @Return System specific information indicating which device(s) -+ generated the interrupt -+ -+******************************************************************************/ -+IMG_UINT32 SysGetInterruptSource(SYS_DATA *psSysData, -+ PVRSRV_DEVICE_NODE *psDeviceNode) -+{ -+ PVR_UNREFERENCED_PARAMETER(psSysData); -+#if defined(NO_HARDWARE) -+ /* no interrupts in no_hw system just return all bits */ -+ return 0xFFFFFFFF; -+#else -+ /* Not a shared irq, so we know this is an interrupt for this device */ -+ return psDeviceNode->ui32SOCInterruptBit; -+#endif -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function SysClearInterrupts -+ -+ @Description Clears specified system interrupts -+ -+ @Input psSysData -+ @Input ui32ClearBits -+ -+ @Return IMG_VOID -+ -+******************************************************************************/ -+IMG_VOID SysClearInterrupts(SYS_DATA* psSysData, IMG_UINT32 ui32ClearBits) -+{ -+ PVR_UNREFERENCED_PARAMETER(ui32ClearBits); -+ PVR_UNREFERENCED_PARAMETER(psSysData); -+#if !defined(NO_HARDWARE) -+#if defined(SGX_OCP_NO_INT_BYPASS) -+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_IRQSTATUS_2, 0x1); -+#endif -+ /* Flush posted writes */ -+ OSReadHWReg(((PVRSRV_SGXDEV_INFO *)gpsSGXDevNode->pvDevice)->pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR); -+#endif /* defined(NO_HARDWARE) */ -+} -+ -+#if defined(SGX_OCP_NO_INT_BYPASS) -+/*! -+****************************************************************************** -+ @Function SysEnableSGXInterrupts -+ -+ @Description Enables SGX interrupts -+ -+ @Input psSysData -+ -+ @Return IMG_VOID -+ -+******************************************************************************/ -+IMG_VOID SysEnableSGXInterrupts(SYS_DATA *psSysData) -+{ -+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *)psSysData->pvSysSpecificData; -+ if (SYS_SPECIFIC_DATA_TEST(psSysSpecData, SYS_SPECIFIC_DATA_ENABLE_LISR) && !SYS_SPECIFIC_DATA_TEST(psSysSpecData, SYS_SPECIFIC_DATA_IRQ_ENABLED)) -+ { -+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_IRQSTATUS_2, 0x1); -+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_IRQENABLE_SET_2, 0x1); -+ SYS_SPECIFIC_DATA_SET(psSysSpecData, SYS_SPECIFIC_DATA_IRQ_ENABLED); -+ } -+} -+ -+/*! -+****************************************************************************** -+ @Function SysDisableSGXInterrupts -+ -+ @Description Disables SGX interrupts -+ -+ @Input psSysData -+ -+ @Return IMG_VOID -+ -+******************************************************************************/ -+IMG_VOID SysDisableSGXInterrupts(SYS_DATA *psSysData) -+{ -+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *)psSysData->pvSysSpecificData; -+ -+ if (SYS_SPECIFIC_DATA_TEST(psSysSpecData, SYS_SPECIFIC_DATA_IRQ_ENABLED)) -+ { -+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_IRQENABLE_CLR_2, 0x1); -+ SYS_SPECIFIC_DATA_CLEAR(psSysSpecData, SYS_SPECIFIC_DATA_IRQ_ENABLED); -+ } -+} -+#endif /* defined(SGX_OCP_NO_INT_BYPASS) */ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysSystemPrePowerState -+ -+ @Description Perform system-level processing required before a power transition -+ -+ @Input eNewPowerState : -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR SysSystemPrePowerState(PVRSRV_SYS_POWER_STATE eNewPowerState) -+{ -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ -+ if (eNewPowerState == PVRSRV_SYS_POWER_STATE_D3) -+ { -+ PVR_TRACE(("SysSystemPrePowerState: Entering state D3")); -+ -+#if defined(SYS_USING_INTERRUPTS) -+ if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR)) -+ { -+#if defined(SYS_CUSTOM_POWERLOCK_WRAP) -+ IMG_BOOL bWrapped = WrapSystemPowerChange(&gsSysSpecificData); -+#endif -+ eError = OSUninstallDeviceLISR(gpsSysData); -+#if defined(SYS_CUSTOM_POWERLOCK_WRAP) -+ if (bWrapped) -+ { -+ UnwrapSystemPowerChange(&gsSysSpecificData); -+ } -+#endif -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysSystemPrePowerState: OSUninstallDeviceLISR failed (%d)", eError)); -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR); -+ SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR); -+ } -+#endif -+ -+ if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS)) -+ { -+ DisableSystemClocks(gpsSysData); -+ -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS); -+ SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS); -+ } -+ } -+ -+ return eError; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysSystemPostPowerState -+ -+ @Description Perform system-level processing required after a power transition -+ -+ @Input eNewPowerState : -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR SysSystemPostPowerState(PVRSRV_SYS_POWER_STATE eNewPowerState) -+{ -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ -+ if (eNewPowerState == PVRSRV_SYS_POWER_STATE_D0) -+ { -+ PVR_TRACE(("SysSystemPostPowerState: Entering state D0")); -+ -+ if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS)) -+ { -+ eError = EnableSystemClocksWrap(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysSystemPostPowerState: EnableSystemClocksWrap failed (%d)", eError)); -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS); -+ SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS); -+ } -+ -+#if defined(SYS_USING_INTERRUPTS) -+ if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR)) -+ { -+#if defined(SYS_CUSTOM_POWERLOCK_WRAP) -+ IMG_BOOL bWrapped = WrapSystemPowerChange(&gsSysSpecificData); -+#endif -+ -+ eError = OSInstallDeviceLISR(gpsSysData, gsSGXDeviceMap.ui32IRQ, "SGX ISR", gpsSGXDevNode); -+#if defined(SYS_CUSTOM_POWERLOCK_WRAP) -+ if (bWrapped) -+ { -+ UnwrapSystemPowerChange(&gsSysSpecificData); -+ } -+#endif -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysSystemPostPowerState: OSInstallDeviceLISR failed to install ISR (%d)", eError)); -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR); -+ SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR); -+ } -+#endif -+ } -+ return eError; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysDevicePrePowerState -+ -+ @Description Perform system level processing required before a device power -+ transition -+ -+ @Input ui32DeviceIndex : -+ @Input eNewPowerState : -+ @Input eCurrentPowerState : -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR SysDevicePrePowerState(IMG_UINT32 ui32DeviceIndex, -+ PVRSRV_DEV_POWER_STATE eNewPowerState, -+ PVRSRV_DEV_POWER_STATE eCurrentPowerState) -+{ -+ PVR_UNREFERENCED_PARAMETER(eCurrentPowerState); -+ -+ if (ui32DeviceIndex != gui32SGXDeviceID) -+ { -+ return PVRSRV_OK; -+ } -+ -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ if (eNewPowerState == PVRSRV_DEV_POWER_STATE_OFF) -+ { -+ PVR_DPF((PVR_DBG_MESSAGE, "SysDevicePrePowerState: SGX Entering state D3")); -+ DisableSGXClocks(gpsSysData); -+ } -+#else /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ PVR_UNREFERENCED_PARAMETER(eNewPowerState ); -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysDevicePostPowerState -+ -+ @Description Perform system level processing required after a device power -+ transition -+ -+ @Input ui32DeviceIndex : -+ @Input eNewPowerState : -+ @Input eCurrentPowerState : -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR SysDevicePostPowerState(IMG_UINT32 ui32DeviceIndex, -+ PVRSRV_DEV_POWER_STATE eNewPowerState, -+ PVRSRV_DEV_POWER_STATE eCurrentPowerState) -+{ -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ -+ PVR_UNREFERENCED_PARAMETER(eNewPowerState); -+ -+ if (ui32DeviceIndex != gui32SGXDeviceID) -+ { -+ return eError; -+ } -+ -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ if (eCurrentPowerState == PVRSRV_DEV_POWER_STATE_OFF) -+ { -+ PVR_DPF((PVR_DBG_MESSAGE, "SysDevicePostPowerState: SGX Leaving state D3")); -+ eError = EnableSGXClocksWrap(gpsSysData); -+ } -+#else /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ PVR_UNREFERENCED_PARAMETER(eCurrentPowerState); -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ -+ return eError; -+} -+ -+#if defined(SYS_SUPPORTS_SGX_IDLE_CALLBACK) -+ -+IMG_VOID SysSGXIdleTransition(IMG_BOOL bSGXIdle) -+{ -+ PVR_DPF((PVR_DBG_MESSAGE, "SysSGXIdleTransition switch to %u", bSGXIdle)); -+} -+ -+#endif /* defined(SYS_SUPPORTS_SGX_IDLE_CALLBACK) */ -+ -+/***************************************************************************** -+ @Function SysOEMFunction -+ -+ @Description marshalling function for custom OEM functions -+ -+ @Input ui32ID - function ID -+ @Input pvIn - in data -+ @Output pvOut - out data -+ -+ @Return PVRSRV_ERROR -+*****************************************************************************/ -+PVRSRV_ERROR SysOEMFunction ( IMG_UINT32 ui32ID, -+ IMG_VOID *pvIn, -+ IMG_UINT32 ulInSize, -+ IMG_VOID *pvOut, -+ IMG_UINT32 ulOutSize) -+{ -+ PVR_UNREFERENCED_PARAMETER(ui32ID); -+ PVR_UNREFERENCED_PARAMETER(pvIn); -+ PVR_UNREFERENCED_PARAMETER(ulInSize); -+ PVR_UNREFERENCED_PARAMETER(pvOut); -+ PVR_UNREFERENCED_PARAMETER(ulOutSize); -+ -+ if ((ui32ID == OEM_GET_EXT_FUNCS) && -+ (ulOutSize == sizeof(PVRSRV_DC_OEM_JTABLE))) -+ { -+ PVRSRV_DC_OEM_JTABLE *psOEMJTable = (PVRSRV_DC_OEM_JTABLE*) pvOut; -+ psOEMJTable->pfnOEMBridgeDispatch = &PVRSRV_BridgeDispatchKM; -+ return PVRSRV_OK; -+ } -+ -+ return PVRSRV_ERROR_INVALID_PARAMS; -+} -+/****************************************************************************** -+ End of file (sysconfig.c) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/system/omap3630/sysconfig.h b/drivers/staging/ti-es8-sgx/services4/system/omap3630/sysconfig.h -new file mode 100644 -index 0000000..06be1ee ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/omap3630/sysconfig.h -@@ -0,0 +1,109 @@ -+/*************************************************************************/ /*! -+@Title System Description Header -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description This header provides system-specific declarations and macros -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#if !defined(__SOCCONFIG_H__) -+#define __SOCCONFIG_H__ -+ -+#define VS_PRODUCT_NAME "OMAP3630" -+ -+ -+#define SYS_SGX_HWRECOVERY_TIMEOUT_FREQ (100) // 10ms (100hz) -+#define SYS_SGX_PDS_TIMER_FREQ (1000) // 1ms (1000hz) -+ -+/* Allow the AP latency to be overridden in the build config */ -+#if !defined(SYS_SGX_ACTIVE_POWER_LATENCY_MS) -+#define SYS_SGX_ACTIVE_POWER_LATENCY_MS (2) -+#endif -+ -+ -+#define SYS_OMAP3630_SGX_REGS_SYS_PHYS_BASE 0x50000000 -+#define SYS_OMAP3630_SGX_REGS_SIZE 0x10000 -+ -+#define SYS_OMAP3630_SGX_IRQ 21 /* OMAP4 IRQ's are offset by 32 */ -+ -+#define SYS_OMAP_DSS_REGS_SYS_PHYS_BASE 0x58000000 -+#define SYS_OMAP_DSS_REGS_SIZE 0x7000 -+ -+#define SYS_OMAP_DSS_HDMI_INTERRUPT_STATUS_REG 0x6028 -+#define SYS_OMAP_DSS_HDMI_INTERRUPT_ENABLE_REG 0x602c -+ -+#define SYS_OMAP_DSS_HDMI_INTERRUPT_VSYNC_ENABLE_MASK 0x10000 -+#define SYS_OMAP_DSS_HDMI_INTERRUPT_VSYNC_STATUS_MASK 0x10000 -+ -+#define SYS_OMAP_DSS_LCD_INTERRUPT_STATUS_REG 0x1018 -+#define SYS_OMAP_DSS_LCD_INTERRUPT_ENABLE_REG 0x101c -+ -+#define SYS_OMAP_DSS_LCD_INTERRUPT_VSYNC_ENABLE_MASK 0x40002 -+#define SYS_OMAP_DSS_LCD_INTERRUPT_VSYNC_STATUS_MASK 0x40002 -+ -+ -+#define SYS_OMAP3630_GP11TIMER_ENABLE_SYS_PHYS_BASE 0x48088024 -+#define SYS_OMAP3630_GP11TIMER_REGS_SYS_PHYS_BASE 0x48088028 -+#define SYS_OMAP3630_GP11TIMER_TSICR_SYS_PHYS_BASE 0x48088040 -+ -+ -+ -+/* Interrupt bits */ -+#define DEVICE_SGX_INTERRUPT (1<<0) -+#define DEVICE_MSVDX_INTERRUPT (1<<1) -+#define DEVICE_DISP_INTERRUPT (1<<2) -+ -+#if 0 -+#if defined(__linux__) -+/* -+ * Recent OMAP4 kernels register SGX as platform device "omap_gpu". -+ * This device must be used with the Linux power management calls -+ * in sysutils_linux.c, in order for SGX to be powered on. -+ */ -+#if defined(PVR_LDM_PLATFORM_PRE_REGISTERED_DEV) -+#define SYS_SGX_DEV_NAME PVR_LDM_PLATFORM_PRE_REGISTERED_DEV -+#else -+#define SYS_SGX_DEV_NAME "omap_gpu" -+#endif /* defined(PVR_LDM_PLATFORM_PRE_REGISTERED_DEV) */ -+#endif /* defined(__linux__) */ -+#endif -+ -+/***************************************************************************** -+ * system specific data structures -+ *****************************************************************************/ -+ -+#endif /* __SYSCONFIG_H__ */ -diff --git a/drivers/staging/ti-es8-sgx/services4/system/omap3630/sysinfo.h b/drivers/staging/ti-es8-sgx/services4/system/omap3630/sysinfo.h -new file mode 100644 -index 0000000..7383b9c ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/omap3630/sysinfo.h -@@ -0,0 +1,70 @@ -+/*************************************************************************/ /*! -+@Title System Description Header -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description This header provides system-specific declarations and macros -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#if !defined(__SYSINFO_H__) -+#define __SYSINFO_H__ -+ -+#if defined(SGX540) && (SGX_CORE_REV == 120) -+#define SYS_SGX_CLOCK_SPEED 307200000 -+#else -+#define SYS_SGX_CLOCK_SPEED 200000000 -+#endif -+ -+/*!< System specific poll/timeout details */ -+#if defined(PVR_LINUX_USING_WORKQUEUES) -+/* -+ * The workqueue based 3rd party display driver may be blocked for up -+ * to 500ms waiting for a vsync when the screen goes blank, so we -+ * need to wait longer for the hardware if a flush of the swap chain is -+ * required. -+ */ -+#define MAX_HW_TIME_US (1000000) -+#define WAIT_TRY_COUNT (20000) -+#else -+#define MAX_HW_TIME_US (500000) -+#define WAIT_TRY_COUNT (10000) -+#endif -+ -+ -+#define SYS_DEVICE_COUNT 15 /* SGX, DISPLAYCLASS (external), BUFFERCLASS (external) */ -+ -+#endif /* __SYSINFO_H__ */ -diff --git a/drivers/staging/ti-es8-sgx/services4/system/omap3630/syslocal.h b/drivers/staging/ti-es8-sgx/services4/system/omap3630/syslocal.h -new file mode 100644 -index 0000000..c849332 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/omap3630/syslocal.h -@@ -0,0 +1,264 @@ -+/*************************************************************************/ /*! -+@Title Local system definitions -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description This header provides local system declarations and macros -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#if !defined(__SYSLOCAL_H__) -+#define __SYSLOCAL_H__ -+ -+#if defined(__linux__) -+ -+#include <linux/version.h> -+#include <linux/clk.h> -+#if defined(PVR_LINUX_USING_WORKQUEUES) -+#include <linux/mutex.h> -+#else -+#include <linux/spinlock.h> -+#endif -+#include <asm/atomic.h> -+ -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)) -+#include <linux/semaphore.h> -+#include <linux/resource.h> -+#else /* (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)) */ -+#include <asm/semaphore.h> -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22)) -+#include <asm/arch/resource.h> -+#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22)) */ -+#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)) */ -+ -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) -+#if !defined(LDM_PLATFORM) -+#error "LDM_PLATFORM must be set" -+#endif -+//#define PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO -+//#include <linux/platform_device.h> -+#endif -+ -+#if ((defined(DEBUG) || defined(TIMING)) && \ -+ (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32))) && \ -+ !defined(PVR_NO_OMAP_TIMER) -+/* -+ * We need to explicitly enable the GPTIMER11 clocks, or we'll get an -+ * abort when we try to access the timer registers. -+ */ -+#define PVR_OMAP4_TIMING_PRCM -+#endif -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) -+//#include <plat/gpu.h> -+#if !defined(PVR_NO_OMAP_TIMER) -+//#define PVR_OMAP_USE_DM_TIMER_API -+//#include <plat/dmtimer.h> -+#endif -+#endif -+ -+#if !defined(PVR_NO_OMAP_TIMER) -+//#define PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA -+#endif -+#endif /* defined(__linux__) */ -+ -+#if !defined(NO_HARDWARE) && \ -+ defined(SYS_USING_INTERRUPTS) && \ -+ defined(SGX540) -+#define SGX_OCP_REGS_ENABLED -+#endif -+ -+#if defined(__linux__) -+#if defined(SGX_OCP_REGS_ENABLED) -+/* FIXME: Temporary workaround for OMAP4470 and active power off in 4430 */ -+#if !defined(SGX544) && defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+//#define SGX_OCP_NO_INT_BYPASS -+#endif -+#endif -+#endif -+ -+#if defined (__cplusplus) -+extern "C" { -+#endif -+ -+/***************************************************************************** -+ * system specific data structures -+ *****************************************************************************/ -+ -+/***************************************************************************** -+ * system specific function prototypes -+ *****************************************************************************/ -+ -+IMG_VOID DisableSystemClocks(SYS_DATA *psSysData); -+PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData); -+ -+IMG_VOID DisableSGXClocks(SYS_DATA *psSysData); -+PVRSRV_ERROR EnableSGXClocks(SYS_DATA *psSysData); -+ -+/* -+ * Various flags to indicate what has been initialised, and what -+ * has been temporarily deinitialised for power management purposes. -+ */ -+#define SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS 0x00000001 -+#define SYS_SPECIFIC_DATA_ENABLE_LISR 0x00000002 -+#define SYS_SPECIFIC_DATA_ENABLE_MISR 0x00000004 -+#define SYS_SPECIFIC_DATA_ENABLE_ENVDATA 0x00000008 -+#define SYS_SPECIFIC_DATA_ENABLE_LOCDEV 0x00000010 -+#define SYS_SPECIFIC_DATA_ENABLE_REGDEV 0x00000020 -+#define SYS_SPECIFIC_DATA_ENABLE_PDUMPINIT 0x00000040 -+#define SYS_SPECIFIC_DATA_ENABLE_INITDEV 0x00000080 -+#define SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV 0x00000100 -+ -+#define SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR 0x00000200 -+#define SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS 0x00000400 -+#define SYS_SPECIFIC_DATA_ENABLE_OCPREGS 0x00000800 -+#define SYS_SPECIFIC_DATA_ENABLE_PM_RUNTIME 0x00001000 -+#define SYS_SPECIFIC_DATA_IRQ_ENABLED 0x00002000 -+#define SYS_SPECIFIC_DATA_DVFS_INIT 0x00004000 -+ -+#define SYS_SPECIFIC_DATA_SET(psSysSpecData, flag) ((IMG_VOID)((psSysSpecData)->ui32SysSpecificData |= (flag))) -+ -+#define SYS_SPECIFIC_DATA_CLEAR(psSysSpecData, flag) ((IMG_VOID)((psSysSpecData)->ui32SysSpecificData &= ~(flag))) -+ -+#define SYS_SPECIFIC_DATA_TEST(psSysSpecData, flag) (((psSysSpecData)->ui32SysSpecificData & (flag)) != 0) -+ -+typedef struct _SYS_SPECIFIC_DATA_TAG_ -+{ -+ IMG_UINT32 ui32SysSpecificData; -+ PVRSRV_DEVICE_NODE *psSGXDevNode; -+ IMG_BOOL bSGXInitComplete; -+#if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA) -+ IMG_CPU_PHYADDR sTimerRegPhysBase; -+#endif -+#if !defined(__linux__) -+ IMG_BOOL bSGXClocksEnabled; -+#endif -+ IMG_UINT32 ui32SrcClockDiv; -+#if defined(__linux__) -+ IMG_BOOL bSysClocksOneTimeInit; -+ atomic_t sSGXClocksEnabled; -+#if defined(PVR_LINUX_USING_WORKQUEUES) -+ struct mutex sPowerLock; -+#else -+ IMG_BOOL bConstraintNotificationsEnabled; -+ spinlock_t sPowerLock; -+ atomic_t sPowerLockCPU; -+ spinlock_t sNotifyLock; -+ atomic_t sNotifyLockCPU; -+ IMG_BOOL bCallVDD2PostFunc; -+#endif -+ struct clk *psCORE_CK; -+ struct clk *psSGX_FCK; -+ struct clk *psSGX_ICK; -+ -+#if defined(DEBUG) || defined(TIMING) -+ struct clk *psGPT11_FCK; -+ struct clk *psGPT11_ICK; -+#endif -+#if defined(PVR_OMAP_USE_DM_TIMER_API) -+ struct omap_dm_timer *psGPTimer; -+#endif -+ IMG_UINT32 ui32SGXFreqListSize; -+ IMG_UINT32 *pui32SGXFreqList; -+ IMG_UINT32 ui32SGXFreqListIndex; -+#endif /* defined(__linux__) */ -+} SYS_SPECIFIC_DATA; -+ -+extern SYS_SPECIFIC_DATA *gpsSysSpecificData; -+ -+#if defined(SGX_OCP_REGS_ENABLED) && defined(SGX_OCP_NO_INT_BYPASS) -+IMG_VOID SysEnableSGXInterrupts(SYS_DATA* psSysData); -+IMG_VOID SysDisableSGXInterrupts(SYS_DATA* psSysData); -+#else -+#define SysEnableSGXInterrupts(psSysData) -+#define SysDisableSGXInterrupts(psSysData) -+#endif -+ -+#if defined(SYS_CUSTOM_POWERLOCK_WRAP) -+IMG_BOOL WrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData); -+IMG_VOID UnwrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData); -+#endif -+ -+#if defined(__linux__) -+ -+PVRSRV_ERROR SysPMRuntimeRegister(void); -+PVRSRV_ERROR SysPMRuntimeUnregister(void); -+ -+PVRSRV_ERROR SysDvfsInitialize(SYS_SPECIFIC_DATA *psSysSpecificData); -+PVRSRV_ERROR SysDvfsDeinitialize(SYS_SPECIFIC_DATA *psSysSpecificData); -+ -+#else /* defined(__linux__) */ -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(SysPMRuntimeRegister) -+#endif -+static INLINE PVRSRV_ERROR SysPMRuntimeRegister(void) -+{ -+ return PVRSRV_OK; -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(SysPMRuntimeUnregister) -+#endif -+static INLINE PVRSRV_ERROR SysPMRuntimeUnregister(void) -+{ -+ return PVRSRV_OK; -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(SysDvfsInitialize) -+#endif -+static INLINE PVRSRV_ERROR SysDvfsInitialize(void) -+{ -+ return PVRSRV_OK; -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(SysDvfsDeinitialize) -+#endif -+static INLINE PVRSRV_ERROR SysDvfsDeinitialize(void) -+{ -+ return PVRSRV_OK; -+} -+ -+#endif /* defined(__linux__) */ -+ -+#if defined(__cplusplus) -+} -+#endif -+ -+#endif /* __SYSLOCAL_H__ */ -diff --git a/drivers/staging/ti-es8-sgx/services4/system/omap3630/sysutils.c b/drivers/staging/ti-es8-sgx/services4/system/omap3630/sysutils.c -new file mode 100644 -index 0000000..6725421 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/omap3630/sysutils.c -@@ -0,0 +1,47 @@ -+/*************************************************************************/ /*! -+@Title Shared (User/kernel) and System dependent utilities -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Provides system-specific functions -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+/* Pull in the correct system dependent sysutils source */ -+ -+#if defined(__linux__) -+#include "sysutils_linux.c" -+#endif -diff --git a/drivers/staging/ti-es8-sgx/services4/system/omap3630/sysutils_linux.c b/drivers/staging/ti-es8-sgx/services4/system/omap3630/sysutils_linux.c -new file mode 100644 -index 0000000..2f5b007 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/omap3630/sysutils_linux.c -@@ -0,0 +1,958 @@ -+/*************************************************************************/ /*! -+@Title System dependent utilities -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Provides system-specific functions -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+#include <linux/version.h> -+#include <linux/clk.h> -+#include <linux/err.h> -+#include <linux/hardirq.h> -+#include <linux/mutex.h> -+#include <linux/slab.h> -+ -+#include "sgxdefs.h" -+#include "services_headers.h" -+#include "sysinfo.h" -+#include "sgxapi_km.h" -+#include "sysconfig.h" -+#include "sgxinfokm.h" -+#include "syslocal.h" -+ -+#include <linux/platform_device.h> -+#include <linux/pm_runtime.h> -+ -+#if defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) -+#include <linux/opp.h> -+#endif -+ -+#if defined(SUPPORT_DRI_DRM_PLUGIN) -+#include <drm/drmP.h> -+#include <drm/drm.h> -+ -+#include <linux/omap_gpu.h> -+ -+#include "pvr_drm.h" -+#endif -+ -+#define ONE_MHZ 1000000 -+#define HZ_TO_MHZ(m) ((m) / ONE_MHZ) -+ -+#if defined(SUPPORT_OMAP3430_SGXFCLK_96M) -+#define SGX_PARENT_CLOCK "cm_96m_fck" -+#else -+#define SGX_PARENT_CLOCK "core_ck" -+#endif -+ -+#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) -+extern struct platform_device *gpsPVRLDMDev; -+#endif -+ -+static PVRSRV_ERROR PowerLockWrap(SYS_SPECIFIC_DATA *psSysSpecData, IMG_BOOL bTryLock) -+{ -+ if (!in_interrupt()) -+ { -+ if (bTryLock) -+ { -+ int locked = mutex_trylock(&psSysSpecData->sPowerLock); -+ if (locked == 0) -+ { -+ return PVRSRV_ERROR_RETRY; -+ } -+ } -+ else -+ { -+ mutex_lock(&psSysSpecData->sPowerLock); -+ } -+ } -+ -+ return PVRSRV_OK; -+} -+ -+static IMG_VOID PowerLockUnwrap(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ if (!in_interrupt()) -+ { -+ mutex_unlock(&psSysSpecData->sPowerLock); -+ } -+} -+ -+PVRSRV_ERROR SysPowerLockWrap(IMG_BOOL bTryLock) -+{ -+ SYS_DATA *psSysData; -+ -+ SysAcquireData(&psSysData); -+ -+ return PowerLockWrap(psSysData->pvSysSpecificData, bTryLock); -+} -+ -+IMG_VOID SysPowerLockUnwrap(IMG_VOID) -+{ -+ SYS_DATA *psSysData; -+ -+ SysAcquireData(&psSysData); -+ -+ PowerLockUnwrap(psSysData->pvSysSpecificData); -+} -+ -+/* -+ * This function should be called to unwrap the Services power lock, prior -+ * to calling any function that might sleep. -+ * This function shouldn't be called prior to calling EnableSystemClocks -+ * or DisableSystemClocks, as those functions perform their own power lock -+ * unwrapping. -+ * If the function returns IMG_TRUE, UnwrapSystemPowerChange must be -+ * called to rewrap the power lock, prior to returning to Services. -+ */ -+IMG_BOOL WrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ return IMG_TRUE; -+} -+ -+IMG_VOID UnwrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+} -+ -+/* -+ * Return SGX timining information to caller. -+ */ -+IMG_VOID SysGetSGXTimingInformation(SGX_TIMING_INFORMATION *psTimingInfo) -+{ -+#if !defined(NO_HARDWARE) -+ PVR_ASSERT(atomic_read(&gpsSysSpecificData->sSGXClocksEnabled) != 0); -+#endif -+#if defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) -+ psTimingInfo->ui32CoreClockSpeed = -+ gpsSysSpecificData->pui32SGXFreqList[gpsSysSpecificData->ui32SGXFreqListIndex]; -+#else /* defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) */ -+ psTimingInfo->ui32CoreClockSpeed = SYS_SGX_CLOCK_SPEED; -+#endif -+ psTimingInfo->ui32HWRecoveryFreq = SYS_SGX_HWRECOVERY_TIMEOUT_FREQ; -+ psTimingInfo->ui32uKernelFreq = SYS_SGX_PDS_TIMER_FREQ; -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ psTimingInfo->bEnableActivePM = IMG_TRUE; -+#else -+ psTimingInfo->bEnableActivePM = IMG_FALSE; -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ psTimingInfo->ui32ActivePowManLatencyms = SYS_SGX_ACTIVE_POWER_LATENCY_MS; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function EnableSGXClocks -+ -+ @Description Enable SGX clocks -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR EnableSGXClocks(SYS_DATA *psSysData) -+{ -+#if !defined(NO_HARDWARE) -+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; -+#if !defined(PM_RUNTIME_SUPPORT) -+ IMG_INT res; -+ long lRate,lNewRate; -+#endif -+ /* SGX clocks already enabled? */ -+ if (atomic_read(&psSysSpecData->sSGXClocksEnabled) != 0) -+ { -+ return PVRSRV_OK; -+ } -+ -+#if !defined(PM_RUNTIME_SUPPORT) -+ PVR_DPF((PVR_DBG_MESSAGE, "EnableSGXClocks: Enabling SGX Clocks")); -+ res=clk_enable(psSysSpecData->psSGX_FCK); -+ if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Couldn't enable SGX functional clock (%d)", res)); -+ return PVRSRV_ERROR_UNABLE_TO_ENABLE_CLOCK; -+ } -+ -+ lNewRate = clk_round_rate(psSysSpecData->psSGX_FCK, SYS_SGX_CLOCK_SPEED + ONE_MHZ); -+ if (lNewRate <= 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Couldn't round SGX functional clock rate")); -+ return PVRSRV_ERROR_UNABLE_TO_ROUND_CLOCK_RATE; -+ } -+ -+ -+ lRate = clk_get_rate(psSysSpecData->psSGX_FCK); -+ if (lRate != lNewRate) -+ { -+ res = clk_set_rate(psSysSpecData->psSGX_FCK, lNewRate); -+ if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_WARNING, "EnableSGXClocks: Couldn't set SGX functional clock rate (%d)", res)); -+ return PVRSRV_ERROR_UNABLE_TO_SET_CLOCK_RATE; -+ } -+ } -+ -+#if defined(DEBUG) -+ { -+ IMG_UINT32 rate = clk_get_rate(psSysSpecData->psSGX_FCK); -+ PVR_DPF((PVR_DBG_MESSAGE, "EnableSGXClocks: SGX Functional Clock is %dMhz", HZ_TO_MHZ(rate))); -+ } -+#endif -+#endif -+#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) -+#if defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) -+ { -+ struct gpu_platform_data *pdata; -+ IMG_UINT32 max_freq_index; -+ int res; -+ -+ pdata = (struct gpu_platform_data *)gpsPVRLDMDev->dev.platform_data; -+ max_freq_index = psSysSpecData->ui32SGXFreqListSize - 2; -+ -+ /* -+ * Request maximum frequency from DVFS layer if not already set. DVFS may -+ * report busy if early in initialization, but all other errors are -+ * considered serious. Upon any error we proceed assuming our safe frequency -+ * value to be in use as indicated by the "unknown" index. -+ */ -+ if (psSysSpecData->ui32SGXFreqListIndex != max_freq_index) -+ { -+ PVR_ASSERT(pdata->device_scale != IMG_NULL); -+ res = pdata->device_scale(&gpsPVRLDMDev->dev, -+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3,4,0)) -+ &gpsPVRLDMDev->dev, -+#endif -+ psSysSpecData->pui32SGXFreqList[max_freq_index]); -+ if (res == 0) -+ { -+ psSysSpecData->ui32SGXFreqListIndex = max_freq_index; -+ } -+ else if (res == -EBUSY) -+ { -+ PVR_DPF((PVR_DBG_WARNING, "EnableSGXClocks: Unable to scale SGX frequency (EBUSY)")); -+ psSysSpecData->ui32SGXFreqListIndex = psSysSpecData->ui32SGXFreqListSize - 1; -+ } -+ else if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Unable to scale SGX frequency (%d)", res)); -+ psSysSpecData->ui32SGXFreqListIndex = psSysSpecData->ui32SGXFreqListSize - 1; -+ } -+ } -+ } -+#endif /* defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) */ -+ { -+ /* -+ * pm_runtime_get_sync returns 1 after the module has -+ * been reloaded. -+ */ -+#if defined(PM_RUNTIME_SUPPORT) -+ -+ int res = pm_runtime_get_sync(&gpsPVRLDMDev->dev); -+ if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: pm_runtime_get_sync failed (%d)", -res)); -+ return PVRSRV_ERROR_UNABLE_TO_ENABLE_CLOCK; -+ } -+#endif -+ } -+#endif /* defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) */ -+ -+ SysEnableSGXInterrupts(psSysData); -+ -+ /* Indicate that the SGX clocks are enabled */ -+ atomic_set(&psSysSpecData->sSGXClocksEnabled, 1); -+ -+#else /* !defined(NO_HARDWARE) */ -+ PVR_UNREFERENCED_PARAMETER(psSysData); -+#endif /* !defined(NO_HARDWARE) */ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function DisableSGXClocks -+ -+ @Description Disable SGX clocks. -+ -+ @Return none -+ -+******************************************************************************/ -+IMG_VOID DisableSGXClocks(SYS_DATA *psSysData) -+{ -+#if !defined(NO_HARDWARE) -+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; -+ -+ /* SGX clocks already disabled? */ -+ if (atomic_read(&psSysSpecData->sSGXClocksEnabled) == 0) -+ { -+ return; -+ } -+ -+ PVR_DPF((PVR_DBG_MESSAGE, "DisableSGXClocks: Disabling SGX Clocks")); -+#if !defined(PM_RUNTIME_SUPPORT) -+ clk_disable(psSysSpecData->psSGX_FCK); -+#endif -+ SysDisableSGXInterrupts(psSysData); -+ -+#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) -+ { -+#if defined(PM_RUNTIME_SUPPORT) -+ -+ int res = pm_runtime_put_sync(&gpsPVRLDMDev->dev); -+ if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "DisableSGXClocks: pm_runtime_put_sync failed (%d)", -res)); -+ } -+#endif -+ } -+#if defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) -+ { -+ struct gpu_platform_data *pdata; -+ int res; -+ -+ pdata = (struct gpu_platform_data *)gpsPVRLDMDev->dev.platform_data; -+ -+ /* -+ * Request minimum frequency (list index 0) from DVFS layer if not already -+ * set. DVFS may report busy if early in initialization, but all other errors -+ * are considered serious. Upon any error we proceed assuming our safe frequency -+ * value to be in use as indicated by the "unknown" index. -+ */ -+ if (psSysSpecData->ui32SGXFreqListIndex != 0) -+ { -+ PVR_ASSERT(pdata->device_scale != IMG_NULL); -+ res = pdata->device_scale(&gpsPVRLDMDev->dev, -+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3,4,0)) -+ &gpsPVRLDMDev->dev, -+#endif -+ psSysSpecData->pui32SGXFreqList[0]); -+ if (res == 0) -+ { -+ psSysSpecData->ui32SGXFreqListIndex = 0; -+ } -+ else if (res == -EBUSY) -+ { -+ PVR_DPF((PVR_DBG_WARNING, "DisableSGXClocks: Unable to scale SGX frequency (EBUSY)")); -+ psSysSpecData->ui32SGXFreqListIndex = psSysSpecData->ui32SGXFreqListSize - 1; -+ } -+ else if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "DisableSGXClocks: Unable to scale SGX frequency (%d)", res)); -+ psSysSpecData->ui32SGXFreqListIndex = psSysSpecData->ui32SGXFreqListSize - 1; -+ } -+ } -+ } -+#endif /* defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) */ -+#endif /* defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) */ -+ -+ /* Indicate that the SGX clocks are disabled */ -+ atomic_set(&psSysSpecData->sSGXClocksEnabled, 0); -+ -+#else /* !defined(NO_HARDWARE) */ -+ PVR_UNREFERENCED_PARAMETER(psSysData); -+#endif /* !defined(NO_HARDWARE) */ -+} -+ -+#if (defined(DEBUG) || defined(TIMING)) && !defined(PVR_NO_OMAP_TIMER) -+#if defined(PVR_OMAP_USE_DM_TIMER_API) -+#define GPTIMER_TO_USE 11 -+/*! -+****************************************************************************** -+ -+ @Function AcquireGPTimer -+ -+ @Description Acquire a GP timer -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+static PVRSRV_ERROR AcquireGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ PVR_ASSERT(psSysSpecData->psGPTimer == NULL); -+ -+ /* -+ * This code has problems on module reload for OMAP5 running Linux -+ * 3.4.10, due to omap2_dm_timer_set_src (called by -+ * omap_dm_timer_request_specific), being unable to set the parent -+ * clock to OMAP_TIMER_SRC_32_KHZ. -+ * Not calling omap_dm_timer_set_source doesn't help. -+ */ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) || !defined(MODULE) -+ /* -+ * This code could try requesting registers 9, 10, and 11, -+ * stopping at the first succesful request. We'll stick with -+ * 11 for now, as it avoids having to hard code yet more -+ * physical addresses into the code. -+ */ -+ psSysSpecData->psGPTimer = omap_dm_timer_request_specific(GPTIMER_TO_USE); -+ if (psSysSpecData->psGPTimer == NULL) -+ { -+ -+ PVR_DPF((PVR_DBG_WARNING, "%s: omap_dm_timer_request_specific failed", __FUNCTION__)); -+ return PVRSRV_ERROR_CLOCK_REQUEST_FAILED; -+ } -+ -+ omap_dm_timer_set_source(psSysSpecData->psGPTimer, OMAP_TIMER_SRC_SYS_CLK); -+ omap_dm_timer_enable(psSysSpecData->psGPTimer); -+ -+ /* Set autoreload, and start value of 0 */ -+ omap_dm_timer_set_load_start(psSysSpecData->psGPTimer, 1, 0); -+ -+ omap_dm_timer_start(psSysSpecData->psGPTimer); -+ -+ /* -+ * The DM timer API doesn't have a mechanism for obtaining the -+ * physical address of the counter register. -+ */ -+ psSysSpecData->sTimerRegPhysBase.uiAddr = SYS_OMAP3630_GP11TIMER_REGS_SYS_PHYS_BASE; -+#else /* (LINUX_VERSION_CODE <= KERNEL_VERSION(3,4,0)) || !defined(MODULE) */ -+ (void)psSysSpecData; -+#endif /* (LINUX_VERSION_CODE <= KERNEL_VERSION(3,4,0)) || !defined(MODULE) */ -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function ReleaseGPTimer -+ -+ @Description Release a GP timer -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+static void ReleaseGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ if (psSysSpecData->psGPTimer != NULL) -+ { -+ /* Always returns 0 */ -+ (void) omap_dm_timer_stop(psSysSpecData->psGPTimer); -+ -+ omap_dm_timer_disable(psSysSpecData->psGPTimer); -+ -+ omap_dm_timer_free(psSysSpecData->psGPTimer); -+ -+ psSysSpecData->sTimerRegPhysBase.uiAddr = 0; -+ -+ psSysSpecData->psGPTimer = NULL; -+ } -+ -+} -+#else /* PVR_OMAP_USE_DM_TIMER_API */ -+/*! -+****************************************************************************** -+ -+ @Function AcquireGPTimer -+ -+ @Description Acquire a GP timer -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+static PVRSRV_ERROR AcquireGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+#if defined(PVR_OMAP4_TIMING_PRCM) -+ struct clk *psCLK; -+ IMG_INT res; -+ struct clk *sys_ck; -+ IMG_INT rate; -+#endif -+ PVRSRV_ERROR eError; -+ -+ IMG_CPU_PHYADDR sTimerRegPhysBase; -+ IMG_HANDLE hTimerEnable; -+ IMG_UINT32 *pui32TimerEnable; -+#if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA) -+ PVR_ASSERT(psSysSpecData->sTimerRegPhysBase.uiAddr == 0); -+#endif -+ -+#if defined(PVR_OMAP4_TIMING_PRCM) -+ /* assert our dependence on the GPTIMER11 module */ -+ psCLK = clk_get(NULL, "gpt11_fck"); -+ if (IS_ERR(psCLK)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get GPTIMER11 functional clock")); -+ goto ExitError; -+ } -+ psSysSpecData->psGPT11_FCK = psCLK; -+ -+ psCLK = clk_get(NULL, "gpt11_ick"); -+ if (IS_ERR(psCLK)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get GPTIMER11 interface clock")); -+ goto ExitError; -+ } -+ psSysSpecData->psGPT11_ICK = psCLK; -+ -+ sys_ck = clk_get(NULL, "sys_ck"); -+ if (IS_ERR(sys_ck)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get System clock")); -+ goto ExitError; -+ } -+ -+ if(clk_get_parent(psSysSpecData->psGPT11_FCK) != sys_ck) -+ { -+ PVR_TRACE(("Setting GPTIMER11 parent to System Clock")); -+ res = clk_set_parent(psSysSpecData->psGPT11_FCK, sys_ck); -+ if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't set GPTIMER11 parent clock (%d)", res)); -+ goto ExitError; -+ } -+ } -+ -+ rate = clk_get_rate(psSysSpecData->psGPT11_FCK); -+ PVR_TRACE(("GPTIMER11 clock is %dMHz", HZ_TO_MHZ(rate))); -+ -+ res = clk_enable(psSysSpecData->psGPT11_FCK); -+ if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't enable GPTIMER11 functional clock (%d)", res)); -+ goto ExitError; -+ } -+ -+ res = clk_enable(psSysSpecData->psGPT11_ICK); -+ if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't enable GPTIMER11 interface clock (%d)", res)); -+ goto ExitDisableGPT11FCK; -+ } -+#endif /* defined(PVR_OMAP4_TIMING_PRCM) */ -+ -+ /* Set the timer to non-posted mode */ -+ sTimerRegPhysBase.uiAddr = SYS_OMAP3630_GP11TIMER_TSICR_SYS_PHYS_BASE; -+ pui32TimerEnable = OSMapPhysToLin(sTimerRegPhysBase, -+ 4, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ &hTimerEnable); -+ -+ if (pui32TimerEnable == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: OSMapPhysToLin failed")); -+ goto ExitDisableGPT11ICK; -+ } -+ -+ if(!(*pui32TimerEnable & 4)) -+ { -+ PVR_TRACE(("Setting GPTIMER11 mode to posted (currently is non-posted)")); -+ -+ /* Set posted mode */ -+ *pui32TimerEnable |= 4; -+ } -+ -+ OSUnMapPhysToLin(pui32TimerEnable, -+ 4, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ hTimerEnable); -+ -+ /* Enable the timer */ -+ sTimerRegPhysBase.uiAddr = SYS_OMAP3630_GP11TIMER_ENABLE_SYS_PHYS_BASE; -+ pui32TimerEnable = OSMapPhysToLin(sTimerRegPhysBase, -+ 4, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ &hTimerEnable); -+ -+ if (pui32TimerEnable == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: OSMapPhysToLin failed")); -+ goto ExitDisableGPT11ICK; -+ } -+ -+ /* Enable and set autoreload on overflow */ -+ *pui32TimerEnable = 3; -+ -+ OSUnMapPhysToLin(pui32TimerEnable, -+ 4, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ hTimerEnable); -+#if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA) -+ psSysSpecData->sTimerRegPhysBase = sTimerRegPhysBase; -+#endif -+ eError = PVRSRV_OK; -+ -+ goto Exit; -+ -+ExitDisableGPT11ICK: -+#if defined(PVR_OMAP4_TIMING_PRCM) -+ clk_disable(psSysSpecData->psGPT11_ICK); -+ExitDisableGPT11FCK: -+ clk_disable(psSysSpecData->psGPT11_FCK); -+ExitError: -+#endif /* defined(PVR_OMAP4_TIMING_PRCM) */ -+ eError = PVRSRV_ERROR_CLOCK_REQUEST_FAILED; -+Exit: -+ return eError; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function ReleaseGPTimer -+ -+ @Description Release a GP timer -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+static void ReleaseGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ IMG_HANDLE hTimerDisable; -+ IMG_UINT32 *pui32TimerDisable; -+ IMG_CPU_PHYADDR TimerRegPhysBase; -+#if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA) -+ if (psSysSpecData->sTimerRegPhysBase.uiAddr == 0) -+ { -+ return; -+ } -+#endif -+ /* Disable the timer */ -+ pui32TimerDisable = OSMapPhysToLin(TimerRegPhysBase, -+ 4, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ &hTimerDisable); -+ -+ if (pui32TimerDisable == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "DisableSystemClocks: OSMapPhysToLin failed")); -+ } -+ else -+ { -+ *pui32TimerDisable = 0; -+ -+ OSUnMapPhysToLin(pui32TimerDisable, -+ 4, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ hTimerDisable); -+ } -+#if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA) -+ psSysSpecData->sTimerRegPhysBase.uiAddr = 0; -+#endif -+#if defined(PVR_OMAP4_TIMING_PRCM) -+ clk_disable(psSysSpecData->psGPT11_ICK); -+ -+ clk_disable(psSysSpecData->psGPT11_FCK); -+#endif /* defined(PVR_OMAP4_TIMING_PRCM) */ -+} -+#endif /* PVR_OMAP_USE_DM_TIMER_API */ -+#else /* (DEBUG || TIMING) && !PVR_NO_OMAP_TIMER */ -+static PVRSRV_ERROR AcquireGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ PVR_UNREFERENCED_PARAMETER(psSysSpecData); -+ -+ return PVRSRV_OK; -+} -+static void ReleaseGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ PVR_UNREFERENCED_PARAMETER(psSysSpecData); -+} -+#endif /* (DEBUG || TIMING) && !PVR_NO_OMAP_TIMER */ -+ -+/*! -+****************************************************************************** -+ -+ @Function EnableSystemClocks -+ -+ @Description Setup up the clocks for the graphics device to work. -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData) -+{ -+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; -+#if !defined(PM_RUNTIME_SUPPORT) -+ struct clk *psCLK; -+ IMG_INT res; -+#endif -+ -+ PVR_TRACE(("EnableSystemClocks: Enabling System Clocks")); -+ -+ if (!psSysSpecData->bSysClocksOneTimeInit) -+ { -+ mutex_init(&psSysSpecData->sPowerLock); -+ -+ atomic_set(&psSysSpecData->sSGXClocksEnabled, 0); -+ -+ psCLK = clk_get(NULL, SGX_PARENT_CLOCK); -+ if (IS_ERR(psCLK)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSsystemClocks: Couldn't get Core Clock")); -+ return PVRSRV_ERROR_UNABLE_TO_GET_PARENT_CLOCK; -+ } -+ psSysSpecData->psCORE_CK = psCLK; -+ -+ -+// psSysSpecData->bSysClocksOneTimeInit = IMG_TRUE; -+#if !defined(PM_RUNTIME_SUPPORT) -+ psCLK = clk_get(NULL, "sgx_fck"); -+ if (IS_ERR(psCLK)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSsystemClocks: Couldn't get SGX Functional Clock")); -+ return PVRSRV_ERROR_UNABLE_TO_GET_CLOCK; -+ } -+ psSysSpecData->psSGX_FCK = psCLK; -+ -+ psCLK = clk_get(NULL, "sgx_ick"); -+ if (IS_ERR(psCLK)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get SGX Interface Clock")); -+ return PVRSRV_ERROR_UNABLE_TO_GET_CLOCK; -+ } -+ psSysSpecData->psSGX_ICK = psCLK; -+ -+ res = clk_set_parent(psSysSpecData->psSGX_FCK, psSysSpecData->psCORE_CK); -+ if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't set SGX parent clock (%d)", res)); -+ return PVRSRV_ERROR_UNABLE_TO_GET_PARENT_CLOCK; -+ } -+ -+ -+ psSysSpecData->bSysClocksOneTimeInit = IMG_TRUE; -+ -+ -+#endif -+ -+ } -+ -+ return AcquireGPTimer(psSysSpecData); -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function DisableSystemClocks -+ -+ @Description Disable the graphics clocks. -+ -+ @Return none -+ -+******************************************************************************/ -+IMG_VOID DisableSystemClocks(SYS_DATA *psSysData) -+{ -+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; -+ -+ PVR_TRACE(("DisableSystemClocks: Disabling System Clocks")); -+ -+ /* -+ * Always disable the SGX clocks when the system clocks are disabled. -+ * This saves having to make an explicit call to DisableSGXClocks if -+ * active power management is enabled. -+ */ -+ DisableSGXClocks(psSysData); -+ -+ ReleaseGPTimer(psSysSpecData); -+} -+ -+PVRSRV_ERROR SysPMRuntimeRegister(void) -+{ -+#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) -+#if defined(PM_RUNTIME_SUPPORT) -+ pm_runtime_enable(&gpsPVRLDMDev->dev); -+#endif -+#endif -+ return PVRSRV_OK; -+} -+ -+PVRSRV_ERROR SysPMRuntimeUnregister(void) -+{ -+#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) -+#if defined(PM_RUNTIME_SUPPORT) -+ pm_runtime_disable(&gpsPVRLDMDev->dev); -+#endif -+#endif -+ return PVRSRV_OK; -+} -+ -+PVRSRV_ERROR SysDvfsInitialize(SYS_SPECIFIC_DATA *psSysSpecificData) -+{ -+#if !defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) -+ PVR_UNREFERENCED_PARAMETER(psSysSpecificData); -+#else /* !defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) */ -+ IMG_UINT32 i, *freq_list; -+ IMG_INT32 opp_count; -+ unsigned long freq; -+ struct opp *opp; -+ -+ /* -+ * We query and store the list of SGX frequencies just this once under the -+ * assumption that they are unchanging, e.g. no disabling of high frequency -+ * option for thermal management. This is currently valid for 4430 and 4460. -+ */ -+ rcu_read_lock(); -+ opp_count = opp_get_opp_count(&gpsPVRLDMDev->dev); -+ if (opp_count < 1) -+ { -+ rcu_read_unlock(); -+ PVR_DPF((PVR_DBG_ERROR, "SysDvfsInitialize: Could not retrieve opp count")); -+ return PVRSRV_ERROR_NOT_SUPPORTED; -+ } -+ -+ /* -+ * Allocate the frequency list with a slot for each available frequency plus -+ * one additional slot to hold a designated frequency value to assume when in -+ * an unknown frequency state. -+ */ -+ freq_list = kmalloc((opp_count + 1) * sizeof(IMG_UINT32), GFP_ATOMIC); -+ if (!freq_list) -+ { -+ rcu_read_unlock(); -+ PVR_DPF((PVR_DBG_ERROR, "SysDvfsInitialize: Could not allocate frequency list")); -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ -+ /* -+ * Fill in frequency list from lowest to highest then finally the "unknown" -+ * frequency value. We use the highest available frequency as our assumed value -+ * when in an unknown state, because it is safer for APM and hardware recovery -+ * timers to be longer than intended rather than shorter. -+ */ -+ freq = 0; -+ for (i = 0; i < opp_count; i++) -+ { -+ opp = opp_find_freq_ceil(&gpsPVRLDMDev->dev, &freq); -+ if (IS_ERR_OR_NULL(opp)) -+ { -+ rcu_read_unlock(); -+ PVR_DPF((PVR_DBG_ERROR, "SysDvfsInitialize: Could not retrieve opp level %d", i)); -+ kfree(freq_list); -+ return PVRSRV_ERROR_NOT_SUPPORTED; -+ } -+ freq_list[i] = (IMG_UINT32)freq; -+ freq++; -+ } -+ rcu_read_unlock(); -+ freq_list[opp_count] = freq_list[opp_count - 1]; -+ -+ psSysSpecificData->ui32SGXFreqListSize = opp_count + 1; -+ psSysSpecificData->pui32SGXFreqList = freq_list; -+ -+ /* Start in unknown state - no frequency request to DVFS yet made */ -+ psSysSpecificData->ui32SGXFreqListIndex = opp_count; -+#endif /* !defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) */ -+ -+ return PVRSRV_OK; -+} -+ -+PVRSRV_ERROR SysDvfsDeinitialize(SYS_SPECIFIC_DATA *psSysSpecificData) -+{ -+#if !defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) -+ PVR_UNREFERENCED_PARAMETER(psSysSpecificData); -+#else /* !defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) */ -+ /* -+ * We assume this function is only called if SysDvfsInitialize() was -+ * completed successfully before. -+ * -+ * The DVFS interface does not allow us to actually unregister as a -+ * user of SGX, so we do the next best thing which is to lower our -+ * required frequency to the minimum if not already set. DVFS may -+ * report busy if early in initialization, but all other errors are -+ * considered serious. -+ */ -+ if (psSysSpecificData->ui32SGXFreqListIndex != 0) -+ { -+ struct gpu_platform_data *pdata; -+ IMG_INT32 res; -+ -+ pdata = (struct gpu_platform_data *)gpsPVRLDMDev->dev.platform_data; -+ -+ PVR_ASSERT(pdata->device_scale != IMG_NULL); -+ res = pdata->device_scale(&gpsPVRLDMDev->dev, -+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3,4,0)) -+ &gpsPVRLDMDev->dev, -+#endif -+ psSysSpecificData->pui32SGXFreqList[0]); -+ if (res == -EBUSY) -+ { -+ PVR_DPF((PVR_DBG_WARNING, "SysDvfsDeinitialize: Unable to scale SGX frequency (EBUSY)")); -+ } -+ else if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SysDvfsDeinitialize: Unable to scale SGX frequency (%d)", res)); -+ } -+ -+ psSysSpecificData->ui32SGXFreqListIndex = 0; -+ } -+ -+ kfree(psSysSpecificData->pui32SGXFreqList); -+ psSysSpecificData->pui32SGXFreqList = 0; -+ psSysSpecificData->ui32SGXFreqListSize = 0; -+#endif /* !defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) */ -+ -+ return PVRSRV_OK; -+} -+ -+#if defined(SUPPORT_DRI_DRM_PLUGIN) -+static struct omap_gpu_plugin sOMAPGPUPlugin; -+ -+#define SYS_DRM_SET_PLUGIN_FIELD(d, s, f) (d)->f = (s)->f -+int -+SysDRMRegisterPlugin(PVRSRV_DRM_PLUGIN *psDRMPlugin) -+{ -+ int iRes; -+ -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, name); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, open); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, load); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, unload); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, release); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, mmap); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, ioctls); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, num_ioctls); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, ioctl_start); -+ -+ iRes = omap_gpu_register_plugin(&sOMAPGPUPlugin); -+ if (iRes != 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: omap_gpu_register_plugin failed (%d)", __FUNCTION__, iRes)); -+ } -+ -+ return iRes; -+} -+ -+void -+SysDRMUnregisterPlugin(PVRSRV_DRM_PLUGIN *psDRMPlugin) -+{ -+ int iRes = omap_gpu_unregister_plugin(&sOMAPGPUPlugin); -+ if (iRes != 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: omap_gpu_unregister_plugin failed (%d)", __FUNCTION__, iRes)); -+ } -+} -+#endif -diff --git a/drivers/staging/ti-es8-sgx/services4/system/omap4/oemfuncs.h b/drivers/staging/ti-es8-sgx/services4/system/omap4/oemfuncs.h -new file mode 100644 -index 0000000..77c70d6 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/omap4/oemfuncs.h -@@ -0,0 +1,78 @@ -+/*************************************************************************/ /*! -+@Title SGX kernel/client driver interface structures and prototypes -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#if !defined(__OEMFUNCS_H__) -+#define __OEMFUNCS_H__ -+ -+#if defined (__cplusplus) -+extern "C" { -+#endif -+ -+/* function in/out data structures: */ -+typedef IMG_UINT32 (*PFN_SRV_BRIDGEDISPATCH)( IMG_UINT32 Ioctl, -+ IMG_BYTE *pInBuf, -+ IMG_UINT32 InBufLen, -+ IMG_BYTE *pOutBuf, -+ IMG_UINT32 OutBufLen, -+ IMG_UINT32 *pdwBytesTransferred); -+/* -+ Function table for kernel 3rd party driver to kernel services -+*/ -+typedef struct PVRSRV_DC_OEM_JTABLE_TAG -+{ -+ PFN_SRV_BRIDGEDISPATCH pfnOEMBridgeDispatch; -+ IMG_PVOID pvDummy1; -+ IMG_PVOID pvDummy2; -+ IMG_PVOID pvDummy3; -+ -+} PVRSRV_DC_OEM_JTABLE; -+ -+#define OEM_GET_EXT_FUNCS (1<<1) -+ -+#if defined(__cplusplus) -+} -+#endif -+ -+#endif /* __OEMFUNCS_H__ */ -+ -+/***************************************************************************** -+ End of file (oemfuncs.h) -+*****************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/system/omap4/sysconfig.c b/drivers/staging/ti-es8-sgx/services4/system/omap4/sysconfig.c -new file mode 100644 -index 0000000..733b839 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/omap4/sysconfig.c -@@ -0,0 +1,1298 @@ -+/*************************************************************************/ /*! -+@Title System Configuration -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description System Configuration functions -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#include "sysconfig.h" -+#include "services_headers.h" -+#include "kerneldisplay.h" -+#include "oemfuncs.h" -+#include "sgxinfo.h" -+#include "sgxinfokm.h" -+#include "syslocal.h" -+ -+#include "ocpdefs.h" -+ -+/* top level system data anchor point*/ -+SYS_DATA* gpsSysData = (SYS_DATA*)IMG_NULL; -+SYS_DATA gsSysData; -+ -+static SYS_SPECIFIC_DATA gsSysSpecificData; -+SYS_SPECIFIC_DATA *gpsSysSpecificData; -+ -+/* SGX structures */ -+static IMG_UINT32 gui32SGXDeviceID; -+static SGX_DEVICE_MAP gsSGXDeviceMap; -+static PVRSRV_DEVICE_NODE *gpsSGXDevNode; -+ -+ -+#if defined(NO_HARDWARE) || defined(SGX_OCP_REGS_ENABLED) -+static IMG_CPU_VIRTADDR gsSGXRegsCPUVAddr; -+#endif -+ -+#if defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO) -+extern struct platform_device *gpsPVRLDMDev; -+#endif -+ -+IMG_UINT32 PVRSRV_BridgeDispatchKM(IMG_UINT32 Ioctl, -+ IMG_BYTE *pInBuf, -+ IMG_UINT32 InBufLen, -+ IMG_BYTE *pOutBuf, -+ IMG_UINT32 OutBufLen, -+ IMG_UINT32 *pdwBytesTransferred); -+ -+#if defined(SGX_OCP_REGS_ENABLED) -+ -+static IMG_CPU_VIRTADDR gpvOCPRegsLinAddr; -+ -+static PVRSRV_ERROR EnableSGXClocksWrap(SYS_DATA *psSysData) -+{ -+ PVRSRV_ERROR eError = EnableSGXClocks(psSysData); -+ -+#if !defined(SGX_OCP_NO_INT_BYPASS) -+ if(eError == PVRSRV_OK) -+ { -+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_SYSCONFIG, 0x14); -+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_DEBUG_CONFIG, EUR_CR_OCP_DEBUG_CONFIG_THALIA_INT_BYPASS_MASK); -+ } -+#endif -+ return eError; -+} -+ -+#else /* defined(SGX_OCP_REGS_ENABLED) */ -+ -+static INLINE PVRSRV_ERROR EnableSGXClocksWrap(SYS_DATA *psSysData) -+{ -+ return EnableSGXClocks(psSysData); -+} -+ -+#endif /* defined(SGX_OCP_REGS_ENABLED) */ -+ -+static INLINE PVRSRV_ERROR EnableSystemClocksWrap(SYS_DATA *psSysData) -+{ -+ PVRSRV_ERROR eError = EnableSystemClocks(psSysData); -+ -+#if !defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ if(eError == PVRSRV_OK) -+ { -+ /* -+ * The SGX Clocks are enabled separately if active power -+ * management is enabled. -+ */ -+ eError = EnableSGXClocksWrap(psSysData); -+ if (eError != PVRSRV_OK) -+ { -+ DisableSystemClocks(psSysData); -+ } -+ } -+#endif -+ -+ return eError; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function SysLocateDevices -+ -+ @Description Specifies devices in the systems memory map -+ -+ @Input psSysData - sys data -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+static PVRSRV_ERROR SysLocateDevices(SYS_DATA *psSysData) -+{ -+#if defined(NO_HARDWARE) -+ PVRSRV_ERROR eError; -+ IMG_CPU_PHYADDR sCpuPAddr; -+#else -+#if defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO) -+ struct resource *dev_res; -+ int dev_irq; -+#endif -+#endif -+ -+ PVR_UNREFERENCED_PARAMETER(psSysData); -+ -+ /* SGX Device: */ -+ gsSGXDeviceMap.ui32Flags = 0x0; -+ -+#if defined(NO_HARDWARE) -+ /* -+ * For no hardware, allocate some contiguous memory for the -+ * register block. -+ */ -+ -+ /* Registers */ -+ gsSGXDeviceMap.ui32RegsSize = SYS_OMAP4430_SGX_REGS_SIZE; -+ -+ eError = OSBaseAllocContigMemory(gsSGXDeviceMap.ui32RegsSize, -+ &gsSGXRegsCPUVAddr, -+ &sCpuPAddr); -+ if(eError != PVRSRV_OK) -+ { -+ return eError; -+ } -+ gsSGXDeviceMap.sRegsCpuPBase = sCpuPAddr; -+ gsSGXDeviceMap.sRegsSysPBase = SysCpuPAddrToSysPAddr(gsSGXDeviceMap.sRegsCpuPBase); -+#if defined(__linux__) -+ /* Indicate the registers are already mapped */ -+ gsSGXDeviceMap.pvRegsCpuVBase = gsSGXRegsCPUVAddr; -+#else -+ /* -+ * FIXME: Could we just use the virtual address returned by -+ * OSBaseAllocContigMemory? -+ */ -+ gsSGXDeviceMap.pvRegsCpuVBase = IMG_NULL; -+#endif -+ -+ OSMemSet(gsSGXRegsCPUVAddr, 0, gsSGXDeviceMap.ui32RegsSize); -+ -+ /* -+ device interrupt IRQ -+ Note: no interrupts available on no hardware system -+ */ -+ gsSGXDeviceMap.ui32IRQ = 0; -+ -+#else /* defined(NO_HARDWARE) */ -+#if defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO) -+ /* get the resource and IRQ through platform resource API */ -+ dev_res = platform_get_resource(gpsPVRLDMDev, IORESOURCE_MEM, 0); -+ if (dev_res == NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: platform_get_resource failed", __FUNCTION__)); -+ return PVRSRV_ERROR_INVALID_DEVICE; -+ } -+ -+ dev_irq = platform_get_irq(gpsPVRLDMDev, 0); -+ if (dev_irq < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: platform_get_irq failed (%d)", __FUNCTION__, -dev_irq)); -+ return PVRSRV_ERROR_INVALID_DEVICE; -+ } -+ -+ gsSGXDeviceMap.sRegsSysPBase.uiAddr = dev_res->start; -+ gsSGXDeviceMap.sRegsCpuPBase = -+ SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sRegsSysPBase); -+ PVR_TRACE(("SGX register base: 0x%lx", (unsigned long)gsSGXDeviceMap.sRegsCpuPBase.uiAddr)); -+ -+ gsSGXDeviceMap.ui32RegsSize = (unsigned int)(dev_res->end - dev_res->start); -+ PVR_TRACE(("SGX register size: %d",gsSGXDeviceMap.ui32RegsSize)); -+ -+ gsSGXDeviceMap.ui32IRQ = dev_irq; -+ PVR_TRACE(("SGX IRQ: %d", gsSGXDeviceMap.ui32IRQ)); -+#else /* defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO) */ -+ gsSGXDeviceMap.sRegsSysPBase.uiAddr = SYS_OMAP4430_SGX_REGS_SYS_PHYS_BASE; -+ gsSGXDeviceMap.sRegsCpuPBase = SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sRegsSysPBase); -+ gsSGXDeviceMap.ui32RegsSize = SYS_OMAP4430_SGX_REGS_SIZE; -+ -+ gsSGXDeviceMap.ui32IRQ = SYS_OMAP4430_SGX_IRQ; -+ -+#endif /* defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO) */ -+#if defined(SGX_OCP_REGS_ENABLED) -+ gsSGXRegsCPUVAddr = OSMapPhysToLin(gsSGXDeviceMap.sRegsCpuPBase, -+ gsSGXDeviceMap.ui32RegsSize, -+ PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY, -+ IMG_NULL); -+ -+ if (gsSGXRegsCPUVAddr == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysLocateDevices: Failed to map SGX registers")); -+ return PVRSRV_ERROR_BAD_MAPPING; -+ } -+ -+ /* Indicate the registers are already mapped */ -+ gsSGXDeviceMap.pvRegsCpuVBase = gsSGXRegsCPUVAddr; -+ gpvOCPRegsLinAddr = gsSGXRegsCPUVAddr; -+#endif -+#endif /* defined(NO_HARDWARE) */ -+ -+#if defined(PDUMP) -+ { -+ /* initialise memory region name for pdumping */ -+ static IMG_CHAR pszPDumpDevName[] = "SGXMEM"; -+ gsSGXDeviceMap.pszPDumpDevName = pszPDumpDevName; -+ } -+#endif -+ -+ /* add other devices here: */ -+ -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysCreateVersionString -+ -+ @Description Read the version string -+ -+ @Return IMG_CHAR * : Version string -+ -+******************************************************************************/ -+static IMG_CHAR *SysCreateVersionString(void) -+{ -+ static IMG_CHAR aszVersionString[100]; -+ SYS_DATA *psSysData; -+ IMG_UINT32 ui32SGXRevision; -+ IMG_INT32 i32Count; -+#if !defined(NO_HARDWARE) -+ IMG_VOID *pvRegsLinAddr; -+ -+ pvRegsLinAddr = OSMapPhysToLin(gsSGXDeviceMap.sRegsCpuPBase, -+ gsSGXDeviceMap.ui32RegsSize, -+ PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY, -+ IMG_NULL); -+ if(!pvRegsLinAddr) -+ { -+ return IMG_NULL; -+ } -+ -+ ui32SGXRevision = OSReadHWReg((IMG_PVOID)((IMG_PBYTE)pvRegsLinAddr), -+ EUR_CR_CORE_REVISION); -+#else -+ ui32SGXRevision = 0; -+#endif -+ -+ SysAcquireData(&psSysData); -+ -+ i32Count = OSSNPrintf(aszVersionString, 100, -+ "SGX revision = %u.%u.%u", -+ (IMG_UINT)((ui32SGXRevision & EUR_CR_CORE_REVISION_MAJOR_MASK) -+ >> EUR_CR_CORE_REVISION_MAJOR_SHIFT), -+ (IMG_UINT)((ui32SGXRevision & EUR_CR_CORE_REVISION_MINOR_MASK) -+ >> EUR_CR_CORE_REVISION_MINOR_SHIFT), -+ (IMG_UINT)((ui32SGXRevision & EUR_CR_CORE_REVISION_MAINTENANCE_MASK) -+ >> EUR_CR_CORE_REVISION_MAINTENANCE_SHIFT) -+ ); -+ -+#if !defined(NO_HARDWARE) -+ OSUnMapPhysToLin(pvRegsLinAddr, -+ SYS_OMAP4430_SGX_REGS_SIZE, -+ PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY, -+ IMG_NULL); -+#endif -+ -+ if(i32Count == -1) -+ { -+ return IMG_NULL; -+ } -+ -+ return aszVersionString; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysInitialise -+ -+ @Description Initialises kernel services at 'driver load' time -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+PVRSRV_ERROR SysInitialise(IMG_VOID) -+{ -+ IMG_UINT32 i; -+ PVRSRV_ERROR eError; -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+#if !defined(PVR_NO_OMAP_TIMER) -+ IMG_CPU_PHYADDR TimerRegPhysBase; -+#endif -+#if !defined(SGX_DYNAMIC_TIMING_INFO) -+ SGX_TIMING_INFORMATION* psTimingInfo; -+#endif -+ gpsSysData = &gsSysData; -+ OSMemSet(gpsSysData, 0, sizeof(SYS_DATA)); -+ -+ gpsSysSpecificData = &gsSysSpecificData; -+ OSMemSet(gpsSysSpecificData, 0, sizeof(SYS_SPECIFIC_DATA)); -+ -+ gpsSysData->pvSysSpecificData = gpsSysSpecificData; -+ -+ eError = OSInitEnvData(&gpsSysData->pvEnvSpecificData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to setup env structure")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_ENVDATA); -+ -+ gpsSysData->ui32NumDevices = SYS_DEVICE_COUNT; -+ -+ /* init device ID's */ -+ for(i=0; i<SYS_DEVICE_COUNT; i++) -+ { -+ gpsSysData->sDeviceID[i].uiID = i; -+ gpsSysData->sDeviceID[i].bInUse = IMG_FALSE; -+ } -+ -+ gpsSysData->psDeviceNodeList = IMG_NULL; -+ gpsSysData->psQueueList = IMG_NULL; -+ -+ eError = SysInitialiseCommon(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed in SysInitialiseCommon")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ -+#if !defined(SGX_DYNAMIC_TIMING_INFO) -+ /* Set up timing information*/ -+ psTimingInfo = &gsSGXDeviceMap.sTimingInfo; -+ psTimingInfo->ui32CoreClockSpeed = SYS_SGX_CLOCK_SPEED; -+ psTimingInfo->ui32HWRecoveryFreq = SYS_SGX_HWRECOVERY_TIMEOUT_FREQ; -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ psTimingInfo->bEnableActivePM = IMG_TRUE; -+#else -+ psTimingInfo->bEnableActivePM = IMG_FALSE; -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ psTimingInfo->ui32ActivePowManLatencyms = SYS_SGX_ACTIVE_POWER_LATENCY_MS; -+ psTimingInfo->ui32uKernelFreq = SYS_SGX_PDS_TIMER_FREQ; -+#endif -+ -+ /* -+ Setup the Source Clock Divider value -+ */ -+ gpsSysSpecificData->ui32SrcClockDiv = 3; -+ -+ /* -+ Locate the devices within the system, specifying -+ the physical addresses of each devices components -+ (regs, mem, ports etc.) -+ */ -+ eError = SysLocateDevices(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to locate devices")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV); -+ -+ eError = SysPMRuntimeRegister(); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to register with OSPM!")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_PM_RUNTIME); -+ -+ eError = SysDvfsInitialize(gpsSysSpecificData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to initialize DVFS")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_DVFS_INIT); -+ -+ /* -+ Register devices with the system -+ This also sets up their memory maps/heaps -+ */ -+ eError = PVRSRVRegisterDevice(gpsSysData, SGXRegisterDevice, -+ DEVICE_SGX_INTERRUPT, &gui32SGXDeviceID); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to register device!")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_REGDEV); -+ -+ /* -+ Once all devices are registered, specify the backing store -+ and, if required, customise the memory heap config -+ */ -+ psDeviceNode = gpsSysData->psDeviceNodeList; -+ while(psDeviceNode) -+ { -+ /* perform any OEM SOC address space customisations here */ -+ switch(psDeviceNode->sDevId.eDeviceType) -+ { -+ case PVRSRV_DEVICE_TYPE_SGX: -+ { -+ DEVICE_MEMORY_INFO *psDevMemoryInfo; -+ DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; -+ -+ /* -+ specify the backing store to use for the devices MMU PT/PDs -+ - the PT/PDs are always UMA in this system -+ */ -+ psDeviceNode->psLocalDevMemArena = IMG_NULL; -+ -+ /* useful pointers */ -+ psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo; -+ psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap; -+ -+ /* specify the backing store for all SGX heaps */ -+ for(i=0; i<psDevMemoryInfo->ui32HeapCount; i++) -+ { -+ psDeviceMemoryHeap[i].ui32Attribs |= PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG; -+ } -+ -+ gpsSGXDevNode = psDeviceNode; -+ gsSysSpecificData.psSGXDevNode = psDeviceNode; -+ -+ break; -+ } -+ default: -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to find SGX device node!")); -+ return PVRSRV_ERROR_INIT_FAILURE; -+ } -+ -+ /* advance to next device */ -+ psDeviceNode = psDeviceNode->psNext; -+ } -+ -+ eError = EnableSystemClocksWrap(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable system clocks (%d)", eError)); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS); -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ eError = EnableSGXClocksWrap(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable SGX clocks (%d)", eError)); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ -+ eError = PVRSRVInitialiseDevice(gui32SGXDeviceID); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to initialise device!")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_INITDEV); -+ -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ /* SGX defaults to D3 power state */ -+ DisableSGXClocks(gpsSysData); -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ -+#if !defined(PVR_NO_OMAP_TIMER) -+#if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA) -+ TimerRegPhysBase = gsSysSpecificData.sTimerRegPhysBase; -+#else -+ TimerRegPhysBase.uiAddr = SYS_OMAP4430_GP11TIMER_REGS_SYS_PHYS_BASE; -+#endif -+ gpsSysData->pvSOCTimerRegisterKM = IMG_NULL; -+ gpsSysData->hSOCTimerRegisterOSMemHandle = 0; -+ if (TimerRegPhysBase.uiAddr != 0) -+ { -+ OSReservePhys(TimerRegPhysBase, -+ 4, -+ PVRSRV_HAP_MULTI_PROCESS|PVRSRV_HAP_UNCACHED, -+ IMG_NULL, -+ (IMG_VOID **)&gpsSysData->pvSOCTimerRegisterKM, -+ &gpsSysData->hSOCTimerRegisterOSMemHandle); -+ } -+#endif /* !defined(PVR_NO_OMAP_TIMER) */ -+ -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysFinalise -+ -+ @Description Final part of initialisation at 'driver load' time -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+PVRSRV_ERROR SysFinalise(IMG_VOID) -+{ -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ eError = EnableSGXClocksWrap(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to Enable SGX clocks (%d)", eError)); -+ return eError; -+ } -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ -+ eError = OSInstallMISR(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to install MISR")); -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_MISR); -+ -+#if defined(SYS_USING_INTERRUPTS) -+ /* install a Device ISR */ -+ eError = OSInstallDeviceLISR(gpsSysData, gsSGXDeviceMap.ui32IRQ, "SGX ISR", gpsSGXDevNode); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to install ISR")); -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR); -+#if !defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ SysEnableSGXInterrupts(gpsSysData); -+#endif -+#endif /* defined(SYS_USING_INTERRUPTS) */ -+#if defined(__linux__) -+ /* Create a human readable version string for this system */ -+ gpsSysData->pszVersionString = SysCreateVersionString(); -+ if (!gpsSysData->pszVersionString) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to create a system version string")); -+ } -+ else -+ { -+ PVR_TRACE(("SysFinalise: Version string: %s", gpsSysData->pszVersionString)); -+ } -+#endif -+ -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ /* SGX defaults to D3 power state */ -+ DisableSGXClocks(gpsSysData); -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ -+ gpsSysSpecificData->bSGXInitComplete = IMG_TRUE; -+ -+ return eError; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysDeinitialise -+ -+ @Description De-initialises kernel services at 'driver unload' time -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR SysDeinitialise (SYS_DATA *psSysData) -+{ -+ PVRSRV_ERROR eError; -+ -+ PVR_UNREFERENCED_PARAMETER(psSysData); -+ -+ if(gpsSysData->pvSOCTimerRegisterKM) -+ { -+ OSUnReservePhys(gpsSysData->pvSOCTimerRegisterKM, -+ 4, -+ PVRSRV_HAP_MULTI_PROCESS|PVRSRV_HAP_UNCACHED, -+ gpsSysData->hSOCTimerRegisterOSMemHandle); -+ } -+ -+ -+#if defined(SYS_USING_INTERRUPTS) -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR)) -+ { -+ eError = OSUninstallDeviceLISR(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: OSUninstallDeviceLISR failed")); -+ return eError; -+ } -+ } -+#endif -+ -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_MISR)) -+ { -+ eError = OSUninstallMISR(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: OSUninstallMISR failed")); -+ return eError; -+ } -+ } -+ -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_INITDEV)) -+ { -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ PVR_ASSERT(SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS)); -+ /* Reenable SGX clocks whilst SGX is being deinitialised. */ -+ eError = EnableSGXClocksWrap(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: EnableSGXClocks failed")); -+ return eError; -+ } -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ -+ /* Deinitialise SGX */ -+ eError = PVRSRVDeinitialiseDevice (gui32SGXDeviceID); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: failed to de-init the device")); -+ return eError; -+ } -+ } -+ -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_DVFS_INIT)) -+ { -+ eError = SysDvfsDeinitialize(gpsSysSpecificData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: Failed to de-init DVFS")); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ } -+ -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_PM_RUNTIME)) -+ { -+ eError = SysPMRuntimeUnregister(); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: Failed to unregister with OSPM!")); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ } -+ -+ /* -+ Disable system clocks - must happen after last access to hardware. -+ */ -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS)) -+ { -+ DisableSystemClocks(gpsSysData); -+ } -+ -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_ENVDATA)) -+ { -+ eError = OSDeInitEnvData(gpsSysData->pvEnvSpecificData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: failed to de-init env structure")); -+ return eError; -+ } -+ } -+ -+ SysDeinitialiseCommon(gpsSysData); -+ -+#if defined(NO_HARDWARE) || defined(SGX_OCP_REGS_ENABLED) -+ if(gsSGXRegsCPUVAddr != IMG_NULL) -+ { -+#if defined(NO_HARDWARE) -+ /* Free hardware resources. */ -+ OSBaseFreeContigMemory(SYS_OMAP4430_SGX_REGS_SIZE, gsSGXRegsCPUVAddr, gsSGXDeviceMap.sRegsCpuPBase); -+#else -+#if defined(SGX_OCP_REGS_ENABLED) -+ OSUnMapPhysToLin(gsSGXRegsCPUVAddr, -+ gsSGXDeviceMap.ui32RegsSize, -+ PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY, -+ IMG_NULL); -+ -+ gpvOCPRegsLinAddr = IMG_NULL; -+#endif -+#endif /* defined(NO_HARDWARE) */ -+ gsSGXRegsCPUVAddr = IMG_NULL; -+ gsSGXDeviceMap.pvRegsCpuVBase = gsSGXRegsCPUVAddr; -+ } -+#endif /* defined(NO_HARDWARE) || defined(SGX_OCP_REGS_ENABLED) */ -+ -+ -+ gpsSysSpecificData->ui32SysSpecificData = 0; -+ gpsSysSpecificData->bSGXInitComplete = IMG_FALSE; -+ -+ gpsSysData = IMG_NULL; -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysGetDeviceMemoryMap -+ -+ @Description returns a device address map for the specified device -+ -+ @Input eDeviceType - device type -+ @Input ppvDeviceMap - void ptr to receive device specific info. -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE eDeviceType, -+ IMG_VOID **ppvDeviceMap) -+{ -+ -+ switch(eDeviceType) -+ { -+ case PVRSRV_DEVICE_TYPE_SGX: -+ { -+ /* just return a pointer to the structure */ -+ *ppvDeviceMap = (IMG_VOID*)&gsSGXDeviceMap; -+ -+ break; -+ } -+ default: -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysGetDeviceMemoryMap: unsupported device type")); -+ } -+ } -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function SysCpuPAddrToDevPAddr -+ -+ @Description Compute a device physical address from a cpu physical -+ address. Relevant when -+ -+ @Input cpu_paddr - cpu physical address. -+ @Input eDeviceType - device type required if DevPAddr -+ address spaces vary across devices -+ in the same system -+ @Return device physical address. -+ -+******************************************************************************/ -+IMG_DEV_PHYADDR SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType, -+ IMG_CPU_PHYADDR CpuPAddr) -+{ -+ IMG_DEV_PHYADDR DevPAddr; -+ -+ PVR_UNREFERENCED_PARAMETER(eDeviceType); -+ -+ /* Note: for UMA system we assume DevP == CpuP */ -+ DevPAddr.uiAddr = CpuPAddr.uiAddr; -+ -+ return DevPAddr; -+} -+ -+/*! -+****************************************************************************** -+ @Function SysSysPAddrToCpuPAddr -+ -+ @Description Compute a cpu physical address from a system physical -+ address. -+ -+ @Input sys_paddr - system physical address. -+ @Return cpu physical address. -+ -+******************************************************************************/ -+IMG_CPU_PHYADDR SysSysPAddrToCpuPAddr (IMG_SYS_PHYADDR sys_paddr) -+{ -+ IMG_CPU_PHYADDR cpu_paddr; -+ -+ /* This would only be an inequality if the CPU's MMU did not point to -+ sys address 0, ie. multi CPU system */ -+ cpu_paddr.uiAddr = sys_paddr.uiAddr; -+ return cpu_paddr; -+} -+ -+/*! -+****************************************************************************** -+ @Function SysCpuPAddrToSysPAddr -+ -+ @Description Compute a system physical address from a cpu physical -+ address. -+ -+ @Input cpu_paddr - cpu physical address. -+ @Return device physical address. -+ -+******************************************************************************/ -+IMG_SYS_PHYADDR SysCpuPAddrToSysPAddr (IMG_CPU_PHYADDR cpu_paddr) -+{ -+ IMG_SYS_PHYADDR sys_paddr; -+ -+ /* This would only be an inequality if the CPU's MMU did not point to -+ sys address 0, ie. multi CPU system */ -+ sys_paddr.uiAddr = cpu_paddr.uiAddr; -+ return sys_paddr; -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function SysSysPAddrToDevPAddr -+ -+ @Description Compute a device physical address from a system physical -+ address. -+ -+ @Input SysPAddr - system physical address. -+ @Input eDeviceType - device type required if DevPAddr -+ address spaces vary across devices -+ in the same system -+ -+ @Return Device physical address. -+ -+******************************************************************************/ -+IMG_DEV_PHYADDR SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType, IMG_SYS_PHYADDR SysPAddr) -+{ -+ IMG_DEV_PHYADDR DevPAddr; -+ -+ PVR_UNREFERENCED_PARAMETER(eDeviceType); -+ -+ /* Note: for UMA system we assume DevP == CpuP */ -+ DevPAddr.uiAddr = SysPAddr.uiAddr; -+ -+ return DevPAddr; -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function SysDevPAddrToSysPAddr -+ -+ @Description Compute a device physical address from a system physical -+ address. -+ -+ @Input DevPAddr - device physical address. -+ @Input eDeviceType - device type required if DevPAddr -+ address spaces vary across devices -+ in the same system -+ -+ @Return System physical address. -+ -+******************************************************************************/ -+IMG_SYS_PHYADDR SysDevPAddrToSysPAddr(PVRSRV_DEVICE_TYPE eDeviceType, IMG_DEV_PHYADDR DevPAddr) -+{ -+ IMG_SYS_PHYADDR SysPAddr; -+ -+ PVR_UNREFERENCED_PARAMETER(eDeviceType); -+ -+ /* Note: for UMA system we assume DevP == SysP */ -+ SysPAddr.uiAddr = DevPAddr.uiAddr; -+ -+ return SysPAddr; -+} -+ -+ -+/***************************************************************************** -+ @Function SysRegisterExternalDevice -+ -+ @Description Called when a 3rd party device registers with services -+ -+ @Input psDeviceNode - the new device node. -+ -+ @Return IMG_VOID -+*****************************************************************************/ -+IMG_VOID SysRegisterExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode) -+{ -+ PVR_UNREFERENCED_PARAMETER(psDeviceNode); -+} -+ -+ -+/***************************************************************************** -+ @Function SysRemoveExternalDevice -+ -+ @Description Called when a 3rd party device unregisters from services -+ -+ @Input psDeviceNode - the device node being removed. -+ -+ @Return IMG_VOID -+*****************************************************************************/ -+IMG_VOID SysRemoveExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode) -+{ -+ PVR_UNREFERENCED_PARAMETER(psDeviceNode); -+} -+ -+/*! -+****************************************************************************** -+ @Function SysGetInterruptSource -+ -+ @Description Returns System specific information about the device(s) that -+ generated the interrupt in the system -+ -+ @Input psSysData -+ @Input psDeviceNode -+ -+ @Return System specific information indicating which device(s) -+ generated the interrupt -+ -+******************************************************************************/ -+IMG_UINT32 SysGetInterruptSource(SYS_DATA *psSysData, -+ PVRSRV_DEVICE_NODE *psDeviceNode) -+{ -+ PVR_UNREFERENCED_PARAMETER(psSysData); -+#if defined(NO_HARDWARE) -+ /* no interrupts in no_hw system just return all bits */ -+ return 0xFFFFFFFF; -+#else -+ /* Not a shared irq, so we know this is an interrupt for this device */ -+ return psDeviceNode->ui32SOCInterruptBit; -+#endif -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function SysClearInterrupts -+ -+ @Description Clears specified system interrupts -+ -+ @Input psSysData -+ @Input ui32ClearBits -+ -+ @Return IMG_VOID -+ -+******************************************************************************/ -+IMG_VOID SysClearInterrupts(SYS_DATA* psSysData, IMG_UINT32 ui32ClearBits) -+{ -+ PVR_UNREFERENCED_PARAMETER(ui32ClearBits); -+ PVR_UNREFERENCED_PARAMETER(psSysData); -+#if !defined(NO_HARDWARE) -+#if defined(SGX_OCP_NO_INT_BYPASS) -+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_IRQSTATUS_2, 0x1); -+#endif -+ /* Flush posted writes */ -+ OSReadHWReg(((PVRSRV_SGXDEV_INFO *)gpsSGXDevNode->pvDevice)->pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR); -+#endif /* defined(NO_HARDWARE) */ -+} -+ -+#if defined(SGX_OCP_NO_INT_BYPASS) -+/*! -+****************************************************************************** -+ @Function SysEnableSGXInterrupts -+ -+ @Description Enables SGX interrupts -+ -+ @Input psSysData -+ -+ @Return IMG_VOID -+ -+******************************************************************************/ -+IMG_VOID SysEnableSGXInterrupts(SYS_DATA *psSysData) -+{ -+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *)psSysData->pvSysSpecificData; -+ if (SYS_SPECIFIC_DATA_TEST(psSysSpecData, SYS_SPECIFIC_DATA_ENABLE_LISR) && !SYS_SPECIFIC_DATA_TEST(psSysSpecData, SYS_SPECIFIC_DATA_IRQ_ENABLED)) -+ { -+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_IRQSTATUS_2, 0x1); -+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_IRQENABLE_SET_2, 0x1); -+ SYS_SPECIFIC_DATA_SET(psSysSpecData, SYS_SPECIFIC_DATA_IRQ_ENABLED); -+ } -+} -+ -+/*! -+****************************************************************************** -+ @Function SysDisableSGXInterrupts -+ -+ @Description Disables SGX interrupts -+ -+ @Input psSysData -+ -+ @Return IMG_VOID -+ -+******************************************************************************/ -+IMG_VOID SysDisableSGXInterrupts(SYS_DATA *psSysData) -+{ -+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *)psSysData->pvSysSpecificData; -+ -+ if (SYS_SPECIFIC_DATA_TEST(psSysSpecData, SYS_SPECIFIC_DATA_IRQ_ENABLED)) -+ { -+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_IRQENABLE_CLR_2, 0x1); -+ SYS_SPECIFIC_DATA_CLEAR(psSysSpecData, SYS_SPECIFIC_DATA_IRQ_ENABLED); -+ } -+} -+#endif /* defined(SGX_OCP_NO_INT_BYPASS) */ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysSystemPrePowerState -+ -+ @Description Perform system-level processing required before a power transition -+ -+ @Input eNewPowerState : -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR SysSystemPrePowerState(PVRSRV_SYS_POWER_STATE eNewPowerState) -+{ -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ -+ if (eNewPowerState == PVRSRV_SYS_POWER_STATE_D3) -+ { -+ PVR_TRACE(("SysSystemPrePowerState: Entering state D3")); -+ -+#if defined(SYS_USING_INTERRUPTS) -+ if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR)) -+ { -+#if defined(SYS_CUSTOM_POWERLOCK_WRAP) -+ IMG_BOOL bWrapped = WrapSystemPowerChange(&gsSysSpecificData); -+#endif -+ eError = OSUninstallDeviceLISR(gpsSysData); -+#if defined(SYS_CUSTOM_POWERLOCK_WRAP) -+ if (bWrapped) -+ { -+ UnwrapSystemPowerChange(&gsSysSpecificData); -+ } -+#endif -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysSystemPrePowerState: OSUninstallDeviceLISR failed (%d)", eError)); -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR); -+ SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR); -+ } -+#endif -+ -+ if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS)) -+ { -+ DisableSystemClocks(gpsSysData); -+ -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS); -+ SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS); -+ } -+ } -+ -+ return eError; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysSystemPostPowerState -+ -+ @Description Perform system-level processing required after a power transition -+ -+ @Input eNewPowerState : -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR SysSystemPostPowerState(PVRSRV_SYS_POWER_STATE eNewPowerState) -+{ -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ -+ if (eNewPowerState == PVRSRV_SYS_POWER_STATE_D0) -+ { -+ PVR_TRACE(("SysSystemPostPowerState: Entering state D0")); -+ -+ if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS)) -+ { -+ eError = EnableSystemClocksWrap(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysSystemPostPowerState: EnableSystemClocksWrap failed (%d)", eError)); -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS); -+ SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS); -+ } -+ -+#if defined(SYS_USING_INTERRUPTS) -+ if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR)) -+ { -+#if defined(SYS_CUSTOM_POWERLOCK_WRAP) -+ IMG_BOOL bWrapped = WrapSystemPowerChange(&gsSysSpecificData); -+#endif -+ -+ eError = OSInstallDeviceLISR(gpsSysData, gsSGXDeviceMap.ui32IRQ, "SGX ISR", gpsSGXDevNode); -+#if defined(SYS_CUSTOM_POWERLOCK_WRAP) -+ if (bWrapped) -+ { -+ UnwrapSystemPowerChange(&gsSysSpecificData); -+ } -+#endif -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysSystemPostPowerState: OSInstallDeviceLISR failed to install ISR (%d)", eError)); -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR); -+ SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR); -+ } -+#endif -+ } -+ return eError; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysDevicePrePowerState -+ -+ @Description Perform system level processing required before a device power -+ transition -+ -+ @Input ui32DeviceIndex : -+ @Input eNewPowerState : -+ @Input eCurrentPowerState : -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR SysDevicePrePowerState(IMG_UINT32 ui32DeviceIndex, -+ PVRSRV_DEV_POWER_STATE eNewPowerState, -+ PVRSRV_DEV_POWER_STATE eCurrentPowerState) -+{ -+ PVR_UNREFERENCED_PARAMETER(eCurrentPowerState); -+ -+ if (ui32DeviceIndex != gui32SGXDeviceID) -+ { -+ return PVRSRV_OK; -+ } -+ -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ if (eNewPowerState == PVRSRV_DEV_POWER_STATE_OFF) -+ { -+ PVR_DPF((PVR_DBG_MESSAGE, "SysDevicePrePowerState: SGX Entering state D3")); -+ DisableSGXClocks(gpsSysData); -+ } -+#else /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ PVR_UNREFERENCED_PARAMETER(eNewPowerState ); -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysDevicePostPowerState -+ -+ @Description Perform system level processing required after a device power -+ transition -+ -+ @Input ui32DeviceIndex : -+ @Input eNewPowerState : -+ @Input eCurrentPowerState : -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR SysDevicePostPowerState(IMG_UINT32 ui32DeviceIndex, -+ PVRSRV_DEV_POWER_STATE eNewPowerState, -+ PVRSRV_DEV_POWER_STATE eCurrentPowerState) -+{ -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ -+ PVR_UNREFERENCED_PARAMETER(eNewPowerState); -+ -+ if (ui32DeviceIndex != gui32SGXDeviceID) -+ { -+ return eError; -+ } -+ -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ if (eCurrentPowerState == PVRSRV_DEV_POWER_STATE_OFF) -+ { -+ PVR_DPF((PVR_DBG_MESSAGE, "SysDevicePostPowerState: SGX Leaving state D3")); -+ eError = EnableSGXClocksWrap(gpsSysData); -+ } -+#else /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ PVR_UNREFERENCED_PARAMETER(eCurrentPowerState); -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ -+ return eError; -+} -+ -+#if defined(SYS_SUPPORTS_SGX_IDLE_CALLBACK) -+ -+IMG_VOID SysSGXIdleTransition(IMG_BOOL bSGXIdle) -+{ -+ PVR_DPF((PVR_DBG_MESSAGE, "SysSGXIdleTransition switch to %u", bSGXIdle)); -+} -+ -+#endif /* defined(SYS_SUPPORTS_SGX_IDLE_CALLBACK) */ -+ -+/***************************************************************************** -+ @Function SysOEMFunction -+ -+ @Description marshalling function for custom OEM functions -+ -+ @Input ui32ID - function ID -+ @Input pvIn - in data -+ @Output pvOut - out data -+ -+ @Return PVRSRV_ERROR -+*****************************************************************************/ -+PVRSRV_ERROR SysOEMFunction ( IMG_UINT32 ui32ID, -+ IMG_VOID *pvIn, -+ IMG_UINT32 ulInSize, -+ IMG_VOID *pvOut, -+ IMG_UINT32 ulOutSize) -+{ -+ PVR_UNREFERENCED_PARAMETER(ui32ID); -+ PVR_UNREFERENCED_PARAMETER(pvIn); -+ PVR_UNREFERENCED_PARAMETER(ulInSize); -+ PVR_UNREFERENCED_PARAMETER(pvOut); -+ PVR_UNREFERENCED_PARAMETER(ulOutSize); -+ -+ if ((ui32ID == OEM_GET_EXT_FUNCS) && -+ (ulOutSize == sizeof(PVRSRV_DC_OEM_JTABLE))) -+ { -+ PVRSRV_DC_OEM_JTABLE *psOEMJTable = (PVRSRV_DC_OEM_JTABLE*) pvOut; -+ psOEMJTable->pfnOEMBridgeDispatch = &PVRSRV_BridgeDispatchKM; -+ return PVRSRV_OK; -+ } -+ -+ return PVRSRV_ERROR_INVALID_PARAMS; -+} -+/****************************************************************************** -+ End of file (sysconfig.c) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/system/omap4/sysconfig.h b/drivers/staging/ti-es8-sgx/services4/system/omap4/sysconfig.h -new file mode 100644 -index 0000000..f351c27 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/omap4/sysconfig.h -@@ -0,0 +1,110 @@ -+/*************************************************************************/ /*! -+@Title System Description Header -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description This header provides system-specific declarations and macros -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#if !defined(__SOCCONFIG_H__) -+#define __SOCCONFIG_H__ -+ -+#define VS_PRODUCT_NAME "OMAP4" -+ -+#if defined(SGX540) && (SGX_CORE_REV == 120) -+#define SYS_SGX_CLOCK_SPEED 307200000 -+#else -+#define SYS_SGX_CLOCK_SPEED 304742400 -+#endif -+ -+#define SYS_SGX_HWRECOVERY_TIMEOUT_FREQ (100) // 10ms (100hz) -+#define SYS_SGX_PDS_TIMER_FREQ (1000) // 1ms (1000hz) -+ -+/* Allow the AP latency to be overridden in the build config */ -+#if !defined(SYS_SGX_ACTIVE_POWER_LATENCY_MS) -+#define SYS_SGX_ACTIVE_POWER_LATENCY_MS (2) -+#endif -+ -+ -+#define SYS_OMAP4430_SGX_REGS_SYS_PHYS_BASE 0x56000000 -+#define SYS_OMAP4430_SGX_REGS_SIZE 0xFFFF -+ -+#define SYS_OMAP4430_SGX_IRQ 53 /* OMAP4 IRQ's are offset by 32 */ -+ -+#define SYS_OMAP4430_DSS_REGS_SYS_PHYS_BASE 0x58000000 -+#define SYS_OMAP4430_DSS_REGS_SIZE 0x7000 -+ -+#define SYS_OMAP4430_DSS_HDMI_INTERRUPT_STATUS_REG 0x6028 -+#define SYS_OMAP4430_DSS_HDMI_INTERRUPT_ENABLE_REG 0x602c -+ -+#define SYS_OMAP4430_DSS_HDMI_INTERRUPT_VSYNC_ENABLE_MASK 0x10000 -+#define SYS_OMAP4430_DSS_HDMI_INTERRUPT_VSYNC_STATUS_MASK 0x10000 -+ -+#define SYS_OMAP4430_DSS_LCD_INTERRUPT_STATUS_REG 0x1018 -+#define SYS_OMAP4430_DSS_LCD_INTERRUPT_ENABLE_REG 0x101c -+ -+#define SYS_OMAP4430_DSS_LCD_INTERRUPT_VSYNC_ENABLE_MASK 0x40002 -+#define SYS_OMAP4430_DSS_LCD_INTERRUPT_VSYNC_STATUS_MASK 0x40002 -+ -+ -+#define SYS_OMAP4430_GP11TIMER_ENABLE_SYS_PHYS_BASE 0x48088038 -+#define SYS_OMAP4430_GP11TIMER_REGS_SYS_PHYS_BASE 0x4808803C -+#define SYS_OMAP4430_GP11TIMER_TSICR_SYS_PHYS_BASE 0x48088054 -+ -+/* Interrupt bits */ -+#define DEVICE_SGX_INTERRUPT (1<<0) -+#define DEVICE_MSVDX_INTERRUPT (1<<1) -+#define DEVICE_DISP_INTERRUPT (1<<2) -+ -+#if defined(__linux__) -+/* -+ * Recent OMAP4 kernels register SGX as platform device "omap_gpu". -+ * This device must be used with the Linux power management calls -+ * in sysutils_linux.c, in order for SGX to be powered on. -+ */ -+#if defined(PVR_LDM_PLATFORM_PRE_REGISTERED_DEV) -+#define SYS_SGX_DEV_NAME PVR_LDM_PLATFORM_PRE_REGISTERED_DEV -+#else -+#define SYS_SGX_DEV_NAME "omap_gpu" -+#endif /* defined(PVR_LDM_PLATFORM_PRE_REGISTERED_DEV) */ -+#endif /* defined(__linux__) */ -+ -+/***************************************************************************** -+ * system specific data structures -+ *****************************************************************************/ -+ -+#endif /* __SYSCONFIG_H__ */ -diff --git a/drivers/staging/ti-es8-sgx/services4/system/omap4/sysinfo.h b/drivers/staging/ti-es8-sgx/services4/system/omap4/sysinfo.h -new file mode 100644 -index 0000000..70ae148 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/omap4/sysinfo.h -@@ -0,0 +1,64 @@ -+/*************************************************************************/ /*! -+@Title System Description Header -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description This header provides system-specific declarations and macros -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#if !defined(__SYSINFO_H__) -+#define __SYSINFO_H__ -+ -+/*!< System specific poll/timeout details */ -+#if defined(PVR_LINUX_USING_WORKQUEUES) -+/* -+ * The workqueue based 3rd party display driver may be blocked for up -+ * to 500ms waiting for a vsync when the screen goes blank, so we -+ * need to wait longer for the hardware if a flush of the swap chain is -+ * required. -+ */ -+#define MAX_HW_TIME_US (1000000) -+#define WAIT_TRY_COUNT (20000) -+#else -+#define MAX_HW_TIME_US (500000) -+#define WAIT_TRY_COUNT (10000) -+#endif -+ -+ -+#define SYS_DEVICE_COUNT 15 /* SGX, DISPLAYCLASS (external), BUFFERCLASS (external) */ -+ -+#endif /* __SYSINFO_H__ */ -diff --git a/drivers/staging/ti-es8-sgx/services4/system/omap4/syslocal.h b/drivers/staging/ti-es8-sgx/services4/system/omap4/syslocal.h -new file mode 100644 -index 0000000..a648da2 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/omap4/syslocal.h -@@ -0,0 +1,256 @@ -+/*************************************************************************/ /*! -+@Title Local system definitions -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description This header provides local system declarations and macros -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#if !defined(__SYSLOCAL_H__) -+#define __SYSLOCAL_H__ -+ -+#if defined(__linux__) -+ -+#include <linux/version.h> -+#include <linux/clk.h> -+#if defined(PVR_LINUX_USING_WORKQUEUES) -+#include <linux/mutex.h> -+#else -+#include <linux/spinlock.h> -+#endif -+#include <asm/atomic.h> -+ -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)) -+#include <linux/semaphore.h> -+#include <linux/resource.h> -+#else /* (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)) */ -+#include <asm/semaphore.h> -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22)) -+#include <asm/arch/resource.h> -+#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22)) */ -+#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)) */ -+ -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) -+#if !defined(LDM_PLATFORM) -+#error "LDM_PLATFORM must be set" -+#endif -+#define PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO -+#include <linux/platform_device.h> -+#endif -+ -+#if ((defined(DEBUG) || defined(TIMING)) && \ -+ (LINUX_VERSION_CODE == KERNEL_VERSION(2,6,34))) && \ -+ !defined(PVR_NO_OMAP_TIMER) -+/* -+ * We need to explicitly enable the GPTIMER11 clocks, or we'll get an -+ * abort when we try to access the timer registers. -+ */ -+#define PVR_OMAP4_TIMING_PRCM -+#endif -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) -+#include <plat/gpu.h> -+#if !defined(PVR_NO_OMAP_TIMER) -+#define PVR_OMAP_USE_DM_TIMER_API -+#include <plat/dmtimer.h> -+#endif -+#endif -+ -+#if !defined(PVR_NO_OMAP_TIMER) -+#define PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA -+#endif -+#endif /* defined(__linux__) */ -+ -+#if !defined(NO_HARDWARE) && \ -+ defined(SYS_USING_INTERRUPTS) -+#define SGX_OCP_REGS_ENABLED -+#endif -+ -+#if defined(__linux__) -+#if defined(SGX_OCP_REGS_ENABLED) -+#define SGX_OCP_NO_INT_BYPASS -+#endif -+#endif -+ -+#if defined (__cplusplus) -+extern "C" { -+#endif -+ -+/***************************************************************************** -+ * system specific data structures -+ *****************************************************************************/ -+ -+/***************************************************************************** -+ * system specific function prototypes -+ *****************************************************************************/ -+ -+IMG_VOID DisableSystemClocks(SYS_DATA *psSysData); -+PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData); -+ -+IMG_VOID DisableSGXClocks(SYS_DATA *psSysData); -+PVRSRV_ERROR EnableSGXClocks(SYS_DATA *psSysData); -+ -+/* -+ * Various flags to indicate what has been initialised, and what -+ * has been temporarily deinitialised for power management purposes. -+ */ -+#define SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS 0x00000001 -+#define SYS_SPECIFIC_DATA_ENABLE_LISR 0x00000002 -+#define SYS_SPECIFIC_DATA_ENABLE_MISR 0x00000004 -+#define SYS_SPECIFIC_DATA_ENABLE_ENVDATA 0x00000008 -+#define SYS_SPECIFIC_DATA_ENABLE_LOCDEV 0x00000010 -+#define SYS_SPECIFIC_DATA_ENABLE_REGDEV 0x00000020 -+#define SYS_SPECIFIC_DATA_ENABLE_PDUMPINIT 0x00000040 -+#define SYS_SPECIFIC_DATA_ENABLE_INITDEV 0x00000080 -+#define SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV 0x00000100 -+ -+#define SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR 0x00000200 -+#define SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS 0x00000400 -+#define SYS_SPECIFIC_DATA_ENABLE_OCPREGS 0x00000800 -+#define SYS_SPECIFIC_DATA_ENABLE_PM_RUNTIME 0x00001000 -+#define SYS_SPECIFIC_DATA_IRQ_ENABLED 0x00002000 -+#define SYS_SPECIFIC_DATA_DVFS_INIT 0x00004000 -+ -+#define SYS_SPECIFIC_DATA_SET(psSysSpecData, flag) ((IMG_VOID)((psSysSpecData)->ui32SysSpecificData |= (flag))) -+ -+#define SYS_SPECIFIC_DATA_CLEAR(psSysSpecData, flag) ((IMG_VOID)((psSysSpecData)->ui32SysSpecificData &= ~(flag))) -+ -+#define SYS_SPECIFIC_DATA_TEST(psSysSpecData, flag) (((psSysSpecData)->ui32SysSpecificData & (flag)) != 0) -+ -+typedef struct _SYS_SPECIFIC_DATA_TAG_ -+{ -+ IMG_UINT32 ui32SysSpecificData; -+ PVRSRV_DEVICE_NODE *psSGXDevNode; -+ IMG_BOOL bSGXInitComplete; -+#if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA) -+ IMG_CPU_PHYADDR sTimerRegPhysBase; -+#endif -+#if !defined(__linux__) -+ IMG_BOOL bSGXClocksEnabled; -+#endif -+ IMG_UINT32 ui32SrcClockDiv; -+#if defined(__linux__) -+ IMG_BOOL bSysClocksOneTimeInit; -+ atomic_t sSGXClocksEnabled; -+#if defined(PVR_LINUX_USING_WORKQUEUES) -+ struct mutex sPowerLock; -+#else -+ IMG_BOOL bConstraintNotificationsEnabled; -+ spinlock_t sPowerLock; -+ atomic_t sPowerLockCPU; -+ spinlock_t sNotifyLock; -+ atomic_t sNotifyLockCPU; -+ IMG_BOOL bCallVDD2PostFunc; -+#endif -+#if defined(DEBUG) || defined(TIMING) -+ struct clk *psGPT11_FCK; -+ struct clk *psGPT11_ICK; -+#endif -+#if defined(PVR_OMAP_USE_DM_TIMER_API) -+ struct omap_dm_timer *psGPTimer; -+#endif -+ IMG_UINT32 ui32SGXFreqListSize; -+ IMG_UINT32 *pui32SGXFreqList; -+ IMG_UINT32 ui32SGXFreqListIndex; -+#endif /* defined(__linux__) */ -+} SYS_SPECIFIC_DATA; -+ -+extern SYS_SPECIFIC_DATA *gpsSysSpecificData; -+ -+#if defined(SGX_OCP_REGS_ENABLED) && defined(SGX_OCP_NO_INT_BYPASS) -+IMG_VOID SysEnableSGXInterrupts(SYS_DATA* psSysData); -+IMG_VOID SysDisableSGXInterrupts(SYS_DATA* psSysData); -+#else -+#define SysEnableSGXInterrupts(psSysData) -+#define SysDisableSGXInterrupts(psSysData) -+#endif -+ -+#if defined(SYS_CUSTOM_POWERLOCK_WRAP) -+IMG_BOOL WrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData); -+IMG_VOID UnwrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData); -+#endif -+ -+#if defined(__linux__) -+ -+PVRSRV_ERROR SysPMRuntimeRegister(void); -+PVRSRV_ERROR SysPMRuntimeUnregister(void); -+ -+PVRSRV_ERROR SysDvfsInitialize(SYS_SPECIFIC_DATA *psSysSpecificData); -+PVRSRV_ERROR SysDvfsDeinitialize(SYS_SPECIFIC_DATA *psSysSpecificData); -+ -+#else /* defined(__linux__) */ -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(SysPMRuntimeRegister) -+#endif -+static INLINE PVRSRV_ERROR SysPMRuntimeRegister(void) -+{ -+ return PVRSRV_OK; -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(SysPMRuntimeUnregister) -+#endif -+static INLINE PVRSRV_ERROR SysPMRuntimeUnregister(void) -+{ -+ return PVRSRV_OK; -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(SysDvfsInitialize) -+#endif -+static INLINE PVRSRV_ERROR SysDvfsInitialize(void) -+{ -+ return PVRSRV_OK; -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(SysDvfsDeinitialize) -+#endif -+static INLINE PVRSRV_ERROR SysDvfsDeinitialize(void) -+{ -+ return PVRSRV_OK; -+} -+ -+#endif /* defined(__linux__) */ -+ -+#if defined(__cplusplus) -+} -+#endif -+ -+#endif /* __SYSLOCAL_H__ */ -diff --git a/drivers/staging/ti-es8-sgx/services4/system/omap4/sysutils.c b/drivers/staging/ti-es8-sgx/services4/system/omap4/sysutils.c -new file mode 100644 -index 0000000..6725421 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/omap4/sysutils.c -@@ -0,0 +1,47 @@ -+/*************************************************************************/ /*! -+@Title Shared (User/kernel) and System dependent utilities -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Provides system-specific functions -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+/* Pull in the correct system dependent sysutils source */ -+ -+#if defined(__linux__) -+#include "sysutils_linux.c" -+#endif -diff --git a/drivers/staging/ti-es8-sgx/services4/system/omap4/sysutils_linux.c b/drivers/staging/ti-es8-sgx/services4/system/omap4/sysutils_linux.c -new file mode 100644 -index 0000000..2008d94 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/omap4/sysutils_linux.c -@@ -0,0 +1,849 @@ -+/*************************************************************************/ /*! -+@Title System dependent utilities -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Provides system-specific functions -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+#include <linux/version.h> -+#include <linux/clk.h> -+#include <linux/err.h> -+#include <linux/hardirq.h> -+#include <linux/mutex.h> -+#include <linux/slab.h> -+ -+#include "sgxdefs.h" -+#include "services_headers.h" -+#include "sysinfo.h" -+#include "sgxapi_km.h" -+#include "sysconfig.h" -+#include "sgxinfokm.h" -+#include "syslocal.h" -+ -+#include <linux/platform_device.h> -+#include <linux/pm_runtime.h> -+ -+#if defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK) -+#include <linux/opp.h> -+#endif -+ -+#if defined(SUPPORT_DRI_DRM_PLUGIN) -+#include <drm/drmP.h> -+#include <drm/drm.h> -+ -+#include <linux/omap_gpu.h> -+ -+#include "pvr_drm.h" -+#endif -+ -+#define ONE_MHZ 1000000 -+#define HZ_TO_MHZ(m) ((m) / ONE_MHZ) -+ -+#if defined(SUPPORT_OMAP3430_SGXFCLK_96M) -+#define SGX_PARENT_CLOCK "cm_96m_fck" -+#else -+#define SGX_PARENT_CLOCK "core_ck" -+#endif -+ -+#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) -+extern struct platform_device *gpsPVRLDMDev; -+#endif -+ -+static PVRSRV_ERROR PowerLockWrap(SYS_SPECIFIC_DATA *psSysSpecData, IMG_BOOL bTryLock) -+{ -+ if (!in_interrupt()) -+ { -+ if (bTryLock) -+ { -+ int locked = mutex_trylock(&psSysSpecData->sPowerLock); -+ if (locked == 0) -+ { -+ return PVRSRV_ERROR_RETRY; -+ } -+ } -+ else -+ { -+ mutex_lock(&psSysSpecData->sPowerLock); -+ } -+ } -+ -+ return PVRSRV_OK; -+} -+ -+static IMG_VOID PowerLockUnwrap(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ if (!in_interrupt()) -+ { -+ mutex_unlock(&psSysSpecData->sPowerLock); -+ } -+} -+ -+PVRSRV_ERROR SysPowerLockWrap(IMG_BOOL bTryLock) -+{ -+ SYS_DATA *psSysData; -+ -+ SysAcquireData(&psSysData); -+ -+ return PowerLockWrap(psSysData->pvSysSpecificData, bTryLock); -+} -+ -+IMG_VOID SysPowerLockUnwrap(IMG_VOID) -+{ -+ SYS_DATA *psSysData; -+ -+ SysAcquireData(&psSysData); -+ -+ PowerLockUnwrap(psSysData->pvSysSpecificData); -+} -+ -+/* -+ * This function should be called to unwrap the Services power lock, prior -+ * to calling any function that might sleep. -+ * This function shouldn't be called prior to calling EnableSystemClocks -+ * or DisableSystemClocks, as those functions perform their own power lock -+ * unwrapping. -+ * If the function returns IMG_TRUE, UnwrapSystemPowerChange must be -+ * called to rewrap the power lock, prior to returning to Services. -+ */ -+IMG_BOOL WrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ return IMG_TRUE; -+} -+ -+IMG_VOID UnwrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+} -+ -+/* -+ * Return SGX timining information to caller. -+ */ -+IMG_VOID SysGetSGXTimingInformation(SGX_TIMING_INFORMATION *psTimingInfo) -+{ -+#if !defined(NO_HARDWARE) -+ PVR_ASSERT(atomic_read(&gpsSysSpecificData->sSGXClocksEnabled) != 0); -+#endif -+#if defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK) -+ psTimingInfo->ui32CoreClockSpeed = -+ gpsSysSpecificData->pui32SGXFreqList[gpsSysSpecificData->ui32SGXFreqListIndex]; -+#else /* defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK) */ -+ psTimingInfo->ui32CoreClockSpeed = SYS_SGX_CLOCK_SPEED; -+#endif -+ psTimingInfo->ui32HWRecoveryFreq = SYS_SGX_HWRECOVERY_TIMEOUT_FREQ; -+ psTimingInfo->ui32uKernelFreq = SYS_SGX_PDS_TIMER_FREQ; -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ psTimingInfo->bEnableActivePM = IMG_TRUE; -+#else -+ psTimingInfo->bEnableActivePM = IMG_FALSE; -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ psTimingInfo->ui32ActivePowManLatencyms = SYS_SGX_ACTIVE_POWER_LATENCY_MS; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function EnableSGXClocks -+ -+ @Description Enable SGX clocks -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR EnableSGXClocks(SYS_DATA *psSysData) -+{ -+#if !defined(NO_HARDWARE) -+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; -+ -+ /* SGX clocks already enabled? */ -+ if (atomic_read(&psSysSpecData->sSGXClocksEnabled) != 0) -+ { -+ return PVRSRV_OK; -+ } -+ -+ PVR_DPF((PVR_DBG_MESSAGE, "EnableSGXClocks: Enabling SGX Clocks")); -+ -+#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) -+#if defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK) -+ { -+ struct gpu_platform_data *pdata; -+ IMG_UINT32 max_freq_index; -+ int res; -+ -+ pdata = (struct gpu_platform_data *)gpsPVRLDMDev->dev.platform_data; -+ max_freq_index = psSysSpecData->ui32SGXFreqListSize - 2; -+ -+ /* -+ * Request maximum frequency from DVFS layer if not already set. DVFS may -+ * report busy if early in initialization, but all other errors are -+ * considered serious. Upon any error we proceed assuming our safe frequency -+ * value to be in use as indicated by the "unknown" index. -+ */ -+ if (psSysSpecData->ui32SGXFreqListIndex != max_freq_index) -+ { -+ PVR_ASSERT(pdata->device_scale != IMG_NULL); -+ res = pdata->device_scale(&gpsPVRLDMDev->dev, -+ &gpsPVRLDMDev->dev, -+ psSysSpecData->pui32SGXFreqList[max_freq_index]); -+ if (res == 0) -+ { -+ psSysSpecData->ui32SGXFreqListIndex = max_freq_index; -+ } -+ else if (res == -EBUSY) -+ { -+ PVR_DPF((PVR_DBG_WARNING, "EnableSGXClocks: Unable to scale SGX frequency (EBUSY)")); -+ psSysSpecData->ui32SGXFreqListIndex = psSysSpecData->ui32SGXFreqListSize - 1; -+ } -+ else if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Unable to scale SGX frequency (%d)", res)); -+ psSysSpecData->ui32SGXFreqListIndex = psSysSpecData->ui32SGXFreqListSize - 1; -+ } -+ } -+ } -+#endif /* defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK) */ -+ { -+ /* -+ * pm_runtime_get_sync returns 1 after the module has -+ * been reloaded. -+ */ -+ int res = pm_runtime_get_sync(&gpsPVRLDMDev->dev); -+ if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: pm_runtime_get_sync failed (%d)", -res)); -+ return PVRSRV_ERROR_UNABLE_TO_ENABLE_CLOCK; -+ } -+ } -+#endif /* defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) */ -+ -+ SysEnableSGXInterrupts(psSysData); -+ -+ /* Indicate that the SGX clocks are enabled */ -+ atomic_set(&psSysSpecData->sSGXClocksEnabled, 1); -+ -+#else /* !defined(NO_HARDWARE) */ -+ PVR_UNREFERENCED_PARAMETER(psSysData); -+#endif /* !defined(NO_HARDWARE) */ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function DisableSGXClocks -+ -+ @Description Disable SGX clocks. -+ -+ @Return none -+ -+******************************************************************************/ -+IMG_VOID DisableSGXClocks(SYS_DATA *psSysData) -+{ -+#if !defined(NO_HARDWARE) -+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; -+ -+ /* SGX clocks already disabled? */ -+ if (atomic_read(&psSysSpecData->sSGXClocksEnabled) == 0) -+ { -+ return; -+ } -+ -+ PVR_DPF((PVR_DBG_MESSAGE, "DisableSGXClocks: Disabling SGX Clocks")); -+ -+ SysDisableSGXInterrupts(psSysData); -+ -+#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) -+ { -+ int res = pm_runtime_put_sync(&gpsPVRLDMDev->dev); -+ if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "DisableSGXClocks: pm_runtime_put_sync failed (%d)", -res)); -+ } -+ } -+#if defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK) -+ { -+ struct gpu_platform_data *pdata; -+ int res; -+ -+ pdata = (struct gpu_platform_data *)gpsPVRLDMDev->dev.platform_data; -+ -+ /* -+ * Request minimum frequency (list index 0) from DVFS layer if not already -+ * set. DVFS may report busy if early in initialization, but all other errors -+ * are considered serious. Upon any error we proceed assuming our safe frequency -+ * value to be in use as indicated by the "unknown" index. -+ */ -+ if (psSysSpecData->ui32SGXFreqListIndex != 0) -+ { -+ PVR_ASSERT(pdata->device_scale != IMG_NULL); -+ res = pdata->device_scale(&gpsPVRLDMDev->dev, -+ &gpsPVRLDMDev->dev, -+ psSysSpecData->pui32SGXFreqList[0]); -+ if (res == 0) -+ { -+ psSysSpecData->ui32SGXFreqListIndex = 0; -+ } -+ else if (res == -EBUSY) -+ { -+ PVR_DPF((PVR_DBG_WARNING, "DisableSGXClocks: Unable to scale SGX frequency (EBUSY)")); -+ psSysSpecData->ui32SGXFreqListIndex = psSysSpecData->ui32SGXFreqListSize - 1; -+ } -+ else if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "DisableSGXClocks: Unable to scale SGX frequency (%d)", res)); -+ psSysSpecData->ui32SGXFreqListIndex = psSysSpecData->ui32SGXFreqListSize - 1; -+ } -+ } -+ } -+#endif /* defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK) */ -+#endif /* defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) */ -+ -+ /* Indicate that the SGX clocks are disabled */ -+ atomic_set(&psSysSpecData->sSGXClocksEnabled, 0); -+ -+#else /* !defined(NO_HARDWARE) */ -+ PVR_UNREFERENCED_PARAMETER(psSysData); -+#endif /* !defined(NO_HARDWARE) */ -+} -+ -+#if (defined(DEBUG) || defined(TIMING)) && !defined(PVR_NO_OMAP_TIMER) -+#if defined(PVR_OMAP_USE_DM_TIMER_API) -+#define GPTIMER_TO_USE 11 -+/*! -+****************************************************************************** -+ -+ @Function AcquireGPTimer -+ -+ @Description Acquire a GP timer -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+static PVRSRV_ERROR AcquireGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ PVR_ASSERT(psSysSpecData->psGPTimer == NULL); -+ -+ /* -+ * This code could try requesting registers 9, 10, and 11, -+ * stopping at the first succesful request. We'll stick with -+ * 11 for now, as it avoids having to hard code yet more -+ * physical addresses into the code. -+ */ -+ psSysSpecData->psGPTimer = omap_dm_timer_request_specific(GPTIMER_TO_USE); -+ if (psSysSpecData->psGPTimer == NULL) -+ { -+ -+ PVR_DPF((PVR_DBG_WARNING, "%s: omap_dm_timer_request_specific failed", __FUNCTION__)); -+ return PVRSRV_ERROR_CLOCK_REQUEST_FAILED; -+ } -+ -+ /* Set timer source to system clock */ -+ omap_dm_timer_set_source(psSysSpecData->psGPTimer, OMAP_TIMER_SRC_SYS_CLK); -+ omap_dm_timer_enable(psSysSpecData->psGPTimer); -+ -+ /* Set autoreload, and start value of 0 */ -+ omap_dm_timer_set_load_start(psSysSpecData->psGPTimer, 1, 0); -+ -+ omap_dm_timer_start(psSysSpecData->psGPTimer); -+ -+ /* -+ * The DM timer API doesn't have a mechansim for obtaining the -+ * physical address of the counter register. -+ */ -+ psSysSpecData->sTimerRegPhysBase.uiAddr = SYS_OMAP4430_GP11TIMER_REGS_SYS_PHYS_BASE; -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function ReleaseGPTimer -+ -+ @Description Release a GP timer -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+static void ReleaseGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ if (psSysSpecData->psGPTimer != NULL) -+ { -+ /* Always returns 0 */ -+ (void) omap_dm_timer_stop(psSysSpecData->psGPTimer); -+ -+ omap_dm_timer_disable(psSysSpecData->psGPTimer); -+ -+ omap_dm_timer_free(psSysSpecData->psGPTimer); -+ -+ psSysSpecData->sTimerRegPhysBase.uiAddr = 0; -+ -+ psSysSpecData->psGPTimer = NULL; -+ } -+ -+} -+#else /* PVR_OMAP_USE_DM_TIMER_API */ -+/*! -+****************************************************************************** -+ -+ @Function AcquireGPTimer -+ -+ @Description Acquire a GP timer -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+static PVRSRV_ERROR AcquireGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+#if defined(PVR_OMAP4_TIMING_PRCM) -+ struct clk *psCLK; -+ IMG_INT res; -+ struct clk *sys_ck; -+ IMG_INT rate; -+#endif -+ PVRSRV_ERROR eError; -+ -+ IMG_CPU_PHYADDR sTimerRegPhysBase; -+ IMG_HANDLE hTimerEnable; -+ IMG_UINT32 *pui32TimerEnable; -+ -+ PVR_ASSERT(psSysSpecData->sTimerRegPhysBase.uiAddr == 0); -+ -+#if defined(PVR_OMAP4_TIMING_PRCM) -+ /* assert our dependence on the GPTIMER11 module */ -+ psCLK = clk_get(NULL, "gpt11_fck"); -+ if (IS_ERR(psCLK)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get GPTIMER11 functional clock")); -+ goto ExitError; -+ } -+ psSysSpecData->psGPT11_FCK = psCLK; -+ -+ psCLK = clk_get(NULL, "gpt11_ick"); -+ if (IS_ERR(psCLK)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get GPTIMER11 interface clock")); -+ goto ExitError; -+ } -+ psSysSpecData->psGPT11_ICK = psCLK; -+ -+ sys_ck = clk_get(NULL, "sys_clkin_ck"); -+ if (IS_ERR(sys_ck)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get System clock")); -+ goto ExitError; -+ } -+ -+ if(clk_get_parent(psSysSpecData->psGPT11_FCK) != sys_ck) -+ { -+ PVR_TRACE(("Setting GPTIMER11 parent to System Clock")); -+ res = clk_set_parent(psSysSpecData->psGPT11_FCK, sys_ck); -+ if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't set GPTIMER11 parent clock (%d)", res)); -+ goto ExitError; -+ } -+ } -+ -+ rate = clk_get_rate(psSysSpecData->psGPT11_FCK); -+ PVR_TRACE(("GPTIMER11 clock is %dMHz", HZ_TO_MHZ(rate))); -+ -+ res = clk_enable(psSysSpecData->psGPT11_FCK); -+ if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't enable GPTIMER11 functional clock (%d)", res)); -+ goto ExitError; -+ } -+ -+ res = clk_enable(psSysSpecData->psGPT11_ICK); -+ if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't enable GPTIMER11 interface clock (%d)", res)); -+ goto ExitDisableGPT11FCK; -+ } -+#endif /* defined(PVR_OMAP4_TIMING_PRCM) */ -+ -+ /* Set the timer to non-posted mode */ -+ sTimerRegPhysBase.uiAddr = SYS_OMAP4430_GP11TIMER_TSICR_SYS_PHYS_BASE; -+ pui32TimerEnable = OSMapPhysToLin(sTimerRegPhysBase, -+ 4, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ &hTimerEnable); -+ -+ if (pui32TimerEnable == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: OSMapPhysToLin failed")); -+ goto ExitDisableGPT11ICK; -+ } -+ -+ if(!(*pui32TimerEnable & 4)) -+ { -+ PVR_TRACE(("Setting GPTIMER11 mode to posted (currently is non-posted)")); -+ -+ /* Set posted mode */ -+ *pui32TimerEnable |= 4; -+ } -+ -+ OSUnMapPhysToLin(pui32TimerEnable, -+ 4, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ hTimerEnable); -+ -+ /* Enable the timer */ -+ sTimerRegPhysBase.uiAddr = SYS_OMAP4430_GP11TIMER_ENABLE_SYS_PHYS_BASE; -+ pui32TimerEnable = OSMapPhysToLin(sTimerRegPhysBase, -+ 4, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ &hTimerEnable); -+ -+ if (pui32TimerEnable == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: OSMapPhysToLin failed")); -+ goto ExitDisableGPT11ICK; -+ } -+ -+ /* Enable and set autoreload on overflow */ -+ *pui32TimerEnable = 3; -+ -+ OSUnMapPhysToLin(pui32TimerEnable, -+ 4, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ hTimerEnable); -+ -+ psSysSpecData->sTimerRegPhysBase = sTimerRegPhysBase; -+ -+ eError = PVRSRV_OK; -+ -+ goto Exit; -+ -+ExitDisableGPT11ICK: -+#if defined(PVR_OMAP4_TIMING_PRCM) -+ clk_disable(psSysSpecData->psGPT11_ICK); -+ExitDisableGPT11FCK: -+ clk_disable(psSysSpecData->psGPT11_FCK); -+ExitError: -+#endif /* defined(PVR_OMAP4_TIMING_PRCM) */ -+ eError = PVRSRV_ERROR_CLOCK_REQUEST_FAILED; -+Exit: -+ return eError; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function ReleaseGPTimer -+ -+ @Description Release a GP timer -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+static void ReleaseGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ IMG_HANDLE hTimerDisable; -+ IMG_UINT32 *pui32TimerDisable; -+ -+ if (psSysSpecData->sTimerRegPhysBase.uiAddr == 0) -+ { -+ return; -+ } -+ -+ /* Disable the timer */ -+ pui32TimerDisable = OSMapPhysToLin(psSysSpecData->sTimerRegPhysBase, -+ 4, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ &hTimerDisable); -+ -+ if (pui32TimerDisable == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "DisableSystemClocks: OSMapPhysToLin failed")); -+ } -+ else -+ { -+ *pui32TimerDisable = 0; -+ -+ OSUnMapPhysToLin(pui32TimerDisable, -+ 4, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ hTimerDisable); -+ } -+ -+ psSysSpecData->sTimerRegPhysBase.uiAddr = 0; -+ -+#if defined(PVR_OMAP4_TIMING_PRCM) -+ clk_disable(psSysSpecData->psGPT11_ICK); -+ -+ clk_disable(psSysSpecData->psGPT11_FCK); -+#endif /* defined(PVR_OMAP4_TIMING_PRCM) */ -+} -+#endif /* PVR_OMAP_USE_DM_TIMER_API */ -+#else /* (DEBUG || TIMING) && !PVR_NO_OMAP_TIMER */ -+static PVRSRV_ERROR AcquireGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ PVR_UNREFERENCED_PARAMETER(psSysSpecData); -+ -+ return PVRSRV_OK; -+} -+static void ReleaseGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ PVR_UNREFERENCED_PARAMETER(psSysSpecData); -+} -+#endif /* (DEBUG || TIMING) && !PVR_NO_OMAP_TIMER */ -+ -+/*! -+****************************************************************************** -+ -+ @Function EnableSystemClocks -+ -+ @Description Setup up the clocks for the graphics device to work. -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData) -+{ -+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; -+ -+ PVR_TRACE(("EnableSystemClocks: Enabling System Clocks")); -+ -+ if (!psSysSpecData->bSysClocksOneTimeInit) -+ { -+ mutex_init(&psSysSpecData->sPowerLock); -+ -+ atomic_set(&psSysSpecData->sSGXClocksEnabled, 0); -+ -+ psSysSpecData->bSysClocksOneTimeInit = IMG_TRUE; -+ } -+ -+ return AcquireGPTimer(psSysSpecData); -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function DisableSystemClocks -+ -+ @Description Disable the graphics clocks. -+ -+ @Return none -+ -+******************************************************************************/ -+IMG_VOID DisableSystemClocks(SYS_DATA *psSysData) -+{ -+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; -+ -+ PVR_TRACE(("DisableSystemClocks: Disabling System Clocks")); -+ -+ /* -+ * Always disable the SGX clocks when the system clocks are disabled. -+ * This saves having to make an explicit call to DisableSGXClocks if -+ * active power management is enabled. -+ */ -+ DisableSGXClocks(psSysData); -+ -+ ReleaseGPTimer(psSysSpecData); -+} -+ -+PVRSRV_ERROR SysPMRuntimeRegister(void) -+{ -+#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) -+ pm_runtime_enable(&gpsPVRLDMDev->dev); -+#endif -+ return PVRSRV_OK; -+} -+ -+PVRSRV_ERROR SysPMRuntimeUnregister(void) -+{ -+#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) -+ pm_runtime_disable(&gpsPVRLDMDev->dev); -+#endif -+ return PVRSRV_OK; -+} -+ -+PVRSRV_ERROR SysDvfsInitialize(SYS_SPECIFIC_DATA *psSysSpecificData) -+{ -+#if !defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK) -+ PVR_UNREFERENCED_PARAMETER(psSysSpecificData); -+#else /* !defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK) */ -+ IMG_UINT32 i, *freq_list; -+ IMG_INT32 opp_count; -+ unsigned long freq; -+ struct opp *opp; -+ -+ /* -+ * We query and store the list of SGX frequencies just this once under the -+ * assumption that they are unchanging, e.g. no disabling of high frequency -+ * option for thermal management. This is currently valid for 4430 and 4460. -+ */ -+ rcu_read_lock(); -+ opp_count = opp_get_opp_count(&gpsPVRLDMDev->dev); -+ if (opp_count < 1) -+ { -+ rcu_read_unlock(); -+ PVR_DPF((PVR_DBG_ERROR, "SysDvfsInitialize: Could not retrieve opp count")); -+ return PVRSRV_ERROR_NOT_SUPPORTED; -+ } -+ -+ /* -+ * Allocate the frequency list with a slot for each available frequency plus -+ * one additional slot to hold a designated frequency value to assume when in -+ * an unknown frequency state. -+ */ -+ freq_list = kmalloc((opp_count + 1) * sizeof(IMG_UINT32), GFP_ATOMIC); -+ if (!freq_list) -+ { -+ rcu_read_unlock(); -+ PVR_DPF((PVR_DBG_ERROR, "SysDvfsInitialize: Could not allocate frequency list")); -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ -+ /* -+ * Fill in frequency list from lowest to highest then finally the "unknown" -+ * frequency value. We use the highest available frequency as our assumed value -+ * when in an unknown state, because it is safer for APM and hardware recovery -+ * timers to be longer than intended rather than shorter. -+ */ -+ freq = 0; -+ for (i = 0; i < opp_count; i++) -+ { -+ opp = opp_find_freq_ceil(&gpsPVRLDMDev->dev, &freq); -+ if (IS_ERR_OR_NULL(opp)) -+ { -+ rcu_read_unlock(); -+ PVR_DPF((PVR_DBG_ERROR, "SysDvfsInitialize: Could not retrieve opp level %d", i)); -+ kfree(freq_list); -+ return PVRSRV_ERROR_NOT_SUPPORTED; -+ } -+ freq_list[i] = (IMG_UINT32)freq; -+ freq++; -+ } -+ rcu_read_unlock(); -+ freq_list[opp_count] = freq_list[opp_count - 1]; -+ -+ psSysSpecificData->ui32SGXFreqListSize = opp_count + 1; -+ psSysSpecificData->pui32SGXFreqList = freq_list; -+ -+ /* Start in unknown state - no frequency request to DVFS yet made */ -+ psSysSpecificData->ui32SGXFreqListIndex = opp_count; -+#endif /* !defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK) */ -+ -+ return PVRSRV_OK; -+} -+ -+PVRSRV_ERROR SysDvfsDeinitialize(SYS_SPECIFIC_DATA *psSysSpecificData) -+{ -+#if !defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK) -+ PVR_UNREFERENCED_PARAMETER(psSysSpecificData); -+#else /* !defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK) */ -+ /* -+ * We assume this function is only called if SysDvfsInitialize() was -+ * completed successfully before. -+ * -+ * The DVFS interface does not allow us to actually unregister as a -+ * user of SGX, so we do the next best thing which is to lower our -+ * required frequency to the minimum if not already set. DVFS may -+ * report busy if early in initialization, but all other errors are -+ * considered serious. -+ */ -+ if (psSysSpecificData->ui32SGXFreqListIndex != 0) -+ { -+ struct gpu_platform_data *pdata; -+ IMG_INT32 res; -+ -+ pdata = (struct gpu_platform_data *)gpsPVRLDMDev->dev.platform_data; -+ -+ PVR_ASSERT(pdata->device_scale != IMG_NULL); -+ res = pdata->device_scale(&gpsPVRLDMDev->dev, -+ &gpsPVRLDMDev->dev, -+ psSysSpecificData->pui32SGXFreqList[0]); -+ if (res == -EBUSY) -+ { -+ PVR_DPF((PVR_DBG_WARNING, "SysDvfsDeinitialize: Unable to scale SGX frequency (EBUSY)")); -+ } -+ else if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SysDvfsDeinitialize: Unable to scale SGX frequency (%d)", res)); -+ } -+ -+ psSysSpecificData->ui32SGXFreqListIndex = 0; -+ } -+ -+ kfree(psSysSpecificData->pui32SGXFreqList); -+ psSysSpecificData->pui32SGXFreqList = 0; -+ psSysSpecificData->ui32SGXFreqListSize = 0; -+#endif /* !defined(SYS_OMAP4_HAS_DVFS_FRAMEWORK) */ -+ -+ return PVRSRV_OK; -+} -+ -+#if defined(SUPPORT_DRI_DRM_PLUGIN) -+static struct omap_gpu_plugin sOMAPGPUPlugin; -+ -+#define SYS_DRM_SET_PLUGIN_FIELD(d, s, f) (d)->f = (s)->f -+int -+SysDRMRegisterPlugin(PVRSRV_DRM_PLUGIN *psDRMPlugin) -+{ -+ int iRes; -+ -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, name); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, open); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, load); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, unload); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, release); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, mmap); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, ioctls); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, num_ioctls); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, ioctl_start); -+ -+ iRes = omap_gpu_register_plugin(&sOMAPGPUPlugin); -+ if (iRes != 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: omap_gpu_register_plugin failed (%d)", __FUNCTION__, iRes)); -+ } -+ -+ return iRes; -+} -+ -+void -+SysDRMUnregisterPlugin(PVRSRV_DRM_PLUGIN *psDRMPlugin) -+{ -+ int iRes = omap_gpu_unregister_plugin(&sOMAPGPUPlugin); -+ if (iRes != 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: omap_gpu_unregister_plugin failed (%d)", __FUNCTION__, iRes)); -+ } -+} -+#endif -diff --git a/drivers/staging/ti-es8-sgx/services4/system/ti335x/oemfuncs.h b/drivers/staging/ti-es8-sgx/services4/system/ti335x/oemfuncs.h -new file mode 100644 -index 0000000..77c70d6 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/ti335x/oemfuncs.h -@@ -0,0 +1,78 @@ -+/*************************************************************************/ /*! -+@Title SGX kernel/client driver interface structures and prototypes -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#if !defined(__OEMFUNCS_H__) -+#define __OEMFUNCS_H__ -+ -+#if defined (__cplusplus) -+extern "C" { -+#endif -+ -+/* function in/out data structures: */ -+typedef IMG_UINT32 (*PFN_SRV_BRIDGEDISPATCH)( IMG_UINT32 Ioctl, -+ IMG_BYTE *pInBuf, -+ IMG_UINT32 InBufLen, -+ IMG_BYTE *pOutBuf, -+ IMG_UINT32 OutBufLen, -+ IMG_UINT32 *pdwBytesTransferred); -+/* -+ Function table for kernel 3rd party driver to kernel services -+*/ -+typedef struct PVRSRV_DC_OEM_JTABLE_TAG -+{ -+ PFN_SRV_BRIDGEDISPATCH pfnOEMBridgeDispatch; -+ IMG_PVOID pvDummy1; -+ IMG_PVOID pvDummy2; -+ IMG_PVOID pvDummy3; -+ -+} PVRSRV_DC_OEM_JTABLE; -+ -+#define OEM_GET_EXT_FUNCS (1<<1) -+ -+#if defined(__cplusplus) -+} -+#endif -+ -+#endif /* __OEMFUNCS_H__ */ -+ -+/***************************************************************************** -+ End of file (oemfuncs.h) -+*****************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/system/ti335x/sysconfig.c b/drivers/staging/ti-es8-sgx/services4/system/ti335x/sysconfig.c -new file mode 100644 -index 0000000..a6fd4fa ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/ti335x/sysconfig.c -@@ -0,0 +1,1274 @@ -+/*************************************************************************/ /*! -+@Title System Configuration -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description System Configuration functions -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#include "sysconfig.h" -+#include "services_headers.h" -+#include "kerneldisplay.h" -+#include "oemfuncs.h" -+#include "sgxinfo.h" -+#include "sgxinfokm.h" -+#include "syslocal.h" -+ -+#include "ocpdefs.h" -+ -+/* top level system data anchor point*/ -+SYS_DATA* gpsSysData = (SYS_DATA*)IMG_NULL; -+SYS_DATA gsSysData; -+ -+static SYS_SPECIFIC_DATA gsSysSpecificData; -+SYS_SPECIFIC_DATA *gpsSysSpecificData; -+ -+/* SGX structures */ -+static IMG_UINT32 gui32SGXDeviceID; -+static SGX_DEVICE_MAP gsSGXDeviceMap; -+static PVRSRV_DEVICE_NODE *gpsSGXDevNode; -+ -+ -+#if defined(NO_HARDWARE) || defined(SGX_OCP_REGS_ENABLED) -+static IMG_CPU_VIRTADDR gsSGXRegsCPUVAddr; -+#endif -+ -+#if defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO) -+extern struct platform_device *gpsPVRLDMDev; -+#endif -+ -+IMG_UINT32 PVRSRV_BridgeDispatchKM(IMG_UINT32 Ioctl, -+ IMG_BYTE *pInBuf, -+ IMG_UINT32 InBufLen, -+ IMG_BYTE *pOutBuf, -+ IMG_UINT32 OutBufLen, -+ IMG_UINT32 *pdwBytesTransferred); -+ -+#if defined(SGX_OCP_REGS_ENABLED) -+ -+static IMG_CPU_VIRTADDR gpvOCPRegsLinAddr; -+ -+static PVRSRV_ERROR EnableSGXClocksWrap(SYS_DATA *psSysData) -+{ -+ PVRSRV_ERROR eError = EnableSGXClocks(psSysData); -+ -+#if !defined(SGX_OCP_NO_INT_BYPASS) -+ if(eError == PVRSRV_OK) -+ { -+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_SYSCONFIG, 0x14); -+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_DEBUG_CONFIG, EUR_CR_OCP_DEBUG_CONFIG_THALIA_INT_BYPASS_MASK); -+ } -+#endif -+ return eError; -+} -+ -+#else /* defined(SGX_OCP_REGS_ENABLED) */ -+ -+static INLINE PVRSRV_ERROR EnableSGXClocksWrap(SYS_DATA *psSysData) -+{ -+ return EnableSGXClocks(psSysData); -+} -+ -+#endif /* defined(SGX_OCP_REGS_ENABLED) */ -+ -+static INLINE PVRSRV_ERROR EnableSystemClocksWrap(SYS_DATA *psSysData) -+{ -+ PVRSRV_ERROR eError = EnableSystemClocks(psSysData); -+ -+#if !defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ if(eError == PVRSRV_OK) -+ { -+ /* -+ * The SGX Clocks are enabled separately if active power -+ * management is enabled. -+ */ -+ eError = EnableSGXClocksWrap(psSysData); -+ if (eError != PVRSRV_OK) -+ { -+ DisableSystemClocks(psSysData); -+ } -+ } -+#endif -+ -+ return eError; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function SysLocateDevices -+ -+ @Description Specifies devices in the systems memory map -+ -+ @Input psSysData - sys data -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+static PVRSRV_ERROR SysLocateDevices(SYS_DATA *psSysData) -+{ -+#if defined(NO_HARDWARE) -+ PVRSRV_ERROR eError; -+ IMG_CPU_PHYADDR sCpuPAddr; -+#else -+#if defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO) -+ struct resource *dev_res; -+ int dev_irq; -+#endif -+#endif -+ -+ PVR_UNREFERENCED_PARAMETER(psSysData); -+ -+ /* SGX Device: */ -+ gsSGXDeviceMap.ui32Flags = 0x0; -+ -+#if defined(NO_HARDWARE) -+ /* -+ * For no hardware, allocate some contiguous memory for the -+ * register block. -+ */ -+ -+ /* Registers */ -+ gsSGXDeviceMap.ui32RegsSize = SYS_TI335x_SGX_REGS_SIZE; -+ -+ eError = OSBaseAllocContigMemory(gsSGXDeviceMap.ui32RegsSize, -+ &gsSGXRegsCPUVAddr, -+ &sCpuPAddr); -+ if(eError != PVRSRV_OK) -+ { -+ return eError; -+ } -+ gsSGXDeviceMap.sRegsCpuPBase = sCpuPAddr; -+ gsSGXDeviceMap.sRegsSysPBase = SysCpuPAddrToSysPAddr(gsSGXDeviceMap.sRegsCpuPBase); -+#if defined(__linux__) -+ /* Indicate the registers are already mapped */ -+ gsSGXDeviceMap.pvRegsCpuVBase = gsSGXRegsCPUVAddr; -+#else -+ /* -+ * FIXME: Could we just use the virtual address returned by -+ * OSBaseAllocContigMemory? -+ */ -+ gsSGXDeviceMap.pvRegsCpuVBase = IMG_NULL; -+#endif -+ -+ OSMemSet(gsSGXRegsCPUVAddr, 0, gsSGXDeviceMap.ui32RegsSize); -+ -+ /* -+ device interrupt IRQ -+ Note: no interrupts available on no hardware system -+ */ -+ gsSGXDeviceMap.ui32IRQ = 0; -+ -+#else /* defined(NO_HARDWARE) */ -+#if defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO) -+ /* get the resource and IRQ through platform resource API */ -+ dev_res = platform_get_resource(gpsPVRLDMDev, IORESOURCE_MEM, 0); -+ if (dev_res == NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: platform_get_resource failed", __FUNCTION__)); -+ return PVRSRV_ERROR_INVALID_DEVICE; -+ } -+ -+ dev_irq = platform_get_irq(gpsPVRLDMDev, 0); -+ if (dev_irq < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: platform_get_irq failed (%d)", __FUNCTION__, -dev_irq)); -+ return PVRSRV_ERROR_INVALID_DEVICE; -+ } -+ -+ gsSGXDeviceMap.sRegsSysPBase.uiAddr = dev_res->start; -+ gsSGXDeviceMap.sRegsCpuPBase = -+ SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sRegsSysPBase); -+ PVR_TRACE(("SGX register base: 0x%lx", (unsigned long)gsSGXDeviceMap.sRegsCpuPBase.uiAddr)); -+ -+#if defined(SGX544) && defined(SGX_FEATURE_MP) -+ /* FIXME: Workaround due to HWMOD change. Otherwise this region is too small. */ -+ gsSGXDeviceMap.ui32RegsSize = SYS_TI335x_SGX_REGS_SIZE; -+#else -+ gsSGXDeviceMap.ui32RegsSize = (unsigned int)(dev_res->end - dev_res->start); -+#endif -+ PVR_TRACE(("SGX register size: %d",gsSGXDeviceMap.ui32RegsSize)); -+ -+ gsSGXDeviceMap.ui32IRQ = dev_irq; -+ PVR_TRACE(("SGX IRQ: %d", gsSGXDeviceMap.ui32IRQ)); -+#else /* defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO) */ -+ gsSGXDeviceMap.sRegsSysPBase.uiAddr = SYS_TI335x_SGX_REGS_SYS_PHYS_BASE; -+ gsSGXDeviceMap.sRegsCpuPBase = SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sRegsSysPBase); -+ gsSGXDeviceMap.ui32RegsSize = SYS_TI335x_SGX_REGS_SIZE; -+ -+ gsSGXDeviceMap.ui32IRQ = SYS_TI335x_SGX_IRQ; -+ -+#endif /* defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO) */ -+#if defined(SGX_OCP_REGS_ENABLED) -+ gsSGXRegsCPUVAddr = OSMapPhysToLin(gsSGXDeviceMap.sRegsCpuPBase, -+ gsSGXDeviceMap.ui32RegsSize, -+ PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY, -+ IMG_NULL); -+ -+ if (gsSGXRegsCPUVAddr == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysLocateDevices: Failed to map SGX registers")); -+ return PVRSRV_ERROR_BAD_MAPPING; -+ } -+ -+ /* Indicate the registers are already mapped */ -+ gsSGXDeviceMap.pvRegsCpuVBase = gsSGXRegsCPUVAddr; -+ gpvOCPRegsLinAddr = gsSGXRegsCPUVAddr; -+#endif -+#endif /* defined(NO_HARDWARE) */ -+ -+#if defined(PDUMP) -+ { -+ /* initialise memory region name for pdumping */ -+ static IMG_CHAR pszPDumpDevName[] = "SGXMEM"; -+ gsSGXDeviceMap.pszPDumpDevName = pszPDumpDevName; -+ } -+#endif -+ -+ /* add other devices here: */ -+ -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysCreateVersionString -+ -+ @Description Read the version string -+ -+ @Return IMG_CHAR * : Version string -+ -+******************************************************************************/ -+static IMG_CHAR *SysCreateVersionString(void) -+{ -+ static IMG_CHAR aszVersionString[100]; -+ IMG_UINT32 ui32MaxStrLen; -+ SYS_DATA *psSysData; -+ IMG_UINT32 ui32SGXRevision; -+ IMG_INT32 i32Count; -+ -+ SysAcquireData(&psSysData); -+ -+ ui32SGXRevision = SGX_CORE_REV; -+ ui32MaxStrLen = 99; -+ -+ i32Count = OSSNPrintf(aszVersionString, ui32MaxStrLen + 1, -+ "SGX revision = %u", -+ (IMG_UINT)(ui32SGXRevision)); -+ if(i32Count == -1) -+ { -+ return IMG_NULL; -+ } -+ -+ return aszVersionString; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysInitialise -+ -+ @Description Initialises kernel services at 'driver load' time -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+PVRSRV_ERROR SysInitialise(IMG_VOID) -+{ -+ IMG_UINT32 i; -+ PVRSRV_ERROR eError; -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+#if !defined(PVR_NO_OMAP_TIMER) -+ IMG_CPU_PHYADDR TimerRegPhysBase; -+#endif -+#if !defined(SGX_DYNAMIC_TIMING_INFO) -+ SGX_TIMING_INFORMATION* psTimingInfo; -+#endif -+ gpsSysData = &gsSysData; -+ OSMemSet(gpsSysData, 0, sizeof(SYS_DATA)); -+ -+ gpsSysSpecificData = &gsSysSpecificData; -+ OSMemSet(gpsSysSpecificData, 0, sizeof(SYS_SPECIFIC_DATA)); -+ -+ gpsSysData->pvSysSpecificData = gpsSysSpecificData; -+ -+ eError = OSInitEnvData(&gpsSysData->pvEnvSpecificData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to setup env structure")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_ENVDATA); -+ -+ gpsSysData->ui32NumDevices = SYS_DEVICE_COUNT; -+ -+ /* init device ID's */ -+ for(i=0; i<SYS_DEVICE_COUNT; i++) -+ { -+ gpsSysData->sDeviceID[i].uiID = i; -+ gpsSysData->sDeviceID[i].bInUse = IMG_FALSE; -+ } -+ -+ gpsSysData->psDeviceNodeList = IMG_NULL; -+ gpsSysData->psQueueList = IMG_NULL; -+ -+ eError = SysInitialiseCommon(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed in SysInitialiseCommon")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ -+#if !defined(SGX_DYNAMIC_TIMING_INFO) -+ /* Set up timing information*/ -+ psTimingInfo = &gsSGXDeviceMap.sTimingInfo; -+ psTimingInfo->ui32CoreClockSpeed = SYS_SGX_CLOCK_SPEED; -+ psTimingInfo->ui32HWRecoveryFreq = SYS_SGX_HWRECOVERY_TIMEOUT_FREQ; -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ psTimingInfo->bEnableActivePM = IMG_TRUE; -+#else -+ psTimingInfo->bEnableActivePM = IMG_FALSE; -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ psTimingInfo->ui32ActivePowManLatencyms = SYS_SGX_ACTIVE_POWER_LATENCY_MS; -+ psTimingInfo->ui32uKernelFreq = SYS_SGX_PDS_TIMER_FREQ; -+#endif -+ -+ /* -+ Setup the Source Clock Divider value -+ */ -+ gpsSysSpecificData->ui32SrcClockDiv = 3; -+ -+ /* -+ Locate the devices within the system, specifying -+ the physical addresses of each devices components -+ (regs, mem, ports etc.) -+ */ -+ eError = SysLocateDevices(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to locate devices")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV); -+ -+ eError = SysPMRuntimeRegister(); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to register with OSPM!")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_PM_RUNTIME); -+ -+ eError = SysDvfsInitialize(gpsSysSpecificData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to initialize DVFS")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_DVFS_INIT); -+ -+ /* -+ Register devices with the system -+ This also sets up their memory maps/heaps -+ */ -+ eError = PVRSRVRegisterDevice(gpsSysData, SGXRegisterDevice, -+ DEVICE_SGX_INTERRUPT, &gui32SGXDeviceID); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to register device!")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_REGDEV); -+ -+ /* -+ Once all devices are registered, specify the backing store -+ and, if required, customise the memory heap config -+ */ -+ psDeviceNode = gpsSysData->psDeviceNodeList; -+ while(psDeviceNode) -+ { -+ /* perform any OEM SOC address space customisations here */ -+ switch(psDeviceNode->sDevId.eDeviceType) -+ { -+ case PVRSRV_DEVICE_TYPE_SGX: -+ { -+ DEVICE_MEMORY_INFO *psDevMemoryInfo; -+ DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; -+ -+ /* -+ specify the backing store to use for the devices MMU PT/PDs -+ - the PT/PDs are always UMA in this system -+ */ -+ psDeviceNode->psLocalDevMemArena = IMG_NULL; -+ -+ /* useful pointers */ -+ psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo; -+ psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap; -+ -+ /* specify the backing store for all SGX heaps */ -+ for(i=0; i<psDevMemoryInfo->ui32HeapCount; i++) -+ { -+ psDeviceMemoryHeap[i].ui32Attribs |= PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG; -+ } -+ -+ gpsSGXDevNode = psDeviceNode; -+ gsSysSpecificData.psSGXDevNode = psDeviceNode; -+ -+ break; -+ } -+ default: -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to find SGX device node!")); -+ return PVRSRV_ERROR_INIT_FAILURE; -+ } -+ -+ /* advance to next device */ -+ psDeviceNode = psDeviceNode->psNext; -+ } -+ -+ eError = EnableSystemClocksWrap(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable system clocks (%d)", eError)); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS); -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ eError = EnableSGXClocksWrap(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable SGX clocks (%d)", eError)); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ -+ eError = PVRSRVInitialiseDevice(gui32SGXDeviceID); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to initialise device!")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_INITDEV); -+ -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ /* SGX defaults to D3 power state */ -+ DisableSGXClocks(gpsSysData); -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ -+#if !defined(PVR_NO_OMAP_TIMER) -+#if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA) -+ TimerRegPhysBase = gsSysSpecificData.sTimerRegPhysBase; -+#else -+ TimerRegPhysBase.uiAddr = SYS_TI335x_GP7TIMER_REGS_SYS_PHYS_BASE; -+#endif -+ gpsSysData->pvSOCTimerRegisterKM = IMG_NULL; -+ gpsSysData->hSOCTimerRegisterOSMemHandle = 0; -+ if (TimerRegPhysBase.uiAddr != 0) -+ { -+ OSReservePhys(TimerRegPhysBase, -+ 4, -+ PVRSRV_HAP_MULTI_PROCESS|PVRSRV_HAP_UNCACHED, -+ IMG_NULL, -+ (IMG_VOID **)&gpsSysData->pvSOCTimerRegisterKM, -+ &gpsSysData->hSOCTimerRegisterOSMemHandle); -+ } -+#endif /* !defined(PVR_NO_OMAP_TIMER) */ -+ -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysFinalise -+ -+ @Description Final part of initialisation at 'driver load' time -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+PVRSRV_ERROR SysFinalise(IMG_VOID) -+{ -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ eError = EnableSGXClocksWrap(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to Enable SGX clocks (%d)", eError)); -+ return eError; -+ } -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ -+ eError = OSInstallMISR(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to install MISR")); -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_MISR); -+ -+#if defined(SYS_USING_INTERRUPTS) -+ /* install a Device ISR */ -+ eError = OSInstallDeviceLISR(gpsSysData, gsSGXDeviceMap.ui32IRQ, "SGX ISR", gpsSGXDevNode); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to install ISR")); -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR); -+#if !defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ SysEnableSGXInterrupts(gpsSysData); -+#endif -+#endif /* defined(SYS_USING_INTERRUPTS) */ -+#if defined(__linux__) -+ /* Create a human readable version string for this system */ -+ gpsSysData->pszVersionString = SysCreateVersionString(); -+ if (!gpsSysData->pszVersionString) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to create a system version string")); -+ } -+ else -+ { -+ PVR_TRACE(("SysFinalise: Version string: %s", gpsSysData->pszVersionString)); -+ } -+#endif -+ -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ /* SGX defaults to D3 power state */ -+ DisableSGXClocks(gpsSysData); -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ -+ gpsSysSpecificData->bSGXInitComplete = IMG_TRUE; -+ -+ return eError; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysDeinitialise -+ -+ @Description De-initialises kernel services at 'driver unload' time -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR SysDeinitialise (SYS_DATA *psSysData) -+{ -+ PVRSRV_ERROR eError; -+ -+ PVR_UNREFERENCED_PARAMETER(psSysData); -+ -+ if(gpsSysData->pvSOCTimerRegisterKM) -+ { -+ OSUnReservePhys(gpsSysData->pvSOCTimerRegisterKM, -+ 4, -+ PVRSRV_HAP_MULTI_PROCESS|PVRSRV_HAP_UNCACHED, -+ gpsSysData->hSOCTimerRegisterOSMemHandle); -+ } -+ -+ -+#if defined(SYS_USING_INTERRUPTS) -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR)) -+ { -+ eError = OSUninstallDeviceLISR(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: OSUninstallDeviceLISR failed")); -+ return eError; -+ } -+ } -+#endif -+ -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_MISR)) -+ { -+ eError = OSUninstallMISR(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: OSUninstallMISR failed")); -+ return eError; -+ } -+ } -+ -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_INITDEV)) -+ { -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ PVR_ASSERT(SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS)); -+ /* Reenable SGX clocks whilst SGX is being deinitialised. */ -+ eError = EnableSGXClocksWrap(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: EnableSGXClocks failed")); -+ return eError; -+ } -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ -+ /* Deinitialise SGX */ -+ eError = PVRSRVDeinitialiseDevice(gui32SGXDeviceID); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: failed to de-init the device")); -+ return eError; -+ } -+ } -+ -+ /* Disable system clocks. Must happen after last access to hardware */ -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS)) -+ { -+ DisableSystemClocks(gpsSysData); -+ } -+ -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_DVFS_INIT)) -+ { -+ eError = SysDvfsDeinitialize(gpsSysSpecificData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: Failed to de-init DVFS")); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ } -+ -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_PM_RUNTIME)) -+ { -+ eError = SysPMRuntimeUnregister(); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: Failed to unregister with OSPM!")); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ } -+ -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_ENVDATA)) -+ { -+ eError = OSDeInitEnvData(gpsSysData->pvEnvSpecificData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: failed to de-init env structure")); -+ return eError; -+ } -+ } -+ -+ SysDeinitialiseCommon(gpsSysData); -+ -+#if defined(NO_HARDWARE) || defined(SGX_OCP_REGS_ENABLED) -+ if(gsSGXRegsCPUVAddr != IMG_NULL) -+ { -+#if defined(NO_HARDWARE) -+ /* Free hardware resources. */ -+ OSBaseFreeContigMemory(SYS_TI335x_SGX_REGS_SIZE, gsSGXRegsCPUVAddr, gsSGXDeviceMap.sRegsCpuPBase); -+#else -+#if defined(SGX_OCP_REGS_ENABLED) -+ OSUnMapPhysToLin(gsSGXRegsCPUVAddr, -+ gsSGXDeviceMap.ui32RegsSize, -+ PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY, -+ IMG_NULL); -+ -+ gpvOCPRegsLinAddr = IMG_NULL; -+#endif -+#endif /* defined(NO_HARDWARE) */ -+ gsSGXRegsCPUVAddr = IMG_NULL; -+ gsSGXDeviceMap.pvRegsCpuVBase = gsSGXRegsCPUVAddr; -+ } -+#endif /* defined(NO_HARDWARE) || defined(SGX_OCP_REGS_ENABLED) */ -+ -+ -+ gpsSysSpecificData->ui32SysSpecificData = 0; -+ gpsSysSpecificData->bSGXInitComplete = IMG_FALSE; -+ -+ gpsSysData = IMG_NULL; -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysGetDeviceMemoryMap -+ -+ @Description returns a device address map for the specified device -+ -+ @Input eDeviceType - device type -+ @Input ppvDeviceMap - void ptr to receive device specific info. -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE eDeviceType, -+ IMG_VOID **ppvDeviceMap) -+{ -+ -+ switch(eDeviceType) -+ { -+ case PVRSRV_DEVICE_TYPE_SGX: -+ { -+ /* just return a pointer to the structure */ -+ *ppvDeviceMap = (IMG_VOID*)&gsSGXDeviceMap; -+ -+ break; -+ } -+ default: -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysGetDeviceMemoryMap: unsupported device type")); -+ } -+ } -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function SysCpuPAddrToDevPAddr -+ -+ @Description Compute a device physical address from a cpu physical -+ address. Relevant when -+ -+ @Input cpu_paddr - cpu physical address. -+ @Input eDeviceType - device type required if DevPAddr -+ address spaces vary across devices -+ in the same system -+ @Return device physical address. -+ -+******************************************************************************/ -+IMG_DEV_PHYADDR SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType, -+ IMG_CPU_PHYADDR CpuPAddr) -+{ -+ IMG_DEV_PHYADDR DevPAddr; -+ -+ PVR_UNREFERENCED_PARAMETER(eDeviceType); -+ -+ /* Note: for UMA system we assume DevP == CpuP */ -+ DevPAddr.uiAddr = CpuPAddr.uiAddr; -+ -+ return DevPAddr; -+} -+ -+/*! -+****************************************************************************** -+ @Function SysSysPAddrToCpuPAddr -+ -+ @Description Compute a cpu physical address from a system physical -+ address. -+ -+ @Input sys_paddr - system physical address. -+ @Return cpu physical address. -+ -+******************************************************************************/ -+IMG_CPU_PHYADDR SysSysPAddrToCpuPAddr (IMG_SYS_PHYADDR sys_paddr) -+{ -+ IMG_CPU_PHYADDR cpu_paddr; -+ -+ /* This would only be an inequality if the CPU's MMU did not point to -+ sys address 0, ie. multi CPU system */ -+ cpu_paddr.uiAddr = sys_paddr.uiAddr; -+ return cpu_paddr; -+} -+ -+/*! -+****************************************************************************** -+ @Function SysCpuPAddrToSysPAddr -+ -+ @Description Compute a system physical address from a cpu physical -+ address. -+ -+ @Input cpu_paddr - cpu physical address. -+ @Return device physical address. -+ -+******************************************************************************/ -+IMG_SYS_PHYADDR SysCpuPAddrToSysPAddr (IMG_CPU_PHYADDR cpu_paddr) -+{ -+ IMG_SYS_PHYADDR sys_paddr; -+ -+ /* This would only be an inequality if the CPU's MMU did not point to -+ sys address 0, ie. multi CPU system */ -+ sys_paddr.uiAddr = cpu_paddr.uiAddr; -+ return sys_paddr; -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function SysSysPAddrToDevPAddr -+ -+ @Description Compute a device physical address from a system physical -+ address. -+ -+ @Input SysPAddr - system physical address. -+ @Input eDeviceType - device type required if DevPAddr -+ address spaces vary across devices -+ in the same system -+ -+ @Return Device physical address. -+ -+******************************************************************************/ -+IMG_DEV_PHYADDR SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType, IMG_SYS_PHYADDR SysPAddr) -+{ -+ IMG_DEV_PHYADDR DevPAddr; -+ -+ PVR_UNREFERENCED_PARAMETER(eDeviceType); -+ -+ /* Note: for UMA system we assume DevP == CpuP */ -+ DevPAddr.uiAddr = SysPAddr.uiAddr; -+ -+ return DevPAddr; -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function SysDevPAddrToSysPAddr -+ -+ @Description Compute a device physical address from a system physical -+ address. -+ -+ @Input DevPAddr - device physical address. -+ @Input eDeviceType - device type required if DevPAddr -+ address spaces vary across devices -+ in the same system -+ -+ @Return System physical address. -+ -+******************************************************************************/ -+IMG_SYS_PHYADDR SysDevPAddrToSysPAddr(PVRSRV_DEVICE_TYPE eDeviceType, IMG_DEV_PHYADDR DevPAddr) -+{ -+ IMG_SYS_PHYADDR SysPAddr; -+ -+ PVR_UNREFERENCED_PARAMETER(eDeviceType); -+ -+ /* Note: for UMA system we assume DevP == SysP */ -+ SysPAddr.uiAddr = DevPAddr.uiAddr; -+ -+ return SysPAddr; -+} -+ -+ -+/***************************************************************************** -+ @Function SysRegisterExternalDevice -+ -+ @Description Called when a 3rd party device registers with services -+ -+ @Input psDeviceNode - the new device node. -+ -+ @Return IMG_VOID -+*****************************************************************************/ -+IMG_VOID SysRegisterExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode) -+{ -+ PVR_UNREFERENCED_PARAMETER(psDeviceNode); -+} -+ -+ -+/***************************************************************************** -+ @Function SysRemoveExternalDevice -+ -+ @Description Called when a 3rd party device unregisters from services -+ -+ @Input psDeviceNode - the device node being removed. -+ -+ @Return IMG_VOID -+*****************************************************************************/ -+IMG_VOID SysRemoveExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode) -+{ -+ PVR_UNREFERENCED_PARAMETER(psDeviceNode); -+} -+ -+/*! -+****************************************************************************** -+ @Function SysGetInterruptSource -+ -+ @Description Returns System specific information about the device(s) that -+ generated the interrupt in the system -+ -+ @Input psSysData -+ @Input psDeviceNode -+ -+ @Return System specific information indicating which device(s) -+ generated the interrupt -+ -+******************************************************************************/ -+IMG_UINT32 SysGetInterruptSource(SYS_DATA *psSysData, -+ PVRSRV_DEVICE_NODE *psDeviceNode) -+{ -+ PVR_UNREFERENCED_PARAMETER(psSysData); -+#if defined(NO_HARDWARE) -+ /* no interrupts in no_hw system just return all bits */ -+ return 0xFFFFFFFF; -+#else -+ /* Not a shared irq, so we know this is an interrupt for this device */ -+ return psDeviceNode->ui32SOCInterruptBit; -+#endif -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function SysClearInterrupts -+ -+ @Description Clears specified system interrupts -+ -+ @Input psSysData -+ @Input ui32ClearBits -+ -+ @Return IMG_VOID -+ -+******************************************************************************/ -+IMG_VOID SysClearInterrupts(SYS_DATA* psSysData, IMG_UINT32 ui32ClearBits) -+{ -+ PVR_UNREFERENCED_PARAMETER(ui32ClearBits); -+ PVR_UNREFERENCED_PARAMETER(psSysData); -+#if !defined(NO_HARDWARE) -+#if defined(SGX_OCP_NO_INT_BYPASS) -+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_IRQSTATUS_2, 0x1); -+#endif -+ /* Flush posted writes */ -+ OSReadHWReg(((PVRSRV_SGXDEV_INFO *)gpsSGXDevNode->pvDevice)->pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR); -+#endif /* defined(NO_HARDWARE) */ -+} -+ -+#if defined(SGX_OCP_NO_INT_BYPASS) -+/*! -+****************************************************************************** -+ @Function SysEnableSGXInterrupts -+ -+ @Description Enables SGX interrupts -+ -+ @Input psSysData -+ -+ @Return IMG_VOID -+ -+******************************************************************************/ -+IMG_VOID SysEnableSGXInterrupts(SYS_DATA *psSysData) -+{ -+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *)psSysData->pvSysSpecificData; -+ if (SYS_SPECIFIC_DATA_TEST(psSysSpecData, SYS_SPECIFIC_DATA_ENABLE_LISR) && !SYS_SPECIFIC_DATA_TEST(psSysSpecData, SYS_SPECIFIC_DATA_IRQ_ENABLED)) -+ { -+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_IRQSTATUS_2, 0x1); -+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_IRQENABLE_SET_2, 0x1); -+ SYS_SPECIFIC_DATA_SET(psSysSpecData, SYS_SPECIFIC_DATA_IRQ_ENABLED); -+ } -+} -+ -+/*! -+****************************************************************************** -+ @Function SysDisableSGXInterrupts -+ -+ @Description Disables SGX interrupts -+ -+ @Input psSysData -+ -+ @Return IMG_VOID -+ -+******************************************************************************/ -+IMG_VOID SysDisableSGXInterrupts(SYS_DATA *psSysData) -+{ -+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *)psSysData->pvSysSpecificData; -+ -+ if (SYS_SPECIFIC_DATA_TEST(psSysSpecData, SYS_SPECIFIC_DATA_IRQ_ENABLED)) -+ { -+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_IRQENABLE_CLR_2, 0x1); -+ SYS_SPECIFIC_DATA_CLEAR(psSysSpecData, SYS_SPECIFIC_DATA_IRQ_ENABLED); -+ } -+} -+#endif /* defined(SGX_OCP_NO_INT_BYPASS) */ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysSystemPrePowerState -+ -+ @Description Perform system-level processing required before a power transition -+ -+ @Input eNewPowerState : -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR SysSystemPrePowerState(PVRSRV_SYS_POWER_STATE eNewPowerState) -+{ -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ -+ if (eNewPowerState == PVRSRV_SYS_POWER_STATE_D3) -+ { -+ PVR_TRACE(("SysSystemPrePowerState: Entering state D3")); -+ -+#if defined(SYS_USING_INTERRUPTS) -+ if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR)) -+ { -+#if defined(SYS_CUSTOM_POWERLOCK_WRAP) -+ IMG_BOOL bWrapped = WrapSystemPowerChange(&gsSysSpecificData); -+#endif -+ eError = OSUninstallDeviceLISR(gpsSysData); -+#if defined(SYS_CUSTOM_POWERLOCK_WRAP) -+ if (bWrapped) -+ { -+ UnwrapSystemPowerChange(&gsSysSpecificData); -+ } -+#endif -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysSystemPrePowerState: OSUninstallDeviceLISR failed (%d)", eError)); -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR); -+ SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR); -+ } -+#endif -+ -+ if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS)) -+ { -+ DisableSystemClocks(gpsSysData); -+ -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS); -+ SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS); -+ } -+ } -+ -+ return eError; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysSystemPostPowerState -+ -+ @Description Perform system-level processing required after a power transition -+ -+ @Input eNewPowerState : -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR SysSystemPostPowerState(PVRSRV_SYS_POWER_STATE eNewPowerState) -+{ -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ -+ if (eNewPowerState == PVRSRV_SYS_POWER_STATE_D0) -+ { -+ PVR_TRACE(("SysSystemPostPowerState: Entering state D0")); -+ -+ if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS)) -+ { -+ eError = EnableSystemClocksWrap(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysSystemPostPowerState: EnableSystemClocksWrap failed (%d)", eError)); -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS); -+ SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS); -+ } -+ -+#if defined(SYS_USING_INTERRUPTS) -+ if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR)) -+ { -+#if defined(SYS_CUSTOM_POWERLOCK_WRAP) -+ IMG_BOOL bWrapped = WrapSystemPowerChange(&gsSysSpecificData); -+#endif -+ -+ eError = OSInstallDeviceLISR(gpsSysData, gsSGXDeviceMap.ui32IRQ, "SGX ISR", gpsSGXDevNode); -+#if defined(SYS_CUSTOM_POWERLOCK_WRAP) -+ if (bWrapped) -+ { -+ UnwrapSystemPowerChange(&gsSysSpecificData); -+ } -+#endif -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysSystemPostPowerState: OSInstallDeviceLISR failed to install ISR (%d)", eError)); -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR); -+ SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR); -+ } -+#endif -+ } -+ return eError; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysDevicePrePowerState -+ -+ @Description Perform system level processing required before a device power -+ transition -+ -+ @Input ui32DeviceIndex : -+ @Input eNewPowerState : -+ @Input eCurrentPowerState : -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR SysDevicePrePowerState(IMG_UINT32 ui32DeviceIndex, -+ PVRSRV_DEV_POWER_STATE eNewPowerState, -+ PVRSRV_DEV_POWER_STATE eCurrentPowerState) -+{ -+ PVR_UNREFERENCED_PARAMETER(eCurrentPowerState); -+ -+ if (ui32DeviceIndex != gui32SGXDeviceID) -+ { -+ return PVRSRV_OK; -+ } -+ -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ if (eNewPowerState == PVRSRV_DEV_POWER_STATE_OFF) -+ { -+ PVR_DPF((PVR_DBG_MESSAGE, "SysDevicePrePowerState: SGX Entering state D3")); -+ DisableSGXClocks(gpsSysData); -+ } -+#else /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ PVR_UNREFERENCED_PARAMETER(eNewPowerState ); -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysDevicePostPowerState -+ -+ @Description Perform system level processing required after a device power -+ transition -+ -+ @Input ui32DeviceIndex : -+ @Input eNewPowerState : -+ @Input eCurrentPowerState : -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR SysDevicePostPowerState(IMG_UINT32 ui32DeviceIndex, -+ PVRSRV_DEV_POWER_STATE eNewPowerState, -+ PVRSRV_DEV_POWER_STATE eCurrentPowerState) -+{ -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ -+ PVR_UNREFERENCED_PARAMETER(eNewPowerState); -+ -+ if (ui32DeviceIndex != gui32SGXDeviceID) -+ { -+ return eError; -+ } -+ -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ if (eCurrentPowerState == PVRSRV_DEV_POWER_STATE_OFF) -+ { -+ PVR_DPF((PVR_DBG_MESSAGE, "SysDevicePostPowerState: SGX Leaving state D3")); -+ eError = EnableSGXClocksWrap(gpsSysData); -+ } -+#else /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ PVR_UNREFERENCED_PARAMETER(eCurrentPowerState); -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ -+ return eError; -+} -+ -+#if defined(SYS_SUPPORTS_SGX_IDLE_CALLBACK) -+ -+IMG_VOID SysSGXIdleTransition(IMG_BOOL bSGXIdle) -+{ -+ PVR_DPF((PVR_DBG_MESSAGE, "SysSGXIdleTransition switch to %u", bSGXIdle)); -+} -+ -+#endif /* defined(SYS_SUPPORTS_SGX_IDLE_CALLBACK) */ -+ -+/***************************************************************************** -+ @Function SysOEMFunction -+ -+ @Description marshalling function for custom OEM functions -+ -+ @Input ui32ID - function ID -+ @Input pvIn - in data -+ @Output pvOut - out data -+ -+ @Return PVRSRV_ERROR -+*****************************************************************************/ -+PVRSRV_ERROR SysOEMFunction ( IMG_UINT32 ui32ID, -+ IMG_VOID *pvIn, -+ IMG_UINT32 ulInSize, -+ IMG_VOID *pvOut, -+ IMG_UINT32 ulOutSize) -+{ -+ PVR_UNREFERENCED_PARAMETER(ui32ID); -+ PVR_UNREFERENCED_PARAMETER(pvIn); -+ PVR_UNREFERENCED_PARAMETER(ulInSize); -+ PVR_UNREFERENCED_PARAMETER(pvOut); -+ PVR_UNREFERENCED_PARAMETER(ulOutSize); -+ -+ if ((ui32ID == OEM_GET_EXT_FUNCS) && -+ (ulOutSize == sizeof(PVRSRV_DC_OEM_JTABLE))) -+ { -+ PVRSRV_DC_OEM_JTABLE *psOEMJTable = (PVRSRV_DC_OEM_JTABLE*) pvOut; -+ psOEMJTable->pfnOEMBridgeDispatch = &PVRSRV_BridgeDispatchKM; -+ return PVRSRV_OK; -+ } -+ -+ return PVRSRV_ERROR_INVALID_PARAMS; -+} -+/****************************************************************************** -+ End of file (sysconfig.c) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/system/ti335x/sysconfig.h b/drivers/staging/ti-es8-sgx/services4/system/ti335x/sysconfig.h -new file mode 100644 -index 0000000..c47228b ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/ti335x/sysconfig.h -@@ -0,0 +1,109 @@ -+/*************************************************************************/ /*! -+@Title System Description Header -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description This header provides system-specific declarations and macros -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#if !defined(__SOCCONFIG_H__) -+#define __SOCCONFIG_H__ -+ -+#define VS_PRODUCT_NAME "TI335x" -+ -+ -+#define SYS_SGX_HWRECOVERY_TIMEOUT_FREQ (100) // 10ms (100hz) -+#define SYS_SGX_PDS_TIMER_FREQ (1000) // 1ms (1000hz) -+ -+/* Allow the AP latency to be overridden in the build config */ -+#if !defined(SYS_SGX_ACTIVE_POWER_LATENCY_MS) -+#define SYS_SGX_ACTIVE_POWER_LATENCY_MS (2) -+#endif -+ -+ -+#define SYS_TI335x_SGX_REGS_SYS_PHYS_BASE 0x56000000 -+#define SYS_TI335x_SGX_REGS_SIZE 0x1000000 -+ -+#define SYS_TI335x_SGX_IRQ 37 /* OMAP4 IRQ's are offset by 32 */ -+ -+#define SYS_OMAP_DSS_REGS_SYS_PHYS_BASE 0x58000000 -+#define SYS_OMAP_DSS_REGS_SIZE 0x7000 -+ -+#define SYS_OMAP_DSS_HDMI_INTERRUPT_STATUS_REG 0x6028 -+#define SYS_OMAP_DSS_HDMI_INTERRUPT_ENABLE_REG 0x602c -+ -+#define SYS_OMAP_DSS_HDMI_INTERRUPT_VSYNC_ENABLE_MASK 0x10000 -+#define SYS_OMAP_DSS_HDMI_INTERRUPT_VSYNC_STATUS_MASK 0x10000 -+ -+#define SYS_OMAP_DSS_LCD_INTERRUPT_STATUS_REG 0x1018 -+#define SYS_OMAP_DSS_LCD_INTERRUPT_ENABLE_REG 0x101c -+ -+#define SYS_OMAP_DSS_LCD_INTERRUPT_VSYNC_ENABLE_MASK 0x40002 -+#define SYS_OMAP_DSS_LCD_INTERRUPT_VSYNC_STATUS_MASK 0x40002 -+ -+ -+#define SYS_TI335x_GP7TIMER_ENABLE_SYS_PHYS_BASE 0x4804A038 -+#define SYS_TI335x_GP7TIMER_REGS_SYS_PHYS_BASE 0x4804A03C -+#define SYS_TI335x_GP7TIMER_TSICR_SYS_PHYS_BASE 0x4804A054 -+ -+ -+ -+/* Interrupt bits */ -+#define DEVICE_SGX_INTERRUPT (1<<0) -+#define DEVICE_MSVDX_INTERRUPT (1<<1) -+#define DEVICE_DISP_INTERRUPT (1<<2) -+ -+#if 0 -+#if defined(__linux__) -+/* -+ * Recent OMAP4 kernels register SGX as platform device "omap_gpu". -+ * This device must be used with the Linux power management calls -+ * in sysutils_linux.c, in order for SGX to be powered on. -+ */ -+#if defined(PVR_LDM_PLATFORM_PRE_REGISTERED_DEV) -+#define SYS_SGX_DEV_NAME PVR_LDM_PLATFORM_PRE_REGISTERED_DEV -+#else -+#define SYS_SGX_DEV_NAME "omap_gpu" -+#endif /* defined(PVR_LDM_PLATFORM_PRE_REGISTERED_DEV) */ -+#endif /* defined(__linux__) */ -+#endif -+ -+/***************************************************************************** -+ * system specific data structures -+ *****************************************************************************/ -+ -+#endif /* __SYSCONFIG_H__ */ -diff --git a/drivers/staging/ti-es8-sgx/services4/system/ti335x/sysinfo.h b/drivers/staging/ti-es8-sgx/services4/system/ti335x/sysinfo.h -new file mode 100644 -index 0000000..7383b9c ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/ti335x/sysinfo.h -@@ -0,0 +1,70 @@ -+/*************************************************************************/ /*! -+@Title System Description Header -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description This header provides system-specific declarations and macros -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#if !defined(__SYSINFO_H__) -+#define __SYSINFO_H__ -+ -+#if defined(SGX540) && (SGX_CORE_REV == 120) -+#define SYS_SGX_CLOCK_SPEED 307200000 -+#else -+#define SYS_SGX_CLOCK_SPEED 200000000 -+#endif -+ -+/*!< System specific poll/timeout details */ -+#if defined(PVR_LINUX_USING_WORKQUEUES) -+/* -+ * The workqueue based 3rd party display driver may be blocked for up -+ * to 500ms waiting for a vsync when the screen goes blank, so we -+ * need to wait longer for the hardware if a flush of the swap chain is -+ * required. -+ */ -+#define MAX_HW_TIME_US (1000000) -+#define WAIT_TRY_COUNT (20000) -+#else -+#define MAX_HW_TIME_US (500000) -+#define WAIT_TRY_COUNT (10000) -+#endif -+ -+ -+#define SYS_DEVICE_COUNT 15 /* SGX, DISPLAYCLASS (external), BUFFERCLASS (external) */ -+ -+#endif /* __SYSINFO_H__ */ -diff --git a/drivers/staging/ti-es8-sgx/services4/system/ti335x/syslocal.h b/drivers/staging/ti-es8-sgx/services4/system/ti335x/syslocal.h -new file mode 100644 -index 0000000..8dd7239 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/ti335x/syslocal.h -@@ -0,0 +1,264 @@ -+/*************************************************************************/ /*! -+@Title Local system definitions -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description This header provides local system declarations and macros -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#if !defined(__SYSLOCAL_H__) -+#define __SYSLOCAL_H__ -+ -+#if defined(__linux__) -+ -+#include <linux/version.h> -+#include <linux/clk.h> -+#if defined(PVR_LINUX_USING_WORKQUEUES) -+#include <linux/mutex.h> -+#else -+#include <linux/spinlock.h> -+#endif -+#include <asm/atomic.h> -+ -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)) -+#include <linux/semaphore.h> -+#include <linux/resource.h> -+#else /* (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)) */ -+#include <asm/semaphore.h> -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22)) -+#include <asm/arch/resource.h> -+#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22)) */ -+#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)) */ -+ -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)) -+#if !defined(LDM_PLATFORM) -+#error "LDM_PLATFORM must be set" -+#endif -+#define PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO -+#include <linux/platform_device.h> -+#endif -+ -+#if ((defined(DEBUG) || defined(TIMING)) && \ -+ (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32))) && \ -+ !defined(PVR_NO_OMAP_TIMER) -+/* -+ * We need to explicitly enable the GPTIMER11 clocks, or we'll get an -+ * abort when we try to access the timer registers. -+ */ -+#define PVR_OMAP4_TIMING_PRCM -+#endif -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) -+//#include <plat/gpu.h> -+#if !defined(PVR_NO_OMAP_TIMER) -+//#define PVR_OMAP_USE_DM_TIMER_API -+//#include <plat/dmtimer.h> -+#endif -+#endif -+ -+#if !defined(PVR_NO_OMAP_TIMER) -+//#define PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA -+#endif -+#endif /* defined(__linux__) */ -+ -+#if !defined(NO_HARDWARE) && \ -+ defined(SYS_USING_INTERRUPTS) && \ -+ defined(SGX540) -+#define SGX_OCP_REGS_ENABLED -+#endif -+ -+#if defined(__linux__) -+#if defined(SGX_OCP_REGS_ENABLED) -+/* FIXME: Temporary workaround for OMAP4470 and active power off in 4430 */ -+#if !defined(SGX544) && defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+//#define SGX_OCP_NO_INT_BYPASS -+#endif -+#endif -+#endif -+ -+#if defined (__cplusplus) -+extern "C" { -+#endif -+ -+/***************************************************************************** -+ * system specific data structures -+ *****************************************************************************/ -+ -+/***************************************************************************** -+ * system specific function prototypes -+ *****************************************************************************/ -+ -+IMG_VOID DisableSystemClocks(SYS_DATA *psSysData); -+PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData); -+ -+IMG_VOID DisableSGXClocks(SYS_DATA *psSysData); -+PVRSRV_ERROR EnableSGXClocks(SYS_DATA *psSysData); -+ -+/* -+ * Various flags to indicate what has been initialised, and what -+ * has been temporarily deinitialised for power management purposes. -+ */ -+#define SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS 0x00000001 -+#define SYS_SPECIFIC_DATA_ENABLE_LISR 0x00000002 -+#define SYS_SPECIFIC_DATA_ENABLE_MISR 0x00000004 -+#define SYS_SPECIFIC_DATA_ENABLE_ENVDATA 0x00000008 -+#define SYS_SPECIFIC_DATA_ENABLE_LOCDEV 0x00000010 -+#define SYS_SPECIFIC_DATA_ENABLE_REGDEV 0x00000020 -+#define SYS_SPECIFIC_DATA_ENABLE_PDUMPINIT 0x00000040 -+#define SYS_SPECIFIC_DATA_ENABLE_INITDEV 0x00000080 -+#define SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV 0x00000100 -+ -+#define SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR 0x00000200 -+#define SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS 0x00000400 -+#define SYS_SPECIFIC_DATA_ENABLE_OCPREGS 0x00000800 -+#define SYS_SPECIFIC_DATA_ENABLE_PM_RUNTIME 0x00001000 -+#define SYS_SPECIFIC_DATA_IRQ_ENABLED 0x00002000 -+#define SYS_SPECIFIC_DATA_DVFS_INIT 0x00004000 -+ -+#define SYS_SPECIFIC_DATA_SET(psSysSpecData, flag) ((IMG_VOID)((psSysSpecData)->ui32SysSpecificData |= (flag))) -+ -+#define SYS_SPECIFIC_DATA_CLEAR(psSysSpecData, flag) ((IMG_VOID)((psSysSpecData)->ui32SysSpecificData &= ~(flag))) -+ -+#define SYS_SPECIFIC_DATA_TEST(psSysSpecData, flag) (((psSysSpecData)->ui32SysSpecificData & (flag)) != 0) -+ -+typedef struct _SYS_SPECIFIC_DATA_TAG_ -+{ -+ IMG_UINT32 ui32SysSpecificData; -+ PVRSRV_DEVICE_NODE *psSGXDevNode; -+ IMG_BOOL bSGXInitComplete; -+#if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA) -+ IMG_CPU_PHYADDR sTimerRegPhysBase; -+#endif -+#if !defined(__linux__) -+ IMG_BOOL bSGXClocksEnabled; -+#endif -+ IMG_UINT32 ui32SrcClockDiv; -+#if defined(__linux__) -+ IMG_BOOL bSysClocksOneTimeInit; -+ atomic_t sSGXClocksEnabled; -+#if defined(PVR_LINUX_USING_WORKQUEUES) -+ struct mutex sPowerLock; -+#else -+ IMG_BOOL bConstraintNotificationsEnabled; -+ spinlock_t sPowerLock; -+ atomic_t sPowerLockCPU; -+ spinlock_t sNotifyLock; -+ atomic_t sNotifyLockCPU; -+ IMG_BOOL bCallVDD2PostFunc; -+#endif -+ struct clk *psCORE_CK; -+ struct clk *psSGX_FCK; -+ struct clk *psSGX_ICK; -+ -+#if defined(DEBUG) || defined(TIMING) -+ struct clk *psGPT11_FCK; -+ struct clk *psGPT11_ICK; -+#endif -+#if defined(PVR_OMAP_USE_DM_TIMER_API) -+ struct omap_dm_timer *psGPTimer; -+#endif -+ IMG_UINT32 ui32SGXFreqListSize; -+ IMG_UINT32 *pui32SGXFreqList; -+ IMG_UINT32 ui32SGXFreqListIndex; -+#endif /* defined(__linux__) */ -+} SYS_SPECIFIC_DATA; -+ -+extern SYS_SPECIFIC_DATA *gpsSysSpecificData; -+ -+#if defined(SGX_OCP_REGS_ENABLED) && defined(SGX_OCP_NO_INT_BYPASS) -+IMG_VOID SysEnableSGXInterrupts(SYS_DATA* psSysData); -+IMG_VOID SysDisableSGXInterrupts(SYS_DATA* psSysData); -+#else -+#define SysEnableSGXInterrupts(psSysData) -+#define SysDisableSGXInterrupts(psSysData) -+#endif -+ -+#if defined(SYS_CUSTOM_POWERLOCK_WRAP) -+IMG_BOOL WrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData); -+IMG_VOID UnwrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData); -+#endif -+ -+#if defined(__linux__) -+ -+PVRSRV_ERROR SysPMRuntimeRegister(void); -+PVRSRV_ERROR SysPMRuntimeUnregister(void); -+ -+PVRSRV_ERROR SysDvfsInitialize(SYS_SPECIFIC_DATA *psSysSpecificData); -+PVRSRV_ERROR SysDvfsDeinitialize(SYS_SPECIFIC_DATA *psSysSpecificData); -+ -+#else /* defined(__linux__) */ -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(SysPMRuntimeRegister) -+#endif -+static INLINE PVRSRV_ERROR SysPMRuntimeRegister(void) -+{ -+ return PVRSRV_OK; -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(SysPMRuntimeUnregister) -+#endif -+static INLINE PVRSRV_ERROR SysPMRuntimeUnregister(void) -+{ -+ return PVRSRV_OK; -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(SysDvfsInitialize) -+#endif -+static INLINE PVRSRV_ERROR SysDvfsInitialize(void) -+{ -+ return PVRSRV_OK; -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(SysDvfsDeinitialize) -+#endif -+static INLINE PVRSRV_ERROR SysDvfsDeinitialize(void) -+{ -+ return PVRSRV_OK; -+} -+ -+#endif /* defined(__linux__) */ -+ -+#if defined(__cplusplus) -+} -+#endif -+ -+#endif /* __SYSLOCAL_H__ */ -diff --git a/drivers/staging/ti-es8-sgx/services4/system/ti335x/sysutils.c b/drivers/staging/ti-es8-sgx/services4/system/ti335x/sysutils.c -new file mode 100644 -index 0000000..6725421 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/ti335x/sysutils.c -@@ -0,0 +1,47 @@ -+/*************************************************************************/ /*! -+@Title Shared (User/kernel) and System dependent utilities -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Provides system-specific functions -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+/* Pull in the correct system dependent sysutils source */ -+ -+#if defined(__linux__) -+#include "sysutils_linux.c" -+#endif -diff --git a/drivers/staging/ti-es8-sgx/services4/system/ti335x/sysutils_linux.c b/drivers/staging/ti-es8-sgx/services4/system/ti335x/sysutils_linux.c -new file mode 100644 -index 0000000..f9a04db ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/ti335x/sysutils_linux.c -@@ -0,0 +1,963 @@ -+/*************************************************************************/ /*! -+@Title System dependent utilities -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Provides system-specific functions -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+#include <linux/version.h> -+#include <linux/clk.h> -+#include <linux/err.h> -+#include <linux/hardirq.h> -+#include <linux/mutex.h> -+#include <linux/slab.h> -+ -+#include "sgxdefs.h" -+#include "services_headers.h" -+#include "sysinfo.h" -+#include "sgxapi_km.h" -+#include "sysconfig.h" -+#include "sgxinfokm.h" -+#include "syslocal.h" -+ -+#include <linux/platform_device.h> -+#include <linux/pm_runtime.h> -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)) -+#include <linux/reset.h> -+#endif -+ -+#if defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) -+#include <linux/opp.h> -+#endif -+ -+#if defined(SUPPORT_DRI_DRM_PLUGIN) -+#include <drm/drmP.h> -+#include <drm/drm.h> -+ -+#include <linux/omap_gpu.h> -+ -+#include "pvr_drm.h" -+#endif -+ -+#define ONE_MHZ 1000000 -+#define HZ_TO_MHZ(m) ((m) / ONE_MHZ) -+ -+#if defined(SUPPORT_OMAP3430_SGXFCLK_96M) -+#define SGX_PARENT_CLOCK "cm_96m_fck" -+#else -+#define SGX_PARENT_CLOCK "core_ck" -+#endif -+ -+#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) -+extern struct platform_device *gpsPVRLDMDev; -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)) -+extern struct reset_control *rstc; -+extern bool already_deasserted; -+#endif -+#endif -+ -+ -+static PVRSRV_ERROR PowerLockWrap(SYS_SPECIFIC_DATA *psSysSpecData, IMG_BOOL bTryLock) -+{ -+ if (!in_interrupt()) -+ { -+ if (bTryLock) -+ { -+ int locked = mutex_trylock(&psSysSpecData->sPowerLock); -+ if (locked == 0) -+ { -+ return PVRSRV_ERROR_RETRY; -+ } -+ } -+ else -+ { -+ mutex_lock(&psSysSpecData->sPowerLock); -+ } -+ } -+ -+ return PVRSRV_OK; -+} -+ -+static IMG_VOID PowerLockUnwrap(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ if (!in_interrupt()) -+ { -+ mutex_unlock(&psSysSpecData->sPowerLock); -+ } -+} -+ -+PVRSRV_ERROR SysPowerLockWrap(IMG_BOOL bTryLock) -+{ -+ SYS_DATA *psSysData; -+ -+ SysAcquireData(&psSysData); -+ -+ return PowerLockWrap(psSysData->pvSysSpecificData, bTryLock); -+} -+ -+IMG_VOID SysPowerLockUnwrap(IMG_VOID) -+{ -+ SYS_DATA *psSysData; -+ -+ SysAcquireData(&psSysData); -+ -+ PowerLockUnwrap(psSysData->pvSysSpecificData); -+} -+ -+/* -+ * This function should be called to unwrap the Services power lock, prior -+ * to calling any function that might sleep. -+ * This function shouldn't be called prior to calling EnableSystemClocks -+ * or DisableSystemClocks, as those functions perform their own power lock -+ * unwrapping. -+ * If the function returns IMG_TRUE, UnwrapSystemPowerChange must be -+ * called to rewrap the power lock, prior to returning to Services. -+ */ -+IMG_BOOL WrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ return IMG_TRUE; -+} -+ -+IMG_VOID UnwrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+} -+ -+/* -+ * Return SGX timining information to caller. -+ */ -+IMG_VOID SysGetSGXTimingInformation(SGX_TIMING_INFORMATION *psTimingInfo) -+{ -+#if !defined(NO_HARDWARE) -+ PVR_ASSERT(atomic_read(&gpsSysSpecificData->sSGXClocksEnabled) != 0); -+#endif -+#if defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) -+ psTimingInfo->ui32CoreClockSpeed = -+ gpsSysSpecificData->pui32SGXFreqList[gpsSysSpecificData->ui32SGXFreqListIndex]; -+#else /* defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) */ -+ psTimingInfo->ui32CoreClockSpeed = SYS_SGX_CLOCK_SPEED; -+#endif -+ psTimingInfo->ui32HWRecoveryFreq = SYS_SGX_HWRECOVERY_TIMEOUT_FREQ; -+ psTimingInfo->ui32uKernelFreq = SYS_SGX_PDS_TIMER_FREQ; -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ psTimingInfo->bEnableActivePM = IMG_TRUE; -+#else -+ psTimingInfo->bEnableActivePM = IMG_FALSE; -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ psTimingInfo->ui32ActivePowManLatencyms = SYS_SGX_ACTIVE_POWER_LATENCY_MS; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function EnableSGXClocks -+ -+ @Description Enable SGX clocks -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR EnableSGXClocks(SYS_DATA *psSysData) -+{ -+#if !defined(NO_HARDWARE) -+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; -+#if !defined(PM_RUNTIME_SUPPORT) -+ IMG_INT res; -+ long lRate,lNewRate; -+#endif -+ int ret; -+ /* SGX clocks already enabled? */ -+ if (atomic_read(&psSysSpecData->sSGXClocksEnabled) != 0) -+ { -+ return PVRSRV_OK; -+ } -+ -+ PVR_DPF((PVR_DBG_MESSAGE, "EnableSGXClocks: Enabling SGX Clocks")); -+#if !defined(PM_RUNTIME_SUPPORT) -+ PVR_DPF((PVR_DBG_MESSAGE, "EnableSGXClocks: Enabling SGX Clocks")); -+ res=clk_enable(psSysSpecData->psSGX_FCK); -+ if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Couldn't enable SGX functional clock (%d)", res)); -+ return PVRSRV_ERROR_UNABLE_TO_ENABLE_CLOCK; -+ } -+ -+ lNewRate = clk_round_rate(psSysSpecData->psSGX_FCK, SYS_SGX_CLOCK_SPEED + ONE_MHZ); -+ if (lNewRate <= 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Couldn't round SGX functional clock rate")); -+ return PVRSRV_ERROR_UNABLE_TO_ROUND_CLOCK_RATE; -+ } -+ -+ -+ lRate = clk_get_rate(psSysSpecData->psSGX_FCK); -+ if (lRate != lNewRate) -+ { -+ res = clk_set_rate(psSysSpecData->psSGX_FCK, lNewRate); -+ if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_WARNING, "EnableSGXClocks: Couldn't set SGX functional clock rate (%d)", res)); -+ return PVRSRV_ERROR_UNABLE_TO_SET_CLOCK_RATE; -+ } -+ } -+ -+#if defined(DEBUG) -+ { -+ IMG_UINT32 rate = clk_get_rate(psSysSpecData->psSGX_FCK); -+ PVR_DPF((PVR_DBG_MESSAGE, "EnableSGXClocks: SGX Functional Clock is %dMhz", HZ_TO_MHZ(rate))); -+ } -+#endif -+#endif -+#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) -+#if defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) -+ { -+ struct gpu_platform_data *pdata; -+ IMG_UINT32 max_freq_index; -+ int res; -+ -+ pdata = (struct gpu_platform_data *)gpsPVRLDMDev->dev.platform_data; -+ max_freq_index = psSysSpecData->ui32SGXFreqListSize - 2; -+ -+ /* -+ * Request maximum frequency from DVFS layer if not already set. DVFS may -+ * report busy if early in initialization, but all other errors are -+ * considered serious. Upon any error we proceed assuming our safe frequency -+ * value to be in use as indicated by the "unknown" index. -+ */ -+ if (psSysSpecData->ui32SGXFreqListIndex != max_freq_index) -+ { -+ PVR_ASSERT(pdata->device_scale != IMG_NULL); -+ res = pdata->device_scale(&gpsPVRLDMDev->dev, -+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3,4,0)) -+ &gpsPVRLDMDev->dev, -+#endif -+ psSysSpecData->pui32SGXFreqList[max_freq_index]); -+ if (res == 0) -+ { -+ psSysSpecData->ui32SGXFreqListIndex = max_freq_index; -+ } -+ else if (res == -EBUSY) -+ { -+ PVR_DPF((PVR_DBG_WARNING, "EnableSGXClocks: Unable to scale SGX frequency (EBUSY)")); -+ psSysSpecData->ui32SGXFreqListIndex = psSysSpecData->ui32SGXFreqListSize - 1; -+ } -+ else if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Unable to scale SGX frequency (%d)", res)); -+ psSysSpecData->ui32SGXFreqListIndex = psSysSpecData->ui32SGXFreqListSize - 1; -+ } -+ } -+ } -+#endif /* defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) */ -+ { -+ /* -+ * pm_runtime_get_sync returns 1 after the module has -+ * been reloaded. -+ */ -+#if defined(PM_RUNTIME_SUPPORT) -+ -+ int res = pm_runtime_get_sync(&gpsPVRLDMDev->dev); -+ if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: pm_runtime_get_sync failed (%d)", -res)); -+ return PVRSRV_ERROR_UNABLE_TO_ENABLE_CLOCK; -+ } -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)) -+ if (!already_deasserted) -+ { -+ ret = reset_control_is_reset(rstc); -+ if (ret <= 0) -+ { -+ PVR_DPF((PVR_DBG_MESSAGE, "reset control reset")); -+ } -+ } -+ reset_control_put(rstc); -+#endif -+ -+#endif -+ } -+#endif /* defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) */ -+ -+ SysEnableSGXInterrupts(psSysData); -+ -+ /* Indicate that the SGX clocks are enabled */ -+ atomic_set(&psSysSpecData->sSGXClocksEnabled, 1); -+ -+#else /* !defined(NO_HARDWARE) */ -+ PVR_UNREFERENCED_PARAMETER(psSysData); -+#endif /* !defined(NO_HARDWARE) */ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function DisableSGXClocks -+ -+ @Description Disable SGX clocks. -+ -+ @Return none -+ -+******************************************************************************/ -+IMG_VOID DisableSGXClocks(SYS_DATA *psSysData) -+{ -+#if !defined(NO_HARDWARE) -+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; -+ -+ /* SGX clocks already disabled? */ -+ if (atomic_read(&psSysSpecData->sSGXClocksEnabled) == 0) -+ { -+ return; -+ } -+ -+ PVR_DPF((PVR_DBG_MESSAGE, "DisableSGXClocks: Disabling SGX Clocks")); -+#if !defined(PM_RUNTIME_SUPPORT) -+ clk_disable(psSysSpecData->psSGX_FCK); -+#endif -+ SysDisableSGXInterrupts(psSysData); -+ -+#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) -+ { -+#if defined(PM_RUNTIME_SUPPORT) -+ -+ int res = pm_runtime_put_sync(&gpsPVRLDMDev->dev); -+ if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "DisableSGXClocks: pm_runtime_put_sync failed (%d)", -res)); -+ } -+#endif -+ } -+#if defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) -+ { -+ struct gpu_platform_data *pdata; -+ int res; -+ -+ pdata = (struct gpu_platform_data *)gpsPVRLDMDev->dev.platform_data; -+ -+ /* -+ * Request minimum frequency (list index 0) from DVFS layer if not already -+ * set. DVFS may report busy if early in initialization, but all other errors -+ * are considered serious. Upon any error we proceed assuming our safe frequency -+ * value to be in use as indicated by the "unknown" index. -+ */ -+ if (psSysSpecData->ui32SGXFreqListIndex != 0) -+ { -+ PVR_ASSERT(pdata->device_scale != IMG_NULL); -+ res = pdata->device_scale(&gpsPVRLDMDev->dev, -+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3,4,0)) -+ &gpsPVRLDMDev->dev, -+#endif -+ psSysSpecData->pui32SGXFreqList[0]); -+ if (res == 0) -+ { -+ psSysSpecData->ui32SGXFreqListIndex = 0; -+ } -+ else if (res == -EBUSY) -+ { -+ PVR_DPF((PVR_DBG_WARNING, "DisableSGXClocks: Unable to scale SGX frequency (EBUSY)")); -+ psSysSpecData->ui32SGXFreqListIndex = psSysSpecData->ui32SGXFreqListSize - 1; -+ } -+ else if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "DisableSGXClocks: Unable to scale SGX frequency (%d)", res)); -+ psSysSpecData->ui32SGXFreqListIndex = psSysSpecData->ui32SGXFreqListSize - 1; -+ } -+ } -+ } -+#endif /* defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) */ -+#endif /* defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) */ -+ -+ /* Indicate that the SGX clocks are disabled */ -+ atomic_set(&psSysSpecData->sSGXClocksEnabled, 0); -+ -+#else /* !defined(NO_HARDWARE) */ -+ PVR_UNREFERENCED_PARAMETER(psSysData); -+#endif /* !defined(NO_HARDWARE) */ -+} -+ -+#if (defined(DEBUG) || defined(TIMING)) && !defined(PVR_NO_OMAP_TIMER) -+#if defined(PVR_OMAP_USE_DM_TIMER_API) -+#define GPTIMER_TO_USE 11 -+/*! -+****************************************************************************** -+ -+ @Function AcquireGPTimer -+ -+ @Description Acquire a GP timer -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+static PVRSRV_ERROR AcquireGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ PVR_ASSERT(psSysSpecData->psGPTimer == NULL); -+ -+ /* -+ * This code has problems on module reload for OMAP5 running Linux -+ * 3.4.10, due to omap2_dm_timer_set_src (called by -+ * omap_dm_timer_request_specific), being unable to set the parent -+ * clock to OMAP_TIMER_SRC_32_KHZ. -+ * Not calling omap_dm_timer_set_source doesn't help. -+ */ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) || !defined(MODULE) -+ /* -+ * This code could try requesting registers 9, 10, and 11, -+ * stopping at the first succesful request. We'll stick with -+ * 11 for now, as it avoids having to hard code yet more -+ * physical addresses into the code. -+ */ -+ psSysSpecData->psGPTimer = omap_dm_timer_request_specific(GPTIMER_TO_USE); -+ if (psSysSpecData->psGPTimer == NULL) -+ { -+ -+ PVR_DPF((PVR_DBG_WARNING, "%s: omap_dm_timer_request_specific failed", __FUNCTION__)); -+ return PVRSRV_ERROR_CLOCK_REQUEST_FAILED; -+ } -+ -+ omap_dm_timer_set_source(psSysSpecData->psGPTimer, OMAP_TIMER_SRC_SYS_CLK); -+ omap_dm_timer_enable(psSysSpecData->psGPTimer); -+ -+ /* Set autoreload, and start value of 0 */ -+ omap_dm_timer_set_load_start(psSysSpecData->psGPTimer, 1, 0); -+ -+ omap_dm_timer_start(psSysSpecData->psGPTimer); -+ -+ /* -+ * The DM timer API doesn't have a mechanism for obtaining the -+ * physical address of the counter register. -+ */ -+ psSysSpecData->sTimerRegPhysBase.uiAddr = SYS_TI335x_GP7TIMER_REGS_SYS_PHYS_BASE; -+#else /* (LINUX_VERSION_CODE <= KERNEL_VERSION(3,4,0)) || !defined(MODULE) */ -+ (void)psSysSpecData; -+#endif /* (LINUX_VERSION_CODE <= KERNEL_VERSION(3,4,0)) || !defined(MODULE) */ -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function ReleaseGPTimer -+ -+ @Description Release a GP timer -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+static void ReleaseGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ if (psSysSpecData->psGPTimer != NULL) -+ { -+ /* Always returns 0 */ -+ (void) omap_dm_timer_stop(psSysSpecData->psGPTimer); -+ -+ omap_dm_timer_disable(psSysSpecData->psGPTimer); -+ -+ omap_dm_timer_free(psSysSpecData->psGPTimer); -+#if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA) -+ psSysSpecData->sTimerRegPhysBase.uiAddr = 0; -+#endif -+ -+ psSysSpecData->psGPTimer = NULL; -+ } -+ -+} -+#else /* PVR_OMAP_USE_DM_TIMER_API */ -+ -+/*! -+****************************************************************************** -+ -+ @Function AcquireGPTimer -+ -+ @Description Acquire a GP timer -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+static PVRSRV_ERROR AcquireGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+#if defined(PVR_OMAP4_TIMING_PRCM) -+ struct clk *psCLK; -+ IMG_INT res; -+ struct clk *sys_ck; -+ IMG_INT rate; -+#endif -+ PVRSRV_ERROR eError; -+ IMG_CPU_PHYADDR sTimerRegPhysBase; -+ IMG_HANDLE hTimerEnable; -+ IMG_UINT32 *pui32TimerEnable; -+#if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA) -+ PVR_ASSERT(psSysSpecData->sTimerRegPhysBase.uiAddr == 0); -+#endif -+ -+#if defined(PVR_OMAP4_TIMING_PRCM) -+ /* assert our dependence on the GPTIMER11 module */ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)) -+ psCLK = clk_get(NULL, "timer7_fck"); -+#else -+ psCLK = clk_get(NULL, "gpt7_fck"); -+#endif -+ if (IS_ERR(psCLK)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get GPTIMER11 functional clock")); -+ goto ExitError; -+ } -+ psSysSpecData->psGPT11_FCK = psCLK; -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) -+ psCLK = clk_get(NULL, "gpt7_ick"); -+ if (IS_ERR(psCLK)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get GPTIMER11 interface clock")); -+ goto ExitError; -+ } -+ psSysSpecData->psGPT11_ICK = psCLK; -+#endif -+#if 0 -+ sys_ck = clk_get(NULL, "sys_clkin_ck"); -+ if (IS_ERR(sys_ck)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get System clock")); -+ goto ExitError; -+ } -+ -+ if(clk_get_parent(psSysSpecData->psGPT11_FCK) != sys_ck) -+ { -+ PVR_TRACE(("Setting GPTIMER11 parent to System Clock")); -+ res = clk_set_parent(psSysSpecData->psGPT11_FCK, sys_ck); -+ if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't set GPTIMER11 parent clock (%d)", res)); -+ goto ExitError; -+ } -+ } -+#endif -+ rate = clk_get_rate(psSysSpecData->psGPT11_FCK); -+ PVR_TRACE(("GPTIMER11 clock is %dMHz", HZ_TO_MHZ(rate))); -+ -+ res = clk_enable(psSysSpecData->psGPT11_FCK); -+ if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't enable GPTIMER11 functional clock (%d)", res)); -+ goto ExitError; -+ } -+ -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) -+ res = clk_enable(psSysSpecData->psGPT11_ICK); -+ if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't enable GPTIMER11 interface clock (%d)", res)); -+ goto ExitDisableGPT11FCK; -+ } -+#endif -+#endif /* defined(PVR_OMAP4_TIMING_PRCM) */ -+ -+ /* Set the timer to non-posted mode */ -+ sTimerRegPhysBase.uiAddr = SYS_TI335x_GP7TIMER_TSICR_SYS_PHYS_BASE; -+ pui32TimerEnable = OSMapPhysToLin(sTimerRegPhysBase, -+ 4, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ &hTimerEnable); -+ -+ if (pui32TimerEnable == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: OSMapPhysToLin failed")); -+ goto ExitDisableGPT11ICK; -+ } -+ -+ if(!(*pui32TimerEnable & 4)) -+ { -+ PVR_TRACE(("Setting GPTIMER11 mode to posted (currently is non-posted)")); -+ -+ /* Set posted mode */ -+ *pui32TimerEnable |= 4; -+ } -+ -+ OSUnMapPhysToLin(pui32TimerEnable, -+ 4, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ hTimerEnable); -+ -+ /* Enable the timer */ -+ sTimerRegPhysBase.uiAddr = SYS_TI335x_GP7TIMER_ENABLE_SYS_PHYS_BASE; -+ pui32TimerEnable = OSMapPhysToLin(sTimerRegPhysBase, -+ 4, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ &hTimerEnable); -+ -+ if (pui32TimerEnable == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: OSMapPhysToLin failed")); -+ goto ExitDisableGPT11ICK; -+ } -+ -+ /* Enable and set autoreload on overflow */ -+ *pui32TimerEnable = 3; -+ -+ OSUnMapPhysToLin(pui32TimerEnable, -+ 4, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ hTimerEnable); -+#if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA) -+ psSysSpecData->sTimerRegPhysBase = sTimerRegPhysBase; -+#endif -+ eError = PVRSRV_OK; -+ -+ goto Exit; -+ -+ExitDisableGPT11ICK: -+#if defined(PVR_OMAP4_TIMING_PRCM) -+ clk_disable(psSysSpecData->psGPT11_ICK); -+ExitDisableGPT11FCK: -+ clk_disable(psSysSpecData->psGPT11_FCK); -+ExitError: -+#endif /* defined(PVR_OMAP4_TIMING_PRCM) */ -+ eError = PVRSRV_ERROR_CLOCK_REQUEST_FAILED; -+Exit: -+ return eError; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function ReleaseGPTimer -+ -+ @Description Release a GP timer -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+static void ReleaseGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ IMG_HANDLE hTimerDisable; -+ IMG_UINT32 *pui32TimerDisable; -+ IMG_CPU_PHYADDR TimerRegPhysBase; -+#if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA) -+ if (psSysSpecData->sTimerRegPhysBase.uiAddr == 0) -+ { -+ return; -+ } -+#endif -+ /* Disable the timer */ -+ pui32TimerDisable = OSMapPhysToLin(TimerRegPhysBase, -+ 4, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ &hTimerDisable); -+ -+ if (pui32TimerDisable == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "DisableSystemClocks: OSMapPhysToLin failed")); -+ } -+ else -+ { -+ *pui32TimerDisable = 0; -+ -+ OSUnMapPhysToLin(pui32TimerDisable, -+ 4, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ hTimerDisable); -+ } -+#if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA) -+ psSysSpecData->sTimerRegPhysBase.uiAddr = 0; -+#endif -+#if defined(PVR_OMAP4_TIMING_PRCM) -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) -+ clk_disable(psSysSpecData->psGPT11_ICK); -+#endif -+ -+ clk_disable(psSysSpecData->psGPT11_FCK); -+#endif /* defined(PVR_OMAP4_TIMING_PRCM) */ -+} -+#endif /* PVR_OMAP_USE_DM_TIMER_API */ -+#else /* (DEBUG || TIMING) && !PVR_NO_OMAP_TIMER */ -+static PVRSRV_ERROR AcquireGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ PVR_UNREFERENCED_PARAMETER(psSysSpecData); -+ -+ return PVRSRV_OK; -+} -+static void ReleaseGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ PVR_UNREFERENCED_PARAMETER(psSysSpecData); -+} -+#endif /* (DEBUG || TIMING) && !PVR_NO_OMAP_TIMER */ -+ -+/*! -+****************************************************************************** -+ -+ @Function EnableSystemClocks -+ -+ @Description Setup up the clocks for the graphics device to work. -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData) -+{ -+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; -+#if !defined(PM_RUNTIME_SUPPORT) -+ struct clk *psCLK; -+#endif -+ -+ PVR_TRACE(("EnableSystemClocks: Enabling System Clocks")); -+ -+ if (!psSysSpecData->bSysClocksOneTimeInit) -+ { -+ mutex_init(&psSysSpecData->sPowerLock); -+ -+ atomic_set(&psSysSpecData->sSGXClocksEnabled, 0); -+ -+ psSysSpecData->bSysClocksOneTimeInit = IMG_TRUE; -+#if !defined(PM_RUNTIME_SUPPORT) -+ psCLK = clk_get(NULL, "sgx_ck"); -+ if (IS_ERR(psCLK)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSsystemClocks: Couldn't get SGX Functional Clock")); -+ return PVRSRV_ERROR_UNABLE_TO_GET_CLOCK; -+ } -+ psSysSpecData->psSGX_FCK = psCLK; -+#endif -+ -+ } -+ -+ return AcquireGPTimer(psSysSpecData); -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function DisableSystemClocks -+ -+ @Description Disable the graphics clocks. -+ -+ @Return none -+ -+******************************************************************************/ -+IMG_VOID DisableSystemClocks(SYS_DATA *psSysData) -+{ -+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; -+ -+ PVR_TRACE(("DisableSystemClocks: Disabling System Clocks")); -+ -+ /* -+ * Always disable the SGX clocks when the system clocks are disabled. -+ * This saves having to make an explicit call to DisableSGXClocks if -+ * active power management is enabled. -+ */ -+ DisableSGXClocks(psSysData); -+ -+ ReleaseGPTimer(psSysSpecData); -+} -+ -+PVRSRV_ERROR SysPMRuntimeRegister(void) -+{ -+#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) -+#if defined(PM_RUNTIME_SUPPORT) -+ pm_runtime_enable(&gpsPVRLDMDev->dev); -+#endif -+#endif -+ return PVRSRV_OK; -+} -+ -+PVRSRV_ERROR SysPMRuntimeUnregister(void) -+{ -+#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) -+#if defined(PM_RUNTIME_SUPPORT) -+ pm_runtime_disable(&gpsPVRLDMDev->dev); -+#endif -+#endif -+ return PVRSRV_OK; -+} -+ -+PVRSRV_ERROR SysDvfsInitialize(SYS_SPECIFIC_DATA *psSysSpecificData) -+{ -+#if !defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) -+ PVR_UNREFERENCED_PARAMETER(psSysSpecificData); -+#else /* !defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) */ -+ IMG_UINT32 i, *freq_list; -+ IMG_INT32 opp_count; -+ unsigned long freq; -+ struct opp *opp; -+ -+ /* -+ * We query and store the list of SGX frequencies just this once under the -+ * assumption that they are unchanging, e.g. no disabling of high frequency -+ * option for thermal management. This is currently valid for 4430 and 4460. -+ */ -+ rcu_read_lock(); -+ opp_count = opp_get_opp_count(&gpsPVRLDMDev->dev); -+ if (opp_count < 1) -+ { -+ rcu_read_unlock(); -+ PVR_DPF((PVR_DBG_ERROR, "SysDvfsInitialize: Could not retrieve opp count")); -+ return PVRSRV_ERROR_NOT_SUPPORTED; -+ } -+ -+ /* -+ * Allocate the frequency list with a slot for each available frequency plus -+ * one additional slot to hold a designated frequency value to assume when in -+ * an unknown frequency state. -+ */ -+ freq_list = kmalloc((opp_count + 1) * sizeof(IMG_UINT32), GFP_ATOMIC); -+ if (!freq_list) -+ { -+ rcu_read_unlock(); -+ PVR_DPF((PVR_DBG_ERROR, "SysDvfsInitialize: Could not allocate frequency list")); -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ -+ /* -+ * Fill in frequency list from lowest to highest then finally the "unknown" -+ * frequency value. We use the highest available frequency as our assumed value -+ * when in an unknown state, because it is safer for APM and hardware recovery -+ * timers to be longer than intended rather than shorter. -+ */ -+ freq = 0; -+ for (i = 0; i < opp_count; i++) -+ { -+ opp = opp_find_freq_ceil(&gpsPVRLDMDev->dev, &freq); -+ if (IS_ERR_OR_NULL(opp)) -+ { -+ rcu_read_unlock(); -+ PVR_DPF((PVR_DBG_ERROR, "SysDvfsInitialize: Could not retrieve opp level %d", i)); -+ kfree(freq_list); -+ return PVRSRV_ERROR_NOT_SUPPORTED; -+ } -+ freq_list[i] = (IMG_UINT32)freq; -+ freq++; -+ } -+ rcu_read_unlock(); -+ freq_list[opp_count] = freq_list[opp_count - 1]; -+ -+ psSysSpecificData->ui32SGXFreqListSize = opp_count + 1; -+ psSysSpecificData->pui32SGXFreqList = freq_list; -+ -+ /* Start in unknown state - no frequency request to DVFS yet made */ -+ psSysSpecificData->ui32SGXFreqListIndex = opp_count; -+#endif /* !defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) */ -+ -+ return PVRSRV_OK; -+} -+ -+PVRSRV_ERROR SysDvfsDeinitialize(SYS_SPECIFIC_DATA *psSysSpecificData) -+{ -+#if !defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) -+ PVR_UNREFERENCED_PARAMETER(psSysSpecificData); -+#else /* !defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) */ -+ /* -+ * We assume this function is only called if SysDvfsInitialize() was -+ * completed successfully before. -+ * -+ * The DVFS interface does not allow us to actually unregister as a -+ * user of SGX, so we do the next best thing which is to lower our -+ * required frequency to the minimum if not already set. DVFS may -+ * report busy if early in initialization, but all other errors are -+ * considered serious. -+ */ -+ if (psSysSpecificData->ui32SGXFreqListIndex != 0) -+ { -+ struct gpu_platform_data *pdata; -+ IMG_INT32 res; -+ -+ pdata = (struct gpu_platform_data *)gpsPVRLDMDev->dev.platform_data; -+ -+ PVR_ASSERT(pdata->device_scale != IMG_NULL); -+ res = pdata->device_scale(&gpsPVRLDMDev->dev, -+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3,4,0)) -+ &gpsPVRLDMDev->dev, -+#endif -+ psSysSpecificData->pui32SGXFreqList[0]); -+ if (res == -EBUSY) -+ { -+ PVR_DPF((PVR_DBG_WARNING, "SysDvfsDeinitialize: Unable to scale SGX frequency (EBUSY)")); -+ } -+ else if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SysDvfsDeinitialize: Unable to scale SGX frequency (%d)", res)); -+ } -+ -+ psSysSpecificData->ui32SGXFreqListIndex = 0; -+ } -+ -+ kfree(psSysSpecificData->pui32SGXFreqList); -+ psSysSpecificData->pui32SGXFreqList = 0; -+ psSysSpecificData->ui32SGXFreqListSize = 0; -+#endif /* !defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) */ -+ -+ return PVRSRV_OK; -+} -+ -+#if defined(SUPPORT_DRI_DRM_PLUGIN) -+static struct omap_gpu_plugin sOMAPGPUPlugin; -+ -+#define SYS_DRM_SET_PLUGIN_FIELD(d, s, f) (d)->f = (s)->f -+int -+SysDRMRegisterPlugin(PVRSRV_DRM_PLUGIN *psDRMPlugin) -+{ -+ int iRes; -+ -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, name); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, open); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, load); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, unload); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, release); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, mmap); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, ioctls); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, num_ioctls); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, ioctl_start); -+ -+ iRes = omap_gpu_register_plugin(&sOMAPGPUPlugin); -+ if (iRes != 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: omap_gpu_register_plugin failed (%d)", __FUNCTION__, iRes)); -+ } -+ -+ return iRes; -+} -+ -+void -+SysDRMUnregisterPlugin(PVRSRV_DRM_PLUGIN *psDRMPlugin) -+{ -+ int iRes = omap_gpu_unregister_plugin(&sOMAPGPUPlugin); -+ if (iRes != 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: omap_gpu_unregister_plugin failed (%d)", __FUNCTION__, iRes)); -+ } -+} -+#endif -diff --git a/drivers/staging/ti-es8-sgx/services4/system/ti43xx/oemfuncs.h b/drivers/staging/ti-es8-sgx/services4/system/ti43xx/oemfuncs.h -new file mode 100644 -index 0000000..77c70d6 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/ti43xx/oemfuncs.h -@@ -0,0 +1,78 @@ -+/*************************************************************************/ /*! -+@Title SGX kernel/client driver interface structures and prototypes -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#if !defined(__OEMFUNCS_H__) -+#define __OEMFUNCS_H__ -+ -+#if defined (__cplusplus) -+extern "C" { -+#endif -+ -+/* function in/out data structures: */ -+typedef IMG_UINT32 (*PFN_SRV_BRIDGEDISPATCH)( IMG_UINT32 Ioctl, -+ IMG_BYTE *pInBuf, -+ IMG_UINT32 InBufLen, -+ IMG_BYTE *pOutBuf, -+ IMG_UINT32 OutBufLen, -+ IMG_UINT32 *pdwBytesTransferred); -+/* -+ Function table for kernel 3rd party driver to kernel services -+*/ -+typedef struct PVRSRV_DC_OEM_JTABLE_TAG -+{ -+ PFN_SRV_BRIDGEDISPATCH pfnOEMBridgeDispatch; -+ IMG_PVOID pvDummy1; -+ IMG_PVOID pvDummy2; -+ IMG_PVOID pvDummy3; -+ -+} PVRSRV_DC_OEM_JTABLE; -+ -+#define OEM_GET_EXT_FUNCS (1<<1) -+ -+#if defined(__cplusplus) -+} -+#endif -+ -+#endif /* __OEMFUNCS_H__ */ -+ -+/***************************************************************************** -+ End of file (oemfuncs.h) -+*****************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/system/ti43xx/sysconfig.c b/drivers/staging/ti-es8-sgx/services4/system/ti43xx/sysconfig.c -new file mode 100644 -index 0000000..a111c03 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/ti43xx/sysconfig.c -@@ -0,0 +1,1274 @@ -+/*************************************************************************/ /*! -+@Title System Configuration -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description System Configuration functions -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#include "sysconfig.h" -+#include "services_headers.h" -+#include "kerneldisplay.h" -+#include "oemfuncs.h" -+#include "sgxinfo.h" -+#include "sgxinfokm.h" -+#include "syslocal.h" -+ -+#include "ocpdefs.h" -+ -+/* top level system data anchor point*/ -+SYS_DATA* gpsSysData = (SYS_DATA*)IMG_NULL; -+SYS_DATA gsSysData; -+ -+static SYS_SPECIFIC_DATA gsSysSpecificData; -+SYS_SPECIFIC_DATA *gpsSysSpecificData; -+ -+/* SGX structures */ -+static IMG_UINT32 gui32SGXDeviceID; -+static SGX_DEVICE_MAP gsSGXDeviceMap; -+static PVRSRV_DEVICE_NODE *gpsSGXDevNode; -+ -+ -+#if defined(NO_HARDWARE) || defined(SGX_OCP_REGS_ENABLED) -+static IMG_CPU_VIRTADDR gsSGXRegsCPUVAddr; -+#endif -+ -+#if defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO) -+extern struct platform_device *gpsPVRLDMDev; -+#endif -+ -+IMG_UINT32 PVRSRV_BridgeDispatchKM(IMG_UINT32 Ioctl, -+ IMG_BYTE *pInBuf, -+ IMG_UINT32 InBufLen, -+ IMG_BYTE *pOutBuf, -+ IMG_UINT32 OutBufLen, -+ IMG_UINT32 *pdwBytesTransferred); -+ -+#if defined(SGX_OCP_REGS_ENABLED) -+ -+static IMG_CPU_VIRTADDR gpvOCPRegsLinAddr; -+ -+static PVRSRV_ERROR EnableSGXClocksWrap(SYS_DATA *psSysData) -+{ -+ PVRSRV_ERROR eError = EnableSGXClocks(psSysData); -+ -+#if !defined(SGX_OCP_NO_INT_BYPASS) -+ if(eError == PVRSRV_OK) -+ { -+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_SYSCONFIG, 0x14); -+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_DEBUG_CONFIG, EUR_CR_OCP_DEBUG_CONFIG_THALIA_INT_BYPASS_MASK); -+ } -+#endif -+ return eError; -+} -+ -+#else /* defined(SGX_OCP_REGS_ENABLED) */ -+ -+static INLINE PVRSRV_ERROR EnableSGXClocksWrap(SYS_DATA *psSysData) -+{ -+ return EnableSGXClocks(psSysData); -+} -+ -+#endif /* defined(SGX_OCP_REGS_ENABLED) */ -+ -+static INLINE PVRSRV_ERROR EnableSystemClocksWrap(SYS_DATA *psSysData) -+{ -+ PVRSRV_ERROR eError = EnableSystemClocks(psSysData); -+ -+#if !defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ if(eError == PVRSRV_OK) -+ { -+ /* -+ * The SGX Clocks are enabled separately if active power -+ * management is enabled. -+ */ -+ eError = EnableSGXClocksWrap(psSysData); -+ if (eError != PVRSRV_OK) -+ { -+ DisableSystemClocks(psSysData); -+ } -+ } -+#endif -+ -+ return eError; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function SysLocateDevices -+ -+ @Description Specifies devices in the systems memory map -+ -+ @Input psSysData - sys data -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+static PVRSRV_ERROR SysLocateDevices(SYS_DATA *psSysData) -+{ -+#if defined(NO_HARDWARE) -+ PVRSRV_ERROR eError; -+ IMG_CPU_PHYADDR sCpuPAddr; -+#else -+#if defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO) -+ struct resource *dev_res; -+ int dev_irq; -+#endif -+#endif -+ -+ PVR_UNREFERENCED_PARAMETER(psSysData); -+ -+ /* SGX Device: */ -+ gsSGXDeviceMap.ui32Flags = 0x0; -+ -+#if defined(NO_HARDWARE) -+ /* -+ * For no hardware, allocate some contiguous memory for the -+ * register block. -+ */ -+ -+ /* Registers */ -+ gsSGXDeviceMap.ui32RegsSize = SYS_TI43xx_SGX_REGS_SIZE; -+ -+ eError = OSBaseAllocContigMemory(gsSGXDeviceMap.ui32RegsSize, -+ &gsSGXRegsCPUVAddr, -+ &sCpuPAddr); -+ if(eError != PVRSRV_OK) -+ { -+ return eError; -+ } -+ gsSGXDeviceMap.sRegsCpuPBase = sCpuPAddr; -+ gsSGXDeviceMap.sRegsSysPBase = SysCpuPAddrToSysPAddr(gsSGXDeviceMap.sRegsCpuPBase); -+#if defined(__linux__) -+ /* Indicate the registers are already mapped */ -+ gsSGXDeviceMap.pvRegsCpuVBase = gsSGXRegsCPUVAddr; -+#else -+ /* -+ * FIXME: Could we just use the virtual address returned by -+ * OSBaseAllocContigMemory? -+ */ -+ gsSGXDeviceMap.pvRegsCpuVBase = IMG_NULL; -+#endif -+ -+ OSMemSet(gsSGXRegsCPUVAddr, 0, gsSGXDeviceMap.ui32RegsSize); -+ -+ /* -+ device interrupt IRQ -+ Note: no interrupts available on no hardware system -+ */ -+ gsSGXDeviceMap.ui32IRQ = 0; -+ -+#else /* defined(NO_HARDWARE) */ -+#if defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO) -+ /* get the resource and IRQ through platform resource API */ -+ dev_res = platform_get_resource(gpsPVRLDMDev, IORESOURCE_MEM, 0); -+ if (dev_res == NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: platform_get_resource failed", __FUNCTION__)); -+ return PVRSRV_ERROR_INVALID_DEVICE; -+ } -+ -+ dev_irq = platform_get_irq(gpsPVRLDMDev, 0); -+ if (dev_irq < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: platform_get_irq failed (%d)", __FUNCTION__, -dev_irq)); -+ return PVRSRV_ERROR_INVALID_DEVICE; -+ } -+ -+ gsSGXDeviceMap.sRegsSysPBase.uiAddr = dev_res->start; -+ gsSGXDeviceMap.sRegsCpuPBase = -+ SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sRegsSysPBase); -+ PVR_TRACE(("SGX register base: 0x%lx", (unsigned long)gsSGXDeviceMap.sRegsCpuPBase.uiAddr)); -+ -+#if defined(SGX544) && defined(SGX_FEATURE_MP) -+ /* FIXME: Workaround due to HWMOD change. Otherwise this region is too small. */ -+ gsSGXDeviceMap.ui32RegsSize = SYS_TI43xx_SGX_REGS_SIZE; -+#else -+ gsSGXDeviceMap.ui32RegsSize = (unsigned int)(dev_res->end - dev_res->start); -+#endif -+ PVR_TRACE(("SGX register size: %d",gsSGXDeviceMap.ui32RegsSize)); -+ -+ gsSGXDeviceMap.ui32IRQ = dev_irq; -+ PVR_TRACE(("SGX IRQ: %d", gsSGXDeviceMap.ui32IRQ)); -+#else /* defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO) */ -+ gsSGXDeviceMap.sRegsSysPBase.uiAddr = SYS_TI43xx_SGX_REGS_SYS_PHYS_BASE; -+ gsSGXDeviceMap.sRegsCpuPBase = SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sRegsSysPBase); -+ gsSGXDeviceMap.ui32RegsSize = SYS_TI43xx_SGX_REGS_SIZE; -+ -+ gsSGXDeviceMap.ui32IRQ = SYS_TI43xx_SGX_IRQ; -+ -+#endif /* defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO) */ -+#if defined(SGX_OCP_REGS_ENABLED) -+ gsSGXRegsCPUVAddr = OSMapPhysToLin(gsSGXDeviceMap.sRegsCpuPBase, -+ gsSGXDeviceMap.ui32RegsSize, -+ PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY, -+ IMG_NULL); -+ -+ if (gsSGXRegsCPUVAddr == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysLocateDevices: Failed to map SGX registers")); -+ return PVRSRV_ERROR_BAD_MAPPING; -+ } -+ -+ /* Indicate the registers are already mapped */ -+ gsSGXDeviceMap.pvRegsCpuVBase = gsSGXRegsCPUVAddr; -+ gpvOCPRegsLinAddr = gsSGXRegsCPUVAddr; -+#endif -+#endif /* defined(NO_HARDWARE) */ -+ -+#if defined(PDUMP) -+ { -+ /* initialise memory region name for pdumping */ -+ static IMG_CHAR pszPDumpDevName[] = "SGXMEM"; -+ gsSGXDeviceMap.pszPDumpDevName = pszPDumpDevName; -+ } -+#endif -+ -+ /* add other devices here: */ -+ -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysCreateVersionString -+ -+ @Description Read the version string -+ -+ @Return IMG_CHAR * : Version string -+ -+******************************************************************************/ -+static IMG_CHAR *SysCreateVersionString(void) -+{ -+ static IMG_CHAR aszVersionString[100]; -+ IMG_UINT32 ui32MaxStrLen; -+ SYS_DATA *psSysData; -+ IMG_UINT32 ui32SGXRevision; -+ IMG_INT32 i32Count; -+ -+ SysAcquireData(&psSysData); -+ -+ ui32SGXRevision = SGX_CORE_REV; -+ ui32MaxStrLen = 99; -+ -+ i32Count = OSSNPrintf(aszVersionString, ui32MaxStrLen + 1, -+ "SGX revision = %u", -+ (IMG_UINT)(ui32SGXRevision)); -+ if(i32Count == -1) -+ { -+ return IMG_NULL; -+ } -+ -+ return aszVersionString; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysInitialise -+ -+ @Description Initialises kernel services at 'driver load' time -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+PVRSRV_ERROR SysInitialise(IMG_VOID) -+{ -+ IMG_UINT32 i; -+ PVRSRV_ERROR eError; -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+#if !defined(PVR_NO_OMAP_TIMER) -+ IMG_CPU_PHYADDR TimerRegPhysBase; -+#endif -+#if !defined(SGX_DYNAMIC_TIMING_INFO) -+ SGX_TIMING_INFORMATION* psTimingInfo; -+#endif -+ gpsSysData = &gsSysData; -+ OSMemSet(gpsSysData, 0, sizeof(SYS_DATA)); -+ -+ gpsSysSpecificData = &gsSysSpecificData; -+ OSMemSet(gpsSysSpecificData, 0, sizeof(SYS_SPECIFIC_DATA)); -+ -+ gpsSysData->pvSysSpecificData = gpsSysSpecificData; -+ -+ eError = OSInitEnvData(&gpsSysData->pvEnvSpecificData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to setup env structure")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_ENVDATA); -+ -+ gpsSysData->ui32NumDevices = SYS_DEVICE_COUNT; -+ -+ /* init device ID's */ -+ for(i=0; i<SYS_DEVICE_COUNT; i++) -+ { -+ gpsSysData->sDeviceID[i].uiID = i; -+ gpsSysData->sDeviceID[i].bInUse = IMG_FALSE; -+ } -+ -+ gpsSysData->psDeviceNodeList = IMG_NULL; -+ gpsSysData->psQueueList = IMG_NULL; -+ -+ eError = SysInitialiseCommon(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed in SysInitialiseCommon")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ -+#if !defined(SGX_DYNAMIC_TIMING_INFO) -+ /* Set up timing information*/ -+ psTimingInfo = &gsSGXDeviceMap.sTimingInfo; -+ psTimingInfo->ui32CoreClockSpeed = SYS_SGX_CLOCK_SPEED; -+ psTimingInfo->ui32HWRecoveryFreq = SYS_SGX_HWRECOVERY_TIMEOUT_FREQ; -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ psTimingInfo->bEnableActivePM = IMG_TRUE; -+#else -+ psTimingInfo->bEnableActivePM = IMG_FALSE; -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ psTimingInfo->ui32ActivePowManLatencyms = SYS_SGX_ACTIVE_POWER_LATENCY_MS; -+ psTimingInfo->ui32uKernelFreq = SYS_SGX_PDS_TIMER_FREQ; -+#endif -+ -+ /* -+ Setup the Source Clock Divider value -+ */ -+ gpsSysSpecificData->ui32SrcClockDiv = 3; -+ -+ /* -+ Locate the devices within the system, specifying -+ the physical addresses of each devices components -+ (regs, mem, ports etc.) -+ */ -+ eError = SysLocateDevices(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to locate devices")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV); -+ -+ eError = SysPMRuntimeRegister(); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to register with OSPM!")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_PM_RUNTIME); -+ -+ eError = SysDvfsInitialize(gpsSysSpecificData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to initialize DVFS")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_DVFS_INIT); -+ -+ /* -+ Register devices with the system -+ This also sets up their memory maps/heaps -+ */ -+ eError = PVRSRVRegisterDevice(gpsSysData, SGXRegisterDevice, -+ DEVICE_SGX_INTERRUPT, &gui32SGXDeviceID); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to register device!")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_REGDEV); -+ -+ /* -+ Once all devices are registered, specify the backing store -+ and, if required, customise the memory heap config -+ */ -+ psDeviceNode = gpsSysData->psDeviceNodeList; -+ while(psDeviceNode) -+ { -+ /* perform any OEM SOC address space customisations here */ -+ switch(psDeviceNode->sDevId.eDeviceType) -+ { -+ case PVRSRV_DEVICE_TYPE_SGX: -+ { -+ DEVICE_MEMORY_INFO *psDevMemoryInfo; -+ DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; -+ -+ /* -+ specify the backing store to use for the devices MMU PT/PDs -+ - the PT/PDs are always UMA in this system -+ */ -+ psDeviceNode->psLocalDevMemArena = IMG_NULL; -+ -+ /* useful pointers */ -+ psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo; -+ psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap; -+ -+ /* specify the backing store for all SGX heaps */ -+ for(i=0; i<psDevMemoryInfo->ui32HeapCount; i++) -+ { -+ psDeviceMemoryHeap[i].ui32Attribs |= PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG; -+ } -+ -+ gpsSGXDevNode = psDeviceNode; -+ gsSysSpecificData.psSGXDevNode = psDeviceNode; -+ -+ break; -+ } -+ default: -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to find SGX device node!")); -+ return PVRSRV_ERROR_INIT_FAILURE; -+ } -+ -+ /* advance to next device */ -+ psDeviceNode = psDeviceNode->psNext; -+ } -+ -+ eError = EnableSystemClocksWrap(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable system clocks (%d)", eError)); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS); -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ eError = EnableSGXClocksWrap(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable SGX clocks (%d)", eError)); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ -+ eError = PVRSRVInitialiseDevice(gui32SGXDeviceID); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to initialise device!")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_INITDEV); -+ -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ /* SGX defaults to D3 power state */ -+ DisableSGXClocks(gpsSysData); -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ -+#if !defined(PVR_NO_OMAP_TIMER) -+#if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA) -+ TimerRegPhysBase = gsSysSpecificData.sTimerRegPhysBase; -+#else -+ TimerRegPhysBase.uiAddr = SYS_TI43xx_GP7TIMER_REGS_SYS_PHYS_BASE; -+#endif -+ gpsSysData->pvSOCTimerRegisterKM = IMG_NULL; -+ gpsSysData->hSOCTimerRegisterOSMemHandle = 0; -+ if (TimerRegPhysBase.uiAddr != 0) -+ { -+ OSReservePhys(TimerRegPhysBase, -+ 4, -+ PVRSRV_HAP_MULTI_PROCESS|PVRSRV_HAP_UNCACHED, -+ IMG_NULL, -+ (IMG_VOID **)&gpsSysData->pvSOCTimerRegisterKM, -+ &gpsSysData->hSOCTimerRegisterOSMemHandle); -+ } -+#endif /* !defined(PVR_NO_OMAP_TIMER) */ -+ -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysFinalise -+ -+ @Description Final part of initialisation at 'driver load' time -+ -+ @Return PVRSRV_ERROR : -+ -+******************************************************************************/ -+PVRSRV_ERROR SysFinalise(IMG_VOID) -+{ -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ eError = EnableSGXClocksWrap(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to Enable SGX clocks (%d)", eError)); -+ return eError; -+ } -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ -+ eError = OSInstallMISR(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to install MISR")); -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_MISR); -+ -+#if defined(SYS_USING_INTERRUPTS) -+ /* install a Device ISR */ -+ eError = OSInstallDeviceLISR(gpsSysData, gsSGXDeviceMap.ui32IRQ, "SGX ISR", gpsSGXDevNode); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to install ISR")); -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR); -+#if !defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ SysEnableSGXInterrupts(gpsSysData); -+#endif -+#endif /* defined(SYS_USING_INTERRUPTS) */ -+#if defined(__linux__) -+ /* Create a human readable version string for this system */ -+ gpsSysData->pszVersionString = SysCreateVersionString(); -+ if (!gpsSysData->pszVersionString) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to create a system version string")); -+ } -+ else -+ { -+ PVR_TRACE(("SysFinalise: Version string: %s", gpsSysData->pszVersionString)); -+ } -+#endif -+ -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ /* SGX defaults to D3 power state */ -+ DisableSGXClocks(gpsSysData); -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ -+ gpsSysSpecificData->bSGXInitComplete = IMG_TRUE; -+ -+ return eError; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysDeinitialise -+ -+ @Description De-initialises kernel services at 'driver unload' time -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR SysDeinitialise (SYS_DATA *psSysData) -+{ -+ PVRSRV_ERROR eError; -+ -+ PVR_UNREFERENCED_PARAMETER(psSysData); -+ -+ if(gpsSysData->pvSOCTimerRegisterKM) -+ { -+ OSUnReservePhys(gpsSysData->pvSOCTimerRegisterKM, -+ 4, -+ PVRSRV_HAP_MULTI_PROCESS|PVRSRV_HAP_UNCACHED, -+ gpsSysData->hSOCTimerRegisterOSMemHandle); -+ } -+ -+ -+#if defined(SYS_USING_INTERRUPTS) -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR)) -+ { -+ eError = OSUninstallDeviceLISR(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: OSUninstallDeviceLISR failed")); -+ return eError; -+ } -+ } -+#endif -+ -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_MISR)) -+ { -+ eError = OSUninstallMISR(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: OSUninstallMISR failed")); -+ return eError; -+ } -+ } -+ -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_INITDEV)) -+ { -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ PVR_ASSERT(SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS)); -+ /* Reenable SGX clocks whilst SGX is being deinitialised. */ -+ eError = EnableSGXClocksWrap(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: EnableSGXClocks failed")); -+ return eError; -+ } -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ -+ /* Deinitialise SGX */ -+ eError = PVRSRVDeinitialiseDevice(gui32SGXDeviceID); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: failed to de-init the device")); -+ return eError; -+ } -+ } -+ -+ /* Disable system clocks. Must happen after last access to hardware */ -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS)) -+ { -+ DisableSystemClocks(gpsSysData); -+ } -+ -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_DVFS_INIT)) -+ { -+ eError = SysDvfsDeinitialize(gpsSysSpecificData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: Failed to de-init DVFS")); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ } -+ -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_PM_RUNTIME)) -+ { -+ eError = SysPMRuntimeUnregister(); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: Failed to unregister with OSPM!")); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ } -+ -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_ENVDATA)) -+ { -+ eError = OSDeInitEnvData(gpsSysData->pvEnvSpecificData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: failed to de-init env structure")); -+ return eError; -+ } -+ } -+ -+ SysDeinitialiseCommon(gpsSysData); -+ -+#if defined(NO_HARDWARE) || defined(SGX_OCP_REGS_ENABLED) -+ if(gsSGXRegsCPUVAddr != IMG_NULL) -+ { -+#if defined(NO_HARDWARE) -+ /* Free hardware resources. */ -+ OSBaseFreeContigMemory(SYS_TI43xx_SGX_REGS_SIZE, gsSGXRegsCPUVAddr, gsSGXDeviceMap.sRegsCpuPBase); -+#else -+#if defined(SGX_OCP_REGS_ENABLED) -+ OSUnMapPhysToLin(gsSGXRegsCPUVAddr, -+ gsSGXDeviceMap.ui32RegsSize, -+ PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY, -+ IMG_NULL); -+ -+ gpvOCPRegsLinAddr = IMG_NULL; -+#endif -+#endif /* defined(NO_HARDWARE) */ -+ gsSGXRegsCPUVAddr = IMG_NULL; -+ gsSGXDeviceMap.pvRegsCpuVBase = gsSGXRegsCPUVAddr; -+ } -+#endif /* defined(NO_HARDWARE) || defined(SGX_OCP_REGS_ENABLED) */ -+ -+ -+ gpsSysSpecificData->ui32SysSpecificData = 0; -+ gpsSysSpecificData->bSGXInitComplete = IMG_FALSE; -+ -+ gpsSysData = IMG_NULL; -+ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysGetDeviceMemoryMap -+ -+ @Description returns a device address map for the specified device -+ -+ @Input eDeviceType - device type -+ @Input ppvDeviceMap - void ptr to receive device specific info. -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE eDeviceType, -+ IMG_VOID **ppvDeviceMap) -+{ -+ -+ switch(eDeviceType) -+ { -+ case PVRSRV_DEVICE_TYPE_SGX: -+ { -+ /* just return a pointer to the structure */ -+ *ppvDeviceMap = (IMG_VOID*)&gsSGXDeviceMap; -+ -+ break; -+ } -+ default: -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysGetDeviceMemoryMap: unsupported device type")); -+ } -+ } -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function SysCpuPAddrToDevPAddr -+ -+ @Description Compute a device physical address from a cpu physical -+ address. Relevant when -+ -+ @Input cpu_paddr - cpu physical address. -+ @Input eDeviceType - device type required if DevPAddr -+ address spaces vary across devices -+ in the same system -+ @Return device physical address. -+ -+******************************************************************************/ -+IMG_DEV_PHYADDR SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType, -+ IMG_CPU_PHYADDR CpuPAddr) -+{ -+ IMG_DEV_PHYADDR DevPAddr; -+ -+ PVR_UNREFERENCED_PARAMETER(eDeviceType); -+ -+ /* Note: for UMA system we assume DevP == CpuP */ -+ DevPAddr.uiAddr = CpuPAddr.uiAddr; -+ -+ return DevPAddr; -+} -+ -+/*! -+****************************************************************************** -+ @Function SysSysPAddrToCpuPAddr -+ -+ @Description Compute a cpu physical address from a system physical -+ address. -+ -+ @Input sys_paddr - system physical address. -+ @Return cpu physical address. -+ -+******************************************************************************/ -+IMG_CPU_PHYADDR SysSysPAddrToCpuPAddr (IMG_SYS_PHYADDR sys_paddr) -+{ -+ IMG_CPU_PHYADDR cpu_paddr; -+ -+ /* This would only be an inequality if the CPU's MMU did not point to -+ sys address 0, ie. multi CPU system */ -+ cpu_paddr.uiAddr = sys_paddr.uiAddr; -+ return cpu_paddr; -+} -+ -+/*! -+****************************************************************************** -+ @Function SysCpuPAddrToSysPAddr -+ -+ @Description Compute a system physical address from a cpu physical -+ address. -+ -+ @Input cpu_paddr - cpu physical address. -+ @Return device physical address. -+ -+******************************************************************************/ -+IMG_SYS_PHYADDR SysCpuPAddrToSysPAddr (IMG_CPU_PHYADDR cpu_paddr) -+{ -+ IMG_SYS_PHYADDR sys_paddr; -+ -+ /* This would only be an inequality if the CPU's MMU did not point to -+ sys address 0, ie. multi CPU system */ -+ sys_paddr.uiAddr = cpu_paddr.uiAddr; -+ return sys_paddr; -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function SysSysPAddrToDevPAddr -+ -+ @Description Compute a device physical address from a system physical -+ address. -+ -+ @Input SysPAddr - system physical address. -+ @Input eDeviceType - device type required if DevPAddr -+ address spaces vary across devices -+ in the same system -+ -+ @Return Device physical address. -+ -+******************************************************************************/ -+IMG_DEV_PHYADDR SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType, IMG_SYS_PHYADDR SysPAddr) -+{ -+ IMG_DEV_PHYADDR DevPAddr; -+ -+ PVR_UNREFERENCED_PARAMETER(eDeviceType); -+ -+ /* Note: for UMA system we assume DevP == CpuP */ -+ DevPAddr.uiAddr = SysPAddr.uiAddr; -+ -+ return DevPAddr; -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function SysDevPAddrToSysPAddr -+ -+ @Description Compute a device physical address from a system physical -+ address. -+ -+ @Input DevPAddr - device physical address. -+ @Input eDeviceType - device type required if DevPAddr -+ address spaces vary across devices -+ in the same system -+ -+ @Return System physical address. -+ -+******************************************************************************/ -+IMG_SYS_PHYADDR SysDevPAddrToSysPAddr(PVRSRV_DEVICE_TYPE eDeviceType, IMG_DEV_PHYADDR DevPAddr) -+{ -+ IMG_SYS_PHYADDR SysPAddr; -+ -+ PVR_UNREFERENCED_PARAMETER(eDeviceType); -+ -+ /* Note: for UMA system we assume DevP == SysP */ -+ SysPAddr.uiAddr = DevPAddr.uiAddr; -+ -+ return SysPAddr; -+} -+ -+ -+/***************************************************************************** -+ @Function SysRegisterExternalDevice -+ -+ @Description Called when a 3rd party device registers with services -+ -+ @Input psDeviceNode - the new device node. -+ -+ @Return IMG_VOID -+*****************************************************************************/ -+IMG_VOID SysRegisterExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode) -+{ -+ PVR_UNREFERENCED_PARAMETER(psDeviceNode); -+} -+ -+ -+/***************************************************************************** -+ @Function SysRemoveExternalDevice -+ -+ @Description Called when a 3rd party device unregisters from services -+ -+ @Input psDeviceNode - the device node being removed. -+ -+ @Return IMG_VOID -+*****************************************************************************/ -+IMG_VOID SysRemoveExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode) -+{ -+ PVR_UNREFERENCED_PARAMETER(psDeviceNode); -+} -+ -+/*! -+****************************************************************************** -+ @Function SysGetInterruptSource -+ -+ @Description Returns System specific information about the device(s) that -+ generated the interrupt in the system -+ -+ @Input psSysData -+ @Input psDeviceNode -+ -+ @Return System specific information indicating which device(s) -+ generated the interrupt -+ -+******************************************************************************/ -+IMG_UINT32 SysGetInterruptSource(SYS_DATA *psSysData, -+ PVRSRV_DEVICE_NODE *psDeviceNode) -+{ -+ PVR_UNREFERENCED_PARAMETER(psSysData); -+#if defined(NO_HARDWARE) -+ /* no interrupts in no_hw system just return all bits */ -+ return 0xFFFFFFFF; -+#else -+ /* Not a shared irq, so we know this is an interrupt for this device */ -+ return psDeviceNode->ui32SOCInterruptBit; -+#endif -+} -+ -+ -+/*! -+****************************************************************************** -+ @Function SysClearInterrupts -+ -+ @Description Clears specified system interrupts -+ -+ @Input psSysData -+ @Input ui32ClearBits -+ -+ @Return IMG_VOID -+ -+******************************************************************************/ -+IMG_VOID SysClearInterrupts(SYS_DATA* psSysData, IMG_UINT32 ui32ClearBits) -+{ -+ PVR_UNREFERENCED_PARAMETER(ui32ClearBits); -+ PVR_UNREFERENCED_PARAMETER(psSysData); -+#if !defined(NO_HARDWARE) -+#if defined(SGX_OCP_NO_INT_BYPASS) -+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_IRQSTATUS_2, 0x1); -+#endif -+ /* Flush posted writes */ -+ OSReadHWReg(((PVRSRV_SGXDEV_INFO *)gpsSGXDevNode->pvDevice)->pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR); -+#endif /* defined(NO_HARDWARE) */ -+} -+ -+#if defined(SGX_OCP_NO_INT_BYPASS) -+/*! -+****************************************************************************** -+ @Function SysEnableSGXInterrupts -+ -+ @Description Enables SGX interrupts -+ -+ @Input psSysData -+ -+ @Return IMG_VOID -+ -+******************************************************************************/ -+IMG_VOID SysEnableSGXInterrupts(SYS_DATA *psSysData) -+{ -+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *)psSysData->pvSysSpecificData; -+ if (SYS_SPECIFIC_DATA_TEST(psSysSpecData, SYS_SPECIFIC_DATA_ENABLE_LISR) && !SYS_SPECIFIC_DATA_TEST(psSysSpecData, SYS_SPECIFIC_DATA_IRQ_ENABLED)) -+ { -+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_IRQSTATUS_2, 0x1); -+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_IRQENABLE_SET_2, 0x1); -+ SYS_SPECIFIC_DATA_SET(psSysSpecData, SYS_SPECIFIC_DATA_IRQ_ENABLED); -+ } -+} -+ -+/*! -+****************************************************************************** -+ @Function SysDisableSGXInterrupts -+ -+ @Description Disables SGX interrupts -+ -+ @Input psSysData -+ -+ @Return IMG_VOID -+ -+******************************************************************************/ -+IMG_VOID SysDisableSGXInterrupts(SYS_DATA *psSysData) -+{ -+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *)psSysData->pvSysSpecificData; -+ -+ if (SYS_SPECIFIC_DATA_TEST(psSysSpecData, SYS_SPECIFIC_DATA_IRQ_ENABLED)) -+ { -+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_IRQENABLE_CLR_2, 0x1); -+ SYS_SPECIFIC_DATA_CLEAR(psSysSpecData, SYS_SPECIFIC_DATA_IRQ_ENABLED); -+ } -+} -+#endif /* defined(SGX_OCP_NO_INT_BYPASS) */ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysSystemPrePowerState -+ -+ @Description Perform system-level processing required before a power transition -+ -+ @Input eNewPowerState : -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR SysSystemPrePowerState(PVRSRV_SYS_POWER_STATE eNewPowerState) -+{ -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ -+ if (eNewPowerState == PVRSRV_SYS_POWER_STATE_D3) -+ { -+ PVR_TRACE(("SysSystemPrePowerState: Entering state D3")); -+ -+#if defined(SYS_USING_INTERRUPTS) -+ if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR)) -+ { -+#if defined(SYS_CUSTOM_POWERLOCK_WRAP) -+ IMG_BOOL bWrapped = WrapSystemPowerChange(&gsSysSpecificData); -+#endif -+ eError = OSUninstallDeviceLISR(gpsSysData); -+#if defined(SYS_CUSTOM_POWERLOCK_WRAP) -+ if (bWrapped) -+ { -+ UnwrapSystemPowerChange(&gsSysSpecificData); -+ } -+#endif -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysSystemPrePowerState: OSUninstallDeviceLISR failed (%d)", eError)); -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR); -+ SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR); -+ } -+#endif -+ -+ if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS)) -+ { -+ DisableSystemClocks(gpsSysData); -+ -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS); -+ SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS); -+ } -+ } -+ -+ return eError; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysSystemPostPowerState -+ -+ @Description Perform system-level processing required after a power transition -+ -+ @Input eNewPowerState : -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR SysSystemPostPowerState(PVRSRV_SYS_POWER_STATE eNewPowerState) -+{ -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ -+ if (eNewPowerState == PVRSRV_SYS_POWER_STATE_D0) -+ { -+ PVR_TRACE(("SysSystemPostPowerState: Entering state D0")); -+ -+ if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS)) -+ { -+ eError = EnableSystemClocksWrap(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysSystemPostPowerState: EnableSystemClocksWrap failed (%d)", eError)); -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS); -+ SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS); -+ } -+ -+#if defined(SYS_USING_INTERRUPTS) -+ if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR)) -+ { -+#if defined(SYS_CUSTOM_POWERLOCK_WRAP) -+ IMG_BOOL bWrapped = WrapSystemPowerChange(&gsSysSpecificData); -+#endif -+ -+ eError = OSInstallDeviceLISR(gpsSysData, gsSGXDeviceMap.ui32IRQ, "SGX ISR", gpsSGXDevNode); -+#if defined(SYS_CUSTOM_POWERLOCK_WRAP) -+ if (bWrapped) -+ { -+ UnwrapSystemPowerChange(&gsSysSpecificData); -+ } -+#endif -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysSystemPostPowerState: OSInstallDeviceLISR failed to install ISR (%d)", eError)); -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR); -+ SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR); -+ } -+#endif -+ } -+ return eError; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysDevicePrePowerState -+ -+ @Description Perform system level processing required before a device power -+ transition -+ -+ @Input ui32DeviceIndex : -+ @Input eNewPowerState : -+ @Input eCurrentPowerState : -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR SysDevicePrePowerState(IMG_UINT32 ui32DeviceIndex, -+ PVRSRV_DEV_POWER_STATE eNewPowerState, -+ PVRSRV_DEV_POWER_STATE eCurrentPowerState) -+{ -+ PVR_UNREFERENCED_PARAMETER(eCurrentPowerState); -+ -+ if (ui32DeviceIndex != gui32SGXDeviceID) -+ { -+ return PVRSRV_OK; -+ } -+ -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ if (eNewPowerState == PVRSRV_DEV_POWER_STATE_OFF) -+ { -+ PVR_DPF((PVR_DBG_MESSAGE, "SysDevicePrePowerState: SGX Entering state D3")); -+ DisableSGXClocks(gpsSysData); -+ } -+#else /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ PVR_UNREFERENCED_PARAMETER(eNewPowerState ); -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function SysDevicePostPowerState -+ -+ @Description Perform system level processing required after a device power -+ transition -+ -+ @Input ui32DeviceIndex : -+ @Input eNewPowerState : -+ @Input eCurrentPowerState : -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR SysDevicePostPowerState(IMG_UINT32 ui32DeviceIndex, -+ PVRSRV_DEV_POWER_STATE eNewPowerState, -+ PVRSRV_DEV_POWER_STATE eCurrentPowerState) -+{ -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ -+ PVR_UNREFERENCED_PARAMETER(eNewPowerState); -+ -+ if (ui32DeviceIndex != gui32SGXDeviceID) -+ { -+ return eError; -+ } -+ -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ if (eCurrentPowerState == PVRSRV_DEV_POWER_STATE_OFF) -+ { -+ PVR_DPF((PVR_DBG_MESSAGE, "SysDevicePostPowerState: SGX Leaving state D3")); -+ eError = EnableSGXClocksWrap(gpsSysData); -+ } -+#else /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ PVR_UNREFERENCED_PARAMETER(eCurrentPowerState); -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ -+ return eError; -+} -+ -+#if defined(SYS_SUPPORTS_SGX_IDLE_CALLBACK) -+ -+IMG_VOID SysSGXIdleTransition(IMG_BOOL bSGXIdle) -+{ -+ PVR_DPF((PVR_DBG_MESSAGE, "SysSGXIdleTransition switch to %u", bSGXIdle)); -+} -+ -+#endif /* defined(SYS_SUPPORTS_SGX_IDLE_CALLBACK) */ -+ -+/***************************************************************************** -+ @Function SysOEMFunction -+ -+ @Description marshalling function for custom OEM functions -+ -+ @Input ui32ID - function ID -+ @Input pvIn - in data -+ @Output pvOut - out data -+ -+ @Return PVRSRV_ERROR -+*****************************************************************************/ -+PVRSRV_ERROR SysOEMFunction ( IMG_UINT32 ui32ID, -+ IMG_VOID *pvIn, -+ IMG_UINT32 ulInSize, -+ IMG_VOID *pvOut, -+ IMG_UINT32 ulOutSize) -+{ -+ PVR_UNREFERENCED_PARAMETER(ui32ID); -+ PVR_UNREFERENCED_PARAMETER(pvIn); -+ PVR_UNREFERENCED_PARAMETER(ulInSize); -+ PVR_UNREFERENCED_PARAMETER(pvOut); -+ PVR_UNREFERENCED_PARAMETER(ulOutSize); -+ -+ if ((ui32ID == OEM_GET_EXT_FUNCS) && -+ (ulOutSize == sizeof(PVRSRV_DC_OEM_JTABLE))) -+ { -+ PVRSRV_DC_OEM_JTABLE *psOEMJTable = (PVRSRV_DC_OEM_JTABLE*) pvOut; -+ psOEMJTable->pfnOEMBridgeDispatch = &PVRSRV_BridgeDispatchKM; -+ return PVRSRV_OK; -+ } -+ -+ return PVRSRV_ERROR_INVALID_PARAMS; -+} -+/****************************************************************************** -+ End of file (sysconfig.c) -+******************************************************************************/ -diff --git a/drivers/staging/ti-es8-sgx/services4/system/ti43xx/sysconfig.h b/drivers/staging/ti-es8-sgx/services4/system/ti43xx/sysconfig.h -new file mode 100644 -index 0000000..295984c ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/ti43xx/sysconfig.h -@@ -0,0 +1,109 @@ -+/*************************************************************************/ /*! -+@Title System Description Header -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description This header provides system-specific declarations and macros -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#if !defined(__SOCCONFIG_H__) -+#define __SOCCONFIG_H__ -+ -+#define VS_PRODUCT_NAME "TI43xx" -+ -+ -+#define SYS_SGX_HWRECOVERY_TIMEOUT_FREQ (100) // 10ms (100hz) -+#define SYS_SGX_PDS_TIMER_FREQ (1000) // 1ms (1000hz) -+ -+/* Allow the AP latency to be overridden in the build config */ -+#if !defined(SYS_SGX_ACTIVE_POWER_LATENCY_MS) -+#define SYS_SGX_ACTIVE_POWER_LATENCY_MS (2) -+#endif -+ -+ -+#define SYS_TI43xx_SGX_REGS_SYS_PHYS_BASE 0x56000000 -+#define SYS_TI43xx_SGX_REGS_SIZE 0x1000000 -+ -+#define SYS_TI43xx_SGX_IRQ 37 /* OMAP4 IRQ's are offset by 32 */ -+ -+#define SYS_OMAP_DSS_REGS_SYS_PHYS_BASE 0x58000000 -+#define SYS_OMAP_DSS_REGS_SIZE 0x7000 -+ -+#define SYS_OMAP_DSS_HDMI_INTERRUPT_STATUS_REG 0x6028 -+#define SYS_OMAP_DSS_HDMI_INTERRUPT_ENABLE_REG 0x602c -+ -+#define SYS_OMAP_DSS_HDMI_INTERRUPT_VSYNC_ENABLE_MASK 0x10000 -+#define SYS_OMAP_DSS_HDMI_INTERRUPT_VSYNC_STATUS_MASK 0x10000 -+ -+#define SYS_OMAP_DSS_LCD_INTERRUPT_STATUS_REG 0x1018 -+#define SYS_OMAP_DSS_LCD_INTERRUPT_ENABLE_REG 0x101c -+ -+#define SYS_OMAP_DSS_LCD_INTERRUPT_VSYNC_ENABLE_MASK 0x40002 -+#define SYS_OMAP_DSS_LCD_INTERRUPT_VSYNC_STATUS_MASK 0x40002 -+ -+ -+#define SYS_TI43xx_GP7TIMER_ENABLE_SYS_PHYS_BASE 0x4804A038 -+#define SYS_TI43xx_GP7TIMER_REGS_SYS_PHYS_BASE 0x4804A03C -+#define SYS_TI43xx_GP7TIMER_TSICR_SYS_PHYS_BASE 0x4804A054 -+ -+ -+ -+/* Interrupt bits */ -+#define DEVICE_SGX_INTERRUPT (1<<0) -+#define DEVICE_MSVDX_INTERRUPT (1<<1) -+#define DEVICE_DISP_INTERRUPT (1<<2) -+ -+#if 0 -+#if defined(__linux__) -+/* -+ * Recent OMAP4 kernels register SGX as platform device "omap_gpu". -+ * This device must be used with the Linux power management calls -+ * in sysutils_linux.c, in order for SGX to be powered on. -+ */ -+#if defined(PVR_LDM_PLATFORM_PRE_REGISTERED_DEV) -+#define SYS_SGX_DEV_NAME PVR_LDM_PLATFORM_PRE_REGISTERED_DEV -+#else -+#define SYS_SGX_DEV_NAME "omap_gpu" -+#endif /* defined(PVR_LDM_PLATFORM_PRE_REGISTERED_DEV) */ -+#endif /* defined(__linux__) */ -+#endif -+ -+/***************************************************************************** -+ * system specific data structures -+ *****************************************************************************/ -+ -+#endif /* __SYSCONFIG_H__ */ -diff --git a/drivers/staging/ti-es8-sgx/services4/system/ti43xx/sysinfo.h b/drivers/staging/ti-es8-sgx/services4/system/ti43xx/sysinfo.h -new file mode 100644 -index 0000000..7383b9c ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/ti43xx/sysinfo.h -@@ -0,0 +1,70 @@ -+/*************************************************************************/ /*! -+@Title System Description Header -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description This header provides system-specific declarations and macros -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#if !defined(__SYSINFO_H__) -+#define __SYSINFO_H__ -+ -+#if defined(SGX540) && (SGX_CORE_REV == 120) -+#define SYS_SGX_CLOCK_SPEED 307200000 -+#else -+#define SYS_SGX_CLOCK_SPEED 200000000 -+#endif -+ -+/*!< System specific poll/timeout details */ -+#if defined(PVR_LINUX_USING_WORKQUEUES) -+/* -+ * The workqueue based 3rd party display driver may be blocked for up -+ * to 500ms waiting for a vsync when the screen goes blank, so we -+ * need to wait longer for the hardware if a flush of the swap chain is -+ * required. -+ */ -+#define MAX_HW_TIME_US (1000000) -+#define WAIT_TRY_COUNT (20000) -+#else -+#define MAX_HW_TIME_US (500000) -+#define WAIT_TRY_COUNT (10000) -+#endif -+ -+ -+#define SYS_DEVICE_COUNT 15 /* SGX, DISPLAYCLASS (external), BUFFERCLASS (external) */ -+ -+#endif /* __SYSINFO_H__ */ -diff --git a/drivers/staging/ti-es8-sgx/services4/system/ti43xx/syslocal.h b/drivers/staging/ti-es8-sgx/services4/system/ti43xx/syslocal.h -new file mode 100644 -index 0000000..7062722 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/ti43xx/syslocal.h -@@ -0,0 +1,264 @@ -+/*************************************************************************/ /*! -+@Title Local system definitions -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description This header provides local system declarations and macros -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+#if !defined(__SYSLOCAL_H__) -+#define __SYSLOCAL_H__ -+ -+#if defined(__linux__) -+ -+#include <linux/version.h> -+#include <linux/clk.h> -+#if defined(PVR_LINUX_USING_WORKQUEUES) -+#include <linux/mutex.h> -+#else -+#include <linux/spinlock.h> -+#endif -+#include <asm/atomic.h> -+ -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)) -+#include <linux/semaphore.h> -+#include <linux/resource.h> -+#else /* (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)) */ -+#include <asm/semaphore.h> -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22)) -+#include <asm/arch/resource.h> -+#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22)) */ -+#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)) */ -+ -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) -+#if !defined(LDM_PLATFORM) -+#error "LDM_PLATFORM must be set" -+#endif -+#define PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO -+#include <linux/platform_device.h> -+#endif -+ -+#if ((defined(DEBUG) || defined(TIMING)) && \ -+ (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32))) && \ -+ !defined(PVR_NO_OMAP_TIMER) -+/* -+ * We need to explicitly enable the GPTIMER11 clocks, or we'll get an -+ * abort when we try to access the timer registers. -+ */ -+#define PVR_OMAP4_TIMING_PRCM -+#endif -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) -+//#include <plat/gpu.h> -+#if !defined(PVR_NO_OMAP_TIMER) -+//#define PVR_OMAP_USE_DM_TIMER_API -+//#include <plat/dmtimer.h> -+#endif -+#endif -+ -+#if !defined(PVR_NO_OMAP_TIMER) -+//#define PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA -+#endif -+#endif /* defined(__linux__) */ -+ -+#if !defined(NO_HARDWARE) && \ -+ defined(SYS_USING_INTERRUPTS) && \ -+ defined(SGX540) -+#define SGX_OCP_REGS_ENABLED -+#endif -+ -+#if defined(__linux__) -+#if defined(SGX_OCP_REGS_ENABLED) -+/* FIXME: Temporary workaround for OMAP4470 and active power off in 4430 */ -+#if !defined(SGX544) && defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+//#define SGX_OCP_NO_INT_BYPASS -+#endif -+#endif -+#endif -+ -+#if defined (__cplusplus) -+extern "C" { -+#endif -+ -+/***************************************************************************** -+ * system specific data structures -+ *****************************************************************************/ -+ -+/***************************************************************************** -+ * system specific function prototypes -+ *****************************************************************************/ -+ -+IMG_VOID DisableSystemClocks(SYS_DATA *psSysData); -+PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData); -+ -+IMG_VOID DisableSGXClocks(SYS_DATA *psSysData); -+PVRSRV_ERROR EnableSGXClocks(SYS_DATA *psSysData); -+ -+/* -+ * Various flags to indicate what has been initialised, and what -+ * has been temporarily deinitialised for power management purposes. -+ */ -+#define SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS 0x00000001 -+#define SYS_SPECIFIC_DATA_ENABLE_LISR 0x00000002 -+#define SYS_SPECIFIC_DATA_ENABLE_MISR 0x00000004 -+#define SYS_SPECIFIC_DATA_ENABLE_ENVDATA 0x00000008 -+#define SYS_SPECIFIC_DATA_ENABLE_LOCDEV 0x00000010 -+#define SYS_SPECIFIC_DATA_ENABLE_REGDEV 0x00000020 -+#define SYS_SPECIFIC_DATA_ENABLE_PDUMPINIT 0x00000040 -+#define SYS_SPECIFIC_DATA_ENABLE_INITDEV 0x00000080 -+#define SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV 0x00000100 -+ -+#define SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR 0x00000200 -+#define SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS 0x00000400 -+#define SYS_SPECIFIC_DATA_ENABLE_OCPREGS 0x00000800 -+#define SYS_SPECIFIC_DATA_ENABLE_PM_RUNTIME 0x00001000 -+#define SYS_SPECIFIC_DATA_IRQ_ENABLED 0x00002000 -+#define SYS_SPECIFIC_DATA_DVFS_INIT 0x00004000 -+ -+#define SYS_SPECIFIC_DATA_SET(psSysSpecData, flag) ((IMG_VOID)((psSysSpecData)->ui32SysSpecificData |= (flag))) -+ -+#define SYS_SPECIFIC_DATA_CLEAR(psSysSpecData, flag) ((IMG_VOID)((psSysSpecData)->ui32SysSpecificData &= ~(flag))) -+ -+#define SYS_SPECIFIC_DATA_TEST(psSysSpecData, flag) (((psSysSpecData)->ui32SysSpecificData & (flag)) != 0) -+ -+typedef struct _SYS_SPECIFIC_DATA_TAG_ -+{ -+ IMG_UINT32 ui32SysSpecificData; -+ PVRSRV_DEVICE_NODE *psSGXDevNode; -+ IMG_BOOL bSGXInitComplete; -+#if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA) -+ IMG_CPU_PHYADDR sTimerRegPhysBase; -+#endif -+#if !defined(__linux__) -+ IMG_BOOL bSGXClocksEnabled; -+#endif -+ IMG_UINT32 ui32SrcClockDiv; -+#if defined(__linux__) -+ IMG_BOOL bSysClocksOneTimeInit; -+ atomic_t sSGXClocksEnabled; -+#if defined(PVR_LINUX_USING_WORKQUEUES) -+ struct mutex sPowerLock; -+#else -+ IMG_BOOL bConstraintNotificationsEnabled; -+ spinlock_t sPowerLock; -+ atomic_t sPowerLockCPU; -+ spinlock_t sNotifyLock; -+ atomic_t sNotifyLockCPU; -+ IMG_BOOL bCallVDD2PostFunc; -+#endif -+ struct clk *psCORE_CK; -+ struct clk *psSGX_FCK; -+ struct clk *psSGX_ICK; -+ -+#if defined(DEBUG) || defined(TIMING) -+ struct clk *psGPT11_FCK; -+ struct clk *psGPT11_ICK; -+#endif -+#if defined(PVR_OMAP_USE_DM_TIMER_API) -+ struct omap_dm_timer *psGPTimer; -+#endif -+ IMG_UINT32 ui32SGXFreqListSize; -+ IMG_UINT32 *pui32SGXFreqList; -+ IMG_UINT32 ui32SGXFreqListIndex; -+#endif /* defined(__linux__) */ -+} SYS_SPECIFIC_DATA; -+ -+extern SYS_SPECIFIC_DATA *gpsSysSpecificData; -+ -+#if defined(SGX_OCP_REGS_ENABLED) && defined(SGX_OCP_NO_INT_BYPASS) -+IMG_VOID SysEnableSGXInterrupts(SYS_DATA* psSysData); -+IMG_VOID SysDisableSGXInterrupts(SYS_DATA* psSysData); -+#else -+#define SysEnableSGXInterrupts(psSysData) -+#define SysDisableSGXInterrupts(psSysData) -+#endif -+ -+#if defined(SYS_CUSTOM_POWERLOCK_WRAP) -+IMG_BOOL WrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData); -+IMG_VOID UnwrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData); -+#endif -+ -+#if defined(__linux__) -+ -+PVRSRV_ERROR SysPMRuntimeRegister(void); -+PVRSRV_ERROR SysPMRuntimeUnregister(void); -+ -+PVRSRV_ERROR SysDvfsInitialize(SYS_SPECIFIC_DATA *psSysSpecificData); -+PVRSRV_ERROR SysDvfsDeinitialize(SYS_SPECIFIC_DATA *psSysSpecificData); -+ -+#else /* defined(__linux__) */ -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(SysPMRuntimeRegister) -+#endif -+static INLINE PVRSRV_ERROR SysPMRuntimeRegister(void) -+{ -+ return PVRSRV_OK; -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(SysPMRuntimeUnregister) -+#endif -+static INLINE PVRSRV_ERROR SysPMRuntimeUnregister(void) -+{ -+ return PVRSRV_OK; -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(SysDvfsInitialize) -+#endif -+static INLINE PVRSRV_ERROR SysDvfsInitialize(void) -+{ -+ return PVRSRV_OK; -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(SysDvfsDeinitialize) -+#endif -+static INLINE PVRSRV_ERROR SysDvfsDeinitialize(void) -+{ -+ return PVRSRV_OK; -+} -+ -+#endif /* defined(__linux__) */ -+ -+#if defined(__cplusplus) -+} -+#endif -+ -+#endif /* __SYSLOCAL_H__ */ -diff --git a/drivers/staging/ti-es8-sgx/services4/system/ti43xx/sysutils.c b/drivers/staging/ti-es8-sgx/services4/system/ti43xx/sysutils.c -new file mode 100644 -index 0000000..6725421 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/ti43xx/sysutils.c -@@ -0,0 +1,47 @@ -+/*************************************************************************/ /*! -+@Title Shared (User/kernel) and System dependent utilities -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Provides system-specific functions -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+ -+/* Pull in the correct system dependent sysutils source */ -+ -+#if defined(__linux__) -+#include "sysutils_linux.c" -+#endif -diff --git a/drivers/staging/ti-es8-sgx/services4/system/ti43xx/sysutils_linux.c b/drivers/staging/ti-es8-sgx/services4/system/ti43xx/sysutils_linux.c -new file mode 100644 -index 0000000..e38dd46 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/ti43xx/sysutils_linux.c -@@ -0,0 +1,982 @@ -+/*************************************************************************/ /*! -+@Title System dependent utilities -+@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved -+@Description Provides system-specific functions -+@License Dual MIT/GPLv2 -+ -+The contents of this file are subject to the MIT license as set out below. -+ -+Permission is hereby granted, free of charge, to any person obtaining a copy -+of this software and associated documentation files (the "Software"), to deal -+in the Software without restriction, including without limitation the rights -+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -+copies of the Software, and to permit persons to whom the Software is -+furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included in -+all copies or substantial portions of the Software. -+ -+Alternatively, the contents of this file may be used under the terms of -+the GNU General Public License Version 2 ("GPL") in which case the provisions -+of GPL are applicable instead of those above. -+ -+If you wish to allow use of your version of this file only under the terms of -+GPL, and not to allow others to use your version of this file under the terms -+of the MIT license, indicate your decision by deleting the provisions above -+and replace them with the notice and other provisions required by GPL as set -+out in the file called "GPL-COPYING" included in this distribution. If you do -+not delete the provisions above, a recipient may use your version of this file -+under the terms of either the MIT license or GPL. -+ -+This License is also included in this distribution in the file called -+"MIT-COPYING". -+ -+EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS -+PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -+BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -+PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR -+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+*/ /**************************************************************************/ -+#include <linux/version.h> -+#include <linux/clk.h> -+#include <linux/err.h> -+#include <linux/hardirq.h> -+#include <linux/mutex.h> -+#include <linux/slab.h> -+ -+#include "sgxdefs.h" -+#include "services_headers.h" -+#include "sysinfo.h" -+#include "sgxapi_km.h" -+#include "sysconfig.h" -+#include "sgxinfokm.h" -+#include "syslocal.h" -+ -+#include <linux/platform_device.h> -+#include <linux/pm_runtime.h> -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)) -+#include <linux/reset.h> -+#endif -+ -+#if defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) -+#include <linux/opp.h> -+#endif -+ -+#if defined(SUPPORT_DRI_DRM_PLUGIN) -+#include <drm/drmP.h> -+#include <drm/drm.h> -+ -+#include <linux/omap_gpu.h> -+ -+#include "pvr_drm.h" -+#endif -+ -+#define ONE_MHZ 1000000 -+#define HZ_TO_MHZ(m) ((m) / ONE_MHZ) -+ -+#if defined(SUPPORT_OMAP3430_SGXFCLK_96M) -+#define SGX_PARENT_CLOCK "cm_96m_fck" -+#else -+#define SGX_PARENT_CLOCK "core_ck" -+#endif -+ -+#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) -+extern struct platform_device *gpsPVRLDMDev; -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)) -+extern struct reset_control *rstc; -+extern bool already_deasserted; -+#endif -+#endif -+ -+static PVRSRV_ERROR PowerLockWrap(SYS_SPECIFIC_DATA *psSysSpecData, IMG_BOOL bTryLock) -+{ -+ if (!in_interrupt()) -+ { -+ if (bTryLock) -+ { -+ int locked = mutex_trylock(&psSysSpecData->sPowerLock); -+ if (locked == 0) -+ { -+ return PVRSRV_ERROR_RETRY; -+ } -+ } -+ else -+ { -+ mutex_lock(&psSysSpecData->sPowerLock); -+ } -+ } -+ -+ return PVRSRV_OK; -+} -+ -+static IMG_VOID PowerLockUnwrap(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ if (!in_interrupt()) -+ { -+ mutex_unlock(&psSysSpecData->sPowerLock); -+ } -+} -+ -+PVRSRV_ERROR SysPowerLockWrap(IMG_BOOL bTryLock) -+{ -+ SYS_DATA *psSysData; -+ -+ SysAcquireData(&psSysData); -+ -+ return PowerLockWrap(psSysData->pvSysSpecificData, bTryLock); -+} -+ -+IMG_VOID SysPowerLockUnwrap(IMG_VOID) -+{ -+ SYS_DATA *psSysData; -+ -+ SysAcquireData(&psSysData); -+ -+ PowerLockUnwrap(psSysData->pvSysSpecificData); -+} -+ -+/* -+ * This function should be called to unwrap the Services power lock, prior -+ * to calling any function that might sleep. -+ * This function shouldn't be called prior to calling EnableSystemClocks -+ * or DisableSystemClocks, as those functions perform their own power lock -+ * unwrapping. -+ * If the function returns IMG_TRUE, UnwrapSystemPowerChange must be -+ * called to rewrap the power lock, prior to returning to Services. -+ */ -+IMG_BOOL WrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ return IMG_TRUE; -+} -+ -+IMG_VOID UnwrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+} -+ -+/* -+ * Return SGX timining information to caller. -+ */ -+IMG_VOID SysGetSGXTimingInformation(SGX_TIMING_INFORMATION *psTimingInfo) -+{ -+#if !defined(NO_HARDWARE) -+ PVR_ASSERT(atomic_read(&gpsSysSpecificData->sSGXClocksEnabled) != 0); -+#endif -+#if defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) -+ psTimingInfo->ui32CoreClockSpeed = -+ gpsSysSpecificData->pui32SGXFreqList[gpsSysSpecificData->ui32SGXFreqListIndex]; -+#else /* defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) */ -+ psTimingInfo->ui32CoreClockSpeed = SYS_SGX_CLOCK_SPEED; -+#endif -+ psTimingInfo->ui32HWRecoveryFreq = SYS_SGX_HWRECOVERY_TIMEOUT_FREQ; -+ psTimingInfo->ui32uKernelFreq = SYS_SGX_PDS_TIMER_FREQ; -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ psTimingInfo->bEnableActivePM = IMG_TRUE; -+#else -+ psTimingInfo->bEnableActivePM = IMG_FALSE; -+#endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ -+ psTimingInfo->ui32ActivePowManLatencyms = SYS_SGX_ACTIVE_POWER_LATENCY_MS; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function EnableSGXClocks -+ -+ @Description Enable SGX clocks -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR EnableSGXClocks(SYS_DATA *psSysData) -+{ -+#if !defined(NO_HARDWARE) -+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; -+#if !defined(PM_RUNTIME_SUPPORT) -+ IMG_INT res; -+ long lRate,lNewRate; -+#endif -+ /* SGX clocks already enabled? */ -+ if (atomic_read(&psSysSpecData->sSGXClocksEnabled) != 0) -+ { -+ return PVRSRV_OK; -+ } -+ -+#if !defined(PM_RUNTIME_SUPPORT) -+ PVR_DPF((PVR_DBG_MESSAGE, "EnableSGXClocks: Enabling SGX Clocks")); -+ res=clk_enable(psSysSpecData->psSGX_FCK); -+ if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Couldn't enable SGX functional clock (%d)", res)); -+ return PVRSRV_ERROR_UNABLE_TO_ENABLE_CLOCK; -+ } -+ -+ lNewRate = clk_round_rate(psSysSpecData->psSGX_FCK, SYS_SGX_CLOCK_SPEED + ONE_MHZ); -+ if (lNewRate <= 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Couldn't round SGX functional clock rate")); -+ return PVRSRV_ERROR_UNABLE_TO_ROUND_CLOCK_RATE; -+ } -+ -+ -+ lRate = clk_get_rate(psSysSpecData->psSGX_FCK); -+ if (lRate != lNewRate) -+ { -+ res = clk_set_rate(psSysSpecData->psSGX_FCK, lNewRate); -+ if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_WARNING, "EnableSGXClocks: Couldn't set SGX functional clock rate (%d)", res)); -+ return PVRSRV_ERROR_UNABLE_TO_SET_CLOCK_RATE; -+ } -+ } -+ -+#if defined(DEBUG) -+ { -+ IMG_UINT32 rate = clk_get_rate(psSysSpecData->psSGX_FCK); -+ PVR_DPF((PVR_DBG_MESSAGE, "EnableSGXClocks: SGX Functional Clock is %dMhz", HZ_TO_MHZ(rate))); -+ } -+#endif -+#endif -+#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) -+#if defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) -+ { -+ struct gpu_platform_data *pdata; -+ IMG_UINT32 max_freq_index; -+ int res; -+ -+ pdata = (struct gpu_platform_data *)gpsPVRLDMDev->dev.platform_data; -+ max_freq_index = psSysSpecData->ui32SGXFreqListSize - 2; -+ -+ /* -+ * Request maximum frequency from DVFS layer if not already set. DVFS may -+ * report busy if early in initialization, but all other errors are -+ * considered serious. Upon any error we proceed assuming our safe frequency -+ * value to be in use as indicated by the "unknown" index. -+ */ -+ if (psSysSpecData->ui32SGXFreqListIndex != max_freq_index) -+ { -+ PVR_ASSERT(pdata->device_scale != IMG_NULL); -+ res = pdata->device_scale(&gpsPVRLDMDev->dev, -+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3,4,0)) -+ &gpsPVRLDMDev->dev, -+#endif -+ psSysSpecData->pui32SGXFreqList[max_freq_index]); -+ if (res == 0) -+ { -+ psSysSpecData->ui32SGXFreqListIndex = max_freq_index; -+ } -+ else if (res == -EBUSY) -+ { -+ PVR_DPF((PVR_DBG_WARNING, "EnableSGXClocks: Unable to scale SGX frequency (EBUSY)")); -+ psSysSpecData->ui32SGXFreqListIndex = psSysSpecData->ui32SGXFreqListSize - 1; -+ } -+ else if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Unable to scale SGX frequency (%d)", res)); -+ psSysSpecData->ui32SGXFreqListIndex = psSysSpecData->ui32SGXFreqListSize - 1; -+ } -+ } -+ } -+#endif /* defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) */ -+ { -+ /* -+ * pm_runtime_get_sync returns 1 after the module has -+ * been reloaded. -+ */ -+#if defined(PM_RUNTIME_SUPPORT) -+ -+ int res = pm_runtime_get_sync(&gpsPVRLDMDev->dev); -+ if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: pm_runtime_get_sync failed (%d)", -res)); -+ return PVRSRV_ERROR_UNABLE_TO_ENABLE_CLOCK; -+ } -+ if (!already_deasserted) -+ { -+ int ret = reset_control_is_reset(rstc); -+ if (ret <= 0) -+ { -+ PVR_DPF((PVR_DBG_MESSAGE, "reset control reset")); -+ } -+ } -+ reset_control_put(rstc); -+ -+#endif -+ } -+#endif /* defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) */ -+ -+ SysEnableSGXInterrupts(psSysData); -+ -+ /* Indicate that the SGX clocks are enabled */ -+ atomic_set(&psSysSpecData->sSGXClocksEnabled, 1); -+ -+#else /* !defined(NO_HARDWARE) */ -+ PVR_UNREFERENCED_PARAMETER(psSysData); -+#endif /* !defined(NO_HARDWARE) */ -+ return PVRSRV_OK; -+} -+ -+ -+/*! -+****************************************************************************** -+ -+ @Function DisableSGXClocks -+ -+ @Description Disable SGX clocks. -+ -+ @Return none -+ -+******************************************************************************/ -+IMG_VOID DisableSGXClocks(SYS_DATA *psSysData) -+{ -+#if !defined(NO_HARDWARE) -+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; -+ -+ /* SGX clocks already disabled? */ -+ if (atomic_read(&psSysSpecData->sSGXClocksEnabled) == 0) -+ { -+ return; -+ } -+ -+ PVR_DPF((PVR_DBG_MESSAGE, "DisableSGXClocks: Disabling SGX Clocks")); -+#if !defined(PM_RUNTIME_SUPPORT) -+ clk_disable(psSysSpecData->psSGX_FCK); -+#endif -+ SysDisableSGXInterrupts(psSysData); -+ -+#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) -+ { -+#if defined(PM_RUNTIME_SUPPORT) -+ -+ int res = pm_runtime_put_sync(&gpsPVRLDMDev->dev); -+ if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "DisableSGXClocks: pm_runtime_put_sync failed (%d)", -res)); -+ } -+#endif -+ } -+#if defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) -+ { -+ struct gpu_platform_data *pdata; -+ int res; -+ -+ pdata = (struct gpu_platform_data *)gpsPVRLDMDev->dev.platform_data; -+ -+ /* -+ * Request minimum frequency (list index 0) from DVFS layer if not already -+ * set. DVFS may report busy if early in initialization, but all other errors -+ * are considered serious. Upon any error we proceed assuming our safe frequency -+ * value to be in use as indicated by the "unknown" index. -+ */ -+ if (psSysSpecData->ui32SGXFreqListIndex != 0) -+ { -+ PVR_ASSERT(pdata->device_scale != IMG_NULL); -+ res = pdata->device_scale(&gpsPVRLDMDev->dev, -+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3,4,0)) -+ &gpsPVRLDMDev->dev, -+#endif -+ psSysSpecData->pui32SGXFreqList[0]); -+ if (res == 0) -+ { -+ psSysSpecData->ui32SGXFreqListIndex = 0; -+ } -+ else if (res == -EBUSY) -+ { -+ PVR_DPF((PVR_DBG_WARNING, "DisableSGXClocks: Unable to scale SGX frequency (EBUSY)")); -+ psSysSpecData->ui32SGXFreqListIndex = psSysSpecData->ui32SGXFreqListSize - 1; -+ } -+ else if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "DisableSGXClocks: Unable to scale SGX frequency (%d)", res)); -+ psSysSpecData->ui32SGXFreqListIndex = psSysSpecData->ui32SGXFreqListSize - 1; -+ } -+ } -+ } -+#endif /* defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) */ -+#endif /* defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) */ -+ -+ /* Indicate that the SGX clocks are disabled */ -+ atomic_set(&psSysSpecData->sSGXClocksEnabled, 0); -+ -+#else /* !defined(NO_HARDWARE) */ -+ PVR_UNREFERENCED_PARAMETER(psSysData); -+#endif /* !defined(NO_HARDWARE) */ -+} -+ -+#if (defined(DEBUG) || defined(TIMING)) && !defined(PVR_NO_OMAP_TIMER) -+#if defined(PVR_OMAP_USE_DM_TIMER_API) -+#define GPTIMER_TO_USE 11 -+/*! -+****************************************************************************** -+ -+ @Function AcquireGPTimer -+ -+ @Description Acquire a GP timer -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+static PVRSRV_ERROR AcquireGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ PVR_ASSERT(psSysSpecData->psGPTimer == NULL); -+ -+ /* -+ * This code has problems on module reload for OMAP5 running Linux -+ * 3.4.10, due to omap2_dm_timer_set_src (called by -+ * omap_dm_timer_request_specific), being unable to set the parent -+ * clock to OMAP_TIMER_SRC_32_KHZ. -+ * Not calling omap_dm_timer_set_source doesn't help. -+ */ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) || !defined(MODULE) -+ /* -+ * This code could try requesting registers 9, 10, and 11, -+ * stopping at the first succesful request. We'll stick with -+ * 11 for now, as it avoids having to hard code yet more -+ * physical addresses into the code. -+ */ -+ psSysSpecData->psGPTimer = omap_dm_timer_request_specific(GPTIMER_TO_USE); -+ if (psSysSpecData->psGPTimer == NULL) -+ { -+ -+ PVR_DPF((PVR_DBG_WARNING, "%s: omap_dm_timer_request_specific failed", __FUNCTION__)); -+ return PVRSRV_ERROR_CLOCK_REQUEST_FAILED; -+ } -+ -+ omap_dm_timer_set_source(psSysSpecData->psGPTimer, OMAP_TIMER_SRC_SYS_CLK); -+ omap_dm_timer_enable(psSysSpecData->psGPTimer); -+ -+ /* Set autoreload, and start value of 0 */ -+ omap_dm_timer_set_load_start(psSysSpecData->psGPTimer, 1, 0); -+ -+ omap_dm_timer_start(psSysSpecData->psGPTimer); -+ -+ /* -+ * The DM timer API doesn't have a mechanism for obtaining the -+ * physical address of the counter register. -+ */ -+ psSysSpecData->sTimerRegPhysBase.uiAddr = SYS_TI43xx_GP7TIMER_REGS_SYS_PHYS_BASE; -+#else /* (LINUX_VERSION_CODE <= KERNEL_VERSION(3,4,0)) || !defined(MODULE) */ -+ (void)psSysSpecData; -+#endif /* (LINUX_VERSION_CODE <= KERNEL_VERSION(3,4,0)) || !defined(MODULE) */ -+ -+ return PVRSRV_OK; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function ReleaseGPTimer -+ -+ @Description Release a GP timer -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+static void ReleaseGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ if (psSysSpecData->psGPTimer != NULL) -+ { -+ /* Always returns 0 */ -+ (void) omap_dm_timer_stop(psSysSpecData->psGPTimer); -+ -+ omap_dm_timer_disable(psSysSpecData->psGPTimer); -+ -+ omap_dm_timer_free(psSysSpecData->psGPTimer); -+ -+ psSysSpecData->sTimerRegPhysBase.uiAddr = 0; -+ -+ psSysSpecData->psGPTimer = NULL; -+ } -+ -+} -+#else /* PVR_OMAP_USE_DM_TIMER_API */ -+/*! -+****************************************************************************** -+ -+ @Function AcquireGPTimer -+ -+ @Description Acquire a GP timer -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+static PVRSRV_ERROR AcquireGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+#if defined(PVR_OMAP4_TIMING_PRCM) -+ struct clk *psCLK; -+ IMG_INT res; -+ struct clk *sys_ck; -+ IMG_INT rate; -+#endif -+ PVRSRV_ERROR eError; -+ -+ IMG_CPU_PHYADDR sTimerRegPhysBase; -+ IMG_HANDLE hTimerEnable; -+ IMG_UINT32 *pui32TimerEnable; -+#if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA) -+ PVR_ASSERT(psSysSpecData->sTimerRegPhysBase.uiAddr == 0); -+#endif -+ -+#if defined(PVR_OMAP4_TIMING_PRCM) -+#if 0 -+ /* assert our dependence on the GPTIMER11 module */ -+ psCLK = clk_get(NULL, "gpt11_fck"); -+ if (IS_ERR(psCLK)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get GPTIMER11 functional clock")); -+ goto ExitError; -+ } -+ psSysSpecData->psGPT11_FCK = psCLK; -+ -+ psCLK = clk_get(NULL, "gpt11_ick"); -+ if (IS_ERR(psCLK)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get GPTIMER11 interface clock")); -+ goto ExitError; -+ } -+ psSysSpecData->psGPT11_ICK = psCLK; -+ -+ sys_ck = clk_get(NULL, "sys_ck"); -+ if (IS_ERR(sys_ck)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get System clock")); -+ goto ExitError; -+ } -+ -+ if(clk_get_parent(psSysSpecData->psGPT11_FCK) != sys_ck) -+ { -+ PVR_TRACE(("Setting GPTIMER11 parent to System Clock")); -+ res = clk_set_parent(psSysSpecData->psGPT11_FCK, sys_ck); -+ if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't set GPTIMER11 parent clock (%d)", res)); -+ goto ExitError; -+ } -+ } -+ -+ rate = clk_get_rate(psSysSpecData->psGPT11_FCK); -+ PVR_TRACE(("GPTIMER11 clock is %dMHz", HZ_TO_MHZ(rate))); -+ -+ res = clk_enable(psSysSpecData->psGPT11_FCK); -+ if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't enable GPTIMER11 functional clock (%d)", res)); -+ goto ExitError; -+ } -+ -+ res = clk_enable(psSysSpecData->psGPT11_ICK); -+ if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't enable GPTIMER11 interface clock (%d)", res)); -+ goto ExitDisableGPT11FCK; -+ } -+#endif -+#endif /* defined(PVR_OMAP4_TIMING_PRCM) */ -+ -+ /* Set the timer to non-posted mode */ -+ sTimerRegPhysBase.uiAddr = SYS_TI43xx_GP7TIMER_TSICR_SYS_PHYS_BASE; -+ pui32TimerEnable = OSMapPhysToLin(sTimerRegPhysBase, -+ 4, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ &hTimerEnable); -+ -+ if (pui32TimerEnable == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: OSMapPhysToLin failed")); -+ goto ExitDisableGPT11ICK; -+ } -+ -+ if(!(*pui32TimerEnable & 4)) -+ { -+ PVR_TRACE(("Setting GPTIMER11 mode to posted (currently is non-posted)")); -+ -+ /* Set posted mode */ -+ *pui32TimerEnable |= 4; -+ } -+ -+ OSUnMapPhysToLin(pui32TimerEnable, -+ 4, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ hTimerEnable); -+ -+ /* Enable the timer */ -+ sTimerRegPhysBase.uiAddr = SYS_TI43xx_GP7TIMER_ENABLE_SYS_PHYS_BASE; -+ pui32TimerEnable = OSMapPhysToLin(sTimerRegPhysBase, -+ 4, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ &hTimerEnable); -+ -+ if (pui32TimerEnable == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: OSMapPhysToLin failed")); -+ goto ExitDisableGPT11ICK; -+ } -+ -+ /* Enable and set autoreload on overflow */ -+ *pui32TimerEnable = 3; -+ -+ OSUnMapPhysToLin(pui32TimerEnable, -+ 4, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ hTimerEnable); -+#if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA) -+ psSysSpecData->sTimerRegPhysBase = sTimerRegPhysBase; -+#endif -+ eError = PVRSRV_OK; -+ -+ goto Exit; -+ -+ExitDisableGPT11ICK: -+#if defined(PVR_OMAP4_TIMING_PRCM) -+#if 0 -+ clk_disable(psSysSpecData->psGPT11_ICK); -+#endif -+ExitDisableGPT11FCK: -+#if 0 -+ clk_disable(psSysSpecData->psGPT11_FCK); -+#endif -+ExitError: -+#endif /* defined(PVR_OMAP4_TIMING_PRCM) */ -+ eError = PVRSRV_ERROR_CLOCK_REQUEST_FAILED; -+Exit: -+ return eError; -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function ReleaseGPTimer -+ -+ @Description Release a GP timer -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+static void ReleaseGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ IMG_HANDLE hTimerDisable; -+ IMG_UINT32 *pui32TimerDisable; -+ IMG_CPU_PHYADDR TimerRegPhysBase; -+#if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA) -+ if (psSysSpecData->sTimerRegPhysBase.uiAddr == 0) -+ { -+ return; -+ } -+#endif -+ /* Disable the timer */ -+ pui32TimerDisable = OSMapPhysToLin(TimerRegPhysBase, -+ 4, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ &hTimerDisable); -+ -+ if (pui32TimerDisable == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "DisableSystemClocks: OSMapPhysToLin failed")); -+ } -+ else -+ { -+ *pui32TimerDisable = 0; -+ -+ OSUnMapPhysToLin(pui32TimerDisable, -+ 4, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ hTimerDisable); -+ } -+#if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA) -+ psSysSpecData->sTimerRegPhysBase.uiAddr = 0; -+#endif -+#if defined(PVR_OMAP4_TIMING_PRCM) -+#if 0 -+ clk_disable(psSysSpecData->psGPT11_ICK); -+ -+ clk_disable(psSysSpecData->psGPT11_FCK); -+#endif -+#endif /* defined(PVR_OMAP4_TIMING_PRCM) */ -+} -+#endif /* PVR_OMAP_USE_DM_TIMER_API */ -+#else /* (DEBUG || TIMING) && !PVR_NO_OMAP_TIMER */ -+static PVRSRV_ERROR AcquireGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ PVR_UNREFERENCED_PARAMETER(psSysSpecData); -+ -+ return PVRSRV_OK; -+} -+static void ReleaseGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ PVR_UNREFERENCED_PARAMETER(psSysSpecData); -+} -+#endif /* (DEBUG || TIMING) && !PVR_NO_OMAP_TIMER */ -+ -+/*! -+****************************************************************************** -+ -+ @Function EnableSystemClocks -+ -+ @Description Setup up the clocks for the graphics device to work. -+ -+ @Return PVRSRV_ERROR -+ -+******************************************************************************/ -+PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData) -+{ -+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; -+#if !defined(PM_RUNTIME_SUPPORT) -+ struct clk *psCLK; -+ IMG_INT res; -+#endif -+ PVR_TRACE(("EnableSystemClocks: Enabling System Clocks")); -+ -+ if (!psSysSpecData->bSysClocksOneTimeInit) -+ { -+ mutex_init(&psSysSpecData->sPowerLock); -+ -+ atomic_set(&psSysSpecData->sSGXClocksEnabled, 0); -+ -+ psSysSpecData->bSysClocksOneTimeInit = IMG_TRUE; -+ -+#if !defined(PM_RUNTIME_SUPPORT) -+ psCLK = clk_get(NULL, SGX_PARENT_CLOCK); -+ if (IS_ERR(psCLK)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSsystemClocks: Couldn't get Core Clock")); -+ return PVRSRV_ERROR_UNABLE_TO_GET_PARENT_CLOCK; -+ } -+ psSysSpecData->psCORE_CK = psCLK; -+ -+ -+ psCLK = clk_get(NULL, "sgx_fck"); -+ if (IS_ERR(psCLK)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSsystemClocks: Couldn't get SGX Functional Clock")); -+ return PVRSRV_ERROR_UNABLE_TO_GET_CLOCK; -+ } -+ psSysSpecData->psSGX_FCK = psCLK; -+ -+ psCLK = clk_get(NULL, "sgx_ick"); -+ if (IS_ERR(psCLK)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get SGX Interface Clock")); -+ return PVRSRV_ERROR_UNABLE_TO_GET_CLOCK; -+ } -+ psSysSpecData->psSGX_ICK = psCLK; -+ -+ res = clk_set_parent(psSysSpecData->psSGX_FCK, psSysSpecData->psCORE_CK); -+ if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't set SGX parent clock (%d)", res)); -+ return PVRSRV_ERROR_UNABLE_TO_GET_PARENT_CLOCK; -+ } -+ -+ -+ psSysSpecData->bSysClocksOneTimeInit = IMG_TRUE; -+ -+#endif -+ } -+ -+ return AcquireGPTimer(psSysSpecData); -+} -+ -+/*! -+****************************************************************************** -+ -+ @Function DisableSystemClocks -+ -+ @Description Disable the graphics clocks. -+ -+ @Return none -+ -+******************************************************************************/ -+IMG_VOID DisableSystemClocks(SYS_DATA *psSysData) -+{ -+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; -+ -+ PVR_TRACE(("DisableSystemClocks: Disabling System Clocks")); -+ -+ /* -+ * Always disable the SGX clocks when the system clocks are disabled. -+ * This saves having to make an explicit call to DisableSGXClocks if -+ * active power management is enabled. -+ */ -+ DisableSGXClocks(psSysData); -+ -+ ReleaseGPTimer(psSysSpecData); -+} -+ -+PVRSRV_ERROR SysPMRuntimeRegister(void) -+{ -+#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) -+#if defined(PM_RUNTIME_SUPPORT) -+ pm_runtime_enable(&gpsPVRLDMDev->dev); -+#endif -+#endif -+ return PVRSRV_OK; -+} -+ -+PVRSRV_ERROR SysPMRuntimeUnregister(void) -+{ -+#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) -+#if defined(PM_RUNTIME_SUPPORT) -+ pm_runtime_disable(&gpsPVRLDMDev->dev); -+#endif -+#endif -+ return PVRSRV_OK; -+} -+ -+PVRSRV_ERROR SysDvfsInitialize(SYS_SPECIFIC_DATA *psSysSpecificData) -+{ -+#if !defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) -+ PVR_UNREFERENCED_PARAMETER(psSysSpecificData); -+#else /* !defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) */ -+ IMG_UINT32 i, *freq_list; -+ IMG_INT32 opp_count; -+ unsigned long freq; -+ struct opp *opp; -+ -+ /* -+ * We query and store the list of SGX frequencies just this once under the -+ * assumption that they are unchanging, e.g. no disabling of high frequency -+ * option for thermal management. This is currently valid for 4430 and 4460. -+ */ -+ rcu_read_lock(); -+ opp_count = opp_get_opp_count(&gpsPVRLDMDev->dev); -+ if (opp_count < 1) -+ { -+ rcu_read_unlock(); -+ PVR_DPF((PVR_DBG_ERROR, "SysDvfsInitialize: Could not retrieve opp count")); -+ return PVRSRV_ERROR_NOT_SUPPORTED; -+ } -+ -+ /* -+ * Allocate the frequency list with a slot for each available frequency plus -+ * one additional slot to hold a designated frequency value to assume when in -+ * an unknown frequency state. -+ */ -+ freq_list = kmalloc((opp_count + 1) * sizeof(IMG_UINT32), GFP_ATOMIC); -+ if (!freq_list) -+ { -+ rcu_read_unlock(); -+ PVR_DPF((PVR_DBG_ERROR, "SysDvfsInitialize: Could not allocate frequency list")); -+ return PVRSRV_ERROR_OUT_OF_MEMORY; -+ } -+ -+ /* -+ * Fill in frequency list from lowest to highest then finally the "unknown" -+ * frequency value. We use the highest available frequency as our assumed value -+ * when in an unknown state, because it is safer for APM and hardware recovery -+ * timers to be longer than intended rather than shorter. -+ */ -+ freq = 0; -+ for (i = 0; i < opp_count; i++) -+ { -+ opp = opp_find_freq_ceil(&gpsPVRLDMDev->dev, &freq); -+ if (IS_ERR_OR_NULL(opp)) -+ { -+ rcu_read_unlock(); -+ PVR_DPF((PVR_DBG_ERROR, "SysDvfsInitialize: Could not retrieve opp level %d", i)); -+ kfree(freq_list); -+ return PVRSRV_ERROR_NOT_SUPPORTED; -+ } -+ freq_list[i] = (IMG_UINT32)freq; -+ freq++; -+ } -+ rcu_read_unlock(); -+ freq_list[opp_count] = freq_list[opp_count - 1]; -+ -+ psSysSpecificData->ui32SGXFreqListSize = opp_count + 1; -+ psSysSpecificData->pui32SGXFreqList = freq_list; -+ -+ /* Start in unknown state - no frequency request to DVFS yet made */ -+ psSysSpecificData->ui32SGXFreqListIndex = opp_count; -+#endif /* !defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) */ -+ -+ return PVRSRV_OK; -+} -+ -+PVRSRV_ERROR SysDvfsDeinitialize(SYS_SPECIFIC_DATA *psSysSpecificData) -+{ -+#if !defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) -+ PVR_UNREFERENCED_PARAMETER(psSysSpecificData); -+#else /* !defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) */ -+ /* -+ * We assume this function is only called if SysDvfsInitialize() was -+ * completed successfully before. -+ * -+ * The DVFS interface does not allow us to actually unregister as a -+ * user of SGX, so we do the next best thing which is to lower our -+ * required frequency to the minimum if not already set. DVFS may -+ * report busy if early in initialization, but all other errors are -+ * considered serious. -+ */ -+ if (psSysSpecificData->ui32SGXFreqListIndex != 0) -+ { -+ struct gpu_platform_data *pdata; -+ IMG_INT32 res; -+ -+ pdata = (struct gpu_platform_data *)gpsPVRLDMDev->dev.platform_data; -+ -+ PVR_ASSERT(pdata->device_scale != IMG_NULL); -+ res = pdata->device_scale(&gpsPVRLDMDev->dev, -+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3,4,0)) -+ &gpsPVRLDMDev->dev, -+#endif -+ psSysSpecificData->pui32SGXFreqList[0]); -+ if (res == -EBUSY) -+ { -+ PVR_DPF((PVR_DBG_WARNING, "SysDvfsDeinitialize: Unable to scale SGX frequency (EBUSY)")); -+ } -+ else if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "SysDvfsDeinitialize: Unable to scale SGX frequency (%d)", res)); -+ } -+ -+ psSysSpecificData->ui32SGXFreqListIndex = 0; -+ } -+ -+ kfree(psSysSpecificData->pui32SGXFreqList); -+ psSysSpecificData->pui32SGXFreqList = 0; -+ psSysSpecificData->ui32SGXFreqListSize = 0; -+#endif /* !defined(SYS_OMAP_HAS_DVFS_FRAMEWORK) */ -+ -+ return PVRSRV_OK; -+} -+ -+#if defined(SUPPORT_DRI_DRM_PLUGIN) -+static struct omap_gpu_plugin sOMAPGPUPlugin; -+ -+#define SYS_DRM_SET_PLUGIN_FIELD(d, s, f) (d)->f = (s)->f -+int -+SysDRMRegisterPlugin(PVRSRV_DRM_PLUGIN *psDRMPlugin) -+{ -+ int iRes; -+ -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, name); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, open); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, load); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, unload); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, release); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, mmap); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, ioctls); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, num_ioctls); -+ SYS_DRM_SET_PLUGIN_FIELD(&sOMAPGPUPlugin, psDRMPlugin, ioctl_start); -+ -+ iRes = omap_gpu_register_plugin(&sOMAPGPUPlugin); -+ if (iRes != 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: omap_gpu_register_plugin failed (%d)", __FUNCTION__, iRes)); -+ } -+ -+ return iRes; -+} -+ -+void -+SysDRMUnregisterPlugin(PVRSRV_DRM_PLUGIN *psDRMPlugin) -+{ -+ int iRes = omap_gpu_unregister_plugin(&sOMAPGPUPlugin); -+ if (iRes != 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: omap_gpu_unregister_plugin failed (%d)", __FUNCTION__, iRes)); -+ } -+} -+#endif -diff --git a/drivers/staging/ti-es8-sgx/services4/system/ti81xx/oemfuncs.h b/drivers/staging/ti-es8-sgx/services4/system/ti81xx/oemfuncs.h -new file mode 100644 -index 0000000..dfe00c8 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/ti81xx/oemfuncs.h -@@ -0,0 +1,55 @@ -+/********************************************************************** -+ * -+ * Copyright (C) Imagination Technologies Ltd. All rights reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful but, except -+ * as otherwise stated in writing, without any warranty; without even the -+ * implied warranty of merchantability or fitness for a particular purpose. -+ * See the GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -+ * -+ * The full GNU General Public License is included in this distribution in -+ * the file called "COPYING". -+ * -+ * Contact Information: -+ * Imagination Technologies Ltd. <gpl-support@imgtec.com> -+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK -+ * -+ ******************************************************************************/ -+ -+#if !defined(__OEMFUNCS_H__) -+#define __OEMFUNCS_H__ -+ -+#if defined (__cplusplus) -+extern "C" { -+#endif -+ -+typedef IMG_UINT32 (*PFN_SRV_BRIDGEDISPATCH)( IMG_UINT32 Ioctl, -+ IMG_BYTE *pInBuf, -+ IMG_UINT32 InBufLen, -+ IMG_BYTE *pOutBuf, -+ IMG_UINT32 OutBufLen, -+ IMG_UINT32 *pdwBytesTransferred); -+typedef struct PVRSRV_DC_OEM_JTABLE_TAG -+{ -+ PFN_SRV_BRIDGEDISPATCH pfnOEMBridgeDispatch; -+ IMG_PVOID pvDummy1; -+ IMG_PVOID pvDummy2; -+ IMG_PVOID pvDummy3; -+ -+} PVRSRV_DC_OEM_JTABLE; -+ -+#define OEM_GET_EXT_FUNCS (1<<1) -+ -+#if defined(__cplusplus) -+} -+#endif -+ -+#endif -diff --git a/drivers/staging/ti-es8-sgx/services4/system/ti81xx/sysconfig.c b/drivers/staging/ti-es8-sgx/services4/system/ti81xx/sysconfig.c -new file mode 100644 -index 0000000..d5fd818 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/ti81xx/sysconfig.c -@@ -0,0 +1,969 @@ -+/********************************************************************** -+ * -+ * Copyright (C) Imagination Technologies Ltd. All rights reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful but, except -+ * as otherwise stated in writing, without any warranty; without even the -+ * implied warranty of merchantability or fitness for a particular purpose. -+ * See the GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -+ * -+ * The full GNU General Public License is included in this distribution in -+ * the file called "COPYING". -+ * -+ * Contact Information: -+ * Imagination Technologies Ltd. <gpl-support@imgtec.com> -+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK -+ * -+ ******************************************************************************/ -+ -+#include "sysconfig.h" -+#include "services_headers.h" -+#include "kerneldisplay.h" -+#include "oemfuncs.h" -+#include "sgxinfo.h" -+#include "sgxinfokm.h" -+#include "syslocal.h" -+ -+#include "ocpdefs.h" -+ -+SYS_DATA* gpsSysData = (SYS_DATA*)IMG_NULL; -+SYS_DATA gsSysData; -+ -+static SYS_SPECIFIC_DATA gsSysSpecificData; -+SYS_SPECIFIC_DATA *gpsSysSpecificData; -+ -+static IMG_UINT32 gui32SGXDeviceID; -+static SGX_DEVICE_MAP gsSGXDeviceMap; -+static PVRSRV_DEVICE_NODE *gpsSGXDevNode; -+ -+#define DEVICE_SGX_INTERRUPT (1 << 0) -+ -+#if defined(NO_HARDWARE) || defined(SGX_OCP_REGS_ENABLED) -+static IMG_CPU_VIRTADDR gsSGXRegsCPUVAddr; -+#endif -+ -+#if defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO) -+extern struct platform_device *gpsPVRLDMDev; -+#endif -+ -+IMG_UINT32 PVRSRV_BridgeDispatchKM(IMG_UINT32 Ioctl, -+ IMG_BYTE *pInBuf, -+ IMG_UINT32 InBufLen, -+ IMG_BYTE *pOutBuf, -+ IMG_UINT32 OutBufLen, -+ IMG_UINT32 *pdwBytesTransferred); -+ -+#if defined(SGX_OCP_REGS_ENABLED) -+ -+static IMG_CPU_VIRTADDR gpvOCPRegsLinAddr; -+ -+static PVRSRV_ERROR EnableSGXClocksWrap(SYS_DATA *psSysData) -+{ -+ PVRSRV_ERROR eError = EnableSGXClocks(psSysData); -+ -+#if !defined(SGX_OCP_NO_INT_BYPASS) -+ if(eError == PVRSRV_OK) -+ { -+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_SYSCONFIG, 0x14); -+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_DEBUG_CONFIG, EUR_CR_OCP_DEBUG_CONFIG_THALIA_INT_BYPASS_MASK); -+ } -+#endif -+ return eError; -+} -+ -+#else -+ -+static INLINE PVRSRV_ERROR EnableSGXClocksWrap(SYS_DATA *psSysData) -+{ -+ return EnableSGXClocks(psSysData); -+} -+ -+#endif -+ -+static INLINE PVRSRV_ERROR EnableSystemClocksWrap(SYS_DATA *psSysData) -+{ -+ PVRSRV_ERROR eError = EnableSystemClocks(psSysData); -+ -+#if !defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ if(eError == PVRSRV_OK) -+ { -+ -+ eError = EnableSGXClocksWrap(psSysData); -+ if (eError != PVRSRV_OK) -+ { -+ DisableSystemClocks(psSysData); -+ } -+ } -+#endif -+ -+ return eError; -+} -+ -+static PVRSRV_ERROR SysLocateDevices(SYS_DATA *psSysData) -+{ -+#if defined(NO_HARDWARE) -+ PVRSRV_ERROR eError; -+ IMG_CPU_PHYADDR sCpuPAddr; -+#else -+#if defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO) -+ struct resource *dev_res; -+ int dev_irq; -+#endif -+#endif -+ -+ PVR_UNREFERENCED_PARAMETER(psSysData); -+ -+ -+ gsSGXDeviceMap.ui32Flags = 0x0; -+ -+#if defined(NO_HARDWARE) -+ -+ -+ gsSGXDeviceMap.ui32RegsSize = SYS_TI81xx_SGX_REGS_SIZE; -+ -+ eError = OSBaseAllocContigMemory(gsSGXDeviceMap.ui32RegsSize, -+ &gsSGXRegsCPUVAddr, -+ &sCpuPAddr); -+ if(eError != PVRSRV_OK) -+ { -+ return eError; -+ } -+ gsSGXDeviceMap.sRegsCpuPBase = sCpuPAddr; -+ gsSGXDeviceMap.sRegsSysPBase = SysCpuPAddrToSysPAddr(gsSGXDeviceMap.sRegsCpuPBase); -+#if defined(__linux__) -+ -+ gsSGXDeviceMap.pvRegsCpuVBase = gsSGXRegsCPUVAddr; -+#else -+ -+ gsSGXDeviceMap.pvRegsCpuVBase = IMG_NULL; -+#endif -+ -+ OSMemSet(gsSGXRegsCPUVAddr, 0, gsSGXDeviceMap.ui32RegsSize); -+ -+ -+ -+ -+ gsSGXDeviceMap.ui32IRQ = 0; -+ -+#else -+#if defined(PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO) -+ -+ dev_res = platform_get_resource(gpsPVRLDMDev, IORESOURCE_MEM, 0); -+ if (dev_res == NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: platform_get_resource failed", __FUNCTION__)); -+ return PVRSRV_ERROR_INVALID_DEVICE; -+ } -+ -+ dev_irq = platform_get_irq(gpsPVRLDMDev, 0); -+ if (dev_irq < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "%s: platform_get_irq failed (%d)", __FUNCTION__, -dev_irq)); -+ return PVRSRV_ERROR_INVALID_DEVICE; -+ } -+ -+ gsSGXDeviceMap.sRegsSysPBase.uiAddr = dev_res->start; -+ gsSGXDeviceMap.sRegsCpuPBase = -+ SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sRegsSysPBase); -+ PVR_TRACE(("SGX register base: 0x%lx", (unsigned long)gsSGXDeviceMap.sRegsCpuPBase.uiAddr)); -+ -+ gsSGXDeviceMap.ui32RegsSize = (unsigned int)(dev_res->end - dev_res->start); -+ PVR_TRACE(("SGX register size: %d",gsSGXDeviceMap.ui32RegsSize)); -+ -+ gsSGXDeviceMap.ui32IRQ = dev_irq; -+ PVR_TRACE(("SGX IRQ: %d", gsSGXDeviceMap.ui32IRQ)); -+#else -+ gsSGXDeviceMap.sRegsSysPBase.uiAddr = SYS_TI81xx_SGX_REGS_SYS_PHYS_BASE; -+ gsSGXDeviceMap.sRegsCpuPBase = SysSysPAddrToCpuPAddr(gsSGXDeviceMap.sRegsSysPBase); -+ gsSGXDeviceMap.ui32RegsSize = SYS_TI81xx_SGX_REGS_SIZE; -+ -+ gsSGXDeviceMap.ui32IRQ = SYS_TI81xx_SGX_IRQ; -+ -+#endif -+#if defined(SGX_OCP_REGS_ENABLED) -+ gsSGXRegsCPUVAddr = OSMapPhysToLin(gsSGXDeviceMap.sRegsCpuPBase, -+ gsSGXDeviceMap.ui32RegsSize, -+ PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY, -+ IMG_NULL); -+ -+ if (gsSGXRegsCPUVAddr == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysLocateDevices: Failed to map SGX registers")); -+ return PVRSRV_ERROR_BAD_MAPPING; -+ } -+ -+ -+ gsSGXDeviceMap.pvRegsCpuVBase = gsSGXRegsCPUVAddr; -+ gpvOCPRegsLinAddr = gsSGXRegsCPUVAddr; -+#endif -+#endif -+ -+#if defined(PDUMP) -+ { -+ -+ static IMG_CHAR pszPDumpDevName[] = "SGXMEM"; -+ gsSGXDeviceMap.pszPDumpDevName = pszPDumpDevName; -+ } -+#endif -+ -+ -+ -+ -+ return PVRSRV_OK; -+} -+ -+ -+static IMG_CHAR *SysCreateVersionString(void) -+{ -+ static IMG_CHAR aszVersionString[100]; -+ SYS_DATA *psSysData; -+ IMG_UINT32 ui32SGXRevision; -+ IMG_INT32 i32Count; -+#if !defined(NO_HARDWARE) -+ IMG_VOID *pvRegsLinAddr; -+ -+ pvRegsLinAddr = OSMapPhysToLin(gsSGXDeviceMap.sRegsCpuPBase, -+ SYS_TI81xx_SGX_REGS_SIZE, -+ PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY, -+ IMG_NULL); -+ if(!pvRegsLinAddr) -+ { -+ return IMG_NULL; -+ } -+ -+ ui32SGXRevision = OSReadHWReg((IMG_PVOID)((IMG_PBYTE)pvRegsLinAddr), -+ EUR_CR_CORE_REVISION); -+#else -+ ui32SGXRevision = 0; -+#endif -+ -+ SysAcquireData(&psSysData); -+ -+ i32Count = OSSNPrintf(aszVersionString, 100, -+ "SGX revision = %u.%u.%u", -+ (IMG_UINT)((ui32SGXRevision & EUR_CR_CORE_REVISION_MAJOR_MASK) -+ >> EUR_CR_CORE_REVISION_MAJOR_SHIFT), -+ (IMG_UINT)((ui32SGXRevision & EUR_CR_CORE_REVISION_MINOR_MASK) -+ >> EUR_CR_CORE_REVISION_MINOR_SHIFT), -+ (IMG_UINT)((ui32SGXRevision & EUR_CR_CORE_REVISION_MAINTENANCE_MASK) -+ >> EUR_CR_CORE_REVISION_MAINTENANCE_SHIFT) -+ ); -+ -+#if !defined(NO_HARDWARE) -+ OSUnMapPhysToLin(pvRegsLinAddr, -+ SYS_TI81xx_SGX_REGS_SIZE, -+ PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY, -+ IMG_NULL); -+#endif -+ -+ if(i32Count == -1) -+ { -+ return IMG_NULL; -+ } -+ -+ return aszVersionString; -+} -+ -+ -+PVRSRV_ERROR SysInitialise(IMG_VOID) -+{ -+ IMG_UINT32 i; -+ PVRSRV_ERROR eError; -+ PVRSRV_DEVICE_NODE *psDeviceNode; -+#if !defined(PVR_NO_OMAP_TIMER) -+ IMG_CPU_PHYADDR TimerRegPhysBase; -+#endif -+#if !defined(SGX_DYNAMIC_TIMING_INFO) -+ SGX_TIMING_INFORMATION* psTimingInfo; -+#endif -+ gpsSysData = &gsSysData; -+ OSMemSet(gpsSysData, 0, sizeof(SYS_DATA)); -+ -+ gpsSysSpecificData = &gsSysSpecificData; -+ OSMemSet(gpsSysSpecificData, 0, sizeof(SYS_SPECIFIC_DATA)); -+ -+ gpsSysData->pvSysSpecificData = gpsSysSpecificData; -+ -+ eError = OSInitEnvData(&gpsSysData->pvEnvSpecificData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to setup env structure")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_ENVDATA); -+ -+ gpsSysData->ui32NumDevices = SYS_DEVICE_COUNT; -+ -+ -+ for(i=0; i<SYS_DEVICE_COUNT; i++) -+ { -+ gpsSysData->sDeviceID[i].uiID = i; -+ gpsSysData->sDeviceID[i].bInUse = IMG_FALSE; -+ } -+ -+ gpsSysData->psDeviceNodeList = IMG_NULL; -+ gpsSysData->psQueueList = IMG_NULL; -+ -+ eError = SysInitialiseCommon(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed in SysInitialiseCommon")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ -+#if !defined(SGX_DYNAMIC_TIMING_INFO) -+ -+ psTimingInfo = &gsSGXDeviceMap.sTimingInfo; -+if(cpu_is_ti816x()) -+ psTimingInfo->ui32CoreClockSpeed = SYS_389x_SGX_CLOCK_SPEED; -+else -+ psTimingInfo->ui32CoreClockSpeed = SYS_387x_SGX_CLOCK_SPEED; -+ psTimingInfo->ui32HWRecoveryFreq = SYS_SGX_HWRECOVERY_TIMEOUT_FREQ; -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ psTimingInfo->bEnableActivePM = IMG_TRUE; -+#else -+ psTimingInfo->bEnableActivePM = IMG_FALSE; -+#endif -+ psTimingInfo->ui32ActivePowManLatencyms = SYS_SGX_ACTIVE_POWER_LATENCY_MS; -+ psTimingInfo->ui32uKernelFreq = SYS_SGX_PDS_TIMER_FREQ; -+#endif -+ -+ -+ -+ gpsSysSpecificData->ui32SrcClockDiv = 3; -+ -+ -+ -+ -+ -+ eError = SysLocateDevices(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to locate devices")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV); -+#if 0 -+ eError = SysPMRuntimeRegister(); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to register with OSPM!")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_PM_RUNTIME); -+#endif -+ -+ -+ -+ eError = PVRSRVRegisterDevice(gpsSysData, SGXRegisterDevice, -+ DEVICE_SGX_INTERRUPT, &gui32SGXDeviceID); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to register device!")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_REGDEV); -+ -+ -+ -+ -+ -+ psDeviceNode = gpsSysData->psDeviceNodeList; -+ while(psDeviceNode) -+ { -+ -+ switch(psDeviceNode->sDevId.eDeviceType) -+ { -+ case PVRSRV_DEVICE_TYPE_SGX: -+ { -+ DEVICE_MEMORY_INFO *psDevMemoryInfo; -+ DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; -+ -+ -+ -+ -+ psDeviceNode->psLocalDevMemArena = IMG_NULL; -+ -+ -+ psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo; -+ psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap; -+ -+ -+ for(i=0; i<psDevMemoryInfo->ui32HeapCount; i++) -+ { -+ psDeviceMemoryHeap[i].ui32Attribs |= PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG; -+ } -+ -+ gpsSGXDevNode = psDeviceNode; -+ gsSysSpecificData.psSGXDevNode = psDeviceNode; -+ -+ break; -+ } -+ default: -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to find SGX device node!")); -+ return PVRSRV_ERROR_INIT_FAILURE; -+ } -+ -+ -+ psDeviceNode = psDeviceNode->psNext; -+ } -+ -+ eError = EnableSystemClocksWrap(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable system clocks (%d)", eError)); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS); -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ eError = EnableSGXClocksWrap(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to Enable SGX clocks (%d)", eError)); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+#endif -+ -+ eError = PVRSRVInitialiseDevice(gui32SGXDeviceID); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysInitialise: Failed to initialise device!")); -+ (IMG_VOID)SysDeinitialise(gpsSysData); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_INITDEV); -+ -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ -+ DisableSGXClocks(gpsSysData); -+#endif -+ -+#if !defined(PVR_NO_OMAP_TIMER) -+#if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA) -+ TimerRegPhysBase = gsSysSpecificData.sTimerRegPhysBase; -+#else -+ TimerRegPhysBase.uiAddr = SYS_TI81xx_GP7TIMER_REGS_SYS_PHYS_BASE; -+#endif -+ gpsSysData->pvSOCTimerRegisterKM = IMG_NULL; -+ gpsSysData->hSOCTimerRegisterOSMemHandle = 0; -+ if (TimerRegPhysBase.uiAddr != 0) -+ { -+ OSReservePhys(TimerRegPhysBase, -+ 4, -+ PVRSRV_HAP_MULTI_PROCESS|PVRSRV_HAP_UNCACHED, -+ IMG_NULL, -+ (IMG_VOID **)&gpsSysData->pvSOCTimerRegisterKM, -+ &gpsSysData->hSOCTimerRegisterOSMemHandle); -+ } -+#endif -+ -+ return PVRSRV_OK; -+} -+ -+ -+PVRSRV_ERROR SysFinalise(IMG_VOID) -+{ -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ eError = EnableSGXClocksWrap(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to Enable SGX clocks (%d)", eError)); -+ return eError; -+ } -+#endif -+ -+ eError = OSInstallMISR(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to install MISR")); -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_MISR); -+ -+#if defined(SYS_USING_INTERRUPTS) -+ -+ eError = OSInstallDeviceLISR(gpsSysData, gsSGXDeviceMap.ui32IRQ, "SGX ISR", gpsSGXDevNode); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to install ISR")); -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR); -+#endif -+ -+#if defined(__linux__) -+ -+ gpsSysData->pszVersionString = SysCreateVersionString(); -+ if (!gpsSysData->pszVersionString) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysFinalise: Failed to create a system version string")); -+ } -+ else -+ { -+ PVR_TRACE(("SysFinalise: Version string: %s", gpsSysData->pszVersionString)); -+ } -+#endif -+ -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ -+ DisableSGXClocks(gpsSysData); -+#endif -+ -+ gpsSysSpecificData->bSGXInitComplete = IMG_TRUE; -+ -+ return eError; -+} -+ -+ -+PVRSRV_ERROR SysDeinitialise (SYS_DATA *psSysData) -+{ -+ PVRSRV_ERROR eError; -+ -+ if(gpsSysData->pvSOCTimerRegisterKM) -+ { -+ OSUnReservePhys(gpsSysData->pvSOCTimerRegisterKM, -+ 4, -+ PVRSRV_HAP_MULTI_PROCESS|PVRSRV_HAP_UNCACHED, -+ gpsSysData->hSOCTimerRegisterOSMemHandle); -+ } -+ -+#if defined(SYS_USING_INTERRUPTS) -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR)) -+ { -+ eError = OSUninstallDeviceLISR(psSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: OSUninstallDeviceLISR failed")); -+ return eError; -+ } -+ } -+#endif -+ -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_MISR)) -+ { -+ eError = OSUninstallMISR(psSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: OSUninstallMISR failed")); -+ return eError; -+ } -+ } -+ -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_INITDEV)) -+ { -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ PVR_ASSERT(SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS)); -+ -+ eError = EnableSGXClocksWrap(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: EnableSGXClocks failed")); -+ return eError; -+ } -+#endif -+ -+ -+ eError = PVRSRVDeinitialiseDevice (gui32SGXDeviceID); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: failed to de-init the device")); -+ return eError; -+ } -+ } -+#if 0 -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_PM_RUNTIME)) -+ { -+ eError = SysPMRuntimeUnregister(); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: Failed to unregister with OSPM!")); -+ gpsSysData = IMG_NULL; -+ return eError; -+ } -+ } -+#endif -+ -+ -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS)) -+ { -+ DisableSystemClocks(gpsSysData); -+ } -+ -+ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_ENVDATA)) -+ { -+ eError = OSDeInitEnvData(gpsSysData->pvEnvSpecificData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: failed to de-init env structure")); -+ return eError; -+ } -+ } -+ -+ SysDeinitialiseCommon(gpsSysData); -+ -+#if defined(NO_HARDWARE) || defined(SGX_OCP_REGS_ENABLED) -+ if(gsSGXRegsCPUVAddr != IMG_NULL) -+ { -+#if defined(NO_HARDWARE) -+ -+ OSBaseFreeContigMemory(SYS_TI81xx_SGX_REGS_SIZE, gsSGXRegsCPUVAddr, gsSGXDeviceMap.sRegsCpuPBase); -+#else -+#if defined(SGX_OCP_REGS_ENABLED) -+ OSUnMapPhysToLin(gsSGXRegsCPUVAddr, -+ gsSGXDeviceMap.ui32RegsSize, -+ PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY, -+ IMG_NULL); -+ -+ gpvOCPRegsLinAddr = IMG_NULL; -+#endif -+#endif -+ gsSGXRegsCPUVAddr = IMG_NULL; -+ gsSGXDeviceMap.pvRegsCpuVBase = gsSGXRegsCPUVAddr; -+ } -+#endif -+ -+ -+ gpsSysSpecificData->ui32SysSpecificData = 0; -+ gpsSysSpecificData->bSGXInitComplete = IMG_FALSE; -+ -+ gpsSysData = IMG_NULL; -+ -+ return PVRSRV_OK; -+} -+ -+ -+PVRSRV_ERROR SysGetDeviceMemoryMap(PVRSRV_DEVICE_TYPE eDeviceType, -+ IMG_VOID **ppvDeviceMap) -+{ -+ -+ switch(eDeviceType) -+ { -+ case PVRSRV_DEVICE_TYPE_SGX: -+ { -+ -+ *ppvDeviceMap = (IMG_VOID*)&gsSGXDeviceMap; -+ -+ break; -+ } -+ default: -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysGetDeviceMemoryMap: unsupported device type")); -+ } -+ } -+ return PVRSRV_OK; -+} -+ -+ -+IMG_DEV_PHYADDR SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType, -+ IMG_CPU_PHYADDR CpuPAddr) -+{ -+ IMG_DEV_PHYADDR DevPAddr; -+ -+ PVR_UNREFERENCED_PARAMETER(eDeviceType); -+ -+ -+ DevPAddr.uiAddr = CpuPAddr.uiAddr; -+ -+ return DevPAddr; -+} -+ -+IMG_CPU_PHYADDR SysSysPAddrToCpuPAddr (IMG_SYS_PHYADDR sys_paddr) -+{ -+ IMG_CPU_PHYADDR cpu_paddr; -+ -+ -+ cpu_paddr.uiAddr = sys_paddr.uiAddr; -+ return cpu_paddr; -+} -+ -+IMG_SYS_PHYADDR SysCpuPAddrToSysPAddr (IMG_CPU_PHYADDR cpu_paddr) -+{ -+ IMG_SYS_PHYADDR sys_paddr; -+ -+ -+ sys_paddr.uiAddr = cpu_paddr.uiAddr; -+ return sys_paddr; -+} -+ -+ -+IMG_DEV_PHYADDR SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType, IMG_SYS_PHYADDR SysPAddr) -+{ -+ IMG_DEV_PHYADDR DevPAddr; -+ -+ PVR_UNREFERENCED_PARAMETER(eDeviceType); -+ -+ -+ DevPAddr.uiAddr = SysPAddr.uiAddr; -+ -+ return DevPAddr; -+} -+ -+ -+IMG_SYS_PHYADDR SysDevPAddrToSysPAddr(PVRSRV_DEVICE_TYPE eDeviceType, IMG_DEV_PHYADDR DevPAddr) -+{ -+ IMG_SYS_PHYADDR SysPAddr; -+ -+ PVR_UNREFERENCED_PARAMETER(eDeviceType); -+ -+ -+ SysPAddr.uiAddr = DevPAddr.uiAddr; -+ -+ return SysPAddr; -+} -+ -+ -+IMG_VOID SysRegisterExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode) -+{ -+ PVR_UNREFERENCED_PARAMETER(psDeviceNode); -+} -+ -+ -+IMG_VOID SysRemoveExternalDevice(PVRSRV_DEVICE_NODE *psDeviceNode) -+{ -+ PVR_UNREFERENCED_PARAMETER(psDeviceNode); -+} -+ -+ -+IMG_UINT32 SysGetInterruptSource(SYS_DATA *psSysData, -+ PVRSRV_DEVICE_NODE *psDeviceNode) -+{ -+ PVR_UNREFERENCED_PARAMETER(psSysData); -+#if defined(NO_HARDWARE) -+ -+ return 0xFFFFFFFF; -+#else -+ -+ return psDeviceNode->ui32SOCInterruptBit; -+#endif -+} -+ -+ -+IMG_VOID SysClearInterrupts(SYS_DATA* psSysData, IMG_UINT32 ui32ClearBits) -+{ -+ PVR_UNREFERENCED_PARAMETER(ui32ClearBits); -+#if defined(NO_HARDWARE) -+ PVR_UNREFERENCED_PARAMETER(psSysData); -+#else -+#if defined(SGX_OCP_NO_INT_BYPASS) -+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_IRQSTATUS_2, 0x1); -+#endif -+ -+ OSReadHWReg(((PVRSRV_SGXDEV_INFO *)gpsSGXDevNode->pvDevice)->pvRegsBaseKM, EUR_CR_EVENT_HOST_CLEAR); -+#endif -+} -+ -+#if defined(SGX_OCP_NO_INT_BYPASS) -+IMG_VOID SysEnableSGXInterrupts(SYS_DATA *psSysData) -+{ -+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *)psSysData->pvSysSpecificData; -+ if (SYS_SPECIFIC_DATA_TEST(psSysSpecData, SYS_SPECIFIC_DATA_ENABLE_LISR) && !SYS_SPECIFIC_DATA_TEST(psSysSpecData, SYS_SPECIFIC_DATA_IRQ_ENABLED)) -+ { -+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_IRQSTATUS_2, 0x1); -+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_IRQENABLE_SET_2, 0x1); -+ SYS_SPECIFIC_DATA_SET(psSysSpecData, SYS_SPECIFIC_DATA_IRQ_ENABLED); -+ } -+} -+ -+IMG_VOID SysDisableSGXInterrupts(SYS_DATA *psSysData) -+{ -+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *)psSysData->pvSysSpecificData; -+ -+ if (SYS_SPECIFIC_DATA_TEST(psSysSpecData, SYS_SPECIFIC_DATA_IRQ_ENABLED)) -+ { -+ OSWriteHWReg(gpvOCPRegsLinAddr, EUR_CR_OCP_IRQENABLE_CLR_2, 0x1); -+ SYS_SPECIFIC_DATA_CLEAR(psSysSpecData, SYS_SPECIFIC_DATA_IRQ_ENABLED); -+ } -+} -+#endif -+ -+PVRSRV_ERROR SysSystemPrePowerState(PVRSRV_SYS_POWER_STATE eNewPowerState) -+{ -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ -+ if (eNewPowerState == PVRSRV_SYS_POWER_STATE_D3) -+ { -+ PVR_TRACE(("SysSystemPrePowerState: Entering state D3")); -+ -+#if defined(SYS_USING_INTERRUPTS) -+ if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR)) -+ { -+#if defined(SYS_CUSTOM_POWERLOCK_WRAP) -+ IMG_BOOL bWrapped = WrapSystemPowerChange(&gsSysSpecificData); -+#endif -+ eError = OSUninstallDeviceLISR(gpsSysData); -+#if defined(SYS_CUSTOM_POWERLOCK_WRAP) -+ if (bWrapped) -+ { -+ UnwrapSystemPowerChange(&gsSysSpecificData); -+ } -+#endif -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysSystemPrePowerState: OSUninstallDeviceLISR failed (%d)", eError)); -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR); -+ SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR); -+ } -+#endif -+ -+ if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS)) -+ { -+ DisableSystemClocks(gpsSysData); -+ -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS); -+ SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS); -+ } -+ } -+ -+ return eError; -+} -+ -+ -+PVRSRV_ERROR SysSystemPostPowerState(PVRSRV_SYS_POWER_STATE eNewPowerState) -+{ -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ -+ if (eNewPowerState == PVRSRV_SYS_POWER_STATE_D0) -+ { -+ PVR_TRACE(("SysSystemPostPowerState: Entering state D0")); -+ -+ if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS)) -+ { -+ eError = EnableSystemClocksWrap(gpsSysData); -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysSystemPostPowerState: EnableSystemClocksWrap failed (%d)", eError)); -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS); -+ SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS); -+ } -+ -+#if defined(SYS_USING_INTERRUPTS) -+ if (SYS_SPECIFIC_DATA_TEST(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR)) -+ { -+#if defined(SYS_CUSTOM_POWERLOCK_WRAP) -+ IMG_BOOL bWrapped = WrapSystemPowerChange(&gsSysSpecificData); -+#endif -+ -+ eError = OSInstallDeviceLISR(gpsSysData, gsSGXDeviceMap.ui32IRQ, "SGX ISR", gpsSGXDevNode); -+#if defined(SYS_CUSTOM_POWERLOCK_WRAP) -+ if (bWrapped) -+ { -+ UnwrapSystemPowerChange(&gsSysSpecificData); -+ } -+#endif -+ if (eError != PVRSRV_OK) -+ { -+ PVR_DPF((PVR_DBG_ERROR,"SysSystemPostPowerState: OSInstallDeviceLISR failed to install ISR (%d)", eError)); -+ return eError; -+ } -+ SYS_SPECIFIC_DATA_SET(&gsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR); -+ SYS_SPECIFIC_DATA_CLEAR(&gsSysSpecificData, SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR); -+ } -+#endif -+ } -+ return eError; -+} -+ -+ -+PVRSRV_ERROR SysDevicePrePowerState(IMG_UINT32 ui32DeviceIndex, -+ PVRSRV_DEV_POWER_STATE eNewPowerState, -+ PVRSRV_DEV_POWER_STATE eCurrentPowerState) -+{ -+ PVR_UNREFERENCED_PARAMETER(eCurrentPowerState); -+ -+ if (ui32DeviceIndex != gui32SGXDeviceID) -+ { -+ return PVRSRV_OK; -+ } -+ -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ if (eNewPowerState == PVRSRV_DEV_POWER_STATE_OFF) -+ { -+ PVR_DPF((PVR_DBG_MESSAGE, "SysDevicePrePowerState: SGX Entering state D3")); -+ DisableSGXClocks(gpsSysData); -+ } -+#else -+ PVR_UNREFERENCED_PARAMETER(eNewPowerState ); -+#endif -+ return PVRSRV_OK; -+} -+ -+ -+PVRSRV_ERROR SysDevicePostPowerState(IMG_UINT32 ui32DeviceIndex, -+ PVRSRV_DEV_POWER_STATE eNewPowerState, -+ PVRSRV_DEV_POWER_STATE eCurrentPowerState) -+{ -+ PVRSRV_ERROR eError = PVRSRV_OK; -+ -+ PVR_UNREFERENCED_PARAMETER(eNewPowerState); -+ -+ if (ui32DeviceIndex != gui32SGXDeviceID) -+ { -+ return eError; -+ } -+ -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ if (eCurrentPowerState == PVRSRV_DEV_POWER_STATE_OFF) -+ { -+ PVR_DPF((PVR_DBG_MESSAGE, "SysDevicePostPowerState: SGX Leaving state D3")); -+ eError = EnableSGXClocksWrap(gpsSysData); -+ } -+#else -+ PVR_UNREFERENCED_PARAMETER(eCurrentPowerState); -+#endif -+ -+ return eError; -+} -+ -+ -+PVRSRV_ERROR SysOEMFunction ( IMG_UINT32 ui32ID, -+ IMG_VOID *pvIn, -+ IMG_UINT32 ulInSize, -+ IMG_VOID *pvOut, -+ IMG_UINT32 ulOutSize) -+{ -+ PVR_UNREFERENCED_PARAMETER(ui32ID); -+ PVR_UNREFERENCED_PARAMETER(pvIn); -+ PVR_UNREFERENCED_PARAMETER(ulInSize); -+ PVR_UNREFERENCED_PARAMETER(pvOut); -+ PVR_UNREFERENCED_PARAMETER(ulOutSize); -+ -+ if ((ui32ID == OEM_GET_EXT_FUNCS) && -+ (ulOutSize == sizeof(PVRSRV_DC_OEM_JTABLE))) -+ { -+ -+ PVRSRV_DC_OEM_JTABLE *psOEMJTable = (PVRSRV_DC_OEM_JTABLE*) pvOut; -+ psOEMJTable->pfnOEMBridgeDispatch = &PVRSRV_BridgeDispatchKM; -+ return PVRSRV_OK; -+ } -+ -+ return PVRSRV_ERROR_INVALID_PARAMS; -+} -diff --git a/drivers/staging/ti-es8-sgx/services4/system/ti81xx/sysconfig.h b/drivers/staging/ti-es8-sgx/services4/system/ti81xx/sysconfig.h -new file mode 100644 -index 0000000..fa7c42e ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/ti81xx/sysconfig.h -@@ -0,0 +1,59 @@ -+/********************************************************************** -+ * -+ * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful but, except -+ * as otherwise stated in writing, without any warranty; without even the -+ * implied warranty of merchantability or fitness for a particular purpose. -+ * See the GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -+ * -+ * The full GNU General Public License is included in this distribution in -+ * the file called "COPYING". -+ * -+ * Contact Information: -+ * Imagination Technologies Ltd. <gpl-support@imgtec.com> -+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK -+ * -+ ******************************************************************************/ -+ -+#if !defined(__SOCCONFIG_H__) -+#define __SOCCONFIG_H__ -+ -+ -+#define VS_PRODUCT_NAME "TI81xx" -+ -+#define SYS_SGX_CLOCK_SPEED 200000000 -+#define SYS_387x_SGX_CLOCK_SPEED 200000000 -+ -+/* Allowed SGX Clock Speeds on Netra -+SGX_RATES = main_pll_clk2_ck(987428571) /D (3 to 8) = 329142857, 246857142, -+ 197485714,164571428,141061224, 123428571 */ -+#define SYS_389x_SGX_CLOCK_SPEED 329142857 -+ -+#define SYS_SGX_HWRECOVERY_TIMEOUT_FREQ (100) -+#define SYS_SGX_PDS_TIMER_FREQ (1000) -+ -+#if !defined(SYS_SGX_ACTIVE_POWER_LATENCY_MS) -+#define SYS_SGX_ACTIVE_POWER_LATENCY_MS (1) -+#endif -+ -+ -+#define SYS_TI81xx_SGX_REGS_SYS_PHYS_BASE 0x56000000 -+ -+#define SYS_TI81xx_SGX_REGS_SIZE 0x10000 -+ -+#define SYS_TI81xx_SGX_IRQ 37 -+ -+#define SYS_TI81xx_GP7TIMER_ENABLE_SYS_PHYS_BASE 0x48048038 -+#define SYS_TI81xx_GP7TIMER_REGS_SYS_PHYS_BASE 0x4804803C -+#define SYS_TI81xx_GP7TIMER_TSICR_SYS_PHYS_BASE 0x48048054 -+ -+#endif -diff --git a/drivers/staging/ti-es8-sgx/services4/system/ti81xx/sysinfo.h b/drivers/staging/ti-es8-sgx/services4/system/ti81xx/sysinfo.h -new file mode 100644 -index 0000000..ea3b790 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/ti81xx/sysinfo.h -@@ -0,0 +1,41 @@ -+/********************************************************************** -+ * -+ * Copyright (C) Imagination Technologies Ltd. All rights reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful but, except -+ * as otherwise stated in writing, without any warranty; without even the -+ * implied warranty of merchantability or fitness for a particular purpose. -+ * See the GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -+ * -+ * The full GNU General Public License is included in this distribution in -+ * the file called "COPYING". -+ * -+ * Contact Information: -+ * Imagination Technologies Ltd. <gpl-support@imgtec.com> -+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK -+ * -+ ******************************************************************************/ -+ -+#if !defined(__SYSINFO_H__) -+#define __SYSINFO_H__ -+ -+#if defined(PVR_LINUX_USING_WORKQUEUES) -+#define MAX_HW_TIME_US (1000000) -+#define WAIT_TRY_COUNT (20000) -+#else -+#define MAX_HW_TIME_US (500000) -+#define WAIT_TRY_COUNT (10000) -+#endif -+ -+ -+#define SYS_DEVICE_COUNT 15 -+ -+#endif -diff --git a/drivers/staging/ti-es8-sgx/services4/system/ti81xx/syslocal.h b/drivers/staging/ti-es8-sgx/services4/system/ti81xx/syslocal.h -new file mode 100644 -index 0000000..4e833bd ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/ti81xx/syslocal.h -@@ -0,0 +1,210 @@ -+/********************************************************************** -+ * -+ * Copyright (C) Imagination Technologies Ltd. All rights reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful but, except -+ * as otherwise stated in writing, without any warranty; without even the -+ * implied warranty of merchantability or fitness for a particular purpose. -+ * See the GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -+ * -+ * The full GNU General Public License is included in this distribution in -+ * the file called "COPYING". -+ * -+ * Contact Information: -+ * Imagination Technologies Ltd. <gpl-support@imgtec.com> -+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK -+ * -+ ******************************************************************************/ -+ -+#if !defined(__SYSLOCAL_H__) -+#define __SYSLOCAL_H__ -+ -+#if defined(__linux__) -+ -+#include <linux/version.h> -+#include <linux/clk.h> -+#if defined(PVR_LINUX_USING_WORKQUEUES) -+#include <linux/mutex.h> -+#else -+#include <linux/spinlock.h> -+#endif -+#include <asm/atomic.h> -+ -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)) -+#include <linux/semaphore.h> -+#include <linux/resource.h> -+#else -+#include <asm/semaphore.h> -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22)) -+#include <asm/arch/resource.h> -+#endif -+#endif -+ -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) -+#if !defined(LDM_PLATFORM) -+#error "LDM_PLATFORM must be set" -+#endif -+/*#define PVR_LINUX_DYNAMIC_SGX_RESOURCE_INFO*/ -+//#include <linux/platform_device.h> -+#endif -+ -+#if ((defined(DEBUG) || defined(TIMING)) && \ -+ (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32))) && \ -+ !defined(PVR_NO_OMAP_TIMER) -+#define PVR_OMAP3_TIMING_PRCM -+#endif -+ -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) -+/*#include <plat/gpu.h>*/ -+#if !defined(PVR_NO_OMAP_TIMER) -+/*#define PVR_OMAP_USE_DM_TIMER_API*/ -+//#include <plat/dmtimer.h> -+#endif -+#endif -+ -+#if !defined(PVR_NO_OMAP_TIMER) -+//#define PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA -+#endif -+#endif -+ -+#if !defined(NO_HARDWARE) && \ -+ defined(SYS_USING_INTERRUPTS) && \ -+ defined(SGX540) -+#define SGX_OCP_REGS_ENABLED -+#endif -+ -+#if defined(__linux__) -+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) && defined(SGX_OCP_REGS_ENABLED) -+/*#define SGX_OCP_NO_INT_BYPASS*/ -+#endif -+#endif -+ -+#if defined (__cplusplus) -+extern "C" { -+#endif -+ -+ -+ -+IMG_VOID DisableSystemClocks(SYS_DATA *psSysData); -+PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData); -+ -+IMG_VOID DisableSGXClocks(SYS_DATA *psSysData); -+PVRSRV_ERROR EnableSGXClocks(SYS_DATA *psSysData); -+ -+#define SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS 0x00000001 -+#define SYS_SPECIFIC_DATA_ENABLE_LISR 0x00000002 -+#define SYS_SPECIFIC_DATA_ENABLE_MISR 0x00000004 -+#define SYS_SPECIFIC_DATA_ENABLE_ENVDATA 0x00000008 -+#define SYS_SPECIFIC_DATA_ENABLE_LOCDEV 0x00000010 -+#define SYS_SPECIFIC_DATA_ENABLE_REGDEV 0x00000020 -+#define SYS_SPECIFIC_DATA_ENABLE_PDUMPINIT 0x00000040 -+#define SYS_SPECIFIC_DATA_ENABLE_INITDEV 0x00000080 -+#define SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV 0x00000100 -+ -+#define SYS_SPECIFIC_DATA_PM_UNINSTALL_LISR 0x00000200 -+#define SYS_SPECIFIC_DATA_PM_DISABLE_SYSCLOCKS 0x00000400 -+#define SYS_SPECIFIC_DATA_ENABLE_OCPREGS 0x00000800 -+#define SYS_SPECIFIC_DATA_ENABLE_PM_RUNTIME 0x00001000 -+#if defined(SGX_OCP_REGS_ENABLED) && defined(SGX_OCP_NO_INT_BYPASS) -+#define SYS_SPECIFIC_DATA_IRQ_ENABLED 0x00002000 -+#endif -+ -+#define SYS_SPECIFIC_DATA_SET(psSysSpecData, flag) ((IMG_VOID)((psSysSpecData)->ui32SysSpecificData |= (flag))) -+ -+#define SYS_SPECIFIC_DATA_CLEAR(psSysSpecData, flag) ((IMG_VOID)((psSysSpecData)->ui32SysSpecificData &= ~(flag))) -+ -+#define SYS_SPECIFIC_DATA_TEST(psSysSpecData, flag) (((psSysSpecData)->ui32SysSpecificData & (flag)) != 0) -+ -+typedef struct _SYS_SPECIFIC_DATA_TAG_ -+{ -+ IMG_UINT32 ui32SysSpecificData; -+ PVRSRV_DEVICE_NODE *psSGXDevNode; -+ IMG_BOOL bSGXInitComplete; -+#if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA) -+ IMG_CPU_PHYADDR sTimerRegPhysBase; -+#endif -+#if !defined(__linux__) -+ IMG_BOOL bSGXClocksEnabled; -+#endif -+ IMG_UINT32 ui32SrcClockDiv; -+#if defined(__linux__) -+ IMG_BOOL bSysClocksOneTimeInit; -+ atomic_t sSGXClocksEnabled; -+#if defined(PVR_LINUX_USING_WORKQUEUES) -+ struct mutex sPowerLock; -+#else -+ IMG_BOOL bConstraintNotificationsEnabled; -+ spinlock_t sPowerLock; -+ atomic_t sPowerLockCPU; -+ spinlock_t sNotifyLock; -+ atomic_t sNotifyLockCPU; -+ IMG_BOOL bCallVDD2PostFunc; -+#endif -+ struct clk *psCORE_CK; -+ struct clk *psSGX_FCK; -+ struct clk *psSGX_ICK; -+ -+#if defined(DEBUG) || defined(TIMING) -+ struct clk *psGPT11_FCK; -+ struct clk *psGPT11_ICK; -+#endif -+#if defined(PVR_OMAP_USE_DM_TIMER_API) -+ struct omap_dm_timer *psGPTimer; -+#endif -+#endif -+} SYS_SPECIFIC_DATA; -+ -+extern SYS_SPECIFIC_DATA *gpsSysSpecificData; -+ -+#if defined(SGX_OCP_REGS_ENABLED) && defined(SGX_OCP_NO_INT_BYPASS) -+IMG_VOID SysEnableSGXInterrupts(SYS_DATA* psSysData); -+IMG_VOID SysDisableSGXInterrupts(SYS_DATA* psSysData); -+#else -+#define SysEnableSGXInterrupts(psSysData) -+#define SysDisableSGXInterrupts(psSysData) -+#endif -+ -+#if defined(SYS_CUSTOM_POWERLOCK_WRAP) -+IMG_BOOL WrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData); -+IMG_VOID UnwrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData); -+#endif -+ -+#if defined(__linux__) -+ -+PVRSRV_ERROR SysPMRuntimeRegister(void); -+PVRSRV_ERROR SysPMRuntimeUnregister(void); -+ -+#else -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(SysPMRuntimeRegister) -+#endif -+static INLINE PVRSRV_ERROR SysPMRuntimeRegister(void) -+{ -+ return PVRSRV_OK; -+} -+ -+#ifdef INLINE_IS_PRAGMA -+#pragma inline(SysPMRuntimeUnregister) -+#endif -+static INLINE PVRSRV_ERROR SysPMRuntimeUnregister(void) -+{ -+ return PVRSRV_OK; -+} -+ -+#endif -+ -+#if defined(__cplusplus) -+} -+#endif -+ -+#endif -diff --git a/drivers/staging/ti-es8-sgx/services4/system/ti81xx/sysutils.c b/drivers/staging/ti-es8-sgx/services4/system/ti81xx/sysutils.c -new file mode 100644 -index 0000000..d54765f ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/ti81xx/sysutils.c -@@ -0,0 +1,29 @@ -+/********************************************************************** -+ * -+ * Copyright (C) Imagination Technologies Ltd. All rights reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful but, except -+ * as otherwise stated in writing, without any warranty; without even the -+ * implied warranty of merchantability or fitness for a particular purpose. -+ * See the GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -+ * -+ * The full GNU General Public License is included in this distribution in -+ * the file called "COPYING". -+ * -+ * Contact Information: -+ * Imagination Technologies Ltd. <gpl-support@imgtec.com> -+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK -+ * -+ ******************************************************************************/ -+ -+#if defined(__linux__) -+#include "sysutils_linux.c" -+#endif -diff --git a/drivers/staging/ti-es8-sgx/services4/system/ti81xx/sysutils_linux.c b/drivers/staging/ti-es8-sgx/services4/system/ti81xx/sysutils_linux.c -new file mode 100644 -index 0000000..fbe87fa ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/services4/system/ti81xx/sysutils_linux.c -@@ -0,0 +1,576 @@ -+/********************************************************************** -+ * -+ * Copyright (C) Imagination Technologies Ltd. All rights reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful but, except -+ * as otherwise stated in writing, without any warranty; without even the -+ * implied warranty of merchantability or fitness for a particular purpose. -+ * See the GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -+ * -+ * The full GNU General Public License is included in this distribution in -+ * the file called "COPYING". -+ * -+ * Contact Information: -+ * Imagination Technologies Ltd. <gpl-support@imgtec.com> -+ * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK -+ * -+ ******************************************************************************/ -+ -+#include <linux/version.h> -+#include <linux/clk.h> -+#include <linux/err.h> -+#include <linux/hardirq.h> -+#include <linux/mutex.h> -+ -+#include "sgxdefs.h" -+#include "services_headers.h" -+#include "sysinfo.h" -+#include "sgxapi_km.h" -+#include "sysconfig.h" -+#include "sgxinfokm.h" -+#include "syslocal.h" -+ -+//#include <linux/platform_device.h> -+//#include <linux/pm_runtime.h> -+ -+#define ONE_MHZ 1000000 -+#define HZ_TO_MHZ(m) ((m) / ONE_MHZ) -+ -+#if defined(SUPPORT_TI81xx_SGXFCLK_96M) -+#define SGX_PARENT_CLOCK "cm_96m_fck" -+#else -+#define SGX_PARENT_CLOCK "core_ck" -+#endif -+ -+#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) -+extern struct platform_device *gpsPVRLDMDev; -+#endif -+ -+ -+static PVRSRV_ERROR PowerLockWrap(SYS_SPECIFIC_DATA *psSysSpecData, IMG_BOOL bTryLock) -+{ -+ if (!in_interrupt()) -+ { -+ if (bTryLock) -+ { -+ int locked = mutex_trylock(&psSysSpecData->sPowerLock); -+ if (locked == 0) -+ { -+ return PVRSRV_ERROR_RETRY; -+ } -+ } -+ else -+ { -+ mutex_lock(&psSysSpecData->sPowerLock); -+ } -+ } -+ -+ return PVRSRV_OK; -+} -+ -+static IMG_VOID PowerLockUnwrap(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ if (!in_interrupt()) -+ { -+ mutex_unlock(&psSysSpecData->sPowerLock); -+ } -+} -+ -+PVRSRV_ERROR SysPowerLockWrap(IMG_BOOL bTryLock) -+{ -+ SYS_DATA *psSysData; -+ -+ SysAcquireData(&psSysData); -+ -+ return PowerLockWrap(psSysData->pvSysSpecificData, bTryLock); -+} -+ -+IMG_VOID SysPowerLockUnwrap(IMG_VOID) -+{ -+ SYS_DATA *psSysData; -+ -+ SysAcquireData(&psSysData); -+ -+ PowerLockUnwrap(psSysData->pvSysSpecificData); -+} -+ -+ -+ -+ -+IMG_BOOL WrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ return IMG_TRUE; -+} -+ -+IMG_VOID UnwrapSystemPowerChange(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+} -+ -+static inline IMG_UINT32 scale_by_rate(IMG_UINT32 val, IMG_UINT32 rate1, IMG_UINT32 rate2) -+{ -+ if (rate1 >= rate2) -+ { -+ return val * (rate1 / rate2); -+ } -+ -+ return val / (rate2 / rate1); -+} -+ -+static inline IMG_UINT32 scale_prop_to_SGX_clock(IMG_UINT32 val, IMG_UINT32 rate) -+{ -+ if(cpu_is_ti816x()) -+ { -+ return scale_by_rate(val, rate, SYS_389x_SGX_CLOCK_SPEED); -+ } -+ else -+ { -+ return scale_by_rate(val, rate, SYS_387x_SGX_CLOCK_SPEED); -+ } -+ -+} -+ -+static inline IMG_UINT32 scale_inv_prop_to_SGX_clock(IMG_UINT32 val, IMG_UINT32 rate) -+{ -+ if(cpu_is_ti816x()) -+ return scale_by_rate(val, SYS_389x_SGX_CLOCK_SPEED, rate); -+ else -+ return scale_by_rate(val, SYS_387x_SGX_CLOCK_SPEED, rate); -+ -+} -+ -+IMG_VOID SysGetSGXTimingInformation(SGX_TIMING_INFORMATION *psTimingInfo) -+{ -+ IMG_UINT32 rate; -+ -+ if(cpu_is_ti816x()) -+ rate = SYS_389x_SGX_CLOCK_SPEED; -+ else -+ rate = SYS_387x_SGX_CLOCK_SPEED; -+ -+#if !defined(NO_HARDWARE) -+ PVR_ASSERT(atomic_read(&gpsSysSpecificData->sSGXClocksEnabled) != 0); -+#endif -+ psTimingInfo->ui32CoreClockSpeed = rate; -+ psTimingInfo->ui32HWRecoveryFreq = scale_prop_to_SGX_clock(SYS_SGX_HWRECOVERY_TIMEOUT_FREQ, rate); -+ psTimingInfo->ui32uKernelFreq = scale_prop_to_SGX_clock(SYS_SGX_PDS_TIMER_FREQ, rate); -+#if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) -+ psTimingInfo->bEnableActivePM = IMG_TRUE; -+#else -+ psTimingInfo->bEnableActivePM = IMG_FALSE; -+#endif -+ psTimingInfo->ui32ActivePowManLatencyms = SYS_SGX_ACTIVE_POWER_LATENCY_MS; -+} -+ -+PVRSRV_ERROR EnableSGXClocks(SYS_DATA *psSysData) -+{ -+#if !defined(NO_HARDWARE) -+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; -+ IMG_INT res; -+ -+ if (atomic_read(&psSysSpecData->sSGXClocksEnabled) != 0) -+ { -+ return PVRSRV_OK; -+ } -+ -+ PVR_DPF((PVR_DBG_MESSAGE, "EnableSGXClocks: Enabling SGX Clocks")); -+ -+ res=clk_enable(psSysSpecData->psSGX_FCK); -+ if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Couldn't enable SGX functional clock (%d)", res)); -+ return PVRSRV_ERROR_UNABLE_TO_ENABLE_CLOCK; -+ } -+#if 0 -+if(cpu_is_ti816x()) -+ lNewRate = clk_round_rate(psSysSpecData->psSGX_FCK, SYS_389x_SGX_CLOCK_SPEED + ONE_MHZ); -+else -+ lNewRate = clk_round_rate(psSysSpecData->psSGX_FCK, SYS_387x_SGX_CLOCK_SPEED + ONE_MHZ); -+ if (lNewRate <= 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: Couldn't round SGX functional clock rate")); -+ return PVRSRV_ERROR_UNABLE_TO_ROUND_CLOCK_RATE; -+ } -+ -+ -+ lRate = clk_get_rate(psSysSpecData->psSGX_FCK); -+ if (lRate != lNewRate) -+ { -+ res = clk_set_rate(psSysSpecData->psSGX_FCK, lNewRate); -+ if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_WARNING, "EnableSGXClocks: Couldn't set SGX functional clock rate (%d)", res)); -+ return PVRSRV_ERROR_UNABLE_TO_SET_CLOCK_RATE; -+ } -+ } -+#endif -+ -+ if(cpu_is_ti816x()) -+ res = clk_set_rate(psSysSpecData->psSGX_FCK,SYS_389x_SGX_CLOCK_SPEED); -+ else -+ res = clk_set_rate(psSysSpecData->psSGX_FCK,SYS_387x_SGX_CLOCK_SPEED); -+ -+ if(res != 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSsystemClocks: Couldn't set SGX Functional Clock rate")); -+ return PVRSRV_ERROR_UNABLE_TO_SET_CLOCK_RATE; -+ } -+ else -+ { -+ res = clk_get_rate(psSysSpecData->psSGX_FCK); -+ PVR_TRACE(("SGX clock rate is %dMHz", HZ_TO_MHZ(res))); -+ } -+ -+ -+#if defined(DEBUG) -+ { -+ IMG_UINT32 rate = clk_get_rate(psSysSpecData->psSGX_FCK); -+ PVR_DPF((PVR_DBG_MESSAGE, "EnableSGXClocks: SGX Functional Clock is %dMhz", HZ_TO_MHZ(rate))); -+ } -+#endif -+ -+ -+ -+#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) -+ { -+ -+// int res = pm_runtime_get_sync(&gpsPVRLDMDev->dev); -+// if (res < 0) -+// { -+// PVR_DPF((PVR_DBG_ERROR, "EnableSGXClocks: pm_runtime_get_sync failed (%d)", -res)); -+// return PVRSRV_ERROR_UNABLE_TO_ENABLE_CLOCK; -+// } -+ } -+#endif -+// SysEnableSGXInterrupts(psSysData); -+ -+ -+ atomic_set(&psSysSpecData->sSGXClocksEnabled, 1); -+ -+#else -+ PVR_UNREFERENCED_PARAMETER(psSysData); -+#endif -+ return PVRSRV_OK; -+} -+ -+ -+IMG_VOID DisableSGXClocks(SYS_DATA *psSysData) -+{ -+#if !defined(NO_HARDWARE) -+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; -+ -+ if (atomic_read(&psSysSpecData->sSGXClocksEnabled) == 0) -+ { -+ return; -+ } -+ -+ PVR_DPF((PVR_DBG_MESSAGE, "DisableSGXClocks: Disabling SGX Clocks")); -+ -+ clk_disable(psSysSpecData->psSGX_FCK); -+ -+ clk_disable(psSysSpecData->psSGX_ICK); -+ -+// SysDisableSGXInterrupts(psSysData); -+ -+#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) -+ { -+// int res = pm_runtime_put_sync(&gpsPVRLDMDev->dev); -+// if (res < 0) -+// { -+// PVR_DPF((PVR_DBG_ERROR, "DisableSGXClocks: pm_runtime_put_sync failed (%d)", -res)); -+// } -+ } -+#endif -+ -+ atomic_set(&psSysSpecData->sSGXClocksEnabled, 0); -+ -+#else -+ PVR_UNREFERENCED_PARAMETER(psSysData); -+#endif -+} -+ -+#if (defined(DEBUG) || defined(TIMING)) && !defined(PVR_NO_OMAP_TIMER) -+#if defined(PVR_OMAP_USE_DM_TIMER_API) -+#define GPTIMER_TO_USE 11 -+static PVRSRV_ERROR AcquireGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ PVR_ASSERT(psSysSpecData->psGPTimer == NULL); -+ -+ -+ psSysSpecData->psGPTimer = omap_dm_timer_request_specific(GPTIMER_TO_USE); -+ if (psSysSpecData->psGPTimer == NULL) -+ { -+ -+ PVR_DPF((PVR_DBG_WARNING, "%s: omap_dm_timer_request_specific failed", __FUNCTION__)); -+ return PVRSRV_ERROR_CLOCK_REQUEST_FAILED; -+ } -+ -+ -+ omap_dm_timer_set_source(psSysSpecData->psGPTimer, OMAP_TIMER_SRC_SYS_CLK); -+ omap_dm_timer_enable(psSysSpecData->psGPTimer); -+ -+ -+ omap_dm_timer_set_load_start(psSysSpecData->psGPTimer, 1, 0); -+ -+ omap_dm_timer_start(psSysSpecData->psGPTimer); -+ -+ -+ psSysSpecData->sTimerRegPhysBase.uiAddr = SYS_TI81xx_GP7TIMER_REGS_SYS_PHYS_BASE; -+ -+ return PVRSRV_OK; -+} -+ -+static void ReleaseGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ if (psSysSpecData->psGPTimer != NULL) -+ { -+ -+ (void) omap_dm_timer_stop(psSysSpecData->psGPTimer); -+ -+ omap_dm_timer_disable(psSysSpecData->psGPTimer); -+ -+ omap_dm_timer_free(psSysSpecData->psGPTimer); -+ -+ psSysSpecData->sTimerRegPhysBase.uiAddr = 0; -+ -+ psSysSpecData->psGPTimer = NULL; -+ } -+ -+} -+#else -+static PVRSRV_ERROR AcquireGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+#if defined(PVR_OMAP3_TIMING_PRCM) -+ struct clk *psCLK; -+ IMG_INT res; -+ IMG_INT rate; -+#endif -+ PVRSRV_ERROR eError; -+ -+ IMG_CPU_PHYADDR sTimerRegPhysBase; -+ IMG_HANDLE hTimerEnable; -+ IMG_UINT32 *pui32TimerEnable; -+#if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA) -+ PVR_ASSERT(psSysSpecData->sTimerRegPhysBase.uiAddr == 0); -+#endif -+ -+ -+#if defined(PVR_OMAP3_TIMING_PRCM) -+if(cpu_is_ti816x()) -+ psCLK = clk_get(NULL, "gpt6_fck"); -+else -+ psCLK = clk_get(NULL, "gpt6_fck"); -+ if (IS_ERR(psCLK)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get GPTIMER11 functional clock")); -+ goto ExitError; -+ } -+ psSysSpecData->psGPT11_FCK = psCLK; -+ -+if(cpu_is_ti816x()) -+ psCLK = clk_get(NULL, "gpt6_ick"); -+else -+ psCLK = clk_get(NULL, "gpt7_ick"); -+ if (IS_ERR(psCLK)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't get GPTIMER11 interface clock")); -+ goto ExitError; -+ } -+ psSysSpecData->psGPT11_ICK = psCLK; -+ -+ rate = clk_get_rate(psSysSpecData->psGPT11_FCK); -+ PVR_TRACE(("GPTIMER11 clock is %dMHz", HZ_TO_MHZ(rate))); -+ -+ res = clk_enable(psSysSpecData->psGPT11_FCK); -+ if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't enable GPTIMER11 functional clock (%d)", res)); -+ goto ExitError; -+ } -+ -+ res = clk_enable(psSysSpecData->psGPT11_ICK); -+ if (res < 0) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: Couldn't enable GPTIMER11 interface clock (%d)", res)); -+ goto ExitDisableGPT11FCK; -+ } -+#endif -+ -+ -+ sTimerRegPhysBase.uiAddr = SYS_TI81xx_GP7TIMER_TSICR_SYS_PHYS_BASE; -+ pui32TimerEnable = OSMapPhysToLin(sTimerRegPhysBase, -+ 4, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ &hTimerEnable); -+ -+ if (pui32TimerEnable == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: OSMapPhysToLin failed")); -+ goto ExitDisableGPT11ICK; -+ } -+ -+ if(!(*pui32TimerEnable & 4)) -+ { -+ PVR_TRACE(("Setting GPTIMER11 mode to posted (currently is non-posted)")); -+ -+ -+ *pui32TimerEnable |= 4; -+ } -+ -+ OSUnMapPhysToLin(pui32TimerEnable, -+ 4, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ hTimerEnable); -+ -+ -+ sTimerRegPhysBase.uiAddr = SYS_TI81xx_GP7TIMER_ENABLE_SYS_PHYS_BASE; -+ pui32TimerEnable = OSMapPhysToLin(sTimerRegPhysBase, -+ 4, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ &hTimerEnable); -+ -+ if (pui32TimerEnable == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSystemClocks: OSMapPhysToLin failed")); -+ goto ExitDisableGPT11ICK; -+ } -+ -+ *pui32TimerEnable = 3; -+ -+ OSUnMapPhysToLin(pui32TimerEnable, -+ 4, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ hTimerEnable); -+#if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA) -+ psSysSpecData->sTimerRegPhysBase = sTimerRegPhysBase; -+#endif -+ -+ eError = PVRSRV_OK; -+ -+ goto Exit; -+ -+ExitDisableGPT11ICK: -+#if defined(PVR_OMAP3_TIMING_PRCM) -+ clk_disable(psSysSpecData->psGPT11_ICK); -+ExitDisableGPT11FCK: -+ clk_disable(psSysSpecData->psGPT11_FCK); -+ExitError: -+#endif -+ eError = PVRSRV_ERROR_CLOCK_REQUEST_FAILED; -+Exit: -+ return eError; -+} -+ -+static void ReleaseGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ IMG_HANDLE hTimerDisable; -+ IMG_UINT32 *pui32TimerDisable; -+ IMG_CPU_PHYADDR TimerRegPhysBase; -+#if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA) -+ if (psSysSpecData->sTimerRegPhysBase.uiAddr == 0) -+ { -+ return; -+ } -+#endif -+ TimerRegPhysBase.uiAddr = SYS_TI81xx_GP7TIMER_ENABLE_SYS_PHYS_BASE; -+ pui32TimerDisable = OSMapPhysToLin(TimerRegPhysBase, -+ 4, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ &hTimerDisable); -+ -+ if (pui32TimerDisable == IMG_NULL) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "DisableSystemClocks: OSMapPhysToLin failed")); -+ } -+ else -+ { -+ *pui32TimerDisable = 0; -+ -+ OSUnMapPhysToLin(pui32TimerDisable, -+ 4, -+ PVRSRV_HAP_KERNEL_ONLY|PVRSRV_HAP_UNCACHED, -+ hTimerDisable); -+ } -+ -+#if defined(PVR_OMAP_TIMER_BASE_IN_SYS_SPEC_DATA) -+ psSysSpecData->sTimerRegPhysBase.uiAddr = 0; -+#endif -+ -+#if defined(PVR_OMAP3_TIMING_PRCM) -+ clk_disable(psSysSpecData->psGPT11_ICK); -+ -+ clk_disable(psSysSpecData->psGPT11_FCK); -+#endif -+} -+#endif -+#else -+static PVRSRV_ERROR AcquireGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ PVR_UNREFERENCED_PARAMETER(psSysSpecData); -+ return PVRSRV_OK; -+} -+static void ReleaseGPTimer(SYS_SPECIFIC_DATA *psSysSpecData) -+{ -+ PVR_UNREFERENCED_PARAMETER(psSysSpecData); -+} -+#endif -+ -+PVRSRV_ERROR EnableSystemClocks(SYS_DATA *psSysData) -+{ -+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; -+ struct clk *psCLK; -+ PVR_TRACE(("EnableSystemClocks: Enabling System Clocks")); -+ -+ if (!psSysSpecData->bSysClocksOneTimeInit) -+ { -+ mutex_init(&psSysSpecData->sPowerLock); -+ -+ atomic_set(&psSysSpecData->sSGXClocksEnabled, 0); -+ -+ -+ psCLK = clk_get(NULL, "sgx_ck"); -+ if (IS_ERR(psCLK)) -+ { -+ PVR_DPF((PVR_DBG_ERROR, "EnableSsystemClocks: Couldn't get SGX Functional Clock")); -+ return PVRSRV_ERROR_UNABLE_TO_GET_CLOCK; -+ } -+ psSysSpecData->psSGX_FCK = psCLK; -+ -+ } -+ -+ return AcquireGPTimer(psSysSpecData); -+} -+ -+IMG_VOID DisableSystemClocks(SYS_DATA *psSysData) -+{ -+ SYS_SPECIFIC_DATA *psSysSpecData = (SYS_SPECIFIC_DATA *) psSysData->pvSysSpecificData; -+ PVR_TRACE(("DisableSystemClocks: Disabling System Clocks")); -+ -+ DisableSGXClocks(psSysData); -+ -+ ReleaseGPTimer(psSysSpecData); -+ -+} -+ -+PVRSRV_ERROR SysPMRuntimeRegister(void) -+{ -+#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) -+// pm_runtime_enable(&gpsPVRLDMDev->dev); -+#endif -+ return PVRSRV_OK; -+} -+ -+PVRSRV_ERROR SysPMRuntimeUnregister(void) -+{ -+#if defined(LDM_PLATFORM) && !defined(PVR_DRI_DRM_NOT_PCI) -+// pm_runtime_disable(&gpsPVRLDMDev->dev); -+#endif -+ return PVRSRV_OK; -+} --- -1.8.5.1 - diff --git a/patches/sgx-blob/0002-NFM-use-drm-for-3.4-3.8.patch b/patches/sgx-blob/0002-NFM-use-drm-for-3.4-3.8.patch deleted file mode 100644 index f3342bc987906aca1788fda00d618a6c1ed5851d..0000000000000000000000000000000000000000 --- a/patches/sgx-blob/0002-NFM-use-drm-for-3.4-3.8.patch +++ /dev/null @@ -1,76 +0,0 @@ -From c541d2ca61f629d9c0bbf74db0dc252feeb24cf8 Mon Sep 17 00:00:00 2001 -From: Robert Nelson <robertcnelson@gmail.com> -Date: Fri, 20 Dec 2013 14:56:47 -0600 -Subject: [PATCH 2/2] NFM: use drm for 3.4-3.8 - -Signed-off-by: Robert Nelson <robertcnelson@gmail.com> ---- - .../ti-es8-sgx/services4/3rdparty/linux_drm/Kbuild | 40 +++++++++++----------- - 1 file changed, 20 insertions(+), 20 deletions(-) - -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/linux_drm/Kbuild b/drivers/staging/ti-es8-sgx/services4/3rdparty/linux_drm/Kbuild -index d01ef39..ccca3cd 100644 ---- a/drivers/staging/ti-es8-sgx/services4/3rdparty/linux_drm/Kbuild -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/linux_drm/Kbuild -@@ -26,38 +26,38 @@ endif - endif - - obj-m := drm.o --ifeq ($(TI_PLATFORM),omap4) --drm-y := pvr_drm_stubs.o drm_auth.o drm_bufs.o drm_cache.o drm_context.o drm_dma.o drm_drawable.o drm_drv.o drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \ -- drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \ -- drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \ -- drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o \ -- drm_crtc.o drm_modes.o drm_edid.o \ -- drm_info.o drm_debugfs.o drm_encoder_slave.o --else -+#ifeq ($(TI_PLATFORM),omap4) -+#drm-y := pvr_drm_stubs.o drm_auth.o drm_bufs.o drm_cache.o drm_context.o drm_dma.o drm_drawable.o drm_drv.o drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \ -+# drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \ -+# drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \ -+# drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o \ -+# drm_crtc.o drm_modes.o drm_edid.o \ -+# drm_info.o drm_debugfs.o drm_encoder_slave.o -+#else - # Works for 2.6.37 till 3.2 kernel --drm-y := pvr_drm_stubs.o drm_auth.o drm_bufs.o drm_cache.o drm_context.o drm_dma.o drm_drv.o drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \ -- drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \ -- drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \ -- drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o \ -- drm_crtc.o drm_modes.o drm_edid.o \ -- drm_info.o drm_debugfs.o drm_encoder_slave.o drm_global.o drm_platform.o drm_trace_points.o --endif -- --# For 3.3 kernel only - #drm-y := pvr_drm_stubs.o drm_auth.o drm_bufs.o drm_cache.o drm_context.o drm_dma.o drm_drv.o drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \ - # drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \ - # drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \ --# drm_sysfs.o drm_hashtab.o drm_mm.o \ -+# drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o \ - # drm_crtc.o drm_modes.o drm_edid.o \ - # drm_info.o drm_debugfs.o drm_encoder_slave.o drm_global.o drm_platform.o drm_trace_points.o -+#endif - --# For greater than/equal to 3.4 till 3.8 kernel -+# For 3.3 kernel only - #drm-y := pvr_drm_stubs.o drm_auth.o drm_bufs.o drm_cache.o drm_context.o drm_dma.o drm_drv.o drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \ - # drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \ - # drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \ - # drm_sysfs.o drm_hashtab.o drm_mm.o \ - # drm_crtc.o drm_modes.o drm_edid.o \ --# drm_info.o drm_debugfs.o drm_encoder_slave.o drm_global.o drm_platform.o drm_trace_points.o drm_prime.o -+# drm_info.o drm_debugfs.o drm_encoder_slave.o drm_global.o drm_platform.o drm_trace_points.o -+ -+# For greater than/equal to 3.4 till 3.8 kernel -+drm-y := pvr_drm_stubs.o drm_auth.o drm_bufs.o drm_cache.o drm_context.o drm_dma.o drm_drv.o drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \ -+ drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \ -+ drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \ -+ drm_sysfs.o drm_hashtab.o drm_mm.o \ -+ drm_crtc.o drm_modes.o drm_edid.o \ -+ drm_info.o drm_debugfs.o drm_encoder_slave.o drm_global.o drm_platform.o drm_trace_points.o drm_prime.o - - # less than 2.6.32 kernel - --- -1.8.5.1 - diff --git a/patches/sgx-blob/0003-NFW-sgx-drm_fasync-has-been-removed.patch b/patches/sgx-blob/0003-NFW-sgx-drm_fasync-has-been-removed.patch deleted file mode 100644 index 47b87ad4ad22b41b100f8ffda503e9bfb6f441ec..0000000000000000000000000000000000000000 --- a/patches/sgx-blob/0003-NFW-sgx-drm_fasync-has-been-removed.patch +++ /dev/null @@ -1,33 +0,0 @@ -From b93b8381e4e66e393785b03948e30714292a9470 Mon Sep 17 00:00:00 2001 -From: Robert Nelson <robertcnelson@gmail.com> -Date: Fri, 20 Dec 2013 14:58:31 -0600 -Subject: [PATCH 3/3] NFW: sgx: drm_fasync has been removed - -Signed-off-by: Robert Nelson <robertcnelson@gmail.com> ---- - drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/pvr_drm.c | 2 -- - 1 file changed, 2 deletions(-) - -diff --git a/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/pvr_drm.c b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/pvr_drm.c -index f59e544..6d6b3b5 100644 ---- a/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/pvr_drm.c -+++ b/drivers/staging/ti-es8-sgx/services4/srvkm/env/linux/pvr_drm.c -@@ -485,7 +485,6 @@ static const struct file_operations sPVRFileOps = - PVR_DRM_FOPS_IOCTL = drm_ioctl, - .mmap = PVRMMap, - .poll = drm_poll, -- .fasync = drm_fasync, - }; - #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) */ - -@@ -527,7 +526,6 @@ static struct drm_driver sPVRDrmDriver = - PVR_DRM_FOPS_IOCTL = drm_ioctl, - .mmap = PVRMMap, - .poll = drm_poll, -- .fasync = drm_fasync, - }, - #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) */ - #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39)) --- -1.8.5.1 - diff --git a/patches/sgx-blob/0004-NFM-SGX-enable-driver-building.patch b/patches/sgx-blob/0004-NFM-SGX-enable-driver-building.patch deleted file mode 100644 index 9c69bccb55db6748bcd10ba92b8cc407a6f1943e..0000000000000000000000000000000000000000 --- a/patches/sgx-blob/0004-NFM-SGX-enable-driver-building.patch +++ /dev/null @@ -1,229 +0,0 @@ -From 3fabd18010daf6c90c18de07b53f05474c77b81f Mon Sep 17 00:00:00 2001 -From: Robert Nelson <robertcnelson@gmail.com> -Date: Fri, 13 Dec 2013 10:10:59 -0600 -Subject: [PATCH 2/2] NFM: SGX enable driver building - -Signed-off-by: Robert Nelson <robertcnelson@gmail.com> ---- - drivers/staging/Kconfig | 2 + - drivers/staging/Makefile | 1 + - drivers/staging/ti-es8-sgx/Kbuild | 53 +++++++++++++--------- - drivers/staging/ti-es8-sgx/Kconfig | 9 ++++ - .../services4/3rdparty/bufferclass_ti/Kbuild | 6 +-- - .../services4/3rdparty/dc_ti335x_linux/Kbuild | 22 ++++----- - .../ti-es8-sgx/services4/3rdparty/linux_drm/Kbuild | 17 ++++--- - 7 files changed, 66 insertions(+), 44 deletions(-) - create mode 100644 drivers/staging/ti-es8-sgx/Kconfig - -diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig -index 3626dbc8..73faa87 100644 ---- a/drivers/staging/Kconfig -+++ b/drivers/staging/Kconfig -@@ -148,4 +148,6 @@ source "drivers/staging/dgnc/Kconfig" - - source "drivers/staging/dgap/Kconfig" - -+source "drivers/staging/ti-es8-sgx/Kconfig" -+ - endif # STAGING -diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile -index d1b4b80..10683e1 100644 ---- a/drivers/staging/Makefile -+++ b/drivers/staging/Makefile -@@ -66,3 +66,4 @@ obj-$(CONFIG_USB_BTMTK) += btmtk_usb/ - obj-$(CONFIG_XILLYBUS) += xillybus/ - obj-$(CONFIG_DGNC) += dgnc/ - obj-$(CONFIG_DGAP) += dgap/ -+obj-$(CONFIG_TI_ES8_SGX) += ti-es8-sgx/ -diff --git a/drivers/staging/ti-es8-sgx/Kbuild b/drivers/staging/ti-es8-sgx/Kbuild -index 3098a8d..9d75770 100755 ---- a/drivers/staging/ti-es8-sgx/Kbuild -+++ b/drivers/staging/ti-es8-sgx/Kbuild -@@ -1,3 +1,13 @@ -+# -+ -+BUILD=release -+OMAPES=8.x -+FBDEV=no -+ -+TI_PLATFORM=ti335x -+#SUPPORT_XORG=no -+#FBDEV=no -+ - obj-m := pvrsrvkm.o - - FILES := \ -@@ -42,19 +52,19 @@ services4/system/$(TI_PLATFORM)/sysutils.c \ - services4/system/$(TI_PLATFORM)/sysconfig.c \ - - ifneq ($(FBDEV),no) --EXTRA_CFLAGS += -DFBDEV_PRESENT -+ccflags-y += -DFBDEV_PRESENT - endif - - ifeq ($(TI_PLATFORM),ti43xx) - ifneq ($(PM_RUNTIME),no) --EXTRA_CFLAGS += -DPM_RUNTIME_SUPPORT -+ccflags-y += -DPM_RUNTIME_SUPPORT - endif - endif - - ifeq ($(TI_PLATFORM),ti335x) - ifneq ($(SUPPORT_XORG),1) - ifneq ($(PM_RUNTIME),no) --EXTRA_CFLAGS += -DPM_RUNTIME_SUPPORT -+ccflags-y += -DPM_RUNTIME_SUPPORT - endif - endif - endif -@@ -73,30 +83,31 @@ endif - endif - endif - --EXTRA_CFLAGS += -I$(src)/include4 --EXTRA_CFLAGS += -I$(src)/services4/include --EXTRA_CFLAGS += -I$(src)/services4/srvkm/include --EXTRA_CFLAGS += -I$(src)/services4/srvkm/hwdefs --EXTRA_CFLAGS += -I$(src)/services4/srvkm/bridged --EXTRA_CFLAGS += -I$(src)/services4/srvkm/devices/sgx --EXTRA_CFLAGS += -I$(src)/services4/srvkm/env/linux --EXTRA_CFLAGS += -I$(src)/services4/system/include --EXTRA_CFLAGS += -I$(src)/services4/system/$(TI_PLATFORM) --EXTRA_CFLAGS += -I$(src)/services4/srvkm/bridged/sgx --EXTRA_CFLAGS += -I$(KERNELDIR)/arch/arm/mach-omap2 -+ccflags-y += -DLINUX -+ccflags-y += -Idrivers/staging/ti-es8-sgx/include4 -+ccflags-y += -Idrivers/staging/ti-es8-sgx/services4/include -+ccflags-y += -Idrivers/staging/ti-es8-sgx/services4/srvkm/include -+ccflags-y += -Idrivers/staging/ti-es8-sgx/services4/srvkm/hwdefs -+ccflags-y += -Idrivers/staging/ti-es8-sgx/services4/srvkm/bridged -+ccflags-y += -Idrivers/staging/ti-es8-sgx/services4/srvkm/devices/sgx -+ccflags-y += -Idrivers/staging/ti-es8-sgx/services4/srvkm/env/linux -+ccflags-y += -Idrivers/staging/ti-es8-sgx/services4/system/include -+ccflags-y += -Idrivers/staging/ti-es8-sgx/services4/system/$(TI_PLATFORM) -+ccflags-y += -Idrivers/staging/ti-es8-sgx/services4/srvkm/bridged/sgx -+ccflags-y += -Iarch/arm/mach-omap2 - - ifeq ($(SUPPORT_XORG),1) --EXTRA_CFLAGS += -I$(KERNELDIR)/include/drm --EXTRA_CFLAGS += -I$(src)/services4/3rdparty/linux_drm --EXTRA_CFLAGS += -I$(src)/services4/include/env/linux --EXTRA_CFLAGS += -I$(KERNELDIR)/drivers/video/omap2 --EXTRA_CFLAGS += -I$(KERNELDIR)/arch/arm/plat-omap/include -+ccflags-y += -Iinclude/drm -+ccflags-y += -Idrivers/staging/ti-es8-sgx/services4/3rdparty/linux_drm -+ccflags-y += -Idrivers/staging/ti-es8-sgx/services4/include/env/linux -+ccflags-y += -Idrivers/video/omap2 -+ccflags-y += -Iarch/arm/plat-omap/include - ifeq ($(TI_PLATFORM),omap4) --EXTRA_CFLAGS += -DCONFIG_SLOW_WORK -+ccflags-y += -DCONFIG_SLOW_WORK - endif - endif - --EXTRA_CFLAGS += $(ALL_CFLAGS) -+ccflags-y += $(ALL_CFLAGS) - - pvrsrvkm-y := $(FILES:.c=.o) - -diff --git a/drivers/staging/ti-es8-sgx/Kconfig b/drivers/staging/ti-es8-sgx/Kconfig -new file mode 100644 -index 0000000..41c7937 ---- /dev/null -+++ b/drivers/staging/ti-es8-sgx/Kconfig -@@ -0,0 +1,9 @@ -+# -+# TI SGX Driver Support -+# -+ -+config TI_ES8_SGX -+ bool "TI ES8 SGX support (TI: 5.00.00.01)" -+ depends on RESET_TI && m -+ help -+ This is TI's ES8 SGX Kernel Modules 5.00.00.01 -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_ti/Kbuild b/drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_ti/Kbuild -index c6f3b93..87c5364 100755 ---- a/drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_ti/Kbuild -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/bufferclass_ti/Kbuild -@@ -1,6 +1,6 @@ --EXTRA_CFLAGS = -DLINUX \ -- -I$(PVR_BUILD_DIR)/include4 \ -- -I$(PVR_BUILD_DIR)/services4/include -+ccflags-y += -DLINUX -+ccflags-y += -Idrivers/staging/ti-es8-sgx/include4 -+ccflags-y += -Idrivers/staging/ti-es8-sgx/services4/include - - ifeq ($(TI_PLATFORM),ti81xx) - EXTRA_CFLAGS += -DPLAT_TI81xx -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti335x_linux/Kbuild b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti335x_linux/Kbuild -index 1ae23593..6e98a6d 100644 ---- a/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti335x_linux/Kbuild -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/dc_ti335x_linux/Kbuild -@@ -9,22 +9,22 @@ SYS_CFLAGS.$(SUPPORT_TI_DSS_FW) += -DSUPPORT_TI_DSS_FW - SYS_CFLAGS.$(PVR_LINUX_USING_WORKQUEUES) += -DPVR_LINUX_USING_WORKQUEUES - SYS_CFLAGS += -DDISPLAY_CONTROLLER=omaplfb - --EXTRA_CFLAGS = -DLINUX \ -- -DCONFIG_OMAP2_DSS \ -- -I$(PVR_BUILD_DIR)/include4 \ -- -I$(PVR_BUILD_DIR)/services4/include \ -- -I$(PVR_BUILD_DIR)/services4/system/$(PVR_SYSTEM) \ -- -I$(KERNELDIR)/drivers/video/omap2 \ -- -I$(PVR_BUILD_DIR)/services4/system/include \ -- $(SYS_CFLAGS.1) \ -+ccflags-y += -DLINUX -+ccflags-y += -DCONFIG_OMAP2_DSS -+ccflags-y += -Idrivers/staging/ti-es8-sgx/include4 -+ccflags-y += -Idrivers/staging/ti-es8-sgx/services4/include -+ccflags-y += -Idrivers/staging/ti-es8-sgx/services4/system/$(PVR_SYSTEM) -+ccflags-y += -Idrivers/video/omap2 -+ccflags-y += -Idrivers/staging/ti-es8-sgx/services4/system/include -+ccflags-y += $(SYS_CFLAGS.1) - - ifneq ($(FBDEV),no) --EXTRA_CFLAGS += -DFBDEV_PRESENT -+ccflags-y += -DFBDEV_PRESENT - endif - - ifeq ($(SUPPORT_XORG),1) --EXTRA_CFLAGS += -DSUPPORT_DRI_DRM --EXTRA_CFLAGS += -DPVR_DISPLAY_CONTROLLER_DRM_IOCTL -+ccflags-y += -DSUPPORT_DRI_DRM -+ccflags-y += -DPVR_DISPLAY_CONTROLLER_DRM_IOCTL - endif - - -diff --git a/drivers/staging/ti-es8-sgx/services4/3rdparty/linux_drm/Kbuild b/drivers/staging/ti-es8-sgx/services4/3rdparty/linux_drm/Kbuild -index d01ef39..23f8990 100755 ---- a/drivers/staging/ti-es8-sgx/services4/3rdparty/linux_drm/Kbuild -+++ b/drivers/staging/ti-es8-sgx/services4/3rdparty/linux_drm/Kbuild -@@ -10,18 +10,17 @@ SYS_CFLAGS.$(PVR_LINUX_USING_WORKQUEUES) += -DPVR_LINUX_USING_WORKQU - - EXT_SOURCE_DIR := $(KERNELDIR)/drivers/gpu/drm - --EXTRA_CFLAGS = -DLINUX \ -- -DCONFIG_PCI \ -- -Wno-error \ -- -I$(KERNELDIR)/include/drm \ -- -I$(KERNELDIR)/include/linux \ -- -I$(EXT_SOURCE_DIR) \ -- $(SYS_CFLAGS.1) \ -+ccflags-y += -DLINUX -+ccflags-y += -DCONFIG_PCI -+ccflags-y += -Wno-error -+ccflags-y += -Iinclude/drm -+ccflags-y += -Iinclude/linux -+ccflags-y += $(SYS_CFLAGS.1) - - ifeq ($(SUPPORT_DRI_DRM),1) --EXTRA_CFLAGS += -DPVR_DISPLAY_CONTROLLER_DRM_IOCTL -+ccflags-y += -DPVR_DISPLAY_CONTROLLER_DRM_IOCTL - ifeq ($(TI_PLATFORM),omap4) --EXTRA_CFLAGS += -DCONFIG_SLOW_WORK -+ccflags-y += -DCONFIG_SLOW_WORK - endif - endif - --- -1.8.5.1 - diff --git a/patches/sgx/0001-HACK-drm-fb_helper-enable-panning-support.patch b/patches/sgx/0001-HACK-drm-fb_helper-enable-panning-support.patch deleted file mode 100644 index 620eefee4eaa020e6f7c284b5a08fb5d7f8e8806..0000000000000000000000000000000000000000 --- a/patches/sgx/0001-HACK-drm-fb_helper-enable-panning-support.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 7bd5a1f82a078dfa67bf85d3b5d9e6ed32a2be31 Mon Sep 17 00:00:00 2001 -From: Darren Etheridge <detheridge@ti.com> -Date: Thu, 24 Jul 2014 11:49:28 -0500 -Subject: [PATCH 1/7] HACK: drm/fb_helper: enable panning support - -Increase the size of the buffer that is created in the fbdev emulation -helpers. And fill in the var structure with the amount that was allocated. - -Signed-off-by: Darren Etheridge <detheridge@ti.com> ---- - drivers/gpu/drm/drm_fb_cma_helper.c | 10 ++++++++-- - 1 file changed, 8 insertions(+), 2 deletions(-) - -diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c b/drivers/gpu/drm/drm_fb_cma_helper.c -index c19a625..fd260f3 100644 ---- a/drivers/gpu/drm/drm_fb_cma_helper.c -+++ b/drivers/gpu/drm/drm_fb_cma_helper.c -@@ -25,6 +25,12 @@ - #include <drm/drm_fb_cma_helper.h> - #include <linux/module.h> - -+/* -+ * number of buffers to allocate from CMA pool, often increased for -+ * double/triple buffering -+ */ -+#define DRM_NUM_FBDEV_BUFFERS 3 -+ - struct drm_fb_cma { - struct drm_framebuffer fb; - struct drm_gem_cma_object *obj[4]; -@@ -253,7 +259,7 @@ static int drm_fbdev_cma_create(struct drm_fb_helper *helper, - bytes_per_pixel = DIV_ROUND_UP(sizes->surface_bpp, 8); - - mode_cmd.width = sizes->surface_width; -- mode_cmd.height = sizes->surface_height; -+ mode_cmd.height = sizes->surface_height * DRM_NUM_FBDEV_BUFFERS; - mode_cmd.pitches[0] = sizes->surface_width * bytes_per_pixel; - mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp, - sizes->surface_depth); -@@ -284,7 +290,7 @@ static int drm_fbdev_cma_create(struct drm_fb_helper *helper, - fbi->fbops = &drm_fbdev_cma_ops; - - drm_fb_helper_fill_fix(fbi, fb->pitches[0], fb->depth); -- drm_fb_helper_fill_var(fbi, helper, sizes->fb_width, sizes->fb_height); -+ drm_fb_helper_fill_var(fbi, helper, sizes->fb_width, sizes->surface_height); - - offset = fbi->var.xoffset * bytes_per_pixel; - offset += fbi->var.yoffset * fb->pitches[0]; --- -2.6.4 - diff --git a/patches/sgx/0002-HACK-drm-tilcdc-add-vsync-callback-for-use-in-omaplf.patch b/patches/sgx/0002-HACK-drm-tilcdc-add-vsync-callback-for-use-in-omaplf.patch deleted file mode 100644 index 8cc2e8ffc65a106b9eebf5d3289d0d89480d3dbb..0000000000000000000000000000000000000000 --- a/patches/sgx/0002-HACK-drm-tilcdc-add-vsync-callback-for-use-in-omaplf.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 6756e4d8df80a903c74f91ea0812e2c349cc28f6 Mon Sep 17 00:00:00 2001 -From: Darren Etheridge <detheridge@ti.com> -Date: Fri, 11 Jul 2014 09:15:25 -0500 -Subject: [PATCH 2/7] HACK: drm/tilcdc: add vsync callback for use in omaplfb - for gpu - -Add a vsync callback registration API that is identical to what was done -for da8xx-fb.c. - -Need to find if there is a better way using the DRM infrastructure from -kernel space. Either that or change the userspace window manager stuff in -the gpu libraries to make use of the DRM provided syncronization -mechanisms. - -Signed-off-by: Darren Etheridge <detheridge@ti.com> ---- - drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 34 ++++++++++++++++++++++++++++++++++ - drivers/gpu/drm/tilcdc/tilcdc_drv.h | 5 +++++ - 2 files changed, 39 insertions(+) - -diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -index 7d07733..4764183 100644 ---- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -@@ -41,6 +41,10 @@ struct tilcdc_crtc { - /* Only set if an external encoder is connected */ - bool simulate_vesa_sync; - }; -+ -+static vsync_callback_t vsync_cb_handler; -+static void *vsync_cb_arg; -+ - #define to_tilcdc_crtc(x) container_of(x, struct tilcdc_crtc, base) - - static void unref_worker(struct drm_flip_work *work, void *val) -@@ -611,6 +615,32 @@ out: - pm_runtime_put_sync(dev->dev); - } - -+int register_vsync_cb(vsync_callback_t handler, void *arg, int idx) -+{ -+ if ((vsync_cb_handler == NULL) && (vsync_cb_arg == NULL)) { -+ vsync_cb_arg = arg; -+ vsync_cb_handler = handler; -+ } else { -+ return -EEXIST; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL(register_vsync_cb); -+ -+int unregister_vsync_cb(vsync_callback_t handler, void *arg, int idx) -+{ -+ if ((vsync_cb_handler == handler) && (vsync_cb_arg == arg)) { -+ vsync_cb_handler = NULL; -+ vsync_cb_arg = NULL; -+ } else { -+ return -ENXIO; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL(unregister_vsync_cb); -+ - irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc) - { - struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); -@@ -645,6 +675,10 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc) - tilcdc_crtc->event = NULL; - if (event) - drm_send_vblank_event(dev, 0, event); -+ -+ if (vsync_cb_handler) -+ vsync_cb_handler(vsync_cb_arg); -+ - spin_unlock_irqrestore(&dev->event_lock, flags); - - if (dirty && !tilcdc_crtc->dirty) -diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.h b/drivers/gpu/drm/tilcdc/tilcdc_drv.h -index e863ad0..a6713ae 100644 ---- a/drivers/gpu/drm/tilcdc/tilcdc_drv.h -+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.h -@@ -173,4 +173,9 @@ void tilcdc_crtc_set_simulate_vesa_sync(struct drm_crtc *crtc, - int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode); - int tilcdc_crtc_max_width(struct drm_crtc *crtc); - -+/* used by SGX OMAPLFB drvier */ -+typedef void (*vsync_callback_t)(void *arg); -+int register_vsync_cb(vsync_callback_t handler, void *arg, int idx); -+int unregister_vsync_cb(vsync_callback_t handler, void *arg, int idx); -+ - #endif /* __TILCDC_DRV_H__ */ --- -2.6.4 - diff --git a/patches/sgx/0003-drm-tilcdc-fix-the-ping-pong-dma-tearing-issue-seen-.patch b/patches/sgx/0003-drm-tilcdc-fix-the-ping-pong-dma-tearing-issue-seen-.patch deleted file mode 100644 index b51a3b9c04b4dec029d24b5be2de5211e1a240cc..0000000000000000000000000000000000000000 --- a/patches/sgx/0003-drm-tilcdc-fix-the-ping-pong-dma-tearing-issue-seen-.patch +++ /dev/null @@ -1,97 +0,0 @@ -From 5571745daafb0898fba8306c7d4fe918585786d3 Mon Sep 17 00:00:00 2001 -From: Darren Etheridge <detheridge@ti.com> -Date: Fri, 18 Jul 2014 16:21:46 -0500 -Subject: [PATCH 3/7] drm/tilcdc: fix the ping-pong dma tearing issue seen on - buffer flipping - -Update the DMA pointers during the pan display ioctl. Borrowed from -da8xx_fb.c update the scanout buffers immediately so the DMA ping/pong -doesn't end up out of sync with what we really want it to DMA. - -Signed-off-by: Darren Etheridge <detheridge@ti.com> ---- - drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 36 +++++++++++++++++++++++++++++++----- - 1 file changed, 31 insertions(+), 5 deletions(-) - -diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -index 4764183..4f345ea 100644 ---- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c -@@ -31,6 +31,8 @@ struct tilcdc_crtc { - int dpms; - wait_queue_head_t frame_done_wq; - bool frame_done; -+ spinlock_t irq_lock; -+ int dma_completed_channel; - - /* fb currently set to scanout 0/1: */ - struct drm_framebuffer *scanout[2]; -@@ -106,10 +108,23 @@ static void update_scanout(struct drm_crtc *crtc) - (crtc->mode.vdisplay * fb->pitches[0]); - - if (tilcdc_crtc->dpms == DRM_MODE_DPMS_ON) { -- /* already enabled, so just mark the frames that need -- * updating and they will be updated on vblank: -+ /* -+ * already enabled, so just mark the frames that need -+ * updating and they will be updated on vblank -+ * and update the inactive DMA channel immediately -+ * to avoid any tearing due to the DMA already starting -+ * on the pending dma buffer when we hit the vblank IRQ - */ -- tilcdc_crtc->dirty |= LCDC_END_OF_FRAME0 | LCDC_END_OF_FRAME1; -+ if (tilcdc_crtc->dma_completed_channel == 0) { -+ tilcdc_crtc->dirty |= LCDC_END_OF_FRAME1; -+ set_scanout(crtc, 0); -+ } -+ -+ if (tilcdc_crtc->dma_completed_channel == 1) { -+ tilcdc_crtc->dirty |= LCDC_END_OF_FRAME0; -+ set_scanout(crtc, 1); -+ } -+ - drm_vblank_get(dev, 0); - } else { - /* not enabled yet, so update registers immediately: */ -@@ -647,6 +662,7 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc) - struct drm_device *dev = crtc->dev; - struct tilcdc_drm_private *priv = dev->dev_private; - uint32_t stat = tilcdc_read_irqstatus(dev); -+ unsigned long irq_flags; - - if ((stat & LCDC_SYNC_LOST) && (stat & LCDC_FIFO_UNDERFLOW)) { - stop(crtc); -@@ -662,11 +678,19 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc) - - tilcdc_clear_irqstatus(dev, stat); - -- if (dirty & LCDC_END_OF_FRAME0) -+ spin_lock_irqsave(&tilcdc_crtc->irq_lock, irq_flags); -+ -+ if (dirty & LCDC_END_OF_FRAME0) { - set_scanout(crtc, 0); -+ tilcdc_crtc->dma_completed_channel = 0; -+ } - -- if (dirty & LCDC_END_OF_FRAME1) -+ if (dirty & LCDC_END_OF_FRAME1) { - set_scanout(crtc, 1); -+ tilcdc_crtc->dma_completed_channel = 1; -+ } -+ -+ spin_unlock_irqrestore(&tilcdc_crtc->irq_lock, irq_flags); - - drm_handle_vblank(dev, 0); - -@@ -736,6 +760,8 @@ struct drm_crtc *tilcdc_crtc_create(struct drm_device *dev) - drm_flip_work_init(&tilcdc_crtc->unref_work, - "unref", unref_worker); - -+ spin_lock_init(&tilcdc_crtc->irq_lock); -+ - ret = drm_crtc_init(dev, crtc, &tilcdc_crtc_funcs); - if (ret < 0) - goto fail; --- -2.6.4 - diff --git a/patches/sgx/0004-ARM-OMAP2-Use-pdata-quirks-for-sgx-deassert_hardrese.patch b/patches/sgx/0004-ARM-OMAP2-Use-pdata-quirks-for-sgx-deassert_hardrese.patch deleted file mode 100644 index 410f9902f72a178c123c96b868eda30e30902f5c..0000000000000000000000000000000000000000 --- a/patches/sgx/0004-ARM-OMAP2-Use-pdata-quirks-for-sgx-deassert_hardrese.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 5052acd8c5a313511673ec09a29971515434eb69 Mon Sep 17 00:00:00 2001 -From: Darren Etheridge <detheridge@ti.com> -Date: Fri, 25 Jul 2014 16:09:53 -0500 -Subject: [PATCH 4/7] ARM: OMAP2+: Use pdata-quirks for sgx deassert_hardreset - -Use pdata_quirks to provide platform data to the sgx driver. -The data that is provided includes: - -1) Function pointers for the driver to use to reset the h/w block. -2) The reset name that matches with what is used in hwmod. - -Signed-off-by: Darren Etheridge <detheridge@ti.com> ---- - arch/arm/mach-omap2/pdata-quirks.c | 12 ++++++++++++ - include/linux/platform_data/sgx-omap.h | 22 ++++++++++++++++++++++ - 2 files changed, 34 insertions(+) - create mode 100644 include/linux/platform_data/sgx-omap.h - -diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c -index 339b859..573d72f 100644 ---- a/arch/arm/mach-omap2/pdata-quirks.c -+++ b/arch/arm/mach-omap2/pdata-quirks.c -@@ -24,6 +24,7 @@ - #include <linux/platform_data/iommu-omap.h> - #include <linux/platform_data/wkup_m3.h> - #include <linux/platform_data/pwm_omap_dmtimer.h> -+#include <linux/platform_data/sgx-omap.h> - #include <plat/dmtimer.h> - - #include "common.h" -@@ -43,6 +44,13 @@ struct pdata_init { - static struct of_dev_auxdata omap_auxdata_lookup[]; - static struct twl4030_gpio_platform_data twl_gpio_auxdata; - -+#if defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_AM43XX) -+static struct gfx_sgx_platform_data gfx_pdata = { -+ .reset_name = "gfx", -+ .deassert_reset = omap_device_deassert_hardreset, -+}; -+#endif -+ - #ifdef CONFIG_MACH_NOKIA_N8X0 - static void __init omap2420_n8x0_legacy_init(void) - { -@@ -484,6 +492,10 @@ static struct of_dev_auxdata omap_auxdata_lookup[] __initdata = { - OF_DEV_AUXDATA("ti,am3352-wkup-m3", 0x44d00000, "44d00000.wkup_m3", - &wkup_m3_data), - #endif -+#if defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_AM43XX) -+ OF_DEV_AUXDATA("ti,sgx", 0x56000000, "56000000.sgx", -+ &gfx_pdata), -+#endif - #ifdef CONFIG_ARCH_OMAP4 - OF_DEV_AUXDATA("ti,omap4-padconf", 0x4a100040, "4a100040.pinmux", &pcs_pdata), - OF_DEV_AUXDATA("ti,omap4-padconf", 0x4a31e040, "4a31e040.pinmux", &pcs_pdata), -diff --git a/include/linux/platform_data/sgx-omap.h b/include/linux/platform_data/sgx-omap.h -new file mode 100644 -index 0000000..aa59b2c ---- /dev/null -+++ b/include/linux/platform_data/sgx-omap.h -@@ -0,0 +1,22 @@ -+/* -+ * SGX Graphics Driver Platform Data -+ * -+ * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ -+ * Darren Etheridge <detheridge@ti.com> -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any -+ * kind, whether express or implied; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+#include <linux/platform_device.h> -+ -+struct gfx_sgx_platform_data { -+ const char *reset_name; -+ -+ int (*deassert_reset)(struct platform_device *pdev, const char *name); -+}; --- -2.7.0.rc3 - diff --git a/patches/sgx/0005-ARM-dts-am33xx-add-DT-node-for-gpu.patch b/patches/sgx/0005-ARM-dts-am33xx-add-DT-node-for-gpu.patch deleted file mode 100644 index c90217ee1c9306052fce889a202c8988e4f4d5a8..0000000000000000000000000000000000000000 --- a/patches/sgx/0005-ARM-dts-am33xx-add-DT-node-for-gpu.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 94bd03b85ee326790fcba2318d3ff08e0f223c11 Mon Sep 17 00:00:00 2001 -From: Darren Etheridge <detheridge@ti.com> -Date: Fri, 18 Jul 2014 16:19:54 -0500 -Subject: [PATCH 5/7] ARM: dts: am33xx: add DT node for gpu - -Add the node into the am33xx.dtsi file for the SGX GPU -that is found in some variants of the SoC. - -Signed-off-by: Darren Etheridge <detheridge@ti.com> ---- - arch/arm/boot/dts/am33xx.dtsi | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi -index 1dde0a1..c7ba3b5 100644 ---- a/arch/arm/boot/dts/am33xx.dtsi -+++ b/arch/arm/boot/dts/am33xx.dtsi -@@ -905,6 +905,13 @@ - reg = <0x48310000 0x2000>; - interrupts = <111>; - }; -+ -+ sgx@0x56000000 { -+ compatible = "ti,sgx"; -+ ti,hwmods = "gfx"; -+ reg = <0x56000000 0x1000000>; -+ interrupts = <37>; -+ }; - }; - }; - --- -2.6.4 - diff --git a/patches/sgx/0006-Revert-ARM-reduce-visibility-of-dmac_-functions.patch b/patches/sgx/0006-Revert-ARM-reduce-visibility-of-dmac_-functions.patch deleted file mode 100644 index 47b4337bb30403d8dd4634630c0ba577f3b654ea..0000000000000000000000000000000000000000 --- a/patches/sgx/0006-Revert-ARM-reduce-visibility-of-dmac_-functions.patch +++ /dev/null @@ -1,104 +0,0 @@ -From 054c0c9cdb598b32dd31ab40aa359c59c51ac793 Mon Sep 17 00:00:00 2001 -From: Robert Nelson <robertcnelson@gmail.com> -Date: Mon, 4 Jan 2016 11:00:59 -0600 -Subject: [PATCH 6/7] Revert "ARM: reduce visibility of dmac_* functions" - -This reverts commit 1234e3fda9aa24b2d650bbcd9ef09d5f6a12dc86. - -Signed-off-by: Robert Nelson <robertcnelson@gmail.com> ---- - arch/arm/include/asm/cacheflush.h | 4 ++++ - arch/arm/include/asm/glue-cache.h | 2 ++ - arch/arm/mm/dma-mapping.c | 1 - - arch/arm/mm/dma.h | 32 -------------------------------- - 4 files changed, 6 insertions(+), 33 deletions(-) - delete mode 100644 arch/arm/mm/dma.h - -diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h -index d5525bf..46d06f6 100644 ---- a/arch/arm/include/asm/cacheflush.h -+++ b/arch/arm/include/asm/cacheflush.h -@@ -140,6 +140,8 @@ extern struct cpu_cache_fns cpu_cache; - * is visible to DMA, or data written by DMA to system memory is - * visible to the CPU. - */ -+#define dmac_map_area cpu_cache.dma_map_area -+#define dmac_unmap_area cpu_cache.dma_unmap_area - #define dmac_flush_range cpu_cache.dma_flush_range - - #else -@@ -159,6 +161,8 @@ extern void __cpuc_flush_dcache_area(void *, size_t); - * is visible to DMA, or data written by DMA to system memory is - * visible to the CPU. - */ -+extern void dmac_map_area(const void *, size_t, int); -+extern void dmac_unmap_area(const void *, size_t, int); - extern void dmac_flush_range(const void *, const void *); - - #endif -diff --git a/arch/arm/include/asm/glue-cache.h b/arch/arm/include/asm/glue-cache.h -index cab07f6..a3c24cd 100644 ---- a/arch/arm/include/asm/glue-cache.h -+++ b/arch/arm/include/asm/glue-cache.h -@@ -158,6 +158,8 @@ static inline void nop_dma_unmap_area(const void *s, size_t l, int f) { } - #define __cpuc_coherent_user_range __glue(_CACHE,_coherent_user_range) - #define __cpuc_flush_dcache_area __glue(_CACHE,_flush_kern_dcache_area) - -+#define dmac_map_area __glue(_CACHE,_dma_map_area) -+#define dmac_unmap_area __glue(_CACHE,_dma_unmap_area) - #define dmac_flush_range __glue(_CACHE,_dma_flush_range) - #endif - -diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c -index ad4eb2d..3623669 100644 ---- a/arch/arm/mm/dma-mapping.c -+++ b/arch/arm/mm/dma-mapping.c -@@ -39,7 +39,6 @@ - #include <asm/system_info.h> - #include <asm/dma-contiguous.h> - --#include "dma.h" - #include "mm.h" - - /* -diff --git a/arch/arm/mm/dma.h b/arch/arm/mm/dma.h -deleted file mode 100644 -index 70ea6852..0000000 ---- a/arch/arm/mm/dma.h -+++ /dev/null -@@ -1,32 +0,0 @@ --#ifndef DMA_H --#define DMA_H -- --#include <asm/glue-cache.h> -- --#ifndef MULTI_CACHE --#define dmac_map_area __glue(_CACHE,_dma_map_area) --#define dmac_unmap_area __glue(_CACHE,_dma_unmap_area) -- --/* -- * These are private to the dma-mapping API. Do not use directly. -- * Their sole purpose is to ensure that data held in the cache -- * is visible to DMA, or data written by DMA to system memory is -- * visible to the CPU. -- */ --extern void dmac_map_area(const void *, size_t, int); --extern void dmac_unmap_area(const void *, size_t, int); -- --#else -- --/* -- * These are private to the dma-mapping API. Do not use directly. -- * Their sole purpose is to ensure that data held in the cache -- * is visible to DMA, or data written by DMA to system memory is -- * visible to the CPU. -- */ --#define dmac_map_area cpu_cache.dma_map_area --#define dmac_unmap_area cpu_cache.dma_unmap_area -- --#endif -- --#endif --- -2.6.4 - diff --git a/patches/sgx/0007-arm-Export-cache-flush-management-symbols-when-MULTI.patch b/patches/sgx/0007-arm-Export-cache-flush-management-symbols-when-MULTI.patch deleted file mode 100644 index 78a3b4c4dad591878c6187c34ee4cafaafef3f66..0000000000000000000000000000000000000000 --- a/patches/sgx/0007-arm-Export-cache-flush-management-symbols-when-MULTI.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 22b297d642930612244399b3b53a8410547740d3 Mon Sep 17 00:00:00 2001 -From: Pantelis Antoniou <panto@antoniou-consulting.com> -Date: Fri, 4 Jan 2013 00:32:33 +0200 -Subject: [PATCH 7/7] arm: Export cache flush management symbols when - !MULTI_CACHE - -When compiling a kernel without CONFIG_MULTI_CACHE enabled the -dma access functions end up not being exported. Fix it. - -Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com> ---- - arch/arm/kernel/setup.c | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c -index 20edd34..4e84a54 100644 ---- a/arch/arm/kernel/setup.c -+++ b/arch/arm/kernel/setup.c -@@ -1163,3 +1163,12 @@ const struct seq_operations cpuinfo_op = { - .stop = c_stop, - .show = c_show - }; -+ -+/* export the cache management functions */ -+#ifndef MULTI_CACHE -+ -+EXPORT_SYMBOL(__glue(_CACHE,_dma_map_area)); -+EXPORT_SYMBOL(__glue(_CACHE,_dma_unmap_area)); -+EXPORT_SYMBOL(__glue(_CACHE,_dma_flush_range)); -+ -+#endif --- -2.6.4 - diff --git a/patches/ti/ticpufreq/0001-Documentation-dt-add-bindings-for-ti-cpufreq.patch b/patches/ti/ticpufreq/0001-Documentation-dt-add-bindings-for-ti-cpufreq.patch new file mode 100644 index 0000000000000000000000000000000000000000..3371095227b2228fe865c1d6818e7598df397ae8 --- /dev/null +++ b/patches/ti/ticpufreq/0001-Documentation-dt-add-bindings-for-ti-cpufreq.patch @@ -0,0 +1,117 @@ +From 59c19659184909e85dc4bd2ff49fb3ae133ae5f3 Mon Sep 17 00:00:00 2001 +From: Dave Gerlach <d-gerlach@ti.com> +Date: Wed, 18 May 2016 18:30:25 -0500 +Subject: [PATCH 01/10] Documentation: dt: add bindings for ti-cpufreq + +Add the device tree bindings document for the TI CPUFreq/OPP driver +on AM33xx and AM43xx SoCs. The operating-points-v2 binding allows us +to provide an opp-supported-hw property for each OPP to define when +it is available. This driver is responsible for reading and parsing +registers to determine which OPPs can be selectively enabled based +on the specific SoC in use by matching against the opp-supported-hw +data. + +Signed-off-by: Dave Gerlach <d-gerlach@ti.com> +--- + .../devicetree/bindings/cpufreq/ti-cpufreq.txt | 89 ++++++++++++++++++++++ + 1 file changed, 89 insertions(+) + create mode 100644 Documentation/devicetree/bindings/cpufreq/ti-cpufreq.txt + +diff --git a/Documentation/devicetree/bindings/cpufreq/ti-cpufreq.txt b/Documentation/devicetree/bindings/cpufreq/ti-cpufreq.txt +new file mode 100644 +index 0000000..f719b2d +--- /dev/null ++++ b/Documentation/devicetree/bindings/cpufreq/ti-cpufreq.txt +@@ -0,0 +1,89 @@ ++Bindings for TI's CPUFreq driver ++================================ ++ ++The ti-cpufreq driver works with the operating-points-v2 binding described ++at [../opp/opp.txt] to make sure the proper OPPs for a platform get enabled ++and then creates a "cpufreq-dt" platform device to leverage the cpufreq-dt ++driver described in [cpufreq-dt.txt]. ++ ++Certain TI SoCs, like those in the am335x, am437x, am57xx, and dra7xx ++families support different OPPs depending on the silicon variant in use. ++The ti-cpufreq driver uses the revision and an efuse value from the SoC to ++provide the OPP framework with supported hardware information. This is used ++to determine which OPPs from the operating-points-v2 table get enabled. In ++order to maintain backwards compatilibity if this information is not present ++the "cpufreq-dt" platform device is still created to attempt to find an ++operating-points (v1) table, otherwise no OPPs will be available because ++safe OPPs cannot be determined. ++ ++Required properties: ++-------------------- ++In 'cpus' nodes: ++- operating-points-v2: Phandle to the operating-points-v2 table to use ++- ti,syscon-efuse: Syscon phandle, offset to efuse register, efuse register ++ mask, and efuse register shift to get the relevant bits ++ that describe OPP availability ++- ti,syscon-rev: Syscon and offset used to look up revision value on SoC ++ ++In 'operating-points-v2' table: ++- opp-supported-hw: Two bitfields indicating: ++ 1. Which revision of the SoC the OPP is supported by ++ 2. Which eFuse bits indicate this OPP is available ++ ++ A bitwise and is performed against these values and if any bit ++ matches, the OPP gets enabled. ++ ++NOTE: Without the above, platform-device for "cpufreq-dt" is still created ++ but no determination of which OPPs should be available is done, but this ++ allows for use of a v1 operating-points table. ++ ++Example: ++-------- ++ ++/* From arch/arm/boot/dts/am4372.dtsi */ ++cpus { ++ cpu: cpu@0 { ++ ... ++ ++ operating-points-v2 = <&cpu0_opp_table>; ++ ++ ti,syscon-efuse = <&scm_conf 0x610 0x3f 0>; ++ ti,syscon-rev = <&scm_conf 0x600>; ++ ++ ... ++ }; ++}; ++ ++cpu0_opp_table: opp_table0 { ++ compatible = "operating-points-v2"; ++ opp50@300000000 { ++ opp-hz = /bits/ 64 <300000000>; ++ opp-microvolt = <950000>; ++ opp-supported-hw = <0xFF 0x01>; ++ opp-suspend; ++ }; ++ ++ opp100@600000000 { ++ opp-hz = /bits/ 64 <600000000>; ++ opp-microvolt = <1100000>; ++ opp-supported-hw = <0xFF 0x04>; ++ }; ++ ++ opp120@720000000 { ++ opp-hz = /bits/ 64 <720000000>; ++ opp-microvolt = <1200000>; ++ opp-supported-hw = <0xFF 0x08>; ++ }; ++ ++ oppturbo@800000000 { ++ opp-hz = /bits/ 64 <800000000>; ++ opp-microvolt = <1260000>; ++ opp-supported-hw = <0xFF 0x10>; ++ }; ++ ++ oppnitro@1000000000 { ++ opp-hz = /bits/ 64 <1000000000>; ++ opp-microvolt = <1325000>; ++ opp-supported-hw = <0xFF 0x20>; ++ }; ++}; +-- +2.8.1 + diff --git a/patches/ti/ticpufreq/0002-cpufreq-ti-Add-cpufreq-driver-to-determine-available.patch b/patches/ti/ticpufreq/0002-cpufreq-ti-Add-cpufreq-driver-to-determine-available.patch new file mode 100644 index 0000000000000000000000000000000000000000..1be894e6261acc8560e4041aea1aa3488cb86109 --- /dev/null +++ b/patches/ti/ticpufreq/0002-cpufreq-ti-Add-cpufreq-driver-to-determine-available.patch @@ -0,0 +1,327 @@ +From ce2d04a4cb8ccc0fbd9dfb7f7e0e26831828178c Mon Sep 17 00:00:00 2001 +From: Dave Gerlach <d-gerlach@ti.com> +Date: Wed, 18 May 2016 18:30:26 -0500 +Subject: [PATCH 02/10] cpufreq: ti: Add cpufreq driver to determine available + OPPs at runtime + +Some TI SoCs, like those in the AM335x, AM437x, DRA7x, and AM57x families, +have different OPPs available for the MPU depending on which specific +variant of the SoC is in use. This can be determined through use of the +revision and an eFuse register present in the silicon. Introduce a +ti-cpufreq driver that can read the aformentioned values and provide +them as version matching data to the opp framework. Through this the +opp-supported-hw dt binding that is part of the operating-points-v2 +table can be used to indicate availability of OPPs for each device. + +This driver also creates the "cpufreq-dt" platform_device after passing +the version matching data to the OPP framework so that the cpufreq-dt +handles the actual cpufreq implementation. Even without the necessary +data to pass the version matching data the driver will still create this +device to maintain backwards compatibility with operating-points v1 +tables. + +Signed-off-by: Dave Gerlach <d-gerlach@ti.com> +--- + drivers/cpufreq/Kconfig.arm | 11 ++ + drivers/cpufreq/Makefile | 1 + + drivers/cpufreq/ti-cpufreq.c | 254 +++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 266 insertions(+) + create mode 100644 drivers/cpufreq/ti-cpufreq.c + +diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm +index d89b8af..0dea6849 100644 +--- a/drivers/cpufreq/Kconfig.arm ++++ b/drivers/cpufreq/Kconfig.arm +@@ -234,6 +234,17 @@ config ARM_TEGRA124_CPUFREQ + help + This adds the CPUFreq driver support for Tegra124 SOCs. + ++config ARM_TI_CPUFREQ ++ tristate "Texas Instruments CPUFreq support" ++ depends on ARCH_OMAP2PLUS ++ help ++ This driver enables valid OPPs on the running platform based on ++ values contained within the SoC in use. Enable this in order to ++ use the cpufreq-dt driver on all Texas Instruments platforms that ++ provide dt based operating-points-v2 tables with opp-supported-hw ++ data provided. Required for cpufreq support on AM335x, AM437x, ++ DRA7x, and AM57x platforms. ++ + config ARM_PXA2xx_CPUFREQ + tristate "Intel PXA2xx CPUfreq driver" + depends on PXA27x || PXA25x +diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile +index e1eb11e..e38efde 100644 +--- a/drivers/cpufreq/Makefile ++++ b/drivers/cpufreq/Makefile +@@ -77,6 +77,7 @@ obj-$(CONFIG_ARM_SPEAR_CPUFREQ) += spear-cpufreq.o + obj-$(CONFIG_ARM_STI_CPUFREQ) += sti-cpufreq.o + obj-$(CONFIG_ARM_TEGRA20_CPUFREQ) += tegra20-cpufreq.o + obj-$(CONFIG_ARM_TEGRA124_CPUFREQ) += tegra124-cpufreq.o ++obj-$(CONFIG_ARM_TI_CPUFREQ) += ti-cpufreq.o + obj-$(CONFIG_ARM_VEXPRESS_SPC_CPUFREQ) += vexpress-spc-cpufreq.o + obj-$(CONFIG_ACPI_CPPC_CPUFREQ) += cppc_cpufreq.o + obj-$(CONFIG_MACH_MVEBU_V7) += mvebu-cpufreq.o +diff --git a/drivers/cpufreq/ti-cpufreq.c b/drivers/cpufreq/ti-cpufreq.c +new file mode 100644 +index 0000000..e47b452 +--- /dev/null ++++ b/drivers/cpufreq/ti-cpufreq.c +@@ -0,0 +1,254 @@ ++/* ++ * TI CPUFreq/OPP hw-supported driver ++ * ++ * Copyright (C) 2016 Texas Instruments, Inc. ++ * Dave Gerlach <d-gerlach@ti.com> ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include <linux/cpu.h> ++#include <linux/io.h> ++#include <linux/mfd/syscon.h> ++#include <linux/module.h> ++#include <linux/of.h> ++#include <linux/of_platform.h> ++#include <linux/pm_opp.h> ++#include <linux/regmap.h> ++ ++#define REVISION_MASK (0xF << 28) ++#define REVISION_SHIFT 28 ++ ++#define DRA7_EFUSE_HAS_OD_MPU_OPP 11 ++#define DRA7_EFUSE_HAS_HIGH_MPU_OPP 15 ++#define DRA7_EFUSE_HAS_ALL_MPU_OPP 23 ++ ++#define DRA7_EFUSE_NOM_MPU_OPP BIT(0) ++#define DRA7_EFUSE_OD_MPU_OPP BIT(1) ++#define DRA7_EFUSE_HIGH_MPU_OPP BIT(2) ++ ++#define VERSION_COUNT 2 ++ ++static struct ti_cpufreq_data { ++ struct device *cpu; ++ struct regmap *opp_efuse; ++ struct regmap *revision; ++} opp_data; ++ ++static struct ti_cpufreq_soc_data { ++ unsigned long (*efuse_xlate)(unsigned long efuse); ++} *soc_data; ++ ++static unsigned long amx3_efuse_xlate(unsigned long efuse) ++{ ++ /* AM335x and AM437x use "OPP disable" bits, so invert */ ++ return ~efuse; ++} ++ ++static unsigned long dra7_efuse_xlate(unsigned long efuse) ++{ ++ unsigned long calculated_efuse = DRA7_EFUSE_NOM_MPU_OPP; ++ ++ /* ++ * The efuse on dra7 and am57 parts contains a specific ++ * value indicating the highest available OPP. ++ */ ++ ++ switch (efuse) { ++ case DRA7_EFUSE_HAS_ALL_MPU_OPP: ++ case DRA7_EFUSE_HAS_HIGH_MPU_OPP: ++ calculated_efuse |= DRA7_EFUSE_HIGH_MPU_OPP; ++ case DRA7_EFUSE_HAS_OD_MPU_OPP: ++ calculated_efuse |= DRA7_EFUSE_OD_MPU_OPP; ++ } ++ ++ return calculated_efuse; ++} ++ ++static struct ti_cpufreq_soc_data amx3_soc_data = { ++ .efuse_xlate = amx3_efuse_xlate, ++}; ++ ++static struct ti_cpufreq_soc_data dra7_soc_data = { ++ .efuse_xlate = dra7_efuse_xlate, ++}; ++ ++/** ++ * ti_cpufreq_get_efuse() - Parse and return efuse value present on SoC ++ * @efuse_value: Set to the value parsed from efuse ++ * ++ * Returns error code if efuse not read properly. ++ */ ++static int ti_cpufreq_get_efuse(u32 *efuse_value) ++{ ++ struct device *dev = opp_data.cpu; ++ struct device_node *np = dev->of_node; ++ unsigned int efuse_offset; ++ u32 efuse, efuse_mask, efuse_shift; ++ int ret; ++ ++ ret = of_property_read_u32_index(np, "ti,syscon-efuse", ++ 1, &efuse_offset); ++ if (ret) { ++ dev_err(dev, ++ "No efuse offset provided %s: %d\n", ++ np->full_name, ret); ++ return ret; ++ } ++ ++ ret = of_property_read_u32_index(np, "ti,syscon-efuse", 2, ++ &efuse_mask); ++ if (ret) ++ efuse_mask = 0xffffffff; ++ ++ ret = of_property_read_u32_index(np, "ti,syscon-efuse", 3, ++ &efuse_shift); ++ if (ret) ++ efuse_shift = 0; ++ ++ ret = regmap_read(opp_data.opp_efuse, efuse_offset, &efuse); ++ if (ret) { ++ dev_err(dev, ++ "Failed to read the efuse value from syscon: %d\n", ++ ret); ++ return ret; ++ } ++ ++ efuse = (efuse & efuse_mask) >> efuse_shift; ++ ++ *efuse_value = soc_data->efuse_xlate(efuse); ++ ++ return 0; ++} ++ ++/** ++ * ti_cpufreq_get_rev() - Parse and return rev value present on SoC ++ * @revision_value: Set to the value parsed from revision register ++ * ++ * Returns error code if revision not read properly. ++ */ ++static int ti_cpufreq_get_rev(u32 *revision_value) ++{ ++ struct device *dev = opp_data.cpu; ++ struct device_node *np = dev->of_node; ++ unsigned int revision_offset; ++ u32 revision; ++ int ret; ++ ++ ret = of_property_read_u32_index(np, "ti,syscon-rev", ++ 1, &revision_offset); ++ if (ret) { ++ dev_err(dev, ++ "No revision offset provided %s [%d]\n", ++ np->full_name, ret); ++ return ret; ++ } ++ ++ ret = regmap_read(opp_data.revision, revision_offset, &revision); ++ if (ret) { ++ dev_err(dev, ++ "Failed to read the revision number from syscon: %d\n", ++ ret); ++ return ret; ++ } ++ ++ *revision_value = BIT((revision & REVISION_MASK) >> REVISION_SHIFT); ++ ++ return 0; ++} ++ ++static int ti_cpufreq_setup_syscon_registers(void) ++{ ++ struct device *dev = opp_data.cpu; ++ struct device_node *np = dev->of_node; ++ ++ opp_data.opp_efuse = syscon_regmap_lookup_by_phandle(np, ++ "ti,syscon-efuse"); ++ if (IS_ERR(opp_data.opp_efuse)) { ++ dev_dbg(dev, "\"ti,syscon-efuse\" is missing, cannot use OPPv2 table.\n"); ++ return PTR_ERR(opp_data.opp_efuse); ++ } ++ ++ opp_data.revision = syscon_regmap_lookup_by_phandle(np, ++ "ti,syscon-rev"); ++ if (IS_ERR(opp_data.revision)) { ++ dev_dbg(dev, "\"ti,syscon-rev\" is missing, cannot use OPPv2 table.\n"); ++ return PTR_ERR(opp_data.revision); ++ } ++ ++ return 0; ++} ++ ++static struct ti_cpufreq_soc_data *ti_cpufreq_get_soc_data(void) ++{ ++ if (of_machine_is_compatible("ti,am33xx") || ++ of_machine_is_compatible("ti,am4372")) ++ return &amx3_soc_data; ++ else if (of_machine_is_compatible("ti,dra7")) ++ return &dra7_soc_data; ++ else ++ return NULL; ++} ++ ++static int ti_cpufreq_init(void) ++{ ++ int ret; ++ u32 version[VERSION_COUNT]; ++ ++ soc_data = ti_cpufreq_get_soc_data(); ++ if (!soc_data) ++ return -ENODEV; ++ ++ opp_data.cpu = get_cpu_device(0); ++ if (!opp_data.cpu) { ++ pr_err("%s: Failed to get device for CPU0\n", __func__); ++ return -ENODEV; ++ } ++ ++ if (!of_get_property(opp_data.cpu->of_node, "operating-points-v2", ++ NULL)) { ++ dev_info(opp_data.cpu, "OPP-v2 not supported, cpufreq-dt will attempt to use legacy tables.\n"); ++ goto register_cpufreq_dt; ++ } ++ ++ ret = ti_cpufreq_setup_syscon_registers(); ++ if (ret) ++ goto register_cpufreq_dt; ++ ++ /* ++ * OPPs determine whether or not they are supported based on ++ * two metrics: ++ * 0 - SoC Revision ++ * 1 - eFuse value ++ */ ++ ret = ti_cpufreq_get_rev(&version[0]); ++ if (ret) ++ return ret; ++ ++ ret = ti_cpufreq_get_efuse(&version[1]); ++ if (ret) ++ return ret; ++ ++ ret = dev_pm_opp_set_supported_hw(opp_data.cpu, version, VERSION_COUNT); ++ if (ret) { ++ dev_err(opp_data.cpu, "Failed to set supported hardware\n"); ++ return ret; ++ } ++ ++register_cpufreq_dt: ++ platform_device_register_simple("cpufreq-dt", -1, NULL, 0); ++ ++ return 0; ++} ++module_init(ti_cpufreq_init); ++ ++MODULE_DESCRIPTION("TI CPUFreq/OPP hw-supported driver"); ++MODULE_AUTHOR("Dave Gerlach <d-gerlach@ti.com>"); ++MODULE_LICENSE("GPL v2"); +-- +2.8.1 + diff --git a/patches/ti/ticpufreq/0003-ARM-dts-am335x-Update-MPU-regulator-range-for-TI-boa.patch b/patches/ti/ticpufreq/0003-ARM-dts-am335x-Update-MPU-regulator-range-for-TI-boa.patch new file mode 100644 index 0000000000000000000000000000000000000000..b083515b572b51c9ee1b03c2e1c094c447b40592 --- /dev/null +++ b/patches/ti/ticpufreq/0003-ARM-dts-am335x-Update-MPU-regulator-range-for-TI-boa.patch @@ -0,0 +1,60 @@ +From 63b05cc31d98171d1092648453d8905b3565839c Mon Sep 17 00:00:00 2001 +From: Dave Gerlach <d-gerlach@ti.com> +Date: Wed, 18 May 2016 18:36:26 -0500 +Subject: [PATCH 03/10] ARM: dts: am335x: Update MPU regulator range for TI + boards + +Now that we are moving to OPPv2 bindings and able to add 1GHz OPP for +MPU, let's update the max MPU voltage range to align with the maximum +possible value allowed in the operating-points table, which is max +target voltage of 132500 uV + 2%. + +Signed-off-by: Dave Gerlach <d-gerlach@ti.com> +--- + arch/arm/boot/dts/am335x-bone-common.dtsi | 2 +- + arch/arm/boot/dts/am335x-evm.dts | 2 +- + arch/arm/boot/dts/am335x-evmsk.dts | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi +index 0cc150b..13133f3 100644 +--- a/arch/arm/boot/dts/am335x-bone-common.dtsi ++++ b/arch/arm/boot/dts/am335x-bone-common.dtsi +@@ -318,7 +318,7 @@ + /* VDD_MPU voltage limits 0.95V - 1.26V with +/-4% tolerance */ + regulator-name = "vdd_mpu"; + regulator-min-microvolt = <925000>; +- regulator-max-microvolt = <1325000>; ++ regulator-max-microvolt = <1351500>; + regulator-boot-on; + regulator-always-on; + }; +diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts +index 516673b..5d28712 100644 +--- a/arch/arm/boot/dts/am335x-evm.dts ++++ b/arch/arm/boot/dts/am335x-evm.dts +@@ -640,7 +640,7 @@ + /* VDD_MPU voltage limits 0.95V - 1.26V with +/-4% tolerance */ + regulator-name = "vdd_mpu"; + regulator-min-microvolt = <912500>; +- regulator-max-microvolt = <1312500>; ++ regulator-max-microvolt = <1351500>; + regulator-boot-on; + regulator-always-on; + }; +diff --git a/arch/arm/boot/dts/am335x-evmsk.dts b/arch/arm/boot/dts/am335x-evmsk.dts +index 282fe1b..09308d6 100644 +--- a/arch/arm/boot/dts/am335x-evmsk.dts ++++ b/arch/arm/boot/dts/am335x-evmsk.dts +@@ -560,7 +560,7 @@ + /* VDD_MPU voltage limits 0.95V - 1.26V with +/-4% tolerance */ + regulator-name = "vdd_mpu"; + regulator-min-microvolt = <912500>; +- regulator-max-microvolt = <1312500>; ++ regulator-max-microvolt = <1351500>; + regulator-boot-on; + regulator-always-on; + }; +-- +2.8.1 + diff --git a/patches/ti/ticpufreq/0004-ARM-dts-am33xx-Move-to-operating-points-v2-table-and.patch b/patches/ti/ticpufreq/0004-ARM-dts-am33xx-Move-to-operating-points-v2-table-and.patch new file mode 100644 index 0000000000000000000000000000000000000000..c2da54226edc0e2f6300dc59172921a12b145b49 --- /dev/null +++ b/patches/ti/ticpufreq/0004-ARM-dts-am33xx-Move-to-operating-points-v2-table-and.patch @@ -0,0 +1,130 @@ +From dbf098cf075a38d364a38e8c3faf5db49e75ca8e Mon Sep 17 00:00:00 2001 +From: Dave Gerlach <d-gerlach@ti.com> +Date: Wed, 18 May 2016 18:36:27 -0500 +Subject: [PATCH 04/10] ARM: dts: am33xx: Move to operating-points-v2 table and + ti-cpufreq driver + +Drop the operating-points table present in am33xx.dtsi and add an +operating-points-v2 table with all OPPs available for all silicon +revisions along with necessary data for use by ti-cpufreq to selectively +enable the appropriate OPPs at runtime. Also, drop the voltage-tolerance +value and provide voltages for each OPP using the <target min max> +format instead. + +Information from AM335x Data Manual, SPRS717i, Revised December 2015, +Table 5-7. + +Signed-off-by: Dave Gerlach <d-gerlach@ti.com> +--- + arch/arm/boot/dts/am33xx.dtsi | 88 ++++++++++++++++++++++++++++++++++++------- + 1 file changed, 75 insertions(+), 13 deletions(-) + +diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi +index 52be48b..df1106f 100644 +--- a/arch/arm/boot/dts/am33xx.dtsi ++++ b/arch/arm/boot/dts/am33xx.dtsi +@@ -45,19 +45,9 @@ + device_type = "cpu"; + reg = <0>; + +- /* +- * To consider voltage drop between PMIC and SoC, +- * tolerance value is reduced to 2% from 4% and +- * voltage value is increased as a precaution. +- */ +- operating-points = < +- /* kHz uV */ +- 720000 1285000 +- 600000 1225000 +- 500000 1125000 +- 275000 1125000 +- >; +- voltage-tolerance = <2>; /* 2 percentage */ ++ operating-points-v2 = <&cpu0_opp_table>; ++ ti,syscon-efuse = <&scm_conf 0x7fc 0x1fff 0>; ++ ti,syscon-rev = <&scm_conf 0x600>; + + clocks = <&dpll_mpu_ck>; + clock-names = "cpu"; +@@ -66,6 +56,78 @@ + }; + }; + ++ cpu0_opp_table: opp_table0 { ++ compatible = "operating-points-v2"; ++ ++ /* ++ * The three following nodes are marked with opp-suspend ++ * because the can not be enabled simultaneously on a ++ * single SoC. ++ */ ++ opp50@300000000 { ++ opp-hz = /bits/ 64 <300000000>; ++ opp-microvolt = <950000 931000 969000>; ++ opp-supported-hw = <0x06 0x0010>; ++ opp-suspend; ++ }; ++ ++ opp100@275000000 { ++ opp-hz = /bits/ 64 <275000000>; ++ opp-microvolt = <1100000 1078000 1122000>; ++ opp-supported-hw = <0x01 0x00FF>; ++ opp-suspend; ++ }; ++ ++ opp100@300000000 { ++ opp-hz = /bits/ 64 <300000000>; ++ opp-microvolt = <1100000 1078000 1122000>; ++ opp-supported-hw = <0x06 0x0020>; ++ opp-suspend; ++ }; ++ ++ opp100@500000000 { ++ opp-hz = /bits/ 64 <500000000>; ++ opp-microvolt = <1100000 1078000 1122000>; ++ opp-supported-hw = <0x01 0xFFFF>; ++ }; ++ ++ opp100@600000000 { ++ opp-hz = /bits/ 64 <600000000>; ++ opp-microvolt = <1100000 1078000 1122000>; ++ opp-supported-hw = <0x06 0x0040>; ++ }; ++ ++ opp120@600000000 { ++ opp-hz = /bits/ 64 <600000000>; ++ opp-microvolt = <1200000 1176000 1224000>; ++ opp-supported-hw = <0x01 0xFFFF>; ++ }; ++ ++ opp120@720000000 { ++ opp-hz = /bits/ 64 <720000000>; ++ opp-microvolt = <1200000 1176000 1224000>; ++ opp-supported-hw = <0x06 0x0080>; ++ }; ++ ++ oppturbo@720000000 { ++ opp-hz = /bits/ 64 <720000000>; ++ opp-microvolt = <1260000 1234800 1285200>; ++ opp-supported-hw = <0x01 0xFFFF>; ++ }; ++ ++ oppturbo@800000000 { ++ opp-hz = /bits/ 64 <800000000>; ++ opp-microvolt = <1260000 1234800 1285200>; ++ opp-supported-hw = <0x06 0x0100>; ++ }; ++ ++ oppnitro@1000000000 { ++ opp-hz = /bits/ 64 <1000000000>; ++ opp-microvolt = <1325000 1298500 1351500>; ++ opp-supported-hw = <0x04 0x0200>; ++ }; ++ }; ++ + pmu { + compatible = "arm,cortex-a8-pmu"; + interrupts = <3>; +-- +2.8.1 + diff --git a/patches/ti/ticpufreq/0005-ARM-dts-am335x-boneblack-Enable-1GHz-OPP-for-cpu.patch b/patches/ti/ticpufreq/0005-ARM-dts-am335x-boneblack-Enable-1GHz-OPP-for-cpu.patch new file mode 100644 index 0000000000000000000000000000000000000000..1ba10d0b462241979dc30d4996fa7f5e1db60828 --- /dev/null +++ b/patches/ti/ticpufreq/0005-ARM-dts-am335x-boneblack-Enable-1GHz-OPP-for-cpu.patch @@ -0,0 +1,40 @@ +From 9cd95617ef8775bf10d3c113c9a9e564e083b9ec Mon Sep 17 00:00:00 2001 +From: Dave Gerlach <d-gerlach@ti.com> +Date: Wed, 18 May 2016 18:36:28 -0500 +Subject: [PATCH 05/10] ARM: dts: am335x-boneblack: Enable 1GHz OPP for cpu + +Although all PG2.0 silicon may not support 1GHz OPP for the MPU, older +Beaglebone Blacks may have PG2.0 silicon populated and these particular +parts are guaranteed to support the OPP, so enable it for PG2.0 on +am335x-boneblack only. + +Signed-off-by: Dave Gerlach <d-gerlach@ti.com> +--- + arch/arm/boot/dts/am335x-boneblack.dts | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/arch/arm/boot/dts/am335x-boneblack.dts b/arch/arm/boot/dts/am335x-boneblack.dts +index 55c0e95..ca72167 100644 +--- a/arch/arm/boot/dts/am335x-boneblack.dts ++++ b/arch/arm/boot/dts/am335x-boneblack.dts +@@ -33,6 +33,17 @@ + status = "okay"; + }; + ++&cpu0_opp_table { ++ /* ++ * All PG 2.0 silicon may not support 1GHz but some of the early ++ * BeagleBone Blacks have PG 2.0 silicon which is guaranteed ++ * to support 1GHz OPP so enable it for PG 2.0 on this board. ++ */ ++ oppnitro@1000000000 { ++ opp-supported-hw = <0x06 0x0100>; ++ }; ++}; ++ + &am33xx_pinmux { + nxp_hdmi_bonelt_pins: nxp_hdmi_bonelt_pins { + pinctrl-single,pins = < +-- +2.8.1 + diff --git a/patches/ti/ticpufreq/0006-ARM-dts-am4372-Add-operating-points-v2-table.patch b/patches/ti/ticpufreq/0006-ARM-dts-am4372-Add-operating-points-v2-table.patch new file mode 100644 index 0000000000000000000000000000000000000000..c72f2f1b7fb1307b86d159c05d0dde9064bdcf31 --- /dev/null +++ b/patches/ti/ticpufreq/0006-ARM-dts-am4372-Add-operating-points-v2-table.patch @@ -0,0 +1,74 @@ +From dec4ac12b1f6a3dc6a00f5584d6d8787bffa3faf Mon Sep 17 00:00:00 2001 +From: Dave Gerlach <d-gerlach@ti.com> +Date: Wed, 18 May 2016 18:36:29 -0500 +Subject: [PATCH 06/10] ARM: dts: am4372: Add operating-points-v2 table + +Add an operating-points-v2 table with all OPPs available for all silicon +revisions along with necessary data for use by ti-cpufreq to selectively +enable the appropriate OPPs at runtime. + +Information from AM437x Data Manual, SPRS851B, Revised April 2015, +Table 5-2. + +Signed-off-by: Dave Gerlach <d-gerlach@ti.com> +--- + arch/arm/boot/dts/am4372.dtsi | 39 +++++++++++++++++++++++++++++++++++++++ + 1 file changed, 39 insertions(+) + +diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi +index 12fcde4..8bf2db2 100644 +--- a/arch/arm/boot/dts/am4372.dtsi ++++ b/arch/arm/boot/dts/am4372.dtsi +@@ -44,10 +44,49 @@ + clocks = <&dpll_mpu_ck>; + clock-names = "cpu"; + ++ operating-points-v2 = <&cpu0_opp_table>; ++ ti,syscon-efuse = <&scm_conf 0x610 0x3f 0>; ++ ti,syscon-rev = <&scm_conf 0x600>; ++ + clock-latency = <300000>; /* From omap-cpufreq driver */ + }; + }; + ++ cpu0_opp_table: opp_table0 { ++ compatible = "operating-points-v2"; ++ ++ opp50@300000000 { ++ opp-hz = /bits/ 64 <300000000>; ++ opp-microvolt = <950000 931000 969000>; ++ opp-supported-hw = <0xFF 0x01>; ++ opp-suspend; ++ }; ++ ++ opp100@600000000 { ++ opp-hz = /bits/ 64 <600000000>; ++ opp-microvolt = <1100000 1078000 1122000>; ++ opp-supported-hw = <0xFF 0x04>; ++ }; ++ ++ opp120@720000000 { ++ opp-hz = /bits/ 64 <720000000>; ++ opp-microvolt = <1200000 1176000 1224000>; ++ opp-supported-hw = <0xFF 0x08>; ++ }; ++ ++ oppturbo@800000000 { ++ opp-hz = /bits/ 64 <800000000>; ++ opp-microvolt = <1260000 1234800 1285200>; ++ opp-supported-hw = <0xFF 0x10>; ++ }; ++ ++ oppnitro@1000000000 { ++ opp-hz = /bits/ 64 <1000000000>; ++ opp-microvolt = <1325000 1298500 1351500>; ++ opp-supported-hw = <0xFF 0x20>; ++ }; ++ }; ++ + gic: interrupt-controller@48241000 { + compatible = "arm,cortex-a9-gic"; + interrupt-controller; +-- +2.8.1 + diff --git a/patches/ti/ticpufreq/0007-ARM-dts-am437x-gp-evm-Hook-dcdc2-as-the-cpu0-supply.patch b/patches/ti/ticpufreq/0007-ARM-dts-am437x-gp-evm-Hook-dcdc2-as-the-cpu0-supply.patch new file mode 100644 index 0000000000000000000000000000000000000000..2ed7d1a5156d9beff285fcc5f785cfbc3cefca4b --- /dev/null +++ b/patches/ti/ticpufreq/0007-ARM-dts-am437x-gp-evm-Hook-dcdc2-as-the-cpu0-supply.patch @@ -0,0 +1,27 @@ +From 1ddd4b782ab5624e5bcf51e93f1f4908a12ddc96 Mon Sep 17 00:00:00 2001 +From: Dave Gerlach <d-gerlach@ti.com> +Date: Wed, 18 May 2016 18:36:30 -0500 +Subject: [PATCH 07/10] ARM: dts: am437x-gp-evm: Hook dcdc2 as the cpu0-supply + +Hook dcdc2 as the cpu0-supply. + +Signed-off-by: Dave Gerlach <d-gerlach@ti.com> +--- + arch/arm/boot/dts/am437x-gp-evm.dts | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/arch/arm/boot/dts/am437x-gp-evm.dts b/arch/arm/boot/dts/am437x-gp-evm.dts +index 5bcd3aa..84832bf 100644 +--- a/arch/arm/boot/dts/am437x-gp-evm.dts ++++ b/arch/arm/boot/dts/am437x-gp-evm.dts +@@ -975,3 +975,7 @@ + clock-names = "ext-clk", "int-clk"; + status = "okay"; + }; ++ ++&cpu { ++ cpu0-supply = <&dcdc2>; ++}; +-- +2.8.1 + diff --git a/patches/ti/ticpufreq/0008-ARM-dts-dra7-Add-dt-node-for-the-syscon-control-modu.patch b/patches/ti/ticpufreq/0008-ARM-dts-dra7-Add-dt-node-for-the-syscon-control-modu.patch new file mode 100644 index 0000000000000000000000000000000000000000..304557a046ef95e3a37785a8b843eb0024be55ae --- /dev/null +++ b/patches/ti/ticpufreq/0008-ARM-dts-dra7-Add-dt-node-for-the-syscon-control-modu.patch @@ -0,0 +1,33 @@ +From 52b3516ac04333459f0b030cd2cdc1a36ad83d5a Mon Sep 17 00:00:00 2001 +From: Dave Gerlach <d-gerlach@ti.com> +Date: Wed, 18 May 2016 18:36:31 -0500 +Subject: [PATCH 08/10] ARM: dts: dra7: Add dt node for the syscon control + module wkup + +Create a system control module node for the control module portion that +resides under l4_wkup. + +Signed-off-by: Dave Gerlach <d-gerlach@ti.com> +--- + arch/arm/boot/dts/dra7.dtsi | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi +index e73edc2..dfe9678 100644 +--- a/arch/arm/boot/dts/dra7.dtsi ++++ b/arch/arm/boot/dts/dra7.dtsi +@@ -233,6 +233,11 @@ + prm_clockdomains: clockdomains { + }; + }; ++ ++ scm_wkup: scm_conf@c000 { ++ compatible = "syscon"; ++ reg = <0xc000 0x1000>; ++ }; + }; + + axi@0 { +-- +2.8.1 + diff --git a/patches/ti/ticpufreq/0009-ARM-dts-dra7-Move-cpus-node-to-parent-dts-for-dra74x.patch b/patches/ti/ticpufreq/0009-ARM-dts-dra7-Move-cpus-node-to-parent-dts-for-dra74x.patch new file mode 100644 index 0000000000000000000000000000000000000000..8a9199fa461307855cae9d093a7c50f5c4e1d849 --- /dev/null +++ b/patches/ti/ticpufreq/0009-ARM-dts-dra7-Move-cpus-node-to-parent-dts-for-dra74x.patch @@ -0,0 +1,120 @@ +From 7b8af01428953c089582a7c906b916b64c0d4d3d Mon Sep 17 00:00:00 2001 +From: Dave Gerlach <d-gerlach@ti.com> +Date: Wed, 18 May 2016 18:36:32 -0500 +Subject: [PATCH 09/10] ARM: dts: dra7: Move cpus node to parent dts for dra74x + and dra72x + +Nearly all of the information in the cpus node, especially for cpu0, is +the same between dra74x and dra72x so move the common information to +the parent dra7.dtsi to avoid duplication of data. + +Signed-off-by: Dave Gerlach <d-gerlach@ti.com> +--- + arch/arm/boot/dts/dra7.dtsi | 27 +++++++++++++++++++++++++++ + arch/arm/boot/dts/dra72x.dtsi | 16 ---------------- + arch/arm/boot/dts/dra74x.dtsi | 24 ------------------------ + 3 files changed, 27 insertions(+), 40 deletions(-) + +diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi +index dfe9678..7ff4ae4 100644 +--- a/arch/arm/boot/dts/dra7.dtsi ++++ b/arch/arm/boot/dts/dra7.dtsi +@@ -73,6 +73,33 @@ + interrupt-parent = <&gic>; + }; + ++ cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ cpu0: cpu@0 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a15"; ++ reg = <0>; ++ ++ operating-points = < ++ /* kHz uV */ ++ 1000000 1060000 ++ 1176000 1160000 ++ >; ++ ++ clocks = <&dpll_mpu_ck>; ++ clock-names = "cpu"; ++ ++ clock-latency = <300000>; /* From omap-cpufreq driver */ ++ ++ /* cooling options */ ++ cooling-min-level = <0>; ++ cooling-max-level = <2>; ++ #cooling-cells = <2>; /* min followed by max */ ++ }; ++ }; ++ + /* + * The soc node represents the soc top level view. It is used for IPs + * that are not memory mapped in the MPU view or for the MPU itself. +diff --git a/arch/arm/boot/dts/dra72x.dtsi b/arch/arm/boot/dts/dra72x.dtsi +index 70a2170..6710760 100644 +--- a/arch/arm/boot/dts/dra72x.dtsi ++++ b/arch/arm/boot/dts/dra72x.dtsi +@@ -12,22 +12,6 @@ + / { + compatible = "ti,dra722", "ti,dra72", "ti,dra7"; + +- cpus { +- #address-cells = <1>; +- #size-cells = <0>; +- +- cpu0: cpu@0 { +- device_type = "cpu"; +- compatible = "arm,cortex-a15"; +- reg = <0>; +- +- /* cooling options */ +- cooling-min-level = <0>; +- cooling-max-level = <2>; +- #cooling-cells = <2>; /* min followed by max */ +- }; +- }; +- + pmu { + compatible = "arm,cortex-a15-pmu"; + interrupt-parent = <&wakeupgen>; +diff --git a/arch/arm/boot/dts/dra74x.dtsi b/arch/arm/boot/dts/dra74x.dtsi +index 4220eef..0c31db3 100644 +--- a/arch/arm/boot/dts/dra74x.dtsi ++++ b/arch/arm/boot/dts/dra74x.dtsi +@@ -13,30 +13,6 @@ + compatible = "ti,dra742", "ti,dra74", "ti,dra7"; + + cpus { +- #address-cells = <1>; +- #size-cells = <0>; +- +- cpu0: cpu@0 { +- device_type = "cpu"; +- compatible = "arm,cortex-a15"; +- reg = <0>; +- +- operating-points = < +- /* kHz uV */ +- 1000000 1060000 +- 1176000 1160000 +- >; +- +- clocks = <&dpll_mpu_ck>; +- clock-names = "cpu"; +- +- clock-latency = <300000>; /* From omap-cpufreq driver */ +- +- /* cooling options */ +- cooling-min-level = <0>; +- cooling-max-level = <2>; +- #cooling-cells = <2>; /* min followed by max */ +- }; + cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; +-- +2.8.1 + diff --git a/patches/ti/ticpufreq/0010-ARM-dts-dra7-Move-to-operating-points-v2-table.patch b/patches/ti/ticpufreq/0010-ARM-dts-dra7-Move-to-operating-points-v2-table.patch new file mode 100644 index 0000000000000000000000000000000000000000..6100ef6cd74833a0cf005721eae09471a829c7e2 --- /dev/null +++ b/patches/ti/ticpufreq/0010-ARM-dts-dra7-Move-to-operating-points-v2-table.patch @@ -0,0 +1,85 @@ +From bd4416ee6a2f660ff413840025e683584f2bdc20 Mon Sep 17 00:00:00 2001 +From: Dave Gerlach <d-gerlach@ti.com> +Date: Wed, 18 May 2016 18:36:33 -0500 +Subject: [PATCH 10/10] ARM: dts: dra7: Move to operating-points-v2 table + +Add an operating-points-v2 table with all OPPs available for all silicon +revisions along with necessary data for use by ti-opp driver to selectively +enable the appropriate OPPs at runtime and handle voltage transitions + +As we now need to define voltage ranges for each OPP, we define the +minimum and maximum voltage to match the ranges possible for AVS class0 +voltage as defined by the DRA7/AM57 Data Manual, with the exception of +using a range for OPP_OD based on historical data to ensure that SoCs +from older lots still continue to boot, even though more optimal voltages +are now the standard. Once an AVS Class0 driver is in place it will be +possible for these OPP voltages to be adjusted to any voltage within the +provided range. + +Information from SPRS953, Revised December 2015. + +Signed-off-by: Dave Gerlach <d-gerlach@ti.com> +--- + arch/arm/boot/dts/dra7.dtsi | 26 +++++++++++++++++++++----- + arch/arm/boot/dts/dra74x.dtsi | 1 + + 2 files changed, 22 insertions(+), 5 deletions(-) + +diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi +index 7ff4ae4..3df9dce 100644 +--- a/arch/arm/boot/dts/dra7.dtsi ++++ b/arch/arm/boot/dts/dra7.dtsi +@@ -82,11 +82,9 @@ + compatible = "arm,cortex-a15"; + reg = <0>; + +- operating-points = < +- /* kHz uV */ +- 1000000 1060000 +- 1176000 1160000 +- >; ++ operating-points-v2 = <&cpu0_opp_table>; ++ ti,syscon-efuse = <&scm_wkup 0x20c 0xf80000 19>; ++ ti,syscon-rev = <&scm_wkup 0x204>; + + clocks = <&dpll_mpu_ck>; + clock-names = "cpu"; +@@ -100,6 +98,24 @@ + }; + }; + ++ cpu0_opp_table: opp_table0 { ++ compatible = "operating-points-v2"; ++ opp-shared; ++ ++ opp_nom@1000000000 { ++ opp-hz = /bits/ 64 <1000000000>; ++ opp-microvolt = <1060000 850000 1150000>; ++ opp-supported-hw = <0xFF 0x01>; ++ opp-suspend; ++ }; ++ ++ opp_od@1176000000 { ++ opp-hz = /bits/ 64 <1176000000>; ++ opp-microvolt = <1160000 885000 1160000>; ++ opp-supported-hw = <0xFF 0x02>; ++ }; ++ }; ++ + /* + * The soc node represents the soc top level view. It is used for IPs + * that are not memory mapped in the MPU view or for the MPU itself. +diff --git a/arch/arm/boot/dts/dra74x.dtsi b/arch/arm/boot/dts/dra74x.dtsi +index 0c31db3..0a8a5ee 100644 +--- a/arch/arm/boot/dts/dra74x.dtsi ++++ b/arch/arm/boot/dts/dra74x.dtsi +@@ -17,6 +17,7 @@ + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <1>; ++ operating-points-v2 = <&cpu0_opp_table>; + }; + }; + +-- +2.8.1 + diff --git a/version.sh b/version.sh index 932d952d4a7fd67b46e0e43e5eccc71f7361c082..1609dad8d9954d72dfb339cba74d09d9fe0e04b7 100644 --- a/version.sh +++ b/version.sh @@ -23,10 +23,10 @@ toolchain="gcc_linaro_gnueabihf_5" #toolchain="gcc_linaro_aarch64_gnu_5" #Kernel/Build -KERNEL_REL=4.6 -KERNEL_TAG=${KERNEL_REL} -BUILD=${build_prefix}3 -kernel_rt="-rc7-rt1" +KERNEL_REL=4.7 +KERNEL_TAG=${KERNEL_REL}-rc1 +BUILD=${build_prefix}0 +kernel_rt="" #v4.X-rcX + upto SHA #prev_KERNEL_SHA=""