diff --git a/target/linux/bcm27xx/Makefile b/target/linux/bcm27xx/Makefile index e408c9040..d7b56b23b 100644 --- a/target/linux/bcm27xx/Makefile +++ b/target/linux/bcm27xx/Makefile @@ -9,9 +9,9 @@ ARCH:=arm BOARD:=bcm27xx BOARDNAME:=Broadcom BCM27xx FEATURES:=audio boot-part display ext4 fpu gpio rootfs-part rtc squashfs usb usbgadget -SUBTARGETS:=bcm2708 bcm2709 bcm2710 bcm2711 +SUBTARGETS:=bcm2708 bcm2709 bcm2710 bcm2711 bcm2712 -KERNEL_PATCHVER:=5.15 +KERNEL_PATCHVER:=6.1 define Target/Description Build firmware image for Broadcom BCM27xx SoC devices. @@ -22,7 +22,7 @@ include $(INCLUDE_DIR)/target.mk DEFAULT_PACKAGES := $(filter-out urngd,$(DEFAULT_PACKAGES)) DEFAULT_PACKAGES += \ - bcm27xx-gpu-fw \ + bcm27xx-gpu-fw bcm27xx-utils \ kmod-usb-hid \ kmod-sound-core kmod-sound-arm-bcm2835 \ kmod-fs-vfat kmod-nls-cp437 kmod-nls-iso8859-1 \ diff --git a/target/linux/bcm27xx/base-files/etc/board.d/02_network b/target/linux/bcm27xx/base-files/etc/board.d/02_network index 23bc9afdb..f246139c3 100644 --- a/target/linux/bcm27xx/base-files/etc/board.d/02_network +++ b/target/linux/bcm27xx/base-files/etc/board.d/02_network @@ -17,6 +17,7 @@ raspberrypi,3-model-b-plus |\ raspberrypi,400 |\ raspberrypi,4-compute-module |\ raspberrypi,4-model-b |\ +raspberrypi,5-model-b |\ raspberrypi,model-b |\ raspberrypi,model-b-plus |\ raspberrypi,model-b-rev2) diff --git a/target/linux/bcm27xx/base-files/etc/diag.sh b/target/linux/bcm27xx/base-files/etc/diag.sh index 180b31ec9..92d72bea1 100644 --- a/target/linux/bcm27xx/base-files/etc/diag.sh +++ b/target/linux/bcm27xx/base-files/etc/diag.sh @@ -14,6 +14,7 @@ set_state() { raspberrypi,400 |\ raspberrypi,4-compute-module |\ raspberrypi,4-model-b |\ + raspberrypi,5-model-b |\ raspberrypi,model-b-plus) status_led="led1" ;; diff --git a/target/linux/bcm27xx/base-files/lib/preinit/05_set_preinit_iface_brcm2708 b/target/linux/bcm27xx/base-files/lib/preinit/05_set_preinit_iface_brcm2708 index c52995bd1..120475b55 100644 --- a/target/linux/bcm27xx/base-files/lib/preinit/05_set_preinit_iface_brcm2708 +++ b/target/linux/bcm27xx/base-files/lib/preinit/05_set_preinit_iface_brcm2708 @@ -12,6 +12,7 @@ set_preinit_iface() { raspberrypi,400 |\ raspberrypi,4-compute-module |\ raspberrypi,4-model-b |\ + raspberrypi,5-model-b |\ raspberrypi,model-b |\ raspberrypi,model-b-plus |\ raspberrypi,model-b-rev2) diff --git a/target/linux/bcm27xx/base-files/lib/preinit/79_move_config b/target/linux/bcm27xx/base-files/lib/preinit/79_move_config index c9fb59a64..db5bf93b6 100644 --- a/target/linux/bcm27xx/base-files/lib/preinit/79_move_config +++ b/target/linux/bcm27xx/base-files/lib/preinit/79_move_config @@ -2,16 +2,20 @@ . /lib/upgrade/common.sh -BOOTPART=/dev/mmcblk0p1 - move_config() { - if [ -b $BOOTPART ]; then + local partdev + + export_bootdevice && export_partdevice partdev 1 || { + partdev=mmcblk0p1 + } + + if [ -b "/dev/$partdev" ]; then insmod nls_cp437 insmod nls_iso8859-1 insmod fat insmod vfat mkdir -p /boot - mount -t vfat -o rw,noatime $BOOTPART /boot + mount -t vfat -o rw,noatime /dev/$partdev /boot [ -f "/boot/$BACKUP_FILE" ] && mv -f "/boot/$BACKUP_FILE" / fi } diff --git a/target/linux/bcm27xx/base-files/lib/upgrade/platform.sh b/target/linux/bcm27xx/base-files/lib/upgrade/platform.sh index a48b7cc08..956bc1c78 100644 --- a/target/linux/bcm27xx/base-files/lib/upgrade/platform.sh +++ b/target/linux/bcm27xx/base-files/lib/upgrade/platform.sh @@ -90,7 +90,7 @@ platform_copy_config() { if export_partdevice partdev 1; then mkdir -p /boot - [ -f /boot/kernel.img ] || mount -t vfat -o rw,noatime "/dev/$partdev" /boot + [ -f "/boot/kernel*.img" ] || mount -t vfat -o rw,noatime "/dev/$partdev" /boot cp -af "$UPGRADE_BACKUP" "/boot/$BACKUP_FILE" tar -C / -zxvf "$UPGRADE_BACKUP" boot/cmdline.txt boot/config.txt sync diff --git a/target/linux/bcm27xx/bcm2708/config-5.15 b/target/linux/bcm27xx/bcm2708/config-6.1 similarity index 90% rename from target/linux/bcm27xx/bcm2708/config-5.15 rename to target/linux/bcm27xx/bcm2708/config-6.1 index 1c2b177c2..af5d0183e 100644 --- a/target/linux/bcm27xx/bcm2708/config-5.15 +++ b/target/linux/bcm27xx/bcm2708/config-6.1 @@ -1,5 +1,6 @@ # CONFIG_AIO is not set CONFIG_ALIGNMENT_TRAP=y +CONFIG_APERTURE_HELPERS=y CONFIG_ARCH_32BIT_OFF_T=y CONFIG_ARCH_BCM=y CONFIG_ARCH_BCM2835=y @@ -17,9 +18,8 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_ARM=y CONFIG_ARM_AMBA=y CONFIG_ARM_CPU_SUSPEND=y -CONFIG_ARM_CRYPTO=y CONFIG_ARM_ERRATA_411920=y -CONFIG_ARM_HAS_SG_CHAIN=y +CONFIG_ARM_HAS_GROUP_RELOCS=y CONFIG_ARM_L1_CACHE_SHIFT=5 # CONFIG_ARM_MHU_V2 is not set CONFIG_ARM_PATCH_PHYS_VIRT=y @@ -30,7 +30,6 @@ CONFIG_ARM_UNWIND=y CONFIG_AUTO_ZRELADDR=y CONFIG_BCM2708_VCMEM=y # CONFIG_BCM2711_THERMAL is not set -CONFIG_BCM2835_DEVGPIOMEM=y CONFIG_BCM2835_FAST_MEMCPY=y CONFIG_BCM2835_MBOX=y CONFIG_BCM2835_POWER=y @@ -54,6 +53,9 @@ CONFIG_BLK_PM=y CONFIG_BRCMSTB_L2_IRQ=y CONFIG_BRCM_CHAR_DRIVERS=y # CONFIG_CACHE_L2X0 is not set +CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y +CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" +CONFIG_CC_NO_ARRAY_BOUNDS=y CONFIG_CLKSRC_MMIO=y CONFIG_CLK_BCM2711_DVP=y CONFIG_CLK_BCM2835=y @@ -71,6 +73,7 @@ CONFIG_CMA_SIZE_SEL_MBYTES=y # CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set # CONFIG_CMA_SYSFS is not set CONFIG_COMMON_CLK=y +CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1 CONFIG_COMPAT_32BIT_TIME=y CONFIG_CONFIGFS_FS=y CONFIG_CONSOLE_TRANSLATIONS=y @@ -100,19 +103,23 @@ CONFIG_CPU_HAS_ASID=y CONFIG_CPU_IDLE=y CONFIG_CPU_IDLE_GOV_LADDER=y CONFIG_CPU_IDLE_GOV_MENU=y +CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_CPU_PABRT_V6=y CONFIG_CPU_PM=y CONFIG_CPU_THUMB_CAPABLE=y CONFIG_CPU_TLB_V6=y CONFIG_CPU_V6K=y CONFIG_CRC16=y -CONFIG_CRYPTO_BLAKE2S=y CONFIG_CRYPTO_CRC32=y CONFIG_CRYPTO_CRC32C=y CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y +CONFIG_CRYPTO_LIB_SHA1=y +CONFIG_CRYPTO_LIB_UTILS=y CONFIG_CRYPTO_RNG2=y +CONFIG_CURRENT_POINTER_IN_TPIDRURO=y CONFIG_DCACHE_WORD_ACCESS=y CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" CONFIG_DMABUF_HEAPS=y CONFIG_DMABUF_HEAPS_CMA=y @@ -124,7 +131,6 @@ CONFIG_DMA_CMA=y CONFIG_DMA_ENGINE=y CONFIG_DMA_OF=y CONFIG_DMA_OPS=y -CONFIG_DMA_REMAP=y CONFIG_DMA_SHARED_BUFFER=y CONFIG_DMA_VIRTUAL_CHANNELS=y CONFIG_DNOTIFY=y @@ -132,6 +138,7 @@ CONFIG_DTC=y CONFIG_DUMMY_CONSOLE=y CONFIG_EDAC_ATOMIC_SCRUB=y CONFIG_EDAC_SUPPORT=y +CONFIG_EXCLUSIVE_SYSTEM_RAM=y CONFIG_EXT4_FS=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y @@ -143,7 +150,6 @@ CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_IMAGEBLIT=y CONFIG_FB_CMDLINE=y -# CONFIG_FB_RPISENSE is not set CONFIG_FB_SIMPLE=y CONFIG_FIQ=y CONFIG_FIXED_PHY=y @@ -151,8 +157,6 @@ CONFIG_FIX_EARLYCON_MEM=y CONFIG_FONT_8x16=y CONFIG_FONT_8x8=y CONFIG_FONT_SUPPORT=y -# CONFIG_FPE_FASTFPE is not set -# CONFIG_FPE_NWFPE is not set CONFIG_FRAMEBUFFER_CONSOLE=y # CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y @@ -163,6 +167,8 @@ CONFIG_FS_POSIX_ACL=y CONFIG_FWNODE_MDIO=y CONFIG_FW_CACHE=y CONFIG_FW_LOADER_PAGED_BUF=y +CONFIG_FW_LOADER_SYSFS=y +CONFIG_GCC11_NO_ARRAY_BOUNDS=y CONFIG_GENERIC_ALLOCATOR=y CONFIG_GENERIC_BUG=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -187,7 +193,6 @@ CONFIG_GPIOLIB_IRQCHIP=y CONFIG_GPIO_CDEV=y # CONFIG_GPIO_FSM is not set CONFIG_GPIO_RASPBERRYPI_EXP=y -CONFIG_HANDLE_DOMAIN_IRQ=y CONFIG_HARDIRQS_SW_RESEND=y CONFIG_HAS_DMA=y CONFIG_HAS_IOMEM=y @@ -205,6 +210,7 @@ CONFIG_INPUT_MOUSEDEV=y CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 CONFIG_IRQCHIP=y +CONFIG_IRQSTACKS=y CONFIG_IRQ_DOMAIN=y CONFIG_IRQ_FORCED_THREADING=y CONFIG_IRQ_WORK=y @@ -228,16 +234,20 @@ CONFIG_MAILBOX=y CONFIG_MDIO_BUS=y CONFIG_MDIO_DEVICE=y CONFIG_MDIO_DEVRES=y +CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_CONTROLLER=y +CONFIG_MEDIA_PLATFORM_DRIVERS=y +CONFIG_MEDIA_PLATFORM_SUPPORT=y +CONFIG_MEDIA_SUPPORT=y +CONFIG_MEDIA_SUPPORT_FILTER=y CONFIG_MEMFD_CREATE=y CONFIG_MEMORY_ISOLATION=y CONFIG_MFD_CORE=y -# CONFIG_MFD_RASPBERRYPI_POE_HAT is not set -# CONFIG_MFD_RPISENSE_CORE is not set CONFIG_MFD_SYSCON=y CONFIG_MIGHT_HAVE_CACHE_L2X0=y CONFIG_MIGRATION=y CONFIG_MMC=y -CONFIG_MMC_BCM2835=y +# CONFIG_MMC_BCM2835 is not set CONFIG_MMC_BCM2835_DMA=y CONFIG_MMC_BCM2835_MMC=y CONFIG_MMC_BCM2835_PIO_DMA_BARRIER=2 @@ -258,7 +268,7 @@ CONFIG_NO_HZ=y CONFIG_NO_HZ_COMMON=y CONFIG_NO_HZ_IDLE=y CONFIG_NVMEM=y -CONFIG_OABI_COMPAT=y +CONFIG_NVMEM_LAYOUTS=y CONFIG_OF=y CONFIG_OF_ADDRESS=y CONFIG_OF_CONFIGFS=y @@ -274,6 +284,9 @@ CONFIG_OF_RESOLVE=y CONFIG_OLD_SIGACTION=y CONFIG_OLD_SIGSUSPEND3=y CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_PAGE_POOL=y +CONFIG_PAGE_SIZE_LESS_THAN_256KB=y +CONFIG_PAGE_SIZE_LESS_THAN_64KB=y CONFIG_PERF_USE_VMALLOC=y CONFIG_PGTABLE_LEVELS=2 CONFIG_PHYLIB=y @@ -287,12 +300,15 @@ CONFIG_PM_GENERIC_DOMAINS_SLEEP=y CONFIG_PM_OPP=y CONFIG_PM_SLEEP=y CONFIG_POWER_SUPPLY=y +CONFIG_PREEMPT_NONE_BUILD=y CONFIG_PRINTK_TIME=y CONFIG_PTP_1588_CLOCK_OPTIONAL=y CONFIG_PWM=y CONFIG_PWM_BCM2835=y CONFIG_PWM_SYSFS=y +CONFIG_RANDSTRUCT_NONE=y CONFIG_RASPBERRYPI_FIRMWARE=y +CONFIG_RASPBERRYPI_GPIOMEM=y CONFIG_RASPBERRYPI_POWER=y CONFIG_RATIONAL=y # CONFIG_RAVE_SP_CORE is not set @@ -324,6 +340,7 @@ CONFIG_SERIAL_MCTRL_GPIO=y CONFIG_SERIAL_OF_PLATFORM=y CONFIG_SG_POOL=y CONFIG_SMSC_PHY=y +CONFIG_SOFTIRQ_ON_OWN_STACK=y CONFIG_SPARSE_IRQ=y CONFIG_SRCU=y # CONFIG_STRIP_ASM_SYMS is not set @@ -337,6 +354,7 @@ CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 CONFIG_THERMAL_GOV_STEP_WISE=y CONFIG_THERMAL_OF=y +CONFIG_THREAD_INFO_IN_TASK=y CONFIG_TICK_CPU_ACCOUNTING=y CONFIG_TIMER_OF=y CONFIG_TIMER_PROBE=y @@ -360,6 +378,8 @@ CONFIG_USB_USBNET=y CONFIG_USE_OF=y CONFIG_VCHIQ_CDEV=y CONFIG_VFP=y +CONFIG_VIDEO_DEV=y +CONFIG_VIDEO_V4L2_I2C=y CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_VT_CONSOLE_SLEEP=y diff --git a/target/linux/bcm27xx/bcm2709/config-5.15 b/target/linux/bcm27xx/bcm2709/config-6.1 similarity index 91% rename from target/linux/bcm27xx/bcm2709/config-5.15 rename to target/linux/bcm27xx/bcm2709/config-6.1 index f9a98cb7d..4d307add5 100644 --- a/target/linux/bcm27xx/bcm2709/config-5.15 +++ b/target/linux/bcm27xx/bcm2709/config-6.1 @@ -1,9 +1,9 @@ # CONFIG_AIO is not set CONFIG_ALIGNMENT_TRAP=y +CONFIG_APERTURE_HELPERS=y CONFIG_ARCH_32BIT_OFF_T=y CONFIG_ARCH_BCM=y CONFIG_ARCH_BCM2835=y -# CONFIG_ARCH_BCM_HR2 is not set CONFIG_ARCH_DMA_ADDR_T_64BIT=y CONFIG_ARCH_HIBERNATION_POSSIBLE=y CONFIG_ARCH_KEEP_MEMBLOCK=y @@ -22,9 +22,8 @@ CONFIG_ARM_AMBA=y CONFIG_ARM_ARCH_TIMER=y CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y CONFIG_ARM_CPU_SUSPEND=y -CONFIG_ARM_CRYPTO=y CONFIG_ARM_GIC=y -CONFIG_ARM_HAS_SG_CHAIN=y +CONFIG_ARM_HAS_GROUP_RELOCS=y CONFIG_ARM_L1_CACHE_SHIFT=6 CONFIG_ARM_L1_CACHE_SHIFT_6=y CONFIG_ARM_LPAE=y @@ -40,7 +39,6 @@ CONFIG_ASSOCIATIVE_ARRAY=y CONFIG_AUTO_ZRELADDR=y CONFIG_BCM2708_VCMEM=y CONFIG_BCM2711_THERMAL=y -CONFIG_BCM2835_DEVGPIOMEM=y CONFIG_BCM2835_MBOX=y CONFIG_BCM2835_POWER=y # CONFIG_BCM2835_SMI is not set @@ -69,6 +67,9 @@ CONFIG_BRCMSTB_L2_IRQ=y CONFIG_BRCM_CHAR_DRIVERS=y CONFIG_BROADCOM_PHY=y # CONFIG_CACHE_L2X0 is not set +CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y +CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" +CONFIG_CC_NO_ARRAY_BOUNDS=y CONFIG_CLKSRC_MMIO=y CONFIG_CLK_BCM2711_DVP=y CONFIG_CLK_BCM2835=y @@ -86,9 +87,12 @@ CONFIG_CMA_SIZE_SEL_MBYTES=y # CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set # CONFIG_CMA_SYSFS is not set CONFIG_COMMON_CLK=y +CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1 CONFIG_COMPAT_32BIT_TIME=y CONFIG_CONFIGFS_FS=y CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_CONTEXT_TRACKING=y +CONFIG_CONTEXT_TRACKING_IDLE=y CONFIG_CONTIG_ALLOC=y CONFIG_CPUFREQ_DT=y CONFIG_CPUFREQ_DT_PLATDEV=y @@ -116,6 +120,7 @@ CONFIG_CPU_HAS_ASID=y CONFIG_CPU_IDLE=y CONFIG_CPU_IDLE_GOV_LADDER=y CONFIG_CPU_IDLE_GOV_MENU=y +CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_CPU_PABRT_V7=y CONFIG_CPU_PM=y CONFIG_CPU_RMAP=y @@ -124,7 +129,6 @@ CONFIG_CPU_THUMB_CAPABLE=y CONFIG_CPU_TLB_V7=y CONFIG_CPU_V7=y CONFIG_CRC16=y -CONFIG_CRYPTO_BLAKE2S=y CONFIG_CRYPTO_CBC=y CONFIG_CRYPTO_CRC32=y CONFIG_CRYPTO_CRC32C=y @@ -136,7 +140,9 @@ CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_JITTERENTROPY=y CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y +CONFIG_CRYPTO_LIB_SHA1=y CONFIG_CRYPTO_LIB_SHA256=y +CONFIG_CRYPTO_LIB_UTILS=y CONFIG_CRYPTO_RNG=y CONFIG_CRYPTO_RNG2=y CONFIG_CRYPTO_RNG_DEFAULT=y @@ -144,8 +150,10 @@ CONFIG_CRYPTO_SEQIV=y CONFIG_CRYPTO_SHA256=y CONFIG_CRYPTO_SHA512=y CONFIG_CRYPTO_XTS=y +CONFIG_CURRENT_POINTER_IN_TPIDRURO=y CONFIG_DCACHE_WORD_ACCESS=y CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" CONFIG_DIMLIB=y CONFIG_DMABUF_HEAPS=y @@ -158,7 +166,6 @@ CONFIG_DMA_CMA=y CONFIG_DMA_ENGINE=y CONFIG_DMA_OF=y CONFIG_DMA_OPS=y -CONFIG_DMA_REMAP=y CONFIG_DMA_SHARED_BUFFER=y CONFIG_DMA_VIRTUAL_CHANNELS=y CONFIG_DNOTIFY=y @@ -166,6 +173,7 @@ CONFIG_DTC=y CONFIG_DUMMY_CONSOLE=y CONFIG_EDAC_ATOMIC_SCRUB=y CONFIG_EDAC_SUPPORT=y +CONFIG_EXCLUSIVE_SYSTEM_RAM=y CONFIG_EXT4_FS=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y @@ -177,7 +185,6 @@ CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_IMAGEBLIT=y CONFIG_FB_CMDLINE=y -# CONFIG_FB_RPISENSE is not set CONFIG_FB_SIMPLE=y CONFIG_FIQ=y CONFIG_FIXED_PHY=y @@ -185,8 +192,6 @@ CONFIG_FIX_EARLYCON_MEM=y CONFIG_FONT_8x16=y CONFIG_FONT_8x8=y CONFIG_FONT_SUPPORT=y -# CONFIG_FPE_FASTFPE is not set -# CONFIG_FPE_NWFPE is not set CONFIG_FRAMEBUFFER_CONSOLE=y # CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y @@ -199,6 +204,8 @@ CONFIG_FS_POSIX_ACL=y CONFIG_FWNODE_MDIO=y CONFIG_FW_CACHE=y CONFIG_FW_LOADER_PAGED_BUF=y +CONFIG_FW_LOADER_SYSFS=y +CONFIG_GCC11_NO_ARRAY_BOUNDS=y CONFIG_GENERIC_ALLOCATOR=y CONFIG_GENERIC_ARCH_TOPOLOGY=y CONFIG_GENERIC_BUG=y @@ -234,7 +241,6 @@ CONFIG_GPIO_BCM_VIRT=y CONFIG_GPIO_CDEV=y # CONFIG_GPIO_FSM is not set CONFIG_GPIO_RASPBERRYPI_EXP=y -CONFIG_HANDLE_DOMAIN_IRQ=y CONFIG_HARDEN_BRANCH_PREDICTOR=y CONFIG_HARDIRQS_SW_RESEND=y CONFIG_HAS_DMA=y @@ -258,6 +264,7 @@ CONFIG_INPUT_MOUSEDEV=y CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 CONFIG_IRQCHIP=y +CONFIG_IRQSTACKS=y CONFIG_IRQ_DOMAIN=y CONFIG_IRQ_DOMAIN_HIERARCHY=y CONFIG_IRQ_FORCED_THREADING=y @@ -285,17 +292,21 @@ CONFIG_MDIO_BCM_UNIMAC=y CONFIG_MDIO_BUS=y CONFIG_MDIO_DEVICE=y CONFIG_MDIO_DEVRES=y +CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_CONTROLLER=y +CONFIG_MEDIA_PLATFORM_DRIVERS=y +CONFIG_MEDIA_PLATFORM_SUPPORT=y +CONFIG_MEDIA_SUPPORT=y +CONFIG_MEDIA_SUPPORT_FILTER=y CONFIG_MEMFD_CREATE=y CONFIG_MEMORY_ISOLATION=y CONFIG_MFD_CORE=y -# CONFIG_MFD_RASPBERRYPI_POE_HAT is not set -# CONFIG_MFD_RPISENSE_CORE is not set CONFIG_MFD_SYSCON=y CONFIG_MICROCHIP_PHY=y CONFIG_MIGHT_HAVE_CACHE_L2X0=y CONFIG_MIGRATION=y CONFIG_MMC=y -CONFIG_MMC_BCM2835=y +# CONFIG_MMC_BCM2835 is not set CONFIG_MMC_BCM2835_DMA=y CONFIG_MMC_BCM2835_MMC=y CONFIG_MMC_BCM2835_PIO_DMA_BARRIER=2 @@ -313,6 +324,7 @@ CONFIG_MUTEX_SPIN_ON_OWNER=y CONFIG_NEED_DMA_MAP_STATE=y CONFIG_NEON=y CONFIG_NET_FLOW_LIMIT=y +CONFIG_NET_PTP_CLASSIFY=y CONFIG_NET_SELFTESTS=y CONFIG_NLS=y CONFIG_NLS_ASCII=y @@ -322,7 +334,7 @@ CONFIG_NO_HZ_COMMON=y CONFIG_NO_HZ_IDLE=y CONFIG_NR_CPUS=4 CONFIG_NVMEM=y -CONFIG_OABI_COMPAT=y +CONFIG_NVMEM_LAYOUTS=y CONFIG_OF=y CONFIG_OF_ADDRESS=y CONFIG_OF_CONFIGFS=y @@ -339,6 +351,9 @@ CONFIG_OLD_SIGACTION=y CONFIG_OLD_SIGSUSPEND3=y CONFIG_PADATA=y CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_PAGE_POOL=y +CONFIG_PAGE_SIZE_LESS_THAN_256KB=y +CONFIG_PAGE_SIZE_LESS_THAN_64KB=y CONFIG_PCI=y CONFIG_PCIEAER=y CONFIG_PCIEPORTBUS=y @@ -363,13 +378,18 @@ CONFIG_PM_OPP=y CONFIG_PM_SLEEP=y CONFIG_PM_SLEEP_SMP=y CONFIG_POWER_SUPPLY=y +CONFIG_PPS=y +CONFIG_PREEMPT_NONE_BUILD=y CONFIG_PRINTK_TIME=y +CONFIG_PTP_1588_CLOCK=y CONFIG_PTP_1588_CLOCK_OPTIONAL=y CONFIG_PWM=y CONFIG_PWM_BCM2835=y CONFIG_PWM_SYSFS=y +CONFIG_RANDSTRUCT_NONE=y CONFIG_RAS=y CONFIG_RASPBERRYPI_FIRMWARE=y +CONFIG_RASPBERRYPI_GPIOMEM=y CONFIG_RASPBERRYPI_POWER=y CONFIG_RATIONAL=y # CONFIG_RAVE_SP_CORE is not set @@ -408,6 +428,7 @@ CONFIG_SMP=y CONFIG_SMP_ON_UP=y CONFIG_SMSC_PHY=y CONFIG_SOCK_RX_QUEUE_MAPPING=y +CONFIG_SOFTIRQ_ON_OWN_STACK=y CONFIG_SPARSE_IRQ=y CONFIG_SRCU=y # CONFIG_STRIP_ASM_SYMS is not set @@ -423,6 +444,7 @@ CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 CONFIG_THERMAL_GOV_STEP_WISE=y CONFIG_THERMAL_OF=y +CONFIG_THREAD_INFO_IN_TASK=y CONFIG_TICK_CPU_ACCOUNTING=y CONFIG_TIMER_OF=y CONFIG_TIMER_PROBE=y @@ -456,6 +478,8 @@ CONFIG_USE_OF=y CONFIG_VCHIQ_CDEV=y CONFIG_VFP=y CONFIG_VFPv3=y +CONFIG_VIDEO_DEV=y +CONFIG_VIDEO_V4L2_I2C=y CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_VT_CONSOLE_SLEEP=y diff --git a/target/linux/bcm27xx/bcm2710/config-5.15 b/target/linux/bcm27xx/bcm2710/config-6.1 similarity index 90% rename from target/linux/bcm27xx/bcm2710/config-5.15 rename to target/linux/bcm27xx/bcm2710/config-6.1 index ada4d4d7c..f29d8483f 100644 --- a/target/linux/bcm27xx/bcm2710/config-5.15 +++ b/target/linux/bcm27xx/bcm2710/config-6.1 @@ -1,6 +1,10 @@ CONFIG_64BIT=y # CONFIG_AIO is not set +CONFIG_APERTURE_HELPERS=y +CONFIG_ARCH_BCM=y CONFIG_ARCH_BCM2835=y +CONFIG_ARCH_BINFMT_ELF_EXTRA_PHDRS=y +CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE=y CONFIG_ARCH_DMA_ADDR_T_64BIT=y CONFIG_ARCH_HIBERNATION_POSSIBLE=y CONFIG_ARCH_KEEP_MEMBLOCK=y @@ -9,15 +13,16 @@ CONFIG_ARCH_MMAP_RND_BITS=18 CONFIG_ARCH_MMAP_RND_BITS_MAX=24 CONFIG_ARCH_MMAP_RND_BITS_MIN=18 CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11 +CONFIG_ARCH_NR_GPIO=0 CONFIG_ARCH_PROC_KCORE_TEXT=y CONFIG_ARCH_SPARSEMEM_ENABLE=y CONFIG_ARCH_STACKWALK=y CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_ARCH_WANTS_NO_INSTR=y +CONFIG_ARCH_WANTS_THP_SWAP=y CONFIG_ARM64=y CONFIG_ARM64_4K_PAGES=y CONFIG_ARM64_CNP=y -CONFIG_ARM64_CRYPTO=y CONFIG_ARM64_EPAN=y CONFIG_ARM64_ERRATUM_819472=y CONFIG_ARM64_ERRATUM_824069=y @@ -27,7 +32,6 @@ CONFIG_ARM64_ERRATUM_832075=y CONFIG_ARM64_ERRATUM_843419=y CONFIG_ARM64_HW_AFDBM=y CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y -CONFIG_ARM64_MODULE_PLTS=y CONFIG_ARM64_PAGE_SHIFT=12 CONFIG_ARM64_PAN=y CONFIG_ARM64_PA_BITS=48 @@ -56,7 +60,6 @@ CONFIG_ASSOCIATIVE_ARRAY=y CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y CONFIG_BCM2708_VCMEM=y # CONFIG_BCM2711_THERMAL is not set -CONFIG_BCM2835_DEVGPIOMEM=y CONFIG_BCM2835_MBOX=y CONFIG_BCM2835_POWER=y # CONFIG_BCM2835_SMI is not set @@ -80,7 +83,10 @@ CONFIG_BRCM_CHAR_DRIVERS=y CONFIG_CAVIUM_ERRATUM_22375=y CONFIG_CAVIUM_ERRATUM_23154=y CONFIG_CAVIUM_ERRATUM_27456=y +CONFIG_CC_HAVE_SHADOW_CALL_STACK=y CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y +CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" +CONFIG_CC_NO_ARRAY_BOUNDS=y CONFIG_CLKSRC_MMIO=y CONFIG_CLK_BCM2711_DVP=y CONFIG_CLK_BCM2835=y @@ -99,9 +105,12 @@ CONFIG_CMA_SIZE_SEL_MBYTES=y # CONFIG_CMA_SYSFS is not set CONFIG_COMMON_CLK=y CONFIG_COMMON_CLK_XGENE=y +CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1 # CONFIG_COMPAT_32BIT_TIME is not set CONFIG_CONFIGFS_FS=y CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_CONTEXT_TRACKING=y +CONFIG_CONTEXT_TRACKING_IDLE=y CONFIG_CONTIG_ALLOC=y CONFIG_CPUFREQ_DT=y CONFIG_CPUFREQ_DT_PLATDEV=y @@ -120,13 +129,13 @@ CONFIG_CPU_FREQ_STAT=y CONFIG_CPU_IDLE=y CONFIG_CPU_IDLE_GOV_LADDER=y CONFIG_CPU_IDLE_GOV_MENU=y +CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_CPU_PM=y CONFIG_CPU_RMAP=y CONFIG_CRC16=y CONFIG_CRYPTO_AES_ARM64=y CONFIG_CRYPTO_AES_ARM64_BS=y CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y -CONFIG_CRYPTO_BLAKE2S=y CONFIG_CRYPTO_CBC=y CONFIG_CRYPTO_CRC32=y CONFIG_CRYPTO_CRC32C=y @@ -139,7 +148,9 @@ CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_JITTERENTROPY=y CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y +CONFIG_CRYPTO_LIB_SHA1=y CONFIG_CRYPTO_LIB_SHA256=y +CONFIG_CRYPTO_LIB_UTILS=y CONFIG_CRYPTO_RNG=y CONFIG_CRYPTO_RNG2=y CONFIG_CRYPTO_RNG_DEFAULT=y @@ -148,10 +159,10 @@ CONFIG_CRYPTO_SHA256=y CONFIG_CRYPTO_SHA256_ARM64=y CONFIG_CRYPTO_SHA512=y CONFIG_CRYPTO_SHA512_ARM64=y -CONFIG_CRYPTO_SIMD=y CONFIG_CRYPTO_XTS=y CONFIG_DCACHE_WORD_ACCESS=y CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y CONFIG_DMABUF_HEAPS=y CONFIG_DMABUF_HEAPS_CMA=y CONFIG_DMABUF_HEAPS_SYSTEM=y @@ -162,13 +173,13 @@ CONFIG_DMA_CMA=y CONFIG_DMA_DIRECT_REMAP=y CONFIG_DMA_ENGINE=y CONFIG_DMA_OF=y -CONFIG_DMA_REMAP=y CONFIG_DMA_SHARED_BUFFER=y CONFIG_DMA_VIRTUAL_CHANNELS=y CONFIG_DNOTIFY=y CONFIG_DTC=y CONFIG_DUMMY_CONSOLE=y CONFIG_EDAC_SUPPORT=y +CONFIG_EXCLUSIVE_SYSTEM_RAM=y CONFIG_EXT4_FS=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y @@ -180,7 +191,6 @@ CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_IMAGEBLIT=y CONFIG_FB_CMDLINE=y -# CONFIG_FB_RPISENSE is not set CONFIG_FB_SIMPLE=y CONFIG_FIXED_PHY=y CONFIG_FIX_EARLYCON_MEM=y @@ -201,6 +211,9 @@ CONFIG_FS_POSIX_ACL=y CONFIG_FWNODE_MDIO=y CONFIG_FW_CACHE=y CONFIG_FW_LOADER_PAGED_BUF=y +CONFIG_FW_LOADER_SYSFS=y +CONFIG_GCC11_NO_ARRAY_BOUNDS=y +CONFIG_GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_REGS=y CONFIG_GENERIC_ALLOCATOR=y CONFIG_GENERIC_ARCH_TOPOLOGY=y CONFIG_GENERIC_BUG=y @@ -211,9 +224,9 @@ CONFIG_GENERIC_CPU_AUTOPROBE=y CONFIG_GENERIC_CPU_VULNERABILITIES=y CONFIG_GENERIC_CSUM=y CONFIG_GENERIC_EARLY_IOREMAP=y -CONFIG_GENERIC_FIND_FIRST_BIT=y CONFIG_GENERIC_GETTIMEOFDAY=y CONFIG_GENERIC_IDLE_POLL_SETUP=y +CONFIG_GENERIC_IOREMAP=y CONFIG_GENERIC_IRQ_CHIP=y CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y CONFIG_GENERIC_IRQ_MIGRATION=y @@ -236,7 +249,6 @@ CONFIG_GPIO_BCM_VIRT=y CONFIG_GPIO_CDEV=y # CONFIG_GPIO_FSM is not set CONFIG_GPIO_RASPBERRYPI_EXP=y -CONFIG_HANDLE_DOMAIN_IRQ=y CONFIG_HARDIRQS_SW_RESEND=y CONFIG_HAS_DMA=y CONFIG_HAS_IOMEM=y @@ -279,16 +291,20 @@ CONFIG_MAILBOX=y CONFIG_MDIO_BUS=y CONFIG_MDIO_DEVICE=y CONFIG_MDIO_DEVRES=y +CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_CONTROLLER=y +CONFIG_MEDIA_PLATFORM_DRIVERS=y +CONFIG_MEDIA_PLATFORM_SUPPORT=y +CONFIG_MEDIA_SUPPORT=y +CONFIG_MEDIA_SUPPORT_FILTER=y CONFIG_MEMFD_CREATE=y CONFIG_MEMORY_ISOLATION=y CONFIG_MFD_CORE=y -# CONFIG_MFD_RASPBERRYPI_POE_HAT is not set -# CONFIG_MFD_RPISENSE_CORE is not set CONFIG_MFD_SYSCON=y CONFIG_MICROCHIP_PHY=y CONFIG_MIGRATION=y CONFIG_MMC=y -CONFIG_MMC_BCM2835=y +# CONFIG_MMC_BCM2835 is not set CONFIG_MMC_BCM2835_DMA=y CONFIG_MMC_BCM2835_MMC=y CONFIG_MMC_BCM2835_PIO_DMA_BARRIER=2 @@ -315,6 +331,7 @@ CONFIG_NO_HZ_COMMON=y CONFIG_NO_HZ_IDLE=y CONFIG_NR_CPUS=4 CONFIG_NVMEM=y +CONFIG_NVMEM_LAYOUTS=y CONFIG_OF=y CONFIG_OF_ADDRESS=y CONFIG_OF_CONFIGFS=y @@ -328,6 +345,9 @@ CONFIG_OF_MDIO=y CONFIG_OF_OVERLAY=y CONFIG_OF_RESOLVE=y CONFIG_PADATA=y +CONFIG_PAGE_POOL=y +CONFIG_PAGE_SIZE_LESS_THAN_256KB=y +CONFIG_PAGE_SIZE_LESS_THAN_64KB=y CONFIG_PARTITION_PERCPU=y CONFIG_PCI=y # CONFIG_PCIE_BRCMSTB is not set @@ -348,8 +368,10 @@ CONFIG_PM_GENERIC_DOMAINS_SLEEP=y CONFIG_PM_OPP=y CONFIG_PM_SLEEP=y CONFIG_PM_SLEEP_SMP=y +CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y CONFIG_POWER_RESET=y CONFIG_POWER_SUPPLY=y +CONFIG_PREEMPT_NONE_BUILD=y CONFIG_PRINTK_TIME=y CONFIG_PTP_1588_CLOCK_OPTIONAL=y CONFIG_PWM=y @@ -357,7 +379,9 @@ CONFIG_PWM_BCM2835=y CONFIG_PWM_SYSFS=y CONFIG_QUEUED_RWLOCKS=y CONFIG_QUEUED_SPINLOCKS=y +CONFIG_RANDSTRUCT_NONE=y CONFIG_RASPBERRYPI_FIRMWARE=y +CONFIG_RASPBERRYPI_GPIOMEM=y CONFIG_RASPBERRYPI_POWER=y CONFIG_RATIONAL=y # CONFIG_RAVE_SP_CORE is not set @@ -396,6 +420,7 @@ CONFIG_SG_POOL=y CONFIG_SMP=y CONFIG_SMSC_PHY=y CONFIG_SOCK_RX_QUEUE_MAPPING=y +CONFIG_SOFTIRQ_ON_OWN_STACK=y CONFIG_SPARSEMEM=y CONFIG_SPARSEMEM_EXTREME=y CONFIG_SPARSEMEM_VMEMMAP=y @@ -420,6 +445,7 @@ CONFIG_TICK_CPU_ACCOUNTING=y CONFIG_TIMER_OF=y CONFIG_TIMER_PROBE=y CONFIG_TMPFS_POSIX_ACL=y +CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y CONFIG_TREE_RCU=y CONFIG_TREE_SRCU=y # CONFIG_UCLAMP_TASK is not set @@ -438,6 +464,8 @@ CONFIG_USB_SUPPORT=y CONFIG_USB_UAS=y CONFIG_USB_USBNET=y CONFIG_VCHIQ_CDEV=y +CONFIG_VIDEO_DEV=y +CONFIG_VIDEO_V4L2_I2C=y CONFIG_VMAP_STACK=y CONFIG_VT=y CONFIG_VT_CONSOLE=y diff --git a/target/linux/bcm27xx/bcm2711/config-5.15 b/target/linux/bcm27xx/bcm2711/config-6.1 similarity index 89% rename from target/linux/bcm27xx/bcm2711/config-5.15 rename to target/linux/bcm27xx/bcm2711/config-6.1 index a2499b8bf..2feb6e9ae 100644 --- a/target/linux/bcm27xx/bcm2711/config-5.15 +++ b/target/linux/bcm27xx/bcm2711/config-6.1 @@ -1,6 +1,10 @@ CONFIG_64BIT=y # CONFIG_AIO is not set +CONFIG_APERTURE_HELPERS=y +CONFIG_ARCH_BCM=y CONFIG_ARCH_BCM2835=y +CONFIG_ARCH_BINFMT_ELF_EXTRA_PHDRS=y +CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE=y CONFIG_ARCH_DMA_ADDR_T_64BIT=y CONFIG_ARCH_HIBERNATION_POSSIBLE=y CONFIG_ARCH_KEEP_MEMBLOCK=y @@ -9,25 +13,20 @@ CONFIG_ARCH_MMAP_RND_BITS=18 CONFIG_ARCH_MMAP_RND_BITS_MAX=24 CONFIG_ARCH_MMAP_RND_BITS_MIN=18 CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11 +CONFIG_ARCH_NR_GPIO=0 CONFIG_ARCH_PROC_KCORE_TEXT=y CONFIG_ARCH_SPARSEMEM_ENABLE=y CONFIG_ARCH_STACKWALK=y CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_ARCH_WANTS_NO_INSTR=y +CONFIG_ARCH_WANTS_THP_SWAP=y CONFIG_ARM64=y CONFIG_ARM64_4K_PAGES=y CONFIG_ARM64_CNP=y -CONFIG_ARM64_CRYPTO=y CONFIG_ARM64_EPAN=y -CONFIG_ARM64_ERRATUM_819472=y -CONFIG_ARM64_ERRATUM_824069=y -CONFIG_ARM64_ERRATUM_826319=y -CONFIG_ARM64_ERRATUM_827319=y -CONFIG_ARM64_ERRATUM_832075=y -CONFIG_ARM64_ERRATUM_843419=y +CONFIG_ARM64_ERRATUM_1319367=y CONFIG_ARM64_HW_AFDBM=y CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y -CONFIG_ARM64_MODULE_PLTS=y CONFIG_ARM64_PAGE_SHIFT=12 CONFIG_ARM64_PAN=y CONFIG_ARM64_PA_BITS=48 @@ -38,7 +37,7 @@ CONFIG_ARM64_SVE=y CONFIG_ARM64_TAGGED_ADDR_ABI=y CONFIG_ARM64_VA_BITS=39 CONFIG_ARM64_VA_BITS_39=y -CONFIG_ARM64_WORKAROUND_CLEAN_CACHE=y +CONFIG_ARM64_WORKAROUND_SPECULATIVE_AT=y CONFIG_ARM_AMBA=y CONFIG_ARM_ARCH_TIMER=y CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y @@ -56,7 +55,6 @@ CONFIG_ASSOCIATIVE_ARRAY=y CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y CONFIG_BCM2708_VCMEM=y CONFIG_BCM2711_THERMAL=y -CONFIG_BCM2835_DEVGPIOMEM=y CONFIG_BCM2835_MBOX=y CONFIG_BCM2835_POWER=y # CONFIG_BCM2835_SMI is not set @@ -84,7 +82,10 @@ CONFIG_BROADCOM_PHY=y CONFIG_CAVIUM_ERRATUM_22375=y CONFIG_CAVIUM_ERRATUM_23154=y CONFIG_CAVIUM_ERRATUM_27456=y +CONFIG_CC_HAVE_SHADOW_CALL_STACK=y CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y +CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" +CONFIG_CC_NO_ARRAY_BOUNDS=y CONFIG_CLKSRC_MMIO=y CONFIG_CLK_BCM2711_DVP=y CONFIG_CLK_BCM2835=y @@ -103,9 +104,12 @@ CONFIG_CMA_SIZE_SEL_MBYTES=y # CONFIG_CMA_SYSFS is not set CONFIG_COMMON_CLK=y CONFIG_COMMON_CLK_XGENE=y +CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1 # CONFIG_COMPAT_32BIT_TIME is not set CONFIG_CONFIGFS_FS=y CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_CONTEXT_TRACKING=y +CONFIG_CONTEXT_TRACKING_IDLE=y CONFIG_CONTIG_ALLOC=y CONFIG_CPUFREQ_DT=y CONFIG_CPUFREQ_DT_PLATDEV=y @@ -124,13 +128,13 @@ CONFIG_CPU_FREQ_STAT=y CONFIG_CPU_IDLE=y CONFIG_CPU_IDLE_GOV_LADDER=y CONFIG_CPU_IDLE_GOV_MENU=y +CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_CPU_PM=y CONFIG_CPU_RMAP=y CONFIG_CRC16=y CONFIG_CRYPTO_AES_ARM64=y CONFIG_CRYPTO_AES_ARM64_BS=y CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y -CONFIG_CRYPTO_BLAKE2S=y CONFIG_CRYPTO_CBC=y CONFIG_CRYPTO_CRC32=y CONFIG_CRYPTO_CRC32C=y @@ -143,7 +147,9 @@ CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_JITTERENTROPY=y CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y +CONFIG_CRYPTO_LIB_SHA1=y CONFIG_CRYPTO_LIB_SHA256=y +CONFIG_CRYPTO_LIB_UTILS=y CONFIG_CRYPTO_RNG=y CONFIG_CRYPTO_RNG2=y CONFIG_CRYPTO_RNG_DEFAULT=y @@ -152,10 +158,10 @@ CONFIG_CRYPTO_SHA256=y CONFIG_CRYPTO_SHA256_ARM64=y CONFIG_CRYPTO_SHA512=y CONFIG_CRYPTO_SHA512_ARM64=y -CONFIG_CRYPTO_SIMD=y CONFIG_CRYPTO_XTS=y CONFIG_DCACHE_WORD_ACCESS=y CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y CONFIG_DIMLIB=y CONFIG_DMABUF_HEAPS=y CONFIG_DMABUF_HEAPS_CMA=y @@ -167,13 +173,13 @@ CONFIG_DMA_CMA=y CONFIG_DMA_DIRECT_REMAP=y CONFIG_DMA_ENGINE=y CONFIG_DMA_OF=y -CONFIG_DMA_REMAP=y CONFIG_DMA_SHARED_BUFFER=y CONFIG_DMA_VIRTUAL_CHANNELS=y CONFIG_DNOTIFY=y CONFIG_DTC=y CONFIG_DUMMY_CONSOLE=y CONFIG_EDAC_SUPPORT=y +CONFIG_EXCLUSIVE_SYSTEM_RAM=y CONFIG_EXT4_FS=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y @@ -185,7 +191,6 @@ CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_IMAGEBLIT=y CONFIG_FB_CMDLINE=y -# CONFIG_FB_RPISENSE is not set CONFIG_FB_SIMPLE=y CONFIG_FIXED_PHY=y CONFIG_FIX_EARLYCON_MEM=y @@ -206,6 +211,9 @@ CONFIG_FS_POSIX_ACL=y CONFIG_FWNODE_MDIO=y CONFIG_FW_CACHE=y CONFIG_FW_LOADER_PAGED_BUF=y +CONFIG_FW_LOADER_SYSFS=y +CONFIG_GCC11_NO_ARRAY_BOUNDS=y +CONFIG_GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_REGS=y CONFIG_GENERIC_ALLOCATOR=y CONFIG_GENERIC_ARCH_TOPOLOGY=y CONFIG_GENERIC_BUG=y @@ -216,9 +224,9 @@ CONFIG_GENERIC_CPU_AUTOPROBE=y CONFIG_GENERIC_CPU_VULNERABILITIES=y CONFIG_GENERIC_CSUM=y CONFIG_GENERIC_EARLY_IOREMAP=y -CONFIG_GENERIC_FIND_FIRST_BIT=y CONFIG_GENERIC_GETTIMEOFDAY=y CONFIG_GENERIC_IDLE_POLL_SETUP=y +CONFIG_GENERIC_IOREMAP=y CONFIG_GENERIC_IRQ_CHIP=y CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y CONFIG_GENERIC_IRQ_MIGRATION=y @@ -242,7 +250,6 @@ CONFIG_GPIO_BCM_VIRT=y CONFIG_GPIO_CDEV=y # CONFIG_GPIO_FSM is not set CONFIG_GPIO_RASPBERRYPI_EXP=y -CONFIG_HANDLE_DOMAIN_IRQ=y CONFIG_HARDIRQS_SW_RESEND=y CONFIG_HAS_DMA=y CONFIG_HAS_IOMEM=y @@ -250,7 +257,6 @@ CONFIG_HAS_IOPORT_MAP=y CONFIG_HOTPLUG_CPU=y CONFIG_HW_CONSOLE=y CONFIG_HW_RANDOM=y -# CONFIG_HW_RANDOM_BCM2835 is not set CONFIG_HW_RANDOM_IPROC_RNG200=y CONFIG_I2C=y # CONFIG_I2C_BCM2708 is not set @@ -287,15 +293,19 @@ CONFIG_MDIO_BCM_UNIMAC=y CONFIG_MDIO_BUS=y CONFIG_MDIO_DEVICE=y CONFIG_MDIO_DEVRES=y +CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_CONTROLLER=y +CONFIG_MEDIA_PLATFORM_DRIVERS=y +CONFIG_MEDIA_PLATFORM_SUPPORT=y +CONFIG_MEDIA_SUPPORT=y +CONFIG_MEDIA_SUPPORT_FILTER=y CONFIG_MEMFD_CREATE=y CONFIG_MEMORY_ISOLATION=y CONFIG_MFD_CORE=y -# CONFIG_MFD_RASPBERRYPI_POE_HAT is not set -# CONFIG_MFD_RPISENSE_CORE is not set CONFIG_MFD_SYSCON=y CONFIG_MIGRATION=y CONFIG_MMC=y -CONFIG_MMC_BCM2835=y +# CONFIG_MMC_BCM2835 is not set CONFIG_MMC_BCM2835_DMA=y CONFIG_MMC_BCM2835_MMC=y CONFIG_MMC_BCM2835_PIO_DMA_BARRIER=2 @@ -313,6 +323,7 @@ CONFIG_MUTEX_SPIN_ON_OWNER=y CONFIG_NEED_DMA_MAP_STATE=y CONFIG_NEED_SG_DMA_LENGTH=y CONFIG_NET_FLOW_LIMIT=y +CONFIG_NET_PTP_CLASSIFY=y CONFIG_NET_SELFTESTS=y CONFIG_NLS=y CONFIG_NLS_ASCII=y @@ -322,6 +333,7 @@ CONFIG_NO_HZ_COMMON=y CONFIG_NO_HZ_IDLE=y CONFIG_NR_CPUS=4 CONFIG_NVMEM=y +CONFIG_NVMEM_LAYOUTS=y CONFIG_OF=y CONFIG_OF_ADDRESS=y CONFIG_OF_CONFIGFS=y @@ -335,6 +347,9 @@ CONFIG_OF_MDIO=y CONFIG_OF_OVERLAY=y CONFIG_OF_RESOLVE=y CONFIG_PADATA=y +CONFIG_PAGE_POOL=y +CONFIG_PAGE_SIZE_LESS_THAN_256KB=y +CONFIG_PAGE_SIZE_LESS_THAN_64KB=y CONFIG_PARTITION_PERCPU=y CONFIG_PCI=y CONFIG_PCIEAER=y @@ -358,17 +373,23 @@ CONFIG_PM_GENERIC_DOMAINS_SLEEP=y CONFIG_PM_OPP=y CONFIG_PM_SLEEP=y CONFIG_PM_SLEEP_SMP=y +CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y CONFIG_POWER_RESET=y CONFIG_POWER_SUPPLY=y +CONFIG_PPS=y +CONFIG_PREEMPT_NONE_BUILD=y CONFIG_PRINTK_TIME=y +CONFIG_PTP_1588_CLOCK=y CONFIG_PTP_1588_CLOCK_OPTIONAL=y CONFIG_PWM=y CONFIG_PWM_BCM2835=y CONFIG_PWM_SYSFS=y CONFIG_QUEUED_RWLOCKS=y CONFIG_QUEUED_SPINLOCKS=y +CONFIG_RANDSTRUCT_NONE=y CONFIG_RAS=y CONFIG_RASPBERRYPI_FIRMWARE=y +CONFIG_RASPBERRYPI_GPIOMEM=y CONFIG_RASPBERRYPI_POWER=y CONFIG_RATIONAL=y # CONFIG_RAVE_SP_CORE is not set @@ -406,6 +427,7 @@ CONFIG_SERIAL_OF_PLATFORM=y CONFIG_SG_POOL=y CONFIG_SMP=y CONFIG_SOCK_RX_QUEUE_MAPPING=y +CONFIG_SOFTIRQ_ON_OWN_STACK=y CONFIG_SPARSEMEM=y CONFIG_SPARSEMEM_EXTREME=y CONFIG_SPARSEMEM_VMEMMAP=y @@ -430,6 +452,7 @@ CONFIG_TICK_CPU_ACCOUNTING=y CONFIG_TIMER_OF=y CONFIG_TIMER_PROBE=y CONFIG_TMPFS_POSIX_ACL=y +CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y CONFIG_TREE_RCU=y CONFIG_TREE_SRCU=y # CONFIG_UCLAMP_TASK is not set @@ -450,6 +473,8 @@ CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_PCI=y CONFIG_USB_XHCI_PLATFORM=y CONFIG_VCHIQ_CDEV=y +CONFIG_VIDEO_DEV=y +CONFIG_VIDEO_V4L2_I2C=y CONFIG_VMAP_STACK=y CONFIG_VT=y CONFIG_VT_CONSOLE=y diff --git a/target/linux/bcm27xx/bcm2712/config-6.1 b/target/linux/bcm27xx/bcm2712/config-6.1 new file mode 100644 index 000000000..ddd29f78f --- /dev/null +++ b/target/linux/bcm27xx/bcm2712/config-6.1 @@ -0,0 +1,612 @@ +CONFIG_64BIT=y +# CONFIG_AIO is not set +CONFIG_APERTURE_HELPERS=y +CONFIG_ARCH_BCM=y +CONFIG_ARCH_BCM2835=y +CONFIG_ARCH_BINFMT_ELF_EXTRA_PHDRS=y +CONFIG_ARCH_BRCMSTB=y +CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE=y +CONFIG_ARCH_DMA_ADDR_T_64BIT=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_KEEP_MEMBLOCK=y +CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y +CONFIG_ARCH_MMAP_RND_BITS=18 +CONFIG_ARCH_MMAP_RND_BITS_MAX=24 +CONFIG_ARCH_MMAP_RND_BITS_MIN=18 +CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11 +CONFIG_ARCH_NR_GPIO=0 +CONFIG_ARCH_PROC_KCORE_TEXT=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_STACKWALK=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARCH_WANTS_NO_INSTR=y +CONFIG_ARCH_WANTS_THP_SWAP=y +CONFIG_ARM64=y +CONFIG_ARM64_4K_PAGES=y +CONFIG_ARM64_CNP=y +CONFIG_ARM64_EPAN=y +CONFIG_ARM64_ERRATUM_1165522=y +CONFIG_ARM64_ERRATUM_1286807=y +CONFIG_ARM64_ERRATUM_1463225=y +CONFIG_ARM64_HW_AFDBM=y +CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y +CONFIG_ARM64_PAGE_SHIFT=12 +CONFIG_ARM64_PAN=y +CONFIG_ARM64_PA_BITS=48 +CONFIG_ARM64_PA_BITS_48=y +CONFIG_ARM64_PTR_AUTH=y +CONFIG_ARM64_PTR_AUTH_KERNEL=y +CONFIG_ARM64_SVE=y +CONFIG_ARM64_TAGGED_ADDR_ABI=y +CONFIG_ARM64_VA_BITS=39 +CONFIG_ARM64_VA_BITS_39=y +CONFIG_ARM64_WORKAROUND_REPEAT_TLBI=y +CONFIG_ARM64_WORKAROUND_SPECULATIVE_AT=y +CONFIG_ARM_AMBA=y +CONFIG_ARM_ARCH_TIMER=y +CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y +CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND=y +CONFIG_ARM_BRCMSTB_AVS_CPUFREQ=y +CONFIG_ARM_GIC=y +CONFIG_ARM_GIC_V2M=y +CONFIG_ARM_GIC_V3=y +CONFIG_ARM_GIC_V3_ITS=y +CONFIG_ARM_GIC_V3_ITS_PCI=y +# CONFIG_ARM_MHU_V2 is not set +# CONFIG_ARM_PL172_MPMC is not set +CONFIG_ARM_PSCI_FW=y +CONFIG_ARM_RASPBERRYPI_CPUFREQ=y +# CONFIG_ARM_SMMU is not set +# CONFIG_ARM_SMMU_V3 is not set +CONFIG_ARM_TIMER_SP804=y +CONFIG_ASSOCIATIVE_ARRAY=y +CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y +CONFIG_BCM2708_VCMEM=y +CONFIG_BCM2711_THERMAL=y +CONFIG_BCM2712_IOMMU=y +CONFIG_BCM2712_MIP=y +CONFIG_BCM2835_MBOX=y +CONFIG_BCM2835_POWER=y +CONFIG_BCM2835_SMI=y +CONFIG_BCM2835_SMI_DEV=m +CONFIG_BCM2835_THERMAL=y +CONFIG_BCM2835_VCHIQ=y +# CONFIG_BCM2835_VCHIQ_MMAL is not set +CONFIG_BCM2835_WDT=y +CONFIG_BCM7038_L1_IRQ=y +CONFIG_BCM7120_L2_IRQ=y +CONFIG_BCM7XXX_PHY=y +CONFIG_BCMA=y +CONFIG_BCMA_BLOCKIO=y +# CONFIG_BCMA_DEBUG is not set +# CONFIG_BCMA_DRIVER_GMAC_CMN is not set +CONFIG_BCMA_DRIVER_PCI=y +CONFIG_BCMA_FALLBACK_SPROM=y +CONFIG_BCMA_HOST_PCI=y +CONFIG_BCMA_HOST_PCI_POSSIBLE=y +# CONFIG_BCMA_HOST_SOC is not set +CONFIG_BCMGENET=y +CONFIG_BCM_NET_PHYLIB=y +CONFIG_BCM_VCIO=y +# CONFIG_BCM_VC_SM_CMA is not set +CONFIG_BCM_VIDEOCORE=y +# CONFIG_BLK_DEV_INITRD is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_NVME=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_SD=y +CONFIG_BLK_MQ_PCI=y +CONFIG_BLK_PM=y +CONFIG_BRCMSTB_DPFE=y +CONFIG_BRCMSTB_L2_IRQ=y +CONFIG_BRCMSTB_MEMC=y +CONFIG_BRCMSTB_PM=y +# CONFIG_BRCMSTB_THERMAL is not set +CONFIG_BRCM_CHAR_DRIVERS=y +CONFIG_BRCM_USB_PINMAP=y +CONFIG_BROADCOM_PHY=y +CONFIG_CC_HAVE_SHADOW_CALL_STACK=y +CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y +CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" +CONFIG_CC_NO_ARRAY_BOUNDS=y +CONFIG_CLKSRC_MMIO=y +CONFIG_CLK_BCM2711_DVP=y +CONFIG_CLK_BCM2835=y +CONFIG_CLK_RASPBERRYPI=y +CONFIG_CLONE_BACKWARDS=y +CONFIG_CMA=y +CONFIG_CMA_ALIGNMENT=8 +CONFIG_CMA_AREAS=7 +# CONFIG_CMA_DEBUG is not set +# CONFIG_CMA_DEBUGFS is not set +CONFIG_CMA_SIZE_MBYTES=5 +# CONFIG_CMA_SIZE_SEL_MAX is not set +CONFIG_CMA_SIZE_SEL_MBYTES=y +# CONFIG_CMA_SIZE_SEL_MIN is not set +# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set +# CONFIG_CMA_SYSFS is not set +CONFIG_COMMON_CLK=y +CONFIG_COMMON_CLK_RP1=y +# CONFIG_COMMON_CLK_RP1_SDIO is not set +CONFIG_COMMON_CLK_XGENE=y +CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1 +# CONFIG_COMPAT_32BIT_TIME is not set +CONFIG_CONFIGFS_FS=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_CONTEXT_TRACKING=y +CONFIG_CONTEXT_TRACKING_IDLE=y +CONFIG_CONTIG_ALLOC=y +CONFIG_CPUFREQ_DT=y +CONFIG_CPUFREQ_DT_PLATDEV=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +CONFIG_CPU_FREQ_GOV_ATTR_SET=y +CONFIG_CPU_FREQ_GOV_COMMON=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_STAT=y +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_CPU_IDLE_GOV_MENU=y +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_CPU_PM=y +CONFIG_CPU_RMAP=y +CONFIG_CRC16=y +CONFIG_CRYPTO_AES_ARM64=y +CONFIG_CRYPTO_AES_ARM64_BS=y +CONFIG_CRYPTO_AES_ARM64_CE=y +CONFIG_CRYPTO_AES_ARM64_CE_BLK=y +CONFIG_CRYPTO_AES_ARM64_CE_CCM=y +CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_CRC32=y +CONFIG_CRYPTO_CRC32C=y +CONFIG_CRYPTO_CRYPTD=y +CONFIG_CRYPTO_CTS=y +CONFIG_CRYPTO_DRBG=y +CONFIG_CRYPTO_DRBG_HMAC=y +CONFIG_CRYPTO_DRBG_MENU=y +CONFIG_CRYPTO_ECB=y +CONFIG_CRYPTO_GHASH_ARM64_CE=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_JITTERENTROPY=y +CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y +CONFIG_CRYPTO_LIB_SHA1=y +CONFIG_CRYPTO_LIB_SHA256=y +CONFIG_CRYPTO_LIB_UTILS=y +CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_RNG_DEFAULT=y +CONFIG_CRYPTO_SEQIV=y +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA1_ARM64_CE=y +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_SHA256_ARM64=y +CONFIG_CRYPTO_SHA2_ARM64_CE=y +CONFIG_CRYPTO_SHA3=y +CONFIG_CRYPTO_SHA3_ARM64=y +CONFIG_CRYPTO_SHA512=y +CONFIG_CRYPTO_SHA512_ARM64=y +CONFIG_CRYPTO_SHA512_ARM64_CE=y +CONFIG_CRYPTO_SM3=y +CONFIG_CRYPTO_SM3_ARM64_CE=y +CONFIG_CRYPTO_SM4=y +CONFIG_CRYPTO_SM4_ARM64_CE=y +CONFIG_CRYPTO_SM4_ARM64_CE_BLK=y +CONFIG_CRYPTO_XTS=y +CONFIG_DCACHE_WORD_ACCESS=y +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +CONFIG_DIMLIB=y +CONFIG_DMABUF_HEAPS=y +CONFIG_DMABUF_HEAPS_CMA=y +CONFIG_DMABUF_HEAPS_SYSTEM=y +CONFIG_DMADEVICES=y +CONFIG_DMA_BCM2708=y +CONFIG_DMA_BCM2835=y +CONFIG_DMA_CMA=y +CONFIG_DMA_DIRECT_REMAP=y +CONFIG_DMA_ENGINE=y +CONFIG_DMA_OF=y +CONFIG_DMA_OPS=y +CONFIG_DMA_SHARED_BUFFER=y +CONFIG_DMA_VIRTUAL_CHANNELS=y +CONFIG_DNOTIFY=y +CONFIG_DTC=y +CONFIG_DUMMY_CONSOLE=y +CONFIG_EDAC_SUPPORT=y +CONFIG_EXCLUSIVE_SYSTEM_RAM=y +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_EXTCON=y +CONFIG_F2FS_FS=y +CONFIG_FB=y +CONFIG_FB_BCM2708=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_CMDLINE=y +CONFIG_FB_SIMPLE=y +CONFIG_FIXED_PHY=y +CONFIG_FIX_EARLYCON_MEM=y +CONFIG_FONT_8x16=y +CONFIG_FONT_8x8=y +CONFIG_FONT_SUPPORT=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y +CONFIG_FRAME_POINTER=y +CONFIG_FREEZER=y +CONFIG_FSL_ERRATUM_A008585=y +CONFIG_FS_ENCRYPTION=y +CONFIG_FS_ENCRYPTION_ALGS=y +CONFIG_FS_IOMAP=y +CONFIG_FS_MBCACHE=y +CONFIG_FS_POSIX_ACL=y +CONFIG_FWNODE_MDIO=y +CONFIG_FW_CACHE=y +CONFIG_FW_LOADER_PAGED_BUF=y +CONFIG_FW_LOADER_SYSFS=y +CONFIG_GCC11_NO_ARRAY_BOUNDS=y +CONFIG_GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_REGS=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_GENERIC_ARCH_TOPOLOGY=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_GENERIC_CPU_AUTOPROBE=y +CONFIG_GENERIC_CPU_VULNERABILITIES=y +CONFIG_GENERIC_CSUM=y +CONFIG_GENERIC_EARLY_IOREMAP=y +CONFIG_GENERIC_GETTIMEOFDAY=y +CONFIG_GENERIC_IDLE_POLL_SETUP=y +CONFIG_GENERIC_IOREMAP=y +CONFIG_GENERIC_IRQ_CHIP=y +CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y +CONFIG_GENERIC_IRQ_INJECTION=y +CONFIG_GENERIC_IRQ_MIGRATION=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_IRQ_SHOW_LEVEL=y +CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y +CONFIG_GENERIC_MSI_IRQ=y +CONFIG_GENERIC_MSI_IRQ_DOMAIN=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_PHY=y +CONFIG_GENERIC_PINCONF=y +CONFIG_GENERIC_PINCTRL_GROUPS=y +CONFIG_GENERIC_PINMUX_FUNCTIONS=y +CONFIG_GENERIC_SCHED_CLOCK=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_GENERIC_STRNCPY_FROM_USER=y +CONFIG_GENERIC_STRNLEN_USER=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GLOB=y +CONFIG_GPIOLIB_IRQCHIP=y +CONFIG_GPIO_BCM_VIRT=y +CONFIG_GPIO_BRCMSTB=y +CONFIG_GPIO_CDEV=y +# CONFIG_GPIO_FSM is not set +CONFIG_GPIO_GENERIC=y +CONFIG_GPIO_RASPBERRYPI_EXP=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT_MAP=y +CONFIG_HOTPLUG_CPU=y +CONFIG_HOTPLUG_PCI=y +# CONFIG_HOTPLUG_PCI_CPCI is not set +# CONFIG_HOTPLUG_PCI_PCIE is not set +CONFIG_HOTPLUG_PCI_SHPC=y +CONFIG_HWMON=y +CONFIG_HW_CONSOLE=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_IPROC_RNG200=y +CONFIG_I2C=y +CONFIG_I2C_ALGOBIT=y +# CONFIG_I2C_BCM2708 is not set +CONFIG_I2C_BCM2835=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_BRCMSTB=y +CONFIG_I2C_DESIGNWARE_CORE=y +CONFIG_I2C_DESIGNWARE_PLATFORM=y +CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 +CONFIG_INPUT=y +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_RASPBERRYPI_BUTTON=y +CONFIG_IOMMU_API=y +# CONFIG_IOMMU_DEBUGFS is not set +# CONFIG_IOMMU_DEFAULT_DMA_LAZY is not set +CONFIG_IOMMU_DEFAULT_DMA_STRICT=y +# CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set +CONFIG_IOMMU_DMA=y +CONFIG_IOMMU_IOVA=y +# CONFIG_IOMMU_IO_PGTABLE_ARMV7S is not set +# CONFIG_IOMMU_IO_PGTABLE_DART is not set +# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set +CONFIG_IOMMU_SUPPORT=y +CONFIG_IRQCHIP=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_DOMAIN_HIERARCHY=y +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_IRQ_MSI_IOMMU=y +CONFIG_IRQ_WORK=y +CONFIG_JBD2=y +CONFIG_KEYS=y +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_PWM=y +CONFIG_LEDS_TRIGGER_ACTPWR=y +CONFIG_LEDS_TRIGGER_INPUT=y +CONFIG_LIBFDT=y +CONFIG_LOCK_DEBUGGING_SUPPORT=y +CONFIG_LOCK_SPIN_ON_OWNER=y +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_CLUT224=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_MACB=y +CONFIG_MACB_PCI=y +CONFIG_MACB_USE_HWSTAMP=y +CONFIG_MAC_PARTITION=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_MAILBOX=y +# CONFIG_MAILBOX_TEST is not set +CONFIG_MDIO_BCM_UNIMAC=y +CONFIG_MDIO_BUS=y +CONFIG_MDIO_DEVICE=y +CONFIG_MDIO_DEVRES=y +CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_CONTROLLER=y +CONFIG_MEDIA_PLATFORM_DRIVERS=y +CONFIG_MEDIA_PLATFORM_SUPPORT=y +CONFIG_MEDIA_SUPPORT=y +CONFIG_MEDIA_SUPPORT_FILTER=y +CONFIG_MEMFD_CREATE=y +CONFIG_MEMORY=y +CONFIG_MEMORY_ISOLATION=y +CONFIG_MFD_CORE=y +CONFIG_MFD_RP1=y +CONFIG_MFD_SYSCON=y +CONFIG_MICROCHIP_PHY=y +CONFIG_MIGRATION=y +CONFIG_MMC=y +# CONFIG_MMC_BCM2835 is not set +CONFIG_MMC_BCM2835_DMA=y +CONFIG_MMC_BCM2835_MMC=y +CONFIG_MMC_BCM2835_PIO_DMA_BARRIER=2 +CONFIG_MMC_BCM2835_SDHOST=y +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_MINORS=32 +CONFIG_MMC_CQHCI=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_BRCMSTB=y +CONFIG_MMC_SDHCI_IO_ACCESSORS=y +CONFIG_MMC_SDHCI_IPROC=y +CONFIG_MMC_SDHCI_OF_DWCMSHC=y +# CONFIG_MMC_SDHCI_PCI is not set +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MODULES_USE_ELF_RELA=y +CONFIG_MUTEX_SPIN_ON_OWNER=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEED_SG_DMA_LENGTH=y +CONFIG_NET_FLOW_LIMIT=y +CONFIG_NET_PTP_CLASSIFY=y +CONFIG_NET_SELFTESTS=y +CONFIG_NLS=y +CONFIG_NLS_ASCII=y +CONFIG_NOP_USB_XCEIV=y +CONFIG_NO_HZ=y +CONFIG_NO_HZ_COMMON=y +CONFIG_NO_HZ_IDLE=y +CONFIG_NR_CPUS=4 +CONFIG_NVMEM=y +CONFIG_NVMEM_LAYOUTS=y +CONFIG_NVME_CORE=y +# CONFIG_NVME_HWMON is not set +# CONFIG_NVME_MULTIPATH is not set +CONFIG_OF=y +CONFIG_OF_ADDRESS=y +CONFIG_OF_CONFIGFS=y +CONFIG_OF_DYNAMIC=y +CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_FLATTREE=y +CONFIG_OF_GPIO=y +CONFIG_OF_IOMMU=y +CONFIG_OF_IRQ=y +CONFIG_OF_KOBJ=y +CONFIG_OF_MDIO=y +CONFIG_OF_OVERLAY=y +CONFIG_OF_RESOLVE=y +CONFIG_PADATA=y +CONFIG_PAGE_POOL=y +CONFIG_PAGE_SIZE_LESS_THAN_256KB=y +CONFIG_PAGE_SIZE_LESS_THAN_64KB=y +CONFIG_PARTITION_PERCPU=y +CONFIG_PCI=y +CONFIG_PCIEAER=y +CONFIG_PCIEAER_INJECT=y +CONFIG_PCIEASPM=y +# CONFIG_PCIEASPM_DEFAULT is not set +# CONFIG_PCIEASPM_PERFORMANCE is not set +CONFIG_PCIEASPM_POWERSAVE=y +# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set +CONFIG_PCIEPORTBUS=y +CONFIG_PCIE_BRCMSTB=y +CONFIG_PCIE_DPC=y +CONFIG_PCIE_DW=y +CONFIG_PCIE_DW_HOST=y +CONFIG_PCIE_DW_PLAT=y +CONFIG_PCIE_DW_PLAT_HOST=y +CONFIG_PCIE_MICROCHIP_HOST=y +CONFIG_PCIE_PME=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_DOMAINS_GENERIC=y +CONFIG_PCI_ECAM=y +CONFIG_PCI_HOST_COMMON=y +CONFIG_PCI_HOST_GENERIC=y +CONFIG_PCI_MSI=y +CONFIG_PCI_MSI_IRQ_DOMAIN=y +CONFIG_PCI_STUB=y +CONFIG_PGTABLE_LEVELS=3 +CONFIG_PHYLIB=y +CONFIG_PHYLINK=y +CONFIG_PHYS_ADDR_T_64BIT=y +# CONFIG_PHY_BRCM_SATA is not set +CONFIG_PHY_BRCM_USB=y +CONFIG_PINCTRL=y +CONFIG_PINCTRL_BCM2712=y +CONFIG_PINCTRL_BCM2835=y +CONFIG_PINCTRL_RP1=y +CONFIG_PM=y +CONFIG_PM_CLK=y +CONFIG_PM_GENERIC_DOMAINS=y +CONFIG_PM_GENERIC_DOMAINS_OF=y +CONFIG_PM_GENERIC_DOMAINS_SLEEP=y +CONFIG_PM_OPP=y +CONFIG_PM_SLEEP=y +CONFIG_PM_SLEEP_SMP=y +CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_GPIO=y +CONFIG_POWER_SUPPLY=y +CONFIG_PPS=y +CONFIG_PREEMPT_NONE_BUILD=y +CONFIG_PRINTK_TIME=y +CONFIG_PTP_1588_CLOCK=y +CONFIG_PTP_1588_CLOCK_OPTIONAL=y +CONFIG_PWM=y +CONFIG_PWM_BCM2835=y +CONFIG_PWM_BRCMSTB=y +CONFIG_PWM_RP1=y +CONFIG_PWM_SYSFS=y +CONFIG_QUEUED_RWLOCKS=y +CONFIG_QUEUED_SPINLOCKS=y +CONFIG_RANDSTRUCT_NONE=y +CONFIG_RAS=y +CONFIG_RASPBERRYPI_FIRMWARE=y +CONFIG_RASPBERRYPI_GPIOMEM=y +CONFIG_RASPBERRYPI_POWER=y +CONFIG_RATIONAL=y +# CONFIG_RAVE_SP_CORE is not set +CONFIG_REGMAP=y +CONFIG_REGMAP_MMIO=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_GPIO=y +CONFIG_RESET_BRCMSTB=y +CONFIG_RESET_BRCMSTB_RESCAL=y +CONFIG_RESET_CONTROLLER=y +CONFIG_RESET_RASPBERRYPI=y +CONFIG_RESET_SIMPLE=y +CONFIG_RFS_ACCEL=y +CONFIG_RODATA_FULL_DEFAULT_ENABLED=y +# CONFIG_RPIVID_MEM is not set +# CONFIG_RPI_POE_POWER is not set +CONFIG_RPS=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_BRCMSTB=y +CONFIG_RTC_DRV_RPI=y +CONFIG_RTC_I2C_AND_SPI=y +CONFIG_RWSEM_SPIN_ON_OWNER=y +CONFIG_SCSI=y +CONFIG_SCSI_COMMON=y +# CONFIG_SCSI_LOWLEVEL is not set +# CONFIG_SCSI_PROC_FS is not set +CONFIG_SENSORS_RASPBERRYPI_HWMON=y +CONFIG_SENSORS_RP1_ADC=y +CONFIG_SERIAL_8250_BCM2835AUX=y +CONFIG_SERIAL_8250_BCM7271=y +# CONFIG_SERIAL_8250_DMA is not set +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_FSL=y +CONFIG_SERIAL_8250_NR_UARTS=1 +CONFIG_SERIAL_8250_RUNTIME_UARTS=0 +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +CONFIG_SERIAL_DEV_BUS=y +# CONFIG_SERIAL_DEV_CTRL_TTYPORT is not set +CONFIG_SERIAL_MCTRL_GPIO=y +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_SG_POOL=y +CONFIG_SMP=y +CONFIG_SMSC_PHY=y +CONFIG_SOCK_RX_QUEUE_MAPPING=y +CONFIG_SOC_BRCMSTB=y +CONFIG_SOC_BUS=y +CONFIG_SOFTIRQ_ON_OWN_STACK=y +CONFIG_SPARSEMEM=y +CONFIG_SPARSEMEM_EXTREME=y +CONFIG_SPARSEMEM_VMEMMAP=y +CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y +CONFIG_SPARSE_IRQ=y +CONFIG_SRCU=y +# CONFIG_STRIP_ASM_SYMS is not set +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +CONFIG_SWIOTLB=y +CONFIG_SWPHY=y +CONFIG_SYSCTL_EXCEPTION_TRACE=y +# CONFIG_TEXTSEARCH is not set +CONFIG_THERMAL=y +CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y +CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 +CONFIG_THERMAL_GOV_STEP_WISE=y +CONFIG_THERMAL_OF=y +CONFIG_THERMAL_WRITABLE_TRIPS=y +CONFIG_THREAD_INFO_IN_TASK=y +CONFIG_TICK_CPU_ACCOUNTING=y +CONFIG_TIMER_OF=y +CONFIG_TIMER_PROBE=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y +CONFIG_TREE_RCU=y +CONFIG_TREE_SRCU=y +# CONFIG_UACCE is not set +# CONFIG_UCLAMP_TASK is not set +CONFIG_UEVENT_HELPER_PATH="" +CONFIG_UNMAP_KERNEL_AT_EL0=y +CONFIG_USB=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +# CONFIG_USB_BRCMSTB is not set +CONFIG_USB_COMMON=y +CONFIG_USB_DWC3=y +# CONFIG_USB_DWC3_DUAL_ROLE is not set +# CONFIG_USB_DWC3_GADGET is not set +CONFIG_USB_DWC3_HOST=y +CONFIG_USB_DWCOTG=y +CONFIG_USB_GADGET=y +# CONFIG_USB_HCD_BCMA is not set +CONFIG_USB_PCI=y +CONFIG_USB_PHY=y +CONFIG_USB_STORAGE=y +CONFIG_USB_SUPPORT=y +CONFIG_USB_UAS=y +# CONFIG_USB_UHCI_HCD is not set +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_PCI=y +CONFIG_USB_XHCI_PLATFORM=y +CONFIG_VCHIQ_CDEV=y +CONFIG_VIDEO_DEV=y +CONFIG_VIDEO_V4L2_I2C=y +CONFIG_VMAP_STACK=y +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_VT_CONSOLE_SLEEP=y +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_WATCHDOG_CORE=y +CONFIG_XPS=y +CONFIG_XZ_DEC_ARM=y +CONFIG_XZ_DEC_BCJ=y +CONFIG_ZONE_DMA32=y diff --git a/target/linux/bcm27xx/bcm2712/target.mk b/target/linux/bcm27xx/bcm2712/target.mk new file mode 100644 index 000000000..4fe991035 --- /dev/null +++ b/target/linux/bcm27xx/bcm2712/target.mk @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: GPL-2.0-only + +ARCH:=aarch64 +SUBTARGET:=bcm2712 +BOARDNAME:=BCM2712 boards (64 bit) +CPU_TYPE:=cortex-a76 +FEATURES+=pci pcie + +define Target/Description + Build firmware image for BCM2712 devices. + This firmware features a 64 bit kernel. +endef diff --git a/target/linux/bcm27xx/image/Makefile b/target/linux/bcm27xx/image/Makefile index 4cd105294..12ac0012a 100644 --- a/target/linux/bcm27xx/image/Makefile +++ b/target/linux/bcm27xx/image/Makefile @@ -76,8 +76,8 @@ define Device/rpi raspberrypi,model-zero raspberrypi,model-zero-w DEVICE_PACKAGES := \ cypress-firmware-43430-sdio \ - cypress-nvram-43430-sdio-rpi-zero-w \ - kmod-brcmfmac wpad-basic-wolfssl + brcmfmac-nvram-43430-sdio \ + kmod-brcmfmac wpad-basic-mbedtls endef ifeq ($(SUBTARGET),bcm2708) TARGET_DEVICES += rpi @@ -87,10 +87,10 @@ define Device/rpi-2 DEVICE_MODEL := 2B/2B 1.2 DEVICE_VARIANT := (32bit) DEVICE_ALT0_VENDOR := Raspberry Pi - DEVICE_ALT0_MODEL := 3B/3B+/3CM + DEVICE_ALT0_MODEL := 3B/3B+/CM3 DEVICE_ALT0_VARIANT := (32bit) DEVICE_ALT1_VENDOR := Raspberry Pi - DEVICE_ALT1_MODEL := 4B/400/4CM + DEVICE_ALT1_MODEL := 4B/400/CM4 DEVICE_ALT1_VARIANT := (32bit) DEVICE_DTS := \ bcm2709-rpi-2-b bcm2710-rpi-2-b \ @@ -107,10 +107,10 @@ define Device/rpi-2 raspberrypi,model-zero-2 DEVICE_PACKAGES := \ cypress-firmware-43430-sdio \ - cypress-nvram-43430-sdio-rpi-3b \ + brcmfmac-nvram-43430-sdio \ cypress-firmware-43455-sdio \ - cypress-nvram-43455-sdio-rpi-3b-plus cypress-nvram-43455-sdio-rpi-4b \ - kmod-brcmfmac wpad-basic-wolfssl + brcmfmac-nvram-43455-sdio \ + kmod-brcmfmac wpad-basic-mbedtls IMAGE/sysupgrade.img.gz := boot-common | boot-2708 | boot-2711 | sdcard-img | gzip | append-metadata IMAGE/factory.img.gz := boot-common | boot-2708 | boot-2711 | sdcard-img | gzip endef @@ -119,7 +119,7 @@ ifeq ($(SUBTARGET),bcm2709) endif define Device/rpi-3 - DEVICE_MODEL := 3B/3B+/3CM + DEVICE_MODEL := 3B/3B+/CM3 DEVICE_VARIANT := (64bit) DEVICE_ALT0_VENDOR := Raspberry Pi DEVICE_ALT0_MODEL := 2B-1.2 @@ -138,17 +138,17 @@ define Device/rpi-3 raspberrypi,model-zero-2 DEVICE_PACKAGES := \ cypress-firmware-43430-sdio \ - cypress-nvram-43430-sdio-rpi-3b \ + brcmfmac-nvram-43430-sdio \ cypress-firmware-43455-sdio \ - cypress-nvram-43455-sdio-rpi-3b-plus \ - kmod-brcmfmac wpad-basic-wolfssl + brcmfmac-nvram-43455-sdio \ + kmod-brcmfmac wpad-basic-mbedtls endef ifeq ($(SUBTARGET),bcm2710) TARGET_DEVICES += rpi-3 endif define Device/rpi-4 - DEVICE_MODEL := 4B/400/4CM + DEVICE_MODEL := 4B/400/CM4 DEVICE_VARIANT := (64bit) KERNEL_IMG := kernel8.img DEVICE_DTS := \ @@ -161,9 +161,10 @@ define Device/rpi-4 raspberrypi,4-model-b DEVICE_PACKAGES := \ cypress-firmware-43455-sdio \ - cypress-nvram-43455-sdio-rpi-4b \ - kmod-brcmfmac wpad-basic-wolfssl \ - kmod-usb-net-lan78xx + brcmfmac-nvram-43455-sdio \ + kmod-brcmfmac wpad-basic-mbedtls \ + kmod-usb-net-lan78xx \ + kmod-r8169 IMAGE/sysupgrade.img.gz := boot-common | boot-2711 | sdcard-img | gzip | append-metadata IMAGE/factory.img.gz := boot-common | boot-2711 | sdcard-img | gzip endef @@ -171,4 +172,21 @@ ifeq ($(SUBTARGET),bcm2711) TARGET_DEVICES += rpi-4 endif +define Device/rpi-5 + DEVICE_MODEL := 5 + KERNEL_IMG := kernel_2712.img + DEVICE_DTS := broadcom/bcm2712-rpi-5-b + SUPPORTED_DEVICES := raspberrypi,5-model-b + DEVICE_PACKAGES := \ + cypress-firmware-43455-sdio \ + brcmfmac-nvram-43455-sdio \ + kmod-brcmfmac wpad-basic-mbedtls \ + kmod-hwmon-pwmfan kmod-thermal + IMAGE/sysupgrade.img.gz := boot-common | sdcard-img | gzip | append-metadata + IMAGE/factory.img.gz := boot-common | sdcard-img | gzip +endef +ifeq ($(SUBTARGET),bcm2712) + TARGET_DEVICES += rpi-5 +endif + $(eval $(call BuildImage)) diff --git a/target/linux/bcm27xx/image/config.txt b/target/linux/bcm27xx/image/config.txt index f8ca1bf2d..db35d72ab 100644 --- a/target/linux/bcm27xx/image/config.txt +++ b/target/linux/bcm27xx/image/config.txt @@ -4,7 +4,7 @@ ################################################################################ # For overclocking and various other settings, see: -# https://www.raspberrypi.org/documentation/configuration/config-txt/README.md +# https://www.raspberrypi.com/documentation/computers/config_txt.html ################################################################################ # OpenWrt config diff --git a/target/linux/bcm27xx/image/distroconfig.txt b/target/linux/bcm27xx/image/distroconfig.txt index 103c5d2e8..b09e5b846 100644 --- a/target/linux/bcm27xx/image/distroconfig.txt +++ b/target/linux/bcm27xx/image/distroconfig.txt @@ -5,7 +5,7 @@ # Restore PL011 (ttyAMA0) to GPIOs 14 & 15, instead of Mini UART (ttyS0). # Mini UART is disabled by default unless "enable_uart=1" is specified, # which changes the core frequency to a fixed value and impacts performance. -# See https://www.raspberrypi.org/documentation/configuration/uart.md +# See https://www.raspberrypi.com/documentation/computers/configuration.html#mini-uart-and-cpu-core-frequency [pi0w] dtoverlay=disable-bt [pi3] diff --git a/target/linux/bcm27xx/image/gen_rpi_sdcard_img.sh b/target/linux/bcm27xx/image/gen_rpi_sdcard_img.sh index 5e8fb2769..488a3517c 100755 --- a/target/linux/bcm27xx/image/gen_rpi_sdcard_img.sh +++ b/target/linux/bcm27xx/image/gen_rpi_sdcard_img.sh @@ -1,10 +1,11 @@ #!/bin/sh -set -x -[ $# -eq 5 ] || { +set -e -x + +if [ $# -ne 5 ]; then echo "SYNTAX: $0 " exit 1 -} +fi OUTPUT="$1" BOOTFS="$2" @@ -12,18 +13,16 @@ ROOTFS="$3" BOOTFSSIZE="$4" ROOTFSSIZE="$5" +align=4096 head=4 +kernel_type=c +rootfs_type=83 sect=63 -set $(ptgen -o $OUTPUT -h $head -s $sect -l 4096 -t c -p ${BOOTFSSIZE}M -t 83 -p ${ROOTFSSIZE}M) +set $(ptgen -o $OUTPUT -h $head -s $sect -l $align -t $kernel_type -p ${BOOTFSSIZE}M -t $rootfs_type -p ${ROOTFSSIZE}M) BOOTOFFSET="$(($1 / 512))" -BOOTSIZE="$(($2 / 512))" ROOTFSOFFSET="$(($3 / 512))" -ROOTFSSIZE="$(($4 / 512))" dd bs=512 if="$BOOTFS" of="$OUTPUT" seek="$BOOTOFFSET" conv=notrunc dd bs=512 if="$ROOTFS" of="$OUTPUT" seek="$ROOTFSOFFSET" conv=notrunc - - - diff --git a/target/linux/bcm27xx/modules/other.mk b/target/linux/bcm27xx/modules/other.mk index a9103029e..99b71d4d6 100644 --- a/target/linux/bcm27xx/modules/other.mk +++ b/target/linux/bcm27xx/modules/other.mk @@ -10,7 +10,7 @@ define KernelPackage/pwm-raspberrypi-poe CONFIG_PWM_RASPBERRYPI_POE FILES:=$(LINUX_DIR)/drivers/pwm/pwm-raspberrypi-poe.ko AUTOLOAD:=$(call AutoLoad,20,pwm-raspberrypi-poe) - DEPENDS:=@TARGET_bcm27xx @LINUX_5_15 +kmod-hwmon-pwmfan + DEPENDS:=@TARGET_bcm27xx +kmod-hwmon-pwmfan endef define KernelPackage/pwm-raspberrypi-poe/description diff --git a/target/linux/bcm27xx/modules/sound.mk b/target/linux/bcm27xx/modules/sound.mk index cf12ec33a..e61f07852 100644 --- a/target/linux/bcm27xx/modules/sound.mk +++ b/target/linux/bcm27xx/modules/sound.mk @@ -371,8 +371,7 @@ define KernelPackage/sound-soc-chipdip-dac $(LINUX_DIR)/sound/soc/bcm/snd-soc-chipdip-dac.ko AUTOLOAD:=$(call AutoLoad,68,snd-soc-chipdip-dac) DEPENDS:= \ - kmod-sound-soc-bcm2835-i2s \ - @LINUX_5_10 + kmod-sound-soc-bcm2835-i2s $(call AddDepends/sound) endef @@ -383,6 +382,29 @@ endef $(eval $(call KernelPackage,sound-soc-chipdip-dac)) +define KernelPackage/sound-soc-dacberry-soundcard + TITLE:=Support for DACBERRY400 Soundcard + KCONFIG:= \ + CONFIG_SND_DACBERRY400 \ + CONFIG_SND_SOC_TLV320AIC3X_I2C + FILES:= \ + $(LINUX_DIR)/sound/soc/bcm/snd-soc-dacberry400.ko \ + $(LINUX_DIR)/sound/soc/codecs/snd-soc-tlv320aic3x.ko + AUTOLOAD:=$(call AutoLoad,68,snd-soc-tlv320aic3x-i2c snd-soc-dacberry400) + DEPENDS:= \ + kmod-sound-soc-bcm2835-i2s \ + +kmod-i2c-bcm2835 \ + +kmod-regmap-i2c + $(call AddDepends/sound) +endef + +define KernelPackage/sound-soc-dacberry-soundcard/description + This package contains support for DACBERRY400 Soundcard +endef + +$(eval $(call KernelPackage,sound-soc-dacberry-soundcard)) + + define KernelPackage/sound-soc-digidac1-soundcard TITLE:=Support for RRA DigiDAC1 KCONFIG:= \ @@ -660,14 +682,17 @@ define KernelPackage/sound-soc-hifiberry-digi TITLE:=Support for HifiBerry Digi / Digi+ / Digi+ Pro KCONFIG:= \ CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI \ - CONFIG_SND_SOC_WM8804 + CONFIG_SND_SOC_WM8804 \ + CONFIG_SND_SOC_WM8804_I2C FILES:= \ - $(LINUX_DIR)/sound/soc/codecs/snd-soc-wm8804.ko - AUTOLOAD:=$(call AutoLoad,68,snd-soc-wm8804) + $(LINUX_DIR)/sound/soc/codecs/snd-soc-wm8804.ko \ + $(LINUX_DIR)/sound/soc/codecs/snd-soc-wm8804-i2c.ko + AUTOLOAD:=$(call AutoLoad,68,snd-soc-wm8804 snd-soc-wm8804-i2c) DEPENDS:= \ kmod-sound-soc-bcm2835-i2s \ +kmod-sound-soc-rpi-wm8804-soundcard \ - +kmod-i2c-bcm2835 + +kmod-i2c-bcm2835 \ + +kmod-regmap-i2c $(call AddDepends/sound) endef @@ -803,17 +828,23 @@ define KernelPackage/sound-soc-justboom-both KCONFIG:= \ CONFIG_SND_BCM2708_SOC_JUSTBOOM_BOTH \ CONFIG_SND_SOC_PCM512x \ - CONFIG_SND_SOC_WM8804 + CONFIG_SND_SOC_PCM512x_I2C \ + CONFIG_SND_SOC_WM8804 \ + CONFIG_SND_SOC_WM8804_I2C FILES:= \ $(LINUX_DIR)/sound/soc/bcm/snd-soc-justboom-both.ko \ $(LINUX_DIR)/sound/soc/codecs/snd-soc-pcm512x.ko \ - $(LINUX_DIR)/sound/soc/codecs/snd-soc-wm8804.ko - AUTOLOAD:=$(call AutoLoad,68,snd-soc-pcm512x snd-soc-wm8804 \ + $(LINUX_DIR)/sound/soc/codecs/snd-soc-pcm512x-i2c.ko \ + $(LINUX_DIR)/sound/soc/codecs/snd-soc-wm8804.ko \ + $(LINUX_DIR)/sound/soc/codecs/snd-soc-wm8804-i2c.ko + AUTOLOAD:=$(call AutoLoad,68,snd-soc-pcm512x-i2c snd-soc-pcm512x \ + snd-soc-wm8804-i2c snd-soc-wm8804 \ snd-soc-justboom-both) DEPENDS:= \ kmod-sound-soc-bcm2835-i2s \ +kmod-sound-soc-rpi-wm8804-soundcard \ - +kmod-i2c-bcm2835 + +kmod-i2c-bcm2835 \ + +kmod-regmap-i2c $(call AddDepends/sound) endef @@ -828,14 +859,18 @@ define KernelPackage/sound-soc-justboom-dac TITLE:=Support for JustBoom DAC KCONFIG:= \ CONFIG_SND_BCM2708_SOC_JUSTBOOM_DAC \ - CONFIG_SND_SOC_PCM512x + CONFIG_SND_SOC_PCM512x \ + CONFIG_SND_SOC_PCM512x_I2C FILES:= \ $(LINUX_DIR)/sound/soc/bcm/snd-soc-justboom-dac.ko \ - $(LINUX_DIR)/sound/soc/codecs/snd-soc-pcm512x.ko - AUTOLOAD:=$(call AutoLoad,68,snd-soc-pcm512x snd-soc-justboom-dac) + $(LINUX_DIR)/sound/soc/codecs/snd-soc-pcm512x.ko \ + $(LINUX_DIR)/sound/soc/codecs/snd-soc-pcm512x-i2c.ko + AUTOLOAD:=$(call AutoLoad,68,snd-soc-pcm512x-i2c snd-soc-pcm512x \ + snd-soc-justboom-dac) DEPENDS:= \ kmod-sound-soc-bcm2835-i2s \ - +kmod-i2c-bcm2835 + +kmod-i2c-bcm2835 \ + +kmod-regmap-i2c $(call AddDepends/sound) endef @@ -850,14 +885,17 @@ define KernelPackage/sound-soc-justboom-digi TITLE:=Support for JustBoom Digi KCONFIG:= \ CONFIG_SND_BCM2708_SOC_JUSTBOOM_DIGI \ - CONFIG_SND_SOC_WM8804 + CONFIG_SND_SOC_WM8804 \ + CONFIG_SND_SOC_WM8804_I2C FILES:= \ - $(LINUX_DIR)/sound/soc/codecs/snd-soc-wm8804.ko - AUTOLOAD:=$(call AutoLoad,68,snd-soc-wm8804) + $(LINUX_DIR)/sound/soc/codecs/snd-soc-wm8804.ko \ + $(LINUX_DIR)/sound/soc/codecs/snd-soc-wm8804-i2c.ko + AUTOLOAD:=$(call AutoLoad,68,snd-soc-wm8804-i2c snd-soc-wm8804) DEPENDS:= \ kmod-sound-soc-bcm2835-i2s \ +kmod-sound-soc-rpi-wm8804-soundcard \ - +kmod-i2c-bcm2835 + +kmod-i2c-bcm2835 \ + +kmod-regmap-i2c $(call AddDepends/sound) endef @@ -932,6 +970,7 @@ define KernelPackage/sound-soc-rpi-cirrus CONFIG_SND_SOC_WM8804 \ CONFIG_SND_SOC_WM_ADSP FILES:= \ + $(LINUX_DIR)/drivers/firmware/cirrus/cs_dsp.ko \ $(LINUX_DIR)/drivers/mfd/arizona.ko \ $(LINUX_DIR)/drivers/mfd/arizona-i2c.ko \ $(LINUX_DIR)/sound/soc/bcm/snd-soc-rpi-cirrus.ko \ @@ -939,7 +978,7 @@ define KernelPackage/sound-soc-rpi-cirrus $(LINUX_DIR)/sound/soc/codecs/snd-soc-wm-adsp.ko \ $(LINUX_DIR)/sound/soc/codecs/snd-soc-wm5102.ko \ $(LINUX_DIR)/sound/soc/codecs/snd-soc-wm8804.ko - AUTOLOAD:=$(call AutoLoad,68,snd-soc-pcm1794a snd-soc-rpi-cirrus) + AUTOLOAD:=$(call AutoLoad,68,snd-soc-rpi-cirrus) DEPENDS:= \ kmod-sound-soc-bcm2835-i2s \ +kmod-i2c-bcm2835 \ diff --git a/target/linux/bcm27xx/modules/video.mk b/target/linux/bcm27xx/modules/video.mk index 7e80203cb..c9b9555b0 100644 --- a/target/linux/bcm27xx/modules/video.mk +++ b/target/linux/bcm27xx/modules/video.mk @@ -5,13 +5,10 @@ define KernelPackage/camera-bcm2835 TITLE:=BCM2835 Camera KCONFIG:= \ - CONFIG_VIDEO_BCM2835 \ - CONFIG_VIDEO_BCM2835_MMAL \ - CONFIG_VIDEO_BCM2835_UNICAM=n \ - CONFIG_VIDEO_ISP_BCM2835=n + CONFIG_VIDEO_BCM2835 FILES:= \ $(LINUX_DIR)/drivers/staging/vc04_services/bcm2835-camera/bcm2835-v4l2.ko - AUTOLOAD:=$(call AutoLoad,65,bcm2835-v4l2) + AUTOLOAD:=$(call AutoLoad,66,bcm2835-v4l2) $(call AddDepends/video,@TARGET_bcm27xx +kmod-vchiq-mmal-bcm2835 +kmod-video-videobuf2) endef @@ -23,6 +20,24 @@ endef $(eval $(call KernelPackage,camera-bcm2835)) +define KernelPackage/codec-bcm2835 + TITLE:=BCM2835 Video Codec + KCONFIG:= \ + CONFIG_VIDEO_CODEC_BCM2835 + FILES:= \ + $(LINUX_DIR)/drivers/staging/vc04_services/bcm2835-codec/bcm2835-codec.ko + AUTOLOAD:=$(call AutoLoad,67,bcm2835-codec) + $(call AddDepends/video,@TARGET_bcm27xx +kmod-vchiq-mmal-bcm2835 +kmod-video-dma +kmod-video-mem2mem) +endef + +define KernelPackage/codec-bcm2835/description + V4L2 video codecs for Broadcom BCM2835 SoC. + This operates over the VCHIQ interface to a service running on VideoCore. +endef + +$(eval $(call KernelPackage,codec-bcm2835)) + + define KernelPackage/drm-vc4 SUBMENU:=$(VIDEO_MENU) TITLE:=Broadcom VC4 Graphics @@ -32,14 +47,12 @@ define KernelPackage/drm-vc4 +kmod-sound-soc-core KCONFIG:= \ CONFIG_DRM_VC4 \ - CONFIG_DRM_VC4_HDMI_CEC=y \ - CONFIG_DRM_GUD=n \ - CONFIG_DRM_V3D=n \ - CONFIG_DRM_TVE200=n + CONFIG_DRM_VC4_HDMI_CEC=y FILES:= \ + $(LINUX_DIR)/drivers/gpu/drm/display/drm_display_helper.ko \ + $(LINUX_DIR)/drivers/gpu/drm/drm_dma_helper.ko \ $(LINUX_DIR)/drivers/gpu/drm/vc4/vc4.ko \ $(LINUX_DIR)/drivers/gpu/drm/drm_kms_helper.ko \ - $(LINUX_DIR)/drivers/media/cec/cec.ko@lt5.10 \ $(LINUX_DIR)/drivers/media/cec/core/cec.ko AUTOLOAD:=$(call AutoProbe,vc4) endef @@ -52,6 +65,24 @@ endef $(eval $(call KernelPackage,drm-vc4)) +define KernelPackage/isp-bcm2835 + TITLE:=BCM2835 ISP + KCONFIG:= \ + CONFIG_VIDEO_ISP_BCM2835 + FILES:= \ + $(LINUX_DIR)/drivers/staging/vc04_services/bcm2835-isp/bcm2835-isp.ko + AUTOLOAD:=$(call AutoLoad,67,bcm2835-isp) + $(call AddDepends/video,@TARGET_bcm27xx +kmod-vchiq-mmal-bcm2835 +kmod-video-dma) +endef + +define KernelPackage/isp-bcm2835/description + V4L2 driver for the Broadcom BCM2835 ISP hardware. + This operates over the VCHIQ interface to a service running on VideoCore. +endef + +$(eval $(call KernelPackage,isp-bcm2835)) + + define KernelPackage/vc-sm-cma TITLE:=VideoCore Shared Memory (CMA) driver KCONFIG:= \ @@ -72,8 +103,7 @@ $(eval $(call KernelPackage,vc-sm-cma)) define KernelPackage/vchiq-mmal-bcm2835 TITLE:=BCM2835 MMAL VCHIQ service KCONFIG:= \ - CONFIG_BCM2835_VCHIQ_MMAL \ - CONFIG_VIDEO_CODEC_BCM2835=n + CONFIG_BCM2835_VCHIQ_MMAL FILES:= \ $(LINUX_DIR)/drivers/staging/vc04_services/vchiq-mmal/bcm2835-mmal-vchiq.ko $(call AddDepends/video,@TARGET_bcm27xx +kmod-vc-sm-cma) diff --git a/target/linux/bcm27xx/patches-5.15/200-Revert-net-broadcom-Add-PTP_1588_CLOCK_OPTIONAL-depe.patch b/target/linux/bcm27xx/patches-5.15/200-Revert-net-broadcom-Add-PTP_1588_CLOCK_OPTIONAL-depe.patch deleted file mode 100644 index 4357a6ba1..000000000 --- a/target/linux/bcm27xx/patches-5.15/200-Revert-net-broadcom-Add-PTP_1588_CLOCK_OPTIONAL-depe.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 882882912cd25a637ba0cf09932ad248f584e680 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= -Date: Wed, 28 Dec 2022 13:19:49 +0100 -Subject: [PATCH 1/2] Revert "net: broadcom: Add PTP_1588_CLOCK_OPTIONAL - dependency for BCMGENET under ARCH_BCM2835" - -[ Upstream commit 421f8663b3a775c32f724f793264097c60028f2e ] - -This reverts commit eb96fd3983b2cca1c90db45eaff1de67b94f9950. ---- - drivers/net/ethernet/broadcom/Kconfig | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - ---- a/drivers/net/ethernet/broadcom/Kconfig -+++ b/drivers/net/ethernet/broadcom/Kconfig -@@ -71,14 +71,13 @@ config BCM63XX_ENET - config BCMGENET - tristate "Broadcom GENET internal MAC support" - depends on HAS_IOMEM -- depends on PTP_1588_CLOCK_OPTIONAL || !ARCH_BCM2835 - select MII - select PHYLIB - select FIXED_PHY - select BCM7XXX_PHY - select MDIO_BCM_UNIMAC - select DIMLIB -- select BROADCOM_PHY if ARCH_BCM2835 -+ select BROADCOM_PHY if (ARCH_BCM2835 && PTP_1588_CLOCK_OPTIONAL) - help - This driver supports the built-in Ethernet MACs found in the - Broadcom BCM7xxx Set Top Box family chipset. diff --git a/target/linux/bcm27xx/patches-5.15/201-Revert-net-broadcom-Fix-BCMGENET-Kconfig.patch b/target/linux/bcm27xx/patches-5.15/201-Revert-net-broadcom-Fix-BCMGENET-Kconfig.patch deleted file mode 100644 index 1e29da5c9..000000000 --- a/target/linux/bcm27xx/patches-5.15/201-Revert-net-broadcom-Fix-BCMGENET-Kconfig.patch +++ /dev/null @@ -1,23 +0,0 @@ -From f032f801658ce6b47498f3e140f7e4aef0645042 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= -Date: Wed, 28 Dec 2022 13:20:24 +0100 -Subject: [PATCH 2/2] Revert "net: broadcom: Fix BCMGENET Kconfig" - -[ Upstream commit 8d820bc9d12b8beebca836cceaf2bbe68216c2f8 ] - -This reverts commit 6a264203dbdb0d076891d83bf3bb274d6b3863f2. ---- - drivers/net/ethernet/broadcom/Kconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/ethernet/broadcom/Kconfig -+++ b/drivers/net/ethernet/broadcom/Kconfig -@@ -77,7 +77,7 @@ config BCMGENET - select BCM7XXX_PHY - select MDIO_BCM_UNIMAC - select DIMLIB -- select BROADCOM_PHY if (ARCH_BCM2835 && PTP_1588_CLOCK_OPTIONAL) -+ select BROADCOM_PHY if ARCH_BCM2835 - help - This driver supports the built-in Ethernet MACs found in the - Broadcom BCM7xxx Set Top Box family chipset. diff --git a/target/linux/bcm27xx/patches-5.15/950-0001-drm-vc4-hdmi-Split-the-CEC-disable-enable-functions-.patch b/target/linux/bcm27xx/patches-5.15/950-0001-drm-vc4-hdmi-Split-the-CEC-disable-enable-functions-.patch deleted file mode 100644 index b12b6843d..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0001-drm-vc4-hdmi-Split-the-CEC-disable-enable-functions-.patch +++ /dev/null @@ -1,111 +0,0 @@ -From d145ff5ff4c35bf00a84c7f916165150d0a75e53 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Thu, 19 Aug 2021 15:59:29 +0200 -Subject: [PATCH] drm/vc4: hdmi: Split the CEC disable / enable - functions in two - -In order to ease further additions to the CEC enable and disable, let's -split the function into two functions, one to enable and the other to -disable. - -Reviewed-by: Dave Stevenson -Signed-off-by: Maxime Ripard -Link: https://patchwork.freedesktop.org/patch/msgid/20210819135931.895976-5-maxime@cerno.tech ---- - drivers/gpu/drm/vc4/vc4_hdmi.c | 75 ++++++++++++++++++++-------------- - 1 file changed, 45 insertions(+), 30 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_hdmi.c -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c -@@ -1749,7 +1749,7 @@ static irqreturn_t vc4_cec_irq_handler(i - return ret; - } - --static int vc4_hdmi_cec_adap_enable(struct cec_adapter *adap, bool enable) -+static int vc4_hdmi_cec_enable(struct cec_adapter *adap) - { - struct vc4_hdmi *vc4_hdmi = cec_get_drvdata(adap); - /* clock period in microseconds */ -@@ -1762,38 +1762,53 @@ static int vc4_hdmi_cec_adap_enable(stru - val |= ((4700 / usecs) << VC4_HDMI_CEC_CNT_TO_4700_US_SHIFT) | - ((4500 / usecs) << VC4_HDMI_CEC_CNT_TO_4500_US_SHIFT); - -- if (enable) { -- HDMI_WRITE(HDMI_CEC_CNTRL_5, val | -- VC4_HDMI_CEC_TX_SW_RESET | VC4_HDMI_CEC_RX_SW_RESET); -- HDMI_WRITE(HDMI_CEC_CNTRL_5, val); -- HDMI_WRITE(HDMI_CEC_CNTRL_2, -- ((1500 / usecs) << VC4_HDMI_CEC_CNT_TO_1500_US_SHIFT) | -- ((1300 / usecs) << VC4_HDMI_CEC_CNT_TO_1300_US_SHIFT) | -- ((800 / usecs) << VC4_HDMI_CEC_CNT_TO_800_US_SHIFT) | -- ((600 / usecs) << VC4_HDMI_CEC_CNT_TO_600_US_SHIFT) | -- ((400 / usecs) << VC4_HDMI_CEC_CNT_TO_400_US_SHIFT)); -- HDMI_WRITE(HDMI_CEC_CNTRL_3, -- ((2750 / usecs) << VC4_HDMI_CEC_CNT_TO_2750_US_SHIFT) | -- ((2400 / usecs) << VC4_HDMI_CEC_CNT_TO_2400_US_SHIFT) | -- ((2050 / usecs) << VC4_HDMI_CEC_CNT_TO_2050_US_SHIFT) | -- ((1700 / usecs) << VC4_HDMI_CEC_CNT_TO_1700_US_SHIFT)); -- HDMI_WRITE(HDMI_CEC_CNTRL_4, -- ((4300 / usecs) << VC4_HDMI_CEC_CNT_TO_4300_US_SHIFT) | -- ((3900 / usecs) << VC4_HDMI_CEC_CNT_TO_3900_US_SHIFT) | -- ((3600 / usecs) << VC4_HDMI_CEC_CNT_TO_3600_US_SHIFT) | -- ((3500 / usecs) << VC4_HDMI_CEC_CNT_TO_3500_US_SHIFT)); -- -- if (!vc4_hdmi->variant->external_irq_controller) -- HDMI_WRITE(HDMI_CEC_CPU_MASK_CLEAR, VC4_HDMI_CPU_CEC); -- } else { -- if (!vc4_hdmi->variant->external_irq_controller) -- HDMI_WRITE(HDMI_CEC_CPU_MASK_SET, VC4_HDMI_CPU_CEC); -- HDMI_WRITE(HDMI_CEC_CNTRL_5, val | -- VC4_HDMI_CEC_TX_SW_RESET | VC4_HDMI_CEC_RX_SW_RESET); -- } -+ HDMI_WRITE(HDMI_CEC_CNTRL_5, val | -+ VC4_HDMI_CEC_TX_SW_RESET | VC4_HDMI_CEC_RX_SW_RESET); -+ HDMI_WRITE(HDMI_CEC_CNTRL_5, val); -+ HDMI_WRITE(HDMI_CEC_CNTRL_2, -+ ((1500 / usecs) << VC4_HDMI_CEC_CNT_TO_1500_US_SHIFT) | -+ ((1300 / usecs) << VC4_HDMI_CEC_CNT_TO_1300_US_SHIFT) | -+ ((800 / usecs) << VC4_HDMI_CEC_CNT_TO_800_US_SHIFT) | -+ ((600 / usecs) << VC4_HDMI_CEC_CNT_TO_600_US_SHIFT) | -+ ((400 / usecs) << VC4_HDMI_CEC_CNT_TO_400_US_SHIFT)); -+ HDMI_WRITE(HDMI_CEC_CNTRL_3, -+ ((2750 / usecs) << VC4_HDMI_CEC_CNT_TO_2750_US_SHIFT) | -+ ((2400 / usecs) << VC4_HDMI_CEC_CNT_TO_2400_US_SHIFT) | -+ ((2050 / usecs) << VC4_HDMI_CEC_CNT_TO_2050_US_SHIFT) | -+ ((1700 / usecs) << VC4_HDMI_CEC_CNT_TO_1700_US_SHIFT)); -+ HDMI_WRITE(HDMI_CEC_CNTRL_4, -+ ((4300 / usecs) << VC4_HDMI_CEC_CNT_TO_4300_US_SHIFT) | -+ ((3900 / usecs) << VC4_HDMI_CEC_CNT_TO_3900_US_SHIFT) | -+ ((3600 / usecs) << VC4_HDMI_CEC_CNT_TO_3600_US_SHIFT) | -+ ((3500 / usecs) << VC4_HDMI_CEC_CNT_TO_3500_US_SHIFT)); -+ -+ if (!vc4_hdmi->variant->external_irq_controller) -+ HDMI_WRITE(HDMI_CEC_CPU_MASK_CLEAR, VC4_HDMI_CPU_CEC); -+ - return 0; - } - -+static int vc4_hdmi_cec_disable(struct cec_adapter *adap) -+{ -+ struct vc4_hdmi *vc4_hdmi = cec_get_drvdata(adap); -+ -+ if (!vc4_hdmi->variant->external_irq_controller) -+ HDMI_WRITE(HDMI_CEC_CPU_MASK_SET, VC4_HDMI_CPU_CEC); -+ -+ HDMI_WRITE(HDMI_CEC_CNTRL_5, HDMI_READ(HDMI_CEC_CNTRL_5) | -+ VC4_HDMI_CEC_TX_SW_RESET | VC4_HDMI_CEC_RX_SW_RESET); -+ -+ return 0; -+} -+ -+static int vc4_hdmi_cec_adap_enable(struct cec_adapter *adap, bool enable) -+{ -+ if (enable) -+ return vc4_hdmi_cec_enable(adap); -+ else -+ return vc4_hdmi_cec_disable(adap); -+} -+ - static int vc4_hdmi_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr) - { - struct vc4_hdmi *vc4_hdmi = cec_get_drvdata(adap); diff --git a/target/linux/bcm27xx/patches-5.15/950-0002-drm-vc4-hdmi-Make-sure-the-device-is-powered-with-CE.patch b/target/linux/bcm27xx/patches-5.15/950-0002-drm-vc4-hdmi-Make-sure-the-device-is-powered-with-CE.patch deleted file mode 100644 index 1904f1822..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0002-drm-vc4-hdmi-Make-sure-the-device-is-powered-with-CE.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 0ba6ff7f5632f01143911e307be538ecc62e5094 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Thu, 19 Aug 2021 15:59:30 +0200 -Subject: [PATCH] drm/vc4: hdmi: Make sure the device is powered with - CEC - -Similarly to what we encountered with the detect hook with DRM, nothing -actually prevents any of the CEC callback from being run while the HDMI -output is disabled. - -However, this is an issue since any register access to the controller -when it's powered down will result in a silent hang. - -Let's make sure we run the runtime_pm hooks when the CEC adapter is -opened and closed by the userspace to avoid that issue. - -Fixes: 15b4511a4af6 ("drm/vc4: add HDMI CEC support") -Reviewed-by: Dave Stevenson -Signed-off-by: Maxime Ripard -Link: https://patchwork.freedesktop.org/patch/msgid/20210819135931.895976-6-maxime@cerno.tech ---- - drivers/gpu/drm/vc4/vc4_hdmi.c | 10 +++++++++- - 1 file changed, 9 insertions(+), 1 deletion(-) - ---- a/drivers/gpu/drm/vc4/vc4_hdmi.c -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c -@@ -1754,8 +1754,14 @@ static int vc4_hdmi_cec_enable(struct ce - struct vc4_hdmi *vc4_hdmi = cec_get_drvdata(adap); - /* clock period in microseconds */ - const u32 usecs = 1000000 / CEC_CLOCK_FREQ; -- u32 val = HDMI_READ(HDMI_CEC_CNTRL_5); -+ u32 val; -+ int ret; - -+ ret = pm_runtime_resume_and_get(&vc4_hdmi->pdev->dev); -+ if (ret) -+ return ret; -+ -+ val = HDMI_READ(HDMI_CEC_CNTRL_5); - val &= ~(VC4_HDMI_CEC_TX_SW_RESET | VC4_HDMI_CEC_RX_SW_RESET | - VC4_HDMI_CEC_CNT_TO_4700_US_MASK | - VC4_HDMI_CEC_CNT_TO_4500_US_MASK); -@@ -1798,6 +1804,8 @@ static int vc4_hdmi_cec_disable(struct c - HDMI_WRITE(HDMI_CEC_CNTRL_5, HDMI_READ(HDMI_CEC_CNTRL_5) | - VC4_HDMI_CEC_TX_SW_RESET | VC4_HDMI_CEC_RX_SW_RESET); - -+ pm_runtime_put(&vc4_hdmi->pdev->dev); -+ - return 0; - } - diff --git a/target/linux/bcm27xx/patches-5.15/950-0003-drm-vc4-hdmi-Warn-if-we-access-the-controller-while-.patch b/target/linux/bcm27xx/patches-5.15/950-0003-drm-vc4-hdmi-Warn-if-we-access-the-controller-while-.patch deleted file mode 100644 index adf4709e2..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0003-drm-vc4-hdmi-Warn-if-we-access-the-controller-while-.patch +++ /dev/null @@ -1,49 +0,0 @@ -From d0a44f399526a061e74b9a34b554f3d0e9cdddb3 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Thu, 19 Aug 2021 15:59:31 +0200 -Subject: [PATCH] drm/vc4: hdmi: Warn if we access the controller while - disabled - -We've had many silent hangs where the kernel would look like it just -stalled due to the access to one of the HDMI registers while the -controller was disabled. - -Add a warning if we're about to do that so that it's at least not silent -anymore. - -Reviewed-by: Dave Stevenson -Signed-off-by: Maxime Ripard -Link: https://patchwork.freedesktop.org/patch/msgid/20210819135931.895976-7-maxime@cerno.tech ---- - drivers/gpu/drm/vc4/vc4_hdmi_regs.h | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- a/drivers/gpu/drm/vc4/vc4_hdmi_regs.h -+++ b/drivers/gpu/drm/vc4/vc4_hdmi_regs.h -@@ -1,6 +1,8 @@ - #ifndef _VC4_HDMI_REGS_H_ - #define _VC4_HDMI_REGS_H_ - -+#include -+ - #include "vc4_hdmi.h" - - #define VC4_HDMI_PACKET_STRIDE 0x24 -@@ -415,6 +417,8 @@ static inline u32 vc4_hdmi_read(struct v - const struct vc4_hdmi_variant *variant = hdmi->variant; - void __iomem *base; - -+ WARN_ON(!pm_runtime_active(&hdmi->pdev->dev)); -+ - if (reg >= variant->num_registers) { - dev_warn(&hdmi->pdev->dev, - "Invalid register ID %u\n", reg); -@@ -441,6 +445,8 @@ static inline void vc4_hdmi_write(struct - const struct vc4_hdmi_variant *variant = hdmi->variant; - void __iomem *base; - -+ WARN_ON(!pm_runtime_active(&hdmi->pdev->dev)); -+ - if (reg >= variant->num_registers) { - dev_warn(&hdmi->pdev->dev, - "Invalid register ID %u\n", reg); diff --git a/target/linux/bcm27xx/patches-5.15/950-0004-drm-vc4-hdmi-Remove-the-DDC-probing-for-status-detec.patch b/target/linux/bcm27xx/patches-5.15/950-0004-drm-vc4-hdmi-Remove-the-DDC-probing-for-status-detec.patch deleted file mode 100644 index 83976961e..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0004-drm-vc4-hdmi-Remove-the-DDC-probing-for-status-detec.patch +++ /dev/null @@ -1,47 +0,0 @@ -From faa24f47c0066893e0b7772befe378bde4dc2ff9 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Mon, 25 Oct 2021 17:28:54 +0200 -Subject: [PATCH] drm/vc4: hdmi: Remove the DDC probing for status - detection - -Commit 9d44abbbb8d5 ("drm/vc4: Fall back to using an EDID probe in the -absence of a GPIO.") added some code to read the EDID through DDC in the -HDMI driver detect hook since the Pi3 had no HPD GPIO back then. -However, commit b1b8f45b3130 ("ARM: dts: bcm2837: Add missing GPIOs of -Expander") changed that a couple of years later. - -This causes an issue though since some TV (like the LG 55C8) when it -comes out of standy will deassert the HPD line, but the EDID will -remain readable. - -It causes an issues nn platforms without an HPD GPIO, like the Pi4, -where the DDC probing will be our primary mean to detect a display, and -thus we will never detect the HPD pulse. This was fine before since the -pulse was small enough that we would never detect it, and we also didn't -have anything (like the scrambler) that needed to be set up in the -display. - -However, now that we have both, the display during the HPD pulse will -clear its scrambler status, and since we won't detect the -disconnect/reconnect cycle we will never enable the scrambler back. - -As our main reason for that DDC probing is gone, let's just remove it. - -Signed-off-by: Maxime Ripard -Reviewed-by: Dave Stevenson -Link: https://lore.kernel.org/r/20211025152903.1088803-2-maxime@cerno.tech ---- - drivers/gpu/drm/vc4/vc4_hdmi.c | 2 -- - 1 file changed, 2 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_hdmi.c -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c -@@ -179,8 +179,6 @@ vc4_hdmi_connector_detect(struct drm_con - if (vc4_hdmi->hpd_gpio) { - if (gpiod_get_value_cansleep(vc4_hdmi->hpd_gpio)) - connected = true; -- } else if (drm_probe_ddc(vc4_hdmi->ddc)) { -- connected = true; - } else if (HDMI_READ(HDMI_HOTPLUG) & VC4_HDMI_HOTPLUG_CONNECTED) { - connected = true; - } diff --git a/target/linux/bcm27xx/patches-5.15/950-0005-drm-vc4-hdmi-Raise-the-maximum-clock-rate.patch b/target/linux/bcm27xx/patches-5.15/950-0005-drm-vc4-hdmi-Raise-the-maximum-clock-rate.patch deleted file mode 100644 index 020b56b87..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0005-drm-vc4-hdmi-Raise-the-maximum-clock-rate.patch +++ /dev/null @@ -1,31 +0,0 @@ -From f818ed9b9033ef7fbe45a7f5e2fc8c0d0cfe8c1d Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Mon, 25 Oct 2021 17:29:01 +0200 -Subject: [PATCH] drm/vc4: hdmi: Raise the maximum clock rate - -Now that we have the infrastructure in place, we can raise the maximum -pixel rate we can reach for HDMI0 on the BCM2711. - -HDMI1 is left untouched since its pixelvalve has a smaller FIFO and -would need a clock faster than what we can provide to support the same -modes. - -Acked-by: Thomas Zimmermann -Reviewed-by: Dave Stevenson -Signed-off-by: Maxime Ripard -Link: https://lore.kernel.org/r/20211025152903.1088803-9-maxime@cerno.tech ---- - drivers/gpu/drm/vc4/vc4_hdmi.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/gpu/drm/vc4/vc4_hdmi.c -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c -@@ -2387,7 +2387,7 @@ static const struct vc4_hdmi_variant bcm - .encoder_type = VC4_ENCODER_TYPE_HDMI0, - .debugfs_name = "hdmi0_regs", - .card_name = "vc4-hdmi-0", -- .max_pixel_clock = HDMI_14_MAX_TMDS_CLK, -+ .max_pixel_clock = 600000000, - .registers = vc5_hdmi_hdmi0_fields, - .num_registers = ARRAY_SIZE(vc5_hdmi_hdmi0_fields), - .phy_lane_mapping = { diff --git a/target/linux/bcm27xx/patches-5.15/950-0007-drm-vc4-hdmi-Add-a-spinlock-to-protect-register-acce.patch b/target/linux/bcm27xx/patches-5.15/950-0007-drm-vc4-hdmi-Add-a-spinlock-to-protect-register-acce.patch deleted file mode 100644 index 8691fdc49..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0007-drm-vc4-hdmi-Add-a-spinlock-to-protect-register-acce.patch +++ /dev/null @@ -1,907 +0,0 @@ -From d91a953904e1aeddf24a95af40fc1ae7ba2319fd Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Mon, 25 Oct 2021 16:11:08 +0200 -Subject: [PATCH] drm/vc4: hdmi: Add a spinlock to protect register - access - -The vc4 HDMI driver has multiple path shared between the CEC, ALSA and -KMS frameworks, plus two interrupt handlers (CEC and hotplug) that will -read and modify a number of registers. - -Even though not bug has been reported so far, it's definitely unsafe, so -let's just add a spinlock to protect the register access of the HDMI -controller. - -Link: https://lore.kernel.org/r/20211025141113.702757-5-maxime@cerno.tech -Fixes: c8b75bca92cb ("drm/vc4: Add KMS support for Raspberry Pi.") -Acked-by: Daniel Vetter -Signed-off-by: Maxime Ripard ---- - drivers/gpu/drm/vc4/vc4_hdmi.c | 202 ++++++++++++++++++++++++++-- - drivers/gpu/drm/vc4/vc4_hdmi.h | 5 + - drivers/gpu/drm/vc4/vc4_hdmi_phy.c | 37 +++++ - drivers/gpu/drm/vc4/vc4_hdmi_regs.h | 2 + - 4 files changed, 236 insertions(+), 10 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_hdmi.c -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c -@@ -122,6 +122,10 @@ static int vc4_hdmi_debugfs_regs(struct - - static void vc4_hdmi_reset(struct vc4_hdmi *vc4_hdmi) - { -+ unsigned long flags; -+ -+ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); -+ - HDMI_WRITE(HDMI_M_CTL, VC4_HD_M_SW_RST); - udelay(1); - HDMI_WRITE(HDMI_M_CTL, 0); -@@ -133,24 +137,36 @@ static void vc4_hdmi_reset(struct vc4_hd - VC4_HDMI_SW_RESET_FORMAT_DETECT); - - HDMI_WRITE(HDMI_SW_RESET_CONTROL, 0); -+ -+ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); - } - - static void vc5_hdmi_reset(struct vc4_hdmi *vc4_hdmi) - { -+ unsigned long flags; -+ - reset_control_reset(vc4_hdmi->reset); - -+ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); -+ - HDMI_WRITE(HDMI_DVP_CTL, 0); - - HDMI_WRITE(HDMI_CLOCK_STOP, - HDMI_READ(HDMI_CLOCK_STOP) | VC4_DVP_HT_CLOCK_STOP_PIXEL); -+ -+ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); - } - - #ifdef CONFIG_DRM_VC4_HDMI_CEC - static void vc4_hdmi_cec_update_clk_div(struct vc4_hdmi *vc4_hdmi) - { -+ unsigned long cec_rate = clk_get_rate(vc4_hdmi->cec_clock); -+ unsigned long flags; - u16 clk_cnt; - u32 value; - -+ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); -+ - value = HDMI_READ(HDMI_CEC_CNTRL_1); - value &= ~VC4_HDMI_CEC_DIV_CLK_CNT_MASK; - -@@ -158,9 +174,11 @@ static void vc4_hdmi_cec_update_clk_div( - * Set the clock divider: the hsm_clock rate and this divider - * setting will give a 40 kHz CEC clock. - */ -- clk_cnt = clk_get_rate(vc4_hdmi->cec_clock) / CEC_CLOCK_FREQ; -+ clk_cnt = cec_rate / CEC_CLOCK_FREQ; - value |= clk_cnt << VC4_HDMI_CEC_DIV_CLK_CNT_SHIFT; - HDMI_WRITE(HDMI_CEC_CNTRL_1, value); -+ -+ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); - } - #else - static void vc4_hdmi_cec_update_clk_div(struct vc4_hdmi *vc4_hdmi) {} -@@ -179,8 +197,16 @@ vc4_hdmi_connector_detect(struct drm_con - if (vc4_hdmi->hpd_gpio) { - if (gpiod_get_value_cansleep(vc4_hdmi->hpd_gpio)) - connected = true; -- } else if (HDMI_READ(HDMI_HOTPLUG) & VC4_HDMI_HOTPLUG_CONNECTED) { -- connected = true; -+ } else { -+ unsigned long flags; -+ u32 hotplug; -+ -+ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); -+ hotplug = HDMI_READ(HDMI_HOTPLUG); -+ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); -+ -+ if (hotplug & VC4_HDMI_HOTPLUG_CONNECTED) -+ connected = true; - } - - if (connected) { -@@ -374,9 +400,12 @@ static int vc4_hdmi_stop_packet(struct d - { - struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); - u32 packet_id = type - 0x80; -+ unsigned long flags; - -+ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); - HDMI_WRITE(HDMI_RAM_PACKET_CONFIG, - HDMI_READ(HDMI_RAM_PACKET_CONFIG) & ~BIT(packet_id)); -+ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); - - if (!poll) - return 0; -@@ -396,6 +425,7 @@ static void vc4_hdmi_write_infoframe(str - void __iomem *base = __vc4_hdmi_get_field_base(vc4_hdmi, - ram_packet_start->reg); - uint8_t buffer[VC4_HDMI_PACKET_STRIDE]; -+ unsigned long flags; - ssize_t len, i; - int ret; - -@@ -413,6 +443,8 @@ static void vc4_hdmi_write_infoframe(str - return; - } - -+ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); -+ - for (i = 0; i < len; i += 7) { - writel(buffer[i + 0] << 0 | - buffer[i + 1] << 8 | -@@ -430,6 +462,9 @@ static void vc4_hdmi_write_infoframe(str - - HDMI_WRITE(HDMI_RAM_PACKET_CONFIG, - HDMI_READ(HDMI_RAM_PACKET_CONFIG) | BIT(packet_id)); -+ -+ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); -+ - ret = wait_for((HDMI_READ(HDMI_RAM_PACKET_STATUS) & - BIT(packet_id)), 100); - if (ret) -@@ -549,6 +584,7 @@ static void vc4_hdmi_enable_scrambling(s - { - struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode; - struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); -+ unsigned long flags; - - if (!vc4_hdmi_supports_scrambling(encoder, mode)) - return; -@@ -559,8 +595,10 @@ static void vc4_hdmi_enable_scrambling(s - drm_scdc_set_high_tmds_clock_ratio(vc4_hdmi->ddc, true); - drm_scdc_set_scrambling(vc4_hdmi->ddc, true); - -+ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); - HDMI_WRITE(HDMI_SCRAMBLER_CTL, HDMI_READ(HDMI_SCRAMBLER_CTL) | - VC5_HDMI_SCRAMBLER_CTL_ENABLE); -+ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); - - queue_delayed_work(system_wq, &vc4_hdmi->scrambling_work, - msecs_to_jiffies(SCRAMBLING_POLLING_DELAY_MS)); -@@ -570,6 +608,7 @@ static void vc4_hdmi_disable_scrambling( - { - struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); - struct drm_crtc *crtc = encoder->crtc; -+ unsigned long flags; - - /* - * At boot, encoder->crtc will be NULL. Since we don't know the -@@ -585,8 +624,10 @@ static void vc4_hdmi_disable_scrambling( - if (delayed_work_pending(&vc4_hdmi->scrambling_work)) - cancel_delayed_work_sync(&vc4_hdmi->scrambling_work); - -+ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); - HDMI_WRITE(HDMI_SCRAMBLER_CTL, HDMI_READ(HDMI_SCRAMBLER_CTL) & - ~VC5_HDMI_SCRAMBLER_CTL_ENABLE); -+ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); - - drm_scdc_set_scrambling(vc4_hdmi->ddc, false); - drm_scdc_set_high_tmds_clock_ratio(vc4_hdmi->ddc, false); -@@ -612,15 +653,23 @@ static void vc4_hdmi_encoder_post_crtc_d - struct drm_atomic_state *state) - { - struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); -+ unsigned long flags; -+ -+ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); - - HDMI_WRITE(HDMI_RAM_PACKET_CONFIG, 0); - - HDMI_WRITE(HDMI_VID_CTL, HDMI_READ(HDMI_VID_CTL) | VC4_HD_VID_CTL_CLRRGB); - -+ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); -+ - mdelay(1); - -+ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); - HDMI_WRITE(HDMI_VID_CTL, - HDMI_READ(HDMI_VID_CTL) & ~VC4_HD_VID_CTL_ENABLE); -+ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); -+ - vc4_hdmi_disable_scrambling(encoder); - } - -@@ -628,10 +677,13 @@ static void vc4_hdmi_encoder_post_crtc_p - struct drm_atomic_state *state) - { - struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); -+ unsigned long flags; - int ret; - -+ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); - HDMI_WRITE(HDMI_VID_CTL, - HDMI_READ(HDMI_VID_CTL) | VC4_HD_VID_CTL_BLANKPIX); -+ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); - - if (vc4_hdmi->variant->phy_disable) - vc4_hdmi->variant->phy_disable(vc4_hdmi); -@@ -650,8 +702,11 @@ static void vc4_hdmi_encoder_disable(str - - static void vc4_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, bool enable) - { -+ unsigned long flags; - u32 csc_ctl; - -+ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); -+ - csc_ctl = VC4_SET_FIELD(VC4_HD_CSC_CTL_ORDER_BGR, - VC4_HD_CSC_CTL_ORDER); - -@@ -681,14 +736,19 @@ static void vc4_hdmi_csc_setup(struct vc - - /* The RGB order applies even when CSC is disabled. */ - HDMI_WRITE(HDMI_CSC_CTL, csc_ctl); -+ -+ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); - } - - static void vc5_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, bool enable) - { -+ unsigned long flags; - u32 csc_ctl; - - csc_ctl = 0x07; /* RGB_CONVERT_MODE = custom matrix, || USE_RGB_TO_YCBCR */ - -+ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); -+ - if (enable) { - /* CEA VICs other than #1 requre limited range RGB - * output unless overridden by an AVI infoframe. -@@ -720,6 +780,8 @@ static void vc5_hdmi_csc_setup(struct vc - } - - HDMI_WRITE(HDMI_CSC_CTL, csc_ctl); -+ -+ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); - } - - static void vc4_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi, -@@ -743,6 +805,9 @@ static void vc4_hdmi_set_timings(struct - VC4_SET_FIELD(mode->crtc_vtotal - - mode->crtc_vsync_end, - VC4_HDMI_VERTB_VBP)); -+ unsigned long flags; -+ -+ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); - - HDMI_WRITE(HDMI_HORZA, - (vsync_pos ? VC4_HDMI_HORZA_VPOS : 0) | -@@ -766,6 +831,8 @@ static void vc4_hdmi_set_timings(struct - - HDMI_WRITE(HDMI_VERTB0, vertb_even); - HDMI_WRITE(HDMI_VERTB1, vertb); -+ -+ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); - } - - static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi, -@@ -790,10 +857,13 @@ static void vc5_hdmi_set_timings(struct - VC4_SET_FIELD(mode->crtc_vtotal - - mode->crtc_vsync_end, - VC4_HDMI_VERTB_VBP)); -+ unsigned long flags; - unsigned char gcp; - bool gcp_en; - u32 reg; - -+ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); -+ - HDMI_WRITE(HDMI_VEC_INTERFACE_XBAR, 0x354021); - HDMI_WRITE(HDMI_HORZA, - (vsync_pos ? VC5_HDMI_HORZA_VPOS : 0) | -@@ -857,13 +927,18 @@ static void vc5_hdmi_set_timings(struct - HDMI_WRITE(HDMI_MISC_CONTROL, reg); - - HDMI_WRITE(HDMI_CLOCK_STOP, 0); -+ -+ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); - } - - static void vc4_hdmi_recenter_fifo(struct vc4_hdmi *vc4_hdmi) - { -+ unsigned long flags; - u32 drift; - int ret; - -+ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); -+ - drift = HDMI_READ(HDMI_FIFO_CTL); - drift &= VC4_HDMI_FIFO_VALID_WRITE_MASK; - -@@ -871,12 +946,20 @@ static void vc4_hdmi_recenter_fifo(struc - drift & ~VC4_HDMI_FIFO_CTL_RECENTER); - HDMI_WRITE(HDMI_FIFO_CTL, - drift | VC4_HDMI_FIFO_CTL_RECENTER); -+ -+ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); -+ - usleep_range(1000, 1100); -+ -+ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); -+ - HDMI_WRITE(HDMI_FIFO_CTL, - drift & ~VC4_HDMI_FIFO_CTL_RECENTER); - HDMI_WRITE(HDMI_FIFO_CTL, - drift | VC4_HDMI_FIFO_CTL_RECENTER); - -+ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); -+ - ret = wait_for(HDMI_READ(HDMI_FIFO_CTL) & - VC4_HDMI_FIFO_CTL_RECENTER_DONE, 1); - WARN_ONCE(ret, "Timeout waiting for " -@@ -910,6 +993,7 @@ static void vc4_hdmi_encoder_pre_crtc_co - struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); - unsigned long pixel_rate = vc4_conn_state->pixel_rate; - unsigned long bvb_rate, hsm_rate; -+ unsigned long flags; - int ret; - - /* -@@ -978,11 +1062,15 @@ static void vc4_hdmi_encoder_pre_crtc_co - if (vc4_hdmi->variant->phy_init) - vc4_hdmi->variant->phy_init(vc4_hdmi, vc4_conn_state); - -+ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); -+ - HDMI_WRITE(HDMI_SCHEDULER_CONTROL, - HDMI_READ(HDMI_SCHEDULER_CONTROL) | - VC4_HDMI_SCHEDULER_CONTROL_MANUAL_FORMAT | - VC4_HDMI_SCHEDULER_CONTROL_IGNORE_VSYNC_PREDICTS); - -+ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); -+ - if (vc4_hdmi->variant->set_timings) - vc4_hdmi->variant->set_timings(vc4_hdmi, conn_state, mode); - -@@ -1002,6 +1090,7 @@ static void vc4_hdmi_encoder_pre_crtc_en - struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode; - struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder); - struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); -+ unsigned long flags; - - if (vc4_encoder->hdmi_monitor && - drm_default_rgb_quant_range(mode) == HDMI_QUANTIZATION_RANGE_LIMITED) { -@@ -1016,7 +1105,9 @@ static void vc4_hdmi_encoder_pre_crtc_en - vc4_encoder->limited_rgb_range = false; - } - -+ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); - HDMI_WRITE(HDMI_FIFO_CTL, VC4_HDMI_FIFO_CTL_MASTER_SLAVE_N); -+ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); - } - - static void vc4_hdmi_encoder_post_crtc_enable(struct drm_encoder *encoder, -@@ -1027,8 +1118,11 @@ static void vc4_hdmi_encoder_post_crtc_e - struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder); - bool hsync_pos = mode->flags & DRM_MODE_FLAG_PHSYNC; - bool vsync_pos = mode->flags & DRM_MODE_FLAG_PVSYNC; -+ unsigned long flags; - int ret; - -+ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); -+ - HDMI_WRITE(HDMI_VID_CTL, - VC4_HD_VID_CTL_ENABLE | - VC4_HD_VID_CTL_CLRRGB | -@@ -1045,6 +1139,8 @@ static void vc4_hdmi_encoder_post_crtc_e - HDMI_READ(HDMI_SCHEDULER_CONTROL) | - VC4_HDMI_SCHEDULER_CONTROL_MODE_HDMI); - -+ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); -+ - ret = wait_for(HDMI_READ(HDMI_SCHEDULER_CONTROL) & - VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE, 1000); - WARN_ONCE(ret, "Timeout waiting for " -@@ -1057,6 +1153,8 @@ static void vc4_hdmi_encoder_post_crtc_e - HDMI_READ(HDMI_SCHEDULER_CONTROL) & - ~VC4_HDMI_SCHEDULER_CONTROL_MODE_HDMI); - -+ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); -+ - ret = wait_for(!(HDMI_READ(HDMI_SCHEDULER_CONTROL) & - VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE), 1000); - WARN_ONCE(ret, "Timeout waiting for " -@@ -1064,6 +1162,8 @@ static void vc4_hdmi_encoder_post_crtc_e - } - - if (vc4_encoder->hdmi_monitor) { -+ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); -+ - WARN_ON(!(HDMI_READ(HDMI_SCHEDULER_CONTROL) & - VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE)); - HDMI_WRITE(HDMI_SCHEDULER_CONTROL, -@@ -1073,6 +1173,8 @@ static void vc4_hdmi_encoder_post_crtc_e - HDMI_WRITE(HDMI_RAM_PACKET_CONFIG, - VC4_HDMI_RAM_PACKET_ENABLE); - -+ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); -+ - vc4_hdmi_set_infoframes(encoder); - } - -@@ -1196,6 +1298,7 @@ static void vc4_hdmi_audio_set_mai_clock - unsigned int samplerate) - { - u32 hsm_clock = clk_get_rate(vc4_hdmi->audio_clock); -+ unsigned long flags; - unsigned long n, m; - - rational_best_approximation(hsm_clock, samplerate, -@@ -1205,9 +1308,11 @@ static void vc4_hdmi_audio_set_mai_clock - VC4_HD_MAI_SMP_M_SHIFT) + 1, - &n, &m); - -+ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); - HDMI_WRITE(HDMI_MAI_SMP, - VC4_SET_FIELD(n, VC4_HD_MAI_SMP_N) | - VC4_SET_FIELD(m - 1, VC4_HD_MAI_SMP_M)); -+ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); - } - - static void vc4_hdmi_set_n_cts(struct vc4_hdmi *vc4_hdmi, unsigned int samplerate) -@@ -1218,6 +1323,8 @@ static void vc4_hdmi_set_n_cts(struct vc - u32 n, cts; - u64 tmp; - -+ lockdep_assert_held(&vc4_hdmi->hw_lock); -+ - n = 128 * samplerate / 1000; - tmp = (u64)(mode->clock * 1000) * n; - do_div(tmp, 128 * samplerate); -@@ -1247,6 +1354,7 @@ static int vc4_hdmi_audio_startup(struct - { - struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev); - struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base; -+ unsigned long flags; - - /* - * If the HDMI encoder hasn't probed, or the encoder is -@@ -1258,12 +1366,14 @@ static int vc4_hdmi_audio_startup(struct - - vc4_hdmi->audio.streaming = true; - -+ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); - HDMI_WRITE(HDMI_MAI_CTL, - VC4_HD_MAI_CTL_RESET | - VC4_HD_MAI_CTL_FLUSH | - VC4_HD_MAI_CTL_DLATE | - VC4_HD_MAI_CTL_ERRORE | - VC4_HD_MAI_CTL_ERRORF); -+ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); - - if (vc4_hdmi->variant->phy_rng_enable) - vc4_hdmi->variant->phy_rng_enable(vc4_hdmi); -@@ -1275,6 +1385,7 @@ static void vc4_hdmi_audio_reset(struct - { - struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base; - struct device *dev = &vc4_hdmi->pdev->dev; -+ unsigned long flags; - int ret; - - vc4_hdmi->audio.streaming = false; -@@ -1282,20 +1393,29 @@ static void vc4_hdmi_audio_reset(struct - if (ret) - dev_err(dev, "Failed to stop audio infoframe: %d\n", ret); - -+ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); -+ - HDMI_WRITE(HDMI_MAI_CTL, VC4_HD_MAI_CTL_RESET); - HDMI_WRITE(HDMI_MAI_CTL, VC4_HD_MAI_CTL_ERRORF); - HDMI_WRITE(HDMI_MAI_CTL, VC4_HD_MAI_CTL_FLUSH); -+ -+ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); - } - - static void vc4_hdmi_audio_shutdown(struct device *dev, void *data) - { - struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev); -+ unsigned long flags; -+ -+ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); - - HDMI_WRITE(HDMI_MAI_CTL, - VC4_HD_MAI_CTL_DLATE | - VC4_HD_MAI_CTL_ERRORE | - VC4_HD_MAI_CTL_ERRORF); - -+ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); -+ - if (vc4_hdmi->variant->phy_rng_disable) - vc4_hdmi->variant->phy_rng_disable(vc4_hdmi); - -@@ -1350,6 +1470,7 @@ static int vc4_hdmi_audio_prepare(struct - struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base; - unsigned int sample_rate = params->sample_rate; - unsigned int channels = params->channels; -+ unsigned long flags; - u32 audio_packet_config, channel_mask; - u32 channel_map; - u32 mai_audio_format; -@@ -1358,14 +1479,15 @@ static int vc4_hdmi_audio_prepare(struct - dev_dbg(dev, "%s: %u Hz, %d bit, %d channels\n", __func__, - sample_rate, params->sample_width, channels); - -+ vc4_hdmi_audio_set_mai_clock(vc4_hdmi, sample_rate); -+ -+ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); - HDMI_WRITE(HDMI_MAI_CTL, - VC4_SET_FIELD(channels, VC4_HD_MAI_CTL_CHNUM) | - VC4_HD_MAI_CTL_WHOLSMP | - VC4_HD_MAI_CTL_CHALIGN | - VC4_HD_MAI_CTL_ENABLE); - -- vc4_hdmi_audio_set_mai_clock(vc4_hdmi, sample_rate); -- - mai_sample_rate = sample_rate_to_mai_fmt(sample_rate); - if (params->iec.status[0] & IEC958_AES0_NONAUDIO && - params->channels == 8) -@@ -1403,8 +1525,11 @@ static int vc4_hdmi_audio_prepare(struct - channel_map = vc4_hdmi->variant->channel_map(vc4_hdmi, channel_mask); - HDMI_WRITE(HDMI_MAI_CHANNEL_MAP, channel_map); - HDMI_WRITE(HDMI_AUDIO_PACKET_CONFIG, audio_packet_config); -+ - vc4_hdmi_set_n_cts(vc4_hdmi, sample_rate); - -+ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); -+ - memcpy(&vc4_hdmi->audio.infoframe, ¶ms->cea, sizeof(params->cea)); - vc4_hdmi_set_audio_infoframe(encoder); - -@@ -1678,6 +1803,8 @@ static void vc4_cec_read_msg(struct vc4_ - struct cec_msg *msg = &vc4_hdmi->cec_rx_msg; - unsigned int i; - -+ lockdep_assert_held(&vc4_hdmi->hw_lock); -+ - msg->len = 1 + ((cntrl1 & VC4_HDMI_CEC_REC_WRD_CNT_MASK) >> - VC4_HDMI_CEC_REC_WRD_CNT_SHIFT); - -@@ -1696,11 +1823,12 @@ static void vc4_cec_read_msg(struct vc4_ - } - } - --static irqreturn_t vc4_cec_irq_handler_tx_bare(int irq, void *priv) -+static irqreturn_t vc4_cec_irq_handler_tx_bare_locked(struct vc4_hdmi *vc4_hdmi) - { -- struct vc4_hdmi *vc4_hdmi = priv; - u32 cntrl1; - -+ lockdep_assert_held(&vc4_hdmi->hw_lock); -+ - cntrl1 = HDMI_READ(HDMI_CEC_CNTRL_1); - vc4_hdmi->cec_tx_ok = cntrl1 & VC4_HDMI_CEC_TX_STATUS_GOOD; - cntrl1 &= ~VC4_HDMI_CEC_START_XMIT_BEGIN; -@@ -1709,11 +1837,24 @@ static irqreturn_t vc4_cec_irq_handler_t - return IRQ_WAKE_THREAD; - } - --static irqreturn_t vc4_cec_irq_handler_rx_bare(int irq, void *priv) -+static irqreturn_t vc4_cec_irq_handler_tx_bare(int irq, void *priv) - { - struct vc4_hdmi *vc4_hdmi = priv; -+ irqreturn_t ret; -+ -+ spin_lock(&vc4_hdmi->hw_lock); -+ ret = vc4_cec_irq_handler_tx_bare_locked(vc4_hdmi); -+ spin_unlock(&vc4_hdmi->hw_lock); -+ -+ return ret; -+} -+ -+static irqreturn_t vc4_cec_irq_handler_rx_bare_locked(struct vc4_hdmi *vc4_hdmi) -+{ - u32 cntrl1; - -+ lockdep_assert_held(&vc4_hdmi->hw_lock); -+ - vc4_hdmi->cec_rx_msg.len = 0; - cntrl1 = HDMI_READ(HDMI_CEC_CNTRL_1); - vc4_cec_read_msg(vc4_hdmi, cntrl1); -@@ -1726,6 +1867,18 @@ static irqreturn_t vc4_cec_irq_handler_r - return IRQ_WAKE_THREAD; - } - -+static irqreturn_t vc4_cec_irq_handler_rx_bare(int irq, void *priv) -+{ -+ struct vc4_hdmi *vc4_hdmi = priv; -+ irqreturn_t ret; -+ -+ spin_lock(&vc4_hdmi->hw_lock); -+ ret = vc4_cec_irq_handler_rx_bare_locked(vc4_hdmi); -+ spin_unlock(&vc4_hdmi->hw_lock); -+ -+ return ret; -+} -+ - static irqreturn_t vc4_cec_irq_handler(int irq, void *priv) - { - struct vc4_hdmi *vc4_hdmi = priv; -@@ -1736,14 +1889,17 @@ static irqreturn_t vc4_cec_irq_handler(i - if (!(stat & VC4_HDMI_CPU_CEC)) - return IRQ_NONE; - -+ spin_lock(&vc4_hdmi->hw_lock); - cntrl5 = HDMI_READ(HDMI_CEC_CNTRL_5); - vc4_hdmi->cec_irq_was_rx = cntrl5 & VC4_HDMI_CEC_RX_CEC_INT; - if (vc4_hdmi->cec_irq_was_rx) -- ret = vc4_cec_irq_handler_rx_bare(irq, priv); -+ ret = vc4_cec_irq_handler_rx_bare_locked(vc4_hdmi); - else -- ret = vc4_cec_irq_handler_tx_bare(irq, priv); -+ ret = vc4_cec_irq_handler_tx_bare_locked(vc4_hdmi); - - HDMI_WRITE(HDMI_CEC_CPU_CLEAR, VC4_HDMI_CPU_CEC); -+ spin_unlock(&vc4_hdmi->hw_lock); -+ - return ret; - } - -@@ -1752,6 +1908,7 @@ static int vc4_hdmi_cec_enable(struct ce - struct vc4_hdmi *vc4_hdmi = cec_get_drvdata(adap); - /* clock period in microseconds */ - const u32 usecs = 1000000 / CEC_CLOCK_FREQ; -+ unsigned long flags; - u32 val; - int ret; - -@@ -1759,6 +1916,8 @@ static int vc4_hdmi_cec_enable(struct ce - if (ret) - return ret; - -+ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); -+ - val = HDMI_READ(HDMI_CEC_CNTRL_5); - val &= ~(VC4_HDMI_CEC_TX_SW_RESET | VC4_HDMI_CEC_RX_SW_RESET | - VC4_HDMI_CEC_CNT_TO_4700_US_MASK | -@@ -1789,12 +1948,17 @@ static int vc4_hdmi_cec_enable(struct ce - if (!vc4_hdmi->variant->external_irq_controller) - HDMI_WRITE(HDMI_CEC_CPU_MASK_CLEAR, VC4_HDMI_CPU_CEC); - -+ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); -+ - return 0; - } - - static int vc4_hdmi_cec_disable(struct cec_adapter *adap) - { - struct vc4_hdmi *vc4_hdmi = cec_get_drvdata(adap); -+ unsigned long flags; -+ -+ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); - - if (!vc4_hdmi->variant->external_irq_controller) - HDMI_WRITE(HDMI_CEC_CPU_MASK_SET, VC4_HDMI_CPU_CEC); -@@ -1802,6 +1966,8 @@ static int vc4_hdmi_cec_disable(struct c - HDMI_WRITE(HDMI_CEC_CNTRL_5, HDMI_READ(HDMI_CEC_CNTRL_5) | - VC4_HDMI_CEC_TX_SW_RESET | VC4_HDMI_CEC_RX_SW_RESET); - -+ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); -+ - pm_runtime_put(&vc4_hdmi->pdev->dev); - - return 0; -@@ -1818,10 +1984,14 @@ static int vc4_hdmi_cec_adap_enable(stru - static int vc4_hdmi_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr) - { - struct vc4_hdmi *vc4_hdmi = cec_get_drvdata(adap); -+ unsigned long flags; - -+ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); - HDMI_WRITE(HDMI_CEC_CNTRL_1, - (HDMI_READ(HDMI_CEC_CNTRL_1) & ~VC4_HDMI_CEC_ADDR_MASK) | - (log_addr & 0xf) << VC4_HDMI_CEC_ADDR_SHIFT); -+ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); -+ - return 0; - } - -@@ -1830,6 +2000,7 @@ static int vc4_hdmi_cec_adap_transmit(st - { - struct vc4_hdmi *vc4_hdmi = cec_get_drvdata(adap); - struct drm_device *dev = vc4_hdmi->connector.dev; -+ unsigned long flags; - u32 val; - unsigned int i; - -@@ -1838,6 +2009,8 @@ static int vc4_hdmi_cec_adap_transmit(st - return -ENOMEM; - } - -+ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); -+ - for (i = 0; i < msg->len; i += 4) - HDMI_WRITE(HDMI_CEC_TX_DATA_1 + (i >> 2), - (msg->msg[i]) | -@@ -1853,6 +2026,9 @@ static int vc4_hdmi_cec_adap_transmit(st - val |= VC4_HDMI_CEC_START_XMIT_BEGIN; - - HDMI_WRITE(HDMI_CEC_CNTRL_1, val); -+ -+ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); -+ - return 0; - } - -@@ -1867,6 +2043,7 @@ static int vc4_hdmi_cec_init(struct vc4_ - struct cec_connector_info conn_info; - struct platform_device *pdev = vc4_hdmi->pdev; - struct device *dev = &pdev->dev; -+ unsigned long flags; - u32 value; - int ret; - -@@ -1887,10 +2064,12 @@ static int vc4_hdmi_cec_init(struct vc4_ - cec_fill_conn_info_from_drm(&conn_info, &vc4_hdmi->connector); - cec_s_conn_info(vc4_hdmi->cec_adap, &conn_info); - -+ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); - value = HDMI_READ(HDMI_CEC_CNTRL_1); - /* Set the logical address to Unregistered */ - value |= VC4_HDMI_CEC_ADDR_MASK; - HDMI_WRITE(HDMI_CEC_CNTRL_1, value); -+ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); - - vc4_hdmi_cec_update_clk_div(vc4_hdmi); - -@@ -1909,7 +2088,9 @@ static int vc4_hdmi_cec_init(struct vc4_ - if (ret) - goto err_remove_cec_rx_handler; - } else { -+ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); - HDMI_WRITE(HDMI_CEC_CPU_MASK_SET, 0xffffffff); -+ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); - - ret = request_threaded_irq(platform_get_irq(pdev, 0), - vc4_cec_irq_handler, -@@ -2179,6 +2360,7 @@ static int vc4_hdmi_bind(struct device * - vc4_hdmi = devm_kzalloc(dev, sizeof(*vc4_hdmi), GFP_KERNEL); - if (!vc4_hdmi) - return -ENOMEM; -+ spin_lock_init(&vc4_hdmi->hw_lock); - INIT_DELAYED_WORK(&vc4_hdmi->scrambling_work, vc4_hdmi_scrambling_wq); - - dev_set_drvdata(dev, vc4_hdmi); ---- a/drivers/gpu/drm/vc4/vc4_hdmi.h -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.h -@@ -179,6 +179,11 @@ struct vc4_hdmi { - - struct debugfs_regset32 hdmi_regset; - struct debugfs_regset32 hd_regset; -+ -+ /** -+ * @hw_lock: Spinlock protecting device register access. -+ */ -+ spinlock_t hw_lock; - }; - - static inline struct vc4_hdmi * ---- a/drivers/gpu/drm/vc4/vc4_hdmi_phy.c -+++ b/drivers/gpu/drm/vc4/vc4_hdmi_phy.c -@@ -130,31 +130,49 @@ - void vc4_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi, - struct vc4_hdmi_connector_state *conn_state) - { -+ unsigned long flags; -+ - /* PHY should be in reset, like - * vc4_hdmi_encoder_disable() does. - */ - -+ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); -+ - HDMI_WRITE(HDMI_TX_PHY_RESET_CTL, 0xf << 16); - HDMI_WRITE(HDMI_TX_PHY_RESET_CTL, 0); -+ -+ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); - } - - void vc4_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi) - { -+ unsigned long flags; -+ -+ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); - HDMI_WRITE(HDMI_TX_PHY_RESET_CTL, 0xf << 16); -+ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); - } - - void vc4_hdmi_phy_rng_enable(struct vc4_hdmi *vc4_hdmi) - { -+ unsigned long flags; -+ -+ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); - HDMI_WRITE(HDMI_TX_PHY_CTL_0, - HDMI_READ(HDMI_TX_PHY_CTL_0) & - ~VC4_HDMI_TX_PHY_RNG_PWRDN); -+ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); - } - - void vc4_hdmi_phy_rng_disable(struct vc4_hdmi *vc4_hdmi) - { -+ unsigned long flags; -+ -+ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); - HDMI_WRITE(HDMI_TX_PHY_CTL_0, - HDMI_READ(HDMI_TX_PHY_CTL_0) | - VC4_HDMI_TX_PHY_RNG_PWRDN); -+ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); - } - - static unsigned long long -@@ -336,6 +354,8 @@ phy_get_channel_settings(enum vc4_hdmi_p - - static void vc5_hdmi_reset_phy(struct vc4_hdmi *vc4_hdmi) - { -+ lockdep_assert_held(&vc4_hdmi->hw_lock); -+ - HDMI_WRITE(HDMI_TX_PHY_RESET_CTL, 0x0f); - HDMI_WRITE(HDMI_TX_PHY_POWERDOWN_CTL, BIT(10)); - } -@@ -348,10 +368,13 @@ void vc5_hdmi_phy_init(struct vc4_hdmi * - unsigned long long pixel_freq = conn_state->pixel_rate; - unsigned long long vco_freq; - unsigned char word_sel; -+ unsigned long flags; - u8 vco_sel, vco_div; - - vco_freq = phy_get_vco_freq(pixel_freq, &vco_sel, &vco_div); - -+ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); -+ - vc5_hdmi_reset_phy(vc4_hdmi); - - HDMI_WRITE(HDMI_TX_PHY_POWERDOWN_CTL, -@@ -501,23 +524,37 @@ void vc5_hdmi_phy_init(struct vc4_hdmi * - HDMI_READ(HDMI_TX_PHY_RESET_CTL) | - VC4_HDMI_TX_PHY_RESET_CTL_PLL_RESETB | - VC4_HDMI_TX_PHY_RESET_CTL_PLLDIV_RESETB); -+ -+ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); - } - - void vc5_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi) - { -+ unsigned long flags; -+ -+ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); - vc5_hdmi_reset_phy(vc4_hdmi); -+ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); - } - - void vc5_hdmi_phy_rng_enable(struct vc4_hdmi *vc4_hdmi) - { -+ unsigned long flags; -+ -+ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); - HDMI_WRITE(HDMI_TX_PHY_POWERDOWN_CTL, - HDMI_READ(HDMI_TX_PHY_POWERDOWN_CTL) & - ~VC4_HDMI_TX_PHY_POWERDOWN_CTL_RNDGEN_PWRDN); -+ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); - } - - void vc5_hdmi_phy_rng_disable(struct vc4_hdmi *vc4_hdmi) - { -+ unsigned long flags; -+ -+ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); - HDMI_WRITE(HDMI_TX_PHY_POWERDOWN_CTL, - HDMI_READ(HDMI_TX_PHY_POWERDOWN_CTL) | - VC4_HDMI_TX_PHY_POWERDOWN_CTL_RNDGEN_PWRDN); -+ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); - } ---- a/drivers/gpu/drm/vc4/vc4_hdmi_regs.h -+++ b/drivers/gpu/drm/vc4/vc4_hdmi_regs.h -@@ -445,6 +445,8 @@ static inline void vc4_hdmi_write(struct - const struct vc4_hdmi_variant *variant = hdmi->variant; - void __iomem *base; - -+ lockdep_assert_held(&hdmi->hw_lock); -+ - WARN_ON(!pm_runtime_active(&hdmi->pdev->dev)); - - if (reg >= variant->num_registers) { diff --git a/target/linux/bcm27xx/patches-5.15/950-0008-drm-vc4-hdmi-Use-a-mutex-to-prevent-concurrent-frame.patch b/target/linux/bcm27xx/patches-5.15/950-0008-drm-vc4-hdmi-Use-a-mutex-to-prevent-concurrent-frame.patch deleted file mode 100644 index 49470cdb4..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0008-drm-vc4-hdmi-Use-a-mutex-to-prevent-concurrent-frame.patch +++ /dev/null @@ -1,444 +0,0 @@ -From 5976ef1d81c8d474eddb55103f29a686f84f22f1 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Mon, 25 Oct 2021 16:11:09 +0200 -Subject: [PATCH] drm/vc4: hdmi: Use a mutex to prevent concurrent - framework access - -The vc4 HDMI controller registers into the KMS, CEC and ALSA -frameworks. - -However, no particular care is done to prevent the concurrent execution -of different framework hooks from happening at the same time. - -In order to protect against that scenario, let's introduce a mutex that -relevant ALSA and KMS hooks will need to take to prevent concurrent -execution. - -CEC is left out at the moment though, since the .get_modes and .detect -KMS hooks, when running cec_s_phys_addr_from_edid, can end up calling -CEC's .adap_enable hook. This introduces some reentrancy that isn't easy -to deal with properly. - -The CEC hooks also don't share much state with the rest of the driver: -the registers are entirely separate, we don't share any variable, the -only thing that can conflict is the CEC clock divider setup that can be -affected by a mode set. - -However, after discussing it, it looks like CEC should be able to -recover from this if it was to happen. - -Link: https://lore.kernel.org/r/20211025141113.702757-6-maxime@cerno.tech -Fixes: bb7d78568814 ("drm/vc4: Add HDMI audio support") -Acked-by: Daniel Vetter -Signed-off-by: Maxime Ripard ---- - drivers/gpu/drm/vc4/vc4_hdmi.c | 118 +++++++++++++++++++++++++++++++-- - drivers/gpu/drm/vc4/vc4_hdmi.h | 14 ++++ - 2 files changed, 126 insertions(+), 6 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_hdmi.c -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c -@@ -192,6 +192,8 @@ vc4_hdmi_connector_detect(struct drm_con - struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector); - bool connected = false; - -+ mutex_lock(&vc4_hdmi->mutex); -+ - WARN_ON(pm_runtime_resume_and_get(&vc4_hdmi->pdev->dev)); - - if (vc4_hdmi->hpd_gpio) { -@@ -222,11 +224,13 @@ vc4_hdmi_connector_detect(struct drm_con - - vc4_hdmi_enable_scrambling(&vc4_hdmi->encoder.base.base); - pm_runtime_put(&vc4_hdmi->pdev->dev); -+ mutex_unlock(&vc4_hdmi->mutex); - return connector_status_connected; - } - - cec_phys_addr_invalidate(vc4_hdmi->cec_adap); - pm_runtime_put(&vc4_hdmi->pdev->dev); -+ mutex_unlock(&vc4_hdmi->mutex); - return connector_status_disconnected; - } - -@@ -243,10 +247,14 @@ static int vc4_hdmi_connector_get_modes( - int ret = 0; - struct edid *edid; - -+ mutex_lock(&vc4_hdmi->mutex); -+ - edid = drm_get_edid(connector, vc4_hdmi->ddc); - cec_s_phys_addr_from_edid(vc4_hdmi->cec_adap, edid); -- if (!edid) -- return -ENODEV; -+ if (!edid) { -+ ret = -ENODEV; -+ goto out; -+ } - - vc4_encoder->hdmi_monitor = drm_detect_hdmi_monitor(edid); - -@@ -266,6 +274,9 @@ static int vc4_hdmi_connector_get_modes( - } - } - -+out: -+ mutex_unlock(&vc4_hdmi->mutex); -+ - return ret; - } - -@@ -482,6 +493,8 @@ static void vc4_hdmi_set_avi_infoframe(s - union hdmi_infoframe frame; - int ret; - -+ lockdep_assert_held(&vc4_hdmi->mutex); -+ - ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, - connector, mode); - if (ret < 0) { -@@ -533,6 +546,8 @@ static void vc4_hdmi_set_hdr_infoframe(s - struct drm_connector_state *conn_state = connector->state; - union hdmi_infoframe frame; - -+ lockdep_assert_held(&vc4_hdmi->mutex); -+ - if (!vc4_hdmi->variant->supports_hdr) - return; - -@@ -549,6 +564,8 @@ static void vc4_hdmi_set_infoframes(stru - { - struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); - -+ lockdep_assert_held(&vc4_hdmi->mutex); -+ - vc4_hdmi_set_avi_infoframe(encoder); - vc4_hdmi_set_spd_infoframe(encoder); - /* -@@ -568,6 +585,8 @@ static bool vc4_hdmi_supports_scrambling - struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); - struct drm_display_info *display = &vc4_hdmi->connector.display_info; - -+ lockdep_assert_held(&vc4_hdmi->mutex); -+ - if (!vc4_encoder->hdmi_monitor) - return false; - -@@ -586,6 +605,8 @@ static void vc4_hdmi_enable_scrambling(s - struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); - unsigned long flags; - -+ lockdep_assert_held(&vc4_hdmi->mutex); -+ - if (!vc4_hdmi_supports_scrambling(encoder, mode)) - return; - -@@ -655,6 +676,8 @@ static void vc4_hdmi_encoder_post_crtc_d - struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); - unsigned long flags; - -+ mutex_lock(&vc4_hdmi->mutex); -+ - spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); - - HDMI_WRITE(HDMI_RAM_PACKET_CONFIG, 0); -@@ -671,6 +694,8 @@ static void vc4_hdmi_encoder_post_crtc_d - spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); - - vc4_hdmi_disable_scrambling(encoder); -+ -+ mutex_unlock(&vc4_hdmi->mutex); - } - - static void vc4_hdmi_encoder_post_crtc_powerdown(struct drm_encoder *encoder, -@@ -680,6 +705,8 @@ static void vc4_hdmi_encoder_post_crtc_p - unsigned long flags; - int ret; - -+ mutex_lock(&vc4_hdmi->mutex); -+ - spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); - HDMI_WRITE(HDMI_VID_CTL, - HDMI_READ(HDMI_VID_CTL) | VC4_HD_VID_CTL_BLANKPIX); -@@ -694,6 +721,8 @@ static void vc4_hdmi_encoder_post_crtc_p - ret = pm_runtime_put(&vc4_hdmi->pdev->dev); - if (ret < 0) - DRM_ERROR("Failed to release power domain: %d\n", ret); -+ -+ mutex_unlock(&vc4_hdmi->mutex); - } - - static void vc4_hdmi_encoder_disable(struct drm_encoder *encoder) -@@ -996,6 +1025,8 @@ static void vc4_hdmi_encoder_pre_crtc_co - unsigned long flags; - int ret; - -+ mutex_lock(&vc4_hdmi->mutex); -+ - /* - * As stated in RPi's vc4 firmware "HDMI state machine (HSM) clock must - * be faster than pixel clock, infinitesimally faster, tested in -@@ -1016,13 +1047,13 @@ static void vc4_hdmi_encoder_pre_crtc_co - ret = clk_set_min_rate(vc4_hdmi->hsm_clock, hsm_rate); - if (ret) { - DRM_ERROR("Failed to set HSM clock rate: %d\n", ret); -- return; -+ goto out; - } - - ret = pm_runtime_resume_and_get(&vc4_hdmi->pdev->dev); - if (ret < 0) { - DRM_ERROR("Failed to retain power domain: %d\n", ret); -- return; -+ goto out; - } - - ret = clk_set_rate(vc4_hdmi->pixel_clock, pixel_rate); -@@ -1074,13 +1105,16 @@ static void vc4_hdmi_encoder_pre_crtc_co - if (vc4_hdmi->variant->set_timings) - vc4_hdmi->variant->set_timings(vc4_hdmi, conn_state, mode); - -+ mutex_unlock(&vc4_hdmi->mutex); -+ - return; - - err_disable_pixel_clock: - clk_disable_unprepare(vc4_hdmi->pixel_clock); - err_put_runtime_pm: - pm_runtime_put(&vc4_hdmi->pdev->dev); -- -+out: -+ mutex_unlock(&vc4_hdmi->mutex); - return; - } - -@@ -1092,6 +1126,8 @@ static void vc4_hdmi_encoder_pre_crtc_en - struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); - unsigned long flags; - -+ mutex_lock(&vc4_hdmi->mutex); -+ - if (vc4_encoder->hdmi_monitor && - drm_default_rgb_quant_range(mode) == HDMI_QUANTIZATION_RANGE_LIMITED) { - if (vc4_hdmi->variant->csc_setup) -@@ -1108,6 +1144,8 @@ static void vc4_hdmi_encoder_pre_crtc_en - spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); - HDMI_WRITE(HDMI_FIFO_CTL, VC4_HDMI_FIFO_CTL_MASTER_SLAVE_N); - spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); -+ -+ mutex_unlock(&vc4_hdmi->mutex); - } - - static void vc4_hdmi_encoder_post_crtc_enable(struct drm_encoder *encoder, -@@ -1121,6 +1159,8 @@ static void vc4_hdmi_encoder_post_crtc_e - unsigned long flags; - int ret; - -+ mutex_lock(&vc4_hdmi->mutex); -+ - spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); - - HDMI_WRITE(HDMI_VID_CTL, -@@ -1180,6 +1220,8 @@ static void vc4_hdmi_encoder_post_crtc_e - - vc4_hdmi_recenter_fifo(vc4_hdmi); - vc4_hdmi_enable_scrambling(encoder); -+ -+ mutex_unlock(&vc4_hdmi->mutex); - } - - static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder) -@@ -1323,6 +1365,7 @@ static void vc4_hdmi_set_n_cts(struct vc - u32 n, cts; - u64 tmp; - -+ lockdep_assert_held(&vc4_hdmi->mutex); - lockdep_assert_held(&vc4_hdmi->hw_lock); - - n = 128 * samplerate / 1000; -@@ -1356,13 +1399,17 @@ static int vc4_hdmi_audio_startup(struct - struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base; - unsigned long flags; - -+ mutex_lock(&vc4_hdmi->mutex); -+ - /* - * If the HDMI encoder hasn't probed, or the encoder is - * currently in DVI mode, treat the codec dai as missing. - */ - if (!encoder->crtc || !(HDMI_READ(HDMI_RAM_PACKET_CONFIG) & -- VC4_HDMI_RAM_PACKET_ENABLE)) -+ VC4_HDMI_RAM_PACKET_ENABLE)) { -+ mutex_unlock(&vc4_hdmi->mutex); - return -ENODEV; -+ } - - vc4_hdmi->audio.streaming = true; - -@@ -1378,6 +1425,8 @@ static int vc4_hdmi_audio_startup(struct - if (vc4_hdmi->variant->phy_rng_enable) - vc4_hdmi->variant->phy_rng_enable(vc4_hdmi); - -+ mutex_unlock(&vc4_hdmi->mutex); -+ - return 0; - } - -@@ -1388,6 +1437,8 @@ static void vc4_hdmi_audio_reset(struct - unsigned long flags; - int ret; - -+ lockdep_assert_held(&vc4_hdmi->mutex); -+ - vc4_hdmi->audio.streaming = false; - ret = vc4_hdmi_stop_packet(encoder, HDMI_INFOFRAME_TYPE_AUDIO, false); - if (ret) -@@ -1407,6 +1458,8 @@ static void vc4_hdmi_audio_shutdown(stru - struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev); - unsigned long flags; - -+ mutex_lock(&vc4_hdmi->mutex); -+ - spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); - - HDMI_WRITE(HDMI_MAI_CTL, -@@ -1421,6 +1474,8 @@ static void vc4_hdmi_audio_shutdown(stru - - vc4_hdmi->audio.streaming = false; - vc4_hdmi_audio_reset(vc4_hdmi); -+ -+ mutex_unlock(&vc4_hdmi->mutex); - } - - static int sample_rate_to_mai_fmt(int samplerate) -@@ -1479,6 +1534,8 @@ static int vc4_hdmi_audio_prepare(struct - dev_dbg(dev, "%s: %u Hz, %d bit, %d channels\n", __func__, - sample_rate, params->sample_width, channels); - -+ mutex_lock(&vc4_hdmi->mutex); -+ - vc4_hdmi_audio_set_mai_clock(vc4_hdmi, sample_rate); - - spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); -@@ -1533,6 +1590,8 @@ static int vc4_hdmi_audio_prepare(struct - memcpy(&vc4_hdmi->audio.infoframe, ¶ms->cea, sizeof(params->cea)); - vc4_hdmi_set_audio_infoframe(encoder); - -+ mutex_unlock(&vc4_hdmi->mutex); -+ - return 0; - } - -@@ -1575,7 +1634,9 @@ static int vc4_hdmi_audio_get_eld(struct - struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev); - struct drm_connector *connector = &vc4_hdmi->connector; - -+ mutex_lock(&vc4_hdmi->mutex); - memcpy(buf, connector->eld, min(sizeof(connector->eld), len)); -+ mutex_unlock(&vc4_hdmi->mutex); - - return 0; - } -@@ -1912,6 +1973,17 @@ static int vc4_hdmi_cec_enable(struct ce - u32 val; - int ret; - -+ /* -+ * NOTE: This function should really take vc4_hdmi->mutex, but doing so -+ * results in a reentrancy since cec_s_phys_addr_from_edid() called in -+ * .detect or .get_modes might call .adap_enable, which leads to this -+ * function being called with that mutex held. -+ * -+ * Concurrency is not an issue for the moment since we don't share any -+ * state with KMS, so we can ignore the lock for now, but we need to -+ * keep it in mind if we were to change that assumption. -+ */ -+ - ret = pm_runtime_resume_and_get(&vc4_hdmi->pdev->dev); - if (ret) - return ret; -@@ -1958,6 +2030,17 @@ static int vc4_hdmi_cec_disable(struct c - struct vc4_hdmi *vc4_hdmi = cec_get_drvdata(adap); - unsigned long flags; - -+ /* -+ * NOTE: This function should really take vc4_hdmi->mutex, but doing so -+ * results in a reentrancy since cec_s_phys_addr_from_edid() called in -+ * .detect or .get_modes might call .adap_enable, which leads to this -+ * function being called with that mutex held. -+ * -+ * Concurrency is not an issue for the moment since we don't share any -+ * state with KMS, so we can ignore the lock for now, but we need to -+ * keep it in mind if we were to change that assumption. -+ */ -+ - spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); - - if (!vc4_hdmi->variant->external_irq_controller) -@@ -1986,6 +2069,17 @@ static int vc4_hdmi_cec_adap_log_addr(st - struct vc4_hdmi *vc4_hdmi = cec_get_drvdata(adap); - unsigned long flags; - -+ /* -+ * NOTE: This function should really take vc4_hdmi->mutex, but doing so -+ * results in a reentrancy since cec_s_phys_addr_from_edid() called in -+ * .detect or .get_modes might call .adap_enable, which leads to this -+ * function being called with that mutex held. -+ * -+ * Concurrency is not an issue for the moment since we don't share any -+ * state with KMS, so we can ignore the lock for now, but we need to -+ * keep it in mind if we were to change that assumption. -+ */ -+ - spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); - HDMI_WRITE(HDMI_CEC_CNTRL_1, - (HDMI_READ(HDMI_CEC_CNTRL_1) & ~VC4_HDMI_CEC_ADDR_MASK) | -@@ -2004,6 +2098,17 @@ static int vc4_hdmi_cec_adap_transmit(st - u32 val; - unsigned int i; - -+ /* -+ * NOTE: This function should really take vc4_hdmi->mutex, but doing so -+ * results in a reentrancy since cec_s_phys_addr_from_edid() called in -+ * .detect or .get_modes might call .adap_enable, which leads to this -+ * function being called with that mutex held. -+ * -+ * Concurrency is not an issue for the moment since we don't share any -+ * state with KMS, so we can ignore the lock for now, but we need to -+ * keep it in mind if we were to change that assumption. -+ */ -+ - if (msg->len > 16) { - drm_err(dev, "Attempting to transmit too much data (%d)\n", msg->len); - return -ENOMEM; -@@ -2360,6 +2465,7 @@ static int vc4_hdmi_bind(struct device * - vc4_hdmi = devm_kzalloc(dev, sizeof(*vc4_hdmi), GFP_KERNEL); - if (!vc4_hdmi) - return -ENOMEM; -+ mutex_init(&vc4_hdmi->mutex); - spin_lock_init(&vc4_hdmi->hw_lock); - INIT_DELAYED_WORK(&vc4_hdmi->scrambling_work, vc4_hdmi_scrambling_wq); - ---- a/drivers/gpu/drm/vc4/vc4_hdmi.h -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.h -@@ -184,6 +184,20 @@ struct vc4_hdmi { - * @hw_lock: Spinlock protecting device register access. - */ - spinlock_t hw_lock; -+ -+ /** -+ * @mutex: Mutex protecting the driver access across multiple -+ * frameworks (KMS, ALSA). -+ * -+ * NOTE: While supported, CEC has been left out since -+ * cec_s_phys_addr_from_edid() might call .adap_enable and lead to a -+ * reentrancy issue between .get_modes (or .detect) and .adap_enable. -+ * Since we don't share any state between the CEC hooks and KMS', it's -+ * not a big deal. The only trouble might come from updating the CEC -+ * clock divider which might be affected by a modeset, but CEC should -+ * be resilient to that. -+ */ -+ struct mutex mutex; - }; - - static inline struct vc4_hdmi * diff --git a/target/linux/bcm27xx/patches-5.15/950-0009-drm-vc4-hdmi-Prevent-access-to-crtc-state-outside-of.patch b/target/linux/bcm27xx/patches-5.15/950-0009-drm-vc4-hdmi-Prevent-access-to-crtc-state-outside-of.patch deleted file mode 100644 index c298d2cde..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0009-drm-vc4-hdmi-Prevent-access-to-crtc-state-outside-of.patch +++ /dev/null @@ -1,161 +0,0 @@ -From d6ecbdcba5174488d403ccddc016721243eb1797 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Tue, 19 Oct 2021 14:19:29 +0200 -Subject: [PATCH] drm/vc4: hdmi: Prevent access to crtc->state outside - of KMS - -Accessing the crtc->state pointer from outside the modesetting context -is not allowed. We thus need to copy whatever we need from the KMS state -to our structure in order to access it. - -However, in the vc4 HDMI driver we do use that pointer in the ALSA code -path, and potentially in the hotplug interrupt handler path. - -These paths both need access to the CRTC adjusted mode in order for the -proper dividers to be set for ALSA, and the scrambler state to be -reinstated properly for hotplug. - -Let's copy this mode into our private encoder structure and reference it -from there when needed. Since that part is shared between KMS and other -paths, we need to protect it using our mutex. - -Link: https://lore.kernel.org/all/YWgteNaNeaS9uWDe@phenom.ffwll.local/ -Fixes: bb7d78568814 ("drm/vc4: Add HDMI audio support") -Signed-off-by: Maxime Ripard ---- - drivers/gpu/drm/vc4/vc4_hdmi.c | 38 +++++++++++++++++++++++----------- - drivers/gpu/drm/vc4/vc4_hdmi.h | 6 ++++++ - 2 files changed, 32 insertions(+), 12 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_hdmi.c -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c -@@ -488,8 +488,7 @@ static void vc4_hdmi_set_avi_infoframe(s - struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder); - struct drm_connector *connector = &vc4_hdmi->connector; - struct drm_connector_state *cstate = connector->state; -- struct drm_crtc *crtc = encoder->crtc; -- const struct drm_display_mode *mode = &crtc->state->adjusted_mode; -+ const struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode; - union hdmi_infoframe frame; - int ret; - -@@ -601,8 +600,8 @@ static bool vc4_hdmi_supports_scrambling - - static void vc4_hdmi_enable_scrambling(struct drm_encoder *encoder) - { -- struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode; - struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); -+ struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode; - unsigned long flags; - - lockdep_assert_held(&vc4_hdmi->mutex); -@@ -628,18 +627,21 @@ static void vc4_hdmi_enable_scrambling(s - static void vc4_hdmi_disable_scrambling(struct drm_encoder *encoder) - { - struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); -+ struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode; - struct drm_crtc *crtc = encoder->crtc; - unsigned long flags; - -+ lockdep_assert_held(&vc4_hdmi->mutex); -+ - /* - * At boot, encoder->crtc will be NULL. Since we don't know the - * state of the scrambler and in order to avoid any - * inconsistency, let's disable it all the time. - */ -- if (crtc && !vc4_hdmi_supports_scrambling(encoder, &crtc->mode)) -+ if (crtc && !vc4_hdmi_supports_scrambling(encoder, mode)) - return; - -- if (crtc && !vc4_hdmi_mode_needs_scrambling(&crtc->mode)) -+ if (crtc && !vc4_hdmi_mode_needs_scrambling(mode)) - return; - - if (delayed_work_pending(&vc4_hdmi->scrambling_work)) -@@ -1018,8 +1020,8 @@ static void vc4_hdmi_encoder_pre_crtc_co - vc4_hdmi_encoder_get_connector_state(encoder, state); - struct vc4_hdmi_connector_state *vc4_conn_state = - conn_state_to_vc4_hdmi_conn_state(conn_state); -- struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode; - struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); -+ struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode; - unsigned long pixel_rate = vc4_conn_state->pixel_rate; - unsigned long bvb_rate, hsm_rate; - unsigned long flags; -@@ -1121,9 +1123,9 @@ out: - static void vc4_hdmi_encoder_pre_crtc_enable(struct drm_encoder *encoder, - struct drm_atomic_state *state) - { -- struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode; -- struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder); - struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); -+ struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode; -+ struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder); - unsigned long flags; - - mutex_lock(&vc4_hdmi->mutex); -@@ -1151,8 +1153,8 @@ static void vc4_hdmi_encoder_pre_crtc_en - static void vc4_hdmi_encoder_post_crtc_enable(struct drm_encoder *encoder, - struct drm_atomic_state *state) - { -- struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode; - struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); -+ struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode; - struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder); - bool hsync_pos = mode->flags & DRM_MODE_FLAG_PHSYNC; - bool vsync_pos = mode->flags & DRM_MODE_FLAG_PVSYNC; -@@ -1228,6 +1230,19 @@ static void vc4_hdmi_encoder_enable(stru - { - } - -+static void vc4_hdmi_encoder_atomic_mode_set(struct drm_encoder *encoder, -+ struct drm_crtc_state *crtc_state, -+ struct drm_connector_state *conn_state) -+{ -+ struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); -+ -+ mutex_lock(&vc4_hdmi->mutex); -+ memcpy(&vc4_hdmi->saved_adjusted_mode, -+ &crtc_state->adjusted_mode, -+ sizeof(vc4_hdmi->saved_adjusted_mode)); -+ mutex_unlock(&vc4_hdmi->mutex); -+} -+ - #define WIFI_2_4GHz_CH1_MIN_FREQ 2400000000ULL - #define WIFI_2_4GHz_CH1_MAX_FREQ 2422000000ULL - -@@ -1306,6 +1321,7 @@ vc4_hdmi_encoder_mode_valid(struct drm_e - - static const struct drm_encoder_helper_funcs vc4_hdmi_encoder_helper_funcs = { - .atomic_check = vc4_hdmi_encoder_atomic_check, -+ .atomic_mode_set = vc4_hdmi_encoder_atomic_mode_set, - .mode_valid = vc4_hdmi_encoder_mode_valid, - .disable = vc4_hdmi_encoder_disable, - .enable = vc4_hdmi_encoder_enable, -@@ -1359,9 +1375,7 @@ static void vc4_hdmi_audio_set_mai_clock - - static void vc4_hdmi_set_n_cts(struct vc4_hdmi *vc4_hdmi, unsigned int samplerate) - { -- struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base; -- struct drm_crtc *crtc = encoder->crtc; -- const struct drm_display_mode *mode = &crtc->state->adjusted_mode; -+ const struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode; - u32 n, cts; - u64 tmp; - ---- a/drivers/gpu/drm/vc4/vc4_hdmi.h -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.h -@@ -198,6 +198,12 @@ struct vc4_hdmi { - * be resilient to that. - */ - struct mutex mutex; -+ -+ /** -+ * @saved_adjusted_mode: Copy of @drm_crtc_state.adjusted_mode -+ * for use by ALSA hooks and interrupt handlers. Protected by @mutex. -+ */ -+ struct drm_display_mode saved_adjusted_mode; - }; - - static inline struct vc4_hdmi * diff --git a/target/linux/bcm27xx/patches-5.15/950-0010-drm-vc4-hdmi-Check-the-device-state-in-prepare.patch b/target/linux/bcm27xx/patches-5.15/950-0010-drm-vc4-hdmi-Check-the-device-state-in-prepare.patch deleted file mode 100644 index 31243f810..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0010-drm-vc4-hdmi-Check-the-device-state-in-prepare.patch +++ /dev/null @@ -1,77 +0,0 @@ -From ba0375640d2d82158600a398181bb9f9c3835d0a Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Fri, 24 Sep 2021 14:27:38 +0200 -Subject: [PATCH] drm/vc4: hdmi: Check the device state in prepare() - -Even though we already check that the encoder->crtc pointer is there -during in startup(), which is part of the open() path in ASoC, nothing -guarantees that our encoder state won't change between the time when we -open the device and the time we prepare it. - -Move the sanity checks we do in startup() to a helper and call it from -prepare(). - -Fixes: 91e99e113929 ("drm/vc4: hdmi: Register HDMI codec") -Signed-off-by: Maxime Ripard ---- - drivers/gpu/drm/vc4/vc4_hdmi.c | 35 +++++++++++++++++++++++++++------- - 1 file changed, 28 insertions(+), 7 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_hdmi.c -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c -@@ -1407,20 +1407,36 @@ static inline struct vc4_hdmi *dai_to_hd - return snd_soc_card_get_drvdata(card); - } - -+static bool vc4_hdmi_audio_can_stream(struct vc4_hdmi *vc4_hdmi) -+{ -+ struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base; -+ -+ lockdep_assert_held(&vc4_hdmi->mutex); -+ -+ /* -+ * The encoder doesn't have a CRTC until the first modeset. -+ */ -+ if (!encoder->crtc) -+ return false; -+ -+ /* -+ * If the encoder is currently in DVI mode, treat the codec DAI -+ * as missing. -+ */ -+ if (!(HDMI_READ(HDMI_RAM_PACKET_CONFIG) & VC4_HDMI_RAM_PACKET_ENABLE)) -+ return false; -+ -+ return true; -+} -+ - static int vc4_hdmi_audio_startup(struct device *dev, void *data) - { - struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev); -- struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base; - unsigned long flags; - - mutex_lock(&vc4_hdmi->mutex); - -- /* -- * If the HDMI encoder hasn't probed, or the encoder is -- * currently in DVI mode, treat the codec dai as missing. -- */ -- if (!encoder->crtc || !(HDMI_READ(HDMI_RAM_PACKET_CONFIG) & -- VC4_HDMI_RAM_PACKET_ENABLE)) { -+ if (!vc4_hdmi_audio_can_stream(vc4_hdmi)) { - mutex_unlock(&vc4_hdmi->mutex); - return -ENODEV; - } -@@ -1550,6 +1566,11 @@ static int vc4_hdmi_audio_prepare(struct - - mutex_lock(&vc4_hdmi->mutex); - -+ if (!vc4_hdmi_audio_can_stream(vc4_hdmi)) { -+ mutex_unlock(&vc4_hdmi->mutex); -+ return -EINVAL; -+ } -+ - vc4_hdmi_audio_set_mai_clock(vc4_hdmi, sample_rate); - - spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); diff --git a/target/linux/bcm27xx/patches-5.15/950-0011-drm-vc4-hdmi-Introduce-an-output_enabled-flag.patch b/target/linux/bcm27xx/patches-5.15/950-0011-drm-vc4-hdmi-Introduce-an-output_enabled-flag.patch deleted file mode 100644 index 326fd7526..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0011-drm-vc4-hdmi-Introduce-an-output_enabled-flag.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 02631cb4e30d7bc46f2b30657a84ddeb65831798 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Tue, 19 Oct 2021 17:31:58 +0200 -Subject: [PATCH] drm/vc4: hdmi: Introduce an output_enabled flag - -We currently poke at encoder->crtc in the ALSA code path to determine -whether the HDMI output is enabled or not, and thus whether we should -allow the audio output. - -However, that pointer is deprecated and shouldn't really be used by -atomic drivers anymore. Since we have the infrastructure in place now, -let's just create a flag that we toggle to report whether the controller -is currently enabled and use that instead of encoder->crtc in ALSA. - -Signed-off-by: Maxime Ripard ---- - drivers/gpu/drm/vc4/vc4_hdmi.c | 16 ++++++++++++---- - drivers/gpu/drm/vc4/vc4_hdmi.h | 6 ++++++ - 2 files changed, 18 insertions(+), 4 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_hdmi.c -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c -@@ -729,6 +729,11 @@ static void vc4_hdmi_encoder_post_crtc_p - - static void vc4_hdmi_encoder_disable(struct drm_encoder *encoder) - { -+ struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); -+ -+ mutex_lock(&vc4_hdmi->mutex); -+ vc4_hdmi->output_enabled = false; -+ mutex_unlock(&vc4_hdmi->mutex); - } - - static void vc4_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, bool enable) -@@ -1228,6 +1233,11 @@ static void vc4_hdmi_encoder_post_crtc_e - - static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder) - { -+ struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); -+ -+ mutex_lock(&vc4_hdmi->mutex); -+ vc4_hdmi->output_enabled = true; -+ mutex_unlock(&vc4_hdmi->mutex); - } - - static void vc4_hdmi_encoder_atomic_mode_set(struct drm_encoder *encoder, -@@ -1409,14 +1419,12 @@ static inline struct vc4_hdmi *dai_to_hd - - static bool vc4_hdmi_audio_can_stream(struct vc4_hdmi *vc4_hdmi) - { -- struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base; -- - lockdep_assert_held(&vc4_hdmi->mutex); - - /* -- * The encoder doesn't have a CRTC until the first modeset. -+ * If the controller is disabled, prevent any ALSA output. - */ -- if (!encoder->crtc) -+ if (!vc4_hdmi->output_enabled) - return false; - - /* ---- a/drivers/gpu/drm/vc4/vc4_hdmi.h -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.h -@@ -204,6 +204,12 @@ struct vc4_hdmi { - * for use by ALSA hooks and interrupt handlers. Protected by @mutex. - */ - struct drm_display_mode saved_adjusted_mode; -+ -+ /** -+ * @output_enabled: Is the HDMI controller currently active? -+ * Protected by @mutex. -+ */ -+ bool output_enabled; - }; - - static inline struct vc4_hdmi * diff --git a/target/linux/bcm27xx/patches-5.15/950-0012-drm-vc4-hdmi-Introduce-a-scdc_enabled-flag.patch b/target/linux/bcm27xx/patches-5.15/950-0012-drm-vc4-hdmi-Introduce-a-scdc_enabled-flag.patch deleted file mode 100644 index 2a7ac223a..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0012-drm-vc4-hdmi-Introduce-a-scdc_enabled-flag.patch +++ /dev/null @@ -1,101 +0,0 @@ -From 4b98173449085326199e97a10d06cee4cce021a1 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Tue, 19 Oct 2021 19:13:46 +0200 -Subject: [PATCH] drm/vc4: hdmi: Introduce a scdc_enabled flag - -We currently rely on two functions, vc4_hdmi_supports_scrambling() and -vc4_hdmi_mode_needs_scrambling() to determine if we should enable and -disable the scrambler for any given mode. - -Since we might need to disable the controller at boot, we also always -run vc4_hdmi_disable_scrambling() and thus call those functions without -a mode yet, which in turns need to make some special casing in order for -it to work. - -Instead of duplicating the check for whether or not we need to take care -of the scrambler in both vc4_hdmi_enable_scrambling() and -vc4_hdmi_disable_scrambling(), we can do that check only when we enable -it and store whether or not it's been enabled in our private structure. - -We also need to initialize that flag at true to make sure we disable the -scrambler at boot since we can't really know its state yet. - -This allows to simplify a bit that part of the driver, and removes one -user of our copy of the CRTC adjusted mode outside of KMS (since -vc4_hdmi_disable_scrambling() might be called from the hotplug interrupt -handler). - -It also removes our last user of the legacy encoder->crtc pointer. - -Signed-off-by: Maxime Ripard ---- - drivers/gpu/drm/vc4/vc4_hdmi.c | 22 ++++++++++++---------- - drivers/gpu/drm/vc4/vc4_hdmi.h | 6 ++++++ - 2 files changed, 18 insertions(+), 10 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_hdmi.c -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c -@@ -620,6 +620,8 @@ static void vc4_hdmi_enable_scrambling(s - VC5_HDMI_SCRAMBLER_CTL_ENABLE); - spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); - -+ vc4_hdmi->scdc_enabled = true; -+ - queue_delayed_work(system_wq, &vc4_hdmi->scrambling_work, - msecs_to_jiffies(SCRAMBLING_POLLING_DELAY_MS)); - } -@@ -627,22 +629,14 @@ static void vc4_hdmi_enable_scrambling(s - static void vc4_hdmi_disable_scrambling(struct drm_encoder *encoder) - { - struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); -- struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode; -- struct drm_crtc *crtc = encoder->crtc; - unsigned long flags; - - lockdep_assert_held(&vc4_hdmi->mutex); - -- /* -- * At boot, encoder->crtc will be NULL. Since we don't know the -- * state of the scrambler and in order to avoid any -- * inconsistency, let's disable it all the time. -- */ -- if (crtc && !vc4_hdmi_supports_scrambling(encoder, mode)) -+ if (!vc4_hdmi->scdc_enabled) - return; - -- if (crtc && !vc4_hdmi_mode_needs_scrambling(mode)) -- return; -+ vc4_hdmi->scdc_enabled = false; - - if (delayed_work_pending(&vc4_hdmi->scrambling_work)) - cancel_delayed_work_sync(&vc4_hdmi->scrambling_work); -@@ -2523,6 +2517,14 @@ static int vc4_hdmi_bind(struct device * - vc4_hdmi->pdev = pdev; - vc4_hdmi->variant = variant; - -+ /* -+ * Since we don't know the state of the controller and its -+ * display (if any), let's assume it's always enabled. -+ * vc4_hdmi_disable_scrambling() will thus run at boot, make -+ * sure it's disabled, and avoid any inconsistency. -+ */ -+ vc4_hdmi->scdc_enabled = true; -+ - ret = variant->init_resources(vc4_hdmi); - if (ret) - return ret; ---- a/drivers/gpu/drm/vc4/vc4_hdmi.h -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.h -@@ -210,6 +210,12 @@ struct vc4_hdmi { - * Protected by @mutex. - */ - bool output_enabled; -+ -+ /** -+ * @scdc_enabled: Is the HDMI controller currently running with -+ * the scrambler on? Protected by @mutex. -+ */ -+ bool scdc_enabled; - }; - - static inline struct vc4_hdmi * diff --git a/target/linux/bcm27xx/patches-5.15/950-0013-drm-vc4-Make-vc4_crtc_get_encoder-public.patch b/target/linux/bcm27xx/patches-5.15/950-0013-drm-vc4-Make-vc4_crtc_get_encoder-public.patch deleted file mode 100644 index 6258f1a86..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0013-drm-vc4-Make-vc4_crtc_get_encoder-public.patch +++ /dev/null @@ -1,45 +0,0 @@ -From e83ac8f131b0f691e2a35866fa67b484c7256a49 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Wed, 26 May 2021 16:07:01 +0200 -Subject: [PATCH] drm/vc4: Make vc4_crtc_get_encoder public - -We'll need that function in vc4_kms to compute the core clock rate -requirements. - -Signed-off-by: Maxime Ripard ---- - drivers/gpu/drm/vc4/vc4_crtc.c | 8 ++++---- - drivers/gpu/drm/vc4/vc4_drv.h | 5 +++++ - 2 files changed, 9 insertions(+), 4 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_crtc.c -+++ b/drivers/gpu/drm/vc4/vc4_crtc.c -@@ -281,10 +281,10 @@ static u32 vc4_crtc_get_fifo_full_level_ - * allows drivers to push pixels to more than one encoder from the - * same CRTC. - */ --static struct drm_encoder *vc4_get_crtc_encoder(struct drm_crtc *crtc, -- struct drm_atomic_state *state, -- struct drm_connector_state *(*get_state)(struct drm_atomic_state *state, -- struct drm_connector *connector)) -+struct drm_encoder *vc4_get_crtc_encoder(struct drm_crtc *crtc, -+ struct drm_atomic_state *state, -+ struct drm_connector_state *(*get_state)(struct drm_atomic_state *state, -+ struct drm_connector *connector)) - { - struct drm_connector *connector; - struct drm_connector_list_iter conn_iter; ---- a/drivers/gpu/drm/vc4/vc4_drv.h -+++ b/drivers/gpu/drm/vc4/vc4_drv.h -@@ -544,6 +544,11 @@ vc4_crtc_to_vc4_pv_data(const struct vc4 - return container_of(data, struct vc4_pv_data, base); - } - -+struct drm_encoder *vc4_get_crtc_encoder(struct drm_crtc *crtc, -+ struct drm_atomic_state *state, -+ struct drm_connector_state *(*get_state)(struct drm_atomic_state *state, -+ struct drm_connector *connector)); -+ - struct vc4_crtc_state { - struct drm_crtc_state base; - /* Dlist area for this CRTC configuration. */ diff --git a/target/linux/bcm27xx/patches-5.15/950-0014-drm-vc4-crtc-Add-encoder-to-vc4_crtc_config_pv-proto.patch b/target/linux/bcm27xx/patches-5.15/950-0014-drm-vc4-crtc-Add-encoder-to-vc4_crtc_config_pv-proto.patch deleted file mode 100644 index 060b7659d..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0014-drm-vc4-crtc-Add-encoder-to-vc4_crtc_config_pv-proto.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 28f071bd81de9d9026587c9fe7a6f9c3781a30cf Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Mon, 14 Jun 2021 15:27:24 +0200 -Subject: [PATCH] drm/vc4: crtc: Add encoder to vc4_crtc_config_pv - prototype - -vc4_crtc_config_pv() retrieves the encoder again, even though its only -caller, vc4_crtc_atomic_enable(), already did. - -Pass the encoder pointer as an argument instead of going through all the -connectors to retrieve it again. - -Signed-off-by: Maxime Ripard ---- - drivers/gpu/drm/vc4/vc4_crtc.c | 7 +++---- - 1 file changed, 3 insertions(+), 4 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_crtc.c -+++ b/drivers/gpu/drm/vc4/vc4_crtc.c -@@ -315,12 +315,11 @@ static void vc4_crtc_pixelvalve_reset(st - CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) | PV_CONTROL_FIFO_CLR); - } - --static void vc4_crtc_config_pv(struct drm_crtc *crtc, struct drm_atomic_state *state) -+static void vc4_crtc_config_pv(struct drm_crtc *crtc, struct drm_encoder *encoder, -+ struct drm_atomic_state *state) - { - struct drm_device *dev = crtc->dev; - struct vc4_dev *vc4 = to_vc4_dev(dev); -- struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc, state, -- drm_atomic_get_new_connector_state); - struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder); - struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); - const struct vc4_pv_data *pv_data = vc4_crtc_to_vc4_pv_data(vc4_crtc); -@@ -601,7 +600,7 @@ static void vc4_crtc_atomic_enable(struc - if (vc4_encoder->pre_crtc_configure) - vc4_encoder->pre_crtc_configure(encoder, state); - -- vc4_crtc_config_pv(crtc, state); -+ vc4_crtc_config_pv(crtc, encoder, state); - - CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) | PV_CONTROL_EN); - diff --git a/target/linux/bcm27xx/patches-5.15/950-0015-drm-vc4-crtc-Rework-the-encoder-retrieval-code-again.patch b/target/linux/bcm27xx/patches-5.15/950-0015-drm-vc4-crtc-Rework-the-encoder-retrieval-code-again.patch deleted file mode 100644 index 5d8f0835a..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0015-drm-vc4-crtc-Rework-the-encoder-retrieval-code-again.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 0496e855a6e1acd60d4ae2e52ee906a4cffae014 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Mon, 21 Jun 2021 16:07:22 +0200 -Subject: [PATCH] drm/vc4: crtc: Rework the encoder retrieval code - (again) - -It turns out the encoder retrieval code, in addition to being -unnecessarily complicated, has a bug when only the planes and crtcs are -affected by a given atomic commit. - -Indeed, in such a case, either drm_atomic_get_old_connector_state or -drm_atomic_get_new_connector_state will return NULL and thus our encoder -retrieval code will not match on anything. - -We can however simplify the code by using drm_for_each_encoder_mask, the -drm_crtc_state storing the encoders a given CRTC is connected to -directly and without relying on any other state. - -Signed-off-by: Maxime Ripard ---- - drivers/gpu/drm/vc4/vc4_crtc.c | 30 +++++++++--------------------- - drivers/gpu/drm/vc4/vc4_drv.h | 4 +--- - 2 files changed, 10 insertions(+), 24 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_crtc.c -+++ b/drivers/gpu/drm/vc4/vc4_crtc.c -@@ -282,26 +282,14 @@ static u32 vc4_crtc_get_fifo_full_level_ - * same CRTC. - */ - struct drm_encoder *vc4_get_crtc_encoder(struct drm_crtc *crtc, -- struct drm_atomic_state *state, -- struct drm_connector_state *(*get_state)(struct drm_atomic_state *state, -- struct drm_connector *connector)) -+ struct drm_crtc_state *state) - { -- struct drm_connector *connector; -- struct drm_connector_list_iter conn_iter; -+ struct drm_encoder *encoder; - -- drm_connector_list_iter_begin(crtc->dev, &conn_iter); -- drm_for_each_connector_iter(connector, &conn_iter) { -- struct drm_connector_state *conn_state = get_state(state, connector); -- -- if (!conn_state) -- continue; -- -- if (conn_state->crtc == crtc) { -- drm_connector_list_iter_end(&conn_iter); -- return connector->encoder; -- } -- } -- drm_connector_list_iter_end(&conn_iter); -+ WARN_ON(hweight32(state->encoder_mask) > 1); -+ -+ drm_for_each_encoder_mask(encoder, crtc->dev, state->encoder_mask) -+ return encoder; - - return NULL; - } -@@ -554,8 +542,7 @@ static void vc4_crtc_atomic_disable(stru - struct drm_crtc_state *old_state = drm_atomic_get_old_crtc_state(state, - crtc); - struct vc4_crtc_state *old_vc4_state = to_vc4_crtc_state(old_state); -- struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc, state, -- drm_atomic_get_old_connector_state); -+ struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc, old_state); - struct drm_device *dev = crtc->dev; - - require_hvs_enabled(dev); -@@ -582,10 +569,11 @@ static void vc4_crtc_atomic_disable(stru - static void vc4_crtc_atomic_enable(struct drm_crtc *crtc, - struct drm_atomic_state *state) - { -+ struct drm_crtc_state *new_state = drm_atomic_get_new_crtc_state(state, -+ crtc); - struct drm_device *dev = crtc->dev; - struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); -- struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc, state, -- drm_atomic_get_new_connector_state); -+ struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc, new_state); - struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder); - - require_hvs_enabled(dev); ---- a/drivers/gpu/drm/vc4/vc4_drv.h -+++ b/drivers/gpu/drm/vc4/vc4_drv.h -@@ -545,9 +545,7 @@ vc4_crtc_to_vc4_pv_data(const struct vc4 - } - - struct drm_encoder *vc4_get_crtc_encoder(struct drm_crtc *crtc, -- struct drm_atomic_state *state, -- struct drm_connector_state *(*get_state)(struct drm_atomic_state *state, -- struct drm_connector *connector)); -+ struct drm_crtc_state *state); - - struct vc4_crtc_state { - struct drm_crtc_state base; diff --git a/target/linux/bcm27xx/patches-5.15/950-0016-drm-vc4-crtc-Add-some-logging.patch b/target/linux/bcm27xx/patches-5.15/950-0016-drm-vc4-crtc-Add-some-logging.patch deleted file mode 100644 index 0b855b7c2..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0016-drm-vc4-crtc-Add-some-logging.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 28de437934da2fb9f04b0c4f5aa73553e63894e3 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Mon, 21 Jun 2021 16:13:02 +0200 -Subject: [PATCH] drm/vc4: crtc: Add some logging - -The encoder retrieval code has been a source of bugs and glitches in the -past and the crtc <-> encoder association been wrong in a number of -different ways. - -Add some logging to quickly spot issues if they occur. - -Signed-off-by: Maxime Ripard ---- - drivers/gpu/drm/vc4/vc4_crtc.c | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- a/drivers/gpu/drm/vc4/vc4_crtc.c -+++ b/drivers/gpu/drm/vc4/vc4_crtc.c -@@ -545,6 +545,9 @@ static void vc4_crtc_atomic_disable(stru - struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc, old_state); - struct drm_device *dev = crtc->dev; - -+ drm_dbg(dev, "Disabling CRTC %s (%u) connected to Encoder %s (%u)", -+ crtc->name, crtc->base.id, encoder->name, encoder->base.id); -+ - require_hvs_enabled(dev); - - /* Disable vblank irq handling before crtc is disabled. */ -@@ -576,6 +579,9 @@ static void vc4_crtc_atomic_enable(struc - struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc, new_state); - struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder); - -+ drm_dbg(dev, "Enabling CRTC %s (%u) connected to Encoder %s (%u)", -+ crtc->name, crtc->base.id, encoder->name, encoder->base.id); -+ - require_hvs_enabled(dev); - - /* Enable vblank irq handling before crtc is started otherwise diff --git a/target/linux/bcm27xx/patches-5.15/950-0017-drm-vc4-Leverage-the-load-tracker-on-the-BCM2711.patch b/target/linux/bcm27xx/patches-5.15/950-0017-drm-vc4-Leverage-the-load-tracker-on-the-BCM2711.patch deleted file mode 100644 index f13a8c73e..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0017-drm-vc4-Leverage-the-load-tracker-on-the-BCM2711.patch +++ /dev/null @@ -1,123 +0,0 @@ -From 1cc57695d3103fa93eda71bb6ba212c3e5806b4a Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Mon, 21 Jun 2021 17:19:22 +0200 -Subject: [PATCH] drm/vc4: Leverage the load tracker on the BCM2711 - -The load tracker was initially designed to report and warn about a load -too high for the HVS. To do so, it computes for each plane the impact -it's going to have on the HVS, and will warn (if it's enabled) if we go -over what the hardware can process. - -While the limits being used are a bit irrelevant to the BCM2711, the -algorithm to compute the HVS load will be one component used in order to -compute the core clock rate on the BCM2711. - -Let's remove the hooks to prevent the load tracker to do its -computation, but since we don't have the same limits, don't check them -against them, and prevent the debugfs file to enable it from being -created. - -Signed-off-by: Maxime Ripard ---- - drivers/gpu/drm/vc4/vc4_debugfs.c | 7 +++++-- - drivers/gpu/drm/vc4/vc4_drv.h | 3 --- - drivers/gpu/drm/vc4/vc4_kms.c | 16 +++++----------- - drivers/gpu/drm/vc4/vc4_plane.c | 5 ----- - 4 files changed, 10 insertions(+), 21 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_debugfs.c -+++ b/drivers/gpu/drm/vc4/vc4_debugfs.c -@@ -7,6 +7,7 @@ - #include - #include - #include -+#include - - #include "vc4_drv.h" - #include "vc4_regs.h" -@@ -26,8 +27,10 @@ vc4_debugfs_init(struct drm_minor *minor - struct vc4_dev *vc4 = to_vc4_dev(minor->dev); - struct vc4_debugfs_info_entry *entry; - -- debugfs_create_bool("hvs_load_tracker", S_IRUGO | S_IWUSR, -- minor->debugfs_root, &vc4->load_tracker_enabled); -+ if (!of_device_is_compatible(vc4->hvs->pdev->dev.of_node, -+ "brcm,bcm2711-vc5")) -+ debugfs_create_bool("hvs_load_tracker", S_IRUGO | S_IWUSR, -+ minor->debugfs_root, &vc4->load_tracker_enabled); - - list_for_each_entry(entry, &vc4->debugfs_list, link) { - drm_debugfs_create_files(&entry->info, 1, ---- a/drivers/gpu/drm/vc4/vc4_drv.h -+++ b/drivers/gpu/drm/vc4/vc4_drv.h -@@ -202,9 +202,6 @@ struct vc4_dev { - - int power_refcount; - -- /* Set to true when the load tracker is supported. */ -- bool load_tracker_available; -- - /* Set to true when the load tracker is active. */ - bool load_tracker_enabled; - ---- a/drivers/gpu/drm/vc4/vc4_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_kms.c -@@ -554,9 +554,6 @@ static int vc4_load_tracker_atomic_check - struct drm_plane *plane; - int i; - -- if (!vc4->load_tracker_available) -- return 0; -- - priv_state = drm_atomic_get_private_obj_state(state, - &vc4->load_tracker); - if (IS_ERR(priv_state)) -@@ -631,9 +628,6 @@ static void vc4_load_tracker_obj_fini(st - { - struct vc4_dev *vc4 = to_vc4_dev(dev); - -- if (!vc4->load_tracker_available) -- return; -- - drm_atomic_private_obj_fini(&vc4->load_tracker); - } - -@@ -641,9 +635,6 @@ static int vc4_load_tracker_obj_init(str - { - struct vc4_load_tracker_state *load_state; - -- if (!vc4->load_tracker_available) -- return 0; -- - load_state = kzalloc(sizeof(*load_state), GFP_KERNEL); - if (!load_state) - return -ENOMEM; -@@ -865,9 +856,12 @@ int vc4_kms_load(struct drm_device *dev) - "brcm,bcm2711-vc5"); - int ret; - -+ /* -+ * The limits enforced by the load tracker aren't relevant for -+ * the BCM2711, but the load tracker computations are used for -+ * the core clock rate calculation. -+ */ - if (!is_vc5) { -- vc4->load_tracker_available = true; -- - /* Start with the load tracker enabled. Can be - * disabled through the debugfs load_tracker file. - */ ---- a/drivers/gpu/drm/vc4/vc4_plane.c -+++ b/drivers/gpu/drm/vc4/vc4_plane.c -@@ -527,11 +527,6 @@ static void vc4_plane_calc_load(struct d - struct vc4_plane_state *vc4_state; - struct drm_crtc_state *crtc_state; - unsigned int vscale_factor; -- struct vc4_dev *vc4; -- -- vc4 = to_vc4_dev(state->plane->dev); -- if (!vc4->load_tracker_available) -- return; - - vc4_state = to_vc4_plane_state(state); - crtc_state = drm_atomic_get_existing_crtc_state(state->state, diff --git a/target/linux/bcm27xx/patches-5.15/950-0018-drm-vc4-Increase-the-core-clock-based-on-HVS-load.patch b/target/linux/bcm27xx/patches-5.15/950-0018-drm-vc4-Increase-the-core-clock-based-on-HVS-load.patch deleted file mode 100644 index 3807c0bd7..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0018-drm-vc4-Increase-the-core-clock-based-on-HVS-load.patch +++ /dev/null @@ -1,242 +0,0 @@ -From 99c821dc4cd65ff067e2dfff4a47ceb5aa61ad0c Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Wed, 26 May 2021 16:13:02 +0200 -Subject: [PATCH] drm/vc4: Increase the core clock based on HVS load - -Depending on a given HVS output (HVS to PixelValves) and input (planes -attached to a channel) load, the HVS needs for the core clock to be -raised above its boot time default. - -Failing to do so will result in a vblank timeout and a stalled display -pipeline. - -Signed-off-by: Maxime Ripard ---- - drivers/gpu/drm/vc4/vc4_crtc.c | 15 +++++ - drivers/gpu/drm/vc4/vc4_drv.h | 2 + - drivers/gpu/drm/vc4/vc4_kms.c | 112 ++++++++++++++++++++++++++++++--- - 3 files changed, 119 insertions(+), 10 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_crtc.c -+++ b/drivers/gpu/drm/vc4/vc4_crtc.c -@@ -663,12 +663,27 @@ static int vc4_crtc_atomic_check(struct - struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc_state); - struct drm_connector *conn; - struct drm_connector_state *conn_state; -+ struct drm_encoder *encoder; - int ret, i; - - ret = vc4_hvs_atomic_check(crtc, state); - if (ret) - return ret; - -+ encoder = vc4_get_crtc_encoder(crtc, crtc_state); -+ if (encoder) { -+ const struct drm_display_mode *mode = &crtc_state->adjusted_mode; -+ struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder); -+ -+ mode = &crtc_state->adjusted_mode; -+ if (vc4_encoder->type == VC4_ENCODER_TYPE_HDMI0) { -+ vc4_state->hvs_load = max(mode->clock * mode->hdisplay / mode->htotal + 1000, -+ mode->clock * 9 / 10) * 1000; -+ } else { -+ vc4_state->hvs_load = mode->clock * 1000; -+ } -+ } -+ - for_each_new_connector_in_state(state, conn, conn_state, - i) { - if (conn_state->crtc != crtc) ---- a/drivers/gpu/drm/vc4/vc4_drv.h -+++ b/drivers/gpu/drm/vc4/vc4_drv.h -@@ -558,6 +558,8 @@ struct vc4_crtc_state { - unsigned int bottom; - } margins; - -+ unsigned long hvs_load; -+ - /* Transitional state below, only valid during atomic commits */ - bool update_muxing; - }; ---- a/drivers/gpu/drm/vc4/vc4_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_kms.c -@@ -39,9 +39,11 @@ static struct vc4_ctm_state *to_vc4_ctm_ - - struct vc4_hvs_state { - struct drm_private_state base; -+ unsigned long core_clock_rate; - - struct { - unsigned in_use: 1; -+ unsigned long fifo_load; - struct drm_crtc_commit *pending_commit; - } fifo_state[HVS_NUM_CHANNELS]; - }; -@@ -339,11 +341,20 @@ static void vc4_atomic_commit_tail(struc - struct vc4_dev *vc4 = to_vc4_dev(dev); - struct vc4_hvs *hvs = vc4->hvs; - struct drm_crtc_state *new_crtc_state; -+ struct vc4_hvs_state *new_hvs_state; - struct drm_crtc *crtc; - struct vc4_hvs_state *old_hvs_state; - unsigned int channel; - int i; - -+ old_hvs_state = vc4_hvs_get_old_global_state(state); -+ if (WARN_ON(!old_hvs_state)) -+ return; -+ -+ new_hvs_state = vc4_hvs_get_new_global_state(state); -+ if (WARN_ON(!new_hvs_state)) -+ return; -+ - for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) { - struct vc4_crtc_state *vc4_crtc_state; - -@@ -354,10 +365,6 @@ static void vc4_atomic_commit_tail(struc - vc4_hvs_mask_underrun(dev, vc4_crtc_state->assigned_channel); - } - -- old_hvs_state = vc4_hvs_get_old_global_state(state); -- if (IS_ERR(old_hvs_state)) -- return; -- - for (channel = 0; channel < HVS_NUM_CHANNELS; channel++) { - struct drm_crtc_commit *commit; - int ret; -@@ -377,8 +384,13 @@ static void vc4_atomic_commit_tail(struc - old_hvs_state->fifo_state[channel].pending_commit = NULL; - } - -- if (vc4->hvs->hvs5) -- clk_set_min_rate(hvs->core_clk, 500000000); -+ if (vc4->hvs->hvs5) { -+ unsigned long core_rate = max_t(unsigned long, -+ 500000000, -+ new_hvs_state->core_clock_rate); -+ -+ clk_set_min_rate(hvs->core_clk, core_rate); -+ } - - drm_atomic_helper_commit_modeset_disables(dev, state); - -@@ -401,8 +413,12 @@ static void vc4_atomic_commit_tail(struc - - drm_atomic_helper_cleanup_planes(dev, state); - -- if (vc4->hvs->hvs5) -- clk_set_min_rate(hvs->core_clk, 0); -+ if (vc4->hvs->hvs5) { -+ drm_dbg(dev, "Running the core clock at %lu Hz\n", -+ new_hvs_state->core_clock_rate); -+ -+ clk_set_min_rate(hvs->core_clk, new_hvs_state->core_clock_rate); -+ } - } - - static int vc4_atomic_commit_setup(struct drm_atomic_state *state) -@@ -659,11 +675,13 @@ vc4_hvs_channels_duplicate_state(struct - - __drm_atomic_helper_private_obj_duplicate_state(obj, &state->base); - -- - for (i = 0; i < HVS_NUM_CHANNELS; i++) { - state->fifo_state[i].in_use = old_state->fifo_state[i].in_use; -+ state->fifo_state[i].fifo_load = old_state->fifo_state[i].fifo_load; - } - -+ state->core_clock_rate = old_state->core_clock_rate; -+ - return &state->base; - } - -@@ -819,6 +837,76 @@ static int vc4_pv_muxing_atomic_check(st - } - - static int -+vc4_core_clock_atomic_check(struct drm_atomic_state *state) -+{ -+ struct vc4_dev *vc4 = to_vc4_dev(state->dev); -+ struct drm_private_state *priv_state; -+ struct vc4_hvs_state *hvs_new_state; -+ struct vc4_load_tracker_state *load_state; -+ struct drm_crtc_state *old_crtc_state, *new_crtc_state; -+ struct drm_crtc *crtc; -+ unsigned int num_outputs; -+ unsigned long pixel_rate; -+ unsigned long cob_rate; -+ unsigned int i; -+ -+ priv_state = drm_atomic_get_private_obj_state(state, -+ &vc4->load_tracker); -+ if (IS_ERR(priv_state)) -+ return PTR_ERR(priv_state); -+ -+ load_state = to_vc4_load_tracker_state(priv_state); -+ -+ hvs_new_state = vc4_hvs_get_global_state(state); -+ if (!hvs_new_state) -+ return -EINVAL; -+ -+ for_each_oldnew_crtc_in_state(state, crtc, -+ old_crtc_state, -+ new_crtc_state, -+ i) { -+ if (old_crtc_state->active) { -+ struct vc4_crtc_state *old_vc4_state = -+ to_vc4_crtc_state(old_crtc_state); -+ unsigned int channel = old_vc4_state->assigned_channel; -+ -+ hvs_new_state->fifo_state[channel].fifo_load = 0; -+ } -+ -+ if (new_crtc_state->active) { -+ struct vc4_crtc_state *new_vc4_state = -+ to_vc4_crtc_state(new_crtc_state); -+ unsigned int channel = new_vc4_state->assigned_channel; -+ -+ hvs_new_state->fifo_state[channel].fifo_load = -+ new_vc4_state->hvs_load; -+ } -+ } -+ -+ cob_rate = 0; -+ num_outputs = 0; -+ for (i = 0; i < HVS_NUM_CHANNELS; i++) { -+ if (!hvs_new_state->fifo_state[i].in_use) -+ continue; -+ -+ num_outputs++; -+ cob_rate += hvs_new_state->fifo_state[i].fifo_load; -+ } -+ -+ pixel_rate = load_state->hvs_load; -+ if (num_outputs > 1) { -+ pixel_rate = (pixel_rate * 40) / 100; -+ } else { -+ pixel_rate = (pixel_rate * 60) / 100; -+ } -+ -+ hvs_new_state->core_clock_rate = max(cob_rate, pixel_rate); -+ -+ return 0; -+} -+ -+ -+static int - vc4_atomic_check(struct drm_device *dev, struct drm_atomic_state *state) - { - int ret; -@@ -835,7 +923,11 @@ vc4_atomic_check(struct drm_device *dev, - if (ret) - return ret; - -- return vc4_load_tracker_atomic_check(state); -+ ret = vc4_load_tracker_atomic_check(state); -+ if (ret) -+ return ret; -+ -+ return vc4_core_clock_atomic_check(state); - } - - static struct drm_mode_config_helper_funcs vc4_mode_config_helpers = { diff --git a/target/linux/bcm27xx/patches-5.15/950-0019-drm-vc4-select-PM.patch b/target/linux/bcm27xx/patches-5.15/950-0019-drm-vc4-select-PM.patch deleted file mode 100644 index d1183245c..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0019-drm-vc4-select-PM.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 0ba0b0f41c143fe0f30ea248e55872e681870be2 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Thu, 19 Aug 2021 15:53:03 +0200 -Subject: [PATCH] drm/vc4: select PM - -We already depend on runtime PM to get the power domains and clocks for -most of the devices supported by the vc4 driver, so let's just select it -to make sure it's there, and remove the ifdef. - -Signed-off-by: Maxime Ripard ---- - drivers/gpu/drm/vc4/Kconfig | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/gpu/drm/vc4/Kconfig -+++ b/drivers/gpu/drm/vc4/Kconfig -@@ -5,11 +5,11 @@ config DRM_VC4 - depends on DRM - depends on SND && SND_SOC - depends on COMMON_CLK -- depends on PM - select DRM_KMS_HELPER - select DRM_KMS_CMA_HELPER - select DRM_GEM_CMA_HELPER - select DRM_PANEL_BRIDGE -+ select PM - select SND_PCM - select SND_PCM_ELD - select SND_SOC_GENERIC_DMAENGINE_PCM diff --git a/target/linux/bcm27xx/patches-5.15/950-0020-drm-probe-helper-Create-a-HPD-IRQ-event-helper-for-a.patch b/target/linux/bcm27xx/patches-5.15/950-0020-drm-probe-helper-Create-a-HPD-IRQ-event-helper-for-a.patch deleted file mode 100644 index 82086a13f..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0020-drm-probe-helper-Create-a-HPD-IRQ-event-helper-for-a.patch +++ /dev/null @@ -1,201 +0,0 @@ -From 22ce134cee72bd9ef4b02c8769f868309f2ab8fd Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Thu, 19 Aug 2021 14:37:04 +0200 -Subject: [PATCH] drm/probe-helper: Create a HPD IRQ event helper for a - single connector - -The drm_helper_hpd_irq_event() function is iterating over all the -connectors when an hotplug event is detected. - -During that iteration, it will call each connector detect function and -figure out if its status changed. - -Finally, if any connector changed, it will notify the user-space and the -clients that something changed on the DRM device. - -This is supposed to be used for drivers that don't have a hotplug -interrupt for individual connectors. However, drivers that can use an -interrupt for a single connector are left in the dust and can either -reimplement the logic used during the iteration for each connector or -use that helper and iterate over all connectors all the time. - -Since both are suboptimal, let's create a helper that will only perform -the status detection on a single connector. - -Signed-off-by: Maxime Ripard - ---- - -Changes from v1: - - Rename the shared function - - Move the hotplug event notification out of the shared function - - Added missing locks - - Improve the documentation - - Switched to drm_dbg_kms ---- - drivers/gpu/drm/drm_probe_helper.c | 120 ++++++++++++++++++++--------- - include/drm/drm_probe_helper.h | 1 + - 2 files changed, 86 insertions(+), 35 deletions(-) - ---- a/drivers/gpu/drm/drm_probe_helper.c -+++ b/drivers/gpu/drm/drm_probe_helper.c -@@ -796,6 +796,86 @@ void drm_kms_helper_poll_fini(struct drm - } - EXPORT_SYMBOL(drm_kms_helper_poll_fini); - -+static bool check_connector_changed(struct drm_connector *connector) -+{ -+ struct drm_device *dev = connector->dev; -+ enum drm_connector_status old_status; -+ u64 old_epoch_counter; -+ bool changed = false; -+ -+ /* Only handle HPD capable connectors. */ -+ drm_WARN_ON(dev, !(connector->polled & DRM_CONNECTOR_POLL_HPD)); -+ -+ drm_WARN_ON(dev, !mutex_is_locked(&dev->mode_config.mutex)); -+ -+ old_status = connector->status; -+ old_epoch_counter = connector->epoch_counter; -+ -+ drm_dbg_kms(dev, "[CONNECTOR:%d:%s] Old epoch counter %llu\n", -+ connector->base.id, -+ connector->name, -+ old_epoch_counter); -+ -+ connector->status = drm_helper_probe_detect(connector, NULL, false); -+ drm_dbg_kms(dev, "[CONNECTOR:%d:%s] status updated from %s to %s\n", -+ connector->base.id, -+ connector->name, -+ drm_get_connector_status_name(old_status), -+ drm_get_connector_status_name(connector->status)); -+ -+ drm_dbg_kms(dev, "[CONNECTOR:%d:%s] New epoch counter %llu\n", -+ connector->base.id, -+ connector->name, -+ connector->epoch_counter); -+ -+ /* -+ * Check if epoch counter had changed, meaning that we need -+ * to send a uevent. -+ */ -+ if (old_epoch_counter != connector->epoch_counter) -+ changed = true; -+ -+ return changed; -+} -+ -+/** -+ * drm_connector_helper_hpd_irq_event - hotplug processing -+ * @connector: drm_connector -+ * -+ * Drivers can use this helper function to run a detect cycle on a connector -+ * which has the DRM_CONNECTOR_POLL_HPD flag set in its &polled member. -+ * -+ * This helper function is useful for drivers which can track hotplug -+ * interrupts for a single connector. Drivers that want to send a -+ * hotplug event for all connectors or can't track hotplug interrupts -+ * per connector need to use drm_helper_hpd_irq_event(). -+ * -+ * This function must be called from process context with no mode -+ * setting locks held. -+ * -+ * Note that a connector can be both polled and probed from the hotplug -+ * handler, in case the hotplug interrupt is known to be unreliable. -+ */ -+bool drm_connector_helper_hpd_irq_event(struct drm_connector *connector) -+{ -+ struct drm_device *dev = connector->dev; -+ bool changed; -+ -+ mutex_lock(&dev->mode_config.mutex); -+ changed = check_connector_changed(connector); -+ mutex_unlock(&dev->mode_config.mutex); -+ -+ if (changed) { -+ drm_kms_helper_hotplug_event(dev); -+ drm_dbg_kms(dev, "[CONNECTOR:%d:%s] Sent hotplug event\n", -+ connector->base.id, -+ connector->name); -+ } -+ -+ return changed; -+} -+EXPORT_SYMBOL(drm_connector_helper_hpd_irq_event); -+ - /** - * drm_helper_hpd_irq_event - hotplug processing - * @dev: drm_device -@@ -809,9 +889,10 @@ EXPORT_SYMBOL(drm_kms_helper_poll_fini); - * interrupts for each connector. - * - * Drivers which support hotplug interrupts for each connector individually and -- * which have a more fine-grained detect logic should bypass this code and -- * directly call drm_kms_helper_hotplug_event() in case the connector state -- * changed. -+ * which have a more fine-grained detect logic can use -+ * drm_connector_helper_hpd_irq_event(). Alternatively, they should bypass this -+ * code and directly call drm_kms_helper_hotplug_event() in case the connector -+ * state changed. - * - * This function must be called from process context with no mode - * setting locks held. -@@ -823,9 +904,7 @@ bool drm_helper_hpd_irq_event(struct drm - { - struct drm_connector *connector; - struct drm_connector_list_iter conn_iter; -- enum drm_connector_status old_status; - bool changed = false; -- u64 old_epoch_counter; - - if (!dev->mode_config.poll_enabled) - return false; -@@ -833,37 +912,8 @@ bool drm_helper_hpd_irq_event(struct drm - mutex_lock(&dev->mode_config.mutex); - drm_connector_list_iter_begin(dev, &conn_iter); - drm_for_each_connector_iter(connector, &conn_iter) { -- /* Only handle HPD capable connectors. */ -- if (!(connector->polled & DRM_CONNECTOR_POLL_HPD)) -- continue; -- -- old_status = connector->status; -- -- old_epoch_counter = connector->epoch_counter; -- -- DRM_DEBUG_KMS("[CONNECTOR:%d:%s] Old epoch counter %llu\n", connector->base.id, -- connector->name, -- old_epoch_counter); -- -- connector->status = drm_helper_probe_detect(connector, NULL, false); -- DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %s to %s\n", -- connector->base.id, -- connector->name, -- drm_get_connector_status_name(old_status), -- drm_get_connector_status_name(connector->status)); -- -- DRM_DEBUG_KMS("[CONNECTOR:%d:%s] New epoch counter %llu\n", -- connector->base.id, -- connector->name, -- connector->epoch_counter); -- -- /* -- * Check if epoch counter had changed, meaning that we need -- * to send a uevent. -- */ -- if (old_epoch_counter != connector->epoch_counter) -+ if (check_connector_changed(connector)) - changed = true; -- - } - drm_connector_list_iter_end(&conn_iter); - mutex_unlock(&dev->mode_config.mutex); ---- a/include/drm/drm_probe_helper.h -+++ b/include/drm/drm_probe_helper.h -@@ -18,6 +18,7 @@ int drm_helper_probe_detect(struct drm_c - void drm_kms_helper_poll_init(struct drm_device *dev); - void drm_kms_helper_poll_fini(struct drm_device *dev); - bool drm_helper_hpd_irq_event(struct drm_device *dev); -+bool drm_connector_helper_hpd_irq_event(struct drm_connector *connector); - void drm_kms_helper_hotplug_event(struct drm_device *dev); - - void drm_kms_helper_poll_disable(struct drm_device *dev); diff --git a/target/linux/bcm27xx/patches-5.15/950-0021-drm-vc4-hdmi-Actually-check-for-the-connector-status.patch b/target/linux/bcm27xx/patches-5.15/950-0021-drm-vc4-hdmi-Actually-check-for-the-connector-status.patch deleted file mode 100644 index 96913ed7b..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0021-drm-vc4-hdmi-Actually-check-for-the-connector-status.patch +++ /dev/null @@ -1,60 +0,0 @@ -From b30b747d76946fb176bb4b044c830415d551b7bb Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Thu, 19 Aug 2021 13:50:12 +0200 -Subject: [PATCH] drm/vc4: hdmi: Actually check for the connector - status in hotplug - -The drm_helper_hpd_irq_event() documentation states that this function -is "useful for drivers which can't or don't track hotplug interrupts for -each connector." and that "Drivers which support hotplug interrupts for -each connector individually and which have a more fine-grained detect -logic should bypass this code and directly call -drm_kms_helper_hotplug_event()". This is thus what we ended-up doing. - -However, what this actually means, and is further explained in the -drm_kms_helper_hotplug_event() documentation, is that -drm_kms_helper_hotplug_event() should be called by drivers that can -track the connection status change, and if it has changed we should call -that function. - -This underlying expectation we failed to provide is that the caller of -drm_kms_helper_hotplug_event() should call drm_helper_probe_detect() to -probe the new status of the connector. - -Since we didn't do it, it meant that even though we were sending the -notification to user-space and the DRM clients that something changed we -never probed or updated our internal connector status ourselves. - -This went mostly unnoticed since the detect callback usually doesn't -have any side-effect. Also, if we were using the DRM fbdev emulation -(which is a DRM client), or any user-space application that can deal -with hotplug events, chances are they would react to the hotplug event -by probing the connector status eventually. - -However, now that we have to enable the scrambler in detect() if it was -enabled it has a side effect, and an application such as Kodi or -modetest doesn't deal with hotplug events. This resulted with a black -screen when Kodi or modetest was running when a screen was disconnected -and then reconnected, or switched off and on. - -Signed-off-by: Maxime Ripard ---- - drivers/gpu/drm/vc4/vc4_hdmi.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_hdmi.c -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c -@@ -1802,10 +1802,11 @@ static void vc4_hdmi_audio_exit(struct v - static irqreturn_t vc4_hdmi_hpd_irq_thread(int irq, void *priv) - { - struct vc4_hdmi *vc4_hdmi = priv; -- struct drm_device *dev = vc4_hdmi->connector.dev; -+ struct drm_connector *connector = &vc4_hdmi->connector; -+ struct drm_device *dev = connector->dev; - - if (dev && dev->registered) -- drm_kms_helper_hotplug_event(dev); -+ drm_connector_helper_hpd_irq_event(connector); - - return IRQ_HANDLED; - } diff --git a/target/linux/bcm27xx/patches-5.15/950-0022-firmware-raspberrypi-Add-RPI_FIRMWARE_NOTIFY_DISPLAY.patch b/target/linux/bcm27xx/patches-5.15/950-0022-firmware-raspberrypi-Add-RPI_FIRMWARE_NOTIFY_DISPLAY.patch deleted file mode 100644 index bbb50fc98..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0022-firmware-raspberrypi-Add-RPI_FIRMWARE_NOTIFY_DISPLAY.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 269985a75363eecabfc6e039c4731100c4d47b05 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Wed, 15 Dec 2021 10:51:14 +0100 -Subject: [PATCH] firmware: raspberrypi: Add - RPI_FIRMWARE_NOTIFY_DISPLAY_DONE - -The RPI_FIRMWARE_NOTIFY_DISPLAY_DONE firmware call allows to tell the -firmware the kernel is in charge of the display now and the firmware can -free whatever resources it was using. - -Acked-by: Nicolas Saenz Julienne -Signed-off-by: Maxime Ripard -Link: https://patchwork.freedesktop.org/patch/msgid/20211215095117.176435-2-maxime@cerno.tech ---- - include/soc/bcm2835/raspberrypi-firmware.h | 1 + - 1 file changed, 1 insertion(+) - ---- a/include/soc/bcm2835/raspberrypi-firmware.h -+++ b/include/soc/bcm2835/raspberrypi-firmware.h -@@ -91,6 +91,7 @@ enum rpi_firmware_property_tag { - RPI_FIRMWARE_GET_POE_HAT_VAL = 0x00030049, - RPI_FIRMWARE_SET_POE_HAT_VAL = 0x00030050, - RPI_FIRMWARE_NOTIFY_XHCI_RESET = 0x00030058, -+ RPI_FIRMWARE_NOTIFY_DISPLAY_DONE = 0x00030066, - - /* Dispmanx TAGS */ - RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE = 0x00040001, diff --git a/target/linux/bcm27xx/patches-5.15/950-0023-drm-vc4-Remove-conflicting-framebuffers-before-calli.patch b/target/linux/bcm27xx/patches-5.15/950-0023-drm-vc4-Remove-conflicting-framebuffers-before-calli.patch deleted file mode 100644 index e78c5aa80..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0023-drm-vc4-Remove-conflicting-framebuffers-before-calli.patch +++ /dev/null @@ -1,39 +0,0 @@ -From c8f54918eece907f904d160815603bfcee0cfa1e Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Wed, 15 Dec 2021 10:51:16 +0100 -Subject: [PATCH] drm/vc4: Remove conflicting framebuffers before - callind bind_all - -The bind hooks will modify their controller registers, so simplefb is -going to be unusable anyway. Let's avoid any transient state where it -could still be in the system but no longer functionnal. - -Acked-by: Nicolas Saenz Julienne -Signed-off-by: Maxime Ripard -Link: https://patchwork.freedesktop.org/patch/msgid/20211215095117.176435-4-maxime@cerno.tech ---- - drivers/gpu/drm/vc4/vc4_drv.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_drv.c -+++ b/drivers/gpu/drm/vc4/vc4_drv.c -@@ -272,15 +272,15 @@ static int vc4_drm_bind(struct device *d - if (ret) - return ret; - -- ret = component_bind_all(dev, drm); -+ ret = drm_aperture_remove_framebuffers(false, &vc4_drm_driver); - if (ret) - return ret; - -- ret = vc4_plane_create_additional_planes(drm); -+ ret = component_bind_all(dev, drm); - if (ret) -- goto unbind_all; -+ return ret; - -- ret = drm_aperture_remove_framebuffers(false, &vc4_drm_driver); -+ ret = vc4_plane_create_additional_planes(drm); - if (ret) - goto unbind_all; - diff --git a/target/linux/bcm27xx/patches-5.15/950-0024-drm-vc4-Notify-the-firmware-when-DRM-is-in-charge.patch b/target/linux/bcm27xx/patches-5.15/950-0024-drm-vc4-Notify-the-firmware-when-DRM-is-in-charge.patch deleted file mode 100644 index 65c47edb5..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0024-drm-vc4-Notify-the-firmware-when-DRM-is-in-charge.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 9e9177db83609c19bbe523cc4d20119cf09ea787 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Wed, 15 Dec 2021 10:51:17 +0100 -Subject: [PATCH] drm/vc4: Notify the firmware when DRM is in charge - -Once the call to drm_fb_helper_remove_conflicting_framebuffers() has -been made, simplefb has been unregistered and the KMS driver is entirely -in charge of the display. - -Thus, we can notify the firmware it can free whatever resource it was -using to maintain simplefb functional. - -Signed-off-by: Maxime Ripard -Reviewed-by: Javier Martinez Canillas -Acked-by: Thomas Zimmermann -Link: https://patchwork.freedesktop.org/patch/msgid/20211215095117.176435-5-maxime@cerno.tech ---- - drivers/gpu/drm/vc4/vc4_drv.c | 22 ++++++++++++++++++++++ - 1 file changed, 22 insertions(+) - ---- a/drivers/gpu/drm/vc4/vc4_drv.c -+++ b/drivers/gpu/drm/vc4/vc4_drv.c -@@ -37,6 +37,8 @@ - #include - #include - -+#include -+ - #include "uapi/drm/vc4_drm.h" - - #include "vc4_drv.h" -@@ -226,6 +228,7 @@ static const struct of_device_id vc4_dma - static int vc4_drm_bind(struct device *dev) - { - struct platform_device *pdev = to_platform_device(dev); -+ struct rpi_firmware *firmware = NULL; - struct drm_device *drm; - struct vc4_dev *vc4; - struct device_node *node; -@@ -272,10 +275,29 @@ static int vc4_drm_bind(struct device *d - if (ret) - return ret; - -+ node = of_find_compatible_node(NULL, NULL, "raspberrypi,bcm2835-firmware"); -+ if (node) { -+ firmware = rpi_firmware_get(node); -+ of_node_put(node); -+ -+ if (!firmware) -+ return -EPROBE_DEFER; -+ } -+ - ret = drm_aperture_remove_framebuffers(false, &vc4_drm_driver); - if (ret) - return ret; - -+ if (firmware) { -+ ret = rpi_firmware_property(firmware, -+ RPI_FIRMWARE_NOTIFY_DISPLAY_DONE, -+ NULL, 0); -+ if (ret) -+ drm_warn(drm, "Couldn't stop firmware display driver: %d\n", ret); -+ -+ rpi_firmware_put(firmware); -+ } -+ - ret = component_bind_all(dev, drm); - if (ret) - return ret; diff --git a/target/linux/bcm27xx/patches-5.15/950-0027-Revert-staging-bcm2835-audio-Drop-DT-dependency.patch b/target/linux/bcm27xx/patches-5.15/950-0027-Revert-staging-bcm2835-audio-Drop-DT-dependency.patch deleted file mode 100644 index 579e6d5e0..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0027-Revert-staging-bcm2835-audio-Drop-DT-dependency.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 85c2420c3b800f5ec030b28f19b2a77022173a9b Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Fri, 15 Mar 2019 21:11:10 +0000 -Subject: [PATCH] Revert "staging: bcm2835-audio: Drop DT dependency" - -This reverts commit b7491a9fca2dc2535b9dc922550a37c5baae9d3d. ---- - .../vc04_services/bcm2835-audio/bcm2835.c | 31 +++++++++++++------ - 1 file changed, 22 insertions(+), 9 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c -@@ -6,13 +6,13 @@ - #include - #include - #include -+#include - - #include "bcm2835.h" - - static bool enable_hdmi; - static bool enable_headphones; - static bool enable_compat_alsa = true; --static int num_channels = MAX_SUBSTREAMS; - - module_param(enable_hdmi, bool, 0444); - MODULE_PARM_DESC(enable_hdmi, "Enables HDMI virtual audio device"); -@@ -21,8 +21,6 @@ MODULE_PARM_DESC(enable_headphones, "Ena - module_param(enable_compat_alsa, bool, 0444); - MODULE_PARM_DESC(enable_compat_alsa, - "Enables ALSA compatibility virtual audio device"); --module_param(num_channels, int, 0644); --MODULE_PARM_DESC(num_channels, "Number of audio channels (default: 8)"); - - static void bcm2835_devm_free_vchi_ctx(struct device *dev, void *res) - { -@@ -296,19 +294,28 @@ static int snd_add_child_devices(struct - static int snd_bcm2835_alsa_probe(struct platform_device *pdev) - { - struct device *dev = &pdev->dev; -+ u32 numchans; - int err; - -- if (num_channels <= 0 || num_channels > MAX_SUBSTREAMS) { -- num_channels = MAX_SUBSTREAMS; -- dev_warn(dev, "Illegal num_channels value, will use %u\n", -- num_channels); -+ err = of_property_read_u32(dev->of_node, "brcm,pwm-channels", -+ &numchans); -+ if (err) { -+ dev_err(dev, "Failed to get DT property 'brcm,pwm-channels'"); -+ return err; -+ } -+ -+ if (numchans == 0 || numchans > MAX_SUBSTREAMS) { -+ numchans = MAX_SUBSTREAMS; -+ dev_warn(dev, -+ "Illegal 'brcm,pwm-channels' value, will use %u\n", -+ numchans); - } - - err = bcm2835_devm_add_vchi_ctx(dev); - if (err) - return err; - -- err = snd_add_child_devices(dev, num_channels); -+ err = snd_add_child_devices(dev, numchans); - if (err) - return err; - -@@ -330,6 +337,12 @@ static int snd_bcm2835_alsa_resume(struc - - #endif - -+static const struct of_device_id snd_bcm2835_of_match_table[] = { -+ { .compatible = "brcm,bcm2835-audio",}, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, snd_bcm2835_of_match_table); -+ - static struct platform_driver bcm2835_alsa_driver = { - .probe = snd_bcm2835_alsa_probe, - #ifdef CONFIG_PM -@@ -338,6 +351,7 @@ static struct platform_driver bcm2835_al - #endif - .driver = { - .name = "bcm2835_audio", -+ .of_match_table = snd_bcm2835_of_match_table, - }, - }; - module_platform_driver(bcm2835_alsa_driver); -@@ -345,4 +359,3 @@ module_platform_driver(bcm2835_alsa_driv - MODULE_AUTHOR("Dom Cobley"); - MODULE_DESCRIPTION("Alsa driver for BCM2835 chip"); - MODULE_LICENSE("GPL"); --MODULE_ALIAS("platform:bcm2835_audio"); diff --git a/target/linux/bcm27xx/patches-5.15/950-0040-spi-spidev-Completely-disable-the-spidev-warning.patch b/target/linux/bcm27xx/patches-5.15/950-0040-spi-spidev-Completely-disable-the-spidev-warning.patch deleted file mode 100644 index 8fa7c55aa..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0040-spi-spidev-Completely-disable-the-spidev-warning.patch +++ /dev/null @@ -1,24 +0,0 @@ -From e61ce76e706cdafe29c9c0e7bbe39bc8af9377ba Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 14 Jul 2015 10:26:09 +0100 -Subject: [PATCH] spi: spidev: Completely disable the spidev warning - -An alternative strategy would be to use "rpi,spidev" instead, but that -would require many Raspberry Pi Device Tree changes. - -Signed-off-by: Phil Elwell ---- - drivers/spi/spidev.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/spi/spidev.c -+++ b/drivers/spi/spidev.c -@@ -759,7 +759,7 @@ static int spidev_probe(struct spi_devic - * compatible string, it is a Linux implementation thing - * rather than a description of the hardware. - */ -- WARN(spi->dev.of_node && -+ WARN(0 && spi->dev.of_node && - of_device_is_compatible(spi->dev.of_node, "spidev"), - "%pOF: buggy DT: spidev listed directly in DT\n", spi->dev.of_node); - diff --git a/target/linux/bcm27xx/patches-5.15/950-0056-amba_pl011-Don-t-use-DT-aliases-for-numbering.patch b/target/linux/bcm27xx/patches-5.15/950-0056-amba_pl011-Don-t-use-DT-aliases-for-numbering.patch deleted file mode 100644 index 14f4ee66e..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0056-amba_pl011-Don-t-use-DT-aliases-for-numbering.patch +++ /dev/null @@ -1,29 +0,0 @@ -From da6e94edb85fc948357b4163b6ddaa9e75f5e0df Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 23 Feb 2016 17:26:48 +0000 -Subject: [PATCH] amba_pl011: Don't use DT aliases for numbering - -The pl011 driver looks for DT aliases of the form "serial", -and if found uses as the device ID. This can cause -/dev/ttyAMA0 to become /dev/ttyAMA1, which is confusing if the -other serial port is provided by the 8250 driver which doesn't -use the same logic. ---- - drivers/tty/serial/amba-pl011.c | 5 +++++ - 1 file changed, 5 insertions(+) - ---- a/drivers/tty/serial/amba-pl011.c -+++ b/drivers/tty/serial/amba-pl011.c -@@ -2752,7 +2752,12 @@ static int pl011_setup_port(struct devic - if (IS_ERR(base)) - return PTR_ERR(base); - -+ /* Don't use DT serial aliases - it causes the device to -+ be renumbered to ttyAMA1 if it is the second serial port in the -+ system, even though the other one is ttyS0. The 8250 driver -+ doesn't use this logic, so always remains ttyS0. - index = pl011_probe_dt_alias(index, dev); -+ */ - - uap->old_cr = 0; - uap->port.dev = dev; diff --git a/target/linux/bcm27xx/patches-5.15/950-0057-amba_pl011-Round-input-clock-up.patch b/target/linux/bcm27xx/patches-5.15/950-0057-amba_pl011-Round-input-clock-up.patch deleted file mode 100644 index 416df594a..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0057-amba_pl011-Round-input-clock-up.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 307744a359bddf354711e54836e4757788c9dfc4 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 1 Mar 2017 16:07:39 +0000 -Subject: [PATCH] amba_pl011: Round input clock up - -The UART clock is initialised to be as close to the requested -frequency as possible without exceeding it. Now that there is a -clock manager that returns the actual frequencies, an expected -48MHz clock is reported as 47999625. If the requested baudrate -== requested clock/16, there is no headroom and the slight -reduction in actual clock rate results in failure. - -Detect cases where it looks like a "round" clock was chosen and -adjust the reported clock to match that "round" value. As the -code comment says: - -/* - * If increasing a clock by less than 0.1% changes it - * from ..999.. to ..000.., round up. - */ - -Signed-off-by: Phil Elwell ---- - drivers/tty/serial/amba-pl011.c | 23 +++++++++++++++++++++-- - 1 file changed, 21 insertions(+), 2 deletions(-) - ---- a/drivers/tty/serial/amba-pl011.c -+++ b/drivers/tty/serial/amba-pl011.c -@@ -1726,6 +1726,23 @@ static void pl011_put_poll_char(struct u - - #endif /* CONFIG_CONSOLE_POLL */ - -+unsigned long pl011_clk_round(unsigned long clk) -+{ -+ unsigned long scaler; -+ -+ /* -+ * If increasing a clock by less than 0.1% changes it -+ * from ..999.. to ..000.., round up. -+ */ -+ scaler = 1; -+ while (scaler * 100000 < clk) -+ scaler *= 10; -+ if ((clk + scaler - 1)/scaler % 1000 == 0) -+ clk = (clk/scaler + 1) * scaler; -+ -+ return clk; -+} -+ - static int pl011_hwinit(struct uart_port *port) - { - struct uart_amba_port *uap = -@@ -1742,7 +1759,7 @@ static int pl011_hwinit(struct uart_port - if (retval) - return retval; - -- uap->port.uartclk = clk_get_rate(uap->clk); -+ uap->port.uartclk = pl011_clk_round(clk_get_rate(uap->clk)); - - /* Clear pending error and receive interrupts */ - pl011_write(UART011_OEIS | UART011_BEIS | UART011_PEIS | -@@ -2448,7 +2465,7 @@ static int pl011_console_setup(struct co - plat->init(); - } - -- uap->port.uartclk = clk_get_rate(uap->clk); -+ uap->port.uartclk = pl011_clk_round(clk_get_rate(uap->clk)); - - if (uap->vendor->fixed_options) { - baud = uap->fixed_baud; -@@ -2665,6 +2682,7 @@ static struct uart_driver amba_reg = { - .cons = AMBA_CONSOLE, - }; - -+#if 0 - static int pl011_probe_dt_alias(int index, struct device *dev) - { - struct device_node *np; -@@ -2696,6 +2714,7 @@ static int pl011_probe_dt_alias(int inde - - return ret; - } -+#endif - - /* unregisters the driver also if no more ports are left */ - static void pl011_unregister_port(struct uart_amba_port *uap) diff --git a/target/linux/bcm27xx/patches-5.15/950-0068-Speed-up-console-framebuffer-imageblit-function.patch b/target/linux/bcm27xx/patches-5.15/950-0068-Speed-up-console-framebuffer-imageblit-function.patch deleted file mode 100644 index 8c938f50b..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0068-Speed-up-console-framebuffer-imageblit-function.patch +++ /dev/null @@ -1,209 +0,0 @@ -From 784d9bd9e4fecb27ceb3a0d0375dc13d1f35e44c Mon Sep 17 00:00:00 2001 -From: Harm Hanemaaijer -Date: Thu, 20 Jun 2013 20:21:39 +0200 -Subject: [PATCH] Speed up console framebuffer imageblit function - -Especially on platforms with a slower CPU but a relatively high -framebuffer fill bandwidth, like current ARM devices, the existing -console monochrome imageblit function used to draw console text is -suboptimal for common pixel depths such as 16bpp and 32bpp. The existing -code is quite general and can deal with several pixel depths. By creating -special case functions for 16bpp and 32bpp, by far the most common pixel -formats used on modern systems, a significant speed-up is attained -which can be readily felt on ARM-based devices like the Raspberry Pi -and the Allwinner platform, but should help any platform using the -fb layer. - -The special case functions allow constant folding, eliminating a number -of instructions including divide operations, and allow the use of an -unrolled loop, eliminating instructions with a variable shift size, -reducing source memory access instructions, and eliminating excessive -branching. These unrolled loops also allow much better code optimization -by the C compiler. The code that selects which optimized variant is used -is also simplified, eliminating integer divide instructions. - -The speed-up, measured by timing 'cat file.txt' in the console, varies -between 40% and 70%, when testing on the Raspberry Pi and Allwinner -ARM-based platforms, depending on font size and the pixel depth, with -the greater benefit for 32bpp. - -Signed-off-by: Harm Hanemaaijer ---- - drivers/video/fbdev/core/cfbimgblt.c | 152 ++++++++++++++++++++++++++- - 1 file changed, 147 insertions(+), 5 deletions(-) - ---- a/drivers/video/fbdev/core/cfbimgblt.c -+++ b/drivers/video/fbdev/core/cfbimgblt.c -@@ -28,6 +28,11 @@ - * - * Also need to add code to deal with cards endians that are different than - * the native cpu endians. I also need to deal with MSB position in the word. -+ * Modified by Harm Hanemaaijer (fgenfb@yahoo.com) 2013: -+ * - Provide optimized versions of fast_imageblit for 16 and 32bpp that are -+ * significantly faster than the previous implementation. -+ * - Simplify the fast/slow_imageblit selection code, avoiding integer -+ * divides. - */ - #include - #include -@@ -262,6 +267,133 @@ static inline void fast_imageblit(const - } - } - -+/* -+ * Optimized fast_imageblit for bpp == 16. ppw = 2, bit_mask = 3 folded -+ * into the code, main loop unrolled. -+ */ -+ -+static inline void fast_imageblit16(const struct fb_image *image, -+ struct fb_info *p, u8 __iomem * dst1, -+ u32 fgcolor, u32 bgcolor) -+{ -+ u32 fgx = fgcolor, bgx = bgcolor; -+ u32 spitch = (image->width + 7) / 8; -+ u32 end_mask, eorx; -+ const char *s = image->data, *src; -+ u32 __iomem *dst; -+ const u32 *tab = NULL; -+ int i, j, k; -+ -+ tab = fb_be_math(p) ? cfb_tab16_be : cfb_tab16_le; -+ -+ fgx <<= 16; -+ bgx <<= 16; -+ fgx |= fgcolor; -+ bgx |= bgcolor; -+ -+ eorx = fgx ^ bgx; -+ k = image->width / 2; -+ -+ for (i = image->height; i--;) { -+ dst = (u32 __iomem *) dst1; -+ src = s; -+ -+ j = k; -+ while (j >= 4) { -+ u8 bits = *src; -+ end_mask = tab[(bits >> 6) & 3]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); -+ end_mask = tab[(bits >> 4) & 3]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); -+ end_mask = tab[(bits >> 2) & 3]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); -+ end_mask = tab[bits & 3]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); -+ src++; -+ j -= 4; -+ } -+ if (j != 0) { -+ u8 bits = *src; -+ end_mask = tab[(bits >> 6) & 3]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); -+ if (j >= 2) { -+ end_mask = tab[(bits >> 4) & 3]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); -+ if (j == 3) { -+ end_mask = tab[(bits >> 2) & 3]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst); -+ } -+ } -+ } -+ dst1 += p->fix.line_length; -+ s += spitch; -+ } -+} -+ -+/* -+ * Optimized fast_imageblit for bpp == 32. ppw = 1, bit_mask = 1 folded -+ * into the code, main loop unrolled. -+ */ -+ -+static inline void fast_imageblit32(const struct fb_image *image, -+ struct fb_info *p, u8 __iomem * dst1, -+ u32 fgcolor, u32 bgcolor) -+{ -+ u32 fgx = fgcolor, bgx = bgcolor; -+ u32 spitch = (image->width + 7) / 8; -+ u32 end_mask, eorx; -+ const char *s = image->data, *src; -+ u32 __iomem *dst; -+ const u32 *tab = NULL; -+ int i, j, k; -+ -+ tab = cfb_tab32; -+ -+ eorx = fgx ^ bgx; -+ k = image->width; -+ -+ for (i = image->height; i--;) { -+ dst = (u32 __iomem *) dst1; -+ src = s; -+ -+ j = k; -+ while (j >= 8) { -+ u8 bits = *src; -+ end_mask = tab[(bits >> 7) & 1]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); -+ end_mask = tab[(bits >> 6) & 1]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); -+ end_mask = tab[(bits >> 5) & 1]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); -+ end_mask = tab[(bits >> 4) & 1]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); -+ end_mask = tab[(bits >> 3) & 1]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); -+ end_mask = tab[(bits >> 2) & 1]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); -+ end_mask = tab[(bits >> 1) & 1]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); -+ end_mask = tab[bits & 1]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); -+ src++; -+ j -= 8; -+ } -+ if (j != 0) { -+ u32 bits = (u32) * src; -+ while (j > 1) { -+ end_mask = tab[(bits >> 7) & 1]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); -+ bits <<= 1; -+ j--; -+ } -+ end_mask = tab[(bits >> 7) & 1]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst); -+ } -+ dst1 += p->fix.line_length; -+ s += spitch; -+ } -+} -+ - void cfb_imageblit(struct fb_info *p, const struct fb_image *image) - { - u32 fgcolor, bgcolor, start_index, bitstart, pitch_index = 0; -@@ -294,11 +426,21 @@ void cfb_imageblit(struct fb_info *p, co - bgcolor = image->bg_color; - } - -- if (32 % bpp == 0 && !start_index && !pitch_index && -- ((width & (32/bpp-1)) == 0) && -- bpp >= 8 && bpp <= 32) -- fast_imageblit(image, p, dst1, fgcolor, bgcolor); -- else -+ if (!start_index && !pitch_index) { -+ if (bpp == 32) -+ fast_imageblit32(image, p, dst1, fgcolor, -+ bgcolor); -+ else if (bpp == 16 && (width & 1) == 0) -+ fast_imageblit16(image, p, dst1, fgcolor, -+ bgcolor); -+ else if (bpp == 8 && (width & 3) == 0) -+ fast_imageblit(image, p, dst1, fgcolor, -+ bgcolor); -+ else -+ slow_imageblit(image, p, dst1, fgcolor, -+ bgcolor, -+ start_index, pitch_index); -+ } else - slow_imageblit(image, p, dst1, fgcolor, bgcolor, - start_index, pitch_index); - } else diff --git a/target/linux/bcm27xx/patches-5.15/950-0100-Add-ability-to-export-gpio-used-by-gpio-poweroff.patch b/target/linux/bcm27xx/patches-5.15/950-0100-Add-ability-to-export-gpio-used-by-gpio-poweroff.patch deleted file mode 100644 index 7b438f8f4..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0100-Add-ability-to-export-gpio-used-by-gpio-poweroff.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 03a2b2dc2c01a00838b83b6843c086230847239f Mon Sep 17 00:00:00 2001 -From: Nick Bulleid -Date: Thu, 10 May 2018 21:57:02 +0100 -Subject: [PATCH] Add ability to export gpio used by gpio-poweroff - -Signed-off-by: Nick Bulleid - -Added export feature to gpio-poweroff documentation - -Signed-off-by: Nick Bulleid ---- - .../devicetree/bindings/power/reset/gpio-poweroff.txt | 1 + - drivers/power/reset/gpio-poweroff.c | 9 +++++++++ - 2 files changed, 10 insertions(+) - ---- a/Documentation/devicetree/bindings/power/reset/gpio-poweroff.txt -+++ b/Documentation/devicetree/bindings/power/reset/gpio-poweroff.txt -@@ -31,6 +31,7 @@ Optional properties: - - inactive-delay-ms: Delay (default 100) to wait after driving gpio inactive - - timeout-ms: Time to wait before asserting a WARN_ON(1). If nothing is - specified, 3000 ms is used. -+- export : Export the GPIO line to the sysfs system - - Examples: - ---- a/drivers/power/reset/gpio-poweroff.c -+++ b/drivers/power/reset/gpio-poweroff.c -@@ -51,6 +51,7 @@ static int gpio_poweroff_probe(struct pl - bool input = false; - enum gpiod_flags flags; - bool force = false; -+ bool export = false; - - /* If a pm_power_off function has already been added, leave it alone */ - force = of_property_read_bool(pdev->dev.of_node, "force"); -@@ -76,6 +77,12 @@ static int gpio_poweroff_probe(struct pl - if (IS_ERR(reset_gpio)) - return PTR_ERR(reset_gpio); - -+ export = of_property_read_bool(pdev->dev.of_node, "export"); -+ if (export) { -+ gpiod_export(reset_gpio, false); -+ gpiod_export_link(&pdev->dev, "poweroff-gpio", reset_gpio); -+ } -+ - pm_power_off = &gpio_poweroff_do_poweroff; - return 0; - } -@@ -85,6 +92,8 @@ static int gpio_poweroff_remove(struct p - if (pm_power_off == &gpio_poweroff_do_poweroff) - pm_power_off = NULL; - -+ gpiod_unexport(reset_gpio); -+ - return 0; - } - diff --git a/target/linux/bcm27xx/patches-5.15/950-0103-of-configfs-Use-of_overlay_fdt_apply-API-call.patch b/target/linux/bcm27xx/patches-5.15/950-0103-of-configfs-Use-of_overlay_fdt_apply-API-call.patch deleted file mode 100644 index c0858adf9..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0103-of-configfs-Use-of_overlay_fdt_apply-API-call.patch +++ /dev/null @@ -1,114 +0,0 @@ -From bf71202ee22c77b2dd594d56a411dec94a0f7436 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 14 Jun 2018 15:07:26 +0100 -Subject: [PATCH] of: configfs: Use of_overlay_fdt_apply API call - -The published API to the dynamic overlay application mechanism now -takes a Flattened Device Tree blob as input so that it can manage the -lifetime of the unflattened tree. Conveniently, the new API call - -of_overlay_fdt_apply - is virtually a drop-in replacement for -create_overlay, which can now be deleted. - -Signed-off-by: Phil Elwell ---- - drivers/of/configfs.c | 47 +++++++------------------------------------ - 1 file changed, 7 insertions(+), 40 deletions(-) - ---- a/drivers/of/configfs.c -+++ b/drivers/of/configfs.c -@@ -40,41 +40,6 @@ struct cfs_overlay_item { - int dtbo_size; - }; - --static int create_overlay(struct cfs_overlay_item *overlay, void *blob) --{ -- int err; -- -- /* unflatten the tree */ -- of_fdt_unflatten_tree(blob, NULL, &overlay->overlay); -- if (overlay->overlay == NULL) { -- pr_err("%s: failed to unflatten tree\n", __func__); -- err = -EINVAL; -- goto out_err; -- } -- pr_debug("%s: unflattened OK\n", __func__); -- -- /* mark it as detached */ -- of_node_set_flag(overlay->overlay, OF_DETACHED); -- -- /* perform resolution */ -- err = of_resolve_phandles(overlay->overlay); -- if (err != 0) { -- pr_err("%s: Failed to resolve tree\n", __func__); -- goto out_err; -- } -- pr_debug("%s: resolved OK\n", __func__); -- -- err = of_overlay_apply(overlay->overlay, &overlay->ov_id); -- if (err < 0) { -- pr_err("%s: Failed to create overlay (err=%d)\n", -- __func__, err); -- goto out_err; -- } -- --out_err: -- return err; --} -- - static inline struct cfs_overlay_item *to_cfs_overlay_item( - struct config_item *item) - { -@@ -115,7 +80,8 @@ static ssize_t cfs_overlay_item_path_sto - if (err != 0) - goto out_err; - -- err = create_overlay(overlay, (void *)overlay->fw->data); -+ err = of_overlay_fdt_apply((void *)overlay->fw->data, -+ (u32)overlay->fw->size, &overlay->ov_id); - if (err != 0) - goto out_err; - -@@ -136,7 +102,7 @@ static ssize_t cfs_overlay_item_status_s - struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); - - return sprintf(page, "%s\n", -- overlay->ov_id >= 0 ? "applied" : "unapplied"); -+ overlay->ov_id > 0 ? "applied" : "unapplied"); - } - - CONFIGFS_ATTR(cfs_overlay_item_, path); -@@ -188,7 +154,8 @@ ssize_t cfs_overlay_item_dtbo_write(stru - - overlay->dtbo_size = count; - -- err = create_overlay(overlay, overlay->dtbo); -+ err = of_overlay_fdt_apply(overlay->dtbo, overlay->dtbo_size, -+ &overlay->ov_id); - if (err != 0) - goto out_err; - -@@ -198,6 +165,7 @@ out_err: - kfree(overlay->dtbo); - overlay->dtbo = NULL; - overlay->dtbo_size = 0; -+ overlay->ov_id = 0; - - return err; - } -@@ -213,7 +181,7 @@ static void cfs_overlay_release(struct c - { - struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); - -- if (overlay->ov_id >= 0) -+ if (overlay->ov_id > 0) - of_overlay_remove(&overlay->ov_id); - if (overlay->fw) - release_firmware(overlay->fw); -@@ -241,7 +209,6 @@ static struct config_item *cfs_overlay_g - overlay = kzalloc(sizeof(*overlay), GFP_KERNEL); - if (!overlay) - return ERR_PTR(-ENOMEM); -- overlay->ov_id = -1; - - config_item_init_type_name(&overlay->item, name, &cfs_overlay_type); - return &overlay->item; diff --git a/target/linux/bcm27xx/patches-5.15/950-0108-sc16is7xx-Don-t-spin-if-no-data-received.patch b/target/linux/bcm27xx/patches-5.15/950-0108-sc16is7xx-Don-t-spin-if-no-data-received.patch deleted file mode 100644 index f2016a48a..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0108-sc16is7xx-Don-t-spin-if-no-data-received.patch +++ /dev/null @@ -1,23 +0,0 @@ -From c625bcbb6a4c45e29c7c2c0dec24831025051032 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 6 Nov 2018 12:57:48 +0000 -Subject: [PATCH] sc16is7xx: Don't spin if no data received - -See: https://github.com/raspberrypi/linux/issues/2676 - -Signed-off-by: Phil Elwell ---- - drivers/tty/serial/sc16is7xx.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/tty/serial/sc16is7xx.c -+++ b/drivers/tty/serial/sc16is7xx.c -@@ -709,6 +709,8 @@ static bool sc16is7xx_port_irq(struct sc - - if (rxlen) - sc16is7xx_handle_rx(port, rxlen, iir); -+ else -+ return false; - break; - case SC16IS7XX_IIR_THRI_SRC: - sc16is7xx_handle_tx(port); diff --git a/target/linux/bcm27xx/patches-5.15/950-0111-Update-issue-templates-2736.patch b/target/linux/bcm27xx/patches-5.15/950-0111-Update-issue-templates-2736.patch deleted file mode 100644 index 5a5c04006..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0111-Update-issue-templates-2736.patch +++ /dev/null @@ -1,47 +0,0 @@ -From d6fafd1bfe1388aee8e7294fb663d0054d77ea34 Mon Sep 17 00:00:00 2001 -From: James Hughes -Date: Fri, 2 Nov 2018 11:55:49 +0000 -Subject: [PATCH] Update issue templates (#2736) - ---- - .github/ISSUE_TEMPLATE/bug_report.md | 34 ++++++++++++++++++++++++++++ - 1 file changed, 34 insertions(+) - create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md - ---- /dev/null -+++ b/.github/ISSUE_TEMPLATE/bug_report.md -@@ -0,0 +1,34 @@ -+--- -+name: Bug report -+about: Create a report to help us fix your issue -+ -+--- -+ -+**Is this the right place for my bug report?** -+This repository contains the Linux kernel used on the Raspberry Pi. If you believe that the issue you are seeing is kernel-related, this is the right place. If not, we have other repositories for the GPU firmware at [github.com/raspberrypi/firmware](https://github.com/raspberrypi/firmware) and Raspberry Pi userland applications at [github.com/raspberrypi/userland](https://github.com/raspberrypi/userland). If you have problems with the Raspbian distribution packages, report them in the [github.com/RPi-Distro/repo](https://github.com/RPi-Distro/repo). If you simply have a question, then [the Raspberry Pi forums](https://www.raspberrypi.org/forums) are the best place to ask it. -+ -+**Describe the bug** -+Add a clear and concise description of what you think the bug is. -+ -+**To reproduce** -+List the steps required to reproduce the issue. -+ -+**Expected behaviour** -+Add a clear and concise description of what you expected to happen. -+ -+**Actual behaviour** -+Add a clear and concise description of what actually happened. -+ -+**System** -+ Copy and paste the results of the raspinfo command in to this section. Alternatively, copy and paste a pastebin link, or add answers to the following questions: -+ -+* Which model of Raspberry Pi? e.g. Pi3B+, PiZeroW -+* Which OS and version (`cat /etc/rpi-issue`)? -+* Which firmware version (`vcgencmd version`)? -+* Which kernel version (`uname -a`)? -+ -+**Logs** -+If applicable, add the relevant output from `dmesg` or similar. -+ -+**Additional context** -+Add any other relevant context for the problem. diff --git a/target/linux/bcm27xx/patches-5.15/950-0117-rtc-rv3028-Add-backup-switchover-mode-support.patch b/target/linux/bcm27xx/patches-5.15/950-0117-rtc-rv3028-Add-backup-switchover-mode-support.patch deleted file mode 100644 index bf62a3319..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0117-rtc-rv3028-Add-backup-switchover-mode-support.patch +++ /dev/null @@ -1,50 +0,0 @@ -From aaf2a1e8450ce447683d3a7daec5644e72252db8 Mon Sep 17 00:00:00 2001 -From: Phil Howard -Date: Fri, 29 Mar 2019 10:53:14 +0000 -Subject: [PATCH] rtc: rv3028: Add backup switchover mode support - -Signed-off-by: Phil Howard ---- - drivers/rtc/rtc-rv3028.c | 17 +++++++++++++++++ - 1 file changed, 17 insertions(+) - ---- a/drivers/rtc/rtc-rv3028.c -+++ b/drivers/rtc/rtc-rv3028.c -@@ -80,6 +80,7 @@ - - #define RV3028_BACKUP_TCE BIT(5) - #define RV3028_BACKUP_TCR_MASK GENMASK(1,0) -+#define RV3028_BACKUP_BSM_MASK 0x0C - - #define OFFSET_STEP_PPT 953674 - -@@ -789,6 +790,7 @@ static int rv3028_probe(struct i2c_clien - struct rv3028_data *rv3028; - int ret, status; - u32 ohms; -+ u8 bsm; - struct nvmem_config nvmem_cfg = { - .name = "rv3028_nvram", - .word_size = 1, -@@ -855,6 +857,21 @@ static int rv3028_probe(struct i2c_clien - if (ret) - return ret; - -+ /* setup backup switchover mode */ -+ if (!device_property_read_u8(&client->dev, "backup-switchover-mode", -+ &bsm)) { -+ if (bsm <= 3) { -+ ret = regmap_update_bits(rv3028->regmap, RV3028_BACKUP, -+ RV3028_BACKUP_BSM_MASK, -+ (bsm & 0x03) << 2); -+ -+ if (ret) -+ return ret; -+ } else { -+ dev_warn(&client->dev, "invalid backup switchover mode value\n"); -+ } -+ } -+ - /* setup trickle charger */ - if (!device_property_read_u32(&client->dev, "trickle-resistor-ohms", - &ohms)) { diff --git a/target/linux/bcm27xx/patches-5.15/950-0118-lan78xx-use-default-alignment-for-rx-buffers.patch b/target/linux/bcm27xx/patches-5.15/950-0118-lan78xx-use-default-alignment-for-rx-buffers.patch deleted file mode 100644 index 6bb311b57..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0118-lan78xx-use-default-alignment-for-rx-buffers.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 0b3302cebb33cb64e4cff1c01996b61cec44fc0e Mon Sep 17 00:00:00 2001 -From: P33M -Date: Thu, 2 May 2019 11:53:45 +0100 -Subject: [PATCH] lan78xx: use default alignment for rx buffers - -The lan78xx uses a 12-byte hardware rx header, so there is no need -to allocate SKBs with NET_IP_ALIGN set. Removes alignment faults -in both dwc_otg and in ipv6 processing. ---- - drivers/net/usb/lan78xx.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/usb/lan78xx.c -+++ b/drivers/net/usb/lan78xx.c -@@ -3502,7 +3502,7 @@ static int rx_submit(struct lan78xx_net - size_t size = dev->rx_urb_size; - int ret = 0; - -- skb = netdev_alloc_skb_ip_align(dev->net, size); -+ skb = netdev_alloc_skb(dev->net, size); - if (!skb) { - usb_free_urb(urb); - return -ENOMEM; diff --git a/target/linux/bcm27xx/patches-5.15/950-0120-media-tc358743-fix-connected-active-CSI-2-lane-repor.patch b/target/linux/bcm27xx/patches-5.15/950-0120-media-tc358743-fix-connected-active-CSI-2-lane-repor.patch deleted file mode 100644 index b25b4a259..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0120-media-tc358743-fix-connected-active-CSI-2-lane-repor.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 31fe8b118083aa6caff216fa476ae2393c49df27 Mon Sep 17 00:00:00 2001 -From: Philipp Zabel -Date: Thu, 21 Sep 2017 17:30:24 +0200 -Subject: [PATCH] media: tc358743: fix connected/active CSI-2 lane - reporting - -g_mbus_config was supposed to indicate all supported lane numbers, not -only the number of those currently in active use. Since the TC358743 -can dynamically reduce the number of active lanes if the required -bandwidth allows for it, report all lane numbers up to the connected -number of lanes as supported in pdata mode. -In device tree mode, do not report lane count and clock mode at all, as -the receiver driver can determine these from the device tree. - -To allow communicating the number of currently active lanes, add a new -bitfield to the v4l2_mbus_config flags. This is a temporary fix, to be -used only until a better solution is found. - -Signed-off-by: Philipp Zabel ---- - drivers/media/i2c/tc358743.c | 14 ++++++++++++-- - include/media/v4l2-mediabus.h | 8 ++++++++ - 2 files changed, 20 insertions(+), 2 deletions(-) - ---- a/drivers/media/i2c/tc358743.c -+++ b/drivers/media/i2c/tc358743.c -@@ -1609,11 +1609,20 @@ static int tc358743_get_mbus_config(stru - struct v4l2_mbus_config *cfg) - { - struct tc358743_state *state = to_state(sd); -+ const u32 mask = V4L2_MBUS_CSI2_LANE_MASK; -+ -+ if (state->csi_lanes_in_use > state->bus.num_data_lanes) -+ return -EINVAL; - - cfg->type = V4L2_MBUS_CSI2_DPHY; -+ cfg->flags = (state->csi_lanes_in_use << __ffs(mask)) & mask; -+ -+ /* In DT mode, only report the number of active lanes */ -+ if (sd->dev->of_node) -+ return 0; - -- /* Support for non-continuous CSI-2 clock is missing in the driver */ -- cfg->flags = V4L2_MBUS_CSI2_CONTINUOUS_CLOCK; -+ /* Support for non-continuous CSI-2 clock is missing in pdate mode */ -+ cfg->flags |= V4L2_MBUS_CSI2_CONTINUOUS_CLOCK; - - switch (state->csi_lanes_in_use) { - case 1: -@@ -2056,6 +2065,7 @@ static int tc358743_probe(struct i2c_cli - if (pdata) { - state->pdata = *pdata; - state->bus.flags = V4L2_MBUS_CSI2_CONTINUOUS_CLOCK; -+ state->bus.num_data_lanes = 4; - } else { - err = tc358743_probe_of(state); - if (err == -ENODEV) ---- a/include/media/v4l2-mediabus.h -+++ b/include/media/v4l2-mediabus.h -@@ -92,6 +92,14 @@ - V4L2_MBUS_CSI2_CHANNEL_1 | \ - V4L2_MBUS_CSI2_CHANNEL_2 | \ - V4L2_MBUS_CSI2_CHANNEL_3) -+/* -+ * Number of lanes in use, 0 == use all available lanes (default) -+ * -+ * This is a temporary fix for devices that need to reduce the number of active -+ * lanes for certain modes, until g_mbus_config() can be replaced with a better -+ * solution. -+ */ -+#define V4L2_MBUS_CSI2_LANE_MASK (0xf << 10) - - /** - * enum v4l2_mbus_type - media bus type diff --git a/target/linux/bcm27xx/patches-5.15/950-0146-spi-bcm2835-enable-shared-interrupt-support.patch b/target/linux/bcm27xx/patches-5.15/950-0146-spi-bcm2835-enable-shared-interrupt-support.patch deleted file mode 100644 index 723e44f0e..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0146-spi-bcm2835-enable-shared-interrupt-support.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 81a2bf6bf59e24bac2c9bc6b4a76ecea74d80a11 Mon Sep 17 00:00:00 2001 -From: Martin Sperl -Date: Mon, 13 May 2019 11:05:27 +0000 -Subject: [PATCH] spi: bcm2835: enable shared interrupt support - -Add shared interrupt support for this driver. - -Signed-off-by: Martin Sperl ---- - drivers/spi/spi-bcm2835.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - ---- a/drivers/spi/spi-bcm2835.c -+++ b/drivers/spi/spi-bcm2835.c -@@ -384,6 +384,10 @@ static irqreturn_t bcm2835_spi_interrupt - if (bs->tx_len && cs & BCM2835_SPI_CS_DONE) - bcm2835_wr_fifo_blind(bs, BCM2835_SPI_FIFO_SIZE); - -+ /* check if we got interrupt enabled */ -+ if (!(bcm2835_rd(bs, BCM2835_SPI_CS) & BCM2835_SPI_CS_INTR)) -+ return IRQ_NONE; -+ - /* Read as many bytes as possible from FIFO */ - bcm2835_rd_fifo(bs); - /* Write as many bytes as possible to FIFO */ -@@ -1369,7 +1373,8 @@ static int bcm2835_spi_probe(struct plat - bcm2835_wr(bs, BCM2835_SPI_CS, - BCM2835_SPI_CS_CLEAR_RX | BCM2835_SPI_CS_CLEAR_TX); - -- err = devm_request_irq(&pdev->dev, bs->irq, bcm2835_spi_interrupt, 0, -+ err = devm_request_irq(&pdev->dev, bs->irq, bcm2835_spi_interrupt, -+ IRQF_SHARED, - dev_name(&pdev->dev), bs); - if (err) { - dev_err(&pdev->dev, "could not request IRQ: %d\n", err); diff --git a/target/linux/bcm27xx/patches-5.15/950-0148-soc-bcm-bcm2835-pm-Add-support-for-2711.patch b/target/linux/bcm27xx/patches-5.15/950-0148-soc-bcm-bcm2835-pm-Add-support-for-2711.patch deleted file mode 100644 index fd006e59a..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0148-soc-bcm-bcm2835-pm-Add-support-for-2711.patch +++ /dev/null @@ -1,102 +0,0 @@ -From 9c20d47206de1b7ac78c8186dbb717751100eac6 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Fri, 11 Jan 2019 17:31:07 -0800 -Subject: [PATCH] soc: bcm: bcm2835-pm: Add support for 2711. - -Without the actual power management part any more, there's a lot less -to set up for V3D. We just need to clear the RSTN field for the power -domain, and expose the reset controller for toggling it again. - -This is definitely incomplete -- the old ISP and H264 is in the old -bridge, but since we have no consumers of it I've just done the -minimum to get V3D working. - -Signed-off-by: Eric Anholt ---- - drivers/mfd/bcm2835-pm.c | 11 +++++++++++ - drivers/soc/bcm/bcm2835-power.c | 22 ++++++++++++++++++++++ - include/linux/mfd/bcm2835-pm.h | 1 + - 3 files changed, 34 insertions(+) - ---- a/drivers/mfd/bcm2835-pm.c -+++ b/drivers/mfd/bcm2835-pm.c -@@ -50,6 +50,17 @@ static int bcm2835_pm_probe(struct platf - if (ret) - return ret; - -+ /* Map the ARGON ASB regs if present. */ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 2); -+ if (res) { -+ pm->arg_asb = devm_ioremap_resource(dev, res); -+ if (IS_ERR(pm->arg_asb)) { -+ dev_err(dev, "Failed to map ARGON ASB: %ld\n", -+ PTR_ERR(pm->arg_asb)); -+ return PTR_ERR(pm->arg_asb); -+ } -+ } -+ - /* We'll use the presence of the AXI ASB regs in the - * bcm2835-pm binding as the key for whether we can reference - * the full PM register range and support power domains. ---- a/drivers/soc/bcm/bcm2835-power.c -+++ b/drivers/soc/bcm/bcm2835-power.c -@@ -143,6 +143,8 @@ struct bcm2835_power { - /* AXI Async bridge registers. */ - void __iomem *asb; - -+ bool is_2711; -+ - struct genpd_onecell_data pd_xlate; - struct bcm2835_power_domain domains[BCM2835_POWER_DOMAIN_COUNT]; - struct reset_controller_dev reset; -@@ -192,6 +194,10 @@ static int bcm2835_power_power_off(struc - { - struct bcm2835_power *power = pd->power; - -+ /* 2711 has no power domains above the reset controller. */ -+ if (power->is_2711) -+ return 0; -+ - /* Enable functional isolation */ - PM_WRITE(pm_reg, PM_READ(pm_reg) & ~PM_ISFUNC); - -@@ -213,6 +219,10 @@ static int bcm2835_power_power_on(struct - int inrush; - bool powok; - -+ /* 2711 has no power domains above the reset controller. */ -+ if (power->is_2711) -+ return 0; -+ - /* If it was already powered on by the fw, leave it that way. */ - if (PM_READ(pm_reg) & PM_POWUP) - return 0; -@@ -627,6 +637,18 @@ static int bcm2835_power_probe(struct pl - power->base = pm->base; - power->asb = pm->asb; - -+ /* 2711 hack: the new ARGON ASB took over V3D, which is our -+ * only consumer of this driver so far. The old ASB seems to -+ * still be present with ISP and H264 bits but no V3D, but I -+ * don't know if that's real or not. The V3D is in the same -+ * place in the new ASB as the old one, so just poke the new -+ * one for now. -+ */ -+ if (pm->arg_asb) { -+ power->asb = pm->arg_asb; -+ power->is_2711 = true; -+ } -+ - id = ASB_READ(ASB_AXI_BRDG_ID); - if (id != 0x62726467 /* "BRDG" */) { - dev_err(dev, "ASB register ID returned 0x%08x\n", id); ---- a/include/linux/mfd/bcm2835-pm.h -+++ b/include/linux/mfd/bcm2835-pm.h -@@ -9,6 +9,7 @@ struct bcm2835_pm { - struct device *dev; - void __iomem *base; - void __iomem *asb; -+ void __iomem *arg_asb; - }; - - #endif /* BCM2835_MFD_PM_H */ diff --git a/target/linux/bcm27xx/patches-5.15/950-0155-drm-v3d-Add-support-for-2711.patch b/target/linux/bcm27xx/patches-5.15/950-0155-drm-v3d-Add-support-for-2711.patch deleted file mode 100644 index 4bc8cd03e..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0155-drm-v3d-Add-support-for-2711.patch +++ /dev/null @@ -1,20 +0,0 @@ -From c9c8772ef6ae86678a793d168129866bdc0a92cc Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Thu, 4 Oct 2018 17:22:43 -0700 -Subject: [PATCH] drm/v3d: Add support for 2711. - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/v3d/v3d_drv.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/gpu/drm/v3d/v3d_drv.c -+++ b/drivers/gpu/drm/v3d/v3d_drv.c -@@ -199,6 +199,7 @@ static const struct drm_driver v3d_drm_d - static const struct of_device_id v3d_of_match[] = { - { .compatible = "brcm,7268-v3d" }, - { .compatible = "brcm,7278-v3d" }, -+ { .compatible = "brcm,2711-v3d" }, - {}, - }; - MODULE_DEVICE_TABLE(of, v3d_of_match); diff --git a/target/linux/bcm27xx/patches-5.15/950-0156-drm-v3d-Skip-MMU-flush-if-the-device-is-currently-of.patch b/target/linux/bcm27xx/patches-5.15/950-0156-drm-v3d-Skip-MMU-flush-if-the-device-is-currently-of.patch deleted file mode 100644 index 166446959..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0156-drm-v3d-Skip-MMU-flush-if-the-device-is-currently-of.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 15d0d4bb7c817c3cbcdb276d911b9e93a0c825e9 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Mon, 14 Jan 2019 12:35:43 -0800 -Subject: [PATCH] drm/v3d: Skip MMU flush if the device is currently - off. - -If it's off, we know it will be reset on poweron, so the MMU won't -have any TLB cached from before this point. Avoids failed waits for -MMU flush to reply. - -Signed-off-by: Eric Anholt -(cherry picked from commit 3ee4e2e0a9e9587eacbb69b067bbc72ab2cdc47b) ---- - drivers/gpu/drm/v3d/v3d_mmu.c | 13 +++++++++++++ - 1 file changed, 13 insertions(+) - ---- a/drivers/gpu/drm/v3d/v3d_mmu.c -+++ b/drivers/gpu/drm/v3d/v3d_mmu.c -@@ -18,6 +18,8 @@ - * each client. This is not yet implemented. - */ - -+#include -+ - #include "v3d_drv.h" - #include "v3d_regs.h" - -@@ -34,6 +36,14 @@ static int v3d_mmu_flush_all(struct v3d_ - { - int ret; - -+ /* Keep power on the device on until we're done with this -+ * call, but skip the flush if the device is off and will be -+ * reset when powered back on. -+ */ -+ ret = pm_runtime_get_if_in_use(v3d->dev); -+ if (ret == 0) -+ return 0; -+ - /* Make sure that another flush isn't already running when we - * start this one. - */ -@@ -61,6 +71,9 @@ static int v3d_mmu_flush_all(struct v3d_ - if (ret) - dev_err(v3d->drm.dev, "MMUC flush wait idle failed\n"); - -+ pm_runtime_mark_last_busy(v3d->dev); -+ pm_runtime_put_autosuspend(v3d->dev); -+ - return ret; - } - diff --git a/target/linux/bcm27xx/patches-5.15/950-0157-drm-v3d-Hook-up-the-runtime-PM-ops.patch b/target/linux/bcm27xx/patches-5.15/950-0157-drm-v3d-Hook-up-the-runtime-PM-ops.patch deleted file mode 100644 index 128868000..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0157-drm-v3d-Hook-up-the-runtime-PM-ops.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 9d058ec3839e19637efc1957cdbbdafd69878acb Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Mon, 14 Jan 2019 14:47:57 -0800 -Subject: [PATCH] drm/v3d: Hook up the runtime PM ops. - -In translating the runtime PM code from vc4, I missed the ".pm" -assignment to actually connect them up. Fixes missing MMU setup if -runtime PM resets V3D. - -Signed-off-by: Eric Anholt -(cherry picked from commit ca197699af29baa8236c74c53d4904ca8957ee06) ---- - drivers/gpu/drm/v3d/v3d_drv.c | 37 +++++++++++++++++++++++++++++++++++ - 1 file changed, 37 insertions(+) - ---- a/drivers/gpu/drm/v3d/v3d_drv.c -+++ b/drivers/gpu/drm/v3d/v3d_drv.c -@@ -38,6 +38,42 @@ - #define DRIVER_MINOR 0 - #define DRIVER_PATCHLEVEL 0 - -+#ifdef CONFIG_PM -+static int v3d_runtime_suspend(struct device *dev) -+{ -+ struct drm_device *drm = dev_get_drvdata(dev); -+ struct v3d_dev *v3d = to_v3d_dev(drm); -+ -+ v3d_irq_disable(v3d); -+ -+ clk_disable_unprepare(v3d->clk); -+ -+ return 0; -+} -+ -+static int v3d_runtime_resume(struct device *dev) -+{ -+ struct drm_device *drm = dev_get_drvdata(dev); -+ struct v3d_dev *v3d = to_v3d_dev(drm); -+ int ret; -+ -+ ret = clk_prepare_enable(v3d->clk); -+ if (ret != 0) -+ return ret; -+ -+ /* XXX: VPM base */ -+ -+ v3d_mmu_set_page_table(v3d); -+ v3d_irq_enable(v3d); -+ -+ return 0; -+} -+#endif -+ -+static const struct dev_pm_ops v3d_pm_ops = { -+ SET_RUNTIME_PM_OPS(v3d_runtime_suspend, v3d_runtime_resume, NULL) -+}; -+ - static int v3d_get_param_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) - { -@@ -332,6 +368,7 @@ static struct platform_driver v3d_platfo - .driver = { - .name = "v3d", - .of_match_table = v3d_of_match, -+ .pm = &v3d_pm_ops, - }, - }; - diff --git a/target/linux/bcm27xx/patches-5.15/950-0160-drm-v3d-HACK-gut-runtime-pm-for-now.patch b/target/linux/bcm27xx/patches-5.15/950-0160-drm-v3d-HACK-gut-runtime-pm-for-now.patch deleted file mode 100644 index dabf4c0ec..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0160-drm-v3d-HACK-gut-runtime-pm-for-now.patch +++ /dev/null @@ -1,109 +0,0 @@ -From b0f7366704c0da4e0be8f8df887378717acf135b Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Mon, 14 Jan 2019 15:13:17 -0800 -Subject: [PATCH] drm/v3d: HACK: gut runtime pm for now. - -Something is still unstable -- on starting a new glxgears from an idle -X11, I get an MMU violation in high addresses. The CTS also failed -quite quickly. With this, CTS progresses for an hour before OOMing -(allocating some big buffers when my board only has 600MB available to -Linux) - -Signed-off-by: Eric Anholt ---- - drivers/gpu/drm/v3d/v3d_debugfs.c | 16 +--------------- - drivers/gpu/drm/v3d/v3d_drv.c | 9 --------- - 2 files changed, 1 insertion(+), 24 deletions(-) - ---- a/drivers/gpu/drm/v3d/v3d_debugfs.c -+++ b/drivers/gpu/drm/v3d/v3d_debugfs.c -@@ -4,7 +4,6 @@ - #include - #include - #include --#include - #include - - #include -@@ -130,11 +129,8 @@ static int v3d_v3d_debugfs_ident(struct - struct drm_device *dev = node->minor->dev; - struct v3d_dev *v3d = to_v3d_dev(dev); - u32 ident0, ident1, ident2, ident3, cores; -- int ret, core; -+ int core; - -- ret = pm_runtime_get_sync(v3d->drm.dev); -- if (ret < 0) -- return ret; - - ident0 = V3D_READ(V3D_HUB_IDENT0); - ident1 = V3D_READ(V3D_HUB_IDENT1); -@@ -187,9 +183,6 @@ static int v3d_v3d_debugfs_ident(struct - (misccfg & V3D_MISCCFG_OVRTMUOUT) != 0); - } - -- pm_runtime_mark_last_busy(v3d->drm.dev); -- pm_runtime_put_autosuspend(v3d->drm.dev); -- - return 0; - } - -@@ -217,11 +210,6 @@ static int v3d_measure_clock(struct seq_ - uint32_t cycles; - int core = 0; - int measure_ms = 1000; -- int ret; -- -- ret = pm_runtime_get_sync(v3d->drm.dev); -- if (ret < 0) -- return ret; - - if (v3d->ver >= 40) { - V3D_CORE_WRITE(core, V3D_V4_PCTR_0_SRC_0_3, -@@ -245,8 +233,6 @@ static int v3d_measure_clock(struct seq_ - cycles / (measure_ms * 1000), - (cycles / (measure_ms * 100)) % 10); - -- pm_runtime_mark_last_busy(v3d->drm.dev); -- pm_runtime_put_autosuspend(v3d->drm.dev); - - return 0; - } ---- a/drivers/gpu/drm/v3d/v3d_drv.c -+++ b/drivers/gpu/drm/v3d/v3d_drv.c -@@ -79,7 +79,6 @@ static int v3d_get_param_ioctl(struct dr - { - struct v3d_dev *v3d = to_v3d_dev(dev); - struct drm_v3d_get_param *args = data; -- int ret; - static const u32 reg_map[] = { - [DRM_V3D_PARAM_V3D_UIFCFG] = V3D_HUB_UIFCFG, - [DRM_V3D_PARAM_V3D_HUB_IDENT1] = V3D_HUB_IDENT1, -@@ -105,17 +104,12 @@ static int v3d_get_param_ioctl(struct dr - if (args->value != 0) - return -EINVAL; - -- ret = pm_runtime_get_sync(v3d->drm.dev); -- if (ret < 0) -- return ret; - if (args->param >= DRM_V3D_PARAM_V3D_CORE0_IDENT0 && - args->param <= DRM_V3D_PARAM_V3D_CORE0_IDENT2) { - args->value = V3D_CORE_READ(0, offset); - } else { - args->value = V3D_READ(offset); - } -- pm_runtime_mark_last_busy(v3d->drm.dev); -- pm_runtime_put_autosuspend(v3d->drm.dev); - return 0; - } - -@@ -320,9 +314,6 @@ static int v3d_platform_drm_probe(struct - return -ENOMEM; - } - -- pm_runtime_use_autosuspend(dev); -- pm_runtime_set_autosuspend_delay(dev, 50); -- pm_runtime_enable(dev); - - ret = v3d_gem_init(drm); - if (ret) diff --git a/target/linux/bcm27xx/patches-5.15/950-0164-Add-HDMI1-facility-to-the-driver.patch b/target/linux/bcm27xx/patches-5.15/950-0164-Add-HDMI1-facility-to-the-driver.patch deleted file mode 100644 index 30bcd5880..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0164-Add-HDMI1-facility-to-the-driver.patch +++ /dev/null @@ -1,85 +0,0 @@ -From c22955161cfe7f3c10ff0ee4b1ff296c5bee9496 Mon Sep 17 00:00:00 2001 -From: James Hughes -Date: Tue, 16 Jul 2019 12:18:21 +0100 -Subject: [PATCH] Add HDMI1 facility to the driver. - -For generic ALSA, all you need is the bcm2835.h change, but -have also added structures for IEC958 HDMI. Not sure how to -test those. ---- - .../vc04_services/bcm2835-audio/bcm2835.c | 29 ++++++++++++++++--- - .../vc04_services/bcm2835-audio/bcm2835.h | 4 ++- - 2 files changed, 28 insertions(+), 5 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c -@@ -79,7 +79,11 @@ static int bcm2835_audio_alsa_newpcm(str - if (err) - return err; - -- err = snd_bcm2835_new_pcm(chip, "bcm2835 IEC958/HDMI", 1, 0, 1, true); -+ err = snd_bcm2835_new_pcm(chip, "bcm2835 IEC958/HDMI", 1, AUDIO_DEST_HDMI0, 1, true); -+ if (err) -+ return err; -+ -+ err = snd_bcm2835_new_pcm(chip, "bcm2835 IEC958/HDMI1", 2, AUDIO_DEST_HDMI1, 1, true); - if (err) - return err; - -@@ -106,7 +110,7 @@ static struct bcm2835_audio_driver bcm28 - .newctl = snd_bcm2835_new_ctl, - }; - --static struct bcm2835_audio_driver bcm2835_audio_hdmi = { -+static struct bcm2835_audio_driver bcm2835_audio_hdmi0 = { - .driver = { - .name = "bcm2835_hdmi", - .owner = THIS_MODULE, -@@ -116,7 +120,20 @@ static struct bcm2835_audio_driver bcm28 - .minchannels = 1, - .newpcm = bcm2835_audio_simple_newpcm, - .newctl = snd_bcm2835_new_hdmi_ctl, -- .route = AUDIO_DEST_HDMI -+ .route = AUDIO_DEST_HDMI0 -+}; -+ -+static struct bcm2835_audio_driver bcm2835_audio_hdmi1 = { -+ .driver = { -+ .name = "bcm2835_hdmi", -+ .owner = THIS_MODULE, -+ }, -+ .shortname = "bcm2835 HDMI 1", -+ .longname = "bcm2835 HDMI 1", -+ .minchannels = 1, -+ .newpcm = bcm2835_audio_simple_newpcm, -+ .newctl = snd_bcm2835_new_hdmi_ctl, -+ .route = AUDIO_DEST_HDMI1 - }; - - static struct bcm2835_audio_driver bcm2835_audio_headphones = { -@@ -143,7 +160,11 @@ static struct bcm2835_audio_drivers chil - .is_enabled = &enable_compat_alsa, - }, - { -- .audio_driver = &bcm2835_audio_hdmi, -+ .audio_driver = &bcm2835_audio_hdmi0, -+ .is_enabled = &enable_hdmi, -+ }, -+ { -+ .audio_driver = &bcm2835_audio_hdmi1, - .is_enabled = &enable_hdmi, - }, - { ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h -@@ -33,7 +33,9 @@ enum { - enum snd_bcm2835_route { - AUDIO_DEST_AUTO = 0, - AUDIO_DEST_HEADPHONES = 1, -- AUDIO_DEST_HDMI = 2, -+ AUDIO_DEST_HDMI = 2, // for backwards compatibility. -+ AUDIO_DEST_HDMI0 = 2, -+ AUDIO_DEST_HDMI1 = 3, - AUDIO_DEST_MAX, - }; - diff --git a/target/linux/bcm27xx/patches-5.15/950-0167-configs-arm64-bcm2711-Enable-V3D.patch b/target/linux/bcm27xx/patches-5.15/950-0167-configs-arm64-bcm2711-Enable-V3D.patch deleted file mode 100644 index 0ba6078f4..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0167-configs-arm64-bcm2711-Enable-V3D.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 98631cef94563d6857f4133e7917f234be8667bd Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 15 Aug 2019 12:02:34 +0100 -Subject: [PATCH] configs: arm64/bcm2711: Enable V3D - -Enable the V3D driver, which depends on BCM2835_POWER. - -Originally submitted by GitHub user 'phire' in a slightly different -form. - -See: https://github.com/raspberrypi/linux/pull/3063 - -Signed-off-by: Phil Elwell ---- - drivers/gpu/drm/v3d/Kconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/gpu/drm/v3d/Kconfig -+++ b/drivers/gpu/drm/v3d/Kconfig -@@ -1,7 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0-only - config DRM_V3D - tristate "Broadcom V3D 3.x and newer" -- depends on ARCH_BCM || ARCH_BCMSTB || COMPILE_TEST -+ depends on ARCH_BCM || ARCH_BCMSTB || ARCH_BCM2835 || COMPILE_TEST - depends on DRM - depends on COMMON_CLK - depends on MMU diff --git a/target/linux/bcm27xx/patches-5.15/950-0170-media-dt-bindings-Add-binding-for-the-Sony-IMX219-se.patch b/target/linux/bcm27xx/patches-5.15/950-0170-media-dt-bindings-Add-binding-for-the-Sony-IMX219-se.patch deleted file mode 100644 index 49efff387..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0170-media-dt-bindings-Add-binding-for-the-Sony-IMX219-se.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 3c54a4cdc8c65248c347a02b36ac378fe81379ba Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Wed, 28 Aug 2019 13:34:30 +0100 -Subject: [PATCH] media: dt-bindings: Add binding for the Sony IMX219 - sensor - -The IMX219 is an 8MPix CSI2 sensor, supporting 2 or 4 data lanes. -Document the binding for this device. - -Signed-off-by: Dave Stevenson ---- - .../devicetree/bindings/media/i2c/imx219.txt | 59 +++++++++++++++++++ - 1 file changed, 59 insertions(+) - create mode 100644 Documentation/devicetree/bindings/media/i2c/imx219.txt - ---- /dev/null -+++ b/Documentation/devicetree/bindings/media/i2c/imx219.txt -@@ -0,0 +1,59 @@ -+* Sony 1/4.0-Inch 8Mpixel CMOS Digital Image Sensor -+ -+The Sony imx219 is a 1/4.0-inch CMOS active pixel digital image sensor with -+an active array size of 3280H x 2464V. It is programmable through I2C -+interface. The I2C address is fixed to 0x10 as per sensor data sheet. -+Image data is sent through MIPI CSI-2, which is configured as either 2 or 4 -+data lanes. -+ -+Required Properties: -+- compatible: value should be "sony,imx219" for imx219 sensor -+- reg: I2C bus address of the device -+- clocks: reference to the xclk input clock. -+- clock-names: should be "xclk". -+- DOVDD-supply: Digital I/O voltage supply, 1.8 volts -+- AVDD-supply: Analog voltage supply, 2.8 volts -+- DVDD-supply: Digital core voltage supply, 1.2 volts -+ -+Optional Properties: -+- xclr-gpios: reference to the GPIO connected to the xclr pin, if any. Must be -+ released after all supplies are applied. -+ This is an active high signal to the imx219. -+ -+The imx219 device node should contain one 'port' child node with -+an 'endpoint' subnode. For further reading on port node refer to -+Documentation/devicetree/bindings/media/video-interfaces.txt. -+ -+Endpoint node required properties for CSI-2 connection are: -+- remote-endpoint: a phandle to the bus receiver's endpoint node. -+- clock-lanes: should be set to <0> (clock lane on hardware lane 0) -+- data-lanes: should be set to <1 2>, or <1 2 3 4> (two or four lane CSI-2 -+ supported) -+ -+Example: -+ sensor@10 { -+ compatible = "sony,imx219"; -+ reg = <0x10>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ clocks = <&imx219_clk>; -+ clock-names = "xclk"; -+ xclr-gpios = <&gpio_sensor 0 0>; -+ DOVDD-supply = <&vgen4_reg>; /* 1.8v */ -+ AVDD-supply = <&vgen3_reg>; /* 2.8v */ -+ DVDD-supply = <&vgen2_reg>; /* 1.2v */ -+ -+ imx219_clk: camera-clk { -+ compatible = "fixed-clock"; -+ #clock-cells = <0>; -+ clock-frequency = <24000000>; -+ }; -+ -+ port { -+ sensor_out: endpoint { -+ remote-endpoint = <&csiss_in>; -+ clock-lanes = <0>; -+ data-lanes = <1 2>; -+ }; -+ }; -+ }; diff --git a/target/linux/bcm27xx/patches-5.15/950-0171-v4l2-Add-a-Greyworld-AWB-mode.patch b/target/linux/bcm27xx/patches-5.15/950-0171-v4l2-Add-a-Greyworld-AWB-mode.patch deleted file mode 100644 index 3f7a2aa6b..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0171-v4l2-Add-a-Greyworld-AWB-mode.patch +++ /dev/null @@ -1,5064 +0,0 @@ -From 8b666c067e3a52f960e0e6112451596d8b1c672f Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Fri, 6 Sep 2019 15:04:51 +0100 -Subject: [PATCH] v4l2: Add a Greyworld AWB mode. - -Adds a simple greyworld white balance preset, mainly for use -with cameras without an IR filter (eg Raspberry Pi NoIR) - -Signed-off-by: Dave Stevenson ---- - drivers/media/v4l2-core/v4l2-ctrls.c | 5036 ++++++++++++++++++++++++++ - include/uapi/linux/v4l2-controls.h | 1 + - 2 files changed, 5037 insertions(+) - create mode 100644 drivers/media/v4l2-core/v4l2-ctrls.c - ---- /dev/null -+++ b/drivers/media/v4l2-core/v4l2-ctrls.c -@@ -0,0 +1,5036 @@ -+// SPDX-License-Identifier: GPL-2.0-or-later -+/* -+ V4L2 controls framework implementation. -+ -+ Copyright (C) 2010 Hans Verkuil -+ -+ */ -+ -+#define pr_fmt(fmt) "v4l2-ctrls: " fmt -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define dprintk(vdev, fmt, arg...) do { \ -+ if (!WARN_ON(!(vdev)) && ((vdev)->dev_debug & V4L2_DEV_DEBUG_CTRL)) \ -+ printk(KERN_DEBUG pr_fmt("%s: %s: " fmt), \ -+ __func__, video_device_node_name(vdev), ##arg); \ -+} while (0) -+ -+#define has_op(master, op) \ -+ (master->ops && master->ops->op) -+#define call_op(master, op) \ -+ (has_op(master, op) ? master->ops->op(master) : 0) -+ -+static const union v4l2_ctrl_ptr ptr_null; -+ -+/* Internal temporary helper struct, one for each v4l2_ext_control */ -+struct v4l2_ctrl_helper { -+ /* Pointer to the control reference of the master control */ -+ struct v4l2_ctrl_ref *mref; -+ /* The control ref corresponding to the v4l2_ext_control ID field. */ -+ struct v4l2_ctrl_ref *ref; -+ /* v4l2_ext_control index of the next control belonging to the -+ same cluster, or 0 if there isn't any. */ -+ u32 next; -+}; -+ -+/* Small helper function to determine if the autocluster is set to manual -+ mode. */ -+static bool is_cur_manual(const struct v4l2_ctrl *master) -+{ -+ return master->is_auto && master->cur.val == master->manual_mode_value; -+} -+ -+/* Same as above, but this checks the against the new value instead of the -+ current value. */ -+static bool is_new_manual(const struct v4l2_ctrl *master) -+{ -+ return master->is_auto && master->val == master->manual_mode_value; -+} -+ -+/* Returns NULL or a character pointer array containing the menu for -+ the given control ID. The pointer array ends with a NULL pointer. -+ An empty string signifies a menu entry that is invalid. This allows -+ drivers to disable certain options if it is not supported. */ -+const char * const *v4l2_ctrl_get_menu(u32 id) -+{ -+ static const char * const mpeg_audio_sampling_freq[] = { -+ "44.1 kHz", -+ "48 kHz", -+ "32 kHz", -+ NULL -+ }; -+ static const char * const mpeg_audio_encoding[] = { -+ "MPEG-1/2 Layer I", -+ "MPEG-1/2 Layer II", -+ "MPEG-1/2 Layer III", -+ "MPEG-2/4 AAC", -+ "AC-3", -+ NULL -+ }; -+ static const char * const mpeg_audio_l1_bitrate[] = { -+ "32 kbps", -+ "64 kbps", -+ "96 kbps", -+ "128 kbps", -+ "160 kbps", -+ "192 kbps", -+ "224 kbps", -+ "256 kbps", -+ "288 kbps", -+ "320 kbps", -+ "352 kbps", -+ "384 kbps", -+ "416 kbps", -+ "448 kbps", -+ NULL -+ }; -+ static const char * const mpeg_audio_l2_bitrate[] = { -+ "32 kbps", -+ "48 kbps", -+ "56 kbps", -+ "64 kbps", -+ "80 kbps", -+ "96 kbps", -+ "112 kbps", -+ "128 kbps", -+ "160 kbps", -+ "192 kbps", -+ "224 kbps", -+ "256 kbps", -+ "320 kbps", -+ "384 kbps", -+ NULL -+ }; -+ static const char * const mpeg_audio_l3_bitrate[] = { -+ "32 kbps", -+ "40 kbps", -+ "48 kbps", -+ "56 kbps", -+ "64 kbps", -+ "80 kbps", -+ "96 kbps", -+ "112 kbps", -+ "128 kbps", -+ "160 kbps", -+ "192 kbps", -+ "224 kbps", -+ "256 kbps", -+ "320 kbps", -+ NULL -+ }; -+ static const char * const mpeg_audio_ac3_bitrate[] = { -+ "32 kbps", -+ "40 kbps", -+ "48 kbps", -+ "56 kbps", -+ "64 kbps", -+ "80 kbps", -+ "96 kbps", -+ "112 kbps", -+ "128 kbps", -+ "160 kbps", -+ "192 kbps", -+ "224 kbps", -+ "256 kbps", -+ "320 kbps", -+ "384 kbps", -+ "448 kbps", -+ "512 kbps", -+ "576 kbps", -+ "640 kbps", -+ NULL -+ }; -+ static const char * const mpeg_audio_mode[] = { -+ "Stereo", -+ "Joint Stereo", -+ "Dual", -+ "Mono", -+ NULL -+ }; -+ static const char * const mpeg_audio_mode_extension[] = { -+ "Bound 4", -+ "Bound 8", -+ "Bound 12", -+ "Bound 16", -+ NULL -+ }; -+ static const char * const mpeg_audio_emphasis[] = { -+ "No Emphasis", -+ "50/15 us", -+ "CCITT J17", -+ NULL -+ }; -+ static const char * const mpeg_audio_crc[] = { -+ "No CRC", -+ "16-bit CRC", -+ NULL -+ }; -+ static const char * const mpeg_audio_dec_playback[] = { -+ "Auto", -+ "Stereo", -+ "Left", -+ "Right", -+ "Mono", -+ "Swapped Stereo", -+ NULL -+ }; -+ static const char * const mpeg_video_encoding[] = { -+ "MPEG-1", -+ "MPEG-2", -+ "MPEG-4 AVC", -+ NULL -+ }; -+ static const char * const mpeg_video_aspect[] = { -+ "1x1", -+ "4x3", -+ "16x9", -+ "2.21x1", -+ NULL -+ }; -+ static const char * const mpeg_video_bitrate_mode[] = { -+ "Variable Bitrate", -+ "Constant Bitrate", -+ "Constant Quality", -+ NULL -+ }; -+ static const char * const mpeg_stream_type[] = { -+ "MPEG-2 Program Stream", -+ "MPEG-2 Transport Stream", -+ "MPEG-1 System Stream", -+ "MPEG-2 DVD-compatible Stream", -+ "MPEG-1 VCD-compatible Stream", -+ "MPEG-2 SVCD-compatible Stream", -+ NULL -+ }; -+ static const char * const mpeg_stream_vbi_fmt[] = { -+ "No VBI", -+ "Private Packet, IVTV Format", -+ NULL -+ }; -+ static const char * const camera_power_line_frequency[] = { -+ "Disabled", -+ "50 Hz", -+ "60 Hz", -+ "Auto", -+ NULL -+ }; -+ static const char * const camera_exposure_auto[] = { -+ "Auto Mode", -+ "Manual Mode", -+ "Shutter Priority Mode", -+ "Aperture Priority Mode", -+ NULL -+ }; -+ static const char * const camera_exposure_metering[] = { -+ "Average", -+ "Center Weighted", -+ "Spot", -+ "Matrix", -+ NULL -+ }; -+ static const char * const camera_auto_focus_range[] = { -+ "Auto", -+ "Normal", -+ "Macro", -+ "Infinity", -+ NULL -+ }; -+ static const char * const colorfx[] = { -+ "None", -+ "Black & White", -+ "Sepia", -+ "Negative", -+ "Emboss", -+ "Sketch", -+ "Sky Blue", -+ "Grass Green", -+ "Skin Whiten", -+ "Vivid", -+ "Aqua", -+ "Art Freeze", -+ "Silhouette", -+ "Solarization", -+ "Antique", -+ "Set Cb/Cr", -+ NULL -+ }; -+ static const char * const auto_n_preset_white_balance[] = { -+ "Manual", -+ "Auto", -+ "Incandescent", -+ "Fluorescent", -+ "Fluorescent H", -+ "Horizon", -+ "Daylight", -+ "Flash", -+ "Cloudy", -+ "Shade", -+ "Greyworld", -+ NULL, -+ }; -+ static const char * const camera_iso_sensitivity_auto[] = { -+ "Manual", -+ "Auto", -+ NULL -+ }; -+ static const char * const scene_mode[] = { -+ "None", -+ "Backlight", -+ "Beach/Snow", -+ "Candle Light", -+ "Dusk/Dawn", -+ "Fall Colors", -+ "Fireworks", -+ "Landscape", -+ "Night", -+ "Party/Indoor", -+ "Portrait", -+ "Sports", -+ "Sunset", -+ "Text", -+ NULL -+ }; -+ static const char * const tune_emphasis[] = { -+ "None", -+ "50 Microseconds", -+ "75 Microseconds", -+ NULL, -+ }; -+ static const char * const header_mode[] = { -+ "Separate Buffer", -+ "Joined With 1st Frame", -+ NULL, -+ }; -+ static const char * const multi_slice[] = { -+ "Single", -+ "Max Macroblocks", -+ "Max Bytes", -+ NULL, -+ }; -+ static const char * const entropy_mode[] = { -+ "CAVLC", -+ "CABAC", -+ NULL, -+ }; -+ static const char * const mpeg_h264_level[] = { -+ "1", -+ "1b", -+ "1.1", -+ "1.2", -+ "1.3", -+ "2", -+ "2.1", -+ "2.2", -+ "3", -+ "3.1", -+ "3.2", -+ "4", -+ "4.1", -+ "4.2", -+ "5", -+ "5.1", -+ "5.2", -+ "6.0", -+ "6.1", -+ "6.2", -+ NULL, -+ }; -+ static const char * const h264_loop_filter[] = { -+ "Enabled", -+ "Disabled", -+ "Disabled at Slice Boundary", -+ NULL, -+ }; -+ static const char * const h264_profile[] = { -+ "Baseline", -+ "Constrained Baseline", -+ "Main", -+ "Extended", -+ "High", -+ "High 10", -+ "High 422", -+ "High 444 Predictive", -+ "High 10 Intra", -+ "High 422 Intra", -+ "High 444 Intra", -+ "CAVLC 444 Intra", -+ "Scalable Baseline", -+ "Scalable High", -+ "Scalable High Intra", -+ "Stereo High", -+ "Multiview High", -+ "Constrained High", -+ NULL, -+ }; -+ static const char * const vui_sar_idc[] = { -+ "Unspecified", -+ "1:1", -+ "12:11", -+ "10:11", -+ "16:11", -+ "40:33", -+ "24:11", -+ "20:11", -+ "32:11", -+ "80:33", -+ "18:11", -+ "15:11", -+ "64:33", -+ "160:99", -+ "4:3", -+ "3:2", -+ "2:1", -+ "Extended SAR", -+ NULL, -+ }; -+ static const char * const h264_fp_arrangement_type[] = { -+ "Checkerboard", -+ "Column", -+ "Row", -+ "Side by Side", -+ "Top Bottom", -+ "Temporal", -+ NULL, -+ }; -+ static const char * const h264_fmo_map_type[] = { -+ "Interleaved Slices", -+ "Scattered Slices", -+ "Foreground with Leftover", -+ "Box Out", -+ "Raster Scan", -+ "Wipe Scan", -+ "Explicit", -+ NULL, -+ }; -+ static const char * const h264_decode_mode[] = { -+ "Slice-Based", -+ "Frame-Based", -+ NULL, -+ }; -+ static const char * const h264_start_code[] = { -+ "No Start Code", -+ "Annex B Start Code", -+ NULL, -+ }; -+ static const char * const h264_hierarchical_coding_type[] = { -+ "Hier Coding B", -+ "Hier Coding P", -+ NULL, -+ }; -+ static const char * const mpeg_mpeg2_level[] = { -+ "Low", -+ "Main", -+ "High 1440", -+ "High", -+ NULL, -+ }; -+ static const char * const mpeg2_profile[] = { -+ "Simple", -+ "Main", -+ "SNR Scalable", -+ "Spatially Scalable", -+ "High", -+ NULL, -+ }; -+ static const char * const mpeg_mpeg4_level[] = { -+ "0", -+ "0b", -+ "1", -+ "2", -+ "3", -+ "3b", -+ "4", -+ "5", -+ NULL, -+ }; -+ static const char * const mpeg4_profile[] = { -+ "Simple", -+ "Advanced Simple", -+ "Core", -+ "Simple Scalable", -+ "Advanced Coding Efficiency", -+ NULL, -+ }; -+ -+ static const char * const vpx_golden_frame_sel[] = { -+ "Use Previous Frame", -+ "Use Previous Specific Frame", -+ NULL, -+ }; -+ static const char * const vp8_profile[] = { -+ "0", -+ "1", -+ "2", -+ "3", -+ NULL, -+ }; -+ static const char * const vp9_profile[] = { -+ "0", -+ "1", -+ "2", -+ "3", -+ NULL, -+ }; -+ static const char * const vp9_level[] = { -+ "1", -+ "1.1", -+ "2", -+ "2.1", -+ "3", -+ "3.1", -+ "4", -+ "4.1", -+ "5", -+ "5.1", -+ "5.2", -+ "6", -+ "6.1", -+ "6.2", -+ NULL, -+ }; -+ -+ static const char * const flash_led_mode[] = { -+ "Off", -+ "Flash", -+ "Torch", -+ NULL, -+ }; -+ static const char * const flash_strobe_source[] = { -+ "Software", -+ "External", -+ NULL, -+ }; -+ -+ static const char * const jpeg_chroma_subsampling[] = { -+ "4:4:4", -+ "4:2:2", -+ "4:2:0", -+ "4:1:1", -+ "4:1:0", -+ "Gray", -+ NULL, -+ }; -+ static const char * const dv_tx_mode[] = { -+ "DVI-D", -+ "HDMI", -+ NULL, -+ }; -+ static const char * const dv_rgb_range[] = { -+ "Automatic", -+ "RGB Limited Range (16-235)", -+ "RGB Full Range (0-255)", -+ NULL, -+ }; -+ static const char * const dv_it_content_type[] = { -+ "Graphics", -+ "Photo", -+ "Cinema", -+ "Game", -+ "No IT Content", -+ NULL, -+ }; -+ static const char * const detect_md_mode[] = { -+ "Disabled", -+ "Global", -+ "Threshold Grid", -+ "Region Grid", -+ NULL, -+ }; -+ -+ static const char * const hevc_profile[] = { -+ "Main", -+ "Main Still Picture", -+ "Main 10", -+ NULL, -+ }; -+ static const char * const hevc_level[] = { -+ "1", -+ "2", -+ "2.1", -+ "3", -+ "3.1", -+ "4", -+ "4.1", -+ "5", -+ "5.1", -+ "5.2", -+ "6", -+ "6.1", -+ "6.2", -+ NULL, -+ }; -+ static const char * const hevc_hierarchial_coding_type[] = { -+ "B", -+ "P", -+ NULL, -+ }; -+ static const char * const hevc_refresh_type[] = { -+ "None", -+ "CRA", -+ "IDR", -+ NULL, -+ }; -+ static const char * const hevc_size_of_length_field[] = { -+ "0", -+ "1", -+ "2", -+ "4", -+ NULL, -+ }; -+ static const char * const hevc_tier[] = { -+ "Main", -+ "High", -+ NULL, -+ }; -+ static const char * const hevc_loop_filter_mode[] = { -+ "Disabled", -+ "Enabled", -+ "Disabled at slice boundary", -+ "NULL", -+ }; -+ static const char * const hevc_decode_mode[] = { -+ "Slice-Based", -+ "Frame-Based", -+ NULL, -+ }; -+ static const char * const hevc_start_code[] = { -+ "No Start Code", -+ "Annex B Start Code", -+ NULL, -+ }; -+ static const char * const camera_orientation[] = { -+ "Front", -+ "Back", -+ "External", -+ NULL, -+ }; -+ static const char * const mpeg_video_frame_skip[] = { -+ "Disabled", -+ "Level Limit", -+ "VBV/CPB Limit", -+ NULL, -+ }; -+ -+ switch (id) { -+ case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: -+ return mpeg_audio_sampling_freq; -+ case V4L2_CID_MPEG_AUDIO_ENCODING: -+ return mpeg_audio_encoding; -+ case V4L2_CID_MPEG_AUDIO_L1_BITRATE: -+ return mpeg_audio_l1_bitrate; -+ case V4L2_CID_MPEG_AUDIO_L2_BITRATE: -+ return mpeg_audio_l2_bitrate; -+ case V4L2_CID_MPEG_AUDIO_L3_BITRATE: -+ return mpeg_audio_l3_bitrate; -+ case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: -+ return mpeg_audio_ac3_bitrate; -+ case V4L2_CID_MPEG_AUDIO_MODE: -+ return mpeg_audio_mode; -+ case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: -+ return mpeg_audio_mode_extension; -+ case V4L2_CID_MPEG_AUDIO_EMPHASIS: -+ return mpeg_audio_emphasis; -+ case V4L2_CID_MPEG_AUDIO_CRC: -+ return mpeg_audio_crc; -+ case V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK: -+ case V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK: -+ return mpeg_audio_dec_playback; -+ case V4L2_CID_MPEG_VIDEO_ENCODING: -+ return mpeg_video_encoding; -+ case V4L2_CID_MPEG_VIDEO_ASPECT: -+ return mpeg_video_aspect; -+ case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: -+ return mpeg_video_bitrate_mode; -+ case V4L2_CID_MPEG_STREAM_TYPE: -+ return mpeg_stream_type; -+ case V4L2_CID_MPEG_STREAM_VBI_FMT: -+ return mpeg_stream_vbi_fmt; -+ case V4L2_CID_POWER_LINE_FREQUENCY: -+ return camera_power_line_frequency; -+ case V4L2_CID_EXPOSURE_AUTO: -+ return camera_exposure_auto; -+ case V4L2_CID_EXPOSURE_METERING: -+ return camera_exposure_metering; -+ case V4L2_CID_AUTO_FOCUS_RANGE: -+ return camera_auto_focus_range; -+ case V4L2_CID_COLORFX: -+ return colorfx; -+ case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE: -+ return auto_n_preset_white_balance; -+ case V4L2_CID_ISO_SENSITIVITY_AUTO: -+ return camera_iso_sensitivity_auto; -+ case V4L2_CID_SCENE_MODE: -+ return scene_mode; -+ case V4L2_CID_TUNE_PREEMPHASIS: -+ return tune_emphasis; -+ case V4L2_CID_TUNE_DEEMPHASIS: -+ return tune_emphasis; -+ case V4L2_CID_FLASH_LED_MODE: -+ return flash_led_mode; -+ case V4L2_CID_FLASH_STROBE_SOURCE: -+ return flash_strobe_source; -+ case V4L2_CID_MPEG_VIDEO_HEADER_MODE: -+ return header_mode; -+ case V4L2_CID_MPEG_VIDEO_FRAME_SKIP_MODE: -+ return mpeg_video_frame_skip; -+ case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE: -+ return multi_slice; -+ case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE: -+ return entropy_mode; -+ case V4L2_CID_MPEG_VIDEO_H264_LEVEL: -+ return mpeg_h264_level; -+ case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE: -+ return h264_loop_filter; -+ case V4L2_CID_MPEG_VIDEO_H264_PROFILE: -+ return h264_profile; -+ case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC: -+ return vui_sar_idc; -+ case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE: -+ return h264_fp_arrangement_type; -+ case V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE: -+ return h264_fmo_map_type; -+ case V4L2_CID_STATELESS_H264_DECODE_MODE: -+ return h264_decode_mode; -+ case V4L2_CID_STATELESS_H264_START_CODE: -+ return h264_start_code; -+ case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE: -+ return h264_hierarchical_coding_type; -+ case V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL: -+ return mpeg_mpeg2_level; -+ case V4L2_CID_MPEG_VIDEO_MPEG2_PROFILE: -+ return mpeg2_profile; -+ case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL: -+ return mpeg_mpeg4_level; -+ case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE: -+ return mpeg4_profile; -+ case V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_SEL: -+ return vpx_golden_frame_sel; -+ case V4L2_CID_MPEG_VIDEO_VP8_PROFILE: -+ return vp8_profile; -+ case V4L2_CID_MPEG_VIDEO_VP9_PROFILE: -+ return vp9_profile; -+ case V4L2_CID_MPEG_VIDEO_VP9_LEVEL: -+ return vp9_level; -+ case V4L2_CID_JPEG_CHROMA_SUBSAMPLING: -+ return jpeg_chroma_subsampling; -+ case V4L2_CID_DV_TX_MODE: -+ return dv_tx_mode; -+ case V4L2_CID_DV_TX_RGB_RANGE: -+ case V4L2_CID_DV_RX_RGB_RANGE: -+ return dv_rgb_range; -+ case V4L2_CID_DV_TX_IT_CONTENT_TYPE: -+ case V4L2_CID_DV_RX_IT_CONTENT_TYPE: -+ return dv_it_content_type; -+ case V4L2_CID_DETECT_MD_MODE: -+ return detect_md_mode; -+ case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE: -+ return hevc_profile; -+ case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL: -+ return hevc_level; -+ case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE: -+ return hevc_hierarchial_coding_type; -+ case V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_TYPE: -+ return hevc_refresh_type; -+ case V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD: -+ return hevc_size_of_length_field; -+ case V4L2_CID_MPEG_VIDEO_HEVC_TIER: -+ return hevc_tier; -+ case V4L2_CID_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE: -+ return hevc_loop_filter_mode; -+ case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE: -+ return hevc_decode_mode; -+ case V4L2_CID_MPEG_VIDEO_HEVC_START_CODE: -+ return hevc_start_code; -+ case V4L2_CID_CAMERA_ORIENTATION: -+ return camera_orientation; -+ default: -+ return NULL; -+ } -+} -+EXPORT_SYMBOL(v4l2_ctrl_get_menu); -+ -+#define __v4l2_qmenu_int_len(arr, len) ({ *(len) = ARRAY_SIZE(arr); arr; }) -+/* -+ * Returns NULL or an s64 type array containing the menu for given -+ * control ID. The total number of the menu items is returned in @len. -+ */ -+const s64 *v4l2_ctrl_get_int_menu(u32 id, u32 *len) -+{ -+ static const s64 qmenu_int_vpx_num_partitions[] = { -+ 1, 2, 4, 8, -+ }; -+ -+ static const s64 qmenu_int_vpx_num_ref_frames[] = { -+ 1, 2, 3, -+ }; -+ -+ switch (id) { -+ case V4L2_CID_MPEG_VIDEO_VPX_NUM_PARTITIONS: -+ return __v4l2_qmenu_int_len(qmenu_int_vpx_num_partitions, len); -+ case V4L2_CID_MPEG_VIDEO_VPX_NUM_REF_FRAMES: -+ return __v4l2_qmenu_int_len(qmenu_int_vpx_num_ref_frames, len); -+ default: -+ *len = 0; -+ return NULL; -+ } -+} -+EXPORT_SYMBOL(v4l2_ctrl_get_int_menu); -+ -+/* Return the control name. */ -+const char *v4l2_ctrl_get_name(u32 id) -+{ -+ switch (id) { -+ /* USER controls */ -+ /* Keep the order of the 'case's the same as in v4l2-controls.h! */ -+ case V4L2_CID_USER_CLASS: return "User Controls"; -+ case V4L2_CID_BRIGHTNESS: return "Brightness"; -+ case V4L2_CID_CONTRAST: return "Contrast"; -+ case V4L2_CID_SATURATION: return "Saturation"; -+ case V4L2_CID_HUE: return "Hue"; -+ case V4L2_CID_AUDIO_VOLUME: return "Volume"; -+ case V4L2_CID_AUDIO_BALANCE: return "Balance"; -+ case V4L2_CID_AUDIO_BASS: return "Bass"; -+ case V4L2_CID_AUDIO_TREBLE: return "Treble"; -+ case V4L2_CID_AUDIO_MUTE: return "Mute"; -+ case V4L2_CID_AUDIO_LOUDNESS: return "Loudness"; -+ case V4L2_CID_BLACK_LEVEL: return "Black Level"; -+ case V4L2_CID_AUTO_WHITE_BALANCE: return "White Balance, Automatic"; -+ case V4L2_CID_DO_WHITE_BALANCE: return "Do White Balance"; -+ case V4L2_CID_RED_BALANCE: return "Red Balance"; -+ case V4L2_CID_BLUE_BALANCE: return "Blue Balance"; -+ case V4L2_CID_GAMMA: return "Gamma"; -+ case V4L2_CID_EXPOSURE: return "Exposure"; -+ case V4L2_CID_AUTOGAIN: return "Gain, Automatic"; -+ case V4L2_CID_GAIN: return "Gain"; -+ case V4L2_CID_HFLIP: return "Horizontal Flip"; -+ case V4L2_CID_VFLIP: return "Vertical Flip"; -+ case V4L2_CID_POWER_LINE_FREQUENCY: return "Power Line Frequency"; -+ case V4L2_CID_HUE_AUTO: return "Hue, Automatic"; -+ case V4L2_CID_WHITE_BALANCE_TEMPERATURE: return "White Balance Temperature"; -+ case V4L2_CID_SHARPNESS: return "Sharpness"; -+ case V4L2_CID_BACKLIGHT_COMPENSATION: return "Backlight Compensation"; -+ case V4L2_CID_CHROMA_AGC: return "Chroma AGC"; -+ case V4L2_CID_COLOR_KILLER: return "Color Killer"; -+ case V4L2_CID_COLORFX: return "Color Effects"; -+ case V4L2_CID_AUTOBRIGHTNESS: return "Brightness, Automatic"; -+ case V4L2_CID_BAND_STOP_FILTER: return "Band-Stop Filter"; -+ case V4L2_CID_ROTATE: return "Rotate"; -+ case V4L2_CID_BG_COLOR: return "Background Color"; -+ case V4L2_CID_CHROMA_GAIN: return "Chroma Gain"; -+ case V4L2_CID_ILLUMINATORS_1: return "Illuminator 1"; -+ case V4L2_CID_ILLUMINATORS_2: return "Illuminator 2"; -+ case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE: return "Min Number of Capture Buffers"; -+ case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT: return "Min Number of Output Buffers"; -+ case V4L2_CID_ALPHA_COMPONENT: return "Alpha Component"; -+ case V4L2_CID_COLORFX_CBCR: return "Color Effects, CbCr"; -+ -+ /* Codec controls */ -+ /* The MPEG controls are applicable to all codec controls -+ * and the 'MPEG' part of the define is historical */ -+ /* Keep the order of the 'case's the same as in videodev2.h! */ -+ case V4L2_CID_CODEC_CLASS: return "Codec Controls"; -+ case V4L2_CID_MPEG_STREAM_TYPE: return "Stream Type"; -+ case V4L2_CID_MPEG_STREAM_PID_PMT: return "Stream PMT Program ID"; -+ case V4L2_CID_MPEG_STREAM_PID_AUDIO: return "Stream Audio Program ID"; -+ case V4L2_CID_MPEG_STREAM_PID_VIDEO: return "Stream Video Program ID"; -+ case V4L2_CID_MPEG_STREAM_PID_PCR: return "Stream PCR Program ID"; -+ case V4L2_CID_MPEG_STREAM_PES_ID_AUDIO: return "Stream PES Audio ID"; -+ case V4L2_CID_MPEG_STREAM_PES_ID_VIDEO: return "Stream PES Video ID"; -+ case V4L2_CID_MPEG_STREAM_VBI_FMT: return "Stream VBI Format"; -+ case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: return "Audio Sampling Frequency"; -+ case V4L2_CID_MPEG_AUDIO_ENCODING: return "Audio Encoding"; -+ case V4L2_CID_MPEG_AUDIO_L1_BITRATE: return "Audio Layer I Bitrate"; -+ case V4L2_CID_MPEG_AUDIO_L2_BITRATE: return "Audio Layer II Bitrate"; -+ case V4L2_CID_MPEG_AUDIO_L3_BITRATE: return "Audio Layer III Bitrate"; -+ case V4L2_CID_MPEG_AUDIO_MODE: return "Audio Stereo Mode"; -+ case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: return "Audio Stereo Mode Extension"; -+ case V4L2_CID_MPEG_AUDIO_EMPHASIS: return "Audio Emphasis"; -+ case V4L2_CID_MPEG_AUDIO_CRC: return "Audio CRC"; -+ case V4L2_CID_MPEG_AUDIO_MUTE: return "Audio Mute"; -+ case V4L2_CID_MPEG_AUDIO_AAC_BITRATE: return "Audio AAC Bitrate"; -+ case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: return "Audio AC-3 Bitrate"; -+ case V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK: return "Audio Playback"; -+ case V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK: return "Audio Multilingual Playback"; -+ case V4L2_CID_MPEG_VIDEO_ENCODING: return "Video Encoding"; -+ case V4L2_CID_MPEG_VIDEO_ASPECT: return "Video Aspect"; -+ case V4L2_CID_MPEG_VIDEO_B_FRAMES: return "Video B Frames"; -+ case V4L2_CID_MPEG_VIDEO_GOP_SIZE: return "Video GOP Size"; -+ case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: return "Video GOP Closure"; -+ case V4L2_CID_MPEG_VIDEO_PULLDOWN: return "Video Pulldown"; -+ case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: return "Video Bitrate Mode"; -+ case V4L2_CID_MPEG_VIDEO_CONSTANT_QUALITY: return "Constant Quality"; -+ case V4L2_CID_MPEG_VIDEO_BITRATE: return "Video Bitrate"; -+ case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: return "Video Peak Bitrate"; -+ case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION: return "Video Temporal Decimation"; -+ case V4L2_CID_MPEG_VIDEO_MUTE: return "Video Mute"; -+ case V4L2_CID_MPEG_VIDEO_MUTE_YUV: return "Video Mute YUV"; -+ case V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE: return "Decoder Slice Interface"; -+ case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER: return "MPEG4 Loop Filter Enable"; -+ case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB: return "Number of Intra Refresh MBs"; -+ case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE: return "Frame Level Rate Control Enable"; -+ case V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE: return "H264 MB Level Rate Control"; -+ case V4L2_CID_MPEG_VIDEO_HEADER_MODE: return "Sequence Header Mode"; -+ case V4L2_CID_MPEG_VIDEO_MAX_REF_PIC: return "Max Number of Reference Pics"; -+ case V4L2_CID_MPEG_VIDEO_FRAME_SKIP_MODE: return "Frame Skip Mode"; -+ case V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY: return "Display Delay"; -+ case V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY_ENABLE: return "Display Delay Enable"; -+ case V4L2_CID_MPEG_VIDEO_AU_DELIMITER: return "Generate Access Unit Delimiters"; -+ case V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP: return "H263 I-Frame QP Value"; -+ case V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP: return "H263 P-Frame QP Value"; -+ case V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP: return "H263 B-Frame QP Value"; -+ case V4L2_CID_MPEG_VIDEO_H263_MIN_QP: return "H263 Minimum QP Value"; -+ case V4L2_CID_MPEG_VIDEO_H263_MAX_QP: return "H263 Maximum QP Value"; -+ case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP: return "H264 I-Frame QP Value"; -+ case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP: return "H264 P-Frame QP Value"; -+ case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP: return "H264 B-Frame QP Value"; -+ case V4L2_CID_MPEG_VIDEO_H264_MAX_QP: return "H264 Maximum QP Value"; -+ case V4L2_CID_MPEG_VIDEO_H264_MIN_QP: return "H264 Minimum QP Value"; -+ case V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM: return "H264 8x8 Transform Enable"; -+ case V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE: return "H264 CPB Buffer Size"; -+ case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE: return "H264 Entropy Mode"; -+ case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD: return "H264 I-Frame Period"; -+ case V4L2_CID_MPEG_VIDEO_H264_LEVEL: return "H264 Level"; -+ case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA: return "H264 Loop Filter Alpha Offset"; -+ case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA: return "H264 Loop Filter Beta Offset"; -+ case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE: return "H264 Loop Filter Mode"; -+ case V4L2_CID_MPEG_VIDEO_H264_PROFILE: return "H264 Profile"; -+ case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT: return "Vertical Size of SAR"; -+ case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH: return "Horizontal Size of SAR"; -+ case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE: return "Aspect Ratio VUI Enable"; -+ case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC: return "VUI Aspect Ratio IDC"; -+ case V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING: return "H264 Enable Frame Packing SEI"; -+ case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_CURRENT_FRAME_0: return "H264 Set Curr. Frame as Frame0"; -+ case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE: return "H264 FP Arrangement Type"; -+ case V4L2_CID_MPEG_VIDEO_H264_FMO: return "H264 Flexible MB Ordering"; -+ case V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE: return "H264 Map Type for FMO"; -+ case V4L2_CID_MPEG_VIDEO_H264_FMO_SLICE_GROUP: return "H264 FMO Number of Slice Groups"; -+ case V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_DIRECTION: return "H264 FMO Direction of Change"; -+ case V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_RATE: return "H264 FMO Size of 1st Slice Grp"; -+ case V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH: return "H264 FMO No. of Consecutive MBs"; -+ case V4L2_CID_MPEG_VIDEO_H264_ASO: return "H264 Arbitrary Slice Ordering"; -+ case V4L2_CID_MPEG_VIDEO_H264_ASO_SLICE_ORDER: return "H264 ASO Slice Order"; -+ case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING: return "Enable H264 Hierarchical Coding"; -+ case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE: return "H264 Hierarchical Coding Type"; -+ case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER:return "H264 Number of HC Layers"; -+ case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP: -+ return "H264 Set QP Value for HC Layers"; -+ case V4L2_CID_MPEG_VIDEO_H264_CONSTRAINED_INTRA_PREDICTION: -+ return "H264 Constrained Intra Pred"; -+ case V4L2_CID_MPEG_VIDEO_H264_CHROMA_QP_INDEX_OFFSET: return "H264 Chroma QP Index Offset"; -+ case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MIN_QP: return "H264 I-Frame Minimum QP Value"; -+ case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MAX_QP: return "H264 I-Frame Maximum QP Value"; -+ case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MIN_QP: return "H264 P-Frame Minimum QP Value"; -+ case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MAX_QP: return "H264 P-Frame Maximum QP Value"; -+ case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MIN_QP: return "H264 B-Frame Minimum QP Value"; -+ case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MAX_QP: return "H264 B-Frame Maximum QP Value"; -+ case V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L0_BR: return "H264 Hierarchical Lay 0 Bitrate"; -+ case V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L1_BR: return "H264 Hierarchical Lay 1 Bitrate"; -+ case V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L2_BR: return "H264 Hierarchical Lay 2 Bitrate"; -+ case V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L3_BR: return "H264 Hierarchical Lay 3 Bitrate"; -+ case V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L4_BR: return "H264 Hierarchical Lay 4 Bitrate"; -+ case V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L5_BR: return "H264 Hierarchical Lay 5 Bitrate"; -+ case V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L6_BR: return "H264 Hierarchical Lay 6 Bitrate"; -+ case V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL: return "MPEG2 Level"; -+ case V4L2_CID_MPEG_VIDEO_MPEG2_PROFILE: return "MPEG2 Profile"; -+ case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP: return "MPEG4 I-Frame QP Value"; -+ case V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP: return "MPEG4 P-Frame QP Value"; -+ case V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP: return "MPEG4 B-Frame QP Value"; -+ case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP: return "MPEG4 Minimum QP Value"; -+ case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP: return "MPEG4 Maximum QP Value"; -+ case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL: return "MPEG4 Level"; -+ case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE: return "MPEG4 Profile"; -+ case V4L2_CID_MPEG_VIDEO_MPEG4_QPEL: return "Quarter Pixel Search Enable"; -+ case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES: return "Maximum Bytes in a Slice"; -+ case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB: return "Number of MBs in a Slice"; -+ case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE: return "Slice Partitioning Method"; -+ case V4L2_CID_MPEG_VIDEO_VBV_SIZE: return "VBV Buffer Size"; -+ case V4L2_CID_MPEG_VIDEO_DEC_PTS: return "Video Decoder PTS"; -+ case V4L2_CID_MPEG_VIDEO_DEC_FRAME: return "Video Decoder Frame Count"; -+ case V4L2_CID_MPEG_VIDEO_DEC_CONCEAL_COLOR: return "Video Decoder Conceal Color"; -+ case V4L2_CID_MPEG_VIDEO_VBV_DELAY: return "Initial Delay for VBV Control"; -+ case V4L2_CID_MPEG_VIDEO_MV_H_SEARCH_RANGE: return "Horizontal MV Search Range"; -+ case V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE: return "Vertical MV Search Range"; -+ case V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER: return "Repeat Sequence Header"; -+ case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME: return "Force Key Frame"; -+ case V4L2_CID_MPEG_VIDEO_BASELAYER_PRIORITY_ID: return "Base Layer Priority ID"; -+ case V4L2_CID_MPEG_VIDEO_LTR_COUNT: return "LTR Count"; -+ case V4L2_CID_MPEG_VIDEO_FRAME_LTR_INDEX: return "Frame LTR Index"; -+ case V4L2_CID_MPEG_VIDEO_USE_LTR_FRAMES: return "Use LTR Frames"; -+ case V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS: return "MPEG-2 Slice Parameters"; -+ case V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION: return "MPEG-2 Quantization Matrices"; -+ case V4L2_CID_FWHT_I_FRAME_QP: return "FWHT I-Frame QP Value"; -+ case V4L2_CID_FWHT_P_FRAME_QP: return "FWHT P-Frame QP Value"; -+ -+ /* VPX controls */ -+ case V4L2_CID_MPEG_VIDEO_VPX_NUM_PARTITIONS: return "VPX Number of Partitions"; -+ case V4L2_CID_MPEG_VIDEO_VPX_IMD_DISABLE_4X4: return "VPX Intra Mode Decision Disable"; -+ case V4L2_CID_MPEG_VIDEO_VPX_NUM_REF_FRAMES: return "VPX No. of Refs for P Frame"; -+ case V4L2_CID_MPEG_VIDEO_VPX_FILTER_LEVEL: return "VPX Loop Filter Level Range"; -+ case V4L2_CID_MPEG_VIDEO_VPX_FILTER_SHARPNESS: return "VPX Deblocking Effect Control"; -+ case V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_REF_PERIOD: return "VPX Golden Frame Refresh Period"; -+ case V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_SEL: return "VPX Golden Frame Indicator"; -+ case V4L2_CID_MPEG_VIDEO_VPX_MIN_QP: return "VPX Minimum QP Value"; -+ case V4L2_CID_MPEG_VIDEO_VPX_MAX_QP: return "VPX Maximum QP Value"; -+ case V4L2_CID_MPEG_VIDEO_VPX_I_FRAME_QP: return "VPX I-Frame QP Value"; -+ case V4L2_CID_MPEG_VIDEO_VPX_P_FRAME_QP: return "VPX P-Frame QP Value"; -+ case V4L2_CID_MPEG_VIDEO_VP8_PROFILE: return "VP8 Profile"; -+ case V4L2_CID_MPEG_VIDEO_VP9_PROFILE: return "VP9 Profile"; -+ case V4L2_CID_MPEG_VIDEO_VP9_LEVEL: return "VP9 Level"; -+ -+ /* HEVC controls */ -+ case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP: return "HEVC I-Frame QP Value"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP: return "HEVC P-Frame QP Value"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP: return "HEVC B-Frame QP Value"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP: return "HEVC Minimum QP Value"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP: return "HEVC Maximum QP Value"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MIN_QP: return "HEVC I-Frame Minimum QP Value"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MAX_QP: return "HEVC I-Frame Maximum QP Value"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_MIN_QP: return "HEVC P-Frame Minimum QP Value"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_MAX_QP: return "HEVC P-Frame Maximum QP Value"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_MIN_QP: return "HEVC B-Frame Minimum QP Value"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_MAX_QP: return "HEVC B-Frame Maximum QP Value"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE: return "HEVC Profile"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL: return "HEVC Level"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_TIER: return "HEVC Tier"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_FRAME_RATE_RESOLUTION: return "HEVC Frame Rate Resolution"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_MAX_PARTITION_DEPTH: return "HEVC Maximum Coding Unit Depth"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_TYPE: return "HEVC Refresh Type"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_CONST_INTRA_PRED: return "HEVC Constant Intra Prediction"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_LOSSLESS_CU: return "HEVC Lossless Encoding"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_WAVEFRONT: return "HEVC Wavefront"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE: return "HEVC Loop Filter"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_HIER_QP: return "HEVC QP Values"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE: return "HEVC Hierarchical Coding Type"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER: return "HEVC Hierarchical Coding Layer"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_QP: return "HEVC Hierarchical Layer 0 QP"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_QP: return "HEVC Hierarchical Layer 1 QP"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_QP: return "HEVC Hierarchical Layer 2 QP"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_QP: return "HEVC Hierarchical Layer 3 QP"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_QP: return "HEVC Hierarchical Layer 4 QP"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_QP: return "HEVC Hierarchical Layer 5 QP"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L6_QP: return "HEVC Hierarchical Layer 6 QP"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_BR: return "HEVC Hierarchical Lay 0 BitRate"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_BR: return "HEVC Hierarchical Lay 1 BitRate"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_BR: return "HEVC Hierarchical Lay 2 BitRate"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_BR: return "HEVC Hierarchical Lay 3 BitRate"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_BR: return "HEVC Hierarchical Lay 4 BitRate"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_BR: return "HEVC Hierarchical Lay 5 BitRate"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L6_BR: return "HEVC Hierarchical Lay 6 BitRate"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_GENERAL_PB: return "HEVC General PB"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_TEMPORAL_ID: return "HEVC Temporal ID"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_STRONG_SMOOTHING: return "HEVC Strong Intra Smoothing"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_INTRA_PU_SPLIT: return "HEVC Intra PU Split"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_TMV_PREDICTION: return "HEVC TMV Prediction"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_MAX_NUM_MERGE_MV_MINUS1: return "HEVC Max Num of Candidate MVs"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_WITHOUT_STARTCODE: return "HEVC ENC Without Startcode"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_PERIOD: return "HEVC Num of I-Frame b/w 2 IDR"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_LF_BETA_OFFSET_DIV2: return "HEVC Loop Filter Beta Offset"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_LF_TC_OFFSET_DIV2: return "HEVC Loop Filter TC Offset"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD: return "HEVC Size of Length Field"; -+ case V4L2_CID_MPEG_VIDEO_REF_NUMBER_FOR_PFRAMES: return "Reference Frames for a P-Frame"; -+ case V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR: return "Prepend SPS and PPS to IDR"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_SPS: return "HEVC Sequence Parameter Set"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_PPS: return "HEVC Picture Parameter Set"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS: return "HEVC Slice Parameters"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE: return "HEVC Decode Mode"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_START_CODE: return "HEVC Start Code"; -+ -+ /* CAMERA controls */ -+ /* Keep the order of the 'case's the same as in v4l2-controls.h! */ -+ case V4L2_CID_CAMERA_CLASS: return "Camera Controls"; -+ case V4L2_CID_EXPOSURE_AUTO: return "Auto Exposure"; -+ case V4L2_CID_EXPOSURE_ABSOLUTE: return "Exposure Time, Absolute"; -+ case V4L2_CID_EXPOSURE_AUTO_PRIORITY: return "Exposure, Dynamic Framerate"; -+ case V4L2_CID_PAN_RELATIVE: return "Pan, Relative"; -+ case V4L2_CID_TILT_RELATIVE: return "Tilt, Relative"; -+ case V4L2_CID_PAN_RESET: return "Pan, Reset"; -+ case V4L2_CID_TILT_RESET: return "Tilt, Reset"; -+ case V4L2_CID_PAN_ABSOLUTE: return "Pan, Absolute"; -+ case V4L2_CID_TILT_ABSOLUTE: return "Tilt, Absolute"; -+ case V4L2_CID_FOCUS_ABSOLUTE: return "Focus, Absolute"; -+ case V4L2_CID_FOCUS_RELATIVE: return "Focus, Relative"; -+ case V4L2_CID_FOCUS_AUTO: return "Focus, Automatic Continuous"; -+ case V4L2_CID_ZOOM_ABSOLUTE: return "Zoom, Absolute"; -+ case V4L2_CID_ZOOM_RELATIVE: return "Zoom, Relative"; -+ case V4L2_CID_ZOOM_CONTINUOUS: return "Zoom, Continuous"; -+ case V4L2_CID_PRIVACY: return "Privacy"; -+ case V4L2_CID_IRIS_ABSOLUTE: return "Iris, Absolute"; -+ case V4L2_CID_IRIS_RELATIVE: return "Iris, Relative"; -+ case V4L2_CID_AUTO_EXPOSURE_BIAS: return "Auto Exposure, Bias"; -+ case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE: return "White Balance, Auto & Preset"; -+ case V4L2_CID_WIDE_DYNAMIC_RANGE: return "Wide Dynamic Range"; -+ case V4L2_CID_IMAGE_STABILIZATION: return "Image Stabilization"; -+ case V4L2_CID_ISO_SENSITIVITY: return "ISO Sensitivity"; -+ case V4L2_CID_ISO_SENSITIVITY_AUTO: return "ISO Sensitivity, Auto"; -+ case V4L2_CID_EXPOSURE_METERING: return "Exposure, Metering Mode"; -+ case V4L2_CID_SCENE_MODE: return "Scene Mode"; -+ case V4L2_CID_3A_LOCK: return "3A Lock"; -+ case V4L2_CID_AUTO_FOCUS_START: return "Auto Focus, Start"; -+ case V4L2_CID_AUTO_FOCUS_STOP: return "Auto Focus, Stop"; -+ case V4L2_CID_AUTO_FOCUS_STATUS: return "Auto Focus, Status"; -+ case V4L2_CID_AUTO_FOCUS_RANGE: return "Auto Focus, Range"; -+ case V4L2_CID_PAN_SPEED: return "Pan, Speed"; -+ case V4L2_CID_TILT_SPEED: return "Tilt, Speed"; -+ case V4L2_CID_UNIT_CELL_SIZE: return "Unit Cell Size"; -+ case V4L2_CID_CAMERA_ORIENTATION: return "Camera Orientation"; -+ case V4L2_CID_CAMERA_SENSOR_ROTATION: return "Camera Sensor Rotation"; -+ -+ /* FM Radio Modulator controls */ -+ /* Keep the order of the 'case's the same as in v4l2-controls.h! */ -+ case V4L2_CID_FM_TX_CLASS: return "FM Radio Modulator Controls"; -+ case V4L2_CID_RDS_TX_DEVIATION: return "RDS Signal Deviation"; -+ case V4L2_CID_RDS_TX_PI: return "RDS Program ID"; -+ case V4L2_CID_RDS_TX_PTY: return "RDS Program Type"; -+ case V4L2_CID_RDS_TX_PS_NAME: return "RDS PS Name"; -+ case V4L2_CID_RDS_TX_RADIO_TEXT: return "RDS Radio Text"; -+ case V4L2_CID_RDS_TX_MONO_STEREO: return "RDS Stereo"; -+ case V4L2_CID_RDS_TX_ARTIFICIAL_HEAD: return "RDS Artificial Head"; -+ case V4L2_CID_RDS_TX_COMPRESSED: return "RDS Compressed"; -+ case V4L2_CID_RDS_TX_DYNAMIC_PTY: return "RDS Dynamic PTY"; -+ case V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT: return "RDS Traffic Announcement"; -+ case V4L2_CID_RDS_TX_TRAFFIC_PROGRAM: return "RDS Traffic Program"; -+ case V4L2_CID_RDS_TX_MUSIC_SPEECH: return "RDS Music"; -+ case V4L2_CID_RDS_TX_ALT_FREQS_ENABLE: return "RDS Enable Alt Frequencies"; -+ case V4L2_CID_RDS_TX_ALT_FREQS: return "RDS Alternate Frequencies"; -+ case V4L2_CID_AUDIO_LIMITER_ENABLED: return "Audio Limiter Feature Enabled"; -+ case V4L2_CID_AUDIO_LIMITER_RELEASE_TIME: return "Audio Limiter Release Time"; -+ case V4L2_CID_AUDIO_LIMITER_DEVIATION: return "Audio Limiter Deviation"; -+ case V4L2_CID_AUDIO_COMPRESSION_ENABLED: return "Audio Compression Enabled"; -+ case V4L2_CID_AUDIO_COMPRESSION_GAIN: return "Audio Compression Gain"; -+ case V4L2_CID_AUDIO_COMPRESSION_THRESHOLD: return "Audio Compression Threshold"; -+ case V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME: return "Audio Compression Attack Time"; -+ case V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME: return "Audio Compression Release Time"; -+ case V4L2_CID_PILOT_TONE_ENABLED: return "Pilot Tone Feature Enabled"; -+ case V4L2_CID_PILOT_TONE_DEVIATION: return "Pilot Tone Deviation"; -+ case V4L2_CID_PILOT_TONE_FREQUENCY: return "Pilot Tone Frequency"; -+ case V4L2_CID_TUNE_PREEMPHASIS: return "Pre-Emphasis"; -+ case V4L2_CID_TUNE_POWER_LEVEL: return "Tune Power Level"; -+ case V4L2_CID_TUNE_ANTENNA_CAPACITOR: return "Tune Antenna Capacitor"; -+ -+ /* Flash controls */ -+ /* Keep the order of the 'case's the same as in v4l2-controls.h! */ -+ case V4L2_CID_FLASH_CLASS: return "Flash Controls"; -+ case V4L2_CID_FLASH_LED_MODE: return "LED Mode"; -+ case V4L2_CID_FLASH_STROBE_SOURCE: return "Strobe Source"; -+ case V4L2_CID_FLASH_STROBE: return "Strobe"; -+ case V4L2_CID_FLASH_STROBE_STOP: return "Stop Strobe"; -+ case V4L2_CID_FLASH_STROBE_STATUS: return "Strobe Status"; -+ case V4L2_CID_FLASH_TIMEOUT: return "Strobe Timeout"; -+ case V4L2_CID_FLASH_INTENSITY: return "Intensity, Flash Mode"; -+ case V4L2_CID_FLASH_TORCH_INTENSITY: return "Intensity, Torch Mode"; -+ case V4L2_CID_FLASH_INDICATOR_INTENSITY: return "Intensity, Indicator"; -+ case V4L2_CID_FLASH_FAULT: return "Faults"; -+ case V4L2_CID_FLASH_CHARGE: return "Charge"; -+ case V4L2_CID_FLASH_READY: return "Ready to Strobe"; -+ -+ /* JPEG encoder controls */ -+ /* Keep the order of the 'case's the same as in v4l2-controls.h! */ -+ case V4L2_CID_JPEG_CLASS: return "JPEG Compression Controls"; -+ case V4L2_CID_JPEG_CHROMA_SUBSAMPLING: return "Chroma Subsampling"; -+ case V4L2_CID_JPEG_RESTART_INTERVAL: return "Restart Interval"; -+ case V4L2_CID_JPEG_COMPRESSION_QUALITY: return "Compression Quality"; -+ case V4L2_CID_JPEG_ACTIVE_MARKER: return "Active Markers"; -+ -+ /* Image source controls */ -+ /* Keep the order of the 'case's the same as in v4l2-controls.h! */ -+ case V4L2_CID_IMAGE_SOURCE_CLASS: return "Image Source Controls"; -+ case V4L2_CID_VBLANK: return "Vertical Blanking"; -+ case V4L2_CID_HBLANK: return "Horizontal Blanking"; -+ case V4L2_CID_ANALOGUE_GAIN: return "Analogue Gain"; -+ case V4L2_CID_TEST_PATTERN_RED: return "Red Pixel Value"; -+ case V4L2_CID_TEST_PATTERN_GREENR: return "Green (Red) Pixel Value"; -+ case V4L2_CID_TEST_PATTERN_BLUE: return "Blue Pixel Value"; -+ case V4L2_CID_TEST_PATTERN_GREENB: return "Green (Blue) Pixel Value"; -+ -+ /* Image processing controls */ -+ /* Keep the order of the 'case's the same as in v4l2-controls.h! */ -+ case V4L2_CID_IMAGE_PROC_CLASS: return "Image Processing Controls"; -+ case V4L2_CID_LINK_FREQ: return "Link Frequency"; -+ case V4L2_CID_PIXEL_RATE: return "Pixel Rate"; -+ case V4L2_CID_TEST_PATTERN: return "Test Pattern"; -+ case V4L2_CID_DEINTERLACING_MODE: return "Deinterlacing Mode"; -+ case V4L2_CID_DIGITAL_GAIN: return "Digital Gain"; -+ -+ /* DV controls */ -+ /* Keep the order of the 'case's the same as in v4l2-controls.h! */ -+ case V4L2_CID_DV_CLASS: return "Digital Video Controls"; -+ case V4L2_CID_DV_TX_HOTPLUG: return "Hotplug Present"; -+ case V4L2_CID_DV_TX_RXSENSE: return "RxSense Present"; -+ case V4L2_CID_DV_TX_EDID_PRESENT: return "EDID Present"; -+ case V4L2_CID_DV_TX_MODE: return "Transmit Mode"; -+ case V4L2_CID_DV_TX_RGB_RANGE: return "Tx RGB Quantization Range"; -+ case V4L2_CID_DV_TX_IT_CONTENT_TYPE: return "Tx IT Content Type"; -+ case V4L2_CID_DV_RX_POWER_PRESENT: return "Power Present"; -+ case V4L2_CID_DV_RX_RGB_RANGE: return "Rx RGB Quantization Range"; -+ case V4L2_CID_DV_RX_IT_CONTENT_TYPE: return "Rx IT Content Type"; -+ -+ case V4L2_CID_FM_RX_CLASS: return "FM Radio Receiver Controls"; -+ case V4L2_CID_TUNE_DEEMPHASIS: return "De-Emphasis"; -+ case V4L2_CID_RDS_RECEPTION: return "RDS Reception"; -+ case V4L2_CID_RF_TUNER_CLASS: return "RF Tuner Controls"; -+ case V4L2_CID_RF_TUNER_RF_GAIN: return "RF Gain"; -+ case V4L2_CID_RF_TUNER_LNA_GAIN_AUTO: return "LNA Gain, Auto"; -+ case V4L2_CID_RF_TUNER_LNA_GAIN: return "LNA Gain"; -+ case V4L2_CID_RF_TUNER_MIXER_GAIN_AUTO: return "Mixer Gain, Auto"; -+ case V4L2_CID_RF_TUNER_MIXER_GAIN: return "Mixer Gain"; -+ case V4L2_CID_RF_TUNER_IF_GAIN_AUTO: return "IF Gain, Auto"; -+ case V4L2_CID_RF_TUNER_IF_GAIN: return "IF Gain"; -+ case V4L2_CID_RF_TUNER_BANDWIDTH_AUTO: return "Bandwidth, Auto"; -+ case V4L2_CID_RF_TUNER_BANDWIDTH: return "Bandwidth"; -+ case V4L2_CID_RF_TUNER_PLL_LOCK: return "PLL Lock"; -+ case V4L2_CID_RDS_RX_PTY: return "RDS Program Type"; -+ case V4L2_CID_RDS_RX_PS_NAME: return "RDS PS Name"; -+ case V4L2_CID_RDS_RX_RADIO_TEXT: return "RDS Radio Text"; -+ case V4L2_CID_RDS_RX_TRAFFIC_ANNOUNCEMENT: return "RDS Traffic Announcement"; -+ case V4L2_CID_RDS_RX_TRAFFIC_PROGRAM: return "RDS Traffic Program"; -+ case V4L2_CID_RDS_RX_MUSIC_SPEECH: return "RDS Music"; -+ -+ /* Detection controls */ -+ /* Keep the order of the 'case's the same as in v4l2-controls.h! */ -+ case V4L2_CID_DETECT_CLASS: return "Detection Controls"; -+ case V4L2_CID_DETECT_MD_MODE: return "Motion Detection Mode"; -+ case V4L2_CID_DETECT_MD_GLOBAL_THRESHOLD: return "MD Global Threshold"; -+ case V4L2_CID_DETECT_MD_THRESHOLD_GRID: return "MD Threshold Grid"; -+ case V4L2_CID_DETECT_MD_REGION_GRID: return "MD Region Grid"; -+ -+ /* Stateless Codec controls */ -+ /* Keep the order of the 'case's the same as in v4l2-controls.h! */ -+ case V4L2_CID_CODEC_STATELESS_CLASS: return "Stateless Codec Controls"; -+ case V4L2_CID_STATELESS_H264_DECODE_MODE: return "H264 Decode Mode"; -+ case V4L2_CID_STATELESS_H264_START_CODE: return "H264 Start Code"; -+ case V4L2_CID_STATELESS_H264_SPS: return "H264 Sequence Parameter Set"; -+ case V4L2_CID_STATELESS_H264_PPS: return "H264 Picture Parameter Set"; -+ case V4L2_CID_STATELESS_H264_SCALING_MATRIX: return "H264 Scaling Matrix"; -+ case V4L2_CID_STATELESS_H264_PRED_WEIGHTS: return "H264 Prediction Weight Table"; -+ case V4L2_CID_STATELESS_H264_SLICE_PARAMS: return "H264 Slice Parameters"; -+ case V4L2_CID_STATELESS_H264_DECODE_PARAMS: return "H264 Decode Parameters"; -+ case V4L2_CID_STATELESS_FWHT_PARAMS: return "FWHT Stateless Parameters"; -+ case V4L2_CID_STATELESS_VP8_FRAME: return "VP8 Frame Parameters"; -+ -+ /* Colorimetry controls */ -+ /* Keep the order of the 'case's the same as in v4l2-controls.h! */ -+ case V4L2_CID_COLORIMETRY_CLASS: return "Colorimetry Controls"; -+ case V4L2_CID_COLORIMETRY_HDR10_CLL_INFO: return "HDR10 Content Light Info"; -+ case V4L2_CID_COLORIMETRY_HDR10_MASTERING_DISPLAY: return "HDR10 Mastering Display"; -+ default: -+ return NULL; -+ } -+} -+EXPORT_SYMBOL(v4l2_ctrl_get_name); -+ -+void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type, -+ s64 *min, s64 *max, u64 *step, s64 *def, u32 *flags) -+{ -+ *name = v4l2_ctrl_get_name(id); -+ *flags = 0; -+ -+ switch (id) { -+ case V4L2_CID_AUDIO_MUTE: -+ case V4L2_CID_AUDIO_LOUDNESS: -+ case V4L2_CID_AUTO_WHITE_BALANCE: -+ case V4L2_CID_AUTOGAIN: -+ case V4L2_CID_HFLIP: -+ case V4L2_CID_VFLIP: -+ case V4L2_CID_HUE_AUTO: -+ case V4L2_CID_CHROMA_AGC: -+ case V4L2_CID_COLOR_KILLER: -+ case V4L2_CID_AUTOBRIGHTNESS: -+ case V4L2_CID_MPEG_AUDIO_MUTE: -+ case V4L2_CID_MPEG_VIDEO_MUTE: -+ case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: -+ case V4L2_CID_MPEG_VIDEO_PULLDOWN: -+ case V4L2_CID_EXPOSURE_AUTO_PRIORITY: -+ case V4L2_CID_FOCUS_AUTO: -+ case V4L2_CID_PRIVACY: -+ case V4L2_CID_AUDIO_LIMITER_ENABLED: -+ case V4L2_CID_AUDIO_COMPRESSION_ENABLED: -+ case V4L2_CID_PILOT_TONE_ENABLED: -+ case V4L2_CID_ILLUMINATORS_1: -+ case V4L2_CID_ILLUMINATORS_2: -+ case V4L2_CID_FLASH_STROBE_STATUS: -+ case V4L2_CID_FLASH_CHARGE: -+ case V4L2_CID_FLASH_READY: -+ case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER: -+ case V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE: -+ case V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY_ENABLE: -+ case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE: -+ case V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE: -+ case V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM: -+ case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE: -+ case V4L2_CID_MPEG_VIDEO_MPEG4_QPEL: -+ case V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER: -+ case V4L2_CID_MPEG_VIDEO_AU_DELIMITER: -+ case V4L2_CID_WIDE_DYNAMIC_RANGE: -+ case V4L2_CID_IMAGE_STABILIZATION: -+ case V4L2_CID_RDS_RECEPTION: -+ case V4L2_CID_RF_TUNER_LNA_GAIN_AUTO: -+ case V4L2_CID_RF_TUNER_MIXER_GAIN_AUTO: -+ case V4L2_CID_RF_TUNER_IF_GAIN_AUTO: -+ case V4L2_CID_RF_TUNER_BANDWIDTH_AUTO: -+ case V4L2_CID_RF_TUNER_PLL_LOCK: -+ case V4L2_CID_RDS_TX_MONO_STEREO: -+ case V4L2_CID_RDS_TX_ARTIFICIAL_HEAD: -+ case V4L2_CID_RDS_TX_COMPRESSED: -+ case V4L2_CID_RDS_TX_DYNAMIC_PTY: -+ case V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT: -+ case V4L2_CID_RDS_TX_TRAFFIC_PROGRAM: -+ case V4L2_CID_RDS_TX_MUSIC_SPEECH: -+ case V4L2_CID_RDS_TX_ALT_FREQS_ENABLE: -+ case V4L2_CID_RDS_RX_TRAFFIC_ANNOUNCEMENT: -+ case V4L2_CID_RDS_RX_TRAFFIC_PROGRAM: -+ case V4L2_CID_RDS_RX_MUSIC_SPEECH: -+ *type = V4L2_CTRL_TYPE_BOOLEAN; -+ *min = 0; -+ *max = *step = 1; -+ break; -+ case V4L2_CID_ROTATE: -+ *type = V4L2_CTRL_TYPE_INTEGER; -+ *flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT; -+ break; -+ case V4L2_CID_MPEG_VIDEO_MV_H_SEARCH_RANGE: -+ case V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE: -+ case V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY: -+ *type = V4L2_CTRL_TYPE_INTEGER; -+ break; -+ case V4L2_CID_MPEG_VIDEO_LTR_COUNT: -+ *type = V4L2_CTRL_TYPE_INTEGER; -+ break; -+ case V4L2_CID_MPEG_VIDEO_FRAME_LTR_INDEX: -+ *type = V4L2_CTRL_TYPE_INTEGER; -+ *flags |= V4L2_CTRL_FLAG_EXECUTE_ON_WRITE; -+ break; -+ case V4L2_CID_MPEG_VIDEO_USE_LTR_FRAMES: -+ *type = V4L2_CTRL_TYPE_BITMASK; -+ *flags |= V4L2_CTRL_FLAG_EXECUTE_ON_WRITE; -+ break; -+ case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME: -+ case V4L2_CID_PAN_RESET: -+ case V4L2_CID_TILT_RESET: -+ case V4L2_CID_FLASH_STROBE: -+ case V4L2_CID_FLASH_STROBE_STOP: -+ case V4L2_CID_AUTO_FOCUS_START: -+ case V4L2_CID_AUTO_FOCUS_STOP: -+ case V4L2_CID_DO_WHITE_BALANCE: -+ *type = V4L2_CTRL_TYPE_BUTTON; -+ *flags |= V4L2_CTRL_FLAG_WRITE_ONLY | -+ V4L2_CTRL_FLAG_EXECUTE_ON_WRITE; -+ *min = *max = *step = *def = 0; -+ break; -+ case V4L2_CID_POWER_LINE_FREQUENCY: -+ case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: -+ case V4L2_CID_MPEG_AUDIO_ENCODING: -+ case V4L2_CID_MPEG_AUDIO_L1_BITRATE: -+ case V4L2_CID_MPEG_AUDIO_L2_BITRATE: -+ case V4L2_CID_MPEG_AUDIO_L3_BITRATE: -+ case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: -+ case V4L2_CID_MPEG_AUDIO_MODE: -+ case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: -+ case V4L2_CID_MPEG_AUDIO_EMPHASIS: -+ case V4L2_CID_MPEG_AUDIO_CRC: -+ case V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK: -+ case V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK: -+ case V4L2_CID_MPEG_VIDEO_ENCODING: -+ case V4L2_CID_MPEG_VIDEO_ASPECT: -+ case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: -+ case V4L2_CID_MPEG_STREAM_TYPE: -+ case V4L2_CID_MPEG_STREAM_VBI_FMT: -+ case V4L2_CID_EXPOSURE_AUTO: -+ case V4L2_CID_AUTO_FOCUS_RANGE: -+ case V4L2_CID_COLORFX: -+ case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE: -+ case V4L2_CID_TUNE_PREEMPHASIS: -+ case V4L2_CID_FLASH_LED_MODE: -+ case V4L2_CID_FLASH_STROBE_SOURCE: -+ case V4L2_CID_MPEG_VIDEO_HEADER_MODE: -+ case V4L2_CID_MPEG_VIDEO_FRAME_SKIP_MODE: -+ case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE: -+ case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE: -+ case V4L2_CID_MPEG_VIDEO_H264_LEVEL: -+ case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE: -+ case V4L2_CID_MPEG_VIDEO_H264_PROFILE: -+ case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC: -+ case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE: -+ case V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE: -+ case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE: -+ case V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL: -+ case V4L2_CID_MPEG_VIDEO_MPEG2_PROFILE: -+ case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL: -+ case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE: -+ case V4L2_CID_JPEG_CHROMA_SUBSAMPLING: -+ case V4L2_CID_ISO_SENSITIVITY_AUTO: -+ case V4L2_CID_EXPOSURE_METERING: -+ case V4L2_CID_SCENE_MODE: -+ case V4L2_CID_DV_TX_MODE: -+ case V4L2_CID_DV_TX_RGB_RANGE: -+ case V4L2_CID_DV_TX_IT_CONTENT_TYPE: -+ case V4L2_CID_DV_RX_RGB_RANGE: -+ case V4L2_CID_DV_RX_IT_CONTENT_TYPE: -+ case V4L2_CID_TEST_PATTERN: -+ case V4L2_CID_DEINTERLACING_MODE: -+ case V4L2_CID_TUNE_DEEMPHASIS: -+ case V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_SEL: -+ case V4L2_CID_MPEG_VIDEO_VP8_PROFILE: -+ case V4L2_CID_MPEG_VIDEO_VP9_PROFILE: -+ case V4L2_CID_MPEG_VIDEO_VP9_LEVEL: -+ case V4L2_CID_DETECT_MD_MODE: -+ case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE: -+ case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL: -+ case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE: -+ case V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_TYPE: -+ case V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD: -+ case V4L2_CID_MPEG_VIDEO_HEVC_TIER: -+ case V4L2_CID_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE: -+ case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE: -+ case V4L2_CID_MPEG_VIDEO_HEVC_START_CODE: -+ case V4L2_CID_STATELESS_H264_DECODE_MODE: -+ case V4L2_CID_STATELESS_H264_START_CODE: -+ case V4L2_CID_CAMERA_ORIENTATION: -+ *type = V4L2_CTRL_TYPE_MENU; -+ break; -+ case V4L2_CID_LINK_FREQ: -+ *type = V4L2_CTRL_TYPE_INTEGER_MENU; -+ break; -+ case V4L2_CID_RDS_TX_PS_NAME: -+ case V4L2_CID_RDS_TX_RADIO_TEXT: -+ case V4L2_CID_RDS_RX_PS_NAME: -+ case V4L2_CID_RDS_RX_RADIO_TEXT: -+ *type = V4L2_CTRL_TYPE_STRING; -+ break; -+ case V4L2_CID_ISO_SENSITIVITY: -+ case V4L2_CID_AUTO_EXPOSURE_BIAS: -+ case V4L2_CID_MPEG_VIDEO_VPX_NUM_PARTITIONS: -+ case V4L2_CID_MPEG_VIDEO_VPX_NUM_REF_FRAMES: -+ *type = V4L2_CTRL_TYPE_INTEGER_MENU; -+ break; -+ case V4L2_CID_USER_CLASS: -+ case V4L2_CID_CAMERA_CLASS: -+ case V4L2_CID_CODEC_CLASS: -+ case V4L2_CID_FM_TX_CLASS: -+ case V4L2_CID_FLASH_CLASS: -+ case V4L2_CID_JPEG_CLASS: -+ case V4L2_CID_IMAGE_SOURCE_CLASS: -+ case V4L2_CID_IMAGE_PROC_CLASS: -+ case V4L2_CID_DV_CLASS: -+ case V4L2_CID_FM_RX_CLASS: -+ case V4L2_CID_RF_TUNER_CLASS: -+ case V4L2_CID_DETECT_CLASS: -+ case V4L2_CID_CODEC_STATELESS_CLASS: -+ case V4L2_CID_COLORIMETRY_CLASS: -+ *type = V4L2_CTRL_TYPE_CTRL_CLASS; -+ /* You can neither read nor write these */ -+ *flags |= V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY; -+ *min = *max = *step = *def = 0; -+ break; -+ case V4L2_CID_BG_COLOR: -+ *type = V4L2_CTRL_TYPE_INTEGER; -+ *step = 1; -+ *min = 0; -+ /* Max is calculated as RGB888 that is 2^24 */ -+ *max = 0xFFFFFF; -+ break; -+ case V4L2_CID_FLASH_FAULT: -+ case V4L2_CID_JPEG_ACTIVE_MARKER: -+ case V4L2_CID_3A_LOCK: -+ case V4L2_CID_AUTO_FOCUS_STATUS: -+ case V4L2_CID_DV_TX_HOTPLUG: -+ case V4L2_CID_DV_TX_RXSENSE: -+ case V4L2_CID_DV_TX_EDID_PRESENT: -+ case V4L2_CID_DV_RX_POWER_PRESENT: -+ *type = V4L2_CTRL_TYPE_BITMASK; -+ break; -+ case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE: -+ case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT: -+ *type = V4L2_CTRL_TYPE_INTEGER; -+ *flags |= V4L2_CTRL_FLAG_READ_ONLY; -+ break; -+ case V4L2_CID_MPEG_VIDEO_DEC_PTS: -+ *type = V4L2_CTRL_TYPE_INTEGER64; -+ *flags |= V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY; -+ *min = *def = 0; -+ *max = 0x1ffffffffLL; -+ *step = 1; -+ break; -+ case V4L2_CID_MPEG_VIDEO_DEC_FRAME: -+ *type = V4L2_CTRL_TYPE_INTEGER64; -+ *flags |= V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY; -+ *min = *def = 0; -+ *max = 0x7fffffffffffffffLL; -+ *step = 1; -+ break; -+ case V4L2_CID_MPEG_VIDEO_DEC_CONCEAL_COLOR: -+ *type = V4L2_CTRL_TYPE_INTEGER64; -+ *min = 0; -+ /* default for 8 bit black, luma is 16, chroma is 128 */ -+ *def = 0x8000800010LL; -+ *max = 0xffffffffffffLL; -+ *step = 1; -+ break; -+ case V4L2_CID_PIXEL_RATE: -+ *type = V4L2_CTRL_TYPE_INTEGER64; -+ *flags |= V4L2_CTRL_FLAG_READ_ONLY; -+ break; -+ case V4L2_CID_DETECT_MD_REGION_GRID: -+ *type = V4L2_CTRL_TYPE_U8; -+ break; -+ case V4L2_CID_DETECT_MD_THRESHOLD_GRID: -+ *type = V4L2_CTRL_TYPE_U16; -+ break; -+ case V4L2_CID_RDS_TX_ALT_FREQS: -+ *type = V4L2_CTRL_TYPE_U32; -+ break; -+ case V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS: -+ *type = V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS; -+ break; -+ case V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION: -+ *type = V4L2_CTRL_TYPE_MPEG2_QUANTIZATION; -+ break; -+ case V4L2_CID_STATELESS_FWHT_PARAMS: -+ *type = V4L2_CTRL_TYPE_FWHT_PARAMS; -+ break; -+ case V4L2_CID_STATELESS_H264_SPS: -+ *type = V4L2_CTRL_TYPE_H264_SPS; -+ break; -+ case V4L2_CID_STATELESS_H264_PPS: -+ *type = V4L2_CTRL_TYPE_H264_PPS; -+ break; -+ case V4L2_CID_STATELESS_H264_SCALING_MATRIX: -+ *type = V4L2_CTRL_TYPE_H264_SCALING_MATRIX; -+ break; -+ case V4L2_CID_STATELESS_H264_SLICE_PARAMS: -+ *type = V4L2_CTRL_TYPE_H264_SLICE_PARAMS; -+ break; -+ case V4L2_CID_STATELESS_H264_DECODE_PARAMS: -+ *type = V4L2_CTRL_TYPE_H264_DECODE_PARAMS; -+ break; -+ case V4L2_CID_STATELESS_H264_PRED_WEIGHTS: -+ *type = V4L2_CTRL_TYPE_H264_PRED_WEIGHTS; -+ break; -+ case V4L2_CID_STATELESS_VP8_FRAME: -+ *type = V4L2_CTRL_TYPE_VP8_FRAME; -+ break; -+ case V4L2_CID_MPEG_VIDEO_HEVC_SPS: -+ *type = V4L2_CTRL_TYPE_HEVC_SPS; -+ break; -+ case V4L2_CID_MPEG_VIDEO_HEVC_PPS: -+ *type = V4L2_CTRL_TYPE_HEVC_PPS; -+ break; -+ case V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS: -+ *type = V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS; -+ break; -+ case V4L2_CID_UNIT_CELL_SIZE: -+ *type = V4L2_CTRL_TYPE_AREA; -+ *flags |= V4L2_CTRL_FLAG_READ_ONLY; -+ break; -+ case V4L2_CID_COLORIMETRY_HDR10_CLL_INFO: -+ *type = V4L2_CTRL_TYPE_HDR10_CLL_INFO; -+ break; -+ case V4L2_CID_COLORIMETRY_HDR10_MASTERING_DISPLAY: -+ *type = V4L2_CTRL_TYPE_HDR10_MASTERING_DISPLAY; -+ break; -+ default: -+ *type = V4L2_CTRL_TYPE_INTEGER; -+ break; -+ } -+ switch (id) { -+ case V4L2_CID_MPEG_AUDIO_ENCODING: -+ case V4L2_CID_MPEG_AUDIO_MODE: -+ case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: -+ case V4L2_CID_MPEG_VIDEO_B_FRAMES: -+ case V4L2_CID_MPEG_STREAM_TYPE: -+ *flags |= V4L2_CTRL_FLAG_UPDATE; -+ break; -+ case V4L2_CID_AUDIO_VOLUME: -+ case V4L2_CID_AUDIO_BALANCE: -+ case V4L2_CID_AUDIO_BASS: -+ case V4L2_CID_AUDIO_TREBLE: -+ case V4L2_CID_BRIGHTNESS: -+ case V4L2_CID_CONTRAST: -+ case V4L2_CID_SATURATION: -+ case V4L2_CID_HUE: -+ case V4L2_CID_RED_BALANCE: -+ case V4L2_CID_BLUE_BALANCE: -+ case V4L2_CID_GAMMA: -+ case V4L2_CID_SHARPNESS: -+ case V4L2_CID_CHROMA_GAIN: -+ case V4L2_CID_RDS_TX_DEVIATION: -+ case V4L2_CID_AUDIO_LIMITER_RELEASE_TIME: -+ case V4L2_CID_AUDIO_LIMITER_DEVIATION: -+ case V4L2_CID_AUDIO_COMPRESSION_GAIN: -+ case V4L2_CID_AUDIO_COMPRESSION_THRESHOLD: -+ case V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME: -+ case V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME: -+ case V4L2_CID_PILOT_TONE_DEVIATION: -+ case V4L2_CID_PILOT_TONE_FREQUENCY: -+ case V4L2_CID_TUNE_POWER_LEVEL: -+ case V4L2_CID_TUNE_ANTENNA_CAPACITOR: -+ case V4L2_CID_RF_TUNER_RF_GAIN: -+ case V4L2_CID_RF_TUNER_LNA_GAIN: -+ case V4L2_CID_RF_TUNER_MIXER_GAIN: -+ case V4L2_CID_RF_TUNER_IF_GAIN: -+ case V4L2_CID_RF_TUNER_BANDWIDTH: -+ case V4L2_CID_DETECT_MD_GLOBAL_THRESHOLD: -+ *flags |= V4L2_CTRL_FLAG_SLIDER; -+ break; -+ case V4L2_CID_PAN_RELATIVE: -+ case V4L2_CID_TILT_RELATIVE: -+ case V4L2_CID_FOCUS_RELATIVE: -+ case V4L2_CID_IRIS_RELATIVE: -+ case V4L2_CID_ZOOM_RELATIVE: -+ *flags |= V4L2_CTRL_FLAG_WRITE_ONLY | -+ V4L2_CTRL_FLAG_EXECUTE_ON_WRITE; -+ break; -+ case V4L2_CID_FLASH_STROBE_STATUS: -+ case V4L2_CID_AUTO_FOCUS_STATUS: -+ case V4L2_CID_FLASH_READY: -+ case V4L2_CID_DV_TX_HOTPLUG: -+ case V4L2_CID_DV_TX_RXSENSE: -+ case V4L2_CID_DV_TX_EDID_PRESENT: -+ case V4L2_CID_DV_RX_POWER_PRESENT: -+ case V4L2_CID_DV_RX_IT_CONTENT_TYPE: -+ case V4L2_CID_RDS_RX_PTY: -+ case V4L2_CID_RDS_RX_PS_NAME: -+ case V4L2_CID_RDS_RX_RADIO_TEXT: -+ case V4L2_CID_RDS_RX_TRAFFIC_ANNOUNCEMENT: -+ case V4L2_CID_RDS_RX_TRAFFIC_PROGRAM: -+ case V4L2_CID_RDS_RX_MUSIC_SPEECH: -+ case V4L2_CID_CAMERA_ORIENTATION: -+ case V4L2_CID_CAMERA_SENSOR_ROTATION: -+ *flags |= V4L2_CTRL_FLAG_READ_ONLY; -+ break; -+ case V4L2_CID_RF_TUNER_PLL_LOCK: -+ *flags |= V4L2_CTRL_FLAG_VOLATILE; -+ break; -+ } -+} -+EXPORT_SYMBOL(v4l2_ctrl_fill); -+ -+static u32 user_flags(const struct v4l2_ctrl *ctrl) -+{ -+ u32 flags = ctrl->flags; -+ -+ if (ctrl->is_ptr) -+ flags |= V4L2_CTRL_FLAG_HAS_PAYLOAD; -+ -+ return flags; -+} -+ -+static void fill_event(struct v4l2_event *ev, struct v4l2_ctrl *ctrl, u32 changes) -+{ -+ memset(ev, 0, sizeof(*ev)); -+ ev->type = V4L2_EVENT_CTRL; -+ ev->id = ctrl->id; -+ ev->u.ctrl.changes = changes; -+ ev->u.ctrl.type = ctrl->type; -+ ev->u.ctrl.flags = user_flags(ctrl); -+ if (ctrl->is_ptr) -+ ev->u.ctrl.value64 = 0; -+ else -+ ev->u.ctrl.value64 = *ctrl->p_cur.p_s64; -+ ev->u.ctrl.minimum = ctrl->minimum; -+ ev->u.ctrl.maximum = ctrl->maximum; -+ if (ctrl->type == V4L2_CTRL_TYPE_MENU -+ || ctrl->type == V4L2_CTRL_TYPE_INTEGER_MENU) -+ ev->u.ctrl.step = 1; -+ else -+ ev->u.ctrl.step = ctrl->step; -+ ev->u.ctrl.default_value = ctrl->default_value; -+} -+ -+static void send_event(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, u32 changes) -+{ -+ struct v4l2_event ev; -+ struct v4l2_subscribed_event *sev; -+ -+ if (list_empty(&ctrl->ev_subs)) -+ return; -+ fill_event(&ev, ctrl, changes); -+ -+ list_for_each_entry(sev, &ctrl->ev_subs, node) -+ if (sev->fh != fh || -+ (sev->flags & V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK)) -+ v4l2_event_queue_fh(sev->fh, &ev); -+} -+ -+static bool std_equal(const struct v4l2_ctrl *ctrl, u32 idx, -+ union v4l2_ctrl_ptr ptr1, -+ union v4l2_ctrl_ptr ptr2) -+{ -+ switch (ctrl->type) { -+ case V4L2_CTRL_TYPE_BUTTON: -+ return false; -+ case V4L2_CTRL_TYPE_STRING: -+ idx *= ctrl->elem_size; -+ /* strings are always 0-terminated */ -+ return !strcmp(ptr1.p_char + idx, ptr2.p_char + idx); -+ case V4L2_CTRL_TYPE_INTEGER64: -+ return ptr1.p_s64[idx] == ptr2.p_s64[idx]; -+ case V4L2_CTRL_TYPE_U8: -+ return ptr1.p_u8[idx] == ptr2.p_u8[idx]; -+ case V4L2_CTRL_TYPE_U16: -+ return ptr1.p_u16[idx] == ptr2.p_u16[idx]; -+ case V4L2_CTRL_TYPE_U32: -+ return ptr1.p_u32[idx] == ptr2.p_u32[idx]; -+ default: -+ if (ctrl->is_int) -+ return ptr1.p_s32[idx] == ptr2.p_s32[idx]; -+ idx *= ctrl->elem_size; -+ return !memcmp(ptr1.p_const + idx, ptr2.p_const + idx, -+ ctrl->elem_size); -+ } -+} -+ -+static void std_init_compound(const struct v4l2_ctrl *ctrl, u32 idx, -+ union v4l2_ctrl_ptr ptr) -+{ -+ struct v4l2_ctrl_mpeg2_slice_params *p_mpeg2_slice_params; -+ struct v4l2_ctrl_vp8_frame *p_vp8_frame; -+ struct v4l2_ctrl_fwht_params *p_fwht_params; -+ void *p = ptr.p + idx * ctrl->elem_size; -+ -+ if (ctrl->p_def.p_const) -+ memcpy(p, ctrl->p_def.p_const, ctrl->elem_size); -+ else -+ memset(p, 0, ctrl->elem_size); -+ -+ /* -+ * The cast is needed to get rid of a gcc warning complaining that -+ * V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS is not part of the -+ * v4l2_ctrl_type enum. -+ */ -+ switch ((u32)ctrl->type) { -+ case V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS: -+ p_mpeg2_slice_params = p; -+ /* 4:2:0 */ -+ p_mpeg2_slice_params->sequence.chroma_format = 1; -+ /* interlaced top field */ -+ p_mpeg2_slice_params->picture.picture_structure = 1; -+ p_mpeg2_slice_params->picture.picture_coding_type = -+ V4L2_MPEG2_PICTURE_CODING_TYPE_I; -+ break; -+ case V4L2_CTRL_TYPE_VP8_FRAME: -+ p_vp8_frame = p; -+ p_vp8_frame->num_dct_parts = 1; -+ break; -+ case V4L2_CTRL_TYPE_FWHT_PARAMS: -+ p_fwht_params = p; -+ p_fwht_params->version = V4L2_FWHT_VERSION; -+ p_fwht_params->width = 1280; -+ p_fwht_params->height = 720; -+ p_fwht_params->flags = V4L2_FWHT_FL_PIXENC_YUV | -+ (2 << V4L2_FWHT_FL_COMPONENTS_NUM_OFFSET); -+ break; -+ } -+} -+ -+static void std_init(const struct v4l2_ctrl *ctrl, u32 idx, -+ union v4l2_ctrl_ptr ptr) -+{ -+ switch (ctrl->type) { -+ case V4L2_CTRL_TYPE_STRING: -+ idx *= ctrl->elem_size; -+ memset(ptr.p_char + idx, ' ', ctrl->minimum); -+ ptr.p_char[idx + ctrl->minimum] = '\0'; -+ break; -+ case V4L2_CTRL_TYPE_INTEGER64: -+ ptr.p_s64[idx] = ctrl->default_value; -+ break; -+ case V4L2_CTRL_TYPE_INTEGER: -+ case V4L2_CTRL_TYPE_INTEGER_MENU: -+ case V4L2_CTRL_TYPE_MENU: -+ case V4L2_CTRL_TYPE_BITMASK: -+ case V4L2_CTRL_TYPE_BOOLEAN: -+ ptr.p_s32[idx] = ctrl->default_value; -+ break; -+ case V4L2_CTRL_TYPE_BUTTON: -+ case V4L2_CTRL_TYPE_CTRL_CLASS: -+ ptr.p_s32[idx] = 0; -+ break; -+ case V4L2_CTRL_TYPE_U8: -+ ptr.p_u8[idx] = ctrl->default_value; -+ break; -+ case V4L2_CTRL_TYPE_U16: -+ ptr.p_u16[idx] = ctrl->default_value; -+ break; -+ case V4L2_CTRL_TYPE_U32: -+ ptr.p_u32[idx] = ctrl->default_value; -+ break; -+ default: -+ std_init_compound(ctrl, idx, ptr); -+ break; -+ } -+} -+ -+static void std_log(const struct v4l2_ctrl *ctrl) -+{ -+ union v4l2_ctrl_ptr ptr = ctrl->p_cur; -+ -+ if (ctrl->is_array) { -+ unsigned i; -+ -+ for (i = 0; i < ctrl->nr_of_dims; i++) -+ pr_cont("[%u]", ctrl->dims[i]); -+ pr_cont(" "); -+ } -+ -+ switch (ctrl->type) { -+ case V4L2_CTRL_TYPE_INTEGER: -+ pr_cont("%d", *ptr.p_s32); -+ break; -+ case V4L2_CTRL_TYPE_BOOLEAN: -+ pr_cont("%s", *ptr.p_s32 ? "true" : "false"); -+ break; -+ case V4L2_CTRL_TYPE_MENU: -+ pr_cont("%s", ctrl->qmenu[*ptr.p_s32]); -+ break; -+ case V4L2_CTRL_TYPE_INTEGER_MENU: -+ pr_cont("%lld", ctrl->qmenu_int[*ptr.p_s32]); -+ break; -+ case V4L2_CTRL_TYPE_BITMASK: -+ pr_cont("0x%08x", *ptr.p_s32); -+ break; -+ case V4L2_CTRL_TYPE_INTEGER64: -+ pr_cont("%lld", *ptr.p_s64); -+ break; -+ case V4L2_CTRL_TYPE_STRING: -+ pr_cont("%s", ptr.p_char); -+ break; -+ case V4L2_CTRL_TYPE_U8: -+ pr_cont("%u", (unsigned)*ptr.p_u8); -+ break; -+ case V4L2_CTRL_TYPE_U16: -+ pr_cont("%u", (unsigned)*ptr.p_u16); -+ break; -+ case V4L2_CTRL_TYPE_U32: -+ pr_cont("%u", (unsigned)*ptr.p_u32); -+ break; -+ case V4L2_CTRL_TYPE_H264_SPS: -+ pr_cont("H264_SPS"); -+ break; -+ case V4L2_CTRL_TYPE_H264_PPS: -+ pr_cont("H264_PPS"); -+ break; -+ case V4L2_CTRL_TYPE_H264_SCALING_MATRIX: -+ pr_cont("H264_SCALING_MATRIX"); -+ break; -+ case V4L2_CTRL_TYPE_H264_SLICE_PARAMS: -+ pr_cont("H264_SLICE_PARAMS"); -+ break; -+ case V4L2_CTRL_TYPE_H264_DECODE_PARAMS: -+ pr_cont("H264_DECODE_PARAMS"); -+ break; -+ case V4L2_CTRL_TYPE_H264_PRED_WEIGHTS: -+ pr_cont("H264_PRED_WEIGHTS"); -+ break; -+ case V4L2_CTRL_TYPE_FWHT_PARAMS: -+ pr_cont("FWHT_PARAMS"); -+ break; -+ case V4L2_CTRL_TYPE_VP8_FRAME: -+ pr_cont("VP8_FRAME"); -+ break; -+ case V4L2_CTRL_TYPE_HDR10_CLL_INFO: -+ pr_cont("HDR10_CLL_INFO"); -+ break; -+ case V4L2_CTRL_TYPE_HDR10_MASTERING_DISPLAY: -+ pr_cont("HDR10_MASTERING_DISPLAY"); -+ break; -+ default: -+ pr_cont("unknown type %d", ctrl->type); -+ break; -+ } -+} -+ -+/* -+ * Round towards the closest legal value. Be careful when we are -+ * close to the maximum range of the control type to prevent -+ * wrap-arounds. -+ */ -+#define ROUND_TO_RANGE(val, offset_type, ctrl) \ -+({ \ -+ offset_type offset; \ -+ if ((ctrl)->maximum >= 0 && \ -+ val >= (ctrl)->maximum - (s32)((ctrl)->step / 2)) \ -+ val = (ctrl)->maximum; \ -+ else \ -+ val += (s32)((ctrl)->step / 2); \ -+ val = clamp_t(typeof(val), val, \ -+ (ctrl)->minimum, (ctrl)->maximum); \ -+ offset = (val) - (ctrl)->minimum; \ -+ offset = (ctrl)->step * (offset / (u32)(ctrl)->step); \ -+ val = (ctrl)->minimum + offset; \ -+ 0; \ -+}) -+ -+/* Validate a new control */ -+ -+#define zero_padding(s) \ -+ memset(&(s).padding, 0, sizeof((s).padding)) -+#define zero_reserved(s) \ -+ memset(&(s).reserved, 0, sizeof((s).reserved)) -+ -+/* -+ * Compound controls validation requires setting unused fields/flags to zero -+ * in order to properly detect unchanged controls with std_equal's memcmp. -+ */ -+static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx, -+ union v4l2_ctrl_ptr ptr) -+{ -+ struct v4l2_ctrl_mpeg2_slice_params *p_mpeg2_slice_params; -+ struct v4l2_ctrl_vp8_frame *p_vp8_frame; -+ struct v4l2_ctrl_fwht_params *p_fwht_params; -+ struct v4l2_ctrl_h264_sps *p_h264_sps; -+ struct v4l2_ctrl_h264_pps *p_h264_pps; -+ struct v4l2_ctrl_h264_pred_weights *p_h264_pred_weights; -+ struct v4l2_ctrl_h264_slice_params *p_h264_slice_params; -+ struct v4l2_ctrl_h264_decode_params *p_h264_dec_params; -+ struct v4l2_ctrl_hevc_sps *p_hevc_sps; -+ struct v4l2_ctrl_hevc_pps *p_hevc_pps; -+ struct v4l2_ctrl_hevc_slice_params *p_hevc_slice_params; -+ struct v4l2_ctrl_hdr10_mastering_display *p_hdr10_mastering; -+ struct v4l2_area *area; -+ void *p = ptr.p + idx * ctrl->elem_size; -+ unsigned int i; -+ -+ switch ((u32)ctrl->type) { -+ case V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS: -+ p_mpeg2_slice_params = p; -+ -+ switch (p_mpeg2_slice_params->sequence.chroma_format) { -+ case 1: /* 4:2:0 */ -+ case 2: /* 4:2:2 */ -+ case 3: /* 4:4:4 */ -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ switch (p_mpeg2_slice_params->picture.intra_dc_precision) { -+ case 0: /* 8 bits */ -+ case 1: /* 9 bits */ -+ case 2: /* 10 bits */ -+ case 3: /* 11 bits */ -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ switch (p_mpeg2_slice_params->picture.picture_structure) { -+ case 1: /* interlaced top field */ -+ case 2: /* interlaced bottom field */ -+ case 3: /* progressive */ -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ switch (p_mpeg2_slice_params->picture.picture_coding_type) { -+ case V4L2_MPEG2_PICTURE_CODING_TYPE_I: -+ case V4L2_MPEG2_PICTURE_CODING_TYPE_P: -+ case V4L2_MPEG2_PICTURE_CODING_TYPE_B: -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ break; -+ -+ case V4L2_CTRL_TYPE_MPEG2_QUANTIZATION: -+ break; -+ -+ case V4L2_CTRL_TYPE_FWHT_PARAMS: -+ p_fwht_params = p; -+ if (p_fwht_params->version < V4L2_FWHT_VERSION) -+ return -EINVAL; -+ if (!p_fwht_params->width || !p_fwht_params->height) -+ return -EINVAL; -+ break; -+ -+ case V4L2_CTRL_TYPE_H264_SPS: -+ p_h264_sps = p; -+ -+ /* Some syntax elements are only conditionally valid */ -+ if (p_h264_sps->pic_order_cnt_type != 0) { -+ p_h264_sps->log2_max_pic_order_cnt_lsb_minus4 = 0; -+ } else if (p_h264_sps->pic_order_cnt_type != 1) { -+ p_h264_sps->num_ref_frames_in_pic_order_cnt_cycle = 0; -+ p_h264_sps->offset_for_non_ref_pic = 0; -+ p_h264_sps->offset_for_top_to_bottom_field = 0; -+ memset(&p_h264_sps->offset_for_ref_frame, 0, -+ sizeof(p_h264_sps->offset_for_ref_frame)); -+ } -+ -+ if (!V4L2_H264_SPS_HAS_CHROMA_FORMAT(p_h264_sps)) { -+ p_h264_sps->chroma_format_idc = 1; -+ p_h264_sps->bit_depth_luma_minus8 = 0; -+ p_h264_sps->bit_depth_chroma_minus8 = 0; -+ -+ p_h264_sps->flags &= -+ ~V4L2_H264_SPS_FLAG_QPPRIME_Y_ZERO_TRANSFORM_BYPASS; -+ -+ if (p_h264_sps->chroma_format_idc < 3) -+ p_h264_sps->flags &= -+ ~V4L2_H264_SPS_FLAG_SEPARATE_COLOUR_PLANE; -+ } -+ -+ if (p_h264_sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY) -+ p_h264_sps->flags &= -+ ~V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD; -+ -+ /* -+ * Chroma 4:2:2 format require at least High 4:2:2 profile. -+ * -+ * The H264 specification and well-known parser implementations -+ * use profile-idc values directly, as that is clearer and -+ * less ambiguous. We do the same here. -+ */ -+ if (p_h264_sps->profile_idc < 122 && -+ p_h264_sps->chroma_format_idc > 1) -+ return -EINVAL; -+ /* Chroma 4:4:4 format require at least High 4:2:2 profile */ -+ if (p_h264_sps->profile_idc < 244 && -+ p_h264_sps->chroma_format_idc > 2) -+ return -EINVAL; -+ if (p_h264_sps->chroma_format_idc > 3) -+ return -EINVAL; -+ -+ if (p_h264_sps->bit_depth_luma_minus8 > 6) -+ return -EINVAL; -+ if (p_h264_sps->bit_depth_chroma_minus8 > 6) -+ return -EINVAL; -+ if (p_h264_sps->log2_max_frame_num_minus4 > 12) -+ return -EINVAL; -+ if (p_h264_sps->pic_order_cnt_type > 2) -+ return -EINVAL; -+ if (p_h264_sps->log2_max_pic_order_cnt_lsb_minus4 > 12) -+ return -EINVAL; -+ if (p_h264_sps->max_num_ref_frames > V4L2_H264_REF_LIST_LEN) -+ return -EINVAL; -+ break; -+ -+ case V4L2_CTRL_TYPE_H264_PPS: -+ p_h264_pps = p; -+ -+ if (p_h264_pps->num_slice_groups_minus1 > 7) -+ return -EINVAL; -+ if (p_h264_pps->num_ref_idx_l0_default_active_minus1 > -+ (V4L2_H264_REF_LIST_LEN - 1)) -+ return -EINVAL; -+ if (p_h264_pps->num_ref_idx_l1_default_active_minus1 > -+ (V4L2_H264_REF_LIST_LEN - 1)) -+ return -EINVAL; -+ if (p_h264_pps->weighted_bipred_idc > 2) -+ return -EINVAL; -+ /* -+ * pic_init_qp_minus26 shall be in the range of -+ * -(26 + QpBdOffset_y) to +25, inclusive, -+ * where QpBdOffset_y is 6 * bit_depth_luma_minus8 -+ */ -+ if (p_h264_pps->pic_init_qp_minus26 < -62 || -+ p_h264_pps->pic_init_qp_minus26 > 25) -+ return -EINVAL; -+ if (p_h264_pps->pic_init_qs_minus26 < -26 || -+ p_h264_pps->pic_init_qs_minus26 > 25) -+ return -EINVAL; -+ if (p_h264_pps->chroma_qp_index_offset < -12 || -+ p_h264_pps->chroma_qp_index_offset > 12) -+ return -EINVAL; -+ if (p_h264_pps->second_chroma_qp_index_offset < -12 || -+ p_h264_pps->second_chroma_qp_index_offset > 12) -+ return -EINVAL; -+ break; -+ -+ case V4L2_CTRL_TYPE_H264_SCALING_MATRIX: -+ break; -+ -+ case V4L2_CTRL_TYPE_H264_PRED_WEIGHTS: -+ p_h264_pred_weights = p; -+ -+ if (p_h264_pred_weights->luma_log2_weight_denom > 7) -+ return -EINVAL; -+ if (p_h264_pred_weights->chroma_log2_weight_denom > 7) -+ return -EINVAL; -+ break; -+ -+ case V4L2_CTRL_TYPE_H264_SLICE_PARAMS: -+ p_h264_slice_params = p; -+ -+ if (p_h264_slice_params->slice_type != V4L2_H264_SLICE_TYPE_B) -+ p_h264_slice_params->flags &= -+ ~V4L2_H264_SLICE_FLAG_DIRECT_SPATIAL_MV_PRED; -+ -+ if (p_h264_slice_params->colour_plane_id > 2) -+ return -EINVAL; -+ if (p_h264_slice_params->cabac_init_idc > 2) -+ return -EINVAL; -+ if (p_h264_slice_params->disable_deblocking_filter_idc > 2) -+ return -EINVAL; -+ if (p_h264_slice_params->slice_alpha_c0_offset_div2 < -6 || -+ p_h264_slice_params->slice_alpha_c0_offset_div2 > 6) -+ return -EINVAL; -+ if (p_h264_slice_params->slice_beta_offset_div2 < -6 || -+ p_h264_slice_params->slice_beta_offset_div2 > 6) -+ return -EINVAL; -+ -+ if (p_h264_slice_params->slice_type == V4L2_H264_SLICE_TYPE_I || -+ p_h264_slice_params->slice_type == V4L2_H264_SLICE_TYPE_SI) -+ p_h264_slice_params->num_ref_idx_l0_active_minus1 = 0; -+ if (p_h264_slice_params->slice_type != V4L2_H264_SLICE_TYPE_B) -+ p_h264_slice_params->num_ref_idx_l1_active_minus1 = 0; -+ -+ if (p_h264_slice_params->num_ref_idx_l0_active_minus1 > -+ (V4L2_H264_REF_LIST_LEN - 1)) -+ return -EINVAL; -+ if (p_h264_slice_params->num_ref_idx_l1_active_minus1 > -+ (V4L2_H264_REF_LIST_LEN - 1)) -+ return -EINVAL; -+ zero_reserved(*p_h264_slice_params); -+ break; -+ -+ case V4L2_CTRL_TYPE_H264_DECODE_PARAMS: -+ p_h264_dec_params = p; -+ -+ if (p_h264_dec_params->nal_ref_idc > 3) -+ return -EINVAL; -+ for (i = 0; i < V4L2_H264_NUM_DPB_ENTRIES; i++) { -+ struct v4l2_h264_dpb_entry *dpb_entry = -+ &p_h264_dec_params->dpb[i]; -+ -+ zero_reserved(*dpb_entry); -+ } -+ zero_reserved(*p_h264_dec_params); -+ break; -+ -+ case V4L2_CTRL_TYPE_VP8_FRAME: -+ p_vp8_frame = p; -+ -+ switch (p_vp8_frame->num_dct_parts) { -+ case 1: -+ case 2: -+ case 4: -+ case 8: -+ break; -+ default: -+ return -EINVAL; -+ } -+ zero_padding(p_vp8_frame->segment); -+ zero_padding(p_vp8_frame->lf); -+ zero_padding(p_vp8_frame->quant); -+ zero_padding(p_vp8_frame->entropy); -+ zero_padding(p_vp8_frame->coder_state); -+ break; -+ -+ case V4L2_CTRL_TYPE_HEVC_SPS: -+ p_hevc_sps = p; -+ -+ if (!(p_hevc_sps->flags & V4L2_HEVC_SPS_FLAG_PCM_ENABLED)) { -+ p_hevc_sps->pcm_sample_bit_depth_luma_minus1 = 0; -+ p_hevc_sps->pcm_sample_bit_depth_chroma_minus1 = 0; -+ p_hevc_sps->log2_min_pcm_luma_coding_block_size_minus3 = 0; -+ p_hevc_sps->log2_diff_max_min_pcm_luma_coding_block_size = 0; -+ } -+ -+ if (!(p_hevc_sps->flags & -+ V4L2_HEVC_SPS_FLAG_LONG_TERM_REF_PICS_PRESENT)) -+ p_hevc_sps->num_long_term_ref_pics_sps = 0; -+ break; -+ -+ case V4L2_CTRL_TYPE_HEVC_PPS: -+ p_hevc_pps = p; -+ -+ if (!(p_hevc_pps->flags & -+ V4L2_HEVC_PPS_FLAG_CU_QP_DELTA_ENABLED)) -+ p_hevc_pps->diff_cu_qp_delta_depth = 0; -+ -+ if (!(p_hevc_pps->flags & V4L2_HEVC_PPS_FLAG_TILES_ENABLED)) { -+ p_hevc_pps->num_tile_columns_minus1 = 0; -+ p_hevc_pps->num_tile_rows_minus1 = 0; -+ memset(&p_hevc_pps->column_width_minus1, 0, -+ sizeof(p_hevc_pps->column_width_minus1)); -+ memset(&p_hevc_pps->row_height_minus1, 0, -+ sizeof(p_hevc_pps->row_height_minus1)); -+ -+ p_hevc_pps->flags &= -+ ~V4L2_HEVC_PPS_FLAG_LOOP_FILTER_ACROSS_TILES_ENABLED; -+ } -+ -+ if (p_hevc_pps->flags & -+ V4L2_HEVC_PPS_FLAG_PPS_DISABLE_DEBLOCKING_FILTER) { -+ p_hevc_pps->pps_beta_offset_div2 = 0; -+ p_hevc_pps->pps_tc_offset_div2 = 0; -+ } -+ -+ zero_padding(*p_hevc_pps); -+ break; -+ -+ case V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS: -+ p_hevc_slice_params = p; -+ -+ if (p_hevc_slice_params->num_active_dpb_entries > -+ V4L2_HEVC_DPB_ENTRIES_NUM_MAX) -+ return -EINVAL; -+ -+ zero_padding(p_hevc_slice_params->pred_weight_table); -+ -+ for (i = 0; i < p_hevc_slice_params->num_active_dpb_entries; -+ i++) { -+ struct v4l2_hevc_dpb_entry *dpb_entry = -+ &p_hevc_slice_params->dpb[i]; -+ -+ zero_padding(*dpb_entry); -+ } -+ -+ zero_padding(*p_hevc_slice_params); -+ break; -+ -+ case V4L2_CTRL_TYPE_HDR10_CLL_INFO: -+ break; -+ -+ case V4L2_CTRL_TYPE_HDR10_MASTERING_DISPLAY: -+ p_hdr10_mastering = p; -+ -+ for (i = 0; i < 3; ++i) { -+ if (p_hdr10_mastering->display_primaries_x[i] < -+ V4L2_HDR10_MASTERING_PRIMARIES_X_LOW || -+ p_hdr10_mastering->display_primaries_x[i] > -+ V4L2_HDR10_MASTERING_PRIMARIES_X_HIGH || -+ p_hdr10_mastering->display_primaries_y[i] < -+ V4L2_HDR10_MASTERING_PRIMARIES_Y_LOW || -+ p_hdr10_mastering->display_primaries_y[i] > -+ V4L2_HDR10_MASTERING_PRIMARIES_Y_HIGH) -+ return -EINVAL; -+ } -+ -+ if (p_hdr10_mastering->white_point_x < -+ V4L2_HDR10_MASTERING_WHITE_POINT_X_LOW || -+ p_hdr10_mastering->white_point_x > -+ V4L2_HDR10_MASTERING_WHITE_POINT_X_HIGH || -+ p_hdr10_mastering->white_point_y < -+ V4L2_HDR10_MASTERING_WHITE_POINT_Y_LOW || -+ p_hdr10_mastering->white_point_y > -+ V4L2_HDR10_MASTERING_WHITE_POINT_Y_HIGH) -+ return -EINVAL; -+ -+ if (p_hdr10_mastering->max_display_mastering_luminance < -+ V4L2_HDR10_MASTERING_MAX_LUMA_LOW || -+ p_hdr10_mastering->max_display_mastering_luminance > -+ V4L2_HDR10_MASTERING_MAX_LUMA_HIGH || -+ p_hdr10_mastering->min_display_mastering_luminance < -+ V4L2_HDR10_MASTERING_MIN_LUMA_LOW || -+ p_hdr10_mastering->min_display_mastering_luminance > -+ V4L2_HDR10_MASTERING_MIN_LUMA_HIGH) -+ return -EINVAL; -+ -+ /* The following restriction comes from ITU-T Rec. H.265 spec */ -+ if (p_hdr10_mastering->max_display_mastering_luminance == -+ V4L2_HDR10_MASTERING_MAX_LUMA_LOW && -+ p_hdr10_mastering->min_display_mastering_luminance == -+ V4L2_HDR10_MASTERING_MIN_LUMA_HIGH) -+ return -EINVAL; -+ -+ break; -+ -+ case V4L2_CTRL_TYPE_AREA: -+ area = p; -+ if (!area->width || !area->height) -+ return -EINVAL; -+ break; -+ -+ default: -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int std_validate(const struct v4l2_ctrl *ctrl, u32 idx, -+ union v4l2_ctrl_ptr ptr) -+{ -+ size_t len; -+ u64 offset; -+ s64 val; -+ -+ switch ((u32)ctrl->type) { -+ case V4L2_CTRL_TYPE_INTEGER: -+ return ROUND_TO_RANGE(ptr.p_s32[idx], u32, ctrl); -+ case V4L2_CTRL_TYPE_INTEGER64: -+ /* -+ * We can't use the ROUND_TO_RANGE define here due to -+ * the u64 divide that needs special care. -+ */ -+ val = ptr.p_s64[idx]; -+ if (ctrl->maximum >= 0 && val >= ctrl->maximum - (s64)(ctrl->step / 2)) -+ val = ctrl->maximum; -+ else -+ val += (s64)(ctrl->step / 2); -+ val = clamp_t(s64, val, ctrl->minimum, ctrl->maximum); -+ offset = val - ctrl->minimum; -+ do_div(offset, ctrl->step); -+ ptr.p_s64[idx] = ctrl->minimum + offset * ctrl->step; -+ return 0; -+ case V4L2_CTRL_TYPE_U8: -+ return ROUND_TO_RANGE(ptr.p_u8[idx], u8, ctrl); -+ case V4L2_CTRL_TYPE_U16: -+ return ROUND_TO_RANGE(ptr.p_u16[idx], u16, ctrl); -+ case V4L2_CTRL_TYPE_U32: -+ return ROUND_TO_RANGE(ptr.p_u32[idx], u32, ctrl); -+ -+ case V4L2_CTRL_TYPE_BOOLEAN: -+ ptr.p_s32[idx] = !!ptr.p_s32[idx]; -+ return 0; -+ -+ case V4L2_CTRL_TYPE_MENU: -+ case V4L2_CTRL_TYPE_INTEGER_MENU: -+ if (ptr.p_s32[idx] < ctrl->minimum || ptr.p_s32[idx] > ctrl->maximum) -+ return -ERANGE; -+ if (ptr.p_s32[idx] < BITS_PER_LONG_LONG && -+ (ctrl->menu_skip_mask & BIT_ULL(ptr.p_s32[idx]))) -+ return -EINVAL; -+ if (ctrl->type == V4L2_CTRL_TYPE_MENU && -+ ctrl->qmenu[ptr.p_s32[idx]][0] == '\0') -+ return -EINVAL; -+ return 0; -+ -+ case V4L2_CTRL_TYPE_BITMASK: -+ ptr.p_s32[idx] &= ctrl->maximum; -+ return 0; -+ -+ case V4L2_CTRL_TYPE_BUTTON: -+ case V4L2_CTRL_TYPE_CTRL_CLASS: -+ ptr.p_s32[idx] = 0; -+ return 0; -+ -+ case V4L2_CTRL_TYPE_STRING: -+ idx *= ctrl->elem_size; -+ len = strlen(ptr.p_char + idx); -+ if (len < ctrl->minimum) -+ return -ERANGE; -+ if ((len - (u32)ctrl->minimum) % (u32)ctrl->step) -+ return -ERANGE; -+ return 0; -+ -+ default: -+ return std_validate_compound(ctrl, idx, ptr); -+ } -+} -+ -+static const struct v4l2_ctrl_type_ops std_type_ops = { -+ .equal = std_equal, -+ .init = std_init, -+ .log = std_log, -+ .validate = std_validate, -+}; -+ -+/* Helper function: copy the given control value back to the caller */ -+static int ptr_to_user(struct v4l2_ext_control *c, -+ struct v4l2_ctrl *ctrl, -+ union v4l2_ctrl_ptr ptr) -+{ -+ u32 len; -+ -+ if (ctrl->is_ptr && !ctrl->is_string) -+ return copy_to_user(c->ptr, ptr.p_const, c->size) ? -+ -EFAULT : 0; -+ -+ switch (ctrl->type) { -+ case V4L2_CTRL_TYPE_STRING: -+ len = strlen(ptr.p_char); -+ if (c->size < len + 1) { -+ c->size = ctrl->elem_size; -+ return -ENOSPC; -+ } -+ return copy_to_user(c->string, ptr.p_char, len + 1) ? -+ -EFAULT : 0; -+ case V4L2_CTRL_TYPE_INTEGER64: -+ c->value64 = *ptr.p_s64; -+ break; -+ default: -+ c->value = *ptr.p_s32; -+ break; -+ } -+ return 0; -+} -+ -+/* Helper function: copy the current control value back to the caller */ -+static int cur_to_user(struct v4l2_ext_control *c, -+ struct v4l2_ctrl *ctrl) -+{ -+ return ptr_to_user(c, ctrl, ctrl->p_cur); -+} -+ -+/* Helper function: copy the new control value back to the caller */ -+static int new_to_user(struct v4l2_ext_control *c, -+ struct v4l2_ctrl *ctrl) -+{ -+ return ptr_to_user(c, ctrl, ctrl->p_new); -+} -+ -+/* Helper function: copy the request value back to the caller */ -+static int req_to_user(struct v4l2_ext_control *c, -+ struct v4l2_ctrl_ref *ref) -+{ -+ return ptr_to_user(c, ref->ctrl, ref->p_req); -+} -+ -+/* Helper function: copy the initial control value back to the caller */ -+static int def_to_user(struct v4l2_ext_control *c, struct v4l2_ctrl *ctrl) -+{ -+ int idx; -+ -+ for (idx = 0; idx < ctrl->elems; idx++) -+ ctrl->type_ops->init(ctrl, idx, ctrl->p_new); -+ -+ return ptr_to_user(c, ctrl, ctrl->p_new); -+} -+ -+/* Helper function: copy the caller-provider value to the given control value */ -+static int user_to_ptr(struct v4l2_ext_control *c, -+ struct v4l2_ctrl *ctrl, -+ union v4l2_ctrl_ptr ptr) -+{ -+ int ret; -+ u32 size; -+ -+ ctrl->is_new = 1; -+ if (ctrl->is_ptr && !ctrl->is_string) { -+ unsigned idx; -+ -+ ret = copy_from_user(ptr.p, c->ptr, c->size) ? -EFAULT : 0; -+ if (ret || !ctrl->is_array) -+ return ret; -+ for (idx = c->size / ctrl->elem_size; idx < ctrl->elems; idx++) -+ ctrl->type_ops->init(ctrl, idx, ptr); -+ return 0; -+ } -+ -+ switch (ctrl->type) { -+ case V4L2_CTRL_TYPE_INTEGER64: -+ *ptr.p_s64 = c->value64; -+ break; -+ case V4L2_CTRL_TYPE_STRING: -+ size = c->size; -+ if (size == 0) -+ return -ERANGE; -+ if (size > ctrl->maximum + 1) -+ size = ctrl->maximum + 1; -+ ret = copy_from_user(ptr.p_char, c->string, size) ? -EFAULT : 0; -+ if (!ret) { -+ char last = ptr.p_char[size - 1]; -+ -+ ptr.p_char[size - 1] = 0; -+ /* If the string was longer than ctrl->maximum, -+ then return an error. */ -+ if (strlen(ptr.p_char) == ctrl->maximum && last) -+ return -ERANGE; -+ } -+ return ret; -+ default: -+ *ptr.p_s32 = c->value; -+ break; -+ } -+ return 0; -+} -+ -+/* Helper function: copy the caller-provider value as the new control value */ -+static int user_to_new(struct v4l2_ext_control *c, -+ struct v4l2_ctrl *ctrl) -+{ -+ return user_to_ptr(c, ctrl, ctrl->p_new); -+} -+ -+/* Copy the one value to another. */ -+static void ptr_to_ptr(struct v4l2_ctrl *ctrl, -+ union v4l2_ctrl_ptr from, union v4l2_ctrl_ptr to) -+{ -+ if (ctrl == NULL) -+ return; -+ memcpy(to.p, from.p_const, ctrl->elems * ctrl->elem_size); -+} -+ -+/* Copy the new value to the current value. */ -+static void new_to_cur(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, u32 ch_flags) -+{ -+ bool changed; -+ -+ if (ctrl == NULL) -+ return; -+ -+ /* has_changed is set by cluster_changed */ -+ changed = ctrl->has_changed; -+ if (changed) -+ ptr_to_ptr(ctrl, ctrl->p_new, ctrl->p_cur); -+ -+ if (ch_flags & V4L2_EVENT_CTRL_CH_FLAGS) { -+ /* Note: CH_FLAGS is only set for auto clusters. */ -+ ctrl->flags &= -+ ~(V4L2_CTRL_FLAG_INACTIVE | V4L2_CTRL_FLAG_VOLATILE); -+ if (!is_cur_manual(ctrl->cluster[0])) { -+ ctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; -+ if (ctrl->cluster[0]->has_volatiles) -+ ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; -+ } -+ fh = NULL; -+ } -+ if (changed || ch_flags) { -+ /* If a control was changed that was not one of the controls -+ modified by the application, then send the event to all. */ -+ if (!ctrl->is_new) -+ fh = NULL; -+ send_event(fh, ctrl, -+ (changed ? V4L2_EVENT_CTRL_CH_VALUE : 0) | ch_flags); -+ if (ctrl->call_notify && changed && ctrl->handler->notify) -+ ctrl->handler->notify(ctrl, ctrl->handler->notify_priv); -+ } -+} -+ -+/* Copy the current value to the new value */ -+static void cur_to_new(struct v4l2_ctrl *ctrl) -+{ -+ if (ctrl == NULL) -+ return; -+ ptr_to_ptr(ctrl, ctrl->p_cur, ctrl->p_new); -+} -+ -+/* Copy the new value to the request value */ -+static void new_to_req(struct v4l2_ctrl_ref *ref) -+{ -+ if (!ref) -+ return; -+ ptr_to_ptr(ref->ctrl, ref->ctrl->p_new, ref->p_req); -+ ref->valid_p_req = true; -+} -+ -+/* Copy the current value to the request value */ -+static void cur_to_req(struct v4l2_ctrl_ref *ref) -+{ -+ if (!ref) -+ return; -+ ptr_to_ptr(ref->ctrl, ref->ctrl->p_cur, ref->p_req); -+ ref->valid_p_req = true; -+} -+ -+/* Copy the request value to the new value */ -+static void req_to_new(struct v4l2_ctrl_ref *ref) -+{ -+ if (!ref) -+ return; -+ if (ref->valid_p_req) -+ ptr_to_ptr(ref->ctrl, ref->p_req, ref->ctrl->p_new); -+ else -+ ptr_to_ptr(ref->ctrl, ref->ctrl->p_cur, ref->ctrl->p_new); -+} -+ -+/* Return non-zero if one or more of the controls in the cluster has a new -+ value that differs from the current value. */ -+static int cluster_changed(struct v4l2_ctrl *master) -+{ -+ bool changed = false; -+ unsigned idx; -+ int i; -+ -+ for (i = 0; i < master->ncontrols; i++) { -+ struct v4l2_ctrl *ctrl = master->cluster[i]; -+ bool ctrl_changed = false; -+ -+ if (ctrl == NULL) -+ continue; -+ -+ if (ctrl->flags & V4L2_CTRL_FLAG_EXECUTE_ON_WRITE) -+ changed = ctrl_changed = true; -+ -+ /* -+ * Set has_changed to false to avoid generating -+ * the event V4L2_EVENT_CTRL_CH_VALUE -+ */ -+ if (ctrl->flags & V4L2_CTRL_FLAG_VOLATILE) { -+ ctrl->has_changed = false; -+ continue; -+ } -+ -+ for (idx = 0; !ctrl_changed && idx < ctrl->elems; idx++) -+ ctrl_changed = !ctrl->type_ops->equal(ctrl, idx, -+ ctrl->p_cur, ctrl->p_new); -+ ctrl->has_changed = ctrl_changed; -+ changed |= ctrl->has_changed; -+ } -+ return changed; -+} -+ -+/* Control range checking */ -+static int check_range(enum v4l2_ctrl_type type, -+ s64 min, s64 max, u64 step, s64 def) -+{ -+ switch (type) { -+ case V4L2_CTRL_TYPE_BOOLEAN: -+ if (step != 1 || max > 1 || min < 0) -+ return -ERANGE; -+ fallthrough; -+ case V4L2_CTRL_TYPE_U8: -+ case V4L2_CTRL_TYPE_U16: -+ case V4L2_CTRL_TYPE_U32: -+ case V4L2_CTRL_TYPE_INTEGER: -+ case V4L2_CTRL_TYPE_INTEGER64: -+ if (step == 0 || min > max || def < min || def > max) -+ return -ERANGE; -+ return 0; -+ case V4L2_CTRL_TYPE_BITMASK: -+ if (step || min || !max || (def & ~max)) -+ return -ERANGE; -+ return 0; -+ case V4L2_CTRL_TYPE_MENU: -+ case V4L2_CTRL_TYPE_INTEGER_MENU: -+ if (min > max || def < min || def > max) -+ return -ERANGE; -+ /* Note: step == menu_skip_mask for menu controls. -+ So here we check if the default value is masked out. */ -+ if (step && ((1 << def) & step)) -+ return -EINVAL; -+ return 0; -+ case V4L2_CTRL_TYPE_STRING: -+ if (min > max || min < 0 || step < 1 || def) -+ return -ERANGE; -+ return 0; -+ default: -+ return 0; -+ } -+} -+ -+/* Validate a new control */ -+static int validate_new(const struct v4l2_ctrl *ctrl, union v4l2_ctrl_ptr p_new) -+{ -+ unsigned idx; -+ int err = 0; -+ -+ for (idx = 0; !err && idx < ctrl->elems; idx++) -+ err = ctrl->type_ops->validate(ctrl, idx, p_new); -+ return err; -+} -+ -+static inline u32 node2id(struct list_head *node) -+{ -+ return list_entry(node, struct v4l2_ctrl_ref, node)->ctrl->id; -+} -+ -+/* Set the handler's error code if it wasn't set earlier already */ -+static inline int handler_set_err(struct v4l2_ctrl_handler *hdl, int err) -+{ -+ if (hdl->error == 0) -+ hdl->error = err; -+ return err; -+} -+ -+/* Initialize the handler */ -+int v4l2_ctrl_handler_init_class(struct v4l2_ctrl_handler *hdl, -+ unsigned nr_of_controls_hint, -+ struct lock_class_key *key, const char *name) -+{ -+ mutex_init(&hdl->_lock); -+ hdl->lock = &hdl->_lock; -+ lockdep_set_class_and_name(hdl->lock, key, name); -+ INIT_LIST_HEAD(&hdl->ctrls); -+ INIT_LIST_HEAD(&hdl->ctrl_refs); -+ INIT_LIST_HEAD(&hdl->requests); -+ INIT_LIST_HEAD(&hdl->requests_queued); -+ hdl->request_is_queued = false; -+ hdl->nr_of_buckets = 1 + nr_of_controls_hint / 8; -+ hdl->buckets = kvmalloc_array(hdl->nr_of_buckets, -+ sizeof(hdl->buckets[0]), -+ GFP_KERNEL | __GFP_ZERO); -+ hdl->error = hdl->buckets ? 0 : -ENOMEM; -+ media_request_object_init(&hdl->req_obj); -+ return hdl->error; -+} -+EXPORT_SYMBOL(v4l2_ctrl_handler_init_class); -+ -+/* Free all controls and control refs */ -+void v4l2_ctrl_handler_free(struct v4l2_ctrl_handler *hdl) -+{ -+ struct v4l2_ctrl_ref *ref, *next_ref; -+ struct v4l2_ctrl *ctrl, *next_ctrl; -+ struct v4l2_subscribed_event *sev, *next_sev; -+ -+ if (hdl == NULL || hdl->buckets == NULL) -+ return; -+ -+ /* -+ * If the main handler is freed and it is used by handler objects in -+ * outstanding requests, then unbind and put those objects before -+ * freeing the main handler. -+ * -+ * The main handler can be identified by having a NULL ops pointer in -+ * the request object. -+ */ -+ if (!hdl->req_obj.ops && !list_empty(&hdl->requests)) { -+ struct v4l2_ctrl_handler *req, *next_req; -+ -+ list_for_each_entry_safe(req, next_req, &hdl->requests, requests) { -+ media_request_object_unbind(&req->req_obj); -+ media_request_object_put(&req->req_obj); -+ } -+ } -+ mutex_lock(hdl->lock); -+ /* Free all nodes */ -+ list_for_each_entry_safe(ref, next_ref, &hdl->ctrl_refs, node) { -+ list_del(&ref->node); -+ kfree(ref); -+ } -+ /* Free all controls owned by the handler */ -+ list_for_each_entry_safe(ctrl, next_ctrl, &hdl->ctrls, node) { -+ list_del(&ctrl->node); -+ list_for_each_entry_safe(sev, next_sev, &ctrl->ev_subs, node) -+ list_del(&sev->node); -+ kvfree(ctrl); -+ } -+ kvfree(hdl->buckets); -+ hdl->buckets = NULL; -+ hdl->cached = NULL; -+ hdl->error = 0; -+ mutex_unlock(hdl->lock); -+ mutex_destroy(&hdl->_lock); -+} -+EXPORT_SYMBOL(v4l2_ctrl_handler_free); -+ -+/* For backwards compatibility: V4L2_CID_PRIVATE_BASE should no longer -+ be used except in G_CTRL, S_CTRL, QUERYCTRL and QUERYMENU when dealing -+ with applications that do not use the NEXT_CTRL flag. -+ -+ We just find the n-th private user control. It's O(N), but that should not -+ be an issue in this particular case. */ -+static struct v4l2_ctrl_ref *find_private_ref( -+ struct v4l2_ctrl_handler *hdl, u32 id) -+{ -+ struct v4l2_ctrl_ref *ref; -+ -+ id -= V4L2_CID_PRIVATE_BASE; -+ list_for_each_entry(ref, &hdl->ctrl_refs, node) { -+ /* Search for private user controls that are compatible with -+ VIDIOC_G/S_CTRL. */ -+ if (V4L2_CTRL_ID2WHICH(ref->ctrl->id) == V4L2_CTRL_CLASS_USER && -+ V4L2_CTRL_DRIVER_PRIV(ref->ctrl->id)) { -+ if (!ref->ctrl->is_int) -+ continue; -+ if (id == 0) -+ return ref; -+ id--; -+ } -+ } -+ return NULL; -+} -+ -+/* Find a control with the given ID. */ -+static struct v4l2_ctrl_ref *find_ref(struct v4l2_ctrl_handler *hdl, u32 id) -+{ -+ struct v4l2_ctrl_ref *ref; -+ int bucket; -+ -+ id &= V4L2_CTRL_ID_MASK; -+ -+ /* Old-style private controls need special handling */ -+ if (id >= V4L2_CID_PRIVATE_BASE) -+ return find_private_ref(hdl, id); -+ bucket = id % hdl->nr_of_buckets; -+ -+ /* Simple optimization: cache the last control found */ -+ if (hdl->cached && hdl->cached->ctrl->id == id) -+ return hdl->cached; -+ -+ /* Not in cache, search the hash */ -+ ref = hdl->buckets ? hdl->buckets[bucket] : NULL; -+ while (ref && ref->ctrl->id != id) -+ ref = ref->next; -+ -+ if (ref) -+ hdl->cached = ref; /* cache it! */ -+ return ref; -+} -+ -+/* Find a control with the given ID. Take the handler's lock first. */ -+static struct v4l2_ctrl_ref *find_ref_lock( -+ struct v4l2_ctrl_handler *hdl, u32 id) -+{ -+ struct v4l2_ctrl_ref *ref = NULL; -+ -+ if (hdl) { -+ mutex_lock(hdl->lock); -+ ref = find_ref(hdl, id); -+ mutex_unlock(hdl->lock); -+ } -+ return ref; -+} -+ -+/* Find a control with the given ID. */ -+struct v4l2_ctrl *v4l2_ctrl_find(struct v4l2_ctrl_handler *hdl, u32 id) -+{ -+ struct v4l2_ctrl_ref *ref = find_ref_lock(hdl, id); -+ -+ return ref ? ref->ctrl : NULL; -+} -+EXPORT_SYMBOL(v4l2_ctrl_find); -+ -+/* Allocate a new v4l2_ctrl_ref and hook it into the handler. */ -+static int handler_new_ref(struct v4l2_ctrl_handler *hdl, -+ struct v4l2_ctrl *ctrl, -+ struct v4l2_ctrl_ref **ctrl_ref, -+ bool from_other_dev, bool allocate_req) -+{ -+ struct v4l2_ctrl_ref *ref; -+ struct v4l2_ctrl_ref *new_ref; -+ u32 id = ctrl->id; -+ u32 class_ctrl = V4L2_CTRL_ID2WHICH(id) | 1; -+ int bucket = id % hdl->nr_of_buckets; /* which bucket to use */ -+ unsigned int size_extra_req = 0; -+ -+ if (ctrl_ref) -+ *ctrl_ref = NULL; -+ -+ /* -+ * Automatically add the control class if it is not yet present and -+ * the new control is not a compound control. -+ */ -+ if (ctrl->type < V4L2_CTRL_COMPOUND_TYPES && -+ id != class_ctrl && find_ref_lock(hdl, class_ctrl) == NULL) -+ if (!v4l2_ctrl_new_std(hdl, NULL, class_ctrl, 0, 0, 0, 0)) -+ return hdl->error; -+ -+ if (hdl->error) -+ return hdl->error; -+ -+ if (allocate_req) -+ size_extra_req = ctrl->elems * ctrl->elem_size; -+ new_ref = kzalloc(sizeof(*new_ref) + size_extra_req, GFP_KERNEL); -+ if (!new_ref) -+ return handler_set_err(hdl, -ENOMEM); -+ new_ref->ctrl = ctrl; -+ new_ref->from_other_dev = from_other_dev; -+ if (size_extra_req) -+ new_ref->p_req.p = &new_ref[1]; -+ -+ INIT_LIST_HEAD(&new_ref->node); -+ -+ mutex_lock(hdl->lock); -+ -+ /* Add immediately at the end of the list if the list is empty, or if -+ the last element in the list has a lower ID. -+ This ensures that when elements are added in ascending order the -+ insertion is an O(1) operation. */ -+ if (list_empty(&hdl->ctrl_refs) || id > node2id(hdl->ctrl_refs.prev)) { -+ list_add_tail(&new_ref->node, &hdl->ctrl_refs); -+ goto insert_in_hash; -+ } -+ -+ /* Find insert position in sorted list */ -+ list_for_each_entry(ref, &hdl->ctrl_refs, node) { -+ if (ref->ctrl->id < id) -+ continue; -+ /* Don't add duplicates */ -+ if (ref->ctrl->id == id) { -+ kfree(new_ref); -+ goto unlock; -+ } -+ list_add(&new_ref->node, ref->node.prev); -+ break; -+ } -+ -+insert_in_hash: -+ /* Insert the control node in the hash */ -+ new_ref->next = hdl->buckets[bucket]; -+ hdl->buckets[bucket] = new_ref; -+ if (ctrl_ref) -+ *ctrl_ref = new_ref; -+ if (ctrl->handler == hdl) { -+ /* By default each control starts in a cluster of its own. -+ * new_ref->ctrl is basically a cluster array with one -+ * element, so that's perfect to use as the cluster pointer. -+ * But only do this for the handler that owns the control. -+ */ -+ ctrl->cluster = &new_ref->ctrl; -+ ctrl->ncontrols = 1; -+ } -+ -+unlock: -+ mutex_unlock(hdl->lock); -+ return 0; -+} -+ -+/* Add a new control */ -+static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl, -+ const struct v4l2_ctrl_ops *ops, -+ const struct v4l2_ctrl_type_ops *type_ops, -+ u32 id, const char *name, enum v4l2_ctrl_type type, -+ s64 min, s64 max, u64 step, s64 def, -+ const u32 dims[V4L2_CTRL_MAX_DIMS], u32 elem_size, -+ u32 flags, const char * const *qmenu, -+ const s64 *qmenu_int, const union v4l2_ctrl_ptr p_def, -+ void *priv) -+{ -+ struct v4l2_ctrl *ctrl; -+ unsigned sz_extra; -+ unsigned nr_of_dims = 0; -+ unsigned elems = 1; -+ bool is_array; -+ unsigned tot_ctrl_size; -+ unsigned idx; -+ void *data; -+ int err; -+ -+ if (hdl->error) -+ return NULL; -+ -+ while (dims && dims[nr_of_dims]) { -+ elems *= dims[nr_of_dims]; -+ nr_of_dims++; -+ if (nr_of_dims == V4L2_CTRL_MAX_DIMS) -+ break; -+ } -+ is_array = nr_of_dims > 0; -+ -+ /* Prefill elem_size for all types handled by std_type_ops */ -+ switch ((u32)type) { -+ case V4L2_CTRL_TYPE_INTEGER64: -+ elem_size = sizeof(s64); -+ break; -+ case V4L2_CTRL_TYPE_STRING: -+ elem_size = max + 1; -+ break; -+ case V4L2_CTRL_TYPE_U8: -+ elem_size = sizeof(u8); -+ break; -+ case V4L2_CTRL_TYPE_U16: -+ elem_size = sizeof(u16); -+ break; -+ case V4L2_CTRL_TYPE_U32: -+ elem_size = sizeof(u32); -+ break; -+ case V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS: -+ elem_size = sizeof(struct v4l2_ctrl_mpeg2_slice_params); -+ break; -+ case V4L2_CTRL_TYPE_MPEG2_QUANTIZATION: -+ elem_size = sizeof(struct v4l2_ctrl_mpeg2_quantization); -+ break; -+ case V4L2_CTRL_TYPE_FWHT_PARAMS: -+ elem_size = sizeof(struct v4l2_ctrl_fwht_params); -+ break; -+ case V4L2_CTRL_TYPE_H264_SPS: -+ elem_size = sizeof(struct v4l2_ctrl_h264_sps); -+ break; -+ case V4L2_CTRL_TYPE_H264_PPS: -+ elem_size = sizeof(struct v4l2_ctrl_h264_pps); -+ break; -+ case V4L2_CTRL_TYPE_H264_SCALING_MATRIX: -+ elem_size = sizeof(struct v4l2_ctrl_h264_scaling_matrix); -+ break; -+ case V4L2_CTRL_TYPE_H264_SLICE_PARAMS: -+ elem_size = sizeof(struct v4l2_ctrl_h264_slice_params); -+ break; -+ case V4L2_CTRL_TYPE_H264_DECODE_PARAMS: -+ elem_size = sizeof(struct v4l2_ctrl_h264_decode_params); -+ break; -+ case V4L2_CTRL_TYPE_H264_PRED_WEIGHTS: -+ elem_size = sizeof(struct v4l2_ctrl_h264_pred_weights); -+ break; -+ case V4L2_CTRL_TYPE_VP8_FRAME: -+ elem_size = sizeof(struct v4l2_ctrl_vp8_frame); -+ break; -+ case V4L2_CTRL_TYPE_HEVC_SPS: -+ elem_size = sizeof(struct v4l2_ctrl_hevc_sps); -+ break; -+ case V4L2_CTRL_TYPE_HEVC_PPS: -+ elem_size = sizeof(struct v4l2_ctrl_hevc_pps); -+ break; -+ case V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS: -+ elem_size = sizeof(struct v4l2_ctrl_hevc_slice_params); -+ break; -+ case V4L2_CTRL_TYPE_HDR10_CLL_INFO: -+ elem_size = sizeof(struct v4l2_ctrl_hdr10_cll_info); -+ break; -+ case V4L2_CTRL_TYPE_HDR10_MASTERING_DISPLAY: -+ elem_size = sizeof(struct v4l2_ctrl_hdr10_mastering_display); -+ break; -+ case V4L2_CTRL_TYPE_AREA: -+ elem_size = sizeof(struct v4l2_area); -+ break; -+ default: -+ if (type < V4L2_CTRL_COMPOUND_TYPES) -+ elem_size = sizeof(s32); -+ break; -+ } -+ tot_ctrl_size = elem_size * elems; -+ -+ /* Sanity checks */ -+ if (id == 0 || name == NULL || !elem_size || -+ id >= V4L2_CID_PRIVATE_BASE || -+ (type == V4L2_CTRL_TYPE_MENU && qmenu == NULL) || -+ (type == V4L2_CTRL_TYPE_INTEGER_MENU && qmenu_int == NULL)) { -+ handler_set_err(hdl, -ERANGE); -+ return NULL; -+ } -+ err = check_range(type, min, max, step, def); -+ if (err) { -+ handler_set_err(hdl, err); -+ return NULL; -+ } -+ if (is_array && -+ (type == V4L2_CTRL_TYPE_BUTTON || -+ type == V4L2_CTRL_TYPE_CTRL_CLASS)) { -+ handler_set_err(hdl, -EINVAL); -+ return NULL; -+ } -+ -+ sz_extra = 0; -+ if (type == V4L2_CTRL_TYPE_BUTTON) -+ flags |= V4L2_CTRL_FLAG_WRITE_ONLY | -+ V4L2_CTRL_FLAG_EXECUTE_ON_WRITE; -+ else if (type == V4L2_CTRL_TYPE_CTRL_CLASS) -+ flags |= V4L2_CTRL_FLAG_READ_ONLY; -+ else if (type == V4L2_CTRL_TYPE_INTEGER64 || -+ type == V4L2_CTRL_TYPE_STRING || -+ type >= V4L2_CTRL_COMPOUND_TYPES || -+ is_array) -+ sz_extra += 2 * tot_ctrl_size; -+ -+ if (type >= V4L2_CTRL_COMPOUND_TYPES && p_def.p_const) -+ sz_extra += elem_size; -+ -+ ctrl = kvzalloc(sizeof(*ctrl) + sz_extra, GFP_KERNEL); -+ if (ctrl == NULL) { -+ handler_set_err(hdl, -ENOMEM); -+ return NULL; -+ } -+ -+ INIT_LIST_HEAD(&ctrl->node); -+ INIT_LIST_HEAD(&ctrl->ev_subs); -+ ctrl->handler = hdl; -+ ctrl->ops = ops; -+ ctrl->type_ops = type_ops ? type_ops : &std_type_ops; -+ ctrl->id = id; -+ ctrl->name = name; -+ ctrl->type = type; -+ ctrl->flags = flags; -+ ctrl->minimum = min; -+ ctrl->maximum = max; -+ ctrl->step = step; -+ ctrl->default_value = def; -+ ctrl->is_string = !is_array && type == V4L2_CTRL_TYPE_STRING; -+ ctrl->is_ptr = is_array || type >= V4L2_CTRL_COMPOUND_TYPES || ctrl->is_string; -+ ctrl->is_int = !ctrl->is_ptr && type != V4L2_CTRL_TYPE_INTEGER64; -+ ctrl->is_array = is_array; -+ ctrl->elems = elems; -+ ctrl->nr_of_dims = nr_of_dims; -+ if (nr_of_dims) -+ memcpy(ctrl->dims, dims, nr_of_dims * sizeof(dims[0])); -+ ctrl->elem_size = elem_size; -+ if (type == V4L2_CTRL_TYPE_MENU) -+ ctrl->qmenu = qmenu; -+ else if (type == V4L2_CTRL_TYPE_INTEGER_MENU) -+ ctrl->qmenu_int = qmenu_int; -+ ctrl->priv = priv; -+ ctrl->cur.val = ctrl->val = def; -+ data = &ctrl[1]; -+ -+ if (!ctrl->is_int) { -+ ctrl->p_new.p = data; -+ ctrl->p_cur.p = data + tot_ctrl_size; -+ } else { -+ ctrl->p_new.p = &ctrl->val; -+ ctrl->p_cur.p = &ctrl->cur.val; -+ } -+ -+ if (type >= V4L2_CTRL_COMPOUND_TYPES && p_def.p_const) { -+ ctrl->p_def.p = ctrl->p_cur.p + tot_ctrl_size; -+ memcpy(ctrl->p_def.p, p_def.p_const, elem_size); -+ } -+ -+ for (idx = 0; idx < elems; idx++) { -+ ctrl->type_ops->init(ctrl, idx, ctrl->p_cur); -+ ctrl->type_ops->init(ctrl, idx, ctrl->p_new); -+ } -+ -+ if (handler_new_ref(hdl, ctrl, NULL, false, false)) { -+ kvfree(ctrl); -+ return NULL; -+ } -+ mutex_lock(hdl->lock); -+ list_add_tail(&ctrl->node, &hdl->ctrls); -+ mutex_unlock(hdl->lock); -+ return ctrl; -+} -+ -+struct v4l2_ctrl *v4l2_ctrl_new_custom(struct v4l2_ctrl_handler *hdl, -+ const struct v4l2_ctrl_config *cfg, void *priv) -+{ -+ bool is_menu; -+ struct v4l2_ctrl *ctrl; -+ const char *name = cfg->name; -+ const char * const *qmenu = cfg->qmenu; -+ const s64 *qmenu_int = cfg->qmenu_int; -+ enum v4l2_ctrl_type type = cfg->type; -+ u32 flags = cfg->flags; -+ s64 min = cfg->min; -+ s64 max = cfg->max; -+ u64 step = cfg->step; -+ s64 def = cfg->def; -+ -+ if (name == NULL) -+ v4l2_ctrl_fill(cfg->id, &name, &type, &min, &max, &step, -+ &def, &flags); -+ -+ is_menu = (type == V4L2_CTRL_TYPE_MENU || -+ type == V4L2_CTRL_TYPE_INTEGER_MENU); -+ if (is_menu) -+ WARN_ON(step); -+ else -+ WARN_ON(cfg->menu_skip_mask); -+ if (type == V4L2_CTRL_TYPE_MENU && !qmenu) { -+ qmenu = v4l2_ctrl_get_menu(cfg->id); -+ } else if (type == V4L2_CTRL_TYPE_INTEGER_MENU && !qmenu_int) { -+ handler_set_err(hdl, -EINVAL); -+ return NULL; -+ } -+ -+ ctrl = v4l2_ctrl_new(hdl, cfg->ops, cfg->type_ops, cfg->id, name, -+ type, min, max, -+ is_menu ? cfg->menu_skip_mask : step, def, -+ cfg->dims, cfg->elem_size, -+ flags, qmenu, qmenu_int, cfg->p_def, priv); -+ if (ctrl) -+ ctrl->is_private = cfg->is_private; -+ return ctrl; -+} -+EXPORT_SYMBOL(v4l2_ctrl_new_custom); -+ -+/* Helper function for standard non-menu controls */ -+struct v4l2_ctrl *v4l2_ctrl_new_std(struct v4l2_ctrl_handler *hdl, -+ const struct v4l2_ctrl_ops *ops, -+ u32 id, s64 min, s64 max, u64 step, s64 def) -+{ -+ const char *name; -+ enum v4l2_ctrl_type type; -+ u32 flags; -+ -+ v4l2_ctrl_fill(id, &name, &type, &min, &max, &step, &def, &flags); -+ if (type == V4L2_CTRL_TYPE_MENU || -+ type == V4L2_CTRL_TYPE_INTEGER_MENU || -+ type >= V4L2_CTRL_COMPOUND_TYPES) { -+ handler_set_err(hdl, -EINVAL); -+ return NULL; -+ } -+ return v4l2_ctrl_new(hdl, ops, NULL, id, name, type, -+ min, max, step, def, NULL, 0, -+ flags, NULL, NULL, ptr_null, NULL); -+} -+EXPORT_SYMBOL(v4l2_ctrl_new_std); -+ -+/* Helper function for standard menu controls */ -+struct v4l2_ctrl *v4l2_ctrl_new_std_menu(struct v4l2_ctrl_handler *hdl, -+ const struct v4l2_ctrl_ops *ops, -+ u32 id, u8 _max, u64 mask, u8 _def) -+{ -+ const char * const *qmenu = NULL; -+ const s64 *qmenu_int = NULL; -+ unsigned int qmenu_int_len = 0; -+ const char *name; -+ enum v4l2_ctrl_type type; -+ s64 min; -+ s64 max = _max; -+ s64 def = _def; -+ u64 step; -+ u32 flags; -+ -+ v4l2_ctrl_fill(id, &name, &type, &min, &max, &step, &def, &flags); -+ -+ if (type == V4L2_CTRL_TYPE_MENU) -+ qmenu = v4l2_ctrl_get_menu(id); -+ else if (type == V4L2_CTRL_TYPE_INTEGER_MENU) -+ qmenu_int = v4l2_ctrl_get_int_menu(id, &qmenu_int_len); -+ -+ if ((!qmenu && !qmenu_int) || (qmenu_int && max > qmenu_int_len)) { -+ handler_set_err(hdl, -EINVAL); -+ return NULL; -+ } -+ return v4l2_ctrl_new(hdl, ops, NULL, id, name, type, -+ 0, max, mask, def, NULL, 0, -+ flags, qmenu, qmenu_int, ptr_null, NULL); -+} -+EXPORT_SYMBOL(v4l2_ctrl_new_std_menu); -+ -+/* Helper function for standard menu controls with driver defined menu */ -+struct v4l2_ctrl *v4l2_ctrl_new_std_menu_items(struct v4l2_ctrl_handler *hdl, -+ const struct v4l2_ctrl_ops *ops, u32 id, u8 _max, -+ u64 mask, u8 _def, const char * const *qmenu) -+{ -+ enum v4l2_ctrl_type type; -+ const char *name; -+ u32 flags; -+ u64 step; -+ s64 min; -+ s64 max = _max; -+ s64 def = _def; -+ -+ /* v4l2_ctrl_new_std_menu_items() should only be called for -+ * standard controls without a standard menu. -+ */ -+ if (v4l2_ctrl_get_menu(id)) { -+ handler_set_err(hdl, -EINVAL); -+ return NULL; -+ } -+ -+ v4l2_ctrl_fill(id, &name, &type, &min, &max, &step, &def, &flags); -+ if (type != V4L2_CTRL_TYPE_MENU || qmenu == NULL) { -+ handler_set_err(hdl, -EINVAL); -+ return NULL; -+ } -+ return v4l2_ctrl_new(hdl, ops, NULL, id, name, type, -+ 0, max, mask, def, NULL, 0, -+ flags, qmenu, NULL, ptr_null, NULL); -+ -+} -+EXPORT_SYMBOL(v4l2_ctrl_new_std_menu_items); -+ -+/* Helper function for standard compound controls */ -+struct v4l2_ctrl *v4l2_ctrl_new_std_compound(struct v4l2_ctrl_handler *hdl, -+ const struct v4l2_ctrl_ops *ops, u32 id, -+ const union v4l2_ctrl_ptr p_def) -+{ -+ const char *name; -+ enum v4l2_ctrl_type type; -+ u32 flags; -+ s64 min, max, step, def; -+ -+ v4l2_ctrl_fill(id, &name, &type, &min, &max, &step, &def, &flags); -+ if (type < V4L2_CTRL_COMPOUND_TYPES) { -+ handler_set_err(hdl, -EINVAL); -+ return NULL; -+ } -+ return v4l2_ctrl_new(hdl, ops, NULL, id, name, type, -+ min, max, step, def, NULL, 0, -+ flags, NULL, NULL, p_def, NULL); -+} -+EXPORT_SYMBOL(v4l2_ctrl_new_std_compound); -+ -+/* Helper function for standard integer menu controls */ -+struct v4l2_ctrl *v4l2_ctrl_new_int_menu(struct v4l2_ctrl_handler *hdl, -+ const struct v4l2_ctrl_ops *ops, -+ u32 id, u8 _max, u8 _def, const s64 *qmenu_int) -+{ -+ const char *name; -+ enum v4l2_ctrl_type type; -+ s64 min; -+ u64 step; -+ s64 max = _max; -+ s64 def = _def; -+ u32 flags; -+ -+ v4l2_ctrl_fill(id, &name, &type, &min, &max, &step, &def, &flags); -+ if (type != V4L2_CTRL_TYPE_INTEGER_MENU) { -+ handler_set_err(hdl, -EINVAL); -+ return NULL; -+ } -+ return v4l2_ctrl_new(hdl, ops, NULL, id, name, type, -+ 0, max, 0, def, NULL, 0, -+ flags, NULL, qmenu_int, ptr_null, NULL); -+} -+EXPORT_SYMBOL(v4l2_ctrl_new_int_menu); -+ -+/* Add the controls from another handler to our own. */ -+int v4l2_ctrl_add_handler(struct v4l2_ctrl_handler *hdl, -+ struct v4l2_ctrl_handler *add, -+ bool (*filter)(const struct v4l2_ctrl *ctrl), -+ bool from_other_dev) -+{ -+ struct v4l2_ctrl_ref *ref; -+ int ret = 0; -+ -+ /* Do nothing if either handler is NULL or if they are the same */ -+ if (!hdl || !add || hdl == add) -+ return 0; -+ if (hdl->error) -+ return hdl->error; -+ mutex_lock(add->lock); -+ list_for_each_entry(ref, &add->ctrl_refs, node) { -+ struct v4l2_ctrl *ctrl = ref->ctrl; -+ -+ /* Skip handler-private controls. */ -+ if (ctrl->is_private) -+ continue; -+ /* And control classes */ -+ if (ctrl->type == V4L2_CTRL_TYPE_CTRL_CLASS) -+ continue; -+ /* Filter any unwanted controls */ -+ if (filter && !filter(ctrl)) -+ continue; -+ ret = handler_new_ref(hdl, ctrl, NULL, from_other_dev, false); -+ if (ret) -+ break; -+ } -+ mutex_unlock(add->lock); -+ return ret; -+} -+EXPORT_SYMBOL(v4l2_ctrl_add_handler); -+ -+bool v4l2_ctrl_radio_filter(const struct v4l2_ctrl *ctrl) -+{ -+ if (V4L2_CTRL_ID2WHICH(ctrl->id) == V4L2_CTRL_CLASS_FM_TX) -+ return true; -+ if (V4L2_CTRL_ID2WHICH(ctrl->id) == V4L2_CTRL_CLASS_FM_RX) -+ return true; -+ switch (ctrl->id) { -+ case V4L2_CID_AUDIO_MUTE: -+ case V4L2_CID_AUDIO_VOLUME: -+ case V4L2_CID_AUDIO_BALANCE: -+ case V4L2_CID_AUDIO_BASS: -+ case V4L2_CID_AUDIO_TREBLE: -+ case V4L2_CID_AUDIO_LOUDNESS: -+ return true; -+ default: -+ break; -+ } -+ return false; -+} -+EXPORT_SYMBOL(v4l2_ctrl_radio_filter); -+ -+/* Cluster controls */ -+void v4l2_ctrl_cluster(unsigned ncontrols, struct v4l2_ctrl **controls) -+{ -+ bool has_volatiles = false; -+ int i; -+ -+ /* The first control is the master control and it must not be NULL */ -+ if (WARN_ON(ncontrols == 0 || controls[0] == NULL)) -+ return; -+ -+ for (i = 0; i < ncontrols; i++) { -+ if (controls[i]) { -+ controls[i]->cluster = controls; -+ controls[i]->ncontrols = ncontrols; -+ if (controls[i]->flags & V4L2_CTRL_FLAG_VOLATILE) -+ has_volatiles = true; -+ } -+ } -+ controls[0]->has_volatiles = has_volatiles; -+} -+EXPORT_SYMBOL(v4l2_ctrl_cluster); -+ -+void v4l2_ctrl_auto_cluster(unsigned ncontrols, struct v4l2_ctrl **controls, -+ u8 manual_val, bool set_volatile) -+{ -+ struct v4l2_ctrl *master = controls[0]; -+ u32 flag = 0; -+ int i; -+ -+ v4l2_ctrl_cluster(ncontrols, controls); -+ WARN_ON(ncontrols <= 1); -+ WARN_ON(manual_val < master->minimum || manual_val > master->maximum); -+ WARN_ON(set_volatile && !has_op(master, g_volatile_ctrl)); -+ master->is_auto = true; -+ master->has_volatiles = set_volatile; -+ master->manual_mode_value = manual_val; -+ master->flags |= V4L2_CTRL_FLAG_UPDATE; -+ -+ if (!is_cur_manual(master)) -+ flag = V4L2_CTRL_FLAG_INACTIVE | -+ (set_volatile ? V4L2_CTRL_FLAG_VOLATILE : 0); -+ -+ for (i = 1; i < ncontrols; i++) -+ if (controls[i]) -+ controls[i]->flags |= flag; -+} -+EXPORT_SYMBOL(v4l2_ctrl_auto_cluster); -+ -+/* Activate/deactivate a control. */ -+void v4l2_ctrl_activate(struct v4l2_ctrl *ctrl, bool active) -+{ -+ /* invert since the actual flag is called 'inactive' */ -+ bool inactive = !active; -+ bool old; -+ -+ if (ctrl == NULL) -+ return; -+ -+ if (inactive) -+ /* set V4L2_CTRL_FLAG_INACTIVE */ -+ old = test_and_set_bit(4, &ctrl->flags); -+ else -+ /* clear V4L2_CTRL_FLAG_INACTIVE */ -+ old = test_and_clear_bit(4, &ctrl->flags); -+ if (old != inactive) -+ send_event(NULL, ctrl, V4L2_EVENT_CTRL_CH_FLAGS); -+} -+EXPORT_SYMBOL(v4l2_ctrl_activate); -+ -+void __v4l2_ctrl_grab(struct v4l2_ctrl *ctrl, bool grabbed) -+{ -+ bool old; -+ -+ if (ctrl == NULL) -+ return; -+ -+ lockdep_assert_held(ctrl->handler->lock); -+ -+ if (grabbed) -+ /* set V4L2_CTRL_FLAG_GRABBED */ -+ old = test_and_set_bit(1, &ctrl->flags); -+ else -+ /* clear V4L2_CTRL_FLAG_GRABBED */ -+ old = test_and_clear_bit(1, &ctrl->flags); -+ if (old != grabbed) -+ send_event(NULL, ctrl, V4L2_EVENT_CTRL_CH_FLAGS); -+} -+EXPORT_SYMBOL(__v4l2_ctrl_grab); -+ -+/* Log the control name and value */ -+static void log_ctrl(const struct v4l2_ctrl *ctrl, -+ const char *prefix, const char *colon) -+{ -+ if (ctrl->flags & (V4L2_CTRL_FLAG_DISABLED | V4L2_CTRL_FLAG_WRITE_ONLY)) -+ return; -+ if (ctrl->type == V4L2_CTRL_TYPE_CTRL_CLASS) -+ return; -+ -+ pr_info("%s%s%s: ", prefix, colon, ctrl->name); -+ -+ ctrl->type_ops->log(ctrl); -+ -+ if (ctrl->flags & (V4L2_CTRL_FLAG_INACTIVE | -+ V4L2_CTRL_FLAG_GRABBED | -+ V4L2_CTRL_FLAG_VOLATILE)) { -+ if (ctrl->flags & V4L2_CTRL_FLAG_INACTIVE) -+ pr_cont(" inactive"); -+ if (ctrl->flags & V4L2_CTRL_FLAG_GRABBED) -+ pr_cont(" grabbed"); -+ if (ctrl->flags & V4L2_CTRL_FLAG_VOLATILE) -+ pr_cont(" volatile"); -+ } -+ pr_cont("\n"); -+} -+ -+/* Log all controls owned by the handler */ -+void v4l2_ctrl_handler_log_status(struct v4l2_ctrl_handler *hdl, -+ const char *prefix) -+{ -+ struct v4l2_ctrl *ctrl; -+ const char *colon = ""; -+ int len; -+ -+ if (hdl == NULL) -+ return; -+ if (prefix == NULL) -+ prefix = ""; -+ len = strlen(prefix); -+ if (len && prefix[len - 1] != ' ') -+ colon = ": "; -+ mutex_lock(hdl->lock); -+ list_for_each_entry(ctrl, &hdl->ctrls, node) -+ if (!(ctrl->flags & V4L2_CTRL_FLAG_DISABLED)) -+ log_ctrl(ctrl, prefix, colon); -+ mutex_unlock(hdl->lock); -+} -+EXPORT_SYMBOL(v4l2_ctrl_handler_log_status); -+ -+int v4l2_ctrl_subdev_log_status(struct v4l2_subdev *sd) -+{ -+ v4l2_ctrl_handler_log_status(sd->ctrl_handler, sd->name); -+ return 0; -+} -+EXPORT_SYMBOL(v4l2_ctrl_subdev_log_status); -+ -+/* Call s_ctrl for all controls owned by the handler */ -+int __v4l2_ctrl_handler_setup(struct v4l2_ctrl_handler *hdl) -+{ -+ struct v4l2_ctrl *ctrl; -+ int ret = 0; -+ -+ if (hdl == NULL) -+ return 0; -+ -+ lockdep_assert_held(hdl->lock); -+ -+ list_for_each_entry(ctrl, &hdl->ctrls, node) -+ ctrl->done = false; -+ -+ list_for_each_entry(ctrl, &hdl->ctrls, node) { -+ struct v4l2_ctrl *master = ctrl->cluster[0]; -+ int i; -+ -+ /* Skip if this control was already handled by a cluster. */ -+ /* Skip button controls and read-only controls. */ -+ if (ctrl->done || ctrl->type == V4L2_CTRL_TYPE_BUTTON || -+ (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY)) -+ continue; -+ -+ for (i = 0; i < master->ncontrols; i++) { -+ if (master->cluster[i]) { -+ cur_to_new(master->cluster[i]); -+ master->cluster[i]->is_new = 1; -+ master->cluster[i]->done = true; -+ } -+ } -+ ret = call_op(master, s_ctrl); -+ if (ret) -+ break; -+ } -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(__v4l2_ctrl_handler_setup); -+ -+int v4l2_ctrl_handler_setup(struct v4l2_ctrl_handler *hdl) -+{ -+ int ret; -+ -+ if (hdl == NULL) -+ return 0; -+ -+ mutex_lock(hdl->lock); -+ ret = __v4l2_ctrl_handler_setup(hdl); -+ mutex_unlock(hdl->lock); -+ -+ return ret; -+} -+EXPORT_SYMBOL(v4l2_ctrl_handler_setup); -+ -+/* Implement VIDIOC_QUERY_EXT_CTRL */ -+int v4l2_query_ext_ctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_query_ext_ctrl *qc) -+{ -+ const unsigned next_flags = V4L2_CTRL_FLAG_NEXT_CTRL | V4L2_CTRL_FLAG_NEXT_COMPOUND; -+ u32 id = qc->id & V4L2_CTRL_ID_MASK; -+ struct v4l2_ctrl_ref *ref; -+ struct v4l2_ctrl *ctrl; -+ -+ if (hdl == NULL) -+ return -EINVAL; -+ -+ mutex_lock(hdl->lock); -+ -+ /* Try to find it */ -+ ref = find_ref(hdl, id); -+ -+ if ((qc->id & next_flags) && !list_empty(&hdl->ctrl_refs)) { -+ bool is_compound; -+ /* Match any control that is not hidden */ -+ unsigned mask = 1; -+ bool match = false; -+ -+ if ((qc->id & next_flags) == V4L2_CTRL_FLAG_NEXT_COMPOUND) { -+ /* Match any hidden control */ -+ match = true; -+ } else if ((qc->id & next_flags) == next_flags) { -+ /* Match any control, compound or not */ -+ mask = 0; -+ } -+ -+ /* Find the next control with ID > qc->id */ -+ -+ /* Did we reach the end of the control list? */ -+ if (id >= node2id(hdl->ctrl_refs.prev)) { -+ ref = NULL; /* Yes, so there is no next control */ -+ } else if (ref) { -+ /* We found a control with the given ID, so just get -+ the next valid one in the list. */ -+ list_for_each_entry_continue(ref, &hdl->ctrl_refs, node) { -+ is_compound = ref->ctrl->is_array || -+ ref->ctrl->type >= V4L2_CTRL_COMPOUND_TYPES; -+ if (id < ref->ctrl->id && -+ (is_compound & mask) == match) -+ break; -+ } -+ if (&ref->node == &hdl->ctrl_refs) -+ ref = NULL; -+ } else { -+ /* No control with the given ID exists, so start -+ searching for the next largest ID. We know there -+ is one, otherwise the first 'if' above would have -+ been true. */ -+ list_for_each_entry(ref, &hdl->ctrl_refs, node) { -+ is_compound = ref->ctrl->is_array || -+ ref->ctrl->type >= V4L2_CTRL_COMPOUND_TYPES; -+ if (id < ref->ctrl->id && -+ (is_compound & mask) == match) -+ break; -+ } -+ if (&ref->node == &hdl->ctrl_refs) -+ ref = NULL; -+ } -+ } -+ mutex_unlock(hdl->lock); -+ -+ if (!ref) -+ return -EINVAL; -+ -+ ctrl = ref->ctrl; -+ memset(qc, 0, sizeof(*qc)); -+ if (id >= V4L2_CID_PRIVATE_BASE) -+ qc->id = id; -+ else -+ qc->id = ctrl->id; -+ strscpy(qc->name, ctrl->name, sizeof(qc->name)); -+ qc->flags = user_flags(ctrl); -+ qc->type = ctrl->type; -+ qc->elem_size = ctrl->elem_size; -+ qc->elems = ctrl->elems; -+ qc->nr_of_dims = ctrl->nr_of_dims; -+ memcpy(qc->dims, ctrl->dims, qc->nr_of_dims * sizeof(qc->dims[0])); -+ qc->minimum = ctrl->minimum; -+ qc->maximum = ctrl->maximum; -+ qc->default_value = ctrl->default_value; -+ if (ctrl->type == V4L2_CTRL_TYPE_MENU -+ || ctrl->type == V4L2_CTRL_TYPE_INTEGER_MENU) -+ qc->step = 1; -+ else -+ qc->step = ctrl->step; -+ return 0; -+} -+EXPORT_SYMBOL(v4l2_query_ext_ctrl); -+ -+/* Implement VIDIOC_QUERYCTRL */ -+int v4l2_queryctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_queryctrl *qc) -+{ -+ struct v4l2_query_ext_ctrl qec = { qc->id }; -+ int rc; -+ -+ rc = v4l2_query_ext_ctrl(hdl, &qec); -+ if (rc) -+ return rc; -+ -+ qc->id = qec.id; -+ qc->type = qec.type; -+ qc->flags = qec.flags; -+ strscpy(qc->name, qec.name, sizeof(qc->name)); -+ switch (qc->type) { -+ case V4L2_CTRL_TYPE_INTEGER: -+ case V4L2_CTRL_TYPE_BOOLEAN: -+ case V4L2_CTRL_TYPE_MENU: -+ case V4L2_CTRL_TYPE_INTEGER_MENU: -+ case V4L2_CTRL_TYPE_STRING: -+ case V4L2_CTRL_TYPE_BITMASK: -+ qc->minimum = qec.minimum; -+ qc->maximum = qec.maximum; -+ qc->step = qec.step; -+ qc->default_value = qec.default_value; -+ break; -+ default: -+ qc->minimum = 0; -+ qc->maximum = 0; -+ qc->step = 0; -+ qc->default_value = 0; -+ break; -+ } -+ return 0; -+} -+EXPORT_SYMBOL(v4l2_queryctrl); -+ -+/* Implement VIDIOC_QUERYMENU */ -+int v4l2_querymenu(struct v4l2_ctrl_handler *hdl, struct v4l2_querymenu *qm) -+{ -+ struct v4l2_ctrl *ctrl; -+ u32 i = qm->index; -+ -+ ctrl = v4l2_ctrl_find(hdl, qm->id); -+ if (!ctrl) -+ return -EINVAL; -+ -+ qm->reserved = 0; -+ /* Sanity checks */ -+ switch (ctrl->type) { -+ case V4L2_CTRL_TYPE_MENU: -+ if (ctrl->qmenu == NULL) -+ return -EINVAL; -+ break; -+ case V4L2_CTRL_TYPE_INTEGER_MENU: -+ if (ctrl->qmenu_int == NULL) -+ return -EINVAL; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ if (i < ctrl->minimum || i > ctrl->maximum) -+ return -EINVAL; -+ -+ /* Use mask to see if this menu item should be skipped */ -+ if (ctrl->menu_skip_mask & (1ULL << i)) -+ return -EINVAL; -+ /* Empty menu items should also be skipped */ -+ if (ctrl->type == V4L2_CTRL_TYPE_MENU) { -+ if (ctrl->qmenu[i] == NULL || ctrl->qmenu[i][0] == '\0') -+ return -EINVAL; -+ strscpy(qm->name, ctrl->qmenu[i], sizeof(qm->name)); -+ } else { -+ qm->value = ctrl->qmenu_int[i]; -+ } -+ return 0; -+} -+EXPORT_SYMBOL(v4l2_querymenu); -+ -+static int v4l2_ctrl_request_clone(struct v4l2_ctrl_handler *hdl, -+ const struct v4l2_ctrl_handler *from) -+{ -+ struct v4l2_ctrl_ref *ref; -+ int err = 0; -+ -+ if (WARN_ON(!hdl || hdl == from)) -+ return -EINVAL; -+ -+ if (hdl->error) -+ return hdl->error; -+ -+ WARN_ON(hdl->lock != &hdl->_lock); -+ -+ mutex_lock(from->lock); -+ list_for_each_entry(ref, &from->ctrl_refs, node) { -+ struct v4l2_ctrl *ctrl = ref->ctrl; -+ struct v4l2_ctrl_ref *new_ref; -+ -+ /* Skip refs inherited from other devices */ -+ if (ref->from_other_dev) -+ continue; -+ err = handler_new_ref(hdl, ctrl, &new_ref, false, true); -+ if (err) -+ break; -+ } -+ mutex_unlock(from->lock); -+ return err; -+} -+ -+static void v4l2_ctrl_request_queue(struct media_request_object *obj) -+{ -+ struct v4l2_ctrl_handler *hdl = -+ container_of(obj, struct v4l2_ctrl_handler, req_obj); -+ struct v4l2_ctrl_handler *main_hdl = obj->priv; -+ -+ mutex_lock(main_hdl->lock); -+ list_add_tail(&hdl->requests_queued, &main_hdl->requests_queued); -+ hdl->request_is_queued = true; -+ mutex_unlock(main_hdl->lock); -+} -+ -+static void v4l2_ctrl_request_unbind(struct media_request_object *obj) -+{ -+ struct v4l2_ctrl_handler *hdl = -+ container_of(obj, struct v4l2_ctrl_handler, req_obj); -+ struct v4l2_ctrl_handler *main_hdl = obj->priv; -+ -+ mutex_lock(main_hdl->lock); -+ list_del_init(&hdl->requests); -+ if (hdl->request_is_queued) { -+ list_del_init(&hdl->requests_queued); -+ hdl->request_is_queued = false; -+ } -+ mutex_unlock(main_hdl->lock); -+} -+ -+static void v4l2_ctrl_request_release(struct media_request_object *obj) -+{ -+ struct v4l2_ctrl_handler *hdl = -+ container_of(obj, struct v4l2_ctrl_handler, req_obj); -+ -+ v4l2_ctrl_handler_free(hdl); -+ kfree(hdl); -+} -+ -+static const struct media_request_object_ops req_ops = { -+ .queue = v4l2_ctrl_request_queue, -+ .unbind = v4l2_ctrl_request_unbind, -+ .release = v4l2_ctrl_request_release, -+}; -+ -+struct v4l2_ctrl_handler *v4l2_ctrl_request_hdl_find(struct media_request *req, -+ struct v4l2_ctrl_handler *parent) -+{ -+ struct media_request_object *obj; -+ -+ if (WARN_ON(req->state != MEDIA_REQUEST_STATE_VALIDATING && -+ req->state != MEDIA_REQUEST_STATE_QUEUED)) -+ return NULL; -+ -+ obj = media_request_object_find(req, &req_ops, parent); -+ if (obj) -+ return container_of(obj, struct v4l2_ctrl_handler, req_obj); -+ return NULL; -+} -+EXPORT_SYMBOL_GPL(v4l2_ctrl_request_hdl_find); -+ -+struct v4l2_ctrl * -+v4l2_ctrl_request_hdl_ctrl_find(struct v4l2_ctrl_handler *hdl, u32 id) -+{ -+ struct v4l2_ctrl_ref *ref = find_ref_lock(hdl, id); -+ -+ return (ref && ref->valid_p_req) ? ref->ctrl : NULL; -+} -+EXPORT_SYMBOL_GPL(v4l2_ctrl_request_hdl_ctrl_find); -+ -+static int v4l2_ctrl_request_bind(struct media_request *req, -+ struct v4l2_ctrl_handler *hdl, -+ struct v4l2_ctrl_handler *from) -+{ -+ int ret; -+ -+ ret = v4l2_ctrl_request_clone(hdl, from); -+ -+ if (!ret) { -+ ret = media_request_object_bind(req, &req_ops, -+ from, false, &hdl->req_obj); -+ if (!ret) { -+ mutex_lock(from->lock); -+ list_add_tail(&hdl->requests, &from->requests); -+ mutex_unlock(from->lock); -+ } -+ } -+ return ret; -+} -+ -+/* Some general notes on the atomic requirements of VIDIOC_G/TRY/S_EXT_CTRLS: -+ -+ It is not a fully atomic operation, just best-effort only. After all, if -+ multiple controls have to be set through multiple i2c writes (for example) -+ then some initial writes may succeed while others fail. Thus leaving the -+ system in an inconsistent state. The question is how much effort you are -+ willing to spend on trying to make something atomic that really isn't. -+ -+ From the point of view of an application the main requirement is that -+ when you call VIDIOC_S_EXT_CTRLS and some values are invalid then an -+ error should be returned without actually affecting any controls. -+ -+ If all the values are correct, then it is acceptable to just give up -+ in case of low-level errors. -+ -+ It is important though that the application can tell when only a partial -+ configuration was done. The way we do that is through the error_idx field -+ of struct v4l2_ext_controls: if that is equal to the count field then no -+ controls were affected. Otherwise all controls before that index were -+ successful in performing their 'get' or 'set' operation, the control at -+ the given index failed, and you don't know what happened with the controls -+ after the failed one. Since if they were part of a control cluster they -+ could have been successfully processed (if a cluster member was encountered -+ at index < error_idx), they could have failed (if a cluster member was at -+ error_idx), or they may not have been processed yet (if the first cluster -+ member appeared after error_idx). -+ -+ It is all fairly theoretical, though. In practice all you can do is to -+ bail out. If error_idx == count, then it is an application bug. If -+ error_idx < count then it is only an application bug if the error code was -+ EBUSY. That usually means that something started streaming just when you -+ tried to set the controls. In all other cases it is a driver/hardware -+ problem and all you can do is to retry or bail out. -+ -+ Note that these rules do not apply to VIDIOC_TRY_EXT_CTRLS: since that -+ never modifies controls the error_idx is just set to whatever control -+ has an invalid value. -+ */ -+ -+/* Prepare for the extended g/s/try functions. -+ Find the controls in the control array and do some basic checks. */ -+static int prepare_ext_ctrls(struct v4l2_ctrl_handler *hdl, -+ struct v4l2_ext_controls *cs, -+ struct v4l2_ctrl_helper *helpers, -+ struct video_device *vdev, -+ bool get) -+{ -+ struct v4l2_ctrl_helper *h; -+ bool have_clusters = false; -+ u32 i; -+ -+ for (i = 0, h = helpers; i < cs->count; i++, h++) { -+ struct v4l2_ext_control *c = &cs->controls[i]; -+ struct v4l2_ctrl_ref *ref; -+ struct v4l2_ctrl *ctrl; -+ u32 id = c->id & V4L2_CTRL_ID_MASK; -+ -+ cs->error_idx = i; -+ -+ if (cs->which && -+ cs->which != V4L2_CTRL_WHICH_DEF_VAL && -+ cs->which != V4L2_CTRL_WHICH_REQUEST_VAL && -+ V4L2_CTRL_ID2WHICH(id) != cs->which) { -+ dprintk(vdev, -+ "invalid which 0x%x or control id 0x%x\n", -+ cs->which, id); -+ return -EINVAL; -+ } -+ -+ /* Old-style private controls are not allowed for -+ extended controls */ -+ if (id >= V4L2_CID_PRIVATE_BASE) { -+ dprintk(vdev, -+ "old-style private controls not allowed\n"); -+ return -EINVAL; -+ } -+ ref = find_ref_lock(hdl, id); -+ if (ref == NULL) { -+ dprintk(vdev, "cannot find control id 0x%x\n", id); -+ return -EINVAL; -+ } -+ h->ref = ref; -+ ctrl = ref->ctrl; -+ if (ctrl->flags & V4L2_CTRL_FLAG_DISABLED) { -+ dprintk(vdev, "control id 0x%x is disabled\n", id); -+ return -EINVAL; -+ } -+ -+ if (ctrl->cluster[0]->ncontrols > 1) -+ have_clusters = true; -+ if (ctrl->cluster[0] != ctrl) -+ ref = find_ref_lock(hdl, ctrl->cluster[0]->id); -+ if (ctrl->is_ptr && !ctrl->is_string) { -+ unsigned tot_size = ctrl->elems * ctrl->elem_size; -+ -+ if (c->size < tot_size) { -+ /* -+ * In the get case the application first -+ * queries to obtain the size of the control. -+ */ -+ if (get) { -+ c->size = tot_size; -+ return -ENOSPC; -+ } -+ dprintk(vdev, -+ "pointer control id 0x%x size too small, %d bytes but %d bytes needed\n", -+ id, c->size, tot_size); -+ return -EFAULT; -+ } -+ c->size = tot_size; -+ } -+ /* Store the ref to the master control of the cluster */ -+ h->mref = ref; -+ /* Initially set next to 0, meaning that there is no other -+ control in this helper array belonging to the same -+ cluster */ -+ h->next = 0; -+ } -+ -+ /* We are done if there were no controls that belong to a multi- -+ control cluster. */ -+ if (!have_clusters) -+ return 0; -+ -+ /* The code below figures out in O(n) time which controls in the list -+ belong to the same cluster. */ -+ -+ /* This has to be done with the handler lock taken. */ -+ mutex_lock(hdl->lock); -+ -+ /* First zero the helper field in the master control references */ -+ for (i = 0; i < cs->count; i++) -+ helpers[i].mref->helper = NULL; -+ for (i = 0, h = helpers; i < cs->count; i++, h++) { -+ struct v4l2_ctrl_ref *mref = h->mref; -+ -+ /* If the mref->helper is set, then it points to an earlier -+ helper that belongs to the same cluster. */ -+ if (mref->helper) { -+ /* Set the next field of mref->helper to the current -+ index: this means that that earlier helper now -+ points to the next helper in the same cluster. */ -+ mref->helper->next = i; -+ /* mref should be set only for the first helper in the -+ cluster, clear the others. */ -+ h->mref = NULL; -+ } -+ /* Point the mref helper to the current helper struct. */ -+ mref->helper = h; -+ } -+ mutex_unlock(hdl->lock); -+ return 0; -+} -+ -+/* Handles the corner case where cs->count == 0. It checks whether the -+ specified control class exists. If that class ID is 0, then it checks -+ whether there are any controls at all. */ -+static int class_check(struct v4l2_ctrl_handler *hdl, u32 which) -+{ -+ if (which == 0 || which == V4L2_CTRL_WHICH_DEF_VAL || -+ which == V4L2_CTRL_WHICH_REQUEST_VAL) -+ return 0; -+ return find_ref_lock(hdl, which | 1) ? 0 : -EINVAL; -+} -+ -+/* -+ * Get extended controls. Allocates the helpers array if needed. -+ * -+ * Note that v4l2_g_ext_ctrls_common() with 'which' set to -+ * V4L2_CTRL_WHICH_REQUEST_VAL is only called if the request was -+ * completed, and in that case valid_p_req is true for all controls. -+ */ -+static int v4l2_g_ext_ctrls_common(struct v4l2_ctrl_handler *hdl, -+ struct v4l2_ext_controls *cs, -+ struct video_device *vdev) -+{ -+ struct v4l2_ctrl_helper helper[4]; -+ struct v4l2_ctrl_helper *helpers = helper; -+ int ret; -+ int i, j; -+ bool is_default, is_request; -+ -+ is_default = (cs->which == V4L2_CTRL_WHICH_DEF_VAL); -+ is_request = (cs->which == V4L2_CTRL_WHICH_REQUEST_VAL); -+ -+ cs->error_idx = cs->count; -+ cs->which = V4L2_CTRL_ID2WHICH(cs->which); -+ -+ if (hdl == NULL) -+ return -EINVAL; -+ -+ if (cs->count == 0) -+ return class_check(hdl, cs->which); -+ -+ if (cs->count > ARRAY_SIZE(helper)) { -+ helpers = kvmalloc_array(cs->count, sizeof(helper[0]), -+ GFP_KERNEL); -+ if (helpers == NULL) -+ return -ENOMEM; -+ } -+ -+ ret = prepare_ext_ctrls(hdl, cs, helpers, vdev, true); -+ cs->error_idx = cs->count; -+ -+ for (i = 0; !ret && i < cs->count; i++) -+ if (helpers[i].ref->ctrl->flags & V4L2_CTRL_FLAG_WRITE_ONLY) -+ ret = -EACCES; -+ -+ for (i = 0; !ret && i < cs->count; i++) { -+ struct v4l2_ctrl *master; -+ bool is_volatile = false; -+ u32 idx = i; -+ -+ if (helpers[i].mref == NULL) -+ continue; -+ -+ master = helpers[i].mref->ctrl; -+ cs->error_idx = i; -+ -+ v4l2_ctrl_lock(master); -+ -+ /* -+ * g_volatile_ctrl will update the new control values. -+ * This makes no sense for V4L2_CTRL_WHICH_DEF_VAL and -+ * V4L2_CTRL_WHICH_REQUEST_VAL. In the case of requests -+ * it is v4l2_ctrl_request_complete() that copies the -+ * volatile controls at the time of request completion -+ * to the request, so you don't want to do that again. -+ */ -+ if (!is_default && !is_request && -+ ((master->flags & V4L2_CTRL_FLAG_VOLATILE) || -+ (master->has_volatiles && !is_cur_manual(master)))) { -+ for (j = 0; j < master->ncontrols; j++) -+ cur_to_new(master->cluster[j]); -+ ret = call_op(master, g_volatile_ctrl); -+ is_volatile = true; -+ } -+ -+ if (ret) { -+ v4l2_ctrl_unlock(master); -+ break; -+ } -+ -+ /* -+ * Copy the default value (if is_default is true), the -+ * request value (if is_request is true and p_req is valid), -+ * the new volatile value (if is_volatile is true) or the -+ * current value. -+ */ -+ do { -+ struct v4l2_ctrl_ref *ref = helpers[idx].ref; -+ -+ if (is_default) -+ ret = def_to_user(cs->controls + idx, ref->ctrl); -+ else if (is_request && ref->valid_p_req) -+ ret = req_to_user(cs->controls + idx, ref); -+ else if (is_volatile) -+ ret = new_to_user(cs->controls + idx, ref->ctrl); -+ else -+ ret = cur_to_user(cs->controls + idx, ref->ctrl); -+ idx = helpers[idx].next; -+ } while (!ret && idx); -+ -+ v4l2_ctrl_unlock(master); -+ } -+ -+ if (cs->count > ARRAY_SIZE(helper)) -+ kvfree(helpers); -+ return ret; -+} -+ -+static struct media_request_object * -+v4l2_ctrls_find_req_obj(struct v4l2_ctrl_handler *hdl, -+ struct media_request *req, bool set) -+{ -+ struct media_request_object *obj; -+ struct v4l2_ctrl_handler *new_hdl; -+ int ret; -+ -+ if (IS_ERR(req)) -+ return ERR_CAST(req); -+ -+ if (set && WARN_ON(req->state != MEDIA_REQUEST_STATE_UPDATING)) -+ return ERR_PTR(-EBUSY); -+ -+ obj = media_request_object_find(req, &req_ops, hdl); -+ if (obj) -+ return obj; -+ if (!set) -+ return ERR_PTR(-ENOENT); -+ -+ new_hdl = kzalloc(sizeof(*new_hdl), GFP_KERNEL); -+ if (!new_hdl) -+ return ERR_PTR(-ENOMEM); -+ -+ obj = &new_hdl->req_obj; -+ ret = v4l2_ctrl_handler_init(new_hdl, (hdl->nr_of_buckets - 1) * 8); -+ if (!ret) -+ ret = v4l2_ctrl_request_bind(req, new_hdl, hdl); -+ if (ret) { -+ kfree(new_hdl); -+ -+ return ERR_PTR(ret); -+ } -+ -+ media_request_object_get(obj); -+ return obj; -+} -+ -+int v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct video_device *vdev, -+ struct media_device *mdev, struct v4l2_ext_controls *cs) -+{ -+ struct media_request_object *obj = NULL; -+ struct media_request *req = NULL; -+ int ret; -+ -+ if (cs->which == V4L2_CTRL_WHICH_REQUEST_VAL) { -+ if (!mdev || cs->request_fd < 0) -+ return -EINVAL; -+ -+ req = media_request_get_by_fd(mdev, cs->request_fd); -+ if (IS_ERR(req)) -+ return PTR_ERR(req); -+ -+ if (req->state != MEDIA_REQUEST_STATE_COMPLETE) { -+ media_request_put(req); -+ return -EACCES; -+ } -+ -+ ret = media_request_lock_for_access(req); -+ if (ret) { -+ media_request_put(req); -+ return ret; -+ } -+ -+ obj = v4l2_ctrls_find_req_obj(hdl, req, false); -+ if (IS_ERR(obj)) { -+ media_request_unlock_for_access(req); -+ media_request_put(req); -+ return PTR_ERR(obj); -+ } -+ -+ hdl = container_of(obj, struct v4l2_ctrl_handler, -+ req_obj); -+ } -+ -+ ret = v4l2_g_ext_ctrls_common(hdl, cs, vdev); -+ -+ if (obj) { -+ media_request_unlock_for_access(req); -+ media_request_object_put(obj); -+ media_request_put(req); -+ } -+ return ret; -+} -+EXPORT_SYMBOL(v4l2_g_ext_ctrls); -+ -+/* Helper function to get a single control */ -+static int get_ctrl(struct v4l2_ctrl *ctrl, struct v4l2_ext_control *c) -+{ -+ struct v4l2_ctrl *master = ctrl->cluster[0]; -+ int ret = 0; -+ int i; -+ -+ /* Compound controls are not supported. The new_to_user() and -+ * cur_to_user() calls below would need to be modified not to access -+ * userspace memory when called from get_ctrl(). -+ */ -+ if (!ctrl->is_int && ctrl->type != V4L2_CTRL_TYPE_INTEGER64) -+ return -EINVAL; -+ -+ if (ctrl->flags & V4L2_CTRL_FLAG_WRITE_ONLY) -+ return -EACCES; -+ -+ v4l2_ctrl_lock(master); -+ /* g_volatile_ctrl will update the current control values */ -+ if (ctrl->flags & V4L2_CTRL_FLAG_VOLATILE) { -+ for (i = 0; i < master->ncontrols; i++) -+ cur_to_new(master->cluster[i]); -+ ret = call_op(master, g_volatile_ctrl); -+ new_to_user(c, ctrl); -+ } else { -+ cur_to_user(c, ctrl); -+ } -+ v4l2_ctrl_unlock(master); -+ return ret; -+} -+ -+int v4l2_g_ctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_control *control) -+{ -+ struct v4l2_ctrl *ctrl = v4l2_ctrl_find(hdl, control->id); -+ struct v4l2_ext_control c; -+ int ret; -+ -+ if (ctrl == NULL || !ctrl->is_int) -+ return -EINVAL; -+ ret = get_ctrl(ctrl, &c); -+ control->value = c.value; -+ return ret; -+} -+EXPORT_SYMBOL(v4l2_g_ctrl); -+ -+s32 v4l2_ctrl_g_ctrl(struct v4l2_ctrl *ctrl) -+{ -+ struct v4l2_ext_control c; -+ -+ /* It's a driver bug if this happens. */ -+ if (WARN_ON(!ctrl->is_int)) -+ return 0; -+ c.value = 0; -+ get_ctrl(ctrl, &c); -+ return c.value; -+} -+EXPORT_SYMBOL(v4l2_ctrl_g_ctrl); -+ -+s64 v4l2_ctrl_g_ctrl_int64(struct v4l2_ctrl *ctrl) -+{ -+ struct v4l2_ext_control c; -+ -+ /* It's a driver bug if this happens. */ -+ if (WARN_ON(ctrl->is_ptr || ctrl->type != V4L2_CTRL_TYPE_INTEGER64)) -+ return 0; -+ c.value64 = 0; -+ get_ctrl(ctrl, &c); -+ return c.value64; -+} -+EXPORT_SYMBOL(v4l2_ctrl_g_ctrl_int64); -+ -+ -+/* Core function that calls try/s_ctrl and ensures that the new value is -+ copied to the current value on a set. -+ Must be called with ctrl->handler->lock held. */ -+static int try_or_set_cluster(struct v4l2_fh *fh, struct v4l2_ctrl *master, -+ bool set, u32 ch_flags) -+{ -+ bool update_flag; -+ int ret; -+ int i; -+ -+ /* Go through the cluster and either validate the new value or -+ (if no new value was set), copy the current value to the new -+ value, ensuring a consistent view for the control ops when -+ called. */ -+ for (i = 0; i < master->ncontrols; i++) { -+ struct v4l2_ctrl *ctrl = master->cluster[i]; -+ -+ if (ctrl == NULL) -+ continue; -+ -+ if (!ctrl->is_new) { -+ cur_to_new(ctrl); -+ continue; -+ } -+ /* Check again: it may have changed since the -+ previous check in try_or_set_ext_ctrls(). */ -+ if (set && (ctrl->flags & V4L2_CTRL_FLAG_GRABBED)) -+ return -EBUSY; -+ } -+ -+ ret = call_op(master, try_ctrl); -+ -+ /* Don't set if there is no change */ -+ if (ret || !set || !cluster_changed(master)) -+ return ret; -+ ret = call_op(master, s_ctrl); -+ if (ret) -+ return ret; -+ -+ /* If OK, then make the new values permanent. */ -+ update_flag = is_cur_manual(master) != is_new_manual(master); -+ -+ for (i = 0; i < master->ncontrols; i++) { -+ /* -+ * If we switch from auto to manual mode, and this cluster -+ * contains volatile controls, then all non-master controls -+ * have to be marked as changed. The 'new' value contains -+ * the volatile value (obtained by update_from_auto_cluster), -+ * which now has to become the current value. -+ */ -+ if (i && update_flag && is_new_manual(master) && -+ master->has_volatiles && master->cluster[i]) -+ master->cluster[i]->has_changed = true; -+ -+ new_to_cur(fh, master->cluster[i], ch_flags | -+ ((update_flag && i > 0) ? V4L2_EVENT_CTRL_CH_FLAGS : 0)); -+ } -+ return 0; -+} -+ -+/* Validate controls. */ -+static int validate_ctrls(struct v4l2_ext_controls *cs, -+ struct v4l2_ctrl_helper *helpers, -+ struct video_device *vdev, -+ bool set) -+{ -+ unsigned i; -+ int ret = 0; -+ -+ cs->error_idx = cs->count; -+ for (i = 0; i < cs->count; i++) { -+ struct v4l2_ctrl *ctrl = helpers[i].ref->ctrl; -+ union v4l2_ctrl_ptr p_new; -+ -+ cs->error_idx = i; -+ -+ if (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY) { -+ dprintk(vdev, -+ "control id 0x%x is read-only\n", -+ ctrl->id); -+ return -EACCES; -+ } -+ /* This test is also done in try_set_control_cluster() which -+ is called in atomic context, so that has the final say, -+ but it makes sense to do an up-front check as well. Once -+ an error occurs in try_set_control_cluster() some other -+ controls may have been set already and we want to do a -+ best-effort to avoid that. */ -+ if (set && (ctrl->flags & V4L2_CTRL_FLAG_GRABBED)) { -+ dprintk(vdev, -+ "control id 0x%x is grabbed, cannot set\n", -+ ctrl->id); -+ return -EBUSY; -+ } -+ /* -+ * Skip validation for now if the payload needs to be copied -+ * from userspace into kernelspace. We'll validate those later. -+ */ -+ if (ctrl->is_ptr) -+ continue; -+ if (ctrl->type == V4L2_CTRL_TYPE_INTEGER64) -+ p_new.p_s64 = &cs->controls[i].value64; -+ else -+ p_new.p_s32 = &cs->controls[i].value; -+ ret = validate_new(ctrl, p_new); -+ if (ret) -+ return ret; -+ } -+ return 0; -+} -+ -+/* Obtain the current volatile values of an autocluster and mark them -+ as new. */ -+static void update_from_auto_cluster(struct v4l2_ctrl *master) -+{ -+ int i; -+ -+ for (i = 1; i < master->ncontrols; i++) -+ cur_to_new(master->cluster[i]); -+ if (!call_op(master, g_volatile_ctrl)) -+ for (i = 1; i < master->ncontrols; i++) -+ if (master->cluster[i]) -+ master->cluster[i]->is_new = 1; -+} -+ -+/* Try or try-and-set controls */ -+static int try_set_ext_ctrls_common(struct v4l2_fh *fh, -+ struct v4l2_ctrl_handler *hdl, -+ struct v4l2_ext_controls *cs, -+ struct video_device *vdev, bool set) -+{ -+ struct v4l2_ctrl_helper helper[4]; -+ struct v4l2_ctrl_helper *helpers = helper; -+ unsigned i, j; -+ int ret; -+ -+ cs->error_idx = cs->count; -+ -+ /* Default value cannot be changed */ -+ if (cs->which == V4L2_CTRL_WHICH_DEF_VAL) { -+ dprintk(vdev, "%s: cannot change default value\n", -+ video_device_node_name(vdev)); -+ return -EINVAL; -+ } -+ -+ cs->which = V4L2_CTRL_ID2WHICH(cs->which); -+ -+ if (hdl == NULL) { -+ dprintk(vdev, "%s: invalid null control handler\n", -+ video_device_node_name(vdev)); -+ return -EINVAL; -+ } -+ -+ if (cs->count == 0) -+ return class_check(hdl, cs->which); -+ -+ if (cs->count > ARRAY_SIZE(helper)) { -+ helpers = kvmalloc_array(cs->count, sizeof(helper[0]), -+ GFP_KERNEL); -+ if (!helpers) -+ return -ENOMEM; -+ } -+ ret = prepare_ext_ctrls(hdl, cs, helpers, vdev, false); -+ if (!ret) -+ ret = validate_ctrls(cs, helpers, vdev, set); -+ if (ret && set) -+ cs->error_idx = cs->count; -+ for (i = 0; !ret && i < cs->count; i++) { -+ struct v4l2_ctrl *master; -+ u32 idx = i; -+ -+ if (helpers[i].mref == NULL) -+ continue; -+ -+ cs->error_idx = i; -+ master = helpers[i].mref->ctrl; -+ v4l2_ctrl_lock(master); -+ -+ /* Reset the 'is_new' flags of the cluster */ -+ for (j = 0; j < master->ncontrols; j++) -+ if (master->cluster[j]) -+ master->cluster[j]->is_new = 0; -+ -+ /* For volatile autoclusters that are currently in auto mode -+ we need to discover if it will be set to manual mode. -+ If so, then we have to copy the current volatile values -+ first since those will become the new manual values (which -+ may be overwritten by explicit new values from this set -+ of controls). */ -+ if (master->is_auto && master->has_volatiles && -+ !is_cur_manual(master)) { -+ /* Pick an initial non-manual value */ -+ s32 new_auto_val = master->manual_mode_value + 1; -+ u32 tmp_idx = idx; -+ -+ do { -+ /* Check if the auto control is part of the -+ list, and remember the new value. */ -+ if (helpers[tmp_idx].ref->ctrl == master) -+ new_auto_val = cs->controls[tmp_idx].value; -+ tmp_idx = helpers[tmp_idx].next; -+ } while (tmp_idx); -+ /* If the new value == the manual value, then copy -+ the current volatile values. */ -+ if (new_auto_val == master->manual_mode_value) -+ update_from_auto_cluster(master); -+ } -+ -+ /* Copy the new caller-supplied control values. -+ user_to_new() sets 'is_new' to 1. */ -+ do { -+ struct v4l2_ctrl *ctrl = helpers[idx].ref->ctrl; -+ -+ ret = user_to_new(cs->controls + idx, ctrl); -+ if (!ret && ctrl->is_ptr) { -+ ret = validate_new(ctrl, ctrl->p_new); -+ if (ret) -+ dprintk(vdev, -+ "failed to validate control %s (%d)\n", -+ v4l2_ctrl_get_name(ctrl->id), ret); -+ } -+ idx = helpers[idx].next; -+ } while (!ret && idx); -+ -+ if (!ret) -+ ret = try_or_set_cluster(fh, master, -+ !hdl->req_obj.req && set, 0); -+ if (!ret && hdl->req_obj.req && set) { -+ for (j = 0; j < master->ncontrols; j++) { -+ struct v4l2_ctrl_ref *ref = -+ find_ref(hdl, master->cluster[j]->id); -+ -+ new_to_req(ref); -+ } -+ } -+ -+ /* Copy the new values back to userspace. */ -+ if (!ret) { -+ idx = i; -+ do { -+ ret = new_to_user(cs->controls + idx, -+ helpers[idx].ref->ctrl); -+ idx = helpers[idx].next; -+ } while (!ret && idx); -+ } -+ v4l2_ctrl_unlock(master); -+ } -+ -+ if (cs->count > ARRAY_SIZE(helper)) -+ kvfree(helpers); -+ return ret; -+} -+ -+static int try_set_ext_ctrls(struct v4l2_fh *fh, -+ struct v4l2_ctrl_handler *hdl, -+ struct video_device *vdev, -+ struct media_device *mdev, -+ struct v4l2_ext_controls *cs, bool set) -+{ -+ struct media_request_object *obj = NULL; -+ struct media_request *req = NULL; -+ int ret; -+ -+ if (cs->which == V4L2_CTRL_WHICH_REQUEST_VAL) { -+ if (!mdev) { -+ dprintk(vdev, "%s: missing media device\n", -+ video_device_node_name(vdev)); -+ return -EINVAL; -+ } -+ -+ if (cs->request_fd < 0) { -+ dprintk(vdev, "%s: invalid request fd %d\n", -+ video_device_node_name(vdev), cs->request_fd); -+ return -EINVAL; -+ } -+ -+ req = media_request_get_by_fd(mdev, cs->request_fd); -+ if (IS_ERR(req)) { -+ dprintk(vdev, "%s: cannot find request fd %d\n", -+ video_device_node_name(vdev), cs->request_fd); -+ return PTR_ERR(req); -+ } -+ -+ ret = media_request_lock_for_update(req); -+ if (ret) { -+ dprintk(vdev, "%s: cannot lock request fd %d\n", -+ video_device_node_name(vdev), cs->request_fd); -+ media_request_put(req); -+ return ret; -+ } -+ -+ obj = v4l2_ctrls_find_req_obj(hdl, req, set); -+ if (IS_ERR(obj)) { -+ dprintk(vdev, -+ "%s: cannot find request object for request fd %d\n", -+ video_device_node_name(vdev), -+ cs->request_fd); -+ media_request_unlock_for_update(req); -+ media_request_put(req); -+ return PTR_ERR(obj); -+ } -+ hdl = container_of(obj, struct v4l2_ctrl_handler, -+ req_obj); -+ } -+ -+ ret = try_set_ext_ctrls_common(fh, hdl, cs, vdev, set); -+ if (ret) -+ dprintk(vdev, -+ "%s: try_set_ext_ctrls_common failed (%d)\n", -+ video_device_node_name(vdev), ret); -+ -+ if (obj) { -+ media_request_unlock_for_update(req); -+ media_request_object_put(obj); -+ media_request_put(req); -+ } -+ -+ return ret; -+} -+ -+int v4l2_try_ext_ctrls(struct v4l2_ctrl_handler *hdl, -+ struct video_device *vdev, -+ struct media_device *mdev, -+ struct v4l2_ext_controls *cs) -+{ -+ return try_set_ext_ctrls(NULL, hdl, vdev, mdev, cs, false); -+} -+EXPORT_SYMBOL(v4l2_try_ext_ctrls); -+ -+int v4l2_s_ext_ctrls(struct v4l2_fh *fh, -+ struct v4l2_ctrl_handler *hdl, -+ struct video_device *vdev, -+ struct media_device *mdev, -+ struct v4l2_ext_controls *cs) -+{ -+ return try_set_ext_ctrls(fh, hdl, vdev, mdev, cs, true); -+} -+EXPORT_SYMBOL(v4l2_s_ext_ctrls); -+ -+/* Helper function for VIDIOC_S_CTRL compatibility */ -+static int set_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, u32 ch_flags) -+{ -+ struct v4l2_ctrl *master = ctrl->cluster[0]; -+ int ret; -+ int i; -+ -+ /* Reset the 'is_new' flags of the cluster */ -+ for (i = 0; i < master->ncontrols; i++) -+ if (master->cluster[i]) -+ master->cluster[i]->is_new = 0; -+ -+ ret = validate_new(ctrl, ctrl->p_new); -+ if (ret) -+ return ret; -+ -+ /* For autoclusters with volatiles that are switched from auto to -+ manual mode we have to update the current volatile values since -+ those will become the initial manual values after such a switch. */ -+ if (master->is_auto && master->has_volatiles && ctrl == master && -+ !is_cur_manual(master) && ctrl->val == master->manual_mode_value) -+ update_from_auto_cluster(master); -+ -+ ctrl->is_new = 1; -+ return try_or_set_cluster(fh, master, true, ch_flags); -+} -+ -+/* Helper function for VIDIOC_S_CTRL compatibility */ -+static int set_ctrl_lock(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, -+ struct v4l2_ext_control *c) -+{ -+ int ret; -+ -+ v4l2_ctrl_lock(ctrl); -+ user_to_new(c, ctrl); -+ ret = set_ctrl(fh, ctrl, 0); -+ if (!ret) -+ cur_to_user(c, ctrl); -+ v4l2_ctrl_unlock(ctrl); -+ return ret; -+} -+ -+int v4l2_s_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl, -+ struct v4l2_control *control) -+{ -+ struct v4l2_ctrl *ctrl = v4l2_ctrl_find(hdl, control->id); -+ struct v4l2_ext_control c = { control->id }; -+ int ret; -+ -+ if (ctrl == NULL || !ctrl->is_int) -+ return -EINVAL; -+ -+ if (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY) -+ return -EACCES; -+ -+ c.value = control->value; -+ ret = set_ctrl_lock(fh, ctrl, &c); -+ control->value = c.value; -+ return ret; -+} -+EXPORT_SYMBOL(v4l2_s_ctrl); -+ -+int __v4l2_ctrl_s_ctrl(struct v4l2_ctrl *ctrl, s32 val) -+{ -+ lockdep_assert_held(ctrl->handler->lock); -+ -+ /* It's a driver bug if this happens. */ -+ if (WARN_ON(!ctrl->is_int)) -+ return -EINVAL; -+ ctrl->val = val; -+ return set_ctrl(NULL, ctrl, 0); -+} -+EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl); -+ -+int __v4l2_ctrl_s_ctrl_int64(struct v4l2_ctrl *ctrl, s64 val) -+{ -+ lockdep_assert_held(ctrl->handler->lock); -+ -+ /* It's a driver bug if this happens. */ -+ if (WARN_ON(ctrl->is_ptr || ctrl->type != V4L2_CTRL_TYPE_INTEGER64)) -+ return -EINVAL; -+ *ctrl->p_new.p_s64 = val; -+ return set_ctrl(NULL, ctrl, 0); -+} -+EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl_int64); -+ -+int __v4l2_ctrl_s_ctrl_string(struct v4l2_ctrl *ctrl, const char *s) -+{ -+ lockdep_assert_held(ctrl->handler->lock); -+ -+ /* It's a driver bug if this happens. */ -+ if (WARN_ON(ctrl->type != V4L2_CTRL_TYPE_STRING)) -+ return -EINVAL; -+ strscpy(ctrl->p_new.p_char, s, ctrl->maximum + 1); -+ return set_ctrl(NULL, ctrl, 0); -+} -+EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl_string); -+ -+int __v4l2_ctrl_s_ctrl_compound(struct v4l2_ctrl *ctrl, -+ enum v4l2_ctrl_type type, const void *p) -+{ -+ lockdep_assert_held(ctrl->handler->lock); -+ -+ /* It's a driver bug if this happens. */ -+ if (WARN_ON(ctrl->type != type)) -+ return -EINVAL; -+ memcpy(ctrl->p_new.p, p, ctrl->elems * ctrl->elem_size); -+ return set_ctrl(NULL, ctrl, 0); -+} -+EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl_compound); -+ -+void v4l2_ctrl_request_complete(struct media_request *req, -+ struct v4l2_ctrl_handler *main_hdl) -+{ -+ struct media_request_object *obj; -+ struct v4l2_ctrl_handler *hdl; -+ struct v4l2_ctrl_ref *ref; -+ -+ if (!req || !main_hdl) -+ return; -+ -+ /* -+ * Note that it is valid if nothing was found. It means -+ * that this request doesn't have any controls and so just -+ * wants to leave the controls unchanged. -+ */ -+ obj = media_request_object_find(req, &req_ops, main_hdl); -+ if (!obj) -+ return; -+ hdl = container_of(obj, struct v4l2_ctrl_handler, req_obj); -+ -+ list_for_each_entry(ref, &hdl->ctrl_refs, node) { -+ struct v4l2_ctrl *ctrl = ref->ctrl; -+ struct v4l2_ctrl *master = ctrl->cluster[0]; -+ unsigned int i; -+ -+ if (ctrl->flags & V4L2_CTRL_FLAG_VOLATILE) { -+ v4l2_ctrl_lock(master); -+ /* g_volatile_ctrl will update the current control values */ -+ for (i = 0; i < master->ncontrols; i++) -+ cur_to_new(master->cluster[i]); -+ call_op(master, g_volatile_ctrl); -+ new_to_req(ref); -+ v4l2_ctrl_unlock(master); -+ continue; -+ } -+ if (ref->valid_p_req) -+ continue; -+ -+ /* Copy the current control value into the request */ -+ v4l2_ctrl_lock(ctrl); -+ cur_to_req(ref); -+ v4l2_ctrl_unlock(ctrl); -+ } -+ -+ mutex_lock(main_hdl->lock); -+ WARN_ON(!hdl->request_is_queued); -+ list_del_init(&hdl->requests_queued); -+ hdl->request_is_queued = false; -+ mutex_unlock(main_hdl->lock); -+ media_request_object_complete(obj); -+ media_request_object_put(obj); -+} -+EXPORT_SYMBOL(v4l2_ctrl_request_complete); -+ -+int v4l2_ctrl_request_setup(struct media_request *req, -+ struct v4l2_ctrl_handler *main_hdl) -+{ -+ struct media_request_object *obj; -+ struct v4l2_ctrl_handler *hdl; -+ struct v4l2_ctrl_ref *ref; -+ int ret = 0; -+ -+ if (!req || !main_hdl) -+ return 0; -+ -+ if (WARN_ON(req->state != MEDIA_REQUEST_STATE_QUEUED)) -+ return -EBUSY; -+ -+ /* -+ * Note that it is valid if nothing was found. It means -+ * that this request doesn't have any controls and so just -+ * wants to leave the controls unchanged. -+ */ -+ obj = media_request_object_find(req, &req_ops, main_hdl); -+ if (!obj) -+ return 0; -+ if (obj->completed) { -+ media_request_object_put(obj); -+ return -EBUSY; -+ } -+ hdl = container_of(obj, struct v4l2_ctrl_handler, req_obj); -+ -+ list_for_each_entry(ref, &hdl->ctrl_refs, node) -+ ref->req_done = false; -+ -+ list_for_each_entry(ref, &hdl->ctrl_refs, node) { -+ struct v4l2_ctrl *ctrl = ref->ctrl; -+ struct v4l2_ctrl *master = ctrl->cluster[0]; -+ bool have_new_data = false; -+ int i; -+ -+ /* -+ * Skip if this control was already handled by a cluster. -+ * Skip button controls and read-only controls. -+ */ -+ if (ref->req_done || (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY)) -+ continue; -+ -+ v4l2_ctrl_lock(master); -+ for (i = 0; i < master->ncontrols; i++) { -+ if (master->cluster[i]) { -+ struct v4l2_ctrl_ref *r = -+ find_ref(hdl, master->cluster[i]->id); -+ -+ if (r->valid_p_req) { -+ have_new_data = true; -+ break; -+ } -+ } -+ } -+ if (!have_new_data) { -+ v4l2_ctrl_unlock(master); -+ continue; -+ } -+ -+ for (i = 0; i < master->ncontrols; i++) { -+ if (master->cluster[i]) { -+ struct v4l2_ctrl_ref *r = -+ find_ref(hdl, master->cluster[i]->id); -+ -+ req_to_new(r); -+ master->cluster[i]->is_new = 1; -+ r->req_done = true; -+ } -+ } -+ /* -+ * For volatile autoclusters that are currently in auto mode -+ * we need to discover if it will be set to manual mode. -+ * If so, then we have to copy the current volatile values -+ * first since those will become the new manual values (which -+ * may be overwritten by explicit new values from this set -+ * of controls). -+ */ -+ if (master->is_auto && master->has_volatiles && -+ !is_cur_manual(master)) { -+ s32 new_auto_val = *master->p_new.p_s32; -+ -+ /* -+ * If the new value == the manual value, then copy -+ * the current volatile values. -+ */ -+ if (new_auto_val == master->manual_mode_value) -+ update_from_auto_cluster(master); -+ } -+ -+ ret = try_or_set_cluster(NULL, master, true, 0); -+ v4l2_ctrl_unlock(master); -+ -+ if (ret) -+ break; -+ } -+ -+ media_request_object_put(obj); -+ return ret; -+} -+EXPORT_SYMBOL(v4l2_ctrl_request_setup); -+ -+void v4l2_ctrl_notify(struct v4l2_ctrl *ctrl, v4l2_ctrl_notify_fnc notify, void *priv) -+{ -+ if (ctrl == NULL) -+ return; -+ if (notify == NULL) { -+ ctrl->call_notify = 0; -+ return; -+ } -+ if (WARN_ON(ctrl->handler->notify && ctrl->handler->notify != notify)) -+ return; -+ ctrl->handler->notify = notify; -+ ctrl->handler->notify_priv = priv; -+ ctrl->call_notify = 1; -+} -+EXPORT_SYMBOL(v4l2_ctrl_notify); -+ -+int __v4l2_ctrl_modify_range(struct v4l2_ctrl *ctrl, -+ s64 min, s64 max, u64 step, s64 def) -+{ -+ bool value_changed; -+ bool range_changed = false; -+ int ret; -+ -+ lockdep_assert_held(ctrl->handler->lock); -+ -+ switch (ctrl->type) { -+ case V4L2_CTRL_TYPE_INTEGER: -+ case V4L2_CTRL_TYPE_INTEGER64: -+ case V4L2_CTRL_TYPE_BOOLEAN: -+ case V4L2_CTRL_TYPE_MENU: -+ case V4L2_CTRL_TYPE_INTEGER_MENU: -+ case V4L2_CTRL_TYPE_BITMASK: -+ case V4L2_CTRL_TYPE_U8: -+ case V4L2_CTRL_TYPE_U16: -+ case V4L2_CTRL_TYPE_U32: -+ if (ctrl->is_array) -+ return -EINVAL; -+ ret = check_range(ctrl->type, min, max, step, def); -+ if (ret) -+ return ret; -+ break; -+ default: -+ return -EINVAL; -+ } -+ if ((ctrl->minimum != min) || (ctrl->maximum != max) || -+ (ctrl->step != step) || ctrl->default_value != def) { -+ range_changed = true; -+ ctrl->minimum = min; -+ ctrl->maximum = max; -+ ctrl->step = step; -+ ctrl->default_value = def; -+ } -+ cur_to_new(ctrl); -+ if (validate_new(ctrl, ctrl->p_new)) { -+ if (ctrl->type == V4L2_CTRL_TYPE_INTEGER64) -+ *ctrl->p_new.p_s64 = def; -+ else -+ *ctrl->p_new.p_s32 = def; -+ } -+ -+ if (ctrl->type == V4L2_CTRL_TYPE_INTEGER64) -+ value_changed = *ctrl->p_new.p_s64 != *ctrl->p_cur.p_s64; -+ else -+ value_changed = *ctrl->p_new.p_s32 != *ctrl->p_cur.p_s32; -+ if (value_changed) -+ ret = set_ctrl(NULL, ctrl, V4L2_EVENT_CTRL_CH_RANGE); -+ else if (range_changed) -+ send_event(NULL, ctrl, V4L2_EVENT_CTRL_CH_RANGE); -+ return ret; -+} -+EXPORT_SYMBOL(__v4l2_ctrl_modify_range); -+ -+static int v4l2_ctrl_add_event(struct v4l2_subscribed_event *sev, unsigned elems) -+{ -+ struct v4l2_ctrl *ctrl = v4l2_ctrl_find(sev->fh->ctrl_handler, sev->id); -+ -+ if (ctrl == NULL) -+ return -EINVAL; -+ -+ v4l2_ctrl_lock(ctrl); -+ list_add_tail(&sev->node, &ctrl->ev_subs); -+ if (ctrl->type != V4L2_CTRL_TYPE_CTRL_CLASS && -+ (sev->flags & V4L2_EVENT_SUB_FL_SEND_INITIAL)) { -+ struct v4l2_event ev; -+ u32 changes = V4L2_EVENT_CTRL_CH_FLAGS; -+ -+ if (!(ctrl->flags & V4L2_CTRL_FLAG_WRITE_ONLY)) -+ changes |= V4L2_EVENT_CTRL_CH_VALUE; -+ fill_event(&ev, ctrl, changes); -+ /* Mark the queue as active, allowing this initial -+ event to be accepted. */ -+ sev->elems = elems; -+ v4l2_event_queue_fh(sev->fh, &ev); -+ } -+ v4l2_ctrl_unlock(ctrl); -+ return 0; -+} -+ -+static void v4l2_ctrl_del_event(struct v4l2_subscribed_event *sev) -+{ -+ struct v4l2_ctrl *ctrl = v4l2_ctrl_find(sev->fh->ctrl_handler, sev->id); -+ -+ if (ctrl == NULL) -+ return; -+ -+ v4l2_ctrl_lock(ctrl); -+ list_del(&sev->node); -+ v4l2_ctrl_unlock(ctrl); -+} -+ -+void v4l2_ctrl_replace(struct v4l2_event *old, const struct v4l2_event *new) -+{ -+ u32 old_changes = old->u.ctrl.changes; -+ -+ old->u.ctrl = new->u.ctrl; -+ old->u.ctrl.changes |= old_changes; -+} -+EXPORT_SYMBOL(v4l2_ctrl_replace); -+ -+void v4l2_ctrl_merge(const struct v4l2_event *old, struct v4l2_event *new) -+{ -+ new->u.ctrl.changes |= old->u.ctrl.changes; -+} -+EXPORT_SYMBOL(v4l2_ctrl_merge); -+ -+const struct v4l2_subscribed_event_ops v4l2_ctrl_sub_ev_ops = { -+ .add = v4l2_ctrl_add_event, -+ .del = v4l2_ctrl_del_event, -+ .replace = v4l2_ctrl_replace, -+ .merge = v4l2_ctrl_merge, -+}; -+EXPORT_SYMBOL(v4l2_ctrl_sub_ev_ops); -+ -+int v4l2_ctrl_log_status(struct file *file, void *fh) -+{ -+ struct video_device *vfd = video_devdata(file); -+ struct v4l2_fh *vfh = file->private_data; -+ -+ if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) && vfd->v4l2_dev) -+ v4l2_ctrl_handler_log_status(vfh->ctrl_handler, -+ vfd->v4l2_dev->name); -+ return 0; -+} -+EXPORT_SYMBOL(v4l2_ctrl_log_status); -+ -+int v4l2_ctrl_subscribe_event(struct v4l2_fh *fh, -+ const struct v4l2_event_subscription *sub) -+{ -+ if (sub->type == V4L2_EVENT_CTRL) -+ return v4l2_event_subscribe(fh, sub, 0, &v4l2_ctrl_sub_ev_ops); -+ return -EINVAL; -+} -+EXPORT_SYMBOL(v4l2_ctrl_subscribe_event); -+ -+int v4l2_ctrl_subdev_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh, -+ struct v4l2_event_subscription *sub) -+{ -+ if (!sd->ctrl_handler) -+ return -EINVAL; -+ return v4l2_ctrl_subscribe_event(fh, sub); -+} -+EXPORT_SYMBOL(v4l2_ctrl_subdev_subscribe_event); -+ -+__poll_t v4l2_ctrl_poll(struct file *file, struct poll_table_struct *wait) -+{ -+ struct v4l2_fh *fh = file->private_data; -+ -+ poll_wait(file, &fh->wait, wait); -+ if (v4l2_event_pending(fh)) -+ return EPOLLPRI; -+ return 0; -+} -+EXPORT_SYMBOL(v4l2_ctrl_poll); -+ -+int v4l2_ctrl_new_fwnode_properties(struct v4l2_ctrl_handler *hdl, -+ const struct v4l2_ctrl_ops *ctrl_ops, -+ const struct v4l2_fwnode_device_properties *p) -+{ -+ if (p->orientation != V4L2_FWNODE_PROPERTY_UNSET) { -+ u32 orientation_ctrl; -+ -+ switch (p->orientation) { -+ case V4L2_FWNODE_ORIENTATION_FRONT: -+ orientation_ctrl = V4L2_CAMERA_ORIENTATION_FRONT; -+ break; -+ case V4L2_FWNODE_ORIENTATION_BACK: -+ orientation_ctrl = V4L2_CAMERA_ORIENTATION_BACK; -+ break; -+ case V4L2_FWNODE_ORIENTATION_EXTERNAL: -+ orientation_ctrl = V4L2_CAMERA_ORIENTATION_EXTERNAL; -+ break; -+ default: -+ return -EINVAL; -+ } -+ if (!v4l2_ctrl_new_std_menu(hdl, ctrl_ops, -+ V4L2_CID_CAMERA_ORIENTATION, -+ V4L2_CAMERA_ORIENTATION_EXTERNAL, 0, -+ orientation_ctrl)) -+ return hdl->error; -+ } -+ -+ if (p->rotation != V4L2_FWNODE_PROPERTY_UNSET) { -+ if (!v4l2_ctrl_new_std(hdl, ctrl_ops, -+ V4L2_CID_CAMERA_SENSOR_ROTATION, -+ p->rotation, p->rotation, 1, -+ p->rotation)) -+ return hdl->error; -+ } -+ -+ return hdl->error; -+} -+EXPORT_SYMBOL(v4l2_ctrl_new_fwnode_properties); ---- a/include/uapi/linux/v4l2-controls.h -+++ b/include/uapi/linux/v4l2-controls.h -@@ -926,6 +926,7 @@ enum v4l2_auto_n_preset_white_balance { - V4L2_WHITE_BALANCE_FLASH = 7, - V4L2_WHITE_BALANCE_CLOUDY = 8, - V4L2_WHITE_BALANCE_SHADE = 9, -+ V4L2_WHITE_BALANCE_GREYWORLD = 10, - }; - - #define V4L2_CID_WIDE_DYNAMIC_RANGE (V4L2_CID_CAMERA_CLASS_BASE+21) diff --git a/target/linux/bcm27xx/patches-5.15/950-0173-drm-v3d-Delete-pm_runtime-support.patch b/target/linux/bcm27xx/patches-5.15/950-0173-drm-v3d-Delete-pm_runtime-support.patch deleted file mode 100644 index 950dd89b9..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0173-drm-v3d-Delete-pm_runtime-support.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 5154d39501380fa5680aea0fab0c3f3f2337fe1f Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 18 Sep 2019 17:22:36 +0100 -Subject: [PATCH] drm/v3d: Delete pm_runtime support - -The pm_runtime was blocking changelist submission, so delete it as a -temporary workaround. - -Signed-off-by: Phil Elwell ---- - drivers/gpu/drm/v3d/v3d_gem.c | 5 ----- - drivers/gpu/drm/v3d/v3d_mmu.c | 11 ----------- - 2 files changed, 16 deletions(-) - ---- a/drivers/gpu/drm/v3d/v3d_gem.c -+++ b/drivers/gpu/drm/v3d/v3d_gem.c -@@ -485,10 +485,6 @@ v3d_job_init(struct v3d_dev *v3d, struct - job->v3d = v3d; - job->free = free; - -- ret = pm_runtime_get_sync(v3d->drm.dev); -- if (ret < 0) -- return ret; -- - xa_init_flags(&job->deps, XA_FLAGS_ALLOC); - - ret = drm_syncobj_find_fence(file_priv, in_sync, 0, 0, &in_fence); -@@ -505,7 +501,6 @@ v3d_job_init(struct v3d_dev *v3d, struct - return 0; - fail: - xa_destroy(&job->deps); -- pm_runtime_put_autosuspend(v3d->drm.dev); - return ret; - } - ---- a/drivers/gpu/drm/v3d/v3d_mmu.c -+++ b/drivers/gpu/drm/v3d/v3d_mmu.c -@@ -36,14 +36,6 @@ static int v3d_mmu_flush_all(struct v3d_ - { - int ret; - -- /* Keep power on the device on until we're done with this -- * call, but skip the flush if the device is off and will be -- * reset when powered back on. -- */ -- ret = pm_runtime_get_if_in_use(v3d->dev); -- if (ret == 0) -- return 0; -- - /* Make sure that another flush isn't already running when we - * start this one. - */ -@@ -71,9 +63,6 @@ static int v3d_mmu_flush_all(struct v3d_ - if (ret) - dev_err(v3d->drm.dev, "MMUC flush wait idle failed\n"); - -- pm_runtime_mark_last_busy(v3d->dev); -- pm_runtime_put_autosuspend(v3d->dev); -- - return ret; - } - diff --git a/target/linux/bcm27xx/patches-5.15/950-0175-Rename-HDMI-ALSA-device-names-check-for-enable-state.patch b/target/linux/bcm27xx/patches-5.15/950-0175-Rename-HDMI-ALSA-device-names-check-for-enable-state.patch deleted file mode 100644 index c7d703434..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0175-Rename-HDMI-ALSA-device-names-check-for-enable-state.patch +++ /dev/null @@ -1,139 +0,0 @@ -From 078a4914aaa74a3af8262b29ff82011b9e752a8e Mon Sep 17 00:00:00 2001 -From: James Hughes -Date: Tue, 24 Sep 2019 18:26:55 +0100 -Subject: [PATCH] Rename HDMI ALSA device names, check for enable state - -HDMI Alsa devices renamed to match names used by DRM, to -HDMI 1 and HDMI 2 - -Check for which HDMI devices are connected and only create -devices for those that are present. - -The rename of the devices might cause some backwards compatibility -issues, but since this particular part of the driver needs to be -specifically enabled, I suspect the number of people who will see -the problem will be very small. - -Signed-off-by: James Hughes ---- - .../vc04_services/bcm2835-audio/bcm2835.c | 70 +++++++++++++++++-- - 1 file changed, 63 insertions(+), 7 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c -@@ -9,8 +9,9 @@ - #include - - #include "bcm2835.h" -+#include - --static bool enable_hdmi; -+static bool enable_hdmi, enable_hdmi0, enable_hdmi1; - static bool enable_headphones; - static bool enable_compat_alsa = true; - -@@ -115,8 +116,8 @@ static struct bcm2835_audio_driver bcm28 - .name = "bcm2835_hdmi", - .owner = THIS_MODULE, - }, -- .shortname = "bcm2835 HDMI", -- .longname = "bcm2835 HDMI", -+ .shortname = "bcm2835 HDMI 1", -+ .longname = "bcm2835 HDMI 1", - .minchannels = 1, - .newpcm = bcm2835_audio_simple_newpcm, - .newctl = snd_bcm2835_new_hdmi_ctl, -@@ -128,8 +129,8 @@ static struct bcm2835_audio_driver bcm28 - .name = "bcm2835_hdmi", - .owner = THIS_MODULE, - }, -- .shortname = "bcm2835 HDMI 1", -- .longname = "bcm2835 HDMI 1", -+ .shortname = "bcm2835 HDMI 2", -+ .longname = "bcm2835 HDMI 2", - .minchannels = 1, - .newpcm = bcm2835_audio_simple_newpcm, - .newctl = snd_bcm2835_new_hdmi_ctl, -@@ -161,11 +162,11 @@ static struct bcm2835_audio_drivers chil - }, - { - .audio_driver = &bcm2835_audio_hdmi0, -- .is_enabled = &enable_hdmi, -+ .is_enabled = &enable_hdmi0, - }, - { - .audio_driver = &bcm2835_audio_hdmi1, -- .is_enabled = &enable_hdmi, -+ .is_enabled = &enable_hdmi1, - }, - { - .audio_driver = &bcm2835_audio_headphones, -@@ -312,6 +313,53 @@ static int snd_add_child_devices(struct - return 0; - } - -+static void set_hdmi_enables(struct device *dev) -+{ -+ struct device_node *firmware_node; -+ struct rpi_firmware *firmware; -+ u32 num_displays, i, display_id; -+ int ret; -+ -+ firmware_node = of_parse_phandle(dev->of_node, "brcm,firmware", 0); -+ firmware = rpi_firmware_get(firmware_node); -+ -+ if (!firmware) -+ return; -+ -+ of_node_put(firmware_node); -+ -+ ret = rpi_firmware_property(firmware, -+ RPI_FIRMWARE_FRAMEBUFFER_GET_NUM_DISPLAYS, -+ &num_displays, sizeof(u32)); -+ -+ if (ret) -+ return; -+ -+ for (i = 0; i < num_displays; i++) { -+ display_id = i; -+ ret = rpi_firmware_property(firmware, -+ RPI_FIRMWARE_FRAMEBUFFER_GET_DISPLAY_ID, -+ &display_id, sizeof(display_id)); -+ if (!ret) { -+ if (display_id == 2) -+ enable_hdmi0 = true; -+ if (display_id == 7) -+ enable_hdmi1 = true; -+ } -+ } -+ -+ if (!enable_hdmi0 && enable_hdmi1) { -+ /* Swap them over and reassign route. This means -+ * that if we only have one connected, it is always named -+ * HDMI1, irrespective of if its on port HDMI0 or HDMI1. -+ * This should match with the naming of HDMI ports in DRM -+ */ -+ enable_hdmi0 = true; -+ enable_hdmi1 = false; -+ bcm2835_audio_hdmi0.route = AUDIO_DEST_HDMI1; -+ } -+} -+ - static int snd_bcm2835_alsa_probe(struct platform_device *pdev) - { - struct device *dev = &pdev->dev; -@@ -332,6 +380,14 @@ static int snd_bcm2835_alsa_probe(struct - numchans); - } - -+ if (!enable_compat_alsa) { -+ set_hdmi_enables(dev); -+ // In this mode, always enable analog output -+ enable_headphones = true; -+ } else { -+ enable_hdmi0 = enable_hdmi; -+ } -+ - err = bcm2835_devm_add_vchi_ctx(dev); - if (err) - return err; diff --git a/target/linux/bcm27xx/patches-5.15/950-0193-drivers-char-vcio-Use-common-compat-header.patch b/target/linux/bcm27xx/patches-5.15/950-0193-drivers-char-vcio-Use-common-compat-header.patch deleted file mode 100644 index f85e2961b..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0193-drivers-char-vcio-Use-common-compat-header.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 9d335660546d3ed85193ca0276f5bf8ca4ee61eb Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 2 Mar 2020 14:40:19 +0000 -Subject: [PATCH] drivers: char: vcio: Use common compat header - -The definition of compat_ptr is now common for most platforms, but -requires the inclusion of . - -Signed-off-by: Phil Elwell ---- - drivers/char/broadcom/vcio.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/char/broadcom/vcio.c -+++ b/drivers/char/broadcom/vcio.c -@@ -18,6 +18,7 @@ - #include - #include - #include -+#include - #include - - #define MBOX_CHAN_PROPERTY 8 diff --git a/target/linux/bcm27xx/patches-5.15/950-0199-media-uapi-hevc-Add-scaling-matrix-control.patch b/target/linux/bcm27xx/patches-5.15/950-0199-media-uapi-hevc-Add-scaling-matrix-control.patch deleted file mode 100644 index 47d523a32..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0199-media-uapi-hevc-Add-scaling-matrix-control.patch +++ /dev/null @@ -1,154 +0,0 @@ -From 49bdb5120b45a6c92e6f10d1d2db85f9d88ba1e3 Mon Sep 17 00:00:00 2001 -From: Jernej Skrabec -Date: Fri, 13 Dec 2019 17:04:25 +0100 -Subject: [PATCH] media: uapi: hevc: Add scaling matrix control - -Taken from https://patchwork.linuxtv.org/patch/60728/ -Changes (mainly documentation) have been requested. - -HEVC has a scaling matrix concept. Add support for it. - -Signed-off-by: Jernej Skrabec ---- - .../media/v4l/ext-ctrls-codec.rst | 41 +++++++++++++++++++ - .../media/v4l/pixfmt-compressed.rst | 5 ++- - drivers/media/v4l2-core/v4l2-ctrls.c | 10 +++++ - include/media/hevc-ctrls.h | 11 +++++ - 4 files changed, 65 insertions(+), 2 deletions(-) - ---- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst -+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst -@@ -3181,6 +3181,47 @@ enum v4l2_mpeg_video_hevc_size_of_length - - \normalsize - -+``V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX (struct)`` -+ Specifies the scaling matrix (as extracted from the bitstream) for -+ the associated HEVC slice data. The bitstream parameters are -+ defined according to :ref:`hevc`, section 7.4.5 "Scaling list -+ data semantics". For further documentation, refer to the above -+ specification, unless there is an explicit comment stating -+ otherwise. -+ -+ .. note:: -+ -+ This compound control is not yet part of the public kernel API and -+ it is expected to change. -+ -+.. c:type:: v4l2_ctrl_hevc_scaling_matrix -+ -+.. cssclass:: longtable -+ -+.. flat-table:: struct v4l2_ctrl_hevc_scaling_matrix -+ :header-rows: 0 -+ :stub-columns: 0 -+ :widths: 1 1 2 -+ -+ * - __u8 -+ - ``scaling_list_4x4[6][16]`` -+ - -+ * - __u8 -+ - ``scaling_list_8x8[6][64]`` -+ - -+ * - __u8 -+ - ``scaling_list_16x16[6][64]`` -+ - -+ * - __u8 -+ - ``scaling_list_32x32[2][64]`` -+ - -+ * - __u8 -+ - ``scaling_list_dc_coef_16x16[6]`` -+ - -+ * - __u8 -+ - ``scaling_list_dc_coef_32x32[2]`` -+ - -+ - ``V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE (enum)`` - Specifies the decoding mode to use. Currently exposes slice-based and - frame-based decoding but new modes might be added later on. ---- a/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst -+++ b/Documentation/userspace-api/media/v4l/pixfmt-compressed.rst -@@ -195,8 +195,9 @@ Compressed Formats - Metadata associated with the frame to decode is required to be passed - through the following controls: - ``V4L2_CID_MPEG_VIDEO_HEVC_SPS``, -- ``V4L2_CID_MPEG_VIDEO_HEVC_PPS``, and -- ``V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS``. -+ ``V4L2_CID_MPEG_VIDEO_HEVC_PPS``, -+ ``V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS``, and -+ ``V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX``. - See the :ref:`associated Codec Control IDs `. - Buffers associated with this pixel format must contain the appropriate - number of macroblocks to decode a full corresponding frame. ---- a/drivers/media/v4l2-core/v4l2-ctrls.c -+++ b/drivers/media/v4l2-core/v4l2-ctrls.c -@@ -1042,6 +1042,7 @@ const char *v4l2_ctrl_get_name(u32 id) - case V4L2_CID_MPEG_VIDEO_HEVC_SPS: return "HEVC Sequence Parameter Set"; - case V4L2_CID_MPEG_VIDEO_HEVC_PPS: return "HEVC Picture Parameter Set"; - case V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS: return "HEVC Slice Parameters"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX: return "HEVC Scaling Matrix"; - case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE: return "HEVC Decode Mode"; - case V4L2_CID_MPEG_VIDEO_HEVC_START_CODE: return "HEVC Start Code"; - -@@ -1527,6 +1528,9 @@ void v4l2_ctrl_fill(u32 id, const char * - case V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS: - *type = V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS; - break; -+ case V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX: -+ *type = V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX; -+ break; - case V4L2_CID_UNIT_CELL_SIZE: - *type = V4L2_CTRL_TYPE_AREA; - *flags |= V4L2_CTRL_FLAG_READ_ONLY; -@@ -2238,6 +2242,9 @@ static int std_validate_compound(const s - - break; - -+ case V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX: -+ break; -+ - case V4L2_CTRL_TYPE_AREA: - area = p; - if (!area->width || !area->height) -@@ -2954,6 +2961,9 @@ static struct v4l2_ctrl *v4l2_ctrl_new(s - case V4L2_CTRL_TYPE_HDR10_MASTERING_DISPLAY: - elem_size = sizeof(struct v4l2_ctrl_hdr10_mastering_display); - break; -+ case V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX: -+ elem_size = sizeof(struct v4l2_ctrl_hevc_scaling_matrix); -+ break; - case V4L2_CTRL_TYPE_AREA: - elem_size = sizeof(struct v4l2_area); - break; ---- a/include/media/hevc-ctrls.h -+++ b/include/media/hevc-ctrls.h -@@ -19,6 +19,7 @@ - #define V4L2_CID_MPEG_VIDEO_HEVC_SPS (V4L2_CID_CODEC_BASE + 1008) - #define V4L2_CID_MPEG_VIDEO_HEVC_PPS (V4L2_CID_CODEC_BASE + 1009) - #define V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS (V4L2_CID_CODEC_BASE + 1010) -+#define V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX (V4L2_CID_CODEC_BASE + 1011) - #define V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS (V4L2_CID_CODEC_BASE + 1012) - #define V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE (V4L2_CID_CODEC_BASE + 1015) - #define V4L2_CID_MPEG_VIDEO_HEVC_START_CODE (V4L2_CID_CODEC_BASE + 1016) -@@ -27,6 +28,7 @@ - #define V4L2_CTRL_TYPE_HEVC_SPS 0x0120 - #define V4L2_CTRL_TYPE_HEVC_PPS 0x0121 - #define V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS 0x0122 -+#define V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX 0x0123 - #define V4L2_CTRL_TYPE_HEVC_DECODE_PARAMS 0x0124 - - enum v4l2_mpeg_video_hevc_decode_mode { -@@ -238,4 +240,13 @@ struct v4l2_ctrl_hevc_decode_params { - */ - #define V4L2_CID_HANTRO_HEVC_SLICE_HEADER_SKIP (V4L2_CID_CODEC_HANTRO_BASE + 0) - -+struct v4l2_ctrl_hevc_scaling_matrix { -+ __u8 scaling_list_4x4[6][16]; -+ __u8 scaling_list_8x8[6][64]; -+ __u8 scaling_list_16x16[6][64]; -+ __u8 scaling_list_32x32[2][64]; -+ __u8 scaling_list_dc_coef_16x16[6]; -+ __u8 scaling_list_dc_coef_32x32[2]; -+}; -+ - #endif diff --git a/target/linux/bcm27xx/patches-5.15/950-0200-media-uapi-hevc-Add-segment-address-field.patch b/target/linux/bcm27xx/patches-5.15/950-0200-media-uapi-hevc-Add-segment-address-field.patch deleted file mode 100644 index 6bd8e11e5..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0200-media-uapi-hevc-Add-segment-address-field.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 8ed873d6e26bc706b0af3bef29f87e2975046222 Mon Sep 17 00:00:00 2001 -From: Jernej Skrabec -Date: Fri, 13 Dec 2019 17:04:27 +0100 -Subject: [PATCH] media: uapi: hevc: Add segment address field - -From https://patchwork.linuxtv.org/patch/60725/ -Changes requested, but mainly docs. - -If HEVC frame consists of multiple slices, segment address has to be -known in order to properly decode it. - -Add segment address field to slice parameters. - -Signed-off-by: Jernej Skrabec ---- - .../userspace-api/media/v4l/ext-ctrls-codec.rst | 3 +++ - include/media/hevc-ctrls.h | 9 +++++++-- - 2 files changed, 10 insertions(+), 2 deletions(-) - ---- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst -+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst -@@ -2961,6 +2961,9 @@ enum v4l2_mpeg_video_hevc_size_of_length - * - __u32 - - ``data_bit_offset`` - - Offset (in bits) to the video data in the current slice data. -+ * - __u32 -+ - ``slice_segment_addr`` -+ - - * - __u8 - - ``nal_unit_type`` - - ---- a/include/media/hevc-ctrls.h -+++ b/include/media/hevc-ctrls.h -@@ -173,6 +173,10 @@ struct v4l2_ctrl_hevc_slice_params { - __u32 bit_size; - __u32 data_bit_offset; - -+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */ -+ __u32 slice_segment_addr; -+ __u32 num_entry_point_offsets; -+ - /* ISO/IEC 23008-2, ITU-T Rec. H.265: NAL unit header */ - __u8 nal_unit_type; - __u8 nuh_temporal_id_plus1; -@@ -198,11 +202,12 @@ struct v4l2_ctrl_hevc_slice_params { - __u8 pic_struct; - - /* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */ -- __u32 slice_segment_addr; - __u8 ref_idx_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; - __u8 ref_idx_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; - -- __u8 padding; -+ __u8 padding[5]; -+ -+ __u32 entry_point_offset_minus1[256]; - - /* ISO/IEC 23008-2, ITU-T Rec. H.265: Weighted prediction parameter */ - struct v4l2_hevc_pred_weight_table pred_weight_table; diff --git a/target/linux/bcm27xx/patches-5.15/950-0204-dt-bindings-clock-Add-a-binding-for-the-RPi-Firmware.patch b/target/linux/bcm27xx/patches-5.15/950-0204-dt-bindings-clock-Add-a-binding-for-the-RPi-Firmware.patch deleted file mode 100644 index 7b98b69fd..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0204-dt-bindings-clock-Add-a-binding-for-the-RPi-Firmware.patch +++ /dev/null @@ -1,63 +0,0 @@ -From b0682b4ef5d4eb82ee702d8c3f3560349f1a231c Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Thu, 13 Feb 2020 17:51:09 +0100 -Subject: [PATCH] dt-bindings: clock: Add a binding for the RPi - Firmware clocks - -The firmare running on the RPi VideoCore can be used to discover and -change the various clocks running in the BCM2711. Since devices will -need to use them through the DT, let's add a pretty simple binding. - -Cc: Michael Turquette -Cc: Stephen Boyd -Cc: Rob Herring -Cc: linux-clk@vger.kernel.org -Cc: devicetree@vger.kernel.org -Signed-off-by: Maxime Ripard ---- - .../clock/raspberrypi,firmware-clocks.yaml | 39 +++++++++++++++++++ - 1 file changed, 39 insertions(+) - create mode 100644 Documentation/devicetree/bindings/clock/raspberrypi,firmware-clocks.yaml - ---- /dev/null -+++ b/Documentation/devicetree/bindings/clock/raspberrypi,firmware-clocks.yaml -@@ -0,0 +1,39 @@ -+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) -+%YAML 1.2 -+--- -+$id: http://devicetree.org/schemas/clock/raspberrypi,firmware-clocks.yaml# -+$schema: http://devicetree.org/meta-schemas/core.yaml# -+ -+title: RaspberryPi Firmware Clocks Device Tree Bindings -+ -+maintainers: -+ - Maxime Ripard -+ -+properties: -+ "#clock-cells": -+ const: 1 -+ -+ compatible: -+ const: raspberrypi,firmware-clocks -+ -+ raspberrypi,firmware: -+ $ref: /schemas/types.yaml#/definitions/phandle -+ description: > -+ Phandle to the mailbox node to communicate with the firmware. -+ -+required: -+ - "#clock-cells" -+ - compatible -+ - raspberrypi,firmware -+ -+additionalProperties: false -+ -+examples: -+ - | -+ firmware_clocks: firmware-clocks { -+ compatible = "raspberrypi,firmware-clocks"; -+ raspberrypi,firmware = <&firmware>; -+ #clock-cells = <1>; -+ }; -+ -+... diff --git a/target/linux/bcm27xx/patches-5.15/950-0205-dt-bindings-display-vc4-hdmi-Add-BCM2711-HDMI-contro.patch b/target/linux/bcm27xx/patches-5.15/950-0205-dt-bindings-display-vc4-hdmi-Add-BCM2711-HDMI-contro.patch deleted file mode 100644 index efde9d381..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0205-dt-bindings-display-vc4-hdmi-Add-BCM2711-HDMI-contro.patch +++ /dev/null @@ -1,174 +0,0 @@ -From b60e8bcad707be3999f253d0d8a829130c1862c2 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Thu, 13 Feb 2020 16:45:24 +0100 -Subject: [PATCH] dt-bindings: display: vc4: hdmi: Add BCM2711 HDMI - controllers bindings - -The HDMI controllers found in the BCM2711 SoC need some adjustments to the -bindings, especially since the registers have been shuffled around in more -register ranges. - -Cc: Rob Herring -Cc: devicetree@vger.kernel.org -Signed-off-by: Maxime Ripard ---- - .../bindings/display/brcm,bcm2835-hdmi.yaml | 118 ++++++++++++++++-- - 1 file changed, 109 insertions(+), 9 deletions(-) - ---- a/Documentation/devicetree/bindings/display/brcm,bcm2835-hdmi.yaml -+++ b/Documentation/devicetree/bindings/display/brcm,bcm2835-hdmi.yaml -@@ -11,24 +11,58 @@ maintainers: - - properties: - compatible: -- const: brcm,bcm2835-hdmi -+ enum: -+ - brcm,bcm2835-hdmi -+ - brcm,bcm2711-hdmi0 -+ - brcm,bcm2711-hdmi1 - - reg: -+ oneOf: -+ - items: -+ - description: HDMI register range -+ - description: HD register range -+ -+ - items: -+ - description: HDMI controller register range -+ - description: DVP register range -+ - description: HDMI PHY register range -+ - description: Rate Manager register range -+ - description: Packet RAM register range -+ - description: Metadata RAM register range -+ - description: CSC register range -+ - description: CEC register range -+ - description: HD register range -+ -+ reg-names: - items: -- - description: HDMI register range -- - description: HD register range -+ - const: hdmi -+ - const: dvp -+ - const: phy -+ - const: rm -+ - const: packet -+ - const: metadata -+ - const: csc -+ - const: cec -+ - const: hd - - interrupts: - minItems: 2 - - clocks: -- items: -- - description: The pixel clock -- - description: The HDMI state machine clock -+ oneOf: -+ - items: -+ - description: The pixel clock -+ - description: The HDMI state machine clock -+ -+ - items: -+ - description: The HDMI state machine clock - - clock-names: -- items: -- - const: pixel -+ oneOf: -+ - items: -+ - const: pixel -+ - const: hdmi -+ - - const: hdmi - - ddc: -@@ -51,15 +85,54 @@ properties: - dma-names: - const: audio-rx - -+ resets: -+ maxItems: 1 -+ - required: - - compatible - - reg -- - interrupts - - clocks - - ddc - - additionalProperties: false - -+if: -+ properties: -+ compatible: -+ contains: -+ enum: -+ - brcm,bcm2711-hdmi0 -+ - brcm,bcm2711-hdmi1 -+ -+then: -+ properties: -+ reg: -+ minItems: 9 -+ -+ clocks: -+ maxItems: 1 -+ -+ clock-names: -+ maxItems: 1 -+ -+ required: -+ - reg-names -+ - resets -+ -+else: -+ properties: -+ reg: -+ maxItems: 2 -+ -+ clocks: -+ minItems: 2 -+ -+ clock-names: -+ minItems: 2 -+ -+ required: -+ - interrupts -+ - examples: - - | - #include -@@ -77,4 +150,31 @@ examples: - clock-names = "pixel", "hdmi"; - }; - -+ - | -+ hdmi0: hdmi@7ef00700 { -+ compatible = "brcm,bcm2711-hdmi0"; -+ reg = <0x7ef00700 0x300>, -+ <0x7ef00300 0x200>, -+ <0x7ef00f00 0x80>, -+ <0x7ef00f80 0x80>, -+ <0x7ef01b00 0x200>, -+ <0x7ef01f00 0x400>, -+ <0x7ef00200 0x80>, -+ <0x7ef04300 0x100>, -+ <0x7ef20000 0x100>; -+ reg-names = "hdmi", -+ "dvp", -+ "phy", -+ "rm", -+ "packet", -+ "metadata", -+ "csc", -+ "cec", -+ "hd"; -+ clocks = <&firmware_clocks 13>; -+ clock-names = "hdmi"; -+ resets = <&dvp 0>; -+ ddc = <&ddc0>; -+ }; -+ - ... diff --git a/target/linux/bcm27xx/patches-5.15/950-0206-drm-Checking-of-the-pitch-is-only-valid-for-linear-f.patch b/target/linux/bcm27xx/patches-5.15/950-0206-drm-Checking-of-the-pitch-is-only-valid-for-linear-f.patch deleted file mode 100644 index 06ad9d301..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0206-drm-Checking-of-the-pitch-is-only-valid-for-linear-f.patch +++ /dev/null @@ -1,39 +0,0 @@ -From e8a4f85fb2d132ccd7e5773176df779588ba1281 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 27 Jan 2020 10:22:44 +0000 -Subject: [PATCH] drm: Checking of the pitch is only valid for linear - formats - -framebuffer_check was computing a minimum pitch value and ensuring -that the provided value was greater than this. -That check is only valid if the format is linear. - -Signed-off-by: Dave Stevenson ---- - drivers/gpu/drm/drm_framebuffer.c | 16 ++++++++++------ - 1 file changed, 10 insertions(+), 6 deletions(-) - ---- a/drivers/gpu/drm/drm_framebuffer.c -+++ b/drivers/gpu/drm/drm_framebuffer.c -@@ -214,12 +214,16 @@ static int framebuffer_check(struct drm_ - if (min_pitch > UINT_MAX) - return -ERANGE; - -- if ((uint64_t) height * r->pitches[i] + r->offsets[i] > UINT_MAX) -- return -ERANGE; -+ if (r->modifier[i] == DRM_FORMAT_MOD_LINEAR) { -+ if ((uint64_t)height * r->pitches[i] + r->offsets[i] > -+ UINT_MAX) -+ return -ERANGE; - -- if (block_size && r->pitches[i] < min_pitch) { -- DRM_DEBUG_KMS("bad pitch %u for plane %d\n", r->pitches[i], i); -- return -EINVAL; -+ if (block_size && r->pitches[i] < min_pitch) { -+ DRM_DEBUG_KMS("bad pitch %u for plane %d\n", -+ r->pitches[i], i); -+ return -EINVAL; -+ } - } - - if (r->modifier[i] && !(r->flags & DRM_MODE_FB_MODIFIERS)) { diff --git a/target/linux/bcm27xx/patches-5.15/950-0207-driver-char-rpivid-Remove-legacy-name-support.patch b/target/linux/bcm27xx/patches-5.15/950-0207-driver-char-rpivid-Remove-legacy-name-support.patch deleted file mode 100644 index df0f3caa4..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0207-driver-char-rpivid-Remove-legacy-name-support.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 7f47cc7fd70961891c50ce303147274b6f318464 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 20 Apr 2020 22:18:52 +0100 -Subject: [PATCH] driver: char: rpivid: Remove legacy name support - -Signed-off-by: Phil Elwell ---- - drivers/char/broadcom/rpivid-mem.c | 22 ---------------------- - 1 file changed, 22 deletions(-) - ---- a/drivers/char/broadcom/rpivid-mem.c -+++ b/drivers/char/broadcom/rpivid-mem.c -@@ -193,32 +193,11 @@ static int rpivid_mem_probe(struct platf - goto failed_device_create; - } - -- /* Legacy alias */ -- { -- char *oldname = kstrdup(priv->name, GFP_KERNEL); -- -- oldname[1] = 'a'; -- oldname[2] = 'r'; -- oldname[3] = 'g'; -- oldname[4] = 'o'; -- oldname[5] = 'n'; -- dev = device_create(priv->class, NULL, priv->devid + 1, NULL, -- oldname + 1); -- kfree(oldname); -- -- if (IS_ERR(dev)) { -- err = PTR_ERR(dev); -- goto failed_legacy_device_create; -- } -- } -- - dev_info(priv->dev, "%s initialised: Registers at 0x%08lx length 0x%08lx", - priv->name, priv->regs_phys, priv->mem_window_len); - - return 0; - --failed_legacy_device_create: -- device_destroy(priv->class, priv->devid); - failed_device_create: - class_destroy(priv->class); - failed_class_create: -@@ -238,7 +217,6 @@ static int rpivid_mem_remove(struct plat - struct device *dev = &pdev->dev; - struct rpivid_mem_priv *priv = platform_get_drvdata(pdev); - -- device_destroy(priv->class, priv->devid + 1); - device_destroy(priv->class, priv->devid); - class_destroy(priv->class); - cdev_del(&priv->rpivid_mem_cdev); diff --git a/target/linux/bcm27xx/patches-5.15/950-0209-driver-char-rpivid-Don-t-map-more-than-wanted.patch b/target/linux/bcm27xx/patches-5.15/950-0209-driver-char-rpivid-Don-t-map-more-than-wanted.patch deleted file mode 100644 index c1a1f7431..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0209-driver-char-rpivid-Don-t-map-more-than-wanted.patch +++ /dev/null @@ -1,51 +0,0 @@ -From f24635237a6c0f3338955169098fd6709b4420d5 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 21 Apr 2020 11:30:23 +0100 -Subject: [PATCH] driver: char: rpivid: Don't map more than wanted - -Limit mappings to the permitted range, but don't map more than asked -for otherwise we walk off the end of the allocated VMA. - -Signed-off-by: Phil Elwell ---- - drivers/char/broadcom/rpivid-mem.c | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - ---- a/drivers/char/broadcom/rpivid-mem.c -+++ b/drivers/char/broadcom/rpivid-mem.c -@@ -100,6 +100,7 @@ static int rpivid_mem_mmap(struct file * - { - struct rpivid_mem_priv *priv; - unsigned long pages; -+ unsigned long len; - - priv = file->private_data; - pages = priv->regs_phys >> PAGE_SHIFT; -@@ -107,14 +108,13 @@ static int rpivid_mem_mmap(struct file * - * The address decode is far larger than the actual number of registers. - * Just map the whole lot in. - */ -- vma->vm_page_prot = phys_mem_access_prot(file, pages, -- priv->mem_window_len, -+ len = min(vma->vm_end - vma->vm_start, priv->mem_window_len); -+ vma->vm_page_prot = phys_mem_access_prot(file, pages, len, - vma->vm_page_prot); - vma->vm_ops = &rpivid_mem_vm_ops; - if (remap_pfn_range(vma, vma->vm_start, -- pages, -- priv->mem_window_len, -- vma->vm_page_prot)) { -+ pages, len, -+ vma->vm_page_prot)) { - return -EAGAIN; - } - return 0; -@@ -156,7 +156,7 @@ static int rpivid_mem_probe(struct platf - ioresource = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (ioresource) { - priv->regs_phys = ioresource->start; -- priv->mem_window_len = ioresource->end - ioresource->start; -+ priv->mem_window_len = (ioresource->end + 1) - ioresource->start; - } else { - dev_err(priv->dev, "failed to get IO resource"); - err = -ENOENT; diff --git a/target/linux/bcm27xx/patches-5.15/950-0210-media-bcm2835-unicam-Driver-for-CCP2-CSI2-camera-int.patch b/target/linux/bcm27xx/patches-5.15/950-0210-media-bcm2835-unicam-Driver-for-CCP2-CSI2-camera-int.patch deleted file mode 100644 index b7bb1474e..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0210-media-bcm2835-unicam-Driver-for-CCP2-CSI2-camera-int.patch +++ /dev/null @@ -1,2711 +0,0 @@ -From 8f4208f42c896b71abe54b697cd044f0af490e67 Mon Sep 17 00:00:00 2001 -From: Naushir Patuck -Date: Wed, 1 Apr 2020 08:39:49 +0100 -Subject: [PATCH] media: bcm2835-unicam: Driver for CCP2/CSI2 camera - interface - -Add driver for the Unicam camera receiver block on -BCM283x processors. - -This commit is made up of a series of changes cherry-picked from the -rpi-4.19.y branch. - -Signed-off-by: Dave Stevenson -Signed-off-by: Naushir Patuck ---- - MAINTAINERS | 2 +- - drivers/media/platform/Kconfig | 1 + - drivers/media/platform/Makefile | 2 + - drivers/media/platform/bcm2835/Kconfig | 14 + - drivers/media/platform/bcm2835/Makefile | 3 + - .../media/platform/bcm2835/bcm2835-unicam.c | 2369 +++++++++++++++++ - .../media/platform/bcm2835/vc4-regs-unicam.h | 253 ++ - 7 files changed, 2643 insertions(+), 1 deletion(-) - create mode 100644 drivers/media/platform/bcm2835/Kconfig - create mode 100644 drivers/media/platform/bcm2835/Makefile - create mode 100644 drivers/media/platform/bcm2835/bcm2835-unicam.c - create mode 100644 drivers/media/platform/bcm2835/vc4-regs-unicam.h - ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -3563,7 +3563,7 @@ F: Documentation/devicetree/bindings/med - F: drivers/staging/media/rpivid - - BROADCOM BCM2835 CAMERA DRIVER --M: Dave Stevenson -+M: Raspberry Pi Kernel Maintenance - L: linux-media@vger.kernel.org - S: Maintained - F: drivers/media/platform/bcm2835/ ---- a/drivers/media/platform/Kconfig -+++ b/drivers/media/platform/Kconfig -@@ -170,6 +170,7 @@ source "drivers/media/platform/am437x/Kc - source "drivers/media/platform/xilinx/Kconfig" - source "drivers/media/platform/rcar-vin/Kconfig" - source "drivers/media/platform/atmel/Kconfig" -+source "drivers/media/platform/bcm2835/Kconfig" - source "drivers/media/platform/sunxi/Kconfig" - - config VIDEO_TI_CAL ---- a/drivers/media/platform/Makefile -+++ b/drivers/media/platform/Makefile -@@ -83,6 +83,8 @@ obj-$(CONFIG_VIDEO_QCOM_CAMSS) += qcom/ - - obj-$(CONFIG_VIDEO_QCOM_VENUS) += qcom/venus/ - -+obj-y += bcm2835/ -+ - obj-y += sunxi/ - - obj-$(CONFIG_VIDEO_MESON_GE2D) += meson/ge2d/ ---- /dev/null -+++ b/drivers/media/platform/bcm2835/Kconfig -@@ -0,0 +1,14 @@ -+# Broadcom VideoCore4 V4L2 camera support -+ -+config VIDEO_BCM2835_UNICAM -+ tristate "Broadcom BCM2835 Unicam video capture driver" -+ depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && MEDIA_CONTROLLER -+ depends on ARCH_BCM2835 || COMPILE_TEST -+ select VIDEOBUF2_DMA_CONTIG -+ select V4L2_FWNODE -+ help -+ Say Y here to enable V4L2 subdevice for CSI2 receiver. -+ This is a V4L2 subdevice that interfaces directly to the VC4 peripheral. -+ -+ To compile this driver as a module, choose M here. The module -+ will be called bcm2835-unicam. ---- /dev/null -+++ b/drivers/media/platform/bcm2835/Makefile -@@ -0,0 +1,3 @@ -+# Makefile for BCM2835 Unicam driver -+ -+obj-$(CONFIG_VIDEO_BCM2835_UNICAM) += bcm2835-unicam.o ---- /dev/null -+++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c -@@ -0,0 +1,2369 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * BCM2835 Unicam Capture Driver -+ * -+ * Copyright (C) 2017-2020 - Raspberry Pi (Trading) Ltd. -+ * -+ * Dave Stevenson -+ * -+ * Based on TI am437x driver by -+ * Benoit Parrot -+ * Lad, Prabhakar -+ * -+ * and TI CAL camera interface driver by -+ * Benoit Parrot -+ * -+ * -+ * There are two camera drivers in the kernel for BCM283x - this one -+ * and bcm2835-camera (currently in staging). -+ * -+ * This driver directly controls the Unicam peripheral - there is no -+ * involvement with the VideoCore firmware. Unicam receives CSI-2 or -+ * CCP2 data and writes it into SDRAM. -+ * The only potential processing options are to repack Bayer data into an -+ * alternate format, and applying windowing. -+ * The repacking does not shift the data, so can repack V4L2_PIX_FMT_Sxxxx10P -+ * to V4L2_PIX_FMT_Sxxxx10, or V4L2_PIX_FMT_Sxxxx12P to V4L2_PIX_FMT_Sxxxx12, -+ * but not generically up to V4L2_PIX_FMT_Sxxxx16. The driver will add both -+ * formats where the relevant formats are defined, and will automatically -+ * configure the repacking as required. -+ * Support for windowing may be added later. -+ * -+ * It should be possible to connect this driver to any sensor with a -+ * suitable output interface and V4L2 subdevice driver. -+ * -+ * bcm2835-camera uses the VideoCore firmware to control the sensor, -+ * Unicam, ISP, and all tuner control loops. Fully processed frames are -+ * delivered to the driver by the firmware. It only has sensor drivers -+ * for Omnivision OV5647, and Sony IMX219 sensors. -+ * -+ * The two drivers are mutually exclusive for the same Unicam instance. -+ * The VideoCore firmware checks the device tree configuration during boot. -+ * If it finds device tree nodes called csi0 or csi1 it will block the -+ * firmware from accessing the peripheral, and bcm2835-camera will -+ * not be able to stream data. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "vc4-regs-unicam.h" -+ -+#define UNICAM_MODULE_NAME "unicam" -+#define UNICAM_VERSION "0.1.0" -+ -+static int debug; -+module_param(debug, int, 0644); -+MODULE_PARM_DESC(debug, "Debug level 0-3"); -+ -+#define unicam_dbg(level, dev, fmt, arg...) \ -+ v4l2_dbg(level, debug, &(dev)->v4l2_dev, fmt, ##arg) -+#define unicam_info(dev, fmt, arg...) \ -+ v4l2_info(&(dev)->v4l2_dev, fmt, ##arg) -+#define unicam_err(dev, fmt, arg...) \ -+ v4l2_err(&(dev)->v4l2_dev, fmt, ##arg) -+ -+/* To protect against a dodgy sensor driver never returning an error from -+ * enum_mbus_code, set a maximum index value to be used. -+ */ -+#define MAX_ENUM_MBUS_CODE 128 -+ -+/* -+ * Stride is a 16 bit register, but also has to be a multiple of 32. -+ */ -+#define BPL_ALIGNMENT 32 -+#define MAX_BYTESPERLINE ((1 << 16) - BPL_ALIGNMENT) -+/* -+ * Max width is therefore determined by the max stride divided by -+ * the number of bits per pixel. Take 32bpp as a -+ * worst case. -+ * No imposed limit on the height, so adopt a square image for want -+ * of anything better. -+ */ -+#define MAX_WIDTH (MAX_BYTESPERLINE / 4) -+#define MAX_HEIGHT MAX_WIDTH -+/* Define a nominal minimum image size */ -+#define MIN_WIDTH 16 -+#define MIN_HEIGHT 16 -+ -+/* -+ * struct unicam_fmt - Unicam media bus format information -+ * @pixelformat: V4L2 pixel format FCC identifier. 0 if n/a. -+ * @repacked_fourcc: V4L2 pixel format FCC identifier if the data is expanded -+ * out to 16bpp. 0 if n/a. -+ * @code: V4L2 media bus format code. -+ * @depth: Bits per pixel as delivered from the source. -+ * @csi_dt: CSI data type. -+ * @check_variants: Flag to denote that there are multiple mediabus formats -+ * still in the list that could match this V4L2 format. -+ */ -+struct unicam_fmt { -+ u32 fourcc; -+ u32 repacked_fourcc; -+ u32 code; -+ u8 depth; -+ u8 csi_dt; -+ u8 check_variants; -+}; -+ -+static const struct unicam_fmt formats[] = { -+ /* YUV Formats */ -+ { -+ .fourcc = V4L2_PIX_FMT_YUYV, -+ .code = MEDIA_BUS_FMT_YUYV8_2X8, -+ .depth = 16, -+ .csi_dt = 0x1e, -+ .check_variants = 1, -+ }, { -+ .fourcc = V4L2_PIX_FMT_UYVY, -+ .code = MEDIA_BUS_FMT_UYVY8_2X8, -+ .depth = 16, -+ .csi_dt = 0x1e, -+ .check_variants = 1, -+ }, { -+ .fourcc = V4L2_PIX_FMT_YVYU, -+ .code = MEDIA_BUS_FMT_YVYU8_2X8, -+ .depth = 16, -+ .csi_dt = 0x1e, -+ .check_variants = 1, -+ }, { -+ .fourcc = V4L2_PIX_FMT_VYUY, -+ .code = MEDIA_BUS_FMT_VYUY8_2X8, -+ .depth = 16, -+ .csi_dt = 0x1e, -+ .check_variants = 1, -+ }, { -+ .fourcc = V4L2_PIX_FMT_YUYV, -+ .code = MEDIA_BUS_FMT_YUYV8_1X16, -+ .depth = 16, -+ .csi_dt = 0x1e, -+ }, { -+ .fourcc = V4L2_PIX_FMT_UYVY, -+ .code = MEDIA_BUS_FMT_UYVY8_1X16, -+ .depth = 16, -+ .csi_dt = 0x1e, -+ }, { -+ .fourcc = V4L2_PIX_FMT_YVYU, -+ .code = MEDIA_BUS_FMT_YVYU8_1X16, -+ .depth = 16, -+ .csi_dt = 0x1e, -+ }, { -+ .fourcc = V4L2_PIX_FMT_VYUY, -+ .code = MEDIA_BUS_FMT_VYUY8_1X16, -+ .depth = 16, -+ .csi_dt = 0x1e, -+ }, { -+ /* RGB Formats */ -+ .fourcc = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */ -+ .code = MEDIA_BUS_FMT_RGB565_2X8_LE, -+ .depth = 16, -+ .csi_dt = 0x22, -+ }, { -+ .fourcc = V4L2_PIX_FMT_RGB565X, /* rrrrrggg gggbbbbb */ -+ .code = MEDIA_BUS_FMT_RGB565_2X8_BE, -+ .depth = 16, -+ .csi_dt = 0x22 -+ }, { -+ .fourcc = V4L2_PIX_FMT_RGB555, /* gggbbbbb arrrrrgg */ -+ .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE, -+ .depth = 16, -+ .csi_dt = 0x21, -+ }, { -+ .fourcc = V4L2_PIX_FMT_RGB555X, /* arrrrrgg gggbbbbb */ -+ .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE, -+ .depth = 16, -+ .csi_dt = 0x21, -+ }, { -+ .fourcc = V4L2_PIX_FMT_RGB24, /* rgb */ -+ .code = MEDIA_BUS_FMT_RGB888_1X24, -+ .depth = 24, -+ .csi_dt = 0x24, -+ }, { -+ .fourcc = V4L2_PIX_FMT_BGR24, /* bgr */ -+ .code = MEDIA_BUS_FMT_BGR888_1X24, -+ .depth = 24, -+ .csi_dt = 0x24, -+ }, { -+ .fourcc = V4L2_PIX_FMT_RGB32, /* argb */ -+ .code = MEDIA_BUS_FMT_ARGB8888_1X32, -+ .depth = 32, -+ .csi_dt = 0x0, -+ }, { -+ /* Bayer Formats */ -+ .fourcc = V4L2_PIX_FMT_SBGGR8, -+ .code = MEDIA_BUS_FMT_SBGGR8_1X8, -+ .depth = 8, -+ .csi_dt = 0x2a, -+ }, { -+ .fourcc = V4L2_PIX_FMT_SGBRG8, -+ .code = MEDIA_BUS_FMT_SGBRG8_1X8, -+ .depth = 8, -+ .csi_dt = 0x2a, -+ }, { -+ .fourcc = V4L2_PIX_FMT_SGRBG8, -+ .code = MEDIA_BUS_FMT_SGRBG8_1X8, -+ .depth = 8, -+ .csi_dt = 0x2a, -+ }, { -+ .fourcc = V4L2_PIX_FMT_SRGGB8, -+ .code = MEDIA_BUS_FMT_SRGGB8_1X8, -+ .depth = 8, -+ .csi_dt = 0x2a, -+ }, { -+ .fourcc = V4L2_PIX_FMT_SBGGR10P, -+ .repacked_fourcc = V4L2_PIX_FMT_SBGGR10, -+ .code = MEDIA_BUS_FMT_SBGGR10_1X10, -+ .depth = 10, -+ .csi_dt = 0x2b, -+ }, { -+ .fourcc = V4L2_PIX_FMT_SGBRG10P, -+ .repacked_fourcc = V4L2_PIX_FMT_SGBRG10, -+ .code = MEDIA_BUS_FMT_SGBRG10_1X10, -+ .depth = 10, -+ .csi_dt = 0x2b, -+ }, { -+ .fourcc = V4L2_PIX_FMT_SGRBG10P, -+ .repacked_fourcc = V4L2_PIX_FMT_SGRBG10, -+ .code = MEDIA_BUS_FMT_SGRBG10_1X10, -+ .depth = 10, -+ .csi_dt = 0x2b, -+ }, { -+ .fourcc = V4L2_PIX_FMT_SRGGB10P, -+ .repacked_fourcc = V4L2_PIX_FMT_SRGGB10, -+ .code = MEDIA_BUS_FMT_SRGGB10_1X10, -+ .depth = 10, -+ .csi_dt = 0x2b, -+ }, { -+ .fourcc = V4L2_PIX_FMT_SBGGR12P, -+ .repacked_fourcc = V4L2_PIX_FMT_SBGGR12, -+ .code = MEDIA_BUS_FMT_SBGGR12_1X12, -+ .depth = 12, -+ .csi_dt = 0x2c, -+ }, { -+ .fourcc = V4L2_PIX_FMT_SGBRG12P, -+ .repacked_fourcc = V4L2_PIX_FMT_SGBRG12, -+ .code = MEDIA_BUS_FMT_SGBRG12_1X12, -+ .depth = 12, -+ .csi_dt = 0x2c, -+ }, { -+ .fourcc = V4L2_PIX_FMT_SGRBG12P, -+ .repacked_fourcc = V4L2_PIX_FMT_SGRBG12, -+ .code = MEDIA_BUS_FMT_SGRBG12_1X12, -+ .depth = 12, -+ .csi_dt = 0x2c, -+ }, { -+ .fourcc = V4L2_PIX_FMT_SRGGB12P, -+ .repacked_fourcc = V4L2_PIX_FMT_SRGGB12, -+ .code = MEDIA_BUS_FMT_SRGGB12_1X12, -+ .depth = 12, -+ .csi_dt = 0x2c, -+ }, { -+ .fourcc = V4L2_PIX_FMT_SBGGR14P, -+ .code = MEDIA_BUS_FMT_SBGGR14_1X14, -+ .depth = 14, -+ .csi_dt = 0x2d, -+ }, { -+ .fourcc = V4L2_PIX_FMT_SGBRG14P, -+ .code = MEDIA_BUS_FMT_SGBRG14_1X14, -+ .depth = 14, -+ .csi_dt = 0x2d, -+ }, { -+ .fourcc = V4L2_PIX_FMT_SGRBG14P, -+ .code = MEDIA_BUS_FMT_SGRBG14_1X14, -+ .depth = 14, -+ .csi_dt = 0x2d, -+ }, { -+ .fourcc = V4L2_PIX_FMT_SRGGB14P, -+ .code = MEDIA_BUS_FMT_SRGGB14_1X14, -+ .depth = 14, -+ .csi_dt = 0x2d, -+ }, { -+ /* -+ * 16 bit Bayer formats could be supported, but there is no CSI2 -+ * data_type defined for raw 16, and no sensors that produce it at -+ * present. -+ */ -+ -+ /* Greyscale formats */ -+ .fourcc = V4L2_PIX_FMT_GREY, -+ .code = MEDIA_BUS_FMT_Y8_1X8, -+ .depth = 8, -+ .csi_dt = 0x2a, -+ }, { -+ .fourcc = V4L2_PIX_FMT_Y10P, -+ .repacked_fourcc = V4L2_PIX_FMT_Y10, -+ .code = MEDIA_BUS_FMT_Y10_1X10, -+ .depth = 10, -+ .csi_dt = 0x2b, -+ }, { -+ /* NB There is no packed V4L2 fourcc for this format. */ -+ .repacked_fourcc = V4L2_PIX_FMT_Y12, -+ .code = MEDIA_BUS_FMT_Y12_1X12, -+ .depth = 12, -+ .csi_dt = 0x2c, -+ }, -+}; -+ -+struct unicam_dmaqueue { -+ struct list_head active; -+}; -+ -+struct unicam_buffer { -+ struct vb2_v4l2_buffer vb; -+ struct list_head list; -+}; -+ -+struct unicam_cfg { -+ /* peripheral base address */ -+ void __iomem *base; -+ /* clock gating base address */ -+ void __iomem *clk_gate_base; -+}; -+ -+#define MAX_POSSIBLE_PIX_FMTS (ARRAY_SIZE(formats)) -+ -+struct unicam_device { -+ /* V4l2 specific parameters */ -+ /* Identifies video device for this channel */ -+ struct video_device video_dev; -+ struct v4l2_ctrl_handler ctrl_handler; -+ -+ struct v4l2_fwnode_endpoint endpoint; -+ -+ struct v4l2_async_subdev asd; -+ -+ /* unicam cfg */ -+ struct unicam_cfg cfg; -+ /* clock handle */ -+ struct clk *clock; -+ /* V4l2 device */ -+ struct v4l2_device v4l2_dev; -+ struct media_device mdev; -+ struct media_pad pad; -+ -+ /* parent device */ -+ struct platform_device *pdev; -+ /* subdevice async Notifier */ -+ struct v4l2_async_notifier notifier; -+ unsigned int sequence; -+ -+ /* ptr to sub device */ -+ struct v4l2_subdev *sensor; -+ /* Pad config for the sensor */ -+ struct v4l2_subdev_pad_config *sensor_config; -+ /* current input at the sub device */ -+ int current_input; -+ -+ /* Pointer pointing to current v4l2_buffer */ -+ struct unicam_buffer *cur_frm; -+ /* Pointer pointing to next v4l2_buffer */ -+ struct unicam_buffer *next_frm; -+ -+ /* video capture */ -+ const struct unicam_fmt *fmt; -+ /* Used to store current pixel format */ -+ struct v4l2_format v_fmt; -+ /* Used to store current mbus frame format */ -+ struct v4l2_mbus_framefmt m_fmt; -+ -+ unsigned int virtual_channel; -+ enum v4l2_mbus_type bus_type; -+ /* -+ * Stores bus.mipi_csi2.flags for CSI2 sensors, or -+ * bus.mipi_csi1.strobe for CCP2. -+ */ -+ unsigned int bus_flags; -+ unsigned int max_data_lanes; -+ unsigned int active_data_lanes; -+ -+ struct v4l2_rect crop; -+ -+ /* Currently selected input on subdev */ -+ int input; -+ -+ /* Buffer queue used in video-buf */ -+ struct vb2_queue buffer_queue; -+ /* Queue of filled frames */ -+ struct unicam_dmaqueue dma_queue; -+ /* IRQ lock for DMA queue */ -+ spinlock_t dma_queue_lock; -+ /* lock used to access this structure */ -+ struct mutex lock; -+ /* Flag to denote that we are processing buffers */ -+ int streaming; -+}; -+ -+/* Hardware access */ -+#define clk_write(dev, val) writel((val) | 0x5a000000, (dev)->clk_gate_base) -+#define clk_read(dev) readl((dev)->clk_gate_base) -+ -+#define reg_read(dev, offset) readl((dev)->base + (offset)) -+#define reg_write(dev, offset, val) writel(val, (dev)->base + (offset)) -+ -+#define reg_read_field(dev, offset, mask) get_field(reg_read((dev), (offset), \ -+ mask)) -+ -+static inline int get_field(u32 value, u32 mask) -+{ -+ return (value & mask) >> __ffs(mask); -+} -+ -+static inline void set_field(u32 *valp, u32 field, u32 mask) -+{ -+ u32 val = *valp; -+ -+ val &= ~mask; -+ val |= (field << __ffs(mask)) & mask; -+ *valp = val; -+} -+ -+static inline void reg_write_field(struct unicam_cfg *dev, u32 offset, -+ u32 field, u32 mask) -+{ -+ u32 val = reg_read((dev), (offset)); -+ -+ set_field(&val, field, mask); -+ reg_write((dev), (offset), val); -+} -+ -+/* Power management functions */ -+static inline int unicam_runtime_get(struct unicam_device *dev) -+{ -+ return pm_runtime_get_sync(&dev->pdev->dev); -+} -+ -+static inline void unicam_runtime_put(struct unicam_device *dev) -+{ -+ pm_runtime_put_sync(&dev->pdev->dev); -+} -+ -+/* Format setup functions */ -+static const struct unicam_fmt *find_format_by_code(u32 code) -+{ -+ unsigned int i; -+ -+ for (i = 0; i < ARRAY_SIZE(formats); i++) { -+ if (formats[i].code == code) -+ return &formats[i]; -+ } -+ -+ return NULL; -+} -+ -+static int check_mbus_format(struct unicam_device *dev, -+ const struct unicam_fmt *format) -+{ -+ struct v4l2_subdev_mbus_code_enum mbus_code; -+ int ret = 0; -+ int i; -+ -+ for (i = 0; !ret && i < MAX_ENUM_MBUS_CODE; i++) { -+ memset(&mbus_code, 0, sizeof(mbus_code)); -+ mbus_code.index = i; -+ mbus_code.which = V4L2_SUBDEV_FORMAT_ACTIVE; -+ -+ ret = v4l2_subdev_call(dev->sensor, pad, enum_mbus_code, -+ NULL, &mbus_code); -+ -+ if (!ret && mbus_code.code == format->code) -+ return 1; -+ } -+ -+ return 0; -+} -+ -+static const struct unicam_fmt *find_format_by_pix(struct unicam_device *dev, -+ u32 pixelformat) -+{ -+ unsigned int i; -+ -+ for (i = 0; i < ARRAY_SIZE(formats); i++) { -+ if (formats[i].fourcc == pixelformat || -+ formats[i].repacked_fourcc == pixelformat) { -+ if (formats[i].check_variants && -+ !check_mbus_format(dev, &formats[i])) -+ continue; -+ return &formats[i]; -+ } -+ } -+ -+ return NULL; -+} -+ -+static inline unsigned int bytes_per_line(u32 width, -+ const struct unicam_fmt *fmt, -+ u32 v4l2_fourcc) -+{ -+ if (v4l2_fourcc == fmt->repacked_fourcc) -+ /* Repacking always goes to 16bpp */ -+ return ALIGN(width << 1, BPL_ALIGNMENT); -+ else -+ return ALIGN((width * fmt->depth) >> 3, BPL_ALIGNMENT); -+} -+ -+static int __subdev_get_format(struct unicam_device *dev, -+ struct v4l2_mbus_framefmt *fmt) -+{ -+ struct v4l2_subdev_format sd_fmt = { -+ .which = V4L2_SUBDEV_FORMAT_ACTIVE, -+ }; -+ int ret; -+ -+ ret = v4l2_subdev_call(dev->sensor, pad, get_fmt, dev->sensor_config, -+ &sd_fmt); -+ if (ret < 0) -+ return ret; -+ -+ *fmt = sd_fmt.format; -+ -+ unicam_dbg(1, dev, "%s %dx%d code:%04x\n", __func__, -+ fmt->width, fmt->height, fmt->code); -+ -+ return 0; -+} -+ -+static int __subdev_set_format(struct unicam_device *dev, -+ struct v4l2_mbus_framefmt *fmt) -+{ -+ struct v4l2_subdev_format sd_fmt = { -+ .which = V4L2_SUBDEV_FORMAT_ACTIVE, -+ }; -+ int ret; -+ -+ sd_fmt.format = *fmt; -+ -+ ret = v4l2_subdev_call(dev->sensor, pad, set_fmt, dev->sensor_config, -+ &sd_fmt); -+ if (ret < 0) -+ return ret; -+ -+ unicam_dbg(1, dev, "%s %dx%d code:%04x\n", __func__, -+ fmt->width, fmt->height, fmt->code); -+ -+ return 0; -+} -+ -+static int unicam_calc_format_size_bpl(struct unicam_device *dev, -+ const struct unicam_fmt *fmt, -+ struct v4l2_format *f) -+{ -+ unsigned int min_bytesperline; -+ -+ v4l_bound_align_image(&f->fmt.pix.width, MIN_WIDTH, MAX_WIDTH, 2, -+ &f->fmt.pix.height, MIN_HEIGHT, MAX_HEIGHT, 0, -+ 0); -+ -+ min_bytesperline = bytes_per_line(f->fmt.pix.width, fmt, -+ f->fmt.pix.pixelformat); -+ -+ if (f->fmt.pix.bytesperline > min_bytesperline && -+ f->fmt.pix.bytesperline <= MAX_BYTESPERLINE) -+ f->fmt.pix.bytesperline = ALIGN(f->fmt.pix.bytesperline, -+ BPL_ALIGNMENT); -+ else -+ f->fmt.pix.bytesperline = min_bytesperline; -+ -+ f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; -+ -+ unicam_dbg(3, dev, "%s: fourcc: %08X size: %dx%d bpl:%d img_size:%d\n", -+ __func__, -+ f->fmt.pix.pixelformat, -+ f->fmt.pix.width, f->fmt.pix.height, -+ f->fmt.pix.bytesperline, f->fmt.pix.sizeimage); -+ -+ return 0; -+} -+ -+static int unicam_reset_format(struct unicam_device *dev) -+{ -+ struct v4l2_mbus_framefmt mbus_fmt; -+ int ret; -+ -+ ret = __subdev_get_format(dev, &mbus_fmt); -+ if (ret) { -+ unicam_err(dev, "Failed to get_format - ret %d\n", ret); -+ return ret; -+ } -+ -+ if (mbus_fmt.code != dev->fmt->code) { -+ unicam_err(dev, "code mismatch - fmt->code %08x, mbus_fmt.code %08x\n", -+ dev->fmt->code, mbus_fmt.code); -+ return ret; -+ } -+ -+ v4l2_fill_pix_format(&dev->v_fmt.fmt.pix, &mbus_fmt); -+ dev->v_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; -+ -+ unicam_calc_format_size_bpl(dev, dev->fmt, &dev->v_fmt); -+ -+ dev->m_fmt = mbus_fmt; -+ -+ return 0; -+} -+ -+static void unicam_wr_dma_addr(struct unicam_device *dev, dma_addr_t dmaaddr) -+{ -+ /* -+ * dmaaddr should be a 32-bit address with the top two bits set to 0x3 -+ * to signify uncached access through the Videocore memory controller. -+ */ -+ BUG_ON((dmaaddr >> 30) != 0x3); -+ -+ reg_write(&dev->cfg, UNICAM_IBSA0, dmaaddr); -+ reg_write(&dev->cfg, UNICAM_IBEA0, -+ dmaaddr + dev->v_fmt.fmt.pix.sizeimage); -+} -+ -+static inline unsigned int unicam_get_lines_done(struct unicam_device *dev) -+{ -+ dma_addr_t start_addr, cur_addr; -+ unsigned int stride = dev->v_fmt.fmt.pix.bytesperline; -+ struct unicam_buffer *frm = dev->cur_frm; -+ -+ if (!frm) -+ return 0; -+ -+ start_addr = vb2_dma_contig_plane_dma_addr(&frm->vb.vb2_buf, 0); -+ cur_addr = reg_read(&dev->cfg, UNICAM_IBWP); -+ return (unsigned int)(cur_addr - start_addr) / stride; -+} -+ -+static inline void unicam_schedule_next_buffer(struct unicam_device *dev) -+{ -+ struct unicam_dmaqueue *dma_q = &dev->dma_queue; -+ struct unicam_buffer *buf; -+ dma_addr_t addr; -+ -+ buf = list_entry(dma_q->active.next, struct unicam_buffer, list); -+ dev->next_frm = buf; -+ list_del(&buf->list); -+ -+ addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0); -+ unicam_wr_dma_addr(dev, addr); -+} -+ -+static inline void unicam_process_buffer_complete(struct unicam_device *dev) -+{ -+ dev->cur_frm->vb.field = dev->m_fmt.field; -+ dev->cur_frm->vb.sequence = dev->sequence++; -+ -+ vb2_buffer_done(&dev->cur_frm->vb.vb2_buf, VB2_BUF_STATE_DONE); -+ dev->cur_frm = dev->next_frm; -+} -+ -+/* -+ * unicam_isr : ISR handler for unicam capture -+ * @irq: irq number -+ * @dev_id: dev_id ptr -+ * -+ * It changes status of the captured buffer, takes next buffer from the queue -+ * and sets its address in unicam registers -+ */ -+static irqreturn_t unicam_isr(int irq, void *dev) -+{ -+ struct unicam_device *unicam = (struct unicam_device *)dev; -+ struct unicam_cfg *cfg = &unicam->cfg; -+ struct unicam_dmaqueue *dma_q = &unicam->dma_queue; -+ unsigned int lines_done = unicam_get_lines_done(dev); -+ unsigned int sequence = unicam->sequence; -+ int ista, sta; -+ -+ /* -+ * Don't service interrupts if not streaming. -+ * Avoids issues if the VPU should enable the -+ * peripheral without the kernel knowing (that -+ * shouldn't happen, but causes issues if it does). -+ */ -+ if (!unicam->streaming) -+ return IRQ_HANDLED; -+ -+ sta = reg_read(cfg, UNICAM_STA); -+ /* Write value back to clear the interrupts */ -+ reg_write(cfg, UNICAM_STA, sta); -+ -+ ista = reg_read(cfg, UNICAM_ISTA); -+ /* Write value back to clear the interrupts */ -+ reg_write(cfg, UNICAM_ISTA, ista); -+ -+ unicam_dbg(3, unicam, "ISR: ISTA: 0x%X, STA: 0x%X, sequence %d, lines done %d", -+ ista, sta, sequence, lines_done); -+ -+ if (!(sta && (UNICAM_IS | UNICAM_PI0))) -+ return IRQ_HANDLED; -+ -+ if (ista & UNICAM_FSI) { -+ /* -+ * Timestamp is to be when the first data byte was captured, -+ * aka frame start. -+ */ -+ if (unicam->cur_frm) -+ unicam->cur_frm->vb.vb2_buf.timestamp = ktime_get_ns(); -+ } -+ if (ista & UNICAM_FEI || sta & UNICAM_PI0) { -+ /* -+ * Ensure we have swapped buffers already as we can't -+ * stop the peripheral. Overwrite the frame we've just -+ * captured instead. -+ */ -+ if (unicam->cur_frm && unicam->cur_frm != unicam->next_frm) -+ unicam_process_buffer_complete(unicam); -+ } -+ -+ /* Cannot swap buffer at frame end, there may be a race condition -+ * where the HW does not actually swap it if the new frame has -+ * already started. -+ */ -+ if (ista & (UNICAM_FSI | UNICAM_LCI) && !(ista & UNICAM_FEI)) { -+ spin_lock(&unicam->dma_queue_lock); -+ if (!list_empty(&dma_q->active) && -+ unicam->cur_frm == unicam->next_frm) -+ unicam_schedule_next_buffer(unicam); -+ spin_unlock(&unicam->dma_queue_lock); -+ } -+ -+ if (reg_read(&unicam->cfg, UNICAM_ICTL) & UNICAM_FCM) { -+ /* Switch out of trigger mode if selected */ -+ reg_write_field(&unicam->cfg, UNICAM_ICTL, 1, UNICAM_TFC); -+ reg_write_field(&unicam->cfg, UNICAM_ICTL, 0, UNICAM_FCM); -+ } -+ return IRQ_HANDLED; -+} -+ -+static int unicam_querycap(struct file *file, void *priv, -+ struct v4l2_capability *cap) -+{ -+ struct unicam_device *dev = video_drvdata(file); -+ -+ strlcpy(cap->driver, UNICAM_MODULE_NAME, sizeof(cap->driver)); -+ strlcpy(cap->card, UNICAM_MODULE_NAME, sizeof(cap->card)); -+ -+ snprintf(cap->bus_info, sizeof(cap->bus_info), -+ "platform:%s", dev->v4l2_dev.name); -+ -+ return 0; -+} -+ -+static int unicam_enum_fmt_vid_cap(struct file *file, void *priv, -+ struct v4l2_fmtdesc *f) -+{ -+ struct unicam_device *dev = video_drvdata(file); -+ struct v4l2_subdev_mbus_code_enum mbus_code; -+ const struct unicam_fmt *fmt = NULL; -+ int index = 0; -+ int ret = 0; -+ int i; -+ -+ for (i = 0; !ret && i < MAX_ENUM_MBUS_CODE; i++) { -+ memset(&mbus_code, 0, sizeof(mbus_code)); -+ mbus_code.index = i; -+ -+ ret = v4l2_subdev_call(dev->sensor, pad, enum_mbus_code, -+ NULL, &mbus_code); -+ if (ret < 0) { -+ unicam_dbg(2, dev, -+ "subdev->enum_mbus_code idx %d returned %d - index invalid\n", -+ i, ret); -+ return -EINVAL; -+ } -+ -+ fmt = find_format_by_code(mbus_code.code); -+ if (fmt) { -+ if (fmt->fourcc) { -+ if (index == f->index) { -+ f->pixelformat = fmt->fourcc; -+ break; -+ } -+ index++; -+ } -+ if (fmt->repacked_fourcc) { -+ if (index == f->index) { -+ f->pixelformat = fmt->repacked_fourcc; -+ break; -+ } -+ index++; -+ } -+ } -+ } -+ -+ return 0; -+} -+ -+static int unicam_g_fmt_vid_cap(struct file *file, void *priv, -+ struct v4l2_format *f) -+{ -+ struct unicam_device *dev = video_drvdata(file); -+ -+ *f = dev->v_fmt; -+ -+ return 0; -+} -+ -+static -+const struct unicam_fmt *get_first_supported_format(struct unicam_device *dev) -+{ -+ struct v4l2_subdev_mbus_code_enum mbus_code; -+ const struct unicam_fmt *fmt = NULL; -+ int ret; -+ int j; -+ -+ for (j = 0; ret != -EINVAL && ret != -ENOIOCTLCMD; ++j) { -+ memset(&mbus_code, 0, sizeof(mbus_code)); -+ mbus_code.index = j; -+ ret = v4l2_subdev_call(dev->sensor, pad, enum_mbus_code, NULL, -+ &mbus_code); -+ if (ret < 0) { -+ unicam_dbg(2, dev, -+ "subdev->enum_mbus_code idx %d returned %d - continue\n", -+ j, ret); -+ continue; -+ } -+ -+ unicam_dbg(2, dev, "subdev %s: code: 0x%08x idx: %d\n", -+ dev->sensor->name, mbus_code.code, j); -+ -+ fmt = find_format_by_code(mbus_code.code); -+ unicam_dbg(2, dev, "fmt 0x%08x returned as %p, V4L2 FOURCC 0x%08x, csi_dt 0x%02x\n", -+ mbus_code.code, fmt, fmt ? fmt->fourcc : 0, -+ fmt ? fmt->csi_dt : 0); -+ if (fmt) -+ return fmt; -+ } -+ -+ return NULL; -+} -+ -+static int unicam_try_fmt_vid_cap(struct file *file, void *priv, -+ struct v4l2_format *f) -+{ -+ struct unicam_device *dev = video_drvdata(file); -+ struct v4l2_subdev_format sd_fmt = { -+ .which = V4L2_SUBDEV_FORMAT_TRY, -+ }; -+ struct v4l2_mbus_framefmt *mbus_fmt = &sd_fmt.format; -+ const struct unicam_fmt *fmt; -+ int ret; -+ -+ fmt = find_format_by_pix(dev, f->fmt.pix.pixelformat); -+ if (!fmt) { -+ /* Pixel format not supported by unicam. Choose the first -+ * supported format, and let the sensor choose something else. -+ */ -+ unicam_dbg(3, dev, "Fourcc format (0x%08x) not found. Use first format.\n", -+ f->fmt.pix.pixelformat); -+ -+ fmt = &formats[0]; -+ f->fmt.pix.pixelformat = fmt->fourcc; -+ } -+ -+ v4l2_fill_mbus_format(mbus_fmt, &f->fmt.pix, fmt->code); -+ /* -+ * No support for receiving interlaced video, so never -+ * request it from the sensor subdev. -+ */ -+ mbus_fmt->field = V4L2_FIELD_NONE; -+ -+ ret = v4l2_subdev_call(dev->sensor, pad, set_fmt, dev->sensor_config, -+ &sd_fmt); -+ if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) -+ return ret; -+ -+ if (mbus_fmt->field != V4L2_FIELD_NONE) -+ unicam_info(dev, "Sensor trying to send interlaced video - results may be unpredictable\n"); -+ -+ v4l2_fill_pix_format(&f->fmt.pix, &sd_fmt.format); -+ if (mbus_fmt->code != fmt->code) { -+ /* Sensor has returned an alternate format */ -+ fmt = find_format_by_code(mbus_fmt->code); -+ if (!fmt) { -+ /* The alternate format is one unicam can't support. -+ * Find the first format that is supported by both, and -+ * then set that. -+ */ -+ fmt = get_first_supported_format(dev); -+ mbus_fmt->code = fmt->code; -+ -+ ret = v4l2_subdev_call(dev->sensor, pad, set_fmt, -+ dev->sensor_config, &sd_fmt); -+ if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) -+ return ret; -+ -+ if (mbus_fmt->field != V4L2_FIELD_NONE) -+ unicam_info(dev, "Sensor trying to send interlaced video - results may be unpredictable\n"); -+ -+ v4l2_fill_pix_format(&f->fmt.pix, &sd_fmt.format); -+ -+ if (mbus_fmt->code != fmt->code) { -+ /* We've set a format that the sensor reports -+ * as being supported, but it refuses to set it. -+ * Not much else we can do. -+ * Assume that the sensor driver may accept the -+ * format when it is set (rather than tried). -+ */ -+ unicam_err(dev, "Sensor won't accept default format, and Unicam can't support sensor default\n"); -+ } -+ } -+ -+ if (fmt->fourcc) -+ f->fmt.pix.pixelformat = fmt->fourcc; -+ else -+ f->fmt.pix.pixelformat = fmt->repacked_fourcc; -+ } -+ -+ return unicam_calc_format_size_bpl(dev, fmt, f); -+} -+ -+static int unicam_s_fmt_vid_cap(struct file *file, void *priv, -+ struct v4l2_format *f) -+{ -+ struct unicam_device *dev = video_drvdata(file); -+ struct vb2_queue *q = &dev->buffer_queue; -+ struct v4l2_mbus_framefmt mbus_fmt = {0}; -+ const struct unicam_fmt *fmt; -+ int ret; -+ -+ if (vb2_is_busy(q)) -+ return -EBUSY; -+ -+ ret = unicam_try_fmt_vid_cap(file, priv, f); -+ if (ret < 0) -+ return ret; -+ -+ fmt = find_format_by_pix(dev, f->fmt.pix.pixelformat); -+ if (!fmt) { -+ /* Unknown pixel format - adopt a default. -+ * This shouldn't happen as try_fmt should have resolved any -+ * issues first. -+ */ -+ fmt = get_first_supported_format(dev); -+ if (!fmt) -+ /* It shouldn't be possible to get here with no -+ * supported formats -+ */ -+ return -EINVAL; -+ f->fmt.pix.pixelformat = fmt->fourcc; -+ return -EINVAL; -+ } -+ -+ v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, fmt->code); -+ -+ ret = __subdev_set_format(dev, &mbus_fmt); -+ if (ret) { -+ unicam_dbg(3, dev, "%s __subdev_set_format failed %d\n", -+ __func__, ret); -+ return ret; -+ } -+ -+ /* Just double check nothing has gone wrong */ -+ if (mbus_fmt.code != fmt->code) { -+ unicam_dbg(3, dev, -+ "%s subdev changed format on us, this should not happen\n", -+ __func__); -+ return -EINVAL; -+ } -+ -+ dev->fmt = fmt; -+ dev->v_fmt.fmt.pix.pixelformat = f->fmt.pix.pixelformat; -+ dev->v_fmt.fmt.pix.bytesperline = f->fmt.pix.bytesperline; -+ unicam_reset_format(dev); -+ -+ unicam_dbg(3, dev, "%s %dx%d, mbus_fmt 0x%08X, V4L2 pix 0x%08X.\n", -+ __func__, dev->v_fmt.fmt.pix.width, -+ dev->v_fmt.fmt.pix.height, mbus_fmt.code, -+ dev->v_fmt.fmt.pix.pixelformat); -+ -+ *f = dev->v_fmt; -+ -+ return 0; -+} -+ -+static int unicam_queue_setup(struct vb2_queue *vq, -+ unsigned int *nbuffers, -+ unsigned int *nplanes, -+ unsigned int sizes[], -+ struct device *alloc_devs[]) -+{ -+ struct unicam_device *dev = vb2_get_drv_priv(vq); -+ unsigned int size = dev->v_fmt.fmt.pix.sizeimage; -+ -+ if (vq->num_buffers + *nbuffers < 3) -+ *nbuffers = 3 - vq->num_buffers; -+ -+ if (*nplanes) { -+ if (sizes[0] < size) { -+ unicam_err(dev, "sizes[0] %i < size %u\n", sizes[0], -+ size); -+ return -EINVAL; -+ } -+ size = sizes[0]; -+ } -+ -+ *nplanes = 1; -+ sizes[0] = size; -+ -+ return 0; -+} -+ -+static int unicam_buffer_prepare(struct vb2_buffer *vb) -+{ -+ struct unicam_device *dev = vb2_get_drv_priv(vb->vb2_queue); -+ struct unicam_buffer *buf = container_of(vb, struct unicam_buffer, -+ vb.vb2_buf); -+ unsigned long size; -+ -+ if (WARN_ON(!dev->fmt)) -+ return -EINVAL; -+ -+ size = dev->v_fmt.fmt.pix.sizeimage; -+ if (vb2_plane_size(vb, 0) < size) { -+ unicam_err(dev, "data will not fit into plane (%lu < %lu)\n", -+ vb2_plane_size(vb, 0), size); -+ return -EINVAL; -+ } -+ -+ vb2_set_plane_payload(&buf->vb.vb2_buf, 0, size); -+ return 0; -+} -+ -+static void unicam_buffer_queue(struct vb2_buffer *vb) -+{ -+ struct unicam_device *dev = vb2_get_drv_priv(vb->vb2_queue); -+ struct unicam_buffer *buf = container_of(vb, struct unicam_buffer, -+ vb.vb2_buf); -+ struct unicam_dmaqueue *dma_queue = &dev->dma_queue; -+ unsigned long flags = 0; -+ -+ spin_lock_irqsave(&dev->dma_queue_lock, flags); -+ list_add_tail(&buf->list, &dma_queue->active); -+ spin_unlock_irqrestore(&dev->dma_queue_lock, flags); -+} -+ -+static void unicam_set_packing_config(struct unicam_device *dev) -+{ -+ int pack, unpack; -+ u32 val; -+ -+ if (dev->v_fmt.fmt.pix.pixelformat == dev->fmt->fourcc) { -+ unpack = UNICAM_PUM_NONE; -+ pack = UNICAM_PPM_NONE; -+ } else { -+ switch (dev->fmt->depth) { -+ case 8: -+ unpack = UNICAM_PUM_UNPACK8; -+ break; -+ case 10: -+ unpack = UNICAM_PUM_UNPACK10; -+ break; -+ case 12: -+ unpack = UNICAM_PUM_UNPACK12; -+ break; -+ case 14: -+ unpack = UNICAM_PUM_UNPACK14; -+ break; -+ case 16: -+ unpack = UNICAM_PUM_UNPACK16; -+ break; -+ default: -+ unpack = UNICAM_PUM_NONE; -+ break; -+ } -+ -+ /* Repacking is always to 16bpp */ -+ pack = UNICAM_PPM_PACK16; -+ } -+ -+ val = 0; -+ set_field(&val, unpack, UNICAM_PUM_MASK); -+ set_field(&val, pack, UNICAM_PPM_MASK); -+ reg_write(&dev->cfg, UNICAM_IPIPE, val); -+} -+ -+static void unicam_cfg_image_id(struct unicam_device *dev) -+{ -+ struct unicam_cfg *cfg = &dev->cfg; -+ -+ if (dev->bus_type == V4L2_MBUS_CSI2_DPHY) { -+ /* CSI2 mode */ -+ reg_write(cfg, UNICAM_IDI0, -+ (dev->virtual_channel << 6) | dev->fmt->csi_dt); -+ } else { -+ /* CCP2 mode */ -+ reg_write(cfg, UNICAM_IDI0, (0x80 | dev->fmt->csi_dt)); -+ } -+} -+ -+static void unicam_start_rx(struct unicam_device *dev, unsigned long addr) -+{ -+ struct unicam_cfg *cfg = &dev->cfg; -+ int line_int_freq = dev->v_fmt.fmt.pix.height >> 2; -+ unsigned int i; -+ u32 val; -+ -+ if (line_int_freq < 128) -+ line_int_freq = 128; -+ -+ /* Enable lane clocks */ -+ val = 1; -+ for (i = 0; i < dev->active_data_lanes; i++) -+ val = val << 2 | 1; -+ clk_write(cfg, val); -+ -+ /* Basic init */ -+ reg_write(cfg, UNICAM_CTRL, UNICAM_MEM); -+ -+ /* Enable analogue control, and leave in reset. */ -+ val = UNICAM_AR; -+ set_field(&val, 7, UNICAM_CTATADJ_MASK); -+ set_field(&val, 7, UNICAM_PTATADJ_MASK); -+ reg_write(cfg, UNICAM_ANA, val); -+ usleep_range(1000, 2000); -+ -+ /* Come out of reset */ -+ reg_write_field(cfg, UNICAM_ANA, 0, UNICAM_AR); -+ -+ /* Peripheral reset */ -+ reg_write_field(cfg, UNICAM_CTRL, 1, UNICAM_CPR); -+ reg_write_field(cfg, UNICAM_CTRL, 0, UNICAM_CPR); -+ -+ reg_write_field(cfg, UNICAM_CTRL, 0, UNICAM_CPE); -+ -+ /* Enable Rx control. */ -+ val = reg_read(cfg, UNICAM_CTRL); -+ if (dev->bus_type == V4L2_MBUS_CSI2_DPHY) { -+ set_field(&val, UNICAM_CPM_CSI2, UNICAM_CPM_MASK); -+ set_field(&val, UNICAM_DCM_STROBE, UNICAM_DCM_MASK); -+ } else { -+ set_field(&val, UNICAM_CPM_CCP2, UNICAM_CPM_MASK); -+ set_field(&val, dev->bus_flags, UNICAM_DCM_MASK); -+ } -+ /* Packet framer timeout */ -+ set_field(&val, 0xf, UNICAM_PFT_MASK); -+ set_field(&val, 128, UNICAM_OET_MASK); -+ reg_write(cfg, UNICAM_CTRL, val); -+ -+ reg_write(cfg, UNICAM_IHWIN, 0); -+ reg_write(cfg, UNICAM_IVWIN, 0); -+ -+ /* AXI bus access QoS setup */ -+ val = reg_read(&dev->cfg, UNICAM_PRI); -+ set_field(&val, 0, UNICAM_BL_MASK); -+ set_field(&val, 0, UNICAM_BS_MASK); -+ set_field(&val, 0xe, UNICAM_PP_MASK); -+ set_field(&val, 8, UNICAM_NP_MASK); -+ set_field(&val, 2, UNICAM_PT_MASK); -+ set_field(&val, 1, UNICAM_PE); -+ reg_write(cfg, UNICAM_PRI, val); -+ -+ reg_write_field(cfg, UNICAM_ANA, 0, UNICAM_DDL); -+ -+ /* Always start in trigger frame capture mode (UNICAM_FCM set) */ -+ val = UNICAM_FSIE | UNICAM_FEIE | UNICAM_FCM; -+ set_field(&val, line_int_freq, UNICAM_LCIE_MASK); -+ reg_write(cfg, UNICAM_ICTL, val); -+ reg_write(cfg, UNICAM_STA, UNICAM_STA_MASK_ALL); -+ reg_write(cfg, UNICAM_ISTA, UNICAM_ISTA_MASK_ALL); -+ -+ /* tclk_term_en */ -+ reg_write_field(cfg, UNICAM_CLT, 2, UNICAM_CLT1_MASK); -+ /* tclk_settle */ -+ reg_write_field(cfg, UNICAM_CLT, 6, UNICAM_CLT2_MASK); -+ /* td_term_en */ -+ reg_write_field(cfg, UNICAM_DLT, 2, UNICAM_DLT1_MASK); -+ /* ths_settle */ -+ reg_write_field(cfg, UNICAM_DLT, 6, UNICAM_DLT2_MASK); -+ /* trx_enable */ -+ reg_write_field(cfg, UNICAM_DLT, 0, UNICAM_DLT3_MASK); -+ -+ reg_write_field(cfg, UNICAM_CTRL, 0, UNICAM_SOE); -+ -+ /* Packet compare setup - required to avoid missing frame ends */ -+ val = 0; -+ set_field(&val, 1, UNICAM_PCE); -+ set_field(&val, 1, UNICAM_GI); -+ set_field(&val, 1, UNICAM_CPH); -+ set_field(&val, 0, UNICAM_PCVC_MASK); -+ set_field(&val, 1, UNICAM_PCDT_MASK); -+ reg_write(cfg, UNICAM_CMP0, val); -+ -+ /* Enable clock lane and set up terminations */ -+ val = 0; -+ if (dev->bus_type == V4L2_MBUS_CSI2_DPHY) { -+ /* CSI2 */ -+ set_field(&val, 1, UNICAM_CLE); -+ set_field(&val, 1, UNICAM_CLLPE); -+ if (dev->bus_flags & V4L2_MBUS_CSI2_CONTINUOUS_CLOCK) { -+ set_field(&val, 1, UNICAM_CLTRE); -+ set_field(&val, 1, UNICAM_CLHSE); -+ } -+ } else { -+ /* CCP2 */ -+ set_field(&val, 1, UNICAM_CLE); -+ set_field(&val, 1, UNICAM_CLHSE); -+ set_field(&val, 1, UNICAM_CLTRE); -+ } -+ reg_write(cfg, UNICAM_CLK, val); -+ -+ /* -+ * Enable required data lanes with appropriate terminations. -+ * The same value needs to be written to UNICAM_DATn registers for -+ * the active lanes, and 0 for inactive ones. -+ */ -+ val = 0; -+ if (dev->bus_type == V4L2_MBUS_CSI2_DPHY) { -+ /* CSI2 */ -+ set_field(&val, 1, UNICAM_DLE); -+ set_field(&val, 1, UNICAM_DLLPE); -+ if (dev->bus_flags & V4L2_MBUS_CSI2_CONTINUOUS_CLOCK) { -+ set_field(&val, 1, UNICAM_DLTRE); -+ set_field(&val, 1, UNICAM_DLHSE); -+ } -+ } else { -+ /* CCP2 */ -+ set_field(&val, 1, UNICAM_DLE); -+ set_field(&val, 1, UNICAM_DLHSE); -+ set_field(&val, 1, UNICAM_DLTRE); -+ } -+ reg_write(cfg, UNICAM_DAT0, val); -+ -+ if (dev->active_data_lanes == 1) -+ val = 0; -+ reg_write(cfg, UNICAM_DAT1, val); -+ -+ if (dev->max_data_lanes > 2) { -+ /* -+ * Registers UNICAM_DAT2 and UNICAM_DAT3 only valid if the -+ * instance supports more than 2 data lanes. -+ */ -+ if (dev->active_data_lanes == 2) -+ val = 0; -+ reg_write(cfg, UNICAM_DAT2, val); -+ -+ if (dev->active_data_lanes == 3) -+ val = 0; -+ reg_write(cfg, UNICAM_DAT3, val); -+ } -+ -+ reg_write(&dev->cfg, UNICAM_IBLS, dev->v_fmt.fmt.pix.bytesperline); -+ unicam_wr_dma_addr(dev, addr); -+ unicam_set_packing_config(dev); -+ unicam_cfg_image_id(dev); -+ -+ /* Disabled embedded data */ -+ val = 0; -+ set_field(&val, 0, UNICAM_EDL_MASK); -+ reg_write(cfg, UNICAM_DCS, val); -+ -+ val = reg_read(cfg, UNICAM_MISC); -+ set_field(&val, 1, UNICAM_FL0); -+ set_field(&val, 1, UNICAM_FL1); -+ reg_write(cfg, UNICAM_MISC, val); -+ -+ /* Enable peripheral */ -+ reg_write_field(cfg, UNICAM_CTRL, 1, UNICAM_CPE); -+ -+ /* Load image pointers */ -+ reg_write_field(cfg, UNICAM_ICTL, 1, UNICAM_LIP_MASK); -+ -+ /* -+ * Enable trigger only for the first frame to -+ * sync correctly to the FS from the source. -+ */ -+ reg_write_field(cfg, UNICAM_ICTL, 1, UNICAM_TFC); -+} -+ -+static void unicam_disable(struct unicam_device *dev) -+{ -+ struct unicam_cfg *cfg = &dev->cfg; -+ -+ /* Analogue lane control disable */ -+ reg_write_field(cfg, UNICAM_ANA, 1, UNICAM_DDL); -+ -+ /* Stop the output engine */ -+ reg_write_field(cfg, UNICAM_CTRL, 1, UNICAM_SOE); -+ -+ /* Disable the data lanes. */ -+ reg_write(cfg, UNICAM_DAT0, 0); -+ reg_write(cfg, UNICAM_DAT1, 0); -+ -+ if (dev->max_data_lanes > 2) { -+ reg_write(cfg, UNICAM_DAT2, 0); -+ reg_write(cfg, UNICAM_DAT3, 0); -+ } -+ -+ /* Peripheral reset */ -+ reg_write_field(cfg, UNICAM_CTRL, 1, UNICAM_CPR); -+ usleep_range(50, 100); -+ reg_write_field(cfg, UNICAM_CTRL, 0, UNICAM_CPR); -+ -+ /* Disable peripheral */ -+ reg_write_field(cfg, UNICAM_CTRL, 0, UNICAM_CPE); -+ -+ /* Disable all lane clocks */ -+ clk_write(cfg, 0); -+} -+ -+static int unicam_start_streaming(struct vb2_queue *vq, unsigned int count) -+{ -+ struct unicam_device *dev = vb2_get_drv_priv(vq); -+ struct unicam_dmaqueue *dma_q = &dev->dma_queue; -+ struct unicam_buffer *buf, *tmp; -+ unsigned long addr = 0; -+ unsigned long flags; -+ int ret; -+ -+ spin_lock_irqsave(&dev->dma_queue_lock, flags); -+ buf = list_entry(dma_q->active.next, struct unicam_buffer, list); -+ dev->cur_frm = buf; -+ dev->next_frm = buf; -+ list_del(&buf->list); -+ spin_unlock_irqrestore(&dev->dma_queue_lock, flags); -+ -+ addr = vb2_dma_contig_plane_dma_addr(&dev->cur_frm->vb.vb2_buf, 0); -+ dev->sequence = 0; -+ -+ ret = unicam_runtime_get(dev); -+ if (ret < 0) { -+ unicam_dbg(3, dev, "unicam_runtime_get failed\n"); -+ goto err_release_buffers; -+ } -+ -+ dev->active_data_lanes = dev->max_data_lanes; -+ if (dev->bus_type == V4L2_MBUS_CSI2_DPHY && -+ v4l2_subdev_has_op(dev->sensor, video, g_mbus_config)) { -+ struct v4l2_mbus_config mbus_config; -+ -+ ret = v4l2_subdev_call(dev->sensor, video, g_mbus_config, -+ &mbus_config); -+ if (ret < 0) { -+ unicam_dbg(3, dev, "g_mbus_config failed\n"); -+ goto err_pm_put; -+ } -+ -+ dev->active_data_lanes = -+ (mbus_config.flags & V4L2_MBUS_CSI2_LANE_MASK) >> -+ __ffs(V4L2_MBUS_CSI2_LANE_MASK); -+ if (!dev->active_data_lanes) -+ dev->active_data_lanes = dev->max_data_lanes; -+ } -+ if (dev->active_data_lanes > dev->max_data_lanes) { -+ unicam_err(dev, "Device has requested %u data lanes, which is >%u configured in DT\n", -+ dev->active_data_lanes, dev->max_data_lanes); -+ ret = -EINVAL; -+ goto err_pm_put; -+ } -+ -+ unicam_dbg(1, dev, "Running with %u data lanes\n", -+ dev->active_data_lanes); -+ -+ ret = clk_set_rate(dev->clock, 100 * 1000 * 1000); -+ if (ret) { -+ unicam_err(dev, "failed to set up clock\n"); -+ goto err_pm_put; -+ } -+ -+ ret = clk_prepare_enable(dev->clock); -+ if (ret) { -+ unicam_err(dev, "Failed to enable CSI clock: %d\n", ret); -+ goto err_pm_put; -+ } -+ dev->streaming = 1; -+ -+ unicam_start_rx(dev, addr); -+ -+ ret = v4l2_subdev_call(dev->sensor, video, s_stream, 1); -+ if (ret < 0) { -+ unicam_err(dev, "stream on failed in subdev\n"); -+ goto err_disable_unicam; -+ } -+ -+ return 0; -+ -+err_disable_unicam: -+ unicam_disable(dev); -+ clk_disable_unprepare(dev->clock); -+err_pm_put: -+ unicam_runtime_put(dev); -+err_release_buffers: -+ list_for_each_entry_safe(buf, tmp, &dma_q->active, list) { -+ list_del(&buf->list); -+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_QUEUED); -+ } -+ if (dev->cur_frm != dev->next_frm) -+ vb2_buffer_done(&dev->next_frm->vb.vb2_buf, -+ VB2_BUF_STATE_QUEUED); -+ vb2_buffer_done(&dev->cur_frm->vb.vb2_buf, VB2_BUF_STATE_QUEUED); -+ dev->next_frm = NULL; -+ dev->cur_frm = NULL; -+ -+ return ret; -+} -+ -+static void unicam_stop_streaming(struct vb2_queue *vq) -+{ -+ struct unicam_device *dev = vb2_get_drv_priv(vq); -+ struct unicam_dmaqueue *dma_q = &dev->dma_queue; -+ struct unicam_buffer *buf, *tmp; -+ unsigned long flags; -+ -+ if (v4l2_subdev_call(dev->sensor, video, s_stream, 0) < 0) -+ unicam_err(dev, "stream off failed in subdev\n"); -+ -+ unicam_disable(dev); -+ -+ /* Release all active buffers */ -+ spin_lock_irqsave(&dev->dma_queue_lock, flags); -+ list_for_each_entry_safe(buf, tmp, &dma_q->active, list) { -+ list_del(&buf->list); -+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); -+ } -+ -+ if (dev->cur_frm == dev->next_frm) { -+ vb2_buffer_done(&dev->cur_frm->vb.vb2_buf, VB2_BUF_STATE_ERROR); -+ } else { -+ vb2_buffer_done(&dev->cur_frm->vb.vb2_buf, VB2_BUF_STATE_ERROR); -+ vb2_buffer_done(&dev->next_frm->vb.vb2_buf, -+ VB2_BUF_STATE_ERROR); -+ } -+ dev->cur_frm = NULL; -+ dev->next_frm = NULL; -+ spin_unlock_irqrestore(&dev->dma_queue_lock, flags); -+ -+ clk_disable_unprepare(dev->clock); -+ unicam_runtime_put(dev); -+} -+ -+static int unicam_enum_input(struct file *file, void *priv, -+ struct v4l2_input *inp) -+{ -+ struct unicam_device *dev = video_drvdata(file); -+ -+ if (inp->index != 0) -+ return -EINVAL; -+ -+ inp->type = V4L2_INPUT_TYPE_CAMERA; -+ if (v4l2_subdev_has_op(dev->sensor, video, s_dv_timings)) { -+ inp->capabilities = V4L2_IN_CAP_DV_TIMINGS; -+ inp->std = 0; -+ } else if (v4l2_subdev_has_op(dev->sensor, video, s_std)) { -+ inp->capabilities = V4L2_IN_CAP_STD; -+ if (v4l2_subdev_call(dev->sensor, video, g_tvnorms, &inp->std) -+ < 0) -+ inp->std = V4L2_STD_ALL; -+ } else { -+ inp->capabilities = 0; -+ inp->std = 0; -+ } -+ sprintf(inp->name, "Camera 0"); -+ return 0; -+} -+ -+static int unicam_g_input(struct file *file, void *priv, unsigned int *i) -+{ -+ *i = 0; -+ -+ return 0; -+} -+ -+static int unicam_s_input(struct file *file, void *priv, unsigned int i) -+{ -+ /* -+ * FIXME: Ideally we would like to be able to query the source -+ * subdevice for information over the input connectors it supports, -+ * and map that through in to a call to video_ops->s_routing. -+ * There is no infrastructure support for defining that within -+ * devicetree at present. Until that is implemented we can't -+ * map a user physical connector number to s_routing input number. -+ */ -+ if (i > 0) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+static int unicam_querystd(struct file *file, void *priv, -+ v4l2_std_id *std) -+{ -+ struct unicam_device *dev = video_drvdata(file); -+ -+ return v4l2_subdev_call(dev->sensor, video, querystd, std); -+} -+ -+static int unicam_g_std(struct file *file, void *priv, v4l2_std_id *std) -+{ -+ struct unicam_device *dev = video_drvdata(file); -+ -+ return v4l2_subdev_call(dev->sensor, video, g_std, std); -+} -+ -+static int unicam_s_std(struct file *file, void *priv, v4l2_std_id std) -+{ -+ struct unicam_device *dev = video_drvdata(file); -+ int ret; -+ v4l2_std_id current_std; -+ -+ ret = v4l2_subdev_call(dev->sensor, video, g_std, ¤t_std); -+ if (ret) -+ return ret; -+ -+ if (std == current_std) -+ return 0; -+ -+ if (vb2_is_busy(&dev->buffer_queue)) -+ return -EBUSY; -+ -+ ret = v4l2_subdev_call(dev->sensor, video, s_std, std); -+ -+ /* Force recomputation of bytesperline */ -+ dev->v_fmt.fmt.pix.bytesperline = 0; -+ -+ unicam_reset_format(dev); -+ -+ return ret; -+} -+ -+static int unicam_s_edid(struct file *file, void *priv, struct v4l2_edid *edid) -+{ -+ struct unicam_device *dev = video_drvdata(file); -+ -+ return v4l2_subdev_call(dev->sensor, pad, set_edid, edid); -+} -+ -+static int unicam_g_edid(struct file *file, void *priv, struct v4l2_edid *edid) -+{ -+ struct unicam_device *dev = video_drvdata(file); -+ -+ return v4l2_subdev_call(dev->sensor, pad, get_edid, edid); -+} -+ -+static int unicam_enum_framesizes(struct file *file, void *priv, -+ struct v4l2_frmsizeenum *fsize) -+{ -+ struct unicam_device *dev = video_drvdata(file); -+ const struct unicam_fmt *fmt; -+ struct v4l2_subdev_frame_size_enum fse; -+ int ret; -+ -+ /* check for valid format */ -+ fmt = find_format_by_pix(dev, fsize->pixel_format); -+ if (!fmt) { -+ unicam_dbg(3, dev, "Invalid pixel code: %x\n", -+ fsize->pixel_format); -+ return -EINVAL; -+ } -+ -+ fse.index = fsize->index; -+ fse.pad = 0; -+ fse.code = fmt->code; -+ -+ ret = v4l2_subdev_call(dev->sensor, pad, enum_frame_size, NULL, &fse); -+ if (ret) -+ return ret; -+ -+ unicam_dbg(1, dev, "%s: index: %d code: %x W:[%d,%d] H:[%d,%d]\n", -+ __func__, fse.index, fse.code, fse.min_width, fse.max_width, -+ fse.min_height, fse.max_height); -+ -+ fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; -+ fsize->discrete.width = fse.max_width; -+ fsize->discrete.height = fse.max_height; -+ -+ return 0; -+} -+ -+static int unicam_enum_frameintervals(struct file *file, void *priv, -+ struct v4l2_frmivalenum *fival) -+{ -+ struct unicam_device *dev = video_drvdata(file); -+ const struct unicam_fmt *fmt; -+ struct v4l2_subdev_frame_interval_enum fie = { -+ .index = fival->index, -+ .width = fival->width, -+ .height = fival->height, -+ .which = V4L2_SUBDEV_FORMAT_ACTIVE, -+ }; -+ int ret; -+ -+ fmt = find_format_by_pix(dev, fival->pixel_format); -+ if (!fmt) -+ return -EINVAL; -+ -+ fie.code = fmt->code; -+ ret = v4l2_subdev_call(dev->sensor, pad, enum_frame_interval, -+ NULL, &fie); -+ if (ret) -+ return ret; -+ -+ fival->type = V4L2_FRMIVAL_TYPE_DISCRETE; -+ fival->discrete = fie.interval; -+ -+ return 0; -+} -+ -+static int unicam_g_parm(struct file *file, void *fh, struct v4l2_streamparm *a) -+{ -+ struct unicam_device *dev = video_drvdata(file); -+ -+ return v4l2_g_parm_cap(video_devdata(file), dev->sensor, a); -+} -+ -+static int unicam_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a) -+{ -+ struct unicam_device *dev = video_drvdata(file); -+ -+ return v4l2_s_parm_cap(video_devdata(file), dev->sensor, a); -+} -+ -+static int unicam_g_dv_timings(struct file *file, void *priv, -+ struct v4l2_dv_timings *timings) -+{ -+ struct unicam_device *dev = video_drvdata(file); -+ -+ return v4l2_subdev_call(dev->sensor, video, g_dv_timings, timings); -+} -+ -+static int unicam_s_dv_timings(struct file *file, void *priv, -+ struct v4l2_dv_timings *timings) -+{ -+ struct unicam_device *dev = video_drvdata(file); -+ struct v4l2_dv_timings current_timings; -+ int ret; -+ -+ ret = v4l2_subdev_call(dev->sensor, video, g_dv_timings, -+ ¤t_timings); -+ -+ if (v4l2_match_dv_timings(timings, ¤t_timings, 0, false)) -+ return 0; -+ -+ if (vb2_is_busy(&dev->buffer_queue)) -+ return -EBUSY; -+ -+ ret = v4l2_subdev_call(dev->sensor, video, s_dv_timings, timings); -+ -+ /* Force recomputation of bytesperline */ -+ dev->v_fmt.fmt.pix.bytesperline = 0; -+ -+ unicam_reset_format(dev); -+ -+ return ret; -+} -+ -+static int unicam_query_dv_timings(struct file *file, void *priv, -+ struct v4l2_dv_timings *timings) -+{ -+ struct unicam_device *dev = video_drvdata(file); -+ -+ return v4l2_subdev_call(dev->sensor, video, query_dv_timings, timings); -+} -+ -+static int unicam_enum_dv_timings(struct file *file, void *priv, -+ struct v4l2_enum_dv_timings *timings) -+{ -+ struct unicam_device *dev = video_drvdata(file); -+ -+ return v4l2_subdev_call(dev->sensor, pad, enum_dv_timings, timings); -+} -+ -+static int unicam_dv_timings_cap(struct file *file, void *priv, -+ struct v4l2_dv_timings_cap *cap) -+{ -+ struct unicam_device *dev = video_drvdata(file); -+ -+ return v4l2_subdev_call(dev->sensor, pad, dv_timings_cap, cap); -+} -+ -+static int unicam_subscribe_event(struct v4l2_fh *fh, -+ const struct v4l2_event_subscription *sub) -+{ -+ switch (sub->type) { -+ case V4L2_EVENT_SOURCE_CHANGE: -+ return v4l2_event_subscribe(fh, sub, 4, NULL); -+ } -+ -+ return v4l2_ctrl_subscribe_event(fh, sub); -+} -+ -+static int unicam_log_status(struct file *file, void *fh) -+{ -+ struct unicam_device *dev = video_drvdata(file); -+ struct unicam_cfg *cfg = &dev->cfg; -+ u32 reg; -+ -+ /* status for sub devices */ -+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, log_status); -+ -+ unicam_info(dev, "-----Receiver status-----\n"); -+ unicam_info(dev, "V4L2 width/height: %ux%u\n", -+ dev->v_fmt.fmt.pix.width, dev->v_fmt.fmt.pix.height); -+ unicam_info(dev, "Mediabus format: %08x\n", dev->fmt->code); -+ unicam_info(dev, "V4L2 format: %08x\n", -+ dev->v_fmt.fmt.pix.pixelformat); -+ reg = reg_read(&dev->cfg, UNICAM_IPIPE); -+ unicam_info(dev, "Unpacking/packing: %u / %u\n", -+ get_field(reg, UNICAM_PUM_MASK), -+ get_field(reg, UNICAM_PPM_MASK)); -+ unicam_info(dev, "----Live data----\n"); -+ unicam_info(dev, "Programmed stride: %4u\n", -+ reg_read(cfg, UNICAM_IBLS)); -+ unicam_info(dev, "Detected resolution: %ux%u\n", -+ reg_read(cfg, UNICAM_IHSTA), -+ reg_read(cfg, UNICAM_IVSTA)); -+ unicam_info(dev, "Write pointer: %08x\n", -+ reg_read(cfg, UNICAM_IBWP)); -+ -+ return 0; -+} -+ -+static void unicam_notify(struct v4l2_subdev *sd, -+ unsigned int notification, void *arg) -+{ -+ struct unicam_device *dev = -+ container_of(sd->v4l2_dev, struct unicam_device, v4l2_dev); -+ -+ switch (notification) { -+ case V4L2_DEVICE_NOTIFY_EVENT: -+ v4l2_event_queue(&dev->video_dev, arg); -+ break; -+ default: -+ break; -+ } -+} -+ -+static const struct vb2_ops unicam_video_qops = { -+ .wait_prepare = vb2_ops_wait_prepare, -+ .wait_finish = vb2_ops_wait_finish, -+ .queue_setup = unicam_queue_setup, -+ .buf_prepare = unicam_buffer_prepare, -+ .buf_queue = unicam_buffer_queue, -+ .start_streaming = unicam_start_streaming, -+ .stop_streaming = unicam_stop_streaming, -+}; -+ -+/* -+ * unicam_open : This function is based on the v4l2_fh_open helper function. -+ * It has been augmented to handle sensor subdevice power management, -+ */ -+static int unicam_open(struct file *file) -+{ -+ struct unicam_device *dev = video_drvdata(file); -+ int ret; -+ -+ mutex_lock(&dev->lock); -+ -+ ret = v4l2_fh_open(file); -+ if (ret) { -+ unicam_err(dev, "v4l2_fh_open failed\n"); -+ goto unlock; -+ } -+ -+ if (!v4l2_fh_is_singular_file(file)) -+ goto unlock; -+ -+ ret = v4l2_subdev_call(dev->sensor, core, s_power, 1); -+ if (ret < 0 && ret != -ENOIOCTLCMD) { -+ v4l2_fh_release(file); -+ goto unlock; -+ } -+ -+ ret = 0; -+ -+unlock: -+ mutex_unlock(&dev->lock); -+ return ret; -+} -+ -+static int unicam_release(struct file *file) -+{ -+ struct unicam_device *dev = video_drvdata(file); -+ struct v4l2_subdev *sd = dev->sensor; -+ bool fh_singular; -+ int ret; -+ -+ mutex_lock(&dev->lock); -+ -+ fh_singular = v4l2_fh_is_singular_file(file); -+ -+ ret = _vb2_fop_release(file, NULL); -+ -+ if (fh_singular) -+ v4l2_subdev_call(sd, core, s_power, 0); -+ -+ mutex_unlock(&dev->lock); -+ -+ return ret; -+} -+ -+/* unicam capture driver file operations */ -+static const struct v4l2_file_operations unicam_fops = { -+ .owner = THIS_MODULE, -+ .open = unicam_open, -+ .release = unicam_release, -+ .read = vb2_fop_read, -+ .poll = vb2_fop_poll, -+ .unlocked_ioctl = video_ioctl2, -+ .mmap = vb2_fop_mmap, -+}; -+ -+/* unicam capture ioctl operations */ -+static const struct v4l2_ioctl_ops unicam_ioctl_ops = { -+ .vidioc_querycap = unicam_querycap, -+ .vidioc_enum_fmt_vid_cap = unicam_enum_fmt_vid_cap, -+ .vidioc_g_fmt_vid_cap = unicam_g_fmt_vid_cap, -+ .vidioc_s_fmt_vid_cap = unicam_s_fmt_vid_cap, -+ .vidioc_try_fmt_vid_cap = unicam_try_fmt_vid_cap, -+ -+ .vidioc_enum_input = unicam_enum_input, -+ .vidioc_g_input = unicam_g_input, -+ .vidioc_s_input = unicam_s_input, -+ -+ .vidioc_querystd = unicam_querystd, -+ .vidioc_s_std = unicam_s_std, -+ .vidioc_g_std = unicam_g_std, -+ -+ .vidioc_g_edid = unicam_g_edid, -+ .vidioc_s_edid = unicam_s_edid, -+ -+ .vidioc_enum_framesizes = unicam_enum_framesizes, -+ .vidioc_enum_frameintervals = unicam_enum_frameintervals, -+ -+ .vidioc_g_parm = unicam_g_parm, -+ .vidioc_s_parm = unicam_s_parm, -+ -+ .vidioc_s_dv_timings = unicam_s_dv_timings, -+ .vidioc_g_dv_timings = unicam_g_dv_timings, -+ .vidioc_query_dv_timings = unicam_query_dv_timings, -+ .vidioc_enum_dv_timings = unicam_enum_dv_timings, -+ .vidioc_dv_timings_cap = unicam_dv_timings_cap, -+ -+ .vidioc_reqbufs = vb2_ioctl_reqbufs, -+ .vidioc_create_bufs = vb2_ioctl_create_bufs, -+ .vidioc_prepare_buf = vb2_ioctl_prepare_buf, -+ .vidioc_querybuf = vb2_ioctl_querybuf, -+ .vidioc_qbuf = vb2_ioctl_qbuf, -+ .vidioc_dqbuf = vb2_ioctl_dqbuf, -+ .vidioc_expbuf = vb2_ioctl_expbuf, -+ .vidioc_streamon = vb2_ioctl_streamon, -+ .vidioc_streamoff = vb2_ioctl_streamoff, -+ -+ .vidioc_log_status = unicam_log_status, -+ .vidioc_subscribe_event = unicam_subscribe_event, -+ .vidioc_unsubscribe_event = v4l2_event_unsubscribe, -+}; -+ -+static int -+unicam_async_bound(struct v4l2_async_notifier *notifier, -+ struct v4l2_subdev *subdev, -+ struct v4l2_async_subdev *asd) -+{ -+ struct unicam_device *unicam = container_of(notifier->v4l2_dev, -+ struct unicam_device, v4l2_dev); -+ -+ if (unicam->sensor) { -+ unicam_info(unicam, "Rejecting subdev %s (Already set!!)", -+ subdev->name); -+ return 0; -+ } -+ -+ unicam->sensor = subdev; -+ unicam_dbg(1, unicam, "Using sensor %s for capture\n", subdev->name); -+ -+ return 0; -+} -+ -+static int unicam_probe_complete(struct unicam_device *unicam) -+{ -+ struct video_device *vdev; -+ struct vb2_queue *q; -+ struct v4l2_mbus_framefmt mbus_fmt = {0}; -+ const struct unicam_fmt *fmt; -+ int ret; -+ -+ v4l2_set_subdev_hostdata(unicam->sensor, unicam); -+ -+ unicam->v4l2_dev.notify = unicam_notify; -+ -+ unicam->sensor_config = v4l2_subdev_alloc_pad_config(unicam->sensor); -+ if (!unicam->sensor_config) -+ return -ENOMEM; -+ -+ ret = __subdev_get_format(unicam, &mbus_fmt); -+ if (ret) { -+ unicam_err(unicam, "Failed to get_format - ret %d\n", ret); -+ return ret; -+ } -+ -+ fmt = find_format_by_code(mbus_fmt.code); -+ if (!fmt) { -+ /* Find the first format that the sensor and unicam both -+ * support -+ */ -+ fmt = get_first_supported_format(unicam); -+ -+ if (!fmt) -+ /* No compatible formats */ -+ return -EINVAL; -+ -+ mbus_fmt.code = fmt->code; -+ ret = __subdev_set_format(unicam, &mbus_fmt); -+ if (ret) -+ return -EINVAL; -+ } -+ if (mbus_fmt.field != V4L2_FIELD_NONE) { -+ /* Interlaced not supported - disable it now. */ -+ mbus_fmt.field = V4L2_FIELD_NONE; -+ ret = __subdev_set_format(unicam, &mbus_fmt); -+ if (ret) -+ return -EINVAL; -+ } -+ -+ unicam->fmt = fmt; -+ if (fmt->fourcc) -+ unicam->v_fmt.fmt.pix.pixelformat = fmt->fourcc; -+ else -+ unicam->v_fmt.fmt.pix.pixelformat = fmt->repacked_fourcc; -+ -+ /* Read current subdev format */ -+ unicam_reset_format(unicam); -+ -+ if (v4l2_subdev_has_op(unicam->sensor, video, s_std)) { -+ v4l2_std_id tvnorms; -+ -+ if (WARN_ON(!v4l2_subdev_has_op(unicam->sensor, video, -+ g_tvnorms))) -+ /* -+ * Subdevice should not advertise s_std but not -+ * g_tvnorms -+ */ -+ return -EINVAL; -+ -+ ret = v4l2_subdev_call(unicam->sensor, video, -+ g_tvnorms, &tvnorms); -+ if (WARN_ON(ret)) -+ return -EINVAL; -+ unicam->video_dev.tvnorms |= tvnorms; -+ } -+ -+ spin_lock_init(&unicam->dma_queue_lock); -+ mutex_init(&unicam->lock); -+ -+ /* Add controls from the subdevice */ -+ ret = v4l2_ctrl_add_handler(&unicam->ctrl_handler, -+ unicam->sensor->ctrl_handler, NULL, true); -+ if (ret < 0) -+ return ret; -+ -+ q = &unicam->buffer_queue; -+ q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; -+ q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_READ; -+ q->drv_priv = unicam; -+ q->ops = &unicam_video_qops; -+ q->mem_ops = &vb2_dma_contig_memops; -+ q->buf_struct_size = sizeof(struct unicam_buffer); -+ q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; -+ q->lock = &unicam->lock; -+ q->min_buffers_needed = 2; -+ q->dev = &unicam->pdev->dev; -+ -+ ret = vb2_queue_init(q); -+ if (ret) { -+ unicam_err(unicam, "vb2_queue_init() failed\n"); -+ return ret; -+ } -+ -+ INIT_LIST_HEAD(&unicam->dma_queue.active); -+ -+ vdev = &unicam->video_dev; -+ strlcpy(vdev->name, UNICAM_MODULE_NAME, sizeof(vdev->name)); -+ vdev->release = video_device_release_empty; -+ vdev->fops = &unicam_fops; -+ vdev->ioctl_ops = &unicam_ioctl_ops; -+ vdev->v4l2_dev = &unicam->v4l2_dev; -+ vdev->vfl_dir = VFL_DIR_RX; -+ vdev->queue = q; -+ vdev->lock = &unicam->lock; -+ vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | -+ V4L2_CAP_READWRITE; -+ -+ /* If the source has no controls then remove our ctrl handler. */ -+ if (list_empty(&unicam->ctrl_handler.ctrls)) -+ unicam->v4l2_dev.ctrl_handler = NULL; -+ -+ video_set_drvdata(vdev, unicam); -+ vdev->entity.flags |= MEDIA_ENT_FL_DEFAULT; -+ -+ if (!v4l2_subdev_has_op(unicam->sensor, video, s_std)) { -+ v4l2_disable_ioctl(&unicam->video_dev, VIDIOC_S_STD); -+ v4l2_disable_ioctl(&unicam->video_dev, VIDIOC_G_STD); -+ v4l2_disable_ioctl(&unicam->video_dev, VIDIOC_ENUMSTD); -+ } -+ if (!v4l2_subdev_has_op(unicam->sensor, video, querystd)) -+ v4l2_disable_ioctl(&unicam->video_dev, VIDIOC_QUERYSTD); -+ if (!v4l2_subdev_has_op(unicam->sensor, video, s_dv_timings)) { -+ v4l2_disable_ioctl(&unicam->video_dev, VIDIOC_S_EDID); -+ v4l2_disable_ioctl(&unicam->video_dev, VIDIOC_G_EDID); -+ v4l2_disable_ioctl(&unicam->video_dev, VIDIOC_DV_TIMINGS_CAP); -+ v4l2_disable_ioctl(&unicam->video_dev, VIDIOC_G_DV_TIMINGS); -+ v4l2_disable_ioctl(&unicam->video_dev, VIDIOC_S_DV_TIMINGS); -+ v4l2_disable_ioctl(&unicam->video_dev, VIDIOC_ENUM_DV_TIMINGS); -+ v4l2_disable_ioctl(&unicam->video_dev, VIDIOC_QUERY_DV_TIMINGS); -+ } -+ if (!v4l2_subdev_has_op(unicam->sensor, pad, enum_frame_interval)) -+ v4l2_disable_ioctl(&unicam->video_dev, -+ VIDIOC_ENUM_FRAMEINTERVALS); -+ if (!v4l2_subdev_has_op(unicam->sensor, video, g_frame_interval)) -+ v4l2_disable_ioctl(&unicam->video_dev, VIDIOC_G_PARM); -+ if (!v4l2_subdev_has_op(unicam->sensor, video, s_frame_interval)) -+ v4l2_disable_ioctl(&unicam->video_dev, VIDIOC_S_PARM); -+ -+ if (!v4l2_subdev_has_op(unicam->sensor, pad, enum_frame_size)) -+ v4l2_disable_ioctl(&unicam->video_dev, VIDIOC_ENUM_FRAMESIZES); -+ -+ ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1); -+ if (ret) { -+ unicam_err(unicam, "Unable to register video device.\n"); -+ return ret; -+ } -+ -+ ret = v4l2_device_register_ro_subdev_nodes(&unicam->v4l2_dev); -+ if (ret) { -+ unicam_err(unicam, -+ "Unable to register subdev nodes.\n"); -+ video_unregister_device(&unicam->video_dev); -+ return ret; -+ } -+ -+ ret = media_create_pad_link(&unicam->sensor->entity, 0, -+ &unicam->video_dev.entity, 0, -+ MEDIA_LNK_FL_ENABLED | -+ MEDIA_LNK_FL_IMMUTABLE); -+ if (ret) { -+ unicam_err(unicam, "Unable to create pad links.\n"); -+ video_unregister_device(&unicam->video_dev); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int unicam_async_complete(struct v4l2_async_notifier *notifier) -+{ -+ struct unicam_device *unicam = container_of(notifier->v4l2_dev, -+ struct unicam_device, v4l2_dev); -+ -+ return unicam_probe_complete(unicam); -+} -+ -+static const struct v4l2_async_notifier_operations unicam_async_ops = { -+ .bound = unicam_async_bound, -+ .complete = unicam_async_complete, -+}; -+ -+static int of_unicam_connect_subdevs(struct unicam_device *dev) -+{ -+ struct platform_device *pdev = dev->pdev; -+ struct device_node *parent, *ep_node = NULL, *remote_ep = NULL, -+ *sensor_node = NULL; -+ struct v4l2_fwnode_endpoint *ep; -+ struct v4l2_async_subdev *asd; -+ unsigned int peripheral_data_lanes; -+ int ret = -EINVAL; -+ unsigned int lane; -+ -+ parent = pdev->dev.of_node; -+ -+ asd = &dev->asd; -+ ep = &dev->endpoint; -+ -+ ep_node = of_graph_get_next_endpoint(parent, NULL); -+ if (!ep_node) { -+ unicam_dbg(3, dev, "can't get next endpoint\n"); -+ goto cleanup_exit; -+ } -+ -+ unicam_dbg(3, dev, "ep_node is %s\n", ep_node->name); -+ -+ v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep_node), ep); -+ -+ for (lane = 0; lane < ep->bus.mipi_csi2.num_data_lanes; lane++) { -+ if (ep->bus.mipi_csi2.data_lanes[lane] != lane + 1) { -+ unicam_err(dev, "Local endpoint - data lane reordering not supported\n"); -+ goto cleanup_exit; -+ } -+ } -+ -+ peripheral_data_lanes = ep->bus.mipi_csi2.num_data_lanes; -+ -+ sensor_node = of_graph_get_remote_port_parent(ep_node); -+ if (!sensor_node) { -+ unicam_dbg(3, dev, "can't get remote parent\n"); -+ goto cleanup_exit; -+ } -+ unicam_dbg(3, dev, "sensor_node is %s\n", sensor_node->name); -+ asd->match_type = V4L2_ASYNC_MATCH_FWNODE; -+ asd->match.fwnode = of_fwnode_handle(sensor_node); -+ -+ remote_ep = of_graph_get_remote_endpoint(ep_node); -+ if (!remote_ep) { -+ unicam_dbg(3, dev, "can't get remote-endpoint\n"); -+ goto cleanup_exit; -+ } -+ unicam_dbg(3, dev, "remote_ep is %s\n", remote_ep->name); -+ v4l2_fwnode_endpoint_parse(of_fwnode_handle(remote_ep), ep); -+ unicam_dbg(3, dev, "parsed remote_ep to endpoint. nr_of_link_frequencies %u, bus_type %u\n", -+ ep->nr_of_link_frequencies, ep->bus_type); -+ -+ switch (ep->bus_type) { -+ case V4L2_MBUS_CSI2_DPHY: -+ if (ep->bus.mipi_csi2.num_data_lanes > -+ peripheral_data_lanes) { -+ unicam_err(dev, "Subdevice %s wants too many data lanes (%u > %u)\n", -+ sensor_node->name, -+ ep->bus.mipi_csi2.num_data_lanes, -+ peripheral_data_lanes); -+ goto cleanup_exit; -+ } -+ for (lane = 0; -+ lane < ep->bus.mipi_csi2.num_data_lanes; -+ lane++) { -+ if (ep->bus.mipi_csi2.data_lanes[lane] != lane + 1) { -+ unicam_err(dev, "Subdevice %s - incompatible data lane config\n", -+ sensor_node->name); -+ goto cleanup_exit; -+ } -+ } -+ dev->max_data_lanes = ep->bus.mipi_csi2.num_data_lanes; -+ dev->bus_flags = ep->bus.mipi_csi2.flags; -+ break; -+ case V4L2_MBUS_CCP2: -+ if (ep->bus.mipi_csi1.clock_lane != 0 || -+ ep->bus.mipi_csi1.data_lane != 1) { -+ unicam_err(dev, "Subdevice %s incompatible lane config\n", -+ sensor_node->name); -+ goto cleanup_exit; -+ } -+ dev->max_data_lanes = 1; -+ dev->bus_flags = ep->bus.mipi_csi1.strobe; -+ break; -+ default: -+ /* Unsupported bus type */ -+ unicam_err(dev, "sub-device %s is not a CSI2 or CCP2 device %d\n", -+ sensor_node->name, ep->bus_type); -+ goto cleanup_exit; -+ } -+ -+ /* Store bus type - CSI2 or CCP2 */ -+ dev->bus_type = ep->bus_type; -+ unicam_dbg(3, dev, "bus_type is %d\n", dev->bus_type); -+ -+ /* Store Virtual Channel number */ -+ dev->virtual_channel = ep->base.id; -+ -+ unicam_dbg(3, dev, "v4l2-endpoint: %s\n", -+ dev->bus_type == V4L2_MBUS_CSI2_DPHY ? "CSI2" : "CCP2"); -+ unicam_dbg(3, dev, "Virtual Channel=%d\n", dev->virtual_channel); -+ if (dev->bus_type == V4L2_MBUS_CSI2_DPHY) -+ unicam_dbg(3, dev, "flags=0x%08x\n", ep->bus.mipi_csi2.flags); -+ unicam_dbg(3, dev, "num_data_lanes=%d\n", dev->max_data_lanes); -+ -+ unicam_dbg(1, dev, "found sub-device %s\n", sensor_node->name); -+ -+ v4l2_async_notifier_init(&dev->notifier); -+ -+ ret = v4l2_async_notifier_add_subdev(&dev->notifier, asd); -+ if (ret) { -+ unicam_err(dev, "Error adding subdevice - ret %d\n", ret); -+ goto cleanup_exit; -+ } -+ -+ dev->notifier.ops = &unicam_async_ops; -+ ret = v4l2_async_notifier_register(&dev->v4l2_dev, -+ &dev->notifier); -+ if (ret) { -+ unicam_err(dev, "Error registering async notifier - ret %d\n", -+ ret); -+ ret = -EINVAL; -+ } -+ -+cleanup_exit: -+ if (remote_ep) -+ of_node_put(remote_ep); -+ if (sensor_node) -+ of_node_put(sensor_node); -+ if (ep_node) -+ of_node_put(ep_node); -+ -+ return ret; -+} -+ -+static int unicam_probe(struct platform_device *pdev) -+{ -+ struct unicam_cfg *unicam_cfg; -+ struct unicam_device *unicam; -+ struct v4l2_ctrl_handler *hdl; -+ struct resource *res; -+ int ret; -+ -+ unicam = devm_kzalloc(&pdev->dev, sizeof(*unicam), GFP_KERNEL); -+ if (!unicam) -+ return -ENOMEM; -+ -+ unicam->pdev = pdev; -+ unicam_cfg = &unicam->cfg; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ unicam_cfg->base = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(unicam_cfg->base)) { -+ unicam_err(unicam, "Failed to get main io block\n"); -+ return PTR_ERR(unicam_cfg->base); -+ } -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1); -+ unicam_cfg->clk_gate_base = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(unicam_cfg->clk_gate_base)) { -+ unicam_err(unicam, "Failed to get 2nd io block\n"); -+ return PTR_ERR(unicam_cfg->clk_gate_base); -+ } -+ -+ unicam->clock = devm_clk_get(&pdev->dev, "lp"); -+ if (IS_ERR(unicam->clock)) { -+ unicam_err(unicam, "Failed to get clock\n"); -+ return PTR_ERR(unicam->clock); -+ } -+ -+ ret = platform_get_irq(pdev, 0); -+ if (ret <= 0) { -+ dev_err(&pdev->dev, "No IRQ resource\n"); -+ return -ENODEV; -+ } -+ -+ ret = devm_request_irq(&pdev->dev, ret, unicam_isr, 0, -+ "unicam_capture0", unicam); -+ if (ret) { -+ dev_err(&pdev->dev, "Unable to request interrupt\n"); -+ return -EINVAL; -+ } -+ -+ unicam->mdev.dev = &pdev->dev; -+ strscpy(unicam->mdev.model, UNICAM_MODULE_NAME, -+ sizeof(unicam->mdev.model)); -+ strscpy(unicam->mdev.serial, "", sizeof(unicam->mdev.serial)); -+ snprintf(unicam->mdev.bus_info, sizeof(unicam->mdev.bus_info), -+ "platform:%s %s", -+ pdev->dev.driver->name, dev_name(&pdev->dev)); -+ unicam->mdev.hw_revision = 1; -+ -+ media_entity_pads_init(&unicam->video_dev.entity, 1, &unicam->pad); -+ media_device_init(&unicam->mdev); -+ -+ unicam->v4l2_dev.mdev = &unicam->mdev; -+ -+ ret = v4l2_device_register(&pdev->dev, &unicam->v4l2_dev); -+ if (ret) { -+ unicam_err(unicam, -+ "Unable to register v4l2 device.\n"); -+ goto media_cleanup; -+ } -+ -+ ret = media_device_register(&unicam->mdev); -+ if (ret < 0) { -+ unicam_err(unicam, -+ "Unable to register media-controller device.\n"); -+ goto probe_out_v4l2_unregister; -+ } -+ -+ /* Reserve space for the controls */ -+ hdl = &unicam->ctrl_handler; -+ ret = v4l2_ctrl_handler_init(hdl, 16); -+ if (ret < 0) -+ goto media_unregister; -+ unicam->v4l2_dev.ctrl_handler = hdl; -+ -+ /* set the driver data in platform device */ -+ platform_set_drvdata(pdev, unicam); -+ -+ ret = of_unicam_connect_subdevs(unicam); -+ if (ret) { -+ dev_err(&pdev->dev, "Failed to connect subdevs\n"); -+ goto free_hdl; -+ } -+ -+ /* Enable the block power domain */ -+ pm_runtime_enable(&pdev->dev); -+ -+ return 0; -+ -+free_hdl: -+ v4l2_ctrl_handler_free(hdl); -+media_unregister: -+ media_device_unregister(&unicam->mdev); -+probe_out_v4l2_unregister: -+ v4l2_device_unregister(&unicam->v4l2_dev); -+media_cleanup: -+ media_device_cleanup(&unicam->mdev); -+ -+ return ret; -+} -+ -+static int unicam_remove(struct platform_device *pdev) -+{ -+ struct unicam_device *unicam = platform_get_drvdata(pdev); -+ -+ unicam_dbg(2, unicam, "%s\n", __func__); -+ -+ pm_runtime_disable(&pdev->dev); -+ -+ v4l2_async_notifier_unregister(&unicam->notifier); -+ v4l2_ctrl_handler_free(&unicam->ctrl_handler); -+ v4l2_device_unregister(&unicam->v4l2_dev); -+ video_unregister_device(&unicam->video_dev); -+ if (unicam->sensor_config) -+ v4l2_subdev_free_pad_config(unicam->sensor_config); -+ media_device_unregister(&unicam->mdev); -+ media_device_cleanup(&unicam->mdev); -+ -+ return 0; -+} -+ -+static const struct of_device_id unicam_of_match[] = { -+ { .compatible = "brcm,bcm2835-unicam", }, -+ { /* sentinel */ }, -+}; -+MODULE_DEVICE_TABLE(of, unicam_of_match); -+ -+static struct platform_driver unicam_driver = { -+ .probe = unicam_probe, -+ .remove = unicam_remove, -+ .driver = { -+ .name = UNICAM_MODULE_NAME, -+ .of_match_table = of_match_ptr(unicam_of_match), -+ }, -+}; -+ -+module_platform_driver(unicam_driver); -+ -+MODULE_AUTHOR("Dave Stevenson "); -+MODULE_DESCRIPTION("BCM2835 Unicam driver"); -+MODULE_LICENSE("GPL"); -+MODULE_VERSION(UNICAM_VERSION); ---- /dev/null -+++ b/drivers/media/platform/bcm2835/vc4-regs-unicam.h -@@ -0,0 +1,253 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+ -+/* -+ * Copyright (C) 2017-2020 Raspberry Pi Trading. -+ * Dave Stevenson -+ */ -+ -+#ifndef VC4_REGS_UNICAM_H -+#define VC4_REGS_UNICAM_H -+ -+/* -+ * The following values are taken from files found within the code drop -+ * made by Broadcom for the BCM21553 Graphics Driver, predominantly in -+ * brcm_usrlib/dag/vmcsx/vcinclude/hardware_vc4.h. -+ * They have been modified to be only the register offset. -+ */ -+#define UNICAM_CTRL 0x000 -+#define UNICAM_STA 0x004 -+#define UNICAM_ANA 0x008 -+#define UNICAM_PRI 0x00c -+#define UNICAM_CLK 0x010 -+#define UNICAM_CLT 0x014 -+#define UNICAM_DAT0 0x018 -+#define UNICAM_DAT1 0x01c -+#define UNICAM_DAT2 0x020 -+#define UNICAM_DAT3 0x024 -+#define UNICAM_DLT 0x028 -+#define UNICAM_CMP0 0x02c -+#define UNICAM_CMP1 0x030 -+#define UNICAM_CAP0 0x034 -+#define UNICAM_CAP1 0x038 -+#define UNICAM_ICTL 0x100 -+#define UNICAM_ISTA 0x104 -+#define UNICAM_IDI0 0x108 -+#define UNICAM_IPIPE 0x10c -+#define UNICAM_IBSA0 0x110 -+#define UNICAM_IBEA0 0x114 -+#define UNICAM_IBLS 0x118 -+#define UNICAM_IBWP 0x11c -+#define UNICAM_IHWIN 0x120 -+#define UNICAM_IHSTA 0x124 -+#define UNICAM_IVWIN 0x128 -+#define UNICAM_IVSTA 0x12c -+#define UNICAM_ICC 0x130 -+#define UNICAM_ICS 0x134 -+#define UNICAM_IDC 0x138 -+#define UNICAM_IDPO 0x13c -+#define UNICAM_IDCA 0x140 -+#define UNICAM_IDCD 0x144 -+#define UNICAM_IDS 0x148 -+#define UNICAM_DCS 0x200 -+#define UNICAM_DBSA0 0x204 -+#define UNICAM_DBEA0 0x208 -+#define UNICAM_DBWP 0x20c -+#define UNICAM_DBCTL 0x300 -+#define UNICAM_IBSA1 0x304 -+#define UNICAM_IBEA1 0x308 -+#define UNICAM_IDI1 0x30c -+#define UNICAM_DBSA1 0x310 -+#define UNICAM_DBEA1 0x314 -+#define UNICAM_MISC 0x400 -+ -+/* -+ * The following bitmasks are from the kernel released by Broadcom -+ * for Android - https://android.googlesource.com/kernel/bcm/ -+ * The Rhea, Hawaii, and Java chips all contain the same VideoCore4 -+ * Unicam block as BCM2835, as defined in eg -+ * arch/arm/mach-rhea/include/mach/rdb_A0/brcm_rdb_cam.h and similar. -+ * Values reworked to use the kernel BIT and GENMASK macros. -+ * -+ * Some of the bit mnenomics have been amended to match the datasheet. -+ */ -+/* UNICAM_CTRL Register */ -+#define UNICAM_CPE BIT(0) -+#define UNICAM_MEM BIT(1) -+#define UNICAM_CPR BIT(2) -+#define UNICAM_CPM_MASK GENMASK(3, 3) -+#define UNICAM_CPM_CSI2 0 -+#define UNICAM_CPM_CCP2 1 -+#define UNICAM_SOE BIT(4) -+#define UNICAM_DCM_MASK GENMASK(5, 5) -+#define UNICAM_DCM_STROBE 0 -+#define UNICAM_DCM_DATA 1 -+#define UNICAM_SLS BIT(6) -+#define UNICAM_PFT_MASK GENMASK(11, 8) -+#define UNICAM_OET_MASK GENMASK(20, 12) -+ -+/* UNICAM_STA Register */ -+#define UNICAM_SYN BIT(0) -+#define UNICAM_CS BIT(1) -+#define UNICAM_SBE BIT(2) -+#define UNICAM_PBE BIT(3) -+#define UNICAM_HOE BIT(4) -+#define UNICAM_PLE BIT(5) -+#define UNICAM_SSC BIT(6) -+#define UNICAM_CRCE BIT(7) -+#define UNICAM_OES BIT(8) -+#define UNICAM_IFO BIT(9) -+#define UNICAM_OFO BIT(10) -+#define UNICAM_BFO BIT(11) -+#define UNICAM_DL BIT(12) -+#define UNICAM_PS BIT(13) -+#define UNICAM_IS BIT(14) -+#define UNICAM_PI0 BIT(15) -+#define UNICAM_PI1 BIT(16) -+#define UNICAM_FSI_S BIT(17) -+#define UNICAM_FEI_S BIT(18) -+#define UNICAM_LCI_S BIT(19) -+#define UNICAM_BUF0_RDY BIT(20) -+#define UNICAM_BUF0_NO BIT(21) -+#define UNICAM_BUF1_RDY BIT(22) -+#define UNICAM_BUF1_NO BIT(23) -+#define UNICAM_DI BIT(24) -+ -+#define UNICAM_STA_MASK_ALL \ -+ (UNICAM_DL + \ -+ UNICAM_SBE + \ -+ UNICAM_PBE + \ -+ UNICAM_HOE + \ -+ UNICAM_PLE + \ -+ UNICAM_SSC + \ -+ UNICAM_CRCE + \ -+ UNICAM_IFO + \ -+ UNICAM_OFO + \ -+ UNICAM_PS + \ -+ UNICAM_PI0 + \ -+ UNICAM_PI1) -+ -+/* UNICAM_ANA Register */ -+#define UNICAM_APD BIT(0) -+#define UNICAM_BPD BIT(1) -+#define UNICAM_AR BIT(2) -+#define UNICAM_DDL BIT(3) -+#define UNICAM_CTATADJ_MASK GENMASK(7, 4) -+#define UNICAM_PTATADJ_MASK GENMASK(11, 8) -+ -+/* UNICAM_PRI Register */ -+#define UNICAM_PE BIT(0) -+#define UNICAM_PT_MASK GENMASK(2, 1) -+#define UNICAM_NP_MASK GENMASK(7, 4) -+#define UNICAM_PP_MASK GENMASK(11, 8) -+#define UNICAM_BS_MASK GENMASK(15, 12) -+#define UNICAM_BL_MASK GENMASK(17, 16) -+ -+/* UNICAM_CLK Register */ -+#define UNICAM_CLE BIT(0) -+#define UNICAM_CLPD BIT(1) -+#define UNICAM_CLLPE BIT(2) -+#define UNICAM_CLHSE BIT(3) -+#define UNICAM_CLTRE BIT(4) -+#define UNICAM_CLAC_MASK GENMASK(8, 5) -+#define UNICAM_CLSTE BIT(29) -+ -+/* UNICAM_CLT Register */ -+#define UNICAM_CLT1_MASK GENMASK(7, 0) -+#define UNICAM_CLT2_MASK GENMASK(15, 8) -+ -+/* UNICAM_DATn Registers */ -+#define UNICAM_DLE BIT(0) -+#define UNICAM_DLPD BIT(1) -+#define UNICAM_DLLPE BIT(2) -+#define UNICAM_DLHSE BIT(3) -+#define UNICAM_DLTRE BIT(4) -+#define UNICAM_DLSM BIT(5) -+#define UNICAM_DLFO BIT(28) -+#define UNICAM_DLSTE BIT(29) -+ -+#define UNICAM_DAT_MASK_ALL (UNICAM_DLSTE + UNICAM_DLFO) -+ -+/* UNICAM_DLT Register */ -+#define UNICAM_DLT1_MASK GENMASK(7, 0) -+#define UNICAM_DLT2_MASK GENMASK(15, 8) -+#define UNICAM_DLT3_MASK GENMASK(23, 16) -+ -+/* UNICAM_ICTL Register */ -+#define UNICAM_FSIE BIT(0) -+#define UNICAM_FEIE BIT(1) -+#define UNICAM_IBOB BIT(2) -+#define UNICAM_FCM BIT(3) -+#define UNICAM_TFC BIT(4) -+#define UNICAM_LIP_MASK GENMASK(6, 5) -+#define UNICAM_LCIE_MASK GENMASK(28, 16) -+ -+/* UNICAM_IDI0/1 Register */ -+#define UNICAM_ID0_MASK GENMASK(7, 0) -+#define UNICAM_ID1_MASK GENMASK(15, 8) -+#define UNICAM_ID2_MASK GENMASK(23, 16) -+#define UNICAM_ID3_MASK GENMASK(31, 24) -+ -+/* UNICAM_ISTA Register */ -+#define UNICAM_FSI BIT(0) -+#define UNICAM_FEI BIT(1) -+#define UNICAM_LCI BIT(2) -+ -+#define UNICAM_ISTA_MASK_ALL (UNICAM_FSI + UNICAM_FEI + UNICAM_LCI) -+ -+/* UNICAM_IPIPE Register */ -+#define UNICAM_PUM_MASK GENMASK(2, 0) -+ /* Unpacking modes */ -+ #define UNICAM_PUM_NONE 0 -+ #define UNICAM_PUM_UNPACK6 1 -+ #define UNICAM_PUM_UNPACK7 2 -+ #define UNICAM_PUM_UNPACK8 3 -+ #define UNICAM_PUM_UNPACK10 4 -+ #define UNICAM_PUM_UNPACK12 5 -+ #define UNICAM_PUM_UNPACK14 6 -+ #define UNICAM_PUM_UNPACK16 7 -+#define UNICAM_DDM_MASK GENMASK(6, 3) -+#define UNICAM_PPM_MASK GENMASK(9, 7) -+ /* Packing modes */ -+ #define UNICAM_PPM_NONE 0 -+ #define UNICAM_PPM_PACK8 1 -+ #define UNICAM_PPM_PACK10 2 -+ #define UNICAM_PPM_PACK12 3 -+ #define UNICAM_PPM_PACK14 4 -+ #define UNICAM_PPM_PACK16 5 -+#define UNICAM_DEM_MASK GENMASK(11, 10) -+#define UNICAM_DEBL_MASK GENMASK(14, 12) -+#define UNICAM_ICM_MASK GENMASK(16, 15) -+#define UNICAM_IDM_MASK GENMASK(17, 17) -+ -+/* UNICAM_ICC Register */ -+#define UNICAM_ICFL_MASK GENMASK(4, 0) -+#define UNICAM_ICFH_MASK GENMASK(9, 5) -+#define UNICAM_ICST_MASK GENMASK(12, 10) -+#define UNICAM_ICLT_MASK GENMASK(15, 13) -+#define UNICAM_ICLL_MASK GENMASK(31, 16) -+ -+/* UNICAM_DCS Register */ -+#define UNICAM_DIE BIT(0) -+#define UNICAM_DIM BIT(1) -+#define UNICAM_DBOB BIT(3) -+#define UNICAM_FDE BIT(4) -+#define UNICAM_LDP BIT(5) -+#define UNICAM_EDL_MASK GENMASK(15, 8) -+ -+/* UNICAM_DBCTL Register */ -+#define UNICAM_DBEN BIT(0) -+#define UNICAM_BUF0_IE BIT(1) -+#define UNICAM_BUF1_IE BIT(2) -+ -+/* UNICAM_CMP[0,1] register */ -+#define UNICAM_PCE BIT(31) -+#define UNICAM_GI BIT(9) -+#define UNICAM_CPH BIT(8) -+#define UNICAM_PCVC_MASK GENMASK(7, 6) -+#define UNICAM_PCDT_MASK GENMASK(5, 0) -+ -+/* UNICAM_MISC register */ -+#define UNICAM_FL0 BIT(6) -+#define UNICAM_FL1 BIT(9) -+ -+#endif diff --git a/target/linux/bcm27xx/patches-5.15/950-0213-media-bcm2835-unicam-Add-support-for-mulitple-device.patch b/target/linux/bcm27xx/patches-5.15/950-0213-media-bcm2835-unicam-Add-support-for-mulitple-device.patch deleted file mode 100644 index cac6779a5..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0213-media-bcm2835-unicam-Add-support-for-mulitple-device.patch +++ /dev/null @@ -1,1084 +0,0 @@ -From f69e7d7aaaea4c6531b357ac2a1a522b400c7cd0 Mon Sep 17 00:00:00 2001 -From: Naushir Patuck -Date: Tue, 7 Apr 2020 10:42:14 +0100 -Subject: [PATCH] media: bcm2835-unicam: Add support for mulitple - device nodes. - -Move device node specific state out of the device state structure and -into a new node structure. This separation will be needed for future -changes where we will add an embedded data node to the driver to work -alongside the existing image data node. - -Currently only use a single image node, so this commit does not add -any functional changes. - -Signed-off-by: Naushir Patuck ---- - .../media/platform/bcm2835/bcm2835-unicam.c | 484 ++++++++++-------- - 1 file changed, 283 insertions(+), 201 deletions(-) - ---- a/drivers/media/platform/bcm2835/bcm2835-unicam.c -+++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c -@@ -109,7 +109,8 @@ MODULE_PARM_DESC(debug, "Debug level 0-3 - /* Define a nominal minimum image size */ - #define MIN_WIDTH 16 - #define MIN_HEIGHT 16 -- -+/* Maximum number of simulataneous streams Uncaim can handle. */ -+#define MAX_NODES 2 - /* - * struct unicam_fmt - Unicam media bus format information - * @pixelformat: V4L2 pixel format FCC identifier. 0 if n/a. -@@ -346,11 +347,37 @@ struct unicam_cfg { - - #define MAX_POSSIBLE_PIX_FMTS (ARRAY_SIZE(formats)) - --struct unicam_device { -- /* V4l2 specific parameters */ -+struct unicam_node { -+ bool registered; -+ unsigned int pad_id; -+ /* Pointer pointing to current v4l2_buffer */ -+ struct unicam_buffer *cur_frm; -+ /* Pointer pointing to next v4l2_buffer */ -+ struct unicam_buffer *next_frm; -+ /* video capture */ -+ const struct unicam_fmt *fmt; -+ /* Used to store current pixel format */ -+ struct v4l2_format v_fmt; -+ /* Used to store current mbus frame format */ -+ struct v4l2_mbus_framefmt m_fmt; -+ /* Buffer queue used in video-buf */ -+ struct vb2_queue buffer_queue; -+ /* Queue of filled frames */ -+ struct unicam_dmaqueue dma_queue; -+ /* IRQ lock for DMA queue */ -+ spinlock_t dma_queue_lock; -+ /* lock used to access this structure */ -+ struct mutex lock; - /* Identifies video device for this channel */ - struct video_device video_dev; -+ /* Pointer to the parent handle */ -+ struct unicam_device *dev; -+ struct media_pad pad; - struct v4l2_ctrl_handler ctrl_handler; -+}; -+ -+struct unicam_device { -+ /* V4l2 specific parameters */ - - struct v4l2_fwnode_endpoint endpoint; - -@@ -363,7 +390,6 @@ struct unicam_device { - /* V4l2 device */ - struct v4l2_device v4l2_dev; - struct media_device mdev; -- struct media_pad pad; - - /* parent device */ - struct platform_device *pdev; -@@ -378,18 +404,6 @@ struct unicam_device { - /* current input at the sub device */ - int current_input; - -- /* Pointer pointing to current v4l2_buffer */ -- struct unicam_buffer *cur_frm; -- /* Pointer pointing to next v4l2_buffer */ -- struct unicam_buffer *next_frm; -- -- /* video capture */ -- const struct unicam_fmt *fmt; -- /* Used to store current pixel format */ -- struct v4l2_format v_fmt; -- /* Used to store current mbus frame format */ -- struct v4l2_mbus_framefmt m_fmt; -- - unsigned int virtual_channel; - enum v4l2_mbus_type bus_type; - /* -@@ -401,20 +415,10 @@ struct unicam_device { - unsigned int active_data_lanes; - - struct v4l2_rect crop; -- -- /* Currently selected input on subdev */ -- int input; -- -- /* Buffer queue used in video-buf */ -- struct vb2_queue buffer_queue; -- /* Queue of filled frames */ -- struct unicam_dmaqueue dma_queue; -- /* IRQ lock for DMA queue */ -- spinlock_t dma_queue_lock; -- /* lock used to access this structure */ -- struct mutex lock; - /* Flag to denote that we are processing buffers */ - int streaming; -+ -+ struct unicam_node node[MAX_NODES]; - }; - - /* Hardware access */ -@@ -526,10 +530,11 @@ static inline unsigned int bytes_per_lin - } - - static int __subdev_get_format(struct unicam_device *dev, -- struct v4l2_mbus_framefmt *fmt) -+ struct v4l2_mbus_framefmt *fmt, int pad_id) - { - struct v4l2_subdev_format sd_fmt = { - .which = V4L2_SUBDEV_FORMAT_ACTIVE, -+ .pad = pad_id - }; - int ret; - -@@ -598,29 +603,30 @@ static int unicam_calc_format_size_bpl(s - return 0; - } - --static int unicam_reset_format(struct unicam_device *dev) -+static int unicam_reset_format(struct unicam_node *node) - { -+ struct unicam_device *dev = node->dev; - struct v4l2_mbus_framefmt mbus_fmt; - int ret; - -- ret = __subdev_get_format(dev, &mbus_fmt); -+ ret = __subdev_get_format(dev, &mbus_fmt, node->pad_id); - if (ret) { - unicam_err(dev, "Failed to get_format - ret %d\n", ret); - return ret; - } - -- if (mbus_fmt.code != dev->fmt->code) { -+ if (mbus_fmt.code != dev->node[0].fmt->code) { - unicam_err(dev, "code mismatch - fmt->code %08x, mbus_fmt.code %08x\n", -- dev->fmt->code, mbus_fmt.code); -+ dev->node[0].fmt->code, mbus_fmt.code); - return ret; - } - -- v4l2_fill_pix_format(&dev->v_fmt.fmt.pix, &mbus_fmt); -- dev->v_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; -+ v4l2_fill_pix_format(&dev->node[0].v_fmt.fmt.pix, &mbus_fmt); -+ dev->node[0].v_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - -- unicam_calc_format_size_bpl(dev, dev->fmt, &dev->v_fmt); -+ unicam_calc_format_size_bpl(dev, dev->node[0].fmt, &dev->node[0].v_fmt); - -- dev->m_fmt = mbus_fmt; -+ dev->node[0].m_fmt = mbus_fmt; - - return 0; - } -@@ -635,14 +641,14 @@ static void unicam_wr_dma_addr(struct un - - reg_write(&dev->cfg, UNICAM_IBSA0, dmaaddr); - reg_write(&dev->cfg, UNICAM_IBEA0, -- dmaaddr + dev->v_fmt.fmt.pix.sizeimage); -+ dmaaddr + dev->node[0].v_fmt.fmt.pix.sizeimage); - } - - static inline unsigned int unicam_get_lines_done(struct unicam_device *dev) - { - dma_addr_t start_addr, cur_addr; -- unsigned int stride = dev->v_fmt.fmt.pix.bytesperline; -- struct unicam_buffer *frm = dev->cur_frm; -+ unsigned int stride = dev->node[0].v_fmt.fmt.pix.bytesperline; -+ struct unicam_buffer *frm = dev->node[0].cur_frm; - - if (!frm) - return 0; -@@ -654,12 +660,12 @@ static inline unsigned int unicam_get_li - - static inline void unicam_schedule_next_buffer(struct unicam_device *dev) - { -- struct unicam_dmaqueue *dma_q = &dev->dma_queue; -+ struct unicam_dmaqueue *dma_q = &dev->node[0].dma_queue; - struct unicam_buffer *buf; - dma_addr_t addr; - - buf = list_entry(dma_q->active.next, struct unicam_buffer, list); -- dev->next_frm = buf; -+ dev->node[0].next_frm = buf; - list_del(&buf->list); - - addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0); -@@ -668,11 +674,11 @@ static inline void unicam_schedule_next_ - - static inline void unicam_process_buffer_complete(struct unicam_device *dev) - { -- dev->cur_frm->vb.field = dev->m_fmt.field; -- dev->cur_frm->vb.sequence = dev->sequence++; -+ dev->node[0].cur_frm->vb.field = dev->node[0].m_fmt.field; -+ dev->node[0].cur_frm->vb.sequence = dev->sequence++; - -- vb2_buffer_done(&dev->cur_frm->vb.vb2_buf, VB2_BUF_STATE_DONE); -- dev->cur_frm = dev->next_frm; -+ vb2_buffer_done(&dev->node[0].cur_frm->vb.vb2_buf, VB2_BUF_STATE_DONE); -+ dev->node[0].cur_frm = dev->node[0].next_frm; - } - - /* -@@ -687,7 +693,7 @@ static irqreturn_t unicam_isr(int irq, v - { - struct unicam_device *unicam = (struct unicam_device *)dev; - struct unicam_cfg *cfg = &unicam->cfg; -- struct unicam_dmaqueue *dma_q = &unicam->dma_queue; -+ struct unicam_dmaqueue *dma_q = &unicam->node[0].dma_queue; - unsigned int lines_done = unicam_get_lines_done(dev); - unsigned int sequence = unicam->sequence; - int ista, sta; -@@ -720,8 +726,9 @@ static irqreturn_t unicam_isr(int irq, v - * Timestamp is to be when the first data byte was captured, - * aka frame start. - */ -- if (unicam->cur_frm) -- unicam->cur_frm->vb.vb2_buf.timestamp = ktime_get_ns(); -+ if (unicam->node[0].cur_frm) -+ unicam->node[0].cur_frm->vb.vb2_buf.timestamp = -+ ktime_get_ns(); - } - if (ista & UNICAM_FEI || sta & UNICAM_PI0) { - /* -@@ -729,7 +736,8 @@ static irqreturn_t unicam_isr(int irq, v - * stop the peripheral. Overwrite the frame we've just - * captured instead. - */ -- if (unicam->cur_frm && unicam->cur_frm != unicam->next_frm) -+ if (unicam->node[0].cur_frm && -+ unicam->node[0].cur_frm != unicam->node[0].next_frm) - unicam_process_buffer_complete(unicam); - } - -@@ -738,11 +746,11 @@ static irqreturn_t unicam_isr(int irq, v - * already started. - */ - if (ista & (UNICAM_FSI | UNICAM_LCI) && !(ista & UNICAM_FEI)) { -- spin_lock(&unicam->dma_queue_lock); -+ spin_lock(&unicam->node[0].dma_queue_lock); - if (!list_empty(&dma_q->active) && -- unicam->cur_frm == unicam->next_frm) -+ unicam->node[0].cur_frm == unicam->node[0].next_frm) - unicam_schedule_next_buffer(unicam); -- spin_unlock(&unicam->dma_queue_lock); -+ spin_unlock(&unicam->node[0].dma_queue_lock); - } - - if (reg_read(&unicam->cfg, UNICAM_ICTL) & UNICAM_FCM) { -@@ -756,7 +764,8 @@ static irqreturn_t unicam_isr(int irq, v - static int unicam_querycap(struct file *file, void *priv, - struct v4l2_capability *cap) - { -- struct unicam_device *dev = video_drvdata(file); -+ struct unicam_node *node = video_drvdata(file); -+ struct unicam_device *dev = node->dev; - - strlcpy(cap->driver, UNICAM_MODULE_NAME, sizeof(cap->driver)); - strlcpy(cap->card, UNICAM_MODULE_NAME, sizeof(cap->card)); -@@ -770,7 +779,8 @@ static int unicam_querycap(struct file * - static int unicam_enum_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_fmtdesc *f) - { -- struct unicam_device *dev = video_drvdata(file); -+ struct unicam_node *node = video_drvdata(file); -+ struct unicam_device *dev = node->dev; - struct v4l2_subdev_mbus_code_enum mbus_code; - const struct unicam_fmt *fmt = NULL; - int index = 0; -@@ -815,9 +825,9 @@ static int unicam_enum_fmt_vid_cap(struc - static int unicam_g_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) - { -- struct unicam_device *dev = video_drvdata(file); -+ struct unicam_node *node = video_drvdata(file); - -- *f = dev->v_fmt; -+ *f = node->v_fmt; - - return 0; - } -@@ -859,9 +869,11 @@ const struct unicam_fmt *get_first_suppo - static int unicam_try_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) - { -- struct unicam_device *dev = video_drvdata(file); -+ struct unicam_node *node = video_drvdata(file); -+ struct unicam_device *dev = node->dev; - struct v4l2_subdev_format sd_fmt = { - .which = V4L2_SUBDEV_FORMAT_TRY, -+ .pad = 0 - }; - struct v4l2_mbus_framefmt *mbus_fmt = &sd_fmt.format; - const struct unicam_fmt *fmt; -@@ -939,8 +951,9 @@ static int unicam_try_fmt_vid_cap(struct - static int unicam_s_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) - { -- struct unicam_device *dev = video_drvdata(file); -- struct vb2_queue *q = &dev->buffer_queue; -+ struct unicam_node *node = video_drvdata(file); -+ struct unicam_device *dev = node->dev; -+ struct vb2_queue *q = &node->buffer_queue; - struct v4l2_mbus_framefmt mbus_fmt = {0}; - const struct unicam_fmt *fmt; - int ret; -@@ -985,17 +998,18 @@ static int unicam_s_fmt_vid_cap(struct f - return -EINVAL; - } - -- dev->fmt = fmt; -- dev->v_fmt.fmt.pix.pixelformat = f->fmt.pix.pixelformat; -- dev->v_fmt.fmt.pix.bytesperline = f->fmt.pix.bytesperline; -- unicam_reset_format(dev); -- -- unicam_dbg(3, dev, "%s %dx%d, mbus_fmt 0x%08X, V4L2 pix 0x%08X.\n", -- __func__, dev->v_fmt.fmt.pix.width, -- dev->v_fmt.fmt.pix.height, mbus_fmt.code, -- dev->v_fmt.fmt.pix.pixelformat); -+ node->fmt = fmt; -+ node->v_fmt.fmt.pix.pixelformat = f->fmt.pix.pixelformat; -+ node->v_fmt.fmt.pix.bytesperline = f->fmt.pix.bytesperline; -+ unicam_reset_format(node); -+ -+ unicam_dbg(3, dev, -+ "%s %dx%d, mbus_fmt 0x%08X, V4L2 pix 0x%08X.\n", -+ __func__, node->v_fmt.fmt.pix.width, -+ node->v_fmt.fmt.pix.height, mbus_fmt.code, -+ node->v_fmt.fmt.pix.pixelformat); - -- *f = dev->v_fmt; -+ *f = node->v_fmt; - - return 0; - } -@@ -1006,8 +1020,9 @@ static int unicam_queue_setup(struct vb2 - unsigned int sizes[], - struct device *alloc_devs[]) - { -- struct unicam_device *dev = vb2_get_drv_priv(vq); -- unsigned int size = dev->v_fmt.fmt.pix.sizeimage; -+ struct unicam_node *node = vb2_get_drv_priv(vq); -+ struct unicam_device *dev = node->dev; -+ unsigned int size = node->v_fmt.fmt.pix.sizeimage; - - if (vq->num_buffers + *nbuffers < 3) - *nbuffers = 3 - vq->num_buffers; -@@ -1029,15 +1044,16 @@ static int unicam_queue_setup(struct vb2 - - static int unicam_buffer_prepare(struct vb2_buffer *vb) - { -- struct unicam_device *dev = vb2_get_drv_priv(vb->vb2_queue); -+ struct unicam_node *node = vb2_get_drv_priv(vb->vb2_queue); -+ struct unicam_device *dev = node->dev; - struct unicam_buffer *buf = container_of(vb, struct unicam_buffer, - vb.vb2_buf); - unsigned long size; - -- if (WARN_ON(!dev->fmt)) -+ if (WARN_ON(!node->fmt)) - return -EINVAL; - -- size = dev->v_fmt.fmt.pix.sizeimage; -+ size = node->v_fmt.fmt.pix.sizeimage; - if (vb2_plane_size(vb, 0) < size) { - unicam_err(dev, "data will not fit into plane (%lu < %lu)\n", - vb2_plane_size(vb, 0), size); -@@ -1050,15 +1066,15 @@ static int unicam_buffer_prepare(struct - - static void unicam_buffer_queue(struct vb2_buffer *vb) - { -- struct unicam_device *dev = vb2_get_drv_priv(vb->vb2_queue); -+ struct unicam_node *node = vb2_get_drv_priv(vb->vb2_queue); - struct unicam_buffer *buf = container_of(vb, struct unicam_buffer, - vb.vb2_buf); -- struct unicam_dmaqueue *dma_queue = &dev->dma_queue; -+ struct unicam_dmaqueue *dma_queue = &node->dma_queue; - unsigned long flags = 0; - -- spin_lock_irqsave(&dev->dma_queue_lock, flags); -+ spin_lock_irqsave(&node->dma_queue_lock, flags); - list_add_tail(&buf->list, &dma_queue->active); -- spin_unlock_irqrestore(&dev->dma_queue_lock, flags); -+ spin_unlock_irqrestore(&node->dma_queue_lock, flags); - } - - static void unicam_set_packing_config(struct unicam_device *dev) -@@ -1066,11 +1082,12 @@ static void unicam_set_packing_config(st - int pack, unpack; - u32 val; - -- if (dev->v_fmt.fmt.pix.pixelformat == dev->fmt->fourcc) { -+ if (dev->node[0].v_fmt.fmt.pix.pixelformat == -+ dev->node[0].fmt->fourcc) { - unpack = UNICAM_PUM_NONE; - pack = UNICAM_PPM_NONE; - } else { -- switch (dev->fmt->depth) { -+ switch (dev->node[0].fmt->depth) { - case 8: - unpack = UNICAM_PUM_UNPACK8; - break; -@@ -1108,17 +1125,17 @@ static void unicam_cfg_image_id(struct u - if (dev->bus_type == V4L2_MBUS_CSI2_DPHY) { - /* CSI2 mode */ - reg_write(cfg, UNICAM_IDI0, -- (dev->virtual_channel << 6) | dev->fmt->csi_dt); -+ (dev->virtual_channel << 6) | dev->node[0].fmt->csi_dt); - } else { - /* CCP2 mode */ -- reg_write(cfg, UNICAM_IDI0, (0x80 | dev->fmt->csi_dt)); -+ reg_write(cfg, UNICAM_IDI0, (0x80 | dev->node[0].fmt->csi_dt)); - } - } - - static void unicam_start_rx(struct unicam_device *dev, unsigned long addr) - { - struct unicam_cfg *cfg = &dev->cfg; -- int line_int_freq = dev->v_fmt.fmt.pix.height >> 2; -+ int line_int_freq = dev->node[0].v_fmt.fmt.pix.height >> 2; - unsigned int i; - u32 val; - -@@ -1266,7 +1283,8 @@ static void unicam_start_rx(struct unica - reg_write(cfg, UNICAM_DAT3, val); - } - -- reg_write(&dev->cfg, UNICAM_IBLS, dev->v_fmt.fmt.pix.bytesperline); -+ reg_write(&dev->cfg, UNICAM_IBLS, -+ dev->node[0].v_fmt.fmt.pix.bytesperline); - unicam_wr_dma_addr(dev, addr); - unicam_set_packing_config(dev); - unicam_cfg_image_id(dev); -@@ -1327,21 +1345,22 @@ static void unicam_disable(struct unicam - - static int unicam_start_streaming(struct vb2_queue *vq, unsigned int count) - { -- struct unicam_device *dev = vb2_get_drv_priv(vq); -- struct unicam_dmaqueue *dma_q = &dev->dma_queue; -+ struct unicam_node *node = vb2_get_drv_priv(vq); -+ struct unicam_device *dev = node->dev; -+ struct unicam_dmaqueue *dma_q = &node->dma_queue; - struct unicam_buffer *buf, *tmp; - unsigned long addr = 0; - unsigned long flags; - int ret; - -- spin_lock_irqsave(&dev->dma_queue_lock, flags); -+ spin_lock_irqsave(&node->dma_queue_lock, flags); - buf = list_entry(dma_q->active.next, struct unicam_buffer, list); -- dev->cur_frm = buf; -- dev->next_frm = buf; -+ node->cur_frm = buf; -+ node->next_frm = buf; - list_del(&buf->list); -- spin_unlock_irqrestore(&dev->dma_queue_lock, flags); -+ spin_unlock_irqrestore(&node->dma_queue_lock, flags); - -- addr = vb2_dma_contig_plane_dma_addr(&dev->cur_frm->vb.vb2_buf, 0); -+ addr = vb2_dma_contig_plane_dma_addr(&node->cur_frm->vb.vb2_buf, 0); - dev->sequence = 0; - - ret = unicam_runtime_get(dev); -@@ -1411,20 +1430,21 @@ err_release_buffers: - list_del(&buf->list); - vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_QUEUED); - } -- if (dev->cur_frm != dev->next_frm) -- vb2_buffer_done(&dev->next_frm->vb.vb2_buf, -+ if (node->cur_frm != node->next_frm) -+ vb2_buffer_done(&node->next_frm->vb.vb2_buf, - VB2_BUF_STATE_QUEUED); -- vb2_buffer_done(&dev->cur_frm->vb.vb2_buf, VB2_BUF_STATE_QUEUED); -- dev->next_frm = NULL; -- dev->cur_frm = NULL; -+ vb2_buffer_done(&node->cur_frm->vb.vb2_buf, VB2_BUF_STATE_QUEUED); -+ node->next_frm = NULL; -+ node->cur_frm = NULL; - - return ret; - } - - static void unicam_stop_streaming(struct vb2_queue *vq) - { -- struct unicam_device *dev = vb2_get_drv_priv(vq); -- struct unicam_dmaqueue *dma_q = &dev->dma_queue; -+ struct unicam_node *node = vb2_get_drv_priv(vq); -+ struct unicam_device *dev = node->dev; -+ struct unicam_dmaqueue *dma_q = &node->dma_queue; - struct unicam_buffer *buf, *tmp; - unsigned long flags; - -@@ -1434,22 +1454,24 @@ static void unicam_stop_streaming(struct - unicam_disable(dev); - - /* Release all active buffers */ -- spin_lock_irqsave(&dev->dma_queue_lock, flags); -+ spin_lock_irqsave(&node->dma_queue_lock, flags); - list_for_each_entry_safe(buf, tmp, &dma_q->active, list) { - list_del(&buf->list); - vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); - } - -- if (dev->cur_frm == dev->next_frm) { -- vb2_buffer_done(&dev->cur_frm->vb.vb2_buf, VB2_BUF_STATE_ERROR); -+ if (node->cur_frm == node->next_frm) { -+ vb2_buffer_done(&node->cur_frm->vb.vb2_buf, -+ VB2_BUF_STATE_ERROR); - } else { -- vb2_buffer_done(&dev->cur_frm->vb.vb2_buf, VB2_BUF_STATE_ERROR); -- vb2_buffer_done(&dev->next_frm->vb.vb2_buf, -+ vb2_buffer_done(&node->cur_frm->vb.vb2_buf, -+ VB2_BUF_STATE_ERROR); -+ vb2_buffer_done(&node->next_frm->vb.vb2_buf, - VB2_BUF_STATE_ERROR); - } -- dev->cur_frm = NULL; -- dev->next_frm = NULL; -- spin_unlock_irqrestore(&dev->dma_queue_lock, flags); -+ node->cur_frm = NULL; -+ node->next_frm = NULL; -+ spin_unlock_irqrestore(&node->dma_queue_lock, flags); - - clk_disable_unprepare(dev->clock); - unicam_runtime_put(dev); -@@ -1458,7 +1480,8 @@ static void unicam_stop_streaming(struct - static int unicam_enum_input(struct file *file, void *priv, - struct v4l2_input *inp) - { -- struct unicam_device *dev = video_drvdata(file); -+ struct unicam_node *node = video_drvdata(file); -+ struct unicam_device *dev = node->dev; - - if (inp->index != 0) - return -EINVAL; -@@ -1506,21 +1529,24 @@ static int unicam_s_input(struct file *f - static int unicam_querystd(struct file *file, void *priv, - v4l2_std_id *std) - { -- struct unicam_device *dev = video_drvdata(file); -+ struct unicam_node *node = video_drvdata(file); -+ struct unicam_device *dev = node->dev; - - return v4l2_subdev_call(dev->sensor, video, querystd, std); - } - - static int unicam_g_std(struct file *file, void *priv, v4l2_std_id *std) - { -- struct unicam_device *dev = video_drvdata(file); -+ struct unicam_node *node = video_drvdata(file); -+ struct unicam_device *dev = node->dev; - - return v4l2_subdev_call(dev->sensor, video, g_std, std); - } - - static int unicam_s_std(struct file *file, void *priv, v4l2_std_id std) - { -- struct unicam_device *dev = video_drvdata(file); -+ struct unicam_node *node = video_drvdata(file); -+ struct unicam_device *dev = node->dev; - int ret; - v4l2_std_id current_std; - -@@ -1531,29 +1557,31 @@ static int unicam_s_std(struct file *fil - if (std == current_std) - return 0; - -- if (vb2_is_busy(&dev->buffer_queue)) -+ if (vb2_is_busy(&node->buffer_queue)) - return -EBUSY; - - ret = v4l2_subdev_call(dev->sensor, video, s_std, std); - - /* Force recomputation of bytesperline */ -- dev->v_fmt.fmt.pix.bytesperline = 0; -+ node->v_fmt.fmt.pix.bytesperline = 0; - -- unicam_reset_format(dev); -+ unicam_reset_format(node); - - return ret; - } - - static int unicam_s_edid(struct file *file, void *priv, struct v4l2_edid *edid) - { -- struct unicam_device *dev = video_drvdata(file); -+ struct unicam_node *node = video_drvdata(file); -+ struct unicam_device *dev = node->dev; - - return v4l2_subdev_call(dev->sensor, pad, set_edid, edid); - } - - static int unicam_g_edid(struct file *file, void *priv, struct v4l2_edid *edid) - { -- struct unicam_device *dev = video_drvdata(file); -+ struct unicam_node *node = video_drvdata(file); -+ struct unicam_device *dev = node->dev; - - return v4l2_subdev_call(dev->sensor, pad, get_edid, edid); - } -@@ -1561,7 +1589,8 @@ static int unicam_g_edid(struct file *fi - static int unicam_enum_framesizes(struct file *file, void *priv, - struct v4l2_frmsizeenum *fsize) - { -- struct unicam_device *dev = video_drvdata(file); -+ struct unicam_node *node = video_drvdata(file); -+ struct unicam_device *dev = node->dev; - const struct unicam_fmt *fmt; - struct v4l2_subdev_frame_size_enum fse; - int ret; -@@ -1596,7 +1625,8 @@ static int unicam_enum_framesizes(struct - static int unicam_enum_frameintervals(struct file *file, void *priv, - struct v4l2_frmivalenum *fival) - { -- struct unicam_device *dev = video_drvdata(file); -+ struct unicam_node *node = video_drvdata(file); -+ struct unicam_device *dev = node->dev; - const struct unicam_fmt *fmt; - struct v4l2_subdev_frame_interval_enum fie = { - .index = fival->index, -@@ -1624,14 +1654,16 @@ static int unicam_enum_frameintervals(st - - static int unicam_g_parm(struct file *file, void *fh, struct v4l2_streamparm *a) - { -- struct unicam_device *dev = video_drvdata(file); -+ struct unicam_node *node = video_drvdata(file); -+ struct unicam_device *dev = node->dev; - - return v4l2_g_parm_cap(video_devdata(file), dev->sensor, a); - } - - static int unicam_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a) - { -- struct unicam_device *dev = video_drvdata(file); -+ struct unicam_node *node = video_drvdata(file); -+ struct unicam_device *dev = node->dev; - - return v4l2_s_parm_cap(video_devdata(file), dev->sensor, a); - } -@@ -1639,7 +1671,8 @@ static int unicam_s_parm(struct file *fi - static int unicam_g_dv_timings(struct file *file, void *priv, - struct v4l2_dv_timings *timings) - { -- struct unicam_device *dev = video_drvdata(file); -+ struct unicam_node *node = video_drvdata(file); -+ struct unicam_device *dev = node->dev; - - return v4l2_subdev_call(dev->sensor, video, g_dv_timings, timings); - } -@@ -1647,7 +1680,8 @@ static int unicam_g_dv_timings(struct fi - static int unicam_s_dv_timings(struct file *file, void *priv, - struct v4l2_dv_timings *timings) - { -- struct unicam_device *dev = video_drvdata(file); -+ struct unicam_node *node = video_drvdata(file); -+ struct unicam_device *dev = node->dev; - struct v4l2_dv_timings current_timings; - int ret; - -@@ -1657,15 +1691,15 @@ static int unicam_s_dv_timings(struct fi - if (v4l2_match_dv_timings(timings, ¤t_timings, 0, false)) - return 0; - -- if (vb2_is_busy(&dev->buffer_queue)) -+ if (vb2_is_busy(&node->buffer_queue)) - return -EBUSY; - - ret = v4l2_subdev_call(dev->sensor, video, s_dv_timings, timings); - - /* Force recomputation of bytesperline */ -- dev->v_fmt.fmt.pix.bytesperline = 0; -+ node->v_fmt.fmt.pix.bytesperline = 0; - -- unicam_reset_format(dev); -+ unicam_reset_format(node); - - return ret; - } -@@ -1673,7 +1707,8 @@ static int unicam_s_dv_timings(struct fi - static int unicam_query_dv_timings(struct file *file, void *priv, - struct v4l2_dv_timings *timings) - { -- struct unicam_device *dev = video_drvdata(file); -+ struct unicam_node *node = video_drvdata(file); -+ struct unicam_device *dev = node->dev; - - return v4l2_subdev_call(dev->sensor, video, query_dv_timings, timings); - } -@@ -1681,7 +1716,8 @@ static int unicam_query_dv_timings(struc - static int unicam_enum_dv_timings(struct file *file, void *priv, - struct v4l2_enum_dv_timings *timings) - { -- struct unicam_device *dev = video_drvdata(file); -+ struct unicam_node *node = video_drvdata(file); -+ struct unicam_device *dev = node->dev; - - return v4l2_subdev_call(dev->sensor, pad, enum_dv_timings, timings); - } -@@ -1689,7 +1725,8 @@ static int unicam_enum_dv_timings(struct - static int unicam_dv_timings_cap(struct file *file, void *priv, - struct v4l2_dv_timings_cap *cap) - { -- struct unicam_device *dev = video_drvdata(file); -+ struct unicam_node *node = video_drvdata(file); -+ struct unicam_device *dev = node->dev; - - return v4l2_subdev_call(dev->sensor, pad, dv_timings_cap, cap); - } -@@ -1707,7 +1744,8 @@ static int unicam_subscribe_event(struct - - static int unicam_log_status(struct file *file, void *fh) - { -- struct unicam_device *dev = video_drvdata(file); -+ struct unicam_node *node = video_drvdata(file); -+ struct unicam_device *dev = node->dev; - struct unicam_cfg *cfg = &dev->cfg; - u32 reg; - -@@ -1716,10 +1754,10 @@ static int unicam_log_status(struct file - - unicam_info(dev, "-----Receiver status-----\n"); - unicam_info(dev, "V4L2 width/height: %ux%u\n", -- dev->v_fmt.fmt.pix.width, dev->v_fmt.fmt.pix.height); -- unicam_info(dev, "Mediabus format: %08x\n", dev->fmt->code); -+ node->v_fmt.fmt.pix.width, node->v_fmt.fmt.pix.height); -+ unicam_info(dev, "Mediabus format: %08x\n", node->fmt->code); - unicam_info(dev, "V4L2 format: %08x\n", -- dev->v_fmt.fmt.pix.pixelformat); -+ node->v_fmt.fmt.pix.pixelformat); - reg = reg_read(&dev->cfg, UNICAM_IPIPE); - unicam_info(dev, "Unpacking/packing: %u / %u\n", - get_field(reg, UNICAM_PUM_MASK), -@@ -1744,7 +1782,7 @@ static void unicam_notify(struct v4l2_su - - switch (notification) { - case V4L2_DEVICE_NOTIFY_EVENT: -- v4l2_event_queue(&dev->video_dev, arg); -+ v4l2_event_queue(&dev->node[0].video_dev, arg); - break; - default: - break; -@@ -1767,10 +1805,11 @@ static const struct vb2_ops unicam_video - */ - static int unicam_open(struct file *file) - { -- struct unicam_device *dev = video_drvdata(file); -+ struct unicam_node *node = video_drvdata(file); -+ struct unicam_device *dev = node->dev; - int ret; - -- mutex_lock(&dev->lock); -+ mutex_lock(&node->lock); - - ret = v4l2_fh_open(file); - if (ret) { -@@ -1790,18 +1829,19 @@ static int unicam_open(struct file *file - ret = 0; - - unlock: -- mutex_unlock(&dev->lock); -+ mutex_unlock(&node->lock); - return ret; - } - - static int unicam_release(struct file *file) - { -- struct unicam_device *dev = video_drvdata(file); -+ struct unicam_node *node = video_drvdata(file); -+ struct unicam_device *dev = node->dev; - struct v4l2_subdev *sd = dev->sensor; - bool fh_singular; - int ret; - -- mutex_lock(&dev->lock); -+ mutex_lock(&node->lock); - - fh_singular = v4l2_fh_is_singular_file(file); - -@@ -1810,7 +1850,7 @@ static int unicam_release(struct file *f - if (fh_singular) - v4l2_subdev_call(sd, core, s_power, 0); - -- mutex_unlock(&dev->lock); -+ mutex_unlock(&node->lock); - - return ret; - } -@@ -1892,7 +1932,8 @@ unicam_async_bound(struct v4l2_async_not - return 0; - } - --static int unicam_probe_complete(struct unicam_device *unicam) -+static int register_node(struct unicam_device *unicam, struct unicam_node *node, -+ enum v4l2_buf_type type, int pad_id) - { - struct video_device *vdev; - struct vb2_queue *q; -@@ -1900,15 +1941,7 @@ static int unicam_probe_complete(struct - const struct unicam_fmt *fmt; - int ret; - -- v4l2_set_subdev_hostdata(unicam->sensor, unicam); -- -- unicam->v4l2_dev.notify = unicam_notify; -- -- unicam->sensor_config = v4l2_subdev_alloc_pad_config(unicam->sensor); -- if (!unicam->sensor_config) -- return -ENOMEM; -- -- ret = __subdev_get_format(unicam, &mbus_fmt); -+ ret = __subdev_get_format(unicam, &mbus_fmt, pad_id); - if (ret) { - unicam_err(unicam, "Failed to get_format - ret %d\n", ret); - return ret; -@@ -1938,14 +1971,15 @@ static int unicam_probe_complete(struct - return -EINVAL; - } - -- unicam->fmt = fmt; -+ node->pad_id = pad_id; -+ node->fmt = fmt; - if (fmt->fourcc) -- unicam->v_fmt.fmt.pix.pixelformat = fmt->fourcc; -+ node->v_fmt.fmt.pix.pixelformat = fmt->fourcc; - else -- unicam->v_fmt.fmt.pix.pixelformat = fmt->repacked_fourcc; -+ node->v_fmt.fmt.pix.pixelformat = fmt->repacked_fourcc; - - /* Read current subdev format */ -- unicam_reset_format(unicam); -+ unicam_reset_format(node); - - if (v4l2_subdev_has_op(unicam->sensor, video, s_std)) { - v4l2_std_id tvnorms; -@@ -1962,27 +1996,30 @@ static int unicam_probe_complete(struct - g_tvnorms, &tvnorms); - if (WARN_ON(ret)) - return -EINVAL; -- unicam->video_dev.tvnorms |= tvnorms; -+ node->video_dev.tvnorms |= tvnorms; - } - -- spin_lock_init(&unicam->dma_queue_lock); -- mutex_init(&unicam->lock); -+ spin_lock_init(&node->dma_queue_lock); -+ mutex_init(&node->lock); - -- /* Add controls from the subdevice */ -- ret = v4l2_ctrl_add_handler(&unicam->ctrl_handler, -- unicam->sensor->ctrl_handler, NULL, true); -- if (ret < 0) -- return ret; -+ if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { -+ /* Add controls from the subdevice */ -+ ret = v4l2_ctrl_add_handler(&node->ctrl_handler, -+ unicam->sensor->ctrl_handler, NULL, -+ true); -+ if (ret < 0) -+ return ret; -+ } - -- q = &unicam->buffer_queue; -- q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; -+ q = &node->buffer_queue; -+ q->type = type; - q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_READ; -- q->drv_priv = unicam; -+ q->drv_priv = node; - q->ops = &unicam_video_qops; - q->mem_ops = &vb2_dma_contig_memops; - q->buf_struct_size = sizeof(struct unicam_buffer); - q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; -- q->lock = &unicam->lock; -+ q->lock = &node->lock; - q->min_buffers_needed = 2; - q->dev = &unicam->pdev->dev; - -@@ -1992,9 +2029,9 @@ static int unicam_probe_complete(struct - return ret; - } - -- INIT_LIST_HEAD(&unicam->dma_queue.active); -+ INIT_LIST_HEAD(&node->dma_queue.active); - -- vdev = &unicam->video_dev; -+ vdev = &node->video_dev; - strlcpy(vdev->name, UNICAM_MODULE_NAME, sizeof(vdev->name)); - vdev->release = video_device_release_empty; - vdev->fops = &unicam_fops; -@@ -2002,69 +2039,113 @@ static int unicam_probe_complete(struct - vdev->v4l2_dev = &unicam->v4l2_dev; - vdev->vfl_dir = VFL_DIR_RX; - vdev->queue = q; -- vdev->lock = &unicam->lock; -+ vdev->lock = &node->lock; - vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | - V4L2_CAP_READWRITE; -- - /* If the source has no controls then remove our ctrl handler. */ -- if (list_empty(&unicam->ctrl_handler.ctrls)) -+ if (list_empty(&node->ctrl_handler.ctrls)) - unicam->v4l2_dev.ctrl_handler = NULL; - -- video_set_drvdata(vdev, unicam); -+ node->dev = unicam; -+ video_set_drvdata(vdev, node); - vdev->entity.flags |= MEDIA_ENT_FL_DEFAULT; - - if (!v4l2_subdev_has_op(unicam->sensor, video, s_std)) { -- v4l2_disable_ioctl(&unicam->video_dev, VIDIOC_S_STD); -- v4l2_disable_ioctl(&unicam->video_dev, VIDIOC_G_STD); -- v4l2_disable_ioctl(&unicam->video_dev, VIDIOC_ENUMSTD); -+ v4l2_disable_ioctl(&node->video_dev, VIDIOC_S_STD); -+ v4l2_disable_ioctl(&node->video_dev, VIDIOC_G_STD); -+ v4l2_disable_ioctl(&node->video_dev, VIDIOC_ENUMSTD); - } - if (!v4l2_subdev_has_op(unicam->sensor, video, querystd)) -- v4l2_disable_ioctl(&unicam->video_dev, VIDIOC_QUERYSTD); -+ v4l2_disable_ioctl(&node->video_dev, VIDIOC_QUERYSTD); - if (!v4l2_subdev_has_op(unicam->sensor, video, s_dv_timings)) { -- v4l2_disable_ioctl(&unicam->video_dev, VIDIOC_S_EDID); -- v4l2_disable_ioctl(&unicam->video_dev, VIDIOC_G_EDID); -- v4l2_disable_ioctl(&unicam->video_dev, VIDIOC_DV_TIMINGS_CAP); -- v4l2_disable_ioctl(&unicam->video_dev, VIDIOC_G_DV_TIMINGS); -- v4l2_disable_ioctl(&unicam->video_dev, VIDIOC_S_DV_TIMINGS); -- v4l2_disable_ioctl(&unicam->video_dev, VIDIOC_ENUM_DV_TIMINGS); -- v4l2_disable_ioctl(&unicam->video_dev, VIDIOC_QUERY_DV_TIMINGS); -+ v4l2_disable_ioctl(&node->video_dev, VIDIOC_S_EDID); -+ v4l2_disable_ioctl(&node->video_dev, VIDIOC_G_EDID); -+ v4l2_disable_ioctl(&node->video_dev, VIDIOC_DV_TIMINGS_CAP); -+ v4l2_disable_ioctl(&node->video_dev, VIDIOC_G_DV_TIMINGS); -+ v4l2_disable_ioctl(&node->video_dev, VIDIOC_S_DV_TIMINGS); -+ v4l2_disable_ioctl(&node->video_dev, VIDIOC_ENUM_DV_TIMINGS); -+ v4l2_disable_ioctl(&node->video_dev, VIDIOC_QUERY_DV_TIMINGS); - } - if (!v4l2_subdev_has_op(unicam->sensor, pad, enum_frame_interval)) -- v4l2_disable_ioctl(&unicam->video_dev, -+ v4l2_disable_ioctl(&node->video_dev, - VIDIOC_ENUM_FRAMEINTERVALS); - if (!v4l2_subdev_has_op(unicam->sensor, video, g_frame_interval)) -- v4l2_disable_ioctl(&unicam->video_dev, VIDIOC_G_PARM); -+ v4l2_disable_ioctl(&node->video_dev, VIDIOC_G_PARM); - if (!v4l2_subdev_has_op(unicam->sensor, video, s_frame_interval)) -- v4l2_disable_ioctl(&unicam->video_dev, VIDIOC_S_PARM); -+ v4l2_disable_ioctl(&node->video_dev, VIDIOC_S_PARM); - - if (!v4l2_subdev_has_op(unicam->sensor, pad, enum_frame_size)) -- v4l2_disable_ioctl(&unicam->video_dev, VIDIOC_ENUM_FRAMESIZES); -+ v4l2_disable_ioctl(&node->video_dev, VIDIOC_ENUM_FRAMESIZES); - - ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1); - if (ret) { - unicam_err(unicam, "Unable to register video device.\n"); - return ret; - } -+ node->registered = true; - -- ret = v4l2_device_register_ro_subdev_nodes(&unicam->v4l2_dev); -+ ret = media_create_pad_link(&unicam->sensor->entity, -+ 0, &node->video_dev.entity, 0, -+ MEDIA_LNK_FL_ENABLED | -+ MEDIA_LNK_FL_IMMUTABLE); -+ if (ret) -+ unicam_err(unicam, "Unable to create pad links.\n"); -+ -+ return ret; -+} -+ -+static void unregister_nodes(struct unicam_device *unicam) -+{ -+ if (unicam->node[0].registered) { -+ video_unregister_device(&unicam->node[0].video_dev); -+ unicam->node[0].registered = false; -+ } -+ if (unicam->node[1].registered) { -+ video_unregister_device(&unicam->node[1].video_dev); -+ unicam->node[1].registered = false; -+ } -+} -+ -+static int unicam_probe_complete(struct unicam_device *unicam) -+{ -+ int ret; -+ -+ v4l2_set_subdev_hostdata(unicam->sensor, unicam); -+ -+ unicam->v4l2_dev.notify = unicam_notify; -+ -+ unicam->sensor_config = v4l2_subdev_alloc_pad_config(unicam->sensor); -+ if (!unicam->sensor_config) -+ return -ENOMEM; -+ -+ ret = register_node(unicam, &unicam->node[0], -+ V4L2_BUF_TYPE_VIDEO_CAPTURE, 0); - if (ret) { -- unicam_err(unicam, -- "Unable to register subdev nodes.\n"); -- video_unregister_device(&unicam->video_dev); -- return ret; -+ unicam_err(unicam, "Unable to register subdev node 0.\n"); -+ goto unregister; -+ } -+ if (unicam->sensor->entity.num_pads >= 2) { -+ ret = register_node(unicam, &unicam->node[1], -+ V4L2_BUF_TYPE_META_CAPTURE, 1); -+ if (ret) { -+ unicam_err(unicam, -+ "Unable to register subdev node 1.\n"); -+ goto unregister; -+ } - } - -- ret = media_create_pad_link(&unicam->sensor->entity, 0, -- &unicam->video_dev.entity, 0, -- MEDIA_LNK_FL_ENABLED | -- MEDIA_LNK_FL_IMMUTABLE); -+ ret = v4l2_device_register_ro_subdev_nodes(&unicam->v4l2_dev); - if (ret) { -- unicam_err(unicam, "Unable to create pad links.\n"); -- video_unregister_device(&unicam->video_dev); -- return ret; -+ unicam_err(unicam, "Unable to register subdev nodes.\n"); -+ goto unregister; - } - - return 0; -+ -+unregister: -+ unregister_nodes(unicam); -+ -+ return ret; - } - - static int unicam_async_complete(struct v4l2_async_notifier *notifier) -@@ -2274,7 +2355,8 @@ static int unicam_probe(struct platform_ - pdev->dev.driver->name, dev_name(&pdev->dev)); - unicam->mdev.hw_revision = 1; - -- media_entity_pads_init(&unicam->video_dev.entity, 1, &unicam->pad); -+ media_entity_pads_init(&unicam->node[0].video_dev.entity, 1, -+ &unicam->node[0].pad); - media_device_init(&unicam->mdev); - - unicam->v4l2_dev.mdev = &unicam->mdev; -@@ -2294,7 +2376,7 @@ static int unicam_probe(struct platform_ - } - - /* Reserve space for the controls */ -- hdl = &unicam->ctrl_handler; -+ hdl = &unicam->node[0].ctrl_handler; - ret = v4l2_ctrl_handler_init(hdl, 16); - if (ret < 0) - goto media_unregister; -@@ -2335,9 +2417,9 @@ static int unicam_remove(struct platform - pm_runtime_disable(&pdev->dev); - - v4l2_async_notifier_unregister(&unicam->notifier); -- v4l2_ctrl_handler_free(&unicam->ctrl_handler); -+ v4l2_ctrl_handler_free(&unicam->node[0].ctrl_handler); - v4l2_device_unregister(&unicam->v4l2_dev); -- video_unregister_device(&unicam->video_dev); -+ unregister_nodes(unicam); - if (unicam->sensor_config) - v4l2_subdev_free_pad_config(unicam->sensor_config); - media_device_unregister(&unicam->mdev); diff --git a/target/linux/bcm27xx/patches-5.15/950-0214-media-bcm2835-unicam-Add-embedded-data-node.patch b/target/linux/bcm27xx/patches-5.15/950-0214-media-bcm2835-unicam-Add-embedded-data-node.patch deleted file mode 100644 index 84f80b555..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0214-media-bcm2835-unicam-Add-embedded-data-node.patch +++ /dev/null @@ -1,1170 +0,0 @@ -From 85fc685aabde594162e398c048b901d31332c2e6 Mon Sep 17 00:00:00 2001 -From: Naushir Patuck -Date: Thu, 16 Apr 2020 11:35:41 +0100 -Subject: [PATCH] media: bcm2835-unicam: Add embedded data node. - -This patch adds a new node in the bcm2835-unicam driver to support -CSI-2 embedded data streams. The subdevice is queried to see if -embedded data is available from the sensor. - -Signed-off-by: Naushir Patuck ---- - .../media/platform/bcm2835/bcm2835-unicam.c | 667 +++++++++++++----- - 1 file changed, 474 insertions(+), 193 deletions(-) - ---- a/drivers/media/platform/bcm2835/bcm2835-unicam.c -+++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c -@@ -109,8 +109,15 @@ MODULE_PARM_DESC(debug, "Debug level 0-3 - /* Define a nominal minimum image size */ - #define MIN_WIDTH 16 - #define MIN_HEIGHT 16 --/* Maximum number of simulataneous streams Uncaim can handle. */ --#define MAX_NODES 2 -+/* Default size of the embedded buffer */ -+#define UNICAM_EMBEDDED_SIZE 8192 -+ -+enum pad_types { -+ IMAGE_PAD, -+ METADATA_PAD, -+ MAX_NODES -+}; -+ - /* - * struct unicam_fmt - Unicam media bus format information - * @pixelformat: V4L2 pixel format FCC identifier. 0 if n/a. -@@ -327,6 +334,12 @@ static const struct unicam_fmt formats[] - .depth = 12, - .csi_dt = 0x2c, - }, -+ /* Embedded data format */ -+ { -+ .fourcc = V4L2_META_FMT_SENSOR_DATA, -+ .code = MEDIA_BUS_FMT_SENSOR_DATA, -+ .depth = 8, -+ } - }; - - struct unicam_dmaqueue { -@@ -348,7 +361,9 @@ struct unicam_cfg { - #define MAX_POSSIBLE_PIX_FMTS (ARRAY_SIZE(formats)) - - struct unicam_node { -- bool registered; -+ int registered; -+ int open; -+ int streaming; - unsigned int pad_id; - /* Pointer pointing to current v4l2_buffer */ - struct unicam_buffer *cur_frm; -@@ -374,6 +389,7 @@ struct unicam_node { - struct unicam_device *dev; - struct media_pad pad; - struct v4l2_ctrl_handler ctrl_handler; -+ unsigned int embedded_lines; - }; - - struct unicam_device { -@@ -401,8 +417,6 @@ struct unicam_device { - struct v4l2_subdev *sensor; - /* Pad config for the sensor */ - struct v4l2_subdev_pad_config *sensor_config; -- /* current input at the sub device */ -- int current_input; - - unsigned int virtual_channel; - enum v4l2_mbus_type bus_type; -@@ -413,10 +427,7 @@ struct unicam_device { - unsigned int bus_flags; - unsigned int max_data_lanes; - unsigned int active_data_lanes; -- -- struct v4l2_rect crop; -- /* Flag to denote that we are processing buffers */ -- int streaming; -+ bool sensor_embedded_data; - - struct unicam_node node[MAX_NODES]; - }; -@@ -488,6 +499,7 @@ static int check_mbus_format(struct unic - for (i = 0; !ret && i < MAX_ENUM_MBUS_CODE; i++) { - memset(&mbus_code, 0, sizeof(mbus_code)); - mbus_code.index = i; -+ mbus_code.pad = IMAGE_PAD; - mbus_code.which = V4L2_SUBDEV_FORMAT_ACTIVE; - - ret = v4l2_subdev_call(dev->sensor, pad, enum_mbus_code, -@@ -552,10 +564,11 @@ static int __subdev_get_format(struct un - } - - static int __subdev_set_format(struct unicam_device *dev, -- struct v4l2_mbus_framefmt *fmt) -+ struct v4l2_mbus_framefmt *fmt, int pad_id) - { - struct v4l2_subdev_format sd_fmt = { - .which = V4L2_SUBDEV_FORMAT_ACTIVE, -+ .pad = pad_id - }; - int ret; - -@@ -566,8 +579,12 @@ static int __subdev_set_format(struct un - if (ret < 0) - return ret; - -- unicam_dbg(1, dev, "%s %dx%d code:%04x\n", __func__, -- fmt->width, fmt->height, fmt->code); -+ if (pad_id == IMAGE_PAD) -+ unicam_dbg(1, dev, "%s %dx%d code:%04x\n", __func__, fmt->width, -+ fmt->height, fmt->code); -+ else -+ unicam_dbg(1, dev, "%s Embedded data code:%04x\n", __func__, -+ sd_fmt.format.code); - - return 0; - } -@@ -609,46 +626,70 @@ static int unicam_reset_format(struct un - struct v4l2_mbus_framefmt mbus_fmt; - int ret; - -- ret = __subdev_get_format(dev, &mbus_fmt, node->pad_id); -- if (ret) { -- unicam_err(dev, "Failed to get_format - ret %d\n", ret); -- return ret; -- } -+ if (dev->sensor_embedded_data || node->pad_id != METADATA_PAD) { -+ ret = __subdev_get_format(dev, &mbus_fmt, node->pad_id); -+ if (ret) { -+ unicam_err(dev, "Failed to get_format - ret %d\n", ret); -+ return ret; -+ } - -- if (mbus_fmt.code != dev->node[0].fmt->code) { -- unicam_err(dev, "code mismatch - fmt->code %08x, mbus_fmt.code %08x\n", -- dev->node[0].fmt->code, mbus_fmt.code); -- return ret; -+ if (mbus_fmt.code != node->fmt->code) { -+ unicam_err(dev, "code mismatch - fmt->code %08x, mbus_fmt.code %08x\n", -+ node->fmt->code, mbus_fmt.code); -+ return ret; -+ } - } - -- v4l2_fill_pix_format(&dev->node[0].v_fmt.fmt.pix, &mbus_fmt); -- dev->node[0].v_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; -- -- unicam_calc_format_size_bpl(dev, dev->node[0].fmt, &dev->node[0].v_fmt); -- -- dev->node[0].m_fmt = mbus_fmt; -+ if (node->pad_id == IMAGE_PAD) { -+ v4l2_fill_pix_format(&node->v_fmt.fmt.pix, &mbus_fmt); -+ node->v_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; -+ unicam_calc_format_size_bpl(dev, node->fmt, &node->v_fmt); -+ } else { -+ node->v_fmt.type = V4L2_BUF_TYPE_META_CAPTURE; -+ node->v_fmt.fmt.meta.dataformat = V4L2_META_FMT_SENSOR_DATA; -+ if (dev->sensor_embedded_data) { -+ node->v_fmt.fmt.meta.buffersize = -+ mbus_fmt.width * mbus_fmt.height; -+ node->embedded_lines = mbus_fmt.height; -+ } else { -+ node->v_fmt.fmt.meta.buffersize = UNICAM_EMBEDDED_SIZE; -+ node->embedded_lines = 1; -+ } -+ } - -+ node->m_fmt = mbus_fmt; - return 0; - } - --static void unicam_wr_dma_addr(struct unicam_device *dev, dma_addr_t dmaaddr) -+static void unicam_wr_dma_addr(struct unicam_device *dev, dma_addr_t dmaaddr, -+ int pad_id) - { -+ dma_addr_t endaddr; -+ - /* - * dmaaddr should be a 32-bit address with the top two bits set to 0x3 - * to signify uncached access through the Videocore memory controller. - */ - BUG_ON((dmaaddr >> 30) != 0x3); - -- reg_write(&dev->cfg, UNICAM_IBSA0, dmaaddr); -- reg_write(&dev->cfg, UNICAM_IBEA0, -- dmaaddr + dev->node[0].v_fmt.fmt.pix.sizeimage); -+ if (pad_id == IMAGE_PAD) { -+ endaddr = dmaaddr + -+ dev->node[IMAGE_PAD].v_fmt.fmt.pix.sizeimage; -+ reg_write(&dev->cfg, UNICAM_IBSA0, dmaaddr); -+ reg_write(&dev->cfg, UNICAM_IBEA0, endaddr); -+ } else { -+ endaddr = dmaaddr + -+ dev->node[METADATA_PAD].v_fmt.fmt.meta.buffersize; -+ reg_write(&dev->cfg, UNICAM_DBSA0, dmaaddr); -+ reg_write(&dev->cfg, UNICAM_DBEA0, endaddr); -+ } - } - - static inline unsigned int unicam_get_lines_done(struct unicam_device *dev) - { - dma_addr_t start_addr, cur_addr; -- unsigned int stride = dev->node[0].v_fmt.fmt.pix.bytesperline; -- struct unicam_buffer *frm = dev->node[0].cur_frm; -+ unsigned int stride = dev->node[IMAGE_PAD].v_fmt.fmt.pix.bytesperline; -+ struct unicam_buffer *frm = dev->node[IMAGE_PAD].cur_frm; - - if (!frm) - return 0; -@@ -658,27 +699,51 @@ static inline unsigned int unicam_get_li - return (unsigned int)(cur_addr - start_addr) / stride; - } - --static inline void unicam_schedule_next_buffer(struct unicam_device *dev) -+static inline void unicam_schedule_next_buffer(struct unicam_node *node) - { -- struct unicam_dmaqueue *dma_q = &dev->node[0].dma_queue; -+ struct unicam_device *dev = node->dev; -+ struct unicam_dmaqueue *dma_q = &node->dma_queue; - struct unicam_buffer *buf; - dma_addr_t addr; - - buf = list_entry(dma_q->active.next, struct unicam_buffer, list); -- dev->node[0].next_frm = buf; -+ node->next_frm = buf; - list_del(&buf->list); - - addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0); -- unicam_wr_dma_addr(dev, addr); -+ unicam_wr_dma_addr(dev, addr, node->pad_id); - } - --static inline void unicam_process_buffer_complete(struct unicam_device *dev) -+static inline void unicam_process_buffer_complete(struct unicam_node *node, -+ unsigned int sequence) - { -- dev->node[0].cur_frm->vb.field = dev->node[0].m_fmt.field; -- dev->node[0].cur_frm->vb.sequence = dev->sequence++; -+ node->cur_frm->vb.field = node->m_fmt.field; -+ node->cur_frm->vb.sequence = sequence; -+ -+ vb2_buffer_done(&node->cur_frm->vb.vb2_buf, VB2_BUF_STATE_DONE); -+ node->cur_frm = node->next_frm; -+} - -- vb2_buffer_done(&dev->node[0].cur_frm->vb.vb2_buf, VB2_BUF_STATE_DONE); -- dev->node[0].cur_frm = dev->node[0].next_frm; -+static int unicam_num_nodes_streaming(struct unicam_device *dev) -+{ -+ return dev->node[IMAGE_PAD].streaming + -+ dev->node[METADATA_PAD].streaming; -+} -+ -+static int unicam_all_nodes_streaming(struct unicam_device *dev) -+{ -+ int ret; -+ -+ ret = dev->node[IMAGE_PAD].open && dev->node[IMAGE_PAD].streaming; -+ ret &= !dev->node[METADATA_PAD].open || -+ dev->node[METADATA_PAD].streaming; -+ return ret; -+} -+ -+static int unicam_all_nodes_disabled(struct unicam_device *dev) -+{ -+ return !dev->node[IMAGE_PAD].streaming && -+ !dev->node[METADATA_PAD].streaming; - } - - /* -@@ -693,10 +758,12 @@ static irqreturn_t unicam_isr(int irq, v - { - struct unicam_device *unicam = (struct unicam_device *)dev; - struct unicam_cfg *cfg = &unicam->cfg; -- struct unicam_dmaqueue *dma_q = &unicam->node[0].dma_queue; - unsigned int lines_done = unicam_get_lines_done(dev); - unsigned int sequence = unicam->sequence; -+ int num_nodes_streaming = unicam_num_nodes_streaming(dev); - int ista, sta; -+ u64 ts; -+ int i; - - /* - * Don't service interrupts if not streaming. -@@ -704,7 +771,7 @@ static irqreturn_t unicam_isr(int irq, v - * peripheral without the kernel knowing (that - * shouldn't happen, but causes issues if it does). - */ -- if (!unicam->streaming) -+ if (unicam_all_nodes_disabled(unicam)) - return IRQ_HANDLED; - - sta = reg_read(cfg, UNICAM_STA); -@@ -726,9 +793,12 @@ static irqreturn_t unicam_isr(int irq, v - * Timestamp is to be when the first data byte was captured, - * aka frame start. - */ -- if (unicam->node[0].cur_frm) -- unicam->node[0].cur_frm->vb.vb2_buf.timestamp = -- ktime_get_ns(); -+ ts = ktime_get_ns(); -+ for (i = 0; i < num_nodes_streaming; i++) { -+ if (unicam->node[i].cur_frm) -+ unicam->node[i].cur_frm->vb.vb2_buf.timestamp = -+ ts; -+ } - } - if (ista & UNICAM_FEI || sta & UNICAM_PI0) { - /* -@@ -736,9 +806,13 @@ static irqreturn_t unicam_isr(int irq, v - * stop the peripheral. Overwrite the frame we've just - * captured instead. - */ -- if (unicam->node[0].cur_frm && -- unicam->node[0].cur_frm != unicam->node[0].next_frm) -- unicam_process_buffer_complete(unicam); -+ for (i = 0; i < num_nodes_streaming; i++) { -+ if (unicam->node[i].cur_frm && -+ unicam->node[i].cur_frm != unicam->node[i].next_frm) -+ unicam_process_buffer_complete(&unicam->node[i], -+ sequence); -+ } -+ unicam->sequence++; - } - - /* Cannot swap buffer at frame end, there may be a race condition -@@ -746,11 +820,13 @@ static irqreturn_t unicam_isr(int irq, v - * already started. - */ - if (ista & (UNICAM_FSI | UNICAM_LCI) && !(ista & UNICAM_FEI)) { -- spin_lock(&unicam->node[0].dma_queue_lock); -- if (!list_empty(&dma_q->active) && -- unicam->node[0].cur_frm == unicam->node[0].next_frm) -- unicam_schedule_next_buffer(unicam); -- spin_unlock(&unicam->node[0].dma_queue_lock); -+ for (i = 0; i < num_nodes_streaming; i++) { -+ spin_lock(&unicam->node[i].dma_queue_lock); -+ if (!list_empty(&unicam->node[i].dma_queue.active) && -+ unicam->node[i].cur_frm == unicam->node[i].next_frm) -+ unicam_schedule_next_buffer(&unicam->node[i]); -+ spin_unlock(&unicam->node[i].dma_queue_lock); -+ } - } - - if (reg_read(&unicam->cfg, UNICAM_ICTL) & UNICAM_FCM) { -@@ -773,6 +849,15 @@ static int unicam_querycap(struct file * - snprintf(cap->bus_info, sizeof(cap->bus_info), - "platform:%s", dev->v4l2_dev.name); - -+ cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | -+ V4L2_CAP_READWRITE | V4L2_CAP_DEVICE_CAPS | -+ V4L2_CAP_META_CAPTURE; -+ -+ if (node->pad_id == IMAGE_PAD) -+ cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; -+ else -+ cap->device_caps = V4L2_CAP_META_CAPTURE | V4L2_CAP_STREAMING; -+ - return 0; - } - -@@ -787,9 +872,14 @@ static int unicam_enum_fmt_vid_cap(struc - int ret = 0; - int i; - -+ if (node->pad_id == METADATA_PAD) -+ return -EINVAL; -+ - for (i = 0; !ret && i < MAX_ENUM_MBUS_CODE; i++) { - memset(&mbus_code, 0, sizeof(mbus_code)); - mbus_code.index = i; -+ mbus_code.pad = IMAGE_PAD; -+ mbus_code.which = V4L2_SUBDEV_FORMAT_ACTIVE; - - ret = v4l2_subdev_call(dev->sensor, pad, enum_mbus_code, - NULL, &mbus_code); -@@ -827,6 +917,9 @@ static int unicam_g_fmt_vid_cap(struct f - { - struct unicam_node *node = video_drvdata(file); - -+ if (node->pad_id == METADATA_PAD) -+ return -EINVAL; -+ - *f = node->v_fmt; - - return 0; -@@ -843,6 +936,9 @@ const struct unicam_fmt *get_first_suppo - for (j = 0; ret != -EINVAL && ret != -ENOIOCTLCMD; ++j) { - memset(&mbus_code, 0, sizeof(mbus_code)); - mbus_code.index = j; -+ mbus_code.pad = IMAGE_PAD; -+ mbus_code.which = V4L2_SUBDEV_FORMAT_ACTIVE; -+ - ret = v4l2_subdev_call(dev->sensor, pad, enum_mbus_code, NULL, - &mbus_code); - if (ret < 0) { -@@ -873,12 +969,15 @@ static int unicam_try_fmt_vid_cap(struct - struct unicam_device *dev = node->dev; - struct v4l2_subdev_format sd_fmt = { - .which = V4L2_SUBDEV_FORMAT_TRY, -- .pad = 0 -+ .pad = IMAGE_PAD - }; - struct v4l2_mbus_framefmt *mbus_fmt = &sd_fmt.format; - const struct unicam_fmt *fmt; - int ret; - -+ if (node->pad_id == METADATA_PAD) -+ return -EINVAL; -+ - fmt = find_format_by_pix(dev, f->fmt.pix.pixelformat); - if (!fmt) { - /* Pixel format not supported by unicam. Choose the first -@@ -983,7 +1082,7 @@ static int unicam_s_fmt_vid_cap(struct f - - v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, fmt->code); - -- ret = __subdev_set_format(dev, &mbus_fmt); -+ ret = __subdev_set_format(dev, &mbus_fmt, node->pad_id); - if (ret) { - unicam_dbg(3, dev, "%s __subdev_set_format failed %d\n", - __func__, ret); -@@ -1014,6 +1113,106 @@ static int unicam_s_fmt_vid_cap(struct f - return 0; - } - -+static int unicam_enum_fmt_meta_cap(struct file *file, void *priv, -+ struct v4l2_fmtdesc *f) -+{ -+ struct unicam_node *node = video_drvdata(file); -+ struct unicam_device *dev = node->dev; -+ struct v4l2_subdev_mbus_code_enum mbus_code; -+ const struct unicam_fmt *fmt = NULL; -+ int ret = 0; -+ -+ if (node->pad_id != METADATA_PAD || f->index != 0) -+ return -EINVAL; -+ -+ if (dev->sensor_embedded_data) { -+ memset(&mbus_code, 0, sizeof(mbus_code)); -+ mbus_code.index = f->index; -+ mbus_code.which = V4L2_SUBDEV_FORMAT_ACTIVE; -+ mbus_code.pad = METADATA_PAD; -+ -+ ret = v4l2_subdev_call(dev->sensor, pad, enum_mbus_code, NULL, -+ &mbus_code); -+ if (ret < 0) { -+ unicam_dbg(2, dev, -+ "subdev->enum_mbus_code idx 0 returned %d - index invalid\n", -+ ret); -+ return -EINVAL; -+ } -+ } else { -+ mbus_code.code = MEDIA_BUS_FMT_SENSOR_DATA; -+ } -+ -+ fmt = find_format_by_code(mbus_code.code); -+ if (fmt) -+ f->pixelformat = fmt->fourcc; -+ -+ return 0; -+} -+ -+static int unicam_g_fmt_meta_cap(struct file *file, void *priv, -+ struct v4l2_format *f) -+{ -+ struct unicam_node *node = video_drvdata(file); -+ -+ if (node->pad_id != METADATA_PAD) -+ return -EINVAL; -+ -+ *f = node->v_fmt; -+ -+ return 0; -+} -+ -+static int unicam_try_fmt_meta_cap(struct file *file, void *priv, -+ struct v4l2_format *f) -+{ -+ struct unicam_node *node = video_drvdata(file); -+ -+ if (node->pad_id != METADATA_PAD) -+ return -EINVAL; -+ -+ *f = node->v_fmt; -+ -+ return 0; -+} -+ -+static int unicam_s_fmt_meta_cap(struct file *file, void *priv, -+ struct v4l2_format *f) -+{ -+ struct unicam_node *node = video_drvdata(file); -+ struct unicam_device *dev = node->dev; -+ struct v4l2_mbus_framefmt mbus_fmt = { 0 }; -+ const struct unicam_fmt *fmt; -+ int ret; -+ -+ if (node->pad_id == IMAGE_PAD) -+ return -EINVAL; -+ -+ if (dev->sensor_embedded_data) { -+ fmt = find_format_by_pix(dev, f->fmt.meta.dataformat); -+ if (!fmt) { -+ unicam_err(dev, "unknown format: V4L2 pix 0x%08x\n", -+ f->fmt.meta.dataformat); -+ return -EINVAL; -+ } -+ mbus_fmt.code = fmt->code; -+ ret = __subdev_set_format(dev, &mbus_fmt, node->pad_id); -+ if (ret) { -+ unicam_dbg(3, dev, "%s __subdev_set_format failed %d\n", -+ __func__, ret); -+ return ret; -+ } -+ } -+ -+ *f = node->v_fmt; -+ -+ unicam_dbg(3, dev, "%s size %d, V4L2 pix 0x%08x\n", -+ __func__, node->v_fmt.fmt.meta.buffersize, -+ node->v_fmt.fmt.meta.dataformat); -+ -+ return 0; -+} -+ - static int unicam_queue_setup(struct vb2_queue *vq, - unsigned int *nbuffers, - unsigned int *nplanes, -@@ -1022,7 +1221,9 @@ static int unicam_queue_setup(struct vb2 - { - struct unicam_node *node = vb2_get_drv_priv(vq); - struct unicam_device *dev = node->dev; -- unsigned int size = node->v_fmt.fmt.pix.sizeimage; -+ unsigned int size = node->pad_id == IMAGE_PAD ? -+ node->v_fmt.fmt.pix.sizeimage : -+ node->v_fmt.fmt.meta.buffersize; - - if (vq->num_buffers + *nbuffers < 3) - *nbuffers = 3 - vq->num_buffers; -@@ -1053,7 +1254,8 @@ static int unicam_buffer_prepare(struct - if (WARN_ON(!node->fmt)) - return -EINVAL; - -- size = node->v_fmt.fmt.pix.sizeimage; -+ size = node->pad_id == IMAGE_PAD ? node->v_fmt.fmt.pix.sizeimage : -+ node->v_fmt.fmt.meta.buffersize; - if (vb2_plane_size(vb, 0) < size) { - unicam_err(dev, "data will not fit into plane (%lu < %lu)\n", - vb2_plane_size(vb, 0), size); -@@ -1082,12 +1284,12 @@ static void unicam_set_packing_config(st - int pack, unpack; - u32 val; - -- if (dev->node[0].v_fmt.fmt.pix.pixelformat == -- dev->node[0].fmt->fourcc) { -+ if (dev->node[IMAGE_PAD].v_fmt.fmt.pix.pixelformat == -+ dev->node[IMAGE_PAD].fmt->fourcc) { - unpack = UNICAM_PUM_NONE; - pack = UNICAM_PPM_NONE; - } else { -- switch (dev->node[0].fmt->depth) { -+ switch (dev->node[IMAGE_PAD].fmt->depth) { - case 8: - unpack = UNICAM_PUM_UNPACK8; - break; -@@ -1125,17 +1327,31 @@ static void unicam_cfg_image_id(struct u - if (dev->bus_type == V4L2_MBUS_CSI2_DPHY) { - /* CSI2 mode */ - reg_write(cfg, UNICAM_IDI0, -- (dev->virtual_channel << 6) | dev->node[0].fmt->csi_dt); -+ (dev->virtual_channel << 6) | -+ dev->node[IMAGE_PAD].fmt->csi_dt); - } else { - /* CCP2 mode */ -- reg_write(cfg, UNICAM_IDI0, (0x80 | dev->node[0].fmt->csi_dt)); -+ reg_write(cfg, UNICAM_IDI0, -+ 0x80 | dev->node[IMAGE_PAD].fmt->csi_dt); - } - } - --static void unicam_start_rx(struct unicam_device *dev, unsigned long addr) -+static void unicam_enable_ed(struct unicam_device *dev) -+{ -+ struct unicam_cfg *cfg = &dev->cfg; -+ u32 val = reg_read(cfg, UNICAM_DCS); -+ -+ set_field(&val, 2, UNICAM_EDL_MASK); -+ /* Do not wrap at the end of the embedded data buffer */ -+ set_field(&val, 0, UNICAM_DBOB); -+ -+ reg_write(cfg, UNICAM_DCS, val); -+} -+ -+static void unicam_start_rx(struct unicam_device *dev, dma_addr_t *addr) - { - struct unicam_cfg *cfg = &dev->cfg; -- int line_int_freq = dev->node[0].v_fmt.fmt.pix.height >> 2; -+ int line_int_freq = dev->node[IMAGE_PAD].v_fmt.fmt.pix.height >> 2; - unsigned int i; - u32 val; - -@@ -1284,27 +1500,31 @@ static void unicam_start_rx(struct unica - } - - reg_write(&dev->cfg, UNICAM_IBLS, -- dev->node[0].v_fmt.fmt.pix.bytesperline); -- unicam_wr_dma_addr(dev, addr); -+ dev->node[IMAGE_PAD].v_fmt.fmt.pix.bytesperline); -+ unicam_wr_dma_addr(dev, addr[IMAGE_PAD], IMAGE_PAD); - unicam_set_packing_config(dev); - unicam_cfg_image_id(dev); - -- /* Disabled embedded data */ -- val = 0; -- set_field(&val, 0, UNICAM_EDL_MASK); -- reg_write(cfg, UNICAM_DCS, val); -- - val = reg_read(cfg, UNICAM_MISC); - set_field(&val, 1, UNICAM_FL0); - set_field(&val, 1, UNICAM_FL1); - reg_write(cfg, UNICAM_MISC, val); - -+ if (dev->node[METADATA_PAD].streaming && dev->sensor_embedded_data) { -+ unicam_enable_ed(dev); -+ unicam_wr_dma_addr(dev, addr[METADATA_PAD], METADATA_PAD); -+ } -+ - /* Enable peripheral */ - reg_write_field(cfg, UNICAM_CTRL, 1, UNICAM_CPE); - - /* Load image pointers */ - reg_write_field(cfg, UNICAM_ICTL, 1, UNICAM_LIP_MASK); - -+ /* Load embedded data buffer pointers if needed */ -+ if (dev->node[METADATA_PAD].streaming && dev->sensor_embedded_data) -+ reg_write_field(cfg, UNICAM_DCS, 1, UNICAM_LDP); -+ - /* - * Enable trigger only for the first frame to - * sync correctly to the FS from the source. -@@ -1339,6 +1559,9 @@ static void unicam_disable(struct unicam - /* Disable peripheral */ - reg_write_field(cfg, UNICAM_CTRL, 0, UNICAM_CPE); - -+ /* Clear ED setup */ -+ reg_write(cfg, UNICAM_DCS, 0); -+ - /* Disable all lane clocks */ - clk_write(cfg, 0); - } -@@ -1347,26 +1570,23 @@ static int unicam_start_streaming(struct - { - struct unicam_node *node = vb2_get_drv_priv(vq); - struct unicam_device *dev = node->dev; -- struct unicam_dmaqueue *dma_q = &node->dma_queue; -- struct unicam_buffer *buf, *tmp; -- unsigned long addr = 0; -+ struct unicam_buffer *buf; -+ dma_addr_t buffer_addr[MAX_NODES] = { 0 }; -+ int num_nodes_streaming; - unsigned long flags; -- int ret; -+ int ret, i; - -- spin_lock_irqsave(&node->dma_queue_lock, flags); -- buf = list_entry(dma_q->active.next, struct unicam_buffer, list); -- node->cur_frm = buf; -- node->next_frm = buf; -- list_del(&buf->list); -- spin_unlock_irqrestore(&node->dma_queue_lock, flags); -+ node->streaming = 1; -+ if (!unicam_all_nodes_streaming(dev)) { -+ unicam_dbg(3, dev, "Not all nodes are streaming yet."); -+ return 0; -+ } - -- addr = vb2_dma_contig_plane_dma_addr(&node->cur_frm->vb.vb2_buf, 0); - dev->sequence = 0; -- - ret = unicam_runtime_get(dev); - if (ret < 0) { - unicam_dbg(3, dev, "unicam_runtime_get failed\n"); -- goto err_release_buffers; -+ return ret; - } - - dev->active_data_lanes = dev->max_data_lanes; -@@ -1388,7 +1608,7 @@ static int unicam_start_streaming(struct - dev->active_data_lanes = dev->max_data_lanes; - } - if (dev->active_data_lanes > dev->max_data_lanes) { -- unicam_err(dev, "Device has requested %u data lanes, which is >%u configured in DT\n", -+ unicam_err(dev, "Device has requested %u data lanes, which is >%u configured in DT\n", - dev->active_data_lanes, dev->max_data_lanes); - ret = -EINVAL; - goto err_pm_put; -@@ -1408,9 +1628,22 @@ static int unicam_start_streaming(struct - unicam_err(dev, "Failed to enable CSI clock: %d\n", ret); - goto err_pm_put; - } -- dev->streaming = 1; - -- unicam_start_rx(dev, addr); -+ num_nodes_streaming = unicam_num_nodes_streaming(dev); -+ for (i = 0; i < num_nodes_streaming; i++) { -+ spin_lock_irqsave(&dev->node[i].dma_queue_lock, flags); -+ buf = list_entry(dev->node[i].dma_queue.active.next, -+ struct unicam_buffer, list); -+ dev->node[i].cur_frm = buf; -+ dev->node[i].next_frm = buf; -+ list_del(&buf->list); -+ spin_unlock_irqrestore(&dev->node[i].dma_queue_lock, flags); -+ buffer_addr[i] = -+ vb2_dma_contig_plane_dma_addr(&dev->node[i].cur_frm->vb.vb2_buf, -+ 0); -+ } -+ -+ unicam_start_rx(dev, buffer_addr); - - ret = v4l2_subdev_call(dev->sensor, video, s_stream, 1); - if (ret < 0) { -@@ -1421,21 +1654,11 @@ static int unicam_start_streaming(struct - return 0; - - err_disable_unicam: -+ node->streaming = 0; - unicam_disable(dev); - clk_disable_unprepare(dev->clock); - err_pm_put: - unicam_runtime_put(dev); --err_release_buffers: -- list_for_each_entry_safe(buf, tmp, &dma_q->active, list) { -- list_del(&buf->list); -- vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_QUEUED); -- } -- if (node->cur_frm != node->next_frm) -- vb2_buffer_done(&node->next_frm->vb.vb2_buf, -- VB2_BUF_STATE_QUEUED); -- vb2_buffer_done(&node->cur_frm->vb.vb2_buf, VB2_BUF_STATE_QUEUED); -- node->next_frm = NULL; -- node->cur_frm = NULL; - - return ret; - } -@@ -1448,33 +1671,47 @@ static void unicam_stop_streaming(struct - struct unicam_buffer *buf, *tmp; - unsigned long flags; - -- if (v4l2_subdev_call(dev->sensor, video, s_stream, 0) < 0) -- unicam_err(dev, "stream off failed in subdev\n"); -+ node->streaming = 0; - -- unicam_disable(dev); -+ if (node->pad_id == IMAGE_PAD) { -+ /* Stop streaming the sensor and disable the peripheral. -+ * We cannot continue streaming embedded data with the -+ * image pad disabled. -+ */ -+ if (v4l2_subdev_call(dev->sensor, video, s_stream, 0) < 0) -+ unicam_err(dev, "stream off failed in subdev\n"); - -- /* Release all active buffers */ -+ unicam_disable(dev); -+ clk_disable_unprepare(dev->clock); -+ unicam_runtime_put(dev); -+ -+ } else if (node->pad_id == METADATA_PAD) { -+ /* Null out the embedded data buffer address so the HW does -+ * not use it. This is only really needed if the embedded data -+ * pad is disabled before the image pad. The 0x3 in the top two -+ * bits signifies uncached accesses through the Videocore -+ * memory controller. -+ */ -+ unicam_wr_dma_addr(dev, 0xc0000000, METADATA_PAD); -+ } -+ -+ /* Clear all queued buffers for the node */ - spin_lock_irqsave(&node->dma_queue_lock, flags); - list_for_each_entry_safe(buf, tmp, &dma_q->active, list) { - list_del(&buf->list); - vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); - } - -- if (node->cur_frm == node->next_frm) { -- vb2_buffer_done(&node->cur_frm->vb.vb2_buf, -- VB2_BUF_STATE_ERROR); -- } else { -+ if (node->cur_frm) - vb2_buffer_done(&node->cur_frm->vb.vb2_buf, - VB2_BUF_STATE_ERROR); -+ if (node->next_frm && node->cur_frm != node->next_frm) - vb2_buffer_done(&node->next_frm->vb.vb2_buf, - VB2_BUF_STATE_ERROR); -- } -+ - node->cur_frm = NULL; - node->next_frm = NULL; - spin_unlock_irqrestore(&node->dma_queue_lock, flags); -- -- clk_disable_unprepare(dev->clock); -- unicam_runtime_put(dev); - } - - static int unicam_enum_input(struct file *file, void *priv, -@@ -1595,17 +1832,23 @@ static int unicam_enum_framesizes(struct - struct v4l2_subdev_frame_size_enum fse; - int ret; - -- /* check for valid format */ -- fmt = find_format_by_pix(dev, fsize->pixel_format); -- if (!fmt) { -- unicam_dbg(3, dev, "Invalid pixel code: %x\n", -- fsize->pixel_format); -- return -EINVAL; -+ if (node->pad_id == IMAGE_PAD) { -+ /* check for valid format */ -+ fmt = find_format_by_pix(dev, fsize->pixel_format); -+ if (!fmt) { -+ unicam_dbg(3, dev, "Invalid pixel code: %x\n", -+ fsize->pixel_format); -+ return -EINVAL; -+ } -+ fse.code = fmt->code; -+ } else { -+ /* This pad is for embedded data, so just set the format */ -+ fse.code = MEDIA_BUS_FMT_SENSOR_DATA; - } - -+ fse.which = V4L2_SUBDEV_FORMAT_ACTIVE; - fse.index = fsize->index; -- fse.pad = 0; -- fse.code = fmt->code; -+ fse.pad = node->pad_id; - - ret = v4l2_subdev_call(dev->sensor, pad, enum_frame_size, NULL, &fse); - if (ret) -@@ -1782,7 +2025,7 @@ static void unicam_notify(struct v4l2_su - - switch (notification) { - case V4L2_DEVICE_NOTIFY_EVENT: -- v4l2_event_queue(&dev->node[0].video_dev, arg); -+ v4l2_event_queue(&dev->node[IMAGE_PAD].video_dev, arg); - break; - default: - break; -@@ -1826,6 +2069,7 @@ static int unicam_open(struct file *file - goto unlock; - } - -+ node->open++; - ret = 0; - - unlock: -@@ -1850,6 +2094,10 @@ static int unicam_release(struct file *f - if (fh_singular) - v4l2_subdev_call(sd, core, s_power, 0); - -+ if (node->streaming) -+ unicam_stop_streaming(&node->buffer_queue); -+ -+ node->open--; - mutex_unlock(&node->lock); - - return ret; -@@ -1874,6 +2122,11 @@ static const struct v4l2_ioctl_ops unica - .vidioc_s_fmt_vid_cap = unicam_s_fmt_vid_cap, - .vidioc_try_fmt_vid_cap = unicam_try_fmt_vid_cap, - -+ .vidioc_enum_fmt_meta_cap = unicam_enum_fmt_meta_cap, -+ .vidioc_g_fmt_meta_cap = unicam_g_fmt_meta_cap, -+ .vidioc_s_fmt_meta_cap = unicam_s_fmt_meta_cap, -+ .vidioc_try_fmt_meta_cap = unicam_try_fmt_meta_cap, -+ - .vidioc_enum_input = unicam_enum_input, - .vidioc_g_input = unicam_g_input, - .vidioc_s_input = unicam_s_input, -@@ -1941,42 +2194,53 @@ static int register_node(struct unicam_d - const struct unicam_fmt *fmt; - int ret; - -- ret = __subdev_get_format(unicam, &mbus_fmt, pad_id); -- if (ret) { -- unicam_err(unicam, "Failed to get_format - ret %d\n", ret); -- return ret; -- } -- -- fmt = find_format_by_code(mbus_fmt.code); -- if (!fmt) { -- /* Find the first format that the sensor and unicam both -- * support -- */ -- fmt = get_first_supported_format(unicam); -+ if (unicam->sensor_embedded_data || pad_id != METADATA_PAD) { -+ ret = __subdev_get_format(unicam, &mbus_fmt, pad_id); -+ if (ret) { -+ unicam_err(unicam, "Failed to get_format - ret %d\n", -+ ret); -+ return ret; -+ } - -- if (!fmt) -- /* No compatible formats */ -- return -EINVAL; -+ fmt = find_format_by_code(mbus_fmt.code); -+ if (!fmt) { -+ /* Find the first format that the sensor and unicam both -+ * support -+ */ -+ fmt = get_first_supported_format(unicam); - -- mbus_fmt.code = fmt->code; -- ret = __subdev_set_format(unicam, &mbus_fmt); -- if (ret) -- return -EINVAL; -- } -- if (mbus_fmt.field != V4L2_FIELD_NONE) { -- /* Interlaced not supported - disable it now. */ -- mbus_fmt.field = V4L2_FIELD_NONE; -- ret = __subdev_set_format(unicam, &mbus_fmt); -- if (ret) -- return -EINVAL; -+ if (!fmt) -+ /* No compatible formats */ -+ return -EINVAL; -+ -+ mbus_fmt.code = fmt->code; -+ ret = __subdev_set_format(unicam, &mbus_fmt, pad_id); -+ if (ret) -+ return -EINVAL; -+ } -+ if (mbus_fmt.field != V4L2_FIELD_NONE) { -+ /* Interlaced not supported - disable it now. */ -+ mbus_fmt.field = V4L2_FIELD_NONE; -+ ret = __subdev_set_format(unicam, &mbus_fmt, pad_id); -+ if (ret) -+ return -EINVAL; -+ } -+ } else { -+ /* Fix this node format as embedded data. */ -+ fmt = find_format_by_code(MEDIA_BUS_FMT_SENSOR_DATA); - } - -+ node->dev = unicam; - node->pad_id = pad_id; - node->fmt = fmt; -- if (fmt->fourcc) -- node->v_fmt.fmt.pix.pixelformat = fmt->fourcc; -- else -+ if (fmt->fourcc) { -+ if (fmt->fourcc != V4L2_META_FMT_SENSOR_DATA) -+ node->v_fmt.fmt.pix.pixelformat = fmt->fourcc; -+ else -+ node->v_fmt.fmt.meta.dataformat = fmt->fourcc; -+ } else { - node->v_fmt.fmt.pix.pixelformat = fmt->repacked_fourcc; -+ } - - /* Read current subdev format */ - unicam_reset_format(node); -@@ -2002,13 +2266,21 @@ static int register_node(struct unicam_d - spin_lock_init(&node->dma_queue_lock); - mutex_init(&node->lock); - -- if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { -+ vdev = &node->video_dev; -+ if (pad_id == IMAGE_PAD) { - /* Add controls from the subdevice */ - ret = v4l2_ctrl_add_handler(&node->ctrl_handler, - unicam->sensor->ctrl_handler, NULL, - true); - if (ret < 0) - return ret; -+ -+ /* -+ * If the sensor subdevice has any controls, associate the node -+ * with the ctrl handler to allow access from userland. -+ */ -+ if (!list_empty(&node->ctrl_handler.ctrls)) -+ vdev->ctrl_handler = &node->ctrl_handler; - } - - q = &node->buffer_queue; -@@ -2031,8 +2303,6 @@ static int register_node(struct unicam_d - - INIT_LIST_HEAD(&node->dma_queue.active); - -- vdev = &node->video_dev; -- strlcpy(vdev->name, UNICAM_MODULE_NAME, sizeof(vdev->name)); - vdev->release = video_device_release_empty; - vdev->fops = &unicam_fops; - vdev->ioctl_ops = &unicam_ioctl_ops; -@@ -2040,24 +2310,28 @@ static int register_node(struct unicam_d - vdev->vfl_dir = VFL_DIR_RX; - vdev->queue = q; - vdev->lock = &node->lock; -- vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | -- V4L2_CAP_READWRITE; -- /* If the source has no controls then remove our ctrl handler. */ -- if (list_empty(&node->ctrl_handler.ctrls)) -- unicam->v4l2_dev.ctrl_handler = NULL; -+ vdev->device_caps = (pad_id == IMAGE_PAD) ? -+ (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING) : -+ (V4L2_CAP_META_CAPTURE | V4L2_CAP_STREAMING); -+ -+ /* Define the device names */ -+ snprintf(vdev->name, sizeof(vdev->name), "%s-%s", UNICAM_MODULE_NAME, -+ node->pad_id == IMAGE_PAD ? "image" : "embedded"); - -- node->dev = unicam; - video_set_drvdata(vdev, node); - vdev->entity.flags |= MEDIA_ENT_FL_DEFAULT; - -- if (!v4l2_subdev_has_op(unicam->sensor, video, s_std)) { -+ if (node->pad_id == METADATA_PAD || -+ !v4l2_subdev_has_op(unicam->sensor, video, s_std)) { - v4l2_disable_ioctl(&node->video_dev, VIDIOC_S_STD); - v4l2_disable_ioctl(&node->video_dev, VIDIOC_G_STD); - v4l2_disable_ioctl(&node->video_dev, VIDIOC_ENUMSTD); - } -- if (!v4l2_subdev_has_op(unicam->sensor, video, querystd)) -+ if (node->pad_id == METADATA_PAD || -+ !v4l2_subdev_has_op(unicam->sensor, video, querystd)) - v4l2_disable_ioctl(&node->video_dev, VIDIOC_QUERYSTD); -- if (!v4l2_subdev_has_op(unicam->sensor, video, s_dv_timings)) { -+ if (node->pad_id == METADATA_PAD || -+ !v4l2_subdev_has_op(unicam->sensor, video, s_dv_timings)) { - v4l2_disable_ioctl(&node->video_dev, VIDIOC_S_EDID); - v4l2_disable_ioctl(&node->video_dev, VIDIOC_G_EDID); - v4l2_disable_ioctl(&node->video_dev, VIDIOC_DV_TIMINGS_CAP); -@@ -2066,15 +2340,19 @@ static int register_node(struct unicam_d - v4l2_disable_ioctl(&node->video_dev, VIDIOC_ENUM_DV_TIMINGS); - v4l2_disable_ioctl(&node->video_dev, VIDIOC_QUERY_DV_TIMINGS); - } -- if (!v4l2_subdev_has_op(unicam->sensor, pad, enum_frame_interval)) -+ if (node->pad_id == METADATA_PAD || -+ !v4l2_subdev_has_op(unicam->sensor, pad, enum_frame_interval)) - v4l2_disable_ioctl(&node->video_dev, - VIDIOC_ENUM_FRAMEINTERVALS); -- if (!v4l2_subdev_has_op(unicam->sensor, video, g_frame_interval)) -+ if (node->pad_id == METADATA_PAD || -+ !v4l2_subdev_has_op(unicam->sensor, video, g_frame_interval)) - v4l2_disable_ioctl(&node->video_dev, VIDIOC_G_PARM); -- if (!v4l2_subdev_has_op(unicam->sensor, video, s_frame_interval)) -+ if (node->pad_id == METADATA_PAD || -+ !v4l2_subdev_has_op(unicam->sensor, video, s_frame_interval)) - v4l2_disable_ioctl(&node->video_dev, VIDIOC_S_PARM); - -- if (!v4l2_subdev_has_op(unicam->sensor, pad, enum_frame_size)) -+ if (node->pad_id == METADATA_PAD || -+ !v4l2_subdev_has_op(unicam->sensor, pad, enum_frame_size)) - v4l2_disable_ioctl(&node->video_dev, VIDIOC_ENUM_FRAMESIZES); - - ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1); -@@ -2082,27 +2360,29 @@ static int register_node(struct unicam_d - unicam_err(unicam, "Unable to register video device.\n"); - return ret; - } -- node->registered = true; -+ node->registered = 1; - -- ret = media_create_pad_link(&unicam->sensor->entity, -- 0, &node->video_dev.entity, 0, -- MEDIA_LNK_FL_ENABLED | -- MEDIA_LNK_FL_IMMUTABLE); -- if (ret) -- unicam_err(unicam, "Unable to create pad links.\n"); -+ if (unicam->sensor_embedded_data) { -+ ret = media_create_pad_link(&unicam->sensor->entity, pad_id, -+ &node->video_dev.entity, 0, -+ MEDIA_LNK_FL_ENABLED | -+ MEDIA_LNK_FL_IMMUTABLE); -+ if (ret) -+ unicam_err(unicam, "Unable to create pad links.\n"); -+ } - - return ret; - } - - static void unregister_nodes(struct unicam_device *unicam) - { -- if (unicam->node[0].registered) { -- video_unregister_device(&unicam->node[0].video_dev); -- unicam->node[0].registered = false; -- } -- if (unicam->node[1].registered) { -- video_unregister_device(&unicam->node[1].video_dev); -- unicam->node[1].registered = false; -+ if (unicam->node[IMAGE_PAD].registered) { -+ video_unregister_device(&unicam->node[IMAGE_PAD].video_dev); -+ unicam->node[IMAGE_PAD].registered = 0; -+ } -+ if (unicam->node[METADATA_PAD].registered) { -+ video_unregister_device(&unicam->node[METADATA_PAD].video_dev); -+ unicam->node[METADATA_PAD].registered = 0; - } - } - -@@ -2118,20 +2398,20 @@ static int unicam_probe_complete(struct - if (!unicam->sensor_config) - return -ENOMEM; - -- ret = register_node(unicam, &unicam->node[0], -- V4L2_BUF_TYPE_VIDEO_CAPTURE, 0); -+ unicam->sensor_embedded_data = (unicam->sensor->entity.num_pads >= 2); -+ -+ ret = register_node(unicam, &unicam->node[IMAGE_PAD], -+ V4L2_BUF_TYPE_VIDEO_CAPTURE, IMAGE_PAD); - if (ret) { - unicam_err(unicam, "Unable to register subdev node 0.\n"); - goto unregister; - } -- if (unicam->sensor->entity.num_pads >= 2) { -- ret = register_node(unicam, &unicam->node[1], -- V4L2_BUF_TYPE_META_CAPTURE, 1); -- if (ret) { -- unicam_err(unicam, -- "Unable to register subdev node 1.\n"); -- goto unregister; -- } -+ -+ ret = register_node(unicam, &unicam->node[METADATA_PAD], -+ V4L2_BUF_TYPE_META_CAPTURE, METADATA_PAD); -+ if (ret) { -+ unicam_err(unicam, "Unable to register subdev node 1.\n"); -+ goto unregister; - } - - ret = v4l2_device_register_ro_subdev_nodes(&unicam->v4l2_dev); -@@ -2355,8 +2635,10 @@ static int unicam_probe(struct platform_ - pdev->dev.driver->name, dev_name(&pdev->dev)); - unicam->mdev.hw_revision = 1; - -- media_entity_pads_init(&unicam->node[0].video_dev.entity, 1, -- &unicam->node[0].pad); -+ media_entity_pads_init(&unicam->node[IMAGE_PAD].video_dev.entity, 1, -+ &unicam->node[IMAGE_PAD].pad); -+ media_entity_pads_init(&unicam->node[METADATA_PAD].video_dev.entity, 1, -+ &unicam->node[METADATA_PAD].pad); - media_device_init(&unicam->mdev); - - unicam->v4l2_dev.mdev = &unicam->mdev; -@@ -2376,11 +2658,10 @@ static int unicam_probe(struct platform_ - } - - /* Reserve space for the controls */ -- hdl = &unicam->node[0].ctrl_handler; -+ hdl = &unicam->node[IMAGE_PAD].ctrl_handler; - ret = v4l2_ctrl_handler_init(hdl, 16); - if (ret < 0) - goto media_unregister; -- unicam->v4l2_dev.ctrl_handler = hdl; - - /* set the driver data in platform device */ - platform_set_drvdata(pdev, unicam); -@@ -2417,7 +2698,7 @@ static int unicam_remove(struct platform - pm_runtime_disable(&pdev->dev); - - v4l2_async_notifier_unregister(&unicam->notifier); -- v4l2_ctrl_handler_free(&unicam->node[0].ctrl_handler); -+ v4l2_ctrl_handler_free(&unicam->node[IMAGE_PAD].ctrl_handler); - v4l2_device_unregister(&unicam->v4l2_dev); - unregister_nodes(unicam); - if (unicam->sensor_config) diff --git a/target/linux/bcm27xx/patches-5.15/950-0215-media-bcm2835-unicam-Use-dummy-buffer-if-none-have-b.patch b/target/linux/bcm27xx/patches-5.15/950-0215-media-bcm2835-unicam-Use-dummy-buffer-if-none-have-b.patch deleted file mode 100644 index f25d63d69..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0215-media-bcm2835-unicam-Use-dummy-buffer-if-none-have-b.patch +++ /dev/null @@ -1,308 +0,0 @@ -From f84e5dc673c401f4ac3d9b7423bf611a88a7b0c0 Mon Sep 17 00:00:00 2001 -From: Naushir Patuck -Date: Thu, 2 Apr 2020 16:08:51 +0100 -Subject: [PATCH] media: bcm2835-unicam: Use dummy buffer if none have - been queued - -If no buffer has been queued by a userland application, we use an -internal dummy buffer for the hardware to spin in. This will allow -the driver to release the existing userland buffer back to the -application for processing. - -Signed-off-by: Naushir Patuck ---- - .../media/platform/bcm2835/bcm2835-unicam.c | 160 ++++++++++++------ - 1 file changed, 110 insertions(+), 50 deletions(-) - ---- a/drivers/media/platform/bcm2835/bcm2835-unicam.c -+++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c -@@ -47,6 +47,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -112,6 +113,12 @@ MODULE_PARM_DESC(debug, "Debug level 0-3 - /* Default size of the embedded buffer */ - #define UNICAM_EMBEDDED_SIZE 8192 - -+/* -+ * Size of the dummy buffer. Can be any size really, but the DMA -+ * allocation works in units of page sizes. -+ */ -+#define DUMMY_BUF_SIZE (PAGE_SIZE) -+ - enum pad_types { - IMAGE_PAD, - METADATA_PAD, -@@ -390,6 +397,12 @@ struct unicam_node { - struct media_pad pad; - struct v4l2_ctrl_handler ctrl_handler; - unsigned int embedded_lines; -+ /* -+ * Dummy buffer intended to be used by unicam -+ * if we have no other queued buffers to swap to. -+ */ -+ void *dummy_buf_cpu_addr; -+ dma_addr_t dummy_buf_dma_addr; - }; - - struct unicam_device { -@@ -661,27 +674,24 @@ static int unicam_reset_format(struct un - return 0; - } - --static void unicam_wr_dma_addr(struct unicam_device *dev, dma_addr_t dmaaddr, -- int pad_id) -+static void unicam_wr_dma_addr(struct unicam_cfg *cfg, dma_addr_t dmaaddr, -+ unsigned int buffer_size, int pad_id) - { -- dma_addr_t endaddr; -+ dma_addr_t endaddr = dmaaddr + buffer_size; - - /* -- * dmaaddr should be a 32-bit address with the top two bits set to 0x3 -- * to signify uncached access through the Videocore memory controller. -+ * dmaaddr and endaddr should be a 32-bit address with the top two bits -+ * set to 0x3 to signify uncached access through the Videocore memory -+ * controller. - */ -- BUG_ON((dmaaddr >> 30) != 0x3); -+ BUG_ON((dmaaddr >> 30) != 0x3 && (endaddr >> 30) != 0x3); - - if (pad_id == IMAGE_PAD) { -- endaddr = dmaaddr + -- dev->node[IMAGE_PAD].v_fmt.fmt.pix.sizeimage; -- reg_write(&dev->cfg, UNICAM_IBSA0, dmaaddr); -- reg_write(&dev->cfg, UNICAM_IBEA0, endaddr); -+ reg_write(cfg, UNICAM_IBSA0, dmaaddr); -+ reg_write(cfg, UNICAM_IBEA0, endaddr); - } else { -- endaddr = dmaaddr + -- dev->node[METADATA_PAD].v_fmt.fmt.meta.buffersize; -- reg_write(&dev->cfg, UNICAM_DBSA0, dmaaddr); -- reg_write(&dev->cfg, UNICAM_DBEA0, endaddr); -+ reg_write(cfg, UNICAM_DBSA0, dmaaddr); -+ reg_write(cfg, UNICAM_DBEA0, endaddr); - } - } - -@@ -704,6 +714,7 @@ static inline void unicam_schedule_next_ - struct unicam_device *dev = node->dev; - struct unicam_dmaqueue *dma_q = &node->dma_queue; - struct unicam_buffer *buf; -+ unsigned int size; - dma_addr_t addr; - - buf = list_entry(dma_q->active.next, struct unicam_buffer, list); -@@ -711,7 +722,23 @@ static inline void unicam_schedule_next_ - list_del(&buf->list); - - addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0); -- unicam_wr_dma_addr(dev, addr, node->pad_id); -+ size = (node->pad_id == IMAGE_PAD) ? -+ dev->node[IMAGE_PAD].v_fmt.fmt.pix.sizeimage : -+ dev->node[METADATA_PAD].v_fmt.fmt.meta.buffersize; -+ -+ unicam_wr_dma_addr(&dev->cfg, addr, size, node->pad_id); -+} -+ -+static inline void unicam_schedule_dummy_buffer(struct unicam_node *node) -+{ -+ struct unicam_device *dev = node->dev; -+ dma_addr_t addr = node->dummy_buf_dma_addr; -+ -+ unicam_dbg(3, dev, "Scheduling dummy buffer for node %d\n", -+ node->pad_id); -+ -+ unicam_wr_dma_addr(&dev->cfg, addr, DUMMY_BUF_SIZE, node->pad_id); -+ node->next_frm = NULL; - } - - static inline void unicam_process_buffer_complete(struct unicam_node *node, -@@ -721,7 +748,6 @@ static inline void unicam_process_buffer - node->cur_frm->vb.sequence = sequence; - - vb2_buffer_done(&node->cur_frm->vb.vb2_buf, VB2_BUF_STATE_DONE); -- node->cur_frm = node->next_frm; - } - - static int unicam_num_nodes_streaming(struct unicam_device *dev) -@@ -788,6 +814,28 @@ static irqreturn_t unicam_isr(int irq, v - if (!(sta && (UNICAM_IS | UNICAM_PI0))) - return IRQ_HANDLED; - -+ /* -+ * We must run the frame end handler first. If we have a valid next_frm -+ * and we get a simultaneout FE + FS interrupt, running the FS handler -+ * first would null out the next_frm ptr and we would have lost the -+ * buffer forever. -+ */ -+ if (ista & UNICAM_FEI || sta & UNICAM_PI0) { -+ /* -+ * Ensure we have swapped buffers already as we can't -+ * stop the peripheral. If no buffer is available, use a -+ * dummy buffer to dump out frames until we get a new buffer -+ * to use. -+ */ -+ for (i = 0; i < num_nodes_streaming; i++) { -+ if (unicam->node[i].cur_frm) -+ unicam_process_buffer_complete(&unicam->node[i], -+ sequence); -+ unicam->node[i].cur_frm = unicam->node[i].next_frm; -+ } -+ unicam->sequence++; -+ } -+ - if (ista & UNICAM_FSI) { - /* - * Timestamp is to be when the first data byte was captured, -@@ -798,24 +846,16 @@ static irqreturn_t unicam_isr(int irq, v - if (unicam->node[i].cur_frm) - unicam->node[i].cur_frm->vb.vb2_buf.timestamp = - ts; -+ /* -+ * Set the next frame output to go to a dummy frame -+ * if we have not managed to obtain another frame -+ * from the queue. -+ */ -+ unicam_schedule_dummy_buffer(&unicam->node[i]); - } - } -- if (ista & UNICAM_FEI || sta & UNICAM_PI0) { -- /* -- * Ensure we have swapped buffers already as we can't -- * stop the peripheral. Overwrite the frame we've just -- * captured instead. -- */ -- for (i = 0; i < num_nodes_streaming; i++) { -- if (unicam->node[i].cur_frm && -- unicam->node[i].cur_frm != unicam->node[i].next_frm) -- unicam_process_buffer_complete(&unicam->node[i], -- sequence); -- } -- unicam->sequence++; -- } -- -- /* Cannot swap buffer at frame end, there may be a race condition -+ /* -+ * Cannot swap buffer at frame end, there may be a race condition - * where the HW does not actually swap it if the new frame has - * already started. - */ -@@ -823,7 +863,7 @@ static irqreturn_t unicam_isr(int irq, v - for (i = 0; i < num_nodes_streaming; i++) { - spin_lock(&unicam->node[i].dma_queue_lock); - if (!list_empty(&unicam->node[i].dma_queue.active) && -- unicam->node[i].cur_frm == unicam->node[i].next_frm) -+ !unicam->node[i].next_frm) - unicam_schedule_next_buffer(&unicam->node[i]); - spin_unlock(&unicam->node[i].dma_queue_lock); - } -@@ -1352,7 +1392,7 @@ static void unicam_start_rx(struct unica - { - struct unicam_cfg *cfg = &dev->cfg; - int line_int_freq = dev->node[IMAGE_PAD].v_fmt.fmt.pix.height >> 2; -- unsigned int i; -+ unsigned int size, i; - u32 val; - - if (line_int_freq < 128) -@@ -1413,7 +1453,7 @@ static void unicam_start_rx(struct unica - reg_write_field(cfg, UNICAM_ANA, 0, UNICAM_DDL); - - /* Always start in trigger frame capture mode (UNICAM_FCM set) */ -- val = UNICAM_FSIE | UNICAM_FEIE | UNICAM_FCM; -+ val = UNICAM_FSIE | UNICAM_FEIE | UNICAM_FCM | UNICAM_IBOB; - set_field(&val, line_int_freq, UNICAM_LCIE_MASK); - reg_write(cfg, UNICAM_ICTL, val); - reg_write(cfg, UNICAM_STA, UNICAM_STA_MASK_ALL); -@@ -1501,7 +1541,8 @@ static void unicam_start_rx(struct unica - - reg_write(&dev->cfg, UNICAM_IBLS, - dev->node[IMAGE_PAD].v_fmt.fmt.pix.bytesperline); -- unicam_wr_dma_addr(dev, addr[IMAGE_PAD], IMAGE_PAD); -+ size = dev->node[IMAGE_PAD].v_fmt.fmt.pix.sizeimage; -+ unicam_wr_dma_addr(&dev->cfg, addr[IMAGE_PAD], size, IMAGE_PAD); - unicam_set_packing_config(dev); - unicam_cfg_image_id(dev); - -@@ -1511,8 +1552,10 @@ static void unicam_start_rx(struct unica - reg_write(cfg, UNICAM_MISC, val); - - if (dev->node[METADATA_PAD].streaming && dev->sensor_embedded_data) { -+ size = dev->node[METADATA_PAD].v_fmt.fmt.meta.buffersize; - unicam_enable_ed(dev); -- unicam_wr_dma_addr(dev, addr[METADATA_PAD], METADATA_PAD); -+ unicam_wr_dma_addr(&dev->cfg, addr[METADATA_PAD], size, -+ METADATA_PAD); - } - - /* Enable peripheral */ -@@ -1686,13 +1729,14 @@ static void unicam_stop_streaming(struct - unicam_runtime_put(dev); - - } else if (node->pad_id == METADATA_PAD) { -- /* Null out the embedded data buffer address so the HW does -- * not use it. This is only really needed if the embedded data -- * pad is disabled before the image pad. The 0x3 in the top two -- * bits signifies uncached accesses through the Videocore -- * memory controller. -+ /* Allow the hardware to spin in the dummy buffer. -+ * This is only really needed if the embedded data pad is -+ * disabled before the image pad. The 0x3 in the top two bits -+ * signifies uncached accesses through the Videocore memory -+ * controller. - */ -- unicam_wr_dma_addr(dev, 0xc0000000, METADATA_PAD); -+ unicam_wr_dma_addr(&dev->cfg, node->dummy_buf_dma_addr, -+ DUMMY_BUF_SIZE, METADATA_PAD); - } - - /* Clear all queued buffers for the node */ -@@ -2321,6 +2365,15 @@ static int register_node(struct unicam_d - video_set_drvdata(vdev, node); - vdev->entity.flags |= MEDIA_ENT_FL_DEFAULT; - -+ node->dummy_buf_cpu_addr = dma_alloc_coherent(&unicam->pdev->dev, -+ DUMMY_BUF_SIZE, -+ &node->dummy_buf_dma_addr, -+ GFP_ATOMIC); -+ if (!node->dummy_buf_cpu_addr) { -+ unicam_err(unicam, "Unable to allocate dummy buffer.\n"); -+ return -ENOMEM; -+ } -+ - if (node->pad_id == METADATA_PAD || - !v4l2_subdev_has_op(unicam->sensor, video, s_std)) { - v4l2_disable_ioctl(&node->video_dev, VIDIOC_S_STD); -@@ -2376,13 +2429,20 @@ static int register_node(struct unicam_d - - static void unregister_nodes(struct unicam_device *unicam) - { -- if (unicam->node[IMAGE_PAD].registered) { -- video_unregister_device(&unicam->node[IMAGE_PAD].video_dev); -- unicam->node[IMAGE_PAD].registered = 0; -- } -- if (unicam->node[METADATA_PAD].registered) { -- video_unregister_device(&unicam->node[METADATA_PAD].video_dev); -- unicam->node[METADATA_PAD].registered = 0; -+ struct unicam_node *node; -+ int i; -+ -+ for (i = 0; i < MAX_NODES; i++) { -+ node = &unicam->node[i]; -+ if (node->dummy_buf_cpu_addr) { -+ dma_free_coherent(&unicam->pdev->dev, DUMMY_BUF_SIZE, -+ node->dummy_buf_cpu_addr, -+ node->dummy_buf_dma_addr); -+ } -+ if (node->registered) { -+ video_unregister_device(&node->video_dev); -+ node->registered = 0; -+ } - } - } - diff --git a/target/linux/bcm27xx/patches-5.15/950-0216-media-bcm2835-unicam-Disable-event-related-ioctls-on.patch b/target/linux/bcm27xx/patches-5.15/950-0216-media-bcm2835-unicam-Disable-event-related-ioctls-on.patch deleted file mode 100644 index 0015da5db..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0216-media-bcm2835-unicam-Disable-event-related-ioctls-on.patch +++ /dev/null @@ -1,31 +0,0 @@ -From e60e756a1354d248a01b4e1cd231c0ceb9d97a20 Mon Sep 17 00:00:00 2001 -From: Laurent Pinchart -Date: Tue, 24 Mar 2020 23:13:02 +0200 -Subject: [PATCH] media: bcm2835-unicam: Disable event-related ioctls - on metadata node - -The unicam driver supports both the SOURCE_CHANGE and CTRL events. Both -events are only generated on the image video node, so the event-related -ioctls are useless on the medatada node. Disable them. - -Signed-off-by: Laurent Pinchart -Reviewed-by: Jacopo Mondi -Reviewed-by: Naushir Patuck ---- - drivers/media/platform/bcm2835/bcm2835-unicam.c | 5 +++++ - 1 file changed, 5 insertions(+) - ---- a/drivers/media/platform/bcm2835/bcm2835-unicam.c -+++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c -@@ -2374,6 +2374,11 @@ static int register_node(struct unicam_d - return -ENOMEM; - } - -+ if (node->pad_id == METADATA_PAD) { -+ v4l2_disable_ioctl(vdev, VIDIOC_DQEVENT); -+ v4l2_disable_ioctl(vdev, VIDIOC_SUBSCRIBE_EVENT); -+ v4l2_disable_ioctl(vdev, VIDIOC_UNSUBSCRIBE_EVENT); -+ } - if (node->pad_id == METADATA_PAD || - !v4l2_subdev_has_op(unicam->sensor, video, s_std)) { - v4l2_disable_ioctl(&node->video_dev, VIDIOC_S_STD); diff --git a/target/linux/bcm27xx/patches-5.15/950-0217-media-bcm2835-unicam-Add-support-for-the-FRAME_SYNC-.patch b/target/linux/bcm27xx/patches-5.15/950-0217-media-bcm2835-unicam-Add-support-for-the-FRAME_SYNC-.patch deleted file mode 100644 index 7195ab179..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0217-media-bcm2835-unicam-Add-support-for-the-FRAME_SYNC-.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 507598bd205c63215a636e80acb95772f65a712e Mon Sep 17 00:00:00 2001 -From: Laurent Pinchart -Date: Tue, 24 Mar 2020 23:13:02 +0200 -Subject: [PATCH] media: bcm2835-unicam: Add support for the FRAME_SYNC - event - -The FRAME_SYNC event is useful for userspace image processing algorithms -to program the camera sensor as early as possible after frame start. -Support it. - -Signed-off-by: Laurent Pinchart -Reviewed-by: Kieran Bingham -Reviewed-by: Jacopo Mondi -Reviewed-by: Naushir Patuck ---- - drivers/media/platform/bcm2835/bcm2835-unicam.c | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - ---- a/drivers/media/platform/bcm2835/bcm2835-unicam.c -+++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c -@@ -772,6 +772,16 @@ static int unicam_all_nodes_disabled(str - !dev->node[METADATA_PAD].streaming; - } - -+static void unicam_queue_event_sof(struct unicam_device *unicam) -+{ -+ struct v4l2_event event = { -+ .type = V4L2_EVENT_FRAME_SYNC, -+ .u.frame_sync.frame_sequence = unicam->sequence, -+ }; -+ -+ v4l2_event_queue(&unicam->node[IMAGE_PAD].video_dev, &event); -+} -+ - /* - * unicam_isr : ISR handler for unicam capture - * @irq: irq number -@@ -853,6 +863,8 @@ static irqreturn_t unicam_isr(int irq, v - */ - unicam_schedule_dummy_buffer(&unicam->node[i]); - } -+ -+ unicam_queue_event_sof(unicam); - } - /* - * Cannot swap buffer at frame end, there may be a race condition -@@ -2022,6 +2034,8 @@ static int unicam_subscribe_event(struct - const struct v4l2_event_subscription *sub) - { - switch (sub->type) { -+ case V4L2_EVENT_FRAME_SYNC: -+ return v4l2_event_subscribe(fh, sub, 2, NULL); - case V4L2_EVENT_SOURCE_CHANGE: - return v4l2_event_subscribe(fh, sub, 4, NULL); - } diff --git a/target/linux/bcm27xx/patches-5.15/950-0218-media-bcm2835-unicam-Re-fetch-mbus-code-from-subdev-.patch b/target/linux/bcm27xx/patches-5.15/950-0218-media-bcm2835-unicam-Re-fetch-mbus-code-from-subdev-.patch deleted file mode 100644 index 9e5e8e974..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0218-media-bcm2835-unicam-Re-fetch-mbus-code-from-subdev-.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 15af88c051fb4807a5e8bb265288de52a650aea7 Mon Sep 17 00:00:00 2001 -From: Naushir Patuck -Date: Tue, 21 Apr 2020 16:26:03 +0100 -Subject: [PATCH] media: bcm2835-unicam: Re-fetch mbus code from subdev - on a g_fmt call - -The sensor subdevice may change the Bayer order if a H/V flip is -requested after a s_fmt call. Unicam g_fmt must call the subdev get_fmt -in case this has happened and return out the correct format 4cc. - -Signed-off-by: Naushir Patuck ---- - .../media/platform/bcm2835/bcm2835-unicam.c | 21 ++++++++++++++++++- - 1 file changed, 20 insertions(+), 1 deletion(-) - ---- a/drivers/media/platform/bcm2835/bcm2835-unicam.c -+++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c -@@ -967,11 +967,30 @@ static int unicam_enum_fmt_vid_cap(struc - static int unicam_g_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) - { -+ struct v4l2_mbus_framefmt mbus_fmt = {0}; - struct unicam_node *node = video_drvdata(file); -+ struct unicam_device *dev = node->dev; -+ const struct unicam_fmt *fmt = NULL; -+ int ret; - -- if (node->pad_id == METADATA_PAD) -+ if (node->pad_id != IMAGE_PAD) - return -EINVAL; - -+ /* -+ * If a flip has occurred in the sensor, the fmt code might have -+ * changed. So we will need to re-fetch the format from the subdevice. -+ */ -+ ret = __subdev_get_format(dev, &mbus_fmt, node->pad_id); -+ if (ret) -+ return -EINVAL; -+ -+ /* Find the V4L2 format from mbus code. We must match a known format. */ -+ fmt = find_format_by_code(mbus_fmt.code); -+ if (!fmt) -+ return -EINVAL; -+ -+ node->fmt = fmt; -+ node->v_fmt.fmt.pix.pixelformat = fmt->fourcc; - *f = node->v_fmt; - - return 0; diff --git a/target/linux/bcm27xx/patches-5.15/950-0223-media-bcm2835-unicam-Add-support-for-VIDIOC_-S-G-_SE.patch b/target/linux/bcm27xx/patches-5.15/950-0223-media-bcm2835-unicam-Add-support-for-VIDIOC_-S-G-_SE.patch deleted file mode 100644 index 18cffde79..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0223-media-bcm2835-unicam-Add-support-for-VIDIOC_-S-G-_SE.patch +++ /dev/null @@ -1,82 +0,0 @@ -From 2a6df1416027768c6e6f01ef39659b8b2e95f034 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Wed, 29 Apr 2020 16:45:02 +0100 -Subject: [PATCH] media: bcm2835-unicam: Add support for - VIDIOC_[S|G]_SELECTION - -Sensors are now reflecting cropping and scaling parameters through -the selection API, therefore Unicam needs to forward the requests -through to the subdev. - -Signed-off-by: Dave Stevenson ---- - .../media/platform/bcm2835/bcm2835-unicam.c | 44 +++++++++++++++++++ - 1 file changed, 44 insertions(+) - ---- a/drivers/media/platform/bcm2835/bcm2835-unicam.c -+++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c -@@ -1898,6 +1898,39 @@ static int unicam_g_edid(struct file *fi - return v4l2_subdev_call(dev->sensor, pad, get_edid, edid); - } - -+static int unicam_s_selection(struct file *file, void *priv, -+ struct v4l2_selection *sel) -+{ -+ struct unicam_node *node = video_drvdata(file); -+ struct unicam_device *dev = node->dev; -+ struct v4l2_subdev_selection sdsel = { -+ .which = V4L2_SUBDEV_FORMAT_ACTIVE, -+ .target = sel->target, -+ .flags = sel->flags, -+ .r = sel->r, -+ }; -+ -+ return v4l2_subdev_call(dev->sensor, pad, set_selection, NULL, &sdsel); -+} -+ -+static int unicam_g_selection(struct file *file, void *priv, -+ struct v4l2_selection *sel) -+{ -+ struct unicam_node *node = video_drvdata(file); -+ struct unicam_device *dev = node->dev; -+ struct v4l2_subdev_selection sdsel = { -+ .which = V4L2_SUBDEV_FORMAT_ACTIVE, -+ .target = sel->target, -+ }; -+ int ret; -+ -+ ret = v4l2_subdev_call(dev->sensor, pad, get_selection, NULL, &sdsel); -+ if (!ret) -+ sel->r = sdsel.r; -+ -+ return ret; -+} -+ - static int unicam_enum_framesizes(struct file *file, void *priv, - struct v4l2_frmsizeenum *fsize) - { -@@ -2218,6 +2251,9 @@ static const struct v4l2_ioctl_ops unica - .vidioc_enum_framesizes = unicam_enum_framesizes, - .vidioc_enum_frameintervals = unicam_enum_frameintervals, - -+ .vidioc_g_selection = unicam_g_selection, -+ .vidioc_s_selection = unicam_s_selection, -+ - .vidioc_g_parm = unicam_g_parm, - .vidioc_s_parm = unicam_s_parm, - -@@ -2446,6 +2482,14 @@ static int register_node(struct unicam_d - !v4l2_subdev_has_op(unicam->sensor, pad, enum_frame_size)) - v4l2_disable_ioctl(&node->video_dev, VIDIOC_ENUM_FRAMESIZES); - -+ if (node->pad_id == METADATA_PAD || -+ !v4l2_subdev_has_op(unicam->sensor, pad, set_selection)) -+ v4l2_disable_ioctl(&node->video_dev, VIDIOC_S_SELECTION); -+ -+ if (node->pad_id == METADATA_PAD || -+ !v4l2_subdev_has_op(unicam->sensor, pad, get_selection)) -+ v4l2_disable_ioctl(&node->video_dev, VIDIOC_G_SELECTION); -+ - ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1); - if (ret) { - unicam_err(unicam, "Unable to register video device.\n"); diff --git a/target/linux/bcm27xx/patches-5.15/950-0224-media-bcm2835-unicam-Do-not-stop-streaming-in-unicam.patch b/target/linux/bcm27xx/patches-5.15/950-0224-media-bcm2835-unicam-Do-not-stop-streaming-in-unicam.patch deleted file mode 100644 index d15eb8247..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0224-media-bcm2835-unicam-Do-not-stop-streaming-in-unicam.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 8e878b9ef7d6078e5facad9ebc0eacca9cbe3688 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Wed, 29 Apr 2020 22:05:09 +0100 -Subject: [PATCH] media: bcm2835-unicam: Do not stop streaming in - unicam_release - -unicam_release calls _vb2_fop_release, which will call stop_streaming -if that particular node was streaming. Calling it unconditionally (as -the code was) means that if a second handle was opened eg to alter -a setting, on closing that connection it also stopped Unicam. - -Signed-off-by: Dave Stevenson ---- - drivers/media/platform/bcm2835/bcm2835-unicam.c | 3 --- - 1 file changed, 3 deletions(-) - ---- a/drivers/media/platform/bcm2835/bcm2835-unicam.c -+++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c -@@ -2204,9 +2204,6 @@ static int unicam_release(struct file *f - if (fh_singular) - v4l2_subdev_call(sd, core, s_power, 0); - -- if (node->streaming) -- unicam_stop_streaming(&node->buffer_queue); -- - node->open--; - mutex_unlock(&node->lock); - diff --git a/target/linux/bcm27xx/patches-5.15/950-0225-media-bcm2835-unicam-Fix-reference-counting-in-unica.patch b/target/linux/bcm27xx/patches-5.15/950-0225-media-bcm2835-unicam-Fix-reference-counting-in-unica.patch deleted file mode 100644 index 51e88cad1..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0225-media-bcm2835-unicam-Fix-reference-counting-in-unica.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 25ab75ec729423e9e230ef3fe027c275ab17addb Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 30 Apr 2020 09:52:50 +0100 -Subject: [PATCH] media: bcm2835-unicam: Fix reference counting in - unicam_open - -The reference counting of node->open was only incremented after -a check that the node was v4l2_fh_is_singular_file, which resulted -in the counting going wrong and s_power not being called at an -appropriate time. - -Signed-off-by: Dave Stevenson ---- - drivers/media/platform/bcm2835/bcm2835-unicam.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - ---- a/drivers/media/platform/bcm2835/bcm2835-unicam.c -+++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c -@@ -2170,16 +2170,18 @@ static int unicam_open(struct file *file - goto unlock; - } - -+ node->open++; -+ - if (!v4l2_fh_is_singular_file(file)) - goto unlock; - - ret = v4l2_subdev_call(dev->sensor, core, s_power, 1); - if (ret < 0 && ret != -ENOIOCTLCMD) { - v4l2_fh_release(file); -+ node->open--; - goto unlock; - } - -- node->open++; - ret = 0; - - unlock: diff --git a/target/linux/bcm27xx/patches-5.15/950-0227-media-bcm2835-unicam-Fix-uninitialized-warning.patch b/target/linux/bcm27xx/patches-5.15/950-0227-media-bcm2835-unicam-Fix-uninitialized-warning.patch deleted file mode 100644 index 30404168e..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0227-media-bcm2835-unicam-Fix-uninitialized-warning.patch +++ /dev/null @@ -1,21 +0,0 @@ -From 9daa9e4fe269c5b1fbdeee4e8219ac204b84c72c Mon Sep 17 00:00:00 2001 -From: Jacko Dirks -Date: Tue, 5 May 2020 14:33:31 +0200 -Subject: [PATCH] media: bcm2835: unicam: Fix uninitialized warning - -Signed-off-by: Jacko Dirks ---- - drivers/media/platform/bcm2835/bcm2835-unicam.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/media/platform/bcm2835/bcm2835-unicam.c -+++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c -@@ -1001,7 +1001,7 @@ const struct unicam_fmt *get_first_suppo - { - struct v4l2_subdev_mbus_code_enum mbus_code; - const struct unicam_fmt *fmt = NULL; -- int ret; -+ int ret = 0; - int j; - - for (j = 0; ret != -EINVAL && ret != -ENOIOCTLCMD; ++j) { diff --git a/target/linux/bcm27xx/patches-5.15/950-0229-dt-bindings-media-i2c-Add-IMX477-CMOS-sensor-binding.patch b/target/linux/bcm27xx/patches-5.15/950-0229-dt-bindings-media-i2c-Add-IMX477-CMOS-sensor-binding.patch deleted file mode 100644 index 5e8143510..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0229-dt-bindings-media-i2c-Add-IMX477-CMOS-sensor-binding.patch +++ /dev/null @@ -1,130 +0,0 @@ -From d46001f333424af540e02d2a19c11205d40a11f3 Mon Sep 17 00:00:00 2001 -From: Naushir Patuck -Date: Thu, 7 May 2020 15:50:54 +0100 -Subject: [PATCH] dt-bindings: media: i2c: Add IMX477 CMOS sensor - binding - -Add YAML device tree binding for IMX477 CMOS image sensor. - -Signed-off-by: Naushir Patuck ---- - .../devicetree/bindings/media/i2c/imx477.yaml | 113 ++++++++++++++++++ - 1 file changed, 113 insertions(+) - create mode 100644 Documentation/devicetree/bindings/media/i2c/imx477.yaml - ---- /dev/null -+++ b/Documentation/devicetree/bindings/media/i2c/imx477.yaml -@@ -0,0 +1,113 @@ -+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) -+%YAML 1.2 -+--- -+$id: http://devicetree.org/schemas/media/i2c/imx477.yaml# -+$schema: http://devicetree.org/meta-schemas/core.yaml# -+ -+title: Sony 1/2.3-Inch 12Mpixel CMOS Digital Image Sensor -+ -+maintainers: -+ - Naushir Patuck -+ -+description: |- -+ The Sony IMX477 is a 1/2.3-inch CMOS active pixel digital image sensor -+ with an active array size of 4056H x 3040V. It is programmable through -+ I2C interface. The I2C address is fixed to 0x1A as per sensor data sheet. -+ Image data is sent through MIPI CSI-2, which is configured as either 2 or -+ 4 data lanes. -+ -+properties: -+ compatible: -+ const: sony,imx477 -+ -+ reg: -+ description: I2C device address -+ maxItems: 1 -+ -+ clocks: -+ maxItems: 1 -+ -+ VDIG-supply: -+ description: -+ Digital I/O voltage supply, 1.05 volts -+ -+ VANA-supply: -+ description: -+ Analog voltage supply, 2.8 volts -+ -+ VDDL-supply: -+ description: -+ Digital core voltage supply, 1.8 volts -+ -+ reset-gpios: -+ description: |- -+ Reference to the GPIO connected to the xclr pin, if any. -+ Must be released (set high) after all all supplies and INCK are applied. -+ -+ # See ../video-interfaces.txt for more details -+ port: -+ type: object -+ properties: -+ endpoint: -+ type: object -+ properties: -+ data-lanes: -+ description: |- -+ The sensor supports either two-lane, or four-lane operation. -+ For two-lane operation the property must be set to <1 2>. -+ items: -+ - const: 1 -+ - const: 2 -+ -+ clock-noncontinuous: -+ type: boolean -+ description: |- -+ MIPI CSI-2 clock is non-continuous if this property is present, -+ otherwise it's continuous. -+ -+ link-frequencies: -+ allOf: -+ - $ref: /schemas/types.yaml#/definitions/uint64-array -+ description: -+ Allowed data bus frequencies. -+ -+ required: -+ - link-frequencies -+ -+required: -+ - compatible -+ - reg -+ - clocks -+ - VANA-supply -+ - VDIG-supply -+ - VDDL-supply -+ - port -+ -+additionalProperties: false -+ -+examples: -+ - | -+ i2c0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ imx477: sensor@10 { -+ compatible = "sony,imx477"; -+ reg = <0x1a>; -+ clocks = <&imx477_clk>; -+ VANA-supply = <&imx477_vana>; /* 2.8v */ -+ VDIG-supply = <&imx477_vdig>; /* 1.05v */ -+ VDDL-supply = <&imx477_vddl>; /* 1.8v */ -+ -+ port { -+ imx477_0: endpoint { -+ remote-endpoint = <&csi1_ep>; -+ data-lanes = <1 2>; -+ clock-noncontinuous; -+ link-frequencies = /bits/ 64 <450000000>; -+ }; -+ }; -+ }; -+ }; -+ -+... diff --git a/target/linux/bcm27xx/patches-5.15/950-0230-media-bcm2835-unicam-Always-service-interrupts.patch b/target/linux/bcm27xx/patches-5.15/950-0230-media-bcm2835-unicam-Always-service-interrupts.patch deleted file mode 100644 index a941d8258..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0230-media-bcm2835-unicam-Always-service-interrupts.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 04d21a5b2bbfee3b0a09c72ea5c11cfef10b08c1 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Wed, 13 May 2020 18:28:27 +0100 -Subject: [PATCH] media: bcm2835-unicam: Always service interrupts - -From when bringing up the driver, there was a check in the isr -to ignore interrupts (claiming them handled) should the driver -not be streaming. - -The VPU now will not register a camera driver if it finds a -CSI2 node enabled in device tree, therefore this flawed check is -redundant. - -https://github.com/raspberrypi/linux/issues/3602 - -Signed-off-by: Dave Stevenson ---- - drivers/media/platform/bcm2835/bcm2835-unicam.c | 15 --------------- - 1 file changed, 15 deletions(-) - ---- a/drivers/media/platform/bcm2835/bcm2835-unicam.c -+++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c -@@ -766,12 +766,6 @@ static int unicam_all_nodes_streaming(st - return ret; - } - --static int unicam_all_nodes_disabled(struct unicam_device *dev) --{ -- return !dev->node[IMAGE_PAD].streaming && -- !dev->node[METADATA_PAD].streaming; --} -- - static void unicam_queue_event_sof(struct unicam_device *unicam) - { - struct v4l2_event event = { -@@ -801,15 +795,6 @@ static irqreturn_t unicam_isr(int irq, v - u64 ts; - int i; - -- /* -- * Don't service interrupts if not streaming. -- * Avoids issues if the VPU should enable the -- * peripheral without the kernel knowing (that -- * shouldn't happen, but causes issues if it does). -- */ -- if (unicam_all_nodes_disabled(unicam)) -- return IRQ_HANDLED; -- - sta = reg_read(cfg, UNICAM_STA); - /* Write value back to clear the interrupts */ - reg_write(cfg, UNICAM_STA, sta); diff --git a/target/linux/bcm27xx/patches-5.15/950-0231-sc16is7xx-Fix-for-hardware-flow-control.patch b/target/linux/bcm27xx/patches-5.15/950-0231-sc16is7xx-Fix-for-hardware-flow-control.patch deleted file mode 100644 index ce66193e7..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0231-sc16is7xx-Fix-for-hardware-flow-control.patch +++ /dev/null @@ -1,70 +0,0 @@ -From e37d08d5cc0eece55a886f52ef35ac148acabe08 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 13 May 2020 20:10:15 +0100 -Subject: [PATCH] sc16is7xx: Fix for hardware flow control - -The SC16IS7XX hardware flow control is mishandled by the driver in -a number of ways: - - 1. The set_baud method accidentally clears it when setting EFR bit. - 2. Even though hardware flow control is enabled, it isn't indicated - back to the serial framework. - 3. Applying the flow control clears the EFR bit. - 4. The CTS support is not indicated in the return from - sc16is7xx_get_mctrl. - -Address all of those issues using a mixture of patches found on the -linked pages. - -See: https://github.com/raspberrypi/linux/issues/2542 -See: https://www.spinics.net/lists/linux-serial/msg21794.html - -Signed-off-by: Phil Elwell ---- - drivers/tty/serial/sc16is7xx.c | 14 ++++++++++---- - 1 file changed, 10 insertions(+), 4 deletions(-) - ---- a/drivers/tty/serial/sc16is7xx.c -+++ b/drivers/tty/serial/sc16is7xx.c -@@ -524,8 +524,9 @@ static int sc16is7xx_set_baud(struct uar - - /* Enable enhanced features */ - regcache_cache_bypass(s->regmap, true); -- sc16is7xx_port_write(port, SC16IS7XX_EFR_REG, -- SC16IS7XX_EFR_ENABLE_BIT); -+ sc16is7xx_port_update(port, SC16IS7XX_EFR_REG, -+ SC16IS7XX_EFR_ENABLE_BIT, -+ SC16IS7XX_EFR_ENABLE_BIT); - regcache_cache_bypass(s->regmap, false); - - /* Put LCR back to the normal mode */ -@@ -855,7 +856,7 @@ static unsigned int sc16is7xx_get_mctrl( - /* DCD and DSR are not wired and CTS/RTS is handled automatically - * so just indicate DSR and CAR asserted - */ -- return TIOCM_DSR | TIOCM_CAR; -+ return TIOCM_DSR | TIOCM_CAR | TIOCM_RI | TIOCM_CTS; - } - - static void sc16is7xx_set_mctrl(struct uart_port *port, unsigned int mctrl) -@@ -942,14 +943,19 @@ static void sc16is7xx_set_termios(struct - regcache_cache_bypass(s->regmap, true); - sc16is7xx_port_write(port, SC16IS7XX_XON1_REG, termios->c_cc[VSTART]); - sc16is7xx_port_write(port, SC16IS7XX_XOFF1_REG, termios->c_cc[VSTOP]); -- if (termios->c_cflag & CRTSCTS) -+ if (termios->c_cflag & CRTSCTS) { - flow |= SC16IS7XX_EFR_AUTOCTS_BIT | - SC16IS7XX_EFR_AUTORTS_BIT; -+ port->status |= UPSTAT_AUTOCTS; -+ }; - if (termios->c_iflag & IXON) - flow |= SC16IS7XX_EFR_SWFLOW3_BIT; - if (termios->c_iflag & IXOFF) - flow |= SC16IS7XX_EFR_SWFLOW1_BIT; - -+ /* Always set enable enhanced */ -+ flow |= SC16IS7XX_EFR_ENABLE_BIT; -+ - sc16is7xx_port_write(port, SC16IS7XX_EFR_REG, flow); - regcache_cache_bypass(s->regmap, false); - diff --git a/target/linux/bcm27xx/patches-5.15/950-0236-media-bcm2835-unicam-change-minimum-number-of-vb2_qu.patch b/target/linux/bcm27xx/patches-5.15/950-0236-media-bcm2835-unicam-change-minimum-number-of-vb2_qu.patch deleted file mode 100644 index a921e0797..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0236-media-bcm2835-unicam-change-minimum-number-of-vb2_qu.patch +++ /dev/null @@ -1,28 +0,0 @@ -From a516ca77e73d369486803865e06a6854b6f0dd97 Mon Sep 17 00:00:00 2001 -From: David Plowman -Date: Thu, 28 May 2020 11:09:48 +0100 -Subject: [PATCH] media: bcm2835-unicam: change minimum number of - vb2_queue buffers to 1 - -Since the unicam driver was modified to write to a dummy buffer when no -user-supplied buffer is available, it can now write to and return a -buffer even when there's only a single one. Enable this by changing the -min_buffers_needed in the vb2_queue; it will be useful for enabling -still captures without allocating more memory than absolutely necessary. - -Signed-off-by: David Plowman ---- - drivers/media/platform/bcm2835/bcm2835-unicam.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/media/platform/bcm2835/bcm2835-unicam.c -+++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c -@@ -2404,7 +2404,7 @@ static int register_node(struct unicam_d - q->buf_struct_size = sizeof(struct unicam_buffer); - q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; - q->lock = &node->lock; -- q->min_buffers_needed = 2; -+ q->min_buffers_needed = 1; - q->dev = &unicam->pdev->dev; - - ret = vb2_queue_init(q); diff --git a/target/linux/bcm27xx/patches-5.15/950-0237-snd_bcm2835-disable-HDMI-audio-when-vc4-is-used-3640.patch b/target/linux/bcm27xx/patches-5.15/950-0237-snd_bcm2835-disable-HDMI-audio-when-vc4-is-used-3640.patch deleted file mode 100644 index 6277667da..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0237-snd_bcm2835-disable-HDMI-audio-when-vc4-is-used-3640.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 3b5412d506f5b7f2d947346ccdda8b67c9902576 Mon Sep 17 00:00:00 2001 -From: Hristo Venev -Date: Fri, 5 Jun 2020 09:22:49 +0000 -Subject: [PATCH] snd_bcm2835: disable HDMI audio when vc4 is used - (#3640) - -Things don't work too well when both the vc4 driver and the firmware -driver are trying to control the same audio output: - -[ 763.569406] bcm2835_audio bcm2835_audio: vchi message timeout, msg=5 - -Hence, when the vc4 HDMI driver is used, let it control audio. This is done -by introducing a new device tree property to the audio node, and -extending the vc4-kms-v3d overlays to set it appropriately. - -Signed-off-by: Hristo Venev ---- - drivers/staging/vc04_services/bcm2835-audio/bcm2835.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c -@@ -381,7 +381,9 @@ static int snd_bcm2835_alsa_probe(struct - } - - if (!enable_compat_alsa) { -- set_hdmi_enables(dev); -+ if (!of_property_read_bool(dev->of_node, "brcm,disable-hdmi")) -+ set_hdmi_enables(dev); -+ - // In this mode, always enable analog output - enable_headphones = true; - } else { diff --git a/target/linux/bcm27xx/patches-5.15/950-0244-staging-bcm2835-audio-Add-missing-MODULE_ALIAS.patch b/target/linux/bcm27xx/patches-5.15/950-0244-staging-bcm2835-audio-Add-missing-MODULE_ALIAS.patch deleted file mode 100644 index b28e8b555..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0244-staging-bcm2835-audio-Add-missing-MODULE_ALIAS.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 013c1eecd74e1c40eda16fc6230e6d4ec6106d53 Mon Sep 17 00:00:00 2001 -From: Maxim Mikityanskiy -Date: Sat, 20 Jun 2020 15:40:00 +0300 -Subject: [PATCH] staging: bcm2835-audio: Add missing MODULE_ALIAS - -Commit 8353fe6f1e0f ("Revert "staging: bcm2835-audio: Drop DT -dependency"") reverts the upstream change and makes bcm2835-audio use -device tree again, however, it also removes the MODULE_ALIAS for the -platform device. This MODULE_ALIAS is needed, because VCHIQ registers -bcm2835-audio as a child platform device since commit 25c7597af20d -("staging: vchiq_arm: Register a platform device for audio"), and this -mechanism is adopted also in the downstream kernel. - -This commit puts back that MODULE_ALIAS to make bcm2835-audio -autoprobing work again. The rest of VCHIQ children have their -MODULE_ALIASes in place. - -Fixes: 8353fe6f1e0f ("Revert "staging: bcm2835-audio: Drop DT dependency"") -Signed-off-by: Maxim Mikityanskiy ---- - drivers/staging/vc04_services/bcm2835-audio/bcm2835.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c -@@ -438,3 +438,4 @@ module_platform_driver(bcm2835_alsa_driv - MODULE_AUTHOR("Dom Cobley"); - MODULE_DESCRIPTION("Alsa driver for BCM2835 chip"); - MODULE_LICENSE("GPL"); -+MODULE_ALIAS("platform:bcm2835_audio"); diff --git a/target/linux/bcm27xx/patches-5.15/950-0245-drivers-media-Remove-the-downstream-version-of-bcm28.patch b/target/linux/bcm27xx/patches-5.15/950-0245-drivers-media-Remove-the-downstream-version-of-bcm28.patch deleted file mode 100644 index 36893a99e..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0245-drivers-media-Remove-the-downstream-version-of-bcm28.patch +++ /dev/null @@ -1,3175 +0,0 @@ -From 606a02e0617f3adbcdd7aa82913771403d137269 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 23 Jun 2020 10:05:57 +0100 -Subject: [PATCH] drivers: media: Remove the downstream version of - bcm2835-unicam - -About to be replaced by the upstream version. - -Signed-off-by: Dave Stevenson ---- - drivers/media/platform/bcm2835/Kconfig | 14 - - drivers/media/platform/bcm2835/Makefile | 3 - - .../media/platform/bcm2835/bcm2835-unicam.c | 2873 ----------------- - .../media/platform/bcm2835/vc4-regs-unicam.h | 253 -- - 4 files changed, 3143 deletions(-) - delete mode 100644 drivers/media/platform/bcm2835/Kconfig - delete mode 100644 drivers/media/platform/bcm2835/Makefile - delete mode 100644 drivers/media/platform/bcm2835/bcm2835-unicam.c - delete mode 100644 drivers/media/platform/bcm2835/vc4-regs-unicam.h - ---- a/drivers/media/platform/bcm2835/Kconfig -+++ /dev/null -@@ -1,14 +0,0 @@ --# Broadcom VideoCore4 V4L2 camera support -- --config VIDEO_BCM2835_UNICAM -- tristate "Broadcom BCM2835 Unicam video capture driver" -- depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && MEDIA_CONTROLLER -- depends on ARCH_BCM2835 || COMPILE_TEST -- select VIDEOBUF2_DMA_CONTIG -- select V4L2_FWNODE -- help -- Say Y here to enable V4L2 subdevice for CSI2 receiver. -- This is a V4L2 subdevice that interfaces directly to the VC4 peripheral. -- -- To compile this driver as a module, choose M here. The module -- will be called bcm2835-unicam. ---- a/drivers/media/platform/bcm2835/Makefile -+++ /dev/null -@@ -1,3 +0,0 @@ --# Makefile for BCM2835 Unicam driver -- --obj-$(CONFIG_VIDEO_BCM2835_UNICAM) += bcm2835-unicam.o ---- a/drivers/media/platform/bcm2835/bcm2835-unicam.c -+++ /dev/null -@@ -1,2873 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0-only --/* -- * BCM2835 Unicam Capture Driver -- * -- * Copyright (C) 2017-2020 - Raspberry Pi (Trading) Ltd. -- * -- * Dave Stevenson -- * -- * Based on TI am437x driver by -- * Benoit Parrot -- * Lad, Prabhakar -- * -- * and TI CAL camera interface driver by -- * Benoit Parrot -- * -- * -- * There are two camera drivers in the kernel for BCM283x - this one -- * and bcm2835-camera (currently in staging). -- * -- * This driver directly controls the Unicam peripheral - there is no -- * involvement with the VideoCore firmware. Unicam receives CSI-2 or -- * CCP2 data and writes it into SDRAM. -- * The only potential processing options are to repack Bayer data into an -- * alternate format, and applying windowing. -- * The repacking does not shift the data, so can repack V4L2_PIX_FMT_Sxxxx10P -- * to V4L2_PIX_FMT_Sxxxx10, or V4L2_PIX_FMT_Sxxxx12P to V4L2_PIX_FMT_Sxxxx12, -- * but not generically up to V4L2_PIX_FMT_Sxxxx16. The driver will add both -- * formats where the relevant formats are defined, and will automatically -- * configure the repacking as required. -- * Support for windowing may be added later. -- * -- * It should be possible to connect this driver to any sensor with a -- * suitable output interface and V4L2 subdevice driver. -- * -- * bcm2835-camera uses the VideoCore firmware to control the sensor, -- * Unicam, ISP, and all tuner control loops. Fully processed frames are -- * delivered to the driver by the firmware. It only has sensor drivers -- * for Omnivision OV5647, and Sony IMX219 sensors. -- * -- * The two drivers are mutually exclusive for the same Unicam instance. -- * The VideoCore firmware checks the device tree configuration during boot. -- * If it finds device tree nodes called csi0 or csi1 it will block the -- * firmware from accessing the peripheral, and bcm2835-camera will -- * not be able to stream data. -- */ -- --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#include "vc4-regs-unicam.h" -- --#define UNICAM_MODULE_NAME "unicam" --#define UNICAM_VERSION "0.1.0" -- --static int debug; --module_param(debug, int, 0644); --MODULE_PARM_DESC(debug, "Debug level 0-3"); -- --#define unicam_dbg(level, dev, fmt, arg...) \ -- v4l2_dbg(level, debug, &(dev)->v4l2_dev, fmt, ##arg) --#define unicam_info(dev, fmt, arg...) \ -- v4l2_info(&(dev)->v4l2_dev, fmt, ##arg) --#define unicam_err(dev, fmt, arg...) \ -- v4l2_err(&(dev)->v4l2_dev, fmt, ##arg) -- --/* To protect against a dodgy sensor driver never returning an error from -- * enum_mbus_code, set a maximum index value to be used. -- */ --#define MAX_ENUM_MBUS_CODE 128 -- --/* -- * Stride is a 16 bit register, but also has to be a multiple of 32. -- */ --#define BPL_ALIGNMENT 32 --#define MAX_BYTESPERLINE ((1 << 16) - BPL_ALIGNMENT) --/* -- * Max width is therefore determined by the max stride divided by -- * the number of bits per pixel. Take 32bpp as a -- * worst case. -- * No imposed limit on the height, so adopt a square image for want -- * of anything better. -- */ --#define MAX_WIDTH (MAX_BYTESPERLINE / 4) --#define MAX_HEIGHT MAX_WIDTH --/* Define a nominal minimum image size */ --#define MIN_WIDTH 16 --#define MIN_HEIGHT 16 --/* Default size of the embedded buffer */ --#define UNICAM_EMBEDDED_SIZE 8192 -- --/* -- * Size of the dummy buffer. Can be any size really, but the DMA -- * allocation works in units of page sizes. -- */ --#define DUMMY_BUF_SIZE (PAGE_SIZE) -- --enum pad_types { -- IMAGE_PAD, -- METADATA_PAD, -- MAX_NODES --}; -- --/* -- * struct unicam_fmt - Unicam media bus format information -- * @pixelformat: V4L2 pixel format FCC identifier. 0 if n/a. -- * @repacked_fourcc: V4L2 pixel format FCC identifier if the data is expanded -- * out to 16bpp. 0 if n/a. -- * @code: V4L2 media bus format code. -- * @depth: Bits per pixel as delivered from the source. -- * @csi_dt: CSI data type. -- * @check_variants: Flag to denote that there are multiple mediabus formats -- * still in the list that could match this V4L2 format. -- */ --struct unicam_fmt { -- u32 fourcc; -- u32 repacked_fourcc; -- u32 code; -- u8 depth; -- u8 csi_dt; -- u8 check_variants; --}; -- --static const struct unicam_fmt formats[] = { -- /* YUV Formats */ -- { -- .fourcc = V4L2_PIX_FMT_YUYV, -- .code = MEDIA_BUS_FMT_YUYV8_2X8, -- .depth = 16, -- .csi_dt = 0x1e, -- .check_variants = 1, -- }, { -- .fourcc = V4L2_PIX_FMT_UYVY, -- .code = MEDIA_BUS_FMT_UYVY8_2X8, -- .depth = 16, -- .csi_dt = 0x1e, -- .check_variants = 1, -- }, { -- .fourcc = V4L2_PIX_FMT_YVYU, -- .code = MEDIA_BUS_FMT_YVYU8_2X8, -- .depth = 16, -- .csi_dt = 0x1e, -- .check_variants = 1, -- }, { -- .fourcc = V4L2_PIX_FMT_VYUY, -- .code = MEDIA_BUS_FMT_VYUY8_2X8, -- .depth = 16, -- .csi_dt = 0x1e, -- .check_variants = 1, -- }, { -- .fourcc = V4L2_PIX_FMT_YUYV, -- .code = MEDIA_BUS_FMT_YUYV8_1X16, -- .depth = 16, -- .csi_dt = 0x1e, -- }, { -- .fourcc = V4L2_PIX_FMT_UYVY, -- .code = MEDIA_BUS_FMT_UYVY8_1X16, -- .depth = 16, -- .csi_dt = 0x1e, -- }, { -- .fourcc = V4L2_PIX_FMT_YVYU, -- .code = MEDIA_BUS_FMT_YVYU8_1X16, -- .depth = 16, -- .csi_dt = 0x1e, -- }, { -- .fourcc = V4L2_PIX_FMT_VYUY, -- .code = MEDIA_BUS_FMT_VYUY8_1X16, -- .depth = 16, -- .csi_dt = 0x1e, -- }, { -- /* RGB Formats */ -- .fourcc = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */ -- .code = MEDIA_BUS_FMT_RGB565_2X8_LE, -- .depth = 16, -- .csi_dt = 0x22, -- }, { -- .fourcc = V4L2_PIX_FMT_RGB565X, /* rrrrrggg gggbbbbb */ -- .code = MEDIA_BUS_FMT_RGB565_2X8_BE, -- .depth = 16, -- .csi_dt = 0x22 -- }, { -- .fourcc = V4L2_PIX_FMT_RGB555, /* gggbbbbb arrrrrgg */ -- .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE, -- .depth = 16, -- .csi_dt = 0x21, -- }, { -- .fourcc = V4L2_PIX_FMT_RGB555X, /* arrrrrgg gggbbbbb */ -- .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE, -- .depth = 16, -- .csi_dt = 0x21, -- }, { -- .fourcc = V4L2_PIX_FMT_RGB24, /* rgb */ -- .code = MEDIA_BUS_FMT_RGB888_1X24, -- .depth = 24, -- .csi_dt = 0x24, -- }, { -- .fourcc = V4L2_PIX_FMT_BGR24, /* bgr */ -- .code = MEDIA_BUS_FMT_BGR888_1X24, -- .depth = 24, -- .csi_dt = 0x24, -- }, { -- .fourcc = V4L2_PIX_FMT_RGB32, /* argb */ -- .code = MEDIA_BUS_FMT_ARGB8888_1X32, -- .depth = 32, -- .csi_dt = 0x0, -- }, { -- /* Bayer Formats */ -- .fourcc = V4L2_PIX_FMT_SBGGR8, -- .code = MEDIA_BUS_FMT_SBGGR8_1X8, -- .depth = 8, -- .csi_dt = 0x2a, -- }, { -- .fourcc = V4L2_PIX_FMT_SGBRG8, -- .code = MEDIA_BUS_FMT_SGBRG8_1X8, -- .depth = 8, -- .csi_dt = 0x2a, -- }, { -- .fourcc = V4L2_PIX_FMT_SGRBG8, -- .code = MEDIA_BUS_FMT_SGRBG8_1X8, -- .depth = 8, -- .csi_dt = 0x2a, -- }, { -- .fourcc = V4L2_PIX_FMT_SRGGB8, -- .code = MEDIA_BUS_FMT_SRGGB8_1X8, -- .depth = 8, -- .csi_dt = 0x2a, -- }, { -- .fourcc = V4L2_PIX_FMT_SBGGR10P, -- .repacked_fourcc = V4L2_PIX_FMT_SBGGR10, -- .code = MEDIA_BUS_FMT_SBGGR10_1X10, -- .depth = 10, -- .csi_dt = 0x2b, -- }, { -- .fourcc = V4L2_PIX_FMT_SGBRG10P, -- .repacked_fourcc = V4L2_PIX_FMT_SGBRG10, -- .code = MEDIA_BUS_FMT_SGBRG10_1X10, -- .depth = 10, -- .csi_dt = 0x2b, -- }, { -- .fourcc = V4L2_PIX_FMT_SGRBG10P, -- .repacked_fourcc = V4L2_PIX_FMT_SGRBG10, -- .code = MEDIA_BUS_FMT_SGRBG10_1X10, -- .depth = 10, -- .csi_dt = 0x2b, -- }, { -- .fourcc = V4L2_PIX_FMT_SRGGB10P, -- .repacked_fourcc = V4L2_PIX_FMT_SRGGB10, -- .code = MEDIA_BUS_FMT_SRGGB10_1X10, -- .depth = 10, -- .csi_dt = 0x2b, -- }, { -- .fourcc = V4L2_PIX_FMT_SBGGR12P, -- .repacked_fourcc = V4L2_PIX_FMT_SBGGR12, -- .code = MEDIA_BUS_FMT_SBGGR12_1X12, -- .depth = 12, -- .csi_dt = 0x2c, -- }, { -- .fourcc = V4L2_PIX_FMT_SGBRG12P, -- .repacked_fourcc = V4L2_PIX_FMT_SGBRG12, -- .code = MEDIA_BUS_FMT_SGBRG12_1X12, -- .depth = 12, -- .csi_dt = 0x2c, -- }, { -- .fourcc = V4L2_PIX_FMT_SGRBG12P, -- .repacked_fourcc = V4L2_PIX_FMT_SGRBG12, -- .code = MEDIA_BUS_FMT_SGRBG12_1X12, -- .depth = 12, -- .csi_dt = 0x2c, -- }, { -- .fourcc = V4L2_PIX_FMT_SRGGB12P, -- .repacked_fourcc = V4L2_PIX_FMT_SRGGB12, -- .code = MEDIA_BUS_FMT_SRGGB12_1X12, -- .depth = 12, -- .csi_dt = 0x2c, -- }, { -- .fourcc = V4L2_PIX_FMT_SBGGR14P, -- .code = MEDIA_BUS_FMT_SBGGR14_1X14, -- .depth = 14, -- .csi_dt = 0x2d, -- }, { -- .fourcc = V4L2_PIX_FMT_SGBRG14P, -- .code = MEDIA_BUS_FMT_SGBRG14_1X14, -- .depth = 14, -- .csi_dt = 0x2d, -- }, { -- .fourcc = V4L2_PIX_FMT_SGRBG14P, -- .code = MEDIA_BUS_FMT_SGRBG14_1X14, -- .depth = 14, -- .csi_dt = 0x2d, -- }, { -- .fourcc = V4L2_PIX_FMT_SRGGB14P, -- .code = MEDIA_BUS_FMT_SRGGB14_1X14, -- .depth = 14, -- .csi_dt = 0x2d, -- }, { -- /* -- * 16 bit Bayer formats could be supported, but there is no CSI2 -- * data_type defined for raw 16, and no sensors that produce it at -- * present. -- */ -- -- /* Greyscale formats */ -- .fourcc = V4L2_PIX_FMT_GREY, -- .code = MEDIA_BUS_FMT_Y8_1X8, -- .depth = 8, -- .csi_dt = 0x2a, -- }, { -- .fourcc = V4L2_PIX_FMT_Y10P, -- .repacked_fourcc = V4L2_PIX_FMT_Y10, -- .code = MEDIA_BUS_FMT_Y10_1X10, -- .depth = 10, -- .csi_dt = 0x2b, -- }, { -- /* NB There is no packed V4L2 fourcc for this format. */ -- .repacked_fourcc = V4L2_PIX_FMT_Y12, -- .code = MEDIA_BUS_FMT_Y12_1X12, -- .depth = 12, -- .csi_dt = 0x2c, -- }, -- /* Embedded data format */ -- { -- .fourcc = V4L2_META_FMT_SENSOR_DATA, -- .code = MEDIA_BUS_FMT_SENSOR_DATA, -- .depth = 8, -- } --}; -- --struct unicam_dmaqueue { -- struct list_head active; --}; -- --struct unicam_buffer { -- struct vb2_v4l2_buffer vb; -- struct list_head list; --}; -- --struct unicam_cfg { -- /* peripheral base address */ -- void __iomem *base; -- /* clock gating base address */ -- void __iomem *clk_gate_base; --}; -- --#define MAX_POSSIBLE_PIX_FMTS (ARRAY_SIZE(formats)) -- --struct unicam_node { -- int registered; -- int open; -- int streaming; -- unsigned int pad_id; -- /* Pointer pointing to current v4l2_buffer */ -- struct unicam_buffer *cur_frm; -- /* Pointer pointing to next v4l2_buffer */ -- struct unicam_buffer *next_frm; -- /* video capture */ -- const struct unicam_fmt *fmt; -- /* Used to store current pixel format */ -- struct v4l2_format v_fmt; -- /* Used to store current mbus frame format */ -- struct v4l2_mbus_framefmt m_fmt; -- /* Buffer queue used in video-buf */ -- struct vb2_queue buffer_queue; -- /* Queue of filled frames */ -- struct unicam_dmaqueue dma_queue; -- /* IRQ lock for DMA queue */ -- spinlock_t dma_queue_lock; -- /* lock used to access this structure */ -- struct mutex lock; -- /* Identifies video device for this channel */ -- struct video_device video_dev; -- /* Pointer to the parent handle */ -- struct unicam_device *dev; -- struct media_pad pad; -- struct v4l2_ctrl_handler ctrl_handler; -- unsigned int embedded_lines; -- /* -- * Dummy buffer intended to be used by unicam -- * if we have no other queued buffers to swap to. -- */ -- void *dummy_buf_cpu_addr; -- dma_addr_t dummy_buf_dma_addr; --}; -- --struct unicam_device { -- /* V4l2 specific parameters */ -- -- struct v4l2_fwnode_endpoint endpoint; -- -- struct v4l2_async_subdev asd; -- -- /* unicam cfg */ -- struct unicam_cfg cfg; -- /* clock handle */ -- struct clk *clock; -- /* V4l2 device */ -- struct v4l2_device v4l2_dev; -- struct media_device mdev; -- -- /* parent device */ -- struct platform_device *pdev; -- /* subdevice async Notifier */ -- struct v4l2_async_notifier notifier; -- unsigned int sequence; -- -- /* ptr to sub device */ -- struct v4l2_subdev *sensor; -- /* Pad config for the sensor */ -- struct v4l2_subdev_pad_config *sensor_config; -- -- unsigned int virtual_channel; -- enum v4l2_mbus_type bus_type; -- /* -- * Stores bus.mipi_csi2.flags for CSI2 sensors, or -- * bus.mipi_csi1.strobe for CCP2. -- */ -- unsigned int bus_flags; -- unsigned int max_data_lanes; -- unsigned int active_data_lanes; -- bool sensor_embedded_data; -- -- struct unicam_node node[MAX_NODES]; --}; -- --/* Hardware access */ --#define clk_write(dev, val) writel((val) | 0x5a000000, (dev)->clk_gate_base) --#define clk_read(dev) readl((dev)->clk_gate_base) -- --#define reg_read(dev, offset) readl((dev)->base + (offset)) --#define reg_write(dev, offset, val) writel(val, (dev)->base + (offset)) -- --#define reg_read_field(dev, offset, mask) get_field(reg_read((dev), (offset), \ -- mask)) -- --static inline int get_field(u32 value, u32 mask) --{ -- return (value & mask) >> __ffs(mask); --} -- --static inline void set_field(u32 *valp, u32 field, u32 mask) --{ -- u32 val = *valp; -- -- val &= ~mask; -- val |= (field << __ffs(mask)) & mask; -- *valp = val; --} -- --static inline void reg_write_field(struct unicam_cfg *dev, u32 offset, -- u32 field, u32 mask) --{ -- u32 val = reg_read((dev), (offset)); -- -- set_field(&val, field, mask); -- reg_write((dev), (offset), val); --} -- --/* Power management functions */ --static inline int unicam_runtime_get(struct unicam_device *dev) --{ -- return pm_runtime_get_sync(&dev->pdev->dev); --} -- --static inline void unicam_runtime_put(struct unicam_device *dev) --{ -- pm_runtime_put_sync(&dev->pdev->dev); --} -- --/* Format setup functions */ --static const struct unicam_fmt *find_format_by_code(u32 code) --{ -- unsigned int i; -- -- for (i = 0; i < ARRAY_SIZE(formats); i++) { -- if (formats[i].code == code) -- return &formats[i]; -- } -- -- return NULL; --} -- --static int check_mbus_format(struct unicam_device *dev, -- const struct unicam_fmt *format) --{ -- struct v4l2_subdev_mbus_code_enum mbus_code; -- int ret = 0; -- int i; -- -- for (i = 0; !ret && i < MAX_ENUM_MBUS_CODE; i++) { -- memset(&mbus_code, 0, sizeof(mbus_code)); -- mbus_code.index = i; -- mbus_code.pad = IMAGE_PAD; -- mbus_code.which = V4L2_SUBDEV_FORMAT_ACTIVE; -- -- ret = v4l2_subdev_call(dev->sensor, pad, enum_mbus_code, -- NULL, &mbus_code); -- -- if (!ret && mbus_code.code == format->code) -- return 1; -- } -- -- return 0; --} -- --static const struct unicam_fmt *find_format_by_pix(struct unicam_device *dev, -- u32 pixelformat) --{ -- unsigned int i; -- -- for (i = 0; i < ARRAY_SIZE(formats); i++) { -- if (formats[i].fourcc == pixelformat || -- formats[i].repacked_fourcc == pixelformat) { -- if (formats[i].check_variants && -- !check_mbus_format(dev, &formats[i])) -- continue; -- return &formats[i]; -- } -- } -- -- return NULL; --} -- --static inline unsigned int bytes_per_line(u32 width, -- const struct unicam_fmt *fmt, -- u32 v4l2_fourcc) --{ -- if (v4l2_fourcc == fmt->repacked_fourcc) -- /* Repacking always goes to 16bpp */ -- return ALIGN(width << 1, BPL_ALIGNMENT); -- else -- return ALIGN((width * fmt->depth) >> 3, BPL_ALIGNMENT); --} -- --static int __subdev_get_format(struct unicam_device *dev, -- struct v4l2_mbus_framefmt *fmt, int pad_id) --{ -- struct v4l2_subdev_format sd_fmt = { -- .which = V4L2_SUBDEV_FORMAT_ACTIVE, -- .pad = pad_id -- }; -- int ret; -- -- ret = v4l2_subdev_call(dev->sensor, pad, get_fmt, dev->sensor_config, -- &sd_fmt); -- if (ret < 0) -- return ret; -- -- *fmt = sd_fmt.format; -- -- unicam_dbg(1, dev, "%s %dx%d code:%04x\n", __func__, -- fmt->width, fmt->height, fmt->code); -- -- return 0; --} -- --static int __subdev_set_format(struct unicam_device *dev, -- struct v4l2_mbus_framefmt *fmt, int pad_id) --{ -- struct v4l2_subdev_format sd_fmt = { -- .which = V4L2_SUBDEV_FORMAT_ACTIVE, -- .pad = pad_id -- }; -- int ret; -- -- sd_fmt.format = *fmt; -- -- ret = v4l2_subdev_call(dev->sensor, pad, set_fmt, dev->sensor_config, -- &sd_fmt); -- if (ret < 0) -- return ret; -- -- if (pad_id == IMAGE_PAD) -- unicam_dbg(1, dev, "%s %dx%d code:%04x\n", __func__, fmt->width, -- fmt->height, fmt->code); -- else -- unicam_dbg(1, dev, "%s Embedded data code:%04x\n", __func__, -- sd_fmt.format.code); -- -- return 0; --} -- --static int unicam_calc_format_size_bpl(struct unicam_device *dev, -- const struct unicam_fmt *fmt, -- struct v4l2_format *f) --{ -- unsigned int min_bytesperline; -- -- v4l_bound_align_image(&f->fmt.pix.width, MIN_WIDTH, MAX_WIDTH, 2, -- &f->fmt.pix.height, MIN_HEIGHT, MAX_HEIGHT, 0, -- 0); -- -- min_bytesperline = bytes_per_line(f->fmt.pix.width, fmt, -- f->fmt.pix.pixelformat); -- -- if (f->fmt.pix.bytesperline > min_bytesperline && -- f->fmt.pix.bytesperline <= MAX_BYTESPERLINE) -- f->fmt.pix.bytesperline = ALIGN(f->fmt.pix.bytesperline, -- BPL_ALIGNMENT); -- else -- f->fmt.pix.bytesperline = min_bytesperline; -- -- f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; -- -- unicam_dbg(3, dev, "%s: fourcc: %08X size: %dx%d bpl:%d img_size:%d\n", -- __func__, -- f->fmt.pix.pixelformat, -- f->fmt.pix.width, f->fmt.pix.height, -- f->fmt.pix.bytesperline, f->fmt.pix.sizeimage); -- -- return 0; --} -- --static int unicam_reset_format(struct unicam_node *node) --{ -- struct unicam_device *dev = node->dev; -- struct v4l2_mbus_framefmt mbus_fmt; -- int ret; -- -- if (dev->sensor_embedded_data || node->pad_id != METADATA_PAD) { -- ret = __subdev_get_format(dev, &mbus_fmt, node->pad_id); -- if (ret) { -- unicam_err(dev, "Failed to get_format - ret %d\n", ret); -- return ret; -- } -- -- if (mbus_fmt.code != node->fmt->code) { -- unicam_err(dev, "code mismatch - fmt->code %08x, mbus_fmt.code %08x\n", -- node->fmt->code, mbus_fmt.code); -- return ret; -- } -- } -- -- if (node->pad_id == IMAGE_PAD) { -- v4l2_fill_pix_format(&node->v_fmt.fmt.pix, &mbus_fmt); -- node->v_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; -- unicam_calc_format_size_bpl(dev, node->fmt, &node->v_fmt); -- } else { -- node->v_fmt.type = V4L2_BUF_TYPE_META_CAPTURE; -- node->v_fmt.fmt.meta.dataformat = V4L2_META_FMT_SENSOR_DATA; -- if (dev->sensor_embedded_data) { -- node->v_fmt.fmt.meta.buffersize = -- mbus_fmt.width * mbus_fmt.height; -- node->embedded_lines = mbus_fmt.height; -- } else { -- node->v_fmt.fmt.meta.buffersize = UNICAM_EMBEDDED_SIZE; -- node->embedded_lines = 1; -- } -- } -- -- node->m_fmt = mbus_fmt; -- return 0; --} -- --static void unicam_wr_dma_addr(struct unicam_cfg *cfg, dma_addr_t dmaaddr, -- unsigned int buffer_size, int pad_id) --{ -- dma_addr_t endaddr = dmaaddr + buffer_size; -- -- /* -- * dmaaddr and endaddr should be a 32-bit address with the top two bits -- * set to 0x3 to signify uncached access through the Videocore memory -- * controller. -- */ -- BUG_ON((dmaaddr >> 30) != 0x3 && (endaddr >> 30) != 0x3); -- -- if (pad_id == IMAGE_PAD) { -- reg_write(cfg, UNICAM_IBSA0, dmaaddr); -- reg_write(cfg, UNICAM_IBEA0, endaddr); -- } else { -- reg_write(cfg, UNICAM_DBSA0, dmaaddr); -- reg_write(cfg, UNICAM_DBEA0, endaddr); -- } --} -- --static inline unsigned int unicam_get_lines_done(struct unicam_device *dev) --{ -- dma_addr_t start_addr, cur_addr; -- unsigned int stride = dev->node[IMAGE_PAD].v_fmt.fmt.pix.bytesperline; -- struct unicam_buffer *frm = dev->node[IMAGE_PAD].cur_frm; -- -- if (!frm) -- return 0; -- -- start_addr = vb2_dma_contig_plane_dma_addr(&frm->vb.vb2_buf, 0); -- cur_addr = reg_read(&dev->cfg, UNICAM_IBWP); -- return (unsigned int)(cur_addr - start_addr) / stride; --} -- --static inline void unicam_schedule_next_buffer(struct unicam_node *node) --{ -- struct unicam_device *dev = node->dev; -- struct unicam_dmaqueue *dma_q = &node->dma_queue; -- struct unicam_buffer *buf; -- unsigned int size; -- dma_addr_t addr; -- -- buf = list_entry(dma_q->active.next, struct unicam_buffer, list); -- node->next_frm = buf; -- list_del(&buf->list); -- -- addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0); -- size = (node->pad_id == IMAGE_PAD) ? -- dev->node[IMAGE_PAD].v_fmt.fmt.pix.sizeimage : -- dev->node[METADATA_PAD].v_fmt.fmt.meta.buffersize; -- -- unicam_wr_dma_addr(&dev->cfg, addr, size, node->pad_id); --} -- --static inline void unicam_schedule_dummy_buffer(struct unicam_node *node) --{ -- struct unicam_device *dev = node->dev; -- dma_addr_t addr = node->dummy_buf_dma_addr; -- -- unicam_dbg(3, dev, "Scheduling dummy buffer for node %d\n", -- node->pad_id); -- -- unicam_wr_dma_addr(&dev->cfg, addr, DUMMY_BUF_SIZE, node->pad_id); -- node->next_frm = NULL; --} -- --static inline void unicam_process_buffer_complete(struct unicam_node *node, -- unsigned int sequence) --{ -- node->cur_frm->vb.field = node->m_fmt.field; -- node->cur_frm->vb.sequence = sequence; -- -- vb2_buffer_done(&node->cur_frm->vb.vb2_buf, VB2_BUF_STATE_DONE); --} -- --static int unicam_num_nodes_streaming(struct unicam_device *dev) --{ -- return dev->node[IMAGE_PAD].streaming + -- dev->node[METADATA_PAD].streaming; --} -- --static int unicam_all_nodes_streaming(struct unicam_device *dev) --{ -- int ret; -- -- ret = dev->node[IMAGE_PAD].open && dev->node[IMAGE_PAD].streaming; -- ret &= !dev->node[METADATA_PAD].open || -- dev->node[METADATA_PAD].streaming; -- return ret; --} -- --static void unicam_queue_event_sof(struct unicam_device *unicam) --{ -- struct v4l2_event event = { -- .type = V4L2_EVENT_FRAME_SYNC, -- .u.frame_sync.frame_sequence = unicam->sequence, -- }; -- -- v4l2_event_queue(&unicam->node[IMAGE_PAD].video_dev, &event); --} -- --/* -- * unicam_isr : ISR handler for unicam capture -- * @irq: irq number -- * @dev_id: dev_id ptr -- * -- * It changes status of the captured buffer, takes next buffer from the queue -- * and sets its address in unicam registers -- */ --static irqreturn_t unicam_isr(int irq, void *dev) --{ -- struct unicam_device *unicam = (struct unicam_device *)dev; -- struct unicam_cfg *cfg = &unicam->cfg; -- unsigned int lines_done = unicam_get_lines_done(dev); -- unsigned int sequence = unicam->sequence; -- int num_nodes_streaming = unicam_num_nodes_streaming(dev); -- int ista, sta; -- u64 ts; -- int i; -- -- sta = reg_read(cfg, UNICAM_STA); -- /* Write value back to clear the interrupts */ -- reg_write(cfg, UNICAM_STA, sta); -- -- ista = reg_read(cfg, UNICAM_ISTA); -- /* Write value back to clear the interrupts */ -- reg_write(cfg, UNICAM_ISTA, ista); -- -- unicam_dbg(3, unicam, "ISR: ISTA: 0x%X, STA: 0x%X, sequence %d, lines done %d", -- ista, sta, sequence, lines_done); -- -- if (!(sta && (UNICAM_IS | UNICAM_PI0))) -- return IRQ_HANDLED; -- -- /* -- * We must run the frame end handler first. If we have a valid next_frm -- * and we get a simultaneout FE + FS interrupt, running the FS handler -- * first would null out the next_frm ptr and we would have lost the -- * buffer forever. -- */ -- if (ista & UNICAM_FEI || sta & UNICAM_PI0) { -- /* -- * Ensure we have swapped buffers already as we can't -- * stop the peripheral. If no buffer is available, use a -- * dummy buffer to dump out frames until we get a new buffer -- * to use. -- */ -- for (i = 0; i < num_nodes_streaming; i++) { -- if (unicam->node[i].cur_frm) -- unicam_process_buffer_complete(&unicam->node[i], -- sequence); -- unicam->node[i].cur_frm = unicam->node[i].next_frm; -- } -- unicam->sequence++; -- } -- -- if (ista & UNICAM_FSI) { -- /* -- * Timestamp is to be when the first data byte was captured, -- * aka frame start. -- */ -- ts = ktime_get_ns(); -- for (i = 0; i < num_nodes_streaming; i++) { -- if (unicam->node[i].cur_frm) -- unicam->node[i].cur_frm->vb.vb2_buf.timestamp = -- ts; -- /* -- * Set the next frame output to go to a dummy frame -- * if we have not managed to obtain another frame -- * from the queue. -- */ -- unicam_schedule_dummy_buffer(&unicam->node[i]); -- } -- -- unicam_queue_event_sof(unicam); -- } -- /* -- * Cannot swap buffer at frame end, there may be a race condition -- * where the HW does not actually swap it if the new frame has -- * already started. -- */ -- if (ista & (UNICAM_FSI | UNICAM_LCI) && !(ista & UNICAM_FEI)) { -- for (i = 0; i < num_nodes_streaming; i++) { -- spin_lock(&unicam->node[i].dma_queue_lock); -- if (!list_empty(&unicam->node[i].dma_queue.active) && -- !unicam->node[i].next_frm) -- unicam_schedule_next_buffer(&unicam->node[i]); -- spin_unlock(&unicam->node[i].dma_queue_lock); -- } -- } -- -- if (reg_read(&unicam->cfg, UNICAM_ICTL) & UNICAM_FCM) { -- /* Switch out of trigger mode if selected */ -- reg_write_field(&unicam->cfg, UNICAM_ICTL, 1, UNICAM_TFC); -- reg_write_field(&unicam->cfg, UNICAM_ICTL, 0, UNICAM_FCM); -- } -- return IRQ_HANDLED; --} -- --static int unicam_querycap(struct file *file, void *priv, -- struct v4l2_capability *cap) --{ -- struct unicam_node *node = video_drvdata(file); -- struct unicam_device *dev = node->dev; -- -- strlcpy(cap->driver, UNICAM_MODULE_NAME, sizeof(cap->driver)); -- strlcpy(cap->card, UNICAM_MODULE_NAME, sizeof(cap->card)); -- -- snprintf(cap->bus_info, sizeof(cap->bus_info), -- "platform:%s", dev->v4l2_dev.name); -- -- cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | -- V4L2_CAP_READWRITE | V4L2_CAP_DEVICE_CAPS | -- V4L2_CAP_META_CAPTURE; -- -- if (node->pad_id == IMAGE_PAD) -- cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; -- else -- cap->device_caps = V4L2_CAP_META_CAPTURE | V4L2_CAP_STREAMING; -- -- return 0; --} -- --static int unicam_enum_fmt_vid_cap(struct file *file, void *priv, -- struct v4l2_fmtdesc *f) --{ -- struct unicam_node *node = video_drvdata(file); -- struct unicam_device *dev = node->dev; -- struct v4l2_subdev_mbus_code_enum mbus_code; -- const struct unicam_fmt *fmt = NULL; -- int index = 0; -- int ret = 0; -- int i; -- -- if (node->pad_id == METADATA_PAD) -- return -EINVAL; -- -- for (i = 0; !ret && i < MAX_ENUM_MBUS_CODE; i++) { -- memset(&mbus_code, 0, sizeof(mbus_code)); -- mbus_code.index = i; -- mbus_code.pad = IMAGE_PAD; -- mbus_code.which = V4L2_SUBDEV_FORMAT_ACTIVE; -- -- ret = v4l2_subdev_call(dev->sensor, pad, enum_mbus_code, -- NULL, &mbus_code); -- if (ret < 0) { -- unicam_dbg(2, dev, -- "subdev->enum_mbus_code idx %d returned %d - index invalid\n", -- i, ret); -- return -EINVAL; -- } -- -- fmt = find_format_by_code(mbus_code.code); -- if (fmt) { -- if (fmt->fourcc) { -- if (index == f->index) { -- f->pixelformat = fmt->fourcc; -- break; -- } -- index++; -- } -- if (fmt->repacked_fourcc) { -- if (index == f->index) { -- f->pixelformat = fmt->repacked_fourcc; -- break; -- } -- index++; -- } -- } -- } -- -- return 0; --} -- --static int unicam_g_fmt_vid_cap(struct file *file, void *priv, -- struct v4l2_format *f) --{ -- struct v4l2_mbus_framefmt mbus_fmt = {0}; -- struct unicam_node *node = video_drvdata(file); -- struct unicam_device *dev = node->dev; -- const struct unicam_fmt *fmt = NULL; -- int ret; -- -- if (node->pad_id != IMAGE_PAD) -- return -EINVAL; -- -- /* -- * If a flip has occurred in the sensor, the fmt code might have -- * changed. So we will need to re-fetch the format from the subdevice. -- */ -- ret = __subdev_get_format(dev, &mbus_fmt, node->pad_id); -- if (ret) -- return -EINVAL; -- -- /* Find the V4L2 format from mbus code. We must match a known format. */ -- fmt = find_format_by_code(mbus_fmt.code); -- if (!fmt) -- return -EINVAL; -- -- if (node->fmt != fmt) { -- /* -- * The sensor format has changed so the pixelformat needs to -- * be updated. Try and retain the packed/unpacked choice if -- * at all possible. -- */ -- if (node->fmt->repacked_fourcc == -- node->v_fmt.fmt.pix.pixelformat) -- /* Using the repacked format */ -- node->v_fmt.fmt.pix.pixelformat = fmt->repacked_fourcc; -- else -- /* Using the native format */ -- node->v_fmt.fmt.pix.pixelformat = fmt->fourcc; -- -- node->fmt = fmt; -- } -- -- *f = node->v_fmt; -- -- return 0; --} -- --static --const struct unicam_fmt *get_first_supported_format(struct unicam_device *dev) --{ -- struct v4l2_subdev_mbus_code_enum mbus_code; -- const struct unicam_fmt *fmt = NULL; -- int ret = 0; -- int j; -- -- for (j = 0; ret != -EINVAL && ret != -ENOIOCTLCMD; ++j) { -- memset(&mbus_code, 0, sizeof(mbus_code)); -- mbus_code.index = j; -- mbus_code.pad = IMAGE_PAD; -- mbus_code.which = V4L2_SUBDEV_FORMAT_ACTIVE; -- -- ret = v4l2_subdev_call(dev->sensor, pad, enum_mbus_code, NULL, -- &mbus_code); -- if (ret < 0) { -- unicam_dbg(2, dev, -- "subdev->enum_mbus_code idx %d returned %d - continue\n", -- j, ret); -- continue; -- } -- -- unicam_dbg(2, dev, "subdev %s: code: 0x%08x idx: %d\n", -- dev->sensor->name, mbus_code.code, j); -- -- fmt = find_format_by_code(mbus_code.code); -- unicam_dbg(2, dev, "fmt 0x%08x returned as %p, V4L2 FOURCC 0x%08x, csi_dt 0x%02x\n", -- mbus_code.code, fmt, fmt ? fmt->fourcc : 0, -- fmt ? fmt->csi_dt : 0); -- if (fmt) -- return fmt; -- } -- -- return NULL; --} -- --static int unicam_try_fmt_vid_cap(struct file *file, void *priv, -- struct v4l2_format *f) --{ -- struct unicam_node *node = video_drvdata(file); -- struct unicam_device *dev = node->dev; -- struct v4l2_subdev_format sd_fmt = { -- .which = V4L2_SUBDEV_FORMAT_TRY, -- .pad = IMAGE_PAD -- }; -- struct v4l2_mbus_framefmt *mbus_fmt = &sd_fmt.format; -- const struct unicam_fmt *fmt; -- int ret; -- -- if (node->pad_id == METADATA_PAD) -- return -EINVAL; -- -- fmt = find_format_by_pix(dev, f->fmt.pix.pixelformat); -- if (!fmt) { -- /* Pixel format not supported by unicam. Choose the first -- * supported format, and let the sensor choose something else. -- */ -- unicam_dbg(3, dev, "Fourcc format (0x%08x) not found. Use first format.\n", -- f->fmt.pix.pixelformat); -- -- fmt = &formats[0]; -- f->fmt.pix.pixelformat = fmt->fourcc; -- } -- -- v4l2_fill_mbus_format(mbus_fmt, &f->fmt.pix, fmt->code); -- /* -- * No support for receiving interlaced video, so never -- * request it from the sensor subdev. -- */ -- mbus_fmt->field = V4L2_FIELD_NONE; -- -- ret = v4l2_subdev_call(dev->sensor, pad, set_fmt, dev->sensor_config, -- &sd_fmt); -- if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) -- return ret; -- -- if (mbus_fmt->field != V4L2_FIELD_NONE) -- unicam_info(dev, "Sensor trying to send interlaced video - results may be unpredictable\n"); -- -- v4l2_fill_pix_format(&f->fmt.pix, &sd_fmt.format); -- if (mbus_fmt->code != fmt->code) { -- /* Sensor has returned an alternate format */ -- fmt = find_format_by_code(mbus_fmt->code); -- if (!fmt) { -- /* The alternate format is one unicam can't support. -- * Find the first format that is supported by both, and -- * then set that. -- */ -- fmt = get_first_supported_format(dev); -- mbus_fmt->code = fmt->code; -- -- ret = v4l2_subdev_call(dev->sensor, pad, set_fmt, -- dev->sensor_config, &sd_fmt); -- if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) -- return ret; -- -- if (mbus_fmt->field != V4L2_FIELD_NONE) -- unicam_info(dev, "Sensor trying to send interlaced video - results may be unpredictable\n"); -- -- v4l2_fill_pix_format(&f->fmt.pix, &sd_fmt.format); -- -- if (mbus_fmt->code != fmt->code) { -- /* We've set a format that the sensor reports -- * as being supported, but it refuses to set it. -- * Not much else we can do. -- * Assume that the sensor driver may accept the -- * format when it is set (rather than tried). -- */ -- unicam_err(dev, "Sensor won't accept default format, and Unicam can't support sensor default\n"); -- } -- } -- -- if (fmt->fourcc) -- f->fmt.pix.pixelformat = fmt->fourcc; -- else -- f->fmt.pix.pixelformat = fmt->repacked_fourcc; -- } -- -- return unicam_calc_format_size_bpl(dev, fmt, f); --} -- --static int unicam_s_fmt_vid_cap(struct file *file, void *priv, -- struct v4l2_format *f) --{ -- struct unicam_node *node = video_drvdata(file); -- struct unicam_device *dev = node->dev; -- struct vb2_queue *q = &node->buffer_queue; -- struct v4l2_mbus_framefmt mbus_fmt = {0}; -- const struct unicam_fmt *fmt; -- int ret; -- -- if (vb2_is_busy(q)) -- return -EBUSY; -- -- ret = unicam_try_fmt_vid_cap(file, priv, f); -- if (ret < 0) -- return ret; -- -- fmt = find_format_by_pix(dev, f->fmt.pix.pixelformat); -- if (!fmt) { -- /* Unknown pixel format - adopt a default. -- * This shouldn't happen as try_fmt should have resolved any -- * issues first. -- */ -- fmt = get_first_supported_format(dev); -- if (!fmt) -- /* It shouldn't be possible to get here with no -- * supported formats -- */ -- return -EINVAL; -- f->fmt.pix.pixelformat = fmt->fourcc; -- return -EINVAL; -- } -- -- v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, fmt->code); -- -- ret = __subdev_set_format(dev, &mbus_fmt, node->pad_id); -- if (ret) { -- unicam_dbg(3, dev, "%s __subdev_set_format failed %d\n", -- __func__, ret); -- return ret; -- } -- -- /* Just double check nothing has gone wrong */ -- if (mbus_fmt.code != fmt->code) { -- unicam_dbg(3, dev, -- "%s subdev changed format on us, this should not happen\n", -- __func__); -- return -EINVAL; -- } -- -- node->fmt = fmt; -- node->v_fmt.fmt.pix.pixelformat = f->fmt.pix.pixelformat; -- node->v_fmt.fmt.pix.bytesperline = f->fmt.pix.bytesperline; -- unicam_reset_format(node); -- -- unicam_dbg(3, dev, -- "%s %dx%d, mbus_fmt 0x%08X, V4L2 pix 0x%08X.\n", -- __func__, node->v_fmt.fmt.pix.width, -- node->v_fmt.fmt.pix.height, mbus_fmt.code, -- node->v_fmt.fmt.pix.pixelformat); -- -- *f = node->v_fmt; -- -- return 0; --} -- --static int unicam_enum_fmt_meta_cap(struct file *file, void *priv, -- struct v4l2_fmtdesc *f) --{ -- struct unicam_node *node = video_drvdata(file); -- struct unicam_device *dev = node->dev; -- struct v4l2_subdev_mbus_code_enum mbus_code; -- const struct unicam_fmt *fmt = NULL; -- int ret = 0; -- -- if (node->pad_id != METADATA_PAD || f->index != 0) -- return -EINVAL; -- -- if (dev->sensor_embedded_data) { -- memset(&mbus_code, 0, sizeof(mbus_code)); -- mbus_code.index = f->index; -- mbus_code.which = V4L2_SUBDEV_FORMAT_ACTIVE; -- mbus_code.pad = METADATA_PAD; -- -- ret = v4l2_subdev_call(dev->sensor, pad, enum_mbus_code, NULL, -- &mbus_code); -- if (ret < 0) { -- unicam_dbg(2, dev, -- "subdev->enum_mbus_code idx 0 returned %d - index invalid\n", -- ret); -- return -EINVAL; -- } -- } else { -- mbus_code.code = MEDIA_BUS_FMT_SENSOR_DATA; -- } -- -- fmt = find_format_by_code(mbus_code.code); -- if (fmt) -- f->pixelformat = fmt->fourcc; -- -- return 0; --} -- --static int unicam_g_fmt_meta_cap(struct file *file, void *priv, -- struct v4l2_format *f) --{ -- struct unicam_node *node = video_drvdata(file); -- -- if (node->pad_id != METADATA_PAD) -- return -EINVAL; -- -- *f = node->v_fmt; -- -- return 0; --} -- --static int unicam_try_fmt_meta_cap(struct file *file, void *priv, -- struct v4l2_format *f) --{ -- struct unicam_node *node = video_drvdata(file); -- -- if (node->pad_id != METADATA_PAD) -- return -EINVAL; -- -- *f = node->v_fmt; -- -- return 0; --} -- --static int unicam_s_fmt_meta_cap(struct file *file, void *priv, -- struct v4l2_format *f) --{ -- struct unicam_node *node = video_drvdata(file); -- struct unicam_device *dev = node->dev; -- struct v4l2_mbus_framefmt mbus_fmt = { 0 }; -- const struct unicam_fmt *fmt; -- int ret; -- -- if (node->pad_id == IMAGE_PAD) -- return -EINVAL; -- -- if (dev->sensor_embedded_data) { -- fmt = find_format_by_pix(dev, f->fmt.meta.dataformat); -- if (!fmt) { -- unicam_err(dev, "unknown format: V4L2 pix 0x%08x\n", -- f->fmt.meta.dataformat); -- return -EINVAL; -- } -- mbus_fmt.code = fmt->code; -- ret = __subdev_set_format(dev, &mbus_fmt, node->pad_id); -- if (ret) { -- unicam_dbg(3, dev, "%s __subdev_set_format failed %d\n", -- __func__, ret); -- return ret; -- } -- } -- -- *f = node->v_fmt; -- -- unicam_dbg(3, dev, "%s size %d, V4L2 pix 0x%08x\n", -- __func__, node->v_fmt.fmt.meta.buffersize, -- node->v_fmt.fmt.meta.dataformat); -- -- return 0; --} -- --static int unicam_queue_setup(struct vb2_queue *vq, -- unsigned int *nbuffers, -- unsigned int *nplanes, -- unsigned int sizes[], -- struct device *alloc_devs[]) --{ -- struct unicam_node *node = vb2_get_drv_priv(vq); -- struct unicam_device *dev = node->dev; -- unsigned int size = node->pad_id == IMAGE_PAD ? -- node->v_fmt.fmt.pix.sizeimage : -- node->v_fmt.fmt.meta.buffersize; -- -- if (vq->num_buffers + *nbuffers < 3) -- *nbuffers = 3 - vq->num_buffers; -- -- if (*nplanes) { -- if (sizes[0] < size) { -- unicam_err(dev, "sizes[0] %i < size %u\n", sizes[0], -- size); -- return -EINVAL; -- } -- size = sizes[0]; -- } -- -- *nplanes = 1; -- sizes[0] = size; -- -- return 0; --} -- --static int unicam_buffer_prepare(struct vb2_buffer *vb) --{ -- struct unicam_node *node = vb2_get_drv_priv(vb->vb2_queue); -- struct unicam_device *dev = node->dev; -- struct unicam_buffer *buf = container_of(vb, struct unicam_buffer, -- vb.vb2_buf); -- unsigned long size; -- -- if (WARN_ON(!node->fmt)) -- return -EINVAL; -- -- size = node->pad_id == IMAGE_PAD ? node->v_fmt.fmt.pix.sizeimage : -- node->v_fmt.fmt.meta.buffersize; -- if (vb2_plane_size(vb, 0) < size) { -- unicam_err(dev, "data will not fit into plane (%lu < %lu)\n", -- vb2_plane_size(vb, 0), size); -- return -EINVAL; -- } -- -- vb2_set_plane_payload(&buf->vb.vb2_buf, 0, size); -- return 0; --} -- --static void unicam_buffer_queue(struct vb2_buffer *vb) --{ -- struct unicam_node *node = vb2_get_drv_priv(vb->vb2_queue); -- struct unicam_buffer *buf = container_of(vb, struct unicam_buffer, -- vb.vb2_buf); -- struct unicam_dmaqueue *dma_queue = &node->dma_queue; -- unsigned long flags = 0; -- -- spin_lock_irqsave(&node->dma_queue_lock, flags); -- list_add_tail(&buf->list, &dma_queue->active); -- spin_unlock_irqrestore(&node->dma_queue_lock, flags); --} -- --static void unicam_set_packing_config(struct unicam_device *dev) --{ -- int pack, unpack; -- u32 val; -- -- if (dev->node[IMAGE_PAD].v_fmt.fmt.pix.pixelformat == -- dev->node[IMAGE_PAD].fmt->fourcc) { -- unpack = UNICAM_PUM_NONE; -- pack = UNICAM_PPM_NONE; -- } else { -- switch (dev->node[IMAGE_PAD].fmt->depth) { -- case 8: -- unpack = UNICAM_PUM_UNPACK8; -- break; -- case 10: -- unpack = UNICAM_PUM_UNPACK10; -- break; -- case 12: -- unpack = UNICAM_PUM_UNPACK12; -- break; -- case 14: -- unpack = UNICAM_PUM_UNPACK14; -- break; -- case 16: -- unpack = UNICAM_PUM_UNPACK16; -- break; -- default: -- unpack = UNICAM_PUM_NONE; -- break; -- } -- -- /* Repacking is always to 16bpp */ -- pack = UNICAM_PPM_PACK16; -- } -- -- val = 0; -- set_field(&val, unpack, UNICAM_PUM_MASK); -- set_field(&val, pack, UNICAM_PPM_MASK); -- reg_write(&dev->cfg, UNICAM_IPIPE, val); --} -- --static void unicam_cfg_image_id(struct unicam_device *dev) --{ -- struct unicam_cfg *cfg = &dev->cfg; -- -- if (dev->bus_type == V4L2_MBUS_CSI2_DPHY) { -- /* CSI2 mode */ -- reg_write(cfg, UNICAM_IDI0, -- (dev->virtual_channel << 6) | -- dev->node[IMAGE_PAD].fmt->csi_dt); -- } else { -- /* CCP2 mode */ -- reg_write(cfg, UNICAM_IDI0, -- 0x80 | dev->node[IMAGE_PAD].fmt->csi_dt); -- } --} -- --static void unicam_enable_ed(struct unicam_device *dev) --{ -- struct unicam_cfg *cfg = &dev->cfg; -- u32 val = reg_read(cfg, UNICAM_DCS); -- -- set_field(&val, 2, UNICAM_EDL_MASK); -- /* Do not wrap at the end of the embedded data buffer */ -- set_field(&val, 0, UNICAM_DBOB); -- -- reg_write(cfg, UNICAM_DCS, val); --} -- --static void unicam_start_rx(struct unicam_device *dev, dma_addr_t *addr) --{ -- struct unicam_cfg *cfg = &dev->cfg; -- int line_int_freq = dev->node[IMAGE_PAD].v_fmt.fmt.pix.height >> 2; -- unsigned int size, i; -- u32 val; -- -- if (line_int_freq < 128) -- line_int_freq = 128; -- -- /* Enable lane clocks */ -- val = 1; -- for (i = 0; i < dev->active_data_lanes; i++) -- val = val << 2 | 1; -- clk_write(cfg, val); -- -- /* Basic init */ -- reg_write(cfg, UNICAM_CTRL, UNICAM_MEM); -- -- /* Enable analogue control, and leave in reset. */ -- val = UNICAM_AR; -- set_field(&val, 7, UNICAM_CTATADJ_MASK); -- set_field(&val, 7, UNICAM_PTATADJ_MASK); -- reg_write(cfg, UNICAM_ANA, val); -- usleep_range(1000, 2000); -- -- /* Come out of reset */ -- reg_write_field(cfg, UNICAM_ANA, 0, UNICAM_AR); -- -- /* Peripheral reset */ -- reg_write_field(cfg, UNICAM_CTRL, 1, UNICAM_CPR); -- reg_write_field(cfg, UNICAM_CTRL, 0, UNICAM_CPR); -- -- reg_write_field(cfg, UNICAM_CTRL, 0, UNICAM_CPE); -- -- /* Enable Rx control. */ -- val = reg_read(cfg, UNICAM_CTRL); -- if (dev->bus_type == V4L2_MBUS_CSI2_DPHY) { -- set_field(&val, UNICAM_CPM_CSI2, UNICAM_CPM_MASK); -- set_field(&val, UNICAM_DCM_STROBE, UNICAM_DCM_MASK); -- } else { -- set_field(&val, UNICAM_CPM_CCP2, UNICAM_CPM_MASK); -- set_field(&val, dev->bus_flags, UNICAM_DCM_MASK); -- } -- /* Packet framer timeout */ -- set_field(&val, 0xf, UNICAM_PFT_MASK); -- set_field(&val, 128, UNICAM_OET_MASK); -- reg_write(cfg, UNICAM_CTRL, val); -- -- reg_write(cfg, UNICAM_IHWIN, 0); -- reg_write(cfg, UNICAM_IVWIN, 0); -- -- /* AXI bus access QoS setup */ -- val = reg_read(&dev->cfg, UNICAM_PRI); -- set_field(&val, 0, UNICAM_BL_MASK); -- set_field(&val, 0, UNICAM_BS_MASK); -- set_field(&val, 0xe, UNICAM_PP_MASK); -- set_field(&val, 8, UNICAM_NP_MASK); -- set_field(&val, 2, UNICAM_PT_MASK); -- set_field(&val, 1, UNICAM_PE); -- reg_write(cfg, UNICAM_PRI, val); -- -- reg_write_field(cfg, UNICAM_ANA, 0, UNICAM_DDL); -- -- /* Always start in trigger frame capture mode (UNICAM_FCM set) */ -- val = UNICAM_FSIE | UNICAM_FEIE | UNICAM_FCM | UNICAM_IBOB; -- set_field(&val, line_int_freq, UNICAM_LCIE_MASK); -- reg_write(cfg, UNICAM_ICTL, val); -- reg_write(cfg, UNICAM_STA, UNICAM_STA_MASK_ALL); -- reg_write(cfg, UNICAM_ISTA, UNICAM_ISTA_MASK_ALL); -- -- /* tclk_term_en */ -- reg_write_field(cfg, UNICAM_CLT, 2, UNICAM_CLT1_MASK); -- /* tclk_settle */ -- reg_write_field(cfg, UNICAM_CLT, 6, UNICAM_CLT2_MASK); -- /* td_term_en */ -- reg_write_field(cfg, UNICAM_DLT, 2, UNICAM_DLT1_MASK); -- /* ths_settle */ -- reg_write_field(cfg, UNICAM_DLT, 6, UNICAM_DLT2_MASK); -- /* trx_enable */ -- reg_write_field(cfg, UNICAM_DLT, 0, UNICAM_DLT3_MASK); -- -- reg_write_field(cfg, UNICAM_CTRL, 0, UNICAM_SOE); -- -- /* Packet compare setup - required to avoid missing frame ends */ -- val = 0; -- set_field(&val, 1, UNICAM_PCE); -- set_field(&val, 1, UNICAM_GI); -- set_field(&val, 1, UNICAM_CPH); -- set_field(&val, 0, UNICAM_PCVC_MASK); -- set_field(&val, 1, UNICAM_PCDT_MASK); -- reg_write(cfg, UNICAM_CMP0, val); -- -- /* Enable clock lane and set up terminations */ -- val = 0; -- if (dev->bus_type == V4L2_MBUS_CSI2_DPHY) { -- /* CSI2 */ -- set_field(&val, 1, UNICAM_CLE); -- set_field(&val, 1, UNICAM_CLLPE); -- if (dev->bus_flags & V4L2_MBUS_CSI2_CONTINUOUS_CLOCK) { -- set_field(&val, 1, UNICAM_CLTRE); -- set_field(&val, 1, UNICAM_CLHSE); -- } -- } else { -- /* CCP2 */ -- set_field(&val, 1, UNICAM_CLE); -- set_field(&val, 1, UNICAM_CLHSE); -- set_field(&val, 1, UNICAM_CLTRE); -- } -- reg_write(cfg, UNICAM_CLK, val); -- -- /* -- * Enable required data lanes with appropriate terminations. -- * The same value needs to be written to UNICAM_DATn registers for -- * the active lanes, and 0 for inactive ones. -- */ -- val = 0; -- if (dev->bus_type == V4L2_MBUS_CSI2_DPHY) { -- /* CSI2 */ -- set_field(&val, 1, UNICAM_DLE); -- set_field(&val, 1, UNICAM_DLLPE); -- if (dev->bus_flags & V4L2_MBUS_CSI2_CONTINUOUS_CLOCK) { -- set_field(&val, 1, UNICAM_DLTRE); -- set_field(&val, 1, UNICAM_DLHSE); -- } -- } else { -- /* CCP2 */ -- set_field(&val, 1, UNICAM_DLE); -- set_field(&val, 1, UNICAM_DLHSE); -- set_field(&val, 1, UNICAM_DLTRE); -- } -- reg_write(cfg, UNICAM_DAT0, val); -- -- if (dev->active_data_lanes == 1) -- val = 0; -- reg_write(cfg, UNICAM_DAT1, val); -- -- if (dev->max_data_lanes > 2) { -- /* -- * Registers UNICAM_DAT2 and UNICAM_DAT3 only valid if the -- * instance supports more than 2 data lanes. -- */ -- if (dev->active_data_lanes == 2) -- val = 0; -- reg_write(cfg, UNICAM_DAT2, val); -- -- if (dev->active_data_lanes == 3) -- val = 0; -- reg_write(cfg, UNICAM_DAT3, val); -- } -- -- reg_write(&dev->cfg, UNICAM_IBLS, -- dev->node[IMAGE_PAD].v_fmt.fmt.pix.bytesperline); -- size = dev->node[IMAGE_PAD].v_fmt.fmt.pix.sizeimage; -- unicam_wr_dma_addr(&dev->cfg, addr[IMAGE_PAD], size, IMAGE_PAD); -- unicam_set_packing_config(dev); -- unicam_cfg_image_id(dev); -- -- val = reg_read(cfg, UNICAM_MISC); -- set_field(&val, 1, UNICAM_FL0); -- set_field(&val, 1, UNICAM_FL1); -- reg_write(cfg, UNICAM_MISC, val); -- -- if (dev->node[METADATA_PAD].streaming && dev->sensor_embedded_data) { -- size = dev->node[METADATA_PAD].v_fmt.fmt.meta.buffersize; -- unicam_enable_ed(dev); -- unicam_wr_dma_addr(&dev->cfg, addr[METADATA_PAD], size, -- METADATA_PAD); -- } -- -- /* Enable peripheral */ -- reg_write_field(cfg, UNICAM_CTRL, 1, UNICAM_CPE); -- -- /* Load image pointers */ -- reg_write_field(cfg, UNICAM_ICTL, 1, UNICAM_LIP_MASK); -- -- /* Load embedded data buffer pointers if needed */ -- if (dev->node[METADATA_PAD].streaming && dev->sensor_embedded_data) -- reg_write_field(cfg, UNICAM_DCS, 1, UNICAM_LDP); -- -- /* -- * Enable trigger only for the first frame to -- * sync correctly to the FS from the source. -- */ -- reg_write_field(cfg, UNICAM_ICTL, 1, UNICAM_TFC); --} -- --static void unicam_disable(struct unicam_device *dev) --{ -- struct unicam_cfg *cfg = &dev->cfg; -- -- /* Analogue lane control disable */ -- reg_write_field(cfg, UNICAM_ANA, 1, UNICAM_DDL); -- -- /* Stop the output engine */ -- reg_write_field(cfg, UNICAM_CTRL, 1, UNICAM_SOE); -- -- /* Disable the data lanes. */ -- reg_write(cfg, UNICAM_DAT0, 0); -- reg_write(cfg, UNICAM_DAT1, 0); -- -- if (dev->max_data_lanes > 2) { -- reg_write(cfg, UNICAM_DAT2, 0); -- reg_write(cfg, UNICAM_DAT3, 0); -- } -- -- /* Peripheral reset */ -- reg_write_field(cfg, UNICAM_CTRL, 1, UNICAM_CPR); -- usleep_range(50, 100); -- reg_write_field(cfg, UNICAM_CTRL, 0, UNICAM_CPR); -- -- /* Disable peripheral */ -- reg_write_field(cfg, UNICAM_CTRL, 0, UNICAM_CPE); -- -- /* Clear ED setup */ -- reg_write(cfg, UNICAM_DCS, 0); -- -- /* Disable all lane clocks */ -- clk_write(cfg, 0); --} -- --static int unicam_start_streaming(struct vb2_queue *vq, unsigned int count) --{ -- struct unicam_node *node = vb2_get_drv_priv(vq); -- struct unicam_device *dev = node->dev; -- struct unicam_buffer *buf; -- dma_addr_t buffer_addr[MAX_NODES] = { 0 }; -- int num_nodes_streaming; -- unsigned long flags; -- int ret, i; -- -- node->streaming = 1; -- if (!unicam_all_nodes_streaming(dev)) { -- unicam_dbg(3, dev, "Not all nodes are streaming yet."); -- return 0; -- } -- -- dev->sequence = 0; -- ret = unicam_runtime_get(dev); -- if (ret < 0) { -- unicam_dbg(3, dev, "unicam_runtime_get failed\n"); -- return ret; -- } -- -- dev->active_data_lanes = dev->max_data_lanes; -- if (dev->bus_type == V4L2_MBUS_CSI2_DPHY && -- v4l2_subdev_has_op(dev->sensor, video, g_mbus_config)) { -- struct v4l2_mbus_config mbus_config; -- -- ret = v4l2_subdev_call(dev->sensor, video, g_mbus_config, -- &mbus_config); -- if (ret < 0) { -- unicam_dbg(3, dev, "g_mbus_config failed\n"); -- goto err_pm_put; -- } -- -- dev->active_data_lanes = -- (mbus_config.flags & V4L2_MBUS_CSI2_LANE_MASK) >> -- __ffs(V4L2_MBUS_CSI2_LANE_MASK); -- if (!dev->active_data_lanes) -- dev->active_data_lanes = dev->max_data_lanes; -- } -- if (dev->active_data_lanes > dev->max_data_lanes) { -- unicam_err(dev, "Device has requested %u data lanes, which is >%u configured in DT\n", -- dev->active_data_lanes, dev->max_data_lanes); -- ret = -EINVAL; -- goto err_pm_put; -- } -- -- unicam_dbg(1, dev, "Running with %u data lanes\n", -- dev->active_data_lanes); -- -- ret = clk_set_rate(dev->clock, 100 * 1000 * 1000); -- if (ret) { -- unicam_err(dev, "failed to set up clock\n"); -- goto err_pm_put; -- } -- -- ret = clk_prepare_enable(dev->clock); -- if (ret) { -- unicam_err(dev, "Failed to enable CSI clock: %d\n", ret); -- goto err_pm_put; -- } -- -- num_nodes_streaming = unicam_num_nodes_streaming(dev); -- for (i = 0; i < num_nodes_streaming; i++) { -- spin_lock_irqsave(&dev->node[i].dma_queue_lock, flags); -- buf = list_entry(dev->node[i].dma_queue.active.next, -- struct unicam_buffer, list); -- dev->node[i].cur_frm = buf; -- dev->node[i].next_frm = buf; -- list_del(&buf->list); -- spin_unlock_irqrestore(&dev->node[i].dma_queue_lock, flags); -- buffer_addr[i] = -- vb2_dma_contig_plane_dma_addr(&dev->node[i].cur_frm->vb.vb2_buf, -- 0); -- } -- -- unicam_start_rx(dev, buffer_addr); -- -- ret = v4l2_subdev_call(dev->sensor, video, s_stream, 1); -- if (ret < 0) { -- unicam_err(dev, "stream on failed in subdev\n"); -- goto err_disable_unicam; -- } -- -- return 0; -- --err_disable_unicam: -- node->streaming = 0; -- unicam_disable(dev); -- clk_disable_unprepare(dev->clock); --err_pm_put: -- unicam_runtime_put(dev); -- -- return ret; --} -- --static void unicam_stop_streaming(struct vb2_queue *vq) --{ -- struct unicam_node *node = vb2_get_drv_priv(vq); -- struct unicam_device *dev = node->dev; -- struct unicam_dmaqueue *dma_q = &node->dma_queue; -- struct unicam_buffer *buf, *tmp; -- unsigned long flags; -- -- node->streaming = 0; -- -- if (node->pad_id == IMAGE_PAD) { -- /* Stop streaming the sensor and disable the peripheral. -- * We cannot continue streaming embedded data with the -- * image pad disabled. -- */ -- if (v4l2_subdev_call(dev->sensor, video, s_stream, 0) < 0) -- unicam_err(dev, "stream off failed in subdev\n"); -- -- unicam_disable(dev); -- clk_disable_unprepare(dev->clock); -- unicam_runtime_put(dev); -- -- } else if (node->pad_id == METADATA_PAD) { -- /* Allow the hardware to spin in the dummy buffer. -- * This is only really needed if the embedded data pad is -- * disabled before the image pad. The 0x3 in the top two bits -- * signifies uncached accesses through the Videocore memory -- * controller. -- */ -- unicam_wr_dma_addr(&dev->cfg, node->dummy_buf_dma_addr, -- DUMMY_BUF_SIZE, METADATA_PAD); -- } -- -- /* Clear all queued buffers for the node */ -- spin_lock_irqsave(&node->dma_queue_lock, flags); -- list_for_each_entry_safe(buf, tmp, &dma_q->active, list) { -- list_del(&buf->list); -- vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); -- } -- -- if (node->cur_frm) -- vb2_buffer_done(&node->cur_frm->vb.vb2_buf, -- VB2_BUF_STATE_ERROR); -- if (node->next_frm && node->cur_frm != node->next_frm) -- vb2_buffer_done(&node->next_frm->vb.vb2_buf, -- VB2_BUF_STATE_ERROR); -- -- node->cur_frm = NULL; -- node->next_frm = NULL; -- spin_unlock_irqrestore(&node->dma_queue_lock, flags); --} -- --static int unicam_enum_input(struct file *file, void *priv, -- struct v4l2_input *inp) --{ -- struct unicam_node *node = video_drvdata(file); -- struct unicam_device *dev = node->dev; -- -- if (inp->index != 0) -- return -EINVAL; -- -- inp->type = V4L2_INPUT_TYPE_CAMERA; -- if (v4l2_subdev_has_op(dev->sensor, video, s_dv_timings)) { -- inp->capabilities = V4L2_IN_CAP_DV_TIMINGS; -- inp->std = 0; -- } else if (v4l2_subdev_has_op(dev->sensor, video, s_std)) { -- inp->capabilities = V4L2_IN_CAP_STD; -- if (v4l2_subdev_call(dev->sensor, video, g_tvnorms, &inp->std) -- < 0) -- inp->std = V4L2_STD_ALL; -- } else { -- inp->capabilities = 0; -- inp->std = 0; -- } -- sprintf(inp->name, "Camera 0"); -- return 0; --} -- --static int unicam_g_input(struct file *file, void *priv, unsigned int *i) --{ -- *i = 0; -- -- return 0; --} -- --static int unicam_s_input(struct file *file, void *priv, unsigned int i) --{ -- /* -- * FIXME: Ideally we would like to be able to query the source -- * subdevice for information over the input connectors it supports, -- * and map that through in to a call to video_ops->s_routing. -- * There is no infrastructure support for defining that within -- * devicetree at present. Until that is implemented we can't -- * map a user physical connector number to s_routing input number. -- */ -- if (i > 0) -- return -EINVAL; -- -- return 0; --} -- --static int unicam_querystd(struct file *file, void *priv, -- v4l2_std_id *std) --{ -- struct unicam_node *node = video_drvdata(file); -- struct unicam_device *dev = node->dev; -- -- return v4l2_subdev_call(dev->sensor, video, querystd, std); --} -- --static int unicam_g_std(struct file *file, void *priv, v4l2_std_id *std) --{ -- struct unicam_node *node = video_drvdata(file); -- struct unicam_device *dev = node->dev; -- -- return v4l2_subdev_call(dev->sensor, video, g_std, std); --} -- --static int unicam_s_std(struct file *file, void *priv, v4l2_std_id std) --{ -- struct unicam_node *node = video_drvdata(file); -- struct unicam_device *dev = node->dev; -- int ret; -- v4l2_std_id current_std; -- -- ret = v4l2_subdev_call(dev->sensor, video, g_std, ¤t_std); -- if (ret) -- return ret; -- -- if (std == current_std) -- return 0; -- -- if (vb2_is_busy(&node->buffer_queue)) -- return -EBUSY; -- -- ret = v4l2_subdev_call(dev->sensor, video, s_std, std); -- -- /* Force recomputation of bytesperline */ -- node->v_fmt.fmt.pix.bytesperline = 0; -- -- unicam_reset_format(node); -- -- return ret; --} -- --static int unicam_s_edid(struct file *file, void *priv, struct v4l2_edid *edid) --{ -- struct unicam_node *node = video_drvdata(file); -- struct unicam_device *dev = node->dev; -- -- return v4l2_subdev_call(dev->sensor, pad, set_edid, edid); --} -- --static int unicam_g_edid(struct file *file, void *priv, struct v4l2_edid *edid) --{ -- struct unicam_node *node = video_drvdata(file); -- struct unicam_device *dev = node->dev; -- -- return v4l2_subdev_call(dev->sensor, pad, get_edid, edid); --} -- --static int unicam_s_selection(struct file *file, void *priv, -- struct v4l2_selection *sel) --{ -- struct unicam_node *node = video_drvdata(file); -- struct unicam_device *dev = node->dev; -- struct v4l2_subdev_selection sdsel = { -- .which = V4L2_SUBDEV_FORMAT_ACTIVE, -- .target = sel->target, -- .flags = sel->flags, -- .r = sel->r, -- }; -- -- return v4l2_subdev_call(dev->sensor, pad, set_selection, NULL, &sdsel); --} -- --static int unicam_g_selection(struct file *file, void *priv, -- struct v4l2_selection *sel) --{ -- struct unicam_node *node = video_drvdata(file); -- struct unicam_device *dev = node->dev; -- struct v4l2_subdev_selection sdsel = { -- .which = V4L2_SUBDEV_FORMAT_ACTIVE, -- .target = sel->target, -- }; -- int ret; -- -- ret = v4l2_subdev_call(dev->sensor, pad, get_selection, NULL, &sdsel); -- if (!ret) -- sel->r = sdsel.r; -- -- return ret; --} -- --static int unicam_enum_framesizes(struct file *file, void *priv, -- struct v4l2_frmsizeenum *fsize) --{ -- struct unicam_node *node = video_drvdata(file); -- struct unicam_device *dev = node->dev; -- const struct unicam_fmt *fmt; -- struct v4l2_subdev_frame_size_enum fse; -- int ret; -- -- if (node->pad_id == IMAGE_PAD) { -- /* check for valid format */ -- fmt = find_format_by_pix(dev, fsize->pixel_format); -- if (!fmt) { -- unicam_dbg(3, dev, "Invalid pixel code: %x\n", -- fsize->pixel_format); -- return -EINVAL; -- } -- fse.code = fmt->code; -- } else { -- /* This pad is for embedded data, so just set the format */ -- fse.code = MEDIA_BUS_FMT_SENSOR_DATA; -- } -- -- fse.which = V4L2_SUBDEV_FORMAT_ACTIVE; -- fse.index = fsize->index; -- fse.pad = node->pad_id; -- -- ret = v4l2_subdev_call(dev->sensor, pad, enum_frame_size, NULL, &fse); -- if (ret) -- return ret; -- -- unicam_dbg(1, dev, "%s: index: %d code: %x W:[%d,%d] H:[%d,%d]\n", -- __func__, fse.index, fse.code, fse.min_width, fse.max_width, -- fse.min_height, fse.max_height); -- -- fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; -- fsize->discrete.width = fse.max_width; -- fsize->discrete.height = fse.max_height; -- -- return 0; --} -- --static int unicam_enum_frameintervals(struct file *file, void *priv, -- struct v4l2_frmivalenum *fival) --{ -- struct unicam_node *node = video_drvdata(file); -- struct unicam_device *dev = node->dev; -- const struct unicam_fmt *fmt; -- struct v4l2_subdev_frame_interval_enum fie = { -- .index = fival->index, -- .width = fival->width, -- .height = fival->height, -- .which = V4L2_SUBDEV_FORMAT_ACTIVE, -- }; -- int ret; -- -- fmt = find_format_by_pix(dev, fival->pixel_format); -- if (!fmt) -- return -EINVAL; -- -- fie.code = fmt->code; -- ret = v4l2_subdev_call(dev->sensor, pad, enum_frame_interval, -- NULL, &fie); -- if (ret) -- return ret; -- -- fival->type = V4L2_FRMIVAL_TYPE_DISCRETE; -- fival->discrete = fie.interval; -- -- return 0; --} -- --static int unicam_g_parm(struct file *file, void *fh, struct v4l2_streamparm *a) --{ -- struct unicam_node *node = video_drvdata(file); -- struct unicam_device *dev = node->dev; -- -- return v4l2_g_parm_cap(video_devdata(file), dev->sensor, a); --} -- --static int unicam_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a) --{ -- struct unicam_node *node = video_drvdata(file); -- struct unicam_device *dev = node->dev; -- -- return v4l2_s_parm_cap(video_devdata(file), dev->sensor, a); --} -- --static int unicam_g_dv_timings(struct file *file, void *priv, -- struct v4l2_dv_timings *timings) --{ -- struct unicam_node *node = video_drvdata(file); -- struct unicam_device *dev = node->dev; -- -- return v4l2_subdev_call(dev->sensor, video, g_dv_timings, timings); --} -- --static int unicam_s_dv_timings(struct file *file, void *priv, -- struct v4l2_dv_timings *timings) --{ -- struct unicam_node *node = video_drvdata(file); -- struct unicam_device *dev = node->dev; -- struct v4l2_dv_timings current_timings; -- int ret; -- -- ret = v4l2_subdev_call(dev->sensor, video, g_dv_timings, -- ¤t_timings); -- -- if (v4l2_match_dv_timings(timings, ¤t_timings, 0, false)) -- return 0; -- -- if (vb2_is_busy(&node->buffer_queue)) -- return -EBUSY; -- -- ret = v4l2_subdev_call(dev->sensor, video, s_dv_timings, timings); -- -- /* Force recomputation of bytesperline */ -- node->v_fmt.fmt.pix.bytesperline = 0; -- -- unicam_reset_format(node); -- -- return ret; --} -- --static int unicam_query_dv_timings(struct file *file, void *priv, -- struct v4l2_dv_timings *timings) --{ -- struct unicam_node *node = video_drvdata(file); -- struct unicam_device *dev = node->dev; -- -- return v4l2_subdev_call(dev->sensor, video, query_dv_timings, timings); --} -- --static int unicam_enum_dv_timings(struct file *file, void *priv, -- struct v4l2_enum_dv_timings *timings) --{ -- struct unicam_node *node = video_drvdata(file); -- struct unicam_device *dev = node->dev; -- -- return v4l2_subdev_call(dev->sensor, pad, enum_dv_timings, timings); --} -- --static int unicam_dv_timings_cap(struct file *file, void *priv, -- struct v4l2_dv_timings_cap *cap) --{ -- struct unicam_node *node = video_drvdata(file); -- struct unicam_device *dev = node->dev; -- -- return v4l2_subdev_call(dev->sensor, pad, dv_timings_cap, cap); --} -- --static int unicam_subscribe_event(struct v4l2_fh *fh, -- const struct v4l2_event_subscription *sub) --{ -- switch (sub->type) { -- case V4L2_EVENT_FRAME_SYNC: -- return v4l2_event_subscribe(fh, sub, 2, NULL); -- case V4L2_EVENT_SOURCE_CHANGE: -- return v4l2_event_subscribe(fh, sub, 4, NULL); -- } -- -- return v4l2_ctrl_subscribe_event(fh, sub); --} -- --static int unicam_log_status(struct file *file, void *fh) --{ -- struct unicam_node *node = video_drvdata(file); -- struct unicam_device *dev = node->dev; -- struct unicam_cfg *cfg = &dev->cfg; -- u32 reg; -- -- /* status for sub devices */ -- v4l2_device_call_all(&dev->v4l2_dev, 0, core, log_status); -- -- unicam_info(dev, "-----Receiver status-----\n"); -- unicam_info(dev, "V4L2 width/height: %ux%u\n", -- node->v_fmt.fmt.pix.width, node->v_fmt.fmt.pix.height); -- unicam_info(dev, "Mediabus format: %08x\n", node->fmt->code); -- unicam_info(dev, "V4L2 format: %08x\n", -- node->v_fmt.fmt.pix.pixelformat); -- reg = reg_read(&dev->cfg, UNICAM_IPIPE); -- unicam_info(dev, "Unpacking/packing: %u / %u\n", -- get_field(reg, UNICAM_PUM_MASK), -- get_field(reg, UNICAM_PPM_MASK)); -- unicam_info(dev, "----Live data----\n"); -- unicam_info(dev, "Programmed stride: %4u\n", -- reg_read(cfg, UNICAM_IBLS)); -- unicam_info(dev, "Detected resolution: %ux%u\n", -- reg_read(cfg, UNICAM_IHSTA), -- reg_read(cfg, UNICAM_IVSTA)); -- unicam_info(dev, "Write pointer: %08x\n", -- reg_read(cfg, UNICAM_IBWP)); -- -- return 0; --} -- --static void unicam_notify(struct v4l2_subdev *sd, -- unsigned int notification, void *arg) --{ -- struct unicam_device *dev = -- container_of(sd->v4l2_dev, struct unicam_device, v4l2_dev); -- -- switch (notification) { -- case V4L2_DEVICE_NOTIFY_EVENT: -- v4l2_event_queue(&dev->node[IMAGE_PAD].video_dev, arg); -- break; -- default: -- break; -- } --} -- --static const struct vb2_ops unicam_video_qops = { -- .wait_prepare = vb2_ops_wait_prepare, -- .wait_finish = vb2_ops_wait_finish, -- .queue_setup = unicam_queue_setup, -- .buf_prepare = unicam_buffer_prepare, -- .buf_queue = unicam_buffer_queue, -- .start_streaming = unicam_start_streaming, -- .stop_streaming = unicam_stop_streaming, --}; -- --/* -- * unicam_open : This function is based on the v4l2_fh_open helper function. -- * It has been augmented to handle sensor subdevice power management, -- */ --static int unicam_open(struct file *file) --{ -- struct unicam_node *node = video_drvdata(file); -- struct unicam_device *dev = node->dev; -- int ret; -- -- mutex_lock(&node->lock); -- -- ret = v4l2_fh_open(file); -- if (ret) { -- unicam_err(dev, "v4l2_fh_open failed\n"); -- goto unlock; -- } -- -- node->open++; -- -- if (!v4l2_fh_is_singular_file(file)) -- goto unlock; -- -- ret = v4l2_subdev_call(dev->sensor, core, s_power, 1); -- if (ret < 0 && ret != -ENOIOCTLCMD) { -- v4l2_fh_release(file); -- node->open--; -- goto unlock; -- } -- -- ret = 0; -- --unlock: -- mutex_unlock(&node->lock); -- return ret; --} -- --static int unicam_release(struct file *file) --{ -- struct unicam_node *node = video_drvdata(file); -- struct unicam_device *dev = node->dev; -- struct v4l2_subdev *sd = dev->sensor; -- bool fh_singular; -- int ret; -- -- mutex_lock(&node->lock); -- -- fh_singular = v4l2_fh_is_singular_file(file); -- -- ret = _vb2_fop_release(file, NULL); -- -- if (fh_singular) -- v4l2_subdev_call(sd, core, s_power, 0); -- -- node->open--; -- mutex_unlock(&node->lock); -- -- return ret; --} -- --/* unicam capture driver file operations */ --static const struct v4l2_file_operations unicam_fops = { -- .owner = THIS_MODULE, -- .open = unicam_open, -- .release = unicam_release, -- .read = vb2_fop_read, -- .poll = vb2_fop_poll, -- .unlocked_ioctl = video_ioctl2, -- .mmap = vb2_fop_mmap, --}; -- --/* unicam capture ioctl operations */ --static const struct v4l2_ioctl_ops unicam_ioctl_ops = { -- .vidioc_querycap = unicam_querycap, -- .vidioc_enum_fmt_vid_cap = unicam_enum_fmt_vid_cap, -- .vidioc_g_fmt_vid_cap = unicam_g_fmt_vid_cap, -- .vidioc_s_fmt_vid_cap = unicam_s_fmt_vid_cap, -- .vidioc_try_fmt_vid_cap = unicam_try_fmt_vid_cap, -- -- .vidioc_enum_fmt_meta_cap = unicam_enum_fmt_meta_cap, -- .vidioc_g_fmt_meta_cap = unicam_g_fmt_meta_cap, -- .vidioc_s_fmt_meta_cap = unicam_s_fmt_meta_cap, -- .vidioc_try_fmt_meta_cap = unicam_try_fmt_meta_cap, -- -- .vidioc_enum_input = unicam_enum_input, -- .vidioc_g_input = unicam_g_input, -- .vidioc_s_input = unicam_s_input, -- -- .vidioc_querystd = unicam_querystd, -- .vidioc_s_std = unicam_s_std, -- .vidioc_g_std = unicam_g_std, -- -- .vidioc_g_edid = unicam_g_edid, -- .vidioc_s_edid = unicam_s_edid, -- -- .vidioc_enum_framesizes = unicam_enum_framesizes, -- .vidioc_enum_frameintervals = unicam_enum_frameintervals, -- -- .vidioc_g_selection = unicam_g_selection, -- .vidioc_s_selection = unicam_s_selection, -- -- .vidioc_g_parm = unicam_g_parm, -- .vidioc_s_parm = unicam_s_parm, -- -- .vidioc_s_dv_timings = unicam_s_dv_timings, -- .vidioc_g_dv_timings = unicam_g_dv_timings, -- .vidioc_query_dv_timings = unicam_query_dv_timings, -- .vidioc_enum_dv_timings = unicam_enum_dv_timings, -- .vidioc_dv_timings_cap = unicam_dv_timings_cap, -- -- .vidioc_reqbufs = vb2_ioctl_reqbufs, -- .vidioc_create_bufs = vb2_ioctl_create_bufs, -- .vidioc_prepare_buf = vb2_ioctl_prepare_buf, -- .vidioc_querybuf = vb2_ioctl_querybuf, -- .vidioc_qbuf = vb2_ioctl_qbuf, -- .vidioc_dqbuf = vb2_ioctl_dqbuf, -- .vidioc_expbuf = vb2_ioctl_expbuf, -- .vidioc_streamon = vb2_ioctl_streamon, -- .vidioc_streamoff = vb2_ioctl_streamoff, -- -- .vidioc_log_status = unicam_log_status, -- .vidioc_subscribe_event = unicam_subscribe_event, -- .vidioc_unsubscribe_event = v4l2_event_unsubscribe, --}; -- --static int --unicam_async_bound(struct v4l2_async_notifier *notifier, -- struct v4l2_subdev *subdev, -- struct v4l2_async_subdev *asd) --{ -- struct unicam_device *unicam = container_of(notifier->v4l2_dev, -- struct unicam_device, v4l2_dev); -- -- if (unicam->sensor) { -- unicam_info(unicam, "Rejecting subdev %s (Already set!!)", -- subdev->name); -- return 0; -- } -- -- unicam->sensor = subdev; -- unicam_dbg(1, unicam, "Using sensor %s for capture\n", subdev->name); -- -- return 0; --} -- --static int register_node(struct unicam_device *unicam, struct unicam_node *node, -- enum v4l2_buf_type type, int pad_id) --{ -- struct video_device *vdev; -- struct vb2_queue *q; -- struct v4l2_mbus_framefmt mbus_fmt = {0}; -- const struct unicam_fmt *fmt; -- int ret; -- -- if (unicam->sensor_embedded_data || pad_id != METADATA_PAD) { -- ret = __subdev_get_format(unicam, &mbus_fmt, pad_id); -- if (ret) { -- unicam_err(unicam, "Failed to get_format - ret %d\n", -- ret); -- return ret; -- } -- -- fmt = find_format_by_code(mbus_fmt.code); -- if (!fmt) { -- /* Find the first format that the sensor and unicam both -- * support -- */ -- fmt = get_first_supported_format(unicam); -- -- if (!fmt) -- /* No compatible formats */ -- return -EINVAL; -- -- mbus_fmt.code = fmt->code; -- ret = __subdev_set_format(unicam, &mbus_fmt, pad_id); -- if (ret) -- return -EINVAL; -- } -- if (mbus_fmt.field != V4L2_FIELD_NONE) { -- /* Interlaced not supported - disable it now. */ -- mbus_fmt.field = V4L2_FIELD_NONE; -- ret = __subdev_set_format(unicam, &mbus_fmt, pad_id); -- if (ret) -- return -EINVAL; -- } -- } else { -- /* Fix this node format as embedded data. */ -- fmt = find_format_by_code(MEDIA_BUS_FMT_SENSOR_DATA); -- } -- -- node->dev = unicam; -- node->pad_id = pad_id; -- node->fmt = fmt; -- if (fmt->fourcc) { -- if (fmt->fourcc != V4L2_META_FMT_SENSOR_DATA) -- node->v_fmt.fmt.pix.pixelformat = fmt->fourcc; -- else -- node->v_fmt.fmt.meta.dataformat = fmt->fourcc; -- } else { -- node->v_fmt.fmt.pix.pixelformat = fmt->repacked_fourcc; -- } -- -- /* Read current subdev format */ -- unicam_reset_format(node); -- -- if (v4l2_subdev_has_op(unicam->sensor, video, s_std)) { -- v4l2_std_id tvnorms; -- -- if (WARN_ON(!v4l2_subdev_has_op(unicam->sensor, video, -- g_tvnorms))) -- /* -- * Subdevice should not advertise s_std but not -- * g_tvnorms -- */ -- return -EINVAL; -- -- ret = v4l2_subdev_call(unicam->sensor, video, -- g_tvnorms, &tvnorms); -- if (WARN_ON(ret)) -- return -EINVAL; -- node->video_dev.tvnorms |= tvnorms; -- } -- -- spin_lock_init(&node->dma_queue_lock); -- mutex_init(&node->lock); -- -- vdev = &node->video_dev; -- if (pad_id == IMAGE_PAD) { -- /* Add controls from the subdevice */ -- ret = v4l2_ctrl_add_handler(&node->ctrl_handler, -- unicam->sensor->ctrl_handler, NULL, -- true); -- if (ret < 0) -- return ret; -- -- /* -- * If the sensor subdevice has any controls, associate the node -- * with the ctrl handler to allow access from userland. -- */ -- if (!list_empty(&node->ctrl_handler.ctrls)) -- vdev->ctrl_handler = &node->ctrl_handler; -- } -- -- q = &node->buffer_queue; -- q->type = type; -- q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_READ; -- q->drv_priv = node; -- q->ops = &unicam_video_qops; -- q->mem_ops = &vb2_dma_contig_memops; -- q->buf_struct_size = sizeof(struct unicam_buffer); -- q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; -- q->lock = &node->lock; -- q->min_buffers_needed = 1; -- q->dev = &unicam->pdev->dev; -- -- ret = vb2_queue_init(q); -- if (ret) { -- unicam_err(unicam, "vb2_queue_init() failed\n"); -- return ret; -- } -- -- INIT_LIST_HEAD(&node->dma_queue.active); -- -- vdev->release = video_device_release_empty; -- vdev->fops = &unicam_fops; -- vdev->ioctl_ops = &unicam_ioctl_ops; -- vdev->v4l2_dev = &unicam->v4l2_dev; -- vdev->vfl_dir = VFL_DIR_RX; -- vdev->queue = q; -- vdev->lock = &node->lock; -- vdev->device_caps = (pad_id == IMAGE_PAD) ? -- (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING) : -- (V4L2_CAP_META_CAPTURE | V4L2_CAP_STREAMING); -- -- /* Define the device names */ -- snprintf(vdev->name, sizeof(vdev->name), "%s-%s", UNICAM_MODULE_NAME, -- node->pad_id == IMAGE_PAD ? "image" : "embedded"); -- -- video_set_drvdata(vdev, node); -- vdev->entity.flags |= MEDIA_ENT_FL_DEFAULT; -- -- node->dummy_buf_cpu_addr = dma_alloc_coherent(&unicam->pdev->dev, -- DUMMY_BUF_SIZE, -- &node->dummy_buf_dma_addr, -- GFP_ATOMIC); -- if (!node->dummy_buf_cpu_addr) { -- unicam_err(unicam, "Unable to allocate dummy buffer.\n"); -- return -ENOMEM; -- } -- -- if (node->pad_id == METADATA_PAD) { -- v4l2_disable_ioctl(vdev, VIDIOC_DQEVENT); -- v4l2_disable_ioctl(vdev, VIDIOC_SUBSCRIBE_EVENT); -- v4l2_disable_ioctl(vdev, VIDIOC_UNSUBSCRIBE_EVENT); -- } -- if (node->pad_id == METADATA_PAD || -- !v4l2_subdev_has_op(unicam->sensor, video, s_std)) { -- v4l2_disable_ioctl(&node->video_dev, VIDIOC_S_STD); -- v4l2_disable_ioctl(&node->video_dev, VIDIOC_G_STD); -- v4l2_disable_ioctl(&node->video_dev, VIDIOC_ENUMSTD); -- } -- if (node->pad_id == METADATA_PAD || -- !v4l2_subdev_has_op(unicam->sensor, video, querystd)) -- v4l2_disable_ioctl(&node->video_dev, VIDIOC_QUERYSTD); -- if (node->pad_id == METADATA_PAD || -- !v4l2_subdev_has_op(unicam->sensor, video, s_dv_timings)) { -- v4l2_disable_ioctl(&node->video_dev, VIDIOC_S_EDID); -- v4l2_disable_ioctl(&node->video_dev, VIDIOC_G_EDID); -- v4l2_disable_ioctl(&node->video_dev, VIDIOC_DV_TIMINGS_CAP); -- v4l2_disable_ioctl(&node->video_dev, VIDIOC_G_DV_TIMINGS); -- v4l2_disable_ioctl(&node->video_dev, VIDIOC_S_DV_TIMINGS); -- v4l2_disable_ioctl(&node->video_dev, VIDIOC_ENUM_DV_TIMINGS); -- v4l2_disable_ioctl(&node->video_dev, VIDIOC_QUERY_DV_TIMINGS); -- } -- if (node->pad_id == METADATA_PAD || -- !v4l2_subdev_has_op(unicam->sensor, pad, enum_frame_interval)) -- v4l2_disable_ioctl(&node->video_dev, -- VIDIOC_ENUM_FRAMEINTERVALS); -- if (node->pad_id == METADATA_PAD || -- !v4l2_subdev_has_op(unicam->sensor, video, g_frame_interval)) -- v4l2_disable_ioctl(&node->video_dev, VIDIOC_G_PARM); -- if (node->pad_id == METADATA_PAD || -- !v4l2_subdev_has_op(unicam->sensor, video, s_frame_interval)) -- v4l2_disable_ioctl(&node->video_dev, VIDIOC_S_PARM); -- -- if (node->pad_id == METADATA_PAD || -- !v4l2_subdev_has_op(unicam->sensor, pad, enum_frame_size)) -- v4l2_disable_ioctl(&node->video_dev, VIDIOC_ENUM_FRAMESIZES); -- -- if (node->pad_id == METADATA_PAD || -- !v4l2_subdev_has_op(unicam->sensor, pad, set_selection)) -- v4l2_disable_ioctl(&node->video_dev, VIDIOC_S_SELECTION); -- -- if (node->pad_id == METADATA_PAD || -- !v4l2_subdev_has_op(unicam->sensor, pad, get_selection)) -- v4l2_disable_ioctl(&node->video_dev, VIDIOC_G_SELECTION); -- -- ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1); -- if (ret) { -- unicam_err(unicam, "Unable to register video device.\n"); -- return ret; -- } -- node->registered = 1; -- -- if (unicam->sensor_embedded_data) { -- ret = media_create_pad_link(&unicam->sensor->entity, pad_id, -- &node->video_dev.entity, 0, -- MEDIA_LNK_FL_ENABLED | -- MEDIA_LNK_FL_IMMUTABLE); -- if (ret) -- unicam_err(unicam, "Unable to create pad links.\n"); -- } -- -- return ret; --} -- --static void unregister_nodes(struct unicam_device *unicam) --{ -- struct unicam_node *node; -- int i; -- -- for (i = 0; i < MAX_NODES; i++) { -- node = &unicam->node[i]; -- if (node->dummy_buf_cpu_addr) { -- dma_free_coherent(&unicam->pdev->dev, DUMMY_BUF_SIZE, -- node->dummy_buf_cpu_addr, -- node->dummy_buf_dma_addr); -- } -- if (node->registered) { -- video_unregister_device(&node->video_dev); -- node->registered = 0; -- } -- } --} -- --static int unicam_probe_complete(struct unicam_device *unicam) --{ -- int ret; -- -- v4l2_set_subdev_hostdata(unicam->sensor, unicam); -- -- unicam->v4l2_dev.notify = unicam_notify; -- -- unicam->sensor_config = v4l2_subdev_alloc_pad_config(unicam->sensor); -- if (!unicam->sensor_config) -- return -ENOMEM; -- -- unicam->sensor_embedded_data = (unicam->sensor->entity.num_pads >= 2); -- -- ret = register_node(unicam, &unicam->node[IMAGE_PAD], -- V4L2_BUF_TYPE_VIDEO_CAPTURE, IMAGE_PAD); -- if (ret) { -- unicam_err(unicam, "Unable to register subdev node 0.\n"); -- goto unregister; -- } -- -- ret = register_node(unicam, &unicam->node[METADATA_PAD], -- V4L2_BUF_TYPE_META_CAPTURE, METADATA_PAD); -- if (ret) { -- unicam_err(unicam, "Unable to register subdev node 1.\n"); -- goto unregister; -- } -- -- ret = v4l2_device_register_ro_subdev_nodes(&unicam->v4l2_dev); -- if (ret) { -- unicam_err(unicam, "Unable to register subdev nodes.\n"); -- goto unregister; -- } -- -- return 0; -- --unregister: -- unregister_nodes(unicam); -- -- return ret; --} -- --static int unicam_async_complete(struct v4l2_async_notifier *notifier) --{ -- struct unicam_device *unicam = container_of(notifier->v4l2_dev, -- struct unicam_device, v4l2_dev); -- -- return unicam_probe_complete(unicam); --} -- --static const struct v4l2_async_notifier_operations unicam_async_ops = { -- .bound = unicam_async_bound, -- .complete = unicam_async_complete, --}; -- --static int of_unicam_connect_subdevs(struct unicam_device *dev) --{ -- struct platform_device *pdev = dev->pdev; -- struct device_node *parent, *ep_node = NULL, *remote_ep = NULL, -- *sensor_node = NULL; -- struct v4l2_fwnode_endpoint *ep; -- struct v4l2_async_subdev *asd; -- unsigned int peripheral_data_lanes; -- int ret = -EINVAL; -- unsigned int lane; -- -- parent = pdev->dev.of_node; -- -- asd = &dev->asd; -- ep = &dev->endpoint; -- -- ep_node = of_graph_get_next_endpoint(parent, NULL); -- if (!ep_node) { -- unicam_dbg(3, dev, "can't get next endpoint\n"); -- goto cleanup_exit; -- } -- -- unicam_dbg(3, dev, "ep_node is %s\n", ep_node->name); -- -- v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep_node), ep); -- -- for (lane = 0; lane < ep->bus.mipi_csi2.num_data_lanes; lane++) { -- if (ep->bus.mipi_csi2.data_lanes[lane] != lane + 1) { -- unicam_err(dev, "Local endpoint - data lane reordering not supported\n"); -- goto cleanup_exit; -- } -- } -- -- peripheral_data_lanes = ep->bus.mipi_csi2.num_data_lanes; -- -- sensor_node = of_graph_get_remote_port_parent(ep_node); -- if (!sensor_node) { -- unicam_dbg(3, dev, "can't get remote parent\n"); -- goto cleanup_exit; -- } -- unicam_dbg(3, dev, "sensor_node is %s\n", sensor_node->name); -- asd->match_type = V4L2_ASYNC_MATCH_FWNODE; -- asd->match.fwnode = of_fwnode_handle(sensor_node); -- -- remote_ep = of_graph_get_remote_endpoint(ep_node); -- if (!remote_ep) { -- unicam_dbg(3, dev, "can't get remote-endpoint\n"); -- goto cleanup_exit; -- } -- unicam_dbg(3, dev, "remote_ep is %s\n", remote_ep->name); -- v4l2_fwnode_endpoint_parse(of_fwnode_handle(remote_ep), ep); -- unicam_dbg(3, dev, "parsed remote_ep to endpoint. nr_of_link_frequencies %u, bus_type %u\n", -- ep->nr_of_link_frequencies, ep->bus_type); -- -- switch (ep->bus_type) { -- case V4L2_MBUS_CSI2_DPHY: -- if (ep->bus.mipi_csi2.num_data_lanes > -- peripheral_data_lanes) { -- unicam_err(dev, "Subdevice %s wants too many data lanes (%u > %u)\n", -- sensor_node->name, -- ep->bus.mipi_csi2.num_data_lanes, -- peripheral_data_lanes); -- goto cleanup_exit; -- } -- for (lane = 0; -- lane < ep->bus.mipi_csi2.num_data_lanes; -- lane++) { -- if (ep->bus.mipi_csi2.data_lanes[lane] != lane + 1) { -- unicam_err(dev, "Subdevice %s - incompatible data lane config\n", -- sensor_node->name); -- goto cleanup_exit; -- } -- } -- dev->max_data_lanes = ep->bus.mipi_csi2.num_data_lanes; -- dev->bus_flags = ep->bus.mipi_csi2.flags; -- break; -- case V4L2_MBUS_CCP2: -- if (ep->bus.mipi_csi1.clock_lane != 0 || -- ep->bus.mipi_csi1.data_lane != 1) { -- unicam_err(dev, "Subdevice %s incompatible lane config\n", -- sensor_node->name); -- goto cleanup_exit; -- } -- dev->max_data_lanes = 1; -- dev->bus_flags = ep->bus.mipi_csi1.strobe; -- break; -- default: -- /* Unsupported bus type */ -- unicam_err(dev, "sub-device %s is not a CSI2 or CCP2 device %d\n", -- sensor_node->name, ep->bus_type); -- goto cleanup_exit; -- } -- -- /* Store bus type - CSI2 or CCP2 */ -- dev->bus_type = ep->bus_type; -- unicam_dbg(3, dev, "bus_type is %d\n", dev->bus_type); -- -- /* Store Virtual Channel number */ -- dev->virtual_channel = ep->base.id; -- -- unicam_dbg(3, dev, "v4l2-endpoint: %s\n", -- dev->bus_type == V4L2_MBUS_CSI2_DPHY ? "CSI2" : "CCP2"); -- unicam_dbg(3, dev, "Virtual Channel=%d\n", dev->virtual_channel); -- if (dev->bus_type == V4L2_MBUS_CSI2_DPHY) -- unicam_dbg(3, dev, "flags=0x%08x\n", ep->bus.mipi_csi2.flags); -- unicam_dbg(3, dev, "num_data_lanes=%d\n", dev->max_data_lanes); -- -- unicam_dbg(1, dev, "found sub-device %s\n", sensor_node->name); -- -- v4l2_async_notifier_init(&dev->notifier); -- -- ret = v4l2_async_notifier_add_subdev(&dev->notifier, asd); -- if (ret) { -- unicam_err(dev, "Error adding subdevice - ret %d\n", ret); -- goto cleanup_exit; -- } -- -- dev->notifier.ops = &unicam_async_ops; -- ret = v4l2_async_notifier_register(&dev->v4l2_dev, -- &dev->notifier); -- if (ret) { -- unicam_err(dev, "Error registering async notifier - ret %d\n", -- ret); -- ret = -EINVAL; -- } -- --cleanup_exit: -- if (remote_ep) -- of_node_put(remote_ep); -- if (sensor_node) -- of_node_put(sensor_node); -- if (ep_node) -- of_node_put(ep_node); -- -- return ret; --} -- --static int unicam_probe(struct platform_device *pdev) --{ -- struct unicam_cfg *unicam_cfg; -- struct unicam_device *unicam; -- struct v4l2_ctrl_handler *hdl; -- struct resource *res; -- int ret; -- -- unicam = devm_kzalloc(&pdev->dev, sizeof(*unicam), GFP_KERNEL); -- if (!unicam) -- return -ENOMEM; -- -- unicam->pdev = pdev; -- unicam_cfg = &unicam->cfg; -- -- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- unicam_cfg->base = devm_ioremap_resource(&pdev->dev, res); -- if (IS_ERR(unicam_cfg->base)) { -- unicam_err(unicam, "Failed to get main io block\n"); -- return PTR_ERR(unicam_cfg->base); -- } -- -- res = platform_get_resource(pdev, IORESOURCE_MEM, 1); -- unicam_cfg->clk_gate_base = devm_ioremap_resource(&pdev->dev, res); -- if (IS_ERR(unicam_cfg->clk_gate_base)) { -- unicam_err(unicam, "Failed to get 2nd io block\n"); -- return PTR_ERR(unicam_cfg->clk_gate_base); -- } -- -- unicam->clock = devm_clk_get(&pdev->dev, "lp"); -- if (IS_ERR(unicam->clock)) { -- unicam_err(unicam, "Failed to get clock\n"); -- return PTR_ERR(unicam->clock); -- } -- -- ret = platform_get_irq(pdev, 0); -- if (ret <= 0) { -- dev_err(&pdev->dev, "No IRQ resource\n"); -- return -ENODEV; -- } -- -- ret = devm_request_irq(&pdev->dev, ret, unicam_isr, 0, -- "unicam_capture0", unicam); -- if (ret) { -- dev_err(&pdev->dev, "Unable to request interrupt\n"); -- return -EINVAL; -- } -- -- unicam->mdev.dev = &pdev->dev; -- strscpy(unicam->mdev.model, UNICAM_MODULE_NAME, -- sizeof(unicam->mdev.model)); -- strscpy(unicam->mdev.serial, "", sizeof(unicam->mdev.serial)); -- snprintf(unicam->mdev.bus_info, sizeof(unicam->mdev.bus_info), -- "platform:%s %s", -- pdev->dev.driver->name, dev_name(&pdev->dev)); -- unicam->mdev.hw_revision = 1; -- -- media_entity_pads_init(&unicam->node[IMAGE_PAD].video_dev.entity, 1, -- &unicam->node[IMAGE_PAD].pad); -- media_entity_pads_init(&unicam->node[METADATA_PAD].video_dev.entity, 1, -- &unicam->node[METADATA_PAD].pad); -- media_device_init(&unicam->mdev); -- -- unicam->v4l2_dev.mdev = &unicam->mdev; -- -- ret = v4l2_device_register(&pdev->dev, &unicam->v4l2_dev); -- if (ret) { -- unicam_err(unicam, -- "Unable to register v4l2 device.\n"); -- goto media_cleanup; -- } -- -- ret = media_device_register(&unicam->mdev); -- if (ret < 0) { -- unicam_err(unicam, -- "Unable to register media-controller device.\n"); -- goto probe_out_v4l2_unregister; -- } -- -- /* Reserve space for the controls */ -- hdl = &unicam->node[IMAGE_PAD].ctrl_handler; -- ret = v4l2_ctrl_handler_init(hdl, 16); -- if (ret < 0) -- goto media_unregister; -- -- /* set the driver data in platform device */ -- platform_set_drvdata(pdev, unicam); -- -- ret = of_unicam_connect_subdevs(unicam); -- if (ret) { -- dev_err(&pdev->dev, "Failed to connect subdevs\n"); -- goto free_hdl; -- } -- -- /* Enable the block power domain */ -- pm_runtime_enable(&pdev->dev); -- -- return 0; -- --free_hdl: -- v4l2_ctrl_handler_free(hdl); --media_unregister: -- media_device_unregister(&unicam->mdev); --probe_out_v4l2_unregister: -- v4l2_device_unregister(&unicam->v4l2_dev); --media_cleanup: -- media_device_cleanup(&unicam->mdev); -- -- return ret; --} -- --static int unicam_remove(struct platform_device *pdev) --{ -- struct unicam_device *unicam = platform_get_drvdata(pdev); -- -- unicam_dbg(2, unicam, "%s\n", __func__); -- -- pm_runtime_disable(&pdev->dev); -- -- v4l2_async_notifier_unregister(&unicam->notifier); -- v4l2_ctrl_handler_free(&unicam->node[IMAGE_PAD].ctrl_handler); -- v4l2_device_unregister(&unicam->v4l2_dev); -- unregister_nodes(unicam); -- if (unicam->sensor_config) -- v4l2_subdev_free_pad_config(unicam->sensor_config); -- media_device_unregister(&unicam->mdev); -- media_device_cleanup(&unicam->mdev); -- -- return 0; --} -- --static const struct of_device_id unicam_of_match[] = { -- { .compatible = "brcm,bcm2835-unicam", }, -- { /* sentinel */ }, --}; --MODULE_DEVICE_TABLE(of, unicam_of_match); -- --static struct platform_driver unicam_driver = { -- .probe = unicam_probe, -- .remove = unicam_remove, -- .driver = { -- .name = UNICAM_MODULE_NAME, -- .of_match_table = of_match_ptr(unicam_of_match), -- }, --}; -- --module_platform_driver(unicam_driver); -- --MODULE_AUTHOR("Dave Stevenson "); --MODULE_DESCRIPTION("BCM2835 Unicam driver"); --MODULE_LICENSE("GPL"); --MODULE_VERSION(UNICAM_VERSION); ---- a/drivers/media/platform/bcm2835/vc4-regs-unicam.h -+++ /dev/null -@@ -1,253 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0-only */ -- --/* -- * Copyright (C) 2017-2020 Raspberry Pi Trading. -- * Dave Stevenson -- */ -- --#ifndef VC4_REGS_UNICAM_H --#define VC4_REGS_UNICAM_H -- --/* -- * The following values are taken from files found within the code drop -- * made by Broadcom for the BCM21553 Graphics Driver, predominantly in -- * brcm_usrlib/dag/vmcsx/vcinclude/hardware_vc4.h. -- * They have been modified to be only the register offset. -- */ --#define UNICAM_CTRL 0x000 --#define UNICAM_STA 0x004 --#define UNICAM_ANA 0x008 --#define UNICAM_PRI 0x00c --#define UNICAM_CLK 0x010 --#define UNICAM_CLT 0x014 --#define UNICAM_DAT0 0x018 --#define UNICAM_DAT1 0x01c --#define UNICAM_DAT2 0x020 --#define UNICAM_DAT3 0x024 --#define UNICAM_DLT 0x028 --#define UNICAM_CMP0 0x02c --#define UNICAM_CMP1 0x030 --#define UNICAM_CAP0 0x034 --#define UNICAM_CAP1 0x038 --#define UNICAM_ICTL 0x100 --#define UNICAM_ISTA 0x104 --#define UNICAM_IDI0 0x108 --#define UNICAM_IPIPE 0x10c --#define UNICAM_IBSA0 0x110 --#define UNICAM_IBEA0 0x114 --#define UNICAM_IBLS 0x118 --#define UNICAM_IBWP 0x11c --#define UNICAM_IHWIN 0x120 --#define UNICAM_IHSTA 0x124 --#define UNICAM_IVWIN 0x128 --#define UNICAM_IVSTA 0x12c --#define UNICAM_ICC 0x130 --#define UNICAM_ICS 0x134 --#define UNICAM_IDC 0x138 --#define UNICAM_IDPO 0x13c --#define UNICAM_IDCA 0x140 --#define UNICAM_IDCD 0x144 --#define UNICAM_IDS 0x148 --#define UNICAM_DCS 0x200 --#define UNICAM_DBSA0 0x204 --#define UNICAM_DBEA0 0x208 --#define UNICAM_DBWP 0x20c --#define UNICAM_DBCTL 0x300 --#define UNICAM_IBSA1 0x304 --#define UNICAM_IBEA1 0x308 --#define UNICAM_IDI1 0x30c --#define UNICAM_DBSA1 0x310 --#define UNICAM_DBEA1 0x314 --#define UNICAM_MISC 0x400 -- --/* -- * The following bitmasks are from the kernel released by Broadcom -- * for Android - https://android.googlesource.com/kernel/bcm/ -- * The Rhea, Hawaii, and Java chips all contain the same VideoCore4 -- * Unicam block as BCM2835, as defined in eg -- * arch/arm/mach-rhea/include/mach/rdb_A0/brcm_rdb_cam.h and similar. -- * Values reworked to use the kernel BIT and GENMASK macros. -- * -- * Some of the bit mnenomics have been amended to match the datasheet. -- */ --/* UNICAM_CTRL Register */ --#define UNICAM_CPE BIT(0) --#define UNICAM_MEM BIT(1) --#define UNICAM_CPR BIT(2) --#define UNICAM_CPM_MASK GENMASK(3, 3) --#define UNICAM_CPM_CSI2 0 --#define UNICAM_CPM_CCP2 1 --#define UNICAM_SOE BIT(4) --#define UNICAM_DCM_MASK GENMASK(5, 5) --#define UNICAM_DCM_STROBE 0 --#define UNICAM_DCM_DATA 1 --#define UNICAM_SLS BIT(6) --#define UNICAM_PFT_MASK GENMASK(11, 8) --#define UNICAM_OET_MASK GENMASK(20, 12) -- --/* UNICAM_STA Register */ --#define UNICAM_SYN BIT(0) --#define UNICAM_CS BIT(1) --#define UNICAM_SBE BIT(2) --#define UNICAM_PBE BIT(3) --#define UNICAM_HOE BIT(4) --#define UNICAM_PLE BIT(5) --#define UNICAM_SSC BIT(6) --#define UNICAM_CRCE BIT(7) --#define UNICAM_OES BIT(8) --#define UNICAM_IFO BIT(9) --#define UNICAM_OFO BIT(10) --#define UNICAM_BFO BIT(11) --#define UNICAM_DL BIT(12) --#define UNICAM_PS BIT(13) --#define UNICAM_IS BIT(14) --#define UNICAM_PI0 BIT(15) --#define UNICAM_PI1 BIT(16) --#define UNICAM_FSI_S BIT(17) --#define UNICAM_FEI_S BIT(18) --#define UNICAM_LCI_S BIT(19) --#define UNICAM_BUF0_RDY BIT(20) --#define UNICAM_BUF0_NO BIT(21) --#define UNICAM_BUF1_RDY BIT(22) --#define UNICAM_BUF1_NO BIT(23) --#define UNICAM_DI BIT(24) -- --#define UNICAM_STA_MASK_ALL \ -- (UNICAM_DL + \ -- UNICAM_SBE + \ -- UNICAM_PBE + \ -- UNICAM_HOE + \ -- UNICAM_PLE + \ -- UNICAM_SSC + \ -- UNICAM_CRCE + \ -- UNICAM_IFO + \ -- UNICAM_OFO + \ -- UNICAM_PS + \ -- UNICAM_PI0 + \ -- UNICAM_PI1) -- --/* UNICAM_ANA Register */ --#define UNICAM_APD BIT(0) --#define UNICAM_BPD BIT(1) --#define UNICAM_AR BIT(2) --#define UNICAM_DDL BIT(3) --#define UNICAM_CTATADJ_MASK GENMASK(7, 4) --#define UNICAM_PTATADJ_MASK GENMASK(11, 8) -- --/* UNICAM_PRI Register */ --#define UNICAM_PE BIT(0) --#define UNICAM_PT_MASK GENMASK(2, 1) --#define UNICAM_NP_MASK GENMASK(7, 4) --#define UNICAM_PP_MASK GENMASK(11, 8) --#define UNICAM_BS_MASK GENMASK(15, 12) --#define UNICAM_BL_MASK GENMASK(17, 16) -- --/* UNICAM_CLK Register */ --#define UNICAM_CLE BIT(0) --#define UNICAM_CLPD BIT(1) --#define UNICAM_CLLPE BIT(2) --#define UNICAM_CLHSE BIT(3) --#define UNICAM_CLTRE BIT(4) --#define UNICAM_CLAC_MASK GENMASK(8, 5) --#define UNICAM_CLSTE BIT(29) -- --/* UNICAM_CLT Register */ --#define UNICAM_CLT1_MASK GENMASK(7, 0) --#define UNICAM_CLT2_MASK GENMASK(15, 8) -- --/* UNICAM_DATn Registers */ --#define UNICAM_DLE BIT(0) --#define UNICAM_DLPD BIT(1) --#define UNICAM_DLLPE BIT(2) --#define UNICAM_DLHSE BIT(3) --#define UNICAM_DLTRE BIT(4) --#define UNICAM_DLSM BIT(5) --#define UNICAM_DLFO BIT(28) --#define UNICAM_DLSTE BIT(29) -- --#define UNICAM_DAT_MASK_ALL (UNICAM_DLSTE + UNICAM_DLFO) -- --/* UNICAM_DLT Register */ --#define UNICAM_DLT1_MASK GENMASK(7, 0) --#define UNICAM_DLT2_MASK GENMASK(15, 8) --#define UNICAM_DLT3_MASK GENMASK(23, 16) -- --/* UNICAM_ICTL Register */ --#define UNICAM_FSIE BIT(0) --#define UNICAM_FEIE BIT(1) --#define UNICAM_IBOB BIT(2) --#define UNICAM_FCM BIT(3) --#define UNICAM_TFC BIT(4) --#define UNICAM_LIP_MASK GENMASK(6, 5) --#define UNICAM_LCIE_MASK GENMASK(28, 16) -- --/* UNICAM_IDI0/1 Register */ --#define UNICAM_ID0_MASK GENMASK(7, 0) --#define UNICAM_ID1_MASK GENMASK(15, 8) --#define UNICAM_ID2_MASK GENMASK(23, 16) --#define UNICAM_ID3_MASK GENMASK(31, 24) -- --/* UNICAM_ISTA Register */ --#define UNICAM_FSI BIT(0) --#define UNICAM_FEI BIT(1) --#define UNICAM_LCI BIT(2) -- --#define UNICAM_ISTA_MASK_ALL (UNICAM_FSI + UNICAM_FEI + UNICAM_LCI) -- --/* UNICAM_IPIPE Register */ --#define UNICAM_PUM_MASK GENMASK(2, 0) -- /* Unpacking modes */ -- #define UNICAM_PUM_NONE 0 -- #define UNICAM_PUM_UNPACK6 1 -- #define UNICAM_PUM_UNPACK7 2 -- #define UNICAM_PUM_UNPACK8 3 -- #define UNICAM_PUM_UNPACK10 4 -- #define UNICAM_PUM_UNPACK12 5 -- #define UNICAM_PUM_UNPACK14 6 -- #define UNICAM_PUM_UNPACK16 7 --#define UNICAM_DDM_MASK GENMASK(6, 3) --#define UNICAM_PPM_MASK GENMASK(9, 7) -- /* Packing modes */ -- #define UNICAM_PPM_NONE 0 -- #define UNICAM_PPM_PACK8 1 -- #define UNICAM_PPM_PACK10 2 -- #define UNICAM_PPM_PACK12 3 -- #define UNICAM_PPM_PACK14 4 -- #define UNICAM_PPM_PACK16 5 --#define UNICAM_DEM_MASK GENMASK(11, 10) --#define UNICAM_DEBL_MASK GENMASK(14, 12) --#define UNICAM_ICM_MASK GENMASK(16, 15) --#define UNICAM_IDM_MASK GENMASK(17, 17) -- --/* UNICAM_ICC Register */ --#define UNICAM_ICFL_MASK GENMASK(4, 0) --#define UNICAM_ICFH_MASK GENMASK(9, 5) --#define UNICAM_ICST_MASK GENMASK(12, 10) --#define UNICAM_ICLT_MASK GENMASK(15, 13) --#define UNICAM_ICLL_MASK GENMASK(31, 16) -- --/* UNICAM_DCS Register */ --#define UNICAM_DIE BIT(0) --#define UNICAM_DIM BIT(1) --#define UNICAM_DBOB BIT(3) --#define UNICAM_FDE BIT(4) --#define UNICAM_LDP BIT(5) --#define UNICAM_EDL_MASK GENMASK(15, 8) -- --/* UNICAM_DBCTL Register */ --#define UNICAM_DBEN BIT(0) --#define UNICAM_BUF0_IE BIT(1) --#define UNICAM_BUF1_IE BIT(2) -- --/* UNICAM_CMP[0,1] register */ --#define UNICAM_PCE BIT(31) --#define UNICAM_GI BIT(9) --#define UNICAM_CPH BIT(8) --#define UNICAM_PCVC_MASK GENMASK(7, 6) --#define UNICAM_PCDT_MASK GENMASK(5, 0) -- --/* UNICAM_MISC register */ --#define UNICAM_FL0 BIT(6) --#define UNICAM_FL1 BIT(9) -- --#endif diff --git a/target/linux/bcm27xx/patches-5.15/950-0249-media-i2c-imx290-set-the-format-before-VIDIOC_SUBDEV.patch b/target/linux/bcm27xx/patches-5.15/950-0249-media-i2c-imx290-set-the-format-before-VIDIOC_SUBDEV.patch deleted file mode 100644 index 6acd7f34b..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0249-media-i2c-imx290-set-the-format-before-VIDIOC_SUBDEV.patch +++ /dev/null @@ -1,40 +0,0 @@ -From e2d1526bc0029a25dc1aac46f63630cd876a978b Mon Sep 17 00:00:00 2001 -From: Andrey Konovalov -Date: Fri, 12 Jun 2020 15:53:46 +0200 -Subject: [PATCH] media: i2c: imx290: set the format before - VIDIOC_SUBDEV_G_FMT is called - -Commit d46cfdc86c30d5ec768924f0b1e2683c8d20b671 upstream. - -With the current driver 'media-ctl -p' issued right after the imx290 driver -is loaded prints: -pad0: Source - [fmt:unknown/0x0] - -The format value of zero is due to the current_format field of the imx290 -struct not being initialized yet. - -As imx290_entity_init_cfg() calls imx290_set_fmt(), the current_mode field -is also initialized, so the line which set current_mode to a default value -in driver's probe() function is no longer needed. - -Signed-off-by: Andrey Konovalov -Reviewed-by: Manivannan Sadhasivam -Signed-off-by: Sakari Ailus -Signed-off-by: Mauro Carvalho Chehab ---- - drivers/media/i2c/imx290.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/drivers/media/i2c/imx290.c -+++ b/drivers/media/i2c/imx290.c -@@ -1087,6 +1087,9 @@ static int imx290_probe(struct i2c_clien - goto free_ctrl; - } - -+ /* Initialize the frame format (this also sets imx290->current_mode) */ -+ imx290_entity_init_cfg(&imx290->sd, NULL); -+ - ret = v4l2_async_register_subdev(&imx290->sd); - if (ret < 0) { - dev_err(dev, "Could not register v4l2 device\n"); diff --git a/target/linux/bcm27xx/patches-5.15/950-0250-media-i2c-imx290-Add-support-for-74.25MHz-clock.patch b/target/linux/bcm27xx/patches-5.15/950-0250-media-i2c-imx290-Add-support-for-74.25MHz-clock.patch deleted file mode 100644 index 916ab1e56..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0250-media-i2c-imx290-Add-support-for-74.25MHz-clock.patch +++ /dev/null @@ -1,264 +0,0 @@ -From 9fe4d33587bd7931e2a0decc7c4881945a1c0ab3 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 25 Jun 2020 08:28:51 +0100 -Subject: [PATCH] media: i2c: imx290: Add support for 74.25MHz clock - -The existing driver only supported a clock of 37.125MHz, but the -sensor also supports 74.25MHz. - -Add the relevant register modifications to support this alternate -clock frequency. - -Signed-off-by: Dave Stevenson ---- - drivers/media/i2c/imx290.c | 119 ++++++++++++++++++++++++++++++------- - 1 file changed, 97 insertions(+), 22 deletions(-) - ---- a/drivers/media/i2c/imx290.c -+++ b/drivers/media/i2c/imx290.c -@@ -1,6 +1,10 @@ - // SPDX-License-Identifier: GPL-2.0 - /* -- * Sony IMX290 CMOS Image Sensor Driver -+ * Sony IMX290/327 CMOS Image Sensor Driver -+ * -+ * The IMX290 and IMX327 are very similar 1920x1080 1/2.8 CMOS image sensors. -+ * IMX327 can support up to 60fps, whilst IMX290 support up to 120fps (only -+ * 10bit and when connected over 4 CSI-2 lanes). - * - * Copyright (C) 2019 FRAMOS GmbH. - * -@@ -22,6 +26,11 @@ - #include - #include - -+enum imx290_clk_index { -+ CLK_37_125, -+ CLK_74_25, -+}; -+ - #define IMX290_STANDBY 0x3000 - #define IMX290_REGHOLD 0x3001 - #define IMX290_XMSTA 0x3002 -@@ -60,11 +69,16 @@ struct imx290_mode { - - const struct imx290_regval *data; - u32 data_size; -+ -+ /* Clock setup can vary. Index as enum imx290_clk_index */ -+ const struct imx290_regval *clk_data[2]; -+ u32 clk_size; - }; - - struct imx290 { - struct device *dev; - struct clk *xclk; -+ u32 xclk_freq; - struct regmap *regmap; - u8 nlanes; - u8 bpp; -@@ -116,8 +130,6 @@ static const struct imx290_regval imx290 - { 0x3018, 0x65 }, - { 0x3019, 0x04 }, - { 0x301a, 0x00 }, -- { 0x3444, 0x20 }, -- { 0x3445, 0x25 }, - { 0x303a, 0x0c }, - { 0x3040, 0x00 }, - { 0x3041, 0x00 }, -@@ -171,6 +183,30 @@ static const struct imx290_regval imx290 - { 0x33b3, 0x04 }, - }; - -+static const struct imx290_regval imx290_37_125mhz_clock_1080p[] = { -+ { 0x305c, 0x18 }, -+ { 0x305d, 0x03 }, -+ { 0x305e, 0x20 }, -+ { 0x305f, 0x01 }, -+ { 0x315e, 0x1a }, -+ { 0x3164, 0x1a }, -+ { 0x3444, 0x20 }, -+ { 0x3445, 0x25 }, -+ { 0x3480, 0x49 }, -+}; -+ -+static const struct imx290_regval imx290_74_250mhz_clock_1080p[] = { -+ { 0x305c, 0x0c }, -+ { 0x305d, 0x03 }, -+ { 0x305e, 0x10 }, -+ { 0x305f, 0x01 }, -+ { 0x315e, 0x1b }, -+ { 0x3164, 0x1b }, -+ { 0x3444, 0x40 }, -+ { 0x3445, 0x4a }, -+ { 0x3480, 0x92 }, -+}; -+ - static const struct imx290_regval imx290_1080p_settings[] = { - /* mode settings */ - { 0x3007, 0x00 }, -@@ -182,13 +218,6 @@ static const struct imx290_regval imx290 - { 0x3419, 0x04 }, - { 0x3012, 0x64 }, - { 0x3013, 0x00 }, -- { 0x305c, 0x18 }, -- { 0x305d, 0x03 }, -- { 0x305e, 0x20 }, -- { 0x305f, 0x01 }, -- { 0x315e, 0x1a }, -- { 0x3164, 0x1a }, -- { 0x3480, 0x49 }, - /* data rate settings */ - { 0x3405, 0x10 }, - { 0x3446, 0x57 }, -@@ -209,6 +238,30 @@ static const struct imx290_regval imx290 - { 0x3455, 0x00 }, - }; - -+static const struct imx290_regval imx290_37_125mhz_clock_720p[] = { -+ { 0x305c, 0x20 }, -+ { 0x305d, 0x00 }, -+ { 0x305e, 0x20 }, -+ { 0x305f, 0x01 }, -+ { 0x315e, 0x1a }, -+ { 0x3164, 0x1a }, -+ { 0x3444, 0x20 }, -+ { 0x3445, 0x25 }, -+ { 0x3480, 0x49 }, -+}; -+ -+static const struct imx290_regval imx290_74_250mhz_clock_720p[] = { -+ { 0x305c, 0x10 }, -+ { 0x305d, 0x00 }, -+ { 0x305e, 0x10 }, -+ { 0x305f, 0x01 }, -+ { 0x315e, 0x1b }, -+ { 0x3164, 0x1b }, -+ { 0x3444, 0x40 }, -+ { 0x3445, 0x4a }, -+ { 0x3480, 0x92 }, -+}; -+ - static const struct imx290_regval imx290_720p_settings[] = { - /* mode settings */ - { 0x3007, 0x10 }, -@@ -220,13 +273,6 @@ static const struct imx290_regval imx290 - { 0x3419, 0x02 }, - { 0x3012, 0x64 }, - { 0x3013, 0x00 }, -- { 0x305c, 0x20 }, -- { 0x305d, 0x00 }, -- { 0x305e, 0x20 }, -- { 0x305f, 0x01 }, -- { 0x315e, 0x1a }, -- { 0x3164, 0x1a }, -- { 0x3480, 0x49 }, - /* data rate settings */ - { 0x3405, 0x10 }, - { 0x3446, 0x4f }, -@@ -312,6 +358,11 @@ static const struct imx290_mode imx290_m - .link_freq_index = FREQ_INDEX_1080P, - .data = imx290_1080p_settings, - .data_size = ARRAY_SIZE(imx290_1080p_settings), -+ .clk_data = { -+ [CLK_37_125] = imx290_37_125mhz_clock_1080p, -+ [CLK_74_25] = imx290_74_250mhz_clock_1080p, -+ }, -+ .clk_size = ARRAY_SIZE(imx290_37_125mhz_clock_1080p), - }, - { - .width = 1280, -@@ -320,6 +371,11 @@ static const struct imx290_mode imx290_m - .link_freq_index = FREQ_INDEX_720P, - .data = imx290_720p_settings, - .data_size = ARRAY_SIZE(imx290_720p_settings), -+ .clk_data = { -+ [CLK_37_125] = imx290_37_125mhz_clock_1080p, -+ [CLK_74_25] = imx290_74_250mhz_clock_1080p, -+ }, -+ .clk_size = ARRAY_SIZE(imx290_37_125mhz_clock_1080p), - }, - }; - -@@ -331,6 +387,11 @@ static const struct imx290_mode imx290_m - .link_freq_index = FREQ_INDEX_1080P, - .data = imx290_1080p_settings, - .data_size = ARRAY_SIZE(imx290_1080p_settings), -+ .clk_data = { -+ [CLK_37_125] = imx290_37_125mhz_clock_720p, -+ [CLK_74_25] = imx290_74_250mhz_clock_720p, -+ }, -+ .clk_size = ARRAY_SIZE(imx290_37_125mhz_clock_720p), - }, - { - .width = 1280, -@@ -339,6 +400,11 @@ static const struct imx290_mode imx290_m - .link_freq_index = FREQ_INDEX_720P, - .data = imx290_720p_settings, - .data_size = ARRAY_SIZE(imx290_720p_settings), -+ .clk_data = { -+ [CLK_37_125] = imx290_37_125mhz_clock_720p, -+ [CLK_74_25] = imx290_74_250mhz_clock_720p, -+ }, -+ .clk_size = ARRAY_SIZE(imx290_37_125mhz_clock_720p), - }, - }; - -@@ -712,6 +778,8 @@ static int imx290_set_hmax(struct imx290 - /* Start streaming */ - static int imx290_start_streaming(struct imx290 *imx290) - { -+ enum imx290_clk_index clk_idx = imx290->xclk_freq == 37125000 ? -+ CLK_37_125 : CLK_74_25; - int ret; - - /* Set init register settings */ -@@ -723,6 +791,14 @@ static int imx290_start_streaming(struct - return ret; - } - -+ ret = imx290_set_register_array(imx290, -+ imx290->current_mode->clk_data[clk_idx], -+ imx290->current_mode->clk_size); -+ if (ret < 0) { -+ dev_err(imx290->dev, "Could not set clock registers\n"); -+ return ret; -+ } -+ - /* Apply the register values related to current frame format */ - ret = imx290_write_current_format(imx290); - if (ret < 0) { -@@ -935,7 +1011,6 @@ static int imx290_probe(struct i2c_clien - .bus_type = V4L2_MBUS_CSI2_DPHY - }; - struct imx290 *imx290; -- u32 xclk_freq; - s64 fq; - int ret; - -@@ -999,21 +1074,21 @@ static int imx290_probe(struct i2c_clien - } - - ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency", -- &xclk_freq); -+ &imx290->xclk_freq); - if (ret) { - dev_err(dev, "Could not get xclk frequency\n"); - goto free_err; - } - - /* external clock must be 37.125 MHz */ -- if (xclk_freq != 37125000) { -+ if (imx290->xclk_freq != 37125000 && imx290->xclk_freq != 74250000) { - dev_err(dev, "External clock frequency %u is not supported\n", -- xclk_freq); -+ imx290->xclk_freq); - ret = -EINVAL; - goto free_err; - } - -- ret = clk_set_rate(imx290->xclk, xclk_freq); -+ ret = clk_set_rate(imx290->xclk, imx290->xclk_freq); - if (ret) { - dev_err(dev, "Could not set xclk frequency\n"); - goto free_err; diff --git a/target/linux/bcm27xx/patches-5.15/950-0251-media-i2c-imx290-Correct-range-for-V4L2_CID_GAIN-to-.patch b/target/linux/bcm27xx/patches-5.15/950-0251-media-i2c-imx290-Correct-range-for-V4L2_CID_GAIN-to-.patch deleted file mode 100644 index 975194339..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0251-media-i2c-imx290-Correct-range-for-V4L2_CID_GAIN-to-.patch +++ /dev/null @@ -1,26 +0,0 @@ -From fd92c9d240a36459944a971ef3bd7fec0ebf1400 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 11 Jun 2020 13:41:43 +0100 -Subject: [PATCH] media: i2c: imx290: Correct range for V4L2_CID_GAIN - to 0-238 - -The datasheet lists the gain as being 0.0 to 72.0dB in 0.3dB steps, which -makes 238 steps total. -Correct the 0-72 range defined in the driver. - -Signed-off-by: Dave Stevenson ---- - drivers/media/i2c/imx290.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/media/i2c/imx290.c -+++ b/drivers/media/i2c/imx290.c -@@ -1120,7 +1120,7 @@ static int imx290_probe(struct i2c_clien - v4l2_ctrl_handler_init(&imx290->ctrls, 4); - - v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops, -- V4L2_CID_GAIN, 0, 72, 1, 0); -+ V4L2_CID_GAIN, 0, 238, 1, 0); - - imx290->link_freq = - v4l2_ctrl_new_int_menu(&imx290->ctrls, &imx290_ctrl_ops, diff --git a/target/linux/bcm27xx/patches-5.15/950-0252-media-i2c-imx290-Convert-HMAX-setting-into-V4L2_CID_.patch b/target/linux/bcm27xx/patches-5.15/950-0252-media-i2c-imx290-Convert-HMAX-setting-into-V4L2_CID_.patch deleted file mode 100644 index 6d21d183a..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0252-media-i2c-imx290-Convert-HMAX-setting-into-V4L2_CID_.patch +++ /dev/null @@ -1,159 +0,0 @@ -From 1ef87a70e7e946447835c8cefa0bc690c29d7ac8 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 11 Jun 2020 14:36:40 +0100 -Subject: [PATCH] media: i2c: imx290: Convert HMAX setting into - V4L2_CID_HBLANK - -Userspace needs to know HBLANK if it is to work out exposure times -and frame rates, therefore convert it to map onto V4L2_CID_HBLANK - -Signed-off-by: Dave Stevenson ---- - drivers/media/i2c/imx290.c | 66 +++++++++++++++++++++++++------------- - 1 file changed, 44 insertions(+), 22 deletions(-) - ---- a/drivers/media/i2c/imx290.c -+++ b/drivers/media/i2c/imx290.c -@@ -40,6 +40,9 @@ enum imx290_clk_index { - #define IMX290_GAIN 0x3014 - #define IMX290_HMAX_LOW 0x301c - #define IMX290_HMAX_HIGH 0x301d -+#define IMX290_HMAX_MIN_2LANE 4400 /* Min of 4400 pixels = 30fps */ -+#define IMX290_HMAX_MIN_4LANE 2200 /* Min of 2200 pixels = 60fps */ -+#define IMX290_HMAX_MAX 0xffff - #define IMX290_PGCTRL 0x308c - #define IMX290_PHY_LANE_NUM 0x3407 - #define IMX290_CSI_LANE_MODE 0x3443 -@@ -82,6 +85,7 @@ struct imx290 { - struct regmap *regmap; - u8 nlanes; - u8 bpp; -+ u16 hmax_min; - - struct v4l2_subdev sd; - struct media_pad pad; -@@ -94,6 +98,7 @@ struct imx290 { - struct v4l2_ctrl_handler ctrls; - struct v4l2_ctrl *link_freq; - struct v4l2_ctrl *pixel_rate; -+ struct v4l2_ctrl *hblank; - - struct mutex lock; - }; -@@ -518,6 +523,26 @@ static int imx290_set_gain(struct imx290 - return ret; - } - -+static int imx290_set_hmax(struct imx290 *imx290, u32 val) -+{ -+ u32 hmax = val + imx290->current_mode->width; -+ int ret; -+ -+ ret = imx290_write_reg(imx290, IMX290_HMAX_LOW, (hmax & 0xff)); -+ if (ret) { -+ dev_err(imx290->dev, "Error setting HMAX register\n"); -+ return ret; -+ } -+ -+ ret = imx290_write_reg(imx290, IMX290_HMAX_HIGH, ((hmax >> 8) & 0xff)); -+ if (ret) { -+ dev_err(imx290->dev, "Error setting HMAX register\n"); -+ return ret; -+ } -+ -+ return 0; -+} -+ - /* Stop streaming */ - static int imx290_stop_streaming(struct imx290 *imx290) - { -@@ -546,6 +571,9 @@ static int imx290_set_ctrl(struct v4l2_c - case V4L2_CID_GAIN: - ret = imx290_set_gain(imx290, ctrl->val); - break; -+ case V4L2_CID_HBLANK: -+ ret = imx290_set_hmax(imx290, ctrl->val); -+ break; - case V4L2_CID_TEST_PATTERN: - if (ctrl->val) { - imx290_write_reg(imx290, IMX290_BLKLEVEL_LOW, 0x00); -@@ -702,6 +730,12 @@ static int imx290_set_fmt(struct v4l2_su - if (imx290->pixel_rate) - __v4l2_ctrl_s_ctrl_int64(imx290->pixel_rate, - imx290_calc_pixel_rate(imx290)); -+ -+ if (imx290->hblank) -+ __v4l2_ctrl_modify_range(imx290->hblank, -+ imx290->hmax_min - mode->width, -+ IMX290_HMAX_MAX - mode->width, -+ 1, mode->hmax - mode->width); - } - - *format = fmt->format; -@@ -756,25 +790,6 @@ static int imx290_write_current_format(s - return 0; - } - --static int imx290_set_hmax(struct imx290 *imx290, u32 val) --{ -- int ret; -- -- ret = imx290_write_reg(imx290, IMX290_HMAX_LOW, (val & 0xff)); -- if (ret) { -- dev_err(imx290->dev, "Error setting HMAX register\n"); -- return ret; -- } -- -- ret = imx290_write_reg(imx290, IMX290_HMAX_HIGH, ((val >> 8) & 0xff)); -- if (ret) { -- dev_err(imx290->dev, "Error setting HMAX register\n"); -- return ret; -- } -- -- return 0; --} -- - /* Start streaming */ - static int imx290_start_streaming(struct imx290 *imx290) - { -@@ -813,9 +828,6 @@ static int imx290_start_streaming(struct - dev_err(imx290->dev, "Could not set current mode\n"); - return ret; - } -- ret = imx290_set_hmax(imx290, imx290->current_mode->hmax); -- if (ret < 0) -- return ret; - - /* Apply customized values from user */ - ret = v4l2_ctrl_handler_setup(imx290->sd.ctrl_handler); -@@ -1010,6 +1022,7 @@ static int imx290_probe(struct i2c_clien - struct v4l2_fwnode_endpoint ep = { - .bus_type = V4L2_MBUS_CSI2_DPHY - }; -+ const struct imx290_mode *mode; - struct imx290 *imx290; - s64 fq; - int ret; -@@ -1048,6 +1061,8 @@ static int imx290_probe(struct i2c_clien - ret = -EINVAL; - goto free_err; - } -+ imx290->hmax_min = (imx290->nlanes == 2) ? IMX290_HMAX_MIN_2LANE : -+ IMX290_HMAX_MIN_4LANE; - - dev_dbg(dev, "Using %u data lanes\n", imx290->nlanes); - -@@ -1122,6 +1137,13 @@ static int imx290_probe(struct i2c_clien - v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops, - V4L2_CID_GAIN, 0, 238, 1, 0); - -+ mode = imx290->current_mode; -+ imx290->hblank = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops, -+ V4L2_CID_HBLANK, -+ imx290->hmax_min - mode->width, -+ IMX290_HMAX_MAX - mode->width, 1, -+ mode->hmax - mode->width); -+ - imx290->link_freq = - v4l2_ctrl_new_int_menu(&imx290->ctrls, &imx290_ctrl_ops, - V4L2_CID_LINK_FREQ, diff --git a/target/linux/bcm27xx/patches-5.15/950-0253-media-i2c-imx290-Add-support-for-V4L2_CID_VBLANK.patch b/target/linux/bcm27xx/patches-5.15/950-0253-media-i2c-imx290-Add-support-for-V4L2_CID_VBLANK.patch deleted file mode 100644 index f54d57135..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0253-media-i2c-imx290-Add-support-for-V4L2_CID_VBLANK.patch +++ /dev/null @@ -1,141 +0,0 @@ -From 2ec876df0a1c42bb42fff3d34fdb618d42c39e43 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 11 Jun 2020 18:09:12 +0100 -Subject: [PATCH] media: i2c: imx290: Add support for V4L2_CID_VBLANK - -In order to calculate framerate and durations userspace needs -the vertical blanking information. This can be configurable, -and indeed the datasheet lists different values for VBLANK for -the 1080p and 720p modes. - -Add the new control, and adopt the datasheet values for each mode. - -Signed-off-by: Dave Stevenson ---- - drivers/media/i2c/imx290.c | 38 ++++++++++++++++++++++++++++++++++++-- - 1 file changed, 36 insertions(+), 2 deletions(-) - ---- a/drivers/media/i2c/imx290.c -+++ b/drivers/media/i2c/imx290.c -@@ -38,6 +38,8 @@ enum imx290_clk_index { - #define IMX290_BLKLEVEL_LOW 0x300a - #define IMX290_BLKLEVEL_HIGH 0x300b - #define IMX290_GAIN 0x3014 -+#define IMX290_VMAX_LOW 0x3018 -+#define IMX290_VMAX_MAX 0x3fff - #define IMX290_HMAX_LOW 0x301c - #define IMX290_HMAX_HIGH 0x301d - #define IMX290_HMAX_MIN_2LANE 4400 /* Min of 4400 pixels = 30fps */ -@@ -68,6 +70,7 @@ struct imx290_mode { - u32 width; - u32 height; - u32 hmax; -+ u32 vmax; - u8 link_freq_index; - - const struct imx290_regval *data; -@@ -99,6 +102,7 @@ struct imx290 { - struct v4l2_ctrl *link_freq; - struct v4l2_ctrl *pixel_rate; - struct v4l2_ctrl *hblank; -+ struct v4l2_ctrl *vblank; - - struct mutex lock; - }; -@@ -132,8 +136,6 @@ static const char * const imx290_test_pa - - static const struct imx290_regval imx290_global_init_settings[] = { - { 0x3007, 0x00 }, -- { 0x3018, 0x65 }, -- { 0x3019, 0x04 }, - { 0x301a, 0x00 }, - { 0x303a, 0x0c }, - { 0x3040, 0x00 }, -@@ -360,6 +362,7 @@ static const struct imx290_mode imx290_m - .width = 1920, - .height = 1080, - .hmax = 0x1130, -+ .vmax = 0x0465, - .link_freq_index = FREQ_INDEX_1080P, - .data = imx290_1080p_settings, - .data_size = ARRAY_SIZE(imx290_1080p_settings), -@@ -373,6 +376,7 @@ static const struct imx290_mode imx290_m - .width = 1280, - .height = 720, - .hmax = 0x19c8, -+ .vmax = 0x02ee, - .link_freq_index = FREQ_INDEX_720P, - .data = imx290_720p_settings, - .data_size = ARRAY_SIZE(imx290_720p_settings), -@@ -389,6 +393,7 @@ static const struct imx290_mode imx290_m - .width = 1920, - .height = 1080, - .hmax = 0x0898, -+ .vmax = 0x0465, - .link_freq_index = FREQ_INDEX_1080P, - .data = imx290_1080p_settings, - .data_size = ARRAY_SIZE(imx290_1080p_settings), -@@ -402,6 +407,7 @@ static const struct imx290_mode imx290_m - .width = 1280, - .height = 720, - .hmax = 0x0ce4, -+ .vmax = 0x02ee, - .link_freq_index = FREQ_INDEX_720P, - .data = imx290_720p_settings, - .data_size = ARRAY_SIZE(imx290_720p_settings), -@@ -543,6 +549,19 @@ static int imx290_set_hmax(struct imx290 - return 0; - } - -+static int imx290_set_vmax(struct imx290 *imx290, u32 val) -+{ -+ u32 vmax = val + imx290->current_mode->height; -+ int ret; -+ -+ ret = imx290_write_buffered_reg(imx290, IMX290_VMAX_LOW, 3, -+ vmax); -+ if (ret) -+ dev_err(imx290->dev, "Unable to write vmax\n"); -+ -+ return ret; -+} -+ - /* Stop streaming */ - static int imx290_stop_streaming(struct imx290 *imx290) - { -@@ -574,6 +593,9 @@ static int imx290_set_ctrl(struct v4l2_c - case V4L2_CID_HBLANK: - ret = imx290_set_hmax(imx290, ctrl->val); - break; -+ case V4L2_CID_VBLANK: -+ ret = imx290_set_vmax(imx290, ctrl->val); -+ break; - case V4L2_CID_TEST_PATTERN: - if (ctrl->val) { - imx290_write_reg(imx290, IMX290_BLKLEVEL_LOW, 0x00); -@@ -736,6 +758,12 @@ static int imx290_set_fmt(struct v4l2_su - imx290->hmax_min - mode->width, - IMX290_HMAX_MAX - mode->width, - 1, mode->hmax - mode->width); -+ if (imx290->vblank) -+ __v4l2_ctrl_modify_range(imx290->vblank, -+ mode->vmax - mode->height, -+ IMX290_VMAX_MAX - mode->height, -+ 1, -+ mode->vmax - mode->height); - } - - *format = fmt->format; -@@ -1144,6 +1172,12 @@ static int imx290_probe(struct i2c_clien - IMX290_HMAX_MAX - mode->width, 1, - mode->hmax - mode->width); - -+ imx290->vblank = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops, -+ V4L2_CID_VBLANK, -+ mode->vmax - mode->height, -+ IMX290_VMAX_MAX - mode->height, 1, -+ mode->vmax - mode->height); -+ - imx290->link_freq = - v4l2_ctrl_new_int_menu(&imx290->ctrls, &imx290_ctrl_ops, - V4L2_CID_LINK_FREQ, diff --git a/target/linux/bcm27xx/patches-5.15/950-0254-media-i2c-imx290-Add-exposure-control-to-the-driver.patch b/target/linux/bcm27xx/patches-5.15/950-0254-media-i2c-imx290-Add-exposure-control-to-the-driver.patch deleted file mode 100644 index 5c6185774..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0254-media-i2c-imx290-Add-exposure-control-to-the-driver.patch +++ /dev/null @@ -1,93 +0,0 @@ -From e14032e74f63afc123d631d4475b057221b2de60 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 11 Jun 2020 18:19:13 +0100 -Subject: [PATCH] media: i2c: imx290: Add exposure control to the - driver. - -Adds support for V4L2_CID_EXPOSURE so that userspace can control -the sensor exposure time. - -Signed-off-by: Dave Stevenson ---- - drivers/media/i2c/imx290.c | 35 +++++++++++++++++++++++++++++++++++ - 1 file changed, 35 insertions(+) - ---- a/drivers/media/i2c/imx290.c -+++ b/drivers/media/i2c/imx290.c -@@ -45,6 +45,10 @@ enum imx290_clk_index { - #define IMX290_HMAX_MIN_2LANE 4400 /* Min of 4400 pixels = 30fps */ - #define IMX290_HMAX_MIN_4LANE 2200 /* Min of 2200 pixels = 60fps */ - #define IMX290_HMAX_MAX 0xffff -+ -+#define IMX290_EXPOSURE_MIN 2 -+#define IMX290_EXPOSURE_STEP 1 -+#define IMX290_EXPOSURE_LOW 0x3020 - #define IMX290_PGCTRL 0x308c - #define IMX290_PHY_LANE_NUM 0x3407 - #define IMX290_CSI_LANE_MODE 0x3443 -@@ -103,6 +107,7 @@ struct imx290 { - struct v4l2_ctrl *pixel_rate; - struct v4l2_ctrl *hblank; - struct v4l2_ctrl *vblank; -+ struct v4l2_ctrl *exposure; - - struct mutex lock; - }; -@@ -529,6 +534,20 @@ static int imx290_set_gain(struct imx290 - return ret; - } - -+static int imx290_set_exposure(struct imx290 *imx290, u32 value) -+{ -+ u32 exposure = (imx290->current_mode->height + imx290->vblank->val) - -+ value; -+ int ret; -+ -+ ret = imx290_write_buffered_reg(imx290, IMX290_EXPOSURE_LOW, 3, -+ exposure); -+ if (ret) -+ dev_err(imx290->dev, "Unable to write exposure\n"); -+ -+ return ret; -+} -+ - static int imx290_set_hmax(struct imx290 *imx290, u32 val) - { - u32 hmax = val + imx290->current_mode->width; -@@ -590,6 +609,9 @@ static int imx290_set_ctrl(struct v4l2_c - case V4L2_CID_GAIN: - ret = imx290_set_gain(imx290, ctrl->val); - break; -+ case V4L2_CID_EXPOSURE: -+ ret = imx290_set_exposure(imx290, ctrl->val); -+ break; - case V4L2_CID_HBLANK: - ret = imx290_set_hmax(imx290, ctrl->val); - break; -@@ -764,6 +786,12 @@ static int imx290_set_fmt(struct v4l2_su - IMX290_VMAX_MAX - mode->height, - 1, - mode->vmax - mode->height); -+ if (imx290->exposure) -+ __v4l2_ctrl_modify_range(imx290->exposure, -+ mode->vmax - mode->height, -+ mode->vmax - 4, -+ IMX290_EXPOSURE_STEP, -+ mode->vmax - 4); - } - - *format = fmt->format; -@@ -1178,6 +1206,13 @@ static int imx290_probe(struct i2c_clien - IMX290_VMAX_MAX - mode->height, 1, - mode->vmax - mode->height); - -+ imx290->exposure = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops, -+ V4L2_CID_EXPOSURE, -+ IMX290_EXPOSURE_MIN, -+ mode->vmax - 4, -+ IMX290_EXPOSURE_STEP, -+ mode->vmax - 4); -+ - imx290->link_freq = - v4l2_ctrl_new_int_menu(&imx290->ctrls, &imx290_ctrl_ops, - V4L2_CID_LINK_FREQ, diff --git a/target/linux/bcm27xx/patches-5.15/950-0255-media-i2c-imx290-Add-H-and-V-flip-controls.patch b/target/linux/bcm27xx/patches-5.15/950-0255-media-i2c-imx290-Add-H-and-V-flip-controls.patch deleted file mode 100644 index 01bce3ce1..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0255-media-i2c-imx290-Add-H-and-V-flip-controls.patch +++ /dev/null @@ -1,83 +0,0 @@ -From e6e2b986f038f049fc02e224ad54e939318b909e Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 11 Jun 2020 18:34:16 +0100 -Subject: [PATCH] media: i2c: imx290: Add H and V flip controls - -The sensor supports horizontal and vertical flips, so support them -through V4L2_CID_HFLIP and V4L2_CID_VFLIP. - -This sensor does NOT change the Bayer order when changing the -direction of readout, therefore no special handling is required for -that. - -Signed-off-by: Dave Stevenson ---- - drivers/media/i2c/imx290.c | 22 ++++++++++++++++++++++ - 1 file changed, 22 insertions(+) - ---- a/drivers/media/i2c/imx290.c -+++ b/drivers/media/i2c/imx290.c -@@ -34,6 +34,7 @@ enum imx290_clk_index { - #define IMX290_STANDBY 0x3000 - #define IMX290_REGHOLD 0x3001 - #define IMX290_XMSTA 0x3002 -+#define IMX290_FLIP_WINMODE 0x3007 - #define IMX290_FR_FDG_SEL 0x3009 - #define IMX290_BLKLEVEL_LOW 0x300a - #define IMX290_BLKLEVEL_HIGH 0x300b -@@ -107,6 +108,8 @@ struct imx290 { - struct v4l2_ctrl *pixel_rate; - struct v4l2_ctrl *hblank; - struct v4l2_ctrl *vblank; -+ struct v4l2_ctrl *hflip; -+ struct v4l2_ctrl *vflip; - struct v4l2_ctrl *exposure; - - struct mutex lock; -@@ -600,6 +603,7 @@ static int imx290_set_ctrl(struct v4l2_c - struct imx290 *imx290 = container_of(ctrl->handler, - struct imx290, ctrls); - int ret = 0; -+ u8 val; - - /* V4L2 controls values will be applied only when power is already up */ - if (!pm_runtime_get_if_in_use(imx290->dev)) -@@ -618,6 +622,16 @@ static int imx290_set_ctrl(struct v4l2_c - case V4L2_CID_VBLANK: - ret = imx290_set_vmax(imx290, ctrl->val); - break; -+ case V4L2_CID_HFLIP: -+ case V4L2_CID_VFLIP: -+ /* WINMODE is in bits [6:4], so need to read-modify-write */ -+ ret = imx290_read_reg(imx290, IMX290_FLIP_WINMODE, &val); -+ if (ret) -+ break; -+ val &= ~0x03; -+ val |= imx290->vflip->val | (imx290->hflip->val << 1); -+ ret = imx290_write_reg(imx290, IMX290_FLIP_WINMODE, val); -+ break; - case V4L2_CID_TEST_PATTERN: - if (ctrl->val) { - imx290_write_reg(imx290, IMX290_BLKLEVEL_LOW, 0x00); -@@ -922,6 +936,9 @@ static int imx290_set_stream(struct v4l2 - imx290_stop_streaming(imx290); - pm_runtime_put(imx290->dev); - } -+ /* vflip and hflip cannot change during streaming */ -+ __v4l2_ctrl_grab(imx290->vflip, enable); -+ __v4l2_ctrl_grab(imx290->hflip, enable); - - unlock_and_return: - -@@ -1213,6 +1230,11 @@ static int imx290_probe(struct i2c_clien - IMX290_EXPOSURE_STEP, - mode->vmax - 4); - -+ imx290->hflip = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops, -+ V4L2_CID_HFLIP, 0, 1, 1, 0); -+ imx290->vflip = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops, -+ V4L2_CID_VFLIP, 0, 1, 1, 0); -+ - imx290->link_freq = - v4l2_ctrl_new_int_menu(&imx290->ctrls, &imx290_ctrl_ops, - V4L2_CID_LINK_FREQ, diff --git a/target/linux/bcm27xx/patches-5.15/950-0256-media-dt-bindings-media-i2c-Add-mono-version-to-IMX2.patch b/target/linux/bcm27xx/patches-5.15/950-0256-media-dt-bindings-media-i2c-Add-mono-version-to-IMX2.patch deleted file mode 100644 index 7d446901c..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0256-media-dt-bindings-media-i2c-Add-mono-version-to-IMX2.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 5257f480d8ca030b13bbc30b2b5c1dd58cfbbbf5 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 25 Jun 2020 16:52:14 +0100 -Subject: [PATCH] media: dt-bindings: media: i2c: Add mono version to - IMX290 bindings - -The IMX290 module is available as either monochrome or colour and -the variant is not detectable at runtime. - -Add a new compatible string for the monochrome version. - -Signed-off-by: Dave Stevenson ---- - Documentation/devicetree/bindings/media/i2c/imx290.txt | 7 ++++--- - 1 file changed, 4 insertions(+), 3 deletions(-) - ---- a/Documentation/devicetree/bindings/media/i2c/imx290.txt -+++ b/Documentation/devicetree/bindings/media/i2c/imx290.txt -@@ -1,13 +1,14 @@ - * Sony IMX290 1/2.8-Inch CMOS Image Sensor - - The Sony IMX290 is a 1/2.8-Inch CMOS Solid-state image sensor with --Square Pixel for Color Cameras. It is programmable through I2C and 4-wire --interfaces. The sensor output is available via CMOS logic parallel SDR output, -+Square Pixel for Color or Monochrome Cameras. It is programmable through I2C -+and 4-wire interfaces. -+The sensor output is available via CMOS logic parallel SDR output, - Low voltage LVDS DDR output and CSI-2 serial data output. The CSI-2 bus is the - default. No bindings have been defined for the other busses. - - Required Properties: --- compatible: Should be "sony,imx290" -+- compatible: Should be "sony,imx290", or "sony,imx290-mono" - - reg: I2C bus address of the device - - clocks: Reference to the xclk clock. - - clock-names: Should be "xclk". diff --git a/target/linux/bcm27xx/patches-5.15/950-0257-media-i2c-imx290-Add-support-for-the-mono-sensor-var.patch b/target/linux/bcm27xx/patches-5.15/950-0257-media-i2c-imx290-Add-support-for-the-mono-sensor-var.patch deleted file mode 100644 index ce0ac0d69..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0257-media-i2c-imx290-Add-support-for-the-mono-sensor-var.patch +++ /dev/null @@ -1,185 +0,0 @@ -From 1cec09c2c2f4c65350d29a0c597da6c7df5ef3bc Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 25 Jun 2020 17:03:11 +0100 -Subject: [PATCH] media : i2c: imx290: Add support for the mono sensor - variant. - -The IMX290 module is available as either mono or colour (Bayer). - -Update the driver so that it can advertise the correct mono -formats instead of the colour ones. - -Signed-off-by: Dave Stevenson ---- - drivers/media/i2c/imx290.c | 58 +++++++++++++++++++++++++++----------- - 1 file changed, 41 insertions(+), 17 deletions(-) - ---- a/drivers/media/i2c/imx290.c -+++ b/drivers/media/i2c/imx290.c -@@ -1,10 +1,12 @@ - // SPDX-License-Identifier: GPL-2.0 - /* -- * Sony IMX290/327 CMOS Image Sensor Driver -+ * Sony IMX290 & IMX327 CMOS Image Sensor Driver - * - * The IMX290 and IMX327 are very similar 1920x1080 1/2.8 CMOS image sensors. -- * IMX327 can support up to 60fps, whilst IMX290 support up to 120fps (only -- * 10bit and when connected over 4 CSI-2 lanes). -+ * IMX327 can support up to 60fps, whilst IMX290 can support up to 120fps, but -+ * only 10bit and when connected over 4 CSI-2 lanes. -+ * The modules don't appear to have a mechanism to identify whether the mono or -+ * colour variant is connected, therefore it is done via compatible string. - * - * Copyright (C) 2019 FRAMOS GmbH. - * -@@ -17,6 +19,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -95,6 +98,8 @@ struct imx290 { - u8 bpp; - u16 hmax_min; - -+ const struct imx290_pixfmt *formats; -+ - struct v4l2_subdev sd; - struct media_pad pad; - struct v4l2_mbus_framefmt current_format; -@@ -120,11 +125,18 @@ struct imx290_pixfmt { - u8 bpp; - }; - --static const struct imx290_pixfmt imx290_formats[] = { -+#define IMX290_NUM_FORMATS 2 -+ -+static const struct imx290_pixfmt imx290_colour_formats[IMX290_NUM_FORMATS] = { - { MEDIA_BUS_FMT_SRGGB10_1X10, 10 }, - { MEDIA_BUS_FMT_SRGGB12_1X12, 12 }, - }; - -+static const struct imx290_pixfmt imx290_mono_formats[IMX290_NUM_FORMATS] = { -+ { MEDIA_BUS_FMT_Y10_1X10, 10 }, -+ { MEDIA_BUS_FMT_Y12_1X12, 12 }, -+}; -+ - static const struct regmap_config imx290_regmap_config = { - .reg_bits = 16, - .val_bits = 8, -@@ -671,10 +683,12 @@ static int imx290_enum_mbus_code(struct - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_mbus_code_enum *code) - { -- if (code->index >= ARRAY_SIZE(imx290_formats)) -+ const struct imx290 *imx290 = to_imx290(sd); -+ -+ if (code->index >= IMX290_NUM_FORMATS) - return -EINVAL; - -- code->code = imx290_formats[code->index].code; -+ code->code = imx290->formats[code->index].code; - - return 0; - } -@@ -686,8 +700,8 @@ static int imx290_enum_frame_size(struct - const struct imx290 *imx290 = to_imx290(sd); - const struct imx290_mode *imx290_modes = imx290_modes_ptr(imx290); - -- if ((fse->code != imx290_formats[0].code) && -- (fse->code != imx290_formats[1].code)) -+ if (fse->code != imx290->formats[0].code && -+ fse->code != imx290->formats[1].code) - return -EINVAL; - - if (fse->index >= imx290_modes_num(imx290)) -@@ -765,14 +779,14 @@ static int imx290_set_fmt(struct v4l2_su - fmt->format.width = mode->width; - fmt->format.height = mode->height; - -- for (i = 0; i < ARRAY_SIZE(imx290_formats); i++) -- if (imx290_formats[i].code == fmt->format.code) -+ for (i = 0; i < IMX290_NUM_FORMATS; i++) -+ if (imx290->formats[i].code == fmt->format.code) - break; - -- if (i >= ARRAY_SIZE(imx290_formats)) -+ if (i >= IMX290_NUM_FORMATS) - i = 0; - -- fmt->format.code = imx290_formats[i].code; -+ fmt->format.code = imx290->formats[i].code; - fmt->format.field = V4L2_FIELD_NONE; - - if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { -@@ -780,7 +794,7 @@ static int imx290_set_fmt(struct v4l2_su - } else { - format = &imx290->current_format; - imx290->current_mode = mode; -- imx290->bpp = imx290_formats[i].bpp; -+ imx290->bpp = imx290->formats[i].bpp; - - if (imx290->link_freq) - __v4l2_ctrl_s_ctrl(imx290->link_freq, -@@ -835,6 +849,7 @@ static int imx290_write_current_format(s - - switch (imx290->current_format.code) { - case MEDIA_BUS_FMT_SRGGB10_1X10: -+ case MEDIA_BUS_FMT_Y10_1X10: - ret = imx290_set_register_array(imx290, imx290_10bit_settings, - ARRAY_SIZE( - imx290_10bit_settings)); -@@ -844,6 +859,7 @@ static int imx290_write_current_format(s - } - break; - case MEDIA_BUS_FMT_SRGGB12_1X12: -+ case MEDIA_BUS_FMT_Y12_1X12: - ret = imx290_set_register_array(imx290, imx290_12bit_settings, - ARRAY_SIZE( - imx290_12bit_settings)); -@@ -1087,6 +1103,12 @@ static s64 imx290_check_link_freqs(const - return 0; - } - -+static const struct of_device_id imx290_of_match[] = { -+ { .compatible = "sony,imx290", .data = imx290_colour_formats }, -+ { .compatible = "sony,imx290-mono", .data = imx290_mono_formats }, -+ { /* sentinel */ } -+}; -+ - static int imx290_probe(struct i2c_client *client) - { - struct device *dev = &client->dev; -@@ -1095,6 +1117,7 @@ static int imx290_probe(struct i2c_clien - struct v4l2_fwnode_endpoint ep = { - .bus_type = V4L2_MBUS_CSI2_DPHY - }; -+ const struct of_device_id *match; - const struct imx290_mode *mode; - struct imx290 *imx290; - s64 fq; -@@ -1111,6 +1134,11 @@ static int imx290_probe(struct i2c_clien - return -ENODEV; - } - -+ match = of_match_device(imx290_of_match, dev); -+ if (!match) -+ return -ENODEV; -+ imx290->formats = (const struct imx290_pixfmt *)match->data; -+ - endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(dev), NULL); - if (!endpoint) { - dev_err(dev, "Endpoint node not found\n"); -@@ -1329,10 +1357,6 @@ static int imx290_remove(struct i2c_clie - return 0; - } - --static const struct of_device_id imx290_of_match[] = { -- { .compatible = "sony,imx290" }, -- { /* sentinel */ } --}; - MODULE_DEVICE_TABLE(of, imx290_of_match); - - static struct i2c_driver imx290_i2c_driver = { diff --git a/target/linux/bcm27xx/patches-5.15/950-0258-media-i2c-imx290-Switch-set_hmax-to-use-imx290_write.patch b/target/linux/bcm27xx/patches-5.15/950-0258-media-i2c-imx290-Switch-set_hmax-to-use-imx290_write.patch deleted file mode 100644 index 86fcea690..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0258-media-i2c-imx290-Switch-set_hmax-to-use-imx290_write.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 3707b7f288db239633547399276beb3bb03830d6 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Fri, 26 Jun 2020 18:11:49 +0100 -Subject: [PATCH] media: i2c: imx290: Switch set_hmax to use - imx290_write_buffered_reg - -imx290_set_hmax was using two independent writes to set up hmax, -when all other multi-register writes were using imx290_write_buffered_reg -which claims the group hold first. - -Switch imx290_set_hmax to using imx290_write_buffered_reg too. - -Signed-off-by: Dave Stevenson ---- - drivers/media/i2c/imx290.c | 15 ++++----------- - 1 file changed, 4 insertions(+), 11 deletions(-) - ---- a/drivers/media/i2c/imx290.c -+++ b/drivers/media/i2c/imx290.c -@@ -568,19 +568,12 @@ static int imx290_set_hmax(struct imx290 - u32 hmax = val + imx290->current_mode->width; - int ret; - -- ret = imx290_write_reg(imx290, IMX290_HMAX_LOW, (hmax & 0xff)); -- if (ret) { -+ ret = imx290_write_buffered_reg(imx290, IMX290_HMAX_LOW, 2, -+ hmax); -+ if (ret) - dev_err(imx290->dev, "Error setting HMAX register\n"); -- return ret; -- } - -- ret = imx290_write_reg(imx290, IMX290_HMAX_HIGH, ((hmax >> 8) & 0xff)); -- if (ret) { -- dev_err(imx290->dev, "Error setting HMAX register\n"); -- return ret; -- } -- -- return 0; -+ return ret; - } - - static int imx290_set_vmax(struct imx290 *imx290, u32 val) diff --git a/target/linux/bcm27xx/patches-5.15/950-0266-media-i2c-imx290-Explicitly-set-v-h-blank-on-mode-ch.patch b/target/linux/bcm27xx/patches-5.15/950-0266-media-i2c-imx290-Explicitly-set-v-h-blank-on-mode-ch.patch deleted file mode 100644 index 2d8c645ef..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0266-media-i2c-imx290-Explicitly-set-v-h-blank-on-mode-ch.patch +++ /dev/null @@ -1,46 +0,0 @@ -From f77451147a60ac62a6cdbd06b14e7b292fff80d6 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 7 Jul 2020 10:31:53 +0100 -Subject: [PATCH] media: i2c: imx290: Explicitly set v&h blank on mode - change - -__v4l2_ctrl_modify_range only updates the current value should -it be invalid within the new range. That can leave modes producing -odd frame rates. - -Explicitly update the HBLANK and VBLANK values so that on mode -change we revert to the default frame rate for the mode. - -Signed-off-by: Dave Stevenson ---- - drivers/media/i2c/imx290.c | 10 ++++++++-- - 1 file changed, 8 insertions(+), 2 deletions(-) - ---- a/drivers/media/i2c/imx290.c -+++ b/drivers/media/i2c/imx290.c -@@ -796,17 +796,23 @@ static int imx290_set_fmt(struct v4l2_su - __v4l2_ctrl_s_ctrl_int64(imx290->pixel_rate, - imx290_calc_pixel_rate(imx290)); - -- if (imx290->hblank) -+ if (imx290->hblank) { - __v4l2_ctrl_modify_range(imx290->hblank, - imx290->hmax_min - mode->width, - IMX290_HMAX_MAX - mode->width, - 1, mode->hmax - mode->width); -- if (imx290->vblank) -+ __v4l2_ctrl_s_ctrl(imx290->hblank, -+ mode->hmax - mode->width); -+ } -+ if (imx290->vblank) { - __v4l2_ctrl_modify_range(imx290->vblank, - mode->vmax - mode->height, - IMX290_VMAX_MAX - mode->height, - 1, - mode->vmax - mode->height); -+ __v4l2_ctrl_s_ctrl(imx290->vblank, -+ mode->vmax - mode->height); -+ } - if (imx290->exposure) - __v4l2_ctrl_modify_range(imx290->exposure, - mode->vmax - mode->height, diff --git a/target/linux/bcm27xx/patches-5.15/950-0267-media-i2c-imx290-Add-support-for-g_selection-to-repo.patch b/target/linux/bcm27xx/patches-5.15/950-0267-media-i2c-imx290-Add-support-for-g_selection-to-repo.patch deleted file mode 100644 index d5b4317d3..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0267-media-i2c-imx290-Add-support-for-g_selection-to-repo.patch +++ /dev/null @@ -1,156 +0,0 @@ -From b1d7e2e6a94018681fe027edbe90038727c6d169 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 7 Jul 2020 11:23:48 +0100 -Subject: [PATCH] media: i2c: imx290: Add support for g_selection to - report cropping - -Userspace needs to know the cropping arrangements for each mode, -so expose this through g_selection. - -Signed-off-by: Dave Stevenson ---- - drivers/media/i2c/imx290.c | 84 ++++++++++++++++++++++++++++++++++++++ - 1 file changed, 84 insertions(+) - ---- a/drivers/media/i2c/imx290.c -+++ b/drivers/media/i2c/imx290.c -@@ -61,6 +61,13 @@ enum imx290_clk_index { - #define IMX290_PGCTRL_THRU BIT(1) - #define IMX290_PGCTRL_MODE(n) ((n) << 4) - -+#define IMX290_NATIVE_WIDTH 1945U -+#define IMX290_NATIVE_HEIGHT 1109U -+#define IMX290_PIXEL_ARRAY_LEFT 4U -+#define IMX290_PIXEL_ARRAY_TOP 12U -+#define IMX290_PIXEL_ARRAY_WIDTH 1937U -+#define IMX290_PIXEL_ARRAY_HEIGHT 1097U -+ - static const char * const imx290_supply_name[] = { - "vdda", - "vddd", -@@ -80,6 +87,7 @@ struct imx290_mode { - u32 hmax; - u32 vmax; - u8 link_freq_index; -+ struct v4l2_rect crop; - - const struct imx290_regval *data; - u32 data_size; -@@ -384,6 +392,12 @@ static const struct imx290_mode imx290_m - .hmax = 0x1130, - .vmax = 0x0465, - .link_freq_index = FREQ_INDEX_1080P, -+ .crop = { -+ .left = 4 + 8, -+ .top = 12 + 8, -+ .width = 1920, -+ .height = 1080, -+ }, - .data = imx290_1080p_settings, - .data_size = ARRAY_SIZE(imx290_1080p_settings), - .clk_data = { -@@ -398,6 +412,12 @@ static const struct imx290_mode imx290_m - .hmax = 0x19c8, - .vmax = 0x02ee, - .link_freq_index = FREQ_INDEX_720P, -+ .crop = { -+ .left = 4 + 8 + 320, -+ .top = 12 + 8 + 180, -+ .width = 1280, -+ .height = 720, -+ }, - .data = imx290_720p_settings, - .data_size = ARRAY_SIZE(imx290_720p_settings), - .clk_data = { -@@ -415,6 +435,12 @@ static const struct imx290_mode imx290_m - .hmax = 0x0898, - .vmax = 0x0465, - .link_freq_index = FREQ_INDEX_1080P, -+ .crop = { -+ .left = 4 + 8, -+ .top = 12 + 8, -+ .width = 1920, -+ .height = 1080, -+ }, - .data = imx290_1080p_settings, - .data_size = ARRAY_SIZE(imx290_1080p_settings), - .clk_data = { -@@ -429,6 +455,12 @@ static const struct imx290_mode imx290_m - .hmax = 0x0ce4, - .vmax = 0x02ee, - .link_freq_index = FREQ_INDEX_720P, -+ .crop = { -+ .left = 4 + 8 + 320, -+ .top = 12 + 8 + 180, -+ .width = 1280, -+ .height = 720, -+ }, - .data = imx290_720p_settings, - .data_size = ARRAY_SIZE(imx290_720p_settings), - .clk_data = { -@@ -875,6 +907,57 @@ static int imx290_write_current_format(s - return 0; - } - -+static const struct v4l2_rect * -+__imx290_get_pad_crop(struct imx290 *imx290, struct v4l2_subdev_pad_config *cfg, -+ unsigned int pad, enum v4l2_subdev_format_whence which) -+{ -+ switch (which) { -+ case V4L2_SUBDEV_FORMAT_TRY: -+ return v4l2_subdev_get_try_crop(&imx290->sd, cfg, pad); -+ case V4L2_SUBDEV_FORMAT_ACTIVE: -+ return &imx290->current_mode->crop; -+ } -+ -+ return NULL; -+} -+ -+static int imx290_get_selection(struct v4l2_subdev *sd, -+ struct v4l2_subdev_pad_config *cfg, -+ struct v4l2_subdev_selection *sel) -+{ -+ switch (sel->target) { -+ case V4L2_SEL_TGT_CROP: { -+ struct imx290 *imx290 = to_imx290(sd); -+ -+ mutex_lock(&imx290->lock); -+ sel->r = *__imx290_get_pad_crop(imx290, cfg, sel->pad, -+ sel->which); -+ mutex_unlock(&imx290->lock); -+ -+ return 0; -+ } -+ -+ case V4L2_SEL_TGT_NATIVE_SIZE: -+ sel->r.top = 0; -+ sel->r.left = 0; -+ sel->r.width = IMX290_NATIVE_WIDTH; -+ sel->r.height = IMX290_NATIVE_HEIGHT; -+ -+ return 0; -+ -+ case V4L2_SEL_TGT_CROP_DEFAULT: -+ case V4L2_SEL_TGT_CROP_BOUNDS: -+ sel->r.top = IMX290_PIXEL_ARRAY_TOP; -+ sel->r.left = IMX290_PIXEL_ARRAY_LEFT; -+ sel->r.width = IMX290_PIXEL_ARRAY_WIDTH; -+ sel->r.height = IMX290_PIXEL_ARRAY_HEIGHT; -+ -+ return 0; -+ } -+ -+ return -EINVAL; -+} -+ - /* Start streaming */ - static int imx290_start_streaming(struct imx290 *imx290) - { -@@ -1069,6 +1152,7 @@ static const struct v4l2_subdev_pad_ops - .enum_frame_size = imx290_enum_frame_size, - .get_fmt = imx290_get_fmt, - .set_fmt = imx290_set_fmt, -+ .get_selection = imx290_get_selection, - }; - - static const struct v4l2_subdev_ops imx290_subdev_ops = { diff --git a/target/linux/bcm27xx/patches-5.15/950-0268-media-i2c-imx290-Set-the-colorspace-fields-in-the-fo.patch b/target/linux/bcm27xx/patches-5.15/950-0268-media-i2c-imx290-Set-the-colorspace-fields-in-the-fo.patch deleted file mode 100644 index 3bde34873..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0268-media-i2c-imx290-Set-the-colorspace-fields-in-the-fo.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 011a58382464937945ad70946241aaa881b8a512 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 7 Jul 2020 11:51:26 +0100 -Subject: [PATCH] media: i2c: imx290: Set the colorspace fields in the - format - -The colorspace fields were left untouched in imx290_set_fmt -which lead to a v4l2-compliance failure. - -Signed-off-by: Dave Stevenson ---- - drivers/media/i2c/imx290.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - ---- a/drivers/media/i2c/imx290.c -+++ b/drivers/media/i2c/imx290.c -@@ -813,6 +813,14 @@ static int imx290_set_fmt(struct v4l2_su - - fmt->format.code = imx290->formats[i].code; - fmt->format.field = V4L2_FIELD_NONE; -+ fmt->format.colorspace = V4L2_COLORSPACE_SRGB; -+ fmt->format.ycbcr_enc = -+ V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->format.colorspace); -+ fmt->format.quantization = -+ V4L2_MAP_QUANTIZATION_DEFAULT(true, fmt->format.colorspace, -+ fmt->format.ycbcr_enc); -+ fmt->format.xfer_func = -+ V4L2_MAP_XFER_FUNC_DEFAULT(fmt->format.colorspace); - - if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - format = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad); diff --git a/target/linux/bcm27xx/patches-5.15/950-0275-media-bcm2835-unicam-Select-MEDIA_CONTROLLER-and-VID.patch b/target/linux/bcm27xx/patches-5.15/950-0275-media-bcm2835-unicam-Select-MEDIA_CONTROLLER-and-VID.patch deleted file mode 100644 index 2ae207442..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0275-media-bcm2835-unicam-Select-MEDIA_CONTROLLER-and-VID.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 618001e2e90c1d7311c930c0eff674fc844619f3 Mon Sep 17 00:00:00 2001 -From: Hristo Venev -Date: Wed, 19 Aug 2020 17:02:22 +0300 -Subject: [PATCH] media: bcm2835: unicam: Select MEDIA_CONTROLLER and - VIDEO_V4L2_SUBDEV_API - -That is what almost all other drivers appear to be doing. - -Signed-off-by: Hristo Venev ---- - drivers/media/platform/bcm2835/Kconfig | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - ---- a/drivers/media/platform/bcm2835/Kconfig -+++ b/drivers/media/platform/bcm2835/Kconfig -@@ -2,8 +2,10 @@ - - config VIDEO_BCM2835_UNICAM - tristate "Broadcom BCM2835 Unicam video capture driver" -- depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && MEDIA_CONTROLLER -+ depends on VIDEO_V4L2 - depends on ARCH_BCM2835 || COMPILE_TEST -+ select VIDEO_V4L2_SUBDEV_API -+ select MEDIA_CONTROLLER - select VIDEOBUF2_DMA_CONTIG - select V4L2_FWNODE - help diff --git a/target/linux/bcm27xx/patches-5.15/950-0276-staging-media-rpivid-Select-MEDIA_CONTROLLER-and-MED.patch b/target/linux/bcm27xx/patches-5.15/950-0276-staging-media-rpivid-Select-MEDIA_CONTROLLER-and-MED.patch deleted file mode 100644 index 72bd1994c..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0276-staging-media-rpivid-Select-MEDIA_CONTROLLER-and-MED.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 914098ba4c3b746211fe03085c33dcb6c8c6fa15 Mon Sep 17 00:00:00 2001 -From: Hristo Venev -Date: Wed, 19 Aug 2020 17:05:53 +0300 -Subject: [PATCH] staging: media: rpivid: Select MEDIA_CONTROLLER and - MEDIA_CONTROLLER_REQUEST_API - -MEDIA_CONTROLLER_REQUEST_API is a hidden option. If rpivid depends on it, -the user would need to first enable another driver that selects -MEDIA_CONTROLLER_REQUEST_API, and only then rpivid would become available. - -By selecting it instead of depending on it, it becomes possible to enable -rpivid without having to enable other potentially unnecessary drivers. - -Signed-off-by: Hristo Venev ---- - drivers/staging/media/rpivid/Kconfig | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/staging/media/rpivid/Kconfig -+++ b/drivers/staging/media/rpivid/Kconfig -@@ -3,9 +3,9 @@ - config VIDEO_RPIVID - tristate "Rpi H265 driver" - depends on VIDEO_DEV && VIDEO_V4L2 -- depends on MEDIA_CONTROLLER - depends on OF -- depends on MEDIA_CONTROLLER_REQUEST_API -+ select MEDIA_CONTROLLER -+ select MEDIA_CONTROLLER_REQUEST_API - select VIDEOBUF2_DMA_CONTIG - select V4L2_MEM2MEM_DEV - help diff --git a/target/linux/bcm27xx/patches-5.15/950-0279-dwc_otg-whitelist_table-is-now-productlist_table.patch b/target/linux/bcm27xx/patches-5.15/950-0279-dwc_otg-whitelist_table-is-now-productlist_table.patch deleted file mode 100644 index d3b920fdd..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0279-dwc_otg-whitelist_table-is-now-productlist_table.patch +++ /dev/null @@ -1,20 +0,0 @@ -From 1a61ef7d787f940b8ff93f054a332b4a47a512c6 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Thu, 3 Sep 2020 14:02:41 +0100 -Subject: [PATCH] dwc_otg: whitelist_table is now productlist_table - ---- - drivers/usb/core/otg_productlist.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/usb/core/otg_productlist.h -+++ b/drivers/usb/core/otg_productlist.h -@@ -139,7 +139,7 @@ static int is_targeted(struct usb_device - /* NOTE: can't use usb_match_id() since interface caches - * aren't set up yet. this is cut/paste from that code. - */ -- for (id = whitelist_table; id->match_flags; id++) { -+ for (id = productlist_table; id->match_flags; id++) { - #ifdef DEBUG - dev_dbg(&dev->dev, - "ID: V:%04x P:%04x DC:%04x SC:%04x PR:%04x \n", diff --git a/target/linux/bcm27xx/patches-5.15/950-0280-include-firmware-Add-enum-for-RPI_FIRMWARE_FRAMEBUFF.patch b/target/linux/bcm27xx/patches-5.15/950-0280-include-firmware-Add-enum-for-RPI_FIRMWARE_FRAMEBUFF.patch deleted file mode 100644 index 1ed2f6051..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0280-include-firmware-Add-enum-for-RPI_FIRMWARE_FRAMEBUFF.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 4e9a87cfa5e6d7ee2dae51872634a4bf0e33b8f3 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 3 Sep 2020 17:09:07 +0100 -Subject: [PATCH] include/firmware: Add enum for - RPI_FIRMWARE_FRAMEBUFFER_GET_DISPLAY_ID - -Used by audio and FKMS. - -Signed-off-by: Dave Stevenson ---- - include/soc/bcm2835/raspberrypi-firmware.h | 1 + - 1 file changed, 1 insertion(+) - ---- a/include/soc/bcm2835/raspberrypi-firmware.h -+++ b/include/soc/bcm2835/raspberrypi-firmware.h -@@ -113,6 +113,7 @@ enum rpi_firmware_property_tag { - RPI_FIRMWARE_FRAMEBUFFER_GET_TOUCHBUF = 0x0004000f, - RPI_FIRMWARE_FRAMEBUFFER_GET_GPIOVIRTBUF = 0x00040010, - RPI_FIRMWARE_FRAMEBUFFER_RELEASE = 0x00048001, -+ RPI_FIRMWARE_FRAMEBUFFER_GET_DISPLAY_ID = 0x00040016, - RPI_FIRMWARE_FRAMEBUFFER_SET_DISPLAY_NUM = 0x00048013, - RPI_FIRMWARE_FRAMEBUFFER_GET_NUM_DISPLAYS = 0x00040013, - RPI_FIRMWARE_FRAMEBUFFER_GET_DISPLAY_SETTINGS = 0x00040014, diff --git a/target/linux/bcm27xx/patches-5.15/950-0282-media-i2c-imx477-Add-support-for-adaptive-frame-cont.patch b/target/linux/bcm27xx/patches-5.15/950-0282-media-i2c-imx477-Add-support-for-adaptive-frame-cont.patch deleted file mode 100644 index c94213589..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0282-media-i2c-imx477-Add-support-for-adaptive-frame-cont.patch +++ /dev/null @@ -1,182 +0,0 @@ -From a189a016325250d0dd40d98ac0616f96f98b834d Mon Sep 17 00:00:00 2001 -From: Naushir Patuck -Date: Fri, 8 May 2020 09:41:17 +0100 -Subject: [PATCH] media: i2c: imx477: Add support for adaptive frame - control - -Use V4L2_CID_EXPOSURE_AUTO_PRIORITY to control if the driver should -automatically adjust the sensor frame length based on exposure time, -allowing variable frame rates and longer exposures. - -Signed-off-by: Naushir Patuck ---- - drivers/media/i2c/imx477.c | 113 +++++++++++++++++++++++++++++-------- - 1 file changed, 91 insertions(+), 22 deletions(-) - ---- a/drivers/media/i2c/imx477.c -+++ b/drivers/media/i2c/imx477.c -@@ -1082,6 +1082,8 @@ struct imx477 { - struct v4l2_ctrl *hflip; - struct v4l2_ctrl *vblank; - struct v4l2_ctrl *hblank; -+ /* This ctrl allows automatic variable framerate */ -+ struct v4l2_ctrl *exposure_auto; - - /* Current mode */ - const struct imx477_mode *mode; -@@ -1278,6 +1280,72 @@ static int imx477_open(struct v4l2_subde - return 0; - } - -+static int imx477_set_exposure(struct imx477 *imx477, unsigned int val) -+{ -+ int ret; -+ -+ ret = imx477_write_reg(imx477, IMX477_REG_EXPOSURE, -+ IMX477_REG_VALUE_16BIT, val); -+ -+ /* Setup the frame length in the case of auto framerate mode. */ -+ if (imx477->exposure_auto->val) { -+ unsigned int frame_length, frame_length_max, frame_length_min; -+ -+ frame_length_min = imx477->vblank->minimum + -+ imx477->mode->height; -+ frame_length_max = imx477->vblank->maximum + -+ imx477->mode->height; -+ frame_length = max(frame_length_min, -+ val + IMX477_EXPOSURE_OFFSET); -+ frame_length = min(frame_length_max, frame_length); -+ ret += imx477_write_reg(imx477, IMX477_REG_FRAME_LENGTH, -+ IMX477_REG_VALUE_16BIT, frame_length); -+ } -+ -+ return ret; -+} -+ -+static void imx477_adjust_exposure_range(struct imx477 *imx477, -+ struct v4l2_ctrl *ctrl) -+{ -+ int exposure_max, exposure_def; -+ -+ if (ctrl->id == V4L2_CID_VBLANK || !ctrl->val) { -+ /* -+ * Either VBLANK has been changed or auto framerate -+ * adjusting has been disabled. Honour the VBLANK limits -+ * when setting exposure. -+ */ -+ exposure_max = imx477->mode->height + imx477->vblank->val - -+ IMX477_EXPOSURE_OFFSET; -+ -+ if (ctrl->id == V4L2_CID_EXPOSURE_AUTO_PRIORITY) { -+ /* -+ * Allow VBLANK adjustments since the driver is not -+ * handling frame length control automatically. -+ */ -+ __v4l2_ctrl_grab(imx477->vblank, false); -+ } -+ } else { -+ /* -+ * Auto framerate adjusting has been enabled. VBLANK -+ * ctrl has been disabled and exposure can ramp up -+ * to the maximum allowable value. -+ */ -+ exposure_max = IMX477_EXPOSURE_MAX; -+ /* -+ * Do not allow VBLANK adjustments if the driver is -+ * handling it frame length control automatically. -+ */ -+ __v4l2_ctrl_grab(imx477->vblank, true); -+ } -+ -+ exposure_def = min(exposure_max, imx477->exposure->val); -+ __v4l2_ctrl_modify_range(imx477->exposure, imx477->exposure->minimum, -+ exposure_max, imx477->exposure->step, -+ exposure_def); -+} -+ - static int imx477_set_ctrl(struct v4l2_ctrl *ctrl) - { - struct imx477 *imx477 = -@@ -1285,17 +1353,13 @@ static int imx477_set_ctrl(struct v4l2_c - struct i2c_client *client = v4l2_get_subdevdata(&imx477->sd); - int ret = 0; - -- if (ctrl->id == V4L2_CID_VBLANK) { -- int exposure_max, exposure_def; -- -- /* Update max exposure while meeting expected vblanking */ -- exposure_max = imx477->mode->height + ctrl->val - -- IMX477_EXPOSURE_OFFSET; -- exposure_def = min(exposure_max, imx477->exposure->val); -- __v4l2_ctrl_modify_range(imx477->exposure, -- imx477->exposure->minimum, -- exposure_max, imx477->exposure->step, -- exposure_def); -+ if (ctrl->id == V4L2_CID_VBLANK || -+ ctrl->id == V4L2_CID_EXPOSURE_AUTO_PRIORITY) { -+ /* -+ * These controls may change the limits of usable exposure, -+ * so check and adjust if necessary. -+ */ -+ imx477_adjust_exposure_range(imx477, ctrl); - } - - /* -@@ -1311,8 +1375,14 @@ static int imx477_set_ctrl(struct v4l2_c - IMX477_REG_VALUE_16BIT, ctrl->val); - break; - case V4L2_CID_EXPOSURE: -- ret = imx477_write_reg(imx477, IMX477_REG_EXPOSURE, -- IMX477_REG_VALUE_16BIT, ctrl->val); -+ ret = imx477_set_exposure(imx477, ctrl->val); -+ break; -+ case V4L2_CID_EXPOSURE_AUTO_PRIORITY: -+ /* -+ * imx477_set_exposure() will recalculate the frame length -+ * to adjust the framerate to match the exposure. -+ */ -+ ret = imx477_set_exposure(imx477, imx477->exposure->val); - break; - case V4L2_CID_DIGITAL_GAIN: - ret = imx477_write_reg(imx477, IMX477_REG_DIGITAL_GAIN, -@@ -1510,9 +1580,8 @@ unsigned int imx477_get_frame_length(con - - static void imx477_set_framing_limits(struct imx477 *imx477) - { -+ unsigned int frm_length_min, frm_length_default, hblank; - const struct imx477_mode *mode = imx477->mode; -- unsigned int frm_length_min, frm_length_default; -- unsigned int exposure_max, exposure_def, hblank; - - frm_length_min = imx477_get_frame_length(mode, &mode->timeperframe_min); - frm_length_default = -@@ -1522,15 +1591,10 @@ static void imx477_set_framing_limits(st - __v4l2_ctrl_modify_range(imx477->vblank, frm_length_min - mode->height, - IMX477_FRAME_LENGTH_MAX - mode->height, - 1, frm_length_default - mode->height); -+ -+ /* Setting this will adjust the exposure limits as well. */ - __v4l2_ctrl_s_ctrl(imx477->vblank, frm_length_default - mode->height); - -- /* Update max exposure while meeting expected vblanking */ -- exposure_max = IMX477_FRAME_LENGTH_MAX - IMX477_EXPOSURE_OFFSET; -- exposure_def = frm_length_default - mode->height - -- IMX477_EXPOSURE_OFFSET; -- __v4l2_ctrl_modify_range(imx477->exposure, imx477->exposure->minimum, -- exposure_max, imx477->exposure->step, -- exposure_def); - /* - * Currently PPL is fixed to the mode specified value, so hblank - * depends on mode->width only, and is not changeable in any -@@ -1939,6 +2003,11 @@ static int imx477_init_controls(struct i - IMX477_DGTL_GAIN_MIN, IMX477_DGTL_GAIN_MAX, - IMX477_DGTL_GAIN_STEP, IMX477_DGTL_GAIN_DEFAULT); - -+ imx477->exposure_auto = -+ v4l2_ctrl_new_std(ctrl_hdlr, &imx477_ctrl_ops, -+ V4L2_CID_EXPOSURE_AUTO_PRIORITY, -+ 0, 1, 1, 0); -+ - imx477->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx477_ctrl_ops, - V4L2_CID_HFLIP, 0, 1, 1, 0); - if (imx477->hflip) diff --git a/target/linux/bcm27xx/patches-5.15/950-0283-media-i2c-imx477-Return-correct-result-on-sensor-id-.patch b/target/linux/bcm27xx/patches-5.15/950-0283-media-i2c-imx477-Return-correct-result-on-sensor-id-.patch deleted file mode 100644 index 47d490fc4..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0283-media-i2c-imx477-Return-correct-result-on-sensor-id-.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 4f6d901936f956afba1253f1fba337cf49957e2f Mon Sep 17 00:00:00 2001 -From: Naushir Patuck -Date: Tue, 19 May 2020 16:56:33 +0100 -Subject: [PATCH] media: i2c: imx477: Return correct result on sensor - id verification - -The test should return -EIO if the register read id does not match -the expected sensor id. - -Signed-off-by: Naushir Patuck ---- - drivers/media/i2c/imx477.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/media/i2c/imx477.c -+++ b/drivers/media/i2c/imx477.c -@@ -1919,7 +1919,7 @@ static int imx477_identify_module(struct - if (val != IMX477_CHIP_ID) { - dev_err(&client->dev, "chip id mismatch: %x!=%x\n", - IMX477_CHIP_ID, val); -- ret = -EINVAL; -+ return -EIO; - } - - return 0; diff --git a/target/linux/bcm27xx/patches-5.15/950-0284-media-i2c-imx477-Parse-and-register-properties.patch b/target/linux/bcm27xx/patches-5.15/950-0284-media-i2c-imx477-Parse-and-register-properties.patch deleted file mode 100644 index 55b78ea0c..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0284-media-i2c-imx477-Parse-and-register-properties.patch +++ /dev/null @@ -1,45 +0,0 @@ -From b2334a401dd6d38b2fd38e1168480dc3ec7d704e Mon Sep 17 00:00:00 2001 -From: Laurent Pinchart -Date: Sat, 4 Jul 2020 01:45:08 +0300 -Subject: [PATCH] media: i2c: imx477: Parse and register properties - -Parse device properties and register controls for them using the V4L2 -fwnode properties helpers. - -Signed-off-by: Laurent Pinchart ---- - drivers/media/i2c/imx477.c | 12 +++++++++++- - 1 file changed, 11 insertions(+), 1 deletion(-) - ---- a/drivers/media/i2c/imx477.c -+++ b/drivers/media/i2c/imx477.c -@@ -1957,11 +1957,12 @@ static int imx477_init_controls(struct i - { - struct v4l2_ctrl_handler *ctrl_hdlr; - struct i2c_client *client = v4l2_get_subdevdata(&imx477->sd); -+ struct v4l2_fwnode_device_properties props; - unsigned int i; - int ret; - - ctrl_hdlr = &imx477->ctrl_handler; -- ret = v4l2_ctrl_handler_init(ctrl_hdlr, 14); -+ ret = v4l2_ctrl_handler_init(ctrl_hdlr, 16); - if (ret) - return ret; - -@@ -2045,6 +2046,15 @@ static int imx477_init_controls(struct i - goto error; - } - -+ ret = v4l2_fwnode_device_parse(&client->dev, &props); -+ if (ret) -+ goto error; -+ -+ ret = v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, &imx477_ctrl_ops, -+ &props); -+ if (ret) -+ goto error; -+ - imx477->sd.ctrl_handler = ctrl_hdlr; - - /* Setup exposure and frame/line length limits. */ diff --git a/target/linux/bcm27xx/patches-5.15/950-0288-media-bcm2835-unicam-Retain-packing-information-on-G.patch b/target/linux/bcm27xx/patches-5.15/950-0288-media-bcm2835-unicam-Retain-packing-information-on-G.patch deleted file mode 100644 index 60b802537..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0288-media-bcm2835-unicam-Retain-packing-information-on-G.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 6f1696959ba011cda3138d0dac6ed587282606b6 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 19 May 2020 11:46:47 +0100 -Subject: [PATCH] media: bcm2835-unicam: Retain packing information on - G_FMT - -The change to retrieve the pixel format always on g_fmt didn't -check whether the native or unpacked version of the format -had been requested, and always returned the packed one. -Correct this so that the packing setting is retained whereever -possible. - -Fixes "9d59e89 media: bcm2835-unicam: Re-fetch mbus code from subdev -on a g_fmt call" - -Signed-off-by: Dave Stevenson ---- - .../media/platform/bcm2835/bcm2835-unicam.c | 19 +++++++++++++++++-- - 1 file changed, 17 insertions(+), 2 deletions(-) - ---- a/drivers/media/platform/bcm2835/bcm2835-unicam.c -+++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c -@@ -980,8 +980,23 @@ static int unicam_g_fmt_vid_cap(struct f - if (!fmt) - return -EINVAL; - -- node->fmt = fmt; -- node->v_fmt.fmt.pix.pixelformat = fmt->fourcc; -+ if (node->fmt != fmt) { -+ /* -+ * The sensor format has changed so the pixelformat needs to -+ * be updated. Try and retain the packed/unpacked choice if -+ * at all possible. -+ */ -+ if (node->fmt->repacked_fourcc == -+ node->v_fmt.fmt.pix.pixelformat) -+ /* Using the repacked format */ -+ node->v_fmt.fmt.pix.pixelformat = fmt->repacked_fourcc; -+ else -+ /* Using the native format */ -+ node->v_fmt.fmt.pix.pixelformat = fmt->fourcc; -+ -+ node->fmt = fmt; -+ } -+ - *f = node->v_fmt; - - return 0; diff --git a/target/linux/bcm27xx/patches-5.15/950-0291-rpivid_h265-Fix-width-height-typo.patch b/target/linux/bcm27xx/patches-5.15/950-0291-rpivid_h265-Fix-width-height-typo.patch deleted file mode 100644 index 8ddebeeed..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0291-rpivid_h265-Fix-width-height-typo.patch +++ /dev/null @@ -1,21 +0,0 @@ -From c8ff5702a2f40ecdd9915328a906002351c1e072 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 21 Sep 2020 14:02:44 +0100 -Subject: [PATCH] rpivid_h265: Fix width/height typo - -Signed-off-by: popcornmix ---- - drivers/staging/media/rpivid/rpivid_h265.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/staging/media/rpivid/rpivid_h265.c -+++ b/drivers/staging/media/rpivid/rpivid_h265.c -@@ -2178,7 +2178,7 @@ static int rpivid_h265_start(struct rpiv - if (w > 4096) - w = 4096; - if (h == 0) -- w = 1088; -+ h = 1088; - if (h > 4096) - h = 4096; - wxh = w * h; diff --git a/target/linux/bcm27xx/patches-5.15/950-0294-dwc_otg-initialise-sched_frame-for-periodic-QHs-that.patch b/target/linux/bcm27xx/patches-5.15/950-0294-dwc_otg-initialise-sched_frame-for-periodic-QHs-that.patch deleted file mode 100644 index 93a3b7941..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0294-dwc_otg-initialise-sched_frame-for-periodic-QHs-that.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 6c10d1142ad073622d338f20aa2e44b2d41927ce Mon Sep 17 00:00:00 2001 -From: Jonathan Bell -Date: Wed, 7 Oct 2020 15:09:29 +0100 -Subject: [PATCH] dwc_otg: initialise sched_frame for periodic QHs that - were parked - -If a periodic QH has no remaining QTDs, then it is removed from all -periodic schedules. When re-adding, initialise the sched_frame and -start_split_frame from the current value of the frame counter. - -See https://bugs.launchpad.net/raspbian/+bug/1819560 -and - https://github.com/raspberrypi/linux/issues/3883 - -Signed-off-by: Jonathan Bell ---- - drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c -@@ -689,7 +689,11 @@ int dwc_otg_hcd_qh_add(dwc_otg_hcd_t * h - &qh->qh_list_entry); - //hcd->fiq_state->kick_np_queues = 1; - } else { -+ /* If the QH wasn't in a schedule, then sched_frame is stale. */ -+ qh->sched_frame = dwc_frame_num_inc(dwc_otg_hcd_get_frame_number(hcd), -+ SCHEDULE_SLOP); - status = schedule_periodic(hcd, qh); -+ qh->start_split_frame = qh->sched_frame; - if ( !hcd->periodic_qh_count ) { - intr_mask.b.sofintr = 1; - if (fiq_enable) { diff --git a/target/linux/bcm27xx/patches-5.15/950-0305-staging-bcm2835-audio-Add-disable-headphones-flag.patch b/target/linux/bcm27xx/patches-5.15/950-0305-staging-bcm2835-audio-Add-disable-headphones-flag.patch deleted file mode 100644 index ced894d2c..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0305-staging-bcm2835-audio-Add-disable-headphones-flag.patch +++ /dev/null @@ -1,34 +0,0 @@ -From ff97c20aea1878155c3576516b689c6b3639d92a Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 26 Oct 2020 10:23:22 +0000 -Subject: [PATCH] staging: bcm2835-audio: Add disable-headphones flag - -Add a property to allow the headphone output to be disabled. Use an -integer property rather than a boolean so that an overlay can clear it. - -Signed-off-by: Phil Elwell ---- - drivers/staging/vc04_services/bcm2835-audio/bcm2835.c | 9 +++++++-- - 1 file changed, 7 insertions(+), 2 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c -@@ -381,11 +381,16 @@ static int snd_bcm2835_alsa_probe(struct - } - - if (!enable_compat_alsa) { -+ // In this mode, enable analog output by default -+ u32 disable_headphones = 0; -+ - if (!of_property_read_bool(dev->of_node, "brcm,disable-hdmi")) - set_hdmi_enables(dev); - -- // In this mode, always enable analog output -- enable_headphones = true; -+ of_property_read_u32(dev->of_node, -+ "brcm,disable-headphones", -+ &disable_headphones); -+ enable_headphones = !disable_headphones; - } else { - enable_hdmi0 = enable_hdmi; - } diff --git a/target/linux/bcm27xx/patches-5.15/950-0307-dwc_otg-Minimise-header-and-fix-build-warnings.patch b/target/linux/bcm27xx/patches-5.15/950-0307-dwc_otg-Minimise-header-and-fix-build-warnings.patch deleted file mode 100644 index 3bbfe347e..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0307-dwc_otg-Minimise-header-and-fix-build-warnings.patch +++ /dev/null @@ -1,887 +0,0 @@ -From dcc649e165ea83abb3fb441a54292fef6481a6c5 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 27 Oct 2020 09:59:49 +0000 -Subject: [PATCH] dwc_otg: Minimise header and fix build warnings - -Delete a large amount of unused declaration from "usb.h", some of which -were causing build warnings, and get the module building cleanly. - -Signed-off-by: Phil Elwell ---- - drivers/usb/host/dwc_common_port/usb.h | 664 ------------------- - drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c | 10 +- - drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 23 +- - drivers/usb/host/dwc_otg/dwc_otg_hcd_ddma.c | 3 +- - drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 8 +- - drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 4 +- - drivers/usb/host/dwc_otg/dwc_otg_pcd_intr.c | 2 +- - 7 files changed, 30 insertions(+), 684 deletions(-) - ---- a/drivers/usb/host/dwc_common_port/usb.h -+++ b/drivers/usb/host/dwc_common_port/usb.h -@@ -55,12 +55,6 @@ typedef u_int8_t uByte; - typedef u_int8_t uWord[2]; - typedef u_int8_t uDWord[4]; - --#define USETW2(w,h,l) ((w)[0] = (u_int8_t)(l), (w)[1] = (u_int8_t)(h)) --#define UCONSTW(x) { (x) & 0xff, ((x) >> 8) & 0xff } --#define UCONSTDW(x) { (x) & 0xff, ((x) >> 8) & 0xff, \ -- ((x) >> 16) & 0xff, ((x) >> 24) & 0xff } -- --#if 1 - #define UGETW(w) ((w)[0] | ((w)[1] << 8)) - #define USETW(w,v) ((w)[0] = (u_int8_t)(v), (w)[1] = (u_int8_t)((v) >> 8)) - #define UGETDW(w) ((w)[0] | ((w)[1] << 8) | ((w)[2] << 16) | ((w)[3] << 24)) -@@ -68,31 +62,6 @@ typedef u_int8_t uDWord[4]; - (w)[1] = (u_int8_t)((v) >> 8), \ - (w)[2] = (u_int8_t)((v) >> 16), \ - (w)[3] = (u_int8_t)((v) >> 24)) --#else --/* -- * On little-endian machines that can handle unanliged accesses -- * (e.g. i386) these macros can be replaced by the following. -- */ --#define UGETW(w) (*(u_int16_t *)(w)) --#define USETW(w,v) (*(u_int16_t *)(w) = (v)) --#define UGETDW(w) (*(u_int32_t *)(w)) --#define USETDW(w,v) (*(u_int32_t *)(w) = (v)) --#endif -- --/* -- * Macros for accessing UAS IU fields, which are big-endian -- */ --#define IUSETW2(w,h,l) ((w)[0] = (u_int8_t)(h), (w)[1] = (u_int8_t)(l)) --#define IUCONSTW(x) { ((x) >> 8) & 0xff, (x) & 0xff } --#define IUCONSTDW(x) { ((x) >> 24) & 0xff, ((x) >> 16) & 0xff, \ -- ((x) >> 8) & 0xff, (x) & 0xff } --#define IUGETW(w) (((w)[0] << 8) | (w)[1]) --#define IUSETW(w,v) ((w)[0] = (u_int8_t)((v) >> 8), (w)[1] = (u_int8_t)(v)) --#define IUGETDW(w) (((w)[0] << 24) | ((w)[1] << 16) | ((w)[2] << 8) | (w)[3]) --#define IUSETDW(w,v) ((w)[0] = (u_int8_t)((v) >> 24), \ -- (w)[1] = (u_int8_t)((v) >> 16), \ -- (w)[2] = (u_int8_t)((v) >> 8), \ -- (w)[3] = (u_int8_t)(v)) - - #define UPACKED __attribute__((__packed__)) - -@@ -119,29 +88,6 @@ typedef struct { - #define UT_ENDPOINT 0x02 - #define UT_OTHER 0x03 - --#define UT_READ_DEVICE (UT_READ | UT_STANDARD | UT_DEVICE) --#define UT_READ_INTERFACE (UT_READ | UT_STANDARD | UT_INTERFACE) --#define UT_READ_ENDPOINT (UT_READ | UT_STANDARD | UT_ENDPOINT) --#define UT_WRITE_DEVICE (UT_WRITE | UT_STANDARD | UT_DEVICE) --#define UT_WRITE_INTERFACE (UT_WRITE | UT_STANDARD | UT_INTERFACE) --#define UT_WRITE_ENDPOINT (UT_WRITE | UT_STANDARD | UT_ENDPOINT) --#define UT_READ_CLASS_DEVICE (UT_READ | UT_CLASS | UT_DEVICE) --#define UT_READ_CLASS_INTERFACE (UT_READ | UT_CLASS | UT_INTERFACE) --#define UT_READ_CLASS_OTHER (UT_READ | UT_CLASS | UT_OTHER) --#define UT_READ_CLASS_ENDPOINT (UT_READ | UT_CLASS | UT_ENDPOINT) --#define UT_WRITE_CLASS_DEVICE (UT_WRITE | UT_CLASS | UT_DEVICE) --#define UT_WRITE_CLASS_INTERFACE (UT_WRITE | UT_CLASS | UT_INTERFACE) --#define UT_WRITE_CLASS_OTHER (UT_WRITE | UT_CLASS | UT_OTHER) --#define UT_WRITE_CLASS_ENDPOINT (UT_WRITE | UT_CLASS | UT_ENDPOINT) --#define UT_READ_VENDOR_DEVICE (UT_READ | UT_VENDOR | UT_DEVICE) --#define UT_READ_VENDOR_INTERFACE (UT_READ | UT_VENDOR | UT_INTERFACE) --#define UT_READ_VENDOR_OTHER (UT_READ | UT_VENDOR | UT_OTHER) --#define UT_READ_VENDOR_ENDPOINT (UT_READ | UT_VENDOR | UT_ENDPOINT) --#define UT_WRITE_VENDOR_DEVICE (UT_WRITE | UT_VENDOR | UT_DEVICE) --#define UT_WRITE_VENDOR_INTERFACE (UT_WRITE | UT_VENDOR | UT_INTERFACE) --#define UT_WRITE_VENDOR_OTHER (UT_WRITE | UT_VENDOR | UT_OTHER) --#define UT_WRITE_VENDOR_ENDPOINT (UT_WRITE | UT_VENDOR | UT_ENDPOINT) -- - /* Requests */ - #define UR_GET_STATUS 0x00 - #define USTAT_STANDARD_STATUS 0x00 -@@ -243,71 +189,6 @@ typedef struct { - typedef struct { - uByte bLength; - uByte bDescriptorType; -- uByte bDescriptorSubtype; --} UPACKED usb_descriptor_t; -- --typedef struct { -- uByte bLength; -- uByte bDescriptorType; --} UPACKED usb_descriptor_header_t; -- --typedef struct { -- uByte bLength; -- uByte bDescriptorType; -- uWord bcdUSB; --#define UD_USB_2_0 0x0200 --#define UD_IS_USB2(d) (UGETW((d)->bcdUSB) >= UD_USB_2_0) -- uByte bDeviceClass; -- uByte bDeviceSubClass; -- uByte bDeviceProtocol; -- uByte bMaxPacketSize; -- /* The fields below are not part of the initial descriptor. */ -- uWord idVendor; -- uWord idProduct; -- uWord bcdDevice; -- uByte iManufacturer; -- uByte iProduct; -- uByte iSerialNumber; -- uByte bNumConfigurations; --} UPACKED usb_device_descriptor_t; --#define USB_DEVICE_DESCRIPTOR_SIZE 18 -- --typedef struct { -- uByte bLength; -- uByte bDescriptorType; -- uWord wTotalLength; -- uByte bNumInterface; -- uByte bConfigurationValue; -- uByte iConfiguration; --#define UC_ATT_ONE (1 << 7) /* must be set */ --#define UC_ATT_SELFPOWER (1 << 6) /* self powered */ --#define UC_ATT_WAKEUP (1 << 5) /* can wakeup */ --#define UC_ATT_BATTERY (1 << 4) /* battery powered */ -- uByte bmAttributes; --#define UC_BUS_POWERED 0x80 --#define UC_SELF_POWERED 0x40 --#define UC_REMOTE_WAKEUP 0x20 -- uByte bMaxPower; /* max current in 2 mA units */ --#define UC_POWER_FACTOR 2 --} UPACKED usb_config_descriptor_t; --#define USB_CONFIG_DESCRIPTOR_SIZE 9 -- --typedef struct { -- uByte bLength; -- uByte bDescriptorType; -- uByte bInterfaceNumber; -- uByte bAlternateSetting; -- uByte bNumEndpoints; -- uByte bInterfaceClass; -- uByte bInterfaceSubClass; -- uByte bInterfaceProtocol; -- uByte iInterface; --} UPACKED usb_interface_descriptor_t; --#define USB_INTERFACE_DESCRIPTOR_SIZE 9 -- --typedef struct { -- uByte bLength; -- uByte bDescriptorType; - uByte bEndpointAddress; - #define UE_GET_DIR(a) ((a) & 0x80) - #define UE_SET_DIR(a,d) ((a) | (((d)&1) << 7)) -@@ -332,27 +213,6 @@ typedef struct { - } UPACKED usb_endpoint_descriptor_t; - #define USB_ENDPOINT_DESCRIPTOR_SIZE 7 - --typedef struct ss_endpoint_companion_descriptor { -- uByte bLength; -- uByte bDescriptorType; -- uByte bMaxBurst; --#define USSE_GET_MAX_STREAMS(a) ((a) & 0x1f) --#define USSE_SET_MAX_STREAMS(a, b) ((a) | ((b) & 0x1f)) --#define USSE_GET_MAX_PACKET_NUM(a) ((a) & 0x03) --#define USSE_SET_MAX_PACKET_NUM(a, b) ((a) | ((b) & 0x03)) -- uByte bmAttributes; -- uWord wBytesPerInterval; --} UPACKED ss_endpoint_companion_descriptor_t; --#define USB_SS_ENDPOINT_COMPANION_DESCRIPTOR_SIZE 6 -- --typedef struct { -- uByte bLength; -- uByte bDescriptorType; -- uWord bString[127]; --} UPACKED usb_string_descriptor_t; --#define USB_MAX_STRING_LEN 128 --#define USB_LANGUAGE_TABLE 0 /* # of the string language id table */ -- - /* Hub specific request */ - #define UR_GET_BUS_STATE 0x02 - #define UR_CLEAR_TT_BUFFER 0x08 -@@ -411,530 +271,6 @@ typedef struct { - } UPACKED usb_hub_descriptor_t; - #define USB_HUB_DESCRIPTOR_SIZE 9 /* includes deprecated PortPowerCtrlMask */ - --typedef struct { -- uByte bLength; -- uByte bDescriptorType; -- uWord bcdUSB; -- uByte bDeviceClass; -- uByte bDeviceSubClass; -- uByte bDeviceProtocol; -- uByte bMaxPacketSize0; -- uByte bNumConfigurations; -- uByte bReserved; --} UPACKED usb_device_qualifier_t; --#define USB_DEVICE_QUALIFIER_SIZE 10 -- --typedef struct { -- uByte bLength; -- uByte bDescriptorType; -- uByte bmAttributes; --#define UOTG_SRP 0x01 --#define UOTG_HNP 0x02 --} UPACKED usb_otg_descriptor_t; -- --/* OTG feature selectors */ --#define UOTG_B_HNP_ENABLE 3 --#define UOTG_A_HNP_SUPPORT 4 --#define UOTG_A_ALT_HNP_SUPPORT 5 -- --typedef struct { -- uWord wStatus; --/* Device status flags */ --#define UDS_SELF_POWERED 0x0001 --#define UDS_REMOTE_WAKEUP 0x0002 --/* Endpoint status flags */ --#define UES_HALT 0x0001 --} UPACKED usb_status_t; -- --typedef struct { -- uWord wHubStatus; --#define UHS_LOCAL_POWER 0x0001 --#define UHS_OVER_CURRENT 0x0002 -- uWord wHubChange; --} UPACKED usb_hub_status_t; -- --typedef struct { -- uWord wPortStatus; --#define UPS_CURRENT_CONNECT_STATUS 0x0001 --#define UPS_PORT_ENABLED 0x0002 --#define UPS_SUSPEND 0x0004 --#define UPS_OVERCURRENT_INDICATOR 0x0008 --#define UPS_RESET 0x0010 --#define UPS_PORT_POWER 0x0100 --#define UPS_LOW_SPEED 0x0200 --#define UPS_HIGH_SPEED 0x0400 --#define UPS_PORT_TEST 0x0800 --#define UPS_PORT_INDICATOR 0x1000 -- uWord wPortChange; --#define UPS_C_CONNECT_STATUS 0x0001 --#define UPS_C_PORT_ENABLED 0x0002 --#define UPS_C_SUSPEND 0x0004 --#define UPS_C_OVERCURRENT_INDICATOR 0x0008 --#define UPS_C_PORT_RESET 0x0010 --} UPACKED usb_port_status_t; -- --#ifdef _MSC_VER --#include --#endif -- --/* Device class codes */ --#define UDCLASS_IN_INTERFACE 0x00 --#define UDCLASS_COMM 0x02 --#define UDCLASS_HUB 0x09 --#define UDSUBCLASS_HUB 0x00 --#define UDPROTO_FSHUB 0x00 --#define UDPROTO_HSHUBSTT 0x01 --#define UDPROTO_HSHUBMTT 0x02 --#define UDCLASS_DIAGNOSTIC 0xdc --#define UDCLASS_WIRELESS 0xe0 --#define UDSUBCLASS_RF 0x01 --#define UDPROTO_BLUETOOTH 0x01 --#define UDCLASS_VENDOR 0xff -- --/* Interface class codes */ --#define UICLASS_UNSPEC 0x00 -- --#define UICLASS_AUDIO 0x01 --#define UISUBCLASS_AUDIOCONTROL 1 --#define UISUBCLASS_AUDIOSTREAM 2 --#define UISUBCLASS_MIDISTREAM 3 -- --#define UICLASS_CDC 0x02 /* communication */ --#define UISUBCLASS_DIRECT_LINE_CONTROL_MODEL 1 --#define UISUBCLASS_ABSTRACT_CONTROL_MODEL 2 --#define UISUBCLASS_TELEPHONE_CONTROL_MODEL 3 --#define UISUBCLASS_MULTICHANNEL_CONTROL_MODEL 4 --#define UISUBCLASS_CAPI_CONTROLMODEL 5 --#define UISUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL 6 --#define UISUBCLASS_ATM_NETWORKING_CONTROL_MODEL 7 --#define UIPROTO_CDC_AT 1 -- --#define UICLASS_HID 0x03 --#define UISUBCLASS_BOOT 1 --#define UIPROTO_BOOT_KEYBOARD 1 -- --#define UICLASS_PHYSICAL 0x05 -- --#define UICLASS_IMAGE 0x06 -- --#define UICLASS_PRINTER 0x07 --#define UISUBCLASS_PRINTER 1 --#define UIPROTO_PRINTER_UNI 1 --#define UIPROTO_PRINTER_BI 2 --#define UIPROTO_PRINTER_1284 3 -- --#define UICLASS_MASS 0x08 --#define UISUBCLASS_RBC 1 --#define UISUBCLASS_SFF8020I 2 --#define UISUBCLASS_QIC157 3 --#define UISUBCLASS_UFI 4 --#define UISUBCLASS_SFF8070I 5 --#define UISUBCLASS_SCSI 6 --#define UIPROTO_MASS_CBI_I 0 --#define UIPROTO_MASS_CBI 1 --#define UIPROTO_MASS_BBB_OLD 2 /* Not in the spec anymore */ --#define UIPROTO_MASS_BBB 80 /* 'P' for the Iomega Zip drive */ -- --#define UICLASS_HUB 0x09 --#define UISUBCLASS_HUB 0 --#define UIPROTO_FSHUB 0 --#define UIPROTO_HSHUBSTT 0 /* Yes, same as previous */ --#define UIPROTO_HSHUBMTT 1 -- --#define UICLASS_CDC_DATA 0x0a --#define UISUBCLASS_DATA 0 --#define UIPROTO_DATA_ISDNBRI 0x30 /* Physical iface */ --#define UIPROTO_DATA_HDLC 0x31 /* HDLC */ --#define UIPROTO_DATA_TRANSPARENT 0x32 /* Transparent */ --#define UIPROTO_DATA_Q921M 0x50 /* Management for Q921 */ --#define UIPROTO_DATA_Q921 0x51 /* Data for Q921 */ --#define UIPROTO_DATA_Q921TM 0x52 /* TEI multiplexer for Q921 */ --#define UIPROTO_DATA_V42BIS 0x90 /* Data compression */ --#define UIPROTO_DATA_Q931 0x91 /* Euro-ISDN */ --#define UIPROTO_DATA_V120 0x92 /* V.24 rate adaption */ --#define UIPROTO_DATA_CAPI 0x93 /* CAPI 2.0 commands */ --#define UIPROTO_DATA_HOST_BASED 0xfd /* Host based driver */ --#define UIPROTO_DATA_PUF 0xfe /* see Prot. Unit Func. Desc.*/ --#define UIPROTO_DATA_VENDOR 0xff /* Vendor specific */ -- --#define UICLASS_SMARTCARD 0x0b -- --/*#define UICLASS_FIRM_UPD 0x0c*/ -- --#define UICLASS_SECURITY 0x0d -- --#define UICLASS_DIAGNOSTIC 0xdc -- --#define UICLASS_WIRELESS 0xe0 --#define UISUBCLASS_RF 0x01 --#define UIPROTO_BLUETOOTH 0x01 -- --#define UICLASS_APPL_SPEC 0xfe --#define UISUBCLASS_FIRMWARE_DOWNLOAD 1 --#define UISUBCLASS_IRDA 2 --#define UIPROTO_IRDA 0 -- --#define UICLASS_VENDOR 0xff -- --#define USB_HUB_MAX_DEPTH 5 -- --/* -- * Minimum time a device needs to be powered down to go through -- * a power cycle. XXX Are these time in the spec? -- */ --#define USB_POWER_DOWN_TIME 200 /* ms */ --#define USB_PORT_POWER_DOWN_TIME 100 /* ms */ -- --#if 0 --/* These are the values from the spec. */ --#define USB_PORT_RESET_DELAY 10 /* ms */ --#define USB_PORT_ROOT_RESET_DELAY 50 /* ms */ --#define USB_PORT_RESET_RECOVERY 10 /* ms */ --#define USB_PORT_POWERUP_DELAY 100 /* ms */ --#define USB_SET_ADDRESS_SETTLE 2 /* ms */ --#define USB_RESUME_DELAY (20*5) /* ms */ --#define USB_RESUME_WAIT 10 /* ms */ --#define USB_RESUME_RECOVERY 10 /* ms */ --#define USB_EXTRA_POWER_UP_TIME 0 /* ms */ --#else --/* Allow for marginal (i.e. non-conforming) devices. */ --#define USB_PORT_RESET_DELAY 50 /* ms */ --#define USB_PORT_ROOT_RESET_DELAY 250 /* ms */ --#define USB_PORT_RESET_RECOVERY 250 /* ms */ --#define USB_PORT_POWERUP_DELAY 300 /* ms */ --#define USB_SET_ADDRESS_SETTLE 10 /* ms */ --#define USB_RESUME_DELAY (50*5) /* ms */ --#define USB_RESUME_WAIT 50 /* ms */ --#define USB_RESUME_RECOVERY 50 /* ms */ --#define USB_EXTRA_POWER_UP_TIME 20 /* ms */ --#endif -- --#define USB_MIN_POWER 100 /* mA */ --#define USB_MAX_POWER 500 /* mA */ -- --#define USB_BUS_RESET_DELAY 100 /* ms XXX?*/ -- --#define USB_UNCONFIG_NO 0 --#define USB_UNCONFIG_INDEX (-1) -- --/*** ioctl() related stuff ***/ -- --struct usb_ctl_request { -- int ucr_addr; -- usb_device_request_t ucr_request; -- void *ucr_data; -- int ucr_flags; --#define USBD_SHORT_XFER_OK 0x04 /* allow short reads */ -- int ucr_actlen; /* actual length transferred */ --}; -- --struct usb_alt_interface { -- int uai_config_index; -- int uai_interface_index; -- int uai_alt_no; --}; -- --#define USB_CURRENT_CONFIG_INDEX (-1) --#define USB_CURRENT_ALT_INDEX (-1) -- --struct usb_config_desc { -- int ucd_config_index; -- usb_config_descriptor_t ucd_desc; --}; -- --struct usb_interface_desc { -- int uid_config_index; -- int uid_interface_index; -- int uid_alt_index; -- usb_interface_descriptor_t uid_desc; --}; -- --struct usb_endpoint_desc { -- int ued_config_index; -- int ued_interface_index; -- int ued_alt_index; -- int ued_endpoint_index; -- usb_endpoint_descriptor_t ued_desc; --}; -- --struct usb_full_desc { -- int ufd_config_index; -- u_int ufd_size; -- u_char *ufd_data; --}; -- --struct usb_string_desc { -- int usd_string_index; -- int usd_language_id; -- usb_string_descriptor_t usd_desc; --}; -- --struct usb_ctl_report_desc { -- int ucrd_size; -- u_char ucrd_data[1024]; /* filled data size will vary */ --}; -- --typedef struct { u_int32_t cookie; } usb_event_cookie_t; -- --#define USB_MAX_DEVNAMES 4 --#define USB_MAX_DEVNAMELEN 16 --struct usb_device_info { -- u_int8_t udi_bus; -- u_int8_t udi_addr; /* device address */ -- usb_event_cookie_t udi_cookie; -- char udi_product[USB_MAX_STRING_LEN]; -- char udi_vendor[USB_MAX_STRING_LEN]; -- char udi_release[8]; -- u_int16_t udi_productNo; -- u_int16_t udi_vendorNo; -- u_int16_t udi_releaseNo; -- u_int8_t udi_class; -- u_int8_t udi_subclass; -- u_int8_t udi_protocol; -- u_int8_t udi_config; -- u_int8_t udi_speed; --#define USB_SPEED_UNKNOWN 0 --#define USB_SPEED_LOW 1 --#define USB_SPEED_FULL 2 --#define USB_SPEED_HIGH 3 --#define USB_SPEED_VARIABLE 4 --#define USB_SPEED_SUPER 5 -- int udi_power; /* power consumption in mA, 0 if selfpowered */ -- int udi_nports; -- char udi_devnames[USB_MAX_DEVNAMES][USB_MAX_DEVNAMELEN]; -- u_int8_t udi_ports[16];/* hub only: addresses of devices on ports */ --#define USB_PORT_ENABLED 0xff --#define USB_PORT_SUSPENDED 0xfe --#define USB_PORT_POWERED 0xfd --#define USB_PORT_DISABLED 0xfc --}; -- --struct usb_ctl_report { -- int ucr_report; -- u_char ucr_data[1024]; /* filled data size will vary */ --}; -- --struct usb_device_stats { -- u_long uds_requests[4]; /* indexed by transfer type UE_* */ --}; -- --#define WUSB_MIN_IE 0x80 --#define WUSB_WCTA_IE 0x80 --#define WUSB_WCONNECTACK_IE 0x81 --#define WUSB_WHOSTINFO_IE 0x82 --#define WUHI_GET_CA(_bmAttributes_) ((_bmAttributes_) & 0x3) --#define WUHI_CA_RECONN 0x00 --#define WUHI_CA_LIMITED 0x01 --#define WUHI_CA_ALL 0x03 --#define WUHI_GET_MLSI(_bmAttributes_) (((_bmAttributes_) & 0x38) >> 3) --#define WUSB_WCHCHANGEANNOUNCE_IE 0x83 --#define WUSB_WDEV_DISCONNECT_IE 0x84 --#define WUSB_WHOST_DISCONNECT_IE 0x85 --#define WUSB_WRELEASE_CHANNEL_IE 0x86 --#define WUSB_WWORK_IE 0x87 --#define WUSB_WCHANNEL_STOP_IE 0x88 --#define WUSB_WDEV_KEEPALIVE_IE 0x89 --#define WUSB_WISOCH_DISCARD_IE 0x8A --#define WUSB_WRESETDEVICE_IE 0x8B --#define WUSB_WXMIT_PACKET_ADJUST_IE 0x8C --#define WUSB_MAX_IE 0x8C -- --/* Device Notification Types */ -- --#define WUSB_DN_MIN 0x01 --#define WUSB_DN_CONNECT 0x01 --# define WUSB_DA_OLDCONN 0x00 --# define WUSB_DA_NEWCONN 0x01 --# define WUSB_DA_SELF_BEACON 0x02 --# define WUSB_DA_DIR_BEACON 0x04 --# define WUSB_DA_NO_BEACON 0x06 --#define WUSB_DN_DISCONNECT 0x02 --#define WUSB_DN_EPRDY 0x03 --#define WUSB_DN_MASAVAILCHANGED 0x04 --#define WUSB_DN_REMOTEWAKEUP 0x05 --#define WUSB_DN_SLEEP 0x06 --#define WUSB_DN_ALIVE 0x07 --#define WUSB_DN_MAX 0x07 -- --#ifdef _MSC_VER --#include --#endif -- --/* WUSB Handshake Data. Used during the SET/GET HANDSHAKE requests */ --typedef struct wusb_hndshk_data { -- uByte bMessageNumber; -- uByte bStatus; -- uByte tTKID[3]; -- uByte bReserved; -- uByte CDID[16]; -- uByte Nonce[16]; -- uByte MIC[8]; --} UPACKED wusb_hndshk_data_t; --#define WUSB_HANDSHAKE_LEN_FOR_MIC 38 -- --/* WUSB Connection Context */ --typedef struct wusb_conn_context { -- uByte CHID [16]; -- uByte CDID [16]; -- uByte CK [16]; --} UPACKED wusb_conn_context_t; -- --/* WUSB Security Descriptor */ --typedef struct wusb_security_desc { -- uByte bLength; -- uByte bDescriptorType; -- uWord wTotalLength; -- uByte bNumEncryptionTypes; --} UPACKED wusb_security_desc_t; -- --/* WUSB Encryption Type Descriptor */ --typedef struct wusb_encrypt_type_desc { -- uByte bLength; -- uByte bDescriptorType; -- -- uByte bEncryptionType; --#define WUETD_UNSECURE 0 --#define WUETD_WIRED 1 --#define WUETD_CCM_1 2 --#define WUETD_RSA_1 3 -- -- uByte bEncryptionValue; -- uByte bAuthKeyIndex; --} UPACKED wusb_encrypt_type_desc_t; -- --/* WUSB Key Descriptor */ --typedef struct wusb_key_desc { -- uByte bLength; -- uByte bDescriptorType; -- uByte tTKID[3]; -- uByte bReserved; -- uByte KeyData[1]; /* variable length */ --} UPACKED wusb_key_desc_t; -- --/* WUSB BOS Descriptor (Binary device Object Store) */ --typedef struct wusb_bos_desc { -- uByte bLength; -- uByte bDescriptorType; -- uWord wTotalLength; -- uByte bNumDeviceCaps; --} UPACKED wusb_bos_desc_t; -- --#define USB_DEVICE_CAPABILITY_20_EXTENSION 0x02 --typedef struct usb_dev_cap_20_ext_desc { -- uByte bLength; -- uByte bDescriptorType; -- uByte bDevCapabilityType; --#define USB_20_EXT_LPM 0x02 -- uDWord bmAttributes; --} UPACKED usb_dev_cap_20_ext_desc_t; -- --#define USB_DEVICE_CAPABILITY_SS_USB 0x03 --typedef struct usb_dev_cap_ss_usb { -- uByte bLength; -- uByte bDescriptorType; -- uByte bDevCapabilityType; --#define USB_DC_SS_USB_LTM_CAPABLE 0x02 -- uByte bmAttributes; --#define USB_DC_SS_USB_SPEED_SUPPORT_LOW 0x01 --#define USB_DC_SS_USB_SPEED_SUPPORT_FULL 0x02 --#define USB_DC_SS_USB_SPEED_SUPPORT_HIGH 0x04 --#define USB_DC_SS_USB_SPEED_SUPPORT_SS 0x08 -- uWord wSpeedsSupported; -- uByte bFunctionalitySupport; -- uByte bU1DevExitLat; -- uWord wU2DevExitLat; --} UPACKED usb_dev_cap_ss_usb_t; -- --#define USB_DEVICE_CAPABILITY_CONTAINER_ID 0x04 --typedef struct usb_dev_cap_container_id { -- uByte bLength; -- uByte bDescriptorType; -- uByte bDevCapabilityType; -- uByte bReserved; -- uByte containerID[16]; --} UPACKED usb_dev_cap_container_id_t; -- --/* Device Capability Type Codes */ --#define WUSB_DEVICE_CAPABILITY_WIRELESS_USB 0x01 -- --/* Device Capability Descriptor */ --typedef struct wusb_dev_cap_desc { -- uByte bLength; -- uByte bDescriptorType; -- uByte bDevCapabilityType; -- uByte caps[1]; /* Variable length */ --} UPACKED wusb_dev_cap_desc_t; -- --/* Device Capability Descriptor */ --typedef struct wusb_dev_cap_uwb_desc { -- uByte bLength; -- uByte bDescriptorType; -- uByte bDevCapabilityType; -- uByte bmAttributes; -- uWord wPHYRates; /* Bitmap */ -- uByte bmTFITXPowerInfo; -- uByte bmFFITXPowerInfo; -- uWord bmBandGroup; -- uByte bReserved; --} UPACKED wusb_dev_cap_uwb_desc_t; -- --/* Wireless USB Endpoint Companion Descriptor */ --typedef struct wusb_endpoint_companion_desc { -- uByte bLength; -- uByte bDescriptorType; -- uByte bMaxBurst; -- uByte bMaxSequence; -- uWord wMaxStreamDelay; -- uWord wOverTheAirPacketSize; -- uByte bOverTheAirInterval; -- uByte bmCompAttributes; --} UPACKED wusb_endpoint_companion_desc_t; -- --/* Wireless USB Numeric Association M1 Data Structure */ --typedef struct wusb_m1_data { -- uByte version; -- uWord langId; -- uByte deviceFriendlyNameLength; -- uByte sha_256_m3[32]; -- uByte deviceFriendlyName[256]; --} UPACKED wusb_m1_data_t; -- --typedef struct wusb_m2_data { -- uByte version; -- uWord langId; -- uByte hostFriendlyNameLength; -- uByte pkh[384]; -- uByte hostFriendlyName[256]; --} UPACKED wusb_m2_data_t; -- --typedef struct wusb_m3_data { -- uByte pkd[384]; -- uByte nd; --} UPACKED wusb_m3_data_t; -- --typedef struct wusb_m4_data { -- uDWord _attributeTypeIdAndLength_1; -- uWord associationTypeId; -- -- uDWord _attributeTypeIdAndLength_2; -- uWord associationSubTypeId; -- -- uDWord _attributeTypeIdAndLength_3; -- uDWord length; -- -- uDWord _attributeTypeIdAndLength_4; -- uDWord associationStatus; -- -- uDWord _attributeTypeIdAndLength_5; -- uByte chid[16]; -- -- uDWord _attributeTypeIdAndLength_6; -- uByte cdid[16]; -- -- uDWord _attributeTypeIdAndLength_7; -- uByte bandGroups[2]; --} UPACKED wusb_m4_data_t; -- - #ifdef _MSC_VER - #include - #endif ---- a/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c -@@ -240,7 +240,8 @@ static int notrace fiq_increment_dma_buf - hcdma_data_t hcdma; - int i = st->channel[n].dma_info.index; - int len; -- struct fiq_dma_blob *blob = (struct fiq_dma_blob *) st->dma_base; -+ struct fiq_dma_blob *blob = -+ (struct fiq_dma_blob *)(uintptr_t)st->dma_base; - - len = fiq_get_xfer_len(st, n); - fiq_print(FIQDBG_INT, st, "LEN: %03d", len); -@@ -249,7 +250,7 @@ static int notrace fiq_increment_dma_buf - if (i > 6) - BUG(); - -- hcdma.d32 = (dma_addr_t) &blob->channel[n].index[i].buf[0]; -+ hcdma.d32 = (u32)(uintptr_t)&blob->channel[n].index[i].buf[0]; - FIQ_WRITE(st->dwc_regs_base + HC_START + (HC_OFFSET * n) + HC_DMA, hcdma.d32); - st->channel[n].dma_info.index = i; - return 0; -@@ -289,7 +290,8 @@ static int notrace fiq_iso_out_advance(s - hcsplt_data_t hcsplt; - hctsiz_data_t hctsiz; - hcdma_data_t hcdma; -- struct fiq_dma_blob *blob = (struct fiq_dma_blob *) st->dma_base; -+ struct fiq_dma_blob *blob = -+ (struct fiq_dma_blob *)(uintptr_t)st->dma_base; - int last = 0; - int i = st->channel[n].dma_info.index; - -@@ -301,7 +303,7 @@ static int notrace fiq_iso_out_advance(s - last = 1; - - /* New DMA address - address of bounce buffer referred to in index */ -- hcdma.d32 = (dma_addr_t) blob->channel[n].index[i].buf; -+ hcdma.d32 = (u32)(uintptr_t)blob->channel[n].index[i].buf; - //hcdma.d32 = FIQ_READ(st->dwc_regs_base + HC_START + (HC_OFFSET * n) + HC_DMA); - //hcdma.d32 += st->channel[n].dma_info.slot_len[i]; - fiq_print(FIQDBG_INT, st, "LAST: %01d ", last); ---- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c -@@ -1270,7 +1270,8 @@ static void assign_and_init_hc(dwc_otg_h - hc->multi_count = 1; - - if (hcd->core_if->dma_enable) { -- hc->xfer_buff = (uint8_t *) urb->dma + urb->actual_length; -+ hc->xfer_buff = -+ (uint8_t *)(uintptr_t)urb->dma + urb->actual_length; - - /* For non-dword aligned case */ - if (((unsigned long)hc->xfer_buff & 0x3) -@@ -1314,7 +1315,8 @@ static void assign_and_init_hc(dwc_otg_h - hc->ep_is_in = 0; - hc->data_pid_start = DWC_OTG_HC_PID_SETUP; - if (hcd->core_if->dma_enable) { -- hc->xfer_buff = (uint8_t *) urb->setup_dma; -+ hc->xfer_buff = -+ (uint8_t *)(uintptr_t)urb->setup_dma; - } else { - hc->xfer_buff = (uint8_t *) urb->setup_packet; - } -@@ -1362,7 +1364,8 @@ static void assign_and_init_hc(dwc_otg_h - - hc->xfer_len = 0; - if (hcd->core_if->dma_enable) { -- hc->xfer_buff = (uint8_t *) hcd->status_buf_dma; -+ hc->xfer_buff = (uint8_t *) -+ (uintptr_t)hcd->status_buf_dma; - } else { - hc->xfer_buff = (uint8_t *) hcd->status_buf; - } -@@ -1390,7 +1393,7 @@ static void assign_and_init_hc(dwc_otg_h - frame_desc->status = 0; - - if (hcd->core_if->dma_enable) { -- hc->xfer_buff = (uint8_t *) urb->dma; -+ hc->xfer_buff = (uint8_t *)(uintptr_t)urb->dma; - } else { - hc->xfer_buff = (uint8_t *) urb->buf; - } -@@ -1571,8 +1574,10 @@ int fiq_fsm_setup_periodic_dma(dwc_otg_h - * Pointer arithmetic on hcd->fiq_state->dma_base (a dma_addr_t) - * to point it to the correct offset in the allocated buffers. - */ -- blob = (struct fiq_dma_blob *) hcd->fiq_state->dma_base; -- st->hcdma_copy.d32 = (dma_addr_t) blob->channel[hc->hc_num].index[0].buf; -+ blob = (struct fiq_dma_blob *) -+ (uintptr_t)hcd->fiq_state->dma_base; -+ st->hcdma_copy.d32 =(u32)(uintptr_t) -+ blob->channel[hc->hc_num].index[0].buf; - - /* Calculate the max number of CSPLITS such that the FIQ can time out - * a transaction if it fails. -@@ -1627,8 +1632,10 @@ int fiq_fsm_setup_periodic_dma(dwc_otg_h - * dma_addr_t) to point it to the correct offset in the - * allocated buffers. - */ -- blob = (struct fiq_dma_blob *) hcd->fiq_state->dma_base; -- st->hcdma_copy.d32 = (dma_addr_t) blob->channel[hc->hc_num].index[0].buf; -+ blob = (struct fiq_dma_blob *) -+ (uintptr_t)hcd->fiq_state->dma_base; -+ st->hcdma_copy.d32 = (u32)(uintptr_t) -+ blob->channel[hc->hc_num].index[0].buf; - - /* fixup xfersize to the actual packet size */ - st->hctsiz_copy.b.pid = 0; ---- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_ddma.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_ddma.c -@@ -620,7 +620,8 @@ static void init_non_isoc_dma_desc(dwc_o - - if (n_desc) { - /* SG request - more than 1 QTDs */ -- hc->xfer_buff = (uint8_t *)qtd->urb->dma + qtd->urb->actual_length; -+ hc->xfer_buff = (uint8_t *)(uintptr_t)qtd->urb->dma + -+ qtd->urb->actual_length; - hc->xfer_len = qtd->urb->length - qtd->urb->actual_length; - } - ---- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c -@@ -1857,10 +1857,10 @@ static int32_t handle_hc_ahberr_intr(dwc - DWC_ERROR(" Max packet size: %d\n", - dwc_otg_hcd_get_mps(&urb->pipe_info)); - DWC_ERROR(" Data buffer length: %d\n", urb->length); -- DWC_ERROR(" Transfer buffer: %p, Transfer DMA: %p\n", -- urb->buf, (void *)urb->dma); -- DWC_ERROR(" Setup buffer: %p, Setup DMA: %p\n", -- urb->setup_packet, (void *)urb->setup_dma); -+ DWC_ERROR(" Transfer buffer: %p, Transfer DMA: %pad\n", -+ urb->buf, &urb->dma); -+ DWC_ERROR(" Setup buffer: %p, Setup DMA: %pad\n", -+ urb->setup_packet, &urb->setup_dma); - DWC_ERROR(" Interval: %d\n", urb->interval); - - /* Core haltes the channel for Descriptor DMA mode */ ---- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c -@@ -482,8 +482,8 @@ static void hcd_init_fiq(void *cookie) - otg_dev->os_dep.mphi_base + 0x1f0; - dwc_otg_hcd->fiq_state->mphi_regs.swirq_clr = - otg_dev->os_dep.mphi_base + 0x1f4; -- DWC_WARN("Fake MPHI regs_base at 0x%08x", -- (int)dwc_otg_hcd->fiq_state->mphi_regs.base); -+ DWC_WARN("Fake MPHI regs_base at %px", -+ dwc_otg_hcd->fiq_state->mphi_regs.base); - } else { - dwc_otg_hcd->fiq_state->mphi_regs.ctrl = - otg_dev->os_dep.mphi_base + 0x4c; ---- a/drivers/usb/host/dwc_otg/dwc_otg_pcd_intr.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_pcd_intr.c -@@ -3377,7 +3377,7 @@ void predict_nextep_seq( dwc_otg_core_if - dtknq1_data_t dtknqr1; - uint32_t in_tkn_epnums[4]; - uint8_t seqnum[MAX_EPS_CHANNELS]; -- uint8_t intkn_seq[TOKEN_Q_DEPTH]; -+ uint8_t intkn_seq[1 << 5]; - grstctl_t resetctl = {.d32 = 0 }; - uint8_t temp; - int ndx = 0; diff --git a/target/linux/bcm27xx/patches-5.15/950-0308-rpivid_h625-Fix-build-warnings.patch b/target/linux/bcm27xx/patches-5.15/950-0308-rpivid_h625-Fix-build-warnings.patch deleted file mode 100644 index c0243a329..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0308-rpivid_h625-Fix-build-warnings.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 60940ef958ec9886f189b1df3a587716eebc3d4d Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 27 Oct 2020 12:10:40 +0000 -Subject: [PATCH] rpivid_h625: Fix build warnings - -Signed-off-by: Phil Elwell ---- - drivers/staging/media/rpivid/rpivid_h265.c | 16 ++++++++-------- - 1 file changed, 8 insertions(+), 8 deletions(-) - ---- a/drivers/staging/media/rpivid/rpivid_h265.c -+++ b/drivers/staging/media/rpivid/rpivid_h265.c -@@ -1341,10 +1341,10 @@ static int frame_end(struct rpivid_dev * - - if (gptr_realloc_new(dev, de->cmd_copy_gptr, cmd_alloc)) { - v4l2_err(&dev->v4l2_dev, -- "Alloc cmd buffer (%d): FAILED\n", cmd_alloc); -+ "Alloc cmd buffer (%zu): FAILED\n", cmd_alloc); - return -ENOMEM; - } -- v4l2_info(&dev->v4l2_dev, "Alloc cmd buffer (%d): OK\n", -+ v4l2_info(&dev->v4l2_dev, "Alloc cmd buffer (%zu): OK\n", - cmd_alloc); - } - -@@ -1696,12 +1696,12 @@ static void rpivid_h265_setup(struct rpi - bits_alloc, - DMA_ATTR_FORCE_CONTIGUOUS) != 0) { - v4l2_err(&dev->v4l2_dev, -- "Unable to alloc buf (%d) for bit copy\n", -+ "Unable to alloc buf (%zu) for bit copy\n", - bits_alloc); - goto fail; - } - v4l2_info(&dev->v4l2_dev, -- "Alloc buf (%d) for bit copy OK\n", -+ "Alloc buf (%zu) for bit copy OK\n", - bits_alloc); - } - } -@@ -1995,11 +1995,11 @@ static void phase1_thread(struct rpivid_ - if (de->p1_status & STATUS_PU_EXHAUSTED) { - if (gptr_realloc_new(dev, pu_gptr, next_size(pu_gptr->size))) { - v4l2_err(&dev->v4l2_dev, -- "%s: PU realloc (%#x) failed\n", -+ "%s: PU realloc (%zx) failed\n", - __func__, pu_gptr->size); - goto fail; - } -- v4l2_info(&dev->v4l2_dev, "%s: PU realloc (%#x) OK\n", -+ v4l2_info(&dev->v4l2_dev, "%s: PU realloc (%zx) OK\n", - __func__, pu_gptr->size); - } - -@@ -2007,11 +2007,11 @@ static void phase1_thread(struct rpivid_ - if (gptr_realloc_new(dev, coeff_gptr, - next_size(coeff_gptr->size))) { - v4l2_err(&dev->v4l2_dev, -- "%s: Coeff realloc (%#x) failed\n", -+ "%s: Coeff realloc (%zx) failed\n", - __func__, coeff_gptr->size); - goto fail; - } -- v4l2_info(&dev->v4l2_dev, "%s: Coeff realloc (%#x) OK\n", -+ v4l2_info(&dev->v4l2_dev, "%s: Coeff realloc (%zx) OK\n", - __func__, coeff_gptr->size); - } - diff --git a/target/linux/bcm27xx/patches-5.15/950-0324-media-i2c-imx477-Selection-compliance-fixes.patch b/target/linux/bcm27xx/patches-5.15/950-0324-media-i2c-imx477-Selection-compliance-fixes.patch deleted file mode 100644 index a0c5a9311..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0324-media-i2c-imx477-Selection-compliance-fixes.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 7da0b5ae8e757e56c3405a4e68b5ae91a2ea3227 Mon Sep 17 00:00:00 2001 -From: Naushir Patuck -Date: Wed, 9 Dec 2020 11:30:12 +0000 -Subject: [PATCH] media: i2c: imx477: Selection compliance fixes - -To comply with the intended usage of the V4L2 selection target when -used to retrieve a sensor image properties, adjust the rectangles -returned by the imx477 driver. - -The top/left crop coordinates of the TGT_CROP rectangle were set to -(0, 0) instead of (8, 16) which is the offset from the larger physical -pixel array rectangle. This was also a mismatch with the default values -crop rectangle value, so this is corrected. Found with v4l2-compliance. - -While at it, add V4L2_SEL_TGT_CROP_BOUNDS support: CROP_DEFAULT and -CROP_BOUNDS have the same size as the non-active pixels are not readable -using the selection API. Found with v4l2-compliance. - -This commit mirrors 543790f777ba1b3264c168c653db6d415e7c983f done for -the imx219 sensor. - -Signed-off-by: Naushir Patuck ---- - drivers/media/i2c/imx477.c | 17 +++++++++-------- - 1 file changed, 9 insertions(+), 8 deletions(-) - ---- a/drivers/media/i2c/imx477.c -+++ b/drivers/media/i2c/imx477.c -@@ -900,8 +900,8 @@ static const struct imx477_mode supporte - .height = 3040, - .line_length_pix = 0x5dc0, - .crop = { -- .left = 0, -- .top = 0, -+ .left = IMX477_PIXEL_ARRAY_LEFT, -+ .top = IMX477_PIXEL_ARRAY_TOP, - .width = 4056, - .height = 3040, - }, -@@ -924,8 +924,8 @@ static const struct imx477_mode supporte - .height = 1520, - .line_length_pix = 0x31c4, - .crop = { -- .left = 0, -- .top = 0, -+ .left = IMX477_PIXEL_ARRAY_LEFT, -+ .top = IMX477_PIXEL_ARRAY_TOP, - .width = 4056, - .height = 3040, - }, -@@ -948,8 +948,8 @@ static const struct imx477_mode supporte - .height = 1080, - .line_length_pix = 0x31c4, - .crop = { -- .left = 0, -- .top = 440, -+ .left = IMX477_PIXEL_ARRAY_LEFT, -+ .top = IMX477_PIXEL_ARRAY_TOP + 440, - .width = 4056, - .height = 2600, - }, -@@ -983,8 +983,8 @@ static const struct imx477_mode supporte - * rectangle once the driver is expanded to represent - * its processing blocks with multiple subdevs. - */ -- .left = 4, -- .top = 0, -+ .left = IMX477_PIXEL_ARRAY_LEFT + 4, -+ .top = IMX477_PIXEL_ARRAY_TOP, - .width = 4052, - .height = 3040, - }, -@@ -1696,6 +1696,7 @@ static int imx477_get_selection(struct v - return 0; - - case V4L2_SEL_TGT_CROP_DEFAULT: -+ case V4L2_SEL_TGT_CROP_BOUNDS: - sel->r.left = IMX477_PIXEL_ARRAY_LEFT; - sel->r.top = IMX477_PIXEL_ARRAY_TOP; - sel->r.width = IMX477_PIXEL_ARRAY_WIDTH; diff --git a/target/linux/bcm27xx/patches-5.15/950-0327-staging-bcm2835-codec-Add-the-unpacked-16bpp-raw-for.patch b/target/linux/bcm27xx/patches-5.15/950-0327-staging-bcm2835-codec-Add-the-unpacked-16bpp-raw-for.patch deleted file mode 100644 index 221b01db0..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0327-staging-bcm2835-codec-Add-the-unpacked-16bpp-raw-for.patch +++ /dev/null @@ -1,167 +0,0 @@ -From 0bc0dd69488ae3e0ef593596586d84639b93bf4d Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 7 Jan 2021 10:45:16 +0000 -Subject: [PATCH] staging/bcm2835-codec: Add the unpacked (16bpp) raw - formats - -Now that the firmware supports the unpacked (16bpp) variants -of the MIPI raw formats, add the mappings. - -Signed-off-by: Dave Stevenson ---- - .../bcm2835-codec/bcm2835-v4l2-codec.c | 128 +++++++++++++++++- - 1 file changed, 126 insertions(+), 2 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -381,6 +381,106 @@ static const struct bcm2835_codec_fmt su - .size_multiplier_x2 = 2, - .is_bayer = true, - }, { -+ /* Bayer formats unpacked to 16bpp */ -+ /* 10 bit */ -+ .fourcc = V4L2_PIX_FMT_SRGGB10, -+ .depth = 16, -+ .bytesperline_align = 32, -+ .flags = 0, -+ .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB10, -+ .size_multiplier_x2 = 2, -+ .is_bayer = true, -+ }, { -+ .fourcc = V4L2_PIX_FMT_SBGGR10, -+ .depth = 16, -+ .bytesperline_align = 32, -+ .flags = 0, -+ .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR10, -+ .size_multiplier_x2 = 2, -+ .is_bayer = true, -+ }, { -+ .fourcc = V4L2_PIX_FMT_SGRBG10, -+ .depth = 16, -+ .bytesperline_align = 32, -+ .flags = 0, -+ .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG10, -+ .size_multiplier_x2 = 2, -+ .is_bayer = true, -+ }, { -+ .fourcc = V4L2_PIX_FMT_SGBRG10, -+ .depth = 16, -+ .bytesperline_align = 32, -+ .flags = 0, -+ .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG10, -+ .size_multiplier_x2 = 2, -+ .is_bayer = true, -+ }, { -+ /* 12 bit */ -+ .fourcc = V4L2_PIX_FMT_SRGGB12, -+ .depth = 16, -+ .bytesperline_align = 32, -+ .flags = 0, -+ .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB12, -+ .size_multiplier_x2 = 2, -+ .is_bayer = true, -+ }, { -+ .fourcc = V4L2_PIX_FMT_SBGGR12, -+ .depth = 16, -+ .bytesperline_align = 32, -+ .flags = 0, -+ .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR12, -+ .size_multiplier_x2 = 2, -+ .is_bayer = true, -+ }, { -+ .fourcc = V4L2_PIX_FMT_SGRBG12, -+ .depth = 16, -+ .bytesperline_align = 32, -+ .flags = 0, -+ .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG12, -+ .size_multiplier_x2 = 2, -+ .is_bayer = true, -+ }, { -+ .fourcc = V4L2_PIX_FMT_SGBRG12, -+ .depth = 16, -+ .bytesperline_align = 32, -+ .flags = 0, -+ .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG12, -+ .size_multiplier_x2 = 2, -+ .is_bayer = true, -+ }, { -+ /* 14 bit */ -+ .fourcc = V4L2_PIX_FMT_SRGGB14, -+ .depth = 16, -+ .bytesperline_align = 32, -+ .flags = 0, -+ .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB14, -+ .size_multiplier_x2 = 2, -+ .is_bayer = true, -+ }, { -+ .fourcc = V4L2_PIX_FMT_SBGGR14, -+ .depth = 16, -+ .bytesperline_align = 32, -+ .flags = 0, -+ .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR14, -+ .size_multiplier_x2 = 2, -+ .is_bayer = true, -+ }, { -+ .fourcc = V4L2_PIX_FMT_SGRBG14, -+ .depth = 16, -+ .bytesperline_align = 32, -+ .flags = 0, -+ .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG14, -+ .size_multiplier_x2 = 2, -+ .is_bayer = true, -+ }, { -+ .fourcc = V4L2_PIX_FMT_SGBRG14, -+ .depth = 16, -+ .bytesperline_align = 32, -+ .flags = 0, -+ .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG14, -+ .size_multiplier_x2 = 2, -+ .is_bayer = true, -+ }, { - /* Monochrome MIPI formats */ - /* 8 bit */ - .fourcc = V4L2_PIX_FMT_GREY, -@@ -422,6 +522,30 @@ static const struct bcm2835_codec_fmt su - .mmal_fmt = MMAL_ENCODING_Y16, - .size_multiplier_x2 = 2, - }, { -+ /* 10 bit as 16bpp */ -+ .fourcc = V4L2_PIX_FMT_Y10, -+ .depth = 16, -+ .bytesperline_align = 32, -+ .flags = 0, -+ .mmal_fmt = MMAL_ENCODING_Y10, -+ .size_multiplier_x2 = 2, -+ }, { -+ /* 12 bit as 16bpp */ -+ .fourcc = V4L2_PIX_FMT_Y12, -+ .depth = 16, -+ .bytesperline_align = 32, -+ .flags = 0, -+ .mmal_fmt = MMAL_ENCODING_Y12, -+ .size_multiplier_x2 = 2, -+ }, { -+ /* 14 bit as 16bpp */ -+ .fourcc = V4L2_PIX_FMT_Y14, -+ .depth = 16, -+ .bytesperline_align = 32, -+ .flags = 0, -+ .mmal_fmt = MMAL_ENCODING_Y14, -+ .size_multiplier_x2 = 2, -+ }, { - /* Compressed formats */ - .fourcc = V4L2_PIX_FMT_H264, - .depth = 0, -@@ -2681,10 +2805,10 @@ static const struct v4l2_m2m_ops m2m_ops - - /* Size of the array to provide to the VPU when asking for the list of supported - * formats. -- * The ISP component currently advertises 44 input formats, so add a small -+ * The ISP component currently advertises 62 input formats, so add a small - * overhead on that. - */ --#define MAX_SUPPORTED_ENCODINGS 50 -+#define MAX_SUPPORTED_ENCODINGS 70 - - /* Populate dev->supported_fmts with the formats supported by those ports. */ - static int bcm2835_codec_get_supported_fmts(struct bcm2835_codec_dev *dev) diff --git a/target/linux/bcm27xx/patches-5.15/950-0328-staging-bcm2835-codec-Log-the-number-of-excess-suppo.patch b/target/linux/bcm27xx/patches-5.15/950-0328-staging-bcm2835-codec-Log-the-number-of-excess-suppo.patch deleted file mode 100644 index 25ed1950a..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0328-staging-bcm2835-codec-Log-the-number-of-excess-suppo.patch +++ /dev/null @@ -1,43 +0,0 @@ -From e575bca2b5e1e44a23b435711219e3941878dcb4 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 7 Jan 2021 11:41:26 +0000 -Subject: [PATCH] staging/bcm2835-codec: Log the number of excess - supported formats - -When logging that the firmware has provided more supported formats -than we had allocated storage for, log the number allocated and -returned. - -Signed-off-by: Dave Stevenson ---- - .../vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c | 12 ++++++++---- - 1 file changed, 8 insertions(+), 4 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -2836,8 +2836,10 @@ static int bcm2835_codec_get_supported_f - - if (ret) { - if (ret == MMAL_MSG_STATUS_ENOSPC) { -- v4l2_err(&dev->v4l2_dev, "%s: port has more encoding than we provided space for. Some are dropped.\n", -- __func__); -+ v4l2_err(&dev->v4l2_dev, -+ "%s: port has more encodings than we provided space for. Some are dropped (%u vs %u).\n", -+ __func__, param_size / sizeof(u32), -+ MAX_SUPPORTED_ENCODINGS); - num_encodings = MAX_SUPPORTED_ENCODINGS; - } else { - v4l2_err(&dev->v4l2_dev, "%s: get_param ret %u.\n", -@@ -2880,8 +2882,10 @@ static int bcm2835_codec_get_supported_f - - if (ret) { - if (ret == MMAL_MSG_STATUS_ENOSPC) { -- v4l2_err(&dev->v4l2_dev, "%s: port has more encoding than we provided space for. Some are dropped.\n", -- __func__); -+ v4l2_err(&dev->v4l2_dev, -+ "%s: port has more encodings than we provided space for. Some are dropped (%u vs %u).\n", -+ __func__, param_size / sizeof(u32), -+ MAX_SUPPORTED_ENCODINGS); - num_encodings = MAX_SUPPORTED_ENCODINGS; - } else { - ret = -EINVAL; diff --git a/target/linux/bcm27xx/patches-5.15/950-0332-arch-arm-Add-__memset-alias-to-memset_rpi.S.patch b/target/linux/bcm27xx/patches-5.15/950-0332-arch-arm-Add-__memset-alias-to-memset_rpi.S.patch deleted file mode 100644 index 2a2798a54..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0332-arch-arm-Add-__memset-alias-to-memset_rpi.S.patch +++ /dev/null @@ -1,33 +0,0 @@ -From f6b2421dd93a7eee29b58816cf7d3c1811dab9f9 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 8 Jan 2021 13:37:25 +0000 -Subject: [PATCH] arch/arm: Add __memset alias to memset_rpi.S - -memset_rpi.S is an optimised memset implementation, but doesn't define -__memset (which was just added to memset.S). As a result, building -for the BCM2835 platform causes a link failure. - -Add __memset as yet another alias to our common implementation. - -Signed-off-by: Phil Elwell ---- - arch/arm/lib/memset_rpi.S | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/arch/arm/lib/memset_rpi.S -+++ b/arch/arm/lib/memset_rpi.S -@@ -52,6 +52,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBI - */ - ENTRY(mmioset) - ENTRY(memset) -+ENTRY(__memset) - ENTRY(__memset32) - ENTRY(__memset64) - -@@ -124,5 +125,6 @@ ENTRY(__memset64) - .unreq DAT3 - ENDPROC(__memset64) - ENDPROC(__memset32) -+ENDPROC(__memset) - ENDPROC(memset) - ENDPROC(mmioset) diff --git a/target/linux/bcm27xx/patches-5.15/950-0338-media-i2c-imx290-Replace-V4L2_CID_GAIN-with-V4L2_CID.patch b/target/linux/bcm27xx/patches-5.15/950-0338-media-i2c-imx290-Replace-V4L2_CID_GAIN-with-V4L2_CID.patch deleted file mode 100644 index f99cd4e99..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0338-media-i2c-imx290-Replace-V4L2_CID_GAIN-with-V4L2_CID.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 8999614346ab0bbbd9ddd0798222edef7bce6b47 Mon Sep 17 00:00:00 2001 -From: David Plowman -Date: Thu, 4 Feb 2021 17:29:32 +0000 -Subject: [PATCH] media: i2c: imx290: Replace V4L2_CID_GAIN with - V4L2_CID_ANALOGUE_GAIN - -Most software (including libcamera) requires V4L2_CID_ANALOGUE_GAIN, -not V4L2_CID_GAIN. - -The range for the control is 0 to 100 for which the sensor uses only -analogue gain; higher values would involve digital gain which this -control should not apply. - -Signed-off-by: David Plowman ---- - drivers/media/i2c/imx290.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/media/i2c/imx290.c -+++ b/drivers/media/i2c/imx290.c -@@ -647,7 +647,7 @@ static int imx290_set_ctrl(struct v4l2_c - return 0; - - switch (ctrl->id) { -- case V4L2_CID_GAIN: -+ case V4L2_CID_ANALOGUE_GAIN: - ret = imx290_set_gain(imx290, ctrl->val); - break; - case V4L2_CID_EXPOSURE: -@@ -1327,7 +1327,7 @@ static int imx290_probe(struct i2c_clien - v4l2_ctrl_handler_init(&imx290->ctrls, 4); - - v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops, -- V4L2_CID_GAIN, 0, 238, 1, 0); -+ V4L2_CID_ANALOGUE_GAIN, 0, 100, 1, 0); - - mode = imx290->current_mode; - imx290->hblank = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops, diff --git a/target/linux/bcm27xx/patches-5.15/950-0339-media-i2c-imx290-Fix-number-of-controls-in-v4l2_ctrl.patch b/target/linux/bcm27xx/patches-5.15/950-0339-media-i2c-imx290-Fix-number-of-controls-in-v4l2_ctrl.patch deleted file mode 100644 index 970099d3f..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0339-media-i2c-imx290-Fix-number-of-controls-in-v4l2_ctrl.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 8ec3be7296445f9958e732274676db8b8af372cd Mon Sep 17 00:00:00 2001 -From: David Plowman -Date: Thu, 4 Feb 2021 21:21:44 +0000 -Subject: [PATCH] media: i2c: imx290: Fix number of controls in - v4l2_ctrl_handler_init - -The number is only a hint, but may as well be correct. - -Fixes: 471e0029e98aa ("media: i2c: imx290: Convert HMAX setting into V4L2_CID_HBLANK") -Fixes: be0b9b7ad1c27 ("media: i2c: imx290: Add support for V4L2_CID_VBLANK") -Fixes: 8483f0d7599aa ("media: i2c: imx290: Add exposure control to the driver.") -Fixes: 9764f3459c401 ("media: i2c: imx290: Add H and V flip controls") -Signed-off-by: David Plowman ---- - drivers/media/i2c/imx290.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/media/i2c/imx290.c -+++ b/drivers/media/i2c/imx290.c -@@ -1324,7 +1324,7 @@ static int imx290_probe(struct i2c_clien - */ - imx290_entity_init_cfg(&imx290->sd, NULL); - -- v4l2_ctrl_handler_init(&imx290->ctrls, 4); -+ v4l2_ctrl_handler_init(&imx290->ctrls, 9); - - v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops, - V4L2_CID_ANALOGUE_GAIN, 0, 100, 1, 0); diff --git a/target/linux/bcm27xx/patches-5.15/950-0340-dt-binding-display-bcm2711-hdmi-Add-CEC-and-hotplug-.patch b/target/linux/bcm27xx/patches-5.15/950-0340-dt-binding-display-bcm2711-hdmi-Add-CEC-and-hotplug-.patch deleted file mode 100644 index 36c739c75..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0340-dt-binding-display-bcm2711-hdmi-Add-CEC-and-hotplug-.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 8c0e1c141dfba089992f63b5d58218240d009ad7 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Mon, 11 Jan 2021 15:23:07 +0100 -Subject: [PATCH] dt-binding: display: bcm2711-hdmi: Add CEC and - hotplug interrupts - -The CEC and hotplug interrupts were missing when that binding was -introduced, let's add them in now that we've figured out how it works. - -Signed-off-by: Maxime Ripard -Acked-by: Dave Stevenson ---- - .../devicetree/bindings/display/brcm,bcm2711-hdmi.yaml | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml -+++ b/Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml -@@ -109,7 +109,7 @@ required: - - resets - - ddc - --additionalProperties: false -+unevaluatedProperties: false - - examples: - - | diff --git a/target/linux/bcm27xx/patches-5.15/950-0343-staging-rpivid-Fix-crash-when-CMA-alloc-fails.patch b/target/linux/bcm27xx/patches-5.15/950-0343-staging-rpivid-Fix-crash-when-CMA-alloc-fails.patch deleted file mode 100644 index afd27ffb7..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0343-staging-rpivid-Fix-crash-when-CMA-alloc-fails.patch +++ /dev/null @@ -1,118 +0,0 @@ -From 929d12a467d630372882dbf8eed47d212f102326 Mon Sep 17 00:00:00 2001 -From: John Cox -Date: Mon, 8 Feb 2021 16:01:37 +0000 -Subject: [PATCH] staging: rpivid: Fix crash when CMA alloc fails - -If realloc to increase coeff size fails then attempt to re-allocate -the original size. If that also fails then flag a fatal error to abort -all further decode. - -Signed-off-by: John Cox ---- - drivers/staging/media/rpivid/rpivid.h | 3 ++ - drivers/staging/media/rpivid/rpivid_h265.c | 44 +++++++++++++++++++++- - 2 files changed, 45 insertions(+), 2 deletions(-) - ---- a/drivers/staging/media/rpivid/rpivid.h -+++ b/drivers/staging/media/rpivid/rpivid.h -@@ -88,6 +88,9 @@ struct rpivid_ctx { - struct v4l2_pix_format src_fmt; - struct v4l2_pix_format dst_fmt; - int dst_fmt_set; -+ // fatal_err is set if an error has occurred s.t. decode cannot -+ // continue (such as running out of CMA) -+ int fatal_err; - - struct v4l2_ctrl_handler hdl; - struct v4l2_ctrl **ctrls; ---- a/drivers/staging/media/rpivid/rpivid_h265.c -+++ b/drivers/staging/media/rpivid/rpivid_h265.c -@@ -73,10 +73,18 @@ static void gptr_free(struct rpivid_dev - gptr->attrs = 0; - } - --/* Realloc but do not copy */ -+/* Realloc but do not copy -+ * -+ * Frees then allocs. -+ * If the alloc fails then it attempts to re-allocote the old size -+ * On error then check gptr->ptr to determine if anything is currently -+ * allocated. -+ */ - static int gptr_realloc_new(struct rpivid_dev * const dev, - struct rpivid_gptr * const gptr, size_t size) - { -+ const size_t old_size = gptr->size; -+ - if (size == gptr->size) - return 0; - -@@ -88,7 +96,21 @@ static int gptr_realloc_new(struct rpivi - gptr->size = size; - gptr->ptr = dma_alloc_attrs(dev->dev, gptr->size, - &gptr->addr, GFP_KERNEL, gptr->attrs); -- return gptr->ptr ? 0 : -ENOMEM; -+ -+ if (!gptr->ptr) { -+ gptr->addr = 0; -+ gptr->size = old_size; -+ gptr->ptr = dma_alloc_attrs(dev->dev, gptr->size, -+ &gptr->addr, GFP_KERNEL, gptr->attrs); -+ if (!gptr->ptr) { -+ gptr->size = 0; -+ gptr->addr = 0; -+ gptr->attrs = 0; -+ } -+ return -ENOMEM; -+ } -+ -+ return 0; - } - - /* floor(log2(x)) */ -@@ -2020,6 +2042,12 @@ static void phase1_thread(struct rpivid_ - return; - - fail: -+ if (!pu_gptr->addr || !coeff_gptr->addr) { -+ v4l2_err(&dev->v4l2_dev, -+ "%s: Fatal: failed to reclaim old alloc\n", -+ __func__); -+ ctx->fatal_err = 1; -+ } - dec_env_delete(de); - xtrace_fin(dev, de); - v4l2_m2m_buf_done_and_job_finish(dev->m2m_dev, ctx->fh.m2m_ctx, -@@ -2093,6 +2121,9 @@ static void phase1_claimed(struct rpivid - - xtrace_in(dev, de); - -+ if (ctx->fatal_err) -+ goto fail; -+ - de->pu_base_vc = pu_gptr->addr; - de->pu_stride = - ALIGN_DOWN(pu_gptr->size / de->pic_height_in_ctbs_y, 64); -@@ -2116,6 +2147,14 @@ static void phase1_claimed(struct rpivid - apb_write_vc_addr_final(dev, RPI_CFBASE, de->cmd_copy_gptr->addr); - - xtrace_ok(dev, de); -+ return; -+ -+fail: -+ dec_env_delete(de); -+ xtrace_fin(dev, de); -+ v4l2_m2m_buf_done_and_job_finish(dev->m2m_dev, ctx->fh.m2m_ctx, -+ VB2_BUF_STATE_ERROR); -+ xtrace_fail(dev, de); - } - - static void dec_state_delete(struct rpivid_ctx *const ctx) -@@ -2186,6 +2225,7 @@ static int rpivid_h265_start(struct rpiv - v4l2_info(&dev->v4l2_dev, "%s: (%dx%d)\n", __func__, - ctx->dst_fmt.width, ctx->dst_fmt.height); - -+ ctx->fatal_err = 0; - ctx->dec0 = NULL; - ctx->state = kzalloc(sizeof(*ctx->state), GFP_KERNEL); - if (!ctx->state) { diff --git a/target/linux/bcm27xx/patches-5.15/950-0344-media-i2c-imx477-Remove-auto-frame-length-adjusting.patch b/target/linux/bcm27xx/patches-5.15/950-0344-media-i2c-imx477-Remove-auto-frame-length-adjusting.patch deleted file mode 100644 index 41273687d..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0344-media-i2c-imx477-Remove-auto-frame-length-adjusting.patch +++ /dev/null @@ -1,142 +0,0 @@ -From e783c62652ae18705f1a9cfeaa5c830c76e7facc Mon Sep 17 00:00:00 2001 -From: Naushir Patuck -Date: Wed, 10 Feb 2021 10:18:53 +0000 -Subject: [PATCH] media: i2c: imx477: Remove auto frame length - adjusting - -The V4L2_CID_EXPOSURE_AUTO_PRIORITY was used to let the sensor control -frame length (effectively framerate) based on the requested exposure -time requested. Remove this feature as it is never used, and goes -against how V4L2 likes to handle exposure and vblank controls. - -Signed-off-by: Naushir Patuck ---- - drivers/media/i2c/imx477.c | 83 +++----------------------------------- - 1 file changed, 6 insertions(+), 77 deletions(-) - ---- a/drivers/media/i2c/imx477.c -+++ b/drivers/media/i2c/imx477.c -@@ -1082,8 +1082,6 @@ struct imx477 { - struct v4l2_ctrl *hflip; - struct v4l2_ctrl *vblank; - struct v4l2_ctrl *hblank; -- /* This ctrl allows automatic variable framerate */ -- struct v4l2_ctrl *exposure_auto; - - /* Current mode */ - const struct imx477_mode *mode; -@@ -1280,66 +1278,14 @@ static int imx477_open(struct v4l2_subde - return 0; - } - --static int imx477_set_exposure(struct imx477 *imx477, unsigned int val) --{ -- int ret; -- -- ret = imx477_write_reg(imx477, IMX477_REG_EXPOSURE, -- IMX477_REG_VALUE_16BIT, val); -- -- /* Setup the frame length in the case of auto framerate mode. */ -- if (imx477->exposure_auto->val) { -- unsigned int frame_length, frame_length_max, frame_length_min; -- -- frame_length_min = imx477->vblank->minimum + -- imx477->mode->height; -- frame_length_max = imx477->vblank->maximum + -- imx477->mode->height; -- frame_length = max(frame_length_min, -- val + IMX477_EXPOSURE_OFFSET); -- frame_length = min(frame_length_max, frame_length); -- ret += imx477_write_reg(imx477, IMX477_REG_FRAME_LENGTH, -- IMX477_REG_VALUE_16BIT, frame_length); -- } -- -- return ret; --} -- - static void imx477_adjust_exposure_range(struct imx477 *imx477, - struct v4l2_ctrl *ctrl) - { - int exposure_max, exposure_def; - -- if (ctrl->id == V4L2_CID_VBLANK || !ctrl->val) { -- /* -- * Either VBLANK has been changed or auto framerate -- * adjusting has been disabled. Honour the VBLANK limits -- * when setting exposure. -- */ -- exposure_max = imx477->mode->height + imx477->vblank->val - -- IMX477_EXPOSURE_OFFSET; -- -- if (ctrl->id == V4L2_CID_EXPOSURE_AUTO_PRIORITY) { -- /* -- * Allow VBLANK adjustments since the driver is not -- * handling frame length control automatically. -- */ -- __v4l2_ctrl_grab(imx477->vblank, false); -- } -- } else { -- /* -- * Auto framerate adjusting has been enabled. VBLANK -- * ctrl has been disabled and exposure can ramp up -- * to the maximum allowable value. -- */ -- exposure_max = IMX477_EXPOSURE_MAX; -- /* -- * Do not allow VBLANK adjustments if the driver is -- * handling it frame length control automatically. -- */ -- __v4l2_ctrl_grab(imx477->vblank, true); -- } -- -+ /* Honour the VBLANK limits when setting exposure. */ -+ exposure_max = imx477->mode->height + imx477->vblank->val - -+ IMX477_EXPOSURE_OFFSET; - exposure_def = min(exposure_max, imx477->exposure->val); - __v4l2_ctrl_modify_range(imx477->exposure, imx477->exposure->minimum, - exposure_max, imx477->exposure->step, -@@ -1353,14 +1299,8 @@ static int imx477_set_ctrl(struct v4l2_c - struct i2c_client *client = v4l2_get_subdevdata(&imx477->sd); - int ret = 0; - -- if (ctrl->id == V4L2_CID_VBLANK || -- ctrl->id == V4L2_CID_EXPOSURE_AUTO_PRIORITY) { -- /* -- * These controls may change the limits of usable exposure, -- * so check and adjust if necessary. -- */ -+ if (ctrl->id == V4L2_CID_VBLANK) - imx477_adjust_exposure_range(imx477, ctrl); -- } - - /* - * Applying V4L2 control value only happens -@@ -1375,14 +1315,8 @@ static int imx477_set_ctrl(struct v4l2_c - IMX477_REG_VALUE_16BIT, ctrl->val); - break; - case V4L2_CID_EXPOSURE: -- ret = imx477_set_exposure(imx477, ctrl->val); -- break; -- case V4L2_CID_EXPOSURE_AUTO_PRIORITY: -- /* -- * imx477_set_exposure() will recalculate the frame length -- * to adjust the framerate to match the exposure. -- */ -- ret = imx477_set_exposure(imx477, imx477->exposure->val); -+ ret = imx477_write_reg(imx477, IMX477_REG_EXPOSURE, -+ IMX477_REG_VALUE_16BIT, ctrl->val); - break; - case V4L2_CID_DIGITAL_GAIN: - ret = imx477_write_reg(imx477, IMX477_REG_DIGITAL_GAIN, -@@ -2005,11 +1939,6 @@ static int imx477_init_controls(struct i - IMX477_DGTL_GAIN_MIN, IMX477_DGTL_GAIN_MAX, - IMX477_DGTL_GAIN_STEP, IMX477_DGTL_GAIN_DEFAULT); - -- imx477->exposure_auto = -- v4l2_ctrl_new_std(ctrl_hdlr, &imx477_ctrl_ops, -- V4L2_CID_EXPOSURE_AUTO_PRIORITY, -- 0, 1, 1, 0); -- - imx477->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx477_ctrl_ops, - V4L2_CID_HFLIP, 0, 1, 1, 0); - if (imx477->hflip) diff --git a/target/linux/bcm27xx/patches-5.15/950-0345-media-i2c-imx477-Add-very-long-exposure-control-to-t.patch b/target/linux/bcm27xx/patches-5.15/950-0345-media-i2c-imx477-Add-very-long-exposure-control-to-t.patch deleted file mode 100644 index 01c90b880..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0345-media-i2c-imx477-Add-very-long-exposure-control-to-t.patch +++ /dev/null @@ -1,126 +0,0 @@ -From 0633c60ff1ed5897d8996c5683ea07a5d345e660 Mon Sep 17 00:00:00 2001 -From: Naushir Patuck -Date: Wed, 10 Feb 2021 10:50:32 +0000 -Subject: [PATCH] media: i2c: imx477: Add very long exposure control to - the driver - -Add support for very long exposures by using the exposure multiplier -register. Userland does not need to pass any additional controls to -enable long exposures, it simply requests a larger vblank to extend the -exposure control range appropriately. - -Currently, since hblank is fixed, a maximum of approximately 124 seconds -of exposure time can be used. In a future change, hblank could also be -controlled in userland to give over 200 seconds of exposure time. - -Signed-off-by: Naushir Patuck ---- - drivers/media/i2c/imx477.c | 47 +++++++++++++++++++++++++++++++++----- - 1 file changed, 41 insertions(+), 6 deletions(-) - ---- a/drivers/media/i2c/imx477.c -+++ b/drivers/media/i2c/imx477.c -@@ -44,6 +44,10 @@ - #define IMX477_REG_FRAME_LENGTH 0x0340 - #define IMX477_FRAME_LENGTH_MAX 0xffdc - -+/* Long exposure multiplier */ -+#define IMX477_LONG_EXP_SHIFT_MAX 7 -+#define IMX477_LONG_EXP_SHIFT_REG 0x3100 -+ - /* Exposure control */ - #define IMX477_REG_EXPOSURE 0x0202 - #define IMX477_EXPOSURE_OFFSET 22 -@@ -1097,6 +1101,9 @@ struct imx477 { - - /* Rewrite common registers on stream on? */ - bool common_regs_written; -+ -+ /* Current long exposure factor in use. Set through V4L2_CID_VBLANK */ -+ unsigned int long_exp_shift; - }; - - static inline struct imx477 *to_imx477(struct v4l2_subdev *_sd) -@@ -1285,13 +1292,33 @@ static void imx477_adjust_exposure_range - - /* Honour the VBLANK limits when setting exposure. */ - exposure_max = imx477->mode->height + imx477->vblank->val - -- IMX477_EXPOSURE_OFFSET; -+ (IMX477_EXPOSURE_OFFSET << imx477->long_exp_shift); - exposure_def = min(exposure_max, imx477->exposure->val); - __v4l2_ctrl_modify_range(imx477->exposure, imx477->exposure->minimum, - exposure_max, imx477->exposure->step, - exposure_def); - } - -+static int imx477_set_frame_length(struct imx477 *imx477, unsigned int val) -+{ -+ int ret = 0; -+ -+ imx477->long_exp_shift = 0; -+ -+ while (val > IMX477_FRAME_LENGTH_MAX) { -+ imx477->long_exp_shift++; -+ val >>= 1; -+ } -+ -+ ret = imx477_write_reg(imx477, IMX477_REG_FRAME_LENGTH, -+ IMX477_REG_VALUE_16BIT, val); -+ if (ret) -+ return ret; -+ -+ return imx477_write_reg(imx477, IMX477_LONG_EXP_SHIFT_REG, -+ IMX477_REG_VALUE_08BIT, imx477->long_exp_shift); -+} -+ - static int imx477_set_ctrl(struct v4l2_ctrl *ctrl) - { - struct imx477 *imx477 = -@@ -1299,6 +1326,10 @@ static int imx477_set_ctrl(struct v4l2_c - struct i2c_client *client = v4l2_get_subdevdata(&imx477->sd); - int ret = 0; - -+ /* -+ * The VBLANK control may change the limits of usable exposure, so check -+ * and adjust if necessary. -+ */ - if (ctrl->id == V4L2_CID_VBLANK) - imx477_adjust_exposure_range(imx477, ctrl); - -@@ -1316,7 +1347,8 @@ static int imx477_set_ctrl(struct v4l2_c - break; - case V4L2_CID_EXPOSURE: - ret = imx477_write_reg(imx477, IMX477_REG_EXPOSURE, -- IMX477_REG_VALUE_16BIT, ctrl->val); -+ IMX477_REG_VALUE_16BIT, ctrl->val >> -+ imx477->long_exp_shift); - break; - case V4L2_CID_DIGITAL_GAIN: - ret = imx477_write_reg(imx477, IMX477_REG_DIGITAL_GAIN, -@@ -1350,9 +1382,8 @@ static int imx477_set_ctrl(struct v4l2_c - imx477->vflip->val << 1); - break; - case V4L2_CID_VBLANK: -- ret = imx477_write_reg(imx477, IMX477_REG_FRAME_LENGTH, -- IMX477_REG_VALUE_16BIT, -- imx477->mode->height + ctrl->val); -+ ret = imx477_set_frame_length(imx477, -+ imx477->mode->height + ctrl->val); - break; - default: - dev_info(&client->dev, -@@ -1521,9 +1552,13 @@ static void imx477_set_framing_limits(st - frm_length_default = - imx477_get_frame_length(mode, &mode->timeperframe_default); - -+ /* Default to no long exposure multiplier. */ -+ imx477->long_exp_shift = 0; -+ - /* Update limits and set FPS to default */ - __v4l2_ctrl_modify_range(imx477->vblank, frm_length_min - mode->height, -- IMX477_FRAME_LENGTH_MAX - mode->height, -+ ((1 << IMX477_LONG_EXP_SHIFT_MAX) * -+ IMX477_FRAME_LENGTH_MAX) - mode->height, - 1, frm_length_default - mode->height); - - /* Setting this will adjust the exposure limits as well. */ diff --git a/target/linux/bcm27xx/patches-5.15/950-0346-media-i2c-imx290-Fix-up-exposure-calcuations-and-ran.patch b/target/linux/bcm27xx/patches-5.15/950-0346-media-i2c-imx290-Fix-up-exposure-calcuations-and-ran.patch deleted file mode 100644 index e61ce8971..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0346-media-i2c-imx290-Fix-up-exposure-calcuations-and-ran.patch +++ /dev/null @@ -1,59 +0,0 @@ -From b6117da06f6d72d847985e5f179db62beb0227ca Mon Sep 17 00:00:00 2001 -From: David Plowman -Date: Wed, 17 Feb 2021 18:08:12 +0000 -Subject: [PATCH] media: i2c: imx290: Fix up exposure calcuations and - ranges - -Should now correspond exactly to the datasheet. - -Signed-off-by: David Plowman ---- - drivers/media/i2c/imx290.c | 14 +++++++------- - 1 file changed, 7 insertions(+), 7 deletions(-) - ---- a/drivers/media/i2c/imx290.c -+++ b/drivers/media/i2c/imx290.c -@@ -50,7 +50,7 @@ enum imx290_clk_index { - #define IMX290_HMAX_MIN_4LANE 2200 /* Min of 2200 pixels = 60fps */ - #define IMX290_HMAX_MAX 0xffff - --#define IMX290_EXPOSURE_MIN 2 -+#define IMX290_EXPOSURE_MIN 1 - #define IMX290_EXPOSURE_STEP 1 - #define IMX290_EXPOSURE_LOW 0x3020 - #define IMX290_PGCTRL 0x308c -@@ -584,7 +584,7 @@ static int imx290_set_gain(struct imx290 - static int imx290_set_exposure(struct imx290 *imx290, u32 value) - { - u32 exposure = (imx290->current_mode->height + imx290->vblank->val) - -- value; -+ value - 1; - int ret; - - ret = imx290_write_buffered_reg(imx290, IMX290_EXPOSURE_LOW, 3, -@@ -855,10 +855,10 @@ static int imx290_set_fmt(struct v4l2_su - } - if (imx290->exposure) - __v4l2_ctrl_modify_range(imx290->exposure, -- mode->vmax - mode->height, -- mode->vmax - 4, -+ IMX290_EXPOSURE_MIN, -+ mode->vmax - 2, - IMX290_EXPOSURE_STEP, -- mode->vmax - 4); -+ mode->vmax - 2); - } - - *format = fmt->format; -@@ -1345,9 +1345,9 @@ static int imx290_probe(struct i2c_clien - imx290->exposure = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops, - V4L2_CID_EXPOSURE, - IMX290_EXPOSURE_MIN, -- mode->vmax - 4, -+ mode->vmax - 2, - IMX290_EXPOSURE_STEP, -- mode->vmax - 4); -+ mode->vmax - 2); - - imx290->hflip = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops, - V4L2_CID_HFLIP, 0, 1, 1, 0); diff --git a/target/linux/bcm27xx/patches-5.15/950-0347-media-i2c-imx290-Handle-exposure-correctly-when-vbla.patch b/target/linux/bcm27xx/patches-5.15/950-0347-media-i2c-imx290-Handle-exposure-correctly-when-vbla.patch deleted file mode 100644 index 5511d620e..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0347-media-i2c-imx290-Handle-exposure-correctly-when-vbla.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 312748a4a15eba1d63a0861acabb7941c36e69d7 Mon Sep 17 00:00:00 2001 -From: David Plowman -Date: Thu, 18 Feb 2021 11:58:29 +0000 -Subject: [PATCH] media: i2c: imx290: Handle exposure correctly when - vblank changes - -When vblank changes we must modify the exposure range. Also, with this -sensor, the effective exposure time implicitly changes when vblank -does, so we have to reset it after every vblank update. - -Signed-off-by: David Plowman ---- - drivers/media/i2c/imx290.c | 18 ++++++++++++++++++ - 1 file changed, 18 insertions(+) - ---- a/drivers/media/i2c/imx290.c -+++ b/drivers/media/i2c/imx290.c -@@ -618,6 +618,24 @@ static int imx290_set_vmax(struct imx290 - if (ret) - dev_err(imx290->dev, "Unable to write vmax\n"); - -+ /* -+ * Changing vblank changes the allowed range for exposure. -+ * We don't supply the current exposure as default here as it -+ * may lie outside the new range. We will reset it just below. -+ */ -+ __v4l2_ctrl_modify_range(imx290->exposure, -+ IMX290_EXPOSURE_MIN, -+ vmax - 2, -+ IMX290_EXPOSURE_STEP, -+ vmax - 2); -+ -+ /* -+ * Becuse of the way exposure works for this sensor, updating -+ * vblank causes the effective exposure to change, so we must -+ * set it back to the "new" correct value. -+ */ -+ imx290_set_exposure(imx290, imx290->exposure->val); -+ - return ret; - } - diff --git a/target/linux/bcm27xx/patches-5.15/950-0348-media-i2c-imx477-Fix-crop-height-for-2028x1080-mode.patch b/target/linux/bcm27xx/patches-5.15/950-0348-media-i2c-imx477-Fix-crop-height-for-2028x1080-mode.patch deleted file mode 100644 index 660467bc6..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0348-media-i2c-imx477-Fix-crop-height-for-2028x1080-mode.patch +++ /dev/null @@ -1,25 +0,0 @@ -From ccee8f195e3a5b82e3fbfabc7e04f3db7d5f4449 Mon Sep 17 00:00:00 2001 -From: Naushir Patuck -Date: Thu, 18 Feb 2021 15:05:57 +0000 -Subject: [PATCH] media: i2c: imx477: Fix crop height for 2028x1080 - mode - -The crop height for this mode was set at 2600 lines, it should be 2160 -lines instead. - -Signed-off-by: Naushir Patuck ---- - drivers/media/i2c/imx477.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/media/i2c/imx477.c -+++ b/drivers/media/i2c/imx477.c -@@ -955,7 +955,7 @@ static const struct imx477_mode supporte - .left = IMX477_PIXEL_ARRAY_LEFT, - .top = IMX477_PIXEL_ARRAY_TOP + 440, - .width = 4056, -- .height = 2600, -+ .height = 2160, - }, - .timeperframe_min = { - .numerator = 100, diff --git a/target/linux/bcm27xx/patches-5.15/950-0349-media-i2c-imx477-Replace-existing-1012x760-mode.patch b/target/linux/bcm27xx/patches-5.15/950-0349-media-i2c-imx477-Replace-existing-1012x760-mode.patch deleted file mode 100644 index b06e451f4..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0349-media-i2c-imx477-Replace-existing-1012x760-mode.patch +++ /dev/null @@ -1,197 +0,0 @@ -From 43568d1ac29fbbdc812a52a82f6ec1cd5ff6d6e6 Mon Sep 17 00:00:00 2001 -From: Naushir Patuck -Date: Thu, 18 Feb 2021 15:23:11 +0000 -Subject: [PATCH] media: i2c: imx477: Replace existing 1012x760 mode - -The existing 1012x760 120 fps mode has significant IQ problem using -the internal sensor scaler. Replace this mode with a 1332x990 120 fps -mode instead. This new mode has a smaller field of view, but does not -suffer from the bad IQ of the original mode. - -Signed-off-by: Naushir Patuck ---- - drivers/media/i2c/imx477.c | 97 ++++++++++++++++++++------------------ - 1 file changed, 50 insertions(+), 47 deletions(-) - ---- a/drivers/media/i2c/imx477.c -+++ b/drivers/media/i2c/imx477.c -@@ -770,7 +770,7 @@ static const struct imx477_reg mode_2028 - }; - - /* 4x4 binned. 120fps */ --static const struct imx477_reg mode_1012x760_regs[] = { -+static const struct imx477_reg mode_1332x990_regs[] = { - {0x420b, 0x01}, - {0x990c, 0x00}, - {0x990d, 0x08}, -@@ -786,28 +786,31 @@ static const struct imx477_reg mode_1012 - {0x0112, 0x0a}, - {0x0113, 0x0a}, - {0x0114, 0x01}, -- {0x0342, 0x14}, -- {0x0343, 0x60}, -+ {0x0342, 0x1a}, -+ {0x0343, 0x08}, -+ {0x0340, 0x04}, -+ {0x0341, 0x1a}, - {0x0344, 0x00}, - {0x0345, 0x00}, -- {0x0346, 0x00}, -- {0x0347, 0x00}, -+ {0x0346, 0x02}, -+ {0x0347, 0x10}, - {0x0348, 0x0f}, -- {0x0349, 0xd3}, -- {0x034a, 0x0b}, -- {0x034b, 0xdf}, -+ {0x0349, 0xd7}, -+ {0x034a, 0x09}, -+ {0x034b, 0xcf}, - {0x00e3, 0x00}, - {0x00e4, 0x00}, - {0x00fc, 0x0a}, - {0x00fd, 0x0a}, - {0x00fe, 0x0a}, - {0x00ff, 0x0a}, -+ {0xe013, 0x00}, - {0x0220, 0x00}, - {0x0221, 0x11}, - {0x0381, 0x01}, - {0x0383, 0x01}, - {0x0385, 0x01}, -- {0x0387, 0x03}, -+ {0x0387, 0x01}, - {0x0900, 0x01}, - {0x0901, 0x22}, - {0x0902, 0x02}, -@@ -831,29 +834,29 @@ static const struct imx477_reg mode_1012 - {0x936d, 0x5f}, - {0x9304, 0x03}, - {0x9305, 0x80}, -- {0x9e9a, 0x3f}, -- {0x9e9b, 0x3f}, -- {0x9e9c, 0x3f}, -- {0x9e9d, 0x27}, -- {0x9e9e, 0x27}, -- {0x9e9f, 0x27}, -+ {0x9e9a, 0x2f}, -+ {0x9e9b, 0x2f}, -+ {0x9e9c, 0x2f}, -+ {0x9e9d, 0x00}, -+ {0x9e9e, 0x00}, -+ {0x9e9f, 0x00}, - {0xa2a9, 0x27}, - {0xa2b7, 0x03}, -- {0x0401, 0x01}, -+ {0x0401, 0x00}, - {0x0404, 0x00}, -- {0x0405, 0x20}, -- {0x0408, 0x00}, -- {0x0409, 0x00}, -+ {0x0405, 0x10}, -+ {0x0408, 0x01}, -+ {0x0409, 0x5c}, - {0x040a, 0x00}, - {0x040b, 0x00}, -- {0x040c, 0x07}, -- {0x040d, 0xea}, -- {0x040e, 0x02}, -- {0x040f, 0xf8}, -- {0x034c, 0x03}, -- {0x034d, 0xf4}, -- {0x034e, 0x02}, -- {0x034f, 0xf8}, -+ {0x040c, 0x05}, -+ {0x040d, 0x34}, -+ {0x040e, 0x03}, -+ {0x040f, 0xde}, -+ {0x034c, 0x05}, -+ {0x034d, 0x34}, -+ {0x034e, 0x03}, -+ {0x034f, 0xde}, - {0x0301, 0x05}, - {0x0303, 0x02}, - {0x0305, 0x02}, -@@ -870,21 +873,21 @@ static const struct imx477_reg mode_1012 - {0x0822, 0x00}, - {0x0823, 0x00}, - {0x080a, 0x00}, -- {0x080b, 0x6f}, -+ {0x080b, 0x7f}, - {0x080c, 0x00}, -- {0x080d, 0x3f}, -+ {0x080d, 0x4f}, - {0x080e, 0x00}, -- {0x080f, 0xff}, -+ {0x080f, 0x77}, - {0x0810, 0x00}, -- {0x0811, 0x4f}, -+ {0x0811, 0x5f}, - {0x0812, 0x00}, -- {0x0813, 0x47}, -+ {0x0813, 0x57}, - {0x0814, 0x00}, -- {0x0815, 0x37}, -- {0x0816, 0x00}, -- {0x0817, 0xe7}, -+ {0x0815, 0x4f}, -+ {0x0816, 0x01}, -+ {0x0817, 0x27}, - {0x0818, 0x00}, -- {0x0819, 0x2f}, -+ {0x0819, 0x3f}, - {0xe04c, 0x00}, - {0xe04d, 0x5f}, - {0xe04e, 0x00}, -@@ -893,7 +896,7 @@ static const struct imx477_reg mode_1012 - {0x3e37, 0x00}, - {0x3f50, 0x00}, - {0x3f56, 0x00}, -- {0x3f57, 0x96}, -+ {0x3f57, 0xbf}, - }; - - /* Mode configs */ -@@ -974,9 +977,9 @@ static const struct imx477_mode supporte - - static const struct imx477_mode supported_modes_10bit[] = { - { -- /* 720P 120fps. 4x4 binned */ -- .width = 1012, -- .height = 760, -+ /* 120fps. 2x2 binned and cropped */ -+ .width = 1332, -+ .height = 990, - .line_length_pix = 0x1460, - .crop = { - /* -@@ -987,10 +990,10 @@ static const struct imx477_mode supporte - * rectangle once the driver is expanded to represent - * its processing blocks with multiple subdevs. - */ -- .left = IMX477_PIXEL_ARRAY_LEFT + 4, -- .top = IMX477_PIXEL_ARRAY_TOP, -- .width = 4052, -- .height = 3040, -+ .left = IMX477_PIXEL_ARRAY_LEFT + 696, -+ .top = IMX477_PIXEL_ARRAY_TOP + 528, -+ .width = 2664, -+ .height = 1980, - }, - .timeperframe_min = { - .numerator = 100, -@@ -998,11 +1001,11 @@ static const struct imx477_mode supporte - }, - .timeperframe_default = { - .numerator = 100, -- .denominator = 60000 -+ .denominator = 12000 - }, - .reg_list = { -- .num_of_regs = ARRAY_SIZE(mode_1012x760_regs), -- .regs = mode_1012x760_regs, -+ .num_of_regs = ARRAY_SIZE(mode_1332x990_regs), -+ .regs = mode_1332x990_regs, - } - } - }; diff --git a/target/linux/bcm27xx/patches-5.15/950-0350-media-i2c-imx477-Remove-internal-v4l2_mbus_framefmt-.patch b/target/linux/bcm27xx/patches-5.15/950-0350-media-i2c-imx477-Remove-internal-v4l2_mbus_framefmt-.patch deleted file mode 100644 index bfe91581a..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0350-media-i2c-imx477-Remove-internal-v4l2_mbus_framefmt-.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 34bed428fea0d0da58a22365588f7511b491a497 Mon Sep 17 00:00:00 2001 -From: Naushir Patuck -Date: Fri, 19 Feb 2021 10:30:49 +0000 -Subject: [PATCH] media: i2c: imx477: Remove internal - v4l2_mbus_framefmt from the state - -The only field in this struct that is used is the format code, so -replace the struct with this single field. - -Save the format code in imx477_set_pad_format() when setting up a new -mode so that imx477_get_pad_format() performs the right lookup. -Otherwise, this caused a bug where the mode lookup occurred on the -12-bit table rather than the 10-bit table. - -Signed-off-by: Naushir Patuck ---- - drivers/media/i2c/imx477.c | 19 ++++--------------- - 1 file changed, 4 insertions(+), 15 deletions(-) - ---- a/drivers/media/i2c/imx477.c -+++ b/drivers/media/i2c/imx477.c -@@ -1073,7 +1073,7 @@ struct imx477 { - struct v4l2_subdev sd; - struct media_pad pad[NUM_PADS]; - -- struct v4l2_mbus_framefmt fmt; -+ unsigned int fmt_code; - - struct clk *xclk; - u32 xclk_freq; -@@ -1235,21 +1235,9 @@ static u32 imx477_get_format_code(struct - - static void imx477_set_default_format(struct imx477 *imx477) - { -- struct v4l2_mbus_framefmt *fmt = &imx477->fmt; -- - /* Set default mode to max resolution */ - imx477->mode = &supported_modes_12bit[0]; -- -- fmt->code = MEDIA_BUS_FMT_SRGGB12_1X12; -- fmt->colorspace = V4L2_COLORSPACE_SRGB; -- fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace); -- fmt->quantization = V4L2_MAP_QUANTIZATION_DEFAULT(true, -- fmt->colorspace, -- fmt->ycbcr_enc); -- fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt->colorspace); -- fmt->width = imx477->mode->width; -- fmt->height = imx477->mode->height; -- fmt->field = V4L2_FIELD_NONE; -+ imx477->fmt_code = MEDIA_BUS_FMT_SRGGB12_1X12; - } - - static int imx477_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) -@@ -1520,7 +1508,7 @@ static int imx477_get_pad_format(struct - imx477_update_image_pad_format(imx477, imx477->mode, - fmt); - fmt->format.code = -- imx477_get_format_code(imx477, imx477->fmt.code); -+ imx477_get_format_code(imx477, imx477->fmt_code); - } else { - imx477_update_metadata_pad_format(fmt); - } -@@ -1611,6 +1599,7 @@ static int imx477_set_pad_format(struct - *framefmt = fmt->format; - } else { - imx477->mode = mode; -+ imx477->fmt_code = fmt->format.code; - imx477_set_framing_limits(imx477); - } - } else { diff --git a/target/linux/bcm27xx/patches-5.15/950-0351-media-i2c-imx477-Remove-unused-function-parameter.patch b/target/linux/bcm27xx/patches-5.15/950-0351-media-i2c-imx477-Remove-unused-function-parameter.patch deleted file mode 100644 index 580df482b..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0351-media-i2c-imx477-Remove-unused-function-parameter.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 6f4861904ed9838d2f896889f051dfba3e33861e Mon Sep 17 00:00:00 2001 -From: Naushir Patuck -Date: Fri, 19 Feb 2021 11:06:40 +0000 -Subject: [PATCH] media: i2c: imx477: Remove unused function parameter - -The struct imx477 *ctrl parameter is not used in the function -imx477_adjust_exposure_range(), so remove it. - -Signed-off-by: Naushir Patuck ---- - drivers/media/i2c/imx477.c | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - ---- a/drivers/media/i2c/imx477.c -+++ b/drivers/media/i2c/imx477.c -@@ -1276,8 +1276,7 @@ static int imx477_open(struct v4l2_subde - return 0; - } - --static void imx477_adjust_exposure_range(struct imx477 *imx477, -- struct v4l2_ctrl *ctrl) -+static void imx477_adjust_exposure_range(struct imx477 *imx477) - { - int exposure_max, exposure_def; - -@@ -1322,7 +1321,7 @@ static int imx477_set_ctrl(struct v4l2_c - * and adjust if necessary. - */ - if (ctrl->id == V4L2_CID_VBLANK) -- imx477_adjust_exposure_range(imx477, ctrl); -+ imx477_adjust_exposure_range(imx477); - - /* - * Applying V4L2 control value only happens diff --git a/target/linux/bcm27xx/patches-5.15/950-0355-staging-bcm2835-codec-Correct-logging-of-size_t-to-z.patch b/target/linux/bcm27xx/patches-5.15/950-0355-staging-bcm2835-codec-Correct-logging-of-size_t-to-z.patch deleted file mode 100644 index 7313cd29b..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0355-staging-bcm2835-codec-Correct-logging-of-size_t-to-z.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 2a316a52b69d136933a5b22f6f7f93a6f057db7f Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 1 Feb 2021 18:55:37 +0000 -Subject: [PATCH] staging/bcm2835-codec: Correct logging of size_t to - %zu - -Fixes: "staging/bcm2835-codec: Log the number of excess supported formats" -Which used %u for printing a size_t, and 64bit builds then log a warning. - -Signed-off-by: Dave Stevenson ---- - .../staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -2837,7 +2837,7 @@ static int bcm2835_codec_get_supported_f - if (ret) { - if (ret == MMAL_MSG_STATUS_ENOSPC) { - v4l2_err(&dev->v4l2_dev, -- "%s: port has more encodings than we provided space for. Some are dropped (%u vs %u).\n", -+ "%s: port has more encodings than we provided space for. Some are dropped (%zu vs %u).\n", - __func__, param_size / sizeof(u32), - MAX_SUPPORTED_ENCODINGS); - num_encodings = MAX_SUPPORTED_ENCODINGS; -@@ -2883,7 +2883,7 @@ static int bcm2835_codec_get_supported_f - if (ret) { - if (ret == MMAL_MSG_STATUS_ENOSPC) { - v4l2_err(&dev->v4l2_dev, -- "%s: port has more encodings than we provided space for. Some are dropped (%u vs %u).\n", -+ "%s: port has more encodings than we provided space for. Some are dropped (%zu vs %u).\n", - __func__, param_size / sizeof(u32), - MAX_SUPPORTED_ENCODINGS); - num_encodings = MAX_SUPPORTED_ENCODINGS; diff --git a/target/linux/bcm27xx/patches-5.15/950-0356-staging-bcm2835-codec-Add-support-for-pixel-aspect-r.patch b/target/linux/bcm27xx/patches-5.15/950-0356-staging-bcm2835-codec-Add-support-for-pixel-aspect-r.patch deleted file mode 100644 index b431bb76f..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0356-staging-bcm2835-codec-Add-support-for-pixel-aspect-r.patch +++ /dev/null @@ -1,82 +0,0 @@ -From 9fd39b1fe86a26b942fc0ebf2138076758547c44 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 2 Feb 2021 15:50:18 +0000 -Subject: [PATCH] staging/bcm2835-codec: Add support for pixel aspect - ratio - -If the format is detected by the driver and a V4L2_EVENT_SOURCE_CHANGE -event is generated, then pass on the pixel aspect ratio as well. - -Signed-off-by: Dave Stevenson ---- - .../bcm2835-codec/bcm2835-v4l2-codec.c | 31 +++++++++++++++++++ - 1 file changed, 31 insertions(+) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -602,6 +602,7 @@ struct bcm2835_codec_q_data { - unsigned int crop_width; - unsigned int crop_height; - bool selection_set; -+ struct v4l2_fract aspect_ratio; - - unsigned int sizeimage; - unsigned int sequence; -@@ -981,6 +982,9 @@ static void handle_fmt_changed(struct bc - if (format->es.video.color_space) - color_mmal2v4l(ctx, format->es.video.color_space); - -+ q_data->aspect_ratio.numerator = format->es.video.par.num; -+ q_data->aspect_ratio.denominator = format->es.video.par.den; -+ - queue_res_chg_event(ctx); - } - -@@ -1657,6 +1661,29 @@ static int vidioc_g_parm(struct file *fi - return 0; - } - -+static int vidioc_g_pixelaspect(struct file *file, void *fh, int type, -+ struct v4l2_fract *f) -+{ -+ struct bcm2835_codec_ctx *ctx = file2ctx(file); -+ -+ /* -+ * The selection API takes V4L2_BUF_TYPE_VIDEO_CAPTURE and -+ * V4L2_BUF_TYPE_VIDEO_OUTPUT, even if the device implements the MPLANE -+ * API. The V4L2 core will have converted the MPLANE variants to -+ * non-MPLANE. -+ * Open code this instead of using get_q_data in this case. -+ */ -+ if (ctx->dev->role != DECODE) -+ return -ENOIOCTLCMD; -+ -+ if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) -+ return -EINVAL; -+ -+ *f = ctx->q_data[V4L2_M2M_DST].aspect_ratio; -+ -+ return 0; -+} -+ - static int vidioc_subscribe_evt(struct v4l2_fh *fh, - const struct v4l2_event_subscription *sub) - { -@@ -2082,6 +2109,8 @@ static const struct v4l2_ioctl_ops bcm28 - .vidioc_g_parm = vidioc_g_parm, - .vidioc_s_parm = vidioc_s_parm, - -+ .vidioc_g_pixelaspect = vidioc_g_pixelaspect, -+ - .vidioc_subscribe_event = vidioc_subscribe_evt, - .vidioc_unsubscribe_event = v4l2_event_unsubscribe, - -@@ -2640,6 +2669,8 @@ static int bcm2835_codec_open(struct fil - ctx->q_data[V4L2_M2M_DST].crop_width, - ctx->q_data[V4L2_M2M_DST].height, - ctx->q_data[V4L2_M2M_DST].fmt); -+ ctx->q_data[V4L2_M2M_DST].aspect_ratio.numerator = 1; -+ ctx->q_data[V4L2_M2M_DST].aspect_ratio.denominator = 1; - - ctx->colorspace = V4L2_COLORSPACE_REC709; - ctx->bitrate = 10 * 1000 * 1000; diff --git a/target/linux/bcm27xx/patches-5.15/950-0357-staging-bcm2835-codec-Implement-additional-g_selecti.patch b/target/linux/bcm27xx/patches-5.15/950-0357-staging-bcm2835-codec-Implement-additional-g_selecti.patch deleted file mode 100644 index 9c1fa2ba6..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0357-staging-bcm2835-codec-Implement-additional-g_selecti.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 87bb03be2c8ab1db246181ebeaf2588cda3dfd31 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 2 Feb 2021 16:46:39 +0000 -Subject: [PATCH] staging/bcm2835-codec: Implement additional - g_selection calls for decode - -v4l_cropcap calls our vidioc_g_pixelaspect function to get the pixel -aspect ratio, but also calls g_selection for V4L2_SEL_TGT_CROP_BOUNDS -and V4L2_SEL_TGT_CROP_DEFAULT. Whilst it allows for vidioc_g_pixelaspect -not to be implemented, it doesn't allow for either of the other two. - -Add in support for the additional selection targets. - -Signed-off-by: Dave Stevenson ---- - .../vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -1517,6 +1517,14 @@ static int vidioc_g_selection(struct fil - s->r.width = q_data->crop_width; - s->r.height = q_data->crop_height; - break; -+ case V4L2_SEL_TGT_CROP_BOUNDS: -+ case V4L2_SEL_TGT_CROP_DEFAULT: -+ s->r.left = 0; -+ s->r.top = 0; -+ s->r.width = (q_data->bytesperline << 3) / -+ q_data->fmt->depth; -+ s->r.height = q_data->height; -+ break; - default: - return -EINVAL; - } diff --git a/target/linux/bcm27xx/patches-5.15/950-0358-staging-bcm2835-codec-Add-VC-1-support.patch b/target/linux/bcm27xx/patches-5.15/950-0358-staging-bcm2835-codec-Add-VC-1-support.patch deleted file mode 100644 index 25c098210..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0358-staging-bcm2835-codec-Add-VC-1-support.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 0ebb1e9d7c922fb94b149783e46b20974b95a16d Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Wed, 10 Mar 2021 19:07:48 +0000 -Subject: [PATCH] staging/bcm2835-codec: Add VC-1 support. - -Providing the relevant licence has been purchased, then Pi0-3 -can decode VC-1. - -Signed-off-by: Dave Stevenson ---- - .../vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -576,7 +576,12 @@ static const struct bcm2835_codec_fmt su - .depth = 0, - .flags = V4L2_FMT_FLAG_COMPRESSED, - .mmal_fmt = MMAL_ENCODING_VP8, -- }, -+ }, { -+ .fourcc = V4L2_PIX_FMT_VC1_ANNEX_G, -+ .depth = 0, -+ .flags = V4L2_FMT_FLAG_COMPRESSED, -+ .mmal_fmt = MMAL_ENCODING_WVC1, -+ } - }; - - struct bcm2835_codec_fmt_list { diff --git a/target/linux/bcm27xx/patches-5.15/950-0359-hack-fixup-bcm2835-unicam.patch b/target/linux/bcm27xx/patches-5.15/950-0359-hack-fixup-bcm2835-unicam.patch deleted file mode 100644 index c45b4d1bd..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0359-hack-fixup-bcm2835-unicam.patch +++ /dev/null @@ -1,21 +0,0 @@ -From 2320a8d1a847d31ffa678ad61970c138dd626113 Mon Sep 17 00:00:00 2001 -From: Dom Cobley -Date: Wed, 17 Mar 2021 12:45:53 +0000 -Subject: [PATCH] hack: fixup bcm2835-unicam - ---- - drivers/media/platform/bcm2835/bcm2835-unicam.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/drivers/media/platform/bcm2835/bcm2835-unicam.c -+++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c -@@ -72,6 +72,9 @@ - #include - #include - -+#include -+#define v4l2_async_notifier_add_subdev __v4l2_async_notifier_add_subdev -+ - #include "vc4-regs-unicam.h" - - #define UNICAM_MODULE_NAME "unicam" diff --git a/target/linux/bcm27xx/patches-5.15/950-0360-media-i2c-add-ov9281-driver.patch b/target/linux/bcm27xx/patches-5.15/950-0360-media-i2c-add-ov9281-driver.patch deleted file mode 100644 index 7f11a6143..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0360-media-i2c-add-ov9281-driver.patch +++ /dev/null @@ -1,1218 +0,0 @@ -From 2caa809318d62cff46258e8109a904c7b43b9ff7 Mon Sep 17 00:00:00 2001 -From: Zefa Chen -Date: Fri, 17 May 2019 18:23:03 +0800 -Subject: [PATCH] media: i2c: add ov9281 driver. - -Change-Id: I7b77250bbc56d2f861450cf77271ad15f9b88ab1 -Signed-off-by: Zefa Chen ---- - drivers/media/i2c/Kconfig | 11 + - drivers/media/i2c/Makefile | 1 + - drivers/media/i2c/ov9281.c | 1171 ++++++++++++++++++++++++++++++++++++ - 3 files changed, 1183 insertions(+) - create mode 100644 drivers/media/i2c/ov9281.c - ---- a/drivers/media/i2c/Kconfig -+++ b/drivers/media/i2c/Kconfig -@@ -1164,6 +1164,17 @@ config VIDEO_OV9640 - This is a Video4Linux2 sensor driver for the OmniVision - OV9640 camera sensor. - -+config VIDEO_OV9281 -+ tristate "OmniVision OV9281 sensor support" -+ depends on I2C && VIDEO_V4L2 -+ depends on MEDIA_CAMERA_SUPPORT -+ help -+ This is a Video4Linux2 sensor-level driver for the OmniVision -+ OV9281 camera. -+ -+ To compile this driver as a module, choose M here: the -+ module will be called ov9281. -+ - config VIDEO_OV9650 - tristate "OmniVision OV9650/OV9652 sensor support" - depends on I2C && VIDEO_V4L2 ---- a/drivers/media/i2c/Makefile -+++ b/drivers/media/i2c/Makefile -@@ -84,6 +84,7 @@ obj-$(CONFIG_VIDEO_OV772X) += ov772x.o - obj-$(CONFIG_VIDEO_OV7740) += ov7740.o - obj-$(CONFIG_VIDEO_OV8856) += ov8856.o - obj-$(CONFIG_VIDEO_OV8865) += ov8865.o -+obj-$(CONFIG_VIDEO_OV9281) += ov9281.o - obj-$(CONFIG_VIDEO_OV9282) += ov9282.o - obj-$(CONFIG_VIDEO_OV9640) += ov9640.o - obj-$(CONFIG_VIDEO_OV9650) += ov9650.o ---- /dev/null -+++ b/drivers/media/i2c/ov9281.c -@@ -0,0 +1,1171 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * ov9281 driver -+ * -+ * Copyright (C) 2017 Fuzhou Rockchip Electronics Co., Ltd. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x0) -+ -+#ifndef V4L2_CID_DIGITAL_GAIN -+#define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN -+#endif -+ -+#define OV9281_LINK_FREQ_400MHZ 400000000 -+/* pixel rate = link frequency * 2 * lanes / BITS_PER_SAMPLE */ -+#define OV9281_PIXEL_RATE (OV9281_LINK_FREQ_400MHZ * 2 * 2 / 10) -+#define OV9281_XVCLK_FREQ 24000000 -+ -+#define CHIP_ID 0x9281 -+#define OV9281_REG_CHIP_ID 0x300a -+ -+#define OV9281_REG_CTRL_MODE 0x0100 -+#define OV9281_MODE_SW_STANDBY 0x0 -+#define OV9281_MODE_STREAMING BIT(0) -+ -+#define OV9281_REG_EXPOSURE 0x3500 -+#define OV9281_EXPOSURE_MIN 4 -+#define OV9281_EXPOSURE_STEP 1 -+#define OV9281_VTS_MAX 0x7fff -+ -+#define OV9281_REG_GAIN_H 0x3508 -+#define OV9281_REG_GAIN_L 0x3509 -+#define OV9281_GAIN_H_MASK 0x07 -+#define OV9281_GAIN_H_SHIFT 8 -+#define OV9281_GAIN_L_MASK 0xff -+#define OV9281_GAIN_MIN 0x10 -+#define OV9281_GAIN_MAX 0xf8 -+#define OV9281_GAIN_STEP 1 -+#define OV9281_GAIN_DEFAULT 0x10 -+ -+#define OV9281_REG_TEST_PATTERN 0x5e00 -+#define OV9281_TEST_PATTERN_ENABLE 0x80 -+#define OV9281_TEST_PATTERN_DISABLE 0x0 -+ -+#define OV9281_REG_VTS 0x380e -+ -+#define REG_NULL 0xFFFF -+ -+#define OV9281_REG_VALUE_08BIT 1 -+#define OV9281_REG_VALUE_16BIT 2 -+#define OV9281_REG_VALUE_24BIT 3 -+ -+#define OV9281_LANES 2 -+#define OV9281_BITS_PER_SAMPLE 10 -+ -+#define OF_CAMERA_PINCTRL_STATE_DEFAULT "rockchip,camera_default" -+#define OF_CAMERA_PINCTRL_STATE_SLEEP "rockchip,camera_sleep" -+ -+#define OV9281_NAME "ov9281" -+ -+static const char * const ov9281_supply_names[] = { -+ "avdd", /* Analog power */ -+ "dovdd", /* Digital I/O power */ -+ "dvdd", /* Digital core power */ -+}; -+ -+#define OV9281_NUM_SUPPLIES ARRAY_SIZE(ov9281_supply_names) -+ -+struct regval { -+ u16 addr; -+ u8 val; -+}; -+ -+struct ov9281_mode { -+ u32 width; -+ u32 height; -+ u32 max_fps; -+ u32 hts_def; -+ u32 vts_def; -+ u32 exp_def; -+ const struct regval *reg_list; -+}; -+ -+struct ov9281 { -+ struct i2c_client *client; -+ struct clk *xvclk; -+ struct gpio_desc *reset_gpio; -+ struct gpio_desc *pwdn_gpio; -+ struct regulator_bulk_data supplies[OV9281_NUM_SUPPLIES]; -+ -+ struct pinctrl *pinctrl; -+ struct pinctrl_state *pins_default; -+ struct pinctrl_state *pins_sleep; -+ -+ struct v4l2_subdev subdev; -+ struct media_pad pad; -+ struct v4l2_ctrl_handler ctrl_handler; -+ struct v4l2_ctrl *exposure; -+ struct v4l2_ctrl *anal_gain; -+ struct v4l2_ctrl *digi_gain; -+ struct v4l2_ctrl *hblank; -+ struct v4l2_ctrl *vblank; -+ struct v4l2_ctrl *test_pattern; -+ struct mutex mutex; -+ bool streaming; -+ bool power_on; -+ const struct ov9281_mode *cur_mode; -+ u32 module_index; -+ const char *module_facing; -+ const char *module_name; -+ const char *len_name; -+}; -+ -+#define to_ov9281(sd) container_of(sd, struct ov9281, subdev) -+ -+/* -+ * Xclk 24Mhz -+ */ -+static const struct regval ov9281_global_regs[] = { -+ {REG_NULL, 0x00}, -+}; -+ -+/* -+ * Xclk 24Mhz -+ * max_framerate 120fps -+ * mipi_datarate per lane 800Mbps -+ */ -+static const struct regval ov9281_1280x800_regs[] = { -+ {0x0103, 0x01}, -+ {0x0302, 0x32}, -+ {0x030d, 0x50}, -+ {0x030e, 0x02}, -+ {0x3001, 0x00}, -+ {0x3004, 0x00}, -+ {0x3005, 0x00}, -+ {0x3006, 0x04}, -+ {0x3011, 0x0a}, -+ {0x3013, 0x18}, -+ {0x3022, 0x01}, -+ {0x3023, 0x00}, -+ {0x302c, 0x00}, -+ {0x302f, 0x00}, -+ {0x3030, 0x04}, -+ {0x3039, 0x32}, -+ {0x303a, 0x00}, -+ {0x303f, 0x01}, -+ {0x3500, 0x00}, -+ {0x3501, 0x2a}, -+ {0x3502, 0x90}, -+ {0x3503, 0x08}, -+ {0x3505, 0x8c}, -+ {0x3507, 0x03}, -+ {0x3508, 0x00}, -+ {0x3509, 0x10}, -+ {0x3610, 0x80}, -+ {0x3611, 0xa0}, -+ {0x3620, 0x6f}, -+ {0x3632, 0x56}, -+ {0x3633, 0x78}, -+ {0x3662, 0x05}, -+ {0x3666, 0x00}, -+ {0x366f, 0x5a}, -+ {0x3680, 0x84}, -+ {0x3712, 0x80}, -+ {0x372d, 0x22}, -+ {0x3731, 0x80}, -+ {0x3732, 0x30}, -+ {0x3778, 0x00}, -+ {0x377d, 0x22}, -+ {0x3788, 0x02}, -+ {0x3789, 0xa4}, -+ {0x378a, 0x00}, -+ {0x378b, 0x4a}, -+ {0x3799, 0x20}, -+ {0x3800, 0x00}, -+ {0x3801, 0x00}, -+ {0x3802, 0x00}, -+ {0x3803, 0x00}, -+ {0x3804, 0x05}, -+ {0x3805, 0x0f}, -+ {0x3806, 0x03}, -+ {0x3807, 0x2f}, -+ {0x3808, 0x05}, -+ {0x3809, 0x00}, -+ {0x380a, 0x03}, -+ {0x380b, 0x20}, -+ {0x380c, 0x02}, -+ {0x380d, 0xd8}, -+ {0x380e, 0x03}, -+ {0x380f, 0x8e}, -+ {0x3810, 0x00}, -+ {0x3811, 0x08}, -+ {0x3812, 0x00}, -+ {0x3813, 0x08}, -+ {0x3814, 0x11}, -+ {0x3815, 0x11}, -+ {0x3820, 0x40}, -+ {0x3821, 0x00}, -+ {0x3881, 0x42}, -+ {0x38b1, 0x00}, -+ {0x3920, 0xff}, -+ {0x4003, 0x40}, -+ {0x4008, 0x04}, -+ {0x4009, 0x0b}, -+ {0x400c, 0x00}, -+ {0x400d, 0x07}, -+ {0x4010, 0x40}, -+ {0x4043, 0x40}, -+ {0x4307, 0x30}, -+ {0x4317, 0x00}, -+ {0x4501, 0x00}, -+ {0x4507, 0x00}, -+ {0x4509, 0x00}, -+ {0x450a, 0x08}, -+ {0x4601, 0x04}, -+ {0x470f, 0x00}, -+ {0x4f07, 0x00}, -+ {0x4800, 0x00}, -+ {0x5000, 0x9f}, -+ {0x5001, 0x00}, -+ {0x5e00, 0x00}, -+ {0x5d00, 0x07}, -+ {0x5d01, 0x00}, -+ {REG_NULL, 0x00}, -+}; -+ -+static const struct ov9281_mode supported_modes[] = { -+ { -+ .width = 1280, -+ .height = 800, -+ .max_fps = 120, -+ .exp_def = 0x0320, -+ .hts_def = 0x0b60,//0x2d8*4 -+ .vts_def = 0x038e, -+ .reg_list = ov9281_1280x800_regs, -+ }, -+}; -+ -+static const s64 link_freq_menu_items[] = { -+ OV9281_LINK_FREQ_400MHZ -+}; -+ -+static const char * const ov9281_test_pattern_menu[] = { -+ "Disabled", -+ "Vertical Color Bar Type 1", -+ "Vertical Color Bar Type 2", -+ "Vertical Color Bar Type 3", -+ "Vertical Color Bar Type 4" -+}; -+ -+/* Write registers up to 4 at a time */ -+static int ov9281_write_reg(struct i2c_client *client, u16 reg, -+ u32 len, u32 val) -+{ -+ u32 buf_i, val_i; -+ u8 buf[6]; -+ u8 *val_p; -+ __be32 val_be; -+ -+ if (len > 4) -+ return -EINVAL; -+ -+ buf[0] = reg >> 8; -+ buf[1] = reg & 0xff; -+ -+ val_be = cpu_to_be32(val); -+ val_p = (u8 *)&val_be; -+ buf_i = 2; -+ val_i = 4 - len; -+ -+ while (val_i < 4) -+ buf[buf_i++] = val_p[val_i++]; -+ -+ if (i2c_master_send(client, buf, len + 2) != len + 2) -+ return -EIO; -+ -+ return 0; -+} -+ -+static int ov9281_write_array(struct i2c_client *client, -+ const struct regval *regs) -+{ -+ u32 i; -+ int ret = 0; -+ -+ for (i = 0; ret == 0 && regs[i].addr != REG_NULL; i++) -+ ret = ov9281_write_reg(client, regs[i].addr, -+ OV9281_REG_VALUE_08BIT, regs[i].val); -+ -+ return ret; -+} -+ -+/* Read registers up to 4 at a time */ -+static int ov9281_read_reg(struct i2c_client *client, u16 reg, unsigned int len, -+ u32 *val) -+{ -+ struct i2c_msg msgs[2]; -+ u8 *data_be_p; -+ __be32 data_be = 0; -+ __be16 reg_addr_be = cpu_to_be16(reg); -+ int ret; -+ -+ if (len > 4 || !len) -+ return -EINVAL; -+ -+ data_be_p = (u8 *)&data_be; -+ /* Write register address */ -+ msgs[0].addr = client->addr; -+ msgs[0].flags = 0; -+ msgs[0].len = 2; -+ msgs[0].buf = (u8 *)®_addr_be; -+ -+ /* Read data from register */ -+ msgs[1].addr = client->addr; -+ msgs[1].flags = I2C_M_RD; -+ msgs[1].len = len; -+ msgs[1].buf = &data_be_p[4 - len]; -+ -+ ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); -+ if (ret != ARRAY_SIZE(msgs)) -+ return -EIO; -+ -+ *val = be32_to_cpu(data_be); -+ -+ return 0; -+} -+ -+static int ov9281_get_reso_dist(const struct ov9281_mode *mode, -+ struct v4l2_mbus_framefmt *framefmt) -+{ -+ return abs(mode->width - framefmt->width) + -+ abs(mode->height - framefmt->height); -+} -+ -+static const struct ov9281_mode * -+ov9281_find_best_fit(struct v4l2_subdev_format *fmt) -+{ -+ struct v4l2_mbus_framefmt *framefmt = &fmt->format; -+ int dist; -+ int cur_best_fit = 0; -+ int cur_best_fit_dist = -1; -+ unsigned int i; -+ -+ for (i = 0; i < ARRAY_SIZE(supported_modes); i++) { -+ dist = ov9281_get_reso_dist(&supported_modes[i], framefmt); -+ if (cur_best_fit_dist == -1 || dist < cur_best_fit_dist) { -+ cur_best_fit_dist = dist; -+ cur_best_fit = i; -+ } -+ } -+ -+ return &supported_modes[cur_best_fit]; -+} -+ -+static int ov9281_set_fmt(struct v4l2_subdev *sd, -+ struct v4l2_subdev_pad_config *cfg, -+ struct v4l2_subdev_format *fmt) -+{ -+ struct ov9281 *ov9281 = to_ov9281(sd); -+ const struct ov9281_mode *mode; -+ s64 h_blank, vblank_def; -+ -+ mutex_lock(&ov9281->mutex); -+ -+ mode = ov9281_find_best_fit(fmt); -+ fmt->format.code = MEDIA_BUS_FMT_Y10_1X10; -+ fmt->format.width = mode->width; -+ fmt->format.height = mode->height; -+ fmt->format.field = V4L2_FIELD_NONE; -+ if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { -+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API -+ *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format; -+#else -+ mutex_unlock(&ov9281->mutex); -+ return -ENOTTY; -+#endif -+ } else { -+ ov9281->cur_mode = mode; -+ h_blank = mode->hts_def - mode->width; -+ __v4l2_ctrl_modify_range(ov9281->hblank, h_blank, -+ h_blank, 1, h_blank); -+ vblank_def = mode->vts_def - mode->height; -+ __v4l2_ctrl_modify_range(ov9281->vblank, vblank_def, -+ OV9281_VTS_MAX - mode->height, -+ 1, vblank_def); -+ } -+ -+ mutex_unlock(&ov9281->mutex); -+ -+ return 0; -+} -+ -+static int ov9281_get_fmt(struct v4l2_subdev *sd, -+ struct v4l2_subdev_pad_config *cfg, -+ struct v4l2_subdev_format *fmt) -+{ -+ struct ov9281 *ov9281 = to_ov9281(sd); -+ const struct ov9281_mode *mode = ov9281->cur_mode; -+ -+ mutex_lock(&ov9281->mutex); -+ if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { -+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API -+ fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad); -+#else -+ mutex_unlock(&ov9281->mutex); -+ return -ENOTTY; -+#endif -+ } else { -+ fmt->format.width = mode->width; -+ fmt->format.height = mode->height; -+ fmt->format.code = MEDIA_BUS_FMT_Y10_1X10; -+ fmt->format.field = V4L2_FIELD_NONE; -+ } -+ mutex_unlock(&ov9281->mutex); -+ -+ return 0; -+} -+ -+static int ov9281_enum_mbus_code(struct v4l2_subdev *sd, -+ struct v4l2_subdev_pad_config *cfg, -+ struct v4l2_subdev_mbus_code_enum *code) -+{ -+ if (code->index != 0) -+ return -EINVAL; -+ code->code = MEDIA_BUS_FMT_Y10_1X10; -+ -+ return 0; -+} -+ -+static int ov9281_enum_frame_sizes(struct v4l2_subdev *sd, -+ struct v4l2_subdev_pad_config *cfg, -+ struct v4l2_subdev_frame_size_enum *fse) -+{ -+ if (fse->index >= ARRAY_SIZE(supported_modes)) -+ return -EINVAL; -+ -+ if (fse->code != MEDIA_BUS_FMT_Y10_1X10) -+ return -EINVAL; -+ -+ fse->min_width = supported_modes[fse->index].width; -+ fse->max_width = supported_modes[fse->index].width; -+ fse->max_height = supported_modes[fse->index].height; -+ fse->min_height = supported_modes[fse->index].height; -+ -+ return 0; -+} -+ -+static int ov9281_enable_test_pattern(struct ov9281 *ov9281, u32 pattern) -+{ -+ u32 val; -+ -+ if (pattern) -+ val = (pattern - 1) | OV9281_TEST_PATTERN_ENABLE; -+ else -+ val = OV9281_TEST_PATTERN_DISABLE; -+ -+ return ov9281_write_reg(ov9281->client, OV9281_REG_TEST_PATTERN, -+ OV9281_REG_VALUE_08BIT, val); -+} -+ -+static int OV9281_g_frame_interval(struct v4l2_subdev *sd, -+ struct v4l2_subdev_frame_interval *fi) -+{ -+ struct ov9281 *ov9281 = to_ov9281(sd); -+ const struct ov9281_mode *mode = ov9281->cur_mode; -+ -+ mutex_lock(&ov9281->mutex); -+ fi->interval.numerator = 10000; -+ fi->interval.denominator = mode->max_fps * 10000; -+ mutex_unlock(&ov9281->mutex); -+ -+ return 0; -+} -+ -+static void ov9281_get_module_inf(struct ov9281 *ov9281, -+ struct rkmodule_inf *inf) -+{ -+ memset(inf, 0, sizeof(*inf)); -+ strlcpy(inf->base.sensor, OV9281_NAME, sizeof(inf->base.sensor)); -+ strlcpy(inf->base.module, ov9281->module_name, -+ sizeof(inf->base.module)); -+ strlcpy(inf->base.lens, ov9281->len_name, sizeof(inf->base.lens)); -+} -+ -+static long ov9281_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) -+{ -+ struct ov9281 *ov9281 = to_ov9281(sd); -+ long ret = 0; -+ -+ switch (cmd) { -+ case RKMODULE_GET_MODULE_INFO: -+ ov9281_get_module_inf(ov9281, (struct rkmodule_inf *)arg); -+ break; -+ default: -+ ret = -ENOIOCTLCMD; -+ break; -+ } -+ -+ return ret; -+} -+ -+#ifdef CONFIG_COMPAT -+static long ov9281_compat_ioctl32(struct v4l2_subdev *sd, -+ unsigned int cmd, unsigned long arg) -+{ -+ void __user *up = compat_ptr(arg); -+ struct rkmodule_inf *inf; -+ struct rkmodule_awb_cfg *cfg; -+ long ret; -+ -+ switch (cmd) { -+ case RKMODULE_GET_MODULE_INFO: -+ inf = kzalloc(sizeof(*inf), GFP_KERNEL); -+ if (!inf) { -+ ret = -ENOMEM; -+ return ret; -+ } -+ -+ ret = ov9281_ioctl(sd, cmd, inf); -+ if (!ret) -+ ret = copy_to_user(up, inf, sizeof(*inf)); -+ kfree(inf); -+ break; -+ case RKMODULE_AWB_CFG: -+ cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); -+ if (!cfg) { -+ ret = -ENOMEM; -+ return ret; -+ } -+ -+ ret = copy_from_user(cfg, up, sizeof(*cfg)); -+ if (!ret) -+ ret = ov9281_ioctl(sd, cmd, cfg); -+ kfree(cfg); -+ break; -+ default: -+ ret = -ENOIOCTLCMD; -+ break; -+ } -+ -+ return ret; -+} -+#endif -+ -+static int __ov9281_start_stream(struct ov9281 *ov9281) -+{ -+ int ret; -+ -+ ret = ov9281_write_array(ov9281->client, ov9281->cur_mode->reg_list); -+ if (ret) -+ return ret; -+ -+ /* In case these controls are set before streaming */ -+ mutex_unlock(&ov9281->mutex); -+ ret = v4l2_ctrl_handler_setup(&ov9281->ctrl_handler); -+ mutex_lock(&ov9281->mutex); -+ if (ret) -+ return ret; -+ -+ return ov9281_write_reg(ov9281->client, OV9281_REG_CTRL_MODE, -+ OV9281_REG_VALUE_08BIT, OV9281_MODE_STREAMING); -+} -+ -+static int __ov9281_stop_stream(struct ov9281 *ov9281) -+{ -+ return ov9281_write_reg(ov9281->client, OV9281_REG_CTRL_MODE, -+ OV9281_REG_VALUE_08BIT, OV9281_MODE_SW_STANDBY); -+} -+ -+static int ov9281_s_stream(struct v4l2_subdev *sd, int on) -+{ -+ struct ov9281 *ov9281 = to_ov9281(sd); -+ struct i2c_client *client = ov9281->client; -+ int ret = 0; -+ -+ mutex_lock(&ov9281->mutex); -+ on = !!on; -+ if (on == ov9281->streaming) -+ goto unlock_and_return; -+ -+ if (on) { -+ ret = pm_runtime_get_sync(&client->dev); -+ if (ret < 0) { -+ pm_runtime_put_noidle(&client->dev); -+ goto unlock_and_return; -+ } -+ -+ ret = __ov9281_start_stream(ov9281); -+ if (ret) { -+ v4l2_err(sd, "start stream failed while write regs\n"); -+ pm_runtime_put(&client->dev); -+ goto unlock_and_return; -+ } -+ } else { -+ __ov9281_stop_stream(ov9281); -+ pm_runtime_put(&client->dev); -+ } -+ -+ ov9281->streaming = on; -+ -+unlock_and_return: -+ mutex_unlock(&ov9281->mutex); -+ -+ return ret; -+} -+ -+static int ov9281_s_power(struct v4l2_subdev *sd, int on) -+{ -+ struct ov9281 *ov9281 = to_ov9281(sd); -+ struct i2c_client *client = ov9281->client; -+ int ret = 0; -+ -+ mutex_lock(&ov9281->mutex); -+ -+ /* If the power state is not modified - no work to do. */ -+ if (ov9281->power_on == !!on) -+ goto unlock_and_return; -+ -+ if (on) { -+ ret = pm_runtime_get_sync(&client->dev); -+ if (ret < 0) { -+ pm_runtime_put_noidle(&client->dev); -+ goto unlock_and_return; -+ } -+ ret = ov9281_write_array(ov9281->client, ov9281_global_regs); -+ if (ret) { -+ v4l2_err(sd, "could not set init registers\n"); -+ pm_runtime_put_noidle(&client->dev); -+ goto unlock_and_return; -+ } -+ ov9281->power_on = true; -+ } else { -+ pm_runtime_put(&client->dev); -+ ov9281->power_on = false; -+ } -+ -+unlock_and_return: -+ mutex_unlock(&ov9281->mutex); -+ -+ return ret; -+} -+ -+/* Calculate the delay in us by clock rate and clock cycles */ -+static inline u32 ov9281_cal_delay(u32 cycles) -+{ -+ return DIV_ROUND_UP(cycles, OV9281_XVCLK_FREQ / 1000 / 1000); -+} -+ -+static int __ov9281_power_on(struct ov9281 *ov9281) -+{ -+ int ret; -+ u32 delay_us; -+ struct device *dev = &ov9281->client->dev; -+ -+ if (!IS_ERR_OR_NULL(ov9281->pins_default)) { -+ ret = pinctrl_select_state(ov9281->pinctrl, -+ ov9281->pins_default); -+ if (ret < 0) -+ dev_err(dev, "could not set pins\n"); -+ } -+ -+ ret = clk_prepare_enable(ov9281->xvclk); -+ if (ret < 0) { -+ dev_err(dev, "Failed to enable xvclk\n"); -+ return ret; -+ } -+ -+ if (!IS_ERR(ov9281->reset_gpio)) -+ gpiod_set_value_cansleep(ov9281->reset_gpio, 0); -+ -+ ret = regulator_bulk_enable(OV9281_NUM_SUPPLIES, ov9281->supplies); -+ if (ret < 0) { -+ dev_err(dev, "Failed to enable regulators\n"); -+ goto disable_clk; -+ } -+ -+ if (!IS_ERR(ov9281->reset_gpio)) -+ gpiod_set_value_cansleep(ov9281->reset_gpio, 1); -+ -+ usleep_range(500, 1000); -+ if (!IS_ERR(ov9281->pwdn_gpio)) -+ gpiod_set_value_cansleep(ov9281->pwdn_gpio, 1); -+ -+ /* 8192 cycles prior to first SCCB transaction */ -+ delay_us = ov9281_cal_delay(8192); -+ usleep_range(delay_us, delay_us * 2); -+ -+ return 0; -+ -+disable_clk: -+ clk_disable_unprepare(ov9281->xvclk); -+ -+ return ret; -+} -+ -+static void __ov9281_power_off(struct ov9281 *ov9281) -+{ -+ int ret; -+ struct device *dev = &ov9281->client->dev; -+ -+ if (!IS_ERR(ov9281->pwdn_gpio)) -+ gpiod_set_value_cansleep(ov9281->pwdn_gpio, 0); -+ clk_disable_unprepare(ov9281->xvclk); -+ if (!IS_ERR(ov9281->reset_gpio)) -+ gpiod_set_value_cansleep(ov9281->reset_gpio, 0); -+ if (!IS_ERR_OR_NULL(ov9281->pins_sleep)) { -+ ret = pinctrl_select_state(ov9281->pinctrl, -+ ov9281->pins_sleep); -+ if (ret < 0) -+ dev_dbg(dev, "could not set pins\n"); -+ } -+ regulator_bulk_disable(OV9281_NUM_SUPPLIES, ov9281->supplies); -+} -+ -+static int ov9281_runtime_resume(struct device *dev) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ struct v4l2_subdev *sd = i2c_get_clientdata(client); -+ struct ov9281 *ov9281 = to_ov9281(sd); -+ -+ return __ov9281_power_on(ov9281); -+} -+ -+static int ov9281_runtime_suspend(struct device *dev) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ struct v4l2_subdev *sd = i2c_get_clientdata(client); -+ struct ov9281 *ov9281 = to_ov9281(sd); -+ -+ __ov9281_power_off(ov9281); -+ -+ return 0; -+} -+ -+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API -+static int ov9281_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) -+{ -+ struct ov9281 *ov9281 = to_ov9281(sd); -+ struct v4l2_mbus_framefmt *try_fmt = -+ v4l2_subdev_get_try_format(sd, fh->pad, 0); -+ const struct ov9281_mode *def_mode = &supported_modes[0]; -+ -+ mutex_lock(&ov9281->mutex); -+ /* Initialize try_fmt */ -+ try_fmt->width = def_mode->width; -+ try_fmt->height = def_mode->height; -+ try_fmt->code = MEDIA_BUS_FMT_Y10_1X10; -+ try_fmt->field = V4L2_FIELD_NONE; -+ -+ mutex_unlock(&ov9281->mutex); -+ /* No crop or compose */ -+ -+ return 0; -+} -+#endif -+ -+static const struct dev_pm_ops ov9281_pm_ops = { -+ SET_RUNTIME_PM_OPS(ov9281_runtime_suspend, -+ ov9281_runtime_resume, NULL) -+}; -+ -+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API -+static const struct v4l2_subdev_internal_ops ov9281_internal_ops = { -+ .open = ov9281_open, -+}; -+#endif -+ -+static const struct v4l2_subdev_core_ops ov9281_core_ops = { -+ .s_power = ov9281_s_power, -+ .ioctl = ov9281_ioctl, -+#ifdef CONFIG_COMPAT -+ .compat_ioctl32 = ov9281_compat_ioctl32, -+#endif -+}; -+ -+static const struct v4l2_subdev_video_ops ov9281_video_ops = { -+ .s_stream = ov9281_s_stream, -+ .g_frame_interval = OV9281_g_frame_interval, -+}; -+ -+static const struct v4l2_subdev_pad_ops ov9281_pad_ops = { -+ .enum_mbus_code = ov9281_enum_mbus_code, -+ .enum_frame_size = ov9281_enum_frame_sizes, -+ .get_fmt = ov9281_get_fmt, -+ .set_fmt = ov9281_set_fmt, -+}; -+ -+static const struct v4l2_subdev_ops ov9281_subdev_ops = { -+ .core = &ov9281_core_ops, -+ .video = &ov9281_video_ops, -+ .pad = &ov9281_pad_ops, -+}; -+ -+static int ov9281_set_ctrl(struct v4l2_ctrl *ctrl) -+{ -+ struct ov9281 *ov9281 = container_of(ctrl->handler, -+ struct ov9281, ctrl_handler); -+ struct i2c_client *client = ov9281->client; -+ s64 max; -+ int ret = 0; -+ -+ /* Propagate change of current control to all related controls */ -+ switch (ctrl->id) { -+ case V4L2_CID_VBLANK: -+ /* Update max exposure while meeting expected vblanking */ -+ max = ov9281->cur_mode->height + ctrl->val - 4; -+ __v4l2_ctrl_modify_range(ov9281->exposure, -+ ov9281->exposure->minimum, max, -+ ov9281->exposure->step, -+ ov9281->exposure->default_value); -+ break; -+ } -+ -+ if (pm_runtime_get(&client->dev) <= 0) -+ return 0; -+ -+ switch (ctrl->id) { -+ case V4L2_CID_EXPOSURE: -+ /* 4 least significant bits of expsoure are fractional part */ -+ ret = ov9281_write_reg(ov9281->client, OV9281_REG_EXPOSURE, -+ OV9281_REG_VALUE_24BIT, ctrl->val << 4); -+ break; -+ case V4L2_CID_ANALOGUE_GAIN: -+ ret = ov9281_write_reg(ov9281->client, OV9281_REG_GAIN_H, -+ OV9281_REG_VALUE_08BIT, -+ (ctrl->val >> OV9281_GAIN_H_SHIFT) & OV9281_GAIN_H_MASK); -+ ret |= ov9281_write_reg(ov9281->client, OV9281_REG_GAIN_L, -+ OV9281_REG_VALUE_08BIT, -+ ctrl->val & OV9281_GAIN_L_MASK); -+ break; -+ case V4L2_CID_VBLANK: -+ ret = ov9281_write_reg(ov9281->client, OV9281_REG_VTS, -+ OV9281_REG_VALUE_16BIT, -+ ctrl->val + ov9281->cur_mode->height); -+ break; -+ case V4L2_CID_TEST_PATTERN: -+ ret = ov9281_enable_test_pattern(ov9281, ctrl->val); -+ break; -+ default: -+ dev_warn(&client->dev, "%s Unhandled id:0x%x, val:0x%x\n", -+ __func__, ctrl->id, ctrl->val); -+ break; -+ } -+ -+ pm_runtime_put(&client->dev); -+ -+ return ret; -+} -+ -+static const struct v4l2_ctrl_ops ov9281_ctrl_ops = { -+ .s_ctrl = ov9281_set_ctrl, -+}; -+ -+static int ov9281_initialize_controls(struct ov9281 *ov9281) -+{ -+ const struct ov9281_mode *mode; -+ struct v4l2_ctrl_handler *handler; -+ struct v4l2_ctrl *ctrl; -+ s64 exposure_max, vblank_def; -+ u32 h_blank; -+ int ret; -+ -+ handler = &ov9281->ctrl_handler; -+ mode = ov9281->cur_mode; -+ ret = v4l2_ctrl_handler_init(handler, 8); -+ if (ret) -+ return ret; -+ handler->lock = &ov9281->mutex; -+ -+ ctrl = v4l2_ctrl_new_int_menu(handler, NULL, V4L2_CID_LINK_FREQ, -+ 0, 0, link_freq_menu_items); -+ if (ctrl) -+ ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; -+ -+ v4l2_ctrl_new_std(handler, NULL, V4L2_CID_PIXEL_RATE, -+ 0, OV9281_PIXEL_RATE, 1, OV9281_PIXEL_RATE); -+ -+ h_blank = mode->hts_def - mode->width; -+ ov9281->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK, -+ h_blank, h_blank, 1, h_blank); -+ if (ov9281->hblank) -+ ov9281->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; -+ -+ vblank_def = mode->vts_def - mode->height; -+ ov9281->vblank = v4l2_ctrl_new_std(handler, &ov9281_ctrl_ops, -+ V4L2_CID_VBLANK, vblank_def, -+ OV9281_VTS_MAX - mode->height, -+ 1, vblank_def); -+ -+ exposure_max = mode->vts_def - 4; -+ ov9281->exposure = v4l2_ctrl_new_std(handler, &ov9281_ctrl_ops, -+ V4L2_CID_EXPOSURE, OV9281_EXPOSURE_MIN, -+ exposure_max, OV9281_EXPOSURE_STEP, -+ mode->exp_def); -+ -+ ov9281->anal_gain = v4l2_ctrl_new_std(handler, &ov9281_ctrl_ops, -+ V4L2_CID_ANALOGUE_GAIN, OV9281_GAIN_MIN, -+ OV9281_GAIN_MAX, OV9281_GAIN_STEP, -+ OV9281_GAIN_DEFAULT); -+ -+ ov9281->test_pattern = v4l2_ctrl_new_std_menu_items(handler, -+ &ov9281_ctrl_ops, V4L2_CID_TEST_PATTERN, -+ ARRAY_SIZE(ov9281_test_pattern_menu) - 1, -+ 0, 0, ov9281_test_pattern_menu); -+ -+ if (handler->error) { -+ ret = handler->error; -+ dev_err(&ov9281->client->dev, -+ "Failed to init controls(%d)\n", ret); -+ goto err_free_handler; -+ } -+ -+ ov9281->subdev.ctrl_handler = handler; -+ -+ return 0; -+ -+err_free_handler: -+ v4l2_ctrl_handler_free(handler); -+ -+ return ret; -+} -+ -+static int ov9281_check_sensor_id(struct ov9281 *ov9281, -+ struct i2c_client *client) -+{ -+ struct device *dev = &ov9281->client->dev; -+ u32 id = 0; -+ int ret; -+ -+ ret = ov9281_read_reg(client, OV9281_REG_CHIP_ID, -+ OV9281_REG_VALUE_16BIT, &id); -+ if (id != CHIP_ID) { -+ dev_err(dev, "Unexpected sensor id(%06x), ret(%d)\n", id, ret); -+ return -ENODEV; -+ } -+ -+ dev_info(dev, "Detected OV%06x sensor\n", CHIP_ID); -+ -+ return 0; -+} -+ -+static int ov9281_configure_regulators(struct ov9281 *ov9281) -+{ -+ unsigned int i; -+ -+ for (i = 0; i < OV9281_NUM_SUPPLIES; i++) -+ ov9281->supplies[i].supply = ov9281_supply_names[i]; -+ -+ return devm_regulator_bulk_get(&ov9281->client->dev, -+ OV9281_NUM_SUPPLIES, -+ ov9281->supplies); -+} -+ -+static int ov9281_probe(struct i2c_client *client, -+ const struct i2c_device_id *id) -+{ -+ struct device *dev = &client->dev; -+ struct device_node *node = dev->of_node; -+ struct ov9281 *ov9281; -+ struct v4l2_subdev *sd; -+ char facing[2]; -+ int ret; -+ -+ dev_info(dev, "driver version: %02x.%02x.%02x", -+ DRIVER_VERSION >> 16, -+ (DRIVER_VERSION & 0xff00) >> 8, -+ DRIVER_VERSION & 0x00ff); -+ -+ ov9281 = devm_kzalloc(dev, sizeof(*ov9281), GFP_KERNEL); -+ if (!ov9281) -+ return -ENOMEM; -+ -+ ret = of_property_read_u32(node, RKMODULE_CAMERA_MODULE_INDEX, -+ &ov9281->module_index); -+ ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_FACING, -+ &ov9281->module_facing); -+ ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_NAME, -+ &ov9281->module_name); -+ ret |= of_property_read_string(node, RKMODULE_CAMERA_LENS_NAME, -+ &ov9281->len_name); -+ if (ret) { -+ dev_err(dev, "could not get module information!\n"); -+ return -EINVAL; -+ } -+ -+ ov9281->client = client; -+ ov9281->cur_mode = &supported_modes[0]; -+ -+ ov9281->xvclk = devm_clk_get(dev, "xvclk"); -+ if (IS_ERR(ov9281->xvclk)) { -+ dev_err(dev, "Failed to get xvclk\n"); -+ return -EINVAL; -+ } -+ ret = clk_set_rate(ov9281->xvclk, OV9281_XVCLK_FREQ); -+ if (ret < 0) { -+ dev_err(dev, "Failed to set xvclk rate (24MHz)\n"); -+ return ret; -+ } -+ if (clk_get_rate(ov9281->xvclk) != OV9281_XVCLK_FREQ) -+ dev_warn(dev, "xvclk mismatched, modes are based on 24MHz\n"); -+ -+ ov9281->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); -+ if (IS_ERR(ov9281->reset_gpio)) -+ dev_warn(dev, "Failed to get reset-gpios\n"); -+ -+ ov9281->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW); -+ if (IS_ERR(ov9281->pwdn_gpio)) -+ dev_warn(dev, "Failed to get pwdn-gpios\n"); -+ -+ ov9281->pinctrl = devm_pinctrl_get(dev); -+ if (!IS_ERR(ov9281->pinctrl)) { -+ ov9281->pins_default = -+ pinctrl_lookup_state(ov9281->pinctrl, -+ OF_CAMERA_PINCTRL_STATE_DEFAULT); -+ if (IS_ERR(ov9281->pins_default)) -+ dev_err(dev, "could not get default pinstate\n"); -+ -+ ov9281->pins_sleep = -+ pinctrl_lookup_state(ov9281->pinctrl, -+ OF_CAMERA_PINCTRL_STATE_SLEEP); -+ if (IS_ERR(ov9281->pins_sleep)) -+ dev_err(dev, "could not get sleep pinstate\n"); -+ } else { -+ dev_err(dev, "no pinctrl\n"); -+ } -+ -+ ret = ov9281_configure_regulators(ov9281); -+ if (ret) { -+ dev_err(dev, "Failed to get power regulators\n"); -+ return ret; -+ } -+ -+ mutex_init(&ov9281->mutex); -+ -+ sd = &ov9281->subdev; -+ v4l2_i2c_subdev_init(sd, client, &ov9281_subdev_ops); -+ ret = ov9281_initialize_controls(ov9281); -+ if (ret) -+ goto err_destroy_mutex; -+ -+ ret = __ov9281_power_on(ov9281); -+ if (ret) -+ goto err_free_handler; -+ -+ ret = ov9281_check_sensor_id(ov9281, client); -+ if (ret) -+ goto err_power_off; -+ -+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API -+ sd->internal_ops = &ov9281_internal_ops; -+ sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; -+#endif -+#if defined(CONFIG_MEDIA_CONTROLLER) -+ ov9281->pad.flags = MEDIA_PAD_FL_SOURCE; -+ sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; -+ ret = media_entity_init(&sd->entity, 1, &ov9281->pad, 0); -+ if (ret < 0) -+ goto err_power_off; -+#endif -+ -+ memset(facing, 0, sizeof(facing)); -+ if (strcmp(ov9281->module_facing, "back") == 0) -+ facing[0] = 'b'; -+ else -+ facing[0] = 'f'; -+ -+ snprintf(sd->name, sizeof(sd->name), "m%02d_%s_%s %s", -+ ov9281->module_index, facing, -+ OV9281_NAME, dev_name(sd->dev)); -+ ret = v4l2_async_register_subdev_sensor(sd); -+ if (ret) { -+ dev_err(dev, "v4l2 async register subdev failed\n"); -+ goto err_clean_entity; -+ } -+ -+ pm_runtime_set_active(dev); -+ pm_runtime_enable(dev); -+ pm_runtime_idle(dev); -+ -+ return 0; -+ -+err_clean_entity: -+#if defined(CONFIG_MEDIA_CONTROLLER) -+ media_entity_cleanup(&sd->entity); -+#endif -+err_power_off: -+ __ov9281_power_off(ov9281); -+err_free_handler: -+ v4l2_ctrl_handler_free(&ov9281->ctrl_handler); -+err_destroy_mutex: -+ mutex_destroy(&ov9281->mutex); -+ -+ return ret; -+} -+ -+static int ov9281_remove(struct i2c_client *client) -+{ -+ struct v4l2_subdev *sd = i2c_get_clientdata(client); -+ struct ov9281 *ov9281 = to_ov9281(sd); -+ -+ v4l2_async_unregister_subdev(sd); -+#if defined(CONFIG_MEDIA_CONTROLLER) -+ media_entity_cleanup(&sd->entity); -+#endif -+ v4l2_ctrl_handler_free(&ov9281->ctrl_handler); -+ mutex_destroy(&ov9281->mutex); -+ -+ pm_runtime_disable(&client->dev); -+ if (!pm_runtime_status_suspended(&client->dev)) -+ __ov9281_power_off(ov9281); -+ pm_runtime_set_suspended(&client->dev); -+ -+ return 0; -+} -+ -+#if IS_ENABLED(CONFIG_OF) -+static const struct of_device_id ov9281_of_match[] = { -+ { .compatible = "ovti,ov9281" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, ov9281_of_match); -+#endif -+ -+static const struct i2c_device_id ov9281_match_id[] = { -+ { "ovti,ov9281", 0 }, -+ { }, -+}; -+ -+static struct i2c_driver ov9281_i2c_driver = { -+ .driver = { -+ .name = OV9281_NAME, -+ .pm = &ov9281_pm_ops, -+ .of_match_table = of_match_ptr(ov9281_of_match), -+ }, -+ .probe = &ov9281_probe, -+ .remove = &ov9281_remove, -+ .id_table = ov9281_match_id, -+}; -+ -+static int __init sensor_mod_init(void) -+{ -+ return i2c_add_driver(&ov9281_i2c_driver); -+} -+ -+static void __exit sensor_mod_exit(void) -+{ -+ i2c_del_driver(&ov9281_i2c_driver); -+} -+ -+device_initcall_sync(sensor_mod_init); -+module_exit(sensor_mod_exit); -+ -+MODULE_DESCRIPTION("OmniVision ov9281 sensor driver"); -+MODULE_LICENSE("GPL v2"); diff --git a/target/linux/bcm27xx/patches-5.15/950-0361-media-i2c-ov9281-fix-mclk-issue-when-probe-multiple-.patch b/target/linux/bcm27xx/patches-5.15/950-0361-media-i2c-ov9281-fix-mclk-issue-when-probe-multiple-.patch deleted file mode 100644 index 170327882..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0361-media-i2c-ov9281-fix-mclk-issue-when-probe-multiple-.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 9c9fb7cc79522452903f48f6f57b9fd83ad3f4ec Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 14 Apr 2020 15:47:09 +0100 -Subject: [PATCH] media: i2c: ov9281: fix mclk issue when probe - multiple camera. - -Takes the ov9281 part only from the Rockchip's patch. - -Change-Id: I30e833baf2c1bb07d6d87ddb3b00759ab45a90e4 -Signed-off-by: Zefa Chen ---- - drivers/media/i2c/ov9281.c | 16 ++++++++-------- - 1 file changed, 8 insertions(+), 8 deletions(-) - ---- a/drivers/media/i2c/ov9281.c -+++ b/drivers/media/i2c/ov9281.c -@@ -3,6 +3,7 @@ - * ov9281 driver - * - * Copyright (C) 2017 Fuzhou Rockchip Electronics Co., Ltd. -+ * V0.0X01.0X02 fix mclk issue when probe multiple camera. - */ - - #include -@@ -22,7 +23,7 @@ - #include - #include - --#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x0) -+#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x2) - - #ifndef V4L2_CID_DIGITAL_GAIN - #define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN -@@ -676,6 +677,12 @@ static int __ov9281_power_on(struct ov92 - dev_err(dev, "could not set pins\n"); - } - -+ ret = clk_set_rate(ov9281->xvclk, OV9281_XVCLK_FREQ); -+ if (ret < 0) -+ dev_warn(dev, "Failed to set xvclk rate (24MHz)\n"); -+ if (clk_get_rate(ov9281->xvclk) != OV9281_XVCLK_FREQ) -+ dev_warn(dev, "xvclk mismatched, modes are based on 24MHz\n"); -+ - ret = clk_prepare_enable(ov9281->xvclk); - if (ret < 0) { - dev_err(dev, "Failed to enable xvclk\n"); -@@ -1008,13 +1015,6 @@ static int ov9281_probe(struct i2c_clien - dev_err(dev, "Failed to get xvclk\n"); - return -EINVAL; - } -- ret = clk_set_rate(ov9281->xvclk, OV9281_XVCLK_FREQ); -- if (ret < 0) { -- dev_err(dev, "Failed to set xvclk rate (24MHz)\n"); -- return ret; -- } -- if (clk_get_rate(ov9281->xvclk) != OV9281_XVCLK_FREQ) -- dev_warn(dev, "xvclk mismatched, modes are based on 24MHz\n"); - - ov9281->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); - if (IS_ERR(ov9281->reset_gpio)) diff --git a/target/linux/bcm27xx/patches-5.15/950-0362-media-i2c-ov9281-add-enum_frame_interval-function-fo.patch b/target/linux/bcm27xx/patches-5.15/950-0362-media-i2c-ov9281-add-enum_frame_interval-function-fo.patch deleted file mode 100644 index ed76e9ed0..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0362-media-i2c-ov9281-add-enum_frame_interval-function-fo.patch +++ /dev/null @@ -1,97 +0,0 @@ -From a0b461a669b2e106a8b22dc3e9bd1666128d69a4 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 14 Apr 2020 15:51:50 +0100 -Subject: [PATCH] media: i2c: ov9281: add enum_frame_interval function - for iq tool 2.2 and hal3 - -Adds the ov9281 parts of the Rockchip patch adding enum_frame_interval to -a large number of drivers. - -Change-Id: I03344cd6cf278dd7c18fce8e97479089ef185a5c -Signed-off-by: Zefa Chen ---- - drivers/media/i2c/ov9281.c | 31 ++++++++++++++++++++++++++----- - 1 file changed, 26 insertions(+), 5 deletions(-) - ---- a/drivers/media/i2c/ov9281.c -+++ b/drivers/media/i2c/ov9281.c -@@ -4,6 +4,7 @@ - * - * Copyright (C) 2017 Fuzhou Rockchip Electronics Co., Ltd. - * V0.0X01.0X02 fix mclk issue when probe multiple camera. -+ * V0.0X01.0X03 add enum_frame_interval function. - */ - - #include -@@ -23,7 +24,7 @@ - #include - #include - --#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x2) -+#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x3) - - #ifndef V4L2_CID_DIGITAL_GAIN - #define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN -@@ -92,7 +93,7 @@ struct regval { - struct ov9281_mode { - u32 width; - u32 height; -- u32 max_fps; -+ struct v4l2_fract max_fps; - u32 hts_def; - u32 vts_def; - u32 exp_def; -@@ -246,7 +247,10 @@ static const struct ov9281_mode supporte - { - .width = 1280, - .height = 800, -- .max_fps = 120, -+ .max_fps = { -+ .numerator = 10000, -+ .denominator = 1200000, -+ }, - .exp_def = 0x0320, - .hts_def = 0x0b60,//0x2d8*4 - .vts_def = 0x038e, -@@ -483,8 +487,7 @@ static int OV9281_g_frame_interval(struc - const struct ov9281_mode *mode = ov9281->cur_mode; - - mutex_lock(&ov9281->mutex); -- fi->interval.numerator = 10000; -- fi->interval.denominator = mode->max_fps * 10000; -+ fi->interval = mode->max_fps; - mutex_unlock(&ov9281->mutex); - - return 0; -@@ -778,6 +781,23 @@ static int ov9281_open(struct v4l2_subde - } - #endif - -+static int -+ov9281_enum_frame_interval(struct v4l2_subdev *sd, -+ struct v4l2_subdev_pad_config *cfg, -+ struct v4l2_subdev_frame_interval_enum *fie) -+{ -+ if (fie->index >= ARRAY_SIZE(supported_modes)) -+ return -EINVAL; -+ -+ if (fie->code != MEDIA_BUS_FMT_Y10_1X10) -+ return -EINVAL; -+ -+ fie->width = supported_modes[fie->index].width; -+ fie->height = supported_modes[fie->index].height; -+ fie->interval = supported_modes[fie->index].max_fps; -+ return 0; -+} -+ - static const struct dev_pm_ops ov9281_pm_ops = { - SET_RUNTIME_PM_OPS(ov9281_runtime_suspend, - ov9281_runtime_resume, NULL) -@@ -805,6 +825,7 @@ static const struct v4l2_subdev_video_op - static const struct v4l2_subdev_pad_ops ov9281_pad_ops = { - .enum_mbus_code = ov9281_enum_mbus_code, - .enum_frame_size = ov9281_enum_frame_sizes, -+ .enum_frame_interval = ov9281_enum_frame_interval, - .get_fmt = ov9281_get_fmt, - .set_fmt = ov9281_set_fmt, - }; diff --git a/target/linux/bcm27xx/patches-5.15/950-0363-media-i2c-ov9281-Fixup-for-recent-kernel-releases-an.patch b/target/linux/bcm27xx/patches-5.15/950-0363-media-i2c-ov9281-Fixup-for-recent-kernel-releases-an.patch deleted file mode 100644 index ab9683d1e..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0363-media-i2c-ov9281-Fixup-for-recent-kernel-releases-an.patch +++ /dev/null @@ -1,681 +0,0 @@ -From 39d7bf57e12edfb28cbc8a329d546fe8a6a396ef Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 14 Apr 2020 16:12:33 +0100 -Subject: [PATCH] media: i2c: ov9281: Fixup for recent kernel releases, - and remove custom code - -The Rockchip driver was based on a 4.4 kernel, and had several custom -Rockchip parts. - -Update to 5.4 kernel APIs, with the relevant controls required by -libcamera, and remove custom Rockchip parts. - -Signed-off-by: Dave Stevenson ---- - drivers/media/i2c/ov9281.c | 361 +++++++++++++------------------------ - 1 file changed, 122 insertions(+), 239 deletions(-) - ---- a/drivers/media/i2c/ov9281.c -+++ b/drivers/media/i2c/ov9281.c -@@ -1,6 +1,11 @@ - // SPDX-License-Identifier: GPL-2.0 - /* -- * ov9281 driver -+ * Omnivision OV9281 1280x800 global shutter image sensor driver -+ * -+ * This driver has been taken from -+ * https://github.com/rockchip-linux/kernel/blob/develop-4.4/drivers/media/i2c/ov9281.c -+ * cleaned up, made to compile against mainline kernels instead of the Rockchip -+ * vendor kernel, and the relevant controls added to work with libcamera. - * - * Copyright (C) 2017 Fuzhou Rockchip Electronics Co., Ltd. - * V0.0X01.0X02 fix mclk issue when probe multiple camera. -@@ -17,22 +22,18 @@ - #include - #include - #include --#include - #include - #include - #include - #include --#include -- --#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x3) -- --#ifndef V4L2_CID_DIGITAL_GAIN --#define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN --#endif - - #define OV9281_LINK_FREQ_400MHZ 400000000 -+#define OV9281_LANES 2 -+#define OV9281_BITS_PER_SAMPLE 10 -+ - /* pixel rate = link frequency * 2 * lanes / BITS_PER_SAMPLE */ --#define OV9281_PIXEL_RATE (OV9281_LINK_FREQ_400MHZ * 2 * 2 / 10) -+#define OV9281_PIXEL_RATE (OV9281_LINK_FREQ_400MHZ * 2 * \ -+ OV9281_LANES / OV9281_BITS_PER_SAMPLE) - #define OV9281_XVCLK_FREQ 24000000 - - #define CHIP_ID 0x9281 -@@ -63,18 +64,24 @@ - - #define OV9281_REG_VTS 0x380e - -+/* -+ * OV9281 native and active pixel array size. -+ * Datasheet not available to confirm these values, so assume there are no -+ * border pixels. -+ */ -+#define OV9281_NATIVE_WIDTH 1280U -+#define OV9281_NATIVE_HEIGHT 800U -+#define OV9281_PIXEL_ARRAY_LEFT 0U -+#define OV9281_PIXEL_ARRAY_TOP 0U -+#define OV9281_PIXEL_ARRAY_WIDTH 1280U -+#define OV9281_PIXEL_ARRAY_HEIGHT 800U -+ - #define REG_NULL 0xFFFF - - #define OV9281_REG_VALUE_08BIT 1 - #define OV9281_REG_VALUE_16BIT 2 - #define OV9281_REG_VALUE_24BIT 3 - --#define OV9281_LANES 2 --#define OV9281_BITS_PER_SAMPLE 10 -- --#define OF_CAMERA_PINCTRL_STATE_DEFAULT "rockchip,camera_default" --#define OF_CAMERA_PINCTRL_STATE_SLEEP "rockchip,camera_sleep" -- - #define OV9281_NAME "ov9281" - - static const char * const ov9281_supply_names[] = { -@@ -93,10 +100,10 @@ struct regval { - struct ov9281_mode { - u32 width; - u32 height; -- struct v4l2_fract max_fps; - u32 hts_def; - u32 vts_def; - u32 exp_def; -+ struct v4l2_rect crop; - const struct regval *reg_list; - }; - -@@ -107,10 +114,6 @@ struct ov9281 { - struct gpio_desc *pwdn_gpio; - struct regulator_bulk_data supplies[OV9281_NUM_SUPPLIES]; - -- struct pinctrl *pinctrl; -- struct pinctrl_state *pins_default; -- struct pinctrl_state *pins_sleep; -- - struct v4l2_subdev subdev; - struct media_pad pad; - struct v4l2_ctrl_handler ctrl_handler; -@@ -124,23 +127,12 @@ struct ov9281 { - bool streaming; - bool power_on; - const struct ov9281_mode *cur_mode; -- u32 module_index; -- const char *module_facing; -- const char *module_name; -- const char *len_name; - }; - - #define to_ov9281(sd) container_of(sd, struct ov9281, subdev) - - /* - * Xclk 24Mhz -- */ --static const struct regval ov9281_global_regs[] = { -- {REG_NULL, 0x00}, --}; -- --/* -- * Xclk 24Mhz - * max_framerate 120fps - * mipi_datarate per lane 800Mbps - */ -@@ -247,13 +239,15 @@ static const struct ov9281_mode supporte - { - .width = 1280, - .height = 800, -- .max_fps = { -- .numerator = 10000, -- .denominator = 1200000, -- }, - .exp_def = 0x0320, -- .hts_def = 0x0b60,//0x2d8*4 -+ .hts_def = 0x05b0, /* 0x2d8*2 */ - .vts_def = 0x038e, -+ .crop = { -+ .left = 0, -+ .top = 0, -+ .width = 1280, -+ .height = 800 -+ }, - .reg_list = ov9281_1280x800_regs, - }, - }; -@@ -389,22 +383,28 @@ static int ov9281_set_fmt(struct v4l2_su - fmt->format.width = mode->width; - fmt->format.height = mode->height; - fmt->format.field = V4L2_FIELD_NONE; -+ fmt->format.colorspace = V4L2_COLORSPACE_SRGB; -+ fmt->format.ycbcr_enc = -+ V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->format.colorspace); -+ fmt->format.quantization = -+ V4L2_MAP_QUANTIZATION_DEFAULT(true, fmt->format.colorspace, -+ fmt->format.ycbcr_enc); -+ fmt->format.xfer_func = -+ V4L2_MAP_XFER_FUNC_DEFAULT(fmt->format.colorspace); -+ - if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { --#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API - *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format; --#else -- mutex_unlock(&ov9281->mutex); -- return -ENOTTY; --#endif - } else { - ov9281->cur_mode = mode; - h_blank = mode->hts_def - mode->width; - __v4l2_ctrl_modify_range(ov9281->hblank, h_blank, - h_blank, 1, h_blank); -+ __v4l2_ctrl_s_ctrl(ov9281->hblank, h_blank); - vblank_def = mode->vts_def - mode->height; - __v4l2_ctrl_modify_range(ov9281->vblank, vblank_def, - OV9281_VTS_MAX - mode->height, - 1, vblank_def); -+ __v4l2_ctrl_s_ctrl(ov9281->vblank, vblank_def); - } - - mutex_unlock(&ov9281->mutex); -@@ -421,17 +421,21 @@ static int ov9281_get_fmt(struct v4l2_su - - mutex_lock(&ov9281->mutex); - if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { --#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API - fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad); --#else -- mutex_unlock(&ov9281->mutex); -- return -ENOTTY; --#endif - } else { - fmt->format.width = mode->width; - fmt->format.height = mode->height; - fmt->format.code = MEDIA_BUS_FMT_Y10_1X10; - fmt->format.field = V4L2_FIELD_NONE; -+ fmt->format.colorspace = V4L2_COLORSPACE_SRGB; -+ fmt->format.ycbcr_enc = -+ V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->format.colorspace); -+ fmt->format.quantization = -+ V4L2_MAP_QUANTIZATION_DEFAULT(true, -+ fmt->format.colorspace, -+ fmt->format.ycbcr_enc); -+ fmt->format.xfer_func = -+ V4L2_MAP_XFER_FUNC_DEFAULT(fmt->format.colorspace); - } - mutex_unlock(&ov9281->mutex); - -@@ -442,7 +446,7 @@ static int ov9281_enum_mbus_code(struct - struct v4l2_subdev_pad_config *cfg, - struct v4l2_subdev_mbus_code_enum *code) - { -- if (code->index != 0) -+ if (code->index) - return -EINVAL; - code->code = MEDIA_BUS_FMT_Y10_1X10; - -@@ -480,88 +484,56 @@ static int ov9281_enable_test_pattern(st - OV9281_REG_VALUE_08BIT, val); - } - --static int OV9281_g_frame_interval(struct v4l2_subdev *sd, -- struct v4l2_subdev_frame_interval *fi) --{ -- struct ov9281 *ov9281 = to_ov9281(sd); -- const struct ov9281_mode *mode = ov9281->cur_mode; -- -- mutex_lock(&ov9281->mutex); -- fi->interval = mode->max_fps; -- mutex_unlock(&ov9281->mutex); -+static const struct v4l2_rect * -+__ov9281_get_pad_crop(struct ov9281 *ov9281, struct v4l2_subdev_pad_config *cfg, -+ unsigned int pad, enum v4l2_subdev_format_whence which) -+{ -+ switch (which) { -+ case V4L2_SUBDEV_FORMAT_TRY: -+ return v4l2_subdev_get_try_crop(&ov9281->subdev, cfg, pad); -+ case V4L2_SUBDEV_FORMAT_ACTIVE: -+ return &ov9281->cur_mode->crop; -+ } - -- return 0; -+ return NULL; - } - --static void ov9281_get_module_inf(struct ov9281 *ov9281, -- struct rkmodule_inf *inf) -+static int ov9281_get_selection(struct v4l2_subdev *sd, -+ struct v4l2_subdev_pad_config *cfg, -+ struct v4l2_subdev_selection *sel) - { -- memset(inf, 0, sizeof(*inf)); -- strlcpy(inf->base.sensor, OV9281_NAME, sizeof(inf->base.sensor)); -- strlcpy(inf->base.module, ov9281->module_name, -- sizeof(inf->base.module)); -- strlcpy(inf->base.lens, ov9281->len_name, sizeof(inf->base.lens)); --} -+ switch (sel->target) { -+ case V4L2_SEL_TGT_CROP: { -+ struct ov9281 *ov9281 = to_ov9281(sd); - --static long ov9281_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) --{ -- struct ov9281 *ov9281 = to_ov9281(sd); -- long ret = 0; -+ mutex_lock(&ov9281->mutex); -+ sel->r = *__ov9281_get_pad_crop(ov9281, cfg, sel->pad, -+ sel->which); -+ mutex_unlock(&ov9281->mutex); - -- switch (cmd) { -- case RKMODULE_GET_MODULE_INFO: -- ov9281_get_module_inf(ov9281, (struct rkmodule_inf *)arg); -- break; -- default: -- ret = -ENOIOCTLCMD; -- break; -+ return 0; - } - -- return ret; --} -+ case V4L2_SEL_TGT_NATIVE_SIZE: -+ sel->r.top = 0; -+ sel->r.left = 0; -+ sel->r.width = OV9281_NATIVE_WIDTH; -+ sel->r.height = OV9281_NATIVE_HEIGHT; - --#ifdef CONFIG_COMPAT --static long ov9281_compat_ioctl32(struct v4l2_subdev *sd, -- unsigned int cmd, unsigned long arg) --{ -- void __user *up = compat_ptr(arg); -- struct rkmodule_inf *inf; -- struct rkmodule_awb_cfg *cfg; -- long ret; -- -- switch (cmd) { -- case RKMODULE_GET_MODULE_INFO: -- inf = kzalloc(sizeof(*inf), GFP_KERNEL); -- if (!inf) { -- ret = -ENOMEM; -- return ret; -- } -+ return 0; - -- ret = ov9281_ioctl(sd, cmd, inf); -- if (!ret) -- ret = copy_to_user(up, inf, sizeof(*inf)); -- kfree(inf); -- break; -- case RKMODULE_AWB_CFG: -- cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); -- if (!cfg) { -- ret = -ENOMEM; -- return ret; -- } -+ case V4L2_SEL_TGT_CROP_DEFAULT: -+ case V4L2_SEL_TGT_CROP_BOUNDS: -+ sel->r.top = OV9281_PIXEL_ARRAY_TOP; -+ sel->r.left = OV9281_PIXEL_ARRAY_LEFT; -+ sel->r.width = OV9281_PIXEL_ARRAY_WIDTH; -+ sel->r.height = OV9281_PIXEL_ARRAY_HEIGHT; - -- ret = copy_from_user(cfg, up, sizeof(*cfg)); -- if (!ret) -- ret = ov9281_ioctl(sd, cmd, cfg); -- kfree(cfg); -- break; -- default: -- ret = -ENOIOCTLCMD; -- break; -+ return 0; - } - -- return ret; -+ return -EINVAL; - } --#endif - - static int __ov9281_start_stream(struct ov9281 *ov9281) - { -@@ -643,12 +615,6 @@ static int ov9281_s_power(struct v4l2_su - pm_runtime_put_noidle(&client->dev); - goto unlock_and_return; - } -- ret = ov9281_write_array(ov9281->client, ov9281_global_regs); -- if (ret) { -- v4l2_err(sd, "could not set init registers\n"); -- pm_runtime_put_noidle(&client->dev); -- goto unlock_and_return; -- } - ov9281->power_on = true; - } else { - pm_runtime_put(&client->dev); -@@ -673,18 +639,12 @@ static int __ov9281_power_on(struct ov92 - u32 delay_us; - struct device *dev = &ov9281->client->dev; - -- if (!IS_ERR_OR_NULL(ov9281->pins_default)) { -- ret = pinctrl_select_state(ov9281->pinctrl, -- ov9281->pins_default); -- if (ret < 0) -- dev_err(dev, "could not set pins\n"); -- } -- - ret = clk_set_rate(ov9281->xvclk, OV9281_XVCLK_FREQ); - if (ret < 0) - dev_warn(dev, "Failed to set xvclk rate (24MHz)\n"); - if (clk_get_rate(ov9281->xvclk) != OV9281_XVCLK_FREQ) -- dev_warn(dev, "xvclk mismatched, modes are based on 24MHz\n"); -+ dev_warn(dev, "xvclk mismatched, modes are based on 24MHz - rate is %lu\n", -+ clk_get_rate(ov9281->xvclk)); - - ret = clk_prepare_enable(ov9281->xvclk); - if (ret < 0) { -@@ -722,20 +682,11 @@ disable_clk: - - static void __ov9281_power_off(struct ov9281 *ov9281) - { -- int ret; -- struct device *dev = &ov9281->client->dev; -- - if (!IS_ERR(ov9281->pwdn_gpio)) - gpiod_set_value_cansleep(ov9281->pwdn_gpio, 0); - clk_disable_unprepare(ov9281->xvclk); - if (!IS_ERR(ov9281->reset_gpio)) - gpiod_set_value_cansleep(ov9281->reset_gpio, 0); -- if (!IS_ERR_OR_NULL(ov9281->pins_sleep)) { -- ret = pinctrl_select_state(ov9281->pinctrl, -- ov9281->pins_sleep); -- if (ret < 0) -- dev_dbg(dev, "could not set pins\n"); -- } - regulator_bulk_disable(OV9281_NUM_SUPPLIES, ov9281->supplies); - } - -@@ -759,7 +710,6 @@ static int ov9281_runtime_suspend(struct - return 0; - } - --#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API - static int ov9281_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) - { - struct ov9281 *ov9281 = to_ov9281(sd); -@@ -773,61 +723,42 @@ static int ov9281_open(struct v4l2_subde - try_fmt->height = def_mode->height; - try_fmt->code = MEDIA_BUS_FMT_Y10_1X10; - try_fmt->field = V4L2_FIELD_NONE; -+ try_fmt->colorspace = V4L2_COLORSPACE_SRGB; -+ try_fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(try_fmt->colorspace); -+ try_fmt->quantization = -+ V4L2_MAP_QUANTIZATION_DEFAULT(true, try_fmt->colorspace, -+ try_fmt->ycbcr_enc); -+ try_fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(try_fmt->colorspace); - - mutex_unlock(&ov9281->mutex); - /* No crop or compose */ - - return 0; - } --#endif -- --static int --ov9281_enum_frame_interval(struct v4l2_subdev *sd, -- struct v4l2_subdev_pad_config *cfg, -- struct v4l2_subdev_frame_interval_enum *fie) --{ -- if (fie->index >= ARRAY_SIZE(supported_modes)) -- return -EINVAL; -- -- if (fie->code != MEDIA_BUS_FMT_Y10_1X10) -- return -EINVAL; -- -- fie->width = supported_modes[fie->index].width; -- fie->height = supported_modes[fie->index].height; -- fie->interval = supported_modes[fie->index].max_fps; -- return 0; --} - - static const struct dev_pm_ops ov9281_pm_ops = { - SET_RUNTIME_PM_OPS(ov9281_runtime_suspend, - ov9281_runtime_resume, NULL) - }; - --#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API - static const struct v4l2_subdev_internal_ops ov9281_internal_ops = { - .open = ov9281_open, - }; --#endif - - static const struct v4l2_subdev_core_ops ov9281_core_ops = { - .s_power = ov9281_s_power, -- .ioctl = ov9281_ioctl, --#ifdef CONFIG_COMPAT -- .compat_ioctl32 = ov9281_compat_ioctl32, --#endif - }; - - static const struct v4l2_subdev_video_ops ov9281_video_ops = { - .s_stream = ov9281_s_stream, -- .g_frame_interval = OV9281_g_frame_interval, - }; - - static const struct v4l2_subdev_pad_ops ov9281_pad_ops = { - .enum_mbus_code = ov9281_enum_mbus_code, - .enum_frame_size = ov9281_enum_frame_sizes, -- .enum_frame_interval = ov9281_enum_frame_interval, - .get_fmt = ov9281_get_fmt, - .set_fmt = ov9281_set_fmt, -+ .get_selection = ov9281_get_selection, - }; - - static const struct v4l2_subdev_ops ov9281_subdev_ops = { -@@ -868,7 +799,8 @@ static int ov9281_set_ctrl(struct v4l2_c - case V4L2_CID_ANALOGUE_GAIN: - ret = ov9281_write_reg(ov9281->client, OV9281_REG_GAIN_H, - OV9281_REG_VALUE_08BIT, -- (ctrl->val >> OV9281_GAIN_H_SHIFT) & OV9281_GAIN_H_MASK); -+ (ctrl->val >> OV9281_GAIN_H_SHIFT) & -+ OV9281_GAIN_H_MASK); - ret |= ov9281_write_reg(ov9281->client, OV9281_REG_GAIN_L, - OV9281_REG_VALUE_08BIT, - ctrl->val & OV9281_GAIN_L_MASK); -@@ -922,31 +854,34 @@ static int ov9281_initialize_controls(st - - h_blank = mode->hts_def - mode->width; - ov9281->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK, -- h_blank, h_blank, 1, h_blank); -+ h_blank, h_blank, 1, h_blank); - if (ov9281->hblank) - ov9281->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; - - vblank_def = mode->vts_def - mode->height; - ov9281->vblank = v4l2_ctrl_new_std(handler, &ov9281_ctrl_ops, -- V4L2_CID_VBLANK, vblank_def, -- OV9281_VTS_MAX - mode->height, -- 1, vblank_def); -+ V4L2_CID_VBLANK, vblank_def, -+ OV9281_VTS_MAX - mode->height, 1, -+ vblank_def); - - exposure_max = mode->vts_def - 4; - ov9281->exposure = v4l2_ctrl_new_std(handler, &ov9281_ctrl_ops, -- V4L2_CID_EXPOSURE, OV9281_EXPOSURE_MIN, -- exposure_max, OV9281_EXPOSURE_STEP, -- mode->exp_def); -+ V4L2_CID_EXPOSURE, -+ OV9281_EXPOSURE_MIN, exposure_max, -+ OV9281_EXPOSURE_STEP, -+ mode->exp_def); - - ov9281->anal_gain = v4l2_ctrl_new_std(handler, &ov9281_ctrl_ops, -- V4L2_CID_ANALOGUE_GAIN, OV9281_GAIN_MIN, -- OV9281_GAIN_MAX, OV9281_GAIN_STEP, -- OV9281_GAIN_DEFAULT); -- -- ov9281->test_pattern = v4l2_ctrl_new_std_menu_items(handler, -- &ov9281_ctrl_ops, V4L2_CID_TEST_PATTERN, -- ARRAY_SIZE(ov9281_test_pattern_menu) - 1, -- 0, 0, ov9281_test_pattern_menu); -+ V4L2_CID_ANALOGUE_GAIN, -+ OV9281_GAIN_MIN, OV9281_GAIN_MAX, -+ OV9281_GAIN_STEP, -+ OV9281_GAIN_DEFAULT); -+ -+ ov9281->test_pattern = -+ v4l2_ctrl_new_std_menu_items(handler, &ov9281_ctrl_ops, -+ V4L2_CID_TEST_PATTERN, -+ ARRAY_SIZE(ov9281_test_pattern_menu) - 1, -+ 0, 0, ov9281_test_pattern_menu); - - if (handler->error) { - ret = handler->error; -@@ -1000,34 +935,14 @@ static int ov9281_probe(struct i2c_clien - const struct i2c_device_id *id) - { - struct device *dev = &client->dev; -- struct device_node *node = dev->of_node; - struct ov9281 *ov9281; - struct v4l2_subdev *sd; -- char facing[2]; - int ret; - -- dev_info(dev, "driver version: %02x.%02x.%02x", -- DRIVER_VERSION >> 16, -- (DRIVER_VERSION & 0xff00) >> 8, -- DRIVER_VERSION & 0x00ff); -- - ov9281 = devm_kzalloc(dev, sizeof(*ov9281), GFP_KERNEL); - if (!ov9281) - return -ENOMEM; - -- ret = of_property_read_u32(node, RKMODULE_CAMERA_MODULE_INDEX, -- &ov9281->module_index); -- ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_FACING, -- &ov9281->module_facing); -- ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_NAME, -- &ov9281->module_name); -- ret |= of_property_read_string(node, RKMODULE_CAMERA_LENS_NAME, -- &ov9281->len_name); -- if (ret) { -- dev_err(dev, "could not get module information!\n"); -- return -EINVAL; -- } -- - ov9281->client = client; - ov9281->cur_mode = &supported_modes[0]; - -@@ -1037,31 +952,15 @@ static int ov9281_probe(struct i2c_clien - return -EINVAL; - } - -- ov9281->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); -+ ov9281->reset_gpio = devm_gpiod_get_optional(dev, "reset", -+ GPIOD_OUT_LOW); - if (IS_ERR(ov9281->reset_gpio)) - dev_warn(dev, "Failed to get reset-gpios\n"); - -- ov9281->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW); -+ ov9281->pwdn_gpio = devm_gpiod_get_optional(dev, "pwdn", GPIOD_OUT_LOW); - if (IS_ERR(ov9281->pwdn_gpio)) - dev_warn(dev, "Failed to get pwdn-gpios\n"); - -- ov9281->pinctrl = devm_pinctrl_get(dev); -- if (!IS_ERR(ov9281->pinctrl)) { -- ov9281->pins_default = -- pinctrl_lookup_state(ov9281->pinctrl, -- OF_CAMERA_PINCTRL_STATE_DEFAULT); -- if (IS_ERR(ov9281->pins_default)) -- dev_err(dev, "could not get default pinstate\n"); -- -- ov9281->pins_sleep = -- pinctrl_lookup_state(ov9281->pinctrl, -- OF_CAMERA_PINCTRL_STATE_SLEEP); -- if (IS_ERR(ov9281->pins_sleep)) -- dev_err(dev, "could not get sleep pinstate\n"); -- } else { -- dev_err(dev, "no pinctrl\n"); -- } -- - ret = ov9281_configure_regulators(ov9281); - if (ret) { - dev_err(dev, "Failed to get power regulators\n"); -@@ -1084,26 +983,16 @@ static int ov9281_probe(struct i2c_clien - if (ret) - goto err_power_off; - --#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API - sd->internal_ops = &ov9281_internal_ops; - sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; --#endif --#if defined(CONFIG_MEDIA_CONTROLLER) -+ - ov9281->pad.flags = MEDIA_PAD_FL_SOURCE; -- sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; -- ret = media_entity_init(&sd->entity, 1, &ov9281->pad, 0); -+ sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; -+ ret = media_entity_pads_init(&sd->entity, 1, &ov9281->pad); - if (ret < 0) - goto err_power_off; --#endif -- -- memset(facing, 0, sizeof(facing)); -- if (strcmp(ov9281->module_facing, "back") == 0) -- facing[0] = 'b'; -- else -- facing[0] = 'f'; - -- snprintf(sd->name, sizeof(sd->name), "m%02d_%s_%s %s", -- ov9281->module_index, facing, -+ snprintf(sd->name, sizeof(sd->name), "m%s %s", - OV9281_NAME, dev_name(sd->dev)); - ret = v4l2_async_register_subdev_sensor(sd); - if (ret) { -@@ -1118,9 +1007,7 @@ static int ov9281_probe(struct i2c_clien - return 0; - - err_clean_entity: --#if defined(CONFIG_MEDIA_CONTROLLER) - media_entity_cleanup(&sd->entity); --#endif - err_power_off: - __ov9281_power_off(ov9281); - err_free_handler: -@@ -1137,9 +1024,7 @@ static int ov9281_remove(struct i2c_clie - struct ov9281 *ov9281 = to_ov9281(sd); - - v4l2_async_unregister_subdev(sd); --#if defined(CONFIG_MEDIA_CONTROLLER) - media_entity_cleanup(&sd->entity); --#endif - v4l2_ctrl_handler_free(&ov9281->ctrl_handler); - mutex_destroy(&ov9281->mutex); - -@@ -1151,13 +1036,11 @@ static int ov9281_remove(struct i2c_clie - return 0; - } - --#if IS_ENABLED(CONFIG_OF) - static const struct of_device_id ov9281_of_match[] = { - { .compatible = "ovti,ov9281" }, - {}, - }; - MODULE_DEVICE_TABLE(of, ov9281_of_match); --#endif - - static const struct i2c_device_id ov9281_match_id[] = { - { "ovti,ov9281", 0 }, diff --git a/target/linux/bcm27xx/patches-5.15/950-0364-media-i2c-ov9281-Read-chip-ID-via-2-reads.patch b/target/linux/bcm27xx/patches-5.15/950-0364-media-i2c-ov9281-Read-chip-ID-via-2-reads.patch deleted file mode 100644 index 2644c5659..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0364-media-i2c-ov9281-Read-chip-ID-via-2-reads.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 18e32b190c3e58cba734073706d5ff0fcd7cbba3 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 6 Jul 2020 17:51:32 +0100 -Subject: [PATCH] media: i2c: ov9281: Read chip ID via 2 reads - -Vision Components have made an OV9281 module which blocks reading -back the majority of registers to comply with NDAs, and in doing -so doesn't allow auto-increment register reading as used when -reading the chip ID. - -Use two reads and manually combine the results. - -Signed-off-by: Dave Stevenson ---- - drivers/media/i2c/ov9281.c | 14 +++++++++----- - 1 file changed, 9 insertions(+), 5 deletions(-) - ---- a/drivers/media/i2c/ov9281.c -+++ b/drivers/media/i2c/ov9281.c -@@ -904,13 +904,17 @@ static int ov9281_check_sensor_id(struct - struct i2c_client *client) - { - struct device *dev = &ov9281->client->dev; -- u32 id = 0; -+ u32 id = 0, id_msb; - int ret; - -- ret = ov9281_read_reg(client, OV9281_REG_CHIP_ID, -- OV9281_REG_VALUE_16BIT, &id); -- if (id != CHIP_ID) { -- dev_err(dev, "Unexpected sensor id(%06x), ret(%d)\n", id, ret); -+ ret = ov9281_read_reg(client, OV9281_REG_CHIP_ID + 1, -+ OV9281_REG_VALUE_08BIT, &id); -+ if (!ret) -+ ret = ov9281_read_reg(client, OV9281_REG_CHIP_ID, -+ OV9281_REG_VALUE_08BIT, &id_msb); -+ id |= (id_msb << 8); -+ if (ret || id != CHIP_ID) { -+ dev_err(dev, "Unexpected sensor id(%04x), ret(%d)\n", id, ret); - return -ENODEV; - } - diff --git a/target/linux/bcm27xx/patches-5.15/950-0365-media-i2c-ov9281-Add-support-for-8-bit-readout.patch b/target/linux/bcm27xx/patches-5.15/950-0365-media-i2c-ov9281-Add-support-for-8-bit-readout.patch deleted file mode 100644 index 670e9567f..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0365-media-i2c-ov9281-Add-support-for-8-bit-readout.patch +++ /dev/null @@ -1,188 +0,0 @@ -From 86e3f6d35527608611176b6591bc6a80bfc0f7cf Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 7 Jul 2020 18:29:10 +0100 -Subject: [PATCH] media: i2c: ov9281: Add support for 8 bit readout - -The sensor supports 8 bit mode as well as 10bit, so add the -relevant code to allow selection of this. - -Signed-off-by: Dave Stevenson ---- - drivers/media/i2c/ov9281.c | 66 ++++++++++++++++++++++++++++++-------- - 1 file changed, 52 insertions(+), 14 deletions(-) - ---- a/drivers/media/i2c/ov9281.c -+++ b/drivers/media/i2c/ov9281.c -@@ -29,11 +29,12 @@ - - #define OV9281_LINK_FREQ_400MHZ 400000000 - #define OV9281_LANES 2 --#define OV9281_BITS_PER_SAMPLE 10 - - /* pixel rate = link frequency * 2 * lanes / BITS_PER_SAMPLE */ --#define OV9281_PIXEL_RATE (OV9281_LINK_FREQ_400MHZ * 2 * \ -- OV9281_LANES / OV9281_BITS_PER_SAMPLE) -+#define OV9281_PIXEL_RATE_10BIT (OV9281_LINK_FREQ_400MHZ * 2 * \ -+ OV9281_LANES / 10) -+#define OV9281_PIXEL_RATE_8BIT (OV9281_LINK_FREQ_400MHZ * 2 * \ -+ OV9281_LANES / 8) - #define OV9281_XVCLK_FREQ 24000000 - - #define CHIP_ID 0x9281 -@@ -122,24 +123,25 @@ struct ov9281 { - struct v4l2_ctrl *digi_gain; - struct v4l2_ctrl *hblank; - struct v4l2_ctrl *vblank; -+ struct v4l2_ctrl *pixel_rate; - struct v4l2_ctrl *test_pattern; - struct mutex mutex; - bool streaming; - bool power_on; - const struct ov9281_mode *cur_mode; -+ u32 code; - }; - - #define to_ov9281(sd) container_of(sd, struct ov9281, subdev) - - /* - * Xclk 24Mhz -- * max_framerate 120fps -+ * max_framerate 120fps for 10 bit, 144fps for 8 bit. - * mipi_datarate per lane 800Mbps - */ - static const struct regval ov9281_1280x800_regs[] = { - {0x0103, 0x01}, - {0x0302, 0x32}, -- {0x030d, 0x50}, - {0x030e, 0x02}, - {0x3001, 0x00}, - {0x3004, 0x00}, -@@ -168,7 +170,6 @@ static const struct regval ov9281_1280x8 - {0x3620, 0x6f}, - {0x3632, 0x56}, - {0x3633, 0x78}, -- {0x3662, 0x05}, - {0x3666, 0x00}, - {0x366f, 0x5a}, - {0x3680, 0x84}, -@@ -235,6 +236,18 @@ static const struct regval ov9281_1280x8 - {REG_NULL, 0x00}, - }; - -+static const struct regval op_10bit[] = { -+ {0x030d, 0x50}, -+ {0x3662, 0x05}, -+ {REG_NULL, 0x00}, -+}; -+ -+static const struct regval op_8bit[] = { -+ {0x030d, 0x60}, -+ {0x3662, 0x07}, -+ {REG_NULL, 0x00}, -+}; -+ - static const struct ov9281_mode supported_modes[] = { - { - .width = 1280, -@@ -374,12 +387,13 @@ static int ov9281_set_fmt(struct v4l2_su - { - struct ov9281 *ov9281 = to_ov9281(sd); - const struct ov9281_mode *mode; -- s64 h_blank, vblank_def; -+ s64 h_blank, vblank_def, pixel_rate; - - mutex_lock(&ov9281->mutex); - - mode = ov9281_find_best_fit(fmt); -- fmt->format.code = MEDIA_BUS_FMT_Y10_1X10; -+ if (fmt->format.code != MEDIA_BUS_FMT_Y8_1X8) -+ fmt->format.code = MEDIA_BUS_FMT_Y10_1X10; - fmt->format.width = mode->width; - fmt->format.height = mode->height; - fmt->format.field = V4L2_FIELD_NONE; -@@ -396,6 +410,7 @@ static int ov9281_set_fmt(struct v4l2_su - *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format; - } else { - ov9281->cur_mode = mode; -+ ov9281->code = fmt->format.code; - h_blank = mode->hts_def - mode->width; - __v4l2_ctrl_modify_range(ov9281->hblank, h_blank, - h_blank, 1, h_blank); -@@ -405,6 +420,11 @@ static int ov9281_set_fmt(struct v4l2_su - OV9281_VTS_MAX - mode->height, - 1, vblank_def); - __v4l2_ctrl_s_ctrl(ov9281->vblank, vblank_def); -+ -+ pixel_rate = (fmt->format.code == MEDIA_BUS_FMT_Y10_1X10) ? -+ OV9281_PIXEL_RATE_10BIT : OV9281_PIXEL_RATE_8BIT; -+ __v4l2_ctrl_modify_range(ov9281->pixel_rate, pixel_rate, -+ pixel_rate, 1, pixel_rate); - } - - mutex_unlock(&ov9281->mutex); -@@ -425,7 +445,7 @@ static int ov9281_get_fmt(struct v4l2_su - } else { - fmt->format.width = mode->width; - fmt->format.height = mode->height; -- fmt->format.code = MEDIA_BUS_FMT_Y10_1X10; -+ fmt->format.code = ov9281->code; - fmt->format.field = V4L2_FIELD_NONE; - fmt->format.colorspace = V4L2_COLORSPACE_SRGB; - fmt->format.ycbcr_enc = -@@ -446,9 +466,16 @@ static int ov9281_enum_mbus_code(struct - struct v4l2_subdev_pad_config *cfg, - struct v4l2_subdev_mbus_code_enum *code) - { -- if (code->index) -+ switch (code->index) { -+ default: - return -EINVAL; -- code->code = MEDIA_BUS_FMT_Y10_1X10; -+ case 0: -+ code->code = MEDIA_BUS_FMT_Y10_1X10; -+ break; -+ case 1: -+ code->code = MEDIA_BUS_FMT_Y8_1X8; -+ break; -+ } - - return 0; - } -@@ -460,7 +487,8 @@ static int ov9281_enum_frame_sizes(struc - if (fse->index >= ARRAY_SIZE(supported_modes)) - return -EINVAL; - -- if (fse->code != MEDIA_BUS_FMT_Y10_1X10) -+ if (fse->code != MEDIA_BUS_FMT_Y10_1X10 && -+ fse->code != MEDIA_BUS_FMT_Y8_1X8) - return -EINVAL; - - fse->min_width = supported_modes[fse->index].width; -@@ -543,6 +571,13 @@ static int __ov9281_start_stream(struct - if (ret) - return ret; - -+ if (ov9281->code == MEDIA_BUS_FMT_Y10_1X10) -+ ret = ov9281_write_array(ov9281->client, op_10bit); -+ else -+ ret = ov9281_write_array(ov9281->client, op_8bit); -+ if (ret) -+ return ret; -+ - /* In case these controls are set before streaming */ - mutex_unlock(&ov9281->mutex); - ret = v4l2_ctrl_handler_setup(&ov9281->ctrl_handler); -@@ -849,8 +884,11 @@ static int ov9281_initialize_controls(st - if (ctrl) - ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; - -- v4l2_ctrl_new_std(handler, NULL, V4L2_CID_PIXEL_RATE, -- 0, OV9281_PIXEL_RATE, 1, OV9281_PIXEL_RATE); -+ ov9281->pixel_rate = v4l2_ctrl_new_std(handler, NULL, -+ V4L2_CID_PIXEL_RATE, -+ OV9281_PIXEL_RATE_10BIT, -+ OV9281_PIXEL_RATE_10BIT, 1, -+ OV9281_PIXEL_RATE_10BIT); - - h_blank = mode->hts_def - mode->width; - ov9281->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK, diff --git a/target/linux/bcm27xx/patches-5.15/950-0366-media-ov9281-Add-1280x720-and-640x480-modes.patch b/target/linux/bcm27xx/patches-5.15/950-0366-media-ov9281-Add-1280x720-and-640x480-modes.patch deleted file mode 100644 index 33efb12f6..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0366-media-ov9281-Add-1280x720-and-640x480-modes.patch +++ /dev/null @@ -1,209 +0,0 @@ -From 22a869d373bc642562e55107028d19926a593984 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Sun, 22 Nov 2020 11:01:08 +0000 -Subject: [PATCH] media: ov9281: Add 1280x720 and 640x480 modes - -Breaks out common register set and adds the different registers -for 1280x720 (cropped) and 640x480 (skipped) modes - -Signed-off-by: Dave Stevenson ---- - drivers/media/i2c/ov9281.c | 146 ++++++++++++++++++++++++++++++++----- - 1 file changed, 126 insertions(+), 20 deletions(-) - ---- a/drivers/media/i2c/ov9281.c -+++ b/drivers/media/i2c/ov9281.c -@@ -139,7 +139,7 @@ struct ov9281 { - * max_framerate 120fps for 10 bit, 144fps for 8 bit. - * mipi_datarate per lane 800Mbps - */ --static const struct regval ov9281_1280x800_regs[] = { -+static const struct regval ov9281_common_regs[] = { - {0x0103, 0x01}, - {0x0302, 0x32}, - {0x030e, 0x02}, -@@ -177,13 +177,35 @@ static const struct regval ov9281_1280x8 - {0x372d, 0x22}, - {0x3731, 0x80}, - {0x3732, 0x30}, -- {0x3778, 0x00}, - {0x377d, 0x22}, - {0x3788, 0x02}, - {0x3789, 0xa4}, - {0x378a, 0x00}, - {0x378b, 0x4a}, - {0x3799, 0x20}, -+ {0x3881, 0x42}, -+ {0x38b1, 0x00}, -+ {0x3920, 0xff}, -+ {0x4010, 0x40}, -+ {0x4043, 0x40}, -+ {0x4307, 0x30}, -+ {0x4317, 0x00}, -+ {0x4501, 0x00}, -+ {0x450a, 0x08}, -+ {0x4601, 0x04}, -+ {0x470f, 0x00}, -+ {0x4f07, 0x00}, -+ {0x4800, 0x00}, -+ {0x5000, 0x9f}, -+ {0x5001, 0x00}, -+ {0x5e00, 0x00}, -+ {0x5d00, 0x07}, -+ {0x5d01, 0x00}, -+ {REG_NULL, 0x00}, -+}; -+ -+static const struct regval ov9281_1280x800_regs[] = { -+ {0x3778, 0x10}, - {0x3800, 0x00}, - {0x3801, 0x00}, - {0x3802, 0x00}, -@@ -208,31 +230,83 @@ static const struct regval ov9281_1280x8 - {0x3815, 0x11}, - {0x3820, 0x40}, - {0x3821, 0x00}, -- {0x3881, 0x42}, -- {0x38b1, 0x00}, -- {0x3920, 0xff}, - {0x4003, 0x40}, - {0x4008, 0x04}, - {0x4009, 0x0b}, - {0x400c, 0x00}, - {0x400d, 0x07}, -- {0x4010, 0x40}, -- {0x4043, 0x40}, -- {0x4307, 0x30}, -- {0x4317, 0x00}, -- {0x4501, 0x00}, - {0x4507, 0x00}, - {0x4509, 0x00}, -- {0x450a, 0x08}, -- {0x4601, 0x04}, -- {0x470f, 0x00}, -- {0x4f07, 0x00}, -- {0x4800, 0x00}, -- {0x5000, 0x9f}, -- {0x5001, 0x00}, -- {0x5e00, 0x00}, -- {0x5d00, 0x07}, -- {0x5d01, 0x00}, -+ {REG_NULL, 0x00}, -+}; -+ -+static const struct regval ov9281_1280x720_regs[] = { -+ {0x3778, 0x10}, -+ {0x3800, 0x00}, -+ {0x3801, 0x00}, -+ {0x3802, 0x00}, -+ {0x3803, 0x28}, -+ {0x3804, 0x05}, -+ {0x3805, 0x0f}, -+ {0x3806, 0x03}, -+ {0x3807, 0x07}, -+ {0x3808, 0x05}, -+ {0x3809, 0x00}, -+ {0x380a, 0x02}, -+ {0x380b, 0xd0}, -+ {0x380c, 0x02}, -+ {0x380d, 0xd8}, -+ {0x380e, 0x03}, -+ {0x380f, 0x8e}, -+ {0x3810, 0x00}, -+ {0x3811, 0x08}, -+ {0x3812, 0x00}, -+ {0x3813, 0x08}, -+ {0x3814, 0x11}, -+ {0x3815, 0x11}, -+ {0x3820, 0x40}, -+ {0x3821, 0x00}, -+ {0x4003, 0x40}, -+ {0x4008, 0x04}, -+ {0x4009, 0x0b}, -+ {0x400c, 0x00}, -+ {0x400d, 0x07}, -+ {0x4507, 0x00}, -+ {0x4509, 0x00}, -+ {REG_NULL, 0x00}, -+}; -+ -+static const struct regval ov9281_640x400_regs[] = { -+ {0x3800, 0x00}, -+ {0x3801, 0x00}, -+ {0x3802, 0x00}, -+ {0x3803, 0x00}, -+ {0x3804, 0x05}, -+ {0x3805, 0x0f}, -+ {0x3806, 0x03}, -+ {0x3807, 0x2f}, -+ {0x3808, 0x02}, -+ {0x3809, 0x80}, -+ {0x380a, 0x01}, -+ {0x380b, 0x90}, -+ {0x380c, 0x02}, -+ {0x380d, 0xd8}, -+ {0x380e, 0x02}, -+ {0x380f, 0x08}, -+ {0x3810, 0x00}, -+ {0x3811, 0x04}, -+ {0x3812, 0x00}, -+ {0x3813, 0x04}, -+ {0x3814, 0x31}, -+ {0x3815, 0x22}, -+ {0x3820, 0x60}, -+ {0x3821, 0x01}, -+ {0x4008, 0x02}, -+ {0x4009, 0x05}, -+ {0x400c, 0x00}, -+ {0x400d, 0x03}, -+ {0x4507, 0x03}, -+ {0x4509, 0x80}, - {REG_NULL, 0x00}, - }; - -@@ -263,6 +337,34 @@ static const struct ov9281_mode supporte - }, - .reg_list = ov9281_1280x800_regs, - }, -+ { -+ .width = 1280, -+ .height = 720, -+ .exp_def = 0x0320, -+ .hts_def = 0x05b0, -+ .vts_def = 761, -+ .crop = { -+ .left = 0, -+ .top = 40, -+ .width = 1280, -+ .height = 720 -+ }, -+ .reg_list = ov9281_1280x720_regs, -+ }, -+ { -+ .width = 640, -+ .height = 400, -+ .exp_def = 0x0320, -+ .hts_def = 0x05b0, -+ .vts_def = 421, -+ .crop = { -+ .left = 0, -+ .top = 0, -+ .width = 1280, -+ .height = 800 -+ }, -+ .reg_list = ov9281_640x400_regs, -+ }, - }; - - static const s64 link_freq_menu_items[] = { -@@ -567,6 +669,10 @@ static int __ov9281_start_stream(struct - { - int ret; - -+ ret = ov9281_write_array(ov9281->client, ov9281_common_regs); -+ if (ret) -+ return ret; -+ - ret = ov9281_write_array(ov9281->client, ov9281->cur_mode->reg_list); - if (ret) - return ret; diff --git a/target/linux/bcm27xx/patches-5.15/950-0367-Fixed-picture-line-bug-in-all-ov9281-modes.patch b/target/linux/bcm27xx/patches-5.15/950-0367-Fixed-picture-line-bug-in-all-ov9281-modes.patch deleted file mode 100644 index c66fa6486..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0367-Fixed-picture-line-bug-in-all-ov9281-modes.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 3a2b3212618601346fbd042fa008a2200f09bda5 Mon Sep 17 00:00:00 2001 -From: Mathias Anhalt -Date: Sun, 24 Jan 2021 15:15:01 +0100 -Subject: [PATCH] Fixed picture line bug in all ov9281 modes - -Signed-off-by: Mathias Anhalt ---- - drivers/media/i2c/ov9281.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - ---- a/drivers/media/i2c/ov9281.c -+++ b/drivers/media/i2c/ov9281.c -@@ -205,7 +205,7 @@ static const struct regval ov9281_common - }; - - static const struct regval ov9281_1280x800_regs[] = { -- {0x3778, 0x10}, -+ {0x3778, 0x00}, - {0x3800, 0x00}, - {0x3801, 0x00}, - {0x3802, 0x00}, -@@ -241,7 +241,7 @@ static const struct regval ov9281_1280x8 - }; - - static const struct regval ov9281_1280x720_regs[] = { -- {0x3778, 0x10}, -+ {0x3778, 0x00}, - {0x3800, 0x00}, - {0x3801, 0x00}, - {0x3802, 0x00}, -@@ -277,6 +277,7 @@ static const struct regval ov9281_1280x7 - }; - - static const struct regval ov9281_640x400_regs[] = { -+ {0x3778, 0x10}, - {0x3800, 0x00}, - {0x3801, 0x00}, - {0x3802, 0x00}, diff --git a/target/linux/bcm27xx/patches-5.15/950-0368-Added-hflip-and-vflip-controls-to-ov9281.patch b/target/linux/bcm27xx/patches-5.15/950-0368-Added-hflip-and-vflip-controls-to-ov9281.patch deleted file mode 100644 index 9df252c10..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0368-Added-hflip-and-vflip-controls-to-ov9281.patch +++ /dev/null @@ -1,112 +0,0 @@ -From 0eab0865261fd1da54330c59de9e0929e27ec330 Mon Sep 17 00:00:00 2001 -From: Mathias Anhalt -Date: Wed, 3 Feb 2021 20:34:09 +0100 -Subject: [PATCH] Added hflip and vflip controls to ov9281 - -Signed-off-by: Mathias Anhalt ---- - drivers/media/i2c/ov9281.c | 58 +++++++++++++++++++++++++++++++++++++- - 1 file changed, 57 insertions(+), 1 deletion(-) - ---- a/drivers/media/i2c/ov9281.c -+++ b/drivers/media/i2c/ov9281.c -@@ -40,6 +40,10 @@ - #define CHIP_ID 0x9281 - #define OV9281_REG_CHIP_ID 0x300a - -+#define OV9281_REG_TIMING_FORMAT_1 0x3820 -+#define OV9281_REG_TIMING_FORMAT_2 0x3821 -+#define OV9281_FLIP_BIT BIT(2) -+ - #define OV9281_REG_CTRL_MODE 0x0100 - #define OV9281_MODE_SW_STANDBY 0x0 - #define OV9281_MODE_STREAMING BIT(0) -@@ -123,6 +127,8 @@ struct ov9281 { - struct v4l2_ctrl *digi_gain; - struct v4l2_ctrl *hblank; - struct v4l2_ctrl *vblank; -+ struct v4l2_ctrl *hflip; -+ struct v4l2_ctrl *vflip; - struct v4l2_ctrl *pixel_rate; - struct v4l2_ctrl *test_pattern; - struct mutex mutex; -@@ -615,6 +621,42 @@ static int ov9281_enable_test_pattern(st - OV9281_REG_VALUE_08BIT, val); - } - -+static int ov9281_set_ctrl_hflip(struct ov9281 *ov9281, int value) -+{ -+ u32 current_val; -+ int ret = ov9281_read_reg(ov9281->client, OV9281_REG_TIMING_FORMAT_2, -+ OV9281_REG_VALUE_08BIT, ¤t_val); -+ if (!ret) { -+ if (value) -+ current_val |= OV9281_FLIP_BIT; -+ else -+ current_val &= ~OV9281_FLIP_BIT; -+ return ov9281_write_reg(ov9281->client, -+ OV9281_REG_TIMING_FORMAT_2, -+ OV9281_REG_VALUE_08BIT, -+ current_val); -+ } -+ return ret; -+} -+ -+static int ov9281_set_ctrl_vflip(struct ov9281 *ov9281, int value) -+{ -+ u32 current_val; -+ int ret = ov9281_read_reg(ov9281->client, OV9281_REG_TIMING_FORMAT_1, -+ OV9281_REG_VALUE_08BIT, ¤t_val); -+ if (!ret) { -+ if (value) -+ current_val |= OV9281_FLIP_BIT; -+ else -+ current_val &= ~OV9281_FLIP_BIT; -+ return ov9281_write_reg(ov9281->client, -+ OV9281_REG_TIMING_FORMAT_1, -+ OV9281_REG_VALUE_08BIT, -+ current_val); -+ } -+ return ret; -+} -+ - static const struct v4l2_rect * - __ov9281_get_pad_crop(struct ov9281 *ov9281, struct v4l2_subdev_pad_config *cfg, - unsigned int pad, enum v4l2_subdev_format_whence which) -@@ -933,6 +975,12 @@ static int ov9281_set_ctrl(struct v4l2_c - return 0; - - switch (ctrl->id) { -+ case V4L2_CID_HFLIP: -+ ret = ov9281_set_ctrl_hflip(ov9281, ctrl->val); -+ break; -+ case V4L2_CID_VFLIP: -+ ret = ov9281_set_ctrl_vflip(ov9281, ctrl->val); -+ break; - case V4L2_CID_EXPOSURE: - /* 4 least significant bits of expsoure are fractional part */ - ret = ov9281_write_reg(ov9281->client, OV9281_REG_EXPOSURE, -@@ -981,7 +1029,7 @@ static int ov9281_initialize_controls(st - - handler = &ov9281->ctrl_handler; - mode = ov9281->cur_mode; -- ret = v4l2_ctrl_handler_init(handler, 8); -+ ret = v4l2_ctrl_handler_init(handler, 9); - if (ret) - return ret; - handler->lock = &ov9281->mutex; -@@ -1022,6 +1070,14 @@ static int ov9281_initialize_controls(st - OV9281_GAIN_STEP, - OV9281_GAIN_DEFAULT); - -+ ov9281->vflip = v4l2_ctrl_new_std(handler, &ov9281_ctrl_ops, -+ V4L2_CID_VFLIP, -+ 0, 1, 1, 0); -+ -+ ov9281->hflip = v4l2_ctrl_new_std(handler, &ov9281_ctrl_ops, -+ V4L2_CID_HFLIP, -+ 0, 1, 1, 0); -+ - ov9281->test_pattern = - v4l2_ctrl_new_std_menu_items(handler, &ov9281_ctrl_ops, - V4L2_CID_TEST_PATTERN, diff --git a/target/linux/bcm27xx/patches-5.15/950-0371-clk-raspberrypi-Also-support-HEVC-clock.patch b/target/linux/bcm27xx/patches-5.15/950-0371-clk-raspberrypi-Also-support-HEVC-clock.patch deleted file mode 100644 index dceb16819..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0371-clk-raspberrypi-Also-support-HEVC-clock.patch +++ /dev/null @@ -1,20 +0,0 @@ -From a6823d1513a3cfd2acbacdf0a9d7d9e510618936 Mon Sep 17 00:00:00 2001 -From: Dom Cobley -Date: Mon, 22 Feb 2021 18:47:19 +0000 -Subject: [PATCH] clk-raspberrypi: Also support HEVC clock - -Signed-off-by: Dom Cobley ---- - drivers/clk/bcm/clk-raspberrypi.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/clk/bcm/clk-raspberrypi.c -+++ b/drivers/clk/bcm/clk-raspberrypi.c -@@ -276,6 +276,7 @@ static int raspberrypi_discover_clocks(s - case RPI_FIRMWARE_CORE_CLK_ID: - case RPI_FIRMWARE_M2MC_CLK_ID: - case RPI_FIRMWARE_V3D_CLK_ID: -+ case RPI_FIRMWARE_HEVC_CLK_ID: - case RPI_FIRMWARE_PIXEL_BVB_CLK_ID: - hw = raspberrypi_clk_register(rpi, clks->parent, - clks->id); diff --git a/target/linux/bcm27xx/patches-5.15/950-0372-rpivid-Request-maximum-hevc-clock.patch b/target/linux/bcm27xx/patches-5.15/950-0372-rpivid-Request-maximum-hevc-clock.patch deleted file mode 100644 index 241b1e738..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0372-rpivid-Request-maximum-hevc-clock.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 276aead8fe8654ba130f2bc866fd8aa7f236e507 Mon Sep 17 00:00:00 2001 -From: Dom Cobley -Date: Mon, 22 Feb 2021 18:50:50 +0000 -Subject: [PATCH] rpivid: Request maximum hevc clock - -Query maximum and minimum clock from driver -and use those - -Signed-off-by: Dom Cobley ---- - drivers/staging/media/rpivid/rpivid_video.c | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - ---- a/drivers/staging/media/rpivid/rpivid_video.c -+++ b/drivers/staging/media/rpivid/rpivid_video.c -@@ -490,6 +490,7 @@ static int rpivid_start_streaming(struct - { - struct rpivid_ctx *ctx = vb2_get_drv_priv(vq); - struct rpivid_dev *dev = ctx->dev; -+ long max_hevc_clock = clk_round_rate(dev->clock, ULONG_MAX); - int ret = 0; - - if (ctx->src_fmt.pixelformat != V4L2_PIX_FMT_HEVC_SLICE) -@@ -498,7 +499,7 @@ static int rpivid_start_streaming(struct - if (V4L2_TYPE_IS_OUTPUT(vq->type) && dev->dec_ops->start) - ret = dev->dec_ops->start(ctx); - -- ret = clk_set_rate(dev->clock, 500 * 1000 * 1000); -+ ret = clk_set_rate(dev->clock, max_hevc_clock); - if (ret) { - dev_err(dev->dev, "Failed to set clock rate\n"); - goto out; -@@ -519,12 +520,18 @@ static void rpivid_stop_streaming(struct - { - struct rpivid_ctx *ctx = vb2_get_drv_priv(vq); - struct rpivid_dev *dev = ctx->dev; -+ long min_hevc_clock = clk_round_rate(dev->clock, 0); -+ int ret; - - if (V4L2_TYPE_IS_OUTPUT(vq->type) && dev->dec_ops->stop) - dev->dec_ops->stop(ctx); - - rpivid_queue_cleanup(vq, VB2_BUF_STATE_ERROR); - -+ ret = clk_set_rate(dev->clock, min_hevc_clock); -+ if (ret) -+ dev_err(dev->dev, "Failed to set minimum clock rate\n"); -+ - clk_disable_unprepare(dev->clock); - } - diff --git a/target/linux/bcm27xx/patches-5.15/950-0375-dwc-otg-fix-clang-Wignored-attributes-warning.patch b/target/linux/bcm27xx/patches-5.15/950-0375-dwc-otg-fix-clang-Wignored-attributes-warning.patch deleted file mode 100644 index b0e54c5c9..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0375-dwc-otg-fix-clang-Wignored-attributes-warning.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 9a07fe13e3dae16f3acbffcbf16176d97584506f Mon Sep 17 00:00:00 2001 -From: Jo Henke <37883863+jo-he@users.noreply.github.com> -Date: Tue, 6 Apr 2021 11:21:35 +0000 -Subject: [PATCH] dwc-otg: fix clang -Wignored-attributes warning - -warning: attribute declaration must precede definition ---- - drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - ---- a/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h -+++ b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h -@@ -255,17 +255,17 @@ struct fiq_dma_info { - u8 slot_len[6]; - }; - --struct __attribute__((packed)) fiq_split_dma_slot { -+struct fiq_split_dma_slot { - u8 buf[188]; --}; -+} __attribute__((packed)); - - struct fiq_dma_channel { -- struct __attribute__((packed)) fiq_split_dma_slot index[6]; --}; -+ struct fiq_split_dma_slot index[6]; -+} __attribute__((packed)); - - struct fiq_dma_blob { -- struct __attribute__((packed)) fiq_dma_channel channel[0]; --}; -+ struct fiq_dma_channel channel[0]; -+} __attribute__((packed)); - - /** - * struct fiq_hs_isoc_info - USB2.0 isochronous data diff --git a/target/linux/bcm27xx/patches-5.15/950-0376-dwc-otg-fix-clang-Wsometimes-uninitialized-warning.patch b/target/linux/bcm27xx/patches-5.15/950-0376-dwc-otg-fix-clang-Wsometimes-uninitialized-warning.patch deleted file mode 100644 index c0749f17a..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0376-dwc-otg-fix-clang-Wsometimes-uninitialized-warning.patch +++ /dev/null @@ -1,21 +0,0 @@ -From da8fee9ca5bce1228e699ab65d346aac737e174c Mon Sep 17 00:00:00 2001 -From: Jo Henke <37883863+jo-he@users.noreply.github.com> -Date: Tue, 6 Apr 2021 11:38:28 +0000 -Subject: [PATCH] dwc-otg: fix clang -Wsometimes-uninitialized warning - -warning: variable 'retval' is used uninitialized whenever 'if' condition is false ---- - drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c -@@ -805,7 +805,7 @@ static int32_t dwc_otg_handle_pwrdn_sess - */ - static uint32_t dwc_otg_handle_pwrdn_stschng_intr(dwc_otg_device_t *otg_dev) - { -- int retval; -+ uint32_t retval = 0; - gpwrdn_data_t gpwrdn = {.d32 = 0 }; - gpwrdn_data_t gpwrdn_temp = {.d32 = 0 }; - dwc_otg_core_if_t *core_if = otg_dev->core_if; diff --git a/target/linux/bcm27xx/patches-5.15/950-0377-dwc-otg-fix-clang-Wpointer-bool-conversion-warning.patch b/target/linux/bcm27xx/patches-5.15/950-0377-dwc-otg-fix-clang-Wpointer-bool-conversion-warning.patch deleted file mode 100644 index 2baab423c..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0377-dwc-otg-fix-clang-Wpointer-bool-conversion-warning.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 92be81ca5125c980e0c4a62c134fbb6e4eb7cd6a Mon Sep 17 00:00:00 2001 -From: Jo Henke <37883863+jo-he@users.noreply.github.com> -Date: Tue, 6 Apr 2021 11:45:14 +0000 -Subject: [PATCH] dwc-otg: fix clang -Wpointer-bool-conversion warning - -warning: address of array 'desc->wMaxPacketSize' will always evaluate to 'true' - -The wMaxPacketSize field is actually a two element array which content should -be accessed via the UGETW macro. ---- - drivers/usb/host/dwc_otg/dwc_otg_pcd.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/usb/host/dwc_otg/dwc_otg_pcd.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_pcd.c -@@ -1487,7 +1487,7 @@ int dwc_otg_pcd_ep_enable(dwc_otg_pcd_t - num = UE_GET_ADDR(desc->bEndpointAddress); - dir = UE_GET_DIR(desc->bEndpointAddress); - -- if (!desc->wMaxPacketSize) { -+ if (!UGETW(desc->wMaxPacketSize)) { - DWC_WARN("bad maxpacketsize\n"); - retval = -DWC_E_INVALID; - goto out; diff --git a/target/linux/bcm27xx/patches-5.15/950-0378-staging-vcsm-cma-Fix-memory-leak-from-not-detaching-.patch b/target/linux/bcm27xx/patches-5.15/950-0378-staging-vcsm-cma-Fix-memory-leak-from-not-detaching-.patch deleted file mode 100644 index f67723676..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0378-staging-vcsm-cma-Fix-memory-leak-from-not-detaching-.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 8c5dbd19e5182253e5f6b1deff6441599e01132d Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Wed, 4 Nov 2020 18:54:20 +0000 -Subject: [PATCH] staging: vcsm-cma: Fix memory leak from not detaching - dmabuf - -When importing there was a missing call to detach the buffer, -so each import leaked the sg table entry. - -Actually the release process for both locally allocated and -imported buffers is identical, so fix them to both use the same -function. - -Signed-off-by: Dave Stevenson ---- - .../staging/vc04_services/vc-sm-cma/vc_sm.c | 22 ++----------------- - 1 file changed, 2 insertions(+), 20 deletions(-) - ---- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c -+++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c -@@ -237,6 +237,7 @@ static void vc_sm_add_resource(struct vc - - /* - * Cleans up imported dmabuf. -+ * Should be called with mutex held. - */ - static void vc_sm_clean_up_dmabuf(struct vc_sm_buffer *buffer) - { -@@ -244,7 +245,6 @@ static void vc_sm_clean_up_dmabuf(struct - return; - - /* Handle cleaning up imported dmabufs */ -- mutex_lock(&buffer->lock); - if (buffer->import.sgt) { - dma_buf_unmap_attachment(buffer->import.attach, - buffer->import.sgt, -@@ -255,7 +255,6 @@ static void vc_sm_clean_up_dmabuf(struct - dma_buf_detach(buffer->dma_buf, buffer->import.attach); - buffer->import.attach = NULL; - } -- mutex_unlock(&buffer->lock); - } - - /* -@@ -673,23 +672,6 @@ int vc_sm_import_dmabuf_mmap(struct dma_ - } - - static --void vc_sm_import_dma_buf_release(struct dma_buf *dmabuf) --{ -- struct vc_sm_buffer *buf = dmabuf->priv; -- -- pr_debug("%s: Relasing dma_buf %p\n", __func__, dmabuf); -- mutex_lock(&buf->lock); -- if (!buf->imported) -- return; -- -- buf->in_use = 0; -- -- vc_sm_vpu_free(buf); -- -- vc_sm_release_resource(buf); --} -- --static - int vc_sm_import_dma_buf_begin_cpu_access(struct dma_buf *dmabuf, - enum dma_data_direction direction) - { -@@ -717,7 +699,7 @@ static const struct dma_buf_ops dma_buf_ - .map_dma_buf = vc_sm_import_map_dma_buf, - .unmap_dma_buf = vc_sm_import_unmap_dma_buf, - .mmap = vc_sm_import_dmabuf_mmap, -- .release = vc_sm_import_dma_buf_release, -+ .release = vc_sm_dma_buf_release, - .attach = vc_sm_import_dma_buf_attach, - .detach = vc_sm_import_dma_buf_detatch, - .begin_cpu_access = vc_sm_import_dma_buf_begin_cpu_access, diff --git a/target/linux/bcm27xx/patches-5.15/950-0379-rpivid-Switch-to-new-clock-api.patch b/target/linux/bcm27xx/patches-5.15/950-0379-rpivid-Switch-to-new-clock-api.patch deleted file mode 100644 index 3bcd2450e..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0379-rpivid-Switch-to-new-clock-api.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 792ae143562fc4d4c22e492d3b1a3216d0fa2d14 Mon Sep 17 00:00:00 2001 -From: Dom Cobley -Date: Mon, 19 Apr 2021 19:30:26 +0100 -Subject: [PATCH] rpivid: Switch to new clock api - -Signed-off-by: Dom Cobley ---- - drivers/staging/media/rpivid/rpivid.h | 1 + - drivers/staging/media/rpivid/rpivid_video.c | 11 +++-------- - 2 files changed, 4 insertions(+), 8 deletions(-) - ---- a/drivers/staging/media/rpivid/rpivid.h -+++ b/drivers/staging/media/rpivid/rpivid.h -@@ -172,6 +172,7 @@ struct rpivid_dev { - void __iomem *base_h265; - - struct clk *clock; -+ struct clk_request *hevc_req; - - struct rpivid_hw_irq_ctrl ic_active1; - struct rpivid_hw_irq_ctrl ic_active2; ---- a/drivers/staging/media/rpivid/rpivid_video.c -+++ b/drivers/staging/media/rpivid/rpivid_video.c -@@ -499,8 +499,8 @@ static int rpivid_start_streaming(struct - if (V4L2_TYPE_IS_OUTPUT(vq->type) && dev->dec_ops->start) - ret = dev->dec_ops->start(ctx); - -- ret = clk_set_rate(dev->clock, max_hevc_clock); -- if (ret) { -+ dev->hevc_req = clk_request_start(dev->clock, max_hevc_clock); -+ if (!dev->hevc_req) { - dev_err(dev->dev, "Failed to set clock rate\n"); - goto out; - } -@@ -520,18 +520,13 @@ static void rpivid_stop_streaming(struct - { - struct rpivid_ctx *ctx = vb2_get_drv_priv(vq); - struct rpivid_dev *dev = ctx->dev; -- long min_hevc_clock = clk_round_rate(dev->clock, 0); -- int ret; - - if (V4L2_TYPE_IS_OUTPUT(vq->type) && dev->dec_ops->stop) - dev->dec_ops->stop(ctx); - - rpivid_queue_cleanup(vq, VB2_BUF_STATE_ERROR); - -- ret = clk_set_rate(dev->clock, min_hevc_clock); -- if (ret) -- dev_err(dev->dev, "Failed to set minimum clock rate\n"); -- -+ clk_request_done(dev->hevc_req); - clk_disable_unprepare(dev->clock); - } - diff --git a/target/linux/bcm27xx/patches-5.15/950-0380-rpivid-Only-clk_request_done-once.patch b/target/linux/bcm27xx/patches-5.15/950-0380-rpivid-Only-clk_request_done-once.patch deleted file mode 100644 index c62ac4587..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0380-rpivid-Only-clk_request_done-once.patch +++ /dev/null @@ -1,26 +0,0 @@ -From b18502733e7a1eeb2011150fb35fe332be7b8f5a Mon Sep 17 00:00:00 2001 -From: Dom Cobley -Date: Tue, 20 Apr 2021 13:34:18 +0100 -Subject: [PATCH] rpivid: Only clk_request_done once - -Fixes: 25486f49bfe2e3ae13b90478d1eebd91413136ad -Signed-off-by: Dom Cobley ---- - drivers/staging/media/rpivid/rpivid_video.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - ---- a/drivers/staging/media/rpivid/rpivid_video.c -+++ b/drivers/staging/media/rpivid/rpivid_video.c -@@ -526,7 +526,11 @@ static void rpivid_stop_streaming(struct - - rpivid_queue_cleanup(vq, VB2_BUF_STATE_ERROR); - -- clk_request_done(dev->hevc_req); -+ if (dev->hevc_req) -+ { -+ clk_request_done(dev->hevc_req); -+ dev->hevc_req = NULL; -+ } - clk_disable_unprepare(dev->clock); - } - diff --git a/target/linux/bcm27xx/patches-5.15/950-0381-dwc_otg-fix-an-undeclared-variable.patch b/target/linux/bcm27xx/patches-5.15/950-0381-dwc_otg-fix-an-undeclared-variable.patch deleted file mode 100644 index 532a1e8f5..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0381-dwc_otg-fix-an-undeclared-variable.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 3888c829511b97d08462844312f24825dea413d9 Mon Sep 17 00:00:00 2001 -From: wangzx <593074943@qq.com> -Date: Tue, 20 Apr 2021 22:33:26 +0800 -Subject: [PATCH] dwc_otg: fix an undeclared variable Replace an - undeclared variable used by DWC_DEBUGPL with the real endpoint address. - DWC_DEBUGPL does nothing with DEBUG undefined so it did not go wrong before. - Signed-off-by: Zixuan Wang - ---- - drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c -@@ -1026,7 +1026,8 @@ static void endpoint_reset(struct usb_hc - dwc_irqflags_t flags; - dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd); - -- DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD EP RESET: Endpoint Num=0x%02d\n", epnum); -+ DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD EP RESET: Endpoint Num=0x%02d\n", -+ ep->desc.bEndpointAddress); - - DWC_SPINLOCK_IRQSAVE(dwc_otg_hcd->lock, &flags); - if (ep->hcpriv) { diff --git a/target/linux/bcm27xx/patches-5.15/950-0383-staging-bcm2835-codec-Fix-support-for-levels-4.1-and.patch b/target/linux/bcm27xx/patches-5.15/950-0383-staging-bcm2835-codec-Fix-support-for-levels-4.1-and.patch deleted file mode 100644 index 16ec06005..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0383-staging-bcm2835-codec-Fix-support-for-levels-4.1-and.patch +++ /dev/null @@ -1,36 +0,0 @@ -From a7c3abc971eb4e7771697a70f8b6ca42bc2b1db0 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 25 Mar 2021 18:28:40 +0000 -Subject: [PATCH] staging/bcm2835-codec: Fix support for levels 4.1 and - 4.2 - -The driver said it supported H264 levels 4.1 and 4.2, but -was missing the V4L2 to MMAL mappings. - -Add in those mappings. - -Signed-off-by: Dave Stevenson ---- - .../vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -1789,6 +1789,17 @@ static int bcm2835_codec_set_level_profi - case V4L2_MPEG_VIDEO_H264_LEVEL_4_0: - param.level = MMAL_VIDEO_LEVEL_H264_4; - break; -+ /* -+ * Note that the hardware spec is level 4.0. Levels above that -+ * are there for correctly encoding the headers and may not -+ * be able to keep up with real-time. -+ */ -+ case V4L2_MPEG_VIDEO_H264_LEVEL_4_1: -+ param.level = MMAL_VIDEO_LEVEL_H264_41; -+ break; -+ case V4L2_MPEG_VIDEO_H264_LEVEL_4_2: -+ param.level = MMAL_VIDEO_LEVEL_H264_42; -+ break; - default: - /* Should never get here */ - break; diff --git a/target/linux/bcm27xx/patches-5.15/950-0384-staging-bcm2835-codec-Set-the-colourspace-appropriat.patch b/target/linux/bcm27xx/patches-5.15/950-0384-staging-bcm2835-codec-Set-the-colourspace-appropriat.patch deleted file mode 100644 index 91443600e..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0384-staging-bcm2835-codec-Set-the-colourspace-appropriat.patch +++ /dev/null @@ -1,83 +0,0 @@ -From f540950062dc13d81cf3cf5d34195bc4948d0c55 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 4 Feb 2021 19:08:23 +0000 -Subject: [PATCH] staging/bcm2835-codec: Set the colourspace - appropriately for RGB formats - -Video decode supports YUV and RGB formats. YUV needs to report SMPTE170M -or REC709 appropriately, whilst RGB should report SRGB. - -Signed-off-by: Dave Stevenson ---- - .../bcm2835-codec/bcm2835-v4l2-codec.c | 51 +++++++++++++------ - 1 file changed, 36 insertions(+), 15 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -930,23 +930,43 @@ static void send_eos_event(struct bcm283 - v4l2_event_queue_fh(&ctx->fh, &ev); - } - --static void color_mmal2v4l(struct bcm2835_codec_ctx *ctx, u32 mmal_color_space) -+static void color_mmal2v4l(struct bcm2835_codec_ctx *ctx, u32 encoding, -+ u32 color_space) - { -- switch (mmal_color_space) { -- case MMAL_COLOR_SPACE_ITUR_BT601: -- ctx->colorspace = V4L2_COLORSPACE_REC709; -- ctx->xfer_func = V4L2_XFER_FUNC_709; -- ctx->ycbcr_enc = V4L2_YCBCR_ENC_601; -- ctx->quant = V4L2_QUANTIZATION_LIM_RANGE; -- break; -+ int is_rgb; - -- case MMAL_COLOR_SPACE_ITUR_BT709: -- ctx->colorspace = V4L2_COLORSPACE_REC709; -- ctx->xfer_func = V4L2_XFER_FUNC_709; -- ctx->ycbcr_enc = V4L2_YCBCR_ENC_709; -- ctx->quant = V4L2_QUANTIZATION_LIM_RANGE; -+ switch (encoding) { -+ case MMAL_ENCODING_I420: -+ case MMAL_ENCODING_YV12: -+ case MMAL_ENCODING_NV12: -+ case MMAL_ENCODING_NV21: -+ case V4L2_PIX_FMT_YUYV: -+ case V4L2_PIX_FMT_YVYU: -+ case V4L2_PIX_FMT_UYVY: -+ case V4L2_PIX_FMT_VYUY: -+ /* YUV based colourspaces */ -+ switch (color_space) { -+ case MMAL_COLOR_SPACE_ITUR_BT601: -+ ctx->colorspace = V4L2_COLORSPACE_SMPTE170M; -+ break; -+ -+ case MMAL_COLOR_SPACE_ITUR_BT709: -+ ctx->colorspace = V4L2_COLORSPACE_REC709; -+ break; -+ default: -+ break; -+ } -+ break; -+ default: -+ /* RGB based colourspaces */ -+ ctx->colorspace = V4L2_COLORSPACE_SRGB; - break; - } -+ ctx->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(ctx->colorspace); -+ ctx->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(ctx->colorspace); -+ is_rgb = ctx->colorspace == V4L2_COLORSPACE_SRGB; -+ ctx->quant = V4L2_MAP_QUANTIZATION_DEFAULT(is_rgb, ctx->colorspace, -+ ctx->ycbcr_enc); - } - - static void handle_fmt_changed(struct bcm2835_codec_ctx *ctx, -@@ -985,7 +1005,8 @@ static void handle_fmt_changed(struct bc - q_data->height = format->es.video.height; - q_data->sizeimage = format->buffer_size_min; - if (format->es.video.color_space) -- color_mmal2v4l(ctx, format->es.video.color_space); -+ color_mmal2v4l(ctx, format->format.encoding, -+ format->es.video.color_space); - - q_data->aspect_ratio.numerator = format->es.video.par.num; - q_data->aspect_ratio.denominator = format->es.video.par.den; diff --git a/target/linux/bcm27xx/patches-5.15/950-0385-staging-bcm2835-codec-Pass-corrupt-frame-flag.patch b/target/linux/bcm27xx/patches-5.15/950-0385-staging-bcm2835-codec-Pass-corrupt-frame-flag.patch deleted file mode 100644 index 4f1aa13b5..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0385-staging-bcm2835-codec-Pass-corrupt-frame-flag.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 4cbf4590272002606374d4fcd31f99be85869a13 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Wed, 9 Dec 2020 18:53:56 +0000 -Subject: [PATCH] staging/bcm2835-codec: Pass corrupt frame flag. - -MMAL has the flag MMAL_BUFFER_HEADER_FLAG_CORRUPTED but that -wasn't being passed through, so add it. - -Signed-off-by: Dave Stevenson ---- - .../vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -1019,6 +1019,7 @@ static void op_buffer_cb(struct vchiq_mm - struct mmal_buffer *mmal_buf) - { - struct bcm2835_codec_ctx *ctx = port->cb_ctx; -+ enum vb2_buffer_state buf_state = VB2_BUF_STATE_DONE; - struct m2m_mmal_buffer *buf; - struct vb2_v4l2_buffer *vb2; - -@@ -1075,6 +1076,9 @@ static void op_buffer_cb(struct vchiq_mm - vb2->flags |= V4L2_BUF_FLAG_LAST; - } - -+ if (mmal_buf->mmal_flags & MMAL_BUFFER_HEADER_FLAG_CORRUPTED) -+ buf_state = VB2_BUF_STATE_ERROR; -+ - /* vb2 timestamps in nsecs, mmal in usecs */ - vb2->vb2_buf.timestamp = mmal_buf->pts * 1000; - -@@ -1082,7 +1086,7 @@ static void op_buffer_cb(struct vchiq_mm - if (mmal_buf->mmal_flags & MMAL_BUFFER_HEADER_FLAG_KEYFRAME) - vb2->flags |= V4L2_BUF_FLAG_KEYFRAME; - -- vb2_buffer_done(&vb2->vb2_buf, VB2_BUF_STATE_DONE); -+ vb2_buffer_done(&vb2->vb2_buf, buf_state); - ctx->num_op_buffers++; - - v4l2_dbg(2, debug, &ctx->dev->v4l2_dev, "%s: done %d output buffers\n", diff --git a/target/linux/bcm27xx/patches-5.15/950-0387-staging-bcm2835-codec-Do-not-update-crop-from-S_FMT-.patch b/target/linux/bcm27xx/patches-5.15/950-0387-staging-bcm2835-codec-Do-not-update-crop-from-S_FMT-.patch deleted file mode 100644 index c87ca955b..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0387-staging-bcm2835-codec-Do-not-update-crop-from-S_FMT-.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 9a7b20e4a376a2cccb2fb8d3e87eb4358c17d2e8 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 15 Apr 2021 11:07:55 +0100 -Subject: [PATCH] staging/bcm2835-codec: Do not update crop from S_FMT - after res change - -During decode, setting the CAPTURE queue format was setting the crop -rectangle to the requested height before aligning up the format to -cater for simple clients that weren't expecting to deal with cropping -and the SELECTION API. -This caused problems on some resolution change events if the client -didn't also then use the selection API. - -Disable the crop update after a resolution change. - -Signed-off-by: Dave Stevenson ---- - .../vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c | 7 +++++++ - 1 file changed, 7 insertions(+) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -999,6 +999,13 @@ static void handle_fmt_changed(struct bc - - q_data->crop_width = format->es.video.crop.width; - q_data->crop_height = format->es.video.crop.height; -+ /* -+ * Stop S_FMT updating crop_height should it be unaligned. -+ * Client can still update the crop region via S_SELECTION should it -+ * really want to, but the decoder is likely to complain that the -+ * format then doesn't match. -+ */ -+ q_data->selection_set = true; - q_data->bytesperline = get_bytesperline(format->es.video.width, - q_data->fmt); - diff --git a/target/linux/bcm27xx/patches-5.15/950-0393-media-rpivid-Remove-the-need-to-have-num_entry_point.patch b/target/linux/bcm27xx/patches-5.15/950-0393-media-rpivid-Remove-the-need-to-have-num_entry_point.patch deleted file mode 100644 index aec95636f..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0393-media-rpivid-Remove-the-need-to-have-num_entry_point.patch +++ /dev/null @@ -1,980 +0,0 @@ -From 4b33f988d9da9776bcfe218df4ab9865f4b771a8 Mon Sep 17 00:00:00 2001 -From: John Cox -Date: Thu, 21 May 2020 11:49:37 +0100 -Subject: [PATCH] media: rpivid: Remove the need to have - num_entry_points set - -VAAPI H265 has num entry points but never sets it. Allow a VAAPI -shim to work without requiring rewriting the VAAPI driver. -num_entry_points can be calculated from the slice_segment_addr -of the next slice so delay processing until we have that. - -Also includes some minor cosmetics. - -Signed-off-by: John Cox ---- - drivers/staging/media/rpivid/rpivid_h265.c | 699 +++++++++++---------- - 1 file changed, 365 insertions(+), 334 deletions(-) - ---- a/drivers/staging/media/rpivid/rpivid_h265.c -+++ b/drivers/staging/media/rpivid/rpivid_h265.c -@@ -202,8 +202,17 @@ struct rpivid_dec_env { - unsigned int dpbno_col; - u32 reg_slicestart; - int collocated_from_l0_flag; -- unsigned int wpp_entry_x; -- unsigned int wpp_entry_y; -+ /* -+ * Last CTB/Tile X,Y processed by (wpp_)entry_point -+ * Could be in _state as P0 only but needs updating where _state -+ * is const -+ */ -+ unsigned int entry_ctb_x; -+ unsigned int entry_ctb_y; -+ unsigned int entry_tile_x; -+ unsigned int entry_tile_y; -+ unsigned int entry_qp; -+ u32 entry_slice; - - u32 rpi_config2; - u32 rpi_framesize; -@@ -239,22 +248,17 @@ struct rpivid_dec_state { - struct v4l2_ctrl_hevc_pps pps; - - // Helper vars & tables derived from sps/pps -- unsigned int log2_ctb_size; /* log2 width of a CTB */ -- unsigned int ctb_width; /* Width in CTBs */ -- unsigned int ctb_height; /* Height in CTBs */ -- unsigned int ctb_size; /* Pic area in CTBs */ -- unsigned int num_tile_columns; -- unsigned int num_tile_rows; -- u8 column_width[member_size(struct v4l2_ctrl_hevc_pps, -- column_width_minus1)]; -- u8 row_height[member_size(struct v4l2_ctrl_hevc_pps, -- row_height_minus1)]; -+ unsigned int log2_ctb_size; /* log2 width of a CTB */ -+ unsigned int ctb_width; /* Width in CTBs */ -+ unsigned int ctb_height; /* Height in CTBs */ -+ unsigned int ctb_size; /* Pic area in CTBs */ -+ unsigned int tile_width; /* Width in tiles */ -+ unsigned int tile_height; /* Height in tiles */ - - int *col_bd; - int *row_bd; - int *ctb_addr_rs_to_ts; - int *ctb_addr_ts_to_rs; -- int *tile_id; - - // Aux starage for DPB - // Hold refs -@@ -274,6 +278,12 @@ struct rpivid_dec_state { - unsigned int slice_qp; - unsigned int max_num_merge_cand; // 0 if I-slice - bool dependent_slice_segment_flag; -+ -+ unsigned int start_ts; /* slice_segment_addr -> ts */ -+ unsigned int start_ctb_x; /* CTB X,Y of start_ts */ -+ unsigned int start_ctb_y; -+ unsigned int prev_ctb_x; /* CTB X,Y of start_ts - 1 */ -+ unsigned int prev_ctb_y; - }; - - static inline int clip_int(const int x, const int lo, const int hi) -@@ -319,15 +329,16 @@ static int ctb_to_tile(unsigned int ctb, - return i - 1; - } - --static int ctb_to_slice_w_h(unsigned int ctb, int ctb_size, int width, -- unsigned int *bd, int num) -+static unsigned int ctb_to_tile_x(const struct rpivid_dec_state *const s, -+ const unsigned int ctb_x) - { -- if (ctb < bd[num - 1]) -- return ctb_size; -- else if (width % ctb_size) -- return width % ctb_size; -- else -- return ctb_size; -+ return ctb_to_tile(ctb_x, s->col_bd, s->tile_width); -+} -+ -+static unsigned int ctb_to_tile_y(const struct rpivid_dec_state *const s, -+ const unsigned int ctb_y) -+{ -+ return ctb_to_tile(ctb_y, s->row_bd, s->tile_height); - } - - static void aux_q_free(struct rpivid_ctx *const ctx, -@@ -532,6 +543,15 @@ static void write_prob(struct rpivid_dec - p1_apb_write(de, 0x1000 + i, - dst[i] + (dst[i + 1] << 8) + (dst[i + 2] << 16) + - (dst[i + 3] << 24)); -+ -+ /* -+ * Having written the prob array back it up -+ * This is not always needed but is a small overhead that simplifies -+ * (and speeds up) some multi-tile & WPP scenarios -+ * There are no scenarios where having written a prob we ever want -+ * a previous (non-initial) state back -+ */ -+ p1_apb_write(de, RPI_TRANSFER, PROB_BACKUP); - } - - static void write_scaling_factors(struct rpivid_dec_env *const de) -@@ -552,8 +572,8 @@ static inline __u32 dma_to_axi_addr(dma_ - static void write_bitstream(struct rpivid_dec_env *const de, - const struct rpivid_dec_state *const s) - { -- // Note that FFmpeg removes emulation prevention bytes, so this is -- // matched in the configuration here. -+ // Note that FFmpeg V4L2 does not remove emulation prevention bytes, -+ // so this is matched in the configuration here. - // Whether that is the correct behaviour or not is not clear in the - // spec. - const int rpi_use_emu = 1; -@@ -579,78 +599,26 @@ static void write_bitstream(struct rpivi - - ////////////////////////////////////////////////////////////////////////////// - --static void write_slice(struct rpivid_dec_env *const de, -- const struct rpivid_dec_state *const s, -- const unsigned int slice_w, -- const unsigned int slice_h) --{ -- u32 u32 = (s->sh->slice_type << 12) + -- (((s->sh->flags & -- V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_SAO_LUMA) != 0) -- << 14) + -- (((s->sh->flags & -- V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_SAO_CHROMA) != 0) -- << 15) + -- (slice_w << 17) + (slice_h << 24); -- -- u32 |= (s->max_num_merge_cand << 0) + (s->nb_refs[L0] << 4) + -- (s->nb_refs[L1] << 8); -- -- if (s->sh->slice_type == HEVC_SLICE_B) -- u32 |= ((s->sh->flags & -- V4L2_HEVC_SLICE_PARAMS_FLAG_MVD_L1_ZERO) != 0) -- << 16; -- p1_apb_write(de, RPI_SLICE, u32); --} -- --////////////////////////////////////////////////////////////////////////////// --// Tiles mode -- --static void new_entry_point(struct rpivid_dec_env *const de, -- const struct rpivid_dec_state *const s, -- const int do_bte, -- const int reset_qp_y, const int ctb_addr_ts) -+/* -+ * The slice constant part of the slice register - width and height need to -+ * be ORed in later as they are per-tile / WPP-row -+ */ -+static u32 slice_reg_const(const struct rpivid_dec_state *const s) - { -- int ctb_col = s->ctb_addr_ts_to_rs[ctb_addr_ts] % -- de->pic_width_in_ctbs_y; -- int ctb_row = s->ctb_addr_ts_to_rs[ctb_addr_ts] / -- de->pic_width_in_ctbs_y; -- -- int tile_x = ctb_to_tile(ctb_col, s->col_bd, s->num_tile_columns); -- int tile_y = ctb_to_tile(ctb_row, s->row_bd, s->num_tile_rows); -- -- int endx = s->col_bd[tile_x + 1] - 1; -- int endy = s->row_bd[tile_y + 1] - 1; -- -- u8 slice_w = ctb_to_slice_w_h(ctb_col, 1 << s->log2_ctb_size, -- s->sps.pic_width_in_luma_samples, -- s->col_bd, s->num_tile_columns); -- u8 slice_h = ctb_to_slice_w_h(ctb_row, 1 << s->log2_ctb_size, -- s->sps.pic_height_in_luma_samples, -- s->row_bd, s->num_tile_rows); -- -- p1_apb_write(de, RPI_TILESTART, -- s->col_bd[tile_x] + (s->row_bd[tile_y] << 16)); -- p1_apb_write(de, RPI_TILEEND, endx + (endy << 16)); -- -- if (do_bte) -- p1_apb_write(de, RPI_BEGINTILEEND, endx + (endy << 16)); -+ u32 x = (s->max_num_merge_cand << 0) | -+ (s->nb_refs[L0] << 4) | -+ (s->nb_refs[L1] << 8) | -+ (s->sh->slice_type << 12); -+ -+ if (s->sh->flags & V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_SAO_LUMA) -+ x |= BIT(14); -+ if (s->sh->flags & V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_SAO_CHROMA) -+ x |= BIT(15); -+ if (s->sh->slice_type == HEVC_SLICE_B && -+ (s->sh->flags & V4L2_HEVC_SLICE_PARAMS_FLAG_MVD_L1_ZERO)) -+ x |= BIT(16); - -- write_slice(de, s, slice_w, slice_h); -- -- if (reset_qp_y) { -- unsigned int sps_qp_bd_offset = -- 6 * s->sps.bit_depth_luma_minus8; -- -- p1_apb_write(de, RPI_QP, sps_qp_bd_offset + s->slice_qp); -- } -- -- p1_apb_write(de, RPI_MODE, -- (0xFFFF << 0) + (0x0 << 16) + -- ((tile_x == s->num_tile_columns - 1) << 17) + -- ((tile_y == s->num_tile_rows - 1) << 18)); -- -- p1_apb_write(de, RPI_CONTROL, (ctb_col << 0) + (ctb_row << 16)); -+ return x; - } - - ////////////////////////////////////////////////////////////////////////////// -@@ -934,197 +902,256 @@ static void pre_slice_decode(struct rpiv - (sh->slice_cb_qp_offset & 31)); // CMD_QPOFF - } - --////////////////////////////////////////////////////////////////////////////// --// Write STATUS register with expected end CTU address of previous slice -- --static void end_previous_slice(struct rpivid_dec_env *const de, -- const struct rpivid_dec_state *const s, -- const int ctb_addr_ts) --{ -- int last_x = -- s->ctb_addr_ts_to_rs[ctb_addr_ts - 1] % de->pic_width_in_ctbs_y; -- int last_y = -- s->ctb_addr_ts_to_rs[ctb_addr_ts - 1] / de->pic_width_in_ctbs_y; -- -- p1_apb_write(de, RPI_STATUS, 1 + (last_x << 5) + (last_y << 18)); --} -- --static void wpp_pause(struct rpivid_dec_env *const de, int ctb_row) --{ -- p1_apb_write(de, RPI_STATUS, (ctb_row << 18) + 0x25); -- p1_apb_write(de, RPI_TRANSFER, PROB_BACKUP); -- p1_apb_write(de, RPI_MODE, -- ctb_row == de->pic_height_in_ctbs_y - 1 ? -- 0x70000 : 0x30000); -- p1_apb_write(de, RPI_CONTROL, (ctb_row << 16) + 2); --} -- --static void wpp_end_previous_slice(struct rpivid_dec_env *const de, -- const struct rpivid_dec_state *const s, -- int ctb_addr_ts) --{ -- int new_x = s->sh->slice_segment_addr % de->pic_width_in_ctbs_y; -- int new_y = s->sh->slice_segment_addr / de->pic_width_in_ctbs_y; -- int last_x = -- s->ctb_addr_ts_to_rs[ctb_addr_ts - 1] % de->pic_width_in_ctbs_y; -- int last_y = -- s->ctb_addr_ts_to_rs[ctb_addr_ts - 1] / de->pic_width_in_ctbs_y; -- -- if (de->wpp_entry_x < 2 && (de->wpp_entry_y < new_y || new_x > 2) && -- de->pic_width_in_ctbs_y > 2) -- wpp_pause(de, last_y); -- p1_apb_write(de, RPI_STATUS, 1 + (last_x << 5) + (last_y << 18)); -- if (new_x == 2 || (de->pic_width_in_ctbs_y == 2 && -- de->wpp_entry_y < new_y)) -- p1_apb_write(de, RPI_TRANSFER, PROB_BACKUP); -+static void write_slice(struct rpivid_dec_env *const de, -+ const struct rpivid_dec_state *const s, -+ const u32 slice_const, -+ const unsigned int ctb_col, -+ const unsigned int ctb_row) -+{ -+ const unsigned int cs = (1 << s->log2_ctb_size); -+ const unsigned int w_last = s->sps.pic_width_in_luma_samples & (cs - 1); -+ const unsigned int h_last = s->sps.pic_height_in_luma_samples & (cs - 1); -+ -+ p1_apb_write(de, RPI_SLICE, -+ slice_const | -+ ((ctb_col + 1 < s->ctb_width || !w_last ? -+ cs : w_last) << 17) | -+ ((ctb_row + 1 < s->ctb_height || !h_last ? -+ cs : h_last) << 24)); - } - --////////////////////////////////////////////////////////////////////////////// --// Wavefront mode -+#define PAUSE_MODE_WPP 1 -+#define PAUSE_MODE_TILE 0xffff - --static void wpp_entry_point(struct rpivid_dec_env *const de, -+/* -+ * N.B. This can be called to fill in data from the previous slice so must not -+ * use any state data that may change from slice to slice (e.g. qp) -+ */ -+static void new_entry_point(struct rpivid_dec_env *const de, - const struct rpivid_dec_state *const s, -- const int do_bte, -- const int reset_qp_y, const int ctb_addr_ts) --{ -- int ctb_size = 1 << s->log2_ctb_size; -- int ctb_addr_rs = s->ctb_addr_ts_to_rs[ctb_addr_ts]; -- -- int ctb_col = de->wpp_entry_x = ctb_addr_rs % de->pic_width_in_ctbs_y; -- int ctb_row = de->wpp_entry_y = ctb_addr_rs / de->pic_width_in_ctbs_y; -+ const bool do_bte, -+ const bool reset_qp_y, -+ const u32 pause_mode, -+ const unsigned int tile_x, -+ const unsigned int tile_y, -+ const unsigned int ctb_col, -+ const unsigned int ctb_row, -+ const unsigned int slice_qp, -+ const u32 slice_const) -+{ -+ const unsigned int endx = s->col_bd[tile_x + 1] - 1; -+ const unsigned int endy = (pause_mode == PAUSE_MODE_WPP) ? -+ ctb_row : s->row_bd[tile_y + 1] - 1; - -- int endx = de->pic_width_in_ctbs_y - 1; -- int endy = ctb_row; -- -- u8 slice_w = ctb_to_slice_w_h(ctb_col, ctb_size, -- s->sps.pic_width_in_luma_samples, -- s->col_bd, s->num_tile_columns); -- u8 slice_h = ctb_to_slice_w_h(ctb_row, ctb_size, -- s->sps.pic_height_in_luma_samples, -- s->row_bd, s->num_tile_rows); -- -- p1_apb_write(de, RPI_TILESTART, 0); -- p1_apb_write(de, RPI_TILEEND, endx + (endy << 16)); -+ p1_apb_write(de, RPI_TILESTART, -+ s->col_bd[tile_x] | (s->row_bd[tile_y] << 16)); -+ p1_apb_write(de, RPI_TILEEND, endx | (endy << 16)); - - if (do_bte) -- p1_apb_write(de, RPI_BEGINTILEEND, endx + (endy << 16)); -+ p1_apb_write(de, RPI_BEGINTILEEND, endx | (endy << 16)); - -- write_slice(de, s, slice_w, -- ctb_row == de->pic_height_in_ctbs_y - 1 ? -- slice_h : ctb_size); -+ write_slice(de, s, slice_const, endx, endy); - - if (reset_qp_y) { - unsigned int sps_qp_bd_offset = - 6 * s->sps.bit_depth_luma_minus8; - -- p1_apb_write(de, RPI_QP, sps_qp_bd_offset + s->slice_qp); -+ p1_apb_write(de, RPI_QP, sps_qp_bd_offset + slice_qp); - } - - p1_apb_write(de, RPI_MODE, -- ctb_row == de->pic_height_in_ctbs_y - 1 ? -- 0x60001 : 0x20001); -- p1_apb_write(de, RPI_CONTROL, (ctb_col << 0) + (ctb_row << 16)); -+ pause_mode | -+ ((endx == s->ctb_width - 1) << 17) | -+ ((endy == s->ctb_height - 1) << 18)); -+ -+ p1_apb_write(de, RPI_CONTROL, (ctb_col << 0) | (ctb_row << 16)); -+ -+ de->entry_tile_x = tile_x; -+ de->entry_tile_y = tile_y; -+ de->entry_ctb_x = ctb_col; -+ de->entry_ctb_y = ctb_row; -+ de->entry_qp = slice_qp; -+ de->entry_slice = slice_const; - } - - ////////////////////////////////////////////////////////////////////////////// - // Wavefront mode - -+static void wpp_pause(struct rpivid_dec_env *const de, int ctb_row) -+{ -+ p1_apb_write(de, RPI_STATUS, (ctb_row << 18) | 0x25); -+ p1_apb_write(de, RPI_TRANSFER, PROB_BACKUP); -+ p1_apb_write(de, RPI_MODE, -+ ctb_row == de->pic_height_in_ctbs_y - 1 ? -+ 0x70000 : 0x30000); -+ p1_apb_write(de, RPI_CONTROL, (ctb_row << 16) + 2); -+} -+ -+static void wpp_entry_fill(struct rpivid_dec_env *const de, -+ const struct rpivid_dec_state *const s, -+ const unsigned int last_y) -+{ -+ const unsigned int last_x = s->ctb_width - 1; -+ -+ while (de->entry_ctb_y < last_y) { -+ /* wpp_entry_x/y set by wpp_entry_point */ -+ if (s->ctb_width > 2) -+ wpp_pause(de, de->entry_ctb_y); -+ p1_apb_write(de, RPI_STATUS, -+ (de->entry_ctb_y << 18) | (last_x << 5) | 2); -+ -+ /* if width == 1 then the saved state is the init one */ -+ if (s->ctb_width == 2) -+ p1_apb_write(de, RPI_TRANSFER, PROB_BACKUP); -+ else -+ p1_apb_write(de, RPI_TRANSFER, PROB_RELOAD); -+ -+ new_entry_point(de, s, false, true, PAUSE_MODE_WPP, -+ 0, 0, 0, de->entry_ctb_y + 1, -+ de->entry_qp, de->entry_slice); -+ } -+} -+ -+static void wpp_end_previous_slice(struct rpivid_dec_env *const de, -+ const struct rpivid_dec_state *const s) -+{ -+ wpp_entry_fill(de, s, s->prev_ctb_y); -+ -+ if (de->entry_ctb_x < 2 && -+ (de->entry_ctb_y < s->start_ctb_y || s->start_ctb_x > 2) && -+ s->ctb_width > 2) -+ wpp_pause(de, s->prev_ctb_y); -+ p1_apb_write(de, RPI_STATUS, -+ 1 | (s->prev_ctb_x << 5) | (s->prev_ctb_y << 18)); -+ if (s->start_ctb_x == 2 || -+ (s->ctb_width == 2 && de->entry_ctb_y < s->start_ctb_y)) -+ p1_apb_write(de, RPI_TRANSFER, PROB_BACKUP); -+} -+ -+/* Only main profile supported so WPP => !Tiles which makes some of the -+ * next chunk code simpler -+ */ - static void wpp_decode_slice(struct rpivid_dec_env *const de, -- const struct rpivid_dec_state *const s, -- const struct v4l2_ctrl_hevc_slice_params *sh, -- int ctb_addr_ts) --{ -- int i, reset_qp_y = 1; -- int indep = !s->dependent_slice_segment_flag; -- int ctb_col = s->sh->slice_segment_addr % de->pic_width_in_ctbs_y; -+ const struct rpivid_dec_state *const s) -+{ -+ bool reset_qp_y = true; -+ const bool indep = !s->dependent_slice_segment_flag; - -- if (ctb_addr_ts) -- wpp_end_previous_slice(de, s, ctb_addr_ts); -+ if (s->start_ts) -+ wpp_end_previous_slice(de, s); - pre_slice_decode(de, s); - write_bitstream(de, s); -- if (ctb_addr_ts == 0 || indep || de->pic_width_in_ctbs_y == 1) -+ -+ if (!s->start_ts || indep || s->ctb_width == 1) - write_prob(de, s); -- else if (ctb_col == 0) -+ else if (!s->start_ctb_x) - p1_apb_write(de, RPI_TRANSFER, PROB_RELOAD); - else -- reset_qp_y = 0; -+ reset_qp_y = false; -+ - program_slicecmds(de, s->slice_idx); - new_slice_segment(de, s); -- wpp_entry_point(de, s, indep, reset_qp_y, ctb_addr_ts); -+ new_entry_point(de, s, indep, reset_qp_y, PAUSE_MODE_WPP, -+ 0, 0, s->start_ctb_x, s->start_ctb_y, -+ s->slice_qp, slice_reg_const(s)); - -- for (i = 0; i < s->sh->num_entry_point_offsets; i++) { -- int ctb_addr_rs = s->ctb_addr_ts_to_rs[ctb_addr_ts]; -- int ctb_row = ctb_addr_rs / de->pic_width_in_ctbs_y; -- int last_x = de->pic_width_in_ctbs_y - 1; -+ if (s->frame_end) { -+ wpp_entry_fill(de, s, s->ctb_height - 1); -+ -+ if (de->entry_ctb_x < 2 && s->ctb_width > 2) -+ wpp_pause(de, s->ctb_height - 1); - -- if (de->pic_width_in_ctbs_y > 2) -- wpp_pause(de, ctb_row); - p1_apb_write(de, RPI_STATUS, -- (ctb_row << 18) + (last_x << 5) + 2); -- if (de->pic_width_in_ctbs_y == 2) -- p1_apb_write(de, RPI_TRANSFER, PROB_BACKUP); -- if (de->pic_width_in_ctbs_y == 1) -- write_prob(de, s); -- else -- p1_apb_write(de, RPI_TRANSFER, PROB_RELOAD); -- ctb_addr_ts += s->column_width[0]; -- wpp_entry_point(de, s, 0, 1, ctb_addr_ts); -+ 1 | ((s->ctb_width - 1) << 5) | -+ ((s->ctb_height - 1) << 18)); - } -+ - } - - ////////////////////////////////////////////////////////////////////////////// - // Tiles mode - -+static void tile_entry_fill(struct rpivid_dec_env *const de, -+ const struct rpivid_dec_state *const s, -+ const unsigned int last_tile_x, -+ const unsigned int last_tile_y) -+{ -+ while (de->entry_tile_y < last_tile_y || -+ (de->entry_tile_y == last_tile_y && -+ de->entry_tile_x < last_tile_x)) { -+ unsigned int t_x = de->entry_tile_x; -+ unsigned int t_y = de->entry_tile_y; -+ const unsigned int last_x = s->col_bd[t_x + 1] - 1; -+ const unsigned int last_y = s->row_bd[t_y + 1] - 1; -+ -+ p1_apb_write(de, RPI_STATUS, -+ 2 | (last_x << 5) | (last_y << 18)); -+ p1_apb_write(de, RPI_TRANSFER, PROB_RELOAD); -+ -+ // Inc tile -+ if (++t_x >= s->tile_width) { -+ t_x = 0; -+ ++t_y; -+ } -+ -+ new_entry_point(de, s, false, true, PAUSE_MODE_TILE, -+ t_x, t_y, s->col_bd[t_x], s->row_bd[t_y], -+ de->entry_qp, de->entry_slice); -+ } -+} -+ -+/* -+ * Write STATUS register with expected end CTU address of previous slice -+ */ -+static void end_previous_slice(struct rpivid_dec_env *const de, -+ const struct rpivid_dec_state *const s) -+{ -+ tile_entry_fill(de, s, -+ ctb_to_tile_x(s, s->prev_ctb_x), -+ ctb_to_tile_y(s, s->prev_ctb_y)); -+ p1_apb_write(de, RPI_STATUS, -+ 1 | (s->prev_ctb_x << 5) | (s->prev_ctb_y << 18)); -+} -+ - static void decode_slice(struct rpivid_dec_env *const de, -- const struct rpivid_dec_state *const s, -- const struct v4l2_ctrl_hevc_slice_params *const sh, -- int ctb_addr_ts) -+ const struct rpivid_dec_state *const s) - { -- int i, reset_qp_y; -+ bool reset_qp_y; -+ unsigned int tile_x = ctb_to_tile_x(s, s->start_ctb_x); -+ unsigned int tile_y = ctb_to_tile_y(s, s->start_ctb_y); - -- if (ctb_addr_ts) -- end_previous_slice(de, s, ctb_addr_ts); -+ if (s->start_ts) -+ end_previous_slice(de, s); - - pre_slice_decode(de, s); - write_bitstream(de, s); - --#if DEBUG_TRACE_P1_CMD -- if (p1_z < 256) { -- v4l2_info(&de->ctx->dev->v4l2_dev, -- "TS=%d, tile=%d/%d, dss=%d, flags=%#llx\n", -- ctb_addr_ts, s->tile_id[ctb_addr_ts], -- s->tile_id[ctb_addr_ts - 1], -- s->dependent_slice_segment_flag, sh->flags); -- } --#endif -- -- reset_qp_y = ctb_addr_ts == 0 || -- s->tile_id[ctb_addr_ts] != s->tile_id[ctb_addr_ts - 1] || -- !s->dependent_slice_segment_flag; -+ reset_qp_y = !s->start_ts || -+ !s->dependent_slice_segment_flag || -+ tile_x != ctb_to_tile_x(s, s->prev_ctb_x) || -+ tile_y != ctb_to_tile_y(s, s->prev_ctb_y); - if (reset_qp_y) - write_prob(de, s); - - program_slicecmds(de, s->slice_idx); - new_slice_segment(de, s); - new_entry_point(de, s, !s->dependent_slice_segment_flag, reset_qp_y, -- ctb_addr_ts); -- -- for (i = 0; i < s->sh->num_entry_point_offsets; i++) { -- int ctb_addr_rs = s->ctb_addr_ts_to_rs[ctb_addr_ts]; -- int ctb_col = ctb_addr_rs % de->pic_width_in_ctbs_y; -- int ctb_row = ctb_addr_rs / de->pic_width_in_ctbs_y; -- int tile_x = ctb_to_tile(ctb_col, s->col_bd, -- s->num_tile_columns - 1); -- int tile_y = -- ctb_to_tile(ctb_row, s->row_bd, s->num_tile_rows - 1); -- int last_x = s->col_bd[tile_x + 1] - 1; -- int last_y = s->row_bd[tile_y + 1] - 1; -+ PAUSE_MODE_TILE, -+ tile_x, tile_y, s->start_ctb_x, s->start_ctb_y, -+ s->slice_qp, slice_reg_const(s)); - -+ /* -+ * If this is the last slice then fill in the other tile entries -+ * now, otherwise this will be done at the start of the next slice -+ * when it will be known where this slice finishes -+ */ -+ if (s->frame_end) { -+ tile_entry_fill(de, s, -+ s->tile_width - 1, -+ s->tile_height - 1); - p1_apb_write(de, RPI_STATUS, -- 2 + (last_x << 5) + (last_y << 18)); -- write_prob(de, s); -- ctb_addr_ts += s->column_width[tile_x] * s->row_height[tile_y]; -- new_entry_point(de, s, 0, 1, ctb_addr_ts); -+ 1 | ((s->ctb_width - 1) << 5) | -+ ((s->ctb_height - 1) << 18)); - } - } - -@@ -1132,13 +1159,12 @@ static void decode_slice(struct rpivid_d - // Scaling factors - - static void expand_scaling_list(const unsigned int size_id, -- const unsigned int matrix_id, u8 *const dst0, -+ u8 *const dst0, - const u8 *const src0, uint8_t dc) - { - u8 *d; - unsigned int x, y; - -- // FIXME: matrix_id is unused ? - switch (size_id) { - case 0: - memcpy(dst0, src0, 16); -@@ -1199,24 +1225,20 @@ static void populate_scaling_factors(con - unsigned int mid; - - for (mid = 0; mid < 6; mid++) -- expand_scaling_list(0, mid, -- de->scaling_factors + -+ expand_scaling_list(0, de->scaling_factors + - scaling_factor_offsets[0][mid], - sl->scaling_list_4x4[mid], 0); - for (mid = 0; mid < 6; mid++) -- expand_scaling_list(1, mid, -- de->scaling_factors + -+ expand_scaling_list(1, de->scaling_factors + - scaling_factor_offsets[1][mid], - sl->scaling_list_8x8[mid], 0); - for (mid = 0; mid < 6; mid++) -- expand_scaling_list(2, mid, -- de->scaling_factors + -+ expand_scaling_list(2, de->scaling_factors + - scaling_factor_offsets[2][mid], - sl->scaling_list_16x16[mid], - sl->scaling_list_dc_coef_16x16[mid]); -- for (mid = 0; mid < 2; mid += 1) -- expand_scaling_list(3, mid, -- de->scaling_factors + -+ for (mid = 0; mid < 2; mid++) -+ expand_scaling_list(3, de->scaling_factors + - scaling_factor_offsets[3][mid], - sl->scaling_list_32x32[mid], - sl->scaling_list_dc_coef_32x32[mid]); -@@ -1228,8 +1250,6 @@ static void free_ps_info(struct rpivid_d - s->ctb_addr_rs_to_ts = NULL; - kfree(s->ctb_addr_ts_to_rs); - s->ctb_addr_ts_to_rs = NULL; -- kfree(s->tile_id); -- s->tile_id = NULL; - - kfree(s->col_bd); - s->col_bd = NULL; -@@ -1237,10 +1257,52 @@ static void free_ps_info(struct rpivid_d - s->row_bd = NULL; - } - -+static unsigned int tile_width(const struct rpivid_dec_state *const s, -+ const unsigned int t_x) -+{ -+ return s->col_bd[t_x + 1] - s->col_bd[t_x]; -+} -+ -+static unsigned int tile_height(const struct rpivid_dec_state *const s, -+ const unsigned int t_y) -+{ -+ return s->row_bd[t_y + 1] - s->row_bd[t_y]; -+} -+ -+static void fill_rs_to_ts(struct rpivid_dec_state *const s) -+{ -+ unsigned int ts = 0; -+ unsigned int t_y; -+ unsigned int tr_rs = 0; -+ -+ for (t_y = 0; t_y != s->tile_height; ++t_y) { -+ const unsigned int t_h = tile_height(s, t_y); -+ unsigned int t_x; -+ unsigned int tc_rs = tr_rs; -+ -+ for (t_x = 0; t_x != s->tile_width; ++t_x) { -+ const unsigned int t_w = tile_width(s, t_x); -+ unsigned int y; -+ unsigned int rs = tc_rs; -+ -+ for (y = 0; y != t_h; ++y) { -+ unsigned int x; -+ -+ for (x = 0; x != t_w; ++x) { -+ s->ctb_addr_rs_to_ts[rs + x] = ts; -+ s->ctb_addr_ts_to_rs[ts] = rs + x; -+ ++ts; -+ } -+ rs += s->ctb_width; -+ } -+ tc_rs += t_w; -+ } -+ tr_rs += t_h * s->ctb_width; -+ } -+} -+ - static int updated_ps(struct rpivid_dec_state *const s) - { -- unsigned int ctb_addr_rs; -- int j, x, y, tile_id; - unsigned int i; - - free_ps_info(s); -@@ -1259,104 +1321,49 @@ static int updated_ps(struct rpivid_dec_ - - // Inferred parameters - -+ s->ctb_addr_rs_to_ts = kmalloc_array(s->ctb_size, -+ sizeof(*s->ctb_addr_rs_to_ts), -+ GFP_KERNEL); -+ s->ctb_addr_ts_to_rs = kmalloc_array(s->ctb_size, -+ sizeof(*s->ctb_addr_ts_to_rs), -+ GFP_KERNEL); -+ - if (!(s->pps.flags & V4L2_HEVC_PPS_FLAG_TILES_ENABLED)) { -- s->num_tile_columns = 1; -- s->num_tile_rows = 1; -- s->column_width[0] = s->ctb_width; -- s->row_height[0] = s->ctb_height; -+ s->tile_width = 1; -+ s->tile_height = 1; - } else { -- s->num_tile_columns = s->pps.num_tile_columns_minus1 + 1; -- s->num_tile_rows = s->pps.num_tile_rows_minus1 + 1; -- for (i = 0; i < s->num_tile_columns; ++i) -- s->column_width[i] = s->pps.column_width_minus1[i] + 1; -- for (i = 0; i < s->num_tile_rows; ++i) -- s->row_height[i] = s->pps.row_height_minus1[i] + 1; -+ s->tile_width = s->pps.num_tile_columns_minus1 + 1; -+ s->tile_height = s->pps.num_tile_rows_minus1 + 1; - } - -- s->col_bd = kmalloc((s->num_tile_columns + 1) * sizeof(*s->col_bd), -+ s->col_bd = kmalloc((s->tile_width + 1) * sizeof(*s->col_bd), - GFP_KERNEL); -- s->row_bd = kmalloc((s->num_tile_rows + 1) * sizeof(*s->row_bd), -+ s->row_bd = kmalloc((s->tile_height + 1) * sizeof(*s->row_bd), - GFP_KERNEL); - - s->col_bd[0] = 0; -- for (i = 0; i < s->num_tile_columns; i++) -- s->col_bd[i + 1] = s->col_bd[i] + s->column_width[i]; -+ for (i = 1; i < s->tile_width; i++) -+ s->col_bd[i] = s->col_bd[i - 1] + -+ s->pps.column_width_minus1[i - 1] + 1; -+ s->col_bd[s->tile_width] = s->ctb_width; - - s->row_bd[0] = 0; -- for (i = 0; i < s->num_tile_rows; i++) -- s->row_bd[i + 1] = s->row_bd[i] + s->row_height[i]; -+ for (i = 1; i < s->tile_height; i++) -+ s->row_bd[i] = s->row_bd[i - 1] + -+ s->pps.row_height_minus1[i - 1] + 1; -+ s->row_bd[s->tile_height] = s->ctb_height; - -- s->ctb_addr_rs_to_ts = kmalloc_array(s->ctb_size, -- sizeof(*s->ctb_addr_rs_to_ts), -- GFP_KERNEL); -- s->ctb_addr_ts_to_rs = kmalloc_array(s->ctb_size, -- sizeof(*s->ctb_addr_ts_to_rs), -- GFP_KERNEL); -- s->tile_id = kmalloc_array(s->ctb_size, sizeof(*s->tile_id), -- GFP_KERNEL); -- -- for (ctb_addr_rs = 0; ctb_addr_rs < s->ctb_size; ctb_addr_rs++) { -- int tb_x = ctb_addr_rs % s->ctb_width; -- int tb_y = ctb_addr_rs / s->ctb_width; -- int tile_x = 0; -- int tile_y = 0; -- int val = 0; -- -- for (i = 0; i < s->num_tile_columns; i++) { -- if (tb_x < s->col_bd[i + 1]) { -- tile_x = i; -- break; -- } -- } -- -- for (i = 0; i < s->num_tile_rows; i++) { -- if (tb_y < s->row_bd[i + 1]) { -- tile_y = i; -- break; -- } -- } -- -- for (i = 0; i < tile_x; i++) -- val += s->row_height[tile_y] * s->column_width[i]; -- for (i = 0; i < tile_y; i++) -- val += s->ctb_width * s->row_height[i]; -- -- val += (tb_y - s->row_bd[tile_y]) * s->column_width[tile_x] + -- tb_x - s->col_bd[tile_x]; -- -- s->ctb_addr_rs_to_ts[ctb_addr_rs] = val; -- s->ctb_addr_ts_to_rs[val] = ctb_addr_rs; -- } -- -- for (j = 0, tile_id = 0; j < s->num_tile_rows; j++) -- for (i = 0; i < s->num_tile_columns; i++, tile_id++) -- for (y = s->row_bd[j]; y < s->row_bd[j + 1]; y++) -- for (x = s->col_bd[i]; -- x < s->col_bd[i + 1]; -- x++) -- s->tile_id[s->ctb_addr_rs_to_ts -- [y * s->ctb_width + -- x]] = tile_id; -+ fill_rs_to_ts(s); - - return 0; - } - --static int frame_end(struct rpivid_dev *const dev, -- struct rpivid_dec_env *const de, -- const struct rpivid_dec_state *const s) --{ -- const unsigned int last_x = s->col_bd[s->num_tile_columns] - 1; -- const unsigned int last_y = s->row_bd[s->num_tile_rows] - 1; -- size_t cmd_size; -- -- if (s->pps.flags & V4L2_HEVC_PPS_FLAG_ENTROPY_CODING_SYNC_ENABLED) { -- if (de->wpp_entry_x < 2 && de->pic_width_in_ctbs_y > 2) -- wpp_pause(de, last_y); -- } -- p1_apb_write(de, RPI_STATUS, 1 + (last_x << 5) + (last_y << 18)); -- -+static int write_cmd_buffer(struct rpivid_dev *const dev, -+ struct rpivid_dec_env *const de, -+ const struct rpivid_dec_state *const s) -+{ - // Copy commands out to dma buf -- cmd_size = de->cmd_len * sizeof(de->cmd_fifo[0]); -+ const size_t cmd_size = de->cmd_len * sizeof(de->cmd_fifo[0]); - - if (!de->cmd_copy_gptr->ptr || cmd_size > de->cmd_copy_gptr->size) { - size_t cmd_alloc = round_up_size(cmd_size); -@@ -1521,18 +1528,19 @@ static void rpivid_h265_setup(struct rpi - struct rpivid_q_aux *dpb_q_aux[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; - struct rpivid_dec_state *const s = ctx->state; - struct vb2_queue *vq; -- struct rpivid_dec_env *de; -- int ctb_addr_ts; -+ struct rpivid_dec_env *de = ctx->dec0; -+ unsigned int prev_rs; - unsigned int i; - int use_aux; - bool slice_temporal_mvp; - -+ xtrace_in(dev, de); -+ - pred_weight_table = &sh->pred_weight_table; - - s->frame_end = - ((run->src->flags & V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF) == 0); - -- de = ctx->dec0; - slice_temporal_mvp = (sh->flags & - V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_TEMPORAL_MVP_ENABLED); - -@@ -1662,6 +1670,13 @@ static void rpivid_h265_setup(struct rpi - s->sps.pic_height_in_luma_samples); - goto fail; - } -+ if ((s->tile_width != 1 || s->tile_height != 1) && -+ (s->pps.flags & -+ V4L2_HEVC_PPS_FLAG_ENTROPY_CODING_SYNC_ENABLED)) { -+ v4l2_warn(&dev->v4l2_dev, -+ "Tiles + WPP not supported\n"); -+ goto fail; -+ } - - // Fill in ref planes with our address s.t. if we mess - // up refs somehow then we still have a valid address -@@ -1760,15 +1775,24 @@ static void rpivid_h265_setup(struct rpi - if (s->sps.flags & V4L2_HEVC_SPS_FLAG_SCALING_LIST_ENABLED) - populate_scaling_factors(run, de, s); - -- ctb_addr_ts = s->ctb_addr_rs_to_ts[sh->slice_segment_addr]; -+ // Calc all the random coord info to avoid repeated conversion in/out -+ s->start_ts = s->ctb_addr_rs_to_ts[sh->slice_segment_addr]; -+ s->start_ctb_x = sh->slice_segment_addr % de->pic_width_in_ctbs_y; -+ s->start_ctb_y = sh->slice_segment_addr / de->pic_width_in_ctbs_y; -+ // Last CTB of previous slice -+ prev_rs = !s->start_ts ? 0 : s->ctb_addr_ts_to_rs[s->start_ts - 1]; -+ s->prev_ctb_x = prev_rs % de->pic_width_in_ctbs_y; -+ s->prev_ctb_y = prev_rs / de->pic_width_in_ctbs_y; - - if ((s->pps.flags & V4L2_HEVC_PPS_FLAG_ENTROPY_CODING_SYNC_ENABLED)) -- wpp_decode_slice(de, s, sh, ctb_addr_ts); -+ wpp_decode_slice(de, s); - else -- decode_slice(de, s, sh, ctb_addr_ts); -+ decode_slice(de, s); - -- if (!s->frame_end) -+ if (!s->frame_end) { -+ xtrace_ok(dev, de); - return; -+ } - - // Frame end - memset(dpb_q_aux, 0, -@@ -1776,8 +1800,9 @@ static void rpivid_h265_setup(struct rpi - /* - * Need Aux ents for all (ref) DPB ents if temporal MV could - * be enabled for any pic -- * ** At the moment we have aux ents for all pics whether or not -- * they are ref -+ * ** At the moment we create aux ents for all pics whether or not -+ * they are ref - they should then be discarded by the DPB-aux -+ * garbage collection code - */ - use_aux = ((s->sps.flags & - V4L2_HEVC_SPS_FLAG_SPS_TEMPORAL_MVP_ENABLED) != 0); -@@ -1795,7 +1820,7 @@ static void rpivid_h265_setup(struct rpi - } - - // v4l2_info(&dev->v4l2_dev, "rpivid_h265_end of frame\n"); -- if (frame_end(dev, de, s)) -+ if (write_cmd_buffer(dev, de, s)) - goto fail; - - for (i = 0; i < sh->num_active_dpb_entries; ++i) { -@@ -1876,6 +1901,7 @@ static void rpivid_h265_setup(struct rpi - } - - de->state = RPIVID_DECODE_PHASE1; -+ xtrace_ok(dev, de); - return; - - fail: -@@ -1883,6 +1909,7 @@ fail: - // Actual error reporting happens in Trigger - de->state = s->frame_end ? RPIVID_DECODE_ERROR_DONE : - RPIVID_DECODE_ERROR_CONTINUE; -+ xtrace_fail(dev, de); - } - - ////////////////////////////////////////////////////////////////////////////// -@@ -2210,6 +2237,10 @@ static int rpivid_h265_start(struct rpiv - size_t pu_alloc; - size_t coeff_alloc; - -+#if DEBUG_TRACE_P1_CMD -+ p1_z = 0; -+#endif -+ - // Generate a sanitised WxH for memory alloc - // Assume HD if unset - if (w == 0) diff --git a/target/linux/bcm27xx/patches-5.15/950-0394-media-rpivid-Convert-to-MPLANE.patch b/target/linux/bcm27xx/patches-5.15/950-0394-media-rpivid-Convert-to-MPLANE.patch deleted file mode 100644 index 1ac0a0390..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0394-media-rpivid-Convert-to-MPLANE.patch +++ /dev/null @@ -1,329 +0,0 @@ -From 103259e6629a419bc07d6348dd1544213daac45b Mon Sep 17 00:00:00 2001 -From: John Cox -Date: Thu, 11 Mar 2021 12:51:00 +0000 -Subject: [PATCH] media: rpivid: Convert to MPLANE - -Use multi-planar interface rather than single plane interface. This -allows dmabufs holding compressed data to be resized. - -Signed-off-by: John Cox ---- - drivers/staging/media/rpivid/rpivid.c | 2 +- - drivers/staging/media/rpivid/rpivid.h | 4 +- - drivers/staging/media/rpivid/rpivid_h265.c | 9 ++- - drivers/staging/media/rpivid/rpivid_video.c | 88 ++++++++++----------- - drivers/staging/media/rpivid/rpivid_video.h | 4 +- - 5 files changed, 52 insertions(+), 55 deletions(-) - ---- a/drivers/staging/media/rpivid/rpivid.c -+++ b/drivers/staging/media/rpivid/rpivid.c -@@ -283,7 +283,7 @@ static const struct video_device rpivid_ - .ioctl_ops = &rpivid_ioctl_ops, - .minor = -1, - .release = video_device_release_empty, -- .device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING, -+ .device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING, - }; - - static const struct v4l2_m2m_ops rpivid_m2m_ops = { ---- a/drivers/staging/media/rpivid/rpivid.h -+++ b/drivers/staging/media/rpivid/rpivid.h -@@ -85,8 +85,8 @@ struct rpivid_ctx { - struct v4l2_fh fh; - struct rpivid_dev *dev; - -- struct v4l2_pix_format src_fmt; -- struct v4l2_pix_format dst_fmt; -+ struct v4l2_pix_format_mplane src_fmt; -+ struct v4l2_pix_format_mplane dst_fmt; - int dst_fmt_set; - // fatal_err is set if an error has occurred s.t. decode cannot - // continue (such as running out of CMA) ---- a/drivers/staging/media/rpivid/rpivid_h265.c -+++ b/drivers/staging/media/rpivid/rpivid_h265.c -@@ -1613,7 +1613,7 @@ static void rpivid_h265_setup(struct rpi - de->cmd_copy_gptr = ctx->cmdbufs + 0; - - de->frame_c_offset = ctx->dst_fmt.height * 128; -- de->frame_stride = ctx->dst_fmt.bytesperline * 128; -+ de->frame_stride = ctx->dst_fmt.plane_fmt[0].bytesperline * 128; - de->frame_addr = - vb2_dma_contig_plane_dma_addr(&run->dst->vb2_buf, 0); - de->frame_aux = NULL; -@@ -1654,11 +1654,11 @@ static void rpivid_h265_setup(struct rpi - goto fail; - } - if (run->dst->planes[0].length < -- ctx->dst_fmt.sizeimage) { -+ ctx->dst_fmt.plane_fmt[0].sizeimage) { - v4l2_warn(&dev->v4l2_dev, - "Capture plane[0] length (%d) < sizeimage (%d)\n", - run->dst->planes[0].length, -- ctx->dst_fmt.sizeimage); -+ ctx->dst_fmt.plane_fmt[0].sizeimage); - goto fail; - } - -@@ -1812,7 +1812,8 @@ static void rpivid_h265_setup(struct rpi - // slices. If this changes we will need idx mapping code. - // Uses sh so here rather than trigger - -- vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); -+ vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, -+ V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); - - if (!vq) { - v4l2_err(&dev->v4l2_dev, "VQ gone!\n"); ---- a/drivers/staging/media/rpivid/rpivid_video.c -+++ b/drivers/staging/media/rpivid/rpivid_video.c -@@ -42,25 +42,27 @@ static inline unsigned int constrain2x(u - (x > y * 2) ? y : x; - } - --int rpivid_prepare_src_format(struct v4l2_pix_format *pix_fmt) -+int rpivid_prepare_src_format(struct v4l2_pix_format_mplane *pix_fmt) - { - if (pix_fmt->pixelformat != V4L2_PIX_FMT_HEVC_SLICE) - return -EINVAL; - - /* Zero bytes per line for encoded source. */ -- pix_fmt->bytesperline = 0; -+ pix_fmt->plane_fmt[0].bytesperline = 0; - /* Choose some minimum size since this can't be 0 */ -- pix_fmt->sizeimage = max_t(u32, SZ_1K, pix_fmt->sizeimage); -+ pix_fmt->plane_fmt[0].sizeimage = max_t(u32, SZ_1K, -+ pix_fmt->plane_fmt[0].sizeimage); -+ pix_fmt->num_planes = 1; - pix_fmt->field = V4L2_FIELD_NONE; - return 0; - } - --int rpivid_prepare_dst_format(struct v4l2_pix_format *pix_fmt) -+int rpivid_prepare_dst_format(struct v4l2_pix_format_mplane *pix_fmt) - { - unsigned int width = pix_fmt->width; - unsigned int height = pix_fmt->height; -- unsigned int sizeimage = pix_fmt->sizeimage; -- unsigned int bytesperline = pix_fmt->bytesperline; -+ unsigned int sizeimage = pix_fmt->plane_fmt[0].sizeimage; -+ unsigned int bytesperline = pix_fmt->plane_fmt[0].bytesperline; - - switch (pix_fmt->pixelformat) { - /* For column formats set bytesperline to column height (stride2) */ -@@ -112,8 +114,9 @@ int rpivid_prepare_dst_format(struct v4l - pix_fmt->height = height; - - pix_fmt->field = V4L2_FIELD_NONE; -- pix_fmt->bytesperline = bytesperline; -- pix_fmt->sizeimage = sizeimage; -+ pix_fmt->plane_fmt[0].bytesperline = bytesperline; -+ pix_fmt->plane_fmt[0].sizeimage = sizeimage; -+ pix_fmt->num_planes = 1; - return 0; - } - -@@ -222,12 +225,12 @@ static u32 pixelformat_from_sps(const st - return pf; - } - --static struct v4l2_pix_format -+static struct v4l2_pix_format_mplane - rpivid_hevc_default_dst_fmt(struct rpivid_ctx * const ctx) - { - const struct v4l2_ctrl_hevc_sps * const sps = - rpivid_find_control_data(ctx, V4L2_CID_MPEG_VIDEO_HEVC_SPS); -- struct v4l2_pix_format pix_fmt = { -+ struct v4l2_pix_format_mplane pix_fmt = { - .width = sps->pic_width_in_luma_samples, - .height = sps->pic_height_in_luma_samples, - .pixelformat = pixelformat_from_sps(sps, 0) -@@ -267,7 +270,7 @@ static int rpivid_g_fmt_vid_cap(struct f - - if (!ctx->dst_fmt_set) - ctx->dst_fmt = rpivid_hevc_default_dst_fmt(ctx); -- f->fmt.pix = ctx->dst_fmt; -+ f->fmt.pix_mp = ctx->dst_fmt; - return 0; - } - -@@ -276,12 +279,12 @@ static int rpivid_g_fmt_vid_out(struct f - { - struct rpivid_ctx *ctx = rpivid_file2ctx(file); - -- f->fmt.pix = ctx->src_fmt; -+ f->fmt.pix_mp = ctx->src_fmt; - return 0; - } - --static inline void copy_color(struct v4l2_pix_format *d, -- const struct v4l2_pix_format *s) -+static inline void copy_color(struct v4l2_pix_format_mplane *d, -+ const struct v4l2_pix_format_mplane *s) - { - d->colorspace = s->colorspace; - d->xfer_func = s->xfer_func; -@@ -298,12 +301,8 @@ static int rpivid_try_fmt_vid_cap(struct - u32 pixelformat; - int i; - -- /* Reject format types we don't support */ -- if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) -- return -EINVAL; -- - for (i = 0; (pixelformat = pixelformat_from_sps(sps, i)) != 0; i++) { -- if (f->fmt.pix.pixelformat == pixelformat) -+ if (f->fmt.pix_mp.pixelformat == pixelformat) - break; - } - -@@ -317,23 +316,20 @@ static int rpivid_try_fmt_vid_cap(struct - - // We don't have any way of finding out colourspace so believe - // anything we are told - take anything set in src as a default -- if (f->fmt.pix.colorspace == V4L2_COLORSPACE_DEFAULT) -- copy_color(&f->fmt.pix, &ctx->src_fmt); -+ if (f->fmt.pix_mp.colorspace == V4L2_COLORSPACE_DEFAULT) -+ copy_color(&f->fmt.pix_mp, &ctx->src_fmt); - -- f->fmt.pix.pixelformat = pixelformat; -- return rpivid_prepare_dst_format(&f->fmt.pix); -+ f->fmt.pix_mp.pixelformat = pixelformat; -+ return rpivid_prepare_dst_format(&f->fmt.pix_mp); - } - - static int rpivid_try_fmt_vid_out(struct file *file, void *priv, - struct v4l2_format *f) - { -- if (f->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) -- return -EINVAL; -- -- if (rpivid_prepare_src_format(&f->fmt.pix)) { -+ if (rpivid_prepare_src_format(&f->fmt.pix_mp)) { - // Set default src format -- f->fmt.pix.pixelformat = RPIVID_SRC_PIXELFORMAT_DEFAULT; -- rpivid_prepare_src_format(&f->fmt.pix); -+ f->fmt.pix_mp.pixelformat = RPIVID_SRC_PIXELFORMAT_DEFAULT; -+ rpivid_prepare_src_format(&f->fmt.pix_mp); - } - return 0; - } -@@ -353,7 +349,7 @@ static int rpivid_s_fmt_vid_cap(struct f - if (ret) - return ret; - -- ctx->dst_fmt = f->fmt.pix; -+ ctx->dst_fmt = f->fmt.pix_mp; - ctx->dst_fmt_set = 1; - - return 0; -@@ -374,14 +370,14 @@ static int rpivid_s_fmt_vid_out(struct f - if (ret) - return ret; - -- ctx->src_fmt = f->fmt.pix; -+ ctx->src_fmt = f->fmt.pix_mp; - ctx->dst_fmt_set = 0; // Setting src invalidates dst - - vq->subsystem_flags |= - VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF; - - /* Propagate colorspace information to capture. */ -- copy_color(&ctx->dst_fmt, &f->fmt.pix); -+ copy_color(&ctx->dst_fmt, &f->fmt.pix_mp); - return 0; - } - -@@ -389,14 +385,14 @@ const struct v4l2_ioctl_ops rpivid_ioctl - .vidioc_querycap = rpivid_querycap, - - .vidioc_enum_fmt_vid_cap = rpivid_enum_fmt_vid_cap, -- .vidioc_g_fmt_vid_cap = rpivid_g_fmt_vid_cap, -- .vidioc_try_fmt_vid_cap = rpivid_try_fmt_vid_cap, -- .vidioc_s_fmt_vid_cap = rpivid_s_fmt_vid_cap, -+ .vidioc_g_fmt_vid_cap_mplane = rpivid_g_fmt_vid_cap, -+ .vidioc_try_fmt_vid_cap_mplane = rpivid_try_fmt_vid_cap, -+ .vidioc_s_fmt_vid_cap_mplane = rpivid_s_fmt_vid_cap, - - .vidioc_enum_fmt_vid_out = rpivid_enum_fmt_vid_out, -- .vidioc_g_fmt_vid_out = rpivid_g_fmt_vid_out, -- .vidioc_try_fmt_vid_out = rpivid_try_fmt_vid_out, -- .vidioc_s_fmt_vid_out = rpivid_s_fmt_vid_out, -+ .vidioc_g_fmt_vid_out_mplane = rpivid_g_fmt_vid_out, -+ .vidioc_try_fmt_vid_out_mplane = rpivid_try_fmt_vid_out, -+ .vidioc_s_fmt_vid_out_mplane = rpivid_s_fmt_vid_out, - - .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, - .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, -@@ -421,7 +417,7 @@ static int rpivid_queue_setup(struct vb2 - struct device *alloc_devs[]) - { - struct rpivid_ctx *ctx = vb2_get_drv_priv(vq); -- struct v4l2_pix_format *pix_fmt; -+ struct v4l2_pix_format_mplane *pix_fmt; - - if (V4L2_TYPE_IS_OUTPUT(vq->type)) - pix_fmt = &ctx->src_fmt; -@@ -429,10 +425,10 @@ static int rpivid_queue_setup(struct vb2 - pix_fmt = &ctx->dst_fmt; - - if (*nplanes) { -- if (sizes[0] < pix_fmt->sizeimage) -+ if (sizes[0] < pix_fmt->plane_fmt[0].sizeimage) - return -EINVAL; - } else { -- sizes[0] = pix_fmt->sizeimage; -+ sizes[0] = pix_fmt->plane_fmt[0].sizeimage; - *nplanes = 1; - } - -@@ -471,17 +467,17 @@ static int rpivid_buf_prepare(struct vb2 - { - struct vb2_queue *vq = vb->vb2_queue; - struct rpivid_ctx *ctx = vb2_get_drv_priv(vq); -- struct v4l2_pix_format *pix_fmt; -+ struct v4l2_pix_format_mplane *pix_fmt; - - if (V4L2_TYPE_IS_OUTPUT(vq->type)) - pix_fmt = &ctx->src_fmt; - else - pix_fmt = &ctx->dst_fmt; - -- if (vb2_plane_size(vb, 0) < pix_fmt->sizeimage) -+ if (vb2_plane_size(vb, 0) < pix_fmt->plane_fmt[0].sizeimage) - return -EINVAL; - -- vb2_set_plane_payload(vb, 0, pix_fmt->sizeimage); -+ vb2_set_plane_payload(vb, 0, pix_fmt->plane_fmt[0].sizeimage); - - return 0; - } -@@ -567,7 +563,7 @@ int rpivid_queue_init(void *priv, struct - struct rpivid_ctx *ctx = priv; - int ret; - -- src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; -+ src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - src_vq->io_modes = VB2_MMAP | VB2_DMABUF; - src_vq->drv_priv = ctx; - src_vq->buf_struct_size = sizeof(struct rpivid_buffer); -@@ -584,7 +580,7 @@ int rpivid_queue_init(void *priv, struct - if (ret) - return ret; - -- dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; -+ dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - dst_vq->io_modes = VB2_MMAP | VB2_DMABUF; - dst_vq->drv_priv = ctx; - dst_vq->buf_struct_size = sizeof(struct rpivid_buffer); ---- a/drivers/staging/media/rpivid/rpivid_video.h -+++ b/drivers/staging/media/rpivid/rpivid_video.h -@@ -24,7 +24,7 @@ extern const struct v4l2_ioctl_ops rpivi - - int rpivid_queue_init(void *priv, struct vb2_queue *src_vq, - struct vb2_queue *dst_vq); --int rpivid_prepare_src_format(struct v4l2_pix_format *pix_fmt); --int rpivid_prepare_dst_format(struct v4l2_pix_format *pix_fmt); -+int rpivid_prepare_src_format(struct v4l2_pix_format_mplane *pix_fmt); -+int rpivid_prepare_dst_format(struct v4l2_pix_format_mplane *pix_fmt); - - #endif diff --git a/target/linux/bcm27xx/patches-5.15/950-0395-media-rpivid-Add-an-enable-count-to-irq-claim-Qs.patch b/target/linux/bcm27xx/patches-5.15/950-0395-media-rpivid-Add-an-enable-count-to-irq-claim-Qs.patch deleted file mode 100644 index b404c733f..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0395-media-rpivid-Add-an-enable-count-to-irq-claim-Qs.patch +++ /dev/null @@ -1,234 +0,0 @@ -From d9419b25780a1fe58421edb49637a42ba8b83800 Mon Sep 17 00:00:00 2001 -From: John Cox -Date: Thu, 11 Mar 2021 18:43:15 +0000 -Subject: [PATCH] media: rpivid: Add an enable count to irq claim Qs - -Add an enable count to the irq Q structures to allow the irq logic to -block further callbacks if resources associated with the irq are not -yet available. - -Signed-off-by: John Cox ---- - drivers/staging/media/rpivid/rpivid.h | 2 + - drivers/staging/media/rpivid/rpivid_hw.c | 118 +++++++++++++++-------- - drivers/staging/media/rpivid/rpivid_hw.h | 3 + - 3 files changed, 85 insertions(+), 38 deletions(-) - ---- a/drivers/staging/media/rpivid/rpivid.h -+++ b/drivers/staging/media/rpivid/rpivid.h -@@ -151,6 +151,8 @@ struct rpivid_hw_irq_ctrl { - struct rpivid_hw_irq_ent *irq; - /* Non-zero => do not start a new job - outer layer sched pending */ - int no_sched; -+ /* Enable count. -1 always OK, 0 do not sched, +ve shed & count down */ -+ int enable; - /* Thread CB requested */ - bool thread_reqed; - }; ---- a/drivers/staging/media/rpivid/rpivid_hw.c -+++ b/drivers/staging/media/rpivid/rpivid_hw.c -@@ -42,35 +42,62 @@ static void pre_irq(struct rpivid_dev *d - ient->cb = cb; - ient->v = v; - -- // Not sure this lock is actually required - spin_lock_irqsave(&ictl->lock, flags); - ictl->irq = ient; -+ ictl->no_sched++; - spin_unlock_irqrestore(&ictl->lock, flags); - } - --static void sched_claim(struct rpivid_dev * const dev, -- struct rpivid_hw_irq_ctrl * const ictl) -+/* Should be called from inside ictl->lock */ -+static inline bool sched_enabled(const struct rpivid_hw_irq_ctrl * const ictl) - { -- for (;;) { -- struct rpivid_hw_irq_ent *ient = NULL; -- unsigned long flags; -+ return ictl->no_sched <= 0 && ictl->enable; -+} - -- spin_lock_irqsave(&ictl->lock, flags); -+/* Should be called from inside ictl->lock & after checking sched_enabled() */ -+static inline void set_claimed(struct rpivid_hw_irq_ctrl * const ictl) -+{ -+ if (ictl->enable > 0) -+ --ictl->enable; -+ ictl->no_sched = 1; -+} - -- if (--ictl->no_sched <= 0) { -- ient = ictl->claim; -- if (!ictl->irq && ient) { -- ictl->claim = ient->next; -- ictl->no_sched = 1; -- } -- } -+/* Should be called from inside ictl->lock */ -+static struct rpivid_hw_irq_ent *get_sched(struct rpivid_hw_irq_ctrl * const ictl) -+{ -+ struct rpivid_hw_irq_ent *ient; - -- spin_unlock_irqrestore(&ictl->lock, flags); -+ if (!sched_enabled(ictl)) -+ return NULL; -+ -+ ient = ictl->claim; -+ if (!ient) -+ return NULL; -+ ictl->claim = ient->next; -+ -+ set_claimed(ictl); -+ return ient; -+} - -- if (!ient) -- break; -+/* Run a callback & check to see if there is anything else to run */ -+static void sched_cb(struct rpivid_dev * const dev, -+ struct rpivid_hw_irq_ctrl * const ictl, -+ struct rpivid_hw_irq_ent *ient) -+{ -+ while (ient) { -+ unsigned long flags; - - ient->cb(dev, ient->v); -+ -+ spin_lock_irqsave(&ictl->lock, flags); -+ -+ /* Always dec no_sched after cb exec - must have been set -+ * on entry to cb -+ */ -+ --ictl->no_sched; -+ ient = get_sched(ictl); -+ -+ spin_unlock_irqrestore(&ictl->lock, flags); - } - } - -@@ -84,7 +111,7 @@ static void pre_thread(struct rpivid_dev - ient->v = v; - ictl->irq = ient; - ictl->thread_reqed = true; -- ictl->no_sched++; -+ ictl->no_sched++; /* This is unwound in do_thread */ - } - - // Called in irq context -@@ -96,17 +123,10 @@ static void do_irq(struct rpivid_dev * c - - spin_lock_irqsave(&ictl->lock, flags); - ient = ictl->irq; -- if (ient) { -- ictl->no_sched++; -- ictl->irq = NULL; -- } -+ ictl->irq = NULL; - spin_unlock_irqrestore(&ictl->lock, flags); - -- if (ient) { -- ient->cb(dev, ient->v); -- -- sched_claim(dev, ictl); -- } -+ sched_cb(dev, ictl, ient); - } - - static void do_claim(struct rpivid_dev * const dev, -@@ -127,7 +147,7 @@ static void do_claim(struct rpivid_dev * - ictl->tail->next = ient; - ictl->tail = ient; - ient = NULL; -- } else if (ictl->no_sched || ictl->irq) { -+ } else if (!sched_enabled(ictl)) { - // Empty Q but other activity in progress so Q - ictl->claim = ient; - ictl->tail = ient; -@@ -135,16 +155,34 @@ static void do_claim(struct rpivid_dev * - } else { - // Nothing else going on - schedule immediately and - // prevent anything else scheduling claims -- ictl->no_sched = 1; -+ set_claimed(ictl); - } - - spin_unlock_irqrestore(&ictl->lock, flags); - -- if (ient) { -- ient->cb(dev, ient->v); -+ sched_cb(dev, ictl, ient); -+} - -- sched_claim(dev, ictl); -- } -+/* Enable n claims. -+ * n < 0 set to unlimited (default on init) -+ * n = 0 if previously unlimited then disable otherwise nop -+ * n > 0 if previously unlimited then set to n enables -+ * otherwise add n enables -+ * The enable count is automatically decremented every time a claim is run -+ */ -+static void do_enable_claim(struct rpivid_dev * const dev, -+ int n, -+ struct rpivid_hw_irq_ctrl * const ictl) -+{ -+ unsigned long flags; -+ struct rpivid_hw_irq_ent *ient; -+ -+ spin_lock_irqsave(&ictl->lock, flags); -+ ictl->enable = n < 0 ? -1 : ictl->enable <= 0 ? n : ictl->enable + n; -+ ient = get_sched(ictl); -+ spin_unlock_irqrestore(&ictl->lock, flags); -+ -+ sched_cb(dev, ictl, ient); - } - - static void ictl_init(struct rpivid_hw_irq_ctrl * const ictl) -@@ -154,6 +192,8 @@ static void ictl_init(struct rpivid_hw_i - ictl->tail = NULL; - ictl->irq = NULL; - ictl->no_sched = 0; -+ ictl->enable = -1; -+ ictl->thread_reqed = false; - } - - static void ictl_uninit(struct rpivid_hw_irq_ctrl * const ictl) -@@ -203,11 +243,7 @@ static void do_thread(struct rpivid_dev - - spin_unlock_irqrestore(&ictl->lock, flags); - -- if (ient) { -- ient->cb(dev, ient->v); -- -- sched_claim(dev, ictl); -- } -+ sched_cb(dev, ictl, ient); - } - - static irqreturn_t rpivid_irq_thread(int irq, void *data) -@@ -231,6 +267,12 @@ void rpivid_hw_irq_active1_thread(struct - pre_thread(dev, ient, thread_cb, ctx, &dev->ic_active1); - } - -+void rpivid_hw_irq_active1_enable_claim(struct rpivid_dev *dev, -+ int n) -+{ -+ do_enable_claim(dev, n, &dev->ic_active1); -+} -+ - void rpivid_hw_irq_active1_claim(struct rpivid_dev *dev, - struct rpivid_hw_irq_ent *ient, - rpivid_irq_callback ready_cb, void *ctx) ---- a/drivers/staging/media/rpivid/rpivid_hw.h -+++ b/drivers/staging/media/rpivid/rpivid_hw.h -@@ -272,6 +272,9 @@ static inline void apb_write_vc_len(cons - ARG_IC_ICTRL_ACTIVE1_INT_SET |\ - ARG_IC_ICTRL_ACTIVE2_INT_SET) - -+/* Regulate claim Q */ -+void rpivid_hw_irq_active1_enable_claim(struct rpivid_dev *dev, -+ int n); - /* Auto release once all CBs called */ - void rpivid_hw_irq_active1_claim(struct rpivid_dev *dev, - struct rpivid_hw_irq_ent *ient, diff --git a/target/linux/bcm27xx/patches-5.15/950-0397-media-rpivid-Add-a-Pass0-to-accumulate-slices-and-re.patch b/target/linux/bcm27xx/patches-5.15/950-0397-media-rpivid-Add-a-Pass0-to-accumulate-slices-and-re.patch deleted file mode 100644 index 064ebaf2e..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0397-media-rpivid-Add-a-Pass0-to-accumulate-slices-and-re.patch +++ /dev/null @@ -1,1049 +0,0 @@ -From 006d6d95a003be26df5b34be959f29725ded0bb6 Mon Sep 17 00:00:00 2001 -From: John Cox -Date: Thu, 11 Mar 2021 19:08:00 +0000 -Subject: [PATCH] media: rpivid: Add a Pass0 to accumulate slices and - rework job finish - -Due to overheads in assembling controls and requests it is worth having -the slice assembly phase separate from the h/w pass1 processing. Create -a queue to service pass1 rather than have the pass1 finished callback -trigger the next slice job. - -This requires a rework of the logic that splits up the buffer and -request done events. This code contains two ways of doing that, we use -Ezequiel Garcias solution, but expect that -in the future this will be handled by the framework in a cleaner manner. - -Fix up the handling of some of the memory exhaustion crashes uncovered -in the process of writing this code. - -Signed-off-by: John Cox ---- - drivers/media/v4l2-core/v4l2-mem2mem.c | 2 - - drivers/staging/media/rpivid/rpivid.c | 11 +- - drivers/staging/media/rpivid/rpivid.h | 20 +- - drivers/staging/media/rpivid/rpivid_dec.c | 32 +- - drivers/staging/media/rpivid/rpivid_h265.c | 432 ++++++++++++++++----- - drivers/staging/media/rpivid/rpivid_hw.c | 8 +- - 6 files changed, 374 insertions(+), 131 deletions(-) - ---- a/drivers/media/v4l2-core/v4l2-mem2mem.c -+++ b/drivers/media/v4l2-core/v4l2-mem2mem.c -@@ -492,8 +492,6 @@ void v4l2_m2m_job_finish(struct v4l2_m2m - * holding capture buffers. Those should use - * v4l2_m2m_buf_done_and_job_finish() instead. - */ -- WARN_ON(m2m_ctx->out_q_ctx.q.subsystem_flags & -- VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF); - spin_lock_irqsave(&m2m_dev->job_spinlock, flags); - schedule_next = _v4l2_m2m_job_finish(m2m_dev, m2m_ctx); - spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); ---- a/drivers/staging/media/rpivid/rpivid.c -+++ b/drivers/staging/media/rpivid/rpivid.c -@@ -79,17 +79,24 @@ static const struct rpivid_control rpivi - - #define rpivid_ctrls_COUNT ARRAY_SIZE(rpivid_ctrls) - --void *rpivid_find_control_data(struct rpivid_ctx *ctx, u32 id) -+struct v4l2_ctrl *rpivid_find_ctrl(struct rpivid_ctx *ctx, u32 id) - { - unsigned int i; - - for (i = 0; ctx->ctrls[i]; i++) - if (ctx->ctrls[i]->id == id) -- return ctx->ctrls[i]->p_cur.p; -+ return ctx->ctrls[i]; - - return NULL; - } - -+void *rpivid_find_control_data(struct rpivid_ctx *ctx, u32 id) -+{ -+ struct v4l2_ctrl *const ctrl = rpivid_find_ctrl(ctx, id); -+ -+ return !ctrl ? NULL : ctrl->p_cur.p; -+} -+ - static int rpivid_init_ctrls(struct rpivid_dev *dev, struct rpivid_ctx *ctx) - { - struct v4l2_ctrl_handler *hdl = &ctx->hdl; ---- a/drivers/staging/media/rpivid/rpivid.h -+++ b/drivers/staging/media/rpivid/rpivid.h -@@ -24,6 +24,10 @@ - - #define OPT_DEBUG_POLL_IRQ 0 - -+#define RPIVID_DEC_ENV_COUNT 6 -+#define RPIVID_P1BUF_COUNT 3 -+#define RPIVID_P2BUF_COUNT 3 -+ - #define RPIVID_NAME "rpivid" - - #define RPIVID_CAPABILITY_UNTILED BIT(0) -@@ -45,6 +49,7 @@ struct rpivid_control { - }; - - struct rpivid_h265_run { -+ u32 slice_ents; - const struct v4l2_ctrl_hevc_sps *sps; - const struct v4l2_ctrl_hevc_pps *pps; - const struct v4l2_ctrl_hevc_slice_params *slice_params; -@@ -64,7 +69,6 @@ struct rpivid_buffer { - - struct rpivid_dec_state; - struct rpivid_dec_env; --#define RPIVID_DEC_ENV_COUNT 3 - - struct rpivid_gptr { - size_t size; -@@ -79,7 +83,6 @@ typedef void (*rpivid_irq_callback)(stru - struct rpivid_q_aux; - #define RPIVID_AUX_ENT_COUNT VB2_MAX_FRAME - --#define RPIVID_P2BUF_COUNT 2 - - struct rpivid_ctx { - struct v4l2_fh fh; -@@ -108,11 +111,13 @@ struct rpivid_ctx { - - struct rpivid_dec_env *dec_pool; - -- /* Some of these should be in dev */ -- struct rpivid_gptr bitbufs[1]; /* Will be 2 */ -- struct rpivid_gptr cmdbufs[1]; /* Will be 2 */ -+ unsigned int p1idx; -+ atomic_t p1out; -+ struct rpivid_gptr bitbufs[RPIVID_P1BUF_COUNT]; -+ struct rpivid_gptr cmdbufs[RPIVID_P1BUF_COUNT]; -+ -+ /* *** Should be in dev *** */ - unsigned int p2idx; -- atomic_t p2out; - struct rpivid_gptr pu_bufs[RPIVID_P2BUF_COUNT]; - struct rpivid_gptr coeff_bufs[RPIVID_P2BUF_COUNT]; - -@@ -141,6 +146,8 @@ struct rpivid_variant { - - struct rpivid_hw_irq_ent; - -+#define RPIVID_ICTL_ENABLE_UNLIMITED (-1) -+ - struct rpivid_hw_irq_ctrl { - /* Spinlock protecting claim and tail */ - spinlock_t lock; -@@ -182,6 +189,7 @@ struct rpivid_dev { - - extern struct rpivid_dec_ops rpivid_dec_ops_h265; - -+struct v4l2_ctrl *rpivid_find_ctrl(struct rpivid_ctx *ctx, u32 id); - void *rpivid_find_control_data(struct rpivid_ctx *ctx, u32 id); - - #endif ---- a/drivers/staging/media/rpivid/rpivid_dec.c -+++ b/drivers/staging/media/rpivid/rpivid_dec.c -@@ -21,8 +21,8 @@ - - void rpivid_device_run(void *priv) - { -- struct rpivid_ctx *ctx = priv; -- struct rpivid_dev *dev = ctx->dev; -+ struct rpivid_ctx *const ctx = priv; -+ struct rpivid_dev *const dev = ctx->dev; - struct rpivid_run run = {}; - struct media_request *src_req; - -@@ -32,19 +32,17 @@ void rpivid_device_run(void *priv) - if (!run.src || !run.dst) { - v4l2_err(&dev->v4l2_dev, "%s: Missing buffer: src=%p, dst=%p\n", - __func__, run.src, run.dst); -- /* We are stuffed - this probably won't dig us out of our -- * current situation but it is better than nothing -- */ -- v4l2_m2m_buf_done_and_job_finish(dev->m2m_dev, ctx->fh.m2m_ctx, -- VB2_BUF_STATE_ERROR); -- return; -+ goto fail; - } - -- /* Apply request(s) controls if needed. */ -+ /* Apply request(s) controls */ - src_req = run.src->vb2_buf.req_obj.req; -+ if (!src_req) { -+ v4l2_err(&dev->v4l2_dev, "%s: Missing request\n", __func__); -+ goto fail; -+ } - -- if (src_req) -- v4l2_ctrl_request_setup(src_req, &ctx->hdl); -+ v4l2_ctrl_request_setup(src_req, &ctx->hdl); - - switch (ctx->src_fmt.pixelformat) { - case V4L2_PIX_FMT_HEVC_SLICE: -@@ -70,10 +68,14 @@ void rpivid_device_run(void *priv) - - dev->dec_ops->setup(ctx, &run); - -- /* Complete request(s) controls if needed. */ -- -- if (src_req) -- v4l2_ctrl_request_complete(src_req, &ctx->hdl); -+ /* Complete request(s) controls */ -+ v4l2_ctrl_request_complete(src_req, &ctx->hdl); - - dev->dec_ops->trigger(ctx); -+ return; -+ -+fail: -+ /* We really shouldn't get here but tidy up what we can */ -+ v4l2_m2m_buf_done_and_job_finish(dev->m2m_dev, ctx->fh.m2m_ctx, -+ VB2_BUF_STATE_ERROR); - } ---- a/drivers/staging/media/rpivid/rpivid_h265.c -+++ b/drivers/staging/media/rpivid/rpivid_h265.c -@@ -22,6 +22,8 @@ - #define DEBUG_TRACE_P1_CMD 0 - #define DEBUG_TRACE_EXECUTION 0 - -+#define USE_REQUEST_PIN 1 -+ - #if DEBUG_TRACE_EXECUTION - #define xtrace_in(dev_, de_)\ - v4l2_info(&(dev_)->v4l2_dev, "%s[%d]: in\n", __func__,\ -@@ -192,8 +194,6 @@ struct rpivid_dec_env { - unsigned int decode_order; - int p1_status; /* P1 status - what to realloc */ - -- struct rpivid_dec_env *phase_wait_q_next; -- - struct rpi_cmd *cmd_fifo; - unsigned int cmd_len, cmd_max; - unsigned int num_slice_msgs; -@@ -219,6 +219,7 @@ struct rpivid_dec_env { - u32 rpi_currpoc; - - struct vb2_v4l2_buffer *frame_buf; // Detached dest buffer -+ struct vb2_v4l2_buffer *src_buf; // Detached src buffer - unsigned int frame_c_offset; - unsigned int frame_stride; - dma_addr_t frame_addr; -@@ -235,9 +236,15 @@ struct rpivid_dec_env { - size_t bit_copy_len; - struct rpivid_gptr *cmd_copy_gptr; - -- u16 slice_msgs[2 * HEVC_MAX_REFS * 8 + 3]; -+#define SLICE_MSGS_MAX (2 * HEVC_MAX_REFS * 8 + 3) -+ u16 slice_msgs[SLICE_MSGS_MAX]; - u8 scaling_factors[NUM_SCALING_FACTORS]; - -+#if USE_REQUEST_PIN -+ struct media_request *req_pin; -+#else -+ struct media_request_object *req_obj; -+#endif - struct rpivid_hw_irq_ent irq_ent; - }; - -@@ -286,6 +293,17 @@ struct rpivid_dec_state { - unsigned int prev_ctb_y; - }; - -+#if !USE_REQUEST_PIN -+static void dst_req_obj_release(struct media_request_object *object) -+{ -+ kfree(object); -+} -+ -+static const struct media_request_object_ops dst_req_obj_ops = { -+ .release = dst_req_obj_release, -+}; -+#endif -+ - static inline int clip_int(const int x, const int lo, const int hi) - { - return x < lo ? lo : x > hi ? hi : x; -@@ -298,15 +316,48 @@ static inline int clip_int(const int x, - static int p1_z; - #endif - -+static int cmds_check_space(struct rpivid_dec_env *const de, unsigned int n) -+{ -+ struct rpi_cmd *a; -+ unsigned int newmax; -+ -+ if (n > 0x100000) { -+ v4l2_err(&de->ctx->dev->v4l2_dev, -+ "%s: n %u implausible\n", __func__, n); -+ return -ENOMEM; -+ } -+ -+ if (de->cmd_len + n <= de->cmd_max) -+ return 0; -+ -+ newmax = 2 << log2_size(de->cmd_len + n); -+ -+ a = krealloc(de->cmd_fifo, newmax * sizeof(struct rpi_cmd), -+ GFP_KERNEL); -+ if (!a) { -+ v4l2_err(&de->ctx->dev->v4l2_dev, -+ "Failed cmd buffer realloc from %u to %u\n", -+ de->cmd_max, newmax); -+ return -ENOMEM; -+ } -+ v4l2_info(&de->ctx->dev->v4l2_dev, -+ "cmd buffer realloc from %u to %u\n", de->cmd_max, newmax); -+ -+ de->cmd_fifo = a; -+ de->cmd_max = newmax; -+ return 0; -+} -+ - // ???? u16 addr - put in u32 --static int p1_apb_write(struct rpivid_dec_env *const de, const u16 addr, -- const u32 data) -+static void p1_apb_write(struct rpivid_dec_env *const de, const u16 addr, -+ const u32 data) - { -- if (de->cmd_len == de->cmd_max) -- de->cmd_fifo = -- krealloc(de->cmd_fifo, -- (de->cmd_max *= 2) * sizeof(struct rpi_cmd), -- GFP_KERNEL); -+ if (de->cmd_len >= de->cmd_max) { -+ v4l2_err(&de->ctx->dev->v4l2_dev, -+ "%s: Overflow @ %d\n", __func__, de->cmd_len); -+ return; -+ } -+ - de->cmd_fifo[de->cmd_len].addr = addr; - de->cmd_fifo[de->cmd_len].data = data; - -@@ -316,8 +367,7 @@ static int p1_apb_write(struct rpivid_de - de->cmd_len, addr, data); - } - #endif -- -- return de->cmd_len++; -+ de->cmd_len++; - } - - static int ctb_to_tile(unsigned int ctb, unsigned int *bd, int num) -@@ -511,6 +561,7 @@ static const u8 prob_init[3][156] = { - }, - }; - -+#define CMDS_WRITE_PROB ((RPI_PROB_ARRAY_SIZE / 4) + 1) - static void write_prob(struct rpivid_dec_env *const de, - const struct rpivid_dec_state *const s) - { -@@ -554,6 +605,7 @@ static void write_prob(struct rpivid_dec - p1_apb_write(de, RPI_TRANSFER, PROB_BACKUP); - } - -+#define CMDS_WRITE_SCALING_FACTORS NUM_SCALING_FACTORS - static void write_scaling_factors(struct rpivid_dec_env *const de) - { - int i; -@@ -569,8 +621,9 @@ static inline __u32 dma_to_axi_addr(dma_ - return (__u32)(a >> 6); - } - --static void write_bitstream(struct rpivid_dec_env *const de, -- const struct rpivid_dec_state *const s) -+#define CMDS_WRITE_BITSTREAM 4 -+static int write_bitstream(struct rpivid_dec_env *const de, -+ const struct rpivid_dec_state *const s) - { - // Note that FFmpeg V4L2 does not remove emulation prevention bytes, - // so this is matched in the configuration here. -@@ -584,6 +637,13 @@ static void write_bitstream(struct rpivi - if (s->src_addr != 0) { - addr = s->src_addr + offset; - } else { -+ if (len + de->bit_copy_len > de->bit_copy_gptr->size) { -+ v4l2_warn(&de->ctx->dev->v4l2_dev, -+ "Bit copy buffer overflow: size=%zu, offset=%zu, len=%u\n", -+ de->bit_copy_gptr->size, -+ de->bit_copy_len, len); -+ return -ENOMEM; -+ } - memcpy(de->bit_copy_gptr->ptr + de->bit_copy_len, - s->src_buf + offset, len); - addr = de->bit_copy_gptr->addr + de->bit_copy_len; -@@ -595,6 +655,7 @@ static void write_bitstream(struct rpivi - p1_apb_write(de, RPI_BFNUM, len); - p1_apb_write(de, RPI_BFCONTROL, offset + (1 << 7)); // Stop - p1_apb_write(de, RPI_BFCONTROL, offset + (rpi_use_emu << 6)); -+ return 0; - } - - ////////////////////////////////////////////////////////////////////////////// -@@ -623,6 +684,7 @@ static u32 slice_reg_const(const struct - - ////////////////////////////////////////////////////////////////////////////// - -+#define CMDS_NEW_SLICE_SEGMENT (4 + CMDS_WRITE_SCALING_FACTORS) - static void new_slice_segment(struct rpivid_dec_env *const de, - const struct rpivid_dec_state *const s) - { -@@ -706,6 +768,7 @@ static void msg_slice(struct rpivid_dec_ - de->slice_msgs[de->num_slice_msgs++] = msg; - } - -+#define CMDS_PROGRAM_SLICECMDS (1 + SLICE_MSGS_MAX) - static void program_slicecmds(struct rpivid_dec_env *const de, - const int sliceid) - { -@@ -902,6 +965,7 @@ static void pre_slice_decode(struct rpiv - (sh->slice_cb_qp_offset & 31)); // CMD_QPOFF - } - -+#define CMDS_WRITE_SLICE 1 - static void write_slice(struct rpivid_dec_env *const de, - const struct rpivid_dec_state *const s, - const u32 slice_const, -@@ -927,6 +991,7 @@ static void write_slice(struct rpivid_de - * N.B. This can be called to fill in data from the previous slice so must not - * use any state data that may change from slice to slice (e.g. qp) - */ -+#define CMDS_NEW_ENTRY_POINT (6 + CMDS_WRITE_SLICE) - static void new_entry_point(struct rpivid_dec_env *const de, - const struct rpivid_dec_state *const s, - const bool do_bte, -@@ -977,6 +1042,7 @@ static void new_entry_point(struct rpivi - ////////////////////////////////////////////////////////////////////////////// - // Wavefront mode - -+#define CMDS_WPP_PAUSE 4 - static void wpp_pause(struct rpivid_dec_env *const de, int ctb_row) - { - p1_apb_write(de, RPI_STATUS, (ctb_row << 18) | 0x25); -@@ -987,12 +1053,19 @@ static void wpp_pause(struct rpivid_dec_ - p1_apb_write(de, RPI_CONTROL, (ctb_row << 16) + 2); - } - --static void wpp_entry_fill(struct rpivid_dec_env *const de, -- const struct rpivid_dec_state *const s, -- const unsigned int last_y) -+#define CMDS_WPP_ENTRY_FILL_1 (CMDS_WPP_PAUSE + 2 + CMDS_NEW_ENTRY_POINT) -+static int wpp_entry_fill(struct rpivid_dec_env *const de, -+ const struct rpivid_dec_state *const s, -+ const unsigned int last_y) - { -+ int rv; - const unsigned int last_x = s->ctb_width - 1; - -+ rv = cmds_check_space(de, CMDS_WPP_ENTRY_FILL_1 * -+ (last_y - de->entry_ctb_y)); -+ if (rv) -+ return rv; -+ - while (de->entry_ctb_y < last_y) { - /* wpp_entry_x/y set by wpp_entry_point */ - if (s->ctb_width > 2) -@@ -1010,12 +1083,21 @@ static void wpp_entry_fill(struct rpivid - 0, 0, 0, de->entry_ctb_y + 1, - de->entry_qp, de->entry_slice); - } -+ return 0; - } - --static void wpp_end_previous_slice(struct rpivid_dec_env *const de, -- const struct rpivid_dec_state *const s) -+static int wpp_end_previous_slice(struct rpivid_dec_env *const de, -+ const struct rpivid_dec_state *const s) - { -- wpp_entry_fill(de, s, s->prev_ctb_y); -+ int rv; -+ -+ rv = wpp_entry_fill(de, s, s->prev_ctb_y); -+ if (rv) -+ return rv; -+ -+ rv = cmds_check_space(de, CMDS_WPP_PAUSE + 2); -+ if (rv) -+ return rv; - - if (de->entry_ctb_x < 2 && - (de->entry_ctb_y < s->start_ctb_y || s->start_ctb_x > 2) && -@@ -1026,21 +1108,38 @@ static void wpp_end_previous_slice(struc - if (s->start_ctb_x == 2 || - (s->ctb_width == 2 && de->entry_ctb_y < s->start_ctb_y)) - p1_apb_write(de, RPI_TRANSFER, PROB_BACKUP); -+ return 0; - } - - /* Only main profile supported so WPP => !Tiles which makes some of the - * next chunk code simpler - */ --static void wpp_decode_slice(struct rpivid_dec_env *const de, -- const struct rpivid_dec_state *const s) -+static int wpp_decode_slice(struct rpivid_dec_env *const de, -+ const struct rpivid_dec_state *const s) - { - bool reset_qp_y = true; - const bool indep = !s->dependent_slice_segment_flag; -+ int rv; - -- if (s->start_ts) -- wpp_end_previous_slice(de, s); -+ if (s->start_ts) { -+ rv = wpp_end_previous_slice(de, s); -+ if (rv) -+ return rv; -+ } - pre_slice_decode(de, s); -- write_bitstream(de, s); -+ -+ rv = cmds_check_space(de, -+ CMDS_WRITE_BITSTREAM + -+ CMDS_WRITE_PROB + -+ CMDS_PROGRAM_SLICECMDS + -+ CMDS_NEW_SLICE_SEGMENT + -+ CMDS_NEW_ENTRY_POINT); -+ if (rv) -+ return rv; -+ -+ rv = write_bitstream(de, s); -+ if (rv) -+ return rv; - - if (!s->start_ts || indep || s->ctb_width == 1) - write_prob(de, s); -@@ -1056,7 +1155,13 @@ static void wpp_decode_slice(struct rpiv - s->slice_qp, slice_reg_const(s)); - - if (s->frame_end) { -- wpp_entry_fill(de, s, s->ctb_height - 1); -+ rv = wpp_entry_fill(de, s, s->ctb_height - 1); -+ if (rv) -+ return rv; -+ -+ rv = cmds_check_space(de, CMDS_WPP_PAUSE + 1); -+ if (rv) -+ return rv; - - if (de->entry_ctb_x < 2 && s->ctb_width > 2) - wpp_pause(de, s->ctb_height - 1); -@@ -1065,25 +1170,32 @@ static void wpp_decode_slice(struct rpiv - 1 | ((s->ctb_width - 1) << 5) | - ((s->ctb_height - 1) << 18)); - } -- -+ return 0; - } - - ////////////////////////////////////////////////////////////////////////////// - // Tiles mode - --static void tile_entry_fill(struct rpivid_dec_env *const de, -- const struct rpivid_dec_state *const s, -- const unsigned int last_tile_x, -- const unsigned int last_tile_y) -+// Guarantees 1 cmd entry free on exit -+static int tile_entry_fill(struct rpivid_dec_env *const de, -+ const struct rpivid_dec_state *const s, -+ const unsigned int last_tile_x, -+ const unsigned int last_tile_y) - { - while (de->entry_tile_y < last_tile_y || - (de->entry_tile_y == last_tile_y && - de->entry_tile_x < last_tile_x)) { -+ int rv; - unsigned int t_x = de->entry_tile_x; - unsigned int t_y = de->entry_tile_y; - const unsigned int last_x = s->col_bd[t_x + 1] - 1; - const unsigned int last_y = s->row_bd[t_y + 1] - 1; - -+ // One more than needed here -+ rv = cmds_check_space(de, CMDS_NEW_ENTRY_POINT + 3); -+ if (rv) -+ return rv; -+ - p1_apb_write(de, RPI_STATUS, - 2 | (last_x << 5) | (last_y << 18)); - p1_apb_write(de, RPI_TRANSFER, PROB_RELOAD); -@@ -1098,33 +1210,55 @@ static void tile_entry_fill(struct rpivi - t_x, t_y, s->col_bd[t_x], s->row_bd[t_y], - de->entry_qp, de->entry_slice); - } -+ return 0; - } - - /* - * Write STATUS register with expected end CTU address of previous slice - */ --static void end_previous_slice(struct rpivid_dec_env *const de, -- const struct rpivid_dec_state *const s) -+static int end_previous_slice(struct rpivid_dec_env *const de, -+ const struct rpivid_dec_state *const s) - { -- tile_entry_fill(de, s, -- ctb_to_tile_x(s, s->prev_ctb_x), -- ctb_to_tile_y(s, s->prev_ctb_y)); -+ int rv; -+ -+ rv = tile_entry_fill(de, s, -+ ctb_to_tile_x(s, s->prev_ctb_x), -+ ctb_to_tile_y(s, s->prev_ctb_y)); -+ if (rv) -+ return rv; -+ - p1_apb_write(de, RPI_STATUS, - 1 | (s->prev_ctb_x << 5) | (s->prev_ctb_y << 18)); -+ return 0; - } - --static void decode_slice(struct rpivid_dec_env *const de, -- const struct rpivid_dec_state *const s) -+static int decode_slice(struct rpivid_dec_env *const de, -+ const struct rpivid_dec_state *const s) - { - bool reset_qp_y; - unsigned int tile_x = ctb_to_tile_x(s, s->start_ctb_x); - unsigned int tile_y = ctb_to_tile_y(s, s->start_ctb_y); -+ int rv; - -- if (s->start_ts) -- end_previous_slice(de, s); -+ if (s->start_ts) { -+ rv = end_previous_slice(de, s); -+ if (rv) -+ return rv; -+ } -+ -+ rv = cmds_check_space(de, -+ CMDS_WRITE_BITSTREAM + -+ CMDS_WRITE_PROB + -+ CMDS_PROGRAM_SLICECMDS + -+ CMDS_NEW_SLICE_SEGMENT + -+ CMDS_NEW_ENTRY_POINT); -+ if (rv) -+ return rv; - - pre_slice_decode(de, s); -- write_bitstream(de, s); -+ rv = write_bitstream(de, s); -+ if (rv) -+ return rv; - - reset_qp_y = !s->start_ts || - !s->dependent_slice_segment_flag || -@@ -1146,13 +1280,16 @@ static void decode_slice(struct rpivid_d - * when it will be known where this slice finishes - */ - if (s->frame_end) { -- tile_entry_fill(de, s, -- s->tile_width - 1, -- s->tile_height - 1); -+ rv = tile_entry_fill(de, s, -+ s->tile_width - 1, -+ s->tile_height - 1); -+ if (rv) -+ return rv; - p1_apb_write(de, RPI_STATUS, - 1 | ((s->ctb_width - 1) << 5) | - ((s->ctb_height - 1) << 18)); - } -+ return 0; - } - - ////////////////////////////////////////////////////////////////////////////// -@@ -1524,7 +1661,7 @@ static void rpivid_h265_setup(struct rpi - struct rpivid_dev *const dev = ctx->dev; - const struct v4l2_ctrl_hevc_slice_params *const sh = - run->h265.slice_params; -- const struct v4l2_hevc_pred_weight_table *pred_weight_table; -+// const struct v4l2_hevc_pred_weight_table *pred_weight_table; - struct rpivid_q_aux *dpb_q_aux[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; - struct rpivid_dec_state *const s = ctx->state; - struct vb2_queue *vq; -@@ -1532,11 +1669,12 @@ static void rpivid_h265_setup(struct rpi - unsigned int prev_rs; - unsigned int i; - int use_aux; -+ int rv; - bool slice_temporal_mvp; - - xtrace_in(dev, de); - -- pred_weight_table = &sh->pred_weight_table; -+// pred_weight_table = &sh->pred_weight_table; - - s->frame_end = - ((run->src->flags & V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF) == 0); -@@ -1608,9 +1746,9 @@ static void rpivid_h265_setup(struct rpi - de->cmd_len = 0; - de->dpbno_col = ~0U; - -- de->bit_copy_gptr = ctx->bitbufs + 0; -+ de->bit_copy_gptr = ctx->bitbufs + ctx->p1idx; - de->bit_copy_len = 0; -- de->cmd_copy_gptr = ctx->cmdbufs + 0; -+ de->cmd_copy_gptr = ctx->cmdbufs + ctx->p1idx; - - de->frame_c_offset = ctx->dst_fmt.height * 128; - de->frame_stride = ctx->dst_fmt.plane_fmt[0].bytesperline * 128; -@@ -1727,6 +1865,9 @@ static void rpivid_h265_setup(struct rpi - bits_alloc = wxh < 983040 ? wxh * 3 / 4 : - wxh < 983040 * 2 ? 983040 * 3 / 4 : - wxh * 3 / 8; -+ /* Allow for bit depth */ -+ bits_alloc += (bits_alloc * -+ s->sps.bit_depth_luma_minus8) / 8; - bits_alloc = round_up_size(bits_alloc); - - if (gptr_alloc(dev, de->bit_copy_gptr, -@@ -1743,18 +1884,35 @@ static void rpivid_h265_setup(struct rpi - } - } - -- // Pre calc a few things -- s->src_addr = -- !s->frame_end ? -- 0 : -- vb2_dma_contig_plane_dma_addr(&run->src->vb2_buf, 0); -- s->src_buf = s->src_addr != 0 ? NULL : -- vb2_plane_vaddr(&run->src->vb2_buf, 0); -+ // Either map src buffer or use directly -+ s->src_addr = 0; -+ s->src_buf = NULL; -+ -+ if (run->src->planes[0].bytesused < (sh->bit_size + 7) / 8) { -+ v4l2_warn(&dev->v4l2_dev, -+ "Bit size %d > bytesused %d\n", -+ sh->bit_size, run->src->planes[0].bytesused); -+ goto fail; -+ } -+ if (sh->data_bit_offset >= sh->bit_size || -+ sh->bit_size - sh->data_bit_offset < 8) { -+ v4l2_warn(&dev->v4l2_dev, -+ "Bit size %d < Bit offset %d + 8\n", -+ sh->bit_size, sh->data_bit_offset); -+ goto fail; -+ } -+ -+ if (s->frame_end) -+ s->src_addr = vb2_dma_contig_plane_dma_addr(&run->src->vb2_buf, -+ 0); -+ if (!s->src_addr) -+ s->src_buf = vb2_plane_vaddr(&run->src->vb2_buf, 0); - if (!s->src_addr && !s->src_buf) { - v4l2_err(&dev->v4l2_dev, "Failed to map src buffer\n"); - goto fail; - } - -+ // Pre calc a few things - s->sh = sh; - s->slice_qp = 26 + s->pps.init_qp_minus26 + s->sh->slice_qp_delta; - s->max_num_merge_cand = sh->slice_type == HEVC_SLICE_I ? -@@ -1785,9 +1943,11 @@ static void rpivid_h265_setup(struct rpi - s->prev_ctb_y = prev_rs / de->pic_width_in_ctbs_y; - - if ((s->pps.flags & V4L2_HEVC_PPS_FLAG_ENTROPY_CODING_SYNC_ENABLED)) -- wpp_decode_slice(de, s); -+ rv = wpp_decode_slice(de, s); - else -- decode_slice(de, s); -+ rv = decode_slice(de, s); -+ if (rv) -+ goto fail; - - if (!s->frame_end) { - xtrace_ok(dev, de); -@@ -1945,29 +2105,28 @@ static int check_status(const struct rpi - return -1; - } - --static void cb_phase2(struct rpivid_dev *const dev, void *v) -+static void phase2_cb(struct rpivid_dev *const dev, void *v) - { - struct rpivid_dec_env *const de = v; -- struct rpivid_ctx *const ctx = de->ctx; - - xtrace_in(dev, de); - -- v4l2_m2m_cap_buf_return(dev->m2m_dev, ctx->fh.m2m_ctx, de->frame_buf, -- VB2_BUF_STATE_DONE); -- de->frame_buf = NULL; -+ /* Done with buffers - allow new P1 */ -+ rpivid_hw_irq_active1_enable_claim(dev, 1); - -- /* Delete de before finish as finish might immediately trigger a reuse -- * of de -- */ -- dec_env_delete(de); -+ v4l2_m2m_buf_done(de->frame_buf, VB2_BUF_STATE_DONE); -+ de->frame_buf = NULL; - -- if (atomic_add_return(-1, &ctx->p2out) >= RPIVID_P2BUF_COUNT - 1) { -- xtrace_fin(dev, de); -- v4l2_m2m_buf_done_and_job_finish(dev->m2m_dev, ctx->fh.m2m_ctx, -- VB2_BUF_STATE_DONE); -- } -+#if USE_REQUEST_PIN -+ media_request_unpin(de->req_pin); -+ de->req_pin = NULL; -+#else -+ media_request_object_complete(de->req_obj); -+ de->req_obj = NULL; -+#endif - - xtrace_ok(dev, de); -+ dec_env_delete(de); - } - - static void phase2_claimed(struct rpivid_dev *const dev, void *v) -@@ -2023,7 +2182,7 @@ static void phase2_claimed(struct rpivid - // de->ctx->colmvbuf.addr, de->ctx->colmvbuf.addr + - // de->ctx->colmvbuf.size); - -- rpivid_hw_irq_active2_irq(dev, &de->irq_ent, cb_phase2, de); -+ rpivid_hw_irq_active2_irq(dev, &de->irq_ent, phase2_cb, de); - - apb_write_final(dev, RPI_NUMROWS, de->pic_height_in_ctbs_y); - -@@ -2032,6 +2191,39 @@ static void phase2_claimed(struct rpivid - - static void phase1_claimed(struct rpivid_dev *const dev, void *v); - -+// release any and all objects associated with de -+// and reenable phase 1 if required -+static void phase1_err_fin(struct rpivid_dev *const dev, -+ struct rpivid_ctx *const ctx, -+ struct rpivid_dec_env *const de) -+{ -+ /* Return all detached buffers */ -+ if (de->src_buf) -+ v4l2_m2m_buf_done(de->src_buf, VB2_BUF_STATE_ERROR); -+ de->src_buf = NULL; -+ if (de->frame_buf) -+ v4l2_m2m_buf_done(de->frame_buf, VB2_BUF_STATE_ERROR); -+ de->frame_buf = NULL; -+#if USE_REQUEST_PIN -+ if (de->req_pin) -+ media_request_unpin(de->req_pin); -+ de->req_pin = NULL; -+#else -+ if (de->req_obj) -+ media_request_object_complete(de->req_obj); -+ de->req_obj = NULL; -+#endif -+ -+ dec_env_delete(de); -+ -+ /* Reenable phase 0 if we were blocking */ -+ if (atomic_add_return(-1, &ctx->p1out) >= RPIVID_P1BUF_COUNT - 1) -+ v4l2_m2m_job_finish(dev->m2m_dev, ctx->fh.m2m_ctx); -+ -+ /* Done with P1-P2 buffers - allow new P1 */ -+ rpivid_hw_irq_active1_enable_claim(dev, 1); -+} -+ - static void phase1_thread(struct rpivid_dev *const dev, void *v) - { - struct rpivid_dec_env *const de = v; -@@ -2076,15 +2268,12 @@ fail: - __func__); - ctx->fatal_err = 1; - } -- dec_env_delete(de); -- xtrace_fin(dev, de); -- v4l2_m2m_buf_done_and_job_finish(dev->m2m_dev, ctx->fh.m2m_ctx, -- VB2_BUF_STATE_ERROR); - xtrace_fail(dev, de); -+ phase1_err_fin(dev, ctx, de); - } - - /* Always called in irq context (this is good) */ --static void cb_phase1(struct rpivid_dev *const dev, void *v) -+static void phase1_cb(struct rpivid_dev *const dev, void *v) - { - struct rpivid_dec_env *const de = v; - struct rpivid_ctx *const ctx = de->ctx; -@@ -2092,6 +2281,7 @@ static void cb_phase1(struct rpivid_dev - xtrace_in(dev, de); - - de->p1_status = check_status(dev); -+ - if (de->p1_status != 0) { - v4l2_info(&dev->v4l2_dev, "%s: Post wait: %#x\n", - __func__, de->p1_status); -@@ -2105,24 +2295,17 @@ static void cb_phase1(struct rpivid_dev - return; - } - -- /* After the frame-buf is detached it must be returned but from -- * this point onward (phase2_claimed, cb_phase2) there are no error -- * paths so the return at the end of cb_phase2 is all that is needed -- */ -- de->frame_buf = v4l2_m2m_cap_buf_detach(dev->m2m_dev, ctx->fh.m2m_ctx); -- if (!de->frame_buf) { -- v4l2_err(&dev->v4l2_dev, "%s: No detached buffer\n", __func__); -- goto fail; -- } -+ v4l2_m2m_buf_done(de->src_buf, VB2_BUF_STATE_DONE); -+ de->src_buf = NULL; - -+ /* All phase1 error paths done - it is safe to inc p2idx */ - ctx->p2idx = - (ctx->p2idx + 1 >= RPIVID_P2BUF_COUNT) ? 0 : ctx->p2idx + 1; - -- // Enable the next setup if our Q isn't too big -- if (atomic_add_return(1, &ctx->p2out) < RPIVID_P2BUF_COUNT) { -+ /* Renable the next setup if we were blocking */ -+ if (atomic_add_return(-1, &ctx->p1out) >= RPIVID_P1BUF_COUNT - 1) { - xtrace_fin(dev, de); -- v4l2_m2m_buf_done_and_job_finish(dev->m2m_dev, ctx->fh.m2m_ctx, -- VB2_BUF_STATE_DONE); -+ v4l2_m2m_job_finish(dev->m2m_dev, ctx->fh.m2m_ctx); - } - - rpivid_hw_irq_active2_claim(dev, &de->irq_ent, phase2_claimed, de); -@@ -2131,11 +2314,8 @@ static void cb_phase1(struct rpivid_dev - return; - - fail: -- dec_env_delete(de); -- xtrace_fin(dev, de); -- v4l2_m2m_buf_done_and_job_finish(dev->m2m_dev, ctx->fh.m2m_ctx, -- VB2_BUF_STATE_ERROR); - xtrace_fail(dev, de); -+ phase1_err_fin(dev, ctx, de); - } - - static void phase1_claimed(struct rpivid_dev *const dev, void *v) -@@ -2160,6 +2340,10 @@ static void phase1_claimed(struct rpivid - de->coeff_stride = - ALIGN_DOWN(coeff_gptr->size / de->pic_height_in_ctbs_y, 64); - -+ /* phase1_claimed blocked until cb_phase1 completed so p2idx inc -+ * in cb_phase1 after error detection -+ */ -+ - apb_write_vc_addr(dev, RPI_PUWBASE, de->pu_base_vc); - apb_write_vc_len(dev, RPI_PUWSTRIDE, de->pu_stride); - apb_write_vc_addr(dev, RPI_COEFFWBASE, de->coeff_base_vc); -@@ -2169,7 +2353,7 @@ static void phase1_claimed(struct rpivid - apb_write(dev, RPI_CFNUM, de->cmd_len); - - // Claim irq -- rpivid_hw_irq_active1_irq(dev, &de->irq_ent, cb_phase1, de); -+ rpivid_hw_irq_active1_irq(dev, &de->irq_ent, phase1_cb, de); - - // And start the h/w - apb_write_vc_addr_final(dev, RPI_CFBASE, de->cmd_copy_gptr->addr); -@@ -2178,11 +2362,8 @@ static void phase1_claimed(struct rpivid - return; - - fail: -- dec_env_delete(de); -- xtrace_fin(dev, de); -- v4l2_m2m_buf_done_and_job_finish(dev->m2m_dev, ctx->fh.m2m_ctx, -- VB2_BUF_STATE_ERROR); - xtrace_fail(dev, de); -+ phase1_err_fin(dev, ctx, de); - } - - static void dec_state_delete(struct rpivid_ctx *const ctx) -@@ -2315,7 +2496,9 @@ static void rpivid_h265_trigger(struct r - case RPIVID_DECODE_SLICE_CONTINUE: - v4l2_m2m_buf_done_and_job_finish(dev->m2m_dev, ctx->fh.m2m_ctx, - VB2_BUF_STATE_DONE); -+ xtrace_ok(dev, de); - break; -+ - default: - v4l2_err(&dev->v4l2_dev, "%s: Unexpected state: %d\n", __func__, - de->state); -@@ -2329,14 +2512,59 @@ static void rpivid_h265_trigger(struct r - v4l2_m2m_buf_done_and_job_finish(dev->m2m_dev, ctx->fh.m2m_ctx, - VB2_BUF_STATE_ERROR); - break; -+ - case RPIVID_DECODE_PHASE1: - ctx->dec0 = NULL; -+ -+#if !USE_REQUEST_PIN -+ /* Alloc a new request object - needs to be alloced dynamically -+ * as the media request will release it some random time after -+ * it is completed -+ */ -+ de->req_obj = kmalloc(sizeof(*de->req_obj), GFP_KERNEL); -+ if (!de->req_obj) { -+ xtrace_fail(dev, de); -+ dec_env_delete(de); -+ v4l2_m2m_buf_done_and_job_finish(dev->m2m_dev, -+ ctx->fh.m2m_ctx, -+ VB2_BUF_STATE_ERROR); -+ break; -+ } -+ media_request_object_init(de->req_obj); -+#warning probably needs to _get the req obj too -+#endif -+ ctx->p1idx = (ctx->p1idx + 1 >= RPIVID_P1BUF_COUNT) ? -+ 0 : ctx->p1idx + 1; -+ -+ /* We know we have src & dst so no need to test */ -+ de->src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); -+ de->frame_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); -+ -+#if USE_REQUEST_PIN -+ de->req_pin = de->src_buf->vb2_buf.req_obj.req; -+ media_request_pin(de->req_pin); -+#else -+ media_request_object_bind(de->src_buf->vb2_buf.req_obj.req, -+ &dst_req_obj_ops, de, false, -+ de->req_obj); -+#endif -+ -+ /* We could get rid of the src buffer here if we've already -+ * copied it, but we don't copy the last buffer unless it -+ * didn't return a contig dma addr and that shouldn't happen -+ */ -+ -+ /* Enable the next setup if our Q isn't too big */ -+ if (atomic_add_return(1, &ctx->p1out) < RPIVID_P1BUF_COUNT) { -+ xtrace_fin(dev, de); -+ v4l2_m2m_job_finish(dev->m2m_dev, ctx->fh.m2m_ctx); -+ } -+ - rpivid_hw_irq_active1_claim(dev, &de->irq_ent, phase1_claimed, - de); -+ xtrace_ok(dev, de); - break; - } -- -- xtrace_ok(dev, de); - } - - struct rpivid_dec_ops rpivid_dec_ops_h265 = { ---- a/drivers/staging/media/rpivid/rpivid_hw.c -+++ b/drivers/staging/media/rpivid/rpivid_hw.c -@@ -185,14 +185,14 @@ static void do_enable_claim(struct rpivi - sched_cb(dev, ictl, ient); - } - --static void ictl_init(struct rpivid_hw_irq_ctrl * const ictl) -+static void ictl_init(struct rpivid_hw_irq_ctrl * const ictl, int enables) - { - spin_lock_init(&ictl->lock); - ictl->claim = NULL; - ictl->tail = NULL; - ictl->irq = NULL; - ictl->no_sched = 0; -- ictl->enable = -1; -+ ictl->enable = enables; - ictl->thread_reqed = false; - } - -@@ -308,8 +308,8 @@ int rpivid_hw_probe(struct rpivid_dev *d - int irq_dec; - int ret = 0; - -- ictl_init(&dev->ic_active1); -- ictl_init(&dev->ic_active2); -+ ictl_init(&dev->ic_active1, RPIVID_P2BUF_COUNT); -+ ictl_init(&dev->ic_active2, RPIVID_ICTL_ENABLE_UNLIMITED); - - res = platform_get_resource_byname(dev->pdev, IORESOURCE_MEM, "intc"); - if (!res) diff --git a/target/linux/bcm27xx/patches-5.15/950-0398-media-rpivid-Map-cmd-buffer-directly.patch b/target/linux/bcm27xx/patches-5.15/950-0398-media-rpivid-Map-cmd-buffer-directly.patch deleted file mode 100644 index b56947325..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0398-media-rpivid-Map-cmd-buffer-directly.patch +++ /dev/null @@ -1,160 +0,0 @@ -From a84845bed68844d9d84c242b9357b908bdd19b9d Mon Sep 17 00:00:00 2001 -From: John Cox -Date: Mon, 29 Mar 2021 17:42:16 +0100 -Subject: [PATCH] media: rpivid: Map cmd buffer directly - -It is unnecessary to have a separate dmabuf to hold the cmd buffer. -Map it directly from the kmalloc. - -Signed-off-by: John Cox ---- - drivers/staging/media/rpivid/rpivid.h | 3 +- - drivers/staging/media/rpivid/rpivid_h265.c | 48 ++++++++++------------ - drivers/staging/media/rpivid/rpivid_hw.c | 2 + - 3 files changed, 25 insertions(+), 28 deletions(-) - ---- a/drivers/staging/media/rpivid/rpivid.h -+++ b/drivers/staging/media/rpivid/rpivid.h -@@ -114,7 +114,6 @@ struct rpivid_ctx { - unsigned int p1idx; - atomic_t p1out; - struct rpivid_gptr bitbufs[RPIVID_P1BUF_COUNT]; -- struct rpivid_gptr cmdbufs[RPIVID_P1BUF_COUNT]; - - /* *** Should be in dev *** */ - unsigned int p2idx; -@@ -183,6 +182,8 @@ struct rpivid_dev { - struct clk *clock; - struct clk_request *hevc_req; - -+ int cache_align; -+ - struct rpivid_hw_irq_ctrl ic_active1; - struct rpivid_hw_irq_ctrl ic_active2; - }; ---- a/drivers/staging/media/rpivid/rpivid_h265.c -+++ b/drivers/staging/media/rpivid/rpivid_h265.c -@@ -227,6 +227,9 @@ struct rpivid_dec_env { - struct rpivid_q_aux *frame_aux; - struct rpivid_q_aux *col_aux; - -+ dma_addr_t cmd_addr; -+ size_t cmd_size; -+ - dma_addr_t pu_base_vc; - dma_addr_t coeff_base_vc; - u32 pu_stride; -@@ -234,7 +237,6 @@ struct rpivid_dec_env { - - struct rpivid_gptr *bit_copy_gptr; - size_t bit_copy_len; -- struct rpivid_gptr *cmd_copy_gptr; - - #define SLICE_MSGS_MAX (2 * HEVC_MAX_REFS * 8 + 3) - u16 slice_msgs[SLICE_MSGS_MAX]; -@@ -1499,22 +1501,17 @@ static int write_cmd_buffer(struct rpivi - struct rpivid_dec_env *const de, - const struct rpivid_dec_state *const s) - { -- // Copy commands out to dma buf -- const size_t cmd_size = de->cmd_len * sizeof(de->cmd_fifo[0]); -- -- if (!de->cmd_copy_gptr->ptr || cmd_size > de->cmd_copy_gptr->size) { -- size_t cmd_alloc = round_up_size(cmd_size); -+ const size_t cmd_size = ALIGN(de->cmd_len * sizeof(de->cmd_fifo[0]), -+ dev->cache_align); - -- if (gptr_realloc_new(dev, de->cmd_copy_gptr, cmd_alloc)) { -- v4l2_err(&dev->v4l2_dev, -- "Alloc cmd buffer (%zu): FAILED\n", cmd_alloc); -- return -ENOMEM; -- } -- v4l2_info(&dev->v4l2_dev, "Alloc cmd buffer (%zu): OK\n", -- cmd_alloc); -+ de->cmd_addr = dma_map_single(dev->dev, de->cmd_fifo, -+ cmd_size, DMA_TO_DEVICE); -+ if (dma_mapping_error(dev->dev, de->cmd_addr)) { -+ v4l2_err(&dev->v4l2_dev, -+ "Map cmd buffer (%zu): FAILED\n", cmd_size); -+ return -ENOMEM; - } -- -- memcpy(de->cmd_copy_gptr->ptr, de->cmd_fifo, cmd_size); -+ de->cmd_size = cmd_size; - return 0; - } - -@@ -1551,6 +1548,12 @@ static void dec_env_delete(struct rpivid - struct rpivid_ctx * const ctx = de->ctx; - unsigned long lock_flags; - -+ if (de->cmd_size) { -+ dma_unmap_single(ctx->dev->dev, de->cmd_addr, de->cmd_size, -+ DMA_TO_DEVICE); -+ de->cmd_size = 0; -+ } -+ - aux_q_release(ctx, &de->frame_aux); - aux_q_release(ctx, &de->col_aux); - -@@ -1603,7 +1606,8 @@ static int dec_env_init(struct rpivid_ct - - de->ctx = ctx; - de->decode_order = i; -- de->cmd_max = 1024; -+// de->cmd_max = 1024; -+ de->cmd_max = 8096; - de->cmd_fifo = kmalloc_array(de->cmd_max, - sizeof(struct rpi_cmd), - GFP_KERNEL); -@@ -1748,7 +1752,6 @@ static void rpivid_h265_setup(struct rpi - - de->bit_copy_gptr = ctx->bitbufs + ctx->p1idx; - de->bit_copy_len = 0; -- de->cmd_copy_gptr = ctx->cmdbufs + ctx->p1idx; - - de->frame_c_offset = ctx->dst_fmt.height * 128; - de->frame_stride = ctx->dst_fmt.plane_fmt[0].bytesperline * 128; -@@ -2356,7 +2359,7 @@ static void phase1_claimed(struct rpivid - rpivid_hw_irq_active1_irq(dev, &de->irq_ent, phase1_cb, de); - - // And start the h/w -- apb_write_vc_addr_final(dev, RPI_CFBASE, de->cmd_copy_gptr->addr); -+ apb_write_vc_addr_final(dev, RPI_CFBASE, de->cmd_addr); - - xtrace_ok(dev, de); - return; -@@ -2400,8 +2403,6 @@ static void rpivid_h265_stop(struct rpiv - - for (i = 0; i != ARRAY_SIZE(ctx->bitbufs); ++i) - gptr_free(dev, ctx->bitbufs + i); -- for (i = 0; i != ARRAY_SIZE(ctx->cmdbufs); ++i) -- gptr_free(dev, ctx->cmdbufs + i); - for (i = 0; i != ARRAY_SIZE(ctx->pu_bufs); ++i) - gptr_free(dev, ctx->pu_bufs + i); - for (i = 0; i != ARRAY_SIZE(ctx->coeff_bufs); ++i) -@@ -2451,13 +2452,6 @@ static int rpivid_h265_start(struct rpiv - goto fail; - } - -- // 16k is plenty for most purposes but we will realloc if needed -- for (i = 0; i != ARRAY_SIZE(ctx->cmdbufs); ++i) { -- if (gptr_alloc(dev, ctx->cmdbufs + i, 0x4000, -- DMA_ATTR_FORCE_CONTIGUOUS)) -- goto fail; -- } -- - // Finger in the air PU & Coeff alloc - // Will be realloced if too small - coeff_alloc = round_up_size(wxh); ---- a/drivers/staging/media/rpivid/rpivid_hw.c -+++ b/drivers/staging/media/rpivid/rpivid_hw.c -@@ -331,6 +331,8 @@ int rpivid_hw_probe(struct rpivid_dev *d - if (IS_ERR(dev->clock)) - return PTR_ERR(dev->clock); - -+ dev->cache_align = dma_get_cache_alignment(); -+ - // Disable IRQs & reset anything pending - irq_write(dev, 0, - ARG_IC_ICTRL_ACTIVE1_EN_SET | ARG_IC_ICTRL_ACTIVE2_EN_SET); diff --git a/target/linux/bcm27xx/patches-5.15/950-0399-media-rpivid-Improve-values-returned-when-setting-ou.patch b/target/linux/bcm27xx/patches-5.15/950-0399-media-rpivid-Improve-values-returned-when-setting-ou.patch deleted file mode 100644 index 8b6ec75c1..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0399-media-rpivid-Improve-values-returned-when-setting-ou.patch +++ /dev/null @@ -1,216 +0,0 @@ -From 9f32962c0fe4129a01bd0422cd1cda76a13c5ef4 Mon Sep 17 00:00:00 2001 -From: John Cox -Date: Thu, 1 Apr 2021 16:20:58 +0100 -Subject: [PATCH] media: rpivid: Improve values returned when setting - output format - -Guess a better value for the compressed bitstream buffer size - -Signed-off-by: John Cox ---- - drivers/staging/media/rpivid/rpivid_h265.c | 66 ++++----------------- - drivers/staging/media/rpivid/rpivid_video.c | 61 +++++++++++++++++-- - drivers/staging/media/rpivid/rpivid_video.h | 4 ++ - 3 files changed, 70 insertions(+), 61 deletions(-) - ---- a/drivers/staging/media/rpivid/rpivid_h265.c -+++ b/drivers/staging/media/rpivid/rpivid_h265.c -@@ -18,6 +18,7 @@ - - #include "rpivid.h" - #include "rpivid_hw.h" -+#include "rpivid_video.h" - - #define DEBUG_TRACE_P1_CMD 0 - #define DEBUG_TRACE_EXECUTION 0 -@@ -115,41 +116,9 @@ static int gptr_realloc_new(struct rpivi - return 0; - } - --/* floor(log2(x)) */ --static unsigned int log2_size(size_t x) --{ -- unsigned int n = 0; -- -- if (x & ~0xffff) { -- n += 16; -- x >>= 16; -- } -- if (x & ~0xff) { -- n += 8; -- x >>= 8; -- } -- if (x & ~0xf) { -- n += 4; -- x >>= 4; -- } -- if (x & ~3) { -- n += 2; -- x >>= 2; -- } -- return (x & ~1) ? n + 1 : n; --} -- --static size_t round_up_size(const size_t x) --{ -- /* Admit no size < 256 */ -- const unsigned int n = x < 256 ? 8 : log2_size(x) - 1; -- -- return x >= (3 << n) ? 4 << n : (3 << n); --} -- - static size_t next_size(const size_t x) - { -- return round_up_size(x + 1); -+ return rpivid_round_up_size(x + 1); - } - - #define NUM_SCALING_FACTORS 4064 /* Not a typo = 0xbe0 + 0x400 */ -@@ -332,7 +301,7 @@ static int cmds_check_space(struct rpivi - if (de->cmd_len + n <= de->cmd_max) - return 0; - -- newmax = 2 << log2_size(de->cmd_len + n); -+ newmax = roundup_pow_of_two(de->cmd_len + n); - - a = krealloc(de->cmd_fifo, newmax * sizeof(struct rpi_cmd), - GFP_KERNEL); -@@ -1855,23 +1824,10 @@ static void rpivid_h265_setup(struct rpi - * slice as we can use the src buf directly - */ - if (!s->frame_end && !de->bit_copy_gptr->ptr) { -- const size_t wxh = s->sps.pic_width_in_luma_samples * -- s->sps.pic_height_in_luma_samples; - size_t bits_alloc; -- -- /* Annex A gives a min compression of 2 @ lvl 3.1 -- * (wxh <= 983040) and min 4 thereafter but avoid -- * the odity of 983041 having a lower limit than -- * 983040. -- * Multiply by 3/2 for 4:2:0 -- */ -- bits_alloc = wxh < 983040 ? wxh * 3 / 4 : -- wxh < 983040 * 2 ? 983040 * 3 / 4 : -- wxh * 3 / 8; -- /* Allow for bit depth */ -- bits_alloc += (bits_alloc * -- s->sps.bit_depth_luma_minus8) / 8; -- bits_alloc = round_up_size(bits_alloc); -+ bits_alloc = rpivid_bit_buf_size(s->sps.pic_width_in_luma_samples, -+ s->sps.pic_height_in_luma_samples, -+ s->sps.bit_depth_luma_minus8); - - if (gptr_alloc(dev, de->bit_copy_gptr, - bits_alloc, -@@ -2454,17 +2410,15 @@ static int rpivid_h265_start(struct rpiv - - // Finger in the air PU & Coeff alloc - // Will be realloced if too small -- coeff_alloc = round_up_size(wxh); -- pu_alloc = round_up_size(wxh / 4); -+ coeff_alloc = rpivid_round_up_size(wxh); -+ pu_alloc = rpivid_round_up_size(wxh / 4); - for (i = 0; i != ARRAY_SIZE(ctx->pu_bufs); ++i) { - // Don't actually need a kernel mapping here - if (gptr_alloc(dev, ctx->pu_bufs + i, pu_alloc, -- DMA_ATTR_FORCE_CONTIGUOUS | -- DMA_ATTR_NO_KERNEL_MAPPING)) -+ DMA_ATTR_NO_KERNEL_MAPPING)) - goto fail; - if (gptr_alloc(dev, ctx->coeff_bufs + i, coeff_alloc, -- DMA_ATTR_FORCE_CONTIGUOUS | -- DMA_ATTR_NO_KERNEL_MAPPING)) -+ DMA_ATTR_NO_KERNEL_MAPPING)) - goto fail; - } - aux_q_init(ctx); ---- a/drivers/staging/media/rpivid/rpivid_video.c -+++ b/drivers/staging/media/rpivid/rpivid_video.c -@@ -42,18 +42,69 @@ static inline unsigned int constrain2x(u - (x > y * 2) ? y : x; - } - -+size_t rpivid_round_up_size(const size_t x) -+{ -+ /* Admit no size < 256 */ -+ const unsigned int n = x < 256 ? 8 : ilog2(x); -+ -+ return x >= (3 << n) ? 4 << n : (3 << n); -+} -+ -+size_t rpivid_bit_buf_size(unsigned int w, unsigned int h, unsigned int bits_minus8) -+{ -+ const size_t wxh = w * h; -+ size_t bits_alloc; -+ -+ /* Annex A gives a min compression of 2 @ lvl 3.1 -+ * (wxh <= 983040) and min 4 thereafter but avoid -+ * the odity of 983041 having a lower limit than -+ * 983040. -+ * Multiply by 3/2 for 4:2:0 -+ */ -+ bits_alloc = wxh < 983040 ? wxh * 3 / 4 : -+ wxh < 983040 * 2 ? 983040 * 3 / 4 : -+ wxh * 3 / 8; -+ /* Allow for bit depth */ -+ bits_alloc += (bits_alloc * bits_minus8) / 8; -+ return rpivid_round_up_size(bits_alloc); -+} -+ - int rpivid_prepare_src_format(struct v4l2_pix_format_mplane *pix_fmt) - { -+ size_t size; -+ u32 w; -+ u32 h; -+ - if (pix_fmt->pixelformat != V4L2_PIX_FMT_HEVC_SLICE) - return -EINVAL; - -- /* Zero bytes per line for encoded source. */ -- pix_fmt->plane_fmt[0].bytesperline = 0; -- /* Choose some minimum size since this can't be 0 */ -- pix_fmt->plane_fmt[0].sizeimage = max_t(u32, SZ_1K, -- pix_fmt->plane_fmt[0].sizeimage); -+ w = pix_fmt->width; -+ h = pix_fmt->height; -+ if (!w || !h) { -+ w = 1920; -+ h = 1080; -+ } -+ if (w > 4096) -+ w = 4096; -+ if (h > 4096) -+ h = 4096; -+ -+ if (!pix_fmt->plane_fmt[0].sizeimage || -+ pix_fmt->plane_fmt[0].sizeimage > SZ_32M) { -+ /* Unspecified or way too big - pick max for size */ -+ size = rpivid_bit_buf_size(w, h, 2); -+ } -+ /* Set a minimum */ -+ size = max_t(u32, SZ_4K, pix_fmt->plane_fmt[0].sizeimage); -+ -+ pix_fmt->width = w; -+ pix_fmt->height = h; - pix_fmt->num_planes = 1; - pix_fmt->field = V4L2_FIELD_NONE; -+ /* Zero bytes per line for encoded source. */ -+ pix_fmt->plane_fmt[0].bytesperline = 0; -+ pix_fmt->plane_fmt[0].sizeimage = size; -+ - return 0; - } - ---- a/drivers/staging/media/rpivid/rpivid_video.h -+++ b/drivers/staging/media/rpivid/rpivid_video.h -@@ -24,6 +24,10 @@ extern const struct v4l2_ioctl_ops rpivi - - int rpivid_queue_init(void *priv, struct vb2_queue *src_vq, - struct vb2_queue *dst_vq); -+ -+size_t rpivid_bit_buf_size(unsigned int w, unsigned int h, unsigned int bits_minus8); -+size_t rpivid_round_up_size(const size_t x); -+ - int rpivid_prepare_src_format(struct v4l2_pix_format_mplane *pix_fmt); - int rpivid_prepare_dst_format(struct v4l2_pix_format_mplane *pix_fmt); - diff --git a/target/linux/bcm27xx/patches-5.15/950-0400-media-rpivid-Improve-stream_on-off-conformance-clock.patch b/target/linux/bcm27xx/patches-5.15/950-0400-media-rpivid-Improve-stream_on-off-conformance-clock.patch deleted file mode 100644 index b48a4bcca..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0400-media-rpivid-Improve-stream_on-off-conformance-clock.patch +++ /dev/null @@ -1,260 +0,0 @@ -From 6242eec33d0b49a6ea12c60cf98693dc5abc5577 Mon Sep 17 00:00:00 2001 -From: John Cox -Date: Sat, 3 Apr 2021 16:27:03 +0100 -Subject: [PATCH] media: rpivid: Improve stream_on/off conformance & - clock setup - -Fix stream on & off such that failures leave the driver in the correct -state. Ensure that the clock is on when we are streaming and off when -all contexts attached to this device have stopped streaming. - -Signed-off-by: John Cox ---- - drivers/staging/media/rpivid/rpivid.c | 8 +- - drivers/staging/media/rpivid/rpivid.h | 15 ++- - drivers/staging/media/rpivid/rpivid_hw.c | 1 + - drivers/staging/media/rpivid/rpivid_video.c | 103 +++++++++++++++----- - 4 files changed, 101 insertions(+), 26 deletions(-) - ---- a/drivers/staging/media/rpivid/rpivid.c -+++ b/drivers/staging/media/rpivid/rpivid.c -@@ -212,9 +212,12 @@ static int rpivid_open(struct file *file - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); - if (!ctx) { - mutex_unlock(&dev->dev_mutex); -- return -ENOMEM; -+ ret = -ENOMEM; -+ goto err_unlock; - } - -+ mutex_init(&ctx->ctx_mutex); -+ - v4l2_fh_init(&ctx->fh, video_devdata(file)); - file->private_data = &ctx->fh; - ctx->dev = dev; -@@ -245,7 +248,9 @@ static int rpivid_open(struct file *file - err_ctrls: - v4l2_ctrl_handler_free(&ctx->hdl); - err_free: -+ mutex_destroy(&ctx->ctx_mutex); - kfree(ctx); -+err_unlock: - mutex_unlock(&dev->dev_mutex); - - return ret; -@@ -266,6 +271,7 @@ static int rpivid_release(struct file *f - kfree(ctx->ctrls); - - v4l2_fh_exit(&ctx->fh); -+ mutex_destroy(&ctx->ctx_mutex); - - kfree(ctx); - ---- a/drivers/staging/media/rpivid/rpivid.h -+++ b/drivers/staging/media/rpivid/rpivid.h -@@ -84,6 +84,11 @@ struct rpivid_q_aux; - #define RPIVID_AUX_ENT_COUNT VB2_MAX_FRAME - - -+#define RPIVID_CTX_STATE_STOPPED 0 /* stream_off */ -+#define RPIVID_CTX_STATE_STREAM_ON 1 /* decoding */ -+#define RPIVID_CTX_STATE_STREAM_STOP 2 /* in stream_off */ -+#define RPIVID_CTX_STATE_STREAM_ERR 3 /* stream_on but broken */ -+ - struct rpivid_ctx { - struct v4l2_fh fh; - struct rpivid_dev *dev; -@@ -91,10 +96,19 @@ struct rpivid_ctx { - struct v4l2_pix_format_mplane src_fmt; - struct v4l2_pix_format_mplane dst_fmt; - int dst_fmt_set; -+ -+ atomic_t stream_state; -+ struct clk_request *clk_req; -+ int src_stream_on; -+ int dst_stream_on; -+ - // fatal_err is set if an error has occurred s.t. decode cannot - // continue (such as running out of CMA) - int fatal_err; - -+ /* Lock for queue operations */ -+ struct mutex ctx_mutex; -+ - struct v4l2_ctrl_handler hdl; - struct v4l2_ctrl **ctrls; - -@@ -180,7 +194,6 @@ struct rpivid_dev { - void __iomem *base_h265; - - struct clk *clock; -- struct clk_request *hevc_req; - - int cache_align; - ---- a/drivers/staging/media/rpivid/rpivid_hw.c -+++ b/drivers/staging/media/rpivid/rpivid_hw.c -@@ -359,6 +359,7 @@ int rpivid_hw_probe(struct rpivid_dev *d - void rpivid_hw_remove(struct rpivid_dev *dev) - { - // IRQ auto freed on unload so no need to do it here -+ // ioremap auto freed on unload - ictl_uninit(&dev->ic_active1); - ictl_uninit(&dev->ic_active2); - } ---- a/drivers/staging/media/rpivid/rpivid_video.c -+++ b/drivers/staging/media/rpivid/rpivid_video.c -@@ -18,6 +18,7 @@ - #include - - #include "rpivid.h" -+#include "rpivid_hw.h" - #include "rpivid_video.h" - #include "rpivid_dec.h" - -@@ -533,33 +534,85 @@ static int rpivid_buf_prepare(struct vb2 - return 0; - } - -+/* Only stops the clock if streaom off on both output & capture */ -+static void stop_clock(struct rpivid_dev *dev, struct rpivid_ctx *ctx) -+{ -+ if (ctx->src_stream_on || -+ ctx->dst_stream_on || -+ !ctx->clk_req) -+ return; -+ -+ clk_request_done(ctx->clk_req); -+ ctx->clk_req = NULL; -+ -+ clk_disable_unprepare(dev->clock); -+} -+ -+/* Always starts the clock if it isn't already on this ctx */ -+static int start_clock(struct rpivid_dev *dev, struct rpivid_ctx *ctx) -+{ -+ long max_hevc_clock; -+ int rv; -+ -+ if (ctx->clk_req) -+ return 0; -+ -+ max_hevc_clock = clk_round_rate(dev->clock, ULONG_MAX); -+ -+ ctx->clk_req = clk_request_start(dev->clock, max_hevc_clock); -+ if (!ctx->clk_req) { -+ dev_err(dev->dev, "Failed to set clock rate\n"); -+ return -EIO; -+ } -+ -+ rv = clk_prepare_enable(dev->clock); -+ if (rv) { -+ dev_err(dev->dev, "Failed to enable clock\n"); -+ clk_request_done(ctx->clk_req); -+ ctx->clk_req = NULL; -+ return rv; -+ } -+ -+ return 0; -+} -+ - static int rpivid_start_streaming(struct vb2_queue *vq, unsigned int count) - { - struct rpivid_ctx *ctx = vb2_get_drv_priv(vq); - struct rpivid_dev *dev = ctx->dev; -- long max_hevc_clock = clk_round_rate(dev->clock, ULONG_MAX); - int ret = 0; - -- if (ctx->src_fmt.pixelformat != V4L2_PIX_FMT_HEVC_SLICE) -- return -EINVAL; -- -- if (V4L2_TYPE_IS_OUTPUT(vq->type) && dev->dec_ops->start) -- ret = dev->dec_ops->start(ctx); -+ if (!V4L2_TYPE_IS_OUTPUT(vq->type)) { -+ ctx->dst_stream_on = 1; -+ goto ok; -+ } - -- dev->hevc_req = clk_request_start(dev->clock, max_hevc_clock); -- if (!dev->hevc_req) { -- dev_err(dev->dev, "Failed to set clock rate\n"); -- goto out; -+ if (ctx->src_fmt.pixelformat != V4L2_PIX_FMT_HEVC_SLICE) { -+ ret = -EINVAL; -+ goto fail_cleanup; - } - -- ret = clk_prepare_enable(dev->clock); -+ if (ctx->src_stream_on) -+ goto ok; -+ -+ ret = start_clock(dev, ctx); - if (ret) -- dev_err(dev->dev, "Failed to enable clock\n"); -+ goto fail_cleanup; - --out: -+ if (dev->dec_ops->start) -+ ret = dev->dec_ops->start(ctx); - if (ret) -- rpivid_queue_cleanup(vq, VB2_BUF_STATE_QUEUED); -+ goto fail_stop_clock; -+ -+ ctx->src_stream_on = 1; -+ok: -+ return 0; - -+fail_stop_clock: -+ stop_clock(dev, ctx); -+fail_cleanup: -+ v4l2_err(&dev->v4l2_dev, "%s: qtype=%d: FAIL\n", __func__, vq->type); -+ rpivid_queue_cleanup(vq, VB2_BUF_STATE_QUEUED); - return ret; - } - -@@ -568,17 +621,19 @@ static void rpivid_stop_streaming(struct - struct rpivid_ctx *ctx = vb2_get_drv_priv(vq); - struct rpivid_dev *dev = ctx->dev; - -- if (V4L2_TYPE_IS_OUTPUT(vq->type) && dev->dec_ops->stop) -- dev->dec_ops->stop(ctx); -+ if (V4L2_TYPE_IS_OUTPUT(vq->type)) { -+ ctx->src_stream_on = 0; -+ if (dev->dec_ops->stop) -+ dev->dec_ops->stop(ctx); -+ } else { -+ ctx->dst_stream_on = 0; -+ } - - rpivid_queue_cleanup(vq, VB2_BUF_STATE_ERROR); - -- if (dev->hevc_req) -- { -- clk_request_done(dev->hevc_req); -- dev->hevc_req = NULL; -- } -- clk_disable_unprepare(dev->clock); -+ vb2_wait_for_all_buffers(vq); -+ -+ stop_clock(dev, ctx); - } - - static void rpivid_buf_queue(struct vb2_buffer *vb) -@@ -622,7 +677,7 @@ int rpivid_queue_init(void *priv, struct - src_vq->ops = &rpivid_qops; - src_vq->mem_ops = &vb2_dma_contig_memops; - src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; -- src_vq->lock = &ctx->dev->dev_mutex; -+ src_vq->lock = &ctx->ctx_mutex; - src_vq->dev = ctx->dev->dev; - src_vq->supports_requests = true; - src_vq->requires_requests = true; -@@ -639,7 +694,7 @@ int rpivid_queue_init(void *priv, struct - dst_vq->ops = &rpivid_qops; - dst_vq->mem_ops = &vb2_dma_contig_memops; - dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; -- dst_vq->lock = &ctx->dev->dev_mutex; -+ dst_vq->lock = &ctx->ctx_mutex; - dst_vq->dev = ctx->dev->dev; - - return vb2_queue_init(dst_vq); diff --git a/target/linux/bcm27xx/patches-5.15/950-0401-media-rpivid-Improve-SPS-PPS-error-handling-validati.patch b/target/linux/bcm27xx/patches-5.15/950-0401-media-rpivid-Improve-SPS-PPS-error-handling-validati.patch deleted file mode 100644 index 74bd1bc04..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0401-media-rpivid-Improve-SPS-PPS-error-handling-validati.patch +++ /dev/null @@ -1,256 +0,0 @@ -From c93803888818493c5a0b8eb150256e5f4e6887e8 Mon Sep 17 00:00:00 2001 -From: John Cox -Date: Thu, 8 Apr 2021 18:34:09 +0100 -Subject: [PATCH] media: rpivid: Improve SPS/PPS error - handling/validation - -Move size and width checking from bitstream processing to control -validation - -Signed-off-by: John Cox ---- - drivers/staging/media/rpivid/rpivid.c | 5 +- - drivers/staging/media/rpivid/rpivid.h | 6 +- - drivers/staging/media/rpivid/rpivid_h265.c | 132 ++++++++++++++++++--- - 3 files changed, 121 insertions(+), 22 deletions(-) - ---- a/drivers/staging/media/rpivid/rpivid.c -+++ b/drivers/staging/media/rpivid/rpivid.c -@@ -38,12 +38,14 @@ static const struct rpivid_control rpivi - { - .cfg = { - .id = V4L2_CID_MPEG_VIDEO_HEVC_SPS, -+ .ops = &rpivid_hevc_sps_ctrl_ops, - }, - .required = true, - }, - { - .cfg = { - .id = V4L2_CID_MPEG_VIDEO_HEVC_PPS, -+ .ops = &rpivid_hevc_pps_ctrl_ops, - }, - .required = true, - }, -@@ -119,7 +121,7 @@ static int rpivid_init_ctrls(struct rpiv - - for (i = 0; i < rpivid_ctrls_COUNT; i++) { - ctrl = v4l2_ctrl_new_custom(hdl, &rpivid_ctrls[i].cfg, -- NULL); -+ ctx); - if (hdl->error) { - v4l2_err(&dev->v4l2_dev, - "Failed to create new custom control id=%#x\n", -@@ -191,6 +193,7 @@ static int rpivid_request_validate(struc - if (!ctrl_test) { - v4l2_info(&ctx->dev->v4l2_dev, - "Missing required codec control\n"); -+ v4l2_ctrl_request_hdl_put(hdl); - return -ENOENT; - } - } ---- a/drivers/staging/media/rpivid/rpivid.h -+++ b/drivers/staging/media/rpivid/rpivid.h -@@ -185,7 +185,7 @@ struct rpivid_dev { - struct platform_device *pdev; - struct device *dev; - struct v4l2_m2m_dev *m2m_dev; -- struct rpivid_dec_ops *dec_ops; -+ const struct rpivid_dec_ops *dec_ops; - - /* Device file mutex */ - struct mutex dev_mutex; -@@ -201,7 +201,9 @@ struct rpivid_dev { - struct rpivid_hw_irq_ctrl ic_active2; - }; - --extern struct rpivid_dec_ops rpivid_dec_ops_h265; -+extern const struct rpivid_dec_ops rpivid_dec_ops_h265; -+extern const struct v4l2_ctrl_ops rpivid_hevc_sps_ctrl_ops; -+extern const struct v4l2_ctrl_ops rpivid_hevc_pps_ctrl_ops; - - struct v4l2_ctrl *rpivid_find_ctrl(struct rpivid_ctx *ctx, u32 id); - void *rpivid_find_control_data(struct rpivid_ctx *ctx, u32 id); ---- a/drivers/staging/media/rpivid/rpivid_h265.c -+++ b/drivers/staging/media/rpivid/rpivid_h265.c -@@ -1432,9 +1432,13 @@ static int updated_ps(struct rpivid_dec_ - s->ctb_addr_rs_to_ts = kmalloc_array(s->ctb_size, - sizeof(*s->ctb_addr_rs_to_ts), - GFP_KERNEL); -+ if (!s->ctb_addr_rs_to_ts) -+ goto fail; - s->ctb_addr_ts_to_rs = kmalloc_array(s->ctb_size, - sizeof(*s->ctb_addr_ts_to_rs), - GFP_KERNEL); -+ if (!s->ctb_addr_ts_to_rs) -+ goto fail; - - if (!(s->pps.flags & V4L2_HEVC_PPS_FLAG_TILES_ENABLED)) { - s->tile_width = 1; -@@ -1446,8 +1450,12 @@ static int updated_ps(struct rpivid_dec_ - - s->col_bd = kmalloc((s->tile_width + 1) * sizeof(*s->col_bd), - GFP_KERNEL); -+ if (!s->col_bd) -+ goto fail; - s->row_bd = kmalloc((s->tile_height + 1) * sizeof(*s->row_bd), - GFP_KERNEL); -+ if (!s->row_bd) -+ goto fail; - - s->col_bd[0] = 0; - for (i = 1; i < s->tile_width; i++) -@@ -1462,8 +1470,13 @@ static int updated_ps(struct rpivid_dec_ - s->row_bd[s->tile_height] = s->ctb_height; - - fill_rs_to_ts(s); -- - return 0; -+ -+fail: -+ free_ps_info(s); -+ /* Set invalid to force reload */ -+ s->sps.pic_width_in_luma_samples = 0; -+ return -ENOMEM; - } - - static int write_cmd_buffer(struct rpivid_dev *const dev, -@@ -1694,7 +1707,9 @@ static void rpivid_h265_setup(struct rpi - memcpy(&s->pps, run->h265.pps, sizeof(s->pps)); - - /* Recalc stuff as required */ -- updated_ps(s); -+ rv = updated_ps(s); -+ if (rv) -+ goto fail; - } - - de = dec_env_new(ctx); -@@ -1772,22 +1787,6 @@ static void rpivid_h265_setup(struct rpi - goto fail; - } - -- if (s->sps.pic_width_in_luma_samples > 4096 || -- s->sps.pic_height_in_luma_samples > 4096) { -- v4l2_warn(&dev->v4l2_dev, -- "Pic dimension (%dx%d) exeeds 4096\n", -- s->sps.pic_width_in_luma_samples, -- s->sps.pic_height_in_luma_samples); -- goto fail; -- } -- if ((s->tile_width != 1 || s->tile_height != 1) && -- (s->pps.flags & -- V4L2_HEVC_PPS_FLAG_ENTROPY_CODING_SYNC_ENABLED)) { -- v4l2_warn(&dev->v4l2_dev, -- "Tiles + WPP not supported\n"); -- goto fail; -- } -- - // Fill in ref planes with our address s.t. if we mess - // up refs somehow then we still have a valid address - // entry -@@ -2515,9 +2514,104 @@ static void rpivid_h265_trigger(struct r - } - } - --struct rpivid_dec_ops rpivid_dec_ops_h265 = { -+const struct rpivid_dec_ops rpivid_dec_ops_h265 = { - .setup = rpivid_h265_setup, - .start = rpivid_h265_start, - .stop = rpivid_h265_stop, - .trigger = rpivid_h265_trigger, - }; -+ -+static int try_ctrl_sps(struct v4l2_ctrl *ctrl) -+{ -+ const struct v4l2_ctrl_hevc_sps *const sps = ctrl->p_new.p_hevc_sps; -+ struct rpivid_ctx *const ctx = ctrl->priv; -+ struct rpivid_dev *const dev = ctx->dev; -+ -+ if (sps->chroma_format_idc != 1) { -+ v4l2_warn(&dev->v4l2_dev, -+ "Chroma format (%d) unsupported\n", -+ sps->chroma_format_idc); -+ return -EINVAL; -+ } -+ -+ if (sps->bit_depth_luma_minus8 != 0 && -+ sps->bit_depth_luma_minus8 != 2) { -+ v4l2_warn(&dev->v4l2_dev, -+ "Luma depth (%d) unsupported\n", -+ sps->bit_depth_luma_minus8 + 8); -+ return -EINVAL; -+ } -+ -+ if (sps->bit_depth_luma_minus8 != sps->bit_depth_chroma_minus8) { -+ v4l2_warn(&dev->v4l2_dev, -+ "Chroma depth (%d) != Luma depth (%d)\n", -+ sps->bit_depth_chroma_minus8 + 8, -+ sps->bit_depth_luma_minus8 + 8); -+ return -EINVAL; -+ } -+ -+ if (!sps->pic_width_in_luma_samples || -+ !sps->pic_height_in_luma_samples || -+ sps->pic_width_in_luma_samples > 4096 || -+ sps->pic_height_in_luma_samples > 4096) { -+ v4l2_warn(&dev->v4l2_dev, -+ "Bad sps width (%u) x height (%u)\n", -+ sps->pic_width_in_luma_samples, -+ sps->pic_height_in_luma_samples); -+ return -EINVAL; -+ } -+ -+ if (!ctx->dst_fmt_set) -+ return 0; -+ -+ if ((sps->bit_depth_luma_minus8 == 0 && -+ ctx->dst_fmt.pixelformat != V4L2_PIX_FMT_NV12_COL128) || -+ (sps->bit_depth_luma_minus8 == 2 && -+ ctx->dst_fmt.pixelformat != V4L2_PIX_FMT_NV12_10_COL128)) { -+ v4l2_warn(&dev->v4l2_dev, -+ "SPS luma depth %d does not match capture format\n", -+ sps->bit_depth_luma_minus8 + 8); -+ return -EINVAL; -+ } -+ -+ if (sps->pic_width_in_luma_samples > ctx->dst_fmt.width || -+ sps->pic_height_in_luma_samples > ctx->dst_fmt.height) { -+ v4l2_warn(&dev->v4l2_dev, -+ "SPS size (%dx%d) > capture size (%d,%d)\n", -+ sps->pic_width_in_luma_samples, -+ sps->pic_height_in_luma_samples, -+ ctx->dst_fmt.width, -+ ctx->dst_fmt.height); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+const struct v4l2_ctrl_ops rpivid_hevc_sps_ctrl_ops = { -+ .try_ctrl = try_ctrl_sps, -+}; -+ -+static int try_ctrl_pps(struct v4l2_ctrl *ctrl) -+{ -+ const struct v4l2_ctrl_hevc_pps *const pps = ctrl->p_new.p_hevc_pps; -+ struct rpivid_ctx *const ctx = ctrl->priv; -+ struct rpivid_dev *const dev = ctx->dev; -+ -+ if ((pps->flags & -+ V4L2_HEVC_PPS_FLAG_ENTROPY_CODING_SYNC_ENABLED) && -+ (pps->flags & -+ V4L2_HEVC_PPS_FLAG_TILES_ENABLED) && -+ (pps->num_tile_columns_minus1 || pps->num_tile_rows_minus1)) { -+ v4l2_warn(&dev->v4l2_dev, -+ "WPP + Tiles not supported\n"); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+const struct v4l2_ctrl_ops rpivid_hevc_pps_ctrl_ops = { -+ .try_ctrl = try_ctrl_pps, -+}; -+ diff --git a/target/linux/bcm27xx/patches-5.15/950-0402-bcm2835-Allow-compressed-frames-to-set-sizeimage-438.patch b/target/linux/bcm27xx/patches-5.15/950-0402-bcm2835-Allow-compressed-frames-to-set-sizeimage-438.patch deleted file mode 100644 index bdc497d88..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0402-bcm2835-Allow-compressed-frames-to-set-sizeimage-438.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 1e84fba295e3335427ddd9014059617b430077d8 Mon Sep 17 00:00:00 2001 -From: jc-kynesim -Date: Fri, 11 Jun 2021 15:14:31 +0100 -Subject: [PATCH] bcm2835: Allow compressed frames to set sizeimage - (#4386) - -Allow the user to set sizeimage in TRY_FMT and S_FMT if the format -flags have V4L2_FMT_FLAG_COMPRESSED set - -Signed-off-by: John Cox ---- - .../bcm2835-codec/bcm2835-v4l2-codec.c | 17 ++++++++++++++--- - 1 file changed, 14 insertions(+), 3 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -1291,6 +1291,8 @@ static int vidioc_g_fmt_vid_cap(struct f - static int vidioc_try_fmt(struct bcm2835_codec_ctx *ctx, struct v4l2_format *f, - struct bcm2835_codec_fmt *fmt) - { -+ unsigned int sizeimage; -+ - /* - * The V4L2 specification requires the driver to correct the format - * struct if any of the dimensions is unsupported -@@ -1319,9 +1321,18 @@ static int vidioc_try_fmt(struct bcm2835 - f->fmt.pix_mp.num_planes = 1; - f->fmt.pix_mp.plane_fmt[0].bytesperline = - get_bytesperline(f->fmt.pix_mp.width, fmt); -- f->fmt.pix_mp.plane_fmt[0].sizeimage = -- get_sizeimage(f->fmt.pix_mp.plane_fmt[0].bytesperline, -- f->fmt.pix_mp.width, f->fmt.pix_mp.height, fmt); -+ sizeimage = get_sizeimage(f->fmt.pix_mp.plane_fmt[0].bytesperline, -+ f->fmt.pix_mp.width, f->fmt.pix_mp.height, -+ fmt); -+ /* -+ * Drivers must set sizeimage for uncompressed formats -+ * Compressed formats allow the client to request an alternate -+ * size for the buffer. -+ */ -+ if (!(fmt->flags & V4L2_FMT_FLAG_COMPRESSED) || -+ f->fmt.pix_mp.plane_fmt[0].sizeimage < sizeimage) -+ f->fmt.pix_mp.plane_fmt[0].sizeimage = sizeimage; -+ - memset(f->fmt.pix_mp.plane_fmt[0].reserved, 0, - sizeof(f->fmt.pix_mp.plane_fmt[0].reserved)); - diff --git a/target/linux/bcm27xx/patches-5.15/950-0403-media-i2c-imx477-Fix-for-long-exposure-limit-calcula.patch b/target/linux/bcm27xx/patches-5.15/950-0403-media-i2c-imx477-Fix-for-long-exposure-limit-calcula.patch deleted file mode 100644 index 60d1c1b1a..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0403-media-i2c-imx477-Fix-for-long-exposure-limit-calcula.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 28d69f0b8b5b66551071919c652355d266e8a841 Mon Sep 17 00:00:00 2001 -From: Naushir Patuck -Date: Fri, 11 Jun 2021 12:47:07 +0100 -Subject: [PATCH] media: i2c: imx477: Fix for long exposure limit - calculations - -Do not scale IMX477_EXPOSURE_OFFSET with the long exposure factor during -the limit calculations. This allows larger exposure times, and does seem to be -what the sensor is doing internally. - -Signed-off-by: Naushir Patuck ---- - drivers/media/i2c/imx477.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/media/i2c/imx477.c -+++ b/drivers/media/i2c/imx477.c -@@ -1282,7 +1282,7 @@ static void imx477_adjust_exposure_range - - /* Honour the VBLANK limits when setting exposure. */ - exposure_max = imx477->mode->height + imx477->vblank->val - -- (IMX477_EXPOSURE_OFFSET << imx477->long_exp_shift); -+ IMX477_EXPOSURE_OFFSET; - exposure_def = min(exposure_max, imx477->exposure->val); - __v4l2_ctrl_modify_range(imx477->exposure, imx477->exposure->minimum, - exposure_max, imx477->exposure->step, diff --git a/target/linux/bcm27xx/patches-5.15/950-0405-bcm2835-pcm.c-Support-multichannel-audio.patch b/target/linux/bcm27xx/patches-5.15/950-0405-bcm2835-pcm.c-Support-multichannel-audio.patch deleted file mode 100644 index ff1d9c433..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0405-bcm2835-pcm.c-Support-multichannel-audio.patch +++ /dev/null @@ -1,34 +0,0 @@ -From dfd5bc84858c99405a797cb5998fc48ed7d0611d Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Tue, 30 Apr 2019 19:15:30 +0100 -Subject: [PATCH] bcm2835-pcm.c: Support multichannel audio - ---- - .../vc04_services/bcm2835-audio/bcm2835-pcm.c | 13 +++++++------ - 1 file changed, 7 insertions(+), 6 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -@@ -31,15 +31,16 @@ static const struct snd_pcm_hardware snd - SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_SYNC_APPLPTR | SNDRV_PCM_INFO_BATCH), - .formats = SNDRV_PCM_FMTBIT_S16_LE, -- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_44100 | -- SNDRV_PCM_RATE_48000, -+ .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | -+ SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | -+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000, - .rate_min = 44100, -- .rate_max = 48000, -+ .rate_max = 192000, - .channels_min = 2, -- .channels_max = 2, -- .buffer_bytes_max = 128 * 1024, -+ .channels_max = 8, -+ .buffer_bytes_max = 512 * 1024, - .period_bytes_min = 1 * 1024, -- .period_bytes_max = 128 * 1024, -+ .period_bytes_max = 512 * 1024, - .periods_min = 1, - .periods_max = 128, - }; diff --git a/target/linux/bcm27xx/patches-5.15/950-0406-bcm2835-pcm-Fix-up-multichannel-pcm-audio.patch b/target/linux/bcm27xx/patches-5.15/950-0406-bcm2835-pcm-Fix-up-multichannel-pcm-audio.patch deleted file mode 100644 index 57d37e67e..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0406-bcm2835-pcm-Fix-up-multichannel-pcm-audio.patch +++ /dev/null @@ -1,36 +0,0 @@ -From fa8bf1b5e90fd0c137fd35d0ae4a80672f5b9317 Mon Sep 17 00:00:00 2001 -From: Dom Cobley -Date: Tue, 27 Oct 2020 12:24:14 +0000 -Subject: [PATCH] bcm2835-pcm: Fix up multichannel pcm audio - -Fixes: a9c1660ff5f02d048c5f31abf1fd1108ccf9ef87 -Signed-off-by: Dom Cobley ---- - .../vc04_services/bcm2835-audio/bcm2835-pcm.c | 13 ++++++------- - 1 file changed, 6 insertions(+), 7 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -+++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c -@@ -31,16 +31,15 @@ static const struct snd_pcm_hardware snd - SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_SYNC_APPLPTR | SNDRV_PCM_INFO_BATCH), - .formats = SNDRV_PCM_FMTBIT_S16_LE, -- .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | -- SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | -- SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000, -+ .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_44100 | -+ SNDRV_PCM_RATE_48000, - .rate_min = 44100, -- .rate_max = 192000, -+ .rate_max = 48000, - .channels_min = 2, -- .channels_max = 8, -- .buffer_bytes_max = 512 * 1024, -+ .channels_max = 2, -+ .buffer_bytes_max = 128 * 1024, - .period_bytes_min = 1 * 1024, -- .period_bytes_max = 512 * 1024, -+ .period_bytes_max = 128 * 1024, - .periods_min = 1, - .periods_max = 128, - }; diff --git a/target/linux/bcm27xx/patches-5.15/950-0407-media-i2c-imx290-Support-60fps-in-2-lane-operation.patch b/target/linux/bcm27xx/patches-5.15/950-0407-media-i2c-imx290-Support-60fps-in-2-lane-operation.patch deleted file mode 100644 index 454e50932..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0407-media-i2c-imx290-Support-60fps-in-2-lane-operation.patch +++ /dev/null @@ -1,309 +0,0 @@ -From 9a1509cc97e4329475cbd0c45258dcdf5d49a7f1 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 17 Jun 2021 12:05:25 +0100 -Subject: [PATCH] media: i2c: imx290: Support 60fps in 2 lane operation - -Commit "97589ad61c73 media: i2c: imx290: Add support for 2 data lanes" -added support for running in two lane mode (instead of 4), but -without changing the link frequency that resulted in a max of 30fps. - -Commit "98e0500eadb7 media: i2c: imx290: Add configurable link frequency -and pixel rate" then doubled the link frequency when in 2 lane mode, -but didn't undo the correction for running at only 30fps, just extending -horizontal blanking instead. -It also didn't update the CSI timing registers in accordance with the -datasheet. - -Remove the 30fps limit on 2 lane by correcting the register config -in accordance with the datasheet for 60fps operation over 2 lanes. -Frame rate control (via V4L2_CID_VBLANK or HBLANK) can still reduce -the frame rate on 2 lanes back to 30fps. - -Signed-off-by: Dave Stevenson ---- - drivers/media/i2c/imx290.c | 163 ++++++++++++++++++++++--------------- - 1 file changed, 97 insertions(+), 66 deletions(-) - ---- a/drivers/media/i2c/imx290.c -+++ b/drivers/media/i2c/imx290.c -@@ -46,8 +46,7 @@ enum imx290_clk_index { - #define IMX290_VMAX_MAX 0x3fff - #define IMX290_HMAX_LOW 0x301c - #define IMX290_HMAX_HIGH 0x301d --#define IMX290_HMAX_MIN_2LANE 4400 /* Min of 4400 pixels = 30fps */ --#define IMX290_HMAX_MIN_4LANE 2200 /* Min of 2200 pixels = 60fps */ -+#define IMX290_HMAX_MIN 2200 /* Min of 2200 pixels = 60fps */ - #define IMX290_HMAX_MAX 0xffff - - #define IMX290_EXPOSURE_MIN 1 -@@ -89,8 +88,11 @@ struct imx290_mode { - u8 link_freq_index; - struct v4l2_rect crop; - -- const struct imx290_regval *data; -- u32 data_size; -+ const struct imx290_regval *mode_data; -+ u32 mode_data_size; -+ const struct imx290_regval *lane_data; -+ u32 lane_data_size; -+ - - /* Clock setup can vary. Index as enum imx290_clk_index */ - const struct imx290_regval *clk_data[2]; -@@ -242,8 +244,9 @@ static const struct imx290_regval imx290 - { 0x3480, 0x92 }, - }; - --static const struct imx290_regval imx290_1080p_settings[] = { -+static const struct imx290_regval imx290_1080p_common_settings[] = { - /* mode settings */ -+ { IMX290_FR_FDG_SEL, 0x01 }, - { 0x3007, 0x00 }, - { 0x303a, 0x0c }, - { 0x3414, 0x0a }, -@@ -253,8 +256,36 @@ static const struct imx290_regval imx290 - { 0x3419, 0x04 }, - { 0x3012, 0x64 }, - { 0x3013, 0x00 }, -+}; -+ -+static const struct imx290_regval imx290_1080p_2lane_settings[] = { -+ { 0x3405, 0x00 }, - /* data rate settings */ -+ { IMX290_PHY_LANE_NUM, 0x01 }, -+ { IMX290_CSI_LANE_MODE, 0x01 }, -+ { 0x3446, 0x77 }, -+ { 0x3447, 0x00 }, -+ { 0x3448, 0x67 }, -+ { 0x3449, 0x00 }, -+ { 0x344a, 0x47 }, -+ { 0x344b, 0x00 }, -+ { 0x344c, 0x37 }, -+ { 0x344d, 0x00 }, -+ { 0x344e, 0x3f }, -+ { 0x344f, 0x00 }, -+ { 0x3450, 0xff }, -+ { 0x3451, 0x00 }, -+ { 0x3452, 0x3f }, -+ { 0x3453, 0x00 }, -+ { 0x3454, 0x37 }, -+ { 0x3455, 0x00 }, -+}; -+ -+static const struct imx290_regval imx290_1080p_4lane_settings[] = { - { 0x3405, 0x10 }, -+ /* data rate settings */ -+ { IMX290_PHY_LANE_NUM, 0x03 }, -+ { IMX290_CSI_LANE_MODE, 0x03 }, - { 0x3446, 0x57 }, - { 0x3447, 0x00 }, - { 0x3448, 0x37 }, -@@ -297,8 +328,9 @@ static const struct imx290_regval imx290 - { 0x3480, 0x92 }, - }; - --static const struct imx290_regval imx290_720p_settings[] = { -+static const struct imx290_regval imx290_720p_common_settings[] = { - /* mode settings */ -+ { IMX290_FR_FDG_SEL, 0x01 }, - { 0x3007, 0x10 }, - { 0x303a, 0x06 }, - { 0x3414, 0x04 }, -@@ -308,8 +340,36 @@ static const struct imx290_regval imx290 - { 0x3419, 0x02 }, - { 0x3012, 0x64 }, - { 0x3013, 0x00 }, -+}; -+ -+static const struct imx290_regval imx290_720p_2lane_settings[] = { -+ { 0x3405, 0x00 }, -+ { IMX290_PHY_LANE_NUM, 0x01 }, -+ { IMX290_CSI_LANE_MODE, 0x01 }, - /* data rate settings */ -+ { 0x3446, 0x67 }, -+ { 0x3447, 0x00 }, -+ { 0x3448, 0x57 }, -+ { 0x3449, 0x00 }, -+ { 0x344a, 0x2f }, -+ { 0x344b, 0x00 }, -+ { 0x344c, 0x27 }, -+ { 0x344d, 0x00 }, -+ { 0x344e, 0x2f }, -+ { 0x344f, 0x00 }, -+ { 0x3450, 0xbf }, -+ { 0x3451, 0x00 }, -+ { 0x3452, 0x2f }, -+ { 0x3453, 0x00 }, -+ { 0x3454, 0x27 }, -+ { 0x3455, 0x00 }, -+}; -+ -+static const struct imx290_regval imx290_720p_4lane_settings[] = { - { 0x3405, 0x10 }, -+ { IMX290_PHY_LANE_NUM, 0x03 }, -+ { IMX290_CSI_LANE_MODE, 0x03 }, -+ /* data rate settings */ - { 0x3446, 0x4f }, - { 0x3447, 0x00 }, - { 0x3448, 0x2f }, -@@ -389,7 +449,7 @@ static const struct imx290_mode imx290_m - { - .width = 1920, - .height = 1080, -- .hmax = 0x1130, -+ .hmax = 0x0898, - .vmax = 0x0465, - .link_freq_index = FREQ_INDEX_1080P, - .crop = { -@@ -398,8 +458,10 @@ static const struct imx290_mode imx290_m - .width = 1920, - .height = 1080, - }, -- .data = imx290_1080p_settings, -- .data_size = ARRAY_SIZE(imx290_1080p_settings), -+ .mode_data = imx290_1080p_common_settings, -+ .mode_data_size = ARRAY_SIZE(imx290_1080p_common_settings), -+ .lane_data = imx290_1080p_2lane_settings, -+ .lane_data_size = ARRAY_SIZE(imx290_1080p_2lane_settings), - .clk_data = { - [CLK_37_125] = imx290_37_125mhz_clock_1080p, - [CLK_74_25] = imx290_74_250mhz_clock_1080p, -@@ -409,7 +471,7 @@ static const struct imx290_mode imx290_m - { - .width = 1280, - .height = 720, -- .hmax = 0x19c8, -+ .hmax = 0x0ce4, - .vmax = 0x02ee, - .link_freq_index = FREQ_INDEX_720P, - .crop = { -@@ -418,8 +480,10 @@ static const struct imx290_mode imx290_m - .width = 1280, - .height = 720, - }, -- .data = imx290_720p_settings, -- .data_size = ARRAY_SIZE(imx290_720p_settings), -+ .mode_data = imx290_720p_common_settings, -+ .mode_data_size = ARRAY_SIZE(imx290_720p_common_settings), -+ .lane_data = imx290_720p_2lane_settings, -+ .lane_data_size = ARRAY_SIZE(imx290_720p_2lane_settings), - .clk_data = { - [CLK_37_125] = imx290_37_125mhz_clock_1080p, - [CLK_74_25] = imx290_74_250mhz_clock_1080p, -@@ -441,8 +505,10 @@ static const struct imx290_mode imx290_m - .width = 1920, - .height = 1080, - }, -- .data = imx290_1080p_settings, -- .data_size = ARRAY_SIZE(imx290_1080p_settings), -+ .mode_data = imx290_1080p_common_settings, -+ .mode_data_size = ARRAY_SIZE(imx290_1080p_common_settings), -+ .lane_data = imx290_1080p_4lane_settings, -+ .lane_data_size = ARRAY_SIZE(imx290_1080p_4lane_settings), - .clk_data = { - [CLK_37_125] = imx290_37_125mhz_clock_720p, - [CLK_74_25] = imx290_74_250mhz_clock_720p, -@@ -461,8 +527,10 @@ static const struct imx290_mode imx290_m - .width = 1280, - .height = 720, - }, -- .data = imx290_720p_settings, -- .data_size = ARRAY_SIZE(imx290_720p_settings), -+ .mode_data = imx290_720p_common_settings, -+ .mode_data_size = ARRAY_SIZE(imx290_720p_common_settings), -+ .lane_data = imx290_720p_4lane_settings, -+ .lane_data_size = ARRAY_SIZE(imx290_720p_4lane_settings), - .clk_data = { - [CLK_37_125] = imx290_37_125mhz_clock_720p, - [CLK_74_25] = imx290_74_250mhz_clock_720p, -@@ -1016,8 +1084,18 @@ static int imx290_start_streaming(struct - } - - /* Apply default values of current mode */ -- ret = imx290_set_register_array(imx290, imx290->current_mode->data, -- imx290->current_mode->data_size); -+ ret = imx290_set_register_array(imx290, -+ imx290->current_mode->mode_data, -+ imx290->current_mode->mode_data_size); -+ if (ret < 0) { -+ dev_err(imx290->dev, "Could not set current mode\n"); -+ return ret; -+ } -+ -+ /* Apply lane config registers of current mode */ -+ ret = imx290_set_register_array(imx290, -+ imx290->current_mode->lane_data, -+ imx290->current_mode->lane_data_size); - if (ret < 0) { - dev_err(imx290->dev, "Could not set current mode\n"); - return ret; -@@ -1080,49 +1158,6 @@ static int imx290_get_regulators(struct - imx290->supplies); - } - --static int imx290_set_data_lanes(struct imx290 *imx290) --{ -- int ret = 0, laneval, frsel; -- -- switch (imx290->nlanes) { -- case 2: -- laneval = 0x01; -- frsel = 0x02; -- break; -- case 4: -- laneval = 0x03; -- frsel = 0x01; -- break; -- default: -- /* -- * We should never hit this since the data lane count is -- * validated in probe itself -- */ -- dev_err(imx290->dev, "Lane configuration not supported\n"); -- ret = -EINVAL; -- goto exit; -- } -- -- ret = imx290_write_reg(imx290, IMX290_PHY_LANE_NUM, laneval); -- if (ret) { -- dev_err(imx290->dev, "Error setting Physical Lane number register\n"); -- goto exit; -- } -- -- ret = imx290_write_reg(imx290, IMX290_CSI_LANE_MODE, laneval); -- if (ret) { -- dev_err(imx290->dev, "Error setting CSI Lane mode register\n"); -- goto exit; -- } -- -- ret = imx290_write_reg(imx290, IMX290_FR_FDG_SEL, frsel); -- if (ret) -- dev_err(imx290->dev, "Error setting FR/FDG SEL register\n"); -- --exit: -- return ret; --} -- - static int imx290_power_on(struct device *dev) - { - struct v4l2_subdev *sd = dev_get_drvdata(dev); -@@ -1146,9 +1181,6 @@ static int imx290_power_on(struct device - gpiod_set_value_cansleep(imx290->rst_gpio, 0); - usleep_range(30000, 31000); - -- /* Set data lane count */ -- imx290_set_data_lanes(imx290); -- - return 0; - } - -@@ -1271,8 +1303,7 @@ static int imx290_probe(struct i2c_clien - ret = -EINVAL; - goto free_err; - } -- imx290->hmax_min = (imx290->nlanes == 2) ? IMX290_HMAX_MIN_2LANE : -- IMX290_HMAX_MIN_4LANE; -+ imx290->hmax_min = IMX290_HMAX_MIN; - - dev_dbg(dev, "Using %u data lanes\n", imx290->nlanes); - diff --git a/target/linux/bcm27xx/patches-5.15/950-0408-media-i2c-imx290-Fix-the-pixel-rate-at-148.5Mpix-s.patch b/target/linux/bcm27xx/patches-5.15/950-0408-media-i2c-imx290-Fix-the-pixel-rate-at-148.5Mpix-s.patch deleted file mode 100644 index 00d4e133c..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0408-media-i2c-imx290-Fix-the-pixel-rate-at-148.5Mpix-s.patch +++ /dev/null @@ -1,49 +0,0 @@ -From ae89f74e9c2583b2d49ea0c6d5653aa820083c4e Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 17 Jun 2021 13:00:39 +0100 -Subject: [PATCH] media: i2c: imx290: Fix the pixel rate at 148.5Mpix/s - -Whilst the datasheet lists the link frequency changing between -1080p and 720p modes, reality is that with the default blanking -we have -(1920 + 280) * (1080 + 45) * 60fps = 148.5MPix/s -and -(1280 + 2020) * (720 + 30) * 60fps = 148.5MPix/s -and this reflects reality whether in 10 or 12 bit readout modes. - -How this relates to link frequency is unclear as it differs -from the datasheet, but all exposure and frame rate calcs need -the pixel rate to be correct, so make it so. - -Signed-off-by: Dave Stevenson ---- - drivers/media/i2c/imx290.c | 16 +--------------- - 1 file changed, 1 insertion(+), 15 deletions(-) - ---- a/drivers/media/i2c/imx290.c -+++ b/drivers/media/i2c/imx290.c -@@ -853,23 +853,9 @@ static inline u8 imx290_get_link_freq_in - return imx290->current_mode->link_freq_index; - } - --static s64 imx290_get_link_freq(struct imx290 *imx290) --{ -- u8 index = imx290_get_link_freq_index(imx290); -- -- return *(imx290_link_freqs_ptr(imx290) + index); --} -- - static u64 imx290_calc_pixel_rate(struct imx290 *imx290) - { -- s64 link_freq = imx290_get_link_freq(imx290); -- u8 nlanes = imx290->nlanes; -- u64 pixel_rate; -- -- /* pixel rate = link_freq * 2 * nr_of_lanes / bits_per_sample */ -- pixel_rate = link_freq * 2 * nlanes; -- do_div(pixel_rate, imx290->bpp); -- return pixel_rate; -+ return 148500000; - } - - static int imx290_set_fmt(struct v4l2_subdev *sd, diff --git a/target/linux/bcm27xx/patches-5.15/950-0409-media-i2c-imx290-Fix-clock-setup-register-assignment.patch b/target/linux/bcm27xx/patches-5.15/950-0409-media-i2c-imx290-Fix-clock-setup-register-assignment.patch deleted file mode 100644 index 3b3d1f0a5..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0409-media-i2c-imx290-Fix-clock-setup-register-assignment.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 7958a59b6cf1b5f80d12282c9182cae72a1d4f16 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 17 Jun 2021 17:27:46 +0100 -Subject: [PATCH] media: i2c: imx290: Fix clock setup register - assignments - -When the clock setups were added for the alternate external clocks, -the settings for 2 lane 720p and 4 lane 1080p were transposed. -2 lane 720p still worked, but 4 lane 1080p didn't. - -Correct the assignments. - -Fixes: 6b0c094a5b58 (media: i2c: imx290: Add support for 74.25MHz clock") - -Signed-off-by: Dave Stevenson ---- - drivers/media/i2c/imx290.c | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - ---- a/drivers/media/i2c/imx290.c -+++ b/drivers/media/i2c/imx290.c -@@ -485,10 +485,10 @@ static const struct imx290_mode imx290_m - .lane_data = imx290_720p_2lane_settings, - .lane_data_size = ARRAY_SIZE(imx290_720p_2lane_settings), - .clk_data = { -- [CLK_37_125] = imx290_37_125mhz_clock_1080p, -- [CLK_74_25] = imx290_74_250mhz_clock_1080p, -+ [CLK_37_125] = imx290_37_125mhz_clock_720p, -+ [CLK_74_25] = imx290_74_250mhz_clock_720p, - }, -- .clk_size = ARRAY_SIZE(imx290_37_125mhz_clock_1080p), -+ .clk_size = ARRAY_SIZE(imx290_37_125mhz_clock_720p), - }, - }; - -@@ -510,10 +510,10 @@ static const struct imx290_mode imx290_m - .lane_data = imx290_1080p_4lane_settings, - .lane_data_size = ARRAY_SIZE(imx290_1080p_4lane_settings), - .clk_data = { -- [CLK_37_125] = imx290_37_125mhz_clock_720p, -- [CLK_74_25] = imx290_74_250mhz_clock_720p, -+ [CLK_37_125] = imx290_37_125mhz_clock_1080p, -+ [CLK_74_25] = imx290_74_250mhz_clock_1080p, - }, -- .clk_size = ARRAY_SIZE(imx290_37_125mhz_clock_720p), -+ .clk_size = ARRAY_SIZE(imx290_37_125mhz_clock_1080p), - }, - { - .width = 1280, diff --git a/target/linux/bcm27xx/patches-5.15/950-0410-media-rpivid-Fix-H265-aux-ent-reuse-of-the-same-slot.patch b/target/linux/bcm27xx/patches-5.15/950-0410-media-rpivid-Fix-H265-aux-ent-reuse-of-the-same-slot.patch deleted file mode 100644 index 318f2bf0f..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0410-media-rpivid-Fix-H265-aux-ent-reuse-of-the-same-slot.patch +++ /dev/null @@ -1,151 +0,0 @@ -From a873fa8e44651d31d005199053a16cfc440ffc49 Mon Sep 17 00:00:00 2001 -From: John Cox -Date: Thu, 24 Jun 2021 14:43:49 +0100 -Subject: [PATCH] media: rpivid: Fix H265 aux ent reuse of the same - slot - -It is legitimate, though unusual, for an aux ent associated with a slot -to be selected in phase 0 before a previous selection has been used and -released in phase 2. Fix such that if the slot is found to be in use -that the aux ent associated with it is reused rather than an new aux -ent being created. This fixes a problem where when the first aux ent -was released the second was lost track of. - -This bug spotted in Nick's testing. It may explain some other occasional, -unreliable decode error reports where dmesg included "Missing DPB AUX -ent" logging. - -Signed-off-by: John Cox ---- - drivers/staging/media/rpivid/rpivid_h265.c | 75 ++++++++++++++-------- - 1 file changed, 49 insertions(+), 26 deletions(-) - ---- a/drivers/staging/media/rpivid/rpivid_h265.c -+++ b/drivers/staging/media/rpivid/rpivid_h265.c -@@ -371,7 +371,8 @@ static void aux_q_free(struct rpivid_ctx - kfree(aq); - } - --static struct rpivid_q_aux *aux_q_alloc(struct rpivid_ctx *const ctx) -+static struct rpivid_q_aux *aux_q_alloc(struct rpivid_ctx *const ctx, -+ const unsigned int q_index) - { - struct rpivid_dev *const dev = ctx->dev; - struct rpivid_q_aux *const aq = kzalloc(sizeof(*aq), GFP_KERNEL); -@@ -379,11 +380,17 @@ static struct rpivid_q_aux *aux_q_alloc( - if (!aq) - return NULL; - -- aq->refcount = 1; - if (gptr_alloc(dev, &aq->col, ctx->colmv_picsize, - DMA_ATTR_FORCE_CONTIGUOUS | DMA_ATTR_NO_KERNEL_MAPPING)) - goto fail; - -+ /* -+ * Spinlock not required as called in P0 only and -+ * aux checks done by _new -+ */ -+ aq->refcount = 1; -+ aq->q_index = q_index; -+ ctx->aux_ents[q_index] = aq; - return aq; - - fail: -@@ -398,22 +405,38 @@ static struct rpivid_q_aux *aux_q_new(st - unsigned long lockflags; - - spin_lock_irqsave(&ctx->aux_lock, lockflags); -- aq = ctx->aux_free; -- if (aq) { -+ /* -+ * If we already have this allocated to a slot then use that -+ * and assume that it will all work itself out in the pipeline -+ */ -+ if ((aq = ctx->aux_ents[q_index]) != NULL) { -+ ++aq->refcount; -+ } else if ((aq = ctx->aux_free) != NULL) { - ctx->aux_free = aq->next; - aq->next = NULL; - aq->refcount = 1; -+ aq->q_index = q_index; -+ ctx->aux_ents[q_index] = aq; - } - spin_unlock_irqrestore(&ctx->aux_lock, lockflags); - -- if (!aq) { -- aq = aux_q_alloc(ctx); -- if (!aq) -- return NULL; -- } -+ if (!aq) -+ aq = aux_q_alloc(ctx, q_index); -+ -+ return aq; -+} -+ -+static struct rpivid_q_aux *aux_q_ref_idx(struct rpivid_ctx *const ctx, -+ const int q_index) -+{ -+ unsigned long lockflags; -+ struct rpivid_q_aux *aq; -+ -+ spin_lock_irqsave(&ctx->aux_lock, lockflags); -+ if ((aq = ctx->aux_ents[q_index]) != NULL) -+ ++aq->refcount; -+ spin_unlock_irqrestore(&ctx->aux_lock, lockflags); - -- aq->q_index = q_index; -- ctx->aux_ents[q_index] = aq; - return aq; - } - -@@ -436,21 +459,21 @@ static void aux_q_release(struct rpivid_ - struct rpivid_q_aux **const paq) - { - struct rpivid_q_aux *const aq = *paq; -- *paq = NULL; -- -- if (aq) { -- unsigned long lockflags; -+ unsigned long lockflags; - -- spin_lock_irqsave(&ctx->aux_lock, lockflags); -+ if (!aq) -+ return; - -- if (--aq->refcount == 0) { -- aq->next = ctx->aux_free; -- ctx->aux_free = aq; -- ctx->aux_ents[aq->q_index] = NULL; -- } -+ *paq = NULL; - -- spin_unlock_irqrestore(&ctx->aux_lock, lockflags); -+ spin_lock_irqsave(&ctx->aux_lock, lockflags); -+ if (--aq->refcount == 0) { -+ aq->next = ctx->aux_free; -+ ctx->aux_free = aq; -+ ctx->aux_ents[aq->q_index] = NULL; -+ aq->q_index = ~0U; - } -+ spin_unlock_irqrestore(&ctx->aux_lock, lockflags); - } - - static void aux_q_init(struct rpivid_ctx *const ctx) -@@ -1958,12 +1981,12 @@ static void rpivid_h265_setup(struct rpi - } - - if (use_aux) { -- dpb_q_aux[i] = aux_q_ref(ctx, -- ctx->aux_ents[buffer_index]); -+ dpb_q_aux[i] = aux_q_ref_idx(ctx, buffer_index); - if (!dpb_q_aux[i]) - v4l2_warn(&dev->v4l2_dev, -- "Missing DPB AUX ent %d index=%d\n", -- i, buffer_index); -+ "Missing DPB AUX ent %d, timestamp=%lld, index=%d\n", -+ i, (long long)sh->dpb[i].timestamp, -+ buffer_index); - } - - de->ref_addrs[i] = diff --git a/target/linux/bcm27xx/patches-5.15/950-0411-media-i2c-ov9281-Remove-override-of-subdev-name.patch b/target/linux/bcm27xx/patches-5.15/950-0411-media-i2c-ov9281-Remove-override-of-subdev-name.patch deleted file mode 100644 index 1cea95129..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0411-media-i2c-ov9281-Remove-override-of-subdev-name.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 48d412bae5e11baee8cadbe89bbc84f9fff2819c Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 28 Jun 2021 10:49:04 +0100 -Subject: [PATCH] media: i2c: ov9281: Remove override of subdev name - -From the original Rockchip driver, the subdev was renamed -from the default to being "mov9281 " whereas the -default would have been "ov9281 ". - -Remove the override to drop back to the default rather than -a vendor custom string. - -Signed-off-by: Dave Stevenson ---- - drivers/media/i2c/ov9281.c | 2 -- - 1 file changed, 2 deletions(-) - ---- a/drivers/media/i2c/ov9281.c -+++ b/drivers/media/i2c/ov9281.c -@@ -1197,8 +1197,6 @@ static int ov9281_probe(struct i2c_clien - if (ret < 0) - goto err_power_off; - -- snprintf(sd->name, sizeof(sd->name), "m%s %s", -- OV9281_NAME, dev_name(sd->dev)); - ret = v4l2_async_register_subdev_sensor(sd); - if (ret) { - dev_err(dev, "v4l2 async register subdev failed\n"); diff --git a/target/linux/bcm27xx/patches-5.15/950-0414-media-i2c-imx477-Extend-driver-to-support-imx378-sen.patch b/target/linux/bcm27xx/patches-5.15/950-0414-media-i2c-imx477-Extend-driver-to-support-imx378-sen.patch deleted file mode 100644 index 3cd1ff6b1..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0414-media-i2c-imx477-Extend-driver-to-support-imx378-sen.patch +++ /dev/null @@ -1,190 +0,0 @@ -From 99a58cae54a24652ab2e088d0eec2a1a31b22d86 Mon Sep 17 00:00:00 2001 -From: David Plowman -Date: Tue, 29 Jun 2021 14:43:01 +0100 -Subject: [PATCH] media: i2c: imx477: Extend driver to support imx378 - sensor - -The imx378 sensor is almost identical to the imx477 and can be -supported as a "compatible" sensor with just a few extra register -writes. - -Signed-off-by: David Plowman ---- - drivers/media/i2c/Kconfig | 2 +- - drivers/media/i2c/imx477.c | 68 +++++++++++++++++++++++++++++++++----- - 2 files changed, 60 insertions(+), 10 deletions(-) - ---- a/drivers/media/i2c/Kconfig -+++ b/drivers/media/i2c/Kconfig -@@ -823,7 +823,7 @@ config VIDEO_IMX477 - depends on MEDIA_CAMERA_SUPPORT - help - This is a Video4Linux2 sensor driver for the Sony -- IMX477 camera. -+ IMX477 camera. Also supports the Sony IMX378. - - To compile this driver as a module, choose M here: the - module will be called imx477. ---- a/drivers/media/i2c/imx477.c -+++ b/drivers/media/i2c/imx477.c -@@ -12,6 +12,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -26,6 +27,7 @@ - /* Chip ID */ - #define IMX477_REG_CHIP_ID 0x0016 - #define IMX477_CHIP_ID 0x0477 -+#define IMX378_CHIP_ID 0x0378 - - #define IMX477_REG_MODE_SELECT 0x0100 - #define IMX477_MODE_STANDBY 0x00 -@@ -1069,6 +1071,11 @@ static const char * const imx477_supply_ - #define IMX477_XCLR_MIN_DELAY_US 8000 - #define IMX477_XCLR_DELAY_RANGE_US 1000 - -+struct imx477_compatible_data { -+ unsigned int chip_id; -+ struct imx477_reg_list extra_regs; -+}; -+ - struct imx477 { - struct v4l2_subdev sd; - struct media_pad pad[NUM_PADS]; -@@ -1107,6 +1114,9 @@ struct imx477 { - - /* Current long exposure factor in use. Set through V4L2_CID_VBLANK */ - unsigned int long_exp_shift; -+ -+ /* Any extra information related to different compatible sensors */ -+ const struct imx477_compatible_data *compatible_data; - }; - - static inline struct imx477 *to_imx477(struct v4l2_subdev *_sd) -@@ -1673,11 +1683,18 @@ static int imx477_start_streaming(struct - { - struct i2c_client *client = v4l2_get_subdevdata(&imx477->sd); - const struct imx477_reg_list *reg_list; -+ const struct imx477_reg_list *extra_regs; - int ret; - - if (!imx477->common_regs_written) { - ret = imx477_write_regs(imx477, mode_common_regs, - ARRAY_SIZE(mode_common_regs)); -+ if (!ret) { -+ extra_regs = &imx477->compatible_data->extra_regs; -+ ret = imx477_write_regs(imx477, extra_regs->regs, -+ extra_regs->num_of_regs); -+ } -+ - if (ret) { - dev_err(&client->dev, "%s failed to set common settings\n", - __func__); -@@ -1863,7 +1880,7 @@ static int imx477_get_regulators(struct - } - - /* Verify chip ID */ --static int imx477_identify_module(struct imx477 *imx477) -+static int imx477_identify_module(struct imx477 *imx477, u32 expected_id) - { - struct i2c_client *client = v4l2_get_subdevdata(&imx477->sd); - int ret; -@@ -1873,16 +1890,18 @@ static int imx477_identify_module(struct - IMX477_REG_VALUE_16BIT, &val); - if (ret) { - dev_err(&client->dev, "failed to read chip id %x, with error %d\n", -- IMX477_CHIP_ID, ret); -+ expected_id, ret); - return ret; - } - -- if (val != IMX477_CHIP_ID) { -+ if (val != expected_id) { - dev_err(&client->dev, "chip id mismatch: %x!=%x\n", -- IMX477_CHIP_ID, val); -+ expected_id, val); - return -EIO; - } - -+ dev_info(&client->dev, "Device found is imx%x\n", val); -+ - return 0; - } - -@@ -2078,10 +2097,39 @@ error_out: - return ret; - } - -+static const struct imx477_compatible_data imx477_compatible = { -+ .chip_id = IMX477_CHIP_ID, -+ .extra_regs = { -+ .num_of_regs = 0, -+ .regs = NULL -+ } -+}; -+ -+static const struct imx477_reg imx378_regs[] = { -+ {0x3e35, 0x01}, -+ {0x4421, 0x08}, -+ {0x3ff9, 0x00}, -+}; -+ -+static const struct imx477_compatible_data imx378_compatible = { -+ .chip_id = IMX378_CHIP_ID, -+ .extra_regs = { -+ .num_of_regs = ARRAY_SIZE(imx378_regs), -+ .regs = imx378_regs -+ } -+}; -+ -+static const struct of_device_id imx477_dt_ids[] = { -+ { .compatible = "sony,imx477", .data = &imx477_compatible }, -+ { .compatible = "sony,imx378", .data = &imx378_compatible }, -+ { /* sentinel */ } -+}; -+ - static int imx477_probe(struct i2c_client *client) - { - struct device *dev = &client->dev; - struct imx477 *imx477; -+ const struct of_device_id *match; - int ret; - - imx477 = devm_kzalloc(&client->dev, sizeof(*imx477), GFP_KERNEL); -@@ -2090,6 +2138,12 @@ static int imx477_probe(struct i2c_clien - - v4l2_i2c_subdev_init(&imx477->sd, client, &imx477_subdev_ops); - -+ match = of_match_device(imx477_dt_ids, dev); -+ if (!match) -+ return -ENODEV; -+ imx477->compatible_data = -+ (const struct imx477_compatible_data *)match->data; -+ - /* Check the hardware configuration in device tree */ - if (imx477_check_hwcfg(dev)) - return -EINVAL; -@@ -2126,7 +2180,7 @@ static int imx477_probe(struct i2c_clien - if (ret) - return ret; - -- ret = imx477_identify_module(imx477); -+ ret = imx477_identify_module(imx477, imx477->compatible_data->chip_id); - if (ret) - goto error_power_off; - -@@ -2198,10 +2252,6 @@ static int imx477_remove(struct i2c_clie - return 0; - } - --static const struct of_device_id imx477_dt_ids[] = { -- { .compatible = "sony,imx477" }, -- { /* sentinel */ } --}; - MODULE_DEVICE_TABLE(of, imx477_dt_ids); - - static const struct dev_pm_ops imx477_pm_ops = { diff --git a/target/linux/bcm27xx/patches-5.15/950-0415-dt-bindings-clk-raspberrypi-Remove-unused-property.patch b/target/linux/bcm27xx/patches-5.15/950-0415-dt-bindings-clk-raspberrypi-Remove-unused-property.patch deleted file mode 100644 index 7d53b5737..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0415-dt-bindings-clk-raspberrypi-Remove-unused-property.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 4b7d33bb45d2f71ae46bfa3af02a3c8610ad3881 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Wed, 23 Jun 2021 11:47:38 +0200 -Subject: [PATCH] dt-bindings: clk: raspberrypi: Remove unused property - -The raspberrypi,firmware property has been documented as required in the -binding but was never actually used in the final version of the binding. -Remove it. - -Signed-off-by: Maxime Ripard ---- - .../bindings/clock/raspberrypi,firmware-clocks.yaml | 7 ------- - 1 file changed, 7 deletions(-) - ---- a/Documentation/devicetree/bindings/clock/raspberrypi,firmware-clocks.yaml -+++ b/Documentation/devicetree/bindings/clock/raspberrypi,firmware-clocks.yaml -@@ -16,15 +16,9 @@ properties: - compatible: - const: raspberrypi,firmware-clocks - -- raspberrypi,firmware: -- $ref: /schemas/types.yaml#/definitions/phandle -- description: > -- Phandle to the mailbox node to communicate with the firmware. -- - required: - - "#clock-cells" - - compatible -- - raspberrypi,firmware - - additionalProperties: false - -@@ -32,7 +26,6 @@ examples: - - | - firmware_clocks: firmware-clocks { - compatible = "raspberrypi,firmware-clocks"; -- raspberrypi,firmware = <&firmware>; - #clock-cells = <1>; - }; - diff --git a/target/linux/bcm27xx/patches-5.15/950-0416-dt-bindings-display-vc4-Add-phandle-to-the-firmware.patch b/target/linux/bcm27xx/patches-5.15/950-0416-dt-bindings-display-vc4-Add-phandle-to-the-firmware.patch deleted file mode 100644 index 478056d86..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0416-dt-bindings-display-vc4-Add-phandle-to-the-firmware.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 895b50c0855bf5c19525249c388a4b72bf7b0302 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Wed, 23 Jun 2021 11:48:35 +0200 -Subject: [PATCH] dt-bindings: display: vc4: Add phandle to the - firmware - -The vc4 driver will need to tell the firmware that it takes over the -display for the firmware to free its resources (lower the clock, free -some memory, etc.) - -Let's add an optional phandle to our firmware node. - -Signed-off-by: Maxime Ripard ---- - .../devicetree/bindings/display/brcm,bcm2835-vc4.yaml | 5 +++++ - 1 file changed, 5 insertions(+) - ---- a/Documentation/devicetree/bindings/display/brcm,bcm2835-vc4.yaml -+++ b/Documentation/devicetree/bindings/display/brcm,bcm2835-vc4.yaml -@@ -21,6 +21,11 @@ properties: - - brcm,bcm2835-vc4 - - brcm,cygnus-vc4 - -+ raspberrypi,firmware: -+ $ref: /schemas/types.yaml#/definitions/phandle -+ description: > -+ Phandle to the mailbox node to communicate with the firmware. -+ - required: - - compatible - diff --git a/target/linux/bcm27xx/patches-5.15/950-0419-media-v4l2-subdev-add-subdev-wide-state-struct.patch b/target/linux/bcm27xx/patches-5.15/950-0419-media-v4l2-subdev-add-subdev-wide-state-struct.patch deleted file mode 100644 index 30abd463e..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0419-media-v4l2-subdev-add-subdev-wide-state-struct.patch +++ /dev/null @@ -1,477 +0,0 @@ -From c284f9ae98f0c853d93fb7fd3a41e457496fba41 Mon Sep 17 00:00:00 2001 -From: Dom Cobley -Date: Thu, 15 Jul 2021 15:55:22 +0100 -Subject: [PATCH] media: v4l2-subdev: add subdev-wide state struct - -Signed-off-by: Dom Cobley ---- - drivers/media/i2c/imx290.c | 9 +++--- - drivers/media/i2c/imx477.c | 30 ++++++++++--------- - drivers/media/i2c/irs1125.c | 8 ++--- - drivers/media/i2c/ov9281.c | 25 +++++++++------- - .../media/platform/bcm2835/bcm2835-unicam.c | 18 +++++------ - .../platform/rockchip/rkisp1/rkisp1-isp.c | 18 +++++++++++ - .../platform/rockchip/rkisp1/rkisp1-resizer.c | 18 +++++++++++ - .../bcm2835-isp/bcm2835-v4l2-isp.c | 4 +-- - 8 files changed, 86 insertions(+), 44 deletions(-) - ---- a/drivers/media/i2c/imx290.c -+++ b/drivers/media/i2c/imx290.c -@@ -988,12 +988,13 @@ static int imx290_write_current_format(s - } - - static const struct v4l2_rect * --__imx290_get_pad_crop(struct imx290 *imx290, struct v4l2_subdev_pad_config *cfg, -+__imx290_get_pad_crop(struct imx290 *imx290, -+ struct v4l2_subdev_state *sd_state, - unsigned int pad, enum v4l2_subdev_format_whence which) - { - switch (which) { - case V4L2_SUBDEV_FORMAT_TRY: -- return v4l2_subdev_get_try_crop(&imx290->sd, cfg, pad); -+ return v4l2_subdev_get_try_crop(&imx290->sd, sd_state, pad); - case V4L2_SUBDEV_FORMAT_ACTIVE: - return &imx290->current_mode->crop; - } -@@ -1002,7 +1003,7 @@ __imx290_get_pad_crop(struct imx290 *imx - } - - static int imx290_get_selection(struct v4l2_subdev *sd, -- struct v4l2_subdev_pad_config *cfg, -+ struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_selection *sel) - { - switch (sel->target) { -@@ -1010,7 +1011,7 @@ static int imx290_get_selection(struct v - struct imx290 *imx290 = to_imx290(sd); - - mutex_lock(&imx290->lock); -- sel->r = *__imx290_get_pad_crop(imx290, cfg, sel->pad, -+ sel->r = *__imx290_get_pad_crop(imx290, sd_state, sel->pad, - sel->which); - mutex_unlock(&imx290->lock); - ---- a/drivers/media/i2c/imx477.c -+++ b/drivers/media/i2c/imx477.c -@@ -1254,9 +1254,9 @@ static int imx477_open(struct v4l2_subde - { - struct imx477 *imx477 = to_imx477(sd); - struct v4l2_mbus_framefmt *try_fmt_img = -- v4l2_subdev_get_try_format(sd, fh->pad, IMAGE_PAD); -+ v4l2_subdev_get_try_format(sd, fh->state, IMAGE_PAD); - struct v4l2_mbus_framefmt *try_fmt_meta = -- v4l2_subdev_get_try_format(sd, fh->pad, METADATA_PAD); -+ v4l2_subdev_get_try_format(sd, fh->state, METADATA_PAD); - struct v4l2_rect *try_crop; - - mutex_lock(&imx477->mutex); -@@ -1275,7 +1275,7 @@ static int imx477_open(struct v4l2_subde - try_fmt_meta->field = V4L2_FIELD_NONE; - - /* Initialize try_crop */ -- try_crop = v4l2_subdev_get_try_crop(sd, fh->pad, IMAGE_PAD); -+ try_crop = v4l2_subdev_get_try_crop(sd, fh->state, IMAGE_PAD); - try_crop->left = IMX477_PIXEL_ARRAY_LEFT; - try_crop->top = IMX477_PIXEL_ARRAY_TOP; - try_crop->width = IMX477_PIXEL_ARRAY_WIDTH; -@@ -1403,7 +1403,7 @@ static const struct v4l2_ctrl_ops imx477 - }; - - static int imx477_enum_mbus_code(struct v4l2_subdev *sd, -- struct v4l2_subdev_pad_config *cfg, -+ struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_mbus_code_enum *code) - { - struct imx477 *imx477 = to_imx477(sd); -@@ -1428,7 +1428,7 @@ static int imx477_enum_mbus_code(struct - } - - static int imx477_enum_frame_size(struct v4l2_subdev *sd, -- struct v4l2_subdev_pad_config *cfg, -+ struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_frame_size_enum *fse) - { - struct imx477 *imx477 = to_imx477(sd); -@@ -1494,7 +1494,7 @@ static void imx477_update_metadata_pad_f - } - - static int imx477_get_pad_format(struct v4l2_subdev *sd, -- struct v4l2_subdev_pad_config *cfg, -+ struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_format *fmt) - { - struct imx477 *imx477 = to_imx477(sd); -@@ -1506,7 +1506,8 @@ static int imx477_get_pad_format(struct - - if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - struct v4l2_mbus_framefmt *try_fmt = -- v4l2_subdev_get_try_format(&imx477->sd, cfg, fmt->pad); -+ v4l2_subdev_get_try_format(&imx477->sd, sd_state, -+ fmt->pad); - /* update the code which could change due to vflip or hflip: */ - try_fmt->code = fmt->pad == IMAGE_PAD ? - imx477_get_format_code(imx477, try_fmt->code) : -@@ -1574,7 +1575,7 @@ static void imx477_set_framing_limits(st - } - - static int imx477_set_pad_format(struct v4l2_subdev *sd, -- struct v4l2_subdev_pad_config *cfg, -+ struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_format *fmt) - { - struct v4l2_mbus_framefmt *framefmt; -@@ -1603,7 +1604,7 @@ static int imx477_set_pad_format(struct - fmt->format.height); - imx477_update_image_pad_format(imx477, mode, fmt); - if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { -- framefmt = v4l2_subdev_get_try_format(sd, cfg, -+ framefmt = v4l2_subdev_get_try_format(sd, sd_state, - fmt->pad); - *framefmt = fmt->format; - } else { -@@ -1613,7 +1614,7 @@ static int imx477_set_pad_format(struct - } - } else { - if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { -- framefmt = v4l2_subdev_get_try_format(sd, cfg, -+ framefmt = v4l2_subdev_get_try_format(sd, sd_state, - fmt->pad); - *framefmt = fmt->format; - } else { -@@ -1628,12 +1629,13 @@ static int imx477_set_pad_format(struct - } - - static const struct v4l2_rect * --__imx477_get_pad_crop(struct imx477 *imx477, struct v4l2_subdev_pad_config *cfg, -+__imx477_get_pad_crop(struct imx477 *imx477, -+ struct v4l2_subdev_state *sd_state, - unsigned int pad, enum v4l2_subdev_format_whence which) - { - switch (which) { - case V4L2_SUBDEV_FORMAT_TRY: -- return v4l2_subdev_get_try_crop(&imx477->sd, cfg, pad); -+ return v4l2_subdev_get_try_crop(&imx477->sd, sd_state, pad); - case V4L2_SUBDEV_FORMAT_ACTIVE: - return &imx477->mode->crop; - } -@@ -1642,7 +1644,7 @@ __imx477_get_pad_crop(struct imx477 *imx - } - - static int imx477_get_selection(struct v4l2_subdev *sd, -- struct v4l2_subdev_pad_config *cfg, -+ struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_selection *sel) - { - switch (sel->target) { -@@ -1650,7 +1652,7 @@ static int imx477_get_selection(struct v - struct imx477 *imx477 = to_imx477(sd); - - mutex_lock(&imx477->mutex); -- sel->r = *__imx477_get_pad_crop(imx477, cfg, sel->pad, -+ sel->r = *__imx477_get_pad_crop(imx477, sd_state, sel->pad, - sel->which); - mutex_unlock(&imx477->mutex); - ---- a/drivers/media/i2c/irs1125.c -+++ b/drivers/media/i2c/irs1125.c -@@ -562,8 +562,8 @@ static const struct v4l2_subdev_video_op - }; - - static int irs1125_enum_mbus_code(struct v4l2_subdev *sd, -- struct v4l2_subdev_pad_config *cfg, -- struct v4l2_subdev_mbus_code_enum *code) -+ struct v4l2_subdev_state *sd_state, -+ struct v4l2_subdev_mbus_code_enum *code) - { - if (code->index > 0) - return -EINVAL; -@@ -574,7 +574,7 @@ static int irs1125_enum_mbus_code(struct - } - - static int irs1125_set_get_fmt(struct v4l2_subdev *sd, -- struct v4l2_subdev_pad_config *cfg, -+ struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_format *format) - { - struct v4l2_mbus_framefmt *fmt = &format->format; -@@ -930,7 +930,7 @@ static int irs1125_detect(struct v4l2_su - static int irs1125_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) - { - struct v4l2_mbus_framefmt *format = -- v4l2_subdev_get_try_format(sd, fh->pad, 0); -+ v4l2_subdev_get_try_format(sd, fh->state, 0); - - format->code = MEDIA_BUS_FMT_Y12_1X12; - format->width = IRS1125_WINDOW_WIDTH_DEF; ---- a/drivers/media/i2c/ov9281.c -+++ b/drivers/media/i2c/ov9281.c -@@ -491,7 +491,7 @@ ov9281_find_best_fit(struct v4l2_subdev_ - } - - static int ov9281_set_fmt(struct v4l2_subdev *sd, -- struct v4l2_subdev_pad_config *cfg, -+ struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_format *fmt) - { - struct ov9281 *ov9281 = to_ov9281(sd); -@@ -516,7 +516,7 @@ static int ov9281_set_fmt(struct v4l2_su - V4L2_MAP_XFER_FUNC_DEFAULT(fmt->format.colorspace); - - if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { -- *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format; -+ *v4l2_subdev_get_try_format(sd, sd_state, fmt->pad) = fmt->format; - } else { - ov9281->cur_mode = mode; - ov9281->code = fmt->format.code; -@@ -542,7 +542,7 @@ static int ov9281_set_fmt(struct v4l2_su - } - - static int ov9281_get_fmt(struct v4l2_subdev *sd, -- struct v4l2_subdev_pad_config *cfg, -+ struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_format *fmt) - { - struct ov9281 *ov9281 = to_ov9281(sd); -@@ -550,7 +550,8 @@ static int ov9281_get_fmt(struct v4l2_su - - mutex_lock(&ov9281->mutex); - if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { -- fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad); -+ fmt->format = *v4l2_subdev_get_try_format(sd, sd_state, -+ fmt->pad); - } else { - fmt->format.width = mode->width; - fmt->format.height = mode->height; -@@ -572,7 +573,7 @@ static int ov9281_get_fmt(struct v4l2_su - } - - static int ov9281_enum_mbus_code(struct v4l2_subdev *sd, -- struct v4l2_subdev_pad_config *cfg, -+ struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_mbus_code_enum *code) - { - switch (code->index) { -@@ -590,7 +591,7 @@ static int ov9281_enum_mbus_code(struct - } - - static int ov9281_enum_frame_sizes(struct v4l2_subdev *sd, -- struct v4l2_subdev_pad_config *cfg, -+ struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_frame_size_enum *fse) - { - if (fse->index >= ARRAY_SIZE(supported_modes)) -@@ -658,12 +659,14 @@ static int ov9281_set_ctrl_vflip(struct - } - - static const struct v4l2_rect * --__ov9281_get_pad_crop(struct ov9281 *ov9281, struct v4l2_subdev_pad_config *cfg, -+__ov9281_get_pad_crop(struct ov9281 *ov9281, -+ struct v4l2_subdev_state *sd_state, - unsigned int pad, enum v4l2_subdev_format_whence which) - { - switch (which) { - case V4L2_SUBDEV_FORMAT_TRY: -- return v4l2_subdev_get_try_crop(&ov9281->subdev, cfg, pad); -+ return v4l2_subdev_get_try_crop(&ov9281->subdev, sd_state, -+ pad); - case V4L2_SUBDEV_FORMAT_ACTIVE: - return &ov9281->cur_mode->crop; - } -@@ -672,7 +675,7 @@ __ov9281_get_pad_crop(struct ov9281 *ov9 - } - - static int ov9281_get_selection(struct v4l2_subdev *sd, -- struct v4l2_subdev_pad_config *cfg, -+ struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_selection *sel) - { - switch (sel->target) { -@@ -680,7 +683,7 @@ static int ov9281_get_selection(struct v - struct ov9281 *ov9281 = to_ov9281(sd); - - mutex_lock(&ov9281->mutex); -- sel->r = *__ov9281_get_pad_crop(ov9281, cfg, sel->pad, -+ sel->r = *__ov9281_get_pad_crop(ov9281, sd_state, sel->pad, - sel->which); - mutex_unlock(&ov9281->mutex); - -@@ -898,7 +901,7 @@ static int ov9281_open(struct v4l2_subde - { - struct ov9281 *ov9281 = to_ov9281(sd); - struct v4l2_mbus_framefmt *try_fmt = -- v4l2_subdev_get_try_format(sd, fh->pad, 0); -+ v4l2_subdev_get_try_format(sd, fh->state, 0); - const struct ov9281_mode *def_mode = &supported_modes[0]; - - mutex_lock(&ov9281->mutex); ---- a/drivers/media/platform/bcm2835/bcm2835-unicam.c -+++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c -@@ -444,7 +444,7 @@ struct unicam_device { - /* ptr to sub device */ - struct v4l2_subdev *sensor; - /* Pad config for the sensor */ -- struct v4l2_subdev_pad_config *sensor_config; -+ struct v4l2_subdev_state *sensor_state; - - enum v4l2_mbus_type bus_type; - /* -@@ -595,7 +595,7 @@ static int __subdev_get_format(struct un - }; - int ret; - -- ret = v4l2_subdev_call(dev->sensor, pad, get_fmt, dev->sensor_config, -+ ret = v4l2_subdev_call(dev->sensor, pad, get_fmt, dev->sensor_state, - &sd_fmt); - if (ret < 0) - return ret; -@@ -619,7 +619,7 @@ static int __subdev_set_format(struct un - - sd_fmt.format = *fmt; - -- ret = v4l2_subdev_call(dev->sensor, pad, set_fmt, dev->sensor_config, -+ ret = v4l2_subdev_call(dev->sensor, pad, set_fmt, dev->sensor_state, - &sd_fmt); - if (ret < 0) - return ret; -@@ -1095,7 +1095,7 @@ static int unicam_try_fmt_vid_cap(struct - */ - mbus_fmt->field = V4L2_FIELD_NONE; - -- ret = v4l2_subdev_call(dev->sensor, pad, set_fmt, dev->sensor_config, -+ ret = v4l2_subdev_call(dev->sensor, pad, set_fmt, dev->sensor_state, - &sd_fmt); - if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) - return ret; -@@ -1117,7 +1117,7 @@ static int unicam_try_fmt_vid_cap(struct - mbus_fmt->code = fmt->code; - - ret = v4l2_subdev_call(dev->sensor, pad, set_fmt, -- dev->sensor_config, &sd_fmt); -+ dev->sensor_state, &sd_fmt); - if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) - return ret; - -@@ -2330,8 +2330,8 @@ static void unicam_release(struct kref * - v4l2_ctrl_handler_free(&unicam->ctrl_handler); - media_device_cleanup(&unicam->mdev); - -- if (unicam->sensor_config) -- v4l2_subdev_free_pad_config(unicam->sensor_config); -+ if (unicam->sensor_state) -+ v4l2_subdev_free_state(unicam->sensor_state); - - kfree(unicam); - } -@@ -2593,8 +2593,8 @@ static int unicam_probe_complete(struct - - unicam->v4l2_dev.notify = unicam_notify; - -- unicam->sensor_config = v4l2_subdev_alloc_pad_config(unicam->sensor); -- if (!unicam->sensor_config) -+ unicam->sensor_state = v4l2_subdev_alloc_state(unicam->sensor); -+ if (!unicam->sensor_state) - return -ENOMEM; - - unicam->sensor_embedded_data = (unicam->sensor->entity.num_pads >= 2); ---- a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c -+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c -@@ -214,6 +214,12 @@ rkisp1_isp_get_pad_fmt(struct rkisp1_isp - struct v4l2_subdev_state state = { - .pads = isp->pad_cfg - }; -+ struct v4l2_subdev_state state = { -+ .pads = &state -+ }; -+ struct v4l2_subdev_state state = { -+ .pads = &state -+ }; - if (which == V4L2_SUBDEV_FORMAT_TRY) - return v4l2_subdev_get_try_format(&isp->sd, sd_state, pad); - else -@@ -228,6 +234,12 @@ rkisp1_isp_get_pad_crop(struct rkisp1_is - struct v4l2_subdev_state state = { - .pads = isp->pad_cfg - }; -+ struct v4l2_subdev_state state = { -+ .pads = &state -+ }; -+ struct v4l2_subdev_state state = { -+ .pads = &state -+ }; - if (which == V4L2_SUBDEV_FORMAT_TRY) - return v4l2_subdev_get_try_crop(&isp->sd, sd_state, pad); - else -@@ -1053,6 +1065,12 @@ int rkisp1_isp_register(struct rkisp1_de - struct v4l2_subdev_state state = { - .pads = rkisp1->isp.pad_cfg - }; -+ struct v4l2_subdev_state state = { -+ .pads = &state -+ }; -+ struct v4l2_subdev_state state = { -+ .pads = &state -+ }; - struct rkisp1_isp *isp = &rkisp1->isp; - struct media_pad *pads = isp->pads; - struct v4l2_subdev *sd = &isp->sd; ---- a/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c -+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c -@@ -186,6 +186,12 @@ rkisp1_rsz_get_pad_fmt(struct rkisp1_res - struct v4l2_subdev_state state = { - .pads = rsz->pad_cfg - }; -+ struct v4l2_subdev_state state = { -+ .pads = &state -+ }; -+ struct v4l2_subdev_state state = { -+ .pads = &state -+ }; - if (which == V4L2_SUBDEV_FORMAT_TRY) - return v4l2_subdev_get_try_format(&rsz->sd, sd_state, pad); - else -@@ -200,6 +206,12 @@ rkisp1_rsz_get_pad_crop(struct rkisp1_re - struct v4l2_subdev_state state = { - .pads = rsz->pad_cfg - }; -+ struct v4l2_subdev_state state = { -+ .pads = &state -+ }; -+ struct v4l2_subdev_state state = { -+ .pads = &state -+ }; - if (which == V4L2_SUBDEV_FORMAT_TRY) - return v4l2_subdev_get_try_crop(&rsz->sd, sd_state, pad); - else -@@ -795,6 +807,12 @@ static int rkisp1_rsz_register(struct rk - struct v4l2_subdev_state state = { - .pads = rsz->pad_cfg - }; -+ struct v4l2_subdev_state state = { -+ .pads = &state -+ }; -+ struct v4l2_subdev_state state = { -+ .pads = &state -+ }; - static const char * const dev_names[] = { - RKISP1_RSZ_MP_DEV_NAME, - RKISP1_RSZ_SP_DEV_NAME ---- a/drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c -+++ b/drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c -@@ -1463,7 +1463,7 @@ queue_cleanup: - } - - /* Unregister one of the /dev/video nodes associated with the ISP. */ --static void unregister_node(struct bcm2835_isp_node *node) -+static void bcm2835_unregister_node(struct bcm2835_isp_node *node) - { - struct bcm2835_isp_dev *dev = node_get_dev(node); - -@@ -1666,7 +1666,7 @@ static int bcm2835_isp_remove(struct pla - media_controller_unregister(dev); - - for (i = 0; i < BCM2835_ISP_NUM_NODES; i++) -- unregister_node(&dev->node[i]); -+ bcm2835_unregister_node(&dev->node[i]); - - v4l2_device_unregister(&dev->v4l2_dev); - diff --git a/target/linux/bcm27xx/patches-5.15/950-0422-drm-vc4-plane-Add-support-for-DRM_FORMAT_P030.patch b/target/linux/bcm27xx/patches-5.15/950-0422-drm-vc4-plane-Add-support-for-DRM_FORMAT_P030.patch deleted file mode 100644 index 43da4fad4..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0422-drm-vc4-plane-Add-support-for-DRM_FORMAT_P030.patch +++ /dev/null @@ -1,216 +0,0 @@ -From fd317c55c0a5d9f8950b49d1efe32166a378cb26 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Wed, 15 Dec 2021 10:17:38 +0100 -Subject: [PATCH] drm/vc4: plane: Add support for DRM_FORMAT_P030 - -The P030 format, used with the DRM_FORMAT_MOD_BROADCOM_SAND128 modifier, -is a format output by the video decoder on the BCM2711. - -Add native support to the KMS planes for that format. - -Signed-off-by: Dave Stevenson -Signed-off-by: Maxime Ripard -Acked-by: Thomas Zimmermann -Link: https://lore.kernel.org/r/20211215091739.135042-3-maxime@cerno.tech ---- - drivers/gpu/drm/vc4/vc4_plane.c | 127 ++++++++++++++++++++++++-------- - 1 file changed, 96 insertions(+), 31 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_plane.c -+++ b/drivers/gpu/drm/vc4/vc4_plane.c -@@ -33,6 +33,7 @@ static const struct hvs_format { - u32 hvs; /* HVS_FORMAT_* */ - u32 pixel_order; - u32 pixel_order_hvs5; -+ bool hvs5_only; - } hvs_formats[] = { - { - .drm = DRM_FORMAT_XRGB8888, -@@ -130,6 +131,12 @@ static const struct hvs_format { - .hvs = HVS_PIXEL_FORMAT_YCBCR_YUV422_2PLANE, - .pixel_order = HVS_PIXEL_ORDER_XYCRCB, - }, -+ { -+ .drm = DRM_FORMAT_P030, -+ .hvs = HVS_PIXEL_FORMAT_YCBCR_10BIT, -+ .pixel_order = HVS_PIXEL_ORDER_XYCBCR, -+ .hvs5_only = true, -+ }, - }; - - static const struct hvs_format *vc4_get_hvs_format(u32 drm_format) -@@ -760,47 +767,90 @@ static int vc4_plane_mode_set(struct drm - case DRM_FORMAT_MOD_BROADCOM_SAND128: - case DRM_FORMAT_MOD_BROADCOM_SAND256: { - uint32_t param = fourcc_mod_broadcom_param(fb->modifier); -- u32 tile_w, tile, x_off, pix_per_tile; -- -- hvs_format = HVS_PIXEL_FORMAT_H264; -- -- switch (base_format_mod) { -- case DRM_FORMAT_MOD_BROADCOM_SAND64: -- tiling = SCALER_CTL0_TILING_64B; -- tile_w = 64; -- break; -- case DRM_FORMAT_MOD_BROADCOM_SAND128: -- tiling = SCALER_CTL0_TILING_128B; -- tile_w = 128; -- break; -- case DRM_FORMAT_MOD_BROADCOM_SAND256: -- tiling = SCALER_CTL0_TILING_256B_OR_T; -- tile_w = 256; -- break; -- default: -- break; -- } - - if (param > SCALER_TILE_HEIGHT_MASK) { -- DRM_DEBUG_KMS("SAND height too large (%d)\n", param); -+ DRM_DEBUG_KMS("SAND height too large (%d)\n", -+ param); - return -EINVAL; - } - -- pix_per_tile = tile_w / fb->format->cpp[0]; -- tile = vc4_state->src_x / pix_per_tile; -- x_off = vc4_state->src_x % pix_per_tile; -+ if (fb->format->format == DRM_FORMAT_P030) { -+ hvs_format = HVS_PIXEL_FORMAT_YCBCR_10BIT; -+ tiling = SCALER_CTL0_TILING_128B; -+ } else { -+ hvs_format = HVS_PIXEL_FORMAT_H264; -+ -+ switch (base_format_mod) { -+ case DRM_FORMAT_MOD_BROADCOM_SAND64: -+ tiling = SCALER_CTL0_TILING_64B; -+ break; -+ case DRM_FORMAT_MOD_BROADCOM_SAND128: -+ tiling = SCALER_CTL0_TILING_128B; -+ break; -+ case DRM_FORMAT_MOD_BROADCOM_SAND256: -+ tiling = SCALER_CTL0_TILING_256B_OR_T; -+ break; -+ default: -+ return -EINVAL; -+ } -+ } - - /* Adjust the base pointer to the first pixel to be scanned - * out. -+ * -+ * For P030, y_ptr [31:4] is the 128bit word for the start pixel -+ * y_ptr [3:0] is the pixel (0-11) contained within that 128bit -+ * word that should be taken as the first pixel. -+ * Ditto uv_ptr [31:4] vs [3:0], however [3:0] contains the -+ * element within the 128bit word, eg for pixel 3 the value -+ * should be 6. - */ - for (i = 0; i < num_planes; i++) { -+ u32 tile_w, tile, x_off, pix_per_tile; -+ -+ if (fb->format->format == DRM_FORMAT_P030) { -+ /* -+ * Spec says: bits [31:4] of the given address -+ * should point to the 128-bit word containing -+ * the desired starting pixel, and bits[3:0] -+ * should be between 0 and 11, indicating which -+ * of the 12-pixels in that 128-bit word is the -+ * first pixel to be used -+ */ -+ u32 remaining_pixels = vc4_state->src_x % 96; -+ u32 aligned = remaining_pixels / 12; -+ u32 last_bits = remaining_pixels % 12; -+ -+ x_off = aligned * 16 + last_bits; -+ tile_w = 128; -+ pix_per_tile = 96; -+ } else { -+ switch (base_format_mod) { -+ case DRM_FORMAT_MOD_BROADCOM_SAND64: -+ tile_w = 64; -+ break; -+ case DRM_FORMAT_MOD_BROADCOM_SAND128: -+ tile_w = 128; -+ break; -+ case DRM_FORMAT_MOD_BROADCOM_SAND256: -+ tile_w = 256; -+ break; -+ default: -+ return -EINVAL; -+ } -+ pix_per_tile = tile_w / fb->format->cpp[0]; -+ x_off = (vc4_state->src_x % pix_per_tile) / -+ (i ? h_subsample : 1) * -+ fb->format->cpp[i]; -+ } -+ -+ tile = vc4_state->src_x / pix_per_tile; -+ - vc4_state->offsets[i] += param * tile_w * tile; - vc4_state->offsets[i] += src_y / - (i ? v_subsample : 1) * - tile_w; -- vc4_state->offsets[i] += x_off / -- (i ? h_subsample : 1) * -- fb->format->cpp[i]; -+ vc4_state->offsets[i] += x_off & ~(i ? 1 : 0); - } - - pitch0 = VC4_SET_FIELD(param, SCALER_TILE_HEIGHT); -@@ -953,7 +1003,8 @@ static int vc4_plane_mode_set(struct drm - - /* Pitch word 1/2 */ - for (i = 1; i < num_planes; i++) { -- if (hvs_format != HVS_PIXEL_FORMAT_H264) { -+ if (hvs_format != HVS_PIXEL_FORMAT_H264 && -+ hvs_format != HVS_PIXEL_FORMAT_YCBCR_10BIT) { - vc4_dlist_write(vc4_state, - VC4_SET_FIELD(fb->pitches[i], - SCALER_SRC_PITCH)); -@@ -1313,6 +1364,13 @@ static bool vc4_format_mod_supported(str - default: - return false; - } -+ case DRM_FORMAT_P030: -+ switch (fourcc_mod_broadcom_mod(modifier)) { -+ case DRM_FORMAT_MOD_BROADCOM_SAND128: -+ return true; -+ default: -+ return false; -+ } - case DRM_FORMAT_RGBX1010102: - case DRM_FORMAT_BGRX1010102: - case DRM_FORMAT_RGBA1010102: -@@ -1345,8 +1403,11 @@ struct drm_plane *vc4_plane_init(struct - struct drm_plane *plane = NULL; - struct vc4_plane *vc4_plane; - u32 formats[ARRAY_SIZE(hvs_formats)]; -+ int num_formats = 0; - int ret = 0; - unsigned i; -+ bool hvs5 = of_device_is_compatible(dev->dev->of_node, -+ "brcm,bcm2711-vc5"); - static const uint64_t modifiers[] = { - DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED, - DRM_FORMAT_MOD_BROADCOM_SAND128, -@@ -1361,13 +1422,17 @@ struct drm_plane *vc4_plane_init(struct - if (!vc4_plane) - return ERR_PTR(-ENOMEM); - -- for (i = 0; i < ARRAY_SIZE(hvs_formats); i++) -- formats[i] = hvs_formats[i].drm; -+ for (i = 0; i < ARRAY_SIZE(hvs_formats); i++) { -+ if (!hvs_formats[i].hvs5_only || hvs5) { -+ formats[num_formats] = hvs_formats[i].drm; -+ num_formats++; -+ } -+ } - - plane = &vc4_plane->base; - ret = drm_universal_plane_init(dev, plane, 0, - &vc4_plane_funcs, -- formats, ARRAY_SIZE(formats), -+ formats, num_formats, - modifiers, type, NULL); - if (ret) - return ERR_PTR(ret); diff --git a/target/linux/bcm27xx/patches-5.15/950-0423-drm-vc4-plane-Add-support-for-YUV-color-encodings-an.patch b/target/linux/bcm27xx/patches-5.15/950-0423-drm-vc4-plane-Add-support-for-YUV-color-encodings-an.patch deleted file mode 100644 index d230566e6..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0423-drm-vc4-plane-Add-support-for-YUV-color-encodings-an.patch +++ /dev/null @@ -1,158 +0,0 @@ -From 81fe25670ae332380379026469c272e5d466c4cb Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Wed, 15 Dec 2021 10:17:39 +0100 -Subject: [PATCH] drm/vc4: plane: Add support for YUV color encodings - and ranges - -The BT601/BT709 color encoding and limited vs full -range properties were not being exposed, defaulting -always to BT601 limited range. - -Expose the parameters and set the registers appropriately. - -Signed-off-by: Dave Stevenson -Signed-off-by: Maxime Ripard -Acked-by: Thomas Zimmermann -Link: https://lore.kernel.org/r/20211215091739.135042-4-maxime@cerno.tech ---- - drivers/gpu/drm/vc4/vc4_plane.c | 71 +++++++++++++++++++++++++++++++-- - drivers/gpu/drm/vc4/vc4_regs.h | 19 ++++++--- - 2 files changed, 82 insertions(+), 8 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_plane.c -+++ b/drivers/gpu/drm/vc4/vc4_plane.c -@@ -621,6 +621,51 @@ static int vc4_plane_allocate_lbm(struct - return 0; - } - -+/* -+ * The colorspace conversion matrices are held in 3 entries in the dlist. -+ * Create an array of them, with entries for each full and limited mode, and -+ * each supported colorspace. -+ */ -+static const u32 colorspace_coeffs[2][DRM_COLOR_ENCODING_MAX][3] = { -+ { -+ /* Limited range */ -+ { -+ /* BT601 */ -+ SCALER_CSC0_ITR_R_601_5, -+ SCALER_CSC1_ITR_R_601_5, -+ SCALER_CSC2_ITR_R_601_5, -+ }, { -+ /* BT709 */ -+ SCALER_CSC0_ITR_R_709_3, -+ SCALER_CSC1_ITR_R_709_3, -+ SCALER_CSC2_ITR_R_709_3, -+ }, { -+ /* BT2020 */ -+ SCALER_CSC0_ITR_R_2020, -+ SCALER_CSC1_ITR_R_2020, -+ SCALER_CSC2_ITR_R_2020, -+ } -+ }, { -+ /* Full range */ -+ { -+ /* JFIF */ -+ SCALER_CSC0_JPEG_JFIF, -+ SCALER_CSC1_JPEG_JFIF, -+ SCALER_CSC2_JPEG_JFIF, -+ }, { -+ /* BT709 */ -+ SCALER_CSC0_ITR_R_709_3_FR, -+ SCALER_CSC1_ITR_R_709_3_FR, -+ SCALER_CSC2_ITR_R_709_3_FR, -+ }, { -+ /* BT2020 */ -+ SCALER_CSC0_ITR_R_2020_FR, -+ SCALER_CSC1_ITR_R_2020_FR, -+ SCALER_CSC2_ITR_R_2020_FR, -+ } -+ } -+}; -+ - /* Writes out a full display list for an active plane to the plane's - * private dlist state. - */ -@@ -1015,9 +1060,20 @@ static int vc4_plane_mode_set(struct drm - - /* Colorspace conversion words */ - if (vc4_state->is_yuv) { -- vc4_dlist_write(vc4_state, SCALER_CSC0_ITR_R_601_5); -- vc4_dlist_write(vc4_state, SCALER_CSC1_ITR_R_601_5); -- vc4_dlist_write(vc4_state, SCALER_CSC2_ITR_R_601_5); -+ enum drm_color_encoding color_encoding = state->color_encoding; -+ enum drm_color_range color_range = state->color_range; -+ const u32 *ccm; -+ -+ if (color_encoding >= DRM_COLOR_ENCODING_MAX) -+ color_encoding = DRM_COLOR_YCBCR_BT601; -+ if (color_range >= DRM_COLOR_RANGE_MAX) -+ color_range = DRM_COLOR_YCBCR_LIMITED_RANGE; -+ -+ ccm = colorspace_coeffs[color_range][color_encoding]; -+ -+ vc4_dlist_write(vc4_state, ccm[0]); -+ vc4_dlist_write(vc4_state, ccm[1]); -+ vc4_dlist_write(vc4_state, ccm[2]); - } - - vc4_state->lbm_offset = 0; -@@ -1446,6 +1502,15 @@ struct drm_plane *vc4_plane_init(struct - DRM_MODE_REFLECT_X | - DRM_MODE_REFLECT_Y); - -+ drm_plane_create_color_properties(plane, -+ BIT(DRM_COLOR_YCBCR_BT601) | -+ BIT(DRM_COLOR_YCBCR_BT709) | -+ BIT(DRM_COLOR_YCBCR_BT2020), -+ BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) | -+ BIT(DRM_COLOR_YCBCR_FULL_RANGE), -+ DRM_COLOR_YCBCR_BT709, -+ DRM_COLOR_YCBCR_LIMITED_RANGE); -+ - return plane; - } - ---- a/drivers/gpu/drm/vc4/vc4_regs.h -+++ b/drivers/gpu/drm/vc4/vc4_regs.h -@@ -989,7 +989,10 @@ enum hvs_pixel_format { - #define SCALER_CSC0_COEF_CR_OFS_SHIFT 0 - #define SCALER_CSC0_ITR_R_601_5 0x00f00000 - #define SCALER_CSC0_ITR_R_709_3 0x00f00000 -+#define SCALER_CSC0_ITR_R_2020 0x00f00000 - #define SCALER_CSC0_JPEG_JFIF 0x00000000 -+#define SCALER_CSC0_ITR_R_709_3_FR 0x00000000 -+#define SCALER_CSC0_ITR_R_2020_FR 0x00000000 - - /* S2.8 contribution of Cb to Green */ - #define SCALER_CSC1_COEF_CB_GRN_MASK VC4_MASK(31, 22) -@@ -1004,8 +1007,11 @@ enum hvs_pixel_format { - #define SCALER_CSC1_COEF_CR_BLU_MASK VC4_MASK(1, 0) - #define SCALER_CSC1_COEF_CR_BLU_SHIFT 0 - #define SCALER_CSC1_ITR_R_601_5 0xe73304a8 --#define SCALER_CSC1_ITR_R_709_3 0xf2b784a8 --#define SCALER_CSC1_JPEG_JFIF 0xea34a400 -+#define SCALER_CSC1_ITR_R_709_3 0xf27784a8 -+#define SCALER_CSC1_ITR_R_2020 0xf43594a8 -+#define SCALER_CSC1_JPEG_JFIF 0xea349400 -+#define SCALER_CSC1_ITR_R_709_3_FR 0xf4388400 -+#define SCALER_CSC1_ITR_R_2020_FR 0xf5b6d400 - - /* S2.8 contribution of Cb to Red */ - #define SCALER_CSC2_COEF_CB_RED_MASK VC4_MASK(29, 20) -@@ -1016,9 +1022,12 @@ enum hvs_pixel_format { - /* S2.8 contribution of Cb to Blue */ - #define SCALER_CSC2_COEF_CB_BLU_MASK VC4_MASK(19, 10) - #define SCALER_CSC2_COEF_CB_BLU_SHIFT 10 --#define SCALER_CSC2_ITR_R_601_5 0x00066204 --#define SCALER_CSC2_ITR_R_709_3 0x00072a1c --#define SCALER_CSC2_JPEG_JFIF 0x000599c5 -+#define SCALER_CSC2_ITR_R_601_5 0x00066604 -+#define SCALER_CSC2_ITR_R_709_3 0x00072e1d -+#define SCALER_CSC2_ITR_R_2020 0x0006b624 -+#define SCALER_CSC2_JPEG_JFIF 0x00059dc6 -+#define SCALER_CSC2_ITR_R_709_3_FR 0x00064ddb -+#define SCALER_CSC2_ITR_R_2020_FR 0x0005e5e2 - - #define SCALER_TPZ0_VERT_RECALC BIT(31) - #define SCALER_TPZ0_SCALE_MASK VC4_MASK(28, 8) diff --git a/target/linux/bcm27xx/patches-5.15/950-0426-drm-vc4-Add-debugfs-node-that-dumps-the-current-disp.patch b/target/linux/bcm27xx/patches-5.15/950-0426-drm-vc4-Add-debugfs-node-that-dumps-the-current-disp.patch deleted file mode 100644 index d7a5dcaff..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0426-drm-vc4-Add-debugfs-node-that-dumps-the-current-disp.patch +++ /dev/null @@ -1,70 +0,0 @@ -From d2391d8e17532da2e4edf69672504cad2ab4bca1 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 6 Oct 2020 18:44:42 +0100 -Subject: [PATCH] drm/vc4: Add debugfs node that dumps the current - display lists - -This allows easy analysis of display lists when debugging. - -Signed-off-by: Dave Stevenson ---- - drivers/gpu/drm/vc4/vc4_hvs.c | 41 +++++++++++++++++++++++++++++++++++ - 1 file changed, 41 insertions(+) - ---- a/drivers/gpu/drm/vc4/vc4_hvs.c -+++ b/drivers/gpu/drm/vc4/vc4_hvs.c -@@ -95,6 +95,45 @@ static int vc4_hvs_debugfs_underrun(stru - return 0; - } - -+static int vc4_hvs_debugfs_dlist(struct seq_file *m, void *data) -+{ -+ struct drm_info_node *node = m->private; -+ struct drm_device *dev = node->minor->dev; -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ struct drm_printer p = drm_seq_file_printer(m); -+ unsigned int next_entry_start = 0; -+ unsigned int i, j; -+ u32 dlist_word, dispstat; -+ -+ for (i = 0; i < SCALER_CHANNELS_COUNT; i++) { -+ dispstat = VC4_GET_FIELD(HVS_READ(SCALER_DISPSTATX(i)), -+ SCALER_DISPSTATX_MODE); -+ if (dispstat == SCALER_DISPSTATX_MODE_DISABLED || -+ dispstat == SCALER_DISPSTATX_MODE_EOF) { -+ drm_printf(&p, "HVS chan %u disabled\n", i); -+ continue; -+ } -+ -+ drm_printf(&p, "HVS chan %u:\n", i); -+ -+ for (j = HVS_READ(SCALER_DISPLISTX(i)); j < 256; j++) { -+ dlist_word = readl((u32 __iomem *)vc4->hvs->dlist + j); -+ drm_printf(&p, "dlist: %02d: 0x%08x\n", j, -+ dlist_word); -+ if (!next_entry_start || -+ next_entry_start == j) { -+ if (dlist_word & SCALER_CTL0_END) -+ break; -+ next_entry_start = j + -+ VC4_GET_FIELD(dlist_word, -+ SCALER_CTL0_SIZE); -+ } -+ } -+ } -+ -+ return 0; -+} -+ - /* The filter kernel is composed of dwords each containing 3 9-bit - * signed integers packed next to each other. - */ -@@ -739,6 +778,8 @@ static int vc4_hvs_bind(struct device *d - vc4_debugfs_add_regset32(drm, "hvs_regs", &hvs->regset); - vc4_debugfs_add_file(drm, "hvs_underrun", vc4_hvs_debugfs_underrun, - NULL); -+ vc4_debugfs_add_file(drm, "hvs_dlists", vc4_hvs_debugfs_dlist, -+ NULL); - - return 0; - } diff --git a/target/linux/bcm27xx/patches-5.15/950-0427-drm-vc4-Add-all-the-HDMI-registers-into-the-debugfs-.patch b/target/linux/bcm27xx/patches-5.15/950-0427-drm-vc4-Add-all-the-HDMI-registers-into-the-debugfs-.patch deleted file mode 100644 index 5ae2b9f48..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0427-drm-vc4-Add-all-the-HDMI-registers-into-the-debugfs-.patch +++ /dev/null @@ -1,95 +0,0 @@ -From b6d1141860db42137660a44a8c1713a33e6e5833 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Wed, 21 Oct 2020 18:34:56 +0100 -Subject: [PATCH] drm/vc4: Add all the HDMI registers into the debugfs - dumps - -The vc5 HDMI registers hadn't been added into the debugfs -register sets, therefore weren't dumped on request. -Add them in. - -Signed-off-by: Dave Stevenson ---- - drivers/gpu/drm/vc4/vc4_hdmi.c | 39 ++++++++++++++++++++++++++++++++++ - drivers/gpu/drm/vc4/vc4_hdmi.h | 8 +++++++ - 2 files changed, 47 insertions(+) - ---- a/drivers/gpu/drm/vc4/vc4_hdmi.c -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c -@@ -116,6 +116,12 @@ static int vc4_hdmi_debugfs_regs(struct - - drm_print_regset32(&p, &vc4_hdmi->hdmi_regset); - drm_print_regset32(&p, &vc4_hdmi->hd_regset); -+ drm_print_regset32(&p, &vc4_hdmi->cec_regset); -+ drm_print_regset32(&p, &vc4_hdmi->csc_regset); -+ drm_print_regset32(&p, &vc4_hdmi->dvp_regset); -+ drm_print_regset32(&p, &vc4_hdmi->phy_regset); -+ drm_print_regset32(&p, &vc4_hdmi->ram_regset); -+ drm_print_regset32(&p, &vc4_hdmi->rm_regset); - - return 0; - } -@@ -2370,6 +2376,7 @@ static int vc5_hdmi_init_resources(struc - struct platform_device *pdev = vc4_hdmi->pdev; - struct device *dev = &pdev->dev; - struct resource *res; -+ int ret; - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hdmi"); - if (!res) -@@ -2466,6 +2473,38 @@ static int vc5_hdmi_init_resources(struc - return PTR_ERR(vc4_hdmi->reset); - } - -+ ret = vc4_hdmi_build_regset(vc4_hdmi, &vc4_hdmi->hdmi_regset, VC4_HDMI); -+ if (ret) -+ return ret; -+ -+ ret = vc4_hdmi_build_regset(vc4_hdmi, &vc4_hdmi->hd_regset, VC4_HD); -+ if (ret) -+ return ret; -+ -+ ret = vc4_hdmi_build_regset(vc4_hdmi, &vc4_hdmi->cec_regset, VC5_CEC); -+ if (ret) -+ return ret; -+ -+ ret = vc4_hdmi_build_regset(vc4_hdmi, &vc4_hdmi->csc_regset, VC5_CSC); -+ if (ret) -+ return ret; -+ -+ ret = vc4_hdmi_build_regset(vc4_hdmi, &vc4_hdmi->dvp_regset, VC5_DVP); -+ if (ret) -+ return ret; -+ -+ ret = vc4_hdmi_build_regset(vc4_hdmi, &vc4_hdmi->phy_regset, VC5_PHY); -+ if (ret) -+ return ret; -+ -+ ret = vc4_hdmi_build_regset(vc4_hdmi, &vc4_hdmi->ram_regset, VC5_RAM); -+ if (ret) -+ return ret; -+ -+ ret = vc4_hdmi_build_regset(vc4_hdmi, &vc4_hdmi->rm_regset, VC5_RM); -+ if (ret) -+ return ret; -+ - return 0; - } - ---- a/drivers/gpu/drm/vc4/vc4_hdmi.h -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.h -@@ -216,6 +216,14 @@ struct vc4_hdmi { - * the scrambler on? Protected by @mutex. - */ - bool scdc_enabled; -+ -+ /* VC5 debugfs regset */ -+ struct debugfs_regset32 cec_regset; -+ struct debugfs_regset32 csc_regset; -+ struct debugfs_regset32 dvp_regset; -+ struct debugfs_regset32 phy_regset; -+ struct debugfs_regset32 ram_regset; -+ struct debugfs_regset32 rm_regset; - }; - - static inline struct vc4_hdmi * diff --git a/target/linux/bcm27xx/patches-5.15/950-0429-vc4_hdmi-Report-that-3d-stereo-is-allowed.patch b/target/linux/bcm27xx/patches-5.15/950-0429-vc4_hdmi-Report-that-3d-stereo-is-allowed.patch deleted file mode 100644 index a2b71b68c..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0429-vc4_hdmi-Report-that-3d-stereo-is-allowed.patch +++ /dev/null @@ -1,20 +0,0 @@ -From cda5446da5bfd175c0c9c78b57e9a6e935f49f0b Mon Sep 17 00:00:00 2001 -From: Dom Cobley -Date: Mon, 9 Nov 2020 19:49:32 +0000 -Subject: [PATCH] vc4_hdmi: Report that 3d/stereo is allowed - -Signed-off-by: Dom Cobley ---- - drivers/gpu/drm/vc4/vc4_hdmi.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/gpu/drm/vc4/vc4_hdmi.c -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c -@@ -402,6 +402,7 @@ static int vc4_hdmi_connector_init(struc - - connector->interlace_allowed = 1; - connector->doublescan_allowed = 0; -+ connector->stereo_allowed = 1; - - if (vc4_hdmi->variant->supports_hdr) - drm_connector_attach_hdr_output_metadata_property(connector); diff --git a/target/linux/bcm27xx/patches-5.15/950-0430-vc4-Clear-unused-infoframe-packet-RAM-registers.patch b/target/linux/bcm27xx/patches-5.15/950-0430-vc4-Clear-unused-infoframe-packet-RAM-registers.patch deleted file mode 100644 index cb5f273fc..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0430-vc4-Clear-unused-infoframe-packet-RAM-registers.patch +++ /dev/null @@ -1,45 +0,0 @@ -From ce3b4ee2f7d315dadd56ba19587b58339e5d6185 Mon Sep 17 00:00:00 2001 -From: Dom Cobley -Date: Tue, 10 Nov 2020 20:04:08 +0000 -Subject: [PATCH] vc4: Clear unused infoframe packet RAM registers - -Using a hdmi analyser the bytes in packet ram -registers beyond the length were visible in the -infoframes and it flagged the checksum as invalid. - -Zeroing unused words of packet RAM avoids this - -Signed-off-by: Dom Cobley ---- - drivers/gpu/drm/vc4/vc4_hdmi.c | 11 ++++++++++- - 1 file changed, 10 insertions(+), 1 deletion(-) - ---- a/drivers/gpu/drm/vc4/vc4_hdmi.c -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c -@@ -440,9 +440,11 @@ static void vc4_hdmi_write_infoframe(str - const struct vc4_hdmi_register *ram_packet_start = - &vc4_hdmi->variant->registers[HDMI_RAM_PACKET_START]; - u32 packet_reg = ram_packet_start->offset + VC4_HDMI_PACKET_STRIDE * packet_id; -+ u32 packet_reg_next = ram_packet_start->offset + -+ VC4_HDMI_PACKET_STRIDE * (packet_id + 1); - void __iomem *base = __vc4_hdmi_get_field_base(vc4_hdmi, - ram_packet_start->reg); -- uint8_t buffer[VC4_HDMI_PACKET_STRIDE]; -+ uint8_t buffer[VC4_HDMI_PACKET_STRIDE] = {}; - unsigned long flags; - ssize_t len, i; - int ret; -@@ -478,6 +480,13 @@ static void vc4_hdmi_write_infoframe(str - packet_reg += 4; - } - -+ /* -+ * clear remainder of packet ram as it's included in the -+ * infoframe and triggers a checksum error on hdmi analyser -+ */ -+ for (; packet_reg < packet_reg_next; packet_reg += 4) -+ writel(0, base + packet_reg); -+ - HDMI_WRITE(HDMI_RAM_PACKET_CONFIG, - HDMI_READ(HDMI_RAM_PACKET_CONFIG) | BIT(packet_id)); - diff --git a/target/linux/bcm27xx/patches-5.15/950-0434-drm-vc4-hdmi-Convert-to-the-new-clock-request-API.patch b/target/linux/bcm27xx/patches-5.15/950-0434-drm-vc4-hdmi-Convert-to-the-new-clock-request-API.patch deleted file mode 100644 index fb11058c5..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0434-drm-vc4-hdmi-Convert-to-the-new-clock-request-API.patch +++ /dev/null @@ -1,42 +0,0 @@ -From e2f73520b94f49c6ef3ae27e6dc899ec855567ab Mon Sep 17 00:00:00 2001 -From: Dom Cobley -Date: Tue, 13 Apr 2021 14:10:03 +0100 -Subject: [PATCH] drm/vc4: hdmi: Convert to the new clock request API - -The new clock request API allows us to increase the rate of the -core clock as required during mode set while decreasing it when -we're done, resulting in a better power-efficiency. - -Signed-off-by: Dom Cobley ---- - drivers/gpu/drm/vc4/vc4_kms.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_kms.c -@@ -345,6 +345,7 @@ static void vc4_atomic_commit_tail(struc - struct drm_crtc *crtc; - struct vc4_hvs_state *old_hvs_state; - unsigned int channel; -+ struct clk_request *core_req; - int i; - - old_hvs_state = vc4_hvs_get_old_global_state(state); -@@ -389,7 +390,7 @@ static void vc4_atomic_commit_tail(struc - 500000000, - new_hvs_state->core_clock_rate); - -- clk_set_min_rate(hvs->core_clk, core_rate); -+ core_req = clk_request_start(hvs->core_clk, core_rate); - } - - drm_atomic_helper_commit_modeset_disables(dev, state); -@@ -417,7 +418,7 @@ static void vc4_atomic_commit_tail(struc - drm_dbg(dev, "Running the core clock at %lu Hz\n", - new_hvs_state->core_clock_rate); - -- clk_set_min_rate(hvs->core_clk, new_hvs_state->core_clock_rate); -+ clk_request_done(core_req); - } - } - diff --git a/target/linux/bcm27xx/patches-5.15/950-0440-clk-Always-clamp-the-rounded-rate.patch b/target/linux/bcm27xx/patches-5.15/950-0440-clk-Always-clamp-the-rounded-rate.patch deleted file mode 100644 index 434c91f01..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0440-clk-Always-clamp-the-rounded-rate.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 5efe54b26d470785883bec0264d8d5e145715038 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Wed, 5 May 2021 15:35:34 +0200 -Subject: [PATCH] clk: Always clamp the rounded rate - -The current core while setting the min and max rate properly in the -clk_request structure will not make sure that the requested rate is -within these boundaries, leaving it to each and every driver to make -sure it is. - -Add a clamp call to make sure it's always done. - -Signed-off-by: Maxime Ripard ---- - drivers/clk/clk.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/clk/clk.c -+++ b/drivers/clk/clk.c -@@ -1346,6 +1346,8 @@ static int clk_core_determine_round_nolo - if (!core) - return 0; - -+ req->rate = clamp(req->rate, req->min_rate, req->max_rate); -+ - /* - * At this point, core protection will be disabled - * - if the provider is not protected at all diff --git a/target/linux/bcm27xx/patches-5.15/950-0441-drm-vc4-Increase-the-core-clock-based-on-HVS-load.patch b/target/linux/bcm27xx/patches-5.15/950-0441-drm-vc4-Increase-the-core-clock-based-on-HVS-load.patch deleted file mode 100644 index b184172f8..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0441-drm-vc4-Increase-the-core-clock-based-on-HVS-load.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 7971426f2462b02ea1bf12d902ca066e07eeb64b Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Wed, 26 May 2021 16:13:02 +0200 -Subject: [PATCH] drm/vc4: Increase the core clock based on HVS load - -Depending on a given HVS output (HVS to PixelValves) and input (planes -attached to a channel) load, the HVS needs for the core clock to be -raised above its boot time default. - -Failing to do so will result in a vblank timeout and a stalled display -pipeline. - -Signed-off-by: Maxime Ripard ---- - drivers/gpu/drm/vc4/vc4_drv.h | 1 + - drivers/gpu/drm/vc4/vc4_kms.c | 13 +++++++++++++ - 2 files changed, 14 insertions(+) - ---- a/drivers/gpu/drm/vc4/vc4_drv.h -+++ b/drivers/gpu/drm/vc4/vc4_drv.h -@@ -321,6 +321,7 @@ struct vc4_hvs { - u32 __iomem *dlist; - - struct clk *core_clk; -+ struct clk_request *core_req; - - /* Memory manager for CRTCs to allocate space in the display - * list. Units are dwords. ---- a/drivers/gpu/drm/vc4/vc4_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_kms.c -@@ -391,6 +391,11 @@ static void vc4_atomic_commit_tail(struc - new_hvs_state->core_clock_rate); - - core_req = clk_request_start(hvs->core_clk, core_rate); -+ /* -+ * And remove the previous one based on the HVS -+ * requirements if any. -+ */ -+ clk_request_done(hvs->core_req); - } - - drm_atomic_helper_commit_modeset_disables(dev, state); -@@ -418,6 +423,14 @@ static void vc4_atomic_commit_tail(struc - drm_dbg(dev, "Running the core clock at %lu Hz\n", - new_hvs_state->core_clock_rate); - -+ /* -+ * Request a clock rate based on the current HVS -+ * requirements. -+ */ -+ hvs->core_req = clk_request_start(hvs->core_clk, -+ new_hvs_state->core_clock_rate); -+ -+ /* And drop the temporary request */ - clk_request_done(core_req); - } - } diff --git a/target/linux/bcm27xx/patches-5.15/950-0442-drm-vc4-hdmi-Simplify-the-connector-state-retrieval.patch b/target/linux/bcm27xx/patches-5.15/950-0442-drm-vc4-hdmi-Simplify-the-connector-state-retrieval.patch deleted file mode 100644 index 01d9daa05..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0442-drm-vc4-hdmi-Simplify-the-connector-state-retrieval.patch +++ /dev/null @@ -1,51 +0,0 @@ -From fbd09981ff7ecefd9514325bdbfa2b4df4b4f017 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Wed, 27 Oct 2021 14:38:50 +0100 -Subject: [PATCH] drm/vc4: hdmi: Simplify the connector state retrieval - -When we have the entire DRM state, retrieving the connector state only -requires the drm_connector pointer. Fortunately for us, we have -allocated it as a part of the vc4_hdmi structure, so we can retrieve get -a pointer by simply accessing our field in that structure. - -Signed-off-by: Maxime Ripard ---- - drivers/gpu/drm/vc4/vc4_hdmi.c | 21 +++------------------ - 1 file changed, 3 insertions(+), 18 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_hdmi.c -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c -@@ -1012,30 +1012,15 @@ static void vc4_hdmi_recenter_fifo(struc - "VC4_HDMI_FIFO_CTL_RECENTER_DONE"); - } - --static struct drm_connector_state * --vc4_hdmi_encoder_get_connector_state(struct drm_encoder *encoder, -- struct drm_atomic_state *state) --{ -- struct drm_connector_state *conn_state; -- struct drm_connector *connector; -- unsigned int i; -- -- for_each_new_connector_in_state(state, connector, conn_state, i) { -- if (conn_state->best_encoder == encoder) -- return conn_state; -- } -- -- return NULL; --} -- - static void vc4_hdmi_encoder_pre_crtc_configure(struct drm_encoder *encoder, - struct drm_atomic_state *state) - { -+ struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); -+ struct drm_connector *connector = &vc4_hdmi->connector; - struct drm_connector_state *conn_state = -- vc4_hdmi_encoder_get_connector_state(encoder, state); -+ drm_atomic_get_new_connector_state(state, connector); - struct vc4_hdmi_connector_state *vc4_conn_state = - conn_state_to_vc4_hdmi_conn_state(conn_state); -- struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); - struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode; - unsigned long pixel_rate = vc4_conn_state->pixel_rate; - unsigned long bvb_rate, hsm_rate; diff --git a/target/linux/bcm27xx/patches-5.15/950-0444-dwc_otg-Update-NetBSD-usb.h-header-licence.patch b/target/linux/bcm27xx/patches-5.15/950-0444-dwc_otg-Update-NetBSD-usb.h-header-licence.patch deleted file mode 100644 index 1b159e12f..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0444-dwc_otg-Update-NetBSD-usb.h-header-licence.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 9d61ad21064f8c084c4b39df3344e0cd1beaf40e Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 5 Jul 2021 19:38:21 +0100 -Subject: [PATCH] dwc_otg: Update NetBSD usb.h header licence - -NetBSD have changed their licensing requirements such that the 2-clause -licence is preferred. Update usb.h in the downstream dwc_otg code -accordingly. - -See https://www.netbsd.org/about/redistribution.html for more -information. - -Signed-off-by: Phil Elwell ---- - drivers/usb/host/dwc_common_port/usb.h | 7 ------- - 1 file changed, 7 deletions(-) - ---- a/drivers/usb/host/dwc_common_port/usb.h -+++ b/drivers/usb/host/dwc_common_port/usb.h -@@ -14,13 +14,6 @@ - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. -- * 3. All advertising materials mentioning features or use of this software -- * must display the following acknowledgement: -- * This product includes software developed by the NetBSD -- * Foundation, Inc. and its contributors. -- * 4. Neither the name of The NetBSD Foundation nor the names of its -- * contributors may be used to endorse or promote products derived -- * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED diff --git a/target/linux/bcm27xx/patches-5.15/950-0447-drm-vc4-Refactor-VEC-TV-mode-setting.patch b/target/linux/bcm27xx/patches-5.15/950-0447-drm-vc4-Refactor-VEC-TV-mode-setting.patch deleted file mode 100644 index 0af549ba5..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0447-drm-vc4-Refactor-VEC-TV-mode-setting.patch +++ /dev/null @@ -1,167 +0,0 @@ -From 723c2a1a51f64c381ab0b5ad662e3411a6bc9fca Mon Sep 17 00:00:00 2001 -From: Mateusz Kwiatkowski -Date: Thu, 15 Jul 2021 01:07:49 +0200 -Subject: [PATCH] drm/vc4: Refactor VEC TV mode setting - -Change the mode_set function pointer logic to declarative config0, -config1 and custom_freq fields, to make TV mode setting logic more -concise and uniform. - -Additionally, remove the superfluous tv_mode field, which was redundant -with the mode field in struct drm_tv_connector_state. - -Signed-off-by: Mateusz Kwiatkowski ---- - drivers/gpu/drm/vc4/vc4_vec.c | 69 +++++++++++------------------------ - 1 file changed, 22 insertions(+), 47 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_vec.c -+++ b/drivers/gpu/drm/vc4/vc4_vec.c -@@ -170,8 +170,6 @@ struct vc4_vec { - - struct clk *clock; - -- const struct vc4_vec_tv_mode *tv_mode; -- - struct debugfs_regset32 regset; - }; - -@@ -211,7 +209,9 @@ enum vc4_vec_tv_mode_id { - - struct vc4_vec_tv_mode { - const struct drm_display_mode *mode; -- void (*mode_set)(struct vc4_vec *vec); -+ u32 config0; -+ u32 config1; -+ u32 custom_freq; - }; - - static const struct debugfs_reg32 vec_regs[] = { -@@ -241,18 +241,6 @@ static const struct debugfs_reg32 vec_re - VC4_REG32(VEC_DAC_MISC), - }; - --static void vc4_vec_ntsc_mode_set(struct vc4_vec *vec) --{ -- VEC_WRITE(VEC_CONFIG0, VEC_CONFIG0_NTSC_STD | VEC_CONFIG0_PDEN); -- VEC_WRITE(VEC_CONFIG1, VEC_CONFIG1_C_CVBS_CVBS); --} -- --static void vc4_vec_ntsc_j_mode_set(struct vc4_vec *vec) --{ -- VEC_WRITE(VEC_CONFIG0, VEC_CONFIG0_NTSC_STD); -- VEC_WRITE(VEC_CONFIG1, VEC_CONFIG1_C_CVBS_CVBS); --} -- - static const struct drm_display_mode ntsc_mode = { - DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 13500, - 720, 720 + 14, 720 + 14 + 64, 720 + 14 + 64 + 60, 0, -@@ -260,21 +248,6 @@ static const struct drm_display_mode nts - DRM_MODE_FLAG_INTERLACE) - }; - --static void vc4_vec_pal_mode_set(struct vc4_vec *vec) --{ -- VEC_WRITE(VEC_CONFIG0, VEC_CONFIG0_PAL_BDGHI_STD); -- VEC_WRITE(VEC_CONFIG1, VEC_CONFIG1_C_CVBS_CVBS); --} -- --static void vc4_vec_pal_m_mode_set(struct vc4_vec *vec) --{ -- VEC_WRITE(VEC_CONFIG0, VEC_CONFIG0_PAL_BDGHI_STD); -- VEC_WRITE(VEC_CONFIG1, -- VEC_CONFIG1_C_CVBS_CVBS | VEC_CONFIG1_CUSTOM_FREQ); -- VEC_WRITE(VEC_FREQ3_2, 0x223b); -- VEC_WRITE(VEC_FREQ1_0, 0x61d1); --} -- - static const struct drm_display_mode pal_mode = { - DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 13500, - 720, 720 + 20, 720 + 20 + 64, 720 + 20 + 64 + 60, 0, -@@ -285,19 +258,24 @@ static const struct drm_display_mode pal - static const struct vc4_vec_tv_mode vc4_vec_tv_modes[] = { - [VC4_VEC_TV_MODE_NTSC] = { - .mode = &ntsc_mode, -- .mode_set = vc4_vec_ntsc_mode_set, -+ .config0 = VEC_CONFIG0_NTSC_STD | VEC_CONFIG0_PDEN, -+ .config1 = VEC_CONFIG1_C_CVBS_CVBS, - }, - [VC4_VEC_TV_MODE_NTSC_J] = { - .mode = &ntsc_mode, -- .mode_set = vc4_vec_ntsc_j_mode_set, -+ .config0 = VEC_CONFIG0_NTSC_STD, -+ .config1 = VEC_CONFIG1_C_CVBS_CVBS, - }, - [VC4_VEC_TV_MODE_PAL] = { - .mode = &pal_mode, -- .mode_set = vc4_vec_pal_mode_set, -+ .config0 = VEC_CONFIG0_PAL_BDGHI_STD, -+ .config1 = VEC_CONFIG1_C_CVBS_CVBS, - }, - [VC4_VEC_TV_MODE_PAL_M] = { - .mode = &pal_mode, -- .mode_set = vc4_vec_pal_m_mode_set, -+ .config0 = VEC_CONFIG0_PAL_BDGHI_STD, -+ .config1 = VEC_CONFIG1_C_CVBS_CVBS | VEC_CONFIG1_CUSTOM_FREQ, -+ .custom_freq = 0x223b61d1, - }, - }; - -@@ -367,7 +345,6 @@ static struct drm_connector *vc4_vec_con - drm_object_attach_property(&connector->base, - dev->mode_config.tv_mode_property, - VC4_VEC_TV_MODE_NTSC); -- vec->tv_mode = &vc4_vec_tv_modes[VC4_VEC_TV_MODE_NTSC]; - - drm_connector_attach_encoder(connector, vec->encoder); - -@@ -400,6 +377,7 @@ static void vc4_vec_encoder_enable(struc - { - struct vc4_vec_encoder *vc4_vec_encoder = to_vc4_vec_encoder(encoder); - struct vc4_vec *vec = vc4_vec_encoder->vec; -+ unsigned int tv_mode = vec->connector->state->tv.mode; - int ret; - - ret = pm_runtime_get_sync(&vec->pdev->dev); -@@ -455,7 +433,15 @@ static void vc4_vec_encoder_enable(struc - /* Mask all interrupts. */ - VEC_WRITE(VEC_MASK0, 0); - -- vec->tv_mode->mode_set(vec); -+ VEC_WRITE(VEC_CONFIG0, vc4_vec_tv_modes[tv_mode].config0); -+ VEC_WRITE(VEC_CONFIG1, vc4_vec_tv_modes[tv_mode].config1); -+ if (vc4_vec_tv_modes[tv_mode].custom_freq != 0) { -+ VEC_WRITE(VEC_FREQ3_2, -+ (vc4_vec_tv_modes[tv_mode].custom_freq >> 16) & -+ 0xffff); -+ VEC_WRITE(VEC_FREQ1_0, -+ vc4_vec_tv_modes[tv_mode].custom_freq & 0xffff); -+ } - - VEC_WRITE(VEC_DAC_MISC, - VEC_DAC_MISC_VID_ACT | VEC_DAC_MISC_DAC_RST_N); -@@ -470,16 +456,6 @@ static bool vc4_vec_encoder_mode_fixup(s - return true; - } - --static void vc4_vec_encoder_atomic_mode_set(struct drm_encoder *encoder, -- struct drm_crtc_state *crtc_state, -- struct drm_connector_state *conn_state) --{ -- struct vc4_vec_encoder *vc4_vec_encoder = to_vc4_vec_encoder(encoder); -- struct vc4_vec *vec = vc4_vec_encoder->vec; -- -- vec->tv_mode = &vc4_vec_tv_modes[conn_state->tv.mode]; --} -- - static int vc4_vec_encoder_atomic_check(struct drm_encoder *encoder, - struct drm_crtc_state *crtc_state, - struct drm_connector_state *conn_state) -@@ -500,7 +476,6 @@ static const struct drm_encoder_helper_f - .enable = vc4_vec_encoder_enable, - .mode_fixup = vc4_vec_encoder_mode_fixup, - .atomic_check = vc4_vec_encoder_atomic_check, -- .atomic_mode_set = vc4_vec_encoder_atomic_mode_set, - }; - - static const struct vc4_vec_variant bcm2835_vec_variant = { diff --git a/target/linux/bcm27xx/patches-5.15/950-0453-media-i2c-imx477-Fix-framerates-for-1332x990-mode.patch b/target/linux/bcm27xx/patches-5.15/950-0453-media-i2c-imx477-Fix-framerates-for-1332x990-mode.patch deleted file mode 100644 index 302518647..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0453-media-i2c-imx477-Fix-framerates-for-1332x990-mode.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 8ad37eff46c48fff0ae0bbdb04fcbc2216c8d2a9 Mon Sep 17 00:00:00 2001 -From: David Plowman -Date: Tue, 20 Jul 2021 15:10:03 +0100 -Subject: [PATCH] media: i2c: imx477: Fix framerates for 1332x990 mode - -The imx477 driver's line length for this mode had not been updated to -the value supplied to us by the sensor manufacturer. With this -correction the sensor delivers the framerates that are expected. - -Signed-off-by: David Plowman ---- - drivers/media/i2c/imx477.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/media/i2c/imx477.c -+++ b/drivers/media/i2c/imx477.c -@@ -982,7 +982,7 @@ static const struct imx477_mode supporte - /* 120fps. 2x2 binned and cropped */ - .width = 1332, - .height = 990, -- .line_length_pix = 0x1460, -+ .line_length_pix = 6664, - .crop = { - /* - * FIXME: the analog crop rectangle is actually diff --git a/target/linux/bcm27xx/patches-5.15/950-0454-ASoC-bcm-Compiler-warnings-in-audioinjector-octo.patch b/target/linux/bcm27xx/patches-5.15/950-0454-ASoC-bcm-Compiler-warnings-in-audioinjector-octo.patch deleted file mode 100644 index 1d3aa8b7f..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0454-ASoC-bcm-Compiler-warnings-in-audioinjector-octo.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 19d40913d12d4e837022003eca8b5a8c7565b8e6 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 27 Jul 2021 09:27:49 +0100 -Subject: [PATCH] ASoC: bcm: Compiler warnings in audioinjector-octo - -Avoid compiler warnings by using the "fallthrough" pseudo-keyword in -place of the old "/* fall through */" comment convention. - -Signed-off-by: Phil Elwell ---- - sound/soc/bcm/audioinjector-octo-soundcard.c | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - ---- a/sound/soc/bcm/audioinjector-octo-soundcard.c -+++ b/sound/soc/bcm/audioinjector-octo-soundcard.c -@@ -143,40 +143,40 @@ static int audioinjector_octo_trigger(st - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - if (!non_stop_clocks) - break; -- /* fall through */ -+ fallthrough; - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - switch (audioinjector_octo_rate) { - case 96000: - __assign_bit(3, mult, 1); -- /* fall through */ -+ fallthrough; - case 88200: - __assign_bit(1, mult, 1); - __assign_bit(2, mult, 1); - break; - case 48000: - __assign_bit(3, mult, 1); -- /* fall through */ -+ fallthrough; - case 44100: - __assign_bit(2, mult, 1); - break; - case 32000: - __assign_bit(3, mult, 1); -- /* fall through */ -+ fallthrough; - case 29400: - __assign_bit(0, mult, 1); - __assign_bit(1, mult, 1); - break; - case 24000: - __assign_bit(3, mult, 1); -- /* fall through */ -+ fallthrough; - case 22050: - __assign_bit(1, mult, 1); - break; - case 16000: - __assign_bit(3, mult, 1); -- /* fall through */ -+ fallthrough; - case 14700: - __assign_bit(0, mult, 1); - break; diff --git a/target/linux/bcm27xx/patches-5.15/950-0455-media-i2c-tc358743-Fix-compiler-warning.patch b/target/linux/bcm27xx/patches-5.15/950-0455-media-i2c-tc358743-Fix-compiler-warning.patch deleted file mode 100644 index a92299245..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0455-media-i2c-tc358743-Fix-compiler-warning.patch +++ /dev/null @@ -1,24 +0,0 @@ -From b72686b694ac4979450853a6a5dc2ece3df9fe82 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 27 Jul 2021 11:17:08 +0100 -Subject: [PATCH] media: i2c: tc358743: Fix compiler warning - -Avoid a compiler warning by using the "fallthrough" pseudo-keyword in -place of the old "/* fall through */" comment convention. - -Signed-off-by: Phil Elwell ---- - drivers/media/i2c/tc358743.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/media/i2c/tc358743.c -+++ b/drivers/media/i2c/tc358743.c -@@ -2008,7 +2008,7 @@ static int tc358743_probe_of(struct tc35 - switch (bps_pr_lane) { - default: - dev_warn(dev, "untested bps per lane: %u bps\n", bps_pr_lane); -- /* fall through */ -+ fallthrough; - case 594000000U: - state->pdata.lineinitcnt = 0xe80; - state->pdata.lptxtimecnt = 0x003; diff --git a/target/linux/bcm27xx/patches-5.15/950-0456-ASoC-bcm-Add-chipdip-dac-driver.patch b/target/linux/bcm27xx/patches-5.15/950-0456-ASoC-bcm-Add-chipdip-dac-driver.patch deleted file mode 100644 index de6936755..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0456-ASoC-bcm-Add-chipdip-dac-driver.patch +++ /dev/null @@ -1,325 +0,0 @@ -From 7da0da344225ec00f3070f9b4f6cb9dda06093ab Mon Sep 17 00:00:00 2001 -From: "chipdip.lab" <43340836+chipdipru@users.noreply.github.com> -Date: Mon, 26 Jul 2021 14:45:59 +0300 -Subject: [PATCH] ASoC: bcm: Add chipdip-dac driver - -Driver chipdip-dac.c added into sound/soc/bcm/, files -sound/soc/bcm/Kconfig and sound/soc/bcm/Makefile updated. - -Signed-off-by: Evgenij Sapunov ---- - sound/soc/bcm/Kconfig | 6 + - sound/soc/bcm/Makefile | 3 +- - sound/soc/bcm/chipdip-dac.c | 275 ++++++++++++++++++++++++++++++++++++ - 3 files changed, 283 insertions(+), 1 deletion(-) - create mode 100644 sound/soc/bcm/chipdip-dac.c - ---- a/sound/soc/bcm/Kconfig -+++ b/sound/soc/bcm/Kconfig -@@ -27,6 +27,12 @@ config SND_BCM63XX_I2S_WHISTLER - - If you don't know what to do here, say N - -+config SND_BCM2708_SOC_CHIPDIP_DAC -+ tristate "Support for the ChipDip DAC" -+ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S -+ help -+ Say Y or M if you want to add support for the ChipDip DAC soundcard -+ - config SND_BCM2708_SOC_GOOGLEVOICEHAT_SOUNDCARD - tristate "Support for Google voiceHAT soundcard" - depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S ---- a/sound/soc/bcm/Makefile -+++ b/sound/soc/bcm/Makefile -@@ -47,6 +47,7 @@ snd-soc-fe-pi-audio-objs := fe-pi-audio. - snd-soc-rpi-simple-soundcard-objs := rpi-simple-soundcard.o - snd-soc-rpi-wm8804-soundcard-objs := rpi-wm8804-soundcard.o - snd-soc-pifi-40-objs := pifi-40.o -+snd-soc-chipdip-dac-objs := chipdip-dac.o - - obj-$(CONFIG_SND_BCM2708_SOC_GOOGLEVOICEHAT_SOUNDCARD) += snd-soc-googlevoicehat-codec.o - obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) += snd-soc-hifiberry-dacplus.o -@@ -78,4 +79,4 @@ obj-$(CONFIG_SND_BCM2708_SOC_FE_PI_AUDIO - obj-$(CONFIG_SND_RPI_SIMPLE_SOUNDCARD) += snd-soc-rpi-simple-soundcard.o - obj-$(CONFIG_SND_RPI_WM8804_SOUNDCARD) += snd-soc-rpi-wm8804-soundcard.o - obj-$(CONFIG_SND_BCM2708_SOC_PIFI_40) += snd-soc-pifi-40.o -- -+obj-$(CONFIG_SND_BCM2708_SOC_CHIPDIP_DAC) += snd-soc-chipdip-dac.o ---- /dev/null -+++ b/sound/soc/bcm/chipdip-dac.c -@@ -0,0 +1,275 @@ -+/* -+ * ASoC Driver for ChipDip DAC -+ * -+ * Author: Evgenij Sapunov -+ * Copyright 2021 -+ * based on code by Milan Neskovic -+ * based on code by Jaikumar -+ * -+ * Thanks to Phil Elwell (pelwell) for help. -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * version 2 as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#define SR_BIT_0 0 //sample rate bits -+#define SR_BIT_1 1 -+#define SR_BIT_2 2 -+#define BD_BIT_0 3 //bit depth bits -+#define BD_BIT_1 4 -+ -+#define SAMPLE_RATE_MASK_44_1 0 -+#define SAMPLE_RATE_MASK_48 (1 << SR_BIT_0) -+#define SAMPLE_RATE_MASK_88_2 ((1 << SR_BIT_2) | (1 << SR_BIT_1)) -+#define SAMPLE_RATE_MASK_96 (1 << SR_BIT_1) -+#define SAMPLE_RATE_MASK_176_4 ((1 << SR_BIT_2) | (1 << SR_BIT_1) | (1 << SR_BIT_0)) -+#define SAMPLE_RATE_MASK_192 ((1 << SR_BIT_1) | (1 << SR_BIT_0)) -+#define SAMPLE_RATE_MASK ((1 << SR_BIT_2) | (1 << SR_BIT_1) | (1 << SR_BIT_0)) -+ -+#define BIT_DEPTH_MASK_16 0 -+#define BIT_DEPTH_MASK_24 (1 << BD_BIT_0) -+#define BIT_DEPTH_MASK_32 (1 << BD_BIT_1) -+#define BIT_DEPTH_MASK ((1 << BD_BIT_1) | (1 << BD_BIT_0)) -+ -+#define MUTE_ACTIVE 0 -+#define MUTE_NOT_ACTIVE 1 -+ -+#define HW_PARAMS_GPIO_COUNT 5 -+ -+static struct gpio_desc *mute_gpio; -+static struct gpio_desc *sdwn_gpio; -+static struct gpio_desc *hw_params_gpios[HW_PARAMS_GPIO_COUNT]; -+static int current_width; -+static int current_rate; -+ -+static void snd_rpi_chipdip_dac_gpio_array_set(int value); -+static void snd_rpi_chipdip_dac_gpio_set(struct gpio_desc *gpio_item, int value); -+ -+static void snd_rpi_chipdip_dac_gpio_array_set(int value) -+{ -+ int i = 0; -+ -+ for (i = 0; i < HW_PARAMS_GPIO_COUNT; i++) -+ snd_rpi_chipdip_dac_gpio_set(hw_params_gpios[i], ((value >> i) & 1)); -+} -+ -+static void snd_rpi_chipdip_dac_gpio_set(struct gpio_desc *gpio_item, int value) -+{ -+ if (gpio_item) -+ gpiod_set_value_cansleep(gpio_item, value); -+} -+ -+static int snd_rpi_chipdip_dac_init(struct snd_soc_pcm_runtime *rtd) -+{ -+ return 0; -+} -+ -+static int snd_rpi_chipdip_dac_hw_params(struct snd_pcm_substream *substream, -+ struct snd_pcm_hw_params *params) -+{ -+ int ret = 0; -+ int gpio_change_pending = 0; -+ int sample_rate_state = 0; -+ int bit_depth_state = 0; -+ int param_value = params_width(params); -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; -+ -+ ret = snd_soc_dai_set_bclk_ratio(asoc_rtd_to_cpu(rtd, 0), 2 * 32); -+ -+ if (current_width != param_value) { -+ current_width = param_value; -+ gpio_change_pending = 1; -+ -+ switch (param_value) { -+ case 16: -+ bit_depth_state = BIT_DEPTH_MASK_16; -+ break; -+ case 24: -+ bit_depth_state = BIT_DEPTH_MASK_24; -+ break; -+ case 32: -+ bit_depth_state = BIT_DEPTH_MASK_32; -+ break; -+ default: -+ return -EINVAL; -+ } -+ } -+ -+ param_value = params_rate(params); -+ if (current_rate != param_value) { -+ current_rate = param_value; -+ gpio_change_pending = 1; -+ -+ switch (param_value) { -+ case 44100: -+ sample_rate_state = SAMPLE_RATE_MASK_44_1; -+ break; -+ case 48000: -+ sample_rate_state = SAMPLE_RATE_MASK_48; -+ break; -+ case 88200: -+ sample_rate_state = SAMPLE_RATE_MASK_88_2; -+ break; -+ case 96000: -+ sample_rate_state = SAMPLE_RATE_MASK_96; -+ break; -+ case 176400: -+ sample_rate_state = SAMPLE_RATE_MASK_176_4; -+ break; -+ case 192000: -+ sample_rate_state = SAMPLE_RATE_MASK_192; -+ break; -+ default: -+ return -EINVAL; -+ } -+ } -+ -+ if (gpio_change_pending) { -+ snd_rpi_chipdip_dac_gpio_set(mute_gpio, MUTE_ACTIVE); -+ snd_rpi_chipdip_dac_gpio_array_set(bit_depth_state | sample_rate_state); -+ msleep(300); -+ snd_rpi_chipdip_dac_gpio_set(mute_gpio, MUTE_NOT_ACTIVE); -+ } -+ -+ return ret; -+} -+ -+static int snd_rpi_chipdip_dac_startup(struct snd_pcm_substream *substream) -+{ -+ return 0; -+} -+ -+static void snd_rpi_chipdip_dac_shutdown(struct snd_pcm_substream *substream) -+{ -+ -+} -+ -+/* machine stream operations */ -+static struct snd_soc_ops snd_rpi_chipdip_dac_ops = { -+ .hw_params = snd_rpi_chipdip_dac_hw_params, -+ .startup = snd_rpi_chipdip_dac_startup, -+ .shutdown = snd_rpi_chipdip_dac_shutdown, -+}; -+ -+SND_SOC_DAILINK_DEFS(hifi, -+ DAILINK_COMP_ARRAY(COMP_CPU("bcm2708-i2s.0")), -+ DAILINK_COMP_ARRAY(COMP_CODEC("spdif-transmitter", "dit-hifi")), -+ DAILINK_COMP_ARRAY(COMP_PLATFORM("bcm2708-i2s.0"))); -+ -+static struct snd_soc_dai_link snd_rpi_chipdip_dac_dai[] = { -+{ -+ .name = "ChipDip DAC", -+ .stream_name = "ChipDip DAC HiFi", -+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | -+ SND_SOC_DAIFMT_CBM_CFM, -+ .ops = &snd_rpi_chipdip_dac_ops, -+ .init = snd_rpi_chipdip_dac_init, -+ SND_SOC_DAILINK_REG(hifi), -+}, -+}; -+ -+/* audio machine driver */ -+static struct snd_soc_card snd_rpi_chipdip_dac = { -+ .name = "ChipDipDAC", -+ .driver_name = "ChipdipDac", -+ .owner = THIS_MODULE, -+ .dai_link = snd_rpi_chipdip_dac_dai, -+ .num_links = ARRAY_SIZE(snd_rpi_chipdip_dac_dai), -+}; -+ -+static int snd_rpi_chipdip_dac_probe(struct platform_device *pdev) -+{ -+ int ret = 0; -+ int i = 0; -+ -+ snd_rpi_chipdip_dac.dev = &pdev->dev; -+ -+ if (pdev->dev.of_node) { -+ struct device_node *i2s_node; -+ struct snd_soc_dai_link *dai = &snd_rpi_chipdip_dac_dai[0]; -+ i2s_node = of_parse_phandle(pdev->dev.of_node, -+ "i2s-controller", 0); -+ -+ if (i2s_node) { -+ dai->cpus->dai_name = NULL; -+ dai->cpus->of_node = i2s_node; -+ dai->platforms->name = NULL; -+ dai->platforms->of_node = i2s_node; -+ } -+ } -+ -+ hw_params_gpios[SR_BIT_0] = devm_gpiod_get_optional(&pdev->dev, "sr0", GPIOD_OUT_LOW); -+ hw_params_gpios[SR_BIT_1] = devm_gpiod_get_optional(&pdev->dev, "sr1", GPIOD_OUT_LOW); -+ hw_params_gpios[SR_BIT_2] = devm_gpiod_get_optional(&pdev->dev, "sr2", GPIOD_OUT_LOW); -+ hw_params_gpios[BD_BIT_0] = devm_gpiod_get_optional(&pdev->dev, "res0", GPIOD_OUT_LOW); -+ hw_params_gpios[BD_BIT_1] = devm_gpiod_get_optional(&pdev->dev, "res1", GPIOD_OUT_LOW); -+ mute_gpio = devm_gpiod_get_optional(&pdev->dev, "mute", GPIOD_OUT_LOW); -+ sdwn_gpio = devm_gpiod_get_optional(&pdev->dev, "sdwn", GPIOD_OUT_HIGH); -+ -+ for (i = 0; i < HW_PARAMS_GPIO_COUNT; i++) { -+ if (IS_ERR(hw_params_gpios[i])) { -+ ret = PTR_ERR(hw_params_gpios[i]); -+ dev_err(&pdev->dev, "failed to get hw_params gpio: %d\n", ret); -+ return ret; -+ } -+ } -+ -+ if (IS_ERR(mute_gpio)) { -+ ret = PTR_ERR(mute_gpio); -+ dev_err(&pdev->dev, "failed to get mute gpio: %d\n", ret); -+ return ret; -+ } -+ -+ if (IS_ERR(sdwn_gpio)) { -+ ret = PTR_ERR(sdwn_gpio); -+ dev_err(&pdev->dev, "failed to get sdwn gpio: %d\n", ret); -+ return ret; -+ } -+ -+ snd_rpi_chipdip_dac_gpio_set(sdwn_gpio, 1); -+ -+ ret = devm_snd_soc_register_card(&pdev->dev, &snd_rpi_chipdip_dac); -+ if (ret && ret != -EPROBE_DEFER) -+ dev_err(&pdev->dev, -+ "snd_soc_register_card() failed: %d\n", ret); -+ -+ return ret; -+} -+ -+static const struct of_device_id snd_rpi_chipdip_dac_of_match[] = { -+ { .compatible = "chipdip,chipdip-dac", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, snd_rpi_chipdip_dac_of_match); -+ -+static struct platform_driver snd_rpi_chipdip_dac_driver = { -+ .driver = { -+ .name = "snd-rpi-chipdip-dac", -+ .owner = THIS_MODULE, -+ .of_match_table = snd_rpi_chipdip_dac_of_match, -+ }, -+ .probe = snd_rpi_chipdip_dac_probe, -+}; -+ -+module_platform_driver(snd_rpi_chipdip_dac_driver); -+ -+MODULE_AUTHOR("Evgenij Sapunov "); -+MODULE_DESCRIPTION("ASoC Driver for ChipDip DAC"); -+MODULE_LICENSE("GPL v2"); diff --git a/target/linux/bcm27xx/patches-5.15/950-0457-media-i2c-imx290-Add-fwnode-properties-controls.patch b/target/linux/bcm27xx/patches-5.15/950-0457-media-i2c-imx290-Add-fwnode-properties-controls.patch deleted file mode 100644 index ec249d35f..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0457-media-i2c-imx290-Add-fwnode-properties-controls.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 500db93808fcfa78292fe877f5120186f32df841 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 3 Aug 2021 11:25:59 +0100 -Subject: [PATCH] media: i2c: imx290: Add fwnode properties controls - -Add call to v4l2_ctrl_new_fwnode_properties to read and -create the fwnode based controls. - -Signed-off-by: Dave Stevenson ---- - drivers/media/i2c/imx290.c | 12 +++++++++++- - 1 file changed, 11 insertions(+), 1 deletion(-) - ---- a/drivers/media/i2c/imx290.c -+++ b/drivers/media/i2c/imx290.c -@@ -1239,6 +1239,7 @@ static const struct of_device_id imx290_ - - static int imx290_probe(struct i2c_client *client) - { -+ struct v4l2_fwnode_device_properties props; - struct device *dev = &client->dev; - struct fwnode_handle *endpoint; - /* Only CSI2 is supported for now: */ -@@ -1360,7 +1361,7 @@ static int imx290_probe(struct i2c_clien - */ - imx290_entity_init_cfg(&imx290->sd, NULL); - -- v4l2_ctrl_handler_init(&imx290->ctrls, 9); -+ v4l2_ctrl_handler_init(&imx290->ctrls, 11); - - v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops, - V4L2_CID_ANALOGUE_GAIN, 0, 100, 1, 0); -@@ -1408,6 +1409,15 @@ static int imx290_probe(struct i2c_clien - ARRAY_SIZE(imx290_test_pattern_menu) - 1, - 0, 0, imx290_test_pattern_menu); - -+ ret = v4l2_fwnode_device_parse(&client->dev, &props); -+ if (ret) -+ goto free_ctrl; -+ -+ ret = v4l2_ctrl_new_fwnode_properties(&imx290->ctrls, &imx290_ctrl_ops, -+ &props); -+ if (ret) -+ goto free_ctrl; -+ - imx290->sd.ctrl_handler = &imx290->ctrls; - - if (imx290->ctrls.error) { diff --git a/target/linux/bcm27xx/patches-5.15/950-0458-media-i2c-ov9281-Add-fwnode-properties-controls.patch b/target/linux/bcm27xx/patches-5.15/950-0458-media-i2c-ov9281-Add-fwnode-properties-controls.patch deleted file mode 100644 index 57660ab8c..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0458-media-i2c-ov9281-Add-fwnode-properties-controls.patch +++ /dev/null @@ -1,56 +0,0 @@ -From dfaa98b5db1b6ec5f73b18f997cf18c18099d571 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 3 Aug 2021 11:30:58 +0100 -Subject: [PATCH] media: i2c: ov9281: Add fwnode properties controls - -Add call to v4l2_ctrl_new_fwnode_properties to read and -create the fwnode based controls. - -Signed-off-by: Dave Stevenson ---- - drivers/media/i2c/ov9281.c | 13 ++++++++++++- - 1 file changed, 12 insertions(+), 1 deletion(-) - ---- a/drivers/media/i2c/ov9281.c -+++ b/drivers/media/i2c/ov9281.c -@@ -25,6 +25,7 @@ - #include - #include - #include -+#include - #include - - #define OV9281_LINK_FREQ_400MHZ 400000000 -@@ -1023,6 +1024,7 @@ static const struct v4l2_ctrl_ops ov9281 - - static int ov9281_initialize_controls(struct ov9281 *ov9281) - { -+ struct v4l2_fwnode_device_properties props; - const struct ov9281_mode *mode; - struct v4l2_ctrl_handler *handler; - struct v4l2_ctrl *ctrl; -@@ -1032,7 +1034,7 @@ static int ov9281_initialize_controls(st - - handler = &ov9281->ctrl_handler; - mode = ov9281->cur_mode; -- ret = v4l2_ctrl_handler_init(handler, 9); -+ ret = v4l2_ctrl_handler_init(handler, 11); - if (ret) - return ret; - handler->lock = &ov9281->mutex; -@@ -1094,6 +1096,15 @@ static int ov9281_initialize_controls(st - goto err_free_handler; - } - -+ ret = v4l2_fwnode_device_parse(&ov9281->client->dev, &props); -+ if (ret) -+ goto err_free_handler; -+ -+ ret = v4l2_ctrl_new_fwnode_properties(handler, &ov9281_ctrl_ops, -+ &props); -+ if (ret) -+ goto err_free_handler; -+ - ov9281->subdev.ctrl_handler = handler; - - return 0; diff --git a/target/linux/bcm27xx/patches-5.15/950-0460-media-v4l2-Remove-v4l2-ctrls.c.patch b/target/linux/bcm27xx/patches-5.15/950-0460-media-v4l2-Remove-v4l2-ctrls.c.patch deleted file mode 100644 index 8a1c24f6c..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0460-media-v4l2-Remove-v4l2-ctrls.c.patch +++ /dev/null @@ -1,5064 +0,0 @@ -From 95280e5163ea457ccb442bc9d6c003c803d13894 Mon Sep 17 00:00:00 2001 -From: John Cox -Date: Fri, 6 Aug 2021 10:47:11 +0100 -Subject: [PATCH] media: v4l2: Remove v4l2-ctrls.c - -v4l2-ctrls.c has been split into 4 files v4l2-ctrls-*.c, the original -is redundant, confusing and probably should have been removed by a -previous patch. - -Signed-off-by: John Cox ---- - drivers/media/v4l2-core/v4l2-ctrls.c | 5046 -------------------------- - 1 file changed, 5046 deletions(-) - delete mode 100644 drivers/media/v4l2-core/v4l2-ctrls.c - ---- a/drivers/media/v4l2-core/v4l2-ctrls.c -+++ /dev/null -@@ -1,5046 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0-or-later --/* -- V4L2 controls framework implementation. -- -- Copyright (C) 2010 Hans Verkuil -- -- */ -- --#define pr_fmt(fmt) "v4l2-ctrls: " fmt -- --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#define dprintk(vdev, fmt, arg...) do { \ -- if (!WARN_ON(!(vdev)) && ((vdev)->dev_debug & V4L2_DEV_DEBUG_CTRL)) \ -- printk(KERN_DEBUG pr_fmt("%s: %s: " fmt), \ -- __func__, video_device_node_name(vdev), ##arg); \ --} while (0) -- --#define has_op(master, op) \ -- (master->ops && master->ops->op) --#define call_op(master, op) \ -- (has_op(master, op) ? master->ops->op(master) : 0) -- --static const union v4l2_ctrl_ptr ptr_null; -- --/* Internal temporary helper struct, one for each v4l2_ext_control */ --struct v4l2_ctrl_helper { -- /* Pointer to the control reference of the master control */ -- struct v4l2_ctrl_ref *mref; -- /* The control ref corresponding to the v4l2_ext_control ID field. */ -- struct v4l2_ctrl_ref *ref; -- /* v4l2_ext_control index of the next control belonging to the -- same cluster, or 0 if there isn't any. */ -- u32 next; --}; -- --/* Small helper function to determine if the autocluster is set to manual -- mode. */ --static bool is_cur_manual(const struct v4l2_ctrl *master) --{ -- return master->is_auto && master->cur.val == master->manual_mode_value; --} -- --/* Same as above, but this checks the against the new value instead of the -- current value. */ --static bool is_new_manual(const struct v4l2_ctrl *master) --{ -- return master->is_auto && master->val == master->manual_mode_value; --} -- --/* Returns NULL or a character pointer array containing the menu for -- the given control ID. The pointer array ends with a NULL pointer. -- An empty string signifies a menu entry that is invalid. This allows -- drivers to disable certain options if it is not supported. */ --const char * const *v4l2_ctrl_get_menu(u32 id) --{ -- static const char * const mpeg_audio_sampling_freq[] = { -- "44.1 kHz", -- "48 kHz", -- "32 kHz", -- NULL -- }; -- static const char * const mpeg_audio_encoding[] = { -- "MPEG-1/2 Layer I", -- "MPEG-1/2 Layer II", -- "MPEG-1/2 Layer III", -- "MPEG-2/4 AAC", -- "AC-3", -- NULL -- }; -- static const char * const mpeg_audio_l1_bitrate[] = { -- "32 kbps", -- "64 kbps", -- "96 kbps", -- "128 kbps", -- "160 kbps", -- "192 kbps", -- "224 kbps", -- "256 kbps", -- "288 kbps", -- "320 kbps", -- "352 kbps", -- "384 kbps", -- "416 kbps", -- "448 kbps", -- NULL -- }; -- static const char * const mpeg_audio_l2_bitrate[] = { -- "32 kbps", -- "48 kbps", -- "56 kbps", -- "64 kbps", -- "80 kbps", -- "96 kbps", -- "112 kbps", -- "128 kbps", -- "160 kbps", -- "192 kbps", -- "224 kbps", -- "256 kbps", -- "320 kbps", -- "384 kbps", -- NULL -- }; -- static const char * const mpeg_audio_l3_bitrate[] = { -- "32 kbps", -- "40 kbps", -- "48 kbps", -- "56 kbps", -- "64 kbps", -- "80 kbps", -- "96 kbps", -- "112 kbps", -- "128 kbps", -- "160 kbps", -- "192 kbps", -- "224 kbps", -- "256 kbps", -- "320 kbps", -- NULL -- }; -- static const char * const mpeg_audio_ac3_bitrate[] = { -- "32 kbps", -- "40 kbps", -- "48 kbps", -- "56 kbps", -- "64 kbps", -- "80 kbps", -- "96 kbps", -- "112 kbps", -- "128 kbps", -- "160 kbps", -- "192 kbps", -- "224 kbps", -- "256 kbps", -- "320 kbps", -- "384 kbps", -- "448 kbps", -- "512 kbps", -- "576 kbps", -- "640 kbps", -- NULL -- }; -- static const char * const mpeg_audio_mode[] = { -- "Stereo", -- "Joint Stereo", -- "Dual", -- "Mono", -- NULL -- }; -- static const char * const mpeg_audio_mode_extension[] = { -- "Bound 4", -- "Bound 8", -- "Bound 12", -- "Bound 16", -- NULL -- }; -- static const char * const mpeg_audio_emphasis[] = { -- "No Emphasis", -- "50/15 us", -- "CCITT J17", -- NULL -- }; -- static const char * const mpeg_audio_crc[] = { -- "No CRC", -- "16-bit CRC", -- NULL -- }; -- static const char * const mpeg_audio_dec_playback[] = { -- "Auto", -- "Stereo", -- "Left", -- "Right", -- "Mono", -- "Swapped Stereo", -- NULL -- }; -- static const char * const mpeg_video_encoding[] = { -- "MPEG-1", -- "MPEG-2", -- "MPEG-4 AVC", -- NULL -- }; -- static const char * const mpeg_video_aspect[] = { -- "1x1", -- "4x3", -- "16x9", -- "2.21x1", -- NULL -- }; -- static const char * const mpeg_video_bitrate_mode[] = { -- "Variable Bitrate", -- "Constant Bitrate", -- "Constant Quality", -- NULL -- }; -- static const char * const mpeg_stream_type[] = { -- "MPEG-2 Program Stream", -- "MPEG-2 Transport Stream", -- "MPEG-1 System Stream", -- "MPEG-2 DVD-compatible Stream", -- "MPEG-1 VCD-compatible Stream", -- "MPEG-2 SVCD-compatible Stream", -- NULL -- }; -- static const char * const mpeg_stream_vbi_fmt[] = { -- "No VBI", -- "Private Packet, IVTV Format", -- NULL -- }; -- static const char * const camera_power_line_frequency[] = { -- "Disabled", -- "50 Hz", -- "60 Hz", -- "Auto", -- NULL -- }; -- static const char * const camera_exposure_auto[] = { -- "Auto Mode", -- "Manual Mode", -- "Shutter Priority Mode", -- "Aperture Priority Mode", -- NULL -- }; -- static const char * const camera_exposure_metering[] = { -- "Average", -- "Center Weighted", -- "Spot", -- "Matrix", -- NULL -- }; -- static const char * const camera_auto_focus_range[] = { -- "Auto", -- "Normal", -- "Macro", -- "Infinity", -- NULL -- }; -- static const char * const colorfx[] = { -- "None", -- "Black & White", -- "Sepia", -- "Negative", -- "Emboss", -- "Sketch", -- "Sky Blue", -- "Grass Green", -- "Skin Whiten", -- "Vivid", -- "Aqua", -- "Art Freeze", -- "Silhouette", -- "Solarization", -- "Antique", -- "Set Cb/Cr", -- NULL -- }; -- static const char * const auto_n_preset_white_balance[] = { -- "Manual", -- "Auto", -- "Incandescent", -- "Fluorescent", -- "Fluorescent H", -- "Horizon", -- "Daylight", -- "Flash", -- "Cloudy", -- "Shade", -- "Greyworld", -- NULL, -- }; -- static const char * const camera_iso_sensitivity_auto[] = { -- "Manual", -- "Auto", -- NULL -- }; -- static const char * const scene_mode[] = { -- "None", -- "Backlight", -- "Beach/Snow", -- "Candle Light", -- "Dusk/Dawn", -- "Fall Colors", -- "Fireworks", -- "Landscape", -- "Night", -- "Party/Indoor", -- "Portrait", -- "Sports", -- "Sunset", -- "Text", -- NULL -- }; -- static const char * const tune_emphasis[] = { -- "None", -- "50 Microseconds", -- "75 Microseconds", -- NULL, -- }; -- static const char * const header_mode[] = { -- "Separate Buffer", -- "Joined With 1st Frame", -- NULL, -- }; -- static const char * const multi_slice[] = { -- "Single", -- "Max Macroblocks", -- "Max Bytes", -- NULL, -- }; -- static const char * const entropy_mode[] = { -- "CAVLC", -- "CABAC", -- NULL, -- }; -- static const char * const mpeg_h264_level[] = { -- "1", -- "1b", -- "1.1", -- "1.2", -- "1.3", -- "2", -- "2.1", -- "2.2", -- "3", -- "3.1", -- "3.2", -- "4", -- "4.1", -- "4.2", -- "5", -- "5.1", -- "5.2", -- "6.0", -- "6.1", -- "6.2", -- NULL, -- }; -- static const char * const h264_loop_filter[] = { -- "Enabled", -- "Disabled", -- "Disabled at Slice Boundary", -- NULL, -- }; -- static const char * const h264_profile[] = { -- "Baseline", -- "Constrained Baseline", -- "Main", -- "Extended", -- "High", -- "High 10", -- "High 422", -- "High 444 Predictive", -- "High 10 Intra", -- "High 422 Intra", -- "High 444 Intra", -- "CAVLC 444 Intra", -- "Scalable Baseline", -- "Scalable High", -- "Scalable High Intra", -- "Stereo High", -- "Multiview High", -- "Constrained High", -- NULL, -- }; -- static const char * const vui_sar_idc[] = { -- "Unspecified", -- "1:1", -- "12:11", -- "10:11", -- "16:11", -- "40:33", -- "24:11", -- "20:11", -- "32:11", -- "80:33", -- "18:11", -- "15:11", -- "64:33", -- "160:99", -- "4:3", -- "3:2", -- "2:1", -- "Extended SAR", -- NULL, -- }; -- static const char * const h264_fp_arrangement_type[] = { -- "Checkerboard", -- "Column", -- "Row", -- "Side by Side", -- "Top Bottom", -- "Temporal", -- NULL, -- }; -- static const char * const h264_fmo_map_type[] = { -- "Interleaved Slices", -- "Scattered Slices", -- "Foreground with Leftover", -- "Box Out", -- "Raster Scan", -- "Wipe Scan", -- "Explicit", -- NULL, -- }; -- static const char * const h264_decode_mode[] = { -- "Slice-Based", -- "Frame-Based", -- NULL, -- }; -- static const char * const h264_start_code[] = { -- "No Start Code", -- "Annex B Start Code", -- NULL, -- }; -- static const char * const h264_hierarchical_coding_type[] = { -- "Hier Coding B", -- "Hier Coding P", -- NULL, -- }; -- static const char * const mpeg_mpeg2_level[] = { -- "Low", -- "Main", -- "High 1440", -- "High", -- NULL, -- }; -- static const char * const mpeg2_profile[] = { -- "Simple", -- "Main", -- "SNR Scalable", -- "Spatially Scalable", -- "High", -- NULL, -- }; -- static const char * const mpeg_mpeg4_level[] = { -- "0", -- "0b", -- "1", -- "2", -- "3", -- "3b", -- "4", -- "5", -- NULL, -- }; -- static const char * const mpeg4_profile[] = { -- "Simple", -- "Advanced Simple", -- "Core", -- "Simple Scalable", -- "Advanced Coding Efficiency", -- NULL, -- }; -- -- static const char * const vpx_golden_frame_sel[] = { -- "Use Previous Frame", -- "Use Previous Specific Frame", -- NULL, -- }; -- static const char * const vp8_profile[] = { -- "0", -- "1", -- "2", -- "3", -- NULL, -- }; -- static const char * const vp9_profile[] = { -- "0", -- "1", -- "2", -- "3", -- NULL, -- }; -- static const char * const vp9_level[] = { -- "1", -- "1.1", -- "2", -- "2.1", -- "3", -- "3.1", -- "4", -- "4.1", -- "5", -- "5.1", -- "5.2", -- "6", -- "6.1", -- "6.2", -- NULL, -- }; -- -- static const char * const flash_led_mode[] = { -- "Off", -- "Flash", -- "Torch", -- NULL, -- }; -- static const char * const flash_strobe_source[] = { -- "Software", -- "External", -- NULL, -- }; -- -- static const char * const jpeg_chroma_subsampling[] = { -- "4:4:4", -- "4:2:2", -- "4:2:0", -- "4:1:1", -- "4:1:0", -- "Gray", -- NULL, -- }; -- static const char * const dv_tx_mode[] = { -- "DVI-D", -- "HDMI", -- NULL, -- }; -- static const char * const dv_rgb_range[] = { -- "Automatic", -- "RGB Limited Range (16-235)", -- "RGB Full Range (0-255)", -- NULL, -- }; -- static const char * const dv_it_content_type[] = { -- "Graphics", -- "Photo", -- "Cinema", -- "Game", -- "No IT Content", -- NULL, -- }; -- static const char * const detect_md_mode[] = { -- "Disabled", -- "Global", -- "Threshold Grid", -- "Region Grid", -- NULL, -- }; -- -- static const char * const hevc_profile[] = { -- "Main", -- "Main Still Picture", -- "Main 10", -- NULL, -- }; -- static const char * const hevc_level[] = { -- "1", -- "2", -- "2.1", -- "3", -- "3.1", -- "4", -- "4.1", -- "5", -- "5.1", -- "5.2", -- "6", -- "6.1", -- "6.2", -- NULL, -- }; -- static const char * const hevc_hierarchial_coding_type[] = { -- "B", -- "P", -- NULL, -- }; -- static const char * const hevc_refresh_type[] = { -- "None", -- "CRA", -- "IDR", -- NULL, -- }; -- static const char * const hevc_size_of_length_field[] = { -- "0", -- "1", -- "2", -- "4", -- NULL, -- }; -- static const char * const hevc_tier[] = { -- "Main", -- "High", -- NULL, -- }; -- static const char * const hevc_loop_filter_mode[] = { -- "Disabled", -- "Enabled", -- "Disabled at slice boundary", -- "NULL", -- }; -- static const char * const hevc_decode_mode[] = { -- "Slice-Based", -- "Frame-Based", -- NULL, -- }; -- static const char * const hevc_start_code[] = { -- "No Start Code", -- "Annex B Start Code", -- NULL, -- }; -- static const char * const camera_orientation[] = { -- "Front", -- "Back", -- "External", -- NULL, -- }; -- static const char * const mpeg_video_frame_skip[] = { -- "Disabled", -- "Level Limit", -- "VBV/CPB Limit", -- NULL, -- }; -- -- switch (id) { -- case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: -- return mpeg_audio_sampling_freq; -- case V4L2_CID_MPEG_AUDIO_ENCODING: -- return mpeg_audio_encoding; -- case V4L2_CID_MPEG_AUDIO_L1_BITRATE: -- return mpeg_audio_l1_bitrate; -- case V4L2_CID_MPEG_AUDIO_L2_BITRATE: -- return mpeg_audio_l2_bitrate; -- case V4L2_CID_MPEG_AUDIO_L3_BITRATE: -- return mpeg_audio_l3_bitrate; -- case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: -- return mpeg_audio_ac3_bitrate; -- case V4L2_CID_MPEG_AUDIO_MODE: -- return mpeg_audio_mode; -- case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: -- return mpeg_audio_mode_extension; -- case V4L2_CID_MPEG_AUDIO_EMPHASIS: -- return mpeg_audio_emphasis; -- case V4L2_CID_MPEG_AUDIO_CRC: -- return mpeg_audio_crc; -- case V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK: -- case V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK: -- return mpeg_audio_dec_playback; -- case V4L2_CID_MPEG_VIDEO_ENCODING: -- return mpeg_video_encoding; -- case V4L2_CID_MPEG_VIDEO_ASPECT: -- return mpeg_video_aspect; -- case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: -- return mpeg_video_bitrate_mode; -- case V4L2_CID_MPEG_STREAM_TYPE: -- return mpeg_stream_type; -- case V4L2_CID_MPEG_STREAM_VBI_FMT: -- return mpeg_stream_vbi_fmt; -- case V4L2_CID_POWER_LINE_FREQUENCY: -- return camera_power_line_frequency; -- case V4L2_CID_EXPOSURE_AUTO: -- return camera_exposure_auto; -- case V4L2_CID_EXPOSURE_METERING: -- return camera_exposure_metering; -- case V4L2_CID_AUTO_FOCUS_RANGE: -- return camera_auto_focus_range; -- case V4L2_CID_COLORFX: -- return colorfx; -- case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE: -- return auto_n_preset_white_balance; -- case V4L2_CID_ISO_SENSITIVITY_AUTO: -- return camera_iso_sensitivity_auto; -- case V4L2_CID_SCENE_MODE: -- return scene_mode; -- case V4L2_CID_TUNE_PREEMPHASIS: -- return tune_emphasis; -- case V4L2_CID_TUNE_DEEMPHASIS: -- return tune_emphasis; -- case V4L2_CID_FLASH_LED_MODE: -- return flash_led_mode; -- case V4L2_CID_FLASH_STROBE_SOURCE: -- return flash_strobe_source; -- case V4L2_CID_MPEG_VIDEO_HEADER_MODE: -- return header_mode; -- case V4L2_CID_MPEG_VIDEO_FRAME_SKIP_MODE: -- return mpeg_video_frame_skip; -- case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE: -- return multi_slice; -- case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE: -- return entropy_mode; -- case V4L2_CID_MPEG_VIDEO_H264_LEVEL: -- return mpeg_h264_level; -- case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE: -- return h264_loop_filter; -- case V4L2_CID_MPEG_VIDEO_H264_PROFILE: -- return h264_profile; -- case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC: -- return vui_sar_idc; -- case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE: -- return h264_fp_arrangement_type; -- case V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE: -- return h264_fmo_map_type; -- case V4L2_CID_STATELESS_H264_DECODE_MODE: -- return h264_decode_mode; -- case V4L2_CID_STATELESS_H264_START_CODE: -- return h264_start_code; -- case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE: -- return h264_hierarchical_coding_type; -- case V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL: -- return mpeg_mpeg2_level; -- case V4L2_CID_MPEG_VIDEO_MPEG2_PROFILE: -- return mpeg2_profile; -- case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL: -- return mpeg_mpeg4_level; -- case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE: -- return mpeg4_profile; -- case V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_SEL: -- return vpx_golden_frame_sel; -- case V4L2_CID_MPEG_VIDEO_VP8_PROFILE: -- return vp8_profile; -- case V4L2_CID_MPEG_VIDEO_VP9_PROFILE: -- return vp9_profile; -- case V4L2_CID_MPEG_VIDEO_VP9_LEVEL: -- return vp9_level; -- case V4L2_CID_JPEG_CHROMA_SUBSAMPLING: -- return jpeg_chroma_subsampling; -- case V4L2_CID_DV_TX_MODE: -- return dv_tx_mode; -- case V4L2_CID_DV_TX_RGB_RANGE: -- case V4L2_CID_DV_RX_RGB_RANGE: -- return dv_rgb_range; -- case V4L2_CID_DV_TX_IT_CONTENT_TYPE: -- case V4L2_CID_DV_RX_IT_CONTENT_TYPE: -- return dv_it_content_type; -- case V4L2_CID_DETECT_MD_MODE: -- return detect_md_mode; -- case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE: -- return hevc_profile; -- case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL: -- return hevc_level; -- case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE: -- return hevc_hierarchial_coding_type; -- case V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_TYPE: -- return hevc_refresh_type; -- case V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD: -- return hevc_size_of_length_field; -- case V4L2_CID_MPEG_VIDEO_HEVC_TIER: -- return hevc_tier; -- case V4L2_CID_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE: -- return hevc_loop_filter_mode; -- case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE: -- return hevc_decode_mode; -- case V4L2_CID_MPEG_VIDEO_HEVC_START_CODE: -- return hevc_start_code; -- case V4L2_CID_CAMERA_ORIENTATION: -- return camera_orientation; -- default: -- return NULL; -- } --} --EXPORT_SYMBOL(v4l2_ctrl_get_menu); -- --#define __v4l2_qmenu_int_len(arr, len) ({ *(len) = ARRAY_SIZE(arr); arr; }) --/* -- * Returns NULL or an s64 type array containing the menu for given -- * control ID. The total number of the menu items is returned in @len. -- */ --const s64 *v4l2_ctrl_get_int_menu(u32 id, u32 *len) --{ -- static const s64 qmenu_int_vpx_num_partitions[] = { -- 1, 2, 4, 8, -- }; -- -- static const s64 qmenu_int_vpx_num_ref_frames[] = { -- 1, 2, 3, -- }; -- -- switch (id) { -- case V4L2_CID_MPEG_VIDEO_VPX_NUM_PARTITIONS: -- return __v4l2_qmenu_int_len(qmenu_int_vpx_num_partitions, len); -- case V4L2_CID_MPEG_VIDEO_VPX_NUM_REF_FRAMES: -- return __v4l2_qmenu_int_len(qmenu_int_vpx_num_ref_frames, len); -- default: -- *len = 0; -- return NULL; -- } --} --EXPORT_SYMBOL(v4l2_ctrl_get_int_menu); -- --/* Return the control name. */ --const char *v4l2_ctrl_get_name(u32 id) --{ -- switch (id) { -- /* USER controls */ -- /* Keep the order of the 'case's the same as in v4l2-controls.h! */ -- case V4L2_CID_USER_CLASS: return "User Controls"; -- case V4L2_CID_BRIGHTNESS: return "Brightness"; -- case V4L2_CID_CONTRAST: return "Contrast"; -- case V4L2_CID_SATURATION: return "Saturation"; -- case V4L2_CID_HUE: return "Hue"; -- case V4L2_CID_AUDIO_VOLUME: return "Volume"; -- case V4L2_CID_AUDIO_BALANCE: return "Balance"; -- case V4L2_CID_AUDIO_BASS: return "Bass"; -- case V4L2_CID_AUDIO_TREBLE: return "Treble"; -- case V4L2_CID_AUDIO_MUTE: return "Mute"; -- case V4L2_CID_AUDIO_LOUDNESS: return "Loudness"; -- case V4L2_CID_BLACK_LEVEL: return "Black Level"; -- case V4L2_CID_AUTO_WHITE_BALANCE: return "White Balance, Automatic"; -- case V4L2_CID_DO_WHITE_BALANCE: return "Do White Balance"; -- case V4L2_CID_RED_BALANCE: return "Red Balance"; -- case V4L2_CID_BLUE_BALANCE: return "Blue Balance"; -- case V4L2_CID_GAMMA: return "Gamma"; -- case V4L2_CID_EXPOSURE: return "Exposure"; -- case V4L2_CID_AUTOGAIN: return "Gain, Automatic"; -- case V4L2_CID_GAIN: return "Gain"; -- case V4L2_CID_HFLIP: return "Horizontal Flip"; -- case V4L2_CID_VFLIP: return "Vertical Flip"; -- case V4L2_CID_POWER_LINE_FREQUENCY: return "Power Line Frequency"; -- case V4L2_CID_HUE_AUTO: return "Hue, Automatic"; -- case V4L2_CID_WHITE_BALANCE_TEMPERATURE: return "White Balance Temperature"; -- case V4L2_CID_SHARPNESS: return "Sharpness"; -- case V4L2_CID_BACKLIGHT_COMPENSATION: return "Backlight Compensation"; -- case V4L2_CID_CHROMA_AGC: return "Chroma AGC"; -- case V4L2_CID_COLOR_KILLER: return "Color Killer"; -- case V4L2_CID_COLORFX: return "Color Effects"; -- case V4L2_CID_AUTOBRIGHTNESS: return "Brightness, Automatic"; -- case V4L2_CID_BAND_STOP_FILTER: return "Band-Stop Filter"; -- case V4L2_CID_ROTATE: return "Rotate"; -- case V4L2_CID_BG_COLOR: return "Background Color"; -- case V4L2_CID_CHROMA_GAIN: return "Chroma Gain"; -- case V4L2_CID_ILLUMINATORS_1: return "Illuminator 1"; -- case V4L2_CID_ILLUMINATORS_2: return "Illuminator 2"; -- case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE: return "Min Number of Capture Buffers"; -- case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT: return "Min Number of Output Buffers"; -- case V4L2_CID_ALPHA_COMPONENT: return "Alpha Component"; -- case V4L2_CID_COLORFX_CBCR: return "Color Effects, CbCr"; -- -- /* Codec controls */ -- /* The MPEG controls are applicable to all codec controls -- * and the 'MPEG' part of the define is historical */ -- /* Keep the order of the 'case's the same as in videodev2.h! */ -- case V4L2_CID_CODEC_CLASS: return "Codec Controls"; -- case V4L2_CID_MPEG_STREAM_TYPE: return "Stream Type"; -- case V4L2_CID_MPEG_STREAM_PID_PMT: return "Stream PMT Program ID"; -- case V4L2_CID_MPEG_STREAM_PID_AUDIO: return "Stream Audio Program ID"; -- case V4L2_CID_MPEG_STREAM_PID_VIDEO: return "Stream Video Program ID"; -- case V4L2_CID_MPEG_STREAM_PID_PCR: return "Stream PCR Program ID"; -- case V4L2_CID_MPEG_STREAM_PES_ID_AUDIO: return "Stream PES Audio ID"; -- case V4L2_CID_MPEG_STREAM_PES_ID_VIDEO: return "Stream PES Video ID"; -- case V4L2_CID_MPEG_STREAM_VBI_FMT: return "Stream VBI Format"; -- case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: return "Audio Sampling Frequency"; -- case V4L2_CID_MPEG_AUDIO_ENCODING: return "Audio Encoding"; -- case V4L2_CID_MPEG_AUDIO_L1_BITRATE: return "Audio Layer I Bitrate"; -- case V4L2_CID_MPEG_AUDIO_L2_BITRATE: return "Audio Layer II Bitrate"; -- case V4L2_CID_MPEG_AUDIO_L3_BITRATE: return "Audio Layer III Bitrate"; -- case V4L2_CID_MPEG_AUDIO_MODE: return "Audio Stereo Mode"; -- case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: return "Audio Stereo Mode Extension"; -- case V4L2_CID_MPEG_AUDIO_EMPHASIS: return "Audio Emphasis"; -- case V4L2_CID_MPEG_AUDIO_CRC: return "Audio CRC"; -- case V4L2_CID_MPEG_AUDIO_MUTE: return "Audio Mute"; -- case V4L2_CID_MPEG_AUDIO_AAC_BITRATE: return "Audio AAC Bitrate"; -- case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: return "Audio AC-3 Bitrate"; -- case V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK: return "Audio Playback"; -- case V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK: return "Audio Multilingual Playback"; -- case V4L2_CID_MPEG_VIDEO_ENCODING: return "Video Encoding"; -- case V4L2_CID_MPEG_VIDEO_ASPECT: return "Video Aspect"; -- case V4L2_CID_MPEG_VIDEO_B_FRAMES: return "Video B Frames"; -- case V4L2_CID_MPEG_VIDEO_GOP_SIZE: return "Video GOP Size"; -- case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: return "Video GOP Closure"; -- case V4L2_CID_MPEG_VIDEO_PULLDOWN: return "Video Pulldown"; -- case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: return "Video Bitrate Mode"; -- case V4L2_CID_MPEG_VIDEO_CONSTANT_QUALITY: return "Constant Quality"; -- case V4L2_CID_MPEG_VIDEO_BITRATE: return "Video Bitrate"; -- case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: return "Video Peak Bitrate"; -- case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION: return "Video Temporal Decimation"; -- case V4L2_CID_MPEG_VIDEO_MUTE: return "Video Mute"; -- case V4L2_CID_MPEG_VIDEO_MUTE_YUV: return "Video Mute YUV"; -- case V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE: return "Decoder Slice Interface"; -- case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER: return "MPEG4 Loop Filter Enable"; -- case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB: return "Number of Intra Refresh MBs"; -- case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE: return "Frame Level Rate Control Enable"; -- case V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE: return "H264 MB Level Rate Control"; -- case V4L2_CID_MPEG_VIDEO_HEADER_MODE: return "Sequence Header Mode"; -- case V4L2_CID_MPEG_VIDEO_MAX_REF_PIC: return "Max Number of Reference Pics"; -- case V4L2_CID_MPEG_VIDEO_FRAME_SKIP_MODE: return "Frame Skip Mode"; -- case V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY: return "Display Delay"; -- case V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY_ENABLE: return "Display Delay Enable"; -- case V4L2_CID_MPEG_VIDEO_AU_DELIMITER: return "Generate Access Unit Delimiters"; -- case V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP: return "H263 I-Frame QP Value"; -- case V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP: return "H263 P-Frame QP Value"; -- case V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP: return "H263 B-Frame QP Value"; -- case V4L2_CID_MPEG_VIDEO_H263_MIN_QP: return "H263 Minimum QP Value"; -- case V4L2_CID_MPEG_VIDEO_H263_MAX_QP: return "H263 Maximum QP Value"; -- case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP: return "H264 I-Frame QP Value"; -- case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP: return "H264 P-Frame QP Value"; -- case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP: return "H264 B-Frame QP Value"; -- case V4L2_CID_MPEG_VIDEO_H264_MAX_QP: return "H264 Maximum QP Value"; -- case V4L2_CID_MPEG_VIDEO_H264_MIN_QP: return "H264 Minimum QP Value"; -- case V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM: return "H264 8x8 Transform Enable"; -- case V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE: return "H264 CPB Buffer Size"; -- case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE: return "H264 Entropy Mode"; -- case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD: return "H264 I-Frame Period"; -- case V4L2_CID_MPEG_VIDEO_H264_LEVEL: return "H264 Level"; -- case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA: return "H264 Loop Filter Alpha Offset"; -- case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA: return "H264 Loop Filter Beta Offset"; -- case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE: return "H264 Loop Filter Mode"; -- case V4L2_CID_MPEG_VIDEO_H264_PROFILE: return "H264 Profile"; -- case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT: return "Vertical Size of SAR"; -- case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH: return "Horizontal Size of SAR"; -- case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE: return "Aspect Ratio VUI Enable"; -- case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC: return "VUI Aspect Ratio IDC"; -- case V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING: return "H264 Enable Frame Packing SEI"; -- case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_CURRENT_FRAME_0: return "H264 Set Curr. Frame as Frame0"; -- case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE: return "H264 FP Arrangement Type"; -- case V4L2_CID_MPEG_VIDEO_H264_FMO: return "H264 Flexible MB Ordering"; -- case V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE: return "H264 Map Type for FMO"; -- case V4L2_CID_MPEG_VIDEO_H264_FMO_SLICE_GROUP: return "H264 FMO Number of Slice Groups"; -- case V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_DIRECTION: return "H264 FMO Direction of Change"; -- case V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_RATE: return "H264 FMO Size of 1st Slice Grp"; -- case V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH: return "H264 FMO No. of Consecutive MBs"; -- case V4L2_CID_MPEG_VIDEO_H264_ASO: return "H264 Arbitrary Slice Ordering"; -- case V4L2_CID_MPEG_VIDEO_H264_ASO_SLICE_ORDER: return "H264 ASO Slice Order"; -- case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING: return "Enable H264 Hierarchical Coding"; -- case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE: return "H264 Hierarchical Coding Type"; -- case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER:return "H264 Number of HC Layers"; -- case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP: -- return "H264 Set QP Value for HC Layers"; -- case V4L2_CID_MPEG_VIDEO_H264_CONSTRAINED_INTRA_PREDICTION: -- return "H264 Constrained Intra Pred"; -- case V4L2_CID_MPEG_VIDEO_H264_CHROMA_QP_INDEX_OFFSET: return "H264 Chroma QP Index Offset"; -- case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MIN_QP: return "H264 I-Frame Minimum QP Value"; -- case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MAX_QP: return "H264 I-Frame Maximum QP Value"; -- case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MIN_QP: return "H264 P-Frame Minimum QP Value"; -- case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MAX_QP: return "H264 P-Frame Maximum QP Value"; -- case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MIN_QP: return "H264 B-Frame Minimum QP Value"; -- case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MAX_QP: return "H264 B-Frame Maximum QP Value"; -- case V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L0_BR: return "H264 Hierarchical Lay 0 Bitrate"; -- case V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L1_BR: return "H264 Hierarchical Lay 1 Bitrate"; -- case V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L2_BR: return "H264 Hierarchical Lay 2 Bitrate"; -- case V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L3_BR: return "H264 Hierarchical Lay 3 Bitrate"; -- case V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L4_BR: return "H264 Hierarchical Lay 4 Bitrate"; -- case V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L5_BR: return "H264 Hierarchical Lay 5 Bitrate"; -- case V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L6_BR: return "H264 Hierarchical Lay 6 Bitrate"; -- case V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL: return "MPEG2 Level"; -- case V4L2_CID_MPEG_VIDEO_MPEG2_PROFILE: return "MPEG2 Profile"; -- case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP: return "MPEG4 I-Frame QP Value"; -- case V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP: return "MPEG4 P-Frame QP Value"; -- case V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP: return "MPEG4 B-Frame QP Value"; -- case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP: return "MPEG4 Minimum QP Value"; -- case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP: return "MPEG4 Maximum QP Value"; -- case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL: return "MPEG4 Level"; -- case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE: return "MPEG4 Profile"; -- case V4L2_CID_MPEG_VIDEO_MPEG4_QPEL: return "Quarter Pixel Search Enable"; -- case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES: return "Maximum Bytes in a Slice"; -- case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB: return "Number of MBs in a Slice"; -- case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE: return "Slice Partitioning Method"; -- case V4L2_CID_MPEG_VIDEO_VBV_SIZE: return "VBV Buffer Size"; -- case V4L2_CID_MPEG_VIDEO_DEC_PTS: return "Video Decoder PTS"; -- case V4L2_CID_MPEG_VIDEO_DEC_FRAME: return "Video Decoder Frame Count"; -- case V4L2_CID_MPEG_VIDEO_DEC_CONCEAL_COLOR: return "Video Decoder Conceal Color"; -- case V4L2_CID_MPEG_VIDEO_VBV_DELAY: return "Initial Delay for VBV Control"; -- case V4L2_CID_MPEG_VIDEO_MV_H_SEARCH_RANGE: return "Horizontal MV Search Range"; -- case V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE: return "Vertical MV Search Range"; -- case V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER: return "Repeat Sequence Header"; -- case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME: return "Force Key Frame"; -- case V4L2_CID_MPEG_VIDEO_BASELAYER_PRIORITY_ID: return "Base Layer Priority ID"; -- case V4L2_CID_MPEG_VIDEO_LTR_COUNT: return "LTR Count"; -- case V4L2_CID_MPEG_VIDEO_FRAME_LTR_INDEX: return "Frame LTR Index"; -- case V4L2_CID_MPEG_VIDEO_USE_LTR_FRAMES: return "Use LTR Frames"; -- case V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS: return "MPEG-2 Slice Parameters"; -- case V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION: return "MPEG-2 Quantization Matrices"; -- case V4L2_CID_FWHT_I_FRAME_QP: return "FWHT I-Frame QP Value"; -- case V4L2_CID_FWHT_P_FRAME_QP: return "FWHT P-Frame QP Value"; -- -- /* VPX controls */ -- case V4L2_CID_MPEG_VIDEO_VPX_NUM_PARTITIONS: return "VPX Number of Partitions"; -- case V4L2_CID_MPEG_VIDEO_VPX_IMD_DISABLE_4X4: return "VPX Intra Mode Decision Disable"; -- case V4L2_CID_MPEG_VIDEO_VPX_NUM_REF_FRAMES: return "VPX No. of Refs for P Frame"; -- case V4L2_CID_MPEG_VIDEO_VPX_FILTER_LEVEL: return "VPX Loop Filter Level Range"; -- case V4L2_CID_MPEG_VIDEO_VPX_FILTER_SHARPNESS: return "VPX Deblocking Effect Control"; -- case V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_REF_PERIOD: return "VPX Golden Frame Refresh Period"; -- case V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_SEL: return "VPX Golden Frame Indicator"; -- case V4L2_CID_MPEG_VIDEO_VPX_MIN_QP: return "VPX Minimum QP Value"; -- case V4L2_CID_MPEG_VIDEO_VPX_MAX_QP: return "VPX Maximum QP Value"; -- case V4L2_CID_MPEG_VIDEO_VPX_I_FRAME_QP: return "VPX I-Frame QP Value"; -- case V4L2_CID_MPEG_VIDEO_VPX_P_FRAME_QP: return "VPX P-Frame QP Value"; -- case V4L2_CID_MPEG_VIDEO_VP8_PROFILE: return "VP8 Profile"; -- case V4L2_CID_MPEG_VIDEO_VP9_PROFILE: return "VP9 Profile"; -- case V4L2_CID_MPEG_VIDEO_VP9_LEVEL: return "VP9 Level"; -- -- /* HEVC controls */ -- case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP: return "HEVC I-Frame QP Value"; -- case V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP: return "HEVC P-Frame QP Value"; -- case V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP: return "HEVC B-Frame QP Value"; -- case V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP: return "HEVC Minimum QP Value"; -- case V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP: return "HEVC Maximum QP Value"; -- case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MIN_QP: return "HEVC I-Frame Minimum QP Value"; -- case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MAX_QP: return "HEVC I-Frame Maximum QP Value"; -- case V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_MIN_QP: return "HEVC P-Frame Minimum QP Value"; -- case V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_MAX_QP: return "HEVC P-Frame Maximum QP Value"; -- case V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_MIN_QP: return "HEVC B-Frame Minimum QP Value"; -- case V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_MAX_QP: return "HEVC B-Frame Maximum QP Value"; -- case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE: return "HEVC Profile"; -- case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL: return "HEVC Level"; -- case V4L2_CID_MPEG_VIDEO_HEVC_TIER: return "HEVC Tier"; -- case V4L2_CID_MPEG_VIDEO_HEVC_FRAME_RATE_RESOLUTION: return "HEVC Frame Rate Resolution"; -- case V4L2_CID_MPEG_VIDEO_HEVC_MAX_PARTITION_DEPTH: return "HEVC Maximum Coding Unit Depth"; -- case V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_TYPE: return "HEVC Refresh Type"; -- case V4L2_CID_MPEG_VIDEO_HEVC_CONST_INTRA_PRED: return "HEVC Constant Intra Prediction"; -- case V4L2_CID_MPEG_VIDEO_HEVC_LOSSLESS_CU: return "HEVC Lossless Encoding"; -- case V4L2_CID_MPEG_VIDEO_HEVC_WAVEFRONT: return "HEVC Wavefront"; -- case V4L2_CID_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE: return "HEVC Loop Filter"; -- case V4L2_CID_MPEG_VIDEO_HEVC_HIER_QP: return "HEVC QP Values"; -- case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE: return "HEVC Hierarchical Coding Type"; -- case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER: return "HEVC Hierarchical Coding Layer"; -- case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_QP: return "HEVC Hierarchical Layer 0 QP"; -- case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_QP: return "HEVC Hierarchical Layer 1 QP"; -- case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_QP: return "HEVC Hierarchical Layer 2 QP"; -- case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_QP: return "HEVC Hierarchical Layer 3 QP"; -- case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_QP: return "HEVC Hierarchical Layer 4 QP"; -- case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_QP: return "HEVC Hierarchical Layer 5 QP"; -- case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L6_QP: return "HEVC Hierarchical Layer 6 QP"; -- case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_BR: return "HEVC Hierarchical Lay 0 BitRate"; -- case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_BR: return "HEVC Hierarchical Lay 1 BitRate"; -- case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_BR: return "HEVC Hierarchical Lay 2 BitRate"; -- case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_BR: return "HEVC Hierarchical Lay 3 BitRate"; -- case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_BR: return "HEVC Hierarchical Lay 4 BitRate"; -- case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_BR: return "HEVC Hierarchical Lay 5 BitRate"; -- case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L6_BR: return "HEVC Hierarchical Lay 6 BitRate"; -- case V4L2_CID_MPEG_VIDEO_HEVC_GENERAL_PB: return "HEVC General PB"; -- case V4L2_CID_MPEG_VIDEO_HEVC_TEMPORAL_ID: return "HEVC Temporal ID"; -- case V4L2_CID_MPEG_VIDEO_HEVC_STRONG_SMOOTHING: return "HEVC Strong Intra Smoothing"; -- case V4L2_CID_MPEG_VIDEO_HEVC_INTRA_PU_SPLIT: return "HEVC Intra PU Split"; -- case V4L2_CID_MPEG_VIDEO_HEVC_TMV_PREDICTION: return "HEVC TMV Prediction"; -- case V4L2_CID_MPEG_VIDEO_HEVC_MAX_NUM_MERGE_MV_MINUS1: return "HEVC Max Num of Candidate MVs"; -- case V4L2_CID_MPEG_VIDEO_HEVC_WITHOUT_STARTCODE: return "HEVC ENC Without Startcode"; -- case V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_PERIOD: return "HEVC Num of I-Frame b/w 2 IDR"; -- case V4L2_CID_MPEG_VIDEO_HEVC_LF_BETA_OFFSET_DIV2: return "HEVC Loop Filter Beta Offset"; -- case V4L2_CID_MPEG_VIDEO_HEVC_LF_TC_OFFSET_DIV2: return "HEVC Loop Filter TC Offset"; -- case V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD: return "HEVC Size of Length Field"; -- case V4L2_CID_MPEG_VIDEO_REF_NUMBER_FOR_PFRAMES: return "Reference Frames for a P-Frame"; -- case V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR: return "Prepend SPS and PPS to IDR"; -- case V4L2_CID_MPEG_VIDEO_HEVC_SPS: return "HEVC Sequence Parameter Set"; -- case V4L2_CID_MPEG_VIDEO_HEVC_PPS: return "HEVC Picture Parameter Set"; -- case V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS: return "HEVC Slice Parameters"; -- case V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX: return "HEVC Scaling Matrix"; -- case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE: return "HEVC Decode Mode"; -- case V4L2_CID_MPEG_VIDEO_HEVC_START_CODE: return "HEVC Start Code"; -- -- /* CAMERA controls */ -- /* Keep the order of the 'case's the same as in v4l2-controls.h! */ -- case V4L2_CID_CAMERA_CLASS: return "Camera Controls"; -- case V4L2_CID_EXPOSURE_AUTO: return "Auto Exposure"; -- case V4L2_CID_EXPOSURE_ABSOLUTE: return "Exposure Time, Absolute"; -- case V4L2_CID_EXPOSURE_AUTO_PRIORITY: return "Exposure, Dynamic Framerate"; -- case V4L2_CID_PAN_RELATIVE: return "Pan, Relative"; -- case V4L2_CID_TILT_RELATIVE: return "Tilt, Relative"; -- case V4L2_CID_PAN_RESET: return "Pan, Reset"; -- case V4L2_CID_TILT_RESET: return "Tilt, Reset"; -- case V4L2_CID_PAN_ABSOLUTE: return "Pan, Absolute"; -- case V4L2_CID_TILT_ABSOLUTE: return "Tilt, Absolute"; -- case V4L2_CID_FOCUS_ABSOLUTE: return "Focus, Absolute"; -- case V4L2_CID_FOCUS_RELATIVE: return "Focus, Relative"; -- case V4L2_CID_FOCUS_AUTO: return "Focus, Automatic Continuous"; -- case V4L2_CID_ZOOM_ABSOLUTE: return "Zoom, Absolute"; -- case V4L2_CID_ZOOM_RELATIVE: return "Zoom, Relative"; -- case V4L2_CID_ZOOM_CONTINUOUS: return "Zoom, Continuous"; -- case V4L2_CID_PRIVACY: return "Privacy"; -- case V4L2_CID_IRIS_ABSOLUTE: return "Iris, Absolute"; -- case V4L2_CID_IRIS_RELATIVE: return "Iris, Relative"; -- case V4L2_CID_AUTO_EXPOSURE_BIAS: return "Auto Exposure, Bias"; -- case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE: return "White Balance, Auto & Preset"; -- case V4L2_CID_WIDE_DYNAMIC_RANGE: return "Wide Dynamic Range"; -- case V4L2_CID_IMAGE_STABILIZATION: return "Image Stabilization"; -- case V4L2_CID_ISO_SENSITIVITY: return "ISO Sensitivity"; -- case V4L2_CID_ISO_SENSITIVITY_AUTO: return "ISO Sensitivity, Auto"; -- case V4L2_CID_EXPOSURE_METERING: return "Exposure, Metering Mode"; -- case V4L2_CID_SCENE_MODE: return "Scene Mode"; -- case V4L2_CID_3A_LOCK: return "3A Lock"; -- case V4L2_CID_AUTO_FOCUS_START: return "Auto Focus, Start"; -- case V4L2_CID_AUTO_FOCUS_STOP: return "Auto Focus, Stop"; -- case V4L2_CID_AUTO_FOCUS_STATUS: return "Auto Focus, Status"; -- case V4L2_CID_AUTO_FOCUS_RANGE: return "Auto Focus, Range"; -- case V4L2_CID_PAN_SPEED: return "Pan, Speed"; -- case V4L2_CID_TILT_SPEED: return "Tilt, Speed"; -- case V4L2_CID_UNIT_CELL_SIZE: return "Unit Cell Size"; -- case V4L2_CID_CAMERA_ORIENTATION: return "Camera Orientation"; -- case V4L2_CID_CAMERA_SENSOR_ROTATION: return "Camera Sensor Rotation"; -- -- /* FM Radio Modulator controls */ -- /* Keep the order of the 'case's the same as in v4l2-controls.h! */ -- case V4L2_CID_FM_TX_CLASS: return "FM Radio Modulator Controls"; -- case V4L2_CID_RDS_TX_DEVIATION: return "RDS Signal Deviation"; -- case V4L2_CID_RDS_TX_PI: return "RDS Program ID"; -- case V4L2_CID_RDS_TX_PTY: return "RDS Program Type"; -- case V4L2_CID_RDS_TX_PS_NAME: return "RDS PS Name"; -- case V4L2_CID_RDS_TX_RADIO_TEXT: return "RDS Radio Text"; -- case V4L2_CID_RDS_TX_MONO_STEREO: return "RDS Stereo"; -- case V4L2_CID_RDS_TX_ARTIFICIAL_HEAD: return "RDS Artificial Head"; -- case V4L2_CID_RDS_TX_COMPRESSED: return "RDS Compressed"; -- case V4L2_CID_RDS_TX_DYNAMIC_PTY: return "RDS Dynamic PTY"; -- case V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT: return "RDS Traffic Announcement"; -- case V4L2_CID_RDS_TX_TRAFFIC_PROGRAM: return "RDS Traffic Program"; -- case V4L2_CID_RDS_TX_MUSIC_SPEECH: return "RDS Music"; -- case V4L2_CID_RDS_TX_ALT_FREQS_ENABLE: return "RDS Enable Alt Frequencies"; -- case V4L2_CID_RDS_TX_ALT_FREQS: return "RDS Alternate Frequencies"; -- case V4L2_CID_AUDIO_LIMITER_ENABLED: return "Audio Limiter Feature Enabled"; -- case V4L2_CID_AUDIO_LIMITER_RELEASE_TIME: return "Audio Limiter Release Time"; -- case V4L2_CID_AUDIO_LIMITER_DEVIATION: return "Audio Limiter Deviation"; -- case V4L2_CID_AUDIO_COMPRESSION_ENABLED: return "Audio Compression Enabled"; -- case V4L2_CID_AUDIO_COMPRESSION_GAIN: return "Audio Compression Gain"; -- case V4L2_CID_AUDIO_COMPRESSION_THRESHOLD: return "Audio Compression Threshold"; -- case V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME: return "Audio Compression Attack Time"; -- case V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME: return "Audio Compression Release Time"; -- case V4L2_CID_PILOT_TONE_ENABLED: return "Pilot Tone Feature Enabled"; -- case V4L2_CID_PILOT_TONE_DEVIATION: return "Pilot Tone Deviation"; -- case V4L2_CID_PILOT_TONE_FREQUENCY: return "Pilot Tone Frequency"; -- case V4L2_CID_TUNE_PREEMPHASIS: return "Pre-Emphasis"; -- case V4L2_CID_TUNE_POWER_LEVEL: return "Tune Power Level"; -- case V4L2_CID_TUNE_ANTENNA_CAPACITOR: return "Tune Antenna Capacitor"; -- -- /* Flash controls */ -- /* Keep the order of the 'case's the same as in v4l2-controls.h! */ -- case V4L2_CID_FLASH_CLASS: return "Flash Controls"; -- case V4L2_CID_FLASH_LED_MODE: return "LED Mode"; -- case V4L2_CID_FLASH_STROBE_SOURCE: return "Strobe Source"; -- case V4L2_CID_FLASH_STROBE: return "Strobe"; -- case V4L2_CID_FLASH_STROBE_STOP: return "Stop Strobe"; -- case V4L2_CID_FLASH_STROBE_STATUS: return "Strobe Status"; -- case V4L2_CID_FLASH_TIMEOUT: return "Strobe Timeout"; -- case V4L2_CID_FLASH_INTENSITY: return "Intensity, Flash Mode"; -- case V4L2_CID_FLASH_TORCH_INTENSITY: return "Intensity, Torch Mode"; -- case V4L2_CID_FLASH_INDICATOR_INTENSITY: return "Intensity, Indicator"; -- case V4L2_CID_FLASH_FAULT: return "Faults"; -- case V4L2_CID_FLASH_CHARGE: return "Charge"; -- case V4L2_CID_FLASH_READY: return "Ready to Strobe"; -- -- /* JPEG encoder controls */ -- /* Keep the order of the 'case's the same as in v4l2-controls.h! */ -- case V4L2_CID_JPEG_CLASS: return "JPEG Compression Controls"; -- case V4L2_CID_JPEG_CHROMA_SUBSAMPLING: return "Chroma Subsampling"; -- case V4L2_CID_JPEG_RESTART_INTERVAL: return "Restart Interval"; -- case V4L2_CID_JPEG_COMPRESSION_QUALITY: return "Compression Quality"; -- case V4L2_CID_JPEG_ACTIVE_MARKER: return "Active Markers"; -- -- /* Image source controls */ -- /* Keep the order of the 'case's the same as in v4l2-controls.h! */ -- case V4L2_CID_IMAGE_SOURCE_CLASS: return "Image Source Controls"; -- case V4L2_CID_VBLANK: return "Vertical Blanking"; -- case V4L2_CID_HBLANK: return "Horizontal Blanking"; -- case V4L2_CID_ANALOGUE_GAIN: return "Analogue Gain"; -- case V4L2_CID_TEST_PATTERN_RED: return "Red Pixel Value"; -- case V4L2_CID_TEST_PATTERN_GREENR: return "Green (Red) Pixel Value"; -- case V4L2_CID_TEST_PATTERN_BLUE: return "Blue Pixel Value"; -- case V4L2_CID_TEST_PATTERN_GREENB: return "Green (Blue) Pixel Value"; -- -- /* Image processing controls */ -- /* Keep the order of the 'case's the same as in v4l2-controls.h! */ -- case V4L2_CID_IMAGE_PROC_CLASS: return "Image Processing Controls"; -- case V4L2_CID_LINK_FREQ: return "Link Frequency"; -- case V4L2_CID_PIXEL_RATE: return "Pixel Rate"; -- case V4L2_CID_TEST_PATTERN: return "Test Pattern"; -- case V4L2_CID_DEINTERLACING_MODE: return "Deinterlacing Mode"; -- case V4L2_CID_DIGITAL_GAIN: return "Digital Gain"; -- -- /* DV controls */ -- /* Keep the order of the 'case's the same as in v4l2-controls.h! */ -- case V4L2_CID_DV_CLASS: return "Digital Video Controls"; -- case V4L2_CID_DV_TX_HOTPLUG: return "Hotplug Present"; -- case V4L2_CID_DV_TX_RXSENSE: return "RxSense Present"; -- case V4L2_CID_DV_TX_EDID_PRESENT: return "EDID Present"; -- case V4L2_CID_DV_TX_MODE: return "Transmit Mode"; -- case V4L2_CID_DV_TX_RGB_RANGE: return "Tx RGB Quantization Range"; -- case V4L2_CID_DV_TX_IT_CONTENT_TYPE: return "Tx IT Content Type"; -- case V4L2_CID_DV_RX_POWER_PRESENT: return "Power Present"; -- case V4L2_CID_DV_RX_RGB_RANGE: return "Rx RGB Quantization Range"; -- case V4L2_CID_DV_RX_IT_CONTENT_TYPE: return "Rx IT Content Type"; -- -- case V4L2_CID_FM_RX_CLASS: return "FM Radio Receiver Controls"; -- case V4L2_CID_TUNE_DEEMPHASIS: return "De-Emphasis"; -- case V4L2_CID_RDS_RECEPTION: return "RDS Reception"; -- case V4L2_CID_RF_TUNER_CLASS: return "RF Tuner Controls"; -- case V4L2_CID_RF_TUNER_RF_GAIN: return "RF Gain"; -- case V4L2_CID_RF_TUNER_LNA_GAIN_AUTO: return "LNA Gain, Auto"; -- case V4L2_CID_RF_TUNER_LNA_GAIN: return "LNA Gain"; -- case V4L2_CID_RF_TUNER_MIXER_GAIN_AUTO: return "Mixer Gain, Auto"; -- case V4L2_CID_RF_TUNER_MIXER_GAIN: return "Mixer Gain"; -- case V4L2_CID_RF_TUNER_IF_GAIN_AUTO: return "IF Gain, Auto"; -- case V4L2_CID_RF_TUNER_IF_GAIN: return "IF Gain"; -- case V4L2_CID_RF_TUNER_BANDWIDTH_AUTO: return "Bandwidth, Auto"; -- case V4L2_CID_RF_TUNER_BANDWIDTH: return "Bandwidth"; -- case V4L2_CID_RF_TUNER_PLL_LOCK: return "PLL Lock"; -- case V4L2_CID_RDS_RX_PTY: return "RDS Program Type"; -- case V4L2_CID_RDS_RX_PS_NAME: return "RDS PS Name"; -- case V4L2_CID_RDS_RX_RADIO_TEXT: return "RDS Radio Text"; -- case V4L2_CID_RDS_RX_TRAFFIC_ANNOUNCEMENT: return "RDS Traffic Announcement"; -- case V4L2_CID_RDS_RX_TRAFFIC_PROGRAM: return "RDS Traffic Program"; -- case V4L2_CID_RDS_RX_MUSIC_SPEECH: return "RDS Music"; -- -- /* Detection controls */ -- /* Keep the order of the 'case's the same as in v4l2-controls.h! */ -- case V4L2_CID_DETECT_CLASS: return "Detection Controls"; -- case V4L2_CID_DETECT_MD_MODE: return "Motion Detection Mode"; -- case V4L2_CID_DETECT_MD_GLOBAL_THRESHOLD: return "MD Global Threshold"; -- case V4L2_CID_DETECT_MD_THRESHOLD_GRID: return "MD Threshold Grid"; -- case V4L2_CID_DETECT_MD_REGION_GRID: return "MD Region Grid"; -- -- /* Stateless Codec controls */ -- /* Keep the order of the 'case's the same as in v4l2-controls.h! */ -- case V4L2_CID_CODEC_STATELESS_CLASS: return "Stateless Codec Controls"; -- case V4L2_CID_STATELESS_H264_DECODE_MODE: return "H264 Decode Mode"; -- case V4L2_CID_STATELESS_H264_START_CODE: return "H264 Start Code"; -- case V4L2_CID_STATELESS_H264_SPS: return "H264 Sequence Parameter Set"; -- case V4L2_CID_STATELESS_H264_PPS: return "H264 Picture Parameter Set"; -- case V4L2_CID_STATELESS_H264_SCALING_MATRIX: return "H264 Scaling Matrix"; -- case V4L2_CID_STATELESS_H264_PRED_WEIGHTS: return "H264 Prediction Weight Table"; -- case V4L2_CID_STATELESS_H264_SLICE_PARAMS: return "H264 Slice Parameters"; -- case V4L2_CID_STATELESS_H264_DECODE_PARAMS: return "H264 Decode Parameters"; -- case V4L2_CID_STATELESS_FWHT_PARAMS: return "FWHT Stateless Parameters"; -- case V4L2_CID_STATELESS_VP8_FRAME: return "VP8 Frame Parameters"; -- -- /* Colorimetry controls */ -- /* Keep the order of the 'case's the same as in v4l2-controls.h! */ -- case V4L2_CID_COLORIMETRY_CLASS: return "Colorimetry Controls"; -- case V4L2_CID_COLORIMETRY_HDR10_CLL_INFO: return "HDR10 Content Light Info"; -- case V4L2_CID_COLORIMETRY_HDR10_MASTERING_DISPLAY: return "HDR10 Mastering Display"; -- default: -- return NULL; -- } --} --EXPORT_SYMBOL(v4l2_ctrl_get_name); -- --void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type, -- s64 *min, s64 *max, u64 *step, s64 *def, u32 *flags) --{ -- *name = v4l2_ctrl_get_name(id); -- *flags = 0; -- -- switch (id) { -- case V4L2_CID_AUDIO_MUTE: -- case V4L2_CID_AUDIO_LOUDNESS: -- case V4L2_CID_AUTO_WHITE_BALANCE: -- case V4L2_CID_AUTOGAIN: -- case V4L2_CID_HFLIP: -- case V4L2_CID_VFLIP: -- case V4L2_CID_HUE_AUTO: -- case V4L2_CID_CHROMA_AGC: -- case V4L2_CID_COLOR_KILLER: -- case V4L2_CID_AUTOBRIGHTNESS: -- case V4L2_CID_MPEG_AUDIO_MUTE: -- case V4L2_CID_MPEG_VIDEO_MUTE: -- case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: -- case V4L2_CID_MPEG_VIDEO_PULLDOWN: -- case V4L2_CID_EXPOSURE_AUTO_PRIORITY: -- case V4L2_CID_FOCUS_AUTO: -- case V4L2_CID_PRIVACY: -- case V4L2_CID_AUDIO_LIMITER_ENABLED: -- case V4L2_CID_AUDIO_COMPRESSION_ENABLED: -- case V4L2_CID_PILOT_TONE_ENABLED: -- case V4L2_CID_ILLUMINATORS_1: -- case V4L2_CID_ILLUMINATORS_2: -- case V4L2_CID_FLASH_STROBE_STATUS: -- case V4L2_CID_FLASH_CHARGE: -- case V4L2_CID_FLASH_READY: -- case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER: -- case V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE: -- case V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY_ENABLE: -- case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE: -- case V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE: -- case V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM: -- case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE: -- case V4L2_CID_MPEG_VIDEO_MPEG4_QPEL: -- case V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER: -- case V4L2_CID_MPEG_VIDEO_AU_DELIMITER: -- case V4L2_CID_WIDE_DYNAMIC_RANGE: -- case V4L2_CID_IMAGE_STABILIZATION: -- case V4L2_CID_RDS_RECEPTION: -- case V4L2_CID_RF_TUNER_LNA_GAIN_AUTO: -- case V4L2_CID_RF_TUNER_MIXER_GAIN_AUTO: -- case V4L2_CID_RF_TUNER_IF_GAIN_AUTO: -- case V4L2_CID_RF_TUNER_BANDWIDTH_AUTO: -- case V4L2_CID_RF_TUNER_PLL_LOCK: -- case V4L2_CID_RDS_TX_MONO_STEREO: -- case V4L2_CID_RDS_TX_ARTIFICIAL_HEAD: -- case V4L2_CID_RDS_TX_COMPRESSED: -- case V4L2_CID_RDS_TX_DYNAMIC_PTY: -- case V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT: -- case V4L2_CID_RDS_TX_TRAFFIC_PROGRAM: -- case V4L2_CID_RDS_TX_MUSIC_SPEECH: -- case V4L2_CID_RDS_TX_ALT_FREQS_ENABLE: -- case V4L2_CID_RDS_RX_TRAFFIC_ANNOUNCEMENT: -- case V4L2_CID_RDS_RX_TRAFFIC_PROGRAM: -- case V4L2_CID_RDS_RX_MUSIC_SPEECH: -- *type = V4L2_CTRL_TYPE_BOOLEAN; -- *min = 0; -- *max = *step = 1; -- break; -- case V4L2_CID_ROTATE: -- *type = V4L2_CTRL_TYPE_INTEGER; -- *flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT; -- break; -- case V4L2_CID_MPEG_VIDEO_MV_H_SEARCH_RANGE: -- case V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE: -- case V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY: -- *type = V4L2_CTRL_TYPE_INTEGER; -- break; -- case V4L2_CID_MPEG_VIDEO_LTR_COUNT: -- *type = V4L2_CTRL_TYPE_INTEGER; -- break; -- case V4L2_CID_MPEG_VIDEO_FRAME_LTR_INDEX: -- *type = V4L2_CTRL_TYPE_INTEGER; -- *flags |= V4L2_CTRL_FLAG_EXECUTE_ON_WRITE; -- break; -- case V4L2_CID_MPEG_VIDEO_USE_LTR_FRAMES: -- *type = V4L2_CTRL_TYPE_BITMASK; -- *flags |= V4L2_CTRL_FLAG_EXECUTE_ON_WRITE; -- break; -- case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME: -- case V4L2_CID_PAN_RESET: -- case V4L2_CID_TILT_RESET: -- case V4L2_CID_FLASH_STROBE: -- case V4L2_CID_FLASH_STROBE_STOP: -- case V4L2_CID_AUTO_FOCUS_START: -- case V4L2_CID_AUTO_FOCUS_STOP: -- case V4L2_CID_DO_WHITE_BALANCE: -- *type = V4L2_CTRL_TYPE_BUTTON; -- *flags |= V4L2_CTRL_FLAG_WRITE_ONLY | -- V4L2_CTRL_FLAG_EXECUTE_ON_WRITE; -- *min = *max = *step = *def = 0; -- break; -- case V4L2_CID_POWER_LINE_FREQUENCY: -- case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: -- case V4L2_CID_MPEG_AUDIO_ENCODING: -- case V4L2_CID_MPEG_AUDIO_L1_BITRATE: -- case V4L2_CID_MPEG_AUDIO_L2_BITRATE: -- case V4L2_CID_MPEG_AUDIO_L3_BITRATE: -- case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: -- case V4L2_CID_MPEG_AUDIO_MODE: -- case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: -- case V4L2_CID_MPEG_AUDIO_EMPHASIS: -- case V4L2_CID_MPEG_AUDIO_CRC: -- case V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK: -- case V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK: -- case V4L2_CID_MPEG_VIDEO_ENCODING: -- case V4L2_CID_MPEG_VIDEO_ASPECT: -- case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: -- case V4L2_CID_MPEG_STREAM_TYPE: -- case V4L2_CID_MPEG_STREAM_VBI_FMT: -- case V4L2_CID_EXPOSURE_AUTO: -- case V4L2_CID_AUTO_FOCUS_RANGE: -- case V4L2_CID_COLORFX: -- case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE: -- case V4L2_CID_TUNE_PREEMPHASIS: -- case V4L2_CID_FLASH_LED_MODE: -- case V4L2_CID_FLASH_STROBE_SOURCE: -- case V4L2_CID_MPEG_VIDEO_HEADER_MODE: -- case V4L2_CID_MPEG_VIDEO_FRAME_SKIP_MODE: -- case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE: -- case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE: -- case V4L2_CID_MPEG_VIDEO_H264_LEVEL: -- case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE: -- case V4L2_CID_MPEG_VIDEO_H264_PROFILE: -- case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC: -- case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE: -- case V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE: -- case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE: -- case V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL: -- case V4L2_CID_MPEG_VIDEO_MPEG2_PROFILE: -- case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL: -- case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE: -- case V4L2_CID_JPEG_CHROMA_SUBSAMPLING: -- case V4L2_CID_ISO_SENSITIVITY_AUTO: -- case V4L2_CID_EXPOSURE_METERING: -- case V4L2_CID_SCENE_MODE: -- case V4L2_CID_DV_TX_MODE: -- case V4L2_CID_DV_TX_RGB_RANGE: -- case V4L2_CID_DV_TX_IT_CONTENT_TYPE: -- case V4L2_CID_DV_RX_RGB_RANGE: -- case V4L2_CID_DV_RX_IT_CONTENT_TYPE: -- case V4L2_CID_TEST_PATTERN: -- case V4L2_CID_DEINTERLACING_MODE: -- case V4L2_CID_TUNE_DEEMPHASIS: -- case V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_SEL: -- case V4L2_CID_MPEG_VIDEO_VP8_PROFILE: -- case V4L2_CID_MPEG_VIDEO_VP9_PROFILE: -- case V4L2_CID_MPEG_VIDEO_VP9_LEVEL: -- case V4L2_CID_DETECT_MD_MODE: -- case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE: -- case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL: -- case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE: -- case V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_TYPE: -- case V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD: -- case V4L2_CID_MPEG_VIDEO_HEVC_TIER: -- case V4L2_CID_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE: -- case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE: -- case V4L2_CID_MPEG_VIDEO_HEVC_START_CODE: -- case V4L2_CID_STATELESS_H264_DECODE_MODE: -- case V4L2_CID_STATELESS_H264_START_CODE: -- case V4L2_CID_CAMERA_ORIENTATION: -- *type = V4L2_CTRL_TYPE_MENU; -- break; -- case V4L2_CID_LINK_FREQ: -- *type = V4L2_CTRL_TYPE_INTEGER_MENU; -- break; -- case V4L2_CID_RDS_TX_PS_NAME: -- case V4L2_CID_RDS_TX_RADIO_TEXT: -- case V4L2_CID_RDS_RX_PS_NAME: -- case V4L2_CID_RDS_RX_RADIO_TEXT: -- *type = V4L2_CTRL_TYPE_STRING; -- break; -- case V4L2_CID_ISO_SENSITIVITY: -- case V4L2_CID_AUTO_EXPOSURE_BIAS: -- case V4L2_CID_MPEG_VIDEO_VPX_NUM_PARTITIONS: -- case V4L2_CID_MPEG_VIDEO_VPX_NUM_REF_FRAMES: -- *type = V4L2_CTRL_TYPE_INTEGER_MENU; -- break; -- case V4L2_CID_USER_CLASS: -- case V4L2_CID_CAMERA_CLASS: -- case V4L2_CID_CODEC_CLASS: -- case V4L2_CID_FM_TX_CLASS: -- case V4L2_CID_FLASH_CLASS: -- case V4L2_CID_JPEG_CLASS: -- case V4L2_CID_IMAGE_SOURCE_CLASS: -- case V4L2_CID_IMAGE_PROC_CLASS: -- case V4L2_CID_DV_CLASS: -- case V4L2_CID_FM_RX_CLASS: -- case V4L2_CID_RF_TUNER_CLASS: -- case V4L2_CID_DETECT_CLASS: -- case V4L2_CID_CODEC_STATELESS_CLASS: -- case V4L2_CID_COLORIMETRY_CLASS: -- *type = V4L2_CTRL_TYPE_CTRL_CLASS; -- /* You can neither read nor write these */ -- *flags |= V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY; -- *min = *max = *step = *def = 0; -- break; -- case V4L2_CID_BG_COLOR: -- *type = V4L2_CTRL_TYPE_INTEGER; -- *step = 1; -- *min = 0; -- /* Max is calculated as RGB888 that is 2^24 */ -- *max = 0xFFFFFF; -- break; -- case V4L2_CID_FLASH_FAULT: -- case V4L2_CID_JPEG_ACTIVE_MARKER: -- case V4L2_CID_3A_LOCK: -- case V4L2_CID_AUTO_FOCUS_STATUS: -- case V4L2_CID_DV_TX_HOTPLUG: -- case V4L2_CID_DV_TX_RXSENSE: -- case V4L2_CID_DV_TX_EDID_PRESENT: -- case V4L2_CID_DV_RX_POWER_PRESENT: -- *type = V4L2_CTRL_TYPE_BITMASK; -- break; -- case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE: -- case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT: -- *type = V4L2_CTRL_TYPE_INTEGER; -- *flags |= V4L2_CTRL_FLAG_READ_ONLY; -- break; -- case V4L2_CID_MPEG_VIDEO_DEC_PTS: -- *type = V4L2_CTRL_TYPE_INTEGER64; -- *flags |= V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY; -- *min = *def = 0; -- *max = 0x1ffffffffLL; -- *step = 1; -- break; -- case V4L2_CID_MPEG_VIDEO_DEC_FRAME: -- *type = V4L2_CTRL_TYPE_INTEGER64; -- *flags |= V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY; -- *min = *def = 0; -- *max = 0x7fffffffffffffffLL; -- *step = 1; -- break; -- case V4L2_CID_MPEG_VIDEO_DEC_CONCEAL_COLOR: -- *type = V4L2_CTRL_TYPE_INTEGER64; -- *min = 0; -- /* default for 8 bit black, luma is 16, chroma is 128 */ -- *def = 0x8000800010LL; -- *max = 0xffffffffffffLL; -- *step = 1; -- break; -- case V4L2_CID_PIXEL_RATE: -- *type = V4L2_CTRL_TYPE_INTEGER64; -- *flags |= V4L2_CTRL_FLAG_READ_ONLY; -- break; -- case V4L2_CID_DETECT_MD_REGION_GRID: -- *type = V4L2_CTRL_TYPE_U8; -- break; -- case V4L2_CID_DETECT_MD_THRESHOLD_GRID: -- *type = V4L2_CTRL_TYPE_U16; -- break; -- case V4L2_CID_RDS_TX_ALT_FREQS: -- *type = V4L2_CTRL_TYPE_U32; -- break; -- case V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS: -- *type = V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS; -- break; -- case V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION: -- *type = V4L2_CTRL_TYPE_MPEG2_QUANTIZATION; -- break; -- case V4L2_CID_STATELESS_FWHT_PARAMS: -- *type = V4L2_CTRL_TYPE_FWHT_PARAMS; -- break; -- case V4L2_CID_STATELESS_H264_SPS: -- *type = V4L2_CTRL_TYPE_H264_SPS; -- break; -- case V4L2_CID_STATELESS_H264_PPS: -- *type = V4L2_CTRL_TYPE_H264_PPS; -- break; -- case V4L2_CID_STATELESS_H264_SCALING_MATRIX: -- *type = V4L2_CTRL_TYPE_H264_SCALING_MATRIX; -- break; -- case V4L2_CID_STATELESS_H264_SLICE_PARAMS: -- *type = V4L2_CTRL_TYPE_H264_SLICE_PARAMS; -- break; -- case V4L2_CID_STATELESS_H264_DECODE_PARAMS: -- *type = V4L2_CTRL_TYPE_H264_DECODE_PARAMS; -- break; -- case V4L2_CID_STATELESS_H264_PRED_WEIGHTS: -- *type = V4L2_CTRL_TYPE_H264_PRED_WEIGHTS; -- break; -- case V4L2_CID_STATELESS_VP8_FRAME: -- *type = V4L2_CTRL_TYPE_VP8_FRAME; -- break; -- case V4L2_CID_MPEG_VIDEO_HEVC_SPS: -- *type = V4L2_CTRL_TYPE_HEVC_SPS; -- break; -- case V4L2_CID_MPEG_VIDEO_HEVC_PPS: -- *type = V4L2_CTRL_TYPE_HEVC_PPS; -- break; -- case V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS: -- *type = V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS; -- break; -- case V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX: -- *type = V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX; -- break; -- case V4L2_CID_UNIT_CELL_SIZE: -- *type = V4L2_CTRL_TYPE_AREA; -- *flags |= V4L2_CTRL_FLAG_READ_ONLY; -- break; -- case V4L2_CID_COLORIMETRY_HDR10_CLL_INFO: -- *type = V4L2_CTRL_TYPE_HDR10_CLL_INFO; -- break; -- case V4L2_CID_COLORIMETRY_HDR10_MASTERING_DISPLAY: -- *type = V4L2_CTRL_TYPE_HDR10_MASTERING_DISPLAY; -- break; -- default: -- *type = V4L2_CTRL_TYPE_INTEGER; -- break; -- } -- switch (id) { -- case V4L2_CID_MPEG_AUDIO_ENCODING: -- case V4L2_CID_MPEG_AUDIO_MODE: -- case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: -- case V4L2_CID_MPEG_VIDEO_B_FRAMES: -- case V4L2_CID_MPEG_STREAM_TYPE: -- *flags |= V4L2_CTRL_FLAG_UPDATE; -- break; -- case V4L2_CID_AUDIO_VOLUME: -- case V4L2_CID_AUDIO_BALANCE: -- case V4L2_CID_AUDIO_BASS: -- case V4L2_CID_AUDIO_TREBLE: -- case V4L2_CID_BRIGHTNESS: -- case V4L2_CID_CONTRAST: -- case V4L2_CID_SATURATION: -- case V4L2_CID_HUE: -- case V4L2_CID_RED_BALANCE: -- case V4L2_CID_BLUE_BALANCE: -- case V4L2_CID_GAMMA: -- case V4L2_CID_SHARPNESS: -- case V4L2_CID_CHROMA_GAIN: -- case V4L2_CID_RDS_TX_DEVIATION: -- case V4L2_CID_AUDIO_LIMITER_RELEASE_TIME: -- case V4L2_CID_AUDIO_LIMITER_DEVIATION: -- case V4L2_CID_AUDIO_COMPRESSION_GAIN: -- case V4L2_CID_AUDIO_COMPRESSION_THRESHOLD: -- case V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME: -- case V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME: -- case V4L2_CID_PILOT_TONE_DEVIATION: -- case V4L2_CID_PILOT_TONE_FREQUENCY: -- case V4L2_CID_TUNE_POWER_LEVEL: -- case V4L2_CID_TUNE_ANTENNA_CAPACITOR: -- case V4L2_CID_RF_TUNER_RF_GAIN: -- case V4L2_CID_RF_TUNER_LNA_GAIN: -- case V4L2_CID_RF_TUNER_MIXER_GAIN: -- case V4L2_CID_RF_TUNER_IF_GAIN: -- case V4L2_CID_RF_TUNER_BANDWIDTH: -- case V4L2_CID_DETECT_MD_GLOBAL_THRESHOLD: -- *flags |= V4L2_CTRL_FLAG_SLIDER; -- break; -- case V4L2_CID_PAN_RELATIVE: -- case V4L2_CID_TILT_RELATIVE: -- case V4L2_CID_FOCUS_RELATIVE: -- case V4L2_CID_IRIS_RELATIVE: -- case V4L2_CID_ZOOM_RELATIVE: -- *flags |= V4L2_CTRL_FLAG_WRITE_ONLY | -- V4L2_CTRL_FLAG_EXECUTE_ON_WRITE; -- break; -- case V4L2_CID_FLASH_STROBE_STATUS: -- case V4L2_CID_AUTO_FOCUS_STATUS: -- case V4L2_CID_FLASH_READY: -- case V4L2_CID_DV_TX_HOTPLUG: -- case V4L2_CID_DV_TX_RXSENSE: -- case V4L2_CID_DV_TX_EDID_PRESENT: -- case V4L2_CID_DV_RX_POWER_PRESENT: -- case V4L2_CID_DV_RX_IT_CONTENT_TYPE: -- case V4L2_CID_RDS_RX_PTY: -- case V4L2_CID_RDS_RX_PS_NAME: -- case V4L2_CID_RDS_RX_RADIO_TEXT: -- case V4L2_CID_RDS_RX_TRAFFIC_ANNOUNCEMENT: -- case V4L2_CID_RDS_RX_TRAFFIC_PROGRAM: -- case V4L2_CID_RDS_RX_MUSIC_SPEECH: -- case V4L2_CID_CAMERA_ORIENTATION: -- case V4L2_CID_CAMERA_SENSOR_ROTATION: -- *flags |= V4L2_CTRL_FLAG_READ_ONLY; -- break; -- case V4L2_CID_RF_TUNER_PLL_LOCK: -- *flags |= V4L2_CTRL_FLAG_VOLATILE; -- break; -- } --} --EXPORT_SYMBOL(v4l2_ctrl_fill); -- --static u32 user_flags(const struct v4l2_ctrl *ctrl) --{ -- u32 flags = ctrl->flags; -- -- if (ctrl->is_ptr) -- flags |= V4L2_CTRL_FLAG_HAS_PAYLOAD; -- -- return flags; --} -- --static void fill_event(struct v4l2_event *ev, struct v4l2_ctrl *ctrl, u32 changes) --{ -- memset(ev, 0, sizeof(*ev)); -- ev->type = V4L2_EVENT_CTRL; -- ev->id = ctrl->id; -- ev->u.ctrl.changes = changes; -- ev->u.ctrl.type = ctrl->type; -- ev->u.ctrl.flags = user_flags(ctrl); -- if (ctrl->is_ptr) -- ev->u.ctrl.value64 = 0; -- else -- ev->u.ctrl.value64 = *ctrl->p_cur.p_s64; -- ev->u.ctrl.minimum = ctrl->minimum; -- ev->u.ctrl.maximum = ctrl->maximum; -- if (ctrl->type == V4L2_CTRL_TYPE_MENU -- || ctrl->type == V4L2_CTRL_TYPE_INTEGER_MENU) -- ev->u.ctrl.step = 1; -- else -- ev->u.ctrl.step = ctrl->step; -- ev->u.ctrl.default_value = ctrl->default_value; --} -- --static void send_event(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, u32 changes) --{ -- struct v4l2_event ev; -- struct v4l2_subscribed_event *sev; -- -- if (list_empty(&ctrl->ev_subs)) -- return; -- fill_event(&ev, ctrl, changes); -- -- list_for_each_entry(sev, &ctrl->ev_subs, node) -- if (sev->fh != fh || -- (sev->flags & V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK)) -- v4l2_event_queue_fh(sev->fh, &ev); --} -- --static bool std_equal(const struct v4l2_ctrl *ctrl, u32 idx, -- union v4l2_ctrl_ptr ptr1, -- union v4l2_ctrl_ptr ptr2) --{ -- switch (ctrl->type) { -- case V4L2_CTRL_TYPE_BUTTON: -- return false; -- case V4L2_CTRL_TYPE_STRING: -- idx *= ctrl->elem_size; -- /* strings are always 0-terminated */ -- return !strcmp(ptr1.p_char + idx, ptr2.p_char + idx); -- case V4L2_CTRL_TYPE_INTEGER64: -- return ptr1.p_s64[idx] == ptr2.p_s64[idx]; -- case V4L2_CTRL_TYPE_U8: -- return ptr1.p_u8[idx] == ptr2.p_u8[idx]; -- case V4L2_CTRL_TYPE_U16: -- return ptr1.p_u16[idx] == ptr2.p_u16[idx]; -- case V4L2_CTRL_TYPE_U32: -- return ptr1.p_u32[idx] == ptr2.p_u32[idx]; -- default: -- if (ctrl->is_int) -- return ptr1.p_s32[idx] == ptr2.p_s32[idx]; -- idx *= ctrl->elem_size; -- return !memcmp(ptr1.p_const + idx, ptr2.p_const + idx, -- ctrl->elem_size); -- } --} -- --static void std_init_compound(const struct v4l2_ctrl *ctrl, u32 idx, -- union v4l2_ctrl_ptr ptr) --{ -- struct v4l2_ctrl_mpeg2_slice_params *p_mpeg2_slice_params; -- struct v4l2_ctrl_vp8_frame *p_vp8_frame; -- struct v4l2_ctrl_fwht_params *p_fwht_params; -- void *p = ptr.p + idx * ctrl->elem_size; -- -- if (ctrl->p_def.p_const) -- memcpy(p, ctrl->p_def.p_const, ctrl->elem_size); -- else -- memset(p, 0, ctrl->elem_size); -- -- /* -- * The cast is needed to get rid of a gcc warning complaining that -- * V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS is not part of the -- * v4l2_ctrl_type enum. -- */ -- switch ((u32)ctrl->type) { -- case V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS: -- p_mpeg2_slice_params = p; -- /* 4:2:0 */ -- p_mpeg2_slice_params->sequence.chroma_format = 1; -- /* interlaced top field */ -- p_mpeg2_slice_params->picture.picture_structure = 1; -- p_mpeg2_slice_params->picture.picture_coding_type = -- V4L2_MPEG2_PICTURE_CODING_TYPE_I; -- break; -- case V4L2_CTRL_TYPE_VP8_FRAME: -- p_vp8_frame = p; -- p_vp8_frame->num_dct_parts = 1; -- break; -- case V4L2_CTRL_TYPE_FWHT_PARAMS: -- p_fwht_params = p; -- p_fwht_params->version = V4L2_FWHT_VERSION; -- p_fwht_params->width = 1280; -- p_fwht_params->height = 720; -- p_fwht_params->flags = V4L2_FWHT_FL_PIXENC_YUV | -- (2 << V4L2_FWHT_FL_COMPONENTS_NUM_OFFSET); -- break; -- } --} -- --static void std_init(const struct v4l2_ctrl *ctrl, u32 idx, -- union v4l2_ctrl_ptr ptr) --{ -- switch (ctrl->type) { -- case V4L2_CTRL_TYPE_STRING: -- idx *= ctrl->elem_size; -- memset(ptr.p_char + idx, ' ', ctrl->minimum); -- ptr.p_char[idx + ctrl->minimum] = '\0'; -- break; -- case V4L2_CTRL_TYPE_INTEGER64: -- ptr.p_s64[idx] = ctrl->default_value; -- break; -- case V4L2_CTRL_TYPE_INTEGER: -- case V4L2_CTRL_TYPE_INTEGER_MENU: -- case V4L2_CTRL_TYPE_MENU: -- case V4L2_CTRL_TYPE_BITMASK: -- case V4L2_CTRL_TYPE_BOOLEAN: -- ptr.p_s32[idx] = ctrl->default_value; -- break; -- case V4L2_CTRL_TYPE_BUTTON: -- case V4L2_CTRL_TYPE_CTRL_CLASS: -- ptr.p_s32[idx] = 0; -- break; -- case V4L2_CTRL_TYPE_U8: -- ptr.p_u8[idx] = ctrl->default_value; -- break; -- case V4L2_CTRL_TYPE_U16: -- ptr.p_u16[idx] = ctrl->default_value; -- break; -- case V4L2_CTRL_TYPE_U32: -- ptr.p_u32[idx] = ctrl->default_value; -- break; -- default: -- std_init_compound(ctrl, idx, ptr); -- break; -- } --} -- --static void std_log(const struct v4l2_ctrl *ctrl) --{ -- union v4l2_ctrl_ptr ptr = ctrl->p_cur; -- -- if (ctrl->is_array) { -- unsigned i; -- -- for (i = 0; i < ctrl->nr_of_dims; i++) -- pr_cont("[%u]", ctrl->dims[i]); -- pr_cont(" "); -- } -- -- switch (ctrl->type) { -- case V4L2_CTRL_TYPE_INTEGER: -- pr_cont("%d", *ptr.p_s32); -- break; -- case V4L2_CTRL_TYPE_BOOLEAN: -- pr_cont("%s", *ptr.p_s32 ? "true" : "false"); -- break; -- case V4L2_CTRL_TYPE_MENU: -- pr_cont("%s", ctrl->qmenu[*ptr.p_s32]); -- break; -- case V4L2_CTRL_TYPE_INTEGER_MENU: -- pr_cont("%lld", ctrl->qmenu_int[*ptr.p_s32]); -- break; -- case V4L2_CTRL_TYPE_BITMASK: -- pr_cont("0x%08x", *ptr.p_s32); -- break; -- case V4L2_CTRL_TYPE_INTEGER64: -- pr_cont("%lld", *ptr.p_s64); -- break; -- case V4L2_CTRL_TYPE_STRING: -- pr_cont("%s", ptr.p_char); -- break; -- case V4L2_CTRL_TYPE_U8: -- pr_cont("%u", (unsigned)*ptr.p_u8); -- break; -- case V4L2_CTRL_TYPE_U16: -- pr_cont("%u", (unsigned)*ptr.p_u16); -- break; -- case V4L2_CTRL_TYPE_U32: -- pr_cont("%u", (unsigned)*ptr.p_u32); -- break; -- case V4L2_CTRL_TYPE_H264_SPS: -- pr_cont("H264_SPS"); -- break; -- case V4L2_CTRL_TYPE_H264_PPS: -- pr_cont("H264_PPS"); -- break; -- case V4L2_CTRL_TYPE_H264_SCALING_MATRIX: -- pr_cont("H264_SCALING_MATRIX"); -- break; -- case V4L2_CTRL_TYPE_H264_SLICE_PARAMS: -- pr_cont("H264_SLICE_PARAMS"); -- break; -- case V4L2_CTRL_TYPE_H264_DECODE_PARAMS: -- pr_cont("H264_DECODE_PARAMS"); -- break; -- case V4L2_CTRL_TYPE_H264_PRED_WEIGHTS: -- pr_cont("H264_PRED_WEIGHTS"); -- break; -- case V4L2_CTRL_TYPE_FWHT_PARAMS: -- pr_cont("FWHT_PARAMS"); -- break; -- case V4L2_CTRL_TYPE_VP8_FRAME: -- pr_cont("VP8_FRAME"); -- break; -- case V4L2_CTRL_TYPE_HDR10_CLL_INFO: -- pr_cont("HDR10_CLL_INFO"); -- break; -- case V4L2_CTRL_TYPE_HDR10_MASTERING_DISPLAY: -- pr_cont("HDR10_MASTERING_DISPLAY"); -- break; -- default: -- pr_cont("unknown type %d", ctrl->type); -- break; -- } --} -- --/* -- * Round towards the closest legal value. Be careful when we are -- * close to the maximum range of the control type to prevent -- * wrap-arounds. -- */ --#define ROUND_TO_RANGE(val, offset_type, ctrl) \ --({ \ -- offset_type offset; \ -- if ((ctrl)->maximum >= 0 && \ -- val >= (ctrl)->maximum - (s32)((ctrl)->step / 2)) \ -- val = (ctrl)->maximum; \ -- else \ -- val += (s32)((ctrl)->step / 2); \ -- val = clamp_t(typeof(val), val, \ -- (ctrl)->minimum, (ctrl)->maximum); \ -- offset = (val) - (ctrl)->minimum; \ -- offset = (ctrl)->step * (offset / (u32)(ctrl)->step); \ -- val = (ctrl)->minimum + offset; \ -- 0; \ --}) -- --/* Validate a new control */ -- --#define zero_padding(s) \ -- memset(&(s).padding, 0, sizeof((s).padding)) --#define zero_reserved(s) \ -- memset(&(s).reserved, 0, sizeof((s).reserved)) -- --/* -- * Compound controls validation requires setting unused fields/flags to zero -- * in order to properly detect unchanged controls with std_equal's memcmp. -- */ --static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx, -- union v4l2_ctrl_ptr ptr) --{ -- struct v4l2_ctrl_mpeg2_slice_params *p_mpeg2_slice_params; -- struct v4l2_ctrl_vp8_frame *p_vp8_frame; -- struct v4l2_ctrl_fwht_params *p_fwht_params; -- struct v4l2_ctrl_h264_sps *p_h264_sps; -- struct v4l2_ctrl_h264_pps *p_h264_pps; -- struct v4l2_ctrl_h264_pred_weights *p_h264_pred_weights; -- struct v4l2_ctrl_h264_slice_params *p_h264_slice_params; -- struct v4l2_ctrl_h264_decode_params *p_h264_dec_params; -- struct v4l2_ctrl_hevc_sps *p_hevc_sps; -- struct v4l2_ctrl_hevc_pps *p_hevc_pps; -- struct v4l2_ctrl_hevc_slice_params *p_hevc_slice_params; -- struct v4l2_ctrl_hdr10_mastering_display *p_hdr10_mastering; -- struct v4l2_area *area; -- void *p = ptr.p + idx * ctrl->elem_size; -- unsigned int i; -- -- switch ((u32)ctrl->type) { -- case V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS: -- p_mpeg2_slice_params = p; -- -- switch (p_mpeg2_slice_params->sequence.chroma_format) { -- case 1: /* 4:2:0 */ -- case 2: /* 4:2:2 */ -- case 3: /* 4:4:4 */ -- break; -- default: -- return -EINVAL; -- } -- -- switch (p_mpeg2_slice_params->picture.intra_dc_precision) { -- case 0: /* 8 bits */ -- case 1: /* 9 bits */ -- case 2: /* 10 bits */ -- case 3: /* 11 bits */ -- break; -- default: -- return -EINVAL; -- } -- -- switch (p_mpeg2_slice_params->picture.picture_structure) { -- case 1: /* interlaced top field */ -- case 2: /* interlaced bottom field */ -- case 3: /* progressive */ -- break; -- default: -- return -EINVAL; -- } -- -- switch (p_mpeg2_slice_params->picture.picture_coding_type) { -- case V4L2_MPEG2_PICTURE_CODING_TYPE_I: -- case V4L2_MPEG2_PICTURE_CODING_TYPE_P: -- case V4L2_MPEG2_PICTURE_CODING_TYPE_B: -- break; -- default: -- return -EINVAL; -- } -- -- break; -- -- case V4L2_CTRL_TYPE_MPEG2_QUANTIZATION: -- break; -- -- case V4L2_CTRL_TYPE_FWHT_PARAMS: -- p_fwht_params = p; -- if (p_fwht_params->version < V4L2_FWHT_VERSION) -- return -EINVAL; -- if (!p_fwht_params->width || !p_fwht_params->height) -- return -EINVAL; -- break; -- -- case V4L2_CTRL_TYPE_H264_SPS: -- p_h264_sps = p; -- -- /* Some syntax elements are only conditionally valid */ -- if (p_h264_sps->pic_order_cnt_type != 0) { -- p_h264_sps->log2_max_pic_order_cnt_lsb_minus4 = 0; -- } else if (p_h264_sps->pic_order_cnt_type != 1) { -- p_h264_sps->num_ref_frames_in_pic_order_cnt_cycle = 0; -- p_h264_sps->offset_for_non_ref_pic = 0; -- p_h264_sps->offset_for_top_to_bottom_field = 0; -- memset(&p_h264_sps->offset_for_ref_frame, 0, -- sizeof(p_h264_sps->offset_for_ref_frame)); -- } -- -- if (!V4L2_H264_SPS_HAS_CHROMA_FORMAT(p_h264_sps)) { -- p_h264_sps->chroma_format_idc = 1; -- p_h264_sps->bit_depth_luma_minus8 = 0; -- p_h264_sps->bit_depth_chroma_minus8 = 0; -- -- p_h264_sps->flags &= -- ~V4L2_H264_SPS_FLAG_QPPRIME_Y_ZERO_TRANSFORM_BYPASS; -- -- if (p_h264_sps->chroma_format_idc < 3) -- p_h264_sps->flags &= -- ~V4L2_H264_SPS_FLAG_SEPARATE_COLOUR_PLANE; -- } -- -- if (p_h264_sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY) -- p_h264_sps->flags &= -- ~V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD; -- -- /* -- * Chroma 4:2:2 format require at least High 4:2:2 profile. -- * -- * The H264 specification and well-known parser implementations -- * use profile-idc values directly, as that is clearer and -- * less ambiguous. We do the same here. -- */ -- if (p_h264_sps->profile_idc < 122 && -- p_h264_sps->chroma_format_idc > 1) -- return -EINVAL; -- /* Chroma 4:4:4 format require at least High 4:2:2 profile */ -- if (p_h264_sps->profile_idc < 244 && -- p_h264_sps->chroma_format_idc > 2) -- return -EINVAL; -- if (p_h264_sps->chroma_format_idc > 3) -- return -EINVAL; -- -- if (p_h264_sps->bit_depth_luma_minus8 > 6) -- return -EINVAL; -- if (p_h264_sps->bit_depth_chroma_minus8 > 6) -- return -EINVAL; -- if (p_h264_sps->log2_max_frame_num_minus4 > 12) -- return -EINVAL; -- if (p_h264_sps->pic_order_cnt_type > 2) -- return -EINVAL; -- if (p_h264_sps->log2_max_pic_order_cnt_lsb_minus4 > 12) -- return -EINVAL; -- if (p_h264_sps->max_num_ref_frames > V4L2_H264_REF_LIST_LEN) -- return -EINVAL; -- break; -- -- case V4L2_CTRL_TYPE_H264_PPS: -- p_h264_pps = p; -- -- if (p_h264_pps->num_slice_groups_minus1 > 7) -- return -EINVAL; -- if (p_h264_pps->num_ref_idx_l0_default_active_minus1 > -- (V4L2_H264_REF_LIST_LEN - 1)) -- return -EINVAL; -- if (p_h264_pps->num_ref_idx_l1_default_active_minus1 > -- (V4L2_H264_REF_LIST_LEN - 1)) -- return -EINVAL; -- if (p_h264_pps->weighted_bipred_idc > 2) -- return -EINVAL; -- /* -- * pic_init_qp_minus26 shall be in the range of -- * -(26 + QpBdOffset_y) to +25, inclusive, -- * where QpBdOffset_y is 6 * bit_depth_luma_minus8 -- */ -- if (p_h264_pps->pic_init_qp_minus26 < -62 || -- p_h264_pps->pic_init_qp_minus26 > 25) -- return -EINVAL; -- if (p_h264_pps->pic_init_qs_minus26 < -26 || -- p_h264_pps->pic_init_qs_minus26 > 25) -- return -EINVAL; -- if (p_h264_pps->chroma_qp_index_offset < -12 || -- p_h264_pps->chroma_qp_index_offset > 12) -- return -EINVAL; -- if (p_h264_pps->second_chroma_qp_index_offset < -12 || -- p_h264_pps->second_chroma_qp_index_offset > 12) -- return -EINVAL; -- break; -- -- case V4L2_CTRL_TYPE_H264_SCALING_MATRIX: -- break; -- -- case V4L2_CTRL_TYPE_H264_PRED_WEIGHTS: -- p_h264_pred_weights = p; -- -- if (p_h264_pred_weights->luma_log2_weight_denom > 7) -- return -EINVAL; -- if (p_h264_pred_weights->chroma_log2_weight_denom > 7) -- return -EINVAL; -- break; -- -- case V4L2_CTRL_TYPE_H264_SLICE_PARAMS: -- p_h264_slice_params = p; -- -- if (p_h264_slice_params->slice_type != V4L2_H264_SLICE_TYPE_B) -- p_h264_slice_params->flags &= -- ~V4L2_H264_SLICE_FLAG_DIRECT_SPATIAL_MV_PRED; -- -- if (p_h264_slice_params->colour_plane_id > 2) -- return -EINVAL; -- if (p_h264_slice_params->cabac_init_idc > 2) -- return -EINVAL; -- if (p_h264_slice_params->disable_deblocking_filter_idc > 2) -- return -EINVAL; -- if (p_h264_slice_params->slice_alpha_c0_offset_div2 < -6 || -- p_h264_slice_params->slice_alpha_c0_offset_div2 > 6) -- return -EINVAL; -- if (p_h264_slice_params->slice_beta_offset_div2 < -6 || -- p_h264_slice_params->slice_beta_offset_div2 > 6) -- return -EINVAL; -- -- if (p_h264_slice_params->slice_type == V4L2_H264_SLICE_TYPE_I || -- p_h264_slice_params->slice_type == V4L2_H264_SLICE_TYPE_SI) -- p_h264_slice_params->num_ref_idx_l0_active_minus1 = 0; -- if (p_h264_slice_params->slice_type != V4L2_H264_SLICE_TYPE_B) -- p_h264_slice_params->num_ref_idx_l1_active_minus1 = 0; -- -- if (p_h264_slice_params->num_ref_idx_l0_active_minus1 > -- (V4L2_H264_REF_LIST_LEN - 1)) -- return -EINVAL; -- if (p_h264_slice_params->num_ref_idx_l1_active_minus1 > -- (V4L2_H264_REF_LIST_LEN - 1)) -- return -EINVAL; -- zero_reserved(*p_h264_slice_params); -- break; -- -- case V4L2_CTRL_TYPE_H264_DECODE_PARAMS: -- p_h264_dec_params = p; -- -- if (p_h264_dec_params->nal_ref_idc > 3) -- return -EINVAL; -- for (i = 0; i < V4L2_H264_NUM_DPB_ENTRIES; i++) { -- struct v4l2_h264_dpb_entry *dpb_entry = -- &p_h264_dec_params->dpb[i]; -- -- zero_reserved(*dpb_entry); -- } -- zero_reserved(*p_h264_dec_params); -- break; -- -- case V4L2_CTRL_TYPE_VP8_FRAME: -- p_vp8_frame = p; -- -- switch (p_vp8_frame->num_dct_parts) { -- case 1: -- case 2: -- case 4: -- case 8: -- break; -- default: -- return -EINVAL; -- } -- zero_padding(p_vp8_frame->segment); -- zero_padding(p_vp8_frame->lf); -- zero_padding(p_vp8_frame->quant); -- zero_padding(p_vp8_frame->entropy); -- zero_padding(p_vp8_frame->coder_state); -- break; -- -- case V4L2_CTRL_TYPE_HEVC_SPS: -- p_hevc_sps = p; -- -- if (!(p_hevc_sps->flags & V4L2_HEVC_SPS_FLAG_PCM_ENABLED)) { -- p_hevc_sps->pcm_sample_bit_depth_luma_minus1 = 0; -- p_hevc_sps->pcm_sample_bit_depth_chroma_minus1 = 0; -- p_hevc_sps->log2_min_pcm_luma_coding_block_size_minus3 = 0; -- p_hevc_sps->log2_diff_max_min_pcm_luma_coding_block_size = 0; -- } -- -- if (!(p_hevc_sps->flags & -- V4L2_HEVC_SPS_FLAG_LONG_TERM_REF_PICS_PRESENT)) -- p_hevc_sps->num_long_term_ref_pics_sps = 0; -- break; -- -- case V4L2_CTRL_TYPE_HEVC_PPS: -- p_hevc_pps = p; -- -- if (!(p_hevc_pps->flags & -- V4L2_HEVC_PPS_FLAG_CU_QP_DELTA_ENABLED)) -- p_hevc_pps->diff_cu_qp_delta_depth = 0; -- -- if (!(p_hevc_pps->flags & V4L2_HEVC_PPS_FLAG_TILES_ENABLED)) { -- p_hevc_pps->num_tile_columns_minus1 = 0; -- p_hevc_pps->num_tile_rows_minus1 = 0; -- memset(&p_hevc_pps->column_width_minus1, 0, -- sizeof(p_hevc_pps->column_width_minus1)); -- memset(&p_hevc_pps->row_height_minus1, 0, -- sizeof(p_hevc_pps->row_height_minus1)); -- -- p_hevc_pps->flags &= -- ~V4L2_HEVC_PPS_FLAG_LOOP_FILTER_ACROSS_TILES_ENABLED; -- } -- -- if (p_hevc_pps->flags & -- V4L2_HEVC_PPS_FLAG_PPS_DISABLE_DEBLOCKING_FILTER) { -- p_hevc_pps->pps_beta_offset_div2 = 0; -- p_hevc_pps->pps_tc_offset_div2 = 0; -- } -- -- zero_padding(*p_hevc_pps); -- break; -- -- case V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS: -- p_hevc_slice_params = p; -- -- if (p_hevc_slice_params->num_active_dpb_entries > -- V4L2_HEVC_DPB_ENTRIES_NUM_MAX) -- return -EINVAL; -- -- zero_padding(p_hevc_slice_params->pred_weight_table); -- -- for (i = 0; i < p_hevc_slice_params->num_active_dpb_entries; -- i++) { -- struct v4l2_hevc_dpb_entry *dpb_entry = -- &p_hevc_slice_params->dpb[i]; -- -- zero_padding(*dpb_entry); -- } -- -- zero_padding(*p_hevc_slice_params); -- break; -- -- case V4L2_CTRL_TYPE_HDR10_CLL_INFO: -- break; -- -- case V4L2_CTRL_TYPE_HDR10_MASTERING_DISPLAY: -- p_hdr10_mastering = p; -- -- for (i = 0; i < 3; ++i) { -- if (p_hdr10_mastering->display_primaries_x[i] < -- V4L2_HDR10_MASTERING_PRIMARIES_X_LOW || -- p_hdr10_mastering->display_primaries_x[i] > -- V4L2_HDR10_MASTERING_PRIMARIES_X_HIGH || -- p_hdr10_mastering->display_primaries_y[i] < -- V4L2_HDR10_MASTERING_PRIMARIES_Y_LOW || -- p_hdr10_mastering->display_primaries_y[i] > -- V4L2_HDR10_MASTERING_PRIMARIES_Y_HIGH) -- return -EINVAL; -- } -- -- if (p_hdr10_mastering->white_point_x < -- V4L2_HDR10_MASTERING_WHITE_POINT_X_LOW || -- p_hdr10_mastering->white_point_x > -- V4L2_HDR10_MASTERING_WHITE_POINT_X_HIGH || -- p_hdr10_mastering->white_point_y < -- V4L2_HDR10_MASTERING_WHITE_POINT_Y_LOW || -- p_hdr10_mastering->white_point_y > -- V4L2_HDR10_MASTERING_WHITE_POINT_Y_HIGH) -- return -EINVAL; -- -- if (p_hdr10_mastering->max_display_mastering_luminance < -- V4L2_HDR10_MASTERING_MAX_LUMA_LOW || -- p_hdr10_mastering->max_display_mastering_luminance > -- V4L2_HDR10_MASTERING_MAX_LUMA_HIGH || -- p_hdr10_mastering->min_display_mastering_luminance < -- V4L2_HDR10_MASTERING_MIN_LUMA_LOW || -- p_hdr10_mastering->min_display_mastering_luminance > -- V4L2_HDR10_MASTERING_MIN_LUMA_HIGH) -- return -EINVAL; -- -- /* The following restriction comes from ITU-T Rec. H.265 spec */ -- if (p_hdr10_mastering->max_display_mastering_luminance == -- V4L2_HDR10_MASTERING_MAX_LUMA_LOW && -- p_hdr10_mastering->min_display_mastering_luminance == -- V4L2_HDR10_MASTERING_MIN_LUMA_HIGH) -- return -EINVAL; -- -- break; -- -- case V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX: -- break; -- -- case V4L2_CTRL_TYPE_AREA: -- area = p; -- if (!area->width || !area->height) -- return -EINVAL; -- break; -- -- default: -- return -EINVAL; -- } -- -- return 0; --} -- --static int std_validate(const struct v4l2_ctrl *ctrl, u32 idx, -- union v4l2_ctrl_ptr ptr) --{ -- size_t len; -- u64 offset; -- s64 val; -- -- switch ((u32)ctrl->type) { -- case V4L2_CTRL_TYPE_INTEGER: -- return ROUND_TO_RANGE(ptr.p_s32[idx], u32, ctrl); -- case V4L2_CTRL_TYPE_INTEGER64: -- /* -- * We can't use the ROUND_TO_RANGE define here due to -- * the u64 divide that needs special care. -- */ -- val = ptr.p_s64[idx]; -- if (ctrl->maximum >= 0 && val >= ctrl->maximum - (s64)(ctrl->step / 2)) -- val = ctrl->maximum; -- else -- val += (s64)(ctrl->step / 2); -- val = clamp_t(s64, val, ctrl->minimum, ctrl->maximum); -- offset = val - ctrl->minimum; -- do_div(offset, ctrl->step); -- ptr.p_s64[idx] = ctrl->minimum + offset * ctrl->step; -- return 0; -- case V4L2_CTRL_TYPE_U8: -- return ROUND_TO_RANGE(ptr.p_u8[idx], u8, ctrl); -- case V4L2_CTRL_TYPE_U16: -- return ROUND_TO_RANGE(ptr.p_u16[idx], u16, ctrl); -- case V4L2_CTRL_TYPE_U32: -- return ROUND_TO_RANGE(ptr.p_u32[idx], u32, ctrl); -- -- case V4L2_CTRL_TYPE_BOOLEAN: -- ptr.p_s32[idx] = !!ptr.p_s32[idx]; -- return 0; -- -- case V4L2_CTRL_TYPE_MENU: -- case V4L2_CTRL_TYPE_INTEGER_MENU: -- if (ptr.p_s32[idx] < ctrl->minimum || ptr.p_s32[idx] > ctrl->maximum) -- return -ERANGE; -- if (ptr.p_s32[idx] < BITS_PER_LONG_LONG && -- (ctrl->menu_skip_mask & BIT_ULL(ptr.p_s32[idx]))) -- return -EINVAL; -- if (ctrl->type == V4L2_CTRL_TYPE_MENU && -- ctrl->qmenu[ptr.p_s32[idx]][0] == '\0') -- return -EINVAL; -- return 0; -- -- case V4L2_CTRL_TYPE_BITMASK: -- ptr.p_s32[idx] &= ctrl->maximum; -- return 0; -- -- case V4L2_CTRL_TYPE_BUTTON: -- case V4L2_CTRL_TYPE_CTRL_CLASS: -- ptr.p_s32[idx] = 0; -- return 0; -- -- case V4L2_CTRL_TYPE_STRING: -- idx *= ctrl->elem_size; -- len = strlen(ptr.p_char + idx); -- if (len < ctrl->minimum) -- return -ERANGE; -- if ((len - (u32)ctrl->minimum) % (u32)ctrl->step) -- return -ERANGE; -- return 0; -- -- default: -- return std_validate_compound(ctrl, idx, ptr); -- } --} -- --static const struct v4l2_ctrl_type_ops std_type_ops = { -- .equal = std_equal, -- .init = std_init, -- .log = std_log, -- .validate = std_validate, --}; -- --/* Helper function: copy the given control value back to the caller */ --static int ptr_to_user(struct v4l2_ext_control *c, -- struct v4l2_ctrl *ctrl, -- union v4l2_ctrl_ptr ptr) --{ -- u32 len; -- -- if (ctrl->is_ptr && !ctrl->is_string) -- return copy_to_user(c->ptr, ptr.p_const, c->size) ? -- -EFAULT : 0; -- -- switch (ctrl->type) { -- case V4L2_CTRL_TYPE_STRING: -- len = strlen(ptr.p_char); -- if (c->size < len + 1) { -- c->size = ctrl->elem_size; -- return -ENOSPC; -- } -- return copy_to_user(c->string, ptr.p_char, len + 1) ? -- -EFAULT : 0; -- case V4L2_CTRL_TYPE_INTEGER64: -- c->value64 = *ptr.p_s64; -- break; -- default: -- c->value = *ptr.p_s32; -- break; -- } -- return 0; --} -- --/* Helper function: copy the current control value back to the caller */ --static int cur_to_user(struct v4l2_ext_control *c, -- struct v4l2_ctrl *ctrl) --{ -- return ptr_to_user(c, ctrl, ctrl->p_cur); --} -- --/* Helper function: copy the new control value back to the caller */ --static int new_to_user(struct v4l2_ext_control *c, -- struct v4l2_ctrl *ctrl) --{ -- return ptr_to_user(c, ctrl, ctrl->p_new); --} -- --/* Helper function: copy the request value back to the caller */ --static int req_to_user(struct v4l2_ext_control *c, -- struct v4l2_ctrl_ref *ref) --{ -- return ptr_to_user(c, ref->ctrl, ref->p_req); --} -- --/* Helper function: copy the initial control value back to the caller */ --static int def_to_user(struct v4l2_ext_control *c, struct v4l2_ctrl *ctrl) --{ -- int idx; -- -- for (idx = 0; idx < ctrl->elems; idx++) -- ctrl->type_ops->init(ctrl, idx, ctrl->p_new); -- -- return ptr_to_user(c, ctrl, ctrl->p_new); --} -- --/* Helper function: copy the caller-provider value to the given control value */ --static int user_to_ptr(struct v4l2_ext_control *c, -- struct v4l2_ctrl *ctrl, -- union v4l2_ctrl_ptr ptr) --{ -- int ret; -- u32 size; -- -- ctrl->is_new = 1; -- if (ctrl->is_ptr && !ctrl->is_string) { -- unsigned idx; -- -- ret = copy_from_user(ptr.p, c->ptr, c->size) ? -EFAULT : 0; -- if (ret || !ctrl->is_array) -- return ret; -- for (idx = c->size / ctrl->elem_size; idx < ctrl->elems; idx++) -- ctrl->type_ops->init(ctrl, idx, ptr); -- return 0; -- } -- -- switch (ctrl->type) { -- case V4L2_CTRL_TYPE_INTEGER64: -- *ptr.p_s64 = c->value64; -- break; -- case V4L2_CTRL_TYPE_STRING: -- size = c->size; -- if (size == 0) -- return -ERANGE; -- if (size > ctrl->maximum + 1) -- size = ctrl->maximum + 1; -- ret = copy_from_user(ptr.p_char, c->string, size) ? -EFAULT : 0; -- if (!ret) { -- char last = ptr.p_char[size - 1]; -- -- ptr.p_char[size - 1] = 0; -- /* If the string was longer than ctrl->maximum, -- then return an error. */ -- if (strlen(ptr.p_char) == ctrl->maximum && last) -- return -ERANGE; -- } -- return ret; -- default: -- *ptr.p_s32 = c->value; -- break; -- } -- return 0; --} -- --/* Helper function: copy the caller-provider value as the new control value */ --static int user_to_new(struct v4l2_ext_control *c, -- struct v4l2_ctrl *ctrl) --{ -- return user_to_ptr(c, ctrl, ctrl->p_new); --} -- --/* Copy the one value to another. */ --static void ptr_to_ptr(struct v4l2_ctrl *ctrl, -- union v4l2_ctrl_ptr from, union v4l2_ctrl_ptr to) --{ -- if (ctrl == NULL) -- return; -- memcpy(to.p, from.p_const, ctrl->elems * ctrl->elem_size); --} -- --/* Copy the new value to the current value. */ --static void new_to_cur(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, u32 ch_flags) --{ -- bool changed; -- -- if (ctrl == NULL) -- return; -- -- /* has_changed is set by cluster_changed */ -- changed = ctrl->has_changed; -- if (changed) -- ptr_to_ptr(ctrl, ctrl->p_new, ctrl->p_cur); -- -- if (ch_flags & V4L2_EVENT_CTRL_CH_FLAGS) { -- /* Note: CH_FLAGS is only set for auto clusters. */ -- ctrl->flags &= -- ~(V4L2_CTRL_FLAG_INACTIVE | V4L2_CTRL_FLAG_VOLATILE); -- if (!is_cur_manual(ctrl->cluster[0])) { -- ctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; -- if (ctrl->cluster[0]->has_volatiles) -- ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; -- } -- fh = NULL; -- } -- if (changed || ch_flags) { -- /* If a control was changed that was not one of the controls -- modified by the application, then send the event to all. */ -- if (!ctrl->is_new) -- fh = NULL; -- send_event(fh, ctrl, -- (changed ? V4L2_EVENT_CTRL_CH_VALUE : 0) | ch_flags); -- if (ctrl->call_notify && changed && ctrl->handler->notify) -- ctrl->handler->notify(ctrl, ctrl->handler->notify_priv); -- } --} -- --/* Copy the current value to the new value */ --static void cur_to_new(struct v4l2_ctrl *ctrl) --{ -- if (ctrl == NULL) -- return; -- ptr_to_ptr(ctrl, ctrl->p_cur, ctrl->p_new); --} -- --/* Copy the new value to the request value */ --static void new_to_req(struct v4l2_ctrl_ref *ref) --{ -- if (!ref) -- return; -- ptr_to_ptr(ref->ctrl, ref->ctrl->p_new, ref->p_req); -- ref->valid_p_req = true; --} -- --/* Copy the current value to the request value */ --static void cur_to_req(struct v4l2_ctrl_ref *ref) --{ -- if (!ref) -- return; -- ptr_to_ptr(ref->ctrl, ref->ctrl->p_cur, ref->p_req); -- ref->valid_p_req = true; --} -- --/* Copy the request value to the new value */ --static void req_to_new(struct v4l2_ctrl_ref *ref) --{ -- if (!ref) -- return; -- if (ref->valid_p_req) -- ptr_to_ptr(ref->ctrl, ref->p_req, ref->ctrl->p_new); -- else -- ptr_to_ptr(ref->ctrl, ref->ctrl->p_cur, ref->ctrl->p_new); --} -- --/* Return non-zero if one or more of the controls in the cluster has a new -- value that differs from the current value. */ --static int cluster_changed(struct v4l2_ctrl *master) --{ -- bool changed = false; -- unsigned idx; -- int i; -- -- for (i = 0; i < master->ncontrols; i++) { -- struct v4l2_ctrl *ctrl = master->cluster[i]; -- bool ctrl_changed = false; -- -- if (ctrl == NULL) -- continue; -- -- if (ctrl->flags & V4L2_CTRL_FLAG_EXECUTE_ON_WRITE) -- changed = ctrl_changed = true; -- -- /* -- * Set has_changed to false to avoid generating -- * the event V4L2_EVENT_CTRL_CH_VALUE -- */ -- if (ctrl->flags & V4L2_CTRL_FLAG_VOLATILE) { -- ctrl->has_changed = false; -- continue; -- } -- -- for (idx = 0; !ctrl_changed && idx < ctrl->elems; idx++) -- ctrl_changed = !ctrl->type_ops->equal(ctrl, idx, -- ctrl->p_cur, ctrl->p_new); -- ctrl->has_changed = ctrl_changed; -- changed |= ctrl->has_changed; -- } -- return changed; --} -- --/* Control range checking */ --static int check_range(enum v4l2_ctrl_type type, -- s64 min, s64 max, u64 step, s64 def) --{ -- switch (type) { -- case V4L2_CTRL_TYPE_BOOLEAN: -- if (step != 1 || max > 1 || min < 0) -- return -ERANGE; -- fallthrough; -- case V4L2_CTRL_TYPE_U8: -- case V4L2_CTRL_TYPE_U16: -- case V4L2_CTRL_TYPE_U32: -- case V4L2_CTRL_TYPE_INTEGER: -- case V4L2_CTRL_TYPE_INTEGER64: -- if (step == 0 || min > max || def < min || def > max) -- return -ERANGE; -- return 0; -- case V4L2_CTRL_TYPE_BITMASK: -- if (step || min || !max || (def & ~max)) -- return -ERANGE; -- return 0; -- case V4L2_CTRL_TYPE_MENU: -- case V4L2_CTRL_TYPE_INTEGER_MENU: -- if (min > max || def < min || def > max) -- return -ERANGE; -- /* Note: step == menu_skip_mask for menu controls. -- So here we check if the default value is masked out. */ -- if (step && ((1 << def) & step)) -- return -EINVAL; -- return 0; -- case V4L2_CTRL_TYPE_STRING: -- if (min > max || min < 0 || step < 1 || def) -- return -ERANGE; -- return 0; -- default: -- return 0; -- } --} -- --/* Validate a new control */ --static int validate_new(const struct v4l2_ctrl *ctrl, union v4l2_ctrl_ptr p_new) --{ -- unsigned idx; -- int err = 0; -- -- for (idx = 0; !err && idx < ctrl->elems; idx++) -- err = ctrl->type_ops->validate(ctrl, idx, p_new); -- return err; --} -- --static inline u32 node2id(struct list_head *node) --{ -- return list_entry(node, struct v4l2_ctrl_ref, node)->ctrl->id; --} -- --/* Set the handler's error code if it wasn't set earlier already */ --static inline int handler_set_err(struct v4l2_ctrl_handler *hdl, int err) --{ -- if (hdl->error == 0) -- hdl->error = err; -- return err; --} -- --/* Initialize the handler */ --int v4l2_ctrl_handler_init_class(struct v4l2_ctrl_handler *hdl, -- unsigned nr_of_controls_hint, -- struct lock_class_key *key, const char *name) --{ -- mutex_init(&hdl->_lock); -- hdl->lock = &hdl->_lock; -- lockdep_set_class_and_name(hdl->lock, key, name); -- INIT_LIST_HEAD(&hdl->ctrls); -- INIT_LIST_HEAD(&hdl->ctrl_refs); -- INIT_LIST_HEAD(&hdl->requests); -- INIT_LIST_HEAD(&hdl->requests_queued); -- hdl->request_is_queued = false; -- hdl->nr_of_buckets = 1 + nr_of_controls_hint / 8; -- hdl->buckets = kvmalloc_array(hdl->nr_of_buckets, -- sizeof(hdl->buckets[0]), -- GFP_KERNEL | __GFP_ZERO); -- hdl->error = hdl->buckets ? 0 : -ENOMEM; -- media_request_object_init(&hdl->req_obj); -- return hdl->error; --} --EXPORT_SYMBOL(v4l2_ctrl_handler_init_class); -- --/* Free all controls and control refs */ --void v4l2_ctrl_handler_free(struct v4l2_ctrl_handler *hdl) --{ -- struct v4l2_ctrl_ref *ref, *next_ref; -- struct v4l2_ctrl *ctrl, *next_ctrl; -- struct v4l2_subscribed_event *sev, *next_sev; -- -- if (hdl == NULL || hdl->buckets == NULL) -- return; -- -- /* -- * If the main handler is freed and it is used by handler objects in -- * outstanding requests, then unbind and put those objects before -- * freeing the main handler. -- * -- * The main handler can be identified by having a NULL ops pointer in -- * the request object. -- */ -- if (!hdl->req_obj.ops && !list_empty(&hdl->requests)) { -- struct v4l2_ctrl_handler *req, *next_req; -- -- list_for_each_entry_safe(req, next_req, &hdl->requests, requests) { -- media_request_object_unbind(&req->req_obj); -- media_request_object_put(&req->req_obj); -- } -- } -- mutex_lock(hdl->lock); -- /* Free all nodes */ -- list_for_each_entry_safe(ref, next_ref, &hdl->ctrl_refs, node) { -- list_del(&ref->node); -- kfree(ref); -- } -- /* Free all controls owned by the handler */ -- list_for_each_entry_safe(ctrl, next_ctrl, &hdl->ctrls, node) { -- list_del(&ctrl->node); -- list_for_each_entry_safe(sev, next_sev, &ctrl->ev_subs, node) -- list_del(&sev->node); -- kvfree(ctrl); -- } -- kvfree(hdl->buckets); -- hdl->buckets = NULL; -- hdl->cached = NULL; -- hdl->error = 0; -- mutex_unlock(hdl->lock); -- mutex_destroy(&hdl->_lock); --} --EXPORT_SYMBOL(v4l2_ctrl_handler_free); -- --/* For backwards compatibility: V4L2_CID_PRIVATE_BASE should no longer -- be used except in G_CTRL, S_CTRL, QUERYCTRL and QUERYMENU when dealing -- with applications that do not use the NEXT_CTRL flag. -- -- We just find the n-th private user control. It's O(N), but that should not -- be an issue in this particular case. */ --static struct v4l2_ctrl_ref *find_private_ref( -- struct v4l2_ctrl_handler *hdl, u32 id) --{ -- struct v4l2_ctrl_ref *ref; -- -- id -= V4L2_CID_PRIVATE_BASE; -- list_for_each_entry(ref, &hdl->ctrl_refs, node) { -- /* Search for private user controls that are compatible with -- VIDIOC_G/S_CTRL. */ -- if (V4L2_CTRL_ID2WHICH(ref->ctrl->id) == V4L2_CTRL_CLASS_USER && -- V4L2_CTRL_DRIVER_PRIV(ref->ctrl->id)) { -- if (!ref->ctrl->is_int) -- continue; -- if (id == 0) -- return ref; -- id--; -- } -- } -- return NULL; --} -- --/* Find a control with the given ID. */ --static struct v4l2_ctrl_ref *find_ref(struct v4l2_ctrl_handler *hdl, u32 id) --{ -- struct v4l2_ctrl_ref *ref; -- int bucket; -- -- id &= V4L2_CTRL_ID_MASK; -- -- /* Old-style private controls need special handling */ -- if (id >= V4L2_CID_PRIVATE_BASE) -- return find_private_ref(hdl, id); -- bucket = id % hdl->nr_of_buckets; -- -- /* Simple optimization: cache the last control found */ -- if (hdl->cached && hdl->cached->ctrl->id == id) -- return hdl->cached; -- -- /* Not in cache, search the hash */ -- ref = hdl->buckets ? hdl->buckets[bucket] : NULL; -- while (ref && ref->ctrl->id != id) -- ref = ref->next; -- -- if (ref) -- hdl->cached = ref; /* cache it! */ -- return ref; --} -- --/* Find a control with the given ID. Take the handler's lock first. */ --static struct v4l2_ctrl_ref *find_ref_lock( -- struct v4l2_ctrl_handler *hdl, u32 id) --{ -- struct v4l2_ctrl_ref *ref = NULL; -- -- if (hdl) { -- mutex_lock(hdl->lock); -- ref = find_ref(hdl, id); -- mutex_unlock(hdl->lock); -- } -- return ref; --} -- --/* Find a control with the given ID. */ --struct v4l2_ctrl *v4l2_ctrl_find(struct v4l2_ctrl_handler *hdl, u32 id) --{ -- struct v4l2_ctrl_ref *ref = find_ref_lock(hdl, id); -- -- return ref ? ref->ctrl : NULL; --} --EXPORT_SYMBOL(v4l2_ctrl_find); -- --/* Allocate a new v4l2_ctrl_ref and hook it into the handler. */ --static int handler_new_ref(struct v4l2_ctrl_handler *hdl, -- struct v4l2_ctrl *ctrl, -- struct v4l2_ctrl_ref **ctrl_ref, -- bool from_other_dev, bool allocate_req) --{ -- struct v4l2_ctrl_ref *ref; -- struct v4l2_ctrl_ref *new_ref; -- u32 id = ctrl->id; -- u32 class_ctrl = V4L2_CTRL_ID2WHICH(id) | 1; -- int bucket = id % hdl->nr_of_buckets; /* which bucket to use */ -- unsigned int size_extra_req = 0; -- -- if (ctrl_ref) -- *ctrl_ref = NULL; -- -- /* -- * Automatically add the control class if it is not yet present and -- * the new control is not a compound control. -- */ -- if (ctrl->type < V4L2_CTRL_COMPOUND_TYPES && -- id != class_ctrl && find_ref_lock(hdl, class_ctrl) == NULL) -- if (!v4l2_ctrl_new_std(hdl, NULL, class_ctrl, 0, 0, 0, 0)) -- return hdl->error; -- -- if (hdl->error) -- return hdl->error; -- -- if (allocate_req) -- size_extra_req = ctrl->elems * ctrl->elem_size; -- new_ref = kzalloc(sizeof(*new_ref) + size_extra_req, GFP_KERNEL); -- if (!new_ref) -- return handler_set_err(hdl, -ENOMEM); -- new_ref->ctrl = ctrl; -- new_ref->from_other_dev = from_other_dev; -- if (size_extra_req) -- new_ref->p_req.p = &new_ref[1]; -- -- INIT_LIST_HEAD(&new_ref->node); -- -- mutex_lock(hdl->lock); -- -- /* Add immediately at the end of the list if the list is empty, or if -- the last element in the list has a lower ID. -- This ensures that when elements are added in ascending order the -- insertion is an O(1) operation. */ -- if (list_empty(&hdl->ctrl_refs) || id > node2id(hdl->ctrl_refs.prev)) { -- list_add_tail(&new_ref->node, &hdl->ctrl_refs); -- goto insert_in_hash; -- } -- -- /* Find insert position in sorted list */ -- list_for_each_entry(ref, &hdl->ctrl_refs, node) { -- if (ref->ctrl->id < id) -- continue; -- /* Don't add duplicates */ -- if (ref->ctrl->id == id) { -- kfree(new_ref); -- goto unlock; -- } -- list_add(&new_ref->node, ref->node.prev); -- break; -- } -- --insert_in_hash: -- /* Insert the control node in the hash */ -- new_ref->next = hdl->buckets[bucket]; -- hdl->buckets[bucket] = new_ref; -- if (ctrl_ref) -- *ctrl_ref = new_ref; -- if (ctrl->handler == hdl) { -- /* By default each control starts in a cluster of its own. -- * new_ref->ctrl is basically a cluster array with one -- * element, so that's perfect to use as the cluster pointer. -- * But only do this for the handler that owns the control. -- */ -- ctrl->cluster = &new_ref->ctrl; -- ctrl->ncontrols = 1; -- } -- --unlock: -- mutex_unlock(hdl->lock); -- return 0; --} -- --/* Add a new control */ --static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl, -- const struct v4l2_ctrl_ops *ops, -- const struct v4l2_ctrl_type_ops *type_ops, -- u32 id, const char *name, enum v4l2_ctrl_type type, -- s64 min, s64 max, u64 step, s64 def, -- const u32 dims[V4L2_CTRL_MAX_DIMS], u32 elem_size, -- u32 flags, const char * const *qmenu, -- const s64 *qmenu_int, const union v4l2_ctrl_ptr p_def, -- void *priv) --{ -- struct v4l2_ctrl *ctrl; -- unsigned sz_extra; -- unsigned nr_of_dims = 0; -- unsigned elems = 1; -- bool is_array; -- unsigned tot_ctrl_size; -- unsigned idx; -- void *data; -- int err; -- -- if (hdl->error) -- return NULL; -- -- while (dims && dims[nr_of_dims]) { -- elems *= dims[nr_of_dims]; -- nr_of_dims++; -- if (nr_of_dims == V4L2_CTRL_MAX_DIMS) -- break; -- } -- is_array = nr_of_dims > 0; -- -- /* Prefill elem_size for all types handled by std_type_ops */ -- switch ((u32)type) { -- case V4L2_CTRL_TYPE_INTEGER64: -- elem_size = sizeof(s64); -- break; -- case V4L2_CTRL_TYPE_STRING: -- elem_size = max + 1; -- break; -- case V4L2_CTRL_TYPE_U8: -- elem_size = sizeof(u8); -- break; -- case V4L2_CTRL_TYPE_U16: -- elem_size = sizeof(u16); -- break; -- case V4L2_CTRL_TYPE_U32: -- elem_size = sizeof(u32); -- break; -- case V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS: -- elem_size = sizeof(struct v4l2_ctrl_mpeg2_slice_params); -- break; -- case V4L2_CTRL_TYPE_MPEG2_QUANTIZATION: -- elem_size = sizeof(struct v4l2_ctrl_mpeg2_quantization); -- break; -- case V4L2_CTRL_TYPE_FWHT_PARAMS: -- elem_size = sizeof(struct v4l2_ctrl_fwht_params); -- break; -- case V4L2_CTRL_TYPE_H264_SPS: -- elem_size = sizeof(struct v4l2_ctrl_h264_sps); -- break; -- case V4L2_CTRL_TYPE_H264_PPS: -- elem_size = sizeof(struct v4l2_ctrl_h264_pps); -- break; -- case V4L2_CTRL_TYPE_H264_SCALING_MATRIX: -- elem_size = sizeof(struct v4l2_ctrl_h264_scaling_matrix); -- break; -- case V4L2_CTRL_TYPE_H264_SLICE_PARAMS: -- elem_size = sizeof(struct v4l2_ctrl_h264_slice_params); -- break; -- case V4L2_CTRL_TYPE_H264_DECODE_PARAMS: -- elem_size = sizeof(struct v4l2_ctrl_h264_decode_params); -- break; -- case V4L2_CTRL_TYPE_H264_PRED_WEIGHTS: -- elem_size = sizeof(struct v4l2_ctrl_h264_pred_weights); -- break; -- case V4L2_CTRL_TYPE_VP8_FRAME: -- elem_size = sizeof(struct v4l2_ctrl_vp8_frame); -- break; -- case V4L2_CTRL_TYPE_HEVC_SPS: -- elem_size = sizeof(struct v4l2_ctrl_hevc_sps); -- break; -- case V4L2_CTRL_TYPE_HEVC_PPS: -- elem_size = sizeof(struct v4l2_ctrl_hevc_pps); -- break; -- case V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS: -- elem_size = sizeof(struct v4l2_ctrl_hevc_slice_params); -- break; -- case V4L2_CTRL_TYPE_HDR10_CLL_INFO: -- elem_size = sizeof(struct v4l2_ctrl_hdr10_cll_info); -- break; -- case V4L2_CTRL_TYPE_HDR10_MASTERING_DISPLAY: -- elem_size = sizeof(struct v4l2_ctrl_hdr10_mastering_display); -- break; -- case V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX: -- elem_size = sizeof(struct v4l2_ctrl_hevc_scaling_matrix); -- break; -- case V4L2_CTRL_TYPE_AREA: -- elem_size = sizeof(struct v4l2_area); -- break; -- default: -- if (type < V4L2_CTRL_COMPOUND_TYPES) -- elem_size = sizeof(s32); -- break; -- } -- tot_ctrl_size = elem_size * elems; -- -- /* Sanity checks */ -- if (id == 0 || name == NULL || !elem_size || -- id >= V4L2_CID_PRIVATE_BASE || -- (type == V4L2_CTRL_TYPE_MENU && qmenu == NULL) || -- (type == V4L2_CTRL_TYPE_INTEGER_MENU && qmenu_int == NULL)) { -- handler_set_err(hdl, -ERANGE); -- return NULL; -- } -- err = check_range(type, min, max, step, def); -- if (err) { -- handler_set_err(hdl, err); -- return NULL; -- } -- if (is_array && -- (type == V4L2_CTRL_TYPE_BUTTON || -- type == V4L2_CTRL_TYPE_CTRL_CLASS)) { -- handler_set_err(hdl, -EINVAL); -- return NULL; -- } -- -- sz_extra = 0; -- if (type == V4L2_CTRL_TYPE_BUTTON) -- flags |= V4L2_CTRL_FLAG_WRITE_ONLY | -- V4L2_CTRL_FLAG_EXECUTE_ON_WRITE; -- else if (type == V4L2_CTRL_TYPE_CTRL_CLASS) -- flags |= V4L2_CTRL_FLAG_READ_ONLY; -- else if (type == V4L2_CTRL_TYPE_INTEGER64 || -- type == V4L2_CTRL_TYPE_STRING || -- type >= V4L2_CTRL_COMPOUND_TYPES || -- is_array) -- sz_extra += 2 * tot_ctrl_size; -- -- if (type >= V4L2_CTRL_COMPOUND_TYPES && p_def.p_const) -- sz_extra += elem_size; -- -- ctrl = kvzalloc(sizeof(*ctrl) + sz_extra, GFP_KERNEL); -- if (ctrl == NULL) { -- handler_set_err(hdl, -ENOMEM); -- return NULL; -- } -- -- INIT_LIST_HEAD(&ctrl->node); -- INIT_LIST_HEAD(&ctrl->ev_subs); -- ctrl->handler = hdl; -- ctrl->ops = ops; -- ctrl->type_ops = type_ops ? type_ops : &std_type_ops; -- ctrl->id = id; -- ctrl->name = name; -- ctrl->type = type; -- ctrl->flags = flags; -- ctrl->minimum = min; -- ctrl->maximum = max; -- ctrl->step = step; -- ctrl->default_value = def; -- ctrl->is_string = !is_array && type == V4L2_CTRL_TYPE_STRING; -- ctrl->is_ptr = is_array || type >= V4L2_CTRL_COMPOUND_TYPES || ctrl->is_string; -- ctrl->is_int = !ctrl->is_ptr && type != V4L2_CTRL_TYPE_INTEGER64; -- ctrl->is_array = is_array; -- ctrl->elems = elems; -- ctrl->nr_of_dims = nr_of_dims; -- if (nr_of_dims) -- memcpy(ctrl->dims, dims, nr_of_dims * sizeof(dims[0])); -- ctrl->elem_size = elem_size; -- if (type == V4L2_CTRL_TYPE_MENU) -- ctrl->qmenu = qmenu; -- else if (type == V4L2_CTRL_TYPE_INTEGER_MENU) -- ctrl->qmenu_int = qmenu_int; -- ctrl->priv = priv; -- ctrl->cur.val = ctrl->val = def; -- data = &ctrl[1]; -- -- if (!ctrl->is_int) { -- ctrl->p_new.p = data; -- ctrl->p_cur.p = data + tot_ctrl_size; -- } else { -- ctrl->p_new.p = &ctrl->val; -- ctrl->p_cur.p = &ctrl->cur.val; -- } -- -- if (type >= V4L2_CTRL_COMPOUND_TYPES && p_def.p_const) { -- ctrl->p_def.p = ctrl->p_cur.p + tot_ctrl_size; -- memcpy(ctrl->p_def.p, p_def.p_const, elem_size); -- } -- -- for (idx = 0; idx < elems; idx++) { -- ctrl->type_ops->init(ctrl, idx, ctrl->p_cur); -- ctrl->type_ops->init(ctrl, idx, ctrl->p_new); -- } -- -- if (handler_new_ref(hdl, ctrl, NULL, false, false)) { -- kvfree(ctrl); -- return NULL; -- } -- mutex_lock(hdl->lock); -- list_add_tail(&ctrl->node, &hdl->ctrls); -- mutex_unlock(hdl->lock); -- return ctrl; --} -- --struct v4l2_ctrl *v4l2_ctrl_new_custom(struct v4l2_ctrl_handler *hdl, -- const struct v4l2_ctrl_config *cfg, void *priv) --{ -- bool is_menu; -- struct v4l2_ctrl *ctrl; -- const char *name = cfg->name; -- const char * const *qmenu = cfg->qmenu; -- const s64 *qmenu_int = cfg->qmenu_int; -- enum v4l2_ctrl_type type = cfg->type; -- u32 flags = cfg->flags; -- s64 min = cfg->min; -- s64 max = cfg->max; -- u64 step = cfg->step; -- s64 def = cfg->def; -- -- if (name == NULL) -- v4l2_ctrl_fill(cfg->id, &name, &type, &min, &max, &step, -- &def, &flags); -- -- is_menu = (type == V4L2_CTRL_TYPE_MENU || -- type == V4L2_CTRL_TYPE_INTEGER_MENU); -- if (is_menu) -- WARN_ON(step); -- else -- WARN_ON(cfg->menu_skip_mask); -- if (type == V4L2_CTRL_TYPE_MENU && !qmenu) { -- qmenu = v4l2_ctrl_get_menu(cfg->id); -- } else if (type == V4L2_CTRL_TYPE_INTEGER_MENU && !qmenu_int) { -- handler_set_err(hdl, -EINVAL); -- return NULL; -- } -- -- ctrl = v4l2_ctrl_new(hdl, cfg->ops, cfg->type_ops, cfg->id, name, -- type, min, max, -- is_menu ? cfg->menu_skip_mask : step, def, -- cfg->dims, cfg->elem_size, -- flags, qmenu, qmenu_int, cfg->p_def, priv); -- if (ctrl) -- ctrl->is_private = cfg->is_private; -- return ctrl; --} --EXPORT_SYMBOL(v4l2_ctrl_new_custom); -- --/* Helper function for standard non-menu controls */ --struct v4l2_ctrl *v4l2_ctrl_new_std(struct v4l2_ctrl_handler *hdl, -- const struct v4l2_ctrl_ops *ops, -- u32 id, s64 min, s64 max, u64 step, s64 def) --{ -- const char *name; -- enum v4l2_ctrl_type type; -- u32 flags; -- -- v4l2_ctrl_fill(id, &name, &type, &min, &max, &step, &def, &flags); -- if (type == V4L2_CTRL_TYPE_MENU || -- type == V4L2_CTRL_TYPE_INTEGER_MENU || -- type >= V4L2_CTRL_COMPOUND_TYPES) { -- handler_set_err(hdl, -EINVAL); -- return NULL; -- } -- return v4l2_ctrl_new(hdl, ops, NULL, id, name, type, -- min, max, step, def, NULL, 0, -- flags, NULL, NULL, ptr_null, NULL); --} --EXPORT_SYMBOL(v4l2_ctrl_new_std); -- --/* Helper function for standard menu controls */ --struct v4l2_ctrl *v4l2_ctrl_new_std_menu(struct v4l2_ctrl_handler *hdl, -- const struct v4l2_ctrl_ops *ops, -- u32 id, u8 _max, u64 mask, u8 _def) --{ -- const char * const *qmenu = NULL; -- const s64 *qmenu_int = NULL; -- unsigned int qmenu_int_len = 0; -- const char *name; -- enum v4l2_ctrl_type type; -- s64 min; -- s64 max = _max; -- s64 def = _def; -- u64 step; -- u32 flags; -- -- v4l2_ctrl_fill(id, &name, &type, &min, &max, &step, &def, &flags); -- -- if (type == V4L2_CTRL_TYPE_MENU) -- qmenu = v4l2_ctrl_get_menu(id); -- else if (type == V4L2_CTRL_TYPE_INTEGER_MENU) -- qmenu_int = v4l2_ctrl_get_int_menu(id, &qmenu_int_len); -- -- if ((!qmenu && !qmenu_int) || (qmenu_int && max > qmenu_int_len)) { -- handler_set_err(hdl, -EINVAL); -- return NULL; -- } -- return v4l2_ctrl_new(hdl, ops, NULL, id, name, type, -- 0, max, mask, def, NULL, 0, -- flags, qmenu, qmenu_int, ptr_null, NULL); --} --EXPORT_SYMBOL(v4l2_ctrl_new_std_menu); -- --/* Helper function for standard menu controls with driver defined menu */ --struct v4l2_ctrl *v4l2_ctrl_new_std_menu_items(struct v4l2_ctrl_handler *hdl, -- const struct v4l2_ctrl_ops *ops, u32 id, u8 _max, -- u64 mask, u8 _def, const char * const *qmenu) --{ -- enum v4l2_ctrl_type type; -- const char *name; -- u32 flags; -- u64 step; -- s64 min; -- s64 max = _max; -- s64 def = _def; -- -- /* v4l2_ctrl_new_std_menu_items() should only be called for -- * standard controls without a standard menu. -- */ -- if (v4l2_ctrl_get_menu(id)) { -- handler_set_err(hdl, -EINVAL); -- return NULL; -- } -- -- v4l2_ctrl_fill(id, &name, &type, &min, &max, &step, &def, &flags); -- if (type != V4L2_CTRL_TYPE_MENU || qmenu == NULL) { -- handler_set_err(hdl, -EINVAL); -- return NULL; -- } -- return v4l2_ctrl_new(hdl, ops, NULL, id, name, type, -- 0, max, mask, def, NULL, 0, -- flags, qmenu, NULL, ptr_null, NULL); -- --} --EXPORT_SYMBOL(v4l2_ctrl_new_std_menu_items); -- --/* Helper function for standard compound controls */ --struct v4l2_ctrl *v4l2_ctrl_new_std_compound(struct v4l2_ctrl_handler *hdl, -- const struct v4l2_ctrl_ops *ops, u32 id, -- const union v4l2_ctrl_ptr p_def) --{ -- const char *name; -- enum v4l2_ctrl_type type; -- u32 flags; -- s64 min, max, step, def; -- -- v4l2_ctrl_fill(id, &name, &type, &min, &max, &step, &def, &flags); -- if (type < V4L2_CTRL_COMPOUND_TYPES) { -- handler_set_err(hdl, -EINVAL); -- return NULL; -- } -- return v4l2_ctrl_new(hdl, ops, NULL, id, name, type, -- min, max, step, def, NULL, 0, -- flags, NULL, NULL, p_def, NULL); --} --EXPORT_SYMBOL(v4l2_ctrl_new_std_compound); -- --/* Helper function for standard integer menu controls */ --struct v4l2_ctrl *v4l2_ctrl_new_int_menu(struct v4l2_ctrl_handler *hdl, -- const struct v4l2_ctrl_ops *ops, -- u32 id, u8 _max, u8 _def, const s64 *qmenu_int) --{ -- const char *name; -- enum v4l2_ctrl_type type; -- s64 min; -- u64 step; -- s64 max = _max; -- s64 def = _def; -- u32 flags; -- -- v4l2_ctrl_fill(id, &name, &type, &min, &max, &step, &def, &flags); -- if (type != V4L2_CTRL_TYPE_INTEGER_MENU) { -- handler_set_err(hdl, -EINVAL); -- return NULL; -- } -- return v4l2_ctrl_new(hdl, ops, NULL, id, name, type, -- 0, max, 0, def, NULL, 0, -- flags, NULL, qmenu_int, ptr_null, NULL); --} --EXPORT_SYMBOL(v4l2_ctrl_new_int_menu); -- --/* Add the controls from another handler to our own. */ --int v4l2_ctrl_add_handler(struct v4l2_ctrl_handler *hdl, -- struct v4l2_ctrl_handler *add, -- bool (*filter)(const struct v4l2_ctrl *ctrl), -- bool from_other_dev) --{ -- struct v4l2_ctrl_ref *ref; -- int ret = 0; -- -- /* Do nothing if either handler is NULL or if they are the same */ -- if (!hdl || !add || hdl == add) -- return 0; -- if (hdl->error) -- return hdl->error; -- mutex_lock(add->lock); -- list_for_each_entry(ref, &add->ctrl_refs, node) { -- struct v4l2_ctrl *ctrl = ref->ctrl; -- -- /* Skip handler-private controls. */ -- if (ctrl->is_private) -- continue; -- /* And control classes */ -- if (ctrl->type == V4L2_CTRL_TYPE_CTRL_CLASS) -- continue; -- /* Filter any unwanted controls */ -- if (filter && !filter(ctrl)) -- continue; -- ret = handler_new_ref(hdl, ctrl, NULL, from_other_dev, false); -- if (ret) -- break; -- } -- mutex_unlock(add->lock); -- return ret; --} --EXPORT_SYMBOL(v4l2_ctrl_add_handler); -- --bool v4l2_ctrl_radio_filter(const struct v4l2_ctrl *ctrl) --{ -- if (V4L2_CTRL_ID2WHICH(ctrl->id) == V4L2_CTRL_CLASS_FM_TX) -- return true; -- if (V4L2_CTRL_ID2WHICH(ctrl->id) == V4L2_CTRL_CLASS_FM_RX) -- return true; -- switch (ctrl->id) { -- case V4L2_CID_AUDIO_MUTE: -- case V4L2_CID_AUDIO_VOLUME: -- case V4L2_CID_AUDIO_BALANCE: -- case V4L2_CID_AUDIO_BASS: -- case V4L2_CID_AUDIO_TREBLE: -- case V4L2_CID_AUDIO_LOUDNESS: -- return true; -- default: -- break; -- } -- return false; --} --EXPORT_SYMBOL(v4l2_ctrl_radio_filter); -- --/* Cluster controls */ --void v4l2_ctrl_cluster(unsigned ncontrols, struct v4l2_ctrl **controls) --{ -- bool has_volatiles = false; -- int i; -- -- /* The first control is the master control and it must not be NULL */ -- if (WARN_ON(ncontrols == 0 || controls[0] == NULL)) -- return; -- -- for (i = 0; i < ncontrols; i++) { -- if (controls[i]) { -- controls[i]->cluster = controls; -- controls[i]->ncontrols = ncontrols; -- if (controls[i]->flags & V4L2_CTRL_FLAG_VOLATILE) -- has_volatiles = true; -- } -- } -- controls[0]->has_volatiles = has_volatiles; --} --EXPORT_SYMBOL(v4l2_ctrl_cluster); -- --void v4l2_ctrl_auto_cluster(unsigned ncontrols, struct v4l2_ctrl **controls, -- u8 manual_val, bool set_volatile) --{ -- struct v4l2_ctrl *master = controls[0]; -- u32 flag = 0; -- int i; -- -- v4l2_ctrl_cluster(ncontrols, controls); -- WARN_ON(ncontrols <= 1); -- WARN_ON(manual_val < master->minimum || manual_val > master->maximum); -- WARN_ON(set_volatile && !has_op(master, g_volatile_ctrl)); -- master->is_auto = true; -- master->has_volatiles = set_volatile; -- master->manual_mode_value = manual_val; -- master->flags |= V4L2_CTRL_FLAG_UPDATE; -- -- if (!is_cur_manual(master)) -- flag = V4L2_CTRL_FLAG_INACTIVE | -- (set_volatile ? V4L2_CTRL_FLAG_VOLATILE : 0); -- -- for (i = 1; i < ncontrols; i++) -- if (controls[i]) -- controls[i]->flags |= flag; --} --EXPORT_SYMBOL(v4l2_ctrl_auto_cluster); -- --/* Activate/deactivate a control. */ --void v4l2_ctrl_activate(struct v4l2_ctrl *ctrl, bool active) --{ -- /* invert since the actual flag is called 'inactive' */ -- bool inactive = !active; -- bool old; -- -- if (ctrl == NULL) -- return; -- -- if (inactive) -- /* set V4L2_CTRL_FLAG_INACTIVE */ -- old = test_and_set_bit(4, &ctrl->flags); -- else -- /* clear V4L2_CTRL_FLAG_INACTIVE */ -- old = test_and_clear_bit(4, &ctrl->flags); -- if (old != inactive) -- send_event(NULL, ctrl, V4L2_EVENT_CTRL_CH_FLAGS); --} --EXPORT_SYMBOL(v4l2_ctrl_activate); -- --void __v4l2_ctrl_grab(struct v4l2_ctrl *ctrl, bool grabbed) --{ -- bool old; -- -- if (ctrl == NULL) -- return; -- -- lockdep_assert_held(ctrl->handler->lock); -- -- if (grabbed) -- /* set V4L2_CTRL_FLAG_GRABBED */ -- old = test_and_set_bit(1, &ctrl->flags); -- else -- /* clear V4L2_CTRL_FLAG_GRABBED */ -- old = test_and_clear_bit(1, &ctrl->flags); -- if (old != grabbed) -- send_event(NULL, ctrl, V4L2_EVENT_CTRL_CH_FLAGS); --} --EXPORT_SYMBOL(__v4l2_ctrl_grab); -- --/* Log the control name and value */ --static void log_ctrl(const struct v4l2_ctrl *ctrl, -- const char *prefix, const char *colon) --{ -- if (ctrl->flags & (V4L2_CTRL_FLAG_DISABLED | V4L2_CTRL_FLAG_WRITE_ONLY)) -- return; -- if (ctrl->type == V4L2_CTRL_TYPE_CTRL_CLASS) -- return; -- -- pr_info("%s%s%s: ", prefix, colon, ctrl->name); -- -- ctrl->type_ops->log(ctrl); -- -- if (ctrl->flags & (V4L2_CTRL_FLAG_INACTIVE | -- V4L2_CTRL_FLAG_GRABBED | -- V4L2_CTRL_FLAG_VOLATILE)) { -- if (ctrl->flags & V4L2_CTRL_FLAG_INACTIVE) -- pr_cont(" inactive"); -- if (ctrl->flags & V4L2_CTRL_FLAG_GRABBED) -- pr_cont(" grabbed"); -- if (ctrl->flags & V4L2_CTRL_FLAG_VOLATILE) -- pr_cont(" volatile"); -- } -- pr_cont("\n"); --} -- --/* Log all controls owned by the handler */ --void v4l2_ctrl_handler_log_status(struct v4l2_ctrl_handler *hdl, -- const char *prefix) --{ -- struct v4l2_ctrl *ctrl; -- const char *colon = ""; -- int len; -- -- if (hdl == NULL) -- return; -- if (prefix == NULL) -- prefix = ""; -- len = strlen(prefix); -- if (len && prefix[len - 1] != ' ') -- colon = ": "; -- mutex_lock(hdl->lock); -- list_for_each_entry(ctrl, &hdl->ctrls, node) -- if (!(ctrl->flags & V4L2_CTRL_FLAG_DISABLED)) -- log_ctrl(ctrl, prefix, colon); -- mutex_unlock(hdl->lock); --} --EXPORT_SYMBOL(v4l2_ctrl_handler_log_status); -- --int v4l2_ctrl_subdev_log_status(struct v4l2_subdev *sd) --{ -- v4l2_ctrl_handler_log_status(sd->ctrl_handler, sd->name); -- return 0; --} --EXPORT_SYMBOL(v4l2_ctrl_subdev_log_status); -- --/* Call s_ctrl for all controls owned by the handler */ --int __v4l2_ctrl_handler_setup(struct v4l2_ctrl_handler *hdl) --{ -- struct v4l2_ctrl *ctrl; -- int ret = 0; -- -- if (hdl == NULL) -- return 0; -- -- lockdep_assert_held(hdl->lock); -- -- list_for_each_entry(ctrl, &hdl->ctrls, node) -- ctrl->done = false; -- -- list_for_each_entry(ctrl, &hdl->ctrls, node) { -- struct v4l2_ctrl *master = ctrl->cluster[0]; -- int i; -- -- /* Skip if this control was already handled by a cluster. */ -- /* Skip button controls and read-only controls. */ -- if (ctrl->done || ctrl->type == V4L2_CTRL_TYPE_BUTTON || -- (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY)) -- continue; -- -- for (i = 0; i < master->ncontrols; i++) { -- if (master->cluster[i]) { -- cur_to_new(master->cluster[i]); -- master->cluster[i]->is_new = 1; -- master->cluster[i]->done = true; -- } -- } -- ret = call_op(master, s_ctrl); -- if (ret) -- break; -- } -- -- return ret; --} --EXPORT_SYMBOL_GPL(__v4l2_ctrl_handler_setup); -- --int v4l2_ctrl_handler_setup(struct v4l2_ctrl_handler *hdl) --{ -- int ret; -- -- if (hdl == NULL) -- return 0; -- -- mutex_lock(hdl->lock); -- ret = __v4l2_ctrl_handler_setup(hdl); -- mutex_unlock(hdl->lock); -- -- return ret; --} --EXPORT_SYMBOL(v4l2_ctrl_handler_setup); -- --/* Implement VIDIOC_QUERY_EXT_CTRL */ --int v4l2_query_ext_ctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_query_ext_ctrl *qc) --{ -- const unsigned next_flags = V4L2_CTRL_FLAG_NEXT_CTRL | V4L2_CTRL_FLAG_NEXT_COMPOUND; -- u32 id = qc->id & V4L2_CTRL_ID_MASK; -- struct v4l2_ctrl_ref *ref; -- struct v4l2_ctrl *ctrl; -- -- if (hdl == NULL) -- return -EINVAL; -- -- mutex_lock(hdl->lock); -- -- /* Try to find it */ -- ref = find_ref(hdl, id); -- -- if ((qc->id & next_flags) && !list_empty(&hdl->ctrl_refs)) { -- bool is_compound; -- /* Match any control that is not hidden */ -- unsigned mask = 1; -- bool match = false; -- -- if ((qc->id & next_flags) == V4L2_CTRL_FLAG_NEXT_COMPOUND) { -- /* Match any hidden control */ -- match = true; -- } else if ((qc->id & next_flags) == next_flags) { -- /* Match any control, compound or not */ -- mask = 0; -- } -- -- /* Find the next control with ID > qc->id */ -- -- /* Did we reach the end of the control list? */ -- if (id >= node2id(hdl->ctrl_refs.prev)) { -- ref = NULL; /* Yes, so there is no next control */ -- } else if (ref) { -- /* We found a control with the given ID, so just get -- the next valid one in the list. */ -- list_for_each_entry_continue(ref, &hdl->ctrl_refs, node) { -- is_compound = ref->ctrl->is_array || -- ref->ctrl->type >= V4L2_CTRL_COMPOUND_TYPES; -- if (id < ref->ctrl->id && -- (is_compound & mask) == match) -- break; -- } -- if (&ref->node == &hdl->ctrl_refs) -- ref = NULL; -- } else { -- /* No control with the given ID exists, so start -- searching for the next largest ID. We know there -- is one, otherwise the first 'if' above would have -- been true. */ -- list_for_each_entry(ref, &hdl->ctrl_refs, node) { -- is_compound = ref->ctrl->is_array || -- ref->ctrl->type >= V4L2_CTRL_COMPOUND_TYPES; -- if (id < ref->ctrl->id && -- (is_compound & mask) == match) -- break; -- } -- if (&ref->node == &hdl->ctrl_refs) -- ref = NULL; -- } -- } -- mutex_unlock(hdl->lock); -- -- if (!ref) -- return -EINVAL; -- -- ctrl = ref->ctrl; -- memset(qc, 0, sizeof(*qc)); -- if (id >= V4L2_CID_PRIVATE_BASE) -- qc->id = id; -- else -- qc->id = ctrl->id; -- strscpy(qc->name, ctrl->name, sizeof(qc->name)); -- qc->flags = user_flags(ctrl); -- qc->type = ctrl->type; -- qc->elem_size = ctrl->elem_size; -- qc->elems = ctrl->elems; -- qc->nr_of_dims = ctrl->nr_of_dims; -- memcpy(qc->dims, ctrl->dims, qc->nr_of_dims * sizeof(qc->dims[0])); -- qc->minimum = ctrl->minimum; -- qc->maximum = ctrl->maximum; -- qc->default_value = ctrl->default_value; -- if (ctrl->type == V4L2_CTRL_TYPE_MENU -- || ctrl->type == V4L2_CTRL_TYPE_INTEGER_MENU) -- qc->step = 1; -- else -- qc->step = ctrl->step; -- return 0; --} --EXPORT_SYMBOL(v4l2_query_ext_ctrl); -- --/* Implement VIDIOC_QUERYCTRL */ --int v4l2_queryctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_queryctrl *qc) --{ -- struct v4l2_query_ext_ctrl qec = { qc->id }; -- int rc; -- -- rc = v4l2_query_ext_ctrl(hdl, &qec); -- if (rc) -- return rc; -- -- qc->id = qec.id; -- qc->type = qec.type; -- qc->flags = qec.flags; -- strscpy(qc->name, qec.name, sizeof(qc->name)); -- switch (qc->type) { -- case V4L2_CTRL_TYPE_INTEGER: -- case V4L2_CTRL_TYPE_BOOLEAN: -- case V4L2_CTRL_TYPE_MENU: -- case V4L2_CTRL_TYPE_INTEGER_MENU: -- case V4L2_CTRL_TYPE_STRING: -- case V4L2_CTRL_TYPE_BITMASK: -- qc->minimum = qec.minimum; -- qc->maximum = qec.maximum; -- qc->step = qec.step; -- qc->default_value = qec.default_value; -- break; -- default: -- qc->minimum = 0; -- qc->maximum = 0; -- qc->step = 0; -- qc->default_value = 0; -- break; -- } -- return 0; --} --EXPORT_SYMBOL(v4l2_queryctrl); -- --/* Implement VIDIOC_QUERYMENU */ --int v4l2_querymenu(struct v4l2_ctrl_handler *hdl, struct v4l2_querymenu *qm) --{ -- struct v4l2_ctrl *ctrl; -- u32 i = qm->index; -- -- ctrl = v4l2_ctrl_find(hdl, qm->id); -- if (!ctrl) -- return -EINVAL; -- -- qm->reserved = 0; -- /* Sanity checks */ -- switch (ctrl->type) { -- case V4L2_CTRL_TYPE_MENU: -- if (ctrl->qmenu == NULL) -- return -EINVAL; -- break; -- case V4L2_CTRL_TYPE_INTEGER_MENU: -- if (ctrl->qmenu_int == NULL) -- return -EINVAL; -- break; -- default: -- return -EINVAL; -- } -- -- if (i < ctrl->minimum || i > ctrl->maximum) -- return -EINVAL; -- -- /* Use mask to see if this menu item should be skipped */ -- if (ctrl->menu_skip_mask & (1ULL << i)) -- return -EINVAL; -- /* Empty menu items should also be skipped */ -- if (ctrl->type == V4L2_CTRL_TYPE_MENU) { -- if (ctrl->qmenu[i] == NULL || ctrl->qmenu[i][0] == '\0') -- return -EINVAL; -- strscpy(qm->name, ctrl->qmenu[i], sizeof(qm->name)); -- } else { -- qm->value = ctrl->qmenu_int[i]; -- } -- return 0; --} --EXPORT_SYMBOL(v4l2_querymenu); -- --static int v4l2_ctrl_request_clone(struct v4l2_ctrl_handler *hdl, -- const struct v4l2_ctrl_handler *from) --{ -- struct v4l2_ctrl_ref *ref; -- int err = 0; -- -- if (WARN_ON(!hdl || hdl == from)) -- return -EINVAL; -- -- if (hdl->error) -- return hdl->error; -- -- WARN_ON(hdl->lock != &hdl->_lock); -- -- mutex_lock(from->lock); -- list_for_each_entry(ref, &from->ctrl_refs, node) { -- struct v4l2_ctrl *ctrl = ref->ctrl; -- struct v4l2_ctrl_ref *new_ref; -- -- /* Skip refs inherited from other devices */ -- if (ref->from_other_dev) -- continue; -- err = handler_new_ref(hdl, ctrl, &new_ref, false, true); -- if (err) -- break; -- } -- mutex_unlock(from->lock); -- return err; --} -- --static void v4l2_ctrl_request_queue(struct media_request_object *obj) --{ -- struct v4l2_ctrl_handler *hdl = -- container_of(obj, struct v4l2_ctrl_handler, req_obj); -- struct v4l2_ctrl_handler *main_hdl = obj->priv; -- -- mutex_lock(main_hdl->lock); -- list_add_tail(&hdl->requests_queued, &main_hdl->requests_queued); -- hdl->request_is_queued = true; -- mutex_unlock(main_hdl->lock); --} -- --static void v4l2_ctrl_request_unbind(struct media_request_object *obj) --{ -- struct v4l2_ctrl_handler *hdl = -- container_of(obj, struct v4l2_ctrl_handler, req_obj); -- struct v4l2_ctrl_handler *main_hdl = obj->priv; -- -- mutex_lock(main_hdl->lock); -- list_del_init(&hdl->requests); -- if (hdl->request_is_queued) { -- list_del_init(&hdl->requests_queued); -- hdl->request_is_queued = false; -- } -- mutex_unlock(main_hdl->lock); --} -- --static void v4l2_ctrl_request_release(struct media_request_object *obj) --{ -- struct v4l2_ctrl_handler *hdl = -- container_of(obj, struct v4l2_ctrl_handler, req_obj); -- -- v4l2_ctrl_handler_free(hdl); -- kfree(hdl); --} -- --static const struct media_request_object_ops req_ops = { -- .queue = v4l2_ctrl_request_queue, -- .unbind = v4l2_ctrl_request_unbind, -- .release = v4l2_ctrl_request_release, --}; -- --struct v4l2_ctrl_handler *v4l2_ctrl_request_hdl_find(struct media_request *req, -- struct v4l2_ctrl_handler *parent) --{ -- struct media_request_object *obj; -- -- if (WARN_ON(req->state != MEDIA_REQUEST_STATE_VALIDATING && -- req->state != MEDIA_REQUEST_STATE_QUEUED)) -- return NULL; -- -- obj = media_request_object_find(req, &req_ops, parent); -- if (obj) -- return container_of(obj, struct v4l2_ctrl_handler, req_obj); -- return NULL; --} --EXPORT_SYMBOL_GPL(v4l2_ctrl_request_hdl_find); -- --struct v4l2_ctrl * --v4l2_ctrl_request_hdl_ctrl_find(struct v4l2_ctrl_handler *hdl, u32 id) --{ -- struct v4l2_ctrl_ref *ref = find_ref_lock(hdl, id); -- -- return (ref && ref->valid_p_req) ? ref->ctrl : NULL; --} --EXPORT_SYMBOL_GPL(v4l2_ctrl_request_hdl_ctrl_find); -- --static int v4l2_ctrl_request_bind(struct media_request *req, -- struct v4l2_ctrl_handler *hdl, -- struct v4l2_ctrl_handler *from) --{ -- int ret; -- -- ret = v4l2_ctrl_request_clone(hdl, from); -- -- if (!ret) { -- ret = media_request_object_bind(req, &req_ops, -- from, false, &hdl->req_obj); -- if (!ret) { -- mutex_lock(from->lock); -- list_add_tail(&hdl->requests, &from->requests); -- mutex_unlock(from->lock); -- } -- } -- return ret; --} -- --/* Some general notes on the atomic requirements of VIDIOC_G/TRY/S_EXT_CTRLS: -- -- It is not a fully atomic operation, just best-effort only. After all, if -- multiple controls have to be set through multiple i2c writes (for example) -- then some initial writes may succeed while others fail. Thus leaving the -- system in an inconsistent state. The question is how much effort you are -- willing to spend on trying to make something atomic that really isn't. -- -- From the point of view of an application the main requirement is that -- when you call VIDIOC_S_EXT_CTRLS and some values are invalid then an -- error should be returned without actually affecting any controls. -- -- If all the values are correct, then it is acceptable to just give up -- in case of low-level errors. -- -- It is important though that the application can tell when only a partial -- configuration was done. The way we do that is through the error_idx field -- of struct v4l2_ext_controls: if that is equal to the count field then no -- controls were affected. Otherwise all controls before that index were -- successful in performing their 'get' or 'set' operation, the control at -- the given index failed, and you don't know what happened with the controls -- after the failed one. Since if they were part of a control cluster they -- could have been successfully processed (if a cluster member was encountered -- at index < error_idx), they could have failed (if a cluster member was at -- error_idx), or they may not have been processed yet (if the first cluster -- member appeared after error_idx). -- -- It is all fairly theoretical, though. In practice all you can do is to -- bail out. If error_idx == count, then it is an application bug. If -- error_idx < count then it is only an application bug if the error code was -- EBUSY. That usually means that something started streaming just when you -- tried to set the controls. In all other cases it is a driver/hardware -- problem and all you can do is to retry or bail out. -- -- Note that these rules do not apply to VIDIOC_TRY_EXT_CTRLS: since that -- never modifies controls the error_idx is just set to whatever control -- has an invalid value. -- */ -- --/* Prepare for the extended g/s/try functions. -- Find the controls in the control array and do some basic checks. */ --static int prepare_ext_ctrls(struct v4l2_ctrl_handler *hdl, -- struct v4l2_ext_controls *cs, -- struct v4l2_ctrl_helper *helpers, -- struct video_device *vdev, -- bool get) --{ -- struct v4l2_ctrl_helper *h; -- bool have_clusters = false; -- u32 i; -- -- for (i = 0, h = helpers; i < cs->count; i++, h++) { -- struct v4l2_ext_control *c = &cs->controls[i]; -- struct v4l2_ctrl_ref *ref; -- struct v4l2_ctrl *ctrl; -- u32 id = c->id & V4L2_CTRL_ID_MASK; -- -- cs->error_idx = i; -- -- if (cs->which && -- cs->which != V4L2_CTRL_WHICH_DEF_VAL && -- cs->which != V4L2_CTRL_WHICH_REQUEST_VAL && -- V4L2_CTRL_ID2WHICH(id) != cs->which) { -- dprintk(vdev, -- "invalid which 0x%x or control id 0x%x\n", -- cs->which, id); -- return -EINVAL; -- } -- -- /* Old-style private controls are not allowed for -- extended controls */ -- if (id >= V4L2_CID_PRIVATE_BASE) { -- dprintk(vdev, -- "old-style private controls not allowed\n"); -- return -EINVAL; -- } -- ref = find_ref_lock(hdl, id); -- if (ref == NULL) { -- dprintk(vdev, "cannot find control id 0x%x\n", id); -- return -EINVAL; -- } -- h->ref = ref; -- ctrl = ref->ctrl; -- if (ctrl->flags & V4L2_CTRL_FLAG_DISABLED) { -- dprintk(vdev, "control id 0x%x is disabled\n", id); -- return -EINVAL; -- } -- -- if (ctrl->cluster[0]->ncontrols > 1) -- have_clusters = true; -- if (ctrl->cluster[0] != ctrl) -- ref = find_ref_lock(hdl, ctrl->cluster[0]->id); -- if (ctrl->is_ptr && !ctrl->is_string) { -- unsigned tot_size = ctrl->elems * ctrl->elem_size; -- -- if (c->size < tot_size) { -- /* -- * In the get case the application first -- * queries to obtain the size of the control. -- */ -- if (get) { -- c->size = tot_size; -- return -ENOSPC; -- } -- dprintk(vdev, -- "pointer control id 0x%x size too small, %d bytes but %d bytes needed\n", -- id, c->size, tot_size); -- return -EFAULT; -- } -- c->size = tot_size; -- } -- /* Store the ref to the master control of the cluster */ -- h->mref = ref; -- /* Initially set next to 0, meaning that there is no other -- control in this helper array belonging to the same -- cluster */ -- h->next = 0; -- } -- -- /* We are done if there were no controls that belong to a multi- -- control cluster. */ -- if (!have_clusters) -- return 0; -- -- /* The code below figures out in O(n) time which controls in the list -- belong to the same cluster. */ -- -- /* This has to be done with the handler lock taken. */ -- mutex_lock(hdl->lock); -- -- /* First zero the helper field in the master control references */ -- for (i = 0; i < cs->count; i++) -- helpers[i].mref->helper = NULL; -- for (i = 0, h = helpers; i < cs->count; i++, h++) { -- struct v4l2_ctrl_ref *mref = h->mref; -- -- /* If the mref->helper is set, then it points to an earlier -- helper that belongs to the same cluster. */ -- if (mref->helper) { -- /* Set the next field of mref->helper to the current -- index: this means that that earlier helper now -- points to the next helper in the same cluster. */ -- mref->helper->next = i; -- /* mref should be set only for the first helper in the -- cluster, clear the others. */ -- h->mref = NULL; -- } -- /* Point the mref helper to the current helper struct. */ -- mref->helper = h; -- } -- mutex_unlock(hdl->lock); -- return 0; --} -- --/* Handles the corner case where cs->count == 0. It checks whether the -- specified control class exists. If that class ID is 0, then it checks -- whether there are any controls at all. */ --static int class_check(struct v4l2_ctrl_handler *hdl, u32 which) --{ -- if (which == 0 || which == V4L2_CTRL_WHICH_DEF_VAL || -- which == V4L2_CTRL_WHICH_REQUEST_VAL) -- return 0; -- return find_ref_lock(hdl, which | 1) ? 0 : -EINVAL; --} -- --/* -- * Get extended controls. Allocates the helpers array if needed. -- * -- * Note that v4l2_g_ext_ctrls_common() with 'which' set to -- * V4L2_CTRL_WHICH_REQUEST_VAL is only called if the request was -- * completed, and in that case valid_p_req is true for all controls. -- */ --static int v4l2_g_ext_ctrls_common(struct v4l2_ctrl_handler *hdl, -- struct v4l2_ext_controls *cs, -- struct video_device *vdev) --{ -- struct v4l2_ctrl_helper helper[4]; -- struct v4l2_ctrl_helper *helpers = helper; -- int ret; -- int i, j; -- bool is_default, is_request; -- -- is_default = (cs->which == V4L2_CTRL_WHICH_DEF_VAL); -- is_request = (cs->which == V4L2_CTRL_WHICH_REQUEST_VAL); -- -- cs->error_idx = cs->count; -- cs->which = V4L2_CTRL_ID2WHICH(cs->which); -- -- if (hdl == NULL) -- return -EINVAL; -- -- if (cs->count == 0) -- return class_check(hdl, cs->which); -- -- if (cs->count > ARRAY_SIZE(helper)) { -- helpers = kvmalloc_array(cs->count, sizeof(helper[0]), -- GFP_KERNEL); -- if (helpers == NULL) -- return -ENOMEM; -- } -- -- ret = prepare_ext_ctrls(hdl, cs, helpers, vdev, true); -- cs->error_idx = cs->count; -- -- for (i = 0; !ret && i < cs->count; i++) -- if (helpers[i].ref->ctrl->flags & V4L2_CTRL_FLAG_WRITE_ONLY) -- ret = -EACCES; -- -- for (i = 0; !ret && i < cs->count; i++) { -- struct v4l2_ctrl *master; -- bool is_volatile = false; -- u32 idx = i; -- -- if (helpers[i].mref == NULL) -- continue; -- -- master = helpers[i].mref->ctrl; -- cs->error_idx = i; -- -- v4l2_ctrl_lock(master); -- -- /* -- * g_volatile_ctrl will update the new control values. -- * This makes no sense for V4L2_CTRL_WHICH_DEF_VAL and -- * V4L2_CTRL_WHICH_REQUEST_VAL. In the case of requests -- * it is v4l2_ctrl_request_complete() that copies the -- * volatile controls at the time of request completion -- * to the request, so you don't want to do that again. -- */ -- if (!is_default && !is_request && -- ((master->flags & V4L2_CTRL_FLAG_VOLATILE) || -- (master->has_volatiles && !is_cur_manual(master)))) { -- for (j = 0; j < master->ncontrols; j++) -- cur_to_new(master->cluster[j]); -- ret = call_op(master, g_volatile_ctrl); -- is_volatile = true; -- } -- -- if (ret) { -- v4l2_ctrl_unlock(master); -- break; -- } -- -- /* -- * Copy the default value (if is_default is true), the -- * request value (if is_request is true and p_req is valid), -- * the new volatile value (if is_volatile is true) or the -- * current value. -- */ -- do { -- struct v4l2_ctrl_ref *ref = helpers[idx].ref; -- -- if (is_default) -- ret = def_to_user(cs->controls + idx, ref->ctrl); -- else if (is_request && ref->valid_p_req) -- ret = req_to_user(cs->controls + idx, ref); -- else if (is_volatile) -- ret = new_to_user(cs->controls + idx, ref->ctrl); -- else -- ret = cur_to_user(cs->controls + idx, ref->ctrl); -- idx = helpers[idx].next; -- } while (!ret && idx); -- -- v4l2_ctrl_unlock(master); -- } -- -- if (cs->count > ARRAY_SIZE(helper)) -- kvfree(helpers); -- return ret; --} -- --static struct media_request_object * --v4l2_ctrls_find_req_obj(struct v4l2_ctrl_handler *hdl, -- struct media_request *req, bool set) --{ -- struct media_request_object *obj; -- struct v4l2_ctrl_handler *new_hdl; -- int ret; -- -- if (IS_ERR(req)) -- return ERR_CAST(req); -- -- if (set && WARN_ON(req->state != MEDIA_REQUEST_STATE_UPDATING)) -- return ERR_PTR(-EBUSY); -- -- obj = media_request_object_find(req, &req_ops, hdl); -- if (obj) -- return obj; -- if (!set) -- return ERR_PTR(-ENOENT); -- -- new_hdl = kzalloc(sizeof(*new_hdl), GFP_KERNEL); -- if (!new_hdl) -- return ERR_PTR(-ENOMEM); -- -- obj = &new_hdl->req_obj; -- ret = v4l2_ctrl_handler_init(new_hdl, (hdl->nr_of_buckets - 1) * 8); -- if (!ret) -- ret = v4l2_ctrl_request_bind(req, new_hdl, hdl); -- if (ret) { -- kfree(new_hdl); -- -- return ERR_PTR(ret); -- } -- -- media_request_object_get(obj); -- return obj; --} -- --int v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct video_device *vdev, -- struct media_device *mdev, struct v4l2_ext_controls *cs) --{ -- struct media_request_object *obj = NULL; -- struct media_request *req = NULL; -- int ret; -- -- if (cs->which == V4L2_CTRL_WHICH_REQUEST_VAL) { -- if (!mdev || cs->request_fd < 0) -- return -EINVAL; -- -- req = media_request_get_by_fd(mdev, cs->request_fd); -- if (IS_ERR(req)) -- return PTR_ERR(req); -- -- if (req->state != MEDIA_REQUEST_STATE_COMPLETE) { -- media_request_put(req); -- return -EACCES; -- } -- -- ret = media_request_lock_for_access(req); -- if (ret) { -- media_request_put(req); -- return ret; -- } -- -- obj = v4l2_ctrls_find_req_obj(hdl, req, false); -- if (IS_ERR(obj)) { -- media_request_unlock_for_access(req); -- media_request_put(req); -- return PTR_ERR(obj); -- } -- -- hdl = container_of(obj, struct v4l2_ctrl_handler, -- req_obj); -- } -- -- ret = v4l2_g_ext_ctrls_common(hdl, cs, vdev); -- -- if (obj) { -- media_request_unlock_for_access(req); -- media_request_object_put(obj); -- media_request_put(req); -- } -- return ret; --} --EXPORT_SYMBOL(v4l2_g_ext_ctrls); -- --/* Helper function to get a single control */ --static int get_ctrl(struct v4l2_ctrl *ctrl, struct v4l2_ext_control *c) --{ -- struct v4l2_ctrl *master = ctrl->cluster[0]; -- int ret = 0; -- int i; -- -- /* Compound controls are not supported. The new_to_user() and -- * cur_to_user() calls below would need to be modified not to access -- * userspace memory when called from get_ctrl(). -- */ -- if (!ctrl->is_int && ctrl->type != V4L2_CTRL_TYPE_INTEGER64) -- return -EINVAL; -- -- if (ctrl->flags & V4L2_CTRL_FLAG_WRITE_ONLY) -- return -EACCES; -- -- v4l2_ctrl_lock(master); -- /* g_volatile_ctrl will update the current control values */ -- if (ctrl->flags & V4L2_CTRL_FLAG_VOLATILE) { -- for (i = 0; i < master->ncontrols; i++) -- cur_to_new(master->cluster[i]); -- ret = call_op(master, g_volatile_ctrl); -- new_to_user(c, ctrl); -- } else { -- cur_to_user(c, ctrl); -- } -- v4l2_ctrl_unlock(master); -- return ret; --} -- --int v4l2_g_ctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_control *control) --{ -- struct v4l2_ctrl *ctrl = v4l2_ctrl_find(hdl, control->id); -- struct v4l2_ext_control c; -- int ret; -- -- if (ctrl == NULL || !ctrl->is_int) -- return -EINVAL; -- ret = get_ctrl(ctrl, &c); -- control->value = c.value; -- return ret; --} --EXPORT_SYMBOL(v4l2_g_ctrl); -- --s32 v4l2_ctrl_g_ctrl(struct v4l2_ctrl *ctrl) --{ -- struct v4l2_ext_control c; -- -- /* It's a driver bug if this happens. */ -- if (WARN_ON(!ctrl->is_int)) -- return 0; -- c.value = 0; -- get_ctrl(ctrl, &c); -- return c.value; --} --EXPORT_SYMBOL(v4l2_ctrl_g_ctrl); -- --s64 v4l2_ctrl_g_ctrl_int64(struct v4l2_ctrl *ctrl) --{ -- struct v4l2_ext_control c; -- -- /* It's a driver bug if this happens. */ -- if (WARN_ON(ctrl->is_ptr || ctrl->type != V4L2_CTRL_TYPE_INTEGER64)) -- return 0; -- c.value64 = 0; -- get_ctrl(ctrl, &c); -- return c.value64; --} --EXPORT_SYMBOL(v4l2_ctrl_g_ctrl_int64); -- -- --/* Core function that calls try/s_ctrl and ensures that the new value is -- copied to the current value on a set. -- Must be called with ctrl->handler->lock held. */ --static int try_or_set_cluster(struct v4l2_fh *fh, struct v4l2_ctrl *master, -- bool set, u32 ch_flags) --{ -- bool update_flag; -- int ret; -- int i; -- -- /* Go through the cluster and either validate the new value or -- (if no new value was set), copy the current value to the new -- value, ensuring a consistent view for the control ops when -- called. */ -- for (i = 0; i < master->ncontrols; i++) { -- struct v4l2_ctrl *ctrl = master->cluster[i]; -- -- if (ctrl == NULL) -- continue; -- -- if (!ctrl->is_new) { -- cur_to_new(ctrl); -- continue; -- } -- /* Check again: it may have changed since the -- previous check in try_or_set_ext_ctrls(). */ -- if (set && (ctrl->flags & V4L2_CTRL_FLAG_GRABBED)) -- return -EBUSY; -- } -- -- ret = call_op(master, try_ctrl); -- -- /* Don't set if there is no change */ -- if (ret || !set || !cluster_changed(master)) -- return ret; -- ret = call_op(master, s_ctrl); -- if (ret) -- return ret; -- -- /* If OK, then make the new values permanent. */ -- update_flag = is_cur_manual(master) != is_new_manual(master); -- -- for (i = 0; i < master->ncontrols; i++) { -- /* -- * If we switch from auto to manual mode, and this cluster -- * contains volatile controls, then all non-master controls -- * have to be marked as changed. The 'new' value contains -- * the volatile value (obtained by update_from_auto_cluster), -- * which now has to become the current value. -- */ -- if (i && update_flag && is_new_manual(master) && -- master->has_volatiles && master->cluster[i]) -- master->cluster[i]->has_changed = true; -- -- new_to_cur(fh, master->cluster[i], ch_flags | -- ((update_flag && i > 0) ? V4L2_EVENT_CTRL_CH_FLAGS : 0)); -- } -- return 0; --} -- --/* Validate controls. */ --static int validate_ctrls(struct v4l2_ext_controls *cs, -- struct v4l2_ctrl_helper *helpers, -- struct video_device *vdev, -- bool set) --{ -- unsigned i; -- int ret = 0; -- -- cs->error_idx = cs->count; -- for (i = 0; i < cs->count; i++) { -- struct v4l2_ctrl *ctrl = helpers[i].ref->ctrl; -- union v4l2_ctrl_ptr p_new; -- -- cs->error_idx = i; -- -- if (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY) { -- dprintk(vdev, -- "control id 0x%x is read-only\n", -- ctrl->id); -- return -EACCES; -- } -- /* This test is also done in try_set_control_cluster() which -- is called in atomic context, so that has the final say, -- but it makes sense to do an up-front check as well. Once -- an error occurs in try_set_control_cluster() some other -- controls may have been set already and we want to do a -- best-effort to avoid that. */ -- if (set && (ctrl->flags & V4L2_CTRL_FLAG_GRABBED)) { -- dprintk(vdev, -- "control id 0x%x is grabbed, cannot set\n", -- ctrl->id); -- return -EBUSY; -- } -- /* -- * Skip validation for now if the payload needs to be copied -- * from userspace into kernelspace. We'll validate those later. -- */ -- if (ctrl->is_ptr) -- continue; -- if (ctrl->type == V4L2_CTRL_TYPE_INTEGER64) -- p_new.p_s64 = &cs->controls[i].value64; -- else -- p_new.p_s32 = &cs->controls[i].value; -- ret = validate_new(ctrl, p_new); -- if (ret) -- return ret; -- } -- return 0; --} -- --/* Obtain the current volatile values of an autocluster and mark them -- as new. */ --static void update_from_auto_cluster(struct v4l2_ctrl *master) --{ -- int i; -- -- for (i = 1; i < master->ncontrols; i++) -- cur_to_new(master->cluster[i]); -- if (!call_op(master, g_volatile_ctrl)) -- for (i = 1; i < master->ncontrols; i++) -- if (master->cluster[i]) -- master->cluster[i]->is_new = 1; --} -- --/* Try or try-and-set controls */ --static int try_set_ext_ctrls_common(struct v4l2_fh *fh, -- struct v4l2_ctrl_handler *hdl, -- struct v4l2_ext_controls *cs, -- struct video_device *vdev, bool set) --{ -- struct v4l2_ctrl_helper helper[4]; -- struct v4l2_ctrl_helper *helpers = helper; -- unsigned i, j; -- int ret; -- -- cs->error_idx = cs->count; -- -- /* Default value cannot be changed */ -- if (cs->which == V4L2_CTRL_WHICH_DEF_VAL) { -- dprintk(vdev, "%s: cannot change default value\n", -- video_device_node_name(vdev)); -- return -EINVAL; -- } -- -- cs->which = V4L2_CTRL_ID2WHICH(cs->which); -- -- if (hdl == NULL) { -- dprintk(vdev, "%s: invalid null control handler\n", -- video_device_node_name(vdev)); -- return -EINVAL; -- } -- -- if (cs->count == 0) -- return class_check(hdl, cs->which); -- -- if (cs->count > ARRAY_SIZE(helper)) { -- helpers = kvmalloc_array(cs->count, sizeof(helper[0]), -- GFP_KERNEL); -- if (!helpers) -- return -ENOMEM; -- } -- ret = prepare_ext_ctrls(hdl, cs, helpers, vdev, false); -- if (!ret) -- ret = validate_ctrls(cs, helpers, vdev, set); -- if (ret && set) -- cs->error_idx = cs->count; -- for (i = 0; !ret && i < cs->count; i++) { -- struct v4l2_ctrl *master; -- u32 idx = i; -- -- if (helpers[i].mref == NULL) -- continue; -- -- cs->error_idx = i; -- master = helpers[i].mref->ctrl; -- v4l2_ctrl_lock(master); -- -- /* Reset the 'is_new' flags of the cluster */ -- for (j = 0; j < master->ncontrols; j++) -- if (master->cluster[j]) -- master->cluster[j]->is_new = 0; -- -- /* For volatile autoclusters that are currently in auto mode -- we need to discover if it will be set to manual mode. -- If so, then we have to copy the current volatile values -- first since those will become the new manual values (which -- may be overwritten by explicit new values from this set -- of controls). */ -- if (master->is_auto && master->has_volatiles && -- !is_cur_manual(master)) { -- /* Pick an initial non-manual value */ -- s32 new_auto_val = master->manual_mode_value + 1; -- u32 tmp_idx = idx; -- -- do { -- /* Check if the auto control is part of the -- list, and remember the new value. */ -- if (helpers[tmp_idx].ref->ctrl == master) -- new_auto_val = cs->controls[tmp_idx].value; -- tmp_idx = helpers[tmp_idx].next; -- } while (tmp_idx); -- /* If the new value == the manual value, then copy -- the current volatile values. */ -- if (new_auto_val == master->manual_mode_value) -- update_from_auto_cluster(master); -- } -- -- /* Copy the new caller-supplied control values. -- user_to_new() sets 'is_new' to 1. */ -- do { -- struct v4l2_ctrl *ctrl = helpers[idx].ref->ctrl; -- -- ret = user_to_new(cs->controls + idx, ctrl); -- if (!ret && ctrl->is_ptr) { -- ret = validate_new(ctrl, ctrl->p_new); -- if (ret) -- dprintk(vdev, -- "failed to validate control %s (%d)\n", -- v4l2_ctrl_get_name(ctrl->id), ret); -- } -- idx = helpers[idx].next; -- } while (!ret && idx); -- -- if (!ret) -- ret = try_or_set_cluster(fh, master, -- !hdl->req_obj.req && set, 0); -- if (!ret && hdl->req_obj.req && set) { -- for (j = 0; j < master->ncontrols; j++) { -- struct v4l2_ctrl_ref *ref = -- find_ref(hdl, master->cluster[j]->id); -- -- new_to_req(ref); -- } -- } -- -- /* Copy the new values back to userspace. */ -- if (!ret) { -- idx = i; -- do { -- ret = new_to_user(cs->controls + idx, -- helpers[idx].ref->ctrl); -- idx = helpers[idx].next; -- } while (!ret && idx); -- } -- v4l2_ctrl_unlock(master); -- } -- -- if (cs->count > ARRAY_SIZE(helper)) -- kvfree(helpers); -- return ret; --} -- --static int try_set_ext_ctrls(struct v4l2_fh *fh, -- struct v4l2_ctrl_handler *hdl, -- struct video_device *vdev, -- struct media_device *mdev, -- struct v4l2_ext_controls *cs, bool set) --{ -- struct media_request_object *obj = NULL; -- struct media_request *req = NULL; -- int ret; -- -- if (cs->which == V4L2_CTRL_WHICH_REQUEST_VAL) { -- if (!mdev) { -- dprintk(vdev, "%s: missing media device\n", -- video_device_node_name(vdev)); -- return -EINVAL; -- } -- -- if (cs->request_fd < 0) { -- dprintk(vdev, "%s: invalid request fd %d\n", -- video_device_node_name(vdev), cs->request_fd); -- return -EINVAL; -- } -- -- req = media_request_get_by_fd(mdev, cs->request_fd); -- if (IS_ERR(req)) { -- dprintk(vdev, "%s: cannot find request fd %d\n", -- video_device_node_name(vdev), cs->request_fd); -- return PTR_ERR(req); -- } -- -- ret = media_request_lock_for_update(req); -- if (ret) { -- dprintk(vdev, "%s: cannot lock request fd %d\n", -- video_device_node_name(vdev), cs->request_fd); -- media_request_put(req); -- return ret; -- } -- -- obj = v4l2_ctrls_find_req_obj(hdl, req, set); -- if (IS_ERR(obj)) { -- dprintk(vdev, -- "%s: cannot find request object for request fd %d\n", -- video_device_node_name(vdev), -- cs->request_fd); -- media_request_unlock_for_update(req); -- media_request_put(req); -- return PTR_ERR(obj); -- } -- hdl = container_of(obj, struct v4l2_ctrl_handler, -- req_obj); -- } -- -- ret = try_set_ext_ctrls_common(fh, hdl, cs, vdev, set); -- if (ret) -- dprintk(vdev, -- "%s: try_set_ext_ctrls_common failed (%d)\n", -- video_device_node_name(vdev), ret); -- -- if (obj) { -- media_request_unlock_for_update(req); -- media_request_object_put(obj); -- media_request_put(req); -- } -- -- return ret; --} -- --int v4l2_try_ext_ctrls(struct v4l2_ctrl_handler *hdl, -- struct video_device *vdev, -- struct media_device *mdev, -- struct v4l2_ext_controls *cs) --{ -- return try_set_ext_ctrls(NULL, hdl, vdev, mdev, cs, false); --} --EXPORT_SYMBOL(v4l2_try_ext_ctrls); -- --int v4l2_s_ext_ctrls(struct v4l2_fh *fh, -- struct v4l2_ctrl_handler *hdl, -- struct video_device *vdev, -- struct media_device *mdev, -- struct v4l2_ext_controls *cs) --{ -- return try_set_ext_ctrls(fh, hdl, vdev, mdev, cs, true); --} --EXPORT_SYMBOL(v4l2_s_ext_ctrls); -- --/* Helper function for VIDIOC_S_CTRL compatibility */ --static int set_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, u32 ch_flags) --{ -- struct v4l2_ctrl *master = ctrl->cluster[0]; -- int ret; -- int i; -- -- /* Reset the 'is_new' flags of the cluster */ -- for (i = 0; i < master->ncontrols; i++) -- if (master->cluster[i]) -- master->cluster[i]->is_new = 0; -- -- ret = validate_new(ctrl, ctrl->p_new); -- if (ret) -- return ret; -- -- /* For autoclusters with volatiles that are switched from auto to -- manual mode we have to update the current volatile values since -- those will become the initial manual values after such a switch. */ -- if (master->is_auto && master->has_volatiles && ctrl == master && -- !is_cur_manual(master) && ctrl->val == master->manual_mode_value) -- update_from_auto_cluster(master); -- -- ctrl->is_new = 1; -- return try_or_set_cluster(fh, master, true, ch_flags); --} -- --/* Helper function for VIDIOC_S_CTRL compatibility */ --static int set_ctrl_lock(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, -- struct v4l2_ext_control *c) --{ -- int ret; -- -- v4l2_ctrl_lock(ctrl); -- user_to_new(c, ctrl); -- ret = set_ctrl(fh, ctrl, 0); -- if (!ret) -- cur_to_user(c, ctrl); -- v4l2_ctrl_unlock(ctrl); -- return ret; --} -- --int v4l2_s_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl, -- struct v4l2_control *control) --{ -- struct v4l2_ctrl *ctrl = v4l2_ctrl_find(hdl, control->id); -- struct v4l2_ext_control c = { control->id }; -- int ret; -- -- if (ctrl == NULL || !ctrl->is_int) -- return -EINVAL; -- -- if (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY) -- return -EACCES; -- -- c.value = control->value; -- ret = set_ctrl_lock(fh, ctrl, &c); -- control->value = c.value; -- return ret; --} --EXPORT_SYMBOL(v4l2_s_ctrl); -- --int __v4l2_ctrl_s_ctrl(struct v4l2_ctrl *ctrl, s32 val) --{ -- lockdep_assert_held(ctrl->handler->lock); -- -- /* It's a driver bug if this happens. */ -- if (WARN_ON(!ctrl->is_int)) -- return -EINVAL; -- ctrl->val = val; -- return set_ctrl(NULL, ctrl, 0); --} --EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl); -- --int __v4l2_ctrl_s_ctrl_int64(struct v4l2_ctrl *ctrl, s64 val) --{ -- lockdep_assert_held(ctrl->handler->lock); -- -- /* It's a driver bug if this happens. */ -- if (WARN_ON(ctrl->is_ptr || ctrl->type != V4L2_CTRL_TYPE_INTEGER64)) -- return -EINVAL; -- *ctrl->p_new.p_s64 = val; -- return set_ctrl(NULL, ctrl, 0); --} --EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl_int64); -- --int __v4l2_ctrl_s_ctrl_string(struct v4l2_ctrl *ctrl, const char *s) --{ -- lockdep_assert_held(ctrl->handler->lock); -- -- /* It's a driver bug if this happens. */ -- if (WARN_ON(ctrl->type != V4L2_CTRL_TYPE_STRING)) -- return -EINVAL; -- strscpy(ctrl->p_new.p_char, s, ctrl->maximum + 1); -- return set_ctrl(NULL, ctrl, 0); --} --EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl_string); -- --int __v4l2_ctrl_s_ctrl_compound(struct v4l2_ctrl *ctrl, -- enum v4l2_ctrl_type type, const void *p) --{ -- lockdep_assert_held(ctrl->handler->lock); -- -- /* It's a driver bug if this happens. */ -- if (WARN_ON(ctrl->type != type)) -- return -EINVAL; -- memcpy(ctrl->p_new.p, p, ctrl->elems * ctrl->elem_size); -- return set_ctrl(NULL, ctrl, 0); --} --EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl_compound); -- --void v4l2_ctrl_request_complete(struct media_request *req, -- struct v4l2_ctrl_handler *main_hdl) --{ -- struct media_request_object *obj; -- struct v4l2_ctrl_handler *hdl; -- struct v4l2_ctrl_ref *ref; -- -- if (!req || !main_hdl) -- return; -- -- /* -- * Note that it is valid if nothing was found. It means -- * that this request doesn't have any controls and so just -- * wants to leave the controls unchanged. -- */ -- obj = media_request_object_find(req, &req_ops, main_hdl); -- if (!obj) -- return; -- hdl = container_of(obj, struct v4l2_ctrl_handler, req_obj); -- -- list_for_each_entry(ref, &hdl->ctrl_refs, node) { -- struct v4l2_ctrl *ctrl = ref->ctrl; -- struct v4l2_ctrl *master = ctrl->cluster[0]; -- unsigned int i; -- -- if (ctrl->flags & V4L2_CTRL_FLAG_VOLATILE) { -- v4l2_ctrl_lock(master); -- /* g_volatile_ctrl will update the current control values */ -- for (i = 0; i < master->ncontrols; i++) -- cur_to_new(master->cluster[i]); -- call_op(master, g_volatile_ctrl); -- new_to_req(ref); -- v4l2_ctrl_unlock(master); -- continue; -- } -- if (ref->valid_p_req) -- continue; -- -- /* Copy the current control value into the request */ -- v4l2_ctrl_lock(ctrl); -- cur_to_req(ref); -- v4l2_ctrl_unlock(ctrl); -- } -- -- mutex_lock(main_hdl->lock); -- WARN_ON(!hdl->request_is_queued); -- list_del_init(&hdl->requests_queued); -- hdl->request_is_queued = false; -- mutex_unlock(main_hdl->lock); -- media_request_object_complete(obj); -- media_request_object_put(obj); --} --EXPORT_SYMBOL(v4l2_ctrl_request_complete); -- --int v4l2_ctrl_request_setup(struct media_request *req, -- struct v4l2_ctrl_handler *main_hdl) --{ -- struct media_request_object *obj; -- struct v4l2_ctrl_handler *hdl; -- struct v4l2_ctrl_ref *ref; -- int ret = 0; -- -- if (!req || !main_hdl) -- return 0; -- -- if (WARN_ON(req->state != MEDIA_REQUEST_STATE_QUEUED)) -- return -EBUSY; -- -- /* -- * Note that it is valid if nothing was found. It means -- * that this request doesn't have any controls and so just -- * wants to leave the controls unchanged. -- */ -- obj = media_request_object_find(req, &req_ops, main_hdl); -- if (!obj) -- return 0; -- if (obj->completed) { -- media_request_object_put(obj); -- return -EBUSY; -- } -- hdl = container_of(obj, struct v4l2_ctrl_handler, req_obj); -- -- list_for_each_entry(ref, &hdl->ctrl_refs, node) -- ref->req_done = false; -- -- list_for_each_entry(ref, &hdl->ctrl_refs, node) { -- struct v4l2_ctrl *ctrl = ref->ctrl; -- struct v4l2_ctrl *master = ctrl->cluster[0]; -- bool have_new_data = false; -- int i; -- -- /* -- * Skip if this control was already handled by a cluster. -- * Skip button controls and read-only controls. -- */ -- if (ref->req_done || (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY)) -- continue; -- -- v4l2_ctrl_lock(master); -- for (i = 0; i < master->ncontrols; i++) { -- if (master->cluster[i]) { -- struct v4l2_ctrl_ref *r = -- find_ref(hdl, master->cluster[i]->id); -- -- if (r->valid_p_req) { -- have_new_data = true; -- break; -- } -- } -- } -- if (!have_new_data) { -- v4l2_ctrl_unlock(master); -- continue; -- } -- -- for (i = 0; i < master->ncontrols; i++) { -- if (master->cluster[i]) { -- struct v4l2_ctrl_ref *r = -- find_ref(hdl, master->cluster[i]->id); -- -- req_to_new(r); -- master->cluster[i]->is_new = 1; -- r->req_done = true; -- } -- } -- /* -- * For volatile autoclusters that are currently in auto mode -- * we need to discover if it will be set to manual mode. -- * If so, then we have to copy the current volatile values -- * first since those will become the new manual values (which -- * may be overwritten by explicit new values from this set -- * of controls). -- */ -- if (master->is_auto && master->has_volatiles && -- !is_cur_manual(master)) { -- s32 new_auto_val = *master->p_new.p_s32; -- -- /* -- * If the new value == the manual value, then copy -- * the current volatile values. -- */ -- if (new_auto_val == master->manual_mode_value) -- update_from_auto_cluster(master); -- } -- -- ret = try_or_set_cluster(NULL, master, true, 0); -- v4l2_ctrl_unlock(master); -- -- if (ret) -- break; -- } -- -- media_request_object_put(obj); -- return ret; --} --EXPORT_SYMBOL(v4l2_ctrl_request_setup); -- --void v4l2_ctrl_notify(struct v4l2_ctrl *ctrl, v4l2_ctrl_notify_fnc notify, void *priv) --{ -- if (ctrl == NULL) -- return; -- if (notify == NULL) { -- ctrl->call_notify = 0; -- return; -- } -- if (WARN_ON(ctrl->handler->notify && ctrl->handler->notify != notify)) -- return; -- ctrl->handler->notify = notify; -- ctrl->handler->notify_priv = priv; -- ctrl->call_notify = 1; --} --EXPORT_SYMBOL(v4l2_ctrl_notify); -- --int __v4l2_ctrl_modify_range(struct v4l2_ctrl *ctrl, -- s64 min, s64 max, u64 step, s64 def) --{ -- bool value_changed; -- bool range_changed = false; -- int ret; -- -- lockdep_assert_held(ctrl->handler->lock); -- -- switch (ctrl->type) { -- case V4L2_CTRL_TYPE_INTEGER: -- case V4L2_CTRL_TYPE_INTEGER64: -- case V4L2_CTRL_TYPE_BOOLEAN: -- case V4L2_CTRL_TYPE_MENU: -- case V4L2_CTRL_TYPE_INTEGER_MENU: -- case V4L2_CTRL_TYPE_BITMASK: -- case V4L2_CTRL_TYPE_U8: -- case V4L2_CTRL_TYPE_U16: -- case V4L2_CTRL_TYPE_U32: -- if (ctrl->is_array) -- return -EINVAL; -- ret = check_range(ctrl->type, min, max, step, def); -- if (ret) -- return ret; -- break; -- default: -- return -EINVAL; -- } -- if ((ctrl->minimum != min) || (ctrl->maximum != max) || -- (ctrl->step != step) || ctrl->default_value != def) { -- range_changed = true; -- ctrl->minimum = min; -- ctrl->maximum = max; -- ctrl->step = step; -- ctrl->default_value = def; -- } -- cur_to_new(ctrl); -- if (validate_new(ctrl, ctrl->p_new)) { -- if (ctrl->type == V4L2_CTRL_TYPE_INTEGER64) -- *ctrl->p_new.p_s64 = def; -- else -- *ctrl->p_new.p_s32 = def; -- } -- -- if (ctrl->type == V4L2_CTRL_TYPE_INTEGER64) -- value_changed = *ctrl->p_new.p_s64 != *ctrl->p_cur.p_s64; -- else -- value_changed = *ctrl->p_new.p_s32 != *ctrl->p_cur.p_s32; -- if (value_changed) -- ret = set_ctrl(NULL, ctrl, V4L2_EVENT_CTRL_CH_RANGE); -- else if (range_changed) -- send_event(NULL, ctrl, V4L2_EVENT_CTRL_CH_RANGE); -- return ret; --} --EXPORT_SYMBOL(__v4l2_ctrl_modify_range); -- --static int v4l2_ctrl_add_event(struct v4l2_subscribed_event *sev, unsigned elems) --{ -- struct v4l2_ctrl *ctrl = v4l2_ctrl_find(sev->fh->ctrl_handler, sev->id); -- -- if (ctrl == NULL) -- return -EINVAL; -- -- v4l2_ctrl_lock(ctrl); -- list_add_tail(&sev->node, &ctrl->ev_subs); -- if (ctrl->type != V4L2_CTRL_TYPE_CTRL_CLASS && -- (sev->flags & V4L2_EVENT_SUB_FL_SEND_INITIAL)) { -- struct v4l2_event ev; -- u32 changes = V4L2_EVENT_CTRL_CH_FLAGS; -- -- if (!(ctrl->flags & V4L2_CTRL_FLAG_WRITE_ONLY)) -- changes |= V4L2_EVENT_CTRL_CH_VALUE; -- fill_event(&ev, ctrl, changes); -- /* Mark the queue as active, allowing this initial -- event to be accepted. */ -- sev->elems = elems; -- v4l2_event_queue_fh(sev->fh, &ev); -- } -- v4l2_ctrl_unlock(ctrl); -- return 0; --} -- --static void v4l2_ctrl_del_event(struct v4l2_subscribed_event *sev) --{ -- struct v4l2_ctrl *ctrl = v4l2_ctrl_find(sev->fh->ctrl_handler, sev->id); -- -- if (ctrl == NULL) -- return; -- -- v4l2_ctrl_lock(ctrl); -- list_del(&sev->node); -- v4l2_ctrl_unlock(ctrl); --} -- --void v4l2_ctrl_replace(struct v4l2_event *old, const struct v4l2_event *new) --{ -- u32 old_changes = old->u.ctrl.changes; -- -- old->u.ctrl = new->u.ctrl; -- old->u.ctrl.changes |= old_changes; --} --EXPORT_SYMBOL(v4l2_ctrl_replace); -- --void v4l2_ctrl_merge(const struct v4l2_event *old, struct v4l2_event *new) --{ -- new->u.ctrl.changes |= old->u.ctrl.changes; --} --EXPORT_SYMBOL(v4l2_ctrl_merge); -- --const struct v4l2_subscribed_event_ops v4l2_ctrl_sub_ev_ops = { -- .add = v4l2_ctrl_add_event, -- .del = v4l2_ctrl_del_event, -- .replace = v4l2_ctrl_replace, -- .merge = v4l2_ctrl_merge, --}; --EXPORT_SYMBOL(v4l2_ctrl_sub_ev_ops); -- --int v4l2_ctrl_log_status(struct file *file, void *fh) --{ -- struct video_device *vfd = video_devdata(file); -- struct v4l2_fh *vfh = file->private_data; -- -- if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) && vfd->v4l2_dev) -- v4l2_ctrl_handler_log_status(vfh->ctrl_handler, -- vfd->v4l2_dev->name); -- return 0; --} --EXPORT_SYMBOL(v4l2_ctrl_log_status); -- --int v4l2_ctrl_subscribe_event(struct v4l2_fh *fh, -- const struct v4l2_event_subscription *sub) --{ -- if (sub->type == V4L2_EVENT_CTRL) -- return v4l2_event_subscribe(fh, sub, 0, &v4l2_ctrl_sub_ev_ops); -- return -EINVAL; --} --EXPORT_SYMBOL(v4l2_ctrl_subscribe_event); -- --int v4l2_ctrl_subdev_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh, -- struct v4l2_event_subscription *sub) --{ -- if (!sd->ctrl_handler) -- return -EINVAL; -- return v4l2_ctrl_subscribe_event(fh, sub); --} --EXPORT_SYMBOL(v4l2_ctrl_subdev_subscribe_event); -- --__poll_t v4l2_ctrl_poll(struct file *file, struct poll_table_struct *wait) --{ -- struct v4l2_fh *fh = file->private_data; -- -- poll_wait(file, &fh->wait, wait); -- if (v4l2_event_pending(fh)) -- return EPOLLPRI; -- return 0; --} --EXPORT_SYMBOL(v4l2_ctrl_poll); -- --int v4l2_ctrl_new_fwnode_properties(struct v4l2_ctrl_handler *hdl, -- const struct v4l2_ctrl_ops *ctrl_ops, -- const struct v4l2_fwnode_device_properties *p) --{ -- if (p->orientation != V4L2_FWNODE_PROPERTY_UNSET) { -- u32 orientation_ctrl; -- -- switch (p->orientation) { -- case V4L2_FWNODE_ORIENTATION_FRONT: -- orientation_ctrl = V4L2_CAMERA_ORIENTATION_FRONT; -- break; -- case V4L2_FWNODE_ORIENTATION_BACK: -- orientation_ctrl = V4L2_CAMERA_ORIENTATION_BACK; -- break; -- case V4L2_FWNODE_ORIENTATION_EXTERNAL: -- orientation_ctrl = V4L2_CAMERA_ORIENTATION_EXTERNAL; -- break; -- default: -- return -EINVAL; -- } -- if (!v4l2_ctrl_new_std_menu(hdl, ctrl_ops, -- V4L2_CID_CAMERA_ORIENTATION, -- V4L2_CAMERA_ORIENTATION_EXTERNAL, 0, -- orientation_ctrl)) -- return hdl->error; -- } -- -- if (p->rotation != V4L2_FWNODE_PROPERTY_UNSET) { -- if (!v4l2_ctrl_new_std(hdl, ctrl_ops, -- V4L2_CID_CAMERA_SENSOR_ROTATION, -- p->rotation, p->rotation, 1, -- p->rotation)) -- return hdl->error; -- } -- -- return hdl->error; --} --EXPORT_SYMBOL(v4l2_ctrl_new_fwnode_properties); diff --git a/target/linux/bcm27xx/patches-5.15/950-0461-media-v4l2-Add-HEVC_SCALING_MATRIX-attribute-to-v4l2.patch b/target/linux/bcm27xx/patches-5.15/950-0461-media-v4l2-Add-HEVC_SCALING_MATRIX-attribute-to-v4l2.patch deleted file mode 100644 index 0a18b9dff..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0461-media-v4l2-Add-HEVC_SCALING_MATRIX-attribute-to-v4l2.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 7e8e61a7103c53c54cbd1b81c4fb6289141be7c5 Mon Sep 17 00:00:00 2001 -From: John Cox -Date: Fri, 6 Aug 2021 10:53:50 +0100 -Subject: [PATCH] media: v4l2: Add HEVC_SCALING_MATRIX attribute to - v4l2-ctrl-* - -Add code to support V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX to -v4l2-ctrl-*. This change was in the unsplit v4l2-ctrl.c but failed -to make it through the split. - -Signed-off-by: John Cox ---- - drivers/media/v4l2-core/v4l2-ctrls-core.c | 6 ++++++ - drivers/media/v4l2-core/v4l2-ctrls-defs.c | 4 ++++ - 2 files changed, 10 insertions(+) - ---- a/drivers/media/v4l2-core/v4l2-ctrls-core.c -+++ b/drivers/media/v4l2-core/v4l2-ctrls-core.c -@@ -627,6 +627,9 @@ static int std_validate_compound(const s - zero_padding(*p_hevc_pps); - break; - -+ case V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX: -+ break; -+ - case V4L2_CTRL_TYPE_HEVC_DECODE_PARAMS: - p_hevc_decode_params = p; - -@@ -1250,6 +1253,9 @@ static struct v4l2_ctrl *v4l2_ctrl_new(s - case V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS: - elem_size = sizeof(struct v4l2_ctrl_hevc_slice_params); - break; -+ case V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX: -+ elem_size = sizeof(struct v4l2_ctrl_hevc_scaling_matrix); -+ break; - case V4L2_CTRL_TYPE_HEVC_DECODE_PARAMS: - elem_size = sizeof(struct v4l2_ctrl_hevc_decode_params); - break; ---- a/drivers/media/v4l2-core/v4l2-ctrls-defs.c -+++ b/drivers/media/v4l2-core/v4l2-ctrls-defs.c -@@ -997,6 +997,7 @@ const char *v4l2_ctrl_get_name(u32 id) - case V4L2_CID_MPEG_VIDEO_HEVC_SPS: return "HEVC Sequence Parameter Set"; - case V4L2_CID_MPEG_VIDEO_HEVC_PPS: return "HEVC Picture Parameter Set"; - case V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS: return "HEVC Slice Parameters"; -+ case V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX: return "HEVC Scaling Matrix"; - case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS: return "HEVC Decode Parameters"; - case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE: return "HEVC Decode Mode"; - case V4L2_CID_MPEG_VIDEO_HEVC_START_CODE: return "HEVC Start Code"; -@@ -1490,6 +1491,9 @@ void v4l2_ctrl_fill(u32 id, const char * - case V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS: - *type = V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS; - break; -+ case V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX: -+ *type = V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX; -+ break; - case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS: - *type = V4L2_CTRL_TYPE_HEVC_DECODE_PARAMS; - break; diff --git a/target/linux/bcm27xx/patches-5.15/950-0462-media-rpivid-Update-to-compile-with-new-hevc-decode-.patch b/target/linux/bcm27xx/patches-5.15/950-0462-media-rpivid-Update-to-compile-with-new-hevc-decode-.patch deleted file mode 100644 index 142e504bf..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0462-media-rpivid-Update-to-compile-with-new-hevc-decode-.patch +++ /dev/null @@ -1,197 +0,0 @@ -From 2a88d608907e78bc6506579de01fabaa18219483 Mon Sep 17 00:00:00 2001 -From: John Cox -Date: Thu, 5 Aug 2021 15:18:50 +0100 -Subject: [PATCH] media: rpivid: Update to compile with new hevc decode - params - -DPB entries have moved from slice params to the new decode params -attribute - update to deal with this. Also fixes fallthrough -warnings which seem to be new in 5.14. - -Signed-off-by: John Cox ---- - drivers/staging/media/rpivid/rpivid.c | 6 ++++ - drivers/staging/media/rpivid/rpivid.h | 1 + - drivers/staging/media/rpivid/rpivid_dec.c | 3 ++ - drivers/staging/media/rpivid/rpivid_h265.c | 35 ++++++++++++---------- - 4 files changed, 30 insertions(+), 15 deletions(-) - ---- a/drivers/staging/media/rpivid/rpivid.c -+++ b/drivers/staging/media/rpivid/rpivid.c -@@ -57,6 +57,12 @@ static const struct rpivid_control rpivi - }, - { - .cfg = { -+ .id = V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS, -+ }, -+ .required = true, -+ }, -+ { -+ .cfg = { - .id = V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS, - }, - .required = true, ---- a/drivers/staging/media/rpivid/rpivid.h -+++ b/drivers/staging/media/rpivid/rpivid.h -@@ -52,6 +52,7 @@ struct rpivid_h265_run { - u32 slice_ents; - const struct v4l2_ctrl_hevc_sps *sps; - const struct v4l2_ctrl_hevc_pps *pps; -+ const struct v4l2_ctrl_hevc_decode_params *dec; - const struct v4l2_ctrl_hevc_slice_params *slice_params; - const struct v4l2_ctrl_hevc_scaling_matrix *scaling_matrix; - }; ---- a/drivers/staging/media/rpivid/rpivid_dec.c -+++ b/drivers/staging/media/rpivid/rpivid_dec.c -@@ -55,6 +55,9 @@ void rpivid_device_run(void *priv) - run.h265.slice_params = - rpivid_find_control_data(ctx, - V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS); -+ run.h265.dec = -+ rpivid_find_control_data(ctx, -+ V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS); - run.h265.scaling_matrix = - rpivid_find_control_data(ctx, - V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX); ---- a/drivers/staging/media/rpivid/rpivid_h265.c -+++ b/drivers/staging/media/rpivid/rpivid_h265.c -@@ -252,6 +252,7 @@ struct rpivid_dec_state { - u8 *src_buf; - dma_addr_t src_addr; - const struct v4l2_ctrl_hevc_slice_params *sh; -+ const struct v4l2_ctrl_hevc_decode_params *dec; - unsigned int nb_refs[2]; - unsigned int slice_qp; - unsigned int max_num_merge_cand; // 0 if I-slice -@@ -799,6 +800,7 @@ static void pre_slice_decode(struct rpiv - const struct rpivid_dec_state *const s) - { - const struct v4l2_ctrl_hevc_slice_params *const sh = s->sh; -+ const struct v4l2_ctrl_hevc_decode_params *const dec = s->dec; - int weighted_pred_flag, idx; - u16 cmd_slice; - unsigned int collocated_from_l0_flag; -@@ -825,9 +827,9 @@ static void pre_slice_decode(struct rpiv - if (sh->slice_type == HEVC_SLICE_P || sh->slice_type == HEVC_SLICE_B) { - // Flag to say all reference pictures are from the past - const int no_backward_pred_flag = -- has_backward(sh->dpb, sh->ref_idx_l0, s->nb_refs[L0], -+ has_backward(dec->dpb, sh->ref_idx_l0, s->nb_refs[L0], - sh->slice_pic_order_cnt) && -- has_backward(sh->dpb, sh->ref_idx_l1, s->nb_refs[L1], -+ has_backward(dec->dpb, sh->ref_idx_l1, s->nb_refs[L1], - sh->slice_pic_order_cnt); - cmd_slice |= no_backward_pred_flag << 10; - msg_slice(de, cmd_slice); -@@ -855,11 +857,11 @@ static void pre_slice_decode(struct rpiv - - msg_slice(de, - dpb_no | -- (sh->dpb[dpb_no].rps == -+ (dec->dpb[dpb_no].rps == - V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR ? - (1 << 4) : 0) | - (weighted_pred_flag ? (3 << 5) : 0)); -- msg_slice(de, sh->dpb[dpb_no].pic_order_cnt[0]); -+ msg_slice(de, dec->dpb[dpb_no].pic_order_cnt[0]); - - if (weighted_pred_flag) { - const struct v4l2_hevc_pred_weight_table -@@ -901,11 +903,11 @@ static void pre_slice_decode(struct rpiv - // "L1[%d]=dpb[%d]\n", idx, dpb_no); - msg_slice(de, - dpb_no | -- (sh->dpb[dpb_no].rps == -+ (dec->dpb[dpb_no].rps == - V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR ? - (1 << 4) : 0) | - (weighted_pred_flag ? (3 << 5) : 0)); -- msg_slice(de, sh->dpb[dpb_no].pic_order_cnt[0]); -+ msg_slice(de, dec->dpb[dpb_no].pic_order_cnt[0]); - if (weighted_pred_flag) { - const struct v4l2_hevc_pred_weight_table - *const w = &sh->pred_weight_table; -@@ -1670,6 +1672,8 @@ static void rpivid_h265_setup(struct rpi - struct rpivid_dev *const dev = ctx->dev; - const struct v4l2_ctrl_hevc_slice_params *const sh = - run->h265.slice_params; -+ const struct v4l2_ctrl_hevc_decode_params *const dec = -+ run->h265.dec; - // const struct v4l2_hevc_pred_weight_table *pred_weight_table; - struct rpivid_q_aux *dpb_q_aux[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; - struct rpivid_dec_state *const s = ctx->state; -@@ -1895,6 +1899,7 @@ static void rpivid_h265_setup(struct rpi - - // Pre calc a few things - s->sh = sh; -+ s->dec = dec; - s->slice_qp = 26 + s->pps.init_qp_minus26 + s->sh->slice_qp_delta; - s->max_num_merge_cand = sh->slice_type == HEVC_SLICE_I ? - 0 : -@@ -1965,9 +1970,9 @@ static void rpivid_h265_setup(struct rpi - if (write_cmd_buffer(dev, de, s)) - goto fail; - -- for (i = 0; i < sh->num_active_dpb_entries; ++i) { -+ for (i = 0; i < dec->num_active_dpb_entries; ++i) { - int buffer_index = -- vb2_find_timestamp(vq, sh->dpb[i].timestamp, 0); -+ vb2_find_timestamp(vq, dec->dpb[i].timestamp, 0); - struct vb2_buffer *buf = buffer_index < 0 ? - NULL : - vb2_get_buffer(vq, buffer_index); -@@ -1975,7 +1980,7 @@ static void rpivid_h265_setup(struct rpi - if (!buf) { - v4l2_warn(&dev->v4l2_dev, - "Missing DPB ent %d, timestamp=%lld, index=%d\n", -- i, (long long)sh->dpb[i].timestamp, -+ i, (long long)dec->dpb[i].timestamp, - buffer_index); - continue; - } -@@ -1985,7 +1990,7 @@ static void rpivid_h265_setup(struct rpi - if (!dpb_q_aux[i]) - v4l2_warn(&dev->v4l2_dev, - "Missing DPB AUX ent %d, timestamp=%lld, index=%d\n", -- i, (long long)sh->dpb[i].timestamp, -+ i, (long long)dec->dpb[i].timestamp, - buffer_index); - } - -@@ -2017,11 +2022,11 @@ static void rpivid_h265_setup(struct rpi - } - - if (de->dpbno_col != ~0U) { -- if (de->dpbno_col >= sh->num_active_dpb_entries) { -+ if (de->dpbno_col >= dec->num_active_dpb_entries) { - v4l2_err(&dev->v4l2_dev, - "Col ref index %d >= %d\n", - de->dpbno_col, -- sh->num_active_dpb_entries); -+ dec->num_active_dpb_entries); - } else { - // Standard requires that the col pic is - // constant for the duration of the pic -@@ -2462,7 +2467,7 @@ static void rpivid_h265_trigger(struct r - switch (!de ? RPIVID_DECODE_ERROR_CONTINUE : de->state) { - case RPIVID_DECODE_SLICE_START: - de->state = RPIVID_DECODE_SLICE_CONTINUE; -- /* FALLTHRU */ -+ fallthrough; - case RPIVID_DECODE_SLICE_CONTINUE: - v4l2_m2m_buf_done_and_job_finish(dev->m2m_dev, ctx->fh.m2m_ctx, - VB2_BUF_STATE_DONE); -@@ -2472,11 +2477,11 @@ static void rpivid_h265_trigger(struct r - default: - v4l2_err(&dev->v4l2_dev, "%s: Unexpected state: %d\n", __func__, - de->state); -- /* FALLTHRU */ -+ fallthrough; - case RPIVID_DECODE_ERROR_DONE: - ctx->dec0 = NULL; - dec_env_delete(de); -- /* FALLTHRU */ -+ fallthrough; - case RPIVID_DECODE_ERROR_CONTINUE: - xtrace_fin(dev, de); - v4l2_m2m_buf_done_and_job_finish(dev->m2m_dev, ctx->fh.m2m_ctx, diff --git a/target/linux/bcm27xx/patches-5.15/950-0464-videodev2.h-add-V4L2_CTRL_FLAG_DYNAMIC_ARRAY.patch b/target/linux/bcm27xx/patches-5.15/950-0464-videodev2.h-add-V4L2_CTRL_FLAG_DYNAMIC_ARRAY.patch deleted file mode 100644 index 67137dd69..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0464-videodev2.h-add-V4L2_CTRL_FLAG_DYNAMIC_ARRAY.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 1ef126fb69d37c6958a0b945365e532b500d43bd Mon Sep 17 00:00:00 2001 -From: Hans Verkuil -Date: Wed, 14 Apr 2021 15:01:16 +0200 -Subject: [PATCH] videodev2.h: add V4L2_CTRL_FLAG_DYNAMIC_ARRAY - -Add a new flag that indicates that this control is a dynamically sized -array. Also document this flag. - -Currently dynamically sized arrays are limited to one dimensional arrays, -but that might change in the future if there is a need for it. - -The initial use-case of dynamic arrays are stateless codecs. A frame -can be divided in many slices, so you want to provide an array containing -slice information for each slice. Typically the number of slices is small, -but the standard allow for hundreds or thousands of slices. Dynamic arrays -are a good solution since sizing the array for the worst case would waste -substantial amounts of memory. - -Signed-off-by: Hans Verkuil -(cherry picked from commit c095ad310b223b9de38d491c9f66533d05586b45) ---- - .../userspace-api/media/v4l/vidioc-queryctrl.rst | 8 ++++++++ - include/uapi/linux/videodev2.h | 1 + - 2 files changed, 9 insertions(+) - ---- a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst -+++ b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst -@@ -607,6 +607,14 @@ See also the examples in :ref:`control`. - ``V4L2_CTRL_FLAG_GRABBED`` flag when buffers are allocated or - streaming is in progress since most drivers do not support changing - the format in that case. -+ * - ``V4L2_CTRL_FLAG_DYNAMIC_ARRAY`` -+ - 0x0800 -+ - This control is a dynamically sized 1-dimensional array. It -+ behaves the same as a regular array, except that the number -+ of elements as reported by the ``elems`` field is between 1 and -+ ``dims[0]``. So setting the control with a differently sized -+ array will change the ``elems`` field when the control is -+ queried afterwards. - - Return Value - ============ ---- a/include/uapi/linux/videodev2.h -+++ b/include/uapi/linux/videodev2.h -@@ -1883,6 +1883,7 @@ struct v4l2_querymenu { - #define V4L2_CTRL_FLAG_HAS_PAYLOAD 0x0100 - #define V4L2_CTRL_FLAG_EXECUTE_ON_WRITE 0x0200 - #define V4L2_CTRL_FLAG_MODIFY_LAYOUT 0x0400 -+#define V4L2_CTRL_FLAG_DYNAMIC_ARRAY 0x0800 - - /* Query flags, to be ORed with the control ID */ - #define V4L2_CTRL_FLAG_NEXT_CTRL 0x80000000 diff --git a/target/linux/bcm27xx/patches-5.15/950-0465-v4l2-ctrls-add-support-for-dynamically-allocated-arr.patch b/target/linux/bcm27xx/patches-5.15/950-0465-v4l2-ctrls-add-support-for-dynamically-allocated-arr.patch deleted file mode 100644 index 03074222f..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0465-v4l2-ctrls-add-support-for-dynamically-allocated-arr.patch +++ /dev/null @@ -1,688 +0,0 @@ -From 613b860fe9c37b96d9706b02fe77933f086f9896 Mon Sep 17 00:00:00 2001 -From: Hans Verkuil -Date: Thu, 15 Apr 2021 13:56:53 +0200 -Subject: [PATCH] v4l2-ctrls: add support for dynamically allocated - arrays. - -Implement support for dynamically allocated arrays. - -Most of the changes concern keeping track of the number of elements -of the array and the number of elements allocated for the array and -reallocating memory if needed. - -Signed-off-by: Hans Verkuil -(cherry picked from commit fd5d45e6561f6f8c406b81aeddecaa11f0bd15af) ---- - drivers/media/v4l2-core/v4l2-ctrls-api.c | 103 ++++++++--- - drivers/media/v4l2-core/v4l2-ctrls-core.c | 182 +++++++++++++++---- - drivers/media/v4l2-core/v4l2-ctrls-priv.h | 3 +- - drivers/media/v4l2-core/v4l2-ctrls-request.c | 13 +- - include/media/v4l2-ctrls.h | 42 ++++- - 5 files changed, 272 insertions(+), 71 deletions(-) - ---- a/drivers/media/v4l2-core/v4l2-ctrls-api.c -+++ b/drivers/media/v4l2-core/v4l2-ctrls-api.c -@@ -97,29 +97,47 @@ static int def_to_user(struct v4l2_ext_c - return ptr_to_user(c, ctrl, ctrl->p_new); - } - --/* Helper function: copy the caller-provider value to the given control value */ --static int user_to_ptr(struct v4l2_ext_control *c, -- struct v4l2_ctrl *ctrl, -- union v4l2_ctrl_ptr ptr) -+/* Helper function: copy the caller-provider value as the new control value */ -+static int user_to_new(struct v4l2_ext_control *c, struct v4l2_ctrl *ctrl) - { - int ret; - u32 size; - -- ctrl->is_new = 1; -+ ctrl->is_new = 0; -+ if (ctrl->is_dyn_array && -+ c->size > ctrl->p_dyn_alloc_elems * ctrl->elem_size) { -+ void *old = ctrl->p_dyn; -+ void *tmp = kvzalloc(2 * c->size, GFP_KERNEL); -+ -+ if (!tmp) -+ return -ENOMEM; -+ memcpy(tmp, ctrl->p_new.p, ctrl->elems * ctrl->elem_size); -+ memcpy(tmp + c->size, ctrl->p_cur.p, ctrl->elems * ctrl->elem_size); -+ ctrl->p_new.p = tmp; -+ ctrl->p_cur.p = tmp + c->size; -+ ctrl->p_dyn = tmp; -+ ctrl->p_dyn_alloc_elems = c->size / ctrl->elem_size; -+ kvfree(old); -+ } -+ - if (ctrl->is_ptr && !ctrl->is_string) { -+ unsigned int elems = c->size / ctrl->elem_size; - unsigned int idx; - -- ret = copy_from_user(ptr.p, c->ptr, c->size) ? -EFAULT : 0; -- if (ret || !ctrl->is_array) -- return ret; -- for (idx = c->size / ctrl->elem_size; idx < ctrl->elems; idx++) -- ctrl->type_ops->init(ctrl, idx, ptr); -+ if (copy_from_user(ctrl->p_new.p, c->ptr, c->size)) -+ return -EFAULT; -+ ctrl->is_new = 1; -+ if (ctrl->is_dyn_array) -+ ctrl->new_elems = elems; -+ else if (ctrl->is_array) -+ for (idx = elems; idx < ctrl->elems; idx++) -+ ctrl->type_ops->init(ctrl, idx, ctrl->p_new); - return 0; - } - - switch (ctrl->type) { - case V4L2_CTRL_TYPE_INTEGER64: -- *ptr.p_s64 = c->value64; -+ *ctrl->p_new.p_s64 = c->value64; - break; - case V4L2_CTRL_TYPE_STRING: - size = c->size; -@@ -127,32 +145,27 @@ static int user_to_ptr(struct v4l2_ext_c - return -ERANGE; - if (size > ctrl->maximum + 1) - size = ctrl->maximum + 1; -- ret = copy_from_user(ptr.p_char, c->string, size) ? -EFAULT : 0; -+ ret = copy_from_user(ctrl->p_new.p_char, c->string, size) ? -EFAULT : 0; - if (!ret) { -- char last = ptr.p_char[size - 1]; -+ char last = ctrl->p_new.p_char[size - 1]; - -- ptr.p_char[size - 1] = 0; -+ ctrl->p_new.p_char[size - 1] = 0; - /* - * If the string was longer than ctrl->maximum, - * then return an error. - */ -- if (strlen(ptr.p_char) == ctrl->maximum && last) -+ if (strlen(ctrl->p_new.p_char) == ctrl->maximum && last) - return -ERANGE; - } - return ret; - default: -- *ptr.p_s32 = c->value; -+ *ctrl->p_new.p_s32 = c->value; - break; - } -+ ctrl->is_new = 1; - return 0; - } - --/* Helper function: copy the caller-provider value as the new control value */ --static int user_to_new(struct v4l2_ext_control *c, struct v4l2_ctrl *ctrl) --{ -- return user_to_ptr(c, ctrl, ctrl->p_new); --} -- - /* - * VIDIOC_G/TRY/S_EXT_CTRLS implementation - */ -@@ -254,7 +267,31 @@ static int prepare_ext_ctrls(struct v4l2 - have_clusters = true; - if (ctrl->cluster[0] != ctrl) - ref = find_ref_lock(hdl, ctrl->cluster[0]->id); -- if (ctrl->is_ptr && !ctrl->is_string) { -+ if (ctrl->is_dyn_array) { -+ unsigned int max_size = ctrl->dims[0] * ctrl->elem_size; -+ unsigned int tot_size = ctrl->elem_size; -+ -+ if (cs->which == V4L2_CTRL_WHICH_REQUEST_VAL) -+ tot_size *= ref->p_req_elems; -+ else -+ tot_size *= ctrl->elems; -+ -+ c->size = ctrl->elem_size * (c->size / ctrl->elem_size); -+ if (get) { -+ if (c->size < tot_size) { -+ c->size = tot_size; -+ return -ENOSPC; -+ } -+ c->size = tot_size; -+ } else { -+ if (c->size > max_size) { -+ c->size = max_size; -+ return -ENOSPC; -+ } -+ if (!c->size) -+ return -EFAULT; -+ } -+ } else if (ctrl->is_ptr && !ctrl->is_string) { - unsigned int tot_size = ctrl->elems * ctrl->elem_size; - - if (c->size < tot_size) { -@@ -346,7 +383,7 @@ static int class_check(struct v4l2_ctrl_ - * - * Note that v4l2_g_ext_ctrls_common() with 'which' set to - * V4L2_CTRL_WHICH_REQUEST_VAL is only called if the request was -- * completed, and in that case valid_p_req is true for all controls. -+ * completed, and in that case p_req_valid is true for all controls. - */ - int v4l2_g_ext_ctrls_common(struct v4l2_ctrl_handler *hdl, - struct v4l2_ext_controls *cs, -@@ -430,7 +467,9 @@ int v4l2_g_ext_ctrls_common(struct v4l2_ - - if (is_default) - ret = def_to_user(cs->controls + idx, ref->ctrl); -- else if (is_request && ref->valid_p_req) -+ else if (is_request && ref->p_req_dyn_enomem) -+ ret = -ENOMEM; -+ else if (is_request && ref->p_req_valid) - ret = req_to_user(cs->controls + idx, ref); - else if (is_volatile) - ret = new_to_user(cs->controls + idx, ref->ctrl); -@@ -457,6 +496,17 @@ int v4l2_g_ext_ctrls(struct v4l2_ctrl_ha - } - EXPORT_SYMBOL(v4l2_g_ext_ctrls); - -+/* Validate a new control */ -+static int validate_new(const struct v4l2_ctrl *ctrl, union v4l2_ctrl_ptr p_new) -+{ -+ unsigned int idx; -+ int err = 0; -+ -+ for (idx = 0; !err && idx < ctrl->new_elems; idx++) -+ err = ctrl->type_ops->validate(ctrl, idx, p_new); -+ return err; -+} -+ - /* Validate controls. */ - static int validate_ctrls(struct v4l2_ext_controls *cs, - struct v4l2_ctrl_helper *helpers, -@@ -872,6 +922,9 @@ int __v4l2_ctrl_s_ctrl_compound(struct v - /* It's a driver bug if this happens. */ - if (WARN_ON(ctrl->type != type)) - return -EINVAL; -+ /* Setting dynamic arrays is not (yet?) supported. */ -+ if (WARN_ON(ctrl->is_dyn_array)) -+ return -EINVAL; - memcpy(ctrl->p_new.p, p, ctrl->elems * ctrl->elem_size); - return set_ctrl(NULL, ctrl, 0); - } ---- a/drivers/media/v4l2-core/v4l2-ctrls-core.c -+++ b/drivers/media/v4l2-core/v4l2-ctrls-core.c -@@ -809,11 +809,12 @@ EXPORT_SYMBOL(v4l2_ctrl_notify); - - /* Copy the one value to another. */ - static void ptr_to_ptr(struct v4l2_ctrl *ctrl, -- union v4l2_ctrl_ptr from, union v4l2_ctrl_ptr to) -+ union v4l2_ctrl_ptr from, union v4l2_ctrl_ptr to, -+ unsigned int elems) - { - if (ctrl == NULL) - return; -- memcpy(to.p, from.p_const, ctrl->elems * ctrl->elem_size); -+ memcpy(to.p, from.p_const, elems * ctrl->elem_size); - } - - /* Copy the new value to the current value. */ -@@ -826,8 +827,11 @@ void new_to_cur(struct v4l2_fh *fh, stru - - /* has_changed is set by cluster_changed */ - changed = ctrl->has_changed; -- if (changed) -- ptr_to_ptr(ctrl, ctrl->p_new, ctrl->p_cur); -+ if (changed) { -+ if (ctrl->is_dyn_array) -+ ctrl->elems = ctrl->new_elems; -+ ptr_to_ptr(ctrl, ctrl->p_new, ctrl->p_cur, ctrl->elems); -+ } - - if (ch_flags & V4L2_EVENT_CTRL_CH_FLAGS) { - /* Note: CH_FLAGS is only set for auto clusters. */ -@@ -857,36 +861,122 @@ void cur_to_new(struct v4l2_ctrl *ctrl) - { - if (ctrl == NULL) - return; -- ptr_to_ptr(ctrl, ctrl->p_cur, ctrl->p_new); -+ if (ctrl->is_dyn_array) -+ ctrl->new_elems = ctrl->elems; -+ ptr_to_ptr(ctrl, ctrl->p_cur, ctrl->p_new, ctrl->new_elems); -+} -+ -+static bool req_alloc_dyn_array(struct v4l2_ctrl_ref *ref, u32 elems) -+{ -+ void *tmp; -+ -+ if (elems < ref->p_req_dyn_alloc_elems) -+ return true; -+ -+ tmp = kvmalloc(elems * ref->ctrl->elem_size, GFP_KERNEL); -+ -+ if (!tmp) { -+ ref->p_req_dyn_enomem = true; -+ return false; -+ } -+ ref->p_req_dyn_enomem = false; -+ kvfree(ref->p_req.p); -+ ref->p_req.p = tmp; -+ ref->p_req_dyn_alloc_elems = elems; -+ return true; - } - - /* Copy the new value to the request value */ - void new_to_req(struct v4l2_ctrl_ref *ref) - { -+ struct v4l2_ctrl *ctrl; -+ - if (!ref) - return; -- ptr_to_ptr(ref->ctrl, ref->ctrl->p_new, ref->p_req); -- ref->valid_p_req = true; -+ -+ ctrl = ref->ctrl; -+ if (ctrl->is_dyn_array && !req_alloc_dyn_array(ref, ctrl->new_elems)) -+ return; -+ -+ ref->p_req_elems = ctrl->new_elems; -+ ptr_to_ptr(ctrl, ctrl->p_new, ref->p_req, ref->p_req_elems); -+ ref->p_req_valid = true; - } - - /* Copy the current value to the request value */ - void cur_to_req(struct v4l2_ctrl_ref *ref) - { -+ struct v4l2_ctrl *ctrl; -+ - if (!ref) - return; -- ptr_to_ptr(ref->ctrl, ref->ctrl->p_cur, ref->p_req); -- ref->valid_p_req = true; -+ -+ ctrl = ref->ctrl; -+ if (ctrl->is_dyn_array && !req_alloc_dyn_array(ref, ctrl->elems)) -+ return; -+ -+ ref->p_req_elems = ctrl->elems; -+ ptr_to_ptr(ctrl, ctrl->p_cur, ref->p_req, ctrl->elems); -+ ref->p_req_valid = true; - } - - /* Copy the request value to the new value */ --void req_to_new(struct v4l2_ctrl_ref *ref) -+int req_to_new(struct v4l2_ctrl_ref *ref) - { -+ struct v4l2_ctrl *ctrl; -+ - if (!ref) -- return; -- if (ref->valid_p_req) -- ptr_to_ptr(ref->ctrl, ref->p_req, ref->ctrl->p_new); -- else -- ptr_to_ptr(ref->ctrl, ref->ctrl->p_cur, ref->ctrl->p_new); -+ return 0; -+ -+ ctrl = ref->ctrl; -+ -+ /* -+ * This control was never set in the request, so just use the current -+ * value. -+ */ -+ if (!ref->p_req_valid) { -+ if (ctrl->is_dyn_array) -+ ctrl->new_elems = ctrl->elems; -+ ptr_to_ptr(ctrl, ctrl->p_cur, ctrl->p_new, ctrl->new_elems); -+ return 0; -+ } -+ -+ /* Not a dynamic array, so just copy the request value */ -+ if (!ctrl->is_dyn_array) { -+ ptr_to_ptr(ctrl, ref->p_req, ctrl->p_new, ctrl->new_elems); -+ return 0; -+ } -+ -+ /* Sanity check, should never happen */ -+ if (WARN_ON(!ref->p_req_dyn_alloc_elems)) -+ return -ENOMEM; -+ -+ /* -+ * Check if the number of elements in the request is more than the -+ * elements in ctrl->p_dyn. If so, attempt to realloc ctrl->p_dyn. -+ * Note that p_dyn is allocated with twice the number of elements -+ * in the dynamic array since it has to store both the current and -+ * new value of such a control. -+ */ -+ if (ref->p_req_elems > ctrl->p_dyn_alloc_elems) { -+ unsigned int sz = ref->p_req_elems * ctrl->elem_size; -+ void *old = ctrl->p_dyn; -+ void *tmp = kvzalloc(2 * sz, GFP_KERNEL); -+ -+ if (!tmp) -+ return -ENOMEM; -+ memcpy(tmp, ctrl->p_new.p, ctrl->elems * ctrl->elem_size); -+ memcpy(tmp + sz, ctrl->p_cur.p, ctrl->elems * ctrl->elem_size); -+ ctrl->p_new.p = tmp; -+ ctrl->p_cur.p = tmp + sz; -+ ctrl->p_dyn = tmp; -+ ctrl->p_dyn_alloc_elems = ref->p_req_elems; -+ kvfree(old); -+ } -+ -+ ctrl->new_elems = ref->p_req_elems; -+ ptr_to_ptr(ctrl, ref->p_req, ctrl->p_new, ctrl->new_elems); -+ return 0; - } - - /* Control range checking */ -@@ -928,17 +1018,6 @@ int check_range(enum v4l2_ctrl_type type - } - } - --/* Validate a new control */ --int validate_new(const struct v4l2_ctrl *ctrl, union v4l2_ctrl_ptr p_new) --{ -- unsigned idx; -- int err = 0; -- -- for (idx = 0; !err && idx < ctrl->elems; idx++) -- err = ctrl->type_ops->validate(ctrl, idx, p_new); -- return err; --} -- - /* Set the handler's error code if it wasn't set earlier already */ - static inline int handler_set_err(struct v4l2_ctrl_handler *hdl, int err) - { -@@ -983,6 +1062,8 @@ void v4l2_ctrl_handler_free(struct v4l2_ - /* Free all nodes */ - list_for_each_entry_safe(ref, next_ref, &hdl->ctrl_refs, node) { - list_del(&ref->node); -+ if (ref->p_req_dyn_alloc_elems) -+ kvfree(ref->p_req.p); - kfree(ref); - } - /* Free all controls owned by the handler */ -@@ -990,6 +1071,7 @@ void v4l2_ctrl_handler_free(struct v4l2_ - list_del(&ctrl->node); - list_for_each_entry_safe(sev, next_sev, &ctrl->ev_subs, node) - list_del(&sev->node); -+ kvfree(ctrl->p_dyn); - kvfree(ctrl); - } - kvfree(hdl->buckets); -@@ -1105,7 +1187,7 @@ int handler_new_ref(struct v4l2_ctrl_han - if (hdl->error) - return hdl->error; - -- if (allocate_req) -+ if (allocate_req && !ctrl->is_dyn_array) - size_extra_req = ctrl->elems * ctrl->elem_size; - new_ref = kzalloc(sizeof(*new_ref) + size_extra_req, GFP_KERNEL); - if (!new_ref) -@@ -1273,7 +1355,6 @@ static struct v4l2_ctrl *v4l2_ctrl_new(s - elem_size = sizeof(s32); - break; - } -- tot_ctrl_size = elem_size * elems; - - /* Sanity checks */ - if (id == 0 || name == NULL || !elem_size || -@@ -1294,17 +1375,33 @@ static struct v4l2_ctrl *v4l2_ctrl_new(s - handler_set_err(hdl, -EINVAL); - return NULL; - } -+ if (flags & V4L2_CTRL_FLAG_DYNAMIC_ARRAY) { -+ /* -+ * For now only support this for one-dimensional arrays only. -+ * -+ * This can be relaxed in the future, but this will -+ * require more effort. -+ */ -+ if (nr_of_dims != 1) { -+ handler_set_err(hdl, -EINVAL); -+ return NULL; -+ } -+ /* Start with just 1 element */ -+ elems = 1; -+ } - -+ tot_ctrl_size = elem_size * elems; - sz_extra = 0; - if (type == V4L2_CTRL_TYPE_BUTTON) - flags |= V4L2_CTRL_FLAG_WRITE_ONLY | - V4L2_CTRL_FLAG_EXECUTE_ON_WRITE; - else if (type == V4L2_CTRL_TYPE_CTRL_CLASS) - flags |= V4L2_CTRL_FLAG_READ_ONLY; -- else if (type == V4L2_CTRL_TYPE_INTEGER64 || -- type == V4L2_CTRL_TYPE_STRING || -- type >= V4L2_CTRL_COMPOUND_TYPES || -- is_array) -+ else if (!(flags & V4L2_CTRL_FLAG_DYNAMIC_ARRAY) && -+ (type == V4L2_CTRL_TYPE_INTEGER64 || -+ type == V4L2_CTRL_TYPE_STRING || -+ type >= V4L2_CTRL_COMPOUND_TYPES || -+ is_array)) - sz_extra += 2 * tot_ctrl_size; - - if (type >= V4L2_CTRL_COMPOUND_TYPES && p_def.p_const) -@@ -1333,7 +1430,9 @@ static struct v4l2_ctrl *v4l2_ctrl_new(s - ctrl->is_ptr = is_array || type >= V4L2_CTRL_COMPOUND_TYPES || ctrl->is_string; - ctrl->is_int = !ctrl->is_ptr && type != V4L2_CTRL_TYPE_INTEGER64; - ctrl->is_array = is_array; -+ ctrl->is_dyn_array = !!(flags & V4L2_CTRL_FLAG_DYNAMIC_ARRAY); - ctrl->elems = elems; -+ ctrl->new_elems = elems; - ctrl->nr_of_dims = nr_of_dims; - if (nr_of_dims) - memcpy(ctrl->dims, dims, nr_of_dims * sizeof(dims[0])); -@@ -1346,6 +1445,16 @@ static struct v4l2_ctrl *v4l2_ctrl_new(s - ctrl->cur.val = ctrl->val = def; - data = &ctrl[1]; - -+ if (ctrl->is_dyn_array) { -+ ctrl->p_dyn_alloc_elems = elems; -+ ctrl->p_dyn = kvzalloc(2 * elems * elem_size, GFP_KERNEL); -+ if (!ctrl->p_dyn) { -+ kvfree(ctrl); -+ return NULL; -+ } -+ data = ctrl->p_dyn; -+ } -+ - if (!ctrl->is_int) { - ctrl->p_new.p = data; - ctrl->p_cur.p = data + tot_ctrl_size; -@@ -1355,7 +1464,10 @@ static struct v4l2_ctrl *v4l2_ctrl_new(s - } - - if (type >= V4L2_CTRL_COMPOUND_TYPES && p_def.p_const) { -- ctrl->p_def.p = ctrl->p_cur.p + tot_ctrl_size; -+ if (ctrl->is_dyn_array) -+ ctrl->p_def.p = &ctrl[1]; -+ else -+ ctrl->p_def.p = ctrl->p_cur.p + tot_ctrl_size; - memcpy(ctrl->p_def.p, p_def.p_const, elem_size); - } - -@@ -1365,6 +1477,7 @@ static struct v4l2_ctrl *v4l2_ctrl_new(s - } - - if (handler_new_ref(hdl, ctrl, NULL, false, false)) { -+ kvfree(ctrl->p_dyn); - kvfree(ctrl); - return NULL; - } -@@ -1702,6 +1815,9 @@ static int cluster_changed(struct v4l2_c - continue; - } - -+ if (ctrl->elems != ctrl->new_elems) -+ ctrl_changed = true; -+ - for (idx = 0; !ctrl_changed && idx < ctrl->elems; idx++) - ctrl_changed = !ctrl->type_ops->equal(ctrl, idx, - ctrl->p_cur, ctrl->p_new); ---- a/drivers/media/v4l2-core/v4l2-ctrls-priv.h -+++ b/drivers/media/v4l2-core/v4l2-ctrls-priv.h -@@ -57,10 +57,9 @@ void cur_to_new(struct v4l2_ctrl *ctrl); - void cur_to_req(struct v4l2_ctrl_ref *ref); - void new_to_cur(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, u32 ch_flags); - void new_to_req(struct v4l2_ctrl_ref *ref); --void req_to_new(struct v4l2_ctrl_ref *ref); -+int req_to_new(struct v4l2_ctrl_ref *ref); - void send_initial_event(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl); - void send_event(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, u32 changes); --int validate_new(const struct v4l2_ctrl *ctrl, union v4l2_ctrl_ptr p_new); - int handler_new_ref(struct v4l2_ctrl_handler *hdl, - struct v4l2_ctrl *ctrl, - struct v4l2_ctrl_ref **ctrl_ref, ---- a/drivers/media/v4l2-core/v4l2-ctrls-request.c -+++ b/drivers/media/v4l2-core/v4l2-ctrls-request.c -@@ -143,7 +143,7 @@ v4l2_ctrl_request_hdl_ctrl_find(struct v - { - struct v4l2_ctrl_ref *ref = find_ref_lock(hdl, id); - -- return (ref && ref->valid_p_req) ? ref->ctrl : NULL; -+ return (ref && ref->p_req_valid) ? ref->ctrl : NULL; - } - EXPORT_SYMBOL_GPL(v4l2_ctrl_request_hdl_ctrl_find); - -@@ -373,7 +373,7 @@ void v4l2_ctrl_request_complete(struct m - v4l2_ctrl_unlock(master); - continue; - } -- if (ref->valid_p_req) -+ if (ref->p_req_valid) - continue; - - /* Copy the current control value into the request */ -@@ -442,7 +442,7 @@ int v4l2_ctrl_request_setup(struct media - struct v4l2_ctrl_ref *r = - find_ref(hdl, master->cluster[i]->id); - -- if (r->valid_p_req) { -+ if (r->p_req_valid) { - have_new_data = true; - break; - } -@@ -458,7 +458,11 @@ int v4l2_ctrl_request_setup(struct media - struct v4l2_ctrl_ref *r = - find_ref(hdl, master->cluster[i]->id); - -- req_to_new(r); -+ ret = req_to_new(r); -+ if (ret) { -+ v4l2_ctrl_unlock(master); -+ goto error; -+ } - master->cluster[i]->is_new = 1; - r->req_done = true; - } -@@ -490,6 +494,7 @@ int v4l2_ctrl_request_setup(struct media - break; - } - -+error: - media_request_object_put(obj); - return ret; - } ---- a/include/media/v4l2-ctrls.h -+++ b/include/media/v4l2-ctrls.h -@@ -181,6 +181,8 @@ typedef void (*v4l2_ctrl_notify_fnc)(str - * and/or has type %V4L2_CTRL_TYPE_STRING. In other words, &struct - * v4l2_ext_control uses field p to point to the data. - * @is_array: If set, then this control contains an N-dimensional array. -+ * @is_dyn_array: If set, then this control contains a dynamically sized 1-dimensional array. -+ * If this is set, then @is_array is also set. - * @has_volatiles: If set, then one or more members of the cluster are volatile. - * Drivers should never touch this flag. - * @call_notify: If set, then call the handler's notify function whenever the -@@ -201,6 +203,9 @@ typedef void (*v4l2_ctrl_notify_fnc)(str - * @step: The control's step value for non-menu controls. - * @elems: The number of elements in the N-dimensional array. - * @elem_size: The size in bytes of the control. -+ * @new_elems: The number of elements in p_new. This is the same as @elems, -+ * except for dynamic arrays. In that case it is in the range of -+ * 1 to @p_dyn_alloc_elems. - * @dims: The size of each dimension. - * @nr_of_dims:The number of dimensions in @dims. - * @menu_skip_mask: The control's skip mask for menu controls. This makes it -@@ -219,15 +224,21 @@ typedef void (*v4l2_ctrl_notify_fnc)(str - * :math:`ceil(\frac{maximum - minimum}{step}) + 1`. - * Used only if the @type is %V4L2_CTRL_TYPE_INTEGER_MENU. - * @flags: The control's flags. -- * @cur: Structure to store the current value. -- * @cur.val: The control's current value, if the @type is represented via -- * a u32 integer (see &enum v4l2_ctrl_type). -- * @val: The control's new s32 value. - * @priv: The control's private pointer. For use by the driver. It is - * untouched by the control framework. Note that this pointer is - * not freed when the control is deleted. Should this be needed - * then a new internal bitfield can be added to tell the framework - * to free this pointer. -+ * @p_dyn: Pointer to the dynamically allocated array. Only valid if -+ * @is_dyn_array is true. -+ * @p_dyn_alloc_elems: The number of elements in the dynamically allocated -+ * array for both the cur and new values. So @p_dyn is actually -+ * sized for 2 * @p_dyn_alloc_elems * @elem_size. Only valid if -+ * @is_dyn_array is true. -+ * @cur: Structure to store the current value. -+ * @cur.val: The control's current value, if the @type is represented via -+ * a u32 integer (see &enum v4l2_ctrl_type). -+ * @val: The control's new s32 value. - * @p_def: The control's default value represented via a union which - * provides a standard way of accessing control types - * through a pointer (for compound controls only). -@@ -256,6 +267,7 @@ struct v4l2_ctrl { - unsigned int is_string:1; - unsigned int is_ptr:1; - unsigned int is_array:1; -+ unsigned int is_dyn_array:1; - unsigned int has_volatiles:1; - unsigned int call_notify:1; - unsigned int manual_mode_value:8; -@@ -268,6 +280,7 @@ struct v4l2_ctrl { - s64 minimum, maximum, default_value; - u32 elems; - u32 elem_size; -+ u32 new_elems; - u32 dims[V4L2_CTRL_MAX_DIMS]; - u32 nr_of_dims; - union { -@@ -280,6 +293,8 @@ struct v4l2_ctrl { - }; - unsigned long flags; - void *priv; -+ void *p_dyn; -+ u32 p_dyn_alloc_elems; - s32 val; - struct { - s32 val; -@@ -305,12 +320,22 @@ struct v4l2_ctrl { - * the control has been applied. This prevents applying controls - * from a cluster with multiple controls twice (when the first - * control of a cluster is applied, they all are). -- * @valid_p_req: If set, then p_req contains the control value for the request. -+ * @p_req_valid: If set, then p_req contains the control value for the request. -+ * @p_req_dyn_enomem: If set, then p_req is invalid since allocating space for -+ * a dynamic array failed. Attempting to read this value shall -+ * result in ENOMEM. Only valid if ctrl->is_dyn_array is true. -+ * @p_req_dyn_alloc_elems: The number of elements allocated for the dynamic -+ * array. Only valid if @p_req_valid and ctrl->is_dyn_array are -+ * true. -+ * @p_req_elems: The number of elements in @p_req. This is the same as -+ * ctrl->elems, except for dynamic arrays. In that case it is in -+ * the range of 1 to @p_req_dyn_alloc_elems. Only valid if -+ * @p_req_valid is true. - * @p_req: If the control handler containing this control reference - * is bound to a media request, then this points to the - * value of the control that must be applied when the request - * is executed, or to the value of the control at the time -- * that the request was completed. If @valid_p_req is false, -+ * that the request was completed. If @p_req_valid is false, - * then this control was never set for this request and the - * control will not be updated when this request is applied. - * -@@ -325,7 +350,10 @@ struct v4l2_ctrl_ref { - struct v4l2_ctrl_helper *helper; - bool from_other_dev; - bool req_done; -- bool valid_p_req; -+ bool p_req_valid; -+ bool p_req_dyn_enomem; -+ u32 p_req_dyn_alloc_elems; -+ u32 p_req_elems; - union v4l2_ctrl_ptr p_req; - }; - diff --git a/target/linux/bcm27xx/patches-5.15/950-0466-media-rpivid-Make-slice-ctrl-dynamic.patch b/target/linux/bcm27xx/patches-5.15/950-0466-media-rpivid-Make-slice-ctrl-dynamic.patch deleted file mode 100644 index 66e978371..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0466-media-rpivid-Make-slice-ctrl-dynamic.patch +++ /dev/null @@ -1,334 +0,0 @@ -From 4ab81f113bdf1ca8c3b0d53c777885aa33ed27f3 Mon Sep 17 00:00:00 2001 -From: John Cox -Date: Thu, 29 Apr 2021 19:17:06 +0100 -Subject: [PATCH] media: rpivid: Make slice ctrl dynamic - -Allows the user to submit a whole frames worth of slice headers in -one lump along with a single bitstream dmabuf for the whole lot. -This saves potentially a lot of bitstream copying. - -Signed-off-by: John Cox ---- - drivers/staging/media/rpivid/rpivid.c | 4 + - drivers/staging/media/rpivid/rpivid_dec.c | 18 ++- - drivers/staging/media/rpivid/rpivid_h265.c | 151 +++++++++++---------- - 3 files changed, 99 insertions(+), 74 deletions(-) - ---- a/drivers/staging/media/rpivid/rpivid.c -+++ b/drivers/staging/media/rpivid/rpivid.c -@@ -63,7 +63,11 @@ static const struct rpivid_control rpivi - }, - { - .cfg = { -+ .name = "Slice param array", - .id = V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS, -+ .type = V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS, -+ .flags = V4L2_CTRL_FLAG_DYNAMIC_ARRAY, -+ .dims = { 0x1000 }, - }, - .required = true, - }, ---- a/drivers/staging/media/rpivid/rpivid_dec.c -+++ b/drivers/staging/media/rpivid/rpivid_dec.c -@@ -46,22 +46,34 @@ void rpivid_device_run(void *priv) - - switch (ctx->src_fmt.pixelformat) { - case V4L2_PIX_FMT_HEVC_SLICE: -+ { -+ const struct v4l2_ctrl *ctrl; -+ - run.h265.sps = - rpivid_find_control_data(ctx, - V4L2_CID_MPEG_VIDEO_HEVC_SPS); - run.h265.pps = - rpivid_find_control_data(ctx, - V4L2_CID_MPEG_VIDEO_HEVC_PPS); -- run.h265.slice_params = -- rpivid_find_control_data(ctx, -- V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS); - run.h265.dec = - rpivid_find_control_data(ctx, - V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS); -+ -+ ctrl = rpivid_find_ctrl(ctx, -+ V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS); -+ if (!ctrl || !ctrl->elems) { -+ v4l2_err(&dev->v4l2_dev, "%s: Missing slice params\n", -+ __func__); -+ goto fail; -+ } -+ run.h265.slice_ents = ctrl->elems; -+ run.h265.slice_params = ctrl->p_cur.p; -+ - run.h265.scaling_matrix = - rpivid_find_control_data(ctx, - V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX); - break; -+ } - - default: - break; ---- a/drivers/staging/media/rpivid/rpivid_h265.c -+++ b/drivers/staging/media/rpivid/rpivid_h265.c -@@ -245,7 +245,6 @@ struct rpivid_dec_state { - - // Slice vars - unsigned int slice_idx; -- bool frame_end; - bool slice_temporal_mvp; /* Slice flag but constant for frame */ - - // Temp vars per run - don't actually need to persist -@@ -740,7 +739,8 @@ static void new_slice_segment(struct rpi - V4L2_HEVC_PPS_FLAG_CONSTRAINED_INTRA_PRED)) - << 24)); - -- if ((sps->flags & V4L2_HEVC_SPS_FLAG_SCALING_LIST_ENABLED) != 0) -+ if (!s->start_ts && -+ (sps->flags & V4L2_HEVC_SPS_FLAG_SCALING_LIST_ENABLED) != 0) - write_scaling_factors(de); - - if (!s->dependent_slice_segment_flag) { -@@ -1111,7 +1111,8 @@ static int wpp_end_previous_slice(struct - * next chunk code simpler - */ - static int wpp_decode_slice(struct rpivid_dec_env *const de, -- const struct rpivid_dec_state *const s) -+ const struct rpivid_dec_state *const s, -+ bool last_slice) - { - bool reset_qp_y = true; - const bool indep = !s->dependent_slice_segment_flag; -@@ -1150,7 +1151,7 @@ static int wpp_decode_slice(struct rpivi - 0, 0, s->start_ctb_x, s->start_ctb_y, - s->slice_qp, slice_reg_const(s)); - -- if (s->frame_end) { -+ if (last_slice) { - rv = wpp_entry_fill(de, s, s->ctb_height - 1); - if (rv) - return rv; -@@ -1229,7 +1230,8 @@ static int end_previous_slice(struct rpi - } - - static int decode_slice(struct rpivid_dec_env *const de, -- const struct rpivid_dec_state *const s) -+ const struct rpivid_dec_state *const s, -+ bool last_slice) - { - bool reset_qp_y; - unsigned int tile_x = ctb_to_tile_x(s, s->start_ctb_x); -@@ -1275,7 +1277,7 @@ static int decode_slice(struct rpivid_de - * now, otherwise this will be done at the start of the next slice - * when it will be known where this slice finishes - */ -- if (s->frame_end) { -+ if (last_slice) { - rv = tile_entry_fill(de, s, - s->tile_width - 1, - s->tile_height - 1); -@@ -1670,11 +1672,13 @@ static u32 mk_config2(const struct rpivi - static void rpivid_h265_setup(struct rpivid_ctx *ctx, struct rpivid_run *run) - { - struct rpivid_dev *const dev = ctx->dev; -- const struct v4l2_ctrl_hevc_slice_params *const sh = -- run->h265.slice_params; - const struct v4l2_ctrl_hevc_decode_params *const dec = - run->h265.dec; --// const struct v4l2_hevc_pred_weight_table *pred_weight_table; -+ /* sh0 used where slice header contents should be constant over all -+ * slices, or first slice of frame -+ */ -+ const struct v4l2_ctrl_hevc_slice_params *const sh0 = -+ run->h265.slice_params; - struct rpivid_q_aux *dpb_q_aux[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; - struct rpivid_dec_state *const s = ctx->state; - struct vb2_queue *vq; -@@ -1684,20 +1688,18 @@ static void rpivid_h265_setup(struct rpi - int use_aux; - int rv; - bool slice_temporal_mvp; -+ bool frame_end; - - xtrace_in(dev, de); -+ s->sh = NULL; // Avoid use until in the slice loop - --// pred_weight_table = &sh->pred_weight_table; -- -- s->frame_end = -+ frame_end = - ((run->src->flags & V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF) == 0); - -- slice_temporal_mvp = (sh->flags & -+ slice_temporal_mvp = (sh0->flags & - V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_TEMPORAL_MVP_ENABLED); - - if (de && de->state != RPIVID_DECODE_END) { -- ++s->slice_idx; -- - switch (de->state) { - case RPIVID_DECODE_SLICE_CONTINUE: - // Expected state -@@ -1830,7 +1832,7 @@ static void rpivid_h265_setup(struct rpi - de->rpi_config2 = mk_config2(s); - de->rpi_framesize = (s->sps.pic_height_in_luma_samples << 16) | - s->sps.pic_width_in_luma_samples; -- de->rpi_currpoc = sh->slice_pic_order_cnt; -+ de->rpi_currpoc = sh0->slice_pic_order_cnt; - - if (s->sps.flags & - V4L2_HEVC_SPS_FLAG_SPS_TEMPORAL_MVP_ENABLED) { -@@ -1839,17 +1841,17 @@ static void rpivid_h265_setup(struct rpi - - s->slice_idx = 0; - -- if (sh->slice_segment_addr != 0) { -+ if (sh0->slice_segment_addr != 0) { - v4l2_warn(&dev->v4l2_dev, - "New frame but segment_addr=%d\n", -- sh->slice_segment_addr); -+ sh0->slice_segment_addr); - goto fail; - } - - /* Allocate a bitbuf if we need one - don't need one if single - * slice as we can use the src buf directly - */ -- if (!s->frame_end && !de->bit_copy_gptr->ptr) { -+ if (!frame_end && !de->bit_copy_gptr->ptr) { - size_t bits_alloc; - bits_alloc = rpivid_bit_buf_size(s->sps.pic_width_in_luma_samples, - s->sps.pic_height_in_luma_samples, -@@ -1873,21 +1875,7 @@ static void rpivid_h265_setup(struct rpi - s->src_addr = 0; - s->src_buf = NULL; - -- if (run->src->planes[0].bytesused < (sh->bit_size + 7) / 8) { -- v4l2_warn(&dev->v4l2_dev, -- "Bit size %d > bytesused %d\n", -- sh->bit_size, run->src->planes[0].bytesused); -- goto fail; -- } -- if (sh->data_bit_offset >= sh->bit_size || -- sh->bit_size - sh->data_bit_offset < 8) { -- v4l2_warn(&dev->v4l2_dev, -- "Bit size %d < Bit offset %d + 8\n", -- sh->bit_size, sh->data_bit_offset); -- goto fail; -- } -- -- if (s->frame_end) -+ if (frame_end) - s->src_addr = vb2_dma_contig_plane_dma_addr(&run->src->vb2_buf, - 0); - if (!s->src_addr) -@@ -1898,44 +1886,65 @@ static void rpivid_h265_setup(struct rpi - } - - // Pre calc a few things -- s->sh = sh; - s->dec = dec; -- s->slice_qp = 26 + s->pps.init_qp_minus26 + s->sh->slice_qp_delta; -- s->max_num_merge_cand = sh->slice_type == HEVC_SLICE_I ? -+ for (i = 0; i != run->h265.slice_ents; ++i) { -+ const struct v4l2_ctrl_hevc_slice_params *const sh = sh0 + i; -+ const bool last_slice = frame_end && i + 1 == run->h265.slice_ents; -+ -+ s->sh = sh; -+ -+ if (run->src->planes[0].bytesused < (sh->bit_size + 7) / 8) { -+ v4l2_warn(&dev->v4l2_dev, -+ "Bit size %d > bytesused %d\n", -+ sh->bit_size, run->src->planes[0].bytesused); -+ goto fail; -+ } -+ if (sh->data_bit_offset >= sh->bit_size || -+ sh->bit_size - sh->data_bit_offset < 8) { -+ v4l2_warn(&dev->v4l2_dev, -+ "Bit size %d < Bit offset %d + 8\n", -+ sh->bit_size, sh->data_bit_offset); -+ goto fail; -+ } -+ -+ s->slice_qp = 26 + s->pps.init_qp_minus26 + sh->slice_qp_delta; -+ s->max_num_merge_cand = sh->slice_type == HEVC_SLICE_I ? -+ 0 : -+ (5 - sh->five_minus_max_num_merge_cand); -+ s->dependent_slice_segment_flag = -+ ((sh->flags & -+ V4L2_HEVC_SLICE_PARAMS_FLAG_DEPENDENT_SLICE_SEGMENT) != 0); -+ -+ s->nb_refs[0] = (sh->slice_type == HEVC_SLICE_I) ? -+ 0 : -+ sh->num_ref_idx_l0_active_minus1 + 1; -+ s->nb_refs[1] = (sh->slice_type != HEVC_SLICE_B) ? - 0 : -- (5 - sh->five_minus_max_num_merge_cand); -- // * SH DSS flag invented by me - but clearly needed -- s->dependent_slice_segment_flag = -- ((sh->flags & -- V4L2_HEVC_SLICE_PARAMS_FLAG_DEPENDENT_SLICE_SEGMENT) != 0); -- -- s->nb_refs[0] = (sh->slice_type == HEVC_SLICE_I) ? -- 0 : -- sh->num_ref_idx_l0_active_minus1 + 1; -- s->nb_refs[1] = (sh->slice_type != HEVC_SLICE_B) ? -- 0 : -- sh->num_ref_idx_l1_active_minus1 + 1; -- -- if (s->sps.flags & V4L2_HEVC_SPS_FLAG_SCALING_LIST_ENABLED) -- populate_scaling_factors(run, de, s); -- -- // Calc all the random coord info to avoid repeated conversion in/out -- s->start_ts = s->ctb_addr_rs_to_ts[sh->slice_segment_addr]; -- s->start_ctb_x = sh->slice_segment_addr % de->pic_width_in_ctbs_y; -- s->start_ctb_y = sh->slice_segment_addr / de->pic_width_in_ctbs_y; -- // Last CTB of previous slice -- prev_rs = !s->start_ts ? 0 : s->ctb_addr_ts_to_rs[s->start_ts - 1]; -- s->prev_ctb_x = prev_rs % de->pic_width_in_ctbs_y; -- s->prev_ctb_y = prev_rs / de->pic_width_in_ctbs_y; -+ sh->num_ref_idx_l1_active_minus1 + 1; - -- if ((s->pps.flags & V4L2_HEVC_PPS_FLAG_ENTROPY_CODING_SYNC_ENABLED)) -- rv = wpp_decode_slice(de, s); -- else -- rv = decode_slice(de, s); -- if (rv) -- goto fail; -+ if (s->sps.flags & V4L2_HEVC_SPS_FLAG_SCALING_LIST_ENABLED) -+ populate_scaling_factors(run, de, s); -+ -+ /* Calc all the random coord info to avoid repeated conversion in/out */ -+ s->start_ts = s->ctb_addr_rs_to_ts[sh->slice_segment_addr]; -+ s->start_ctb_x = sh->slice_segment_addr % de->pic_width_in_ctbs_y; -+ s->start_ctb_y = sh->slice_segment_addr / de->pic_width_in_ctbs_y; -+ /* Last CTB of previous slice */ -+ prev_rs = !s->start_ts ? 0 : s->ctb_addr_ts_to_rs[s->start_ts - 1]; -+ s->prev_ctb_x = prev_rs % de->pic_width_in_ctbs_y; -+ s->prev_ctb_y = prev_rs / de->pic_width_in_ctbs_y; -+ -+ if ((s->pps.flags & V4L2_HEVC_PPS_FLAG_ENTROPY_CODING_SYNC_ENABLED)) -+ rv = wpp_decode_slice(de, s, last_slice); -+ else -+ rv = decode_slice(de, s, last_slice); -+ if (rv) -+ goto fail; -+ -+ ++s->slice_idx; -+ } - -- if (!s->frame_end) { -+ if (!frame_end) { - xtrace_ok(dev, de); - return; - } -@@ -2054,8 +2063,8 @@ static void rpivid_h265_setup(struct rpi - fail: - if (de) - // Actual error reporting happens in Trigger -- de->state = s->frame_end ? RPIVID_DECODE_ERROR_DONE : -- RPIVID_DECODE_ERROR_CONTINUE; -+ de->state = frame_end ? RPIVID_DECODE_ERROR_DONE : -+ RPIVID_DECODE_ERROR_CONTINUE; - xtrace_fail(dev, de); - } - diff --git a/target/linux/bcm27xx/patches-5.15/950-0467-media-rpivid-Only-create-aux-entries-for-H265-if-nee.patch b/target/linux/bcm27xx/patches-5.15/950-0467-media-rpivid-Only-create-aux-entries-for-H265-if-nee.patch deleted file mode 100644 index 8fcd0c20d..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0467-media-rpivid-Only-create-aux-entries-for-H265-if-nee.patch +++ /dev/null @@ -1,111 +0,0 @@ -From 9b0eddfd7341525e0e3074a7f6202f5ccd431b05 Mon Sep 17 00:00:00 2001 -From: John Cox -Date: Thu, 6 May 2021 13:48:05 +0100 -Subject: [PATCH] media: rpivid: Only create aux entries for H265 if - needed - -Only create aux entries of mv info for frames where that info might -be used by a later frame. This saves some memory bandwidth and -potentially some memory. - -Signed-off-by: John Cox ---- - drivers/staging/media/rpivid/rpivid_h265.c | 38 +++++++++++++--------- - 1 file changed, 23 insertions(+), 15 deletions(-) - ---- a/drivers/staging/media/rpivid/rpivid_h265.c -+++ b/drivers/staging/media/rpivid/rpivid_h265.c -@@ -246,6 +246,8 @@ struct rpivid_dec_state { - // Slice vars - unsigned int slice_idx; - bool slice_temporal_mvp; /* Slice flag but constant for frame */ -+ bool use_aux; -+ bool mk_aux; - - // Temp vars per run - don't actually need to persist - u8 *src_buf; -@@ -1657,7 +1659,7 @@ static u32 mk_config2(const struct rpivi - c |= BIT(13); - if (sps->flags & V4L2_HEVC_SPS_FLAG_STRONG_INTRA_SMOOTHING_ENABLED) - c |= BIT(14); -- if (sps->flags & V4L2_HEVC_SPS_FLAG_SPS_TEMPORAL_MVP_ENABLED) -+ if (s->mk_aux) - c |= BIT(15); /* Write motion vectors to external memory */ - c |= (pps->log2_parallel_merge_level_minus2 + 2) << 16; - if (s->slice_temporal_mvp) -@@ -1669,6 +1671,14 @@ static u32 mk_config2(const struct rpivi - return c; - } - -+static inline bool is_ref_unit_type(const unsigned int nal_unit_type) -+{ -+ /* From Table 7-1 -+ * True for 1, 3, 5, 7, 9, 11, 13, 15 -+ */ -+ return (nal_unit_type & ~0xe) != 0; -+} -+ - static void rpivid_h265_setup(struct rpivid_ctx *ctx, struct rpivid_run *run) - { - struct rpivid_dev *const dev = ctx->dev; -@@ -1685,7 +1695,6 @@ static void rpivid_h265_setup(struct rpi - struct rpivid_dec_env *de = ctx->dec0; - unsigned int prev_rs; - unsigned int i; -- int use_aux; - int rv; - bool slice_temporal_mvp; - bool frame_end; -@@ -1828,6 +1837,16 @@ static void rpivid_h265_setup(struct rpi - */ - s->slice_temporal_mvp = slice_temporal_mvp; - -+ /* -+ * Need Aux ents for all (ref) DPB ents if temporal MV could -+ * be enabled for any pic -+ */ -+ s->use_aux = ((s->sps.flags & -+ V4L2_HEVC_SPS_FLAG_SPS_TEMPORAL_MVP_ENABLED) != 0); -+ s->mk_aux = s->use_aux && -+ (s->sps.sps_max_sub_layers_minus1 >= sh0->nuh_temporal_id_plus1 || -+ is_ref_unit_type(sh0->nal_unit_type)); -+ - // Phase 2 reg pre-calc - de->rpi_config2 = mk_config2(s); - de->rpi_framesize = (s->sps.pic_height_in_luma_samples << 16) | -@@ -1952,15 +1971,6 @@ static void rpivid_h265_setup(struct rpi - // Frame end - memset(dpb_q_aux, 0, - sizeof(*dpb_q_aux) * V4L2_HEVC_DPB_ENTRIES_NUM_MAX); -- /* -- * Need Aux ents for all (ref) DPB ents if temporal MV could -- * be enabled for any pic -- * ** At the moment we create aux ents for all pics whether or not -- * they are ref - they should then be discarded by the DPB-aux -- * garbage collection code -- */ -- use_aux = ((s->sps.flags & -- V4L2_HEVC_SPS_FLAG_SPS_TEMPORAL_MVP_ENABLED) != 0); - - // Locate ref frames - // At least in the current implementation this is constant across all -@@ -1994,7 +2004,7 @@ static void rpivid_h265_setup(struct rpi - continue; - } - -- if (use_aux) { -+ if (s->use_aux) { - dpb_q_aux[i] = aux_q_ref_idx(ctx, buffer_index); - if (!dpb_q_aux[i]) - v4l2_warn(&dev->v4l2_dev, -@@ -2016,9 +2026,7 @@ static void rpivid_h265_setup(struct rpi - // now - aux_q_release(ctx, &s->frame_aux); - -- if (use_aux) { -- // New frame so new aux ent -- // ??? Do we need this if non-ref ??? can we tell -+ if (s->mk_aux) { - s->frame_aux = aux_q_new(ctx, run->dst->vb2_buf.index); - - if (!s->frame_aux) { diff --git a/target/linux/bcm27xx/patches-5.15/950-0469-media-i2c-imx477-Allow-control-of-on-sensor-DPC.patch b/target/linux/bcm27xx/patches-5.15/950-0469-media-i2c-imx477-Allow-control-of-on-sensor-DPC.patch deleted file mode 100644 index c6c4cbc46..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0469-media-i2c-imx477-Allow-control-of-on-sensor-DPC.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 2b6edd13bb5152c659466987846b481df8b37393 Mon Sep 17 00:00:00 2001 -From: David Plowman -Date: Wed, 8 Sep 2021 14:15:17 +0100 -Subject: [PATCH] media: i2c: imx477: Allow control of on-sensor DPC - -A module parameter "dpc_enable" is added to allow the control of the -sensor's on-board DPC (Defective Pixel Correction) function. - -This is a global setting to be configured before using the sensor; -there is no intention that this would ever be changed on-the-fly. - -Signed-off-by: David Plowman ---- - drivers/media/i2c/imx477.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - ---- a/drivers/media/i2c/imx477.c -+++ b/drivers/media/i2c/imx477.c -@@ -21,6 +21,10 @@ - #include - #include - -+static int dpc_enable = 1; -+module_param(dpc_enable, int, 0644); -+MODULE_PARM_DESC(dpc_enable, "Enable on-sensor DPC"); -+ - #define IMX477_REG_VALUE_08BIT 1 - #define IMX477_REG_VALUE_16BIT 2 - -@@ -1713,6 +1717,10 @@ static int imx477_start_streaming(struct - return ret; - } - -+ /* Set on-sensor DPC. */ -+ imx477_write_reg(imx477, 0x0b05, IMX477_REG_VALUE_08BIT, !!dpc_enable); -+ imx477_write_reg(imx477, 0x0b06, IMX477_REG_VALUE_08BIT, !!dpc_enable); -+ - /* Apply customized values from user */ - ret = __v4l2_ctrl_handler_setup(imx477->sd.ctrl_handler); - if (ret) diff --git a/target/linux/bcm27xx/patches-5.15/950-0470-sound-usb-add-device-quirks-for-A4Tech-FHD-1080p-web.patch b/target/linux/bcm27xx/patches-5.15/950-0470-sound-usb-add-device-quirks-for-A4Tech-FHD-1080p-web.patch deleted file mode 100644 index 50fbab5f7..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0470-sound-usb-add-device-quirks-for-A4Tech-FHD-1080p-web.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 01160071692034601de24ff811b1996481bfea55 Mon Sep 17 00:00:00 2001 -From: Jonathan Bell -Date: Thu, 15 Apr 2021 13:15:14 +0100 -Subject: [PATCH] sound/usb: add device quirks for A4Tech FHD 1080p - webcams - -These devices use a type of Sonix chipset that produces broken microphone -data if suspended/resumed. - -They also don't support readback of the sample rate. - -Signed-off-by: Jonathan Bell ---- - sound/usb/quirks.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/sound/usb/quirks.c -+++ b/sound/usb/quirks.c -@@ -1892,6 +1892,8 @@ static const struct usb_audio_quirk_flag - QUIRK_FLAG_GENERIC_IMPLICIT_FB), - DEVICE_FLG(0x2b53, 0x0031, /* Fiero SC-01 (firmware v1.1.0) */ - QUIRK_FLAG_GENERIC_IMPLICIT_FB), -+ DEVICE_FLG(0x09da, 0x2695, /* A4Tech FHD 1080p webcam */ -+ QUIRK_FLAG_DISABLE_AUTOSUSPEND | QUIRK_FLAG_GET_SAMPLE_RATE), - DEVICE_FLG(0x0525, 0xa4ad, /* Hamedal C20 usb camero */ - QUIRK_FLAG_IFACE_SKIP_CLOSE), - diff --git a/target/linux/bcm27xx/patches-5.15/950-0471-sound-usb-call-usb_autopm_get_interface-for-devices-.patch b/target/linux/bcm27xx/patches-5.15/950-0471-sound-usb-call-usb_autopm_get_interface-for-devices-.patch deleted file mode 100644 index a586d075d..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0471-sound-usb-call-usb_autopm_get_interface-for-devices-.patch +++ /dev/null @@ -1,37 +0,0 @@ -From cea2dbec1b8e84b95459f4a589c613b84e3d9737 Mon Sep 17 00:00:00 2001 -From: Jonathan Bell -Date: Wed, 15 Sep 2021 17:56:45 +0100 -Subject: [PATCH] sound/usb: call usb_autopm_get_interface() for - devices that should not be suspended - -Webcams with microphones are composite devices, and autosuspend is set -at the device level. If uvcvideo is probed after snd-usb-audio, the effect -of the quirk applied by snd-usb-audio is undone by uvcvideo's global -application of autosuspend. - -Incrementing the interface's PM refcount in such cases prevents runtime PM -from happening, thus the device is left active. - -Signed-off-by: Jonathan Bell ---- - sound/usb/card.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - ---- a/sound/usb/card.c -+++ b/sound/usb/card.c -@@ -855,8 +855,14 @@ static int usb_audio_probe(struct usb_in - if (ignore_ctl_error) - chip->quirk_flags |= QUIRK_FLAG_IGNORE_CTL_ERROR; - -- if (chip->quirk_flags & QUIRK_FLAG_DISABLE_AUTOSUSPEND) -+ if (chip->quirk_flags & QUIRK_FLAG_DISABLE_AUTOSUSPEND) { -+ /* -+ * Grab the interface, because on a webcam uvcvideo may race -+ * with snd-usb-audio during probe and re-enable autosuspend. -+ */ -+ usb_autopm_get_interface(intf); - usb_disable_autosuspend(interface_to_usbdev(intf)); -+ } - - /* - * For devices with more than one control interface, we assume the diff --git a/target/linux/bcm27xx/patches-5.15/950-0481-regulator-rpi-panel-Register-with-a-unique-backlight.patch b/target/linux/bcm27xx/patches-5.15/950-0481-regulator-rpi-panel-Register-with-a-unique-backlight.patch deleted file mode 100644 index a0e745bc3..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0481-regulator-rpi-panel-Register-with-a-unique-backlight.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 2d0958a56e6b0da1510ed86f4fb7409b43fedb4d Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 11 Feb 2021 18:46:06 +0000 -Subject: [PATCH] regulator: rpi-panel: Register with a unique - backlight name - -There's no reason why 2 Raspberry Pi DSI displays can't be -attached to a Pi Compute Module, so the backlight names need to -be unique. - -Use the parent dev_name. It's not as readable, but is unique. - -Signed-off-by: Dave Stevenson ---- - drivers/regulator/rpi-panel-attiny-regulator.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - ---- a/drivers/regulator/rpi-panel-attiny-regulator.c -+++ b/drivers/regulator/rpi-panel-attiny-regulator.c -@@ -217,8 +217,7 @@ static int attiny_i2c_probe(struct i2c_c - - props.type = BACKLIGHT_RAW; - props.max_brightness = 0xff; -- bl = devm_backlight_device_register(&i2c->dev, -- "7inch-touchscreen-panel-bl", -+ bl = devm_backlight_device_register(&i2c->dev, dev_name(&i2c->dev), - &i2c->dev, regmap, &attiny_bl, - &props); - if (IS_ERR(bl)) diff --git a/target/linux/bcm27xx/patches-5.15/950-0482-regulator-rpi-panel-Serialise-operations.patch b/target/linux/bcm27xx/patches-5.15/950-0482-regulator-rpi-panel-Serialise-operations.patch deleted file mode 100644 index 67543ea19..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0482-regulator-rpi-panel-Serialise-operations.patch +++ /dev/null @@ -1,255 +0,0 @@ -From 354dfe9793ff5f814830c6841ca07ef04bfd66e9 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Wed, 8 Sep 2021 15:02:05 +0100 -Subject: [PATCH] regulator: rpi-panel: Serialise operations. - -The driver was using the regmap lock to serialise the -individual accesses, but we really need to protect the -timings of enabling the regulators, including any communication -with the Atmel. - -Use a mutex within the driver to control overall accesses to -the Atmel, instead of the regmap lock. - -Signed-off-by: Dave Stevenson ---- - .../regulator/rpi-panel-attiny-regulator.c | 91 ++++++++++++++++--- - 1 file changed, 80 insertions(+), 11 deletions(-) - ---- a/drivers/regulator/rpi-panel-attiny-regulator.c -+++ b/drivers/regulator/rpi-panel-attiny-regulator.c -@@ -27,18 +27,28 @@ - #define REG_POWERON 0x85 - #define REG_PWM 0x86 - -+struct attiny_lcd { -+ /* lock to serialise overall accesses to the Atmel */ -+ struct mutex lock; -+ struct regmap *regmap; -+}; -+ - static const struct regmap_config attiny_regmap_config = { - .reg_bits = 8, - .val_bits = 8, -+ .disable_locking = 1, - .max_register = REG_PWM, - .cache_type = REGCACHE_NONE, - }; - - static int attiny_lcd_power_enable(struct regulator_dev *rdev) - { -+ struct mutex *lock = rdev_get_drvdata(rdev); - unsigned int data; - int ret, i; - -+ mutex_lock(lock); -+ - regmap_write(rdev->regmap, REG_POWERON, 1); - msleep(80); - -@@ -63,33 +73,49 @@ static int attiny_lcd_power_enable(struc - */ - regmap_write(rdev->regmap, REG_PORTA, BIT(2)); - -+ mutex_unlock(lock); -+ - return 0; - } - - static int attiny_lcd_power_disable(struct regulator_dev *rdev) - { -+ struct mutex *lock = rdev_get_drvdata(rdev); -+ -+ mutex_lock(lock); -+ - regmap_write(rdev->regmap, REG_PWM, 0); - regmap_write(rdev->regmap, REG_POWERON, 0); - msleep(30); -+ -+ mutex_unlock(lock); -+ - return 0; - } - - static int attiny_lcd_power_is_enabled(struct regulator_dev *rdev) - { -+ struct mutex *lock = rdev_get_drvdata(rdev); - unsigned int data; - int ret, i; - -+ mutex_lock(lock); -+ - for (i = 0; i < 10; i++) { - ret = regmap_read(rdev->regmap, REG_POWERON, &data); - if (!ret) - break; - usleep_range(10000, 12000); - } -- if (ret < 0) -+ if (ret < 0) { -+ mutex_unlock(lock); - return ret; -+ } - -- if (!(data & BIT(0))) -+ if (!(data & BIT(0))) { -+ mutex_unlock(lock); - return 0; -+ } - - for (i = 0; i < 10; i++) { - ret = regmap_read(rdev->regmap, REG_PORTB, &data); -@@ -98,6 +124,8 @@ static int attiny_lcd_power_is_enabled(s - usleep_range(10000, 12000); - } - -+ mutex_unlock(lock); -+ - if (ret < 0) - return ret; - -@@ -125,10 +153,13 @@ static const struct regulator_desc attin - - static int attiny_update_status(struct backlight_device *bl) - { -- struct regmap *regmap = bl_get_data(bl); -+ struct attiny_lcd *state = bl_get_data(bl); -+ struct regmap *regmap = state->regmap; - int brightness = bl->props.brightness; - int ret, i; - -+ mutex_lock(&state->lock); -+ - if (bl->props.power != FB_BLANK_UNBLANK || - bl->props.fb_blank != FB_BLANK_UNBLANK) - brightness = 0; -@@ -139,20 +170,27 @@ static int attiny_update_status(struct b - break; - } - -+ mutex_unlock(&state->lock); -+ - return ret; - } - - static int attiny_get_brightness(struct backlight_device *bl) - { -- struct regmap *regmap = bl_get_data(bl); -+ struct attiny_lcd *state = bl_get_data(bl); -+ struct regmap *regmap = state->regmap; - int ret, brightness, i; - -+ mutex_lock(&state->lock); -+ - for (i = 0; i < 10; i++) { - ret = regmap_read(regmap, REG_PWM, &brightness); - if (!ret) - break; - } - -+ mutex_unlock(&state->lock); -+ - if (ret) - return ret; - -@@ -174,22 +212,30 @@ static int attiny_i2c_probe(struct i2c_c - struct regulator_config config = { }; - struct backlight_device *bl; - struct regulator_dev *rdev; -+ struct attiny_lcd *state; - struct regmap *regmap; - unsigned int data; - int ret; - -+ state = devm_kzalloc(&i2c->dev, sizeof(*state), GFP_KERNEL); -+ if (!state) -+ return -ENOMEM; -+ -+ mutex_init(&state->lock); -+ i2c_set_clientdata(i2c, state); -+ - regmap = devm_regmap_init_i2c(i2c, &attiny_regmap_config); - if (IS_ERR(regmap)) { - ret = PTR_ERR(regmap); - dev_err(&i2c->dev, "Failed to allocate register map: %d\n", - ret); -- return ret; -+ goto error; - } - - ret = regmap_read(regmap, REG_ID, &data); - if (ret < 0) { - dev_err(&i2c->dev, "Failed to read REG_ID reg: %d\n", ret); -- return ret; -+ goto error; - } - - switch (data) { -@@ -198,7 +244,8 @@ static int attiny_i2c_probe(struct i2c_c - break; - default: - dev_err(&i2c->dev, "Unknown Atmel firmware revision: 0x%02x\n", data); -- return -ENODEV; -+ ret = -ENODEV; -+ goto error; - } - - regmap_write(regmap, REG_POWERON, 0); -@@ -208,24 +255,45 @@ static int attiny_i2c_probe(struct i2c_c - config.regmap = regmap; - config.of_node = i2c->dev.of_node; - config.init_data = &attiny_regulator_default; -+ config.driver_data = &state->lock; - - rdev = devm_regulator_register(&i2c->dev, &attiny_regulator, &config); - if (IS_ERR(rdev)) { - dev_err(&i2c->dev, "Failed to register ATTINY regulator\n"); -- return PTR_ERR(rdev); -+ ret = PTR_ERR(rdev); -+ goto error; - } - - props.type = BACKLIGHT_RAW; - props.max_brightness = 0xff; -+ -+ state->regmap = regmap; -+ - bl = devm_backlight_device_register(&i2c->dev, dev_name(&i2c->dev), -- &i2c->dev, regmap, &attiny_bl, -+ &i2c->dev, state, &attiny_bl, - &props); -- if (IS_ERR(bl)) -- return PTR_ERR(bl); -+ if (IS_ERR(bl)) { -+ ret = PTR_ERR(bl); -+ goto error; -+ } - - bl->props.brightness = 0xff; - - return 0; -+ -+error: -+ mutex_destroy(&state->lock); -+ -+ return ret; -+} -+ -+static int attiny_i2c_remove(struct i2c_client *client) -+{ -+ struct attiny_lcd *state = i2c_get_clientdata(client); -+ -+ mutex_destroy(&state->lock); -+ -+ return 0; - } - - static const struct of_device_id attiny_dt_ids[] = { -@@ -240,6 +308,7 @@ static struct i2c_driver attiny_regulato - .of_match_table = of_match_ptr(attiny_dt_ids), - }, - .probe = attiny_i2c_probe, -+ .remove = attiny_i2c_remove, - }; - - module_i2c_driver(attiny_regulator_driver); diff --git a/target/linux/bcm27xx/patches-5.15/950-0483-regulator-rpi-panel-Ensure-the-backlight-is-off-duri.patch b/target/linux/bcm27xx/patches-5.15/950-0483-regulator-rpi-panel-Ensure-the-backlight-is-off-duri.patch deleted file mode 100644 index 7932189de..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0483-regulator-rpi-panel-Ensure-the-backlight-is-off-duri.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 56a0f05720575f229fbbd996c0798aaf23464924 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Wed, 8 Sep 2021 15:41:18 +0100 -Subject: [PATCH] regulator: rpi-panel: Ensure the backlight is off - during probe. - -The initial state of the Atmel is not defined, so ensure the -backlight PWM is set to 0 by default. - -Signed-off-by: Dave Stevenson ---- - drivers/regulator/rpi-panel-attiny-regulator.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/regulator/rpi-panel-attiny-regulator.c -+++ b/drivers/regulator/rpi-panel-attiny-regulator.c -@@ -250,6 +250,7 @@ static int attiny_i2c_probe(struct i2c_c - - regmap_write(regmap, REG_POWERON, 0); - msleep(30); -+ regmap_write(regmap, REG_PWM, 0); - - config.dev = &i2c->dev; - config.regmap = regmap; diff --git a/target/linux/bcm27xx/patches-5.15/950-0484-regulator-rpi-panel-Convert-to-drive-lines-directly.patch b/target/linux/bcm27xx/patches-5.15/950-0484-regulator-rpi-panel-Convert-to-drive-lines-directly.patch deleted file mode 100644 index 04ac57823..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0484-regulator-rpi-panel-Convert-to-drive-lines-directly.patch +++ /dev/null @@ -1,199 +0,0 @@ -From 3cf717e1b077749001602a141dcdc2151e8307e1 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 9 Sep 2021 18:24:57 +0100 -Subject: [PATCH] regulator: rpi-panel: Convert to drive lines directly - -The Atmel was doing a load of automatic sequencing of -control lines, however it was combining the touch controller's -reset with the bridge/panel control. - -Change to control the control signals directly rather than -through the automatic POWERON control. - -Signed-off-by: Dave Stevenson ---- - .../regulator/rpi-panel-attiny-regulator.c | 111 ++++++++++-------- - 1 file changed, 60 insertions(+), 51 deletions(-) - ---- a/drivers/regulator/rpi-panel-attiny-regulator.c -+++ b/drivers/regulator/rpi-panel-attiny-regulator.c -@@ -21,11 +21,28 @@ - /* I2C registers of the Atmel microcontroller. */ - #define REG_ID 0x80 - #define REG_PORTA 0x81 --#define REG_PORTA_HF BIT(2) --#define REG_PORTA_VF BIT(3) - #define REG_PORTB 0x82 -+#define REG_PORTC 0x83 - #define REG_POWERON 0x85 - #define REG_PWM 0x86 -+#define REG_ADDR_L 0x8c -+#define REG_ADDR_H 0x8d -+#define REG_WRITE_DATA_H 0x90 -+#define REG_WRITE_DATA_L 0x91 -+ -+#define PA_LCD_DITHB BIT(0) -+#define PA_LCD_MODE BIT(1) -+#define PA_LCD_LR BIT(2) -+#define PA_LCD_UD BIT(3) -+ -+#define PB_BRIDGE_PWRDNX_N BIT(0) -+#define PB_LCD_VCC_N BIT(1) -+#define PB_LCD_MAIN BIT(7) -+ -+#define PC_LED_EN BIT(0) -+#define PC_RST_TP_N BIT(1) -+#define PC_RST_LCD_N BIT(2) -+#define PC_RST_BRIDGE_N BIT(3) - - struct attiny_lcd { - /* lock to serialise overall accesses to the Atmel */ -@@ -37,99 +54,91 @@ static const struct regmap_config attiny - .reg_bits = 8, - .val_bits = 8, - .disable_locking = 1, -- .max_register = REG_PWM, -+ .max_register = REG_WRITE_DATA_L, - .cache_type = REGCACHE_NONE, - }; - - static int attiny_lcd_power_enable(struct regulator_dev *rdev) - { -- struct mutex *lock = rdev_get_drvdata(rdev); -- unsigned int data; -- int ret, i; -+ struct attiny_lcd *state = rdev_get_drvdata(rdev); - -- mutex_lock(lock); -- -- regmap_write(rdev->regmap, REG_POWERON, 1); -- msleep(80); -+ mutex_lock(&state->lock); - -- /* Wait for nPWRDWN to go low to indicate poweron is done. */ -- for (i = 0; i < 20; i++) { -- ret = regmap_read(rdev->regmap, REG_PORTB, &data); -- if (!ret) { -- if (data & BIT(0)) -- break; -- } -- usleep_range(10000, 12000); -- } -- usleep_range(10000, 12000); -- -- if (ret) -- pr_err("%s: regmap_read_poll_timeout failed %d\n", __func__, ret); -+ /* Ensure bridge, and tp stay in reset */ -+ regmap_write(rdev->regmap, REG_PORTC, 0); -+ usleep_range(5000, 10000); - - /* Default to the same orientation as the closed source - * firmware used for the panel. Runtime rotation - * configuration will be supported using VC4's plane - * orientation bits. - */ -- regmap_write(rdev->regmap, REG_PORTA, BIT(2)); -+ regmap_write(rdev->regmap, REG_PORTA, PA_LCD_LR); -+ usleep_range(5000, 10000); -+ regmap_write(rdev->regmap, REG_PORTB, PB_LCD_MAIN); -+ usleep_range(5000, 10000); -+ /* Bring controllers out of reset */ -+ regmap_write(rdev->regmap, REG_PORTC, -+ PC_LED_EN | PC_RST_BRIDGE_N | PC_RST_LCD_N | PC_RST_TP_N); -+ -+ msleep(80); -+ -+ regmap_write(rdev->regmap, REG_ADDR_H, 0x04); -+ usleep_range(5000, 8000); -+ regmap_write(rdev->regmap, REG_ADDR_L, 0x7c); -+ usleep_range(5000, 8000); -+ regmap_write(rdev->regmap, REG_WRITE_DATA_H, 0x00); -+ usleep_range(5000, 8000); -+ regmap_write(rdev->regmap, REG_WRITE_DATA_L, 0x00); - -- mutex_unlock(lock); -+ msleep(100); -+ -+ mutex_unlock(&state->lock); - - return 0; - } - - static int attiny_lcd_power_disable(struct regulator_dev *rdev) - { -- struct mutex *lock = rdev_get_drvdata(rdev); -+ struct attiny_lcd *state = rdev_get_drvdata(rdev); - -- mutex_lock(lock); -+ mutex_lock(&state->lock); - - regmap_write(rdev->regmap, REG_PWM, 0); -- regmap_write(rdev->regmap, REG_POWERON, 0); -+ usleep_range(5000, 10000); -+ regmap_write(rdev->regmap, REG_PORTA, 0); -+ usleep_range(5000, 10000); -+ regmap_write(rdev->regmap, REG_PORTB, PB_LCD_VCC_N); -+ usleep_range(5000, 10000); -+ regmap_write(rdev->regmap, REG_PORTC, 0); - msleep(30); - -- mutex_unlock(lock); -+ mutex_unlock(&state->lock); - - return 0; - } - - static int attiny_lcd_power_is_enabled(struct regulator_dev *rdev) - { -- struct mutex *lock = rdev_get_drvdata(rdev); -+ struct attiny_lcd *state = rdev_get_drvdata(rdev); - unsigned int data; - int ret, i; - -- mutex_lock(lock); -- -- for (i = 0; i < 10; i++) { -- ret = regmap_read(rdev->regmap, REG_POWERON, &data); -- if (!ret) -- break; -- usleep_range(10000, 12000); -- } -- if (ret < 0) { -- mutex_unlock(lock); -- return ret; -- } -- -- if (!(data & BIT(0))) { -- mutex_unlock(lock); -- return 0; -- } -+ mutex_lock(&state->lock); - - for (i = 0; i < 10; i++) { -- ret = regmap_read(rdev->regmap, REG_PORTB, &data); -+ ret = regmap_read(rdev->regmap, REG_PORTC, &data); - if (!ret) - break; - usleep_range(10000, 12000); - } - -- mutex_unlock(lock); -+ mutex_unlock(&state->lock); - - if (ret < 0) - return ret; - -- return data & BIT(0); -+ return data & PC_RST_BRIDGE_N; - } - - static const struct regulator_init_data attiny_regulator_default = { -@@ -256,7 +265,7 @@ static int attiny_i2c_probe(struct i2c_c - config.regmap = regmap; - config.of_node = i2c->dev.of_node; - config.init_data = &attiny_regulator_default; -- config.driver_data = &state->lock; -+ config.driver_data = state; - - rdev = devm_regulator_register(&i2c->dev, &attiny_regulator, &config); - if (IS_ERR(rdev)) { diff --git a/target/linux/bcm27xx/patches-5.15/950-0485-regulator-rpi-panel-Add-GPIO-control-for-panel-and-t.patch b/target/linux/bcm27xx/patches-5.15/950-0485-regulator-rpi-panel-Add-GPIO-control-for-panel-and-t.patch deleted file mode 100644 index 5da00c14d..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0485-regulator-rpi-panel-Add-GPIO-control-for-panel-and-t.patch +++ /dev/null @@ -1,202 +0,0 @@ -From 6486bb50b96f359844b9c34f0978c69bbdcda140 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Fri, 10 Sep 2021 13:50:28 +0100 -Subject: [PATCH] regulator: rpi-panel: Add GPIO control for panel and - touch resets - -We need independent control of the resets for the panel&bridge, -vs the touch controller. - -Expose the reset lines that are on the Atmel's port C via the GPIO -API so that they can be controlled appropriately. - -Signed-off-by: Dave Stevenson ---- - .../regulator/rpi-panel-attiny-regulator.c | 115 +++++++++++++++--- - 1 file changed, 97 insertions(+), 18 deletions(-) - ---- a/drivers/regulator/rpi-panel-attiny-regulator.c -+++ b/drivers/regulator/rpi-panel-attiny-regulator.c -@@ -8,6 +8,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -44,10 +45,30 @@ - #define PC_RST_LCD_N BIT(2) - #define PC_RST_BRIDGE_N BIT(3) - -+enum gpio_signals { -+ RST_BRIDGE_N, /* TC358762 bridge reset */ -+ RST_TP_N, /* Touch controller reset */ -+ NUM_GPIO -+}; -+ -+struct gpio_signal_mappings { -+ unsigned int reg; -+ unsigned int mask; -+}; -+ -+static const struct gpio_signal_mappings mappings[NUM_GPIO] = { -+ [RST_BRIDGE_N] = { REG_PORTC, PC_RST_BRIDGE_N | PC_RST_LCD_N }, -+ [RST_TP_N] = { REG_PORTC, PC_RST_TP_N }, -+}; -+ - struct attiny_lcd { - /* lock to serialise overall accesses to the Atmel */ - struct mutex lock; - struct regmap *regmap; -+ bool gpio_states[NUM_GPIO]; -+ u8 port_states[3]; -+ -+ struct gpio_chip gc; - }; - - static const struct regmap_config attiny_regmap_config = { -@@ -58,6 +79,17 @@ static const struct regmap_config attiny - .cache_type = REGCACHE_NONE, - }; - -+static int attiny_set_port_state(struct attiny_lcd *state, int reg, u8 val) -+{ -+ state->port_states[reg - REG_PORTA] = val; -+ return regmap_write(state->regmap, reg, val); -+}; -+ -+static u8 attiny_get_port_state(struct attiny_lcd *state, int reg) -+{ -+ return state->port_states[reg - REG_PORTA]; -+}; -+ - static int attiny_lcd_power_enable(struct regulator_dev *rdev) - { - struct attiny_lcd *state = rdev_get_drvdata(rdev); -@@ -65,7 +97,7 @@ static int attiny_lcd_power_enable(struc - mutex_lock(&state->lock); - - /* Ensure bridge, and tp stay in reset */ -- regmap_write(rdev->regmap, REG_PORTC, 0); -+ attiny_set_port_state(state, REG_PORTC, 0); - usleep_range(5000, 10000); - - /* Default to the same orientation as the closed source -@@ -73,26 +105,16 @@ static int attiny_lcd_power_enable(struc - * configuration will be supported using VC4's plane - * orientation bits. - */ -- regmap_write(rdev->regmap, REG_PORTA, PA_LCD_LR); -+ attiny_set_port_state(state, REG_PORTA, PA_LCD_LR); - usleep_range(5000, 10000); -- regmap_write(rdev->regmap, REG_PORTB, PB_LCD_MAIN); -+ /* Main regulator on, and power to the panel (LCD_VCC_N) */ -+ attiny_set_port_state(state, REG_PORTB, PB_LCD_MAIN); - usleep_range(5000, 10000); - /* Bring controllers out of reset */ -- regmap_write(rdev->regmap, REG_PORTC, -- PC_LED_EN | PC_RST_BRIDGE_N | PC_RST_LCD_N | PC_RST_TP_N); -+ attiny_set_port_state(state, REG_PORTC, PC_LED_EN); - - msleep(80); - -- regmap_write(rdev->regmap, REG_ADDR_H, 0x04); -- usleep_range(5000, 8000); -- regmap_write(rdev->regmap, REG_ADDR_L, 0x7c); -- usleep_range(5000, 8000); -- regmap_write(rdev->regmap, REG_WRITE_DATA_H, 0x00); -- usleep_range(5000, 8000); -- regmap_write(rdev->regmap, REG_WRITE_DATA_L, 0x00); -- -- msleep(100); -- - mutex_unlock(&state->lock); - - return 0; -@@ -106,11 +128,12 @@ static int attiny_lcd_power_disable(stru - - regmap_write(rdev->regmap, REG_PWM, 0); - usleep_range(5000, 10000); -- regmap_write(rdev->regmap, REG_PORTA, 0); -+ -+ attiny_set_port_state(state, REG_PORTA, 0); - usleep_range(5000, 10000); -- regmap_write(rdev->regmap, REG_PORTB, PB_LCD_VCC_N); -+ attiny_set_port_state(state, REG_PORTB, PB_LCD_VCC_N); - usleep_range(5000, 10000); -- regmap_write(rdev->regmap, REG_PORTC, 0); -+ attiny_set_port_state(state, REG_PORTC, 0); - msleep(30); - - mutex_unlock(&state->lock); -@@ -211,6 +234,45 @@ static const struct backlight_ops attiny - .get_brightness = attiny_get_brightness, - }; - -+static int attiny_gpio_get_direction(struct gpio_chip *gc, unsigned int off) -+{ -+ return GPIO_LINE_DIRECTION_OUT; -+} -+ -+static void attiny_gpio_set(struct gpio_chip *gc, unsigned int off, int val) -+{ -+ struct attiny_lcd *state = gpiochip_get_data(gc); -+ u8 last_val; -+ -+ if (off >= NUM_GPIO) -+ return; -+ -+ mutex_lock(&state->lock); -+ -+ last_val = attiny_get_port_state(state, mappings[off].reg); -+ if (val) -+ last_val |= mappings[off].mask; -+ else -+ last_val &= ~mappings[off].mask; -+ -+ attiny_set_port_state(state, mappings[off].reg, last_val); -+ -+ if (off == RST_BRIDGE_N && val) { -+ usleep_range(5000, 8000); -+ regmap_write(state->regmap, REG_ADDR_H, 0x04); -+ usleep_range(5000, 8000); -+ regmap_write(state->regmap, REG_ADDR_L, 0x7c); -+ usleep_range(5000, 8000); -+ regmap_write(state->regmap, REG_WRITE_DATA_H, 0x00); -+ usleep_range(5000, 8000); -+ regmap_write(state->regmap, REG_WRITE_DATA_L, 0x00); -+ -+ msleep(100); -+ } -+ -+ mutex_unlock(&state->lock); -+} -+ - /* - * I2C driver interface functions - */ -@@ -289,6 +351,23 @@ static int attiny_i2c_probe(struct i2c_c - - bl->props.brightness = 0xff; - -+ state->gc.parent = &i2c->dev; -+ state->gc.label = i2c->name; -+ state->gc.owner = THIS_MODULE; -+ state->gc.of_node = i2c->dev.of_node; -+ state->gc.base = -1; -+ state->gc.ngpio = NUM_GPIO; -+ -+ state->gc.set = attiny_gpio_set; -+ state->gc.get_direction = attiny_gpio_get_direction; -+ state->gc.can_sleep = true; -+ -+ ret = devm_gpiochip_add_data(&i2c->dev, &state->gc, state); -+ if (ret) { -+ dev_err(&i2c->dev, "Failed to create gpiochip: %d\n", ret); -+ goto error; -+ } -+ - return 0; - - error: diff --git a/target/linux/bcm27xx/patches-5.15/950-0486-staging-bcm2835-codec-Change-the-default-codec-res-t.patch b/target/linux/bcm27xx/patches-5.15/950-0486-staging-bcm2835-codec-Change-the-default-codec-res-t.patch deleted file mode 100644 index 52754e201..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0486-staging-bcm2835-codec-Change-the-default-codec-res-t.patch +++ /dev/null @@ -1,40 +0,0 @@ -From ac2682411d03cf2951abf2856aeaf10206e700fc Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 13 May 2021 11:56:21 +0100 -Subject: [PATCH] staging/bcm2835-codec: Change the default codec res - to 32x32 - -In order to effectively guarantee that a V4L2_EVENT_SOURCE_CHANGE -event occurs, adopt a default resolution of 32x32 so that it -is incredibly unlikely to be decoding a stream of that resolution -and therefore failing to note a "change" requiring the event. - -Signed-off-by: Dave Stevenson ---- - .../bcm2835-codec/bcm2835-v4l2-codec.c | 15 +++++++++++++-- - 1 file changed, 13 insertions(+), 2 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -97,8 +97,19 @@ static const char * const components[] = - #define MAX_W 1920 - #define MAX_H 1920 - #define BPL_ALIGN 32 --#define DEFAULT_WIDTH 640 --#define DEFAULT_HEIGHT 480 -+/* -+ * The decoder spec supports the V4L2_EVENT_SOURCE_CHANGE event, but the docs -+ * seem to want it to always be generated on startup, which prevents the client -+ * from configuring the CAPTURE queue based on any parsing it has already done -+ * which may save time and allow allocation of CAPTURE buffers early. Surely -+ * SOURCE_CHANGE means something has changed, not just "always notify". -+ * -+ * For those clients that don't set the CAPTURE resolution, adopt a default -+ * resolution that is seriously unlikely to be correct, therefore almost -+ * guaranteed to get the SOURCE_CHANGE event. -+ */ -+#define DEFAULT_WIDTH 32 -+#define DEFAULT_HEIGHT 32 - /* - * The unanswered question - what is the maximum size of a compressed frame? - * V4L2 mandates that the encoded frame must fit in a single buffer. Sizing diff --git a/target/linux/bcm27xx/patches-5.15/950-0489-staging-bcm2835-codec-Add-support-for-decoding-inter.patch b/target/linux/bcm27xx/patches-5.15/950-0489-staging-bcm2835-codec-Add-support-for-decoding-inter.patch deleted file mode 100644 index 7d5162d4f..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0489-staging-bcm2835-codec-Add-support-for-decoding-inter.patch +++ /dev/null @@ -1,173 +0,0 @@ -From 6c7a2caf88dda1aa4459b80d399da37dff6c6942 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Fri, 18 Dec 2020 19:56:31 +0000 -Subject: [PATCH] staging/bcm2835-codec: Add support for decoding - interlaced streams - -The video decoder can support decoding interlaced streams, so add -the required plumbing to signal this correctly. - -The encoder and ISP do NOT support interlaced data, so trying to -configure an interlaced format on those nodes will be rejected. - -Signed-off-by: Dave Stevenson ---- - .../bcm2835-codec/bcm2835-v4l2-codec.c | 84 +++++++++++++++++-- - 1 file changed, 77 insertions(+), 7 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -619,6 +619,7 @@ struct bcm2835_codec_q_data { - unsigned int crop_height; - bool selection_set; - struct v4l2_fract aspect_ratio; -+ enum v4l2_field field; - - unsigned int sizeimage; - unsigned int sequence; -@@ -986,6 +987,10 @@ static void handle_fmt_changed(struct bc - struct bcm2835_codec_q_data *q_data; - struct mmal_msg_event_format_changed *format = - (struct mmal_msg_event_format_changed *)mmal_buf->buffer; -+ struct mmal_parameter_video_interlace_type interlace; -+ int interlace_size = sizeof(interlace); -+ int ret; -+ - v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: Format changed: buff size min %u, rec %u, buff num min %u, rec %u\n", - __func__, - format->buffer_size_min, -@@ -1029,6 +1034,30 @@ static void handle_fmt_changed(struct bc - q_data->aspect_ratio.numerator = format->es.video.par.num; - q_data->aspect_ratio.denominator = format->es.video.par.den; - -+ ret = vchiq_mmal_port_parameter_get(ctx->dev->instance, -+ &ctx->component->output[0], -+ MMAL_PARAMETER_VIDEO_INTERLACE_TYPE, -+ &interlace, -+ &interlace_size); -+ if (!ret) { -+ switch (interlace.mode) { -+ case MMAL_INTERLACE_PROGRESSIVE: -+ default: -+ q_data->field = V4L2_FIELD_NONE; -+ break; -+ case MMAL_INTERLACE_FIELDS_INTERLEAVED_UPPER_FIRST: -+ q_data->field = V4L2_FIELD_INTERLACED_TB; -+ break; -+ case MMAL_INTERLACE_FIELDS_INTERLEAVED_LOWER_FIRST: -+ q_data->field = V4L2_FIELD_INTERLACED_BT; -+ break; -+ } -+ v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: interlace mode %u, v4l2 field %u\n", -+ __func__, interlace.mode, q_data->field); -+ } else { -+ q_data->field = V4L2_FIELD_NONE; -+ } -+ - queue_res_chg_event(ctx); - } - -@@ -1101,6 +1130,22 @@ static void op_buffer_cb(struct vchiq_mm - vb2->vb2_buf.timestamp = mmal_buf->pts * 1000; - - vb2_set_plane_payload(&vb2->vb2_buf, 0, mmal_buf->length); -+ switch (mmal_buf->mmal_flags & -+ (MMAL_BUFFER_HEADER_VIDEO_FLAG_INTERLACED | -+ MMAL_BUFFER_HEADER_VIDEO_FLAG_TOP_FIELD_FIRST)) { -+ case 0: -+ case MMAL_BUFFER_HEADER_VIDEO_FLAG_TOP_FIELD_FIRST: /* Bogus */ -+ vb2->field = V4L2_FIELD_NONE; -+ break; -+ case MMAL_BUFFER_HEADER_VIDEO_FLAG_INTERLACED: -+ vb2->field = V4L2_FIELD_INTERLACED_BT; -+ break; -+ case (MMAL_BUFFER_HEADER_VIDEO_FLAG_INTERLACED | -+ MMAL_BUFFER_HEADER_VIDEO_FLAG_TOP_FIELD_FIRST): -+ vb2->field = V4L2_FIELD_INTERLACED_TB; -+ break; -+ } -+ - if (mmal_buf->mmal_flags & MMAL_BUFFER_HEADER_FLAG_KEYFRAME) - vb2->flags |= V4L2_BUF_FLAG_KEYFRAME; - -@@ -1272,7 +1317,7 @@ static int vidioc_g_fmt(struct bcm2835_c - f->fmt.pix_mp.width = q_data->crop_width; - f->fmt.pix_mp.height = q_data->height; - f->fmt.pix_mp.pixelformat = q_data->fmt->fourcc; -- f->fmt.pix_mp.field = V4L2_FIELD_NONE; -+ f->fmt.pix_mp.field = q_data->field; - f->fmt.pix_mp.colorspace = ctx->colorspace; - f->fmt.pix_mp.plane_fmt[0].sizeimage = q_data->sizeimage; - f->fmt.pix_mp.plane_fmt[0].bytesperline = q_data->bytesperline; -@@ -1347,7 +1392,33 @@ static int vidioc_try_fmt(struct bcm2835 - memset(f->fmt.pix_mp.plane_fmt[0].reserved, 0, - sizeof(f->fmt.pix_mp.plane_fmt[0].reserved)); - -- f->fmt.pix_mp.field = V4L2_FIELD_NONE; -+ if (ctx->dev->role == DECODE) { -+ switch (f->fmt.pix_mp.field) { -+ /* -+ * All of this is pretty much guesswork as we'll set the -+ * interlace format correctly come format changed, and signal -+ * it appropriately on each buffer. -+ */ -+ default: -+ case V4L2_FIELD_NONE: -+ case V4L2_FIELD_ANY: -+ f->fmt.pix_mp.field = V4L2_FIELD_NONE; -+ break; -+ case V4L2_FIELD_INTERLACED: -+ f->fmt.pix_mp.field = V4L2_FIELD_INTERLACED; -+ break; -+ case V4L2_FIELD_TOP: -+ case V4L2_FIELD_BOTTOM: -+ case V4L2_FIELD_INTERLACED_TB: -+ f->fmt.pix_mp.field = V4L2_FIELD_INTERLACED_TB; -+ break; -+ case V4L2_FIELD_INTERLACED_BT: -+ f->fmt.pix_mp.field = V4L2_FIELD_INTERLACED_BT; -+ break; -+ } -+ } else { -+ f->fmt.pix_mp.field = V4L2_FIELD_NONE; -+ } - - return 0; - } -@@ -1430,6 +1501,8 @@ static int vidioc_s_fmt(struct bcm2835_c - ctx->ycbcr_enc = f->fmt.pix_mp.ycbcr_enc; - ctx->quant = f->fmt.pix_mp.quantization; - -+ q_data->field = f->fmt.pix_mp.field; -+ - /* All parameters should have been set correctly by try_fmt */ - q_data->bytesperline = f->fmt.pix_mp.plane_fmt[0].bytesperline; - q_data->sizeimage = f->fmt.pix_mp.plane_fmt[0].sizeimage; -@@ -2429,11 +2502,6 @@ static int bcm2835_codec_buf_prepare(str - 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) { -- v4l2_err(&ctx->dev->v4l2_dev, "%s field isn't supported\n", -- __func__); -- return -EINVAL; -- } - } - - if (vb2_plane_size(vb, 0) < q_data->sizeimage) { -@@ -2735,6 +2803,7 @@ static int bcm2835_codec_open(struct fil - ctx->q_data[V4L2_M2M_SRC].crop_width, - ctx->q_data[V4L2_M2M_SRC].height, - ctx->q_data[V4L2_M2M_SRC].fmt); -+ ctx->q_data[V4L2_M2M_SRC].field = V4L2_FIELD_NONE; - - ctx->q_data[V4L2_M2M_DST].crop_width = DEFAULT_WIDTH; - ctx->q_data[V4L2_M2M_DST].crop_height = DEFAULT_HEIGHT; -@@ -2749,6 +2818,7 @@ static int bcm2835_codec_open(struct fil - ctx->q_data[V4L2_M2M_DST].fmt); - ctx->q_data[V4L2_M2M_DST].aspect_ratio.numerator = 1; - ctx->q_data[V4L2_M2M_DST].aspect_ratio.denominator = 1; -+ ctx->q_data[V4L2_M2M_DST].field = V4L2_FIELD_NONE; - - ctx->colorspace = V4L2_COLORSPACE_REC709; - ctx->bitrate = 10 * 1000 * 1000; diff --git a/target/linux/bcm27xx/patches-5.15/950-0490-staging-bcm2835-codec-Correct-ENUM_FRAMESIZES-stepsi.patch b/target/linux/bcm27xx/patches-5.15/950-0490-staging-bcm2835-codec-Correct-ENUM_FRAMESIZES-stepsi.patch deleted file mode 100644 index 4d74cd62c..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0490-staging-bcm2835-codec-Correct-ENUM_FRAMESIZES-stepsi.patch +++ /dev/null @@ -1,29 +0,0 @@ -From c1c9a3f124f3273fc076651f3f89d1746d5bee77 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 5 Aug 2021 15:11:23 +0100 -Subject: [PATCH] staging/bcm2835-codec: Correct ENUM_FRAMESIZES - stepsize to 2 - -Being YUV420 formats, the step size is always 2 to avoid part -chroma subsampling. - -Signed-off-by: Dave Stevenson ---- - .../staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -2222,10 +2222,10 @@ static int vidioc_enum_framesizes(struct - - fsize->stepwise.min_width = MIN_W; - fsize->stepwise.max_width = MAX_W; -- fsize->stepwise.step_width = 1; -+ fsize->stepwise.step_width = 2; - fsize->stepwise.min_height = MIN_H; - fsize->stepwise.max_height = MAX_H; -- fsize->stepwise.step_height = 1; -+ fsize->stepwise.step_height = 2; - - return 0; - } diff --git a/target/linux/bcm27xx/patches-5.15/950-0491-staging-bcm2835-codec-Return-buffers-to-QUEUED-not-E.patch b/target/linux/bcm27xx/patches-5.15/950-0491-staging-bcm2835-codec-Return-buffers-to-QUEUED-not-E.patch deleted file mode 100644 index f33f60335..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0491-staging-bcm2835-codec-Return-buffers-to-QUEUED-not-E.patch +++ /dev/null @@ -1,35 +0,0 @@ -From a07df18f2992baca3fa9d6a16ae93b585786c5d4 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 5 Aug 2021 16:46:42 +0100 -Subject: [PATCH] staging/bcm2835-codec: Return buffers to QUEUED not - ERROR state - -Should start_streaming fail, or buffers be queued during -stop_streaming, they should be returned to the core as QUEUED -and not (as currently) as ERROR. - -Signed-off-by: Dave Stevenson ---- - .../staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -1111,7 +1111,7 @@ static void op_buffer_cb(struct vchiq_mm - v4l2_dbg(2, debug, &ctx->dev->v4l2_dev, "%s: Empty buffer - flags %04x", - __func__, mmal_buf->mmal_flags); - if (!(mmal_buf->mmal_flags & MMAL_BUFFER_HEADER_FLAG_EOS)) { -- vb2_buffer_done(&vb2->vb2_buf, VB2_BUF_STATE_ERROR); -+ vb2_buffer_done(&vb2->vb2_buf, VB2_BUF_STATE_QUEUED); - if (!port->enabled) - complete(&ctx->frame_cmplt); - return; -@@ -2683,7 +2683,7 @@ static void bcm2835_codec_stop_streaming - v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: return buffer %p\n", - __func__, vbuf); - -- v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR); -+ v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_QUEUED); - } - - /* Disable MMAL port - this will flush buffers back */ diff --git a/target/linux/bcm27xx/patches-5.15/950-0492-staging-bcm2835_codec-Log-MMAL-flags-in-hex.patch b/target/linux/bcm27xx/patches-5.15/950-0492-staging-bcm2835_codec-Log-MMAL-flags-in-hex.patch deleted file mode 100644 index 7bdfc399a..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0492-staging-bcm2835_codec-Log-MMAL-flags-in-hex.patch +++ /dev/null @@ -1,24 +0,0 @@ -From dbc825d8cf0435da46532cfbc7199768abc32b4c Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Fri, 6 Aug 2021 13:43:48 +0100 -Subject: [PATCH] staging/bcm2835_codec: Log MMAL flags in hex - -The flags is a bitmask, so it's far easier to interpret as hex -data instead of decimal. - -Signed-off-by: Dave Stevenson ---- - .../staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -1071,7 +1071,7 @@ static void op_buffer_cb(struct vchiq_mm - struct vb2_v4l2_buffer *vb2; - - v4l2_dbg(2, debug, &ctx->dev->v4l2_dev, -- "%s: status:%d, buf:%p, length:%lu, flags %u, pts %lld\n", -+ "%s: status:%d, buf:%p, length:%lu, flags %04x, pts %lld\n", - __func__, status, mmal_buf, mmal_buf->length, - mmal_buf->mmal_flags, mmal_buf->pts); - diff --git a/target/linux/bcm27xx/patches-5.15/950-0493-staging-bcm2835-codec-Allow-custom-specified-strides.patch b/target/linux/bcm27xx/patches-5.15/950-0493-staging-bcm2835-codec-Allow-custom-specified-strides.patch deleted file mode 100644 index e262d61b8..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0493-staging-bcm2835-codec-Allow-custom-specified-strides.patch +++ /dev/null @@ -1,39 +0,0 @@ -From f4d34546637944b30ef09e96aa84802d7d69e72c Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Sat, 11 Sep 2021 17:21:07 +0100 -Subject: [PATCH] staging: bcm2835-codec: Allow custom specified - strides/bytesperline. - -If the client provides a bytesperline value in try_fmt/s_fmt then -validate it and correct if necessary. - -Signed-off-by: Dave Stevenson ---- - .../vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c | 8 ++++++-- - 1 file changed, 6 insertions(+), 2 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -1347,7 +1347,7 @@ static int vidioc_g_fmt_vid_cap(struct f - static int vidioc_try_fmt(struct bcm2835_codec_ctx *ctx, struct v4l2_format *f, - struct bcm2835_codec_fmt *fmt) - { -- unsigned int sizeimage; -+ unsigned int sizeimage, min_bytesperline; - - /* - * The V4L2 specification requires the driver to correct the format -@@ -1375,8 +1375,12 @@ static int vidioc_try_fmt(struct bcm2835 - f->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, 16); - } - f->fmt.pix_mp.num_planes = 1; -+ min_bytesperline = get_bytesperline(f->fmt.pix_mp.width, fmt); -+ if (f->fmt.pix_mp.plane_fmt[0].bytesperline < min_bytesperline) -+ f->fmt.pix_mp.plane_fmt[0].bytesperline = min_bytesperline; - f->fmt.pix_mp.plane_fmt[0].bytesperline = -- get_bytesperline(f->fmt.pix_mp.width, fmt); -+ ALIGN(f->fmt.pix_mp.plane_fmt[0].bytesperline, fmt->bytesperline_align); -+ - sizeimage = get_sizeimage(f->fmt.pix_mp.plane_fmt[0].bytesperline, - f->fmt.pix_mp.width, f->fmt.pix_mp.height, - fmt); diff --git a/target/linux/bcm27xx/patches-5.15/950-0495-staging-bcm2835_codec-Add-support-for-image_fx-to-de.patch b/target/linux/bcm27xx/patches-5.15/950-0495-staging-bcm2835_codec-Add-support-for-image_fx-to-de.patch deleted file mode 100644 index 1823d6269..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0495-staging-bcm2835_codec-Add-support-for-image_fx-to-de.patch +++ /dev/null @@ -1,267 +0,0 @@ -From 3fbd7957bae36bbafb54dc7bf1624b158fa2a984 Mon Sep 17 00:00:00 2001 -From: Dom Cobley -Date: Fri, 6 Aug 2021 15:37:16 +0100 -Subject: [PATCH] staging/bcm2835_codec: Add support for image_fx to - deinterlace - -Adds another /dev/video node wrapping image_fx doing deinterlace. - -Co-developed-by: Dave Stevenson -Signed-off-by: Dom Cobley ---- - .../bcm2835-codec/bcm2835-v4l2-codec.c | 152 +++++++++++++++++- - 1 file changed, 150 insertions(+), 2 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -58,6 +58,10 @@ static int isp_video_nr = 12; - module_param(isp_video_nr, int, 0644); - MODULE_PARM_DESC(isp_video_nr, "isp video device number"); - -+static int deinterlace_video_nr = 18; -+module_param(deinterlace_video_nr, int, 0644); -+MODULE_PARM_DESC(deinterlace_video_nr, "deinterlace video device number"); -+ - /* - * Workaround for GStreamer v4l2convert component not considering Bayer formats - * as raw, and therefore not considering a V4L2 device that supports them as -@@ -71,22 +75,33 @@ static unsigned int debug; - module_param(debug, uint, 0644); - MODULE_PARM_DESC(debug, "activates debug info (0-3)"); - -+static bool advanced_deinterlace = true; -+module_param(advanced_deinterlace, bool, 0644); -+MODULE_PARM_DESC(advanced_deinterlace, "Use advanced deinterlace"); -+ -+static int field_override; -+module_param(field_override, int, 0644); -+MODULE_PARM_DESC(field_override, "force TB(8)/BT(9) field"); -+ - enum bcm2835_codec_role { - DECODE, - ENCODE, - ISP, -+ DEINTERLACE, - }; - - static const char * const roles[] = { - "decode", - "encode", -- "isp" -+ "isp", -+ "image_fx", - }; - - static const char * const components[] = { - "ril.video_decode", - "ril.video_encode", - "ril.isp", -+ "ril.image_fx", - }; - - /* Timeout for stop_streaming to allow all buffers to return */ -@@ -683,6 +698,7 @@ struct bcm2835_codec_driver { - struct bcm2835_codec_dev *encode; - struct bcm2835_codec_dev *decode; - struct bcm2835_codec_dev *isp; -+ struct bcm2835_codec_dev *deinterlace; - }; - - enum { -@@ -1196,6 +1212,19 @@ static void vb2_to_mmal_buffer(struct m2 - do_div(pts, 1000); - buf->mmal.pts = pts; - buf->mmal.dts = MMAL_TIME_UNKNOWN; -+ -+ switch (field_override ? field_override : vb2->field) { -+ default: -+ case V4L2_FIELD_NONE: -+ break; -+ case V4L2_FIELD_INTERLACED_BT: -+ buf->mmal.mmal_flags |= MMAL_BUFFER_HEADER_VIDEO_FLAG_INTERLACED; -+ break; -+ case V4L2_FIELD_INTERLACED_TB: -+ buf->mmal.mmal_flags |= MMAL_BUFFER_HEADER_VIDEO_FLAG_INTERLACED | -+ MMAL_BUFFER_HEADER_VIDEO_FLAG_TOP_FIELD_FIRST; -+ break; -+ } - } - - /* device_run() - prepares and starts the device -@@ -1396,7 +1425,7 @@ static int vidioc_try_fmt(struct bcm2835 - memset(f->fmt.pix_mp.plane_fmt[0].reserved, 0, - sizeof(f->fmt.pix_mp.plane_fmt[0].reserved)); - -- if (ctx->dev->role == DECODE) { -+ if (ctx->dev->role == DECODE || ctx->dev->role == DEINTERLACE) { - switch (f->fmt.pix_mp.field) { - /* - * All of this is pretty much guesswork as we'll set the -@@ -1686,6 +1715,46 @@ static int vidioc_g_selection(struct fil - break; - case ISP: - break; -+ case DEINTERLACE: -+ if (s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { -+ switch (s->target) { -+ case V4L2_SEL_TGT_COMPOSE_DEFAULT: -+ case V4L2_SEL_TGT_COMPOSE: -+ s->r.left = 0; -+ s->r.top = 0; -+ s->r.width = q_data->crop_width; -+ s->r.height = q_data->crop_height; -+ break; -+ case V4L2_SEL_TGT_COMPOSE_BOUNDS: -+ s->r.left = 0; -+ s->r.top = 0; -+ s->r.width = q_data->crop_width; -+ s->r.height = q_data->crop_height; -+ break; -+ default: -+ return -EINVAL; -+ } -+ } else { -+ /* must be V4L2_BUF_TYPE_VIDEO_OUTPUT */ -+ switch (s->target) { -+ case V4L2_SEL_TGT_CROP_DEFAULT: -+ case V4L2_SEL_TGT_CROP_BOUNDS: -+ s->r.top = 0; -+ s->r.left = 0; -+ s->r.width = q_data->bytesperline; -+ s->r.height = q_data->height; -+ break; -+ case V4L2_SEL_TGT_CROP: -+ s->r.top = 0; -+ s->r.left = 0; -+ s->r.width = q_data->crop_width; -+ s->r.height = q_data->crop_height; -+ break; -+ default: -+ return -EINVAL; -+ } -+ } -+ break; - } - - return 0; -@@ -1761,6 +1830,41 @@ static int vidioc_s_selection(struct fil - break; - case ISP: - break; -+ case DEINTERLACE: -+ if (s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { -+ switch (s->target) { -+ case V4L2_SEL_TGT_COMPOSE: -+ /* Accept cropped image */ -+ s->r.left = 0; -+ s->r.top = 0; -+ s->r.width = min(s->r.width, q_data->crop_width); -+ s->r.height = min(s->r.height, q_data->height); -+ q_data->crop_width = s->r.width; -+ q_data->crop_height = s->r.height; -+ q_data->selection_set = true; -+ break; -+ default: -+ return -EINVAL; -+ } -+ break; -+ } else { -+ /* must be V4L2_BUF_TYPE_VIDEO_OUTPUT */ -+ switch (s->target) { -+ case V4L2_SEL_TGT_CROP: -+ /* Only support crop from (0,0) */ -+ s->r.top = 0; -+ s->r.left = 0; -+ s->r.width = min(s->r.width, q_data->crop_width); -+ s->r.height = min(s->r.height, q_data->height); -+ q_data->crop_width = s->r.width; -+ q_data->crop_height = s->r.height; -+ q_data->selection_set = true; -+ break; -+ default: -+ return -EINVAL; -+ } -+ break; -+ } - } - - return 0; -@@ -2335,6 +2439,30 @@ static int bcm2835_codec_create_componen - MMAL_PARAMETER_VIDEO_VALIDATE_TIMESTAMPS, - &enable, - sizeof(enable)); -+ } else if (dev->role == DEINTERLACE) { -+ /* Select the default deinterlace algorithm. */ -+ int half_framerate = 0; -+ int default_frame_interval = -1; /* don't interpolate */ -+ int frame_type = 5; /* 0=progressive, 3=TFF, 4=BFF, 5=see frame */ -+ int use_qpus = 0; -+ enum mmal_parameter_imagefx effect = -+ advanced_deinterlace && ctx->q_data[V4L2_M2M_SRC].crop_width <= 800 ? -+ MMAL_PARAM_IMAGEFX_DEINTERLACE_ADV : -+ MMAL_PARAM_IMAGEFX_DEINTERLACE_FAST; -+ struct mmal_parameter_imagefx_parameters params = { -+ .effect = effect, -+ .num_effect_params = 4, -+ .effect_parameter = { frame_type, -+ default_frame_interval, -+ half_framerate, -+ use_qpus }, -+ }; -+ -+ vchiq_mmal_port_parameter_set(dev->instance, -+ &ctx->component->output[0], -+ MMAL_PARAMETER_IMAGE_EFFECT_PARAMETERS, -+ ¶ms, -+ sizeof(params)); - } - - setup_mmal_port_format(ctx, &ctx->q_data[V4L2_M2M_SRC], -@@ -3173,6 +3301,16 @@ static int bcm2835_codec_create(struct b - function = MEDIA_ENT_F_PROC_VIDEO_SCALER; - video_nr = isp_video_nr; - break; -+ case DEINTERLACE: -+ v4l2_disable_ioctl(vfd, VIDIOC_ENCODER_CMD); -+ v4l2_disable_ioctl(vfd, VIDIOC_TRY_ENCODER_CMD); -+ v4l2_disable_ioctl(vfd, VIDIOC_DECODER_CMD); -+ v4l2_disable_ioctl(vfd, VIDIOC_TRY_DECODER_CMD); -+ v4l2_disable_ioctl(vfd, VIDIOC_S_PARM); -+ v4l2_disable_ioctl(vfd, VIDIOC_G_PARM); -+ function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER; -+ video_nr = deinterlace_video_nr; -+ break; - default: - ret = -EINVAL; - goto unreg_dev; -@@ -3268,6 +3406,10 @@ static int bcm2835_codec_probe(struct pl - if (ret) - goto out; - -+ ret = bcm2835_codec_create(drv, &drv->deinterlace, DEINTERLACE); -+ if (ret) -+ goto out; -+ - /* Register the media device node */ - if (media_device_register(mdev) < 0) - goto out; -@@ -3277,6 +3419,10 @@ static int bcm2835_codec_probe(struct pl - return 0; - - out: -+ if (drv->deinterlace) { -+ bcm2835_codec_destroy(drv->deinterlace); -+ drv->deinterlace = NULL; -+ } - if (drv->isp) { - bcm2835_codec_destroy(drv->isp); - drv->isp = NULL; -@@ -3298,6 +3444,8 @@ static int bcm2835_codec_remove(struct p - - media_device_unregister(&drv->mdev); - -+ bcm2835_codec_destroy(drv->deinterlace); -+ - bcm2835_codec_destroy(drv->isp); - - bcm2835_codec_destroy(drv->encode); diff --git a/target/linux/bcm27xx/patches-5.15/950-0496-staging-bcm2835-v4l2_codec-Fix-for-encode-selection-.patch b/target/linux/bcm27xx/patches-5.15/950-0496-staging-bcm2835-v4l2_codec-Fix-for-encode-selection-.patch deleted file mode 100644 index 57b4f302c..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0496-staging-bcm2835-v4l2_codec-Fix-for-encode-selection-.patch +++ /dev/null @@ -1,24 +0,0 @@ -From a9bf65dcc609ee839a705e7301a3846ae09c75d0 Mon Sep 17 00:00:00 2001 -From: Dom Cobley -Date: Tue, 14 Sep 2021 16:44:18 +0100 -Subject: [PATCH] staging/bcm2835-v4l2_codec: Fix for encode selection - API - -Matches correct behaviour from DECODE and DEINTERLACE - -Signed-off-by: Dom Cobley ---- - .../staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -1819,7 +1819,7 @@ static int vidioc_s_selection(struct fil - s->r.top = 0; - s->r.left = 0; - s->r.width = min(s->r.width, q_data->crop_width); -- s->r.height = min(s->r.height, q_data->crop_height); -+ s->r.height = min(s->r.height, q_data->height); - q_data->crop_width = s->r.width; - q_data->crop_height = s->r.height; - q_data->selection_set = true; diff --git a/target/linux/bcm27xx/patches-5.15/950-0498-ARM-dts-Restore-downstream-dtbs-to-Makefile.patch b/target/linux/bcm27xx/patches-5.15/950-0498-ARM-dts-Restore-downstream-dtbs-to-Makefile.patch deleted file mode 100644 index 19d41f1a6..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0498-ARM-dts-Restore-downstream-dtbs-to-Makefile.patch +++ /dev/null @@ -1,31 +0,0 @@ -From f7cca3c1a3c3e710849603d296c5c90270784055 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 22 Sep 2021 09:16:46 +0100 -Subject: [PATCH] ARM: dts: Restore downstream dtbs to Makefile - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/Makefile | 10 ++++++++++ - 1 file changed, 10 insertions(+) - ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -1,8 +1,18 @@ - # SPDX-License-Identifier: GPL-2.0 - - dtb-$(CONFIG_ARCH_BCM2835) += \ -+ bcm2708-rpi-b.dtb \ - bcm2708-rpi-b-rev1.dtb \ -+ bcm2708-rpi-b-plus.dtb \ - bcm2708-rpi-cm.dtb \ -+ bcm2708-rpi-zero.dtb \ -+ bcm2708-rpi-zero-w.dtb \ -+ bcm2709-rpi-2-b.dtb \ -+ bcm2710-rpi-2-b.dtb \ -+ bcm2710-rpi-3-b.dtb \ -+ bcm2710-rpi-3-b-plus.dtb \ -+ bcm2711-rpi-4-b.dtb \ -+ bcm2711-rpi-400.dtb \ - bcm2710-rpi-cm3.dtb \ - bcm2711-rpi-cm4.dtb - diff --git a/target/linux/bcm27xx/patches-5.15/950-0499-media-rpivid-Avoid-returning-EINVAL-to-a-G_FMT-ioctl.patch b/target/linux/bcm27xx/patches-5.15/950-0499-media-rpivid-Avoid-returning-EINVAL-to-a-G_FMT-ioctl.patch deleted file mode 100644 index acfc07732..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0499-media-rpivid-Avoid-returning-EINVAL-to-a-G_FMT-ioctl.patch +++ /dev/null @@ -1,277 +0,0 @@ -From 7580dc7daa2ac363c20674545be200802e4f6dce Mon Sep 17 00:00:00 2001 -From: John Cox -Date: Wed, 1 Sep 2021 16:34:50 +0100 -Subject: [PATCH] media: rpivid: Avoid returning EINVAL to a G_FMT - ioctl - -V4L2 spec says that G/S/TRY_FMT IOCTLs should never return errors for -anything other than wrong buffer types. Improve the capture format -function such that this is so and unsupported values get converted -to supported ones properly. - -Signed-off-by: John Cox ---- - drivers/staging/media/rpivid/rpivid.c | 1 - - drivers/staging/media/rpivid/rpivid.h | 2 - - drivers/staging/media/rpivid/rpivid_video.c | 99 +++++++++++---------- - drivers/staging/media/rpivid/rpivid_video.h | 3 +- - 4 files changed, 54 insertions(+), 51 deletions(-) - ---- a/drivers/staging/media/rpivid/rpivid.c -+++ b/drivers/staging/media/rpivid/rpivid.c -@@ -249,7 +249,6 @@ static int rpivid_open(struct file *file - /* The only bit of format info that we can guess now is H265 src - * Everything else we need more info for - */ -- ctx->src_fmt.pixelformat = RPIVID_SRC_PIXELFORMAT_DEFAULT; - rpivid_prepare_src_format(&ctx->src_fmt); - - v4l2_fh_add(&ctx->fh); ---- a/drivers/staging/media/rpivid/rpivid.h -+++ b/drivers/staging/media/rpivid/rpivid.h -@@ -35,8 +35,6 @@ - - #define RPIVID_QUIRK_NO_DMA_OFFSET BIT(0) - --#define RPIVID_SRC_PIXELFORMAT_DEFAULT V4L2_PIX_FMT_HEVC_SLICE -- - enum rpivid_irq_status { - RPIVID_IRQ_NONE, - RPIVID_IRQ_ERROR, ---- a/drivers/staging/media/rpivid/rpivid_video.c -+++ b/drivers/staging/media/rpivid/rpivid_video.c -@@ -27,6 +27,8 @@ - - #define RPIVID_MIN_WIDTH 16U - #define RPIVID_MIN_HEIGHT 16U -+#define RPIVID_DEFAULT_WIDTH 1920U -+#define RPIVID_DEFAULT_HEIGHT 1088U - #define RPIVID_MAX_WIDTH 4096U - #define RPIVID_MAX_HEIGHT 4096U - -@@ -70,25 +72,22 @@ size_t rpivid_bit_buf_size(unsigned int - return rpivid_round_up_size(bits_alloc); - } - --int rpivid_prepare_src_format(struct v4l2_pix_format_mplane *pix_fmt) -+void rpivid_prepare_src_format(struct v4l2_pix_format_mplane *pix_fmt) - { - size_t size; - u32 w; - u32 h; - -- if (pix_fmt->pixelformat != V4L2_PIX_FMT_HEVC_SLICE) -- return -EINVAL; -- - w = pix_fmt->width; - h = pix_fmt->height; - if (!w || !h) { -- w = 1920; -- h = 1080; -+ w = RPIVID_DEFAULT_WIDTH; -+ h = RPIVID_DEFAULT_HEIGHT; - } -- if (w > 4096) -- w = 4096; -- if (h > 4096) -- h = 4096; -+ if (w > RPIVID_MAX_WIDTH) -+ w = RPIVID_MAX_WIDTH; -+ if (h > RPIVID_MAX_HEIGHT) -+ h = RPIVID_MAX_HEIGHT; - - if (!pix_fmt->plane_fmt[0].sizeimage || - pix_fmt->plane_fmt[0].sizeimage > SZ_32M) { -@@ -98,6 +97,7 @@ int rpivid_prepare_src_format(struct v4l - /* Set a minimum */ - size = max_t(u32, SZ_4K, pix_fmt->plane_fmt[0].sizeimage); - -+ pix_fmt->pixelformat = V4L2_PIX_FMT_HEVC_SLICE; - pix_fmt->width = w; - pix_fmt->height = h; - pix_fmt->num_planes = 1; -@@ -105,22 +105,33 @@ int rpivid_prepare_src_format(struct v4l - /* Zero bytes per line for encoded source. */ - pix_fmt->plane_fmt[0].bytesperline = 0; - pix_fmt->plane_fmt[0].sizeimage = size; -- -- return 0; - } - --int rpivid_prepare_dst_format(struct v4l2_pix_format_mplane *pix_fmt) -+/* Take any pix_format and make it valid */ -+static void rpivid_prepare_dst_format(struct v4l2_pix_format_mplane *pix_fmt) - { - unsigned int width = pix_fmt->width; - unsigned int height = pix_fmt->height; - unsigned int sizeimage = pix_fmt->plane_fmt[0].sizeimage; - unsigned int bytesperline = pix_fmt->plane_fmt[0].bytesperline; - -- switch (pix_fmt->pixelformat) { -+ if (!width) -+ width = RPIVID_DEFAULT_WIDTH; -+ if (width > RPIVID_MAX_WIDTH) -+ width = RPIVID_MAX_WIDTH; -+ if (!height) -+ height = RPIVID_DEFAULT_HEIGHT; -+ if (height > RPIVID_MAX_HEIGHT) -+ height = RPIVID_MAX_HEIGHT; -+ - /* For column formats set bytesperline to column height (stride2) */ -+ switch (pix_fmt->pixelformat) { -+ default: -+ pix_fmt->pixelformat = V4L2_PIX_FMT_NV12_COL128; -+ fallthrough; - case V4L2_PIX_FMT_NV12_COL128: - /* Width rounds up to columns */ -- width = ALIGN(min(width, RPIVID_MAX_WIDTH), 128); -+ width = ALIGN(width, 128); - - /* 16 aligned height - not sure we even need that */ - height = ALIGN(height, 16); -@@ -140,7 +151,7 @@ int rpivid_prepare_dst_format(struct v4l - /* width in pixels (3 pels = 4 bytes) rounded to 128 byte - * columns - */ -- width = ALIGN(((min(width, RPIVID_MAX_WIDTH) + 2) / 3), 32) * 3; -+ width = ALIGN(((width + 2) / 3), 32) * 3; - - /* 16-aligned height. */ - height = ALIGN(height, 16); -@@ -157,9 +168,6 @@ int rpivid_prepare_dst_format(struct v4l - sizeimage = constrain2x(sizeimage, - bytesperline * width * 4 / 3); - break; -- -- default: -- return -EINVAL; - } - - pix_fmt->width = width; -@@ -169,7 +177,6 @@ int rpivid_prepare_dst_format(struct v4l - pix_fmt->plane_fmt[0].bytesperline = bytesperline; - pix_fmt->plane_fmt[0].sizeimage = sizeimage; - pix_fmt->num_planes = 1; -- return 0; - } - - static int rpivid_querycap(struct file *file, void *priv, -@@ -260,14 +267,13 @@ static u32 pixelformat_from_sps(const st - { - u32 pf = 0; - -- // Use width 0 as a signifier of unsetness -- if (!is_sps_set(sps)) { -+ if (!is_sps_set(sps) || !rpivid_hevc_validate_sps(sps)) { - /* Treat this as an error? For now return both */ - if (index == 0) - pf = V4L2_PIX_FMT_NV12_COL128; - else if (index == 1) - pf = V4L2_PIX_FMT_NV12_10_COL128; -- } else if (index == 0 && rpivid_hevc_validate_sps(sps)) { -+ } else if (index == 0) { - if (sps->bit_depth_luma_minus8 == 0) - pf = V4L2_PIX_FMT_NV12_COL128; - else if (sps->bit_depth_luma_minus8 == 2) -@@ -282,11 +288,14 @@ rpivid_hevc_default_dst_fmt(struct rpivi - { - const struct v4l2_ctrl_hevc_sps * const sps = - rpivid_find_control_data(ctx, V4L2_CID_MPEG_VIDEO_HEVC_SPS); -- struct v4l2_pix_format_mplane pix_fmt = { -- .width = sps->pic_width_in_luma_samples, -- .height = sps->pic_height_in_luma_samples, -- .pixelformat = pixelformat_from_sps(sps, 0) -- }; -+ struct v4l2_pix_format_mplane pix_fmt; -+ -+ memset(&pix_fmt, 0, sizeof(pix_fmt)); -+ if (is_sps_set(sps)) { -+ pix_fmt.width = sps->pic_width_in_luma_samples; -+ pix_fmt.height = sps->pic_height_in_luma_samples; -+ pix_fmt.pixelformat = pixelformat_from_sps(sps, 0); -+ } - - rpivid_prepare_dst_format(&pix_fmt); - return pix_fmt; -@@ -315,14 +324,23 @@ static int rpivid_enum_fmt_vid_cap(struc - return 0; - } - -+/* -+ * get dst format - sets it to default if otherwise unset -+ * returns a pointer to the struct as a convienience -+ */ -+static struct v4l2_pix_format_mplane *get_dst_fmt(struct rpivid_ctx *const ctx) -+{ -+ if (!ctx->dst_fmt_set) -+ ctx->dst_fmt = rpivid_hevc_default_dst_fmt(ctx); -+ return &ctx->dst_fmt; -+} -+ - static int rpivid_g_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) - { - struct rpivid_ctx *ctx = rpivid_file2ctx(file); - -- if (!ctx->dst_fmt_set) -- ctx->dst_fmt = rpivid_hevc_default_dst_fmt(ctx); -- f->fmt.pix_mp = ctx->dst_fmt; -+ f->fmt.pix_mp = *get_dst_fmt(ctx); - return 0; - } - -@@ -358,31 +376,20 @@ static int rpivid_try_fmt_vid_cap(struct - break; - } - -- // If we can't use requested fmt then set to default -- if (pixelformat == 0) { -- pixelformat = pixelformat_from_sps(sps, 0); -- // If we don't have a default then give up -- if (pixelformat == 0) -- return -EINVAL; -- } -- - // We don't have any way of finding out colourspace so believe - // anything we are told - take anything set in src as a default - if (f->fmt.pix_mp.colorspace == V4L2_COLORSPACE_DEFAULT) - copy_color(&f->fmt.pix_mp, &ctx->src_fmt); - - f->fmt.pix_mp.pixelformat = pixelformat; -- return rpivid_prepare_dst_format(&f->fmt.pix_mp); -+ rpivid_prepare_dst_format(&f->fmt.pix_mp); -+ return 0; - } - - static int rpivid_try_fmt_vid_out(struct file *file, void *priv, - struct v4l2_format *f) - { -- if (rpivid_prepare_src_format(&f->fmt.pix_mp)) { -- // Set default src format -- f->fmt.pix_mp.pixelformat = RPIVID_SRC_PIXELFORMAT_DEFAULT; -- rpivid_prepare_src_format(&f->fmt.pix_mp); -- } -+ rpivid_prepare_src_format(&f->fmt.pix_mp); - return 0; - } - -@@ -474,7 +481,7 @@ static int rpivid_queue_setup(struct vb2 - if (V4L2_TYPE_IS_OUTPUT(vq->type)) - pix_fmt = &ctx->src_fmt; - else -- pix_fmt = &ctx->dst_fmt; -+ pix_fmt = get_dst_fmt(ctx); - - if (*nplanes) { - if (sizes[0] < pix_fmt->plane_fmt[0].sizeimage) ---- a/drivers/staging/media/rpivid/rpivid_video.h -+++ b/drivers/staging/media/rpivid/rpivid_video.h -@@ -28,7 +28,6 @@ int rpivid_queue_init(void *priv, struct - size_t rpivid_bit_buf_size(unsigned int w, unsigned int h, unsigned int bits_minus8); - size_t rpivid_round_up_size(const size_t x); - --int rpivid_prepare_src_format(struct v4l2_pix_format_mplane *pix_fmt); --int rpivid_prepare_dst_format(struct v4l2_pix_format_mplane *pix_fmt); -+void rpivid_prepare_src_format(struct v4l2_pix_format_mplane *pix_fmt); - - #endif diff --git a/target/linux/bcm27xx/patches-5.15/950-0500-net-phy-lan87xx-Allow-more-time-for-link-detect.patch b/target/linux/bcm27xx/patches-5.15/950-0500-net-phy-lan87xx-Allow-more-time-for-link-detect.patch deleted file mode 100644 index 7c620c440..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0500-net-phy-lan87xx-Allow-more-time-for-link-detect.patch +++ /dev/null @@ -1,38 +0,0 @@ -From eb860f6a2dee9a4c94a7101c1d43194b95fdbc8d Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 22 Sep 2021 15:38:13 +0100 -Subject: [PATCH] net: phy: lan87xx: Allow more time for link detect - -With EDPWRDOWN set in idle, it must be cleared before checking for -ENERGYON going high, indicating that a link is being established. -The existing code allows 640ms for ENERGYON to go high, but on -Raspberry Pis that appears not to be enough, causing link detection -to fail. - -Increase the polling timeout to 1500ms - with a polling interval of -10ms it shouldn't cause unnecessary delays. - -See: https://github.com/raspberrypi/linux/issues/4393 - -Signed-off-by: Phil Elwell ---- - drivers/net/phy/smsc.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/net/phy/smsc.c -+++ b/drivers/net/phy/smsc.c -@@ -223,12 +223,12 @@ static int lan87xx_read_status(struct ph - if (rc < 0) - return rc; - -- /* Wait max 640 ms to detect energy and the timeout is not -+ /* Wait max 1500 ms to detect energy and the timeout is not - * an actual error. - */ - read_poll_timeout(phy_read, rc, - rc & MII_LAN83C185_ENERGYON || rc < 0, -- 10000, 640000, true, phydev, -+ 10000, 1500000, true, phydev, - MII_LAN83C185_CTRL_STATUS); - if (rc < 0) - return rc; diff --git a/target/linux/bcm27xx/patches-5.15/950-0501-media-rpivid-Remove-unused-ctx-state-variable-and-de.patch b/target/linux/bcm27xx/patches-5.15/950-0501-media-rpivid-Remove-unused-ctx-state-variable-and-de.patch deleted file mode 100644 index 440e666c5..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0501-media-rpivid-Remove-unused-ctx-state-variable-and-de.patch +++ /dev/null @@ -1,37 +0,0 @@ -From f42c5003bb6d755516058e1be86945858f54cca7 Mon Sep 17 00:00:00 2001 -From: John Cox -Date: Wed, 22 Sep 2021 18:57:19 +0100 -Subject: [PATCH] media: rpivid: Remove unused ctx state variable and - defines - -Remove unused ctx state tracking variable and associated defines. -Their presence implies they might be used, but they aren't. - -Signed-off-by: John Cox ---- - drivers/staging/media/rpivid/rpivid.h | 7 ------- - 1 file changed, 7 deletions(-) - ---- a/drivers/staging/media/rpivid/rpivid.h -+++ b/drivers/staging/media/rpivid/rpivid.h -@@ -82,12 +82,6 @@ typedef void (*rpivid_irq_callback)(stru - struct rpivid_q_aux; - #define RPIVID_AUX_ENT_COUNT VB2_MAX_FRAME - -- --#define RPIVID_CTX_STATE_STOPPED 0 /* stream_off */ --#define RPIVID_CTX_STATE_STREAM_ON 1 /* decoding */ --#define RPIVID_CTX_STATE_STREAM_STOP 2 /* in stream_off */ --#define RPIVID_CTX_STATE_STREAM_ERR 3 /* stream_on but broken */ -- - struct rpivid_ctx { - struct v4l2_fh fh; - struct rpivid_dev *dev; -@@ -96,7 +90,6 @@ struct rpivid_ctx { - struct v4l2_pix_format_mplane dst_fmt; - int dst_fmt_set; - -- atomic_t stream_state; - struct clk_request *clk_req; - int src_stream_on; - int dst_stream_on; diff --git a/target/linux/bcm27xx/patches-5.15/950-0502-media-rpivid-Ensure-IRQs-have-completed-before-unini.patch b/target/linux/bcm27xx/patches-5.15/950-0502-media-rpivid-Ensure-IRQs-have-completed-before-unini.patch deleted file mode 100644 index 25081e269..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0502-media-rpivid-Ensure-IRQs-have-completed-before-unini.patch +++ /dev/null @@ -1,100 +0,0 @@ -From de6caac0f49de31d79b487ac1a998f0cfafdd5af Mon Sep 17 00:00:00 2001 -From: John Cox -Date: Wed, 22 Sep 2021 19:05:30 +0100 -Subject: [PATCH] media: rpivid: Ensure IRQs have completed before - uniniting context - -Before uniniting the decode context sync with the IRQ queues to ensure -that decode no longer has any buffers in use. This fixes a problem that -manifested as ffmpeg leaking CMA buffers when it did a stream off on -OUTPUT before CAPTURE, though in reality it was probably much more -dangerous than that. - -Signed-off-by: John Cox ---- - drivers/staging/media/rpivid/rpivid_h265.c | 58 ++++++++++++++++++++-- - 1 file changed, 53 insertions(+), 5 deletions(-) - ---- a/drivers/staging/media/rpivid/rpivid_h265.c -+++ b/drivers/staging/media/rpivid/rpivid_h265.c -@@ -2387,12 +2387,50 @@ static void dec_state_delete(struct rpiv - kfree(s); - } - --static void rpivid_h265_stop(struct rpivid_ctx *ctx) -+struct irq_sync { -+ atomic_t done; -+ wait_queue_head_t wq; -+ struct rpivid_hw_irq_ent irq_ent; -+}; -+ -+static void phase2_sync_claimed(struct rpivid_dev *const dev, void *v) - { -- struct rpivid_dev *const dev = ctx->dev; -- unsigned int i; -+ struct irq_sync *const sync = v; - -- v4l2_info(&dev->v4l2_dev, "%s\n", __func__); -+ atomic_set(&sync->done, 1); -+ wake_up(&sync->wq); -+} -+ -+static void phase1_sync_claimed(struct rpivid_dev *const dev, void *v) -+{ -+ struct irq_sync *const sync = v; -+ -+ rpivid_hw_irq_active1_enable_claim(dev, 1); -+ rpivid_hw_irq_active2_claim(dev, &sync->irq_ent, phase2_sync_claimed, sync); -+} -+ -+/* Sync with IRQ operations -+ * -+ * Claims phase1 and phase2 in turn and waits for the phase2 claim so any -+ * pending IRQ ops will have completed by the time this returns -+ * -+ * phase1 has counted enables so must reenable once claimed -+ * phase2 has unlimited enables -+ */ -+static void irq_sync(struct rpivid_dev *const dev) -+{ -+ struct irq_sync sync; -+ -+ atomic_set(&sync.done, 0); -+ init_waitqueue_head(&sync.wq); -+ -+ rpivid_hw_irq_active1_claim(dev, &sync.irq_ent, phase1_sync_claimed, &sync); -+ wait_event(sync.wq, atomic_read(&sync.done)); -+} -+ -+static void h265_ctx_uninit(struct rpivid_dev *const dev, struct rpivid_ctx *ctx) -+{ -+ unsigned int i; - - dec_env_uninit(ctx); - dec_state_delete(ctx); -@@ -2409,6 +2447,16 @@ static void rpivid_h265_stop(struct rpiv - gptr_free(dev, ctx->coeff_bufs + i); - } - -+static void rpivid_h265_stop(struct rpivid_ctx *ctx) -+{ -+ struct rpivid_dev *const dev = ctx->dev; -+ -+ v4l2_info(&dev->v4l2_dev, "%s\n", __func__); -+ -+ irq_sync(dev); -+ h265_ctx_uninit(dev, ctx); -+} -+ - static int rpivid_h265_start(struct rpivid_ctx *ctx) - { - struct rpivid_dev *const dev = ctx->dev; -@@ -2470,7 +2518,7 @@ static int rpivid_h265_start(struct rpiv - return 0; - - fail: -- rpivid_h265_stop(ctx); -+ h265_ctx_uninit(dev, ctx); - return -ENOMEM; - } - diff --git a/target/linux/bcm27xx/patches-5.15/950-0503-staging-bcm2835-codec-Allow-decode-res-changed-befor.patch b/target/linux/bcm27xx/patches-5.15/950-0503-staging-bcm2835-codec-Allow-decode-res-changed-befor.patch deleted file mode 100644 index e375dcbeb..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0503-staging-bcm2835-codec-Allow-decode-res-changed-befor.patch +++ /dev/null @@ -1,238 +0,0 @@ -From 6eded7dd8bcf00c6c4f354cd2edfaabc8e82e8b7 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Fri, 9 Oct 2020 10:40:27 +0100 -Subject: [PATCH] staging: bcm2835-codec: Allow decode res changed - before STREAMON(CAPTURE) - -The V4L2 stateful video decoder API requires that you can STREAMON -on only the OUTPUT queue, feed in buffers, and wait for the -SOURCE_CHANGE event. -This requires that we enable the MMAL output port at the same time -as the input port, because the output port is the one that creates -the SOURCE_CHANGED event. - -Signed-off-by: Dave Stevenson ---- - .../bcm2835-codec/bcm2835-v4l2-codec.c | 137 +++++++++++++++--- - 1 file changed, 117 insertions(+), 20 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -1498,6 +1498,7 @@ static int vidioc_s_fmt(struct bcm2835_c - struct vb2_queue *vq; - struct vchiq_mmal_port *port; - bool update_capture_port = false; -+ bool reenable_port = false; - int ret; - - v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "Setting format for type %d, wxh: %dx%d, fmt: %08x, size %u\n", -@@ -1575,6 +1576,24 @@ static int vidioc_s_fmt(struct bcm2835_c - if (!port) - return 0; - -+ if (port->enabled) { -+ /* -+ * This should only ever happen with DECODE and the MMAL output -+ * port that has been enabled for resolution changed events. -+ * In this case no buffers have been allocated or sent to the -+ * component, so warn on that. -+ */ -+ WARN_ON(ctx->dev->role != DECODE || -+ f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE || -+ atomic_read(&port->buffers_with_vpu)); -+ -+ ret = vchiq_mmal_port_disable(ctx->dev->instance, port); -+ if (ret) -+ v4l2_err(&ctx->dev->v4l2_dev, "%s: Error disabling port update buffer count, ret %d\n", -+ __func__, ret); -+ reenable_port = true; -+ } -+ - setup_mmal_port_format(ctx, q_data, port); - ret = vchiq_mmal_port_set_format(ctx->dev->instance, port); - if (ret) { -@@ -1589,6 +1608,14 @@ static int vidioc_s_fmt(struct bcm2835_c - port->minimum_buffer.size); - } - -+ if (reenable_port) { -+ ret = vchiq_mmal_port_enable(ctx->dev->instance, -+ port, -+ op_buffer_cb); -+ if (ret) -+ v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed enabling o/p port, ret %d\n", -+ __func__, ret); -+ } - v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "Set format for type %d, wxh: %dx%d, fmt: %08x, size %u\n", - f->type, q_data->crop_width, q_data->height, - q_data->fmt->fourcc, q_data->sizeimage); -@@ -2467,9 +2494,11 @@ static int bcm2835_codec_create_componen - - setup_mmal_port_format(ctx, &ctx->q_data[V4L2_M2M_SRC], - &ctx->component->input[0]); -+ ctx->component->input[0].cb_ctx = ctx; - - setup_mmal_port_format(ctx, &ctx->q_data[V4L2_M2M_DST], - &ctx->component->output[0]); -+ ctx->component->output[0].cb_ctx = ctx; - - ret = vchiq_mmal_port_set_format(dev->instance, - &ctx->component->input[0]); -@@ -2724,6 +2753,24 @@ static void bcm2835_codec_buffer_cleanup - bcm2835_codec_mmal_buf_cleanup(&buf->mmal); - } - -+static void bcm2835_codec_flush_buffers(struct bcm2835_codec_ctx *ctx, -+ struct vchiq_mmal_port *port) -+{ -+ int ret; -+ -+ while (atomic_read(&port->buffers_with_vpu)) { -+ v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: Waiting for buffers to be returned - %d outstanding\n", -+ __func__, atomic_read(&port->buffers_with_vpu)); -+ ret = wait_for_completion_timeout(&ctx->frame_cmplt, -+ COMPLETE_TIMEOUT); -+ if (ret <= 0) { -+ v4l2_err(&ctx->dev->v4l2_dev, "%s: Timeout waiting for buffers to be returned - %d outstanding\n", -+ __func__, -+ atomic_read(&port->buffers_with_vpu)); -+ break; -+ } -+ } -+} - static int bcm2835_codec_start_streaming(struct vb2_queue *q, - unsigned int count) - { -@@ -2731,7 +2778,7 @@ static int bcm2835_codec_start_streaming - struct bcm2835_codec_dev *dev = ctx->dev; - struct bcm2835_codec_q_data *q_data = get_q_data(ctx, q->type); - struct vchiq_mmal_port *port = get_port_data(ctx, q->type); -- int ret; -+ int ret = 0; - - v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: type: %d count %d\n", - __func__, q->type, count); -@@ -2746,6 +2793,34 @@ static int bcm2835_codec_start_streaming - ctx->component_enabled = true; - } - -+ if (port->enabled) { -+ unsigned int num_buffers; -+ -+ init_completion(&ctx->frame_cmplt); -+ -+ /* -+ * This should only ever happen with DECODE and the MMAL output -+ * port that has been enabled for resolution changed events. -+ * In this case no buffers have been allocated or sent to the -+ * component, so warn on that. -+ */ -+ WARN_ON(ctx->dev->role != DECODE); -+ WARN_ON(q->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); -+ WARN_ON(atomic_read(&port->buffers_with_vpu)); -+ -+ /* -+ * Disable will reread the port format, so retain buffer count. -+ */ -+ num_buffers = port->current_buffer.num; -+ -+ ret = vchiq_mmal_port_disable(dev->instance, port); -+ if (ret) -+ v4l2_err(&ctx->dev->v4l2_dev, "%s: Error disabling port update buffer count, ret %d\n", -+ __func__, ret); -+ bcm2835_codec_flush_buffers(ctx, port); -+ port->current_buffer.num = num_buffers; -+ } -+ - if (count < port->minimum_buffer.num) - count = port->minimum_buffer.num; - -@@ -2760,6 +2835,22 @@ static int bcm2835_codec_start_streaming - __func__, ret); - } - -+ if (dev->role == DECODE && -+ q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE && -+ !ctx->component->output[0].enabled) { -+ /* -+ * Decode needs to enable the MMAL output/V4L2 CAPTURE -+ * port at this point too so that we have everything -+ * set up for dynamic resolution changes. -+ */ -+ ret = vchiq_mmal_port_enable(dev->instance, -+ &ctx->component->output[0], -+ op_buffer_cb); -+ if (ret) -+ v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed enabling o/p port, ret %d\n", -+ __func__, ret); -+ } -+ - if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { - /* - * Create the EOS buffer. -@@ -2771,7 +2862,6 @@ static int bcm2835_codec_start_streaming - &q_data->eos_buffer.mmal); - q_data->eos_buffer_in_use = false; - -- port->cb_ctx = ctx; - ret = vchiq_mmal_port_enable(dev->instance, - port, - ip_buffer_cb); -@@ -2779,14 +2869,17 @@ static int bcm2835_codec_start_streaming - v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed enabling i/p port, ret %d\n", - __func__, ret); - } else { -- port->cb_ctx = ctx; -- ret = vchiq_mmal_port_enable(dev->instance, -- port, -- op_buffer_cb); -- if (ret) -- v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed enabling o/p port, ret %d\n", -- __func__, ret); -+ if (!port->enabled) { -+ ret = vchiq_mmal_port_enable(dev->instance, -+ port, -+ op_buffer_cb); -+ if (ret) -+ v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed enabling o/p port, ret %d\n", -+ __func__, ret); -+ } - } -+ v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: Done, ret %d\n", -+ __func__, ret); - return ret; - } - -@@ -2825,17 +2918,21 @@ static void bcm2835_codec_stop_streaming - __func__, V4L2_TYPE_IS_OUTPUT(q->type) ? "i/p" : "o/p", - ret); - -- while (atomic_read(&port->buffers_with_vpu)) { -- v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: Waiting for buffers to be returned - %d outstanding\n", -- __func__, atomic_read(&port->buffers_with_vpu)); -- ret = wait_for_completion_timeout(&ctx->frame_cmplt, -- COMPLETE_TIMEOUT); -- if (ret <= 0) { -- v4l2_err(&ctx->dev->v4l2_dev, "%s: Timeout waiting for buffers to be returned - %d outstanding\n", -- __func__, -- atomic_read(&port->buffers_with_vpu)); -- break; -- } -+ bcm2835_codec_flush_buffers(ctx, port); -+ -+ if (dev->role == DECODE && -+ q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && -+ ctx->component->input[0].enabled) { -+ /* -+ * For decode we need to keep the MMAL output port enabled for -+ * resolution changed events whenever the input is enabled. -+ */ -+ ret = vchiq_mmal_port_enable(dev->instance, -+ &ctx->component->output[0], -+ op_buffer_cb); -+ if (ret) -+ v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed enabling o/p port, ret %d\n", -+ __func__, ret); - } - - /* If both ports disabled, then disable the component */ diff --git a/target/linux/bcm27xx/patches-5.15/950-0504-staging-bcm2835-codec-Do-not-send-buffers-to-the-VPU.patch b/target/linux/bcm27xx/patches-5.15/950-0504-staging-bcm2835-codec-Do-not-send-buffers-to-the-VPU.patch deleted file mode 100644 index 89fac7873..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0504-staging-bcm2835-codec-Do-not-send-buffers-to-the-VPU.patch +++ /dev/null @@ -1,94 +0,0 @@ -From def9aa1e5f2e29d29b493c22fd98e1c0af018d99 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Wed, 15 Sep 2021 17:44:19 +0100 -Subject: [PATCH] staging/bcm2835-codec: Do not send buffers to the VPU - unless streaming - -With video decode we now enable both input and output ports on -the component. This means that buffers will get passed to the VPU -earlier than desired if they are queued befoer STREAMON. - -Check that the queue is streaming before sending buffers to the VPU. - -Signed-off-by: Dave Stevenson ---- - .../bcm2835-codec/bcm2835-v4l2-codec.c | 64 +++++++++++-------- - 1 file changed, 38 insertions(+), 26 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -1244,35 +1244,47 @@ static void device_run(void *priv) - - v4l2_dbg(3, debug, &ctx->dev->v4l2_dev, "%s: off we go\n", __func__); - -- src_buf = v4l2_m2m_buf_remove(&ctx->fh.m2m_ctx->out_q_ctx); -- if (src_buf) { -- m2m = container_of(src_buf, struct v4l2_m2m_buffer, vb); -- src_m2m_buf = container_of(m2m, struct m2m_mmal_buffer, m2m); -- vb2_to_mmal_buffer(src_m2m_buf, src_buf); -- -- ret = vchiq_mmal_submit_buffer(dev->instance, -- &ctx->component->input[0], -- &src_m2m_buf->mmal); -- v4l2_dbg(3, debug, &ctx->dev->v4l2_dev, "%s: Submitted ip buffer len %lu, pts %llu, flags %04x\n", -- __func__, src_m2m_buf->mmal.length, -- src_m2m_buf->mmal.pts, src_m2m_buf->mmal.mmal_flags); -- if (ret) -- v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed submitting ip buffer\n", -- __func__); -+ if (ctx->fh.m2m_ctx->out_q_ctx.q.streaming) { -+ src_buf = v4l2_m2m_buf_remove(&ctx->fh.m2m_ctx->out_q_ctx); -+ if (src_buf) { -+ m2m = container_of(src_buf, struct v4l2_m2m_buffer, vb); -+ src_m2m_buf = container_of(m2m, struct m2m_mmal_buffer, -+ m2m); -+ vb2_to_mmal_buffer(src_m2m_buf, src_buf); -+ -+ ret = vchiq_mmal_submit_buffer(dev->instance, -+ &ctx->component->input[0], -+ &src_m2m_buf->mmal); -+ v4l2_dbg(3, debug, &ctx->dev->v4l2_dev, -+ "%s: Submitted ip buffer len %lu, pts %llu, flags %04x\n", -+ __func__, src_m2m_buf->mmal.length, -+ src_m2m_buf->mmal.pts, -+ src_m2m_buf->mmal.mmal_flags); -+ if (ret) -+ v4l2_err(&ctx->dev->v4l2_dev, -+ "%s: Failed submitting ip buffer\n", -+ __func__); -+ } - } - -- dst_buf = v4l2_m2m_buf_remove(&ctx->fh.m2m_ctx->cap_q_ctx); -- if (dst_buf) { -- m2m = container_of(dst_buf, struct v4l2_m2m_buffer, vb); -- dst_m2m_buf = container_of(m2m, struct m2m_mmal_buffer, m2m); -- vb2_to_mmal_buffer(dst_m2m_buf, dst_buf); -- -- ret = vchiq_mmal_submit_buffer(dev->instance, -- &ctx->component->output[0], -- &dst_m2m_buf->mmal); -- if (ret) -- v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed submitting op buffer\n", -- __func__); -+ if (ctx->fh.m2m_ctx->cap_q_ctx.q.streaming) { -+ dst_buf = v4l2_m2m_buf_remove(&ctx->fh.m2m_ctx->cap_q_ctx); -+ if (dst_buf) { -+ m2m = container_of(dst_buf, struct v4l2_m2m_buffer, vb); -+ dst_m2m_buf = container_of(m2m, struct m2m_mmal_buffer, -+ m2m); -+ vb2_to_mmal_buffer(dst_m2m_buf, dst_buf); -+ -+ v4l2_dbg(3, debug, &ctx->dev->v4l2_dev, -+ "%s: Submitted op buffer\n", __func__); -+ ret = vchiq_mmal_submit_buffer(dev->instance, -+ &ctx->component->output[0], -+ &dst_m2m_buf->mmal); -+ if (ret) -+ v4l2_err(&ctx->dev->v4l2_dev, -+ "%s: Failed submitting op buffer\n", -+ __func__); -+ } - } - - v4l2_dbg(3, debug, &ctx->dev->v4l2_dev, "%s: Submitted src %p, dst %p\n", diff --git a/target/linux/bcm27xx/patches-5.15/950-0506-staging-bcm2835-codec-Format-changed-should-trigger-.patch b/target/linux/bcm27xx/patches-5.15/950-0506-staging-bcm2835-codec-Format-changed-should-trigger-.patch deleted file mode 100644 index a2f3c8471..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0506-staging-bcm2835-codec-Format-changed-should-trigger-.patch +++ /dev/null @@ -1,43 +0,0 @@ -From e3feb9db3003d5461be4c186c12225120af3883c Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 16 Sep 2021 16:32:53 +0100 -Subject: [PATCH] staging: bcm2835-codec: Format changed should trigger - drain - -When a format changed event occurs, the spec says that it -triggers an implicit drain, and that needs to be signalled -via -EPIPE. - -For BCM2835, the format changed event happens at the point -the format change occurs, so no further buffers exist from -before the resolution changed point. We therefore signal the -last buffer immediately. -We don't have a V4L2 available to us at this point, so set -the videobuf2 queue last_buffer_dequeued flag directly. - -Signed-off-by: Dave Stevenson ---- - .../staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c | 5 +++++ - 1 file changed, 5 insertions(+) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -1005,6 +1005,7 @@ static void handle_fmt_changed(struct bc - (struct mmal_msg_event_format_changed *)mmal_buf->buffer; - struct mmal_parameter_video_interlace_type interlace; - int interlace_size = sizeof(interlace); -+ struct vb2_queue *vq; - int ret; - - v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: Format changed: buff size min %u, rec %u, buff num min %u, rec %u\n", -@@ -1074,6 +1075,10 @@ static void handle_fmt_changed(struct bc - q_data->field = V4L2_FIELD_NONE; - } - -+ vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); -+ if (vq->streaming) -+ vq->last_buffer_dequeued = true; -+ - queue_res_chg_event(ctx); - } - diff --git a/target/linux/bcm27xx/patches-5.15/950-0507-staging-bcm2835-codec-Signal-the-firmware-to-stop-on.patch b/target/linux/bcm27xx/patches-5.15/950-0507-staging-bcm2835-codec-Signal-the-firmware-to-stop-on.patch deleted file mode 100644 index 0d9188a1a..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0507-staging-bcm2835-codec-Signal-the-firmware-to-stop-on.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 672e3f61cf8bfd8eb578e19a87bc1ce4187cd546 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 16 Sep 2021 16:39:07 +0100 -Subject: [PATCH] staging: bcm2835-codec: Signal the firmware to stop - on all changes - -The firmware defaults to not stopping video decode if only the -pixel aspect ratio or colourspace change. V4L2 requires us -to stop decoding on any change, therefore tell the firmware -of the desire for this alternate behaviour. - -Signed-off-by: Dave Stevenson ---- - .../vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c | 10 ++++++++++ - .../staging/vc04_services/vchiq-mmal/mmal-parameters.h | 3 +++ - 2 files changed, 13 insertions(+) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -2483,6 +2483,16 @@ static int bcm2835_codec_create_componen - MMAL_PARAMETER_VIDEO_VALIDATE_TIMESTAMPS, - &enable, - sizeof(enable)); -+ /* -+ * Enable firmware option to stop on colourspace and pixel -+ * aspect ratio changed -+ */ -+ enable = 1; -+ vchiq_mmal_port_parameter_set(dev->instance, -+ &ctx->component->control, -+ MMAL_PARAMETER_VIDEO_STOP_ON_PAR_COLOUR_CHANGE, -+ &enable, -+ sizeof(enable)); - } else if (dev->role == DEINTERLACE) { - /* Select the default deinterlace algorithm. */ - int half_framerate = 0; ---- a/drivers/staging/vc04_services/vchiq-mmal/mmal-parameters.h -+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-parameters.h -@@ -682,6 +682,9 @@ enum mmal_parameter_video_type { - - /**< Take a @ref MMAL_PARAMETER_BOOLEAN_T */ - MMAL_PARAMETER_VIDEO_VALIDATE_TIMESTAMPS, -+ -+ /**< Takes a @ref MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_VIDEO_STOP_ON_PAR_COLOUR_CHANGE, - }; - - /** Valid mirror modes */ diff --git a/target/linux/bcm27xx/patches-5.15/950-0509-staging-bcm2835-codec-Queue-flushed-buffers-instead-.patch b/target/linux/bcm27xx/patches-5.15/950-0509-staging-bcm2835-codec-Queue-flushed-buffers-instead-.patch deleted file mode 100644 index abcbe84fc..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0509-staging-bcm2835-codec-Queue-flushed-buffers-instead-.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 24da14f2d745114eddf9d1d7e1bfde90d1c0c35c Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 16 Sep 2021 16:46:58 +0100 -Subject: [PATCH] staging: bcm2835-codec: Queue flushed buffers instead - of completing - -When a buffer is returned on a port that is disabled, return it -to the videobuf2 QUEUED state instead of DONE which returns it -to the client. - -Signed-off-by: Dave Stevenson ---- - .../staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -926,7 +926,9 @@ static void ip_buffer_cb(struct vchiq_mm - - v4l2_dbg(3, debug, &ctx->dev->v4l2_dev, "%s: no error. Return buffer %p\n", - __func__, &buf->m2m.vb.vb2_buf); -- vb2_buffer_done(&buf->m2m.vb.vb2_buf, VB2_BUF_STATE_DONE); -+ vb2_buffer_done(&buf->m2m.vb.vb2_buf, -+ port->enabled ? VB2_BUF_STATE_DONE : -+ VB2_BUF_STATE_QUEUED); - - ctx->num_ip_buffers++; - v4l2_dbg(2, debug, &ctx->dev->v4l2_dev, "%s: done %d input buffers\n", diff --git a/target/linux/bcm27xx/patches-5.15/950-0511-staging-bcm2835_codec-Correct-flushing-code-for-refc.patch b/target/linux/bcm27xx/patches-5.15/950-0511-staging-bcm2835_codec-Correct-flushing-code-for-refc.patch deleted file mode 100644 index febdfcc5d..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0511-staging-bcm2835_codec-Correct-flushing-code-for-refc.patch +++ /dev/null @@ -1,92 +0,0 @@ -From cd850cb03a564c948db4db8cac672284c55cefc3 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Wed, 22 Sep 2021 16:42:49 +0100 -Subject: [PATCH] staging: bcm2835_codec: Correct flushing code for - refcounting - -Completions don't reference count, so setting the completion -on the first buffer returned and then not reinitialising it -means that the flush function doesn't behave as intended. - -Signal the completion when the last buffer is returned. - -Signed-off-by: Dave Stevenson ---- - .../bcm2835-codec/bcm2835-v4l2-codec.c | 20 ++++++++++++++----- - 1 file changed, 15 insertions(+), 5 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -934,7 +934,7 @@ static void ip_buffer_cb(struct vchiq_mm - v4l2_dbg(2, debug, &ctx->dev->v4l2_dev, "%s: done %d input buffers\n", - __func__, ctx->num_ip_buffers); - -- if (!port->enabled) -+ if (!port->enabled && atomic_read(&port->buffers_with_vpu)) - complete(&ctx->frame_cmplt); - } - -@@ -1135,7 +1135,8 @@ static void op_buffer_cb(struct vchiq_mm - __func__, mmal_buf->mmal_flags); - if (!(mmal_buf->mmal_flags & MMAL_BUFFER_HEADER_FLAG_EOS)) { - vb2_buffer_done(&vb2->vb2_buf, VB2_BUF_STATE_QUEUED); -- if (!port->enabled) -+ if (!port->enabled && -+ atomic_read(&port->buffers_with_vpu)) - complete(&ctx->frame_cmplt); - return; - } -@@ -1178,7 +1179,7 @@ static void op_buffer_cb(struct vchiq_mm - v4l2_dbg(2, debug, &ctx->dev->v4l2_dev, "%s: done %d output buffers\n", - __func__, ctx->num_op_buffers); - -- if (!port->enabled) -+ if (!port->enabled && atomic_read(&port->buffers_with_vpu)) - complete(&ctx->frame_cmplt); - } - -@@ -1596,6 +1597,8 @@ static int vidioc_s_fmt(struct bcm2835_c - return 0; - - if (port->enabled) { -+ unsigned int num_buffers; -+ - /* - * This should only ever happen with DECODE and the MMAL output - * port that has been enabled for resolution changed events. -@@ -1606,10 +1609,18 @@ static int vidioc_s_fmt(struct bcm2835_c - f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE || - atomic_read(&port->buffers_with_vpu)); - -+ /* -+ * Disable will reread the port format, so retain buffer count. -+ */ -+ num_buffers = port->current_buffer.num; -+ - ret = vchiq_mmal_port_disable(ctx->dev->instance, port); - if (ret) - v4l2_err(&ctx->dev->v4l2_dev, "%s: Error disabling port update buffer count, ret %d\n", - __func__, ret); -+ -+ port->current_buffer.num = num_buffers; -+ - reenable_port = true; - } - -@@ -2787,7 +2798,7 @@ static void bcm2835_codec_flush_buffers( - { - int ret; - -- while (atomic_read(&port->buffers_with_vpu)) { -+ if (atomic_read(&port->buffers_with_vpu)) { - v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: Waiting for buffers to be returned - %d outstanding\n", - __func__, atomic_read(&port->buffers_with_vpu)); - ret = wait_for_completion_timeout(&ctx->frame_cmplt, -@@ -2796,7 +2807,6 @@ static void bcm2835_codec_flush_buffers( - v4l2_err(&ctx->dev->v4l2_dev, "%s: Timeout waiting for buffers to be returned - %d outstanding\n", - __func__, - atomic_read(&port->buffers_with_vpu)); -- break; - } - } - } diff --git a/target/linux/bcm27xx/patches-5.15/950-0512-staging-bcm2835-codec-Ensure-all-ctrls-are-set-on-st.patch b/target/linux/bcm27xx/patches-5.15/950-0512-staging-bcm2835-codec-Ensure-all-ctrls-are-set-on-st.patch deleted file mode 100644 index 97da4b03a..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0512-staging-bcm2835-codec-Ensure-all-ctrls-are-set-on-st.patch +++ /dev/null @@ -1,111 +0,0 @@ -From df5051094f02f536291e84f2820e9680cc98687d Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 20 Sep 2021 15:00:51 +0100 -Subject: [PATCH] staging: bcm2835-codec: Ensure all ctrls are set on - streamon - -Currently the code was only setting some controls from -bcm2835_codec_set_ctrls, but it's simpler to use -v4l2_ctrl_handler_setup to avoid forgetting to adding new -controls to the list. - -Signed-off-by: Dave Stevenson ---- - .../bcm2835-codec/bcm2835-v4l2-codec.c | 51 +++++++------------ - 1 file changed, 19 insertions(+), 32 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -2437,33 +2437,6 @@ static const struct v4l2_ioctl_ops bcm28 - .vidioc_enum_framesizes = vidioc_enum_framesizes, - }; - --static int bcm2835_codec_set_ctrls(struct bcm2835_codec_ctx *ctx) --{ -- /* -- * Query the control handler for the value of the various controls and -- * set them. -- */ -- const u32 control_ids[] = { -- V4L2_CID_MPEG_VIDEO_BITRATE_MODE, -- V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER, -- V4L2_CID_MPEG_VIDEO_HEADER_MODE, -- V4L2_CID_MPEG_VIDEO_H264_I_PERIOD, -- V4L2_CID_MPEG_VIDEO_H264_LEVEL, -- V4L2_CID_MPEG_VIDEO_H264_PROFILE, -- }; -- int i; -- -- for (i = 0; i < ARRAY_SIZE(control_ids); i++) { -- struct v4l2_ctrl *ctrl; -- -- ctrl = v4l2_ctrl_find(&ctx->hdl, control_ids[i]); -- if (ctrl) -- bcm2835_codec_s_ctrl(ctrl); -- } -- -- return 0; --} -- - static int bcm2835_codec_create_component(struct bcm2835_codec_ctx *ctx) - { - struct bcm2835_codec_dev *dev = ctx->dev; -@@ -2567,9 +2540,6 @@ static int bcm2835_codec_create_componen - ctx->q_data[V4L2_M2M_SRC].sizeimage, - ctx->component->output[0].minimum_buffer.size); - -- /* Now we have a component we can set all the ctrls */ -- bcm2835_codec_set_ctrls(ctx); -- - /* Enable SPS Timing header so framerate information is encoded - * in the H264 header. - */ -@@ -2598,6 +2568,10 @@ static int bcm2835_codec_create_componen - ctx->q_data[V4L2_M2M_DST].sizeimage, - ctx->component->output[0].minimum_buffer.size); - } -+ -+ /* Now we have a component we can set all the ctrls */ -+ ret = v4l2_ctrl_handler_setup(&ctx->hdl); -+ - v4l2_dbg(2, debug, &dev->v4l2_dev, "%s: component created as %s\n", - __func__, components[dev->role]); - -@@ -3099,7 +3073,9 @@ static int bcm2835_codec_open(struct fil - file->private_data = &ctx->fh; - ctx->dev = dev; - hdl = &ctx->hdl; -- if (dev->role == ENCODE) { -+ switch (dev->role) { -+ case ENCODE: -+ { - /* Encode controls */ - v4l2_ctrl_handler_init(hdl, 9); - -@@ -3158,7 +3134,10 @@ static int bcm2835_codec_open(struct fil - } - ctx->fh.ctrl_handler = hdl; - v4l2_ctrl_handler_setup(hdl); -- } else if (dev->role == DECODE) { -+ } -+ break; -+ case DECODE: -+ { - v4l2_ctrl_handler_init(hdl, 1); - - v4l2_ctrl_new_std(hdl, &bcm2835_codec_ctrl_ops, -@@ -3171,6 +3150,14 @@ static int bcm2835_codec_open(struct fil - ctx->fh.ctrl_handler = hdl; - v4l2_ctrl_handler_setup(hdl); - } -+ break; -+ case ISP: -+ case DEINTERLACE: -+ { -+ v4l2_ctrl_handler_init(hdl, 0); -+ } -+ break; -+ } - - ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, &queue_init); - diff --git a/target/linux/bcm27xx/patches-5.15/950-0513-staging-bcm2835-codec-Add-support-for-H-V-Flips-to-I.patch b/target/linux/bcm27xx/patches-5.15/950-0513-staging-bcm2835-codec-Add-support-for-H-V-Flips-to-I.patch deleted file mode 100644 index 2a0380f5e..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0513-staging-bcm2835-codec-Add-support-for-H-V-Flips-to-I.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 3df60f3d0615c011e91b7d6f39cb9123b2e96530 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 20 Sep 2021 14:37:17 +0100 -Subject: [PATCH] staging: bcm2835-codec: Add support for H&V Flips to - ISP - -The ISP can do H & V flips whilst resizing or converting -the image, so expose that via V4L2_CID_[H|V]FLIP. - -Signed-off-by: Dave Stevenson ---- - .../bcm2835-codec/bcm2835-v4l2-codec.c | 48 +++++++++++++++++++ - 1 file changed, 48 insertions(+) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -679,6 +679,9 @@ struct bcm2835_codec_ctx { - enum v4l2_xfer_func xfer_func; - enum v4l2_quantization quant; - -+ int hflip; -+ int vflip; -+ - /* Source and destination queue data */ - struct bcm2835_codec_q_data q_data[2]; - s32 bitrate; -@@ -2202,6 +2205,34 @@ static int bcm2835_codec_s_ctrl(struct v - sizeof(mmal_bool)); - break; - } -+ case V4L2_CID_HFLIP: -+ case V4L2_CID_VFLIP: { -+ u32 u32_value; -+ -+ if (ctrl->id == V4L2_CID_HFLIP) -+ ctx->hflip = ctrl->val; -+ else -+ ctx->vflip = ctrl->val; -+ -+ if (!ctx->component) -+ break; -+ -+ if (ctx->hflip && ctx->vflip) -+ u32_value = MMAL_PARAM_MIRROR_BOTH; -+ else if (ctx->hflip) -+ u32_value = MMAL_PARAM_MIRROR_HORIZONTAL; -+ else if (ctx->vflip) -+ u32_value = MMAL_PARAM_MIRROR_VERTICAL; -+ else -+ u32_value = MMAL_PARAM_MIRROR_NONE; -+ -+ ret = vchiq_mmal_port_parameter_set(ctx->dev->instance, -+ &ctx->component->input[0], -+ MMAL_PARAMETER_MIRROR, -+ &u32_value, -+ sizeof(u32_value)); -+ break; -+ } - - default: - v4l2_err(&ctx->dev->v4l2_dev, "Invalid control\n"); -@@ -3152,6 +3183,23 @@ static int bcm2835_codec_open(struct fil - } - break; - case ISP: -+ { -+ v4l2_ctrl_handler_init(hdl, 2); -+ -+ v4l2_ctrl_new_std(hdl, &bcm2835_codec_ctrl_ops, -+ V4L2_CID_HFLIP, -+ 1, 0, 1, 0); -+ v4l2_ctrl_new_std(hdl, &bcm2835_codec_ctrl_ops, -+ V4L2_CID_VFLIP, -+ 1, 0, 1, 0); -+ if (hdl->error) { -+ rc = hdl->error; -+ goto free_ctrl_handler; -+ } -+ ctx->fh.ctrl_handler = hdl; -+ v4l2_ctrl_handler_setup(hdl); -+ } -+ break; - case DEINTERLACE: - { - v4l2_ctrl_handler_init(hdl, 0); diff --git a/target/linux/bcm27xx/patches-5.15/950-0514-overlays-add-support-for-the-MLX90640-thermal-camera.patch b/target/linux/bcm27xx/patches-5.15/950-0514-overlays-add-support-for-the-MLX90640-thermal-camera.patch deleted file mode 100644 index 1e9bf8eea..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0514-overlays-add-support-for-the-MLX90640-thermal-camera.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 3fd6d30806724fa8b07ae625d828c49855c42fbe Mon Sep 17 00:00:00 2001 -From: Guennadi Liakhovetski -Date: Sun, 19 Sep 2021 13:30:43 +0200 -Subject: [PATCH] overlays: add support for the MLX90640 thermal camera - -This allows using the video-i2c camera driver with MLX90640 thermal -infrared sensors, connected to Raspberry Pi. CONFIG_VIDEO_V4L2_I2C -has to be selected to use the camera. - -Signed-off-by: Guennadi Liakhovetski ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 6 +++++ - .../boot/dts/overlays/mlx90640-overlay.dts | 22 +++++++++++++++++++ - 3 files changed, 29 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/mlx90640-overlay.dts - ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -129,6 +129,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ - midi-uart5.dtbo \ - minipitft13.dtbo \ - miniuart-bt.dtbo \ -+ mlx90640.dtbo \ - mmc.dtbo \ - mpu6050.dtbo \ - mz61581.dtbo \ ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -2152,6 +2152,12 @@ Params: krnbt Set to " - driver without need of hciattach/btattach - - -+Name: mlx90640 -+Info: Overlay for i2c connected mlx90640 thermal camera -+Load: dtoverlay=mlx90640 -+Params: -+ -+ - Name: mmc - Info: Selects the bcm2835-mmc SD/MMC driver, optionally with overclock - Load: dtoverlay=mmc,= ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/mlx90640-overlay.dts -@@ -0,0 +1,22 @@ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835"; -+ -+ fragment@0 { -+ target = <&i2c_arm>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ clock-frequency = <400000>; -+ -+ mlx90640: mlx90640@33 { -+ compatible = "melexis,mlx90640"; -+ reg = <0x33>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; diff --git a/target/linux/bcm27xx/patches-5.15/950-0515-overlays-Add-generic-mcp2515-overlay.patch b/target/linux/bcm27xx/patches-5.15/950-0515-overlays-Add-generic-mcp2515-overlay.patch deleted file mode 100644 index 15feadbe6..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0515-overlays-Add-generic-mcp2515-overlay.patch +++ /dev/null @@ -1,206 +0,0 @@ -From 637535797f538a24a0ce2225185b24b14aa20d51 Mon Sep 17 00:00:00 2001 -From: GabyPCgeeK -Date: Mon, 27 Sep 2021 04:43:21 -0400 -Subject: [PATCH] overlays: Add generic mcp2515 overlay - -Can configure mcp2515 on spi0/1/2 without the need for multiple overlays. ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 15 ++ - .../arm/boot/dts/overlays/mcp2515-overlay.dts | 156 ++++++++++++++++++ - 3 files changed, 172 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/mcp2515-overlay.dts - ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -113,6 +113,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ - mbed-dac.dtbo \ - mcp23017.dtbo \ - mcp23s17.dtbo \ -+ mcp2515.dtbo \ - mcp2515-can0.dtbo \ - mcp2515-can1.dtbo \ - mcp251xfd.dtbo \ ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -1977,6 +1977,21 @@ Params: s08-spi--present 4-bit in - or INTB output of MCP23S17 is connected. - - -+Name: mcp2515 -+Info: Configures the MCP2515 CAN controller on spi0/1/2 -+ For devices on spi1 or spi2, the interfaces should be enabled -+ with one of the spi1-1/2/3cs and/or spi2-1/2/3cs overlays. -+Load: dtoverlay=mcp2515,= -+Params: spi- Configure device at spi, cs -+ (boolean, required) -+ -+ oscillator Clock frequency for the CAN controller (Hz) -+ -+ speed Maximum SPI frequence (Hz) -+ -+ interrupt GPIO for interrupt signal -+ -+ - Name: mcp2515-can0 - Info: Configures the MCP2515 CAN controller on spi0.0 - Load: dtoverlay=mcp2515-can0,= ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/mcp2515-overlay.dts -@@ -0,0 +1,156 @@ -+// SPDX-License-Identifier: (GPL-2.0 OR MIT) -+ -+/dts-v1/; -+/plugin/; -+ -+#include -+#include -+#include -+ -+/ { -+ compatible = "brcm,bcm2835"; -+ -+ fragment@0 { -+ target = <&spidev0>; -+ __dormant__ { -+ status = "disabled"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&spidev1>; -+ __dormant__ { -+ status = "disabled"; -+ }; -+ }; -+ -+ fragment@2 { -+ target-path = "spi1/spidev@0"; -+ __dormant__ { -+ status = "disabled"; -+ }; -+ }; -+ -+ fragment@3 { -+ target-path = "spi1/spidev@1"; -+ __dormant__ { -+ status = "disabled"; -+ }; -+ }; -+ -+ fragment@4 { -+ target-path = "spi1/spidev@2"; -+ __dormant__ { -+ status = "disabled"; -+ }; -+ }; -+ -+ fragment@5 { -+ target-path = "spi2/spidev@0"; -+ __dormant__ { -+ status = "disabled"; -+ }; -+ }; -+ -+ fragment@6 { -+ target-path = "spi2/spidev@1"; -+ __dormant__ { -+ status = "disabled"; -+ }; -+ }; -+ -+ fragment@7 { -+ target-path = "spi2/spidev@2"; -+ __dormant__ { -+ status = "disabled"; -+ }; -+ }; -+ -+ fragment@8 { -+ target = <&gpio>; -+ __overlay__ { -+ mcp2515_pins: mcp2515_pins { -+ brcm,pins = <25>; -+ brcm,function = ; -+ }; -+ }; -+ }; -+ -+ fragment@9 { -+ target-path = "/clocks"; -+ __overlay__ { -+ clk_mcp2515_osc: mcp2515-osc { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <16000000>; -+ }; -+ }; -+ }; -+ -+ mcp2515_frag: fragment@10 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ mcp2515: mcp2515@0 { -+ compatible = "microchip,mcp2515"; -+ reg = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mcp2515_pins>; -+ spi-max-frequency = <10000000>; -+ interrupt-parent = <&gpio>; -+ interrupts = <25 IRQ_TYPE_LEVEL_LOW>; -+ clocks = <&clk_mcp2515_osc>; -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ spi0-0 = <0>, "+0", -+ <&mcp2515_frag>, "target:0=", <&spi0>, -+ <&mcp2515>, "reg:0=0", -+ <&mcp2515_pins>, "name=mcp2515_spi0_0_pins", -+ <&clk_mcp2515_osc>, "name=mcp2515-spi0-0-osc"; -+ spi0-1 = <0>, "+1", -+ <&mcp2515_frag>, "target:0=", <&spi0>, -+ <&mcp2515>, "reg:0=1", -+ <&mcp2515_pins>, "name=mcp2515_spi0_1_pins", -+ <&clk_mcp2515_osc>, "name=mcp2515-spi0-1-osc"; -+ spi1-0 = <0>, "+2", -+ <&mcp2515_frag>, "target:0=", <&spi1>, -+ <&mcp2515>, "reg:0=0", -+ <&mcp2515_pins>, "name=mcp2515_spi1_0_pins", -+ <&clk_mcp2515_osc>, "name=mcp2515-spi1-0-osc"; -+ spi1-1 = <0>, "+3", -+ <&mcp2515_frag>, "target:0=", <&spi1>, -+ <&mcp2515>, "reg:0=1", -+ <&mcp2515_pins>, "name=mcp2515_spi1_1_pins", -+ <&clk_mcp2515_osc>, "name=mcp2515-spi1-1-osc"; -+ spi1-2 = <0>, "+4", -+ <&mcp2515_frag>, "target:0=", <&spi1>, -+ <&mcp2515>, "reg:0=2", -+ <&mcp2515_pins>, "name=mcp2515_spi1_2_pins", -+ <&clk_mcp2515_osc>, "name=mcp2515-spi1-2-osc"; -+ spi2-0 = <0>, "+5", -+ <&mcp2515_frag>, "target:0=", <&spi2>, -+ <&mcp2515>, "reg:0=0", -+ <&mcp2515_pins>, "name=mcp2515_spi2_0_pins", -+ <&clk_mcp2515_osc>, "name=mcp2515-spi2-0-osc"; -+ spi2-1 = <0>, "+6", -+ <&mcp2515_frag>, "target:0=", <&spi2>, -+ <&mcp2515>, "reg:0=1", -+ <&mcp2515_pins>, "name=mcp2515_spi2_1_pins", -+ <&clk_mcp2515_osc>, "name=mcp2515-spi2-1-osc"; -+ spi2-2 = <0>, "+7", -+ <&mcp2515_frag>, "target:0=", <&spi2>, -+ <&mcp2515>, "reg:0=2", -+ <&mcp2515_pins>, "name=mcp2515_spi2_2_pins", -+ <&clk_mcp2515_osc>, "name=mcp2515-spi2-2-osc"; -+ oscillator = <&clk_mcp2515_osc>, "clock-frequency:0"; -+ speed = <&mcp2515>, "spi-max-frequency:0"; -+ interrupt = <&mcp2515_pins>, "brcm,pins:0", -+ <&mcp2515>, "interrupts:0"; -+ }; -+}; diff --git a/target/linux/bcm27xx/patches-5.15/950-0516-regulator-rpi-panel-Remove-get_brightness-hook.patch b/target/linux/bcm27xx/patches-5.15/950-0516-regulator-rpi-panel-Remove-get_brightness-hook.patch deleted file mode 100644 index 81ce24466..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0516-regulator-rpi-panel-Remove-get_brightness-hook.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 7019ea2a7587700e366729872bdec56d54842c8c Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 21 Sep 2021 15:32:50 +0100 -Subject: [PATCH] regulator: rpi-panel: Remove get_brightness hook - -The driver was implementing a get_brightness function that -tried to read back the PWM setting of the display to report -as the current brightness. -The controller on the display does not support that, therefore -we end up reporting a brightness of 0, and that confuses -systemd's backlight service. - -Remove the hook so that the framework returns the current -brightness automatically. - -Signed-off-by: Dave Stevenson ---- - .../regulator/rpi-panel-attiny-regulator.c | 23 ------------------- - 1 file changed, 23 deletions(-) - ---- a/drivers/regulator/rpi-panel-attiny-regulator.c -+++ b/drivers/regulator/rpi-panel-attiny-regulator.c -@@ -207,31 +207,8 @@ static int attiny_update_status(struct b - return ret; - } - --static int attiny_get_brightness(struct backlight_device *bl) --{ -- struct attiny_lcd *state = bl_get_data(bl); -- struct regmap *regmap = state->regmap; -- int ret, brightness, i; -- -- mutex_lock(&state->lock); -- -- for (i = 0; i < 10; i++) { -- ret = regmap_read(regmap, REG_PWM, &brightness); -- if (!ret) -- break; -- } -- -- mutex_unlock(&state->lock); -- -- if (ret) -- return ret; -- -- return brightness; --} -- - static const struct backlight_ops attiny_bl = { - .update_status = attiny_update_status, -- .get_brightness = attiny_get_brightness, - }; - - static int attiny_gpio_get_direction(struct gpio_chip *gc, unsigned int off) diff --git a/target/linux/bcm27xx/patches-5.15/950-0517-bcm2835_smi_dev-Fix-handling-of-word-odd-lengths.patch b/target/linux/bcm27xx/patches-5.15/950-0517-bcm2835_smi_dev-Fix-handling-of-word-odd-lengths.patch deleted file mode 100644 index b0055dfcf..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0517-bcm2835_smi_dev-Fix-handling-of-word-odd-lengths.patch +++ /dev/null @@ -1,91 +0,0 @@ -From 0922abd923ec50f6cc41ded24485bd22c719c7bd Mon Sep 17 00:00:00 2001 -From: madimario -Date: Tue, 28 Sep 2021 04:20:06 -0400 -Subject: [PATCH] bcm2835_smi_dev: Fix handling of word-odd lengths - -The read and write functions did not use the correct pointer offset -when dealing with an odd number of bytes after a DMA transfer. Also, -only handle the remaining odd bytes if the DMA transfer completed -successfully. - -Submitted-by: @madimario (GitHub) -Signed-off-by: Phil Elwell ---- - drivers/char/broadcom/bcm2835_smi_dev.c | 21 ++++++++++++++------- - 1 file changed, 14 insertions(+), 7 deletions(-) - ---- a/drivers/char/broadcom/bcm2835_smi_dev.c -+++ b/drivers/char/broadcom/bcm2835_smi_dev.c -@@ -191,6 +191,7 @@ bcm2835_read_file(struct file *f, char _ - size_t count, loff_t *offs) - { - int odd_bytes; -+ size_t count_check; - - dev_dbg(inst->dev, "User reading %zu bytes from SMI.", count); - /* We don't want to DMA a number of bytes % 4 != 0 (32 bit FIFO) */ -@@ -199,6 +200,7 @@ bcm2835_read_file(struct file *f, char _ - else - odd_bytes = count; - count -= odd_bytes; -+ count_check = count; - if (count) { - struct bcm2835_smi_bounce_info *bounce; - -@@ -209,15 +211,16 @@ bcm2835_read_file(struct file *f, char _ - count = dma_bounce_user(DMA_DEV_TO_MEM, user_ptr, - count, bounce); - } -- if (odd_bytes) { -+ if (odd_bytes && (count == count_check)) { - /* Read from FIFO directly if not using DMA */ - uint8_t buf[DMA_THRESHOLD_BYTES]; -+ unsigned long bytes_not_transferred; - - bcm2835_smi_read_buf(smi_inst, buf, odd_bytes); -- if (copy_to_user(user_ptr, buf, odd_bytes)) -+ bytes_not_transferred = copy_to_user(user_ptr + count, buf, odd_bytes); -+ if (bytes_not_transferred) - dev_err(inst->dev, "copy_to_user() failed."); -- count += odd_bytes; -- -+ count += odd_bytes - bytes_not_transferred; - } - return count; - } -@@ -227,6 +230,7 @@ bcm2835_write_file(struct file *f, const - size_t count, loff_t *offs) - { - int odd_bytes; -+ size_t count_check; - - dev_dbg(inst->dev, "User writing %zu bytes to SMI.", count); - if (count > DMA_THRESHOLD_BYTES) -@@ -234,6 +238,7 @@ bcm2835_write_file(struct file *f, const - else - odd_bytes = count; - count -= odd_bytes; -+ count_check = count; - if (count) { - struct bcm2835_smi_bounce_info *bounce; - -@@ -245,14 +250,16 @@ bcm2835_write_file(struct file *f, const - (char __user *)user_ptr, - count, bounce); - } -- if (odd_bytes) { -+ if (odd_bytes && (count == count_check)) { - uint8_t buf[DMA_THRESHOLD_BYTES]; -+ unsigned long bytes_not_transferred; - -- if (copy_from_user(buf, user_ptr, odd_bytes)) -+ bytes_not_transferred = copy_from_user(buf, user_ptr + count, odd_bytes); -+ if (bytes_not_transferred) - dev_err(inst->dev, "copy_from_user() failed."); - else - bcm2835_smi_write_buf(smi_inst, buf, odd_bytes); -- count += odd_bytes; -+ count += odd_bytes - bytes_not_transferred; - } - return count; - } diff --git a/target/linux/bcm27xx/patches-5.15/950-0518-Revert-mmc-sdhci-iproc-Fix-vmmc-regulators-on-iProc.patch b/target/linux/bcm27xx/patches-5.15/950-0518-Revert-mmc-sdhci-iproc-Fix-vmmc-regulators-on-iProc.patch deleted file mode 100644 index eab5502e7..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0518-Revert-mmc-sdhci-iproc-Fix-vmmc-regulators-on-iProc.patch +++ /dev/null @@ -1,45 +0,0 @@ -From fa836dde1adf33d1c8f6caae9db365f06061b954 Mon Sep 17 00:00:00 2001 -From: Juerg Haefliger -Date: Wed, 29 Sep 2021 11:39:46 +0200 -Subject: [PATCH] Revert "mmc: sdhci-iproc: Fix vmmc regulators on - iProc" - -This reverts commit aed19399a01733dbad9be8bf026a4f7dd823b04f. - -Commit 6c92ae1e452f ("mmc: sdhci: Introduce sdhci_set_power_and_bus_voltage()") -introduced a generic helper that does the same thing so use that instead in -the following commit. - -Signed-off-by: Juerg Haefliger ---- - drivers/mmc/host/sdhci-iproc.c | 12 ------------ - 1 file changed, 12 deletions(-) - ---- a/drivers/mmc/host/sdhci-iproc.c -+++ b/drivers/mmc/host/sdhci-iproc.c -@@ -173,17 +173,6 @@ static unsigned int sdhci_iproc_get_max_ - return pltfm_host->clock; - } - --static void sdhci_iproc_set_power(struct sdhci_host *host, unsigned char mode, -- unsigned short vdd) --{ -- if (!IS_ERR(host->mmc->supply.vmmc)) { -- struct mmc_host *mmc = host->mmc; -- -- mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd); -- } -- sdhci_set_power_noreg(host, mode, vdd); --} -- - /* - * There is a known bug on BCM2711's SDHCI core integration where the - * controller will hang when the difference between the core clock and the bus -@@ -218,7 +207,6 @@ static const struct sdhci_ops sdhci_ipro - .write_b = sdhci_iproc_writeb, - .set_clock = sdhci_set_clock, - .get_max_clock = sdhci_iproc_get_max_clock, -- .set_power = sdhci_iproc_set_power, - .set_bus_width = sdhci_set_bus_width, - .reset = sdhci_reset, - .set_uhs_signaling = sdhci_set_uhs_signaling, diff --git a/target/linux/bcm27xx/patches-5.15/950-0519-mmc-sdhci-iproc-Fix-vmmc-regulators-pre-bcm2711.patch b/target/linux/bcm27xx/patches-5.15/950-0519-mmc-sdhci-iproc-Fix-vmmc-regulators-pre-bcm2711.patch deleted file mode 100644 index 15f225c8e..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0519-mmc-sdhci-iproc-Fix-vmmc-regulators-pre-bcm2711.patch +++ /dev/null @@ -1,28 +0,0 @@ -From dc50e276ae888c06e2daf8549b85dd3ed1765115 Mon Sep 17 00:00:00 2001 -From: Juerg Haefliger -Date: Wed, 29 Sep 2021 11:42:23 +0200 -Subject: [PATCH] mmc: sdhci-iproc: Fix vmmc regulators (pre-bcm2711) - -The Linux support for controlling card power via regulators appears to -be contentious. I would argue that the default behaviour is contrary to -the SDHCI spec - turning off the power writes a reserved value to the -SD Bus Voltage Select field of the Power Control Register, which -seems to kill the Arasan/iProc controller - but fortunately there is a -hook in sdhci_ops to override the behaviour. - -Signed-off-by: Juerg Haefliger -Signed-off-by: Phil Elwell ---- - drivers/mmc/host/sdhci-iproc.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/mmc/host/sdhci-iproc.c -+++ b/drivers/mmc/host/sdhci-iproc.c -@@ -207,6 +207,7 @@ static const struct sdhci_ops sdhci_ipro - .write_b = sdhci_iproc_writeb, - .set_clock = sdhci_set_clock, - .get_max_clock = sdhci_iproc_get_max_clock, -+ .set_power = sdhci_set_power_and_bus_voltage, - .set_bus_width = sdhci_set_bus_width, - .reset = sdhci_reset, - .set_uhs_signaling = sdhci_set_uhs_signaling, diff --git a/target/linux/bcm27xx/patches-5.15/950-0522-media-i2c-imx519-Advertise-embedded-data-node-on-med.patch b/target/linux/bcm27xx/patches-5.15/950-0522-media-i2c-imx519-Advertise-embedded-data-node-on-med.patch deleted file mode 100644 index cc4083343..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0522-media-i2c-imx519-Advertise-embedded-data-node-on-med.patch +++ /dev/null @@ -1,249 +0,0 @@ -From 16a061b6cf7229db782615393f020d723640da69 Mon Sep 17 00:00:00 2001 -From: Arducam -Date: Wed, 15 Sep 2021 09:02:08 +0800 -Subject: [PATCH] media: i2c: imx519: Advertise embedded data node on - media pad 1 - -This commit updates the imx519 driver to adverise support for embedded -data streams. - -The imx519 sensor subdevice overloads the media pad to differentiate -between image stream (pad 0) and embedded data stream (pad 1) when -performing the v4l2_subdev_pad_ops functions. - -Signed-off-by: Lee Jackson ---- - drivers/media/i2c/imx519.c | 138 +++++++++++++++++++++++++++---------- - 1 file changed, 103 insertions(+), 35 deletions(-) - ---- a/drivers/media/i2c/imx519.c -+++ b/drivers/media/i2c/imx519.c -@@ -93,6 +93,16 @@ - #define IMX519_TEST_PATTERN_B_DEFAULT 0 - #define IMX519_TEST_PATTERN_GB_DEFAULT 0 - -+/* Embedded metadata stream structure */ -+#define IMX519_EMBEDDED_LINE_WIDTH 16384 -+#define IMX519_NUM_EMBEDDED_LINES 1 -+ -+enum pad_types { -+ IMAGE_PAD, -+ METADATA_PAD, -+ NUM_PADS -+}; -+ - /* IMX519 native and active pixel array size. */ - #define IMX519_NATIVE_WIDTH 4672U - #define IMX519_NATIVE_HEIGHT 3648U -@@ -970,7 +980,7 @@ static const char * const imx519_supply_ - - struct imx519 { - struct v4l2_subdev sd; -- struct media_pad pad; -+ struct media_pad pad[NUM_PADS]; - - unsigned int fmt_code; - -@@ -1101,7 +1111,9 @@ static int imx519_open(struct v4l2_subde - { - struct imx519 *imx519 = to_imx519(sd); - struct v4l2_mbus_framefmt *try_fmt_img = -- v4l2_subdev_get_try_format(sd, fh->state, 0); -+ v4l2_subdev_get_try_format(sd, fh->state, IMAGE_PAD); -+ struct v4l2_mbus_framefmt *try_fmt_meta = -+ v4l2_subdev_get_try_format(sd, fh->state, METADATA_PAD); - struct v4l2_rect *try_crop; - - mutex_lock(&imx519->mutex); -@@ -1112,8 +1124,14 @@ static int imx519_open(struct v4l2_subde - try_fmt_img->code = imx519_get_format_code(imx519); - try_fmt_img->field = V4L2_FIELD_NONE; - -+ /* Initialize try_fmt for the embedded metadata pad */ -+ try_fmt_meta->width = IMX519_EMBEDDED_LINE_WIDTH; -+ try_fmt_meta->height = IMX519_NUM_EMBEDDED_LINES; -+ try_fmt_meta->code = MEDIA_BUS_FMT_SENSOR_DATA; -+ try_fmt_meta->field = V4L2_FIELD_NONE; -+ - /* Initialize try_crop */ -- try_crop = v4l2_subdev_get_try_crop(sd, fh->state, 0); -+ try_crop = v4l2_subdev_get_try_crop(sd, fh->state, IMAGE_PAD); - try_crop->left = IMX519_PIXEL_ARRAY_LEFT; - try_crop->top = IMX519_PIXEL_ARRAY_TOP; - try_crop->width = IMX519_PIXEL_ARRAY_WIDTH; -@@ -1246,10 +1264,20 @@ static int imx519_enum_mbus_code(struct - { - struct imx519 *imx519 = to_imx519(sd); - -- if (code->index > 0) -+ if (code->pad >= NUM_PADS) - return -EINVAL; - -- code->code = imx519_get_format_code(imx519); -+ if (code->pad == IMAGE_PAD) { -+ if (code->index > 0) -+ return -EINVAL; -+ -+ code->code = imx519_get_format_code(imx519); -+ } else { -+ if (code->index > 0) -+ return -EINVAL; -+ -+ code->code = MEDIA_BUS_FMT_SENSOR_DATA; -+ } - - return 0; - } -@@ -1260,16 +1288,29 @@ static int imx519_enum_frame_size(struct - { - struct imx519 *imx519 = to_imx519(sd); - -- if (fse->index >= ARRAY_SIZE(supported_modes_10bit)) -+ if (fse->pad >= NUM_PADS) - return -EINVAL; - -- if (fse->code != imx519_get_format_code(imx519)) -- return -EINVAL; -+ if (fse->pad == IMAGE_PAD) { -+ if (fse->index >= ARRAY_SIZE(supported_modes_10bit)) -+ return -EINVAL; -+ -+ if (fse->code != imx519_get_format_code(imx519)) -+ return -EINVAL; -+ -+ fse->min_width = supported_modes_10bit[fse->index].width; -+ fse->max_width = fse->min_width; -+ fse->min_height = supported_modes_10bit[fse->index].height; -+ fse->max_height = fse->min_height; -+ } else { -+ if (fse->code != MEDIA_BUS_FMT_SENSOR_DATA || fse->index > 0) -+ return -EINVAL; - -- fse->min_width = supported_modes_10bit[fse->index].width; -- fse->max_width = fse->min_width; -- fse->min_height = supported_modes_10bit[fse->index].height; -- fse->max_height = fse->min_height; -+ fse->min_width = IMX519_EMBEDDED_LINE_WIDTH; -+ fse->max_width = fse->min_width; -+ fse->min_height = IMX519_NUM_EMBEDDED_LINES; -+ fse->max_height = fse->min_height; -+ } - - return 0; - } -@@ -1294,13 +1335,21 @@ static void imx519_update_image_pad_form - imx519_reset_colorspace(&fmt->format); - } - -+static void imx519_update_metadata_pad_format(struct v4l2_subdev_format *fmt) -+{ -+ fmt->format.width = IMX519_EMBEDDED_LINE_WIDTH; -+ fmt->format.height = IMX519_NUM_EMBEDDED_LINES; -+ fmt->format.code = MEDIA_BUS_FMT_SENSOR_DATA; -+ fmt->format.field = V4L2_FIELD_NONE; -+} -+ - static int imx519_get_pad_format(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_format *fmt) - { - struct imx519 *imx519 = to_imx519(sd); - -- if (fmt->pad != 0) -+ if (fmt->pad >= NUM_PADS) - return -EINVAL; - - mutex_lock(&imx519->mutex); -@@ -1310,12 +1359,19 @@ static int imx519_get_pad_format(struct - v4l2_subdev_get_try_format(&imx519->sd, sd_state, - fmt->pad); - /* update the code which could change due to vflip or hflip: */ -- try_fmt->code = imx519_get_format_code(imx519); -+ try_fmt->code = fmt->pad == IMAGE_PAD ? -+ imx519_get_format_code(imx519) : -+ MEDIA_BUS_FMT_SENSOR_DATA; - fmt->format = *try_fmt; - } else { -- imx519_update_image_pad_format(imx519, imx519->mode, -- fmt); -- fmt->format.code = imx519_get_format_code(imx519); -+ if (fmt->pad == IMAGE_PAD) { -+ imx519_update_image_pad_format(imx519, imx519->mode, -+ fmt); -+ fmt->format.code = -+ imx519_get_format_code(imx519); -+ } else { -+ imx519_update_metadata_pad_format(fmt); -+ } - } - - mutex_unlock(&imx519->mutex); -@@ -1376,28 +1432,39 @@ static int imx519_set_pad_format(struct - const struct imx519_mode *mode; - struct imx519 *imx519 = to_imx519(sd); - -- if (fmt->pad != 0) -+ if (fmt->pad >= NUM_PADS) - return -EINVAL; - - mutex_lock(&imx519->mutex); - -- /* Bayer order varies with flips */ -- fmt->format.code = imx519_get_format_code(imx519); -+ if (fmt->pad == IMAGE_PAD) { -+ /* Bayer order varies with flips */ -+ fmt->format.code = imx519_get_format_code(imx519); - -- mode = v4l2_find_nearest_size(supported_modes_10bit, -- ARRAY_SIZE(supported_modes_10bit), -- width, height, -- fmt->format.width, -- fmt->format.height); -- imx519_update_image_pad_format(imx519, mode, fmt); -- if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { -- framefmt = v4l2_subdev_get_try_format(sd, sd_state, -- fmt->pad); -- *framefmt = fmt->format; -+ mode = v4l2_find_nearest_size(supported_modes_10bit, -+ ARRAY_SIZE(supported_modes_10bit), -+ width, height, -+ fmt->format.width, -+ fmt->format.height); -+ imx519_update_image_pad_format(imx519, mode, fmt); -+ if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { -+ framefmt = v4l2_subdev_get_try_format(sd, sd_state, -+ fmt->pad); -+ *framefmt = fmt->format; -+ } else { -+ imx519->mode = mode; -+ imx519->fmt_code = fmt->format.code; -+ imx519_set_framing_limits(imx519); -+ } - } else { -- imx519->mode = mode; -- imx519->fmt_code = fmt->format.code; -- imx519_set_framing_limits(imx519); -+ if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { -+ framefmt = v4l2_subdev_get_try_format(sd, sd_state, -+ fmt->pad); -+ *framefmt = fmt->format; -+ } else { -+ /* Only one embedded data mode is supported */ -+ imx519_update_metadata_pad_format(fmt); -+ } - } - - mutex_unlock(&imx519->mutex); -@@ -1953,9 +2020,10 @@ static int imx519_probe(struct i2c_clien - imx519->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; - - /* Initialize source pads */ -- imx519->pad.flags = MEDIA_PAD_FL_SOURCE; -+ imx519->pad[IMAGE_PAD].flags = MEDIA_PAD_FL_SOURCE; -+ imx519->pad[METADATA_PAD].flags = MEDIA_PAD_FL_SOURCE; - -- ret = media_entity_pads_init(&imx519->sd.entity, 1, &imx519->pad); -+ ret = media_entity_pads_init(&imx519->sd.entity, NUM_PADS, imx519->pad); - if (ret) { - dev_err(dev, "failed to init entity pads: %d\n", ret); - goto error_handler_free; diff --git a/target/linux/bcm27xx/patches-5.15/950-0523-overlays-Add-imx519-overlay.dts.patch b/target/linux/bcm27xx/patches-5.15/950-0523-overlays-Add-imx519-overlay.dts.patch deleted file mode 100644 index bf13523b6..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0523-overlays-Add-imx519-overlay.dts.patch +++ /dev/null @@ -1,164 +0,0 @@ -From d8faff7e7581ee3417675e2f64da18ffb831751a Mon Sep 17 00:00:00 2001 -From: Lee Jackson -Date: Fri, 27 Aug 2021 14:45:43 +0800 -Subject: [PATCH] overlays: Add imx519-overlay.dts - -Added overlays for enabling IMX519 and add the -relevant information to the README. - -Signed-off-by: Lee Jackson ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 11 ++ - arch/arm/boot/dts/overlays/imx519-overlay.dts | 115 ++++++++++++++++++ - 3 files changed, 127 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/imx519-overlay.dts - ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -98,6 +98,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ - imx290.dtbo \ - imx378.dtbo \ - imx477.dtbo \ -+ imx519.dtbo \ - iqaudio-codec.dtbo \ - iqaudio-dac.dtbo \ - iqaudio-dacplus.dtbo \ ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -1738,6 +1738,17 @@ Params: rotation Mounting - 2 = external, default external) - - -+Name: imx519 -+Info: Sony IMX519 camera module. -+ Uses Unicam 1, which is the standard camera connector on most Pi -+ variants. -+Load: dtoverlay=imx519,= -+Params: rotation Mounting rotation of the camera sensor (0 or -+ 180, default 0) -+ orientation Sensor orientation (0 = front, 1 = rear, -+ 2 = external, default external) -+ -+ - Name: iqaudio-codec - Info: Configures the IQaudio Codec audio card - Load: dtoverlay=iqaudio-codec ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/imx519-overlay.dts -@@ -0,0 +1,115 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+// Definitions for imx519 camera module on VC I2C bus -+/dts-v1/; -+/plugin/; -+ -+#include -+ -+/{ -+ compatible = "brcm,bcm2835"; -+ -+ fragment@0 { -+ target = <&i2c_csi_dsi>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ imx519: imx519@1a { -+ compatible = "sony,imx519"; -+ reg = <0x1a>; -+ status = "okay"; -+ -+ clocks = <&imx519_clk>; -+ clock-names = "xclk"; -+ -+ VANA-supply = <&cam1_reg>; /* 2.8v */ -+ VDIG-supply = <&imx519_vdig>; /* 1.8v */ -+ VDDL-supply = <&imx519_vddl>; /* 1.2v */ -+ -+ rotation = <0>; -+ orientation = <2>; -+ -+ port { -+ imx519_0: endpoint { -+ remote-endpoint = <&csi1_ep>; -+ clock-lanes = <0>; -+ data-lanes = <1 2>; -+ clock-noncontinuous; -+ link-frequencies = -+ /bits/ 64 <493500000>; -+ }; -+ }; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&csi1>; -+ __overlay__ { -+ status = "okay"; -+ -+ port{ -+ csi1_ep: endpoint{ -+ remote-endpoint = <&imx519_0>; -+ clock-lanes = <0>; -+ data-lanes = <1 2>; -+ clock-noncontinuous; -+ }; -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&i2c0if>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@3 { -+ target-path="/"; -+ __overlay__ { -+ imx519_vdig: fixedregulator@1 { -+ compatible = "regulator-fixed"; -+ regulator-name = "imx519_vdig"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ }; -+ imx519_vddl: fixedregulator@2 { -+ compatible = "regulator-fixed"; -+ regulator-name = "imx519_vddl"; -+ regulator-min-microvolt = <1200000>; -+ regulator-max-microvolt = <1200000>; -+ }; -+ -+ imx519_clk: camera-clk { -+ compatible = "fixed-clock"; -+ #clock-cells = <0>; -+ clock-frequency = <24000000>; -+ }; -+ }; -+ }; -+ -+ fragment@4 { -+ target = <&i2c0mux>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@5 { -+ target = <&cam1_reg>; -+ __overlay__ { -+ status = "okay"; -+ regulator-name = "imx519_vana"; -+ regulator-min-microvolt = <2800000>; -+ regulator-max-microvolt = <2800000>; -+ }; -+ }; -+ -+ __overrides__ { -+ rotation = <&imx519>,"rotation:0"; -+ orientation = <&imx519>,"orientation:0"; -+ }; -+}; diff --git a/target/linux/bcm27xx/patches-5.15/950-0524-dtoverlays-Add-overlay-for-ST7735R-160x128-TinyDRM-d.patch b/target/linux/bcm27xx/patches-5.15/950-0524-dtoverlays-Add-overlay-for-ST7735R-160x128-TinyDRM-d.patch deleted file mode 100644 index 987bdee29..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0524-dtoverlays-Add-overlay-for-ST7735R-160x128-TinyDRM-d.patch +++ /dev/null @@ -1,140 +0,0 @@ -From 67cd4f249333f3de9b449b9e6ebadd08facc6957 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 4 Oct 2021 14:15:38 +0100 -Subject: [PATCH] dtoverlays: Add overlay for ST7735R (160x128) TinyDRM - driver - -Adds an overlay to configure the TinyDRM driver for ST7735R -based 160x128 and 128x128 (untested) displays such as the -Adafruit 1.8" display. - -Signed-off-by: Dave Stevenson ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 14 ++++ - .../dts/overlays/adafruit-st7735r-overlay.dts | 83 +++++++++++++++++++ - 3 files changed, 98 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/adafruit-st7735r-overlay.dts - ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -4,6 +4,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += overlay_ma - - dtbo-$(CONFIG_ARCH_BCM2835) += \ - act-led.dtbo \ -+ adafruit-st7735r.dtbo \ - adafruit18.dtbo \ - adau1977-adc.dtbo \ - adau7002-simple.dtbo \ ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -299,9 +299,23 @@ Params: activelow Set to " - REQUIRED - - -+Name: adafruit-st7735r -+Info: Overlay for the SPI-connected Adafruit 1.8" 160x128 or 128x128 displays, -+ based on the ST7735R chip. -+ This overlay uses the newer DRM/KMS "Tiny" driver. -+Load: dtoverlay=adafruit-st7735r,= -+Params: 128x128 Select the 128x128 driver (default 160x128) -+ rotate Display rotation {0,90,180,270} (default 90) -+ speed SPI bus speed in Hz (default 4000000) -+ dc_pin GPIO pin for D/C (default 24) -+ reset_pin GPIO pin for RESET (default 25) -+ led_pin GPIO used to control backlight (default 18) -+ -+ - Name: adafruit18 - Info: Overlay for the SPI-connected Adafruit 1.8" display (based on the - ST7735R chip). It includes support for the "green tab" version. -+ This overlay uses the older fbtft driver. - Load: dtoverlay=adafruit18,= - Params: green Use the adafruit18_green variant. - rotate Display rotation {0,90,180,270} ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/adafruit-st7735r-overlay.dts -@@ -0,0 +1,83 @@ -+/* -+ * adafruit-st7735r-overlay.dts -+ * -+ * ST7735R based SPI LCD displays. Either -+ * Adafruit 1.8" 160x128 -+ * or -+ * Okaya 1.44" 128x128 -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+#include -+ -+/ { -+ compatible = "brcm,bcm2835"; -+ -+ fragment@0 { -+ target = <&spidev0>; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ adafruit_pins: adafruit_pins { -+ brcm,pins = <25 24>; -+ brcm,function = <1>; /* out */ -+ }; -+ backlight_pins: backlight_pins { -+ brcm,pins = <18>; -+ brcm,function = <1>; /* out */ -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target-path = "/"; -+ __overlay__ { -+ af18_backlight: backlight { -+ compatible = "gpio-backlight"; -+ gpios = <&gpio 18 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&backlight_pins>; -+ }; -+ }; -+ }; -+ -+ fragment@3 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ af18: adafruit18@0 { -+ compatible = "jianda,jd-t18003-t01"; -+ reg = <0>; -+ spi-max-frequency = <32000000>; -+ dc-gpios = <&gpio 24 GPIO_ACTIVE_HIGH>; -+ reset-gpios = <&gpio 25 GPIO_ACTIVE_HIGH>; -+ rotate = <90>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&adafruit_pins>; -+ backlight = <&af18_backlight>; -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ 128x128 = <&af18>, "compatible=okaya,rh128128t"; -+ speed = <&af18>,"spi-max-frequency:0"; -+ rotate = <&af18>,"rotate:0"; -+ dc_pin = <&af18>,"dc-gpios:4", <&adafruit_pins>,"brcm,pins:4"; -+ reset_pin = <&af18>,"reset-gpios:4", -+ <&adafruit_pins>,"brcm,pins:0"; -+ led_pin = <&af18_backlight>,"gpios:4", -+ <&backlight_pins>,"brcm,pins:0"; -+ }; -+}; diff --git a/target/linux/bcm27xx/patches-5.15/950-0525-dwc_otg-pay-attention-to-qh-interval-when-rescheduli.patch b/target/linux/bcm27xx/patches-5.15/950-0525-dwc_otg-pay-attention-to-qh-interval-when-rescheduli.patch deleted file mode 100644 index 9e1cb110d..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0525-dwc_otg-pay-attention-to-qh-interval-when-rescheduli.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 4e27de0597024fd7070c04a1bf0af82f1be77191 Mon Sep 17 00:00:00 2001 -From: Jonathan Bell -Date: Wed, 6 Oct 2021 15:27:53 +0100 -Subject: [PATCH] dwc_otg: pay attention to qh->interval when - rescheduling periodic queues - -A regression introduced in https://github.com/raspberrypi/linux/pull/3887 -meant that if the newly scheduled transfer immediately returned data, and -the driver resubmitted a single URB after every transfer, then the effective -polling interval would end up being approx 1ms. - -Use the larger of SCHEDULE_SLOP or the configured endpoint interval. - -Signed-off-by: Jonathan Bell ---- - drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c -@@ -691,7 +691,7 @@ int dwc_otg_hcd_qh_add(dwc_otg_hcd_t * h - } else { - /* If the QH wasn't in a schedule, then sched_frame is stale. */ - qh->sched_frame = dwc_frame_num_inc(dwc_otg_hcd_get_frame_number(hcd), -- SCHEDULE_SLOP); -+ max_t(uint32_t, qh->interval, SCHEDULE_SLOP)); - status = schedule_periodic(hcd, qh); - qh->start_split_frame = qh->sched_frame; - if ( !hcd->periodic_qh_count ) { diff --git a/target/linux/bcm27xx/patches-5.15/950-0526-Hifiberry-DAC-ADCPro-DT-overlay-add-optional-headpho.patch b/target/linux/bcm27xx/patches-5.15/950-0526-Hifiberry-DAC-ADCPro-DT-overlay-add-optional-headpho.patch deleted file mode 100644 index eff85e125..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0526-Hifiberry-DAC-ADCPro-DT-overlay-add-optional-headpho.patch +++ /dev/null @@ -1,29 +0,0 @@ -From b1a85e3d9bdb3cc4d850b110ce08331fbc8e9172 Mon Sep 17 00:00:00 2001 -From: Joerg Schambacher -Date: Wed, 6 Oct 2021 17:19:58 +0200 -Subject: [PATCH] Hifiberry DAC+ADCPro DT overlay: add optional - headphone amp - -This is a copy of the approach from our DAC+ driver. -It allows to probe (and activate) an optional TPA6130A2 headphone -amplifier. - -Signed-off-by: Joerg Schambacher ---- - .../boot/dts/overlays/hifiberry-dacplusadcpro-overlay.dts | 5 +++++ - 1 file changed, 5 insertions(+) - ---- a/arch/arm/boot/dts/overlays/hifiberry-dacplusadcpro-overlay.dts -+++ b/arch/arm/boot/dts/overlays/hifiberry-dacplusadcpro-overlay.dts -@@ -43,6 +43,11 @@ - clocks = <&dacpro_osc>; - status = "okay"; - }; -+ hpamp: hpamp@60 { -+ compatible = "ti,tpa6130a2"; -+ reg = <0x60>; -+ status = "disabled"; -+ }; - }; - }; - diff --git a/target/linux/bcm27xx/patches-5.15/950-0527-Hifiberry-DAC-ADCPro-adding-optional-headphone-amp-c.patch b/target/linux/bcm27xx/patches-5.15/950-0527-Hifiberry-DAC-ADCPro-adding-optional-headphone-amp-c.patch deleted file mode 100644 index 02a60a13e..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0527-Hifiberry-DAC-ADCPro-adding-optional-headphone-amp-c.patch +++ /dev/null @@ -1,143 +0,0 @@ -From 74de23a947ad5964b25e9f9f15329d3174488fea Mon Sep 17 00:00:00 2001 -From: Joerg Schambacher -Date: Wed, 6 Oct 2021 17:21:07 +0200 -Subject: [PATCH] Hifiberry DAC+ADCPro: adding optional headphone amp - control - -This is a copy of the code and approach from our DAC+ driver. -It allows to probe (and activate) an optional TPA6130A2 headphone -amplifier. Updated email address. - -Signed-off-by: Joerg Schambacher ---- - sound/soc/bcm/Kconfig | 3 +- - sound/soc/bcm/hifiberry_dacplusadcpro.c | 74 ++++++++++++++++++++++++- - 2 files changed, 73 insertions(+), 4 deletions(-) - ---- a/sound/soc/bcm/Kconfig -+++ b/sound/soc/bcm/Kconfig -@@ -79,7 +79,8 @@ config SND_BCM2708_SOC_HIFIBERRY_DACPLUS - tristate "Support for HifiBerry DAC+ADC PRO" - depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S - select SND_SOC_PCM512x_I2C -- select SND_SOC_PCM186X_I2C -+ select SND_SOC_PCM186X_I2C -+ select SND_SOC_TPA6130A2 - select COMMON_CLK_HIFIBERRY_DACPRO - help - Say Y or M if you want to add support for HifiBerry DAC+ADC PRO. ---- a/sound/soc/bcm/hifiberry_dacplusadcpro.c -+++ b/sound/soc/bcm/hifiberry_dacplusadcpro.c -@@ -4,8 +4,8 @@ - * Author: Daniel Matuschek, Stuart MacLean - * Copyright 2014-2015 - * based on code by Florian Meier -- * ADC added by Joerg Schambacher -- * Copyright 2018-19 -+ * ADC, HP added by Joerg Schambacher -+ * Copyright 2018-21 - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License -@@ -26,6 +26,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -468,6 +469,15 @@ static struct snd_soc_dai_link snd_rpi_h - }, - }; - -+/* aux device for optional headphone amp */ -+static struct snd_soc_aux_dev hifiberry_dacplusadcpro_aux_devs[] = { -+ { -+ .dlc = { -+ .name = "tpa6130a2.1-0060", -+ }, -+ }, -+}; -+ - /* audio machine driver */ - static struct snd_soc_card snd_rpi_hifiberry_dacplusadcpro = { - .name = "snd_rpi_hifiberry_dacplusadcpro", -@@ -477,10 +487,68 @@ static struct snd_soc_card snd_rpi_hifib - .num_links = ARRAY_SIZE(snd_rpi_hifiberry_dacplusadcpro_dai), - }; - -+static int hb_hp_detect(void) -+{ -+ struct i2c_adapter *adap = i2c_get_adapter(1); -+ int ret; -+ struct i2c_client tpa_i2c_client = { -+ .addr = 0x60, -+ .adapter = adap, -+ }; -+ -+ if (!adap) -+ return -EPROBE_DEFER; /* I2C module not yet available */ -+ -+ ret = i2c_smbus_read_byte(&tpa_i2c_client) >= 0; -+ i2c_put_adapter(adap); -+ return ret; -+}; -+ -+static struct property tpa_enable_prop = { -+ .name = "status", -+ .length = 4 + 1, /* length 'okay' + 1 */ -+ .value = "okay", -+ }; -+ - static int snd_rpi_hifiberry_dacplusadcpro_probe(struct platform_device *pdev) - { - int ret = 0, i = 0; - struct snd_soc_card *card = &snd_rpi_hifiberry_dacplusadcpro; -+ struct device_node *tpa_node; -+ struct property *tpa_prop; -+ struct of_changeset ocs; -+ int len; -+ -+ /* probe for head phone amp */ -+ ret = hb_hp_detect(); -+ if (ret < 0) -+ return ret; -+ if (ret) { -+ card->aux_dev = hifiberry_dacplusadcpro_aux_devs; -+ card->num_aux_devs = -+ ARRAY_SIZE(hifiberry_dacplusadcpro_aux_devs); -+ tpa_node = of_find_compatible_node(NULL, NULL, "ti,tpa6130a2"); -+ tpa_prop = of_find_property(tpa_node, "status", &len); -+ -+ if (strcmp((char *)tpa_prop->value, "okay")) { -+ /* and activate headphone using change_sets */ -+ dev_info(&pdev->dev, "activating headphone amplifier"); -+ of_changeset_init(&ocs); -+ ret = of_changeset_update_property(&ocs, tpa_node, -+ &tpa_enable_prop); -+ if (ret) { -+ dev_err(&pdev->dev, -+ "cannot activate headphone amplifier\n"); -+ return -ENODEV; -+ } -+ ret = of_changeset_apply(&ocs); -+ if (ret) { -+ dev_err(&pdev->dev, -+ "cannot activate headphone amplifier\n"); -+ return -ENODEV; -+ } -+ } -+ } - - snd_rpi_hifiberry_dacplusadcpro.dev = &pdev->dev; - if (pdev->dev.of_node) { -@@ -531,7 +599,7 @@ static struct platform_driver snd_rpi_hi - - module_platform_driver(snd_rpi_hifiberry_dacplusadcpro_driver); - --MODULE_AUTHOR("Joerg Schambacher "); -+MODULE_AUTHOR("Joerg Schambacher "); - MODULE_AUTHOR("Daniel Matuschek "); - MODULE_DESCRIPTION("ASoC Driver for HiFiBerry DAC+ADC"); - MODULE_LICENSE("GPL v2"); diff --git a/target/linux/bcm27xx/patches-5.15/950-0529-rtc-pcf85063-Always-clear-EXT_TEST-from-set_time.patch b/target/linux/bcm27xx/patches-5.15/950-0529-rtc-pcf85063-Always-clear-EXT_TEST-from-set_time.patch deleted file mode 100644 index e8a6b4182..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0529-rtc-pcf85063-Always-clear-EXT_TEST-from-set_time.patch +++ /dev/null @@ -1,36 +0,0 @@ -From c3cfd27eb16d2fc12cfa77e6cd5f9eb352403c16 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 15 Oct 2021 11:45:36 +0100 -Subject: [PATCH] rtc: pcf85063: Always clear EXT_TEST from set_time - -Power-on reset after the insertion of a battery does not always complete -successfully, leading to corrupted register content. The EXT_TEST bit -will stop the clock from running, but currently the driver will never -recover. - -Safely handle the erroneous state by clearing EXT_TEST as part of the -usual set_time method. - -Signed-off-by: Phil Elwell ---- - drivers/rtc/rtc-pcf85063.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/rtc/rtc-pcf85063.c -+++ b/drivers/rtc/rtc-pcf85063.c -@@ -34,6 +34,7 @@ - #define PCF85063_REG_CTRL1 0x00 /* status */ - #define PCF85063_REG_CTRL1_CAP_SEL BIT(0) - #define PCF85063_REG_CTRL1_STOP BIT(5) -+#define PCF85063_REG_CTRL1_EXT_TEST BIT(7) - - #define PCF85063_REG_CTRL2 0x01 - #define PCF85063_CTRL2_AF BIT(6) -@@ -117,6 +118,7 @@ static int pcf85063_rtc_set_time(struct - * reset state until all time/date registers are written - */ - rc = regmap_update_bits(pcf85063->regmap, PCF85063_REG_CTRL1, -+ PCF85063_REG_CTRL1_EXT_TEST | - PCF85063_REG_CTRL1_STOP, - PCF85063_REG_CTRL1_STOP); - if (rc) diff --git a/target/linux/bcm27xx/patches-5.15/950-0530-char-vcio-Rewrite-as-a-firmware-node-child.patch b/target/linux/bcm27xx/patches-5.15/950-0530-char-vcio-Rewrite-as-a-firmware-node-child.patch deleted file mode 100644 index 88596312f..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0530-char-vcio-Rewrite-as-a-firmware-node-child.patch +++ /dev/null @@ -1,237 +0,0 @@ -From 512d9fadc272271e1e8e9bc81d445883940f81ca Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 11 Oct 2021 17:33:05 +0100 -Subject: [PATCH] char: vcio: Rewrite as a firmware node child - -The old vcio driver is a simple character device that manually locates -the firmware driver. Initialising it before the firmware driver causes -a failure, and no retries are attempted. - -Rewrite vcio as a platform driver that depends on a DT node for its -instantiation and the location of the firmware driver, making use of -the miscdevice framework to reduce the code size. - -N.B. Using miscdevice changes the udev SUBSYSTEM string, so a change -to the companion udev rule is required in order to continue to set -the correct device permissions, e.g.: - - KERNEL="vcio", GROUP="video", MODE="0660" - -See: https://github.com/raspberrypi/linux/issues/4620 - -Signed-off-by: Phil Elwell ---- - drivers/char/broadcom/vcio.c | 133 ++++++++++++++++------------------- - 1 file changed, 62 insertions(+), 71 deletions(-) - ---- a/drivers/char/broadcom/vcio.c -+++ b/drivers/char/broadcom/vcio.c -@@ -1,6 +1,7 @@ - /* - * Copyright (C) 2010 Broadcom - * Copyright (C) 2015 Noralf Trønnes -+ * Copyright (C) 2021 Raspberry Pi (Trading) Ltd. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as -@@ -8,8 +9,6 @@ - * - */ - --#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -- - #include - #include - #include -@@ -19,24 +18,22 @@ - #include - #include - #include -+#include - #include - --#define MBOX_CHAN_PROPERTY 8 -- -+#define MODULE_NAME "vcio" - #define VCIO_IOC_MAGIC 100 - #define IOCTL_MBOX_PROPERTY _IOWR(VCIO_IOC_MAGIC, 0, char *) - #ifdef CONFIG_COMPAT - #define IOCTL_MBOX_PROPERTY32 _IOWR(VCIO_IOC_MAGIC, 0, compat_uptr_t) - #endif - --static struct { -- dev_t devt; -- struct cdev cdev; -- struct class *class; -+struct vcio_data { - struct rpi_firmware *fw; --} vcio; -+ struct miscdevice misc_dev; -+}; - --static int vcio_user_property_list(void *user) -+static int vcio_user_property_list(struct vcio_data *vcio, void *user) - { - u32 *buf, size; - int ret; -@@ -55,7 +52,7 @@ static int vcio_user_property_list(void - } - - /* Strip off protocol encapsulation */ -- ret = rpi_firmware_property_list(vcio.fw, &buf[2], size - 12); -+ ret = rpi_firmware_property_list(vcio->fw, &buf[2], size - 12); - if (ret) { - kfree(buf); - return ret; -@@ -87,9 +84,12 @@ static int vcio_device_release(struct in - static long vcio_device_ioctl(struct file *file, unsigned int ioctl_num, - unsigned long ioctl_param) - { -+ struct vcio_data *vcio = container_of(file->private_data, -+ struct vcio_data, misc_dev); -+ - switch (ioctl_num) { - case IOCTL_MBOX_PROPERTY: -- return vcio_user_property_list((void *)ioctl_param); -+ return vcio_user_property_list(vcio, (void *)ioctl_param); - default: - pr_err("unknown ioctl: %x\n", ioctl_num); - return -EINVAL; -@@ -100,9 +100,12 @@ static long vcio_device_ioctl(struct fil - static long vcio_device_compat_ioctl(struct file *file, unsigned int ioctl_num, - unsigned long ioctl_param) - { -+ struct vcio_data *vcio = container_of(file->private_data, -+ struct vcio_data, misc_dev); -+ - switch (ioctl_num) { - case IOCTL_MBOX_PROPERTY32: -- return vcio_user_property_list(compat_ptr(ioctl_param)); -+ return vcio_user_property_list(vcio, compat_ptr(ioctl_param)); - default: - pr_err("unknown ioctl: %x\n", ioctl_num); - return -EINVAL; -@@ -119,77 +122,65 @@ const struct file_operations vcio_fops = - .release = vcio_device_release, - }; - --static int __init vcio_init(void) -+static int vcio_probe(struct platform_device *pdev) - { -- struct device_node *np; -- static struct device *dev; -- int ret; -- -- np = of_find_compatible_node(NULL, NULL, -- "raspberrypi,bcm2835-firmware"); -- if (!of_device_is_available(np)) -- return -ENODEV; -- -- vcio.fw = rpi_firmware_get(np); -- if (!vcio.fw) -- return -ENODEV; -- -- ret = alloc_chrdev_region(&vcio.devt, 0, 1, "vcio"); -- if (ret) { -- pr_err("failed to allocate device number\n"); -- return ret; -- } -- -- cdev_init(&vcio.cdev, &vcio_fops); -- vcio.cdev.owner = THIS_MODULE; -- ret = cdev_add(&vcio.cdev, vcio.devt, 1); -- if (ret) { -- pr_err("failed to register device\n"); -- goto err_unregister_chardev; -- } -+ struct device *dev = &pdev->dev; -+ struct device_node *np = dev->of_node; -+ struct device_node *fw_node; -+ struct rpi_firmware *fw; -+ struct vcio_data *vcio; - -- /* -- * Create sysfs entries -- * 'bcm2708_vcio' is used for backwards compatibility so we don't break -- * userspace. Raspian has a udev rule that changes the permissions. -- */ -- vcio.class = class_create(THIS_MODULE, "bcm2708_vcio"); -- if (IS_ERR(vcio.class)) { -- ret = PTR_ERR(vcio.class); -- pr_err("failed to create class\n"); -- goto err_cdev_del; -+ fw_node = of_get_parent(np); -+ if (!fw_node) { -+ dev_err(dev, "Missing firmware node\n"); -+ return -ENOENT; - } - -- dev = device_create(vcio.class, NULL, vcio.devt, NULL, "vcio"); -- if (IS_ERR(dev)) { -- ret = PTR_ERR(dev); -- pr_err("failed to create device\n"); -- goto err_class_destroy; -- } -+ fw = rpi_firmware_get(fw_node); -+ of_node_put(fw_node); -+ if (!fw) -+ return -EPROBE_DEFER; - -- return 0; -+ vcio = devm_kzalloc(dev, sizeof(struct vcio_data), GFP_KERNEL); -+ if (!vcio) -+ return -ENOMEM; - --err_class_destroy: -- class_destroy(vcio.class); --err_cdev_del: -- cdev_del(&vcio.cdev); --err_unregister_chardev: -- unregister_chrdev_region(vcio.devt, 1); -+ vcio->fw = fw; -+ vcio->misc_dev.fops = &vcio_fops; -+ vcio->misc_dev.minor = MISC_DYNAMIC_MINOR; -+ vcio->misc_dev.name = "vcio"; -+ vcio->misc_dev.parent = dev; - -- return ret; -+ return misc_register(&vcio->misc_dev); - } --module_init(vcio_init); - --static void __exit vcio_exit(void) -+static int vcio_remove(struct platform_device *pdev) - { -- device_destroy(vcio.class, vcio.devt); -- class_destroy(vcio.class); -- cdev_del(&vcio.cdev); -- unregister_chrdev_region(vcio.devt, 1); -+ struct device *dev = &pdev->dev; -+ -+ misc_deregister(dev_get_drvdata(dev)); -+ return 0; - } --module_exit(vcio_exit); -+ -+static const struct of_device_id vcio_ids[] = { -+ { .compatible = "raspberrypi,vcio" }, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, vcio_ids); -+ -+static struct platform_driver vcio_driver = { -+ .driver = { -+ .name = MODULE_NAME, -+ .of_match_table = of_match_ptr(vcio_ids), -+ }, -+ .probe = vcio_probe, -+ .remove = vcio_remove, -+}; -+ -+module_platform_driver(vcio_driver); - - MODULE_AUTHOR("Gray Girling"); - MODULE_AUTHOR("Noralf Trønnes"); - MODULE_DESCRIPTION("Mailbox userspace access"); - MODULE_LICENSE("GPL"); -+MODULE_ALIAS("platform:rpi-vcio"); diff --git a/target/linux/bcm27xx/patches-5.15/950-0531-ARM-dts-Make-vcio-a-child-of-the-firmware-node.patch b/target/linux/bcm27xx/patches-5.15/950-0531-ARM-dts-Make-vcio-a-child-of-the-firmware-node.patch deleted file mode 100644 index c1adbb8df..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0531-ARM-dts-Make-vcio-a-child-of-the-firmware-node.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 52186b585d8834085c14fc088f1a36cd6184365c Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 12 Oct 2021 09:59:54 +0100 -Subject: [PATCH] ARM: dts: Make vcio a child of the firmware node - -In order to resolve a potential startup order bug, the vcio driver has -been rewritten as a platform driver that depends on a DT node for -its instantiation and to locate the firmware driver. - -Add that DT node. - -See: https://github.com/raspberrypi/linux/issues/4620 - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/bcm270x-rpi.dtsi | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- a/arch/arm/boot/dts/bcm270x-rpi.dtsi -+++ b/arch/arm/boot/dts/bcm270x-rpi.dtsi -@@ -152,3 +152,9 @@ - status = "disabled"; - }; - }; -+ -+&firmware { -+ vcio: vcio { -+ compatible = "raspberrypi,vcio"; -+ }; -+}; diff --git a/target/linux/bcm27xx/patches-5.15/950-0532-ARM-dts-bcm2835_audio-missing-firmware-reference.patch b/target/linux/bcm27xx/patches-5.15/950-0532-ARM-dts-bcm2835_audio-missing-firmware-reference.patch deleted file mode 100644 index a3df2d9ca..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0532-ARM-dts-bcm2835_audio-missing-firmware-reference.patch +++ /dev/null @@ -1,29 +0,0 @@ -From ad987063207b77763e541f57535ea6b681e4ef3b Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 18 Oct 2021 11:12:42 +0100 -Subject: [PATCH] ARM: dts: bcm2835_audio missing firmware reference - -The firmware driver has been changed to count its clients. An earlier -commit removed the downstream patch permitting the hacky technique of -passing NULL to rpi_firmware_get to pick up the last instace, but -failed to add the necessary "firmware" property to the bcm2835_audio -node. Correct that omission. - -See: https://github.com/raspberrypi/linux/issues/4634 - https://github.com/raspberrypi/linux/issues/4635 - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/bcm270x-rpi.dtsi | 1 + - 1 file changed, 1 insertion(+) - ---- a/arch/arm/boot/dts/bcm270x-rpi.dtsi -+++ b/arch/arm/boot/dts/bcm270x-rpi.dtsi -@@ -148,6 +148,7 @@ - /* Onboard audio */ - audio: bcm2835_audio { - compatible = "brcm,bcm2835-audio"; -+ brcm,firmware = <&firmware>; - brcm,pwm-channels = <8>; - status = "disabled"; - }; diff --git a/target/linux/bcm27xx/patches-5.15/950-0533-ARM-dts-Delete-vestigial-vcsm-node.patch b/target/linux/bcm27xx/patches-5.15/950-0533-ARM-dts-Delete-vestigial-vcsm-node.patch deleted file mode 100644 index c8c6eb2c6..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0533-ARM-dts-Delete-vestigial-vcsm-node.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 151458604b3cf70f55fd7fe66aea22856037f707 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 18 Oct 2021 11:13:35 +0100 -Subject: [PATCH] ARM: dts: Delete vestigial vcsm node - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/bcm270x-rpi.dtsi | 6 ------ - 1 file changed, 6 deletions(-) - ---- a/arch/arm/boot/dts/bcm270x-rpi.dtsi -+++ b/arch/arm/boot/dts/bcm270x-rpi.dtsi -@@ -65,12 +65,6 @@ - status = "okay"; - }; - -- vcsm: vcsm { -- compatible = "raspberrypi,bcm2835-vcsm"; -- firmware = <&firmware>; -- status = "okay"; -- }; -- - /* External sound card */ - sound: sound { - status = "disabled"; diff --git a/target/linux/bcm27xx/patches-5.15/950-0534-gpio-bcm-virt-Fix-the-get-method.patch b/target/linux/bcm27xx/patches-5.15/950-0534-gpio-bcm-virt-Fix-the-get-method.patch deleted file mode 100644 index 9c12ff483..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0534-gpio-bcm-virt-Fix-the-get-method.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 6e6d30ab723843fea8d9df368b35e89327f33c11 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 19 Oct 2021 11:23:43 +0100 -Subject: [PATCH] gpio: bcm-virt: Fix the get() method - -The get() method does not understand the on-the-wire encoding of the -remote GPIO states, thinking they are simple on/off bits when they are -really pairs of 16-bit counts. Rewrite the get() handler to return the -value last written, which will eventually match the actual GPIO state -if there are no other changes. - -See: https://github.com/raspberrypi/linux/issues/4638 - -Signed-off-by: Phil Elwell ---- - drivers/gpio/gpio-bcm-virt.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/gpio/gpio-bcm-virt.c -+++ b/drivers/gpio/gpio-bcm-virt.c -@@ -49,7 +49,7 @@ static int brcmvirt_gpio_get(struct gpio - unsigned v; - gpio = container_of(gc, struct brcmvirt_gpio, gc); - v = readl(gpio->ts_base + off); -- return (v >> off) & 1; -+ return (s16)((v >> 16) - v) > 0; - } - - static void brcmvirt_gpio_set(struct gpio_chip *gc, unsigned off, int val) diff --git a/target/linux/bcm27xx/patches-5.15/950-0536-media-i2c-imx290-Sensor-should-report-RAW-color-spac.patch b/target/linux/bcm27xx/patches-5.15/950-0536-media-i2c-imx290-Sensor-should-report-RAW-color-spac.patch deleted file mode 100644 index 5ea42fa85..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0536-media-i2c-imx290-Sensor-should-report-RAW-color-spac.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 257c415d35c2941855b8429bff591487551e8678 Mon Sep 17 00:00:00 2001 -From: David Plowman -Date: Thu, 21 Oct 2021 14:44:01 +0100 -Subject: [PATCH] media: i2c: imx290: Sensor should report RAW color - space - -Tested on Raspberry Pi running libcamera. - -Signed-off-by: David Plowman ---- - drivers/media/i2c/imx290.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/media/i2c/imx290.c -+++ b/drivers/media/i2c/imx290.c -@@ -885,7 +885,7 @@ static int imx290_set_fmt(struct v4l2_su - - fmt->format.code = imx290->formats[i].code; - fmt->format.field = V4L2_FIELD_NONE; -- fmt->format.colorspace = V4L2_COLORSPACE_SRGB; -+ fmt->format.colorspace = V4L2_COLORSPACE_RAW; - fmt->format.ycbcr_enc = - V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->format.colorspace); - fmt->format.quantization = diff --git a/target/linux/bcm27xx/patches-5.15/950-0537-media-i2c-imx477-Sensor-should-report-RAW-color-spac.patch b/target/linux/bcm27xx/patches-5.15/950-0537-media-i2c-imx477-Sensor-should-report-RAW-color-spac.patch deleted file mode 100644 index 9f2f1b00f..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0537-media-i2c-imx477-Sensor-should-report-RAW-color-spac.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 6a0b7fefa963ad413f6b4554138aac9107995daf Mon Sep 17 00:00:00 2001 -From: David Plowman -Date: Thu, 21 Oct 2021 14:44:43 +0100 -Subject: [PATCH] media: i2c: imx477: Sensor should report RAW color - space - -Tested on Raspberry Pi running libcamera. - -Signed-off-by: David Plowman ---- - drivers/media/i2c/imx477.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/media/i2c/imx477.c -+++ b/drivers/media/i2c/imx477.c -@@ -1471,7 +1471,7 @@ static int imx477_enum_frame_size(struct - - static void imx477_reset_colorspace(struct v4l2_mbus_framefmt *fmt) - { -- fmt->colorspace = V4L2_COLORSPACE_SRGB; -+ fmt->colorspace = V4L2_COLORSPACE_RAW; - fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace); - fmt->quantization = V4L2_MAP_QUANTIZATION_DEFAULT(true, - fmt->colorspace, diff --git a/target/linux/bcm27xx/patches-5.15/950-0538-media-i2c-imx519-Sensor-should-report-RAW-color-spac.patch b/target/linux/bcm27xx/patches-5.15/950-0538-media-i2c-imx519-Sensor-should-report-RAW-color-spac.patch deleted file mode 100644 index 6a026d259..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0538-media-i2c-imx519-Sensor-should-report-RAW-color-spac.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 083e5464b828cfbcb8c2a38a776267ce575d157d Mon Sep 17 00:00:00 2001 -From: David Plowman -Date: Thu, 21 Oct 2021 14:45:07 +0100 -Subject: [PATCH] media: i2c: imx519: Sensor should report RAW color - space - -Tested on Raspberry Pi running libcamera. - -Signed-off-by: David Plowman ---- - drivers/media/i2c/imx519.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/media/i2c/imx519.c -+++ b/drivers/media/i2c/imx519.c -@@ -1317,7 +1317,7 @@ static int imx519_enum_frame_size(struct - - static void imx519_reset_colorspace(struct v4l2_mbus_framefmt *fmt) - { -- fmt->colorspace = V4L2_COLORSPACE_SRGB; -+ fmt->colorspace = V4L2_COLORSPACE_RAW; - fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace); - fmt->quantization = V4L2_MAP_QUANTIZATION_DEFAULT(true, - fmt->colorspace, diff --git a/target/linux/bcm27xx/patches-5.15/950-0540-media-i2c-ov9281-Sensor-should-report-RAW-color-spac.patch b/target/linux/bcm27xx/patches-5.15/950-0540-media-i2c-ov9281-Sensor-should-report-RAW-color-spac.patch deleted file mode 100644 index b3602204f..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0540-media-i2c-ov9281-Sensor-should-report-RAW-color-spac.patch +++ /dev/null @@ -1,42 +0,0 @@ -From e700cec742fc0a3b06b67fde1df2b5819c370e30 Mon Sep 17 00:00:00 2001 -From: David Plowman -Date: Thu, 21 Oct 2021 14:47:20 +0100 -Subject: [PATCH] media: i2c: ov9281: Sensor should report RAW color - space - -Tested on Raspberry Pi running libcamera. - -Signed-off-by: David Plowman ---- - drivers/media/i2c/ov9281.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/drivers/media/i2c/ov9281.c -+++ b/drivers/media/i2c/ov9281.c -@@ -507,7 +507,7 @@ static int ov9281_set_fmt(struct v4l2_su - fmt->format.width = mode->width; - fmt->format.height = mode->height; - fmt->format.field = V4L2_FIELD_NONE; -- fmt->format.colorspace = V4L2_COLORSPACE_SRGB; -+ fmt->format.colorspace = V4L2_COLORSPACE_RAW; - fmt->format.ycbcr_enc = - V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->format.colorspace); - fmt->format.quantization = -@@ -558,7 +558,7 @@ static int ov9281_get_fmt(struct v4l2_su - fmt->format.height = mode->height; - fmt->format.code = ov9281->code; - fmt->format.field = V4L2_FIELD_NONE; -- fmt->format.colorspace = V4L2_COLORSPACE_SRGB; -+ fmt->format.colorspace = V4L2_COLORSPACE_RAW; - fmt->format.ycbcr_enc = - V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->format.colorspace); - fmt->format.quantization = -@@ -911,7 +911,7 @@ static int ov9281_open(struct v4l2_subde - try_fmt->height = def_mode->height; - try_fmt->code = MEDIA_BUS_FMT_Y10_1X10; - try_fmt->field = V4L2_FIELD_NONE; -- try_fmt->colorspace = V4L2_COLORSPACE_SRGB; -+ try_fmt->colorspace = V4L2_COLORSPACE_RAW; - try_fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(try_fmt->colorspace); - try_fmt->quantization = - V4L2_MAP_QUANTIZATION_DEFAULT(true, try_fmt->colorspace, diff --git a/target/linux/bcm27xx/patches-5.15/950-0544-ARM-dts-vc4-kms-v3d-Always-disable-firmware-HDMI.patch b/target/linux/bcm27xx/patches-5.15/950-0544-ARM-dts-vc4-kms-v3d-Always-disable-firmware-HDMI.patch deleted file mode 100644 index 3a5070668..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0544-ARM-dts-vc4-kms-v3d-Always-disable-firmware-HDMI.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 3942525ae16ac52fe8b632a3d3fb34af9f0d5c5e Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 25 Oct 2021 11:48:18 +0100 -Subject: [PATCH] ARM: dts: vc4-kms-v3d: Always disable firmware HDMI - -Both the firmware audio driver and the vc4-kms-v3d driver are capable -of providing HDMI audio, but only one should be active at any time. -The vc4-kms-v3d overlays disable the firmware audio driver, but they -also have a noaudio parameter that as well as disabling the ARM-side -HDMI audio also re-enables the firmware HDMI audio. This is not -guaranteed to work and has been seen to break the display completely. - -Modify the noaudio parameters so that the firmware HDMI audio support -remains disabled. - -See: https://github.com/raspberrypi/linux/issues/4651 - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts | 4 ++-- - arch/arm/boot/dts/overlays/vc4-kms-v3d-pi4-overlay.dts | 2 +- - 2 files changed, 3 insertions(+), 3 deletions(-) - ---- a/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts -+++ b/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts -@@ -116,8 +116,8 @@ - }; - - __overrides__ { -- audio = <0>,"!13", <0>,"=14"; -- noaudio = <0>,"=13", <0>,"!14"; -+ audio = <0>,"!13"; -+ noaudio = <0>,"=13"; - nocomposite = <0>, "!11"; - }; - }; ---- a/arch/arm/boot/dts/overlays/vc4-kms-v3d-pi4-overlay.dts -+++ b/arch/arm/boot/dts/overlays/vc4-kms-v3d-pi4-overlay.dts -@@ -180,7 +180,7 @@ - __overrides__ { - audio = <0>,"!17"; - audio1 = <0>,"!18"; -- noaudio = <0>,"=17", <0>,"=18", <0>,"!19"; -+ noaudio = <0>,"=17", <0>,"=18"; - composite = <0>, "!1", - <0>, "!2", - <0>, "!3", diff --git a/target/linux/bcm27xx/patches-5.15/950-0547-ARM-dts-Add-Pi-Zero-2-support.patch b/target/linux/bcm27xx/patches-5.15/950-0547-ARM-dts-Add-Pi-Zero-2-support.patch deleted file mode 100644 index 4e325e7e7..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0547-ARM-dts-Add-Pi-Zero-2-support.patch +++ /dev/null @@ -1,219 +0,0 @@ -From ab5164dbd0241da27ec87eff34408dd97d9658c0 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 9 Sep 2021 10:37:15 +0100 -Subject: [PATCH] ARM: dts: Add Pi Zero 2 support - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/bcm2710-rpi-zero-2.dts | 177 ++++++++++++++++++ - arch/arm64/boot/dts/broadcom/Makefile | 1 + - .../boot/dts/broadcom/bcm2710-rpi-zero-2.dts | 1 + - 4 files changed, 180 insertions(+) - create mode 100644 arch/arm/boot/dts/bcm2710-rpi-zero-2.dts - create mode 100644 arch/arm64/boot/dts/broadcom/bcm2710-rpi-zero-2.dts - ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -7,6 +7,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += \ - bcm2708-rpi-cm.dtb \ - bcm2708-rpi-zero.dtb \ - bcm2708-rpi-zero-w.dtb \ -+ bcm2710-rpi-zero-2.dtb \ - bcm2709-rpi-2-b.dtb \ - bcm2710-rpi-2-b.dtb \ - bcm2710-rpi-3-b.dtb \ ---- /dev/null -+++ b/arch/arm/boot/dts/bcm2710-rpi-zero-2.dts -@@ -0,0 +1,177 @@ -+/dts-v1/; -+ -+#include "bcm2710.dtsi" -+#include "bcm2709-rpi.dtsi" -+#include "bcm283x-rpi-csi1-2lane.dtsi" -+#include "bcm283x-rpi-i2c0mux_0_44.dtsi" -+#include "bcm2708-rpi-bt.dtsi" -+#include "bcm283x-rpi-cam1-regulator.dtsi" -+ -+/ { -+ compatible = "raspberrypi,model-zero-2", "brcm,bcm2837"; -+ model = "Raspberry Pi Zero 2"; -+ -+ chosen { -+ bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1"; -+ }; -+ -+ aliases { -+ serial0 = &uart1; -+ serial1 = &uart0; -+ mmc1 = &mmcnr; -+ }; -+}; -+ -+&gpio { -+ spi0_pins: spi0_pins { -+ brcm,pins = <9 10 11>; -+ brcm,function = <4>; /* alt0 */ -+ }; -+ -+ spi0_cs_pins: spi0_cs_pins { -+ brcm,pins = <8 7>; -+ brcm,function = <1>; /* output */ -+ }; -+ -+ i2c0_pins: i2c0 { -+ brcm,pins = <0 1>; -+ brcm,function = <4>; -+ }; -+ -+ i2c1_pins: i2c1 { -+ brcm,pins = <2 3>; -+ brcm,function = <4>; -+ }; -+ -+ i2s_pins: i2s { -+ brcm,pins = <18 19 20 21>; -+ brcm,function = <4>; /* alt0 */ -+ }; -+ -+ sdio_pins: sdio_pins { -+ brcm,pins = <34 35 36 37 38 39>; -+ brcm,function = <7>; // alt3 = SD1 -+ brcm,pull = <0 2 2 2 2 2>; -+ }; -+ -+ bt_pins: bt_pins { -+ brcm,pins = <43>; -+ brcm,function = <4>; /* alt0:GPCLK2 */ -+ brcm,pull = <0>; -+ }; -+ -+ uart0_pins: uart0_pins { -+ brcm,pins = <30 31 32 33>; -+ brcm,function = <7>; /* alt3=UART0 */ -+ brcm,pull = <2 0 0 2>; /* up none none up */ -+ }; -+ -+ uart1_pins: uart1_pins { -+ brcm,pins; -+ brcm,function; -+ brcm,pull; -+ }; -+ -+ audio_pins: audio_pins { -+ brcm,pins = <>; -+ brcm,function = <>; -+ }; -+}; -+ -+&mmcnr { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdio_pins>; -+ bus-width = <4>; -+ status = "okay"; -+}; -+ -+&uart0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart0_pins &bt_pins>; -+ status = "okay"; -+}; -+ -+&uart1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart1_pins>; -+ status = "okay"; -+}; -+ -+&spi0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi0_pins &spi0_cs_pins>; -+ cs-gpios = <&gpio 8 1>, <&gpio 7 1>; -+ -+ spidev0: spidev@0{ -+ compatible = "spidev"; -+ reg = <0>; /* CE0 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <125000000>; -+ }; -+ -+ spidev1: spidev@1{ -+ compatible = "spidev"; -+ reg = <1>; /* CE1 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <125000000>; -+ }; -+}; -+ -+&i2c0if { -+ clock-frequency = <100000>; -+}; -+ -+&i2c1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c1_pins>; -+ clock-frequency = <100000>; -+}; -+ -+&i2c2 { -+ clock-frequency = <100000>; -+}; -+ -+&i2s { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2s_pins>; -+}; -+ -+&leds { -+ act_led: led-act { -+ label = "led0"; -+ linux,default-trigger = "actpwr"; -+ gpios = <&gpio 29 GPIO_ACTIVE_LOW>; -+ }; -+}; -+ -+&hdmi { -+ hpd-gpios = <&gpio 28 GPIO_ACTIVE_LOW>; -+}; -+ -+&audio { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&audio_pins>; -+ brcm,disable-headphones = <1>; -+}; -+ -+&bt { -+ shutdown-gpios = <&gpio 42 GPIO_ACTIVE_HIGH>; -+}; -+ -+&minibt { -+ shutdown-gpios = <&gpio 42 GPIO_ACTIVE_HIGH>; -+}; -+ -+&cam1_reg { -+ gpio = <&gpio 40 GPIO_ACTIVE_HIGH>; -+}; -+ -+/ { -+ __overrides__ { -+ act_led_gpio = <&act_led>,"gpios:4"; -+ act_led_activelow = <&act_led>,"gpios:8"; -+ act_led_trigger = <&act_led>,"linux,default-trigger"; -+ }; -+}; ---- a/arch/arm64/boot/dts/broadcom/Makefile -+++ b/arch/arm64/boot/dts/broadcom/Makefile -@@ -5,6 +5,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += bcm2711-rp - bcm2837-rpi-3-b.dtb \ - bcm2837-rpi-3-b-plus.dtb \ - bcm2837-rpi-cm3-io3.dtb -+dtb-$(CONFIG_ARCH_BCM2835) += bcm2710-rpi-zero-2.dtb - dtb-$(CONFIG_ARCH_BCM2835) += bcm2710-rpi-2-b.dtb - dtb-$(CONFIG_ARCH_BCM2835) += bcm2710-rpi-3-b.dtb - dtb-$(CONFIG_ARCH_BCM2835) += bcm2710-rpi-3-b-plus.dtb ---- /dev/null -+++ b/arch/arm64/boot/dts/broadcom/bcm2710-rpi-zero-2.dts -@@ -0,0 +1 @@ -+#include "../../../../arm/boot/dts/bcm2710-rpi-zero-2.dts" diff --git a/target/linux/bcm27xx/patches-5.15/950-0548-clk-raspberrypi-Support-VEC-clock.patch b/target/linux/bcm27xx/patches-5.15/950-0548-clk-raspberrypi-Support-VEC-clock.patch deleted file mode 100644 index 9e3b2188c..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0548-clk-raspberrypi-Support-VEC-clock.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 8cef8cceb28fc9c5521633cfe45bd6971753023b Mon Sep 17 00:00:00 2001 -From: Dom Cobley -Date: Tue, 19 Oct 2021 14:13:53 +0100 -Subject: [PATCH] clk-raspberrypi: Support VEC clock - -Signed-off-by: Dom Cobley ---- - drivers/clk/bcm/clk-raspberrypi.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/drivers/clk/bcm/clk-raspberrypi.c -+++ b/drivers/clk/bcm/clk-raspberrypi.c -@@ -33,6 +33,7 @@ enum rpi_firmware_clk_id { - RPI_FIRMWARE_EMMC2_CLK_ID, - RPI_FIRMWARE_M2MC_CLK_ID, - RPI_FIRMWARE_PIXEL_BVB_CLK_ID, -+ RPI_FIRMWARE_VEC_CLK_ID, - RPI_FIRMWARE_NUM_CLK_ID, - }; - -@@ -51,6 +52,7 @@ static char *rpi_firmware_clk_names[] = - [RPI_FIRMWARE_EMMC2_CLK_ID] = "emmc2", - [RPI_FIRMWARE_M2MC_CLK_ID] = "m2mc", - [RPI_FIRMWARE_PIXEL_BVB_CLK_ID] = "pixel-bvb", -+ [RPI_FIRMWARE_VEC_CLK_ID] = "vec", - }; - - #define RPI_FIRMWARE_STATE_ENABLE_BIT BIT(0) -@@ -278,6 +280,7 @@ static int raspberrypi_discover_clocks(s - case RPI_FIRMWARE_V3D_CLK_ID: - case RPI_FIRMWARE_HEVC_CLK_ID: - case RPI_FIRMWARE_PIXEL_BVB_CLK_ID: -+ case RPI_FIRMWARE_VEC_CLK_ID: - hw = raspberrypi_clk_register(rpi, clks->parent, - clks->id); - if (IS_ERR(hw)) diff --git a/target/linux/bcm27xx/patches-5.15/950-0549-dt-Move-VEC-clock-to-clk-raspberrypi.patch b/target/linux/bcm27xx/patches-5.15/950-0549-dt-Move-VEC-clock-to-clk-raspberrypi.patch deleted file mode 100644 index 8890c3582..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0549-dt-Move-VEC-clock-to-clk-raspberrypi.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 32d5f26a939d8d4477309bc601c1e7901fb01baa Mon Sep 17 00:00:00 2001 -From: Dom Cobley -Date: Tue, 19 Oct 2021 14:15:45 +0100 -Subject: [PATCH] dt: Move VEC clock to clk-raspberrypi - -clk-2835 is deprecated and gets an innacurate clock for VEC (107MHz). -Switch to clk-raspberrypi which uses the right PLL to get an accurate 108MHz. - -Signed-off-by: Dom Cobley ---- - arch/arm/boot/dts/bcm2711.dtsi | 2 +- - arch/arm/boot/dts/bcm2835-common.dtsi | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - ---- a/arch/arm/boot/dts/bcm2711.dtsi -+++ b/arch/arm/boot/dts/bcm2711.dtsi -@@ -304,7 +304,7 @@ - vec: vec@7ec13000 { - compatible = "brcm,bcm2711-vec"; - reg = <0x7ec13000 0x1000>; -- clocks = <&clocks BCM2835_CLOCK_VEC>; -+ clocks = <&firmware_clocks 15>; - interrupts = ; - status = "disabled"; - }; ---- a/arch/arm/boot/dts/bcm2835-common.dtsi -+++ b/arch/arm/boot/dts/bcm2835-common.dtsi -@@ -109,7 +109,7 @@ - vec: vec@7e806000 { - compatible = "brcm,bcm2835-vec"; - reg = <0x7e806000 0x1000>; -- clocks = <&clocks BCM2835_CLOCK_VEC>; -+ clocks = <&firmware_clocks 15>; - interrupts = <2 27>; - status = "disabled"; - }; diff --git a/target/linux/bcm27xx/patches-5.15/950-0554-media-i2c-imx477-Add-vsync-trigger_mode-parameter.patch b/target/linux/bcm27xx/patches-5.15/950-0554-media-i2c-imx477-Add-vsync-trigger_mode-parameter.patch deleted file mode 100644 index 52835f79e..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0554-media-i2c-imx477-Add-vsync-trigger_mode-parameter.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 9ed9132402b92d1957927c8719f37d8b95bb00ff Mon Sep 17 00:00:00 2001 -From: neocortex-vision -Date: Thu, 28 Oct 2021 17:37:36 +0100 -Subject: [PATCH] media: i2c: imx477: Add vsync trigger_mode parameter - -trigger_mode == 0 (default) => no effect / no registers written -trigger_mode == 1 => source -trigger_mode == 2 => sink - -This can be set e.g. in /boot/cmdline.txt as imx477.trigger_mode=N - -Signed-off-by: Jonas Jacob ---- - drivers/media/i2c/imx477.c | 25 +++++++++++++++++++++++++ - 1 file changed, 25 insertions(+) - ---- a/drivers/media/i2c/imx477.c -+++ b/drivers/media/i2c/imx477.c -@@ -25,6 +25,10 @@ static int dpc_enable = 1; - module_param(dpc_enable, int, 0644); - MODULE_PARM_DESC(dpc_enable, "Enable on-sensor DPC"); - -+static int trigger_mode; -+module_param(trigger_mode, int, 0644); -+MODULE_PARM_DESC(trigger_mode, "Set vsync trigger mode: 1=source, 2=sink"); -+ - #define IMX477_REG_VALUE_08BIT 1 - #define IMX477_REG_VALUE_16BIT 2 - -@@ -98,6 +102,12 @@ MODULE_PARM_DESC(dpc_enable, "Enable on- - #define IMX477_TEST_PATTERN_B_DEFAULT 0 - #define IMX477_TEST_PATTERN_GB_DEFAULT 0 - -+/* Trigger mode */ -+#define IMX477_REG_MC_MODE 0x3f0b -+#define IMX477_REG_MS_SEL 0x3041 -+#define IMX477_REG_XVS_IO_CTRL 0x3040 -+#define IMX477_REG_EXTOUT_EN 0x4b81 -+ - /* Embedded metadata stream structure */ - #define IMX477_EMBEDDED_LINE_WIDTH 16384 - #define IMX477_NUM_EMBEDDED_LINES 1 -@@ -1721,6 +1731,21 @@ static int imx477_start_streaming(struct - imx477_write_reg(imx477, 0x0b05, IMX477_REG_VALUE_08BIT, !!dpc_enable); - imx477_write_reg(imx477, 0x0b06, IMX477_REG_VALUE_08BIT, !!dpc_enable); - -+ /* Set vsync trigger mode */ -+ if (trigger_mode != 0) { -+ /* trigger_mode == 1 for source, 2 for sink */ -+ const u32 val = (trigger_mode == 1) ? 1 : 0; -+ -+ imx477_write_reg(imx477, IMX477_REG_MC_MODE, -+ IMX477_REG_VALUE_08BIT, 1); -+ imx477_write_reg(imx477, IMX477_REG_MS_SEL, -+ IMX477_REG_VALUE_08BIT, val); -+ imx477_write_reg(imx477, IMX477_REG_XVS_IO_CTRL, -+ IMX477_REG_VALUE_08BIT, val); -+ imx477_write_reg(imx477, IMX477_REG_EXTOUT_EN, -+ IMX477_REG_VALUE_08BIT, val); -+ } -+ - /* Apply customized values from user */ - ret = __v4l2_ctrl_handler_setup(imx477->sd.ctrl_handler); - if (ret) diff --git a/target/linux/bcm27xx/patches-5.15/950-0557-bcm2835-v4l2-codec-Remove-advertised-support-of-VP8.patch b/target/linux/bcm27xx/patches-5.15/950-0557-bcm2835-v4l2-codec-Remove-advertised-support-of-VP8.patch deleted file mode 100644 index 9aa37a0e4..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0557-bcm2835-v4l2-codec-Remove-advertised-support-of-VP8.patch +++ /dev/null @@ -1,27 +0,0 @@ -From e34d315278b4fcdf181fc7bc7406b7f59c70ba3f Mon Sep 17 00:00:00 2001 -From: Dom Cobley -Date: Sun, 31 Oct 2021 11:47:59 +0000 -Subject: [PATCH] bcm2835-v4l2-codec: Remove advertised support of VP8 - -The support for this format by firmware is very limited -and won't be faster than the arm. - -Signed-off-by: Dom Cobley ---- - .../staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c | 5 ----- - 1 file changed, 5 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -598,11 +598,6 @@ static const struct bcm2835_codec_fmt su - .flags = V4L2_FMT_FLAG_COMPRESSED, - .mmal_fmt = MMAL_ENCODING_MP2V, - }, { -- .fourcc = V4L2_PIX_FMT_VP8, -- .depth = 0, -- .flags = V4L2_FMT_FLAG_COMPRESSED, -- .mmal_fmt = MMAL_ENCODING_VP8, -- }, { - .fourcc = V4L2_PIX_FMT_VC1_ANNEX_G, - .depth = 0, - .flags = V4L2_FMT_FLAG_COMPRESSED, diff --git a/target/linux/bcm27xx/patches-5.15/950-0558-ARM-dts-Rename-Zero-2-W-DT-files.patch b/target/linux/bcm27xx/patches-5.15/950-0558-ARM-dts-Rename-Zero-2-W-DT-files.patch deleted file mode 100644 index 8918967d0..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0558-ARM-dts-Rename-Zero-2-W-DT-files.patch +++ /dev/null @@ -1,387 +0,0 @@ -From d29fb06a96cac4111d23e8f1cfc4d191d2fd5419 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 1 Nov 2021 15:44:31 +0000 -Subject: [PATCH] ARM: dts: Rename Zero 2 W DT files - -Retain the old names for backwards compatibility for a while, while the -necessary firmware change rolls out. - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/bcm2710-rpi-zero-2-w.dts | 177 ++++++++++++++++++++ - arch/arm/boot/dts/bcm2710-rpi-zero-2.dts | 178 +-------------------- - 3 files changed, 179 insertions(+), 177 deletions(-) - create mode 100644 arch/arm/boot/dts/bcm2710-rpi-zero-2-w.dts - ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -8,6 +8,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += \ - bcm2708-rpi-zero.dtb \ - bcm2708-rpi-zero-w.dtb \ - bcm2710-rpi-zero-2.dtb \ -+ bcm2710-rpi-zero-2-w.dtb \ - bcm2709-rpi-2-b.dtb \ - bcm2710-rpi-2-b.dtb \ - bcm2710-rpi-3-b.dtb \ ---- /dev/null -+++ b/arch/arm/boot/dts/bcm2710-rpi-zero-2-w.dts -@@ -0,0 +1,177 @@ -+/dts-v1/; -+ -+#include "bcm2710.dtsi" -+#include "bcm2709-rpi.dtsi" -+#include "bcm283x-rpi-csi1-2lane.dtsi" -+#include "bcm283x-rpi-i2c0mux_0_44.dtsi" -+#include "bcm2708-rpi-bt.dtsi" -+#include "bcm283x-rpi-cam1-regulator.dtsi" -+ -+/ { -+ compatible = "raspberrypi,model-zero-2-w", "brcm,bcm2837"; -+ model = "Raspberry Pi Zero 2 W"; -+ -+ chosen { -+ bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1"; -+ }; -+ -+ aliases { -+ serial0 = &uart1; -+ serial1 = &uart0; -+ mmc1 = &mmcnr; -+ }; -+}; -+ -+&gpio { -+ spi0_pins: spi0_pins { -+ brcm,pins = <9 10 11>; -+ brcm,function = <4>; /* alt0 */ -+ }; -+ -+ spi0_cs_pins: spi0_cs_pins { -+ brcm,pins = <8 7>; -+ brcm,function = <1>; /* output */ -+ }; -+ -+ i2c0_pins: i2c0 { -+ brcm,pins = <0 1>; -+ brcm,function = <4>; -+ }; -+ -+ i2c1_pins: i2c1 { -+ brcm,pins = <2 3>; -+ brcm,function = <4>; -+ }; -+ -+ i2s_pins: i2s { -+ brcm,pins = <18 19 20 21>; -+ brcm,function = <4>; /* alt0 */ -+ }; -+ -+ sdio_pins: sdio_pins { -+ brcm,pins = <34 35 36 37 38 39>; -+ brcm,function = <7>; // alt3 = SD1 -+ brcm,pull = <0 2 2 2 2 2>; -+ }; -+ -+ bt_pins: bt_pins { -+ brcm,pins = <43>; -+ brcm,function = <4>; /* alt0:GPCLK2 */ -+ brcm,pull = <0>; -+ }; -+ -+ uart0_pins: uart0_pins { -+ brcm,pins = <30 31 32 33>; -+ brcm,function = <7>; /* alt3=UART0 */ -+ brcm,pull = <2 0 0 2>; /* up none none up */ -+ }; -+ -+ uart1_pins: uart1_pins { -+ brcm,pins; -+ brcm,function; -+ brcm,pull; -+ }; -+ -+ audio_pins: audio_pins { -+ brcm,pins = <>; -+ brcm,function = <>; -+ }; -+}; -+ -+&mmcnr { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdio_pins>; -+ bus-width = <4>; -+ status = "okay"; -+}; -+ -+&uart0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart0_pins &bt_pins>; -+ status = "okay"; -+}; -+ -+&uart1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart1_pins>; -+ status = "okay"; -+}; -+ -+&spi0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi0_pins &spi0_cs_pins>; -+ cs-gpios = <&gpio 8 1>, <&gpio 7 1>; -+ -+ spidev0: spidev@0{ -+ compatible = "spidev"; -+ reg = <0>; /* CE0 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <125000000>; -+ }; -+ -+ spidev1: spidev@1{ -+ compatible = "spidev"; -+ reg = <1>; /* CE1 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <125000000>; -+ }; -+}; -+ -+&i2c0if { -+ clock-frequency = <100000>; -+}; -+ -+&i2c1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c1_pins>; -+ clock-frequency = <100000>; -+}; -+ -+&i2c2 { -+ clock-frequency = <100000>; -+}; -+ -+&i2s { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2s_pins>; -+}; -+ -+&leds { -+ act_led: led-act { -+ label = "led0"; -+ linux,default-trigger = "actpwr"; -+ gpios = <&gpio 29 GPIO_ACTIVE_LOW>; -+ }; -+}; -+ -+&hdmi { -+ hpd-gpios = <&gpio 28 GPIO_ACTIVE_LOW>; -+}; -+ -+&audio { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&audio_pins>; -+ brcm,disable-headphones = <1>; -+}; -+ -+&bt { -+ shutdown-gpios = <&gpio 42 GPIO_ACTIVE_HIGH>; -+}; -+ -+&minibt { -+ shutdown-gpios = <&gpio 42 GPIO_ACTIVE_HIGH>; -+}; -+ -+&cam1_reg { -+ gpio = <&gpio 40 GPIO_ACTIVE_HIGH>; -+}; -+ -+/ { -+ __overrides__ { -+ act_led_gpio = <&act_led>,"gpios:4"; -+ act_led_activelow = <&act_led>,"gpios:8"; -+ act_led_trigger = <&act_led>,"linux,default-trigger"; -+ }; -+}; ---- a/arch/arm/boot/dts/bcm2710-rpi-zero-2.dts -+++ b/arch/arm/boot/dts/bcm2710-rpi-zero-2.dts -@@ -1,177 +1 @@ --/dts-v1/; -- --#include "bcm2710.dtsi" --#include "bcm2709-rpi.dtsi" --#include "bcm283x-rpi-csi1-2lane.dtsi" --#include "bcm283x-rpi-i2c0mux_0_44.dtsi" --#include "bcm2708-rpi-bt.dtsi" --#include "bcm283x-rpi-cam1-regulator.dtsi" -- --/ { -- compatible = "raspberrypi,model-zero-2", "brcm,bcm2837"; -- model = "Raspberry Pi Zero 2"; -- -- chosen { -- bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1"; -- }; -- -- aliases { -- serial0 = &uart1; -- serial1 = &uart0; -- mmc1 = &mmcnr; -- }; --}; -- --&gpio { -- spi0_pins: spi0_pins { -- brcm,pins = <9 10 11>; -- brcm,function = <4>; /* alt0 */ -- }; -- -- spi0_cs_pins: spi0_cs_pins { -- brcm,pins = <8 7>; -- brcm,function = <1>; /* output */ -- }; -- -- i2c0_pins: i2c0 { -- brcm,pins = <0 1>; -- brcm,function = <4>; -- }; -- -- i2c1_pins: i2c1 { -- brcm,pins = <2 3>; -- brcm,function = <4>; -- }; -- -- i2s_pins: i2s { -- brcm,pins = <18 19 20 21>; -- brcm,function = <4>; /* alt0 */ -- }; -- -- sdio_pins: sdio_pins { -- brcm,pins = <34 35 36 37 38 39>; -- brcm,function = <7>; // alt3 = SD1 -- brcm,pull = <0 2 2 2 2 2>; -- }; -- -- bt_pins: bt_pins { -- brcm,pins = <43>; -- brcm,function = <4>; /* alt0:GPCLK2 */ -- brcm,pull = <0>; -- }; -- -- uart0_pins: uart0_pins { -- brcm,pins = <30 31 32 33>; -- brcm,function = <7>; /* alt3=UART0 */ -- brcm,pull = <2 0 0 2>; /* up none none up */ -- }; -- -- uart1_pins: uart1_pins { -- brcm,pins; -- brcm,function; -- brcm,pull; -- }; -- -- audio_pins: audio_pins { -- brcm,pins = <>; -- brcm,function = <>; -- }; --}; -- --&mmcnr { -- pinctrl-names = "default"; -- pinctrl-0 = <&sdio_pins>; -- bus-width = <4>; -- status = "okay"; --}; -- --&uart0 { -- pinctrl-names = "default"; -- pinctrl-0 = <&uart0_pins &bt_pins>; -- status = "okay"; --}; -- --&uart1 { -- pinctrl-names = "default"; -- pinctrl-0 = <&uart1_pins>; -- status = "okay"; --}; -- --&spi0 { -- pinctrl-names = "default"; -- pinctrl-0 = <&spi0_pins &spi0_cs_pins>; -- cs-gpios = <&gpio 8 1>, <&gpio 7 1>; -- -- spidev0: spidev@0{ -- compatible = "spidev"; -- reg = <0>; /* CE0 */ -- #address-cells = <1>; -- #size-cells = <0>; -- spi-max-frequency = <125000000>; -- }; -- -- spidev1: spidev@1{ -- compatible = "spidev"; -- reg = <1>; /* CE1 */ -- #address-cells = <1>; -- #size-cells = <0>; -- spi-max-frequency = <125000000>; -- }; --}; -- --&i2c0if { -- clock-frequency = <100000>; --}; -- --&i2c1 { -- pinctrl-names = "default"; -- pinctrl-0 = <&i2c1_pins>; -- clock-frequency = <100000>; --}; -- --&i2c2 { -- clock-frequency = <100000>; --}; -- --&i2s { -- pinctrl-names = "default"; -- pinctrl-0 = <&i2s_pins>; --}; -- --&leds { -- act_led: led-act { -- label = "led0"; -- linux,default-trigger = "actpwr"; -- gpios = <&gpio 29 GPIO_ACTIVE_LOW>; -- }; --}; -- --&hdmi { -- hpd-gpios = <&gpio 28 GPIO_ACTIVE_LOW>; --}; -- --&audio { -- pinctrl-names = "default"; -- pinctrl-0 = <&audio_pins>; -- brcm,disable-headphones = <1>; --}; -- --&bt { -- shutdown-gpios = <&gpio 42 GPIO_ACTIVE_HIGH>; --}; -- --&minibt { -- shutdown-gpios = <&gpio 42 GPIO_ACTIVE_HIGH>; --}; -- --&cam1_reg { -- gpio = <&gpio 40 GPIO_ACTIVE_HIGH>; --}; -- --/ { -- __overrides__ { -- act_led_gpio = <&act_led>,"gpios:4"; -- act_led_activelow = <&act_led>,"gpios:8"; -- act_led_trigger = <&act_led>,"linux,default-trigger"; -- }; --}; -+#include "bcm2710-rpi-zero-2-w.dts" diff --git a/target/linux/bcm27xx/patches-5.15/950-0559-dtoverlays-Update-all-image-sensor-overlays-for-Medi.patch b/target/linux/bcm27xx/patches-5.15/950-0559-dtoverlays-Update-all-image-sensor-overlays-for-Medi.patch deleted file mode 100644 index 4dcbd7fb5..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0559-dtoverlays-Update-all-image-sensor-overlays-for-Medi.patch +++ /dev/null @@ -1,337 +0,0 @@ -From 74b6a90ba073ae853640432f824b6308c5a003b5 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 21 Oct 2021 15:06:02 +0100 -Subject: [PATCH] dtoverlays: Update all image sensor overlays for - Media Controller option - -Add an option to enable configuration via the Media Controller API -(rather than the video-node-centric /dev/videoN) as about to -be used by libcamera as it enables more complex pipelines to be -handled. - -Any source that has a libcamera tuning merged has MC enabled by -default. -Sources with no libcamera tuning merged have it disabled by -default. -In either case it can be overridden with the overlay parameter -"media-controller". - -Signed-off-by: Dave Stevenson ---- - arch/arm/boot/dts/overlays/README | 27 +++++++++++++++++-- - .../boot/dts/overlays/adv7282m-overlay.dts | 8 ++++++ - arch/arm/boot/dts/overlays/imx219-overlay.dts | 8 ++++++ - .../boot/dts/overlays/imx290_327-overlay.dtsi | 8 ++++++ - .../boot/dts/overlays/imx477_378-overlay.dtsi | 8 ++++++ - arch/arm/boot/dts/overlays/imx519-overlay.dts | 8 ++++++ - .../arm/boot/dts/overlays/irs1125-overlay.dts | 11 ++++++++ - arch/arm/boot/dts/overlays/ov5647-overlay.dts | 8 ++++++ - arch/arm/boot/dts/overlays/ov7251-overlay.dts | 8 ++++++ - arch/arm/boot/dts/overlays/ov9281-overlay.dts | 8 ++++++ - .../boot/dts/overlays/tc358743-overlay.dts | 8 ++++++ - 11 files changed, 108 insertions(+), 2 deletions(-) - ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -416,6 +416,8 @@ Info: Analog Devices ADV7282M analogue - variants. - Load: dtoverlay=adv7282m,= - Params: addr Overrides the I2C address (default 0x21) -+ media-controller Configure use of Media Controller API for -+ configuring the sensor (default off) - - - Name: adv728x-m -@@ -426,6 +428,8 @@ Params: addr Override - adv7280m Select ADV7280-M. - adv7281m Select ADV7281-M. - adv7281ma Select ADV7281-MA. -+ media-controller Configure use of Media Controller API for -+ configuring the sensor (default off) - - - Name: akkordion-iqdacplus -@@ -1708,6 +1712,8 @@ Params: rotation Mounting - 180, default 180) - orientation Sensor orientation (0 = front, 1 = rear, - 2 = external, default external) -+ media-controller Configure use of Media Controller API for -+ configuring the sensor (default on) - - - Name: imx290 -@@ -1728,6 +1734,8 @@ Params: 4lane Enable 4 - 2 = external, default external) - rotation Mounting rotation of the camera sensor (0 or - 180, default 0) -+ media-controller Configure use of Media Controller API for -+ configuring the sensor (default on) - - - Name: imx378 -@@ -1739,6 +1747,8 @@ Params: rotation Mounting - 180, default 180) - orientation Sensor orientation (0 = front, 1 = rear, - 2 = external, default external) -+ media-controller Configure use of Media Controller API for -+ configuring the sensor (default on) - - - Name: imx477 -@@ -1750,6 +1760,8 @@ Params: rotation Mounting - 180, default 180) - orientation Sensor orientation (0 = front, 1 = rear, - 2 = external, default external) -+ media-controller Configure use of Media Controller API for -+ configuring the sensor (default on) - - - Name: imx519 -@@ -1761,6 +1773,8 @@ Params: rotation Mounting - 180, default 0) - orientation Sensor orientation (0 = front, 1 = rear, - 2 = external, default external) -+ media-controller Configure use of Media Controller API for -+ configuring the sensor (default on) - - - Name: iqaudio-codec -@@ -1824,8 +1838,9 @@ Name: irs1125 - Info: Infineon irs1125 TOF camera module. - Uses Unicam 1, which is the standard camera connector on most Pi - variants. --Load: dtoverlay=irs1125 --Params: -+Load: dtoverlay=irs1125,= -+Params: media-controller Configure use of Media Controller API for -+ configuring the sensor (default off) - - - Name: jedec-spi-nor -@@ -2237,6 +2252,8 @@ Params: rotation Mounting - 180, default 0) - orientation Sensor orientation (0 = front, 1 = rear, - 2 = external, default external) -+ media-controller Configure use of Media Controller API for -+ configuring the sensor (default on) - - - Name: ov7251 -@@ -2248,6 +2265,8 @@ Params: rotation Mounting - 180, default 0) - orientation Sensor orientation (0 = front, 1 = rear, - 2 = external, default external) -+ media-controller Configure use of Media Controller API for -+ configuring the sensor (default off) - - - Name: ov9281 -@@ -2259,6 +2278,8 @@ Params: rotation Mounting - 180, default 0) - orientation Sensor orientation (0 = front, 1 = rear, - 2 = external, default external) -+ media-controller Configure use of Media Controller API for -+ configuring the sensor (default on) - - - Name: papirus -@@ -3239,6 +3260,8 @@ Params: 4lane Use 4 la - link-frequency Set the link frequency. Only values of 297000000 - (574Mbit/s) and 486000000 (972Mbit/s - default) - are supported by the driver. -+ media-controller Configure use of Media Controller API for -+ configuring the sensor (default off) - - - Name: tc358743-audio ---- a/arch/arm/boot/dts/overlays/adv7282m-overlay.dts -+++ b/arch/arm/boot/dts/overlays/adv7282m-overlay.dts -@@ -59,7 +59,15 @@ - }; - }; - -+ fragment@4 { -+ target = <&csi1>; -+ __dormant__ { -+ brcm,media-controller; -+ }; -+ }; -+ - __overrides__ { - addr = <&adv728x>,"reg:0"; -+ media-controller = <0>,"=4"; - }; - }; ---- a/arch/arm/boot/dts/overlays/imx219-overlay.dts -+++ b/arch/arm/boot/dts/overlays/imx219-overlay.dts -@@ -108,8 +108,16 @@ - }; - }; - -+ fragment@6 { -+ target = <&csi1>; -+ __overlay__ { -+ brcm,media-controller; -+ }; -+ }; -+ - __overrides__ { - rotation = <&imx219>,"rotation:0"; - orientation = <&imx219>,"orientation:0"; -+ media-controller = <0>,"=6"; - }; - }; ---- a/arch/arm/boot/dts/overlays/imx290_327-overlay.dtsi -+++ b/arch/arm/boot/dts/overlays/imx290_327-overlay.dtsi -@@ -134,11 +134,19 @@ - }; - }; - -+ fragment@10 { -+ target = <&csi1>; -+ __overlay__ { -+ brcm,media-controller; -+ }; -+ }; -+ - __overrides__ { - 4lane = <0>, "-6+7-8+9"; - clock-frequency = <&imx290_clk>,"clock-frequency:0", - <&imx290>,"clock-frequency:0"; - rotation = <&imx290>,"rotation:0"; - orientation = <&imx290>,"orientation:0"; -+ media-controller = <0>,"=10"; - }; - }; ---- a/arch/arm/boot/dts/overlays/imx477_378-overlay.dtsi -+++ b/arch/arm/boot/dts/overlays/imx477_378-overlay.dtsi -@@ -103,8 +103,16 @@ - }; - }; - -+ fragment@6 { -+ target = <&csi1>; -+ __overlay__ { -+ brcm,media-controller; -+ }; -+ }; -+ - __overrides__ { - rotation = <&imx477>,"rotation:0"; - orientation = <&imx477>,"orientation:0"; -+ media-controller = <0>,"=6"; - }; - }; ---- a/arch/arm/boot/dts/overlays/imx519-overlay.dts -+++ b/arch/arm/boot/dts/overlays/imx519-overlay.dts -@@ -108,8 +108,16 @@ - }; - }; - -+ fragment@6 { -+ target = <&csi1>; -+ __overlay__ { -+ brcm,media-controller; -+ }; -+ }; -+ - __overrides__ { - rotation = <&imx519>,"rotation:0"; - orientation = <&imx519>,"orientation:0"; -+ media-controller = <0>,"=6"; - }; - }; ---- a/arch/arm/boot/dts/overlays/irs1125-overlay.dts -+++ b/arch/arm/boot/dts/overlays/irs1125-overlay.dts -@@ -82,4 +82,15 @@ - }; - }; - }; -+ -+ fragment@6 { -+ target = <&csi1>; -+ __dormant__ { -+ brcm,media-controller; -+ }; -+ }; -+ -+ __overrides__ { -+ media-controller = <0>,"=6"; -+ }; - }; ---- a/arch/arm/boot/dts/overlays/ov5647-overlay.dts -+++ b/arch/arm/boot/dts/overlays/ov5647-overlay.dts -@@ -87,8 +87,16 @@ - }; - }; - -+ fragment@6 { -+ target = <&csi1>; -+ __overlay__ { -+ brcm,media-controller; -+ }; -+ }; -+ - __overrides__ { - rotation = <&ov5647>,"rotation:0"; - orientation = <&ov5647>,"orientation:0"; -+ media-controller = <0>,"=6"; - }; - }; ---- a/arch/arm/boot/dts/overlays/ov7251-overlay.dts -+++ b/arch/arm/boot/dts/overlays/ov7251-overlay.dts -@@ -106,8 +106,16 @@ - }; - }; - -+ fragment@6 { -+ target = <&csi1>; -+ __dormant__ { -+ brcm,media-controller; -+ }; -+ }; -+ - __overrides__ { - rotation = <&ov7251>,"rotation:0"; - orientation = <&ov7251>,"orientation:0"; -+ media-controller = <0>,"=6"; - }; - }; ---- a/arch/arm/boot/dts/overlays/ov9281-overlay.dts -+++ b/arch/arm/boot/dts/overlays/ov9281-overlay.dts -@@ -106,8 +106,16 @@ - }; - }; - -+ fragment@6 { -+ target = <&csi1>; -+ __overlay__ { -+ brcm,media-controller; -+ }; -+ }; -+ - __overrides__ { - rotation = <&ov9281>,"rotation:0"; - orientation = <&ov9281>,"orientation:0"; -+ media-controller = <0>,"=6"; - }; - }; ---- a/arch/arm/boot/dts/overlays/tc358743-overlay.dts -+++ b/arch/arm/boot/dts/overlays/tc358743-overlay.dts -@@ -100,8 +100,16 @@ - }; - }; - -+ fragment@9 { -+ target = <&csi1>; -+ __dormant__ { -+ brcm,media-controller; -+ }; -+ }; -+ - __overrides__ { - 4lane = <0>, "-2+3-7+8"; - link-frequency = <&tc358743>,"link-frequencies#0"; -+ media-controller = <0>,"=9"; - }; - }; diff --git a/target/linux/bcm27xx/patches-5.15/950-0560-ARM-dt-Add-DT-nodes-for-the-WLAN-interfaces.patch b/target/linux/bcm27xx/patches-5.15/950-0560-ARM-dt-Add-DT-nodes-for-the-WLAN-interfaces.patch deleted file mode 100644 index aced47cab..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0560-ARM-dt-Add-DT-nodes-for-the-WLAN-interfaces.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 5676ad01fda218675624294b2818720ea806bf87 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 26 Oct 2021 16:38:44 +0100 -Subject: [PATCH] ARM: dt: Add DT nodes for the WLAN interfaces - -Mirror upstream changes into the downstream dts files. - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/bcm2708-rpi-zero-w.dts | 7 +++++++ - arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts | 7 +++++++ - arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 7 +++++++ - arch/arm/boot/dts/bcm2710-rpi-zero-2-w.dts | 7 +++++++ - 4 files changed, 28 insertions(+) - ---- a/arch/arm/boot/dts/bcm2708-rpi-zero-w.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-zero-w.dts -@@ -83,6 +83,13 @@ - pinctrl-0 = <&sdio_pins>; - bus-width = <4>; - status = "okay"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ brcmf: wifi@1 { -+ reg = <1>; -+ compatible = "brcm,bcm4329-fmac"; -+ }; - }; - - &uart0 { ---- a/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts -@@ -84,6 +84,13 @@ - pinctrl-0 = <&sdio_pins>; - bus-width = <4>; - status = "okay"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ brcmf: wifi@1 { -+ reg = <1>; -+ compatible = "brcm,bcm4329-fmac"; -+ }; - }; - - &firmware { ---- a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -+++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -@@ -84,6 +84,13 @@ - pinctrl-0 = <&sdio_pins>; - bus-width = <4>; - status = "okay"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ brcmf: wifi@1 { -+ reg = <1>; -+ compatible = "brcm,bcm4329-fmac"; -+ }; - }; - - &soc { ---- a/arch/arm/boot/dts/bcm2710-rpi-zero-2-w.dts -+++ b/arch/arm/boot/dts/bcm2710-rpi-zero-2-w.dts -@@ -83,6 +83,13 @@ - pinctrl-0 = <&sdio_pins>; - bus-width = <4>; - status = "okay"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ brcmf: wifi@1 { -+ reg = <1>; -+ compatible = "brcm,bcm4329-fmac"; -+ }; - }; - - &uart0 { diff --git a/target/linux/bcm27xx/patches-5.15/950-0561-ARM-dts-Provide-WLAN-firmware-names-for-Zero-2-W.patch b/target/linux/bcm27xx/patches-5.15/950-0561-ARM-dts-Provide-WLAN-firmware-names-for-Zero-2-W.patch deleted file mode 100644 index 23c8f5964..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0561-ARM-dts-Provide-WLAN-firmware-names-for-Zero-2-W.patch +++ /dev/null @@ -1,40 +0,0 @@ -From ef292559833a279be2aac7ae8222348b1c122826 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 28 Oct 2021 15:09:25 +0100 -Subject: [PATCH] ARM: dts: Provide WLAN firmware names for Zero 2 W - -BCM43430/2 may be BCM43430B0 or BCM43436P, and BCM43430/1 can be either -BCM43430A1 or BCM43436S, the former being upstream names and the -latter downstream names for differently-sourced sister parts. - -Make the choice of firmwares board-specific (without making the actual -firmwares board-specific) by placing the alternative firmware names for -each part in the DT node. - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/bcm2710-rpi-zero-2-w.dts | 13 +++++++++++++ - 1 file changed, 13 insertions(+) - ---- a/arch/arm/boot/dts/bcm2710-rpi-zero-2-w.dts -+++ b/arch/arm/boot/dts/bcm2710-rpi-zero-2-w.dts -@@ -89,6 +89,19 @@ - brcmf: wifi@1 { - reg = <1>; - compatible = "brcm,bcm4329-fmac"; -+ -+ firmwares { -+ fw_43436p { -+ chipid = <43430>; -+ revmask = <4>; -+ fw_base = "brcm/brcmfmac43436-sdio"; -+ }; -+ fw_43436s { -+ chipid = <43430>; -+ revmask = <2>; -+ fw_base = "brcm/brcmfmac43436s-sdio"; -+ }; -+ }; - }; - }; - diff --git a/target/linux/bcm27xx/patches-5.15/950-0563-drm-vc4-kms-Fix-return-code-check.patch b/target/linux/bcm27xx/patches-5.15/950-0563-drm-vc4-kms-Fix-return-code-check.patch deleted file mode 100644 index 2bff88c51..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0563-drm-vc4-kms-Fix-return-code-check.patch +++ /dev/null @@ -1,42 +0,0 @@ -From e0788eaab7b0dca567c52a5959fbdd9da942a1f5 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Wed, 20 Oct 2021 13:31:22 +0200 -Subject: [PATCH] drm/vc4: kms: Fix return code check - -The HVS global state functions return an error pointer, but in most -cases we check if it's NULL, possibly resulting in an invalid pointer -dereference. - -Fixes: 9ec03d7f1ed3 ("drm/vc4: kms: Wait on previous FIFO users before a commit") -Signed-off-by: Maxime Ripard ---- - drivers/gpu/drm/vc4/vc4_kms.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_kms.c -@@ -352,11 +352,11 @@ static void vc4_atomic_commit_tail(struc - int i; - - old_hvs_state = vc4_hvs_get_old_global_state(state); -- if (WARN_ON(!old_hvs_state)) -+ if (WARN_ON(IS_ERR(old_hvs_state))) - return; - - new_hvs_state = vc4_hvs_get_new_global_state(state); -- if (WARN_ON(!new_hvs_state)) -+ if (WARN_ON(IS_ERR(new_hvs_state))) - return; - - for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) { -@@ -891,8 +891,8 @@ vc4_core_clock_atomic_check(struct drm_a - load_state = to_vc4_load_tracker_state(priv_state); - - hvs_new_state = vc4_hvs_get_global_state(state); -- if (!hvs_new_state) -- return -EINVAL; -+ if (IS_ERR(hvs_new_state)) -+ return PTR_ERR(hvs_new_state); - - for_each_oldnew_crtc_in_state(state, crtc, - old_crtc_state, diff --git a/target/linux/bcm27xx/patches-5.15/950-0564-drm-vc4-kms-Move-clock-request-to-our-HVS-state.patch b/target/linux/bcm27xx/patches-5.15/950-0564-drm-vc4-kms-Move-clock-request-to-our-HVS-state.patch deleted file mode 100644 index 6ffe0f1e4..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0564-drm-vc4-kms-Move-clock-request-to-our-HVS-state.patch +++ /dev/null @@ -1,59 +0,0 @@ -From f7d98ba8c30bbc5b29bf740f28bf2daeeec09d2b Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Thu, 4 Nov 2021 14:04:37 +0100 -Subject: [PATCH] drm/vc4: kms: Move clock request to our HVS state - -Our current clock request has been stored so far on the main HVS -structure, but even though we shouldn't have two commits in parallel and -it shouldn't cause any functional change, the request itself is linked -to a given HVS state. - -Move the request there to make a bit more sense. - -Signed-off-by: Maxime Ripard ---- - drivers/gpu/drm/vc4/vc4_drv.h | 1 - - drivers/gpu/drm/vc4/vc4_kms.c | 8 +++++--- - 2 files changed, 5 insertions(+), 4 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_drv.h -+++ b/drivers/gpu/drm/vc4/vc4_drv.h -@@ -326,7 +326,6 @@ struct vc4_hvs { - u32 __iomem *dlist; - - struct clk *core_clk; -- struct clk_request *core_req; - - /* Memory manager for CRTCs to allocate space in the display - * list. Units are dwords. ---- a/drivers/gpu/drm/vc4/vc4_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_kms.c -@@ -40,6 +40,7 @@ static struct vc4_ctm_state *to_vc4_ctm_ - struct vc4_hvs_state { - struct drm_private_state base; - unsigned long core_clock_rate; -+ struct clk_request *core_req; - - struct { - unsigned in_use: 1; -@@ -398,7 +399,8 @@ static void vc4_atomic_commit_tail(struc - * And remove the previous one based on the HVS - * requirements if any. - */ -- clk_request_done(hvs->core_req); -+ clk_request_done(old_hvs_state->core_req); -+ old_hvs_state->core_req = NULL; - } - - drm_atomic_helper_commit_modeset_disables(dev, state); -@@ -432,8 +434,8 @@ static void vc4_atomic_commit_tail(struc - * Request a clock rate based on the current HVS - * requirements. - */ -- hvs->core_req = clk_request_start(hvs->core_clk, -- new_hvs_state->core_clock_rate); -+ new_hvs_state->core_req = clk_request_start(hvs->core_clk, -+ new_hvs_state->core_clock_rate); - - /* And drop the temporary request */ - clk_request_done(core_req); diff --git a/target/linux/bcm27xx/patches-5.15/950-0565-overlays-Add-fbtft-overlay.patch b/target/linux/bcm27xx/patches-5.15/950-0565-overlays-Add-fbtft-overlay.patch deleted file mode 100644 index e9e035364..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0565-overlays-Add-fbtft-overlay.patch +++ /dev/null @@ -1,775 +0,0 @@ -From c218d35ede9474ffa6231e8be88c8ad28044ca2e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Wed, 3 Nov 2021 12:21:14 +0100 -Subject: [PATCH] overlays: Add fbtft overlay -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add an overlay that provides much of the functionality that fbtft_device did. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 124 ++++ - arch/arm/boot/dts/overlays/fbtft-overlay.dts | 611 +++++++++++++++++++ - 3 files changed, 736 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/fbtft-overlay.dts - ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -49,6 +49,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ - enc28j60.dtbo \ - enc28j60-spi2.dtbo \ - exc3000.dtbo \ -+ fbtft.dtbo \ - fe-pi-audio.dtbo \ - fsm-demo.dtbo \ - ghost-amp.dtbo \ ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -857,6 +857,130 @@ Params: interrupt GPIO use - swapxy Touchscreen swapped x y axis - - -+Name: fbtft -+Info: Overlay for SPI-connected displays using the fbtft drivers. -+ -+ This overlay seeks to replace the functionality provided by fbtft_device -+ which is now gone from the kernel. -+ -+ Most displays from fbtft_device have been ported over. -+ Example: -+ dtoverlay=fbtft,spi0-0,rpi-display,reset_pin=23,dc_pin=24,led_pin=18,rotate=270 -+ -+ It is also possible to specify the controller (this will use the default -+ init sequence in the driver). -+ Example: -+ dtoverlay=fbtft,spi0-0,ili9341,bgr,reset_pin=23,dc_pin=24,led_pin=18,rotate=270 -+ -+ For devices on spi1 or spi2, the interfaces should be enabled -+ with one of the spi1-1/2/3cs and/or spi2-1/2/3cs overlays. -+ -+ The following features of fbtft_device have not been ported over: -+ - parallel bus is not supported -+ - the init property which overrides the controller initialization -+ sequence is not supported as a parameter due to memory limitations in -+ the bootloader responsible for applying the overlay. -+ -+ See https://github.com/notro/fbtft/wiki/FBTFT-RPI-overlays for how to -+ create an overlay. -+ -+Load: dtoverlay=fbtft,= -+Params: -+ spi- Configure device at spi, cs -+ (boolean, required) -+ speed SPI bus speed in Hz (default 32000000) -+ cpha Shifted clock phase (CPHA) mode -+ cpol Inverse clock polarity (CPOL) mode -+ -+ adafruit18 Adafruit 1.8 -+ adafruit22 Adafruit 2.2 (old) -+ adafruit22a Adafruit 2.2 -+ adafruit28 Adafruit 2.8 -+ adafruit13m Adafruit 1.3 OLED -+ admatec_c-berry28 C-Berry28 -+ dogs102 EA DOGS102 -+ er_tftm050_2 ER-TFTM070-2 -+ er_tftm070_5 ER-TFTM070-5 -+ ew24ha0 EW24HA0 -+ ew24ha0_9bit EW24HA0 in 9-bit mode -+ freetronicsoled128 Freetronics OLED128 -+ hy28a HY28A -+ hy28b HY28B -+ itdb28_spi ITDB02-2.8 with SPI interface circuit -+ mi0283qt-2 Watterott MI0283QT-2 -+ mi0283qt-9a Watterott MI0283QT-9A -+ nokia3310 Nokia 3310 -+ nokia3310a Nokia 3310a -+ nokia5110 Nokia 5110 -+ piscreen PiScreen -+ pitft Adafruit PiTFT 2.8 -+ pioled ILSoft OLED -+ rpi-display Watterott rpi-display -+ sainsmart18 Sainsmart 1.8 -+ sainsmart32_spi Sainsmart 3.2 with SPI interfce circuit -+ tinylcd35 TinyLCD 3.5 -+ tm022hdh26 Tianma TM022HDH26 -+ tontec35_9481 Tontect 3.5 with ILI9481 controller -+ tontec35_9486 Tontect 3.5 with ILI9486 controller -+ waveshare32b Waveshare 3.2 -+ waveshare22 Waveshare 2.2 -+ -+ bd663474 BD663474 display controller -+ hx8340bn HX8340BN display controller -+ hx8347d HX8347D display controller -+ hx8353d HX8353D display controller -+ hx8357d HX8357D display controller -+ ili9163 ILI9163 display controller -+ ili9320 ILI9320 display controller -+ ili9325 ILI9325 display controller -+ ili9340 ILI9340 display controller -+ ili9341 ILI9341 display controller -+ ili9481 ILI9481 display controller -+ ili9486 ILI9486 display controller -+ pcd8544 PCD8544 display controller -+ ra8875 RA8875 display controller -+ s6d02a1 S6D02A1 display controller -+ s6d1121 S6D1121 display controller -+ seps525 SEPS525 display controller -+ sh1106 SH1106 display controller -+ ssd1289 SSD1289 display controller -+ ssd1305 SSD1305 display controller -+ ssd1306 SSD1306 display controller -+ ssd1325 SSD1325 display controller -+ ssd1331 SSD1331 display controller -+ ssd1351 SSD1351 display controller -+ st7735r ST7735R display controller -+ st7789v ST7789V display controller -+ tls8204 TLS8204 display controller -+ uc1611 UC1611 display controller -+ uc1701 UC1701 display controller -+ upd161704 UPD161704 display controller -+ -+ width Display width in pixels -+ height Display height in pixels -+ regwidth Display controller register width (default is -+ driver specific) -+ buswidth Display bus interface width (default 8) -+ debug Debug output level {0-7} -+ rotate Display rotation {0, 90, 180, 270} (counter -+ clockwise). Not supported by all drivers. -+ bgr Enable BGR mode (default off). Use if Red and -+ Blue are swapped. Not supported by all drivers. -+ fps Frames per second (default 30). In effect this -+ states how long the driver will wait after video -+ memory has been changed until display update -+ transfer is started. -+ txbuflen Length of the FBTFT transmit buffer -+ (default 4096) -+ startbyte Sets the Start byte used by fb_ili9320, -+ fb_ili9325 and fb_hx8347d. Common value is 0x70. -+ gamma String representation of Gamma Curve(s). Driver -+ specific. Not supported by all drivers. -+ reset_pin GPIO pin for RESET -+ dc_pin GPIO pin for D/C -+ led_pin GPIO pin for LED backlight -+ -+ - Name: fe-pi-audio - Info: Configures the Fe-Pi Audio Sound Card - Load: dtoverlay=fe-pi-audio ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/fbtft-overlay.dts -@@ -0,0 +1,611 @@ -+/* -+ * Device Tree overlay for fbtft drivers -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835"; -+ -+ /* adafruit18 */ -+ fragment@0 { -+ target = <&display>; -+ __dormant__ { -+ compatible = "sitronix,st7735r"; -+ spi-max-frequency = <32000000>; -+ gamma = "02 1c 07 12 37 32 29 2d 29 25 2B 39 00 01 03 10\n03 1d 07 06 2E 2C 29 2D 2E 2E 37 3F 00 00 02 10"; -+ }; -+ }; -+ -+ /* adafruit22 */ -+ fragment@1 { -+ target = <&display>; -+ __dormant__ { -+ compatible = "himax,hx8340bn"; -+ spi-max-frequency = <32000000>; -+ buswidth = <9>; -+ bgr; -+ }; -+ }; -+ -+ /* adafruit22a */ -+ fragment@2 { -+ target = <&display>; -+ __dormant__ { -+ compatible = "ilitek,ili9340"; -+ spi-max-frequency = <32000000>; -+ bgr; -+ }; -+ }; -+ -+ /* adafruit28 */ -+ fragment@3 { -+ target = <&display>; -+ __dormant__ { -+ compatible = "ilitek,ili9341"; -+ spi-max-frequency = <32000000>; -+ bgr; -+ }; -+ }; -+ -+ /* adafruit13m */ -+ fragment@4 { -+ target = <&display>; -+ __dormant__ { -+ compatible = "solomon,ssd1306"; -+ spi-max-frequency = <16000000>; -+ }; -+ }; -+ -+ /* admatec_c-berry28 */ -+ fragment@5 { -+ target = <&display>; -+ __dormant__ { -+ compatible = "sitronix,st7789v"; -+ spi-max-frequency = <48000000>; -+ init = <0x01000011 -+ 0x02000078 -+ 0x0100003A 0x05 -+ 0x010000B2 0x0C 0x0C 0x00 0x33 0x33 -+ 0x010000B7 0x35 -+ 0x010000C2 0x01 0xFF -+ 0x010000C3 0x17 -+ 0x010000C4 0x20 -+ 0x010000BB 0x17 -+ 0x010000C5 0x20 -+ 0x010000D0 0xA4 0xA1 -+ 0x01000029>; -+ gamma = "D0 00 14 15 13 2C 42 43 4E 09 16 14 18 21\nD0 00 14 15 13 0B 43 55 53 0C 17 14 23 20"; -+ }; -+ }; -+ -+ /* dogs102 */ -+ fragment@6 { -+ target = <&display>; -+ __dormant__ { -+ compatible = "UltraChip,uc1701"; -+ spi-max-frequency = <8000000>; -+ bgr; -+ }; -+ }; -+ -+ /* er_tftm050_2 */ -+ fragment@7 { -+ target = <&display>; -+ __dormant__ { -+ compatible = "raio,ra8875"; -+ spi-max-frequency = <5000000>; -+ spi-cpha; -+ spi-cpol; -+ width = <480>; -+ height = <272>; -+ bgr; -+ }; -+ }; -+ -+ /* er_tftm070_5 */ -+ fragment@8 { -+ target = <&display>; -+ __dormant__ { -+ compatible = "raio,ra8875"; -+ spi-max-frequency = <5000000>; -+ spi-cpha; -+ spi-cpol; -+ width = <800>; -+ height = <480>; -+ bgr; -+ }; -+ }; -+ -+ /* ew24ha0 */ -+ fragment@9 { -+ target = <&display>; -+ __dormant__ { -+ compatible = "ultrachip,uc1611"; -+ spi-max-frequency = <32000000>; -+ spi-cpha; -+ spi-cpol; -+ }; -+ }; -+ -+ /* ew24ha0_9bit */ -+ fragment@10 { -+ target = <&display>; -+ __dormant__ { -+ compatible = "ultrachip,uc1611"; -+ spi-max-frequency = <32000000>; -+ spi-cpha; -+ spi-cpol; -+ buswidth = <9>; -+ }; -+ }; -+ -+ /* freetronicsoled128 */ -+ fragment@11 { -+ target = <&display>; -+ __dormant__ { -+ compatible = "solomon,ssd1351"; -+ spi-max-frequency = <20000000>; -+ backlight = <2>; /* FBTFT_ONBOARD_BACKLIGHT */ -+ bgr; -+ }; -+ }; -+ -+ /* hy28a */ -+ fragment@12 { -+ target = <&display>; -+ __dormant__ { -+ compatible = "ilitek,ili9320"; -+ spi-max-frequency = <32000000>; -+ spi-cpha; -+ spi-cpol; -+ startbyte = <0x70>; -+ bgr; -+ }; -+ }; -+ -+ /* hy28b */ -+ fragment@13 { -+ target = <&display>; -+ __dormant__ { -+ compatible = "ilitek,ili9325"; -+ spi-max-frequency = <48000000>; -+ spi-cpha; -+ spi-cpol; -+ init = <0x010000e7 0x0010 -+ 0x01000000 0x0001 -+ 0x01000001 0x0100 -+ 0x01000002 0x0700 -+ 0x01000003 0x1030 -+ 0x01000004 0x0000 -+ 0x01000008 0x0207 -+ 0x01000009 0x0000 -+ 0x0100000a 0x0000 -+ 0x0100000c 0x0001 -+ 0x0100000d 0x0000 -+ 0x0100000f 0x0000 -+ 0x01000010 0x0000 -+ 0x01000011 0x0007 -+ 0x01000012 0x0000 -+ 0x01000013 0x0000 -+ 0x02000032 -+ 0x01000010 0x1590 -+ 0x01000011 0x0227 -+ 0x02000032 -+ 0x01000012 0x009c -+ 0x02000032 -+ 0x01000013 0x1900 -+ 0x01000029 0x0023 -+ 0x0100002b 0x000e -+ 0x02000032 -+ 0x01000020 0x0000 -+ 0x01000021 0x0000 -+ 0x02000032 -+ 0x01000050 0x0000 -+ 0x01000051 0x00ef -+ 0x01000052 0x0000 -+ 0x01000053 0x013f -+ 0x01000060 0xa700 -+ 0x01000061 0x0001 -+ 0x0100006a 0x0000 -+ 0x01000080 0x0000 -+ 0x01000081 0x0000 -+ 0x01000082 0x0000 -+ 0x01000083 0x0000 -+ 0x01000084 0x0000 -+ 0x01000085 0x0000 -+ 0x01000090 0x0010 -+ 0x01000092 0x0000 -+ 0x01000093 0x0003 -+ 0x01000095 0x0110 -+ 0x01000097 0x0000 -+ 0x01000098 0x0000 -+ 0x01000007 0x0133 -+ 0x01000020 0x0000 -+ 0x01000021 0x0000 -+ 0x02000064>; -+ startbyte = <0x70>; -+ bgr; -+ fps = <50>; -+ gamma = "04 1F 4 7 7 0 7 7 6 0\n0F 00 1 7 4 0 0 0 6 7"; -+ }; -+ }; -+ -+ /* itdb28_spi */ -+ fragment@14 { -+ target = <&display>; -+ __dormant__ { -+ compatible = "ilitek,ili9325"; -+ spi-max-frequency = <32000000>; -+ bgr; -+ }; -+ }; -+ -+ /* mi0283qt-2 */ -+ fragment@15 { -+ target = <&display>; -+ __dormant__ { -+ compatible = "himax,hx8347d"; -+ spi-max-frequency = <32000000>; -+ startbyte = <0x70>; -+ bgr; -+ }; -+ }; -+ -+ /* mi0283qt-9a */ -+ fragment@16 { -+ target = <&display>; -+ __dormant__ { -+ compatible = "ilitek,ili9341"; -+ spi-max-frequency = <32000000>; -+ buswidth = <9>; -+ bgr; -+ }; -+ }; -+ -+ /* nokia3310 */ -+ fragment@17 { -+ target = <&display>; -+ __dormant__ { -+ compatible = "philips,pcd8544"; -+ spi-max-frequency = <400000>; -+ }; -+ }; -+ -+ /* nokia3310a */ -+ fragment@18 { -+ target = <&display>; -+ __dormant__ { -+ compatible = "teralane,tls8204"; -+ spi-max-frequency = <1000000>; -+ }; -+ }; -+ -+ /* nokia5110 */ -+ fragment@19 { -+ target = <&display>; -+ __dormant__ { -+ compatible = "ilitek,ili9163"; -+ spi-max-frequency = <12000000>; -+ bgr; -+ }; -+ }; -+ -+ /* piscreen */ -+ fragment@20 { -+ target = <&display>; -+ __dormant__ { -+ compatible = "ilitek,ili9486"; -+ spi-max-frequency = <32000000>; -+ regwidth = <16>; -+ bgr; -+ }; -+ }; -+ -+ /* pitft */ -+ fragment@21 { -+ target = <&display>; -+ __dormant__ { -+ compatible = "ilitek,ili9340"; -+ spi-max-frequency = <32000000>; -+ init = <0x01000001 -+ 0x02000005 -+ 0x01000028 -+ 0x010000EF 0x03 0x80 0x02 -+ 0x010000CF 0x00 0xC1 0x30 -+ 0x010000ED 0x64 0x03 0x12 0x81 -+ 0x010000E8 0x85 0x00 0x78 -+ 0x010000CB 0x39 0x2C 0x00 0x34 0x02 -+ 0x010000F7 0x20 -+ 0x010000EA 0x00 0x00 -+ 0x010000C0 0x23 -+ 0x010000C1 0x10 -+ 0x010000C5 0x3E 0x28 -+ 0x010000C7 0x86 -+ 0x0100003A 0x55 -+ 0x010000B1 0x00 0x18 -+ 0x010000B6 0x08 0x82 0x27 -+ 0x010000F2 0x00 -+ 0x01000026 0x01 -+ 0x010000E0 0x0F 0x31 0x2B 0x0C 0x0E 0x08 0x4E 0xF1 0x37 0x07 0x10 0x03 0x0E 0x09 0x00 -+ 0x010000E1 0x00 0x0E 0x14 0x03 0x11 0x07 0x31 0xC1 0x48 0x08 0x0F 0x0C 0x31 0x36 0x0F -+ 0x01000011 -+ 0x02000064 -+ 0x01000029 -+ 0x02000014>; -+ bgr; -+ }; -+ }; -+ -+ /* pioled */ -+ fragment@22 { -+ target = <&display>; -+ __dormant__ { -+ compatible = "solomon,ssd1351"; -+ spi-max-frequency = <20000000>; -+ bgr; -+ gamma = "0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4"; -+ }; -+ }; -+ -+ /* rpi-display */ -+ fragment@23 { -+ target = <&display>; -+ __dormant__ { -+ compatible = "ilitek,ili9341"; -+ spi-max-frequency = <32000000>; -+ bgr; -+ }; -+ }; -+ -+ /* sainsmart18 */ -+ fragment@24 { -+ target = <&display>; -+ __dormant__ { -+ compatible = "sitronix,st7735r"; -+ spi-max-frequency = <32000000>; -+ }; -+ }; -+ -+ /* sainsmart32_spi */ -+ fragment@25 { -+ target = <&display>; -+ __dormant__ { -+ compatible = "solomon,ssd1289"; -+ spi-max-frequency = <16000000>; -+ bgr; -+ }; -+ }; -+ -+ /* tinylcd35 */ -+ fragment@26 { -+ target = <&display>; -+ __dormant__ { -+ compatible = "neosec,tinylcd"; -+ spi-max-frequency = <32000000>; -+ bgr; -+ }; -+ }; -+ -+ /* tm022hdh26 */ -+ fragment@27 { -+ target = <&display>; -+ __dormant__ { -+ compatible = "ilitek,ili9341"; -+ spi-max-frequency = <32000000>; -+ bgr; -+ }; -+ }; -+ -+ /* tontec35_9481 - boards before 02 July 2014 */ -+ fragment@28 { -+ target = <&display>; -+ __dormant__ { -+ compatible = "ilitek,ili9481"; -+ spi-max-frequency = <128000000>; -+ spi-cpha; -+ spi-cpol; -+ bgr; -+ }; -+ }; -+ -+ /* tontec35_9486 - boards after 02 July 2014 */ -+ fragment@29 { -+ target = <&display>; -+ __dormant__ { -+ compatible = "ilitek,ili9486"; -+ spi-max-frequency = <128000000>; -+ spi-cpha; -+ spi-cpol; -+ bgr; -+ }; -+ }; -+ -+ /* waveshare32b */ -+ fragment@30 { -+ target = <&display>; -+ __dormant__ { -+ compatible = "ilitek,ili9340"; -+ spi-max-frequency = <48000000>; -+ init = <0x010000CB 0x39 0x2C 0x00 0x34 0x02 -+ 0x010000CF 0x00 0xC1 0x30 -+ 0x010000E8 0x85 0x00 0x78 -+ 0x010000EA 0x00 0x00 -+ 0x010000ED 0x64 0x03 0x12 0x81 -+ 0x010000F7 0x20 -+ 0x010000C0 0x23 -+ 0x010000C1 0x10 -+ 0x010000C5 0x3E 0x28 -+ 0x010000C7 0x86 -+ 0x01000036 0x28 -+ 0x0100003A 0x55 -+ 0x010000B1 0x00 0x18 -+ 0x010000B6 0x08 0x82 0x27 -+ 0x010000F2 0x00 -+ 0x01000026 0x01 -+ 0x010000E0 0x0F 0x31 0x2B 0x0C 0x0E 0x08 0x4E 0xF1 0x37 0x07 0x10 0x03 0x0E 0x09 0x00 -+ 0x010000E1 0x00 0x0E 0x14 0x03 0x11 0x07 0x31 0xC1 0x48 0x08 0x0F 0x0C 0x31 0x36 0x0F -+ 0x01000011 -+ 0x02000078 -+ 0x01000029 -+ 0x0100002C>; -+ bgr; -+ }; -+ }; -+ -+ /* waveshare22 */ -+ fragment@31 { -+ target = <&display>; -+ __dormant__ { -+ compatible = "hitachi,bd663474"; -+ spi-max-frequency = <32000000>; -+ spi-cpha; -+ spi-cpol; -+ }; -+ }; -+ -+ spidev_fragment: fragment@100 { -+ target-path = "spi0/spidev@0"; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; -+ -+ display_fragment: fragment@101 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ status = "okay"; -+ -+ display: display@0{ -+ reg = <0>; -+ spi-max-frequency = <32000000>; -+ fps = <30>; -+ buswidth = <8>; -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ spi0-0 = <&display_fragment>, "target:0=",<&spi0>, -+ <&spidev_fragment>, "target-path=spi0/spidev@0", -+ <&display>, "reg:0=0"; -+ spi0-1 = <&display_fragment>, "target:0=",<&spi0>, -+ <&spidev_fragment>, "target-path=spi0/spidev@1", -+ <&display>, "reg:0=1"; -+ spi1-0 = <&display_fragment>, "target:0=",<&spi1>, -+ <&spidev_fragment>, "target-path=spi1/spidev@0", -+ <&display>, "reg:0=0"; -+ spi1-1 = <&display_fragment>, "target:0=",<&spi1>, -+ <&spidev_fragment>, "target-path=spi1/spidev@1", -+ <&display>, "reg:0=1"; -+ spi1-2 = <&display_fragment>, "target:0=",<&spi1>, -+ <&spidev_fragment>, "target-path=spi1/spidev@2", -+ <&display>, "reg:0=2"; -+ spi2-0 = <&display_fragment>, "target:0=",<&spi2>, -+ <&spidev_fragment>, "target-path=spi2/spidev@0", -+ <&display>, "reg:0=0"; -+ spi2-1 = <&display_fragment>, "target:0=",<&spi2>, -+ <&spidev_fragment>, "target-path=spi2/spidev@1", -+ <&display>, "reg:0=1"; -+ spi2-2 = <&display_fragment>, "target:0=",<&spi2>, -+ <&spidev_fragment>, "target-path=spi2/spidev@2", -+ <&display>, "reg:0=2"; -+ -+ speed = <&display>, "spi-max-frequency:0"; -+ cpha = <&display>, "spi-cpha?"; -+ cpol = <&display>, "spi-cpol?"; -+ -+ /* Displays */ -+ adafruit18 = <0>, "+0"; -+ adafruit22 = <0>, "+1"; -+ adafruit22a = <0>, "+2"; -+ adafruit28 = <0>, "+3"; -+ adafruit13m = <0>, "+4"; -+ admatec_c-berry28 = <0>, "+5"; -+ dogs102 = <0>, "+6"; -+ er_tftm050_2 = <0>, "+7"; -+ er_tftm070_5 = <0>, "+8"; -+ ew24ha0 = <0>, "+9"; -+ ew24ha0_9bit = <0>, "+10"; -+ freetronicsoled128 = <0>, "+11"; -+ hy28a = <0>, "+12"; -+ hy28b = <0>, "+13"; -+ itdb28_spi = <0>, "+14"; -+ mi0283qt-2 = <0>, "+15"; -+ mi0283qt-9a = <0>, "+16"; -+ nokia3310 = <0>, "+17"; -+ nokia3310a = <0>, "+18"; -+ nokia5110 = <0>, "+19"; -+ piscreen = <0>, "+20"; -+ pitft = <0>, "+21"; -+ pioled = <0>, "+22"; -+ rpi-display = <0>, "+23"; -+ sainsmart18 = <0>, "+24"; -+ sainsmart32_spi = <0>, "+25"; -+ tinylcd35 = <0>, "+26"; -+ tm022hdh26 = <0>, "+27"; -+ tontec35_9481 = <0>, "+28"; -+ tontec35_9486 = <0>, "+29"; -+ waveshare32b = <0>, "+30"; -+ waveshare22 = <0>, "+31"; -+ -+ /* Controllers */ -+ bd663474 = <&display>, "compatible=hitachi,bd663474"; -+ hx8340bn = <&display>, "compatible=himax,hx8340bn"; -+ hx8347d = <&display>, "compatible=himax,hx8347d"; -+ hx8353d = <&display>, "compatible=himax,hx8353d"; -+ hx8357d = <&display>, "compatible=himax,hx8357d"; -+ ili9163 = <&display>, "compatible=ilitek,ili9163"; -+ ili9320 = <&display>, "compatible=ilitek,ili9320"; -+ ili9325 = <&display>, "compatible=ilitek,ili9325"; -+ ili9340 = <&display>, "compatible=ilitek,ili9340"; -+ ili9341 = <&display>, "compatible=ilitek,ili9341"; -+ ili9481 = <&display>, "compatible=ilitek,ili9481"; -+ ili9486 = <&display>, "compatible=ilitek,ili9486"; -+ pcd8544 = <&display>, "compatible=philips,pcd8544"; -+ ra8875 = <&display>, "compatible=raio,ra8875"; -+ s6d02a1 = <&display>, "compatible=samsung,s6d02a1"; -+ s6d1121 = <&display>, "compatible=samsung,s6d1121"; -+ seps525 = <&display>, "compatible=syncoam,seps525"; -+ sh1106 = <&display>, "compatible=sinowealth,sh1106"; -+ ssd1289 = <&display>, "compatible=solomon,ssd1289"; -+ ssd1305 = <&display>, "compatible=solomon,ssd1305"; -+ ssd1306 = <&display>, "compatible=solomon,ssd1306"; -+ ssd1325 = <&display>, "compatible=solomon,ssd1325"; -+ ssd1331 = <&display>, "compatible=solomon,ssd1331"; -+ ssd1351 = <&display>, "compatible=solomon,ssd1351"; -+ st7735r = <&display>, "compatible=sitronix,st7735r"; -+ st7789v = <&display>, "compatible=sitronix,st7789v"; -+ tls8204 = <&display>, "compatible=teralane,tls8204"; -+ uc1611 = <&display>, "compatible=ultrachip,uc1611"; -+ uc1701 = <&display>, "compatible=UltraChip,uc1701"; -+ upd161704 = <&display>, "compatible=nec,upd161704"; -+ -+ width = <&display>, "width:0"; -+ height = <&display>, "height:0"; -+ regwidth = <&display>, "regwidth:0"; -+ buswidth = <&display>, "buswidth:0"; -+ debug = <&display>, "debug:0"; -+ rotate = <&display>, "rotate:0"; -+ bgr = <&display>, "bgr?"; -+ fps = <&display>, "fps:0"; -+ txbuflen = <&display>, "txbuflen:0"; -+ startbyte = <&display>, "startbyte:0"; -+ gamma = <&display>, "gamma"; -+ -+ reset_pin = <&display>, "reset-gpios:0=", <&gpio>, -+ <&display>, "reset-gpios:4", -+ <&display>, "reset-gpios:8=1"; /* GPIO_ACTIVE_LOW */ -+ dc_pin = <&display>, "dc-gpios:0=", <&gpio>, -+ <&display>, "dc-gpios:4", -+ <&display>, "dc-gpios:8=0"; /* GPIO_ACTIVE_HIGH */ -+ led_pin = <&display>, "led-gpios:0=", <&gpio>, -+ <&display>, "led-gpios:4", -+ <&display>, "led-gpios:8=0"; /* GPIO_ACTIVE_HIGH */ -+ }; -+}; diff --git a/target/linux/bcm27xx/patches-5.15/950-0566-overlays-Additional-parameters-for-gpio-poweroff.patch b/target/linux/bcm27xx/patches-5.15/950-0566-overlays-Additional-parameters-for-gpio-poweroff.patch deleted file mode 100644 index e6c7b5fd1..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0566-overlays-Additional-parameters-for-gpio-poweroff.patch +++ /dev/null @@ -1,50 +0,0 @@ -From ae5bd19ff96560fb75a75c7d2374bed60bbd9669 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 11 Nov 2021 10:24:02 +0000 -Subject: [PATCH] overlays: Additional parameters for gpio-poweroff - -The gpio-poweroff driver supports active-delay-ms and inactive-delay-ms -properties. Add parameters to set these parameters - active_delay_ms -and inactive_delay_ms. - -See: https://forums.raspberrypi.com/viewtopic.php?t=323508 - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/overlays/README | 7 +++++++ - arch/arm/boot/dts/overlays/gpio-poweroff-overlay.dts | 2 ++ - 2 files changed, 9 insertions(+) - ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -1155,6 +1155,11 @@ Info: Drives a GPIO high or low on pow - or reboot). This also disables the ability to trigger a boot by driving - GPIO3 low. - -+ The GPIO starts in an inactive state. At poweroff time it is driven -+ active for 100ms, then inactive for 100ms, then active again. It is -+ safe to remove the power at any point after the initial activation of -+ the GPIO. -+ - Users of this overlay are required to provide an external mechanism to - switch off the power supply when signalled - failure to do so results - in a kernel BUG, increased power consumption and undefined behaviour. -@@ -1170,6 +1175,8 @@ Params: gpiopin GPIO for - input Set if the gpio pin should be configured as - an input. - export Set to export the configured pin to sysfs -+ active_delay_ms Initial GPIO active period (default 100) -+ inactive_delay_ms Subsequent GPIO inactive period (default 100) - timeout_ms Specify (in ms) how long the kernel waits for - power-down before issuing a WARN (default 3000). - ---- a/arch/arm/boot/dts/overlays/gpio-poweroff-overlay.dts -+++ b/arch/arm/boot/dts/overlays/gpio-poweroff-overlay.dts -@@ -33,5 +33,7 @@ - input = <&power_ctrl>,"input?"; - export = <&power_ctrl>,"export?"; - timeout_ms = <&power_ctrl>,"timeout-ms:0"; -+ active_delay_ms = <&power_ctrl>,"active-delay-ms:0"; -+ inactive_delay_ms = <&power_ctrl>,"inactive-delay-ms:0"; - }; - }; diff --git a/target/linux/bcm27xx/patches-5.15/950-0567-drm-Fix-double-free-from-checking-if-gamma-lut-has-b.patch b/target/linux/bcm27xx/patches-5.15/950-0567-drm-Fix-double-free-from-checking-if-gamma-lut-has-b.patch deleted file mode 100644 index c0aee3797..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0567-drm-Fix-double-free-from-checking-if-gamma-lut-has-b.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 3e52ea57180471250ba4bb426527ab9bbad4e5a4 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 8 Nov 2021 13:55:15 +0000 -Subject: [PATCH] drm: Fix double free from checking if gamma lut has - been updated - -The code falls through to "fail" under all conditions, so there is no -need for the drm_property_blob_put if the gamma lut hasn't been changed. -Fixes: 9cca26674a2b "drm: Check whether the gamma lut has changed before updating" - -Signed-off-by: Dave Stevenson ---- - drivers/gpu/drm/drm_color_mgmt.c | 2 -- - 1 file changed, 2 deletions(-) - ---- a/drivers/gpu/drm/drm_color_mgmt.c -+++ b/drivers/gpu/drm/drm_color_mgmt.c -@@ -330,8 +330,6 @@ static int drm_crtc_legacy_gamma_set(str - memcmp(crtc_state->gamma_lut->data, blob_data, blob->length)) - replaced |= drm_property_replace_blob(&crtc_state->gamma_lut, - use_gamma_lut ? blob : NULL); -- else -- drm_property_blob_put(blob); - crtc_state->color_mgmt_changed |= replaced; - - ret = drm_atomic_commit(state); diff --git a/target/linux/bcm27xx/patches-5.15/950-0570-dtoverlays-Remove-i2c0mux-and-i20if-status-from-edt-.patch b/target/linux/bcm27xx/patches-5.15/950-0570-dtoverlays-Remove-i2c0mux-and-i20if-status-from-edt-.patch deleted file mode 100644 index be5648c02..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0570-dtoverlays-Remove-i2c0mux-and-i20if-status-from-edt-.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 064acb7882a7d9897dc5f8117ca9a94970387701 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Wed, 10 Nov 2021 15:55:32 +0000 -Subject: [PATCH] dtoverlays: Remove i2c0mux and i20if status from - edt-ft5406.dtsi - -edt-ft5406.dtsi is included from vc4-kms-dsi-7inch which was -also setting i2c0mux and i2c0if status fields. This meant that -dtoverlay wouldn't apply the overlay due to multiple fragments -changing the same parameter. - -Move the enable from edt-ft5406.dtsi to edt-ft5406-overlay.dts -for when it should be needed as an independent overlay. - -Signed-off-by: Dave Stevenson ---- - .../arm/boot/dts/overlays/edt-ft5406-overlay.dts | 16 ++++++++++++++++ - arch/arm/boot/dts/overlays/edt-ft5406.dtsi | 8 -------- - .../dts/overlays/vc4-kms-dsi-7inch-overlay.dts | 2 +- - 3 files changed, 17 insertions(+), 9 deletions(-) - ---- a/arch/arm/boot/dts/overlays/edt-ft5406-overlay.dts -+++ b/arch/arm/boot/dts/overlays/edt-ft5406-overlay.dts -@@ -8,3 +8,19 @@ - /plugin/; - - #include "edt-ft5406.dtsi" -+ -+/ { -+ fragment@0 { -+ target = <&i2c0if>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2c0mux>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+}; ---- a/arch/arm/boot/dts/overlays/edt-ft5406.dtsi -+++ b/arch/arm/boot/dts/overlays/edt-ft5406.dtsi -@@ -27,7 +27,6 @@ - __overlay__ { - #address-cells = <1>; - #size-cells = <0>; -- status = "okay"; - ft5406: ts@38 { - compatible = "edt,edt-ft5406"; - reg = <0x38>; -@@ -38,13 +37,6 @@ - }; - }; - -- fragment@13 { -- target = <&i2c0if>; -- __overlay__ { -- status = "okay"; -- }; -- }; -- - __overrides__ { - sizex = <&ft5406>,"touchscreen-size-x:0"; - sizey = <&ft5406>,"touchscreen-size-y:0"; ---- a/arch/arm/boot/dts/overlays/vc4-kms-dsi-7inch-overlay.dts -+++ b/arch/arm/boot/dts/overlays/vc4-kms-dsi-7inch-overlay.dts -@@ -113,6 +113,6 @@ - }; - - __overrides__ { -- disable_touch = <0>, "-10-11-12-13"; -+ disable_touch = <0>, "-10-11-12"; - }; - }; diff --git a/target/linux/bcm27xx/patches-5.15/950-0572-drm-vc4-Don-t-try-disabling-SCDC-on-Pi0-3.patch b/target/linux/bcm27xx/patches-5.15/950-0572-drm-vc4-Don-t-try-disabling-SCDC-on-Pi0-3.patch deleted file mode 100644 index 3bb136f3c..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0572-drm-vc4-Don-t-try-disabling-SCDC-on-Pi0-3.patch +++ /dev/null @@ -1,32 +0,0 @@ -From e1ee82fdfdba0b210974cf3ccc0048c5aeb83bc6 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 16 Nov 2021 10:34:34 +0000 -Subject: [PATCH] drm/vc4: Don't try disabling SCDC on Pi0-3. - -The code that set the scdc_enabled flag to ensure it was -disabled at boot time also ran on Pi0-3 where there is no -SCDC support. This lead to a warning in vc4_hdmi_encoder_post_crtc_disable -due to vc4_hdmi_disable_scrambling being called and trying to -read (and write) register HDMI_SCRAMBLER_CTL which doesn't -exist on those platforms. - -Only set the flag should the interface be configured to support -more than HDMI 1.4. - -Signed-off-by: Dave Stevenson ---- - drivers/gpu/drm/vc4/vc4_hdmi.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/gpu/drm/vc4/vc4_hdmi.c -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c -@@ -2558,7 +2558,8 @@ static int vc4_hdmi_bind(struct device * - * vc4_hdmi_disable_scrambling() will thus run at boot, make - * sure it's disabled, and avoid any inconsistency. - */ -- vc4_hdmi->scdc_enabled = true; -+ if (variant->max_pixel_clock > HDMI_14_MAX_TMDS_CLK) -+ vc4_hdmi->scdc_enabled = true; - - ret = variant->init_resources(vc4_hdmi); - if (ret) diff --git a/target/linux/bcm27xx/patches-5.15/950-0576-Pass-V4L2_CID_MPEG_VIDEO_H264_MIN_QP-MAX_QP-to-bcm28.patch b/target/linux/bcm27xx/patches-5.15/950-0576-Pass-V4L2_CID_MPEG_VIDEO_H264_MIN_QP-MAX_QP-to-bcm28.patch deleted file mode 100644 index 68f1d1ab7..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0576-Pass-V4L2_CID_MPEG_VIDEO_H264_MIN_QP-MAX_QP-to-bcm28.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 3d21c93db479bf4269630676ba7d48dec9bf75fc Mon Sep 17 00:00:00 2001 -From: Maxim Devaev -Date: Wed, 17 Nov 2021 04:57:56 +0300 -Subject: [PATCH] Pass V4L2_CID_MPEG_VIDEO_H264_MIN_QP/MAX_QP to - bcm2835-v4l2-codec - -Following raspberrypi/linux#4704. This is necessary to set up -quantization for variable bitrate to avoid video flickering. ---- - .../bcm2835-codec/bcm2835-v4l2-codec.c | 32 ++++++++++++++++++- - 1 file changed, 31 insertions(+), 1 deletion(-) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -2187,6 +2187,28 @@ static int bcm2835_codec_s_ctrl(struct v - ret = bcm2835_codec_set_level_profile(ctx, ctrl); - break; - -+ case V4L2_CID_MPEG_VIDEO_H264_MIN_QP: -+ if (!ctx->component) -+ break; -+ -+ ret = vchiq_mmal_port_parameter_set(ctx->dev->instance, -+ &ctx->component->output[0], -+ MMAL_PARAMETER_VIDEO_ENCODE_MIN_QUANT, -+ &ctrl->val, -+ sizeof(ctrl->val)); -+ break; -+ -+ case V4L2_CID_MPEG_VIDEO_H264_MAX_QP: -+ if (!ctx->component) -+ break; -+ -+ ret = vchiq_mmal_port_parameter_set(ctx->dev->instance, -+ &ctx->component->output[0], -+ MMAL_PARAMETER_VIDEO_ENCODE_MAX_QUANT, -+ &ctrl->val, -+ sizeof(ctrl->val)); -+ break; -+ - case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME: { - u32 mmal_bool = 1; - -@@ -3103,7 +3125,7 @@ static int bcm2835_codec_open(struct fil - case ENCODE: - { - /* Encode controls */ -- v4l2_ctrl_handler_init(hdl, 9); -+ v4l2_ctrl_handler_init(hdl, 11); - - v4l2_ctrl_new_std_menu(hdl, &bcm2835_codec_ctrl_ops, - V4L2_CID_MPEG_VIDEO_BITRATE_MODE, -@@ -3152,6 +3174,14 @@ static int bcm2835_codec_open(struct fil - BIT(V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)), - V4L2_MPEG_VIDEO_H264_PROFILE_HIGH); - v4l2_ctrl_new_std(hdl, &bcm2835_codec_ctrl_ops, -+ V4L2_CID_MPEG_VIDEO_H264_MIN_QP, -+ 0, 51, -+ 1, 20); -+ v4l2_ctrl_new_std(hdl, &bcm2835_codec_ctrl_ops, -+ V4L2_CID_MPEG_VIDEO_H264_MAX_QP, -+ 0, 51, -+ 1, 51); -+ v4l2_ctrl_new_std(hdl, &bcm2835_codec_ctrl_ops, - V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME, - 0, 0, 0, 0); - if (hdl->error) { diff --git a/target/linux/bcm27xx/patches-5.15/950-0577-ARM-dts-Update-rpi-400-and-cm4-dts-to-match-4-b.patch b/target/linux/bcm27xx/patches-5.15/950-0577-ARM-dts-Update-rpi-400-and-cm4-dts-to-match-4-b.patch deleted file mode 100644 index 00223ef0c..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0577-ARM-dts-Update-rpi-400-and-cm4-dts-to-match-4-b.patch +++ /dev/null @@ -1,293 +0,0 @@ -From 34e658087e54db26ebd86f86a1549a393002a9ad Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 26 Nov 2021 15:20:06 +0000 -Subject: [PATCH] ARM: dts: Update rpi-400 and cm4 dts to match 4-b - -The Pi 4B dts file has had numerous updates since the Pi 400 and CM4 -dts files were written. Apply those updates to the other files to -minimise the differences. The change is largely cosmetic, except for -the PCI "device-type" to "device_type" rename, and the correction of -the labels on the Pi 400 GPIO expander pins. - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/bcm2711-rpi-400.dts | 90 ++++-------------------- - arch/arm/boot/dts/bcm2711-rpi-cm4.dts | 98 ++++++--------------------- - 2 files changed, 36 insertions(+), 152 deletions(-) - ---- a/arch/arm/boot/dts/bcm2711-rpi-400.dts -+++ b/arch/arm/boot/dts/bcm2711-rpi-400.dts -@@ -1,9 +1,8 @@ - // SPDX-License-Identifier: GPL-2.0 - /dts-v1/; - #include "bcm2711.dtsi" --#include "bcm2835-rpi.dtsi" -- --#include -+#include "bcm2711-rpi.dtsi" -+//#include "bcm283x-rpi-usb-peripheral.dtsi" - - / { - compatible = "raspberrypi,400", "brcm,bcm2711"; -@@ -14,19 +13,6 @@ - stdout-path = "serial1:115200n8"; - }; - -- /* Will be filled by the bootloader */ -- memory@0 { -- device_type = "memory"; -- reg = <0 0 0>; -- }; -- -- aliases { -- emmc2bus = &emmc2bus; -- ethernet0 = &genet; -- pcie0 = &pcie0; -- blconfig = &blconfig; -- }; -- - leds { - led-act { - gpios = <&gpio 42 GPIO_ACTIVE_HIGH>; -@@ -54,8 +40,8 @@ - regulator-always-on; - regulator-settling-time-us = <5000>; - gpios = <&expgpio 4 GPIO_ACTIVE_HIGH>; -- states = <1800000 0x1 -- 3300000 0x0>; -+ states = <1800000 0x1>, -+ <3300000 0x0>; - status = "okay"; - }; - -@@ -179,23 +165,13 @@ - }; - - &hdmi0 { -- clocks = <&firmware_clocks 13>, <&firmware_clocks 14>, <&dvp 0>, <&clk_27MHz>; -- clock-names = "hdmi", "bvb", "audio", "cec"; -- wifi-2.4ghz-coexistence; - status = "okay"; - }; - - &hdmi1 { -- clocks = <&firmware_clocks 13>, <&firmware_clocks 14>, <&dvp 1>, <&clk_27MHz>; -- clock-names = "hdmi", "bvb", "audio", "cec"; -- wifi-2.4ghz-coexistence; - status = "okay"; - }; - --&hvs { -- clocks = <&firmware_clocks 4>; --}; -- - &pixelvalve0 { - status = "okay"; - }; -@@ -218,22 +194,6 @@ - status = "okay"; - }; - --&rmem { -- /* -- * RPi4's co-processor will copy the board's bootloader configuration -- * into memory for the OS to consume. It'll also update this node with -- * its placement information. -- */ -- blconfig: nvram@0 { -- compatible = "raspberrypi,bootloader-config", "nvmem-rmem"; -- #address-cells = <1>; -- #size-cells = <1>; -- reg = <0x0 0x0 0x0>; -- no-map; -- status = "disabled"; -- }; --}; -- - /* SDHCI is used to control the SDIO for wireless */ - &sdhci { - #address-cells = <1>; -@@ -274,7 +234,7 @@ - - &pcie0 { - pci@0,0 { -- device-type = "pci"; -+ device_type = "pci"; - #address-cells = <3>; - #size-cells = <2>; - ranges; -@@ -282,7 +242,7 @@ - reg = <0 0 0 0 0>; - - usb@0,0 { -- reg = <0x0 0 0 0 0>; -+ reg = <0 0 0 0 0>; - resets = <&reset RASPBERRYPI_FIRMWARE_RESET_ID_USB>; - }; - }; -@@ -309,10 +269,6 @@ - status = "okay"; - }; - --&vchiq { -- interrupts = ; --}; -- - &vc4 { - status = "okay"; - }; ---- a/arch/arm/boot/dts/bcm2711-rpi-cm4.dts -+++ b/arch/arm/boot/dts/bcm2711-rpi-cm4.dts -@@ -1,9 +1,8 @@ - // SPDX-License-Identifier: GPL-2.0 - /dts-v1/; - #include "bcm2711.dtsi" --#include "bcm2835-rpi.dtsi" -- --#include -+#include "bcm2711-rpi.dtsi" -+//#include "bcm283x-rpi-usb-peripheral.dtsi" - - / { - compatible = "raspberrypi,4-compute-module", "brcm,bcm2711"; -@@ -14,19 +13,6 @@ - stdout-path = "serial1:115200n8"; - }; - -- /* Will be filled by the bootloader */ -- memory@0 { -- device_type = "memory"; -- reg = <0 0 0>; -- }; -- -- aliases { -- emmc2bus = &emmc2bus; -- ethernet0 = &genet; -- pcie0 = &pcie0; -- blconfig = &blconfig; -- }; -- - leds { - led-act { - gpios = <&gpio 42 GPIO_ACTIVE_HIGH>; -@@ -54,8 +40,8 @@ - regulator-always-on; - regulator-settling-time-us = <5000>; - gpios = <&expgpio 4 GPIO_ACTIVE_HIGH>; -- states = <1800000 0x1 -- 3300000 0x0>; -+ states = <1800000 0x1>, -+ <3300000 0x0>; - status = "okay"; - }; - -@@ -78,42 +64,26 @@ - status = "okay"; - }; - --&firmware { -- firmware_clocks: clocks { -- compatible = "raspberrypi,firmware-clocks"; -- #clock-cells = <1>; -- }; -- -- expgpio: gpio { -- compatible = "raspberrypi,firmware-gpio"; -- gpio-controller; -- #gpio-cells = <2>; -- gpio-line-names = "BT_ON", -- "WL_ON", -- "PWR_LED_OFF", -- "ANT1", -- "VDD_SD_IO_SEL", -- "CAM_GPIO", -- "SD_PWR_ON", -- "ANT2"; -- status = "okay"; -- -- ant1: ant1 { -- gpio-hog; -- gpios = <3 GPIO_ACTIVE_HIGH>; -- output-high; -- }; -- -- ant2: ant2 { -- gpio-hog; -- gpios = <7 GPIO_ACTIVE_HIGH>; -- output-low; -- }; -- }; -- -- reset: reset { -- compatible = "raspberrypi,firmware-reset"; -- #reset-cells = <1>; -+&expgpio { -+ gpio-line-names = "BT_ON", -+ "WL_ON", -+ "PWR_LED_OFF", -+ "ANT1", -+ "VDD_SD_IO_SEL", -+ "CAM_GPIO", -+ "SD_PWR_ON", -+ "ANT2"; -+ -+ ant1: ant1 { -+ gpio-hog; -+ gpios = <3 GPIO_ACTIVE_HIGH>; -+ output-high; -+ }; -+ -+ ant2: ant2 { -+ gpio-hog; -+ gpios = <7 GPIO_ACTIVE_HIGH>; -+ output-low; - }; - }; - -@@ -191,23 +161,13 @@ - }; - - &hdmi0 { -- clocks = <&firmware_clocks 13>, <&firmware_clocks 14>, <&dvp 0>, <&clk_27MHz>; -- clock-names = "hdmi", "bvb", "audio", "cec"; -- wifi-2.4ghz-coexistence; - status = "okay"; - }; - - &hdmi1 { -- clocks = <&firmware_clocks 13>, <&firmware_clocks 14>, <&dvp 1>, <&clk_27MHz>; -- clock-names = "hdmi", "bvb", "audio", "cec"; -- wifi-2.4ghz-coexistence; - status = "okay"; - }; - --&hvs { -- clocks = <&firmware_clocks 4>; --}; -- - &pixelvalve0 { - status = "okay"; - }; -@@ -230,22 +190,6 @@ - status = "okay"; - }; - --&rmem { -- /* -- * RPi4's co-processor will copy the board's bootloader configuration -- * into memory for the OS to consume. It'll also update this node with -- * its placement information. -- */ -- blconfig: nvram@0 { -- compatible = "raspberrypi,bootloader-config", "nvmem-rmem"; -- #address-cells = <1>; -- #size-cells = <1>; -- reg = <0x0 0x0 0x0>; -- no-map; -- status = "disabled"; -- }; --}; -- - /* SDHCI is used to control the SDIO for wireless */ - &sdhci { - #address-cells = <1>; diff --git a/target/linux/bcm27xx/patches-5.15/950-0579-drm-vc4-Add-support-for-composite-syncs-to-vc4_dpi.patch b/target/linux/bcm27xx/patches-5.15/950-0579-drm-vc4-Add-support-for-composite-syncs-to-vc4_dpi.patch deleted file mode 100644 index a9e79d25b..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0579-drm-vc4-Add-support-for-composite-syncs-to-vc4_dpi.patch +++ /dev/null @@ -1,56 +0,0 @@ -From bbd8dd64c1083232f3da8e097207a5b539ab91c9 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 25 Nov 2021 14:45:33 +0000 -Subject: [PATCH] drm/vc4: Add support for composite syncs to vc4_dpi - -The hardware can combine H&V syncs onto the output enable line -as composite syncs, so add the relevant configuration to do that. - -Signed-off-by: Dave Stevenson ---- - drivers/gpu/drm/vc4/vc4_dpi.c | 25 ++++++++++++++++--------- - 1 file changed, 16 insertions(+), 9 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_dpi.c -+++ b/drivers/gpu/drm/vc4/vc4_dpi.c -@@ -131,7 +131,7 @@ static void vc4_dpi_encoder_enable(struc - struct vc4_dpi *dpi = vc4_encoder->dpi; - struct drm_connector_list_iter conn_iter; - struct drm_connector *connector = NULL, *connector_scan; -- u32 dpi_c = DPI_ENABLE | DPI_OUTPUT_ENABLE_MODE; -+ u32 dpi_c = DPI_ENABLE; - int ret; - - /* Look up the connector attached to DPI so we can get the -@@ -202,15 +202,22 @@ static void vc4_dpi_encoder_enable(struc - dpi_c |= VC4_SET_FIELD(DPI_FORMAT_18BIT_666_RGB_1, DPI_FORMAT); - } - -- if (mode->flags & DRM_MODE_FLAG_NHSYNC) -- dpi_c |= DPI_HSYNC_INVERT; -- else if (!(mode->flags & DRM_MODE_FLAG_PHSYNC)) -- dpi_c |= DPI_HSYNC_DISABLE; -- -- if (mode->flags & DRM_MODE_FLAG_NVSYNC) -- dpi_c |= DPI_VSYNC_INVERT; -- else if (!(mode->flags & DRM_MODE_FLAG_PVSYNC)) -- dpi_c |= DPI_VSYNC_DISABLE; -+ if (mode->flags & DRM_MODE_FLAG_CSYNC) { -+ if (mode->flags & DRM_MODE_FLAG_NCSYNC) -+ dpi_c |= DPI_OUTPUT_ENABLE_INVERT; -+ } else { -+ dpi_c |= DPI_OUTPUT_ENABLE_MODE; -+ -+ if (mode->flags & DRM_MODE_FLAG_NHSYNC) -+ dpi_c |= DPI_HSYNC_INVERT; -+ else if (!(mode->flags & DRM_MODE_FLAG_PHSYNC)) -+ dpi_c |= DPI_HSYNC_DISABLE; -+ -+ if (mode->flags & DRM_MODE_FLAG_NVSYNC) -+ dpi_c |= DPI_VSYNC_INVERT; -+ else if (!(mode->flags & DRM_MODE_FLAG_PVSYNC)) -+ dpi_c |= DPI_VSYNC_DISABLE; -+ } - - DPI_WRITE(DPI_C, dpi_c); - diff --git a/target/linux/bcm27xx/patches-5.15/950-0580-drm-vc4-Ensure-vc4_hdmi-doesn-t-use-2711-HPD-registe.patch b/target/linux/bcm27xx/patches-5.15/950-0580-drm-vc4-Ensure-vc4_hdmi-doesn-t-use-2711-HPD-registe.patch deleted file mode 100644 index 689a3d952..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0580-drm-vc4-Ensure-vc4_hdmi-doesn-t-use-2711-HPD-registe.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 3542a39c5655242ba89bb4f51e9237cbb7e8cf09 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Fri, 19 Nov 2021 16:16:40 +0000 -Subject: [PATCH] drm/vc4: Ensure vc4_hdmi doesn't use 2711 HPD - registers on Pi0-3 - -The existing logic was flawed in that it could try reading the -2711 specific registers for HPD on a CM1/3 where the HPD GPIO -hadn't been defined in DT. - -Ensure we don't do the 2711 register read on invalid hardware, -and then - -Signed-off-by: Dave Stevenson ---- - drivers/gpu/drm/vc4/vc4_hdmi.c | 24 ++++++++++++++++-------- - drivers/gpu/drm/vc4/vc4_hdmi.h | 3 +++ - 2 files changed, 19 insertions(+), 8 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_hdmi.c -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c -@@ -206,14 +206,8 @@ vc4_hdmi_connector_detect(struct drm_con - if (gpiod_get_value_cansleep(vc4_hdmi->hpd_gpio)) - connected = true; - } else { -- unsigned long flags; -- u32 hotplug; -- -- spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); -- hotplug = HDMI_READ(HDMI_HOTPLUG); -- spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); -- -- if (hotplug & VC4_HDMI_HOTPLUG_CONNECTED) -+ if (vc4_hdmi->variant->hp_detect && -+ vc4_hdmi->variant->hp_detect(vc4_hdmi)) - connected = true; - } - -@@ -1356,6 +1350,18 @@ static u32 vc5_hdmi_channel_map(struct v - return channel_map; - } - -+static bool vc5_hdmi_hp_detect(struct vc4_hdmi *vc4_hdmi) -+{ -+ unsigned long flags; -+ u32 hotplug; -+ -+ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); -+ hotplug = HDMI_READ(HDMI_HOTPLUG); -+ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); -+ -+ return !!(hotplug & VC4_HDMI_HOTPLUG_CONNECTED); -+} -+ - /* HDMI audio codec callbacks */ - static void vc4_hdmi_audio_set_mai_clock(struct vc4_hdmi *vc4_hdmi, - unsigned int samplerate) -@@ -2778,6 +2784,7 @@ static const struct vc4_hdmi_variant bcm - .phy_rng_disable = vc5_hdmi_phy_rng_disable, - .channel_map = vc5_hdmi_channel_map, - .supports_hdr = true, -+ .hp_detect = vc5_hdmi_hp_detect, - }; - - static const struct vc4_hdmi_variant bcm2711_hdmi1_variant = { -@@ -2806,6 +2813,7 @@ static const struct vc4_hdmi_variant bcm - .phy_rng_disable = vc5_hdmi_phy_rng_disable, - .channel_map = vc5_hdmi_channel_map, - .supports_hdr = true, -+ .hp_detect = vc5_hdmi_hp_detect, - }; - - static const struct of_device_id vc4_hdmi_dt_match[] = { ---- a/drivers/gpu/drm/vc4/vc4_hdmi.h -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.h -@@ -102,6 +102,9 @@ struct vc4_hdmi_variant { - - /* Enables HDR metadata */ - bool supports_hdr; -+ -+ /* Callback for hardware specific hotplug detect */ -+ bool (*hp_detect)(struct vc4_hdmi *vc4_hdmi); - }; - - /* HDMI audio information */ diff --git a/target/linux/bcm27xx/patches-5.15/950-0582-dtoverlays-Use-edt-ft5506-for-10-points-instead-of-e.patch b/target/linux/bcm27xx/patches-5.15/950-0582-dtoverlays-Use-edt-ft5506-for-10-points-instead-of-e.patch deleted file mode 100644 index f2b9a3203..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0582-dtoverlays-Use-edt-ft5506-for-10-points-instead-of-e.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 8bf783e4a473fdd21efe7ba6a60c9b42a8d1bcb2 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Fri, 26 Nov 2021 16:56:37 +0000 -Subject: [PATCH] dtoverlays: Use edt-ft5506 for 10 points, instead of - edt-ft5x06 - -Whilst all the datasheets describe FT5x06 as supporting "up to -10 points of absolution X and Y coordinates", the driver -implementation for the compatible string "edt,edt-ft5x06" only -allows for 5. - -Switch to the "edt,edt-ft5506" compatible string which allows for -10 points with no other differences. - -Signed-off-by: Dave Stevenson ---- - arch/arm/boot/dts/overlays/edt-ft5406.dtsi | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/arch/arm/boot/dts/overlays/edt-ft5406.dtsi -+++ b/arch/arm/boot/dts/overlays/edt-ft5406.dtsi -@@ -28,7 +28,7 @@ - #address-cells = <1>; - #size-cells = <0>; - ft5406: ts@38 { -- compatible = "edt,edt-ft5406"; -+ compatible = "edt,edt-ft5506"; - reg = <0x38>; - - touchscreen-size-x = < 800 >; diff --git a/target/linux/bcm27xx/patches-5.15/950-0583-staging-bcm2835-codec-bytesperline-for-YUV420-YVU420.patch b/target/linux/bcm27xx/patches-5.15/950-0583-staging-bcm2835-codec-bytesperline-for-YUV420-YVU420.patch deleted file mode 100644 index 7b5529194..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0583-staging-bcm2835-codec-bytesperline-for-YUV420-YVU420.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 18277c9cdbb9d3595d442c97ee80b2c10303aeb9 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Fri, 26 Nov 2021 16:46:22 +0000 -Subject: [PATCH] staging/bcm2835-codec: bytesperline for YUV420/YVU420 - needs to be 64 - -Matching https://github.com/raspberrypi/linux/pull/4419, the ISP -block (which is also used on the input of the encoder, and output -of the decoder) needs the base address of all planes to be aligned -to multiples of 32. This includes the chroma planes of YUV420 and -YVU420. -If the height is only a multiple of 2 (not 4), then you get an odd -number of lines in the second plane, which means the 3rd plane -starts at a multiple of bytesperline/2. - -Set the minimum bytesperline alignment to 64 for those formats -so that the plane alignment is always right. - -Signed-off-by: Dave Stevenson ---- - .../staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -157,14 +157,14 @@ static const struct bcm2835_codec_fmt su - /* YUV formats */ - .fourcc = V4L2_PIX_FMT_YUV420, - .depth = 8, -- .bytesperline_align = 32, -+ .bytesperline_align = 64, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_I420, - .size_multiplier_x2 = 3, - }, { - .fourcc = V4L2_PIX_FMT_YVU420, - .depth = 8, -- .bytesperline_align = 32, -+ .bytesperline_align = 64, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_YV12, - .size_multiplier_x2 = 3, diff --git a/target/linux/bcm27xx/patches-5.15/950-0584-media-rpivid-remove-min_buffers_needed-from-src-queu.patch b/target/linux/bcm27xx/patches-5.15/950-0584-media-rpivid-remove-min_buffers_needed-from-src-queu.patch deleted file mode 100644 index b7cf2c9a6..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0584-media-rpivid-remove-min_buffers_needed-from-src-queu.patch +++ /dev/null @@ -1,25 +0,0 @@ -From c18a8b7b527e97391c212a18906ab07fb5f2f476 Mon Sep 17 00:00:00 2001 -From: John Cox -Date: Mon, 29 Nov 2021 16:39:35 +0000 -Subject: [PATCH] media: rpivid: remove min_buffers_needed from src - queue - -Remove min_buffers_needed=1 from src queue init. Src buffers are bound -to media requests therefore this setting is not needed and generates -a WARN in kernel 5.16. - -Signed-off-by: John Cox ---- - drivers/staging/media/rpivid/rpivid_video.c | 1 - - 1 file changed, 1 deletion(-) - ---- a/drivers/staging/media/rpivid/rpivid_video.c -+++ b/drivers/staging/media/rpivid/rpivid_video.c -@@ -680,7 +680,6 @@ int rpivid_queue_init(void *priv, struct - src_vq->io_modes = VB2_MMAP | VB2_DMABUF; - src_vq->drv_priv = ctx; - src_vq->buf_struct_size = sizeof(struct rpivid_buffer); -- src_vq->min_buffers_needed = 1; - src_vq->ops = &rpivid_qops; - src_vq->mem_ops = &vb2_dma_contig_memops; - src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; diff --git a/target/linux/bcm27xx/patches-5.15/950-0585-staging-bcm2835-codec-Allow-a-different-stride-align.patch b/target/linux/bcm27xx/patches-5.15/950-0585-staging-bcm2835-codec-Allow-a-different-stride-align.patch deleted file mode 100644 index befbc0f96..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0585-staging-bcm2835-codec-Allow-a-different-stride-align.patch +++ /dev/null @@ -1,590 +0,0 @@ -From 9d12ccfea8cdc6d1dbb796a3023e8c8297a4465e Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 29 Nov 2021 19:11:29 +0000 -Subject: [PATCH] staging/bcm2835-codec: Allow a different stride - alignment per role - -Deinterlace and decode aren't affected in the same way as encode -and ISP by the alignment requirement on 3 plane YUV420. -Decode would be affected, but it always aligns the height up to -a macroblock, and uses the selection API to reflect that. - -Add in the facility to set the bytesperline alignment per role. - -Signed-off-by: Dave Stevenson ---- - .../bcm2835-codec/bcm2835-v4l2-codec.c | 135 ++++++++++-------- - 1 file changed, 74 insertions(+), 61 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -88,6 +88,7 @@ enum bcm2835_codec_role { - ENCODE, - ISP, - DEINTERLACE, -+ NUM_ROLES - }; - - static const char * const roles[] = { -@@ -145,7 +146,7 @@ static const char * const components[] = - struct bcm2835_codec_fmt { - u32 fourcc; - int depth; -- int bytesperline_align; -+ u8 bytesperline_align[NUM_ROLES]; - u32 flags; - u32 mmal_fmt; - int size_multiplier_x2; -@@ -157,63 +158,63 @@ static const struct bcm2835_codec_fmt su - /* YUV formats */ - .fourcc = V4L2_PIX_FMT_YUV420, - .depth = 8, -- .bytesperline_align = 64, -+ .bytesperline_align = { 32, 64, 64, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_I420, - .size_multiplier_x2 = 3, - }, { - .fourcc = V4L2_PIX_FMT_YVU420, - .depth = 8, -- .bytesperline_align = 64, -+ .bytesperline_align = { 32, 64, 64, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_YV12, - .size_multiplier_x2 = 3, - }, { - .fourcc = V4L2_PIX_FMT_NV12, - .depth = 8, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_NV12, - .size_multiplier_x2 = 3, - }, { - .fourcc = V4L2_PIX_FMT_NV21, - .depth = 8, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_NV21, - .size_multiplier_x2 = 3, - }, { - .fourcc = V4L2_PIX_FMT_RGB565, - .depth = 16, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_RGB16, - .size_multiplier_x2 = 2, - }, { - .fourcc = V4L2_PIX_FMT_YUYV, - .depth = 16, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_YUYV, - .size_multiplier_x2 = 2, - }, { - .fourcc = V4L2_PIX_FMT_UYVY, - .depth = 16, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_UYVY, - .size_multiplier_x2 = 2, - }, { - .fourcc = V4L2_PIX_FMT_YVYU, - .depth = 16, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_YVYU, - .size_multiplier_x2 = 2, - }, { - .fourcc = V4L2_PIX_FMT_VYUY, - .depth = 16, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_VYUY, - .size_multiplier_x2 = 2, -@@ -221,21 +222,21 @@ static const struct bcm2835_codec_fmt su - /* RGB formats */ - .fourcc = V4L2_PIX_FMT_RGB24, - .depth = 24, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_RGB24, - .size_multiplier_x2 = 2, - }, { - .fourcc = V4L2_PIX_FMT_BGR24, - .depth = 24, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BGR24, - .size_multiplier_x2 = 2, - }, { - .fourcc = V4L2_PIX_FMT_BGR32, - .depth = 32, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BGRA, - .size_multiplier_x2 = 2, -@@ -244,7 +245,7 @@ static const struct bcm2835_codec_fmt su - /* 8 bit */ - .fourcc = V4L2_PIX_FMT_SRGGB8, - .depth = 8, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB8, - .size_multiplier_x2 = 2, -@@ -252,7 +253,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SBGGR8, - .depth = 8, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR8, - .size_multiplier_x2 = 2, -@@ -260,7 +261,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SGRBG8, - .depth = 8, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG8, - .size_multiplier_x2 = 2, -@@ -268,7 +269,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SGBRG8, - .depth = 8, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG8, - .size_multiplier_x2 = 2, -@@ -277,7 +278,7 @@ static const struct bcm2835_codec_fmt su - /* 10 bit */ - .fourcc = V4L2_PIX_FMT_SRGGB10P, - .depth = 10, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB10P, - .size_multiplier_x2 = 2, -@@ -285,7 +286,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SBGGR10P, - .depth = 10, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR10P, - .size_multiplier_x2 = 2, -@@ -293,7 +294,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SGRBG10P, - .depth = 10, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG10P, - .size_multiplier_x2 = 2, -@@ -301,7 +302,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SGBRG10P, - .depth = 10, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG10P, - .size_multiplier_x2 = 2, -@@ -310,7 +311,7 @@ static const struct bcm2835_codec_fmt su - /* 12 bit */ - .fourcc = V4L2_PIX_FMT_SRGGB12P, - .depth = 12, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB12P, - .size_multiplier_x2 = 2, -@@ -318,7 +319,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SBGGR12P, - .depth = 12, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR12P, - .size_multiplier_x2 = 2, -@@ -326,7 +327,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SGRBG12P, - .depth = 12, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG12P, - .size_multiplier_x2 = 2, -@@ -334,7 +335,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SGBRG12P, - .depth = 12, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG12P, - .size_multiplier_x2 = 2, -@@ -343,7 +344,7 @@ static const struct bcm2835_codec_fmt su - /* 14 bit */ - .fourcc = V4L2_PIX_FMT_SRGGB14P, - .depth = 14, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB14P, - .size_multiplier_x2 = 2, -@@ -351,7 +352,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SBGGR14P, - .depth = 14, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR14P, - .size_multiplier_x2 = 2, -@@ -360,7 +361,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SGRBG14P, - .depth = 14, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG14P, - .size_multiplier_x2 = 2, -@@ -368,7 +369,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SGBRG14P, - .depth = 14, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG14P, - .size_multiplier_x2 = 2, -@@ -377,7 +378,7 @@ static const struct bcm2835_codec_fmt su - /* 16 bit */ - .fourcc = V4L2_PIX_FMT_SRGGB16, - .depth = 16, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB16, - .size_multiplier_x2 = 2, -@@ -385,7 +386,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SBGGR16, - .depth = 16, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR16, - .size_multiplier_x2 = 2, -@@ -393,7 +394,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SGRBG16, - .depth = 16, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG16, - .size_multiplier_x2 = 2, -@@ -401,7 +402,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SGBRG16, - .depth = 16, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG16, - .size_multiplier_x2 = 2, -@@ -411,7 +412,7 @@ static const struct bcm2835_codec_fmt su - /* 10 bit */ - .fourcc = V4L2_PIX_FMT_SRGGB10, - .depth = 16, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB10, - .size_multiplier_x2 = 2, -@@ -419,7 +420,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SBGGR10, - .depth = 16, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR10, - .size_multiplier_x2 = 2, -@@ -427,7 +428,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SGRBG10, - .depth = 16, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG10, - .size_multiplier_x2 = 2, -@@ -435,7 +436,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SGBRG10, - .depth = 16, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG10, - .size_multiplier_x2 = 2, -@@ -444,7 +445,7 @@ static const struct bcm2835_codec_fmt su - /* 12 bit */ - .fourcc = V4L2_PIX_FMT_SRGGB12, - .depth = 16, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB12, - .size_multiplier_x2 = 2, -@@ -452,7 +453,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SBGGR12, - .depth = 16, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR12, - .size_multiplier_x2 = 2, -@@ -460,7 +461,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SGRBG12, - .depth = 16, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG12, - .size_multiplier_x2 = 2, -@@ -468,7 +469,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SGBRG12, - .depth = 16, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG12, - .size_multiplier_x2 = 2, -@@ -477,7 +478,7 @@ static const struct bcm2835_codec_fmt su - /* 14 bit */ - .fourcc = V4L2_PIX_FMT_SRGGB14, - .depth = 16, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB14, - .size_multiplier_x2 = 2, -@@ -485,7 +486,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SBGGR14, - .depth = 16, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR14, - .size_multiplier_x2 = 2, -@@ -493,7 +494,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SGRBG14, - .depth = 16, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG14, - .size_multiplier_x2 = 2, -@@ -501,7 +502,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SGBRG14, - .depth = 16, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG14, - .size_multiplier_x2 = 2, -@@ -511,7 +512,7 @@ static const struct bcm2835_codec_fmt su - /* 8 bit */ - .fourcc = V4L2_PIX_FMT_GREY, - .depth = 8, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_GREY, - .size_multiplier_x2 = 2, -@@ -519,7 +520,7 @@ static const struct bcm2835_codec_fmt su - /* 10 bit */ - .fourcc = V4L2_PIX_FMT_Y10P, - .depth = 10, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_Y10P, - .size_multiplier_x2 = 2, -@@ -527,7 +528,7 @@ static const struct bcm2835_codec_fmt su - /* 12 bit */ - .fourcc = V4L2_PIX_FMT_Y12P, - .depth = 12, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_Y12P, - .size_multiplier_x2 = 2, -@@ -535,7 +536,7 @@ static const struct bcm2835_codec_fmt su - /* 14 bit */ - .fourcc = V4L2_PIX_FMT_Y14P, - .depth = 14, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_Y14P, - .size_multiplier_x2 = 2, -@@ -543,7 +544,7 @@ static const struct bcm2835_codec_fmt su - /* 16 bit */ - .fourcc = V4L2_PIX_FMT_Y16, - .depth = 16, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_Y16, - .size_multiplier_x2 = 2, -@@ -551,7 +552,7 @@ static const struct bcm2835_codec_fmt su - /* 10 bit as 16bpp */ - .fourcc = V4L2_PIX_FMT_Y10, - .depth = 16, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_Y10, - .size_multiplier_x2 = 2, -@@ -559,7 +560,7 @@ static const struct bcm2835_codec_fmt su - /* 12 bit as 16bpp */ - .fourcc = V4L2_PIX_FMT_Y12, - .depth = 16, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_Y12, - .size_multiplier_x2 = 2, -@@ -567,7 +568,7 @@ static const struct bcm2835_codec_fmt su - /* 14 bit as 16bpp */ - .fourcc = V4L2_PIX_FMT_Y14, - .depth = 16, -- .bytesperline_align = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_Y14, - .size_multiplier_x2 = 2, -@@ -840,9 +841,10 @@ static inline unsigned int get_sizeimage - } - - static inline unsigned int get_bytesperline(int width, -- struct bcm2835_codec_fmt *fmt) -+ struct bcm2835_codec_fmt *fmt, -+ enum bcm2835_codec_role role) - { -- return ALIGN((width * fmt->depth) >> 3, fmt->bytesperline_align); -+ return ALIGN((width * fmt->depth) >> 3, fmt->bytesperline_align[role]); - } - - static void setup_mmal_port_format(struct bcm2835_codec_ctx *ctx, -@@ -1040,7 +1042,7 @@ static void handle_fmt_changed(struct bc - */ - q_data->selection_set = true; - q_data->bytesperline = get_bytesperline(format->es.video.width, -- q_data->fmt); -+ q_data->fmt, ctx->dev->role); - - q_data->height = format->es.video.height; - q_data->sizeimage = format->buffer_size_min; -@@ -1422,11 +1424,13 @@ static int vidioc_try_fmt(struct bcm2835 - f->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, 16); - } - f->fmt.pix_mp.num_planes = 1; -- min_bytesperline = get_bytesperline(f->fmt.pix_mp.width, fmt); -+ min_bytesperline = get_bytesperline(f->fmt.pix_mp.width, fmt, -+ ctx->dev->role); - if (f->fmt.pix_mp.plane_fmt[0].bytesperline < min_bytesperline) - f->fmt.pix_mp.plane_fmt[0].bytesperline = min_bytesperline; - f->fmt.pix_mp.plane_fmt[0].bytesperline = -- ALIGN(f->fmt.pix_mp.plane_fmt[0].bytesperline, fmt->bytesperline_align); -+ ALIGN(f->fmt.pix_mp.plane_fmt[0].bytesperline, -+ fmt->bytesperline_align[ctx->dev->role]); - - sizeimage = get_sizeimage(f->fmt.pix_mp.plane_fmt[0].bytesperline, - f->fmt.pix_mp.width, f->fmt.pix_mp.height, -@@ -1581,7 +1585,8 @@ static int vidioc_s_fmt(struct bcm2835_c - q_data_dst->height = ALIGN(q_data->crop_height, 16); - - q_data_dst->bytesperline = -- get_bytesperline(f->fmt.pix_mp.width, q_data_dst->fmt); -+ get_bytesperline(f->fmt.pix_mp.width, q_data_dst->fmt, -+ ctx->dev->role); - q_data_dst->sizeimage = get_sizeimage(q_data_dst->bytesperline, - q_data_dst->crop_width, - q_data_dst->height, -@@ -1810,6 +1815,8 @@ static int vidioc_g_selection(struct fil - } - } - break; -+ case NUM_ROLES: -+ break; - } - - return 0; -@@ -1920,6 +1927,8 @@ static int vidioc_s_selection(struct fil - } - break; - } -+ case NUM_ROLES: -+ break; - } - - return 0; -@@ -3087,7 +3096,8 @@ static int bcm2835_codec_open(struct fil - ctx->q_data[V4L2_M2M_SRC].height = DEFAULT_HEIGHT; - ctx->q_data[V4L2_M2M_SRC].bytesperline = - get_bytesperline(DEFAULT_WIDTH, -- ctx->q_data[V4L2_M2M_SRC].fmt); -+ ctx->q_data[V4L2_M2M_SRC].fmt, -+ dev->role); - ctx->q_data[V4L2_M2M_SRC].sizeimage = - get_sizeimage(ctx->q_data[V4L2_M2M_SRC].bytesperline, - ctx->q_data[V4L2_M2M_SRC].crop_width, -@@ -3100,7 +3110,8 @@ static int bcm2835_codec_open(struct fil - ctx->q_data[V4L2_M2M_DST].height = DEFAULT_HEIGHT; - ctx->q_data[V4L2_M2M_DST].bytesperline = - get_bytesperline(DEFAULT_WIDTH, -- ctx->q_data[V4L2_M2M_DST].fmt); -+ ctx->q_data[V4L2_M2M_DST].fmt, -+ dev->role); - ctx->q_data[V4L2_M2M_DST].sizeimage = - get_sizeimage(ctx->q_data[V4L2_M2M_DST].bytesperline, - ctx->q_data[V4L2_M2M_DST].crop_width, -@@ -3230,6 +3241,8 @@ static int bcm2835_codec_open(struct fil - v4l2_ctrl_handler_init(hdl, 0); - } - break; -+ case NUM_ROLES: -+ break; - } - - ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, &queue_init); diff --git a/target/linux/bcm27xx/patches-5.15/950-0588-regulator-rpi-panel-attiny-Use-two-transactions-for-.patch b/target/linux/bcm27xx/patches-5.15/950-0588-regulator-rpi-panel-attiny-Use-two-transactions-for-.patch deleted file mode 100644 index a40898bfd..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0588-regulator-rpi-panel-attiny-Use-two-transactions-for-.patch +++ /dev/null @@ -1,68 +0,0 @@ -From de0ad7df43a7399f9c09394b35d74bc75ebc60a4 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 25 Nov 2021 14:50:10 +0000 -Subject: [PATCH] regulator/rpi-panel-attiny: Use two transactions for - I2C read - -The I2C to the Atmel is very fussy, and locks up easily on -Pi0-3 particularly on reads. -If running at 100kHz on Pi3, reading the ID register generally -locks up the Atmel, but splitting the register select write and -read into two transactions is reliable. - -Signed-off-by: Dave Stevenson ---- - .../regulator/rpi-panel-attiny-regulator.c | 35 ++++++++++++++++++- - 1 file changed, 34 insertions(+), 1 deletion(-) - ---- a/drivers/regulator/rpi-panel-attiny-regulator.c -+++ b/drivers/regulator/rpi-panel-attiny-regulator.c -@@ -234,6 +234,39 @@ static void attiny_gpio_set(struct gpio_ - mutex_unlock(&state->lock); - } - -+static int attiny_i2c_read(struct i2c_client *client, u8 reg, unsigned int *buf) -+{ -+ struct i2c_msg msgs[1]; -+ u8 addr_buf[1] = { reg }; -+ u8 data_buf[1] = { 0, }; -+ int ret; -+ -+ /* Write register address */ -+ msgs[0].addr = client->addr; -+ msgs[0].flags = 0; -+ msgs[0].len = ARRAY_SIZE(addr_buf); -+ msgs[0].buf = addr_buf; -+ -+ ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); -+ if (ret != ARRAY_SIZE(msgs)) -+ return -EIO; -+ -+ usleep_range(5000, 10000); -+ -+ /* Read data from register */ -+ msgs[0].addr = client->addr; -+ msgs[0].flags = I2C_M_RD; -+ msgs[0].len = 1; -+ msgs[0].buf = data_buf; -+ -+ ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); -+ if (ret != ARRAY_SIZE(msgs)) -+ return -EIO; -+ -+ *buf = data_buf[0]; -+ return 0; -+} -+ - /* - * I2C driver interface functions - */ -@@ -264,7 +297,7 @@ static int attiny_i2c_probe(struct i2c_c - goto error; - } - -- ret = regmap_read(regmap, REG_ID, &data); -+ ret = attiny_i2c_read(i2c, REG_ID, &data); - if (ret < 0) { - dev_err(&i2c->dev, "Failed to read REG_ID reg: %d\n", ret); - goto error; diff --git a/target/linux/bcm27xx/patches-5.15/950-0590-drm-vc4-Move-HDMI-reset-to-pm_resume.patch b/target/linux/bcm27xx/patches-5.15/950-0590-drm-vc4-Move-HDMI-reset-to-pm_resume.patch deleted file mode 100644 index 6a8ef0ebd..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0590-drm-vc4-Move-HDMI-reset-to-pm_resume.patch +++ /dev/null @@ -1,125 +0,0 @@ -From 740955399f42caa6406761975656b8aa5b88a39c Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 25 Nov 2021 14:46:55 +0000 -Subject: [PATCH] drm/vc4: Move HDMI reset to pm_resume - -Pi0-3 have power domains attached to the pm_runtime hooks -for the HDMI block. Initialisation done in the reset called -from bind is therefore lost if all users of the domain are -suspended. -The VEC shares the same lowest level clock/power gating as -the HDMI block, so whilst that is enabled the block is never -actually powered down, but if it isn't enabled then we lose -the state. - -Reset and initialise the HDMI block from pm_resume. - -Signed-off-by: Dave Stevenson ---- - drivers/gpu/drm/vc4/vc4_hdmi.c | 61 ++++++++++++++++++----------- - drivers/gpu/drm/vc4/vc4_hdmi_regs.h | 4 +- - 2 files changed, 41 insertions(+), 24 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_hdmi.c -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c -@@ -2194,7 +2194,6 @@ static int vc4_hdmi_cec_init(struct vc4_ - struct platform_device *pdev = vc4_hdmi->pdev; - struct device *dev = &pdev->dev; - unsigned long flags; -- u32 value; - int ret; - - if (!of_find_property(dev->of_node, "interrupts", NULL)) { -@@ -2214,15 +2213,6 @@ static int vc4_hdmi_cec_init(struct vc4_ - cec_fill_conn_info_from_drm(&conn_info, &vc4_hdmi->connector); - cec_s_conn_info(vc4_hdmi->cec_adap, &conn_info); - -- spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); -- value = HDMI_READ(HDMI_CEC_CNTRL_1); -- /* Set the logical address to Unregistered */ -- value |= VC4_HDMI_CEC_ADDR_MASK; -- HDMI_WRITE(HDMI_CEC_CNTRL_1, value); -- spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); -- -- vc4_hdmi_cec_update_clk_div(vc4_hdmi); -- - if (vc4_hdmi->variant->external_irq_controller) { - ret = request_threaded_irq(platform_get_irq_byname(pdev, "cec-rx"), - vc4_cec_irq_handler_rx_bare, -@@ -2285,6 +2275,29 @@ static void vc4_hdmi_cec_exit(struct vc4 - - cec_unregister_adapter(vc4_hdmi->cec_adap); - } -+ -+static int vc4_hdmi_cec_resume(struct vc4_hdmi *vc4_hdmi) -+{ -+ unsigned long flags; -+ u32 value; -+ -+ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); -+ value = HDMI_READ(HDMI_CEC_CNTRL_1); -+ /* Set the logical address to Unregistered */ -+ value |= VC4_HDMI_CEC_ADDR_MASK; -+ HDMI_WRITE(HDMI_CEC_CNTRL_1, value); -+ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); -+ -+ vc4_hdmi_cec_update_clk_div(vc4_hdmi); -+ -+ if (!vc4_hdmi->variant->external_irq_controller) { -+ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); -+ HDMI_WRITE(HDMI_CEC_CPU_MASK_SET, 0xffffffff); -+ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); -+ } -+ -+ return 0; -+} - #else - static int vc4_hdmi_cec_init(struct vc4_hdmi *vc4_hdmi) - { -@@ -2293,6 +2306,10 @@ static int vc4_hdmi_cec_init(struct vc4_ - - static void vc4_hdmi_cec_exit(struct vc4_hdmi *vc4_hdmi) {}; - -+static void vc4_hdmi_cec_resume(struct vc4_hdmi *vc4_hdmi) -+{ -+ return 0; -+} - #endif - - static int vc4_hdmi_build_regset(struct vc4_hdmi *vc4_hdmi, -@@ -2527,6 +2544,15 @@ static int vc4_hdmi_runtime_resume(struc - if (ret) - return ret; - -+ if (vc4_hdmi->variant->reset) -+ vc4_hdmi->variant->reset(vc4_hdmi); -+ -+ ret = vc4_hdmi_cec_resume(vc4_hdmi); -+ if (ret) { -+ clk_disable_unprepare(vc4_hdmi->hsm_clock); -+ return ret; -+ } -+ - return 0; - } - ---- a/drivers/gpu/drm/vc4/vc4_hdmi_regs.h -+++ b/drivers/gpu/drm/vc4/vc4_hdmi_regs.h -@@ -417,7 +417,7 @@ static inline u32 vc4_hdmi_read(struct v - const struct vc4_hdmi_variant *variant = hdmi->variant; - void __iomem *base; - -- WARN_ON(!pm_runtime_active(&hdmi->pdev->dev)); -+ WARN_ON(pm_runtime_status_suspended(&hdmi->pdev->dev)); - - if (reg >= variant->num_registers) { - dev_warn(&hdmi->pdev->dev, -@@ -447,7 +447,7 @@ static inline void vc4_hdmi_write(struct - - lockdep_assert_held(&hdmi->hw_lock); - -- WARN_ON(!pm_runtime_active(&hdmi->pdev->dev)); -+ WARN_ON(pm_runtime_status_suspended(&hdmi->pdev->dev)); - - if (reg >= variant->num_registers) { - dev_warn(&hdmi->pdev->dev, diff --git a/target/linux/bcm27xx/patches-5.15/950-0592-dt-bcm283x-Change-BCM283x-HDMI-to-use-firmware-clock.patch b/target/linux/bcm27xx/patches-5.15/950-0592-dt-bcm283x-Change-BCM283x-HDMI-to-use-firmware-clock.patch deleted file mode 100644 index 90ee192da..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0592-dt-bcm283x-Change-BCM283x-HDMI-to-use-firmware-clock.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 264b925a428d109529dca836dfb5160dd67f7f08 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 2 Dec 2021 14:11:09 +0000 -Subject: [PATCH] dt: bcm283x: Change BCM283x HDMI to use firmware - clock driver - -The clk-bcm2835 handling of the pixel clock does not function -correctly when the HDMI power domain is disabled. - -The firmware supports it correctly, and the firmware clock -driver now supports it, so switch the vc4-hdmi driver to use -the firmware clock driver. - -Signed-off-by: Dave Stevenson ---- - arch/arm/boot/dts/bcm2835-common.dtsi | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/arch/arm/boot/dts/bcm2835-common.dtsi -+++ b/arch/arm/boot/dts/bcm2835-common.dtsi -@@ -128,7 +128,7 @@ - "hd"; - interrupts = <2 8>, <2 9>; - ddc = <&i2c2>; -- clocks = <&clocks BCM2835_PLLH_PIX>, -+ clocks = <&firmware_clocks 9>, - <&clocks BCM2835_CLOCK_HSM>; - clock-names = "pixel", "hdmi"; - dmas = <&dma (17|(1<<27)|(1<<24))>; diff --git a/target/linux/bcm27xx/patches-5.15/950-0593-overlays-vc4-kms-v3d-Change-composite-handling.patch b/target/linux/bcm27xx/patches-5.15/950-0593-overlays-vc4-kms-v3d-Change-composite-handling.patch deleted file mode 100644 index fdaf14105..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0593-overlays-vc4-kms-v3d-Change-composite-handling.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 382089f0bf8b49a6a560a778c54bfddc48cc0e5f Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 11 Nov 2021 13:33:25 +0000 -Subject: [PATCH] overlays: vc4-kms-v3d: Change composite handling - -On a Pi 4, enabling composite video disables the HDMI output. As a -consequence, the composite output is disabled by default. Change the -vc4-kms-v3d overlay used on older Pis to also disable composite by -default, replacing the "nocomposite" parameter with a "composite" -parameter. - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/overlays/README | 4 ++-- - arch/arm/boot/dts/overlays/upstream-overlay.dts | 2 +- - arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts | 4 ++-- - 3 files changed, 5 insertions(+), 5 deletions(-) - ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -3620,8 +3620,8 @@ Params: cma-512 CMA is 5 - cma-default Use upstream's default value - audio Enable or disable audio over HDMI (default "on") - noaudio Disable all HDMI audio (default "off") -- nocomposite Disable the composite video output (default -- "off") -+ composite Enable the composite output (default "off") -+ N.B. Disables all other outputs on a Pi 4. - - - Name: vc4-kms-v3d-pi4 ---- a/arch/arm/boot/dts/overlays/upstream-overlay.dts -+++ b/arch/arm/boot/dts/overlays/upstream-overlay.dts -@@ -1,4 +1,4 @@ --// redo: ovmerge -c vc4-kms-v3d-overlay.dts,cma-default dwc2-overlay.dts,dr_mode=otg -+// redo: ovmerge -c vc4-kms-v3d-overlay.dts,cma-default,composite dwc2-overlay.dts,dr_mode=otg - - /dts-v1/; - /plugin/; ---- a/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts -+++ b/arch/arm/boot/dts/overlays/vc4-kms-v3d-overlay.dts -@@ -89,7 +89,7 @@ - - fragment@11 { - target = <&vec>; -- __overlay__ { -+ __dormant__ { - status = "okay"; - }; - }; -@@ -118,6 +118,6 @@ - __overrides__ { - audio = <0>,"!13"; - noaudio = <0>,"=13"; -- nocomposite = <0>, "!11"; -+ composite = <0>, "=11"; - }; - }; diff --git a/target/linux/bcm27xx/patches-5.15/950-0597-drm-vc4-dpi-Ensure-a-default-format-is-selected.patch b/target/linux/bcm27xx/patches-5.15/950-0597-drm-vc4-dpi-Ensure-a-default-format-is-selected.patch deleted file mode 100644 index ab836cbcb..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0597-drm-vc4-dpi-Ensure-a-default-format-is-selected.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 368bba37e67b4589b9286b2f68e6487acd5c0f79 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 2 Dec 2021 18:28:29 +0000 -Subject: [PATCH] drm/vc4: dpi: Ensure a default format is selected - -In a couple of error/incomplete configuration cases, the -DPI_FORMAT bits wouldn't get set. - -Adopt a default of RGB666 in all these cases. - -Signed-off-by: Dave Stevenson ---- - drivers/gpu/drm/vc4/vc4_dpi.c | 13 +++++++++---- - 1 file changed, 9 insertions(+), 4 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_dpi.c -+++ b/drivers/gpu/drm/vc4/vc4_dpi.c -@@ -172,6 +172,10 @@ static void vc4_dpi_encoder_enable(struc - DPI_FORMAT); - dpi_c |= VC4_SET_FIELD(DPI_ORDER_BGR, DPI_ORDER); - break; -+ default: -+ DRM_ERROR("Unknown media bus format %d\n", -+ bus_format); -+ fallthrough; - case MEDIA_BUS_FMT_RGB666_1X18: - dpi_c |= VC4_SET_FIELD(DPI_FORMAT_18BIT_666_RGB_1, - DPI_FORMAT); -@@ -185,11 +189,12 @@ static void vc4_dpi_encoder_enable(struc - dpi_c |= VC4_SET_FIELD(DPI_FORMAT_16BIT_565_RGB_1, - DPI_FORMAT); - break; -- default: -- DRM_ERROR("Unknown media bus format %d\n", -- bus_format); -- break; - } -+ } else { -+ /* Default to 18bit if no connector found. */ -+ dpi_c |= VC4_SET_FIELD(DPI_FORMAT_18BIT_666_RGB_1, -+ DPI_FORMAT); -+ - } - - if (connector->display_info.bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE) diff --git a/target/linux/bcm27xx/patches-5.15/950-0598-dt-bcm270x-Add-GPIO-defines-for-RGB565-DPI-output-mo.patch b/target/linux/bcm27xx/patches-5.15/950-0598-dt-bcm270x-Add-GPIO-defines-for-RGB565-DPI-output-mo.patch deleted file mode 100644 index 1c70b95aa..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0598-dt-bcm270x-Add-GPIO-defines-for-RGB565-DPI-output-mo.patch +++ /dev/null @@ -1,44 +0,0 @@ -From c95312441f2c4e24bbb06da51006f3fe47cb61e5 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 2 Dec 2021 18:24:44 +0000 -Subject: [PATCH] dt: bcm270x: Add GPIO defines for RGB565 DPI output - modes - -Adds the pinctrl defines for the RGB565 DPI output modes. - -Signed-off-by: Dave Stevenson ---- - arch/arm/boot/dts/bcm270x.dtsi | 22 ++++++++++++++++++++++ - 1 file changed, 22 insertions(+) - ---- a/arch/arm/boot/dts/bcm270x.dtsi -+++ b/arch/arm/boot/dts/bcm270x.dtsi -@@ -189,6 +189,28 @@ - 20 21>; - brcm,function = ; - }; -+ dpi_16bit_gpio0: dpi_16bit_gpio0 { -+ brcm,pins = <0 1 2 3 4 5 6 7 8 9 10 11 -+ 12 13 14 15 16 17 18 19>; -+ brcm,function = ; -+ }; -+ dpi_16bit_gpio2: dpi_16bit_gpio2 { -+ brcm,pins = <2 3 4 5 6 7 8 9 10 11 -+ 12 13 14 15 16 17 18 19>; -+ brcm,function = ; -+ }; -+ dpi_16bit_cpadhi_gpio0: dpi_16bit_cpadhi_gpio0 { -+ brcm,pins = <0 1 2 3 4 5 6 7 8 -+ 12 13 14 15 16 17 -+ 20 21 22 23 24>; -+ brcm,function = ; -+ }; -+ dpi_16bit_cpadhi_gpio2: dpi_16bit_cpadhi_gpio2 { -+ brcm,pins = <2 3 4 5 6 7 8 -+ 12 13 14 15 16 17 -+ 20 21 22 23 24>; -+ brcm,function = ; -+ }; - }; - - &uart0 { diff --git a/target/linux/bcm27xx/patches-5.15/950-0599-dtoverlays-Add-a-generic-DPI-panel-overlay-for-KMS.patch b/target/linux/bcm27xx/patches-5.15/950-0599-dtoverlays-Add-a-generic-DPI-panel-overlay-for-KMS.patch deleted file mode 100644 index 0ab14d3e7..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0599-dtoverlays-Add-a-generic-DPI-panel-overlay-for-KMS.patch +++ /dev/null @@ -1,158 +0,0 @@ -From 208d270a7b613e5593390d38a9fba8bd248c5928 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 2 Dec 2021 18:06:37 +0000 -Subject: [PATCH] dtoverlays: Add a generic DPI panel overlay for KMS - -Uses the "panel-dpi" compatible to set panel timings from -DT. - -Signed-off-by: Dave Stevenson ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 28 ++++++ - .../overlays/vc4-kms-dpi-generic-overlay.dts | 92 +++++++++++++++++++ - 3 files changed, 121 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/vc4-kms-dpi-generic-overlay.dts - ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -232,6 +232,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ - vc4-fkms-v3d.dtbo \ - vc4-fkms-v3d-pi4.dtbo \ - vc4-kms-dpi-at056tn53v1.dtbo \ -+ vc4-kms-dpi-generic.dtbo \ - vc4-kms-dsi-7inch.dtbo \ - vc4-kms-dsi-lt070me05000.dtbo \ - vc4-kms-dsi-lt070me05000-v2.dtbo \ ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -3563,6 +3563,34 @@ Load: dtoverlay=vc4-kms-dpi-at056tn53v - Params: - - -+Name: vc4-kms-dpi-generic -+Info: Enable a generic DPI display under KMS. Default timings are for the -+ Adafruit Kippah with 800x480 panel and RGB666 (GPIOs 0-21) -+ Requires vc4-kms-v3d to be loaded. -+Load: dtoverlay=vc4-kms-dpi-generic,= -+Params: clock-frequency Display clock frequency (Hz) -+ hactive Horizontal active pixels -+ hfp Horizontal front porch -+ hsync Horizontal sync pulse width -+ hbp Horizontal back porch -+ vactive Vertical active lines -+ vfp Vertical front porch -+ vsync Vertical sync pulse width -+ vbp Vertical back porch -+ hsync-invert Horizontal sync active low -+ vsync-invert Vertical sync active low -+ de-invert Data Enable active low -+ pixclk-invert Negative edge pixel clock -+ width-mm Define the screen width in mm -+ height-mm Define the screen height in mm -+ rgb565 Change to RGB565 output on GPIOs 0-19 -+ rgb666-padhi Change to RGB666 output on GPIOs 0-9, 12-17, and -+ 20-25 -+ rgb888 Change to RGB888 output on GPIOs 0-27 -+ bus-format Override the bus format for a MEDIA_BUS_FMT_* -+ value. NB also overridden by rgbXXX overrides. -+ -+ - Name: vc4-kms-dsi-7inch - Info: Enable the Raspberry Pi DSI 7" screen. - Includes the edt-ft5406 for the touchscreen element. ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/vc4-kms-dpi-generic-overlay.dts -@@ -0,0 +1,92 @@ -+/* -+ * vc4-kms-dpi-at056tn53v1-overlay.dts -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+#include -+#include -+ -+/ { -+ compatible = "brcm,bcm2835"; -+ -+ fragment@0 { -+ target-path = "/"; -+ __overlay__ { -+ panel: panel { -+ compatible = "panel-dpi"; -+ -+ width-mm = <154>; -+ height-mm = <83>; -+ bus-format = <0x1009>; -+ -+ timing: panel-timing { -+ clock-frequency = <29500000>; -+ hactive = <800>; -+ hfront-porch = <24>; -+ hsync-len = <72>; -+ hback-porch = <96>; -+ hsync-active = <0>; -+ vactive = <480>; -+ vfront-porch = <3>; -+ vsync-len = <10>; -+ vback-porch = <7>; -+ vsync-active = <0>; -+ -+ de-active = <1>; -+ pixelclk-active = <1>; -+ }; -+ -+ port { -+ panel_in: endpoint { -+ remote-endpoint = <&dpi_out>; -+ }; -+ }; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&dpi>; -+ dpi_node: __overlay__ { -+ status = "okay"; -+ -+ pinctrl-names = "default"; -+ pinctrl-0 = <&dpi_18bit_gpio0>; -+ -+ port { -+ dpi_out: endpoint { -+ remote-endpoint = <&panel_in>; -+ }; -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ clock-frequency = <&timing>, "clock-frequency:0"; -+ hactive = <&timing>, "hactive:0"; -+ hfp = <&timing>, "hfront-porch:0"; -+ hsync = <&timing>, "hsync-len:0"; -+ hbp = <&timing>, "hback-porch:0"; -+ vactive = <&timing>, "vactive:0"; -+ vfp = <&timing>, "vfront-porch:0"; -+ vsync = <&timing>, "vsync-len:0"; -+ vbp = <&timing>, "vback-porch:0"; -+ hsync-invert = <&timing>, "hsync-active:0=0"; -+ vsync-invert = <&timing>, "vsync-active:0=0"; -+ de-invert = <&timing>, "de-active:0=0"; -+ pixclk-invert = <&timing>, "pixelclk-active:0=0"; -+ -+ width-mm = <&panel>, "width-mm:0"; -+ height-mm = <&panel>, "height-mm:0"; -+ -+ rgb565 = <&panel>, "bus-format:0=0x1017", -+ <&dpi_node>, "pinctrl-0:0=",<&dpi_16bit_gpio0>; -+ rgb666-padhi = <&panel>, "bus-format:0=0x1015", -+ <&dpi_node>, "pinctrl-0:0=",<&dpi_18bit_cpadhi_gpio0>; -+ rgb888 = <&panel>, "bus-format:0=0x100a", -+ <&dpi_node>, "pinctrl-0:0=",<&dpi_gpio0>; -+ bus-format = <&panel>, "bus-format:0"; -+ }; -+}; diff --git a/target/linux/bcm27xx/patches-5.15/950-0603-vc4-drm-Ignore-vc4_hdmi-output_enabled-for-allowing-.patch b/target/linux/bcm27xx/patches-5.15/950-0603-vc4-drm-Ignore-vc4_hdmi-output_enabled-for-allowing-.patch deleted file mode 100644 index cb0daf15f..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0603-vc4-drm-Ignore-vc4_hdmi-output_enabled-for-allowing-.patch +++ /dev/null @@ -1,98 +0,0 @@ -From 68522ed7c1135fd5ea5b4541d557bdbdcba80669 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Wed, 8 Dec 2021 15:57:15 +0000 -Subject: [PATCH] vc4/drm: Ignore vc4_hdmi->output_enabled for allowing - audio (#4759) - -Otherwise we reject audio playback when switching hdmi modes - -Signed-off-by: Dom Cobley ---- - drivers/gpu/drm/vc4/vc4_hdmi.c | 29 ++--------------------------- - drivers/gpu/drm/vc4/vc4_hdmi.h | 6 ------ - 2 files changed, 2 insertions(+), 33 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_hdmi.c -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c -@@ -211,6 +211,7 @@ vc4_hdmi_connector_detect(struct drm_con - connected = true; - } - -+ vc4_hdmi->encoder.hdmi_monitor = false; - if (connected) { - if (connector->status != connector_status_connected) { - struct edid *edid = drm_get_edid(connector, vc4_hdmi->ddc); -@@ -731,15 +732,6 @@ static void vc4_hdmi_encoder_post_crtc_p - mutex_unlock(&vc4_hdmi->mutex); - } - --static void vc4_hdmi_encoder_disable(struct drm_encoder *encoder) --{ -- struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); -- -- mutex_lock(&vc4_hdmi->mutex); -- vc4_hdmi->output_enabled = false; -- mutex_unlock(&vc4_hdmi->mutex); --} -- - static void vc4_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, bool enable) - { - unsigned long flags; -@@ -1220,15 +1212,6 @@ static void vc4_hdmi_encoder_post_crtc_e - mutex_unlock(&vc4_hdmi->mutex); - } - --static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder) --{ -- struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); -- -- mutex_lock(&vc4_hdmi->mutex); -- vc4_hdmi->output_enabled = true; -- mutex_unlock(&vc4_hdmi->mutex); --} -- - static void vc4_hdmi_encoder_atomic_mode_set(struct drm_encoder *encoder, - struct drm_crtc_state *crtc_state, - struct drm_connector_state *conn_state) -@@ -1322,8 +1305,6 @@ static const struct drm_encoder_helper_f - .atomic_check = vc4_hdmi_encoder_atomic_check, - .atomic_mode_set = vc4_hdmi_encoder_atomic_mode_set, - .mode_valid = vc4_hdmi_encoder_mode_valid, -- .disable = vc4_hdmi_encoder_disable, -- .enable = vc4_hdmi_encoder_enable, - }; - - static u32 vc4_hdmi_channel_map(struct vc4_hdmi *vc4_hdmi, u32 channel_mask) -@@ -1423,16 +1404,10 @@ static bool vc4_hdmi_audio_can_stream(st - lockdep_assert_held(&vc4_hdmi->mutex); - - /* -- * If the controller is disabled, prevent any ALSA output. -- */ -- if (!vc4_hdmi->output_enabled) -- return false; -- -- /* - * If the encoder is currently in DVI mode, treat the codec DAI - * as missing. - */ -- if (!(HDMI_READ(HDMI_RAM_PACKET_CONFIG) & VC4_HDMI_RAM_PACKET_ENABLE)) -+ if (!vc4_hdmi->encoder.hdmi_monitor) - return false; - - return true; ---- a/drivers/gpu/drm/vc4/vc4_hdmi.h -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.h -@@ -209,12 +209,6 @@ struct vc4_hdmi { - struct drm_display_mode saved_adjusted_mode; - - /** -- * @output_enabled: Is the HDMI controller currently active? -- * Protected by @mutex. -- */ -- bool output_enabled; -- -- /** - * @scdc_enabled: Is the HDMI controller currently running with - * the scrambler on? Protected by @mutex. - */ diff --git a/target/linux/bcm27xx/patches-5.15/950-0604-ARM-dts-Create-bcm2711-rpi-cm4s.dts-4761.patch b/target/linux/bcm27xx/patches-5.15/950-0604-ARM-dts-Create-bcm2711-rpi-cm4s.dts-4761.patch deleted file mode 100644 index c1dd848e4..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0604-ARM-dts-Create-bcm2711-rpi-cm4s.dts-4761.patch +++ /dev/null @@ -1,425 +0,0 @@ -From dc1156479b5bf177ecb403e11fe990af5db54394 Mon Sep 17 00:00:00 2001 -From: peterharperuk <77111776+peterharperuk@users.noreply.github.com> -Date: Mon, 13 Dec 2021 14:00:35 +0000 -Subject: [PATCH] ARM: dts: Create bcm2711-rpi-cm4s.dts (#4761) - -Signed-off-by: Peter Harper ---- - arch/arm/boot/dts/Makefile | 3 +- - arch/arm/boot/dts/bcm2711-rpi-cm4s.dts | 398 +++++++++++++++++++++++++ - 2 files changed, 400 insertions(+), 1 deletion(-) - create mode 100644 arch/arm/boot/dts/bcm2711-rpi-cm4s.dts - ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -16,7 +16,8 @@ dtb-$(CONFIG_ARCH_BCM2835) += \ - bcm2711-rpi-4-b.dtb \ - bcm2711-rpi-400.dtb \ - bcm2710-rpi-cm3.dtb \ -- bcm2711-rpi-cm4.dtb -+ bcm2711-rpi-cm4.dtb \ -+ bcm2711-rpi-cm4s.dtb - - dtb-$(CONFIG_ARCH_ALPINE) += \ - alpine-db.dtb ---- /dev/null -+++ b/arch/arm/boot/dts/bcm2711-rpi-cm4s.dts -@@ -0,0 +1,398 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/dts-v1/; -+#include "bcm2711.dtsi" -+#include "bcm2711-rpi.dtsi" -+ -+/ { -+ compatible = "raspberrypi,4-compute-module-s", "brcm,bcm2711"; -+ model = "Raspberry Pi Compute Module 4S"; -+ -+ chosen { -+ /* 8250 auxiliary UART instead of pl011 */ -+ stdout-path = "serial1:115200n8"; -+ }; -+ -+ leds { -+ led-act { -+ gpios = <&virtgpio 0 0>; -+ }; -+ }; -+}; -+ -+&ddc0 { -+ status = "okay"; -+}; -+ -+&gpio { -+ /* -+ * Parts taken from rpi_SCH_4b_4p0_reduced.pdf and -+ * the official GPU firmware DT blob. -+ * -+ * Legend: -+ * "FOO" = GPIO line named "FOO" on the schematic -+ * "FOO_N" = GPIO line named "FOO" on schematic, active low -+ */ -+ gpio-line-names = "ID_SDA", -+ "ID_SCL", -+ "SDA1", -+ "SCL1", -+ "GPIO_GCLK", -+ "GPIO5", -+ "GPIO6", -+ "SPI_CE1_N", -+ "SPI_CE0_N", -+ "SPI_MISO", -+ "SPI_MOSI", -+ "SPI_SCLK", -+ "GPIO12", -+ "GPIO13", -+ /* Serial port */ -+ "TXD1", -+ "RXD1", -+ "GPIO16", -+ "GPIO17", -+ "GPIO18", -+ "GPIO19", -+ "GPIO20", -+ "GPIO21", -+ "GPIO22", -+ "GPIO23", -+ "GPIO24", -+ "GPIO25", -+ "GPIO26", -+ "GPIO27", -+ "GPIO28", -+ "GPIO29", -+ "GPIO30", -+ "GPIO31", -+ "GPIO32", -+ "GPIO33", -+ "GPIO34", -+ "GPIO35", -+ "GPIO36", -+ "GPIO37", -+ "GPIO38", -+ "GPIO39", -+ "PWM0_MISO", -+ "PWM1_MOSI", -+ "GPIO42", -+ "GPIO43", -+ "GPIO44", -+ "GPIO45"; -+}; -+ -+&hdmi0 { -+ status = "okay"; -+}; -+ -+&pixelvalve0 { -+ status = "okay"; -+}; -+ -+&pixelvalve1 { -+ status = "okay"; -+}; -+ -+&pixelvalve2 { -+ status = "okay"; -+}; -+ -+&pixelvalve4 { -+ status = "okay"; -+}; -+ -+&pwm1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pwm1_0_gpio40 &pwm1_1_gpio41>; -+ status = "okay"; -+}; -+ -+/* EMMC2 is used to drive the EMMC card */ -+&emmc2 { -+ bus-width = <8>; -+ broken-cd; -+ status = "okay"; -+}; -+ -+&pcie0 { -+ status = "disabled"; -+}; -+ -+&vchiq { -+ interrupts = ; -+}; -+ -+&vc4 { -+ status = "okay"; -+}; -+ -+&vec { -+ status = "disabled"; -+}; -+ -+// ============================================= -+// Downstream rpi- changes -+ -+#define BCM2711 -+ -+#include "bcm270x.dtsi" -+#include "bcm2711-rpi-ds.dtsi" -+ -+/ { -+ soc { -+ /delete-node/ pixelvalve@7e807000; -+ /delete-node/ hdmi@7e902000; -+ -+ virtgpio: virtgpio { -+ compatible = "brcm,bcm2835-virtgpio"; -+ gpio-controller; -+ #gpio-cells = <2>; -+ firmware = <&firmware>; -+ status = "okay"; -+ }; -+ }; -+}; -+ -+#include "bcm283x-rpi-csi0-2lane.dtsi" -+#include "bcm283x-rpi-csi1-4lane.dtsi" -+#include "bcm283x-rpi-i2c0mux_0_44.dtsi" -+#include "bcm283x-rpi-cam1-regulator.dtsi" -+ -+/ { -+ chosen { -+ bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1"; -+ }; -+ -+ aliases { -+ serial0 = &uart0; -+ mmc0 = &emmc2; -+ mmc1 = &mmcnr; -+ mmc2 = &sdhost; -+ i2c3 = &i2c3; -+ i2c4 = &i2c4; -+ i2c5 = &i2c5; -+ i2c6 = &i2c6; -+ spi3 = &spi3; -+ spi4 = &spi4; -+ spi5 = &spi5; -+ spi6 = &spi6; -+ /delete-property/ intc; -+ }; -+ -+ /delete-node/ wifi-pwrseq; -+}; -+ -+&uart0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart0_pins>; -+ status = "okay"; -+}; -+ -+&spi0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi0_pins &spi0_cs_pins>; -+ cs-gpios = <&gpio 8 1>, <&gpio 7 1>; -+ -+ spidev0: spidev@0{ -+ compatible = "spidev"; -+ reg = <0>; /* CE0 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <125000000>; -+ }; -+ -+ spidev1: spidev@1{ -+ compatible = "spidev"; -+ reg = <1>; /* CE1 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <125000000>; -+ }; -+}; -+ -+&gpio { -+ spi0_pins: spi0_pins { -+ brcm,pins = <9 10 11>; -+ brcm,function = ; -+ }; -+ -+ spi0_cs_pins: spi0_cs_pins { -+ brcm,pins = <8 7>; -+ brcm,function = ; -+ }; -+ -+ spi3_pins: spi3_pins { -+ brcm,pins = <1 2 3>; -+ brcm,function = ; -+ }; -+ -+ spi3_cs_pins: spi3_cs_pins { -+ brcm,pins = <0 24>; -+ brcm,function = ; -+ }; -+ -+ spi4_pins: spi4_pins { -+ brcm,pins = <5 6 7>; -+ brcm,function = ; -+ }; -+ -+ spi4_cs_pins: spi4_cs_pins { -+ brcm,pins = <4 25>; -+ brcm,function = ; -+ }; -+ -+ spi5_pins: spi5_pins { -+ brcm,pins = <13 14 15>; -+ brcm,function = ; -+ }; -+ -+ spi5_cs_pins: spi5_cs_pins { -+ brcm,pins = <12 26>; -+ brcm,function = ; -+ }; -+ -+ spi6_pins: spi6_pins { -+ brcm,pins = <19 20 21>; -+ brcm,function = ; -+ }; -+ -+ spi6_cs_pins: spi6_cs_pins { -+ brcm,pins = <18 27>; -+ brcm,function = ; -+ }; -+ -+ i2c0_pins: i2c0 { -+ brcm,pins = <0 1>; -+ brcm,function = ; -+ brcm,pull = ; -+ }; -+ -+ i2c1_pins: i2c1 { -+ brcm,pins = <2 3>; -+ brcm,function = ; -+ brcm,pull = ; -+ }; -+ -+ i2c3_pins: i2c3 { -+ brcm,pins = <4 5>; -+ brcm,function = ; -+ brcm,pull = ; -+ }; -+ -+ i2c4_pins: i2c4 { -+ brcm,pins = <8 9>; -+ brcm,function = ; -+ brcm,pull = ; -+ }; -+ -+ i2c5_pins: i2c5 { -+ brcm,pins = <12 13>; -+ brcm,function = ; -+ brcm,pull = ; -+ }; -+ -+ i2c6_pins: i2c6 { -+ brcm,pins = <22 23>; -+ brcm,function = ; -+ brcm,pull = ; -+ }; -+ -+ i2s_pins: i2s { -+ brcm,pins = <18 19 20 21>; -+ brcm,function = ; -+ }; -+ -+ sdio_pins: sdio_pins { -+ brcm,pins = <34 35 36 37 38 39>; -+ brcm,function = ; // alt3 = SD1 -+ brcm,pull = <0 2 2 2 2 2>; -+ }; -+ -+ uart0_pins: uart0_pins { -+ brcm,pins; -+ brcm,function; -+ brcm,pull; -+ }; -+ -+ uart2_pins: uart2_pins { -+ brcm,pins = <0 1>; -+ brcm,function = ; -+ brcm,pull = <0 2>; -+ }; -+ -+ uart3_pins: uart3_pins { -+ brcm,pins = <4 5>; -+ brcm,function = ; -+ brcm,pull = <0 2>; -+ }; -+ -+ uart4_pins: uart4_pins { -+ brcm,pins = <8 9>; -+ brcm,function = ; -+ brcm,pull = <0 2>; -+ }; -+ -+ uart5_pins: uart5_pins { -+ brcm,pins = <12 13>; -+ brcm,function = ; -+ brcm,pull = <0 2>; -+ }; -+}; -+ -+&i2c0if { -+ clock-frequency = <100000>; -+}; -+ -+&i2c1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c1_pins>; -+ clock-frequency = <100000>; -+}; -+ -+&i2s { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2s_pins>; -+}; -+ -+// ============================================= -+// Board specific stuff here -+ -+&sdhost { -+ status = "disabled"; -+}; -+ -+&gpio { -+ audio_pins: audio_pins { -+ brcm,pins = <>; -+ brcm,function = <>; -+ }; -+}; -+ -+&leds { -+ act_led: led-act { -+ label = "led0"; -+ linux,default-trigger = "mmc0"; -+ }; -+}; -+ -+&pwm1 { -+ status = "disabled"; -+}; -+ -+&audio { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&audio_pins>; -+ brcm,disable-headphones = <1>; -+}; -+ -+/ { -+ __overrides__ { -+ act_led_gpio = <&act_led>,"gpios:4"; -+ act_led_activelow = <&act_led>,"gpios:8"; -+ act_led_trigger = <&act_led>,"linux,default-trigger"; -+ -+ sd_poll_once = <&emmc2>, "non-removable?"; -+ spi_dma4 = <&spi0>, "dmas:0=", <&dma40>, -+ <&spi0>, "dmas:8=", <&dma40>; -+ }; -+}; diff --git a/target/linux/bcm27xx/patches-5.15/950-0607-drm-vc4-Fix-build-without-DRM_VC4_HDMI_CEC.patch b/target/linux/bcm27xx/patches-5.15/950-0607-drm-vc4-Fix-build-without-DRM_VC4_HDMI_CEC.patch deleted file mode 100644 index 777cdda54..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0607-drm-vc4-Fix-build-without-DRM_VC4_HDMI_CEC.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 977d51f1d3f7058a4bcde2b3f6497880ccd5db6c Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 14 Dec 2021 21:53:18 +0000 -Subject: [PATCH] drm/vc4: Fix build without DRM_VC4_HDMI_CEC - -As reported by @asavah. - -Fixes: https://github.com/raspberrypi/linux/issues/4771 - -Signed-off-by: Phil Elwell ---- - drivers/gpu/drm/vc4/vc4_hdmi.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/gpu/drm/vc4/vc4_hdmi.c -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c -@@ -2281,7 +2281,7 @@ static int vc4_hdmi_cec_init(struct vc4_ - - static void vc4_hdmi_cec_exit(struct vc4_hdmi *vc4_hdmi) {}; - --static void vc4_hdmi_cec_resume(struct vc4_hdmi *vc4_hdmi) -+static int vc4_hdmi_cec_resume(struct vc4_hdmi *vc4_hdmi) - { - return 0; - } diff --git a/target/linux/bcm27xx/patches-5.15/950-0608-dt-Create-static-regulators-and-clocks-for-camera-no.patch b/target/linux/bcm27xx/patches-5.15/950-0608-dt-Create-static-regulators-and-clocks-for-camera-no.patch deleted file mode 100644 index fa83feda9..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0608-dt-Create-static-regulators-and-clocks-for-camera-no.patch +++ /dev/null @@ -1,383 +0,0 @@ -From 322899a48088cb09b3f2a068f78c93a63615da9e Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Sat, 20 Nov 2021 10:48:36 +0000 -Subject: [PATCH] dt: Create static regulators and clocks for camera - nodes - -Unloading regulators through dynamic device tree doesn't work -as the regulators will unregister whilst clients are still -registered. Whilst the regulator framework does WARN when that -happens, the client putting the regulator then typically results -in a NULL dereference and badness. - -Instead of creating regulators and clocks from the overlays, -create regulators and clocks for the sensors in the base DT. - -Signed-off-by: Dave Stevenson ---- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 4 ++- - arch/arm/boot/dts/bcm2708-rpi-b-rev1.dts | 4 ++- - arch/arm/boot/dts/bcm2708-rpi-b.dts | 4 ++- - arch/arm/boot/dts/bcm2708-rpi-cm.dts | 21 ++++-------- - arch/arm/boot/dts/bcm2708-rpi-zero-w.dts | 4 ++- - arch/arm/boot/dts/bcm2708-rpi-zero.dts | 4 ++- - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 4 ++- - arch/arm/boot/dts/bcm270x.dtsi | 33 +++++++++++++++++++ - arch/arm/boot/dts/bcm2710-rpi-2-b.dts | 4 ++- - arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts | 4 ++- - arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 4 ++- - arch/arm/boot/dts/bcm2710-rpi-cm3.dts | 21 ++++-------- - arch/arm/boot/dts/bcm2710-rpi-zero-2-w.dts | 4 ++- - arch/arm/boot/dts/bcm2711-rpi-4-b.dts | 4 ++- - arch/arm/boot/dts/bcm2711-rpi-cm4.dts | 1 - - .../boot/dts/bcm283x-rpi-cam1-regulator.dtsi | 10 ------ - 16 files changed, 80 insertions(+), 50 deletions(-) - delete mode 100644 arch/arm/boot/dts/bcm283x-rpi-cam1-regulator.dtsi - ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -5,7 +5,6 @@ - #include "bcm283x-rpi-smsc9514.dtsi" - #include "bcm283x-rpi-csi1-2lane.dtsi" - #include "bcm283x-rpi-i2c0mux_0_28.dtsi" --#include "bcm283x-rpi-cam1-regulator.dtsi" - - / { - compatible = "raspberrypi,model-b-plus", "brcm,bcm2835"; -@@ -116,6 +115,9 @@ - gpio = <&gpio 41 GPIO_ACTIVE_HIGH>; - }; - -+cam0_reg: &cam_dummy_reg { -+}; -+ - / { - __overrides__ { - act_led_gpio = <&act_led>,"gpios:4"; ---- a/arch/arm/boot/dts/bcm2708-rpi-b-rev1.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-rev1.dts -@@ -4,7 +4,6 @@ - #include "bcm2708-rpi.dtsi" - #include "bcm283x-rpi-smsc9512.dtsi" - #include "bcm283x-rpi-csi1-2lane.dtsi" --#include "bcm283x-rpi-cam1-regulator.dtsi" - - / { - compatible = "raspberrypi,model-b", "brcm,bcm2835"; -@@ -123,6 +122,9 @@ i2c_csi_dsi: &i2c1 { - gpio = <&gpio 27 GPIO_ACTIVE_HIGH>; - }; - -+cam0_reg: &cam_dummy_reg { -+}; -+ - / { - __overrides__ { - act_led_gpio = <&act_led>,"gpios:4"; ---- a/arch/arm/boot/dts/bcm2708-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -5,7 +5,6 @@ - #include "bcm283x-rpi-smsc9512.dtsi" - #include "bcm283x-rpi-csi1-2lane.dtsi" - #include "bcm283x-rpi-i2c0mux_0_28.dtsi" --#include "bcm283x-rpi-cam1-regulator.dtsi" - - / { - compatible = "raspberrypi,model-b", "brcm,bcm2835"; -@@ -110,6 +109,9 @@ - gpio = <&gpio 21 GPIO_ACTIVE_HIGH>; - }; - -+cam0_reg: &cam_dummy_reg { -+}; -+ - / { - __overrides__ { - act_led_gpio = <&act_led>,"gpios:4"; ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -@@ -8,21 +8,14 @@ - / { - compatible = "raspberrypi,compute-module", "brcm,bcm2835"; - model = "Raspberry Pi Compute Module"; -+}; -+ -+&cam1_reg { -+ gpio = <&gpio 2 GPIO_ACTIVE_HIGH>; -+}; - -- cam1_reg: cam1_reg { -- compatible = "regulator-fixed"; -- regulator-name = "cam1-regulator"; -- gpio = <&gpio 2 GPIO_ACTIVE_HIGH>; -- enable-active-high; -- status = "disabled"; -- }; -- cam0_reg: cam0_reg { -- compatible = "regulator-fixed"; -- regulator-name = "cam0-regulator"; -- gpio = <&gpio 30 GPIO_ACTIVE_HIGH>; -- enable-active-high; -- status = "disabled"; -- }; -+cam0_reg: &cam0_regulator { -+ gpio = <&gpio 30 GPIO_ACTIVE_HIGH>; - }; - - &uart0 { ---- a/arch/arm/boot/dts/bcm2708-rpi-zero-w.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-zero-w.dts -@@ -5,7 +5,6 @@ - #include "bcm283x-rpi-csi1-2lane.dtsi" - #include "bcm283x-rpi-i2c0mux_0_28.dtsi" - #include "bcm2708-rpi-bt.dtsi" --#include "bcm283x-rpi-cam1-regulator.dtsi" - - / { - compatible = "raspberrypi,model-zero-w", "brcm,bcm2835"; -@@ -167,6 +166,9 @@ - gpio = <&gpio 44 GPIO_ACTIVE_HIGH>; - }; - -+cam0_reg: &cam_dummy_reg { -+}; -+ - / { - __overrides__ { - act_led_gpio = <&act_led>,"gpios:4"; ---- a/arch/arm/boot/dts/bcm2708-rpi-zero.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-zero.dts -@@ -4,7 +4,6 @@ - #include "bcm2708-rpi.dtsi" - #include "bcm283x-rpi-csi1-2lane.dtsi" - #include "bcm283x-rpi-i2c0mux_0_28.dtsi" --#include "bcm283x-rpi-cam1-regulator.dtsi" - - / { - compatible = "raspberrypi,model-zero", "brcm,bcm2835"; -@@ -114,6 +113,9 @@ - gpio = <&gpio 41 GPIO_ACTIVE_HIGH>; - }; - -+cam0_reg: &cam_dummy_reg { -+}; -+ - / { - __overrides__ { - act_led_gpio = <&act_led>,"gpios:4"; ---- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -+++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -5,7 +5,6 @@ - #include "bcm283x-rpi-smsc9514.dtsi" - #include "bcm283x-rpi-csi1-2lane.dtsi" - #include "bcm283x-rpi-i2c0mux_0_28.dtsi" --#include "bcm283x-rpi-cam1-regulator.dtsi" - - / { - compatible = "raspberrypi,2-model-b", "brcm,bcm2836"; -@@ -116,6 +115,9 @@ - gpio = <&gpio 41 GPIO_ACTIVE_HIGH>; - }; - -+cam0_reg: &cam_dummy_reg { -+}; -+ - / { - __overrides__ { - act_led_gpio = <&act_led>,"gpios:4"; ---- a/arch/arm/boot/dts/bcm270x.dtsi -+++ b/arch/arm/boot/dts/bcm270x.dtsi -@@ -153,6 +153,39 @@ - }; - }; - -+ cam1_reg: cam1_regulator { -+ compatible = "regulator-fixed"; -+ regulator-name = "cam1-reg"; -+ enable-active-high; -+ /* Needs to be enabled, as removing a regulator is very unsafe */ -+ status = "okay"; -+ }; -+ -+ cam1_clk: cam1_clk { -+ compatible = "fixed-clock"; -+ #clock-cells = <0>; -+ status = "disabled"; -+ }; -+ -+ cam0_regulator: cam0_regulator { -+ compatible = "regulator-fixed"; -+ regulator-name = "cam0-reg"; -+ enable-active-high; -+ status = "disabled"; -+ }; -+ -+ cam0_clk: cam0_clk { -+ compatible = "fixed-clock"; -+ #clock-cells = <0>; -+ status = "disabled"; -+ }; -+ -+ cam_dummy_reg: cam_dummy_reg { -+ compatible = "regulator-fixed"; -+ regulator-name = "cam-dummy-reg"; -+ status = "okay"; -+ }; -+ - __overrides__ { - cam0-pwdn-ctrl; - cam0-pwdn; ---- a/arch/arm/boot/dts/bcm2710-rpi-2-b.dts -+++ b/arch/arm/boot/dts/bcm2710-rpi-2-b.dts -@@ -5,7 +5,6 @@ - #include "bcm283x-rpi-smsc9514.dtsi" - #include "bcm283x-rpi-csi1-2lane.dtsi" - #include "bcm283x-rpi-i2c0mux_0_28.dtsi" --#include "bcm283x-rpi-cam1-regulator.dtsi" - - / { - compatible = "raspberrypi,2-model-b-rev2", "brcm,bcm2837"; -@@ -116,6 +115,9 @@ - gpio = <&gpio 41 GPIO_ACTIVE_HIGH>; - }; - -+cam0_reg: &cam_dummy_reg { -+}; -+ - / { - __overrides__ { - act_led_gpio = <&act_led>,"gpios:4"; ---- a/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts -@@ -6,7 +6,6 @@ - #include "bcm283x-rpi-csi1-2lane.dtsi" - #include "bcm283x-rpi-i2c0mux_0_44.dtsi" - #include "bcm271x-rpi-bt.dtsi" --#include "bcm283x-rpi-cam1-regulator.dtsi" - - / { - compatible = "raspberrypi,3-model-b-plus", "brcm,bcm2837"; -@@ -188,6 +187,9 @@ - gpio = <&expgpio 5 GPIO_ACTIVE_HIGH>; - }; - -+cam0_reg: &cam_dummy_reg { -+}; -+ - / { - __overrides__ { - act_led_gpio = <&act_led>,"gpios:4"; ---- a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -+++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -@@ -6,7 +6,6 @@ - #include "bcm283x-rpi-csi1-2lane.dtsi" - #include "bcm283x-rpi-i2c0mux_0_44.dtsi" - #include "bcm271x-rpi-bt.dtsi" --#include "bcm283x-rpi-cam1-regulator.dtsi" - - / { - compatible = "raspberrypi,3-model-b", "brcm,bcm2837"; -@@ -197,6 +196,9 @@ - gpio = <&expgpio 5 GPIO_ACTIVE_HIGH>; - }; - -+cam0_reg: &cam_dummy_reg { -+}; -+ - / { - __overrides__ { - act_led_gpio = <&act_led>,"gpios:4"; ---- a/arch/arm/boot/dts/bcm2710-rpi-cm3.dts -+++ b/arch/arm/boot/dts/bcm2710-rpi-cm3.dts -@@ -8,21 +8,14 @@ - / { - compatible = "raspberrypi,3-compute-module", "brcm,bcm2837"; - model = "Raspberry Pi Compute Module 3"; -+}; -+ -+&cam1_reg { -+ gpio = <&gpio 2 GPIO_ACTIVE_HIGH>; -+}; - -- cam1_reg: cam1_reg { -- compatible = "regulator-fixed"; -- regulator-name = "cam1-regulator"; -- gpio = <&gpio 2 GPIO_ACTIVE_HIGH>; -- enable-active-high; -- status = "disabled"; -- }; -- cam0_reg: cam0_reg { -- compatible = "regulator-fixed"; -- regulator-name = "cam0-regulator"; -- gpio = <&gpio 30 GPIO_ACTIVE_HIGH>; -- enable-active-high; -- status = "disabled"; -- }; -+cam0_reg: &cam0_regulator { -+ gpio = <&gpio 30 GPIO_ACTIVE_HIGH>; - }; - - &uart0 { ---- a/arch/arm/boot/dts/bcm2710-rpi-zero-2-w.dts -+++ b/arch/arm/boot/dts/bcm2710-rpi-zero-2-w.dts -@@ -5,7 +5,6 @@ - #include "bcm283x-rpi-csi1-2lane.dtsi" - #include "bcm283x-rpi-i2c0mux_0_44.dtsi" - #include "bcm2708-rpi-bt.dtsi" --#include "bcm283x-rpi-cam1-regulator.dtsi" - - / { - compatible = "raspberrypi,model-zero-2-w", "brcm,bcm2837"; -@@ -188,6 +187,9 @@ - gpio = <&gpio 40 GPIO_ACTIVE_HIGH>; - }; - -+cam0_reg: &cam_dummy_reg { -+}; -+ - / { - __overrides__ { - act_led_gpio = <&act_led>,"gpios:4"; ---- a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts -+++ b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts -@@ -279,7 +279,6 @@ - #include "bcm2711-rpi-ds.dtsi" - #include "bcm283x-rpi-csi1-2lane.dtsi" - #include "bcm283x-rpi-i2c0mux_0_44.dtsi" --#include "bcm283x-rpi-cam1-regulator.dtsi" - - / { - chosen { -@@ -548,6 +547,9 @@ - gpio = <&expgpio 5 GPIO_ACTIVE_HIGH>; - }; - -+cam0_reg: &cam_dummy_reg { -+}; -+ - / { - __overrides__ { - act_led_gpio = <&act_led>,"gpios:4"; ---- a/arch/arm/boot/dts/bcm2711-rpi-cm4.dts -+++ b/arch/arm/boot/dts/bcm2711-rpi-cm4.dts -@@ -297,7 +297,6 @@ - #include "bcm283x-rpi-csi0-2lane.dtsi" - #include "bcm283x-rpi-csi1-4lane.dtsi" - #include "bcm283x-rpi-i2c0mux_0_44.dtsi" --#include "bcm283x-rpi-cam1-regulator.dtsi" - - / { - chosen { ---- a/arch/arm/boot/dts/bcm283x-rpi-cam1-regulator.dtsi -+++ /dev/null -@@ -1,10 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0 -- --/ { -- cam1_reg: cam1_reg { -- compatible = "regulator-fixed"; -- regulator-name = "cam1-reg"; -- enable-active-high; -- status = "disabled"; -- }; --}; diff --git a/target/linux/bcm27xx/patches-5.15/950-0609-dtoverlays-Convert-the-camera-sensor-overlays-to-use.patch b/target/linux/bcm27xx/patches-5.15/950-0609-dtoverlays-Convert-the-camera-sensor-overlays-to-use.patch deleted file mode 100644 index 6d7203b3b..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0609-dtoverlays-Convert-the-camera-sensor-overlays-to-use.patch +++ /dev/null @@ -1,474 +0,0 @@ -From f8b75a1bcdbf2b5cc591079cafad3b94cc74ff48 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Sat, 20 Nov 2021 14:43:29 +0000 -Subject: [PATCH] dtoverlays: Convert the camera sensor overlays to use - the new regs and clks. - -Now that we have regulators and clocks defined in the base DT for -image sensors, switch the overlays to use them. - -Signed-off-by: Dave Stevenson ---- - arch/arm/boot/dts/overlays/imx219-overlay.dts | 40 ++++--------------- - .../boot/dts/overlays/imx290_327-overlay.dtsi | 40 ++++--------------- - .../boot/dts/overlays/imx477_378-overlay.dtsi | 31 +++----------- - arch/arm/boot/dts/overlays/imx519-overlay.dts | 38 +++--------------- - arch/arm/boot/dts/overlays/ov5647-overlay.dts | 18 +++++---- - arch/arm/boot/dts/overlays/ov7251-overlay.dts | 37 +++-------------- - arch/arm/boot/dts/overlays/ov9281-overlay.dts | 39 ++++-------------- - 7 files changed, 50 insertions(+), 193 deletions(-) - ---- a/arch/arm/boot/dts/overlays/imx219-overlay.dts -+++ b/arch/arm/boot/dts/overlays/imx219-overlay.dts -@@ -20,12 +20,12 @@ - reg = <0x10>; - status = "okay"; - -- clocks = <&imx219_clk>; -+ clocks = <&cam1_clk>; - clock-names = "xclk"; - - VANA-supply = <&cam1_reg>; /* 2.8v */ -- VDIG-supply = <&imx219_vdig>; /* 1.8v */ -- VDDL-supply = <&imx219_vddl>; /* 1.2v */ -+ VDIG-supply = <&cam_dummy_reg>; /* 1.8v */ -+ VDDL-supply = <&cam_dummy_reg>; /* 1.2v */ - - rotation = <180>; - orientation = <2>; -@@ -68,26 +68,10 @@ - }; - - fragment@3 { -- target-path="/"; -+ target = <&cam1_clk>; - __overlay__ { -- imx219_vdig: fixedregulator@1 { -- compatible = "regulator-fixed"; -- regulator-name = "imx219_vdig"; -- regulator-min-microvolt = <1800000>; -- regulator-max-microvolt = <1800000>; -- }; -- imx219_vddl: fixedregulator@2 { -- compatible = "regulator-fixed"; -- regulator-name = "imx219_vddl"; -- regulator-min-microvolt = <1200000>; -- regulator-max-microvolt = <1200000>; -- }; -- -- imx219_clk: camera-clk { -- compatible = "fixed-clock"; -- #clock-cells = <0>; -- clock-frequency = <24000000>; -- }; -+ status = "okay"; -+ clock-frequency = <24000000>; - }; - }; - -@@ -99,16 +83,6 @@ - }; - - fragment@5 { -- target = <&cam1_reg>; -- __overlay__ { -- status = "okay"; -- regulator-name = "imx219_vana"; -- regulator-min-microvolt = <2800000>; -- regulator-max-microvolt = <2800000>; -- }; -- }; -- -- fragment@6 { - target = <&csi1>; - __overlay__ { - brcm,media-controller; -@@ -118,6 +92,6 @@ - __overrides__ { - rotation = <&imx219>,"rotation:0"; - orientation = <&imx219>,"orientation:0"; -- media-controller = <0>,"=6"; -+ media-controller = <0>,"=5"; - }; - }; ---- a/arch/arm/boot/dts/overlays/imx290_327-overlay.dtsi -+++ b/arch/arm/boot/dts/overlays/imx290_327-overlay.dtsi -@@ -20,7 +20,7 @@ - reg = <0x1a>; - status = "okay"; - -- clocks = <&imx290_clk>; -+ clocks = <&cam1_clk>; - clock-names = "xclk"; - clock-frequency = <37125000>; - -@@ -28,8 +28,8 @@ - orientation = <2>; - - vdda-supply = <&cam1_reg>; /* 2.8v */ -- vdddo-supply = <&imx290_vdddo>; /* 1.8v */ -- vddd-supply = <&imx290_vddd>; /* 1.5v */ -+ vdddo-supply = <&cam_dummy_reg>; /* 1.8v */ -+ vddd-supply = <&cam_dummy_reg>; /* 1.5v */ - - port { - imx290_0: endpoint { -@@ -62,26 +62,10 @@ - }; - - fragment@3 { -- target-path="/"; -+ target = <&cam1_clk>; - __overlay__ { -- imx290_vdddo: fixedregulator@1 { -- compatible = "regulator-fixed"; -- regulator-name = "imx290_vdddo"; -- regulator-min-microvolt = <1800000>; -- regulator-max-microvolt = <1800000>; -- }; -- imx290_vddd: fixedregulator@2 { -- compatible = "regulator-fixed"; -- regulator-name = "imx290_vddd"; -- regulator-min-microvolt = <1500000>; -- regulator-max-microvolt = <1500000>; -- }; -- -- imx290_clk: camera-clk { -- compatible = "fixed-clock"; -- #clock-cells = <0>; -- clock-frequency = <37125000>; -- }; -+ status = "okay"; -+ clock-frequency = <37125000>; - }; - }; - -@@ -92,16 +76,6 @@ - }; - }; - -- fragment@5 { -- target = <&cam1_reg>; -- __overlay__ { -- status = "okay"; -- regulator-name = "imx290_vdda"; -- regulator-min-microvolt = <2800000>; -- regulator-max-microvolt = <2800000>; -- }; -- }; -- - fragment@6 { - target = <&imx290_0>; - __overlay__ { -@@ -143,7 +117,7 @@ - - __overrides__ { - 4lane = <0>, "-6+7-8+9"; -- clock-frequency = <&imx290_clk>,"clock-frequency:0", -+ clock-frequency = <&cam1_clk>,"clock-frequency:0", - <&imx290>,"clock-frequency:0"; - rotation = <&imx290>,"rotation:0"; - orientation = <&imx290>,"orientation:0"; ---- a/arch/arm/boot/dts/overlays/imx477_378-overlay.dtsi -+++ b/arch/arm/boot/dts/overlays/imx477_378-overlay.dtsi -@@ -15,12 +15,12 @@ - reg = <0x1a>; - status = "okay"; - -- clocks = <&imx477_clk>; -+ clocks = <&cam1_clk>; - clock-names = "xclk"; - - VANA-supply = <&cam1_reg>; /* 2.8v */ -- VDIG-supply = <&imx477_vdig>; /* 1.05v */ -- VDDL-supply = <&imx477_vddl>; /* 1.8v */ -+ VDIG-supply = <&cam_dummy_reg>; /* 1.05v */ -+ VDDL-supply = <&cam_dummy_reg>; /* 1.8v */ - - rotation = <180>; - orientation = <2>; -@@ -63,25 +63,10 @@ - }; - - fragment@3 { -- target-path="/"; -+ target = <&cam1_clk>; - __overlay__ { -- imx477_vdig: fixedregulator@0 { -- compatible = "regulator-fixed"; -- regulator-name = "imx477_vdig"; -- regulator-min-microvolt = <1050000>; -- regulator-max-microvolt = <1050000>; -- }; -- imx477_vddl: fixedregulator@1 { -- compatible = "regulator-fixed"; -- regulator-name = "imx477_vddl"; -- regulator-min-microvolt = <1800000>; -- regulator-max-microvolt = <1800000>; -- }; -- imx477_clk: camera-clk { -- compatible = "fixed-clock"; -- #clock-cells = <0>; -- clock-frequency = <24000000>; -- }; -+ clock-frequency = <24000000>; -+ status = "okay"; - }; - }; - -@@ -95,11 +80,7 @@ - fragment@5 { - target = <&cam1_reg>; - __overlay__ { -- status = "okay"; -- regulator-name = "imx477_vana"; - startup-delay-us = <300000>; -- regulator-min-microvolt = <2800000>; -- regulator-max-microvolt = <2800000>; - }; - }; - ---- a/arch/arm/boot/dts/overlays/imx519-overlay.dts -+++ b/arch/arm/boot/dts/overlays/imx519-overlay.dts -@@ -20,12 +20,12 @@ - reg = <0x1a>; - status = "okay"; - -- clocks = <&imx519_clk>; -+ clocks = <&cam1_clk>; - clock-names = "xclk"; - - VANA-supply = <&cam1_reg>; /* 2.8v */ -- VDIG-supply = <&imx519_vdig>; /* 1.8v */ -- VDDL-supply = <&imx519_vddl>; /* 1.2v */ -+ VDIG-supply = <&cam_dummy_reg>; /* 1.8v */ -+ VDDL-supply = <&cam_dummy_reg>; /* 1.2v */ - - rotation = <0>; - orientation = <2>; -@@ -68,26 +68,10 @@ - }; - - fragment@3 { -- target-path="/"; -+ target = <&cam1_clk>; - __overlay__ { -- imx519_vdig: fixedregulator@1 { -- compatible = "regulator-fixed"; -- regulator-name = "imx519_vdig"; -- regulator-min-microvolt = <1800000>; -- regulator-max-microvolt = <1800000>; -- }; -- imx519_vddl: fixedregulator@2 { -- compatible = "regulator-fixed"; -- regulator-name = "imx519_vddl"; -- regulator-min-microvolt = <1200000>; -- regulator-max-microvolt = <1200000>; -- }; -- -- imx519_clk: camera-clk { -- compatible = "fixed-clock"; -- #clock-cells = <0>; -- clock-frequency = <24000000>; -- }; -+ clock-frequency = <24000000>; -+ status = "okay"; - }; - }; - -@@ -98,16 +82,6 @@ - }; - }; - -- fragment@5 { -- target = <&cam1_reg>; -- __overlay__ { -- status = "okay"; -- regulator-name = "imx519_vana"; -- regulator-min-microvolt = <2800000>; -- regulator-max-microvolt = <2800000>; -- }; -- }; -- - fragment@6 { - target = <&csi1>; - __overlay__ { ---- a/arch/arm/boot/dts/overlays/ov5647-overlay.dts -+++ b/arch/arm/boot/dts/overlays/ov5647-overlay.dts -@@ -19,7 +19,7 @@ - status = "okay"; - - pwdn-gpios = <&gpio 41 1>, <&gpio 32 1>; -- clocks = <&ov5647_clk>; -+ clocks = <&cam1_clk>; - - rotation = <0>; - orientation = <2>; -@@ -77,13 +77,10 @@ - }; - - fragment@5 { -- target-path = "/"; -+ target = <&cam1_clk>; - __overlay__ { -- ov5647_clk: camera-clk { -- compatible = "fixed-clock"; -- #clock-cells = <0>; -- clock-frequency = <25000000>; -- }; -+ status = "okay"; -+ clock-frequency = <25000000>; - }; - }; - -@@ -94,6 +91,13 @@ - }; - }; - -+ fragment@7 { -+ target = <&cam1_reg>; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; -+ - __overrides__ { - rotation = <&ov5647>,"rotation:0"; - orientation = <&ov5647>,"orientation:0"; ---- a/arch/arm/boot/dts/overlays/ov7251-overlay.dts -+++ b/arch/arm/boot/dts/overlays/ov7251-overlay.dts -@@ -20,13 +20,13 @@ - reg = <0x60>; - status = "okay"; - -- clocks = <&ov7251_clk>; -+ clocks = <&cam1_clk>; - clock-names = "xclk"; - clock-frequency = <24000000>; - -- vdddo-supply = <&ov7251_dovdd>; -+ vdddo-supply = <&cam_dummy_reg>; - vdda-supply = <&cam1_reg>; -- vddd-supply = <&ov7251_dvdd>; -+ vddd-supply = <&cam_dummy_reg>; - - rotation = <0>; - orientation = <2>; -@@ -67,25 +67,10 @@ - }; - - fragment@3 { -- target-path="/"; -+ target = <&cam1_clk>; - __overlay__ { -- ov7251_dovdd: fixedregulator@1 { -- compatible = "regulator-fixed"; -- regulator-name = "ov7251_dovdd"; -- regulator-min-microvolt = <1800000>; -- regulator-max-microvolt = <1800000>; -- }; -- ov7251_dvdd: fixedregulator@2 { -- compatible = "regulator-fixed"; -- regulator-name = "ov7251_dvdd"; -- regulator-min-microvolt = <1200000>; -- regulator-max-microvolt = <1200000>; -- }; -- ov7251_clk: ov7251-clk { -- compatible = "fixed-clock"; -- #clock-cells = <0>; -- clock-frequency = <24000000>; -- }; -+ status = "okay"; -+ clock-frequency = <24000000>; - }; - }; - -@@ -96,16 +81,6 @@ - }; - }; - -- fragment@5 { -- target = <&cam1_reg>; -- __overlay__ { -- status = "okay"; -- regulator-name = "ov7251_avdd"; -- regulator-min-microvolt = <2800000>; -- regulator-max-microvolt = <2800000>; -- }; -- }; -- - fragment@6 { - target = <&csi1>; - __dormant__ { ---- a/arch/arm/boot/dts/overlays/ov9281-overlay.dts -+++ b/arch/arm/boot/dts/overlays/ov9281-overlay.dts -@@ -20,12 +20,12 @@ - reg = <0x60>; - status = "okay"; - -- clocks = <&ov9281_clk>; -+ clocks = <&cam1_clk>; - clock-names = "xvclk"; - - avdd-supply = <&cam1_reg>; -- dovdd-supply = <&ov9281_dovdd>; -- dvdd-supply = <&ov9281_dvdd>; -+ dovdd-supply = <&cam_dummy_reg>; -+ dvdd-supply = <&cam_dummy_reg>; - - rotation = <0>; - orientation = <2>; -@@ -67,25 +67,10 @@ - }; - - fragment@3 { -- target-path="/"; -+ target = <&cam1_clk>; - __overlay__ { -- ov9281_dovdd: fixedregulator@1 { -- compatible = "regulator-fixed"; -- regulator-name = "ov9281_dovdd"; -- regulator-min-microvolt = <1800000>; -- regulator-max-microvolt = <1800000>; -- }; -- ov9281_dvdd: fixedregulator@2 { -- compatible = "regulator-fixed"; -- regulator-name = "ov9281_dvdd"; -- regulator-min-microvolt = <1200000>; -- regulator-max-microvolt = <1200000>; -- }; -- ov9281_clk: ov9281-clk { -- compatible = "fixed-clock"; -- #clock-cells = <0>; -- clock-frequency = <24000000>; -- }; -+ status = "okay"; -+ clock-frequency = <24000000>; - }; - }; - -@@ -97,16 +82,6 @@ - }; - - fragment@5 { -- target = <&cam1_reg>; -- __overlay__ { -- status = "okay"; -- regulator-name = "ov9281_avdd"; -- regulator-min-microvolt = <2800000>; -- regulator-max-microvolt = <2800000>; -- }; -- }; -- -- fragment@6 { - target = <&csi1>; - __overlay__ { - brcm,media-controller; -@@ -116,6 +91,6 @@ - __overrides__ { - rotation = <&ov9281>,"rotation:0"; - orientation = <&ov9281>,"orientation:0"; -- media-controller = <0>,"=6"; -+ media-controller = <0>,"=5"; - }; - }; diff --git a/target/linux/bcm27xx/patches-5.15/950-0611-dtoverlays-Convert-ov5647-to-use-the-regulator-frame.patch b/target/linux/bcm27xx/patches-5.15/950-0611-dtoverlays-Convert-ov5647-to-use-the-regulator-frame.patch deleted file mode 100644 index b0fe1e20a..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0611-dtoverlays-Convert-ov5647-to-use-the-regulator-frame.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 395fb7877a140602e4247690ad02975259bcc6ab Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 22 Nov 2021 12:30:18 +0000 -Subject: [PATCH] dtoverlays: Convert ov5647 to use the regulator - framework - -Fixing up shutdown GPIOs via overrides is ugly, and doesn't work -on eg CM4 where both cameras share the same shutdown GPIO. - -The driver is now updated to use the regulator framework, so switch -to using that instead. - -Signed-off-by: Dave Stevenson ---- - arch/arm/boot/dts/overlays/ov5647-overlay.dts | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - ---- a/arch/arm/boot/dts/overlays/ov5647-overlay.dts -+++ b/arch/arm/boot/dts/overlays/ov5647-overlay.dts -@@ -18,9 +18,12 @@ - reg = <0x36>; - status = "okay"; - -- pwdn-gpios = <&gpio 41 1>, <&gpio 32 1>; - clocks = <&cam1_clk>; - -+ avdd-supply = <&cam1_reg>; -+ dovdd-supply = <&cam_dummy_reg>; -+ dvdd-supply = <&cam_dummy_reg>; -+ - rotation = <0>; - orientation = <2>; - -@@ -67,12 +70,9 @@ - }; - - fragment@4 { -- target-path="/__overrides__"; -+ target = <&cam1_reg>; - __overlay__ { -- cam0-pwdn-ctrl = <&ov5647>,"pwdn-gpios:0"; -- cam0-pwdn = <&ov5647>,"pwdn-gpios:4"; -- cam0-led-ctrl = <&ov5647>,"pwdn-gpios:12"; -- cam0-led = <&ov5647>,"pwdn-gpios:16"; -+ startup-delay-us = <20000>; - }; - }; - diff --git a/target/linux/bcm27xx/patches-5.15/950-0613-ARM-dts-bcm2711-cm4s-Correct-i2c0mux-to-use-0-1-and-.patch b/target/linux/bcm27xx/patches-5.15/950-0613-ARM-dts-bcm2711-cm4s-Correct-i2c0mux-to-use-0-1-and-.patch deleted file mode 100644 index 82bd6ce88..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0613-ARM-dts-bcm2711-cm4s-Correct-i2c0mux-to-use-0-1-and-.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 46fbde5380a7a1707e19ac46842cb9ce526c5216 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 14 Dec 2021 14:54:15 +0000 -Subject: [PATCH] ARM: dts: bcm2711-cm4s Correct i2c0mux to use 0/1 and - 28/29 & 2 regulators - -CM4S follows CM1/3, so based on the documentation cameras/displays -connect to 0/1 and 28/29, not 0/1 and 44/45. - -Likewise the camera regulator controls are independent as on CM1/3. - -Signed-off-by: Dave Stevenson ---- - arch/arm/boot/dts/bcm2711-rpi-cm4s.dts | 18 ++++++++++++++++-- - 1 file changed, 16 insertions(+), 2 deletions(-) - ---- a/arch/arm/boot/dts/bcm2711-rpi-cm4s.dts -+++ b/arch/arm/boot/dts/bcm2711-rpi-cm4s.dts -@@ -155,14 +155,28 @@ - - #include "bcm283x-rpi-csi0-2lane.dtsi" - #include "bcm283x-rpi-csi1-4lane.dtsi" --#include "bcm283x-rpi-i2c0mux_0_44.dtsi" --#include "bcm283x-rpi-cam1-regulator.dtsi" -+#include "bcm283x-rpi-i2c0mux_0_28.dtsi" - - / { - chosen { - bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1"; - }; - -+ cam1_reg: cam1_reg { -+ compatible = "regulator-fixed"; -+ regulator-name = "cam1-regulator"; -+ gpio = <&gpio 2 GPIO_ACTIVE_HIGH>; -+ enable-active-high; -+ status = "disabled"; -+ }; -+ cam0_reg: cam0_reg { -+ compatible = "regulator-fixed"; -+ regulator-name = "cam0-regulator"; -+ gpio = <&gpio 30 GPIO_ACTIVE_HIGH>; -+ enable-active-high; -+ status = "disabled"; -+ }; -+ - aliases { - serial0 = &uart0; - mmc0 = &emmc2; diff --git a/target/linux/bcm27xx/patches-5.15/950-0614-dtoverlays-Add-option-to-select-camera-as-on-CAM0-of.patch b/target/linux/bcm27xx/patches-5.15/950-0614-dtoverlays-Add-option-to-select-camera-as-on-CAM0-of.patch deleted file mode 100644 index 5bc7e7137..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0614-dtoverlays-Add-option-to-select-camera-as-on-CAM0-of.patch +++ /dev/null @@ -1,944 +0,0 @@ -From 0bda3692e0fa20e793ad3857a6ffde6bca7d49ca Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 22 Nov 2021 12:44:29 +0000 -Subject: [PATCH] dtoverlays: Add option to select camera as on CAM0 of - CM - -Parameterise the overlays so that they can have an optional -cam0 parameter to switch to i2c_vc and csi0. - -Signed-off-by: Dave Stevenson ---- - arch/arm/boot/dts/bcm2708-rpi-cm.dts | 1 + - arch/arm/boot/dts/bcm2708-rpi-cm.dtsi | 4 + - arch/arm/boot/dts/bcm2710-rpi-cm3.dts | 5 ++ - arch/arm/boot/dts/bcm2711-rpi-cm4s.dts | 25 +++--- - arch/arm/boot/dts/overlays/README | 30 +++++++ - arch/arm/boot/dts/overlays/imx219-overlay.dts | 67 ++++++++------- - .../boot/dts/overlays/imx290_327-overlay.dtsi | 27 +++--- - .../boot/dts/overlays/imx477_378-overlay.dtsi | 84 +++++++++---------- - arch/arm/boot/dts/overlays/imx519-overlay.dts | 23 +++-- - .../arm/boot/dts/overlays/irs1125-overlay.dts | 35 ++++---- - arch/arm/boot/dts/overlays/ov5647-overlay.dts | 33 +++----- - arch/arm/boot/dts/overlays/ov7251-overlay.dts | 28 +++---- - arch/arm/boot/dts/overlays/ov9281-overlay.dts | 29 ++++--- - .../boot/dts/overlays/tc358743-overlay.dts | 43 ++++------ - 14 files changed, 221 insertions(+), 213 deletions(-) - ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -@@ -12,6 +12,7 @@ - - &cam1_reg { - gpio = <&gpio 2 GPIO_ACTIVE_HIGH>; -+ status = "disabled"; - }; - - cam0_reg: &cam0_regulator { ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -@@ -14,5 +14,9 @@ - act_led_gpio = <&act_led>,"gpios:4"; - act_led_activelow = <&act_led>,"gpios:8"; - act_led_trigger = <&act_led>,"linux,default-trigger"; -+ cam0_reg = <&cam0_reg>,"status"; -+ cam0_reg_gpio = <&cam0_reg>,"gpios:4"; -+ cam1_reg = <&cam1_reg>,"status"; -+ cam1_reg_gpio = <&cam1_reg>,"gpios:4"; - }; - }; ---- a/arch/arm/boot/dts/bcm2710-rpi-cm3.dts -+++ b/arch/arm/boot/dts/bcm2710-rpi-cm3.dts -@@ -12,6 +12,7 @@ - - &cam1_reg { - gpio = <&gpio 2 GPIO_ACTIVE_HIGH>; -+ status = "disabled"; - }; - - cam0_reg: &cam0_regulator { -@@ -137,5 +138,9 @@ cam0_reg: &cam0_regulator { - act_led_gpio = <&act_led>,"gpios:4"; - act_led_activelow = <&act_led>,"gpios:8"; - act_led_trigger = <&act_led>,"linux,default-trigger"; -+ cam0_reg = <&cam0_reg>,"status"; -+ cam0_reg_gpio = <&cam0_reg>,"gpios:4"; -+ cam1_reg = <&cam1_reg>,"status"; -+ cam1_reg_gpio = <&cam1_reg>,"gpios:4"; - }; - }; ---- a/arch/arm/boot/dts/bcm2711-rpi-cm4s.dts -+++ b/arch/arm/boot/dts/bcm2711-rpi-cm4s.dts -@@ -162,21 +162,6 @@ - bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1"; - }; - -- cam1_reg: cam1_reg { -- compatible = "regulator-fixed"; -- regulator-name = "cam1-regulator"; -- gpio = <&gpio 2 GPIO_ACTIVE_HIGH>; -- enable-active-high; -- status = "disabled"; -- }; -- cam0_reg: cam0_reg { -- compatible = "regulator-fixed"; -- regulator-name = "cam0-regulator"; -- gpio = <&gpio 30 GPIO_ACTIVE_HIGH>; -- enable-active-high; -- status = "disabled"; -- }; -- - aliases { - serial0 = &uart0; - mmc0 = &emmc2; -@@ -399,6 +384,16 @@ - brcm,disable-headphones = <1>; - }; - -+&cam1_reg { -+ gpio = <&gpio 2 GPIO_ACTIVE_HIGH>; -+ status = "disabled"; -+}; -+ -+cam0_reg: &cam0_regulator { -+ gpio = <&gpio 30 GPIO_ACTIVE_HIGH>; -+ status = "disabled"; -+}; -+ - / { - __overrides__ { - act_led_gpio = <&act_led>,"gpios:4"; ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -144,6 +144,16 @@ Params: - See /sys/kernel/debug/raspberrypi_axi_monitor - for the results. - -+ cam0_reg Enables CAM 0 regulator. CM1 & 3 only. -+ -+ cam0_reg_gpio Set GPIO for CAM 0 regulator. Default 30. -+ CM1 & 3 only. -+ -+ cam1_reg Enables CAM 1 regulator. CM1 & 3 only. -+ -+ cam1_reg_gpio Set GPIO for CAM 1 regulator. Default 2. -+ CM1 & 3 only. -+ - eee Enable Energy Efficient Ethernet support for - compatible devices (default "on"). See also - "tx_lpi_timer". Pi3B+ only. -@@ -1845,6 +1855,8 @@ Params: rotation Mounting - 2 = external, default external) - media-controller Configure use of Media Controller API for - configuring the sensor (default on) -+ cam0 Adopt the default configuration for CAM0 on a -+ Compute Module (CSI0, i2c_vc, and cam0_reg). - - - Name: imx290 -@@ -1867,6 +1879,8 @@ Params: 4lane Enable 4 - 180, default 0) - media-controller Configure use of Media Controller API for - configuring the sensor (default on) -+ cam0 Adopt the default configuration for CAM0 on a -+ Compute Module (CSI0, i2c_vc, and cam0_reg). - - - Name: imx378 -@@ -1880,6 +1894,8 @@ Params: rotation Mounting - 2 = external, default external) - media-controller Configure use of Media Controller API for - configuring the sensor (default on) -+ cam0 Adopt the default configuration for CAM0 on a -+ Compute Module (CSI0, i2c_vc, and cam0_reg). - - - Name: imx477 -@@ -1893,6 +1909,8 @@ Params: rotation Mounting - 2 = external, default external) - media-controller Configure use of Media Controller API for - configuring the sensor (default on) -+ cam0 Adopt the default configuration for CAM0 on a -+ Compute Module (CSI0, i2c_vc, and cam0_reg). - - - Name: imx519 -@@ -1906,6 +1924,8 @@ Params: rotation Mounting - 2 = external, default external) - media-controller Configure use of Media Controller API for - configuring the sensor (default on) -+ cam0 Adopt the default configuration for CAM0 on a -+ Compute Module (CSI0, i2c_vc, and cam0_reg). - - - Name: iqaudio-codec -@@ -1972,6 +1992,8 @@ Info: Infineon irs1125 TOF camera modu - Load: dtoverlay=irs1125,= - Params: media-controller Configure use of Media Controller API for - configuring the sensor (default off) -+ cam0 Adopt the default configuration for CAM0 on a -+ Compute Module (CSI0, i2c_vc, and cam0_reg). - - - Name: jedec-spi-nor -@@ -2385,6 +2407,8 @@ Params: rotation Mounting - 2 = external, default external) - media-controller Configure use of Media Controller API for - configuring the sensor (default on) -+ cam0 Adopt the default configuration for CAM0 on a -+ Compute Module (CSI0, i2c_vc, and cam0_reg). - - - Name: ov7251 -@@ -2398,6 +2422,8 @@ Params: rotation Mounting - 2 = external, default external) - media-controller Configure use of Media Controller API for - configuring the sensor (default off) -+ cam0 Adopt the default configuration for CAM0 on a -+ Compute Module (CSI0, i2c_vc, and cam0_reg). - - - Name: ov9281 -@@ -2411,6 +2437,8 @@ Params: rotation Mounting - 2 = external, default external) - media-controller Configure use of Media Controller API for - configuring the sensor (default on) -+ cam0 Adopt the default configuration for CAM0 on a -+ Compute Module (CSI0, i2c_vc, and cam0_reg). - - - Name: papirus -@@ -3393,6 +3421,8 @@ Params: 4lane Use 4 la - are supported by the driver. - media-controller Configure use of Media Controller API for - configuring the sensor (default off) -+ cam0 Adopt the default configuration for CAM0 on a -+ Compute Module (CSI0, i2c_vc, and cam0_reg). - - - Name: tc358743-audio ---- a/arch/arm/boot/dts/overlays/imx219-overlay.dts -+++ b/arch/arm/boot/dts/overlays/imx219-overlay.dts -@@ -9,6 +9,28 @@ - compatible = "brcm,bcm2835"; - - fragment@0 { -+ target = <&i2c0if>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ clk_frag: fragment@1 { -+ target = <&cam1_clk>; -+ __overlay__ { -+ status = "okay"; -+ clock-frequency = <24000000>; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&i2c0mux>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ i2c_frag: fragment@100 { - target = <&i2c_csi_dsi>; - __overlay__ { - #address-cells = <1>; -@@ -32,7 +54,7 @@ - - port { - imx219_0: endpoint { -- remote-endpoint = <&csi1_ep>; -+ remote-endpoint = <&csi_ep>; - clock-lanes = <0>; - data-lanes = <1 2>; - clock-noncontinuous; -@@ -44,13 +66,14 @@ - }; - }; - -- fragment@1 { -+ csi_frag: fragment@101 { - target = <&csi1>; -- __overlay__ { -+ csi: __overlay__ { - status = "okay"; -+ brcm,media-controller; - - port { -- csi1_ep: endpoint { -+ csi_ep: endpoint { - remote-endpoint = <&imx219_0>; - clock-lanes = <0>; - data-lanes = <1 2>; -@@ -60,38 +83,14 @@ - }; - }; - -- fragment@2 { -- target = <&i2c0if>; -- __overlay__ { -- status = "okay"; -- }; -- }; -- -- fragment@3 { -- target = <&cam1_clk>; -- __overlay__ { -- status = "okay"; -- clock-frequency = <24000000>; -- }; -- }; -- -- fragment@4 { -- target = <&i2c0mux>; -- __overlay__ { -- status = "okay"; -- }; -- }; -- -- fragment@5 { -- target = <&csi1>; -- __overlay__ { -- brcm,media-controller; -- }; -- }; -- - __overrides__ { - rotation = <&imx219>,"rotation:0"; - orientation = <&imx219>,"orientation:0"; -- media-controller = <0>,"=5"; -+ media-controller = <&csi>,"brcm,media-controller?"; -+ cam0 = <&i2c_frag>, "target:0=",<&i2c_vc>, -+ <&csi_frag>, "target:0=",<&csi0>, -+ <&clk_frag>, "target:0=",<&cam0_clk>, -+ <&imx219>, "clocks:0=",<&cam0_clk>, -+ <&imx219>, "VANA-supply:0=",<&cam0_reg>; - }; - }; ---- a/arch/arm/boot/dts/overlays/imx290_327-overlay.dtsi -+++ b/arch/arm/boot/dts/overlays/imx290_327-overlay.dtsi -@@ -9,7 +9,7 @@ - /{ - compatible = "brcm,bcm2835"; - -- fragment@0 { -+ i2c_frag: fragment@0 { - target = <&i2c_csi_dsi>; - __overlay__ { - #address-cells = <1>; -@@ -41,10 +41,11 @@ - }; - }; - -- fragment@1 { -+ csi_frag: fragment@1 { - target = <&csi1>; -- __overlay__ { -+ csi: __overlay__ { - status = "okay"; -+ brcm,media-controller; - - port { - csi1_ep: endpoint { -@@ -61,9 +62,9 @@ - }; - }; - -- fragment@3 { -+ clk_frag: fragment@3 { - target = <&cam1_clk>; -- __overlay__ { -+ cam_clk: __overlay__ { - status = "okay"; - clock-frequency = <37125000>; - }; -@@ -108,19 +109,17 @@ - }; - }; - -- fragment@10 { -- target = <&csi1>; -- __overlay__ { -- brcm,media-controller; -- }; -- }; -- - __overrides__ { - 4lane = <0>, "-6+7-8+9"; -- clock-frequency = <&cam1_clk>,"clock-frequency:0", -+ clock-frequency = <&cam_clk>,"clock-frequency:0", - <&imx290>,"clock-frequency:0"; - rotation = <&imx290>,"rotation:0"; - orientation = <&imx290>,"orientation:0"; -- media-controller = <0>,"=10"; -+ media-controller = <&csi>,"brcm,media-controller?"; -+ cam0 = <&i2c_frag>, "target:0=",<&i2c_vc>, -+ <&csi_frag>, "target:0=",<&csi0>, -+ <&clk_frag>, "target:0=",<&cam0_clk>, -+ <&imx290>, "clocks:0=",<&cam0_clk>, -+ <&imx290>, "vdda-supply:0=",<&cam0_reg>; - }; - }; ---- a/arch/arm/boot/dts/overlays/imx477_378-overlay.dtsi -+++ b/arch/arm/boot/dts/overlays/imx477_378-overlay.dtsi -@@ -4,7 +4,36 @@ - /{ - compatible = "brcm,bcm2835"; - -- fragment@0 { -+ fragment@2 { -+ target = <&i2c0if>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ clk_frag: fragment@3 { -+ target = <&cam1_clk>; -+ cam_clk: __overlay__ { -+ clock-frequency = <24000000>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@4 { -+ target = <&i2c0mux>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ reg_frag: fragment@5 { -+ target = <&cam1_reg>; -+ cam_reg: __overlay__ { -+ startup-delay-us = <300000>; -+ }; -+ }; -+ -+ i2c_frag: fragment@100 { - target = <&i2c_csi_dsi>; - __overlay__ { - #address-cells = <1>; -@@ -27,7 +56,7 @@ - - port { - imx477_0: endpoint { -- remote-endpoint = <&csi1_ep>; -+ remote-endpoint = <&csi_ep>; - clock-lanes = <0>; - data-lanes = <1 2>; - clock-noncontinuous; -@@ -39,13 +68,14 @@ - }; - }; - -- fragment@1 { -+ csi_frag: fragment@101 { - target = <&csi1>; -- __overlay__ { -+ csi: __overlay__ { - status = "okay"; -+ brcm,media-controller; - - port { -- csi1_ep: endpoint { -+ csi_ep: endpoint { - remote-endpoint = <&imx477_0>; - clock-lanes = <0>; - data-lanes = <1 2>; -@@ -55,45 +85,15 @@ - }; - }; - -- fragment@2 { -- target = <&i2c0if>; -- __overlay__ { -- status = "okay"; -- }; -- }; -- -- fragment@3 { -- target = <&cam1_clk>; -- __overlay__ { -- clock-frequency = <24000000>; -- status = "okay"; -- }; -- }; -- -- fragment@4 { -- target = <&i2c0mux>; -- __overlay__ { -- status = "okay"; -- }; -- }; -- -- fragment@5 { -- target = <&cam1_reg>; -- __overlay__ { -- startup-delay-us = <300000>; -- }; -- }; -- -- fragment@6 { -- target = <&csi1>; -- __overlay__ { -- brcm,media-controller; -- }; -- }; -- - __overrides__ { - rotation = <&imx477>,"rotation:0"; - orientation = <&imx477>,"orientation:0"; -- media-controller = <0>,"=6"; -+ media-controller = <&csi>,"brcm,media-controller?"; -+ cam0 = <&i2c_frag>, "target:0=",<&i2c_vc>, -+ <&csi_frag>, "target:0=",<&csi0>, -+ <&clk_frag>, "target:0=",<&cam0_clk>, -+ <®_frag>, "target:0=",<&cam0_reg>, -+ <&imx477>, "clocks:0=",<&cam0_clk>, -+ <&imx477>, "vdda-supply:0=",<&cam0_reg>; - }; - }; ---- a/arch/arm/boot/dts/overlays/imx519-overlay.dts -+++ b/arch/arm/boot/dts/overlays/imx519-overlay.dts -@@ -8,7 +8,7 @@ - /{ - compatible = "brcm,bcm2835"; - -- fragment@0 { -+ i2c_frag: fragment@0 { - target = <&i2c_csi_dsi>; - __overlay__ { - #address-cells = <1>; -@@ -44,10 +44,11 @@ - }; - }; - -- fragment@1 { -+ csi_frag: fragment@1 { - target = <&csi1>; -- __overlay__ { -+ csi: __overlay__ { - status = "okay"; -+ brcm,media-controller; - - port{ - csi1_ep: endpoint{ -@@ -67,7 +68,7 @@ - }; - }; - -- fragment@3 { -+ clk_frag: fragment@3 { - target = <&cam1_clk>; - __overlay__ { - clock-frequency = <24000000>; -@@ -82,16 +83,14 @@ - }; - }; - -- fragment@6 { -- target = <&csi1>; -- __overlay__ { -- brcm,media-controller; -- }; -- }; -- - __overrides__ { - rotation = <&imx519>,"rotation:0"; - orientation = <&imx519>,"orientation:0"; -- media-controller = <0>,"=6"; -+ media-controller = <&csi>,"brcm,media-controller?"; -+ cam0 = <&i2c_frag>, "target:0=",<&i2c_vc>, -+ <&csi_frag>, "target:0=",<&csi0>, -+ <&clk_frag>, "target:0=",<&cam0_clk>, -+ <&imx519>, "clocks:0=",<&cam0_clk>, -+ <&imx519>, "VANA-supply:0=",<&cam0_reg>; - }; - }; ---- a/arch/arm/boot/dts/overlays/irs1125-overlay.dts -+++ b/arch/arm/boot/dts/overlays/irs1125-overlay.dts -@@ -6,20 +6,20 @@ - /{ - compatible = "brcm,bcm2835"; - -- fragment@0 { -+ i2c_frag: fragment@0 { - target = <&i2c_csi_dsi>; - __overlay__ { - #address-cells = <1>; - #size-cells = <0>; - status = "okay"; - -- irs1125: irs1125@3D { -+ irs1125: irs1125@3d { - compatible = "infineon,irs1125"; -- reg = <0x3D>; -+ reg = <0x3d>; - status = "okay"; - - pwdn-gpios = <&gpio 5 0>; -- clocks = <&irs1125_clk>; -+ clocks = <&cam1_clk>; - - port { - irs1125_0: endpoint { -@@ -35,9 +35,9 @@ - }; - }; - -- fragment@1 { -+ csi_frag: fragment@1 { - target = <&csi1>; -- __overlay__ { -+ csi: __overlay__ { - status = "okay"; - - port { -@@ -72,25 +72,18 @@ - }; - }; - -- fragment@5 { -- target-path = "/"; -+ clk_frag: fragment@5 { -+ target = <&cam1_clk>; - __overlay__ { -- irs1125_clk: camera-clk { -- compatible = "fixed-clock"; -- #clock-cells = <0>; -- clock-frequency = <26000000>; -- }; -- }; -- }; -- -- fragment@6 { -- target = <&csi1>; -- __dormant__ { -- brcm,media-controller; -+ clock-frequency = <26000000>; - }; - }; - - __overrides__ { -- media-controller = <0>,"=6"; -+ media-controller = <&csi>,"brcm,media-controller?"; -+ cam0 = <&i2c_frag>, "target:0=",<&i2c_vc>, -+ <&csi_frag>, "target:0=",<&csi0>, -+ <&clk_frag>, "target:0=",<&cam0_clk>, -+ <&irs1125>, "clocks:0=",<&cam0_clk>; - }; - }; ---- a/arch/arm/boot/dts/overlays/ov5647-overlay.dts -+++ b/arch/arm/boot/dts/overlays/ov5647-overlay.dts -@@ -6,7 +6,7 @@ - /{ - compatible = "brcm,bcm2835"; - -- fragment@0 { -+ i2c_frag: fragment@0 { - target = <&i2c_csi_dsi>; - __overlay__ { - #address-cells = <1>; -@@ -41,10 +41,11 @@ - }; - }; - -- fragment@1 { -+ csi_frag: fragment@1 { - target = <&csi1>; -- __overlay__ { -+ csi: __overlay__ { - status = "okay"; -+ brcm,media-controller; - - port { - csi1_ep: endpoint { -@@ -69,14 +70,14 @@ - }; - }; - -- fragment@4 { -+ reg_frag: fragment@4 { - target = <&cam1_reg>; - __overlay__ { - startup-delay-us = <20000>; - }; - }; - -- fragment@5 { -+ clk_frag: fragment@5 { - target = <&cam1_clk>; - __overlay__ { - status = "okay"; -@@ -84,23 +85,15 @@ - }; - }; - -- fragment@6 { -- target = <&csi1>; -- __overlay__ { -- brcm,media-controller; -- }; -- }; -- -- fragment@7 { -- target = <&cam1_reg>; -- __overlay__ { -- status = "disabled"; -- }; -- }; -- - __overrides__ { - rotation = <&ov5647>,"rotation:0"; - orientation = <&ov5647>,"orientation:0"; -- media-controller = <0>,"=6"; -+ media-controller = <&csi>,"brcm,media-controller?"; -+ cam0 = <&i2c_frag>, "target:0=",<&i2c_vc>, -+ <&csi_frag>, "target:0=",<&csi0>, -+ <®_frag>, "target:0=",<&cam0_reg>, -+ <&clk_frag>, "target:0=",<&cam0_clk>, -+ <&ov5647>, "clocks:0=",<&cam0_clk>, -+ <&ov5647>, "avdd-supply:0=",<&cam0_reg>; - }; - }; ---- a/arch/arm/boot/dts/overlays/ov7251-overlay.dts -+++ b/arch/arm/boot/dts/overlays/ov7251-overlay.dts -@@ -8,7 +8,7 @@ - /{ - compatible = "brcm,bcm2835"; - -- fragment@0 { -+ i2c_frag: fragment@0 { - target = <&i2c_csi_dsi>; - __overlay__ { - #address-cells = <1>; -@@ -45,9 +45,9 @@ - }; - }; - -- fragment@1 { -+ csi_frag: fragment@1 { - target = <&csi1>; -- __overlay__ { -+ csi: __overlay__ { - status = "okay"; - - port { -@@ -67,30 +67,28 @@ - }; - - fragment@3 { -- target = <&cam1_clk>; -+ target = <&i2c0mux>; - __overlay__ { - status = "okay"; -- clock-frequency = <24000000>; - }; - }; - -- fragment@4 { -- target = <&i2c0mux>; -+ clk_frag: fragment@4 { -+ target = <&cam1_clk>; - __overlay__ { - status = "okay"; -- }; -- }; -- -- fragment@6 { -- target = <&csi1>; -- __dormant__ { -- brcm,media-controller; -+ clock-frequency = <24000000>; - }; - }; - - __overrides__ { - rotation = <&ov7251>,"rotation:0"; - orientation = <&ov7251>,"orientation:0"; -- media-controller = <0>,"=6"; -+ media-controller = <&csi>,"brcm,media-controller?"; -+ cam0 = <&i2c_frag>, "target:0=",<&i2c_vc>, -+ <&csi_frag>, "target:0=",<&csi0>, -+ <&clk_frag>, "target:0=",<&cam0_clk>, -+ <&ov7251>, "clocks:0=",<&cam0_clk>, -+ <&ov7251>, "vdda-supply:0=",<&cam0_reg>; - }; - }; ---- a/arch/arm/boot/dts/overlays/ov9281-overlay.dts -+++ b/arch/arm/boot/dts/overlays/ov9281-overlay.dts -@@ -8,7 +8,7 @@ - /{ - compatible = "brcm,bcm2835"; - -- fragment@0 { -+ i2c_frag: fragment@0 { - target = <&i2c_csi_dsi>; - __overlay__ { - #address-cells = <1>; -@@ -44,10 +44,11 @@ - }; - }; - -- fragment@1 { -+ csi_frag: fragment@1 { - target = <&csi1>; -- __overlay__ { -+ csi: __overlay__ { - status = "okay"; -+ brcm,media-controller; - - port { - csi1_ep: endpoint { -@@ -67,30 +68,28 @@ - }; - - fragment@3 { -- target = <&cam1_clk>; -- __overlay__ { -- status = "okay"; -- clock-frequency = <24000000>; -- }; -- }; -- -- fragment@4 { - target = <&i2c0mux>; - __overlay__ { - status = "okay"; - }; - }; - -- fragment@5 { -- target = <&csi1>; -+ clk_frag: fragment@4 { -+ target = <&cam1_clk>; - __overlay__ { -- brcm,media-controller; -+ status = "okay"; -+ clock-frequency = <24000000>; - }; - }; - - __overrides__ { - rotation = <&ov9281>,"rotation:0"; - orientation = <&ov9281>,"orientation:0"; -- media-controller = <0>,"=5"; -+ media-controller = <&csi>,"brcm,media-controller?"; -+ cam0 = <&i2c_frag>, "target:0=",<&i2c_vc>, -+ <&csi_frag>, "target:0=",<&csi0>, -+ <&clk_frag>, "target:0=",<&cam0_clk>, -+ <&ov9281>, "clocks:0=",<&cam0_clk>, -+ <&ov9281>, "avdd-supply:0=",<&cam0_reg>; - }; - }; ---- a/arch/arm/boot/dts/overlays/tc358743-overlay.dts -+++ b/arch/arm/boot/dts/overlays/tc358743-overlay.dts -@@ -6,23 +6,23 @@ - /{ - compatible = "brcm,bcm2835"; - -- fragment@0 { -+ i2c_frag: fragment@0 { - target = <&i2c_csi_dsi>; - __overlay__ { - #address-cells = <1>; - #size-cells = <0>; - status = "okay"; - -- tc358743@0f { -+ tc358743: tc358743@f { - compatible = "toshiba,tc358743"; - reg = <0x0f>; - status = "okay"; - -- clocks = <&tc358743_clk>; -+ clocks = <&cam1_clk>; - clock-names = "refclk"; - - port { -- tc358743: endpoint { -+ tc358743_0: endpoint { - remote-endpoint = <&csi1_ep>; - clock-lanes = <0>; - clock-noncontinuous; -@@ -34,28 +34,28 @@ - }; - }; - -- fragment@1 { -+ csi_frag: fragment@1 { - target = <&csi1>; -- __overlay__ { -+ csi: __overlay__ { - status = "okay"; - - port { - csi1_ep: endpoint { -- remote-endpoint = <&tc358743>; -+ remote-endpoint = <&tc358743_0>; - }; - }; - }; - }; - - fragment@2 { -- target = <&tc358743>; -+ target = <&tc358743_0>; - __overlay__ { - data-lanes = <1 2>; - }; - }; - - fragment@3 { -- target = <&tc358743>; -+ target = <&tc358743_0>; - __dormant__ { - data-lanes = <1 2 3 4>; - }; -@@ -75,14 +75,10 @@ - }; - }; - -- fragment@6 { -- target-path = "/"; -+ clk_frag: fragment@6 { -+ target = <&cam1_clk>; - __overlay__ { -- tc358743_clk: bridge-clk { -- compatible = "fixed-clock"; -- #clock-cells = <0>; -- clock-frequency = <27000000>; -- }; -+ clock-frequency = <27000000>; - }; - }; - -@@ -100,16 +96,13 @@ - }; - }; - -- fragment@9 { -- target = <&csi1>; -- __dormant__ { -- brcm,media-controller; -- }; -- }; -- - __overrides__ { - 4lane = <0>, "-2+3-7+8"; -- link-frequency = <&tc358743>,"link-frequencies#0"; -- media-controller = <0>,"=9"; -+ link-frequency = <&tc358743_0>,"link-frequencies#0"; -+ media-controller = <&csi>,"brcm,media-controller?"; -+ cam0 = <&i2c_frag>, "target:0=",<&i2c_vc>, -+ <&csi_frag>, "target:0=",<&csi0>, -+ <&clk_frag>, "target:0=",<&cam0_clk>, -+ <&tc358743>, "clocks:0=",<&cam0_clk>; - }; - }; diff --git a/target/linux/bcm27xx/patches-5.15/950-0615-ASoC-ma120x0p-Increase-maximum-sample-rate-to-192KHz.patch b/target/linux/bcm27xx/patches-5.15/950-0615-ASoC-ma120x0p-Increase-maximum-sample-rate-to-192KHz.patch deleted file mode 100644 index 9adba5e09..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0615-ASoC-ma120x0p-Increase-maximum-sample-rate-to-192KHz.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 4fe6752d2690c108aba6cd0576b86878b69b597c Mon Sep 17 00:00:00 2001 -From: Joerg Schambacher -Date: Wed, 15 Dec 2021 19:27:00 +0100 -Subject: [PATCH] ASoC:ma120x0p: Increase maximum sample rate to 192KHz - -Change the maximum sample rate for the amplifier to -192KHz as given in the Infineon specification. - -Signed-off-by: Joerg Schambacher ---- - sound/soc/codecs/ma120x0p.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/sound/soc/codecs/ma120x0p.c -+++ b/sound/soc/codecs/ma120x0p.c -@@ -1002,7 +1002,7 @@ static struct snd_soc_dai_driver ma120x0 - .channels_max = 2, - .rates = SNDRV_PCM_RATE_CONTINUOUS, - .rate_min = 44100, -- .rate_max = 96000, -+ .rate_max = 192000, - .formats = SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE - }, - .ops = &ma120x0p_dai_ops, diff --git a/target/linux/bcm27xx/patches-5.15/950-0617-drm-vc4-kms-Take-old-state-core-clock-rate-into-acco.patch b/target/linux/bcm27xx/patches-5.15/950-0617-drm-vc4-kms-Take-old-state-core-clock-rate-into-acco.patch deleted file mode 100644 index 8eb806773..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0617-drm-vc4-kms-Take-old-state-core-clock-rate-into-acco.patch +++ /dev/null @@ -1,38 +0,0 @@ -From ae03b35cf2792e7c4cf55c44dc37322487b72d1d Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Thu, 18 Nov 2021 14:04:00 +0100 -Subject: [PATCH] drm/vc4: kms: Take old state core clock rate into - account - -During a commit, the core clock, which feeds the HVS, needs to run at -a minimum of 500MHz. - -While doing that commit, we can also change the mode to one that -requires a higher core clock, so we take the core clock rate associated -to that new state into account for that boost. - -However, the old state also needs to be taken into account if it -requires a core clock higher that the new one and our 500MHz limit, -since it's still live in hardware at the beginning of our commit. - -Fixes: 16e101051f32 ("drm/vc4: Increase the core clock based on HVS load") -Signed-off-by: Maxime Ripard ---- - drivers/gpu/drm/vc4/vc4_kms.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_kms.c -@@ -390,9 +390,10 @@ static void vc4_atomic_commit_tail(struc - } - - if (vc4->hvs && vc4->hvs->hvs5) { -+ unsigned long state_rate = max(old_hvs_state->core_clock_rate, -+ new_hvs_state->core_clock_rate); - unsigned long core_rate = max_t(unsigned long, -- 500000000, -- new_hvs_state->core_clock_rate); -+ 500000000, state_rate); - - core_req = clk_request_start(hvs->core_clk, core_rate); - /* diff --git a/target/linux/bcm27xx/patches-5.15/950-0618-drm-vc4-hvs-Store-channel-in-variable.patch b/target/linux/bcm27xx/patches-5.15/950-0618-drm-vc4-hvs-Store-channel-in-variable.patch deleted file mode 100644 index 282de9ab2..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0618-drm-vc4-hvs-Store-channel-in-variable.patch +++ /dev/null @@ -1,53 +0,0 @@ -From ac0e3e24176b77fa19a7a2e041879f6c5e652122 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Mon, 29 Nov 2021 12:18:39 +0100 -Subject: [PATCH] drm/vc4: hvs: Store channel in variable - -The assigned_channel field of our vc4_crtc_state structure is accessed -multiple times in vc4_hvs_atomic_flush, so let's move it to a variable -that can be used in all those places. - -Signed-off-by: Maxime Ripard ---- - drivers/gpu/drm/vc4/vc4_hvs.c | 9 +++++---- - 1 file changed, 5 insertions(+), 4 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_hvs.c -+++ b/drivers/gpu/drm/vc4/vc4_hvs.c -@@ -697,6 +697,7 @@ void vc4_hvs_atomic_flush(struct drm_crt - struct drm_device *dev = crtc->dev; - struct vc4_dev *vc4 = to_vc4_dev(dev); - struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state); -+ unsigned int channel = vc4_state->assigned_channel; - struct drm_plane *plane; - struct vc4_plane_state *vc4_plane_state; - bool debug_dump_regs = false; -@@ -737,8 +738,8 @@ void vc4_hvs_atomic_flush(struct drm_crt - /* This sets a black background color fill, as is the case - * with other DRM drivers. - */ -- HVS_WRITE(SCALER_DISPBKGNDX(vc4_state->assigned_channel), -- HVS_READ(SCALER_DISPBKGNDX(vc4_state->assigned_channel)) | -+ HVS_WRITE(SCALER_DISPBKGNDX(channel), -+ HVS_READ(SCALER_DISPBKGNDX(channel)) | - SCALER_DISPBKGND_FILL); - - /* Only update DISPLIST if the CRTC was already running and is not -@@ -752,7 +753,7 @@ void vc4_hvs_atomic_flush(struct drm_crt - vc4_hvs_update_dlist(crtc); - - if (crtc->state->color_mgmt_changed) { -- u32 dispbkgndx = HVS_READ(SCALER_DISPBKGNDX(vc4_state->assigned_channel)); -+ u32 dispbkgndx = HVS_READ(SCALER_DISPBKGNDX(channel)); - - if (crtc->state->gamma_lut) { - if (!vc4->hvs->hvs5) { -@@ -775,7 +776,7 @@ void vc4_hvs_atomic_flush(struct drm_crt - if (!vc4->hvs->hvs5) - dispbkgndx &= ~SCALER_DISPBKGND_GAMMA; - } -- HVS_WRITE(SCALER_DISPBKGNDX(vc4_state->assigned_channel), dispbkgndx); -+ HVS_WRITE(SCALER_DISPBKGNDX(channel), dispbkgndx); - } - - if (debug_dump_regs) { diff --git a/target/linux/bcm27xx/patches-5.15/950-0619-drm-vc4-hvs-Remove-dlist-setup-duplication.patch b/target/linux/bcm27xx/patches-5.15/950-0619-drm-vc4-hvs-Remove-dlist-setup-duplication.patch deleted file mode 100644 index 14d0d24e8..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0619-drm-vc4-hvs-Remove-dlist-setup-duplication.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 5fa4e656501eed725b9151a38e5b55a45571bf31 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Mon, 6 Dec 2021 16:17:56 +0100 -Subject: [PATCH] drm/vc4: hvs: Remove dlist setup duplication - -Setting the DISPLISTx register needs to occur in every case, and we -don't need to protect the register using the event_lock, so we can just -move it after the if branches and simplify a bit the function. - -Signed-off-by: Maxime Ripard ---- - drivers/gpu/drm/vc4/vc4_hvs.c | 9 +++------ - 1 file changed, 3 insertions(+), 6 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_hvs.c -+++ b/drivers/gpu/drm/vc4/vc4_hvs.c -@@ -639,15 +639,12 @@ static void vc4_hvs_update_dlist(struct - crtc->state->event = NULL; - } - -- HVS_WRITE(SCALER_DISPLISTX(vc4_state->assigned_channel), -- vc4_state->mm.start); -- - spin_unlock_irqrestore(&dev->event_lock, flags); -- } else { -- HVS_WRITE(SCALER_DISPLISTX(vc4_state->assigned_channel), -- vc4_state->mm.start); - } - -+ HVS_WRITE(SCALER_DISPLISTX(vc4_state->assigned_channel), -+ vc4_state->mm.start); -+ - spin_lock_irqsave(&vc4_crtc->irq_lock, flags); - vc4_crtc->current_dlist = vc4_state->mm.start; - spin_unlock_irqrestore(&vc4_crtc->irq_lock, flags); diff --git a/target/linux/bcm27xx/patches-5.15/950-0620-drm-vc4-hvs-Move-the-dlist-setup-to-its-own-function.patch b/target/linux/bcm27xx/patches-5.15/950-0620-drm-vc4-hvs-Move-the-dlist-setup-to-its-own-function.patch deleted file mode 100644 index b494bc386..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0620-drm-vc4-hvs-Move-the-dlist-setup-to-its-own-function.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 849b51e0dea1746f17b8b0b59c5e6cc831e23697 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Mon, 6 Dec 2021 16:31:33 +0100 -Subject: [PATCH] drm/vc4: hvs: Move the dlist setup to its own - function - -The vc4_hvs_update_dlist function mostly deals with setting up the -vblank events and setting up the dlist entry pointer to our current -active one. - -We'll want to do the former separately from the vblank handling in later -patches, so let's move it to a function of its own. - -Signed-off-by: Maxime Ripard ---- - drivers/gpu/drm/vc4/vc4_hvs.c | 19 ++++++++++++++----- - 1 file changed, 14 insertions(+), 5 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_hvs.c -+++ b/drivers/gpu/drm/vc4/vc4_hvs.c -@@ -619,10 +619,19 @@ int vc4_hvs_atomic_check(struct drm_crtc - return vc4_hvs_gamma_check(crtc, state); - } - --static void vc4_hvs_update_dlist(struct drm_crtc *crtc) -+static void vc4_hvs_install_dlist(struct drm_crtc *crtc) - { - struct drm_device *dev = crtc->dev; - struct vc4_dev *vc4 = to_vc4_dev(dev); -+ struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state); -+ -+ HVS_WRITE(SCALER_DISPLISTX(vc4_state->assigned_channel), -+ vc4_state->mm.start); -+} -+ -+static void vc4_hvs_update_dlist(struct drm_crtc *crtc) -+{ -+ struct drm_device *dev = crtc->dev; - struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); - struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state); - unsigned long flags; -@@ -642,9 +651,6 @@ static void vc4_hvs_update_dlist(struct - spin_unlock_irqrestore(&dev->event_lock, flags); - } - -- HVS_WRITE(SCALER_DISPLISTX(vc4_state->assigned_channel), -- vc4_state->mm.start); -- - spin_lock_irqsave(&vc4_crtc->irq_lock, flags); - vc4_crtc->current_dlist = vc4_state->mm.start; - spin_unlock_irqrestore(&vc4_crtc->irq_lock, flags); -@@ -671,6 +677,7 @@ void vc4_hvs_atomic_enable(struct drm_cr - struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); - bool oneshot = vc4_crtc->feeds_txp; - -+ vc4_hvs_install_dlist(crtc); - vc4_hvs_update_dlist(crtc); - vc4_hvs_init_channel(vc4, crtc, mode, oneshot); - } -@@ -746,8 +753,10 @@ void vc4_hvs_atomic_flush(struct drm_crt - * If the CRTC is being disabled, there's no point in updating this - * information. - */ -- if (crtc->state->active && old_state->active) -+ if (crtc->state->active && old_state->active) { -+ vc4_hvs_install_dlist(crtc); - vc4_hvs_update_dlist(crtc); -+ } - - if (crtc->state->color_mgmt_changed) { - u32 dispbkgndx = HVS_READ(SCALER_DISPBKGNDX(channel)); diff --git a/target/linux/bcm27xx/patches-5.15/950-0622-drm-vc4-Skip-writes-to-disabled-packet-RAM.patch b/target/linux/bcm27xx/patches-5.15/950-0622-drm-vc4-Skip-writes-to-disabled-packet-RAM.patch deleted file mode 100644 index ab4587cb1..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0622-drm-vc4-Skip-writes-to-disabled-packet-RAM.patch +++ /dev/null @@ -1,58 +0,0 @@ -From f0206374000464f8284826d3bdc50b2fc7c5ea71 Mon Sep 17 00:00:00 2001 -From: Dom Cobley -Date: Fri, 10 Dec 2021 18:03:18 +0000 -Subject: [PATCH] drm/vc4: Skip writes to disabled packet RAM - -This path actually occurs when audio is started during a hdmi mode set. -As the data will be written by vc4_hdmi_set_infoframes when packet RAM -is enabled again, don't treat as an error - -Signed-off-by: Dom Cobley ---- - drivers/gpu/drm/vc4/vc4_hdmi.c | 5 ++++- - drivers/gpu/drm/vc4/vc4_hdmi.h | 6 ++++++ - 2 files changed, 10 insertions(+), 1 deletion(-) - ---- a/drivers/gpu/drm/vc4/vc4_hdmi.c -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c -@@ -685,6 +685,7 @@ static void vc4_hdmi_encoder_post_crtc_d - - mutex_lock(&vc4_hdmi->mutex); - -+ vc4_hdmi->output_enabled = false; - spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); - - HDMI_WRITE(HDMI_RAM_PACKET_CONFIG, 0); -@@ -1202,6 +1203,7 @@ static void vc4_hdmi_encoder_post_crtc_e - VC4_HDMI_RAM_PACKET_ENABLE); - - spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); -+ vc4_hdmi->output_enabled = true; - - vc4_hdmi_set_infoframes(encoder); - } -@@ -1607,7 +1609,8 @@ static int vc4_hdmi_audio_prepare(struct - spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); - - memcpy(&vc4_hdmi->audio.infoframe, ¶ms->cea, sizeof(params->cea)); -- vc4_hdmi_set_audio_infoframe(encoder); -+ if (vc4_hdmi->output_enabled) -+ vc4_hdmi_set_audio_infoframe(encoder); - - mutex_unlock(&vc4_hdmi->mutex); - ---- a/drivers/gpu/drm/vc4/vc4_hdmi.h -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.h -@@ -209,6 +209,12 @@ struct vc4_hdmi { - struct drm_display_mode saved_adjusted_mode; - - /** -+ * @output_enabled: Is the HDMI controller currently active? -+ * Protected by @mutex. -+ */ -+ bool output_enabled; -+ -+ /** - * @scdc_enabled: Is the HDMI controller currently running with - * the scrambler on? Protected by @mutex. - */ diff --git a/target/linux/bcm27xx/patches-5.15/950-0623-drm-edid-Rename-drm_hdmi_avi_infoframe_colorspace-to.patch b/target/linux/bcm27xx/patches-5.15/950-0623-drm-edid-Rename-drm_hdmi_avi_infoframe_colorspace-to.patch deleted file mode 100644 index a9269e4ca..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0623-drm-edid-Rename-drm_hdmi_avi_infoframe_colorspace-to.patch +++ /dev/null @@ -1,100 +0,0 @@ -From d27c36f9beed7d6a9d19ea1d642a7fb898eb6d95 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Wed, 14 Apr 2021 16:21:08 +0200 -Subject: [PATCH] drm/edid: Rename drm_hdmi_avi_infoframe_colorspace to - _colorimetry - -The drm_hdmi_avi_infoframe_colorspace() function actually sets the -colorimetry and extended_colorimetry fields in the hdmi_avi_infoframe -structure with DRM_MODE_COLORIMETRY_* values. - -To make things worse, the hdmi_avi_infoframe structure also has a -colorspace field used to signal whether an RGB or YUV output is being -used. - -Let's remove the inconsistency and allow for the colorspace usage by -renaming the function. - -Signed-off-by: Maxime Ripard ---- - drivers/gpu/drm/drm_edid.c | 8 ++++---- - drivers/gpu/drm/i915/display/intel_hdmi.c | 2 +- - drivers/gpu/drm/i915/display/intel_lspcon.c | 2 +- - drivers/gpu/drm/vc4/vc4_hdmi.c | 2 +- - include/drm/drm_edid.h | 4 ++-- - 5 files changed, 9 insertions(+), 9 deletions(-) - ---- a/drivers/gpu/drm/drm_edid.c -+++ b/drivers/gpu/drm/drm_edid.c -@@ -5746,13 +5746,13 @@ static const u32 hdmi_colorimetry_val[] - #undef ACE - - /** -- * drm_hdmi_avi_infoframe_colorspace() - fill the HDMI AVI infoframe -- * colorspace information -+ * drm_hdmi_avi_infoframe_colorimetry() - fill the HDMI AVI infoframe -+ * colorimetry information - * @frame: HDMI AVI infoframe - * @conn_state: connector state - */ - void --drm_hdmi_avi_infoframe_colorspace(struct hdmi_avi_infoframe *frame, -+drm_hdmi_avi_infoframe_colorimetry(struct hdmi_avi_infoframe *frame, - const struct drm_connector_state *conn_state) - { - u32 colorimetry_val; -@@ -5771,7 +5771,7 @@ drm_hdmi_avi_infoframe_colorspace(struct - frame->extended_colorimetry = (colorimetry_val >> 2) & - EXTENDED_COLORIMETRY_MASK; - } --EXPORT_SYMBOL(drm_hdmi_avi_infoframe_colorspace); -+EXPORT_SYMBOL(drm_hdmi_avi_infoframe_colorimetry); - - /** - * drm_hdmi_avi_infoframe_quant_range() - fill the HDMI AVI infoframe ---- a/drivers/gpu/drm/i915/display/intel_hdmi.c -+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c -@@ -730,7 +730,7 @@ intel_hdmi_compute_avi_infoframe(struct - else - frame->colorspace = HDMI_COLORSPACE_RGB; - -- drm_hdmi_avi_infoframe_colorspace(frame, conn_state); -+ drm_hdmi_avi_infoframe_colorimetry(frame, conn_state); - - /* nonsense combination */ - drm_WARN_ON(encoder->base.dev, crtc_state->limited_color_range && ---- a/drivers/gpu/drm/i915/display/intel_lspcon.c -+++ b/drivers/gpu/drm/i915/display/intel_lspcon.c -@@ -537,7 +537,7 @@ void lspcon_set_infoframes(struct intel_ - frame.avi.colorspace = HDMI_COLORSPACE_RGB; - - /* Set the Colorspace as per the HDMI spec */ -- drm_hdmi_avi_infoframe_colorspace(&frame.avi, conn_state); -+ drm_hdmi_avi_infoframe_colorimetry(&frame.avi, conn_state); - - /* nonsense combination */ - drm_WARN_ON(encoder->base.dev, crtc_state->limited_color_range && ---- a/drivers/gpu/drm/vc4/vc4_hdmi.c -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c -@@ -517,7 +517,7 @@ static void vc4_hdmi_set_avi_infoframe(s - vc4_encoder->limited_rgb_range ? - HDMI_QUANTIZATION_RANGE_LIMITED : - HDMI_QUANTIZATION_RANGE_FULL); -- drm_hdmi_avi_infoframe_colorspace(&frame.avi, cstate); -+ drm_hdmi_avi_infoframe_colorimetry(&frame.avi, cstate); - drm_hdmi_avi_infoframe_bars(&frame.avi, cstate); - - vc4_hdmi_write_infoframe(encoder, &frame); ---- a/include/drm/drm_edid.h -+++ b/include/drm/drm_edid.h -@@ -401,8 +401,8 @@ drm_hdmi_vendor_infoframe_from_display_m - const struct drm_display_mode *mode); - - void --drm_hdmi_avi_infoframe_colorspace(struct hdmi_avi_infoframe *frame, -- const struct drm_connector_state *conn_state); -+drm_hdmi_avi_infoframe_colorimetry(struct hdmi_avi_infoframe *frame, -+ const struct drm_connector_state *conn_state); - - void - drm_hdmi_avi_infoframe_bars(struct hdmi_avi_infoframe *frame, diff --git a/target/linux/bcm27xx/patches-5.15/950-0624-drm-vc4-hdmi-Add-full-range-RGB-helper.patch b/target/linux/bcm27xx/patches-5.15/950-0624-drm-vc4-hdmi-Add-full-range-RGB-helper.patch deleted file mode 100644 index f590f4fa4..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0624-drm-vc4-hdmi-Add-full-range-RGB-helper.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 4809cf80fdd964c413045e550fb137a18dc98ba2 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Tue, 12 Jan 2021 15:55:07 +0100 -Subject: [PATCH] drm/vc4: hdmi: Add full range RGB helper - -We're going to need to tell whether we want to run with a full or -limited range RGB output in multiple places in the code, so let's create -a helper that will return whether we need with full range or not. - -Acked-by: Thomas Zimmermann -Signed-off-by: Maxime Ripard ---- - drivers/gpu/drm/vc4/vc4_hdmi.c | 12 ++++++++++-- - 1 file changed, 10 insertions(+), 2 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_hdmi.c -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c -@@ -108,6 +108,15 @@ static bool vc4_hdmi_mode_needs_scrambli - return (mode->clock * 1000) > HDMI_14_MAX_TMDS_CLK; - } - -+static bool vc4_hdmi_is_full_range_rgb(struct vc4_hdmi *vc4_hdmi, -+ const struct drm_display_mode *mode) -+{ -+ struct vc4_hdmi_encoder *vc4_encoder = &vc4_hdmi->encoder; -+ -+ return !vc4_encoder->hdmi_monitor || -+ drm_default_rgb_quant_range(mode) == HDMI_QUANTIZATION_RANGE_FULL; -+} -+ - static int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused) - { - struct drm_info_node *node = (struct drm_info_node *)m->private; -@@ -1117,8 +1126,7 @@ static void vc4_hdmi_encoder_pre_crtc_en - - mutex_lock(&vc4_hdmi->mutex); - -- if (vc4_encoder->hdmi_monitor && -- drm_default_rgb_quant_range(mode) == HDMI_QUANTIZATION_RANGE_LIMITED) { -+ if (!vc4_hdmi_is_full_range_rgb(vc4_hdmi, mode)) { - if (vc4_hdmi->variant->csc_setup) - vc4_hdmi->variant->csc_setup(vc4_hdmi, true); - diff --git a/target/linux/bcm27xx/patches-5.15/950-0625-drm-vc4-hdmi-Use-full-range-helper-in-csc-functions.patch b/target/linux/bcm27xx/patches-5.15/950-0625-drm-vc4-hdmi-Use-full-range-helper-in-csc-functions.patch deleted file mode 100644 index 9f3b81e54..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0625-drm-vc4-hdmi-Use-full-range-helper-in-csc-functions.patch +++ /dev/null @@ -1,126 +0,0 @@ -From 183b128892a416e4c09b6379f964cb9620f2a7ea Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Tue, 12 Jan 2021 15:57:50 +0100 -Subject: [PATCH] drm/vc4: hdmi: Use full range helper in csc functions - -The CSC callbacks takes a boolean as an argument to tell whether we're -using the full range or limited range RGB. - -However, with the upcoming YUV support, the logic will be a bit more -complex. In order to address this, let's make the callbacks take the -entire mode, and call our new helper to tell whether the full or limited -range RGB should be used. - -Acked-by: Thomas Zimmermann -Signed-off-by: Maxime Ripard ---- - drivers/gpu/drm/vc4/vc4_hdmi.c | 31 +++++++++++-------------------- - drivers/gpu/drm/vc4/vc4_hdmi.h | 4 ++-- - 2 files changed, 13 insertions(+), 22 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_hdmi.c -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c -@@ -505,7 +505,6 @@ static void vc4_hdmi_write_infoframe(str - static void vc4_hdmi_set_avi_infoframe(struct drm_encoder *encoder) - { - struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); -- struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder); - struct drm_connector *connector = &vc4_hdmi->connector; - struct drm_connector_state *cstate = connector->state; - const struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode; -@@ -523,9 +522,9 @@ static void vc4_hdmi_set_avi_infoframe(s - - drm_hdmi_avi_infoframe_quant_range(&frame.avi, - connector, mode, -- vc4_encoder->limited_rgb_range ? -- HDMI_QUANTIZATION_RANGE_LIMITED : -- HDMI_QUANTIZATION_RANGE_FULL); -+ vc4_hdmi_is_full_range_rgb(vc4_hdmi, mode) ? -+ HDMI_QUANTIZATION_RANGE_FULL : -+ HDMI_QUANTIZATION_RANGE_LIMITED); - drm_hdmi_avi_infoframe_colorimetry(&frame.avi, cstate); - drm_hdmi_avi_infoframe_bars(&frame.avi, cstate); - -@@ -742,7 +741,8 @@ static void vc4_hdmi_encoder_post_crtc_p - mutex_unlock(&vc4_hdmi->mutex); - } - --static void vc4_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, bool enable) -+static void vc4_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, -+ const struct drm_display_mode *mode) - { - unsigned long flags; - u32 csc_ctl; -@@ -752,7 +752,7 @@ static void vc4_hdmi_csc_setup(struct vc - csc_ctl = VC4_SET_FIELD(VC4_HD_CSC_CTL_ORDER_BGR, - VC4_HD_CSC_CTL_ORDER); - -- if (enable) { -+ if (!vc4_hdmi_is_full_range_rgb(vc4_hdmi, mode)) { - /* CEA VICs other than #1 requre limited range RGB - * output unless overridden by an AVI infoframe. - * Apply a colorspace conversion to squash 0-255 down -@@ -782,7 +782,8 @@ static void vc4_hdmi_csc_setup(struct vc - spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); - } - --static void vc5_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, bool enable) -+static void vc5_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, -+ const struct drm_display_mode *mode) - { - unsigned long flags; - u32 csc_ctl; -@@ -791,7 +792,7 @@ static void vc5_hdmi_csc_setup(struct vc - - spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); - -- if (enable) { -+ if (!vc4_hdmi_is_full_range_rgb(vc4_hdmi, mode)) { - /* CEA VICs other than #1 requre limited range RGB - * output unless overridden by an AVI infoframe. - * Apply a colorspace conversion to squash 0-255 down -@@ -1121,22 +1122,12 @@ static void vc4_hdmi_encoder_pre_crtc_en - { - struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); - struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode; -- struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder); - unsigned long flags; - - mutex_lock(&vc4_hdmi->mutex); - -- if (!vc4_hdmi_is_full_range_rgb(vc4_hdmi, mode)) { -- if (vc4_hdmi->variant->csc_setup) -- vc4_hdmi->variant->csc_setup(vc4_hdmi, true); -- -- vc4_encoder->limited_rgb_range = true; -- } else { -- if (vc4_hdmi->variant->csc_setup) -- vc4_hdmi->variant->csc_setup(vc4_hdmi, false); -- -- vc4_encoder->limited_rgb_range = false; -- } -+ if (vc4_hdmi->variant->csc_setup) -+ vc4_hdmi->variant->csc_setup(vc4_hdmi, mode); - - spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); - HDMI_WRITE(HDMI_FIFO_CTL, VC4_HDMI_FIFO_CTL_MASTER_SLAVE_N); ---- a/drivers/gpu/drm/vc4/vc4_hdmi.h -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.h -@@ -12,7 +12,6 @@ - struct vc4_hdmi_encoder { - struct vc4_encoder base; - bool hdmi_monitor; -- bool limited_rgb_range; - }; - - static inline struct vc4_hdmi_encoder * -@@ -77,7 +76,8 @@ struct vc4_hdmi_variant { - void (*reset)(struct vc4_hdmi *vc4_hdmi); - - /* Callback to enable / disable the CSC */ -- void (*csc_setup)(struct vc4_hdmi *vc4_hdmi, bool enable); -+ void (*csc_setup)(struct vc4_hdmi *vc4_hdmi, -+ const struct drm_display_mode *mode); - - /* Callback to configure the video timings in the HDMI block */ - void (*set_timings)(struct vc4_hdmi *vc4_hdmi, diff --git a/target/linux/bcm27xx/patches-5.15/950-0626-drm-vc4-hdmi-Move-XBAR-setup-to-csc_setup.patch b/target/linux/bcm27xx/patches-5.15/950-0626-drm-vc4-hdmi-Move-XBAR-setup-to-csc_setup.patch deleted file mode 100644 index aba91b557..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0626-drm-vc4-hdmi-Move-XBAR-setup-to-csc_setup.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 9d59b54f5b608a823f01982a1aabac76a364556d Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Wed, 13 Jan 2021 11:07:48 +0100 -Subject: [PATCH] drm/vc4: hdmi: Move XBAR setup to csc_setup - -On the BCM2711, the HDMI_VEC_INTERFACE_XBAR register configuration -depends on whether we're using an RGB or YUV output. Let's move that -configuration to the CSC setup. - -Acked-by: Thomas Zimmermann -Signed-off-by: Maxime Ripard ---- - drivers/gpu/drm/vc4/vc4_hdmi.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/gpu/drm/vc4/vc4_hdmi.c -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c -@@ -792,6 +792,8 @@ static void vc5_hdmi_csc_setup(struct vc - - spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); - -+ HDMI_WRITE(HDMI_VEC_INTERFACE_XBAR, 0x354021); -+ - if (!vc4_hdmi_is_full_range_rgb(vc4_hdmi, mode)) { - /* CEA VICs other than #1 requre limited range RGB - * output unless overridden by an AVI infoframe. -@@ -907,7 +909,6 @@ static void vc5_hdmi_set_timings(struct - - spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); - -- HDMI_WRITE(HDMI_VEC_INTERFACE_XBAR, 0x354021); - HDMI_WRITE(HDMI_HORZA, - (vsync_pos ? VC5_HDMI_HORZA_VPOS : 0) | - (hsync_pos ? VC5_HDMI_HORZA_HPOS : 0) | diff --git a/target/linux/bcm27xx/patches-5.15/950-0627-drm-vc4-hdmi-Replace-CSC_CTL-hardcoded-value-by-defi.patch b/target/linux/bcm27xx/patches-5.15/950-0627-drm-vc4-hdmi-Replace-CSC_CTL-hardcoded-value-by-defi.patch deleted file mode 100644 index c4349f55b..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0627-drm-vc4-hdmi-Replace-CSC_CTL-hardcoded-value-by-defi.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 77b0e8ded57e7fb5d742fb533d7a9bb3f3788513 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Wed, 13 Jan 2021 11:20:08 +0100 -Subject: [PATCH] drm/vc4: hdmi: Replace CSC_CTL hardcoded value by - defines - -On BCM2711, the HDMI_CSC_CTL register value has been hardcoded to an -opaque value. Let's replace it with properly defined values. - -Acked-by: Thomas Zimmermann -Signed-off-by: Maxime Ripard ---- - drivers/gpu/drm/vc4/vc4_hdmi.c | 5 ++--- - drivers/gpu/drm/vc4/vc4_regs.h | 3 +++ - 2 files changed, 5 insertions(+), 3 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_hdmi.c -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c -@@ -786,9 +786,8 @@ static void vc5_hdmi_csc_setup(struct vc - const struct drm_display_mode *mode) - { - unsigned long flags; -- u32 csc_ctl; -- -- csc_ctl = 0x07; /* RGB_CONVERT_MODE = custom matrix, || USE_RGB_TO_YCBCR */ -+ u32 csc_ctl = VC5_MT_CP_CSC_CTL_ENABLE | VC4_SET_FIELD(VC4_HD_CSC_CTL_MODE_CUSTOM, -+ VC5_MT_CP_CSC_CTL_MODE); - - spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); - ---- a/drivers/gpu/drm/vc4/vc4_regs.h -+++ b/drivers/gpu/drm/vc4/vc4_regs.h -@@ -810,6 +810,9 @@ enum { - # define VC4_HD_CSC_CTL_RGB2YCC BIT(1) - # define VC4_HD_CSC_CTL_ENABLE BIT(0) - -+# define VC5_MT_CP_CSC_CTL_ENABLE BIT(2) -+# define VC5_MT_CP_CSC_CTL_MODE_MASK VC4_MASK(1, 0) -+ - # define VC4_DVP_HT_CLOCK_STOP_PIXEL BIT(1) - - /* HVS display list information. */ diff --git a/target/linux/bcm27xx/patches-5.15/950-0628-drm-vc4-hdmi-Define-colorspace-matrices.patch b/target/linux/bcm27xx/patches-5.15/950-0628-drm-vc4-hdmi-Define-colorspace-matrices.patch deleted file mode 100644 index 20c8b9874..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0628-drm-vc4-hdmi-Define-colorspace-matrices.patch +++ /dev/null @@ -1,115 +0,0 @@ -From cbb71ade28d28e5fcb04171b6be283b150796e7a Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Wed, 13 Jan 2021 11:30:21 +0100 -Subject: [PATCH] drm/vc4: hdmi: Define colorspace matrices - -The current CSC setup code for the BCM2711 uses a sequence of register -writes to configure the CSC depending on whether we output using a full -or limited range. - -However, with the upcoming introduction of the YUV output, we're going -to add new matrices to perform the conversions, so we should switch to -something a bit more flexible that takes the matrix as an argument and -programs the CSC accordingly. - -Acked-by: Thomas Zimmermann -Signed-off-by: Maxime Ripard ---- - drivers/gpu/drm/vc4/vc4_hdmi.c | 79 +++++++++++++++++++++------------- - 1 file changed, 50 insertions(+), 29 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_hdmi.c -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c -@@ -782,6 +782,52 @@ static void vc4_hdmi_csc_setup(struct vc - spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); - } - -+ -+/* -+ * If we need to output Full Range RGB, then use the unity matrix -+ * -+ * [ 1 0 0 0] -+ * [ 0 1 0 0] -+ * [ 0 0 1 0] -+ * -+ * Matrix is signed 2p13 fixed point, with signed 9p6 offsets -+ */ -+static const u16 vc5_hdmi_csc_full_rgb_unity[3][4] = { -+ { 0x2000, 0x0000, 0x0000, 0x0000 }, -+ { 0x0000, 0x2000, 0x0000, 0x0000 }, -+ { 0x0000, 0x0000, 0x2000, 0x0000 }, -+}; -+ -+/* -+ * CEA VICs other than #1 require limited range RGB output unless -+ * overridden by an AVI infoframe. Apply a colorspace conversion to -+ * squash 0-255 down to 16-235. The matrix here is: -+ * -+ * [ 0.8594 0 0 16] -+ * [ 0 0.8594 0 16] -+ * [ 0 0 0.8594 16] -+ * -+ * Matrix is signed 2p13 fixed point, with signed 9p6 offsets -+ */ -+static const u16 vc5_hdmi_csc_full_rgb_to_limited_rgb[3][4] = { -+ { 0x1b80, 0x0000, 0x0000, 0x0400 }, -+ { 0x0000, 0x1b80, 0x0000, 0x0400 }, -+ { 0x0000, 0x0000, 0x1b80, 0x0400 }, -+}; -+ -+static void vc5_hdmi_set_csc_coeffs(struct vc4_hdmi *vc4_hdmi, -+ const u16 coeffs[3][4]) -+{ -+ lockdep_assert_held(&vc4_hdmi->hw_lock); -+ -+ HDMI_WRITE(HDMI_CSC_12_11, (coeffs[0][1] << 16) | coeffs[0][0]); -+ HDMI_WRITE(HDMI_CSC_14_13, (coeffs[0][3] << 16) | coeffs[0][2]); -+ HDMI_WRITE(HDMI_CSC_22_21, (coeffs[1][1] << 16) | coeffs[1][0]); -+ HDMI_WRITE(HDMI_CSC_24_23, (coeffs[1][3] << 16) | coeffs[1][2]); -+ HDMI_WRITE(HDMI_CSC_32_31, (coeffs[2][1] << 16) | coeffs[2][0]); -+ HDMI_WRITE(HDMI_CSC_34_33, (coeffs[2][3] << 16) | coeffs[2][2]); -+} -+ - static void vc5_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, - const struct drm_display_mode *mode) - { -@@ -793,35 +839,10 @@ static void vc5_hdmi_csc_setup(struct vc - - HDMI_WRITE(HDMI_VEC_INTERFACE_XBAR, 0x354021); - -- if (!vc4_hdmi_is_full_range_rgb(vc4_hdmi, mode)) { -- /* CEA VICs other than #1 requre limited range RGB -- * output unless overridden by an AVI infoframe. -- * Apply a colorspace conversion to squash 0-255 down -- * to 16-235. The matrix here is: -- * -- * [ 0.8594 0 0 16] -- * [ 0 0.8594 0 16] -- * [ 0 0 0.8594 16] -- * [ 0 0 0 1] -- * Matrix is signed 2p13 fixed point, with signed 9p6 offsets -- */ -- HDMI_WRITE(HDMI_CSC_12_11, (0x0000 << 16) | 0x1b80); -- HDMI_WRITE(HDMI_CSC_14_13, (0x0400 << 16) | 0x0000); -- HDMI_WRITE(HDMI_CSC_22_21, (0x1b80 << 16) | 0x0000); -- HDMI_WRITE(HDMI_CSC_24_23, (0x0400 << 16) | 0x0000); -- HDMI_WRITE(HDMI_CSC_32_31, (0x0000 << 16) | 0x0000); -- HDMI_WRITE(HDMI_CSC_34_33, (0x0400 << 16) | 0x1b80); -- } else { -- /* Still use the matrix for full range, but make it unity. -- * Matrix is signed 2p13 fixed point, with signed 9p6 offsets -- */ -- HDMI_WRITE(HDMI_CSC_12_11, (0x0000 << 16) | 0x2000); -- HDMI_WRITE(HDMI_CSC_14_13, (0x0000 << 16) | 0x0000); -- HDMI_WRITE(HDMI_CSC_22_21, (0x2000 << 16) | 0x0000); -- HDMI_WRITE(HDMI_CSC_24_23, (0x0000 << 16) | 0x0000); -- HDMI_WRITE(HDMI_CSC_32_31, (0x0000 << 16) | 0x0000); -- HDMI_WRITE(HDMI_CSC_34_33, (0x0000 << 16) | 0x2000); -- } -+ if (!vc4_hdmi_is_full_range_rgb(vc4_hdmi, mode)) -+ vc5_hdmi_set_csc_coeffs(vc4_hdmi, vc5_hdmi_csc_full_rgb_to_limited_rgb); -+ else -+ vc5_hdmi_set_csc_coeffs(vc4_hdmi, vc5_hdmi_csc_full_rgb_unity); - - HDMI_WRITE(HDMI_CSC_CTL, csc_ctl); - diff --git a/target/linux/bcm27xx/patches-5.15/950-0629-drm-vc4-hdmi-Change-CSC-callback-prototype.patch b/target/linux/bcm27xx/patches-5.15/950-0629-drm-vc4-hdmi-Change-CSC-callback-prototype.patch deleted file mode 100644 index 5a1328fa5..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0629-drm-vc4-hdmi-Change-CSC-callback-prototype.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 8c8b3c5a94eb8b5f6a2b0c0c20a25643842646f7 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Mon, 18 Jan 2021 09:51:12 +0100 -Subject: [PATCH] drm/vc4: hdmi: Change CSC callback prototype - -In order to support the YUV output, we'll need the atomic state to know -what is the state of the associated property in the CSC setup callback. - -Let's change the prototype of that callback to allow us to access it. - -Acked-by: Thomas Zimmermann -Signed-off-by: Maxime Ripard ---- - drivers/gpu/drm/vc4/vc4_hdmi.c | 7 ++++++- - drivers/gpu/drm/vc4/vc4_hdmi.h | 1 + - 2 files changed, 7 insertions(+), 1 deletion(-) - ---- a/drivers/gpu/drm/vc4/vc4_hdmi.c -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c -@@ -742,6 +742,7 @@ static void vc4_hdmi_encoder_post_crtc_p - } - - static void vc4_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, -+ struct drm_connector_state *state, - const struct drm_display_mode *mode) - { - unsigned long flags; -@@ -829,6 +830,7 @@ static void vc5_hdmi_set_csc_coeffs(stru - } - - static void vc5_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, -+ struct drm_connector_state *state, - const struct drm_display_mode *mode) - { - unsigned long flags; -@@ -1142,13 +1144,16 @@ static void vc4_hdmi_encoder_pre_crtc_en - struct drm_atomic_state *state) - { - struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); -+ struct drm_connector *connector = &vc4_hdmi->connector; - struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode; -+ struct drm_connector_state *conn_state = -+ drm_atomic_get_new_connector_state(state, connector); - unsigned long flags; - - mutex_lock(&vc4_hdmi->mutex); - - if (vc4_hdmi->variant->csc_setup) -- vc4_hdmi->variant->csc_setup(vc4_hdmi, mode); -+ vc4_hdmi->variant->csc_setup(vc4_hdmi, conn_state, mode); - - spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); - HDMI_WRITE(HDMI_FIFO_CTL, VC4_HDMI_FIFO_CTL_MASTER_SLAVE_N); ---- a/drivers/gpu/drm/vc4/vc4_hdmi.h -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.h -@@ -77,6 +77,7 @@ struct vc4_hdmi_variant { - - /* Callback to enable / disable the CSC */ - void (*csc_setup)(struct vc4_hdmi *vc4_hdmi, -+ struct drm_connector_state *state, - const struct drm_display_mode *mode); - - /* Callback to configure the video timings in the HDMI block */ diff --git a/target/linux/bcm27xx/patches-5.15/950-0630-drm-vc4-hdmi-Move-clock-validation-to-its-own-functi.patch b/target/linux/bcm27xx/patches-5.15/950-0630-drm-vc4-hdmi-Move-clock-validation-to-its-own-functi.patch deleted file mode 100644 index 539d62c3a..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0630-drm-vc4-hdmi-Move-clock-validation-to-its-own-functi.patch +++ /dev/null @@ -1,63 +0,0 @@ -From ca4627ecd3f93cd28ba3ae75af44e28224989b6a Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Thu, 2 Dec 2021 16:58:17 +0100 -Subject: [PATCH] drm/vc4: hdmi: Move clock validation to its own - function - -Our code is doing the same clock rate validation in multiple instances. -Let's create a helper to share the rate validation. - -Signed-off-by: Maxime Ripard ---- - drivers/gpu/drm/vc4/vc4_hdmi.c | 26 +++++++++++++++----------- - 1 file changed, 15 insertions(+), 11 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_hdmi.c -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c -@@ -1252,6 +1252,19 @@ static void vc4_hdmi_encoder_atomic_mode - mutex_unlock(&vc4_hdmi->mutex); - } - -+static enum drm_mode_status -+vc4_hdmi_encoder_clock_valid(const struct vc4_hdmi *vc4_hdmi, -+ unsigned long long clock) -+{ -+ if (clock > vc4_hdmi->variant->max_pixel_clock) -+ return MODE_CLOCK_HIGH; -+ -+ if (vc4_hdmi->disable_4kp60 && clock > HDMI_14_MAX_TMDS_CLK) -+ return MODE_CLOCK_HIGH; -+ -+ return MODE_OK; -+} -+ - #define WIFI_2_4GHz_CH1_MIN_FREQ 2400000000ULL - #define WIFI_2_4GHz_CH1_MAX_FREQ 2422000000ULL - -@@ -1296,10 +1309,7 @@ static int vc4_hdmi_encoder_atomic_check - if (mode->flags & DRM_MODE_FLAG_DBLCLK) - pixel_rate = pixel_rate * 2; - -- if (pixel_rate > vc4_hdmi->variant->max_pixel_clock) -- return -EINVAL; -- -- if (vc4_hdmi->disable_4kp60 && (pixel_rate > HDMI_14_MAX_TMDS_CLK)) -+ if (vc4_hdmi_encoder_clock_valid(vc4_hdmi, pixel_rate) != MODE_OK) - return -EINVAL; - - vc4_state->pixel_rate = pixel_rate; -@@ -1319,13 +1329,7 @@ vc4_hdmi_encoder_mode_valid(struct drm_e - (mode->hsync_end % 2) || (mode->htotal % 2))) - return MODE_H_ILLEGAL; - -- if ((mode->clock * 1000) > vc4_hdmi->variant->max_pixel_clock) -- return MODE_CLOCK_HIGH; -- -- if (vc4_hdmi->disable_4kp60 && vc4_hdmi_mode_needs_scrambling(mode)) -- return MODE_CLOCK_HIGH; -- -- return MODE_OK; -+ return vc4_hdmi_encoder_clock_valid(vc4_hdmi, mode->clock * 1000); - } - - static const struct drm_encoder_helper_funcs vc4_hdmi_encoder_helper_funcs = { diff --git a/target/linux/bcm27xx/patches-5.15/950-0631-drm-vc4-hdmi-Move-clock-calculation-into-its-own-fun.patch b/target/linux/bcm27xx/patches-5.15/950-0631-drm-vc4-hdmi-Move-clock-calculation-into-its-own-fun.patch deleted file mode 100644 index 04a32b239..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0631-drm-vc4-hdmi-Move-clock-calculation-into-its-own-fun.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 60b7ddb0b3c9d906a20d8a84e527ccf5a792a64b Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Thu, 2 Dec 2021 17:04:18 +0100 -Subject: [PATCH] drm/vc4: hdmi: Move clock calculation into its own - function - -The code to compute our clock rate for a given setup will be called in -multiple places in the next patches, so let's create a separate function -for it. - -Signed-off-by: Maxime Ripard ---- - drivers/gpu/drm/vc4/vc4_hdmi.c | 49 +++++++++++++++++++++++----------- - 1 file changed, 34 insertions(+), 15 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_hdmi.c -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c -@@ -1265,6 +1265,35 @@ vc4_hdmi_encoder_clock_valid(const struc - return MODE_OK; - } - -+static unsigned long long -+vc4_hdmi_encoder_compute_mode_clock(const struct drm_display_mode *mode, -+ unsigned int bpc) -+{ -+ unsigned long long clock = mode->crtc_clock * 1000; -+ -+ if (mode->flags & DRM_MODE_FLAG_DBLCLK) -+ clock = clock * 2; -+ -+ return clock * bpc / 8; -+} -+ -+static int -+vc4_hdmi_encoder_compute_clock(const struct vc4_hdmi *vc4_hdmi, -+ struct vc4_hdmi_connector_state *vc4_state, -+ const struct drm_display_mode *mode, -+ unsigned int bpc) -+{ -+ unsigned long long clock; -+ -+ clock = vc4_hdmi_encoder_compute_mode_clock(mode, bpc); -+ if (vc4_hdmi_encoder_clock_valid(vc4_hdmi, clock) != MODE_OK) -+ return -EINVAL; -+ -+ vc4_state->pixel_rate = clock; -+ -+ return 0; -+} -+ - #define WIFI_2_4GHz_CH1_MIN_FREQ 2400000000ULL - #define WIFI_2_4GHz_CH1_MAX_FREQ 2422000000ULL - -@@ -1277,6 +1306,7 @@ static int vc4_hdmi_encoder_atomic_check - struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); - unsigned long long pixel_rate = mode->clock * 1000; - unsigned long long tmds_rate; -+ int ret; - - if (vc4_hdmi->variant->unsupported_odd_h_timings && - !(mode->flags & DRM_MODE_FLAG_DBLCLK) && -@@ -1298,21 +1328,10 @@ static int vc4_hdmi_encoder_atomic_check - pixel_rate = mode->clock * 1000; - } - -- if (conn_state->max_bpc == 12) { -- pixel_rate = pixel_rate * 150; -- do_div(pixel_rate, 100); -- } else if (conn_state->max_bpc == 10) { -- pixel_rate = pixel_rate * 125; -- do_div(pixel_rate, 100); -- } -- -- if (mode->flags & DRM_MODE_FLAG_DBLCLK) -- pixel_rate = pixel_rate * 2; -- -- if (vc4_hdmi_encoder_clock_valid(vc4_hdmi, pixel_rate) != MODE_OK) -- return -EINVAL; -- -- vc4_state->pixel_rate = pixel_rate; -+ ret = vc4_hdmi_encoder_compute_clock(vc4_hdmi, vc4_state, mode, -+ conn_state->max_bpc); -+ if (ret) -+ return ret; - - return 0; - } diff --git a/target/linux/bcm27xx/patches-5.15/950-0632-drm-vc4-hdmi-Take-the-sink-maximum-TMDS-clock-into-a.patch b/target/linux/bcm27xx/patches-5.15/950-0632-drm-vc4-hdmi-Take-the-sink-maximum-TMDS-clock-into-a.patch deleted file mode 100644 index 8f999472d..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0632-drm-vc4-hdmi-Take-the-sink-maximum-TMDS-clock-into-a.patch +++ /dev/null @@ -1,40 +0,0 @@ -From e63d40712a11de18ea217c2211dfd3ae937bab7f Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Mon, 13 Dec 2021 15:33:11 +0100 -Subject: [PATCH] drm/vc4: hdmi: Take the sink maximum TMDS clock into - account - -In the function that validates that the clock isn't too high, we've only -taken our controller limitations into account so far. - -However, the sink can have a limit on the maximum TMDS clock it can deal -with too which is exposed through the EDID and the drm_display_info. - -Make sure we check it. - -Signed-off-by: Maxime Ripard ---- - drivers/gpu/drm/vc4/vc4_hdmi.c | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- a/drivers/gpu/drm/vc4/vc4_hdmi.c -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c -@@ -1256,12 +1256,18 @@ static enum drm_mode_status - vc4_hdmi_encoder_clock_valid(const struct vc4_hdmi *vc4_hdmi, - unsigned long long clock) - { -+ const struct drm_connector *connector = &vc4_hdmi->connector; -+ const struct drm_display_info *info = &connector->display_info; -+ - if (clock > vc4_hdmi->variant->max_pixel_clock) - return MODE_CLOCK_HIGH; - - if (vc4_hdmi->disable_4kp60 && clock > HDMI_14_MAX_TMDS_CLK) - return MODE_CLOCK_HIGH; - -+ if (info->max_tmds_clock && clock > (info->max_tmds_clock * 1000)) -+ return MODE_CLOCK_HIGH; -+ - return MODE_OK; - } - diff --git a/target/linux/bcm27xx/patches-5.15/950-0633-drm-vc4-hdmi-Take-bpp-into-account-for-the-scrambler.patch b/target/linux/bcm27xx/patches-5.15/950-0633-drm-vc4-hdmi-Take-bpp-into-account-for-the-scrambler.patch deleted file mode 100644 index db29d11f3..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0633-drm-vc4-hdmi-Take-bpp-into-account-for-the-scrambler.patch +++ /dev/null @@ -1,81 +0,0 @@ -From 8b7091e1795e50b559b7896b71c45df4fc83353b Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Fri, 10 Dec 2021 15:00:04 +0100 -Subject: [PATCH] drm/vc4: hdmi: Take bpp into account for the - scrambler - -The current code only base its decision for whether the scrambler must be -enabled or not on the pixel clock of the mode, but doesn't take the bits -per color into account. - -Let's leverage the new function to compute the clock rate in the -scrambler setup code. - -Signed-off-by: Maxime Ripard ---- - drivers/gpu/drm/vc4/vc4_hdmi.c | 17 +++++++++++++---- - drivers/gpu/drm/vc4/vc4_hdmi.h | 5 +++++ - 2 files changed, 18 insertions(+), 4 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_hdmi.c -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c -@@ -103,9 +103,17 @@ - - #define HDMI_14_MAX_TMDS_CLK (340 * 1000 * 1000) - --static bool vc4_hdmi_mode_needs_scrambling(const struct drm_display_mode *mode) -+ -+static unsigned long long -+vc4_hdmi_encoder_compute_mode_clock(const struct drm_display_mode *mode, -+ unsigned int bpc); -+ -+static bool vc4_hdmi_mode_needs_scrambling(const struct drm_display_mode *mode, -+ unsigned int bpc) - { -- return (mode->clock * 1000) > HDMI_14_MAX_TMDS_CLK; -+ unsigned long long clock = vc4_hdmi_encoder_compute_mode_clock(mode, bpc); -+ -+ return clock > HDMI_14_MAX_TMDS_CLK; - } - - static bool vc4_hdmi_is_full_range_rgb(struct vc4_hdmi *vc4_hdmi, -@@ -277,7 +285,7 @@ static int vc4_hdmi_connector_get_modes( - struct drm_display_mode *mode; - - list_for_each_entry(mode, &connector->probed_modes, head) { -- if (vc4_hdmi_mode_needs_scrambling(mode)) { -+ if (vc4_hdmi_mode_needs_scrambling(mode, 8)) { - drm_warn_once(drm, "The core clock cannot reach frequencies high enough to support 4k @ 60Hz."); - drm_warn_once(drm, "Please change your config.txt file to add hdmi_enable_4kp60."); - } -@@ -628,7 +636,7 @@ static void vc4_hdmi_enable_scrambling(s - if (!vc4_hdmi_supports_scrambling(encoder, mode)) - return; - -- if (!vc4_hdmi_mode_needs_scrambling(mode)) -+ if (!vc4_hdmi_mode_needs_scrambling(mode, vc4_hdmi->output_bpc)) - return; - - drm_scdc_set_high_tmds_clock_ratio(vc4_hdmi->ddc, true); -@@ -1246,6 +1254,7 @@ static void vc4_hdmi_encoder_atomic_mode - struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); - - mutex_lock(&vc4_hdmi->mutex); -+ vc4_hdmi->output_bpc = conn_state->max_bpc; - memcpy(&vc4_hdmi->saved_adjusted_mode, - &crtc_state->adjusted_mode, - sizeof(vc4_hdmi->saved_adjusted_mode)); ---- a/drivers/gpu/drm/vc4/vc4_hdmi.h -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.h -@@ -221,6 +221,11 @@ struct vc4_hdmi { - */ - bool scdc_enabled; - -+ /** -+ * @output_bpc: BPC currently being used. Protected by @mutex. -+ */ -+ unsigned int output_bpc; -+ - /* VC5 debugfs regset */ - struct debugfs_regset32 cec_regset; - struct debugfs_regset32 csc_regset; diff --git a/target/linux/bcm27xx/patches-5.15/950-0634-drm-vc4-hdmi-Always-try-to-have-the-highest-bpc.patch b/target/linux/bcm27xx/patches-5.15/950-0634-drm-vc4-hdmi-Always-try-to-have-the-highest-bpc.patch deleted file mode 100644 index 869fa1964..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0634-drm-vc4-hdmi-Always-try-to-have-the-highest-bpc.patch +++ /dev/null @@ -1,131 +0,0 @@ -From 5194c69ca3e4af8c3a6ffc77e5eb1ee0a62a6bbe Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Fri, 10 Dec 2021 15:29:56 +0100 -Subject: [PATCH] drm/vc4: hdmi: Always try to have the highest bpc - -Currently we take the max_bpc property as the bpc value and do not try -anything else. - -However, what the other drivers seem to be doing is that they would try -with the highest bpc allowed by the max_bpc property and the hardware -capabilities, test if it results in an acceptable configuration, and if -not decrease the bpc and try again. - -Let's use the same logic. - -Signed-off-by: Maxime Ripard ---- - drivers/gpu/drm/vc4/vc4_hdmi.c | 44 ++++++++++++++++++++++++++++++---- - drivers/gpu/drm/vc4/vc4_hdmi.h | 4 +++- - 2 files changed, 43 insertions(+), 5 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_hdmi.c -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c -@@ -357,6 +357,7 @@ vc4_hdmi_connector_duplicate_state(struc - return NULL; - - new_state->pixel_rate = vc4_state->pixel_rate; -+ new_state->output_bpc = vc4_state->output_bpc; - __drm_atomic_helper_connector_duplicate_state(connector, &new_state->base); - - return &new_state->base; -@@ -914,6 +915,8 @@ static void vc5_hdmi_set_timings(struct - struct drm_connector_state *state, - struct drm_display_mode *mode) - { -+ const struct vc4_hdmi_connector_state *vc4_state = -+ conn_state_to_vc4_hdmi_conn_state(state); - bool hsync_pos = mode->flags & DRM_MODE_FLAG_PHSYNC; - bool vsync_pos = mode->flags & DRM_MODE_FLAG_PVSYNC; - bool interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE; -@@ -962,7 +965,7 @@ static void vc5_hdmi_set_timings(struct - HDMI_WRITE(HDMI_VERTB0, vertb_even); - HDMI_WRITE(HDMI_VERTB1, vertb); - -- switch (state->max_bpc) { -+ switch (vc4_state->output_bpc) { - case 12: - gcp = 6; - gcp_en = true; -@@ -1252,9 +1255,11 @@ static void vc4_hdmi_encoder_atomic_mode - struct drm_connector_state *conn_state) - { - struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); -+ struct vc4_hdmi_connector_state *vc4_state = -+ conn_state_to_vc4_hdmi_conn_state(conn_state); - - mutex_lock(&vc4_hdmi->mutex); -- vc4_hdmi->output_bpc = conn_state->max_bpc; -+ vc4_hdmi->output_bpc = vc4_state->output_bpc; - memcpy(&vc4_hdmi->saved_adjusted_mode, - &crtc_state->adjusted_mode, - sizeof(vc4_hdmi->saved_adjusted_mode)); -@@ -1309,6 +1314,38 @@ vc4_hdmi_encoder_compute_clock(const str - return 0; - } - -+static int -+vc4_hdmi_encoder_compute_config(const struct vc4_hdmi *vc4_hdmi, -+ struct vc4_hdmi_connector_state *vc4_state, -+ const struct drm_display_mode *mode) -+{ -+ struct drm_connector_state *conn_state = &vc4_state->base; -+ unsigned int max_bpc = clamp_t(unsigned int, conn_state->max_bpc, 8, 12); -+ unsigned int bpc; -+ int ret; -+ -+ for (bpc = max_bpc; bpc >= 8; bpc -= 2) { -+ drm_dbg(dev, "Trying with a %d bpc output\n", bpc); -+ -+ ret = vc4_hdmi_encoder_compute_clock(vc4_hdmi, vc4_state, -+ mode, bpc); -+ if (ret) -+ continue; -+ -+ vc4_state->output_bpc = bpc; -+ -+ drm_dbg(dev, -+ "Mode %ux%u @ %uHz: Found configuration: bpc: %u, clock: %llu\n", -+ mode->hdisplay, mode->vdisplay, drm_mode_vrefresh(mode), -+ vc4_state->output_bpc, -+ vc4_state->pixel_rate); -+ -+ break; -+ } -+ -+ return ret; -+} -+ - #define WIFI_2_4GHz_CH1_MIN_FREQ 2400000000ULL - #define WIFI_2_4GHz_CH1_MAX_FREQ 2422000000ULL - -@@ -1343,8 +1380,7 @@ static int vc4_hdmi_encoder_atomic_check - pixel_rate = mode->clock * 1000; - } - -- ret = vc4_hdmi_encoder_compute_clock(vc4_hdmi, vc4_state, mode, -- conn_state->max_bpc); -+ ret = vc4_hdmi_encoder_compute_config(vc4_hdmi, vc4_state, mode); - if (ret) - return ret; - ---- a/drivers/gpu/drm/vc4/vc4_hdmi.h -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.h -@@ -222,7 +222,8 @@ struct vc4_hdmi { - bool scdc_enabled; - - /** -- * @output_bpc: BPC currently being used. Protected by @mutex. -+ * @output_bpc: Copy of @vc4_connector_state.output_bpc for use -+ * outside of KMS hooks. Protected by @mutex. - */ - unsigned int output_bpc; - -@@ -252,6 +253,7 @@ encoder_to_vc4_hdmi(struct drm_encoder * - struct vc4_hdmi_connector_state { - struct drm_connector_state base; - unsigned long long pixel_rate; -+ unsigned int output_bpc; - }; - - static inline struct vc4_hdmi_connector_state * diff --git a/target/linux/bcm27xx/patches-5.15/950-0635-drm-vc4-hdmi-Support-HDMI-YUV-output.patch b/target/linux/bcm27xx/patches-5.15/950-0635-drm-vc4-hdmi-Support-HDMI-YUV-output.patch deleted file mode 100644 index 4c92bc296..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0635-drm-vc4-hdmi-Support-HDMI-YUV-output.patch +++ /dev/null @@ -1,578 +0,0 @@ -From ef94081204ede8c11a28b3c3713c54fee6bc6fea Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Fri, 4 Dec 2020 17:12:06 +0100 -Subject: [PATCH] drm/vc4: hdmi: Support HDMI YUV output - -In addition to the RGB444 output, the BCM2711 HDMI controller supports -the YUV444 and YUV422 output formats. - -Let's add support for them in the driver, but still use RGB as the -preferred format. - -Signed-off-by: Maxime Ripard ---- - drivers/gpu/drm/vc4/vc4_hdmi.c | 289 ++++++++++++++++++++++++++-- - drivers/gpu/drm/vc4/vc4_hdmi.h | 14 ++ - drivers/gpu/drm/vc4/vc4_hdmi_regs.h | 6 + - drivers/gpu/drm/vc4/vc4_regs.h | 16 ++ - 4 files changed, 309 insertions(+), 16 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_hdmi.c -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c -@@ -103,15 +103,30 @@ - - #define HDMI_14_MAX_TMDS_CLK (340 * 1000 * 1000) - -+static const char * const output_format_str[] = { -+ [VC4_HDMI_OUTPUT_RGB] = "RGB", -+ [VC4_HDMI_OUTPUT_YUV420] = "YUV 4:2:0", -+ [VC4_HDMI_OUTPUT_YUV422] = "YUV 4:2:2", -+ [VC4_HDMI_OUTPUT_YUV444] = "YUV 4:4:4", -+}; -+ -+static const char *vc4_hdmi_output_fmt_str(enum vc4_hdmi_output_format fmt) -+{ -+ if (fmt >= ARRAY_SIZE(output_format_str)) -+ return "invalid"; -+ -+ return output_format_str[fmt]; -+} - - static unsigned long long - vc4_hdmi_encoder_compute_mode_clock(const struct drm_display_mode *mode, -- unsigned int bpc); -+ unsigned int bpc, enum vc4_hdmi_output_format fmt); - - static bool vc4_hdmi_mode_needs_scrambling(const struct drm_display_mode *mode, -- unsigned int bpc) -+ unsigned int bpc, -+ enum vc4_hdmi_output_format fmt) - { -- unsigned long long clock = vc4_hdmi_encoder_compute_mode_clock(mode, bpc); -+ unsigned long long clock = vc4_hdmi_encoder_compute_mode_clock(mode, bpc, fmt); - - return clock > HDMI_14_MAX_TMDS_CLK; - } -@@ -285,7 +300,7 @@ static int vc4_hdmi_connector_get_modes( - struct drm_display_mode *mode; - - list_for_each_entry(mode, &connector->probed_modes, head) { -- if (vc4_hdmi_mode_needs_scrambling(mode, 8)) { -+ if (vc4_hdmi_mode_needs_scrambling(mode, 8, VC4_HDMI_OUTPUT_RGB)) { - drm_warn_once(drm, "The core clock cannot reach frequencies high enough to support 4k @ 60Hz."); - drm_warn_once(drm, "Please change your config.txt file to add hdmi_enable_4kp60."); - } -@@ -342,6 +357,7 @@ static void vc4_hdmi_connector_reset(str - - new_state->base.max_bpc = 8; - new_state->base.max_requested_bpc = 8; -+ new_state->output_format = VC4_HDMI_OUTPUT_RGB; - drm_atomic_helper_connector_tv_reset(connector); - } - -@@ -358,6 +374,7 @@ vc4_hdmi_connector_duplicate_state(struc - - new_state->pixel_rate = vc4_state->pixel_rate; - new_state->output_bpc = vc4_state->output_bpc; -+ new_state->output_format = vc4_state->output_format; - __drm_atomic_helper_connector_duplicate_state(connector, &new_state->base); - - return &new_state->base; -@@ -511,11 +528,38 @@ static void vc4_hdmi_write_infoframe(str - DRM_ERROR("Failed to wait for infoframe to start: %d\n", ret); - } - -+static void vc4_hdmi_avi_infoframe_colorspace(struct hdmi_avi_infoframe *frame, -+ enum vc4_hdmi_output_format fmt) -+{ -+ switch (fmt) { -+ case VC4_HDMI_OUTPUT_RGB: -+ frame->colorspace = HDMI_COLORSPACE_RGB; -+ break; -+ -+ case VC4_HDMI_OUTPUT_YUV420: -+ frame->colorspace = HDMI_COLORSPACE_YUV420; -+ break; -+ -+ case VC4_HDMI_OUTPUT_YUV422: -+ frame->colorspace = HDMI_COLORSPACE_YUV422; -+ break; -+ -+ case VC4_HDMI_OUTPUT_YUV444: -+ frame->colorspace = HDMI_COLORSPACE_YUV444; -+ break; -+ -+ default: -+ break; -+ } -+} -+ - static void vc4_hdmi_set_avi_infoframe(struct drm_encoder *encoder) - { - struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); - struct drm_connector *connector = &vc4_hdmi->connector; - struct drm_connector_state *cstate = connector->state; -+ struct vc4_hdmi_connector_state *vc4_state = -+ conn_state_to_vc4_hdmi_conn_state(cstate); - const struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode; - union hdmi_infoframe frame; - int ret; -@@ -535,6 +579,7 @@ static void vc4_hdmi_set_avi_infoframe(s - HDMI_QUANTIZATION_RANGE_FULL : - HDMI_QUANTIZATION_RANGE_LIMITED); - drm_hdmi_avi_infoframe_colorimetry(&frame.avi, cstate); -+ vc4_hdmi_avi_infoframe_colorspace(&frame.avi, vc4_state->output_format); - drm_hdmi_avi_infoframe_bars(&frame.avi, cstate); - - vc4_hdmi_write_infoframe(encoder, &frame); -@@ -637,7 +682,9 @@ static void vc4_hdmi_enable_scrambling(s - if (!vc4_hdmi_supports_scrambling(encoder, mode)) - return; - -- if (!vc4_hdmi_mode_needs_scrambling(mode, vc4_hdmi->output_bpc)) -+ if (!vc4_hdmi_mode_needs_scrambling(mode, -+ vc4_hdmi->output_bpc, -+ vc4_hdmi->output_format)) - return; - - drm_scdc_set_high_tmds_clock_ratio(vc4_hdmi->ddc, true); -@@ -825,6 +872,38 @@ static const u16 vc5_hdmi_csc_full_rgb_t - { 0x0000, 0x0000, 0x1b80, 0x0400 }, - }; - -+/* -+ * Conversion between Full Range RGB and Full Range YUV422 using the -+ * BT.709 Colorspace -+ * -+ * [ 0.212639 0.715169 0.072192 0 ] -+ * [ -0.117208 -0.394207 0.511416 128 ] -+ * [ 0.511416 -0.464524 -0.046891 128 ] -+ * -+ * Matrix is signed 2p13 fixed point, with signed 9p6 offsets -+ */ -+static const u16 vc5_hdmi_csc_full_rgb_to_full_yuv422_bt709[3][4] = { -+ { 0x06ce, 0x16e3, 0x024f, 0x0000 }, -+ { 0xfc41, 0xf364, 0x105e, 0x2000 }, -+ { 0x105e, 0xf124, 0xfe81, 0x2000 }, -+}; -+ -+/* -+ * Conversion between Full Range RGB and Full Range YUV444 using the -+ * BT.709 Colorspace -+ * -+ * [ -0.117208 -0.394207 0.511416 128 ] -+ * [ 0.511416 -0.464524 -0.046891 128 ] -+ * [ 0.212639 0.715169 0.072192 0 ] -+ * -+ * Matrix is signed 2p13 fixed point, with signed 9p6 offsets -+ */ -+static const u16 vc5_hdmi_csc_full_rgb_to_full_yuv444_bt709[3][4] = { -+ { 0xfc41, 0xf364, 0x105e, 0x2000 }, -+ { 0x105e, 0xf124, 0xfe81, 0x2000 }, -+ { 0x06ce, 0x16e3, 0x024f, 0x0000 }, -+}; -+ - static void vc5_hdmi_set_csc_coeffs(struct vc4_hdmi *vc4_hdmi, - const u16 coeffs[3][4]) - { -@@ -842,19 +921,53 @@ static void vc5_hdmi_csc_setup(struct vc - struct drm_connector_state *state, - const struct drm_display_mode *mode) - { -+ struct vc4_hdmi_connector_state *vc4_state = -+ conn_state_to_vc4_hdmi_conn_state(state); - unsigned long flags; -+ u32 if_cfg = 0; -+ u32 if_xbar = 0x543210; -+ u32 csc_chan_ctl = 0; - u32 csc_ctl = VC5_MT_CP_CSC_CTL_ENABLE | VC4_SET_FIELD(VC4_HD_CSC_CTL_MODE_CUSTOM, - VC5_MT_CP_CSC_CTL_MODE); - - spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); - -- HDMI_WRITE(HDMI_VEC_INTERFACE_XBAR, 0x354021); -+ switch (vc4_state->output_format) { -+ case VC4_HDMI_OUTPUT_YUV444: -+ vc5_hdmi_set_csc_coeffs(vc4_hdmi, vc5_hdmi_csc_full_rgb_to_full_yuv444_bt709); -+ break; -+ -+ case VC4_HDMI_OUTPUT_YUV422: -+ csc_ctl |= VC4_SET_FIELD(VC5_MT_CP_CSC_CTL_FILTER_MODE_444_TO_422_STANDARD, -+ VC5_MT_CP_CSC_CTL_FILTER_MODE_444_TO_422) | -+ VC5_MT_CP_CSC_CTL_USE_444_TO_422 | -+ VC5_MT_CP_CSC_CTL_USE_RNG_SUPPRESSION; - -- if (!vc4_hdmi_is_full_range_rgb(vc4_hdmi, mode)) -- vc5_hdmi_set_csc_coeffs(vc4_hdmi, vc5_hdmi_csc_full_rgb_to_limited_rgb); -- else -- vc5_hdmi_set_csc_coeffs(vc4_hdmi, vc5_hdmi_csc_full_rgb_unity); -+ csc_chan_ctl |= VC4_SET_FIELD(VC5_MT_CP_CHANNEL_CTL_OUTPUT_REMAP_LEGACY_STYLE, -+ VC5_MT_CP_CHANNEL_CTL_OUTPUT_REMAP); -+ -+ if_cfg |= VC4_SET_FIELD(VC5_DVP_HT_VEC_INTERFACE_CFG_SEL_422_FORMAT_422_LEGACY, -+ VC5_DVP_HT_VEC_INTERFACE_CFG_SEL_422); -+ -+ vc5_hdmi_set_csc_coeffs(vc4_hdmi, vc5_hdmi_csc_full_rgb_to_full_yuv422_bt709); -+ break; - -+ case VC4_HDMI_OUTPUT_RGB: -+ if_xbar = 0x354021; -+ -+ if (!vc4_hdmi_is_full_range_rgb(vc4_hdmi, mode)) -+ vc5_hdmi_set_csc_coeffs(vc4_hdmi, vc5_hdmi_csc_full_rgb_to_limited_rgb); -+ else -+ vc5_hdmi_set_csc_coeffs(vc4_hdmi, vc5_hdmi_csc_full_rgb_unity); -+ break; -+ -+ default: -+ break; -+ } -+ -+ HDMI_WRITE(HDMI_VEC_INTERFACE_CFG, if_cfg); -+ HDMI_WRITE(HDMI_VEC_INTERFACE_XBAR, if_xbar); -+ HDMI_WRITE(HDMI_CSC_CHANNEL_CTL, csc_chan_ctl); - HDMI_WRITE(HDMI_CSC_CTL, csc_ctl); - - spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags); -@@ -981,6 +1094,15 @@ static void vc5_hdmi_set_timings(struct - break; - } - -+ /* -+ * YCC422 is always 36-bit and not considered deep colour so -+ * doesn't signal in GCP -+ */ -+ if (vc4_state->output_format == VC4_HDMI_OUTPUT_YUV422) { -+ gcp = 4; -+ gcp_en = false; -+ } -+ - reg = HDMI_READ(HDMI_DEEP_COLOR_CONFIG_1); - reg &= ~(VC5_HDMI_DEEP_COLOR_CONFIG_1_INIT_PACK_PHASE_MASK | - VC5_HDMI_DEEP_COLOR_CONFIG_1_COLOR_DEPTH_MASK); -@@ -1260,12 +1382,97 @@ static void vc4_hdmi_encoder_atomic_mode - - mutex_lock(&vc4_hdmi->mutex); - vc4_hdmi->output_bpc = vc4_state->output_bpc; -+ vc4_hdmi->output_format = vc4_state->output_format; - memcpy(&vc4_hdmi->saved_adjusted_mode, - &crtc_state->adjusted_mode, - sizeof(vc4_hdmi->saved_adjusted_mode)); - mutex_unlock(&vc4_hdmi->mutex); - } - -+static bool -+vc4_hdmi_sink_supports_format_bpc(const struct vc4_hdmi *vc4_hdmi, -+ const struct drm_display_info *info, -+ const struct drm_display_mode *mode, -+ unsigned int format, unsigned int bpc) -+{ -+ struct drm_device *dev = vc4_hdmi->connector.dev; -+ u8 vic = drm_match_cea_mode(mode); -+ -+ if (vic == 1 && bpc != 8) { -+ drm_dbg(dev, "VIC1 requires a bpc of 8, got %u\n", bpc); -+ return false; -+ } -+ -+ if (!info->is_hdmi && -+ (format != VC4_HDMI_OUTPUT_RGB || bpc != 8)) { -+ drm_dbg(dev, "DVI Monitors require an RGB output at 8 bpc\n"); -+ return false; -+ } -+ -+ switch (format) { -+ case VC4_HDMI_OUTPUT_RGB: -+ drm_dbg(dev, "RGB Format, checking the constraints.\n"); -+ -+ if (!(info->color_formats & DRM_COLOR_FORMAT_RGB444)) -+ return false; -+ -+ if (bpc == 10 && !(info->edid_hdmi_rgb444_dc_modes & DRM_EDID_HDMI_DC_30)) { -+ drm_dbg(dev, "10 BPC but sink doesn't support Deep Color 30.\n"); -+ return false; -+ } -+ -+ if (bpc == 12 && !(info->edid_hdmi_rgb444_dc_modes & DRM_EDID_HDMI_DC_36)) { -+ drm_dbg(dev, "12 BPC but sink doesn't support Deep Color 36.\n"); -+ return false; -+ } -+ -+ drm_dbg(dev, "RGB format supported in that configuration.\n"); -+ -+ return true; -+ -+ case VC4_HDMI_OUTPUT_YUV422: -+ drm_dbg(dev, "YUV422 format, checking the constraints.\n"); -+ -+ if (!(info->color_formats & DRM_COLOR_FORMAT_YCRCB422)) { -+ drm_dbg(dev, "Sink doesn't support YUV422.\n"); -+ return false; -+ } -+ -+ if (bpc != 12) { -+ drm_dbg(dev, "YUV422 only supports 12 bpc.\n"); -+ return false; -+ } -+ -+ drm_dbg(dev, "YUV422 format supported in that configuration.\n"); -+ -+ return true; -+ -+ case VC4_HDMI_OUTPUT_YUV444: -+ drm_dbg(dev, "YUV444 format, checking the constraints.\n"); -+ -+ if (!(info->color_formats & DRM_COLOR_FORMAT_YCRCB444)) { -+ drm_dbg(dev, "Sink doesn't support YUV444.\n"); -+ return false; -+ } -+ -+ if (bpc == 10 && !(info->edid_hdmi_rgb444_dc_modes & DRM_EDID_HDMI_DC_30)) { -+ drm_dbg(dev, "10 BPC but sink doesn't support Deep Color 30.\n"); -+ return false; -+ } -+ -+ if (bpc == 12 && !(info->edid_hdmi_rgb444_dc_modes & DRM_EDID_HDMI_DC_36)) { -+ drm_dbg(dev, "12 BPC but sink doesn't support Deep Color 36.\n"); -+ return false; -+ } -+ -+ drm_dbg(dev, "YUV444 format supported in that configuration.\n"); -+ -+ return true; -+ } -+ -+ return false; -+} -+ - static enum drm_mode_status - vc4_hdmi_encoder_clock_valid(const struct vc4_hdmi *vc4_hdmi, - unsigned long long clock) -@@ -1287,13 +1494,17 @@ vc4_hdmi_encoder_clock_valid(const struc - - static unsigned long long - vc4_hdmi_encoder_compute_mode_clock(const struct drm_display_mode *mode, -- unsigned int bpc) -+ unsigned int bpc, -+ enum vc4_hdmi_output_format fmt) - { - unsigned long long clock = mode->crtc_clock * 1000; - - if (mode->flags & DRM_MODE_FLAG_DBLCLK) - clock = clock * 2; - -+ if (fmt == VC4_HDMI_OUTPUT_YUV422) -+ bpc = 8; -+ - return clock * bpc / 8; - } - -@@ -1301,11 +1512,11 @@ static int - vc4_hdmi_encoder_compute_clock(const struct vc4_hdmi *vc4_hdmi, - struct vc4_hdmi_connector_state *vc4_state, - const struct drm_display_mode *mode, -- unsigned int bpc) -+ unsigned int bpc, unsigned int fmt) - { - unsigned long long clock; - -- clock = vc4_hdmi_encoder_compute_mode_clock(mode, bpc); -+ clock = vc4_hdmi_encoder_compute_mode_clock(mode, bpc, fmt); - if (vc4_hdmi_encoder_clock_valid(vc4_hdmi, clock) != MODE_OK) - return -EINVAL; - -@@ -1315,10 +1526,55 @@ vc4_hdmi_encoder_compute_clock(const str - } - - static int -+vc4_hdmi_encoder_compute_format(const struct vc4_hdmi *vc4_hdmi, -+ struct vc4_hdmi_connector_state *vc4_state, -+ const struct drm_display_mode *mode, -+ unsigned int bpc) -+{ -+ struct drm_device *dev = vc4_hdmi->connector.dev; -+ const struct drm_connector *connector = &vc4_hdmi->connector; -+ const struct drm_display_info *info = &connector->display_info; -+ unsigned int format; -+ -+ drm_dbg(dev, "Trying with an RGB output\n"); -+ -+ format = VC4_HDMI_OUTPUT_RGB; -+ if (vc4_hdmi_sink_supports_format_bpc(vc4_hdmi, info, mode, format, bpc)) { -+ int ret; -+ -+ ret = vc4_hdmi_encoder_compute_clock(vc4_hdmi, vc4_state, -+ mode, bpc, format); -+ if (!ret) { -+ vc4_state->output_format = format; -+ return 0; -+ } -+ } -+ -+ drm_dbg(dev, "Failed, Trying with an YUV422 output\n"); -+ -+ format = VC4_HDMI_OUTPUT_YUV422; -+ if (vc4_hdmi_sink_supports_format_bpc(vc4_hdmi, info, mode, format, bpc)) { -+ int ret; -+ -+ ret = vc4_hdmi_encoder_compute_clock(vc4_hdmi, vc4_state, -+ mode, bpc, format); -+ if (!ret) { -+ vc4_state->output_format = format; -+ return 0; -+ } -+ } -+ -+ drm_dbg(dev, "Failed. No Format Supported for that bpc count.\n"); -+ -+ return -EINVAL; -+} -+ -+static int - vc4_hdmi_encoder_compute_config(const struct vc4_hdmi *vc4_hdmi, - struct vc4_hdmi_connector_state *vc4_state, - const struct drm_display_mode *mode) - { -+ struct drm_device *dev = vc4_hdmi->connector.dev; - struct drm_connector_state *conn_state = &vc4_state->base; - unsigned int max_bpc = clamp_t(unsigned int, conn_state->max_bpc, 8, 12); - unsigned int bpc; -@@ -1327,17 +1583,18 @@ vc4_hdmi_encoder_compute_config(const st - for (bpc = max_bpc; bpc >= 8; bpc -= 2) { - drm_dbg(dev, "Trying with a %d bpc output\n", bpc); - -- ret = vc4_hdmi_encoder_compute_clock(vc4_hdmi, vc4_state, -- mode, bpc); -+ ret = vc4_hdmi_encoder_compute_format(vc4_hdmi, vc4_state, -+ mode, bpc); - if (ret) - continue; - - vc4_state->output_bpc = bpc; - - drm_dbg(dev, -- "Mode %ux%u @ %uHz: Found configuration: bpc: %u, clock: %llu\n", -+ "Mode %ux%u @ %uHz: Found configuration: bpc: %u, fmt: %s, clock: %llu\n", - mode->hdisplay, mode->vdisplay, drm_mode_vrefresh(mode), - vc4_state->output_bpc, -+ vc4_hdmi_output_fmt_str(vc4_state->output_format), - vc4_state->pixel_rate); - - break; ---- a/drivers/gpu/drm/vc4/vc4_hdmi.h -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.h -@@ -121,6 +121,13 @@ struct vc4_hdmi_audio { - bool streaming; - }; - -+enum vc4_hdmi_output_format { -+ VC4_HDMI_OUTPUT_RGB, -+ VC4_HDMI_OUTPUT_YUV422, -+ VC4_HDMI_OUTPUT_YUV444, -+ VC4_HDMI_OUTPUT_YUV420, -+}; -+ - /* General HDMI hardware state. */ - struct vc4_hdmi { - struct vc4_hdmi_audio audio; -@@ -227,6 +234,12 @@ struct vc4_hdmi { - */ - unsigned int output_bpc; - -+ /** -+ * @output_format: Copy of @vc4_connector_state.output_format -+ * for use outside of KMS hooks. Protected by @mutex. -+ */ -+ enum vc4_hdmi_output_format output_format; -+ - /* VC5 debugfs regset */ - struct debugfs_regset32 cec_regset; - struct debugfs_regset32 csc_regset; -@@ -254,6 +267,7 @@ struct vc4_hdmi_connector_state { - struct drm_connector_state base; - unsigned long long pixel_rate; - unsigned int output_bpc; -+ enum vc4_hdmi_output_format output_format; - }; - - static inline struct vc4_hdmi_connector_state * ---- a/drivers/gpu/drm/vc4/vc4_hdmi_regs.h -+++ b/drivers/gpu/drm/vc4/vc4_hdmi_regs.h -@@ -54,6 +54,7 @@ enum vc4_hdmi_field { - HDMI_CSC_24_23, - HDMI_CSC_32_31, - HDMI_CSC_34_33, -+ HDMI_CSC_CHANNEL_CTL, - HDMI_CSC_CTL, - - /* -@@ -119,6 +120,7 @@ enum vc4_hdmi_field { - HDMI_TX_PHY_POWERDOWN_CTL, - HDMI_TX_PHY_RESET_CTL, - HDMI_TX_PHY_TMDS_CLK_WORD_SEL, -+ HDMI_VEC_INTERFACE_CFG, - HDMI_VEC_INTERFACE_XBAR, - HDMI_VERTA0, - HDMI_VERTA1, -@@ -246,6 +248,7 @@ static const struct vc4_hdmi_register __ - VC4_HDMI_REG(HDMI_SCRAMBLER_CTL, 0x1c4), - - VC5_DVP_REG(HDMI_CLOCK_STOP, 0x0bc), -+ VC5_DVP_REG(HDMI_VEC_INTERFACE_CFG, 0x0ec), - VC5_DVP_REG(HDMI_VEC_INTERFACE_XBAR, 0x0f0), - - VC5_PHY_REG(HDMI_TX_PHY_RESET_CTL, 0x000), -@@ -291,6 +294,7 @@ static const struct vc4_hdmi_register __ - VC5_CSC_REG(HDMI_CSC_24_23, 0x010), - VC5_CSC_REG(HDMI_CSC_32_31, 0x014), - VC5_CSC_REG(HDMI_CSC_34_33, 0x018), -+ VC5_CSC_REG(HDMI_CSC_CHANNEL_CTL, 0x02c), - }; - - static const struct vc4_hdmi_register __maybe_unused vc5_hdmi_hdmi1_fields[] = { -@@ -327,6 +331,7 @@ static const struct vc4_hdmi_register __ - VC4_HDMI_REG(HDMI_SCRAMBLER_CTL, 0x1c4), - - VC5_DVP_REG(HDMI_CLOCK_STOP, 0x0bc), -+ VC5_DVP_REG(HDMI_VEC_INTERFACE_CFG, 0x0ec), - VC5_DVP_REG(HDMI_VEC_INTERFACE_XBAR, 0x0f0), - - VC5_PHY_REG(HDMI_TX_PHY_RESET_CTL, 0x000), -@@ -372,6 +377,7 @@ static const struct vc4_hdmi_register __ - VC5_CSC_REG(HDMI_CSC_24_23, 0x010), - VC5_CSC_REG(HDMI_CSC_32_31, 0x014), - VC5_CSC_REG(HDMI_CSC_34_33, 0x018), -+ VC5_CSC_REG(HDMI_CSC_CHANNEL_CTL, 0x02c), - }; - - static inline ---- a/drivers/gpu/drm/vc4/vc4_regs.h -+++ b/drivers/gpu/drm/vc4/vc4_regs.h -@@ -810,11 +810,27 @@ enum { - # define VC4_HD_CSC_CTL_RGB2YCC BIT(1) - # define VC4_HD_CSC_CTL_ENABLE BIT(0) - -+# define VC5_MT_CP_CSC_CTL_USE_444_TO_422 BIT(6) -+# define VC5_MT_CP_CSC_CTL_FILTER_MODE_444_TO_422_MASK \ -+ VC4_MASK(5, 4) -+# define VC5_MT_CP_CSC_CTL_FILTER_MODE_444_TO_422_STANDARD \ -+ 3 -+# define VC5_MT_CP_CSC_CTL_USE_RNG_SUPPRESSION BIT(3) - # define VC5_MT_CP_CSC_CTL_ENABLE BIT(2) - # define VC5_MT_CP_CSC_CTL_MODE_MASK VC4_MASK(1, 0) - -+# define VC5_MT_CP_CHANNEL_CTL_OUTPUT_REMAP_MASK \ -+ VC4_MASK(7, 6) -+# define VC5_MT_CP_CHANNEL_CTL_OUTPUT_REMAP_LEGACY_STYLE \ -+ 2 -+ - # define VC4_DVP_HT_CLOCK_STOP_PIXEL BIT(1) - -+# define VC5_DVP_HT_VEC_INTERFACE_CFG_SEL_422_MASK \ -+ VC4_MASK(3, 2) -+# define VC5_DVP_HT_VEC_INTERFACE_CFG_SEL_422_FORMAT_422_LEGACY \ -+ 2 -+ - /* HVS display list information. */ - #define HVS_BOOTLOADER_DLIST_END 32 - diff --git a/target/linux/bcm27xx/patches-5.15/950-0636-media-v4l2-ctrls-Add-V4L2_CID_NOTIFY_GAINS-control.patch b/target/linux/bcm27xx/patches-5.15/950-0636-media-v4l2-ctrls-Add-V4L2_CID_NOTIFY_GAINS-control.patch deleted file mode 100644 index 67546c062..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0636-media-v4l2-ctrls-Add-V4L2_CID_NOTIFY_GAINS-control.patch +++ /dev/null @@ -1,51 +0,0 @@ -From fa9c40c42f2db87e80ac4a89df6a5ecab1b98031 Mon Sep 17 00:00:00 2001 -From: David Plowman -Date: Mon, 16 Aug 2021 13:39:08 +0200 -Subject: [PATCH] media: v4l2-ctrls: Add V4L2_CID_NOTIFY_GAINS control - -commit a9c80593ff80ddb7c6496624e5384e1ea3460a72 upstream. - -We add a new control V4L2_CID_NOTIFY_GAINS which allows the sensor to -be notified what gains will be applied to the different colour -channels by subsequent processing (such as by an ISP), even though the -sensor will not apply any of these gains itself. - -For Bayer sensors this will be an array control taking 4 values which -are the 4 gains arranged in the fixed order B, Gb, Gr and R, -irrespective of the exact Bayer order of the sensor itself. The use of -an array makes it straightforward to extend this control to non-Bayer -sensors (for example, sensors with an RGBW pattern) in future. - -The units are in all cases linear with the default value indicating a -gain of exactly 1.0. For example, if the default value were reported as -128 then the value 192 would represent a gain of exactly 1.5. - -Signed-off-by: David Plowman -Reviewed-by: Laurent Pinchart -Signed-off-by: Sakari Ailus -Signed-off-by: Mauro Carvalho Chehab ---- - drivers/media/v4l2-core/v4l2-ctrls-defs.c | 1 + - include/uapi/linux/v4l2-controls.h | 1 + - 2 files changed, 2 insertions(+) - ---- a/drivers/media/v4l2-core/v4l2-ctrls-defs.c -+++ b/drivers/media/v4l2-core/v4l2-ctrls-defs.c -@@ -1109,6 +1109,7 @@ const char *v4l2_ctrl_get_name(u32 id) - case V4L2_CID_TEST_PATTERN_GREENR: return "Green (Red) Pixel Value"; - case V4L2_CID_TEST_PATTERN_BLUE: return "Blue Pixel Value"; - case V4L2_CID_TEST_PATTERN_GREENB: return "Green (Blue) Pixel Value"; -+ case V4L2_CID_NOTIFY_GAINS: return "Notify Gains"; - - /* Image processing controls */ - /* Keep the order of the 'case's the same as in v4l2-controls.h! */ ---- a/include/uapi/linux/v4l2-controls.h -+++ b/include/uapi/linux/v4l2-controls.h -@@ -1123,6 +1123,7 @@ enum v4l2_jpeg_chroma_subsampling { - #define V4L2_CID_TEST_PATTERN_BLUE (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 6) - #define V4L2_CID_TEST_PATTERN_GREENB (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 7) - #define V4L2_CID_UNIT_CELL_SIZE (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 8) -+#define V4L2_CID_NOTIFY_GAINS (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 9) - - - /* Image processing controls */ diff --git a/target/linux/bcm27xx/patches-5.15/950-0637-media-v4l2-ctrls-Document-V4L2_CID_NOTIFY_GAINS-cont.patch b/target/linux/bcm27xx/patches-5.15/950-0637-media-v4l2-ctrls-Document-V4L2_CID_NOTIFY_GAINS-cont.patch deleted file mode 100644 index 55a2a4ef2..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0637-media-v4l2-ctrls-Document-V4L2_CID_NOTIFY_GAINS-cont.patch +++ /dev/null @@ -1,48 +0,0 @@ -From dd91fe58de578570d49fe644eb05398a27510478 Mon Sep 17 00:00:00 2001 -From: David Plowman -Date: Mon, 16 Aug 2021 13:39:09 +0200 -Subject: [PATCH] media: v4l2-ctrls: Document V4L2_CID_NOTIFY_GAINS - control - -commit 311a839a1ad255ebcb7291fb4e0d2ec2f32312a7 upstream. - -Add documentation for the V4L2_CID_NOTIFY_GAINS control. - -This control is required by sensors that need to know what colour -gains will be applied to pixels by downstream processing (such as by -an ISP), though the sensor does not apply these gains itself. - -Signed-off-by: David Plowman -Reviewed-by: Laurent Pinchart -Signed-off-by: Sakari Ailus -Signed-off-by: Mauro Carvalho Chehab ---- - .../media/v4l/ext-ctrls-image-source.rst | 20 +++++++++++++++++++ - 1 file changed, 20 insertions(+) - ---- a/Documentation/userspace-api/media/v4l/ext-ctrls-image-source.rst -+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-image-source.rst -@@ -72,3 +72,23 @@ Image Source Control IDs - * - __u32 - - ``height`` - - Height of the area. -+ -+``V4L2_CID_NOTIFY_GAINS (integer array)`` -+ The sensor is notified what gains will be applied to the different -+ colour channels by subsequent processing (such as by an ISP). The -+ sensor is merely informed of these values in case it performs -+ processing that requires them, but it does not apply them itself to -+ the output pixels. -+ -+ Currently it is defined only for Bayer sensors, and is an array -+ control taking 4 gain values, being the gains for each of the -+ Bayer channels. The gains are always in the order B, Gb, Gr and R, -+ irrespective of the exact Bayer order of the sensor itself. -+ -+ The use of an array allows this control to be extended to sensors -+ with, for example, non-Bayer CFAs (colour filter arrays). -+ -+ The units for the gain values are linear, with the default value -+ representing a gain of exactly 1.0. For example, if this default value -+ is reported as being (say) 128, then a value of 192 would represent -+ a gain of exactly 1.5. diff --git a/target/linux/bcm27xx/patches-5.15/950-0639-Add-panel-overlay-for-CutiePi.patch b/target/linux/bcm27xx/patches-5.15/950-0639-Add-panel-overlay-for-CutiePi.patch deleted file mode 100644 index 9f5b74d40..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0639-Add-panel-overlay-for-CutiePi.patch +++ /dev/null @@ -1,172 +0,0 @@ -From dabd32c62cb2faa42feacafc6edbe8ab4b3395cb Mon Sep 17 00:00:00 2001 -From: Penk Chen -Date: Mon, 20 Dec 2021 03:46:26 +0900 -Subject: [PATCH] Add panel overlay for CutiePi - -Signed-off-by: Penk Chen ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 6 + - .../dts/overlays/cutiepi-panel-overlay.dts | 117 ++++++++++++++++++ - arch/arm/boot/dts/overlays/overlay_map.dts | 4 + - 4 files changed, 128 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/cutiepi-panel-overlay.dts - ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -34,6 +34,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ - cap1106.dtbo \ - chipdip-dac.dtbo \ - cma.dtbo \ -+ cutiepi-panel.dtbo \ - dht11.dtbo \ - dionaudio-loco.dtbo \ - dionaudio-loco-v2.dtbo \ ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -679,6 +679,12 @@ Params: cma-512 CMA is 5 - cma-default Use upstream's default value - - -+Name: cutiepi-panel -+Info: 8" TFT LCD display and touch panel used by cutiepi.io -+Load: dtoverlay=cutiepi-panel -+Params: -+ -+ - Name: dht11 - Info: Overlay for the DHT11/DHT21/DHT22 humidity/temperature sensors - Also sometimes found with the part number(s) AM230x. ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/cutiepi-panel-overlay.dts -@@ -0,0 +1,117 @@ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2711"; -+ -+ fragment@0 { -+ target=<&dsi1>; -+ -+ __overlay__ { -+ status = "okay"; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ port { -+ dsi1_out_port: endpoint { -+ remote-endpoint = <&panel_dsi_in1>; -+ }; -+ }; -+ -+ display1: panel@0 { -+ compatible = "nwe,nwe080"; -+ reg=<0>; -+ backlight = <&rpi_backlight>; -+ reset-gpios = <&gpio 20 0>; -+ port { -+ panel_dsi_in1: endpoint { -+ remote-endpoint = <&dsi1_out_port>; -+ }; -+ }; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ pwm_pins: pwm_pins { -+ brcm,pins = <12>; -+ brcm,function = <4>; // ALT0 -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&pwm>; -+ frag1: __overlay__ { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pwm_pins>; -+ assigned-clock-rates = <1000000>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@3 { -+ target-path = "/"; -+ __overlay__ { -+ rpi_backlight: rpi_backlight { -+ compatible = "pwm-backlight"; -+ brightness-levels = <0 6 8 12 16 24 32 40 48 64 96 128 160 192 224 255>; -+ default-brightness-level = <6>; -+ pwms = <&pwm 0 200000>; -+ power-supply = <&vdd_3v3_reg>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ fragment@4 { -+ target = <&i2c6>; -+ frag0: __overlay__ { -+ status = "okay"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c6_pins>; -+ clock-frequency = <100000>; -+ }; -+ }; -+ -+ fragment@5 { -+ target = <&i2c6_pins>; -+ __overlay__ { -+ brcm,pins = <22 23>; -+ }; -+ }; -+ -+ fragment@6 { -+ target = <&gpio>; -+ __overlay__ { -+ goodix_pins: goodix_pins { -+ brcm,pins = <21 26>; // interrupt and reset -+ brcm,function = <0 0>; // in -+ brcm,pull = <2 2>; // pull-up -+ }; -+ }; -+ }; -+ -+ fragment@7 { -+ target = <&i2c6>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ gt9xx: gt9xx@5d { -+ compatible = "goodix,gt9271"; -+ reg = <0x5D>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&goodix_pins>; -+ interrupt-parent = <&gpio>; -+ interrupts = <21 2>; // high-to-low edge triggered -+ irq-gpios = <&gpio 21 0>; -+ reset-gpios = <&gpio 26 0>; -+ }; -+ }; -+ }; -+}; ---- a/arch/arm/boot/dts/overlays/overlay_map.dts -+++ b/arch/arm/boot/dts/overlays/overlay_map.dts -@@ -5,6 +5,10 @@ - deprecated = "use i2c-sensor,bmp085"; - }; - -+ cutiepi-panel { -+ bcm2711; -+ }; -+ - highperi { - bcm2711; - }; diff --git a/target/linux/bcm27xx/patches-5.15/950-0640-dtoverlays-Enable-cam1_clock-when-using-tc358743-or-.patch b/target/linux/bcm27xx/patches-5.15/950-0640-dtoverlays-Enable-cam1_clock-when-using-tc358743-or-.patch deleted file mode 100644 index 00f8c9608..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0640-dtoverlays-Enable-cam1_clock-when-using-tc358743-or-.patch +++ /dev/null @@ -1,42 +0,0 @@ -From bf29731068a77344efdf241a7a932ffdd3e8f931 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Jakub=20Van=C4=9Bk?= -Date: Tue, 28 Dec 2021 15:43:10 +0100 -Subject: [PATCH] dtoverlays: Enable cam1_clock when using tc358743 or - irs1125 - -This fixes a regression introduced in 131f1322039284932ccb601a5cffdd9ca5d36d96 -(see also https://github.com/raspberrypi/linux/issues/4791). -The tc358743 driver refused to bind to the device. The irs1125 -driver is likely behaving similarly. - -The new unified cam1_clk node that represents the fixed on-board -oscillator is marked as disabled by default. These overlays didn't -expect this and so the clock nodes were stuck in disabled state. - -This commit just adds the required status = "okay" line. Other sensor -drivers do this too. ---- - arch/arm/boot/dts/overlays/irs1125-overlay.dts | 1 + - arch/arm/boot/dts/overlays/tc358743-overlay.dts | 1 + - 2 files changed, 2 insertions(+) - ---- a/arch/arm/boot/dts/overlays/irs1125-overlay.dts -+++ b/arch/arm/boot/dts/overlays/irs1125-overlay.dts -@@ -75,6 +75,7 @@ - clk_frag: fragment@5 { - target = <&cam1_clk>; - __overlay__ { -+ status = "okay"; - clock-frequency = <26000000>; - }; - }; ---- a/arch/arm/boot/dts/overlays/tc358743-overlay.dts -+++ b/arch/arm/boot/dts/overlays/tc358743-overlay.dts -@@ -78,6 +78,7 @@ - clk_frag: fragment@6 { - target = <&cam1_clk>; - __overlay__ { -+ status = "okay"; - clock-frequency = <27000000>; - }; - }; diff --git a/target/linux/bcm27xx/patches-5.15/950-0642-drm-vc4-hdmi-Fix-HDMI-monitor-detection-in-polled-mo.patch b/target/linux/bcm27xx/patches-5.15/950-0642-drm-vc4-hdmi-Fix-HDMI-monitor-detection-in-polled-mo.patch deleted file mode 100644 index 8fb8fe803..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0642-drm-vc4-hdmi-Fix-HDMI-monitor-detection-in-polled-mo.patch +++ /dev/null @@ -1,46 +0,0 @@ -From a1bf3abe0c1093e81e5dd59b6d3b09b9ebb3a17d Mon Sep 17 00:00:00 2001 -From: Matthias Reichl -Date: Thu, 30 Dec 2021 14:28:37 +0100 -Subject: [PATCH] drm/vc4: hdmi: Fix HDMI monitor detection in polled - mode - -When vc4_hdmi_connector_detect() was called in -connector_status_connected state it incorrectly cleared the -hdmi_monitor flag, leading to no audio on RPi3. - -Fix this by clearing hdmi_monitor only when the hpd check -indicated no connection or if reading the edid failed. - -Signed-off-by: Matthias Reichl ---- - drivers/gpu/drm/vc4/vc4_hdmi.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - ---- a/drivers/gpu/drm/vc4/vc4_hdmi.c -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c -@@ -243,7 +243,6 @@ vc4_hdmi_connector_detect(struct drm_con - connected = true; - } - -- vc4_hdmi->encoder.hdmi_monitor = false; - if (connected) { - if (connector->status != connector_status_connected) { - struct edid *edid = drm_get_edid(connector, vc4_hdmi->ddc); -@@ -252,6 +251,8 @@ vc4_hdmi_connector_detect(struct drm_con - cec_s_phys_addr_from_edid(vc4_hdmi->cec_adap, edid); - vc4_hdmi->encoder.hdmi_monitor = drm_detect_hdmi_monitor(edid); - kfree(edid); -+ } else { -+ vc4_hdmi->encoder.hdmi_monitor = false; - } - } - -@@ -261,6 +262,8 @@ vc4_hdmi_connector_detect(struct drm_con - return connector_status_connected; - } - -+ vc4_hdmi->encoder.hdmi_monitor = false; -+ - cec_phys_addr_invalidate(vc4_hdmi->cec_adap); - pm_runtime_put(&vc4_hdmi->pdev->dev); - mutex_unlock(&vc4_hdmi->mutex); diff --git a/target/linux/bcm27xx/patches-5.15/950-0643-drm-vc4-hdmi-Fix-no-video-output-on-DVI-monitors.patch b/target/linux/bcm27xx/patches-5.15/950-0643-drm-vc4-hdmi-Fix-no-video-output-on-DVI-monitors.patch deleted file mode 100644 index 644ea123d..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0643-drm-vc4-hdmi-Fix-no-video-output-on-DVI-monitors.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 64c3b233b38af0817c70d142c65b915ca1fbc71a Mon Sep 17 00:00:00 2001 -From: Matthias Reichl -Date: Thu, 30 Dec 2021 15:12:19 +0100 -Subject: [PATCH] drm/vc4: hdmi: Fix no video output on DVI monitors - -The drm edid parser doesn't signal RGB support on DVI monitors -with old edid versions, leading to 8-bit RGB mode being rejected -and no video on DVI monitors. - -As 8-bit RGB is mandatory on HDMI and DVI monitors anyways we can -simply drop the RGB format check, aligning vc4 with other drivers. - -Signed-off-by: Matthias Reichl ---- - drivers/gpu/drm/vc4/vc4_hdmi.c | 3 --- - 1 file changed, 3 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_hdmi.c -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c -@@ -1416,9 +1416,6 @@ vc4_hdmi_sink_supports_format_bpc(const - case VC4_HDMI_OUTPUT_RGB: - drm_dbg(dev, "RGB Format, checking the constraints.\n"); - -- if (!(info->color_formats & DRM_COLOR_FORMAT_RGB444)) -- return false; -- - if (bpc == 10 && !(info->edid_hdmi_rgb444_dc_modes & DRM_EDID_HDMI_DC_30)) { - drm_dbg(dev, "10 BPC but sink doesn't support Deep Color 30.\n"); - return false; diff --git a/target/linux/bcm27xx/patches-5.15/950-0644-staging-bcm2835-codec-Fix-typo.patch b/target/linux/bcm27xx/patches-5.15/950-0644-staging-bcm2835-codec-Fix-typo.patch deleted file mode 100644 index 7092e238f..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0644-staging-bcm2835-codec-Fix-typo.patch +++ /dev/null @@ -1,21 +0,0 @@ -From 7b9206228eaaa5b917d5c8be383cec0ddef99f90 Mon Sep 17 00:00:00 2001 -From: Andriy Gelman -Date: Sun, 2 Jan 2022 12:22:52 -0500 -Subject: [PATCH] staging/bcm2835-codec: Fix typo - -Signed-off-by: Andriy Gelman ---- - .../staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -1563,7 +1563,7 @@ static int vidioc_s_fmt(struct bcm2835_c - q_data->bytesperline = f->fmt.pix_mp.plane_fmt[0].bytesperline; - q_data->sizeimage = f->fmt.pix_mp.plane_fmt[0].sizeimage; - -- v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "Calulated bpl as %u, size %u\n", -+ v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "Calculated bpl as %u, size %u\n", - q_data->bytesperline, q_data->sizeimage); - - if (ctx->dev->role == DECODE && diff --git a/target/linux/bcm27xx/patches-5.15/950-0646-Use-GitHubs-issue-form-for-bug-reports.patch b/target/linux/bcm27xx/patches-5.15/950-0646-Use-GitHubs-issue-form-for-bug-reports.patch deleted file mode 100644 index ebdd13639..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0646-Use-GitHubs-issue-form-for-bug-reports.patch +++ /dev/null @@ -1,163 +0,0 @@ -From 51fe0fbf8d49a8d832795b8a12f0c2f83d290aab Mon Sep 17 00:00:00 2001 -From: Andreas Blaesius -Date: Wed, 5 Jan 2022 20:38:39 +0100 -Subject: [PATCH] Use GitHubs issue form for bug reports - -Use GitHubs issue form for bug reports. - -- modern look -- user don't need to mess with given markdown parts while filling the issue template - -Setup config.yml for general questions and problems with the Raspbian distribution packages. ---- - .github/ISSUE_TEMPLATE/bug_report.md | 34 ---------- - .github/ISSUE_TEMPLATE/bug_report.yml | 91 +++++++++++++++++++++++++++ - .github/ISSUE_TEMPLATE/config.yml | 9 +++ - 3 files changed, 100 insertions(+), 34 deletions(-) - delete mode 100644 .github/ISSUE_TEMPLATE/bug_report.md - create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yml - create mode 100644 .github/ISSUE_TEMPLATE/config.yml - ---- a/.github/ISSUE_TEMPLATE/bug_report.md -+++ /dev/null -@@ -1,34 +0,0 @@ ----- --name: Bug report --about: Create a report to help us fix your issue -- ----- -- --**Is this the right place for my bug report?** --This repository contains the Linux kernel used on the Raspberry Pi. If you believe that the issue you are seeing is kernel-related, this is the right place. If not, we have other repositories for the GPU firmware at [github.com/raspberrypi/firmware](https://github.com/raspberrypi/firmware) and Raspberry Pi userland applications at [github.com/raspberrypi/userland](https://github.com/raspberrypi/userland). If you have problems with the Raspbian distribution packages, report them in the [github.com/RPi-Distro/repo](https://github.com/RPi-Distro/repo). If you simply have a question, then [the Raspberry Pi forums](https://www.raspberrypi.org/forums) are the best place to ask it. -- --**Describe the bug** --Add a clear and concise description of what you think the bug is. -- --**To reproduce** --List the steps required to reproduce the issue. -- --**Expected behaviour** --Add a clear and concise description of what you expected to happen. -- --**Actual behaviour** --Add a clear and concise description of what actually happened. -- --**System** -- Copy and paste the results of the raspinfo command in to this section. Alternatively, copy and paste a pastebin link, or add answers to the following questions: -- --* Which model of Raspberry Pi? e.g. Pi3B+, PiZeroW --* Which OS and version (`cat /etc/rpi-issue`)? --* Which firmware version (`vcgencmd version`)? --* Which kernel version (`uname -a`)? -- --**Logs** --If applicable, add the relevant output from `dmesg` or similar. -- --**Additional context** --Add any other relevant context for the problem. ---- /dev/null -+++ b/.github/ISSUE_TEMPLATE/bug_report.yml -@@ -0,0 +1,91 @@ -+name: "Bug report" -+description: Create a report to help us fix your issue -+body: -+- type: markdown -+ attributes: -+ value: | -+ **Is this the right place for my bug report?** -+ This repository contains the Linux kernel used on the Raspberry Pi. -+ If you believe that the issue you are seeing is kernel-related, this is the right place. -+ If not, we have other repositories for the GPU firmware at [github.com/raspberrypi/firmware](https://github.com/raspberrypi/firmware) and Raspberry Pi userland applications at [github.com/raspberrypi/userland](https://github.com/raspberrypi/userland). -+ -+ If you have problems with the Raspbian distribution packages, report them in the [github.com/RPi-Distro/repo](https://github.com/RPi-Distro/repo). -+ If you simply have a question, then [the Raspberry Pi forums](https://www.raspberrypi.org/forums) are the best place to ask it. -+ -+- type: textarea -+ id: description -+ attributes: -+ label: Describe the bug -+ description: | -+ Add a clear and concise description of what you think the bug is. -+ validations: -+ required: true -+ -+- type: textarea -+ id: reproduce -+ attributes: -+ label: Steps to reproduce the behaviour -+ description: | -+ List the steps required to reproduce the issue. -+ validations: -+ required: true -+ -+- type: dropdown -+ id: model -+ attributes: -+ label: Device (s) -+ description: On which device you are facing the bug? -+ multiple: true -+ options: -+ - Raspberry Pi Zero -+ - Raspberry Pi Zero W / WH -+ - Raspberry Pi Zero 2 W -+ - Raspberry Pi 1 Mod. A -+ - Raspberry Pi 1 Mod. A+ -+ - Raspberry Pi 1 Mod. B -+ - Raspberry Pi 1 Mod. B+ -+ - Raspberry Pi 2 Mod. B -+ - Raspberry Pi 2 Mod. B v1.2 -+ - Raspberry Pi 3 Mod. A+ -+ - Raspberry Pi 3 Mod. B -+ - Raspberry Pi 3 Mod. B+ -+ - Raspberry Pi 4 Mod. B -+ - Raspberry Pi 400 -+ - Raspberry Pi CM1 -+ - Raspberry Pi CM3 -+ - Raspberry Pi CM3 Lite -+ - Raspberry Pi CM3+ -+ - Raspberry Pi CM3+ Lite -+ - Raspberry Pi CM4 -+ - Raspberry Pi CM4 Lite -+ - Other -+ validations: -+ required: true -+ -+- type: textarea -+ id: system -+ attributes: -+ label: System -+ description: | -+ Copy and paste the results of the raspinfo command in to this section. -+ Alternatively, copy and paste a pastebin link, or add answers to the following questions: -+ * Which OS and version (`cat /etc/rpi-issue`)? -+ * Which firmware version (`vcgencmd version`)? -+ * Which kernel version (`uname -a`)? -+ validations: -+ required: true -+ -+- type: textarea -+ id: logs -+ attributes: -+ label: Logs -+ description: | -+ If applicable, add the relevant output from `dmesg` or similar. -+ -+- type: textarea -+ id: additional -+ attributes: -+ label: Additional context -+ description: | -+ Add any other relevant context for the problem. -+ ---- /dev/null -+++ b/.github/ISSUE_TEMPLATE/config.yml -@@ -0,0 +1,9 @@ -+blank_issues_enabled: false -+contact_links: -+ - name: "⛔ Question" -+ url: https://www.raspberrypi.org/forums -+ about: "Please do not use GitHub for asking questions. If you simply have a question, then the Raspberry Pi forums are the best place to ask it. Thanks in advance for helping us keep the issue tracker clean!" -+ - name: "⛔ Problems with the Raspbian distribution packages" -+ url: https://github.com/RPi-Distro/repo -+ about: "If you have problems with the Raspbian distribution packages, please report them in the github.com/RPi-Distro/repo." -+ diff --git a/target/linux/bcm27xx/patches-5.15/950-0648-overlays-Add-overlay-for-Azoteq-IQS550.patch b/target/linux/bcm27xx/patches-5.15/950-0648-overlays-Add-overlay-for-Azoteq-IQS550.patch deleted file mode 100644 index 3f5c5642c..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0648-overlays-Add-overlay-for-Azoteq-IQS550.patch +++ /dev/null @@ -1,97 +0,0 @@ -From 7c9c2e970b0a047ae2a747752fdd12e31dbb2451 Mon Sep 17 00:00:00 2001 -From: Jeff LaBundy -Date: Mon, 28 Jan 2019 23:11:47 -0600 -Subject: [PATCH] overlays: Add overlay for Azoteq IQS550 - -This patch adds a device tree overlay for the Azoteq IQS550 -trackpad/touchscreen controller. - -Signed-off-by: Jeff LaBundy ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 13 ++++++ - arch/arm/boot/dts/overlays/iqs550-overlay.dts | 46 +++++++++++++++++++ - 3 files changed, 60 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/iqs550-overlay.dts - ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -106,6 +106,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ - iqaudio-dac.dtbo \ - iqaudio-dacplus.dtbo \ - iqaudio-digi-wm8804-audio.dtbo \ -+ iqs550.dtbo \ - irs1125.dtbo \ - jedec-spi-nor.dtbo \ - justboom-both.dtbo \ ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -1991,6 +1991,19 @@ Params: card_name Override - dai stream name. - - -+Name: iqs550 -+Info: Enables I2C connected Azoteq IQS550 trackpad/touchscreen controller -+ using GPIO 4 (pin 7 on GPIO header) for interrupt. -+Load: dtoverlay=iqs550,= -+Params: interrupt GPIO used for interrupt (default 4) -+ reset GPIO used for reset (optional) -+ sizex Touchscreen size x (default 800) -+ sizey Touchscreen size y (default 480) -+ invx Touchscreen inverted x axis -+ invy Touchscreen inverted y axis -+ swapxy Touchscreen swapped x y axis -+ -+ - Name: irs1125 - Info: Infineon irs1125 TOF camera module. - Uses Unicam 1, which is the standard camera connector on most Pi ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/iqs550-overlay.dts -@@ -0,0 +1,46 @@ -+// SPDX-License-Identifier: GPL-2.0-or-later -+// Definitions for Azoteq IQS550 trackpad/touchscreen controller -+/dts-v1/; -+/plugin/; -+#include -+#include -+ -+/ { -+ compatible = "brcm,bcm2835"; -+ -+ fragment@0 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ iqs550: iqs550@74 { -+ compatible = "azoteq,iqs550"; -+ reg = <0x74>; -+ interrupt-parent = <&gpio>; -+ interrupts = <4 IRQ_TYPE_LEVEL_HIGH>; -+ touchscreen-size-x = <800>; -+ touchscreen-size-y = <480>; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&iqs550>; -+ iqs550_reset: __dormant__ { -+ reset-gpios = <&gpio 255 (GPIO_ACTIVE_LOW | -+ GPIO_PUSH_PULL)>; -+ }; -+ }; -+ -+ __overrides__ { -+ interrupt = <&iqs550>,"interrupts:0"; -+ reset = <0>,"+1", <&iqs550_reset>,"reset-gpios:4"; -+ sizex = <&iqs550>,"touchscreen-size-x:0"; -+ sizey = <&iqs550>,"touchscreen-size-y:0"; -+ invx = <&iqs550>,"touchscreen-inverted-x?"; -+ invy = <&iqs550>,"touchscreen-inverted-y?"; -+ swapxy = <&iqs550>,"touchscreen-swapped-x-y?"; -+ }; -+}; diff --git a/target/linux/bcm27xx/patches-5.15/950-0649-dtoverlays-Add-backlight-gpio-parameter-to-vc4-kms-d.patch b/target/linux/bcm27xx/patches-5.15/950-0649-dtoverlays-Add-backlight-gpio-parameter-to-vc4-kms-d.patch deleted file mode 100644 index e10dc1f68..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0649-dtoverlays-Add-backlight-gpio-parameter-to-vc4-kms-d.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 97a59d460244efdb87b464b9f07c1e90e7e7129a Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Fri, 7 Jan 2022 11:12:08 +0000 -Subject: [PATCH] dtoverlays: Add backlight-gpio parameter to - vc4-kms-dpi-generic - -To allow for the cases where a simple panel does have a GPIO -controlled backlight. Defaults to having no backlight defined. - -Signed-off-by: Dave Stevenson ---- - arch/arm/boot/dts/overlays/README | 2 ++ - .../overlays/vc4-kms-dpi-generic-overlay.dts | 19 +++++++++++++++++++ - 2 files changed, 21 insertions(+) - ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -3638,6 +3638,8 @@ Params: clock-frequency Display - rgb888 Change to RGB888 output on GPIOs 0-27 - bus-format Override the bus format for a MEDIA_BUS_FMT_* - value. NB also overridden by rgbXXX overrides. -+ backlight-gpio Defines a GPIO to be used for backlight control -+ (default of none). - - - Name: vc4-kms-dsi-7inch ---- a/arch/arm/boot/dts/overlays/vc4-kms-dpi-generic-overlay.dts -+++ b/arch/arm/boot/dts/overlays/vc4-kms-dpi-generic-overlay.dts -@@ -63,6 +63,23 @@ - }; - }; - -+ fragment@2 { -+ target = <&panel>; -+ __dormant__ { -+ backlight = <&backlight>; -+ }; -+ }; -+ -+ fragment@3 { -+ target-path = "/"; -+ __dormant__ { -+ backlight: backlight { -+ compatible = "gpio-backlight"; -+ gpios = <&gpio 255 GPIO_ACTIVE_HIGH>; -+ }; -+ }; -+ }; -+ - __overrides__ { - clock-frequency = <&timing>, "clock-frequency:0"; - hactive = <&timing>, "hactive:0"; -@@ -88,5 +105,7 @@ - rgb888 = <&panel>, "bus-format:0=0x100a", - <&dpi_node>, "pinctrl-0:0=",<&dpi_gpio0>; - bus-format = <&panel>, "bus-format:0"; -+ backlight-gpio = <0>, "+2+3", -+ <&backlight>, "gpios:4"; - }; - }; diff --git a/target/linux/bcm27xx/patches-5.15/950-0650-drm-vc4-Add-alpha_blend_mode-property-to-each-plane.patch b/target/linux/bcm27xx/patches-5.15/950-0650-drm-vc4-Add-alpha_blend_mode-property-to-each-plane.patch deleted file mode 100644 index 80e9a7285..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0650-drm-vc4-Add-alpha_blend_mode-property-to-each-plane.patch +++ /dev/null @@ -1,108 +0,0 @@ -From 7760958a0fb50b0e20f88e220f55798ec154c41e Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Sat, 8 Jan 2022 13:24:10 +0000 -Subject: [PATCH] drm/vc4: Add alpha_blend_mode property to each plane. - -Move from only supporting the default of pre-multiplied -alpha to supporting user specified blend mode using the -standardised property. - -Signed-off-by: Dave Stevenson ---- - drivers/gpu/drm/vc4/vc4_plane.c | 62 ++++++++++++++++++++++++++------- - 1 file changed, 49 insertions(+), 13 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_plane.c -+++ b/drivers/gpu/drm/vc4/vc4_plane.c -@@ -666,6 +666,48 @@ static const u32 colorspace_coeffs[2][DR - } - }; - -+static u32 vc4_hvs4_get_alpha_blend_mode(struct drm_plane_state *state) -+{ -+ if (!state->fb->format->has_alpha) -+ return VC4_SET_FIELD(SCALER_POS2_ALPHA_MODE_FIXED, -+ SCALER_POS2_ALPHA_MODE); -+ -+ switch (state->pixel_blend_mode) { -+ case DRM_MODE_BLEND_PIXEL_NONE: -+ return VC4_SET_FIELD(SCALER_POS2_ALPHA_MODE_FIXED, -+ SCALER_POS2_ALPHA_MODE); -+ default: -+ case DRM_MODE_BLEND_PREMULTI: -+ return VC4_SET_FIELD(SCALER_POS2_ALPHA_MODE_PIPELINE, -+ SCALER_POS2_ALPHA_MODE) | -+ SCALER_POS2_ALPHA_PREMULT; -+ case DRM_MODE_BLEND_COVERAGE: -+ return VC4_SET_FIELD(SCALER_POS2_ALPHA_MODE_PIPELINE, -+ SCALER_POS2_ALPHA_MODE); -+ } -+} -+ -+static u32 vc4_hvs5_get_alpha_blend_mode(struct drm_plane_state *state) -+{ -+ if (!state->fb->format->has_alpha) -+ return VC4_SET_FIELD(SCALER5_CTL2_ALPHA_MODE_FIXED, -+ SCALER5_CTL2_ALPHA_MODE); -+ -+ switch (state->pixel_blend_mode) { -+ case DRM_MODE_BLEND_PIXEL_NONE: -+ return VC4_SET_FIELD(SCALER5_CTL2_ALPHA_MODE_FIXED, -+ SCALER5_CTL2_ALPHA_MODE); -+ default: -+ case DRM_MODE_BLEND_PREMULTI: -+ return VC4_SET_FIELD(SCALER5_CTL2_ALPHA_MODE_PIPELINE, -+ SCALER5_CTL2_ALPHA_MODE) | -+ SCALER5_CTL2_ALPHA_PREMULT; -+ case DRM_MODE_BLEND_COVERAGE: -+ return VC4_SET_FIELD(SCALER5_CTL2_ALPHA_MODE_PIPELINE, -+ SCALER5_CTL2_ALPHA_MODE); -+ } -+} -+ - /* Writes out a full display list for an active plane to the plane's - * private dlist state. - */ -@@ -948,13 +990,8 @@ static int vc4_plane_mode_set(struct drm - /* Position Word 2: Source Image Size, Alpha */ - vc4_state->pos2_offset = vc4_state->dlist_count; - vc4_dlist_write(vc4_state, -- VC4_SET_FIELD(fb->format->has_alpha ? -- SCALER_POS2_ALPHA_MODE_PIPELINE : -- SCALER_POS2_ALPHA_MODE_FIXED, -- SCALER_POS2_ALPHA_MODE) | - (mix_plane_alpha ? SCALER_POS2_ALPHA_MIX : 0) | -- (fb->format->has_alpha ? -- SCALER_POS2_ALPHA_PREMULT : 0) | -+ vc4_hvs4_get_alpha_blend_mode(state) | - VC4_SET_FIELD(vc4_state->src_w[0], - SCALER_POS2_WIDTH) | - VC4_SET_FIELD(vc4_state->src_h[0], -@@ -999,14 +1036,9 @@ static int vc4_plane_mode_set(struct drm - vc4_dlist_write(vc4_state, - VC4_SET_FIELD(state->alpha >> 4, - SCALER5_CTL2_ALPHA) | -- (fb->format->has_alpha ? -- SCALER5_CTL2_ALPHA_PREMULT : 0) | -+ vc4_hvs5_get_alpha_blend_mode(state) | - (mix_plane_alpha ? -- SCALER5_CTL2_ALPHA_MIX : 0) | -- VC4_SET_FIELD(fb->format->has_alpha ? -- SCALER5_CTL2_ALPHA_MODE_PIPELINE : -- SCALER5_CTL2_ALPHA_MODE_FIXED, -- SCALER5_CTL2_ALPHA_MODE) -+ SCALER5_CTL2_ALPHA_MIX : 0) - ); - - /* Position Word 1: Scaled Image Dimensions. */ -@@ -1496,6 +1528,10 @@ struct drm_plane *vc4_plane_init(struct - drm_plane_helper_add(plane, &vc4_plane_helper_funcs); - - drm_plane_create_alpha_property(plane); -+ drm_plane_create_blend_mode_property(plane, -+ BIT(DRM_MODE_BLEND_PIXEL_NONE) | -+ BIT(DRM_MODE_BLEND_PREMULTI) | -+ BIT(DRM_MODE_BLEND_COVERAGE)); - drm_plane_create_rotation_property(plane, DRM_MODE_ROTATE_0, - DRM_MODE_ROTATE_0 | - DRM_MODE_ROTATE_180 | diff --git a/target/linux/bcm27xx/patches-5.15/950-0651-arm-Fix-custom-rpi-__memset32-and-__memset64.patch b/target/linux/bcm27xx/patches-5.15/950-0651-arm-Fix-custom-rpi-__memset32-and-__memset64.patch deleted file mode 100644 index d6d464272..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0651-arm-Fix-custom-rpi-__memset32-and-__memset64.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 43e769a2c40287d36c54438898a8b7d9358adba9 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 11 Jan 2022 10:48:30 +0000 -Subject: [PATCH] arm: Fix custom rpi __memset32 and __memset64 - -See: https://github.com/raspberrypi/linux/issues/4798 - -Signed-off-by: Phil Elwell ---- - arch/arm/lib/memset_rpi.S | 12 +++++++----- - 1 file changed, 7 insertions(+), 5 deletions(-) - ---- a/arch/arm/lib/memset_rpi.S -+++ b/arch/arm/lib/memset_rpi.S -@@ -53,8 +53,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBI - ENTRY(mmioset) - ENTRY(memset) - ENTRY(__memset) --ENTRY(__memset32) --ENTRY(__memset64) - - S .req a1 - DAT0 .req a2 -@@ -64,10 +62,14 @@ ENTRY(__memset64) - DAT3 .req lr - - orr DAT0, DAT0, DAT0, lsl #8 -- push {S, lr} - orr DAT0, DAT0, DAT0, lsl #16 -+ -+ENTRY(__memset32) - mov DAT1, DAT0 - -+ENTRY(__memset64) -+ push {S, lr} -+ - /* See if we're guaranteed to have at least one 16-byte aligned 16-byte write */ - cmp N, #31 - blo 170f -@@ -89,7 +91,7 @@ ENTRY(__memset64) - stmcsia S!, {DAT0, DAT1} - 164: /* Delayed set up of DAT2 and DAT3 so we could use them as scratch registers above */ - mov DAT2, DAT0 -- mov DAT3, DAT0 -+ mov DAT3, DAT1 - /* Now the inner loop of 16-byte stores */ - 165: stmia S!, {DAT0, DAT1, DAT2, DAT3} - subs N, N, #16 -@@ -105,7 +107,7 @@ ENTRY(__memset64) - - 170: /* Short case */ - mov DAT2, DAT0 -- mov DAT3, DAT0 -+ mov DAT3, DAT1 - tst S, #3 - beq 174f - 172: subs N, N, #1 diff --git a/target/linux/bcm27xx/patches-5.15/950-0652-overlays-Add-vl805-overlay.patch b/target/linux/bcm27xx/patches-5.15/950-0652-overlays-Add-vl805-overlay.patch deleted file mode 100644 index 6ef1690da..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0652-overlays-Add-vl805-overlay.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 2f1c8eedc108d458fb2566ec582cbd7c45fc280b Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 12 Jan 2022 12:48:53 +0000 -Subject: [PATCH] overlays: Add vl805 overlay - -With the automatic VL805 support being removed from the standard -CM4 dtb (since most CM4 carriers don't have a VL805), retain support -on those that do by creating a "vl805" overlay that restores the -deleted "usb@0,0" node. - -The "vl805" overlay will be loaded automatically (after an upcoming -firmware update) on CM4 boards where the EEPROM config includes the -setting VL805=1. - -See: https://forums.raspberrypi.com/viewtopic.php?t=326088 - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 8 ++++++++ - arch/arm/boot/dts/overlays/vl805-overlay.dts | 18 ++++++++++++++++++ - 3 files changed, 27 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/vl805-overlay.dts - ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -243,6 +243,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ - vc4-kms-v3d-pi4.dtbo \ - vc4-kms-vga666.dtbo \ - vga666.dtbo \ -+ vl805.dtbo \ - w1-gpio.dtbo \ - w1-gpio-pullup.dtbo \ - w5500.dtbo \ ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -3744,6 +3744,14 @@ Load: dtoverlay=vga666 - Params: - - -+Name: vl805 -+Info: Overlay to enable a VIA VL805 USB3 controller on CM4 carriers -+ Will be loaded automatically by up-to-date firmware if "VL805=1" is -+ set in the EEPROM config. -+Load: dtoverlay=vl805 -+Params: -+ -+ - Name: w1-gpio - Info: Configures the w1-gpio Onewire interface module. - Use this overlay if you *don't* need a GPIO to drive an external pullup. ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/vl805-overlay.dts -@@ -0,0 +1,18 @@ -+/dts-v1/; -+/plugin/; -+ -+#include -+ -+/ { -+ compatible = "brcm,bcm2711"; -+ -+ fragment@0 { -+ target-path = "pcie0/pci@0,0"; -+ __overlay__ { -+ usb@0,0 { -+ reg = <0 0 0 0 0>; -+ resets = <&reset RASPBERRYPI_FIRMWARE_RESET_ID_USB>; -+ }; -+ }; -+ }; -+}; diff --git a/target/linux/bcm27xx/patches-5.15/950-0653-arm-Fix-annoying-.eh_frame-section-warnings.patch b/target/linux/bcm27xx/patches-5.15/950-0653-arm-Fix-annoying-.eh_frame-section-warnings.patch deleted file mode 100644 index 4a90eafc0..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0653-arm-Fix-annoying-.eh_frame-section-warnings.patch +++ /dev/null @@ -1,123 +0,0 @@ -From 8dabc6eab444607a68d710f0b09942277095e219 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 12 Jan 2022 17:27:03 +0000 -Subject: [PATCH] arm: Fix annoying .eh_frame section warnings - -Replace the cfi directives with the UNWIND equivalents. This prevents -the .eh_frame section from being created, eliminating the warnings. - -Signed-off-by: Phil Elwell ---- - arch/arm/lib/memcpy_rpi.S | 2 ++ - arch/arm/lib/memcpymove.h | 45 ++++++++++++-------------------------- - arch/arm/lib/memmove_rpi.S | 2 ++ - 3 files changed, 18 insertions(+), 31 deletions(-) - ---- a/arch/arm/lib/memcpy_rpi.S -+++ b/arch/arm/lib/memcpy_rpi.S -@@ -27,6 +27,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBI - */ - - #include -+#include -+#include - #include "arm-mem.h" - #include "memcpymove.h" - ---- a/arch/arm/lib/memcpymove.h -+++ b/arch/arm/lib/memcpymove.h -@@ -280,6 +280,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBI - 199: - pop {DAT3, DAT4, DAT5, DAT6, DAT7} - pop {D, DAT1, DAT2, pc} -+ UNWIND( .fnend ) - .endm - - .macro memcpy_medium_inner_loop backwards, align -@@ -358,19 +359,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBI - LAST .req ip - OFF .req lr - -- .cfi_startproc -+ UNWIND( .fnstart ) - - push {D, DAT1, DAT2, lr} -+ UNWIND( .fnend ) - -- .cfi_def_cfa_offset 16 -- .cfi_rel_offset D, 0 -- .cfi_undefined S -- .cfi_undefined N -- .cfi_undefined DAT0 -- .cfi_rel_offset DAT1, 4 -- .cfi_rel_offset DAT2, 8 -- .cfi_undefined LAST -- .cfi_rel_offset lr, 12 -+ UNWIND( .fnstart ) -+ UNWIND( .save {D, DAT1, DAT2, lr} ) - - .if backwards - add D, D, N -@@ -386,17 +381,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBI - - /* Long case */ - push {DAT3, DAT4, DAT5, DAT6, DAT7} -+ UNWIND( .fnend ) - -- .cfi_def_cfa_offset 36 -- .cfi_rel_offset D, 20 -- .cfi_rel_offset DAT1, 24 -- .cfi_rel_offset DAT2, 28 -- .cfi_rel_offset DAT3, 0 -- .cfi_rel_offset DAT4, 4 -- .cfi_rel_offset DAT5, 8 -- .cfi_rel_offset DAT6, 12 -- .cfi_rel_offset DAT7, 16 -- .cfi_rel_offset lr, 32 -+ UNWIND( .fnstart ) -+ UNWIND( .save {D, DAT1, DAT2, lr} ) -+ UNWIND( .save {DAT3, DAT4, DAT5, DAT6, DAT7} ) - - /* Adjust N so that the decrement instruction can also test for - * inner loop termination. We want it to stop when there are -@@ -436,16 +425,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBI - 156: memcpy_long_inner_loop backwards, 2 - 157: memcpy_long_inner_loop backwards, 3 - -- .cfi_def_cfa_offset 16 -- .cfi_rel_offset D, 0 -- .cfi_rel_offset DAT1, 4 -- .cfi_rel_offset DAT2, 8 -- .cfi_same_value DAT3 -- .cfi_same_value DAT4 -- .cfi_same_value DAT5 -- .cfi_same_value DAT6 -- .cfi_same_value DAT7 -- .cfi_rel_offset lr, 12 -+ UNWIND( .fnend ) -+ -+ UNWIND( .fnstart ) -+ UNWIND( .save {D, DAT1, DAT2, lr} ) - - 160: /* Medium case */ - preload_all backwards, 0, 0, S, N, DAT2, OFF -@@ -488,7 +471,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBI - memcpy_short_inner_loop backwards, 0 - 140: memcpy_short_inner_loop backwards, 1 - -- .cfi_endproc -+ UNWIND( .fnend ) - - .unreq D - .unreq S ---- a/arch/arm/lib/memmove_rpi.S -+++ b/arch/arm/lib/memmove_rpi.S -@@ -27,6 +27,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBI - */ - - #include -+#include -+#include - #include "arm-mem.h" - #include "memcpymove.h" - diff --git a/target/linux/bcm27xx/patches-5.15/950-0655-drm-vc4-hdmi-Fix-clock-value-used-for-validating-hdm.patch b/target/linux/bcm27xx/patches-5.15/950-0655-drm-vc4-hdmi-Fix-clock-value-used-for-validating-hdm.patch deleted file mode 100644 index 67fbf40e7..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0655-drm-vc4-hdmi-Fix-clock-value-used-for-validating-hdm.patch +++ /dev/null @@ -1,29 +0,0 @@ -From f285cba93ac9425078740d20456f34c94ad7511c Mon Sep 17 00:00:00 2001 -From: Dom Cobley -Date: Thu, 13 Jan 2022 15:47:23 +0000 -Subject: [PATCH] drm/vc4: hdmi: Fix clock value used for validating - hdmi modes - -We are using mode->crt_clock here which is filled by drm_mode_set_crtcinfo() -which is called right after .mode_valid. - -Use mode->clock which is valid here. - -Fixes: 624d93a4f0 ("drm/vc4: hdmi: Move clock calculation into its own function") - -Signed-off-by: Dom Cobley ---- - drivers/gpu/drm/vc4/vc4_hdmi.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/gpu/drm/vc4/vc4_hdmi.c -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c -@@ -1497,7 +1497,7 @@ vc4_hdmi_encoder_compute_mode_clock(cons - unsigned int bpc, - enum vc4_hdmi_output_format fmt) - { -- unsigned long long clock = mode->crtc_clock * 1000; -+ unsigned long long clock = mode->clock * 1000; - - if (mode->flags & DRM_MODE_FLAG_DBLCLK) - clock = clock * 2; diff --git a/target/linux/bcm27xx/patches-5.15/950-0656-ARM-dts-Remove-VL805-USB-node-from-CM4-dts.patch b/target/linux/bcm27xx/patches-5.15/950-0656-ARM-dts-Remove-VL805-USB-node-from-CM4-dts.patch deleted file mode 100644 index e7fe76911..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0656-ARM-dts-Remove-VL805-USB-node-from-CM4-dts.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 98695baaffb88f7de0486fa1e039f8b3e47661d2 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 12 Jan 2022 14:39:46 +0000 -Subject: [PATCH] ARM: dts: Remove VL805 USB node from CM4 dts - -Neither the CM4 module nor the CM4IO board have a VL805 USB3 -controller. The existing "usb@0,0" node is a hangover from the -Pi 4 dts; delete it. An up-to-date firmware will automatically load -the vl805 overlay on CM4s with VL805=1 in the EEPROM config, ensuring -that the firmware is notified of any PCIe reset. - -See: https://forums.raspberrypi.com/viewtopic.php?t=326088 - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/bcm2711-rpi-cm4.dts | 5 ----- - 1 file changed, 5 deletions(-) - ---- a/arch/arm/boot/dts/bcm2711-rpi-cm4.dts -+++ b/arch/arm/boot/dts/bcm2711-rpi-cm4.dts -@@ -237,11 +237,6 @@ - ranges; - - reg = <0 0 0 0 0>; -- -- usb@0,0 { -- reg = <0 0 0 0 0>; -- resets = <&reset RASPBERRYPI_FIRMWARE_RESET_ID_USB>; -- }; - }; - }; - diff --git a/target/linux/bcm27xx/patches-5.15/950-0661-dtoverlays-Add-option-for-PoE-HAT-to-use-Linux-I2C-i.patch b/target/linux/bcm27xx/patches-5.15/950-0661-dtoverlays-Add-option-for-PoE-HAT-to-use-Linux-I2C-i.patch deleted file mode 100644 index 8a8a35bb3..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0661-dtoverlays-Add-option-for-PoE-HAT-to-use-Linux-I2C-i.patch +++ /dev/null @@ -1,158 +0,0 @@ -From 7d4346817f31105ed07dd4e3e9fd2294c85a5fee Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Wed, 19 Jan 2022 17:29:13 +0000 -Subject: [PATCH] dtoverlays: Add option for PoE HAT to use Linux I2C - instead of FW. - -Adds parameter "i2c" to use the PoE HAT I2C MFD driver to instantiate -the PoE HAT drivers, instead of being off the firmware. - -Signed-off-by: Dave Stevenson ---- - arch/arm/boot/dts/overlays/README | 4 ++ - .../arm/boot/dts/overlays/rpi-poe-overlay.dts | 62 +++++++++++++++---- - .../dts/overlays/rpi-poe-plus-overlay.dts | 15 +++++ - 3 files changed, 69 insertions(+), 12 deletions(-) - ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -2858,6 +2858,8 @@ Params: poe_fan_temp0 Temperat - speeds up (default 55000) - poe_fan_temp3_hyst Temperature delta (in millicelcius) at which - the fan slows down (default 5000) -+ i2c Control the fan via Linux I2C drivers instead of -+ the firmware. - - - Name: rpi-poe-plus -@@ -2879,6 +2881,8 @@ Params: poe_fan_temp0 Temperat - speeds up (default 55000) - poe_fan_temp3_hyst Temperature delta (in millicelcius) at which - the fan slows down (default 5000) -+ i2c Control the fan via Linux I2C drivers instead of -+ the firmware. - - - Name: rpi-proto ---- a/arch/arm/boot/dts/overlays/rpi-poe-overlay.dts -+++ b/arch/arm/boot/dts/overlays/rpi-poe-overlay.dts -@@ -8,16 +8,6 @@ - compatible = "brcm,bcm2835"; - - fragment@0 { -- target = <&firmware>; -- __overlay__ { -- fwpwm: pwm { -- compatible = "raspberrypi,firmware-poe-pwm"; -- #pwm-cells = <2>; -- }; -- }; -- }; -- -- fragment@1 { - target-path = "/"; - __overlay__ { - fan: pwm-fan { -@@ -29,7 +19,7 @@ - }; - }; - -- fragment@2 { -+ fragment@1 { - target = <&cpu_thermal>; - __overlay__ { - trips { -@@ -75,7 +65,7 @@ - }; - }; - -- fragment@3 { -+ fragment@2 { - target-path = "/__overrides__"; - __overlay__ { - poe_fan_temp0 = <&trip0>,"temperature:0"; -@@ -89,6 +79,52 @@ - }; - }; - -+ fragment@3 { -+ target = <&firmware>; -+ __overlay__ { -+ fwpwm: pwm { -+ compatible = "raspberrypi,firmware-poe-pwm"; -+ #pwm-cells = <2>; -+ }; -+ }; -+ }; -+ -+ fragment@4 { -+ target = <&i2c0>; -+ __dormant__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ poe_mfd: poe@51 { -+ compatible = "raspberrypi,poe-core"; -+ reg = <0x51>; -+ status = "okay"; -+ -+ poe_mfd_pwm: poe_pwm@f0 { -+ compatible = "raspberrypi,poe-pwm"; -+ reg = <0xf0>; -+ status = "okay"; -+ #pwm-cells = <2>; -+ }; -+ }; -+ }; -+ }; -+ -+ fragment@5 { -+ target = <&i2c0if>; -+ __dormant__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@6 { -+ target = <&i2c0mux>; -+ __dormant__ { -+ status = "okay"; -+ }; -+ }; -+ - __overrides__ { - poe_fan_temp0 = <&trip0>,"temperature:0"; - poe_fan_temp0_hyst = <&trip0>,"hysteresis:0"; -@@ -98,5 +134,7 @@ - poe_fan_temp2_hyst = <&trip2>,"hysteresis:0"; - poe_fan_temp3 = <&trip3>,"temperature:0"; - poe_fan_temp3_hyst = <&trip3>,"hysteresis:0"; -+ i2c = <0>, "-3+4+5+6", -+ <&fan>,"pwms:0=",<&poe_mfd_pwm>; - }; - }; ---- a/arch/arm/boot/dts/overlays/rpi-poe-plus-overlay.dts -+++ b/arch/arm/boot/dts/overlays/rpi-poe-plus-overlay.dts -@@ -16,6 +16,21 @@ - }; - }; - }; -+ fragment@11 { -+ target = <&poe_mfd>; -+ __dormant__ { -+ rpi-poe-power-supply@f2 { -+ compatible = "raspberrypi,rpi-poe-power-supply"; -+ reg = <0xf2>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ i2c = <0>, "-3+4+5+6-10+11", -+ <&fan>,"pwms:0=",<&poe_mfd_pwm>; -+ }; - }; - - &fan { diff --git a/target/linux/bcm27xx/patches-5.15/950-0663-arm-Remove-spurious-.fnend-directive.patch b/target/linux/bcm27xx/patches-5.15/950-0663-arm-Remove-spurious-.fnend-directive.patch deleted file mode 100644 index 264a3903d..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0663-arm-Remove-spurious-.fnend-directive.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 98d86729da341c82f4776145511d01e8bfdfed29 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 21 Jan 2022 08:49:13 +0000 -Subject: [PATCH] arm: Remove spurious .fnend directive - -...a.k.a. Fix annoying build error - -Some toolchains rightly object to the fact that once the acros are -expanded this results in multiple ".fnend"s without ".fnstart"s. - -See: https://github.com/raspberrypi/linux/issues/4836 - -Signed-off-by: Phil Elwell ---- - arch/arm/lib/memcpymove.h | 1 - - 1 file changed, 1 deletion(-) - ---- a/arch/arm/lib/memcpymove.h -+++ b/arch/arm/lib/memcpymove.h -@@ -280,7 +280,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBI - 199: - pop {DAT3, DAT4, DAT5, DAT6, DAT7} - pop {D, DAT1, DAT2, pc} -- UNWIND( .fnend ) - .endm - - .macro memcpy_medium_inner_loop backwards, align diff --git a/target/linux/bcm27xx/patches-5.15/950-0665-dtoverlays-Add-pwm-backlight-option-to-vc4-kms-dpi-g.patch b/target/linux/bcm27xx/patches-5.15/950-0665-dtoverlays-Add-pwm-backlight-option-to-vc4-kms-dpi-g.patch deleted file mode 100644 index 5b0243472..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0665-dtoverlays-Add-pwm-backlight-option-to-vc4-kms-dpi-g.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 7ec32023e6ad31c242e2acc179fd35084fa9cea5 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Fri, 21 Jan 2022 14:22:01 +0000 -Subject: [PATCH] dtoverlays: Add pwm backlight option to - vc4-kms-dpi-generic - -Adds the option of a PWM controlled backlight on a generic -DPI display. - -Signed-off-by: Dave Stevenson ---- - arch/arm/boot/dts/overlays/README | 17 +++++++ - .../overlays/vc4-kms-dpi-generic-overlay.dts | 51 +++++++++++++++++++ - 2 files changed, 68 insertions(+) - ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -3644,6 +3644,23 @@ Params: clock-frequency Display - value. NB also overridden by rgbXXX overrides. - backlight-gpio Defines a GPIO to be used for backlight control - (default of none). -+ backlight-pwm Defines a PWM channel to be used for backlight -+ control (default of none). NB Disables audio -+ headphone output as that also uses PWM. -+ backlight-pwm-chan Choose channel on &pwm node for backlight -+ control. -+ (default 0). -+ backlight-pwm-gpio GPIO pin to be used for the PWM backlight. See -+ pwm-2chan for valid options. -+ (default 18 - note this can only work with -+ rgb666-padhi). -+ backlight-pwm-func Pin function of GPIO used for the PWM -+ backlight. -+ See pwm-2chan for valid options. -+ (default 2). -+ backlight-def-brightness -+ Set the default brightness. Normal range 1-16. -+ (default 16). - - - Name: vc4-kms-dsi-7inch ---- a/arch/arm/boot/dts/overlays/vc4-kms-dpi-generic-overlay.dts -+++ b/arch/arm/boot/dts/overlays/vc4-kms-dpi-generic-overlay.dts -@@ -80,6 +80,52 @@ - }; - }; - -+ fragment@4 { -+ target = <&panel>; -+ __dormant__ { -+ backlight = <&backlight_pwm>; -+ }; -+ }; -+ -+ fragment@5 { -+ target-path = "/"; -+ __dormant__ { -+ backlight_pwm: backlight_pwm { -+ compatible = "pwm-backlight"; -+ brightness-levels = <0 6 8 12 16 24 32 40 48 64 96 128 160 192 224 255>; -+ default-brightness-level = <16>; -+ pwms = <&pwm 0 200000>; -+ }; -+ }; -+ }; -+ -+ fragment@6 { -+ target = <&pwm>; -+ __dormant__ { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pwm_pins>; -+ assigned-clock-rates = <1000000>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@7 { -+ target = <&gpio>; -+ __dormant__ { -+ pwm_pins: pwm_pins { -+ brcm,pins = <18>; -+ brcm,function = <2>; /* Alt5 */ -+ }; -+ }; -+ }; -+ -+ fragment@8 { -+ target = <&audio>; -+ __dormant__ { -+ brcm,disable-headphones; -+ }; -+ }; -+ - __overrides__ { - clock-frequency = <&timing>, "clock-frequency:0"; - hactive = <&timing>, "hactive:0"; -@@ -107,5 +153,10 @@ - bus-format = <&panel>, "bus-format:0"; - backlight-gpio = <0>, "+2+3", - <&backlight>, "gpios:4"; -+ backlight-pwm = <0>, "+4+5+6+7+8"; -+ backlight-pwm-chan = <&backlight_pwm>, "pwms:4"; -+ backlight-pwm-gpio = <&pwm_pins>, "brcm,pins:0"; -+ backlight-pwm-func = <&pwm_pins>, "brcm,function:0"; -+ backlight-def-brightness = <&backlight_pwm>, "default-brightness-level:0"; - }; - }; diff --git a/target/linux/bcm27xx/patches-5.15/950-0666-dtoverlays-Correct-h-v-sync_invert-config-in-vc4-kms.patch b/target/linux/bcm27xx/patches-5.15/950-0666-dtoverlays-Correct-h-v-sync_invert-config-in-vc4-kms.patch deleted file mode 100644 index 274e1f5f8..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0666-dtoverlays-Correct-h-v-sync_invert-config-in-vc4-kms.patch +++ /dev/null @@ -1,38 +0,0 @@ -From b02995d0900af96c54acbb1e884b25f9399e9afb Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Fri, 21 Jan 2022 15:12:25 +0000 -Subject: [PATCH]sync_invert config in - vc4-kms-dpi-generic - -Both the base node and override set these parameters to 0, -so it made no difference. The base node should have been 1. - -Signed-off-by: Dave Stevenson ---- - arch/arm/boot/dts/overlays/vc4-kms-dpi-generic-overlay.dts | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/arch/arm/boot/dts/overlays/vc4-kms-dpi-generic-overlay.dts -+++ b/arch/arm/boot/dts/overlays/vc4-kms-dpi-generic-overlay.dts -@@ -1,5 +1,5 @@ - /* -- * vc4-kms-dpi-at056tn53v1-overlay.dts -+ * vc4-kms-dpi-generic-overlay.dts - */ - - /dts-v1/; -@@ -27,12 +27,12 @@ - hfront-porch = <24>; - hsync-len = <72>; - hback-porch = <96>; -- hsync-active = <0>; -+ hsync-active = <1>; - vactive = <480>; - vfront-porch = <3>; - vsync-len = <10>; - vback-porch = <7>; -- vsync-active = <0>; -+ vsync-active = <1>; - - de-active = <1>; - pixelclk-active = <1>; diff --git a/target/linux/bcm27xx/patches-5.15/950-0667-ARM-dts-BCM2711-AON_INTR2-generates-IRQ-edges.patch b/target/linux/bcm27xx/patches-5.15/950-0667-ARM-dts-BCM2711-AON_INTR2-generates-IRQ-edges.patch deleted file mode 100644 index 8e9d8212b..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0667-ARM-dts-BCM2711-AON_INTR2-generates-IRQ-edges.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 3050e07453791b8dfecf355a03cee075ec687a55 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 21 Jan 2022 12:24:57 +0000 -Subject: [PATCH] ARM: dts: BCM2711 AON_INTR2 generates IRQ edges - -THe AON_INTR2 controller manages the HDMI interrupts, combining them -into a single interrupt passed to the GIC. bcm2711.dtsi declares the -interrupt as being IRQ_TYPE_LEVEL_HIGH, but it should be -IRQ_TYPE_EDGE_RISING. Most of the time the distinction shouldn't -matter, but there is a small possibility of losing interrupts unless -it is corrected. - -See: http://lists.infradead.org/pipermail/linux-arm-kernel/2022-January/710292.html - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/bcm2711.dtsi | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/arch/arm/boot/dts/bcm2711.dtsi -+++ b/arch/arm/boot/dts/bcm2711.dtsi -@@ -320,7 +320,7 @@ - aon_intr: interrupt-controller@7ef00100 { - compatible = "brcm,bcm2711-l2-intc", "brcm,l2-intc"; - reg = <0x7ef00100 0x30>; -- interrupts = ; -+ interrupts = ; - interrupt-controller; - #interrupt-cells = <1>; - status = "disabled"; -@@ -403,7 +403,7 @@ - <&clk_27MHz>; - resets = <&dvp 1>; - interrupt-parent = <&aon_intr>; -- interrupts = <8>, <7>, <6>, -+ interrupts = <8>, <7>, <6>, // This is correct - <9>, <10>, <11>; - interrupt-names = "cec-tx", "cec-rx", "cec-low", - "wakeup", "hpd-connected", "hpd-removed"; diff --git a/target/linux/bcm27xx/patches-5.15/950-0670-overlays-Add-MAX30102-HR-to-i2c-sensor-overlay.patch b/target/linux/bcm27xx/patches-5.15/950-0670-overlays-Add-MAX30102-HR-to-i2c-sensor-overlay.patch deleted file mode 100644 index 82bcce667..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0670-overlays-Add-MAX30102-HR-to-i2c-sensor-overlay.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 2f995c2231e449016206dd2905b87846adc2b357 Mon Sep 17 00:00:00 2001 -From: coldspark29 -Date: Wed, 18 Aug 2021 13:41:04 +0200 -Subject: [PATCH] overlays: Add MAX30102 HR to i2c-sensor overlay - -Add support for the MAX30102 heart rate and blood oxygen sensor to the -i2c-sensor overlay. - -See: https://github.com/raspberrypi/linux/pull/4535 - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/overlays/README | 6 ++++++ - .../boot/dts/overlays/i2c-sensor-overlay.dts | 20 +++++++++++++++++++ - 2 files changed, 26 insertions(+) - ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -1725,6 +1725,9 @@ Params: addr Set the - - htu21 Select the HTU21 temperature and humidity sensor - -+ int_pin Set the GPIO to use for interrupts (max30102 -+ only) -+ - lm75 Select the Maxim LM75 temperature sensor - Valid addresses 0x48-0x4f, default 0x4f - -@@ -1733,6 +1736,9 @@ Params: addr Set the - max17040 Select the Maxim Integrated MAX17040 battery - monitor - -+ max30102 Select the Maxim Integrated MAX30102 heart-rate -+ and blood-oxygen sensor -+ - sht3x Select the Sensiron SHT3x temperature and - humidity sensor. Valid addresses 0x44-0x45, - default 0x44 ---- a/arch/arm/boot/dts/overlays/i2c-sensor-overlay.dts -+++ b/arch/arm/boot/dts/overlays/i2c-sensor-overlay.dts -@@ -291,11 +291,30 @@ - }; - }; - -+ fragment@19 { -+ target = <&i2c_arm>; -+ __dormant__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ max30102: max30102@57 { -+ compatible = "maxim,max30102"; -+ reg = <0x57>; -+ maxim,red-led-current-microamp = <7000>; -+ maxim,ir-led-current-microamp = <7000>; -+ interrupt-parent = <&gpio>; -+ interrupts = <4 2>; -+ }; -+ }; -+ }; -+ - __overrides__ { - addr = <&bme280>,"reg:0", <&bmp280>,"reg:0", <&tmp102>,"reg:0", - <&lm75>,"reg:0", <&hdc100x>,"reg:0", <&sht3x>,"reg:0", - <&ds1621>,"reg:0", <&bme680>,"reg:0", <&ccs811>,"reg:0", - <&bh1750>,"reg:0"; -+ int_pin = <&max30102>, "interrupts:0"; - bme280 = <0>,"+0"; - bmp085 = <0>,"+1"; - bmp180 = <0>,"+2"; -@@ -316,5 +335,6 @@ - sgp30 = <0>,"+16"; - ccs811 = <0>, "+17"; - bh1750 = <0>, "+18"; -+ max30102 = <0>,"+19"; - }; - }; diff --git a/target/linux/bcm27xx/patches-5.15/950-0671-misc-bcm2835_smi-Use-proper-enum-types-for-dma_-un-m.patch b/target/linux/bcm27xx/patches-5.15/950-0671-misc-bcm2835_smi-Use-proper-enum-types-for-dma_-un-m.patch deleted file mode 100644 index ff669aab3..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0671-misc-bcm2835_smi-Use-proper-enum-types-for-dma_-un-m.patch +++ /dev/null @@ -1,85 +0,0 @@ -From db1007fae024ae65b6f8a28988ce9d87c7d92995 Mon Sep 17 00:00:00 2001 -From: Nathan Chancellor -Date: Mon, 31 Jan 2022 17:12:10 -0700 -Subject: [PATCH] misc: bcm2835_smi: Use proper enum types for - dma_{,un}map_single() - -Clang warns: - - drivers/misc/bcm2835_smi.c:692:4: warning: implicit conversion from enumeration type 'enum dma_transfer_direction' to different enumeration type 'enum dma_data_direction' [-Wenum-conversion] - DMA_MEM_TO_DEV); - ^~~~~~~~~~~~~~~ - ./include/linux/dma-mapping.h:406:66: note: expanded from macro 'dma_map_single' - #define dma_map_single(d, a, s, r) dma_map_single_attrs(d, a, s, r, 0) - ~~~~~~~~~~~~~~~~~~~~ ^ - drivers/misc/bcm2835_smi.c:705:35: warning: implicit conversion from enumeration type 'enum dma_transfer_direction' to different enumeration type 'enum dma_data_direction' [-Wenum-conversion] - (inst->dev, phy_addr, n_bytes, DMA_MEM_TO_DEV); - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~ - ./include/linux/dma-mapping.h:407:70: note: expanded from macro 'dma_unmap_single' - #define dma_unmap_single(d, a, s, r) dma_unmap_single_attrs(d, a, s, r, 0) - ~~~~~~~~~~~~~~~~~~~~~~ ^ - drivers/misc/bcm2835_smi.c:751:12: warning: implicit conversion from enumeration type 'enum dma_transfer_direction' to different enumeration type 'enum dma_data_direction' [-Wenum-conversion] - DMA_DEV_TO_MEM); - ^~~~~~~~~~~~~~~ - ./include/linux/dma-mapping.h:406:66: note: expanded from macro 'dma_map_single' - #define dma_map_single(d, a, s, r) dma_map_single_attrs(d, a, s, r, 0) - ~~~~~~~~~~~~~~~~~~~~ ^ - drivers/misc/bcm2835_smi.c:761:50: warning: implicit conversion from enumeration type 'enum dma_transfer_direction' to different enumeration type 'enum dma_data_direction' [-Wenum-conversion] - dma_unmap_single(inst->dev, phy_addr, n_bytes, DMA_DEV_TO_MEM); - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~ - ./include/linux/dma-mapping.h:407:70: note: expanded from macro 'dma_unmap_single' - #define dma_unmap_single(d, a, s, r) dma_unmap_single_attrs(d, a, s, r, 0) - ~~~~~~~~~~~~~~~~~~~~~~ ^ - 4 warnings generated. - -Use the proper enumerated type to clear up the warning. There is not -actually a bug here because the enumerated types have the same integer -value: - -DMA_MEM_TO_DEV = DMA_TO_DEVICE = 1 -DMA_DEV_TO_MEM = DMA_FROM_DEVICE = 2 - -Fixes: 93254d0f7bc8 ("Add SMI driver") -Signed-off-by: Nathan Chancellor ---- - drivers/misc/bcm2835_smi.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - ---- a/drivers/misc/bcm2835_smi.c -+++ b/drivers/misc/bcm2835_smi.c -@@ -689,7 +689,7 @@ void bcm2835_smi_write_buf( - inst->dev, - (void *)buf, - n_bytes, -- DMA_MEM_TO_DEV); -+ DMA_TO_DEVICE); - struct scatterlist *sgl = - smi_scatterlist_from_buffer(inst, phy_addr, n_bytes, - &inst->buffer_sgl); -@@ -702,7 +702,7 @@ void bcm2835_smi_write_buf( - smi_dma_write_sgl(inst, sgl, 1, n_bytes); - - dma_unmap_single -- (inst->dev, phy_addr, n_bytes, DMA_MEM_TO_DEV); -+ (inst->dev, phy_addr, n_bytes, DMA_TO_DEVICE); - } else if (n_bytes) { - smi_write_fifo(inst, (uint32_t *) buf, n_bytes); - } -@@ -748,7 +748,7 @@ void bcm2835_smi_read_buf(struct bcm2835 - if (n_bytes > DMA_THRESHOLD_BYTES) { - dma_addr_t phy_addr = dma_map_single(inst->dev, - buf, n_bytes, -- DMA_DEV_TO_MEM); -+ DMA_FROM_DEVICE); - struct scatterlist *sgl = smi_scatterlist_from_buffer( - inst, phy_addr, n_bytes, - &inst->buffer_sgl); -@@ -758,7 +758,7 @@ void bcm2835_smi_read_buf(struct bcm2835 - goto out; - } - smi_dma_read_sgl(inst, sgl, 1, n_bytes); -- dma_unmap_single(inst->dev, phy_addr, n_bytes, DMA_DEV_TO_MEM); -+ dma_unmap_single(inst->dev, phy_addr, n_bytes, DMA_FROM_DEVICE); - } else if (n_bytes) { - smi_read_fifo(inst, (uint32_t *)buf, n_bytes); - } diff --git a/target/linux/bcm27xx/patches-5.15/950-0672-ASoC-ma120x0p-Remove-unnecessary-const-specifier.patch b/target/linux/bcm27xx/patches-5.15/950-0672-ASoC-ma120x0p-Remove-unnecessary-const-specifier.patch deleted file mode 100644 index ac4202820..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0672-ASoC-ma120x0p-Remove-unnecessary-const-specifier.patch +++ /dev/null @@ -1,38 +0,0 @@ -From e7992089f1727409eca46e6244f7dd71d4e01179 Mon Sep 17 00:00:00 2001 -From: Nathan Chancellor -Date: Mon, 31 Jan 2022 17:15:35 -0700 -Subject: [PATCH] ASoC: ma120x0p: Remove unnecessary const specifier - -Clang warns: - - sound/soc/codecs/ma120x0p.c:891:14: warning: duplicate 'const' declaration specifier [-Wduplicate-decl-specifier] - static const SOC_VALUE_ENUM_SINGLE_DECL(pwr_mode_ctrl, - ^ - ./include/sound/soc.h:362:2: note: expanded from macro 'SOC_VALUE_ENUM_SINGLE_DECL' - SOC_VALUE_ENUM_DOUBLE_DECL(name, xreg, xshift, xshift, xmask, xtexts, xvalues) - ^ - ./include/sound/soc.h:359:2: note: expanded from macro 'SOC_VALUE_ENUM_DOUBLE_DECL' - const struct soc_enum name = SOC_VALUE_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, \ - ^ - 1 warning generated. - -SOC_VALUE_ENUM_DOUBLE_DECL already has a const specifier. Remove the duplicate -const to clean up the warning. - -Fixes: 42444979e710 ("Add support for all the downstream rpi sound card drivers") -Signed-off-by: Nathan Chancellor ---- - sound/soc/codecs/ma120x0p.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/sound/soc/codecs/ma120x0p.c -+++ b/sound/soc/codecs/ma120x0p.c -@@ -888,7 +888,7 @@ static const int pwr_mode_values[] = { - 0x70, - }; - --static const SOC_VALUE_ENUM_SINGLE_DECL(pwr_mode_ctrl, -+static SOC_VALUE_ENUM_SINGLE_DECL(pwr_mode_ctrl, - ma_pm_man__a, 0, 0x70, - pwr_mode_texts, - pwr_mode_values); diff --git a/target/linux/bcm27xx/patches-5.15/950-0673-ASoC-bcm-allo-piano-dac-plus-Remove-unnecessary-cons.patch b/target/linux/bcm27xx/patches-5.15/950-0673-ASoC-bcm-allo-piano-dac-plus-Remove-unnecessary-cons.patch deleted file mode 100644 index a98d09e94..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0673-ASoC-bcm-allo-piano-dac-plus-Remove-unnecessary-cons.patch +++ /dev/null @@ -1,75 +0,0 @@ -From fb7adf252e4813f86d2871448a0bdb586bfcd1f1 Mon Sep 17 00:00:00 2001 -From: Nathan Chancellor -Date: Mon, 31 Jan 2022 17:20:55 -0700 -Subject: [PATCH] ASoC: bcm: allo-piano-dac-plus: Remove unnecessary - const specifiers - -Clang warns: - - sound/soc/bcm/allo-piano-dac-plus.c:66:14: warning: duplicate 'const' declaration specifier [-Wduplicate-decl-specifier] - static const SOC_ENUM_SINGLE_DECL(allo_piano_mode_enum, - ^ - ./include/sound/soc.h:355:2: note: expanded from macro 'SOC_ENUM_SINGLE_DECL' - SOC_ENUM_DOUBLE_DECL(name, xreg, xshift, xshift, xtexts) - ^ - ./include/sound/soc.h:352:2: note: expanded from macro 'SOC_ENUM_DOUBLE_DECL' - const struct soc_enum name = SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, \ - ^ - sound/soc/bcm/allo-piano-dac-plus.c:75:14: warning: duplicate 'const' declaration specifier [-Wduplicate-decl-specifier] - static const SOC_ENUM_SINGLE_DECL(allo_piano_dual_mode_enum, - ^ - ./include/sound/soc.h:355:2: note: expanded from macro 'SOC_ENUM_SINGLE_DECL' - SOC_ENUM_DOUBLE_DECL(name, xreg, xshift, xshift, xtexts) - ^ - ./include/sound/soc.h:352:2: note: expanded from macro 'SOC_ENUM_DOUBLE_DECL' - const struct soc_enum name = SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, \ - ^ - sound/soc/bcm/allo-piano-dac-plus.c:96:14: warning: duplicate 'const' declaration specifier [-Wduplicate-decl-specifier] - static const SOC_ENUM_SINGLE_DECL(allo_piano_enum, - ^ - ./include/sound/soc.h:355:2: note: expanded from macro 'SOC_ENUM_SINGLE_DECL' - SOC_ENUM_DOUBLE_DECL(name, xreg, xshift, xshift, xtexts) - ^ - ./include/sound/soc.h:352:2: note: expanded from macro 'SOC_ENUM_DOUBLE_DECL' - const struct soc_enum name = SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, \ - ^ - 3 warnings generated. - -SOC_VALUE_ENUM_DOUBLE_DECL already has a const specifier. Remove the duplicate -const specifiers to clean up the warnings. - -Fixes: 42444979e710 ("Add support for all the downstream rpi sound card drivers") -Signed-off-by: Nathan Chancellor ---- - sound/soc/bcm/allo-piano-dac-plus.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/sound/soc/bcm/allo-piano-dac-plus.c -+++ b/sound/soc/bcm/allo-piano-dac-plus.c -@@ -63,7 +63,7 @@ static const char * const allo_piano_mod - "2.2", - }; - --static const SOC_ENUM_SINGLE_DECL(allo_piano_mode_enum, -+static SOC_ENUM_SINGLE_DECL(allo_piano_mode_enum, - 0, 0, allo_piano_mode_texts); - - static const char * const allo_piano_dual_mode_texts[] = { -@@ -72,7 +72,7 @@ static const char * const allo_piano_dua - "Dual-Stereo", - }; - --static const SOC_ENUM_SINGLE_DECL(allo_piano_dual_mode_enum, -+static SOC_ENUM_SINGLE_DECL(allo_piano_dual_mode_enum, - 0, 0, allo_piano_dual_mode_texts); - - static const char * const allo_piano_dsp_low_pass_texts[] = { -@@ -93,7 +93,7 @@ static const char * const allo_piano_dsp - "200", - }; - --static const SOC_ENUM_SINGLE_DECL(allo_piano_enum, -+static SOC_ENUM_SINGLE_DECL(allo_piano_enum, - 0, 0, allo_piano_dsp_low_pass_texts); - - static int __snd_allo_piano_dsp_program(struct snd_soc_pcm_runtime *rtd, diff --git a/target/linux/bcm27xx/patches-5.15/950-0679-overlays-Add-spi0-0cs-overlay.patch b/target/linux/bcm27xx/patches-5.15/950-0679-overlays-Add-spi0-0cs-overlay.patch deleted file mode 100644 index 0419c6be5..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0679-overlays-Add-spi0-0cs-overlay.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 623f4a862134202e9f0705812cabe2abef6c2f9b Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 31 Jan 2022 21:01:25 +0000 -Subject: [PATCH] overlays: Add spi0-0cs overlay - -An overlay to enable SPI0 without claiming any chip select GPIOs. - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 8 ++++ - .../boot/dts/overlays/spi0-0cs-overlay.dts | 39 +++++++++++++++++++ - 3 files changed, 48 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/spi0-0cs-overlay.dts - ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -195,6 +195,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ - spi-gpio35-39.dtbo \ - spi-gpio40-45.dtbo \ - spi-rtc.dtbo \ -+ spi0-0cs.dtbo \ - spi0-1cs.dtbo \ - spi0-2cs.dtbo \ - spi1-1cs.dtbo \ ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -3115,6 +3115,14 @@ Params: ds3232 Select t - cs_high This device requires an active-high CS - - -+Name: spi0-0cs -+Info: Don't claim any CS pins for SPI0. Requires a device with its chip -+ select permanently enabled, but frees a GPIO for e.g. a DPI display. -+Load: dtoverlay=spi0-0cs,= -+Params: no_miso Don't claim and use the MISO pin (9), freeing -+ it for other uses. -+ -+ - Name: spi0-1cs - Info: Only use one CS pin for SPI0 - Load: dtoverlay=spi0-1cs,= ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/spi0-0cs-overlay.dts -@@ -0,0 +1,39 @@ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835"; -+ -+ fragment@0 { -+ target = <&spi0_cs_pins>; -+ frag0: __overlay__ { -+ brcm,pins; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&spi0>; -+ __overlay__ { -+ cs-gpios; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&spidev1>; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; -+ -+ fragment@3 { -+ target = <&spi0_pins>; -+ __dormant__ { -+ brcm,pins = <10 11>; -+ }; -+ }; -+ -+ __overrides__ { -+ no_miso = <0>,"=3"; -+ }; -+}; diff --git a/target/linux/bcm27xx/patches-5.15/950-0680-dtoverlays-Rework-vc4-kms-dpi-overlays-to-remove-dup.patch b/target/linux/bcm27xx/patches-5.15/950-0680-dtoverlays-Rework-vc4-kms-dpi-overlays-to-remove-dup.patch deleted file mode 100644 index 1aa699f3f..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0680-dtoverlays-Rework-vc4-kms-dpi-overlays-to-remove-dup.patch +++ /dev/null @@ -1,545 +0,0 @@ -From 2cc810fd22f30acabbf5e6726e003c5da56d3212 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 31 Jan 2022 17:25:19 +0000 -Subject: [PATCH] dtoverlays: Rework vc4-kms-dpi overlays to remove - duplication - -Removes all the common panel, dpi, and backlight configuration -from the individual vc4-kms-dpi-* files into vc4-kms-dpi.dtsi. - -Creates a new vc4-kms-dpi-panel-overlay.dts for preconfigured -panels, with overrides to enable the different panel configurations. - -Deprecates vc4-kms-dpi-at056tn53v1 as superceded by vc4-kms-dpi-panel. -vc4-kms-kippah-7inch not deprecated for now as it is likely to be -in wider use than at056tn53v1. - -Signed-off-by: Dave Stevenson ---- - arch/arm/boot/dts/overlays/Makefile | 2 +- - arch/arm/boot/dts/overlays/README | 33 ++++- - arch/arm/boot/dts/overlays/overlay_map.dts | 4 + - .../vc4-kms-dpi-at056tn53v1-overlay.dts | 44 ------ - .../overlays/vc4-kms-dpi-generic-overlay.dts | 138 ++++-------------- - .../overlays/vc4-kms-dpi-panel-overlay.dts | 62 ++++++++ - arch/arm/boot/dts/overlays/vc4-kms-dpi.dtsi | 109 ++++++++++++++ - .../overlays/vc4-kms-kippah-7inch-overlay.dts | 27 +--- - 8 files changed, 235 insertions(+), 184 deletions(-) - delete mode 100644 arch/arm/boot/dts/overlays/vc4-kms-dpi-at056tn53v1-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/vc4-kms-dpi-panel-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/vc4-kms-dpi.dtsi - ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -234,8 +234,8 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ - upstream-pi4.dtbo \ - vc4-fkms-v3d.dtbo \ - vc4-fkms-v3d-pi4.dtbo \ -- vc4-kms-dpi-at056tn53v1.dtbo \ - vc4-kms-dpi-generic.dtbo \ -+ vc4-kms-dpi-panel.dtbo \ - vc4-kms-dsi-7inch.dtbo \ - vc4-kms-dsi-lt070me05000.dtbo \ - vc4-kms-dsi-lt070me05000-v2.dtbo \ ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -3624,10 +3624,8 @@ Params: cma-512 CMA is 5 - - - Name: vc4-kms-dpi-at056tn53v1 --Info: Enable an Innolux 5.6in VGA TFT connected to DPI interface under KMS. -- Requires vc4-kms-v3d to be loaded. --Load: dtoverlay=vc4-kms-dpi-at056tn53v1 --Params: -+Info: This overlay is now deprecated - see vc4-kms-dpi-panel,at056tn53v1 -+Load: - - - Name: vc4-kms-dpi-generic -@@ -3659,6 +3657,33 @@ Params: clock-frequency Display - backlight-gpio Defines a GPIO to be used for backlight control - (default of none). - backlight-pwm Defines a PWM channel to be used for backlight -+ control (default of none). NB Disables audio -+ headphone output as that also uses PWM. -+ backlight-pwm-chan Choose channel on &pwm node for backlight -+ control. -+ (default 0). -+ backlight-pwm-gpio GPIO pin to be used for the PWM backlight. See -+ pwm-2chan for valid options. -+ (default 18 - note this can only work with -+ rgb666-padhi). -+ backlight-pwm-func Pin function of GPIO used for the PWM -+ backlight. -+ See pwm-2chan for valid options. -+ (default 2). -+ backlight-def-brightness -+ Set the default brightness. Normal range 1-16. -+ (default 16). -+ -+ -+Name: vc4-kms-dpi-panel -+Info: Enable a preconfigured KMS DPI panel. -+ Requires vc4-kms-v3d to be loaded. -+Load: dtoverlay=vc4-kms-dpi-panel,= -+Params: at056tn53v1 Enable an Innolux 5.6in VGA TFT -+ kippah-7inch Enable an Adafruit Kippah with 7inch panel. -+ backlight-gpio Defines a GPIO to be used for backlight control -+ (default of none). -+ backlight-pwm Defines a PWM channel to be used for backlight - control (default of none). NB Disables audio - headphone output as that also uses PWM. - backlight-pwm-chan Choose channel on &pwm node for backlight ---- a/arch/arm/boot/dts/overlays/overlay_map.dts -+++ b/arch/arm/boot/dts/overlays/overlay_map.dts -@@ -151,6 +151,10 @@ - bcm2711; - }; - -+ vc4-kms-dpi-at056tn53v1 { -+ deprecated = "use vc4-kms-dpi-panel,at056tn53v1"; -+ }; -+ - vc4-kms-v3d { - bcm2835; - bcm2711 = "vc4-kms-v3d-pi4"; ---- a/arch/arm/boot/dts/overlays/vc4-kms-dpi-at056tn53v1-overlay.dts -+++ /dev/null -@@ -1,44 +0,0 @@ --/* -- * vc4-kms-dpi-at056tn53v1-overlay.dts -- */ -- --/dts-v1/; --/plugin/; -- --#include --#include -- --/ { -- compatible = "brcm,bcm2835"; -- -- fragment@0 { -- target-path = "/"; -- __overlay__ { -- panel: panel { -- compatible = "innolux,at056tn53v1", "simple-panel"; -- -- port { -- panel_in: endpoint { -- remote-endpoint = <&dpi_out>; -- }; -- }; -- }; -- }; -- }; -- -- fragment@1 { -- target = <&dpi>; -- __overlay__ { -- status = "okay"; -- -- pinctrl-names = "default"; -- pinctrl-0 = <&dpi_18bit_cpadhi_gpio0>; -- -- port { -- dpi_out: endpoint { -- remote-endpoint = <&panel_in>; -- }; -- }; -- }; -- }; --}; ---- a/arch/arm/boot/dts/overlays/vc4-kms-dpi-generic-overlay.dts -+++ b/arch/arm/boot/dts/overlays/vc4-kms-dpi-generic-overlay.dts -@@ -5,124 +5,43 @@ - /dts-v1/; - /plugin/; - --#include --#include -+#include "vc4-kms-dpi.dtsi" - - / { - compatible = "brcm,bcm2835"; - - fragment@0 { -- target-path = "/"; -- __overlay__ { -- panel: panel { -- compatible = "panel-dpi"; -- -- width-mm = <154>; -- height-mm = <83>; -- bus-format = <0x1009>; -- -- timing: panel-timing { -- clock-frequency = <29500000>; -- hactive = <800>; -- hfront-porch = <24>; -- hsync-len = <72>; -- hback-porch = <96>; -- hsync-active = <1>; -- vactive = <480>; -- vfront-porch = <3>; -- vsync-len = <10>; -- vback-porch = <7>; -- vsync-active = <1>; -- -- de-active = <1>; -- pixelclk-active = <1>; -- }; -- -- port { -- panel_in: endpoint { -- remote-endpoint = <&dpi_out>; -- }; -- }; -- }; -- }; -- }; -- -- fragment@1 { -- target = <&dpi>; -- dpi_node: __overlay__ { -- status = "okay"; -- -- pinctrl-names = "default"; -- pinctrl-0 = <&dpi_18bit_gpio0>; -- -- port { -- dpi_out: endpoint { -- remote-endpoint = <&panel_in>; -- }; -- }; -- }; -- }; -- -- fragment@2 { -- target = <&panel>; -- __dormant__ { -- backlight = <&backlight>; -- }; -- }; -- -- fragment@3 { -- target-path = "/"; -- __dormant__ { -- backlight: backlight { -- compatible = "gpio-backlight"; -- gpios = <&gpio 255 GPIO_ACTIVE_HIGH>; -- }; -- }; -- }; -- -- fragment@4 { - target = <&panel>; -- __dormant__ { -- backlight = <&backlight_pwm>; -- }; -- }; -- -- fragment@5 { -- target-path = "/"; -- __dormant__ { -- backlight_pwm: backlight_pwm { -- compatible = "pwm-backlight"; -- brightness-levels = <0 6 8 12 16 24 32 40 48 64 96 128 160 192 224 255>; -- default-brightness-level = <16>; -- pwms = <&pwm 0 200000>; -- }; -- }; -- }; -+ __overlay__ { -+ compatible = "panel-dpi"; - -- fragment@6 { -- target = <&pwm>; -- __dormant__ { -- pinctrl-names = "default"; -- pinctrl-0 = <&pwm_pins>; -- assigned-clock-rates = <1000000>; -- status = "okay"; -- }; -- }; -+ width-mm = <154>; -+ height-mm = <83>; -+ bus-format = <0x1009>; -+ -+ timing: panel-timing { -+ clock-frequency = <29500000>; -+ hactive = <800>; -+ hfront-porch = <24>; -+ hsync-len = <72>; -+ hback-porch = <96>; -+ hsync-active = <1>; -+ vactive = <480>; -+ vfront-porch = <3>; -+ vsync-len = <10>; -+ vback-porch = <7>; -+ vsync-active = <1>; - -- fragment@7 { -- target = <&gpio>; -- __dormant__ { -- pwm_pins: pwm_pins { -- brcm,pins = <18>; -- brcm,function = <2>; /* Alt5 */ -+ de-active = <1>; -+ pixelclk-active = <1>; - }; - }; - }; - -- fragment@8 { -- target = <&audio>; -- __dormant__ { -- brcm,disable-headphones; -+ fragment@1 { -+ target = <&dpi>; -+ __overlay__ { -+ pinctrl-0 = <&dpi_18bit_gpio0>; - }; - }; - -@@ -151,12 +70,5 @@ - rgb888 = <&panel>, "bus-format:0=0x100a", - <&dpi_node>, "pinctrl-0:0=",<&dpi_gpio0>; - bus-format = <&panel>, "bus-format:0"; -- backlight-gpio = <0>, "+2+3", -- <&backlight>, "gpios:4"; -- backlight-pwm = <0>, "+4+5+6+7+8"; -- backlight-pwm-chan = <&backlight_pwm>, "pwms:4"; -- backlight-pwm-gpio = <&pwm_pins>, "brcm,pins:0"; -- backlight-pwm-func = <&pwm_pins>, "brcm,function:0"; -- backlight-def-brightness = <&backlight_pwm>, "default-brightness-level:0"; - }; - }; ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/vc4-kms-dpi-panel-overlay.dts -@@ -0,0 +1,62 @@ -+/* -+ * vc4-kms-dpi-panel-overlay.dts -+ * Support for any predefined DPI panel. -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+#include "vc4-kms-dpi.dtsi" -+ -+/ { -+ compatible = "brcm,bcm2835"; -+ -+ fragment@0 { -+ target = <&panel>; -+ __dormant__ { -+ compatible = "innolux,at056tn53v1", "simple-panel"; -+ }; -+ }; -+ fragment@1 { -+ target = <&panel>; -+ __dormant__ { -+ compatible = "ontat,yx700wv03", "simple-panel"; -+ }; -+ }; -+ -+ fragment@90 { -+ target = <&dpi>; -+ __dormant__ { -+ pinctrl-0 = <&dpi_18bit_cpadhi_gpio0>; -+ }; -+ }; -+ fragment@91 { -+ target = <&dpi>; -+ __dormant__ { -+ pinctrl-0 = <&dpi_18bit_gpio0>; -+ }; -+ }; -+ fragment@92 { -+ target = <&dpi>; -+ __dormant__ { -+ pinctrl-0 = <&dpi_gpio0>; -+ }; -+ }; -+ fragment@93 { -+ target = <&dpi>; -+ __dormant__ { -+ pinctrl-0 = <&dpi_16bit_cpadhi_gpio0>; -+ }; -+ }; -+ fragment@94 { -+ target = <&dpi>; -+ __dormant__ { -+ pinctrl-0 = <&dpi_16bit_gpio0>; -+ }; -+ }; -+ -+ __overrides__ { -+ at056tn53v1 = <0>, "+0+90"; -+ kippah-7inch = <0>, "+1+91"; -+ }; -+}; ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/vc4-kms-dpi.dtsi -@@ -0,0 +1,109 @@ -+/* -+ * vc4-kms-dpi.dtsi -+ */ -+ -+#include -+#include -+ -+/ { -+ fragment@100 { -+ target-path = "/"; -+ __overlay__ { -+ panel: panel { -+ port { -+ panel_in: endpoint { -+ remote-endpoint = <&dpi_out>; -+ }; -+ }; -+ }; -+ }; -+ }; -+ -+ fragment@101 { -+ target = <&dpi>; -+ dpi_node: __overlay__ { -+ status = "okay"; -+ -+ pinctrl-names = "default"; -+ -+ port { -+ dpi_out: endpoint { -+ remote-endpoint = <&panel_in>; -+ }; -+ }; -+ }; -+ }; -+ -+ fragment@102 { -+ target = <&panel>; -+ __dormant__ { -+ backlight = <&backlight>; -+ }; -+ }; -+ -+ fragment@103 { -+ target-path = "/"; -+ __dormant__ { -+ backlight: backlight { -+ compatible = "gpio-backlight"; -+ gpios = <&gpio 255 GPIO_ACTIVE_HIGH>; -+ }; -+ }; -+ }; -+ -+ fragment@104 { -+ target = <&panel>; -+ __dormant__ { -+ backlight = <&backlight_pwm>; -+ }; -+ }; -+ -+ fragment@105 { -+ target-path = "/"; -+ __dormant__ { -+ backlight_pwm: backlight_pwm { -+ compatible = "pwm-backlight"; -+ brightness-levels = <0 6 8 12 16 24 32 40 48 64 96 128 160 192 224 255>; -+ default-brightness-level = <16>; -+ pwms = <&pwm 0 200000>; -+ }; -+ }; -+ }; -+ -+ fragment@106 { -+ target = <&pwm>; -+ __dormant__ { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pwm_pins>; -+ assigned-clock-rates = <1000000>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@107 { -+ target = <&gpio>; -+ __dormant__ { -+ pwm_pins: pwm_pins { -+ brcm,pins = <18>; -+ brcm,function = <2>; /* Alt5 */ -+ }; -+ }; -+ }; -+ -+ fragment@108 { -+ target = <&audio>; -+ __dormant__ { -+ brcm,disable-headphones; -+ }; -+ }; -+ -+ __overrides__ { -+ backlight-gpio = <0>, "+102+103", -+ <&backlight>, "gpios:4"; -+ backlight-pwm = <0>, "+104+105+106+107+108"; -+ backlight-pwm-chan = <&backlight_pwm>, "pwms:4"; -+ backlight-pwm-gpio = <&pwm_pins>, "brcm,pins:0"; -+ backlight-pwm-func = <&pwm_pins>, "brcm,function:0"; -+ backlight-def-brightness = <&backlight_pwm>, "default-brightness-level:0"; -+ }; -+}; ---- a/arch/arm/boot/dts/overlays/vc4-kms-kippah-7inch-overlay.dts -+++ b/arch/arm/boot/dts/overlays/vc4-kms-kippah-7inch-overlay.dts -@@ -1,43 +1,26 @@ - /* -- * vc4-kms-v3d-overlay.dts -+ * vc4-kms-kippah-7inch-overlay.dts - */ - - /dts-v1/; - /plugin/; - --#include -+#include "vc4-kms-dpi.dtsi" - - / { - compatible = "brcm,bcm2835"; - - fragment@0 { -- target-path = "/"; -- __overlay__ { -- panel: panel { -- compatible = "ontat,yx700wv03", "simple-panel"; -- -- port { -- panel_in: endpoint { -- remote-endpoint = <&dpi_out>; -- }; -- }; -- }; -+ target = <&panel>; -+ __overlay__ { -+ compatible = "ontat,yx700wv03", "simple-panel"; - }; - }; - - fragment@1 { - target = <&dpi>; - __overlay__ { -- status = "okay"; -- -- pinctrl-names = "default"; - pinctrl-0 = <&dpi_18bit_gpio0>; -- -- port { -- dpi_out: endpoint@0 { -- remote-endpoint = <&panel_in>; -- }; -- }; - }; - }; - }; diff --git a/target/linux/bcm27xx/patches-5.15/950-0682-media-uapi-add-MEDIA_BUS_FMT_RGB565_1X24_CPADHI.patch b/target/linux/bcm27xx/patches-5.15/950-0682-media-uapi-add-MEDIA_BUS_FMT_RGB565_1X24_CPADHI.patch deleted file mode 100644 index 245fcfb8e..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0682-media-uapi-add-MEDIA_BUS_FMT_RGB565_1X24_CPADHI.patch +++ /dev/null @@ -1,31 +0,0 @@ -From b27bc74f47f9e3ef6fce066b3430a6cb59c10909 Mon Sep 17 00:00:00 2001 -From: Chris Morgan -Date: Fri, 28 Jan 2022 17:38:40 -0600 -Subject: [PATCH] media: uapi: add MEDIA_BUS_FMT_RGB565_1X24_CPADHI - -Add the MEDIA_BUS_FMT_RGB565_1X24_CPADHI format used by the Geekworm -MZP280 panel for the Raspberry Pi. - -Signed-off-by: Chris Morgan ---- - include/uapi/linux/media-bus-format.h | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/include/uapi/linux/media-bus-format.h -+++ b/include/uapi/linux/media-bus-format.h -@@ -34,13 +34,14 @@ - - #define MEDIA_BUS_FMT_FIXED 0x0001 - --/* RGB - next is 0x1020 */ -+/* RGB - next is 0x1021 */ - #define MEDIA_BUS_FMT_RGB444_1X12 0x1016 - #define MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE 0x1001 - #define MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE 0x1002 - #define MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE 0x1003 - #define MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE 0x1004 - #define MEDIA_BUS_FMT_RGB565_1X16 0x1017 -+#define MEDIA_BUS_FMT_RGB565_1X24_CPADHI 0x1020 - #define MEDIA_BUS_FMT_BGR565_2X8_BE 0x1005 - #define MEDIA_BUS_FMT_BGR565_2X8_LE 0x1006 - #define MEDIA_BUS_FMT_RGB565_2X8_BE 0x1007 diff --git a/target/linux/bcm27xx/patches-5.15/950-0687-overlays-README-Deprecate-vc4-kms-kippah-7inch.patch b/target/linux/bcm27xx/patches-5.15/950-0687-overlays-README-Deprecate-vc4-kms-kippah-7inch.patch deleted file mode 100644 index 239f49ba9..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0687-overlays-README-Deprecate-vc4-kms-kippah-7inch.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 242dda559ca7f40342fb4266c3114e4e1d1d6269 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 2 Feb 2022 09:11:20 +0000 -Subject: [PATCH] overlays: README: Deprecate vc4-kms-kippah-7inch - -The vc4-kms-kippah-7inch overlay has been replaced by the container -overlay vc4-kms-dpi-panel, using the "kippah-7inch" parameter. The -original overlay has been retained for now to avoid breaking -existing installations, but that doesn't make it any less deprecated, -so update the README accordingly. - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/overlays/README | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -3737,10 +3737,8 @@ Params: - - - Name: vc4-kms-kippah-7inch --Info: Enable the Adafruit DPI Kippah with the 7" Ontat panel attached. -- Requires vc4-kms-v3d to be loaded. --Load: dtoverlay=vc4-kms-kippah-7inch --Params: -+Info: This overlay is now deprecated - see vc4-kms-dpi-panel,kippah-7inch -+Load: - - - Name: vc4-kms-v3d diff --git a/target/linux/bcm27xx/patches-5.15/950-0690-overlays-Add-rotate-property-to-vc4-kms-dpi-panel.patch b/target/linux/bcm27xx/patches-5.15/950-0690-overlays-Add-rotate-property-to-vc4-kms-dpi-panel.patch deleted file mode 100644 index c9c9e46d3..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0690-overlays-Add-rotate-property-to-vc4-kms-dpi-panel.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 4aad06862bbd0a9871b747fbc7decf94a4815a57 Mon Sep 17 00:00:00 2001 -From: Chris Morgan -Date: Wed, 2 Feb 2022 10:42:00 -0600 -Subject: [PATCH] overlays: Add rotate property to vc4-kms-dpi-panel - -Allow a user to specify the panel rotation in devicetree as 0, 90, -180, or 270 by setting a parameter. - -Signed-off-by: Chris Morgan ---- - arch/arm/boot/dts/overlays/README | 2 ++ - arch/arm/boot/dts/overlays/vc4-kms-dpi.dtsi | 2 ++ - 2 files changed, 4 insertions(+) - ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -3673,6 +3673,7 @@ Params: clock-frequency Display - backlight-def-brightness - Set the default brightness. Normal range 1-16. - (default 16). -+ rotate Display rotation {0,90,180,270} (default 0) - - - Name: vc4-kms-dpi-panel -@@ -3700,6 +3701,7 @@ Params: at056tn53v1 Enable a - backlight-def-brightness - Set the default brightness. Normal range 1-16. - (default 16). -+ rotate Display rotation {0,90,180,270} (default 0) - - - Name: vc4-kms-dsi-7inch ---- a/arch/arm/boot/dts/overlays/vc4-kms-dpi.dtsi -+++ b/arch/arm/boot/dts/overlays/vc4-kms-dpi.dtsi -@@ -10,6 +10,7 @@ - target-path = "/"; - __overlay__ { - panel: panel { -+ rotation = <0>; - port { - panel_in: endpoint { - remote-endpoint = <&dpi_out>; -@@ -105,5 +106,6 @@ - backlight-pwm-gpio = <&pwm_pins>, "brcm,pins:0"; - backlight-pwm-func = <&pwm_pins>, "brcm,function:0"; - backlight-def-brightness = <&backlight_pwm>, "default-brightness-level:0"; -+ rotate = <&panel>, "rotation:0"; - }; - }; diff --git a/target/linux/bcm27xx/patches-5.15/950-0691-overlays-Add-Geekworm-mzp280-to-vc4-kms-dpi-panel.patch b/target/linux/bcm27xx/patches-5.15/950-0691-overlays-Add-Geekworm-mzp280-to-vc4-kms-dpi-panel.patch deleted file mode 100644 index b83e9bb52..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0691-overlays-Add-Geekworm-mzp280-to-vc4-kms-dpi-panel.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 152f82d69308b96b0e838918387fa70c26a52454 Mon Sep 17 00:00:00 2001 -From: Chris Morgan -Date: Wed, 2 Feb 2022 10:43:32 -0600 -Subject: [PATCH] overlays: Add Geekworm mzp280 to vc4-kms-dpi-panel - -Add support for the Geekworm mzp280 DPI panel to the generic -vc4-kms-dpi-panel overlay. - -Signed-off-by: Chris Morgan ---- - arch/arm/boot/dts/overlays/README | 1 + - arch/arm/boot/dts/overlays/vc4-kms-dpi-panel-overlay.dts | 7 +++++++ - 2 files changed, 8 insertions(+) - ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -3682,6 +3682,7 @@ Info: Enable a preconfigured KMS DPI p - Load: dtoverlay=vc4-kms-dpi-panel,= - Params: at056tn53v1 Enable an Innolux 5.6in VGA TFT - kippah-7inch Enable an Adafruit Kippah with 7inch panel. -+ mzp280 Enable a Geekworm MZP280 panel. - backlight-gpio Defines a GPIO to be used for backlight control - (default of none). - backlight-pwm Defines a PWM channel to be used for backlight ---- a/arch/arm/boot/dts/overlays/vc4-kms-dpi-panel-overlay.dts -+++ b/arch/arm/boot/dts/overlays/vc4-kms-dpi-panel-overlay.dts -@@ -23,6 +23,12 @@ - compatible = "ontat,yx700wv03", "simple-panel"; - }; - }; -+ fragment@2 { -+ target = <&panel>; -+ __dormant__ { -+ compatible = "geekworm,mzp280", "simple-panel"; -+ }; -+ }; - - fragment@90 { - target = <&dpi>; -@@ -58,5 +64,6 @@ - __overrides__ { - at056tn53v1 = <0>, "+0+90"; - kippah-7inch = <0>, "+1+91"; -+ mzp280 = <0>, "+2+93"; - }; - }; diff --git a/target/linux/bcm27xx/patches-5.15/950-0697-dtoverlays-Add-overlays-for-Pimoroni-Hyperpixel-disp.patch b/target/linux/bcm27xx/patches-5.15/950-0697-dtoverlays-Add-overlays-for-Pimoroni-Hyperpixel-disp.patch deleted file mode 100644 index 74d35109f..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0697-dtoverlays-Add-overlays-for-Pimoroni-Hyperpixel-disp.patch +++ /dev/null @@ -1,394 +0,0 @@ -From 4aa526733f16267bf28ee312e0b5b2ce3246f246 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 6 Jan 2022 13:04:34 +0000 -Subject: [PATCH] dtoverlays: Add overlays for Pimoroni Hyperpixel - displays - -Adds an overlays for the Pimoroni HyperPixel4, HyperPixel 4 -Square, and HyperPixel 2 Round DPI displays. - -We have a conflict over the use of GPIO 27 for touch screen -interrupt and SPI CLK for configuring the display on the -two HyperPixel4 displays. - -Signed-off-by: Dave Stevenson ---- - arch/arm/boot/dts/overlays/Makefile | 3 + - arch/arm/boot/dts/overlays/README | 33 +++++ - .../dts/overlays/vc4-kms-dpi-hyperpixel.dtsi | 94 +++++++++++++++ - .../vc4-kms-dpi-hyperpixel2r-overlay.dts | 114 ++++++++++++++++++ - .../vc4-kms-dpi-hyperpixel4-overlay.dts | 57 +++++++++ - .../vc4-kms-dpi-hyperpixel4sq-overlay.dts | 36 ++++++ - 6 files changed, 337 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/vc4-kms-dpi-hyperpixel.dtsi - create mode 100644 arch/arm/boot/dts/overlays/vc4-kms-dpi-hyperpixel2r-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/vc4-kms-dpi-hyperpixel4-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/vc4-kms-dpi-hyperpixel4sq-overlay.dts - ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -235,6 +235,9 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ - vc4-fkms-v3d.dtbo \ - vc4-fkms-v3d-pi4.dtbo \ - vc4-kms-dpi-generic.dtbo \ -+ vc4-kms-dpi-hyperpixel2r.dtbo \ -+ vc4-kms-dpi-hyperpixel4.dtbo \ -+ vc4-kms-dpi-hyperpixel4sq.dtbo \ - vc4-kms-dpi-panel.dtbo \ - vc4-kms-dsi-7inch.dtbo \ - vc4-kms-dsi-lt070me05000.dtbo \ ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -3676,6 +3676,39 @@ Params: clock-frequency Display - rotate Display rotation {0,90,180,270} (default 0) - - -+Name: vc4-kms-dpi-hyperpixel2r -+Info: Enable the KMS drivers for the Pimoroni HyperPixel2 Round DPI display. -+ Requires vc4-kms-v3d to be loaded. -+Load: dtoverlay=vc4-kms-dpi-hyperpixel2r,= -+Params: disable-touch Disables the touch controller -+ touchscreen-inverted-x Inverts X direction of touch controller -+ touchscreen-inverted-y Inverts Y direction of touch controller -+ touchscreen-swapped-x-y Swaps X & Y axes of touch controller -+ rotate Display rotation {0,90,180,270} (default 0) -+ -+ -+Name: vc4-kms-dpi-hyperpixel4 -+Info: Enable the KMS drivers for the Pimoroni HyperPixel4 DPI display. -+ Requires vc4-kms-v3d to be loaded. -+Load: dtoverlay=vc4-kms-dpi-hyperpixel4,= -+Params: disable-touch Disables the touch controller -+ touchscreen-inverted-x Inverts X direction of touch controller -+ touchscreen-inverted-y Inverts Y direction of touch controller -+ touchscreen-swapped-x-y Swaps X & Y axes of touch controller -+ rotate Display rotation {0,90,180,270} (default 0) -+ -+ -+Name: vc4-kms-dpi-hyperpixel4sq -+Info: Enable the KMS drivers for the Pimoroni HyperPixel4 Square DPI display. -+ Requires vc4-kms-v3d to be loaded. -+Load: dtoverlay=vc4-kms-dpi-hyperpixel4sq,= -+Params: disable-touch Disables the touch controller -+ touchscreen-inverted-x Inverts X direction of touch controller -+ touchscreen-inverted-y Inverts Y direction of touch controller -+ touchscreen-swapped-x-y Swaps X & Y axes of touch controller -+ rotate Display rotation {0,90,180,270} (default 0) -+ -+ - Name: vc4-kms-dpi-panel - Info: Enable a preconfigured KMS DPI panel. - Requires vc4-kms-v3d to be loaded. ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/vc4-kms-dpi-hyperpixel.dtsi -@@ -0,0 +1,94 @@ -+/* -+ * vc4-kms-dpi-hyperpixel4.dtsi -+ * Commmon initialisation for HyperPixel DPI displays -+ */ -+ -+#include -+#include -+ -+/ { -+ compatible = "brcm,bcm2835"; -+ -+ fragment@0 { -+ target-path = "/"; -+ __overlay__ { -+ spi { -+ compatible = "spi-gpio"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ pinctrl-0 = <&spi_pins>; -+ pinctrl-names = "default"; -+ -+ sck-gpios = <&gpio 27 GPIO_ACTIVE_HIGH>; -+ mosi-gpios = <&gpio 26 GPIO_ACTIVE_HIGH>; -+ cs-gpios = <&gpio 18 GPIO_ACTIVE_LOW>; -+ num-chipselects = <1>; -+ sck-idle-input; -+ -+ panel: display@0 { -+ reg = <0>; -+ /* 100 kHz */ -+ spi-max-frequency = <100000>; -+ backlight = <&backlight>; -+ rotation = <0>; -+ -+ port { -+ panel_in: endpoint { -+ remote-endpoint = <&dpi_out>; -+ }; -+ }; -+ }; -+ }; -+ -+ backlight: backlight { -+ compatible = "gpio-backlight"; -+ gpios = <&gpio 19 0>; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&dpi>; -+ __overlay__ { -+ status = "okay"; -+ -+ pinctrl-names = "default"; -+ pinctrl-0 = <&dpi_18bit_cpadhi_gpio0>; -+ -+ port { -+ dpi_out: endpoint { -+ remote-endpoint = <&panel_in>; -+ }; -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&gpio>; -+ __overlay__ { -+ spi_pins: hyperpixel4_spi_pins { -+ brcm,pins = <27 18 26>; -+ brcm,pull = ; -+ brcm,function = <0>; -+ }; -+ }; -+ }; -+ -+ fragment@3 { -+ target-path = "/"; -+ __overlay__ { -+ i2c_gpio: i2c@0 { -+ compatible = "i2c-gpio"; -+ gpios = <&gpio 10 0 /* sda */ -+ &gpio 11 0>; /* scl */ -+ i2c-gpio,delay-us = <4>; /* ~100 kHz */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ rotate = <&panel>, "rotation:0"; -+ }; -+}; ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/vc4-kms-dpi-hyperpixel2r-overlay.dts -@@ -0,0 +1,114 @@ -+/* -+ * vc4-kms-dpi-hyperpixel2r-overlay.dts -+ */ -+ -+#include -+#include -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835"; -+ -+ fragment@0 { -+ target-path = "/"; -+ __overlay__ { -+ spi { -+ compatible = "spi-gpio"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ pinctrl-0 = <&spi_pins>; -+ pinctrl-names = "default"; -+ -+ sck-gpios = <&gpio 11 GPIO_ACTIVE_HIGH>; -+ mosi-gpios = <&gpio 10 GPIO_ACTIVE_HIGH>; -+ cs-gpios = <&gpio 18 GPIO_ACTIVE_LOW>; -+ num-chipselects = <1>; -+ -+ panel: display@0 { -+ compatible = "pimoroni,hyperpixel2round"; -+ reg = <0>; -+ /* 100 kHz */ -+ spi-max-frequency = <100000>; -+ backlight = <&backlight>; -+ rotation = <0>; -+ -+ port { -+ panel_in: endpoint { -+ remote-endpoint = <&dpi_out>; -+ }; -+ }; -+ }; -+ }; -+ -+ backlight: backlight { -+ compatible = "gpio-backlight"; -+ gpios = <&gpio 19 0>; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&dpi>; -+ __overlay__ { -+ status = "okay"; -+ -+ pinctrl-names = "default"; -+ pinctrl-0 = <&dpi_18bit_cpadhi_gpio0>; -+ -+ port { -+ dpi_out: endpoint { -+ remote-endpoint = <&panel_in>; -+ }; -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&gpio>; -+ __overlay__ { -+ spi_pins: hyperpixel4_spi_pins { -+ brcm,pins = <27 18 26>; -+ brcm,pull = ; -+ brcm,function = <0>; -+ }; -+ }; -+ }; -+ -+ fragment@3 { -+ target-path = "/"; -+ __overlay__ { -+ i2c_gpio: i2c@0 { -+ compatible = "i2c-gpio"; -+ status = "disabled"; -+ -+ gpios = <&gpio 10 GPIO_ACTIVE_HIGH /* sda */ -+ &gpio 11 GPIO_ACTIVE_HIGH>; /* scl */ -+ i2c-gpio,delay-us = <4>; /* ~100 kHz */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ polytouch: edt-ft5x06@15 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "edt,edt-ft5406"; -+ reg = <0x15>; -+ interrupt-parent = <&gpio>; -+ interrupts = <27 0x02>; -+ touchscreen-size-x = <240>; -+ touchscreen-size-y = <240>; -+ }; -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ disable-touch = <0>,"-3"; -+ touchscreen-inverted-x = <&polytouch>,"touchscreen-inverted-x?"; -+ touchscreen-inverted-y = <&polytouch>,"touchscreen-inverted-y!"; -+ touchscreen-swapped-x-y = <&polytouch>,"touchscreen-swapped-x-y!"; -+ rotate = <&panel>, "rotation:0"; -+ }; -+ -+}; ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/vc4-kms-dpi-hyperpixel4-overlay.dts -@@ -0,0 +1,57 @@ -+/* -+ * vc4-kms-dpi-hyperpixel4sq-overlay.dts -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+#include "vc4-kms-dpi-hyperpixel.dtsi" -+ -+&panel { -+ compatible = "pimoroni,hyperpixel4"; -+}; -+ -+/ { -+ fragment@11 { -+ target = <&i2c_gpio>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ ft6236_14: ft6236@14 { -+ compatible = "goodix,gt911"; -+ reg = <0x14>; -+ interrupt-parent = <&gpio>; -+ interrupts = <27 2>; -+ touchscreen-size-x = <480>; -+ touchscreen-size-y = <800>; -+ touchscreen-x-mm = <51>; -+ touchscreen-y-mm = <85>; -+ touchscreen-inverted-y; -+ touchscreen-swapped-x-y; -+ }; -+ ft6236_5d: ft6236@5d { -+ compatible = "goodix,gt911"; -+ reg = <0x5d>; -+ interrupt-parent = <&gpio>; -+ interrupts = <27 2>; -+ touchscreen-size-x = <480>; -+ touchscreen-size-y = <800>; -+ touchscreen-x-mm = <51>; -+ touchscreen-y-mm = <85>; -+ touchscreen-inverted-y; -+ touchscreen-swapped-x-y; -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ disable-touch = <0>,"-3-11"; -+ touchscreen-inverted-x = <&ft6236_14>,"touchscreen-inverted-x?", -+ <&ft6236_5d>,"touchscreen-inverted-x?"; -+ touchscreen-inverted-y = <&ft6236_14>,"touchscreen-inverted-y!", -+ <&ft6236_5d>,"touchscreen-inverted-y!"; -+ touchscreen-swapped-x-y = <&ft6236_14>,"touchscreen-swapped-x-y!", -+ <&ft6236_5d>,"touchscreen-swapped-x-y!"; -+ }; -+}; ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/vc4-kms-dpi-hyperpixel4sq-overlay.dts -@@ -0,0 +1,36 @@ -+/* -+ * vc4-kms-dpi-hyperpixel4-overlay.dts -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+#include "vc4-kms-dpi-hyperpixel.dtsi" -+ -+&panel { -+ compatible = "pimoroni,hyperpixel4square"; -+}; -+ -+/ { -+ fragment@11 { -+ target = <&i2c_gpio>; -+ __overlay__ { -+ polytouch: edt-ft5x06@48 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "edt,edt-ft5406"; -+ reg = <0x48>; -+ interrupt-parent = <&gpio>; -+ interrupts = <27 0x02>; -+ touchscreen-size-x = <720>; -+ touchscreen-size-y = <720>; -+ }; -+ }; -+ }; -+ __overrides__ { -+ disable-touch = <0>,"-3-11"; -+ touchscreen-inverted-x = <&polytouch>,"touchscreen-inverted-x?"; -+ touchscreen-inverted-y = <&polytouch>,"touchscreen-inverted-y!"; -+ touchscreen-swapped-x-y = <&polytouch>,"touchscreen-swapped-x-y!"; -+ }; -+}; diff --git a/target/linux/bcm27xx/patches-5.15/950-0698-dtoverlay-Reduce-size-of-PCIE-IB-window-in-pcie-32-d.patch b/target/linux/bcm27xx/patches-5.15/950-0698-dtoverlay-Reduce-size-of-PCIE-IB-window-in-pcie-32-d.patch deleted file mode 100644 index 4badeb1ba..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0698-dtoverlay-Reduce-size-of-PCIE-IB-window-in-pcie-32-d.patch +++ /dev/null @@ -1,51 +0,0 @@ -From e4402c2622756ab56d02159a8ff3c54165ab577c Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 3 Feb 2022 11:17:16 +0000 -Subject: [PATCH] dtoverlay: Reduce size of PCIE IB window in - pcie-32-dma overlay - -The PCIE inbound window is rounded up to a power of 2, so the default -of 3GB rounds up to 4GB starting at 0. This prohibits the MSI vector -sitting at 0x0_fffffffc, and causes warnings from some subsystems -(eg ahci) of a 64bit address on a 32bit configuration. - -Reduce the window down to 2GB to avoid this issue. - -https://github.com/raspberrypi/linux/issues/4848 - -Signed-off-by: Dave Stevenson ---- - .../dts/overlays/pcie-32bit-dma-overlay.dts | 20 +++++++++++++++++++ - 1 file changed, 20 insertions(+) - ---- a/arch/arm/boot/dts/overlays/pcie-32bit-dma-overlay.dts -+++ b/arch/arm/boot/dts/overlays/pcie-32bit-dma-overlay.dts -@@ -11,8 +11,28 @@ - fragment@0 { - target-path = "/aliases"; - __overlay__ { -+ /* -+ * Removing this alias stops the firmware patching the -+ * PCIE DT dma-ranges based on the detected chip -+ * revision. -+ */ - pcie0 = ""; - }; - }; - -+ fragment@1 { -+ target = <&pcie0>; -+ __overlay__ { -+ /* -+ * The size of the range is rounded up to a power of 2, -+ * so the range ends up being 0-4GB, and the MSI vector -+ * gets pushed beyond 4GB. -+ */ -+ #address-cells = <3>; -+ #size-cells = <2>; -+ dma-ranges = <0x02000000 0x0 0x00000000 0x0 0x00000000 -+ 0x0 0x80000000>; -+ }; -+ }; -+ - }; diff --git a/target/linux/bcm27xx/patches-5.15/950-0699-ARM-dts-Permanently-disable-hdmi1-and-ddc1-on-CM4S.patch b/target/linux/bcm27xx/patches-5.15/950-0699-ARM-dts-Permanently-disable-hdmi1-and-ddc1-on-CM4S.patch deleted file mode 100644 index 04b5081cf..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0699-ARM-dts-Permanently-disable-hdmi1-and-ddc1-on-CM4S.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 27dd29f219300bf3d4e5c26d5986ab6c73faa1e7 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 2 Feb 2022 17:47:54 +0000 -Subject: [PATCH] ARM: dts: Permanently disable hdmi1 and ddc1 on CM4S - -CM4S has no HDMI1 output, so it is advisable to disable the controller -and its I2C interface in software. This is ordinarily done by setting -their status properties to "disabled", but the vc4-kms-v3d(-pi4) -overlay enables both HDMIs and DDCs as part of the transfer of control -from the VPU. - -Knobble the CM4S dts in such a way that the overlay applies -successfully but the hdmi1 and ddc1 nodes remain disabled by changing -the compatible string to something unrecognised. - -See: https://github.com/raspberrypi/linux/issues/4857 - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/bcm2711-rpi-cm4s.dts | 10 ++++++++++ - 1 file changed, 10 insertions(+) - ---- a/arch/arm/boot/dts/bcm2711-rpi-cm4s.dts -+++ b/arch/arm/boot/dts/bcm2711-rpi-cm4s.dts -@@ -367,6 +367,16 @@ - }; - }; - -+/* Permanently disable HDMI1 */ -+&hdmi1 { -+ compatible = "disabled"; -+}; -+ -+/* Permanently disable DDC1 */ -+&ddc1 { -+ compatible = "disabled"; -+}; -+ - &leds { - act_led: led-act { - label = "led0"; diff --git a/target/linux/bcm27xx/patches-5.15/950-0700-net-phy-lan87xx-Decrease-phy-polling-rate.patch b/target/linux/bcm27xx/patches-5.15/950-0700-net-phy-lan87xx-Decrease-phy-polling-rate.patch deleted file mode 100644 index 0341a0b7b..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0700-net-phy-lan87xx-Decrease-phy-polling-rate.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 01649f43afb30df3c7450fd09c04a5a8ee6cb2c1 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 3 Feb 2022 15:51:41 +0000 -Subject: [PATCH] net: phy: lan87xx: Decrease phy polling rate - -Polling at 100Hz for 1.5s consumes quite a bit of kworker time with no -obvious benefit. Reduce that polling rate to ~6Hz. - -To further save CPU and power, defer the next poll if no energy is -detected. - -See: https://github.com/raspberrypi/linux/issues/4780 - -Signed-off-by: Phil Elwell ---- - drivers/net/phy/smsc.c | 10 +++++++++- - 1 file changed, 9 insertions(+), 1 deletion(-) - ---- a/drivers/net/phy/smsc.c -+++ b/drivers/net/phy/smsc.c -@@ -213,6 +213,8 @@ static int lan87xx_read_status(struct ph - return err; - - if (!phydev->link && priv->energy_enable && phydev->irq == PHY_POLL) { -+ int energy_detected; -+ - /* Disable EDPD to wake up PHY */ - int rc = phy_read(phydev, MII_LAN83C185_CTRL_STATUS); - if (rc < 0) -@@ -228,7 +230,7 @@ static int lan87xx_read_status(struct ph - */ - read_poll_timeout(phy_read, rc, - rc & MII_LAN83C185_ENERGYON || rc < 0, -- 10000, 1500000, true, phydev, -+ 150000, 1500000, true, phydev, - MII_LAN83C185_CTRL_STATUS); - if (rc < 0) - return rc; -@@ -238,10 +240,16 @@ static int lan87xx_read_status(struct ph - if (rc < 0) - return rc; - -+ energy_detected = !!(rc & MII_LAN83C185_ENERGYON); -+ - rc = phy_write(phydev, MII_LAN83C185_CTRL_STATUS, - rc | MII_LAN83C185_EDPWRDOWN); - if (rc < 0) - return rc; -+ -+ /* Save CPU and power by deferring the next poll */ -+ if (!energy_detected) -+ msleep(2000); - } - - return err; diff --git a/target/linux/bcm27xx/patches-5.15/950-0701-drm-panel-Fix-compilation-warnings.patch b/target/linux/bcm27xx/patches-5.15/950-0701-drm-panel-Fix-compilation-warnings.patch deleted file mode 100644 index 4d47d9374..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0701-drm-panel-Fix-compilation-warnings.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 5ab880f474a2263625033aee6d9236f6c10af2b4 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Sat, 5 Feb 2022 18:41:07 +0000 -Subject: [PATCH] drm: panel: Fix compilation warnings - -See: https://github.com/raspberrypi/linux/pull/4812 - -Signed-off-by: Phil Elwell ---- - drivers/gpu/drm/panel/panel-ilitek-ili9806e.c | 2 +- - drivers/gpu/drm/panel/panel-tdo-y17p.c | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/gpu/drm/panel/panel-ilitek-ili9806e.c -+++ b/drivers/gpu/drm/panel/panel-ilitek-ili9806e.c -@@ -421,7 +421,7 @@ static int ili9806_probe(struct spi_devi - if (!id) - return -ENODEV; - -- ctx->bus_format = (u32)id->data; -+ ctx->bus_format = (u32)(uintptr_t)id->data; - - spi_set_drvdata(spi, ctx); - ctx->spi = spi; ---- a/drivers/gpu/drm/panel/panel-tdo-y17p.c -+++ b/drivers/gpu/drm/panel/panel-tdo-y17p.c -@@ -218,7 +218,7 @@ static int tdo_y17p_probe(struct spi_dev - if (!id) - return -ENODEV; - -- ctx->bus_format = (u32)id->data; -+ ctx->bus_format = (u32)(uintptr_t)id->data; - - spi_set_drvdata(spi, ctx); - ctx->spi = spi; diff --git a/target/linux/bcm27xx/patches-5.15/950-0703-overlays-rpi-poe-plus-Fix-parameters.patch b/target/linux/bcm27xx/patches-5.15/950-0703-overlays-rpi-poe-plus-Fix-parameters.patch deleted file mode 100644 index e4aca831d..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0703-overlays-rpi-poe-plus-Fix-parameters.patch +++ /dev/null @@ -1,120 +0,0 @@ -From c19602f73386571bc9aed6059e2cce14f84eded4 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 7 Feb 2022 16:06:11 +0000 -Subject: [PATCH] overlays: rpi-poe(-plus): Fix parameters - -The support of PoE HATs is complicated because there are two methods to -control them - via the firmware, and directly over I2C - the choice -between the two methods depending on which side "owns" the i2c0 bus. - -The firmware determines the ownership of i2c0 by analysing the Device -Tree after applying any dtoverlays and dtparams. For this reason the -PoE HAT overlays have recently been applied by the firmware _after_ -config.txt has been processed, but this has prevented any user-supplied -threshold settings from being applied - either because the parameters -are unknown or because (after an explicit dtoverlay=rpi-poe) the -firmware's reload of the overlay has overwritten the user's settings. - -Solve the problem by restructuring the rpi-poe overlays to support -a mode switch _after_ the overlay has been merged, thereby allowing -the overlays to be loaded _before_ config.txt is processed. - -There is a companion firmware patch that changes the point at which -the overlays are loaded, and the parameter used to switch modes, but -the updated overlays are still compatible with older firmware, albeit -without working parameters. - -See: https://github.com/raspberrypi/firmware/issues/1689 - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/overlays/rpi-poe-overlay.dts | 15 ++++++++++----- - .../boot/dts/overlays/rpi-poe-plus-overlay.dts | 15 +++++++++++++-- - 2 files changed, 23 insertions(+), 7 deletions(-) - ---- a/arch/arm/boot/dts/overlays/rpi-poe-overlay.dts -+++ b/arch/arm/boot/dts/overlays/rpi-poe-overlay.dts -@@ -67,7 +67,7 @@ - - fragment@2 { - target-path = "/__overrides__"; -- __overlay__ { -+ params: __overlay__ { - poe_fan_temp0 = <&trip0>,"temperature:0"; - poe_fan_temp0_hyst = <&trip0>,"hysteresis:0"; - poe_fan_temp1 = <&trip1>,"temperature:0"; -@@ -76,6 +76,9 @@ - poe_fan_temp2_hyst = <&trip2>,"hysteresis:0"; - poe_fan_temp3 = <&trip3>,"temperature:0"; - poe_fan_temp3_hyst = <&trip3>,"hysteresis:0"; -+ poe_fan_i2c = <&fwpwm>,"status=disabled", -+ <&poe_mfd>,"status=okay", -+ <&fan>,"pwms:0=",<&poe_mfd_pwm>; - }; - }; - -@@ -91,15 +94,14 @@ - - fragment@4 { - target = <&i2c0>; -- __dormant__ { -+ i2c_bus: __overlay__ { - #address-cells = <1>; - #size-cells = <0>; -- status = "okay"; - - poe_mfd: poe@51 { - compatible = "raspberrypi,poe-core"; - reg = <0x51>; -- status = "okay"; -+ status = "disabled"; - - poe_mfd_pwm: poe_pwm@f0 { - compatible = "raspberrypi,poe-pwm"; -@@ -134,7 +136,10 @@ - poe_fan_temp2_hyst = <&trip2>,"hysteresis:0"; - poe_fan_temp3 = <&trip3>,"temperature:0"; - poe_fan_temp3_hyst = <&trip3>,"hysteresis:0"; -- i2c = <0>, "-3+4+5+6", -+ i2c = <0>, "+5+6", -+ <&fwpwm>,"status=disabled", -+ <&i2c_bus>,"status=okay", -+ <&poe_mfd>,"status=okay", - <&fan>,"pwms:0=",<&poe_mfd_pwm>; - }; - }; ---- a/arch/arm/boot/dts/overlays/rpi-poe-plus-overlay.dts -+++ b/arch/arm/boot/dts/overlays/rpi-poe-plus-overlay.dts -@@ -18,7 +18,7 @@ - }; - fragment@11 { - target = <&poe_mfd>; -- __dormant__ { -+ __overlay__ { - rpi-poe-power-supply@f2 { - compatible = "raspberrypi,rpi-poe-power-supply"; - reg = <0xf2>; -@@ -28,7 +28,11 @@ - }; - - __overrides__ { -- i2c = <0>, "-3+4+5+6-10+11", -+ i2c = <0>, "+5+6", -+ <&fwpwm>,"status=disabled", -+ <&rpi_poe_power_supply>,"status=disabled", -+ <&i2c_bus>,"status=okay", -+ <&poe_mfd>,"status=okay", - <&fan>,"pwms:0=",<&poe_mfd_pwm>; - }; - }; -@@ -36,3 +40,10 @@ - &fan { - cooling-levels = <0 32 64 128 255>; - }; -+ -+¶ms { -+ poe_fan_i2c = <&fwpwm>,"status=disabled", -+ <&rpi_poe_power_supply>,"status=disabled", -+ <&poe_mfd>,"status=okay", -+ <&fan>,"pwms:0=",<&poe_mfd_pwm>; -+}; diff --git a/target/linux/bcm27xx/patches-5.15/950-0704-dtoverlays-fix-overrides-in-vc4-kms-dpi-generic.patch b/target/linux/bcm27xx/patches-5.15/950-0704-dtoverlays-fix-overrides-in-vc4-kms-dpi-generic.patch deleted file mode 100644 index d519ce2ca..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0704-dtoverlays-fix-overrides-in-vc4-kms-dpi-generic.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 1d86afb04c942b2ef17a07cf5895b7ff20d5385b Mon Sep 17 00:00:00 2001 -From: Grigori Goronzy -Date: Wed, 9 Feb 2022 22:20:17 +0100 -Subject: [PATCH] dtoverlays: fix overrides in vc4-kms-dpi-generic - -Apparently broken by commit 3c033975. Introduce new names to allow for -proper addressing of overrides. - -Signed-off-by: Grigori Goronzy ---- - .../overlays/vc4-kms-dpi-generic-overlay.dts | 18 +++++++++--------- - 1 file changed, 9 insertions(+), 9 deletions(-) - ---- a/arch/arm/boot/dts/overlays/vc4-kms-dpi-generic-overlay.dts -+++ b/arch/arm/boot/dts/overlays/vc4-kms-dpi-generic-overlay.dts -@@ -12,7 +12,7 @@ - - fragment@0 { - target = <&panel>; -- __overlay__ { -+ panel_generic: __overlay__ { - compatible = "panel-dpi"; - - width-mm = <154>; -@@ -40,7 +40,7 @@ - - fragment@1 { - target = <&dpi>; -- __overlay__ { -+ dpi_node_generic: __overlay__ { - pinctrl-0 = <&dpi_18bit_gpio0>; - }; - }; -@@ -63,12 +63,12 @@ - width-mm = <&panel>, "width-mm:0"; - height-mm = <&panel>, "height-mm:0"; - -- rgb565 = <&panel>, "bus-format:0=0x1017", -- <&dpi_node>, "pinctrl-0:0=",<&dpi_16bit_gpio0>; -- rgb666-padhi = <&panel>, "bus-format:0=0x1015", -- <&dpi_node>, "pinctrl-0:0=",<&dpi_18bit_cpadhi_gpio0>; -- rgb888 = <&panel>, "bus-format:0=0x100a", -- <&dpi_node>, "pinctrl-0:0=",<&dpi_gpio0>; -- bus-format = <&panel>, "bus-format:0"; -+ rgb565 = <&panel_generic>, "bus-format:0=0x1017", -+ <&dpi_node_generic>, "pinctrl-0:0=",<&dpi_16bit_gpio0>; -+ rgb666-padhi = <&panel_generic>, "bus-format:0=0x1015", -+ <&dpi_node_generic>, "pinctrl-0:0=",<&dpi_18bit_cpadhi_gpio0>; -+ rgb888 = <&panel_generic>, "bus-format:0=0x100a", -+ <&dpi_node_generic>, "pinctrl-0:0=",<&dpi_gpio0>; -+ bus-format = <&panel_generic>, "bus-format:0"; - }; - }; diff --git a/target/linux/bcm27xx/patches-5.15/950-0705-dtoverlays-add-rgb565-padhi-output-to-vc4-kms-dpi-ge.patch b/target/linux/bcm27xx/patches-5.15/950-0705-dtoverlays-add-rgb565-padhi-output-to-vc4-kms-dpi-ge.patch deleted file mode 100644 index 0d00d75a1..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0705-dtoverlays-add-rgb565-padhi-output-to-vc4-kms-dpi-ge.patch +++ /dev/null @@ -1,37 +0,0 @@ -From c4d228323c9c302b355cfd27cd59809110d7c74e Mon Sep 17 00:00:00 2001 -From: Grigori Goronzy -Date: Wed, 9 Feb 2022 22:23:11 +0100 -Subject: [PATCH] dtoverlays: add rgb565-padhi output to - vc4-kms-dpi-generic - -This mode is used by some DPI based display adapters, such as the -'VGA565' and 'VGA Zero' low-cost VGA adapters for the Raspberry Pi. - -Signed-off-by: Grigori Goronzy ---- - arch/arm/boot/dts/overlays/README | 2 ++ - arch/arm/boot/dts/overlays/vc4-kms-dpi-generic-overlay.dts | 2 ++ - 2 files changed, 4 insertions(+) - ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -3649,6 +3649,8 @@ Params: clock-frequency Display - width-mm Define the screen width in mm - height-mm Define the screen height in mm - rgb565 Change to RGB565 output on GPIOs 0-19 -+ rgb565-padhi Change to RGB565 output on GPIOs 0-8, 12-17, and -+ 20-24 - rgb666-padhi Change to RGB666 output on GPIOs 0-9, 12-17, and - 20-25 - rgb888 Change to RGB888 output on GPIOs 0-27 ---- a/arch/arm/boot/dts/overlays/vc4-kms-dpi-generic-overlay.dts -+++ b/arch/arm/boot/dts/overlays/vc4-kms-dpi-generic-overlay.dts -@@ -65,6 +65,8 @@ - - rgb565 = <&panel_generic>, "bus-format:0=0x1017", - <&dpi_node_generic>, "pinctrl-0:0=",<&dpi_16bit_gpio0>; -+ rgb565-padhi = <&panel_generic>, "bus-format:0=0x1020", -+ <&dpi_node_generic>, "pinctrl-0:0=",<&dpi_16bit_cpadhi_gpio0>; - rgb666-padhi = <&panel_generic>, "bus-format:0=0x1015", - <&dpi_node_generic>, "pinctrl-0:0=",<&dpi_18bit_cpadhi_gpio0>; - rgb888 = <&panel_generic>, "bus-format:0=0x100a", diff --git a/target/linux/bcm27xx/patches-5.15/950-0708-dtoverlays-Add-additional-mappings-to-vc4-kms-dpi-ge.patch b/target/linux/bcm27xx/patches-5.15/950-0708-dtoverlays-Add-additional-mappings-to-vc4-kms-dpi-ge.patch deleted file mode 100644 index 3cc03de77..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0708-dtoverlays-Add-additional-mappings-to-vc4-kms-dpi-ge.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 4b3fe84c0de9fe0d6669abb0ec8ae628b65b4a2e Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 14 Feb 2022 15:59:32 +0000 -Subject: [PATCH] dtoverlays: Add additional mappings to - vc4-kms-dpi-generic - -Adds mappings for bgr666, bgr666-padhi, and bgr888. - -Signed-off-by: Dave Stevenson ---- - arch/arm/boot/dts/overlays/README | 4 ++++ - arch/arm/boot/dts/overlays/vc4-kms-dpi-generic-overlay.dts | 5 +++++ - 2 files changed, 9 insertions(+) - ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -3651,8 +3651,12 @@ Params: clock-frequency Display - rgb565 Change to RGB565 output on GPIOs 0-19 - rgb565-padhi Change to RGB565 output on GPIOs 0-8, 12-17, and - 20-24 -+ bgr666 Change to BGR666 output on GPIOs 0-21. -+ bgr666-padhi Change to BGR666 output on GPIOs 0-9, 12-17, and -+ 20-25 - rgb666-padhi Change to RGB666 output on GPIOs 0-9, 12-17, and - 20-25 -+ bgr888 Change to BGR888 output on GPIOs 0-27 - rgb888 Change to RGB888 output on GPIOs 0-27 - bus-format Override the bus format for a MEDIA_BUS_FMT_* - value. NB also overridden by rgbXXX overrides. ---- a/arch/arm/boot/dts/overlays/vc4-kms-dpi-generic-overlay.dts -+++ b/arch/arm/boot/dts/overlays/vc4-kms-dpi-generic-overlay.dts -@@ -67,8 +67,13 @@ - <&dpi_node_generic>, "pinctrl-0:0=",<&dpi_16bit_gpio0>; - rgb565-padhi = <&panel_generic>, "bus-format:0=0x1020", - <&dpi_node_generic>, "pinctrl-0:0=",<&dpi_16bit_cpadhi_gpio0>; -+ bgr666 = <&panel_generic>, "bus-format:0=0x101f"; -+ bgr666-padhi = <&panel_generic>, "bus-format:0=0x101e", -+ <&dpi_node_generic>, "pinctrl-0:0=",<&dpi_18bit_cpadhi_gpio0>; - rgb666-padhi = <&panel_generic>, "bus-format:0=0x1015", - <&dpi_node_generic>, "pinctrl-0:0=",<&dpi_18bit_cpadhi_gpio0>; -+ bgr888 = <&panel_generic>, "bus-format:0=0x1013", -+ <&dpi_node_generic>, "pinctrl-0:0=",<&dpi_gpio0>; - rgb888 = <&panel_generic>, "bus-format:0=0x100a", - <&dpi_node_generic>, "pinctrl-0:0=",<&dpi_gpio0>; - bus-format = <&panel_generic>, "bus-format:0"; diff --git a/target/linux/bcm27xx/patches-5.15/950-0718-dtoverlays-Correct-link-frequency-for-ov7251.patch b/target/linux/bcm27xx/patches-5.15/950-0718-dtoverlays-Correct-link-frequency-for-ov7251.patch deleted file mode 100644 index 696115177..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0718-dtoverlays-Correct-link-frequency-for-ov7251.patch +++ /dev/null @@ -1,23 +0,0 @@ -From a390c2098ae9f4ec36b3953b48980f3f75d01d24 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 17 Feb 2022 15:16:56 +0000 -Subject: [PATCH] dtoverlays: Correct link frequency for ov7251 - -It was incorrect, so the driver rejected it. - -Signed-off-by: Dave Stevenson ---- - arch/arm/boot/dts/overlays/ov7251-overlay.dts | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/arch/arm/boot/dts/overlays/ov7251-overlay.dts -+++ b/arch/arm/boot/dts/overlays/ov7251-overlay.dts -@@ -38,7 +38,7 @@ - data-lanes = <1>; - clock-noncontinuous; - link-frequencies = -- /bits/ 64 <456000000>; -+ /bits/ 64 <240000000>; - }; - }; - }; diff --git a/target/linux/bcm27xx/patches-5.15/950-0719-media-i2c-Add-acpi-support-to-ov7251.patch b/target/linux/bcm27xx/patches-5.15/950-0719-media-i2c-Add-acpi-support-to-ov7251.patch deleted file mode 100644 index 5ec3d1b7a..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0719-media-i2c-Add-acpi-support-to-ov7251.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 72ffad08ed8a635ada5a15be818f151f20d92e9b Mon Sep 17 00:00:00 2001 -From: Daniel Scally -Date: Tue, 15 Feb 2022 23:07:30 +0000 -Subject: [PATCH] media: i2c: Add acpi support to ov7251 - -Add support for enumeration through ACPI to the ov7251 driver - -Signed-off-by: Daniel Scally ---- - drivers/media/i2c/ov7251.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - ---- a/drivers/media/i2c/ov7251.c -+++ b/drivers/media/i2c/ov7251.c -@@ -14,6 +14,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -1501,9 +1502,16 @@ static const struct of_device_id ov7251_ - }; - MODULE_DEVICE_TABLE(of, ov7251_of_match); - -+static const struct acpi_device_id ov7251_acpi_match[] = { -+ { "INT347E" }, -+ { } -+}; -+MODULE_DEVICE_TABLE(acpi, ov7251_acpi_match); -+ - static struct i2c_driver ov7251_i2c_driver = { - .driver = { - .of_match_table = ov7251_of_match, -+ .acpi_match_table = ov7251_acpi_match, - .name = "ov7251", - }, - .probe_new = ov7251_probe, diff --git a/target/linux/bcm27xx/patches-5.15/950-0720-media-i2c-Provide-ov7251_check_hwcfg.patch b/target/linux/bcm27xx/patches-5.15/950-0720-media-i2c-Provide-ov7251_check_hwcfg.patch deleted file mode 100644 index b4b99fc4a..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0720-media-i2c-Provide-ov7251_check_hwcfg.patch +++ /dev/null @@ -1,121 +0,0 @@ -From 3b21da2334113027d91829e1fabe332cf21522a3 Mon Sep 17 00:00:00 2001 -From: Daniel Scally -Date: Tue, 15 Feb 2022 23:07:31 +0000 -Subject: [PATCH] media: i2c: Provide ov7251_check_hwcfg() - -Move the endpoint checking from .probe() to a dedicated function, -and additionally check that the firmware provided link frequencies -are a match for those supported by the driver. Finally, return --EPROBE_DEFER if the endpoint is not available, as it could be built -by the ipu3-cio2 driver if that probes later. - -Signed-off-by: Daniel Scally ---- - drivers/media/i2c/ov7251.c | 84 ++++++++++++++++++++++++++++++-------- - 1 file changed, 66 insertions(+), 18 deletions(-) - ---- a/drivers/media/i2c/ov7251.c -+++ b/drivers/media/i2c/ov7251.c -@@ -1255,11 +1255,74 @@ static const struct v4l2_subdev_ops ov72 - .pad = &ov7251_subdev_pad_ops, - }; - -+static int ov7251_check_hwcfg(struct ov7251 *ov7251) -+{ -+ struct fwnode_handle *fwnode = dev_fwnode(ov7251->dev); -+ struct v4l2_fwnode_endpoint bus_cfg = { -+ .bus_type = V4L2_MBUS_CSI2_DPHY, -+ }; -+ struct fwnode_handle *endpoint; -+ bool freq_found; -+ int i, j; -+ int ret; -+ -+ endpoint = fwnode_graph_get_next_endpoint(fwnode, NULL); -+ if (!endpoint) -+ return -EPROBE_DEFER; /* could be provided by cio2-bridge */ -+ -+ ret = v4l2_fwnode_endpoint_alloc_parse(endpoint, &bus_cfg); -+ fwnode_handle_put(endpoint); -+ if (ret) -+ return dev_err_probe(ov7251->dev, ret, -+ "parsing endpoint node failed\n"); -+ -+ if (bus_cfg.bus_type != V4L2_MBUS_CSI2_DPHY) { -+ ret = -EINVAL; -+ dev_err(ov7251->dev, "invalid bus type (%u), must be (%u)\n", -+ bus_cfg.bus_type, V4L2_MBUS_CSI2_DPHY); -+ goto out_free_bus_cfg; -+ } -+ -+ if (bus_cfg.bus.mipi_csi2.num_data_lanes != 1) { -+ dev_err(ov7251->dev, "only a 1-lane CSI2 config is supported"); -+ ret = -EINVAL; -+ goto out_free_bus_cfg; -+ } -+ -+ if (!bus_cfg.nr_of_link_frequencies) { -+ dev_err(ov7251->dev, "no link frequencies defined\n"); -+ ret = -EINVAL; -+ goto out_free_bus_cfg; -+ } -+ -+ freq_found = false; -+ for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) { -+ if (freq_found) -+ break; -+ -+ for (j = 0; j < ARRAY_SIZE(link_freq); j++) -+ if (bus_cfg.link_frequencies[i] == link_freq[j]) { -+ freq_found = true; -+ break; -+ } -+ } -+ -+ if (i == bus_cfg.nr_of_link_frequencies) { -+ dev_err(ov7251->dev, "no supported link freq found\n"); -+ ret = -EINVAL; -+ goto out_free_bus_cfg; -+ } -+ -+out_free_bus_cfg: -+ v4l2_fwnode_endpoint_free(&bus_cfg); -+ -+ return ret; -+} -+ - static int ov7251_probe(struct i2c_client *client) - { - struct v4l2_fwnode_device_properties props; - struct device *dev = &client->dev; -- struct fwnode_handle *endpoint; - struct ov7251 *ov7251; - u8 chip_id_high, chip_id_low, chip_rev; - int ret; -@@ -1271,24 +1334,9 @@ static int ov7251_probe(struct i2c_clien - ov7251->i2c_client = client; - ov7251->dev = dev; - -- endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(dev), NULL); -- if (!endpoint) { -- dev_err(dev, "endpoint node not found\n"); -- return -EINVAL; -- } -- -- ret = v4l2_fwnode_endpoint_parse(endpoint, &ov7251->ep); -- fwnode_handle_put(endpoint); -- if (ret < 0) { -- dev_err(dev, "parsing endpoint node failed\n"); -+ ret = ov7251_check_hwcfg(ov7251); -+ if (ret) - return ret; -- } -- -- if (ov7251->ep.bus_type != V4L2_MBUS_CSI2_DPHY) { -- dev_err(dev, "invalid bus type (%u), must be CSI2 (%u)\n", -- ov7251->ep.bus_type, V4L2_MBUS_CSI2_DPHY); -- return -EINVAL; -- } - - /* get system clock (xclk) */ - ov7251->xclk = devm_clk_get(dev, "xclk"); diff --git a/target/linux/bcm27xx/patches-5.15/950-0721-media-i2c-Add-ov7251_pll_configure.patch b/target/linux/bcm27xx/patches-5.15/950-0721-media-i2c-Add-ov7251_pll_configure.patch deleted file mode 100644 index 040898427..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0721-media-i2c-Add-ov7251_pll_configure.patch +++ /dev/null @@ -1,266 +0,0 @@ -From c16cebe5ebfb309074ff7cc9ddeaf37724d31512 Mon Sep 17 00:00:00 2001 -From: Daniel Scally -Date: Tue, 15 Feb 2022 23:07:32 +0000 -Subject: [PATCH] media: i2c: Add ov7251_pll_configure() - -Rather than having the pll settings hidden inside mode blobs, define -them in structs and use a dedicated function to set them. This makes -it simpler to extend the driver to support other external clock -frequencies. - -Signed-off-by: Daniel Scally ---- - drivers/media/i2c/ov7251.c | 165 ++++++++++++++++++++++++++++++------- - 1 file changed, 135 insertions(+), 30 deletions(-) - ---- a/drivers/media/i2c/ov7251.c -+++ b/drivers/media/i2c/ov7251.c -@@ -42,6 +42,16 @@ - #define OV7251_TIMING_FORMAT2_MIRROR BIT(2) - #define OV7251_PRE_ISP_00 0x5e00 - #define OV7251_PRE_ISP_00_TEST_PATTERN BIT(7) -+#define OV7251_PLL1_PRE_DIV_REG 0x30b4 -+#define OV7251_PLL1_MULT_REG 0x30b3 -+#define OV7251_PLL1_DIVIDER_REG 0x30b1 -+#define OV7251_PLL1_PIX_DIV_REG 0x30b0 -+#define OV7251_PLL1_MIPI_DIV_REG 0x30b5 -+#define OV7251_PLL2_PRE_DIV_REG 0x3098 -+#define OV7251_PLL2_MULT_REG 0x3099 -+#define OV7251_PLL2_DIVIDER_REG 0x309d -+#define OV7251_PLL2_SYS_DIV_REG 0x309a -+#define OV7251_PLL2_ADC_DIV_REG 0x309b - - struct reg_value { - u16 reg; -@@ -60,6 +70,27 @@ struct ov7251_mode_info { - struct v4l2_fract timeperframe; - }; - -+struct ov7251_pll1_config { -+ unsigned int pre_div; -+ unsigned int mult; -+ unsigned int div; -+ unsigned int pix_div; -+ unsigned int mipi_div; -+}; -+ -+struct ov7251_pll2_config { -+ unsigned int pre_div; -+ unsigned int mult; -+ unsigned int div; -+ unsigned int sys_div; -+ unsigned int adc_div; -+}; -+ -+struct ov7251_pll_configs { -+ const struct ov7251_pll1_config *pll1; -+ const struct ov7251_pll2_config *pll2; -+}; -+ - struct ov7251 { - struct i2c_client *i2c_client; - struct device *dev; -@@ -71,6 +102,8 @@ struct ov7251 { - struct clk *xclk; - u32 xclk_freq; - -+ const struct ov7251_pll_configs *pll_configs; -+ - struct regulator *io_regulator; - struct regulator *core_regulator; - struct regulator *analog_regulator; -@@ -100,6 +133,36 @@ static inline struct ov7251 *to_ov7251(s - return container_of(sd, struct ov7251, sd); - } - -+enum xclk_rate { -+ OV7251_24_MHZ, -+ OV7251_NUM_SUPPORTED_RATES -+}; -+ -+static const struct ov7251_pll1_config ov7251_pll1_config_24_mhz = { -+ .pre_div = 0x03, -+ .mult = 0x64, -+ .div = 0x01, -+ .pix_div = 0x0a, -+ .mipi_div = 0x05 -+}; -+ -+static const struct ov7251_pll2_config ov7251_pll2_config_24_mhz = { -+ .pre_div = 0x04, -+ .mult = 0x28, -+ .div = 0x00, -+ .sys_div = 0x05, -+ .adc_div = 0x04 -+}; -+ -+static const struct ov7251_pll_configs ov7251_pll_configs_24_mhz = { -+ .pll1 = &ov7251_pll1_config_24_mhz, -+ .pll2 = &ov7251_pll2_config_24_mhz -+}; -+ -+static const struct ov7251_pll_configs *ov7251_pll_configs[] = { -+ [OV7251_24_MHZ] = &ov7251_pll_configs_24_mhz -+}; -+ - static const struct reg_value ov7251_global_init_setting[] = { - { 0x0103, 0x01 }, - { 0x303b, 0x02 }, -@@ -118,16 +181,6 @@ static const struct reg_value ov7251_set - { 0x301c, 0xf0 }, - { 0x3023, 0x05 }, - { 0x3037, 0xf0 }, -- { 0x3098, 0x04 }, /* pll2 pre divider */ -- { 0x3099, 0x28 }, /* pll2 multiplier */ -- { 0x309a, 0x05 }, /* pll2 sys divider */ -- { 0x309b, 0x04 }, /* pll2 adc divider */ -- { 0x309d, 0x00 }, /* pll2 divider */ -- { 0x30b0, 0x0a }, /* pll1 pix divider */ -- { 0x30b1, 0x01 }, /* pll1 divider */ -- { 0x30b3, 0x64 }, /* pll1 multiplier */ -- { 0x30b4, 0x03 }, /* pll1 pre divider */ -- { 0x30b5, 0x05 }, /* pll1 mipi divider */ - { 0x3106, 0xda }, - { 0x3503, 0x07 }, - { 0x3509, 0x10 }, -@@ -256,16 +309,6 @@ static const struct reg_value ov7251_set - { 0x301c, 0x00 }, - { 0x3023, 0x05 }, - { 0x3037, 0xf0 }, -- { 0x3098, 0x04 }, /* pll2 pre divider */ -- { 0x3099, 0x28 }, /* pll2 multiplier */ -- { 0x309a, 0x05 }, /* pll2 sys divider */ -- { 0x309b, 0x04 }, /* pll2 adc divider */ -- { 0x309d, 0x00 }, /* pll2 divider */ -- { 0x30b0, 0x0a }, /* pll1 pix divider */ -- { 0x30b1, 0x01 }, /* pll1 divider */ -- { 0x30b3, 0x64 }, /* pll1 multiplier */ -- { 0x30b4, 0x03 }, /* pll1 pre divider */ -- { 0x30b5, 0x05 }, /* pll1 mipi divider */ - { 0x3106, 0xda }, - { 0x3503, 0x07 }, - { 0x3509, 0x10 }, -@@ -394,16 +437,6 @@ static const struct reg_value ov7251_set - { 0x301c, 0x00 }, - { 0x3023, 0x05 }, - { 0x3037, 0xf0 }, -- { 0x3098, 0x04 }, /* pll2 pre divider */ -- { 0x3099, 0x28 }, /* pll2 multiplier */ -- { 0x309a, 0x05 }, /* pll2 sys divider */ -- { 0x309b, 0x04 }, /* pll2 adc divider */ -- { 0x309d, 0x00 }, /* pll2 divider */ -- { 0x30b0, 0x0a }, /* pll1 pix divider */ -- { 0x30b1, 0x01 }, /* pll1 divider */ -- { 0x30b3, 0x64 }, /* pll1 multiplier */ -- { 0x30b4, 0x03 }, /* pll1 pre divider */ -- { 0x30b5, 0x05 }, /* pll1 mipi divider */ - { 0x3106, 0xda }, - { 0x3503, 0x07 }, - { 0x3509, 0x10 }, -@@ -519,6 +552,10 @@ static const struct reg_value ov7251_set - { 0x5001, 0x80 }, - }; - -+static const unsigned long supported_xclk_rates[] = { -+ [OV7251_24_MHZ] = 24000000, -+}; -+ - static const s64 link_freq[] = { - 240000000, - }; -@@ -692,6 +729,63 @@ static int ov7251_read_reg(struct ov7251 - return 0; - } - -+static int ov7251_pll_configure(struct ov7251 *ov7251) -+{ -+ const struct ov7251_pll_configs *configs; -+ int ret; -+ -+ configs = ov7251->pll_configs; -+ -+ ret = ov7251_write_reg(ov7251, OV7251_PLL1_PRE_DIV_REG, -+ configs->pll1->pre_div); -+ if (ret < 0) -+ return ret; -+ -+ ret = ov7251_write_reg(ov7251, OV7251_PLL1_MULT_REG, -+ configs->pll1->mult); -+ if (ret < 0) -+ return ret; -+ ret = ov7251_write_reg(ov7251, OV7251_PLL1_DIVIDER_REG, -+ configs->pll1->div); -+ if (ret < 0) -+ return ret; -+ -+ ret = ov7251_write_reg(ov7251, OV7251_PLL1_PIX_DIV_REG, -+ configs->pll1->pix_div); -+ if (ret < 0) -+ return ret; -+ -+ ret = ov7251_write_reg(ov7251, OV7251_PLL1_MIPI_DIV_REG, -+ configs->pll1->mipi_div); -+ if (ret < 0) -+ return ret; -+ -+ ret = ov7251_write_reg(ov7251, OV7251_PLL2_PRE_DIV_REG, -+ configs->pll2->pre_div); -+ if (ret < 0) -+ return ret; -+ -+ ret = ov7251_write_reg(ov7251, OV7251_PLL2_MULT_REG, -+ configs->pll2->mult); -+ if (ret < 0) -+ return ret; -+ -+ ret = ov7251_write_reg(ov7251, OV7251_PLL2_DIVIDER_REG, -+ configs->pll2->div); -+ if (ret < 0) -+ return ret; -+ -+ ret = ov7251_write_reg(ov7251, OV7251_PLL2_SYS_DIV_REG, -+ configs->pll2->sys_div); -+ if (ret < 0) -+ return ret; -+ -+ ret = ov7251_write_reg(ov7251, OV7251_PLL2_ADC_DIV_REG, -+ configs->pll2->adc_div); -+ -+ return ret; -+} -+ - static int ov7251_set_exposure(struct ov7251 *ov7251, s32 exposure) - { - u16 reg; -@@ -1143,6 +1237,11 @@ static int ov7251_s_stream(struct v4l2_s - mutex_lock(&ov7251->lock); - - if (enable) { -+ ret = ov7251_pll_configure(ov7251); -+ if (ret) -+ return dev_err_probe(ov7251->dev, ret, -+ "error configuring PLLs\n"); -+ - ret = ov7251_set_register_array(ov7251, - ov7251->current_mode->data, - ov7251->current_mode->data_size); -@@ -1326,6 +1425,7 @@ static int ov7251_probe(struct i2c_clien - struct ov7251 *ov7251; - u8 chip_id_high, chip_id_low, chip_rev; - int ret; -+ int i; - - ov7251 = devm_kzalloc(dev, sizeof(struct ov7251), GFP_KERNEL); - if (!ov7251) -@@ -1364,6 +1464,11 @@ static int ov7251_probe(struct i2c_clien - dev_err(dev, "could not set xclk frequency\n"); - return ret; - } -+ for (i = 0; i < ARRAY_SIZE(supported_xclk_rates); i++) -+ if (ov7251->xclk_freq == supported_xclk_rates[i]) -+ break; -+ -+ ov7251->pll_configs = ov7251_pll_configs[i]; - - ov7251->io_regulator = devm_regulator_get(dev, "vdddo"); - if (IS_ERR(ov7251->io_regulator)) { diff --git a/target/linux/bcm27xx/patches-5.15/950-0722-media-i2c-Add-support-for-19.2MHz-clock-to-ov7251.patch b/target/linux/bcm27xx/patches-5.15/950-0722-media-i2c-Add-support-for-19.2MHz-clock-to-ov7251.patch deleted file mode 100644 index 6052cfa47..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0722-media-i2c-Add-support-for-19.2MHz-clock-to-ov7251.patch +++ /dev/null @@ -1,144 +0,0 @@ -From 16af9ae925fdb05960f644b6cc84098af8aa3956 Mon Sep 17 00:00:00 2001 -From: Daniel Scally -Date: Tue, 15 Feb 2022 23:07:33 +0000 -Subject: [PATCH] media: i2c: Add support for 19.2MHz clock to ov7251 - -The OV7251 sensor is used as the IR camera sensor on the Microsoft -Surface line of tablets; this provides a 19.2MHz external clock. Add -the ability to support that rate to the driver by defining a new set -of PLL configs. Extend the clock handling in .probe() to check for -either supported frequency. - -Signed-off-by: Daniel Scally ---- - drivers/media/i2c/ov7251.c | 61 ++++++++++++++++++++++++++++---------- - 1 file changed, 45 insertions(+), 16 deletions(-) - ---- a/drivers/media/i2c/ov7251.c -+++ b/drivers/media/i2c/ov7251.c -@@ -134,10 +134,19 @@ static inline struct ov7251 *to_ov7251(s - } - - enum xclk_rate { -+ OV7251_19_2_MHZ, - OV7251_24_MHZ, - OV7251_NUM_SUPPORTED_RATES - }; - -+static const struct ov7251_pll1_config ov7251_pll1_config_19_2_mhz = { -+ .pre_div = 0x03, -+ .mult = 0x4b, -+ .div = 0x01, -+ .pix_div = 0x0a, -+ .mipi_div = 0x05 -+}; -+ - static const struct ov7251_pll1_config ov7251_pll1_config_24_mhz = { - .pre_div = 0x03, - .mult = 0x64, -@@ -146,6 +155,14 @@ static const struct ov7251_pll1_config o - .mipi_div = 0x05 - }; - -+static const struct ov7251_pll2_config ov7251_pll2_config_19_2_mhz = { -+ .pre_div = 0x04, -+ .mult = 0x32, -+ .div = 0x00, -+ .sys_div = 0x05, -+ .adc_div = 0x04 -+}; -+ - static const struct ov7251_pll2_config ov7251_pll2_config_24_mhz = { - .pre_div = 0x04, - .mult = 0x28, -@@ -154,12 +171,18 @@ static const struct ov7251_pll2_config o - .adc_div = 0x04 - }; - -+static const struct ov7251_pll_configs ov7251_pll_configs_19_2_mhz = { -+ .pll1 = &ov7251_pll1_config_19_2_mhz, -+ .pll2 = &ov7251_pll2_config_19_2_mhz -+}; -+ - static const struct ov7251_pll_configs ov7251_pll_configs_24_mhz = { - .pll1 = &ov7251_pll1_config_24_mhz, - .pll2 = &ov7251_pll2_config_24_mhz - }; - - static const struct ov7251_pll_configs *ov7251_pll_configs[] = { -+ [OV7251_19_2_MHZ] = &ov7251_pll_configs_19_2_mhz, - [OV7251_24_MHZ] = &ov7251_pll_configs_24_mhz - }; - -@@ -553,6 +576,7 @@ static const struct reg_value ov7251_set - }; - - static const unsigned long supported_xclk_rates[] = { -+ [OV7251_19_2_MHZ] = 19200000, - [OV7251_24_MHZ] = 24000000, - }; - -@@ -1424,6 +1448,7 @@ static int ov7251_probe(struct i2c_clien - struct device *dev = &client->dev; - struct ov7251 *ov7251; - u8 chip_id_high, chip_id_low, chip_rev; -+ unsigned int rate = 0; - int ret; - int i; - -@@ -1439,35 +1464,39 @@ static int ov7251_probe(struct i2c_clien - return ret; - - /* get system clock (xclk) */ -- ov7251->xclk = devm_clk_get(dev, "xclk"); -+ ov7251->xclk = devm_clk_get(dev, NULL); - if (IS_ERR(ov7251->xclk)) { - dev_err(dev, "could not get xclk"); - return PTR_ERR(ov7251->xclk); - } - -+ /* -+ * We could have either a 24MHz or 19.2MHz clock rate from either dt or -+ * ACPI. We also need to support the IPU3 case which will have both an -+ * external clock AND a clock-frequency property. -+ */ - ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency", -- &ov7251->xclk_freq); -- if (ret) { -- dev_err(dev, "could not get xclk frequency\n"); -- return ret; -+ &rate); -+ if (!ret && ov7251->xclk) { -+ ret = clk_set_rate(ov7251->xclk, rate); -+ if (ret) -+ return dev_err_probe(dev, ret, -+ "failed to set clock rate\n"); -+ } else if (ret && !ov7251->xclk) { -+ return dev_err_probe(dev, ret, "invalid clock config\n"); - } - -- /* external clock must be 24MHz, allow 1% tolerance */ -- if (ov7251->xclk_freq < 23760000 || ov7251->xclk_freq > 24240000) { -- dev_err(dev, "external clock frequency %u is not supported\n", -- ov7251->xclk_freq); -- return -EINVAL; -- } -+ ov7251->xclk_freq = rate ? rate : clk_get_rate(ov7251->xclk); - -- ret = clk_set_rate(ov7251->xclk, ov7251->xclk_freq); -- if (ret) { -- dev_err(dev, "could not set xclk frequency\n"); -- return ret; -- } - for (i = 0; i < ARRAY_SIZE(supported_xclk_rates); i++) - if (ov7251->xclk_freq == supported_xclk_rates[i]) - break; - -+ if (i == ARRAY_SIZE(supported_xclk_rates)) -+ return dev_err_probe(dev, -EINVAL, -+ "clock rate %u Hz is unsupported\n", -+ ov7251->xclk_freq); -+ - ov7251->pll_configs = ov7251_pll_configs[i]; - - ov7251->io_regulator = devm_regulator_get(dev, "vdddo"); diff --git a/target/linux/bcm27xx/patches-5.15/950-0723-media-i2c-Add-ov7251_detect_chip.patch b/target/linux/bcm27xx/patches-5.15/950-0723-media-i2c-Add-ov7251_detect_chip.patch deleted file mode 100644 index 526dd668b..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0723-media-i2c-Add-ov7251_detect_chip.patch +++ /dev/null @@ -1,98 +0,0 @@ -From d67eece3a8ba9e8961e6050129f6f76d31924d62 Mon Sep 17 00:00:00 2001 -From: Daniel Scally -Date: Tue, 15 Feb 2022 23:07:34 +0000 -Subject: [PATCH] media: i2c: Add ov7251_detect_chip() - -.probe() is quite busy for this driver; make it cleaner by moving the -chip verification to a dedicated function. - -Signed-off-by: Daniel Scally ---- - drivers/media/i2c/ov7251.c | 62 +++++++++++++++++++++----------------- - 1 file changed, 35 insertions(+), 27 deletions(-) - ---- a/drivers/media/i2c/ov7251.c -+++ b/drivers/media/i2c/ov7251.c -@@ -1442,12 +1442,44 @@ out_free_bus_cfg: - return ret; - } - -+static int ov7251_detect_chip(struct ov7251 *ov7251) -+{ -+ u8 chip_id_high, chip_id_low, chip_rev; -+ int ret; -+ -+ ret = ov7251_read_reg(ov7251, OV7251_CHIP_ID_HIGH, &chip_id_high); -+ if (ret < 0 || chip_id_high != OV7251_CHIP_ID_HIGH_BYTE) -+ return dev_err_probe(ov7251->dev, -ENODEV, -+ "could not read ID high\n"); -+ -+ ret = ov7251_read_reg(ov7251, OV7251_CHIP_ID_LOW, &chip_id_low); -+ if (ret < 0 || chip_id_low != OV7251_CHIP_ID_LOW_BYTE) -+ return dev_err_probe(ov7251->dev, -ENODEV, -+ "could not read ID low\n"); -+ -+ ret = ov7251_read_reg(ov7251, OV7251_SC_GP_IO_IN1, &chip_rev); -+ if (ret < 0) -+ return dev_err_probe(ov7251->dev, -ENODEV, -+ "could not read revision\n"); -+ chip_rev >>= 4; -+ -+ dev_info(ov7251->dev, -+ "OV7251 revision %x (%s) detected at address 0x%02x\n", -+ chip_rev, -+ chip_rev == 0x4 ? "1A / 1B" : -+ chip_rev == 0x5 ? "1C / 1D" : -+ chip_rev == 0x6 ? "1E" : -+ chip_rev == 0x7 ? "1F" : "unknown", -+ ov7251->i2c_client->addr); -+ -+ return 0; -+} -+ - static int ov7251_probe(struct i2c_client *client) - { - struct v4l2_fwnode_device_properties props; - struct device *dev = &client->dev; - struct ov7251 *ov7251; -- u8 chip_id_high, chip_id_low, chip_rev; - unsigned int rate = 0; - int ret; - int i; -@@ -1589,34 +1621,10 @@ static int ov7251_probe(struct i2c_clien - goto free_entity; - } - -- ret = ov7251_read_reg(ov7251, OV7251_CHIP_ID_HIGH, &chip_id_high); -- if (ret < 0 || chip_id_high != OV7251_CHIP_ID_HIGH_BYTE) { -- dev_err(dev, "could not read ID high\n"); -- ret = -ENODEV; -- goto power_down; -- } -- ret = ov7251_read_reg(ov7251, OV7251_CHIP_ID_LOW, &chip_id_low); -- if (ret < 0 || chip_id_low != OV7251_CHIP_ID_LOW_BYTE) { -- dev_err(dev, "could not read ID low\n"); -- ret = -ENODEV; -- goto power_down; -- } -- -- ret = ov7251_read_reg(ov7251, OV7251_SC_GP_IO_IN1, &chip_rev); -- if (ret < 0) { -- dev_err(dev, "could not read revision\n"); -- ret = -ENODEV; -+ ret = ov7251_detect_chip(ov7251); -+ if (ret) - goto power_down; -- } -- chip_rev >>= 4; - -- dev_info(dev, "OV7251 revision %x (%s) detected at address 0x%02x\n", -- chip_rev, -- chip_rev == 0x4 ? "1A / 1B" : -- chip_rev == 0x5 ? "1C / 1D" : -- chip_rev == 0x6 ? "1E" : -- chip_rev == 0x7 ? "1F" : "unknown", -- client->addr); - - ret = ov7251_read_reg(ov7251, OV7251_PRE_ISP_00, - &ov7251->pre_isp_00); diff --git a/target/linux/bcm27xx/patches-5.15/950-0724-media-i2c-Add-pm_runtime-support-to-ov7251.patch b/target/linux/bcm27xx/patches-5.15/950-0724-media-i2c-Add-pm_runtime-support-to-ov7251.patch deleted file mode 100644 index 3f1c9b50f..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0724-media-i2c-Add-pm_runtime-support-to-ov7251.patch +++ /dev/null @@ -1,208 +0,0 @@ -From 1768a6f48030e8b670ca3aad08e078bd4bd3ef64 Mon Sep 17 00:00:00 2001 -From: Daniel Scally -Date: Tue, 15 Feb 2022 23:07:35 +0000 -Subject: [PATCH] media: i2c: Add pm_runtime support to ov7251 - -Add pm_runtime support to the ov7251 driver. - -Signed-off-by: Daniel Scally ---- - drivers/media/i2c/ov7251.c | 78 ++++++++++++++++++++++++++++++-------- - 1 file changed, 63 insertions(+), 15 deletions(-) - ---- a/drivers/media/i2c/ov7251.c -+++ b/drivers/media/i2c/ov7251.c -@@ -15,6 +15,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -884,6 +885,24 @@ static void ov7251_set_power_off(struct - ov7251_regulators_disable(ov7251); - } - -+static int __maybe_unused ov7251_sensor_suspend(struct device *dev) -+{ -+ struct v4l2_subdev *sd = dev_get_drvdata(dev); -+ struct ov7251 *ov7251 = to_ov7251(sd); -+ -+ ov7251_set_power_off(ov7251); -+ -+ return 0; -+} -+ -+static int __maybe_unused ov7251_sensor_resume(struct device *dev) -+{ -+ struct v4l2_subdev *sd = dev_get_drvdata(dev); -+ struct ov7251 *ov7251 = to_ov7251(sd); -+ -+ return ov7251_set_power_on(ov7251); -+} -+ - static int ov7251_s_power(struct v4l2_subdev *sd, int on) - { - struct ov7251 *ov7251 = to_ov7251(sd); -@@ -985,7 +1004,7 @@ static int ov7251_s_ctrl(struct v4l2_ctr - - /* v4l2_ctrl_lock() locks our mutex */ - -- if (!ov7251->power_on) -+ if (!pm_runtime_get_if_in_use(ov7251->dev)) - return 0; - - switch (ctrl->id) { -@@ -1009,6 +1028,8 @@ static int ov7251_s_ctrl(struct v4l2_ctr - break; - } - -+ pm_runtime_put(ov7251->dev); -+ - return ret; - } - -@@ -1261,10 +1282,15 @@ static int ov7251_s_stream(struct v4l2_s - mutex_lock(&ov7251->lock); - - if (enable) { -+ ret = pm_runtime_get_sync(ov7251->dev); -+ if (ret < 0) -+ return ret; -+ - ret = ov7251_pll_configure(ov7251); -- if (ret) -- return dev_err_probe(ov7251->dev, ret, -- "error configuring PLLs\n"); -+ if (ret) { -+ dev_err(ov7251->dev, "error configuring PLLs\n"); -+ goto err_power_down; -+ } - - ret = ov7251_set_register_array(ov7251, - ov7251->current_mode->data, -@@ -1273,23 +1299,29 @@ static int ov7251_s_stream(struct v4l2_s - dev_err(ov7251->dev, "could not set mode %dx%d\n", - ov7251->current_mode->width, - ov7251->current_mode->height); -- goto exit; -+ goto err_power_down; - } - ret = __v4l2_ctrl_handler_setup(&ov7251->ctrls); - if (ret < 0) { - dev_err(ov7251->dev, "could not sync v4l2 controls\n"); -- goto exit; -+ goto err_power_down; - } - ret = ov7251_write_reg(ov7251, OV7251_SC_MODE_SELECT, - OV7251_SC_MODE_SELECT_STREAMING); -+ if (ret) -+ goto err_power_down; - } else { - ret = ov7251_write_reg(ov7251, OV7251_SC_MODE_SELECT, - OV7251_SC_MODE_SELECT_SW_STANDBY); -+ pm_runtime_put(ov7251->dev); - } - --exit: - mutex_unlock(&ov7251->lock); -+ return ret; - -+err_power_down: -+ pm_runtime_put_noidle(ov7251->dev); -+ mutex_unlock(&ov7251->lock); - return ret; - } - -@@ -1615,23 +1647,24 @@ static int ov7251_probe(struct i2c_clien - goto free_ctrl; - } - -- ret = ov7251_s_power(&ov7251->sd, true); -- if (ret < 0) { -- dev_err(dev, "could not power up OV7251\n"); -+ ret = ov7251_set_power_on(ov7251); -+ if (ret) - goto free_entity; -- } - - ret = ov7251_detect_chip(ov7251); - if (ret) - goto power_down; - -+ pm_runtime_set_active(&client->dev); -+ pm_runtime_get_noresume(&client->dev); -+ pm_runtime_enable(&client->dev); - - ret = ov7251_read_reg(ov7251, OV7251_PRE_ISP_00, - &ov7251->pre_isp_00); - if (ret < 0) { - dev_err(dev, "could not read test pattern value\n"); - ret = -ENODEV; -- goto power_down; -+ goto err_pm_runtime; - } - - ret = ov7251_read_reg(ov7251, OV7251_TIMING_FORMAT1, -@@ -1639,7 +1672,7 @@ static int ov7251_probe(struct i2c_clien - if (ret < 0) { - dev_err(dev, "could not read vflip value\n"); - ret = -ENODEV; -- goto power_down; -+ goto err_pm_runtime; - } - - ret = ov7251_read_reg(ov7251, OV7251_TIMING_FORMAT2, -@@ -1647,10 +1680,12 @@ static int ov7251_probe(struct i2c_clien - if (ret < 0) { - dev_err(dev, "could not read hflip value\n"); - ret = -ENODEV; -- goto power_down; -+ goto err_pm_runtime; - } - -- ov7251_s_power(&ov7251->sd, false); -+ pm_runtime_set_autosuspend_delay(&client->dev, 1000); -+ pm_runtime_use_autosuspend(&client->dev); -+ pm_runtime_put_autosuspend(&client->dev); - - ret = v4l2_async_register_subdev(&ov7251->sd); - if (ret < 0) { -@@ -1662,6 +1697,9 @@ static int ov7251_probe(struct i2c_clien - - return 0; - -+err_pm_runtime: -+ pm_runtime_disable(ov7251->dev); -+ pm_runtime_put_noidle(ov7251->dev); - power_down: - ov7251_s_power(&ov7251->sd, false); - free_entity: -@@ -1683,9 +1721,18 @@ static int ov7251_remove(struct i2c_clie - v4l2_ctrl_handler_free(&ov7251->ctrls); - mutex_destroy(&ov7251->lock); - -+ pm_runtime_disable(ov7251->dev); -+ if (!pm_runtime_status_suspended(ov7251->dev)) -+ ov7251_set_power_off(ov7251); -+ pm_runtime_set_suspended(ov7251->dev); -+ - return 0; - } - -+static const struct dev_pm_ops ov7251_pm_ops = { -+ SET_RUNTIME_PM_OPS(ov7251_sensor_suspend, ov7251_sensor_resume, NULL) -+}; -+ - static const struct of_device_id ov7251_of_match[] = { - { .compatible = "ovti,ov7251" }, - { /* sentinel */ } -@@ -1703,6 +1750,7 @@ static struct i2c_driver ov7251_i2c_driv - .of_match_table = ov7251_of_match, - .acpi_match_table = ov7251_acpi_match, - .name = "ov7251", -+ .pm = &ov7251_pm_ops, - }, - .probe_new = ov7251_probe, - .remove = ov7251_remove, diff --git a/target/linux/bcm27xx/patches-5.15/950-0725-media-i2c-Remove-.s_power-from-ov7251.patch b/target/linux/bcm27xx/patches-5.15/950-0725-media-i2c-Remove-.s_power-from-ov7251.patch deleted file mode 100644 index 0376a1a90..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0725-media-i2c-Remove-.s_power-from-ov7251.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 27a8c7902543676a670424b28fb9b43c6c4ce59b Mon Sep 17 00:00:00 2001 -From: Daniel Scally -Date: Tue, 15 Feb 2022 23:07:36 +0000 -Subject: [PATCH] media: i2c: Remove .s_power() from ov7251 - -The .s_power() callback is deprecated, and now that we have pm_runtime -functionality in the driver there's no further use for it. Delete the -function. - -Signed-off-by: Daniel Scally -Reported-by: kernel test robot ---- - drivers/media/i2c/ov7251.c | 44 +------------------------------------- - 1 file changed, 1 insertion(+), 43 deletions(-) - ---- a/drivers/media/i2c/ov7251.c -+++ b/drivers/media/i2c/ov7251.c -@@ -903,43 +903,6 @@ static int __maybe_unused ov7251_sensor_ - return ov7251_set_power_on(ov7251); - } - --static int ov7251_s_power(struct v4l2_subdev *sd, int on) --{ -- struct ov7251 *ov7251 = to_ov7251(sd); -- int ret = 0; -- -- mutex_lock(&ov7251->lock); -- -- /* If the power state is not modified - no work to do. */ -- if (ov7251->power_on == !!on) -- goto exit; -- -- if (on) { -- ret = ov7251_set_power_on(ov7251); -- if (ret < 0) -- goto exit; -- -- ret = ov7251_set_register_array(ov7251, -- ov7251_global_init_setting, -- ARRAY_SIZE(ov7251_global_init_setting)); -- if (ret < 0) { -- dev_err(ov7251->dev, "could not set init registers\n"); -- ov7251_set_power_off(ov7251); -- goto exit; -- } -- -- ov7251->power_on = true; -- } else { -- ov7251_set_power_off(ov7251); -- ov7251->power_on = false; -- } -- --exit: -- mutex_unlock(&ov7251->lock); -- -- return ret; --} -- - static int ov7251_set_hflip(struct ov7251 *ov7251, s32 value) - { - u8 val = ov7251->timing_format2; -@@ -1384,10 +1347,6 @@ exit: - return ret; - } - --static const struct v4l2_subdev_core_ops ov7251_core_ops = { -- .s_power = ov7251_s_power, --}; -- - static const struct v4l2_subdev_video_ops ov7251_video_ops = { - .s_stream = ov7251_s_stream, - .g_frame_interval = ov7251_get_frame_interval, -@@ -1405,7 +1364,6 @@ static const struct v4l2_subdev_pad_ops - }; - - static const struct v4l2_subdev_ops ov7251_subdev_ops = { -- .core = &ov7251_core_ops, - .video = &ov7251_video_ops, - .pad = &ov7251_subdev_pad_ops, - }; -@@ -1701,7 +1659,7 @@ err_pm_runtime: - pm_runtime_disable(ov7251->dev); - pm_runtime_put_noidle(ov7251->dev); - power_down: -- ov7251_s_power(&ov7251->sd, false); -+ ov7251_set_power_off(ov7251); - free_entity: - media_entity_cleanup(&ov7251->sd.entity); - free_ctrl: diff --git a/target/linux/bcm27xx/patches-5.15/950-0727-media-i2c-ov7251-V4L2_CID_PIXEL_RATE-is-fixed.patch b/target/linux/bcm27xx/patches-5.15/950-0727-media-i2c-ov7251-V4L2_CID_PIXEL_RATE-is-fixed.patch deleted file mode 100644 index 80503693b..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0727-media-i2c-ov7251-V4L2_CID_PIXEL_RATE-is-fixed.patch +++ /dev/null @@ -1,104 +0,0 @@ -From 1fbe6c846412c7c114f599fef881366f1e81ef9c Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Sat, 12 Feb 2022 09:47:38 +0000 -Subject: [PATCH] media: i2c: ov7251: V4L2_CID_PIXEL_RATE is fixed - -The pixel rate doesn't actually change based on the mode, and -can not be set by userspace. - -Fix the control. The control is already read only as set by the core. - -Signed-off-by: Dave Stevenson ---- - drivers/media/i2c/ov7251.c | 24 +++++------------------- - 1 file changed, 5 insertions(+), 19 deletions(-) - ---- a/drivers/media/i2c/ov7251.c -+++ b/drivers/media/i2c/ov7251.c -@@ -54,6 +54,8 @@ - #define OV7251_PLL2_SYS_DIV_REG 0x309a - #define OV7251_PLL2_ADC_DIV_REG 0x309b - -+#define OV7251_PIXEL_CLOCK 48000000 -+ - struct reg_value { - u16 reg; - u8 val; -@@ -64,7 +66,6 @@ struct ov7251_mode_info { - u32 height; - const struct reg_value *data; - u32 data_size; -- u32 pixel_clock; - u32 link_freq; - u16 exposure_max; - u16 exposure_def; -@@ -112,7 +113,6 @@ struct ov7251 { - const struct ov7251_mode_info *current_mode; - - struct v4l2_ctrl_handler ctrls; -- struct v4l2_ctrl *pixel_clock; - struct v4l2_ctrl *link_freq; - struct v4l2_ctrl *exposure; - struct v4l2_ctrl *gain; -@@ -591,7 +591,6 @@ static const struct ov7251_mode_info ov7 - .height = 480, - .data = ov7251_setting_vga_30fps, - .data_size = ARRAY_SIZE(ov7251_setting_vga_30fps), -- .pixel_clock = 48000000, - .link_freq = 0, /* an index in link_freq[] */ - .exposure_max = 1704, - .exposure_def = 504, -@@ -605,7 +604,6 @@ static const struct ov7251_mode_info ov7 - .height = 480, - .data = ov7251_setting_vga_60fps, - .data_size = ARRAY_SIZE(ov7251_setting_vga_60fps), -- .pixel_clock = 48000000, - .link_freq = 0, /* an index in link_freq[] */ - .exposure_max = 840, - .exposure_def = 504, -@@ -619,7 +617,6 @@ static const struct ov7251_mode_info ov7 - .height = 480, - .data = ov7251_setting_vga_90fps, - .data_size = ARRAY_SIZE(ov7251_setting_vga_90fps), -- .pixel_clock = 48000000, - .link_freq = 0, /* an index in link_freq[] */ - .exposure_max = 552, - .exposure_def = 504, -@@ -1155,11 +1152,6 @@ static int ov7251_set_format(struct v4l2 - __crop->height = new_mode->height; - - if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) { -- ret = __v4l2_ctrl_s_ctrl_int64(ov7251->pixel_clock, -- new_mode->pixel_clock); -- if (ret < 0) -- goto exit; -- - ret = __v4l2_ctrl_s_ctrl(ov7251->link_freq, - new_mode->link_freq); - if (ret < 0) -@@ -1319,11 +1311,6 @@ static int ov7251_set_frame_interval(str - new_mode = ov7251_find_mode_by_ival(ov7251, &fi->interval); - - if (new_mode != ov7251->current_mode) { -- ret = __v4l2_ctrl_s_ctrl_int64(ov7251->pixel_clock, -- new_mode->pixel_clock); -- if (ret < 0) -- goto exit; -- - ret = __v4l2_ctrl_s_ctrl(ov7251->link_freq, - new_mode->link_freq); - if (ret < 0) -@@ -1571,10 +1558,9 @@ static int ov7251_probe(struct i2c_clien - V4L2_CID_TEST_PATTERN, - ARRAY_SIZE(ov7251_test_pattern_menu) - 1, - 0, 0, ov7251_test_pattern_menu); -- ov7251->pixel_clock = v4l2_ctrl_new_std(&ov7251->ctrls, -- &ov7251_ctrl_ops, -- V4L2_CID_PIXEL_RATE, -- 1, INT_MAX, 1, 1); -+ v4l2_ctrl_new_std(&ov7251->ctrls, &ov7251_ctrl_ops, -+ V4L2_CID_PIXEL_RATE, OV7251_PIXEL_CLOCK, -+ OV7251_PIXEL_CLOCK, 1, OV7251_PIXEL_CLOCK); - ov7251->link_freq = v4l2_ctrl_new_int_menu(&ov7251->ctrls, - &ov7251_ctrl_ops, - V4L2_CID_LINK_FREQ, diff --git a/target/linux/bcm27xx/patches-5.15/950-0728-media-i2c-ov7251-V4L2_CID_LINK_FREQUENCY-is-fixed.patch b/target/linux/bcm27xx/patches-5.15/950-0728-media-i2c-ov7251-V4L2_CID_LINK_FREQUENCY-is-fixed.patch deleted file mode 100644 index ddd9e6e3b..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0728-media-i2c-ov7251-V4L2_CID_LINK_FREQUENCY-is-fixed.patch +++ /dev/null @@ -1,107 +0,0 @@ -From f8c8c6aed54e064f3ec36eeee0595ec4e2206d66 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Sat, 12 Feb 2022 09:53:47 +0000 -Subject: [PATCH] media: i2c: ov7251: V4L2_CID_LINK_FREQUENCY is fixed - -The link frequency does not change with the mode, so remove -the special handling for it. - -Signed-off-by: Dave Stevenson ---- - drivers/media/i2c/ov7251.c | 29 +++++++---------------------- - 1 file changed, 7 insertions(+), 22 deletions(-) - ---- a/drivers/media/i2c/ov7251.c -+++ b/drivers/media/i2c/ov7251.c -@@ -66,7 +66,6 @@ struct ov7251_mode_info { - u32 height; - const struct reg_value *data; - u32 data_size; -- u32 link_freq; - u16 exposure_max; - u16 exposure_def; - struct v4l2_fract timeperframe; -@@ -113,7 +112,6 @@ struct ov7251 { - const struct ov7251_mode_info *current_mode; - - struct v4l2_ctrl_handler ctrls; -- struct v4l2_ctrl *link_freq; - struct v4l2_ctrl *exposure; - struct v4l2_ctrl *gain; - -@@ -591,7 +589,6 @@ static const struct ov7251_mode_info ov7 - .height = 480, - .data = ov7251_setting_vga_30fps, - .data_size = ARRAY_SIZE(ov7251_setting_vga_30fps), -- .link_freq = 0, /* an index in link_freq[] */ - .exposure_max = 1704, - .exposure_def = 504, - .timeperframe = { -@@ -604,7 +601,6 @@ static const struct ov7251_mode_info ov7 - .height = 480, - .data = ov7251_setting_vga_60fps, - .data_size = ARRAY_SIZE(ov7251_setting_vga_60fps), -- .link_freq = 0, /* an index in link_freq[] */ - .exposure_max = 840, - .exposure_def = 504, - .timeperframe = { -@@ -617,7 +613,6 @@ static const struct ov7251_mode_info ov7 - .height = 480, - .data = ov7251_setting_vga_90fps, - .data_size = ARRAY_SIZE(ov7251_setting_vga_90fps), -- .link_freq = 0, /* an index in link_freq[] */ - .exposure_max = 552, - .exposure_def = 504, - .timeperframe = { -@@ -1152,11 +1147,6 @@ static int ov7251_set_format(struct v4l2 - __crop->height = new_mode->height; - - if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) { -- ret = __v4l2_ctrl_s_ctrl(ov7251->link_freq, -- new_mode->link_freq); -- if (ret < 0) -- goto exit; -- - ret = __v4l2_ctrl_modify_range(ov7251->exposure, - 1, new_mode->exposure_max, - 1, new_mode->exposure_def); -@@ -1311,11 +1301,6 @@ static int ov7251_set_frame_interval(str - new_mode = ov7251_find_mode_by_ival(ov7251, &fi->interval); - - if (new_mode != ov7251->current_mode) { -- ret = __v4l2_ctrl_s_ctrl(ov7251->link_freq, -- new_mode->link_freq); -- if (ret < 0) -- goto exit; -- - ret = __v4l2_ctrl_modify_range(ov7251->exposure, - 1, new_mode->exposure_max, - 1, new_mode->exposure_def); -@@ -1464,6 +1449,7 @@ static int ov7251_probe(struct i2c_clien - { - struct v4l2_fwnode_device_properties props; - struct device *dev = &client->dev; -+ struct v4l2_ctrl *ctrl; - struct ov7251 *ov7251; - unsigned int rate = 0; - int ret; -@@ -1561,13 +1547,12 @@ static int ov7251_probe(struct i2c_clien - v4l2_ctrl_new_std(&ov7251->ctrls, &ov7251_ctrl_ops, - V4L2_CID_PIXEL_RATE, OV7251_PIXEL_CLOCK, - OV7251_PIXEL_CLOCK, 1, OV7251_PIXEL_CLOCK); -- ov7251->link_freq = v4l2_ctrl_new_int_menu(&ov7251->ctrls, -- &ov7251_ctrl_ops, -- V4L2_CID_LINK_FREQ, -- ARRAY_SIZE(link_freq) - 1, -- 0, link_freq); -- if (ov7251->link_freq) -- ov7251->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; -+ ctrl = v4l2_ctrl_new_int_menu(&ov7251->ctrls, &ov7251_ctrl_ops, -+ V4L2_CID_LINK_FREQ, -+ ARRAY_SIZE(link_freq) - 1, -+ 0, link_freq); -+ if (ctrl) -+ ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; - - ov7251->sd.ctrl_handler = &ov7251->ctrls; - diff --git a/target/linux/bcm27xx/patches-5.15/950-0729-media-i2c-ov7251-Initialise-current_mode-during-prob.patch b/target/linux/bcm27xx/patches-5.15/950-0729-media-i2c-ov7251-Initialise-current_mode-during-prob.patch deleted file mode 100644 index 84b1252e1..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0729-media-i2c-ov7251-Initialise-current_mode-during-prob.patch +++ /dev/null @@ -1,26 +0,0 @@ -From cd239eeb0ed6bea434b88d38a5fd8a775f199144 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Sat, 12 Feb 2022 11:57:19 +0000 -Subject: [PATCH] media: i2c: ov7251: Initialise current_mode during - probe - -Initialise ov7251->current_mode during probe to avoid the issue -of a NULL dereference should get_frame_interval be called before -set_frame_interval or set_format. - -Signed-off-by: Dave Stevenson ---- - drivers/media/i2c/ov7251.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/media/i2c/ov7251.c -+++ b/drivers/media/i2c/ov7251.c -@@ -1529,6 +1529,8 @@ static int ov7251_probe(struct i2c_clien - - mutex_init(&ov7251->lock); - -+ ov7251->current_mode = &ov7251_mode_info_data[0]; -+ - v4l2_ctrl_handler_init(&ov7251->ctrls, 9); - ov7251->ctrls.lock = &ov7251->lock; - diff --git a/target/linux/bcm27xx/patches-5.15/950-0730-media-i2c-ov7251-Add-V4L2_CID_HBLANK-control.patch b/target/linux/bcm27xx/patches-5.15/950-0730-media-i2c-ov7251-Add-V4L2_CID_HBLANK-control.patch deleted file mode 100644 index c0f8f5dd8..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0730-media-i2c-ov7251-Add-V4L2_CID_HBLANK-control.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 45a2ad18add0e5c14d1cad5ef0c2c10097b583d9 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Sat, 12 Feb 2022 12:05:02 +0000 -Subject: [PATCH] media: i2c: ov7251: Add V4L2_CID_HBLANK control - -HBLANK is a fixed value in this driver, so add as a fixed -read-only control. -The value is updated during set_format as the V4L2 control is -dependent on width, even though only one width is actually -defined. - -Signed-off-by: Dave Stevenson ---- - drivers/media/i2c/ov7251.c | 18 +++++++++++++++++- - 1 file changed, 17 insertions(+), 1 deletion(-) - ---- a/drivers/media/i2c/ov7251.c -+++ b/drivers/media/i2c/ov7251.c -@@ -37,6 +37,8 @@ - #define OV7251_AEC_EXPO_2 0x3502 - #define OV7251_AEC_AGC_ADJ_0 0x350a - #define OV7251_AEC_AGC_ADJ_1 0x350b -+ /* HTS is registers 0x380c and 0x380d */ -+#define OV7251_HTS 0x3a0 - #define OV7251_TIMING_FORMAT1 0x3820 - #define OV7251_TIMING_FORMAT1_VFLIP BIT(2) - #define OV7251_TIMING_FORMAT2 0x3821 -@@ -114,6 +116,7 @@ struct ov7251 { - struct v4l2_ctrl_handler ctrls; - struct v4l2_ctrl *exposure; - struct v4l2_ctrl *gain; -+ struct v4l2_ctrl *hblank; - - /* Cached register values */ - u8 aec_pk_manual; -@@ -1131,6 +1134,7 @@ static int ov7251_set_format(struct v4l2 - struct v4l2_mbus_framefmt *__format; - struct v4l2_rect *__crop; - const struct ov7251_mode_info *new_mode; -+ s64 h_blank; - int ret = 0; - - mutex_lock(&ov7251->lock); -@@ -1147,6 +1151,11 @@ static int ov7251_set_format(struct v4l2 - __crop->height = new_mode->height; - - if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) { -+ h_blank = OV7251_HTS - new_mode->width; -+ __v4l2_ctrl_modify_range(ov7251->hblank, h_blank, -+ h_blank, 1, h_blank); -+ __v4l2_ctrl_s_ctrl(ov7251->hblank, h_blank); -+ - ret = __v4l2_ctrl_modify_range(ov7251->exposure, - 1, new_mode->exposure_max, - 1, new_mode->exposure_def); -@@ -1452,6 +1461,7 @@ static int ov7251_probe(struct i2c_clien - struct v4l2_ctrl *ctrl; - struct ov7251 *ov7251; - unsigned int rate = 0; -+ u32 h_blank; - int ret; - int i; - -@@ -1531,7 +1541,7 @@ static int ov7251_probe(struct i2c_clien - - ov7251->current_mode = &ov7251_mode_info_data[0]; - -- v4l2_ctrl_handler_init(&ov7251->ctrls, 9); -+ v4l2_ctrl_handler_init(&ov7251->ctrls, 10); - ov7251->ctrls.lock = &ov7251->lock; - - v4l2_ctrl_new_std(&ov7251->ctrls, &ov7251_ctrl_ops, -@@ -1555,6 +1565,12 @@ static int ov7251_probe(struct i2c_clien - 0, link_freq); - if (ctrl) - ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; -+ h_blank = OV7251_HTS - ov7251->current_mode->width; -+ ov7251->hblank = v4l2_ctrl_new_std(&ov7251->ctrls, NULL, -+ V4L2_CID_HBLANK, h_blank, -+ h_blank, 1, h_blank); -+ if (ov7251->hblank) -+ ov7251->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; - - ov7251->sd.ctrl_handler = &ov7251->ctrls; - diff --git a/target/linux/bcm27xx/patches-5.15/950-0731-media-i2c-ov7251-Do-not-reset-gain-on-mode-change.patch b/target/linux/bcm27xx/patches-5.15/950-0731-media-i2c-ov7251-Do-not-reset-gain-on-mode-change.patch deleted file mode 100644 index fba048c72..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0731-media-i2c-ov7251-Do-not-reset-gain-on-mode-change.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 46773bdd99e4ab1bd0d65931ef782122f4f4a031 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Sat, 12 Feb 2022 12:33:13 +0000 -Subject: [PATCH] media: i2c: ov7251: Do not reset gain on mode change - -There is no reaon why changing mode should reset the analogue -gain of the sensor, and it's not the behaviour that userspace -will be expecting. -Remove the reset. - -Signed-off-by: Dave Stevenson ---- - drivers/media/i2c/ov7251.c | 13 ++----------- - 1 file changed, 2 insertions(+), 11 deletions(-) - ---- a/drivers/media/i2c/ov7251.c -+++ b/drivers/media/i2c/ov7251.c -@@ -115,7 +115,6 @@ struct ov7251 { - - struct v4l2_ctrl_handler ctrls; - struct v4l2_ctrl *exposure; -- struct v4l2_ctrl *gain; - struct v4l2_ctrl *hblank; - - /* Cached register values */ -@@ -1167,10 +1166,6 @@ static int ov7251_set_format(struct v4l2 - if (ret < 0) - goto exit; - -- ret = __v4l2_ctrl_s_ctrl(ov7251->gain, 16); -- if (ret < 0) -- goto exit; -- - ov7251->current_mode = new_mode; - } - -@@ -1321,10 +1316,6 @@ static int ov7251_set_frame_interval(str - if (ret < 0) - goto exit; - -- ret = __v4l2_ctrl_s_ctrl(ov7251->gain, 16); -- if (ret < 0) -- goto exit; -- - ov7251->current_mode = new_mode; - } - -@@ -1550,8 +1541,8 @@ static int ov7251_probe(struct i2c_clien - V4L2_CID_VFLIP, 0, 1, 1, 0); - ov7251->exposure = v4l2_ctrl_new_std(&ov7251->ctrls, &ov7251_ctrl_ops, - V4L2_CID_EXPOSURE, 1, 32, 1, 32); -- ov7251->gain = v4l2_ctrl_new_std(&ov7251->ctrls, &ov7251_ctrl_ops, -- V4L2_CID_GAIN, 16, 1023, 1, 16); -+ v4l2_ctrl_new_std(&ov7251->ctrls, &ov7251_ctrl_ops, V4L2_CID_GAIN, -+ 16, 1023, 1, 16); - v4l2_ctrl_new_std_menu_items(&ov7251->ctrls, &ov7251_ctrl_ops, - V4L2_CID_TEST_PATTERN, - ARRAY_SIZE(ov7251_test_pattern_menu) - 1, diff --git a/target/linux/bcm27xx/patches-5.15/950-0732-media-i2c-ov7251-Fix-link_freq-validation-loop.patch b/target/linux/bcm27xx/patches-5.15/950-0732-media-i2c-ov7251-Fix-link_freq-validation-loop.patch deleted file mode 100644 index 560b31d85..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0732-media-i2c-ov7251-Fix-link_freq-validation-loop.patch +++ /dev/null @@ -1,33 +0,0 @@ -From fd7067bd245a90d957b70ce8be96b2a4d7b970a6 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 17 Feb 2022 15:57:01 +0000 -Subject: [PATCH] media: i2c: ov7251: Fix link_freq validation loop - -If only one link frequency was configured, then ov7251_check_hwcfg -failed as the conditions weren't checked in the appropriate places. - -Signed-off-by: Dave Stevenson ---- - drivers/media/i2c/ov7251.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/drivers/media/i2c/ov7251.c -+++ b/drivers/media/i2c/ov7251.c -@@ -1390,14 +1390,14 @@ static int ov7251_check_hwcfg(struct ov7 - - freq_found = false; - for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) { -- if (freq_found) -- break; -- - for (j = 0; j < ARRAY_SIZE(link_freq); j++) - if (bus_cfg.link_frequencies[i] == link_freq[j]) { - freq_found = true; - break; - } -+ -+ if (freq_found) -+ break; - } - - if (i == bus_cfg.nr_of_link_frequencies) { diff --git a/target/linux/bcm27xx/patches-5.15/950-0733-media-i2c-ov7251-Add-get_selection-for-NATIVE_SIZE-C.patch b/target/linux/bcm27xx/patches-5.15/950-0733-media-i2c-ov7251-Add-get_selection-for-NATIVE_SIZE-C.patch deleted file mode 100644 index ae76c0551..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0733-media-i2c-ov7251-Add-get_selection-for-NATIVE_SIZE-C.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 71fdb5d9021eb4aba727af8e5a7daedeb2f00860 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 17 Feb 2022 16:23:23 +0000 -Subject: [PATCH] media: i2c: ov7251: Add get_selection for - NATIVE_SIZE, CROP_BOUNDS, CROP_DEFAULT - -As required by libcamera, add get_selection handling for -V4L2_SEL_TGT_NATIVE_SIZE, V4L2_SEL_TGT_CROP_DEFAULT, and -V4L2_SEL_TGT_CROP_BOUNDS. - -Signed-off-by: Dave Stevenson ---- - drivers/media/i2c/ov7251.c | 45 ++++++++++++++++++++++++++++++++------ - 1 file changed, 38 insertions(+), 7 deletions(-) - ---- a/drivers/media/i2c/ov7251.c -+++ b/drivers/media/i2c/ov7251.c -@@ -56,6 +56,18 @@ - #define OV7251_PLL2_SYS_DIV_REG 0x309a - #define OV7251_PLL2_ADC_DIV_REG 0x309b - -+/* -+ * OV7251 native and active pixel array size. -+ * Datasheet not available to confirm these values, so assume there are no -+ * border pixels. -+ */ -+#define OV7251_NATIVE_WIDTH 640U -+#define OV7251_NATIVE_HEIGHT 480U -+#define OV7251_PIXEL_ARRAY_LEFT 0U -+#define OV7251_PIXEL_ARRAY_TOP 0U -+#define OV7251_PIXEL_ARRAY_WIDTH 640U -+#define OV7251_PIXEL_ARRAY_HEIGHT 480U -+ - #define OV7251_PIXEL_CLOCK 48000000 - - struct reg_value { -@@ -1212,15 +1224,34 @@ static int ov7251_get_selection(struct v - { - struct ov7251 *ov7251 = to_ov7251(sd); - -- if (sel->target != V4L2_SEL_TGT_CROP) -- return -EINVAL; -+ switch (sel->target) { -+ case V4L2_SEL_TGT_CROP: -+ mutex_lock(&ov7251->lock); -+ sel->r = *__ov7251_get_pad_crop(ov7251, sd_state, sel->pad, -+ sel->which); -+ mutex_unlock(&ov7251->lock); - -- mutex_lock(&ov7251->lock); -- sel->r = *__ov7251_get_pad_crop(ov7251, sd_state, sel->pad, -- sel->which); -- mutex_unlock(&ov7251->lock); -+ return 0; - -- return 0; -+ case V4L2_SEL_TGT_NATIVE_SIZE: -+ sel->r.top = 0; -+ sel->r.left = 0; -+ sel->r.width = OV7251_NATIVE_WIDTH; -+ sel->r.height = OV7251_NATIVE_HEIGHT; -+ -+ return 0; -+ -+ case V4L2_SEL_TGT_CROP_DEFAULT: -+ case V4L2_SEL_TGT_CROP_BOUNDS: -+ sel->r.top = OV7251_PIXEL_ARRAY_TOP; -+ sel->r.left = OV7251_PIXEL_ARRAY_LEFT; -+ sel->r.width = OV7251_PIXEL_ARRAY_WIDTH; -+ sel->r.height = OV7251_PIXEL_ARRAY_HEIGHT; -+ -+ return 0; -+ } -+ -+ return -EINVAL; - } - - static int ov7251_s_stream(struct v4l2_subdev *subdev, int enable) diff --git a/target/linux/bcm27xx/patches-5.15/950-0734-media-i2c-ov7251-Set-VTS-instead-of-having-full-tabl.patch b/target/linux/bcm27xx/patches-5.15/950-0734-media-i2c-ov7251-Set-VTS-instead-of-having-full-tabl.patch deleted file mode 100644 index 3e08ae27a..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0734-media-i2c-ov7251-Set-VTS-instead-of-having-full-tabl.patch +++ /dev/null @@ -1,373 +0,0 @@ -From 26934caec8e9a365d71e437333998002b2f2879c Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 17 Feb 2022 16:24:51 +0000 -Subject: [PATCH] media: i2c: ov7251: Set VTS instead of having full - tables for FPS. - -The driver did have a full copy of the registers for each of -the 30, 60, and 90 fps modes. The main difference between them were -registers 0x380e/f which set the total height of the frame (VTS). - -Remove the excess register settings, and Set that register value -explicitly for each mode. - -This has dropped a change for the 30fps mode to registers 0x3016, -0x3017, 0x3018, 0x301a, 0x301b, and 0x301c. The data available -doesn't describe these registers, but the sensor seems fully -functional without the alternate settings. - -Signed-off-by: Dave Stevenson ---- - drivers/media/i2c/ov7251.c | 286 +++---------------------------------- - 1 file changed, 21 insertions(+), 265 deletions(-) - ---- a/drivers/media/i2c/ov7251.c -+++ b/drivers/media/i2c/ov7251.c -@@ -39,6 +39,8 @@ - #define OV7251_AEC_AGC_ADJ_1 0x350b - /* HTS is registers 0x380c and 0x380d */ - #define OV7251_HTS 0x3a0 -+#define OV7251_VTS_HIGH 0x380e -+#define OV7251_VTS_LOW 0x380f - #define OV7251_TIMING_FORMAT1 0x3820 - #define OV7251_TIMING_FORMAT1_VFLIP BIT(2) - #define OV7251_TIMING_FORMAT2 0x3821 -@@ -82,6 +84,7 @@ struct ov7251_mode_info { - u32 data_size; - u16 exposure_max; - u16 exposure_def; -+ u16 vts; - struct v4l2_fract timeperframe; - }; - -@@ -204,263 +207,7 @@ static const struct reg_value ov7251_glo - { 0x303b, 0x02 }, - }; - --static const struct reg_value ov7251_setting_vga_30fps[] = { -- { 0x3005, 0x00 }, -- { 0x3012, 0xc0 }, -- { 0x3013, 0xd2 }, -- { 0x3014, 0x04 }, -- { 0x3016, 0xf0 }, -- { 0x3017, 0xf0 }, -- { 0x3018, 0xf0 }, -- { 0x301a, 0xf0 }, -- { 0x301b, 0xf0 }, -- { 0x301c, 0xf0 }, -- { 0x3023, 0x05 }, -- { 0x3037, 0xf0 }, -- { 0x3106, 0xda }, -- { 0x3503, 0x07 }, -- { 0x3509, 0x10 }, -- { 0x3600, 0x1c }, -- { 0x3602, 0x62 }, -- { 0x3620, 0xb7 }, -- { 0x3622, 0x04 }, -- { 0x3626, 0x21 }, -- { 0x3627, 0x30 }, -- { 0x3630, 0x44 }, -- { 0x3631, 0x35 }, -- { 0x3634, 0x60 }, -- { 0x3636, 0x00 }, -- { 0x3662, 0x01 }, -- { 0x3663, 0x70 }, -- { 0x3664, 0x50 }, -- { 0x3666, 0x0a }, -- { 0x3669, 0x1a }, -- { 0x366a, 0x00 }, -- { 0x366b, 0x50 }, -- { 0x3673, 0x01 }, -- { 0x3674, 0xff }, -- { 0x3675, 0x03 }, -- { 0x3705, 0xc1 }, -- { 0x3709, 0x40 }, -- { 0x373c, 0x08 }, -- { 0x3742, 0x00 }, -- { 0x3757, 0xb3 }, -- { 0x3788, 0x00 }, -- { 0x37a8, 0x01 }, -- { 0x37a9, 0xc0 }, -- { 0x3800, 0x00 }, -- { 0x3801, 0x04 }, -- { 0x3802, 0x00 }, -- { 0x3803, 0x04 }, -- { 0x3804, 0x02 }, -- { 0x3805, 0x8b }, -- { 0x3806, 0x01 }, -- { 0x3807, 0xeb }, -- { 0x3808, 0x02 }, /* width high */ -- { 0x3809, 0x80 }, /* width low */ -- { 0x380a, 0x01 }, /* height high */ -- { 0x380b, 0xe0 }, /* height low */ -- { 0x380c, 0x03 }, /* total horiz timing high */ -- { 0x380d, 0xa0 }, /* total horiz timing low */ -- { 0x380e, 0x06 }, /* total vertical timing high */ -- { 0x380f, 0xbc }, /* total vertical timing low */ -- { 0x3810, 0x00 }, -- { 0x3811, 0x04 }, -- { 0x3812, 0x00 }, -- { 0x3813, 0x05 }, -- { 0x3814, 0x11 }, -- { 0x3815, 0x11 }, -- { 0x3820, 0x40 }, -- { 0x3821, 0x00 }, -- { 0x382f, 0x0e }, -- { 0x3832, 0x00 }, -- { 0x3833, 0x05 }, -- { 0x3834, 0x00 }, -- { 0x3835, 0x0c }, -- { 0x3837, 0x00 }, -- { 0x3b80, 0x00 }, -- { 0x3b81, 0xa5 }, -- { 0x3b82, 0x10 }, -- { 0x3b83, 0x00 }, -- { 0x3b84, 0x08 }, -- { 0x3b85, 0x00 }, -- { 0x3b86, 0x01 }, -- { 0x3b87, 0x00 }, -- { 0x3b88, 0x00 }, -- { 0x3b89, 0x00 }, -- { 0x3b8a, 0x00 }, -- { 0x3b8b, 0x05 }, -- { 0x3b8c, 0x00 }, -- { 0x3b8d, 0x00 }, -- { 0x3b8e, 0x00 }, -- { 0x3b8f, 0x1a }, -- { 0x3b94, 0x05 }, -- { 0x3b95, 0xf2 }, -- { 0x3b96, 0x40 }, -- { 0x3c00, 0x89 }, -- { 0x3c01, 0x63 }, -- { 0x3c02, 0x01 }, -- { 0x3c03, 0x00 }, -- { 0x3c04, 0x00 }, -- { 0x3c05, 0x03 }, -- { 0x3c06, 0x00 }, -- { 0x3c07, 0x06 }, -- { 0x3c0c, 0x01 }, -- { 0x3c0d, 0xd0 }, -- { 0x3c0e, 0x02 }, -- { 0x3c0f, 0x0a }, -- { 0x4001, 0x42 }, -- { 0x4004, 0x04 }, -- { 0x4005, 0x00 }, -- { 0x404e, 0x01 }, -- { 0x4300, 0xff }, -- { 0x4301, 0x00 }, -- { 0x4315, 0x00 }, -- { 0x4501, 0x48 }, -- { 0x4600, 0x00 }, -- { 0x4601, 0x4e }, -- { 0x4801, 0x0f }, -- { 0x4806, 0x0f }, -- { 0x4819, 0xaa }, -- { 0x4823, 0x3e }, -- { 0x4837, 0x19 }, -- { 0x4a0d, 0x00 }, -- { 0x4a47, 0x7f }, -- { 0x4a49, 0xf0 }, -- { 0x4a4b, 0x30 }, -- { 0x5000, 0x85 }, -- { 0x5001, 0x80 }, --}; -- --static const struct reg_value ov7251_setting_vga_60fps[] = { -- { 0x3005, 0x00 }, -- { 0x3012, 0xc0 }, -- { 0x3013, 0xd2 }, -- { 0x3014, 0x04 }, -- { 0x3016, 0x10 }, -- { 0x3017, 0x00 }, -- { 0x3018, 0x00 }, -- { 0x301a, 0x00 }, -- { 0x301b, 0x00 }, -- { 0x301c, 0x00 }, -- { 0x3023, 0x05 }, -- { 0x3037, 0xf0 }, -- { 0x3106, 0xda }, -- { 0x3503, 0x07 }, -- { 0x3509, 0x10 }, -- { 0x3600, 0x1c }, -- { 0x3602, 0x62 }, -- { 0x3620, 0xb7 }, -- { 0x3622, 0x04 }, -- { 0x3626, 0x21 }, -- { 0x3627, 0x30 }, -- { 0x3630, 0x44 }, -- { 0x3631, 0x35 }, -- { 0x3634, 0x60 }, -- { 0x3636, 0x00 }, -- { 0x3662, 0x01 }, -- { 0x3663, 0x70 }, -- { 0x3664, 0x50 }, -- { 0x3666, 0x0a }, -- { 0x3669, 0x1a }, -- { 0x366a, 0x00 }, -- { 0x366b, 0x50 }, -- { 0x3673, 0x01 }, -- { 0x3674, 0xff }, -- { 0x3675, 0x03 }, -- { 0x3705, 0xc1 }, -- { 0x3709, 0x40 }, -- { 0x373c, 0x08 }, -- { 0x3742, 0x00 }, -- { 0x3757, 0xb3 }, -- { 0x3788, 0x00 }, -- { 0x37a8, 0x01 }, -- { 0x37a9, 0xc0 }, -- { 0x3800, 0x00 }, -- { 0x3801, 0x04 }, -- { 0x3802, 0x00 }, -- { 0x3803, 0x04 }, -- { 0x3804, 0x02 }, -- { 0x3805, 0x8b }, -- { 0x3806, 0x01 }, -- { 0x3807, 0xeb }, -- { 0x3808, 0x02 }, /* width high */ -- { 0x3809, 0x80 }, /* width low */ -- { 0x380a, 0x01 }, /* height high */ -- { 0x380b, 0xe0 }, /* height low */ -- { 0x380c, 0x03 }, /* total horiz timing high */ -- { 0x380d, 0xa0 }, /* total horiz timing low */ -- { 0x380e, 0x03 }, /* total vertical timing high */ -- { 0x380f, 0x5c }, /* total vertical timing low */ -- { 0x3810, 0x00 }, -- { 0x3811, 0x04 }, -- { 0x3812, 0x00 }, -- { 0x3813, 0x05 }, -- { 0x3814, 0x11 }, -- { 0x3815, 0x11 }, -- { 0x3820, 0x40 }, -- { 0x3821, 0x00 }, -- { 0x382f, 0x0e }, -- { 0x3832, 0x00 }, -- { 0x3833, 0x05 }, -- { 0x3834, 0x00 }, -- { 0x3835, 0x0c }, -- { 0x3837, 0x00 }, -- { 0x3b80, 0x00 }, -- { 0x3b81, 0xa5 }, -- { 0x3b82, 0x10 }, -- { 0x3b83, 0x00 }, -- { 0x3b84, 0x08 }, -- { 0x3b85, 0x00 }, -- { 0x3b86, 0x01 }, -- { 0x3b87, 0x00 }, -- { 0x3b88, 0x00 }, -- { 0x3b89, 0x00 }, -- { 0x3b8a, 0x00 }, -- { 0x3b8b, 0x05 }, -- { 0x3b8c, 0x00 }, -- { 0x3b8d, 0x00 }, -- { 0x3b8e, 0x00 }, -- { 0x3b8f, 0x1a }, -- { 0x3b94, 0x05 }, -- { 0x3b95, 0xf2 }, -- { 0x3b96, 0x40 }, -- { 0x3c00, 0x89 }, -- { 0x3c01, 0x63 }, -- { 0x3c02, 0x01 }, -- { 0x3c03, 0x00 }, -- { 0x3c04, 0x00 }, -- { 0x3c05, 0x03 }, -- { 0x3c06, 0x00 }, -- { 0x3c07, 0x06 }, -- { 0x3c0c, 0x01 }, -- { 0x3c0d, 0xd0 }, -- { 0x3c0e, 0x02 }, -- { 0x3c0f, 0x0a }, -- { 0x4001, 0x42 }, -- { 0x4004, 0x04 }, -- { 0x4005, 0x00 }, -- { 0x404e, 0x01 }, -- { 0x4300, 0xff }, -- { 0x4301, 0x00 }, -- { 0x4315, 0x00 }, -- { 0x4501, 0x48 }, -- { 0x4600, 0x00 }, -- { 0x4601, 0x4e }, -- { 0x4801, 0x0f }, -- { 0x4806, 0x0f }, -- { 0x4819, 0xaa }, -- { 0x4823, 0x3e }, -- { 0x4837, 0x19 }, -- { 0x4a0d, 0x00 }, -- { 0x4a47, 0x7f }, -- { 0x4a49, 0xf0 }, -- { 0x4a4b, 0x30 }, -- { 0x5000, 0x85 }, -- { 0x5001, 0x80 }, --}; -- --static const struct reg_value ov7251_setting_vga_90fps[] = { -+static const struct reg_value ov7251_setting_vga[] = { - { 0x3005, 0x00 }, - { 0x3012, 0xc0 }, - { 0x3013, 0xd2 }, -@@ -518,8 +265,6 @@ static const struct reg_value ov7251_set - { 0x380b, 0xe0 }, /* height low */ - { 0x380c, 0x03 }, /* total horiz timing high */ - { 0x380d, 0xa0 }, /* total horiz timing low */ -- { 0x380e, 0x02 }, /* total vertical timing high */ -- { 0x380f, 0x3c }, /* total vertical timing low */ - { 0x3810, 0x00 }, - { 0x3811, 0x04 }, - { 0x3812, 0x00 }, -@@ -601,10 +346,11 @@ static const struct ov7251_mode_info ov7 - { - .width = 640, - .height = 480, -- .data = ov7251_setting_vga_30fps, -- .data_size = ARRAY_SIZE(ov7251_setting_vga_30fps), -+ .data = ov7251_setting_vga, -+ .data_size = ARRAY_SIZE(ov7251_setting_vga), - .exposure_max = 1704, - .exposure_def = 504, -+ .vts = 0x6bc, - .timeperframe = { - .numerator = 100, - .denominator = 3000 -@@ -613,10 +359,11 @@ static const struct ov7251_mode_info ov7 - { - .width = 640, - .height = 480, -- .data = ov7251_setting_vga_60fps, -- .data_size = ARRAY_SIZE(ov7251_setting_vga_60fps), -+ .data = ov7251_setting_vga, -+ .data_size = ARRAY_SIZE(ov7251_setting_vga), - .exposure_max = 840, - .exposure_def = 504, -+ .vts = 0x35c, - .timeperframe = { - .numerator = 100, - .denominator = 6014 -@@ -625,10 +372,11 @@ static const struct ov7251_mode_info ov7 - { - .width = 640, - .height = 480, -- .data = ov7251_setting_vga_90fps, -- .data_size = ARRAY_SIZE(ov7251_setting_vga_90fps), -+ .data = ov7251_setting_vga, -+ .data_size = ARRAY_SIZE(ov7251_setting_vga), - .exposure_max = 552, - .exposure_def = 504, -+ .vts = 0x23c, - .timeperframe = { - .numerator = 100, - .denominator = 9043 -@@ -1289,6 +1037,14 @@ static int ov7251_s_stream(struct v4l2_s - ov7251->current_mode->height); - goto err_power_down; - } -+ ret = ov7251_write_reg(ov7251, OV7251_VTS_HIGH, -+ ov7251->current_mode->vts >> 8); -+ if (ret) -+ goto err_power_down; -+ ret = ov7251_write_reg(ov7251, OV7251_VTS_LOW, -+ ov7251->current_mode->vts & 0xff); -+ if (ret) -+ goto err_power_down; - ret = __v4l2_ctrl_handler_setup(&ov7251->ctrls); - if (ret < 0) { - dev_err(ov7251->dev, "could not sync v4l2 controls\n"); diff --git a/target/linux/bcm27xx/patches-5.15/950-0735-media-i2c-ov7251-Limit-exposure-based-on-VTS.patch b/target/linux/bcm27xx/patches-5.15/950-0735-media-i2c-ov7251-Limit-exposure-based-on-VTS.patch deleted file mode 100644 index 77686190e..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0735-media-i2c-ov7251-Limit-exposure-based-on-VTS.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 1c779e83e5f78cadcd8dfc6cfca33e7aeb323f27 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 17 Feb 2022 16:44:33 +0000 -Subject: [PATCH] media: i2c: ov7251: Limit exposure based on VTS - -The maximum exposure is dictated by VTS, so compute it rather -than having the value in the mode table. - -Signed-off-by: Dave Stevenson ---- - drivers/media/i2c/ov7251.c | 14 ++++++-------- - 1 file changed, 6 insertions(+), 8 deletions(-) - ---- a/drivers/media/i2c/ov7251.c -+++ b/drivers/media/i2c/ov7251.c -@@ -37,6 +37,8 @@ - #define OV7251_AEC_EXPO_2 0x3502 - #define OV7251_AEC_AGC_ADJ_0 0x350a - #define OV7251_AEC_AGC_ADJ_1 0x350b -+/* Exposure must be at least 20 lines shorter than VTS */ -+#define OV7251_EXPOSURE_OFFSET 20 - /* HTS is registers 0x380c and 0x380d */ - #define OV7251_HTS 0x3a0 - #define OV7251_VTS_HIGH 0x380e -@@ -82,7 +84,6 @@ struct ov7251_mode_info { - u32 height; - const struct reg_value *data; - u32 data_size; -- u16 exposure_max; - u16 exposure_def; - u16 vts; - struct v4l2_fract timeperframe; -@@ -348,7 +349,6 @@ static const struct ov7251_mode_info ov7 - .height = 480, - .data = ov7251_setting_vga, - .data_size = ARRAY_SIZE(ov7251_setting_vga), -- .exposure_max = 1704, - .exposure_def = 504, - .vts = 0x6bc, - .timeperframe = { -@@ -361,7 +361,6 @@ static const struct ov7251_mode_info ov7 - .height = 480, - .data = ov7251_setting_vga, - .data_size = ARRAY_SIZE(ov7251_setting_vga), -- .exposure_max = 840, - .exposure_def = 504, - .vts = 0x35c, - .timeperframe = { -@@ -374,7 +373,6 @@ static const struct ov7251_mode_info ov7 - .height = 480, - .data = ov7251_setting_vga, - .data_size = ARRAY_SIZE(ov7251_setting_vga), -- .exposure_max = 552, - .exposure_def = 504, - .vts = 0x23c, - .timeperframe = { -@@ -915,8 +913,8 @@ static int ov7251_set_format(struct v4l2 - h_blank, 1, h_blank); - __v4l2_ctrl_s_ctrl(ov7251->hblank, h_blank); - -- ret = __v4l2_ctrl_modify_range(ov7251->exposure, -- 1, new_mode->exposure_max, -+ ret = __v4l2_ctrl_modify_range(ov7251->exposure, 1, -+ new_mode->vts - OV7251_EXPOSURE_OFFSET, - 1, new_mode->exposure_def); - if (ret < 0) - goto exit; -@@ -1092,8 +1090,8 @@ static int ov7251_set_frame_interval(str - new_mode = ov7251_find_mode_by_ival(ov7251, &fi->interval); - - if (new_mode != ov7251->current_mode) { -- ret = __v4l2_ctrl_modify_range(ov7251->exposure, -- 1, new_mode->exposure_max, -+ ret = __v4l2_ctrl_modify_range(ov7251->exposure, 1, -+ new_mode->vts - OV7251_EXPOSURE_OFFSET, - 1, new_mode->exposure_def); - if (ret < 0) - goto exit; diff --git a/target/linux/bcm27xx/patches-5.15/950-0736-media-i2c-ov7251-Separate-modes-from-frame-intervals.patch b/target/linux/bcm27xx/patches-5.15/950-0736-media-i2c-ov7251-Separate-modes-from-frame-intervals.patch deleted file mode 100644 index 6ad35fda0..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0736-media-i2c-ov7251-Separate-modes-from-frame-intervals.patch +++ /dev/null @@ -1,234 +0,0 @@ -From 65e773354de288401a6c498d006b47b7f87e0936 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 17 Feb 2022 17:00:27 +0000 -Subject: [PATCH] media: i2c: ov7251: Separate modes from frame - intervals - -The modes and frame intervals are independent, therefore -separate them into 2 structures. - -Signed-off-by: Dave Stevenson ---- - drivers/media/i2c/ov7251.c | 85 ++++++++++++++++++-------------------- - 1 file changed, 41 insertions(+), 44 deletions(-) - ---- a/drivers/media/i2c/ov7251.c -+++ b/drivers/media/i2c/ov7251.c -@@ -79,14 +79,17 @@ struct reg_value { - u8 val; - }; - -+struct ov7251_frame_ival_info { -+ u16 vts; -+ struct v4l2_fract timeperframe; -+}; -+ - struct ov7251_mode_info { - u32 width; - u32 height; - const struct reg_value *data; - u32 data_size; - u16 exposure_def; -- u16 vts; -- struct v4l2_fract timeperframe; - }; - - struct ov7251_pll1_config { -@@ -128,6 +131,7 @@ struct ov7251 { - struct regulator *analog_regulator; - - const struct ov7251_mode_info *current_mode; -+ const struct ov7251_frame_ival_info *current_ival; - - struct v4l2_ctrl_handler ctrls; - struct v4l2_ctrl *exposure; -@@ -343,13 +347,8 @@ static const s64 link_freq[] = { - 240000000, - }; - --static const struct ov7251_mode_info ov7251_mode_info_data[] = { -+static const struct ov7251_frame_ival_info ov7251_frame_ival_info_data[] = { - { -- .width = 640, -- .height = 480, -- .data = ov7251_setting_vga, -- .data_size = ARRAY_SIZE(ov7251_setting_vga), -- .exposure_def = 504, - .vts = 0x6bc, - .timeperframe = { - .numerator = 100, -@@ -357,11 +356,6 @@ static const struct ov7251_mode_info ov7 - } - }, - { -- .width = 640, -- .height = 480, -- .data = ov7251_setting_vga, -- .data_size = ARRAY_SIZE(ov7251_setting_vga), -- .exposure_def = 504, - .vts = 0x35c, - .timeperframe = { - .numerator = 100, -@@ -369,11 +363,6 @@ static const struct ov7251_mode_info ov7 - } - }, - { -- .width = 640, -- .height = 480, -- .data = ov7251_setting_vga, -- .data_size = ARRAY_SIZE(ov7251_setting_vga), -- .exposure_def = 504, - .vts = 0x23c, - .timeperframe = { - .numerator = 100, -@@ -382,6 +371,16 @@ static const struct ov7251_mode_info ov7 - }, - }; - -+static const struct ov7251_mode_info ov7251_mode_info_data[] = { -+ { -+ .width = 640, -+ .height = 480, -+ .data = ov7251_setting_vga, -+ .data_size = ARRAY_SIZE(ov7251_setting_vga), -+ .exposure_def = 504, -+ }, -+}; -+ - static int ov7251_regulators_enable(struct ov7251 *ov7251) - { - int ret; -@@ -789,13 +788,13 @@ static int ov7251_enum_frame_ival(struct - unsigned int index = fie->index; - unsigned int i; - -- for (i = 0; i < ARRAY_SIZE(ov7251_mode_info_data); i++) { -- if (fie->width != ov7251_mode_info_data[i].width || -- fie->height != ov7251_mode_info_data[i].height) -+ for (i = 0; i < ARRAY_SIZE(ov7251_frame_ival_info_data); i++) { -+ if (fie->width != ov7251_mode_info_data[0].width || -+ fie->height != ov7251_mode_info_data[0].height) - continue; - - if (index-- == 0) { -- fie->interval = ov7251_mode_info_data[i].timeperframe; -+ fie->interval = ov7251_frame_ival_info_data[i].timeperframe; - return 0; - } - } -@@ -854,23 +853,18 @@ static inline u32 avg_fps(const struct v - return (t->denominator + (t->numerator >> 1)) / t->numerator; - } - --static const struct ov7251_mode_info * --ov7251_find_mode_by_ival(struct ov7251 *ov7251, struct v4l2_fract *timeperframe) -+static const struct ov7251_frame_ival_info * -+ov7251_find_frame_ival_by_ival(struct ov7251 *ov7251, struct v4l2_fract *timeperframe) - { -- const struct ov7251_mode_info *mode = ov7251->current_mode; - unsigned int fps_req = avg_fps(timeperframe); - unsigned int max_dist_match = (unsigned int) -1; - unsigned int i, n = 0; - -- for (i = 0; i < ARRAY_SIZE(ov7251_mode_info_data); i++) { -+ for (i = 0; i < ARRAY_SIZE(ov7251_frame_ival_info_data); i++) { - unsigned int dist; - unsigned int fps_tmp; - -- if (mode->width != ov7251_mode_info_data[i].width || -- mode->height != ov7251_mode_info_data[i].height) -- continue; -- -- fps_tmp = avg_fps(&ov7251_mode_info_data[i].timeperframe); -+ fps_tmp = avg_fps(&ov7251_frame_ival_info_data[i].timeperframe); - - dist = abs(fps_req - fps_tmp); - -@@ -880,7 +874,7 @@ ov7251_find_mode_by_ival(struct ov7251 * - } - } - -- return &ov7251_mode_info_data[n]; -+ return &ov7251_frame_ival_info_data[n]; - } - - static int ov7251_set_format(struct v4l2_subdev *sd, -@@ -914,7 +908,8 @@ static int ov7251_set_format(struct v4l2 - __v4l2_ctrl_s_ctrl(ov7251->hblank, h_blank); - - ret = __v4l2_ctrl_modify_range(ov7251->exposure, 1, -- new_mode->vts - OV7251_EXPOSURE_OFFSET, -+ ov7251->current_ival->vts - -+ OV7251_EXPOSURE_OFFSET, - 1, new_mode->exposure_def); - if (ret < 0) - goto exit; -@@ -1036,11 +1031,11 @@ static int ov7251_s_stream(struct v4l2_s - goto err_power_down; - } - ret = ov7251_write_reg(ov7251, OV7251_VTS_HIGH, -- ov7251->current_mode->vts >> 8); -+ ov7251->current_ival->vts >> 8); - if (ret) - goto err_power_down; - ret = ov7251_write_reg(ov7251, OV7251_VTS_LOW, -- ov7251->current_mode->vts & 0xff); -+ ov7251->current_ival->vts & 0xff); - if (ret) - goto err_power_down; - ret = __v4l2_ctrl_handler_setup(&ov7251->ctrls); -@@ -1073,7 +1068,7 @@ static int ov7251_get_frame_interval(str - struct ov7251 *ov7251 = to_ov7251(subdev); - - mutex_lock(&ov7251->lock); -- fi->interval = ov7251->current_mode->timeperframe; -+ fi->interval = ov7251->current_ival->timeperframe; - mutex_unlock(&ov7251->lock); - - return 0; -@@ -1083,28 +1078,29 @@ static int ov7251_set_frame_interval(str - struct v4l2_subdev_frame_interval *fi) - { - struct ov7251 *ov7251 = to_ov7251(subdev); -- const struct ov7251_mode_info *new_mode; -+ const struct ov7251_frame_ival_info *new_ival; - int ret = 0; - - mutex_lock(&ov7251->lock); -- new_mode = ov7251_find_mode_by_ival(ov7251, &fi->interval); -+ new_ival = ov7251_find_frame_ival_by_ival(ov7251, &fi->interval); - -- if (new_mode != ov7251->current_mode) { -+ if (new_ival != ov7251->current_ival) { - ret = __v4l2_ctrl_modify_range(ov7251->exposure, 1, -- new_mode->vts - OV7251_EXPOSURE_OFFSET, -- 1, new_mode->exposure_def); -+ new_ival->vts - -+ OV7251_EXPOSURE_OFFSET, -+ 1, ov7251->current_mode->exposure_def); - if (ret < 0) - goto exit; - - ret = __v4l2_ctrl_s_ctrl(ov7251->exposure, -- new_mode->exposure_def); -+ ov7251->current_mode->exposure_def); - if (ret < 0) - goto exit; - -- ov7251->current_mode = new_mode; -+ ov7251->current_ival = new_ival; - } - -- fi->interval = ov7251->current_mode->timeperframe; -+ fi->interval = ov7251->current_ival->timeperframe; - - exit: - mutex_unlock(&ov7251->lock); -@@ -1316,6 +1312,7 @@ static int ov7251_probe(struct i2c_clien - mutex_init(&ov7251->lock); - - ov7251->current_mode = &ov7251_mode_info_data[0]; -+ ov7251->current_ival = &ov7251_frame_ival_info_data[0]; - - v4l2_ctrl_handler_init(&ov7251->ctrls, 10); - ov7251->ctrls.lock = &ov7251->lock; diff --git a/target/linux/bcm27xx/patches-5.15/950-0737-media-i2c-ov7251-Add-V4L2_CID_VBLANK.patch b/target/linux/bcm27xx/patches-5.15/950-0737-media-i2c-ov7251-Add-V4L2_CID_VBLANK.patch deleted file mode 100644 index c4c3c221d..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0737-media-i2c-ov7251-Add-V4L2_CID_VBLANK.patch +++ /dev/null @@ -1,153 +0,0 @@ -From 9e6a5b925f3b401c9a047237c0014367655b291a Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 17 Feb 2022 18:08:39 +0000 -Subject: [PATCH] media: i2c: ov7251: Add V4L2_CID_VBLANK - -This is a raw sensor so should be implementing V4L2_CID_VBLANK -instead of the frame_interval ops, as per docs at -https://www.kernel.org/doc/html/latest/driver-api/media/camera-sensor.html#frame-interval-configuration - -This driver already implemented the frame_interval ops, so -removing them would be a regression. -Implement V4L2_CID_VBLANK, with the frame_interval ops setting -that control. - -Signed-off-by: Dave Stevenson ---- - drivers/media/i2c/ov7251.c | 56 +++++++++++++++++++++++++++++--------- - 1 file changed, 43 insertions(+), 13 deletions(-) - ---- a/drivers/media/i2c/ov7251.c -+++ b/drivers/media/i2c/ov7251.c -@@ -43,6 +43,8 @@ - #define OV7251_HTS 0x3a0 - #define OV7251_VTS_HIGH 0x380e - #define OV7251_VTS_LOW 0x380f -+#define OV7251_VTS_MIN_OFFSET 92 -+#define OV7251_VTS_MAX 0x7fff - #define OV7251_TIMING_FORMAT1 0x3820 - #define OV7251_TIMING_FORMAT1_VFLIP BIT(2) - #define OV7251_TIMING_FORMAT2 0x3821 -@@ -136,6 +138,7 @@ struct ov7251 { - struct v4l2_ctrl_handler ctrls; - struct v4l2_ctrl *exposure; - struct v4l2_ctrl *hblank; -+ struct v4l2_ctrl *vblank; - - /* Cached register values */ - u8 aec_pk_manual; -@@ -688,6 +691,19 @@ static int ov7251_set_vflip(struct ov725 - return ret; - } - -+static int ov7251_set_vblank(struct ov7251 *ov7251, s32 value) -+{ -+ u16 reg; -+ u8 val[2]; -+ -+ reg = OV7251_VTS_HIGH; -+ value += ov7251->current_mode->height; -+ val[0] = (value & 0xff00) >> 8; /* goes to OV7251_VTS_HIGH */ -+ val[1] = value & 0xff; /* goes to OV7251_VTS_LOW */ -+ -+ return ov7251_write_seq_regs(ov7251, reg, val, 2); -+} -+ - static int ov7251_set_test_pattern(struct ov7251 *ov7251, s32 value) - { - u8 val = ov7251->pre_isp_00; -@@ -714,9 +730,20 @@ static int ov7251_s_ctrl(struct v4l2_ctr - { - struct ov7251 *ov7251 = container_of(ctrl->handler, - struct ov7251, ctrls); -+ s64 max; - int ret; - - /* v4l2_ctrl_lock() locks our mutex */ -+ switch (ctrl->id) { -+ case V4L2_CID_VBLANK: -+ /* Update max exposure while meeting expected vblanking */ -+ max = ov7251->current_mode->height + ctrl->val - OV7251_EXPOSURE_OFFSET; -+ __v4l2_ctrl_modify_range(ov7251->exposure, -+ ov7251->exposure->minimum, max, -+ ov7251->exposure->step, -+ ov7251->exposure->default_value); -+ break; -+ } - - if (!pm_runtime_get_if_in_use(ov7251->dev)) - return 0; -@@ -737,6 +764,9 @@ static int ov7251_s_ctrl(struct v4l2_ctr - case V4L2_CID_VFLIP: - ret = ov7251_set_vflip(ov7251, ctrl->val); - break; -+ case V4L2_CID_VBLANK: -+ ret = ov7251_set_vblank(ov7251, ctrl->val); -+ break; - default: - ret = -EINVAL; - break; -@@ -1030,14 +1060,6 @@ static int ov7251_s_stream(struct v4l2_s - ov7251->current_mode->height); - goto err_power_down; - } -- ret = ov7251_write_reg(ov7251, OV7251_VTS_HIGH, -- ov7251->current_ival->vts >> 8); -- if (ret) -- goto err_power_down; -- ret = ov7251_write_reg(ov7251, OV7251_VTS_LOW, -- ov7251->current_ival->vts & 0xff); -- if (ret) -- goto err_power_down; - ret = __v4l2_ctrl_handler_setup(&ov7251->ctrls); - if (ret < 0) { - dev_err(ov7251->dev, "could not sync v4l2 controls\n"); -@@ -1088,12 +1110,13 @@ static int ov7251_set_frame_interval(str - ret = __v4l2_ctrl_modify_range(ov7251->exposure, 1, - new_ival->vts - - OV7251_EXPOSURE_OFFSET, -- 1, ov7251->current_mode->exposure_def); -+ 1, ov7251->exposure->val); - if (ret < 0) - goto exit; - -- ret = __v4l2_ctrl_s_ctrl(ov7251->exposure, -- ov7251->current_mode->exposure_def); -+ ret = __v4l2_ctrl_s_ctrl(ov7251->vblank, -+ new_ival->vts - -+ ov7251->current_mode->height); - if (ret < 0) - goto exit; - -@@ -1233,7 +1256,7 @@ static int ov7251_probe(struct i2c_clien - struct v4l2_ctrl *ctrl; - struct ov7251 *ov7251; - unsigned int rate = 0; -- u32 h_blank; -+ u32 h_blank, v_blank, v_blank_max; - int ret; - int i; - -@@ -1314,7 +1337,7 @@ static int ov7251_probe(struct i2c_clien - ov7251->current_mode = &ov7251_mode_info_data[0]; - ov7251->current_ival = &ov7251_frame_ival_info_data[0]; - -- v4l2_ctrl_handler_init(&ov7251->ctrls, 10); -+ v4l2_ctrl_handler_init(&ov7251->ctrls, 11); - ov7251->ctrls.lock = &ov7251->lock; - - v4l2_ctrl_new_std(&ov7251->ctrls, &ov7251_ctrl_ops, -@@ -1345,6 +1368,13 @@ static int ov7251_probe(struct i2c_clien - if (ov7251->hblank) - ov7251->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; - -+ v_blank = ov7251->current_ival->vts - ov7251->current_mode->height; -+ v_blank_max = OV7251_VTS_MAX - ov7251->current_mode->width; -+ ov7251->vblank = v4l2_ctrl_new_std(&ov7251->ctrls, &ov7251_ctrl_ops, -+ V4L2_CID_VBLANK, -+ OV7251_VTS_MIN_OFFSET, -+ v_blank_max, 1, v_blank); -+ - ov7251->sd.ctrl_handler = &ov7251->ctrls; - - if (ov7251->ctrls.error) { diff --git a/target/linux/bcm27xx/patches-5.15/950-0738-media-i2c-ov7251-Switch-from-V4L2_CID_GAIN-to-V4L2_C.patch b/target/linux/bcm27xx/patches-5.15/950-0738-media-i2c-ov7251-Switch-from-V4L2_CID_GAIN-to-V4L2_C.patch deleted file mode 100644 index 651fe8663..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0738-media-i2c-ov7251-Switch-from-V4L2_CID_GAIN-to-V4L2_C.patch +++ /dev/null @@ -1,36 +0,0 @@ -From ed38a89fe4fc0b668bfe68559fa4adf55fb4de63 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 17 Feb 2022 18:31:56 +0000 -Subject: [PATCH] media: i2c: ov7251: Switch from V4L2_CID_GAIN to - V4L2_CID_ANALOGUE_GAIN - -The control is specifically for analogue gain, therefore switch -to using the control for that. - -Signed-off-by: Dave Stevenson ---- - drivers/media/i2c/ov7251.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/drivers/media/i2c/ov7251.c -+++ b/drivers/media/i2c/ov7251.c -@@ -752,7 +752,7 @@ static int ov7251_s_ctrl(struct v4l2_ctr - case V4L2_CID_EXPOSURE: - ret = ov7251_set_exposure(ov7251, ctrl->val); - break; -- case V4L2_CID_GAIN: -+ case V4L2_CID_ANALOGUE_GAIN: - ret = ov7251_set_gain(ov7251, ctrl->val); - break; - case V4L2_CID_TEST_PATTERN: -@@ -1346,8 +1346,8 @@ static int ov7251_probe(struct i2c_clien - V4L2_CID_VFLIP, 0, 1, 1, 0); - ov7251->exposure = v4l2_ctrl_new_std(&ov7251->ctrls, &ov7251_ctrl_ops, - V4L2_CID_EXPOSURE, 1, 32, 1, 32); -- v4l2_ctrl_new_std(&ov7251->ctrls, &ov7251_ctrl_ops, V4L2_CID_GAIN, -- 16, 1023, 1, 16); -+ v4l2_ctrl_new_std(&ov7251->ctrls, &ov7251_ctrl_ops, -+ V4L2_CID_ANALOGUE_GAIN, 16, 1023, 1, 16); - v4l2_ctrl_new_std_menu_items(&ov7251->ctrls, &ov7251_ctrl_ops, - V4L2_CID_TEST_PATTERN, - ARRAY_SIZE(ov7251_test_pattern_menu) - 1, diff --git a/target/linux/bcm27xx/patches-5.15/950-0739-dtoverlays-Switch-ov7251-to-using-Media-Controller-b.patch b/target/linux/bcm27xx/patches-5.15/950-0739-dtoverlays-Switch-ov7251-to-using-Media-Controller-b.patch deleted file mode 100644 index a6eab8ea2..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0739-dtoverlays-Switch-ov7251-to-using-Media-Controller-b.patch +++ /dev/null @@ -1,24 +0,0 @@ -From b5f9685aca67cf0dded7914fa89c390891ce8210 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 17 Feb 2022 18:12:36 +0000 -Subject: [PATCH] dtoverlays: Switch ov7251 to using Media Controller - by default - -We should have all the functionality required by now, so switch -to using Media Controller so that it can be used with libcamera. - -Signed-off-by: Dave Stevenson ---- - arch/arm/boot/dts/overlays/ov7251-overlay.dts | 1 + - 1 file changed, 1 insertion(+) - ---- a/arch/arm/boot/dts/overlays/ov7251-overlay.dts -+++ b/arch/arm/boot/dts/overlays/ov7251-overlay.dts -@@ -49,6 +49,7 @@ - target = <&csi1>; - csi: __overlay__ { - status = "okay"; -+ brcm,media-controller; - - port { - csi1_ep: endpoint { diff --git a/target/linux/bcm27xx/patches-5.15/950-0741-drm-vc4-hvs-Use-pointer-to-HVS-in-HVS_READ-and-HVS_W.patch b/target/linux/bcm27xx/patches-5.15/950-0741-drm-vc4-hvs-Use-pointer-to-HVS-in-HVS_READ-and-HVS_W.patch deleted file mode 100644 index aa82f3c7e..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0741-drm-vc4-hvs-Use-pointer-to-HVS-in-HVS_READ-and-HVS_W.patch +++ /dev/null @@ -1,496 +0,0 @@ -From 2a2c0889e2695a39ea0479b5ebe30bd8ff8e3f21 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Mon, 14 Feb 2022 17:21:05 +0100 -Subject: [PATCH] drm/vc4: hvs: Use pointer to HVS in HVS_READ and - HVS_WRITE macros - -Those macros are really about the HVS itself, and thus its associated -structure vc4_hvs, rather than the entire (virtual) vc4 device. - -Let's change those macros to use the hvs pointer directly, and change -the calling sites accordingly. - -Signed-off-by: Maxime Ripard ---- - drivers/gpu/drm/vc4/vc4_crtc.c | 14 +++-- - drivers/gpu/drm/vc4/vc4_drv.h | 16 ++--- - drivers/gpu/drm/vc4/vc4_hvs.c | 109 +++++++++++++++++---------------- - drivers/gpu/drm/vc4/vc4_kms.c | 5 +- - 4 files changed, 77 insertions(+), 67 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_crtc.c -+++ b/drivers/gpu/drm/vc4/vc4_crtc.c -@@ -70,6 +70,7 @@ static const struct debugfs_reg32 crtc_r - static unsigned int - vc4_crtc_get_cob_allocation(struct vc4_dev *vc4, unsigned int channel) - { -+ struct vc4_hvs *hvs = vc4->hvs; - u32 dispbase = HVS_READ(SCALER_DISPBASEX(channel)); - /* Top/base are supposed to be 4-pixel aligned, but the - * Raspberry Pi firmware fills the low bits (which are -@@ -89,6 +90,7 @@ static bool vc4_crtc_get_scanout_positio - { - struct drm_device *dev = crtc->dev; - struct vc4_dev *vc4 = to_vc4_dev(dev); -+ struct vc4_hvs *hvs = vc4->hvs; - struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); - struct vc4_crtc_state *vc4_crtc_state = to_vc4_crtc_state(crtc->state); - unsigned int cob_size; -@@ -123,7 +125,7 @@ static bool vc4_crtc_get_scanout_positio - *vpos /= 2; - - /* Use hpos to correct for field offset in interlaced mode. */ -- if (vc4_hvs_get_fifo_frame_count(dev, vc4_crtc_state->assigned_channel) % 2) -+ if (vc4_hvs_get_fifo_frame_count(hvs, vc4_crtc_state->assigned_channel) % 2) - *hpos += mode->crtc_htotal / 2; - } - -@@ -433,6 +435,7 @@ static void vc4_crtc_config_pv(struct dr - static void require_hvs_enabled(struct drm_device *dev) - { - struct vc4_dev *vc4 = to_vc4_dev(dev); -+ struct vc4_hvs *hvs = vc4->hvs; - - WARN_ON_ONCE((HVS_READ(SCALER_DISPCTRL) & SCALER_DISPCTRL_ENABLE) != - SCALER_DISPCTRL_ENABLE); -@@ -446,6 +449,7 @@ static int vc4_crtc_disable(struct drm_c - struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder); - struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); - struct drm_device *dev = crtc->dev; -+ struct vc4_dev *vc4 = to_vc4_dev(dev); - int ret; - - CRTC_WRITE(PV_V_CONTROL, -@@ -475,7 +479,7 @@ static int vc4_crtc_disable(struct drm_c - vc4_encoder->post_crtc_disable(encoder, state); - - vc4_crtc_pixelvalve_reset(crtc); -- vc4_hvs_stop_channel(dev, channel); -+ vc4_hvs_stop_channel(vc4->hvs, channel); - - if (vc4_encoder && vc4_encoder->post_crtc_powerdown) - vc4_encoder->post_crtc_powerdown(encoder, state); -@@ -501,6 +505,7 @@ static struct drm_encoder *vc4_crtc_get_ - int vc4_crtc_disable_at_boot(struct drm_crtc *crtc) - { - struct drm_device *drm = crtc->dev; -+ struct vc4_dev *vc4 = to_vc4_dev(drm); - struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); - enum vc4_encoder_type encoder_type; - const struct vc4_pv_data *pv_data; -@@ -522,7 +527,7 @@ int vc4_crtc_disable_at_boot(struct drm_ - if (!(CRTC_READ(PV_V_CONTROL) & PV_VCONTROL_VIDEN)) - return 0; - -- channel = vc4_hvs_get_fifo_from_output(drm, vc4_crtc->data->hvs_output); -+ channel = vc4_hvs_get_fifo_from_output(vc4->hvs, vc4_crtc->data->hvs_output); - if (channel < 0) - return 0; - -@@ -738,6 +743,7 @@ static void vc4_crtc_handle_page_flip(st - struct drm_crtc *crtc = &vc4_crtc->base; - struct drm_device *dev = crtc->dev; - struct vc4_dev *vc4 = to_vc4_dev(dev); -+ struct vc4_hvs *hvs = vc4->hvs; - u32 chan = vc4_crtc->current_hvs_channel; - unsigned long flags; - -@@ -756,7 +762,7 @@ static void vc4_crtc_handle_page_flip(st - * the CRTC and encoder already reconfigured, leading to - * underruns. This can be seen when reconfiguring the CRTC. - */ -- vc4_hvs_unmask_underrun(dev, chan); -+ vc4_hvs_unmask_underrun(hvs, chan); - } - spin_unlock(&vc4_crtc->irq_lock); - spin_unlock_irqrestore(&dev->event_lock, flags); ---- a/drivers/gpu/drm/vc4/vc4_drv.h -+++ b/drivers/gpu/drm/vc4/vc4_drv.h -@@ -603,8 +603,8 @@ to_vc4_crtc_state(struct drm_crtc_state - - #define V3D_READ(offset) readl(vc4->v3d->regs + offset) - #define V3D_WRITE(offset, val) writel(val, vc4->v3d->regs + offset) --#define HVS_READ(offset) readl(vc4->hvs->regs + offset) --#define HVS_WRITE(offset, val) writel(val, vc4->hvs->regs + offset) -+#define HVS_READ(offset) readl(hvs->regs + offset) -+#define HVS_WRITE(offset, val) writel(val, hvs->regs + offset) - - #define VC4_REG32(reg) { .name = #reg, .offset = reg } - -@@ -965,17 +965,17 @@ void vc4_irq_reset(struct drm_device *de - - /* vc4_hvs.c */ - extern struct platform_driver vc4_hvs_driver; --void vc4_hvs_stop_channel(struct drm_device *dev, unsigned int output); --int vc4_hvs_get_fifo_from_output(struct drm_device *dev, unsigned int output); --u8 vc4_hvs_get_fifo_frame_count(struct drm_device *dev, unsigned int fifo); -+void vc4_hvs_stop_channel(struct vc4_hvs *hvs, unsigned int output); -+int vc4_hvs_get_fifo_from_output(struct vc4_hvs *hvs, unsigned int output); -+u8 vc4_hvs_get_fifo_frame_count(struct vc4_hvs *hvs, unsigned int fifo); - int vc4_hvs_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state); - void vc4_hvs_atomic_begin(struct drm_crtc *crtc, struct drm_atomic_state *state); - void vc4_hvs_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *state); - void vc4_hvs_atomic_disable(struct drm_crtc *crtc, struct drm_atomic_state *state); - void vc4_hvs_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_state *state); --void vc4_hvs_dump_state(struct drm_device *dev); --void vc4_hvs_unmask_underrun(struct drm_device *dev, int channel); --void vc4_hvs_mask_underrun(struct drm_device *dev, int channel); -+void vc4_hvs_dump_state(struct vc4_hvs *hvs); -+void vc4_hvs_unmask_underrun(struct vc4_hvs *hvs, int channel); -+void vc4_hvs_mask_underrun(struct vc4_hvs *hvs, int channel); - - /* vc4_kms.c */ - int vc4_kms_load(struct drm_device *dev); ---- a/drivers/gpu/drm/vc4/vc4_hvs.c -+++ b/drivers/gpu/drm/vc4/vc4_hvs.c -@@ -64,22 +64,21 @@ static const struct debugfs_reg32 hvs_re - VC4_REG32(SCALER_OLEDCOEF2), - }; - --void vc4_hvs_dump_state(struct drm_device *dev) -+void vc4_hvs_dump_state(struct vc4_hvs *hvs) - { -- struct vc4_dev *vc4 = to_vc4_dev(dev); -- struct drm_printer p = drm_info_printer(&vc4->hvs->pdev->dev); -+ struct drm_printer p = drm_info_printer(&hvs->pdev->dev); - int i; - -- drm_print_regset32(&p, &vc4->hvs->regset); -+ drm_print_regset32(&p, &hvs->regset); - - DRM_INFO("HVS ctx:\n"); - for (i = 0; i < 64; i += 4) { - DRM_INFO("0x%08x (%s): 0x%08x 0x%08x 0x%08x 0x%08x\n", - i * 4, i < HVS_BOOTLOADER_DLIST_END ? "B" : "D", -- readl((u32 __iomem *)vc4->hvs->dlist + i + 0), -- readl((u32 __iomem *)vc4->hvs->dlist + i + 1), -- readl((u32 __iomem *)vc4->hvs->dlist + i + 2), -- readl((u32 __iomem *)vc4->hvs->dlist + i + 3)); -+ readl((u32 __iomem *)hvs->dlist + i + 0), -+ readl((u32 __iomem *)hvs->dlist + i + 1), -+ readl((u32 __iomem *)hvs->dlist + i + 2), -+ readl((u32 __iomem *)hvs->dlist + i + 3)); - } - } - -@@ -100,6 +99,7 @@ static int vc4_hvs_debugfs_dlist(struct - struct drm_info_node *node = m->private; - struct drm_device *dev = node->minor->dev; - struct vc4_dev *vc4 = to_vc4_dev(dev); -+ struct vc4_hvs *hvs = vc4->hvs; - struct drm_printer p = drm_seq_file_printer(m); - unsigned int next_entry_start = 0; - unsigned int i, j; -@@ -139,6 +139,7 @@ static int vc5_hvs_debugfs_gamma(struct - struct drm_info_node *node = m->private; - struct drm_device *dev = node->minor->dev; - struct vc4_dev *vc4 = to_vc4_dev(dev); -+ struct vc4_hvs *hvs = vc4->hvs; - struct drm_printer p = drm_seq_file_printer(m); - unsigned int i, chan; - u32 dispstat, dispbkgndx; -@@ -274,11 +275,10 @@ static int vc4_hvs_upload_linear_kernel( - return 0; - } - --static void vc4_hvs_lut_load(struct drm_crtc *crtc) -+static void vc4_hvs_lut_load(struct vc4_hvs *hvs, -+ struct vc4_crtc *vc4_crtc) - { -- struct drm_device *dev = crtc->dev; -- struct vc4_dev *vc4 = to_vc4_dev(dev); -- struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); -+ struct drm_crtc *crtc = &vc4_crtc->base; - struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state); - u32 i; - -@@ -298,11 +298,12 @@ static void vc4_hvs_lut_load(struct drm_ - HVS_WRITE(SCALER_GAMDATA, vc4_crtc->lut_b[i]); - } - --static void vc4_hvs_update_gamma_lut(struct drm_crtc *crtc) -+static void vc4_hvs_update_gamma_lut(struct vc4_hvs *hvs, -+ struct vc4_crtc *vc4_crtc) - { -- struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); -- struct drm_color_lut *lut = crtc->state->gamma_lut->data; -- u32 length = drm_color_lut_size(crtc->state->gamma_lut); -+ struct drm_crtc_state *crtc_state = vc4_crtc->base.state; -+ struct drm_color_lut *lut = crtc_state->gamma_lut->data; -+ u32 length = drm_color_lut_size(crtc_state->gamma_lut); - u32 i; - - for (i = 0; i < length; i++) { -@@ -311,12 +312,11 @@ static void vc4_hvs_update_gamma_lut(str - vc4_crtc->lut_b[i] = drm_color_lut_extract(lut[i].blue, 8); - } - -- vc4_hvs_lut_load(crtc); -+ vc4_hvs_lut_load(hvs, vc4_crtc); - } - --u8 vc4_hvs_get_fifo_frame_count(struct drm_device *dev, unsigned int fifo) -+u8 vc4_hvs_get_fifo_frame_count(struct vc4_hvs *hvs, unsigned int fifo) - { -- struct vc4_dev *vc4 = to_vc4_dev(dev); - u8 field = 0; - - switch (fifo) { -@@ -337,7 +337,7 @@ u8 vc4_hvs_get_fifo_frame_count(struct d - return field; - } - --static void vc5_hvs_write_gamma_entry(struct vc4_dev *vc4, -+static void vc5_hvs_write_gamma_entry(struct vc4_hvs *hvs, - u32 offset, - struct vc5_gamma_entry *gamma) - { -@@ -345,33 +345,33 @@ static void vc5_hvs_write_gamma_entry(st - HVS_WRITE(offset + 4, gamma->grad_term); - } - --static void vc5_hvs_lut_load(struct drm_crtc *crtc) -+static void vc5_hvs_lut_load(struct vc4_hvs *hvs, -+ struct vc4_crtc *vc4_crtc) - { -- struct drm_device *dev = crtc->dev; -- struct vc4_dev *vc4 = to_vc4_dev(dev); -- struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); -- struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state); -+ struct drm_crtc_state *crtc_state = vc4_crtc->base.state; -+ struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc_state); - u32 i; - u32 offset = SCALER5_DSPGAMMA_START + - vc4_state->assigned_channel * SCALER5_DSPGAMMA_CHAN_OFFSET; - - for (i = 0; i < SCALER5_DSPGAMMA_NUM_POINTS; i++, offset += 8) -- vc5_hvs_write_gamma_entry(vc4, offset, &vc4_crtc->pwl_r[i]); -+ vc5_hvs_write_gamma_entry(hvs, offset, &vc4_crtc->pwl_r[i]); - for (i = 0; i < SCALER5_DSPGAMMA_NUM_POINTS; i++, offset += 8) -- vc5_hvs_write_gamma_entry(vc4, offset, &vc4_crtc->pwl_g[i]); -+ vc5_hvs_write_gamma_entry(hvs, offset, &vc4_crtc->pwl_g[i]); - for (i = 0; i < SCALER5_DSPGAMMA_NUM_POINTS; i++, offset += 8) -- vc5_hvs_write_gamma_entry(vc4, offset, &vc4_crtc->pwl_b[i]); -+ vc5_hvs_write_gamma_entry(hvs, offset, &vc4_crtc->pwl_b[i]); - - if (vc4_state->assigned_channel == 2) { - /* Alpha only valid on channel 2 */ - for (i = 0; i < SCALER5_DSPGAMMA_NUM_POINTS; i++, offset += 8) -- vc5_hvs_write_gamma_entry(vc4, offset, &vc4_crtc->pwl_a[i]); -+ vc5_hvs_write_gamma_entry(hvs, offset, &vc4_crtc->pwl_a[i]); - } - } - --static void vc5_hvs_update_gamma_lut(struct drm_crtc *crtc) -+static void vc5_hvs_update_gamma_lut(struct vc4_hvs *hvs, -+ struct vc4_crtc *vc4_crtc) - { -- struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); -+ struct drm_crtc *crtc = &vc4_crtc->base; - struct drm_color_lut *lut = crtc->state->gamma_lut->data; - unsigned int step, i; - u32 start, end; -@@ -408,16 +408,15 @@ static void vc5_hvs_update_gamma_lut(str - VC5_HVS_UPDATE_GAMMA_ENTRY_FROM_LUT(pwl_b, blue); - } - -- vc5_hvs_lut_load(crtc); -+ vc5_hvs_lut_load(hvs, vc4_crtc); - } - --int vc4_hvs_get_fifo_from_output(struct drm_device *dev, unsigned int output) -+int vc4_hvs_get_fifo_from_output(struct vc4_hvs *hvs, unsigned int output) - { -- struct vc4_dev *vc4 = to_vc4_dev(dev); - u32 reg; - int ret; - -- if (!vc4->hvs->hvs5) -+ if (!hvs->hvs5) - return output; - - switch (output) { -@@ -464,9 +463,10 @@ int vc4_hvs_get_fifo_from_output(struct - } - } - --static int vc4_hvs_init_channel(struct vc4_dev *vc4, struct drm_crtc *crtc, -+static int vc4_hvs_init_channel(struct vc4_hvs *hvs, struct drm_crtc *crtc, - struct drm_display_mode *mode, bool oneshot) - { -+ struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); - struct vc4_crtc_state *vc4_crtc_state = to_vc4_crtc_state(crtc->state); - unsigned int chan = vc4_crtc_state->assigned_channel; - bool interlace = mode->flags & DRM_MODE_FLAG_INTERLACE; -@@ -484,7 +484,7 @@ static int vc4_hvs_init_channel(struct v - */ - dispctrl = SCALER_DISPCTRLX_ENABLE; - -- if (!vc4->hvs->hvs5) -+ if (!hvs->hvs5) - dispctrl |= VC4_SET_FIELD(mode->hdisplay, - SCALER_DISPCTRLX_WIDTH) | - VC4_SET_FIELD(mode->vdisplay, -@@ -514,18 +514,16 @@ static int vc4_hvs_init_channel(struct v - /* Reload the LUT, since the SRAMs would have been disabled if - * all CRTCs had SCALER_DISPBKGND_GAMMA unset at once. - */ -- if (!vc4->hvs->hvs5) -- vc4_hvs_lut_load(crtc); -+ if (!hvs->hvs5) -+ vc4_hvs_lut_load(hvs, vc4_crtc); - else -- vc5_hvs_lut_load(crtc); -+ vc5_hvs_lut_load(hvs, vc4_crtc); - - return 0; - } - --void vc4_hvs_stop_channel(struct drm_device *dev, unsigned int chan) -+void vc4_hvs_stop_channel(struct vc4_hvs *hvs, unsigned int chan) - { -- struct vc4_dev *vc4 = to_vc4_dev(dev); -- - if (HVS_READ(SCALER_DISPCTRLX(chan)) & SCALER_DISPCTRLX_ENABLE) - return; - -@@ -623,6 +621,7 @@ static void vc4_hvs_install_dlist(struct - { - struct drm_device *dev = crtc->dev; - struct vc4_dev *vc4 = to_vc4_dev(dev); -+ struct vc4_hvs *hvs = vc4->hvs; - struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state); - - HVS_WRITE(SCALER_DISPLISTX(vc4_state->assigned_channel), -@@ -679,18 +678,19 @@ void vc4_hvs_atomic_enable(struct drm_cr - - vc4_hvs_install_dlist(crtc); - vc4_hvs_update_dlist(crtc); -- vc4_hvs_init_channel(vc4, crtc, mode, oneshot); -+ vc4_hvs_init_channel(vc4->hvs, crtc, mode, oneshot); - } - - void vc4_hvs_atomic_disable(struct drm_crtc *crtc, - struct drm_atomic_state *state) - { - struct drm_device *dev = crtc->dev; -+ struct vc4_dev *vc4 = to_vc4_dev(dev); - struct drm_crtc_state *old_state = drm_atomic_get_old_crtc_state(state, crtc); - struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(old_state); - unsigned int chan = vc4_state->assigned_channel; - -- vc4_hvs_stop_channel(dev, chan); -+ vc4_hvs_stop_channel(vc4->hvs, chan); - } - - void vc4_hvs_atomic_flush(struct drm_crtc *crtc, -@@ -700,6 +700,8 @@ void vc4_hvs_atomic_flush(struct drm_crt - crtc); - struct drm_device *dev = crtc->dev; - struct vc4_dev *vc4 = to_vc4_dev(dev); -+ struct vc4_hvs *hvs = vc4->hvs; -+ struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); - struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state); - unsigned int channel = vc4_state->assigned_channel; - struct drm_plane *plane; -@@ -714,7 +716,7 @@ void vc4_hvs_atomic_flush(struct drm_crt - - if (debug_dump_regs) { - DRM_INFO("CRTC %d HVS before:\n", drm_crtc_index(crtc)); -- vc4_hvs_dump_state(dev); -+ vc4_hvs_dump_state(hvs); - } - - /* Copy all the active planes' dlist contents to the hardware dlist. */ -@@ -766,10 +768,10 @@ void vc4_hvs_atomic_flush(struct drm_crt - - if (crtc->state->gamma_lut) { - if (!vc4->hvs->hvs5) { -- vc4_hvs_update_gamma_lut(crtc); -+ vc4_hvs_update_gamma_lut(hvs, vc4_crtc); - dispbkgndx |= SCALER_DISPBKGND_GAMMA; - } else { -- vc5_hvs_update_gamma_lut(crtc); -+ vc5_hvs_update_gamma_lut(hvs, vc4_crtc); - } - } else { - /* Unsetting DISPBKGND_GAMMA skips the gamma lut step -@@ -790,13 +792,12 @@ void vc4_hvs_atomic_flush(struct drm_crt - - if (debug_dump_regs) { - DRM_INFO("CRTC %d HVS after:\n", drm_crtc_index(crtc)); -- vc4_hvs_dump_state(dev); -+ vc4_hvs_dump_state(hvs); - } - } - --void vc4_hvs_mask_underrun(struct drm_device *dev, int channel) -+void vc4_hvs_mask_underrun(struct vc4_hvs *hvs, int channel) - { -- struct vc4_dev *vc4 = to_vc4_dev(dev); - u32 dispctrl = HVS_READ(SCALER_DISPCTRL); - - dispctrl &= ~SCALER_DISPCTRL_DSPEISLUR(channel); -@@ -804,9 +805,8 @@ void vc4_hvs_mask_underrun(struct drm_de - HVS_WRITE(SCALER_DISPCTRL, dispctrl); - } - --void vc4_hvs_unmask_underrun(struct drm_device *dev, int channel) -+void vc4_hvs_unmask_underrun(struct vc4_hvs *hvs, int channel) - { -- struct vc4_dev *vc4 = to_vc4_dev(dev); - u32 dispctrl = HVS_READ(SCALER_DISPCTRL); - - dispctrl |= SCALER_DISPCTRL_DSPEISLUR(channel); -@@ -828,6 +828,7 @@ static irqreturn_t vc4_hvs_irq_handler(i - { - struct drm_device *dev = data; - struct vc4_dev *vc4 = to_vc4_dev(dev); -+ struct vc4_hvs *hvs = vc4->hvs; - irqreturn_t irqret = IRQ_NONE; - int channel; - u32 control; -@@ -840,7 +841,7 @@ static irqreturn_t vc4_hvs_irq_handler(i - /* Interrupt masking is not always honored, so check it here. */ - if (status & SCALER_DISPSTAT_EUFLOW(channel) && - control & SCALER_DISPCTRL_DSPEISLUR(channel)) { -- vc4_hvs_mask_underrun(dev, channel); -+ vc4_hvs_mask_underrun(hvs, channel); - vc4_hvs_report_underrun(dev); - - irqret = IRQ_HANDLED; ---- a/drivers/gpu/drm/vc4/vc4_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_kms.c -@@ -158,6 +158,7 @@ static u16 vc4_ctm_s31_32_to_s0_9(u64 in - static void - vc4_ctm_commit(struct vc4_dev *vc4, struct drm_atomic_state *state) - { -+ struct vc4_hvs *hvs = vc4->hvs; - struct vc4_ctm_state *ctm_state = to_vc4_ctm_state(vc4->ctm_manager.state); - struct drm_color_ctm *ctm = ctm_state->ctm; - -@@ -234,6 +235,7 @@ vc4_hvs_get_global_state(struct drm_atom - static void vc4_hvs_pv_muxing_commit(struct vc4_dev *vc4, - struct drm_atomic_state *state) - { -+ struct vc4_hvs *hvs = vc4->hvs; - struct drm_crtc_state *crtc_state; - struct drm_crtc *crtc; - unsigned int i; -@@ -274,6 +276,7 @@ static void vc4_hvs_pv_muxing_commit(str - static void vc5_hvs_pv_muxing_commit(struct vc4_dev *vc4, - struct drm_atomic_state *state) - { -+ struct vc4_hvs *hvs = vc4->hvs; - struct drm_crtc_state *crtc_state; - struct drm_crtc *crtc; - unsigned char mux; -@@ -367,7 +370,7 @@ static void vc4_atomic_commit_tail(struc - continue; - - vc4_crtc_state = to_vc4_crtc_state(new_crtc_state); -- vc4_hvs_mask_underrun(dev, vc4_crtc_state->assigned_channel); -+ vc4_hvs_mask_underrun(hvs, vc4_crtc_state->assigned_channel); - } - - for (channel = 0; channel < HVS_NUM_CHANNELS; channel++) { diff --git a/target/linux/bcm27xx/patches-5.15/950-0743-ARM-dts-Add-GPIO-line-names-for-downstream-RPis.patch b/target/linux/bcm27xx/patches-5.15/950-0743-ARM-dts-Add-GPIO-line-names-for-downstream-RPis.patch deleted file mode 100644 index 6177eca57..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0743-ARM-dts-Add-GPIO-line-names-for-downstream-RPis.patch +++ /dev/null @@ -1,974 +0,0 @@ -From c4276e76a720c00d5115bc38d9834480552bcdbe Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Sun, 20 Feb 2022 16:27:11 +0000 -Subject: [PATCH] ARM: dts: Add GPIO line names for downstream RPis - -Largely copied from the upstream dts files, with a few additions and -tweaks. - -See: https://github.com/raspberrypi/linux/issues/2760 - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 66 +++++++++++++++++++ - arch/arm/boot/dts/bcm2708-rpi-b-rev1.dts | 67 +++++++++++++++++++ - arch/arm/boot/dts/bcm2708-rpi-b.dts | 66 +++++++++++++++++++ - arch/arm/boot/dts/bcm2708-rpi-cm.dts | 65 ++++++++++++++++++ - arch/arm/boot/dts/bcm2708-rpi-zero-w.dts | 67 +++++++++++++++++++ - arch/arm/boot/dts/bcm2708-rpi-zero.dts | 65 ++++++++++++++++++ - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 66 +++++++++++++++++++ - arch/arm/boot/dts/bcm2710-rpi-2-b.dts | 66 +++++++++++++++++++ - arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts | 76 ++++++++++++++++++++++ - arch/arm/boot/dts/bcm2710-rpi-3-b.dts | 76 ++++++++++++++++++++++ - arch/arm/boot/dts/bcm2710-rpi-cm3.dts | 72 ++++++++++++++++++++ - arch/arm/boot/dts/bcm2710-rpi-zero-2-w.dts | 67 +++++++++++++++++++ - 12 files changed, 819 insertions(+) - ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -12,6 +12,72 @@ - }; - - &gpio { -+ /* -+ * Taken from Raspberry-Pi-B-Plus-V1.2-Schematics.pdf -+ * RPI-BPLUS sheet 1 -+ * -+ * Legend: -+ * "NC" = not connected (no rail from the SoC) -+ * "FOO" = GPIO line named "FOO" on the schematic -+ * "FOO_N" = GPIO line named "FOO" on schematic, active low -+ */ -+ gpio-line-names = "ID_SDA", -+ "ID_SCL", -+ "SDA1", -+ "SCL1", -+ "GPIO_GCLK", -+ "GPIO5", -+ "GPIO6", -+ "SPI_CE1_N", -+ "SPI_CE0_N", -+ "SPI_MISO", -+ "SPI_MOSI", -+ "SPI_SCLK", -+ "GPIO12", -+ "GPIO13", -+ /* Serial port */ -+ "TXD0", -+ "RXD0", -+ "GPIO16", -+ "GPIO17", -+ "GPIO18", -+ "GPIO19", -+ "GPIO20", -+ "GPIO21", -+ "GPIO22", -+ "GPIO23", -+ "GPIO24", -+ "GPIO25", -+ "GPIO26", -+ "GPIO27", -+ "SDA0", -+ "SCL0", -+ "NC", /* GPIO30 */ -+ "LAN_RUN", /* GPIO31 */ -+ "CAM_GPIO1", /* GPIO32 */ -+ "NC", /* GPIO33 */ -+ "NC", /* GPIO34 */ -+ "PWR_LOW_N", /* GPIO35 */ -+ "NC", /* GPIO36 */ -+ "NC", /* GPIO37 */ -+ "USB_LIMIT", /* GPIO38 */ -+ "NC", /* GPIO39 */ -+ "PWM0_OUT", /* GPIO40 */ -+ "CAM_GPIO0", /* GPIO41 */ -+ "NC", /* GPIO42 */ -+ "NC", /* GPIO43 */ -+ "ETH_CLK", /* GPIO44 */ -+ "PWM1_OUT", /* GPIO45 */ -+ "HDMI_HPD_N", -+ "STATUS_LED", -+ /* Used by SD Card */ -+ "SD_CLK_R", -+ "SD_CMD_R", -+ "SD_DATA0_R", -+ "SD_DATA1_R", -+ "SD_DATA2_R", -+ "SD_DATA3_R"; -+ - spi0_pins: spi0_pins { - brcm,pins = <9 10 11>; - brcm,function = <4>; /* alt0 */ ---- a/arch/arm/boot/dts/bcm2708-rpi-b-rev1.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-rev1.dts -@@ -11,6 +11,73 @@ - }; - - &gpio { -+ /* -+ * Taken from Raspberry-Pi-Rev-1.0-Model-AB-Schematics.pdf -+ * RPI00021 sheet 02 -+ * -+ * Legend: -+ * "NC" = not connected (no rail from the SoC) -+ * "FOO" = GPIO line named "FOO" on the schematic -+ * "FOO_N" = GPIO line named "FOO" on schematic, active low -+ */ -+ gpio-line-names = "SDA0", -+ "SCL0", -+ "SDA1", -+ "SCL1", -+ "GPIO_GCLK", -+ "CAM_GPIO1", -+ "LAN_RUN", -+ "SPI_CE1_N", -+ "SPI_CE0_N", -+ "SPI_MISO", -+ "SPI_MOSI", -+ "SPI_SCLK", -+ "NC", /* GPIO12 */ -+ "NC", /* GPIO13 */ -+ /* Serial port */ -+ "TXD0", -+ "RXD0", -+ "STATUS_LED_N", -+ "GPIO17", -+ "GPIO18", -+ "NC", /* GPIO19 */ -+ "NC", /* GPIO20 */ -+ "GPIO21", -+ "GPIO22", -+ "GPIO23", -+ "GPIO24", -+ "GPIO25", -+ "NC", /* GPIO26 */ -+ "CAM_GPIO0", -+ /* Binary number representing build/revision */ -+ "CONFIG0", -+ "CONFIG1", -+ "CONFIG2", -+ "CONFIG3", -+ "NC", /* GPIO32 */ -+ "NC", /* GPIO33 */ -+ "NC", /* GPIO34 */ -+ "NC", /* GPIO35 */ -+ "NC", /* GPIO36 */ -+ "NC", /* GPIO37 */ -+ "NC", /* GPIO38 */ -+ "NC", /* GPIO39 */ -+ "PWM0_OUT", -+ "NC", /* GPIO41 */ -+ "NC", /* GPIO42 */ -+ "NC", /* GPIO43 */ -+ "NC", /* GPIO44 */ -+ "PWM1_OUT", -+ "HDMI_HPD_P", -+ "SD_CARD_DET", -+ /* Used by SD Card */ -+ "SD_CLK_R", -+ "SD_CMD_R", -+ "SD_DATA0_R", -+ "SD_DATA1_R", -+ "SD_DATA2_R", -+ "SD_DATA3_R"; -+ - spi0_pins: spi0_pins { - brcm,pins = <9 10 11>; - brcm,function = <4>; /* alt0 */ ---- a/arch/arm/boot/dts/bcm2708-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -12,6 +12,72 @@ - }; - - &gpio { -+ /* -+ * Taken from Raspberry-Pi-Rev-2.0-Model-AB-Schematics.pdf -+ * RPI00022 sheet 02 -+ * -+ * Legend: -+ * "NC" = not connected (no rail from the SoC) -+ * "FOO" = GPIO line named "FOO" on the schematic -+ * "FOO_N" = GPIO line named "FOO" on schematic, active low -+ */ -+ gpio-line-names = "SDA0", -+ "SCL0", -+ "SDA1", -+ "SCL1", -+ "GPIO_GCLK", -+ "CAM_GPIO1", -+ "LAN_RUN", -+ "SPI_CE1_N", -+ "SPI_CE0_N", -+ "SPI_MISO", -+ "SPI_MOSI", -+ "SPI_SCLK", -+ "NC", /* GPIO12 */ -+ "NC", /* GPIO13 */ -+ /* Serial port */ -+ "TXD0", -+ "RXD0", -+ "STATUS_LED_N", -+ "GPIO17", -+ "GPIO18", -+ "NC", /* GPIO19 */ -+ "NC", /* GPIO20 */ -+ "CAM_GPIO0", -+ "GPIO22", -+ "GPIO23", -+ "GPIO24", -+ "GPIO25", -+ "NC", /* GPIO26 */ -+ "GPIO27", -+ "GPIO28", -+ "GPIO29", -+ "GPIO30", -+ "GPIO31", -+ "NC", /* GPIO32 */ -+ "NC", /* GPIO33 */ -+ "NC", /* GPIO34 */ -+ "NC", /* GPIO35 */ -+ "NC", /* GPIO36 */ -+ "NC", /* GPIO37 */ -+ "NC", /* GPIO38 */ -+ "NC", /* GPIO39 */ -+ "PWM0_OUT", -+ "NC", /* GPIO41 */ -+ "NC", /* GPIO42 */ -+ "NC", /* GPIO43 */ -+ "NC", /* GPIO44 */ -+ "PWM1_OUT", -+ "HDMI_HPD_P", -+ "SD_CARD_DET", -+ /* Used by SD Card */ -+ "SD_CLK_R", -+ "SD_CMD_R", -+ "SD_DATA0_R", -+ "SD_DATA1_R", -+ "SD_DATA2_R", -+ "SD_DATA3_R"; -+ - spi0_pins: spi0_pins { - brcm,pins = <9 10 11>; - brcm,function = <4>; /* alt0 */ ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -@@ -24,6 +24,71 @@ cam0_reg: &cam0_regulator { - }; - - &gpio { -+ /* -+ * This is based on the official GPU firmware DT blob. -+ * -+ * Legend: -+ * "NC" = not connected (no rail from the SoC) -+ * "FOO" = GPIO line named "FOO" on the schematic -+ * "FOO_N" = GPIO line named "FOO" on schematic, active low -+ */ -+ gpio-line-names = "GPIO0", -+ "GPIO1", -+ "GPIO2", -+ "GPIO3", -+ "GPIO4", -+ "GPIO5", -+ "GPIO6", -+ "GPIO7", -+ "GPIO8", -+ "GPIO9", -+ "GPIO10", -+ "GPIO11", -+ "GPIO12", -+ "GPIO13", -+ "GPIO14", -+ "GPIO15", -+ "GPIO16", -+ "GPIO17", -+ "GPIO18", -+ "GPIO19", -+ "GPIO20", -+ "GPIO21", -+ "GPIO22", -+ "GPIO23", -+ "GPIO24", -+ "GPIO25", -+ "GPIO26", -+ "GPIO27", -+ "GPIO28", -+ "GPIO29", -+ "GPIO30", -+ "GPIO31", -+ "GPIO32", -+ "GPIO33", -+ "GPIO34", -+ "GPIO35", -+ "GPIO36", -+ "GPIO37", -+ "GPIO38", -+ "GPIO39", -+ "GPIO40", -+ "GPIO41", -+ "GPIO42", -+ "GPIO43", -+ "GPIO44", -+ "GPIO45", -+ "HDMI_HPD_N", -+ /* Also used as ACT LED */ -+ "EMMC_EN_N", -+ /* Used by eMMC */ -+ "SD_CLK_R", -+ "SD_CMD_R", -+ "SD_DATA0_R", -+ "SD_DATA1_R", -+ "SD_DATA2_R", -+ "SD_DATA3_R"; -+ - spi0_pins: spi0_pins { - brcm,pins = <9 10 11>; - brcm,function = <4>; /* alt0 */ ---- a/arch/arm/boot/dts/bcm2708-rpi-zero-w.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-zero-w.dts -@@ -22,6 +22,73 @@ - }; - - &gpio { -+ /* -+ * This is based on the official GPU firmware DT blob. -+ * -+ * Legend: -+ * "NC" = not connected (no rail from the SoC) -+ * "FOO" = GPIO line named "FOO" on the schematic -+ * "FOO_N" = GPIO line named "FOO" on schematic, active low -+ */ -+ gpio-line-names = "ID_SDA", -+ "ID_SCL", -+ "SDA1", -+ "SCL1", -+ "GPIO_GCLK", -+ "GPIO5", -+ "GPIO6", -+ "SPI_CE1_N", -+ "SPI_CE0_N", -+ "SPI_MISO", -+ "SPI_MOSI", -+ "SPI_SCLK", -+ "GPIO12", -+ "GPIO13", -+ /* Serial port */ -+ "TXD0", -+ "RXD0", -+ "GPIO16", -+ "GPIO17", -+ "GPIO18", -+ "GPIO19", -+ "GPIO20", -+ "GPIO21", -+ "GPIO22", -+ "GPIO23", -+ "GPIO24", -+ "GPIO25", -+ "GPIO26", -+ "GPIO27", -+ "SDA0", -+ "SCL0", -+ /* Used by BT module */ -+ "CTS0", -+ "RTS0", -+ "TXD0", -+ "RXD0", -+ /* Used by Wifi */ -+ "SD1_CLK", -+ "SD1_CMD", -+ "SD1_DATA0", -+ "SD1_DATA1", -+ "SD1_DATA2", -+ "SD1_DATA3", -+ "CAM_GPIO1", /* GPIO40 */ -+ "WL_ON", /* GPIO41 */ -+ "NC", /* GPIO42 */ -+ "WIFI_CLK", /* GPIO43 */ -+ "CAM_GPIO0", /* GPIO44 */ -+ "BT_ON", /* GPIO45 */ -+ "HDMI_HPD_N", -+ "STATUS_LED_N", -+ /* Used by SD Card */ -+ "SD_CLK_R", -+ "SD_CMD_R", -+ "SD_DATA0_R", -+ "SD_DATA1_R", -+ "SD_DATA2_R", -+ "SD_DATA3_R"; -+ - spi0_pins: spi0_pins { - brcm,pins = <9 10 11>; - brcm,function = <4>; /* alt0 */ ---- a/arch/arm/boot/dts/bcm2708-rpi-zero.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-zero.dts -@@ -15,6 +15,71 @@ - }; - - &gpio { -+ /* -+ * This is based on the official GPU firmware DT blob. -+ * -+ * Legend: -+ * "NC" = not connected (no rail from the SoC) -+ * "FOO" = GPIO line named "FOO" on the schematic -+ * "FOO_N" = GPIO line named "FOO" on schematic, active low -+ */ -+ gpio-line-names = "ID_SDA", -+ "ID_SCL", -+ "SDA1", -+ "SCL1", -+ "GPIO_GCLK", -+ "GPIO5", -+ "GPIO6", -+ "SPI_CE1_N", -+ "SPI_CE0_N", -+ "SPI_MISO", -+ "SPI_MOSI", -+ "SPI_SCLK", -+ "GPIO12", -+ "GPIO13", -+ /* Serial port */ -+ "TXD0", -+ "RXD0", -+ "GPIO16", -+ "GPIO17", -+ "GPIO18", -+ "GPIO19", -+ "GPIO20", -+ "GPIO21", -+ "GPIO22", -+ "GPIO23", -+ "GPIO24", -+ "GPIO25", -+ "GPIO26", -+ "GPIO27", -+ "SDA0", -+ "SCL0", -+ "NC", /* GPIO30 */ -+ "NC", /* GPIO31 */ -+ "CAM_GPIO1", /* GPIO32 */ -+ "NC", /* GPIO33 */ -+ "NC", /* GPIO34 */ -+ "NC", /* GPIO35 */ -+ "NC", /* GPIO36 */ -+ "NC", /* GPIO37 */ -+ "NC", /* GPIO38 */ -+ "NC", /* GPIO39 */ -+ "NC", /* GPIO40 */ -+ "CAM_GPIO0", /* GPIO41 */ -+ "NC", /* GPIO42 */ -+ "NC", /* GPIO43 */ -+ "NC", /* GPIO44 */ -+ "NC", /* GPIO45 */ -+ "HDMI_HPD_N", -+ "STATUS_LED_N", -+ /* Used by SD Card */ -+ "SD_CLK_R", -+ "SD_CMD_R", -+ "SD_DATA0_R", -+ "SD_DATA1_R", -+ "SD_DATA2_R", -+ "SD_DATA3_R"; -+ - spi0_pins: spi0_pins { - brcm,pins = <9 10 11>; - brcm,function = <4>; /* alt0 */ ---- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -+++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -12,6 +12,72 @@ - }; - - &gpio { -+ /* -+ * Taken from rpi_SCH_2b_1p2_reduced.pdf and -+ * the official GPU firmware DT blob. -+ * -+ * Legend: -+ * "NC" = not connected (no rail from the SoC) -+ * "FOO" = GPIO line named "FOO" on the schematic -+ * "FOO_N" = GPIO line named "FOO" on schematic, active low -+ */ -+ gpio-line-names = "ID_SDA", -+ "ID_SCL", -+ "SDA1", -+ "SCL1", -+ "GPIO_GCLK", -+ "GPIO5", -+ "GPIO6", -+ "SPI_CE1_N", -+ "SPI_CE0_N", -+ "SPI_MISO", -+ "SPI_MOSI", -+ "SPI_SCLK", -+ "GPIO12", -+ "GPIO13", -+ /* Serial port */ -+ "TXD0", -+ "RXD0", -+ "GPIO16", -+ "GPIO17", -+ "GPIO18", -+ "GPIO19", -+ "GPIO20", -+ "GPIO21", -+ "GPIO22", -+ "GPIO23", -+ "GPIO24", -+ "GPIO25", -+ "GPIO26", -+ "GPIO27", -+ "SDA0", -+ "SCL0", -+ "NC", /* GPIO30 */ -+ "LAN_RUN", -+ "CAM_GPIO1", -+ "NC", /* GPIO33 */ -+ "NC", /* GPIO34 */ -+ "PWR_LOW_N", -+ "NC", /* GPIO36 */ -+ "NC", /* GPIO37 */ -+ "USB_LIMIT", -+ "NC", /* GPIO39 */ -+ "PWM0_OUT", -+ "CAM_GPIO0", -+ "SMPS_SCL", -+ "SMPS_SDA", -+ "ETH_CLK", -+ "PWM1_OUT", -+ "HDMI_HPD_N", -+ "STATUS_LED", -+ /* Used by SD Card */ -+ "SD_CLK_R", -+ "SD_CMD_R", -+ "SD_DATA0_R", -+ "SD_DATA1_R", -+ "SD_DATA2_R", -+ "SD_DATA3_R"; -+ - spi0_pins: spi0_pins { - brcm,pins = <9 10 11>; - brcm,function = <4>; /* alt0 */ ---- a/arch/arm/boot/dts/bcm2710-rpi-2-b.dts -+++ b/arch/arm/boot/dts/bcm2710-rpi-2-b.dts -@@ -12,6 +12,72 @@ - }; - - &gpio { -+ /* -+ * Taken from rpi_SCH_2b_1p2_reduced.pdf and -+ * the official GPU firmware DT blob. -+ * -+ * Legend: -+ * "NC" = not connected (no rail from the SoC) -+ * "FOO" = GPIO line named "FOO" on the schematic -+ * "FOO_N" = GPIO line named "FOO" on schematic, active low -+ */ -+ gpio-line-names = "ID_SDA", -+ "ID_SCL", -+ "SDA1", -+ "SCL1", -+ "GPIO_GCLK", -+ "GPIO5", -+ "GPIO6", -+ "SPI_CE1_N", -+ "SPI_CE0_N", -+ "SPI_MISO", -+ "SPI_MOSI", -+ "SPI_SCLK", -+ "GPIO12", -+ "GPIO13", -+ /* Serial port */ -+ "TXD0", -+ "RXD0", -+ "GPIO16", -+ "GPIO17", -+ "GPIO18", -+ "GPIO19", -+ "GPIO20", -+ "GPIO21", -+ "GPIO22", -+ "GPIO23", -+ "GPIO24", -+ "GPIO25", -+ "GPIO26", -+ "GPIO27", -+ "SDA0", -+ "SCL0", -+ "NC", /* GPIO30 */ -+ "LAN_RUN", -+ "CAM_GPIO1", -+ "NC", /* GPIO33 */ -+ "NC", /* GPIO34 */ -+ "PWR_LOW_N", -+ "NC", /* GPIO36 */ -+ "NC", /* GPIO37 */ -+ "USB_LIMIT", -+ "NC", /* GPIO39 */ -+ "PWM0_OUT", -+ "CAM_GPIO0", -+ "SMPS_SCL", -+ "SMPS_SDA", -+ "ETH_CLK", -+ "PWM1_OUT", -+ "HDMI_HPD_N", -+ "STATUS_LED", -+ /* Used by SD Card */ -+ "SD_CLK_R", -+ "SD_CMD_R", -+ "SD_DATA0_R", -+ "SD_DATA1_R", -+ "SD_DATA2_R", -+ "SD_DATA3_R"; -+ - spi0_pins: spi0_pins { - brcm,pins = <9 10 11>; - brcm,function = <4>; /* alt0 */ ---- a/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2710-rpi-3-b-plus.dts -@@ -23,6 +23,74 @@ - }; - - &gpio { -+ /* -+ * Taken from rpi_SCH_3bplus_1p0_reduced.pdf and -+ * the official GPU firmware DT blob. -+ * -+ * Legend: -+ * "NC" = not connected (no rail from the SoC) -+ * "FOO" = GPIO line named "FOO" on the schematic -+ * "FOO_N" = GPIO line named "FOO" on schematic, active low -+ */ -+ gpio-line-names = "ID_SDA", -+ "ID_SCL", -+ "SDA1", -+ "SCL1", -+ "GPIO_GCLK", -+ "GPIO5", -+ "GPIO6", -+ "SPI_CE1_N", -+ "SPI_CE0_N", -+ "SPI_MISO", -+ "SPI_MOSI", -+ "SPI_SCLK", -+ "GPIO12", -+ "GPIO13", -+ /* Serial port */ -+ "TXD1", -+ "RXD1", -+ "GPIO16", -+ "GPIO17", -+ "GPIO18", -+ "GPIO19", -+ "GPIO20", -+ "GPIO21", -+ "GPIO22", -+ "GPIO23", -+ "GPIO24", -+ "GPIO25", -+ "GPIO26", -+ "GPIO27", -+ "HDMI_HPD_N", -+ "STATUS_LED_G", -+ /* Used by BT module */ -+ "CTS0", -+ "RTS0", -+ "TXD0", -+ "RXD0", -+ /* Used by Wifi */ -+ "SD1_CLK", -+ "SD1_CMD", -+ "SD1_DATA0", -+ "SD1_DATA1", -+ "SD1_DATA2", -+ "SD1_DATA3", -+ "PWM0_OUT", -+ "PWM1_OUT", -+ "ETH_CLK", -+ "WIFI_CLK", -+ "SDA0", -+ "SCL0", -+ "SMPS_SCL", -+ "SMPS_SDA", -+ /* Used by SD Card */ -+ "SD_CLK_R", -+ "SD_CMD_R", -+ "SD_DATA0_R", -+ "SD_DATA1_R", -+ "SD_DATA2_R", -+ "SD_DATA3_R"; -+ - spi0_pins: spi0_pins { - brcm,pins = <9 10 11>; - brcm,function = <4>; /* alt0 */ -@@ -97,6 +165,14 @@ - compatible = "raspberrypi,firmware-gpio"; - gpio-controller; - #gpio-cells = <2>; -+ gpio-line-names = "BT_ON", -+ "WL_ON", -+ "PWR_LED_R", -+ "LAN_RUN", -+ "NC", -+ "CAM_GPIO0", -+ "CAM_GPIO1", -+ "NC"; - status = "okay"; - }; - }; ---- a/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -+++ b/arch/arm/boot/dts/bcm2710-rpi-3-b.dts -@@ -23,6 +23,74 @@ - }; - - &gpio { -+ /* -+ * Taken from rpi_SCH_3b_1p2_reduced.pdf and -+ * the official GPU firmware DT blob. -+ * -+ * Legend: -+ * "NC" = not connected (no rail from the SoC) -+ * "FOO" = GPIO line named "FOO" on the schematic -+ * "FOO_N" = GPIO line named "FOO" on schematic, active low -+ */ -+ gpio-line-names = "ID_SDA", -+ "ID_SCL", -+ "SDA1", -+ "SCL1", -+ "GPIO_GCLK", -+ "GPIO5", -+ "GPIO6", -+ "SPI_CE1_N", -+ "SPI_CE0_N", -+ "SPI_MISO", -+ "SPI_MOSI", -+ "SPI_SCLK", -+ "GPIO12", -+ "GPIO13", -+ /* Serial port */ -+ "TXD1", -+ "RXD1", -+ "GPIO16", -+ "GPIO17", -+ "GPIO18", -+ "GPIO19", -+ "GPIO20", -+ "GPIO21", -+ "GPIO22", -+ "GPIO23", -+ "GPIO24", -+ "GPIO25", -+ "GPIO26", -+ "GPIO27", -+ "NC", /* GPIO 28 */ -+ "LAN_RUN_BOOT", -+ /* Used by BT module */ -+ "CTS0", -+ "RTS0", -+ "TXD0", -+ "RXD0", -+ /* Used by Wifi */ -+ "SD1_CLK", -+ "SD1_CMD", -+ "SD1_DATA0", -+ "SD1_DATA1", -+ "SD1_DATA2", -+ "SD1_DATA3", -+ "PWM0_OUT", -+ "PWM1_OUT", -+ "ETH_CLK", -+ "WIFI_CLK", -+ "SDA0", -+ "SCL0", -+ "SMPS_SCL", -+ "SMPS_SDA", -+ /* Used by SD Card */ -+ "SD_CLK_R", -+ "SD_CMD_R", -+ "SD_DATA0_R", -+ "SD_DATA1_R", -+ "SD_DATA2_R", -+ "SD_DATA3_R"; -+ - spi0_pins: spi0_pins { - brcm,pins = <9 10 11>; - brcm,function = <4>; /* alt0 */ -@@ -108,6 +176,14 @@ - compatible = "raspberrypi,firmware-gpio"; - gpio-controller; - #gpio-cells = <2>; -+ gpio-line-names = "BT_ON", -+ "WL_ON", -+ "STATUS_LED", -+ "LAN_RUN", -+ "HDMI_HPD_N", -+ "CAM_GPIO0", -+ "CAM_GPIO1", -+ "PWR_LOW_N"; - status = "okay"; - }; - }; ---- a/arch/arm/boot/dts/bcm2710-rpi-cm3.dts -+++ b/arch/arm/boot/dts/bcm2710-rpi-cm3.dts -@@ -24,6 +24,70 @@ cam0_reg: &cam0_regulator { - }; - - &gpio { -+ /* -+ * This is based on the official GPU firmware DT blob. -+ * -+ * Legend: -+ * "NC" = not connected (no rail from the SoC) -+ * "FOO" = GPIO line named "FOO" on the schematic -+ * "FOO_N" = GPIO line named "FOO" on schematic, active low -+ */ -+ gpio-line-names = "GPIO0", -+ "GPIO1", -+ "GPIO2", -+ "GPIO3", -+ "GPIO4", -+ "GPIO5", -+ "GPIO6", -+ "GPIO7", -+ "GPIO8", -+ "GPIO9", -+ "GPIO10", -+ "GPIO11", -+ "GPIO12", -+ "GPIO13", -+ "GPIO14", -+ "GPIO15", -+ "GPIO16", -+ "GPIO17", -+ "GPIO18", -+ "GPIO19", -+ "GPIO20", -+ "GPIO21", -+ "GPIO22", -+ "GPIO23", -+ "GPIO24", -+ "GPIO25", -+ "GPIO26", -+ "GPIO27", -+ "GPIO28", -+ "GPIO29", -+ "GPIO30", -+ "GPIO31", -+ "GPIO32", -+ "GPIO33", -+ "GPIO34", -+ "GPIO35", -+ "GPIO36", -+ "GPIO37", -+ "GPIO38", -+ "GPIO39", -+ "GPIO40", -+ "GPIO41", -+ "GPIO42", -+ "GPIO43", -+ "GPIO44", -+ "GPIO45", -+ "SMPS_SCL", -+ "SMPS_SDA", -+ /* Used by eMMC */ -+ "SD_CLK_R", -+ "SD_CMD_R", -+ "SD_DATA0_R", -+ "SD_DATA1_R", -+ "SD_DATA2_R", -+ "SD_DATA3_R"; -+ - spi0_pins: spi0_pins { - brcm,pins = <9 10 11>; - brcm,function = <4>; /* alt0 */ -@@ -71,6 +135,14 @@ cam0_reg: &cam0_regulator { - compatible = "raspberrypi,firmware-gpio"; - gpio-controller; - #gpio-cells = <2>; -+ gpio-line-names = "HDMI_HPD_N", -+ "EMMC_EN_N", -+ "NC", -+ "NC", -+ "NC", -+ "NC", -+ "NC", -+ "NC"; - status = "okay"; - }; - }; ---- a/arch/arm/boot/dts/bcm2710-rpi-zero-2-w.dts -+++ b/arch/arm/boot/dts/bcm2710-rpi-zero-2-w.dts -@@ -22,6 +22,73 @@ - }; - - &gpio { -+ /* -+ * This is based on the official GPU firmware DT blob. -+ * -+ * Legend: -+ * "NC" = not connected (no rail from the SoC) -+ * "FOO" = GPIO line named "FOO" on the schematic -+ * "FOO_N" = GPIO line named "FOO" on schematic, active low -+ */ -+ gpio-line-names = "ID_SDA", -+ "ID_SCL", -+ "SDA1", -+ "SCL1", -+ "GPIO_GCLK", -+ "GPIO5", -+ "GPIO6", -+ "SPI_CE1_N", -+ "SPI_CE0_N", -+ "SPI_MISO", -+ "SPI_MOSI", -+ "SPI_SCLK", -+ "GPIO12", -+ "GPIO13", -+ /* Serial port */ -+ "TXD0", -+ "RXD0", -+ "GPIO16", -+ "GPIO17", -+ "GPIO18", -+ "GPIO19", -+ "GPIO20", -+ "GPIO21", -+ "GPIO22", -+ "GPIO23", -+ "GPIO24", -+ "GPIO25", -+ "GPIO26", -+ "GPIO27", -+ "HDMI_HPD_N", -+ "STATUS_LED_N", -+ /* Used by BT module */ -+ "CTS0", -+ "RTS0", -+ "TXD0", -+ "RXD0", -+ /* Used by Wifi */ -+ "SD1_CLK", -+ "SD1_CMD", -+ "SD1_DATA0", -+ "SD1_DATA1", -+ "SD1_DATA2", -+ "SD1_DATA3", -+ "CAM_GPIO1", /* GPIO40 */ -+ "WL_ON", /* GPIO41 */ -+ "BT_ON", /* GPIO42 */ -+ "WIFI_CLK", /* GPIO43 */ -+ "SDA0", /* GPIO44 */ -+ "SCL0", /* GPIO45 */ -+ "SMPS_SCL", /* GPIO46 */ -+ "SMPS_SDA", /* GPIO47 */ -+ /* Used by SD Card */ -+ "SD_CLK_R", -+ "SD_CMD_R", -+ "SD_DATA0_R", -+ "SD_DATA1_R", -+ "SD_DATA2_R", -+ "SD_DATA3_R"; -+ - spi0_pins: spi0_pins { - brcm,pins = <9 10 11>; - brcm,function = <4>; /* alt0 */ diff --git a/target/linux/bcm27xx/patches-5.15/950-0744-overlays-fixes-probing-of-Hifiberry-DAC2-HD.patch b/target/linux/bcm27xx/patches-5.15/950-0744-overlays-fixes-probing-of-Hifiberry-DAC2-HD.patch deleted file mode 100644 index 0d79868c6..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0744-overlays-fixes-probing-of-Hifiberry-DAC2-HD.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 26637f1e9fad7dd14501088c1cac1b5e5c611dbb Mon Sep 17 00:00:00 2001 -From: Joerg Schambacher -Date: Wed, 23 Feb 2022 12:08:42 +0100 -Subject: [PATCH] overlays:fixes probing of Hifiberry DAC2 HD - -Removed clocks-declarations in I2C sections of the DT-overlay -which kept the devices from probing. - -Signed-off-by: Joerg Schambacher ---- - .../dts/overlays/hifiberry-dacplushd-overlay.dts | 16 ++-------------- - 1 file changed, 2 insertions(+), 14 deletions(-) - ---- a/arch/arm/boot/dts/overlays/hifiberry-dacplushd-overlay.dts -+++ b/arch/arm/boot/dts/overlays/hifiberry-dacplushd-overlay.dts -@@ -8,23 +8,13 @@ - compatible = "brcm,bcm2835"; - - fragment@0 { -- target-path = "/"; -- __overlay__ { -- dachd_osc: pll_dachd_osc { -- compatible = "hifiberry,dachd-clk"; -- #clock-cells = <0>; -- }; -- }; -- }; -- -- fragment@1 { - target = <&i2s>; - __overlay__ { - status = "okay"; - }; - }; - -- fragment@2 { -+ fragment@1 { - target = <&i2c1>; - __overlay__ { - #address-cells = <1>; -@@ -35,7 +25,6 @@ - compatible = "ti,pcm1792a"; - #sound-dai-cells = <0>; - #clock-cells = <0>; -- clocks = <&dachd_osc>; - reg = <0x4c>; - status = "okay"; - }; -@@ -43,7 +32,6 @@ - compatible = "hifiberry,dachd-clk"; - #clock-cells = <0>; - reg = <0x62>; -- clocks = <&dachd_osc>; - status = "okay"; - common_pll_regs = [ - 02 53 03 00 07 20 0F 00 -@@ -92,7 +80,7 @@ - }; - }; - -- fragment@3 { -+ fragment@2 { - target = <&sound>; - __overlay__ { - compatible = "hifiberry,hifiberry-dacplushd"; diff --git a/target/linux/bcm27xx/patches-5.15/950-0745-overlays-Overlays-for-WaveShare-2-Chan-CAN-FD-HAT.patch b/target/linux/bcm27xx/patches-5.15/950-0745-overlays-Overlays-for-WaveShare-2-Chan-CAN-FD-HAT.patch deleted file mode 100644 index 4697be295..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0745-overlays-Overlays-for-WaveShare-2-Chan-CAN-FD-HAT.patch +++ /dev/null @@ -1,321 +0,0 @@ -From dadc749c5ccc320127871d7c3ace51a7fae479a7 Mon Sep 17 00:00:00 2001 -From: nmbath -Date: Thu, 24 Feb 2022 13:10:01 +0000 -Subject: [PATCH] overlays: Overlays for WaveShare 2-Chan CAN FD HAT - -This patch adds the overlays for the Waveshare 2-Channel Isolated -CAN FD Expansion HAT for Raspberry Pi, Multi Protections. This HAT -is based on the mcp2518fd chip and can be run in two modes - -Mode A: can0 on spi0.0 and can1 on spi1.0 (cs = pin 26) -Mode B: can1 on spi0.0 and can1 in spi0.1 - -Interupts: can0 pin 25 / can1 pin 16 - -https://www.waveshare.com/2-ch-can-fd-hat.htm - -Overlays generated by: -Mode A: ovmerge -c spi1-1cs-overlay.dts,cs0_pin=26,cs0_spidev=false \ - mcp251xfd-overlay.dts,spi0-0,interrupt=25 \ - mcp251xfd-overlay.dts,spi1-0,interrupt=16 - -Mode B: ovmerge -c mcp251xfd-overlay.dts,spi0-0,interrupt=25 \ - mcp251xfd-overlay.dts,spi0-1,interrupt=16 ---- - arch/arm/boot/dts/overlays/Makefile | 2 + - arch/arm/boot/dts/overlays/README | 20 +++ - .../waveshare-can-fd-hat-mode-a-overlay.dts | 140 ++++++++++++++++++ - .../waveshare-can-fd-hat-mode-b-overlay.dts | 103 +++++++++++++ - 4 files changed, 265 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/waveshare-can-fd-hat-mode-a-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/waveshare-can-fd-hat-mode-b-overlay.dts - ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -251,6 +251,8 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ - w1-gpio.dtbo \ - w1-gpio-pullup.dtbo \ - w5500.dtbo \ -+ waveshare-can-fd-hat-mode-a.dtbo \ -+ waveshare-can-fd-hat-mode-b.dtbo \ - wittypi.dtbo \ - wm8960-soundcard.dtbo - ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -3879,6 +3879,26 @@ Params: int_pin GPIO use - cs SPI bus Chip Select (default 0) - - -+Name: waveshare-can-fd-hat-mode-a -+Info: Overlay for the Waveshare 2-Channel Isolated CAN FD Expansion HAT -+ for Raspberry Pi, Multi Protections. Use this overlay when the -+ HAT is configured in Mode A (Default), with can0 on spi0.0 -+ and can1 on spi1.0. -+ https://www.waveshare.com/2-ch-can-fd-hat.htm -+Load: dtoverlay=waveshare-can-fd-hat-mode-a -+Params: -+ -+ -+Name: waveshare-can-fd-hat-mode-b -+Info: Overlay for the Waveshare 2-Channel Isolated CAN FD Expansion HAT -+ for Raspberry Pi, Multi Protections. Use this overlay when the -+ HAT is configured in Mode B (requires hardware modification), with -+ can0 on spi0.0 and can1 on spi0.1. -+ https://www.waveshare.com/2-ch-can-fd-hat.htm -+Load: dtoverlay=waveshare-can-fd-hat-mode-b -+Params: -+ -+ - Name: wittypi - Info: Configures the wittypi RTC module. - Load: dtoverlay=wittypi,= ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/waveshare-can-fd-hat-mode-a-overlay.dts -@@ -0,0 +1,140 @@ -+// redo: ovmerge -c spi1-1cs-overlay.dts,cs0_pin=26,cs0_spidev=false mcp251xfd-overlay.dts,spi0-0,interrupt=25 mcp251xfd-overlay.dts,spi1-0,interrupt=16 -+ -+// Device tree overlay for https://www.waveshare.com/2-ch-can-fd-hat.htm -+// in "Mode A" (default) configuration -+// for details see https://www.waveshare.com/wiki/2-CH_CAN_FD_HAT -+ -+/dts-v1/; -+/plugin/; -+ -+#include -+#include -+#include -+ -+/ { -+ compatible = "brcm,bcm2835"; -+ fragment@0 { -+ target = <&gpio>; -+ __overlay__ { -+ spi1_pins: spi1_pins { -+ brcm,pins = <19 20 21>; -+ brcm,function = <3>; -+ }; -+ spi1_cs_pins: spi1_cs_pins { -+ brcm,pins = <26>; -+ brcm,function = <1>; -+ }; -+ }; -+ }; -+ fragment@1 { -+ target = <&spi1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi1_pins &spi1_cs_pins>; -+ cs-gpios = <&gpio 26 1>; -+ status = "okay"; -+ spidev@0 { -+ compatible = "spidev"; -+ reg = <0>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <125000000>; -+ status = "disabled"; -+ }; -+ }; -+ }; -+ fragment@2 { -+ target = <&aux>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ fragment@3 { -+ target = <&spidev0>; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; -+ fragment@4 { -+ target = <&gpio>; -+ __overlay__ { -+ mcp251xfd_pins: mcp251xfd_spi0_0_pins { -+ brcm,pins = <25>; -+ brcm,function = ; -+ }; -+ }; -+ }; -+ fragment@5 { -+ target-path = "/clocks"; -+ __overlay__ { -+ clk_mcp251xfd_osc: mcp251xfd-spi0-0-osc { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <40000000>; -+ }; -+ }; -+ }; -+ fragment@6 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ mcp251xfd@0 { -+ compatible = "microchip,mcp251xfd"; -+ reg = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mcp251xfd_pins>; -+ spi-max-frequency = <20000000>; -+ interrupt-parent = <&gpio>; -+ interrupts = <25 IRQ_TYPE_LEVEL_LOW>; -+ clocks = <&clk_mcp251xfd_osc>; -+ }; -+ }; -+ }; -+ fragment@7 { -+ target-path = "spi1/spidev@0"; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; -+ fragment@8 { -+ target = <&gpio>; -+ __overlay__ { -+ mcp251xfd_pins_1: mcp251xfd_spi1_0_pins { -+ brcm,pins = <16>; -+ brcm,function = ; -+ }; -+ }; -+ }; -+ fragment@9 { -+ target-path = "/clocks"; -+ __overlay__ { -+ clk_mcp251xfd_osc_1: mcp251xfd-spi1-0-osc { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <40000000>; -+ }; -+ }; -+ }; -+ fragment@10 { -+ target = <&spi1>; -+ __overlay__ { -+ status = "okay"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ mcp251xfd@0 { -+ compatible = "microchip,mcp251xfd"; -+ reg = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mcp251xfd_pins_1>; -+ spi-max-frequency = <20000000>; -+ interrupt-parent = <&gpio>; -+ interrupts = <16 IRQ_TYPE_LEVEL_LOW>; -+ clocks = <&clk_mcp251xfd_osc_1>; -+ }; -+ }; -+ }; -+}; ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/waveshare-can-fd-hat-mode-b-overlay.dts -@@ -0,0 +1,103 @@ -+// redo: ovmerge -c mcp251xfd-overlay.dts,spi0-0,interrupt=25 mcp251xfd-overlay.dts,spi0-1,interrupt=16 -+ -+// Device tree overlay for https://www.waveshare.com/2-ch-can-fd-hat.htm -+// in "Mode B" (requried hardware modification) configuration -+// for details see https://www.waveshare.com/wiki/2-CH_CAN_FD_HAT -+ -+ -+/dts-v1/; -+/plugin/; -+ -+#include -+#include -+#include -+ -+/ { -+ compatible = "brcm,bcm2835"; -+ fragment@0 { -+ target = <&spidev0>; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ mcp251xfd_pins: mcp251xfd_spi0_0_pins { -+ brcm,pins = <25>; -+ brcm,function = ; -+ }; -+ }; -+ }; -+ fragment@2 { -+ target-path = "/clocks"; -+ __overlay__ { -+ clk_mcp251xfd_osc: mcp251xfd-spi0-0-osc { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <40000000>; -+ }; -+ }; -+ }; -+ fragment@3 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ mcp251xfd@0 { -+ compatible = "microchip,mcp251xfd"; -+ reg = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mcp251xfd_pins>; -+ spi-max-frequency = <20000000>; -+ interrupt-parent = <&gpio>; -+ interrupts = <25 IRQ_TYPE_LEVEL_LOW>; -+ clocks = <&clk_mcp251xfd_osc>; -+ }; -+ }; -+ }; -+ fragment@4 { -+ target = <&spidev1>; -+ __overlay__ { -+ status = "disabled"; -+ }; -+ }; -+ fragment@5 { -+ target = <&gpio>; -+ __overlay__ { -+ mcp251xfd_pins_1: mcp251xfd_spi0_1_pins { -+ brcm,pins = <16>; -+ brcm,function = ; -+ }; -+ }; -+ }; -+ fragment@6 { -+ target-path = "/clocks"; -+ __overlay__ { -+ clk_mcp251xfd_osc_1: mcp251xfd-spi0-1-osc { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <40000000>; -+ }; -+ }; -+ }; -+ fragment@7 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ mcp251xfd@1 { -+ compatible = "microchip,mcp251xfd"; -+ reg = <1>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mcp251xfd_pins_1>; -+ spi-max-frequency = <20000000>; -+ interrupt-parent = <&gpio>; -+ interrupts = <16 IRQ_TYPE_LEVEL_LOW>; -+ clocks = <&clk_mcp251xfd_osc_1>; -+ }; -+ }; -+ }; -+}; diff --git a/target/linux/bcm27xx/patches-5.15/950-0746-overlays-Add-drm-parameter-to-pitft35-resistive.patch b/target/linux/bcm27xx/patches-5.15/950-0746-overlays-Add-drm-parameter-to-pitft35-resistive.patch deleted file mode 100644 index 52f776d70..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0746-overlays-Add-drm-parameter-to-pitft35-resistive.patch +++ /dev/null @@ -1,38 +0,0 @@ -From a6747d9fad7d15345f7703e9f9d2916ea20a6edf Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 25 Feb 2022 09:53:56 +0000 -Subject: [PATCH] overlays: Add "drm" parameter to pitft35-resistive - -The "drm" parameter forces the use of the hx8357d DRM driver, when by -default the fb_hx8357d framebuffer driver will be used in preference. - -See: https://forums.raspberrypi.com/viewtopic.php?t=330088 - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/overlays/README | 4 ++++ - arch/arm/boot/dts/overlays/pitft35-resistive-overlay.dts | 1 + - 2 files changed, 5 insertions(+) - ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -2689,6 +2689,10 @@ Params: speed Display - - debug Debug output level {0-7} - -+ drm Force the use of the hx8357d DRM driver (by -+ default the fb_hx8357d framebuffer driver will -+ be used in preference if available) -+ - - Name: pps-gpio - Info: Configures the pps-gpio (pulse-per-second time signal via GPIO). ---- a/arch/arm/boot/dts/overlays/pitft35-resistive-overlay.dts -+++ b/arch/arm/boot/dts/overlays/pitft35-resistive-overlay.dts -@@ -115,5 +115,6 @@ - rotate = <&pitft>,"rotate:0"; - fps = <&pitft>,"fps:0"; - debug = <&pitft>,"debug:0"; -+ drm = <&pitft>,"compatible=adafruit,yx350hv15"; - }; - }; diff --git a/target/linux/bcm27xx/patches-5.15/950-0749-dtoverlays-Add-overlay-for-Omnivision-OV2311-image-s.patch b/target/linux/bcm27xx/patches-5.15/950-0749-dtoverlays-Add-overlay-for-Omnivision-OV2311-image-s.patch deleted file mode 100644 index c0ba49443..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0749-dtoverlays-Add-overlay-for-Omnivision-OV2311-image-s.patch +++ /dev/null @@ -1,147 +0,0 @@ -From f76b8590a1808ae27ce687b2ab5eedb3cd4b3149 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Fri, 25 Feb 2022 18:16:26 +0000 -Subject: [PATCH] dtoverlays: Add overlay for Omnivision OV2311 image - sensor - -Adds an overlay for the OV2311 1600x1300 monochrome global -shutter image sensor. - -Signed-off-by: Dave Stevenson ---- - arch/arm/boot/dts/overlays/Makefile | 1 + - arch/arm/boot/dts/overlays/README | 15 +++ - arch/arm/boot/dts/overlays/ov2311-overlay.dts | 93 +++++++++++++++++++ - 3 files changed, 109 insertions(+) - create mode 100644 arch/arm/boot/dts/overlays/ov2311-overlay.dts - ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -139,6 +139,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ - mmc.dtbo \ - mpu6050.dtbo \ - mz61581.dtbo \ -+ ov2311.dtbo \ - ov5647.dtbo \ - ov7251.dtbo \ - ov9281.dtbo \ ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -2421,6 +2421,21 @@ Params: speed Display - xohms Touchpanel sensitivity (X-plate resistance) - - -+Name: ov2311 -+Info: Omnivision OV2311 camera module. -+ Uses Unicam 1, which is the standard camera connector on most Pi -+ variants. -+Load: dtoverlay=ov2311,= -+Params: rotation Mounting rotation of the camera sensor (0 or -+ 180, default 0) -+ orientation Sensor orientation (0 = front, 1 = rear, -+ 2 = external, default external) -+ media-controller Configure use of Media Controller API for -+ configuring the sensor (default on) -+ cam0 Adopt the default configuration for CAM0 on a -+ Compute Module (CSI0, i2c_vc, and cam0_reg). -+ -+ - Name: ov5647 - Info: Omnivision OV5647 camera module. - Uses Unicam 1, which is the standard camera connector on most Pi ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/ov2311-overlay.dts -@@ -0,0 +1,93 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+// Definitions for OV2311 camera module on VC I2C bus -+/dts-v1/; -+/plugin/; -+ -+#include -+ -+/{ -+ compatible = "brcm,bcm2835"; -+ -+ i2c_frag: fragment@0 { -+ target = <&i2c_csi_dsi>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ ov2311: ov2311@60 { -+ compatible = "ovti,ov2311"; -+ reg = <0x60>; -+ status = "okay"; -+ -+ clocks = <&cam1_clk>; -+ clock-names = "xvclk"; -+ -+ avdd-supply = <&cam1_reg>; -+ dovdd-supply = <&cam_dummy_reg>; -+ dvdd-supply = <&cam_dummy_reg>; -+ -+ rotation = <0>; -+ orientation = <2>; -+ -+ port { -+ ov2311_0: endpoint { -+ remote-endpoint = <&csi1_ep>; -+ clock-lanes = <0>; -+ data-lanes = <1 2>; -+ link-frequencies = -+ /bits/ 64 <400000000>; -+ }; -+ }; -+ }; -+ }; -+ }; -+ -+ csi_frag: fragment@1 { -+ target = <&csi1>; -+ csi: __overlay__ { -+ status = "okay"; -+ brcm,media-controller; -+ -+ port { -+ csi1_ep: endpoint { -+ remote-endpoint = <&ov2311_0>; -+ data-lanes = <1 2>; -+ }; -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&i2c0if>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@3 { -+ target = <&i2c0mux>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ clk_frag: fragment@4 { -+ target = <&cam1_clk>; -+ __overlay__ { -+ status = "okay"; -+ clock-frequency = <24000000>; -+ }; -+ }; -+ -+ __overrides__ { -+ rotation = <&ov2311>,"rotation:0"; -+ orientation = <&ov2311>,"orientation:0"; -+ media-controller = <&csi>,"brcm,media-controller?"; -+ cam0 = <&i2c_frag>, "target:0=",<&i2c_vc>, -+ <&csi_frag>, "target:0=",<&csi0>, -+ <&clk_frag>, "target:0=",<&cam0_clk>, -+ <&ov2311>, "clocks:0=",<&cam0_clk>, -+ <&ov2311>, "avdd-supply:0=",<&cam0_reg>; -+ }; -+}; diff --git a/target/linux/bcm27xx/patches-5.15/950-0750-staging-vc-sm-cma-Avoid-log-spamming-on-Pi0-1-over-c.patch b/target/linux/bcm27xx/patches-5.15/950-0750-staging-vc-sm-cma-Avoid-log-spamming-on-Pi0-1-over-c.patch deleted file mode 100644 index 0258ae34e..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0750-staging-vc-sm-cma-Avoid-log-spamming-on-Pi0-1-over-c.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 79dd0145cb8220a5be0007350a7501056378e720 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Wed, 2 Mar 2022 17:23:16 +0000 -Subject: [PATCH] staging/vc-sm-cma: Avoid log spamming on Pi0/1 over - cache alias. - -Pi 0/1 use the 0x80000000 cache alias as the ARM also sees the world -through the VPU L2 cache. -vc-sm-cma was trying to ensure it was in an uncached alias (0xc), and -complaining on every allocation if it weren't. Reduce this logging. - -Signed-off-by: Dave Stevenson ---- - drivers/staging/vc04_services/vc-sm-cma/vc_sm.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - ---- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c -+++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c -@@ -720,6 +720,7 @@ vc_sm_cma_import_dmabuf_internal(struct - struct dma_buf_attachment *attach = NULL; - struct sg_table *sgt = NULL; - dma_addr_t dma_addr; -+ u32 cache_alias; - int ret = 0; - int status; - -@@ -762,9 +763,13 @@ vc_sm_cma_import_dmabuf_internal(struct - import.type = VC_SM_ALLOC_NON_CACHED; - dma_addr = sg_dma_address(sgt->sgl); - import.addr = (u32)dma_addr; -- if ((import.addr & 0xC0000000) != 0xC0000000) { -+ cache_alias = import.addr & 0xC0000000; -+ if (cache_alias != 0xC0000000 && cache_alias != 0x80000000) { - pr_err("%s: Expecting an uncached alias for dma_addr %pad\n", - __func__, &dma_addr); -+ /* Note that this assumes we're on >= Pi2, but it implies a -+ * DT configuration error. -+ */ - import.addr |= 0xC0000000; - } - import.size = sg_dma_len(sgt->sgl); diff --git a/target/linux/bcm27xx/patches-5.15/950-0753-drm-vc4-Fix-out-of-order-frames-during-asynchronous-.patch b/target/linux/bcm27xx/patches-5.15/950-0753-drm-vc4-Fix-out-of-order-frames-during-asynchronous-.patch deleted file mode 100644 index 1f765aeb0..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0753-drm-vc4-Fix-out-of-order-frames-during-asynchronous-.patch +++ /dev/null @@ -1,97 +0,0 @@ -From a0bc59127231cbea506651c362d4836a0ff5591f Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Wed, 8 Sep 2021 21:12:26 +0200 -Subject: [PATCH] drm/vc4: Fix out of order frames during asynchronous - page flips - -When doing an asynchronous page flip (PAGE_FLIP ioctl with the -DRM_MODE_PAGE_FLIP_ASYNC flag set), the current code waits for the -possible GPU buffer being rendered through a call to -vc4_queue_seqno_cb(). - -On the BCM2835-37, the GPU driver is part of the vc4 driver and that -function is defined in vc4_gem.c to wait for the buffer to be rendered, -and once it's done, call a callback. - -However, on the BCM2711 used on the RaspberryPi4, the GPU driver is -separate (v3d) and that function won't do anything. This was working -because we were going into a path, due to uninitialized variables, that -was always scheduling the callback. - -However, we were never actually waiting for the buffer to be rendered -which was resulting in frames being displayed out of order. - -The generic API to signal those kind of completion in the kernel are the -DMA fences, and fortunately the v3d drivers supports them and signal -when its job is done. That API also provides an equivalent function that -allows to have a callback being executed when the fence is signalled as -done. - -Let's change our driver a bit to rely on the previous function for the -older SoCs, and on DMA fences for the BCM2711. - -Signed-off-by: Maxime Ripard ---- - drivers/gpu/drm/vc4/vc4_crtc.c | 37 ++++++++++++++++++++++++++++++++-- - 1 file changed, 35 insertions(+), 2 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_crtc.c -+++ b/drivers/gpu/drm/vc4/vc4_crtc.c -@@ -797,6 +797,7 @@ struct vc4_async_flip_state { - struct drm_pending_vblank_event *event; - - struct vc4_seqno_cb cb; -+ struct dma_fence_cb fence_cb; - }; - - /* Called when the V3D execution for the BO being flipped to is done, so that -@@ -842,6 +843,39 @@ vc4_async_page_flip_complete(struct vc4_ - kfree(flip_state); - } - -+static void vc4_async_page_flip_fence_complete(struct dma_fence *fence, -+ struct dma_fence_cb *cb) -+{ -+ struct vc4_async_flip_state *flip_state = -+ container_of(cb, struct vc4_async_flip_state, fence_cb); -+ -+ vc4_async_page_flip_complete(&flip_state->cb); -+ dma_fence_put(fence); -+} -+ -+static int vc4_async_set_fence_cb(struct drm_device *dev, -+ struct vc4_async_flip_state *flip_state) -+{ -+ struct drm_framebuffer *fb = flip_state->fb; -+ struct drm_gem_cma_object *cma_bo = drm_fb_cma_get_gem_obj(fb, 0); -+ struct vc4_dev *vc4 = to_vc4_dev(dev); -+ struct dma_fence *fence; -+ -+ if (!vc4->hvs->hvs5) { -+ struct vc4_bo *bo = to_vc4_bo(&cma_bo->base); -+ -+ return vc4_queue_seqno_cb(dev, &flip_state->cb, bo->seqno, -+ vc4_async_page_flip_complete); -+ } -+ -+ fence = dma_fence_get(dma_resv_excl_fence(cma_bo->base.resv)); -+ if (dma_fence_add_callback(fence, &flip_state->fence_cb, -+ vc4_async_page_flip_fence_complete)) -+ vc4_async_page_flip_fence_complete(fence, &flip_state->fence_cb); -+ -+ return 0; -+} -+ - /* Implements async (non-vblank-synced) page flips. - * - * The page flip ioctl needs to return immediately, so we grab the -@@ -902,8 +936,7 @@ static int vc4_async_page_flip(struct dr - */ - drm_atomic_set_fb_for_plane(plane->state, fb); - -- vc4_queue_seqno_cb(dev, &flip_state->cb, bo->seqno, -- vc4_async_page_flip_complete); -+ vc4_async_set_fence_cb(dev, flip_state); - - /* Driver takes ownership of state on successful async commit. */ - return 0; diff --git a/target/linux/bcm27xx/patches-5.15/950-0754-staging-vc04_services-codec-Add-support-for-V4L2_PIX.patch b/target/linux/bcm27xx/patches-5.15/950-0754-staging-vc04_services-codec-Add-support-for-V4L2_PIX.patch deleted file mode 100644 index 59ff0888b..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0754-staging-vc04_services-codec-Add-support-for-V4L2_PIX.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 64bab887e1861c3db19a37cfab41a45e296e2cc1 Mon Sep 17 00:00:00 2001 -From: David Plowman -Date: Mon, 7 Mar 2022 10:00:33 +0000 -Subject: [PATCH] staging: vc04_services: codec: Add support for - V4L2_PIX_FMT_RGBA32 format - -We already support V4L2_PIX_FMT_BGR32 which is the same thing with red -and blue swapped, so it makes sense to include this variant as well. - -Signed-off-by: David Plowman ---- - .../vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c | 7 +++++++ - 1 file changed, 7 insertions(+) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -241,6 +241,13 @@ static const struct bcm2835_codec_fmt su - .mmal_fmt = MMAL_ENCODING_BGRA, - .size_multiplier_x2 = 2, - }, { -+ .fourcc = V4L2_PIX_FMT_RGBA32, -+ .depth = 32, -+ .bytesperline_align = { 32, 32, 32, 32 }, -+ .flags = 0, -+ .mmal_fmt = MMAL_ENCODING_RGBA, -+ .size_multiplier_x2 = 2, -+ }, { - /* Bayer formats */ - /* 8 bit */ - .fourcc = V4L2_PIX_FMT_SRGGB8, diff --git a/target/linux/bcm27xx/patches-5.15/950-0756-drm-vc4-kms-Store-channel-in-local-variable.patch b/target/linux/bcm27xx/patches-5.15/950-0756-drm-vc4-kms-Store-channel-in-local-variable.patch deleted file mode 100644 index e15e0a713..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0756-drm-vc4-kms-Store-channel-in-local-variable.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 753f22ccb26a9085c987700206bdf6724be9b547 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Fri, 4 Mar 2022 15:58:51 +0100 -Subject: [PATCH] drm/vc4: kms: Store channel in local variable - -We use the channel from our vc4_crtc_state structure in multiple places, -let's store it in a local variable to make it cleaner. - -Signed-off-by: Maxime Ripard ---- - drivers/gpu/drm/vc4/vc4_kms.c | 15 ++++++++------- - 1 file changed, 8 insertions(+), 7 deletions(-) - ---- a/drivers/gpu/drm/vc4/vc4_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_kms.c -@@ -286,13 +286,14 @@ static void vc5_hvs_pv_muxing_commit(str - for_each_new_crtc_in_state(state, crtc, crtc_state, i) { - struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc_state); - struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); -+ unsigned int channel = vc4_state->assigned_channel; - - if (!vc4_state->update_muxing) - continue; - - switch (vc4_crtc->data->hvs_output) { - case 2: -- mux = (vc4_state->assigned_channel == 2) ? 0 : 1; -+ mux = (channel == 2) ? 0 : 1; - reg = HVS_READ(SCALER_DISPECTRL); - HVS_WRITE(SCALER_DISPECTRL, - (reg & ~SCALER_DISPECTRL_DSP2_MUX_MASK) | -@@ -300,10 +301,10 @@ static void vc5_hvs_pv_muxing_commit(str - break; - - case 3: -- if (vc4_state->assigned_channel == VC4_HVS_CHANNEL_DISABLED) -+ if (channel == VC4_HVS_CHANNEL_DISABLED) - mux = 3; - else -- mux = vc4_state->assigned_channel; -+ mux = channel; - - reg = HVS_READ(SCALER_DISPCTRL); - HVS_WRITE(SCALER_DISPCTRL, -@@ -312,10 +313,10 @@ static void vc5_hvs_pv_muxing_commit(str - break; - - case 4: -- if (vc4_state->assigned_channel == VC4_HVS_CHANNEL_DISABLED) -+ if (channel == VC4_HVS_CHANNEL_DISABLED) - mux = 3; - else -- mux = vc4_state->assigned_channel; -+ mux = channel; - - reg = HVS_READ(SCALER_DISPEOLN); - HVS_WRITE(SCALER_DISPEOLN, -@@ -325,10 +326,10 @@ static void vc5_hvs_pv_muxing_commit(str - break; - - case 5: -- if (vc4_state->assigned_channel == VC4_HVS_CHANNEL_DISABLED) -+ if (channel == VC4_HVS_CHANNEL_DISABLED) - mux = 3; - else -- mux = vc4_state->assigned_channel; -+ mux = channel; - - reg = HVS_READ(SCALER_DISPDITHER); - HVS_WRITE(SCALER_DISPDITHER, diff --git a/target/linux/bcm27xx/patches-5.15/950-0757-drm-vc4-kms-Warn-if-we-have-an-incompatible-muxing-s.patch b/target/linux/bcm27xx/patches-5.15/950-0757-drm-vc4-kms-Warn-if-we-have-an-incompatible-muxing-s.patch deleted file mode 100644 index 4c02efe88..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0757-drm-vc4-kms-Warn-if-we-have-an-incompatible-muxing-s.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 87157f42cd40d9302ad2ebae582768b52c46c8e0 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Fri, 4 Mar 2022 15:59:08 +0100 -Subject: [PATCH] drm/vc4: kms: Warn if we have an incompatible muxing - setup - -The documentation explicitly states we must prevent the output -2 and 3 from feeding from the same HVS channel. - -Let's add a warning to make some noise if we ever find ourselves in such -a case. - -Signed-off-by: Maxime Ripard ---- - drivers/gpu/drm/vc4/vc4_kms.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/drivers/gpu/drm/vc4/vc4_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_kms.c -@@ -293,6 +293,9 @@ static void vc5_hvs_pv_muxing_commit(str - - switch (vc4_crtc->data->hvs_output) { - case 2: -+ WARN_ON(VC4_GET_FIELD(HVS_READ(SCALER_DISPCTRL), -+ SCALER_DISPCTRL_DSP3_MUX) == channel); -+ - mux = (channel == 2) ? 0 : 1; - reg = HVS_READ(SCALER_DISPECTRL); - HVS_WRITE(SCALER_DISPECTRL, diff --git a/target/linux/bcm27xx/patches-5.15/950-0758-drm-vc4-kms-Improve-logging.patch b/target/linux/bcm27xx/patches-5.15/950-0758-drm-vc4-kms-Improve-logging.patch deleted file mode 100644 index d6ff83813..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0758-drm-vc4-kms-Improve-logging.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 0fc2455e0b6cf188c529915de2627bdfb3e5ff01 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Fri, 4 Mar 2022 15:59:40 +0100 -Subject: [PATCH] drm/vc4: kms: Improve logging - -When debugging, finding out what muxing decisions were made and what the -actual core clock rate is is always useful, so let's add some more -messages. - -Signed-off-by: Maxime Ripard ---- - drivers/gpu/drm/vc4/vc4_kms.c | 20 +++++++++++++++++++- - 1 file changed, 19 insertions(+), 1 deletion(-) - ---- a/drivers/gpu/drm/vc4/vc4_kms.c -+++ b/drivers/gpu/drm/vc4/vc4_kms.c -@@ -447,6 +447,9 @@ static void vc4_atomic_commit_tail(struc - - /* And drop the temporary request */ - clk_request_done(core_req); -+ -+ drm_dbg(dev, "Core clock actual rate: %lu Hz\n", -+ clk_get_rate(hvs->core_clk)); - } - } - -@@ -827,9 +830,18 @@ static int vc4_pv_muxing_atomic_check(st - if (vc4->firmware_kms) - continue; - -+ drm_dbg(dev, "%s: Trying to find a channel.\n", crtc->name); -+ - /* Nothing to do here, let's skip it */ -- if (old_crtc_state->enable == new_crtc_state->enable) -+ if (old_crtc_state->enable == new_crtc_state->enable) { -+ if (new_crtc_state->enable) -+ drm_dbg(dev, "%s: Already enabled, reusing channel %d.\n", -+ crtc->name, new_vc4_crtc_state->assigned_channel); -+ else -+ drm_dbg(dev, "%s: Disabled, ignoring.\n", crtc->name); -+ - continue; -+ } - - /* Muxing will need to be modified, mark it as such */ - new_vc4_crtc_state->update_muxing = true; -@@ -837,6 +849,10 @@ static int vc4_pv_muxing_atomic_check(st - /* If we're disabling our CRTC, we put back our channel */ - if (!new_crtc_state->enable) { - channel = old_vc4_crtc_state->assigned_channel; -+ -+ drm_dbg(dev, "%s: Disabling, Freeing channel %d\n", -+ crtc->name, channel); -+ - hvs_new_state->fifo_state[channel].in_use = false; - new_vc4_crtc_state->assigned_channel = VC4_HVS_CHANNEL_DISABLED; - continue; -@@ -871,6 +887,8 @@ static int vc4_pv_muxing_atomic_check(st - return -EINVAL; - - channel = ffs(matching_channels) - 1; -+ -+ drm_dbg(dev, "Assigned HVS channel %d to CRTC %s\n", channel, crtc->name); - new_vc4_crtc_state->assigned_channel = channel; - unassigned_channels &= ~BIT(channel); - hvs_new_state->fifo_state[channel].in_use = true; diff --git a/target/linux/bcm27xx/patches-5.15/950-0761-ARM-dts-bcm2711-rpi-ds-Disable-the-BCM2835-STC.patch b/target/linux/bcm27xx/patches-5.15/950-0761-ARM-dts-bcm2711-rpi-ds-Disable-the-BCM2835-STC.patch deleted file mode 100644 index efe7acafd..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0761-ARM-dts-bcm2711-rpi-ds-Disable-the-BCM2835-STC.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 296f6ab3a619b47b6f8d4ac42ec704a700df08b2 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 8 Mar 2022 12:47:49 +0000 -Subject: [PATCH] ARM: dts: bcm2711-rpi-ds: Disable the BCM2835 STC - -Although BCM2711 still includes the old BCM2835 system timer, the newer -per-core local timers are preferred because they are more efficient to -access and can generate core-specific interrupts. Make the usage clear -by disabling the driver for the old STC. - -See: https://github.com/raspberrypi/firmware/issues/1702 - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/bcm2711-rpi-ds.dtsi | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/arch/arm/boot/dts/bcm2711-rpi-ds.dtsi -+++ b/arch/arm/boot/dts/bcm2711-rpi-ds.dtsi -@@ -203,3 +203,7 @@ - &dvp { - status = "disabled"; - }; -+ -+&system_timer { -+ status = "disabled"; -+}; diff --git a/target/linux/bcm27xx/patches-5.15/950-0762-drm-bridge-Introduce-pre_enable_upstream_first-to-al.patch b/target/linux/bcm27xx/patches-5.15/950-0762-drm-bridge-Introduce-pre_enable_upstream_first-to-al.patch deleted file mode 100644 index 6e3dd5778..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0762-drm-bridge-Introduce-pre_enable_upstream_first-to-al.patch +++ /dev/null @@ -1,308 +0,0 @@ -From 2c8b6954e6168d56cc6d35f5f6d075c826a9b8e1 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Thu, 16 Dec 2021 15:25:35 +0000 -Subject: [PATCH] drm/bridge: Introduce pre_enable_upstream_first to - alter bridge init order - -DSI sink devices typically want the DSI host powered up and configured -before they are powered up. pre_enable is the place this would normally -happen, but they are called in reverse order from panel/connector towards -the encoder, which is the "wrong" order. - -Add a new flag pre_enable_upstream_first that any bridge can set -to swap the order of pre_enable (and post_disable) for that and the -immediately upstream bridge. -Should the immediately upstream bridge also set the -pre_enable_upstream_first flag, the bridge upstream of that will be called -before either of those which requested pre_enable_upstream_first. - -eg: -- Panel -- Bridge 1 -- Bridge 2 pre_enable_upstream_first -- Bridge 3 -- Bridge 4 pre_enable_upstream_first -- Bridge 5 pre_enable_upstream_first -- Bridge 6 -- Encoder -Would result in pre_enable's being called as Panel, Bridge 1, Bridge 3, -Bridge 2, Bridge 6, Bridge 5, Bridge 4, Encoder. - -Signed-off-by: Dave Stevenson ---- - drivers/gpu/drm/drm_bridge.c | 177 +++++++++++++++++++++++++---------- - include/drm/drm_bridge.h | 8 ++ - 2 files changed, 137 insertions(+), 48 deletions(-) - ---- a/drivers/gpu/drm/drm_bridge.c -+++ b/drivers/gpu/drm/drm_bridge.c -@@ -462,20 +462,15 @@ EXPORT_SYMBOL(drm_bridge_chain_disable); - * encoder chain, starting from the first bridge to the last. These are called - * after completing the encoder's prepare op. - * -+ * If a bridge sets @pre_enable_upstream_first, then the @post_disable for that -+ * bridge will be called before the previous one to reverse the @pre_enable -+ * calling direction. -+ * - * Note: the bridge passed should be the one closest to the encoder - */ - void drm_bridge_chain_post_disable(struct drm_bridge *bridge) - { -- struct drm_encoder *encoder; -- -- if (!bridge) -- return; -- -- encoder = bridge->encoder; -- list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) { -- if (bridge->funcs->post_disable) -- bridge->funcs->post_disable(bridge); -- } -+ drm_atomic_bridge_chain_post_disable(bridge, NULL); - } - EXPORT_SYMBOL(drm_bridge_chain_post_disable); - -@@ -517,24 +512,14 @@ EXPORT_SYMBOL(drm_bridge_chain_mode_set) - * chain, starting from the last bridge to the first. These are called - * before calling the encoder's commit op. - * -+ * If a bridge sets @pre_enable_upstream_first, then the @pre_enable for the -+ * previous bridge will be called before @pre_enable of this bridge. -+ * - * Note: the bridge passed should be the one closest to the encoder - */ - void drm_bridge_chain_pre_enable(struct drm_bridge *bridge) - { -- struct drm_encoder *encoder; -- struct drm_bridge *iter; -- -- if (!bridge) -- return; -- -- encoder = bridge->encoder; -- list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) { -- if (iter->funcs->pre_enable) -- iter->funcs->pre_enable(iter); -- -- if (iter == bridge) -- break; -- } -+ drm_atomic_bridge_chain_pre_enable(bridge, NULL); - } - EXPORT_SYMBOL(drm_bridge_chain_pre_enable); - -@@ -606,6 +591,25 @@ void drm_atomic_bridge_chain_disable(str - } - EXPORT_SYMBOL(drm_atomic_bridge_chain_disable); - -+static void drm_atomic_bridge_call_post_disable(struct drm_bridge *bridge, -+ struct drm_atomic_state *old_state) -+{ -+ if (old_state && bridge->funcs->atomic_post_disable) { -+ struct drm_bridge_state *old_bridge_state; -+ -+ old_bridge_state = -+ drm_atomic_get_old_bridge_state(old_state, -+ bridge); -+ if (WARN_ON(!old_bridge_state)) -+ return; -+ -+ bridge->funcs->atomic_post_disable(bridge, -+ old_bridge_state); -+ } else if (bridge->funcs->post_disable) { -+ bridge->funcs->post_disable(bridge); -+ } -+} -+ - /** - * drm_atomic_bridge_chain_post_disable - cleans up after disabling all bridges - * in the encoder chain -@@ -616,6 +620,9 @@ EXPORT_SYMBOL(drm_atomic_bridge_chain_di - * &drm_bridge_funcs.post_disable) op for all the bridges in the encoder chain, - * starting from the first bridge to the last. These are called after completing - * &drm_encoder_helper_funcs.atomic_disable -+ * If a bridge sets @pre_enable_upstream_first, then the @post_disable for that -+ * bridge will be called before the previous one to reverse the @pre_enable -+ * calling direction. - * - * Note: the bridge passed should be the one closest to the encoder - */ -@@ -623,30 +630,75 @@ void drm_atomic_bridge_chain_post_disabl - struct drm_atomic_state *old_state) - { - struct drm_encoder *encoder; -+ struct drm_bridge *next, *limit; - - if (!bridge) - return; - - encoder = bridge->encoder; -+ - list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) { -- if (bridge->funcs->atomic_post_disable) { -- struct drm_bridge_state *old_bridge_state; -+ limit = NULL; - -- old_bridge_state = -- drm_atomic_get_old_bridge_state(old_state, -- bridge); -- if (WARN_ON(!old_bridge_state)) -- return; -+ if (!list_is_last(&bridge->chain_node, &encoder->bridge_chain)) { -+ next = list_next_entry(bridge, chain_node); - -- bridge->funcs->atomic_post_disable(bridge, -- old_bridge_state); -- } else if (bridge->funcs->post_disable) { -- bridge->funcs->post_disable(bridge); -+ if (next->pre_enable_upstream_first) { -+ /* Downstream bridge had requested that upstream -+ * was enabled first, so disabled last -+ */ -+ limit = next; -+ -+ /* Find the next bridge that has NOT requested -+ * upstream to be enabled first / disabled last -+ */ -+ list_for_each_entry_from(next, &encoder->bridge_chain, -+ chain_node) { -+ if (next->pre_enable_upstream_first) { -+ next = list_prev_entry(next, chain_node); -+ limit = next; -+ break; -+ } -+ } -+ -+ /* Call these bridges in reverse order */ -+ list_for_each_entry_from_reverse(next, &encoder->bridge_chain, -+ chain_node) { -+ if (next == bridge) -+ break; -+ -+ drm_atomic_bridge_call_post_disable(next, -+ old_state); -+ } -+ } - } -+ -+ drm_atomic_bridge_call_post_disable(bridge, old_state); -+ -+ if (limit) -+ bridge = limit; - } - } - EXPORT_SYMBOL(drm_atomic_bridge_chain_post_disable); - -+static void drm_atomic_bridge_call_pre_enable(struct drm_bridge *bridge, -+ struct drm_atomic_state *old_state) -+{ -+ if (old_state && bridge->funcs->atomic_pre_enable) { -+ struct drm_bridge_state *old_bridge_state; -+ -+ old_bridge_state = -+ drm_atomic_get_old_bridge_state(old_state, -+ bridge); -+ if (WARN_ON(!old_bridge_state)) -+ return; -+ -+ bridge->funcs->atomic_pre_enable(bridge, old_bridge_state); -+ } else if (bridge->funcs->pre_enable) { -+ bridge->funcs->pre_enable(bridge); -+ } -+} -+ - /** - * drm_atomic_bridge_chain_pre_enable - prepares for enabling all bridges in - * the encoder chain -@@ -658,33 +710,62 @@ EXPORT_SYMBOL(drm_atomic_bridge_chain_po - * starting from the last bridge to the first. These are called before calling - * &drm_encoder_helper_funcs.atomic_enable - * -+ * If a bridge sets @pre_enable_upstream_first, then the pre_enable for the -+ * upstream bridge will be called before pre_enable of this bridge. -+ * - * Note: the bridge passed should be the one closest to the encoder - */ - void drm_atomic_bridge_chain_pre_enable(struct drm_bridge *bridge, - struct drm_atomic_state *old_state) - { - struct drm_encoder *encoder; -- struct drm_bridge *iter; -+ struct drm_bridge *iter, *next, *limit; - - if (!bridge) - return; - - encoder = bridge->encoder; -- list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) { -- if (iter->funcs->atomic_pre_enable) { -- struct drm_bridge_state *old_bridge_state; - -- old_bridge_state = -- drm_atomic_get_old_bridge_state(old_state, -- iter); -- if (WARN_ON(!old_bridge_state)) -- return; -+ list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) { -+ if (iter->pre_enable_upstream_first) { -+ next = iter; -+ limit = bridge; -+ list_for_each_entry_from_reverse(next, -+ &encoder->bridge_chain, -+ chain_node) { -+ if (next == bridge) -+ break; -+ -+ if (!next->pre_enable_upstream_first) { -+ /* Found first bridge that does NOT -+ * request upstream to be enabled first -+ */ -+ limit = list_prev_entry(next, chain_node); -+ break; -+ } -+ } -+ -+ list_for_each_entry_from(next, &encoder->bridge_chain, chain_node) { -+ /* Call requested upstream bridge pre_enable -+ * in order. -+ */ -+ if (next == iter) -+ /* At the first bridgge to request upstream -+ * bridges called first. -+ */ -+ break; - -- iter->funcs->atomic_pre_enable(iter, old_bridge_state); -- } else if (iter->funcs->pre_enable) { -- iter->funcs->pre_enable(iter); -+ drm_atomic_bridge_call_pre_enable(next, old_state); -+ } - } - -+ drm_atomic_bridge_call_pre_enable(iter, old_state); -+ -+ if (iter->pre_enable_upstream_first) -+ /* Jump all bridges that we have already pre_enabled -+ */ -+ iter = limit; -+ - if (iter == bridge) - break; - } ---- a/include/drm/drm_bridge.h -+++ b/include/drm/drm_bridge.h -@@ -762,6 +762,14 @@ struct drm_bridge { - */ - bool interlace_allowed; - /** -+ * @pre_enable_upstream_first: The bridge requires that the upstream -+ * bridge @pre_enable function is called before its @pre_enable, -+ * and conversely for post_disable. This is most frequently a -+ * requirement for DSI devices which need the host to be initialised -+ * before the peripheral. -+ */ -+ bool pre_enable_upstream_first; -+ /** - * @ddc: Associated I2C adapter for DDC access, if any. - */ - struct i2c_adapter *ddc; diff --git a/target/linux/bcm27xx/patches-5.15/950-0763-drm-panel-Add-prepare_upstream_first-flag-to-drm_pan.patch b/target/linux/bcm27xx/patches-5.15/950-0763-drm-panel-Add-prepare_upstream_first-flag-to-drm_pan.patch deleted file mode 100644 index 789431ce5..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0763-drm-panel-Add-prepare_upstream_first-flag-to-drm_pan.patch +++ /dev/null @@ -1,48 +0,0 @@ -From b5a2faf6deb6e7accec2c121840a72bdf6e97b4c Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Wed, 23 Feb 2022 15:36:56 +0000 -Subject: [PATCH] drm/panel: Add prepare_upstream_first flag to - drm_panel - -Mapping to the drm_bridge flag pre_enable_upstream_first, -add a new flag prepare_upstream_first to drm_panel to allow -the panel driver to request that the upstream bridge should -be pre_enabled before the panel prepare. - -Signed-off-by: Dave Stevenson ---- - drivers/gpu/drm/bridge/panel.c | 3 +++ - include/drm/drm_panel.h | 10 ++++++++++ - 2 files changed, 13 insertions(+) - ---- a/drivers/gpu/drm/bridge/panel.c -+++ b/drivers/gpu/drm/bridge/panel.c -@@ -226,6 +226,9 @@ struct drm_bridge *drm_panel_bridge_add_ - panel_bridge->bridge.ops = DRM_BRIDGE_OP_MODES; - panel_bridge->bridge.type = connector_type; - -+ panel_bridge->bridge.pre_enable_upstream_first = -+ panel->prepare_upstream_first; -+ - drm_bridge_add(&panel_bridge->bridge); - - return &panel_bridge->bridge; ---- a/include/drm/drm_panel.h -+++ b/include/drm/drm_panel.h -@@ -179,6 +179,16 @@ struct drm_panel { - * Panel entry in registry. - */ - struct list_head list; -+ -+ /** -+ * @prepare_upstream_first: -+ * -+ * The upstream controller should be prepared first, before the prepare -+ * for the panel is called. This is largely required for DSI panels -+ * where the DSI host controller should be initialised to LP-11 before -+ * the panel is powered up. -+ */ -+ bool prepare_upstream_first; - }; - - void drm_panel_init(struct drm_panel *panel, struct device *dev, diff --git a/target/linux/bcm27xx/patches-5.15/950-0766-bcm2835-codec-dev-video31-as-interface-to-image_enco.patch b/target/linux/bcm27xx/patches-5.15/950-0766-bcm2835-codec-dev-video31-as-interface-to-image_enco.patch deleted file mode 100644 index fab3445af..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0766-bcm2835-codec-dev-video31-as-interface-to-image_enco.patch +++ /dev/null @@ -1,799 +0,0 @@ -From edd6ba8103e315dea54c1f1bdbf0562590e0acd8 Mon Sep 17 00:00:00 2001 -From: Maxim Devaev -Date: Thu, 3 Mar 2022 23:06:15 +0300 -Subject: [PATCH] bcm2835-codec: /dev/video31 as interface to - image_encode JPEG encoder - -Signed-off-by: Maxim Devaev ---- - .../bcm2835-codec/bcm2835-v4l2-codec.c | 246 ++++++++++++------ - .../vchiq-mmal/mmal-parameters.h | 2 + - 2 files changed, 165 insertions(+), 83 deletions(-) - ---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c -@@ -62,6 +62,10 @@ static int deinterlace_video_nr = 18; - module_param(deinterlace_video_nr, int, 0644); - MODULE_PARM_DESC(deinterlace_video_nr, "deinterlace video device number"); - -+static int encode_image_nr = 31; -+module_param(encode_image_nr, int, 0644); -+MODULE_PARM_DESC(encode_image_nr, "encoder image device number"); -+ - /* - * Workaround for GStreamer v4l2convert component not considering Bayer formats - * as raw, and therefore not considering a V4L2 device that supports them as -@@ -88,6 +92,7 @@ enum bcm2835_codec_role { - ENCODE, - ISP, - DEINTERLACE, -+ ENCODE_IMAGE, - NUM_ROLES - }; - -@@ -96,6 +101,7 @@ static const char * const roles[] = { - "encode", - "isp", - "image_fx", -+ "encode_image", - }; - - static const char * const components[] = { -@@ -103,6 +109,7 @@ static const char * const components[] = - "ril.video_encode", - "ril.isp", - "ril.image_fx", -+ "ril.image_encode", - }; - - /* Timeout for stop_streaming to allow all buffers to return */ -@@ -136,6 +143,8 @@ static const char * const components[] = - */ - #define DEF_COMP_BUF_SIZE_GREATER_720P (768 << 10) - #define DEF_COMP_BUF_SIZE_720P_OR_LESS (512 << 10) -+/* JPEG image can be very large. For paranoid reasons 4MB is used */ -+#define DEF_COMP_BUF_SIZE_JPEG (4096 << 10) - - /* Flags that indicate a format can be used for capture/output */ - #define MEM2MEM_CAPTURE BIT(0) -@@ -158,63 +167,63 @@ static const struct bcm2835_codec_fmt su - /* YUV formats */ - .fourcc = V4L2_PIX_FMT_YUV420, - .depth = 8, -- .bytesperline_align = { 32, 64, 64, 32 }, -+ .bytesperline_align = { 32, 64, 64, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_I420, - .size_multiplier_x2 = 3, - }, { - .fourcc = V4L2_PIX_FMT_YVU420, - .depth = 8, -- .bytesperline_align = { 32, 64, 64, 32 }, -+ .bytesperline_align = { 32, 64, 64, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_YV12, - .size_multiplier_x2 = 3, - }, { - .fourcc = V4L2_PIX_FMT_NV12, - .depth = 8, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_NV12, - .size_multiplier_x2 = 3, - }, { - .fourcc = V4L2_PIX_FMT_NV21, - .depth = 8, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_NV21, - .size_multiplier_x2 = 3, - }, { - .fourcc = V4L2_PIX_FMT_RGB565, - .depth = 16, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_RGB16, - .size_multiplier_x2 = 2, - }, { - .fourcc = V4L2_PIX_FMT_YUYV, - .depth = 16, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_YUYV, - .size_multiplier_x2 = 2, - }, { - .fourcc = V4L2_PIX_FMT_UYVY, - .depth = 16, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_UYVY, - .size_multiplier_x2 = 2, - }, { - .fourcc = V4L2_PIX_FMT_YVYU, - .depth = 16, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_YVYU, - .size_multiplier_x2 = 2, - }, { - .fourcc = V4L2_PIX_FMT_VYUY, - .depth = 16, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_VYUY, - .size_multiplier_x2 = 2, -@@ -222,21 +231,21 @@ static const struct bcm2835_codec_fmt su - /* RGB formats */ - .fourcc = V4L2_PIX_FMT_RGB24, - .depth = 24, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_RGB24, - .size_multiplier_x2 = 2, - }, { - .fourcc = V4L2_PIX_FMT_BGR24, - .depth = 24, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BGR24, - .size_multiplier_x2 = 2, - }, { - .fourcc = V4L2_PIX_FMT_BGR32, - .depth = 32, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BGRA, - .size_multiplier_x2 = 2, -@@ -252,7 +261,7 @@ static const struct bcm2835_codec_fmt su - /* 8 bit */ - .fourcc = V4L2_PIX_FMT_SRGGB8, - .depth = 8, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB8, - .size_multiplier_x2 = 2, -@@ -260,7 +269,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SBGGR8, - .depth = 8, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR8, - .size_multiplier_x2 = 2, -@@ -268,7 +277,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SGRBG8, - .depth = 8, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG8, - .size_multiplier_x2 = 2, -@@ -276,7 +285,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SGBRG8, - .depth = 8, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG8, - .size_multiplier_x2 = 2, -@@ -285,7 +294,7 @@ static const struct bcm2835_codec_fmt su - /* 10 bit */ - .fourcc = V4L2_PIX_FMT_SRGGB10P, - .depth = 10, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB10P, - .size_multiplier_x2 = 2, -@@ -293,7 +302,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SBGGR10P, - .depth = 10, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR10P, - .size_multiplier_x2 = 2, -@@ -301,7 +310,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SGRBG10P, - .depth = 10, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG10P, - .size_multiplier_x2 = 2, -@@ -309,7 +318,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SGBRG10P, - .depth = 10, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG10P, - .size_multiplier_x2 = 2, -@@ -318,7 +327,7 @@ static const struct bcm2835_codec_fmt su - /* 12 bit */ - .fourcc = V4L2_PIX_FMT_SRGGB12P, - .depth = 12, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB12P, - .size_multiplier_x2 = 2, -@@ -326,7 +335,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SBGGR12P, - .depth = 12, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR12P, - .size_multiplier_x2 = 2, -@@ -334,7 +343,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SGRBG12P, - .depth = 12, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG12P, - .size_multiplier_x2 = 2, -@@ -342,7 +351,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SGBRG12P, - .depth = 12, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG12P, - .size_multiplier_x2 = 2, -@@ -351,7 +360,7 @@ static const struct bcm2835_codec_fmt su - /* 14 bit */ - .fourcc = V4L2_PIX_FMT_SRGGB14P, - .depth = 14, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB14P, - .size_multiplier_x2 = 2, -@@ -359,7 +368,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SBGGR14P, - .depth = 14, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR14P, - .size_multiplier_x2 = 2, -@@ -368,7 +377,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SGRBG14P, - .depth = 14, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG14P, - .size_multiplier_x2 = 2, -@@ -376,7 +385,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SGBRG14P, - .depth = 14, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG14P, - .size_multiplier_x2 = 2, -@@ -385,7 +394,7 @@ static const struct bcm2835_codec_fmt su - /* 16 bit */ - .fourcc = V4L2_PIX_FMT_SRGGB16, - .depth = 16, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB16, - .size_multiplier_x2 = 2, -@@ -393,7 +402,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SBGGR16, - .depth = 16, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR16, - .size_multiplier_x2 = 2, -@@ -401,7 +410,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SGRBG16, - .depth = 16, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG16, - .size_multiplier_x2 = 2, -@@ -409,7 +418,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SGBRG16, - .depth = 16, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG16, - .size_multiplier_x2 = 2, -@@ -419,7 +428,7 @@ static const struct bcm2835_codec_fmt su - /* 10 bit */ - .fourcc = V4L2_PIX_FMT_SRGGB10, - .depth = 16, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB10, - .size_multiplier_x2 = 2, -@@ -427,7 +436,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SBGGR10, - .depth = 16, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR10, - .size_multiplier_x2 = 2, -@@ -435,7 +444,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SGRBG10, - .depth = 16, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG10, - .size_multiplier_x2 = 2, -@@ -443,7 +452,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SGBRG10, - .depth = 16, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG10, - .size_multiplier_x2 = 2, -@@ -452,7 +461,7 @@ static const struct bcm2835_codec_fmt su - /* 12 bit */ - .fourcc = V4L2_PIX_FMT_SRGGB12, - .depth = 16, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB12, - .size_multiplier_x2 = 2, -@@ -460,7 +469,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SBGGR12, - .depth = 16, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR12, - .size_multiplier_x2 = 2, -@@ -468,7 +477,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SGRBG12, - .depth = 16, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG12, - .size_multiplier_x2 = 2, -@@ -476,7 +485,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SGBRG12, - .depth = 16, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG12, - .size_multiplier_x2 = 2, -@@ -485,7 +494,7 @@ static const struct bcm2835_codec_fmt su - /* 14 bit */ - .fourcc = V4L2_PIX_FMT_SRGGB14, - .depth = 16, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SRGGB14, - .size_multiplier_x2 = 2, -@@ -493,7 +502,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SBGGR14, - .depth = 16, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SBGGR14, - .size_multiplier_x2 = 2, -@@ -501,7 +510,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SGRBG14, - .depth = 16, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SGRBG14, - .size_multiplier_x2 = 2, -@@ -509,7 +518,7 @@ static const struct bcm2835_codec_fmt su - }, { - .fourcc = V4L2_PIX_FMT_SGBRG14, - .depth = 16, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_BAYER_SGBRG14, - .size_multiplier_x2 = 2, -@@ -519,7 +528,7 @@ static const struct bcm2835_codec_fmt su - /* 8 bit */ - .fourcc = V4L2_PIX_FMT_GREY, - .depth = 8, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_GREY, - .size_multiplier_x2 = 2, -@@ -527,7 +536,7 @@ static const struct bcm2835_codec_fmt su - /* 10 bit */ - .fourcc = V4L2_PIX_FMT_Y10P, - .depth = 10, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_Y10P, - .size_multiplier_x2 = 2, -@@ -535,7 +544,7 @@ static const struct bcm2835_codec_fmt su - /* 12 bit */ - .fourcc = V4L2_PIX_FMT_Y12P, - .depth = 12, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_Y12P, - .size_multiplier_x2 = 2, -@@ -543,7 +552,7 @@ static const struct bcm2835_codec_fmt su - /* 14 bit */ - .fourcc = V4L2_PIX_FMT_Y14P, - .depth = 14, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_Y14P, - .size_multiplier_x2 = 2, -@@ -551,7 +560,7 @@ static const struct bcm2835_codec_fmt su - /* 16 bit */ - .fourcc = V4L2_PIX_FMT_Y16, - .depth = 16, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_Y16, - .size_multiplier_x2 = 2, -@@ -559,7 +568,7 @@ static const struct bcm2835_codec_fmt su - /* 10 bit as 16bpp */ - .fourcc = V4L2_PIX_FMT_Y10, - .depth = 16, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_Y10, - .size_multiplier_x2 = 2, -@@ -567,7 +576,7 @@ static const struct bcm2835_codec_fmt su - /* 12 bit as 16bpp */ - .fourcc = V4L2_PIX_FMT_Y12, - .depth = 16, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_Y12, - .size_multiplier_x2 = 2, -@@ -575,7 +584,7 @@ static const struct bcm2835_codec_fmt su - /* 14 bit as 16bpp */ - .fourcc = V4L2_PIX_FMT_Y14, - .depth = 16, -- .bytesperline_align = { 32, 32, 32, 32 }, -+ .bytesperline_align = { 32, 32, 32, 32, 32 }, - .flags = 0, - .mmal_fmt = MMAL_ENCODING_Y14, - .size_multiplier_x2 = 2, -@@ -586,6 +595,11 @@ static const struct bcm2835_codec_fmt su - .flags = V4L2_FMT_FLAG_COMPRESSED, - .mmal_fmt = MMAL_ENCODING_H264, - }, { -+ .fourcc = V4L2_PIX_FMT_JPEG, -+ .depth = 0, -+ .flags = V4L2_FMT_FLAG_COMPRESSED, -+ .mmal_fmt = MMAL_ENCODING_JPEG, -+ }, { - .fourcc = V4L2_PIX_FMT_MJPEG, - .depth = 0, - .flags = V4L2_FMT_FLAG_COMPRESSED, -@@ -705,6 +719,7 @@ struct bcm2835_codec_driver { - struct bcm2835_codec_dev *decode; - struct bcm2835_codec_dev *isp; - struct bcm2835_codec_dev *deinterlace; -+ struct bcm2835_codec_dev *encode_image; - }; - - enum { -@@ -838,6 +853,9 @@ static inline unsigned int get_sizeimage - struct bcm2835_codec_fmt *fmt) - { - if (fmt->flags & V4L2_FMT_FLAG_COMPRESSED) { -+ if (fmt->fourcc == V4L2_PIX_FMT_JPEG) -+ return DEF_COMP_BUF_SIZE_JPEG; -+ - if (width * height > 1280 * 720) - return DEF_COMP_BUF_SIZE_GREATER_720P; - else -@@ -1422,12 +1440,12 @@ static int vidioc_try_fmt(struct bcm2835 - f->fmt.pix_mp.height = MIN_H; - - /* -- * For decoders the buffer must have a vertical alignment of 16 -- * lines. -+ * For decoders and image encoders the buffer must have -+ * a vertical alignment of 16 lines. - * The selection will reflect any cropping rectangle when only - * some of the pixels are active. - */ -- if (ctx->dev->role == DECODE) -+ if (ctx->dev->role == DECODE || ctx->dev->role == ENCODE_IMAGE) - f->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, 16); - } - f->fmt.pix_mp.num_planes = 1; -@@ -1573,12 +1591,13 @@ static int vidioc_s_fmt(struct bcm2835_c - v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "Calculated bpl as %u, size %u\n", - q_data->bytesperline, q_data->sizeimage); - -- if (ctx->dev->role == DECODE && -+ if ((ctx->dev->role == DECODE || ctx->dev->role == ENCODE_IMAGE) && - q_data->fmt->flags & V4L2_FMT_FLAG_COMPRESSED && - q_data->crop_width && q_data->height) { - /* -- * On the decoder, if provided with a resolution on the input -- * side, then replicate that to the output side. -+ * On the decoder or image encoder, if provided with -+ * a resolution on the input side, then replicate that -+ * to the output side. - * GStreamer appears not to support V4L2_EVENT_SOURCE_CHANGE, - * nor set up a resolution on the output side, therefore - * we can't decode anything at a resolution other than the -@@ -1719,7 +1738,7 @@ static int vidioc_g_selection(struct fil - switch (s->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - /* CAPTURE on encoder is not valid. */ -- if (ctx->dev->role == ENCODE) -+ if (ctx->dev->role == ENCODE || ctx->dev->role == ENCODE_IMAGE) - return -EINVAL; - q_data = &ctx->q_data[V4L2_M2M_DST]; - break; -@@ -1762,6 +1781,7 @@ static int vidioc_g_selection(struct fil - } - break; - case ENCODE: -+ case ENCODE_IMAGE: - switch (s->target) { - case V4L2_SEL_TGT_CROP_DEFAULT: - case V4L2_SEL_TGT_CROP_BOUNDS: -@@ -1846,7 +1866,7 @@ static int vidioc_s_selection(struct fil - switch (s->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - /* CAPTURE on encoder is not valid. */ -- if (ctx->dev->role == ENCODE) -+ if (ctx->dev->role == ENCODE || ctx->dev->role == ENCODE_IMAGE) - return -EINVAL; - q_data = &ctx->q_data[V4L2_M2M_DST]; - break; -@@ -1882,6 +1902,7 @@ static int vidioc_s_selection(struct fil - } - break; - case ENCODE: -+ case ENCODE_IMAGE: - switch (s->target) { - case V4L2_SEL_TGT_CROP: - /* Only support crop from (0,0) */ -@@ -2266,6 +2287,16 @@ static int bcm2835_codec_s_ctrl(struct v - sizeof(u32_value)); - break; - } -+ case V4L2_CID_JPEG_COMPRESSION_QUALITY: -+ if (!ctx->component) -+ break; -+ -+ ret = vchiq_mmal_port_parameter_set(ctx->dev->instance, -+ &ctx->component->output[0], -+ MMAL_PARAMETER_JPEG_Q_FACTOR, -+ &ctrl->val, -+ sizeof(ctrl->val)); -+ break; - - default: - v4l2_err(&ctx->dev->v4l2_dev, "Invalid control\n"); -@@ -2364,7 +2395,7 @@ static int vidioc_try_encoder_cmd(struct - { - struct bcm2835_codec_ctx *ctx = file2ctx(file); - -- if (ctx->dev->role != ENCODE) -+ if (ctx->dev->role != ENCODE && ctx->dev->role != ENCODE_IMAGE) - return -EINVAL; - - switch (cmd->cmd) { -@@ -2567,6 +2598,20 @@ static int bcm2835_codec_create_componen - MMAL_PARAMETER_IMAGE_EFFECT_PARAMETERS, - ¶ms, - sizeof(params)); -+ -+ } else if (dev->role == ENCODE_IMAGE) { -+ enable = 0; -+ vchiq_mmal_port_parameter_set(dev->instance, -+ &ctx->component->control, -+ MMAL_PARAMETER_EXIF_DISABLE, -+ &enable, -+ sizeof(enable)); -+ enable = 1; -+ vchiq_mmal_port_parameter_set(dev->instance, -+ &ctx->component->output[0], -+ MMAL_PARAMETER_JPEG_IJG_SCALING, -+ &enable, -+ sizeof(enable)); - } - - setup_mmal_port_format(ctx, &ctx->q_data[V4L2_M2M_SRC], -@@ -2595,7 +2640,7 @@ static int bcm2835_codec_create_componen - goto destroy_component; - } - -- if (dev->role == ENCODE) { -+ if (dev->role == ENCODE || dev->role == ENCODE_IMAGE) { - u32 param = 1; - - if (ctx->q_data[V4L2_M2M_SRC].sizeimage < -@@ -2604,27 +2649,29 @@ static int bcm2835_codec_create_componen - ctx->q_data[V4L2_M2M_SRC].sizeimage, - ctx->component->output[0].minimum_buffer.size); - -- /* Enable SPS Timing header so framerate information is encoded -- * in the H264 header. -- */ -- vchiq_mmal_port_parameter_set(ctx->dev->instance, -- &ctx->component->output[0], -- MMAL_PARAMETER_VIDEO_ENCODE_SPS_TIMING, -- ¶m, sizeof(param)); -- -- /* Enable inserting headers into the first frame */ -- vchiq_mmal_port_parameter_set(ctx->dev->instance, -- &ctx->component->control, -- MMAL_PARAMETER_VIDEO_ENCODE_HEADERS_WITH_FRAME, -- ¶m, sizeof(param)); -- /* -- * Avoid fragmenting the buffers over multiple frames (unless -- * the frame is bigger than the whole buffer) -- */ -- vchiq_mmal_port_parameter_set(ctx->dev->instance, -- &ctx->component->control, -- MMAL_PARAMETER_MINIMISE_FRAGMENTATION, -- ¶m, sizeof(param)); -+ if (dev->role == ENCODE) { -+ /* Enable SPS Timing header so framerate information is encoded -+ * in the H264 header. -+ */ -+ vchiq_mmal_port_parameter_set(ctx->dev->instance, -+ &ctx->component->output[0], -+ MMAL_PARAMETER_VIDEO_ENCODE_SPS_TIMING, -+ ¶m, sizeof(param)); -+ -+ /* Enable inserting headers into the first frame */ -+ vchiq_mmal_port_parameter_set(ctx->dev->instance, -+ &ctx->component->control, -+ MMAL_PARAMETER_VIDEO_ENCODE_HEADERS_WITH_FRAME, -+ ¶m, sizeof(param)); -+ /* -+ * Avoid fragmenting the buffers over multiple frames (unless -+ * the frame is bigger than the whole buffer) -+ */ -+ vchiq_mmal_port_parameter_set(ctx->dev->instance, -+ &ctx->component->control, -+ MMAL_PARAMETER_MINIMISE_FRAGMENTATION, -+ ¶m, sizeof(param)); -+ } - } else { - if (ctx->q_data[V4L2_M2M_DST].sizeimage < - ctx->component->output[0].minimum_buffer.size) -@@ -3248,6 +3295,23 @@ static int bcm2835_codec_open(struct fil - v4l2_ctrl_handler_init(hdl, 0); - } - break; -+ case ENCODE_IMAGE: -+ { -+ /* Encode image controls */ -+ v4l2_ctrl_handler_init(hdl, 1); -+ -+ v4l2_ctrl_new_std(hdl, &bcm2835_codec_ctrl_ops, -+ V4L2_CID_JPEG_COMPRESSION_QUALITY, -+ 1, 100, -+ 1, 80); -+ if (hdl->error) { -+ rc = hdl->error; -+ goto free_ctrl_handler; -+ } -+ ctx->fh.ctrl_handler = hdl; -+ v4l2_ctrl_handler_setup(hdl); -+ } -+ break; - case NUM_ROLES: - break; - } -@@ -3527,6 +3591,12 @@ static int bcm2835_codec_create(struct b - function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER; - video_nr = deinterlace_video_nr; - break; -+ case ENCODE_IMAGE: -+ v4l2_disable_ioctl(vfd, VIDIOC_DECODER_CMD); -+ v4l2_disable_ioctl(vfd, VIDIOC_TRY_DECODER_CMD); -+ function = MEDIA_ENT_F_PROC_VIDEO_ENCODER; -+ video_nr = encode_image_nr; -+ break; - default: - ret = -EINVAL; - goto unreg_dev; -@@ -3626,6 +3696,10 @@ static int bcm2835_codec_probe(struct pl - if (ret) - goto out; - -+ ret = bcm2835_codec_create(drv, &drv->encode_image, ENCODE_IMAGE); -+ if (ret) -+ goto out; -+ - /* Register the media device node */ - if (media_device_register(mdev) < 0) - goto out; -@@ -3635,6 +3709,10 @@ static int bcm2835_codec_probe(struct pl - return 0; - - out: -+ if (drv->encode_image) { -+ bcm2835_codec_destroy(drv->encode_image); -+ drv->encode_image = NULL; -+ } - if (drv->deinterlace) { - bcm2835_codec_destroy(drv->deinterlace); - drv->deinterlace = NULL; -@@ -3660,6 +3738,8 @@ static int bcm2835_codec_remove(struct p - - media_device_unregister(&drv->mdev); - -+ bcm2835_codec_destroy(drv->encode_image); -+ - bcm2835_codec_destroy(drv->deinterlace); - - bcm2835_codec_destroy(drv->isp); ---- a/drivers/staging/vc04_services/vchiq-mmal/mmal-parameters.h -+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-parameters.h -@@ -279,6 +279,8 @@ enum mmal_parameter_camera_type { - MMAL_PARAMETER_GAMMA, - /**< Takes a @ref MMAL_PARAMETER_CDN_T */ - MMAL_PARAMETER_CDN, -+ /**< Takes a @ref MMAL_PARAMETER_BOOLEAN_T */ -+ MMAL_PARAMETER_JPEG_IJG_SCALING, - }; - - struct mmal_parameter_rational { diff --git a/target/linux/bcm27xx/patches-5.15/950-0767-media-entity-Skip-non-data-links-in-graph-iteration.patch b/target/linux/bcm27xx/patches-5.15/950-0767-media-entity-Skip-non-data-links-in-graph-iteration.patch deleted file mode 100644 index a99a52983..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0767-media-entity-Skip-non-data-links-in-graph-iteration.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 74a4bd2caa37f07786cdf3e86ad9f7cbc6977b31 Mon Sep 17 00:00:00 2001 -From: Daniel Scally -Date: Wed, 2 Mar 2022 22:03:00 +0000 -Subject: [PATCH] media: entity: Skip non-data links in graph iteration - -When iterating over the media graph, don't follow links that are not -data links. - -Reviewed-by: Laurent Pinchart -Signed-off-by: Daniel Scally ---- - drivers/media/mc/mc-entity.c | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- a/drivers/media/mc/mc-entity.c -+++ b/drivers/media/mc/mc-entity.c -@@ -313,6 +313,12 @@ static void media_graph_walk_iter(struct - - link = list_entry(link_top(graph), typeof(*link), list); - -+ /* If the link is not a data link, don't follow it */ -+ if ((link->flags & MEDIA_LNK_FL_LINK_TYPE) != MEDIA_LNK_FL_DATA_LINK) { -+ link_top(graph) = link_top(graph)->next; -+ return; -+ } -+ - /* The link is not enabled so we do not follow. */ - if (!(link->flags & MEDIA_LNK_FL_ENABLED)) { - link_top(graph) = link_top(graph)->next; diff --git a/target/linux/bcm27xx/patches-5.15/950-0768-media-media.h-Add-new-media-link-type.patch b/target/linux/bcm27xx/patches-5.15/950-0768-media-media.h-Add-new-media-link-type.patch deleted file mode 100644 index ce92c3a31..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0768-media-media.h-Add-new-media-link-type.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 895e81564296a55a0691066a1931fd38a0139f63 Mon Sep 17 00:00:00 2001 -From: Daniel Scally -Date: Wed, 2 Mar 2022 22:03:01 +0000 -Subject: [PATCH] media: media.h: Add new media link type - -To describe in the kernel the connection between devices and their -supporting peripherals (for example, a camera sensor and the vcm -driving the focusing lens for it), add a new type of media link -to introduce the concept of these ancillary links. - -Add some elements to the uAPI documentation to explain the new link -type, their purpose and some aspects of their current implementation. - -Reviewed-by: Laurent Pinchart -Signed-off-by: Daniel Scally ---- - .../media/mediactl/media-controller-model.rst | 6 ++++++ - .../media/mediactl/media-types.rst | 17 ++++++++++++----- - include/uapi/linux/media.h | 1 + - 3 files changed, 19 insertions(+), 5 deletions(-) - ---- a/Documentation/userspace-api/media/mediactl/media-controller-model.rst -+++ b/Documentation/userspace-api/media/mediactl/media-controller-model.rst -@@ -33,3 +33,9 @@ are: - - - An **interface link** is a point-to-point bidirectional control - connection between a Linux Kernel interface and an entity. -+ -+- An **ancillary link** is a point-to-point connection denoting that two -+ entities form a single logical unit. For example this could represent the -+ fact that a particular camera sensor and lens controller form a single -+ physical module, meaning this lens controller drives the lens for this -+ camera sensor. -\ No newline at end of file ---- a/Documentation/userspace-api/media/mediactl/media-types.rst -+++ b/Documentation/userspace-api/media/mediactl/media-types.rst -@@ -412,14 +412,21 @@ must be set for every pad. - is set by drivers and is read-only for applications. - - * - ``MEDIA_LNK_FL_LINK_TYPE`` -- - This is a bitmask that defines the type of the link. Currently, -- two types of links are supported: -+ - This is a bitmask that defines the type of the link. The following -+ link types are currently supported: - - .. _MEDIA-LNK-FL-DATA-LINK: - -- ``MEDIA_LNK_FL_DATA_LINK`` if the link is between two pads -+ ``MEDIA_LNK_FL_DATA_LINK`` for links that represent a data connection -+ between two pads. - - .. _MEDIA-LNK-FL-INTERFACE-LINK: - -- ``MEDIA_LNK_FL_INTERFACE_LINK`` if the link is between an -- interface and an entity -+ ``MEDIA_LNK_FL_INTERFACE_LINK`` for links that associate an entity to its -+ interface. -+ -+ .. _MEDIA-LNK-FL-ANCILLARY-LINK: -+ -+ ``MEDIA_LNK_FL_ANCILLARY_LINK`` for links that represent a physical -+ relationship between two entities. The link may or may not be ummutable, so -+ applications must not assume either case. -\ No newline at end of file ---- a/include/uapi/linux/media.h -+++ b/include/uapi/linux/media.h -@@ -226,6 +226,7 @@ struct media_pad_desc { - #define MEDIA_LNK_FL_LINK_TYPE (0xf << 28) - # define MEDIA_LNK_FL_DATA_LINK (0 << 28) - # define MEDIA_LNK_FL_INTERFACE_LINK (1 << 28) -+# define MEDIA_LNK_FL_ANCILLARY_LINK (2 << 28) - - struct media_link_desc { - struct media_pad_desc source; diff --git a/target/linux/bcm27xx/patches-5.15/950-0769-media-entity-Add-link_type_name-helper.patch b/target/linux/bcm27xx/patches-5.15/950-0769-media-entity-Add-link_type_name-helper.patch deleted file mode 100644 index 6191b2acd..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0769-media-entity-Add-link_type_name-helper.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 7fd3f647f18b808effb3a8d514f9b49c5c9b6d9e Mon Sep 17 00:00:00 2001 -From: Daniel Scally -Date: Wed, 2 Mar 2022 22:03:02 +0000 -Subject: [PATCH] media: entity: Add link_type_name() helper - -Now we have three types of media link, printing the right name during -debug output is slightly more complicated. Add a helper function to -make it easier. - -Reviewed-by: Laurent Pinchart -Signed-off-by: Daniel Scally ---- - drivers/media/mc/mc-entity.c | 18 +++++++++++++++--- - 1 file changed, 15 insertions(+), 3 deletions(-) - ---- a/drivers/media/mc/mc-entity.c -+++ b/drivers/media/mc/mc-entity.c -@@ -60,6 +60,20 @@ static inline const char *intf_type(stru - } - }; - -+static inline const char *link_type_name(struct media_link *link) -+{ -+ switch (link->flags & MEDIA_LNK_FL_LINK_TYPE) { -+ case MEDIA_LNK_FL_DATA_LINK: -+ return "data"; -+ case MEDIA_LNK_FL_INTERFACE_LINK: -+ return "interface"; -+ case MEDIA_LNK_FL_ANCILLARY_LINK: -+ return "ancillary"; -+ default: -+ return "unknown"; -+ } -+} -+ - __must_check int __media_entity_enum_init(struct media_entity_enum *ent_enum, - int idx_max) - { -@@ -107,9 +121,7 @@ static void dev_dbg_obj(const char *even - - dev_dbg(gobj->mdev->dev, - "%s id %u: %s link id %u ==> id %u\n", -- event_name, media_id(gobj), -- media_type(link->gobj0) == MEDIA_GRAPH_PAD ? -- "data" : "interface", -+ event_name, media_id(gobj), link_type_name(link), - media_id(link->gobj0), - media_id(link->gobj1)); - break; diff --git a/target/linux/bcm27xx/patches-5.15/950-0770-media-entity-Add-support-for-ancillary-links.patch b/target/linux/bcm27xx/patches-5.15/950-0770-media-entity-Add-support-for-ancillary-links.patch deleted file mode 100644 index aaf117729..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0770-media-entity-Add-support-for-ancillary-links.patch +++ /dev/null @@ -1,69 +0,0 @@ -From f07c6a12bf8b432e70d312ab60b0a07197fa8162 Mon Sep 17 00:00:00 2001 -From: Daniel Scally -Date: Wed, 2 Mar 2022 22:03:03 +0000 -Subject: [PATCH] media: entity: Add support for ancillary links - -Add functions to create ancillary links, so that they don't need to -be manually created by users. - -Reviewed-by: Laurent Pinchart -Signed-off-by: Daniel Scally ---- - drivers/media/mc/mc-entity.c | 22 ++++++++++++++++++++++ - include/media/media-entity.h | 19 +++++++++++++++++++ - 2 files changed, 41 insertions(+) - ---- a/drivers/media/mc/mc-entity.c -+++ b/drivers/media/mc/mc-entity.c -@@ -1050,3 +1050,25 @@ void media_remove_intf_links(struct medi - mutex_unlock(&mdev->graph_mutex); - } - EXPORT_SYMBOL_GPL(media_remove_intf_links); -+ -+struct media_link *media_create_ancillary_link(struct media_entity *primary, -+ struct media_entity *ancillary) -+{ -+ struct media_link *link; -+ -+ link = media_add_link(&primary->links); -+ if (!link) -+ return ERR_PTR(-ENOMEM); -+ -+ link->gobj0 = &primary->graph_obj; -+ link->gobj1 = &ancillary->graph_obj; -+ link->flags = MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED | -+ MEDIA_LNK_FL_ANCILLARY_LINK; -+ -+ /* Initialize graph object embedded in the new link */ -+ media_gobj_create(primary->graph_obj.mdev, MEDIA_GRAPH_LINK, -+ &link->graph_obj); -+ -+ return link; -+} -+EXPORT_SYMBOL_GPL(media_create_ancillary_link); ---- a/include/media/media-entity.h -+++ b/include/media/media-entity.h -@@ -1107,4 +1107,23 @@ void media_remove_intf_links(struct medi - (((entity)->ops && (entity)->ops->operation) ? \ - (entity)->ops->operation((entity) , ##args) : -ENOIOCTLCMD) - -+/** -+ * media_create_ancillary_link() - create an ancillary link between two -+ * instances of &media_entity -+ * -+ * @primary: pointer to the primary &media_entity -+ * @ancillary: pointer to the ancillary &media_entity -+ * -+ * Create an ancillary link between two entities, indicating that they -+ * represent two connected pieces of hardware that form a single logical unit. -+ * A typical example is a camera lens controller being linked to the sensor that -+ * it is supporting. -+ * -+ * The function sets both MEDIA_LNK_FL_ENABLED and MEDIA_LNK_FL_IMMUTABLE for -+ * the new link. -+ */ -+struct media_link * -+media_create_ancillary_link(struct media_entity *primary, -+ struct media_entity *ancillary); -+ - #endif diff --git a/target/linux/bcm27xx/patches-5.15/950-0771-media-v4l2-async-Create-links-during-v4l2_async_matc.patch b/target/linux/bcm27xx/patches-5.15/950-0771-media-v4l2-async-Create-links-during-v4l2_async_matc.patch deleted file mode 100644 index b18188c2d..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0771-media-v4l2-async-Create-links-during-v4l2_async_matc.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 3f32e8b803061cf04a1fe31a3070e46fd0d379e8 Mon Sep 17 00:00:00 2001 -From: Daniel Scally -Date: Wed, 2 Mar 2022 22:03:04 +0000 -Subject: [PATCH] media: v4l2-async: Create links during - v4l2_async_match_notify() - -Upon an async fwnode match, there's some typical behaviour that the -notifier and matching subdev will want to do. For example, a notifier -representing a sensor matching to an async subdev representing its -VCM will want to create an ancillary link to expose that relationship -to userspace. - -To avoid lots of code in individual drivers, try to build these links -within v4l2 core. - -Signed-off-by: Daniel Scally ---- - drivers/media/v4l2-core/v4l2-async.c | 31 ++++++++++++++++++++++++++++ - 1 file changed, 31 insertions(+) - ---- a/drivers/media/v4l2-core/v4l2-async.c -+++ b/drivers/media/v4l2-core/v4l2-async.c -@@ -275,6 +275,24 @@ v4l2_async_notifier_try_complete(struct - static int - v4l2_async_notifier_try_all_subdevs(struct v4l2_async_notifier *notifier); - -+static int v4l2_async_create_ancillary_links(struct v4l2_async_notifier *n, -+ struct v4l2_subdev *sd) -+{ -+ struct media_link *link = NULL; -+ -+#if IS_ENABLED(CONFIG_MEDIA_CONTROLLER) -+ -+ if (sd->entity.function != MEDIA_ENT_F_LENS && -+ sd->entity.function != MEDIA_ENT_F_FLASH) -+ return 0; -+ -+ link = media_create_ancillary_link(&n->sd->entity, &sd->entity); -+ -+#endif -+ -+ return IS_ERR(link) ? PTR_ERR(link) : 0; -+} -+ - static int v4l2_async_match_notify(struct v4l2_async_notifier *notifier, - struct v4l2_device *v4l2_dev, - struct v4l2_subdev *sd, -@@ -292,6 +310,19 @@ static int v4l2_async_match_notify(struc - v4l2_device_unregister_subdev(sd); - return ret; - } -+ -+ /* -+ * Depending of the function of the entities involved, we may want to -+ * create links between them (for example between a sensor and its lens -+ * or between a sensor's source pad and the connected device's sink -+ * pad). -+ */ -+ ret = v4l2_async_create_ancillary_links(notifier, sd); -+ if (ret) { -+ v4l2_async_notifier_call_unbind(notifier, sd, asd); -+ v4l2_device_unregister_subdev(sd); -+ return ret; -+ } - - /* Remove from the waiting list */ - list_del(&asd->list); diff --git a/target/linux/bcm27xx/patches-5.15/950-0775-dtoverlays-Add-VCM-option-to-imx219.patch b/target/linux/bcm27xx/patches-5.15/950-0775-dtoverlays-Add-VCM-option-to-imx219.patch deleted file mode 100644 index 429b2bb2e..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0775-dtoverlays-Add-VCM-option-to-imx219.patch +++ /dev/null @@ -1,48 +0,0 @@ -From e6caf0202a5618e9f5a174c2ee4465ed2b44ea9e Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Fri, 11 Mar 2022 15:32:00 +0000 -Subject: [PATCH] dtoverlays: Add VCM option to imx219 - -Signed-off-by: Dave Stevenson ---- - arch/arm/boot/dts/overlays/README | 1 + - arch/arm/boot/dts/overlays/imx219-overlay.dts | 12 +++++++++++- - 2 files changed, 12 insertions(+), 1 deletion(-) - ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -1869,6 +1869,7 @@ Params: rotation Mounting - configuring the sensor (default on) - cam0 Adopt the default configuration for CAM0 on a - Compute Module (CSI0, i2c_vc, and cam0_reg). -+ vcm Configure a VCM focus drive on the sensor. - - - Name: imx290 ---- a/arch/arm/boot/dts/overlays/imx219-overlay.dts -+++ b/arch/arm/boot/dts/overlays/imx219-overlay.dts -@@ -63,6 +63,13 @@ - }; - }; - }; -+ -+ vcm: ad5398@0c { -+ compatible = "adi,ad5398"; -+ reg = <0x0c>; -+ status = "disabled"; -+ VANA-supply = <&cam1_reg>; -+ }; - }; - }; - -@@ -91,6 +98,9 @@ - <&csi_frag>, "target:0=",<&csi0>, - <&clk_frag>, "target:0=",<&cam0_clk>, - <&imx219>, "clocks:0=",<&cam0_clk>, -- <&imx219>, "VANA-supply:0=",<&cam0_reg>; -+ <&imx219>, "VANA-supply:0=",<&cam0_reg>, -+ <&vcm>, "VANA-supply:0=", <&cam0_reg>; -+ vcm = <&vcm>, "status=okay", -+ <&imx219>,"lens-focus:0=", <&vcm>; - }; - }; diff --git a/target/linux/bcm27xx/patches-5.15/950-0776-dtoverlay-Add-VCM-option-to-ov5647-overlay.patch b/target/linux/bcm27xx/patches-5.15/950-0776-dtoverlay-Add-VCM-option-to-ov5647-overlay.patch deleted file mode 100644 index 65c1d9a49..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0776-dtoverlay-Add-VCM-option-to-ov5647-overlay.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 654784fd3a33bb9407d7c5edd1f7cf89038049df Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Tue, 15 Mar 2022 18:36:10 +0000 -Subject: [PATCH] dtoverlay: Add VCM option to ov5647 overlay - -Signed-off-by: Dave Stevenson ---- - arch/arm/boot/dts/overlays/README | 1 + - arch/arm/boot/dts/overlays/ov5647-overlay.dts | 9 +++++++++ - 2 files changed, 10 insertions(+) - ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -2450,6 +2450,7 @@ Params: rotation Mounting - configuring the sensor (default on) - cam0 Adopt the default configuration for CAM0 on a - Compute Module (CSI0, i2c_vc, and cam0_reg). -+ vcm Configure a VCM focus drive on the sensor. - - - Name: ov7251 ---- a/arch/arm/boot/dts/overlays/ov5647-overlay.dts -+++ b/arch/arm/boot/dts/overlays/ov5647-overlay.dts -@@ -38,6 +38,13 @@ - }; - }; - }; -+ -+ vcm: ad5398@0c { -+ compatible = "adi,ad5398"; -+ reg = <0x0c>; -+ status = "disabled"; -+ VANA-supply = <&cam1_reg>; -+ }; - }; - }; - -@@ -95,5 +102,7 @@ - <&clk_frag>, "target:0=",<&cam0_clk>, - <&ov5647>, "clocks:0=",<&cam0_clk>, - <&ov5647>, "avdd-supply:0=",<&cam0_reg>; -+ vcm = <&vcm>, "status=okay", -+ <&ov5647>,"lens-focus:0=", <&vcm>; - }; - }; diff --git a/target/linux/bcm27xx/patches-5.15/950-0778-drm-object-Add-drm_object_property_get_default_value.patch b/target/linux/bcm27xx/patches-5.15/950-0778-drm-object-Add-drm_object_property_get_default_value.patch deleted file mode 100644 index 8e7844e05..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0778-drm-object-Add-drm_object_property_get_default_value.patch +++ /dev/null @@ -1,129 +0,0 @@ -From e458f351c7af35775528575611cb9b8f12ef6775 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 21 Feb 2022 10:59:02 +0100 -Subject: [PATCH] drm/object: Add - drm_object_property_get_default_value() function - -Upstream commit adf47b75297ebc71c53b6dc2d3c55f42b8fb79fd. - -Some functions to create properties (drm_plane_create_zpos_property or -drm_plane_create_color_properties for example) will ask for a range of -acceptable value and an initial one. - -This initial value is then stored in the values array for that property. - -Let's provide an helper to access this property. - -Acked-by: Daniel Vetter -Reviewed-by: Laurent Pinchart -Signed-off-by: Dave Stevenson -Signed-off-by: Maxime Ripard -Link: https://patchwork.freedesktop.org/patch/msgid/20220221095918.18763-7-maxime@cerno.tech ---- - drivers/gpu/drm/drm_mode_object.c | 53 +++++++++++++++++++++++++------ - include/drm/drm_mode_object.h | 7 ++++ - 2 files changed, 50 insertions(+), 10 deletions(-) - ---- a/drivers/gpu/drm/drm_mode_object.c -+++ b/drivers/gpu/drm/drm_mode_object.c -@@ -297,11 +297,26 @@ int drm_object_property_set_value(struct - } - EXPORT_SYMBOL(drm_object_property_set_value); - -+static int __drm_object_property_get_prop_value(struct drm_mode_object *obj, -+ struct drm_property *property, -+ uint64_t *val) -+{ -+ int i; -+ -+ for (i = 0; i < obj->properties->count; i++) { -+ if (obj->properties->properties[i] == property) { -+ *val = obj->properties->values[i]; -+ return 0; -+ } -+ } -+ -+ return -EINVAL; -+} -+ - static int __drm_object_property_get_value(struct drm_mode_object *obj, - struct drm_property *property, - uint64_t *val) - { -- int i; - - /* read-only properties bypass atomic mechanism and still store - * their value in obj->properties->values[].. mostly to avoid -@@ -311,15 +326,7 @@ static int __drm_object_property_get_val - !(property->flags & DRM_MODE_PROP_IMMUTABLE)) - return drm_atomic_get_property(obj, property, val); - -- for (i = 0; i < obj->properties->count; i++) { -- if (obj->properties->properties[i] == property) { -- *val = obj->properties->values[i]; -- return 0; -- } -- -- } -- -- return -EINVAL; -+ return __drm_object_property_get_prop_value(obj, property, val); - } - - /** -@@ -348,6 +355,32 @@ int drm_object_property_get_value(struct - } - EXPORT_SYMBOL(drm_object_property_get_value); - -+/** -+ * drm_object_property_get_default_value - retrieve the default value of a -+ * property when in atomic mode. -+ * @obj: drm mode object to get property value from -+ * @property: property to retrieve -+ * @val: storage for the property value -+ * -+ * This function retrieves the default state of the given property as passed in -+ * to drm_object_attach_property -+ * -+ * Only atomic drivers should call this function directly, as for non-atomic -+ * drivers it will return the current value. -+ * -+ * Returns: -+ * Zero on success, error code on failure. -+ */ -+int drm_object_property_get_default_value(struct drm_mode_object *obj, -+ struct drm_property *property, -+ uint64_t *val) -+{ -+ WARN_ON(!drm_drv_uses_atomic_modeset(property->dev)); -+ -+ return __drm_object_property_get_prop_value(obj, property, val); -+} -+EXPORT_SYMBOL(drm_object_property_get_default_value); -+ - /* helper for getconnector and getproperties ioctls */ - int drm_mode_object_get_properties(struct drm_mode_object *obj, bool atomic, - uint32_t __user *prop_ptr, ---- a/include/drm/drm_mode_object.h -+++ b/include/drm/drm_mode_object.h -@@ -98,6 +98,10 @@ struct drm_object_properties { - * Hence atomic drivers should not use drm_object_property_set_value() - * and drm_object_property_get_value() on mutable objects, i.e. those - * without the DRM_MODE_PROP_IMMUTABLE flag set. -+ * -+ * For atomic drivers the default value of properties is stored in this -+ * array, so drm_object_property_get_default_value can be used to -+ * retrieve it. - */ - uint64_t values[DRM_OBJECT_MAX_PROPERTY]; - }; -@@ -126,6 +130,9 @@ int drm_object_property_set_value(struct - int drm_object_property_get_value(struct drm_mode_object *obj, - struct drm_property *property, - uint64_t *value); -+int drm_object_property_get_default_value(struct drm_mode_object *obj, -+ struct drm_property *property, -+ uint64_t *val); - - void drm_object_attach_property(struct drm_mode_object *obj, - struct drm_property *property, diff --git a/target/linux/bcm27xx/patches-5.15/950-0779-drm-object-Add-default-zpos-value-at-reset.patch b/target/linux/bcm27xx/patches-5.15/950-0779-drm-object-Add-default-zpos-value-at-reset.patch deleted file mode 100644 index ff0e2ccf7..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0779-drm-object-Add-default-zpos-value-at-reset.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 69b992bf70df1892cfc8ccff07a79e8ea91e2902 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 21 Feb 2022 10:59:03 +0100 -Subject: [PATCH] drm/object: Add default zpos value at reset - -Upstream commit 1a7998dab5dd3d11bada7e3921781922082e7fe6 - -The drm_plane_create_zpos_property() function asks for an initial value, -and will set the associated plane state variable with that value if a -state is present. - -However, that function is usually called at a time where there's no -state yet. Since the drm_plane_state reset helper doesn't take care of -reading that value when it's called, it means that in most cases the -initial value will be 0, or the drivers will have to work around it. - -Let's add some code in __drm_atomic_helper_plane_state_reset() to get -the initial zpos value if the property has been attached in order to fix -this. - -Reviewed-by: Harry Wentland -Reviewed-by: Laurent Pinchart -Signed-off-by: Dave Stevenson -Signed-off-by: Maxime Ripard -Link: https://patchwork.freedesktop.org/patch/msgid/20220221095918.18763-8-maxime@cerno.tech ---- - drivers/gpu/drm/drm_atomic_state_helper.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - ---- a/drivers/gpu/drm/drm_atomic_state_helper.c -+++ b/drivers/gpu/drm/drm_atomic_state_helper.c -@@ -243,11 +243,22 @@ EXPORT_SYMBOL(drm_atomic_helper_crtc_des - void __drm_atomic_helper_plane_state_reset(struct drm_plane_state *plane_state, - struct drm_plane *plane) - { -+ u64 val; -+ - plane_state->plane = plane; - plane_state->rotation = DRM_MODE_ROTATE_0; - - plane_state->alpha = DRM_BLEND_ALPHA_OPAQUE; - plane_state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI; -+ -+ if (plane->zpos_property) { -+ if (!drm_object_property_get_default_value(&plane->base, -+ plane->zpos_property, -+ &val)) { -+ plane_state->zpos = val; -+ plane_state->normalized_zpos = val; -+ } -+ } - } - EXPORT_SYMBOL(__drm_atomic_helper_plane_state_reset); - diff --git a/target/linux/bcm27xx/patches-5.15/950-0780-drm-object-Add-default-color-encoding-and-range-valu.patch b/target/linux/bcm27xx/patches-5.15/950-0780-drm-object-Add-default-color-encoding-and-range-valu.patch deleted file mode 100644 index 40592b27c..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0780-drm-object-Add-default-color-encoding-and-range-valu.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 2506f4df7531123573ab9f11c9f032ffbb025c1d Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 21 Feb 2022 10:59:14 +0100 -Subject: [PATCH] drm/object: Add default color encoding and range - value at reset - -Upstream commit 9a48ab11714c955456fefdd4ab532d324fbef563 - -The drm_plane_create_color_properties() function asks for an initial -value for the color encoding and range, and will set the associated -plane state variable with that value if a state is present. - -However, that function is usually called at a time where there's no -state yet. Since the drm_plane_state reset helper doesn't take care of -reading that value when it's called, it means that in most cases the -initial value will be 0 (so DRM_COLOR_YCBCR_BT601 and -DRM_COLOR_YCBCR_LIMITED_RANGE, respectively), or the drivers will have -to work around it. - -Let's add some code in __drm_atomic_helper_plane_state_reset() to get -the initial encoding and range value if the property has been attached -in order to fix this. - -Reviewed-by: Harry Wentland -Signed-off-by: Dave Stevenson -Signed-off-by: Maxime Ripard -Link: https://patchwork.freedesktop.org/patch/msgid/20220221095918.18763-19-maxime@cerno.tech ---- - drivers/gpu/drm/drm_atomic_state_helper.c | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - ---- a/drivers/gpu/drm/drm_atomic_state_helper.c -+++ b/drivers/gpu/drm/drm_atomic_state_helper.c -@@ -251,6 +251,20 @@ void __drm_atomic_helper_plane_state_res - plane_state->alpha = DRM_BLEND_ALPHA_OPAQUE; - plane_state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI; - -+ if (plane->color_encoding_property) { -+ if (!drm_object_property_get_default_value(&plane->base, -+ plane->color_encoding_property, -+ &val)) -+ plane_state->color_encoding = val; -+ } -+ -+ if (plane->color_range_property) { -+ if (!drm_object_property_get_default_value(&plane->base, -+ plane->color_range_property, -+ &val)) -+ plane_state->color_range = val; -+ } -+ - if (plane->zpos_property) { - if (!drm_object_property_get_default_value(&plane->base, - plane->zpos_property, diff --git a/target/linux/bcm27xx/patches-5.15/950-0782-CM3-cam1_reg-and-cam1_reg_gpio-fix.patch b/target/linux/bcm27xx/patches-5.15/950-0782-CM3-cam1_reg-and-cam1_reg_gpio-fix.patch deleted file mode 100644 index 8e764f88b..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0782-CM3-cam1_reg-and-cam1_reg_gpio-fix.patch +++ /dev/null @@ -1,23 +0,0 @@ -From ad3e478684767e93f6e900af484571fe4a0bef3b Mon Sep 17 00:00:00 2001 -From: Rafael Sobral -Date: Fri, 18 Mar 2022 23:25:16 -0300 -Subject: [PATCH] CM3 cam1_reg and cam1_reg_gpio fix - -property name is gpio and not gpios ---- - arch/arm/boot/dts/bcm2710-rpi-cm3.dts | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/arch/arm/boot/dts/bcm2710-rpi-cm3.dts -+++ b/arch/arm/boot/dts/bcm2710-rpi-cm3.dts -@@ -211,8 +211,8 @@ cam0_reg: &cam0_regulator { - act_led_activelow = <&act_led>,"gpios:8"; - act_led_trigger = <&act_led>,"linux,default-trigger"; - cam0_reg = <&cam0_reg>,"status"; -- cam0_reg_gpio = <&cam0_reg>,"gpios:4"; -+ cam0_reg_gpio = <&cam0_reg>,"gpio:4"; - cam1_reg = <&cam1_reg>,"status"; -- cam1_reg_gpio = <&cam1_reg>,"gpios:4"; -+ cam1_reg_gpio = <&cam1_reg>,"gpio:4"; - }; - }; diff --git a/target/linux/bcm27xx/patches-5.15/950-0783-overlays-Fix-cam-_reg_gpio-parameter-on-CM1.patch b/target/linux/bcm27xx/patches-5.15/950-0783-overlays-Fix-cam-_reg_gpio-parameter-on-CM1.patch deleted file mode 100644 index 9a3b5bc63..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0783-overlays-Fix-cam-_reg_gpio-parameter-on-CM1.patch +++ /dev/null @@ -1,25 +0,0 @@ -From aae94965421d23e1bf28a5e0180fd698fd3eeb57 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Sat, 19 Mar 2022 22:19:51 +0000 -Subject: [PATCH] overlays: Fix cam*_reg_gpio parameter on CM1 - -See: https://github.com/raspberrypi/linux/pull/4945 - -Signed-off-by: Phil Elwell ---- - arch/arm/boot/dts/bcm2708-rpi-cm.dtsi | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -@@ -15,8 +15,8 @@ - act_led_activelow = <&act_led>,"gpios:8"; - act_led_trigger = <&act_led>,"linux,default-trigger"; - cam0_reg = <&cam0_reg>,"status"; -- cam0_reg_gpio = <&cam0_reg>,"gpios:4"; -+ cam0_reg_gpio = <&cam0_reg>,"gpio:4"; - cam1_reg = <&cam1_reg>,"status"; -- cam1_reg_gpio = <&cam1_reg>,"gpios:4"; -+ cam1_reg_gpio = <&cam1_reg>,"gpio:4"; - }; - }; diff --git a/target/linux/bcm27xx/patches-5.15/950-0784-overlays-iqs550-Enable-interrupt-pull-down.patch b/target/linux/bcm27xx/patches-5.15/950-0784-overlays-iqs550-Enable-interrupt-pull-down.patch deleted file mode 100644 index 21e037f70..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0784-overlays-iqs550-Enable-interrupt-pull-down.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 14ea778d2a5281a0f4c94230abccf30bc72c2bdd Mon Sep 17 00:00:00 2001 -From: Jeff LaBundy -Date: Sat, 19 Mar 2022 20:31:30 -0500 -Subject: [PATCH] overlays: iqs550: Enable interrupt pull-down - -The device's active-high interrupt normally serves as a push-pull -output, but becomes high-impedance during bootloader mode. Enable -a pull-down to hold the pin in the inactive state. - -Signed-off-by: Jeff LaBundy ---- - arch/arm/boot/dts/overlays/iqs550-overlay.dts | 15 ++++++++++++++- - 1 file changed, 14 insertions(+), 1 deletion(-) - ---- a/arch/arm/boot/dts/overlays/iqs550-overlay.dts -+++ b/arch/arm/boot/dts/overlays/iqs550-overlay.dts -@@ -20,6 +20,8 @@ - reg = <0x74>; - interrupt-parent = <&gpio>; - interrupts = <4 IRQ_TYPE_LEVEL_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&iqs550_pins>; - touchscreen-size-x = <800>; - touchscreen-size-y = <480>; - }; -@@ -34,8 +36,19 @@ - }; - }; - -+ fragment@2 { -+ target = <&gpio>; -+ __overlay__ { -+ iqs550_pins: iqs550_pins { -+ brcm,pins = <4>; -+ brcm,pull = <1>; -+ }; -+ }; -+ }; -+ - __overrides__ { -- interrupt = <&iqs550>,"interrupts:0"; -+ interrupt = <&iqs550>,"interrupts:0", -+ <&iqs550_pins>,"brcm,pins:0"; - reset = <0>,"+1", <&iqs550_reset>,"reset-gpios:4"; - sizex = <&iqs550>,"touchscreen-size-x:0"; - sizey = <&iqs550>,"touchscreen-size-y:0"; diff --git a/target/linux/bcm27xx/patches-5.15/950-0785-dtoverlays-Connect-the-backlight-to-the-pitft35-disp.patch b/target/linux/bcm27xx/patches-5.15/950-0785-dtoverlays-Connect-the-backlight-to-the-pitft35-disp.patch deleted file mode 100644 index 53f0a5f24..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0785-dtoverlays-Connect-the-backlight-to-the-pitft35-disp.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 8be4bcd743bb37336f83979fe0834ad601446a13 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -Date: Mon, 21 Mar 2022 18:27:45 +0000 -Subject: [PATCH] dtoverlays: Connect the backlight to the pitft35 - display - -DRM will automatically handle the backlight with the display if -told about the linking, so link the two together. - -Signed-off-by: Dave Stevenson ---- - arch/arm/boot/dts/overlays/pitft35-resistive-overlay.dts | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - ---- a/arch/arm/boot/dts/overlays/pitft35-resistive-overlay.dts -+++ b/arch/arm/boot/dts/overlays/pitft35-resistive-overlay.dts -@@ -102,7 +102,7 @@ - fragment@5 { - target-path = "/soc"; - __overlay__ { -- backlight { -+ backlight: backlight { - compatible = "gpio-backlight"; - gpios = <&stmpe_gpio 2 0>; - default-on; -@@ -115,6 +115,7 @@ - rotate = <&pitft>,"rotate:0"; - fps = <&pitft>,"fps:0"; - debug = <&pitft>,"debug:0"; -- drm = <&pitft>,"compatible=adafruit,yx350hv15"; -+ drm = <&pitft>,"compatible=adafruit,yx350hv15", -+ <&pitft>,"backlight:0=",<&backlight>; - }; - }; diff --git a/target/linux/bcm27xx/patches-5.15/950-0792-dt-bindings-display-add-bindings-for-MIPI-DBI-compat.patch b/target/linux/bcm27xx/patches-5.15/950-0792-dt-bindings-display-add-bindings-for-MIPI-DBI-compat.patch deleted file mode 100644 index 41331381e..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0792-dt-bindings-display-add-bindings-for-MIPI-DBI-compat.patch +++ /dev/null @@ -1,176 +0,0 @@ -From e39c2eeca4868a7cf34e34fb9a9ca7119c30372a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Sun, 27 Feb 2022 13:47:09 +0100 -Subject: [PATCH] dt-bindings: display: add bindings for MIPI DBI - compatible SPI panels -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -commit 2f3468b upstream. - -Add binding for MIPI DBI compatible SPI panels. - -v6: -- Fix indentation (Rob) - -v5: -- Add sainsmart18 to compatible items (Rob) -- Expand write-only description (Sam) - -v4: -- There should only be two compatible (Maxime) -- s/panel-dbi-spi/panel-mipi-dbi-spi/in compatible - -v3: -- Move properties to Device Tree (Maxime) -- Use contains for compatible (Maxime) -- Add backlight property to example -- Flesh out description - -v2: -- Fix path for panel-common.yaml -- Use unevaluatedProperties -- Drop properties which are in the allOf section -- Drop model property (Rob) - -Acked-by: Maxime Ripard -Acked-by: Sam Ravnborg -Reviewed-by: Rob Herring -Signed-off-by: Noralf Trønnes -Signed-off-by: Maxime Ripard -Link: https://patchwork.freedesktop.org/patch/msgid/20220227124713.39766-2-noralf@tronnes.org ---- - .../display/panel/panel-mipi-dbi-spi.yaml | 126 ++++++++++++++++++ - 1 file changed, 126 insertions(+) - create mode 100644 Documentation/devicetree/bindings/display/panel/panel-mipi-dbi-spi.yaml - ---- /dev/null -+++ b/Documentation/devicetree/bindings/display/panel/panel-mipi-dbi-spi.yaml -@@ -0,0 +1,126 @@ -+# SPDX-License-Identifier: (GPL-2.0-only or BSD-2-Clause) -+%YAML 1.2 -+--- -+$id: http://devicetree.org/schemas/display/panel/panel-mipi-dbi-spi.yaml# -+$schema: http://devicetree.org/meta-schemas/core.yaml# -+ -+title: MIPI DBI SPI Panel -+ -+maintainers: -+ - Noralf Trønnes -+ -+description: | -+ This binding is for display panels using a MIPI DBI compatible controller -+ in SPI mode. -+ -+ The MIPI Alliance Standard for Display Bus Interface defines the electrical -+ and logical interfaces for display controllers historically used in mobile -+ phones. The standard defines 4 display architecture types and this binding is -+ for type 1 which has full frame memory. There are 3 interface types in the -+ standard and type C is the serial interface. -+ -+ The standard defines the following interface signals for type C: -+ - Power: -+ - Vdd: Power supply for display module -+ - Vddi: Logic level supply for interface signals -+ Combined into one in this binding called: power-supply -+ - Interface: -+ - CSx: Chip select -+ - SCL: Serial clock -+ - Dout: Serial out -+ - Din: Serial in -+ - SDA: Bidrectional in/out -+ - D/CX: Data/command selection, high=data, low=command -+ Called dc-gpios in this binding. -+ - RESX: Reset when low -+ Called reset-gpios in this binding. -+ -+ The type C interface has 3 options: -+ -+ - Option 1: 9-bit mode and D/CX as the 9th bit -+ | Command | the next command or following data | -+ |<0>|| -+ -+ - Option 2: 16-bit mode and D/CX as a 9th bit -+ | Command or data | -+ || -+ -+ - Option 3: 8-bit mode and D/CX as a separate interface line -+ | Command or data | -+ || -+ -+ The panel resolution is specified using the panel-timing node properties -+ hactive (width) and vactive (height). The other mandatory panel-timing -+ properties should be set to zero except clock-frequency which can be -+ optionally set to inform about the actual pixel clock frequency. -+ -+ If the panel is wired to the controller at an offset specify this using -+ hback-porch (x-offset) and vback-porch (y-offset). -+ -+allOf: -+ - $ref: panel-common.yaml# -+ - $ref: /schemas/spi/spi-peripheral-props.yaml# -+ -+properties: -+ compatible: -+ items: -+ - enum: -+ - sainsmart18 -+ - const: panel-mipi-dbi-spi -+ -+ write-only: -+ type: boolean -+ description: -+ Controller is not readable (ie. Din (MISO on the SPI interface) is not -+ wired up). -+ -+ dc-gpios: -+ maxItems: 1 -+ description: | -+ Controller data/command selection (D/CX) in 4-line SPI mode. -+ If not set, the controller is in 3-line SPI mode. -+ -+required: -+ - compatible -+ - reg -+ - panel-timing -+ -+unevaluatedProperties: false -+ -+examples: -+ - | -+ #include -+ -+ spi { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ display@0{ -+ compatible = "sainsmart18", "panel-mipi-dbi-spi"; -+ reg = <0>; -+ spi-max-frequency = <40000000>; -+ -+ dc-gpios = <&gpio 24 GPIO_ACTIVE_HIGH>; -+ reset-gpios = <&gpio 25 GPIO_ACTIVE_HIGH>; -+ write-only; -+ -+ backlight = <&backlight>; -+ -+ width-mm = <35>; -+ height-mm = <28>; -+ -+ panel-timing { -+ hactive = <160>; -+ vactive = <128>; -+ hback-porch = <0>; -+ vback-porch = <0>; -+ clock-frequency = <0>; -+ hfront-porch = <0>; -+ hsync-len = <0>; -+ vfront-porch = <0>; -+ vsync-len = <0>; -+ }; -+ }; -+ }; -+ -+... diff --git a/target/linux/bcm27xx/patches-5.15/950-0793-drm-modes-Add-of_get_drm_panel_display_mode.patch b/target/linux/bcm27xx/patches-5.15/950-0793-drm-modes-Add-of_get_drm_panel_display_mode.patch deleted file mode 100644 index 57c7dd666..000000000 --- a/target/linux/bcm27xx/patches-5.15/950-0793-drm-modes-Add-of_get_drm_panel_display_mode.patch +++ /dev/null @@ -1,112 +0,0 @@ -From ab0dac9b018f82dfb5696e9671734178d226872f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Sun, 27 Feb 2022 13:47:11 +0100 -Subject: [PATCH] drm/modes: Add of_get_drm_panel_display_mode() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -commit 95ae342 upstream. - -Add a function to get a drm_display_mode from a panel-timing -device tree subnode. - -Suggested-by: Sam Ravnborg -Reviewed-by: Sam Ravnborg -Signed-off-by: Noralf Trønnes -Signed-off-by: Maxime Ripard -Link: https://patchwork.freedesktop.org/patch/msgid/20220227124713.39766-4-noralf@tronnes.org ---- - drivers/gpu/drm/drm_modes.c | 49 +++++++++++++++++++++++++++++++++++++ - include/drm/drm_modes.h | 8 ++++++ - 2 files changed, 57 insertions(+) - ---- a/drivers/gpu/drm/drm_modes.c -+++ b/drivers/gpu/drm/drm_modes.c -@@ -35,6 +35,7 @@ - #include - #include - -+#include