diff --git a/config/boards/ayn-odin2.csc b/config/boards/ayn-odin2.csc index b70fc95c1b95..800d1ada9894 100644 --- a/config/boards/ayn-odin2.csc +++ b/config/boards/ayn-odin2.csc @@ -1,42 +1,66 @@ -# Ayn Odin2 Configuration +# Qualcomm SM8550 octa core 8GB/12GB/16GB RAM SoC eMMC USB-C WiFi/BT declare -g BOARD_NAME="Ayn Odin2" declare -g BOARD_VENDOR="ayntec" declare -g BOARD_MAINTAINER="FantasyGmm" declare -g BOARDFAMILY="sm8550" declare -g KERNEL_TARGET="current,edge" -declare -g KERNEL_TEST_TARGET="edge" +declare -g KERNEL_TEST_TARGET="current" declare -g EXTRAWIFI="no" declare -g BOOTCONFIG="none" -declare -g BOOTFS_TYPE="fat" -declare -g BOOTSIZE="256" -declare -g IMAGE_PARTITION_TABLE="gpt" -declare -g BOOTIMG_CMDLINE_EXTRA="clk_ignore_unused pd_ignore_unused rw quiet rootwait" # Use the full firmware, complete linux-firmware plus Armbian's declare -g BOARD_FIRMWARE_INSTALL="-full" declare -g DESKTOP_AUTOLOGIN="yes" -function ayn-odin2_is_userspace_supported() { - [[ "${RELEASE}" == "jammy" ]] && return 0 - [[ "${RELEASE}" == "trixie" ]] && return 0 - [[ "${RELEASE}" == "noble" ]] && return 0 - return 1 -} +# Check to make sure variants are supported +declare -g VALID_BOARDS=("ayn-odin2" "ayn-odin2portal" "ayn-odin2mini" "ayn-thor") + +declare -g WITH_GRUB="${WITH_GRUB:-no}" + +if [[ ! " ${VALID_BOARDS[*]} " =~ " ${BOARD} " ]]; then + exit_with_error "Error: Invalid board '$BOARD'. Valid options are: ${VALID_BOARDS[*]}" >&2 +fi + +# set grub +if [[ "${WITH_GRUB}" == "yes" ]]; then + display_alert "GRUB DETECTED" + declare -g UEFI_GRUB_TERMINAL="gfxterm" # Use graphics in grub, for the Armbian wallpaper. + declare -g GRUB_CMDLINE_LINUX_DEFAULT="clk_ignore_unused pd_ignore_unused arm64.nopauth efi=noruntime fbcon=rotate:1 console=ttyMSM0,115200n8" + declare -g BOOT_FDT_FILE="qcom/qcs8550-${BOARD}.dtb" + declare -g SERIALCON="${SERIALCON:-tty1}" + + enable_extension "grub" + enable_extension "grub-with-dtb" # important, puts the whole DTB handling in place. +else + declare -g BOOTFS_TYPE="fat" + declare -g BOOTSIZE="256" + declare -g IMAGE_PARTITION_TABLE="gpt" + declare -g BOOTIMG_CMDLINE_EXTRA="clk_ignore_unused pd_ignore_unused rw quiet rootwait" + + function pre_umount_final_image__update_ABL_settings() { + if [ -z "$BOOTFS_TYPE" ]; then + return 0 + fi + display_alert "Update ABL settings for " "${BOARD}" "info" + uuid_line=$(head -n 1 "${SDCARD}"/etc/fstab) + rootfs_image_uuid=$(echo "${uuid_line}" | awk '{print $1}' | awk -F '=' '{print $2}') + initrd_name=$(find "${SDCARD}/boot/" -type f -name "config-*" | sed 's/.*config-//') + sed -i "s/UUID_PLACEHOLDER/${rootfs_image_uuid}/g" "${MOUNT}"/boot/LinuxLoader.cfg + sed -i "s/INITRD_PLACEHOLDER/${initrd_name}/g" "${MOUNT}"/boot/LinuxLoader.cfg + } +fi function pre_customize_image__ayn-odin2_alsa_ucm_conf() { - if ! ayn-odin2_is_userspace_supported; then - return 0 - fi - display_alert "Add alsa-ucm-conf for ${BOARD}" "${RELEASE}" "warn" ( + ( cd "${SDCARD}/usr/share/alsa" || exit 6 curl -L -o temp.zip "https://github.com/AYNTechnologies/alsa-ucm-conf/archive/refs/heads/ayn/v1.2.13.zip" unzip -o temp.zip unzip_dir=$(unzip -Z1 temp.zip | head -n1 | cut -d/ -f1) cp -rf "${unzip_dir}/"* . rm -rf "$unzip_dir" temp.zip - ) + ) ) } function post_family_tweaks_bsp__ayn-odin2_firmware() { @@ -58,23 +82,11 @@ function post_family_tweaks_bsp__ayn-odin2_firmware() { } function post_family_tweaks__ayn-odin2_enable_services() { - if ! ayn-odin2_is_userspace_supported; then - if [[ "${RELEASE}" != "" ]]; then - display_alert "Missing userspace for ${BOARD}" "${RELEASE} does not have the userspace necessary to support the ${BOARD}" "warn" - fi - return 0 - fi - - if [[ "${RELEASE}" == "jammy" ]] || [[ "${RELEASE}" == "noble" ]]; then - display_alert "Adding Mesa PPA For Ubuntu ${BOARD}" "warn" - do_with_retries 3 chroot_sdcard add-apt-repository ppa:liujianfeng1994/qcom-mainline --yes --no-update - fi - # We need unudhcpd from armbian repo, so enable it mv "${SDCARD}"/etc/apt/sources.list.d/armbian.sources.disabled "${SDCARD}"/etc/apt/sources.list.d/armbian.sources do_with_retries 3 chroot_sdcard_apt_get_update - display_alert "Installing ${BOARD} tweaks" "warn" + display_alert "Installing ${BOARD} tweaks" "warn" do_with_retries 3 chroot_sdcard_apt_get_install alsa-ucm-conf qbootctl qrtr-tools unudhcpd mkbootimg # disable armbian repo back mv "${SDCARD}"/etc/apt/sources.list.d/armbian.sources "${SDCARD}"/etc/apt/sources.list.d/armbian.sources.disabled @@ -87,45 +99,35 @@ function post_family_tweaks__ayn-odin2_enable_services() { chroot_sdcard systemctl mask suspend.target chroot_sdcard systemctl enable usbgadget-rndis.service - cp $SRC/packages/bsp/ayn-odin2/LinuxLoader.cfg "${SDCARD}"/boot/ + cp "${SRC}/packages/bsp/${BOARD}/LinuxLoader.cfg" "${SDCARD}"/boot/ return 0 } + function post_family_tweaks_bsp__ayn-odin2_bsp_firmware_in_initrd() { display_alert "Adding to bsp-cli" "${BOARD}: firmware in initrd" "warn" declare file_added_to_bsp_destination # Will be filled in by add_file_from_stdin_to_bsp_destination - # Using odin2's firmware for now - add_file_from_stdin_to_bsp_destination "/etc/initramfs-tools/hooks/ayn-odin2-firmware" <<- 'FIRMWARE_HOOK' - #!/bin/bash - [[ "$1" == "prereqs" ]] && exit 0 - . /usr/share/initramfs-tools/hook-functions - for f in /lib/firmware/qcom/sm8550/ayn/odin2portal/* ; do - add_firmware "${f#/lib/firmware/}" - done - add_firmware "qcom/a740_sqe.fw" # Extra one for dpu - add_firmware "qcom/gmu_gen70200.bin" # Extra one for gpu - add_firmware "qcom/vpu/vpu30_p4.mbn" # Extra one for vpu - # Extra one for wifi - for f in /lib/firmware/ath12k/WCN7850/hw2.0/* ; do - add_firmware "${f#/lib/firmware/}" - done - # Extra one for bt - for f in /lib/firmware/qca/* ; do - add_firmware "${f#/lib/firmware/}" - done - FIRMWARE_HOOK + add_file_from_stdin_to_bsp_destination "/etc/initramfs-tools/hooks/ayn-firmware" <<- 'FIRMWARE_HOOK' +#!/bin/bash +[[ "$1" == "prereqs" ]] && exit 0 +. /usr/share/initramfs-tools/hook-functions +for f in $(find /lib/firmware/qcom/sm8550 -type f) ; do +add_firmware "${f#/lib/firmware/}" +done +add_firmware "qcom/a740_sqe.fw" # Extra one for dpu +add_firmware "qcom/gmu_gen70200.bin" # Extra one for gpu +add_firmware "qcom/vpu/vpu30_p4.mbn" # Extra one for vpu +# Extra one for wifi +for f in $(find /lib/firmware/ath12k/WCN7850/hw2.0 -type f) ; do +add_firmware "${f#/lib/firmware/}" +done +# Extra one for bt +for f in $(find /lib/firmware/qca -type f) ; do +add_firmware "${f#/lib/firmware/}" +done +FIRMWARE_HOOK run_host_command_logged chmod -v +x "${file_added_to_bsp_destination}" } -function pre_umount_final_image__update_ABL_settings() { - if [ -z "$BOOTFS_TYPE" ]; then - return 0 - fi - display_alert "Update ABL settings for " "${BOARD}" "info" - uuid_line=$(head -n 1 "${SDCARD}"/etc/fstab) - rootfs_image_uuid=$(echo "${uuid_line}" | awk '{print $1}' | awk -F '=' '{print $2}') - initrd_name=$(find "${SDCARD}/boot/" -type f -name "config-*" | sed 's/.*config-//') - sed -i "s/UUID_PLACEHOLDER/${rootfs_image_uuid}/g" "${MOUNT}"/boot/LinuxLoader.cfg - sed -i "s/INITRD_PLACEHOLDER/${initrd_name}/g" "${MOUNT}"/boot/LinuxLoader.cfg -} + diff --git a/config/boards/ayn-odin2mini.csc b/config/boards/ayn-odin2mini.csc new file mode 100644 index 000000000000..96db75d37d80 --- /dev/null +++ b/config/boards/ayn-odin2mini.csc @@ -0,0 +1,5 @@ +# Qualcomm SM8550 octa core 8GB/12GB/16GB RAM SoC eMMC USB-C WiFi/BT +source "${SRC}/config/boards/ayn-odin2.csc" +declare -g BOARD_NAME="Ayn Odin2 Mini" +declare -g BOARD_VENDOR="ayntec" +declare -g BOARD_MAINTAINER="Squishy123" diff --git a/config/boards/ayn-odin2portal.csc b/config/boards/ayn-odin2portal.csc new file mode 100644 index 000000000000..00374226ce64 --- /dev/null +++ b/config/boards/ayn-odin2portal.csc @@ -0,0 +1,5 @@ +# Qualcomm SM8550 octa core 8GB/12GB/16GB RAM SoC eMMC USB-C WiFi/BT +source "${SRC}/config/boards/ayn-odin2.csc" +declare -g BOARD_NAME="Ayn Odin2 Portal" +declare -g BOARD_VENDOR="ayntec" +declare -g BOARD_MAINTAINER="Squishy123" diff --git a/config/boards/ayn-thor.csc b/config/boards/ayn-thor.csc new file mode 100644 index 000000000000..ef0e579e6dd1 --- /dev/null +++ b/config/boards/ayn-thor.csc @@ -0,0 +1,5 @@ +# Qualcomm SM8550 octa core 8GB/12GB/16GB RAM SoC eMMC USB-C WiFi/BT +source "${SRC}/config/boards/ayn-odin2.csc" +declare -g BOARD_NAME="Ayn Thor" +declare -g BOARD_VENDOR="ayntec" +declare -g BOARD_MAINTAINER="Squishy123" diff --git a/config/kernel/linux-sm8550-current.config b/config/kernel/linux-sm8550-current.config index cb7a8658ce95..6c3c36d5b937 100644 --- a/config/kernel/linux-sm8550-current.config +++ b/config/kernel/linux-sm8550-current.config @@ -1,4 +1,4 @@ -# Armbian defconfig generated with 6.12 +# Armbian defconfig generated with 6.18 # CONFIG_LOCALVERSION_AUTO is not set CONFIG_DEFAULT_HOSTNAME="@DEVICENAME@" CONFIG_SYSVIPC=y @@ -16,6 +16,7 @@ CONFIG_BSD_PROCESS_ACCT_V3=y CONFIG_TASKSTATS=y CONFIG_TASK_XACCT=y CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_PSI=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_NUMA_BALANCING=y @@ -37,6 +38,13 @@ CONFIG_NAMESPACES=y CONFIG_USER_NS=y CONFIG_SCHED_AUTOGROUP=y CONFIG_BLK_DEV_INITRD=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_RD_XZ is not set +# CONFIG_RD_LZO is not set +# CONFIG_RD_LZ4 is not set +# CONFIG_RD_ZSTD is not set +CONFIG_SYSFS_SYSCALL=y CONFIG_EXPERT=y CONFIG_KALLSYMS_ALL=y CONFIG_PROFILING=y @@ -45,9 +53,6 @@ CONFIG_KEXEC_FILE=y CONFIG_ARCH_QCOM=y # CONFIG_NVIDIA_CARMEL_CNP_ERRATUM is not set # CONFIG_ROCKCHIP_ERRATUM_3588001 is not set -CONFIG_ARM64_VA_BITS_48=y -CONFIG_SCHED_MC=y -CONFIG_SCHED_SMT=y CONFIG_NUMA=y CONFIG_PARAVIRT=y CONFIG_COMPAT=y @@ -69,6 +74,7 @@ CONFIG_ARM_QCOM_CPUFREQ_HW=y CONFIG_ARM_SCMI_CPUFREQ=y CONFIG_ACPI_CPPC_CPUFREQ=m CONFIG_ACPI=y +# CONFIG_ACPI_DEBUG is not set CONFIG_ACPI_HOTPLUG_MEMORY=y CONFIG_ACPI_HMAT=y CONFIG_ACPI_APEI=y @@ -78,7 +84,7 @@ CONFIG_ACPI_APEI_MEMORY_FAILURE=y CONFIG_ACPI_APEI_EINJ=y CONFIG_VIRTUALIZATION=y CONFIG_KVM=y -CONFIG_JUMP_LABEL=y +# CONFIG_SCHED_SMT is not set CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_BLK_DEV_INTEGRITY=y @@ -88,7 +94,6 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_BINFMT_MISC=y CONFIG_ZSWAP=y -CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y # CONFIG_COMPAT_BRK is not set CONFIG_MEMORY_HOTPLUG=y CONFIG_MEMORY_HOTREMOVE=y @@ -102,11 +107,24 @@ CONFIG_UNIX=y CONFIG_XFRM_USER=m CONFIG_INET=y CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_MULTIPLE_TABLES=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_MROUTE=y CONFIG_INET_ESP=m +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BBR=y +CONFIG_DEFAULT_BBR=y +CONFIG_IPV6_ROUTER_PREF=y +CONFIG_IPV6_ROUTE_INFO=y +CONFIG_IPV6_OPTIMISTIC_DAD=y CONFIG_IPV6_SIT=m +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_SUBTREES=y +CONFIG_IPV6_MROUTE=y +CONFIG_IPV6_PIMSM_V2=y CONFIG_NETFILTER=y CONFIG_BRIDGE_NETFILTER=m CONFIG_NETFILTER_NETLINK_HOOK=m @@ -150,18 +168,22 @@ CONFIG_NETFILTER_XT_TARGET_AUDIT=m CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_CT=m CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_HL=m CONFIG_NETFILTER_XT_TARGET_HMARK=m CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m CONFIG_NETFILTER_XT_TARGET_LED=m CONFIG_NETFILTER_XT_TARGET_LOG=m CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_NAT=m +CONFIG_NETFILTER_XT_TARGET_NETMAP=m CONFIG_NETFILTER_XT_TARGET_NFLOG=m CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m -CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_REDIRECT=m +CONFIG_NETFILTER_XT_TARGET_MASQUERADE=m CONFIG_NETFILTER_XT_TARGET_TEE=m CONFIG_NETFILTER_XT_TARGET_TPROXY=m -CONFIG_NETFILTER_XT_TARGET_TRACE=m CONFIG_NETFILTER_XT_TARGET_TCPMSS=m CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m @@ -226,15 +248,6 @@ CONFIG_NFT_DUP_IPV4=m CONFIG_NFT_FIB_IPV4=m CONFIG_NF_TABLES_ARP=y CONFIG_IP_NF_IPTABLES=m -CONFIG_IP_NF_FILTER=m -CONFIG_IP_NF_TARGET_REJECT=m -CONFIG_IP_NF_NAT=m -CONFIG_IP_NF_TARGET_MASQUERADE=m -CONFIG_IP_NF_TARGET_NETMAP=m -CONFIG_IP_NF_TARGET_REDIRECT=m -CONFIG_IP_NF_MANGLE=m -CONFIG_IP_NF_RAW=m -CONFIG_IP_NF_SECURITY=m CONFIG_NFT_DUP_IPV6=m CONFIG_NFT_FIB_IPV6=m CONFIG_IP6_NF_IPTABLES=m @@ -248,15 +261,8 @@ CONFIG_IP6_NF_MATCH_MH=m CONFIG_IP6_NF_MATCH_RPFILTER=m CONFIG_IP6_NF_MATCH_RT=m CONFIG_IP6_NF_MATCH_SRH=m -CONFIG_IP6_NF_TARGET_HL=m -CONFIG_IP6_NF_FILTER=m CONFIG_IP6_NF_TARGET_REJECT=m CONFIG_IP6_NF_TARGET_SYNPROXY=m -CONFIG_IP6_NF_MANGLE=m -CONFIG_IP6_NF_RAW=m -CONFIG_IP6_NF_SECURITY=m -CONFIG_IP6_NF_NAT=m -CONFIG_IP6_NF_TARGET_MASQUERADE=m CONFIG_IP6_NF_TARGET_NPT=m CONFIG_NF_TABLES_BRIDGE=m CONFIG_NFT_BRIDGE_META=m @@ -269,7 +275,10 @@ CONFIG_NET_SCH_CBS=m CONFIG_NET_SCH_ETF=m CONFIG_NET_SCH_TAPRIO=m CONFIG_NET_SCH_MQPRIO=m +CONFIG_NET_SCH_FQ_CODEL=y CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_SCH_DEFAULT=y +CONFIG_DEFAULT_FQ_CODEL=y CONFIG_NET_CLS_BASIC=m CONFIG_NET_CLS_CGROUP=m CONFIG_NET_CLS_FLOWER=m @@ -288,16 +297,17 @@ CONFIG_CGROUP_NET_PRIO=y CONFIG_BPF_STREAM_PARSER=y CONFIG_BT=m CONFIG_BT_HIDP=m -# CONFIG_BT_LE is not set CONFIG_BT_LEDS=y # CONFIG_BT_DEBUGFS is not set CONFIG_BT_HCIUART=m CONFIG_BT_HCIUART_LL=y CONFIG_BT_HCIUART_QCA=y CONFIG_CFG80211=m +CONFIG_CFG80211_WEXT=y CONFIG_MAC80211=m +CONFIG_MAC80211_MESH=y CONFIG_MAC80211_LEDS=y -CONFIG_RFKILL=m +CONFIG_RFKILL=y CONFIG_RFKILL_INPUT=y CONFIG_PAGE_POOL_STATS=y CONFIG_PCI=y @@ -327,6 +337,8 @@ CONFIG_MHI_BUS=y CONFIG_MHI_BUS_PCI_GENERIC=m CONFIG_ARM_SCMI_PROTOCOL=y CONFIG_ARM_SCPI_PROTOCOL=y +CONFIG_EFI_ZBOOT=y +CONFIG_EFI_CAPSULE_LOADER=m CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE=y CONFIG_QCOM_QSEECOM=y CONFIG_QCOM_QSEECOM_UEFISECAPP=y @@ -362,22 +374,20 @@ CONFIG_ZRAM_BACKEND_842=y CONFIG_ZRAM_BACKEND_LZO=y CONFIG_ZRAM_WRITEBACK=y CONFIG_ZRAM_MEMORY_TRACKING=y -CONFIG_ZRAM_MULTI_COMP=y CONFIG_BLK_DEV_LOOP=y CONFIG_VIRTIO_BLK=y CONFIG_QCOM_COINCELL=m CONFIG_QCOM_FASTRPC=y CONFIG_SRAM=y CONFIG_PCI_ENDPOINT_TEST=m +CONFIG_NTSYNC=m CONFIG_EEPROM_AT24=m CONFIG_EEPROM_AT25=m -CONFIG_EEPROM_93CX6=y CONFIG_UACCE=m CONFIG_SCSI=y # CONFIG_SCSI_PROC_FS is not set CONFIG_BLK_DEV_SD=y CONFIG_MD=y -# CONFIG_MD_BITMAP_FILE is not set CONFIG_NETDEVICES=y CONFIG_DUMMY=m CONFIG_WIREGUARD=m @@ -460,6 +470,7 @@ CONFIG_MHI_NET=m # CONFIG_NET_VENDOR_WIZNET is not set # CONFIG_NET_VENDOR_XILINX is not set CONFIG_REALTEK_PHY=m +CONFIG_REALTEK_PHY_HWMON=y CONFIG_USB_RTL8150=m CONFIG_USB_RTL8152=m CONFIG_USB_USBNET=m @@ -499,6 +510,9 @@ CONFIG_JOYSTICK_XPAD_FF=y CONFIG_JOYSTICK_XPAD_LEDS=y CONFIG_JOYSTICK_RSINPUT=y CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_GOODIX=y +CONFIG_TOUCHSCREEN_HYNITRON_CSTXXX=y +CONFIG_TOUCHSCREEN_HYNITRON_ALL=y CONFIG_TOUCHSCREEN_EDT_FT5X06=y CONFIG_INPUT_MISC=y CONFIG_INPUT_PM8941_PWRKEY=y @@ -564,6 +578,7 @@ CONFIG_PINCTRL_QCOM_SPMI_PMIC=y CONFIG_PINCTRL_LPASS_LPI=m CONFIG_PINCTRL_SM8550_LPASS_LPI=m CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_PCA953X=y CONFIG_GPIO_AGGREGATOR=m CONFIG_POWER_RESET_MSM=y CONFIG_POWER_RESET_QCOM_PON=y @@ -600,6 +615,7 @@ CONFIG_REGULATOR_QCOM_RPMH=y CONFIG_REGULATOR_QCOM_SMD_RPM=y CONFIG_REGULATOR_QCOM_SPMI=y CONFIG_REGULATOR_QCOM_USB_VBUS=y +CONFIG_REGULATOR_SGM3804=y CONFIG_REGULATOR_VCTRL=m CONFIG_MEDIA_SUPPORT=y CONFIG_MEDIA_SUPPORT_FILTER=y @@ -613,23 +629,31 @@ CONFIG_VIDEO_QCOM_VENUS=m CONFIG_DRM=y CONFIG_DRM_LOAD_EDID_FIRMWARE=y CONFIG_DRM_DISPLAY_DP_AUX_CHARDEV=y -CONFIG_DRM_I2C_CH7006=m -CONFIG_DRM_I2C_SIL164=m -CONFIG_DRM_I2C_NXP_TDA998X=m +CONFIG_DRM_SIMPLEDRM=y CONFIG_DRM_MSM=y -CONFIG_DRM_PANEL_CHIPONE_ICNA3512=y +CONFIG_DRM_PANEL_AR06_4INCH=y +CONFIG_DRM_PANEL_AR02_3INCH=y +CONFIG_DRM_PANEL_AR11_5INCH=y +CONFIG_DRM_PANEL_BOE_XM91080G=y +CONFIG_DRM_PANEL_CHIPONE_ICNA35XX=y +CONFIG_DRM_PANEL_DDIC_CH13726A=y CONFIG_DRM_PANEL_LVDS=m +CONFIG_DRM_PANEL_RETROID_POCKET_6=y CONFIG_DRM_PANEL_EDP=y CONFIG_DRM_PANEL_SIMPLE=m CONFIG_DRM_PANEL_SYNAPTICS_TD4328=y CONFIG_DRM_DISPLAY_CONNECTOR=y +CONFIG_DRM_I2C_NXP_TDA998X=m +CONFIG_DRM_LONTIUM_LT8912B=y CONFIG_DRM_SIMPLE_BRIDGE=m -CONFIG_DRM_SIMPLEDRM=y CONFIG_FB=y +CONFIG_FB_EFI=y CONFIG_FB_MODE_HELPERS=y CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_ODIN2MINI=y CONFIG_BACKLIGHT_PWM=y CONFIG_BACKLIGHT_QCOM_WLED=y +CONFIG_BACKLIGHT_SY7758=y CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set @@ -662,6 +686,7 @@ CONFIG_SND_SOC_SIMPLE_AMPLIFIER=m CONFIG_SND_SOC_SIMPLE_MUX=m CONFIG_SND_SOC_SPDIF=m CONFIG_SND_SOC_WCD938X_SDW=m +CONFIG_SND_SOC_WSA884X=m CONFIG_SND_SOC_LPASS_WSA_MACRO=m CONFIG_SND_SOC_LPASS_VA_MACRO=m CONFIG_SND_SOC_LPASS_RX_MACRO=m @@ -669,7 +694,9 @@ CONFIG_SND_SOC_LPASS_TX_MACRO=m CONFIG_SND_SIMPLE_CARD=m CONFIG_SND_AUDIO_GRAPH_CARD=m CONFIG_SND_AUDIO_GRAPH_CARD2=m +CONFIG_HID_BATTERY_STRENGTH=y CONFIG_HIDRAW=y +CONFIG_UHID=y CONFIG_HID_A4TECH=y CONFIG_HID_BELKIN=y CONFIG_HID_CHERRY=y @@ -685,14 +712,15 @@ CONFIG_HID_PLAYSTATION=y CONFIG_PLAYSTATION_FF=y CONFIG_HID_SONY=y CONFIG_SONY_FF=y -CONFIG_USB_HIDDEV=y CONFIG_I2C_HID_ACPI=m CONFIG_I2C_HID_OF=m CONFIG_I2C_HID_OF_ELAN=m +CONFIG_USB_HIDDEV=y CONFIG_USB_ULPI_BUS=y CONFIG_USB_CONN_GPIO=y CONFIG_USB_OTG=y CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_PCI_RENESAS=m CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_ROOT_HUB_TT=y CONFIG_USB_EHCI_HCD_PLATFORM=y @@ -728,7 +756,7 @@ CONFIG_TYPEC_TPS6598X=m CONFIG_TYPEC_HD3SS3220=m CONFIG_TYPEC_MUX_FSA4480=y CONFIG_TYPEC_MUX_GPIO_SBU=y -CONFIG_TYPEC_MUX_NB7VPQ904M=m +CONFIG_TYPEC_MUX_NB7VPQ904M=y CONFIG_TYPEC_DP_ALTMODE=y CONFIG_MMC=y CONFIG_MMC_BLOCK_MINORS=32 @@ -738,7 +766,6 @@ CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_ACPI=y CONFIG_MMC_SDHCI_PLTFM=y CONFIG_MMC_SDHCI_MSM=y -CONFIG_MMC_SDHCI_MSM_DOWNSTREAM=y CONFIG_MMC_SPI=y CONFIG_MMC_DW=y CONFIG_MMC_HSQ=y @@ -752,6 +779,7 @@ CONFIG_LEDS_CLASS_MULTICOLOR=y CONFIG_LEDS_HTR3212=y CONFIG_LEDS_GPIO=y CONFIG_LEDS_PWM=y +CONFIG_LEDS_GROUP_MULTICOLOR=y CONFIG_LEDS_PWM_MULTICOLOR=y CONFIG_LEDS_QCOM_LPG=y CONFIG_LEDS_TRIGGER_TIMER=y @@ -762,6 +790,7 @@ CONFIG_LEDS_TRIGGER_PANIC=y CONFIG_EDAC=y CONFIG_EDAC_GHES=y CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_EFI=y CONFIG_RTC_DRV_PM8XXX=y CONFIG_DMADEVICES=y CONFIG_QCOM_BAM_DMA=y @@ -792,6 +821,7 @@ CONFIG_SM_TCSRCC_8550=y CONFIG_SM_VIDEOCC_8550=y CONFIG_SPMI_PMIC_CLKDIV=y CONFIG_QCOM_HFPLL=y +CONFIG_CLK_GFM_LPASS_SM8250=m CONFIG_HWSPINLOCK=y CONFIG_HWSPINLOCK_QCOM=y # CONFIG_FSL_ERRATUM_A008585 is not set @@ -860,6 +890,7 @@ CONFIG_QCOM_MPM=y CONFIG_RESET_GPIO=m CONFIG_RESET_QCOM_AOSS=y CONFIG_RESET_QCOM_PDC=y +CONFIG_PHY_SNPS_EUSB2=y CONFIG_PHY_CAN_TRANSCEIVER=m CONFIG_PHY_CADENCE_TORRENT=m CONFIG_PHY_CADENCE_DPHY_RX=m @@ -870,7 +901,6 @@ CONFIG_PHY_QCOM_PCIE2=m CONFIG_PHY_QCOM_QMP=y CONFIG_PHY_QCOM_QMP_PCIE_8996=m CONFIG_PHY_QCOM_QUSB2=m -CONFIG_PHY_QCOM_SNPS_EUSB2=y CONFIG_PHY_QCOM_EUSB2_REPEATER=y CONFIG_PHY_QCOM_M31_USB=m CONFIG_PHY_QCOM_USB_HS=m @@ -890,6 +920,9 @@ CONFIG_ARM_DMC620_PMU=m CONFIG_HISI_PMU=y CONFIG_ARM_CORESIGHT_PMU_ARCH_SYSTEM_PMU=m CONFIG_NVIDIA_CORESIGHT_PMU_ARCH_SYSTEM_PMU=m +CONFIG_ANDROID_BINDER_IPC=y +CONFIG_ANDROID_BINDERFS=y +CONFIG_ANDROID_BINDER_DEVICES="binder,hwbinder,vndbinder,anbox-binder,anbox-hwbinder,anbox-vndbinder" CONFIG_NVMEM_LAYOUT_SL28_VPD=m CONFIG_NVMEM_QCOM_QFPROM=y CONFIG_NVMEM_QCOM_SEC_QFPROM=y @@ -900,7 +933,6 @@ CONFIG_TEE=y CONFIG_OPTEE=y CONFIG_MUX_GPIO=m CONFIG_MUX_MMIO=m -CONFIG_SLIM_QCOM_CTRL=m CONFIG_SLIM_QCOM_NGD_CTRL=m CONFIG_INTERCONNECT_QCOM=y CONFIG_INTERCONNECT_QCOM_OSM_L3=y @@ -943,36 +975,44 @@ CONFIG_PSTORE_RAM=m CONFIG_EROFS_FS=m CONFIG_NFS_FS=y CONFIG_NFSD=y -CONFIG_NLS_DEFAULT="utf-8" +CONFIG_NLS_DEFAULT="utf8" CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ASCII=y CONFIG_NLS_ISO8859_1=y +CONFIG_NLS_UTF8=y CONFIG_PERSISTENT_KEYRINGS=y CONFIG_ENCRYPTED_KEYS=y CONFIG_KEY_DH_OPERATIONS=y CONFIG_SECURITY=y CONFIG_SECURITY_APPARMOR=y -CONFIG_LSM="landlock,lockdown,yama,loadpin,safesetid,bpf" +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_LSM="landlock,lockdown,yama,loadpin,safesetid,apparmor,bpf" CONFIG_CRYPTO_USER=y -CONFIG_CRYPTO_TEST=m +CONFIG_CRYPTO_NULL=y CONFIG_CRYPTO_ECDH=y -CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_DES=y CONFIG_CRYPTO_ARC4=m CONFIG_CRYPTO_CCM=y CONFIG_CRYPTO_ECHAINIV=y +CONFIG_CRYPTO_BLAKE2B=y CONFIG_CRYPTO_CMAC=y +CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_XXHASH=y +CONFIG_CRYPTO_CRC32C=y +CONFIG_CRYPTO_CRC32=y CONFIG_CRYPTO_ANSI_CPRNG=y -CONFIG_CRYPTO_USER_API_RNG=m +CONFIG_CRYPTO_USER_API_HASH=y +CONFIG_CRYPTO_USER_API_SKCIPHER=y +CONFIG_CRYPTO_USER_API_RNG=y +CONFIG_CRYPTO_USER_API_AEAD=m CONFIG_CRYPTO_GHASH_ARM64_CE=y -CONFIG_CRYPTO_SHA1_ARM64_CE=y -CONFIG_CRYPTO_SHA2_ARM64_CE=y -CONFIG_CRYPTO_SHA512_ARM64_CE=m CONFIG_CRYPTO_SHA3_ARM64=m CONFIG_CRYPTO_SM3_ARM64_CE=m -CONFIG_CRYPTO_AES_ARM64_BS=m +CONFIG_CRYPTO_AES_ARM64=y +CONFIG_CRYPTO_AES_ARM64_BS=y CONFIG_CRYPTO_AES_ARM64_CE_CCM=y -CONFIG_CRYPTO_CRCT10DIF_ARM64_CE=y CONFIG_CRYPTO_DEV_QCE=y CONFIG_CRYPTO_DEV_QCOM_RNG=y CONFIG_CRYPTO_DEV_CCREE=m @@ -983,7 +1023,6 @@ CONFIG_CRYPTO_DEV_HISI_TRNG=m CONFIG_CRYPTO_DEV_AMLOGIC_GXL=m CONFIG_PACKING=y CONFIG_INDIRECT_PIO=y -CONFIG_CRC_CCITT=m CONFIG_DMA_RESTRICTED_POOL=y CONFIG_DMA_CMA=y CONFIG_CMA_SIZE_MBYTES=32 @@ -998,7 +1037,6 @@ CONFIG_DEBUG_INFO_REDUCED=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_FS=y CONFIG_DEBUG_MEMORY_INIT=y -# CONFIG_SCHED_DEBUG is not set CONFIG_FUNCTION_TRACER=y CONFIG_FTRACE_SYSCALLS=y CONFIG_MEMTEST=y diff --git a/config/kernel/linux-sm8550-edge.config b/config/kernel/linux-sm8550-edge.config index e80a2e941e6e..6c3c36d5b937 100644 --- a/config/kernel/linux-sm8550-edge.config +++ b/config/kernel/linux-sm8550-edge.config @@ -7,6 +7,8 @@ CONFIG_NO_HZ_IDLE=y CONFIG_HIGH_RES_TIMERS=y CONFIG_BPF_SYSCALL=y CONFIG_BPF_JIT=y +CONFIG_BPF_JIT_ALWAYS_ON=y +CONFIG_BPF_LSM=y CONFIG_PREEMPT=y CONFIG_IRQ_TIME_ACCOUNTING=y CONFIG_BSD_PROCESS_ACCT=y @@ -14,9 +16,11 @@ CONFIG_BSD_PROCESS_ACCT_V3=y CONFIG_TASKSTATS=y CONFIG_TASK_XACCT=y CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_PSI=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_NUMA_BALANCING=y +CONFIG_CGROUP_FAVOR_DYNMODS=y CONFIG_MEMCG=y CONFIG_BLK_CGROUP=y CONFIG_CFS_BANDWIDTH=y @@ -29,10 +33,18 @@ CONFIG_CGROUP_DEVICE=y CONFIG_CGROUP_CPUACCT=y CONFIG_CGROUP_PERF=y CONFIG_CGROUP_BPF=y +CONFIG_CGROUP_MISC=y CONFIG_NAMESPACES=y CONFIG_USER_NS=y CONFIG_SCHED_AUTOGROUP=y CONFIG_BLK_DEV_INITRD=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_RD_XZ is not set +# CONFIG_RD_LZO is not set +# CONFIG_RD_LZ4 is not set +# CONFIG_RD_ZSTD is not set +CONFIG_SYSFS_SYSCALL=y CONFIG_EXPERT=y CONFIG_KALLSYMS_ALL=y CONFIG_PROFILING=y @@ -41,7 +53,6 @@ CONFIG_KEXEC_FILE=y CONFIG_ARCH_QCOM=y # CONFIG_NVIDIA_CARMEL_CNP_ERRATUM is not set # CONFIG_ROCKCHIP_ERRATUM_3588001 is not set -CONFIG_ARM64_VA_BITS_48=y CONFIG_NUMA=y CONFIG_PARAVIRT=y CONFIG_COMPAT=y @@ -63,6 +74,7 @@ CONFIG_ARM_QCOM_CPUFREQ_HW=y CONFIG_ARM_SCMI_CPUFREQ=y CONFIG_ACPI_CPPC_CPUFREQ=m CONFIG_ACPI=y +# CONFIG_ACPI_DEBUG is not set CONFIG_ACPI_HOTPLUG_MEMORY=y CONFIG_ACPI_HMAT=y CONFIG_ACPI_APEI=y @@ -72,10 +84,12 @@ CONFIG_ACPI_APEI_MEMORY_FAILURE=y CONFIG_ACPI_APEI_EINJ=y CONFIG_VIRTUALIZATION=y CONFIG_KVM=y +# CONFIG_SCHED_SMT is not set CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_BLK_DEV_INTEGRITY=y CONFIG_BLK_DEV_THROTTLING=y +CONFIG_BLK_CGROUP_IOCOST=y CONFIG_PARTITION_ADVANCED=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_BINFMT_MISC=y @@ -93,11 +107,24 @@ CONFIG_UNIX=y CONFIG_XFRM_USER=m CONFIG_INET=y CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_MULTIPLE_TABLES=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_MROUTE=y CONFIG_INET_ESP=m +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BBR=y +CONFIG_DEFAULT_BBR=y +CONFIG_IPV6_ROUTER_PREF=y +CONFIG_IPV6_ROUTE_INFO=y +CONFIG_IPV6_OPTIMISTIC_DAD=y CONFIG_IPV6_SIT=m +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_SUBTREES=y +CONFIG_IPV6_MROUTE=y +CONFIG_IPV6_PIMSM_V2=y CONFIG_NETFILTER=y CONFIG_BRIDGE_NETFILTER=m CONFIG_NETFILTER_NETLINK_HOOK=m @@ -221,7 +248,6 @@ CONFIG_NFT_DUP_IPV4=m CONFIG_NFT_FIB_IPV4=m CONFIG_NF_TABLES_ARP=y CONFIG_IP_NF_IPTABLES=m -CONFIG_IP_NF_TARGET_REJECT=m CONFIG_NFT_DUP_IPV6=m CONFIG_NFT_FIB_IPV6=m CONFIG_IP6_NF_IPTABLES=m @@ -249,7 +275,10 @@ CONFIG_NET_SCH_CBS=m CONFIG_NET_SCH_ETF=m CONFIG_NET_SCH_TAPRIO=m CONFIG_NET_SCH_MQPRIO=m +CONFIG_NET_SCH_FQ_CODEL=y CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_SCH_DEFAULT=y +CONFIG_DEFAULT_FQ_CODEL=y CONFIG_NET_CLS_BASIC=m CONFIG_NET_CLS_CGROUP=m CONFIG_NET_CLS_FLOWER=m @@ -265,9 +294,9 @@ CONFIG_QRTR_TUN=y CONFIG_QRTR_MHI=y CONFIG_NET_NCSI=y CONFIG_CGROUP_NET_PRIO=y +CONFIG_BPF_STREAM_PARSER=y CONFIG_BT=m CONFIG_BT_HIDP=m -# CONFIG_BT_LE is not set CONFIG_BT_LEDS=y # CONFIG_BT_DEBUGFS is not set CONFIG_BT_HCIUART=m @@ -278,7 +307,7 @@ CONFIG_CFG80211_WEXT=y CONFIG_MAC80211=m CONFIG_MAC80211_MESH=y CONFIG_MAC80211_LEDS=y -CONFIG_RFKILL=m +CONFIG_RFKILL=y CONFIG_RFKILL_INPUT=y CONFIG_PAGE_POOL_STATS=y CONFIG_PCI=y @@ -308,6 +337,7 @@ CONFIG_MHI_BUS=y CONFIG_MHI_BUS_PCI_GENERIC=m CONFIG_ARM_SCMI_PROTOCOL=y CONFIG_ARM_SCPI_PROTOCOL=y +CONFIG_EFI_ZBOOT=y CONFIG_EFI_CAPSULE_LOADER=m CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE=y CONFIG_QCOM_QSEECOM=y @@ -344,7 +374,6 @@ CONFIG_ZRAM_BACKEND_842=y CONFIG_ZRAM_BACKEND_LZO=y CONFIG_ZRAM_WRITEBACK=y CONFIG_ZRAM_MEMORY_TRACKING=y -CONFIG_ZRAM_MULTI_COMP=y CONFIG_BLK_DEV_LOOP=y CONFIG_VIRTIO_BLK=y CONFIG_QCOM_COINCELL=m @@ -441,6 +470,7 @@ CONFIG_MHI_NET=m # CONFIG_NET_VENDOR_WIZNET is not set # CONFIG_NET_VENDOR_XILINX is not set CONFIG_REALTEK_PHY=m +CONFIG_REALTEK_PHY_HWMON=y CONFIG_USB_RTL8150=m CONFIG_USB_RTL8152=m CONFIG_USB_USBNET=m @@ -480,6 +510,9 @@ CONFIG_JOYSTICK_XPAD_FF=y CONFIG_JOYSTICK_XPAD_LEDS=y CONFIG_JOYSTICK_RSINPUT=y CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_GOODIX=y +CONFIG_TOUCHSCREEN_HYNITRON_CSTXXX=y +CONFIG_TOUCHSCREEN_HYNITRON_ALL=y CONFIG_TOUCHSCREEN_EDT_FT5X06=y CONFIG_INPUT_MISC=y CONFIG_INPUT_PM8941_PWRKEY=y @@ -545,6 +578,7 @@ CONFIG_PINCTRL_QCOM_SPMI_PMIC=y CONFIG_PINCTRL_LPASS_LPI=m CONFIG_PINCTRL_SM8550_LPASS_LPI=m CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_PCA953X=y CONFIG_GPIO_AGGREGATOR=m CONFIG_POWER_RESET_MSM=y CONFIG_POWER_RESET_QCOM_PON=y @@ -581,6 +615,7 @@ CONFIG_REGULATOR_QCOM_RPMH=y CONFIG_REGULATOR_QCOM_SMD_RPM=y CONFIG_REGULATOR_QCOM_SPMI=y CONFIG_REGULATOR_QCOM_USB_VBUS=y +CONFIG_REGULATOR_SGM3804=y CONFIG_REGULATOR_VCTRL=m CONFIG_MEDIA_SUPPORT=y CONFIG_MEDIA_SUPPORT_FILTER=y @@ -596,20 +631,29 @@ CONFIG_DRM_LOAD_EDID_FIRMWARE=y CONFIG_DRM_DISPLAY_DP_AUX_CHARDEV=y CONFIG_DRM_SIMPLEDRM=y CONFIG_DRM_MSM=y -CONFIG_DRM_PANEL_CHIPONE_ICNA3512=y +CONFIG_DRM_PANEL_AR06_4INCH=y +CONFIG_DRM_PANEL_AR02_3INCH=y +CONFIG_DRM_PANEL_AR11_5INCH=y +CONFIG_DRM_PANEL_BOE_XM91080G=y +CONFIG_DRM_PANEL_CHIPONE_ICNA35XX=y +CONFIG_DRM_PANEL_DDIC_CH13726A=y CONFIG_DRM_PANEL_LVDS=m +CONFIG_DRM_PANEL_RETROID_POCKET_6=y CONFIG_DRM_PANEL_EDP=y CONFIG_DRM_PANEL_SIMPLE=m CONFIG_DRM_PANEL_SYNAPTICS_TD4328=y CONFIG_DRM_DISPLAY_CONNECTOR=y CONFIG_DRM_I2C_NXP_TDA998X=m +CONFIG_DRM_LONTIUM_LT8912B=y CONFIG_DRM_SIMPLE_BRIDGE=m CONFIG_FB=y CONFIG_FB_EFI=y CONFIG_FB_MODE_HELPERS=y CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_ODIN2MINI=y CONFIG_BACKLIGHT_PWM=y CONFIG_BACKLIGHT_QCOM_WLED=y +CONFIG_BACKLIGHT_SY7758=y CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set @@ -642,6 +686,7 @@ CONFIG_SND_SOC_SIMPLE_AMPLIFIER=m CONFIG_SND_SOC_SIMPLE_MUX=m CONFIG_SND_SOC_SPDIF=m CONFIG_SND_SOC_WCD938X_SDW=m +CONFIG_SND_SOC_WSA884X=m CONFIG_SND_SOC_LPASS_WSA_MACRO=m CONFIG_SND_SOC_LPASS_VA_MACRO=m CONFIG_SND_SOC_LPASS_RX_MACRO=m @@ -649,7 +694,9 @@ CONFIG_SND_SOC_LPASS_TX_MACRO=m CONFIG_SND_SIMPLE_CARD=m CONFIG_SND_AUDIO_GRAPH_CARD=m CONFIG_SND_AUDIO_GRAPH_CARD2=m +CONFIG_HID_BATTERY_STRENGTH=y CONFIG_HIDRAW=y +CONFIG_UHID=y CONFIG_HID_A4TECH=y CONFIG_HID_BELKIN=y CONFIG_HID_CHERRY=y @@ -673,6 +720,7 @@ CONFIG_USB_ULPI_BUS=y CONFIG_USB_CONN_GPIO=y CONFIG_USB_OTG=y CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_PCI_RENESAS=m CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_ROOT_HUB_TT=y CONFIG_USB_EHCI_HCD_PLATFORM=y @@ -708,7 +756,7 @@ CONFIG_TYPEC_TPS6598X=m CONFIG_TYPEC_HD3SS3220=m CONFIG_TYPEC_MUX_FSA4480=y CONFIG_TYPEC_MUX_GPIO_SBU=y -CONFIG_TYPEC_MUX_NB7VPQ904M=m +CONFIG_TYPEC_MUX_NB7VPQ904M=y CONFIG_TYPEC_DP_ALTMODE=y CONFIG_MMC=y CONFIG_MMC_BLOCK_MINORS=32 @@ -718,7 +766,6 @@ CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_ACPI=y CONFIG_MMC_SDHCI_PLTFM=y CONFIG_MMC_SDHCI_MSM=y -CONFIG_MMC_SDHCI_MSM_DOWNSTREAM=y CONFIG_MMC_SPI=y CONFIG_MMC_DW=y CONFIG_MMC_HSQ=y @@ -732,6 +779,7 @@ CONFIG_LEDS_CLASS_MULTICOLOR=y CONFIG_LEDS_HTR3212=y CONFIG_LEDS_GPIO=y CONFIG_LEDS_PWM=y +CONFIG_LEDS_GROUP_MULTICOLOR=y CONFIG_LEDS_PWM_MULTICOLOR=y CONFIG_LEDS_QCOM_LPG=y CONFIG_LEDS_TRIGGER_TIMER=y @@ -836,7 +884,7 @@ CONFIG_IIO_TRIGGERED_BUFFER=m CONFIG_QCOM_SPMI_VADC=y CONFIG_QCOM_SPMI_ADC5=y CONFIG_PWM=y -CONFIG_PWM_SN3112=m +CONFIG_PWM_SN3112=y CONFIG_QCOM_PDC=y CONFIG_QCOM_MPM=y CONFIG_RESET_GPIO=m @@ -872,6 +920,9 @@ CONFIG_ARM_DMC620_PMU=m CONFIG_HISI_PMU=y CONFIG_ARM_CORESIGHT_PMU_ARCH_SYSTEM_PMU=m CONFIG_NVIDIA_CORESIGHT_PMU_ARCH_SYSTEM_PMU=m +CONFIG_ANDROID_BINDER_IPC=y +CONFIG_ANDROID_BINDERFS=y +CONFIG_ANDROID_BINDER_DEVICES="binder,hwbinder,vndbinder,anbox-binder,anbox-hwbinder,anbox-vndbinder" CONFIG_NVMEM_LAYOUT_SL28_VPD=m CONFIG_NVMEM_QCOM_QFPROM=y CONFIG_NVMEM_QCOM_SEC_QFPROM=y @@ -924,30 +975,43 @@ CONFIG_PSTORE_RAM=m CONFIG_EROFS_FS=m CONFIG_NFS_FS=y CONFIG_NFSD=y -CONFIG_NLS_DEFAULT="utf-8" +CONFIG_NLS_DEFAULT="utf8" CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ASCII=y CONFIG_NLS_ISO8859_1=y +CONFIG_NLS_UTF8=y CONFIG_PERSISTENT_KEYRINGS=y CONFIG_ENCRYPTED_KEYS=y CONFIG_KEY_DH_OPERATIONS=y CONFIG_SECURITY=y CONFIG_SECURITY_APPARMOR=y -CONFIG_LSM="landlock,lockdown,yama,loadpin,safesetid,bpf" +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_LSM="landlock,lockdown,yama,loadpin,safesetid,apparmor,bpf" CONFIG_CRYPTO_USER=y +CONFIG_CRYPTO_NULL=y CONFIG_CRYPTO_ECDH=y -CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_DES=y CONFIG_CRYPTO_ARC4=m CONFIG_CRYPTO_CCM=y CONFIG_CRYPTO_ECHAINIV=y +CONFIG_CRYPTO_BLAKE2B=y CONFIG_CRYPTO_CMAC=y +CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_XXHASH=y +CONFIG_CRYPTO_CRC32C=y +CONFIG_CRYPTO_CRC32=y CONFIG_CRYPTO_ANSI_CPRNG=y -CONFIG_CRYPTO_USER_API_RNG=m +CONFIG_CRYPTO_USER_API_HASH=y +CONFIG_CRYPTO_USER_API_SKCIPHER=y +CONFIG_CRYPTO_USER_API_RNG=y +CONFIG_CRYPTO_USER_API_AEAD=m CONFIG_CRYPTO_GHASH_ARM64_CE=y CONFIG_CRYPTO_SHA3_ARM64=m CONFIG_CRYPTO_SM3_ARM64_CE=m -CONFIG_CRYPTO_AES_ARM64_BS=m +CONFIG_CRYPTO_AES_ARM64=y +CONFIG_CRYPTO_AES_ARM64_BS=y CONFIG_CRYPTO_AES_ARM64_CE_CCM=y CONFIG_CRYPTO_DEV_QCE=y CONFIG_CRYPTO_DEV_QCOM_RNG=y @@ -968,8 +1032,11 @@ CONFIG_CONSOLE_LOGLEVEL_DEFAULT=4 CONFIG_CONSOLE_LOGLEVEL_QUIET=1 CONFIG_BOOT_PRINTK_DELAY=y CONFIG_DYNAMIC_DEBUG=y +CONFIG_DEBUG_INFO_DWARF5=y +CONFIG_DEBUG_INFO_REDUCED=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_FS=y CONFIG_DEBUG_MEMORY_INIT=y -# CONFIG_FTRACE is not set +CONFIG_FUNCTION_TRACER=y +CONFIG_FTRACE_SYSCALLS=y CONFIG_MEMTEST=y diff --git a/config/sources/families/sm8550.conf b/config/sources/families/sm8550.conf index 345174165716..929af21af949 100644 --- a/config/sources/families/sm8550.conf +++ b/config/sources/families/sm8550.conf @@ -14,10 +14,9 @@ declare -g BOOTENV_FILE="qcom-abl.txt" enable_extension "image-output-abl" case $BRANCH in - current) - declare -g KERNEL_MAJOR_MINOR="6.12" # Major and minor versions of this kernel. - declare -g KERNELBRANCH='branch:linux-6.12.y' + declare -g KERNEL_MAJOR_MINOR="6.18" # Major and minor versions of this kernel. + declare -g KERNELBRANCH='branch:linux-6.18.y' declare -g -i KERNEL_GIT_CACHE_TTL=120 # 2 minutes; this is a high-traffic repo ;; diff --git a/extensions/odin2-preset-firstrun.sh b/extensions/odin2-preset-firstrun.sh new file mode 100644 index 000000000000..503ccfab7896 --- /dev/null +++ b/extensions/odin2-preset-firstrun.sh @@ -0,0 +1,79 @@ +function post_family_tweaks__preset_configs() { + display_alert "$BOARD" "preset configs for rootfs" "info" + # Set PRESET_NET_CHANGE_DEFAULTS to 1 to apply any network related settings below + echo "PRESET_NET_CHANGE_DEFAULTS=1" > "${SDCARD}"/root/.not_logged_in_yet + + # Enable WiFi or Ethernet. + # NB: If both are enabled, WiFi will take priority and Ethernet will be disabled. + echo "PRESET_NET_ETHERNET_ENABLED=1" >> "${SDCARD}"/root/.not_logged_in_yet + echo "PRESET_NET_WIFI_ENABLED=1" >> "${SDCARD}"/root/.not_logged_in_yet + + #Enter your WiFi creds + # SECURITY WARN: Your wifi keys will be stored in plaintext, no encryption. + #echo "PRESET_NET_WIFI_SSID='MySSID'" >> "${SDCARD}"/root/.not_logged_in_yet + #echo "PRESET_NET_WIFI_KEY='MyWiFiKEY'" >> "${SDCARD}"/root/.not_logged_in_yet + + # Country code to enable power ratings and channels for your country. eg: GB US DE | https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 + #echo "PRESET_NET_WIFI_COUNTRYCODE='GB'" >> "${SDCARD}"/root/.not_logged_in_yet + + #If you want to use a static ip, set it here + #echo "PRESET_NET_USE_STATIC=1" >> "${SDCARD}"/root/.not_logged_in_yet + #echo "PRESET_NET_STATIC_IP='192.168.0.100'" >> "${SDCARD}"/root/.not_logged_in_yet + #echo "PRESET_NET_STATIC_MASK='255.255.255.0'" >> "${SDCARD}"/root/.not_logged_in_yet + #echo "PRESET_NET_STATIC_GATEWAY='192.168.0.1'" >> "${SDCARD}"/root/.not_logged_in_yet + #echo "PRESET_NET_STATIC_DNS='8.8.8.8 8.8.4.4'" >> "${SDCARD}"/root/.not_logged_in_yet + + # Preset user default shell, you can choose bash or zsh + echo "PRESET_USER_SHELL=bash" >> "${SDCARD}"/root/.not_logged_in_yet + + # Set PRESET_CONNECT_WIRELESS=y if you want to connect wifi manually at first login + echo "PRESET_CONNECT_WIRELESS=n" >> "${SDCARD}"/root/.not_logged_in_yet + + # Set SET_LANG_BASED_ON_LOCATION=n if you want to choose "Set user language based on your location?" with "n" at first login + echo "SET_LANG_BASED_ON_LOCATION=y" >> "${SDCARD}"/root/.not_logged_in_yet + + # Preset default locale + echo "PRESET_LOCALE=en_US.UTF-8" >> "${SDCARD}"/root/.not_logged_in_yet + + # Preset timezone + echo "PRESET_TIMEZONE=Etc/UTC" >> "${SDCARD}"/root/.not_logged_in_yet + + # Preset root password + echo "PRESET_ROOT_PASSWORD=1234" >> "${SDCARD}"/root/.not_logged_in_yet + + # Preset username + echo "PRESET_USER_NAME=odin2" >> "${SDCARD}"/root/.not_logged_in_yet + + # Preset user password + echo "PRESET_USER_PASSWORD=1234" >> "${SDCARD}"/root/.not_logged_in_yet + + # Preset user default realname + echo "PRESET_DEFAULT_REALNAME=Odin2" >> "${SDCARD}"/root/.not_logged_in_yet +} + +function pre_customize_image__add_odin2_scripts() { + display_alert "Adding Odin2 Scripts" "${EXTENSION}" "info" + + local launcher_dir="${SDCARD}/usr/local" + run_host_command_logged mkdir -pv "${launcher_dir}" + + chroot_sdcard git clone https://github.com/Squishy123/odin2-scripts.git "$launcher_dir/odin2-scripts" + + + local launcher_dir="${SDCARD}/usr/local/bin" + local launcher_file="${launcher_dir}/install-odin2-scripts" + run_host_command_logged mkdir -pv "${launcher_dir}" + + cat <<- 'INSTALL_ODIN_2_SCRIPT' > "${launcher_file}" + #!/usr/bin/env bash + if [[ ! -d ~/sys/odin2-scripts ]]; then + mkdir -p ~/sys + git clone https://github.com/Squishy123/odin2-scripts.git ~/sys/odin2-scripts + fi + cd ~/sys/odin2-scripts + INSTALL_ODIN_2_SCRIPT + + run_host_command_logged chmod -v +x "${launcher_file}" + display_alert "Added Odin2 Scripts" "${EXTENSION}" "info" +} + diff --git a/packages/bsp/ayn-odin2mini/AYN-Odin2.conf b/packages/bsp/ayn-odin2mini/AYN-Odin2.conf new file mode 100644 index 000000000000..e4054ba63bfa --- /dev/null +++ b/packages/bsp/ayn-odin2mini/AYN-Odin2.conf @@ -0,0 +1,31 @@ +# Use case configuration for AYN Odin2 +# Author: Teguh Sobirin + +Syntax 4 + +SectionUseCase."HiFi" { + File "/AYN/Odin2/HiFi.conf" + Comment "HiFi quality Music." +} + +BootSequence [ + cset "name='RX_RX0 Digital Volume' 84" + cset "name='RX_RX1 Digital Volume' 84" + cset "name='HPHL Volume' 20" + cset "name='HPHR Volume' 20" + cset "name='ADC2 Volume' 10" +] + +LibraryConfig.remap.Config { + + ctl.default.map { + "name='HP Volume'" { + "name='HPHL Volume'".vindex.0 0 + "name='HPHR Volume'".vindex.1 0 + } + } +} + +Include.card-init.File "/lib/card-init.conf" +Include.ctl-remap.File "/lib/ctl-remap.conf" +Include.wcd-init.File "/codecs/wcd938x/init.conf" diff --git a/packages/bsp/ayn-odin2mini/HiFi.conf b/packages/bsp/ayn-odin2mini/HiFi.conf new file mode 100644 index 000000000000..dc5211e12a18 --- /dev/null +++ b/packages/bsp/ayn-odin2mini/HiFi.conf @@ -0,0 +1,91 @@ +# Use case configuration for AYN Odin2 +# Author: Teguh Sobirin + +SectionVerb { + EnableSequence [ + cset "name='PRIMARY_MI2S_RX Audio Mixer MultiMedia1' 1" + cset "name='RX_CODEC_DMA_RX_0 Audio Mixer MultiMedia2' 1" + cset "name='DISPLAY_PORT_RX_0 Audio Mixer MultiMedia2' 0" + cset "name='MultiMedia3 Mixer TX_CODEC_DMA_TX_3' 1" + ] + + DisableSequence [ + cset "name='PRIMARY_MI2S_RX Audio Mixer MultiMedia1' 0" + cset "name='RX_CODEC_DMA_RX_0 Audio Mixer MultiMedia2' 0" + cset "name='DISPLAY_PORT_RX_0 Audio Mixer MultiMedia2' 0" + cset "name='MultiMedia3 Mixer TX_CODEC_DMA_TX_3' 0" + ] + + Value { + TQ "HiFi" + } +} + +SectionDevice."Speaker" { + Comment "Speaker playback" + + Value { + PlaybackPriority 150 + PlaybackPCM "hw:${CardId},0" + PlaybackChannels 2 + } +} + +SectionDevice."Headphones" { + Comment "Headphones Playback" + + Include.wcdhpe.File "/codecs/wcd938x/HeadphoneEnableSeq.conf" + Include.wcdhpd.File "/codecs/wcd938x/HeadphoneDisableSeq.conf" + Include.rxmhpe.File "/codecs/qcom-lpass/rx-macro/HeadphoneEnableSeq.conf" + Include.rxmhpd.File "/codecs/qcom-lpass/rx-macro/HeadphoneDisableSeq.conf" + + Value { + PlaybackPriority 200 + PlaybackPCM "hw:${CardId},1" + PlaybackMixer "default:${CardId}" + PlaybackMixerElem "HP" + PlaybackChannels 2 + JackControl "Headphone Jack" + JackHWMute "Speaker" + } +} + +SectionDevice."Headset" { + Comment "Headphone Microphone" + + Include.wcdmice.File "/codecs/wcd938x/HeadphoneMicEnableSeq.conf" + Include.wcdmicd.File "/codecs/wcd938x/HeadphoneMicDisableSeq.conf" + Include.txmhpe.File "/codecs/qcom-lpass/tx-macro/SoundwireMic1EnableSeq.conf" + Include.txmhpd.File "/codecs/qcom-lpass/tx-macro/HeadphoneMicDisableSeq.conf" + + Value { + CapturePriority 200 + CapturePCM "hw:${CardId},2" + CaptureMixerElem "ADC2" + CaptureChannels 1 + JackControl "Mic Jack" + } +} + +SectionDevice."DisplayPort" { + Comment "DisplayPort playback" + + EnableSequence [ + cset "name='PRIMARY_MI2S_RX Audio Mixer MultiMedia1' 0" + cset "name='RX_CODEC_DMA_RX_0 Audio Mixer MultiMedia2' 0" + cset "name='DISPLAY_PORT_RX_0 Audio Mixer MultiMedia2' 1" + ] + + DisableSequence [ + cset "name='PRIMARY_MI2S_RX Audio Mixer MultiMedia1' 1" + cset "name='DISPLAY_PORT_RX_0 Audio Mixer MultiMedia2' 0" + cset "name='RX_CODEC_DMA_RX_0 Audio Mixer MultiMedia2' 1" + ] + + Value { + PlaybackPriority 100 + PlaybackPCM "hw:${CardId},1" + JackControl "DP0 Jack" + JackHWMute "Speaker" + } +} diff --git a/packages/bsp/ayn-odin2mini/LinuxLoader.cfg b/packages/bsp/ayn-odin2mini/LinuxLoader.cfg new file mode 100644 index 000000000000..8a7c1c2c00ba --- /dev/null +++ b/packages/bsp/ayn-odin2mini/LinuxLoader.cfg @@ -0,0 +1,58 @@ +# +# Configure the LinuxLoader settings +# + +[LinuxLoader] + +# Controls on-screen logging +# This setting can persist without config file or sdcard being present +Debug = true + +# Boot target. Can be one of the following: +# "default" (ABL default) +# "Linux" (direct Linux Image load) +# "EFI" +# "UEFI Shell" (will execute startup.nsh automatically if found on any FAT partition) +# "Mass Storage" (will mount the UFS LUN specified below as mass storage) +Target = "default" + +# Default UFS LUN to mount as mass storage +# Allowed values: 0, 1, 2, 3, 4, 5 +MassStorageLUN = 0 + +# Volume up boot target. Can be one of the following: +# "BDS Menu" (will enter the UEFI boot menu provided by Qualcomm, don't touch anything there unless you know what you are doing!) +# "UEFI Shell" (will execute startup.nsh automatically if found on any FAT partition) +# "recovery" +# "Linux" +DefaultVolUp = "Linux" + +# Setting this to *true* will enable USB Host mode in UEFI +# This might be useful if you want to play with UEFI. +# Note that you will need an externally powered type-C hub to connect USB devices. (at least for now) +UsbHostMode = false + +# Controls hypervisor UART enablement +# +# Setting *true* here will force enable the hypervisor UART +# Setting *false* here will force disable the hypervisor UART +# Removing this line will avoid changing the default behavior +# Please leave it to *false* unless you know what you are doing +HypUartEnable = false + +# Controls display hardware status during exit boot services +# +# The dispcc driver from mainline Linux kernel has a bug, which +# prevents the display hardware from initializing properly if +# the display hardware is not disabled before exiting boot services. +# +# Set this to *true* if you are trying to boot a mainline kernel. +DisableDisplayHW = true + +[Linux] +# Accept both gzipped and non-gzipped kernel images +Image = "Image" +initrd = "initrd.img-INITRD_PLACEHOLDER" +devicetree = "dtb/qcom/qcs8550-ayn-odin2mini.dtb" +cmdline = "clk_ignore_unused pd_ignore_unused arm64.nopauthfbcon=rotate:3 console=ttyMSM0,115200n8 root=UUID=UUID_PLACEHOLDER" + diff --git a/packages/bsp/ayn-odin2mini/zz-update-abl-kernel b/packages/bsp/ayn-odin2mini/zz-update-abl-kernel new file mode 100755 index 000000000000..1ff4f1c84e11 --- /dev/null +++ b/packages/bsp/ayn-odin2mini/zz-update-abl-kernel @@ -0,0 +1,20 @@ +#!/bin/bash +set -ex +new_rootfs_image_uuid=$(sed -e 's/^.*root=UUID=//' -e 's/ .*$//' < /proc/cmdline) +gzip -c /boot/vmlinuz-*-sm8550-arm64 > /tmp/Image.gz + +cat /tmp/Image.gz /usr/lib/linux-image-*-sm8550-arm64/qcom/qcs8550-ayn-odin2-hypdtbo.dtb > /tmp/Image.gz-dtb + +source /boot/armbianEnv.txt +/usr/bin/mkbootimg \ + --kernel /tmp/Image.gz-dtb \ + --ramdisk /boot/initrd.img-*-sm8550-arm64 \ + --base 0x0 \ + --second_offset 0x00f00000 \ + --cmdline "clk_ignore_unused pd_ignore_unused panic=30 audit=0 allow_mismatched_32bit_el0 rw mem_sleep_default=s2idle root=UUID=${new_rootfs_image_uuid}" \ + --kernel_offset 0x8000 \ + --ramdisk_offset 0x1000000 \ + --tags_offset 0x100 \ + --pagesize 4096 \ + -o /boot/armbian-kernel.img +rm -f /tmp/Image.gz /tmp/Image.gz-dtb diff --git a/packages/bsp/ayn-odin2portal/AYN-Odin2.conf b/packages/bsp/ayn-odin2portal/AYN-Odin2.conf new file mode 100644 index 000000000000..e4054ba63bfa --- /dev/null +++ b/packages/bsp/ayn-odin2portal/AYN-Odin2.conf @@ -0,0 +1,31 @@ +# Use case configuration for AYN Odin2 +# Author: Teguh Sobirin + +Syntax 4 + +SectionUseCase."HiFi" { + File "/AYN/Odin2/HiFi.conf" + Comment "HiFi quality Music." +} + +BootSequence [ + cset "name='RX_RX0 Digital Volume' 84" + cset "name='RX_RX1 Digital Volume' 84" + cset "name='HPHL Volume' 20" + cset "name='HPHR Volume' 20" + cset "name='ADC2 Volume' 10" +] + +LibraryConfig.remap.Config { + + ctl.default.map { + "name='HP Volume'" { + "name='HPHL Volume'".vindex.0 0 + "name='HPHR Volume'".vindex.1 0 + } + } +} + +Include.card-init.File "/lib/card-init.conf" +Include.ctl-remap.File "/lib/ctl-remap.conf" +Include.wcd-init.File "/codecs/wcd938x/init.conf" diff --git a/packages/bsp/ayn-odin2portal/HiFi.conf b/packages/bsp/ayn-odin2portal/HiFi.conf new file mode 100644 index 000000000000..dc5211e12a18 --- /dev/null +++ b/packages/bsp/ayn-odin2portal/HiFi.conf @@ -0,0 +1,91 @@ +# Use case configuration for AYN Odin2 +# Author: Teguh Sobirin + +SectionVerb { + EnableSequence [ + cset "name='PRIMARY_MI2S_RX Audio Mixer MultiMedia1' 1" + cset "name='RX_CODEC_DMA_RX_0 Audio Mixer MultiMedia2' 1" + cset "name='DISPLAY_PORT_RX_0 Audio Mixer MultiMedia2' 0" + cset "name='MultiMedia3 Mixer TX_CODEC_DMA_TX_3' 1" + ] + + DisableSequence [ + cset "name='PRIMARY_MI2S_RX Audio Mixer MultiMedia1' 0" + cset "name='RX_CODEC_DMA_RX_0 Audio Mixer MultiMedia2' 0" + cset "name='DISPLAY_PORT_RX_0 Audio Mixer MultiMedia2' 0" + cset "name='MultiMedia3 Mixer TX_CODEC_DMA_TX_3' 0" + ] + + Value { + TQ "HiFi" + } +} + +SectionDevice."Speaker" { + Comment "Speaker playback" + + Value { + PlaybackPriority 150 + PlaybackPCM "hw:${CardId},0" + PlaybackChannels 2 + } +} + +SectionDevice."Headphones" { + Comment "Headphones Playback" + + Include.wcdhpe.File "/codecs/wcd938x/HeadphoneEnableSeq.conf" + Include.wcdhpd.File "/codecs/wcd938x/HeadphoneDisableSeq.conf" + Include.rxmhpe.File "/codecs/qcom-lpass/rx-macro/HeadphoneEnableSeq.conf" + Include.rxmhpd.File "/codecs/qcom-lpass/rx-macro/HeadphoneDisableSeq.conf" + + Value { + PlaybackPriority 200 + PlaybackPCM "hw:${CardId},1" + PlaybackMixer "default:${CardId}" + PlaybackMixerElem "HP" + PlaybackChannels 2 + JackControl "Headphone Jack" + JackHWMute "Speaker" + } +} + +SectionDevice."Headset" { + Comment "Headphone Microphone" + + Include.wcdmice.File "/codecs/wcd938x/HeadphoneMicEnableSeq.conf" + Include.wcdmicd.File "/codecs/wcd938x/HeadphoneMicDisableSeq.conf" + Include.txmhpe.File "/codecs/qcom-lpass/tx-macro/SoundwireMic1EnableSeq.conf" + Include.txmhpd.File "/codecs/qcom-lpass/tx-macro/HeadphoneMicDisableSeq.conf" + + Value { + CapturePriority 200 + CapturePCM "hw:${CardId},2" + CaptureMixerElem "ADC2" + CaptureChannels 1 + JackControl "Mic Jack" + } +} + +SectionDevice."DisplayPort" { + Comment "DisplayPort playback" + + EnableSequence [ + cset "name='PRIMARY_MI2S_RX Audio Mixer MultiMedia1' 0" + cset "name='RX_CODEC_DMA_RX_0 Audio Mixer MultiMedia2' 0" + cset "name='DISPLAY_PORT_RX_0 Audio Mixer MultiMedia2' 1" + ] + + DisableSequence [ + cset "name='PRIMARY_MI2S_RX Audio Mixer MultiMedia1' 1" + cset "name='DISPLAY_PORT_RX_0 Audio Mixer MultiMedia2' 0" + cset "name='RX_CODEC_DMA_RX_0 Audio Mixer MultiMedia2' 1" + ] + + Value { + PlaybackPriority 100 + PlaybackPCM "hw:${CardId},1" + JackControl "DP0 Jack" + JackHWMute "Speaker" + } +} diff --git a/packages/bsp/ayn-odin2portal/LinuxLoader.cfg b/packages/bsp/ayn-odin2portal/LinuxLoader.cfg new file mode 100644 index 000000000000..7199d64db58d --- /dev/null +++ b/packages/bsp/ayn-odin2portal/LinuxLoader.cfg @@ -0,0 +1,58 @@ +# +# Configure the LinuxLoader settings +# + +[LinuxLoader] + +# Controls on-screen logging +# This setting can persist without config file or sdcard being present +Debug = true + +# Boot target. Can be one of the following: +# "default" (ABL default) +# "Linux" (direct Linux Image load) +# "EFI" +# "UEFI Shell" (will execute startup.nsh automatically if found on any FAT partition) +# "Mass Storage" (will mount the UFS LUN specified below as mass storage) +Target = "default" + +# Default UFS LUN to mount as mass storage +# Allowed values: 0, 1, 2, 3, 4, 5 +MassStorageLUN = 0 + +# Volume up boot target. Can be one of the following: +# "BDS Menu" (will enter the UEFI boot menu provided by Qualcomm, don't touch anything there unless you know what you are doing!) +# "UEFI Shell" (will execute startup.nsh automatically if found on any FAT partition) +# "recovery" +# "Linux" +DefaultVolUp = "Linux" + +# Setting this to *true* will enable USB Host mode in UEFI +# This might be useful if you want to play with UEFI. +# Note that you will need an externally powered type-C hub to connect USB devices. (at least for now) +UsbHostMode = false + +# Controls hypervisor UART enablement +# +# Setting *true* here will force enable the hypervisor UART +# Setting *false* here will force disable the hypervisor UART +# Removing this line will avoid changing the default behavior +# Please leave it to *false* unless you know what you are doing +HypUartEnable = false + +# Controls display hardware status during exit boot services +# +# The dispcc driver from mainline Linux kernel has a bug, which +# prevents the display hardware from initializing properly if +# the display hardware is not disabled before exiting boot services. +# +# Set this to *true* if you are trying to boot a mainline kernel. +DisableDisplayHW = true + +[Linux] +# Accept both gzipped and non-gzipped kernel images +Image = "Image" +initrd = "initrd.img-INITRD_PLACEHOLDER" +devicetree = "dtb/qcom/qcs8550-ayn-odin2portal.dtb" +cmdline = "clk_ignore_unused pd_ignore_unused arm64.nopauthfbcon=rotate:3 console=ttyMSM0,115200n8 root=UUID=UUID_PLACEHOLDER" + diff --git a/packages/bsp/ayn-odin2portal/zz-update-abl-kernel b/packages/bsp/ayn-odin2portal/zz-update-abl-kernel new file mode 100755 index 000000000000..1ff4f1c84e11 --- /dev/null +++ b/packages/bsp/ayn-odin2portal/zz-update-abl-kernel @@ -0,0 +1,20 @@ +#!/bin/bash +set -ex +new_rootfs_image_uuid=$(sed -e 's/^.*root=UUID=//' -e 's/ .*$//' < /proc/cmdline) +gzip -c /boot/vmlinuz-*-sm8550-arm64 > /tmp/Image.gz + +cat /tmp/Image.gz /usr/lib/linux-image-*-sm8550-arm64/qcom/qcs8550-ayn-odin2-hypdtbo.dtb > /tmp/Image.gz-dtb + +source /boot/armbianEnv.txt +/usr/bin/mkbootimg \ + --kernel /tmp/Image.gz-dtb \ + --ramdisk /boot/initrd.img-*-sm8550-arm64 \ + --base 0x0 \ + --second_offset 0x00f00000 \ + --cmdline "clk_ignore_unused pd_ignore_unused panic=30 audit=0 allow_mismatched_32bit_el0 rw mem_sleep_default=s2idle root=UUID=${new_rootfs_image_uuid}" \ + --kernel_offset 0x8000 \ + --ramdisk_offset 0x1000000 \ + --tags_offset 0x100 \ + --pagesize 4096 \ + -o /boot/armbian-kernel.img +rm -f /tmp/Image.gz /tmp/Image.gz-dtb diff --git a/packages/bsp/ayn-thor/AYN-Odin2.conf b/packages/bsp/ayn-thor/AYN-Odin2.conf new file mode 100644 index 000000000000..e4054ba63bfa --- /dev/null +++ b/packages/bsp/ayn-thor/AYN-Odin2.conf @@ -0,0 +1,31 @@ +# Use case configuration for AYN Odin2 +# Author: Teguh Sobirin + +Syntax 4 + +SectionUseCase."HiFi" { + File "/AYN/Odin2/HiFi.conf" + Comment "HiFi quality Music." +} + +BootSequence [ + cset "name='RX_RX0 Digital Volume' 84" + cset "name='RX_RX1 Digital Volume' 84" + cset "name='HPHL Volume' 20" + cset "name='HPHR Volume' 20" + cset "name='ADC2 Volume' 10" +] + +LibraryConfig.remap.Config { + + ctl.default.map { + "name='HP Volume'" { + "name='HPHL Volume'".vindex.0 0 + "name='HPHR Volume'".vindex.1 0 + } + } +} + +Include.card-init.File "/lib/card-init.conf" +Include.ctl-remap.File "/lib/ctl-remap.conf" +Include.wcd-init.File "/codecs/wcd938x/init.conf" diff --git a/packages/bsp/ayn-thor/HiFi.conf b/packages/bsp/ayn-thor/HiFi.conf new file mode 100644 index 000000000000..dc5211e12a18 --- /dev/null +++ b/packages/bsp/ayn-thor/HiFi.conf @@ -0,0 +1,91 @@ +# Use case configuration for AYN Odin2 +# Author: Teguh Sobirin + +SectionVerb { + EnableSequence [ + cset "name='PRIMARY_MI2S_RX Audio Mixer MultiMedia1' 1" + cset "name='RX_CODEC_DMA_RX_0 Audio Mixer MultiMedia2' 1" + cset "name='DISPLAY_PORT_RX_0 Audio Mixer MultiMedia2' 0" + cset "name='MultiMedia3 Mixer TX_CODEC_DMA_TX_3' 1" + ] + + DisableSequence [ + cset "name='PRIMARY_MI2S_RX Audio Mixer MultiMedia1' 0" + cset "name='RX_CODEC_DMA_RX_0 Audio Mixer MultiMedia2' 0" + cset "name='DISPLAY_PORT_RX_0 Audio Mixer MultiMedia2' 0" + cset "name='MultiMedia3 Mixer TX_CODEC_DMA_TX_3' 0" + ] + + Value { + TQ "HiFi" + } +} + +SectionDevice."Speaker" { + Comment "Speaker playback" + + Value { + PlaybackPriority 150 + PlaybackPCM "hw:${CardId},0" + PlaybackChannels 2 + } +} + +SectionDevice."Headphones" { + Comment "Headphones Playback" + + Include.wcdhpe.File "/codecs/wcd938x/HeadphoneEnableSeq.conf" + Include.wcdhpd.File "/codecs/wcd938x/HeadphoneDisableSeq.conf" + Include.rxmhpe.File "/codecs/qcom-lpass/rx-macro/HeadphoneEnableSeq.conf" + Include.rxmhpd.File "/codecs/qcom-lpass/rx-macro/HeadphoneDisableSeq.conf" + + Value { + PlaybackPriority 200 + PlaybackPCM "hw:${CardId},1" + PlaybackMixer "default:${CardId}" + PlaybackMixerElem "HP" + PlaybackChannels 2 + JackControl "Headphone Jack" + JackHWMute "Speaker" + } +} + +SectionDevice."Headset" { + Comment "Headphone Microphone" + + Include.wcdmice.File "/codecs/wcd938x/HeadphoneMicEnableSeq.conf" + Include.wcdmicd.File "/codecs/wcd938x/HeadphoneMicDisableSeq.conf" + Include.txmhpe.File "/codecs/qcom-lpass/tx-macro/SoundwireMic1EnableSeq.conf" + Include.txmhpd.File "/codecs/qcom-lpass/tx-macro/HeadphoneMicDisableSeq.conf" + + Value { + CapturePriority 200 + CapturePCM "hw:${CardId},2" + CaptureMixerElem "ADC2" + CaptureChannels 1 + JackControl "Mic Jack" + } +} + +SectionDevice."DisplayPort" { + Comment "DisplayPort playback" + + EnableSequence [ + cset "name='PRIMARY_MI2S_RX Audio Mixer MultiMedia1' 0" + cset "name='RX_CODEC_DMA_RX_0 Audio Mixer MultiMedia2' 0" + cset "name='DISPLAY_PORT_RX_0 Audio Mixer MultiMedia2' 1" + ] + + DisableSequence [ + cset "name='PRIMARY_MI2S_RX Audio Mixer MultiMedia1' 1" + cset "name='DISPLAY_PORT_RX_0 Audio Mixer MultiMedia2' 0" + cset "name='RX_CODEC_DMA_RX_0 Audio Mixer MultiMedia2' 1" + ] + + Value { + PlaybackPriority 100 + PlaybackPCM "hw:${CardId},1" + JackControl "DP0 Jack" + JackHWMute "Speaker" + } +} diff --git a/packages/bsp/ayn-thor/LinuxLoader.cfg b/packages/bsp/ayn-thor/LinuxLoader.cfg new file mode 100644 index 000000000000..f14e23f13155 --- /dev/null +++ b/packages/bsp/ayn-thor/LinuxLoader.cfg @@ -0,0 +1,58 @@ +# +# Configure the LinuxLoader settings +# + +[LinuxLoader] + +# Controls on-screen logging +# This setting can persist without config file or sdcard being present +Debug = true + +# Boot target. Can be one of the following: +# "default" (ABL default) +# "Linux" (direct Linux Image load) +# "EFI" +# "UEFI Shell" (will execute startup.nsh automatically if found on any FAT partition) +# "Mass Storage" (will mount the UFS LUN specified below as mass storage) +Target = "default" + +# Default UFS LUN to mount as mass storage +# Allowed values: 0, 1, 2, 3, 4, 5 +MassStorageLUN = 0 + +# Volume up boot target. Can be one of the following: +# "BDS Menu" (will enter the UEFI boot menu provided by Qualcomm, don't touch anything there unless you know what you are doing!) +# "UEFI Shell" (will execute startup.nsh automatically if found on any FAT partition) +# "recovery" +# "Linux" +DefaultVolUp = "Linux" + +# Setting this to *true* will enable USB Host mode in UEFI +# This might be useful if you want to play with UEFI. +# Note that you will need an externally powered type-C hub to connect USB devices. (at least for now) +UsbHostMode = false + +# Controls hypervisor UART enablement +# +# Setting *true* here will force enable the hypervisor UART +# Setting *false* here will force disable the hypervisor UART +# Removing this line will avoid changing the default behavior +# Please leave it to *false* unless you know what you are doing +HypUartEnable = false + +# Controls display hardware status during exit boot services +# +# The dispcc driver from mainline Linux kernel has a bug, which +# prevents the display hardware from initializing properly if +# the display hardware is not disabled before exiting boot services. +# +# Set this to *true* if you are trying to boot a mainline kernel. +DisableDisplayHW = true + +[Linux] +# Accept both gzipped and non-gzipped kernel images +Image = "Image" +initrd = "initrd.img-INITRD_PLACEHOLDER" +devicetree = "dtb/qcom/qcs8550-ayn-thor.dtb" +cmdline = "clk_ignore_unused pd_ignore_unused arm64.nopauthfbcon=rotate:3 console=ttyMSM0,115200n8 root=UUID=UUID_PLACEHOLDER" + diff --git a/packages/bsp/ayn-thor/zz-update-abl-kernel b/packages/bsp/ayn-thor/zz-update-abl-kernel new file mode 100755 index 000000000000..1ff4f1c84e11 --- /dev/null +++ b/packages/bsp/ayn-thor/zz-update-abl-kernel @@ -0,0 +1,20 @@ +#!/bin/bash +set -ex +new_rootfs_image_uuid=$(sed -e 's/^.*root=UUID=//' -e 's/ .*$//' < /proc/cmdline) +gzip -c /boot/vmlinuz-*-sm8550-arm64 > /tmp/Image.gz + +cat /tmp/Image.gz /usr/lib/linux-image-*-sm8550-arm64/qcom/qcs8550-ayn-odin2-hypdtbo.dtb > /tmp/Image.gz-dtb + +source /boot/armbianEnv.txt +/usr/bin/mkbootimg \ + --kernel /tmp/Image.gz-dtb \ + --ramdisk /boot/initrd.img-*-sm8550-arm64 \ + --base 0x0 \ + --second_offset 0x00f00000 \ + --cmdline "clk_ignore_unused pd_ignore_unused panic=30 audit=0 allow_mismatched_32bit_el0 rw mem_sleep_default=s2idle root=UUID=${new_rootfs_image_uuid}" \ + --kernel_offset 0x8000 \ + --ramdisk_offset 0x1000000 \ + --tags_offset 0x100 \ + --pagesize 4096 \ + -o /boot/armbian-kernel.img +rm -f /tmp/Image.gz /tmp/Image.gz-dtb diff --git a/patch/kernel/archive/sm8550-6.12/0000.patching_config.yaml b/patch/kernel/archive/sm8550-6.12/0000.patching_config.yaml deleted file mode 100644 index 4fc665201f4d..000000000000 --- a/patch/kernel/archive/sm8550-6.12/0000.patching_config.yaml +++ /dev/null @@ -1,27 +0,0 @@ -config: # This is file 'patch/kernel/archive/sm8250-6.7/0000.patching_config.yaml' - - # Just some info stuff; not used by the patching scripts - name: sm8550-6.12 - kind: kernel - type: mainline # or: vendor - branch: linux-6.12.y - last-known-good-tag: v6.12.17 - - # .dts files in these directories will be copied as-is to the build tree; later ones overwrite earlier ones. - # This is meant to provide a way to "add a board DTS" without having to null-patch them in. - dts-directories: - - { source: "dt", target: "arch/arm64/boot/dts/qcom" } - - # the Makefile in each of these directories will be magically patched to include the dts files copied - # or patched-in; overlay subdir will be included "-y" if it exists. - # No more Makefile patching needed, yay! - auto-patch-dt-makefile: - - { directory: "arch/arm64/boot/dts/qcom", config-var: "CONFIG_ARCH_QCOM" } - - # configuration for when applying patches to git / auto-rewriting patches (development cycle helpers) - patches-to-git: - do-not-commit-files: - - "MAINTAINERS" # constant churn, drop them. sorry. - do-not-commit-regexes: # Python-style regexes - - "^arch/([a-zA-Z0-9]+)/boot/dts/([a-zA-Z0-9]+)/Makefile$" # ignore DT Makefile patches, we've an auto-patcher now - diff --git a/patch/kernel/archive/sm8550-6.12/0001_dt-bindings--media--Add-video-support-for-QCOM-SM8.patch b/patch/kernel/archive/sm8550-6.12/0001_dt-bindings--media--Add-video-support-for-QCOM-SM8.patch deleted file mode 100644 index fbf063097175..000000000000 --- a/patch/kernel/archive/sm8550-6.12/0001_dt-bindings--media--Add-video-support-for-QCOM-SM8.patch +++ /dev/null @@ -1,189 +0,0 @@ -From a9472b31293c4aa544519883eb600ca9176ae55e Mon Sep 17 00:00:00 2001 -From: Dikshita Agarwal -Date: Fri, 7 Feb 2025 13:24:41 +0530 -Subject: [PATCH] dt-bindings: media: Add video support for QCOM SM8550 SoC - -Introduce support for Qualcomm new video acceleration hardware i.e. -iris, used for video stream decoding and encoding on QCOM SM8550 SoC. - -Cc: devicetree@vger.kernel.org -Reviewed-by: Krzysztof Kozlowski -Tested-by: Stefan Schmidt # x1e80100 (Dell XPS 13 9345) -Reviewed-by: Stefan Schmidt -Tested-by: Neil Armstrong # on SM8550-QRD -Tested-by: Neil Armstrong # on SM8550-HDK -Signed-off-by: Dikshita Agarwal -Link: https://lore.kernel.org/r/20250207-qcom-video-iris-v10-1-ab66eeffbd20@quicinc.com -Signed-off-by: Neil Armstrong ---- - .../bindings/media/qcom,sm8550-iris.yaml | 158 ++++++++++++++++++ - 1 file changed, 158 insertions(+) - create mode 100644 Documentation/devicetree/bindings/media/qcom,sm8550-iris.yaml - -diff --git a/Documentation/devicetree/bindings/media/qcom,sm8550-iris.yaml b/Documentation/devicetree/bindings/media/qcom,sm8550-iris.yaml -new file mode 100644 -index 000000000000..e424ea84c211 ---- /dev/null -+++ b/Documentation/devicetree/bindings/media/qcom,sm8550-iris.yaml -@@ -0,0 +1,158 @@ -+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) -+%YAML 1.2 -+--- -+$id: http://devicetree.org/schemas/media/qcom,sm8550-iris.yaml# -+$schema: http://devicetree.org/meta-schemas/core.yaml# -+ -+title: Qualcomm iris video encode and decode accelerators -+ -+maintainers: -+ - Vikash Garodia -+ - Dikshita Agarwal -+ -+description: -+ The iris video processing unit is a video encode and decode accelerator -+ present on Qualcomm platforms. -+ -+allOf: -+ - $ref: qcom,venus-common.yaml# -+ -+properties: -+ compatible: -+ const: qcom,sm8550-iris -+ -+ power-domains: -+ maxItems: 4 -+ -+ power-domain-names: -+ items: -+ - const: venus -+ - const: vcodec0 -+ - const: mxc -+ - const: mmcx -+ -+ clocks: -+ maxItems: 3 -+ -+ clock-names: -+ items: -+ - const: iface -+ - const: core -+ - const: vcodec0_core -+ -+ interconnects: -+ maxItems: 2 -+ -+ interconnect-names: -+ items: -+ - const: cpu-cfg -+ - const: video-mem -+ -+ resets: -+ maxItems: 1 -+ -+ reset-names: -+ items: -+ - const: bus -+ -+ iommus: -+ maxItems: 2 -+ -+ dma-coherent: true -+ -+ operating-points-v2: true -+ -+ opp-table: -+ type: object -+ -+required: -+ - compatible -+ - power-domain-names -+ - interconnects -+ - interconnect-names -+ - resets -+ - reset-names -+ - iommus -+ - dma-coherent -+ -+unevaluatedProperties: false -+ -+examples: -+ - | -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ -+ video-codec@aa00000 { -+ compatible = "qcom,sm8550-iris"; -+ reg = <0x0aa00000 0xf0000>; -+ interrupts = ; -+ -+ power-domains = <&videocc VIDEO_CC_MVS0C_GDSC>, -+ <&videocc VIDEO_CC_MVS0_GDSC>, -+ <&rpmhpd RPMHPD_MXC>, -+ <&rpmhpd RPMHPD_MMCX>; -+ power-domain-names = "venus", "vcodec0", "mxc", "mmcx"; -+ -+ clocks = <&gcc GCC_VIDEO_AXI0_CLK>, -+ <&videocc VIDEO_CC_MVS0C_CLK>, -+ <&videocc VIDEO_CC_MVS0_CLK>; -+ clock-names = "iface", "core", "vcodec0_core"; -+ -+ interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS -+ &config_noc SLAVE_VENUS_CFG QCOM_ICC_TAG_ALWAYS>, -+ <&mmss_noc MASTER_VIDEO QCOM_ICC_TAG_ALWAYS -+ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; -+ interconnect-names = "cpu-cfg", "video-mem"; -+ -+ memory-region = <&video_mem>; -+ -+ resets = <&gcc GCC_VIDEO_AXI0_CLK_ARES>; -+ reset-names = "bus"; -+ -+ iommus = <&apps_smmu 0x1940 0x0000>, -+ <&apps_smmu 0x1947 0x0000>; -+ dma-coherent; -+ -+ operating-points-v2 = <&iris_opp_table>; -+ -+ iris_opp_table: opp-table { -+ compatible = "operating-points-v2"; -+ -+ opp-240000000 { -+ opp-hz = /bits/ 64 <240000000>; -+ required-opps = <&rpmhpd_opp_svs>, -+ <&rpmhpd_opp_low_svs>; -+ }; -+ -+ opp-338000000 { -+ opp-hz = /bits/ 64 <338000000>; -+ required-opps = <&rpmhpd_opp_svs>, -+ <&rpmhpd_opp_svs>; -+ }; -+ -+ opp-366000000 { -+ opp-hz = /bits/ 64 <366000000>; -+ required-opps = <&rpmhpd_opp_svs_l1>, -+ <&rpmhpd_opp_svs_l1>; -+ }; -+ -+ opp-444000000 { -+ opp-hz = /bits/ 64 <444000000>; -+ required-opps = <&rpmhpd_opp_turbo>, -+ <&rpmhpd_opp_turbo>; -+ }; -+ -+ opp-533333334 { -+ opp-hz = /bits/ 64 <533333334>; -+ required-opps = <&rpmhpd_opp_turbo_l1>, -+ <&rpmhpd_opp_turbo_l1>; -+ }; -+ }; -+ }; -+... --- -2.34.1 - diff --git a/patch/kernel/archive/sm8550-6.12/0002_media--iris--add-platform-driver-for-iris-video-de.patch b/patch/kernel/archive/sm8550-6.12/0002_media--iris--add-platform-driver-for-iris-video-de.patch deleted file mode 100644 index d3c8ab06212f..000000000000 --- a/patch/kernel/archive/sm8550-6.12/0002_media--iris--add-platform-driver-for-iris-video-de.patch +++ /dev/null @@ -1,470 +0,0 @@ -From 6c0d38b27062f15b4a20ece8dbcae548e41a37a6 Mon Sep 17 00:00:00 2001 -From: Dikshita Agarwal -Date: Fri, 7 Feb 2025 13:24:42 +0530 -Subject: [PATCH] media: iris: add platform driver for iris video device - -In preparation for adding H264 decode functionality, add the probe and -remove functions and platform data to initialize iris resources, which -are clocks, interconnects, power domains, reset clocks, and clock -frequencies used for the iris hardware. - -Reviewed-by: Bryan O'Donoghue -Reviewed-by: Hans Verkuil -Tested-by: Stefan Schmidt # x1e80100 (Dell XPS 13 9345) -Reviewed-by: Stefan Schmidt -Tested-by: Neil Armstrong # on SM8550-QRD -Tested-by: Neil Armstrong # on SM8550-HDK -Signed-off-by: Dikshita Agarwal -Link: https://lore.kernel.org/r/20250207-qcom-video-iris-v10-2-ab66eeffbd20@quicinc.com -Signed-off-by: Neil Armstrong ---- - drivers/media/platform/qcom/Kconfig | 1 + - drivers/media/platform/qcom/Makefile | 1 + - drivers/media/platform/qcom/iris/Kconfig | 9 + - drivers/media/platform/qcom/iris/Makefile | 4 + - drivers/media/platform/qcom/iris/iris_core.h | 54 ++++ - .../platform/qcom/iris/iris_platform_common.h | 35 +++ - .../platform/qcom/iris/iris_platform_sm8550.c | 37 +++ - drivers/media/platform/qcom/iris/iris_probe.c | 237 ++++++++++++++++++ - 8 files changed, 378 insertions(+) - create mode 100644 drivers/media/platform/qcom/iris/Kconfig - create mode 100644 drivers/media/platform/qcom/iris/Makefile - create mode 100644 drivers/media/platform/qcom/iris/iris_core.h - create mode 100644 drivers/media/platform/qcom/iris/iris_platform_common.h - create mode 100644 drivers/media/platform/qcom/iris/iris_platform_sm8550.c - create mode 100644 drivers/media/platform/qcom/iris/iris_probe.c - -diff --git a/drivers/media/platform/qcom/Kconfig b/drivers/media/platform/qcom/Kconfig -index cc5799b9ea00..4f4d3a68e6e5 100644 ---- a/drivers/media/platform/qcom/Kconfig -+++ b/drivers/media/platform/qcom/Kconfig -@@ -3,4 +3,5 @@ - comment "Qualcomm media platform drivers" - - source "drivers/media/platform/qcom/camss/Kconfig" -+source "drivers/media/platform/qcom/iris/Kconfig" - source "drivers/media/platform/qcom/venus/Kconfig" -diff --git a/drivers/media/platform/qcom/Makefile b/drivers/media/platform/qcom/Makefile -index 4f055c396e04..ea2221a202c0 100644 ---- a/drivers/media/platform/qcom/Makefile -+++ b/drivers/media/platform/qcom/Makefile -@@ -1,3 +1,4 @@ - # SPDX-License-Identifier: GPL-2.0-only - obj-y += camss/ -+obj-y += iris/ - obj-y += venus/ -diff --git a/drivers/media/platform/qcom/iris/Kconfig b/drivers/media/platform/qcom/iris/Kconfig -new file mode 100644 -index 000000000000..34a2f81c5db3 ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/Kconfig -@@ -0,0 +1,9 @@ -+config VIDEO_QCOM_IRIS -+ tristate "Qualcomm iris V4L2 decoder driver" -+ depends on VIDEO_DEV -+ depends on ARCH_QCOM || COMPILE_TEST -+ help -+ This is a V4L2 driver for Qualcomm iris video accelerator -+ hardware. It accelerates decoding operations on various -+ Qualcomm SoCs. -+ To compile this driver as a module choose m here. -diff --git a/drivers/media/platform/qcom/iris/Makefile b/drivers/media/platform/qcom/iris/Makefile -new file mode 100644 -index 000000000000..7e701361492e ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/Makefile -@@ -0,0 +1,4 @@ -+iris-objs += iris_platform_sm8550.o \ -+ iris_probe.o \ -+ -+obj-$(CONFIG_VIDEO_QCOM_IRIS) += iris.o -diff --git a/drivers/media/platform/qcom/iris/iris_core.h b/drivers/media/platform/qcom/iris/iris_core.h -new file mode 100644 -index 000000000000..27bc2ca71e1b ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_core.h -@@ -0,0 +1,54 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#ifndef __IRIS_CORE_H__ -+#define __IRIS_CORE_H__ -+ -+#include -+#include -+ -+#include "iris_platform_common.h" -+ -+struct icc_info { -+ const char *name; -+ u32 bw_min_kbps; -+ u32 bw_max_kbps; -+}; -+ -+/** -+ * struct iris_core - holds core parameters valid for all instances -+ * -+ * @dev: reference to device structure -+ * @reg_base: IO memory base address -+ * @irq: iris irq -+ * @v4l2_dev: a holder for v4l2 device structure -+ * @vdev_dec: iris video device structure for decoder -+ * @icc_tbl: table of iris interconnects -+ * @icc_count: count of iris interconnects -+ * @pmdomain_tbl: table of iris power domains -+ * @opp_pmdomain_tbl: table of opp power domains -+ * @clock_tbl: table of iris clocks -+ * @clk_count: count of iris clocks -+ * @resets: table of iris reset clocks -+ * @iris_platform_data: a structure for platform data -+ */ -+ -+struct iris_core { -+ struct device *dev; -+ void __iomem *reg_base; -+ int irq; -+ struct v4l2_device v4l2_dev; -+ struct video_device *vdev_dec; -+ struct icc_bulk_data *icc_tbl; -+ u32 icc_count; -+ struct dev_pm_domain_list *pmdomain_tbl; -+ struct dev_pm_domain_list *opp_pmdomain_tbl; -+ struct clk_bulk_data *clock_tbl; -+ u32 clk_count; -+ struct reset_control_bulk_data *resets; -+ const struct iris_platform_data *iris_platform_data; -+}; -+ -+#endif -diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h -new file mode 100644 -index 000000000000..31c53dad8136 ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h -@@ -0,0 +1,35 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#ifndef __IRIS_PLATFORM_COMMON_H__ -+#define __IRIS_PLATFORM_COMMON_H__ -+ -+extern struct iris_platform_data sm8550_data; -+ -+enum platform_clk_type { -+ IRIS_AXI_CLK, -+ IRIS_CTRL_CLK, -+ IRIS_HW_CLK, -+}; -+ -+struct platform_clk_data { -+ enum platform_clk_type clk_type; -+ const char *clk_name; -+}; -+ -+struct iris_platform_data { -+ const struct icc_info *icc_tbl; -+ unsigned int icc_tbl_size; -+ const char * const *pmdomain_tbl; -+ unsigned int pmdomain_tbl_size; -+ const char * const *opp_pd_tbl; -+ unsigned int opp_pd_tbl_size; -+ const struct platform_clk_data *clk_tbl; -+ unsigned int clk_tbl_size; -+ const char * const *clk_rst_tbl; -+ unsigned int clk_rst_tbl_size; -+}; -+ -+#endif -diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c -new file mode 100644 -index 000000000000..3dd91523d783 ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c -@@ -0,0 +1,37 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#include "iris_core.h" -+#include "iris_platform_common.h" -+ -+static const struct icc_info sm8550_icc_table[] = { -+ { "cpu-cfg", 1000, 1000 }, -+ { "video-mem", 1000, 15000000 }, -+}; -+ -+static const char * const sm8550_clk_reset_table[] = { "bus" }; -+ -+static const char * const sm8550_pmdomain_table[] = { "venus", "vcodec0" }; -+ -+static const char * const sm8550_opp_pd_table[] = { "mxc", "mmcx" }; -+ -+static const struct platform_clk_data sm8550_clk_table[] = { -+ {IRIS_AXI_CLK, "iface" }, -+ {IRIS_CTRL_CLK, "core" }, -+ {IRIS_HW_CLK, "vcodec0_core" }, -+}; -+ -+struct iris_platform_data sm8550_data = { -+ .icc_tbl = sm8550_icc_table, -+ .icc_tbl_size = ARRAY_SIZE(sm8550_icc_table), -+ .clk_rst_tbl = sm8550_clk_reset_table, -+ .clk_rst_tbl_size = ARRAY_SIZE(sm8550_clk_reset_table), -+ .pmdomain_tbl = sm8550_pmdomain_table, -+ .pmdomain_tbl_size = ARRAY_SIZE(sm8550_pmdomain_table), -+ .opp_pd_tbl = sm8550_opp_pd_table, -+ .opp_pd_tbl_size = ARRAY_SIZE(sm8550_opp_pd_table), -+ .clk_tbl = sm8550_clk_table, -+ .clk_tbl_size = ARRAY_SIZE(sm8550_clk_table), -+}; -diff --git a/drivers/media/platform/qcom/iris/iris_probe.c b/drivers/media/platform/qcom/iris/iris_probe.c -new file mode 100644 -index 000000000000..911e3bc1b434 ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_probe.c -@@ -0,0 +1,237 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "iris_core.h" -+ -+static int iris_init_icc(struct iris_core *core) -+{ -+ const struct icc_info *icc_tbl; -+ u32 i = 0; -+ -+ icc_tbl = core->iris_platform_data->icc_tbl; -+ -+ core->icc_count = core->iris_platform_data->icc_tbl_size; -+ core->icc_tbl = devm_kzalloc(core->dev, -+ sizeof(struct icc_bulk_data) * core->icc_count, -+ GFP_KERNEL); -+ if (!core->icc_tbl) -+ return -ENOMEM; -+ -+ for (i = 0; i < core->icc_count; i++) { -+ core->icc_tbl[i].name = icc_tbl[i].name; -+ core->icc_tbl[i].avg_bw = icc_tbl[i].bw_min_kbps; -+ core->icc_tbl[i].peak_bw = 0; -+ } -+ -+ return devm_of_icc_bulk_get(core->dev, core->icc_count, core->icc_tbl); -+} -+ -+static int iris_init_power_domains(struct iris_core *core) -+{ -+ const struct platform_clk_data *clk_tbl; -+ u32 clk_cnt, i; -+ int ret; -+ -+ struct dev_pm_domain_attach_data iris_pd_data = { -+ .pd_names = core->iris_platform_data->pmdomain_tbl, -+ .num_pd_names = core->iris_platform_data->pmdomain_tbl_size, -+ .pd_flags = PD_FLAG_NO_DEV_LINK, -+ }; -+ -+ struct dev_pm_domain_attach_data iris_opp_pd_data = { -+ .pd_names = core->iris_platform_data->opp_pd_tbl, -+ .num_pd_names = core->iris_platform_data->opp_pd_tbl_size, -+ .pd_flags = PD_FLAG_DEV_LINK_ON, -+ }; -+ -+ ret = devm_pm_domain_attach_list(core->dev, &iris_pd_data, &core->pmdomain_tbl); -+ if (ret < 0) -+ return ret; -+ -+ ret = devm_pm_domain_attach_list(core->dev, &iris_opp_pd_data, &core->opp_pmdomain_tbl); -+ if (ret < 0) -+ return ret; -+ -+ clk_tbl = core->iris_platform_data->clk_tbl; -+ clk_cnt = core->iris_platform_data->clk_tbl_size; -+ -+ for (i = 0; i < clk_cnt; i++) { -+ if (clk_tbl[i].clk_type == IRIS_HW_CLK) { -+ ret = devm_pm_opp_set_clkname(core->dev, clk_tbl[i].clk_name); -+ if (ret) -+ return ret; -+ } -+ } -+ -+ return devm_pm_opp_of_add_table(core->dev); -+} -+ -+static int iris_init_clocks(struct iris_core *core) -+{ -+ int ret; -+ -+ ret = devm_clk_bulk_get_all(core->dev, &core->clock_tbl); -+ if (ret < 0) -+ return ret; -+ -+ core->clk_count = ret; -+ -+ return 0; -+} -+ -+static int iris_init_resets(struct iris_core *core) -+{ -+ const char * const *rst_tbl; -+ u32 rst_tbl_size; -+ u32 i = 0; -+ -+ rst_tbl = core->iris_platform_data->clk_rst_tbl; -+ rst_tbl_size = core->iris_platform_data->clk_rst_tbl_size; -+ -+ core->resets = devm_kzalloc(core->dev, -+ sizeof(*core->resets) * rst_tbl_size, -+ GFP_KERNEL); -+ if (!core->resets) -+ return -ENOMEM; -+ -+ for (i = 0; i < rst_tbl_size; i++) -+ core->resets[i].id = rst_tbl[i]; -+ -+ return devm_reset_control_bulk_get_exclusive(core->dev, rst_tbl_size, core->resets); -+} -+ -+static int iris_init_resources(struct iris_core *core) -+{ -+ int ret; -+ -+ ret = iris_init_icc(core); -+ if (ret) -+ return ret; -+ -+ ret = iris_init_power_domains(core); -+ if (ret) -+ return ret; -+ -+ ret = iris_init_clocks(core); -+ if (ret) -+ return ret; -+ -+ return iris_init_resets(core); -+} -+ -+static int iris_register_video_device(struct iris_core *core) -+{ -+ struct video_device *vdev; -+ int ret; -+ -+ vdev = video_device_alloc(); -+ if (!vdev) -+ return -ENOMEM; -+ -+ strscpy(vdev->name, "qcom-iris-decoder", sizeof(vdev->name)); -+ vdev->release = video_device_release; -+ vdev->vfl_dir = VFL_DIR_M2M; -+ vdev->v4l2_dev = &core->v4l2_dev; -+ vdev->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING; -+ -+ ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1); -+ if (ret) -+ goto err_vdev_release; -+ -+ core->vdev_dec = vdev; -+ video_set_drvdata(vdev, core); -+ -+ return 0; -+ -+err_vdev_release: -+ video_device_release(vdev); -+ -+ return ret; -+} -+ -+static void iris_remove(struct platform_device *pdev) -+{ -+ struct iris_core *core; -+ -+ core = platform_get_drvdata(pdev); -+ if (!core) -+ return; -+ -+ video_unregister_device(core->vdev_dec); -+ -+ v4l2_device_unregister(&core->v4l2_dev); -+} -+ -+static int iris_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct iris_core *core; -+ int ret; -+ -+ core = devm_kzalloc(&pdev->dev, sizeof(*core), GFP_KERNEL); -+ if (!core) -+ return -ENOMEM; -+ core->dev = dev; -+ -+ core->reg_base = devm_platform_ioremap_resource(pdev, 0); -+ if (IS_ERR(core->reg_base)) -+ return PTR_ERR(core->reg_base); -+ -+ core->irq = platform_get_irq(pdev, 0); -+ if (core->irq < 0) -+ return core->irq; -+ -+ core->iris_platform_data = of_device_get_match_data(core->dev); -+ -+ ret = iris_init_resources(core); -+ if (ret) -+ return ret; -+ -+ ret = v4l2_device_register(dev, &core->v4l2_dev); -+ if (ret) -+ return ret; -+ -+ ret = iris_register_video_device(core); -+ if (ret) -+ goto err_v4l2_unreg; -+ -+ platform_set_drvdata(pdev, core); -+ -+ return 0; -+ -+err_v4l2_unreg: -+ v4l2_device_unregister(&core->v4l2_dev); -+ -+ return ret; -+} -+ -+static const struct of_device_id iris_dt_match[] = { -+ { -+ .compatible = "qcom,sm8550-iris", -+ .data = &sm8550_data, -+ }, -+ { }, -+}; -+MODULE_DEVICE_TABLE(of, iris_dt_match); -+ -+static struct platform_driver qcom_iris_driver = { -+ .probe = iris_probe, -+ .remove = iris_remove, -+ .driver = { -+ .name = "qcom-iris", -+ .of_match_table = iris_dt_match, -+ }, -+}; -+ -+module_platform_driver(qcom_iris_driver); -+MODULE_DESCRIPTION("Qualcomm iris video driver"); -+MODULE_LICENSE("GPL"); --- -2.34.1 - diff --git a/patch/kernel/archive/sm8550-6.12/0003_media--iris--implement-iris-v4l2-file-ops.patch b/patch/kernel/archive/sm8550-6.12/0003_media--iris--implement-iris-v4l2-file-ops.patch deleted file mode 100644 index 36dee97e6a73..000000000000 --- a/patch/kernel/archive/sm8550-6.12/0003_media--iris--implement-iris-v4l2-file-ops.patch +++ /dev/null @@ -1,450 +0,0 @@ -From abaac8cb912c2c187c6c049012af5029d5ed3b38 Mon Sep 17 00:00:00 2001 -From: Dikshita Agarwal -Date: Fri, 7 Feb 2025 13:24:43 +0530 -Subject: [PATCH] media: iris: implement iris v4l2 file ops - -Implement open, close and poll ops. - -Open: -Configure the vb2 queue and v4l2 file handler. Allocate a video instance -and add the instance to core instance list. - -Close: -Free the instance and remove it from core instance list. - -Poll: -Wait for an event on vb2 src and vb2 dst queues. - -Reviewed-by: Bryan O'Donoghue -Reviewed-by: Hans Verkuil -Tested-by: Stefan Schmidt # x1e80100 (Dell XPS 13 9345) -Reviewed-by: Stefan Schmidt -Tested-by: Neil Armstrong # on SM8550-QRD -Tested-by: Neil Armstrong # on SM8550-HDK -Signed-off-by: Dikshita Agarwal -Link: https://lore.kernel.org/r/20250207-qcom-video-iris-v10-3-ab66eeffbd20@quicinc.com -Signed-off-by: Neil Armstrong ---- - drivers/media/platform/qcom/iris/Kconfig | 1 + - drivers/media/platform/qcom/iris/Makefile | 5 +- - drivers/media/platform/qcom/iris/iris_core.h | 2 + - .../media/platform/qcom/iris/iris_hfi_gen1.h | 13 ++ - .../qcom/iris/iris_hfi_gen1_command.c | 12 ++ - .../media/platform/qcom/iris/iris_hfi_gen2.h | 22 +++ - .../qcom/iris/iris_hfi_gen2_command.c | 11 ++ - .../media/platform/qcom/iris/iris_instance.h | 31 ++++ - .../platform/qcom/iris/iris_platform_common.h | 1 + - .../platform/qcom/iris/iris_platform_sm8550.c | 2 + - drivers/media/platform/qcom/iris/iris_probe.c | 3 + - drivers/media/platform/qcom/iris/iris_vidc.c | 147 ++++++++++++++++++ - drivers/media/platform/qcom/iris/iris_vidc.h | 15 ++ - 13 files changed, 264 insertions(+), 1 deletion(-) - create mode 100644 drivers/media/platform/qcom/iris/iris_hfi_gen1.h - create mode 100644 drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c - create mode 100644 drivers/media/platform/qcom/iris/iris_hfi_gen2.h - create mode 100644 drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c - create mode 100644 drivers/media/platform/qcom/iris/iris_instance.h - create mode 100644 drivers/media/platform/qcom/iris/iris_vidc.c - create mode 100644 drivers/media/platform/qcom/iris/iris_vidc.h - -diff --git a/drivers/media/platform/qcom/iris/Kconfig b/drivers/media/platform/qcom/iris/Kconfig -index 34a2f81c5db3..8debddec87a5 100644 ---- a/drivers/media/platform/qcom/iris/Kconfig -+++ b/drivers/media/platform/qcom/iris/Kconfig -@@ -2,6 +2,7 @@ config VIDEO_QCOM_IRIS - tristate "Qualcomm iris V4L2 decoder driver" - depends on VIDEO_DEV - depends on ARCH_QCOM || COMPILE_TEST -+ select V4L2_MEM2MEM_DEV - help - This is a V4L2 driver for Qualcomm iris video accelerator - hardware. It accelerates decoding operations on various -diff --git a/drivers/media/platform/qcom/iris/Makefile b/drivers/media/platform/qcom/iris/Makefile -index 7e701361492e..6de584090a3a 100644 ---- a/drivers/media/platform/qcom/iris/Makefile -+++ b/drivers/media/platform/qcom/iris/Makefile -@@ -1,4 +1,7 @@ --iris-objs += iris_platform_sm8550.o \ -+iris-objs += iris_hfi_gen1_command.o \ -+ iris_hfi_gen2_command.o \ -+ iris_platform_sm8550.o \ - iris_probe.o \ -+ iris_vidc.o \ - - obj-$(CONFIG_VIDEO_QCOM_IRIS) += iris.o -diff --git a/drivers/media/platform/qcom/iris/iris_core.h b/drivers/media/platform/qcom/iris/iris_core.h -index 27bc2ca71e1b..aebb4eba7e15 100644 ---- a/drivers/media/platform/qcom/iris/iris_core.h -+++ b/drivers/media/platform/qcom/iris/iris_core.h -@@ -25,6 +25,7 @@ struct icc_info { - * @irq: iris irq - * @v4l2_dev: a holder for v4l2 device structure - * @vdev_dec: iris video device structure for decoder -+ * @iris_v4l2_file_ops: iris v4l2 file ops - * @icc_tbl: table of iris interconnects - * @icc_count: count of iris interconnects - * @pmdomain_tbl: table of iris power domains -@@ -41,6 +42,7 @@ struct iris_core { - int irq; - struct v4l2_device v4l2_dev; - struct video_device *vdev_dec; -+ const struct v4l2_file_operations *iris_v4l2_file_ops; - struct icc_bulk_data *icc_tbl; - u32 icc_count; - struct dev_pm_domain_list *pmdomain_tbl; -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1.h b/drivers/media/platform/qcom/iris/iris_hfi_gen1.h -new file mode 100644 -index 000000000000..5d05be7470e0 ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1.h -@@ -0,0 +1,13 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#ifndef __IRIS_HFI_GEN1_H__ -+#define __IRIS_HFI_GEN1_H__ -+ -+struct iris_inst; -+ -+struct iris_inst *iris_hfi_gen1_get_instance(void); -+ -+#endif -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c -new file mode 100644 -index 000000000000..20c68f4ffb72 ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c -@@ -0,0 +1,12 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#include "iris_hfi_gen1.h" -+#include "iris_instance.h" -+ -+struct iris_inst *iris_hfi_gen1_get_instance(void) -+{ -+ return kzalloc(sizeof(struct iris_inst), GFP_KERNEL); -+} -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2.h b/drivers/media/platform/qcom/iris/iris_hfi_gen2.h -new file mode 100644 -index 000000000000..c159ed7f64f9 ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2.h -@@ -0,0 +1,22 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#ifndef __IRIS_HFI_GEN2_H__ -+#define __IRIS_HFI_GEN2_H__ -+ -+#include "iris_instance.h" -+ -+/** -+ * struct iris_inst_hfi_gen2 - holds per video instance parameters for hfi_gen2 -+ * -+ * @inst: pointer to iris_instance structure -+ */ -+struct iris_inst_hfi_gen2 { -+ struct iris_inst inst; -+}; -+ -+struct iris_inst *iris_hfi_gen2_get_instance(void); -+ -+#endif -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c -new file mode 100644 -index 000000000000..3ee33c8befae ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c -@@ -0,0 +1,11 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#include "iris_hfi_gen2.h" -+ -+struct iris_inst *iris_hfi_gen2_get_instance(void) -+{ -+ return kzalloc(sizeof(struct iris_inst_hfi_gen2), GFP_KERNEL); -+} -diff --git a/drivers/media/platform/qcom/iris/iris_instance.h b/drivers/media/platform/qcom/iris/iris_instance.h -new file mode 100644 -index 000000000000..527a270f12d4 ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_instance.h -@@ -0,0 +1,31 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#ifndef __IRIS_INSTANCE_H__ -+#define __IRIS_INSTANCE_H__ -+ -+#include "iris_core.h" -+ -+/** -+ * struct iris_inst - holds per video instance parameters -+ * -+ * @core: pointer to core structure -+ * @ctx_q_lock: lock to serialize queues related ioctls -+ * @lock: lock to seralise forward and reverse threads -+ * @fh: reference of v4l2 file handler -+ * @m2m_dev: a reference to m2m device structure -+ * @m2m_ctx: a reference to m2m context structure -+ */ -+ -+struct iris_inst { -+ struct iris_core *core; -+ struct mutex ctx_q_lock;/* lock to serialize queues related ioctls */ -+ struct mutex lock; /* lock to serialize forward and reverse threads */ -+ struct v4l2_fh fh; -+ struct v4l2_m2m_dev *m2m_dev; -+ struct v4l2_m2m_ctx *m2m_ctx; -+}; -+ -+#endif -diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h -index 31c53dad8136..f82081ea135f 100644 ---- a/drivers/media/platform/qcom/iris/iris_platform_common.h -+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h -@@ -20,6 +20,7 @@ struct platform_clk_data { - }; - - struct iris_platform_data { -+ struct iris_inst *(*get_instance)(void); - const struct icc_info *icc_tbl; - unsigned int icc_tbl_size; - const char * const *pmdomain_tbl; -diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c -index 3dd91523d783..dba8d3c22ce5 100644 ---- a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c -+++ b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c -@@ -4,6 +4,7 @@ - */ - - #include "iris_core.h" -+#include "iris_hfi_gen2.h" - #include "iris_platform_common.h" - - static const struct icc_info sm8550_icc_table[] = { -@@ -24,6 +25,7 @@ static const struct platform_clk_data sm8550_clk_table[] = { - }; - - struct iris_platform_data sm8550_data = { -+ .get_instance = iris_hfi_gen2_get_instance, - .icc_tbl = sm8550_icc_table, - .icc_tbl_size = ARRAY_SIZE(sm8550_icc_table), - .clk_rst_tbl = sm8550_clk_reset_table, -diff --git a/drivers/media/platform/qcom/iris/iris_probe.c b/drivers/media/platform/qcom/iris/iris_probe.c -index 911e3bc1b434..ce16d894c809 100644 ---- a/drivers/media/platform/qcom/iris/iris_probe.c -+++ b/drivers/media/platform/qcom/iris/iris_probe.c -@@ -11,6 +11,7 @@ - #include - - #include "iris_core.h" -+#include "iris_vidc.h" - - static int iris_init_icc(struct iris_core *core) - { -@@ -139,6 +140,7 @@ static int iris_register_video_device(struct iris_core *core) - - strscpy(vdev->name, "qcom-iris-decoder", sizeof(vdev->name)); - vdev->release = video_device_release; -+ vdev->fops = core->iris_v4l2_file_ops; - vdev->vfl_dir = VFL_DIR_M2M; - vdev->v4l2_dev = &core->v4l2_dev; - vdev->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING; -@@ -192,6 +194,7 @@ static int iris_probe(struct platform_device *pdev) - - core->iris_platform_data = of_device_get_match_data(core->dev); - -+ iris_init_ops(core); - ret = iris_init_resources(core); - if (ret) - return ret; -diff --git a/drivers/media/platform/qcom/iris/iris_vidc.c b/drivers/media/platform/qcom/iris/iris_vidc.c -new file mode 100644 -index 000000000000..e91d661c6280 ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_vidc.c -@@ -0,0 +1,147 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#include -+#include -+ -+#include "iris_vidc.h" -+#include "iris_instance.h" -+#include "iris_platform_common.h" -+ -+#define IRIS_DRV_NAME "iris_driver" -+#define IRIS_BUS_NAME "platform:iris_icc" -+#define STEP_WIDTH 1 -+#define STEP_HEIGHT 1 -+ -+static void iris_v4l2_fh_init(struct iris_inst *inst) -+{ -+ v4l2_fh_init(&inst->fh, inst->core->vdev_dec); -+ v4l2_fh_add(&inst->fh); -+} -+ -+static void iris_v4l2_fh_deinit(struct iris_inst *inst) -+{ -+ v4l2_fh_del(&inst->fh); -+ v4l2_fh_exit(&inst->fh); -+} -+ -+static inline struct iris_inst *iris_get_inst(struct file *filp, void *fh) -+{ -+ return container_of(filp->private_data, struct iris_inst, fh); -+} -+ -+static void iris_m2m_device_run(void *priv) -+{ -+} -+ -+static void iris_m2m_job_abort(void *priv) -+{ -+ struct iris_inst *inst = priv; -+ struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; -+ -+ v4l2_m2m_job_finish(inst->m2m_dev, m2m_ctx); -+} -+ -+static const struct v4l2_m2m_ops iris_m2m_ops = { -+ .device_run = iris_m2m_device_run, -+ .job_abort = iris_m2m_job_abort, -+}; -+ -+static int -+iris_m2m_queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq) -+{ -+ struct iris_inst *inst = priv; -+ int ret; -+ -+ src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; -+ src_vq->io_modes = VB2_MMAP | VB2_DMABUF; -+ src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; -+ src_vq->drv_priv = inst; -+ src_vq->dev = inst->core->dev; -+ src_vq->lock = &inst->ctx_q_lock; -+ ret = vb2_queue_init(src_vq); -+ if (ret) -+ return ret; -+ -+ dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; -+ dst_vq->io_modes = VB2_MMAP | VB2_DMABUF; -+ dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; -+ dst_vq->drv_priv = inst; -+ dst_vq->dev = inst->core->dev; -+ dst_vq->lock = &inst->ctx_q_lock; -+ -+ return vb2_queue_init(dst_vq); -+} -+ -+int iris_open(struct file *filp) -+{ -+ struct iris_core *core = video_drvdata(filp); -+ struct iris_inst *inst; -+ int ret; -+ -+ inst = core->iris_platform_data->get_instance(); -+ if (!inst) -+ return -ENOMEM; -+ -+ inst->core = core; -+ -+ mutex_init(&inst->ctx_q_lock); -+ -+ iris_v4l2_fh_init(inst); -+ -+ inst->m2m_dev = v4l2_m2m_init(&iris_m2m_ops); -+ if (IS_ERR_OR_NULL(inst->m2m_dev)) { -+ ret = -EINVAL; -+ goto fail_v4l2_fh_deinit; -+ } -+ -+ inst->m2m_ctx = v4l2_m2m_ctx_init(inst->m2m_dev, inst, iris_m2m_queue_init); -+ if (IS_ERR_OR_NULL(inst->m2m_ctx)) { -+ ret = -EINVAL; -+ goto fail_m2m_release; -+ } -+ -+ inst->fh.m2m_ctx = inst->m2m_ctx; -+ filp->private_data = &inst->fh; -+ -+ return 0; -+ -+fail_m2m_release: -+ v4l2_m2m_release(inst->m2m_dev); -+fail_v4l2_fh_deinit: -+ iris_v4l2_fh_deinit(inst); -+ mutex_destroy(&inst->ctx_q_lock); -+ kfree(inst); -+ -+ return ret; -+} -+ -+int iris_close(struct file *filp) -+{ -+ struct iris_inst *inst = iris_get_inst(filp, NULL); -+ -+ v4l2_m2m_ctx_release(inst->m2m_ctx); -+ v4l2_m2m_release(inst->m2m_dev); -+ iris_v4l2_fh_deinit(inst); -+ mutex_destroy(&inst->ctx_q_lock); -+ kfree(inst); -+ filp->private_data = NULL; -+ -+ return 0; -+} -+ -+static struct v4l2_file_operations iris_v4l2_file_ops = { -+ .owner = THIS_MODULE, -+ .open = iris_open, -+ .release = iris_close, -+ .unlocked_ioctl = video_ioctl2, -+ .poll = v4l2_m2m_fop_poll, -+ .mmap = v4l2_m2m_fop_mmap, -+}; -+ -+void iris_init_ops(struct iris_core *core) -+{ -+ core->iris_v4l2_file_ops = &iris_v4l2_file_ops; -+} -diff --git a/drivers/media/platform/qcom/iris/iris_vidc.h b/drivers/media/platform/qcom/iris/iris_vidc.h -new file mode 100644 -index 000000000000..a26054ff55b5 ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_vidc.h -@@ -0,0 +1,15 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#ifndef __IRIS_VIDC_H__ -+#define __IRIS_VIDC_H__ -+ -+struct iris_core; -+ -+void iris_init_ops(struct iris_core *core); -+int iris_open(struct file *filp); -+int iris_close(struct file *filp); -+ -+#endif --- -2.34.1 - diff --git a/patch/kernel/archive/sm8550-6.12/0004_media--iris--introduce-iris-core-state-management-.patch b/patch/kernel/archive/sm8550-6.12/0004_media--iris--introduce-iris-core-state-management-.patch deleted file mode 100644 index 67d109f52123..000000000000 --- a/patch/kernel/archive/sm8550-6.12/0004_media--iris--introduce-iris-core-state-management-.patch +++ /dev/null @@ -1,636 +0,0 @@ -From 3daede024ad4c5fe44a1bcc4d121385271788d13 Mon Sep 17 00:00:00 2001 -From: Dikshita Agarwal -Date: Fri, 7 Feb 2025 13:24:44 +0530 -Subject: [PATCH] media: iris: introduce iris core state management with shared - queues - -Introduce a core state management for iris driver with the necessary -queues needed for the host firmware communication. - -There are 3 types of queues: -Command queue - driver to write any command to firmware. -Message queue - firmware to send any response to the driver. -Debug queue - for the firmware to write debug messages. -Initialize and configure the shared queues during probe. - -Different states for core: -IRIS_CORE_DEINIT - default state. -IRIS_CORE_INIT - core state with core initialized. FW loaded and HW - brought out of reset, shared queues established - between host driver and firmware. -IRIS_CORE_ERROR - error state. - ----------- - | - V - ----------- - | DEINIT | - ----------- - ^ - / \ - / \ - / \ - / \ - v v - ----------- ----------. - | INIT |-->| ERROR | - ----------- ----------. - -Tested-by: Stefan Schmidt # x1e80100 (Dell XPS 13 9345) -Reviewed-by: Stefan Schmidt -Tested-by: Neil Armstrong # on SM8550-QRD -Tested-by: Neil Armstrong # on SM8550-HDK -Signed-off-by: Dikshita Agarwal -Link: https://lore.kernel.org/r/20250207-qcom-video-iris-v10-4-ab66eeffbd20@quicinc.com -Signed-off-by: Neil Armstrong ---- - drivers/media/platform/qcom/iris/Makefile | 4 +- - drivers/media/platform/qcom/iris/iris_core.c | 46 +++++ - drivers/media/platform/qcom/iris/iris_core.h | 23 +++ - .../media/platform/qcom/iris/iris_hfi_queue.c | 127 +++++++++++++ - .../media/platform/qcom/iris/iris_hfi_queue.h | 177 ++++++++++++++++++ - .../platform/qcom/iris/iris_platform_common.h | 1 + - .../platform/qcom/iris/iris_platform_sm8550.c | 2 + - drivers/media/platform/qcom/iris/iris_probe.c | 19 ++ - drivers/media/platform/qcom/iris/iris_state.h | 41 ++++ - drivers/media/platform/qcom/iris/iris_vidc.c | 6 + - 10 files changed, 445 insertions(+), 1 deletion(-) - create mode 100644 drivers/media/platform/qcom/iris/iris_core.c - create mode 100644 drivers/media/platform/qcom/iris/iris_hfi_queue.c - create mode 100644 drivers/media/platform/qcom/iris/iris_hfi_queue.h - create mode 100644 drivers/media/platform/qcom/iris/iris_state.h - -diff --git a/drivers/media/platform/qcom/iris/Makefile b/drivers/media/platform/qcom/iris/Makefile -index 6de584090a3a..93711f108a77 100644 ---- a/drivers/media/platform/qcom/iris/Makefile -+++ b/drivers/media/platform/qcom/iris/Makefile -@@ -1,5 +1,7 @@ --iris-objs += iris_hfi_gen1_command.o \ -+iris-objs += iris_core.o \ -+ iris_hfi_gen1_command.o \ - iris_hfi_gen2_command.o \ -+ iris_hfi_queue.o \ - iris_platform_sm8550.o \ - iris_probe.o \ - iris_vidc.o \ -diff --git a/drivers/media/platform/qcom/iris/iris_core.c b/drivers/media/platform/qcom/iris/iris_core.c -new file mode 100644 -index 000000000000..360a54909ef6 ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_core.c -@@ -0,0 +1,46 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#include "iris_core.h" -+#include "iris_state.h" -+ -+void iris_core_deinit(struct iris_core *core) -+{ -+ mutex_lock(&core->lock); -+ iris_hfi_queues_deinit(core); -+ core->state = IRIS_CORE_DEINIT; -+ mutex_unlock(&core->lock); -+} -+ -+int iris_core_init(struct iris_core *core) -+{ -+ int ret; -+ -+ mutex_lock(&core->lock); -+ if (core->state == IRIS_CORE_INIT) { -+ ret = 0; -+ goto exit; -+ } else if (core->state == IRIS_CORE_ERROR) { -+ ret = -EINVAL; -+ goto error; -+ } -+ -+ core->state = IRIS_CORE_INIT; -+ -+ ret = iris_hfi_queues_init(core); -+ if (ret) -+ goto error; -+ -+ mutex_unlock(&core->lock); -+ -+ return 0; -+ -+error: -+ core->state = IRIS_CORE_DEINIT; -+exit: -+ mutex_unlock(&core->lock); -+ -+ return ret; -+} -diff --git a/drivers/media/platform/qcom/iris/iris_core.h b/drivers/media/platform/qcom/iris/iris_core.h -index aebb4eba7e15..516082aa58c9 100644 ---- a/drivers/media/platform/qcom/iris/iris_core.h -+++ b/drivers/media/platform/qcom/iris/iris_core.h -@@ -9,7 +9,9 @@ - #include - #include - -+#include "iris_hfi_queue.h" - #include "iris_platform_common.h" -+#include "iris_state.h" - - struct icc_info { - const char *name; -@@ -34,6 +36,15 @@ struct icc_info { - * @clk_count: count of iris clocks - * @resets: table of iris reset clocks - * @iris_platform_data: a structure for platform data -+ * @state: current state of core -+ * @iface_q_table_daddr: device address for interface queue table memory -+ * @sfr_daddr: device address for SFR (Sub System Failure Reason) register memory -+ * @iface_q_table_vaddr: virtual address for interface queue table memory -+ * @sfr_vaddr: virtual address for SFR (Sub System Failure Reason) register memory -+ * @command_queue: shared interface queue to send commands to firmware -+ * @message_queue: shared interface queue to receive responses from firmware -+ * @debug_queue: shared interface queue to receive debug info from firmware -+ * @lock: a lock for this strucure - */ - - struct iris_core { -@@ -51,6 +62,18 @@ struct iris_core { - u32 clk_count; - struct reset_control_bulk_data *resets; - const struct iris_platform_data *iris_platform_data; -+ enum iris_core_state state; -+ dma_addr_t iface_q_table_daddr; -+ dma_addr_t sfr_daddr; -+ void *iface_q_table_vaddr; -+ void *sfr_vaddr; -+ struct iris_iface_q_info command_queue; -+ struct iris_iface_q_info message_queue; -+ struct iris_iface_q_info debug_queue; -+ struct mutex lock; /* lock for core related operations */ - }; - -+int iris_core_init(struct iris_core *core); -+void iris_core_deinit(struct iris_core *core); -+ - #endif -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_queue.c b/drivers/media/platform/qcom/iris/iris_hfi_queue.c -new file mode 100644 -index 000000000000..494ef205133d ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_hfi_queue.c -@@ -0,0 +1,127 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#include "iris_core.h" -+#include "iris_hfi_queue.h" -+ -+static void iris_hfi_queue_set_header(struct iris_core *core, u32 queue_id, -+ struct iris_iface_q_info *iface_q) -+{ -+ iface_q->qhdr->status = 0x1; -+ iface_q->qhdr->start_addr = iface_q->device_addr; -+ iface_q->qhdr->header_type = IFACEQ_DFLT_QHDR; -+ iface_q->qhdr->queue_type = queue_id; -+ iface_q->qhdr->q_size = IFACEQ_QUEUE_SIZE / sizeof(u32); -+ iface_q->qhdr->pkt_size = 0; /* variable packet size */ -+ iface_q->qhdr->rx_wm = 0x1; -+ iface_q->qhdr->tx_wm = 0x1; -+ iface_q->qhdr->rx_req = 0x1; -+ iface_q->qhdr->tx_req = 0x0; -+ iface_q->qhdr->rx_irq_status = 0x0; -+ iface_q->qhdr->tx_irq_status = 0x0; -+ iface_q->qhdr->read_idx = 0x0; -+ iface_q->qhdr->write_idx = 0x0; -+ -+ /* -+ * Set receive request to zero on debug queue as there is no -+ * need of interrupt from video hardware for debug messages -+ */ -+ if (queue_id == IFACEQ_DBGQ_ID) -+ iface_q->qhdr->rx_req = 0; -+} -+ -+static void -+iris_hfi_queue_init(struct iris_core *core, u32 queue_id, struct iris_iface_q_info *iface_q) -+{ -+ struct iris_hfi_queue_table_header *q_tbl_hdr = core->iface_q_table_vaddr; -+ u32 offset = sizeof(*q_tbl_hdr) + (queue_id * IFACEQ_QUEUE_SIZE); -+ -+ iface_q->device_addr = core->iface_q_table_daddr + offset; -+ iface_q->kernel_vaddr = -+ (void *)((char *)core->iface_q_table_vaddr + offset); -+ iface_q->qhdr = &q_tbl_hdr->q_hdr[queue_id]; -+ -+ iris_hfi_queue_set_header(core, queue_id, iface_q); -+} -+ -+static void iris_hfi_queue_deinit(struct iris_iface_q_info *iface_q) -+{ -+ iface_q->qhdr = NULL; -+ iface_q->kernel_vaddr = NULL; -+ iface_q->device_addr = 0; -+} -+ -+int iris_hfi_queues_init(struct iris_core *core) -+{ -+ struct iris_hfi_queue_table_header *q_tbl_hdr; -+ u32 queue_size; -+ -+ /* Iris hardware requires 4K queue alignment */ -+ queue_size = ALIGN((sizeof(*q_tbl_hdr) + (IFACEQ_QUEUE_SIZE * IFACEQ_NUMQ)), SZ_4K); -+ core->iface_q_table_vaddr = dma_alloc_attrs(core->dev, queue_size, -+ &core->iface_q_table_daddr, -+ GFP_KERNEL, DMA_ATTR_WRITE_COMBINE); -+ if (!core->iface_q_table_vaddr) { -+ dev_err(core->dev, "queues alloc and map failed\n"); -+ return -ENOMEM; -+ } -+ -+ core->sfr_vaddr = dma_alloc_attrs(core->dev, SFR_SIZE, -+ &core->sfr_daddr, -+ GFP_KERNEL, DMA_ATTR_WRITE_COMBINE); -+ if (!core->sfr_vaddr) { -+ dev_err(core->dev, "sfr alloc and map failed\n"); -+ dma_free_attrs(core->dev, sizeof(*q_tbl_hdr), core->iface_q_table_vaddr, -+ core->iface_q_table_daddr, DMA_ATTR_WRITE_COMBINE); -+ return -ENOMEM; -+ } -+ -+ iris_hfi_queue_init(core, IFACEQ_CMDQ_ID, &core->command_queue); -+ iris_hfi_queue_init(core, IFACEQ_MSGQ_ID, &core->message_queue); -+ iris_hfi_queue_init(core, IFACEQ_DBGQ_ID, &core->debug_queue); -+ -+ q_tbl_hdr = (struct iris_hfi_queue_table_header *)core->iface_q_table_vaddr; -+ q_tbl_hdr->version = 0; -+ q_tbl_hdr->device_addr = (void *)core; -+ strscpy(q_tbl_hdr->name, "iris-hfi-queues", sizeof(q_tbl_hdr->name)); -+ q_tbl_hdr->size = sizeof(*q_tbl_hdr); -+ q_tbl_hdr->qhdr0_offset = sizeof(*q_tbl_hdr) - -+ (IFACEQ_NUMQ * sizeof(struct iris_hfi_queue_header)); -+ q_tbl_hdr->qhdr_size = sizeof(q_tbl_hdr->q_hdr[0]); -+ q_tbl_hdr->num_q = IFACEQ_NUMQ; -+ q_tbl_hdr->num_active_q = IFACEQ_NUMQ; -+ -+ /* Write sfr size in first word to be used by firmware */ -+ *((u32 *)core->sfr_vaddr) = SFR_SIZE; -+ -+ return 0; -+} -+ -+void iris_hfi_queues_deinit(struct iris_core *core) -+{ -+ u32 queue_size; -+ -+ if (!core->iface_q_table_vaddr) -+ return; -+ -+ iris_hfi_queue_deinit(&core->debug_queue); -+ iris_hfi_queue_deinit(&core->message_queue); -+ iris_hfi_queue_deinit(&core->command_queue); -+ -+ dma_free_attrs(core->dev, SFR_SIZE, core->sfr_vaddr, -+ core->sfr_daddr, DMA_ATTR_WRITE_COMBINE); -+ -+ core->sfr_vaddr = NULL; -+ core->sfr_daddr = 0; -+ -+ queue_size = ALIGN(sizeof(struct iris_hfi_queue_table_header) + -+ (IFACEQ_QUEUE_SIZE * IFACEQ_NUMQ), SZ_4K); -+ -+ dma_free_attrs(core->dev, queue_size, core->iface_q_table_vaddr, -+ core->iface_q_table_daddr, DMA_ATTR_WRITE_COMBINE); -+ -+ core->iface_q_table_vaddr = NULL; -+ core->iface_q_table_daddr = 0; -+} -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_queue.h b/drivers/media/platform/qcom/iris/iris_hfi_queue.h -new file mode 100644 -index 000000000000..99a3b83d063f ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_hfi_queue.h -@@ -0,0 +1,177 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#ifndef __IRIS_HFI_QUEUE_H__ -+#define __IRIS_HFI_QUEUE_H__ -+ -+struct iris_core; -+ -+/* -+ * Max 64 Buffers ( 32 input buffers and 32 output buffers) -+ * can be queued by v4l2 framework at any given time. -+ */ -+#define IFACEQ_MAX_BUF_COUNT 64 -+/* -+ * Max session supported are 16. -+ * this value is used to calcualte the size of -+ * individual shared queue. -+ */ -+#define IFACE_MAX_PARALLEL_SESSIONS 16 -+#define IFACEQ_DFLT_QHDR 0x0101 -+#define IFACEQ_MAX_PKT_SIZE 1024 /* Maximum size of a packet in the queue */ -+ -+/* -+ * SFR: Subsystem Failure Reason -+ * when hardware goes into bad state/failure, firmware fills this memory -+ * and driver will get to know the actual failure reason from this SFR buffer. -+ */ -+#define SFR_SIZE SZ_4K /* Iris hardware requires 4K queue alignment */ -+ -+#define IFACEQ_QUEUE_SIZE (IFACEQ_MAX_PKT_SIZE * \ -+ IFACEQ_MAX_BUF_COUNT * IFACE_MAX_PARALLEL_SESSIONS) -+ -+/* -+ * Memory layout of the shared queues: -+ * -+ * ||=================|| ^ ^ ^ -+ * || || | | | -+ * || Queue Table || 288 Bytes | | -+ * || Header || | | | -+ * || || | | | -+ * ||-----------------|| V | | -+ * ||-----------------|| ^ | | -+ * || || | | | -+ * || Command Queue || 56 Bytes | | -+ * || Header || | | | -+ * || || | | | -+ * ||-----------------|| V 456 Bytes | -+ * ||-----------------|| ^ | | -+ * || || | | | -+ * || Message Queue || 56 Bytes | | -+ * || Header || | | | -+ * || || | | | -+ * ||-----------------|| V | Buffer size aligned to 4k -+ * ||-----------------|| ^ | Overall Queue Size = 2,404 KB -+ * || || | | | -+ * || Debug Queue || 56 Bytes | | -+ * || Header || | | | -+ * || || | | | -+ * ||=================|| V V | -+ * ||=================|| ^ | -+ * || || | | -+ * || Command || 800 KB | -+ * || Queue || | | -+ * || || | | -+ * ||=================|| V | -+ * ||=================|| ^ | -+ * || || | | -+ * || Message || 800 KB | -+ * || Queue || | | -+ * || || | | -+ * ||=================|| V | -+ * ||=================|| ^ | -+ * || || | | -+ * || Debug || 800 KB | -+ * || Queue || | | -+ * || || | | -+ * ||=================|| V | -+ * || || | -+ * ||=================|| V -+ */ -+ -+/* -+ * Shared queues are used for communication between driver and firmware. -+ * There are 3 types of queues: -+ * Command queue - driver to write any command to firmware. -+ * Message queue - firmware to send any response to driver. -+ * Debug queue - firmware to write debug message. -+ */ -+ -+/* Host-firmware shared queue ids */ -+enum iris_iface_queue { -+ IFACEQ_CMDQ_ID, -+ IFACEQ_MSGQ_ID, -+ IFACEQ_DBGQ_ID, -+ IFACEQ_NUMQ, /* not an index */ -+}; -+ -+/** -+ * struct iris_hfi_queue_header -+ * -+ * @status: Queue status, bits (7:0), 0x1 - active, 0x0 - inactive -+ * @start_addr: Queue start address in non cached memory -+ * @queue_type: Queue ID -+ * @header_type: Default queue header -+ * @q_size: Queue size -+ * Number of queue packets if pkt_size is non-zero -+ * Queue size in bytes if pkt_size is zero -+ * @pkt_size: Size of queue packet entries -+ * 0x0: variable queue packet size -+ * non zero: size of queue packet entry, fixed -+ * @pkt_drop_cnt: Number of packets dropped by sender -+ * @rx_wm: Receiver watermark, applicable in event driven mode -+ * @tx_wm: Sender watermark, applicable in event driven mode -+ * @rx_req: Receiver sets this bit if queue is empty -+ * @tx_req: Sender sets this bit if queue is full -+ * @rx_irq_status: Receiver sets this bit and triggers an interrupt to -+ * the sender after packets are dequeued. Sender clears this bit -+ * @tx_irq_status: Sender sets this bit and triggers an interrupt to -+ * the receiver after packets are queued. Receiver clears this bit -+ * @read_idx: Index till where receiver has consumed the packets from the queue. -+ * @write_idx: Index till where sender has written the packets into the queue. -+ */ -+struct iris_hfi_queue_header { -+ u32 status; -+ u32 start_addr; -+ u16 queue_type; -+ u16 header_type; -+ u32 q_size; -+ u32 pkt_size; -+ u32 pkt_drop_cnt; -+ u32 rx_wm; -+ u32 tx_wm; -+ u32 rx_req; -+ u32 tx_req; -+ u32 rx_irq_status; -+ u32 tx_irq_status; -+ u32 read_idx; -+ u32 write_idx; -+}; -+ -+/** -+ * struct iris_hfi_queue_table_header -+ * -+ * @version: Queue table version number -+ * @size: Queue table size from version to last parametr in qhdr entry -+ * @qhdr0_offset: Offset to the start of first qhdr -+ * @qhdr_size: Queue header size in bytes -+ * @num_q: Total number of queues in Queue table -+ * @num_active_q: Total number of active queues -+ * @device_addr: Device address of the queue -+ * @name: Queue name in characters -+ * @q_hdr: Array of queue headers -+ */ -+struct iris_hfi_queue_table_header { -+ u32 version; -+ u32 size; -+ u32 qhdr0_offset; -+ u32 qhdr_size; -+ u32 num_q; -+ u32 num_active_q; -+ void *device_addr; -+ char name[256]; /* NUL-terminated array of characters */ -+ struct iris_hfi_queue_header q_hdr[IFACEQ_NUMQ]; -+}; -+ -+struct iris_iface_q_info { -+ struct iris_hfi_queue_header *qhdr; -+ dma_addr_t device_addr; -+ void *kernel_vaddr; -+}; -+ -+int iris_hfi_queues_init(struct iris_core *core); -+void iris_hfi_queues_deinit(struct iris_core *core); -+ -+#endif -diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h -index f82081ea135f..b4d63d6677c5 100644 ---- a/drivers/media/platform/qcom/iris/iris_platform_common.h -+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h -@@ -31,6 +31,7 @@ struct iris_platform_data { - unsigned int clk_tbl_size; - const char * const *clk_rst_tbl; - unsigned int clk_rst_tbl_size; -+ u64 dma_mask; - }; - - #endif -diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c -index dba8d3c22ce5..ddaa4991d645 100644 ---- a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c -+++ b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c -@@ -36,4 +36,6 @@ struct iris_platform_data sm8550_data = { - .opp_pd_tbl_size = ARRAY_SIZE(sm8550_opp_pd_table), - .clk_tbl = sm8550_clk_table, - .clk_tbl_size = ARRAY_SIZE(sm8550_clk_table), -+ /* Upper bound of DMA address range */ -+ .dma_mask = 0xe0000000 - 1, - }; -diff --git a/drivers/media/platform/qcom/iris/iris_probe.c b/drivers/media/platform/qcom/iris/iris_probe.c -index ce16d894c809..3015e6cb347f 100644 ---- a/drivers/media/platform/qcom/iris/iris_probe.c -+++ b/drivers/media/platform/qcom/iris/iris_probe.c -@@ -168,15 +168,20 @@ static void iris_remove(struct platform_device *pdev) - if (!core) - return; - -+ iris_core_deinit(core); -+ - video_unregister_device(core->vdev_dec); - - v4l2_device_unregister(&core->v4l2_dev); -+ -+ mutex_destroy(&core->lock); - } - - static int iris_probe(struct platform_device *pdev) - { - struct device *dev = &pdev->dev; - struct iris_core *core; -+ u64 dma_mask; - int ret; - - core = devm_kzalloc(&pdev->dev, sizeof(*core), GFP_KERNEL); -@@ -184,6 +189,9 @@ static int iris_probe(struct platform_device *pdev) - return -ENOMEM; - core->dev = dev; - -+ core->state = IRIS_CORE_DEINIT; -+ mutex_init(&core->lock); -+ - core->reg_base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(core->reg_base)) - return PTR_ERR(core->reg_base); -@@ -209,8 +217,19 @@ static int iris_probe(struct platform_device *pdev) - - platform_set_drvdata(pdev, core); - -+ dma_mask = core->iris_platform_data->dma_mask; -+ -+ ret = dma_set_mask_and_coherent(dev, dma_mask); -+ if (ret) -+ goto err_vdev_unreg; -+ -+ dma_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32)); -+ dma_set_seg_boundary(&pdev->dev, DMA_BIT_MASK(32)); -+ - return 0; - -+err_vdev_unreg: -+ video_unregister_device(core->vdev_dec); - err_v4l2_unreg: - v4l2_device_unregister(&core->v4l2_dev); - -diff --git a/drivers/media/platform/qcom/iris/iris_state.h b/drivers/media/platform/qcom/iris/iris_state.h -new file mode 100644 -index 000000000000..1ffe6fe706bd ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_state.h -@@ -0,0 +1,41 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#ifndef __IRIS_STATE_H__ -+#define __IRIS_STATE_H__ -+ -+/** -+ * enum iris_core_state -+ * -+ * @IRIS_CORE_DEINIT: default state. -+ * @IRIS_CORE_INIT: core state with core initialized. FW loaded and -+ * HW brought out of reset, shared queues established -+ * between host driver and firmware. -+ * @IRIS_CORE_ERROR: error state. -+ * -+ * ----------- -+ * | -+ * V -+ * ----------- -+ * +--->| DEINIT |<---+ -+ * | ----------- | -+ * | | | -+ * | v | -+ * | ----------- | -+ * | / \ | -+ * | / \ | -+ * | / \ | -+ * | v v v -+ * ----------- ----------- -+ * | INIT |--->| ERROR | -+ * ----------- ----------- -+ */ -+enum iris_core_state { -+ IRIS_CORE_DEINIT, -+ IRIS_CORE_INIT, -+ IRIS_CORE_ERROR, -+}; -+ -+#endif -diff --git a/drivers/media/platform/qcom/iris/iris_vidc.c b/drivers/media/platform/qcom/iris/iris_vidc.c -index e91d661c6280..5dd0ccbaa2fb 100644 ---- a/drivers/media/platform/qcom/iris/iris_vidc.c -+++ b/drivers/media/platform/qcom/iris/iris_vidc.c -@@ -81,6 +81,12 @@ int iris_open(struct file *filp) - struct iris_inst *inst; - int ret; - -+ ret = iris_core_init(core); -+ if (ret) { -+ dev_err(core->dev, "core init failed\n"); -+ return ret; -+ } -+ - inst = core->iris_platform_data->get_instance(); - if (!inst) - return -ENOMEM; --- -2.34.1 - diff --git a/patch/kernel/archive/sm8550-6.12/0005_media--iris--implement-video-firmware-load-unload.patch b/patch/kernel/archive/sm8550-6.12/0005_media--iris--implement-video-firmware-load-unload.patch deleted file mode 100644 index 1ed676df2daa..000000000000 --- a/patch/kernel/archive/sm8550-6.12/0005_media--iris--implement-video-firmware-load-unload.patch +++ /dev/null @@ -1,289 +0,0 @@ -From a8c9526f7d4aae9c3308767e8932aa53cc6b5e4a Mon Sep 17 00:00:00 2001 -From: Dikshita Agarwal -Date: Fri, 7 Feb 2025 13:24:45 +0530 -Subject: [PATCH] media: iris: implement video firmware load/unload - -Load/unload the firmware into/from memory via the MDT loader. -The firmware is loaded as part of core initialization and unloaded as -part of core de-initialization. - -Tested-by: Stefan Schmidt # x1e80100 (Dell XPS 13 9345) -Reviewed-by: Stefan Schmidt -Tested-by: Neil Armstrong # on SM8550-QRD -Tested-by: Neil Armstrong # on SM8550-HDK -Signed-off-by: Dikshita Agarwal -Link: https://lore.kernel.org/r/20250207-qcom-video-iris-v10-5-ab66eeffbd20@quicinc.com -Signed-off-by: Neil Armstrong ---- - drivers/media/platform/qcom/iris/Kconfig | 2 + - drivers/media/platform/qcom/iris/Makefile | 1 + - drivers/media/platform/qcom/iris/iris_core.c | 8 ++ - .../media/platform/qcom/iris/iris_firmware.c | 111 ++++++++++++++++++ - .../media/platform/qcom/iris/iris_firmware.h | 14 +++ - .../platform/qcom/iris/iris_platform_common.h | 12 ++ - .../platform/qcom/iris/iris_platform_sm8550.c | 10 ++ - 7 files changed, 158 insertions(+) - create mode 100644 drivers/media/platform/qcom/iris/iris_firmware.c - create mode 100644 drivers/media/platform/qcom/iris/iris_firmware.h - -diff --git a/drivers/media/platform/qcom/iris/Kconfig b/drivers/media/platform/qcom/iris/Kconfig -index 8debddec87a5..f92cc7fe9378 100644 ---- a/drivers/media/platform/qcom/iris/Kconfig -+++ b/drivers/media/platform/qcom/iris/Kconfig -@@ -3,6 +3,8 @@ config VIDEO_QCOM_IRIS - depends on VIDEO_DEV - depends on ARCH_QCOM || COMPILE_TEST - select V4L2_MEM2MEM_DEV -+ select QCOM_MDT_LOADER if ARCH_QCOM -+ select QCOM_SCM - help - This is a V4L2 driver for Qualcomm iris video accelerator - hardware. It accelerates decoding operations on various -diff --git a/drivers/media/platform/qcom/iris/Makefile b/drivers/media/platform/qcom/iris/Makefile -index 93711f108a77..6906caa2c481 100644 ---- a/drivers/media/platform/qcom/iris/Makefile -+++ b/drivers/media/platform/qcom/iris/Makefile -@@ -1,4 +1,5 @@ - iris-objs += iris_core.o \ -+ iris_firmware.o \ - iris_hfi_gen1_command.o \ - iris_hfi_gen2_command.o \ - iris_hfi_queue.o \ -diff --git a/drivers/media/platform/qcom/iris/iris_core.c b/drivers/media/platform/qcom/iris/iris_core.c -index 360a54909ef6..8c7d53c57086 100644 ---- a/drivers/media/platform/qcom/iris/iris_core.c -+++ b/drivers/media/platform/qcom/iris/iris_core.c -@@ -4,11 +4,13 @@ - */ - - #include "iris_core.h" -+#include "iris_firmware.h" - #include "iris_state.h" - - void iris_core_deinit(struct iris_core *core) - { - mutex_lock(&core->lock); -+ iris_fw_unload(core); - iris_hfi_queues_deinit(core); - core->state = IRIS_CORE_DEINIT; - mutex_unlock(&core->lock); -@@ -33,10 +35,16 @@ int iris_core_init(struct iris_core *core) - if (ret) - goto error; - -+ ret = iris_fw_load(core); -+ if (ret) -+ goto error_queue_deinit; -+ - mutex_unlock(&core->lock); - - return 0; - -+error_queue_deinit: -+ iris_hfi_queues_deinit(core); - error: - core->state = IRIS_CORE_DEINIT; - exit: -diff --git a/drivers/media/platform/qcom/iris/iris_firmware.c b/drivers/media/platform/qcom/iris/iris_firmware.c -new file mode 100644 -index 000000000000..3d14e596a471 ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_firmware.c -@@ -0,0 +1,111 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "iris_core.h" -+#include "iris_firmware.h" -+ -+#define MAX_FIRMWARE_NAME_SIZE 128 -+ -+static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name) -+{ -+ u32 pas_id = core->iris_platform_data->pas_id; -+ const struct firmware *firmware = NULL; -+ struct device *dev = core->dev; -+ struct reserved_mem *rmem; -+ struct device_node *node; -+ phys_addr_t mem_phys; -+ size_t res_size; -+ ssize_t fw_size; -+ void *mem_virt; -+ int ret; -+ -+ if (strlen(fw_name) >= MAX_FIRMWARE_NAME_SIZE - 4) -+ return -EINVAL; -+ -+ node = of_parse_phandle(dev->of_node, "memory-region", 0); -+ if (!node) -+ return -EINVAL; -+ -+ rmem = of_reserved_mem_lookup(node); -+ of_node_put(node); -+ if (!rmem) -+ return -EINVAL; -+ -+ mem_phys = rmem->base; -+ res_size = rmem->size; -+ -+ ret = request_firmware(&firmware, fw_name, dev); -+ if (ret) -+ return ret; -+ -+ fw_size = qcom_mdt_get_size(firmware); -+ if (fw_size < 0 || res_size < (size_t)fw_size) { -+ ret = -EINVAL; -+ goto err_release_fw; -+ } -+ -+ mem_virt = memremap(mem_phys, res_size, MEMREMAP_WC); -+ if (!mem_virt) -+ goto err_release_fw; -+ -+ ret = qcom_mdt_load(dev, firmware, fw_name, -+ pas_id, mem_virt, mem_phys, res_size, NULL); -+ if (ret) -+ goto err_mem_unmap; -+ -+ ret = qcom_scm_pas_auth_and_reset(pas_id); -+ if (ret) -+ goto err_mem_unmap; -+ -+ return ret; -+ -+err_mem_unmap: -+ memunmap(mem_virt); -+err_release_fw: -+ release_firmware(firmware); -+ -+ return ret; -+} -+ -+int iris_fw_load(struct iris_core *core) -+{ -+ struct tz_cp_config *cp_config = core->iris_platform_data->tz_cp_config_data; -+ const char *fwpath = NULL; -+ int ret; -+ -+ ret = of_property_read_string_index(core->dev->of_node, "firmware-name", 0, -+ &fwpath); -+ if (ret) -+ fwpath = core->iris_platform_data->fwname; -+ -+ ret = iris_load_fw_to_memory(core, fwpath); -+ if (ret) { -+ dev_err(core->dev, "firmware download failed\n"); -+ return -ENOMEM; -+ } -+ -+ ret = qcom_scm_mem_protect_video_var(cp_config->cp_start, -+ cp_config->cp_size, -+ cp_config->cp_nonpixel_start, -+ cp_config->cp_nonpixel_size); -+ if (ret) { -+ dev_err(core->dev, "protect memory failed\n"); -+ qcom_scm_pas_shutdown(core->iris_platform_data->pas_id); -+ return ret; -+ } -+ -+ return ret; -+} -+ -+int iris_fw_unload(struct iris_core *core) -+{ -+ return qcom_scm_pas_shutdown(core->iris_platform_data->pas_id); -+} -diff --git a/drivers/media/platform/qcom/iris/iris_firmware.h b/drivers/media/platform/qcom/iris/iris_firmware.h -new file mode 100644 -index 000000000000..266bdd92a124 ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_firmware.h -@@ -0,0 +1,14 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#ifndef __IRIS_FIRMWARE_H__ -+#define __IRIS_FIRMWARE_H__ -+ -+struct iris_core; -+ -+int iris_fw_load(struct iris_core *core); -+int iris_fw_unload(struct iris_core *core); -+ -+#endif -diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h -index b4d63d6677c5..42c1fe8e4fa6 100644 ---- a/drivers/media/platform/qcom/iris/iris_platform_common.h -+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h -@@ -6,6 +6,8 @@ - #ifndef __IRIS_PLATFORM_COMMON_H__ - #define __IRIS_PLATFORM_COMMON_H__ - -+#define IRIS_PAS_ID 9 -+ - extern struct iris_platform_data sm8550_data; - - enum platform_clk_type { -@@ -19,6 +21,13 @@ struct platform_clk_data { - const char *clk_name; - }; - -+struct tz_cp_config { -+ u32 cp_start; -+ u32 cp_size; -+ u32 cp_nonpixel_start; -+ u32 cp_nonpixel_size; -+}; -+ - struct iris_platform_data { - struct iris_inst *(*get_instance)(void); - const struct icc_info *icc_tbl; -@@ -32,6 +41,9 @@ struct iris_platform_data { - const char * const *clk_rst_tbl; - unsigned int clk_rst_tbl_size; - u64 dma_mask; -+ const char *fwname; -+ u32 pas_id; -+ struct tz_cp_config *tz_cp_config_data; - }; - - #endif -diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c -index ddaa4991d645..bf389181d8cc 100644 ---- a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c -+++ b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c -@@ -24,6 +24,13 @@ static const struct platform_clk_data sm8550_clk_table[] = { - {IRIS_HW_CLK, "vcodec0_core" }, - }; - -+static struct tz_cp_config tz_cp_config_sm8550 = { -+ .cp_start = 0, -+ .cp_size = 0x25800000, -+ .cp_nonpixel_start = 0x01000000, -+ .cp_nonpixel_size = 0x24800000, -+}; -+ - struct iris_platform_data sm8550_data = { - .get_instance = iris_hfi_gen2_get_instance, - .icc_tbl = sm8550_icc_table, -@@ -38,4 +45,7 @@ struct iris_platform_data sm8550_data = { - .clk_tbl_size = ARRAY_SIZE(sm8550_clk_table), - /* Upper bound of DMA address range */ - .dma_mask = 0xe0000000 - 1, -+ .fwname = "qcom/vpu/vpu30_p4.mbn", -+ .pas_id = IRIS_PAS_ID, -+ .tz_cp_config_data = &tz_cp_config_sm8550, - }; --- -2.34.1 - diff --git a/patch/kernel/archive/sm8550-6.12/0006_media--iris--implement-the-boot-sequence-of-the-fi.patch b/patch/kernel/archive/sm8550-6.12/0006_media--iris--implement-the-boot-sequence-of-the-fi.patch deleted file mode 100644 index 0df845ea96e8..000000000000 --- a/patch/kernel/archive/sm8550-6.12/0006_media--iris--implement-the-boot-sequence-of-the-fi.patch +++ /dev/null @@ -1,213 +0,0 @@ -From e07ed986c1e7c280e556c6a070fddd70300e2aa1 Mon Sep 17 00:00:00 2001 -From: Dikshita Agarwal -Date: Fri, 7 Feb 2025 13:24:46 +0530 -Subject: [PATCH] media: iris: implement the boot sequence of the firmware - -Set the memory region on the firmware and implement the boot sequence. - -Tested-by: Stefan Schmidt # x1e80100 (Dell XPS 13 9345) -Reviewed-by: Stefan Schmidt -Tested-by: Neil Armstrong # on SM8550-QRD -Tested-by: Neil Armstrong # on SM8550-HDK -Signed-off-by: Dikshita Agarwal -Link: https://lore.kernel.org/r/20250207-qcom-video-iris-v10-6-ab66eeffbd20@quicinc.com -Signed-off-by: Neil Armstrong ---- - drivers/media/platform/qcom/iris/Makefile | 1 + - drivers/media/platform/qcom/iris/iris_core.c | 7 ++ - .../platform/qcom/iris/iris_platform_common.h | 1 + - .../platform/qcom/iris/iris_platform_sm8550.c | 3 + - .../platform/qcom/iris/iris_vpu_common.c | 89 +++++++++++++++++++ - .../platform/qcom/iris/iris_vpu_common.h | 13 +++ - 6 files changed, 114 insertions(+) - create mode 100644 drivers/media/platform/qcom/iris/iris_vpu_common.c - create mode 100644 drivers/media/platform/qcom/iris/iris_vpu_common.h - -diff --git a/drivers/media/platform/qcom/iris/Makefile b/drivers/media/platform/qcom/iris/Makefile -index 6906caa2c481..792f1d6ac8f3 100644 ---- a/drivers/media/platform/qcom/iris/Makefile -+++ b/drivers/media/platform/qcom/iris/Makefile -@@ -6,5 +6,6 @@ iris-objs += iris_core.o \ - iris_platform_sm8550.o \ - iris_probe.o \ - iris_vidc.o \ -+ iris_vpu_common.o \ - - obj-$(CONFIG_VIDEO_QCOM_IRIS) += iris.o -diff --git a/drivers/media/platform/qcom/iris/iris_core.c b/drivers/media/platform/qcom/iris/iris_core.c -index 8c7d53c57086..5ad66ac113ae 100644 ---- a/drivers/media/platform/qcom/iris/iris_core.c -+++ b/drivers/media/platform/qcom/iris/iris_core.c -@@ -6,6 +6,7 @@ - #include "iris_core.h" - #include "iris_firmware.h" - #include "iris_state.h" -+#include "iris_vpu_common.h" - - void iris_core_deinit(struct iris_core *core) - { -@@ -39,10 +40,16 @@ int iris_core_init(struct iris_core *core) - if (ret) - goto error_queue_deinit; - -+ ret = iris_vpu_boot_firmware(core); -+ if (ret) -+ goto error_unload_fw; -+ - mutex_unlock(&core->lock); - - return 0; - -+error_unload_fw: -+ iris_fw_unload(core); - error_queue_deinit: - iris_hfi_queues_deinit(core); - error: -diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h -index 42c1fe8e4fa6..7e661e8928bd 100644 ---- a/drivers/media/platform/qcom/iris/iris_platform_common.h -+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h -@@ -44,6 +44,7 @@ struct iris_platform_data { - const char *fwname; - u32 pas_id; - struct tz_cp_config *tz_cp_config_data; -+ u32 core_arch; - }; - - #endif -diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c -index bf389181d8cc..237f932946d6 100644 ---- a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c -+++ b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c -@@ -7,6 +7,8 @@ - #include "iris_hfi_gen2.h" - #include "iris_platform_common.h" - -+#define VIDEO_ARCH_LX 1 -+ - static const struct icc_info sm8550_icc_table[] = { - { "cpu-cfg", 1000, 1000 }, - { "video-mem", 1000, 15000000 }, -@@ -48,4 +50,5 @@ struct iris_platform_data sm8550_data = { - .fwname = "qcom/vpu/vpu30_p4.mbn", - .pas_id = IRIS_PAS_ID, - .tz_cp_config_data = &tz_cp_config_sm8550, -+ .core_arch = VIDEO_ARCH_LX, - }; -diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.c b/drivers/media/platform/qcom/iris/iris_vpu_common.c -new file mode 100644 -index 000000000000..959ed46e8f47 ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_vpu_common.c -@@ -0,0 +1,89 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#include -+ -+#include "iris_core.h" -+#include "iris_vpu_common.h" -+ -+#define CPU_BASE_OFFS 0x000A0000 -+ -+#define CPU_CS_BASE_OFFS (CPU_BASE_OFFS) -+ -+#define CTRL_INIT (CPU_CS_BASE_OFFS + 0x48) -+#define CTRL_STATUS (CPU_CS_BASE_OFFS + 0x4C) -+ -+#define CTRL_ERROR_STATUS__M 0xfe -+ -+#define QTBL_INFO (CPU_CS_BASE_OFFS + 0x50) -+#define QTBL_ENABLE BIT(0) -+ -+#define QTBL_ADDR (CPU_CS_BASE_OFFS + 0x54) -+#define CPU_CS_SCIACMDARG3 (CPU_CS_BASE_OFFS + 0x58) -+#define SFR_ADDR (CPU_CS_BASE_OFFS + 0x5C) -+#define UC_REGION_ADDR (CPU_CS_BASE_OFFS + 0x64) -+#define UC_REGION_SIZE (CPU_CS_BASE_OFFS + 0x68) -+ -+#define CPU_CS_H2XSOFTINTEN (CPU_CS_BASE_OFFS + 0x148) -+#define HOST2XTENSA_INTR_ENABLE BIT(0) -+ -+#define CPU_CS_X2RPMH (CPU_CS_BASE_OFFS + 0x168) -+ -+static void iris_vpu_setup_ucregion_memory_map(struct iris_core *core) -+{ -+ u32 queue_size, value; -+ -+ /* Iris hardware requires 4K queue alignment */ -+ queue_size = ALIGN(sizeof(struct iris_hfi_queue_table_header) + -+ (IFACEQ_QUEUE_SIZE * IFACEQ_NUMQ), SZ_4K); -+ -+ value = (u32)core->iface_q_table_daddr; -+ writel(value, core->reg_base + UC_REGION_ADDR); -+ -+ /* Iris hardware requires 1M queue alignment */ -+ value = ALIGN(SFR_SIZE + queue_size, SZ_1M); -+ writel(value, core->reg_base + UC_REGION_SIZE); -+ -+ value = (u32)core->iface_q_table_daddr; -+ writel(value, core->reg_base + QTBL_ADDR); -+ -+ writel(QTBL_ENABLE, core->reg_base + QTBL_INFO); -+ -+ if (core->sfr_daddr) { -+ value = (u32)core->sfr_daddr + core->iris_platform_data->core_arch; -+ writel(value, core->reg_base + SFR_ADDR); -+ } -+} -+ -+int iris_vpu_boot_firmware(struct iris_core *core) -+{ -+ u32 ctrl_init = BIT(0), ctrl_status = 0, count = 0, max_tries = 1000; -+ -+ iris_vpu_setup_ucregion_memory_map(core); -+ -+ writel(ctrl_init, core->reg_base + CTRL_INIT); -+ writel(0x1, core->reg_base + CPU_CS_SCIACMDARG3); -+ -+ while (!ctrl_status && count < max_tries) { -+ ctrl_status = readl(core->reg_base + CTRL_STATUS); -+ if ((ctrl_status & CTRL_ERROR_STATUS__M) == 0x4) { -+ dev_err(core->dev, "invalid setting for uc_region\n"); -+ break; -+ } -+ -+ usleep_range(50, 100); -+ count++; -+ } -+ -+ if (count >= max_tries) { -+ dev_err(core->dev, "error booting up iris firmware\n"); -+ return -ETIME; -+ } -+ -+ writel(HOST2XTENSA_INTR_ENABLE, core->reg_base + CPU_CS_H2XSOFTINTEN); -+ writel(0x0, core->reg_base + CPU_CS_X2RPMH); -+ -+ return 0; -+} -diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.h b/drivers/media/platform/qcom/iris/iris_vpu_common.h -new file mode 100644 -index 000000000000..bafcf46520fd ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_vpu_common.h -@@ -0,0 +1,13 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#ifndef __IRIS_VPU_COMMON_H__ -+#define __IRIS_VPU_COMMON_H__ -+ -+struct iris_core; -+ -+int iris_vpu_boot_firmware(struct iris_core *core); -+ -+#endif --- -2.34.1 - diff --git a/patch/kernel/archive/sm8550-6.12/0007_media--iris--introduce-host-firmware-interface-wit.patch b/patch/kernel/archive/sm8550-6.12/0007_media--iris--introduce-host-firmware-interface-wit.patch deleted file mode 100644 index 15189fa00a1b..000000000000 --- a/patch/kernel/archive/sm8550-6.12/0007_media--iris--introduce-host-firmware-interface-wit.patch +++ /dev/null @@ -1,1697 +0,0 @@ -From 7d344e57a0cb46998f3008df4f6e2d20e17aa94f Mon Sep 17 00:00:00 2001 -From: Dikshita Agarwal -Date: Fri, 7 Feb 2025 13:24:47 +0530 -Subject: [PATCH] media: iris: introduce host firmware interface with necessary - hooks - -The Host firmware interface (HFI) is a well defined set of interfaces -for the communication between the host driver and the firmware. The -commands and responses are exchanged in form of packets. One or multiple -packets are grouped under the packet header. Each packet has a packet -type which describes the specific HFI and the payload, which holds the -corresponding value for that HFI. - -Tested-by: Stefan Schmidt # x1e80100 (Dell XPS 13 9345) -Reviewed-by: Stefan Schmidt -Tested-by: Neil Armstrong # on SM8550-QRD -Tested-by: Neil Armstrong # on SM8550-HDK -Signed-off-by: Dikshita Agarwal -Link: https://lore.kernel.org/r/20250207-qcom-video-iris-v10-7-ab66eeffbd20@quicinc.com -Signed-off-by: Neil Armstrong ---- - drivers/media/platform/qcom/iris/Makefile | 4 + - drivers/media/platform/qcom/iris/iris_core.c | 24 +- - drivers/media/platform/qcom/iris/iris_core.h | 20 ++ - .../platform/qcom/iris/iris_hfi_common.c | 50 ++++ - .../platform/qcom/iris/iris_hfi_common.h | 60 +++++ - .../media/platform/qcom/iris/iris_hfi_gen1.h | 3 + - .../qcom/iris/iris_hfi_gen1_command.c | 61 +++++ - .../qcom/iris/iris_hfi_gen1_defines.h | 94 ++++++++ - .../qcom/iris/iris_hfi_gen1_response.c | 176 ++++++++++++++ - .../media/platform/qcom/iris/iris_hfi_gen2.h | 4 + - .../qcom/iris/iris_hfi_gen2_command.c | 74 ++++++ - .../qcom/iris/iris_hfi_gen2_defines.h | 46 ++++ - .../platform/qcom/iris/iris_hfi_gen2_packet.c | 161 +++++++++++++ - .../platform/qcom/iris/iris_hfi_gen2_packet.h | 69 ++++++ - .../qcom/iris/iris_hfi_gen2_response.c | 215 ++++++++++++++++++ - .../media/platform/qcom/iris/iris_hfi_queue.c | 173 ++++++++++++++ - .../media/platform/qcom/iris/iris_hfi_queue.h | 5 + - .../platform/qcom/iris/iris_platform_common.h | 17 ++ - .../platform/qcom/iris/iris_platform_sm8550.c | 14 ++ - drivers/media/platform/qcom/iris/iris_probe.c | 26 +++ - .../platform/qcom/iris/iris_vpu_common.c | 43 ++++ - .../platform/qcom/iris/iris_vpu_common.h | 3 + - 22 files changed, 1341 insertions(+), 1 deletion(-) - create mode 100644 drivers/media/platform/qcom/iris/iris_hfi_common.c - create mode 100644 drivers/media/platform/qcom/iris/iris_hfi_common.h - create mode 100644 drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h - create mode 100644 drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c - create mode 100644 drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h - create mode 100644 drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.c - create mode 100644 drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.h - create mode 100644 drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c - -diff --git a/drivers/media/platform/qcom/iris/Makefile b/drivers/media/platform/qcom/iris/Makefile -index 792f1d6ac8f3..76ca5287c49f 100644 ---- a/drivers/media/platform/qcom/iris/Makefile -+++ b/drivers/media/platform/qcom/iris/Makefile -@@ -1,7 +1,11 @@ - iris-objs += iris_core.o \ - iris_firmware.o \ -+ iris_hfi_common.o \ - iris_hfi_gen1_command.o \ -+ iris_hfi_gen1_response.o \ - iris_hfi_gen2_command.o \ -+ iris_hfi_gen2_packet.o \ -+ iris_hfi_gen2_response.o \ - iris_hfi_queue.o \ - iris_platform_sm8550.o \ - iris_probe.o \ -diff --git a/drivers/media/platform/qcom/iris/iris_core.c b/drivers/media/platform/qcom/iris/iris_core.c -index 5ad66ac113ae..7e19bdd0a19b 100644 ---- a/drivers/media/platform/qcom/iris/iris_core.c -+++ b/drivers/media/platform/qcom/iris/iris_core.c -@@ -17,6 +17,24 @@ void iris_core_deinit(struct iris_core *core) - mutex_unlock(&core->lock); - } - -+static int iris_wait_for_system_response(struct iris_core *core) -+{ -+ u32 hw_response_timeout_val = core->iris_platform_data->hw_response_timeout; -+ int ret; -+ -+ if (core->state == IRIS_CORE_ERROR) -+ return -EIO; -+ -+ ret = wait_for_completion_timeout(&core->core_init_done, -+ msecs_to_jiffies(hw_response_timeout_val)); -+ if (!ret) { -+ core->state = IRIS_CORE_ERROR; -+ return -ETIMEDOUT; -+ } -+ -+ return 0; -+} -+ - int iris_core_init(struct iris_core *core) - { - int ret; -@@ -44,9 +62,13 @@ int iris_core_init(struct iris_core *core) - if (ret) - goto error_unload_fw; - -+ ret = iris_hfi_core_init(core); -+ if (ret) -+ goto error_unload_fw; -+ - mutex_unlock(&core->lock); - -- return 0; -+ return iris_wait_for_system_response(core); - - error_unload_fw: - iris_fw_unload(core); -diff --git a/drivers/media/platform/qcom/iris/iris_core.h b/drivers/media/platform/qcom/iris/iris_core.h -index 516082aa58c9..c0f3c189d779 100644 ---- a/drivers/media/platform/qcom/iris/iris_core.h -+++ b/drivers/media/platform/qcom/iris/iris_core.h -@@ -9,6 +9,7 @@ - #include - #include - -+#include "iris_hfi_common.h" - #include "iris_hfi_queue.h" - #include "iris_platform_common.h" - #include "iris_state.h" -@@ -19,6 +20,9 @@ struct icc_info { - u32 bw_max_kbps; - }; - -+#define IRIS_FW_VERSION_LENGTH 128 -+#define IFACEQ_CORE_PKT_SIZE (1024 * 4) -+ - /** - * struct iris_core - holds core parameters valid for all instances - * -@@ -45,6 +49,14 @@ struct icc_info { - * @message_queue: shared interface queue to receive responses from firmware - * @debug_queue: shared interface queue to receive debug info from firmware - * @lock: a lock for this strucure -+ * @response_packet: a pointer to response packet from fw to driver -+ * @header_id: id of packet header -+ * @packet_id: id of packet -+ * @hfi_ops: iris hfi command ops -+ * @hfi_response_ops: iris hfi response ops -+ * @core_init_done: structure of signal completion for system response -+ * @intr_status: interrupt status -+ * @sys_error_handler: a delayed work for handling system fatal error - */ - - struct iris_core { -@@ -71,6 +83,14 @@ struct iris_core { - struct iris_iface_q_info message_queue; - struct iris_iface_q_info debug_queue; - struct mutex lock; /* lock for core related operations */ -+ u8 *response_packet; -+ u32 header_id; -+ u32 packet_id; -+ const struct iris_hfi_command_ops *hfi_ops; -+ const struct iris_hfi_response_ops *hfi_response_ops; -+ struct completion core_init_done; -+ u32 intr_status; -+ struct delayed_work sys_error_handler; - }; - - int iris_core_init(struct iris_core *core); -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_common.c b/drivers/media/platform/qcom/iris/iris_hfi_common.c -new file mode 100644 -index 000000000000..a19b988c9a88 ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_hfi_common.c -@@ -0,0 +1,50 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#include "iris_core.h" -+#include "iris_hfi_common.h" -+#include "iris_vpu_common.h" -+ -+int iris_hfi_core_init(struct iris_core *core) -+{ -+ const struct iris_hfi_command_ops *hfi_ops = core->hfi_ops; -+ int ret; -+ -+ ret = hfi_ops->sys_init(core); -+ if (ret) -+ return ret; -+ -+ ret = hfi_ops->sys_image_version(core); -+ if (ret) -+ return ret; -+ -+ return hfi_ops->sys_interframe_powercollapse(core); -+} -+ -+irqreturn_t iris_hfi_isr(int irq, void *data) -+{ -+ disable_irq_nosync(irq); -+ -+ return IRQ_WAKE_THREAD; -+} -+ -+irqreturn_t iris_hfi_isr_handler(int irq, void *data) -+{ -+ struct iris_core *core = data; -+ -+ if (!core) -+ return IRQ_NONE; -+ -+ mutex_lock(&core->lock); -+ iris_vpu_clear_interrupt(core); -+ mutex_unlock(&core->lock); -+ -+ core->hfi_response_ops->hfi_response_handler(core); -+ -+ if (!iris_vpu_watchdog(core, core->intr_status)) -+ enable_irq(irq); -+ -+ return IRQ_HANDLED; -+} -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_common.h b/drivers/media/platform/qcom/iris/iris_hfi_common.h -new file mode 100644 -index 000000000000..b46a2f21102a ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_hfi_common.h -@@ -0,0 +1,60 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#ifndef __IRIS_HFI_COMMON_H__ -+#define __IRIS_HFI_COMMON_H__ -+ -+#include -+#include -+ -+struct iris_core; -+ -+enum hfi_packet_port_type { -+ HFI_PORT_NONE = 0x00000000, -+ HFI_PORT_BITSTREAM = 0x00000001, -+ HFI_PORT_RAW = 0x00000002, -+}; -+ -+enum hfi_packet_payload_info { -+ HFI_PAYLOAD_NONE = 0x00000000, -+ HFI_PAYLOAD_U32 = 0x00000001, -+ HFI_PAYLOAD_S32 = 0x00000002, -+ HFI_PAYLOAD_U64 = 0x00000003, -+ HFI_PAYLOAD_S64 = 0x00000004, -+ HFI_PAYLOAD_STRUCTURE = 0x00000005, -+ HFI_PAYLOAD_BLOB = 0x00000006, -+ HFI_PAYLOAD_STRING = 0x00000007, -+ HFI_PAYLOAD_Q16 = 0x00000008, -+ HFI_PAYLOAD_U32_ENUM = 0x00000009, -+ HFI_PAYLOAD_32_PACKED = 0x0000000a, -+ HFI_PAYLOAD_U32_ARRAY = 0x0000000b, -+ HFI_PAYLOAD_S32_ARRAY = 0x0000000c, -+ HFI_PAYLOAD_64_PACKED = 0x0000000d, -+}; -+ -+enum hfi_packet_host_flags { -+ HFI_HOST_FLAGS_NONE = 0x00000000, -+ HFI_HOST_FLAGS_INTR_REQUIRED = 0x00000001, -+ HFI_HOST_FLAGS_RESPONSE_REQUIRED = 0x00000002, -+ HFI_HOST_FLAGS_NON_DISCARDABLE = 0x00000004, -+ HFI_HOST_FLAGS_GET_PROPERTY = 0x00000008, -+}; -+ -+struct iris_hfi_command_ops { -+ int (*sys_init)(struct iris_core *core); -+ int (*sys_image_version)(struct iris_core *core); -+ int (*sys_interframe_powercollapse)(struct iris_core *core); -+}; -+ -+struct iris_hfi_response_ops { -+ void (*hfi_response_handler)(struct iris_core *core); -+}; -+ -+int iris_hfi_core_init(struct iris_core *core); -+ -+irqreturn_t iris_hfi_isr(int irq, void *data); -+irqreturn_t iris_hfi_isr_handler(int irq, void *data); -+ -+#endif -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1.h b/drivers/media/platform/qcom/iris/iris_hfi_gen1.h -index 5d05be7470e0..19b8e9054a75 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen1.h -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1.h -@@ -6,8 +6,11 @@ - #ifndef __IRIS_HFI_GEN1_H__ - #define __IRIS_HFI_GEN1_H__ - -+struct iris_core; - struct iris_inst; - -+void iris_hfi_gen1_command_ops_init(struct iris_core *core); -+void iris_hfi_gen1_response_ops_init(struct iris_core *core); - struct iris_inst *iris_hfi_gen1_get_instance(void); - - #endif -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c -index 20c68f4ffb72..07007d8812ba 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c -@@ -4,8 +4,69 @@ - */ - - #include "iris_hfi_gen1.h" -+#include "iris_hfi_gen1_defines.h" - #include "iris_instance.h" - -+static int iris_hfi_gen1_sys_init(struct iris_core *core) -+{ -+ struct hfi_sys_init_pkt sys_init_pkt; -+ -+ sys_init_pkt.hdr.size = sizeof(sys_init_pkt); -+ sys_init_pkt.hdr.pkt_type = HFI_CMD_SYS_INIT; -+ sys_init_pkt.arch_type = HFI_VIDEO_ARCH_OX; -+ -+ return iris_hfi_queue_cmd_write_locked(core, &sys_init_pkt, sys_init_pkt.hdr.size); -+} -+ -+static int iris_hfi_gen1_sys_image_version(struct iris_core *core) -+{ -+ struct hfi_sys_get_property_pkt packet; -+ -+ packet.hdr.size = sizeof(packet); -+ packet.hdr.pkt_type = HFI_CMD_SYS_GET_PROPERTY; -+ packet.num_properties = 1; -+ packet.data = HFI_PROPERTY_SYS_IMAGE_VERSION; -+ -+ return iris_hfi_queue_cmd_write_locked(core, &packet, packet.hdr.size); -+} -+ -+static int iris_hfi_gen1_sys_interframe_powercollapse(struct iris_core *core) -+{ -+ struct hfi_sys_set_property_pkt *pkt; -+ struct hfi_enable *hfi; -+ u32 packet_size; -+ int ret; -+ -+ packet_size = struct_size(pkt, data, 1) + sizeof(*hfi); -+ pkt = kzalloc(packet_size, GFP_KERNEL); -+ if (!pkt) -+ return -ENOMEM; -+ -+ hfi = (struct hfi_enable *)&pkt->data[1]; -+ -+ pkt->hdr.size = packet_size; -+ pkt->hdr.pkt_type = HFI_CMD_SYS_SET_PROPERTY; -+ pkt->num_properties = 1; -+ pkt->data[0] = HFI_PROPERTY_SYS_CODEC_POWER_PLANE_CTRL; -+ hfi->enable = true; -+ -+ ret = iris_hfi_queue_cmd_write_locked(core, pkt, pkt->hdr.size); -+ kfree(pkt); -+ -+ return ret; -+} -+ -+static const struct iris_hfi_command_ops iris_hfi_gen1_command_ops = { -+ .sys_init = iris_hfi_gen1_sys_init, -+ .sys_image_version = iris_hfi_gen1_sys_image_version, -+ .sys_interframe_powercollapse = iris_hfi_gen1_sys_interframe_powercollapse, -+}; -+ -+void iris_hfi_gen1_command_ops_init(struct iris_core *core) -+{ -+ core->hfi_ops = &iris_hfi_gen1_command_ops; -+} -+ - struct iris_inst *iris_hfi_gen1_get_instance(void) - { - return kzalloc(sizeof(struct iris_inst), GFP_KERNEL); -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h -new file mode 100644 -index 000000000000..8af824a42bcf ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h -@@ -0,0 +1,94 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#ifndef __IRIS_HFI_GEN1_DEFINES_H__ -+#define __IRIS_HFI_GEN1_DEFINES_H__ -+ -+#include -+ -+#define HFI_VIDEO_ARCH_OX 0x1 -+#define HFI_ERR_NONE 0x0 -+ -+#define HFI_CMD_SYS_INIT 0x10001 -+#define HFI_CMD_SYS_SET_PROPERTY 0x10005 -+#define HFI_CMD_SYS_GET_PROPERTY 0x10006 -+ -+#define HFI_PROPERTY_SYS_CODEC_POWER_PLANE_CTRL 0x5 -+#define HFI_PROPERTY_SYS_IMAGE_VERSION 0x6 -+ -+#define HFI_EVENT_SYS_ERROR 0x1 -+ -+#define HFI_MSG_SYS_INIT 0x20001 -+#define HFI_MSG_SYS_COV 0x20009 -+#define HFI_MSG_SYS_PROPERTY_INFO 0x2000a -+ -+#define HFI_MSG_EVENT_NOTIFY 0x21001 -+ -+struct hfi_pkt_hdr { -+ u32 size; -+ u32 pkt_type; -+}; -+ -+struct hfi_sys_init_pkt { -+ struct hfi_pkt_hdr hdr; -+ u32 arch_type; -+}; -+ -+struct hfi_sys_set_property_pkt { -+ struct hfi_pkt_hdr hdr; -+ u32 num_properties; -+ u32 data[]; -+}; -+ -+struct hfi_sys_get_property_pkt { -+ struct hfi_pkt_hdr hdr; -+ u32 num_properties; -+ u32 data; -+}; -+ -+struct hfi_msg_event_notify_pkt { -+ struct hfi_pkt_hdr hdr; -+ u32 event_id; -+ u32 event_data1; -+ u32 event_data2; -+ u32 ext_event_data[]; -+}; -+ -+struct hfi_msg_sys_init_done_pkt { -+ struct hfi_pkt_hdr hdr; -+ u32 error_type; -+ u32 num_properties; -+ u32 data[]; -+}; -+ -+struct hfi_msg_sys_property_info_pkt { -+ struct hfi_pkt_hdr hdr; -+ u32 num_properties; -+ u32 property; -+ u8 data[]; -+}; -+ -+struct hfi_enable { -+ u32 enable; -+}; -+ -+struct hfi_msg_sys_debug_pkt { -+ struct hfi_pkt_hdr hdr; -+ u32 msg_type; -+ u32 msg_size; -+ u32 time_stamp_hi; -+ u32 time_stamp_lo; -+ u8 msg_data[]; -+}; -+ -+struct hfi_msg_sys_coverage_pkt { -+ struct hfi_pkt_hdr hdr; -+ u32 msg_size; -+ u32 time_stamp_hi; -+ u32 time_stamp_lo; -+ u8 msg_data[]; -+}; -+ -+#endif -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c -new file mode 100644 -index 000000000000..78fefa4176f9 ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c -@@ -0,0 +1,176 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#include "iris_hfi_gen1.h" -+#include "iris_hfi_gen1_defines.h" -+#include "iris_instance.h" -+ -+static void -+iris_hfi_gen1_sys_event_notify(struct iris_core *core, void *packet) -+{ -+ struct hfi_msg_event_notify_pkt *pkt = packet; -+ -+ if (pkt->event_id == HFI_EVENT_SYS_ERROR) -+ dev_err(core->dev, "sys error (type: %x, data1:%x, data2:%x)\n", -+ pkt->event_id, pkt->event_data1, pkt->event_data2); -+ -+ core->state = IRIS_CORE_ERROR; -+ schedule_delayed_work(&core->sys_error_handler, msecs_to_jiffies(10)); -+} -+ -+static void iris_hfi_gen1_sys_init_done(struct iris_core *core, void *packet) -+{ -+ struct hfi_msg_sys_init_done_pkt *pkt = packet; -+ -+ if (pkt->error_type != HFI_ERR_NONE) { -+ core->state = IRIS_CORE_ERROR; -+ return; -+ } -+ -+ complete(&core->core_init_done); -+} -+ -+static void -+iris_hfi_gen1_sys_get_prop_image_version(struct iris_core *core, -+ struct hfi_msg_sys_property_info_pkt *pkt) -+{ -+ int req_bytes = pkt->hdr.size - sizeof(*pkt); -+ char fw_version[IRIS_FW_VERSION_LENGTH]; -+ u8 *str_image_version; -+ u32 i; -+ -+ if (req_bytes < IRIS_FW_VERSION_LENGTH - 1 || !pkt->data[0] || pkt->num_properties > 1) { -+ dev_err(core->dev, "bad packet\n"); -+ return; -+ } -+ -+ str_image_version = pkt->data; -+ if (!str_image_version) { -+ dev_err(core->dev, "firmware version not available\n"); -+ return; -+ } -+ -+ for (i = 0; i < IRIS_FW_VERSION_LENGTH - 1; i++) { -+ if (str_image_version[i] != '\0') -+ fw_version[i] = str_image_version[i]; -+ else -+ fw_version[i] = ' '; -+ } -+ fw_version[i] = '\0'; -+ dev_dbg(core->dev, "firmware version: %s\n", fw_version); -+} -+ -+static void iris_hfi_gen1_sys_property_info(struct iris_core *core, void *packet) -+{ -+ struct hfi_msg_sys_property_info_pkt *pkt = packet; -+ -+ if (!pkt->num_properties) { -+ dev_dbg(core->dev, "no properties\n"); -+ return; -+ } -+ -+ switch (pkt->property) { -+ case HFI_PROPERTY_SYS_IMAGE_VERSION: -+ iris_hfi_gen1_sys_get_prop_image_version(core, pkt); -+ break; -+ default: -+ dev_dbg(core->dev, "unknown property data\n"); -+ break; -+ } -+} -+ -+struct iris_hfi_gen1_response_pkt_info { -+ u32 pkt; -+ u32 pkt_sz; -+}; -+ -+static const struct iris_hfi_gen1_response_pkt_info pkt_infos[] = { -+ { -+ .pkt = HFI_MSG_EVENT_NOTIFY, -+ .pkt_sz = sizeof(struct hfi_msg_event_notify_pkt), -+ }, -+ { -+ .pkt = HFI_MSG_SYS_INIT, -+ .pkt_sz = sizeof(struct hfi_msg_sys_init_done_pkt), -+ }, -+ { -+ .pkt = HFI_MSG_SYS_PROPERTY_INFO, -+ .pkt_sz = sizeof(struct hfi_msg_sys_property_info_pkt), -+ }, -+}; -+ -+static void iris_hfi_gen1_handle_response(struct iris_core *core, void *response) -+{ -+ struct hfi_pkt_hdr *hdr = (struct hfi_pkt_hdr *)response; -+ const struct iris_hfi_gen1_response_pkt_info *pkt_info; -+ struct device *dev = core->dev; -+ bool found = false; -+ u32 i; -+ -+ for (i = 0; i < ARRAY_SIZE(pkt_infos); i++) { -+ pkt_info = &pkt_infos[i]; -+ if (pkt_info->pkt != hdr->pkt_type) -+ continue; -+ found = true; -+ break; -+ } -+ -+ if (!found || hdr->size < pkt_info->pkt_sz) { -+ dev_err(dev, "bad packet size (%d should be %d, pkt type:%x, found %d)\n", -+ hdr->size, pkt_info->pkt_sz, hdr->pkt_type, found); -+ -+ return; -+ } -+ -+ switch (hdr->pkt_type) { -+ case HFI_MSG_SYS_INIT: -+ iris_hfi_gen1_sys_init_done(core, hdr); -+ break; -+ case HFI_MSG_SYS_PROPERTY_INFO: -+ iris_hfi_gen1_sys_property_info(core, hdr); -+ break; -+ case HFI_MSG_EVENT_NOTIFY: -+ iris_hfi_gen1_sys_event_notify(core, hdr); -+ break; -+ default: -+ break; -+ } -+} -+ -+static void iris_hfi_gen1_flush_debug_queue(struct iris_core *core, u8 *packet) -+{ -+ struct hfi_msg_sys_coverage_pkt *pkt; -+ -+ while (!iris_hfi_queue_dbg_read(core, packet)) { -+ pkt = (struct hfi_msg_sys_coverage_pkt *)packet; -+ -+ if (pkt->hdr.pkt_type != HFI_MSG_SYS_COV) { -+ struct hfi_msg_sys_debug_pkt *pkt = -+ (struct hfi_msg_sys_debug_pkt *)packet; -+ -+ dev_dbg(core->dev, "%s", pkt->msg_data); -+ } -+ } -+} -+ -+static void iris_hfi_gen1_response_handler(struct iris_core *core) -+{ -+ memset(core->response_packet, 0, sizeof(struct hfi_pkt_hdr)); -+ while (!iris_hfi_queue_msg_read(core, core->response_packet)) { -+ iris_hfi_gen1_handle_response(core, core->response_packet); -+ memset(core->response_packet, 0, sizeof(struct hfi_pkt_hdr)); -+ } -+ -+ iris_hfi_gen1_flush_debug_queue(core, core->response_packet); -+} -+ -+static const struct iris_hfi_response_ops iris_hfi_gen1_response_ops = { -+ .hfi_response_handler = iris_hfi_gen1_response_handler, -+}; -+ -+void iris_hfi_gen1_response_ops_init(struct iris_core *core) -+{ -+ core->hfi_response_ops = &iris_hfi_gen1_response_ops; -+} -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2.h b/drivers/media/platform/qcom/iris/iris_hfi_gen2.h -index c159ed7f64f9..c43b51774978 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen2.h -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2.h -@@ -8,6 +8,8 @@ - - #include "iris_instance.h" - -+struct iris_core; -+ - /** - * struct iris_inst_hfi_gen2 - holds per video instance parameters for hfi_gen2 - * -@@ -17,6 +19,8 @@ struct iris_inst_hfi_gen2 { - struct iris_inst inst; - }; - -+void iris_hfi_gen2_command_ops_init(struct iris_core *core); -+void iris_hfi_gen2_response_ops_init(struct iris_core *core); - struct iris_inst *iris_hfi_gen2_get_instance(void); - - #endif -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c -index 3ee33c8befae..5eaebe170214 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c -@@ -4,6 +4,80 @@ - */ - - #include "iris_hfi_gen2.h" -+#include "iris_hfi_gen2_packet.h" -+ -+#define NUM_SYS_INIT_PACKETS 8 -+ -+#define SYS_INIT_PKT_SIZE (sizeof(struct iris_hfi_header) + \ -+ NUM_SYS_INIT_PACKETS * (sizeof(struct iris_hfi_packet) + sizeof(u32))) -+ -+#define SYS_IFPC_PKT_SIZE (sizeof(struct iris_hfi_header) + \ -+ sizeof(struct iris_hfi_packet) + sizeof(u32)) -+ -+#define SYS_NO_PAYLOAD_PKT_SIZE (sizeof(struct iris_hfi_header) + \ -+ sizeof(struct iris_hfi_packet)) -+ -+static int iris_hfi_gen2_sys_init(struct iris_core *core) -+{ -+ struct iris_hfi_header *hdr; -+ int ret; -+ -+ hdr = kzalloc(SYS_INIT_PKT_SIZE, GFP_KERNEL); -+ if (!hdr) -+ return -ENOMEM; -+ -+ iris_hfi_gen2_packet_sys_init(core, hdr); -+ ret = iris_hfi_queue_cmd_write_locked(core, hdr, hdr->size); -+ -+ kfree(hdr); -+ -+ return ret; -+} -+ -+static int iris_hfi_gen2_sys_image_version(struct iris_core *core) -+{ -+ struct iris_hfi_header *hdr; -+ int ret; -+ -+ hdr = kzalloc(SYS_NO_PAYLOAD_PKT_SIZE, GFP_KERNEL); -+ if (!hdr) -+ return -ENOMEM; -+ -+ iris_hfi_gen2_packet_image_version(core, hdr); -+ ret = iris_hfi_queue_cmd_write_locked(core, hdr, hdr->size); -+ -+ kfree(hdr); -+ -+ return ret; -+} -+ -+static int iris_hfi_gen2_sys_interframe_powercollapse(struct iris_core *core) -+{ -+ struct iris_hfi_header *hdr; -+ int ret; -+ -+ hdr = kzalloc(SYS_IFPC_PKT_SIZE, GFP_KERNEL); -+ if (!hdr) -+ return -ENOMEM; -+ -+ iris_hfi_gen2_packet_sys_interframe_powercollapse(core, hdr); -+ ret = iris_hfi_queue_cmd_write_locked(core, hdr, hdr->size); -+ -+ kfree(hdr); -+ -+ return ret; -+} -+ -+static const struct iris_hfi_command_ops iris_hfi_gen2_command_ops = { -+ .sys_init = iris_hfi_gen2_sys_init, -+ .sys_image_version = iris_hfi_gen2_sys_image_version, -+ .sys_interframe_powercollapse = iris_hfi_gen2_sys_interframe_powercollapse, -+}; -+ -+void iris_hfi_gen2_command_ops_init(struct iris_core *core) -+{ -+ core->hfi_ops = &iris_hfi_gen2_command_ops; -+} - - struct iris_inst *iris_hfi_gen2_get_instance(void) - { -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h -new file mode 100644 -index 000000000000..2640caa7f9c0 ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h -@@ -0,0 +1,46 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#ifndef __IRIS_HFI_GEN2_DEFINES_H__ -+#define __IRIS_HFI_GEN2_DEFINES_H__ -+ -+#include -+ -+#define HFI_VIDEO_ARCH_LX 0x1 -+ -+#define HFI_CMD_BEGIN 0x01000000 -+#define HFI_CMD_INIT 0x01000001 -+#define HFI_CMD_END 0x01FFFFFF -+ -+#define HFI_PROP_BEGIN 0x03000000 -+#define HFI_PROP_IMAGE_VERSION 0x03000001 -+#define HFI_PROP_INTRA_FRAME_POWER_COLLAPSE 0x03000002 -+#define HFI_PROP_UBWC_MAX_CHANNELS 0x03000003 -+#define HFI_PROP_UBWC_MAL_LENGTH 0x03000004 -+#define HFI_PROP_UBWC_HBB 0x03000005 -+#define HFI_PROP_UBWC_BANK_SWZL_LEVEL1 0x03000006 -+#define HFI_PROP_UBWC_BANK_SWZL_LEVEL2 0x03000007 -+#define HFI_PROP_UBWC_BANK_SWZL_LEVEL3 0x03000008 -+#define HFI_PROP_UBWC_BANK_SPREADING 0x03000009 -+#define HFI_PROP_END 0x03FFFFFF -+ -+#define HFI_SYSTEM_ERROR_BEGIN 0x05000000 -+#define HFI_SYS_ERROR_WD_TIMEOUT 0x05000001 -+#define HFI_SYSTEM_ERROR_END 0x05FFFFFF -+ -+enum hfi_packet_firmware_flags { -+ HFI_FW_FLAGS_SUCCESS = 0x00000001, -+ HFI_FW_FLAGS_INFORMATION = 0x00000002, -+ HFI_FW_FLAGS_SESSION_ERROR = 0x00000004, -+ HFI_FW_FLAGS_SYSTEM_ERROR = 0x00000008, -+}; -+ -+struct hfi_debug_header { -+ u32 size; -+ u32 debug_level; -+ u32 reserved[2]; -+}; -+ -+#endif -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.c -new file mode 100644 -index 000000000000..986013aa62df ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.c -@@ -0,0 +1,161 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#include "iris_hfi_common.h" -+#include "iris_hfi_gen2.h" -+#include "iris_hfi_gen2_packet.h" -+ -+static void iris_hfi_gen2_create_header(struct iris_hfi_header *hdr, -+ u32 session_id, u32 header_id) -+{ -+ memset(hdr, 0, sizeof(*hdr)); -+ -+ hdr->size = sizeof(*hdr); -+ hdr->session_id = session_id; -+ hdr->header_id = header_id; -+ hdr->num_packets = 0; -+} -+ -+static void iris_hfi_gen2_create_packet(struct iris_hfi_header *hdr, u32 pkt_type, -+ u32 pkt_flags, u32 payload_type, u32 port, -+ u32 packet_id, void *payload, u32 payload_size) -+{ -+ struct iris_hfi_packet *pkt = (struct iris_hfi_packet *)((u8 *)hdr + hdr->size); -+ u32 pkt_size = sizeof(*pkt) + payload_size; -+ -+ memset(pkt, 0, pkt_size); -+ pkt->size = pkt_size; -+ pkt->type = pkt_type; -+ pkt->flags = pkt_flags; -+ pkt->payload_info = payload_type; -+ pkt->port = port; -+ pkt->packet_id = packet_id; -+ if (payload_size) -+ memcpy(&pkt->payload[0], payload, payload_size); -+ -+ hdr->num_packets++; -+ hdr->size += pkt->size; -+} -+ -+void iris_hfi_gen2_packet_sys_init(struct iris_core *core, struct iris_hfi_header *hdr) -+{ -+ u32 payload = 0; -+ -+ iris_hfi_gen2_create_header(hdr, 0, core->header_id++); -+ -+ payload = HFI_VIDEO_ARCH_LX; -+ iris_hfi_gen2_create_packet(hdr, -+ HFI_CMD_INIT, -+ (HFI_HOST_FLAGS_RESPONSE_REQUIRED | -+ HFI_HOST_FLAGS_INTR_REQUIRED | -+ HFI_HOST_FLAGS_NON_DISCARDABLE), -+ HFI_PAYLOAD_U32, -+ HFI_PORT_NONE, -+ core->packet_id++, -+ &payload, -+ sizeof(u32)); -+ -+ payload = core->iris_platform_data->ubwc_config->max_channels; -+ iris_hfi_gen2_create_packet(hdr, -+ HFI_PROP_UBWC_MAX_CHANNELS, -+ HFI_HOST_FLAGS_NONE, -+ HFI_PAYLOAD_U32, -+ HFI_PORT_NONE, -+ core->packet_id++, -+ &payload, -+ sizeof(u32)); -+ -+ payload = core->iris_platform_data->ubwc_config->mal_length; -+ iris_hfi_gen2_create_packet(hdr, -+ HFI_PROP_UBWC_MAL_LENGTH, -+ HFI_HOST_FLAGS_NONE, -+ HFI_PAYLOAD_U32, -+ HFI_PORT_NONE, -+ core->packet_id++, -+ &payload, -+ sizeof(u32)); -+ -+ payload = core->iris_platform_data->ubwc_config->highest_bank_bit; -+ iris_hfi_gen2_create_packet(hdr, -+ HFI_PROP_UBWC_HBB, -+ HFI_HOST_FLAGS_NONE, -+ HFI_PAYLOAD_U32, -+ HFI_PORT_NONE, -+ core->packet_id++, -+ &payload, -+ sizeof(u32)); -+ -+ payload = core->iris_platform_data->ubwc_config->bank_swzl_level; -+ iris_hfi_gen2_create_packet(hdr, -+ HFI_PROP_UBWC_BANK_SWZL_LEVEL1, -+ HFI_HOST_FLAGS_NONE, -+ HFI_PAYLOAD_U32, -+ HFI_PORT_NONE, -+ core->packet_id++, -+ &payload, -+ sizeof(u32)); -+ -+ payload = core->iris_platform_data->ubwc_config->bank_swz2_level; -+ iris_hfi_gen2_create_packet(hdr, -+ HFI_PROP_UBWC_BANK_SWZL_LEVEL2, -+ HFI_HOST_FLAGS_NONE, -+ HFI_PAYLOAD_U32, -+ HFI_PORT_NONE, -+ core->packet_id++, -+ &payload, -+ sizeof(u32)); -+ -+ payload = core->iris_platform_data->ubwc_config->bank_swz3_level; -+ iris_hfi_gen2_create_packet(hdr, -+ HFI_PROP_UBWC_BANK_SWZL_LEVEL3, -+ HFI_HOST_FLAGS_NONE, -+ HFI_PAYLOAD_U32, -+ HFI_PORT_NONE, -+ core->packet_id++, -+ &payload, -+ sizeof(u32)); -+ -+ payload = core->iris_platform_data->ubwc_config->bank_spreading; -+ iris_hfi_gen2_create_packet(hdr, -+ HFI_PROP_UBWC_BANK_SPREADING, -+ HFI_HOST_FLAGS_NONE, -+ HFI_PAYLOAD_U32, -+ HFI_PORT_NONE, -+ core->packet_id++, -+ &payload, -+ sizeof(u32)); -+} -+ -+void iris_hfi_gen2_packet_image_version(struct iris_core *core, struct iris_hfi_header *hdr) -+{ -+ iris_hfi_gen2_create_header(hdr, 0, core->header_id++); -+ -+ iris_hfi_gen2_create_packet(hdr, -+ HFI_PROP_IMAGE_VERSION, -+ (HFI_HOST_FLAGS_RESPONSE_REQUIRED | -+ HFI_HOST_FLAGS_INTR_REQUIRED | -+ HFI_HOST_FLAGS_GET_PROPERTY), -+ HFI_PAYLOAD_NONE, -+ HFI_PORT_NONE, -+ core->packet_id++, -+ NULL, 0); -+} -+ -+void iris_hfi_gen2_packet_sys_interframe_powercollapse(struct iris_core *core, -+ struct iris_hfi_header *hdr) -+{ -+ u32 payload = 1; /* HFI_TRUE */ -+ -+ iris_hfi_gen2_create_header(hdr, 0 /*session_id*/, core->header_id++); -+ -+ iris_hfi_gen2_create_packet(hdr, -+ HFI_PROP_INTRA_FRAME_POWER_COLLAPSE, -+ HFI_HOST_FLAGS_NONE, -+ HFI_PAYLOAD_U32, -+ HFI_PORT_NONE, -+ core->packet_id++, -+ &payload, -+ sizeof(u32)); -+} -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.h b/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.h -new file mode 100644 -index 000000000000..10dcb6e4c3d9 ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.h -@@ -0,0 +1,69 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#ifndef __IRIS_HFI_GEN2_PACKET_H__ -+#define __IRIS_HFI_GEN2_PACKET_H__ -+ -+#include "iris_hfi_gen2_defines.h" -+ -+struct iris_core; -+ -+/** -+ * struct iris_hfi_header -+ * -+ * @size: size of the total packet in bytes including hfi_header -+ * @session_id: For session level hfi_header session_id is non-zero. -+ * For system level hfi_header session_id is zero. -+ * @header_id: unique header id for each hfi_header -+ * @reserved: reserved for future use -+ * @num_packets: number of hfi_packet that are included with the hfi_header -+ */ -+struct iris_hfi_header { -+ u32 size; -+ u32 session_id; -+ u32 header_id; -+ u32 reserved[4]; -+ u32 num_packets; -+}; -+ -+/** -+ * struct iris_hfi_packet -+ * -+ * @size: size of the hfi_packet in bytes including payload -+ * @type: one of the below hfi_packet types: -+ * HFI_CMD_*, -+ * HFI_PROP_*, -+ * HFI_ERROR_*, -+ * HFI_INFO_*, -+ * HFI_SYS_ERROR_* -+ * @flags: hfi_packet flags. It is represented as bit masks. -+ * host packet flags are "enum hfi_packet_host_flags" -+ * firmware packet flags are "enum hfi_packet_firmware_flags" -+ * @payload_info: payload information indicated by "enum hfi_packet_payload_info" -+ * @port: hfi_packet port type indicated by "enum hfi_packet_port_type" -+ * This is bitmask and may be applicable to multiple ports. -+ * @packet_id: host hfi_packet contains unique packet id. -+ * firmware returns host packet id in response packet -+ * wherever applicable. If not applicable firmware sets it to zero. -+ * @reserved: reserved for future use. -+ * @payload: flexible array of payload having additional packet information. -+ */ -+struct iris_hfi_packet { -+ u32 size; -+ u32 type; -+ u32 flags; -+ u32 payload_info; -+ u32 port; -+ u32 packet_id; -+ u32 reserved[2]; -+ u32 payload[]; -+}; -+ -+void iris_hfi_gen2_packet_sys_init(struct iris_core *core, struct iris_hfi_header *hdr); -+void iris_hfi_gen2_packet_image_version(struct iris_core *core, struct iris_hfi_header *hdr); -+void iris_hfi_gen2_packet_sys_interframe_powercollapse(struct iris_core *core, -+ struct iris_hfi_header *hdr); -+ -+#endif -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c -new file mode 100644 -index 000000000000..007e4a7b6782 ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c -@@ -0,0 +1,215 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#include "iris_hfi_gen2.h" -+#include "iris_hfi_gen2_defines.h" -+#include "iris_hfi_gen2_packet.h" -+#include "iris_vpu_common.h" -+ -+struct iris_hfi_gen2_core_hfi_range { -+ u32 begin; -+ u32 end; -+ int (*handle)(struct iris_core *core, struct iris_hfi_packet *pkt); -+}; -+ -+static int iris_hfi_gen2_validate_packet(u8 *response_pkt, u8 *core_resp_pkt) -+{ -+ u8 *response_limit = core_resp_pkt + IFACEQ_CORE_PKT_SIZE; -+ u32 response_pkt_size = *(u32 *)response_pkt; -+ -+ if (!response_pkt_size) -+ return -EINVAL; -+ -+ if (response_pkt_size < sizeof(struct iris_hfi_packet)) -+ return -EINVAL; -+ -+ if (response_pkt + response_pkt_size > response_limit) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+static int iris_hfi_gen2_validate_hdr_packet(struct iris_core *core, struct iris_hfi_header *hdr) -+{ -+ struct iris_hfi_packet *packet; -+ int ret; -+ u8 *pkt; -+ u32 i; -+ -+ if (hdr->size < sizeof(*hdr) + sizeof(*packet)) -+ return -EINVAL; -+ -+ pkt = (u8 *)((u8 *)hdr + sizeof(*hdr)); -+ -+ for (i = 0; i < hdr->num_packets; i++) { -+ packet = (struct iris_hfi_packet *)pkt; -+ ret = iris_hfi_gen2_validate_packet(pkt, core->response_packet); -+ if (ret) -+ return ret; -+ -+ pkt += packet->size; -+ } -+ -+ return 0; -+} -+ -+static int iris_hfi_gen2_handle_system_error(struct iris_core *core, -+ struct iris_hfi_packet *pkt) -+{ -+ dev_err(core->dev, "received system error of type %#x\n", pkt->type); -+ -+ core->state = IRIS_CORE_ERROR; -+ schedule_delayed_work(&core->sys_error_handler, msecs_to_jiffies(10)); -+ -+ return 0; -+} -+ -+static int iris_hfi_gen2_handle_system_init(struct iris_core *core, -+ struct iris_hfi_packet *pkt) -+{ -+ if (!(pkt->flags & HFI_FW_FLAGS_SUCCESS)) { -+ core->state = IRIS_CORE_ERROR; -+ return 0; -+ } -+ -+ complete(&core->core_init_done); -+ -+ return 0; -+} -+ -+static int iris_hfi_gen2_handle_image_version_property(struct iris_core *core, -+ struct iris_hfi_packet *pkt) -+{ -+ u8 *str_image_version = (u8 *)pkt + sizeof(*pkt); -+ u32 req_bytes = pkt->size - sizeof(*pkt); -+ char fw_version[IRIS_FW_VERSION_LENGTH]; -+ u32 i; -+ -+ if (req_bytes < IRIS_FW_VERSION_LENGTH - 1) -+ return -EINVAL; -+ -+ for (i = 0; i < IRIS_FW_VERSION_LENGTH - 1; i++) { -+ if (str_image_version[i] != '\0') -+ fw_version[i] = str_image_version[i]; -+ else -+ fw_version[i] = ' '; -+ } -+ fw_version[i] = '\0'; -+ dev_dbg(core->dev, "firmware version: %s\n", fw_version); -+ -+ return 0; -+} -+ -+static int iris_hfi_gen2_handle_system_property(struct iris_core *core, -+ struct iris_hfi_packet *pkt) -+{ -+ switch (pkt->type) { -+ case HFI_PROP_IMAGE_VERSION: -+ return iris_hfi_gen2_handle_image_version_property(core, pkt); -+ default: -+ return 0; -+ } -+} -+ -+static int iris_hfi_gen2_handle_system_response(struct iris_core *core, -+ struct iris_hfi_header *hdr) -+{ -+ u8 *start_pkt = (u8 *)((u8 *)hdr + sizeof(*hdr)); -+ struct iris_hfi_packet *packet; -+ u32 i, j; -+ u8 *pkt; -+ int ret; -+ static const struct iris_hfi_gen2_core_hfi_range range[] = { -+ {HFI_SYSTEM_ERROR_BEGIN, HFI_SYSTEM_ERROR_END, iris_hfi_gen2_handle_system_error }, -+ {HFI_PROP_BEGIN, HFI_PROP_END, iris_hfi_gen2_handle_system_property }, -+ {HFI_CMD_BEGIN, HFI_CMD_END, iris_hfi_gen2_handle_system_init }, -+ }; -+ -+ for (i = 0; i < ARRAY_SIZE(range); i++) { -+ pkt = start_pkt; -+ for (j = 0; j < hdr->num_packets; j++) { -+ packet = (struct iris_hfi_packet *)pkt; -+ if (packet->flags & HFI_FW_FLAGS_SYSTEM_ERROR) { -+ ret = iris_hfi_gen2_handle_system_error(core, packet); -+ return ret; -+ } -+ -+ if (packet->type > range[i].begin && packet->type < range[i].end) { -+ ret = range[i].handle(core, packet); -+ if (ret) -+ return ret; -+ -+ if (packet->type > HFI_SYSTEM_ERROR_BEGIN && -+ packet->type < HFI_SYSTEM_ERROR_END) -+ return 0; -+ } -+ pkt += packet->size; -+ } -+ } -+ -+ return 0; -+} -+ -+static int iris_hfi_gen2_handle_response(struct iris_core *core, void *response) -+{ -+ struct iris_hfi_header *hdr = (struct iris_hfi_header *)response; -+ int ret; -+ -+ ret = iris_hfi_gen2_validate_hdr_packet(core, hdr); -+ if (ret) -+ return iris_hfi_gen2_handle_system_error(core, NULL); -+ -+ return iris_hfi_gen2_handle_system_response(core, hdr); -+} -+ -+static void iris_hfi_gen2_flush_debug_queue(struct iris_core *core, u8 *packet) -+{ -+ struct hfi_debug_header *pkt; -+ u8 *log; -+ -+ while (!iris_hfi_queue_dbg_read(core, packet)) { -+ pkt = (struct hfi_debug_header *)packet; -+ -+ if (pkt->size < sizeof(*pkt)) -+ continue; -+ -+ if (pkt->size >= IFACEQ_CORE_PKT_SIZE) -+ continue; -+ -+ packet[pkt->size] = '\0'; -+ log = (u8 *)packet + sizeof(*pkt) + 1; -+ dev_dbg(core->dev, "%s", log); -+ } -+} -+ -+static void iris_hfi_gen2_response_handler(struct iris_core *core) -+{ -+ if (iris_vpu_watchdog(core, core->intr_status)) { -+ struct iris_hfi_packet pkt = {.type = HFI_SYS_ERROR_WD_TIMEOUT}; -+ -+ dev_err(core->dev, "cpu watchdog error received\n"); -+ core->state = IRIS_CORE_ERROR; -+ iris_hfi_gen2_handle_system_error(core, &pkt); -+ -+ return; -+ } -+ -+ memset(core->response_packet, 0, sizeof(struct iris_hfi_header)); -+ while (!iris_hfi_queue_msg_read(core, core->response_packet)) { -+ iris_hfi_gen2_handle_response(core, core->response_packet); -+ memset(core->response_packet, 0, sizeof(struct iris_hfi_header)); -+ } -+ -+ iris_hfi_gen2_flush_debug_queue(core, core->response_packet); -+} -+ -+static const struct iris_hfi_response_ops iris_hfi_gen2_response_ops = { -+ .hfi_response_handler = iris_hfi_gen2_response_handler, -+}; -+ -+void iris_hfi_gen2_response_ops_init(struct iris_core *core) -+{ -+ core->hfi_response_ops = &iris_hfi_gen2_response_ops; -+} -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_queue.c b/drivers/media/platform/qcom/iris/iris_hfi_queue.c -index 494ef205133d..ee245c540ce7 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_queue.c -+++ b/drivers/media/platform/qcom/iris/iris_hfi_queue.c -@@ -5,6 +5,179 @@ - - #include "iris_core.h" - #include "iris_hfi_queue.h" -+#include "iris_vpu_common.h" -+ -+static int iris_hfi_queue_write(struct iris_iface_q_info *qinfo, void *packet, u32 packet_size) -+{ -+ struct iris_hfi_queue_header *queue = qinfo->qhdr; -+ u32 write_idx = queue->write_idx * sizeof(u32); -+ u32 read_idx = queue->read_idx * sizeof(u32); -+ u32 empty_space, new_write_idx, residue; -+ u32 *write_ptr; -+ -+ if (write_idx < read_idx) -+ empty_space = read_idx - write_idx; -+ else -+ empty_space = IFACEQ_QUEUE_SIZE - (write_idx - read_idx); -+ if (empty_space < packet_size) -+ return -ENOSPC; -+ -+ queue->tx_req = 0; -+ -+ new_write_idx = write_idx + packet_size; -+ write_ptr = (u32 *)((u8 *)qinfo->kernel_vaddr + write_idx); -+ -+ if (write_ptr < (u32 *)qinfo->kernel_vaddr || -+ write_ptr > (u32 *)(qinfo->kernel_vaddr + -+ IFACEQ_QUEUE_SIZE)) -+ return -EINVAL; -+ -+ if (new_write_idx < IFACEQ_QUEUE_SIZE) { -+ memcpy(write_ptr, packet, packet_size); -+ } else { -+ residue = new_write_idx - IFACEQ_QUEUE_SIZE; -+ memcpy(write_ptr, packet, (packet_size - residue)); -+ memcpy(qinfo->kernel_vaddr, -+ packet + (packet_size - residue), residue); -+ new_write_idx = residue; -+ } -+ -+ /* Make sure packet is written before updating the write index */ -+ mb(); -+ queue->write_idx = new_write_idx / sizeof(u32); -+ -+ /* Make sure write index is updated before an interrupt is raised */ -+ mb(); -+ -+ return 0; -+} -+ -+static int iris_hfi_queue_read(struct iris_iface_q_info *qinfo, void *packet) -+{ -+ struct iris_hfi_queue_header *queue = qinfo->qhdr; -+ u32 write_idx = queue->write_idx * sizeof(u32); -+ u32 read_idx = queue->read_idx * sizeof(u32); -+ u32 packet_size, receive_request = 0; -+ u32 new_read_idx, residue; -+ u32 *read_ptr; -+ int ret = 0; -+ -+ if (queue->queue_type == IFACEQ_MSGQ_ID) -+ receive_request = 1; -+ -+ if (read_idx == write_idx) { -+ queue->rx_req = receive_request; -+ /* Ensure qhdr is updated in main memory */ -+ mb(); -+ return -ENODATA; -+ } -+ -+ read_ptr = qinfo->kernel_vaddr + read_idx; -+ if (read_ptr < (u32 *)qinfo->kernel_vaddr || -+ read_ptr > (u32 *)(qinfo->kernel_vaddr + -+ IFACEQ_QUEUE_SIZE - sizeof(*read_ptr))) -+ return -ENODATA; -+ -+ packet_size = *read_ptr; -+ if (!packet_size) -+ return -EINVAL; -+ -+ new_read_idx = read_idx + packet_size; -+ if (packet_size <= IFACEQ_CORE_PKT_SIZE) { -+ if (new_read_idx < IFACEQ_QUEUE_SIZE) { -+ memcpy(packet, read_ptr, packet_size); -+ } else { -+ residue = new_read_idx - IFACEQ_QUEUE_SIZE; -+ memcpy(packet, read_ptr, (packet_size - residue)); -+ memcpy((packet + (packet_size - residue)), -+ qinfo->kernel_vaddr, residue); -+ new_read_idx = residue; -+ } -+ } else { -+ new_read_idx = write_idx; -+ ret = -EBADMSG; -+ } -+ -+ queue->rx_req = receive_request; -+ -+ queue->read_idx = new_read_idx / sizeof(u32); -+ /* Ensure qhdr is updated in main memory */ -+ mb(); -+ -+ return ret; -+} -+ -+int iris_hfi_queue_cmd_write_locked(struct iris_core *core, void *pkt, u32 pkt_size) -+{ -+ struct iris_iface_q_info *q_info = &core->command_queue; -+ -+ if (core->state == IRIS_CORE_ERROR) -+ return -EINVAL; -+ -+ if (!iris_hfi_queue_write(q_info, pkt, pkt_size)) { -+ iris_vpu_raise_interrupt(core); -+ } else { -+ dev_err(core->dev, "queue full\n"); -+ return -ENODATA; -+ } -+ -+ return 0; -+} -+ -+int iris_hfi_queue_cmd_write(struct iris_core *core, void *pkt, u32 pkt_size) -+{ -+ int ret; -+ -+ mutex_lock(&core->lock); -+ ret = iris_hfi_queue_cmd_write_locked(core, pkt, pkt_size); -+ mutex_unlock(&core->lock); -+ -+ return ret; -+} -+ -+int iris_hfi_queue_msg_read(struct iris_core *core, void *pkt) -+{ -+ struct iris_iface_q_info *q_info = &core->message_queue; -+ int ret = 0; -+ -+ mutex_lock(&core->lock); -+ if (core->state != IRIS_CORE_INIT) { -+ ret = -EINVAL; -+ goto unlock; -+ } -+ -+ if (iris_hfi_queue_read(q_info, pkt)) { -+ ret = -ENODATA; -+ goto unlock; -+ } -+ -+unlock: -+ mutex_unlock(&core->lock); -+ -+ return ret; -+} -+ -+int iris_hfi_queue_dbg_read(struct iris_core *core, void *pkt) -+{ -+ struct iris_iface_q_info *q_info = &core->debug_queue; -+ int ret = 0; -+ -+ mutex_lock(&core->lock); -+ if (core->state != IRIS_CORE_INIT) { -+ ret = -EINVAL; -+ goto unlock; -+ } -+ -+ if (iris_hfi_queue_read(q_info, pkt)) { -+ ret = -ENODATA; -+ goto unlock; -+ } -+ -+unlock: -+ mutex_unlock(&core->lock); -+ -+ return ret; -+} - - static void iris_hfi_queue_set_header(struct iris_core *core, u32 queue_id, - struct iris_iface_q_info *iface_q) -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_queue.h b/drivers/media/platform/qcom/iris/iris_hfi_queue.h -index 99a3b83d063f..2174fc5ce618 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_queue.h -+++ b/drivers/media/platform/qcom/iris/iris_hfi_queue.h -@@ -174,4 +174,9 @@ struct iris_iface_q_info { - int iris_hfi_queues_init(struct iris_core *core); - void iris_hfi_queues_deinit(struct iris_core *core); - -+int iris_hfi_queue_cmd_write_locked(struct iris_core *core, void *pkt, u32 pkt_size); -+int iris_hfi_queue_cmd_write(struct iris_core *core, void *pkt, u32 pkt_size); -+int iris_hfi_queue_msg_read(struct iris_core *core, void *pkt); -+int iris_hfi_queue_dbg_read(struct iris_core *core, void *pkt); -+ - #endif -diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h -index 7e661e8928bd..adf639d1a109 100644 ---- a/drivers/media/platform/qcom/iris/iris_platform_common.h -+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h -@@ -6,7 +6,10 @@ - #ifndef __IRIS_PLATFORM_COMMON_H__ - #define __IRIS_PLATFORM_COMMON_H__ - -+struct iris_core; -+ - #define IRIS_PAS_ID 9 -+#define HW_RESPONSE_TIMEOUT_VALUE (1000) /* milliseconds */ - - extern struct iris_platform_data sm8550_data; - -@@ -28,7 +31,19 @@ struct tz_cp_config { - u32 cp_nonpixel_size; - }; - -+struct ubwc_config_data { -+ u32 max_channels; -+ u32 mal_length; -+ u32 highest_bank_bit; -+ u32 bank_swzl_level; -+ u32 bank_swz2_level; -+ u32 bank_swz3_level; -+ u32 bank_spreading; -+}; -+ - struct iris_platform_data { -+ void (*init_hfi_command_ops)(struct iris_core *core); -+ void (*init_hfi_response_ops)(struct iris_core *core); - struct iris_inst *(*get_instance)(void); - const struct icc_info *icc_tbl; - unsigned int icc_tbl_size; -@@ -45,6 +60,8 @@ struct iris_platform_data { - u32 pas_id; - struct tz_cp_config *tz_cp_config_data; - u32 core_arch; -+ u32 hw_response_timeout; -+ struct ubwc_config_data *ubwc_config; - }; - - #endif -diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c -index 237f932946d6..30d9664bd419 100644 ---- a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c -+++ b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c -@@ -26,6 +26,16 @@ static const struct platform_clk_data sm8550_clk_table[] = { - {IRIS_HW_CLK, "vcodec0_core" }, - }; - -+static struct ubwc_config_data ubwc_config_sm8550 = { -+ .max_channels = 8, -+ .mal_length = 32, -+ .highest_bank_bit = 16, -+ .bank_swzl_level = 0, -+ .bank_swz2_level = 1, -+ .bank_swz3_level = 1, -+ .bank_spreading = 1, -+}; -+ - static struct tz_cp_config tz_cp_config_sm8550 = { - .cp_start = 0, - .cp_size = 0x25800000, -@@ -35,6 +45,8 @@ static struct tz_cp_config tz_cp_config_sm8550 = { - - struct iris_platform_data sm8550_data = { - .get_instance = iris_hfi_gen2_get_instance, -+ .init_hfi_command_ops = iris_hfi_gen2_command_ops_init, -+ .init_hfi_response_ops = iris_hfi_gen2_response_ops_init, - .icc_tbl = sm8550_icc_table, - .icc_tbl_size = ARRAY_SIZE(sm8550_icc_table), - .clk_rst_tbl = sm8550_clk_reset_table, -@@ -51,4 +63,6 @@ struct iris_platform_data sm8550_data = { - .pas_id = IRIS_PAS_ID, - .tz_cp_config_data = &tz_cp_config_sm8550, - .core_arch = VIDEO_ARCH_LX, -+ .hw_response_timeout = HW_RESPONSE_TIMEOUT_VALUE, -+ .ubwc_config = &ubwc_config_sm8550, - }; -diff --git a/drivers/media/platform/qcom/iris/iris_probe.c b/drivers/media/platform/qcom/iris/iris_probe.c -index 3015e6cb347f..02887b3dbe0e 100644 ---- a/drivers/media/platform/qcom/iris/iris_probe.c -+++ b/drivers/media/platform/qcom/iris/iris_probe.c -@@ -177,6 +177,15 @@ static void iris_remove(struct platform_device *pdev) - mutex_destroy(&core->lock); - } - -+static void iris_sys_error_handler(struct work_struct *work) -+{ -+ struct iris_core *core = -+ container_of(work, struct iris_core, sys_error_handler.work); -+ -+ iris_core_deinit(core); -+ iris_core_init(core); -+} -+ - static int iris_probe(struct platform_device *pdev) - { - struct device *dev = &pdev->dev; -@@ -191,6 +200,13 @@ static int iris_probe(struct platform_device *pdev) - - core->state = IRIS_CORE_DEINIT; - mutex_init(&core->lock); -+ init_completion(&core->core_init_done); -+ -+ core->response_packet = devm_kzalloc(core->dev, IFACEQ_CORE_PKT_SIZE, GFP_KERNEL); -+ if (!core->response_packet) -+ return -ENOMEM; -+ -+ INIT_DELAYED_WORK(&core->sys_error_handler, iris_sys_error_handler); - - core->reg_base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(core->reg_base)) -@@ -202,7 +218,17 @@ static int iris_probe(struct platform_device *pdev) - - core->iris_platform_data = of_device_get_match_data(core->dev); - -+ ret = devm_request_threaded_irq(core->dev, core->irq, iris_hfi_isr, -+ iris_hfi_isr_handler, IRQF_TRIGGER_HIGH, "iris", core); -+ if (ret) -+ return ret; -+ -+ disable_irq_nosync(core->irq); -+ - iris_init_ops(core); -+ core->iris_platform_data->init_hfi_command_ops(core); -+ core->iris_platform_data->init_hfi_response_ops(core); -+ - ret = iris_init_resources(core); - if (ret) - return ret; -diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.c b/drivers/media/platform/qcom/iris/iris_vpu_common.c -index 959ed46e8f47..34817573f61b 100644 ---- a/drivers/media/platform/qcom/iris/iris_vpu_common.c -+++ b/drivers/media/platform/qcom/iris/iris_vpu_common.c -@@ -11,10 +11,15 @@ - #define CPU_BASE_OFFS 0x000A0000 - - #define CPU_CS_BASE_OFFS (CPU_BASE_OFFS) -+#define CPU_IC_BASE_OFFS (CPU_BASE_OFFS) -+ -+#define CPU_CS_A2HSOFTINTCLR (CPU_CS_BASE_OFFS + 0x1C) -+#define CLEAR_XTENSA2HOST_INTR BIT(0) - - #define CTRL_INIT (CPU_CS_BASE_OFFS + 0x48) - #define CTRL_STATUS (CPU_CS_BASE_OFFS + 0x4C) - -+#define CTRL_INIT_IDLE_MSG_BMSK 0x40000000 - #define CTRL_ERROR_STATUS__M 0xfe - - #define QTBL_INFO (CPU_CS_BASE_OFFS + 0x50) -@@ -31,6 +36,14 @@ - - #define CPU_CS_X2RPMH (CPU_CS_BASE_OFFS + 0x168) - -+#define CPU_IC_SOFTINT (CPU_IC_BASE_OFFS + 0x150) -+#define CPU_IC_SOFTINT_H2A_SHFT 0x0 -+ -+#define WRAPPER_BASE_OFFS 0x000B0000 -+#define WRAPPER_INTR_STATUS (WRAPPER_BASE_OFFS + 0x0C) -+#define WRAPPER_INTR_STATUS_A2HWD_BMSK BIT(3) -+#define WRAPPER_INTR_STATUS_A2H_BMSK BIT(2) -+ - static void iris_vpu_setup_ucregion_memory_map(struct iris_core *core) - { - u32 queue_size, value; -@@ -87,3 +100,33 @@ int iris_vpu_boot_firmware(struct iris_core *core) - - return 0; - } -+ -+void iris_vpu_raise_interrupt(struct iris_core *core) -+{ -+ writel(1 << CPU_IC_SOFTINT_H2A_SHFT, core->reg_base + CPU_IC_SOFTINT); -+} -+ -+void iris_vpu_clear_interrupt(struct iris_core *core) -+{ -+ u32 intr_status, mask; -+ -+ intr_status = readl(core->reg_base + WRAPPER_INTR_STATUS); -+ mask = (WRAPPER_INTR_STATUS_A2H_BMSK | -+ WRAPPER_INTR_STATUS_A2HWD_BMSK | -+ CTRL_INIT_IDLE_MSG_BMSK); -+ -+ if (intr_status & mask) -+ core->intr_status |= intr_status; -+ -+ writel(CLEAR_XTENSA2HOST_INTR, core->reg_base + CPU_CS_A2HSOFTINTCLR); -+} -+ -+int iris_vpu_watchdog(struct iris_core *core, u32 intr_status) -+{ -+ if (intr_status & WRAPPER_INTR_STATUS_A2HWD_BMSK) { -+ dev_err(core->dev, "received watchdog interrupt\n"); -+ return -ETIME; -+ } -+ -+ return 0; -+} -diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.h b/drivers/media/platform/qcom/iris/iris_vpu_common.h -index bafcf46520fd..c38c055d3d14 100644 ---- a/drivers/media/platform/qcom/iris/iris_vpu_common.h -+++ b/drivers/media/platform/qcom/iris/iris_vpu_common.h -@@ -9,5 +9,8 @@ - struct iris_core; - - int iris_vpu_boot_firmware(struct iris_core *core); -+void iris_vpu_raise_interrupt(struct iris_core *core); -+void iris_vpu_clear_interrupt(struct iris_core *core); -+int iris_vpu_watchdog(struct iris_core *core, u32 intr_status); - - #endif --- -2.34.1 - diff --git a/patch/kernel/archive/sm8550-6.12/0008_media--iris--implement-power-management.patch b/patch/kernel/archive/sm8550-6.12/0008_media--iris--implement-power-management.patch deleted file mode 100644 index 08f0e31d5537..000000000000 --- a/patch/kernel/archive/sm8550-6.12/0008_media--iris--implement-power-management.patch +++ /dev/null @@ -1,1246 +0,0 @@ -From 719a1fbd3dea369254d096d32ebdb3fbd9894bfa Mon Sep 17 00:00:00 2001 -From: Dikshita Agarwal -Date: Fri, 7 Feb 2025 13:24:48 +0530 -Subject: [PATCH] media: iris: implement power management - -Implement runtime power management for iris, including a platform -specific power on/off sequence. - -Tested-by: Stefan Schmidt # x1e80100 (Dell XPS 13 9345) -Reviewed-by: Stefan Schmidt -Tested-by: Neil Armstrong # on SM8550-QRD -Tested-by: Neil Armstrong # on SM8550-HDK -Signed-off-by: Dikshita Agarwal -Link: https://lore.kernel.org/r/20250207-qcom-video-iris-v10-8-ab66eeffbd20@quicinc.com -Signed-off-by: Neil Armstrong ---- - drivers/media/platform/qcom/iris/Makefile | 3 + - drivers/media/platform/qcom/iris/iris_core.c | 15 +- - drivers/media/platform/qcom/iris/iris_core.h | 4 + - .../media/platform/qcom/iris/iris_firmware.c | 5 + - .../media/platform/qcom/iris/iris_firmware.h | 1 + - .../platform/qcom/iris/iris_hfi_common.c | 62 +++++ - .../platform/qcom/iris/iris_hfi_common.h | 3 + - .../qcom/iris/iris_hfi_gen1_command.c | 11 + - .../qcom/iris/iris_hfi_gen1_defines.h | 5 + - .../qcom/iris/iris_hfi_gen2_command.c | 18 ++ - .../qcom/iris/iris_hfi_gen2_defines.h | 1 + - .../platform/qcom/iris/iris_hfi_gen2_packet.c | 13 + - .../platform/qcom/iris/iris_hfi_gen2_packet.h | 1 + - .../media/platform/qcom/iris/iris_hfi_queue.c | 18 ++ - .../platform/qcom/iris/iris_platform_common.h | 14 + - .../platform/qcom/iris/iris_platform_sm8550.c | 9 + - drivers/media/platform/qcom/iris/iris_probe.c | 53 ++++ - .../media/platform/qcom/iris/iris_resources.c | 131 ++++++++++ - .../media/platform/qcom/iris/iris_resources.h | 18 ++ - drivers/media/platform/qcom/iris/iris_vidc.c | 8 + - drivers/media/platform/qcom/iris/iris_vpu2.c | 11 + - drivers/media/platform/qcom/iris/iris_vpu3.c | 84 ++++++ - .../platform/qcom/iris/iris_vpu_common.c | 243 +++++++++++++++++- - .../platform/qcom/iris/iris_vpu_common.h | 11 + - .../qcom/iris/iris_vpu_register_defines.h | 17 ++ - 25 files changed, 755 insertions(+), 4 deletions(-) - create mode 100644 drivers/media/platform/qcom/iris/iris_resources.c - create mode 100644 drivers/media/platform/qcom/iris/iris_resources.h - create mode 100644 drivers/media/platform/qcom/iris/iris_vpu2.c - create mode 100644 drivers/media/platform/qcom/iris/iris_vpu3.c - create mode 100644 drivers/media/platform/qcom/iris/iris_vpu_register_defines.h - -diff --git a/drivers/media/platform/qcom/iris/Makefile b/drivers/media/platform/qcom/iris/Makefile -index 76ca5287c49f..a5f290a8c4af 100644 ---- a/drivers/media/platform/qcom/iris/Makefile -+++ b/drivers/media/platform/qcom/iris/Makefile -@@ -9,7 +9,10 @@ iris-objs += iris_core.o \ - iris_hfi_queue.o \ - iris_platform_sm8550.o \ - iris_probe.o \ -+ iris_resources.o \ - iris_vidc.o \ -+ iris_vpu2.o \ -+ iris_vpu3.o \ - iris_vpu_common.o \ - - obj-$(CONFIG_VIDEO_QCOM_IRIS) += iris.o -diff --git a/drivers/media/platform/qcom/iris/iris_core.c b/drivers/media/platform/qcom/iris/iris_core.c -index 7e19bdd0a19b..0fa0a3b549a2 100644 ---- a/drivers/media/platform/qcom/iris/iris_core.c -+++ b/drivers/media/platform/qcom/iris/iris_core.c -@@ -3,6 +3,8 @@ - * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. - */ - -+#include -+ - #include "iris_core.h" - #include "iris_firmware.h" - #include "iris_state.h" -@@ -10,11 +12,16 @@ - - void iris_core_deinit(struct iris_core *core) - { -+ pm_runtime_resume_and_get(core->dev); -+ - mutex_lock(&core->lock); - iris_fw_unload(core); -+ iris_vpu_power_off(core); - iris_hfi_queues_deinit(core); - core->state = IRIS_CORE_DEINIT; - mutex_unlock(&core->lock); -+ -+ pm_runtime_put_sync(core->dev); - } - - static int iris_wait_for_system_response(struct iris_core *core) -@@ -54,10 +61,14 @@ int iris_core_init(struct iris_core *core) - if (ret) - goto error; - -- ret = iris_fw_load(core); -+ ret = iris_vpu_power_on(core); - if (ret) - goto error_queue_deinit; - -+ ret = iris_fw_load(core); -+ if (ret) -+ goto error_power_off; -+ - ret = iris_vpu_boot_firmware(core); - if (ret) - goto error_unload_fw; -@@ -72,6 +83,8 @@ int iris_core_init(struct iris_core *core) - - error_unload_fw: - iris_fw_unload(core); -+error_power_off: -+ iris_vpu_power_off(core); - error_queue_deinit: - iris_hfi_queues_deinit(core); - error: -diff --git a/drivers/media/platform/qcom/iris/iris_core.h b/drivers/media/platform/qcom/iris/iris_core.h -index c0f3c189d779..58aab78ab2c4 100644 ---- a/drivers/media/platform/qcom/iris/iris_core.h -+++ b/drivers/media/platform/qcom/iris/iris_core.h -@@ -7,11 +7,13 @@ - #define __IRIS_CORE_H__ - - #include -+#include - #include - - #include "iris_hfi_common.h" - #include "iris_hfi_queue.h" - #include "iris_platform_common.h" -+#include "iris_resources.h" - #include "iris_state.h" - - struct icc_info { -@@ -52,6 +54,7 @@ struct icc_info { - * @response_packet: a pointer to response packet from fw to driver - * @header_id: id of packet header - * @packet_id: id of packet -+ * @power: a structure for clock and bw information - * @hfi_ops: iris hfi command ops - * @hfi_response_ops: iris hfi response ops - * @core_init_done: structure of signal completion for system response -@@ -86,6 +89,7 @@ struct iris_core { - u8 *response_packet; - u32 header_id; - u32 packet_id; -+ struct iris_core_power power; - const struct iris_hfi_command_ops *hfi_ops; - const struct iris_hfi_response_ops *hfi_response_ops; - struct completion core_init_done; -diff --git a/drivers/media/platform/qcom/iris/iris_firmware.c b/drivers/media/platform/qcom/iris/iris_firmware.c -index 3d14e596a471..7c493b4a75db 100644 ---- a/drivers/media/platform/qcom/iris/iris_firmware.c -+++ b/drivers/media/platform/qcom/iris/iris_firmware.c -@@ -109,3 +109,8 @@ int iris_fw_unload(struct iris_core *core) - { - return qcom_scm_pas_shutdown(core->iris_platform_data->pas_id); - } -+ -+int iris_set_hw_state(struct iris_core *core, bool resume) -+{ -+ return qcom_scm_set_remote_state(resume, 0); -+} -diff --git a/drivers/media/platform/qcom/iris/iris_firmware.h b/drivers/media/platform/qcom/iris/iris_firmware.h -index 266bdd92a124..e833ecd34887 100644 ---- a/drivers/media/platform/qcom/iris/iris_firmware.h -+++ b/drivers/media/platform/qcom/iris/iris_firmware.h -@@ -10,5 +10,6 @@ struct iris_core; - - int iris_fw_load(struct iris_core *core); - int iris_fw_unload(struct iris_core *core); -+int iris_set_hw_state(struct iris_core *core, bool resume); - - #endif -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_common.c b/drivers/media/platform/qcom/iris/iris_hfi_common.c -index a19b988c9a88..29f56c2bf74c 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_common.c -+++ b/drivers/media/platform/qcom/iris/iris_hfi_common.c -@@ -3,6 +3,9 @@ - * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. - */ - -+#include -+ -+#include "iris_firmware.h" - #include "iris_core.h" - #include "iris_hfi_common.h" - #include "iris_vpu_common.h" -@@ -38,6 +41,7 @@ irqreturn_t iris_hfi_isr_handler(int irq, void *data) - return IRQ_NONE; - - mutex_lock(&core->lock); -+ pm_runtime_mark_last_busy(core->dev); - iris_vpu_clear_interrupt(core); - mutex_unlock(&core->lock); - -@@ -48,3 +52,61 @@ irqreturn_t iris_hfi_isr_handler(int irq, void *data) - - return IRQ_HANDLED; - } -+ -+int iris_hfi_pm_suspend(struct iris_core *core) -+{ -+ int ret; -+ -+ ret = iris_vpu_prepare_pc(core); -+ if (ret) { -+ pm_runtime_mark_last_busy(core->dev); -+ ret = -EAGAIN; -+ goto error; -+ } -+ -+ ret = iris_set_hw_state(core, false); -+ if (ret) -+ goto error; -+ -+ iris_vpu_power_off(core); -+ -+ return 0; -+ -+error: -+ dev_err(core->dev, "failed to suspend\n"); -+ -+ return ret; -+} -+ -+int iris_hfi_pm_resume(struct iris_core *core) -+{ -+ const struct iris_hfi_command_ops *ops = core->hfi_ops; -+ int ret; -+ -+ ret = iris_vpu_power_on(core); -+ if (ret) -+ goto error; -+ -+ ret = iris_set_hw_state(core, true); -+ if (ret) -+ goto err_power_off; -+ -+ ret = iris_vpu_boot_firmware(core); -+ if (ret) -+ goto err_suspend_hw; -+ -+ ret = ops->sys_interframe_powercollapse(core); -+ if (ret) -+ goto err_suspend_hw; -+ -+ return 0; -+ -+err_suspend_hw: -+ iris_set_hw_state(core, false); -+err_power_off: -+ iris_vpu_power_off(core); -+error: -+ dev_err(core->dev, "failed to resume\n"); -+ -+ return -EBUSY; -+} -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_common.h b/drivers/media/platform/qcom/iris/iris_hfi_common.h -index b46a2f21102a..36673aafe1c9 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_common.h -+++ b/drivers/media/platform/qcom/iris/iris_hfi_common.h -@@ -46,6 +46,7 @@ struct iris_hfi_command_ops { - int (*sys_init)(struct iris_core *core); - int (*sys_image_version)(struct iris_core *core); - int (*sys_interframe_powercollapse)(struct iris_core *core); -+ int (*sys_pc_prep)(struct iris_core *core); - }; - - struct iris_hfi_response_ops { -@@ -53,6 +54,8 @@ struct iris_hfi_response_ops { - }; - - int iris_hfi_core_init(struct iris_core *core); -+int iris_hfi_pm_suspend(struct iris_core *core); -+int iris_hfi_pm_resume(struct iris_core *core); - - irqreturn_t iris_hfi_isr(int irq, void *data); - irqreturn_t iris_hfi_isr_handler(int irq, void *data); -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c -index 07007d8812ba..b2e76d1dcbf7 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c -@@ -56,10 +56,21 @@ static int iris_hfi_gen1_sys_interframe_powercollapse(struct iris_core *core) - return ret; - } - -+static int iris_hfi_gen1_sys_pc_prep(struct iris_core *core) -+{ -+ struct hfi_sys_pc_prep_pkt pkt; -+ -+ pkt.hdr.size = sizeof(struct hfi_sys_pc_prep_pkt); -+ pkt.hdr.pkt_type = HFI_CMD_SYS_PC_PREP; -+ -+ return iris_hfi_queue_cmd_write_locked(core, &pkt, pkt.hdr.size); -+} -+ - static const struct iris_hfi_command_ops iris_hfi_gen1_command_ops = { - .sys_init = iris_hfi_gen1_sys_init, - .sys_image_version = iris_hfi_gen1_sys_image_version, - .sys_interframe_powercollapse = iris_hfi_gen1_sys_interframe_powercollapse, -+ .sys_pc_prep = iris_hfi_gen1_sys_pc_prep, - }; - - void iris_hfi_gen1_command_ops_init(struct iris_core *core) -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h -index 8af824a42bcf..81685a284f23 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h -@@ -12,6 +12,7 @@ - #define HFI_ERR_NONE 0x0 - - #define HFI_CMD_SYS_INIT 0x10001 -+#define HFI_CMD_SYS_PC_PREP 0x10002 - #define HFI_CMD_SYS_SET_PROPERTY 0x10005 - #define HFI_CMD_SYS_GET_PROPERTY 0x10006 - -@@ -48,6 +49,10 @@ struct hfi_sys_get_property_pkt { - u32 data; - }; - -+struct hfi_sys_pc_prep_pkt { -+ struct hfi_pkt_hdr hdr; -+}; -+ - struct hfi_msg_event_notify_pkt { - struct hfi_pkt_hdr hdr; - u32 event_id; -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c -index 5eaebe170214..f8cb1177ef54 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c -@@ -68,10 +68,28 @@ static int iris_hfi_gen2_sys_interframe_powercollapse(struct iris_core *core) - return ret; - } - -+static int iris_hfi_gen2_sys_pc_prep(struct iris_core *core) -+{ -+ struct iris_hfi_header *hdr; -+ int ret; -+ -+ hdr = kzalloc(SYS_NO_PAYLOAD_PKT_SIZE, GFP_KERNEL); -+ if (!hdr) -+ return -ENOMEM; -+ -+ iris_hfi_gen2_packet_sys_pc_prep(core, hdr); -+ ret = iris_hfi_queue_cmd_write_locked(core, hdr, hdr->size); -+ -+ kfree(hdr); -+ -+ return ret; -+} -+ - static const struct iris_hfi_command_ops iris_hfi_gen2_command_ops = { - .sys_init = iris_hfi_gen2_sys_init, - .sys_image_version = iris_hfi_gen2_sys_image_version, - .sys_interframe_powercollapse = iris_hfi_gen2_sys_interframe_powercollapse, -+ .sys_pc_prep = iris_hfi_gen2_sys_pc_prep, - }; - - void iris_hfi_gen2_command_ops_init(struct iris_core *core) -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h -index 2640caa7f9c0..e6a19ffc12fb 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h -@@ -12,6 +12,7 @@ - - #define HFI_CMD_BEGIN 0x01000000 - #define HFI_CMD_INIT 0x01000001 -+#define HFI_CMD_POWER_COLLAPSE 0x01000002 - #define HFI_CMD_END 0x01FFFFFF - - #define HFI_PROP_BEGIN 0x03000000 -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.c -index 986013aa62df..510d44408b41 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.c -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.c -@@ -159,3 +159,16 @@ void iris_hfi_gen2_packet_sys_interframe_powercollapse(struct iris_core *core, - &payload, - sizeof(u32)); - } -+ -+void iris_hfi_gen2_packet_sys_pc_prep(struct iris_core *core, struct iris_hfi_header *hdr) -+{ -+ iris_hfi_gen2_create_header(hdr, 0 /*session_id*/, core->header_id++); -+ -+ iris_hfi_gen2_create_packet(hdr, -+ HFI_CMD_POWER_COLLAPSE, -+ HFI_HOST_FLAGS_NONE, -+ HFI_PAYLOAD_NONE, -+ HFI_PORT_NONE, -+ core->packet_id++, -+ NULL, 0); -+} -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.h b/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.h -index 10dcb6e4c3d9..3b771b7516de 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.h -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.h -@@ -65,5 +65,6 @@ void iris_hfi_gen2_packet_sys_init(struct iris_core *core, struct iris_hfi_heade - void iris_hfi_gen2_packet_image_version(struct iris_core *core, struct iris_hfi_header *hdr); - void iris_hfi_gen2_packet_sys_interframe_powercollapse(struct iris_core *core, - struct iris_hfi_header *hdr); -+void iris_hfi_gen2_packet_sys_pc_prep(struct iris_core *core, struct iris_hfi_header *hdr); - - #endif -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_queue.c b/drivers/media/platform/qcom/iris/iris_hfi_queue.c -index ee245c540ce7..fac7df0c4d1a 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_queue.c -+++ b/drivers/media/platform/qcom/iris/iris_hfi_queue.c -@@ -3,6 +3,8 @@ - * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. - */ - -+#include -+ - #include "iris_core.h" - #include "iris_hfi_queue.h" - #include "iris_vpu_common.h" -@@ -128,10 +130,26 @@ int iris_hfi_queue_cmd_write(struct iris_core *core, void *pkt, u32 pkt_size) - { - int ret; - -+ ret = pm_runtime_resume_and_get(core->dev); -+ if (ret < 0) -+ goto exit; -+ - mutex_lock(&core->lock); - ret = iris_hfi_queue_cmd_write_locked(core, pkt, pkt_size); -+ if (ret) { -+ mutex_unlock(&core->lock); -+ goto exit; -+ } - mutex_unlock(&core->lock); - -+ pm_runtime_mark_last_busy(core->dev); -+ pm_runtime_put_autosuspend(core->dev); -+ -+ return 0; -+ -+exit: -+ pm_runtime_put_sync(core->dev); -+ - return ret; - } - -diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h -index adf639d1a109..69c0a8b3d12d 100644 ---- a/drivers/media/platform/qcom/iris/iris_platform_common.h -+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h -@@ -10,6 +10,7 @@ struct iris_core; - - #define IRIS_PAS_ID 9 - #define HW_RESPONSE_TIMEOUT_VALUE (1000) /* milliseconds */ -+#define AUTOSUSPEND_DELAY_VALUE (HW_RESPONSE_TIMEOUT_VALUE + 500) /* milliseconds */ - - extern struct iris_platform_data sm8550_data; - -@@ -41,10 +42,22 @@ struct ubwc_config_data { - u32 bank_spreading; - }; - -+struct iris_core_power { -+ u64 clk_freq; -+ u64 icc_bw; -+}; -+ -+enum platform_pm_domain_type { -+ IRIS_CTRL_POWER_DOMAIN, -+ IRIS_HW_POWER_DOMAIN, -+}; -+ - struct iris_platform_data { - void (*init_hfi_command_ops)(struct iris_core *core); - void (*init_hfi_response_ops)(struct iris_core *core); - struct iris_inst *(*get_instance)(void); -+ const struct vpu_ops *vpu_ops; -+ void (*set_preset_registers)(struct iris_core *core); - const struct icc_info *icc_tbl; - unsigned int icc_tbl_size; - const char * const *pmdomain_tbl; -@@ -62,6 +75,7 @@ struct iris_platform_data { - u32 core_arch; - u32 hw_response_timeout; - struct ubwc_config_data *ubwc_config; -+ u32 num_vpp_pipe; - }; - - #endif -diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c -index 30d9664bd419..ed99cdb13d06 100644 ---- a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c -+++ b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c -@@ -6,9 +6,15 @@ - #include "iris_core.h" - #include "iris_hfi_gen2.h" - #include "iris_platform_common.h" -+#include "iris_vpu_common.h" - - #define VIDEO_ARCH_LX 1 - -+static void iris_set_sm8550_preset_registers(struct iris_core *core) -+{ -+ writel(0x0, core->reg_base + 0xB0088); -+} -+ - static const struct icc_info sm8550_icc_table[] = { - { "cpu-cfg", 1000, 1000 }, - { "video-mem", 1000, 15000000 }, -@@ -47,6 +53,8 @@ struct iris_platform_data sm8550_data = { - .get_instance = iris_hfi_gen2_get_instance, - .init_hfi_command_ops = iris_hfi_gen2_command_ops_init, - .init_hfi_response_ops = iris_hfi_gen2_response_ops_init, -+ .vpu_ops = &iris_vpu3_ops, -+ .set_preset_registers = iris_set_sm8550_preset_registers, - .icc_tbl = sm8550_icc_table, - .icc_tbl_size = ARRAY_SIZE(sm8550_icc_table), - .clk_rst_tbl = sm8550_clk_reset_table, -@@ -65,4 +73,5 @@ struct iris_platform_data sm8550_data = { - .core_arch = VIDEO_ARCH_LX, - .hw_response_timeout = HW_RESPONSE_TIMEOUT_VALUE, - .ubwc_config = &ubwc_config_sm8550, -+ .num_vpp_pipe = 4, - }; -diff --git a/drivers/media/platform/qcom/iris/iris_probe.c b/drivers/media/platform/qcom/iris/iris_probe.c -index 02887b3dbe0e..e8ef258b4f2e 100644 ---- a/drivers/media/platform/qcom/iris/iris_probe.c -+++ b/drivers/media/platform/qcom/iris/iris_probe.c -@@ -8,6 +8,7 @@ - #include - #include - #include -+#include - #include - - #include "iris_core.h" -@@ -252,6 +253,12 @@ static int iris_probe(struct platform_device *pdev) - dma_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32)); - dma_set_seg_boundary(&pdev->dev, DMA_BIT_MASK(32)); - -+ pm_runtime_set_autosuspend_delay(core->dev, AUTOSUSPEND_DELAY_VALUE); -+ pm_runtime_use_autosuspend(core->dev); -+ ret = devm_pm_runtime_enable(core->dev); -+ if (ret) -+ goto err_vdev_unreg; -+ - return 0; - - err_vdev_unreg: -@@ -262,6 +269,51 @@ static int iris_probe(struct platform_device *pdev) - return ret; - } - -+static int __maybe_unused iris_pm_suspend(struct device *dev) -+{ -+ struct iris_core *core; -+ int ret = 0; -+ -+ core = dev_get_drvdata(dev); -+ -+ mutex_lock(&core->lock); -+ if (core->state != IRIS_CORE_INIT) -+ goto exit; -+ -+ ret = iris_hfi_pm_suspend(core); -+ -+exit: -+ mutex_unlock(&core->lock); -+ -+ return ret; -+} -+ -+static int __maybe_unused iris_pm_resume(struct device *dev) -+{ -+ struct iris_core *core; -+ int ret = 0; -+ -+ core = dev_get_drvdata(dev); -+ -+ mutex_lock(&core->lock); -+ if (core->state != IRIS_CORE_INIT) -+ goto exit; -+ -+ ret = iris_hfi_pm_resume(core); -+ pm_runtime_mark_last_busy(core->dev); -+ -+exit: -+ mutex_unlock(&core->lock); -+ -+ return ret; -+} -+ -+static const struct dev_pm_ops iris_pm_ops = { -+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, -+ pm_runtime_force_resume) -+ SET_RUNTIME_PM_OPS(iris_pm_suspend, iris_pm_resume, NULL) -+}; -+ - static const struct of_device_id iris_dt_match[] = { - { - .compatible = "qcom,sm8550-iris", -@@ -277,6 +329,7 @@ static struct platform_driver qcom_iris_driver = { - .driver = { - .name = "qcom-iris", - .of_match_table = iris_dt_match, -+ .pm = &iris_pm_ops, - }, - }; - -diff --git a/drivers/media/platform/qcom/iris/iris_resources.c b/drivers/media/platform/qcom/iris/iris_resources.c -new file mode 100644 -index 000000000000..cf32f268b703 ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_resources.c -@@ -0,0 +1,131 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "iris_core.h" -+#include "iris_resources.h" -+ -+#define BW_THRESHOLD 50000 -+ -+int iris_set_icc_bw(struct iris_core *core, unsigned long icc_bw) -+{ -+ unsigned long bw_kbps = 0, bw_prev = 0; -+ const struct icc_info *icc_tbl; -+ int ret = 0, i; -+ -+ icc_tbl = core->iris_platform_data->icc_tbl; -+ -+ for (i = 0; i < core->icc_count; i++) { -+ if (!strcmp(core->icc_tbl[i].name, "video-mem")) { -+ bw_kbps = icc_bw; -+ bw_prev = core->power.icc_bw; -+ -+ bw_kbps = clamp_t(typeof(bw_kbps), bw_kbps, -+ icc_tbl[i].bw_min_kbps, icc_tbl[i].bw_max_kbps); -+ -+ if (abs(bw_kbps - bw_prev) < BW_THRESHOLD && bw_prev) -+ return ret; -+ -+ core->icc_tbl[i].avg_bw = bw_kbps; -+ -+ core->power.icc_bw = bw_kbps; -+ break; -+ } -+ } -+ -+ return icc_bulk_set_bw(core->icc_count, core->icc_tbl); -+} -+ -+int iris_unset_icc_bw(struct iris_core *core) -+{ -+ u32 i; -+ -+ core->power.icc_bw = 0; -+ -+ for (i = 0; i < core->icc_count; i++) { -+ core->icc_tbl[i].avg_bw = 0; -+ core->icc_tbl[i].peak_bw = 0; -+ } -+ -+ return icc_bulk_set_bw(core->icc_count, core->icc_tbl); -+} -+ -+int iris_enable_power_domains(struct iris_core *core, struct device *pd_dev) -+{ -+ int ret; -+ -+ ret = dev_pm_opp_set_rate(core->dev, ULONG_MAX); -+ if (ret) -+ return ret; -+ -+ ret = pm_runtime_get_sync(pd_dev); -+ if (ret < 0) -+ return ret; -+ -+ return ret; -+} -+ -+int iris_disable_power_domains(struct iris_core *core, struct device *pd_dev) -+{ -+ int ret; -+ -+ ret = dev_pm_opp_set_rate(core->dev, 0); -+ if (ret) -+ return ret; -+ -+ pm_runtime_put_sync(pd_dev); -+ -+ return 0; -+} -+ -+static struct clk *iris_get_clk_by_type(struct iris_core *core, enum platform_clk_type clk_type) -+{ -+ const struct platform_clk_data *clk_tbl; -+ u32 clk_cnt, i, j; -+ -+ clk_tbl = core->iris_platform_data->clk_tbl; -+ clk_cnt = core->iris_platform_data->clk_tbl_size; -+ -+ for (i = 0; i < clk_cnt; i++) { -+ if (clk_tbl[i].clk_type == clk_type) { -+ for (j = 0; core->clock_tbl && j < core->clk_count; j++) { -+ if (!strcmp(core->clock_tbl[j].id, clk_tbl[i].clk_name)) -+ return core->clock_tbl[j].clk; -+ } -+ } -+ } -+ -+ return NULL; -+} -+ -+int iris_prepare_enable_clock(struct iris_core *core, enum platform_clk_type clk_type) -+{ -+ struct clk *clock; -+ -+ clock = iris_get_clk_by_type(core, clk_type); -+ if (!clock) -+ return -EINVAL; -+ -+ return clk_prepare_enable(clock); -+} -+ -+int iris_disable_unprepare_clock(struct iris_core *core, enum platform_clk_type clk_type) -+{ -+ struct clk *clock; -+ -+ clock = iris_get_clk_by_type(core, clk_type); -+ if (!clock) -+ return -EINVAL; -+ -+ clk_disable_unprepare(clock); -+ -+ return 0; -+} -diff --git a/drivers/media/platform/qcom/iris/iris_resources.h b/drivers/media/platform/qcom/iris/iris_resources.h -new file mode 100644 -index 000000000000..f723dfe5bd81 ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_resources.h -@@ -0,0 +1,18 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#ifndef __IRIS_RESOURCES_H__ -+#define __IRIS_RESOURCES_H__ -+ -+struct iris_core; -+ -+int iris_enable_power_domains(struct iris_core *core, struct device *pd_dev); -+int iris_disable_power_domains(struct iris_core *core, struct device *pd_dev); -+int iris_unset_icc_bw(struct iris_core *core); -+int iris_set_icc_bw(struct iris_core *core, unsigned long icc_bw); -+int iris_disable_unprepare_clock(struct iris_core *core, enum platform_clk_type clk_type); -+int iris_prepare_enable_clock(struct iris_core *core, enum platform_clk_type clk_type); -+ -+#endif -diff --git a/drivers/media/platform/qcom/iris/iris_vidc.c b/drivers/media/platform/qcom/iris/iris_vidc.c -index 5dd0ccbaa2fb..b8654e73f516 100644 ---- a/drivers/media/platform/qcom/iris/iris_vidc.c -+++ b/drivers/media/platform/qcom/iris/iris_vidc.c -@@ -3,6 +3,7 @@ - * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. - */ - -+#include - #include - #include - -@@ -81,12 +82,19 @@ int iris_open(struct file *filp) - struct iris_inst *inst; - int ret; - -+ ret = pm_runtime_resume_and_get(core->dev); -+ if (ret < 0) -+ return ret; -+ - ret = iris_core_init(core); - if (ret) { - dev_err(core->dev, "core init failed\n"); -+ pm_runtime_put_sync(core->dev); - return ret; - } - -+ pm_runtime_put_sync(core->dev); -+ - inst = core->iris_platform_data->get_instance(); - if (!inst) - return -ENOMEM; -diff --git a/drivers/media/platform/qcom/iris/iris_vpu2.c b/drivers/media/platform/qcom/iris/iris_vpu2.c -new file mode 100644 -index 000000000000..bd8427411576 ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_vpu2.c -@@ -0,0 +1,11 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#include "iris_instance.h" -+#include "iris_vpu_common.h" -+ -+const struct vpu_ops iris_vpu2_ops = { -+ .power_off_hw = iris_vpu_power_off_hw, -+}; -diff --git a/drivers/media/platform/qcom/iris/iris_vpu3.c b/drivers/media/platform/qcom/iris/iris_vpu3.c -new file mode 100644 -index 000000000000..10599f1fa789 ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_vpu3.c -@@ -0,0 +1,84 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#include -+ -+#include "iris_instance.h" -+#include "iris_vpu_common.h" -+#include "iris_vpu_register_defines.h" -+ -+#define AON_MVP_NOC_RESET 0x0001F000 -+ -+#define WRAPPER_CORE_CLOCK_CONFIG (WRAPPER_BASE_OFFS + 0x88) -+#define CORE_CLK_RUN 0x0 -+ -+#define CPU_CS_AHB_BRIDGE_SYNC_RESET (CPU_CS_BASE_OFFS + 0x160) -+#define CORE_BRIDGE_SW_RESET BIT(0) -+#define CORE_BRIDGE_HW_RESET_DISABLE BIT(1) -+ -+#define AON_WRAPPER_MVP_NOC_RESET_REQ (AON_MVP_NOC_RESET + 0x000) -+#define VIDEO_NOC_RESET_REQ (BIT(0) | BIT(1)) -+ -+#define AON_WRAPPER_MVP_NOC_RESET_ACK (AON_MVP_NOC_RESET + 0x004) -+ -+#define VCODEC_SS_IDLE_STATUSN (VCODEC_BASE_OFFS + 0x70) -+ -+static bool iris_vpu3_hw_power_collapsed(struct iris_core *core) -+{ -+ u32 value, pwr_status; -+ -+ value = readl(core->reg_base + WRAPPER_CORE_POWER_STATUS); -+ pwr_status = value & BIT(1); -+ -+ return pwr_status ? false : true; -+} -+ -+static void iris_vpu3_power_off_hardware(struct iris_core *core) -+{ -+ u32 reg_val = 0, value, i; -+ int ret; -+ -+ if (iris_vpu3_hw_power_collapsed(core)) -+ goto disable_power; -+ -+ dev_err(core->dev, "video hw is power on\n"); -+ -+ value = readl(core->reg_base + WRAPPER_CORE_CLOCK_CONFIG); -+ if (value) -+ writel(CORE_CLK_RUN, core->reg_base + WRAPPER_CORE_CLOCK_CONFIG); -+ -+ for (i = 0; i < core->iris_platform_data->num_vpp_pipe; i++) { -+ ret = readl_poll_timeout(core->reg_base + VCODEC_SS_IDLE_STATUSN + 4 * i, -+ reg_val, reg_val & 0x400000, 2000, 20000); -+ if (ret) -+ goto disable_power; -+ } -+ -+ writel(VIDEO_NOC_RESET_REQ, core->reg_base + AON_WRAPPER_MVP_NOC_RESET_REQ); -+ -+ ret = readl_poll_timeout(core->reg_base + AON_WRAPPER_MVP_NOC_RESET_ACK, -+ reg_val, reg_val & 0x3, 200, 2000); -+ if (ret) -+ goto disable_power; -+ -+ writel(0x0, core->reg_base + AON_WRAPPER_MVP_NOC_RESET_REQ); -+ -+ ret = readl_poll_timeout(core->reg_base + AON_WRAPPER_MVP_NOC_RESET_ACK, -+ reg_val, !(reg_val & 0x3), 200, 2000); -+ if (ret) -+ goto disable_power; -+ -+ writel(CORE_BRIDGE_SW_RESET | CORE_BRIDGE_HW_RESET_DISABLE, -+ core->reg_base + CPU_CS_AHB_BRIDGE_SYNC_RESET); -+ writel(CORE_BRIDGE_HW_RESET_DISABLE, core->reg_base + CPU_CS_AHB_BRIDGE_SYNC_RESET); -+ writel(0x0, core->reg_base + CPU_CS_AHB_BRIDGE_SYNC_RESET); -+ -+disable_power: -+ iris_vpu_power_off_hw(core); -+} -+ -+const struct vpu_ops iris_vpu3_ops = { -+ .power_off_hw = iris_vpu3_power_off_hardware, -+}; -diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.c b/drivers/media/platform/qcom/iris/iris_vpu_common.c -index 34817573f61b..fe9896d66848 100644 ---- a/drivers/media/platform/qcom/iris/iris_vpu_common.c -+++ b/drivers/media/platform/qcom/iris/iris_vpu_common.c -@@ -4,13 +4,16 @@ - */ - - #include -+#include -+#include - - #include "iris_core.h" - #include "iris_vpu_common.h" -+#include "iris_vpu_register_defines.h" - --#define CPU_BASE_OFFS 0x000A0000 -+#define WRAPPER_TZ_BASE_OFFS 0x000C0000 -+#define AON_BASE_OFFS 0x000E0000 - --#define CPU_CS_BASE_OFFS (CPU_BASE_OFFS) - #define CPU_IC_BASE_OFFS (CPU_BASE_OFFS) - - #define CPU_CS_A2HSOFTINTCLR (CPU_CS_BASE_OFFS + 0x1C) -@@ -21,6 +24,7 @@ - - #define CTRL_INIT_IDLE_MSG_BMSK 0x40000000 - #define CTRL_ERROR_STATUS__M 0xfe -+#define CTRL_STATUS_PC_READY 0x100 - - #define QTBL_INFO (CPU_CS_BASE_OFFS + 0x50) - #define QTBL_ENABLE BIT(0) -@@ -35,15 +39,48 @@ - #define HOST2XTENSA_INTR_ENABLE BIT(0) - - #define CPU_CS_X2RPMH (CPU_CS_BASE_OFFS + 0x168) -+#define MSK_SIGNAL_FROM_TENSILICA BIT(0) -+#define MSK_CORE_POWER_ON BIT(1) - - #define CPU_IC_SOFTINT (CPU_IC_BASE_OFFS + 0x150) - #define CPU_IC_SOFTINT_H2A_SHFT 0x0 - --#define WRAPPER_BASE_OFFS 0x000B0000 - #define WRAPPER_INTR_STATUS (WRAPPER_BASE_OFFS + 0x0C) - #define WRAPPER_INTR_STATUS_A2HWD_BMSK BIT(3) - #define WRAPPER_INTR_STATUS_A2H_BMSK BIT(2) - -+#define WRAPPER_INTR_MASK (WRAPPER_BASE_OFFS + 0x10) -+#define WRAPPER_INTR_MASK_A2HWD_BMSK BIT(3) -+#define WRAPPER_INTR_MASK_A2HCPU_BMSK BIT(2) -+ -+#define WRAPPER_DEBUG_BRIDGE_LPI_CONTROL (WRAPPER_BASE_OFFS + 0x54) -+#define WRAPPER_DEBUG_BRIDGE_LPI_STATUS (WRAPPER_BASE_OFFS + 0x58) -+#define WRAPPER_IRIS_CPU_NOC_LPI_CONTROL (WRAPPER_BASE_OFFS + 0x5C) -+#define WRAPPER_IRIS_CPU_NOC_LPI_STATUS (WRAPPER_BASE_OFFS + 0x60) -+ -+#define WRAPPER_TZ_CPU_STATUS (WRAPPER_TZ_BASE_OFFS + 0x10) -+#define WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG (WRAPPER_TZ_BASE_OFFS + 0x14) -+#define CTL_AXI_CLK_HALT BIT(0) -+#define CTL_CLK_HALT BIT(1) -+ -+#define WRAPPER_TZ_QNS4PDXFIFO_RESET (WRAPPER_TZ_BASE_OFFS + 0x18) -+#define RESET_HIGH BIT(0) -+ -+#define AON_WRAPPER_MVP_NOC_LPI_CONTROL (AON_BASE_OFFS) -+#define REQ_POWER_DOWN_PREP BIT(0) -+ -+#define AON_WRAPPER_MVP_NOC_LPI_STATUS (AON_BASE_OFFS + 0x4) -+ -+static void iris_vpu_interrupt_init(struct iris_core *core) -+{ -+ u32 mask_val; -+ -+ mask_val = readl(core->reg_base + WRAPPER_INTR_MASK); -+ mask_val &= ~(WRAPPER_INTR_MASK_A2HWD_BMSK | -+ WRAPPER_INTR_MASK_A2HCPU_BMSK); -+ writel(mask_val, core->reg_base + WRAPPER_INTR_MASK); -+} -+ - static void iris_vpu_setup_ucregion_memory_map(struct iris_core *core) - { - u32 queue_size, value; -@@ -130,3 +167,203 @@ int iris_vpu_watchdog(struct iris_core *core, u32 intr_status) - - return 0; - } -+ -+int iris_vpu_prepare_pc(struct iris_core *core) -+{ -+ u32 wfi_status, idle_status, pc_ready; -+ u32 ctrl_status, val = 0; -+ int ret; -+ -+ ctrl_status = readl(core->reg_base + CTRL_STATUS); -+ pc_ready = ctrl_status & CTRL_STATUS_PC_READY; -+ idle_status = ctrl_status & BIT(30); -+ if (pc_ready) -+ return 0; -+ -+ wfi_status = readl(core->reg_base + WRAPPER_TZ_CPU_STATUS); -+ wfi_status &= BIT(0); -+ if (!wfi_status || !idle_status) -+ goto skip_power_off; -+ -+ ret = core->hfi_ops->sys_pc_prep(core); -+ if (ret) -+ goto skip_power_off; -+ -+ ret = readl_poll_timeout(core->reg_base + CTRL_STATUS, val, -+ val & CTRL_STATUS_PC_READY, 250, 2500); -+ if (ret) -+ goto skip_power_off; -+ -+ ret = readl_poll_timeout(core->reg_base + WRAPPER_TZ_CPU_STATUS, -+ val, val & BIT(0), 250, 2500); -+ if (ret) -+ goto skip_power_off; -+ -+ return 0; -+ -+skip_power_off: -+ ctrl_status = readl(core->reg_base + CTRL_STATUS); -+ wfi_status = readl(core->reg_base + WRAPPER_TZ_CPU_STATUS); -+ wfi_status &= BIT(0); -+ dev_err(core->dev, "skip power collapse, wfi=%#x, idle=%#x, pcr=%#x, ctrl=%#x)\n", -+ wfi_status, idle_status, pc_ready, ctrl_status); -+ -+ return -EAGAIN; -+} -+ -+static int iris_vpu_power_off_controller(struct iris_core *core) -+{ -+ u32 val = 0; -+ int ret; -+ -+ writel(MSK_SIGNAL_FROM_TENSILICA | MSK_CORE_POWER_ON, core->reg_base + CPU_CS_X2RPMH); -+ -+ writel(REQ_POWER_DOWN_PREP, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL); -+ -+ ret = readl_poll_timeout(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_STATUS, -+ val, val & BIT(0), 200, 2000); -+ if (ret) -+ goto disable_power; -+ -+ writel(REQ_POWER_DOWN_PREP, core->reg_base + WRAPPER_IRIS_CPU_NOC_LPI_CONTROL); -+ -+ ret = readl_poll_timeout(core->reg_base + WRAPPER_IRIS_CPU_NOC_LPI_STATUS, -+ val, val & BIT(0), 200, 2000); -+ if (ret) -+ goto disable_power; -+ -+ writel(0x0, core->reg_base + WRAPPER_DEBUG_BRIDGE_LPI_CONTROL); -+ -+ ret = readl_poll_timeout(core->reg_base + WRAPPER_DEBUG_BRIDGE_LPI_STATUS, -+ val, val == 0, 200, 2000); -+ if (ret) -+ goto disable_power; -+ -+ writel(CTL_AXI_CLK_HALT | CTL_CLK_HALT, -+ core->reg_base + WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG); -+ writel(RESET_HIGH, core->reg_base + WRAPPER_TZ_QNS4PDXFIFO_RESET); -+ writel(0x0, core->reg_base + WRAPPER_TZ_QNS4PDXFIFO_RESET); -+ writel(0x0, core->reg_base + WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG); -+ -+disable_power: -+ iris_disable_unprepare_clock(core, IRIS_CTRL_CLK); -+ iris_disable_unprepare_clock(core, IRIS_AXI_CLK); -+ iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_CTRL_POWER_DOMAIN]); -+ -+ return 0; -+} -+ -+void iris_vpu_power_off_hw(struct iris_core *core) -+{ -+ dev_pm_genpd_set_hwmode(core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN], false); -+ iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN]); -+ iris_disable_unprepare_clock(core, IRIS_HW_CLK); -+} -+ -+void iris_vpu_power_off(struct iris_core *core) -+{ -+ dev_pm_opp_set_rate(core->dev, 0); -+ core->iris_platform_data->vpu_ops->power_off_hw(core); -+ iris_vpu_power_off_controller(core); -+ iris_unset_icc_bw(core); -+ -+ if (!iris_vpu_watchdog(core, core->intr_status)) -+ disable_irq_nosync(core->irq); -+} -+ -+static int iris_vpu_power_on_controller(struct iris_core *core) -+{ -+ u32 rst_tbl_size = core->iris_platform_data->clk_rst_tbl_size; -+ int ret; -+ -+ ret = iris_enable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_CTRL_POWER_DOMAIN]); -+ if (ret) -+ return ret; -+ -+ ret = reset_control_bulk_reset(rst_tbl_size, core->resets); -+ if (ret) -+ goto err_disable_power; -+ -+ ret = iris_prepare_enable_clock(core, IRIS_AXI_CLK); -+ if (ret) -+ goto err_disable_power; -+ -+ ret = iris_prepare_enable_clock(core, IRIS_CTRL_CLK); -+ if (ret) -+ goto err_disable_clock; -+ -+ return 0; -+ -+err_disable_clock: -+ iris_disable_unprepare_clock(core, IRIS_AXI_CLK); -+err_disable_power: -+ iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_CTRL_POWER_DOMAIN]); -+ -+ return ret; -+} -+ -+static int iris_vpu_power_on_hw(struct iris_core *core) -+{ -+ int ret; -+ -+ ret = iris_enable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN]); -+ if (ret) -+ return ret; -+ -+ ret = iris_prepare_enable_clock(core, IRIS_HW_CLK); -+ if (ret) -+ goto err_disable_power; -+ -+ ret = dev_pm_genpd_set_hwmode(core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN], true); -+ if (ret) -+ goto err_disable_clock; -+ -+ return 0; -+ -+err_disable_clock: -+ iris_disable_unprepare_clock(core, IRIS_HW_CLK); -+err_disable_power: -+ iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN]); -+ -+ return ret; -+} -+ -+int iris_vpu_power_on(struct iris_core *core) -+{ -+ u32 freq; -+ int ret; -+ -+ ret = iris_set_icc_bw(core, INT_MAX); -+ if (ret) -+ goto err; -+ -+ ret = iris_vpu_power_on_controller(core); -+ if (ret) -+ goto err_unvote_icc; -+ -+ ret = iris_vpu_power_on_hw(core); -+ if (ret) -+ goto err_power_off_ctrl; -+ -+ freq = core->power.clk_freq ? core->power.clk_freq : -+ (u32)ULONG_MAX; -+ -+ dev_pm_opp_set_rate(core->dev, freq); -+ -+ core->iris_platform_data->set_preset_registers(core); -+ -+ iris_vpu_interrupt_init(core); -+ core->intr_status = 0; -+ enable_irq(core->irq); -+ -+ return 0; -+ -+err_power_off_ctrl: -+ iris_vpu_power_off_controller(core); -+err_unvote_icc: -+ iris_unset_icc_bw(core); -+err: -+ dev_err(core->dev, "power on failed\n"); -+ -+ return ret; -+} -diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.h b/drivers/media/platform/qcom/iris/iris_vpu_common.h -index c38c055d3d14..d3efa7c0ce9a 100644 ---- a/drivers/media/platform/qcom/iris/iris_vpu_common.h -+++ b/drivers/media/platform/qcom/iris/iris_vpu_common.h -@@ -8,9 +8,20 @@ - - struct iris_core; - -+extern const struct vpu_ops iris_vpu2_ops; -+extern const struct vpu_ops iris_vpu3_ops; -+ -+struct vpu_ops { -+ void (*power_off_hw)(struct iris_core *core); -+}; -+ - int iris_vpu_boot_firmware(struct iris_core *core); - void iris_vpu_raise_interrupt(struct iris_core *core); - void iris_vpu_clear_interrupt(struct iris_core *core); - int iris_vpu_watchdog(struct iris_core *core, u32 intr_status); -+int iris_vpu_prepare_pc(struct iris_core *core); -+int iris_vpu_power_on(struct iris_core *core); -+void iris_vpu_power_off_hw(struct iris_core *core); -+void iris_vpu_power_off(struct iris_core *core); - - #endif -diff --git a/drivers/media/platform/qcom/iris/iris_vpu_register_defines.h b/drivers/media/platform/qcom/iris/iris_vpu_register_defines.h -new file mode 100644 -index 000000000000..fe8a39e5e5a3 ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_vpu_register_defines.h -@@ -0,0 +1,17 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#ifndef __IRIS_VPU_REGISTER_DEFINES_H__ -+#define __IRIS_VPU_REGISTER_DEFINES_H__ -+ -+#define VCODEC_BASE_OFFS 0x00000000 -+#define CPU_BASE_OFFS 0x000A0000 -+#define WRAPPER_BASE_OFFS 0x000B0000 -+ -+#define CPU_CS_BASE_OFFS (CPU_BASE_OFFS) -+ -+#define WRAPPER_CORE_POWER_STATUS (WRAPPER_BASE_OFFS + 0x80) -+ -+#endif --- -2.34.1 - diff --git a/patch/kernel/archive/sm8550-6.12/0009_media--iris--implement-reqbuf-ioctl-with-vb2_queue.patch b/patch/kernel/archive/sm8550-6.12/0009_media--iris--implement-reqbuf-ioctl-with-vb2_queue.patch deleted file mode 100644 index 2f9645c7c620..000000000000 --- a/patch/kernel/archive/sm8550-6.12/0009_media--iris--implement-reqbuf-ioctl-with-vb2_queue.patch +++ /dev/null @@ -1,1651 +0,0 @@ -From c099666411578d2d1eea95bd644af25033f24af7 Mon Sep 17 00:00:00 2001 -From: Dikshita Agarwal -Date: Fri, 7 Feb 2025 13:24:49 +0530 -Subject: [PATCH] media: iris: implement reqbuf ioctl with vb2_queue_setup - -Implement the reqbuf IOCTL op and the vb2_queue_setup vb2 op in the -driver with necessary hooks. - -Reviewed-by: Hans Verkuil -Tested-by: Stefan Schmidt # x1e80100 (Dell XPS 13 9345) -Reviewed-by: Stefan Schmidt -Tested-by: Neil Armstrong # on SM8550-QRD -Tested-by: Neil Armstrong # on SM8550-HDK -Signed-off-by: Dikshita Agarwal -Link: https://lore.kernel.org/r/20250207-qcom-video-iris-v10-9-ab66eeffbd20@quicinc.com -Signed-off-by: Neil Armstrong ---- - drivers/media/platform/qcom/iris/Makefile | 7 +- - .../media/platform/qcom/iris/iris_buffer.c | 119 ++++++++++++++++++ - .../media/platform/qcom/iris/iris_buffer.h | 107 ++++++++++++++++ - drivers/media/platform/qcom/iris/iris_core.h | 6 + - .../platform/qcom/iris/iris_hfi_common.h | 3 + - .../qcom/iris/iris_hfi_gen1_command.c | 40 ++++++ - .../qcom/iris/iris_hfi_gen1_defines.h | 47 ++++++- - .../qcom/iris/iris_hfi_gen1_response.c | 79 +++++++++++- - .../media/platform/qcom/iris/iris_hfi_gen2.h | 5 + - .../qcom/iris/iris_hfi_gen2_command.c | 105 ++++++++++++++++ - .../qcom/iris/iris_hfi_gen2_defines.h | 35 ++++++ - .../platform/qcom/iris/iris_hfi_gen2_packet.c | 39 ++++++ - .../platform/qcom/iris/iris_hfi_gen2_packet.h | 7 ++ - .../qcom/iris/iris_hfi_gen2_response.c | 111 +++++++++++++++- - .../media/platform/qcom/iris/iris_instance.h | 22 ++++ - .../platform/qcom/iris/iris_platform_common.h | 5 + - .../platform/qcom/iris/iris_platform_sm8550.c | 6 + - drivers/media/platform/qcom/iris/iris_probe.c | 2 + - drivers/media/platform/qcom/iris/iris_utils.c | 52 ++++++++ - drivers/media/platform/qcom/iris/iris_utils.h | 34 +++++ - drivers/media/platform/qcom/iris/iris_vb2.c | 50 ++++++++ - drivers/media/platform/qcom/iris/iris_vb2.h | 12 ++ - drivers/media/platform/qcom/iris/iris_vdec.c | 56 +++++++++ - drivers/media/platform/qcom/iris/iris_vdec.h | 14 +++ - drivers/media/platform/qcom/iris/iris_vidc.c | 81 ++++++++++++ - .../platform/qcom/iris/iris_vpu_buffer.c | 19 +++ - .../platform/qcom/iris/iris_vpu_buffer.h | 15 +++ - 27 files changed, 1070 insertions(+), 8 deletions(-) - create mode 100644 drivers/media/platform/qcom/iris/iris_buffer.c - create mode 100644 drivers/media/platform/qcom/iris/iris_buffer.h - create mode 100644 drivers/media/platform/qcom/iris/iris_utils.c - create mode 100644 drivers/media/platform/qcom/iris/iris_utils.h - create mode 100644 drivers/media/platform/qcom/iris/iris_vb2.c - create mode 100644 drivers/media/platform/qcom/iris/iris_vb2.h - create mode 100644 drivers/media/platform/qcom/iris/iris_vdec.c - create mode 100644 drivers/media/platform/qcom/iris/iris_vdec.h - create mode 100644 drivers/media/platform/qcom/iris/iris_vpu_buffer.c - create mode 100644 drivers/media/platform/qcom/iris/iris_vpu_buffer.h - -diff --git a/drivers/media/platform/qcom/iris/Makefile b/drivers/media/platform/qcom/iris/Makefile -index a5f290a8c4af..48ab264b7906 100644 ---- a/drivers/media/platform/qcom/iris/Makefile -+++ b/drivers/media/platform/qcom/iris/Makefile -@@ -1,4 +1,5 @@ --iris-objs += iris_core.o \ -+iris-objs += iris_buffer.o \ -+ iris_core.o \ - iris_firmware.o \ - iris_hfi_common.o \ - iris_hfi_gen1_command.o \ -@@ -10,9 +11,13 @@ iris-objs += iris_core.o \ - iris_platform_sm8550.o \ - iris_probe.o \ - iris_resources.o \ -+ iris_utils.o \ - iris_vidc.o \ -+ iris_vb2.o \ -+ iris_vdec.o \ - iris_vpu2.o \ - iris_vpu3.o \ -+ iris_vpu_buffer.o \ - iris_vpu_common.o \ - - obj-$(CONFIG_VIDEO_QCOM_IRIS) += iris.o -diff --git a/drivers/media/platform/qcom/iris/iris_buffer.c b/drivers/media/platform/qcom/iris/iris_buffer.c -new file mode 100644 -index 000000000000..037931ce6550 ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_buffer.c -@@ -0,0 +1,119 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#include -+ -+#include "iris_buffer.h" -+#include "iris_instance.h" -+ -+#define PIXELS_4K 4096 -+#define MAX_WIDTH 4096 -+#define MAX_HEIGHT 2304 -+#define Y_STRIDE_ALIGN 128 -+#define UV_STRIDE_ALIGN 128 -+#define Y_SCANLINE_ALIGN 32 -+#define UV_SCANLINE_ALIGN 16 -+#define UV_SCANLINE_ALIGN_QC08C 32 -+#define META_STRIDE_ALIGNED 64 -+#define META_SCANLINE_ALIGNED 16 -+#define NUM_MBS_4K (DIV_ROUND_UP(MAX_WIDTH, 16) * DIV_ROUND_UP(MAX_HEIGHT, 16)) -+ -+/* -+ * NV12: -+ * YUV 4:2:0 image with a plane of 8 bit Y samples followed -+ * by an interleaved U/V plane containing 8 bit 2x2 subsampled -+ * colour difference samples. -+ * -+ * <-Y/UV_Stride (aligned to 128)-> -+ * <------- Width -------> -+ * Y Y Y Y Y Y Y Y Y Y Y Y . . . . ^ ^ -+ * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | -+ * Y Y Y Y Y Y Y Y Y Y Y Y . . . . Height | -+ * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | y_scanlines (aligned to 32) -+ * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | -+ * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | -+ * Y Y Y Y Y Y Y Y Y Y Y Y . . . . | | -+ * Y Y Y Y Y Y Y Y Y Y Y Y . . . . V | -+ * . . . . . . . . . . . . . . . . | -+ * . . . . . . . . . . . . . . . . | -+ * . . . . . . . . . . . . . . . . | -+ * . . . . . . . . . . . . . . . . V -+ * U V U V U V U V U V U V . . . . ^ -+ * U V U V U V U V U V U V . . . . | -+ * U V U V U V U V U V U V . . . . | -+ * U V U V U V U V U V U V . . . . uv_scanlines (aligned to 16) -+ * . . . . . . . . . . . . . . . . | -+ * . . . . . . . . . . . . . . . . V -+ * . . . . . . . . . . . . . . . . --> Buffer size aligned to 4K -+ * -+ * y_stride : Width aligned to 128 -+ * uv_stride : Width aligned to 128 -+ * y_scanlines: Height aligned to 32 -+ * uv_scanlines: Height/2 aligned to 16 -+ * Total size = align((y_stride * y_scanlines -+ * + uv_stride * uv_scanlines , 4096) -+ * -+ * Note: All the alignments are hardware requirements. -+ */ -+static u32 iris_yuv_buffer_size_nv12(struct iris_inst *inst) -+{ -+ u32 y_plane, uv_plane, y_stride, uv_stride, y_scanlines, uv_scanlines; -+ struct v4l2_format *f = inst->fmt_dst; -+ -+ y_stride = ALIGN(f->fmt.pix_mp.width, Y_STRIDE_ALIGN); -+ uv_stride = ALIGN(f->fmt.pix_mp.width, UV_STRIDE_ALIGN); -+ y_scanlines = ALIGN(f->fmt.pix_mp.height, Y_SCANLINE_ALIGN); -+ uv_scanlines = ALIGN((f->fmt.pix_mp.height + 1) >> 1, UV_SCANLINE_ALIGN); -+ y_plane = y_stride * y_scanlines; -+ uv_plane = uv_stride * uv_scanlines; -+ -+ return ALIGN(y_plane + uv_plane, PIXELS_4K); -+} -+ -+static u32 iris_bitstream_buffer_size(struct iris_inst *inst) -+{ -+ struct platform_inst_caps *caps = inst->core->iris_platform_data->inst_caps; -+ u32 base_res_mbs = NUM_MBS_4K; -+ u32 frame_size, num_mbs; -+ u32 div_factor = 2; -+ -+ num_mbs = iris_get_mbpf(inst); -+ if (num_mbs > NUM_MBS_4K) { -+ div_factor = 4; -+ base_res_mbs = caps->max_mbpf; -+ } -+ -+ /* -+ * frame_size = YUVsize / div_factor -+ * where YUVsize = resolution_in_MBs * MBs_in_pixel * 3 / 2 -+ */ -+ frame_size = base_res_mbs * (16 * 16) * 3 / 2 / div_factor; -+ -+ return ALIGN(frame_size, PIXELS_4K); -+} -+ -+int iris_get_buffer_size(struct iris_inst *inst, -+ enum iris_buffer_type buffer_type) -+{ -+ switch (buffer_type) { -+ case BUF_INPUT: -+ return iris_bitstream_buffer_size(inst); -+ case BUF_OUTPUT: -+ return iris_yuv_buffer_size_nv12(inst); -+ default: -+ return 0; -+ } -+} -+ -+void iris_vb2_queue_error(struct iris_inst *inst) -+{ -+ struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; -+ struct vb2_queue *q; -+ -+ q = v4l2_m2m_get_src_vq(m2m_ctx); -+ vb2_queue_error(q); -+ q = v4l2_m2m_get_dst_vq(m2m_ctx); -+ vb2_queue_error(q); -+} -diff --git a/drivers/media/platform/qcom/iris/iris_buffer.h b/drivers/media/platform/qcom/iris/iris_buffer.h -new file mode 100644 -index 000000000000..ae2ec5637108 ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_buffer.h -@@ -0,0 +1,107 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#ifndef __IRIS_BUFFER_H__ -+#define __IRIS_BUFFER_H__ -+ -+#include -+ -+struct iris_inst; -+ -+#define to_iris_buffer(ptr) container_of(ptr, struct iris_buffer, vb2) -+ -+/** -+ * enum iris_buffer_type -+ * -+ * @BUF_INPUT: input buffer to the iris hardware -+ * @BUF_OUTPUT: output buffer from the iris hardware -+ * @BUF_BIN: buffer to store intermediate bin data -+ * @BUF_ARP: buffer for auto register programming -+ * @BUF_COMV: buffer to store colocated motion vectors -+ * @BUF_NON_COMV: buffer to hold config data for HW -+ * @BUF_LINE: buffer to store decoding/encoding context data for HW -+ * @BUF_DPB: buffer to store display picture buffers for reference -+ * @BUF_PERSIST: buffer to store session context data -+ * @BUF_SCRATCH_1: buffer to store decoding/encoding context data for HW -+ * @BUF_TYPE_MAX: max buffer types -+ */ -+enum iris_buffer_type { -+ BUF_INPUT = 1, -+ BUF_OUTPUT, -+ BUF_BIN, -+ BUF_ARP, -+ BUF_COMV, -+ BUF_NON_COMV, -+ BUF_LINE, -+ BUF_DPB, -+ BUF_PERSIST, -+ BUF_SCRATCH_1, -+ BUF_TYPE_MAX, -+}; -+ -+/* -+ * enum iris_buffer_attributes -+ * -+ * BUF_ATTR_DEFERRED: buffer queued by client but not submitted to firmware. -+ * BUF_ATTR_PENDING_RELEASE: buffers requested to be released from firmware. -+ * BUF_ATTR_QUEUED: buffers submitted to firmware. -+ * BUF_ATTR_DEQUEUED: buffers received from firmware. -+ * BUF_ATTR_BUFFER_DONE: buffers sent back to vb2. -+ */ -+enum iris_buffer_attributes { -+ BUF_ATTR_DEFERRED = BIT(0), -+ BUF_ATTR_PENDING_RELEASE = BIT(1), -+ BUF_ATTR_QUEUED = BIT(2), -+ BUF_ATTR_DEQUEUED = BIT(3), -+ BUF_ATTR_BUFFER_DONE = BIT(4), -+}; -+ -+/** -+ * struct iris_buffer -+ * -+ * @vb2: v4l2 vb2 buffer -+ * @list: list head for the iris_buffers structure -+ * @inst: iris instance structure -+ * @type: enum for type of iris buffer -+ * @index: identifier for the iris buffer -+ * @fd: file descriptor of the buffer -+ * @buffer_size: accessible buffer size in bytes starting from addr_offset -+ * @data_offset: accessible buffer offset from base address -+ * @data_size: data size in bytes -+ * @device_addr: device address of the buffer -+ * @kvaddr: kernel virtual address of the buffer -+ * @dma_attrs: dma attributes -+ * @flags: buffer flags. It is represented as bit masks. -+ * @timestamp: timestamp of the buffer in nano seconds (ns) -+ * @attr: enum for iris buffer attributes -+ */ -+struct iris_buffer { -+ struct vb2_v4l2_buffer vb2; -+ struct list_head list; -+ struct iris_inst *inst; -+ enum iris_buffer_type type; -+ u32 index; -+ int fd; -+ size_t buffer_size; -+ u32 data_offset; -+ size_t data_size; -+ dma_addr_t device_addr; -+ void *kvaddr; -+ unsigned long dma_attrs; -+ u32 flags; /* V4L2_BUF_FLAG_* */ -+ u64 timestamp; -+ enum iris_buffer_attributes attr; -+}; -+ -+struct iris_buffers { -+ struct list_head list; -+ u32 min_count; -+ u32 size; -+}; -+ -+int iris_get_buffer_size(struct iris_inst *inst, enum iris_buffer_type buffer_type); -+void iris_vb2_queue_error(struct iris_inst *inst); -+ -+#endif -diff --git a/drivers/media/platform/qcom/iris/iris_core.h b/drivers/media/platform/qcom/iris/iris_core.h -index 58aab78ab2c4..1ddcb8793172 100644 ---- a/drivers/media/platform/qcom/iris/iris_core.h -+++ b/drivers/media/platform/qcom/iris/iris_core.h -@@ -34,6 +34,8 @@ struct icc_info { - * @v4l2_dev: a holder for v4l2 device structure - * @vdev_dec: iris video device structure for decoder - * @iris_v4l2_file_ops: iris v4l2 file ops -+ * @iris_v4l2_ioctl_ops: iris v4l2 ioctl ops -+ * @iris_vb2_ops: iris vb2 ops - * @icc_tbl: table of iris interconnects - * @icc_count: count of iris interconnects - * @pmdomain_tbl: table of iris power domains -@@ -60,6 +62,7 @@ struct icc_info { - * @core_init_done: structure of signal completion for system response - * @intr_status: interrupt status - * @sys_error_handler: a delayed work for handling system fatal error -+ * @instances: a list_head of all instances - */ - - struct iris_core { -@@ -69,6 +72,8 @@ struct iris_core { - struct v4l2_device v4l2_dev; - struct video_device *vdev_dec; - const struct v4l2_file_operations *iris_v4l2_file_ops; -+ const struct v4l2_ioctl_ops *iris_v4l2_ioctl_ops; -+ const struct vb2_ops *iris_vb2_ops; - struct icc_bulk_data *icc_tbl; - u32 icc_count; - struct dev_pm_domain_list *pmdomain_tbl; -@@ -95,6 +100,7 @@ struct iris_core { - struct completion core_init_done; - u32 intr_status; - struct delayed_work sys_error_handler; -+ struct list_head instances; - }; - - int iris_core_init(struct iris_core *core); -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_common.h b/drivers/media/platform/qcom/iris/iris_hfi_common.h -index 36673aafe1c9..eaa2db469c74 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_common.h -+++ b/drivers/media/platform/qcom/iris/iris_hfi_common.h -@@ -9,6 +9,7 @@ - #include - #include - -+struct iris_inst; - struct iris_core; - - enum hfi_packet_port_type { -@@ -47,6 +48,8 @@ struct iris_hfi_command_ops { - int (*sys_image_version)(struct iris_core *core); - int (*sys_interframe_powercollapse)(struct iris_core *core); - int (*sys_pc_prep)(struct iris_core *core); -+ int (*session_open)(struct iris_inst *inst); -+ int (*session_close)(struct iris_inst *inst); - }; - - struct iris_hfi_response_ops { -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c -index b2e76d1dcbf7..7ee69c5223ce 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c -@@ -66,11 +66,51 @@ static int iris_hfi_gen1_sys_pc_prep(struct iris_core *core) - return iris_hfi_queue_cmd_write_locked(core, &pkt, pkt.hdr.size); - } - -+static int iris_hfi_gen1_session_open(struct iris_inst *inst) -+{ -+ struct hfi_session_open_pkt packet; -+ int ret; -+ -+ packet.shdr.hdr.size = sizeof(struct hfi_session_open_pkt); -+ packet.shdr.hdr.pkt_type = HFI_CMD_SYS_SESSION_INIT; -+ packet.shdr.session_id = inst->session_id; -+ packet.session_domain = HFI_SESSION_TYPE_DEC; -+ packet.session_codec = HFI_VIDEO_CODEC_H264; -+ -+ reinit_completion(&inst->completion); -+ -+ ret = iris_hfi_queue_cmd_write(inst->core, &packet, packet.shdr.hdr.size); -+ if (ret) -+ return ret; -+ -+ return iris_wait_for_session_response(inst); -+} -+ -+static void iris_hfi_gen1_packet_session_cmd(struct iris_inst *inst, -+ struct hfi_session_pkt *packet, -+ u32 ptype) -+{ -+ packet->shdr.hdr.size = sizeof(*packet); -+ packet->shdr.hdr.pkt_type = ptype; -+ packet->shdr.session_id = inst->session_id; -+} -+ -+static int iris_hfi_gen1_session_close(struct iris_inst *inst) -+{ -+ struct hfi_session_pkt packet; -+ -+ iris_hfi_gen1_packet_session_cmd(inst, &packet, HFI_CMD_SYS_SESSION_END); -+ -+ return iris_hfi_queue_cmd_write(inst->core, &packet, packet.shdr.hdr.size); -+} -+ - static const struct iris_hfi_command_ops iris_hfi_gen1_command_ops = { - .sys_init = iris_hfi_gen1_sys_init, - .sys_image_version = iris_hfi_gen1_sys_image_version, - .sys_interframe_powercollapse = iris_hfi_gen1_sys_interframe_powercollapse, - .sys_pc_prep = iris_hfi_gen1_sys_pc_prep, -+ .session_open = iris_hfi_gen1_session_open, -+ .session_close = iris_hfi_gen1_session_close, - }; - - void iris_hfi_gen1_command_ops_init(struct iris_core *core) -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h -index 81685a284f23..3640f8504db9 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h -@@ -9,19 +9,34 @@ - #include - - #define HFI_VIDEO_ARCH_OX 0x1 -+ -+#define HFI_SESSION_TYPE_DEC 2 -+ -+#define HFI_VIDEO_CODEC_H264 0x00000002 -+ - #define HFI_ERR_NONE 0x0 - - #define HFI_CMD_SYS_INIT 0x10001 - #define HFI_CMD_SYS_PC_PREP 0x10002 - #define HFI_CMD_SYS_SET_PROPERTY 0x10005 - #define HFI_CMD_SYS_GET_PROPERTY 0x10006 -+#define HFI_CMD_SYS_SESSION_INIT 0x10007 -+#define HFI_CMD_SYS_SESSION_END 0x10008 - --#define HFI_PROPERTY_SYS_CODEC_POWER_PLANE_CTRL 0x5 --#define HFI_PROPERTY_SYS_IMAGE_VERSION 0x6 -+#define HFI_ERR_SESSION_UNSUPPORTED_SETTING 0x1008 -+#define HFI_ERR_SESSION_UNSUPPORT_BUFFERTYPE 0x1010 -+#define HFI_ERR_SESSION_INVALID_SCALE_FACTOR 0x1012 -+#define HFI_ERR_SESSION_UPSCALE_NOT_SUPPORTED 0x1013 - - #define HFI_EVENT_SYS_ERROR 0x1 -+#define HFI_EVENT_SESSION_ERROR 0x2 -+ -+#define HFI_PROPERTY_SYS_CODEC_POWER_PLANE_CTRL 0x5 -+#define HFI_PROPERTY_SYS_IMAGE_VERSION 0x6 - - #define HFI_MSG_SYS_INIT 0x20001 -+#define HFI_MSG_SYS_SESSION_INIT 0x20006 -+#define HFI_MSG_SYS_SESSION_END 0x20007 - #define HFI_MSG_SYS_COV 0x20009 - #define HFI_MSG_SYS_PROPERTY_INFO 0x2000a - -@@ -32,6 +47,21 @@ struct hfi_pkt_hdr { - u32 pkt_type; - }; - -+struct hfi_session_hdr_pkt { -+ struct hfi_pkt_hdr hdr; -+ u32 session_id; -+}; -+ -+struct hfi_session_open_pkt { -+ struct hfi_session_hdr_pkt shdr; -+ u32 session_domain; -+ u32 session_codec; -+}; -+ -+struct hfi_session_pkt { -+ struct hfi_session_hdr_pkt shdr; -+}; -+ - struct hfi_sys_init_pkt { - struct hfi_pkt_hdr hdr; - u32 arch_type; -@@ -54,7 +84,7 @@ struct hfi_sys_pc_prep_pkt { - }; - - struct hfi_msg_event_notify_pkt { -- struct hfi_pkt_hdr hdr; -+ struct hfi_session_hdr_pkt shdr; - u32 event_id; - u32 event_data1; - u32 event_data2; -@@ -68,6 +98,17 @@ struct hfi_msg_sys_init_done_pkt { - u32 data[]; - }; - -+struct hfi_msg_session_hdr_pkt { -+ struct hfi_session_hdr_pkt shdr; -+ u32 error_type; -+}; -+ -+struct hfi_msg_session_init_done_pkt { -+ struct hfi_msg_session_hdr_pkt shdr; -+ u32 num_properties; -+ u32 data[]; -+}; -+ - struct hfi_msg_sys_property_info_pkt { - struct hfi_pkt_hdr hdr; - u32 num_properties; -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c -index 78fefa4176f9..18ba5f67dd36 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c -@@ -13,13 +13,54 @@ iris_hfi_gen1_sys_event_notify(struct iris_core *core, void *packet) - struct hfi_msg_event_notify_pkt *pkt = packet; - - if (pkt->event_id == HFI_EVENT_SYS_ERROR) -- dev_err(core->dev, "sys error (type: %x, data1:%x, data2:%x)\n", -- pkt->event_id, pkt->event_data1, pkt->event_data2); -+ dev_err(core->dev, "sys error (type: %x, session id:%x, data1:%x, data2:%x)\n", -+ pkt->event_id, pkt->shdr.session_id, pkt->event_data1, -+ pkt->event_data2); - - core->state = IRIS_CORE_ERROR; - schedule_delayed_work(&core->sys_error_handler, msecs_to_jiffies(10)); - } - -+static void -+iris_hfi_gen1_event_session_error(struct iris_inst *inst, struct hfi_msg_event_notify_pkt *pkt) -+{ -+ switch (pkt->event_data1) { -+ /* non fatal session errors */ -+ case HFI_ERR_SESSION_INVALID_SCALE_FACTOR: -+ case HFI_ERR_SESSION_UNSUPPORT_BUFFERTYPE: -+ case HFI_ERR_SESSION_UNSUPPORTED_SETTING: -+ case HFI_ERR_SESSION_UPSCALE_NOT_SUPPORTED: -+ dev_dbg(inst->core->dev, "session error: event id:%x, session id:%x\n", -+ pkt->event_data1, pkt->shdr.session_id); -+ break; -+ /* fatal session errors */ -+ default: -+ /* -+ * firmware fills event_data2 as an additional information about the -+ * hfi command for which session error has ouccured. -+ */ -+ dev_err(inst->core->dev, -+ "session error for command: %x, event id:%x, session id:%x\n", -+ pkt->event_data2, pkt->event_data1, -+ pkt->shdr.session_id); -+ iris_vb2_queue_error(inst); -+ break; -+ } -+} -+ -+static void iris_hfi_gen1_session_event_notify(struct iris_inst *inst, void *packet) -+{ -+ struct hfi_msg_event_notify_pkt *pkt = packet; -+ -+ switch (pkt->event_id) { -+ case HFI_EVENT_SESSION_ERROR: -+ iris_hfi_gen1_event_session_error(inst, pkt); -+ break; -+ default: -+ break; -+ } -+} -+ - static void iris_hfi_gen1_sys_init_done(struct iris_core *core, void *packet) - { - struct hfi_msg_sys_init_done_pkt *pkt = packet; -@@ -99,6 +140,14 @@ static const struct iris_hfi_gen1_response_pkt_info pkt_infos[] = { - .pkt = HFI_MSG_SYS_PROPERTY_INFO, - .pkt_sz = sizeof(struct hfi_msg_sys_property_info_pkt), - }, -+ { -+ .pkt = HFI_MSG_SYS_SESSION_INIT, -+ .pkt_sz = sizeof(struct hfi_msg_session_init_done_pkt), -+ }, -+ { -+ .pkt = HFI_MSG_SYS_SESSION_END, -+ .pkt_sz = sizeof(struct hfi_msg_session_hdr_pkt), -+ }, - }; - - static void iris_hfi_gen1_handle_response(struct iris_core *core, void *response) -@@ -106,6 +155,8 @@ static void iris_hfi_gen1_handle_response(struct iris_core *core, void *response - struct hfi_pkt_hdr *hdr = (struct hfi_pkt_hdr *)response; - const struct iris_hfi_gen1_response_pkt_info *pkt_info; - struct device *dev = core->dev; -+ struct hfi_session_pkt *pkt; -+ struct iris_inst *inst; - bool found = false; - u32 i; - -@@ -132,9 +183,31 @@ static void iris_hfi_gen1_handle_response(struct iris_core *core, void *response - iris_hfi_gen1_sys_property_info(core, hdr); - break; - case HFI_MSG_EVENT_NOTIFY: -- iris_hfi_gen1_sys_event_notify(core, hdr); -+ pkt = (struct hfi_session_pkt *)hdr; -+ inst = iris_get_instance(core, pkt->shdr.session_id); -+ if (inst) { -+ mutex_lock(&inst->lock); -+ iris_hfi_gen1_session_event_notify(inst, hdr); -+ mutex_unlock(&inst->lock); -+ } else { -+ iris_hfi_gen1_sys_event_notify(core, hdr); -+ } -+ - break; - default: -+ pkt = (struct hfi_session_pkt *)hdr; -+ inst = iris_get_instance(core, pkt->shdr.session_id); -+ if (!inst) { -+ dev_warn(dev, "no valid instance(pkt session_id:%x, pkt:%x)\n", -+ pkt->shdr.session_id, -+ pkt_info ? pkt_info->pkt : 0); -+ return; -+ } -+ -+ mutex_lock(&inst->lock); -+ complete(&inst->completion); -+ mutex_unlock(&inst->lock); -+ - break; - } - } -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2.h b/drivers/media/platform/qcom/iris/iris_hfi_gen2.h -index c43b51774978..aaf6660bc1fe 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen2.h -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2.h -@@ -10,13 +10,18 @@ - - struct iris_core; - -+#define to_iris_inst_hfi_gen2(ptr) \ -+ container_of(ptr, struct iris_inst_hfi_gen2, inst) -+ - /** - * struct iris_inst_hfi_gen2 - holds per video instance parameters for hfi_gen2 - * - * @inst: pointer to iris_instance structure -+ * @packet: HFI packet - */ - struct iris_inst_hfi_gen2 { - struct iris_inst inst; -+ struct iris_hfi_header *packet; - }; - - void iris_hfi_gen2_command_ops_init(struct iris_core *core); -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c -index f8cb1177ef54..a08e844bb4bb 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c -@@ -85,11 +85,116 @@ static int iris_hfi_gen2_sys_pc_prep(struct iris_core *core) - return ret; - } - -+static int iris_hfi_gen2_session_set_codec(struct iris_inst *inst) -+{ -+ struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); -+ u32 codec = HFI_CODEC_DECODE_AVC; -+ -+ iris_hfi_gen2_packet_session_property(inst, -+ HFI_PROP_CODEC, -+ HFI_HOST_FLAGS_NONE, -+ HFI_PORT_NONE, -+ HFI_PAYLOAD_U32_ENUM, -+ &codec, -+ sizeof(u32)); -+ -+ return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet, -+ inst_hfi_gen2->packet->size); -+} -+ -+static int iris_hfi_gen2_session_set_default_header(struct iris_inst *inst) -+{ -+ struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); -+ u32 default_header = false; -+ -+ iris_hfi_gen2_packet_session_property(inst, -+ HFI_PROP_DEC_DEFAULT_HEADER, -+ HFI_HOST_FLAGS_NONE, -+ HFI_PORT_BITSTREAM, -+ HFI_PAYLOAD_U32, -+ &default_header, -+ sizeof(u32)); -+ -+ return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet, -+ inst_hfi_gen2->packet->size); -+} -+ -+static int iris_hfi_gen2_session_open(struct iris_inst *inst) -+{ -+ struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); -+ int ret; -+ -+ inst_hfi_gen2->packet = kzalloc(4096, GFP_KERNEL); -+ if (!inst_hfi_gen2->packet) -+ return -ENOMEM; -+ -+ iris_hfi_gen2_packet_session_command(inst, -+ HFI_CMD_OPEN, -+ HFI_HOST_FLAGS_RESPONSE_REQUIRED | -+ HFI_HOST_FLAGS_INTR_REQUIRED, -+ HFI_PORT_NONE, -+ 0, -+ HFI_PAYLOAD_U32, -+ &inst->session_id, -+ sizeof(u32)); -+ -+ ret = iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet, -+ inst_hfi_gen2->packet->size); -+ if (ret) -+ goto fail_free_packet; -+ -+ ret = iris_hfi_gen2_session_set_codec(inst); -+ if (ret) -+ goto fail_free_packet; -+ -+ ret = iris_hfi_gen2_session_set_default_header(inst); -+ if (ret) -+ goto fail_free_packet; -+ -+ return 0; -+ -+fail_free_packet: -+ kfree(inst_hfi_gen2->packet); -+ inst_hfi_gen2->packet = NULL; -+ -+ return ret; -+} -+ -+static int iris_hfi_gen2_session_close(struct iris_inst *inst) -+{ -+ struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); -+ int ret; -+ -+ if (!inst_hfi_gen2->packet) -+ return -EINVAL; -+ -+ iris_hfi_gen2_packet_session_command(inst, -+ HFI_CMD_CLOSE, -+ (HFI_HOST_FLAGS_RESPONSE_REQUIRED | -+ HFI_HOST_FLAGS_INTR_REQUIRED | -+ HFI_HOST_FLAGS_NON_DISCARDABLE), -+ HFI_PORT_NONE, -+ inst->session_id, -+ HFI_PAYLOAD_NONE, -+ NULL, -+ 0); -+ -+ ret = iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet, -+ inst_hfi_gen2->packet->size); -+ -+ kfree(inst_hfi_gen2->packet); -+ inst_hfi_gen2->packet = NULL; -+ -+ return ret; -+} -+ - static const struct iris_hfi_command_ops iris_hfi_gen2_command_ops = { - .sys_init = iris_hfi_gen2_sys_init, - .sys_image_version = iris_hfi_gen2_sys_image_version, - .sys_interframe_powercollapse = iris_hfi_gen2_sys_interframe_powercollapse, - .sys_pc_prep = iris_hfi_gen2_sys_pc_prep, -+ .session_open = iris_hfi_gen2_session_open, -+ .session_close = iris_hfi_gen2_session_close, - }; - - void iris_hfi_gen2_command_ops_init(struct iris_core *core) -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h -index e6a19ffc12fb..ccf5fd0902d7 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h -@@ -13,6 +13,8 @@ - #define HFI_CMD_BEGIN 0x01000000 - #define HFI_CMD_INIT 0x01000001 - #define HFI_CMD_POWER_COLLAPSE 0x01000002 -+#define HFI_CMD_OPEN 0x01000003 -+#define HFI_CMD_CLOSE 0x01000004 - #define HFI_CMD_END 0x01FFFFFF - - #define HFI_PROP_BEGIN 0x03000000 -@@ -25,12 +27,45 @@ - #define HFI_PROP_UBWC_BANK_SWZL_LEVEL2 0x03000007 - #define HFI_PROP_UBWC_BANK_SWZL_LEVEL3 0x03000008 - #define HFI_PROP_UBWC_BANK_SPREADING 0x03000009 -+#define HFI_PROP_CODEC 0x03000100 -+#define HFI_PROP_DEC_DEFAULT_HEADER 0x03000168 - #define HFI_PROP_END 0x03FFFFFF - -+#define HFI_SESSION_ERROR_BEGIN 0x04000000 -+#define HFI_ERROR_UNKNOWN_SESSION 0x04000001 -+#define HFI_ERROR_MAX_SESSIONS 0x04000002 -+#define HFI_ERROR_FATAL 0x04000003 -+#define HFI_ERROR_INVALID_STATE 0x04000004 -+#define HFI_ERROR_INSUFFICIENT_RESOURCES 0x04000005 -+#define HFI_ERROR_BUFFER_NOT_SET 0x04000006 -+#define HFI_ERROR_STREAM_UNSUPPORTED 0x04000008 -+#define HFI_SESSION_ERROR_END 0x04FFFFFF -+ - #define HFI_SYSTEM_ERROR_BEGIN 0x05000000 - #define HFI_SYS_ERROR_WD_TIMEOUT 0x05000001 - #define HFI_SYSTEM_ERROR_END 0x05FFFFFF - -+enum hfi_codec_type { -+ HFI_CODEC_DECODE_AVC = 1, -+ HFI_CODEC_ENCODE_AVC = 2, -+}; -+ -+enum hfi_buffer_type { -+ HFI_BUFFER_BITSTREAM = 0x00000001, -+ HFI_BUFFER_RAW = 0x00000002, -+ HFI_BUFFER_METADATA = 0x00000003, -+ HFI_BUFFER_SUBCACHE = 0x00000004, -+ HFI_BUFFER_PARTIAL_DATA = 0x00000005, -+ HFI_BUFFER_DPB = 0x00000006, -+ HFI_BUFFER_BIN = 0x00000007, -+ HFI_BUFFER_LINE = 0x00000008, -+ HFI_BUFFER_ARP = 0x00000009, -+ HFI_BUFFER_COMV = 0x0000000A, -+ HFI_BUFFER_NON_COMV = 0x0000000B, -+ HFI_BUFFER_PERSIST = 0x0000000C, -+ HFI_BUFFER_VPSS = 0x0000000D, -+}; -+ - enum hfi_packet_firmware_flags { - HFI_FW_FLAGS_SUCCESS = 0x00000001, - HFI_FW_FLAGS_INFORMATION = 0x00000002, -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.c -index 510d44408b41..739b2ce5bfae 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.c -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.c -@@ -143,6 +143,45 @@ void iris_hfi_gen2_packet_image_version(struct iris_core *core, struct iris_hfi_ - NULL, 0); - } - -+void iris_hfi_gen2_packet_session_command(struct iris_inst *inst, u32 pkt_type, -+ u32 flags, u32 port, u32 session_id, -+ u32 payload_type, void *payload, -+ u32 payload_size) -+{ -+ struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); -+ struct iris_core *core = inst->core; -+ -+ iris_hfi_gen2_create_header(inst_hfi_gen2->packet, session_id, core->header_id++); -+ -+ iris_hfi_gen2_create_packet(inst_hfi_gen2->packet, -+ pkt_type, -+ flags, -+ payload_type, -+ port, -+ core->packet_id++, -+ payload, -+ payload_size); -+} -+ -+void iris_hfi_gen2_packet_session_property(struct iris_inst *inst, -+ u32 pkt_type, u32 flags, u32 port, -+ u32 payload_type, void *payload, u32 payload_size) -+{ -+ struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); -+ struct iris_core *core = inst->core; -+ -+ iris_hfi_gen2_create_header(inst_hfi_gen2->packet, inst->session_id, core->header_id++); -+ -+ iris_hfi_gen2_create_packet(inst_hfi_gen2->packet, -+ pkt_type, -+ flags, -+ payload_type, -+ port, -+ core->packet_id++, -+ payload, -+ payload_size); -+} -+ - void iris_hfi_gen2_packet_sys_interframe_powercollapse(struct iris_core *core, - struct iris_hfi_header *hdr) - { -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.h b/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.h -index 3b771b7516de..4a9b88185b0d 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.h -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.h -@@ -63,6 +63,13 @@ struct iris_hfi_packet { - - void iris_hfi_gen2_packet_sys_init(struct iris_core *core, struct iris_hfi_header *hdr); - void iris_hfi_gen2_packet_image_version(struct iris_core *core, struct iris_hfi_header *hdr); -+void iris_hfi_gen2_packet_session_command(struct iris_inst *inst, u32 pkt_type, -+ u32 flags, u32 port, u32 session_id, -+ u32 payload_type, void *payload, -+ u32 payload_size); -+void iris_hfi_gen2_packet_session_property(struct iris_inst *inst, -+ u32 pkt_type, u32 flags, u32 port, -+ u32 payload_type, void *payload, u32 payload_size); - void iris_hfi_gen2_packet_sys_interframe_powercollapse(struct iris_core *core, - struct iris_hfi_header *hdr); - void iris_hfi_gen2_packet_sys_pc_prep(struct iris_core *core, struct iris_hfi_header *hdr); -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c -index 007e4a7b6782..e1c43daea6c7 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c -@@ -14,6 +14,17 @@ struct iris_hfi_gen2_core_hfi_range { - int (*handle)(struct iris_core *core, struct iris_hfi_packet *pkt); - }; - -+struct iris_hfi_gen2_inst_hfi_range { -+ u32 begin; -+ u32 end; -+ int (*handle)(struct iris_inst *inst, struct iris_hfi_packet *pkt); -+}; -+ -+struct iris_hfi_gen2_packet_handle { -+ enum hfi_buffer_type type; -+ int (*handle)(struct iris_inst *inst, struct iris_hfi_packet *pkt); -+}; -+ - static int iris_hfi_gen2_validate_packet(u8 *response_pkt, u8 *core_resp_pkt) - { - u8 *response_limit = core_resp_pkt + IFACEQ_CORE_PKT_SIZE; -@@ -55,6 +66,45 @@ static int iris_hfi_gen2_validate_hdr_packet(struct iris_core *core, struct iris - return 0; - } - -+static int iris_hfi_gen2_handle_session_error(struct iris_inst *inst, -+ struct iris_hfi_packet *pkt) -+{ -+ struct iris_core *core = inst->core; -+ char *error; -+ -+ switch (pkt->type) { -+ case HFI_ERROR_MAX_SESSIONS: -+ error = "exceeded max sessions"; -+ break; -+ case HFI_ERROR_UNKNOWN_SESSION: -+ error = "unknown session id"; -+ break; -+ case HFI_ERROR_INVALID_STATE: -+ error = "invalid operation for current state"; -+ break; -+ case HFI_ERROR_INSUFFICIENT_RESOURCES: -+ error = "insufficient resources"; -+ break; -+ case HFI_ERROR_BUFFER_NOT_SET: -+ error = "internal buffers not set"; -+ break; -+ case HFI_ERROR_FATAL: -+ error = "fatal error"; -+ break; -+ case HFI_ERROR_STREAM_UNSUPPORTED: -+ error = "unsupported stream"; -+ break; -+ default: -+ error = "unknown"; -+ break; -+ } -+ -+ dev_err(core->dev, "session error received %#x: %s\n", pkt->type, error); -+ iris_vb2_queue_error(inst); -+ -+ return 0; -+} -+ - static int iris_hfi_gen2_handle_system_error(struct iris_core *core, - struct iris_hfi_packet *pkt) - { -@@ -79,6 +129,22 @@ static int iris_hfi_gen2_handle_system_init(struct iris_core *core, - return 0; - } - -+static int iris_hfi_gen2_handle_session_command(struct iris_inst *inst, -+ struct iris_hfi_packet *pkt) -+{ -+ int ret = 0; -+ -+ switch (pkt->type) { -+ case HFI_CMD_CLOSE: -+ complete(&inst->completion); -+ break; -+ default: -+ break; -+ } -+ -+ return ret; -+} -+ - static int iris_hfi_gen2_handle_image_version_property(struct iris_core *core, - struct iris_hfi_packet *pkt) - { -@@ -152,6 +218,46 @@ static int iris_hfi_gen2_handle_system_response(struct iris_core *core, - return 0; - } - -+static int iris_hfi_gen2_handle_session_response(struct iris_core *core, -+ struct iris_hfi_header *hdr) -+{ -+ struct iris_hfi_packet *packet; -+ struct iris_inst *inst; -+ int ret = 0; -+ u32 i, j; -+ u8 *pkt; -+ static const struct iris_hfi_gen2_inst_hfi_range range[] = { -+ {HFI_SESSION_ERROR_BEGIN, HFI_SESSION_ERROR_END, -+ iris_hfi_gen2_handle_session_error}, -+ {HFI_CMD_BEGIN, HFI_CMD_END, -+ iris_hfi_gen2_handle_session_command }, -+ }; -+ -+ inst = iris_get_instance(core, hdr->session_id); -+ if (!inst) -+ return -EINVAL; -+ -+ mutex_lock(&inst->lock); -+ -+ pkt = (u8 *)((u8 *)hdr + sizeof(*hdr)); -+ for (i = 0; i < ARRAY_SIZE(range); i++) { -+ pkt = (u8 *)((u8 *)hdr + sizeof(*hdr)); -+ for (j = 0; j < hdr->num_packets; j++) { -+ packet = (struct iris_hfi_packet *)pkt; -+ if (packet->flags & HFI_FW_FLAGS_SESSION_ERROR) -+ iris_hfi_gen2_handle_session_error(inst, packet); -+ -+ if (packet->type > range[i].begin && packet->type < range[i].end) -+ ret = range[i].handle(inst, packet); -+ pkt += packet->size; -+ } -+ } -+ -+ mutex_unlock(&inst->lock); -+ -+ return ret; -+} -+ - static int iris_hfi_gen2_handle_response(struct iris_core *core, void *response) - { - struct iris_hfi_header *hdr = (struct iris_hfi_header *)response; -@@ -161,7 +267,10 @@ static int iris_hfi_gen2_handle_response(struct iris_core *core, void *response) - if (ret) - return iris_hfi_gen2_handle_system_error(core, NULL); - -- return iris_hfi_gen2_handle_system_response(core, hdr); -+ if (!hdr->session_id) -+ return iris_hfi_gen2_handle_system_response(core, hdr); -+ else -+ return iris_hfi_gen2_handle_session_response(core, hdr); - } - - static void iris_hfi_gen2_flush_debug_queue(struct iris_core *core, u8 *packet) -diff --git a/drivers/media/platform/qcom/iris/iris_instance.h b/drivers/media/platform/qcom/iris/iris_instance.h -index 527a270f12d4..b9c7dcfb20f7 100644 ---- a/drivers/media/platform/qcom/iris/iris_instance.h -+++ b/drivers/media/platform/qcom/iris/iris_instance.h -@@ -6,24 +6,46 @@ - #ifndef __IRIS_INSTANCE_H__ - #define __IRIS_INSTANCE_H__ - -+#include -+ -+#include "iris_buffer.h" - #include "iris_core.h" -+#include "iris_utils.h" - - /** - * struct iris_inst - holds per video instance parameters - * -+ * @list: used for attach an instance to the core - * @core: pointer to core structure -+ * @session_id: id of current video session - * @ctx_q_lock: lock to serialize queues related ioctls - * @lock: lock to seralise forward and reverse threads - * @fh: reference of v4l2 file handler -+ * @fmt_src: structure of v4l2_format for source -+ * @fmt_dst: structure of v4l2_format for destination -+ * @crop: structure of crop info -+ * @completion: structure of signal completions -+ * @buffers: array of different iris buffers -+ * @fw_min_count: minimnum count of buffers needed by fw -+ * @once_per_session_set: boolean to set once per session property - * @m2m_dev: a reference to m2m device structure - * @m2m_ctx: a reference to m2m context structure - */ - - struct iris_inst { -+ struct list_head list; - struct iris_core *core; -+ u32 session_id; - struct mutex ctx_q_lock;/* lock to serialize queues related ioctls */ - struct mutex lock; /* lock to serialize forward and reverse threads */ - struct v4l2_fh fh; -+ struct v4l2_format *fmt_src; -+ struct v4l2_format *fmt_dst; -+ struct iris_hfi_rect_desc crop; -+ struct completion completion; -+ struct iris_buffers buffers[BUF_TYPE_MAX]; -+ u32 fw_min_count; -+ bool once_per_session_set; - struct v4l2_m2m_dev *m2m_dev; - struct v4l2_m2m_ctx *m2m_ctx; - }; -diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h -index 69c0a8b3d12d..d508477b066e 100644 ---- a/drivers/media/platform/qcom/iris/iris_platform_common.h -+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h -@@ -42,6 +42,9 @@ struct ubwc_config_data { - u32 bank_spreading; - }; - -+struct platform_inst_caps { -+ u32 max_mbpf; -+}; - struct iris_core_power { - u64 clk_freq; - u64 icc_bw; -@@ -71,11 +74,13 @@ struct iris_platform_data { - u64 dma_mask; - const char *fwname; - u32 pas_id; -+ struct platform_inst_caps *inst_caps; - struct tz_cp_config *tz_cp_config_data; - u32 core_arch; - u32 hw_response_timeout; - struct ubwc_config_data *ubwc_config; - u32 num_vpp_pipe; -+ u32 max_session_count; - }; - - #endif -diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c -index ed99cdb13d06..e4232c755074 100644 ---- a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c -+++ b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c -@@ -10,6 +10,10 @@ - - #define VIDEO_ARCH_LX 1 - -+static struct platform_inst_caps platform_inst_cap_sm8550 = { -+ .max_mbpf = (8192 * 4352) / 256, -+}; -+ - static void iris_set_sm8550_preset_registers(struct iris_core *core) - { - writel(0x0, core->reg_base + 0xB0088); -@@ -69,9 +73,11 @@ struct iris_platform_data sm8550_data = { - .dma_mask = 0xe0000000 - 1, - .fwname = "qcom/vpu/vpu30_p4.mbn", - .pas_id = IRIS_PAS_ID, -+ .inst_caps = &platform_inst_cap_sm8550, - .tz_cp_config_data = &tz_cp_config_sm8550, - .core_arch = VIDEO_ARCH_LX, - .hw_response_timeout = HW_RESPONSE_TIMEOUT_VALUE, - .ubwc_config = &ubwc_config_sm8550, - .num_vpp_pipe = 4, -+ .max_session_count = 16, - }; -diff --git a/drivers/media/platform/qcom/iris/iris_probe.c b/drivers/media/platform/qcom/iris/iris_probe.c -index e8ef258b4f2e..a9162be5f9f6 100644 ---- a/drivers/media/platform/qcom/iris/iris_probe.c -+++ b/drivers/media/platform/qcom/iris/iris_probe.c -@@ -142,6 +142,7 @@ static int iris_register_video_device(struct iris_core *core) - strscpy(vdev->name, "qcom-iris-decoder", sizeof(vdev->name)); - vdev->release = video_device_release; - vdev->fops = core->iris_v4l2_file_ops; -+ vdev->ioctl_ops = core->iris_v4l2_ioctl_ops; - vdev->vfl_dir = VFL_DIR_M2M; - vdev->v4l2_dev = &core->v4l2_dev; - vdev->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING; -@@ -207,6 +208,7 @@ static int iris_probe(struct platform_device *pdev) - if (!core->response_packet) - return -ENOMEM; - -+ INIT_LIST_HEAD(&core->instances); - INIT_DELAYED_WORK(&core->sys_error_handler, iris_sys_error_handler); - - core->reg_base = devm_platform_ioremap_resource(pdev, 0); -diff --git a/drivers/media/platform/qcom/iris/iris_utils.c b/drivers/media/platform/qcom/iris/iris_utils.c -new file mode 100644 -index 000000000000..d5c8e052922c ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_utils.c -@@ -0,0 +1,52 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#include -+ -+#include "iris_instance.h" -+#include "iris_utils.h" -+ -+int iris_get_mbpf(struct iris_inst *inst) -+{ -+ struct v4l2_format *inp_f = inst->fmt_src; -+ u32 height = max(inp_f->fmt.pix_mp.height, inst->crop.height); -+ u32 width = max(inp_f->fmt.pix_mp.width, inst->crop.width); -+ -+ return NUM_MBS_PER_FRAME(height, width); -+} -+ -+int iris_wait_for_session_response(struct iris_inst *inst) -+{ -+ struct iris_core *core = inst->core; -+ u32 hw_response_timeout_val; -+ int ret; -+ -+ hw_response_timeout_val = core->iris_platform_data->hw_response_timeout; -+ -+ mutex_unlock(&inst->lock); -+ ret = wait_for_completion_timeout(&inst->completion, -+ msecs_to_jiffies(hw_response_timeout_val)); -+ mutex_lock(&inst->lock); -+ if (!ret) -+ return -ETIMEDOUT; -+ -+ return 0; -+} -+ -+struct iris_inst *iris_get_instance(struct iris_core *core, u32 session_id) -+{ -+ struct iris_inst *inst; -+ -+ mutex_lock(&core->lock); -+ list_for_each_entry(inst, &core->instances, list) { -+ if (inst->session_id == session_id) { -+ mutex_unlock(&core->lock); -+ return inst; -+ } -+ } -+ -+ mutex_unlock(&core->lock); -+ return NULL; -+} -diff --git a/drivers/media/platform/qcom/iris/iris_utils.h b/drivers/media/platform/qcom/iris/iris_utils.h -new file mode 100644 -index 000000000000..26649b66d978 ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_utils.h -@@ -0,0 +1,34 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#ifndef __IRIS_UTILS_H__ -+#define __IRIS_UTILS_H__ -+ -+struct iris_core; -+#include "iris_buffer.h" -+ -+struct iris_hfi_rect_desc { -+ u32 left; -+ u32 top; -+ u32 width; -+ u32 height; -+}; -+ -+#define NUM_MBS_PER_FRAME(height, width) \ -+ (DIV_ROUND_UP(height, 16) * DIV_ROUND_UP(width, 16)) -+ -+static inline enum iris_buffer_type iris_v4l2_type_to_driver(u32 type) -+{ -+ if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) -+ return BUF_INPUT; -+ else -+ return BUF_OUTPUT; -+} -+ -+int iris_get_mbpf(struct iris_inst *inst); -+struct iris_inst *iris_get_instance(struct iris_core *core, u32 session_id); -+int iris_wait_for_session_response(struct iris_inst *inst); -+ -+#endif -diff --git a/drivers/media/platform/qcom/iris/iris_vb2.c b/drivers/media/platform/qcom/iris/iris_vb2.c -new file mode 100644 -index 000000000000..e9db44515d91 ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_vb2.c -@@ -0,0 +1,50 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#include "iris_instance.h" -+#include "iris_vb2.h" -+ -+int iris_vb2_queue_setup(struct vb2_queue *q, -+ unsigned int *num_buffers, unsigned int *num_planes, -+ unsigned int sizes[], struct device *alloc_devs[]) -+{ -+ struct iris_inst *inst; -+ struct iris_core *core; -+ struct v4l2_format *f; -+ int ret = 0; -+ -+ inst = vb2_get_drv_priv(q); -+ -+ mutex_lock(&inst->lock); -+ -+ core = inst->core; -+ f = V4L2_TYPE_IS_OUTPUT(q->type) ? inst->fmt_src : inst->fmt_dst; -+ -+ if (*num_planes) { -+ if (*num_planes != f->fmt.pix_mp.num_planes || -+ sizes[0] < f->fmt.pix_mp.plane_fmt[0].sizeimage) -+ ret = -EINVAL; -+ goto unlock; -+ } -+ -+ if (!inst->once_per_session_set) { -+ inst->once_per_session_set = true; -+ -+ ret = core->hfi_ops->session_open(inst); -+ if (ret) { -+ ret = -EINVAL; -+ dev_err(core->dev, "session open failed\n"); -+ goto unlock; -+ } -+ } -+ -+ *num_planes = 1; -+ sizes[0] = f->fmt.pix_mp.plane_fmt[0].sizeimage; -+ -+unlock: -+ mutex_unlock(&inst->lock); -+ -+ return ret; -+} -diff --git a/drivers/media/platform/qcom/iris/iris_vb2.h b/drivers/media/platform/qcom/iris/iris_vb2.h -new file mode 100644 -index 000000000000..d2e71d0596cc ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_vb2.h -@@ -0,0 +1,12 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#ifndef __IRIS_VB2_H__ -+#define __IRIS_VB2_H__ -+ -+int iris_vb2_queue_setup(struct vb2_queue *q, -+ unsigned int *num_buffers, unsigned int *num_planes, -+ unsigned int sizes[], struct device *alloc_devs[]); -+#endif -diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c b/drivers/media/platform/qcom/iris/iris_vdec.c -new file mode 100644 -index 000000000000..2ed50ad5d58b ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_vdec.c -@@ -0,0 +1,56 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#include "iris_buffer.h" -+#include "iris_instance.h" -+#include "iris_vdec.h" -+#include "iris_vpu_buffer.h" -+ -+#define DEFAULT_WIDTH 320 -+#define DEFAULT_HEIGHT 240 -+ -+void iris_vdec_inst_init(struct iris_inst *inst) -+{ -+ struct v4l2_format *f; -+ -+ inst->fmt_src = kzalloc(sizeof(*inst->fmt_src), GFP_KERNEL); -+ inst->fmt_dst = kzalloc(sizeof(*inst->fmt_dst), GFP_KERNEL); -+ -+ inst->fw_min_count = MIN_BUFFERS; -+ -+ f = inst->fmt_src; -+ f->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; -+ f->fmt.pix_mp.width = DEFAULT_WIDTH; -+ f->fmt.pix_mp.height = DEFAULT_HEIGHT; -+ f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264; -+ f->fmt.pix_mp.num_planes = 1; -+ f->fmt.pix_mp.plane_fmt[0].bytesperline = 0; -+ f->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_INPUT); -+ f->fmt.pix_mp.field = V4L2_FIELD_NONE; -+ inst->buffers[BUF_INPUT].min_count = iris_vpu_buf_count(inst, BUF_INPUT); -+ inst->buffers[BUF_INPUT].size = f->fmt.pix_mp.plane_fmt[0].sizeimage; -+ -+ f = inst->fmt_dst; -+ f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; -+ f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12; -+ f->fmt.pix_mp.width = ALIGN(DEFAULT_WIDTH, 128); -+ f->fmt.pix_mp.height = ALIGN(DEFAULT_HEIGHT, 32); -+ f->fmt.pix_mp.num_planes = 1; -+ f->fmt.pix_mp.plane_fmt[0].bytesperline = ALIGN(DEFAULT_WIDTH, 128); -+ f->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_OUTPUT); -+ f->fmt.pix_mp.field = V4L2_FIELD_NONE; -+ f->fmt.pix_mp.colorspace = V4L2_COLORSPACE_DEFAULT; -+ f->fmt.pix_mp.xfer_func = V4L2_XFER_FUNC_DEFAULT; -+ f->fmt.pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; -+ f->fmt.pix_mp.quantization = V4L2_QUANTIZATION_DEFAULT; -+ inst->buffers[BUF_OUTPUT].min_count = iris_vpu_buf_count(inst, BUF_OUTPUT); -+ inst->buffers[BUF_OUTPUT].size = f->fmt.pix_mp.plane_fmt[0].sizeimage; -+} -+ -+void iris_vdec_inst_deinit(struct iris_inst *inst) -+{ -+ kfree(inst->fmt_dst); -+ kfree(inst->fmt_src); -+} -diff --git a/drivers/media/platform/qcom/iris/iris_vdec.h b/drivers/media/platform/qcom/iris/iris_vdec.h -new file mode 100644 -index 000000000000..353b73b76230 ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_vdec.h -@@ -0,0 +1,14 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#ifndef __IRIS_VDEC_H__ -+#define __IRIS_VDEC_H__ -+ -+struct iris_inst; -+ -+void iris_vdec_inst_init(struct iris_inst *inst); -+void iris_vdec_inst_deinit(struct iris_inst *inst); -+ -+#endif -diff --git a/drivers/media/platform/qcom/iris/iris_vidc.c b/drivers/media/platform/qcom/iris/iris_vidc.c -index b8654e73f516..ab3b63171c1d 100644 ---- a/drivers/media/platform/qcom/iris/iris_vidc.c -+++ b/drivers/media/platform/qcom/iris/iris_vidc.c -@@ -9,6 +9,9 @@ - - #include "iris_vidc.h" - #include "iris_instance.h" -+#include "iris_vdec.h" -+#include "iris_vb2.h" -+#include "iris_vpu_buffer.h" - #include "iris_platform_common.h" - - #define IRIS_DRV_NAME "iris_driver" -@@ -28,6 +31,38 @@ static void iris_v4l2_fh_deinit(struct iris_inst *inst) - v4l2_fh_exit(&inst->fh); - } - -+static void iris_add_session(struct iris_inst *inst) -+{ -+ struct iris_core *core = inst->core; -+ struct iris_inst *iter; -+ u32 count = 0; -+ -+ mutex_lock(&core->lock); -+ -+ list_for_each_entry(iter, &core->instances, list) -+ count++; -+ -+ if (count < core->iris_platform_data->max_session_count) -+ list_add_tail(&inst->list, &core->instances); -+ -+ mutex_unlock(&core->lock); -+} -+ -+static void iris_remove_session(struct iris_inst *inst) -+{ -+ struct iris_core *core = inst->core; -+ struct iris_inst *iter, *temp; -+ -+ mutex_lock(&core->lock); -+ list_for_each_entry_safe(iter, temp, &core->instances, list) { -+ if (iter->session_id == inst->session_id) { -+ list_del_init(&iter->list); -+ break; -+ } -+ } -+ mutex_unlock(&core->lock); -+} -+ - static inline struct iris_inst *iris_get_inst(struct file *filp, void *fh) - { - return container_of(filp->private_data, struct iris_inst, fh); -@@ -59,7 +94,10 @@ iris_m2m_queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_ - src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - src_vq->io_modes = VB2_MMAP | VB2_DMABUF; - src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; -+ src_vq->ops = inst->core->iris_vb2_ops; - src_vq->drv_priv = inst; -+ src_vq->buf_struct_size = sizeof(struct iris_buffer); -+ src_vq->min_reqbufs_allocation = MIN_BUFFERS; - src_vq->dev = inst->core->dev; - src_vq->lock = &inst->ctx_q_lock; - ret = vb2_queue_init(src_vq); -@@ -69,7 +107,10 @@ iris_m2m_queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_ - dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - dst_vq->io_modes = VB2_MMAP | VB2_DMABUF; - dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; -+ dst_vq->ops = inst->core->iris_vb2_ops; - dst_vq->drv_priv = inst; -+ dst_vq->buf_struct_size = sizeof(struct iris_buffer); -+ dst_vq->min_reqbufs_allocation = MIN_BUFFERS; - dst_vq->dev = inst->core->dev; - dst_vq->lock = &inst->ctx_q_lock; - -@@ -100,8 +141,11 @@ int iris_open(struct file *filp) - return -ENOMEM; - - inst->core = core; -+ inst->session_id = hash32_ptr(inst); - -+ mutex_init(&inst->lock); - mutex_init(&inst->ctx_q_lock); -+ init_completion(&inst->completion); - - iris_v4l2_fh_init(inst); - -@@ -117,6 +161,10 @@ int iris_open(struct file *filp) - goto fail_m2m_release; - } - -+ iris_vdec_inst_init(inst); -+ -+ iris_add_session(inst); -+ - inst->fh.m2m_ctx = inst->m2m_ctx; - filp->private_data = &inst->fh; - -@@ -127,19 +175,42 @@ int iris_open(struct file *filp) - fail_v4l2_fh_deinit: - iris_v4l2_fh_deinit(inst); - mutex_destroy(&inst->ctx_q_lock); -+ mutex_destroy(&inst->lock); - kfree(inst); - - return ret; - } - -+static void iris_session_close(struct iris_inst *inst) -+{ -+ const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; -+ bool wait_for_response = true; -+ int ret; -+ -+ reinit_completion(&inst->completion); -+ -+ ret = hfi_ops->session_close(inst); -+ if (ret) -+ wait_for_response = false; -+ -+ if (wait_for_response) -+ iris_wait_for_session_response(inst); -+} -+ - int iris_close(struct file *filp) - { - struct iris_inst *inst = iris_get_inst(filp, NULL); - - v4l2_m2m_ctx_release(inst->m2m_ctx); - v4l2_m2m_release(inst->m2m_dev); -+ mutex_lock(&inst->lock); -+ iris_vdec_inst_deinit(inst); -+ iris_session_close(inst); - iris_v4l2_fh_deinit(inst); -+ iris_remove_session(inst); -+ mutex_unlock(&inst->lock); - mutex_destroy(&inst->ctx_q_lock); -+ mutex_destroy(&inst->lock); - kfree(inst); - filp->private_data = NULL; - -@@ -155,7 +226,17 @@ static struct v4l2_file_operations iris_v4l2_file_ops = { - .mmap = v4l2_m2m_fop_mmap, - }; - -+static const struct vb2_ops iris_vb2_ops = { -+ .queue_setup = iris_vb2_queue_setup, -+}; -+ -+static const struct v4l2_ioctl_ops iris_v4l2_ioctl_ops = { -+ .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, -+}; -+ - void iris_init_ops(struct iris_core *core) - { - core->iris_v4l2_file_ops = &iris_v4l2_file_ops; -+ core->iris_vb2_ops = &iris_vb2_ops; -+ core->iris_v4l2_ioctl_ops = &iris_v4l2_ioctl_ops; - } -diff --git a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c b/drivers/media/platform/qcom/iris/iris_vpu_buffer.c -new file mode 100644 -index 000000000000..2402a33723ab ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_vpu_buffer.c -@@ -0,0 +1,19 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#include "iris_instance.h" -+#include "iris_vpu_buffer.h" -+ -+int iris_vpu_buf_count(struct iris_inst *inst, enum iris_buffer_type buffer_type) -+{ -+ switch (buffer_type) { -+ case BUF_INPUT: -+ return MIN_BUFFERS; -+ case BUF_OUTPUT: -+ return inst->fw_min_count; -+ default: -+ return 0; -+ } -+} -diff --git a/drivers/media/platform/qcom/iris/iris_vpu_buffer.h b/drivers/media/platform/qcom/iris/iris_vpu_buffer.h -new file mode 100644 -index 000000000000..06e6e958dcac ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_vpu_buffer.h -@@ -0,0 +1,15 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#ifndef __IRIS_VPU_BUFFER_H__ -+#define __IRIS_VPU_BUFFER_H__ -+ -+struct iris_inst; -+ -+#define MIN_BUFFERS 4 -+ -+int iris_vpu_buf_count(struct iris_inst *inst, enum iris_buffer_type buffer_type); -+ -+#endif --- -2.34.1 - diff --git a/patch/kernel/archive/sm8550-6.12/0010_media--iris--implement-s_fmt,-g_fmt-and-try_fmt-io.patch b/patch/kernel/archive/sm8550-6.12/0010_media--iris--implement-s_fmt,-g_fmt-and-try_fmt-io.patch deleted file mode 100644 index 31a3f4e78d9e..000000000000 --- a/patch/kernel/archive/sm8550-6.12/0010_media--iris--implement-s_fmt,-g_fmt-and-try_fmt-io.patch +++ /dev/null @@ -1,248 +0,0 @@ -From 8f9fd0b682dbead270bc0cb83e0511af1f5f4e6d Mon Sep 17 00:00:00 2001 -From: Vedang Nagar -Date: Fri, 7 Feb 2025 13:24:50 +0530 -Subject: [PATCH] media: iris: implement s_fmt, g_fmt and try_fmt ioctls - -Implement the s_fmt, g_fmt and try_fmt ioctl ops with the necessary -hooks. - -Signed-off-by: Vedang Nagar -Reviewed-by: Hans Verkuil -Tested-by: Stefan Schmidt # x1e80100 (Dell XPS 13 9345) -Reviewed-by: Stefan Schmidt -Tested-by: Neil Armstrong # on SM8550-QRD -Tested-by: Neil Armstrong # on SM8550-HDK -Signed-off-by: Dikshita Agarwal -Link: https://lore.kernel.org/r/20250207-qcom-video-iris-v10-10-ab66eeffbd20@quicinc.com -Signed-off-by: Neil Armstrong ---- - drivers/media/platform/qcom/iris/iris_vdec.c | 122 +++++++++++++++++++ - drivers/media/platform/qcom/iris/iris_vdec.h | 2 + - drivers/media/platform/qcom/iris/iris_vidc.c | 48 ++++++++ - 3 files changed, 172 insertions(+) - -diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c b/drivers/media/platform/qcom/iris/iris_vdec.c -index 2ed50ad5d58b..38a5df8191cc 100644 ---- a/drivers/media/platform/qcom/iris/iris_vdec.c -+++ b/drivers/media/platform/qcom/iris/iris_vdec.c -@@ -3,6 +3,8 @@ - * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. - */ - -+#include -+ - #include "iris_buffer.h" - #include "iris_instance.h" - #include "iris_vdec.h" -@@ -10,6 +12,7 @@ - - #define DEFAULT_WIDTH 320 - #define DEFAULT_HEIGHT 240 -+#define DEFAULT_CODEC_ALIGNMENT 16 - - void iris_vdec_inst_init(struct iris_inst *inst) - { -@@ -54,3 +57,122 @@ void iris_vdec_inst_deinit(struct iris_inst *inst) - kfree(inst->fmt_dst); - kfree(inst->fmt_src); - } -+ -+int iris_vdec_try_fmt(struct iris_inst *inst, struct v4l2_format *f) -+{ -+ struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp; -+ struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; -+ struct v4l2_format *f_inst; -+ struct vb2_queue *src_q; -+ -+ memset(pixmp->reserved, 0, sizeof(pixmp->reserved)); -+ switch (f->type) { -+ case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: -+ if (f->fmt.pix_mp.pixelformat != V4L2_PIX_FMT_H264) { -+ f_inst = inst->fmt_src; -+ f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width; -+ f->fmt.pix_mp.height = f_inst->fmt.pix_mp.height; -+ f->fmt.pix_mp.pixelformat = f_inst->fmt.pix_mp.pixelformat; -+ } -+ break; -+ case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: -+ if (f->fmt.pix_mp.pixelformat != V4L2_PIX_FMT_NV12) { -+ f_inst = inst->fmt_dst; -+ f->fmt.pix_mp.pixelformat = f_inst->fmt.pix_mp.pixelformat; -+ f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width; -+ f->fmt.pix_mp.height = f_inst->fmt.pix_mp.height; -+ } -+ -+ src_q = v4l2_m2m_get_src_vq(m2m_ctx); -+ if (vb2_is_streaming(src_q)) { -+ f_inst = inst->fmt_src; -+ f->fmt.pix_mp.height = f_inst->fmt.pix_mp.height; -+ f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width; -+ } -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ if (pixmp->field == V4L2_FIELD_ANY) -+ pixmp->field = V4L2_FIELD_NONE; -+ -+ pixmp->num_planes = 1; -+ -+ return 0; -+} -+ -+int iris_vdec_s_fmt(struct iris_inst *inst, struct v4l2_format *f) -+{ -+ struct v4l2_format *fmt, *output_fmt; -+ struct vb2_queue *q; -+ u32 codec_align; -+ -+ q = v4l2_m2m_get_vq(inst->m2m_ctx, f->type); -+ if (!q) -+ return -EINVAL; -+ -+ if (vb2_is_busy(q)) -+ return -EBUSY; -+ -+ iris_vdec_try_fmt(inst, f); -+ -+ switch (f->type) { -+ case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: -+ if (f->fmt.pix_mp.pixelformat != V4L2_PIX_FMT_H264) -+ return -EINVAL; -+ -+ fmt = inst->fmt_src; -+ fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; -+ -+ codec_align = DEFAULT_CODEC_ALIGNMENT; -+ fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, codec_align); -+ fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, codec_align); -+ fmt->fmt.pix_mp.num_planes = 1; -+ fmt->fmt.pix_mp.plane_fmt[0].bytesperline = 0; -+ fmt->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_INPUT); -+ inst->buffers[BUF_INPUT].min_count = iris_vpu_buf_count(inst, BUF_INPUT); -+ inst->buffers[BUF_INPUT].size = fmt->fmt.pix_mp.plane_fmt[0].sizeimage; -+ -+ fmt->fmt.pix_mp.colorspace = f->fmt.pix_mp.colorspace; -+ fmt->fmt.pix_mp.xfer_func = f->fmt.pix_mp.xfer_func; -+ fmt->fmt.pix_mp.ycbcr_enc = f->fmt.pix_mp.ycbcr_enc; -+ fmt->fmt.pix_mp.quantization = f->fmt.pix_mp.quantization; -+ -+ output_fmt = inst->fmt_dst; -+ output_fmt->fmt.pix_mp.colorspace = f->fmt.pix_mp.colorspace; -+ output_fmt->fmt.pix_mp.xfer_func = f->fmt.pix_mp.xfer_func; -+ output_fmt->fmt.pix_mp.ycbcr_enc = f->fmt.pix_mp.ycbcr_enc; -+ output_fmt->fmt.pix_mp.quantization = f->fmt.pix_mp.quantization; -+ -+ inst->crop.left = 0; -+ inst->crop.top = 0; -+ inst->crop.width = f->fmt.pix_mp.width; -+ inst->crop.height = f->fmt.pix_mp.height; -+ break; -+ case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: -+ fmt = inst->fmt_dst; -+ fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; -+ if (fmt->fmt.pix_mp.pixelformat != V4L2_PIX_FMT_NV12) -+ return -EINVAL; -+ fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat; -+ fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, 128); -+ fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, 32); -+ fmt->fmt.pix_mp.num_planes = 1; -+ fmt->fmt.pix_mp.plane_fmt[0].bytesperline = ALIGN(f->fmt.pix_mp.width, 128); -+ fmt->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_OUTPUT); -+ inst->buffers[BUF_OUTPUT].min_count = iris_vpu_buf_count(inst, BUF_OUTPUT); -+ inst->buffers[BUF_OUTPUT].size = fmt->fmt.pix_mp.plane_fmt[0].sizeimage; -+ -+ inst->crop.top = 0; -+ inst->crop.left = 0; -+ inst->crop.width = f->fmt.pix_mp.width; -+ inst->crop.height = f->fmt.pix_mp.height; -+ break; -+ default: -+ return -EINVAL; -+ } -+ memcpy(f, fmt, sizeof(*fmt)); -+ -+ return 0; -+} -diff --git a/drivers/media/platform/qcom/iris/iris_vdec.h b/drivers/media/platform/qcom/iris/iris_vdec.h -index 353b73b76230..85e93f33e9e7 100644 ---- a/drivers/media/platform/qcom/iris/iris_vdec.h -+++ b/drivers/media/platform/qcom/iris/iris_vdec.h -@@ -10,5 +10,7 @@ struct iris_inst; - - void iris_vdec_inst_init(struct iris_inst *inst); - void iris_vdec_inst_deinit(struct iris_inst *inst); -+int iris_vdec_try_fmt(struct iris_inst *inst, struct v4l2_format *f); -+int iris_vdec_s_fmt(struct iris_inst *inst, struct v4l2_format *f); - - #endif -diff --git a/drivers/media/platform/qcom/iris/iris_vidc.c b/drivers/media/platform/qcom/iris/iris_vidc.c -index ab3b63171c1d..bec965284b6e 100644 ---- a/drivers/media/platform/qcom/iris/iris_vidc.c -+++ b/drivers/media/platform/qcom/iris/iris_vidc.c -@@ -217,6 +217,48 @@ int iris_close(struct file *filp) - return 0; - } - -+static int iris_try_fmt_vid_mplane(struct file *filp, void *fh, struct v4l2_format *f) -+{ -+ struct iris_inst *inst = iris_get_inst(filp, NULL); -+ int ret; -+ -+ mutex_lock(&inst->lock); -+ ret = iris_vdec_try_fmt(inst, f); -+ mutex_unlock(&inst->lock); -+ -+ return ret; -+} -+ -+static int iris_s_fmt_vid_mplane(struct file *filp, void *fh, struct v4l2_format *f) -+{ -+ struct iris_inst *inst = iris_get_inst(filp, NULL); -+ int ret; -+ -+ mutex_lock(&inst->lock); -+ ret = iris_vdec_s_fmt(inst, f); -+ mutex_unlock(&inst->lock); -+ -+ return ret; -+} -+ -+static int iris_g_fmt_vid_mplane(struct file *filp, void *fh, struct v4l2_format *f) -+{ -+ struct iris_inst *inst = iris_get_inst(filp, NULL); -+ int ret = 0; -+ -+ mutex_lock(&inst->lock); -+ if (V4L2_TYPE_IS_OUTPUT(f->type)) -+ *f = *inst->fmt_src; -+ else if (V4L2_TYPE_IS_CAPTURE(f->type)) -+ *f = *inst->fmt_dst; -+ else -+ ret = -EINVAL; -+ -+ mutex_unlock(&inst->lock); -+ -+ return ret; -+} -+ - static struct v4l2_file_operations iris_v4l2_file_ops = { - .owner = THIS_MODULE, - .open = iris_open, -@@ -231,6 +273,12 @@ static const struct vb2_ops iris_vb2_ops = { - }; - - static const struct v4l2_ioctl_ops iris_v4l2_ioctl_ops = { -+ .vidioc_try_fmt_vid_cap_mplane = iris_try_fmt_vid_mplane, -+ .vidioc_try_fmt_vid_out_mplane = iris_try_fmt_vid_mplane, -+ .vidioc_s_fmt_vid_cap_mplane = iris_s_fmt_vid_mplane, -+ .vidioc_s_fmt_vid_out_mplane = iris_s_fmt_vid_mplane, -+ .vidioc_g_fmt_vid_cap_mplane = iris_g_fmt_vid_mplane, -+ .vidioc_g_fmt_vid_out_mplane = iris_g_fmt_vid_mplane, - .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, - }; - --- -2.34.1 - diff --git a/patch/kernel/archive/sm8550-6.12/0011_media--iris--implement-g_selection-ioctl.patch b/patch/kernel/archive/sm8550-6.12/0011_media--iris--implement-g_selection-ioctl.patch deleted file mode 100644 index df3a199dbcf7..000000000000 --- a/patch/kernel/archive/sm8550-6.12/0011_media--iris--implement-g_selection-ioctl.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 304c180d9f6f9cadc42a3ed40b5f82629dd3aeda Mon Sep 17 00:00:00 2001 -From: Vedang Nagar -Date: Fri, 7 Feb 2025 13:24:51 +0530 -Subject: [PATCH] media: iris: implement g_selection ioctl - -Implement the g_selection ioctl op in the driver with the necessary -hooks. - -Signed-off-by: Vedang Nagar -Reviewed-by: Hans Verkuil -Tested-by: Stefan Schmidt # x1e80100 (Dell XPS 13 9345) -Reviewed-by: Stefan Schmidt -Tested-by: Neil Armstrong # on SM8550-QRD -Tested-by: Neil Armstrong # on SM8550-HDK -Signed-off-by: Dikshita Agarwal -Link: https://lore.kernel.org/r/20250207-qcom-video-iris-v10-11-ab66eeffbd20@quicinc.com -Signed-off-by: Neil Armstrong ---- - drivers/media/platform/qcom/iris/iris_vidc.c | 28 ++++++++++++++++++++ - 1 file changed, 28 insertions(+) - -diff --git a/drivers/media/platform/qcom/iris/iris_vidc.c b/drivers/media/platform/qcom/iris/iris_vidc.c -index bec965284b6e..92eb793cbeb7 100644 ---- a/drivers/media/platform/qcom/iris/iris_vidc.c -+++ b/drivers/media/platform/qcom/iris/iris_vidc.c -@@ -259,6 +259,33 @@ static int iris_g_fmt_vid_mplane(struct file *filp, void *fh, struct v4l2_format - return ret; - } - -+static int iris_g_selection(struct file *filp, void *fh, struct v4l2_selection *s) -+{ -+ struct iris_inst *inst = iris_get_inst(filp, NULL); -+ -+ if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) -+ return -EINVAL; -+ -+ switch (s->target) { -+ case V4L2_SEL_TGT_CROP_BOUNDS: -+ case V4L2_SEL_TGT_CROP_DEFAULT: -+ case V4L2_SEL_TGT_CROP: -+ case V4L2_SEL_TGT_COMPOSE_BOUNDS: -+ case V4L2_SEL_TGT_COMPOSE_PADDED: -+ case V4L2_SEL_TGT_COMPOSE_DEFAULT: -+ case V4L2_SEL_TGT_COMPOSE: -+ s->r.left = inst->crop.left; -+ s->r.top = inst->crop.top; -+ s->r.width = inst->crop.width; -+ s->r.height = inst->crop.height; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ - static struct v4l2_file_operations iris_v4l2_file_ops = { - .owner = THIS_MODULE, - .open = iris_open, -@@ -280,6 +307,7 @@ static const struct v4l2_ioctl_ops iris_v4l2_ioctl_ops = { - .vidioc_g_fmt_vid_cap_mplane = iris_g_fmt_vid_mplane, - .vidioc_g_fmt_vid_out_mplane = iris_g_fmt_vid_mplane, - .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, -+ .vidioc_g_selection = iris_g_selection, - }; - - void iris_init_ops(struct iris_core *core) --- -2.34.1 - diff --git a/patch/kernel/archive/sm8550-6.12/0012_media--iris--implement-enum_fmt-and-enum_framesize.patch b/patch/kernel/archive/sm8550-6.12/0012_media--iris--implement-enum_fmt-and-enum_framesize.patch deleted file mode 100644 index f941a7e54f23..000000000000 --- a/patch/kernel/archive/sm8550-6.12/0012_media--iris--implement-enum_fmt-and-enum_framesize.patch +++ /dev/null @@ -1,168 +0,0 @@ -From 7c0295c068f6d1c1ecb76e0ca4e144d197ee974b Mon Sep 17 00:00:00 2001 -From: Vedang Nagar -Date: Fri, 7 Feb 2025 13:24:52 +0530 -Subject: [PATCH] media: iris: implement enum_fmt and enum_framesizes ioctls - -Implement the enum_fmt and enum_framesizes ioctls with the necessary -hooks. - -Signed-off-by: Vedang Nagar -Reviewed-by: Hans Verkuil -Tested-by: Stefan Schmidt # x1e80100 (Dell XPS 13 9345) -Reviewed-by: Stefan Schmidt -Tested-by: Neil Armstrong # on SM8550-QRD -Tested-by: Neil Armstrong # on SM8550-HDK -Signed-off-by: Dikshita Agarwal -Link: https://lore.kernel.org/r/20250207-qcom-video-iris-v10-12-ab66eeffbd20@quicinc.com -Signed-off-by: Neil Armstrong ---- - .../platform/qcom/iris/iris_platform_common.h | 4 ++ - .../platform/qcom/iris/iris_platform_sm8550.c | 4 ++ - drivers/media/platform/qcom/iris/iris_vdec.c | 17 ++++++++ - drivers/media/platform/qcom/iris/iris_vdec.h | 1 + - drivers/media/platform/qcom/iris/iris_vidc.c | 39 +++++++++++++++++++ - 5 files changed, 65 insertions(+) - -diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h -index d508477b066e..75d4932df910 100644 ---- a/drivers/media/platform/qcom/iris/iris_platform_common.h -+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h -@@ -43,6 +43,10 @@ struct ubwc_config_data { - }; - - struct platform_inst_caps { -+ u32 min_frame_width; -+ u32 max_frame_width; -+ u32 min_frame_height; -+ u32 max_frame_height; - u32 max_mbpf; - }; - struct iris_core_power { -diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c -index e4232c755074..3972b64dbda6 100644 ---- a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c -+++ b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c -@@ -11,6 +11,10 @@ - #define VIDEO_ARCH_LX 1 - - static struct platform_inst_caps platform_inst_cap_sm8550 = { -+ .min_frame_width = 96, -+ .max_frame_width = 8192, -+ .min_frame_height = 96, -+ .max_frame_height = 8192, - .max_mbpf = (8192 * 4352) / 256, - }; - -diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c b/drivers/media/platform/qcom/iris/iris_vdec.c -index 38a5df8191cc..081a9eda5c49 100644 ---- a/drivers/media/platform/qcom/iris/iris_vdec.c -+++ b/drivers/media/platform/qcom/iris/iris_vdec.c -@@ -58,6 +58,23 @@ void iris_vdec_inst_deinit(struct iris_inst *inst) - kfree(inst->fmt_src); - } - -+int iris_vdec_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f) -+{ -+ switch (f->type) { -+ case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: -+ f->pixelformat = V4L2_PIX_FMT_H264; -+ f->flags = V4L2_FMT_FLAG_COMPRESSED | V4L2_FMT_FLAG_DYN_RESOLUTION; -+ break; -+ case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: -+ f->pixelformat = V4L2_PIX_FMT_NV12; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ - int iris_vdec_try_fmt(struct iris_inst *inst, struct v4l2_format *f) - { - struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp; -diff --git a/drivers/media/platform/qcom/iris/iris_vdec.h b/drivers/media/platform/qcom/iris/iris_vdec.h -index 85e93f33e9e7..ae456676e578 100644 ---- a/drivers/media/platform/qcom/iris/iris_vdec.h -+++ b/drivers/media/platform/qcom/iris/iris_vdec.h -@@ -10,6 +10,7 @@ struct iris_inst; - - void iris_vdec_inst_init(struct iris_inst *inst); - void iris_vdec_inst_deinit(struct iris_inst *inst); -+int iris_vdec_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f); - int iris_vdec_try_fmt(struct iris_inst *inst, struct v4l2_format *f); - int iris_vdec_s_fmt(struct iris_inst *inst, struct v4l2_format *f); - -diff --git a/drivers/media/platform/qcom/iris/iris_vidc.c b/drivers/media/platform/qcom/iris/iris_vidc.c -index 92eb793cbeb7..82bd0be8e5da 100644 ---- a/drivers/media/platform/qcom/iris/iris_vidc.c -+++ b/drivers/media/platform/qcom/iris/iris_vidc.c -@@ -217,6 +217,16 @@ int iris_close(struct file *filp) - return 0; - } - -+static int iris_enum_fmt(struct file *filp, void *fh, struct v4l2_fmtdesc *f) -+{ -+ struct iris_inst *inst = iris_get_inst(filp, NULL); -+ -+ if (f->index) -+ return -EINVAL; -+ -+ return iris_vdec_enum_fmt(inst, f); -+} -+ - static int iris_try_fmt_vid_mplane(struct file *filp, void *fh, struct v4l2_format *f) - { - struct iris_inst *inst = iris_get_inst(filp, NULL); -@@ -259,6 +269,32 @@ static int iris_g_fmt_vid_mplane(struct file *filp, void *fh, struct v4l2_format - return ret; - } - -+static int iris_enum_framesizes(struct file *filp, void *fh, -+ struct v4l2_frmsizeenum *fsize) -+{ -+ struct iris_inst *inst = iris_get_inst(filp, NULL); -+ struct platform_inst_caps *caps; -+ -+ if (fsize->index) -+ return -EINVAL; -+ -+ if (fsize->pixel_format != V4L2_PIX_FMT_H264 && -+ fsize->pixel_format != V4L2_PIX_FMT_NV12) -+ return -EINVAL; -+ -+ caps = inst->core->iris_platform_data->inst_caps; -+ -+ fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; -+ fsize->stepwise.min_width = caps->min_frame_width; -+ fsize->stepwise.max_width = caps->max_frame_width; -+ fsize->stepwise.step_width = STEP_WIDTH; -+ fsize->stepwise.min_height = caps->min_frame_height; -+ fsize->stepwise.max_height = caps->max_frame_height; -+ fsize->stepwise.step_height = STEP_HEIGHT; -+ -+ return 0; -+} -+ - static int iris_g_selection(struct file *filp, void *fh, struct v4l2_selection *s) - { - struct iris_inst *inst = iris_get_inst(filp, NULL); -@@ -300,12 +336,15 @@ static const struct vb2_ops iris_vb2_ops = { - }; - - static const struct v4l2_ioctl_ops iris_v4l2_ioctl_ops = { -+ .vidioc_enum_fmt_vid_cap = iris_enum_fmt, -+ .vidioc_enum_fmt_vid_out = iris_enum_fmt, - .vidioc_try_fmt_vid_cap_mplane = iris_try_fmt_vid_mplane, - .vidioc_try_fmt_vid_out_mplane = iris_try_fmt_vid_mplane, - .vidioc_s_fmt_vid_cap_mplane = iris_s_fmt_vid_mplane, - .vidioc_s_fmt_vid_out_mplane = iris_s_fmt_vid_mplane, - .vidioc_g_fmt_vid_cap_mplane = iris_g_fmt_vid_mplane, - .vidioc_g_fmt_vid_out_mplane = iris_g_fmt_vid_mplane, -+ .vidioc_enum_framesizes = iris_enum_framesizes, - .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, - .vidioc_g_selection = iris_g_selection, - }; --- -2.34.1 - diff --git a/patch/kernel/archive/sm8550-6.12/0013_media--iris--implement-subscribe_event-and-unsubsc.patch b/patch/kernel/archive/sm8550-6.12/0013_media--iris--implement-subscribe_event-and-unsubsc.patch deleted file mode 100644 index 8759061bd22d..000000000000 --- a/patch/kernel/archive/sm8550-6.12/0013_media--iris--implement-subscribe_event-and-unsubsc.patch +++ /dev/null @@ -1,110 +0,0 @@ -From cbcd78524e95d5d2581ebcafdab2ff4d13ac64c1 Mon Sep 17 00:00:00 2001 -From: Vedang Nagar -Date: Fri, 7 Feb 2025 13:24:53 +0530 -Subject: [PATCH] media: iris: implement subscribe_event and unsubscribe_event - ioctls - -Implement the subscribe_event and unsubscribe_event iocts with the -necessary hooks. - -Signed-off-by: Vedang Nagar -Reviewed-by: Hans Verkuil -Tested-by: Stefan Schmidt # x1e80100 (Dell XPS 13 9345) -Reviewed-by: Stefan Schmidt -Tested-by: Neil Armstrong # on SM8550-QRD -Tested-by: Neil Armstrong # on SM8550-HDK -Signed-off-by: Dikshita Agarwal -Link: https://lore.kernel.org/r/20250207-qcom-video-iris-v10-13-ab66eeffbd20@quicinc.com -Signed-off-by: Neil Armstrong ---- - drivers/media/platform/qcom/iris/iris_vdec.c | 22 ++++++++++++++++++++ - drivers/media/platform/qcom/iris/iris_vdec.h | 1 + - drivers/media/platform/qcom/iris/iris_vidc.c | 10 +++++++++ - 3 files changed, 33 insertions(+) - -diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c b/drivers/media/platform/qcom/iris/iris_vdec.c -index 081a9eda5c49..0ba60bcb9fa9 100644 ---- a/drivers/media/platform/qcom/iris/iris_vdec.c -+++ b/drivers/media/platform/qcom/iris/iris_vdec.c -@@ -3,6 +3,7 @@ - * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. - */ - -+#include - #include - - #include "iris_buffer.h" -@@ -193,3 +194,24 @@ int iris_vdec_s_fmt(struct iris_inst *inst, struct v4l2_format *f) - - return 0; - } -+ -+int iris_vdec_subscribe_event(struct iris_inst *inst, const struct v4l2_event_subscription *sub) -+{ -+ int ret = 0; -+ -+ switch (sub->type) { -+ case V4L2_EVENT_EOS: -+ ret = v4l2_event_subscribe(&inst->fh, sub, 0, NULL); -+ break; -+ case V4L2_EVENT_SOURCE_CHANGE: -+ ret = v4l2_src_change_event_subscribe(&inst->fh, sub); -+ break; -+ case V4L2_EVENT_CTRL: -+ ret = v4l2_ctrl_subscribe_event(&inst->fh, sub); -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return ret; -+} -diff --git a/drivers/media/platform/qcom/iris/iris_vdec.h b/drivers/media/platform/qcom/iris/iris_vdec.h -index ae456676e578..f64ce3234e6a 100644 ---- a/drivers/media/platform/qcom/iris/iris_vdec.h -+++ b/drivers/media/platform/qcom/iris/iris_vdec.h -@@ -13,5 +13,6 @@ void iris_vdec_inst_deinit(struct iris_inst *inst); - int iris_vdec_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f); - int iris_vdec_try_fmt(struct iris_inst *inst, struct v4l2_format *f); - int iris_vdec_s_fmt(struct iris_inst *inst, struct v4l2_format *f); -+int iris_vdec_subscribe_event(struct iris_inst *inst, const struct v4l2_event_subscription *sub); - - #endif -diff --git a/drivers/media/platform/qcom/iris/iris_vidc.c b/drivers/media/platform/qcom/iris/iris_vidc.c -index 82bd0be8e5da..511cd13ac471 100644 ---- a/drivers/media/platform/qcom/iris/iris_vidc.c -+++ b/drivers/media/platform/qcom/iris/iris_vidc.c -@@ -4,6 +4,7 @@ - */ - - #include -+#include - #include - #include - -@@ -322,6 +323,13 @@ static int iris_g_selection(struct file *filp, void *fh, struct v4l2_selection * - return 0; - } - -+static int iris_subscribe_event(struct v4l2_fh *fh, const struct v4l2_event_subscription *sub) -+{ -+ struct iris_inst *inst = container_of(fh, struct iris_inst, fh); -+ -+ return iris_vdec_subscribe_event(inst, sub); -+} -+ - static struct v4l2_file_operations iris_v4l2_file_ops = { - .owner = THIS_MODULE, - .open = iris_open, -@@ -347,6 +355,8 @@ static const struct v4l2_ioctl_ops iris_v4l2_ioctl_ops = { - .vidioc_enum_framesizes = iris_enum_framesizes, - .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, - .vidioc_g_selection = iris_g_selection, -+ .vidioc_subscribe_event = iris_subscribe_event, -+ .vidioc_unsubscribe_event = v4l2_event_unsubscribe, - }; - - void iris_init_ops(struct iris_core *core) --- -2.34.1 - diff --git a/patch/kernel/archive/sm8550-6.12/0014_media--iris--implement-iris-v4l2_ctrl_ops.patch b/patch/kernel/archive/sm8550-6.12/0014_media--iris--implement-iris-v4l2_ctrl_ops.patch deleted file mode 100644 index a74c9f9c7242..000000000000 --- a/patch/kernel/archive/sm8550-6.12/0014_media--iris--implement-iris-v4l2_ctrl_ops.patch +++ /dev/null @@ -1,539 +0,0 @@ -From e94d3d551e3feedc7299f884c3b9b57452fa82c2 Mon Sep 17 00:00:00 2001 -From: Dikshita Agarwal -Date: Fri, 7 Feb 2025 13:24:54 +0530 -Subject: [PATCH] media: iris: implement iris v4l2_ctrl_ops - -Initialize the control handler by reading the platform specific firmware -capabilities. Capabilities are features, which are supported by a -specific platform (SOC). Each capability is defined with a min, max, -range and default value and a corresponding HFI. Implement s_ctrl and -g_volatile_ctrl ctrl ops. - -Co-developed-by: Vedang Nagar -Signed-off-by: Vedang Nagar -Reviewed-by: Hans Verkuil -Tested-by: Stefan Schmidt # x1e80100 (Dell XPS 13 9345) -Reviewed-by: Stefan Schmidt -Tested-by: Neil Armstrong # on SM8550-QRD -Tested-by: Neil Armstrong # on SM8550-HDK -Signed-off-by: Dikshita Agarwal -Link: https://lore.kernel.org/r/20250207-qcom-video-iris-v10-14-ab66eeffbd20@quicinc.com -Signed-off-by: Neil Armstrong ---- - drivers/media/platform/qcom/iris/Makefile | 1 + - drivers/media/platform/qcom/iris/iris_core.h | 2 + - drivers/media/platform/qcom/iris/iris_ctrls.c | 165 ++++++++++++++++++ - drivers/media/platform/qcom/iris/iris_ctrls.h | 17 ++ - .../qcom/iris/iris_hfi_gen2_defines.h | 2 + - .../media/platform/qcom/iris/iris_instance.h | 4 + - .../platform/qcom/iris/iris_platform_common.h | 30 ++++ - .../platform/qcom/iris/iris_platform_sm8550.c | 47 +++++ - drivers/media/platform/qcom/iris/iris_probe.c | 3 + - drivers/media/platform/qcom/iris/iris_vdec.c | 9 +- - drivers/media/platform/qcom/iris/iris_vdec.h | 2 +- - drivers/media/platform/qcom/iris/iris_vidc.c | 9 +- - 12 files changed, 288 insertions(+), 3 deletions(-) - create mode 100644 drivers/media/platform/qcom/iris/iris_ctrls.c - create mode 100644 drivers/media/platform/qcom/iris/iris_ctrls.h - -diff --git a/drivers/media/platform/qcom/iris/Makefile b/drivers/media/platform/qcom/iris/Makefile -index 48ab264b7906..f685d76c2f79 100644 ---- a/drivers/media/platform/qcom/iris/Makefile -+++ b/drivers/media/platform/qcom/iris/Makefile -@@ -1,5 +1,6 @@ - iris-objs += iris_buffer.o \ - iris_core.o \ -+ iris_ctrls.o \ - iris_firmware.o \ - iris_hfi_common.o \ - iris_hfi_gen1_command.o \ -diff --git a/drivers/media/platform/qcom/iris/iris_core.h b/drivers/media/platform/qcom/iris/iris_core.h -index 1ddcb8793172..37fb4919fecc 100644 ---- a/drivers/media/platform/qcom/iris/iris_core.h -+++ b/drivers/media/platform/qcom/iris/iris_core.h -@@ -63,6 +63,7 @@ struct icc_info { - * @intr_status: interrupt status - * @sys_error_handler: a delayed work for handling system fatal error - * @instances: a list_head of all instances -+ * @inst_fw_caps: an array of supported instance capabilities - */ - - struct iris_core { -@@ -101,6 +102,7 @@ struct iris_core { - u32 intr_status; - struct delayed_work sys_error_handler; - struct list_head instances; -+ struct platform_inst_fw_cap inst_fw_caps[INST_FW_CAP_MAX]; - }; - - int iris_core_init(struct iris_core *core); -diff --git a/drivers/media/platform/qcom/iris/iris_ctrls.c b/drivers/media/platform/qcom/iris/iris_ctrls.c -new file mode 100644 -index 000000000000..3652fa535bf3 ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_ctrls.c -@@ -0,0 +1,165 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#include -+#include "iris_ctrls.h" -+#include "iris_instance.h" -+ -+static inline bool iris_valid_cap_id(enum platform_inst_fw_cap_type cap_id) -+{ -+ return cap_id >= 1 && cap_id < INST_FW_CAP_MAX; -+} -+ -+static enum platform_inst_fw_cap_type iris_get_cap_id(u32 id) -+{ -+ switch (id) { -+ case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER: -+ return DEBLOCK; -+ case V4L2_CID_MPEG_VIDEO_H264_PROFILE: -+ return PROFILE; -+ case V4L2_CID_MPEG_VIDEO_H264_LEVEL: -+ return LEVEL; -+ default: -+ return INST_FW_CAP_MAX; -+ } -+} -+ -+static u32 iris_get_v4l2_id(enum platform_inst_fw_cap_type cap_id) -+{ -+ if (!iris_valid_cap_id(cap_id)) -+ return 0; -+ -+ switch (cap_id) { -+ case DEBLOCK: -+ return V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER; -+ case PROFILE: -+ return V4L2_CID_MPEG_VIDEO_H264_PROFILE; -+ case LEVEL: -+ return V4L2_CID_MPEG_VIDEO_H264_LEVEL; -+ default: -+ return 0; -+ } -+} -+ -+static int iris_vdec_op_s_ctrl(struct v4l2_ctrl *ctrl) -+{ -+ struct iris_inst *inst = container_of(ctrl->handler, struct iris_inst, ctrl_handler); -+ enum platform_inst_fw_cap_type cap_id; -+ struct platform_inst_fw_cap *cap; -+ struct vb2_queue *q; -+ -+ cap = &inst->fw_caps[0]; -+ cap_id = iris_get_cap_id(ctrl->id); -+ if (!iris_valid_cap_id(cap_id)) -+ return -EINVAL; -+ -+ q = v4l2_m2m_get_src_vq(inst->m2m_ctx); -+ if (vb2_is_streaming(q) && -+ (!(inst->fw_caps[cap_id].flags & CAP_FLAG_DYNAMIC_ALLOWED))) -+ return -EINVAL; -+ -+ cap[cap_id].flags |= CAP_FLAG_CLIENT_SET; -+ -+ inst->fw_caps[cap_id].value = ctrl->val; -+ -+ return 0; -+} -+ -+static const struct v4l2_ctrl_ops iris_ctrl_ops = { -+ .s_ctrl = iris_vdec_op_s_ctrl, -+}; -+ -+int iris_ctrls_init(struct iris_inst *inst) -+{ -+ struct platform_inst_fw_cap *cap = &inst->fw_caps[0]; -+ u32 num_ctrls = 0, ctrl_idx = 0, idx = 0; -+ u32 v4l2_id; -+ int ret; -+ -+ for (idx = 1; idx < INST_FW_CAP_MAX; idx++) { -+ if (iris_get_v4l2_id(cap[idx].cap_id)) -+ num_ctrls++; -+ } -+ if (!num_ctrls) -+ return -EINVAL; -+ -+ /* Adding 1 to num_ctrls to include V4L2_CID_MIN_BUFFERS_FOR_CAPTURE */ -+ -+ ret = v4l2_ctrl_handler_init(&inst->ctrl_handler, num_ctrls + 1); -+ if (ret) -+ return ret; -+ -+ for (idx = 1; idx < INST_FW_CAP_MAX; idx++) { -+ struct v4l2_ctrl *ctrl; -+ -+ v4l2_id = iris_get_v4l2_id(cap[idx].cap_id); -+ if (!v4l2_id) -+ continue; -+ -+ if (ctrl_idx >= num_ctrls) { -+ ret = -EINVAL; -+ goto error; -+ } -+ -+ if (cap[idx].flags & CAP_FLAG_MENU) { -+ ctrl = v4l2_ctrl_new_std_menu(&inst->ctrl_handler, -+ &iris_ctrl_ops, -+ v4l2_id, -+ cap[idx].max, -+ ~(cap[idx].step_or_mask), -+ cap[idx].value); -+ } else { -+ ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, -+ &iris_ctrl_ops, -+ v4l2_id, -+ cap[idx].min, -+ cap[idx].max, -+ cap[idx].step_or_mask, -+ cap[idx].value); -+ } -+ if (!ctrl) { -+ ret = -EINVAL; -+ goto error; -+ } -+ -+ ctrl_idx++; -+ } -+ -+ v4l2_ctrl_new_std(&inst->ctrl_handler, NULL, -+ V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 4); -+ -+ ret = inst->ctrl_handler.error; -+ if (ret) -+ goto error; -+ -+ return 0; -+error: -+ v4l2_ctrl_handler_free(&inst->ctrl_handler); -+ -+ return ret; -+} -+ -+void iris_session_init_caps(struct iris_core *core) -+{ -+ struct platform_inst_fw_cap *caps; -+ u32 i, num_cap, cap_id; -+ -+ caps = core->iris_platform_data->inst_fw_caps; -+ num_cap = core->iris_platform_data->inst_fw_caps_size; -+ -+ for (i = 0; i < num_cap; i++) { -+ cap_id = caps[i].cap_id; -+ if (!iris_valid_cap_id(cap_id)) -+ continue; -+ -+ core->inst_fw_caps[cap_id].cap_id = caps[i].cap_id; -+ core->inst_fw_caps[cap_id].min = caps[i].min; -+ core->inst_fw_caps[cap_id].max = caps[i].max; -+ core->inst_fw_caps[cap_id].step_or_mask = caps[i].step_or_mask; -+ core->inst_fw_caps[cap_id].value = caps[i].value; -+ core->inst_fw_caps[cap_id].flags = caps[i].flags; -+ core->inst_fw_caps[cap_id].hfi_id = caps[i].hfi_id; -+ } -+} -diff --git a/drivers/media/platform/qcom/iris/iris_ctrls.h b/drivers/media/platform/qcom/iris/iris_ctrls.h -new file mode 100644 -index 000000000000..fe65a772e6dd ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_ctrls.h -@@ -0,0 +1,17 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#ifndef __IRIS_CTRLS_H__ -+#define __IRIS_CTRLS_H__ -+ -+#include "iris_platform_common.h" -+ -+struct iris_core; -+struct iris_inst; -+ -+int iris_ctrls_init(struct iris_inst *inst); -+void iris_session_init_caps(struct iris_core *core); -+ -+#endif -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h -index ccf5fd0902d7..173a554a0d44 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h -@@ -28,6 +28,8 @@ - #define HFI_PROP_UBWC_BANK_SWZL_LEVEL3 0x03000008 - #define HFI_PROP_UBWC_BANK_SPREADING 0x03000009 - #define HFI_PROP_CODEC 0x03000100 -+#define HFI_PROP_PROFILE 0x03000107 -+#define HFI_PROP_LEVEL 0x03000108 - #define HFI_PROP_DEC_DEFAULT_HEADER 0x03000168 - #define HFI_PROP_END 0x03FFFFFF - -diff --git a/drivers/media/platform/qcom/iris/iris_instance.h b/drivers/media/platform/qcom/iris/iris_instance.h -index b9c7dcfb20f7..9f1a1e5ba7c7 100644 ---- a/drivers/media/platform/qcom/iris/iris_instance.h -+++ b/drivers/media/platform/qcom/iris/iris_instance.h -@@ -23,8 +23,10 @@ - * @fh: reference of v4l2 file handler - * @fmt_src: structure of v4l2_format for source - * @fmt_dst: structure of v4l2_format for destination -+ * @ctrl_handler: reference of v4l2 ctrl handler - * @crop: structure of crop info - * @completion: structure of signal completions -+ * @fw_caps: array of supported instance firmware capabilities - * @buffers: array of different iris buffers - * @fw_min_count: minimnum count of buffers needed by fw - * @once_per_session_set: boolean to set once per session property -@@ -41,8 +43,10 @@ struct iris_inst { - struct v4l2_fh fh; - struct v4l2_format *fmt_src; - struct v4l2_format *fmt_dst; -+ struct v4l2_ctrl_handler ctrl_handler; - struct iris_hfi_rect_desc crop; - struct completion completion; -+ struct platform_inst_fw_cap fw_caps[INST_FW_CAP_MAX]; - struct iris_buffers buffers[BUF_TYPE_MAX]; - u32 fw_min_count; - bool once_per_session_set; -diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h -index 75d4932df910..23170cd37c04 100644 ---- a/drivers/media/platform/qcom/iris/iris_platform_common.h -+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h -@@ -49,6 +49,34 @@ struct platform_inst_caps { - u32 max_frame_height; - u32 max_mbpf; - }; -+ -+enum platform_inst_fw_cap_type { -+ PROFILE = 1, -+ LEVEL, -+ DEBLOCK, -+ INST_FW_CAP_MAX, -+}; -+ -+enum platform_inst_fw_cap_flags { -+ CAP_FLAG_DYNAMIC_ALLOWED = BIT(0), -+ CAP_FLAG_MENU = BIT(1), -+ CAP_FLAG_INPUT_PORT = BIT(2), -+ CAP_FLAG_OUTPUT_PORT = BIT(3), -+ CAP_FLAG_CLIENT_SET = BIT(4), -+ CAP_FLAG_BITMASK = BIT(5), -+ CAP_FLAG_VOLATILE = BIT(6), -+}; -+ -+struct platform_inst_fw_cap { -+ enum platform_inst_fw_cap_type cap_id; -+ s64 min; -+ s64 max; -+ s64 step_or_mask; -+ s64 value; -+ u32 hfi_id; -+ enum platform_inst_fw_cap_flags flags; -+}; -+ - struct iris_core_power { - u64 clk_freq; - u64 icc_bw; -@@ -79,6 +107,8 @@ struct iris_platform_data { - const char *fwname; - u32 pas_id; - struct platform_inst_caps *inst_caps; -+ struct platform_inst_fw_cap *inst_fw_caps; -+ u32 inst_fw_caps_size; - struct tz_cp_config *tz_cp_config_data; - u32 core_arch; - u32 hw_response_timeout; -diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c -index 3972b64dbda6..58b1d1d43731 100644 ---- a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c -+++ b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c -@@ -5,11 +5,56 @@ - - #include "iris_core.h" - #include "iris_hfi_gen2.h" -+#include "iris_hfi_gen2_defines.h" - #include "iris_platform_common.h" - #include "iris_vpu_common.h" - - #define VIDEO_ARCH_LX 1 - -+static struct platform_inst_fw_cap inst_fw_cap_sm8550[] = { -+ { -+ .cap_id = PROFILE, -+ .min = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE, -+ .max = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH, -+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) | -+ BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) | -+ BIT(V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) | -+ BIT(V4L2_MPEG_VIDEO_H264_PROFILE_HIGH) | -+ BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH), -+ .value = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH, -+ .hfi_id = HFI_PROP_PROFILE, -+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, -+ }, -+ { -+ .cap_id = LEVEL, -+ .min = V4L2_MPEG_VIDEO_H264_LEVEL_1_0, -+ .max = V4L2_MPEG_VIDEO_H264_LEVEL_6_2, -+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_0) | -+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1B) | -+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_1) | -+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_2) | -+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_3) | -+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_0) | -+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_1) | -+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_2) | -+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_0) | -+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_1) | -+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_2) | -+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_0) | -+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_1) | -+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_2) | -+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_0) | -+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_1) | -+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_2) | -+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_0) | -+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_1) | -+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_2), -+ .value = V4L2_MPEG_VIDEO_H264_LEVEL_6_1, -+ .hfi_id = HFI_PROP_LEVEL, -+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, -+ }, -+}; -+ - static struct platform_inst_caps platform_inst_cap_sm8550 = { - .min_frame_width = 96, - .max_frame_width = 8192, -@@ -78,6 +123,8 @@ struct iris_platform_data sm8550_data = { - .fwname = "qcom/vpu/vpu30_p4.mbn", - .pas_id = IRIS_PAS_ID, - .inst_caps = &platform_inst_cap_sm8550, -+ .inst_fw_caps = inst_fw_cap_sm8550, -+ .inst_fw_caps_size = ARRAY_SIZE(inst_fw_cap_sm8550), - .tz_cp_config_data = &tz_cp_config_sm8550, - .core_arch = VIDEO_ARCH_LX, - .hw_response_timeout = HW_RESPONSE_TIMEOUT_VALUE, -diff --git a/drivers/media/platform/qcom/iris/iris_probe.c b/drivers/media/platform/qcom/iris/iris_probe.c -index a9162be5f9f6..954cc7c0cc97 100644 ---- a/drivers/media/platform/qcom/iris/iris_probe.c -+++ b/drivers/media/platform/qcom/iris/iris_probe.c -@@ -12,6 +12,7 @@ - #include - - #include "iris_core.h" -+#include "iris_ctrls.h" - #include "iris_vidc.h" - - static int iris_init_icc(struct iris_core *core) -@@ -236,6 +237,8 @@ static int iris_probe(struct platform_device *pdev) - if (ret) - return ret; - -+ iris_session_init_caps(core); -+ - ret = v4l2_device_register(dev, &core->v4l2_dev); - if (ret) - return ret; -diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c b/drivers/media/platform/qcom/iris/iris_vdec.c -index 0ba60bcb9fa9..132b578b34dc 100644 ---- a/drivers/media/platform/qcom/iris/iris_vdec.c -+++ b/drivers/media/platform/qcom/iris/iris_vdec.c -@@ -7,6 +7,7 @@ - #include - - #include "iris_buffer.h" -+#include "iris_ctrls.h" - #include "iris_instance.h" - #include "iris_vdec.h" - #include "iris_vpu_buffer.h" -@@ -15,8 +16,9 @@ - #define DEFAULT_HEIGHT 240 - #define DEFAULT_CODEC_ALIGNMENT 16 - --void iris_vdec_inst_init(struct iris_inst *inst) -+int iris_vdec_inst_init(struct iris_inst *inst) - { -+ struct iris_core *core = inst->core; - struct v4l2_format *f; - - inst->fmt_src = kzalloc(sizeof(*inst->fmt_src), GFP_KERNEL); -@@ -51,6 +53,11 @@ void iris_vdec_inst_init(struct iris_inst *inst) - f->fmt.pix_mp.quantization = V4L2_QUANTIZATION_DEFAULT; - inst->buffers[BUF_OUTPUT].min_count = iris_vpu_buf_count(inst, BUF_OUTPUT); - inst->buffers[BUF_OUTPUT].size = f->fmt.pix_mp.plane_fmt[0].sizeimage; -+ -+ memcpy(&inst->fw_caps[0], &core->inst_fw_caps[0], -+ INST_FW_CAP_MAX * sizeof(struct platform_inst_fw_cap)); -+ -+ return iris_ctrls_init(inst); - } - - void iris_vdec_inst_deinit(struct iris_inst *inst) -diff --git a/drivers/media/platform/qcom/iris/iris_vdec.h b/drivers/media/platform/qcom/iris/iris_vdec.h -index f64ce3234e6a..9f08a13cb6bb 100644 ---- a/drivers/media/platform/qcom/iris/iris_vdec.h -+++ b/drivers/media/platform/qcom/iris/iris_vdec.h -@@ -8,7 +8,7 @@ - - struct iris_inst; - --void iris_vdec_inst_init(struct iris_inst *inst); -+int iris_vdec_inst_init(struct iris_inst *inst); - void iris_vdec_inst_deinit(struct iris_inst *inst); - int iris_vdec_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f); - int iris_vdec_try_fmt(struct iris_inst *inst, struct v4l2_format *f); -diff --git a/drivers/media/platform/qcom/iris/iris_vidc.c b/drivers/media/platform/qcom/iris/iris_vidc.c -index 511cd13ac471..90e70aa8eedf 100644 ---- a/drivers/media/platform/qcom/iris/iris_vidc.c -+++ b/drivers/media/platform/qcom/iris/iris_vidc.c -@@ -23,12 +23,14 @@ - static void iris_v4l2_fh_init(struct iris_inst *inst) - { - v4l2_fh_init(&inst->fh, inst->core->vdev_dec); -+ inst->fh.ctrl_handler = &inst->ctrl_handler; - v4l2_fh_add(&inst->fh); - } - - static void iris_v4l2_fh_deinit(struct iris_inst *inst) - { - v4l2_fh_del(&inst->fh); -+ inst->fh.ctrl_handler = NULL; - v4l2_fh_exit(&inst->fh); - } - -@@ -162,7 +164,9 @@ int iris_open(struct file *filp) - goto fail_m2m_release; - } - -- iris_vdec_inst_init(inst); -+ ret = iris_vdec_inst_init(inst); -+ if (ret) -+ goto fail_m2m_ctx_release; - - iris_add_session(inst); - -@@ -171,6 +175,8 @@ int iris_open(struct file *filp) - - return 0; - -+fail_m2m_ctx_release: -+ v4l2_m2m_ctx_release(inst->m2m_ctx); - fail_m2m_release: - v4l2_m2m_release(inst->m2m_dev); - fail_v4l2_fh_deinit: -@@ -202,6 +208,7 @@ int iris_close(struct file *filp) - { - struct iris_inst *inst = iris_get_inst(filp, NULL); - -+ v4l2_ctrl_handler_free(&inst->ctrl_handler); - v4l2_m2m_ctx_release(inst->m2m_ctx); - v4l2_m2m_release(inst->m2m_dev); - mutex_lock(&inst->lock); --- -2.34.1 - diff --git a/patch/kernel/archive/sm8550-6.12/0015_media--iris--implement-query_cap-ioctl.patch b/patch/kernel/archive/sm8550-6.12/0015_media--iris--implement-query_cap-ioctl.patch deleted file mode 100644 index 4cb4a8a4d4a8..000000000000 --- a/patch/kernel/archive/sm8550-6.12/0015_media--iris--implement-query_cap-ioctl.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 33f111b8320ac637150755b607b781f3562d86e3 Mon Sep 17 00:00:00 2001 -From: Vedang Nagar -Date: Fri, 7 Feb 2025 13:24:55 +0530 -Subject: [PATCH] media: iris: implement query_cap ioctl - -Implement the query_cap ioctl with the necessary hooks. - -Signed-off-by: Vedang Nagar -Reviewed-by: Hans Verkuil -Tested-by: Stefan Schmidt # x1e80100 (Dell XPS 13 9345) -Reviewed-by: Stefan Schmidt -Tested-by: Neil Armstrong # on SM8550-QRD -Tested-by: Neil Armstrong # on SM8550-HDK -Signed-off-by: Dikshita Agarwal -Link: https://lore.kernel.org/r/20250207-qcom-video-iris-v10-15-ab66eeffbd20@quicinc.com -Signed-off-by: Neil Armstrong ---- - drivers/media/platform/qcom/iris/iris_vidc.c | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/drivers/media/platform/qcom/iris/iris_vidc.c b/drivers/media/platform/qcom/iris/iris_vidc.c -index 90e70aa8eedf..5b54231f2def 100644 ---- a/drivers/media/platform/qcom/iris/iris_vidc.c -+++ b/drivers/media/platform/qcom/iris/iris_vidc.c -@@ -303,6 +303,14 @@ static int iris_enum_framesizes(struct file *filp, void *fh, - return 0; - } - -+static int iris_querycap(struct file *filp, void *fh, struct v4l2_capability *cap) -+{ -+ strscpy(cap->driver, IRIS_DRV_NAME, sizeof(cap->driver)); -+ strscpy(cap->card, "Iris Decoder", sizeof(cap->card)); -+ -+ return 0; -+} -+ - static int iris_g_selection(struct file *filp, void *fh, struct v4l2_selection *s) - { - struct iris_inst *inst = iris_get_inst(filp, NULL); -@@ -361,6 +369,7 @@ static const struct v4l2_ioctl_ops iris_v4l2_ioctl_ops = { - .vidioc_g_fmt_vid_out_mplane = iris_g_fmt_vid_mplane, - .vidioc_enum_framesizes = iris_enum_framesizes, - .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, -+ .vidioc_querycap = iris_querycap, - .vidioc_g_selection = iris_g_selection, - .vidioc_subscribe_event = iris_subscribe_event, - .vidioc_unsubscribe_event = v4l2_event_unsubscribe, --- -2.34.1 - diff --git a/patch/kernel/archive/sm8550-6.12/0016_media--iris--implement-vb2-streaming-ops.patch b/patch/kernel/archive/sm8550-6.12/0016_media--iris--implement-vb2-streaming-ops.patch deleted file mode 100644 index 3875375cb591..000000000000 --- a/patch/kernel/archive/sm8550-6.12/0016_media--iris--implement-vb2-streaming-ops.patch +++ /dev/null @@ -1,1083 +0,0 @@ -From 5d1672570ca7a2f494c5d0b280242a992fd3eac4 Mon Sep 17 00:00:00 2001 -From: Dikshita Agarwal -Date: Fri, 7 Feb 2025 13:24:56 +0530 -Subject: [PATCH] media: iris: implement vb2 streaming ops - -During the stream on operation, send HFI_CMD_START on the capture and -output planes to start processing on the respective planes. - -During the stream off operation, send HFI_CMD_STOP to the firmware, -which is a synchronous command. After the response is received by the -firmware, the session is closed on the firmware. - -Introduce different states for the instance and state transitions. - -IRIS_INST_INIT - video instance is opened. -IRIS_INST_INPUT_STREAMING - stream on is completed on output plane. -IRIS_INST_OUTPUT_STREAMING - stream on is completed on capture plane. -IRIS_INST_STREAMING - stream on is completed on both output and capture -planes. -IRIS_INST_DEINIT - video instance is closed. -IRIS_INST_ERROR - error state. - - | - v - ------------- - +---------| INIT |--------- + - | ------------- | - | ^ ^ | - | / \ | - | / \ | - | v v | - | ----------- ----------- | - | | INPUT OUTPUT | | - |---| STREAMING STREAMING |---| - | ----------- ----------- | - | ^ ^ | - | \ / | - | \ / | - | v v | - | ------------- | - |--------| STREAMING |-----------| - | ------------- | - | | | - | | | - | v | - | ----------- | - +-------->| DEINIT |<----------+ - | ----------- | - | | | - | | | - | v | - | ---------- | - +-------->| ERROR |<-----------+ - ----------. - -Reviewed-by: Hans Verkuil -Tested-by: Stefan Schmidt # x1e80100 (Dell XPS 13 9345) -Reviewed-by: Stefan Schmidt -Tested-by: Neil Armstrong # on SM8550-QRD -Tested-by: Neil Armstrong # on SM8550-HDK -Signed-off-by: Dikshita Agarwal -Link: https://lore.kernel.org/r/20250207-qcom-video-iris-v10-16-ab66eeffbd20@quicinc.com -Signed-off-by: Neil Armstrong ---- - drivers/media/platform/qcom/iris/Makefile | 1 + - .../platform/qcom/iris/iris_hfi_common.h | 2 + - .../qcom/iris/iris_hfi_gen1_command.c | 82 +++++++++++++- - .../qcom/iris/iris_hfi_gen1_defines.h | 24 ++++ - .../qcom/iris/iris_hfi_gen1_response.c | 39 ++++++- - .../qcom/iris/iris_hfi_gen2_command.c | 61 ++++++++++ - .../qcom/iris/iris_hfi_gen2_defines.h | 2 + - .../qcom/iris/iris_hfi_gen2_response.c | 32 +++++- - .../media/platform/qcom/iris/iris_instance.h | 4 + - drivers/media/platform/qcom/iris/iris_state.c | 104 ++++++++++++++++++ - drivers/media/platform/qcom/iris/iris_state.h | 58 ++++++++++ - drivers/media/platform/qcom/iris/iris_utils.c | 11 +- - drivers/media/platform/qcom/iris/iris_utils.h | 2 +- - drivers/media/platform/qcom/iris/iris_vb2.c | 70 ++++++++++++ - drivers/media/platform/qcom/iris/iris_vb2.h | 3 + - drivers/media/platform/qcom/iris/iris_vdec.c | 75 +++++++++++++ - drivers/media/platform/qcom/iris/iris_vdec.h | 3 + - drivers/media/platform/qcom/iris/iris_vidc.c | 12 +- - 18 files changed, 573 insertions(+), 12 deletions(-) - create mode 100644 drivers/media/platform/qcom/iris/iris_state.c - -diff --git a/drivers/media/platform/qcom/iris/Makefile b/drivers/media/platform/qcom/iris/Makefile -index f685d76c2f79..ab16189aa9e6 100644 ---- a/drivers/media/platform/qcom/iris/Makefile -+++ b/drivers/media/platform/qcom/iris/Makefile -@@ -12,6 +12,7 @@ iris-objs += iris_buffer.o \ - iris_platform_sm8550.o \ - iris_probe.o \ - iris_resources.o \ -+ iris_state.o \ - iris_utils.o \ - iris_vidc.o \ - iris_vb2.o \ -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_common.h b/drivers/media/platform/qcom/iris/iris_hfi_common.h -index eaa2db469c74..8b1c4d156cf2 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_common.h -+++ b/drivers/media/platform/qcom/iris/iris_hfi_common.h -@@ -49,6 +49,8 @@ struct iris_hfi_command_ops { - int (*sys_interframe_powercollapse)(struct iris_core *core); - int (*sys_pc_prep)(struct iris_core *core); - int (*session_open)(struct iris_inst *inst); -+ int (*session_start)(struct iris_inst *inst, u32 plane); -+ int (*session_stop)(struct iris_inst *inst, u32 plane); - int (*session_close)(struct iris_inst *inst); - }; - -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c -index 7ee69c5223ce..a3b09e8d1f49 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c -@@ -71,6 +71,9 @@ static int iris_hfi_gen1_session_open(struct iris_inst *inst) - struct hfi_session_open_pkt packet; - int ret; - -+ if (inst->state != IRIS_INST_DEINIT) -+ return -EALREADY; -+ - packet.shdr.hdr.size = sizeof(struct hfi_session_open_pkt); - packet.shdr.hdr.pkt_type = HFI_CMD_SYS_SESSION_INIT; - packet.shdr.session_id = inst->session_id; -@@ -83,7 +86,7 @@ static int iris_hfi_gen1_session_open(struct iris_inst *inst) - if (ret) - return ret; - -- return iris_wait_for_session_response(inst); -+ return iris_wait_for_session_response(inst, false); - } - - static void iris_hfi_gen1_packet_session_cmd(struct iris_inst *inst, -@@ -104,12 +107,89 @@ static int iris_hfi_gen1_session_close(struct iris_inst *inst) - return iris_hfi_queue_cmd_write(inst->core, &packet, packet.shdr.hdr.size); - } - -+static int iris_hfi_gen1_session_start(struct iris_inst *inst, u32 plane) -+{ -+ struct iris_core *core = inst->core; -+ struct hfi_session_pkt packet; -+ int ret; -+ -+ if (!V4L2_TYPE_IS_OUTPUT(plane)) -+ return 0; -+ -+ reinit_completion(&inst->completion); -+ iris_hfi_gen1_packet_session_cmd(inst, &packet, HFI_CMD_SESSION_LOAD_RESOURCES); -+ -+ ret = iris_hfi_queue_cmd_write(core, &packet, packet.shdr.hdr.size); -+ if (ret) -+ return ret; -+ -+ ret = iris_wait_for_session_response(inst, false); -+ if (ret) -+ return ret; -+ -+ reinit_completion(&inst->completion); -+ iris_hfi_gen1_packet_session_cmd(inst, &packet, HFI_CMD_SESSION_START); -+ -+ ret = iris_hfi_queue_cmd_write(core, &packet, packet.shdr.hdr.size); -+ if (ret) -+ return ret; -+ -+ return iris_wait_for_session_response(inst, false); -+} -+ -+static int iris_hfi_gen1_session_stop(struct iris_inst *inst, u32 plane) -+{ -+ struct hfi_session_flush_pkt flush_pkt; -+ struct iris_core *core = inst->core; -+ struct hfi_session_pkt pkt; -+ u32 flush_type = 0; -+ int ret = 0; -+ -+ if ((V4L2_TYPE_IS_OUTPUT(plane) && -+ inst->state == IRIS_INST_INPUT_STREAMING) || -+ (V4L2_TYPE_IS_CAPTURE(plane) && -+ inst->state == IRIS_INST_OUTPUT_STREAMING) || -+ inst->state == IRIS_INST_ERROR) { -+ reinit_completion(&inst->completion); -+ iris_hfi_gen1_packet_session_cmd(inst, &pkt, HFI_CMD_SESSION_STOP); -+ ret = iris_hfi_queue_cmd_write(core, &pkt, pkt.shdr.hdr.size); -+ if (!ret) -+ ret = iris_wait_for_session_response(inst, false); -+ -+ reinit_completion(&inst->completion); -+ iris_hfi_gen1_packet_session_cmd(inst, &pkt, HFI_CMD_SESSION_RELEASE_RESOURCES); -+ ret = iris_hfi_queue_cmd_write(core, &pkt, pkt.shdr.hdr.size); -+ if (!ret) -+ ret = iris_wait_for_session_response(inst, false); -+ } else if (inst->state == IRIS_INST_STREAMING) { -+ if (V4L2_TYPE_IS_OUTPUT(plane)) -+ flush_type = HFI_FLUSH_ALL; -+ else if (V4L2_TYPE_IS_CAPTURE(plane)) -+ flush_type = HFI_FLUSH_OUTPUT; -+ -+ reinit_completion(&inst->flush_completion); -+ -+ flush_pkt.shdr.hdr.size = sizeof(struct hfi_session_flush_pkt); -+ flush_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_FLUSH; -+ flush_pkt.shdr.session_id = inst->session_id; -+ flush_pkt.flush_type = flush_type; -+ -+ ret = iris_hfi_queue_cmd_write(core, &flush_pkt, flush_pkt.shdr.hdr.size); -+ if (!ret) -+ ret = iris_wait_for_session_response(inst, true); -+ } -+ -+ return ret; -+} -+ - static const struct iris_hfi_command_ops iris_hfi_gen1_command_ops = { - .sys_init = iris_hfi_gen1_sys_init, - .sys_image_version = iris_hfi_gen1_sys_image_version, - .sys_interframe_powercollapse = iris_hfi_gen1_sys_interframe_powercollapse, - .sys_pc_prep = iris_hfi_gen1_sys_pc_prep, - .session_open = iris_hfi_gen1_session_open, -+ .session_start = iris_hfi_gen1_session_start, -+ .session_stop = iris_hfi_gen1_session_stop, - .session_close = iris_hfi_gen1_session_close, - }; - -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h -index 3640f8504db9..1b2bf6afc6ce 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h -@@ -23,6 +23,12 @@ - #define HFI_CMD_SYS_SESSION_INIT 0x10007 - #define HFI_CMD_SYS_SESSION_END 0x10008 - -+#define HFI_CMD_SESSION_LOAD_RESOURCES 0x211001 -+#define HFI_CMD_SESSION_START 0x211002 -+#define HFI_CMD_SESSION_STOP 0x211003 -+#define HFI_CMD_SESSION_FLUSH 0x211008 -+#define HFI_CMD_SESSION_RELEASE_RESOURCES 0x21100c -+ - #define HFI_ERR_SESSION_UNSUPPORTED_SETTING 0x1008 - #define HFI_ERR_SESSION_UNSUPPORT_BUFFERTYPE 0x1010 - #define HFI_ERR_SESSION_INVALID_SCALE_FACTOR 0x1012 -@@ -31,6 +37,9 @@ - #define HFI_EVENT_SYS_ERROR 0x1 - #define HFI_EVENT_SESSION_ERROR 0x2 - -+#define HFI_FLUSH_OUTPUT 0x1000002 -+#define HFI_FLUSH_OUTPUT2 0x1000003 -+#define HFI_FLUSH_ALL 0x1000004 - #define HFI_PROPERTY_SYS_CODEC_POWER_PLANE_CTRL 0x5 - #define HFI_PROPERTY_SYS_IMAGE_VERSION 0x6 - -@@ -41,6 +50,11 @@ - #define HFI_MSG_SYS_PROPERTY_INFO 0x2000a - - #define HFI_MSG_EVENT_NOTIFY 0x21001 -+#define HFI_MSG_SESSION_LOAD_RESOURCES 0x221001 -+#define HFI_MSG_SESSION_START 0x221002 -+#define HFI_MSG_SESSION_STOP 0x221003 -+#define HFI_MSG_SESSION_FLUSH 0x221006 -+#define HFI_MSG_SESSION_RELEASE_RESOURCES 0x22100a - - struct hfi_pkt_hdr { - u32 size; -@@ -83,6 +97,11 @@ struct hfi_sys_pc_prep_pkt { - struct hfi_pkt_hdr hdr; - }; - -+struct hfi_session_flush_pkt { -+ struct hfi_session_hdr_pkt shdr; -+ u32 flush_type; -+}; -+ - struct hfi_msg_event_notify_pkt { - struct hfi_session_hdr_pkt shdr; - u32 event_id; -@@ -116,6 +135,11 @@ struct hfi_msg_sys_property_info_pkt { - u8 data[]; - }; - -+struct hfi_msg_session_flush_done_pkt { -+ struct hfi_msg_session_hdr_pkt shdr; -+ u32 flush_type; -+}; -+ - struct hfi_enable { - u32 enable; - }; -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c -index 18ba5f67dd36..db5858ec04ea 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c -@@ -11,6 +11,7 @@ static void - iris_hfi_gen1_sys_event_notify(struct iris_core *core, void *packet) - { - struct hfi_msg_event_notify_pkt *pkt = packet; -+ struct iris_inst *instance; - - if (pkt->event_id == HFI_EVENT_SYS_ERROR) - dev_err(core->dev, "sys error (type: %x, session id:%x, data1:%x, data2:%x)\n", -@@ -18,6 +19,12 @@ iris_hfi_gen1_sys_event_notify(struct iris_core *core, void *packet) - pkt->event_data2); - - core->state = IRIS_CORE_ERROR; -+ -+ mutex_lock(&core->lock); -+ list_for_each_entry(instance, &core->instances, list) -+ iris_inst_change_state(instance, IRIS_INST_ERROR); -+ mutex_unlock(&core->lock); -+ - schedule_delayed_work(&core->sys_error_handler, msecs_to_jiffies(10)); - } - -@@ -44,6 +51,7 @@ iris_hfi_gen1_event_session_error(struct iris_inst *inst, struct hfi_msg_event_n - pkt->event_data2, pkt->event_data1, - pkt->shdr.session_id); - iris_vb2_queue_error(inst); -+ iris_inst_change_state(inst, IRIS_INST_ERROR); - break; - } - } -@@ -148,6 +156,26 @@ static const struct iris_hfi_gen1_response_pkt_info pkt_infos[] = { - .pkt = HFI_MSG_SYS_SESSION_END, - .pkt_sz = sizeof(struct hfi_msg_session_hdr_pkt), - }, -+ { -+ .pkt = HFI_MSG_SESSION_LOAD_RESOURCES, -+ .pkt_sz = sizeof(struct hfi_msg_session_hdr_pkt), -+ }, -+ { -+ .pkt = HFI_MSG_SESSION_START, -+ .pkt_sz = sizeof(struct hfi_msg_session_hdr_pkt), -+ }, -+ { -+ .pkt = HFI_MSG_SESSION_STOP, -+ .pkt_sz = sizeof(struct hfi_msg_session_hdr_pkt), -+ }, -+ { -+ .pkt = HFI_MSG_SESSION_FLUSH, -+ .pkt_sz = sizeof(struct hfi_msg_session_flush_done_pkt), -+ }, -+ { -+ .pkt = HFI_MSG_SESSION_RELEASE_RESOURCES, -+ .pkt_sz = sizeof(struct hfi_msg_session_hdr_pkt), -+ }, - }; - - static void iris_hfi_gen1_handle_response(struct iris_core *core, void *response) -@@ -156,6 +184,7 @@ static void iris_hfi_gen1_handle_response(struct iris_core *core, void *response - const struct iris_hfi_gen1_response_pkt_info *pkt_info; - struct device *dev = core->dev; - struct hfi_session_pkt *pkt; -+ struct completion *done; - struct iris_inst *inst; - bool found = false; - u32 i; -@@ -205,7 +234,15 @@ static void iris_hfi_gen1_handle_response(struct iris_core *core, void *response - } - - mutex_lock(&inst->lock); -- complete(&inst->completion); -+ struct hfi_msg_session_hdr_pkt *shdr; -+ -+ shdr = (struct hfi_msg_session_hdr_pkt *)hdr; -+ if (shdr->error_type != HFI_ERR_NONE) -+ iris_inst_change_state(inst, IRIS_INST_ERROR); -+ -+ done = pkt_info->pkt == HFI_MSG_SESSION_FLUSH ? -+ &inst->flush_completion : &inst->completion; -+ complete(done); - mutex_unlock(&inst->lock); - - break; -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c -index a08e844bb4bb..b0557917fc52 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c -@@ -85,6 +85,18 @@ static int iris_hfi_gen2_sys_pc_prep(struct iris_core *core) - return ret; - } - -+static u32 iris_hfi_gen2_get_port(u32 plane) -+{ -+ switch (plane) { -+ case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: -+ return HFI_PORT_BITSTREAM; -+ case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: -+ return HFI_PORT_RAW; -+ default: -+ return HFI_PORT_NONE; -+ } -+} -+ - static int iris_hfi_gen2_session_set_codec(struct iris_inst *inst) - { - struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); -@@ -124,6 +136,9 @@ static int iris_hfi_gen2_session_open(struct iris_inst *inst) - struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); - int ret; - -+ if (inst->state != IRIS_INST_DEINIT) -+ return -EALREADY; -+ - inst_hfi_gen2->packet = kzalloc(4096, GFP_KERNEL); - if (!inst_hfi_gen2->packet) - return -ENOMEM; -@@ -188,12 +203,58 @@ static int iris_hfi_gen2_session_close(struct iris_inst *inst) - return ret; - } - -+static int iris_hfi_gen2_session_start(struct iris_inst *inst, u32 plane) -+{ -+ struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); -+ -+ iris_hfi_gen2_packet_session_command(inst, -+ HFI_CMD_START, -+ (HFI_HOST_FLAGS_RESPONSE_REQUIRED | -+ HFI_HOST_FLAGS_INTR_REQUIRED), -+ iris_hfi_gen2_get_port(plane), -+ inst->session_id, -+ HFI_PAYLOAD_NONE, -+ NULL, -+ 0); -+ -+ return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet, -+ inst_hfi_gen2->packet->size); -+} -+ -+static int iris_hfi_gen2_session_stop(struct iris_inst *inst, u32 plane) -+{ -+ struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); -+ int ret = 0; -+ -+ reinit_completion(&inst->completion); -+ -+ iris_hfi_gen2_packet_session_command(inst, -+ HFI_CMD_STOP, -+ (HFI_HOST_FLAGS_RESPONSE_REQUIRED | -+ HFI_HOST_FLAGS_INTR_REQUIRED | -+ HFI_HOST_FLAGS_NON_DISCARDABLE), -+ iris_hfi_gen2_get_port(plane), -+ inst->session_id, -+ HFI_PAYLOAD_NONE, -+ NULL, -+ 0); -+ -+ ret = iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet, -+ inst_hfi_gen2->packet->size); -+ if (ret) -+ return ret; -+ -+ return iris_wait_for_session_response(inst, false); -+} -+ - static const struct iris_hfi_command_ops iris_hfi_gen2_command_ops = { - .sys_init = iris_hfi_gen2_sys_init, - .sys_image_version = iris_hfi_gen2_sys_image_version, - .sys_interframe_powercollapse = iris_hfi_gen2_sys_interframe_powercollapse, - .sys_pc_prep = iris_hfi_gen2_sys_pc_prep, - .session_open = iris_hfi_gen2_session_open, -+ .session_start = iris_hfi_gen2_session_start, -+ .session_stop = iris_hfi_gen2_session_stop, - .session_close = iris_hfi_gen2_session_close, - }; - -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h -index 173a554a0d44..930dbae49dfa 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h -@@ -15,6 +15,8 @@ - #define HFI_CMD_POWER_COLLAPSE 0x01000002 - #define HFI_CMD_OPEN 0x01000003 - #define HFI_CMD_CLOSE 0x01000004 -+#define HFI_CMD_START 0x01000005 -+#define HFI_CMD_STOP 0x01000006 - #define HFI_CMD_END 0x01FFFFFF - - #define HFI_PROP_BEGIN 0x03000000 -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c -index e1c43daea6c7..53b700ef852e 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c -@@ -101,6 +101,7 @@ static int iris_hfi_gen2_handle_session_error(struct iris_inst *inst, - - dev_err(core->dev, "session error received %#x: %s\n", pkt->type, error); - iris_vb2_queue_error(inst); -+ iris_inst_change_state(inst, IRIS_INST_ERROR); - - return 0; - } -@@ -108,9 +109,17 @@ static int iris_hfi_gen2_handle_session_error(struct iris_inst *inst, - static int iris_hfi_gen2_handle_system_error(struct iris_core *core, - struct iris_hfi_packet *pkt) - { -+ struct iris_inst *instance; -+ - dev_err(core->dev, "received system error of type %#x\n", pkt->type); - - core->state = IRIS_CORE_ERROR; -+ -+ mutex_lock(&core->lock); -+ list_for_each_entry(instance, &core->instances, list) -+ iris_inst_change_state(instance, IRIS_INST_ERROR); -+ mutex_unlock(&core->lock); -+ - schedule_delayed_work(&core->sys_error_handler, msecs_to_jiffies(10)); - - return 0; -@@ -129,20 +138,32 @@ static int iris_hfi_gen2_handle_system_init(struct iris_core *core, - return 0; - } - -+static void iris_hfi_gen2_handle_session_close(struct iris_inst *inst, -+ struct iris_hfi_packet *pkt) -+{ -+ if (!(pkt->flags & HFI_FW_FLAGS_SUCCESS)) { -+ iris_inst_change_state(inst, IRIS_INST_ERROR); -+ return; -+ } -+ -+ complete(&inst->completion); -+} -+ - static int iris_hfi_gen2_handle_session_command(struct iris_inst *inst, - struct iris_hfi_packet *pkt) - { -- int ret = 0; -- - switch (pkt->type) { - case HFI_CMD_CLOSE: -+ iris_hfi_gen2_handle_session_close(inst, pkt); -+ break; -+ case HFI_CMD_STOP: - complete(&inst->completion); - break; - default: - break; - } - -- return ret; -+ return 0; - } - - static int iris_hfi_gen2_handle_image_version_property(struct iris_core *core, -@@ -247,8 +268,11 @@ static int iris_hfi_gen2_handle_session_response(struct iris_core *core, - if (packet->flags & HFI_FW_FLAGS_SESSION_ERROR) - iris_hfi_gen2_handle_session_error(inst, packet); - -- if (packet->type > range[i].begin && packet->type < range[i].end) -+ if (packet->type > range[i].begin && packet->type < range[i].end) { - ret = range[i].handle(inst, packet); -+ if (ret) -+ iris_inst_change_state(inst, IRIS_INST_ERROR); -+ } - pkt += packet->size; - } - } -diff --git a/drivers/media/platform/qcom/iris/iris_instance.h b/drivers/media/platform/qcom/iris/iris_instance.h -index 9f1a1e5ba7c7..6b88daf31011 100644 ---- a/drivers/media/platform/qcom/iris/iris_instance.h -+++ b/drivers/media/platform/qcom/iris/iris_instance.h -@@ -26,9 +26,11 @@ - * @ctrl_handler: reference of v4l2 ctrl handler - * @crop: structure of crop info - * @completion: structure of signal completions -+ * @flush_completion: structure of signal completions for flush cmd - * @fw_caps: array of supported instance firmware capabilities - * @buffers: array of different iris buffers - * @fw_min_count: minimnum count of buffers needed by fw -+ * @state: instance state - * @once_per_session_set: boolean to set once per session property - * @m2m_dev: a reference to m2m device structure - * @m2m_ctx: a reference to m2m context structure -@@ -46,9 +48,11 @@ struct iris_inst { - struct v4l2_ctrl_handler ctrl_handler; - struct iris_hfi_rect_desc crop; - struct completion completion; -+ struct completion flush_completion; - struct platform_inst_fw_cap fw_caps[INST_FW_CAP_MAX]; - struct iris_buffers buffers[BUF_TYPE_MAX]; - u32 fw_min_count; -+ enum iris_inst_state state; - bool once_per_session_set; - struct v4l2_m2m_dev *m2m_dev; - struct v4l2_m2m_ctx *m2m_ctx; -diff --git a/drivers/media/platform/qcom/iris/iris_state.c b/drivers/media/platform/qcom/iris/iris_state.c -new file mode 100644 -index 000000000000..44362e8fe18f ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_state.c -@@ -0,0 +1,104 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#include "iris_instance.h" -+ -+static bool iris_allow_inst_state_change(struct iris_inst *inst, -+ enum iris_inst_state req_state) -+{ -+ switch (inst->state) { -+ case IRIS_INST_INIT: -+ if (req_state == IRIS_INST_INPUT_STREAMING || -+ req_state == IRIS_INST_OUTPUT_STREAMING || -+ req_state == IRIS_INST_DEINIT) -+ return true; -+ return false; -+ case IRIS_INST_INPUT_STREAMING: -+ if (req_state == IRIS_INST_INIT || -+ req_state == IRIS_INST_STREAMING || -+ req_state == IRIS_INST_DEINIT) -+ return true; -+ return false; -+ case IRIS_INST_OUTPUT_STREAMING: -+ if (req_state == IRIS_INST_INIT || -+ req_state == IRIS_INST_STREAMING || -+ req_state == IRIS_INST_DEINIT) -+ return true; -+ return false; -+ case IRIS_INST_STREAMING: -+ if (req_state == IRIS_INST_INPUT_STREAMING || -+ req_state == IRIS_INST_OUTPUT_STREAMING || -+ req_state == IRIS_INST_DEINIT) -+ return true; -+ return false; -+ case IRIS_INST_DEINIT: -+ if (req_state == IRIS_INST_INIT) -+ return true; -+ return false; -+ default: -+ return false; -+ } -+} -+ -+int iris_inst_change_state(struct iris_inst *inst, -+ enum iris_inst_state request_state) -+{ -+ if (inst->state == IRIS_INST_ERROR) -+ return 0; -+ -+ if (inst->state == request_state) -+ return 0; -+ -+ if (request_state == IRIS_INST_ERROR) -+ goto change_state; -+ -+ if (!iris_allow_inst_state_change(inst, request_state)) -+ return -EINVAL; -+ -+change_state: -+ inst->state = request_state; -+ dev_dbg(inst->core->dev, "state changed from %x to %x\n", -+ inst->state, request_state); -+ -+ return 0; -+} -+ -+int iris_inst_state_change_streamon(struct iris_inst *inst, u32 plane) -+{ -+ enum iris_inst_state new_state = IRIS_INST_ERROR; -+ -+ if (V4L2_TYPE_IS_OUTPUT(plane)) { -+ if (inst->state == IRIS_INST_INIT) -+ new_state = IRIS_INST_INPUT_STREAMING; -+ else if (inst->state == IRIS_INST_OUTPUT_STREAMING) -+ new_state = IRIS_INST_STREAMING; -+ } else if (V4L2_TYPE_IS_CAPTURE(plane)) { -+ if (inst->state == IRIS_INST_INIT) -+ new_state = IRIS_INST_OUTPUT_STREAMING; -+ else if (inst->state == IRIS_INST_INPUT_STREAMING) -+ new_state = IRIS_INST_STREAMING; -+ } -+ -+ return iris_inst_change_state(inst, new_state); -+} -+ -+int iris_inst_state_change_streamoff(struct iris_inst *inst, u32 plane) -+{ -+ enum iris_inst_state new_state = IRIS_INST_ERROR; -+ -+ if (V4L2_TYPE_IS_OUTPUT(plane)) { -+ if (inst->state == IRIS_INST_INPUT_STREAMING) -+ new_state = IRIS_INST_INIT; -+ else if (inst->state == IRIS_INST_STREAMING) -+ new_state = IRIS_INST_OUTPUT_STREAMING; -+ } else if (V4L2_TYPE_IS_CAPTURE(plane)) { -+ if (inst->state == IRIS_INST_OUTPUT_STREAMING) -+ new_state = IRIS_INST_INIT; -+ else if (inst->state == IRIS_INST_STREAMING) -+ new_state = IRIS_INST_INPUT_STREAMING; -+ } -+ -+ return iris_inst_change_state(inst, new_state); -+} -diff --git a/drivers/media/platform/qcom/iris/iris_state.h b/drivers/media/platform/qcom/iris/iris_state.h -index 1ffe6fe706bd..0bf9d0e063ac 100644 ---- a/drivers/media/platform/qcom/iris/iris_state.h -+++ b/drivers/media/platform/qcom/iris/iris_state.h -@@ -6,6 +6,8 @@ - #ifndef __IRIS_STATE_H__ - #define __IRIS_STATE_H__ - -+struct iris_inst; -+ - /** - * enum iris_core_state - * -@@ -38,4 +40,60 @@ enum iris_core_state { - IRIS_CORE_ERROR, - }; - -+/** -+ * enum iris_inst_state -+ * -+ * @IRIS_INST_INIT: video instance is opened. -+ * @IRIS_INST_INPUT_STREAMING: stream on is completed on output plane. -+ * @IRIS_INST_OUTPUT_STREAMING: stream on is completed on capture plane. -+ * @IRIS_INST_STREAMING: stream on is completed on both output and capture planes. -+ * @IRIS_INST_DEINIT: video instance is closed. -+ * @IRIS_INST_ERROR: error state. -+ * | -+ * V -+ * ------------- -+ * +--------| INIT |----------+ -+ * | ------------- | -+ * | ^ ^ | -+ * | / \ | -+ * | / \ | -+ * | v v | -+ * | ----------- ----------- | -+ * | | INPUT OUTPUT | | -+ * |---| STREAMING STREAMING |---| -+ * | ----------- ----------- | -+ * | ^ ^ | -+ * | \ / | -+ * | \ / | -+ * | v v | -+ * | ------------- | -+ * |--------| STREAMING |-----------| -+ * | ------------- | -+ * | | | -+ * | | | -+ * | v | -+ * | ----------- | -+ * +-------->| DEINIT |<----------+ -+ * | ----------- | -+ * | | | -+ * | | | -+ * | v | -+ * | ---------- | -+ * +-------->| ERROR |<------------+ -+ * ---------- -+ */ -+enum iris_inst_state { -+ IRIS_INST_DEINIT, -+ IRIS_INST_INIT, -+ IRIS_INST_INPUT_STREAMING, -+ IRIS_INST_OUTPUT_STREAMING, -+ IRIS_INST_STREAMING, -+ IRIS_INST_ERROR, -+}; -+ -+int iris_inst_change_state(struct iris_inst *inst, -+ enum iris_inst_state request_state); -+int iris_inst_state_change_streamon(struct iris_inst *inst, u32 plane); -+int iris_inst_state_change_streamoff(struct iris_inst *inst, u32 plane); -+ - #endif -diff --git a/drivers/media/platform/qcom/iris/iris_utils.c b/drivers/media/platform/qcom/iris/iris_utils.c -index d5c8e052922c..4833830f30d5 100644 ---- a/drivers/media/platform/qcom/iris/iris_utils.c -+++ b/drivers/media/platform/qcom/iris/iris_utils.c -@@ -17,20 +17,23 @@ int iris_get_mbpf(struct iris_inst *inst) - return NUM_MBS_PER_FRAME(height, width); - } - --int iris_wait_for_session_response(struct iris_inst *inst) -+int iris_wait_for_session_response(struct iris_inst *inst, bool is_flush) - { - struct iris_core *core = inst->core; - u32 hw_response_timeout_val; -+ struct completion *done; - int ret; - - hw_response_timeout_val = core->iris_platform_data->hw_response_timeout; -+ done = is_flush ? &inst->flush_completion : &inst->completion; - - mutex_unlock(&inst->lock); -- ret = wait_for_completion_timeout(&inst->completion, -- msecs_to_jiffies(hw_response_timeout_val)); -+ ret = wait_for_completion_timeout(done, msecs_to_jiffies(hw_response_timeout_val)); - mutex_lock(&inst->lock); -- if (!ret) -+ if (!ret) { -+ iris_inst_change_state(inst, IRIS_INST_ERROR); - return -ETIMEDOUT; -+ } - - return 0; - } -diff --git a/drivers/media/platform/qcom/iris/iris_utils.h b/drivers/media/platform/qcom/iris/iris_utils.h -index 26649b66d978..40658a6643cf 100644 ---- a/drivers/media/platform/qcom/iris/iris_utils.h -+++ b/drivers/media/platform/qcom/iris/iris_utils.h -@@ -29,6 +29,6 @@ static inline enum iris_buffer_type iris_v4l2_type_to_driver(u32 type) - - int iris_get_mbpf(struct iris_inst *inst); - struct iris_inst *iris_get_instance(struct iris_core *core, u32 session_id); --int iris_wait_for_session_response(struct iris_inst *inst); -+int iris_wait_for_session_response(struct iris_inst *inst, bool is_flush); - - #endif -diff --git a/drivers/media/platform/qcom/iris/iris_vb2.c b/drivers/media/platform/qcom/iris/iris_vb2.c -index e9db44515d91..b93da860d336 100644 ---- a/drivers/media/platform/qcom/iris/iris_vb2.c -+++ b/drivers/media/platform/qcom/iris/iris_vb2.c -@@ -5,6 +5,7 @@ - - #include "iris_instance.h" - #include "iris_vb2.h" -+#include "iris_vdec.h" - - int iris_vb2_queue_setup(struct vb2_queue *q, - unsigned int *num_buffers, unsigned int *num_planes, -@@ -18,6 +19,10 @@ int iris_vb2_queue_setup(struct vb2_queue *q, - inst = vb2_get_drv_priv(q); - - mutex_lock(&inst->lock); -+ if (inst->state == IRIS_INST_ERROR) { -+ ret = -EBUSY; -+ goto unlock; -+ } - - core = inst->core; - f = V4L2_TYPE_IS_OUTPUT(q->type) ? inst->fmt_src : inst->fmt_dst; -@@ -38,6 +43,10 @@ int iris_vb2_queue_setup(struct vb2_queue *q, - dev_err(core->dev, "session open failed\n"); - goto unlock; - } -+ -+ ret = iris_inst_change_state(inst, IRIS_INST_INIT); -+ if (ret) -+ goto unlock; - } - - *num_planes = 1; -@@ -48,3 +57,64 @@ int iris_vb2_queue_setup(struct vb2_queue *q, - - return ret; - } -+ -+int iris_vb2_start_streaming(struct vb2_queue *q, unsigned int count) -+{ -+ struct iris_inst *inst; -+ int ret = 0; -+ -+ inst = vb2_get_drv_priv(q); -+ -+ if (V4L2_TYPE_IS_CAPTURE(q->type) && inst->state == IRIS_INST_INIT) -+ return 0; -+ -+ mutex_lock(&inst->lock); -+ if (inst->state == IRIS_INST_ERROR) { -+ ret = -EBUSY; -+ goto error; -+ } -+ -+ if (!V4L2_TYPE_IS_OUTPUT(q->type) && -+ !V4L2_TYPE_IS_CAPTURE(q->type)) { -+ ret = -EINVAL; -+ goto error; -+ } -+ -+ if (V4L2_TYPE_IS_OUTPUT(q->type)) -+ ret = iris_vdec_streamon_input(inst); -+ else if (V4L2_TYPE_IS_CAPTURE(q->type)) -+ ret = iris_vdec_streamon_output(inst); -+ if (ret) -+ goto error; -+ -+ mutex_unlock(&inst->lock); -+ -+ return ret; -+ -+error: -+ iris_inst_change_state(inst, IRIS_INST_ERROR); -+ mutex_unlock(&inst->lock); -+ -+ return ret; -+} -+ -+void iris_vb2_stop_streaming(struct vb2_queue *q) -+{ -+ struct iris_inst *inst; -+ -+ inst = vb2_get_drv_priv(q); -+ -+ if (V4L2_TYPE_IS_CAPTURE(q->type) && inst->state == IRIS_INST_INIT) -+ return; -+ -+ mutex_lock(&inst->lock); -+ -+ if (!V4L2_TYPE_IS_OUTPUT(q->type) && -+ !V4L2_TYPE_IS_CAPTURE(q->type)) -+ goto exit; -+ -+ iris_vdec_session_streamoff(inst, q->type); -+ -+exit: -+ mutex_unlock(&inst->lock); -+} -diff --git a/drivers/media/platform/qcom/iris/iris_vb2.h b/drivers/media/platform/qcom/iris/iris_vb2.h -index d2e71d0596cc..3906510fa71f 100644 ---- a/drivers/media/platform/qcom/iris/iris_vb2.h -+++ b/drivers/media/platform/qcom/iris/iris_vb2.h -@@ -9,4 +9,7 @@ - int iris_vb2_queue_setup(struct vb2_queue *q, - unsigned int *num_buffers, unsigned int *num_planes, - unsigned int sizes[], struct device *alloc_devs[]); -+int iris_vb2_start_streaming(struct vb2_queue *q, unsigned int count); -+void iris_vb2_stop_streaming(struct vb2_queue *q); -+ - #endif -diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c b/drivers/media/platform/qcom/iris/iris_vdec.c -index 132b578b34dc..92651d86376d 100644 ---- a/drivers/media/platform/qcom/iris/iris_vdec.c -+++ b/drivers/media/platform/qcom/iris/iris_vdec.c -@@ -222,3 +222,78 @@ int iris_vdec_subscribe_event(struct iris_inst *inst, const struct v4l2_event_su - - return ret; - } -+ -+static void iris_vdec_kill_session(struct iris_inst *inst) -+{ -+ const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; -+ -+ if (!inst->session_id) -+ return; -+ -+ hfi_ops->session_close(inst); -+ iris_inst_change_state(inst, IRIS_INST_ERROR); -+} -+ -+void iris_vdec_session_streamoff(struct iris_inst *inst, u32 plane) -+{ -+ const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; -+ int ret; -+ -+ ret = hfi_ops->session_stop(inst, plane); -+ if (ret) -+ goto error; -+ -+ ret = iris_inst_state_change_streamoff(inst, plane); -+ if (ret) -+ goto error; -+ -+ return; -+ -+error: -+ iris_vdec_kill_session(inst); -+} -+ -+static int iris_vdec_process_streamon_input(struct iris_inst *inst) -+{ -+ const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; -+ int ret; -+ -+ ret = hfi_ops->session_start(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); -+ if (ret) -+ return ret; -+ -+ return iris_inst_state_change_streamon(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); -+} -+ -+int iris_vdec_streamon_input(struct iris_inst *inst) -+{ -+ return iris_vdec_process_streamon_input(inst); -+} -+ -+static int iris_vdec_process_streamon_output(struct iris_inst *inst) -+{ -+ const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; -+ int ret; -+ -+ ret = hfi_ops->session_start(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); -+ if (ret) -+ return ret; -+ -+ return iris_inst_state_change_streamon(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); -+} -+ -+int iris_vdec_streamon_output(struct iris_inst *inst) -+{ -+ int ret; -+ -+ ret = iris_vdec_process_streamon_output(inst); -+ if (ret) -+ goto error; -+ -+ return ret; -+ -+error: -+ iris_vdec_session_streamoff(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); -+ -+ return ret; -+} -diff --git a/drivers/media/platform/qcom/iris/iris_vdec.h b/drivers/media/platform/qcom/iris/iris_vdec.h -index 9f08a13cb6bb..a17bb817b6e5 100644 ---- a/drivers/media/platform/qcom/iris/iris_vdec.h -+++ b/drivers/media/platform/qcom/iris/iris_vdec.h -@@ -14,5 +14,8 @@ int iris_vdec_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f); - int iris_vdec_try_fmt(struct iris_inst *inst, struct v4l2_format *f); - int iris_vdec_s_fmt(struct iris_inst *inst, struct v4l2_format *f); - int iris_vdec_subscribe_event(struct iris_inst *inst, const struct v4l2_event_subscription *sub); -+int iris_vdec_streamon_input(struct iris_inst *inst); -+int iris_vdec_streamon_output(struct iris_inst *inst); -+void iris_vdec_session_streamoff(struct iris_inst *inst, u32 plane); - - #endif -diff --git a/drivers/media/platform/qcom/iris/iris_vidc.c b/drivers/media/platform/qcom/iris/iris_vidc.c -index 5b54231f2def..1d10c430c795 100644 ---- a/drivers/media/platform/qcom/iris/iris_vidc.c -+++ b/drivers/media/platform/qcom/iris/iris_vidc.c -@@ -145,10 +145,12 @@ int iris_open(struct file *filp) - - inst->core = core; - inst->session_id = hash32_ptr(inst); -+ inst->state = IRIS_INST_DEINIT; - - mutex_init(&inst->lock); - mutex_init(&inst->ctx_q_lock); - init_completion(&inst->completion); -+ init_completion(&inst->flush_completion); - - iris_v4l2_fh_init(inst); - -@@ -194,6 +196,9 @@ static void iris_session_close(struct iris_inst *inst) - bool wait_for_response = true; - int ret; - -+ if (inst->state == IRIS_INST_DEINIT) -+ return; -+ - reinit_completion(&inst->completion); - - ret = hfi_ops->session_close(inst); -@@ -201,7 +206,7 @@ static void iris_session_close(struct iris_inst *inst) - wait_for_response = false; - - if (wait_for_response) -- iris_wait_for_session_response(inst); -+ iris_wait_for_session_response(inst, false); - } - - int iris_close(struct file *filp) -@@ -214,6 +219,7 @@ int iris_close(struct file *filp) - mutex_lock(&inst->lock); - iris_vdec_inst_deinit(inst); - iris_session_close(inst); -+ iris_inst_change_state(inst, IRIS_INST_DEINIT); - iris_v4l2_fh_deinit(inst); - iris_remove_session(inst); - mutex_unlock(&inst->lock); -@@ -356,6 +362,8 @@ static struct v4l2_file_operations iris_v4l2_file_ops = { - - static const struct vb2_ops iris_vb2_ops = { - .queue_setup = iris_vb2_queue_setup, -+ .start_streaming = iris_vb2_start_streaming, -+ .stop_streaming = iris_vb2_stop_streaming, - }; - - static const struct v4l2_ioctl_ops iris_v4l2_ioctl_ops = { -@@ -373,6 +381,8 @@ static const struct v4l2_ioctl_ops iris_v4l2_ioctl_ops = { - .vidioc_g_selection = iris_g_selection, - .vidioc_subscribe_event = iris_subscribe_event, - .vidioc_unsubscribe_event = v4l2_event_unsubscribe, -+ .vidioc_streamon = v4l2_m2m_ioctl_streamon, -+ .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, - }; - - void iris_init_ops(struct iris_core *core) --- -2.34.1 - diff --git a/patch/kernel/archive/sm8550-6.12/0017_media--iris--implement-set-properties-to-firmware-.patch b/patch/kernel/archive/sm8550-6.12/0017_media--iris--implement-set-properties-to-firmware-.patch deleted file mode 100644 index f086ab64eff0..000000000000 --- a/patch/kernel/archive/sm8550-6.12/0017_media--iris--implement-set-properties-to-firmware-.patch +++ /dev/null @@ -1,1863 +0,0 @@ -From f2eb2b24a358631afbe6f8d0909e1d64ddb1eb48 Mon Sep 17 00:00:00 2001 -From: Vedang Nagar -Date: Fri, 7 Feb 2025 13:24:57 +0530 -Subject: [PATCH] media: iris: implement set properties to firmware during - streamon - -During the stream on operation, set some mandatory properties on the -firmware to start a session. Set all v4l2 properties, which are set by -the client, on to firmware, which is prepared with the dependency graph. - -Signed-off-by: Vedang Nagar -Tested-by: Stefan Schmidt # x1e80100 (Dell XPS 13 9345) -Reviewed-by: Stefan Schmidt -Tested-by: Neil Armstrong # on SM8550-QRD -Tested-by: Neil Armstrong # on SM8550-HDK -Signed-off-by: Dikshita Agarwal -Link: https://lore.kernel.org/r/20250207-qcom-video-iris-v10-17-ab66eeffbd20@quicinc.com -Signed-off-by: Neil Armstrong ---- - .../media/platform/qcom/iris/iris_buffer.c | 121 ++++++ - drivers/media/platform/qcom/iris/iris_ctrls.c | 94 ++++ - drivers/media/platform/qcom/iris/iris_ctrls.h | 5 + - .../platform/qcom/iris/iris_hfi_common.h | 76 ++++ - .../qcom/iris/iris_hfi_gen1_command.c | 411 ++++++++++++++++++ - .../qcom/iris/iris_hfi_gen1_defines.h | 83 ++++ - .../media/platform/qcom/iris/iris_hfi_gen2.h | 2 + - .../qcom/iris/iris_hfi_gen2_command.c | 300 +++++++++++++ - .../qcom/iris/iris_hfi_gen2_defines.h | 27 ++ - .../platform/qcom/iris/iris_hfi_gen2_packet.c | 79 ++++ - .../platform/qcom/iris/iris_hfi_gen2_packet.h | 7 + - .../qcom/iris/iris_hfi_gen2_response.c | 49 +++ - .../platform/qcom/iris/iris_platform_common.h | 32 ++ - .../platform/qcom/iris/iris_platform_sm8550.c | 89 ++++ - drivers/media/platform/qcom/iris/iris_utils.c | 19 + - drivers/media/platform/qcom/iris/iris_utils.h | 3 + - drivers/media/platform/qcom/iris/iris_vdec.c | 11 + - .../platform/qcom/iris/iris_vpu_buffer.c | 20 + - .../platform/qcom/iris/iris_vpu_buffer.h | 1 + - 19 files changed, 1429 insertions(+) - -diff --git a/drivers/media/platform/qcom/iris/iris_buffer.c b/drivers/media/platform/qcom/iris/iris_buffer.c -index 037931ce6550..58d45d23393b 100644 ---- a/drivers/media/platform/qcom/iris/iris_buffer.c -+++ b/drivers/media/platform/qcom/iris/iris_buffer.c -@@ -72,6 +72,125 @@ static u32 iris_yuv_buffer_size_nv12(struct iris_inst *inst) - return ALIGN(y_plane + uv_plane, PIXELS_4K); - } - -+/* -+ * QC08C: -+ * Compressed Macro-tile format for NV12. -+ * Contains 4 planes in the following order - -+ * (A) Y_Meta_Plane -+ * (B) Y_UBWC_Plane -+ * (C) UV_Meta_Plane -+ * (D) UV_UBWC_Plane -+ * -+ * Y_Meta_Plane consists of meta information to decode compressed -+ * tile data in Y_UBWC_Plane. -+ * Y_UBWC_Plane consists of Y data in compressed macro-tile format. -+ * UBWC decoder block will use the Y_Meta_Plane data together with -+ * Y_UBWC_Plane data to produce loss-less uncompressed 8 bit Y samples. -+ * -+ * UV_Meta_Plane consists of meta information to decode compressed -+ * tile data in UV_UBWC_Plane. -+ * UV_UBWC_Plane consists of UV data in compressed macro-tile format. -+ * UBWC decoder block will use UV_Meta_Plane data together with -+ * UV_UBWC_Plane data to produce loss-less uncompressed 8 bit 2x2 -+ * subsampled color difference samples. -+ * -+ * Each tile in Y_UBWC_Plane/UV_UBWC_Plane is independently decodable -+ * and randomly accessible. There is no dependency between tiles. -+ * -+ * <----- y_meta_stride ----> (aligned to 64) -+ * <-------- Width ------> -+ * M M M M M M M M M M M M . . ^ ^ -+ * M M M M M M M M M M M M . . | | -+ * M M M M M M M M M M M M . . Height | -+ * M M M M M M M M M M M M . . | y_meta_scanlines (aligned to 16) -+ * M M M M M M M M M M M M . . | | -+ * M M M M M M M M M M M M . . | | -+ * M M M M M M M M M M M M . . | | -+ * M M M M M M M M M M M M . . V | -+ * . . . . . . . . . . . . . . | -+ * . . . . . . . . . . . . . . | -+ * . . . . . . . . . . . . . . -------> Buffer size aligned to 4k -+ * . . . . . . . . . . . . . . V -+ * <--Compressed tile y_stride---> (aligned to 128) -+ * <------- Width -------> -+ * Y* Y* Y* Y* Y* Y* Y* Y* . . . . ^ ^ -+ * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | -+ * Y* Y* Y* Y* Y* Y* Y* Y* . . . . Height | -+ * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | Macro_tile y_scanlines (aligned to 32) -+ * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | -+ * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | -+ * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | -+ * Y* Y* Y* Y* Y* Y* Y* Y* . . . . V | -+ * . . . . . . . . . . . . . . . . | -+ * . . . . . . . . . . . . . . . . | -+ * . . . . . . . . . . . . . . . . -------> Buffer size aligned to 4k -+ * . . . . . . . . . . . . . . . . V -+ * <----- uv_meta_stride ----> (aligned to 64) -+ * M M M M M M M M M M M M . . ^ -+ * M M M M M M M M M M M M . . | -+ * M M M M M M M M M M M M . . | -+ * M M M M M M M M M M M M . . uv_meta_scanlines (aligned to 16) -+ * . . . . . . . . . . . . . . | -+ * . . . . . . . . . . . . . . V -+ * . . . . . . . . . . . . . . -------> Buffer size aligned to 4k -+ * <--Compressed tile uv_stride---> (aligned to 128) -+ * U* V* U* V* U* V* U* V* . . . . ^ -+ * U* V* U* V* U* V* U* V* . . . . | -+ * U* V* U* V* U* V* U* V* . . . . | -+ * U* V* U* V* U* V* U* V* . . . . uv_scanlines (aligned to 32) -+ * . . . . . . . . . . . . . . . . | -+ * . . . . . . . . . . . . . . . . V -+ * . . . . . . . . . . . . . . . . -------> Buffer size aligned to 4k -+ * -+ * y_stride: width aligned to 128 -+ * uv_stride: width aligned to 128 -+ * y_scanlines: height aligned to 32 -+ * uv_scanlines: height aligned to 32 -+ * y_plane: buffer size aligned to 4096 -+ * uv_plane: buffer size aligned to 4096 -+ * y_meta_stride: width aligned to 64 -+ * y_meta_scanlines: height aligned to 16 -+ * y_meta_plane: buffer size aligned to 4096 -+ * uv_meta_stride: width aligned to 64 -+ * uv_meta_scanlines: height aligned to 16 -+ * uv_meta_plane: buffer size aligned to 4096 -+ * -+ * Total size = align( y_plane + uv_plane + -+ * y_meta_plane + uv_meta_plane, 4096) -+ * -+ * Note: All the alignments are hardware requirements. -+ */ -+static u32 iris_yuv_buffer_size_qc08c(struct iris_inst *inst) -+{ -+ u32 y_plane, uv_plane, y_stride, uv_stride; -+ struct v4l2_format *f = inst->fmt_dst; -+ u32 uv_meta_stride, uv_meta_plane; -+ u32 y_meta_stride, y_meta_plane; -+ -+ y_meta_stride = ALIGN(DIV_ROUND_UP(f->fmt.pix_mp.width, META_STRIDE_ALIGNED >> 1), -+ META_STRIDE_ALIGNED); -+ y_meta_plane = y_meta_stride * ALIGN(DIV_ROUND_UP(f->fmt.pix_mp.height, -+ META_SCANLINE_ALIGNED >> 1), -+ META_SCANLINE_ALIGNED); -+ y_meta_plane = ALIGN(y_meta_plane, PIXELS_4K); -+ -+ y_stride = ALIGN(f->fmt.pix_mp.width, Y_STRIDE_ALIGN); -+ y_plane = ALIGN(y_stride * ALIGN(f->fmt.pix_mp.height, Y_SCANLINE_ALIGN), PIXELS_4K); -+ -+ uv_meta_stride = ALIGN(DIV_ROUND_UP(f->fmt.pix_mp.width / 2, META_STRIDE_ALIGNED >> 2), -+ META_STRIDE_ALIGNED); -+ uv_meta_plane = uv_meta_stride * ALIGN(DIV_ROUND_UP(f->fmt.pix_mp.height / 2, -+ META_SCANLINE_ALIGNED >> 1), -+ META_SCANLINE_ALIGNED); -+ uv_meta_plane = ALIGN(uv_meta_plane, PIXELS_4K); -+ -+ uv_stride = ALIGN(f->fmt.pix_mp.width, UV_STRIDE_ALIGN); -+ uv_plane = ALIGN(uv_stride * ALIGN(f->fmt.pix_mp.height / 2, UV_SCANLINE_ALIGN_QC08C), -+ PIXELS_4K); -+ -+ return ALIGN(y_meta_plane + y_plane + uv_meta_plane + uv_plane, PIXELS_4K); -+} -+ - static u32 iris_bitstream_buffer_size(struct iris_inst *inst) - { - struct platform_inst_caps *caps = inst->core->iris_platform_data->inst_caps; -@@ -102,6 +221,8 @@ int iris_get_buffer_size(struct iris_inst *inst, - return iris_bitstream_buffer_size(inst); - case BUF_OUTPUT: - return iris_yuv_buffer_size_nv12(inst); -+ case BUF_DPB: -+ return iris_yuv_buffer_size_qc08c(inst); - default: - return 0; - } -diff --git a/drivers/media/platform/qcom/iris/iris_ctrls.c b/drivers/media/platform/qcom/iris/iris_ctrls.c -index 3652fa535bf3..b690578256d5 100644 ---- a/drivers/media/platform/qcom/iris/iris_ctrls.c -+++ b/drivers/media/platform/qcom/iris/iris_ctrls.c -@@ -3,7 +3,9 @@ - * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. - */ - -+#include - #include -+ - #include "iris_ctrls.h" - #include "iris_instance.h" - -@@ -163,3 +165,95 @@ void iris_session_init_caps(struct iris_core *core) - core->inst_fw_caps[cap_id].hfi_id = caps[i].hfi_id; - } - } -+ -+static u32 iris_get_port_info(struct iris_inst *inst, -+ enum platform_inst_fw_cap_type cap_id) -+{ -+ if (inst->fw_caps[cap_id].flags & CAP_FLAG_INPUT_PORT) -+ return HFI_PORT_BITSTREAM; -+ else if (inst->fw_caps[cap_id].flags & CAP_FLAG_OUTPUT_PORT) -+ return HFI_PORT_RAW; -+ -+ return HFI_PORT_NONE; -+} -+ -+int iris_set_u32_enum(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id) -+{ -+ const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; -+ u32 hfi_value = inst->fw_caps[cap_id].value; -+ u32 hfi_id = inst->fw_caps[cap_id].hfi_id; -+ -+ return hfi_ops->session_set_property(inst, hfi_id, -+ HFI_HOST_FLAGS_NONE, -+ iris_get_port_info(inst, cap_id), -+ HFI_PAYLOAD_U32_ENUM, -+ &hfi_value, sizeof(u32)); -+} -+ -+int iris_set_u32(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id) -+{ -+ const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; -+ u32 hfi_value = inst->fw_caps[cap_id].value; -+ u32 hfi_id = inst->fw_caps[cap_id].hfi_id; -+ -+ return hfi_ops->session_set_property(inst, hfi_id, -+ HFI_HOST_FLAGS_NONE, -+ iris_get_port_info(inst, cap_id), -+ HFI_PAYLOAD_U32, -+ &hfi_value, sizeof(u32)); -+} -+ -+int iris_set_stage(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id) -+{ -+ const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; -+ struct v4l2_format *inp_f = inst->fmt_src; -+ u32 hfi_id = inst->fw_caps[cap_id].hfi_id; -+ u32 height = inp_f->fmt.pix_mp.height; -+ u32 width = inp_f->fmt.pix_mp.width; -+ u32 work_mode = STAGE_2; -+ -+ if (iris_res_is_less_than(width, height, 1280, 720)) -+ work_mode = STAGE_1; -+ -+ return hfi_ops->session_set_property(inst, hfi_id, -+ HFI_HOST_FLAGS_NONE, -+ iris_get_port_info(inst, cap_id), -+ HFI_PAYLOAD_U32, -+ &work_mode, sizeof(u32)); -+} -+ -+int iris_set_pipe(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id) -+{ -+ const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; -+ u32 work_route = inst->fw_caps[PIPE].value; -+ u32 hfi_id = inst->fw_caps[cap_id].hfi_id; -+ -+ return hfi_ops->session_set_property(inst, hfi_id, -+ HFI_HOST_FLAGS_NONE, -+ iris_get_port_info(inst, cap_id), -+ HFI_PAYLOAD_U32, -+ &work_route, sizeof(u32)); -+} -+ -+int iris_set_properties(struct iris_inst *inst, u32 plane) -+{ -+ const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; -+ struct platform_inst_fw_cap *cap; -+ int ret; -+ u32 i; -+ -+ ret = hfi_ops->session_set_config_params(inst, plane); -+ if (ret) -+ return ret; -+ -+ for (i = 1; i < INST_FW_CAP_MAX; i++) { -+ cap = &inst->fw_caps[i]; -+ if (!iris_valid_cap_id(cap->cap_id)) -+ continue; -+ -+ if (cap->cap_id && cap->set) -+ cap->set(inst, i); -+ } -+ -+ return 0; -+} -diff --git a/drivers/media/platform/qcom/iris/iris_ctrls.h b/drivers/media/platform/qcom/iris/iris_ctrls.h -index fe65a772e6dd..9b5741868933 100644 ---- a/drivers/media/platform/qcom/iris/iris_ctrls.h -+++ b/drivers/media/platform/qcom/iris/iris_ctrls.h -@@ -13,5 +13,10 @@ struct iris_inst; - - int iris_ctrls_init(struct iris_inst *inst); - void iris_session_init_caps(struct iris_core *core); -+int iris_set_u32_enum(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id); -+int iris_set_stage(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id); -+int iris_set_pipe(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id); -+int iris_set_u32(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id); -+int iris_set_properties(struct iris_inst *inst, u32 plane); - - #endif -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_common.h b/drivers/media/platform/qcom/iris/iris_hfi_common.h -index 8b1c4d156cf2..1fba5a9292af 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_common.h -+++ b/drivers/media/platform/qcom/iris/iris_hfi_common.h -@@ -43,11 +43,75 @@ enum hfi_packet_host_flags { - HFI_HOST_FLAGS_GET_PROPERTY = 0x00000008, - }; - -+enum hfi_color_primaries { -+ HFI_PRIMARIES_RESERVED = 0, -+ HFI_PRIMARIES_BT709 = 1, -+ HFI_PRIMARIES_UNSPECIFIED = 2, -+ HFI_PRIMARIES_BT470_SYSTEM_M = 4, -+ HFI_PRIMARIES_BT470_SYSTEM_BG = 5, -+ HFI_PRIMARIES_BT601_525 = 6, -+ HFI_PRIMARIES_SMPTE_ST240M = 7, -+ HFI_PRIMARIES_GENERIC_FILM = 8, -+ HFI_PRIMARIES_BT2020 = 9, -+ HFI_PRIMARIES_SMPTE_ST428_1 = 10, -+ HFI_PRIMARIES_SMPTE_RP431_2 = 11, -+ HFI_PRIMARIES_SMPTE_EG431_1 = 12, -+ HFI_PRIMARIES_SMPTE_EBU_TECH = 22, -+}; -+ -+enum hfi_transfer_characteristics { -+ HFI_TRANSFER_RESERVED = 0, -+ HFI_TRANSFER_BT709 = 1, -+ HFI_TRANSFER_UNSPECIFIED = 2, -+ HFI_TRANSFER_BT470_SYSTEM_M = 4, -+ HFI_TRANSFER_BT470_SYSTEM_BG = 5, -+ HFI_TRANSFER_BT601_525_OR_625 = 6, -+ HFI_TRANSFER_SMPTE_ST240M = 7, -+ HFI_TRANSFER_LINEAR = 8, -+ HFI_TRANSFER_LOG_100_1 = 9, -+ HFI_TRANSFER_LOG_SQRT = 10, -+ HFI_TRANSFER_XVYCC = 11, -+ HFI_TRANSFER_BT1361_0 = 12, -+ HFI_TRANSFER_SRGB_SYCC = 13, -+ HFI_TRANSFER_BT2020_14 = 14, -+ HFI_TRANSFER_BT2020_15 = 15, -+ HFI_TRANSFER_SMPTE_ST2084_PQ = 16, -+ HFI_TRANSFER_SMPTE_ST428_1 = 17, -+ HFI_TRANSFER_BT2100_2_HLG = 18, -+}; -+ -+enum hfi_matrix_coefficients { -+ HFI_MATRIX_COEFF_SRGB_SMPTE_ST428_1 = 0, -+ HFI_MATRIX_COEFF_BT709 = 1, -+ HFI_MATRIX_COEFF_UNSPECIFIED = 2, -+ HFI_MATRIX_COEFF_RESERVED = 3, -+ HFI_MATRIX_COEFF_FCC_TITLE_47 = 4, -+ HFI_MATRIX_COEFF_BT470_SYS_BG_OR_BT601_625 = 5, -+ HFI_MATRIX_COEFF_BT601_525_BT1358_525_OR_625 = 6, -+ HFI_MATRIX_COEFF_SMPTE_ST240 = 7, -+ HFI_MATRIX_COEFF_YCGCO = 8, -+ HFI_MATRIX_COEFF_BT2020_NON_CONSTANT = 9, -+ HFI_MATRIX_COEFF_BT2020_CONSTANT = 10, -+ HFI_MATRIX_COEFF_SMPTE_ST2085 = 11, -+ HFI_MATRIX_COEFF_SMPTE_CHROM_DERV_NON_CONSTANT = 12, -+ HFI_MATRIX_COEFF_SMPTE_CHROM_DERV_CONSTANT = 13, -+ HFI_MATRIX_COEFF_BT2100 = 14, -+}; -+ -+struct iris_hfi_prop_type_handle { -+ u32 type; -+ int (*handle)(struct iris_inst *inst); -+}; -+ - struct iris_hfi_command_ops { - int (*sys_init)(struct iris_core *core); - int (*sys_image_version)(struct iris_core *core); - int (*sys_interframe_powercollapse)(struct iris_core *core); - int (*sys_pc_prep)(struct iris_core *core); -+ int (*session_set_config_params)(struct iris_inst *inst, u32 plane); -+ int (*session_set_property)(struct iris_inst *inst, -+ u32 packet_type, u32 flag, u32 plane, u32 payload_type, -+ void *payload, u32 payload_size); - int (*session_open)(struct iris_inst *inst); - int (*session_start)(struct iris_inst *inst, u32 plane); - int (*session_stop)(struct iris_inst *inst, u32 plane); -@@ -58,6 +122,18 @@ struct iris_hfi_response_ops { - void (*hfi_response_handler)(struct iris_core *core); - }; - -+struct hfi_subscription_params { -+ u32 bitstream_resolution; -+ u32 crop_offsets[2]; -+ u32 bit_depth; -+ u32 coded_frames; -+ u32 fw_min_count; -+ u32 pic_order_cnt; -+ u32 color_info; -+ u32 profile; -+ u32 level; -+}; -+ - int iris_hfi_core_init(struct iris_core *core); - int iris_hfi_pm_suspend(struct iris_core *core); - int iris_hfi_pm_resume(struct iris_core *core); -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c -index a3b09e8d1f49..26fe65ddba8a 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c -@@ -6,6 +6,7 @@ - #include "iris_hfi_gen1.h" - #include "iris_hfi_gen1_defines.h" - #include "iris_instance.h" -+#include "iris_vpu_buffer.h" - - static int iris_hfi_gen1_sys_init(struct iris_core *core) - { -@@ -182,12 +183,422 @@ static int iris_hfi_gen1_session_stop(struct iris_inst *inst, u32 plane) - return ret; - } - -+static int -+iris_hfi_gen1_packet_session_set_property(struct hfi_session_set_property_pkt *packet, -+ struct iris_inst *inst, u32 ptype, void *pdata) -+{ -+ void *prop_data = &packet->data[1]; -+ -+ packet->shdr.hdr.size = sizeof(*packet); -+ packet->shdr.hdr.pkt_type = HFI_CMD_SESSION_SET_PROPERTY; -+ packet->shdr.session_id = inst->session_id; -+ packet->num_properties = 1; -+ packet->data[0] = ptype; -+ -+ switch (ptype) { -+ case HFI_PROPERTY_PARAM_FRAME_SIZE: { -+ struct hfi_framesize *in = pdata, *fsize = prop_data; -+ -+ fsize->buffer_type = in->buffer_type; -+ fsize->height = in->height; -+ fsize->width = in->width; -+ packet->shdr.hdr.size += sizeof(u32) + sizeof(*fsize); -+ break; -+ } -+ case HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE: { -+ struct hfi_videocores_usage_type *in = pdata, *cu = prop_data; -+ -+ cu->video_core_enable_mask = in->video_core_enable_mask; -+ packet->shdr.hdr.size += sizeof(u32) + sizeof(*cu); -+ break; -+ } -+ case HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT: { -+ struct hfi_uncompressed_format_select *in = pdata; -+ struct hfi_uncompressed_format_select *hfi = prop_data; -+ -+ hfi->buffer_type = in->buffer_type; -+ hfi->format = in->format; -+ packet->shdr.hdr.size += sizeof(u32) + sizeof(*hfi); -+ break; -+ } -+ case HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO: { -+ struct hfi_uncompressed_plane_actual_constraints_info *info = prop_data; -+ -+ info->buffer_type = HFI_BUFFER_OUTPUT2; -+ info->num_planes = 2; -+ info->plane_format[0].stride_multiples = 128; -+ info->plane_format[0].max_stride = 8192; -+ info->plane_format[0].min_plane_buffer_height_multiple = 32; -+ info->plane_format[0].buffer_alignment = 256; -+ if (info->num_planes > 1) { -+ info->plane_format[1].stride_multiples = 128; -+ info->plane_format[1].max_stride = 8192; -+ info->plane_format[1].min_plane_buffer_height_multiple = 16; -+ info->plane_format[1].buffer_alignment = 256; -+ } -+ -+ packet->shdr.hdr.size += sizeof(u32) + sizeof(*info); -+ break; -+ } -+ case HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL: { -+ struct hfi_buffer_count_actual *in = pdata; -+ struct hfi_buffer_count_actual *count = prop_data; -+ -+ count->type = in->type; -+ count->count_actual = in->count_actual; -+ count->count_min_host = in->count_min_host; -+ packet->shdr.hdr.size += sizeof(u32) + sizeof(*count); -+ break; -+ } -+ case HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM: { -+ struct hfi_multi_stream *in = pdata; -+ struct hfi_multi_stream *multi = prop_data; -+ -+ multi->buffer_type = in->buffer_type; -+ multi->enable = in->enable; -+ packet->shdr.hdr.size += sizeof(u32) + sizeof(*multi); -+ break; -+ } -+ case HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL: { -+ struct hfi_buffer_size_actual *in = pdata, *sz = prop_data; -+ -+ sz->size = in->size; -+ sz->type = in->type; -+ packet->shdr.hdr.size += sizeof(u32) + sizeof(*sz); -+ break; -+ } -+ case HFI_PROPERTY_PARAM_WORK_ROUTE: { -+ struct hfi_video_work_route *wr = prop_data; -+ u32 *in = pdata; -+ -+ wr->video_work_route = *in; -+ packet->shdr.hdr.size += sizeof(u32) + sizeof(*wr); -+ break; -+ } -+ case HFI_PROPERTY_PARAM_WORK_MODE: { -+ struct hfi_video_work_mode *wm = prop_data; -+ u32 *in = pdata; -+ -+ wm->video_work_mode = *in; -+ packet->shdr.hdr.size += sizeof(u32) + sizeof(*wm); -+ break; -+ } -+ case HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER: { -+ struct hfi_enable *en = prop_data; -+ u32 *in = pdata; -+ -+ en->enable = *in; -+ packet->shdr.hdr.size += sizeof(u32) + sizeof(*en); -+ break; -+ } -+ default: -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int hfi_gen1_set_property(struct iris_inst *inst, u32 packet_type, -+ void *payload, u32 payload_size) -+{ -+ struct hfi_session_set_property_pkt *pkt; -+ u32 packet_size; -+ int ret; -+ -+ packet_size = sizeof(*pkt) + sizeof(u32) + payload_size; -+ pkt = kzalloc(packet_size, GFP_KERNEL); -+ if (!pkt) -+ return -ENOMEM; -+ -+ ret = iris_hfi_gen1_packet_session_set_property(pkt, inst, packet_type, payload); -+ if (ret == -EOPNOTSUPP) { -+ ret = 0; -+ goto exit; -+ } -+ if (ret) -+ goto exit; -+ -+ ret = iris_hfi_queue_cmd_write(inst->core, pkt, pkt->shdr.hdr.size); -+ -+exit: -+ kfree(pkt); -+ -+ return ret; -+} -+ -+static int iris_hfi_gen1_session_set_property(struct iris_inst *inst, u32 packet_type, -+ u32 flag, u32 plane, u32 payload_type, -+ void *payload, u32 payload_size) -+{ -+ return hfi_gen1_set_property(inst, packet_type, payload, payload_size); -+} -+ -+static int iris_hfi_gen1_set_resolution(struct iris_inst *inst) -+{ -+ u32 ptype = HFI_PROPERTY_PARAM_FRAME_SIZE; -+ struct hfi_framesize fs; -+ int ret; -+ -+ fs.buffer_type = HFI_BUFFER_INPUT; -+ fs.width = inst->fmt_src->fmt.pix_mp.width; -+ fs.height = inst->fmt_src->fmt.pix_mp.height; -+ -+ ret = hfi_gen1_set_property(inst, ptype, &fs, sizeof(fs)); -+ if (ret) -+ return ret; -+ -+ fs.buffer_type = HFI_BUFFER_OUTPUT2; -+ fs.width = inst->fmt_dst->fmt.pix_mp.width; -+ fs.height = inst->fmt_dst->fmt.pix_mp.height; -+ -+ return hfi_gen1_set_property(inst, ptype, &fs, sizeof(fs)); -+} -+ -+static int iris_hfi_gen1_decide_core(struct iris_inst *inst) -+{ -+ const u32 ptype = HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE; -+ struct hfi_videocores_usage_type cu; -+ -+ cu.video_core_enable_mask = HFI_CORE_ID_1; -+ -+ return hfi_gen1_set_property(inst, ptype, &cu, sizeof(cu)); -+} -+ -+static int iris_hfi_gen1_set_raw_format(struct iris_inst *inst) -+{ -+ const u32 ptype = HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT; -+ u32 pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat; -+ struct hfi_uncompressed_format_select fmt; -+ int ret; -+ -+ if (iris_split_mode_enabled(inst)) { -+ fmt.buffer_type = HFI_BUFFER_OUTPUT; -+ fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FORMAT_NV12_UBWC : 0; -+ -+ ret = hfi_gen1_set_property(inst, ptype, &fmt, sizeof(fmt)); -+ if (ret) -+ return ret; -+ -+ fmt.buffer_type = HFI_BUFFER_OUTPUT2; -+ fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FORMAT_NV12 : 0; -+ -+ ret = hfi_gen1_set_property(inst, ptype, &fmt, sizeof(fmt)); -+ } else { -+ fmt.buffer_type = HFI_BUFFER_OUTPUT; -+ fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FORMAT_NV12 : 0; -+ -+ ret = hfi_gen1_set_property(inst, ptype, &fmt, sizeof(fmt)); -+ } -+ -+ return ret; -+} -+ -+static int iris_hfi_gen1_set_format_constraints(struct iris_inst *inst) -+{ -+ const u32 ptype = HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO; -+ struct hfi_uncompressed_plane_actual_constraints_info pconstraint; -+ -+ pconstraint.buffer_type = HFI_BUFFER_OUTPUT2; -+ pconstraint.num_planes = 2; -+ pconstraint.plane_format[0].stride_multiples = 128; -+ pconstraint.plane_format[0].max_stride = 8192; -+ pconstraint.plane_format[0].min_plane_buffer_height_multiple = 32; -+ pconstraint.plane_format[0].buffer_alignment = 256; -+ -+ pconstraint.plane_format[1].stride_multiples = 128; -+ pconstraint.plane_format[1].max_stride = 8192; -+ pconstraint.plane_format[1].min_plane_buffer_height_multiple = 16; -+ pconstraint.plane_format[1].buffer_alignment = 256; -+ -+ return hfi_gen1_set_property(inst, ptype, &pconstraint, sizeof(pconstraint)); -+} -+ -+static int iris_hfi_gen1_set_num_bufs(struct iris_inst *inst) -+{ -+ u32 ptype = HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL; -+ struct hfi_buffer_count_actual buf_count; -+ int ret; -+ -+ buf_count.type = HFI_BUFFER_INPUT; -+ buf_count.count_actual = VIDEO_MAX_FRAME; -+ buf_count.count_min_host = VIDEO_MAX_FRAME; -+ -+ ret = hfi_gen1_set_property(inst, ptype, &buf_count, sizeof(buf_count)); -+ if (ret) -+ return ret; -+ -+ if (iris_split_mode_enabled(inst)) { -+ buf_count.type = HFI_BUFFER_OUTPUT; -+ buf_count.count_actual = VIDEO_MAX_FRAME; -+ buf_count.count_min_host = VIDEO_MAX_FRAME; -+ -+ ret = hfi_gen1_set_property(inst, ptype, &buf_count, sizeof(buf_count)); -+ if (ret) -+ return ret; -+ -+ buf_count.type = HFI_BUFFER_OUTPUT2; -+ buf_count.count_actual = iris_vpu_buf_count(inst, BUF_DPB); -+ buf_count.count_min_host = iris_vpu_buf_count(inst, BUF_DPB); -+ -+ ret = hfi_gen1_set_property(inst, ptype, &buf_count, sizeof(buf_count)); -+ } else { -+ buf_count.type = HFI_BUFFER_OUTPUT; -+ buf_count.count_actual = VIDEO_MAX_FRAME; -+ buf_count.count_min_host = VIDEO_MAX_FRAME; -+ -+ ret = hfi_gen1_set_property(inst, ptype, &buf_count, sizeof(buf_count)); -+ } -+ -+ return ret; -+} -+ -+static int iris_hfi_gen1_set_multistream(struct iris_inst *inst) -+{ -+ u32 ptype = HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM; -+ struct hfi_multi_stream multi = {0}; -+ int ret; -+ -+ if (iris_split_mode_enabled(inst)) { -+ multi.buffer_type = HFI_BUFFER_OUTPUT; -+ multi.enable = 0; -+ -+ ret = hfi_gen1_set_property(inst, ptype, &multi, sizeof(multi)); -+ if (ret) -+ return ret; -+ -+ multi.buffer_type = HFI_BUFFER_OUTPUT2; -+ multi.enable = 1; -+ -+ ret = hfi_gen1_set_property(inst, ptype, &multi, sizeof(multi)); -+ } else { -+ multi.buffer_type = HFI_BUFFER_OUTPUT; -+ multi.enable = 1; -+ -+ ret = hfi_gen1_set_property(inst, ptype, &multi, sizeof(multi)); -+ if (ret) -+ return ret; -+ -+ multi.buffer_type = HFI_BUFFER_OUTPUT2; -+ multi.enable = 0; -+ -+ ret = hfi_gen1_set_property(inst, ptype, &multi, sizeof(multi)); -+ } -+ -+ return ret; -+} -+ -+static int iris_hfi_gen1_set_bufsize(struct iris_inst *inst) -+{ -+ const u32 ptype = HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL; -+ struct hfi_buffer_size_actual bufsz; -+ int ret; -+ -+ if (iris_split_mode_enabled(inst)) { -+ bufsz.type = HFI_BUFFER_OUTPUT; -+ bufsz.size = iris_vpu_dec_dpb_size(inst); -+ -+ ret = hfi_gen1_set_property(inst, ptype, &bufsz, sizeof(bufsz)); -+ if (ret) -+ return ret; -+ -+ bufsz.type = HFI_BUFFER_OUTPUT2; -+ bufsz.size = inst->buffers[BUF_OUTPUT].size; -+ -+ ret = hfi_gen1_set_property(inst, ptype, &bufsz, sizeof(bufsz)); -+ } else { -+ bufsz.type = HFI_BUFFER_OUTPUT; -+ bufsz.size = inst->buffers[BUF_OUTPUT].size; -+ -+ ret = hfi_gen1_set_property(inst, ptype, &bufsz, sizeof(bufsz)); -+ if (ret) -+ return ret; -+ -+ bufsz.type = HFI_BUFFER_OUTPUT2; -+ bufsz.size = 0; -+ -+ ret = hfi_gen1_set_property(inst, ptype, &bufsz, sizeof(bufsz)); -+ } -+ -+ return ret; -+} -+ -+static int iris_hfi_gen1_session_set_config_params(struct iris_inst *inst, u32 plane) -+{ -+ struct iris_core *core = inst->core; -+ u32 config_params_size, i, j; -+ const u32 *config_params; -+ int ret; -+ -+ static const struct iris_hfi_prop_type_handle prop_type_handle_inp_arr[] = { -+ {HFI_PROPERTY_PARAM_FRAME_SIZE, -+ iris_hfi_gen1_set_resolution}, -+ {HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE, -+ iris_hfi_gen1_decide_core}, -+ {HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT, -+ iris_hfi_gen1_set_raw_format}, -+ {HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO, -+ iris_hfi_gen1_set_format_constraints}, -+ {HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL, -+ iris_hfi_gen1_set_num_bufs}, -+ {HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM, -+ iris_hfi_gen1_set_multistream}, -+ {HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL, -+ iris_hfi_gen1_set_bufsize}, -+ }; -+ -+ static const struct iris_hfi_prop_type_handle prop_type_handle_out_arr[] = { -+ {HFI_PROPERTY_PARAM_FRAME_SIZE, -+ iris_hfi_gen1_set_resolution}, -+ {HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT, -+ iris_hfi_gen1_set_raw_format}, -+ {HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO, -+ iris_hfi_gen1_set_format_constraints}, -+ {HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL, -+ iris_hfi_gen1_set_num_bufs}, -+ {HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM, -+ iris_hfi_gen1_set_multistream}, -+ {HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL, -+ iris_hfi_gen1_set_bufsize}, -+ }; -+ -+ config_params = core->iris_platform_data->input_config_params; -+ config_params_size = core->iris_platform_data->input_config_params_size; -+ -+ if (V4L2_TYPE_IS_OUTPUT(plane)) { -+ for (i = 0; i < config_params_size; i++) { -+ for (j = 0; j < ARRAY_SIZE(prop_type_handle_inp_arr); j++) { -+ if (prop_type_handle_inp_arr[j].type == config_params[i]) { -+ ret = prop_type_handle_inp_arr[j].handle(inst); -+ if (ret) -+ return ret; -+ break; -+ } -+ } -+ } -+ } else if (V4L2_TYPE_IS_CAPTURE(plane)) { -+ for (i = 0; i < config_params_size; i++) { -+ for (j = 0; j < ARRAY_SIZE(prop_type_handle_out_arr); j++) { -+ if (prop_type_handle_out_arr[j].type == config_params[i]) { -+ ret = prop_type_handle_out_arr[j].handle(inst); -+ if (ret) -+ return ret; -+ break; -+ } -+ } -+ } -+ } -+ -+ return 0; -+} -+ - static const struct iris_hfi_command_ops iris_hfi_gen1_command_ops = { - .sys_init = iris_hfi_gen1_sys_init, - .sys_image_version = iris_hfi_gen1_sys_image_version, - .sys_interframe_powercollapse = iris_hfi_gen1_sys_interframe_powercollapse, - .sys_pc_prep = iris_hfi_gen1_sys_pc_prep, - .session_open = iris_hfi_gen1_session_open, -+ .session_set_config_params = iris_hfi_gen1_session_set_config_params, -+ .session_set_property = iris_hfi_gen1_session_set_property, - .session_start = iris_hfi_gen1_session_start, - .session_stop = iris_hfi_gen1_session_stop, - .session_close = iris_hfi_gen1_session_close, -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h -index 1b2bf6afc6ce..67e7575351d4 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h -@@ -23,6 +23,8 @@ - #define HFI_CMD_SYS_SESSION_INIT 0x10007 - #define HFI_CMD_SYS_SESSION_END 0x10008 - -+#define HFI_CMD_SESSION_SET_PROPERTY 0x11001 -+ - #define HFI_CMD_SESSION_LOAD_RESOURCES 0x211001 - #define HFI_CMD_SESSION_START 0x211002 - #define HFI_CMD_SESSION_STOP 0x211003 -@@ -40,9 +42,32 @@ - #define HFI_FLUSH_OUTPUT 0x1000002 - #define HFI_FLUSH_OUTPUT2 0x1000003 - #define HFI_FLUSH_ALL 0x1000004 -+ -+#define HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL 0x201001 -+#define HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO 0x201002 -+#define HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE 0x201008 -+#define HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL 0x20100c -+ -+#define HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER 0x1200001 -+ -+#define HFI_BUFFER_INPUT 0x1 -+#define HFI_BUFFER_OUTPUT 0x2 -+#define HFI_BUFFER_OUTPUT2 0x3 -+ - #define HFI_PROPERTY_SYS_CODEC_POWER_PLANE_CTRL 0x5 - #define HFI_PROPERTY_SYS_IMAGE_VERSION 0x6 - -+#define HFI_PROPERTY_PARAM_FRAME_SIZE 0x1001 -+#define HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT 0x1003 -+#define HFI_PROPERTY_PARAM_WORK_MODE 0x1015 -+#define HFI_PROPERTY_PARAM_WORK_ROUTE 0x1017 -+#define HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE 0x2002 -+ -+#define HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM 0x1003001 -+#define HFI_CORE_ID_1 1 -+#define HFI_COLOR_FORMAT_NV12 0x02 -+#define HFI_COLOR_FORMAT_NV12_UBWC 0x8002 -+ - #define HFI_MSG_SYS_INIT 0x20001 - #define HFI_MSG_SYS_SESSION_INIT 0x20006 - #define HFI_MSG_SYS_SESSION_END 0x20007 -@@ -93,6 +118,12 @@ struct hfi_sys_get_property_pkt { - u32 data; - }; - -+struct hfi_session_set_property_pkt { -+ struct hfi_session_hdr_pkt shdr; -+ u32 num_properties; -+ u32 data[]; -+}; -+ - struct hfi_sys_pc_prep_pkt { - struct hfi_pkt_hdr hdr; - }; -@@ -144,6 +175,58 @@ struct hfi_enable { - u32 enable; - }; - -+struct hfi_framesize { -+ u32 buffer_type; -+ u32 width; -+ u32 height; -+}; -+ -+struct hfi_videocores_usage_type { -+ u32 video_core_enable_mask; -+}; -+ -+struct hfi_video_work_mode { -+ u32 video_work_mode; -+}; -+ -+struct hfi_video_work_route { -+ u32 video_work_route; -+}; -+ -+struct hfi_uncompressed_format_select { -+ u32 buffer_type; -+ u32 format; -+}; -+ -+struct hfi_uncompressed_plane_constraints { -+ u32 stride_multiples; -+ u32 max_stride; -+ u32 min_plane_buffer_height_multiple; -+ u32 buffer_alignment; -+}; -+ -+struct hfi_uncompressed_plane_actual_constraints_info { -+ u32 buffer_type; -+ u32 num_planes; -+ struct hfi_uncompressed_plane_constraints plane_format[2]; -+}; -+ -+struct hfi_buffer_count_actual { -+ u32 type; -+ u32 count_actual; -+ u32 count_min_host; -+}; -+ -+struct hfi_buffer_size_actual { -+ u32 type; -+ u32 size; -+}; -+ -+struct hfi_multi_stream { -+ u32 buffer_type; -+ u32 enable; -+}; -+ - struct hfi_msg_sys_debug_pkt { - struct hfi_pkt_hdr hdr; - u32 msg_type; -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2.h b/drivers/media/platform/qcom/iris/iris_hfi_gen2.h -index aaf6660bc1fe..676bcb3dc81f 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen2.h -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2.h -@@ -18,10 +18,12 @@ struct iris_core; - * - * @inst: pointer to iris_instance structure - * @packet: HFI packet -+ * @src_subcr_params: subscription params to fw on input port - */ - struct iris_inst_hfi_gen2 { - struct iris_inst inst; - struct iris_hfi_header *packet; -+ struct hfi_subscription_params src_subcr_params; - }; - - void iris_hfi_gen2_command_ops_init(struct iris_core *core); -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c -index b0557917fc52..0845b75aafe9 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c -@@ -3,9 +3,12 @@ - * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. - */ - -+#include -+ - #include "iris_hfi_gen2.h" - #include "iris_hfi_gen2_packet.h" - -+#define UNSPECIFIED_COLOR_FORMAT 5 - #define NUM_SYS_INIT_PACKETS 8 - - #define SYS_INIT_PKT_SIZE (sizeof(struct iris_hfi_header) + \ -@@ -97,6 +100,301 @@ static u32 iris_hfi_gen2_get_port(u32 plane) - } - } - -+static int iris_hfi_gen2_session_set_property(struct iris_inst *inst, u32 packet_type, u32 flag, -+ u32 plane, u32 payload_type, void *payload, -+ u32 payload_size) -+{ -+ struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); -+ -+ iris_hfi_gen2_packet_session_property(inst, -+ packet_type, -+ flag, -+ plane, -+ payload_type, -+ payload, -+ payload_size); -+ -+ return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet, -+ inst_hfi_gen2->packet->size); -+} -+ -+static int iris_hfi_gen2_set_bitstream_resolution(struct iris_inst *inst) -+{ -+ struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); -+ u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); -+ u32 resolution = inst->fmt_src->fmt.pix_mp.width << 16 | -+ inst->fmt_src->fmt.pix_mp.height; -+ -+ inst_hfi_gen2->src_subcr_params.bitstream_resolution = resolution; -+ -+ return iris_hfi_gen2_session_set_property(inst, -+ HFI_PROP_BITSTREAM_RESOLUTION, -+ HFI_HOST_FLAGS_NONE, -+ port, -+ HFI_PAYLOAD_U32, -+ &resolution, -+ sizeof(u32)); -+} -+ -+static int iris_hfi_gen2_set_crop_offsets(struct iris_inst *inst) -+{ -+ u32 bottom_offset = (inst->fmt_src->fmt.pix_mp.height - inst->crop.height); -+ u32 right_offset = (inst->fmt_src->fmt.pix_mp.width - inst->crop.width); -+ struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); -+ u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); -+ u32 left_offset = inst->crop.left; -+ u32 top_offset = inst->crop.top; -+ u32 payload[2]; -+ -+ payload[0] = FIELD_PREP(GENMASK(31, 16), left_offset) | top_offset; -+ payload[1] = FIELD_PREP(GENMASK(31, 16), right_offset) | bottom_offset; -+ inst_hfi_gen2->src_subcr_params.crop_offsets[0] = payload[0]; -+ inst_hfi_gen2->src_subcr_params.crop_offsets[1] = payload[1]; -+ -+ return iris_hfi_gen2_session_set_property(inst, -+ HFI_PROP_CROP_OFFSETS, -+ HFI_HOST_FLAGS_NONE, -+ port, -+ HFI_PAYLOAD_64_PACKED, -+ &payload, -+ sizeof(u64)); -+} -+ -+static int iris_hfi_gen2_set_bit_dpeth(struct iris_inst *inst) -+{ -+ struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); -+ u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); -+ u32 bitdepth = BIT_DEPTH_8; -+ -+ inst_hfi_gen2->src_subcr_params.bit_depth = bitdepth; -+ -+ return iris_hfi_gen2_session_set_property(inst, -+ HFI_PROP_LUMA_CHROMA_BIT_DEPTH, -+ HFI_HOST_FLAGS_NONE, -+ port, -+ HFI_PAYLOAD_U32, -+ &bitdepth, -+ sizeof(u32)); -+} -+ -+static int iris_hfi_gen2_set_coded_frames(struct iris_inst *inst) -+{ -+ struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); -+ u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); -+ u32 coded_frames = 0; -+ -+ if (inst->fw_caps[CODED_FRAMES].value == CODED_FRAMES_PROGRESSIVE) -+ coded_frames = HFI_BITMASK_FRAME_MBS_ONLY_FLAG; -+ inst_hfi_gen2->src_subcr_params.coded_frames = coded_frames; -+ -+ return iris_hfi_gen2_session_set_property(inst, -+ HFI_PROP_CODED_FRAMES, -+ HFI_HOST_FLAGS_NONE, -+ port, -+ HFI_PAYLOAD_U32, -+ &coded_frames, -+ sizeof(u32)); -+} -+ -+static int iris_hfi_gen2_set_min_output_count(struct iris_inst *inst) -+{ -+ struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); -+ u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); -+ u32 min_output = inst->buffers[BUF_OUTPUT].min_count; -+ -+ inst_hfi_gen2->src_subcr_params.fw_min_count = min_output; -+ -+ return iris_hfi_gen2_session_set_property(inst, -+ HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT, -+ HFI_HOST_FLAGS_NONE, -+ port, -+ HFI_PAYLOAD_U32, -+ &min_output, -+ sizeof(u32)); -+} -+ -+static int iris_hfi_gen2_set_picture_order_count(struct iris_inst *inst) -+{ -+ struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); -+ u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); -+ u32 poc = 0; -+ -+ inst_hfi_gen2->src_subcr_params.pic_order_cnt = poc; -+ -+ return iris_hfi_gen2_session_set_property(inst, -+ HFI_PROP_PIC_ORDER_CNT_TYPE, -+ HFI_HOST_FLAGS_NONE, -+ port, -+ HFI_PAYLOAD_U32, -+ &poc, -+ sizeof(u32)); -+} -+ -+static int iris_hfi_gen2_set_colorspace(struct iris_inst *inst) -+{ -+ struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); -+ u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); -+ struct v4l2_pix_format_mplane *pixmp = &inst->fmt_src->fmt.pix_mp; -+ u32 video_signal_type_present_flag = 0, color_info; -+ u32 matrix_coeff = HFI_MATRIX_COEFF_RESERVED; -+ u32 video_format = UNSPECIFIED_COLOR_FORMAT; -+ u32 full_range = V4L2_QUANTIZATION_DEFAULT; -+ u32 transfer_char = HFI_TRANSFER_RESERVED; -+ u32 colour_description_present_flag = 0; -+ u32 primaries = HFI_PRIMARIES_RESERVED; -+ -+ if (pixmp->colorspace != V4L2_COLORSPACE_DEFAULT || -+ pixmp->ycbcr_enc != V4L2_YCBCR_ENC_DEFAULT || -+ pixmp->xfer_func != V4L2_XFER_FUNC_DEFAULT) { -+ colour_description_present_flag = 1; -+ video_signal_type_present_flag = 1; -+ primaries = iris_hfi_gen2_get_color_primaries(pixmp->colorspace); -+ matrix_coeff = iris_hfi_gen2_get_matrix_coefficients(pixmp->ycbcr_enc); -+ transfer_char = iris_hfi_gen2_get_transfer_char(pixmp->xfer_func); -+ } -+ -+ if (pixmp->quantization != V4L2_QUANTIZATION_DEFAULT) { -+ video_signal_type_present_flag = 1; -+ full_range = pixmp->quantization == V4L2_QUANTIZATION_FULL_RANGE ? 1 : 0; -+ } -+ -+ color_info = iris_hfi_gen2_get_color_info(matrix_coeff, transfer_char, primaries, -+ colour_description_present_flag, full_range, -+ video_format, video_signal_type_present_flag); -+ -+ inst_hfi_gen2->src_subcr_params.color_info = color_info; -+ -+ return iris_hfi_gen2_session_set_property(inst, -+ HFI_PROP_SIGNAL_COLOR_INFO, -+ HFI_HOST_FLAGS_NONE, -+ port, -+ HFI_PAYLOAD_32_PACKED, -+ &color_info, -+ sizeof(u32)); -+} -+ -+static int iris_hfi_gen2_set_profile(struct iris_inst *inst) -+{ -+ struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); -+ u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); -+ u32 profile = inst->fw_caps[PROFILE].value; -+ -+ inst_hfi_gen2->src_subcr_params.profile = profile; -+ -+ return iris_hfi_gen2_session_set_property(inst, -+ HFI_PROP_PROFILE, -+ HFI_HOST_FLAGS_NONE, -+ port, -+ HFI_PAYLOAD_U32_ENUM, -+ &profile, -+ sizeof(u32)); -+} -+ -+static int iris_hfi_gen2_set_level(struct iris_inst *inst) -+{ -+ struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); -+ u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); -+ u32 level = inst->fw_caps[LEVEL].value; -+ -+ inst_hfi_gen2->src_subcr_params.level = level; -+ -+ return iris_hfi_gen2_session_set_property(inst, -+ HFI_PROP_LEVEL, -+ HFI_HOST_FLAGS_NONE, -+ port, -+ HFI_PAYLOAD_U32_ENUM, -+ &level, -+ sizeof(u32)); -+} -+ -+static int iris_hfi_gen2_set_colorformat(struct iris_inst *inst) -+{ -+ u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); -+ u32 hfi_colorformat, pixelformat; -+ -+ pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat; -+ hfi_colorformat = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FMT_NV12 : 0; -+ -+ return iris_hfi_gen2_session_set_property(inst, -+ HFI_PROP_COLOR_FORMAT, -+ HFI_HOST_FLAGS_NONE, -+ port, -+ HFI_PAYLOAD_U32, -+ &hfi_colorformat, -+ sizeof(u32)); -+} -+ -+static int iris_hfi_gen2_set_linear_stride_scanline(struct iris_inst *inst) -+{ -+ u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); -+ u32 pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat; -+ u32 scanline_y = inst->fmt_dst->fmt.pix_mp.height; -+ u32 stride_y = inst->fmt_dst->fmt.pix_mp.width; -+ u32 scanline_uv = scanline_y / 2; -+ u32 stride_uv = stride_y; -+ u32 payload[2]; -+ -+ if (pixelformat != V4L2_PIX_FMT_NV12) -+ return 0; -+ -+ payload[0] = stride_y << 16 | scanline_y; -+ payload[1] = stride_uv << 16 | scanline_uv; -+ -+ return iris_hfi_gen2_session_set_property(inst, -+ HFI_PROP_LINEAR_STRIDE_SCANLINE, -+ HFI_HOST_FLAGS_NONE, -+ port, -+ HFI_PAYLOAD_U64, -+ &payload, -+ sizeof(u64)); -+} -+ -+static int iris_hfi_gen2_session_set_config_params(struct iris_inst *inst, u32 plane) -+{ -+ struct iris_core *core = inst->core; -+ u32 config_params_size, i, j; -+ const u32 *config_params; -+ int ret; -+ -+ static const struct iris_hfi_prop_type_handle prop_type_handle_arr[] = { -+ {HFI_PROP_BITSTREAM_RESOLUTION, iris_hfi_gen2_set_bitstream_resolution }, -+ {HFI_PROP_CROP_OFFSETS, iris_hfi_gen2_set_crop_offsets }, -+ {HFI_PROP_CODED_FRAMES, iris_hfi_gen2_set_coded_frames }, -+ {HFI_PROP_LUMA_CHROMA_BIT_DEPTH, iris_hfi_gen2_set_bit_dpeth }, -+ {HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT, iris_hfi_gen2_set_min_output_count }, -+ {HFI_PROP_PIC_ORDER_CNT_TYPE, iris_hfi_gen2_set_picture_order_count }, -+ {HFI_PROP_SIGNAL_COLOR_INFO, iris_hfi_gen2_set_colorspace }, -+ {HFI_PROP_PROFILE, iris_hfi_gen2_set_profile }, -+ {HFI_PROP_LEVEL, iris_hfi_gen2_set_level }, -+ {HFI_PROP_COLOR_FORMAT, iris_hfi_gen2_set_colorformat }, -+ {HFI_PROP_LINEAR_STRIDE_SCANLINE, iris_hfi_gen2_set_linear_stride_scanline }, -+ }; -+ -+ if (V4L2_TYPE_IS_OUTPUT(plane)) { -+ config_params = core->iris_platform_data->input_config_params; -+ config_params_size = core->iris_platform_data->input_config_params_size; -+ } else { -+ config_params = core->iris_platform_data->output_config_params; -+ config_params_size = core->iris_platform_data->output_config_params_size; -+ } -+ -+ if (!config_params || !config_params_size) -+ return -EINVAL; -+ -+ for (i = 0; i < config_params_size; i++) { -+ for (j = 0; j < ARRAY_SIZE(prop_type_handle_arr); j++) { -+ if (prop_type_handle_arr[j].type == config_params[i]) { -+ ret = prop_type_handle_arr[j].handle(inst); -+ if (ret) -+ return ret; -+ break; -+ } -+ } -+ } -+ -+ return 0; -+} -+ - static int iris_hfi_gen2_session_set_codec(struct iris_inst *inst) - { - struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); -@@ -253,6 +551,8 @@ static const struct iris_hfi_command_ops iris_hfi_gen2_command_ops = { - .sys_interframe_powercollapse = iris_hfi_gen2_sys_interframe_powercollapse, - .sys_pc_prep = iris_hfi_gen2_sys_pc_prep, - .session_open = iris_hfi_gen2_session_open, -+ .session_set_config_params = iris_hfi_gen2_session_set_config_params, -+ .session_set_property = iris_hfi_gen2_session_set_property, - .session_start = iris_hfi_gen2_session_start, - .session_stop = iris_hfi_gen2_session_stop, - .session_close = iris_hfi_gen2_session_close, -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h -index 930dbae49dfa..4c9604b05034 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h -@@ -19,6 +19,8 @@ - #define HFI_CMD_STOP 0x01000006 - #define HFI_CMD_END 0x01FFFFFF - -+#define HFI_BITMASK_FRAME_MBS_ONLY_FLAG 0x00000001 -+ - #define HFI_PROP_BEGIN 0x03000000 - #define HFI_PROP_IMAGE_VERSION 0x03000001 - #define HFI_PROP_INTRA_FRAME_POWER_COLLAPSE 0x03000002 -@@ -30,9 +32,23 @@ - #define HFI_PROP_UBWC_BANK_SWZL_LEVEL3 0x03000008 - #define HFI_PROP_UBWC_BANK_SPREADING 0x03000009 - #define HFI_PROP_CODEC 0x03000100 -+#define HFI_PROP_COLOR_FORMAT 0x03000101 -+#define HFI_PROP_BITSTREAM_RESOLUTION 0x03000103 -+#define HFI_PROP_LINEAR_STRIDE_SCANLINE 0x03000104 -+#define HFI_PROP_CROP_OFFSETS 0x03000105 - #define HFI_PROP_PROFILE 0x03000107 - #define HFI_PROP_LEVEL 0x03000108 -+#define HFI_PROP_STAGE 0x0300010a -+#define HFI_PROP_PIPE 0x0300010b -+#define HFI_PROP_LUMA_CHROMA_BIT_DEPTH 0x0300010f -+#define HFI_PROP_CODED_FRAMES 0x03000120 -+#define HFI_PROP_BUFFER_HOST_MAX_COUNT 0x03000123 -+#define HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT 0x03000124 -+#define HFI_PROP_PIC_ORDER_CNT_TYPE 0x03000128 -+#define HFI_PROP_QUALITY_MODE 0x03000148 -+#define HFI_PROP_SIGNAL_COLOR_INFO 0x03000155 - #define HFI_PROP_DEC_DEFAULT_HEADER 0x03000168 -+#define HFI_PROP_DEC_START_FROM_RAP_FRAME 0x03000169 - #define HFI_PROP_END 0x03FFFFFF - - #define HFI_SESSION_ERROR_BEGIN 0x04000000 -@@ -49,6 +65,17 @@ - #define HFI_SYS_ERROR_WD_TIMEOUT 0x05000001 - #define HFI_SYSTEM_ERROR_END 0x05FFFFFF - -+enum hfi_color_format { -+ HFI_COLOR_FMT_OPAQUE = 0, -+ HFI_COLOR_FMT_NV12 = 1, -+ HFI_COLOR_FMT_NV12_UBWC = 2, -+ HFI_COLOR_FMT_P010 = 3, -+ HFI_COLOR_FMT_TP10_UBWC = 4, -+ HFI_COLOR_FMT_RGBA8888 = 5, -+ HFI_COLOR_FMT_RGBA8888_UBWC = 6, -+ HFI_COLOR_FMT_NV21 = 7, -+}; -+ - enum hfi_codec_type { - HFI_CODEC_DECODE_AVC = 1, - HFI_CODEC_ENCODE_AVC = 2, -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.c -index 739b2ce5bfae..d77fa29f44fc 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.c -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.c -@@ -7,6 +7,85 @@ - #include "iris_hfi_gen2.h" - #include "iris_hfi_gen2_packet.h" - -+u32 iris_hfi_gen2_get_color_primaries(u32 primaries) -+{ -+ switch (primaries) { -+ case V4L2_COLORSPACE_DEFAULT: -+ return HFI_PRIMARIES_RESERVED; -+ case V4L2_COLORSPACE_REC709: -+ return HFI_PRIMARIES_BT709; -+ case V4L2_COLORSPACE_470_SYSTEM_M: -+ return HFI_PRIMARIES_BT470_SYSTEM_M; -+ case V4L2_COLORSPACE_470_SYSTEM_BG: -+ return HFI_PRIMARIES_BT470_SYSTEM_BG; -+ case V4L2_COLORSPACE_SMPTE170M: -+ return HFI_PRIMARIES_BT601_525; -+ case V4L2_COLORSPACE_SMPTE240M: -+ return HFI_PRIMARIES_SMPTE_ST240M; -+ case V4L2_COLORSPACE_BT2020: -+ return HFI_PRIMARIES_BT2020; -+ case V4L2_COLORSPACE_DCI_P3: -+ return HFI_PRIMARIES_SMPTE_RP431_2; -+ default: -+ return HFI_PRIMARIES_RESERVED; -+ } -+} -+ -+u32 iris_hfi_gen2_get_transfer_char(u32 characterstics) -+{ -+ switch (characterstics) { -+ case V4L2_XFER_FUNC_DEFAULT: -+ return HFI_TRANSFER_RESERVED; -+ case V4L2_XFER_FUNC_709: -+ return HFI_TRANSFER_BT709; -+ case V4L2_XFER_FUNC_SMPTE240M: -+ return HFI_TRANSFER_SMPTE_ST240M; -+ case V4L2_XFER_FUNC_SRGB: -+ return HFI_TRANSFER_SRGB_SYCC; -+ case V4L2_XFER_FUNC_SMPTE2084: -+ return HFI_TRANSFER_SMPTE_ST2084_PQ; -+ default: -+ return HFI_TRANSFER_RESERVED; -+ } -+} -+ -+u32 iris_hfi_gen2_get_matrix_coefficients(u32 coefficients) -+{ -+ switch (coefficients) { -+ case V4L2_YCBCR_ENC_DEFAULT: -+ return HFI_MATRIX_COEFF_RESERVED; -+ case V4L2_YCBCR_ENC_709: -+ return HFI_MATRIX_COEFF_BT709; -+ case V4L2_YCBCR_ENC_XV709: -+ return HFI_MATRIX_COEFF_BT709; -+ case V4L2_YCBCR_ENC_XV601: -+ return HFI_MATRIX_COEFF_BT470_SYS_BG_OR_BT601_625; -+ case V4L2_YCBCR_ENC_601: -+ return HFI_MATRIX_COEFF_BT601_525_BT1358_525_OR_625; -+ case V4L2_YCBCR_ENC_SMPTE240M: -+ return HFI_MATRIX_COEFF_SMPTE_ST240; -+ case V4L2_YCBCR_ENC_BT2020: -+ return HFI_MATRIX_COEFF_BT2020_NON_CONSTANT; -+ case V4L2_YCBCR_ENC_BT2020_CONST_LUM: -+ return HFI_MATRIX_COEFF_BT2020_CONSTANT; -+ default: -+ return HFI_MATRIX_COEFF_RESERVED; -+ } -+} -+ -+u32 iris_hfi_gen2_get_color_info(u32 matrix_coeff, u32 transfer_char, u32 primaries, -+ u32 colour_description_present_flag, u32 full_range, -+ u32 video_format, u32 video_signal_type_present_flag) -+{ -+ return (matrix_coeff & 0xFF) | -+ ((transfer_char << 8) & 0xFF00) | -+ ((primaries << 16) & 0xFF0000) | -+ ((colour_description_present_flag << 24) & 0x1000000) | -+ ((full_range << 25) & 0x2000000) | -+ ((video_format << 26) & 0x1C000000) | -+ ((video_signal_type_present_flag << 29) & 0x20000000); -+} -+ - static void iris_hfi_gen2_create_header(struct iris_hfi_header *hdr, - u32 session_id, u32 header_id) - { -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.h b/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.h -index 4a9b88185b0d..0333e37572f6 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.h -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.h -@@ -61,6 +61,13 @@ struct iris_hfi_packet { - u32 payload[]; - }; - -+u32 iris_hfi_gen2_get_color_primaries(u32 primaries); -+u32 iris_hfi_gen2_get_transfer_char(u32 characterstics); -+u32 iris_hfi_gen2_get_matrix_coefficients(u32 coefficients); -+u32 iris_hfi_gen2_get_color_info(u32 matrix_coeff, u32 transfer_char, u32 primaries, -+ u32 colour_description_present_flag, u32 full_range, -+ u32 video_format, u32 video_signal_type_present_flag); -+ - void iris_hfi_gen2_packet_sys_init(struct iris_core *core, struct iris_hfi_header *hdr); - void iris_hfi_gen2_packet_image_version(struct iris_core *core, struct iris_hfi_header *hdr); - void iris_hfi_gen2_packet_session_command(struct iris_inst *inst, u32 pkt_type, -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c -index 53b700ef852e..336b43740b72 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c -@@ -166,6 +166,53 @@ static int iris_hfi_gen2_handle_session_command(struct iris_inst *inst, - return 0; - } - -+static int iris_hfi_gen2_handle_session_property(struct iris_inst *inst, -+ struct iris_hfi_packet *pkt) -+{ -+ struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); -+ -+ if (pkt->port != HFI_PORT_BITSTREAM) -+ return 0; -+ -+ if (pkt->flags & HFI_FW_FLAGS_INFORMATION) -+ return 0; -+ -+ switch (pkt->type) { -+ case HFI_PROP_BITSTREAM_RESOLUTION: -+ inst_hfi_gen2->src_subcr_params.bitstream_resolution = pkt->payload[0]; -+ break; -+ case HFI_PROP_CROP_OFFSETS: -+ inst_hfi_gen2->src_subcr_params.crop_offsets[0] = pkt->payload[0]; -+ inst_hfi_gen2->src_subcr_params.crop_offsets[1] = pkt->payload[1]; -+ break; -+ case HFI_PROP_CODED_FRAMES: -+ inst_hfi_gen2->src_subcr_params.coded_frames = pkt->payload[0]; -+ break; -+ case HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT: -+ inst_hfi_gen2->src_subcr_params.fw_min_count = pkt->payload[0]; -+ break; -+ case HFI_PROP_PIC_ORDER_CNT_TYPE: -+ inst_hfi_gen2->src_subcr_params.pic_order_cnt = pkt->payload[0]; -+ break; -+ case HFI_PROP_SIGNAL_COLOR_INFO: -+ inst_hfi_gen2->src_subcr_params.color_info = pkt->payload[0]; -+ break; -+ case HFI_PROP_PROFILE: -+ inst_hfi_gen2->src_subcr_params.profile = pkt->payload[0]; -+ break; -+ case HFI_PROP_LEVEL: -+ inst_hfi_gen2->src_subcr_params.level = pkt->payload[0]; -+ break; -+ case HFI_PROP_QUALITY_MODE: -+ case HFI_PROP_STAGE: -+ case HFI_PROP_PIPE: -+ default: -+ break; -+ } -+ -+ return 0; -+} -+ - static int iris_hfi_gen2_handle_image_version_property(struct iris_core *core, - struct iris_hfi_packet *pkt) - { -@@ -250,6 +297,8 @@ static int iris_hfi_gen2_handle_session_response(struct iris_core *core, - static const struct iris_hfi_gen2_inst_hfi_range range[] = { - {HFI_SESSION_ERROR_BEGIN, HFI_SESSION_ERROR_END, - iris_hfi_gen2_handle_session_error}, -+ {HFI_PROP_BEGIN, HFI_PROP_END, -+ iris_hfi_gen2_handle_session_property}, - {HFI_CMD_BEGIN, HFI_CMD_END, - iris_hfi_gen2_handle_session_command }, - }; -diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h -index 23170cd37c04..5643fb55b09e 100644 ---- a/drivers/media/platform/qcom/iris/iris_platform_common.h -+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h -@@ -6,12 +6,31 @@ - #ifndef __IRIS_PLATFORM_COMMON_H__ - #define __IRIS_PLATFORM_COMMON_H__ - -+#include -+ - struct iris_core; -+struct iris_inst; - - #define IRIS_PAS_ID 9 - #define HW_RESPONSE_TIMEOUT_VALUE (1000) /* milliseconds */ - #define AUTOSUSPEND_DELAY_VALUE (HW_RESPONSE_TIMEOUT_VALUE + 500) /* milliseconds */ - -+#define REGISTER_BIT_DEPTH(luma, chroma) ((luma) << 16 | (chroma)) -+#define BIT_DEPTH_8 REGISTER_BIT_DEPTH(8, 8) -+#define CODED_FRAMES_PROGRESSIVE 0x0 -+#define DEFAULT_MAX_HOST_BUF_COUNT 64 -+#define DEFAULT_MAX_HOST_BURST_BUF_COUNT 256 -+enum stage_type { -+ STAGE_1 = 1, -+ STAGE_2 = 2, -+}; -+ -+enum pipe_type { -+ PIPE_1 = 1, -+ PIPE_2 = 2, -+ PIPE_4 = 4, -+}; -+ - extern struct iris_platform_data sm8550_data; - - enum platform_clk_type { -@@ -53,6 +72,13 @@ struct platform_inst_caps { - enum platform_inst_fw_cap_type { - PROFILE = 1, - LEVEL, -+ INPUT_BUF_HOST_MAX_COUNT, -+ STAGE, -+ PIPE, -+ POC, -+ CODED_FRAMES, -+ BIT_DEPTH, -+ RAP_FRAME, - DEBLOCK, - INST_FW_CAP_MAX, - }; -@@ -75,6 +101,8 @@ struct platform_inst_fw_cap { - s64 value; - u32 hfi_id; - enum platform_inst_fw_cap_flags flags; -+ int (*set)(struct iris_inst *inst, -+ enum platform_inst_fw_cap_type cap_id); - }; - - struct iris_core_power { -@@ -115,6 +143,10 @@ struct iris_platform_data { - struct ubwc_config_data *ubwc_config; - u32 num_vpp_pipe; - u32 max_session_count; -+ const u32 *input_config_params; -+ unsigned int input_config_params_size; -+ const u32 *output_config_params; -+ unsigned int output_config_params_size; - }; - - #endif -diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c -index 58b1d1d43731..8a55c1f731c0 100644 ---- a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c -+++ b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c -@@ -4,6 +4,7 @@ - */ - - #include "iris_core.h" -+#include "iris_ctrls.h" - #include "iris_hfi_gen2.h" - #include "iris_hfi_gen2_defines.h" - #include "iris_platform_common.h" -@@ -24,6 +25,7 @@ static struct platform_inst_fw_cap inst_fw_cap_sm8550[] = { - .value = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH, - .hfi_id = HFI_PROP_PROFILE, - .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, -+ .set = iris_set_u32_enum, - }, - { - .cap_id = LEVEL, -@@ -52,6 +54,69 @@ static struct platform_inst_fw_cap inst_fw_cap_sm8550[] = { - .value = V4L2_MPEG_VIDEO_H264_LEVEL_6_1, - .hfi_id = HFI_PROP_LEVEL, - .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, -+ .set = iris_set_u32_enum, -+ }, -+ { -+ .cap_id = INPUT_BUF_HOST_MAX_COUNT, -+ .min = DEFAULT_MAX_HOST_BUF_COUNT, -+ .max = DEFAULT_MAX_HOST_BURST_BUF_COUNT, -+ .step_or_mask = 1, -+ .value = DEFAULT_MAX_HOST_BUF_COUNT, -+ .hfi_id = HFI_PROP_BUFFER_HOST_MAX_COUNT, -+ .flags = CAP_FLAG_INPUT_PORT, -+ .set = iris_set_u32, -+ }, -+ { -+ .cap_id = STAGE, -+ .min = STAGE_1, -+ .max = STAGE_2, -+ .step_or_mask = 1, -+ .value = STAGE_2, -+ .hfi_id = HFI_PROP_STAGE, -+ .set = iris_set_stage, -+ }, -+ { -+ .cap_id = PIPE, -+ .min = PIPE_1, -+ .max = PIPE_4, -+ .step_or_mask = 1, -+ .value = PIPE_4, -+ .hfi_id = HFI_PROP_PIPE, -+ .set = iris_set_pipe, -+ }, -+ { -+ .cap_id = POC, -+ .min = 0, -+ .max = 2, -+ .step_or_mask = 1, -+ .value = 1, -+ .hfi_id = HFI_PROP_PIC_ORDER_CNT_TYPE, -+ }, -+ { -+ .cap_id = CODED_FRAMES, -+ .min = CODED_FRAMES_PROGRESSIVE, -+ .max = CODED_FRAMES_PROGRESSIVE, -+ .step_or_mask = 0, -+ .value = CODED_FRAMES_PROGRESSIVE, -+ .hfi_id = HFI_PROP_CODED_FRAMES, -+ }, -+ { -+ .cap_id = BIT_DEPTH, -+ .min = BIT_DEPTH_8, -+ .max = BIT_DEPTH_8, -+ .step_or_mask = 1, -+ .value = BIT_DEPTH_8, -+ .hfi_id = HFI_PROP_LUMA_CHROMA_BIT_DEPTH, -+ }, -+ { -+ .cap_id = RAP_FRAME, -+ .min = 0, -+ .max = 1, -+ .step_or_mask = 1, -+ .value = 1, -+ .hfi_id = HFI_PROP_DEC_START_FROM_RAP_FRAME, -+ .flags = CAP_FLAG_INPUT_PORT, -+ .set = iris_set_u32, - }, - }; - -@@ -102,6 +167,22 @@ static struct tz_cp_config tz_cp_config_sm8550 = { - .cp_nonpixel_size = 0x24800000, - }; - -+static const u32 sm8550_vdec_input_config_params[] = { -+ HFI_PROP_BITSTREAM_RESOLUTION, -+ HFI_PROP_CROP_OFFSETS, -+ HFI_PROP_CODED_FRAMES, -+ HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT, -+ HFI_PROP_PIC_ORDER_CNT_TYPE, -+ HFI_PROP_PROFILE, -+ HFI_PROP_LEVEL, -+ HFI_PROP_SIGNAL_COLOR_INFO, -+}; -+ -+static const u32 sm8550_vdec_output_config_params[] = { -+ HFI_PROP_COLOR_FORMAT, -+ HFI_PROP_LINEAR_STRIDE_SCANLINE, -+}; -+ - struct iris_platform_data sm8550_data = { - .get_instance = iris_hfi_gen2_get_instance, - .init_hfi_command_ops = iris_hfi_gen2_command_ops_init, -@@ -131,4 +212,12 @@ struct iris_platform_data sm8550_data = { - .ubwc_config = &ubwc_config_sm8550, - .num_vpp_pipe = 4, - .max_session_count = 16, -+ .input_config_params = -+ sm8550_vdec_input_config_params, -+ .input_config_params_size = -+ ARRAY_SIZE(sm8550_vdec_input_config_params), -+ .output_config_params = -+ sm8550_vdec_output_config_params, -+ .output_config_params_size = -+ ARRAY_SIZE(sm8550_vdec_output_config_params), - }; -diff --git a/drivers/media/platform/qcom/iris/iris_utils.c b/drivers/media/platform/qcom/iris/iris_utils.c -index 4833830f30d5..8bcfa97db97d 100644 ---- a/drivers/media/platform/qcom/iris/iris_utils.c -+++ b/drivers/media/platform/qcom/iris/iris_utils.c -@@ -8,6 +8,20 @@ - #include "iris_instance.h" - #include "iris_utils.h" - -+bool iris_res_is_less_than(u32 width, u32 height, -+ u32 ref_width, u32 ref_height) -+{ -+ u32 num_mbs = NUM_MBS_PER_FRAME(height, width); -+ u32 max_side = max(ref_width, ref_height); -+ -+ if (num_mbs < NUM_MBS_PER_FRAME(ref_height, ref_width) && -+ width < max_side && -+ height < max_side) -+ return true; -+ -+ return false; -+} -+ - int iris_get_mbpf(struct iris_inst *inst) - { - struct v4l2_format *inp_f = inst->fmt_src; -@@ -17,6 +31,11 @@ int iris_get_mbpf(struct iris_inst *inst) - return NUM_MBS_PER_FRAME(height, width); - } - -+bool iris_split_mode_enabled(struct iris_inst *inst) -+{ -+ return inst->fmt_dst->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_NV12; -+} -+ - int iris_wait_for_session_response(struct iris_inst *inst, bool is_flush) - { - struct iris_core *core = inst->core; -diff --git a/drivers/media/platform/qcom/iris/iris_utils.h b/drivers/media/platform/qcom/iris/iris_utils.h -index 40658a6643cf..3400847f5e72 100644 ---- a/drivers/media/platform/qcom/iris/iris_utils.h -+++ b/drivers/media/platform/qcom/iris/iris_utils.h -@@ -27,7 +27,10 @@ static inline enum iris_buffer_type iris_v4l2_type_to_driver(u32 type) - return BUF_OUTPUT; - } - -+bool iris_res_is_less_than(u32 width, u32 height, -+ u32 ref_width, u32 ref_height); - int iris_get_mbpf(struct iris_inst *inst); -+bool iris_split_mode_enabled(struct iris_inst *inst); - struct iris_inst *iris_get_instance(struct iris_core *core, u32 session_id); - int iris_wait_for_session_response(struct iris_inst *inst, bool is_flush); - -diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c b/drivers/media/platform/qcom/iris/iris_vdec.c -index 92651d86376d..13902f4e9724 100644 ---- a/drivers/media/platform/qcom/iris/iris_vdec.c -+++ b/drivers/media/platform/qcom/iris/iris_vdec.c -@@ -267,6 +267,12 @@ static int iris_vdec_process_streamon_input(struct iris_inst *inst) - - int iris_vdec_streamon_input(struct iris_inst *inst) - { -+ int ret; -+ -+ ret = iris_set_properties(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); -+ if (ret) -+ return ret; -+ - return iris_vdec_process_streamon_input(inst); - } - -@@ -284,8 +290,13 @@ static int iris_vdec_process_streamon_output(struct iris_inst *inst) - - int iris_vdec_streamon_output(struct iris_inst *inst) - { -+ const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; - int ret; - -+ ret = hfi_ops->session_set_config_params(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); -+ if (ret) -+ return ret; -+ - ret = iris_vdec_process_streamon_output(inst); - if (ret) - goto error; -diff --git a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c b/drivers/media/platform/qcom/iris/iris_vpu_buffer.c -index 2402a33723ab..0a65a17f13d2 100644 ---- a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c -+++ b/drivers/media/platform/qcom/iris/iris_vpu_buffer.c -@@ -6,6 +6,24 @@ - #include "iris_instance.h" - #include "iris_vpu_buffer.h" - -+u32 iris_vpu_dec_dpb_size(struct iris_inst *inst) -+{ -+ if (iris_split_mode_enabled(inst)) -+ return iris_get_buffer_size(inst, BUF_DPB); -+ else -+ return 0; -+} -+ -+static inline int iris_vpu_dpb_count(struct iris_inst *inst) -+{ -+ if (iris_split_mode_enabled(inst)) { -+ return inst->fw_min_count ? -+ inst->fw_min_count : inst->buffers[BUF_OUTPUT].min_count; -+ } -+ -+ return 0; -+} -+ - int iris_vpu_buf_count(struct iris_inst *inst, enum iris_buffer_type buffer_type) - { - switch (buffer_type) { -@@ -13,6 +31,8 @@ int iris_vpu_buf_count(struct iris_inst *inst, enum iris_buffer_type buffer_type - return MIN_BUFFERS; - case BUF_OUTPUT: - return inst->fw_min_count; -+ case BUF_DPB: -+ return iris_vpu_dpb_count(inst); - default: - return 0; - } -diff --git a/drivers/media/platform/qcom/iris/iris_vpu_buffer.h b/drivers/media/platform/qcom/iris/iris_vpu_buffer.h -index 06e6e958dcac..865539d626b7 100644 ---- a/drivers/media/platform/qcom/iris/iris_vpu_buffer.h -+++ b/drivers/media/platform/qcom/iris/iris_vpu_buffer.h -@@ -10,6 +10,7 @@ struct iris_inst; - - #define MIN_BUFFERS 4 - -+u32 iris_vpu_dec_dpb_size(struct iris_inst *inst); - int iris_vpu_buf_count(struct iris_inst *inst, enum iris_buffer_type buffer_type); - - #endif --- -2.34.1 - diff --git a/patch/kernel/archive/sm8550-6.12/0018_media--iris--subscribe-parameters-and-properties-t.patch b/patch/kernel/archive/sm8550-6.12/0018_media--iris--subscribe-parameters-and-properties-t.patch deleted file mode 100644 index 2708a3515de4..000000000000 --- a/patch/kernel/archive/sm8550-6.12/0018_media--iris--subscribe-parameters-and-properties-t.patch +++ /dev/null @@ -1,331 +0,0 @@ -From fdf8534d663da51ca7377eaea621c2470d7f6e01 Mon Sep 17 00:00:00 2001 -From: Vedang Nagar -Date: Fri, 7 Feb 2025 13:24:58 +0530 -Subject: [PATCH] media: iris: subscribe parameters and properties to firmware - for hfi_gen2 - -For hfi_gen2, subscribe different bitstream parameters on to firmware, -to get notified of a change in any of the subscribed parameters. - -Signed-off-by: Vedang Nagar -Tested-by: Stefan Schmidt # x1e80100 (Dell XPS 13 9345) -Reviewed-by: Stefan Schmidt -Tested-by: Neil Armstrong # on SM8550-QRD -Tested-by: Neil Armstrong # on SM8550-HDK -Signed-off-by: Dikshita Agarwal -Link: https://lore.kernel.org/r/20250207-qcom-video-iris-v10-18-ab66eeffbd20@quicinc.com -Signed-off-by: Neil Armstrong ---- - .../media/platform/qcom/iris/iris_hfi_gen2.h | 6 + - .../qcom/iris/iris_hfi_gen2_command.c | 174 ++++++++++++++++++ - .../qcom/iris/iris_hfi_gen2_defines.h | 9 + - .../platform/qcom/iris/iris_platform_common.h | 4 + - .../platform/qcom/iris/iris_platform_sm8550.c | 13 ++ - 5 files changed, 206 insertions(+) - -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2.h b/drivers/media/platform/qcom/iris/iris_hfi_gen2.h -index 676bcb3dc81f..0a946c1e3a4c 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen2.h -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2.h -@@ -18,12 +18,18 @@ struct iris_core; - * - * @inst: pointer to iris_instance structure - * @packet: HFI packet -+ * @ipsc_properties_set: boolean to set ipsc properties to fw -+ * @opsc_properties_set: boolean to set opsc properties to fw - * @src_subcr_params: subscription params to fw on input port -+ * @dst_subcr_params: subscription params to fw on output port - */ - struct iris_inst_hfi_gen2 { - struct iris_inst inst; - struct iris_hfi_header *packet; -+ bool ipsc_properties_set; -+ bool opsc_properties_set; - struct hfi_subscription_params src_subcr_params; -+ struct hfi_subscription_params dst_subcr_params; - }; - - void iris_hfi_gen2_command_ops_init(struct iris_core *core); -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c -index 0845b75aafe9..dddaa074cae1 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c -@@ -437,6 +437,9 @@ static int iris_hfi_gen2_session_open(struct iris_inst *inst) - if (inst->state != IRIS_INST_DEINIT) - return -EALREADY; - -+ inst_hfi_gen2->ipsc_properties_set = false; -+ inst_hfi_gen2->opsc_properties_set = false; -+ - inst_hfi_gen2->packet = kzalloc(4096, GFP_KERNEL); - if (!inst_hfi_gen2->packet) - return -ENOMEM; -@@ -501,9 +504,180 @@ static int iris_hfi_gen2_session_close(struct iris_inst *inst) - return ret; - } - -+static int iris_hfi_gen2_session_subscribe_mode(struct iris_inst *inst, -+ u32 cmd, u32 plane, u32 payload_type, -+ void *payload, u32 payload_size) -+{ -+ struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); -+ -+ iris_hfi_gen2_packet_session_command(inst, -+ cmd, -+ (HFI_HOST_FLAGS_RESPONSE_REQUIRED | -+ HFI_HOST_FLAGS_INTR_REQUIRED), -+ iris_hfi_gen2_get_port(plane), -+ inst->session_id, -+ payload_type, -+ payload, -+ payload_size); -+ -+ return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet, -+ inst_hfi_gen2->packet->size); -+} -+ -+static int iris_hfi_gen2_subscribe_change_param(struct iris_inst *inst, u32 plane) -+{ -+ struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); -+ struct hfi_subscription_params subsc_params; -+ u32 prop_type, payload_size, payload_type; -+ struct iris_core *core = inst->core; -+ const u32 *change_param; -+ u32 change_param_size; -+ u32 payload[32] = {0}; -+ u32 hfi_port = 0, i; -+ int ret; -+ -+ if ((V4L2_TYPE_IS_OUTPUT(plane) && inst_hfi_gen2->ipsc_properties_set) || -+ (V4L2_TYPE_IS_CAPTURE(plane) && inst_hfi_gen2->opsc_properties_set)) { -+ dev_err(core->dev, "invalid plane\n"); -+ return 0; -+ } -+ -+ change_param = core->iris_platform_data->input_config_params; -+ change_param_size = core->iris_platform_data->input_config_params_size; -+ -+ payload[0] = HFI_MODE_PORT_SETTINGS_CHANGE; -+ -+ for (i = 0; i < change_param_size; i++) -+ payload[i + 1] = change_param[i]; -+ -+ ret = iris_hfi_gen2_session_subscribe_mode(inst, -+ HFI_CMD_SUBSCRIBE_MODE, -+ plane, -+ HFI_PAYLOAD_U32_ARRAY, -+ &payload[0], -+ ((change_param_size + 1) * sizeof(u32))); -+ if (ret) -+ return ret; -+ -+ if (V4L2_TYPE_IS_OUTPUT(plane)) { -+ inst_hfi_gen2->ipsc_properties_set = true; -+ } else { -+ hfi_port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); -+ memcpy(&inst_hfi_gen2->dst_subcr_params, -+ &inst_hfi_gen2->src_subcr_params, -+ sizeof(inst_hfi_gen2->src_subcr_params)); -+ subsc_params = inst_hfi_gen2->dst_subcr_params; -+ for (i = 0; i < change_param_size; i++) { -+ payload[0] = 0; -+ payload[1] = 0; -+ payload_size = 0; -+ payload_type = 0; -+ prop_type = change_param[i]; -+ switch (prop_type) { -+ case HFI_PROP_BITSTREAM_RESOLUTION: -+ payload[0] = subsc_params.bitstream_resolution; -+ payload_size = sizeof(u32); -+ payload_type = HFI_PAYLOAD_U32; -+ break; -+ case HFI_PROP_CROP_OFFSETS: -+ payload[0] = subsc_params.crop_offsets[0]; -+ payload[1] = subsc_params.crop_offsets[1]; -+ payload_size = sizeof(u64); -+ payload_type = HFI_PAYLOAD_64_PACKED; -+ break; -+ case HFI_PROP_CODED_FRAMES: -+ payload[0] = subsc_params.coded_frames; -+ payload_size = sizeof(u32); -+ payload_type = HFI_PAYLOAD_U32; -+ break; -+ case HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT: -+ payload[0] = subsc_params.fw_min_count; -+ payload_size = sizeof(u32); -+ payload_type = HFI_PAYLOAD_U32; -+ break; -+ case HFI_PROP_PIC_ORDER_CNT_TYPE: -+ payload[0] = subsc_params.pic_order_cnt; -+ payload_size = sizeof(u32); -+ payload_type = HFI_PAYLOAD_U32; -+ break; -+ case HFI_PROP_SIGNAL_COLOR_INFO: -+ payload[0] = subsc_params.color_info; -+ payload_size = sizeof(u32); -+ payload_type = HFI_PAYLOAD_U32; -+ break; -+ case HFI_PROP_PROFILE: -+ payload[0] = subsc_params.profile; -+ payload_size = sizeof(u32); -+ payload_type = HFI_PAYLOAD_U32; -+ break; -+ case HFI_PROP_LEVEL: -+ payload[0] = subsc_params.level; -+ payload_size = sizeof(u32); -+ payload_type = HFI_PAYLOAD_U32; -+ break; -+ default: -+ prop_type = 0; -+ ret = -EINVAL; -+ break; -+ } -+ if (prop_type) { -+ ret = iris_hfi_gen2_session_set_property(inst, -+ prop_type, -+ HFI_HOST_FLAGS_NONE, -+ hfi_port, -+ payload_type, -+ &payload, -+ payload_size); -+ if (ret) -+ return ret; -+ } -+ } -+ inst_hfi_gen2->opsc_properties_set = true; -+ } -+ -+ return 0; -+} -+ -+static int iris_hfi_gen2_subscribe_property(struct iris_inst *inst, u32 plane) -+{ -+ struct iris_core *core = inst->core; -+ u32 subscribe_prop_size, i; -+ const u32 *subcribe_prop; -+ u32 payload[32] = {0}; -+ -+ payload[0] = HFI_MODE_PROPERTY; -+ -+ if (V4L2_TYPE_IS_OUTPUT(plane)) { -+ subscribe_prop_size = core->iris_platform_data->dec_input_prop_size; -+ subcribe_prop = core->iris_platform_data->dec_input_prop; -+ } else { -+ subscribe_prop_size = core->iris_platform_data->dec_output_prop_size; -+ subcribe_prop = core->iris_platform_data->dec_output_prop; -+ } -+ -+ for (i = 0; i < subscribe_prop_size; i++) -+ payload[i + 1] = subcribe_prop[i]; -+ -+ return iris_hfi_gen2_session_subscribe_mode(inst, -+ HFI_CMD_SUBSCRIBE_MODE, -+ plane, -+ HFI_PAYLOAD_U32_ARRAY, -+ &payload[0], -+ (subscribe_prop_size + 1) * sizeof(u32)); -+} -+ - static int iris_hfi_gen2_session_start(struct iris_inst *inst, u32 plane) - { - struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); -+ int ret = 0; -+ -+ ret = iris_hfi_gen2_subscribe_change_param(inst, plane); -+ if (ret) -+ return ret; -+ -+ ret = iris_hfi_gen2_subscribe_property(inst, plane); -+ if (ret) -+ return ret; - - iris_hfi_gen2_packet_session_command(inst, - HFI_CMD_START, -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h -index 4c9604b05034..4fb7a4e4604d 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h -@@ -17,6 +17,7 @@ - #define HFI_CMD_CLOSE 0x01000004 - #define HFI_CMD_START 0x01000005 - #define HFI_CMD_STOP 0x01000006 -+#define HFI_CMD_SUBSCRIBE_MODE 0x0100000B - #define HFI_CMD_END 0x01FFFFFF - - #define HFI_BITMASK_FRAME_MBS_ONLY_FLAG 0x00000001 -@@ -42,13 +43,16 @@ - #define HFI_PROP_PIPE 0x0300010b - #define HFI_PROP_LUMA_CHROMA_BIT_DEPTH 0x0300010f - #define HFI_PROP_CODED_FRAMES 0x03000120 -+#define HFI_PROP_CABAC_SESSION 0x03000121 - #define HFI_PROP_BUFFER_HOST_MAX_COUNT 0x03000123 - #define HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT 0x03000124 - #define HFI_PROP_PIC_ORDER_CNT_TYPE 0x03000128 - #define HFI_PROP_QUALITY_MODE 0x03000148 - #define HFI_PROP_SIGNAL_COLOR_INFO 0x03000155 -+#define HFI_PROP_PICTURE_TYPE 0x03000162 - #define HFI_PROP_DEC_DEFAULT_HEADER 0x03000168 - #define HFI_PROP_DEC_START_FROM_RAP_FRAME 0x03000169 -+#define HFI_PROP_NO_OUTPUT 0x0300016a - #define HFI_PROP_END 0x03FFFFFF - - #define HFI_SESSION_ERROR_BEGIN 0x04000000 -@@ -65,6 +69,11 @@ - #define HFI_SYS_ERROR_WD_TIMEOUT 0x05000001 - #define HFI_SYSTEM_ERROR_END 0x05FFFFFF - -+enum hfi_property_mode_type { -+ HFI_MODE_PORT_SETTINGS_CHANGE = 0x00000001, -+ HFI_MODE_PROPERTY = 0x00000002, -+}; -+ - enum hfi_color_format { - HFI_COLOR_FMT_OPAQUE = 0, - HFI_COLOR_FMT_NV12 = 1, -diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h -index 5643fb55b09e..50965450cbb9 100644 ---- a/drivers/media/platform/qcom/iris/iris_platform_common.h -+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h -@@ -147,6 +147,10 @@ struct iris_platform_data { - unsigned int input_config_params_size; - const u32 *output_config_params; - unsigned int output_config_params_size; -+ const u32 *dec_input_prop; -+ unsigned int dec_input_prop_size; -+ const u32 *dec_output_prop; -+ unsigned int dec_output_prop_size; - }; - - #endif -diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c -index 8a55c1f731c0..703e48802795 100644 ---- a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c -+++ b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c -@@ -183,6 +183,15 @@ static const u32 sm8550_vdec_output_config_params[] = { - HFI_PROP_LINEAR_STRIDE_SCANLINE, - }; - -+static const u32 sm8550_vdec_subscribe_input_properties[] = { -+ HFI_PROP_NO_OUTPUT, -+}; -+ -+static const u32 sm8550_vdec_subscribe_output_properties[] = { -+ HFI_PROP_PICTURE_TYPE, -+ HFI_PROP_CABAC_SESSION, -+}; -+ - struct iris_platform_data sm8550_data = { - .get_instance = iris_hfi_gen2_get_instance, - .init_hfi_command_ops = iris_hfi_gen2_command_ops_init, -@@ -220,4 +229,8 @@ struct iris_platform_data sm8550_data = { - sm8550_vdec_output_config_params, - .output_config_params_size = - ARRAY_SIZE(sm8550_vdec_output_config_params), -+ .dec_input_prop = sm8550_vdec_subscribe_input_properties, -+ .dec_input_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_input_properties), -+ .dec_output_prop = sm8550_vdec_subscribe_output_properties, -+ .dec_output_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_output_properties), - }; --- -2.34.1 - diff --git a/patch/kernel/archive/sm8550-6.12/0019_media--iris--allocate,-initialize-and-queue-intern.patch b/patch/kernel/archive/sm8550-6.12/0019_media--iris--allocate,-initialize-and-queue-intern.patch deleted file mode 100644 index 78a0353d716e..000000000000 --- a/patch/kernel/archive/sm8550-6.12/0019_media--iris--allocate,-initialize-and-queue-intern.patch +++ /dev/null @@ -1,1477 +0,0 @@ -From 1d0c9406d6b3174c928b1bd745912e63dfa4106e Mon Sep 17 00:00:00 2001 -From: Dikshita Agarwal -Date: Fri, 7 Feb 2025 13:24:59 +0530 -Subject: [PATCH] media: iris: allocate, initialize and queue internal buffers - -Implement the functions for creating, queueing, releasing and destroying -the buffers for internal usage. - -Tested-by: Stefan Schmidt # x1e80100 (Dell XPS 13 9345) -Reviewed-by: Stefan Schmidt -Tested-by: Neil Armstrong # on SM8550-QRD -Tested-by: Neil Armstrong # on SM8550-HDK -Signed-off-by: Dikshita Agarwal -Link: https://lore.kernel.org/r/20250207-qcom-video-iris-v10-19-ab66eeffbd20@quicinc.com -Signed-off-by: Neil Armstrong ---- - .../media/platform/qcom/iris/iris_buffer.c | 206 ++++++++++++++++ - .../media/platform/qcom/iris/iris_buffer.h | 7 + - .../platform/qcom/iris/iris_hfi_common.h | 4 + - .../qcom/iris/iris_hfi_gen1_command.c | 127 +++++++++- - .../qcom/iris/iris_hfi_gen1_defines.h | 37 +++ - .../qcom/iris/iris_hfi_gen1_response.c | 4 + - .../qcom/iris/iris_hfi_gen2_command.c | 132 ++++++++++ - .../qcom/iris/iris_hfi_gen2_defines.h | 9 + - .../platform/qcom/iris/iris_hfi_gen2_packet.h | 41 +++ - .../qcom/iris/iris_hfi_gen2_response.c | 149 ++++++++++- - .../platform/qcom/iris/iris_platform_common.h | 5 + - .../platform/qcom/iris/iris_platform_sm8550.c | 17 ++ - drivers/media/platform/qcom/iris/iris_vdec.c | 32 +++ - drivers/media/platform/qcom/iris/iris_vidc.c | 11 + - .../platform/qcom/iris/iris_vpu_buffer.c | 233 +++++++++++++++++- - .../platform/qcom/iris/iris_vpu_buffer.h | 77 +++++- - 16 files changed, 1087 insertions(+), 4 deletions(-) - -diff --git a/drivers/media/platform/qcom/iris/iris_buffer.c b/drivers/media/platform/qcom/iris/iris_buffer.c -index 58d45d23393b..e9d372580b5f 100644 ---- a/drivers/media/platform/qcom/iris/iris_buffer.c -+++ b/drivers/media/platform/qcom/iris/iris_buffer.c -@@ -7,6 +7,7 @@ - - #include "iris_buffer.h" - #include "iris_instance.h" -+#include "iris_vpu_buffer.h" - - #define PIXELS_4K 4096 - #define MAX_WIDTH 4096 -@@ -228,6 +229,211 @@ int iris_get_buffer_size(struct iris_inst *inst, - } - } - -+static void iris_fill_internal_buf_info(struct iris_inst *inst, -+ enum iris_buffer_type buffer_type) -+{ -+ struct iris_buffers *buffers = &inst->buffers[buffer_type]; -+ -+ buffers->size = iris_vpu_buf_size(inst, buffer_type); -+ buffers->min_count = iris_vpu_buf_count(inst, buffer_type); -+} -+ -+void iris_get_internal_buffers(struct iris_inst *inst, u32 plane) -+{ -+ const struct iris_platform_data *platform_data = inst->core->iris_platform_data; -+ const u32 *internal_buf_type; -+ u32 internal_buffer_count, i; -+ -+ if (V4L2_TYPE_IS_OUTPUT(plane)) { -+ internal_buf_type = platform_data->dec_ip_int_buf_tbl; -+ internal_buffer_count = platform_data->dec_ip_int_buf_tbl_size; -+ for (i = 0; i < internal_buffer_count; i++) -+ iris_fill_internal_buf_info(inst, internal_buf_type[i]); -+ } else { -+ internal_buf_type = platform_data->dec_op_int_buf_tbl; -+ internal_buffer_count = platform_data->dec_op_int_buf_tbl_size; -+ for (i = 0; i < internal_buffer_count; i++) -+ iris_fill_internal_buf_info(inst, internal_buf_type[i]); -+ } -+} -+ -+static int iris_create_internal_buffer(struct iris_inst *inst, -+ enum iris_buffer_type buffer_type, u32 index) -+{ -+ struct iris_buffers *buffers = &inst->buffers[buffer_type]; -+ struct iris_core *core = inst->core; -+ struct iris_buffer *buffer; -+ -+ if (!buffers->size) -+ return 0; -+ -+ buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); -+ if (!buffer) -+ return -ENOMEM; -+ -+ INIT_LIST_HEAD(&buffer->list); -+ buffer->type = buffer_type; -+ buffer->index = index; -+ buffer->buffer_size = buffers->size; -+ buffer->dma_attrs = DMA_ATTR_WRITE_COMBINE | DMA_ATTR_NO_KERNEL_MAPPING; -+ list_add_tail(&buffer->list, &buffers->list); -+ -+ buffer->kvaddr = dma_alloc_attrs(core->dev, buffer->buffer_size, -+ &buffer->device_addr, GFP_KERNEL, buffer->dma_attrs); -+ if (!buffer->kvaddr) -+ return -ENOMEM; -+ -+ return 0; -+} -+ -+int iris_create_internal_buffers(struct iris_inst *inst, u32 plane) -+{ -+ const struct iris_platform_data *platform_data = inst->core->iris_platform_data; -+ u32 internal_buffer_count, i, j; -+ struct iris_buffers *buffers; -+ const u32 *internal_buf_type; -+ int ret; -+ -+ if (V4L2_TYPE_IS_OUTPUT(plane)) { -+ internal_buf_type = platform_data->dec_ip_int_buf_tbl; -+ internal_buffer_count = platform_data->dec_ip_int_buf_tbl_size; -+ } else { -+ internal_buf_type = platform_data->dec_op_int_buf_tbl; -+ internal_buffer_count = platform_data->dec_op_int_buf_tbl_size; -+ } -+ -+ for (i = 0; i < internal_buffer_count; i++) { -+ buffers = &inst->buffers[internal_buf_type[i]]; -+ for (j = 0; j < buffers->min_count; j++) { -+ ret = iris_create_internal_buffer(inst, internal_buf_type[i], j); -+ if (ret) -+ return ret; -+ } -+ } -+ -+ return 0; -+} -+ -+int iris_queue_buffer(struct iris_inst *inst, struct iris_buffer *buf) -+{ -+ const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; -+ int ret; -+ -+ ret = hfi_ops->session_queue_buf(inst, buf); -+ if (ret) -+ return ret; -+ -+ buf->attr &= ~BUF_ATTR_DEFERRED; -+ buf->attr |= BUF_ATTR_QUEUED; -+ -+ return 0; -+} -+ -+int iris_queue_internal_buffers(struct iris_inst *inst, u32 plane) -+{ -+ const struct iris_platform_data *platform_data = inst->core->iris_platform_data; -+ struct iris_buffer *buffer, *next; -+ struct iris_buffers *buffers; -+ const u32 *internal_buf_type; -+ u32 internal_buffer_count, i; -+ int ret; -+ -+ if (V4L2_TYPE_IS_OUTPUT(plane)) { -+ internal_buf_type = platform_data->dec_ip_int_buf_tbl; -+ internal_buffer_count = platform_data->dec_ip_int_buf_tbl_size; -+ } else { -+ internal_buf_type = platform_data->dec_op_int_buf_tbl; -+ internal_buffer_count = platform_data->dec_op_int_buf_tbl_size; -+ } -+ -+ for (i = 0; i < internal_buffer_count; i++) { -+ buffers = &inst->buffers[internal_buf_type[i]]; -+ list_for_each_entry_safe(buffer, next, &buffers->list, list) { -+ if (buffer->attr & BUF_ATTR_PENDING_RELEASE) -+ continue; -+ if (buffer->attr & BUF_ATTR_QUEUED) -+ continue; -+ ret = iris_queue_buffer(inst, buffer); -+ if (ret) -+ return ret; -+ } -+ } -+ -+ return 0; -+} -+ -+int iris_destroy_internal_buffer(struct iris_inst *inst, struct iris_buffer *buffer) -+{ -+ struct iris_core *core = inst->core; -+ -+ list_del(&buffer->list); -+ dma_free_attrs(core->dev, buffer->buffer_size, buffer->kvaddr, -+ buffer->device_addr, buffer->dma_attrs); -+ kfree(buffer); -+ -+ return 0; -+} -+ -+int iris_destroy_internal_buffers(struct iris_inst *inst, u32 plane) -+{ -+ const struct iris_platform_data *platform_data = inst->core->iris_platform_data; -+ struct iris_buffer *buf, *next; -+ struct iris_buffers *buffers; -+ const u32 *internal_buf_type; -+ u32 i, len; -+ int ret; -+ -+ if (V4L2_TYPE_IS_OUTPUT(plane)) { -+ internal_buf_type = platform_data->dec_ip_int_buf_tbl; -+ len = platform_data->dec_ip_int_buf_tbl_size; -+ } else { -+ internal_buf_type = platform_data->dec_op_int_buf_tbl; -+ len = platform_data->dec_op_int_buf_tbl_size; -+ } -+ -+ for (i = 0; i < len; i++) { -+ buffers = &inst->buffers[internal_buf_type[i]]; -+ list_for_each_entry_safe(buf, next, &buffers->list, list) { -+ ret = iris_destroy_internal_buffer(inst, buf); -+ if (ret) -+ return ret; -+ } -+ } -+ -+ return 0; -+} -+ -+int iris_alloc_and_queue_persist_bufs(struct iris_inst *inst) -+{ -+ struct iris_buffers *buffers = &inst->buffers[BUF_PERSIST]; -+ struct iris_buffer *buffer, *next; -+ int ret; -+ u32 i; -+ -+ if (!list_empty(&buffers->list)) -+ return 0; -+ -+ iris_fill_internal_buf_info(inst, BUF_PERSIST); -+ -+ for (i = 0; i < buffers->min_count; i++) { -+ ret = iris_create_internal_buffer(inst, BUF_PERSIST, i); -+ if (ret) -+ return ret; -+ } -+ -+ list_for_each_entry_safe(buffer, next, &buffers->list, list) { -+ if (buffer->attr & BUF_ATTR_PENDING_RELEASE) -+ continue; -+ if (buffer->attr & BUF_ATTR_QUEUED) -+ continue; -+ ret = iris_queue_buffer(inst, buffer); -+ if (ret) -+ return ret; -+ } -+ -+ return 0; -+} -+ - void iris_vb2_queue_error(struct iris_inst *inst) - { - struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; -diff --git a/drivers/media/platform/qcom/iris/iris_buffer.h b/drivers/media/platform/qcom/iris/iris_buffer.h -index ae2ec5637108..73f3a16ff7a2 100644 ---- a/drivers/media/platform/qcom/iris/iris_buffer.h -+++ b/drivers/media/platform/qcom/iris/iris_buffer.h -@@ -102,6 +102,13 @@ struct iris_buffers { - }; - - int iris_get_buffer_size(struct iris_inst *inst, enum iris_buffer_type buffer_type); -+void iris_get_internal_buffers(struct iris_inst *inst, u32 plane); -+int iris_create_internal_buffers(struct iris_inst *inst, u32 plane); -+int iris_queue_internal_buffers(struct iris_inst *inst, u32 plane); -+int iris_destroy_internal_buffer(struct iris_inst *inst, struct iris_buffer *buffer); -+int iris_destroy_internal_buffers(struct iris_inst *inst, u32 plane); -+int iris_alloc_and_queue_persist_bufs(struct iris_inst *inst); -+int iris_queue_buffer(struct iris_inst *inst, struct iris_buffer *buf); - void iris_vb2_queue_error(struct iris_inst *inst); - - #endif -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_common.h b/drivers/media/platform/qcom/iris/iris_hfi_common.h -index 1fba5a9292af..c54c88658633 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_common.h -+++ b/drivers/media/platform/qcom/iris/iris_hfi_common.h -@@ -9,6 +9,8 @@ - #include - #include - -+#include "iris_buffer.h" -+ - struct iris_inst; - struct iris_core; - -@@ -114,6 +116,8 @@ struct iris_hfi_command_ops { - void *payload, u32 payload_size); - int (*session_open)(struct iris_inst *inst); - int (*session_start)(struct iris_inst *inst, u32 plane); -+ int (*session_queue_buf)(struct iris_inst *inst, struct iris_buffer *buffer); -+ int (*session_release_buf)(struct iris_inst *inst, struct iris_buffer *buffer); - int (*session_stop)(struct iris_inst *inst, u32 plane); - int (*session_close)(struct iris_inst *inst); - }; -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c -index 26fe65ddba8a..603ca485992d 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c -@@ -8,6 +8,24 @@ - #include "iris_instance.h" - #include "iris_vpu_buffer.h" - -+static u32 iris_hfi_gen1_buf_type_from_driver(enum iris_buffer_type buffer_type) -+{ -+ switch (buffer_type) { -+ case BUF_INPUT: -+ return HFI_BUFFER_INPUT; -+ case BUF_OUTPUT: -+ return HFI_BUFFER_OUTPUT; -+ case BUF_PERSIST: -+ return HFI_BUFFER_INTERNAL_PERSIST_1; -+ case BUF_BIN: -+ return HFI_BUFFER_INTERNAL_SCRATCH; -+ case BUF_SCRATCH_1: -+ return HFI_BUFFER_INTERNAL_SCRATCH_1; -+ default: -+ return -EINVAL; -+ } -+} -+ - static int iris_hfi_gen1_sys_init(struct iris_core *core) - { - struct hfi_sys_init_pkt sys_init_pkt; -@@ -183,6 +201,111 @@ static int iris_hfi_gen1_session_stop(struct iris_inst *inst, u32 plane) - return ret; - } - -+static int iris_hfi_gen1_queue_internal_buffer(struct iris_inst *inst, struct iris_buffer *buf) -+{ -+ struct hfi_session_set_buffers_pkt *int_pkt; -+ u32 buffer_type, i; -+ u32 packet_size; -+ int ret; -+ -+ packet_size = struct_size(int_pkt, buffer_info, 1); -+ int_pkt = kzalloc(packet_size, GFP_KERNEL); -+ if (!int_pkt) -+ return -ENOMEM; -+ -+ int_pkt->shdr.hdr.pkt_type = HFI_CMD_SESSION_SET_BUFFERS; -+ int_pkt->shdr.session_id = inst->session_id; -+ int_pkt->buffer_size = buf->buffer_size; -+ int_pkt->min_buffer_size = buf->buffer_size; -+ int_pkt->num_buffers = 1; -+ int_pkt->extradata_size = 0; -+ int_pkt->shdr.hdr.size = packet_size; -+ for (i = 0; i < int_pkt->num_buffers; i++) -+ int_pkt->buffer_info[i] = buf->device_addr; -+ buffer_type = iris_hfi_gen1_buf_type_from_driver(buf->type); -+ if (buffer_type == -EINVAL) { -+ ret = -EINVAL; -+ goto exit; -+ } -+ -+ int_pkt->buffer_type = buffer_type; -+ ret = iris_hfi_queue_cmd_write(inst->core, int_pkt, int_pkt->shdr.hdr.size); -+ -+exit: -+ kfree(int_pkt); -+ -+ return ret; -+} -+ -+static int iris_hfi_gen1_session_queue_buffer(struct iris_inst *inst, struct iris_buffer *buf) -+{ -+ switch (buf->type) { -+ case BUF_PERSIST: -+ case BUF_BIN: -+ case BUF_SCRATCH_1: -+ return iris_hfi_gen1_queue_internal_buffer(inst, buf); -+ default: -+ return -EINVAL; -+ } -+} -+ -+static int iris_hfi_gen1_session_unset_buffers(struct iris_inst *inst, struct iris_buffer *buf) -+{ -+ struct hfi_session_release_buffer_pkt *pkt; -+ u32 packet_size, buffer_type, i; -+ int ret; -+ -+ buffer_type = iris_hfi_gen1_buf_type_from_driver(buf->type); -+ if (buffer_type == -EINVAL) -+ return -EINVAL; -+ -+ if (buffer_type == HFI_BUFFER_INPUT) -+ return 0; -+ -+ packet_size = sizeof(*pkt) + sizeof(struct hfi_buffer_info); -+ pkt = kzalloc(packet_size, GFP_KERNEL); -+ if (!pkt) -+ return -ENOMEM; -+ -+ pkt->shdr.hdr.pkt_type = HFI_CMD_SESSION_RELEASE_BUFFERS; -+ pkt->shdr.session_id = inst->session_id; -+ pkt->buffer_size = buf->buffer_size; -+ pkt->num_buffers = 1; -+ -+ if (buffer_type == HFI_BUFFER_OUTPUT || -+ buffer_type == HFI_BUFFER_OUTPUT2) { -+ struct hfi_buffer_info *bi; -+ -+ bi = (struct hfi_buffer_info *)pkt->buffer_info; -+ for (i = 0; i < pkt->num_buffers; i++) { -+ bi->buffer_addr = buf->device_addr; -+ bi->extradata_addr = 0; -+ } -+ pkt->shdr.hdr.size = packet_size; -+ } else { -+ for (i = 0; i < pkt->num_buffers; i++) -+ pkt->buffer_info[i] = buf->device_addr; -+ pkt->extradata_size = 0; -+ pkt->shdr.hdr.size = -+ sizeof(struct hfi_session_set_buffers_pkt) + -+ ((pkt->num_buffers) * sizeof(u32)); -+ } -+ -+ pkt->response_req = true; -+ pkt->buffer_type = buffer_type; -+ -+ ret = iris_hfi_queue_cmd_write(inst->core, pkt, pkt->shdr.hdr.size); -+ if (ret) -+ goto exit; -+ -+ ret = iris_wait_for_session_response(inst, false); -+ -+exit: -+ kfree(pkt); -+ -+ return ret; -+} -+ - static int - iris_hfi_gen1_packet_session_set_property(struct hfi_session_set_property_pkt *packet, - struct iris_inst *inst, u32 ptype, void *pdata) -@@ -495,7 +618,7 @@ static int iris_hfi_gen1_set_bufsize(struct iris_inst *inst) - - if (iris_split_mode_enabled(inst)) { - bufsz.type = HFI_BUFFER_OUTPUT; -- bufsz.size = iris_vpu_dec_dpb_size(inst); -+ bufsz.size = iris_vpu_buf_size(inst, BUF_DPB); - - ret = hfi_gen1_set_property(inst, ptype, &bufsz, sizeof(bufsz)); - if (ret) -@@ -600,6 +723,8 @@ static const struct iris_hfi_command_ops iris_hfi_gen1_command_ops = { - .session_set_config_params = iris_hfi_gen1_session_set_config_params, - .session_set_property = iris_hfi_gen1_session_set_property, - .session_start = iris_hfi_gen1_session_start, -+ .session_queue_buf = iris_hfi_gen1_session_queue_buffer, -+ .session_release_buf = iris_hfi_gen1_session_unset_buffers, - .session_stop = iris_hfi_gen1_session_stop, - .session_close = iris_hfi_gen1_session_close, - }; -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h -index 67e7575351d4..cabd91eafc92 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h -@@ -24,11 +24,13 @@ - #define HFI_CMD_SYS_SESSION_END 0x10008 - - #define HFI_CMD_SESSION_SET_PROPERTY 0x11001 -+#define HFI_CMD_SESSION_SET_BUFFERS 0x11002 - - #define HFI_CMD_SESSION_LOAD_RESOURCES 0x211001 - #define HFI_CMD_SESSION_START 0x211002 - #define HFI_CMD_SESSION_STOP 0x211003 - #define HFI_CMD_SESSION_FLUSH 0x211008 -+#define HFI_CMD_SESSION_RELEASE_BUFFERS 0x21100b - #define HFI_CMD_SESSION_RELEASE_RESOURCES 0x21100c - - #define HFI_ERR_SESSION_UNSUPPORTED_SETTING 0x1008 -@@ -53,6 +55,9 @@ - #define HFI_BUFFER_INPUT 0x1 - #define HFI_BUFFER_OUTPUT 0x2 - #define HFI_BUFFER_OUTPUT2 0x3 -+#define HFI_BUFFER_INTERNAL_PERSIST_1 0x5 -+#define HFI_BUFFER_INTERNAL_SCRATCH 0x6 -+#define HFI_BUFFER_INTERNAL_SCRATCH_1 0x7 - - #define HFI_PROPERTY_SYS_CODEC_POWER_PLANE_CTRL 0x5 - #define HFI_PROPERTY_SYS_IMAGE_VERSION 0x6 -@@ -80,6 +85,7 @@ - #define HFI_MSG_SESSION_STOP 0x221003 - #define HFI_MSG_SESSION_FLUSH 0x221006 - #define HFI_MSG_SESSION_RELEASE_RESOURCES 0x22100a -+#define HFI_MSG_SESSION_RELEASE_BUFFERS 0x22100c - - struct hfi_pkt_hdr { - u32 size; -@@ -128,11 +134,36 @@ struct hfi_sys_pc_prep_pkt { - struct hfi_pkt_hdr hdr; - }; - -+struct hfi_session_set_buffers_pkt { -+ struct hfi_session_hdr_pkt shdr; -+ u32 buffer_type; -+ u32 buffer_size; -+ u32 extradata_size; -+ u32 min_buffer_size; -+ u32 num_buffers; -+ u32 buffer_info[]; -+}; -+ - struct hfi_session_flush_pkt { - struct hfi_session_hdr_pkt shdr; - u32 flush_type; - }; - -+struct hfi_session_release_buffer_pkt { -+ struct hfi_session_hdr_pkt shdr; -+ u32 buffer_type; -+ u32 buffer_size; -+ u32 extradata_size; -+ u32 response_req; -+ u32 num_buffers; -+ u32 buffer_info[]; -+}; -+ -+struct hfi_buffer_info { -+ u32 buffer_addr; -+ u32 extradata_addr; -+}; -+ - struct hfi_msg_event_notify_pkt { - struct hfi_session_hdr_pkt shdr; - u32 event_id; -@@ -227,6 +258,12 @@ struct hfi_multi_stream { - u32 enable; - }; - -+struct hfi_msg_session_release_buffers_done_pkt { -+ struct hfi_msg_session_hdr_pkt shdr; -+ u32 num_buffers; -+ u32 buffer_info[]; -+}; -+ - struct hfi_msg_sys_debug_pkt { - struct hfi_pkt_hdr hdr; - u32 msg_type; -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c -index db5858ec04ea..a84bb00388d9 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c -@@ -176,6 +176,10 @@ static const struct iris_hfi_gen1_response_pkt_info pkt_infos[] = { - .pkt = HFI_MSG_SESSION_RELEASE_RESOURCES, - .pkt_sz = sizeof(struct hfi_msg_session_hdr_pkt), - }, -+ { -+ .pkt = HFI_MSG_SESSION_RELEASE_BUFFERS, -+ .pkt_sz = sizeof(struct hfi_msg_session_release_buffers_done_pkt), -+ }, - }; - - static void iris_hfi_gen1_handle_response(struct iris_core *core, void *response) -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c -index dddaa074cae1..cc75231f07f1 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c -@@ -100,6 +100,24 @@ static u32 iris_hfi_gen2_get_port(u32 plane) - } - } - -+static u32 iris_hfi_gen2_get_port_from_buf_type(enum iris_buffer_type buffer_type) -+{ -+ switch (buffer_type) { -+ case BUF_INPUT: -+ case BUF_BIN: -+ case BUF_COMV: -+ case BUF_NON_COMV: -+ case BUF_LINE: -+ return HFI_PORT_BITSTREAM; -+ case BUF_OUTPUT: -+ case BUF_DPB: -+ return HFI_PORT_RAW; -+ case BUF_PERSIST: -+ default: -+ return HFI_PORT_NONE; -+ } -+} -+ - static int iris_hfi_gen2_session_set_property(struct iris_inst *inst, u32 packet_type, u32 flag, - u32 plane, u32 payload_type, void *payload, - u32 payload_size) -@@ -719,6 +737,118 @@ static int iris_hfi_gen2_session_stop(struct iris_inst *inst, u32 plane) - return iris_wait_for_session_response(inst, false); - } - -+static u32 iris_hfi_gen2_buf_type_from_driver(enum iris_buffer_type buffer_type) -+{ -+ switch (buffer_type) { -+ case BUF_INPUT: -+ return HFI_BUFFER_BITSTREAM; -+ case BUF_OUTPUT: -+ return HFI_BUFFER_RAW; -+ case BUF_BIN: -+ return HFI_BUFFER_BIN; -+ case BUF_COMV: -+ return HFI_BUFFER_COMV; -+ case BUF_NON_COMV: -+ return HFI_BUFFER_NON_COMV; -+ case BUF_LINE: -+ return HFI_BUFFER_LINE; -+ case BUF_DPB: -+ return HFI_BUFFER_DPB; -+ case BUF_PERSIST: -+ return HFI_BUFFER_PERSIST; -+ default: -+ return 0; -+ } -+} -+ -+static int iris_set_num_comv(struct iris_inst *inst) -+{ -+ struct platform_inst_caps *caps; -+ struct iris_core *core = inst->core; -+ u32 num_comv; -+ -+ caps = core->iris_platform_data->inst_caps; -+ num_comv = caps->num_comv; -+ -+ return core->hfi_ops->session_set_property(inst, -+ HFI_PROP_COMV_BUFFER_COUNT, -+ HFI_HOST_FLAGS_NONE, -+ HFI_PORT_BITSTREAM, -+ HFI_PAYLOAD_U32, -+ &num_comv, sizeof(u32)); -+} -+ -+static void iris_hfi_gen2_get_buffer(struct iris_buffer *buffer, struct iris_hfi_buffer *buf) -+{ -+ memset(buf, 0, sizeof(*buf)); -+ buf->type = iris_hfi_gen2_buf_type_from_driver(buffer->type); -+ buf->index = buffer->index; -+ buf->base_address = buffer->device_addr; -+ buf->addr_offset = 0; -+ buf->buffer_size = buffer->buffer_size; -+ -+ if (buffer->type == BUF_INPUT) -+ buf->buffer_size = ALIGN(buffer->buffer_size, 256); -+ buf->data_offset = buffer->data_offset; -+ buf->data_size = buffer->data_size; -+ if (buffer->attr & BUF_ATTR_PENDING_RELEASE) -+ buf->flags |= HFI_BUF_HOST_FLAG_RELEASE; -+ buf->flags |= HFI_BUF_HOST_FLAGS_CB_NON_SECURE; -+ buf->timestamp = buffer->timestamp; -+} -+ -+static int iris_hfi_gen2_session_queue_buffer(struct iris_inst *inst, struct iris_buffer *buffer) -+{ -+ struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); -+ struct iris_hfi_buffer hfi_buffer; -+ u32 port; -+ int ret; -+ -+ iris_hfi_gen2_get_buffer(buffer, &hfi_buffer); -+ if (buffer->type == BUF_COMV) { -+ ret = iris_set_num_comv(inst); -+ if (ret) -+ return ret; -+ } -+ -+ port = iris_hfi_gen2_get_port_from_buf_type(buffer->type); -+ iris_hfi_gen2_packet_session_command(inst, -+ HFI_CMD_BUFFER, -+ HFI_HOST_FLAGS_INTR_REQUIRED, -+ port, -+ inst->session_id, -+ HFI_PAYLOAD_STRUCTURE, -+ &hfi_buffer, -+ sizeof(hfi_buffer)); -+ -+ return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet, -+ inst_hfi_gen2->packet->size); -+} -+ -+static int iris_hfi_gen2_session_release_buffer(struct iris_inst *inst, struct iris_buffer *buffer) -+{ -+ struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); -+ struct iris_hfi_buffer hfi_buffer; -+ u32 port; -+ -+ iris_hfi_gen2_get_buffer(buffer, &hfi_buffer); -+ hfi_buffer.flags |= HFI_BUF_HOST_FLAG_RELEASE; -+ port = iris_hfi_gen2_get_port_from_buf_type(buffer->type); -+ -+ iris_hfi_gen2_packet_session_command(inst, -+ HFI_CMD_BUFFER, -+ (HFI_HOST_FLAGS_RESPONSE_REQUIRED | -+ HFI_HOST_FLAGS_INTR_REQUIRED), -+ port, -+ inst->session_id, -+ HFI_PAYLOAD_STRUCTURE, -+ &hfi_buffer, -+ sizeof(hfi_buffer)); -+ -+ return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet, -+ inst_hfi_gen2->packet->size); -+} -+ - static const struct iris_hfi_command_ops iris_hfi_gen2_command_ops = { - .sys_init = iris_hfi_gen2_sys_init, - .sys_image_version = iris_hfi_gen2_sys_image_version, -@@ -728,6 +858,8 @@ static const struct iris_hfi_command_ops iris_hfi_gen2_command_ops = { - .session_set_config_params = iris_hfi_gen2_session_set_config_params, - .session_set_property = iris_hfi_gen2_session_set_property, - .session_start = iris_hfi_gen2_session_start, -+ .session_queue_buf = iris_hfi_gen2_session_queue_buffer, -+ .session_release_buf = iris_hfi_gen2_session_release_buffer, - .session_stop = iris_hfi_gen2_session_stop, - .session_close = iris_hfi_gen2_session_close, - }; -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h -index 4fb7a4e4604d..afbdf1f1e68a 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h -@@ -17,6 +17,7 @@ - #define HFI_CMD_CLOSE 0x01000004 - #define HFI_CMD_START 0x01000005 - #define HFI_CMD_STOP 0x01000006 -+#define HFI_CMD_BUFFER 0x01000009 - #define HFI_CMD_SUBSCRIBE_MODE 0x0100000B - #define HFI_CMD_END 0x01FFFFFF - -@@ -53,6 +54,7 @@ - #define HFI_PROP_DEC_DEFAULT_HEADER 0x03000168 - #define HFI_PROP_DEC_START_FROM_RAP_FRAME 0x03000169 - #define HFI_PROP_NO_OUTPUT 0x0300016a -+#define HFI_PROP_COMV_BUFFER_COUNT 0x03000193 - #define HFI_PROP_END 0x03FFFFFF - - #define HFI_SESSION_ERROR_BEGIN 0x04000000 -@@ -106,6 +108,13 @@ enum hfi_buffer_type { - HFI_BUFFER_VPSS = 0x0000000D, - }; - -+enum hfi_buffer_host_flags { -+ HFI_BUF_HOST_FLAG_RELEASE = 0x00000001, -+ HFI_BUF_HOST_FLAG_READONLY = 0x00000010, -+ HFI_BUF_HOST_FLAG_CODEC_CONFIG = 0x00000100, -+ HFI_BUF_HOST_FLAGS_CB_NON_SECURE = 0x00000200, -+}; -+ - enum hfi_packet_firmware_flags { - HFI_FW_FLAGS_SUCCESS = 0x00000001, - HFI_FW_FLAGS_INFORMATION = 0x00000002, -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.h b/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.h -index 0333e37572f6..25b9582349ca 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.h -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.h -@@ -61,6 +61,47 @@ struct iris_hfi_packet { - u32 payload[]; - }; - -+/** -+ * struct iris_hfi_buffer -+ * -+ * @type: buffer type indicated by "enum hfi_buffer_type" -+ * FW needs to return proper type for any buffer command. -+ * @index: index of the buffer -+ * @base_address: base address of the buffer. -+ * This buffer address is always 4KBytes aligned. -+ * @addr_offset: accessible buffer offset from base address -+ * Decoder bitstream buffer: 256 Bytes aligned -+ * Firmware can uniquely identify a buffer based on -+ * base_address & addr_offset. -+ * HW can read memory only from base_address+addr_offset. -+ * @buffer_size: accessible buffer size in bytes starting from addr_offset -+ * @data_offset: data starts from "base_address + addr_offset + data_offset" -+ * RAW buffer: data_offset is 0. Restriction: 4KBytes aligned -+ * decoder bitstream buffer: no restriction (can be any value) -+ * @data_size: data size in bytes -+ * @flags: buffer flags. It is represented as bit masks. -+ * host buffer flags are "enum hfi_buffer_host_flags" -+ * firmware buffer flags are "enum hfi_buffer_firmware_flags" -+ * @timestamp: timestamp of the buffer in nano seconds (ns) -+ * It is Presentation timestamp (PTS) for encoder & decoder. -+ * Decoder: it is pass through from bitstream to raw buffer. -+ * firmware does not need to return as part of input buffer done. -+ * For any internal buffers: there is no timestamp. Host sets as 0. -+ * @reserved: reserved for future use -+ */ -+struct iris_hfi_buffer { -+ u32 type; -+ u32 index; -+ u64 base_address; -+ u32 addr_offset; -+ u32 buffer_size; -+ u32 data_offset; -+ u32 data_size; -+ u64 timestamp; -+ u32 flags; -+ u32 reserved[5]; -+}; -+ - u32 iris_hfi_gen2_get_color_primaries(u32 primaries); - u32 iris_hfi_gen2_get_transfer_char(u32 characterstics); - u32 iris_hfi_gen2_get_matrix_coefficients(u32 coefficients); -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c -index 336b43740b72..9f3764f1903b 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c -@@ -25,6 +25,94 @@ struct iris_hfi_gen2_packet_handle { - int (*handle)(struct iris_inst *inst, struct iris_hfi_packet *pkt); - }; - -+static u32 iris_hfi_gen2_buf_type_to_driver(enum hfi_buffer_type buf_type) -+{ -+ switch (buf_type) { -+ case HFI_BUFFER_BITSTREAM: -+ return BUF_INPUT; -+ case HFI_BUFFER_RAW: -+ return BUF_OUTPUT; -+ case HFI_BUFFER_BIN: -+ return BUF_BIN; -+ case HFI_BUFFER_ARP: -+ return BUF_ARP; -+ case HFI_BUFFER_COMV: -+ return BUF_COMV; -+ case HFI_BUFFER_NON_COMV: -+ return BUF_NON_COMV; -+ case HFI_BUFFER_LINE: -+ return BUF_LINE; -+ case HFI_BUFFER_DPB: -+ return BUF_DPB; -+ case HFI_BUFFER_PERSIST: -+ return BUF_PERSIST; -+ default: -+ return 0; -+ } -+} -+ -+static bool iris_hfi_gen2_is_valid_hfi_buffer_type(u32 buffer_type) -+{ -+ switch (buffer_type) { -+ case HFI_BUFFER_BITSTREAM: -+ case HFI_BUFFER_RAW: -+ case HFI_BUFFER_BIN: -+ case HFI_BUFFER_ARP: -+ case HFI_BUFFER_COMV: -+ case HFI_BUFFER_NON_COMV: -+ case HFI_BUFFER_LINE: -+ case HFI_BUFFER_DPB: -+ case HFI_BUFFER_PERSIST: -+ case HFI_BUFFER_VPSS: -+ return true; -+ default: -+ return false; -+ } -+} -+ -+static bool iris_hfi_gen2_is_valid_hfi_port(u32 port, u32 buffer_type) -+{ -+ if (port == HFI_PORT_NONE && buffer_type != HFI_BUFFER_PERSIST) -+ return false; -+ -+ if (port != HFI_PORT_BITSTREAM && port != HFI_PORT_RAW) -+ return false; -+ -+ return true; -+} -+ -+static bool iris_hfi_gen2_validate_packet_payload(struct iris_hfi_packet *pkt) -+{ -+ u32 payload_size = 0; -+ -+ switch (pkt->payload_info) { -+ case HFI_PAYLOAD_U32: -+ case HFI_PAYLOAD_S32: -+ case HFI_PAYLOAD_Q16: -+ case HFI_PAYLOAD_U32_ENUM: -+ case HFI_PAYLOAD_32_PACKED: -+ payload_size = 4; -+ break; -+ case HFI_PAYLOAD_U64: -+ case HFI_PAYLOAD_S64: -+ case HFI_PAYLOAD_64_PACKED: -+ payload_size = 8; -+ break; -+ case HFI_PAYLOAD_STRUCTURE: -+ if (pkt->type == HFI_CMD_BUFFER) -+ payload_size = sizeof(struct iris_hfi_buffer); -+ break; -+ default: -+ payload_size = 0; -+ break; -+ } -+ -+ if (pkt->size < sizeof(struct iris_hfi_packet) + payload_size) -+ return false; -+ -+ return true; -+} -+ - static int iris_hfi_gen2_validate_packet(u8 *response_pkt, u8 *core_resp_pkt) - { - u8 *response_limit = core_resp_pkt + IFACEQ_CORE_PKT_SIZE; -@@ -149,9 +237,65 @@ static void iris_hfi_gen2_handle_session_close(struct iris_inst *inst, - complete(&inst->completion); - } - -+static int iris_hfi_gen2_handle_release_internal_buffer(struct iris_inst *inst, -+ struct iris_hfi_buffer *buffer) -+{ -+ struct iris_buffer *buf, *iter; -+ struct iris_buffers *buffers; -+ u32 buf_type; -+ int ret = 0; -+ bool found; -+ -+ buf_type = iris_hfi_gen2_buf_type_to_driver(buffer->type); -+ buffers = &inst->buffers[buf_type]; -+ -+ found = false; -+ list_for_each_entry(iter, &buffers->list, list) { -+ if (iter->device_addr == buffer->base_address) { -+ found = true; -+ buf = iter; -+ break; -+ } -+ } -+ if (!found) -+ return -EINVAL; -+ -+ buf->attr &= ~BUF_ATTR_QUEUED; -+ -+ if (buf->attr & BUF_ATTR_PENDING_RELEASE) -+ ret = iris_destroy_internal_buffer(inst, buf); -+ -+ return ret; -+} -+ -+static int iris_hfi_gen2_handle_session_buffer(struct iris_inst *inst, -+ struct iris_hfi_packet *pkt) -+{ -+ struct iris_hfi_buffer *buffer; -+ -+ if (pkt->payload_info == HFI_PAYLOAD_NONE) -+ return 0; -+ -+ if (!iris_hfi_gen2_validate_packet_payload(pkt)) { -+ iris_inst_change_state(inst, IRIS_INST_ERROR); -+ return 0; -+ } -+ -+ buffer = (struct iris_hfi_buffer *)((u8 *)pkt + sizeof(*pkt)); -+ if (!iris_hfi_gen2_is_valid_hfi_buffer_type(buffer->type)) -+ return 0; -+ -+ if (!iris_hfi_gen2_is_valid_hfi_port(pkt->port, buffer->type)) -+ return 0; -+ -+ return iris_hfi_gen2_handle_release_internal_buffer(inst, buffer); -+} -+ - static int iris_hfi_gen2_handle_session_command(struct iris_inst *inst, - struct iris_hfi_packet *pkt) - { -+ int ret = 0; -+ - switch (pkt->type) { - case HFI_CMD_CLOSE: - iris_hfi_gen2_handle_session_close(inst, pkt); -@@ -159,11 +303,14 @@ static int iris_hfi_gen2_handle_session_command(struct iris_inst *inst, - case HFI_CMD_STOP: - complete(&inst->completion); - break; -+ case HFI_CMD_BUFFER: -+ ret = iris_hfi_gen2_handle_session_buffer(inst, pkt); -+ break; - default: - break; - } - -- return 0; -+ return ret; - } - - static int iris_hfi_gen2_handle_session_property(struct iris_inst *inst, -diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h -index 50965450cbb9..de0388a100c3 100644 ---- a/drivers/media/platform/qcom/iris/iris_platform_common.h -+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h -@@ -67,6 +67,7 @@ struct platform_inst_caps { - u32 min_frame_height; - u32 max_frame_height; - u32 max_mbpf; -+ u32 num_comv; - }; - - enum platform_inst_fw_cap_type { -@@ -151,6 +152,10 @@ struct iris_platform_data { - unsigned int dec_input_prop_size; - const u32 *dec_output_prop; - unsigned int dec_output_prop_size; -+ const u32 *dec_ip_int_buf_tbl; -+ unsigned int dec_ip_int_buf_tbl_size; -+ const u32 *dec_op_int_buf_tbl; -+ unsigned int dec_op_int_buf_tbl_size; - }; - - #endif -diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c -index 703e48802795..dc51df71c377 100644 ---- a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c -+++ b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c -@@ -126,6 +126,7 @@ static struct platform_inst_caps platform_inst_cap_sm8550 = { - .min_frame_height = 96, - .max_frame_height = 8192, - .max_mbpf = (8192 * 4352) / 256, -+ .num_comv = 0, - }; - - static void iris_set_sm8550_preset_registers(struct iris_core *core) -@@ -192,6 +193,17 @@ static const u32 sm8550_vdec_subscribe_output_properties[] = { - HFI_PROP_CABAC_SESSION, - }; - -+static const u32 sm8550_dec_ip_int_buf_tbl[] = { -+ BUF_BIN, -+ BUF_COMV, -+ BUF_NON_COMV, -+ BUF_LINE, -+}; -+ -+static const u32 sm8550_dec_op_int_buf_tbl[] = { -+ BUF_DPB, -+}; -+ - struct iris_platform_data sm8550_data = { - .get_instance = iris_hfi_gen2_get_instance, - .init_hfi_command_ops = iris_hfi_gen2_command_ops_init, -@@ -233,4 +245,9 @@ struct iris_platform_data sm8550_data = { - .dec_input_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_input_properties), - .dec_output_prop = sm8550_vdec_subscribe_output_properties, - .dec_output_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_output_properties), -+ -+ .dec_ip_int_buf_tbl = sm8550_dec_ip_int_buf_tbl, -+ .dec_ip_int_buf_tbl_size = ARRAY_SIZE(sm8550_dec_ip_int_buf_tbl), -+ .dec_op_int_buf_tbl = sm8550_dec_op_int_buf_tbl, -+ .dec_op_int_buf_tbl_size = ARRAY_SIZE(sm8550_dec_op_int_buf_tbl), - }; -diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c b/drivers/media/platform/qcom/iris/iris_vdec.c -index 13902f4e9724..8d489530da31 100644 ---- a/drivers/media/platform/qcom/iris/iris_vdec.c -+++ b/drivers/media/platform/qcom/iris/iris_vdec.c -@@ -273,6 +273,24 @@ int iris_vdec_streamon_input(struct iris_inst *inst) - if (ret) - return ret; - -+ ret = iris_alloc_and_queue_persist_bufs(inst); -+ if (ret) -+ return ret; -+ -+ iris_get_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); -+ -+ ret = iris_destroy_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); -+ if (ret) -+ return ret; -+ -+ ret = iris_create_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); -+ if (ret) -+ return ret; -+ -+ ret = iris_queue_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); -+ if (ret) -+ return ret; -+ - return iris_vdec_process_streamon_input(inst); - } - -@@ -297,10 +315,24 @@ int iris_vdec_streamon_output(struct iris_inst *inst) - if (ret) - return ret; - -+ iris_get_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); -+ -+ ret = iris_destroy_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); -+ if (ret) -+ return ret; -+ -+ ret = iris_create_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); -+ if (ret) -+ return ret; -+ - ret = iris_vdec_process_streamon_output(inst); - if (ret) - goto error; - -+ ret = iris_queue_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); -+ if (ret) -+ goto error; -+ - return ret; - - error: -diff --git a/drivers/media/platform/qcom/iris/iris_vidc.c b/drivers/media/platform/qcom/iris/iris_vidc.c -index 1d10c430c795..ec5694c1c8de 100644 ---- a/drivers/media/platform/qcom/iris/iris_vidc.c -+++ b/drivers/media/platform/qcom/iris/iris_vidc.c -@@ -149,6 +149,15 @@ int iris_open(struct file *filp) - - mutex_init(&inst->lock); - mutex_init(&inst->ctx_q_lock); -+ -+ INIT_LIST_HEAD(&inst->buffers[BUF_BIN].list); -+ INIT_LIST_HEAD(&inst->buffers[BUF_ARP].list); -+ INIT_LIST_HEAD(&inst->buffers[BUF_COMV].list); -+ INIT_LIST_HEAD(&inst->buffers[BUF_NON_COMV].list); -+ INIT_LIST_HEAD(&inst->buffers[BUF_LINE].list); -+ INIT_LIST_HEAD(&inst->buffers[BUF_DPB].list); -+ INIT_LIST_HEAD(&inst->buffers[BUF_PERSIST].list); -+ INIT_LIST_HEAD(&inst->buffers[BUF_SCRATCH_1].list); - init_completion(&inst->completion); - init_completion(&inst->flush_completion); - -@@ -221,6 +230,8 @@ int iris_close(struct file *filp) - iris_session_close(inst); - iris_inst_change_state(inst, IRIS_INST_DEINIT); - iris_v4l2_fh_deinit(inst); -+ iris_destroy_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); -+ iris_destroy_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); - iris_remove_session(inst); - mutex_unlock(&inst->lock); - mutex_destroy(&inst->ctx_q_lock); -diff --git a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c b/drivers/media/platform/qcom/iris/iris_vpu_buffer.c -index 0a65a17f13d2..dce25e410d80 100644 ---- a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c -+++ b/drivers/media/platform/qcom/iris/iris_vpu_buffer.c -@@ -6,7 +6,167 @@ - #include "iris_instance.h" - #include "iris_vpu_buffer.h" - --u32 iris_vpu_dec_dpb_size(struct iris_inst *inst) -+static u32 size_h264d_hw_bin_buffer(u32 frame_width, u32 frame_height, u32 num_vpp_pipes) -+{ -+ u32 size_yuv, size_bin_hdr, size_bin_res; -+ -+ size_yuv = ((frame_width * frame_height) <= BIN_BUFFER_THRESHOLD) ? -+ ((BIN_BUFFER_THRESHOLD * 3) >> 1) : -+ ((frame_width * frame_height * 3) >> 1); -+ size_bin_hdr = size_yuv * H264_CABAC_HDR_RATIO_HD_TOT; -+ size_bin_res = size_yuv * H264_CABAC_RES_RATIO_HD_TOT; -+ size_bin_hdr = ALIGN(size_bin_hdr / num_vpp_pipes, -+ DMA_ALIGNMENT) * num_vpp_pipes; -+ size_bin_res = ALIGN(size_bin_res / num_vpp_pipes, -+ DMA_ALIGNMENT) * num_vpp_pipes; -+ -+ return size_bin_hdr + size_bin_res; -+} -+ -+static u32 hfi_buffer_bin_h264d(u32 frame_width, u32 frame_height, u32 num_vpp_pipes) -+{ -+ u32 n_aligned_h = ALIGN(frame_height, 16); -+ u32 n_aligned_w = ALIGN(frame_width, 16); -+ -+ return size_h264d_hw_bin_buffer(n_aligned_w, n_aligned_h, num_vpp_pipes); -+} -+ -+static u32 hfi_buffer_comv_h264d(u32 frame_width, u32 frame_height, u32 _comv_bufcount) -+{ -+ u32 frame_height_in_mbs = DIV_ROUND_UP(frame_height, 16); -+ u32 frame_width_in_mbs = DIV_ROUND_UP(frame_width, 16); -+ u32 col_zero_aligned_width = (frame_width_in_mbs << 2); -+ u32 col_mv_aligned_width = (frame_width_in_mbs << 7); -+ u32 col_zero_size, size_colloc; -+ -+ col_mv_aligned_width = ALIGN(col_mv_aligned_width, 16); -+ col_zero_aligned_width = ALIGN(col_zero_aligned_width, 16); -+ col_zero_size = col_zero_aligned_width * -+ ((frame_height_in_mbs + 1) >> 1); -+ col_zero_size = ALIGN(col_zero_size, 64); -+ col_zero_size <<= 1; -+ col_zero_size = ALIGN(col_zero_size, 512); -+ size_colloc = col_mv_aligned_width * ((frame_height_in_mbs + 1) >> 1); -+ size_colloc = ALIGN(size_colloc, 64); -+ size_colloc <<= 1; -+ size_colloc = ALIGN(size_colloc, 512); -+ size_colloc += (col_zero_size + SIZE_H264D_BUFTAB_T * 2); -+ -+ return (size_colloc * (_comv_bufcount)) + 512; -+} -+ -+static u32 size_h264d_bse_cmd_buf(u32 frame_height) -+{ -+ u32 height = ALIGN(frame_height, 32); -+ -+ return min_t(u32, (DIV_ROUND_UP(height, 16) * 48), H264D_MAX_SLICE) * -+ SIZE_H264D_BSE_CMD_PER_BUF; -+} -+ -+static u32 size_h264d_vpp_cmd_buf(u32 frame_height) -+{ -+ u32 size, height = ALIGN(frame_height, 32); -+ -+ size = min_t(u32, (DIV_ROUND_UP(height, 16) * 48), H264D_MAX_SLICE) * -+ SIZE_H264D_VPP_CMD_PER_BUF; -+ -+ return size > VPP_CMD_MAX_SIZE ? VPP_CMD_MAX_SIZE : size; -+} -+ -+static u32 hfi_buffer_persist_h264d(void) -+{ -+ return ALIGN(SIZE_SLIST_BUF_H264 * NUM_SLIST_BUF_H264 + -+ H264_DISPLAY_BUF_SIZE * H264_NUM_FRM_INFO + -+ NUM_HW_PIC_BUF * SIZE_SEI_USERDATA, -+ DMA_ALIGNMENT); -+} -+ -+static u32 hfi_buffer_non_comv_h264d(u32 frame_width, u32 frame_height, u32 num_vpp_pipes) -+{ -+ u32 size_bse, size_vpp, size; -+ -+ size_bse = size_h264d_bse_cmd_buf(frame_height); -+ size_vpp = size_h264d_vpp_cmd_buf(frame_height); -+ size = ALIGN(size_bse, DMA_ALIGNMENT) + -+ ALIGN(size_vpp, DMA_ALIGNMENT) + -+ ALIGN(SIZE_HW_PIC(SIZE_H264D_HW_PIC_T), DMA_ALIGNMENT); -+ -+ return ALIGN(size, DMA_ALIGNMENT); -+} -+ -+static u32 size_vpss_lb(u32 frame_width, u32 frame_height) -+{ -+ u32 opb_lb_wr_llb_y_buffer_size, opb_lb_wr_llb_uv_buffer_size; -+ u32 opb_wr_top_line_chroma_buffer_size; -+ u32 opb_wr_top_line_luma_buffer_size; -+ u32 macrotiling_size = 32; -+ -+ opb_wr_top_line_luma_buffer_size = -+ ALIGN(frame_width, macrotiling_size) / macrotiling_size * 256; -+ opb_wr_top_line_luma_buffer_size = -+ ALIGN(opb_wr_top_line_luma_buffer_size, DMA_ALIGNMENT) + -+ (MAX_TILE_COLUMNS - 1) * 256; -+ opb_wr_top_line_luma_buffer_size = -+ max_t(u32, opb_wr_top_line_luma_buffer_size, (32 * ALIGN(frame_height, 8))); -+ opb_wr_top_line_chroma_buffer_size = opb_wr_top_line_luma_buffer_size; -+ opb_lb_wr_llb_uv_buffer_size = -+ ALIGN((ALIGN(frame_height, 8) / (4 / 2)) * 64, 32); -+ opb_lb_wr_llb_y_buffer_size = -+ ALIGN((ALIGN(frame_height, 8) / (4 / 2)) * 64, 32); -+ return opb_wr_top_line_luma_buffer_size + -+ opb_wr_top_line_chroma_buffer_size + -+ opb_lb_wr_llb_uv_buffer_size + -+ opb_lb_wr_llb_y_buffer_size; -+} -+ -+static u32 hfi_buffer_line_h264d(u32 frame_width, u32 frame_height, -+ bool is_opb, u32 num_vpp_pipes) -+{ -+ u32 vpss_lb_size = 0; -+ u32 size; -+ -+ size = ALIGN(size_h264d_lb_fe_top_data(frame_width), DMA_ALIGNMENT) + -+ ALIGN(size_h264d_lb_fe_top_ctrl(frame_width), DMA_ALIGNMENT) + -+ ALIGN(size_h264d_lb_fe_left_ctrl(frame_height), DMA_ALIGNMENT) * num_vpp_pipes + -+ ALIGN(size_h264d_lb_se_top_ctrl(frame_width), DMA_ALIGNMENT) + -+ ALIGN(size_h264d_lb_se_left_ctrl(frame_height), DMA_ALIGNMENT) * num_vpp_pipes + -+ ALIGN(size_h264d_lb_pe_top_data(frame_width), DMA_ALIGNMENT) + -+ ALIGN(size_h264d_lb_vsp_top(frame_width), DMA_ALIGNMENT) + -+ ALIGN(size_h264d_lb_recon_dma_metadata_wr(frame_height), DMA_ALIGNMENT) * 2 + -+ ALIGN(size_h264d_qp(frame_width, frame_height), DMA_ALIGNMENT); -+ size = ALIGN(size, DMA_ALIGNMENT); -+ if (is_opb) -+ vpss_lb_size = size_vpss_lb(frame_width, frame_height); -+ -+ return ALIGN((size + vpss_lb_size), DMA_ALIGNMENT); -+} -+ -+static u32 iris_vpu_dec_bin_size(struct iris_inst *inst) -+{ -+ u32 num_vpp_pipes = inst->core->iris_platform_data->num_vpp_pipe; -+ struct v4l2_format *f = inst->fmt_src; -+ u32 height = f->fmt.pix_mp.height; -+ u32 width = f->fmt.pix_mp.width; -+ -+ return hfi_buffer_bin_h264d(width, height, num_vpp_pipes); -+} -+ -+static u32 iris_vpu_dec_comv_size(struct iris_inst *inst) -+{ -+ u32 num_comv = VIDEO_MAX_FRAME; -+ struct v4l2_format *f = inst->fmt_src; -+ u32 height = f->fmt.pix_mp.height; -+ u32 width = f->fmt.pix_mp.width; -+ -+ return hfi_buffer_comv_h264d(width, height, num_comv); -+} -+ -+static u32 iris_vpu_dec_persist_size(struct iris_inst *inst) -+{ -+ return hfi_buffer_persist_h264d(); -+} -+ -+static u32 iris_vpu_dec_dpb_size(struct iris_inst *inst) - { - if (iris_split_mode_enabled(inst)) - return iris_get_buffer_size(inst, BUF_DPB); -@@ -14,6 +174,70 @@ u32 iris_vpu_dec_dpb_size(struct iris_inst *inst) - return 0; - } - -+static u32 iris_vpu_dec_non_comv_size(struct iris_inst *inst) -+{ -+ u32 num_vpp_pipes = inst->core->iris_platform_data->num_vpp_pipe; -+ struct v4l2_format *f = inst->fmt_src; -+ u32 height = f->fmt.pix_mp.height; -+ u32 width = f->fmt.pix_mp.width; -+ -+ return hfi_buffer_non_comv_h264d(width, height, num_vpp_pipes); -+} -+ -+static u32 iris_vpu_dec_line_size(struct iris_inst *inst) -+{ -+ u32 num_vpp_pipes = inst->core->iris_platform_data->num_vpp_pipe; -+ struct v4l2_format *f = inst->fmt_src; -+ u32 height = f->fmt.pix_mp.height; -+ u32 width = f->fmt.pix_mp.width; -+ bool is_opb = false; -+ -+ if (iris_split_mode_enabled(inst)) -+ is_opb = true; -+ -+ return hfi_buffer_line_h264d(width, height, is_opb, num_vpp_pipes); -+} -+ -+static u32 iris_vpu_dec_scratch1_size(struct iris_inst *inst) -+{ -+ return iris_vpu_dec_comv_size(inst) + -+ iris_vpu_dec_non_comv_size(inst) + -+ iris_vpu_dec_line_size(inst); -+} -+ -+struct iris_vpu_buf_type_handle { -+ enum iris_buffer_type type; -+ u32 (*handle)(struct iris_inst *inst); -+}; -+ -+int iris_vpu_buf_size(struct iris_inst *inst, enum iris_buffer_type buffer_type) -+{ -+ const struct iris_vpu_buf_type_handle *buf_type_handle_arr; -+ u32 size = 0, buf_type_handle_size, i; -+ -+ static const struct iris_vpu_buf_type_handle dec_internal_buf_type_handle[] = { -+ {BUF_BIN, iris_vpu_dec_bin_size }, -+ {BUF_COMV, iris_vpu_dec_comv_size }, -+ {BUF_NON_COMV, iris_vpu_dec_non_comv_size }, -+ {BUF_LINE, iris_vpu_dec_line_size }, -+ {BUF_PERSIST, iris_vpu_dec_persist_size }, -+ {BUF_DPB, iris_vpu_dec_dpb_size }, -+ {BUF_SCRATCH_1, iris_vpu_dec_scratch1_size }, -+ }; -+ -+ buf_type_handle_size = ARRAY_SIZE(dec_internal_buf_type_handle); -+ buf_type_handle_arr = dec_internal_buf_type_handle; -+ -+ for (i = 0; i < buf_type_handle_size; i++) { -+ if (buf_type_handle_arr[i].type == buffer_type) { -+ size = buf_type_handle_arr[i].handle(inst); -+ break; -+ } -+ } -+ -+ return size; -+} -+ - static inline int iris_vpu_dpb_count(struct iris_inst *inst) - { - if (iris_split_mode_enabled(inst)) { -@@ -31,6 +255,13 @@ int iris_vpu_buf_count(struct iris_inst *inst, enum iris_buffer_type buffer_type - return MIN_BUFFERS; - case BUF_OUTPUT: - return inst->fw_min_count; -+ case BUF_BIN: -+ case BUF_COMV: -+ case BUF_NON_COMV: -+ case BUF_LINE: -+ case BUF_PERSIST: -+ case BUF_SCRATCH_1: -+ return 1; /* internal buffer count needed by firmware is 1 */ - case BUF_DPB: - return iris_vpu_dpb_count(inst); - default: -diff --git a/drivers/media/platform/qcom/iris/iris_vpu_buffer.h b/drivers/media/platform/qcom/iris/iris_vpu_buffer.h -index 865539d626b7..62af6ea6ba1f 100644 ---- a/drivers/media/platform/qcom/iris/iris_vpu_buffer.h -+++ b/drivers/media/platform/qcom/iris/iris_vpu_buffer.h -@@ -10,7 +10,82 @@ struct iris_inst; - - #define MIN_BUFFERS 4 - --u32 iris_vpu_dec_dpb_size(struct iris_inst *inst); -+#define DMA_ALIGNMENT 256 -+ -+#define NUM_HW_PIC_BUF 32 -+#define SIZE_HW_PIC(size_per_buf) (NUM_HW_PIC_BUF * (size_per_buf)) -+ -+#define MAX_TILE_COLUMNS 32 -+#define BIN_BUFFER_THRESHOLD (1280 * 736) -+#define VPP_CMD_MAX_SIZE (BIT(20)) -+#define H264D_MAX_SLICE 1800 -+ -+#define SIZE_H264D_BUFTAB_T 256 -+#define SIZE_H264D_BSE_CMD_PER_BUF (32 * 4) -+#define SIZE_H264D_VPP_CMD_PER_BUF 512 -+ -+#define NUM_SLIST_BUF_H264 (256 + 32) -+#define SIZE_SLIST_BUF_H264 512 -+#define H264_DISPLAY_BUF_SIZE 3328 -+#define H264_NUM_FRM_INFO 66 -+ -+#define SIZE_SEI_USERDATA 4096 -+ -+#define H264_CABAC_HDR_RATIO_HD_TOT 1 -+#define H264_CABAC_RES_RATIO_HD_TOT 3 -+#define SIZE_H264D_HW_PIC_T (BIT(11)) -+ -+#define MAX_FE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE 64 -+#define MAX_SE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE 16 -+#define MAX_PE_NBR_DATA_LCU64_LINE_BUFFER_SIZE 384 -+#define MAX_FE_NBR_DATA_LUMA_LINE_BUFFER_SIZE 640 -+ -+static inline u32 size_h264d_lb_fe_top_data(u32 frame_width) -+{ -+ return MAX_FE_NBR_DATA_LUMA_LINE_BUFFER_SIZE * ALIGN(frame_width, 16) * 3; -+} -+ -+static inline u32 size_h264d_lb_fe_top_ctrl(u32 frame_width) -+{ -+ return MAX_FE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE * DIV_ROUND_UP(frame_width, 16); -+} -+ -+static inline u32 size_h264d_lb_fe_left_ctrl(u32 frame_height) -+{ -+ return MAX_FE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE * DIV_ROUND_UP(frame_height, 16); -+} -+ -+static inline u32 size_h264d_lb_se_top_ctrl(u32 frame_width) -+{ -+ return MAX_SE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE * DIV_ROUND_UP(frame_width, 16); -+} -+ -+static inline u32 size_h264d_lb_se_left_ctrl(u32 frame_height) -+{ -+ return MAX_SE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE * DIV_ROUND_UP(frame_height, 16); -+} -+ -+static inline u32 size_h264d_lb_pe_top_data(u32 frame_width) -+{ -+ return MAX_PE_NBR_DATA_LCU64_LINE_BUFFER_SIZE * DIV_ROUND_UP(frame_width, 16); -+} -+ -+static inline u32 size_h264d_lb_vsp_top(u32 frame_width) -+{ -+ return (DIV_ROUND_UP(frame_width, 16) << 7); -+} -+ -+static inline u32 size_h264d_lb_recon_dma_metadata_wr(u32 frame_height) -+{ -+ return ALIGN(frame_height, 16) * 32; -+} -+ -+static inline u32 size_h264d_qp(u32 frame_width, u32 frame_height) -+{ -+ return DIV_ROUND_UP(frame_width, 64) * DIV_ROUND_UP(frame_height, 64) * 128; -+} -+ -+int iris_vpu_buf_size(struct iris_inst *inst, enum iris_buffer_type buffer_type); - int iris_vpu_buf_count(struct iris_inst *inst, enum iris_buffer_type buffer_type); - - #endif --- -2.34.1 - diff --git a/patch/kernel/archive/sm8550-6.12/0020_media--iris--implement-vb2-ops-for-buf_queue-and-f.patch b/patch/kernel/archive/sm8550-6.12/0020_media--iris--implement-vb2-ops-for-buf_queue-and-f.patch deleted file mode 100644 index aa37cfade2d9..000000000000 --- a/patch/kernel/archive/sm8550-6.12/0020_media--iris--implement-vb2-ops-for-buf_queue-and-f.patch +++ /dev/null @@ -1,1478 +0,0 @@ -From 0d452286222b3592f297af958172da80dc574d5c Mon Sep 17 00:00:00 2001 -From: Dikshita Agarwal -Date: Fri, 7 Feb 2025 13:25:00 +0530 -Subject: [PATCH] media: iris: implement vb2 ops for buf_queue and firmware - response - -Implement the vb2 ops for the buf queue. These are the different buffer -attributes: -BUF_ATTR_DEFERRED - buffer queued by the client but not submitted to - firmware. -BUF_ATTR_PENDING_RELEASE - buffers requested to be released from - the firmware. -BUF_ATTR_QUEUED - buffers submitted to the firmware. -BUF_ATTR_DEQUEUED - buffers received from the firmware. -BUF_ATTR_BUFFER_DONE - buffers sent back to vb2. - -Reviewed-by: Hans Verkuil -Tested-by: Stefan Schmidt # x1e80100 (Dell XPS 13 9345) -Reviewed-by: Stefan Schmidt -Tested-by: Neil Armstrong # on SM8550-QRD -Tested-by: Neil Armstrong # on SM8550-HDK -Signed-off-by: Dikshita Agarwal -Link: https://lore.kernel.org/r/20250207-qcom-video-iris-v10-20-ab66eeffbd20@quicinc.com -Signed-off-by: Neil Armstrong ---- - drivers/media/platform/qcom/iris/Kconfig | 1 + - .../media/platform/qcom/iris/iris_buffer.c | 116 +++++++++++ - .../media/platform/qcom/iris/iris_buffer.h | 2 + - .../qcom/iris/iris_hfi_gen1_command.c | 53 +++++ - .../qcom/iris/iris_hfi_gen1_defines.h | 80 ++++++++ - .../qcom/iris/iris_hfi_gen1_response.c | 167 +++++++++++++++- - .../media/platform/qcom/iris/iris_hfi_gen2.h | 2 + - .../qcom/iris/iris_hfi_gen2_defines.h | 22 +++ - .../qcom/iris/iris_hfi_gen2_response.c | 183 +++++++++++++++++- - .../media/platform/qcom/iris/iris_instance.h | 8 + - drivers/media/platform/qcom/iris/iris_utils.c | 16 ++ - drivers/media/platform/qcom/iris/iris_utils.h | 16 ++ - drivers/media/platform/qcom/iris/iris_vb2.c | 98 +++++++++- - drivers/media/platform/qcom/iris/iris_vb2.h | 4 + - drivers/media/platform/qcom/iris/iris_vdec.c | 151 ++++++++++++++- - drivers/media/platform/qcom/iris/iris_vdec.h | 3 +- - drivers/media/platform/qcom/iris/iris_vidc.c | 14 ++ - 17 files changed, 916 insertions(+), 20 deletions(-) - -diff --git a/drivers/media/platform/qcom/iris/Kconfig b/drivers/media/platform/qcom/iris/Kconfig -index f92cc7fe9378..3c803a05305a 100644 ---- a/drivers/media/platform/qcom/iris/Kconfig -+++ b/drivers/media/platform/qcom/iris/Kconfig -@@ -5,6 +5,7 @@ config VIDEO_QCOM_IRIS - select V4L2_MEM2MEM_DEV - select QCOM_MDT_LOADER if ARCH_QCOM - select QCOM_SCM -+ select VIDEOBUF2_DMA_CONTIG - help - This is a V4L2 driver for Qualcomm iris video accelerator - hardware. It accelerates decoding operations on various -diff --git a/drivers/media/platform/qcom/iris/iris_buffer.c b/drivers/media/platform/qcom/iris/iris_buffer.c -index e9d372580b5f..de1267c387f1 100644 ---- a/drivers/media/platform/qcom/iris/iris_buffer.c -+++ b/drivers/media/platform/qcom/iris/iris_buffer.c -@@ -3,6 +3,7 @@ - * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. - */ - -+#include - #include - - #include "iris_buffer.h" -@@ -434,6 +435,36 @@ int iris_alloc_and_queue_persist_bufs(struct iris_inst *inst) - return 0; - } - -+int iris_queue_deferred_buffers(struct iris_inst *inst, enum iris_buffer_type buf_type) -+{ -+ struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; -+ struct v4l2_m2m_buffer *buffer, *n; -+ struct iris_buffer *buf; -+ int ret; -+ -+ if (buf_type == BUF_INPUT) { -+ v4l2_m2m_for_each_src_buf_safe(m2m_ctx, buffer, n) { -+ buf = to_iris_buffer(&buffer->vb); -+ if (!(buf->attr & BUF_ATTR_DEFERRED)) -+ continue; -+ ret = iris_queue_buffer(inst, buf); -+ if (ret) -+ return ret; -+ } -+ } else { -+ v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, buffer, n) { -+ buf = to_iris_buffer(&buffer->vb); -+ if (!(buf->attr & BUF_ATTR_DEFERRED)) -+ continue; -+ ret = iris_queue_buffer(inst, buf); -+ if (ret) -+ return ret; -+ } -+ } -+ -+ return 0; -+} -+ - void iris_vb2_queue_error(struct iris_inst *inst) - { - struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; -@@ -444,3 +475,88 @@ void iris_vb2_queue_error(struct iris_inst *inst) - q = v4l2_m2m_get_dst_vq(m2m_ctx); - vb2_queue_error(q); - } -+ -+static struct vb2_v4l2_buffer * -+iris_helper_find_buf(struct iris_inst *inst, u32 type, u32 idx) -+{ -+ struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; -+ -+ if (V4L2_TYPE_IS_OUTPUT(type)) -+ return v4l2_m2m_src_buf_remove_by_idx(m2m_ctx, idx); -+ else -+ return v4l2_m2m_dst_buf_remove_by_idx(m2m_ctx, idx); -+} -+ -+static void iris_get_ts_metadata(struct iris_inst *inst, u64 timestamp_ns, -+ struct vb2_v4l2_buffer *vbuf) -+{ -+ u32 mask = V4L2_BUF_FLAG_TIMECODE | V4L2_BUF_FLAG_TSTAMP_SRC_MASK; -+ u32 i; -+ -+ for (i = 0; i < ARRAY_SIZE(inst->tss); ++i) { -+ if (inst->tss[i].ts_ns != timestamp_ns) -+ continue; -+ -+ vbuf->flags &= ~mask; -+ vbuf->flags |= inst->tss[i].flags; -+ vbuf->timecode = inst->tss[i].tc; -+ return; -+ } -+ -+ vbuf->flags &= ~mask; -+ vbuf->flags |= inst->tss[inst->metadata_idx].flags; -+ vbuf->timecode = inst->tss[inst->metadata_idx].tc; -+} -+ -+int iris_vb2_buffer_done(struct iris_inst *inst, struct iris_buffer *buf) -+{ -+ struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; -+ struct vb2_v4l2_buffer *vbuf; -+ struct vb2_buffer *vb2; -+ u32 type, state; -+ -+ switch (buf->type) { -+ case BUF_INPUT: -+ type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; -+ break; -+ case BUF_OUTPUT: -+ type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; -+ break; -+ default: -+ return 0; /* Internal DPB Buffers */ -+ } -+ -+ vbuf = iris_helper_find_buf(inst, type, buf->index); -+ if (!vbuf) -+ return -EINVAL; -+ -+ vb2 = &vbuf->vb2_buf; -+ -+ if (buf->flags & V4L2_BUF_FLAG_ERROR) -+ state = VB2_BUF_STATE_ERROR; -+ else -+ state = VB2_BUF_STATE_DONE; -+ -+ vbuf->flags |= buf->flags; -+ -+ if (V4L2_TYPE_IS_CAPTURE(type)) { -+ vb2_set_plane_payload(vb2, 0, buf->data_size); -+ vbuf->sequence = inst->sequence_cap++; -+ iris_get_ts_metadata(inst, buf->timestamp, vbuf); -+ } else { -+ vbuf->sequence = inst->sequence_out++; -+ } -+ -+ if (vbuf->flags & V4L2_BUF_FLAG_LAST) { -+ if (!v4l2_m2m_has_stopped(m2m_ctx)) { -+ const struct v4l2_event ev = { .type = V4L2_EVENT_EOS }; -+ -+ v4l2_event_queue_fh(&inst->fh, &ev); -+ v4l2_m2m_mark_stopped(m2m_ctx); -+ } -+ } -+ vb2->timestamp = buf->timestamp; -+ v4l2_m2m_buf_done(vbuf, state); -+ -+ return 0; -+} -diff --git a/drivers/media/platform/qcom/iris/iris_buffer.h b/drivers/media/platform/qcom/iris/iris_buffer.h -index 73f3a16ff7a2..2c7432a59906 100644 ---- a/drivers/media/platform/qcom/iris/iris_buffer.h -+++ b/drivers/media/platform/qcom/iris/iris_buffer.h -@@ -109,6 +109,8 @@ int iris_destroy_internal_buffer(struct iris_inst *inst, struct iris_buffer *buf - int iris_destroy_internal_buffers(struct iris_inst *inst, u32 plane); - int iris_alloc_and_queue_persist_bufs(struct iris_inst *inst); - int iris_queue_buffer(struct iris_inst *inst, struct iris_buffer *buf); -+int iris_queue_deferred_buffers(struct iris_inst *inst, enum iris_buffer_type buf_type); -+int iris_vb2_buffer_done(struct iris_inst *inst, struct iris_buffer *buf); - void iris_vb2_queue_error(struct iris_inst *inst); - - #endif -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c -index 603ca485992d..03f7e6ea4bf3 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c -@@ -180,6 +180,10 @@ static int iris_hfi_gen1_session_stop(struct iris_inst *inst, u32 plane) - ret = iris_hfi_queue_cmd_write(core, &pkt, pkt.shdr.hdr.size); - if (!ret) - ret = iris_wait_for_session_response(inst, false); -+ iris_helper_buffers_done(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, -+ VB2_BUF_STATE_ERROR); -+ iris_helper_buffers_done(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, -+ VB2_BUF_STATE_ERROR); - } else if (inst->state == IRIS_INST_STREAMING) { - if (V4L2_TYPE_IS_OUTPUT(plane)) - flush_type = HFI_FLUSH_ALL; -@@ -201,6 +205,50 @@ static int iris_hfi_gen1_session_stop(struct iris_inst *inst, u32 plane) - return ret; - } - -+static int iris_hfi_gen1_queue_input_buffer(struct iris_inst *inst, struct iris_buffer *buf) -+{ -+ struct hfi_session_empty_buffer_compressed_pkt ip_pkt; -+ -+ ip_pkt.shdr.hdr.size = sizeof(struct hfi_session_empty_buffer_compressed_pkt); -+ ip_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_EMPTY_BUFFER; -+ ip_pkt.shdr.session_id = inst->session_id; -+ ip_pkt.time_stamp_hi = upper_32_bits(buf->timestamp); -+ ip_pkt.time_stamp_lo = lower_32_bits(buf->timestamp); -+ ip_pkt.flags = buf->flags; -+ ip_pkt.mark_target = 0; -+ ip_pkt.mark_data = 0; -+ ip_pkt.offset = buf->data_offset; -+ ip_pkt.alloc_len = buf->buffer_size; -+ ip_pkt.filled_len = buf->data_size; -+ ip_pkt.input_tag = buf->index; -+ ip_pkt.packet_buffer = buf->device_addr; -+ -+ return iris_hfi_queue_cmd_write(inst->core, &ip_pkt, ip_pkt.shdr.hdr.size); -+} -+ -+static int iris_hfi_gen1_queue_output_buffer(struct iris_inst *inst, struct iris_buffer *buf) -+{ -+ struct hfi_session_fill_buffer_pkt op_pkt; -+ -+ op_pkt.shdr.hdr.size = sizeof(struct hfi_session_fill_buffer_pkt); -+ op_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_FILL_BUFFER; -+ op_pkt.shdr.session_id = inst->session_id; -+ op_pkt.output_tag = buf->index; -+ op_pkt.packet_buffer = buf->device_addr; -+ op_pkt.extradata_buffer = 0; -+ op_pkt.alloc_len = buf->buffer_size; -+ op_pkt.filled_len = buf->data_size; -+ op_pkt.offset = buf->data_offset; -+ op_pkt.data = 0; -+ -+ if (buf->type == BUF_OUTPUT && iris_split_mode_enabled(inst)) -+ op_pkt.stream_id = 1; -+ else -+ op_pkt.stream_id = 0; -+ -+ return iris_hfi_queue_cmd_write(inst->core, &op_pkt, op_pkt.shdr.hdr.size); -+} -+ - static int iris_hfi_gen1_queue_internal_buffer(struct iris_inst *inst, struct iris_buffer *buf) - { - struct hfi_session_set_buffers_pkt *int_pkt; -@@ -240,6 +288,11 @@ static int iris_hfi_gen1_queue_internal_buffer(struct iris_inst *inst, struct ir - static int iris_hfi_gen1_session_queue_buffer(struct iris_inst *inst, struct iris_buffer *buf) - { - switch (buf->type) { -+ case BUF_INPUT: -+ return iris_hfi_gen1_queue_input_buffer(inst, buf); -+ case BUF_OUTPUT: -+ case BUF_DPB: -+ return iris_hfi_gen1_queue_output_buffer(inst, buf); - case BUF_PERSIST: - case BUF_BIN: - case BUF_SCRATCH_1: -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h -index cabd91eafc92..108449d703e1 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h -@@ -29,11 +29,14 @@ - #define HFI_CMD_SESSION_LOAD_RESOURCES 0x211001 - #define HFI_CMD_SESSION_START 0x211002 - #define HFI_CMD_SESSION_STOP 0x211003 -+#define HFI_CMD_SESSION_EMPTY_BUFFER 0x211004 -+#define HFI_CMD_SESSION_FILL_BUFFER 0x211005 - #define HFI_CMD_SESSION_FLUSH 0x211008 - #define HFI_CMD_SESSION_RELEASE_BUFFERS 0x21100b - #define HFI_CMD_SESSION_RELEASE_RESOURCES 0x21100c - - #define HFI_ERR_SESSION_UNSUPPORTED_SETTING 0x1008 -+#define HFI_ERR_SESSION_UNSUPPORTED_STREAM 0x100d - #define HFI_ERR_SESSION_UNSUPPORT_BUFFERTYPE 0x1010 - #define HFI_ERR_SESSION_INVALID_SCALE_FACTOR 0x1012 - #define HFI_ERR_SESSION_UPSCALE_NOT_SUPPORTED 0x1013 -@@ -41,6 +44,8 @@ - #define HFI_EVENT_SYS_ERROR 0x1 - #define HFI_EVENT_SESSION_ERROR 0x2 - -+#define HFI_BUFFERFLAG_TIMESTAMPINVALID 0x00000100 -+ - #define HFI_FLUSH_OUTPUT 0x1000002 - #define HFI_FLUSH_OUTPUT2 0x1000003 - #define HFI_FLUSH_ALL 0x1000004 -@@ -84,9 +89,19 @@ - #define HFI_MSG_SESSION_START 0x221002 - #define HFI_MSG_SESSION_STOP 0x221003 - #define HFI_MSG_SESSION_FLUSH 0x221006 -+#define HFI_MSG_SESSION_EMPTY_BUFFER 0x221007 -+#define HFI_MSG_SESSION_FILL_BUFFER 0x221008 - #define HFI_MSG_SESSION_RELEASE_RESOURCES 0x22100a - #define HFI_MSG_SESSION_RELEASE_BUFFERS 0x22100c - -+#define HFI_PICTURE_I 0x00000001 -+#define HFI_PICTURE_P 0x00000002 -+#define HFI_PICTURE_B 0x00000004 -+#define HFI_PICTURE_IDR 0x00000008 -+#define HFI_FRAME_NOTCODED 0x7f002000 -+#define HFI_FRAME_YUV 0x7f004000 -+#define HFI_UNUSED_PICT 0x10000000 -+ - struct hfi_pkt_hdr { - u32 size; - u32 pkt_type; -@@ -144,6 +159,34 @@ struct hfi_session_set_buffers_pkt { - u32 buffer_info[]; - }; - -+struct hfi_session_empty_buffer_compressed_pkt { -+ struct hfi_session_hdr_pkt shdr; -+ u32 time_stamp_hi; -+ u32 time_stamp_lo; -+ u32 flags; -+ u32 mark_target; -+ u32 mark_data; -+ u32 offset; -+ u32 alloc_len; -+ u32 filled_len; -+ u32 input_tag; -+ u32 packet_buffer; -+ u32 extradata_buffer; -+ u32 data; -+}; -+ -+struct hfi_session_fill_buffer_pkt { -+ struct hfi_session_hdr_pkt shdr; -+ u32 stream_id; -+ u32 offset; -+ u32 alloc_len; -+ u32 filled_len; -+ u32 output_tag; -+ u32 packet_buffer; -+ u32 extradata_buffer; -+ u32 data; -+}; -+ - struct hfi_session_flush_pkt { - struct hfi_session_hdr_pkt shdr; - u32 flush_type; -@@ -258,6 +301,43 @@ struct hfi_multi_stream { - u32 enable; - }; - -+struct hfi_msg_session_empty_buffer_done_pkt { -+ struct hfi_msg_session_hdr_pkt shdr; -+ u32 offset; -+ u32 filled_len; -+ u32 input_tag; -+ u32 packet_buffer; -+ u32 extradata_buffer; -+ u32 data[]; -+}; -+ -+struct hfi_msg_session_fbd_uncompressed_plane0_pkt { -+ struct hfi_session_hdr_pkt shdr; -+ u32 stream_id; -+ u32 view_id; -+ u32 error_type; -+ u32 time_stamp_hi; -+ u32 time_stamp_lo; -+ u32 flags; -+ u32 mark_target; -+ u32 mark_data; -+ u32 stats; -+ u32 alloc_len; -+ u32 filled_len; -+ u32 offset; -+ u32 frame_width; -+ u32 frame_height; -+ u32 start_x_coord; -+ u32 start_y_coord; -+ u32 input_tag; -+ u32 input_tag2; -+ u32 output_tag; -+ u32 picture_type; -+ u32 packet_buffer; -+ u32 extradata_buffer; -+ u32 data[]; -+}; -+ - struct hfi_msg_session_release_buffers_done_pkt { - struct hfi_msg_session_hdr_pkt shdr; - u32 num_buffers; -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c -index a84bb00388d9..23a8bf29e381 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c -@@ -3,6 +3,8 @@ - * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. - */ - -+#include -+ - #include "iris_hfi_gen1.h" - #include "iris_hfi_gen1_defines.h" - #include "iris_instance.h" -@@ -130,6 +132,143 @@ static void iris_hfi_gen1_sys_property_info(struct iris_core *core, void *packet - } - } - -+static void iris_hfi_gen1_session_etb_done(struct iris_inst *inst, void *packet) -+{ -+ struct hfi_msg_session_empty_buffer_done_pkt *pkt = packet; -+ struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; -+ struct v4l2_m2m_buffer *m2m_buffer, *n; -+ struct iris_buffer *buf = NULL; -+ bool found = false; -+ -+ v4l2_m2m_for_each_src_buf_safe(m2m_ctx, m2m_buffer, n) { -+ buf = to_iris_buffer(&m2m_buffer->vb); -+ if (buf->index == pkt->input_tag) { -+ found = true; -+ break; -+ } -+ } -+ if (!found) -+ goto error; -+ -+ if (pkt->shdr.error_type == HFI_ERR_SESSION_UNSUPPORTED_STREAM) { -+ buf->flags = V4L2_BUF_FLAG_ERROR; -+ iris_vb2_queue_error(inst); -+ iris_inst_change_state(inst, IRIS_INST_ERROR); -+ } -+ -+ if (!(buf->attr & BUF_ATTR_QUEUED)) -+ return; -+ -+ buf->attr &= ~BUF_ATTR_QUEUED; -+ -+ if (!(buf->attr & BUF_ATTR_BUFFER_DONE)) { -+ buf->attr |= BUF_ATTR_BUFFER_DONE; -+ iris_vb2_buffer_done(inst, buf); -+ } -+ -+ return; -+ -+error: -+ iris_inst_change_state(inst, IRIS_INST_ERROR); -+ dev_err(inst->core->dev, "error in etb done\n"); -+} -+ -+static void iris_hfi_gen1_session_ftb_done(struct iris_inst *inst, void *packet) -+{ -+ struct hfi_msg_session_fbd_uncompressed_plane0_pkt *pkt = packet; -+ struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; -+ struct v4l2_m2m_buffer *m2m_buffer, *n; -+ u32 timestamp_hi = pkt->time_stamp_hi; -+ u32 timestamp_lo = pkt->time_stamp_lo; -+ struct iris_core *core = inst->core; -+ u32 filled_len = pkt->filled_len; -+ u32 pic_type = pkt->picture_type; -+ u32 output_tag = pkt->output_tag; -+ struct iris_buffer *buf, *iter; -+ struct iris_buffers *buffers; -+ u32 offset = pkt->offset; -+ u64 timestamp_us = 0; -+ bool found = false; -+ u32 flags = 0; -+ -+ if (iris_split_mode_enabled(inst) && pkt->stream_id == 0) { -+ buffers = &inst->buffers[BUF_DPB]; -+ if (!buffers) -+ goto error; -+ -+ found = false; -+ list_for_each_entry(iter, &buffers->list, list) { -+ if (!(iter->attr & BUF_ATTR_QUEUED)) -+ continue; -+ -+ found = (iter->index == output_tag && -+ iter->data_offset == offset); -+ -+ if (found) { -+ buf = iter; -+ break; -+ } -+ } -+ } else { -+ v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, m2m_buffer, n) { -+ buf = to_iris_buffer(&m2m_buffer->vb); -+ if (!(buf->attr & BUF_ATTR_QUEUED)) -+ continue; -+ -+ found = (buf->index == output_tag && -+ buf->data_offset == offset); -+ -+ if (found) -+ break; -+ } -+ } -+ if (!found) -+ goto error; -+ -+ buf->data_offset = offset; -+ buf->data_size = filled_len; -+ -+ if (filled_len) { -+ timestamp_us = timestamp_hi; -+ timestamp_us = (timestamp_us << 32) | timestamp_lo; -+ } else { -+ flags |= V4L2_BUF_FLAG_LAST; -+ } -+ buf->timestamp = timestamp_us; -+ -+ switch (pic_type) { -+ case HFI_PICTURE_IDR: -+ case HFI_PICTURE_I: -+ flags |= V4L2_BUF_FLAG_KEYFRAME; -+ break; -+ case HFI_PICTURE_P: -+ flags |= V4L2_BUF_FLAG_PFRAME; -+ break; -+ case HFI_PICTURE_B: -+ flags |= V4L2_BUF_FLAG_BFRAME; -+ break; -+ case HFI_FRAME_NOTCODED: -+ case HFI_UNUSED_PICT: -+ case HFI_FRAME_YUV: -+ default: -+ break; -+ } -+ -+ buf->attr &= ~BUF_ATTR_QUEUED; -+ buf->attr |= BUF_ATTR_DEQUEUED; -+ buf->attr |= BUF_ATTR_BUFFER_DONE; -+ -+ buf->flags |= flags; -+ -+ iris_vb2_buffer_done(inst, buf); -+ -+ return; -+ -+error: -+ iris_inst_change_state(inst, IRIS_INST_ERROR); -+ dev_err(core->dev, "error in ftb done\n"); -+} -+ - struct iris_hfi_gen1_response_pkt_info { - u32 pkt; - u32 pkt_sz; -@@ -168,6 +307,14 @@ static const struct iris_hfi_gen1_response_pkt_info pkt_infos[] = { - .pkt = HFI_MSG_SESSION_STOP, - .pkt_sz = sizeof(struct hfi_msg_session_hdr_pkt), - }, -+ { -+ .pkt = HFI_MSG_SESSION_EMPTY_BUFFER, -+ .pkt_sz = sizeof(struct hfi_msg_session_empty_buffer_done_pkt), -+ }, -+ { -+ .pkt = HFI_MSG_SESSION_FILL_BUFFER, -+ .pkt_sz = sizeof(struct hfi_msg_session_fbd_uncompressed_plane0_pkt), -+ }, - { - .pkt = HFI_MSG_SESSION_FLUSH, - .pkt_sz = sizeof(struct hfi_msg_session_flush_done_pkt), -@@ -238,15 +385,21 @@ static void iris_hfi_gen1_handle_response(struct iris_core *core, void *response - } - - mutex_lock(&inst->lock); -- struct hfi_msg_session_hdr_pkt *shdr; -+ if (hdr->pkt_type == HFI_MSG_SESSION_EMPTY_BUFFER) { -+ iris_hfi_gen1_session_etb_done(inst, hdr); -+ } else if (hdr->pkt_type == HFI_MSG_SESSION_FILL_BUFFER) { -+ iris_hfi_gen1_session_ftb_done(inst, hdr); -+ } else { -+ struct hfi_msg_session_hdr_pkt *shdr; - -- shdr = (struct hfi_msg_session_hdr_pkt *)hdr; -- if (shdr->error_type != HFI_ERR_NONE) -- iris_inst_change_state(inst, IRIS_INST_ERROR); -+ shdr = (struct hfi_msg_session_hdr_pkt *)hdr; -+ if (shdr->error_type != HFI_ERR_NONE) -+ iris_inst_change_state(inst, IRIS_INST_ERROR); - -- done = pkt_info->pkt == HFI_MSG_SESSION_FLUSH ? -- &inst->flush_completion : &inst->completion; -- complete(done); -+ done = pkt_info->pkt == HFI_MSG_SESSION_FLUSH ? -+ &inst->flush_completion : &inst->completion; -+ complete(done); -+ } - mutex_unlock(&inst->lock); - - break; -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2.h b/drivers/media/platform/qcom/iris/iris_hfi_gen2.h -index 0a946c1e3a4c..b9d3749a10ef 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen2.h -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2.h -@@ -20,6 +20,7 @@ struct iris_core; - * @packet: HFI packet - * @ipsc_properties_set: boolean to set ipsc properties to fw - * @opsc_properties_set: boolean to set opsc properties to fw -+ * @hfi_frame_info: structure of frame info - * @src_subcr_params: subscription params to fw on input port - * @dst_subcr_params: subscription params to fw on output port - */ -@@ -28,6 +29,7 @@ struct iris_inst_hfi_gen2 { - struct iris_hfi_header *packet; - bool ipsc_properties_set; - bool opsc_properties_set; -+ struct iris_hfi_frame_info hfi_frame_info; - struct hfi_subscription_params src_subcr_params; - struct hfi_subscription_params dst_subcr_params; - }; -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h -index afbdf1f1e68a..8a9f2b5517ad 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h -@@ -71,6 +71,12 @@ - #define HFI_SYS_ERROR_WD_TIMEOUT 0x05000001 - #define HFI_SYSTEM_ERROR_END 0x05FFFFFF - -+#define HFI_INFORMATION_BEGIN 0x06000000 -+#define HFI_INFO_UNSUPPORTED 0x06000001 -+#define HFI_INFO_DATA_CORRUPT 0x06000002 -+#define HFI_INFO_BUFFER_OVERFLOW 0x06000004 -+#define HFI_INFORMATION_END 0x06FFFFFF -+ - enum hfi_property_mode_type { - HFI_MODE_PORT_SETTINGS_CHANGE = 0x00000001, - HFI_MODE_PROPERTY = 0x00000002, -@@ -92,6 +98,15 @@ enum hfi_codec_type { - HFI_CODEC_ENCODE_AVC = 2, - }; - -+enum hfi_picture_type { -+ HFI_PICTURE_IDR = 0x00000001, -+ HFI_PICTURE_P = 0x00000002, -+ HFI_PICTURE_B = 0x00000004, -+ HFI_PICTURE_I = 0x00000008, -+ HFI_PICTURE_CRA = 0x00000010, -+ HFI_PICTURE_BLA = 0x00000020, -+}; -+ - enum hfi_buffer_type { - HFI_BUFFER_BITSTREAM = 0x00000001, - HFI_BUFFER_RAW = 0x00000002, -@@ -115,6 +130,13 @@ enum hfi_buffer_host_flags { - HFI_BUF_HOST_FLAGS_CB_NON_SECURE = 0x00000200, - }; - -+enum hfi_buffer_firmware_flags { -+ HFI_BUF_FW_FLAG_RELEASE_DONE = 0x00000001, -+ HFI_BUF_FW_FLAG_READONLY = 0x00000010, -+ HFI_BUF_FW_FLAG_LAST = 0x10000000, -+ HFI_BUF_FW_FLAG_PSC_LAST = 0x20000000, -+}; -+ - enum hfi_packet_firmware_flags { - HFI_FW_FLAGS_SUCCESS = 0x00000001, - HFI_FW_FLAGS_INFORMATION = 0x00000002, -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c -index 9f3764f1903b..e8d8caeef021 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c -@@ -3,6 +3,8 @@ - * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. - */ - -+#include -+ - #include "iris_hfi_gen2.h" - #include "iris_hfi_gen2_defines.h" - #include "iris_hfi_gen2_packet.h" -@@ -81,6 +83,29 @@ static bool iris_hfi_gen2_is_valid_hfi_port(u32 port, u32 buffer_type) - return true; - } - -+static int iris_hfi_gen2_get_driver_buffer_flags(struct iris_inst *inst, u32 hfi_flags) -+{ -+ u32 keyframe = HFI_PICTURE_IDR | HFI_PICTURE_I | HFI_PICTURE_CRA | HFI_PICTURE_BLA; -+ struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); -+ u32 driver_flags = 0; -+ -+ if (inst_hfi_gen2->hfi_frame_info.picture_type & keyframe) -+ driver_flags |= V4L2_BUF_FLAG_KEYFRAME; -+ else if (inst_hfi_gen2->hfi_frame_info.picture_type & HFI_PICTURE_P) -+ driver_flags |= V4L2_BUF_FLAG_PFRAME; -+ else if (inst_hfi_gen2->hfi_frame_info.picture_type & HFI_PICTURE_B) -+ driver_flags |= V4L2_BUF_FLAG_BFRAME; -+ -+ if (inst_hfi_gen2->hfi_frame_info.data_corrupt || inst_hfi_gen2->hfi_frame_info.overflow) -+ driver_flags |= V4L2_BUF_FLAG_ERROR; -+ -+ if (hfi_flags & HFI_BUF_FW_FLAG_LAST || -+ hfi_flags & HFI_BUF_FW_FLAG_PSC_LAST) -+ driver_flags |= V4L2_BUF_FLAG_LAST; -+ -+ return driver_flags; -+} -+ - static bool iris_hfi_gen2_validate_packet_payload(struct iris_hfi_packet *pkt) - { - u32 payload_size = 0; -@@ -154,6 +179,37 @@ static int iris_hfi_gen2_validate_hdr_packet(struct iris_core *core, struct iris - return 0; - } - -+static int iris_hfi_gen2_handle_session_info(struct iris_inst *inst, -+ struct iris_hfi_packet *pkt) -+{ -+ struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); -+ struct iris_core *core = inst->core; -+ int ret = 0; -+ char *info; -+ -+ switch (pkt->type) { -+ case HFI_INFO_UNSUPPORTED: -+ info = "unsupported"; -+ break; -+ case HFI_INFO_DATA_CORRUPT: -+ info = "data corrupt"; -+ inst_hfi_gen2->hfi_frame_info.data_corrupt = 1; -+ break; -+ case HFI_INFO_BUFFER_OVERFLOW: -+ info = "buffer overflow"; -+ inst_hfi_gen2->hfi_frame_info.overflow = 1; -+ break; -+ default: -+ info = "unknown"; -+ break; -+ } -+ -+ dev_dbg(core->dev, "session info received %#x: %s\n", -+ pkt->type, info); -+ -+ return ret; -+} -+ - static int iris_hfi_gen2_handle_session_error(struct iris_inst *inst, - struct iris_hfi_packet *pkt) - { -@@ -237,19 +293,108 @@ static void iris_hfi_gen2_handle_session_close(struct iris_inst *inst, - complete(&inst->completion); - } - -+static int iris_hfi_gen2_handle_input_buffer(struct iris_inst *inst, -+ struct iris_hfi_buffer *buffer) -+{ -+ struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; -+ struct v4l2_m2m_buffer *m2m_buffer, *n; -+ struct iris_buffer *buf; -+ bool found = false; -+ -+ v4l2_m2m_for_each_src_buf_safe(m2m_ctx, m2m_buffer, n) { -+ buf = to_iris_buffer(&m2m_buffer->vb); -+ if (buf->index == buffer->index) { -+ found = true; -+ break; -+ } -+ } -+ if (!found) -+ return -EINVAL; -+ -+ if (!(buf->attr & BUF_ATTR_QUEUED)) -+ return -EINVAL; -+ -+ buf->attr &= ~BUF_ATTR_QUEUED; -+ buf->attr |= BUF_ATTR_DEQUEUED; -+ -+ buf->flags = iris_hfi_gen2_get_driver_buffer_flags(inst, buffer->flags); -+ -+ return 0; -+} -+ -+static int iris_hfi_gen2_handle_output_buffer(struct iris_inst *inst, -+ struct iris_hfi_buffer *hfi_buffer) -+{ -+ struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; -+ struct v4l2_m2m_buffer *m2m_buffer, *n; -+ struct iris_buffer *buf; -+ bool found = false; -+ -+ v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, m2m_buffer, n) { -+ buf = to_iris_buffer(&m2m_buffer->vb); -+ if (buf->index == hfi_buffer->index && -+ buf->device_addr == hfi_buffer->base_address && -+ buf->data_offset == hfi_buffer->data_offset) { -+ found = true; -+ break; -+ } -+ } -+ if (!found) -+ return -EINVAL; -+ -+ if (!(buf->attr & BUF_ATTR_QUEUED)) -+ return -EINVAL; -+ -+ buf->data_offset = hfi_buffer->data_offset; -+ buf->data_size = hfi_buffer->data_size; -+ buf->timestamp = hfi_buffer->timestamp; -+ -+ buf->attr &= ~BUF_ATTR_QUEUED; -+ buf->attr |= BUF_ATTR_DEQUEUED; -+ -+ buf->flags = iris_hfi_gen2_get_driver_buffer_flags(inst, hfi_buffer->flags); -+ -+ return 0; -+} -+ -+static void iris_hfi_gen2_handle_dequeue_buffers(struct iris_inst *inst) -+{ -+ struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; -+ struct v4l2_m2m_buffer *buffer, *n; -+ struct iris_buffer *buf = NULL; -+ -+ v4l2_m2m_for_each_src_buf_safe(m2m_ctx, buffer, n) { -+ buf = to_iris_buffer(&buffer->vb); -+ if (buf->attr & BUF_ATTR_DEQUEUED) { -+ buf->attr &= ~BUF_ATTR_DEQUEUED; -+ if (!(buf->attr & BUF_ATTR_BUFFER_DONE)) { -+ buf->attr |= BUF_ATTR_BUFFER_DONE; -+ iris_vb2_buffer_done(inst, buf); -+ } -+ } -+ } -+ -+ v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, buffer, n) { -+ buf = to_iris_buffer(&buffer->vb); -+ if (buf->attr & BUF_ATTR_DEQUEUED) { -+ buf->attr &= ~BUF_ATTR_DEQUEUED; -+ if (!(buf->attr & BUF_ATTR_BUFFER_DONE)) { -+ buf->attr |= BUF_ATTR_BUFFER_DONE; -+ iris_vb2_buffer_done(inst, buf); -+ } -+ } -+ } -+} -+ - static int iris_hfi_gen2_handle_release_internal_buffer(struct iris_inst *inst, - struct iris_hfi_buffer *buffer) - { -+ u32 buf_type = iris_hfi_gen2_buf_type_to_driver(buffer->type); -+ struct iris_buffers *buffers = &inst->buffers[buf_type]; - struct iris_buffer *buf, *iter; -- struct iris_buffers *buffers; -- u32 buf_type; -+ bool found = false; - int ret = 0; -- bool found; - -- buf_type = iris_hfi_gen2_buf_type_to_driver(buffer->type); -- buffers = &inst->buffers[buf_type]; -- -- found = false; - list_for_each_entry(iter, &buffers->list, list) { - if (iter->device_addr == buffer->base_address) { - found = true; -@@ -261,7 +406,6 @@ static int iris_hfi_gen2_handle_release_internal_buffer(struct iris_inst *inst, - return -EINVAL; - - buf->attr &= ~BUF_ATTR_QUEUED; -- - if (buf->attr & BUF_ATTR_PENDING_RELEASE) - ret = iris_destroy_internal_buffer(inst, buf); - -@@ -288,7 +432,12 @@ static int iris_hfi_gen2_handle_session_buffer(struct iris_inst *inst, - if (!iris_hfi_gen2_is_valid_hfi_port(pkt->port, buffer->type)) - return 0; - -- return iris_hfi_gen2_handle_release_internal_buffer(inst, buffer); -+ if (buffer->type == HFI_BUFFER_BITSTREAM) -+ return iris_hfi_gen2_handle_input_buffer(inst, buffer); -+ else if (buffer->type == HFI_BUFFER_RAW) -+ return iris_hfi_gen2_handle_output_buffer(inst, buffer); -+ else -+ return iris_hfi_gen2_handle_release_internal_buffer(inst, buffer); - } - - static int iris_hfi_gen2_handle_session_command(struct iris_inst *inst, -@@ -350,6 +499,12 @@ static int iris_hfi_gen2_handle_session_property(struct iris_inst *inst, - case HFI_PROP_LEVEL: - inst_hfi_gen2->src_subcr_params.level = pkt->payload[0]; - break; -+ case HFI_PROP_PICTURE_TYPE: -+ inst_hfi_gen2->hfi_frame_info.picture_type = pkt->payload[0]; -+ break; -+ case HFI_PROP_NO_OUTPUT: -+ inst_hfi_gen2->hfi_frame_info.no_output = 1; -+ break; - case HFI_PROP_QUALITY_MODE: - case HFI_PROP_STAGE: - case HFI_PROP_PIPE: -@@ -436,14 +591,18 @@ static int iris_hfi_gen2_handle_system_response(struct iris_core *core, - static int iris_hfi_gen2_handle_session_response(struct iris_core *core, - struct iris_hfi_header *hdr) - { -+ struct iris_inst_hfi_gen2 *inst_hfi_gen2; - struct iris_hfi_packet *packet; - struct iris_inst *inst; -+ bool dequeue = false; - int ret = 0; - u32 i, j; - u8 *pkt; - static const struct iris_hfi_gen2_inst_hfi_range range[] = { - {HFI_SESSION_ERROR_BEGIN, HFI_SESSION_ERROR_END, - iris_hfi_gen2_handle_session_error}, -+ {HFI_INFORMATION_BEGIN, HFI_INFORMATION_END, -+ iris_hfi_gen2_handle_session_info}, - {HFI_PROP_BEGIN, HFI_PROP_END, - iris_hfi_gen2_handle_session_property}, - {HFI_CMD_BEGIN, HFI_CMD_END, -@@ -455,6 +614,8 @@ static int iris_hfi_gen2_handle_session_response(struct iris_core *core, - return -EINVAL; - - mutex_lock(&inst->lock); -+ inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); -+ memset(&inst_hfi_gen2->hfi_frame_info, 0, sizeof(struct iris_hfi_frame_info)); - - pkt = (u8 *)((u8 *)hdr + sizeof(*hdr)); - for (i = 0; i < ARRAY_SIZE(range); i++) { -@@ -465,6 +626,7 @@ static int iris_hfi_gen2_handle_session_response(struct iris_core *core, - iris_hfi_gen2_handle_session_error(inst, packet); - - if (packet->type > range[i].begin && packet->type < range[i].end) { -+ dequeue |= (packet->type == HFI_CMD_BUFFER); - ret = range[i].handle(inst, packet); - if (ret) - iris_inst_change_state(inst, IRIS_INST_ERROR); -@@ -473,6 +635,9 @@ static int iris_hfi_gen2_handle_session_response(struct iris_core *core, - } - } - -+ if (dequeue) -+ iris_hfi_gen2_handle_dequeue_buffers(inst); -+ - mutex_unlock(&inst->lock); - - return ret; -diff --git a/drivers/media/platform/qcom/iris/iris_instance.h b/drivers/media/platform/qcom/iris/iris_instance.h -index 6b88daf31011..2886491ad59f 100644 ---- a/drivers/media/platform/qcom/iris/iris_instance.h -+++ b/drivers/media/platform/qcom/iris/iris_instance.h -@@ -34,6 +34,10 @@ - * @once_per_session_set: boolean to set once per session property - * @m2m_dev: a reference to m2m device structure - * @m2m_ctx: a reference to m2m context structure -+ * @sequence_cap: a sequence counter for capture queue -+ * @sequence_out: a sequence counter for output queue -+ * @tss: timestamp metadata -+ * @metadata_idx: index for metadata buffer - */ - - struct iris_inst { -@@ -56,6 +60,10 @@ struct iris_inst { - bool once_per_session_set; - struct v4l2_m2m_dev *m2m_dev; - struct v4l2_m2m_ctx *m2m_ctx; -+ u32 sequence_cap; -+ u32 sequence_out; -+ struct iris_ts_metadata tss[VIDEO_MAX_FRAME]; -+ u32 metadata_idx; - }; - - #endif -diff --git a/drivers/media/platform/qcom/iris/iris_utils.c b/drivers/media/platform/qcom/iris/iris_utils.c -index 8bcfa97db97d..83c70d6a2d90 100644 ---- a/drivers/media/platform/qcom/iris/iris_utils.c -+++ b/drivers/media/platform/qcom/iris/iris_utils.c -@@ -4,6 +4,7 @@ - */ - - #include -+#include - - #include "iris_instance.h" - #include "iris_utils.h" -@@ -36,6 +37,21 @@ bool iris_split_mode_enabled(struct iris_inst *inst) - return inst->fmt_dst->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_NV12; - } - -+void iris_helper_buffers_done(struct iris_inst *inst, unsigned int type, -+ enum vb2_buffer_state state) -+{ -+ struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; -+ struct vb2_v4l2_buffer *buf; -+ -+ if (V4L2_TYPE_IS_OUTPUT(type)) { -+ while ((buf = v4l2_m2m_src_buf_remove(m2m_ctx))) -+ v4l2_m2m_buf_done(buf, state); -+ } else if (V4L2_TYPE_IS_CAPTURE(type)) { -+ while ((buf = v4l2_m2m_dst_buf_remove(m2m_ctx))) -+ v4l2_m2m_buf_done(buf, state); -+ } -+} -+ - int iris_wait_for_session_response(struct iris_inst *inst, bool is_flush) - { - struct iris_core *core = inst->core; -diff --git a/drivers/media/platform/qcom/iris/iris_utils.h b/drivers/media/platform/qcom/iris/iris_utils.h -index 3400847f5e72..49869cf7a376 100644 ---- a/drivers/media/platform/qcom/iris/iris_utils.h -+++ b/drivers/media/platform/qcom/iris/iris_utils.h -@@ -16,6 +16,20 @@ struct iris_hfi_rect_desc { - u32 height; - }; - -+struct iris_hfi_frame_info { -+ u32 picture_type; -+ u32 no_output; -+ u32 data_corrupt; -+ u32 overflow; -+}; -+ -+struct iris_ts_metadata { -+ u64 ts_ns; -+ u64 ts_us; -+ u32 flags; -+ struct v4l2_timecode tc; -+}; -+ - #define NUM_MBS_PER_FRAME(height, width) \ - (DIV_ROUND_UP(height, 16) * DIV_ROUND_UP(width, 16)) - -@@ -32,6 +46,8 @@ bool iris_res_is_less_than(u32 width, u32 height, - int iris_get_mbpf(struct iris_inst *inst); - bool iris_split_mode_enabled(struct iris_inst *inst); - struct iris_inst *iris_get_instance(struct iris_core *core, u32 session_id); -+void iris_helper_buffers_done(struct iris_inst *inst, unsigned int type, -+ enum vb2_buffer_state state); - int iris_wait_for_session_response(struct iris_inst *inst, bool is_flush); - - #endif -diff --git a/drivers/media/platform/qcom/iris/iris_vb2.c b/drivers/media/platform/qcom/iris/iris_vb2.c -index b93da860d336..770e51f9ef91 100644 ---- a/drivers/media/platform/qcom/iris/iris_vb2.c -+++ b/drivers/media/platform/qcom/iris/iris_vb2.c -@@ -3,10 +3,23 @@ - * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. - */ - -+#include -+#include -+ - #include "iris_instance.h" - #include "iris_vb2.h" - #include "iris_vdec.h" - -+int iris_vb2_buf_init(struct vb2_buffer *vb2) -+{ -+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb2); -+ struct iris_buffer *buf = to_iris_buffer(vbuf); -+ -+ buf->device_addr = vb2_dma_contig_plane_dma_addr(vb2, 0); -+ -+ return 0; -+} -+ - int iris_vb2_queue_setup(struct vb2_queue *q, - unsigned int *num_buffers, unsigned int *num_planes, - unsigned int sizes[], struct device *alloc_devs[]) -@@ -60,6 +73,7 @@ int iris_vb2_queue_setup(struct vb2_queue *q, - - int iris_vb2_start_streaming(struct vb2_queue *q, unsigned int count) - { -+ enum iris_buffer_type buf_type; - struct iris_inst *inst; - int ret = 0; - -@@ -87,11 +101,18 @@ int iris_vb2_start_streaming(struct vb2_queue *q, unsigned int count) - if (ret) - goto error; - -+ buf_type = iris_v4l2_type_to_driver(q->type); -+ -+ ret = iris_queue_deferred_buffers(inst, buf_type); -+ if (ret) -+ goto error; -+ - mutex_unlock(&inst->lock); - - return ret; - - error: -+ iris_helper_buffers_done(inst, q->type, VB2_BUF_STATE_QUEUED); - iris_inst_change_state(inst, IRIS_INST_ERROR); - mutex_unlock(&inst->lock); - -@@ -101,6 +122,7 @@ int iris_vb2_start_streaming(struct vb2_queue *q, unsigned int count) - void iris_vb2_stop_streaming(struct vb2_queue *q) - { - struct iris_inst *inst; -+ int ret = 0; - - inst = vb2_get_drv_priv(q); - -@@ -113,8 +135,82 @@ void iris_vb2_stop_streaming(struct vb2_queue *q) - !V4L2_TYPE_IS_CAPTURE(q->type)) - goto exit; - -- iris_vdec_session_streamoff(inst, q->type); -+ ret = iris_vdec_session_streamoff(inst, q->type); -+ if (ret) -+ goto exit; -+ -+exit: -+ iris_helper_buffers_done(inst, q->type, VB2_BUF_STATE_ERROR); -+ if (ret) -+ iris_inst_change_state(inst, IRIS_INST_ERROR); -+ -+ mutex_unlock(&inst->lock); -+} -+ -+int iris_vb2_buf_prepare(struct vb2_buffer *vb) -+{ -+ struct iris_inst *inst = vb2_get_drv_priv(vb->vb2_queue); -+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); -+ -+ if (V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) { -+ if (vbuf->field == V4L2_FIELD_ANY) -+ vbuf->field = V4L2_FIELD_NONE; -+ if (vbuf->field != V4L2_FIELD_NONE) -+ return -EINVAL; -+ } -+ -+ if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && -+ vb2_plane_size(vb, 0) < iris_get_buffer_size(inst, BUF_OUTPUT)) -+ return -EINVAL; -+ if (vb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE && -+ vb2_plane_size(vb, 0) < iris_get_buffer_size(inst, BUF_INPUT)) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+int iris_vb2_buf_out_validate(struct vb2_buffer *vb) -+{ -+ struct vb2_v4l2_buffer *v4l2_buf = to_vb2_v4l2_buffer(vb); -+ -+ v4l2_buf->field = V4L2_FIELD_NONE; -+ -+ return 0; -+} -+ -+void iris_vb2_buf_queue(struct vb2_buffer *vb2) -+{ -+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb2); -+ struct v4l2_m2m_ctx *m2m_ctx; -+ struct iris_inst *inst; -+ int ret = 0; -+ -+ inst = vb2_get_drv_priv(vb2->vb2_queue); -+ -+ mutex_lock(&inst->lock); -+ if (inst->state == IRIS_INST_ERROR) { -+ ret = -EBUSY; -+ goto exit; -+ } -+ -+ if (vbuf->field == V4L2_FIELD_ANY) -+ vbuf->field = V4L2_FIELD_NONE; -+ -+ m2m_ctx = inst->m2m_ctx; -+ -+ if (!vb2->planes[0].bytesused && V4L2_TYPE_IS_OUTPUT(vb2->type)) { -+ ret = -EINVAL; -+ goto exit; -+ } -+ -+ v4l2_m2m_buf_queue(m2m_ctx, vbuf); -+ -+ ret = iris_vdec_qbuf(inst, vbuf); - - exit: -+ if (ret) { -+ iris_inst_change_state(inst, IRIS_INST_ERROR); -+ v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR); -+ } - mutex_unlock(&inst->lock); - } -diff --git a/drivers/media/platform/qcom/iris/iris_vb2.h b/drivers/media/platform/qcom/iris/iris_vb2.h -index 3906510fa71f..a88565fdd3e4 100644 ---- a/drivers/media/platform/qcom/iris/iris_vb2.h -+++ b/drivers/media/platform/qcom/iris/iris_vb2.h -@@ -6,10 +6,14 @@ - #ifndef __IRIS_VB2_H__ - #define __IRIS_VB2_H__ - -+int iris_vb2_buf_init(struct vb2_buffer *vb2); - int iris_vb2_queue_setup(struct vb2_queue *q, - unsigned int *num_buffers, unsigned int *num_planes, - unsigned int sizes[], struct device *alloc_devs[]); - int iris_vb2_start_streaming(struct vb2_queue *q, unsigned int count); - void iris_vb2_stop_streaming(struct vb2_queue *q); -+int iris_vb2_buf_prepare(struct vb2_buffer *vb); -+int iris_vb2_buf_out_validate(struct vb2_buffer *vb); -+void iris_vb2_buf_queue(struct vb2_buffer *vb2); - - #endif -diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c b/drivers/media/platform/qcom/iris/iris_vdec.c -index 8d489530da31..d6b092314b34 100644 ---- a/drivers/media/platform/qcom/iris/iris_vdec.c -+++ b/drivers/media/platform/qcom/iris/iris_vdec.c -@@ -223,6 +223,68 @@ int iris_vdec_subscribe_event(struct iris_inst *inst, const struct v4l2_event_su - return ret; - } - -+static int iris_vdec_get_num_queued_buffers(struct iris_inst *inst, -+ enum iris_buffer_type type) -+{ -+ struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; -+ struct v4l2_m2m_buffer *buffer, *n; -+ struct iris_buffer *buf; -+ u32 count = 0; -+ -+ switch (type) { -+ case BUF_INPUT: -+ v4l2_m2m_for_each_src_buf_safe(m2m_ctx, buffer, n) { -+ buf = to_iris_buffer(&buffer->vb); -+ if (!(buf->attr & BUF_ATTR_QUEUED)) -+ continue; -+ count++; -+ } -+ return count; -+ case BUF_OUTPUT: -+ v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, buffer, n) { -+ buf = to_iris_buffer(&buffer->vb); -+ if (!(buf->attr & BUF_ATTR_QUEUED)) -+ continue; -+ count++; -+ } -+ return count; -+ default: -+ return count; -+ } -+} -+ -+static void iris_vdec_flush_deferred_buffers(struct iris_inst *inst, -+ enum iris_buffer_type type) -+{ -+ struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; -+ struct v4l2_m2m_buffer *buffer, *n; -+ struct iris_buffer *buf; -+ -+ if (type == BUF_INPUT) { -+ v4l2_m2m_for_each_src_buf_safe(m2m_ctx, buffer, n) { -+ buf = to_iris_buffer(&buffer->vb); -+ if (buf->attr & BUF_ATTR_DEFERRED) { -+ if (!(buf->attr & BUF_ATTR_BUFFER_DONE)) { -+ buf->attr |= BUF_ATTR_BUFFER_DONE; -+ buf->data_size = 0; -+ iris_vb2_buffer_done(inst, buf); -+ } -+ } -+ } -+ } else { -+ v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, buffer, n) { -+ buf = to_iris_buffer(&buffer->vb); -+ if (buf->attr & BUF_ATTR_DEFERRED) { -+ if (!(buf->attr & BUF_ATTR_BUFFER_DONE)) { -+ buf->attr |= BUF_ATTR_BUFFER_DONE; -+ buf->data_size = 0; -+ iris_vb2_buffer_done(inst, buf); -+ } -+ } -+ } -+ } -+} -+ - static void iris_vdec_kill_session(struct iris_inst *inst) - { - const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; -@@ -234,23 +296,47 @@ static void iris_vdec_kill_session(struct iris_inst *inst) - iris_inst_change_state(inst, IRIS_INST_ERROR); - } - --void iris_vdec_session_streamoff(struct iris_inst *inst, u32 plane) -+int iris_vdec_session_streamoff(struct iris_inst *inst, u32 plane) - { - const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; -+ enum iris_buffer_type buffer_type; -+ u32 count; - int ret; - -+ switch (plane) { -+ case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: -+ buffer_type = BUF_INPUT; -+ break; -+ case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: -+ buffer_type = BUF_OUTPUT; -+ break; -+ default: -+ return -EINVAL; -+ } -+ - ret = hfi_ops->session_stop(inst, plane); - if (ret) - goto error; - -+ count = iris_vdec_get_num_queued_buffers(inst, buffer_type); -+ if (count) { -+ ret = -EINVAL; -+ goto error; -+ } -+ - ret = iris_inst_state_change_streamoff(inst, plane); - if (ret) - goto error; - -- return; -+ iris_vdec_flush_deferred_buffers(inst, buffer_type); -+ -+ return 0; - - error: - iris_vdec_kill_session(inst); -+ iris_vdec_flush_deferred_buffers(inst, buffer_type); -+ -+ return ret; - } - - static int iris_vdec_process_streamon_input(struct iris_inst *inst) -@@ -340,3 +426,64 @@ int iris_vdec_streamon_output(struct iris_inst *inst) - - return ret; - } -+ -+static int -+iris_vdec_vb2_buffer_to_driver(struct vb2_buffer *vb2, struct iris_buffer *buf) -+{ -+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb2); -+ -+ buf->type = iris_v4l2_type_to_driver(vb2->type); -+ buf->index = vb2->index; -+ buf->fd = vb2->planes[0].m.fd; -+ buf->buffer_size = vb2->planes[0].length; -+ buf->data_offset = vb2->planes[0].data_offset; -+ buf->data_size = vb2->planes[0].bytesused - vb2->planes[0].data_offset; -+ buf->flags = vbuf->flags; -+ buf->timestamp = vb2->timestamp; -+ buf->attr = 0; -+ -+ return 0; -+} -+ -+static void -+iris_set_ts_metadata(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf) -+{ -+ u32 mask = V4L2_BUF_FLAG_TIMECODE | V4L2_BUF_FLAG_TSTAMP_SRC_MASK; -+ struct vb2_buffer *vb = &vbuf->vb2_buf; -+ u64 ts_us = vb->timestamp; -+ -+ if (inst->metadata_idx >= ARRAY_SIZE(inst->tss)) -+ inst->metadata_idx = 0; -+ -+ do_div(ts_us, NSEC_PER_USEC); -+ -+ inst->tss[inst->metadata_idx].flags = vbuf->flags & mask; -+ inst->tss[inst->metadata_idx].tc = vbuf->timecode; -+ inst->tss[inst->metadata_idx].ts_us = ts_us; -+ inst->tss[inst->metadata_idx].ts_ns = vb->timestamp; -+ -+ inst->metadata_idx++; -+} -+ -+int iris_vdec_qbuf(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf) -+{ -+ struct iris_buffer *buf = to_iris_buffer(vbuf); -+ struct vb2_buffer *vb2 = &vbuf->vb2_buf; -+ struct vb2_queue *q; -+ int ret; -+ -+ ret = iris_vdec_vb2_buffer_to_driver(vb2, buf); -+ if (ret) -+ return ret; -+ -+ if (buf->type == BUF_INPUT) -+ iris_set_ts_metadata(inst, vbuf); -+ -+ q = v4l2_m2m_get_vq(inst->m2m_ctx, vb2->type); -+ if (!vb2_is_streaming(q)) { -+ buf->attr |= BUF_ATTR_DEFERRED; -+ return 0; -+ } -+ -+ return iris_queue_buffer(inst, buf); -+} -diff --git a/drivers/media/platform/qcom/iris/iris_vdec.h b/drivers/media/platform/qcom/iris/iris_vdec.h -index a17bb817b6e5..998d4970a42b 100644 ---- a/drivers/media/platform/qcom/iris/iris_vdec.h -+++ b/drivers/media/platform/qcom/iris/iris_vdec.h -@@ -16,6 +16,7 @@ int iris_vdec_s_fmt(struct iris_inst *inst, struct v4l2_format *f); - int iris_vdec_subscribe_event(struct iris_inst *inst, const struct v4l2_event_subscription *sub); - int iris_vdec_streamon_input(struct iris_inst *inst); - int iris_vdec_streamon_output(struct iris_inst *inst); --void iris_vdec_session_streamoff(struct iris_inst *inst, u32 plane); -+int iris_vdec_qbuf(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf); -+int iris_vdec_session_streamoff(struct iris_inst *inst, u32 plane); - - #endif -diff --git a/drivers/media/platform/qcom/iris/iris_vidc.c b/drivers/media/platform/qcom/iris/iris_vidc.c -index ec5694c1c8de..2b27df6b1aad 100644 ---- a/drivers/media/platform/qcom/iris/iris_vidc.c -+++ b/drivers/media/platform/qcom/iris/iris_vidc.c -@@ -7,6 +7,7 @@ - #include - #include - #include -+#include - - #include "iris_vidc.h" - #include "iris_instance.h" -@@ -98,6 +99,7 @@ iris_m2m_queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_ - src_vq->io_modes = VB2_MMAP | VB2_DMABUF; - src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; - src_vq->ops = inst->core->iris_vb2_ops; -+ src_vq->mem_ops = &vb2_dma_contig_memops; - src_vq->drv_priv = inst; - src_vq->buf_struct_size = sizeof(struct iris_buffer); - src_vq->min_reqbufs_allocation = MIN_BUFFERS; -@@ -111,6 +113,7 @@ iris_m2m_queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_ - dst_vq->io_modes = VB2_MMAP | VB2_DMABUF; - dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; - dst_vq->ops = inst->core->iris_vb2_ops; -+ dst_vq->mem_ops = &vb2_dma_contig_memops; - dst_vq->drv_priv = inst; - dst_vq->buf_struct_size = sizeof(struct iris_buffer); - dst_vq->min_reqbufs_allocation = MIN_BUFFERS; -@@ -372,9 +375,13 @@ static struct v4l2_file_operations iris_v4l2_file_ops = { - }; - - static const struct vb2_ops iris_vb2_ops = { -+ .buf_init = iris_vb2_buf_init, - .queue_setup = iris_vb2_queue_setup, - .start_streaming = iris_vb2_start_streaming, - .stop_streaming = iris_vb2_stop_streaming, -+ .buf_prepare = iris_vb2_buf_prepare, -+ .buf_out_validate = iris_vb2_buf_out_validate, -+ .buf_queue = iris_vb2_buf_queue, - }; - - static const struct v4l2_ioctl_ops iris_v4l2_ioctl_ops = { -@@ -388,6 +395,13 @@ static const struct v4l2_ioctl_ops iris_v4l2_ioctl_ops = { - .vidioc_g_fmt_vid_out_mplane = iris_g_fmt_vid_mplane, - .vidioc_enum_framesizes = iris_enum_framesizes, - .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, -+ .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, -+ .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, -+ .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf, -+ .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, -+ .vidioc_qbuf = v4l2_m2m_ioctl_qbuf, -+ .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf, -+ .vidioc_remove_bufs = v4l2_m2m_ioctl_remove_bufs, - .vidioc_querycap = iris_querycap, - .vidioc_g_selection = iris_g_selection, - .vidioc_subscribe_event = iris_subscribe_event, --- -2.34.1 - diff --git a/patch/kernel/archive/sm8550-6.12/0021_media--iris--add-support-for-dynamic-resolution-ch.patch b/patch/kernel/archive/sm8550-6.12/0021_media--iris--add-support-for-dynamic-resolution-ch.patch deleted file mode 100644 index 9c49f0d0c579..000000000000 --- a/patch/kernel/archive/sm8550-6.12/0021_media--iris--add-support-for-dynamic-resolution-ch.patch +++ /dev/null @@ -1,985 +0,0 @@ -From e5ae667c7a8454ed54645d1706a21bd2c3e2882c Mon Sep 17 00:00:00 2001 -From: Dikshita Agarwal -Date: Fri, 7 Feb 2025 13:25:01 +0530 -Subject: [PATCH] media: iris: add support for dynamic resolution change - -Handle the response sent by the firmware, when a source change is -detected. Read the subscribed parameter to get the changed values. Raise -the source change event to the client and update the instance sub-state. - -Mark the last buffer from before the source change with the -V4L2_BUF_FLAG_LAST flag and return to the client. - -Reviewed-by: Hans Verkuil -Tested-by: Stefan Schmidt # x1e80100 (Dell XPS 13 9345) -Reviewed-by: Stefan Schmidt -Tested-by: Neil Armstrong # on SM8550-QRD -Tested-by: Neil Armstrong # on SM8550-HDK -Signed-off-by: Dikshita Agarwal -Link: https://lore.kernel.org/r/20250207-qcom-video-iris-v10-21-ab66eeffbd20@quicinc.com -Signed-off-by: Neil Armstrong ---- - .../platform/qcom/iris/iris_hfi_common.c | 64 ++++++ - .../platform/qcom/iris/iris_hfi_common.h | 3 + - .../qcom/iris/iris_hfi_gen1_defines.h | 82 +++++++ - .../qcom/iris/iris_hfi_gen1_response.c | 208 ++++++++++++++++++ - .../qcom/iris/iris_hfi_gen2_defines.h | 4 + - .../qcom/iris/iris_hfi_gen2_response.c | 183 ++++++++++++++- - .../media/platform/qcom/iris/iris_instance.h | 2 + - drivers/media/platform/qcom/iris/iris_state.c | 64 ++++++ - drivers/media/platform/qcom/iris/iris_state.h | 33 +++ - drivers/media/platform/qcom/iris/iris_vb2.c | 18 ++ - drivers/media/platform/qcom/iris/iris_vdec.c | 15 ++ - drivers/media/platform/qcom/iris/iris_vdec.h | 1 + - 12 files changed, 676 insertions(+), 1 deletion(-) - -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_common.c b/drivers/media/platform/qcom/iris/iris_hfi_common.c -index 29f56c2bf74c..92112eb16c11 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_common.c -+++ b/drivers/media/platform/qcom/iris/iris_hfi_common.c -@@ -10,6 +10,70 @@ - #include "iris_hfi_common.h" - #include "iris_vpu_common.h" - -+u32 iris_hfi_get_v4l2_color_primaries(u32 hfi_primaries) -+{ -+ switch (hfi_primaries) { -+ case HFI_PRIMARIES_RESERVED: -+ return V4L2_COLORSPACE_DEFAULT; -+ case HFI_PRIMARIES_BT709: -+ return V4L2_COLORSPACE_REC709; -+ case HFI_PRIMARIES_BT470_SYSTEM_M: -+ return V4L2_COLORSPACE_470_SYSTEM_M; -+ case HFI_PRIMARIES_BT470_SYSTEM_BG: -+ return V4L2_COLORSPACE_470_SYSTEM_BG; -+ case HFI_PRIMARIES_BT601_525: -+ return V4L2_COLORSPACE_SMPTE170M; -+ case HFI_PRIMARIES_SMPTE_ST240M: -+ return V4L2_COLORSPACE_SMPTE240M; -+ case HFI_PRIMARIES_BT2020: -+ return V4L2_COLORSPACE_BT2020; -+ case V4L2_COLORSPACE_DCI_P3: -+ return HFI_PRIMARIES_SMPTE_RP431_2; -+ default: -+ return V4L2_COLORSPACE_DEFAULT; -+ } -+} -+ -+u32 iris_hfi_get_v4l2_transfer_char(u32 hfi_characterstics) -+{ -+ switch (hfi_characterstics) { -+ case HFI_TRANSFER_RESERVED: -+ return V4L2_XFER_FUNC_DEFAULT; -+ case HFI_TRANSFER_BT709: -+ return V4L2_XFER_FUNC_709; -+ case HFI_TRANSFER_SMPTE_ST240M: -+ return V4L2_XFER_FUNC_SMPTE240M; -+ case HFI_TRANSFER_SRGB_SYCC: -+ return V4L2_XFER_FUNC_SRGB; -+ case HFI_TRANSFER_SMPTE_ST2084_PQ: -+ return V4L2_XFER_FUNC_SMPTE2084; -+ default: -+ return V4L2_XFER_FUNC_DEFAULT; -+ } -+} -+ -+u32 iris_hfi_get_v4l2_matrix_coefficients(u32 hfi_coefficients) -+{ -+ switch (hfi_coefficients) { -+ case HFI_MATRIX_COEFF_RESERVED: -+ return V4L2_YCBCR_ENC_DEFAULT; -+ case HFI_MATRIX_COEFF_BT709: -+ return V4L2_YCBCR_ENC_709; -+ case HFI_MATRIX_COEFF_BT470_SYS_BG_OR_BT601_625: -+ return V4L2_YCBCR_ENC_XV601; -+ case HFI_MATRIX_COEFF_BT601_525_BT1358_525_OR_625: -+ return V4L2_YCBCR_ENC_601; -+ case HFI_MATRIX_COEFF_SMPTE_ST240: -+ return V4L2_YCBCR_ENC_SMPTE240M; -+ case HFI_MATRIX_COEFF_BT2020_NON_CONSTANT: -+ return V4L2_YCBCR_ENC_BT2020; -+ case HFI_MATRIX_COEFF_BT2020_CONSTANT: -+ return V4L2_YCBCR_ENC_BT2020_CONST_LUM; -+ default: -+ return V4L2_YCBCR_ENC_DEFAULT; -+ } -+} -+ - int iris_hfi_core_init(struct iris_core *core) - { - const struct iris_hfi_command_ops *hfi_ops = core->hfi_ops; -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_common.h b/drivers/media/platform/qcom/iris/iris_hfi_common.h -index c54c88658633..6241098dc31d 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_common.h -+++ b/drivers/media/platform/qcom/iris/iris_hfi_common.h -@@ -138,6 +138,9 @@ struct hfi_subscription_params { - u32 level; - }; - -+u32 iris_hfi_get_v4l2_color_primaries(u32 hfi_primaries); -+u32 iris_hfi_get_v4l2_transfer_char(u32 hfi_characterstics); -+u32 iris_hfi_get_v4l2_matrix_coefficients(u32 hfi_coefficients); - int iris_hfi_core_init(struct iris_core *core); - int iris_hfi_pm_suspend(struct iris_core *core); - int iris_hfi_pm_resume(struct iris_core *core); -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h -index 108449d703e1..416e9a19a26f 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h -@@ -44,18 +44,28 @@ - #define HFI_EVENT_SYS_ERROR 0x1 - #define HFI_EVENT_SESSION_ERROR 0x2 - -+#define HFI_EVENT_DATA_SEQUENCE_CHANGED_SUFFICIENT_BUF_RESOURCES 0x1000001 -+#define HFI_EVENT_DATA_SEQUENCE_CHANGED_INSUFFICIENT_BUF_RESOURCES 0x1000002 -+#define HFI_EVENT_SESSION_SEQUENCE_CHANGED 0x1000003 -+ - #define HFI_BUFFERFLAG_TIMESTAMPINVALID 0x00000100 - - #define HFI_FLUSH_OUTPUT 0x1000002 - #define HFI_FLUSH_OUTPUT2 0x1000003 - #define HFI_FLUSH_ALL 0x1000004 - -+#define HFI_INDEX_EXTRADATA_INPUT_CROP 0x0700000e -+ - #define HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL 0x201001 - #define HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO 0x201002 - #define HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE 0x201008 - #define HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL 0x20100c - -+#define HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS 0x202001 -+ - #define HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER 0x1200001 -+#define HFI_PROPERTY_PARAM_VDEC_DPB_COUNTS 0x120300e -+#define HFI_PROPERTY_CONFIG_VDEC_ENTROPY 0x1204004 - - #define HFI_BUFFER_INPUT 0x1 - #define HFI_BUFFER_OUTPUT 0x2 -@@ -69,11 +79,15 @@ - - #define HFI_PROPERTY_PARAM_FRAME_SIZE 0x1001 - #define HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT 0x1003 -+#define HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT 0x1005 - #define HFI_PROPERTY_PARAM_WORK_MODE 0x1015 - #define HFI_PROPERTY_PARAM_WORK_ROUTE 0x1017 - #define HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE 0x2002 - - #define HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM 0x1003001 -+#define HFI_PROPERTY_PARAM_VDEC_PIXEL_BITDEPTH 0x1003007 -+#define HFI_PROPERTY_PARAM_VDEC_PIC_STRUCT 0x1003009 -+#define HFI_PROPERTY_PARAM_VDEC_COLOUR_SPACE 0x100300a - #define HFI_CORE_ID_1 1 - #define HFI_COLOR_FORMAT_NV12 0x02 - #define HFI_COLOR_FORMAT_NV12_UBWC 0x8002 -@@ -249,6 +263,11 @@ struct hfi_enable { - u32 enable; - }; - -+struct hfi_profile_level { -+ u32 profile; -+ u32 level; -+}; -+ - struct hfi_framesize { - u32 buffer_type; - u32 width; -@@ -267,6 +286,37 @@ struct hfi_video_work_route { - u32 video_work_route; - }; - -+struct hfi_bit_depth { -+ u32 buffer_type; -+ u32 bit_depth; -+}; -+ -+struct hfi_pic_struct { -+ u32 progressive_only; -+}; -+ -+struct hfi_colour_space { -+ u32 colour_space; -+}; -+ -+struct hfi_extradata_input_crop { -+ u32 size; -+ u32 version; -+ u32 port_index; -+ u32 left; -+ u32 top; -+ u32 width; -+ u32 height; -+}; -+ -+struct hfi_dpb_counts { -+ u32 max_dpb_count; -+ u32 max_ref_frames; -+ u32 max_dec_buffering; -+ u32 max_reorder_frames; -+ u32 fw_min_count; -+}; -+ - struct hfi_uncompressed_format_select { - u32 buffer_type; - u32 format; -@@ -301,6 +351,38 @@ struct hfi_multi_stream { - u32 enable; - }; - -+struct hfi_buffer_requirements { -+ u32 type; -+ u32 size; -+ u32 region_size; -+ u32 hold_count; -+ u32 count_min; -+ u32 count_actual; -+ u32 contiguous; -+ u32 alignment; -+}; -+ -+struct hfi_event_data { -+ u32 error; -+ u32 height; -+ u32 width; -+ u32 event_type; -+ u32 packet_buffer; -+ u32 extradata_buffer; -+ u32 tag; -+ u32 profile; -+ u32 level; -+ u32 bit_depth; -+ u32 pic_struct; -+ u32 colour_space; -+ u32 entropy_mode; -+ u32 buf_count; -+ struct { -+ u32 left, top; -+ u32 width, height; -+ } input_crop; -+}; -+ - struct hfi_msg_session_empty_buffer_done_pkt { - struct hfi_msg_session_hdr_pkt shdr; - u32 offset; -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c -index 23a8bf29e381..3a47d9f39695 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c -@@ -3,11 +3,216 @@ - * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. - */ - -+#include - #include - - #include "iris_hfi_gen1.h" - #include "iris_hfi_gen1_defines.h" - #include "iris_instance.h" -+#include "iris_vdec.h" -+#include "iris_vpu_buffer.h" -+ -+static void iris_hfi_gen1_read_changed_params(struct iris_inst *inst, -+ struct hfi_msg_event_notify_pkt *pkt) -+{ -+ struct v4l2_pix_format_mplane *pixmp_ip = &inst->fmt_src->fmt.pix_mp; -+ struct v4l2_pix_format_mplane *pixmp_op = &inst->fmt_dst->fmt.pix_mp; -+ u32 num_properties_changed = pkt->event_data2; -+ u8 *data_ptr = (u8 *)&pkt->ext_event_data[0]; -+ u32 primaries, matrix_coeff, transfer_char; -+ struct hfi_dpb_counts *iris_vpu_dpb_count; -+ struct hfi_profile_level *profile_level; -+ struct hfi_buffer_requirements *bufreq; -+ struct hfi_extradata_input_crop *crop; -+ struct hfi_colour_space *colour_info; -+ struct iris_core *core = inst->core; -+ u32 colour_description_present_flag; -+ u32 video_signal_type_present_flag; -+ struct hfi_event_data event = {0}; -+ struct hfi_bit_depth *pixel_depth; -+ struct hfi_pic_struct *pic_struct; -+ struct hfi_framesize *frame_sz; -+ struct vb2_queue *dst_q; -+ struct v4l2_ctrl *ctrl; -+ u32 full_range, ptype; -+ -+ do { -+ ptype = *((u32 *)data_ptr); -+ switch (ptype) { -+ case HFI_PROPERTY_PARAM_FRAME_SIZE: -+ data_ptr += sizeof(u32); -+ frame_sz = (struct hfi_framesize *)data_ptr; -+ event.width = frame_sz->width; -+ event.height = frame_sz->height; -+ data_ptr += sizeof(*frame_sz); -+ break; -+ case HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT: -+ data_ptr += sizeof(u32); -+ profile_level = (struct hfi_profile_level *)data_ptr; -+ event.profile = profile_level->profile; -+ event.level = profile_level->level; -+ data_ptr += sizeof(*profile_level); -+ break; -+ case HFI_PROPERTY_PARAM_VDEC_PIXEL_BITDEPTH: -+ data_ptr += sizeof(u32); -+ pixel_depth = (struct hfi_bit_depth *)data_ptr; -+ event.bit_depth = pixel_depth->bit_depth; -+ data_ptr += sizeof(*pixel_depth); -+ break; -+ case HFI_PROPERTY_PARAM_VDEC_PIC_STRUCT: -+ data_ptr += sizeof(u32); -+ pic_struct = (struct hfi_pic_struct *)data_ptr; -+ event.pic_struct = pic_struct->progressive_only; -+ data_ptr += sizeof(*pic_struct); -+ break; -+ case HFI_PROPERTY_PARAM_VDEC_COLOUR_SPACE: -+ data_ptr += sizeof(u32); -+ colour_info = (struct hfi_colour_space *)data_ptr; -+ event.colour_space = colour_info->colour_space; -+ data_ptr += sizeof(*colour_info); -+ break; -+ case HFI_PROPERTY_CONFIG_VDEC_ENTROPY: -+ data_ptr += sizeof(u32); -+ event.entropy_mode = *(u32 *)data_ptr; -+ data_ptr += sizeof(u32); -+ break; -+ case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS: -+ data_ptr += sizeof(u32); -+ bufreq = (struct hfi_buffer_requirements *)data_ptr; -+ event.buf_count = bufreq->count_min; -+ data_ptr += sizeof(*bufreq); -+ break; -+ case HFI_INDEX_EXTRADATA_INPUT_CROP: -+ data_ptr += sizeof(u32); -+ crop = (struct hfi_extradata_input_crop *)data_ptr; -+ event.input_crop.left = crop->left; -+ event.input_crop.top = crop->top; -+ event.input_crop.width = crop->width; -+ event.input_crop.height = crop->height; -+ data_ptr += sizeof(*crop); -+ break; -+ case HFI_PROPERTY_PARAM_VDEC_DPB_COUNTS: -+ data_ptr += sizeof(u32); -+ iris_vpu_dpb_count = (struct hfi_dpb_counts *)data_ptr; -+ event.buf_count = iris_vpu_dpb_count->fw_min_count; -+ data_ptr += sizeof(*iris_vpu_dpb_count); -+ break; -+ default: -+ break; -+ } -+ num_properties_changed--; -+ } while (num_properties_changed > 0); -+ -+ pixmp_ip->width = event.width; -+ pixmp_ip->height = event.height; -+ -+ pixmp_op->width = ALIGN(event.width, 128); -+ pixmp_op->height = ALIGN(event.height, 32); -+ pixmp_op->plane_fmt[0].bytesperline = ALIGN(event.width, 128); -+ pixmp_op->plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_OUTPUT); -+ -+ matrix_coeff = FIELD_GET(GENMASK(7, 0), event.colour_space); -+ transfer_char = FIELD_GET(GENMASK(15, 8), event.colour_space); -+ primaries = FIELD_GET(GENMASK(23, 16), event.colour_space); -+ colour_description_present_flag = FIELD_GET(GENMASK(24, 24), event.colour_space); -+ full_range = FIELD_GET(GENMASK(25, 25), event.colour_space); -+ video_signal_type_present_flag = FIELD_GET(GENMASK(29, 29), event.colour_space); -+ -+ pixmp_op->colorspace = V4L2_COLORSPACE_DEFAULT; -+ pixmp_op->xfer_func = V4L2_XFER_FUNC_DEFAULT; -+ pixmp_op->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; -+ pixmp_op->quantization = V4L2_QUANTIZATION_DEFAULT; -+ -+ if (video_signal_type_present_flag) { -+ pixmp_op->quantization = -+ full_range ? -+ V4L2_QUANTIZATION_FULL_RANGE : -+ V4L2_QUANTIZATION_LIM_RANGE; -+ if (colour_description_present_flag) { -+ pixmp_op->colorspace = -+ iris_hfi_get_v4l2_color_primaries(primaries); -+ pixmp_op->xfer_func = -+ iris_hfi_get_v4l2_transfer_char(transfer_char); -+ pixmp_op->ycbcr_enc = -+ iris_hfi_get_v4l2_matrix_coefficients(matrix_coeff); -+ } -+ } -+ -+ pixmp_ip->colorspace = pixmp_op->colorspace; -+ pixmp_ip->xfer_func = pixmp_op->xfer_func; -+ pixmp_ip->ycbcr_enc = pixmp_op->ycbcr_enc; -+ pixmp_ip->quantization = pixmp_op->quantization; -+ -+ if (event.input_crop.width > 0 && event.input_crop.height > 0) { -+ inst->crop.left = event.input_crop.left; -+ inst->crop.top = event.input_crop.top; -+ inst->crop.width = event.input_crop.width; -+ inst->crop.height = event.input_crop.height; -+ } else { -+ inst->crop.left = 0; -+ inst->crop.top = 0; -+ inst->crop.width = event.width; -+ inst->crop.height = event.height; -+ } -+ -+ inst->fw_min_count = event.buf_count; -+ inst->buffers[BUF_OUTPUT].min_count = iris_vpu_buf_count(inst, BUF_OUTPUT); -+ inst->buffers[BUF_OUTPUT].size = pixmp_op->plane_fmt[0].sizeimage; -+ ctrl = v4l2_ctrl_find(&inst->ctrl_handler, V4L2_CID_MIN_BUFFERS_FOR_CAPTURE); -+ if (ctrl) -+ v4l2_ctrl_s_ctrl(ctrl, inst->buffers[BUF_OUTPUT].min_count); -+ -+ dst_q = v4l2_m2m_get_dst_vq(inst->m2m_ctx); -+ dst_q->min_reqbufs_allocation = inst->buffers[BUF_OUTPUT].min_count; -+ -+ if (event.bit_depth || !event.pic_struct) { -+ dev_err(core->dev, "unsupported content, bit depth: %x, pic_struct = %x\n", -+ event.bit_depth, event.pic_struct); -+ iris_inst_change_state(inst, IRIS_INST_ERROR); -+ } -+} -+ -+static void iris_hfi_gen1_event_seq_changed(struct iris_inst *inst, -+ struct hfi_msg_event_notify_pkt *pkt) -+{ -+ struct hfi_session_flush_pkt flush_pkt; -+ u32 num_properties_changed; -+ int ret; -+ -+ ret = iris_inst_sub_state_change_drc(inst); -+ if (ret) -+ return; -+ -+ switch (pkt->event_data1) { -+ case HFI_EVENT_DATA_SEQUENCE_CHANGED_SUFFICIENT_BUF_RESOURCES: -+ case HFI_EVENT_DATA_SEQUENCE_CHANGED_INSUFFICIENT_BUF_RESOURCES: -+ break; -+ default: -+ iris_inst_change_state(inst, IRIS_INST_ERROR); -+ return; -+ } -+ -+ num_properties_changed = pkt->event_data2; -+ if (!num_properties_changed) { -+ iris_inst_change_state(inst, IRIS_INST_ERROR); -+ return; -+ } -+ -+ iris_hfi_gen1_read_changed_params(inst, pkt); -+ -+ if (inst->state != IRIS_INST_ERROR) { -+ reinit_completion(&inst->flush_completion); -+ -+ flush_pkt.shdr.hdr.size = sizeof(struct hfi_session_flush_pkt); -+ flush_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_FLUSH; -+ flush_pkt.shdr.session_id = inst->session_id; -+ flush_pkt.flush_type = HFI_FLUSH_OUTPUT; -+ iris_hfi_queue_cmd_write(inst->core, &flush_pkt, flush_pkt.shdr.hdr.size); -+ } -+ -+ iris_vdec_src_change(inst); -+ iris_inst_sub_state_change_drc_last(inst); -+} - - static void - iris_hfi_gen1_sys_event_notify(struct iris_core *core, void *packet) -@@ -66,6 +271,9 @@ static void iris_hfi_gen1_session_event_notify(struct iris_inst *inst, void *pac - case HFI_EVENT_SESSION_ERROR: - iris_hfi_gen1_event_session_error(inst, pkt); - break; -+ case HFI_EVENT_SESSION_SEQUENCE_CHANGED: -+ iris_hfi_gen1_event_seq_changed(inst, pkt); -+ break; - default: - break; - } -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h -index 8a9f2b5517ad..42cd57d5e3b1 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h -@@ -19,8 +19,11 @@ - #define HFI_CMD_STOP 0x01000006 - #define HFI_CMD_BUFFER 0x01000009 - #define HFI_CMD_SUBSCRIBE_MODE 0x0100000B -+#define HFI_CMD_SETTINGS_CHANGE 0x0100000C - #define HFI_CMD_END 0x01FFFFFF - -+#define HFI_BITMASK_BITSTREAM_WIDTH 0xffff0000 -+#define HFI_BITMASK_BITSTREAM_HEIGHT 0x0000ffff - #define HFI_BITMASK_FRAME_MBS_ONLY_FLAG 0x00000001 - - #define HFI_PROP_BEGIN 0x03000000 -@@ -75,6 +78,7 @@ - #define HFI_INFO_UNSUPPORTED 0x06000001 - #define HFI_INFO_DATA_CORRUPT 0x06000002 - #define HFI_INFO_BUFFER_OVERFLOW 0x06000004 -+#define HFI_INFO_HFI_FLAG_PSC_LAST 0x06000007 - #define HFI_INFORMATION_END 0x06FFFFFF - - enum hfi_property_mode_type { -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c -index e8d8caeef021..c7552e041138 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c -@@ -8,6 +8,8 @@ - #include "iris_hfi_gen2.h" - #include "iris_hfi_gen2_defines.h" - #include "iris_hfi_gen2_packet.h" -+#include "iris_vdec.h" -+#include "iris_vpu_buffer.h" - #include "iris_vpu_common.h" - - struct iris_hfi_gen2_core_hfi_range { -@@ -199,6 +201,10 @@ static int iris_hfi_gen2_handle_session_info(struct iris_inst *inst, - info = "buffer overflow"; - inst_hfi_gen2->hfi_frame_info.overflow = 1; - break; -+ case HFI_INFO_HFI_FLAG_PSC_LAST: -+ info = "drc last flag"; -+ ret = iris_inst_sub_state_change_drc_last(inst); -+ break; - default: - info = "unknown"; - break; -@@ -329,6 +335,13 @@ static int iris_hfi_gen2_handle_output_buffer(struct iris_inst *inst, - struct v4l2_m2m_buffer *m2m_buffer, *n; - struct iris_buffer *buf; - bool found = false; -+ int ret; -+ -+ if (hfi_buffer->flags & HFI_BUF_FW_FLAG_PSC_LAST) { -+ ret = iris_inst_sub_state_change_drc_last(inst); -+ if (ret) -+ return ret; -+ } - - v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, m2m_buffer, n) { - buf = to_iris_buffer(&m2m_buffer->vb); -@@ -440,6 +453,115 @@ static int iris_hfi_gen2_handle_session_buffer(struct iris_inst *inst, - return iris_hfi_gen2_handle_release_internal_buffer(inst, buffer); - } - -+static void iris_hfi_gen2_read_input_subcr_params(struct iris_inst *inst) -+{ -+ struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); -+ struct v4l2_pix_format_mplane *pixmp_ip = &inst->fmt_src->fmt.pix_mp; -+ struct v4l2_pix_format_mplane *pixmp_op = &inst->fmt_dst->fmt.pix_mp; -+ u32 primaries, matrix_coeff, transfer_char; -+ struct hfi_subscription_params subsc_params; -+ u32 colour_description_present_flag; -+ u32 video_signal_type_present_flag; -+ struct iris_core *core = inst->core; -+ u32 full_range, width, height; -+ struct vb2_queue *dst_q; -+ struct v4l2_ctrl *ctrl; -+ -+ subsc_params = inst_hfi_gen2->src_subcr_params; -+ width = (subsc_params.bitstream_resolution & -+ HFI_BITMASK_BITSTREAM_WIDTH) >> 16; -+ height = subsc_params.bitstream_resolution & -+ HFI_BITMASK_BITSTREAM_HEIGHT; -+ -+ pixmp_ip->width = width; -+ pixmp_ip->height = height; -+ -+ pixmp_op->width = ALIGN(width, 128); -+ pixmp_op->height = ALIGN(height, 32); -+ pixmp_op->plane_fmt[0].bytesperline = ALIGN(width, 128); -+ pixmp_op->plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_OUTPUT); -+ -+ matrix_coeff = subsc_params.color_info & 0xFF; -+ transfer_char = (subsc_params.color_info & 0xFF00) >> 8; -+ primaries = (subsc_params.color_info & 0xFF0000) >> 16; -+ colour_description_present_flag = -+ (subsc_params.color_info & 0x1000000) >> 24; -+ full_range = (subsc_params.color_info & 0x2000000) >> 25; -+ video_signal_type_present_flag = -+ (subsc_params.color_info & 0x20000000) >> 29; -+ -+ pixmp_op->colorspace = V4L2_COLORSPACE_DEFAULT; -+ pixmp_op->xfer_func = V4L2_XFER_FUNC_DEFAULT; -+ pixmp_op->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; -+ pixmp_op->quantization = V4L2_QUANTIZATION_DEFAULT; -+ -+ if (video_signal_type_present_flag) { -+ pixmp_op->quantization = -+ full_range ? -+ V4L2_QUANTIZATION_FULL_RANGE : -+ V4L2_QUANTIZATION_LIM_RANGE; -+ if (colour_description_present_flag) { -+ pixmp_op->colorspace = -+ iris_hfi_get_v4l2_color_primaries(primaries); -+ pixmp_op->xfer_func = -+ iris_hfi_get_v4l2_transfer_char(transfer_char); -+ pixmp_op->ycbcr_enc = -+ iris_hfi_get_v4l2_matrix_coefficients(matrix_coeff); -+ } -+ } -+ -+ pixmp_ip->colorspace = pixmp_op->colorspace; -+ pixmp_ip->xfer_func = pixmp_op->xfer_func; -+ pixmp_ip->ycbcr_enc = pixmp_op->ycbcr_enc; -+ pixmp_ip->quantization = pixmp_op->quantization; -+ -+ inst->crop.top = subsc_params.crop_offsets[0] & 0xFFFF; -+ inst->crop.left = (subsc_params.crop_offsets[0] >> 16) & 0xFFFF; -+ inst->crop.height = pixmp_ip->height - -+ (subsc_params.crop_offsets[1] & 0xFFFF) - inst->crop.top; -+ inst->crop.width = pixmp_ip->width - -+ ((subsc_params.crop_offsets[1] >> 16) & 0xFFFF) - inst->crop.left; -+ -+ inst->fw_caps[PROFILE].value = subsc_params.profile; -+ inst->fw_caps[LEVEL].value = subsc_params.level; -+ inst->fw_caps[POC].value = subsc_params.pic_order_cnt; -+ -+ if (subsc_params.bit_depth != BIT_DEPTH_8 || -+ !(subsc_params.coded_frames & HFI_BITMASK_FRAME_MBS_ONLY_FLAG)) { -+ dev_err(core->dev, "unsupported content, bit depth: %x, pic_struct = %x\n", -+ subsc_params.bit_depth, subsc_params.coded_frames); -+ iris_inst_change_state(inst, IRIS_INST_ERROR); -+ } -+ -+ inst->fw_min_count = subsc_params.fw_min_count; -+ inst->buffers[BUF_OUTPUT].min_count = iris_vpu_buf_count(inst, BUF_OUTPUT); -+ inst->buffers[BUF_OUTPUT].size = pixmp_op->plane_fmt[0].sizeimage; -+ ctrl = v4l2_ctrl_find(&inst->ctrl_handler, V4L2_CID_MIN_BUFFERS_FOR_CAPTURE); -+ if (ctrl) -+ v4l2_ctrl_s_ctrl(ctrl, inst->buffers[BUF_OUTPUT].min_count); -+ -+ dst_q = v4l2_m2m_get_dst_vq(inst->m2m_ctx); -+ dst_q->min_reqbufs_allocation = inst->buffers[BUF_OUTPUT].min_count; -+} -+ -+static int iris_hfi_gen2_handle_src_change(struct iris_inst *inst, -+ struct iris_hfi_packet *pkt) -+{ -+ int ret; -+ -+ if (pkt->port != HFI_PORT_BITSTREAM) -+ return 0; -+ -+ ret = iris_inst_sub_state_change_drc(inst); -+ if (ret) -+ return ret; -+ -+ iris_hfi_gen2_read_input_subcr_params(inst); -+ iris_vdec_src_change(inst); -+ -+ return 0; -+} -+ - static int iris_hfi_gen2_handle_session_command(struct iris_inst *inst, - struct iris_hfi_packet *pkt) - { -@@ -455,6 +577,9 @@ static int iris_hfi_gen2_handle_session_command(struct iris_inst *inst, - case HFI_CMD_BUFFER: - ret = iris_hfi_gen2_handle_session_buffer(inst, pkt); - break; -+ case HFI_CMD_SETTINGS_CHANGE: -+ ret = iris_hfi_gen2_handle_src_change(inst, pkt); -+ break; - default: - break; - } -@@ -588,16 +713,61 @@ static int iris_hfi_gen2_handle_system_response(struct iris_core *core, - return 0; - } - -+static void iris_hfi_gen2_init_src_change_param(struct iris_inst *inst) -+{ -+ struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); -+ struct v4l2_pix_format_mplane *pixmp_ip = &inst->fmt_src->fmt.pix_mp; -+ struct v4l2_pix_format_mplane *pixmp_op = &inst->fmt_dst->fmt.pix_mp; -+ u32 bottom_offset = (pixmp_ip->height - inst->crop.height); -+ u32 right_offset = (pixmp_ip->width - inst->crop.width); -+ struct hfi_subscription_params *subsc_params; -+ u32 primaries, matrix_coeff, transfer_char; -+ u32 colour_description_present_flag = 0; -+ u32 video_signal_type_present_flag = 0; -+ u32 full_range, video_format = 0; -+ u32 left_offset = inst->crop.left; -+ u32 top_offset = inst->crop.top; -+ -+ subsc_params = &inst_hfi_gen2->src_subcr_params; -+ subsc_params->bitstream_resolution = -+ pixmp_ip->width << 16 | pixmp_ip->height; -+ subsc_params->crop_offsets[0] = -+ left_offset << 16 | top_offset; -+ subsc_params->crop_offsets[1] = -+ right_offset << 16 | bottom_offset; -+ subsc_params->fw_min_count = inst->buffers[BUF_OUTPUT].min_count; -+ -+ primaries = iris_hfi_gen2_get_color_primaries(pixmp_op->colorspace); -+ matrix_coeff = iris_hfi_gen2_get_matrix_coefficients(pixmp_op->ycbcr_enc); -+ transfer_char = iris_hfi_gen2_get_transfer_char(pixmp_op->xfer_func); -+ full_range = pixmp_op->quantization == V4L2_QUANTIZATION_FULL_RANGE ? 1 : 0; -+ subsc_params->color_info = -+ iris_hfi_gen2_get_color_info(matrix_coeff, transfer_char, primaries, -+ colour_description_present_flag, -+ full_range, video_format, -+ video_signal_type_present_flag); -+ -+ subsc_params->profile = inst->fw_caps[PROFILE].value; -+ subsc_params->level = inst->fw_caps[LEVEL].value; -+ subsc_params->pic_order_cnt = inst->fw_caps[POC].value; -+ subsc_params->bit_depth = inst->fw_caps[BIT_DEPTH].value; -+ if (inst->fw_caps[CODED_FRAMES].value == -+ CODED_FRAMES_PROGRESSIVE) -+ subsc_params->coded_frames = HFI_BITMASK_FRAME_MBS_ONLY_FLAG; -+ else -+ subsc_params->coded_frames = 0; -+} -+ - static int iris_hfi_gen2_handle_session_response(struct iris_core *core, - struct iris_hfi_header *hdr) - { -+ u8 *pkt = (u8 *)((u8 *)hdr + sizeof(*hdr)); - struct iris_inst_hfi_gen2 *inst_hfi_gen2; - struct iris_hfi_packet *packet; - struct iris_inst *inst; - bool dequeue = false; - int ret = 0; - u32 i, j; -- u8 *pkt; - static const struct iris_hfi_gen2_inst_hfi_range range[] = { - {HFI_SESSION_ERROR_BEGIN, HFI_SESSION_ERROR_END, - iris_hfi_gen2_handle_session_error}, -@@ -617,6 +787,17 @@ static int iris_hfi_gen2_handle_session_response(struct iris_core *core, - inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); - memset(&inst_hfi_gen2->hfi_frame_info, 0, sizeof(struct iris_hfi_frame_info)); - -+ for (i = 0; i < hdr->num_packets; i++) { -+ packet = (struct iris_hfi_packet *)pkt; -+ if (packet->type == HFI_CMD_SETTINGS_CHANGE) { -+ if (packet->port == HFI_PORT_BITSTREAM) { -+ iris_hfi_gen2_init_src_change_param(inst); -+ break; -+ } -+ } -+ pkt += packet->size; -+ } -+ - pkt = (u8 *)((u8 *)hdr + sizeof(*hdr)); - for (i = 0; i < ARRAY_SIZE(range); i++) { - pkt = (u8 *)((u8 *)hdr + sizeof(*hdr)); -diff --git a/drivers/media/platform/qcom/iris/iris_instance.h b/drivers/media/platform/qcom/iris/iris_instance.h -index 2886491ad59f..89fb63644311 100644 ---- a/drivers/media/platform/qcom/iris/iris_instance.h -+++ b/drivers/media/platform/qcom/iris/iris_instance.h -@@ -31,6 +31,7 @@ - * @buffers: array of different iris buffers - * @fw_min_count: minimnum count of buffers needed by fw - * @state: instance state -+ * @sub_state: instance sub state - * @once_per_session_set: boolean to set once per session property - * @m2m_dev: a reference to m2m device structure - * @m2m_ctx: a reference to m2m context structure -@@ -57,6 +58,7 @@ struct iris_inst { - struct iris_buffers buffers[BUF_TYPE_MAX]; - u32 fw_min_count; - enum iris_inst_state state; -+ enum iris_inst_sub_state sub_state; - bool once_per_session_set; - struct v4l2_m2m_dev *m2m_dev; - struct v4l2_m2m_ctx *m2m_ctx; -diff --git a/drivers/media/platform/qcom/iris/iris_state.c b/drivers/media/platform/qcom/iris/iris_state.c -index 44362e8fe18f..aad7e734d5c8 100644 ---- a/drivers/media/platform/qcom/iris/iris_state.c -+++ b/drivers/media/platform/qcom/iris/iris_state.c -@@ -102,3 +102,67 @@ int iris_inst_state_change_streamoff(struct iris_inst *inst, u32 plane) - - return iris_inst_change_state(inst, new_state); - } -+ -+int iris_inst_change_sub_state(struct iris_inst *inst, -+ enum iris_inst_sub_state clear_sub_state, -+ enum iris_inst_sub_state set_sub_state) -+{ -+ enum iris_inst_sub_state prev_sub_state; -+ -+ if (inst->state == IRIS_INST_ERROR) -+ return 0; -+ -+ if (!clear_sub_state && !set_sub_state) -+ return 0; -+ -+ if ((clear_sub_state & set_sub_state) || -+ set_sub_state > IRIS_INST_MAX_SUB_STATE_VALUE || -+ clear_sub_state > IRIS_INST_MAX_SUB_STATE_VALUE) -+ return -EINVAL; -+ -+ prev_sub_state = inst->sub_state; -+ -+ inst->sub_state |= set_sub_state; -+ inst->sub_state &= ~clear_sub_state; -+ -+ if (inst->sub_state != prev_sub_state) -+ dev_dbg(inst->core->dev, "sub_state changed from %x to %x\n", -+ prev_sub_state, inst->sub_state); -+ -+ return 0; -+} -+ -+int iris_inst_sub_state_change_drc(struct iris_inst *inst) -+{ -+ enum iris_inst_sub_state set_sub_state = 0; -+ -+ if (inst->sub_state & IRIS_INST_SUB_DRC) -+ return -EINVAL; -+ -+ if (inst->state == IRIS_INST_INPUT_STREAMING || -+ inst->state == IRIS_INST_INIT) -+ set_sub_state = IRIS_INST_SUB_FIRST_IPSC | IRIS_INST_SUB_INPUT_PAUSE; -+ else -+ set_sub_state = IRIS_INST_SUB_DRC | IRIS_INST_SUB_INPUT_PAUSE; -+ -+ return iris_inst_change_sub_state(inst, 0, set_sub_state); -+} -+ -+int iris_inst_sub_state_change_drc_last(struct iris_inst *inst) -+{ -+ enum iris_inst_sub_state set_sub_state; -+ -+ if (inst->sub_state & IRIS_INST_SUB_DRC_LAST) -+ return -EINVAL; -+ -+ if (!(inst->sub_state & IRIS_INST_SUB_DRC) || -+ !(inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE)) -+ return -EINVAL; -+ -+ if (inst->sub_state & IRIS_INST_SUB_FIRST_IPSC) -+ return 0; -+ -+ set_sub_state = IRIS_INST_SUB_DRC_LAST | IRIS_INST_SUB_OUTPUT_PAUSE; -+ -+ return iris_inst_change_sub_state(inst, 0, set_sub_state); -+} -diff --git a/drivers/media/platform/qcom/iris/iris_state.h b/drivers/media/platform/qcom/iris/iris_state.h -index 0bf9d0e063ac..b5f0826142f0 100644 ---- a/drivers/media/platform/qcom/iris/iris_state.h -+++ b/drivers/media/platform/qcom/iris/iris_state.h -@@ -91,9 +91,42 @@ enum iris_inst_state { - IRIS_INST_ERROR, - }; - -+#define IRIS_INST_SUB_STATES 8 -+#define IRIS_INST_MAX_SUB_STATE_VALUE ((1 << IRIS_INST_SUB_STATES) - 1) -+ -+/** -+ * enum iris_inst_sub_state -+ * -+ * @IRIS_INST_SUB_FIRST_IPSC: indicates source change is received from firmware -+ * when output port is not yet streaming. -+ * @IRIS_INST_SUB_DRC: indicates source change is received from firmware -+ * when output port is streaming and source change event is -+ * sent to client. -+ * @IRIS_INST_SUB_DRC_LAST: indicates last buffer is received from firmware -+ * as part of source change. -+ * @IRIS_INST_SUB_INPUT_PAUSE: source change is received form firmware. This -+ * indicates that firmware is paused to process -+ * any further input frames. -+ * @IRIS_INST_SUB_OUTPUT_PAUSE: last buffer is received form firmware as part -+ * of drc sequence. This indicates that -+ * firmware is paused to process any further output frames. -+ */ -+enum iris_inst_sub_state { -+ IRIS_INST_SUB_FIRST_IPSC = BIT(0), -+ IRIS_INST_SUB_DRC = BIT(1), -+ IRIS_INST_SUB_DRC_LAST = BIT(2), -+ IRIS_INST_SUB_INPUT_PAUSE = BIT(3), -+ IRIS_INST_SUB_OUTPUT_PAUSE = BIT(4), -+}; -+ - int iris_inst_change_state(struct iris_inst *inst, - enum iris_inst_state request_state); -+int iris_inst_change_sub_state(struct iris_inst *inst, -+ enum iris_inst_sub_state clear_sub_state, -+ enum iris_inst_sub_state set_sub_state); - int iris_inst_state_change_streamon(struct iris_inst *inst, u32 plane); - int iris_inst_state_change_streamoff(struct iris_inst *inst, u32 plane); -+int iris_inst_sub_state_change_drc(struct iris_inst *inst); -+int iris_inst_sub_state_change_drc_last(struct iris_inst *inst); - - #endif -diff --git a/drivers/media/platform/qcom/iris/iris_vb2.c b/drivers/media/platform/qcom/iris/iris_vb2.c -index 770e51f9ef91..3b94011533e8 100644 ---- a/drivers/media/platform/qcom/iris/iris_vb2.c -+++ b/drivers/media/platform/qcom/iris/iris_vb2.c -@@ -4,6 +4,7 @@ - */ - - #include -+#include - #include - - #include "iris_instance.h" -@@ -180,6 +181,7 @@ int iris_vb2_buf_out_validate(struct vb2_buffer *vb) - - void iris_vb2_buf_queue(struct vb2_buffer *vb2) - { -+ static const struct v4l2_event eos = { .type = V4L2_EVENT_EOS }; - struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb2); - struct v4l2_m2m_ctx *m2m_ctx; - struct iris_inst *inst; -@@ -203,6 +205,22 @@ void iris_vb2_buf_queue(struct vb2_buffer *vb2) - goto exit; - } - -+ if (V4L2_TYPE_IS_CAPTURE(vb2->vb2_queue->type)) { -+ if (inst->sub_state & IRIS_INST_SUB_DRC && -+ inst->sub_state & IRIS_INST_SUB_DRC_LAST) { -+ vbuf->flags |= V4L2_BUF_FLAG_LAST; -+ vbuf->sequence = inst->sequence_cap++; -+ vbuf->field = V4L2_FIELD_NONE; -+ vb2_set_plane_payload(vb2, 0, 0); -+ v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE); -+ if (!v4l2_m2m_has_stopped(m2m_ctx)) { -+ v4l2_event_queue_fh(&inst->fh, &eos); -+ v4l2_m2m_mark_stopped(m2m_ctx); -+ } -+ goto exit; -+ } -+ } -+ - v4l2_m2m_buf_queue(m2m_ctx, vbuf); - - ret = iris_vdec_qbuf(inst, vbuf); -diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c b/drivers/media/platform/qcom/iris/iris_vdec.c -index d6b092314b34..1da277ed6cb3 100644 ---- a/drivers/media/platform/qcom/iris/iris_vdec.c -+++ b/drivers/media/platform/qcom/iris/iris_vdec.c -@@ -223,6 +223,21 @@ int iris_vdec_subscribe_event(struct iris_inst *inst, const struct v4l2_event_su - return ret; - } - -+void iris_vdec_src_change(struct iris_inst *inst) -+{ -+ struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; -+ struct v4l2_event event = {0}; -+ struct vb2_queue *src_q; -+ -+ src_q = v4l2_m2m_get_src_vq(m2m_ctx); -+ if (!vb2_is_streaming(src_q)) -+ return; -+ -+ event.type = V4L2_EVENT_SOURCE_CHANGE; -+ event.u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION; -+ v4l2_event_queue_fh(&inst->fh, &event); -+} -+ - static int iris_vdec_get_num_queued_buffers(struct iris_inst *inst, - enum iris_buffer_type type) - { -diff --git a/drivers/media/platform/qcom/iris/iris_vdec.h b/drivers/media/platform/qcom/iris/iris_vdec.h -index 998d4970a42b..dfcc2089a1ef 100644 ---- a/drivers/media/platform/qcom/iris/iris_vdec.h -+++ b/drivers/media/platform/qcom/iris/iris_vdec.h -@@ -14,6 +14,7 @@ int iris_vdec_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f); - int iris_vdec_try_fmt(struct iris_inst *inst, struct v4l2_format *f); - int iris_vdec_s_fmt(struct iris_inst *inst, struct v4l2_format *f); - int iris_vdec_subscribe_event(struct iris_inst *inst, const struct v4l2_event_subscription *sub); -+void iris_vdec_src_change(struct iris_inst *inst); - int iris_vdec_streamon_input(struct iris_inst *inst); - int iris_vdec_streamon_output(struct iris_inst *inst); - int iris_vdec_qbuf(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf); --- -2.34.1 - diff --git a/patch/kernel/archive/sm8550-6.12/0022_media--iris--handle-streamoff-on-from-client-in-dy.patch b/patch/kernel/archive/sm8550-6.12/0022_media--iris--handle-streamoff-on-from-client-in-dy.patch deleted file mode 100644 index dfafc076987f..000000000000 --- a/patch/kernel/archive/sm8550-6.12/0022_media--iris--handle-streamoff-on-from-client-in-dy.patch +++ /dev/null @@ -1,343 +0,0 @@ -From a05ae391b45408d171783c2ba08665c7e9f0fd4b Mon Sep 17 00:00:00 2001 -From: Dikshita Agarwal -Date: Fri, 7 Feb 2025 13:25:02 +0530 -Subject: [PATCH] media: iris: handle streamoff/on from client in dynamic - resolution change - -The decoder is stopped after it completes the dynamic resolution change -sequence. Handle VIDIOC_STREAMOFF() and VIDIOC_STREAMON() on the CAPTURE -queue to resume the decoding process. - -Tested-by: Stefan Schmidt # x1e80100 (Dell XPS 13 9345) -Reviewed-by: Stefan Schmidt -Tested-by: Neil Armstrong # on SM8550-QRD -Tested-by: Neil Armstrong # on SM8550-HDK -Signed-off-by: Dikshita Agarwal -Link: https://lore.kernel.org/r/20250207-qcom-video-iris-v10-22-ab66eeffbd20@quicinc.com -Signed-off-by: Neil Armstrong ---- - .../media/platform/qcom/iris/iris_buffer.c | 58 ++++++++++++++++ - .../media/platform/qcom/iris/iris_buffer.h | 1 + - .../platform/qcom/iris/iris_hfi_common.h | 2 + - .../qcom/iris/iris_hfi_gen1_command.c | 10 +++ - .../qcom/iris/iris_hfi_gen1_defines.h | 1 + - .../qcom/iris/iris_hfi_gen2_command.c | 39 +++++++++++ - .../qcom/iris/iris_hfi_gen2_defines.h | 2 + - drivers/media/platform/qcom/iris/iris_vdec.c | 69 ++++++++++++++++++- - 8 files changed, 179 insertions(+), 3 deletions(-) - -diff --git a/drivers/media/platform/qcom/iris/iris_buffer.c b/drivers/media/platform/qcom/iris/iris_buffer.c -index de1267c387f1..dc096e5e95bf 100644 ---- a/drivers/media/platform/qcom/iris/iris_buffer.c -+++ b/drivers/media/platform/qcom/iris/iris_buffer.c -@@ -404,6 +404,47 @@ int iris_destroy_internal_buffers(struct iris_inst *inst, u32 plane) - return 0; - } - -+static int iris_release_internal_buffers(struct iris_inst *inst, -+ enum iris_buffer_type buffer_type) -+{ -+ const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; -+ struct iris_buffers *buffers = &inst->buffers[buffer_type]; -+ struct iris_buffer *buffer, *next; -+ int ret; -+ -+ list_for_each_entry_safe(buffer, next, &buffers->list, list) { -+ if (buffer->attr & BUF_ATTR_PENDING_RELEASE) -+ continue; -+ if (!(buffer->attr & BUF_ATTR_QUEUED)) -+ continue; -+ ret = hfi_ops->session_release_buf(inst, buffer); -+ if (ret) -+ return ret; -+ buffer->attr |= BUF_ATTR_PENDING_RELEASE; -+ } -+ -+ return 0; -+} -+ -+static int iris_release_input_internal_buffers(struct iris_inst *inst) -+{ -+ const struct iris_platform_data *platform_data = inst->core->iris_platform_data; -+ const u32 *internal_buf_type; -+ u32 internal_buffer_count, i; -+ int ret; -+ -+ internal_buf_type = platform_data->dec_ip_int_buf_tbl; -+ internal_buffer_count = platform_data->dec_ip_int_buf_tbl_size; -+ -+ for (i = 0; i < internal_buffer_count; i++) { -+ ret = iris_release_internal_buffers(inst, internal_buf_type[i]); -+ if (ret) -+ return ret; -+ } -+ -+ return 0; -+} -+ - int iris_alloc_and_queue_persist_bufs(struct iris_inst *inst) - { - struct iris_buffers *buffers = &inst->buffers[BUF_PERSIST]; -@@ -435,6 +476,23 @@ int iris_alloc_and_queue_persist_bufs(struct iris_inst *inst) - return 0; - } - -+int iris_alloc_and_queue_input_int_bufs(struct iris_inst *inst) -+{ -+ int ret; -+ -+ iris_get_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); -+ -+ ret = iris_release_input_internal_buffers(inst); -+ if (ret) -+ return ret; -+ -+ ret = iris_create_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); -+ if (ret) -+ return ret; -+ -+ return iris_queue_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); -+} -+ - int iris_queue_deferred_buffers(struct iris_inst *inst, enum iris_buffer_type buf_type) - { - struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; -diff --git a/drivers/media/platform/qcom/iris/iris_buffer.h b/drivers/media/platform/qcom/iris/iris_buffer.h -index 2c7432a59906..c36b6347b077 100644 ---- a/drivers/media/platform/qcom/iris/iris_buffer.h -+++ b/drivers/media/platform/qcom/iris/iris_buffer.h -@@ -108,6 +108,7 @@ int iris_queue_internal_buffers(struct iris_inst *inst, u32 plane); - int iris_destroy_internal_buffer(struct iris_inst *inst, struct iris_buffer *buffer); - int iris_destroy_internal_buffers(struct iris_inst *inst, u32 plane); - int iris_alloc_and_queue_persist_bufs(struct iris_inst *inst); -+int iris_alloc_and_queue_input_int_bufs(struct iris_inst *inst); - int iris_queue_buffer(struct iris_inst *inst, struct iris_buffer *buf); - int iris_queue_deferred_buffers(struct iris_inst *inst, enum iris_buffer_type buf_type); - int iris_vb2_buffer_done(struct iris_inst *inst, struct iris_buffer *buf); -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_common.h b/drivers/media/platform/qcom/iris/iris_hfi_common.h -index 6241098dc31d..8e14a61c9be4 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_common.h -+++ b/drivers/media/platform/qcom/iris/iris_hfi_common.h -@@ -118,6 +118,8 @@ struct iris_hfi_command_ops { - int (*session_start)(struct iris_inst *inst, u32 plane); - int (*session_queue_buf)(struct iris_inst *inst, struct iris_buffer *buffer); - int (*session_release_buf)(struct iris_inst *inst, struct iris_buffer *buffer); -+ int (*session_pause)(struct iris_inst *inst, u32 plane); -+ int (*session_resume_drc)(struct iris_inst *inst, u32 plane); - int (*session_stop)(struct iris_inst *inst, u32 plane); - int (*session_close)(struct iris_inst *inst); - }; -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c -index 03f7e6ea4bf3..e0cb75a112e3 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c -@@ -205,6 +205,15 @@ static int iris_hfi_gen1_session_stop(struct iris_inst *inst, u32 plane) - return ret; - } - -+static int iris_hfi_gen1_session_continue(struct iris_inst *inst, u32 plane) -+{ -+ struct hfi_session_pkt packet; -+ -+ iris_hfi_gen1_packet_session_cmd(inst, &packet, HFI_CMD_SESSION_CONTINUE); -+ -+ return iris_hfi_queue_cmd_write(inst->core, &packet, packet.shdr.hdr.size); -+} -+ - static int iris_hfi_gen1_queue_input_buffer(struct iris_inst *inst, struct iris_buffer *buf) - { - struct hfi_session_empty_buffer_compressed_pkt ip_pkt; -@@ -778,6 +787,7 @@ static const struct iris_hfi_command_ops iris_hfi_gen1_command_ops = { - .session_start = iris_hfi_gen1_session_start, - .session_queue_buf = iris_hfi_gen1_session_queue_buffer, - .session_release_buf = iris_hfi_gen1_session_unset_buffers, -+ .session_resume_drc = iris_hfi_gen1_session_continue, - .session_stop = iris_hfi_gen1_session_stop, - .session_close = iris_hfi_gen1_session_close, - }; -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h -index 416e9a19a26f..c40e0a28b21f 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h -@@ -34,6 +34,7 @@ - #define HFI_CMD_SESSION_FLUSH 0x211008 - #define HFI_CMD_SESSION_RELEASE_BUFFERS 0x21100b - #define HFI_CMD_SESSION_RELEASE_RESOURCES 0x21100c -+#define HFI_CMD_SESSION_CONTINUE 0x21100d - - #define HFI_ERR_SESSION_UNSUPPORTED_SETTING 0x1008 - #define HFI_ERR_SESSION_UNSUPPORTED_STREAM 0x100d -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c -index cc75231f07f1..8efc6a70a57a 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c -@@ -737,6 +737,43 @@ static int iris_hfi_gen2_session_stop(struct iris_inst *inst, u32 plane) - return iris_wait_for_session_response(inst, false); - } - -+static int iris_hfi_gen2_session_pause(struct iris_inst *inst, u32 plane) -+{ -+ struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); -+ -+ iris_hfi_gen2_packet_session_command(inst, -+ HFI_CMD_PAUSE, -+ (HFI_HOST_FLAGS_RESPONSE_REQUIRED | -+ HFI_HOST_FLAGS_INTR_REQUIRED), -+ iris_hfi_gen2_get_port(plane), -+ inst->session_id, -+ HFI_PAYLOAD_NONE, -+ NULL, -+ 0); -+ -+ return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet, -+ inst_hfi_gen2->packet->size); -+} -+ -+static int iris_hfi_gen2_session_resume_drc(struct iris_inst *inst, u32 plane) -+{ -+ struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); -+ u32 payload = HFI_CMD_SETTINGS_CHANGE; -+ -+ iris_hfi_gen2_packet_session_command(inst, -+ HFI_CMD_RESUME, -+ (HFI_HOST_FLAGS_RESPONSE_REQUIRED | -+ HFI_HOST_FLAGS_INTR_REQUIRED), -+ iris_hfi_gen2_get_port(plane), -+ inst->session_id, -+ HFI_PAYLOAD_U32, -+ &payload, -+ sizeof(u32)); -+ -+ return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet, -+ inst_hfi_gen2->packet->size); -+} -+ - static u32 iris_hfi_gen2_buf_type_from_driver(enum iris_buffer_type buffer_type) - { - switch (buffer_type) { -@@ -860,6 +897,8 @@ static const struct iris_hfi_command_ops iris_hfi_gen2_command_ops = { - .session_start = iris_hfi_gen2_session_start, - .session_queue_buf = iris_hfi_gen2_session_queue_buffer, - .session_release_buf = iris_hfi_gen2_session_release_buffer, -+ .session_pause = iris_hfi_gen2_session_pause, -+ .session_resume_drc = iris_hfi_gen2_session_resume_drc, - .session_stop = iris_hfi_gen2_session_stop, - .session_close = iris_hfi_gen2_session_close, - }; -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h -index 42cd57d5e3b1..620bcb90c35f 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h -@@ -17,9 +17,11 @@ - #define HFI_CMD_CLOSE 0x01000004 - #define HFI_CMD_START 0x01000005 - #define HFI_CMD_STOP 0x01000006 -+#define HFI_CMD_RESUME 0x01000008 - #define HFI_CMD_BUFFER 0x01000009 - #define HFI_CMD_SUBSCRIBE_MODE 0x0100000B - #define HFI_CMD_SETTINGS_CHANGE 0x0100000C -+#define HFI_CMD_PAUSE 0x01000011 - #define HFI_CMD_END 0x01FFFFFF - - #define HFI_BITMASK_BITSTREAM_WIDTH 0xffff0000 -diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c b/drivers/media/platform/qcom/iris/iris_vdec.c -index 1da277ed6cb3..47a44978869b 100644 ---- a/drivers/media/platform/qcom/iris/iris_vdec.c -+++ b/drivers/media/platform/qcom/iris/iris_vdec.c -@@ -357,13 +357,37 @@ int iris_vdec_session_streamoff(struct iris_inst *inst, u32 plane) - static int iris_vdec_process_streamon_input(struct iris_inst *inst) - { - const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; -+ enum iris_inst_sub_state set_sub_state = 0; - int ret; - - ret = hfi_ops->session_start(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); - if (ret) - return ret; - -- return iris_inst_state_change_streamon(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); -+ if (inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) { -+ ret = iris_inst_change_sub_state(inst, IRIS_INST_SUB_INPUT_PAUSE, 0); -+ if (ret) -+ return ret; -+ } -+ -+ if (inst->sub_state & IRIS_INST_SUB_DRC || -+ inst->sub_state & IRIS_INST_SUB_FIRST_IPSC) { -+ if (!(inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE)) { -+ if (hfi_ops->session_pause) { -+ ret = hfi_ops->session_pause(inst, -+ V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); -+ if (ret) -+ return ret; -+ } -+ set_sub_state = IRIS_INST_SUB_INPUT_PAUSE; -+ } -+ } -+ -+ ret = iris_inst_state_change_streamon(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); -+ if (ret) -+ return ret; -+ -+ return iris_inst_change_sub_state(inst, 0, set_sub_state); - } - - int iris_vdec_streamon_input(struct iris_inst *inst) -@@ -398,13 +422,52 @@ int iris_vdec_streamon_input(struct iris_inst *inst) - static int iris_vdec_process_streamon_output(struct iris_inst *inst) - { - const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; -- int ret; -+ enum iris_inst_sub_state clear_sub_state = 0; -+ bool drc_active = false; -+ int ret = 0; -+ -+ drc_active = inst->sub_state & IRIS_INST_SUB_DRC && -+ inst->sub_state & IRIS_INST_SUB_DRC_LAST; -+ -+ if (drc_active) -+ clear_sub_state = IRIS_INST_SUB_DRC | IRIS_INST_SUB_DRC_LAST; -+ -+ if (inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) { -+ ret = iris_alloc_and_queue_input_int_bufs(inst); -+ if (ret) -+ return ret; -+ ret = iris_set_stage(inst, STAGE); -+ if (ret) -+ return ret; -+ ret = iris_set_pipe(inst, PIPE); -+ if (ret) -+ return ret; -+ } -+ -+ if (inst->state == IRIS_INST_INPUT_STREAMING && -+ inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) { -+ ret = hfi_ops->session_resume_drc(inst, -+ V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); -+ if (ret) -+ return ret; -+ clear_sub_state |= IRIS_INST_SUB_INPUT_PAUSE; -+ } -+ -+ if (inst->sub_state & IRIS_INST_SUB_FIRST_IPSC) -+ clear_sub_state |= IRIS_INST_SUB_FIRST_IPSC; - - ret = hfi_ops->session_start(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); - if (ret) - return ret; - -- return iris_inst_state_change_streamon(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); -+ if (inst->sub_state & IRIS_INST_SUB_OUTPUT_PAUSE) -+ clear_sub_state |= IRIS_INST_SUB_OUTPUT_PAUSE; -+ -+ ret = iris_inst_state_change_streamon(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); -+ if (ret) -+ return ret; -+ -+ return iris_inst_change_sub_state(inst, clear_sub_state, 0); - } - - int iris_vdec_streamon_output(struct iris_inst *inst) --- -2.34.1 - diff --git a/patch/kernel/archive/sm8550-6.12/0023_media--iris--add-support-for-drain-sequence.patch b/patch/kernel/archive/sm8550-6.12/0023_media--iris--add-support-for-drain-sequence.patch deleted file mode 100644 index 3d184363339d..000000000000 --- a/patch/kernel/archive/sm8550-6.12/0023_media--iris--add-support-for-drain-sequence.patch +++ /dev/null @@ -1,654 +0,0 @@ -From 3949c6727fb8e4418c73108453c3c512b962d6f4 Mon Sep 17 00:00:00 2001 -From: Dikshita Agarwal -Date: Fri, 7 Feb 2025 13:25:03 +0530 -Subject: [PATCH] media: iris: add support for drain sequence - -handle the V4L2_DEC_CMD_STOP by initiating a drain sequence on the -firmware. Process and decode all OUTPUT buffers, that are queued by the -client, before the VIDIOC_DECODER_CMD() was issued and mark the last -buffer with the V4L2_BUF_FLAG_LAST flag. The decoder is stopped, after -processing the last buffer. - -Resume the decoder when one of these operations are issued by the client: -- V4L2_DEC_CMD_START -- pair of VIDIOC_STREAMOFF() and VIDIOC_STREAMON() on the CAPTURE queue -- pair of VIDIOC_STREAMOFF() and VIDIOC_STREAMON() on the OUTPUT queue - -Add the handling to resume decoding when client issues -V4L2_DEC_CMD_START to resume decoding after a source change is detected. - -Tested-by: Stefan Schmidt # x1e80100 (Dell XPS 13 9345) -Reviewed-by: Stefan Schmidt -Tested-by: Neil Armstrong # on SM8550-QRD -Tested-by: Neil Armstrong # on SM8550-HDK -Signed-off-by: Dikshita Agarwal -Link: https://lore.kernel.org/r/20250207-qcom-video-iris-v10-23-ab66eeffbd20@quicinc.com -Signed-off-by: Neil Armstrong ---- - .../platform/qcom/iris/iris_hfi_common.h | 2 + - .../qcom/iris/iris_hfi_gen1_command.c | 13 +++ - .../qcom/iris/iris_hfi_gen1_defines.h | 1 + - .../qcom/iris/iris_hfi_gen1_response.c | 15 +++ - .../qcom/iris/iris_hfi_gen2_command.c | 43 +++++++++ - .../qcom/iris/iris_hfi_gen2_defines.h | 2 + - .../qcom/iris/iris_hfi_gen2_response.c | 46 +++++++++- - drivers/media/platform/qcom/iris/iris_state.c | 68 ++++++++++++++ - drivers/media/platform/qcom/iris/iris_state.h | 13 ++- - drivers/media/platform/qcom/iris/iris_vb2.c | 6 +- - drivers/media/platform/qcom/iris/iris_vdec.c | 91 ++++++++++++++++++- - drivers/media/platform/qcom/iris/iris_vdec.h | 2 + - drivers/media/platform/qcom/iris/iris_vidc.c | 35 +++++++ - 13 files changed, 329 insertions(+), 8 deletions(-) - -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_common.h b/drivers/media/platform/qcom/iris/iris_hfi_common.h -index 8e14a61c9be4..b2c541367fc6 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_common.h -+++ b/drivers/media/platform/qcom/iris/iris_hfi_common.h -@@ -121,6 +121,8 @@ struct iris_hfi_command_ops { - int (*session_pause)(struct iris_inst *inst, u32 plane); - int (*session_resume_drc)(struct iris_inst *inst, u32 plane); - int (*session_stop)(struct iris_inst *inst, u32 plane); -+ int (*session_drain)(struct iris_inst *inst, u32 plane); -+ int (*session_resume_drain)(struct iris_inst *inst, u32 plane); - int (*session_close)(struct iris_inst *inst); - }; - -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c -index e0cb75a112e3..e1fbbb3c196d 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c -@@ -368,6 +368,18 @@ static int iris_hfi_gen1_session_unset_buffers(struct iris_inst *inst, struct ir - return ret; - } - -+static int iris_hfi_gen1_session_drain(struct iris_inst *inst, u32 plane) -+{ -+ struct hfi_session_empty_buffer_compressed_pkt ip_pkt = {0}; -+ -+ ip_pkt.shdr.hdr.size = sizeof(struct hfi_session_empty_buffer_compressed_pkt); -+ ip_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_EMPTY_BUFFER; -+ ip_pkt.shdr.session_id = inst->session_id; -+ ip_pkt.flags = HFI_BUFFERFLAG_EOS; -+ -+ return iris_hfi_queue_cmd_write(inst->core, &ip_pkt, ip_pkt.shdr.hdr.size); -+} -+ - static int - iris_hfi_gen1_packet_session_set_property(struct hfi_session_set_property_pkt *packet, - struct iris_inst *inst, u32 ptype, void *pdata) -@@ -789,6 +801,7 @@ static const struct iris_hfi_command_ops iris_hfi_gen1_command_ops = { - .session_release_buf = iris_hfi_gen1_session_unset_buffers, - .session_resume_drc = iris_hfi_gen1_session_continue, - .session_stop = iris_hfi_gen1_session_stop, -+ .session_drain = iris_hfi_gen1_session_drain, - .session_close = iris_hfi_gen1_session_close, - }; - -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h -index c40e0a28b21f..9f246816a286 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h -@@ -49,6 +49,7 @@ - #define HFI_EVENT_DATA_SEQUENCE_CHANGED_INSUFFICIENT_BUF_RESOURCES 0x1000002 - #define HFI_EVENT_SESSION_SEQUENCE_CHANGED 0x1000003 - -+#define HFI_BUFFERFLAG_EOS 0x00000001 - #define HFI_BUFFERFLAG_TIMESTAMPINVALID 0x00000100 - - #define HFI_FLUSH_OUTPUT 0x1000002 -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c -index 3a47d9f39695..b72d503dd740 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c -@@ -386,6 +386,7 @@ static void iris_hfi_gen1_session_ftb_done(struct iris_inst *inst, void *packet) - struct hfi_msg_session_fbd_uncompressed_plane0_pkt *pkt = packet; - struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; - struct v4l2_m2m_buffer *m2m_buffer, *n; -+ struct hfi_session_flush_pkt flush_pkt; - u32 timestamp_hi = pkt->time_stamp_hi; - u32 timestamp_lo = pkt->time_stamp_lo; - struct iris_core *core = inst->core; -@@ -394,11 +395,25 @@ static void iris_hfi_gen1_session_ftb_done(struct iris_inst *inst, void *packet) - u32 output_tag = pkt->output_tag; - struct iris_buffer *buf, *iter; - struct iris_buffers *buffers; -+ u32 hfi_flags = pkt->flags; - u32 offset = pkt->offset; - u64 timestamp_us = 0; - bool found = false; - u32 flags = 0; - -+ if ((hfi_flags & HFI_BUFFERFLAG_EOS) && !filled_len) { -+ reinit_completion(&inst->flush_completion); -+ -+ flush_pkt.shdr.hdr.size = sizeof(struct hfi_session_flush_pkt); -+ flush_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_FLUSH; -+ flush_pkt.shdr.session_id = inst->session_id; -+ flush_pkt.flush_type = HFI_FLUSH_OUTPUT; -+ iris_hfi_queue_cmd_write(core, &flush_pkt, flush_pkt.shdr.hdr.size); -+ iris_inst_sub_state_change_drain_last(inst); -+ -+ return; -+ } -+ - if (iris_split_mode_enabled(inst) && pkt->stream_id == 0) { - buffers = &inst->buffers[BUF_DPB]; - if (!buffers) -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c -index 8efc6a70a57a..a908b41e2868 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c -@@ -774,6 +774,47 @@ static int iris_hfi_gen2_session_resume_drc(struct iris_inst *inst, u32 plane) - inst_hfi_gen2->packet->size); - } - -+static int iris_hfi_gen2_session_resume_drain(struct iris_inst *inst, u32 plane) -+{ -+ struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); -+ u32 payload = HFI_CMD_DRAIN; -+ -+ iris_hfi_gen2_packet_session_command(inst, -+ HFI_CMD_RESUME, -+ (HFI_HOST_FLAGS_RESPONSE_REQUIRED | -+ HFI_HOST_FLAGS_INTR_REQUIRED), -+ iris_hfi_gen2_get_port(plane), -+ inst->session_id, -+ HFI_PAYLOAD_U32, -+ &payload, -+ sizeof(u32)); -+ -+ return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet, -+ inst_hfi_gen2->packet->size); -+} -+ -+static int iris_hfi_gen2_session_drain(struct iris_inst *inst, u32 plane) -+{ -+ struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); -+ -+ if (!V4L2_TYPE_IS_OUTPUT(plane)) -+ return 0; -+ -+ iris_hfi_gen2_packet_session_command(inst, -+ HFI_CMD_DRAIN, -+ (HFI_HOST_FLAGS_RESPONSE_REQUIRED | -+ HFI_HOST_FLAGS_INTR_REQUIRED | -+ HFI_HOST_FLAGS_NON_DISCARDABLE), -+ iris_hfi_gen2_get_port(plane), -+ inst->session_id, -+ HFI_PAYLOAD_NONE, -+ NULL, -+ 0); -+ -+ return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet, -+ inst_hfi_gen2->packet->size); -+} -+ - static u32 iris_hfi_gen2_buf_type_from_driver(enum iris_buffer_type buffer_type) - { - switch (buffer_type) { -@@ -900,6 +941,8 @@ static const struct iris_hfi_command_ops iris_hfi_gen2_command_ops = { - .session_pause = iris_hfi_gen2_session_pause, - .session_resume_drc = iris_hfi_gen2_session_resume_drc, - .session_stop = iris_hfi_gen2_session_stop, -+ .session_drain = iris_hfi_gen2_session_drain, -+ .session_resume_drain = iris_hfi_gen2_session_resume_drain, - .session_close = iris_hfi_gen2_session_close, - }; - -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h -index 620bcb90c35f..806f8bb7f505 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h -@@ -17,6 +17,7 @@ - #define HFI_CMD_CLOSE 0x01000004 - #define HFI_CMD_START 0x01000005 - #define HFI_CMD_STOP 0x01000006 -+#define HFI_CMD_DRAIN 0x01000007 - #define HFI_CMD_RESUME 0x01000008 - #define HFI_CMD_BUFFER 0x01000009 - #define HFI_CMD_SUBSCRIBE_MODE 0x0100000B -@@ -80,6 +81,7 @@ - #define HFI_INFO_UNSUPPORTED 0x06000001 - #define HFI_INFO_DATA_CORRUPT 0x06000002 - #define HFI_INFO_BUFFER_OVERFLOW 0x06000004 -+#define HFI_INFO_HFI_FLAG_DRAIN_LAST 0x06000006 - #define HFI_INFO_HFI_FLAG_PSC_LAST 0x06000007 - #define HFI_INFORMATION_END 0x06FFFFFF - -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c -index c7552e041138..b75a01641d5d 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c -@@ -201,6 +201,10 @@ static int iris_hfi_gen2_handle_session_info(struct iris_inst *inst, - info = "buffer overflow"; - inst_hfi_gen2->hfi_frame_info.overflow = 1; - break; -+ case HFI_INFO_HFI_FLAG_DRAIN_LAST: -+ info = "drain last flag"; -+ ret = iris_inst_sub_state_change_drain_last(inst); -+ break; - case HFI_INFO_HFI_FLAG_PSC_LAST: - info = "drc last flag"; - ret = iris_inst_sub_state_change_drc_last(inst); -@@ -337,6 +341,12 @@ static int iris_hfi_gen2_handle_output_buffer(struct iris_inst *inst, - bool found = false; - int ret; - -+ if (hfi_buffer->flags & HFI_BUF_FW_FLAG_LAST) { -+ ret = iris_inst_sub_state_change_drain_last(inst); -+ if (ret) -+ return ret; -+ } -+ - if (hfi_buffer->flags & HFI_BUF_FW_FLAG_PSC_LAST) { - ret = iris_inst_sub_state_change_drc_last(inst); - if (ret) -@@ -425,6 +435,21 @@ static int iris_hfi_gen2_handle_release_internal_buffer(struct iris_inst *inst, - return ret; - } - -+static int iris_hfi_gen2_handle_session_stop(struct iris_inst *inst, -+ struct iris_hfi_packet *pkt) -+{ -+ int ret = 0; -+ -+ if (pkt->port == HFI_PORT_RAW) -+ ret = iris_inst_sub_state_change_pause(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); -+ else if (pkt->port == HFI_PORT_BITSTREAM) -+ ret = iris_inst_sub_state_change_pause(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); -+ -+ complete(&inst->completion); -+ -+ return ret; -+} -+ - static int iris_hfi_gen2_handle_session_buffer(struct iris_inst *inst, - struct iris_hfi_packet *pkt) - { -@@ -453,6 +478,22 @@ static int iris_hfi_gen2_handle_session_buffer(struct iris_inst *inst, - return iris_hfi_gen2_handle_release_internal_buffer(inst, buffer); - } - -+static int iris_hfi_gen2_handle_session_drain(struct iris_inst *inst, -+ struct iris_hfi_packet *pkt) -+{ -+ int ret = 0; -+ -+ if (!(pkt->flags & HFI_FW_FLAGS_SUCCESS)) { -+ iris_inst_change_state(inst, IRIS_INST_ERROR); -+ return 0; -+ } -+ -+ if (inst->sub_state & IRIS_INST_SUB_DRAIN) -+ ret = iris_inst_change_sub_state(inst, 0, IRIS_INST_SUB_INPUT_PAUSE); -+ -+ return ret; -+} -+ - static void iris_hfi_gen2_read_input_subcr_params(struct iris_inst *inst) - { - struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); -@@ -572,7 +613,7 @@ static int iris_hfi_gen2_handle_session_command(struct iris_inst *inst, - iris_hfi_gen2_handle_session_close(inst, pkt); - break; - case HFI_CMD_STOP: -- complete(&inst->completion); -+ iris_hfi_gen2_handle_session_stop(inst, pkt); - break; - case HFI_CMD_BUFFER: - ret = iris_hfi_gen2_handle_session_buffer(inst, pkt); -@@ -580,6 +621,9 @@ static int iris_hfi_gen2_handle_session_command(struct iris_inst *inst, - case HFI_CMD_SETTINGS_CHANGE: - ret = iris_hfi_gen2_handle_src_change(inst, pkt); - break; -+ case HFI_CMD_DRAIN: -+ ret = iris_hfi_gen2_handle_session_drain(inst, pkt); -+ break; - default: - break; - } -diff --git a/drivers/media/platform/qcom/iris/iris_state.c b/drivers/media/platform/qcom/iris/iris_state.c -index aad7e734d5c8..f12306e735ec 100644 ---- a/drivers/media/platform/qcom/iris/iris_state.c -+++ b/drivers/media/platform/qcom/iris/iris_state.c -@@ -3,6 +3,8 @@ - * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. - */ - -+#include -+ - #include "iris_instance.h" - - static bool iris_allow_inst_state_change(struct iris_inst *inst, -@@ -148,6 +150,21 @@ int iris_inst_sub_state_change_drc(struct iris_inst *inst) - return iris_inst_change_sub_state(inst, 0, set_sub_state); - } - -+int iris_inst_sub_state_change_drain_last(struct iris_inst *inst) -+{ -+ enum iris_inst_sub_state set_sub_state; -+ -+ if (inst->sub_state & IRIS_INST_SUB_DRAIN_LAST) -+ return -EINVAL; -+ -+ if (!(inst->sub_state & IRIS_INST_SUB_DRAIN)) -+ return -EINVAL; -+ -+ set_sub_state = IRIS_INST_SUB_DRAIN_LAST | IRIS_INST_SUB_OUTPUT_PAUSE; -+ -+ return iris_inst_change_sub_state(inst, 0, set_sub_state); -+} -+ - int iris_inst_sub_state_change_drc_last(struct iris_inst *inst) - { - enum iris_inst_sub_state set_sub_state; -@@ -166,3 +183,54 @@ int iris_inst_sub_state_change_drc_last(struct iris_inst *inst) - - return iris_inst_change_sub_state(inst, 0, set_sub_state); - } -+ -+int iris_inst_sub_state_change_pause(struct iris_inst *inst, u32 plane) -+{ -+ enum iris_inst_sub_state set_sub_state; -+ -+ if (V4L2_TYPE_IS_OUTPUT(plane)) { -+ if (inst->sub_state & IRIS_INST_SUB_DRC && -+ !(inst->sub_state & IRIS_INST_SUB_DRC_LAST)) -+ return -EINVAL; -+ -+ if (inst->sub_state & IRIS_INST_SUB_DRAIN && -+ !(inst->sub_state & IRIS_INST_SUB_DRAIN_LAST)) -+ return -EINVAL; -+ -+ set_sub_state = IRIS_INST_SUB_INPUT_PAUSE; -+ } else { -+ set_sub_state = IRIS_INST_SUB_OUTPUT_PAUSE; -+ } -+ -+ return iris_inst_change_sub_state(inst, 0, set_sub_state); -+} -+ -+static inline bool iris_drc_pending(struct iris_inst *inst) -+{ -+ return inst->sub_state & IRIS_INST_SUB_DRC && -+ inst->sub_state & IRIS_INST_SUB_DRC_LAST; -+} -+ -+static inline bool iris_drain_pending(struct iris_inst *inst) -+{ -+ return inst->sub_state & IRIS_INST_SUB_DRAIN && -+ inst->sub_state & IRIS_INST_SUB_DRAIN_LAST; -+} -+ -+bool iris_allow_cmd(struct iris_inst *inst, u32 cmd) -+{ -+ struct vb2_queue *src_q = v4l2_m2m_get_src_vq(inst->m2m_ctx); -+ struct vb2_queue *dst_q = v4l2_m2m_get_dst_vq(inst->m2m_ctx); -+ -+ if (cmd == V4L2_DEC_CMD_START) { -+ if (vb2_is_streaming(src_q) || vb2_is_streaming(dst_q)) -+ if (iris_drc_pending(inst) || iris_drain_pending(inst)) -+ return true; -+ } else if (cmd == V4L2_DEC_CMD_STOP) { -+ if (vb2_is_streaming(src_q)) -+ if (inst->sub_state != IRIS_INST_SUB_DRAIN) -+ return true; -+ } -+ -+ return false; -+} -diff --git a/drivers/media/platform/qcom/iris/iris_state.h b/drivers/media/platform/qcom/iris/iris_state.h -index b5f0826142f0..a5c0cad4a78c 100644 ---- a/drivers/media/platform/qcom/iris/iris_state.h -+++ b/drivers/media/platform/qcom/iris/iris_state.h -@@ -104,6 +104,9 @@ enum iris_inst_state { - * sent to client. - * @IRIS_INST_SUB_DRC_LAST: indicates last buffer is received from firmware - * as part of source change. -+ * @IRIS_INST_SUB_DRAIN: indicates drain is in progress. -+ * @IRIS_INST_SUB_DRAIN_LAST: indicates last buffer is received from firmware -+ * as part of drain sequence. - * @IRIS_INST_SUB_INPUT_PAUSE: source change is received form firmware. This - * indicates that firmware is paused to process - * any further input frames. -@@ -115,8 +118,10 @@ enum iris_inst_sub_state { - IRIS_INST_SUB_FIRST_IPSC = BIT(0), - IRIS_INST_SUB_DRC = BIT(1), - IRIS_INST_SUB_DRC_LAST = BIT(2), -- IRIS_INST_SUB_INPUT_PAUSE = BIT(3), -- IRIS_INST_SUB_OUTPUT_PAUSE = BIT(4), -+ IRIS_INST_SUB_DRAIN = BIT(3), -+ IRIS_INST_SUB_DRAIN_LAST = BIT(4), -+ IRIS_INST_SUB_INPUT_PAUSE = BIT(5), -+ IRIS_INST_SUB_OUTPUT_PAUSE = BIT(6), - }; - - int iris_inst_change_state(struct iris_inst *inst, -@@ -124,9 +129,13 @@ int iris_inst_change_state(struct iris_inst *inst, - int iris_inst_change_sub_state(struct iris_inst *inst, - enum iris_inst_sub_state clear_sub_state, - enum iris_inst_sub_state set_sub_state); -+ - int iris_inst_state_change_streamon(struct iris_inst *inst, u32 plane); - int iris_inst_state_change_streamoff(struct iris_inst *inst, u32 plane); - int iris_inst_sub_state_change_drc(struct iris_inst *inst); -+int iris_inst_sub_state_change_drain_last(struct iris_inst *inst); - int iris_inst_sub_state_change_drc_last(struct iris_inst *inst); -+int iris_inst_sub_state_change_pause(struct iris_inst *inst, u32 plane); -+bool iris_allow_cmd(struct iris_inst *inst, u32 cmd); - - #endif -diff --git a/drivers/media/platform/qcom/iris/iris_vb2.c b/drivers/media/platform/qcom/iris/iris_vb2.c -index 3b94011533e8..59fc133c9f98 100644 ---- a/drivers/media/platform/qcom/iris/iris_vb2.c -+++ b/drivers/media/platform/qcom/iris/iris_vb2.c -@@ -206,8 +206,10 @@ void iris_vb2_buf_queue(struct vb2_buffer *vb2) - } - - if (V4L2_TYPE_IS_CAPTURE(vb2->vb2_queue->type)) { -- if (inst->sub_state & IRIS_INST_SUB_DRC && -- inst->sub_state & IRIS_INST_SUB_DRC_LAST) { -+ if ((inst->sub_state & IRIS_INST_SUB_DRC && -+ inst->sub_state & IRIS_INST_SUB_DRC_LAST) || -+ (inst->sub_state & IRIS_INST_SUB_DRAIN && -+ inst->sub_state & IRIS_INST_SUB_DRAIN_LAST)) { - vbuf->flags |= V4L2_BUF_FLAG_LAST; - vbuf->sequence = inst->sequence_cap++; - vbuf->field = V4L2_FIELD_NONE; -diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c b/drivers/media/platform/qcom/iris/iris_vdec.c -index 47a44978869b..076e3ee7969f 100644 ---- a/drivers/media/platform/qcom/iris/iris_vdec.c -+++ b/drivers/media/platform/qcom/iris/iris_vdec.c -@@ -371,6 +371,7 @@ static int iris_vdec_process_streamon_input(struct iris_inst *inst) - } - - if (inst->sub_state & IRIS_INST_SUB_DRC || -+ inst->sub_state & IRIS_INST_SUB_DRAIN || - inst->sub_state & IRIS_INST_SUB_FIRST_IPSC) { - if (!(inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE)) { - if (hfi_ops->session_pause) { -@@ -422,15 +423,20 @@ int iris_vdec_streamon_input(struct iris_inst *inst) - static int iris_vdec_process_streamon_output(struct iris_inst *inst) - { - const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; -+ bool drain_active = false, drc_active = false; - enum iris_inst_sub_state clear_sub_state = 0; -- bool drc_active = false; - int ret = 0; - -+ drain_active = inst->sub_state & IRIS_INST_SUB_DRAIN && -+ inst->sub_state & IRIS_INST_SUB_DRAIN_LAST; -+ - drc_active = inst->sub_state & IRIS_INST_SUB_DRC && - inst->sub_state & IRIS_INST_SUB_DRC_LAST; - - if (drc_active) - clear_sub_state = IRIS_INST_SUB_DRC | IRIS_INST_SUB_DRC_LAST; -+ else if (drain_active) -+ clear_sub_state = IRIS_INST_SUB_DRAIN | IRIS_INST_SUB_DRAIN_LAST; - - if (inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) { - ret = iris_alloc_and_queue_input_int_bufs(inst); -@@ -446,8 +452,12 @@ static int iris_vdec_process_streamon_output(struct iris_inst *inst) - - if (inst->state == IRIS_INST_INPUT_STREAMING && - inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) { -- ret = hfi_ops->session_resume_drc(inst, -- V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); -+ if (!drain_active) -+ ret = hfi_ops->session_resume_drc(inst, -+ V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); -+ else if (hfi_ops->session_resume_drain) -+ ret = hfi_ops->session_resume_drain(inst, -+ V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); - if (ret) - return ret; - clear_sub_state |= IRIS_INST_SUB_INPUT_PAUSE; -@@ -565,3 +575,78 @@ int iris_vdec_qbuf(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf) - - return iris_queue_buffer(inst, buf); - } -+ -+int iris_vdec_start_cmd(struct iris_inst *inst) -+{ -+ const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; -+ enum iris_inst_sub_state clear_sub_state = 0; -+ struct vb2_queue *dst_vq; -+ int ret; -+ -+ dst_vq = v4l2_m2m_get_dst_vq(inst->m2m_ctx); -+ -+ if (inst->sub_state & IRIS_INST_SUB_DRC && -+ inst->sub_state & IRIS_INST_SUB_DRC_LAST) { -+ vb2_clear_last_buffer_dequeued(dst_vq); -+ clear_sub_state = IRIS_INST_SUB_DRC | IRIS_INST_SUB_DRC_LAST; -+ -+ if (inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) { -+ ret = hfi_ops->session_resume_drc(inst, -+ V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); -+ if (ret) -+ return ret; -+ clear_sub_state |= IRIS_INST_SUB_INPUT_PAUSE; -+ } -+ if (inst->sub_state & IRIS_INST_SUB_OUTPUT_PAUSE) { -+ ret = hfi_ops->session_resume_drc(inst, -+ V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); -+ if (ret) -+ return ret; -+ clear_sub_state |= IRIS_INST_SUB_OUTPUT_PAUSE; -+ } -+ } else if (inst->sub_state & IRIS_INST_SUB_DRAIN && -+ inst->sub_state & IRIS_INST_SUB_DRAIN_LAST) { -+ vb2_clear_last_buffer_dequeued(dst_vq); -+ clear_sub_state = IRIS_INST_SUB_DRAIN | IRIS_INST_SUB_DRAIN_LAST; -+ if (inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) { -+ if (hfi_ops->session_resume_drain) { -+ ret = -+ hfi_ops->session_resume_drain(inst, -+ V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); -+ if (ret) -+ return ret; -+ } -+ -+ clear_sub_state |= IRIS_INST_SUB_INPUT_PAUSE; -+ } -+ if (inst->sub_state & IRIS_INST_SUB_OUTPUT_PAUSE) { -+ if (hfi_ops->session_resume_drain) { -+ ret = -+ hfi_ops->session_resume_drain(inst, -+ V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); -+ if (ret) -+ return ret; -+ } -+ -+ clear_sub_state |= IRIS_INST_SUB_OUTPUT_PAUSE; -+ } -+ } else { -+ dev_err(inst->core->dev, "start called before receiving last_flag\n"); -+ iris_inst_change_state(inst, IRIS_INST_ERROR); -+ return -EBUSY; -+ } -+ -+ return iris_inst_change_sub_state(inst, clear_sub_state, 0); -+} -+ -+int iris_vdec_stop_cmd(struct iris_inst *inst) -+{ -+ const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; -+ int ret; -+ -+ ret = hfi_ops->session_drain(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); -+ if (ret) -+ return ret; -+ -+ return iris_inst_change_sub_state(inst, 0, IRIS_INST_SUB_DRAIN); -+} -diff --git a/drivers/media/platform/qcom/iris/iris_vdec.h b/drivers/media/platform/qcom/iris/iris_vdec.h -index dfcc2089a1ef..b24932dc511a 100644 ---- a/drivers/media/platform/qcom/iris/iris_vdec.h -+++ b/drivers/media/platform/qcom/iris/iris_vdec.h -@@ -18,6 +18,8 @@ void iris_vdec_src_change(struct iris_inst *inst); - int iris_vdec_streamon_input(struct iris_inst *inst); - int iris_vdec_streamon_output(struct iris_inst *inst); - int iris_vdec_qbuf(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf); -+int iris_vdec_start_cmd(struct iris_inst *inst); -+int iris_vdec_stop_cmd(struct iris_inst *inst); - int iris_vdec_session_streamoff(struct iris_inst *inst, u32 plane); - - #endif -diff --git a/drivers/media/platform/qcom/iris/iris_vidc.c b/drivers/media/platform/qcom/iris/iris_vidc.c -index 2b27df6b1aad..ca0f4e310f77 100644 ---- a/drivers/media/platform/qcom/iris/iris_vidc.c -+++ b/drivers/media/platform/qcom/iris/iris_vidc.c -@@ -365,6 +365,39 @@ static int iris_subscribe_event(struct v4l2_fh *fh, const struct v4l2_event_subs - return iris_vdec_subscribe_event(inst, sub); - } - -+static int iris_dec_cmd(struct file *filp, void *fh, -+ struct v4l2_decoder_cmd *dec) -+{ -+ struct iris_inst *inst = iris_get_inst(filp, NULL); -+ int ret = 0; -+ -+ mutex_lock(&inst->lock); -+ -+ ret = v4l2_m2m_ioctl_decoder_cmd(filp, fh, dec); -+ if (ret) -+ goto unlock; -+ -+ if (inst->state == IRIS_INST_DEINIT) -+ goto unlock; -+ -+ if (!iris_allow_cmd(inst, dec->cmd)) { -+ ret = -EBUSY; -+ goto unlock; -+ } -+ -+ if (dec->cmd == V4L2_DEC_CMD_START) -+ ret = iris_vdec_start_cmd(inst); -+ else if (dec->cmd == V4L2_DEC_CMD_STOP) -+ ret = iris_vdec_stop_cmd(inst); -+ else -+ ret = -EINVAL; -+ -+unlock: -+ mutex_unlock(&inst->lock); -+ -+ return ret; -+} -+ - static struct v4l2_file_operations iris_v4l2_file_ops = { - .owner = THIS_MODULE, - .open = iris_open, -@@ -408,6 +441,8 @@ static const struct v4l2_ioctl_ops iris_v4l2_ioctl_ops = { - .vidioc_unsubscribe_event = v4l2_event_unsubscribe, - .vidioc_streamon = v4l2_m2m_ioctl_streamon, - .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, -+ .vidioc_try_decoder_cmd = v4l2_m2m_ioctl_try_decoder_cmd, -+ .vidioc_decoder_cmd = iris_dec_cmd, - }; - - void iris_init_ops(struct iris_core *core) --- -2.34.1 - diff --git a/patch/kernel/archive/sm8550-6.12/0024_media--iris--add-check-whether-the-video-session-i.patch b/patch/kernel/archive/sm8550-6.12/0024_media--iris--add-check-whether-the-video-session-i.patch deleted file mode 100644 index 5530b1fcf48f..000000000000 --- a/patch/kernel/archive/sm8550-6.12/0024_media--iris--add-check-whether-the-video-session-i.patch +++ /dev/null @@ -1,171 +0,0 @@ -From b4921470cfb37b2d084bae53792149b47887a448 Mon Sep 17 00:00:00 2001 -From: Vedang Nagar -Date: Fri, 7 Feb 2025 13:25:04 +0530 -Subject: [PATCH] media: iris: add check whether the video session is supported - or not - -Based on the hardware capabilities, add a check during start_streaming -and queue_setup, whether the video session is supported by the hardware. - -Signed-off-by: Vedang Nagar -Tested-by: Stefan Schmidt # x1e80100 (Dell XPS 13 9345) -Reviewed-by: Stefan Schmidt -Tested-by: Neil Armstrong # on SM8550-QRD -Tested-by: Neil Armstrong # on SM8550-HDK -Signed-off-by: Dikshita Agarwal -Link: https://lore.kernel.org/r/20250207-qcom-video-iris-v10-24-ab66eeffbd20@quicinc.com -Signed-off-by: Neil Armstrong ---- - .../platform/qcom/iris/iris_platform_common.h | 1 + - .../platform/qcom/iris/iris_platform_sm8550.c | 1 + - drivers/media/platform/qcom/iris/iris_vb2.c | 96 +++++++++++++++++++ - 3 files changed, 98 insertions(+) - -diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h -index de0388a100c3..a5a7d6838d16 100644 ---- a/drivers/media/platform/qcom/iris/iris_platform_common.h -+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h -@@ -144,6 +144,7 @@ struct iris_platform_data { - struct ubwc_config_data *ubwc_config; - u32 num_vpp_pipe; - u32 max_session_count; -+ u32 max_core_mbpf; - const u32 *input_config_params; - unsigned int input_config_params_size; - const u32 *output_config_params; -diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c -index dc51df71c377..8d23978f5cee 100644 ---- a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c -+++ b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c -@@ -233,6 +233,7 @@ struct iris_platform_data sm8550_data = { - .ubwc_config = &ubwc_config_sm8550, - .num_vpp_pipe = 4, - .max_session_count = 16, -+ .max_core_mbpf = ((8192 * 4352) / 256) * 2, - .input_config_params = - sm8550_vdec_input_config_params, - .input_config_params_size = -diff --git a/drivers/media/platform/qcom/iris/iris_vb2.c b/drivers/media/platform/qcom/iris/iris_vb2.c -index 59fc133c9f98..712d37723ec3 100644 ---- a/drivers/media/platform/qcom/iris/iris_vb2.c -+++ b/drivers/media/platform/qcom/iris/iris_vb2.c -@@ -11,6 +11,94 @@ - #include "iris_vb2.h" - #include "iris_vdec.h" - -+static int iris_check_core_mbpf(struct iris_inst *inst) -+{ -+ struct iris_core *core = inst->core; -+ struct iris_inst *instance; -+ u32 total_mbpf = 0; -+ -+ mutex_lock(&core->lock); -+ list_for_each_entry(instance, &core->instances, list) -+ total_mbpf += iris_get_mbpf(instance); -+ mutex_unlock(&core->lock); -+ -+ if (total_mbpf > core->iris_platform_data->max_core_mbpf) -+ return -ENOMEM; -+ -+ return 0; -+} -+ -+static int iris_check_inst_mbpf(struct iris_inst *inst) -+{ -+ struct platform_inst_caps *caps; -+ u32 mbpf, max_mbpf; -+ -+ caps = inst->core->iris_platform_data->inst_caps; -+ max_mbpf = caps->max_mbpf; -+ mbpf = iris_get_mbpf(inst); -+ if (mbpf > max_mbpf) -+ return -ENOMEM; -+ -+ return 0; -+} -+ -+static int iris_check_resolution_supported(struct iris_inst *inst) -+{ -+ u32 width, height, min_width, min_height, max_width, max_height; -+ struct platform_inst_caps *caps; -+ -+ caps = inst->core->iris_platform_data->inst_caps; -+ width = inst->fmt_src->fmt.pix_mp.width; -+ height = inst->fmt_src->fmt.pix_mp.height; -+ -+ min_width = caps->min_frame_width; -+ max_width = caps->max_frame_width; -+ min_height = caps->min_frame_height; -+ max_height = caps->max_frame_height; -+ -+ if (!(min_width <= width && width <= max_width) || -+ !(min_height <= height && height <= max_height)) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+static int iris_check_session_supported(struct iris_inst *inst) -+{ -+ struct iris_core *core = inst->core; -+ struct iris_inst *instance = NULL; -+ bool found = false; -+ int ret; -+ -+ list_for_each_entry(instance, &core->instances, list) { -+ if (instance == inst) -+ found = true; -+ } -+ -+ if (!found) { -+ ret = -EINVAL; -+ goto exit; -+ } -+ -+ ret = iris_check_core_mbpf(inst); -+ if (ret) -+ goto exit; -+ -+ ret = iris_check_inst_mbpf(inst); -+ if (ret) -+ goto exit; -+ -+ ret = iris_check_resolution_supported(inst); -+ if (ret) -+ goto exit; -+ -+ return 0; -+exit: -+ dev_err(inst->core->dev, "current session not supported(%d)\n", ret); -+ -+ return ret; -+} -+ - int iris_vb2_buf_init(struct vb2_buffer *vb2) - { - struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb2); -@@ -48,6 +136,10 @@ int iris_vb2_queue_setup(struct vb2_queue *q, - goto unlock; - } - -+ ret = iris_check_session_supported(inst); -+ if (ret) -+ goto unlock; -+ - if (!inst->once_per_session_set) { - inst->once_per_session_set = true; - -@@ -95,6 +187,10 @@ int iris_vb2_start_streaming(struct vb2_queue *q, unsigned int count) - goto error; - } - -+ ret = iris_check_session_supported(inst); -+ if (ret) -+ goto error; -+ - if (V4L2_TYPE_IS_OUTPUT(q->type)) - ret = iris_vdec_streamon_input(inst); - else if (V4L2_TYPE_IS_CAPTURE(q->type)) --- -2.34.1 - diff --git a/patch/kernel/archive/sm8550-6.12/0025_media--iris--implement-power-scaling-for-vpu2-and-.patch b/patch/kernel/archive/sm8550-6.12/0025_media--iris--implement-power-scaling-for-vpu2-and-.patch deleted file mode 100644 index 3c24ba8bfbfe..000000000000 --- a/patch/kernel/archive/sm8550-6.12/0025_media--iris--implement-power-scaling-for-vpu2-and-.patch +++ /dev/null @@ -1,515 +0,0 @@ -From e7574ebc04231fafe43d1cec2f4d363b8d8587ea Mon Sep 17 00:00:00 2001 -From: Vedang Nagar -Date: Fri, 7 Feb 2025 13:25:05 +0530 -Subject: [PATCH] media: iris: implement power scaling for vpu2 and vpu3 - -Implement power scaling including a specific vpu2 and vpu3 calculation -for clock and bus bandwidth, which depends on the hardware -configuration, codec format, resolution and frame rate. - -Signed-off-by: Vedang Nagar -Tested-by: Stefan Schmidt # x1e80100 (Dell XPS 13 9345) -Reviewed-by: Stefan Schmidt -Tested-by: Neil Armstrong # on SM8550-QRD -Tested-by: Neil Armstrong # on SM8550-HDK -Signed-off-by: Dikshita Agarwal -Link: https://lore.kernel.org/r/20250207-qcom-video-iris-v10-25-ab66eeffbd20@quicinc.com -Signed-off-by: Neil Armstrong ---- - drivers/media/platform/qcom/iris/Makefile | 1 + - .../media/platform/qcom/iris/iris_buffer.c | 3 + - .../media/platform/qcom/iris/iris_instance.h | 6 + - .../platform/qcom/iris/iris_platform_common.h | 23 +++ - .../platform/qcom/iris/iris_platform_sm8550.c | 12 ++ - drivers/media/platform/qcom/iris/iris_power.c | 140 ++++++++++++++++++ - drivers/media/platform/qcom/iris/iris_power.h | 13 ++ - drivers/media/platform/qcom/iris/iris_vb2.c | 3 + - drivers/media/platform/qcom/iris/iris_vdec.c | 7 + - drivers/media/platform/qcom/iris/iris_vpu2.c | 27 ++++ - drivers/media/platform/qcom/iris/iris_vpu3.c | 38 +++++ - .../platform/qcom/iris/iris_vpu_common.h | 1 + - 12 files changed, 274 insertions(+) - create mode 100644 drivers/media/platform/qcom/iris/iris_power.c - create mode 100644 drivers/media/platform/qcom/iris/iris_power.h - -diff --git a/drivers/media/platform/qcom/iris/Makefile b/drivers/media/platform/qcom/iris/Makefile -index ab16189aa9e6..ca31db847273 100644 ---- a/drivers/media/platform/qcom/iris/Makefile -+++ b/drivers/media/platform/qcom/iris/Makefile -@@ -10,6 +10,7 @@ iris-objs += iris_buffer.o \ - iris_hfi_gen2_response.o \ - iris_hfi_queue.o \ - iris_platform_sm8550.o \ -+ iris_power.o \ - iris_probe.o \ - iris_resources.o \ - iris_state.o \ -diff --git a/drivers/media/platform/qcom/iris/iris_buffer.c b/drivers/media/platform/qcom/iris/iris_buffer.c -index dc096e5e95bf..e5c5a564fcb8 100644 ---- a/drivers/media/platform/qcom/iris/iris_buffer.c -+++ b/drivers/media/platform/qcom/iris/iris_buffer.c -@@ -8,6 +8,7 @@ - - #include "iris_buffer.h" - #include "iris_instance.h" -+#include "iris_power.h" - #include "iris_vpu_buffer.h" - - #define PIXELS_4K 4096 -@@ -500,6 +501,8 @@ int iris_queue_deferred_buffers(struct iris_inst *inst, enum iris_buffer_type bu - struct iris_buffer *buf; - int ret; - -+ iris_scale_power(inst); -+ - if (buf_type == BUF_INPUT) { - v4l2_m2m_for_each_src_buf_safe(m2m_ctx, buffer, n) { - buf = to_iris_buffer(&buffer->vb); -diff --git a/drivers/media/platform/qcom/iris/iris_instance.h b/drivers/media/platform/qcom/iris/iris_instance.h -index 89fb63644311..caa3c6507006 100644 ---- a/drivers/media/platform/qcom/iris/iris_instance.h -+++ b/drivers/media/platform/qcom/iris/iris_instance.h -@@ -33,6 +33,9 @@ - * @state: instance state - * @sub_state: instance sub state - * @once_per_session_set: boolean to set once per session property -+ * @max_input_data_size: max size of input data -+ * @power: structure of power info -+ * @icc_data: structure of interconnect data - * @m2m_dev: a reference to m2m device structure - * @m2m_ctx: a reference to m2m context structure - * @sequence_cap: a sequence counter for capture queue -@@ -60,6 +63,9 @@ struct iris_inst { - enum iris_inst_state state; - enum iris_inst_sub_state sub_state; - bool once_per_session_set; -+ size_t max_input_data_size; -+ struct iris_inst_power power; -+ struct icc_vote_data icc_data; - struct v4l2_m2m_dev *m2m_dev; - struct v4l2_m2m_ctx *m2m_ctx; - u32 sequence_cap; -diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h -index a5a7d6838d16..189dd081ad0a 100644 ---- a/drivers/media/platform/qcom/iris/iris_platform_common.h -+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h -@@ -20,6 +20,8 @@ struct iris_inst; - #define CODED_FRAMES_PROGRESSIVE 0x0 - #define DEFAULT_MAX_HOST_BUF_COUNT 64 - #define DEFAULT_MAX_HOST_BURST_BUF_COUNT 256 -+#define DEFAULT_FPS 30 -+ - enum stage_type { - STAGE_1 = 1, - STAGE_2 = 2, -@@ -67,6 +69,10 @@ struct platform_inst_caps { - u32 min_frame_height; - u32 max_frame_height; - u32 max_mbpf; -+ u32 mb_cycles_vsp; -+ u32 mb_cycles_vpp; -+ u32 mb_cycles_fw; -+ u32 mb_cycles_fw_vpp; - u32 num_comv; - }; - -@@ -106,11 +112,26 @@ struct platform_inst_fw_cap { - enum platform_inst_fw_cap_type cap_id); - }; - -+struct bw_info { -+ u32 mbs_per_sec; -+ u32 bw_ddr; -+}; -+ - struct iris_core_power { - u64 clk_freq; - u64 icc_bw; - }; - -+struct iris_inst_power { -+ u64 min_freq; -+ u32 icc_bw; -+}; -+ -+struct icc_vote_data { -+ u32 height, width; -+ u32 fps; -+}; -+ - enum platform_pm_domain_type { - IRIS_CTRL_POWER_DOMAIN, - IRIS_HW_POWER_DOMAIN, -@@ -124,6 +145,8 @@ struct iris_platform_data { - void (*set_preset_registers)(struct iris_core *core); - const struct icc_info *icc_tbl; - unsigned int icc_tbl_size; -+ const struct bw_info *bw_tbl_dec; -+ unsigned int bw_tbl_dec_size; - const char * const *pmdomain_tbl; - unsigned int pmdomain_tbl_size; - const char * const *opp_pd_tbl; -diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c -index 8d23978f5cee..35d278996c43 100644 ---- a/drivers/media/platform/qcom/iris/iris_platform_sm8550.c -+++ b/drivers/media/platform/qcom/iris/iris_platform_sm8550.c -@@ -126,6 +126,9 @@ static struct platform_inst_caps platform_inst_cap_sm8550 = { - .min_frame_height = 96, - .max_frame_height = 8192, - .max_mbpf = (8192 * 4352) / 256, -+ .mb_cycles_vpp = 200, -+ .mb_cycles_fw = 489583, -+ .mb_cycles_fw_vpp = 66234, - .num_comv = 0, - }; - -@@ -141,6 +144,13 @@ static const struct icc_info sm8550_icc_table[] = { - - static const char * const sm8550_clk_reset_table[] = { "bus" }; - -+static const struct bw_info sm8550_bw_table_dec[] = { -+ { ((4096 * 2160) / 256) * 60, 1608000 }, -+ { ((4096 * 2160) / 256) * 30, 826000 }, -+ { ((1920 * 1080) / 256) * 60, 567000 }, -+ { ((1920 * 1080) / 256) * 30, 294000 }, -+}; -+ - static const char * const sm8550_pmdomain_table[] = { "venus", "vcodec0" }; - - static const char * const sm8550_opp_pd_table[] = { "mxc", "mmcx" }; -@@ -214,6 +224,8 @@ struct iris_platform_data sm8550_data = { - .icc_tbl_size = ARRAY_SIZE(sm8550_icc_table), - .clk_rst_tbl = sm8550_clk_reset_table, - .clk_rst_tbl_size = ARRAY_SIZE(sm8550_clk_reset_table), -+ .bw_tbl_dec = sm8550_bw_table_dec, -+ .bw_tbl_dec_size = ARRAY_SIZE(sm8550_bw_table_dec), - .pmdomain_tbl = sm8550_pmdomain_table, - .pmdomain_tbl_size = ARRAY_SIZE(sm8550_pmdomain_table), - .opp_pd_tbl = sm8550_opp_pd_table, -diff --git a/drivers/media/platform/qcom/iris/iris_power.c b/drivers/media/platform/qcom/iris/iris_power.c -new file mode 100644 -index 000000000000..dbca42df0910 ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_power.c -@@ -0,0 +1,140 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#include -+#include -+#include -+ -+#include "iris_buffer.h" -+#include "iris_instance.h" -+#include "iris_power.h" -+#include "iris_resources.h" -+#include "iris_vpu_common.h" -+ -+static u32 iris_calc_bw(struct iris_inst *inst, struct icc_vote_data *data) -+{ -+ const struct bw_info *bw_tbl = NULL; -+ struct iris_core *core = inst->core; -+ u32 num_rows, i, mbs, mbps; -+ u32 icc_bw = 0; -+ -+ mbs = DIV_ROUND_UP(data->height, 16) * DIV_ROUND_UP(data->width, 16); -+ mbps = mbs * data->fps; -+ if (mbps == 0) -+ goto exit; -+ -+ bw_tbl = core->iris_platform_data->bw_tbl_dec; -+ num_rows = core->iris_platform_data->bw_tbl_dec_size; -+ -+ for (i = 0; i < num_rows; i++) { -+ if (i != 0 && mbps > bw_tbl[i].mbs_per_sec) -+ break; -+ -+ icc_bw = bw_tbl[i].bw_ddr; -+ } -+ -+exit: -+ return icc_bw; -+} -+ -+static int iris_set_interconnects(struct iris_inst *inst) -+{ -+ struct iris_core *core = inst->core; -+ struct iris_inst *instance; -+ u64 total_bw_ddr = 0; -+ int ret; -+ -+ mutex_lock(&core->lock); -+ list_for_each_entry(instance, &core->instances, list) { -+ if (!instance->max_input_data_size) -+ continue; -+ -+ total_bw_ddr += instance->power.icc_bw; -+ } -+ -+ ret = iris_set_icc_bw(core, total_bw_ddr); -+ -+ mutex_unlock(&core->lock); -+ -+ return ret; -+} -+ -+static int iris_vote_interconnects(struct iris_inst *inst) -+{ -+ struct icc_vote_data *vote_data = &inst->icc_data; -+ struct v4l2_format *inp_f = inst->fmt_src; -+ -+ vote_data->width = inp_f->fmt.pix_mp.width; -+ vote_data->height = inp_f->fmt.pix_mp.height; -+ vote_data->fps = DEFAULT_FPS; -+ -+ inst->power.icc_bw = iris_calc_bw(inst, vote_data); -+ -+ return iris_set_interconnects(inst); -+} -+ -+static int iris_set_clocks(struct iris_inst *inst) -+{ -+ struct iris_core *core = inst->core; -+ struct iris_inst *instance; -+ u64 freq = 0; -+ int ret; -+ -+ mutex_lock(&core->lock); -+ list_for_each_entry(instance, &core->instances, list) { -+ if (!instance->max_input_data_size) -+ continue; -+ -+ freq += instance->power.min_freq; -+ } -+ -+ core->power.clk_freq = freq; -+ ret = dev_pm_opp_set_rate(core->dev, freq); -+ mutex_unlock(&core->lock); -+ -+ return ret; -+} -+ -+static int iris_scale_clocks(struct iris_inst *inst) -+{ -+ const struct vpu_ops *vpu_ops = inst->core->iris_platform_data->vpu_ops; -+ struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; -+ struct v4l2_m2m_buffer *buffer, *n; -+ struct iris_buffer *buf; -+ size_t data_size = 0; -+ -+ v4l2_m2m_for_each_src_buf_safe(m2m_ctx, buffer, n) { -+ buf = to_iris_buffer(&buffer->vb); -+ data_size = max(data_size, buf->data_size); -+ } -+ -+ inst->max_input_data_size = data_size; -+ if (!inst->max_input_data_size) -+ return 0; -+ -+ inst->power.min_freq = vpu_ops->calc_freq(inst, inst->max_input_data_size); -+ -+ return iris_set_clocks(inst); -+} -+ -+int iris_scale_power(struct iris_inst *inst) -+{ -+ struct iris_core *core = inst->core; -+ int ret; -+ -+ if (pm_runtime_suspended(core->dev)) { -+ ret = pm_runtime_resume_and_get(core->dev); -+ if (ret < 0) -+ return ret; -+ -+ pm_runtime_put_autosuspend(core->dev); -+ } -+ -+ ret = iris_scale_clocks(inst); -+ if (ret) -+ return ret; -+ -+ return iris_vote_interconnects(inst); -+} -diff --git a/drivers/media/platform/qcom/iris/iris_power.h b/drivers/media/platform/qcom/iris/iris_power.h -new file mode 100644 -index 000000000000..55212660e72d ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_power.h -@@ -0,0 +1,13 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#ifndef __IRIS_POWER_H__ -+#define __IRIS_POWER_H__ -+ -+struct iris_inst; -+ -+int iris_scale_power(struct iris_inst *inst); -+ -+#endif -diff --git a/drivers/media/platform/qcom/iris/iris_vb2.c b/drivers/media/platform/qcom/iris/iris_vb2.c -index 712d37723ec3..cdf11feb590b 100644 ---- a/drivers/media/platform/qcom/iris/iris_vb2.c -+++ b/drivers/media/platform/qcom/iris/iris_vb2.c -@@ -10,6 +10,7 @@ - #include "iris_instance.h" - #include "iris_vb2.h" - #include "iris_vdec.h" -+#include "iris_power.h" - - static int iris_check_core_mbpf(struct iris_inst *inst) - { -@@ -187,6 +188,8 @@ int iris_vb2_start_streaming(struct vb2_queue *q, unsigned int count) - goto error; - } - -+ iris_scale_power(inst); -+ - ret = iris_check_session_supported(inst); - if (ret) - goto error; -diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c b/drivers/media/platform/qcom/iris/iris_vdec.c -index 076e3ee7969f..4143acedfc57 100644 ---- a/drivers/media/platform/qcom/iris/iris_vdec.c -+++ b/drivers/media/platform/qcom/iris/iris_vdec.c -@@ -9,6 +9,7 @@ - #include "iris_buffer.h" - #include "iris_ctrls.h" - #include "iris_instance.h" -+#include "iris_power.h" - #include "iris_vdec.h" - #include "iris_vpu_buffer.h" - -@@ -360,6 +361,8 @@ static int iris_vdec_process_streamon_input(struct iris_inst *inst) - enum iris_inst_sub_state set_sub_state = 0; - int ret; - -+ iris_scale_power(inst); -+ - ret = hfi_ops->session_start(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); - if (ret) - return ret; -@@ -427,6 +430,8 @@ static int iris_vdec_process_streamon_output(struct iris_inst *inst) - enum iris_inst_sub_state clear_sub_state = 0; - int ret = 0; - -+ iris_scale_power(inst); -+ - drain_active = inst->sub_state & IRIS_INST_SUB_DRAIN && - inst->sub_state & IRIS_INST_SUB_DRAIN_LAST; - -@@ -573,6 +578,8 @@ int iris_vdec_qbuf(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf) - return 0; - } - -+ iris_scale_power(inst); -+ - return iris_queue_buffer(inst, buf); - } - -diff --git a/drivers/media/platform/qcom/iris/iris_vpu2.c b/drivers/media/platform/qcom/iris/iris_vpu2.c -index bd8427411576..8f502aed43ce 100644 ---- a/drivers/media/platform/qcom/iris/iris_vpu2.c -+++ b/drivers/media/platform/qcom/iris/iris_vpu2.c -@@ -6,6 +6,33 @@ - #include "iris_instance.h" - #include "iris_vpu_common.h" - -+static u64 iris_vpu2_calc_freq(struct iris_inst *inst, size_t data_size) -+{ -+ struct platform_inst_caps *caps = inst->core->iris_platform_data->inst_caps; -+ struct v4l2_format *inp_f = inst->fmt_src; -+ u32 mbs_per_second, mbpf, height, width; -+ unsigned long vpp_freq, vsp_freq; -+ u32 fps = DEFAULT_FPS; -+ -+ width = max(inp_f->fmt.pix_mp.width, inst->crop.width); -+ height = max(inp_f->fmt.pix_mp.height, inst->crop.height); -+ -+ mbpf = NUM_MBS_PER_FRAME(height, width); -+ mbs_per_second = mbpf * fps; -+ -+ vpp_freq = mbs_per_second * caps->mb_cycles_vpp; -+ -+ /* 21 / 20 is overhead factor */ -+ vpp_freq += vpp_freq / 20; -+ vsp_freq = mbs_per_second * caps->mb_cycles_vsp; -+ -+ /* 10 / 7 is overhead factor */ -+ vsp_freq += ((fps * data_size * 8) * 10) / 7; -+ -+ return max(vpp_freq, vsp_freq); -+} -+ - const struct vpu_ops iris_vpu2_ops = { - .power_off_hw = iris_vpu_power_off_hw, -+ .calc_freq = iris_vpu2_calc_freq, - }; -diff --git a/drivers/media/platform/qcom/iris/iris_vpu3.c b/drivers/media/platform/qcom/iris/iris_vpu3.c -index 10599f1fa789..b484638e6105 100644 ---- a/drivers/media/platform/qcom/iris/iris_vpu3.c -+++ b/drivers/media/platform/qcom/iris/iris_vpu3.c -@@ -79,6 +79,44 @@ static void iris_vpu3_power_off_hardware(struct iris_core *core) - iris_vpu_power_off_hw(core); - } - -+static u64 iris_vpu3_calculate_frequency(struct iris_inst *inst, size_t data_size) -+{ -+ struct platform_inst_caps *caps = inst->core->iris_platform_data->inst_caps; -+ struct v4l2_format *inp_f = inst->fmt_src; -+ u32 height, width, mbs_per_second, mbpf; -+ u64 fw_cycles, fw_vpp_cycles; -+ u64 vsp_cycles, vpp_cycles; -+ u32 fps = DEFAULT_FPS; -+ -+ width = max(inp_f->fmt.pix_mp.width, inst->crop.width); -+ height = max(inp_f->fmt.pix_mp.height, inst->crop.height); -+ -+ mbpf = NUM_MBS_PER_FRAME(height, width); -+ mbs_per_second = mbpf * fps; -+ -+ fw_cycles = fps * caps->mb_cycles_fw; -+ fw_vpp_cycles = fps * caps->mb_cycles_fw_vpp; -+ -+ vpp_cycles = mult_frac(mbs_per_second, caps->mb_cycles_vpp, (u32)inst->fw_caps[PIPE].value); -+ /* 21 / 20 is minimum overhead factor */ -+ vpp_cycles += max(div_u64(vpp_cycles, 20), fw_vpp_cycles); -+ -+ /* 1.059 is multi-pipe overhead */ -+ if (inst->fw_caps[PIPE].value > 1) -+ vpp_cycles += div_u64(vpp_cycles * 59, 1000); -+ -+ vsp_cycles = fps * data_size * 8; -+ vsp_cycles = div_u64(vsp_cycles, 2); -+ /* VSP FW overhead 1.05 */ -+ vsp_cycles = div_u64(vsp_cycles * 21, 20); -+ -+ if (inst->fw_caps[STAGE].value == STAGE_1) -+ vsp_cycles = vsp_cycles * 3; -+ -+ return max3(vpp_cycles, vsp_cycles, fw_cycles); -+} -+ - const struct vpu_ops iris_vpu3_ops = { - .power_off_hw = iris_vpu3_power_off_hardware, -+ .calc_freq = iris_vpu3_calculate_frequency, - }; -diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.h b/drivers/media/platform/qcom/iris/iris_vpu_common.h -index d3efa7c0ce9a..63fa1fa5a498 100644 ---- a/drivers/media/platform/qcom/iris/iris_vpu_common.h -+++ b/drivers/media/platform/qcom/iris/iris_vpu_common.h -@@ -13,6 +13,7 @@ extern const struct vpu_ops iris_vpu3_ops; - - struct vpu_ops { - void (*power_off_hw)(struct iris_core *core); -+ u64 (*calc_freq)(struct iris_inst *inst, size_t data_size); - }; - - int iris_vpu_boot_firmware(struct iris_core *core); --- -2.34.1 - diff --git a/patch/kernel/archive/sm8550-6.12/0026_media--iris--add-check-to-allow-sub-states-transit.patch b/patch/kernel/archive/sm8550-6.12/0026_media--iris--add-check-to-allow-sub-states-transit.patch deleted file mode 100644 index b5d3d86cd706..000000000000 --- a/patch/kernel/archive/sm8550-6.12/0026_media--iris--add-check-to-allow-sub-states-transit.patch +++ /dev/null @@ -1,141 +0,0 @@ -From 0d739925590b4a67db4468920a6288b707b87f7e Mon Sep 17 00:00:00 2001 -From: Vedang Nagar -Date: Fri, 7 Feb 2025 13:25:06 +0530 -Subject: [PATCH] media: iris: add check to allow sub states transitions - -Based on the design of the state machine, add checks whether the -transition from one sub-state to another is allowed. - -Signed-off-by: Vedang Nagar -Tested-by: Stefan Schmidt # x1e80100 (Dell XPS 13 9345) -Reviewed-by: Stefan Schmidt -Tested-by: Neil Armstrong # on SM8550-QRD -Tested-by: Neil Armstrong # on SM8550-HDK -Signed-off-by: Dikshita Agarwal -Link: https://lore.kernel.org/r/20250207-qcom-video-iris-v10-26-ab66eeffbd20@quicinc.com -Signed-off-by: Neil Armstrong ---- - .../qcom/iris/iris_hfi_gen1_command.c | 12 +++++- - drivers/media/platform/qcom/iris/iris_state.c | 40 +++++++++++++++++++ - drivers/media/platform/qcom/iris/iris_state.h | 3 ++ - 3 files changed, 54 insertions(+), 1 deletion(-) - -diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c -index e1fbbb3c196d..64f887d9a17d 100644 ---- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c -+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c -@@ -135,6 +135,9 @@ static int iris_hfi_gen1_session_start(struct iris_inst *inst, u32 plane) - if (!V4L2_TYPE_IS_OUTPUT(plane)) - return 0; - -+ if (inst->sub_state & IRIS_INST_SUB_LOAD_RESOURCES) -+ return 0; -+ - reinit_completion(&inst->completion); - iris_hfi_gen1_packet_session_cmd(inst, &packet, HFI_CMD_SESSION_LOAD_RESOURCES); - -@@ -153,7 +156,11 @@ static int iris_hfi_gen1_session_start(struct iris_inst *inst, u32 plane) - if (ret) - return ret; - -- return iris_wait_for_session_response(inst, false); -+ ret = iris_wait_for_session_response(inst, false); -+ if (ret) -+ return ret; -+ -+ return iris_inst_change_sub_state(inst, 0, IRIS_INST_SUB_LOAD_RESOURCES); - } - - static int iris_hfi_gen1_session_stop(struct iris_inst *inst, u32 plane) -@@ -180,6 +187,9 @@ static int iris_hfi_gen1_session_stop(struct iris_inst *inst, u32 plane) - ret = iris_hfi_queue_cmd_write(core, &pkt, pkt.shdr.hdr.size); - if (!ret) - ret = iris_wait_for_session_response(inst, false); -+ -+ iris_inst_change_sub_state(inst, IRIS_INST_SUB_LOAD_RESOURCES, 0); -+ - iris_helper_buffers_done(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, - VB2_BUF_STATE_ERROR); - iris_helper_buffers_done(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, -diff --git a/drivers/media/platform/qcom/iris/iris_state.c b/drivers/media/platform/qcom/iris/iris_state.c -index f12306e735ec..5976e926c83d 100644 ---- a/drivers/media/platform/qcom/iris/iris_state.c -+++ b/drivers/media/platform/qcom/iris/iris_state.c -@@ -105,6 +105,43 @@ int iris_inst_state_change_streamoff(struct iris_inst *inst, u32 plane) - return iris_inst_change_state(inst, new_state); - } - -+static bool iris_inst_allow_sub_state(struct iris_inst *inst, enum iris_inst_sub_state sub_state) -+{ -+ if (!sub_state) -+ return true; -+ -+ switch (inst->state) { -+ case IRIS_INST_INIT: -+ if (sub_state & IRIS_INST_SUB_LOAD_RESOURCES) -+ return true; -+ return false; -+ case IRIS_INST_INPUT_STREAMING: -+ if (sub_state & (IRIS_INST_SUB_FIRST_IPSC | IRIS_INST_SUB_DRC | -+ IRIS_INST_SUB_DRAIN | IRIS_INST_SUB_INPUT_PAUSE)) -+ return true; -+ return false; -+ case IRIS_INST_OUTPUT_STREAMING: -+ if (sub_state & (IRIS_INST_SUB_DRC_LAST | -+ IRIS_INST_SUB_DRAIN_LAST | IRIS_INST_SUB_OUTPUT_PAUSE)) -+ return true; -+ return false; -+ case IRIS_INST_STREAMING: -+ if (sub_state & (IRIS_INST_SUB_DRC | IRIS_INST_SUB_DRAIN | -+ IRIS_INST_SUB_DRC_LAST | IRIS_INST_SUB_DRAIN_LAST | -+ IRIS_INST_SUB_INPUT_PAUSE | IRIS_INST_SUB_OUTPUT_PAUSE)) -+ return true; -+ return false; -+ case IRIS_INST_DEINIT: -+ if (sub_state & (IRIS_INST_SUB_DRC | IRIS_INST_SUB_DRAIN | -+ IRIS_INST_SUB_DRC_LAST | IRIS_INST_SUB_DRAIN_LAST | -+ IRIS_INST_SUB_INPUT_PAUSE | IRIS_INST_SUB_OUTPUT_PAUSE)) -+ return true; -+ return false; -+ default: -+ return false; -+ } -+} -+ - int iris_inst_change_sub_state(struct iris_inst *inst, - enum iris_inst_sub_state clear_sub_state, - enum iris_inst_sub_state set_sub_state) -@@ -124,6 +161,9 @@ int iris_inst_change_sub_state(struct iris_inst *inst, - - prev_sub_state = inst->sub_state; - -+ if (!iris_inst_allow_sub_state(inst, set_sub_state)) -+ return -EINVAL; -+ - inst->sub_state |= set_sub_state; - inst->sub_state &= ~clear_sub_state; - -diff --git a/drivers/media/platform/qcom/iris/iris_state.h b/drivers/media/platform/qcom/iris/iris_state.h -index a5c0cad4a78c..78c61aac5e7e 100644 ---- a/drivers/media/platform/qcom/iris/iris_state.h -+++ b/drivers/media/platform/qcom/iris/iris_state.h -@@ -113,6 +113,8 @@ enum iris_inst_state { - * @IRIS_INST_SUB_OUTPUT_PAUSE: last buffer is received form firmware as part - * of drc sequence. This indicates that - * firmware is paused to process any further output frames. -+ * @IRIS_INST_SUB_LOAD_RESOURCES: indicates all the resources have been loaded by the -+ * firmware and it is ready for processing. - */ - enum iris_inst_sub_state { - IRIS_INST_SUB_FIRST_IPSC = BIT(0), -@@ -122,6 +124,7 @@ enum iris_inst_sub_state { - IRIS_INST_SUB_DRAIN_LAST = BIT(4), - IRIS_INST_SUB_INPUT_PAUSE = BIT(5), - IRIS_INST_SUB_OUTPUT_PAUSE = BIT(6), -+ IRIS_INST_SUB_LOAD_RESOURCES = BIT(7), - }; - - int iris_inst_change_state(struct iris_inst *inst, --- -2.34.1 - diff --git a/patch/kernel/archive/sm8550-6.12/0027_media--iris--enable-video-driver-probe-of-SM8250-S.patch b/patch/kernel/archive/sm8550-6.12/0027_media--iris--enable-video-driver-probe-of-SM8250-S.patch deleted file mode 100644 index be89ab0cff9f..000000000000 --- a/patch/kernel/archive/sm8550-6.12/0027_media--iris--enable-video-driver-probe-of-SM8250-S.patch +++ /dev/null @@ -1,223 +0,0 @@ -From 22bd43173801987066a8379a0d0f7c5b02dfc1b1 Mon Sep 17 00:00:00 2001 -From: Dikshita Agarwal -Date: Fri, 7 Feb 2025 13:25:07 +0530 -Subject: [PATCH] media: iris: enable video driver probe of SM8250 SoC - -Initialize the platform data and enable video driver probe of SM8250 -SoC. - -Tested-by: Stefan Schmidt # x1e80100 (Dell XPS 13 9345) -Reviewed-by: Stefan Schmidt -Tested-by: Neil Armstrong # on SM8550-QRD -Tested-by: Neil Armstrong # on SM8550-HDK -Signed-off-by: Dikshita Agarwal -Link: https://lore.kernel.org/r/20250207-qcom-video-iris-v10-27-ab66eeffbd20@quicinc.com -Signed-off-by: Neil Armstrong ---- - drivers/media/platform/qcom/iris/Makefile | 4 + - .../platform/qcom/iris/iris_platform_common.h | 1 + - .../platform/qcom/iris/iris_platform_sm8250.c | 149 ++++++++++++++++++ - drivers/media/platform/qcom/iris/iris_probe.c | 6 + - 4 files changed, 160 insertions(+) - create mode 100644 drivers/media/platform/qcom/iris/iris_platform_sm8250.c - -diff --git a/drivers/media/platform/qcom/iris/Makefile b/drivers/media/platform/qcom/iris/Makefile -index ca31db847273..f6d22b88f6db 100644 ---- a/drivers/media/platform/qcom/iris/Makefile -+++ b/drivers/media/platform/qcom/iris/Makefile -@@ -23,4 +23,8 @@ iris-objs += iris_buffer.o \ - iris_vpu_buffer.o \ - iris_vpu_common.o \ - -+ifeq ($(CONFIG_VIDEO_QCOM_VENUS),) -+iris-objs += iris_platform_sm8250.o -+endif -+ - obj-$(CONFIG_VIDEO_QCOM_IRIS) += iris.o -diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h -index 189dd081ad0a..f6b15d2805fb 100644 ---- a/drivers/media/platform/qcom/iris/iris_platform_common.h -+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h -@@ -33,6 +33,7 @@ enum pipe_type { - PIPE_4 = 4, - }; - -+extern struct iris_platform_data sm8250_data; - extern struct iris_platform_data sm8550_data; - - enum platform_clk_type { -diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8250.c b/drivers/media/platform/qcom/iris/iris_platform_sm8250.c -new file mode 100644 -index 000000000000..5c86fd7b7b6f ---- /dev/null -+++ b/drivers/media/platform/qcom/iris/iris_platform_sm8250.c -@@ -0,0 +1,149 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#include "iris_core.h" -+#include "iris_ctrls.h" -+#include "iris_platform_common.h" -+#include "iris_resources.h" -+#include "iris_hfi_gen1.h" -+#include "iris_hfi_gen1_defines.h" -+#include "iris_vpu_common.h" -+ -+static struct platform_inst_fw_cap inst_fw_cap_sm8250[] = { -+ { -+ .cap_id = PIPE, -+ .min = PIPE_1, -+ .max = PIPE_4, -+ .step_or_mask = 1, -+ .value = PIPE_4, -+ .hfi_id = HFI_PROPERTY_PARAM_WORK_ROUTE, -+ .set = iris_set_pipe, -+ }, -+ { -+ .cap_id = STAGE, -+ .min = STAGE_1, -+ .max = STAGE_2, -+ .step_or_mask = 1, -+ .value = STAGE_2, -+ .hfi_id = HFI_PROPERTY_PARAM_WORK_MODE, -+ .set = iris_set_stage, -+ }, -+ { -+ .cap_id = DEBLOCK, -+ .min = 0, -+ .max = 1, -+ .step_or_mask = 1, -+ .value = 0, -+ .hfi_id = HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER, -+ .set = iris_set_u32, -+ }, -+}; -+ -+static struct platform_inst_caps platform_inst_cap_sm8250 = { -+ .min_frame_width = 128, -+ .max_frame_width = 8192, -+ .min_frame_height = 128, -+ .max_frame_height = 8192, -+ .max_mbpf = 138240, -+ .mb_cycles_vsp = 25, -+ .mb_cycles_vpp = 200, -+}; -+ -+static void iris_set_sm8250_preset_registers(struct iris_core *core) -+{ -+ writel(0x0, core->reg_base + 0xB0088); -+} -+ -+static const struct icc_info sm8250_icc_table[] = { -+ { "cpu-cfg", 1000, 1000 }, -+ { "video-mem", 1000, 15000000 }, -+}; -+ -+static const char * const sm8250_clk_reset_table[] = { "bus", "core" }; -+ -+static const struct bw_info sm8250_bw_table_dec[] = { -+ { ((4096 * 2160) / 256) * 60, 2403000 }, -+ { ((4096 * 2160) / 256) * 30, 1224000 }, -+ { ((1920 * 1080) / 256) * 60, 812000 }, -+ { ((1920 * 1080) / 256) * 30, 416000 }, -+}; -+ -+static const char * const sm8250_pmdomain_table[] = { "venus", "vcodec0" }; -+ -+static const char * const sm8250_opp_pd_table[] = { "mx" }; -+ -+static const struct platform_clk_data sm8250_clk_table[] = { -+ {IRIS_AXI_CLK, "iface" }, -+ {IRIS_CTRL_CLK, "core" }, -+ {IRIS_HW_CLK, "vcodec0_core" }, -+}; -+ -+static struct tz_cp_config tz_cp_config_sm8250 = { -+ .cp_start = 0, -+ .cp_size = 0x25800000, -+ .cp_nonpixel_start = 0x01000000, -+ .cp_nonpixel_size = 0x24800000, -+}; -+ -+static const u32 sm8250_vdec_input_config_param_default[] = { -+ HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE, -+ HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT, -+ HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO, -+ HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL, -+ HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM, -+ HFI_PROPERTY_PARAM_FRAME_SIZE, -+ HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL, -+ HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE, -+}; -+ -+static const u32 sm8250_dec_ip_int_buf_tbl[] = { -+ BUF_BIN, -+ BUF_SCRATCH_1, -+}; -+ -+static const u32 sm8250_dec_op_int_buf_tbl[] = { -+ BUF_DPB, -+}; -+ -+struct iris_platform_data sm8250_data = { -+ .get_instance = iris_hfi_gen1_get_instance, -+ .init_hfi_command_ops = &iris_hfi_gen1_command_ops_init, -+ .init_hfi_response_ops = iris_hfi_gen1_response_ops_init, -+ .vpu_ops = &iris_vpu2_ops, -+ .set_preset_registers = iris_set_sm8250_preset_registers, -+ .icc_tbl = sm8250_icc_table, -+ .icc_tbl_size = ARRAY_SIZE(sm8250_icc_table), -+ .clk_rst_tbl = sm8250_clk_reset_table, -+ .clk_rst_tbl_size = ARRAY_SIZE(sm8250_clk_reset_table), -+ .bw_tbl_dec = sm8250_bw_table_dec, -+ .bw_tbl_dec_size = ARRAY_SIZE(sm8250_bw_table_dec), -+ .pmdomain_tbl = sm8250_pmdomain_table, -+ .pmdomain_tbl_size = ARRAY_SIZE(sm8250_pmdomain_table), -+ .opp_pd_tbl = sm8250_opp_pd_table, -+ .opp_pd_tbl_size = ARRAY_SIZE(sm8250_opp_pd_table), -+ .clk_tbl = sm8250_clk_table, -+ .clk_tbl_size = ARRAY_SIZE(sm8250_clk_table), -+ /* Upper bound of DMA address range */ -+ .dma_mask = 0xe0000000 - 1, -+ .fwname = "qcom/vpu-1.0/venus.mbn", -+ .pas_id = IRIS_PAS_ID, -+ .inst_caps = &platform_inst_cap_sm8250, -+ .inst_fw_caps = inst_fw_cap_sm8250, -+ .inst_fw_caps_size = ARRAY_SIZE(inst_fw_cap_sm8250), -+ .tz_cp_config_data = &tz_cp_config_sm8250, -+ .hw_response_timeout = HW_RESPONSE_TIMEOUT_VALUE, -+ .num_vpp_pipe = 4, -+ .max_session_count = 16, -+ .max_core_mbpf = (8192 * 4352) / 256, -+ .input_config_params = -+ sm8250_vdec_input_config_param_default, -+ .input_config_params_size = -+ ARRAY_SIZE(sm8250_vdec_input_config_param_default), -+ -+ .dec_ip_int_buf_tbl = sm8250_dec_ip_int_buf_tbl, -+ .dec_ip_int_buf_tbl_size = ARRAY_SIZE(sm8250_dec_ip_int_buf_tbl), -+ .dec_op_int_buf_tbl = sm8250_dec_op_int_buf_tbl, -+ .dec_op_int_buf_tbl_size = ARRAY_SIZE(sm8250_dec_op_int_buf_tbl), -+}; -diff --git a/drivers/media/platform/qcom/iris/iris_probe.c b/drivers/media/platform/qcom/iris/iris_probe.c -index 954cc7c0cc97..aca442dcc153 100644 ---- a/drivers/media/platform/qcom/iris/iris_probe.c -+++ b/drivers/media/platform/qcom/iris/iris_probe.c -@@ -324,6 +324,12 @@ static const struct of_device_id iris_dt_match[] = { - .compatible = "qcom,sm8550-iris", - .data = &sm8550_data, - }, -+#if (!IS_ENABLED(CONFIG_VIDEO_QCOM_VENUS)) -+ { -+ .compatible = "qcom,sm8250-venus", -+ .data = &sm8250_data, -+ }, -+#endif - { }, - }; - MODULE_DEVICE_TABLE(of, iris_dt_match); --- -2.34.1 - diff --git a/patch/kernel/archive/sm8550-6.12/0028_media--MAINTAINERS--add-Qualcomm-iris-video-accele.patch b/patch/kernel/archive/sm8550-6.12/0028_media--MAINTAINERS--add-Qualcomm-iris-video-accele.patch deleted file mode 100644 index 39d7c34b878b..000000000000 --- a/patch/kernel/archive/sm8550-6.12/0028_media--MAINTAINERS--add-Qualcomm-iris-video-accele.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 0018ef7f51ba5f9001b8870aab40d4db86cccf90 Mon Sep 17 00:00:00 2001 -From: Dikshita Agarwal -Date: Fri, 7 Feb 2025 13:25:08 +0530 -Subject: [PATCH] media: MAINTAINERS: add Qualcomm iris video accelerator - driver - -Add an entry for the iris video decoder accelerator driver. - -Signed-off-by: Vikash Garodia -Tested-by: Stefan Schmidt # x1e80100 (Dell XPS 13 9345) -Reviewed-by: Stefan Schmidt -Tested-by: Neil Armstrong # on SM8550-QRD -Tested-by: Neil Armstrong # on SM8550-HDK -Signed-off-by: Dikshita Agarwal -Link: https://lore.kernel.org/r/20250207-qcom-video-iris-v10-28-ab66eeffbd20@quicinc.com -Signed-off-by: Neil Armstrong ---- - MAINTAINERS | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/MAINTAINERS b/MAINTAINERS -index 0fa7c5728f1e..fb253f68816b 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -19352,6 +19352,16 @@ S: Maintained - F: Documentation/devicetree/bindings/regulator/vqmmc-ipq4019-regulator.yaml - F: drivers/regulator/vqmmc-ipq4019-regulator.c - -+QUALCOMM IRIS VIDEO ACCELERATOR DRIVER -+M: Vikash Garodia -+M: Dikshita Agarwal -+R: Abhinav Kumar -+L: linux-media@vger.kernel.org -+L: linux-arm-msm@vger.kernel.org -+S: Maintained -+F: Documentation/devicetree/bindings/media/qcom,*-iris.yaml -+F: drivers/media/platform/qcom/iris/ -+ - QUALCOMM NAND CONTROLLER DRIVER - M: Manivannan Sadhasivam - L: linux-mtd@lists.infradead.org --- -2.34.1 - diff --git a/patch/kernel/archive/sm8550-6.12/0029_arm64--dts--qcom--sm8550--Add-iris-video-codec-nod.patch b/patch/kernel/archive/sm8550-6.12/0029_arm64--dts--qcom--sm8550--Add-iris-video-codec-nod.patch deleted file mode 100644 index 57f089efd90b..000000000000 --- a/patch/kernel/archive/sm8550-6.12/0029_arm64--dts--qcom--sm8550--Add-iris-video-codec-nod.patch +++ /dev/null @@ -1,100 +0,0 @@ -From 8b02771befadcb1b666488c48fa92ec14a07407a Mon Sep 17 00:00:00 2001 -From: Teguh Sobirin -Date: Wed, 12 Feb 2025 20:50:35 +0800 -Subject: [PATCH] arm64: dts: qcom: sm8550: Add iris video-codec node - -Signed-off-by: Teguh Sobirin ---- - arch/arm64/boot/dts/qcom/sm8550.dtsi | 69 ++++++++++++++++++++++++++++ - 1 file changed, 69 insertions(+) - -diff --git a/arch/arm64/boot/dts/qcom/sm8550.dtsi b/arch/arm64/boot/dts/qcom/sm8550.dtsi -index a2daf9712fc0..42cd9649a962 100644 ---- a/arch/arm64/boot/dts/qcom/sm8550.dtsi -+++ b/arch/arm64/boot/dts/qcom/sm8550.dtsi -@@ -14,6 +14,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -2867,6 +2868,74 @@ opp-202000000 { - }; - }; - -+ video-codec@aa00000 { -+ compatible = "qcom,sm8550-iris"; -+ reg = <0 0x0aa00000 0 0xf0000>; -+ interrupts = ; -+ -+ power-domains = <&videocc VIDEO_CC_MVS0C_GDSC>, -+ <&videocc VIDEO_CC_MVS0_GDSC>, -+ <&rpmhpd RPMHPD_MXC>, -+ <&rpmhpd RPMHPD_MMCX>; -+ power-domain-names = "venus", "vcodec0", "mxc", "mmcx"; -+ -+ clocks = <&gcc GCC_VIDEO_AXI0_CLK>, -+ <&videocc VIDEO_CC_MVS0C_CLK>, -+ <&videocc VIDEO_CC_MVS0_CLK>; -+ clock-names = "iface", "core", "vcodec0_core"; -+ -+ interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS -+ &config_noc SLAVE_VENUS_CFG QCOM_ICC_TAG_ALWAYS>, -+ <&mmss_noc MASTER_VIDEO QCOM_ICC_TAG_ALWAYS -+ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; -+ interconnect-names = "cpu-cfg", "video-mem"; -+ -+ memory-region = <&video_mem>; -+ -+ resets = <&gcc GCC_VIDEO_AXI0_CLK_ARES>; -+ reset-names = "bus"; -+ -+ iommus = <&apps_smmu 0x1940 0x0000>, -+ <&apps_smmu 0x1947 0x0000>; -+ dma-coherent; -+ -+ operating-points-v2 = <&iris_opp_table>; -+ -+ iris_opp_table: opp-table { -+ compatible = "operating-points-v2"; -+ -+ opp-240000000 { -+ opp-hz = /bits/ 64 <240000000>; -+ required-opps = <&rpmhpd_opp_svs>, -+ <&rpmhpd_opp_low_svs>; -+ }; -+ -+ opp-338000000 { -+ opp-hz = /bits/ 64 <338000000>; -+ required-opps = <&rpmhpd_opp_svs>, -+ <&rpmhpd_opp_svs>; -+ }; -+ -+ opp-366000000 { -+ opp-hz = /bits/ 64 <366000000>; -+ required-opps = <&rpmhpd_opp_svs_l1>, -+ <&rpmhpd_opp_svs_l1>; -+ }; -+ -+ opp-444000000 { -+ opp-hz = /bits/ 64 <444000000>; -+ required-opps = <&rpmhpd_opp_turbo>, -+ <&rpmhpd_opp_turbo>; -+ }; -+ -+ opp-533333334 { -+ opp-hz = /bits/ 64 <533333334>; -+ required-opps = <&rpmhpd_opp_turbo_l1>, -+ <&rpmhpd_opp_turbo_l1>; -+ }; -+ }; -+ }; -+ - videocc: clock-controller@aaf0000 { - compatible = "qcom,sm8550-videocc"; - reg = <0 0x0aaf0000 0 0x10000>; --- -2.34.1 - diff --git a/patch/kernel/archive/sm8550-6.12/0032_drm-panel--Add-panel-driver-for-Chipone-ICNA3512-b.patch b/patch/kernel/archive/sm8550-6.12/0032_drm-panel--Add-panel-driver-for-Chipone-ICNA3512-b.patch deleted file mode 100644 index 6d4db21c8476..000000000000 --- a/patch/kernel/archive/sm8550-6.12/0032_drm-panel--Add-panel-driver-for-Chipone-ICNA3512-b.patch +++ /dev/null @@ -1,530 +0,0 @@ -From aae567ecbda8e1c3a8d4aaebc90914b6ff740785 Mon Sep 17 00:00:00 2001 -From: Teguh Sobirin -Date: Thu, 13 Feb 2025 18:25:19 +0800 -Subject: [PATCH] drm/panel: Add panel driver for Chipone ICNA3512 based panels - -Signed-off-by: Teguh Sobirin ---- - drivers/gpu/drm/panel/Kconfig | 11 + - drivers/gpu/drm/panel/Makefile | 1 + - .../gpu/drm/panel/panel-chipone-icna3512.c | 473 ++++++++++++++++++ - 3 files changed, 485 insertions(+) - create mode 100644 drivers/gpu/drm/panel/panel-chipone-icna3512.c - -diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig -index d7469c565d1d..112a7bfcd169 100644 ---- a/drivers/gpu/drm/panel/Kconfig -+++ b/drivers/gpu/drm/panel/Kconfig -@@ -96,6 +96,17 @@ config DRM_PANEL_BOE_TV101WUM_LL2 - Say Y here if you want to support for BOE TV101WUM-LL2 - WUXGA PANEL DSI Video Mode panel - -+config DRM_PANEL_CHIPONE_ICNA3512 -+ tristate "Chipone ICNA3512 panel driver" -+ depends on OF -+ depends on DRM_MIPI_DSI -+ depends on BACKLIGHT_CLASS_DEVICE -+ select DRM_DISPLAY_HELPER -+ help -+ Say Y here if you want to enable support for the panels built -+ around the Chipone ICNA3512 display controller, such as some -+ Tianma panels used in AYN Odin2 Portal. -+ - config DRM_PANEL_EBBG_FT8719 - tristate "EBBG FT8719 panel driver" - depends on OF -diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile -index 7dcf72646cac..8773117908c8 100644 ---- a/drivers/gpu/drm/panel/Makefile -+++ b/drivers/gpu/drm/panel/Makefile -@@ -8,6 +8,7 @@ obj-$(CONFIG_DRM_PANEL_BOE_HIMAX8279D) += panel-boe-himax8279d.o - obj-$(CONFIG_DRM_PANEL_BOE_TH101MB31UIG002_28A) += panel-boe-th101mb31ig002-28a.o - obj-$(CONFIG_DRM_PANEL_BOE_TV101WUM_LL2) += panel-boe-tv101wum-ll2.o - obj-$(CONFIG_DRM_PANEL_BOE_TV101WUM_NL6) += panel-boe-tv101wum-nl6.o -+obj-$(CONFIG_DRM_PANEL_CHIPONE_ICNA3512) += panel-chipone-icna3512.o - obj-$(CONFIG_DRM_PANEL_DSI_CM) += panel-dsi-cm.o - obj-$(CONFIG_DRM_PANEL_LVDS) += panel-lvds.o - obj-$(CONFIG_DRM_PANEL_SIMPLE) += panel-simple.o -diff --git a/drivers/gpu/drm/panel/panel-chipone-icna3512.c b/drivers/gpu/drm/panel/panel-chipone-icna3512.c -new file mode 100644 -index 000000000000..cbda976df1db ---- /dev/null -+++ b/drivers/gpu/drm/panel/panel-chipone-icna3512.c -@@ -0,0 +1,473 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Chipone ICNA3512 Driver IC panels driver -+ * -+ * Copyright (c) 2025 Teguh Sobirin -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include